00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "config.h"
00037 #include "system.h"
00038 #include "coretypes.h"
00039 #include "tm.h"
00040 #include "toplev.h"
00041 #include "rtl.h"
00042 #include "tree.h"
00043 #include "tm_p.h"
00044 #include "flags.h"
00045 #include "function.h"
00046 #include "expr.h"
00047 #include "regs.h"
00048 #include "hard-reg-set.h"
00049 #include "hashtab.h"
00050 #include "insn-config.h"
00051 #include "recog.h"
00052 #include "real.h"
00053 #include "bitmap.h"
00054 #include "basic-block.h"
00055 #include "ggc.h"
00056 #include "debug.h"
00057 #include "langhooks.h"
00058
00059
00060
00061 enum machine_mode byte_mode;
00062 enum machine_mode word_mode;
00063 enum machine_mode double_mode;
00064 enum machine_mode ptr_mode;
00065
00066
00067
00068
00069
00070 static GTY(()) int label_num = 1;
00071
00072
00073
00074 static int no_line_numbers;
00075
00076
00077
00078
00079
00080
00081 rtx global_rtl[GR_MAX];
00082
00083
00084
00085
00086
00087 static GTY(()) rtx static_regno_reg_rtx[FIRST_PSEUDO_REGISTER];
00088
00089
00090
00091
00092
00093 rtx const_tiny_rtx[3][(int) MAX_MACHINE_MODE];
00094
00095 rtx const_true_rtx;
00096
00097 REAL_VALUE_TYPE dconst0;
00098 REAL_VALUE_TYPE dconst1;
00099 REAL_VALUE_TYPE dconst2;
00100 REAL_VALUE_TYPE dconst3;
00101 REAL_VALUE_TYPE dconst10;
00102 REAL_VALUE_TYPE dconstm1;
00103 REAL_VALUE_TYPE dconstm2;
00104 REAL_VALUE_TYPE dconsthalf;
00105 REAL_VALUE_TYPE dconstthird;
00106 REAL_VALUE_TYPE dconstpi;
00107 REAL_VALUE_TYPE dconste;
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 rtx static_chain_rtx;
00128 rtx static_chain_incoming_rtx;
00129 rtx pic_offset_table_rtx;
00130
00131
00132
00133 rtx return_address_pointer_rtx;
00134
00135
00136
00137
00138
00139
00140 rtx const_int_rtx[MAX_SAVED_CONST_INT * 2 + 1];
00141
00142
00143
00144
00145 static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def)))
00146 htab_t const_int_htab;
00147
00148
00149 static GTY ((if_marked ("ggc_marked_p"), param_is (struct mem_attrs)))
00150 htab_t mem_attrs_htab;
00151
00152
00153 static GTY ((if_marked ("ggc_marked_p"), param_is (struct reg_attrs)))
00154 htab_t reg_attrs_htab;
00155
00156
00157 static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def)))
00158 htab_t const_double_htab;
00159
00160 #define first_insn (cfun->emit->x_first_insn)
00161 #define last_insn (cfun->emit->x_last_insn)
00162 #define cur_insn_uid (cfun->emit->x_cur_insn_uid)
00163 #define last_location (cfun->emit->x_last_location)
00164 #define first_label_num (cfun->emit->x_first_label_num)
00165
00166 static rtx make_jump_insn_raw (rtx);
00167 static rtx make_call_insn_raw (rtx);
00168 static rtx find_line_note (rtx);
00169 static rtx change_address_1 (rtx, enum machine_mode, rtx, int);
00170 static void unshare_all_decls (tree);
00171 static void reset_used_decls (tree);
00172 static void mark_label_nuses (rtx);
00173 static hashval_t const_int_htab_hash (const void *);
00174 static int const_int_htab_eq (const void *, const void *);
00175 static hashval_t const_double_htab_hash (const void *);
00176 static int const_double_htab_eq (const void *, const void *);
00177 static rtx lookup_const_double (rtx);
00178 static hashval_t mem_attrs_htab_hash (const void *);
00179 static int mem_attrs_htab_eq (const void *, const void *);
00180 static mem_attrs *get_mem_attrs (HOST_WIDE_INT, tree, rtx, rtx, unsigned int,
00181 enum machine_mode);
00182 static hashval_t reg_attrs_htab_hash (const void *);
00183 static int reg_attrs_htab_eq (const void *, const void *);
00184 static reg_attrs *get_reg_attrs (tree, int);
00185 static tree component_ref_for_mem_expr (tree);
00186 static rtx gen_const_vector (enum machine_mode, int);
00187 static void copy_rtx_if_shared_1 (rtx *orig);
00188
00189
00190
00191 int split_branch_probability = -1;
00192
00193
00194
00195 static hashval_t
00196 const_int_htab_hash (const void *x)
00197 {
00198 return (hashval_t) INTVAL ((rtx) x);
00199 }
00200
00201
00202
00203
00204
00205 static int
00206 const_int_htab_eq (const void *x, const void *y)
00207 {
00208 return (INTVAL ((rtx) x) == *((const HOST_WIDE_INT *) y));
00209 }
00210
00211
00212 static hashval_t
00213 const_double_htab_hash (const void *x)
00214 {
00215 rtx value = (rtx) x;
00216 hashval_t h;
00217
00218 if (GET_MODE (value) == VOIDmode)
00219 h = CONST_DOUBLE_LOW (value) ^ CONST_DOUBLE_HIGH (value);
00220 else
00221 {
00222 h = real_hash (CONST_DOUBLE_REAL_VALUE (value));
00223
00224 h ^= GET_MODE (value);
00225 }
00226 return h;
00227 }
00228
00229
00230
00231 static int
00232 const_double_htab_eq (const void *x, const void *y)
00233 {
00234 rtx a = (rtx)x, b = (rtx)y;
00235
00236 if (GET_MODE (a) != GET_MODE (b))
00237 return 0;
00238 if (GET_MODE (a) == VOIDmode)
00239 return (CONST_DOUBLE_LOW (a) == CONST_DOUBLE_LOW (b)
00240 && CONST_DOUBLE_HIGH (a) == CONST_DOUBLE_HIGH (b));
00241 else
00242 return real_identical (CONST_DOUBLE_REAL_VALUE (a),
00243 CONST_DOUBLE_REAL_VALUE (b));
00244 }
00245
00246
00247
00248 static hashval_t
00249 mem_attrs_htab_hash (const void *x)
00250 {
00251 mem_attrs *p = (mem_attrs *) x;
00252
00253 return (p->alias ^ (p->align * 1000)
00254 ^ ((p->offset ? INTVAL (p->offset) : 0) * 50000)
00255 ^ ((p->size ? INTVAL (p->size) : 0) * 2500000)
00256 ^ (size_t) p->expr);
00257 }
00258
00259
00260
00261
00262
00263 static int
00264 mem_attrs_htab_eq (const void *x, const void *y)
00265 {
00266 mem_attrs *p = (mem_attrs *) x;
00267 mem_attrs *q = (mem_attrs *) y;
00268
00269 return (p->alias == q->alias && p->expr == q->expr && p->offset == q->offset
00270 && p->size == q->size && p->align == q->align);
00271 }
00272
00273
00274
00275
00276
00277 static mem_attrs *
00278 get_mem_attrs (HOST_WIDE_INT alias, tree expr, rtx offset, rtx size,
00279 unsigned int align, enum machine_mode mode)
00280 {
00281 mem_attrs attrs;
00282 void **slot;
00283
00284
00285
00286
00287 if (alias == 0 && expr == 0 && offset == 0
00288 && (size == 0
00289 || (mode != BLKmode && GET_MODE_SIZE (mode) == INTVAL (size)))
00290 && (STRICT_ALIGNMENT && mode != BLKmode
00291 ? align == GET_MODE_ALIGNMENT (mode) : align == BITS_PER_UNIT))
00292 return 0;
00293
00294 attrs.alias = alias;
00295 attrs.expr = expr;
00296 attrs.offset = offset;
00297 attrs.size = size;
00298 attrs.align = align;
00299
00300 slot = htab_find_slot (mem_attrs_htab, &attrs, INSERT);
00301 if (*slot == 0)
00302 {
00303 *slot = ggc_alloc (sizeof (mem_attrs));
00304 memcpy (*slot, &attrs, sizeof (mem_attrs));
00305 }
00306
00307 return *slot;
00308 }
00309
00310
00311
00312 static hashval_t
00313 reg_attrs_htab_hash (const void *x)
00314 {
00315 reg_attrs *p = (reg_attrs *) x;
00316
00317 return ((p->offset * 1000) ^ (long) p->decl);
00318 }
00319
00320
00321
00322
00323
00324 static int
00325 reg_attrs_htab_eq (const void *x, const void *y)
00326 {
00327 reg_attrs *p = (reg_attrs *) x;
00328 reg_attrs *q = (reg_attrs *) y;
00329
00330 return (p->decl == q->decl && p->offset == q->offset);
00331 }
00332
00333
00334
00335
00336 static reg_attrs *
00337 get_reg_attrs (tree decl, int offset)
00338 {
00339 reg_attrs attrs;
00340 void **slot;
00341
00342
00343 if (decl == 0 && offset == 0)
00344 return 0;
00345
00346 attrs.decl = decl;
00347 attrs.offset = offset;
00348
00349 slot = htab_find_slot (reg_attrs_htab, &attrs, INSERT);
00350 if (*slot == 0)
00351 {
00352 *slot = ggc_alloc (sizeof (reg_attrs));
00353 memcpy (*slot, &attrs, sizeof (reg_attrs));
00354 }
00355
00356 return *slot;
00357 }
00358
00359
00360
00361
00362
00363 rtx
00364 gen_raw_REG (enum machine_mode mode, int regno)
00365 {
00366 rtx x = gen_rtx_raw_REG (mode, regno);
00367 ORIGINAL_REGNO (x) = regno;
00368 return x;
00369 }
00370
00371
00372
00373
00374
00375 rtx
00376 gen_rtx_CONST_INT (enum machine_mode mode ATTRIBUTE_UNUSED, HOST_WIDE_INT arg)
00377 {
00378 void **slot;
00379
00380 if (arg >= - MAX_SAVED_CONST_INT && arg <= MAX_SAVED_CONST_INT)
00381 return const_int_rtx[arg + MAX_SAVED_CONST_INT];
00382
00383 #if STORE_FLAG_VALUE != 1 && STORE_FLAG_VALUE != -1
00384 if (const_true_rtx && arg == STORE_FLAG_VALUE)
00385 return const_true_rtx;
00386 #endif
00387
00388
00389 slot = htab_find_slot_with_hash (const_int_htab, &arg,
00390 (hashval_t) arg, INSERT);
00391 if (*slot == 0)
00392 *slot = gen_rtx_raw_CONST_INT (VOIDmode, arg);
00393
00394 return (rtx) *slot;
00395 }
00396
00397 rtx
00398 gen_int_mode (HOST_WIDE_INT c, enum machine_mode mode)
00399 {
00400 return GEN_INT (trunc_int_for_mode (c, mode));
00401 }
00402
00403
00404
00405
00406
00407
00408
00409
00410 static rtx
00411 lookup_const_double (rtx real)
00412 {
00413 void **slot = htab_find_slot (const_double_htab, real, INSERT);
00414 if (*slot == 0)
00415 *slot = real;
00416
00417 return (rtx) *slot;
00418 }
00419
00420
00421
00422 rtx
00423 const_double_from_real_value (REAL_VALUE_TYPE value, enum machine_mode mode)
00424 {
00425 rtx real = rtx_alloc (CONST_DOUBLE);
00426 PUT_MODE (real, mode);
00427
00428 memcpy (&CONST_DOUBLE_LOW (real), &value, sizeof (REAL_VALUE_TYPE));
00429
00430 return lookup_const_double (real);
00431 }
00432
00433
00434
00435
00436
00437
00438 rtx
00439 immed_double_const (HOST_WIDE_INT i0, HOST_WIDE_INT i1, enum machine_mode mode)
00440 {
00441 rtx value;
00442 unsigned int i;
00443
00444 if (mode != VOIDmode)
00445 {
00446 int width;
00447
00448 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT
00449 || GET_MODE_CLASS (mode) == MODE_PARTIAL_INT
00450
00451 || GET_MODE_CLASS (mode) == MODE_VECTOR_INT
00452 || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT);
00453
00454
00455
00456
00457 width = GET_MODE_BITSIZE (mode);
00458 if (width < HOST_BITS_PER_WIDE_INT
00459 && ((i0 & ((HOST_WIDE_INT) (-1) << (width - 1)))
00460 != ((HOST_WIDE_INT) (-1) << (width - 1))))
00461 i0 &= ((HOST_WIDE_INT) 1 << width) - 1, i1 = 0;
00462 else if (width == HOST_BITS_PER_WIDE_INT
00463 && ! (i1 == ~0 && i0 < 0))
00464 i1 = 0;
00465 else
00466
00467 gcc_assert (width <= 2 * HOST_BITS_PER_WIDE_INT);
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478 if (width < HOST_BITS_PER_WIDE_INT
00479 && (i0 & ((HOST_WIDE_INT) 1 << (width - 1))))
00480 i0 |= ((HOST_WIDE_INT) (-1) << width);
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500 if (width <= HOST_BITS_PER_WIDE_INT)
00501 i1 = (i0 < 0) ? ~(HOST_WIDE_INT) 0 : 0;
00502 }
00503
00504
00505 if ((i1 == 0 && i0 >= 0) || (i1 == ~0 && i0 < 0))
00506 return GEN_INT (i0);
00507
00508
00509 value = rtx_alloc (CONST_DOUBLE);
00510 PUT_MODE (value, VOIDmode);
00511
00512 CONST_DOUBLE_LOW (value) = i0;
00513 CONST_DOUBLE_HIGH (value) = i1;
00514
00515 for (i = 2; i < (sizeof CONST_DOUBLE_FORMAT - 1); i++)
00516 XWINT (value, i) = 0;
00517
00518 return lookup_const_double (value);
00519 }
00520
00521 rtx
00522 gen_rtx_REG (enum machine_mode mode, unsigned int regno)
00523 {
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538 if (mode == Pmode && !reload_in_progress)
00539 {
00540 if (regno == FRAME_POINTER_REGNUM
00541 && (!reload_completed || frame_pointer_needed))
00542 return frame_pointer_rtx;
00543 #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
00544 if (regno == HARD_FRAME_POINTER_REGNUM
00545 && (!reload_completed || frame_pointer_needed))
00546 return hard_frame_pointer_rtx;
00547 #endif
00548 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM && HARD_FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
00549 if (regno == ARG_POINTER_REGNUM)
00550 return arg_pointer_rtx;
00551 #endif
00552 #ifdef RETURN_ADDRESS_POINTER_REGNUM
00553 if (regno == RETURN_ADDRESS_POINTER_REGNUM)
00554 return return_address_pointer_rtx;
00555 #endif
00556 if (regno == (unsigned) PIC_OFFSET_TABLE_REGNUM
00557 && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
00558 return pic_offset_table_rtx;
00559 if (regno == STACK_POINTER_REGNUM)
00560 return stack_pointer_rtx;
00561 }
00562
00563 #if 0
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575 if (cfun
00576 && cfun->emit
00577 && regno_reg_rtx
00578 && regno < FIRST_PSEUDO_REGISTER
00579 && reg_raw_mode[regno] == mode)
00580 return regno_reg_rtx[regno];
00581 #endif
00582
00583 return gen_raw_REG (mode, regno);
00584 }
00585
00586 rtx
00587 gen_rtx_MEM (enum machine_mode mode, rtx addr)
00588 {
00589 rtx rt = gen_rtx_raw_MEM (mode, addr);
00590
00591
00592
00593 MEM_ATTRS (rt) = 0;
00594
00595 return rt;
00596 }
00597
00598
00599
00600 rtx
00601 gen_const_mem (enum machine_mode mode, rtx addr)
00602 {
00603 rtx mem = gen_rtx_MEM (mode, addr);
00604 MEM_READONLY_P (mem) = 1;
00605 MEM_NOTRAP_P (mem) = 1;
00606 return mem;
00607 }
00608
00609
00610
00611
00612 bool
00613 validate_subreg (enum machine_mode omode, enum machine_mode imode,
00614 rtx reg, unsigned int offset)
00615 {
00616 unsigned int isize = GET_MODE_SIZE (imode);
00617 unsigned int osize = GET_MODE_SIZE (omode);
00618
00619
00620 if (offset % osize != 0)
00621 return false;
00622
00623
00624 if (offset >= isize)
00625 return false;
00626
00627
00628
00629
00630
00631 if (omode == word_mode)
00632 ;
00633
00634
00635 else if (osize >= UNITS_PER_WORD && isize >= osize)
00636 ;
00637
00638
00639 else if ((COMPLEX_MODE_P (imode) || VECTOR_MODE_P (imode))
00640 && GET_MODE_INNER (imode) == omode)
00641 ;
00642
00643
00644
00645
00646
00647 else if (VECTOR_MODE_P (omode) && GET_MODE_INNER (omode) == imode)
00648 ;
00649
00650
00651
00652 else if (FLOAT_MODE_P (imode) || FLOAT_MODE_P (omode))
00653 {
00654 if (isize != osize)
00655 return false;
00656 }
00657
00658
00659 if (osize > isize)
00660 return offset == 0;
00661
00662
00663
00664
00665
00666 if (reg && REG_P (reg) && HARD_REGISTER_P (reg))
00667 {
00668 unsigned int regno = REGNO (reg);
00669
00670 #ifdef CANNOT_CHANGE_MODE_CLASS
00671 if ((COMPLEX_MODE_P (imode) || VECTOR_MODE_P (imode))
00672 && GET_MODE_INNER (imode) == omode)
00673 ;
00674 else if (REG_CANNOT_CHANGE_MODE_P (regno, imode, omode))
00675 return false;
00676 #endif
00677
00678 return subreg_offset_representable_p (regno, imode, offset, omode);
00679 }
00680
00681
00682
00683
00684
00685
00686
00687 if (osize < UNITS_PER_WORD)
00688 {
00689 enum machine_mode wmode = isize > UNITS_PER_WORD ? word_mode : imode;
00690 unsigned int low_off = subreg_lowpart_offset (omode, wmode);
00691 if (offset % UNITS_PER_WORD != low_off)
00692 return false;
00693 }
00694 return true;
00695 }
00696
00697 rtx
00698 gen_rtx_SUBREG (enum machine_mode mode, rtx reg, int offset)
00699 {
00700 gcc_assert (validate_subreg (mode, GET_MODE (reg), reg, offset));
00701 return gen_rtx_raw_SUBREG (mode, reg, offset);
00702 }
00703
00704
00705
00706
00707 rtx
00708 gen_lowpart_SUBREG (enum machine_mode mode, rtx reg)
00709 {
00710 enum machine_mode inmode;
00711
00712 inmode = GET_MODE (reg);
00713 if (inmode == VOIDmode)
00714 inmode = mode;
00715 return gen_rtx_SUBREG (mode, reg,
00716 subreg_lowpart_offset (mode, inmode));
00717 }
00718
00719
00720
00721
00722
00723
00724
00725
00726 rtvec
00727 gen_rtvec (int n, ...)
00728 {
00729 int i, save_n;
00730 rtx *vector;
00731 va_list p;
00732
00733 va_start (p, n);
00734
00735 if (n == 0)
00736 return NULL_RTVEC;
00737
00738 vector = alloca (n * sizeof (rtx));
00739
00740 for (i = 0; i < n; i++)
00741 vector[i] = va_arg (p, rtx);
00742
00743
00744 save_n = n;
00745 va_end (p);
00746
00747 return gen_rtvec_v (save_n, vector);
00748 }
00749
00750 rtvec
00751 gen_rtvec_v (int n, rtx *argp)
00752 {
00753 int i;
00754 rtvec rt_val;
00755
00756 if (n == 0)
00757 return NULL_RTVEC;
00758
00759 rt_val = rtvec_alloc (n);
00760
00761 for (i = 0; i < n; i++)
00762 rt_val->elem[i] = *argp++;
00763
00764 return rt_val;
00765 }
00766
00767
00768
00769
00770 rtx
00771 gen_reg_rtx (enum machine_mode mode)
00772 {
00773 struct function *f = cfun;
00774 rtx val;
00775
00776
00777
00778 gcc_assert (!no_new_pseudos);
00779
00780 if (generating_concat_p
00781 && (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
00782 || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT))
00783 {
00784
00785
00786
00787
00788
00789 rtx realpart, imagpart;
00790 enum machine_mode partmode = GET_MODE_INNER (mode);
00791
00792 realpart = gen_reg_rtx (partmode);
00793 imagpart = gen_reg_rtx (partmode);
00794 return gen_rtx_CONCAT (mode, realpart, imagpart);
00795 }
00796
00797
00798
00799
00800 if (reg_rtx_no == f->emit->regno_pointer_align_length)
00801 {
00802 int old_size = f->emit->regno_pointer_align_length;
00803 char *new;
00804 rtx *new1;
00805
00806 new = ggc_realloc (f->emit->regno_pointer_align, old_size * 2);
00807 memset (new + old_size, 0, old_size);
00808 f->emit->regno_pointer_align = (unsigned char *) new;
00809
00810 new1 = ggc_realloc (f->emit->x_regno_reg_rtx,
00811 old_size * 2 * sizeof (rtx));
00812 memset (new1 + old_size, 0, old_size * sizeof (rtx));
00813 regno_reg_rtx = new1;
00814
00815 f->emit->regno_pointer_align_length = old_size * 2;
00816 }
00817
00818 val = gen_raw_REG (mode, reg_rtx_no);
00819 regno_reg_rtx[reg_rtx_no++] = val;
00820 return val;
00821 }
00822
00823
00824
00825
00826 rtx
00827 gen_rtx_REG_offset (rtx reg, enum machine_mode mode, unsigned int regno, int offset)
00828 {
00829 rtx new = gen_rtx_REG (mode, regno);
00830 tree decl;
00831 HOST_WIDE_INT var_size;
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867 decl = REG_EXPR (reg);
00868 if ((BYTES_BIG_ENDIAN || WORDS_BIG_ENDIAN)
00869 && decl != NULL
00870 && offset > 0
00871 && GET_MODE_SIZE (GET_MODE (reg)) > GET_MODE_SIZE (mode)
00872 && ((var_size = int_size_in_bytes (TREE_TYPE (decl))) > 0
00873 && var_size < GET_MODE_SIZE (GET_MODE (reg))))
00874 {
00875 int offset_le;
00876
00877
00878 if (WORDS_BIG_ENDIAN)
00879 offset_le = ((GET_MODE_SIZE (GET_MODE (reg)) - 1 - offset)
00880 / UNITS_PER_WORD) * UNITS_PER_WORD;
00881 else
00882 offset_le = (offset / UNITS_PER_WORD) * UNITS_PER_WORD;
00883
00884 if (BYTES_BIG_ENDIAN)
00885 offset_le += ((GET_MODE_SIZE (GET_MODE (reg)) - 1 - offset)
00886 % UNITS_PER_WORD);
00887 else
00888 offset_le += offset % UNITS_PER_WORD;
00889
00890 if (offset_le >= var_size)
00891 {
00892
00893
00894 offset = 0;
00895 }
00896 else
00897 {
00898
00899 if (WORDS_BIG_ENDIAN)
00900 offset = ((var_size - 1 - offset_le)
00901 / UNITS_PER_WORD) * UNITS_PER_WORD;
00902 else
00903 offset = (offset_le / UNITS_PER_WORD) * UNITS_PER_WORD;
00904
00905 if (BYTES_BIG_ENDIAN)
00906 offset += ((var_size - 1 - offset_le)
00907 % UNITS_PER_WORD);
00908 else
00909 offset += offset_le % UNITS_PER_WORD;
00910 }
00911 }
00912
00913 REG_ATTRS (new) = get_reg_attrs (REG_EXPR (reg),
00914 REG_OFFSET (reg) + offset);
00915 return new;
00916 }
00917
00918
00919
00920 void
00921 set_reg_attrs_from_mem (rtx reg, rtx mem)
00922 {
00923 if (MEM_OFFSET (mem) && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
00924 REG_ATTRS (reg)
00925 = get_reg_attrs (MEM_EXPR (mem), INTVAL (MEM_OFFSET (mem)));
00926 }
00927
00928
00929
00930
00931 void
00932 set_reg_attrs_for_parm (rtx parm_rtx, rtx mem)
00933 {
00934 if (REG_P (parm_rtx))
00935 set_reg_attrs_from_mem (parm_rtx, mem);
00936 else if (GET_CODE (parm_rtx) == PARALLEL)
00937 {
00938
00939
00940 int i = XEXP (XVECEXP (parm_rtx, 0, 0), 0) ? 0 : 1;
00941 for (; i < XVECLEN (parm_rtx, 0); i++)
00942 {
00943 rtx x = XVECEXP (parm_rtx, 0, i);
00944 if (REG_P (XEXP (x, 0)))
00945 REG_ATTRS (XEXP (x, 0))
00946 = get_reg_attrs (MEM_EXPR (mem),
00947 INTVAL (XEXP (x, 1)));
00948 }
00949 }
00950 }
00951
00952
00953 void
00954 set_decl_rtl (tree t, rtx x)
00955 {
00956 DECL_CHECK (t)->decl.rtl = x;
00957
00958 if (!x)
00959 return;
00960
00961 if (REG_P (x))
00962 REG_ATTRS (x) = get_reg_attrs (t, 0);
00963 else if (GET_CODE (x) == SUBREG)
00964 REG_ATTRS (SUBREG_REG (x))
00965 = get_reg_attrs (t, -SUBREG_BYTE (x));
00966 if (GET_CODE (x) == CONCAT)
00967 {
00968 if (REG_P (XEXP (x, 0)))
00969 REG_ATTRS (XEXP (x, 0)) = get_reg_attrs (t, 0);
00970 if (REG_P (XEXP (x, 1)))
00971 REG_ATTRS (XEXP (x, 1))
00972 = get_reg_attrs (t, GET_MODE_UNIT_SIZE (GET_MODE (XEXP (x, 0))));
00973 }
00974 if (GET_CODE (x) == PARALLEL)
00975 {
00976 int i;
00977 for (i = 0; i < XVECLEN (x, 0); i++)
00978 {
00979 rtx y = XVECEXP (x, 0, i);
00980 if (REG_P (XEXP (y, 0)))
00981 REG_ATTRS (XEXP (y, 0)) = get_reg_attrs (t, INTVAL (XEXP (y, 1)));
00982 }
00983 }
00984 }
00985
00986
00987 void
00988 set_decl_incoming_rtl (tree t, rtx x)
00989 {
00990 DECL_INCOMING_RTL (t) = x;
00991
00992 if (!x)
00993 return;
00994
00995 if (REG_P (x))
00996 REG_ATTRS (x) = get_reg_attrs (t, 0);
00997 else if (GET_CODE (x) == SUBREG)
00998 REG_ATTRS (SUBREG_REG (x))
00999 = get_reg_attrs (t, -SUBREG_BYTE (x));
01000 if (GET_CODE (x) == CONCAT)
01001 {
01002 if (REG_P (XEXP (x, 0)))
01003 REG_ATTRS (XEXP (x, 0)) = get_reg_attrs (t, 0);
01004 if (REG_P (XEXP (x, 1)))
01005 REG_ATTRS (XEXP (x, 1))
01006 = get_reg_attrs (t, GET_MODE_UNIT_SIZE (GET_MODE (XEXP (x, 0))));
01007 }
01008 if (GET_CODE (x) == PARALLEL)
01009 {
01010 int i, start;
01011
01012
01013
01014 if (XEXP (XVECEXP (x, 0, 0), 0))
01015 start = 0;
01016 else
01017 start = 1;
01018
01019 for (i = start; i < XVECLEN (x, 0); i++)
01020 {
01021 rtx y = XVECEXP (x, 0, i);
01022 if (REG_P (XEXP (y, 0)))
01023 REG_ATTRS (XEXP (y, 0)) = get_reg_attrs (t, INTVAL (XEXP (y, 1)));
01024 }
01025 }
01026 }
01027
01028
01029
01030 void
01031 mark_user_reg (rtx reg)
01032 {
01033 if (GET_CODE (reg) == CONCAT)
01034 {
01035 REG_USERVAR_P (XEXP (reg, 0)) = 1;
01036 REG_USERVAR_P (XEXP (reg, 1)) = 1;
01037 }
01038 else
01039 {
01040 gcc_assert (REG_P (reg));
01041 REG_USERVAR_P (reg) = 1;
01042 }
01043 }
01044
01045
01046
01047
01048 void
01049 mark_reg_pointer (rtx reg, int align)
01050 {
01051 if (! REG_POINTER (reg))
01052 {
01053 REG_POINTER (reg) = 1;
01054
01055 if (align)
01056 REGNO_POINTER_ALIGN (REGNO (reg)) = align;
01057 }
01058 else if (align && align < REGNO_POINTER_ALIGN (REGNO (reg)))
01059
01060 REGNO_POINTER_ALIGN (REGNO (reg)) = align;
01061 }
01062
01063
01064
01065 int
01066 max_reg_num (void)
01067 {
01068 return reg_rtx_no;
01069 }
01070
01071
01072
01073 int
01074 max_label_num (void)
01075 {
01076 return label_num;
01077 }
01078
01079
01080
01081 int
01082 get_first_label_num (void)
01083 {
01084 return first_label_num;
01085 }
01086
01087
01088
01089
01090
01091 void
01092 maybe_set_first_label_num (rtx x)
01093 {
01094 if (CODE_LABEL_NUMBER (x) < first_label_num)
01095 first_label_num = CODE_LABEL_NUMBER (x);
01096 }
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109 rtx
01110 gen_lowpart_common (enum machine_mode mode, rtx x)
01111 {
01112 int msize = GET_MODE_SIZE (mode);
01113 int xsize;
01114 int offset = 0;
01115 enum machine_mode innermode;
01116
01117
01118
01119 innermode = GET_MODE (x);
01120 if (GET_CODE (x) == CONST_INT && msize <= HOST_BITS_PER_WIDE_INT)
01121 innermode = mode_for_size (HOST_BITS_PER_WIDE_INT, MODE_INT, 0);
01122 else if (innermode == VOIDmode)
01123 innermode = mode_for_size (HOST_BITS_PER_WIDE_INT * 2, MODE_INT, 0);
01124
01125 xsize = GET_MODE_SIZE (innermode);
01126
01127 gcc_assert (innermode != VOIDmode && innermode != BLKmode);
01128
01129 if (innermode == mode)
01130 return x;
01131
01132
01133 if ((msize + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD
01134 > ((xsize + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))
01135 return 0;
01136
01137
01138 if (GET_MODE_CLASS (mode) == MODE_FLOAT && msize > xsize)
01139 return 0;
01140
01141 offset = subreg_lowpart_offset (mode, innermode);
01142
01143 if ((GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND)
01144 && (GET_MODE_CLASS (mode) == MODE_INT
01145 || GET_MODE_CLASS (mode) == MODE_PARTIAL_INT))
01146 {
01147
01148
01149
01150
01151
01152
01153
01154
01155 if (GET_MODE (XEXP (x, 0)) == mode)
01156 return XEXP (x, 0);
01157 else if (msize < GET_MODE_SIZE (GET_MODE (XEXP (x, 0))))
01158 return gen_lowpart_common (mode, XEXP (x, 0));
01159 else if (msize < xsize)
01160 return gen_rtx_fmt_e (GET_CODE (x), mode, XEXP (x, 0));
01161 }
01162 else if (GET_CODE (x) == SUBREG || REG_P (x)
01163 || GET_CODE (x) == CONCAT || GET_CODE (x) == CONST_VECTOR
01164 || GET_CODE (x) == CONST_DOUBLE || GET_CODE (x) == CONST_INT)
01165 return simplify_gen_subreg (mode, x, innermode, offset);
01166
01167
01168 return 0;
01169 }
01170
01171 rtx
01172 gen_highpart (enum machine_mode mode, rtx x)
01173 {
01174 unsigned int msize = GET_MODE_SIZE (mode);
01175 rtx result;
01176
01177
01178
01179 gcc_assert (msize <= UNITS_PER_WORD
01180 || msize == (unsigned int) GET_MODE_UNIT_SIZE (GET_MODE (x)));
01181
01182 result = simplify_gen_subreg (mode, x, GET_MODE (x),
01183 subreg_highpart_offset (mode, GET_MODE (x)));
01184 gcc_assert (result);
01185
01186
01187
01188
01189 if (MEM_P (result))
01190 {
01191 result = validize_mem (result);
01192 gcc_assert (result);
01193 }
01194
01195 return result;
01196 }
01197
01198
01199
01200 rtx
01201 gen_highpart_mode (enum machine_mode outermode, enum machine_mode innermode, rtx exp)
01202 {
01203 if (GET_MODE (exp) != VOIDmode)
01204 {
01205 gcc_assert (GET_MODE (exp) == innermode);
01206 return gen_highpart (outermode, exp);
01207 }
01208 return simplify_gen_subreg (outermode, exp, innermode,
01209 subreg_highpart_offset (outermode, innermode));
01210 }
01211
01212
01213
01214
01215 unsigned int
01216 subreg_lowpart_offset (enum machine_mode outermode, enum machine_mode innermode)
01217 {
01218 unsigned int offset = 0;
01219 int difference = (GET_MODE_SIZE (innermode) - GET_MODE_SIZE (outermode));
01220
01221 if (difference > 0)
01222 {
01223 if (WORDS_BIG_ENDIAN)
01224 offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
01225 if (BYTES_BIG_ENDIAN)
01226 offset += difference % UNITS_PER_WORD;
01227 }
01228
01229 return offset;
01230 }
01231
01232
01233
01234 unsigned int
01235 subreg_highpart_offset (enum machine_mode outermode, enum machine_mode innermode)
01236 {
01237 unsigned int offset = 0;
01238 int difference = (GET_MODE_SIZE (innermode) - GET_MODE_SIZE (outermode));
01239
01240 gcc_assert (GET_MODE_SIZE (innermode) >= GET_MODE_SIZE (outermode));
01241
01242 if (difference > 0)
01243 {
01244 if (! WORDS_BIG_ENDIAN)
01245 offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
01246 if (! BYTES_BIG_ENDIAN)
01247 offset += difference % UNITS_PER_WORD;
01248 }
01249
01250 return offset;
01251 }
01252
01253
01254
01255
01256
01257 int
01258 subreg_lowpart_p (rtx x)
01259 {
01260 if (GET_CODE (x) != SUBREG)
01261 return 1;
01262 else if (GET_MODE (SUBREG_REG (x)) == VOIDmode)
01263 return 0;
01264
01265 return (subreg_lowpart_offset (GET_MODE (x), GET_MODE (SUBREG_REG (x)))
01266 == SUBREG_BYTE (x));
01267 }
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294 rtx
01295 operand_subword (rtx op, unsigned int offset, int validate_address, enum machine_mode mode)
01296 {
01297 if (mode == VOIDmode)
01298 mode = GET_MODE (op);
01299
01300 gcc_assert (mode != VOIDmode);
01301
01302
01303 if (mode != BLKmode
01304 && (GET_MODE_SIZE (mode) < UNITS_PER_WORD))
01305 return 0;
01306
01307
01308 if (mode != BLKmode
01309 && (offset + 1) * UNITS_PER_WORD > GET_MODE_SIZE (mode))
01310 return const0_rtx;
01311
01312
01313 if (MEM_P (op))
01314 {
01315 rtx new = adjust_address_nv (op, word_mode, offset * UNITS_PER_WORD);
01316
01317 if (! validate_address)
01318 return new;
01319
01320 else if (reload_completed)
01321 {
01322 if (! strict_memory_address_p (word_mode, XEXP (new, 0)))
01323 return 0;
01324 }
01325 else
01326 return replace_equiv_address (new, XEXP (new, 0));
01327 }
01328
01329
01330 return simplify_gen_subreg (word_mode, op, mode, (offset * UNITS_PER_WORD));
01331 }
01332
01333
01334
01335
01336
01337
01338
01339 rtx
01340 operand_subword_force (rtx op, unsigned int offset, enum machine_mode mode)
01341 {
01342 rtx result = operand_subword (op, offset, 1, mode);
01343
01344 if (result)
01345 return result;
01346
01347 if (mode != BLKmode && mode != VOIDmode)
01348 {
01349
01350
01351 if (REG_P (op))
01352 op = copy_to_reg (op);
01353 else
01354 op = force_reg (mode, op);
01355 }
01356
01357 result = operand_subword (op, offset, 1, mode);
01358 gcc_assert (result);
01359
01360 return result;
01361 }
01362
01363
01364
01365
01366 void
01367 reverse_comparison (rtx insn)
01368 {
01369 rtx body = PATTERN (insn);
01370 rtx comp;
01371
01372 if (GET_CODE (body) == SET)
01373 comp = SET_SRC (body);
01374 else
01375 comp = SET_SRC (XVECEXP (body, 0, 0));
01376
01377 if (GET_CODE (comp) == COMPARE)
01378 {
01379 rtx op0 = XEXP (comp, 0);
01380 rtx op1 = XEXP (comp, 1);
01381 XEXP (comp, 0) = op1;
01382 XEXP (comp, 1) = op0;
01383 }
01384 else
01385 {
01386 rtx new = gen_rtx_COMPARE (VOIDmode,
01387 CONST0_RTX (GET_MODE (comp)), comp);
01388 if (GET_CODE (body) == SET)
01389 SET_SRC (body) = new;
01390 else
01391 SET_SRC (XVECEXP (body, 0, 0)) = new;
01392 }
01393 }
01394
01395
01396
01397
01398
01399 static tree
01400 component_ref_for_mem_expr (tree ref)
01401 {
01402 tree inner = TREE_OPERAND (ref, 0);
01403
01404 if (TREE_CODE (inner) == COMPONENT_REF)
01405 inner = component_ref_for_mem_expr (inner);
01406 else
01407 {
01408
01409
01410 while (TREE_CODE (inner) == NOP_EXPR || TREE_CODE (inner) == CONVERT_EXPR
01411 || TREE_CODE (inner) == NON_LVALUE_EXPR
01412 || TREE_CODE (inner) == VIEW_CONVERT_EXPR
01413 || TREE_CODE (inner) == SAVE_EXPR)
01414 inner = TREE_OPERAND (inner, 0);
01415
01416 if (! DECL_P (inner))
01417 inner = NULL_TREE;
01418 }
01419
01420 if (inner == TREE_OPERAND (ref, 0))
01421 return ref;
01422 else
01423 return build3 (COMPONENT_REF, TREE_TYPE (ref), inner,
01424 TREE_OPERAND (ref, 1), NULL_TREE);
01425 }
01426
01427
01428
01429
01430 int
01431 mem_expr_equal_p (tree expr1, tree expr2)
01432 {
01433 if (expr1 == expr2)
01434 return 1;
01435
01436 if (! expr1 || ! expr2)
01437 return 0;
01438
01439 if (TREE_CODE (expr1) != TREE_CODE (expr2))
01440 return 0;
01441
01442 if (TREE_CODE (expr1) == COMPONENT_REF)
01443 return
01444 mem_expr_equal_p (TREE_OPERAND (expr1, 0),
01445 TREE_OPERAND (expr2, 0))
01446 && mem_expr_equal_p (TREE_OPERAND (expr1, 1),
01447 TREE_OPERAND (expr2, 1));
01448
01449 if (INDIRECT_REF_P (expr1))
01450 return mem_expr_equal_p (TREE_OPERAND (expr1, 0),
01451 TREE_OPERAND (expr2, 0));
01452
01453
01454
01455 gcc_assert (DECL_P (expr1));
01456
01457
01458 return 0;
01459 }
01460
01461
01462
01463
01464
01465
01466 void
01467 set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
01468 HOST_WIDE_INT bitpos)
01469 {
01470 HOST_WIDE_INT alias = MEM_ALIAS_SET (ref);
01471 tree expr = MEM_EXPR (ref);
01472 rtx offset = MEM_OFFSET (ref);
01473 rtx size = MEM_SIZE (ref);
01474 unsigned int align = MEM_ALIGN (ref);
01475 HOST_WIDE_INT apply_bitpos = 0;
01476 tree type;
01477
01478
01479
01480
01481 if (t == NULL_TREE)
01482 return;
01483
01484 type = TYPE_P (t) ? t : TREE_TYPE (t);
01485 if (type == error_mark_node)
01486 return;
01487
01488
01489
01490
01491
01492 gcc_assert (!DECL_P (t) || ref != DECL_RTL_IF_SET (t));
01493
01494
01495
01496 alias = get_alias_set (t);
01497
01498 MEM_VOLATILE_P (ref) |= TYPE_VOLATILE (type);
01499 MEM_IN_STRUCT_P (ref) = AGGREGATE_TYPE_P (type);
01500 MEM_POINTER (ref) = POINTER_TYPE_P (type);
01501 MEM_NOTRAP_P (ref) = TREE_THIS_NOTRAP (t);
01502
01503
01504
01505 if ((objectp || DECL_P (t)) && ! AGGREGATE_TYPE_P (type))
01506 MEM_SCALAR_P (ref) = 1;
01507
01508
01509
01510 if (objectp || TREE_CODE (t) == INDIRECT_REF
01511 || TREE_CODE (t) == ALIGN_INDIRECT_REF
01512 || TYPE_ALIGN_OK (type))
01513 align = MAX (align, TYPE_ALIGN (type));
01514 else
01515 if (TREE_CODE (t) == MISALIGNED_INDIRECT_REF)
01516 {
01517 if (integer_zerop (TREE_OPERAND (t, 1)))
01518
01519 align = BITS_PER_UNIT;
01520 else
01521 align = tree_low_cst (TREE_OPERAND (t, 1), 1);
01522 }
01523
01524
01525 if (TYPE_SIZE_UNIT (type) && host_integerp (TYPE_SIZE_UNIT (type), 1))
01526 size = GEN_INT (tree_low_cst (TYPE_SIZE_UNIT (type), 1));
01527
01528
01529
01530 if (! TYPE_P (t))
01531 {
01532 tree base = get_base_address (t);
01533 if (base && DECL_P (base)
01534 && TREE_READONLY (base)
01535 && (TREE_STATIC (base) || DECL_EXTERNAL (base)))
01536 {
01537 tree base_type = TREE_TYPE (base);
01538 gcc_assert (!(base_type && TYPE_NEEDS_CONSTRUCTING (base_type))
01539 || DECL_ARTIFICIAL (base));
01540 MEM_READONLY_P (ref) = 1;
01541 }
01542
01543 if (TREE_THIS_VOLATILE (t))
01544 MEM_VOLATILE_P (ref) = 1;
01545
01546
01547
01548 while (TREE_CODE (t) == NOP_EXPR || TREE_CODE (t) == CONVERT_EXPR
01549 || TREE_CODE (t) == NON_LVALUE_EXPR
01550 || TREE_CODE (t) == VIEW_CONVERT_EXPR
01551 || TREE_CODE (t) == SAVE_EXPR)
01552 t = TREE_OPERAND (t, 0);
01553
01554
01555
01556 if (component_uses_parent_alias_set (t))
01557 MEM_KEEP_ALIAS_SET_P (ref) = 1;
01558
01559
01560 if (DECL_P (t))
01561 {
01562 expr = t;
01563 offset = const0_rtx;
01564 apply_bitpos = bitpos;
01565 size = (DECL_SIZE_UNIT (t)
01566 && host_integerp (DECL_SIZE_UNIT (t), 1)
01567 ? GEN_INT (tree_low_cst (DECL_SIZE_UNIT (t), 1)) : 0);
01568 align = DECL_ALIGN (t);
01569 }
01570
01571
01572 else if (CONSTANT_CLASS_P (t))
01573 {
01574 align = TYPE_ALIGN (type);
01575 #ifdef CONSTANT_ALIGNMENT
01576 align = CONSTANT_ALIGNMENT (t, align);
01577 #endif
01578 }
01579
01580
01581
01582
01583
01584 else if (TREE_CODE (t) == COMPONENT_REF
01585 && ! DECL_BIT_FIELD (TREE_OPERAND (t, 1)))
01586 {
01587 expr = component_ref_for_mem_expr (t);
01588 offset = const0_rtx;
01589 apply_bitpos = bitpos;
01590
01591
01592 }
01593
01594
01595 else if (TREE_CODE (t) == ARRAY_REF)
01596 {
01597 tree off_tree = size_zero_node;
01598
01599
01600 tree t2 = t;
01601
01602 do
01603 {
01604 tree index = TREE_OPERAND (t2, 1);
01605 tree low_bound = array_ref_low_bound (t2);
01606 tree unit_size = array_ref_element_size (t2);
01607
01608
01609
01610
01611
01612 if (! integer_zerop (low_bound))
01613 index = fold (build2 (MINUS_EXPR, TREE_TYPE (index),
01614 index, low_bound));
01615
01616 off_tree = size_binop (PLUS_EXPR,
01617 size_binop (MULT_EXPR, convert (sizetype,
01618 index),
01619 unit_size),
01620 off_tree);
01621 t2 = TREE_OPERAND (t2, 0);
01622 }
01623 while (TREE_CODE (t2) == ARRAY_REF);
01624
01625 if (DECL_P (t2))
01626 {
01627 expr = t2;
01628 offset = NULL;
01629 if (host_integerp (off_tree, 1))
01630 {
01631 HOST_WIDE_INT ioff = tree_low_cst (off_tree, 1);
01632 HOST_WIDE_INT aoff = (ioff & -ioff) * BITS_PER_UNIT;
01633 align = DECL_ALIGN (t2);
01634 if (aoff && (unsigned HOST_WIDE_INT) aoff < align)
01635 align = aoff;
01636 offset = GEN_INT (ioff);
01637 apply_bitpos = bitpos;
01638 }
01639 }
01640 else if (TREE_CODE (t2) == COMPONENT_REF)
01641 {
01642 expr = component_ref_for_mem_expr (t2);
01643 if (host_integerp (off_tree, 1))
01644 {
01645 offset = GEN_INT (tree_low_cst (off_tree, 1));
01646 apply_bitpos = bitpos;
01647 }
01648
01649
01650 }
01651 else if (flag_argument_noalias > 1
01652 && (INDIRECT_REF_P (t2))
01653 && TREE_CODE (TREE_OPERAND (t2, 0)) == PARM_DECL)
01654 {
01655 expr = t2;
01656 offset = NULL;
01657 }
01658 }
01659
01660
01661
01662 else if (flag_argument_noalias > 1
01663 && (INDIRECT_REF_P (t))
01664 && TREE_CODE (TREE_OPERAND (t, 0)) == PARM_DECL)
01665 {
01666 expr = t;
01667 offset = NULL;
01668 }
01669 }
01670
01671
01672
01673
01674 if (apply_bitpos)
01675 {
01676 offset = plus_constant (offset, -(apply_bitpos / BITS_PER_UNIT));
01677 if (size)
01678 size = plus_constant (size, apply_bitpos / BITS_PER_UNIT);
01679 }
01680
01681 if (TREE_CODE (t) == ALIGN_INDIRECT_REF)
01682 {
01683
01684
01685 offset = NULL;
01686 expr = NULL;
01687 }
01688
01689
01690 MEM_ATTRS (ref)
01691 = get_mem_attrs (alias, expr, offset, size, align, GET_MODE (ref));
01692
01693
01694 if (MEM_IN_STRUCT_P (ref) || MEM_SCALAR_P (ref))
01695 return;
01696
01697
01698
01699 else if (TREE_CODE (t) == COMPONENT_REF || TREE_CODE (t) == ARRAY_REF
01700 || TREE_CODE (t) == ARRAY_RANGE_REF
01701 || TREE_CODE (t) == BIT_FIELD_REF)
01702 MEM_IN_STRUCT_P (ref) = 1;
01703 }
01704
01705 void
01706 set_mem_attributes (rtx ref, tree t, int objectp)
01707 {
01708 set_mem_attributes_minus_bitpos (ref, t, objectp, 0);
01709 }
01710
01711
01712
01713 void
01714 set_mem_attrs_from_reg (rtx mem, rtx reg)
01715 {
01716 MEM_ATTRS (mem)
01717 = get_mem_attrs (MEM_ALIAS_SET (mem), REG_EXPR (reg),
01718 GEN_INT (REG_OFFSET (reg)),
01719 MEM_SIZE (mem), MEM_ALIGN (mem), GET_MODE (mem));
01720 }
01721
01722
01723
01724 void
01725 set_mem_alias_set (rtx mem, HOST_WIDE_INT set)
01726 {
01727 #ifdef ENABLE_CHECKING
01728
01729 gcc_assert (alias_sets_conflict_p (set, MEM_ALIAS_SET (mem)));
01730 #endif
01731
01732 MEM_ATTRS (mem) = get_mem_attrs (set, MEM_EXPR (mem), MEM_OFFSET (mem),
01733 MEM_SIZE (mem), MEM_ALIGN (mem),
01734 GET_MODE (mem));
01735 }
01736
01737
01738
01739 void
01740 set_mem_align (rtx mem, unsigned int align)
01741 {
01742 MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
01743 MEM_OFFSET (mem), MEM_SIZE (mem), align,
01744 GET_MODE (mem));
01745 }
01746
01747
01748
01749 void
01750 set_mem_expr (rtx mem, tree expr)
01751 {
01752 MEM_ATTRS (mem)
01753 = get_mem_attrs (MEM_ALIAS_SET (mem), expr, MEM_OFFSET (mem),
01754 MEM_SIZE (mem), MEM_ALIGN (mem), GET_MODE (mem));
01755 }
01756
01757
01758
01759 void
01760 set_mem_offset (rtx mem, rtx offset)
01761 {
01762 MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
01763 offset, MEM_SIZE (mem), MEM_ALIGN (mem),
01764 GET_MODE (mem));
01765 }
01766
01767
01768
01769 void
01770 set_mem_size (rtx mem, rtx size)
01771 {
01772 MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
01773 MEM_OFFSET (mem), size, MEM_ALIGN (mem),
01774 GET_MODE (mem));
01775 }
01776
01777
01778
01779
01780
01781
01782
01783 static rtx
01784 change_address_1 (rtx memref, enum machine_mode mode, rtx addr, int validate)
01785 {
01786 rtx new;
01787
01788 gcc_assert (MEM_P (memref));
01789 if (mode == VOIDmode)
01790 mode = GET_MODE (memref);
01791 if (addr == 0)
01792 addr = XEXP (memref, 0);
01793 if (mode == GET_MODE (memref) && addr == XEXP (memref, 0)
01794 && (!validate || memory_address_p (mode, addr)))
01795 return memref;
01796
01797 if (validate)
01798 {
01799 if (reload_in_progress || reload_completed)
01800 gcc_assert (memory_address_p (mode, addr));
01801 else
01802 addr = memory_address (mode, addr);
01803 }
01804
01805 if (rtx_equal_p (addr, XEXP (memref, 0)) && mode == GET_MODE (memref))
01806 return memref;
01807
01808 new = gen_rtx_MEM (mode, addr);
01809 MEM_COPY_ATTRIBUTES (new, memref);
01810 return new;
01811 }
01812
01813
01814
01815
01816 rtx
01817 change_address (rtx memref, enum machine_mode mode, rtx addr)
01818 {
01819 rtx new = change_address_1 (memref, mode, addr, 1), size;
01820 enum machine_mode mmode = GET_MODE (new);
01821 unsigned int align;
01822
01823 size = mmode == BLKmode ? 0 : GEN_INT (GET_MODE_SIZE (mmode));
01824 align = mmode == BLKmode ? BITS_PER_UNIT : GET_MODE_ALIGNMENT (mmode);
01825
01826
01827 if (new == memref)
01828 {
01829 if (MEM_ATTRS (memref) == 0
01830 || (MEM_EXPR (memref) == NULL
01831 && MEM_OFFSET (memref) == NULL
01832 && MEM_SIZE (memref) == size
01833 && MEM_ALIGN (memref) == align))
01834 return new;
01835
01836 new = gen_rtx_MEM (mmode, XEXP (memref, 0));
01837 MEM_COPY_ATTRIBUTES (new, memref);
01838 }
01839
01840 MEM_ATTRS (new)
01841 = get_mem_attrs (MEM_ALIAS_SET (memref), 0, 0, size, align, mmode);
01842
01843 return new;
01844 }
01845
01846
01847
01848
01849
01850
01851
01852 rtx
01853 adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset,
01854 int validate, int adjust)
01855 {
01856 rtx addr = XEXP (memref, 0);
01857 rtx new;
01858 rtx memoffset = MEM_OFFSET (memref);
01859 rtx size = 0;
01860 unsigned int memalign = MEM_ALIGN (memref);
01861
01862
01863 if (mode == GET_MODE (memref) && !offset
01864 && (!validate || memory_address_p (mode, addr)))
01865 return memref;
01866
01867
01868
01869
01870 addr = copy_rtx (addr);
01871
01872 if (adjust)
01873 {
01874
01875
01876 if (GET_MODE (memref) != BLKmode && GET_CODE (addr) == LO_SUM
01877 && offset >= 0
01878 && (unsigned HOST_WIDE_INT) offset
01879 < GET_MODE_ALIGNMENT (GET_MODE (memref)) / BITS_PER_UNIT)
01880 addr = gen_rtx_LO_SUM (Pmode, XEXP (addr, 0),
01881 plus_constant (XEXP (addr, 1), offset));
01882 else
01883 addr = plus_constant (addr, offset);
01884 }
01885
01886 new = change_address_1 (memref, mode, addr, validate);
01887
01888
01889
01890 if (memoffset)
01891 memoffset = GEN_INT (offset + INTVAL (memoffset));
01892
01893
01894
01895
01896 if (offset != 0)
01897 memalign
01898 = MIN (memalign,
01899 (unsigned HOST_WIDE_INT) (offset & -offset) * BITS_PER_UNIT);
01900
01901
01902 if (GET_MODE (new) != BLKmode)
01903 size = GEN_INT (GET_MODE_SIZE (GET_MODE (new)));
01904 else if (MEM_SIZE (memref))
01905 size = plus_constant (MEM_SIZE (memref), -offset);
01906
01907 MEM_ATTRS (new) = get_mem_attrs (MEM_ALIAS_SET (memref), MEM_EXPR (memref),
01908 memoffset, size, memalign, GET_MODE (new));
01909
01910
01911
01912 return new;
01913 }
01914
01915
01916
01917
01918
01919
01920 rtx
01921 adjust_automodify_address_1 (rtx memref, enum machine_mode mode, rtx addr,
01922 HOST_WIDE_INT offset, int validate)
01923 {
01924 memref = change_address_1 (memref, VOIDmode, addr, validate);
01925 return adjust_address_1 (memref, mode, offset, validate, 0);
01926 }
01927
01928
01929
01930
01931
01932 rtx
01933 offset_address (rtx memref, rtx offset, unsigned HOST_WIDE_INT pow2)
01934 {
01935 rtx new, addr = XEXP (memref, 0);
01936
01937 new = simplify_gen_binary (PLUS, Pmode, addr, offset);
01938
01939
01940
01941
01942
01943
01944
01945
01946 if (! memory_address_p (GET_MODE (memref), new)
01947 && GET_CODE (addr) == PLUS
01948 && XEXP (addr, 0) == pic_offset_table_rtx)
01949 {
01950 addr = force_reg (GET_MODE (addr), addr);
01951 new = simplify_gen_binary (PLUS, Pmode, addr, offset);
01952 }
01953
01954 update_temp_slot_address (XEXP (memref, 0), new);
01955 new = change_address_1 (memref, VOIDmode, new, 1);
01956
01957
01958 if (new == memref)
01959 return new;
01960
01961
01962
01963 MEM_ATTRS (new)
01964 = get_mem_attrs (MEM_ALIAS_SET (memref), MEM_EXPR (memref), 0, 0,
01965 MIN (MEM_ALIGN (memref), pow2 * BITS_PER_UNIT),
01966 GET_MODE (new));
01967 return new;
01968 }
01969
01970
01971
01972
01973
01974
01975 rtx
01976 replace_equiv_address (rtx memref, rtx addr)
01977 {
01978
01979
01980 update_temp_slot_address (XEXP (memref, 0), addr);
01981 return change_address_1 (memref, VOIDmode, addr, 1);
01982 }
01983
01984
01985
01986 rtx
01987 replace_equiv_address_nv (rtx memref, rtx addr)
01988 {
01989 return change_address_1 (memref, VOIDmode, addr, 0);
01990 }
01991
01992
01993
01994
01995
01996
01997 rtx
01998 widen_memory_access (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset)
01999 {
02000 rtx new = adjust_address_1 (memref, mode, offset, 1, 1);
02001 tree expr = MEM_EXPR (new);
02002 rtx memoffset = MEM_OFFSET (new);
02003 unsigned int size = GET_MODE_SIZE (mode);
02004
02005
02006 if (new == memref)
02007 return new;
02008
02009
02010
02011 if (! memoffset)
02012 expr = NULL_TREE;
02013
02014 while (expr)
02015 {
02016 if (TREE_CODE (expr) == COMPONENT_REF)
02017 {
02018 tree field = TREE_OPERAND (expr, 1);
02019 tree offset = component_ref_field_offset (expr);
02020
02021 if (! DECL_SIZE_UNIT (field))
02022 {
02023 expr = NULL_TREE;
02024 break;
02025 }
02026
02027
02028
02029 if (TREE_CODE (DECL_SIZE_UNIT (field)) == INTEGER_CST
02030 && compare_tree_int (DECL_SIZE_UNIT (field), size) >= 0
02031 && INTVAL (memoffset) >= 0)
02032 break;
02033
02034 if (! host_integerp (offset, 1))
02035 {
02036 expr = NULL_TREE;
02037 break;
02038 }
02039
02040 expr = TREE_OPERAND (expr, 0);
02041 memoffset
02042 = (GEN_INT (INTVAL (memoffset)
02043 + tree_low_cst (offset, 1)
02044 + (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
02045 / BITS_PER_UNIT)));
02046 }
02047
02048 else if (DECL_P (expr)
02049 && DECL_SIZE_UNIT (expr)
02050 && TREE_CODE (DECL_SIZE_UNIT (expr)) == INTEGER_CST
02051 && compare_tree_int (DECL_SIZE_UNIT (expr), size) >= 0
02052 && (! memoffset || INTVAL (memoffset) >= 0))
02053 break;
02054 else
02055 {
02056
02057
02058 expr = NULL_TREE;
02059 break;
02060 }
02061 }
02062
02063 if (! expr)
02064 memoffset = NULL_RTX;
02065
02066
02067
02068
02069 MEM_ATTRS (new) = get_mem_attrs (0, expr, memoffset, GEN_INT (size),
02070 MEM_ALIGN (new), mode);
02071
02072 return new;
02073 }
02074
02075
02076
02077 rtx
02078 gen_label_rtx (void)
02079 {
02080 return gen_rtx_CODE_LABEL (VOIDmode, 0, NULL_RTX, NULL_RTX,
02081 NULL, label_num++, NULL);
02082 }
02083
02084
02085
02086
02087
02088
02089
02090 void
02091 set_new_first_and_last_insn (rtx first, rtx last)
02092 {
02093 rtx insn;
02094
02095 first_insn = first;
02096 last_insn = last;
02097 cur_insn_uid = 0;
02098
02099 for (insn = first; insn; insn = NEXT_INSN (insn))
02100 cur_insn_uid = MAX (cur_insn_uid, INSN_UID (insn));
02101
02102 cur_insn_uid++;
02103 }
02104
02105
02106
02107
02108 static void
02109 unshare_all_rtl_1 (tree fndecl, rtx insn)
02110 {
02111 tree decl;
02112
02113
02114 for (decl = DECL_ARGUMENTS (fndecl); decl; decl = TREE_CHAIN (decl))
02115 SET_DECL_RTL (decl, copy_rtx_if_shared (DECL_RTL (decl)));
02116
02117
02118 unshare_all_decls (DECL_INITIAL (fndecl));
02119
02120
02121 unshare_all_rtl_in_chain (insn);
02122
02123
02124
02125
02126
02127
02128
02129
02130 stack_slot_list = copy_rtx_if_shared (stack_slot_list);
02131 }
02132
02133
02134
02135
02136
02137 void
02138 unshare_all_rtl_again (rtx insn)
02139 {
02140 rtx p;
02141 tree decl;
02142
02143 for (p = insn; p; p = NEXT_INSN (p))
02144 if (INSN_P (p))
02145 {
02146 reset_used_flags (PATTERN (p));
02147 reset_used_flags (REG_NOTES (p));
02148 reset_used_flags (LOG_LINKS (p));
02149 }
02150
02151
02152 reset_used_decls (DECL_INITIAL (cfun->decl));
02153
02154
02155 for (decl = DECL_ARGUMENTS (cfun->decl); decl; decl = TREE_CHAIN (decl))
02156 reset_used_flags (DECL_RTL (decl));
02157
02158 reset_used_flags (stack_slot_list);
02159
02160 unshare_all_rtl_1 (cfun->decl, insn);
02161 }
02162
02163 void
02164 unshare_all_rtl (void)
02165 {
02166 unshare_all_rtl_1 (current_function_decl, get_insns ());
02167 }
02168
02169
02170
02171
02172 static void
02173 verify_rtx_sharing (rtx orig, rtx insn)
02174 {
02175 rtx x = orig;
02176 int i;
02177 enum rtx_code code;
02178 const char *format_ptr;
02179
02180 if (x == 0)
02181 return;
02182
02183 code = GET_CODE (x);
02184
02185
02186
02187 switch (code)
02188 {
02189 case REG:
02190 case CONST_INT:
02191 case CONST_DOUBLE:
02192 case CONST_VECTOR:
02193 case SYMBOL_REF:
02194 case LABEL_REF:
02195 case CODE_LABEL:
02196 case PC:
02197 case CC0:
02198 case SCRATCH:
02199 return;
02200
02201 case CLOBBER:
02202 if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)
02203 return;
02204 break;
02205
02206 case CONST:
02207
02208
02209 if (GET_CODE (XEXP (x, 0)) == PLUS
02210 && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
02211 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
02212 return;
02213 break;
02214
02215 case MEM:
02216
02217 if (CONSTANT_ADDRESS_P (XEXP (x, 0))
02218 || reload_completed || reload_in_progress)
02219 return;
02220
02221 break;
02222
02223 default:
02224 break;
02225 }
02226
02227
02228
02229 #ifdef ENABLE_CHECKING
02230 if (RTX_FLAG (x, used))
02231 {
02232 error ("Invalid rtl sharing found in the insn");
02233 debug_rtx (insn);
02234 error ("Shared rtx");
02235 debug_rtx (x);
02236 internal_error ("Internal consistency failure");
02237 }
02238 #endif
02239 gcc_assert (!RTX_FLAG (x, used));
02240
02241 RTX_FLAG (x, used) = 1;
02242
02243
02244
02245 format_ptr = GET_RTX_FORMAT (code);
02246
02247 for (i = 0; i < GET_RTX_LENGTH (code); i++)
02248 {
02249 switch (*format_ptr++)
02250 {
02251 case 'e':
02252 verify_rtx_sharing (XEXP (x, i), insn);
02253 break;
02254
02255 case 'E':
02256 if (XVEC (x, i) != NULL)
02257 {
02258 int j;
02259 int len = XVECLEN (x, i);
02260
02261 for (j = 0; j < len; j++)
02262 {
02263
02264
02265 if (j && GET_CODE (XVECEXP (x, i, j)) == SET
02266 && (GET_CODE (SET_SRC (XVECEXP (x, i, j)))
02267 == ASM_OPERANDS))
02268 verify_rtx_sharing (SET_DEST (XVECEXP (x, i, j)), insn);
02269 else
02270 verify_rtx_sharing (XVECEXP (x, i, j), insn);
02271 }
02272 }
02273 break;
02274 }
02275 }
02276 return;
02277 }
02278
02279
02280
02281
02282 void
02283 verify_rtl_sharing (void)
02284 {
02285 rtx p;
02286
02287 for (p = get_insns (); p; p = NEXT_INSN (p))
02288 if (INSN_P (p))
02289 {
02290 reset_used_flags (PATTERN (p));
02291 reset_used_flags (REG_NOTES (p));
02292 reset_used_flags (LOG_LINKS (p));
02293 }
02294
02295 for (p = get_insns (); p; p = NEXT_INSN (p))
02296 if (INSN_P (p))
02297 {
02298 verify_rtx_sharing (PATTERN (p), p);
02299 verify_rtx_sharing (REG_NOTES (p), p);
02300 verify_rtx_sharing (LOG_LINKS (p), p);
02301 }
02302 }
02303
02304
02305
02306
02307 void
02308 unshare_all_rtl_in_chain (rtx insn)
02309 {
02310 for (; insn; insn = NEXT_INSN (insn))
02311 if (INSN_P (insn))
02312 {
02313 PATTERN (insn) = copy_rtx_if_shared (PATTERN (insn));
02314 REG_NOTES (insn) = copy_rtx_if_shared (REG_NOTES (insn));
02315 LOG_LINKS (insn) = copy_rtx_if_shared (LOG_LINKS (insn));
02316 }
02317 }
02318
02319
02320
02321 static void
02322 unshare_all_decls (tree blk)
02323 {
02324 tree t;
02325
02326
02327 for (t = BLOCK_VARS (blk); t; t = TREE_CHAIN (t))
02328 if (DECL_RTL_SET_P (t))
02329 SET_DECL_RTL (t, copy_rtx_if_shared (DECL_RTL (t)));
02330
02331
02332 for (t = BLOCK_SUBBLOCKS (blk); t; t = TREE_CHAIN (t))
02333 unshare_all_decls (t);
02334 }
02335
02336
02337
02338 static void
02339 reset_used_decls (tree blk)
02340 {
02341 tree t;
02342
02343
02344 for (t = BLOCK_VARS (blk); t; t = TREE_CHAIN (t))
02345 if (DECL_RTL_SET_P (t))
02346 reset_used_flags (DECL_RTL (t));
02347
02348
02349 for (t = BLOCK_SUBBLOCKS (blk); t; t = TREE_CHAIN (t))
02350 reset_used_decls (t);
02351 }
02352
02353
02354
02355
02356
02357 rtx
02358 copy_rtx_if_shared (rtx orig)
02359 {
02360 copy_rtx_if_shared_1 (&orig);
02361 return orig;
02362 }
02363
02364
02365
02366
02367 static void
02368 copy_rtx_if_shared_1 (rtx *orig1)
02369 {
02370 rtx x;
02371 int i;
02372 enum rtx_code code;
02373 rtx *last_ptr;
02374 const char *format_ptr;
02375 int copied = 0;
02376 int length;
02377
02378
02379 repeat:
02380 x = *orig1;
02381
02382 if (x == 0)
02383 return;
02384
02385 code = GET_CODE (x);
02386
02387
02388
02389 switch (code)
02390 {
02391 case REG:
02392 case CONST_INT:
02393 case CONST_DOUBLE:
02394 case CONST_VECTOR:
02395 case SYMBOL_REF:
02396 case LABEL_REF:
02397 case CODE_LABEL:
02398 case PC:
02399 case CC0:
02400 case SCRATCH:
02401
02402 return;
02403 case CLOBBER:
02404 if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)
02405 return;
02406 break;
02407
02408 case CONST:
02409
02410
02411 if (GET_CODE (XEXP (x, 0)) == PLUS
02412 && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
02413 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
02414 return;
02415 break;
02416
02417 case INSN:
02418 case JUMP_INSN:
02419 case CALL_INSN:
02420 case NOTE:
02421 case BARRIER:
02422
02423 return;
02424
02425 default:
02426 break;
02427 }
02428
02429
02430
02431
02432 if (RTX_FLAG (x, used))
02433 {
02434 rtx copy;
02435
02436 copy = rtx_alloc (code);
02437 memcpy (copy, x, RTX_SIZE (code));
02438 x = copy;
02439 copied = 1;
02440 }
02441 RTX_FLAG (x, used) = 1;
02442
02443
02444
02445
02446
02447
02448 format_ptr = GET_RTX_FORMAT (code);
02449 length = GET_RTX_LENGTH (code);
02450 last_ptr = NULL;
02451
02452 for (i = 0; i < length; i++)
02453 {
02454 switch (*format_ptr++)
02455 {
02456 case 'e':
02457 if (last_ptr)
02458 copy_rtx_if_shared_1 (last_ptr);
02459 last_ptr = &XEXP (x, i);
02460 break;
02461
02462 case 'E':
02463 if (XVEC (x, i) != NULL)
02464 {
02465 int j;
02466 int len = XVECLEN (x, i);
02467
02468
02469
02470 if (copied && len > 0)
02471 XVEC (x, i) = gen_rtvec_v (len, XVEC (x, i)->elem);
02472
02473
02474 for (j = 0; j < len; j++)
02475 {
02476 if (last_ptr)
02477 copy_rtx_if_shared_1 (last_ptr);
02478 last_ptr = &XVECEXP (x, i, j);
02479 }
02480 }
02481 break;
02482 }
02483 }
02484 *orig1 = x;
02485 if (last_ptr)
02486 {
02487 orig1 = last_ptr;
02488 goto repeat;
02489 }
02490 return;
02491 }
02492
02493
02494
02495
02496 void
02497 reset_used_flags (rtx x)
02498 {
02499 int i, j;
02500 enum rtx_code code;
02501 const char *format_ptr;
02502 int length;
02503
02504
02505 repeat:
02506 if (x == 0)
02507 return;
02508
02509 code = GET_CODE (x);
02510
02511
02512
02513
02514 switch (code)
02515 {
02516 case REG:
02517 case CONST_INT:
02518 case CONST_DOUBLE:
02519 case CONST_VECTOR:
02520 case SYMBOL_REF:
02521 case CODE_LABEL:
02522 case PC:
02523 case CC0:
02524 return;
02525
02526 case INSN:
02527 case JUMP_INSN:
02528 case CALL_INSN:
02529 case NOTE:
02530 case LABEL_REF:
02531 case BARRIER:
02532
02533 return;
02534
02535 default:
02536 break;
02537 }
02538
02539 RTX_FLAG (x, used) = 0;
02540
02541 format_ptr = GET_RTX_FORMAT (code);
02542 length = GET_RTX_LENGTH (code);
02543
02544 for (i = 0; i < length; i++)
02545 {
02546 switch (*format_ptr++)
02547 {
02548 case 'e':
02549 if (i == length-1)
02550 {
02551 x = XEXP (x, i);
02552 goto repeat;
02553 }
02554 reset_used_flags (XEXP (x, i));
02555 break;
02556
02557 case 'E':
02558 for (j = 0; j < XVECLEN (x, i); j++)
02559 reset_used_flags (XVECEXP (x, i, j));
02560 break;
02561 }
02562 }
02563 }
02564
02565
02566
02567
02568 void
02569 set_used_flags (rtx x)
02570 {
02571 int i, j;
02572 enum rtx_code code;
02573 const char *format_ptr;
02574
02575 if (x == 0)
02576 return;
02577
02578 code = GET_CODE (x);
02579
02580
02581
02582
02583 switch (code)
02584 {
02585 case REG:
02586 case CONST_INT:
02587 case CONST_DOUBLE:
02588 case CONST_VECTOR:
02589 case SYMBOL_REF:
02590 case CODE_LABEL:
02591 case PC:
02592 case CC0:
02593 return;
02594
02595 case INSN:
02596 case JUMP_INSN:
02597 case CALL_INSN:
02598 case NOTE:
02599 case LABEL_REF:
02600 case BARRIER:
02601
02602 return;
02603
02604 default:
02605 break;
02606 }
02607
02608 RTX_FLAG (x, used) = 1;
02609
02610 format_ptr = GET_RTX_FORMAT (code);
02611 for (i = 0; i < GET_RTX_LENGTH (code); i++)
02612 {
02613 switch (*format_ptr++)
02614 {
02615 case 'e':
02616 set_used_flags (XEXP (x, i));
02617 break;
02618
02619 case 'E':
02620 for (j = 0; j < XVECLEN (x, i); j++)
02621 set_used_flags (XVECEXP (x, i, j));
02622 break;
02623 }
02624 }
02625 }
02626
02627
02628
02629
02630
02631 rtx
02632 make_safe_from (rtx x, rtx other)
02633 {
02634 while (1)
02635 switch (GET_CODE (other))
02636 {
02637 case SUBREG:
02638 other = SUBREG_REG (other);
02639 break;
02640 case STRICT_LOW_PART:
02641 case SIGN_EXTEND:
02642 case ZERO_EXTEND:
02643 other = XEXP (other, 0);
02644 break;
02645 default:
02646 goto done;
02647 }
02648 done:
02649 if ((MEM_P (other)
02650 && ! CONSTANT_P (x)
02651 && !REG_P (x)
02652 && GET_CODE (x) != SUBREG)
02653 || (REG_P (other)
02654 && (REGNO (other) < FIRST_PSEUDO_REGISTER
02655 || reg_mentioned_p (other, x))))
02656 {
02657 rtx temp = gen_reg_rtx (GET_MODE (x));
02658 emit_move_insn (temp, x);
02659 return temp;
02660 }
02661 return x;
02662 }
02663
02664
02665
02666
02667
02668 rtx
02669 get_insns (void)
02670 {
02671 return first_insn;
02672 }
02673
02674
02675
02676 void
02677 set_first_insn (rtx insn)
02678 {
02679 gcc_assert (!PREV_INSN (insn));
02680 first_insn = insn;
02681 }
02682
02683
02684
02685 rtx
02686 get_last_insn (void)
02687 {
02688 return last_insn;
02689 }
02690
02691
02692
02693 void
02694 set_last_insn (rtx insn)
02695 {
02696 gcc_assert (!NEXT_INSN (insn));
02697 last_insn = insn;
02698 }
02699
02700
02701
02702 rtx
02703 get_last_insn_anywhere (void)
02704 {
02705 struct sequence_stack *stack;
02706 if (last_insn)
02707 return last_insn;
02708 for (stack = seq_stack; stack; stack = stack->next)
02709 if (stack->last != 0)
02710 return stack->last;
02711 return 0;
02712 }
02713
02714
02715
02716
02717 rtx
02718 get_first_nonnote_insn (void)
02719 {
02720 rtx insn = first_insn;
02721
02722 if (insn)
02723 {
02724 if (NOTE_P (insn))
02725 for (insn = next_insn (insn);
02726 insn && NOTE_P (insn);
02727 insn = next_insn (insn))
02728 continue;
02729 else
02730 {
02731 if (GET_CODE (insn) == INSN
02732 && GET_CODE (PATTERN (insn)) == SEQUENCE)
02733 insn = XVECEXP (PATTERN (insn), 0, 0);
02734 }
02735 }
02736
02737 return insn;
02738 }
02739
02740
02741
02742
02743 rtx
02744 get_last_nonnote_insn (void)
02745 {
02746 rtx insn = last_insn;
02747
02748 if (insn)
02749 {
02750 if (NOTE_P (insn))
02751 for (insn = previous_insn (insn);
02752 insn && NOTE_P (insn);
02753 insn = previous_insn (insn))
02754 continue;
02755 else
02756 {
02757 if (GET_CODE (insn) == INSN
02758 && GET_CODE (PATTERN (insn)) == SEQUENCE)
02759 insn = XVECEXP (PATTERN (insn), 0,
02760 XVECLEN (PATTERN (insn), 0) - 1);
02761 }
02762 }
02763
02764 return insn;
02765 }
02766
02767
02768
02769 int
02770 get_max_uid (void)
02771 {
02772 return cur_insn_uid;
02773 }
02774
02775
02776
02777 void
02778 renumber_insns (FILE *stream)
02779 {
02780 rtx insn;
02781
02782
02783 if (!flag_renumber_insns)
02784 return;
02785
02786
02787
02788 if (flag_renumber_insns == 1 && get_max_uid () < 25000)
02789 return;
02790
02791 cur_insn_uid = 1;
02792
02793 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
02794 {
02795 if (stream)
02796 fprintf (stream, "Renumbering insn %d to %d\n",
02797 INSN_UID (insn), cur_insn_uid);
02798 INSN_UID (insn) = cur_insn_uid++;
02799 }
02800 }
02801
02802
02803
02804
02805 rtx
02806 next_insn (rtx insn)
02807 {
02808 if (insn)
02809 {
02810 insn = NEXT_INSN (insn);
02811 if (insn && NONJUMP_INSN_P (insn)
02812 && GET_CODE (PATTERN (insn)) == SEQUENCE)
02813 insn = XVECEXP (PATTERN (insn), 0, 0);
02814 }
02815
02816 return insn;
02817 }
02818
02819
02820
02821
02822 rtx
02823 previous_insn (rtx insn)
02824 {
02825 if (insn)
02826 {
02827 insn = PREV_INSN (insn);
02828 if (insn && NONJUMP_INSN_P (insn)
02829 && GET_CODE (PATTERN (insn)) == SEQUENCE)
02830 insn = XVECEXP (PATTERN (insn), 0, XVECLEN (PATTERN (insn), 0) - 1);
02831 }
02832
02833 return insn;
02834 }
02835
02836
02837
02838
02839 rtx
02840 next_nonnote_insn (rtx insn)
02841 {
02842 while (insn)
02843 {
02844 insn = NEXT_INSN (insn);
02845 if (insn == 0 || !NOTE_P (insn))
02846 break;
02847 }
02848
02849 return insn;
02850 }
02851
02852
02853
02854
02855 rtx
02856 prev_nonnote_insn (rtx insn)
02857 {
02858 while (insn)
02859 {
02860 insn = PREV_INSN (insn);
02861 if (insn == 0 || !NOTE_P (insn))
02862 break;
02863 }
02864
02865 return insn;
02866 }
02867
02868
02869
02870
02871
02872 rtx
02873 next_real_insn (rtx insn)
02874 {
02875 while (insn)
02876 {
02877 insn = NEXT_INSN (insn);
02878 if (insn == 0 || INSN_P (insn))
02879 break;
02880 }
02881
02882 return insn;
02883 }
02884
02885
02886
02887
02888
02889 rtx
02890 prev_real_insn (rtx insn)
02891 {
02892 while (insn)
02893 {
02894 insn = PREV_INSN (insn);
02895 if (insn == 0 || INSN_P (insn))
02896 break;
02897 }
02898
02899 return insn;
02900 }
02901
02902
02903
02904
02905 rtx
02906 last_call_insn (void)
02907 {
02908 rtx insn;
02909
02910 for (insn = get_last_insn ();
02911 insn && !CALL_P (insn);
02912 insn = PREV_INSN (insn))
02913 ;
02914
02915 return insn;
02916 }
02917
02918
02919
02920
02921
02922 int
02923 active_insn_p (rtx insn)
02924 {
02925 return (CALL_P (insn) || JUMP_P (insn)
02926 || (NONJUMP_INSN_P (insn)
02927 && (! reload_completed
02928 || (GET_CODE (PATTERN (insn)) != USE
02929 && GET_CODE (PATTERN (insn)) != CLOBBER))));
02930 }
02931
02932 rtx
02933 next_active_insn (rtx insn)
02934 {
02935 while (insn)
02936 {
02937 insn = NEXT_INSN (insn);
02938 if (insn == 0 || active_insn_p (insn))
02939 break;
02940 }
02941
02942 return insn;
02943 }
02944
02945
02946
02947
02948
02949 rtx
02950 prev_active_insn (rtx insn)
02951 {
02952 while (insn)
02953 {
02954 insn = PREV_INSN (insn);
02955 if (insn == 0 || active_insn_p (insn))
02956 break;
02957 }
02958
02959 return insn;
02960 }
02961
02962
02963
02964 rtx
02965 next_label (rtx insn)
02966 {
02967 while (insn)
02968 {
02969 insn = NEXT_INSN (insn);
02970 if (insn == 0 || LABEL_P (insn))
02971 break;
02972 }
02973
02974 return insn;
02975 }
02976
02977
02978
02979 rtx
02980 prev_label (rtx insn)
02981 {
02982 while (insn)
02983 {
02984 insn = PREV_INSN (insn);
02985 if (insn == 0 || LABEL_P (insn))
02986 break;
02987 }
02988
02989 return insn;
02990 }
02991
02992
02993
02994
02995 rtx
02996 skip_consecutive_labels (rtx label)
02997 {
02998 rtx insn;
02999
03000 for (insn = label; insn != 0 && !INSN_P (insn); insn = NEXT_INSN (insn))
03001 if (LABEL_P (insn))
03002 label = insn;
03003
03004 return label;
03005 }
03006
03007 #ifdef HAVE_cc0
03008
03009
03010
03011 void
03012 link_cc0_insns (rtx insn)
03013 {
03014 rtx user = next_nonnote_insn (insn);
03015
03016 if (NONJUMP_INSN_P (user) && GET_CODE (PATTERN (user)) == SEQUENCE)
03017 user = XVECEXP (PATTERN (user), 0, 0);
03018
03019 REG_NOTES (user) = gen_rtx_INSN_LIST (REG_CC_SETTER, insn,
03020 REG_NOTES (user));
03021 REG_NOTES (insn) = gen_rtx_INSN_LIST (REG_CC_USER, user, REG_NOTES (insn));
03022 }
03023
03024
03025
03026
03027
03028
03029
03030
03031
03032
03033 rtx
03034 next_cc0_user (rtx insn)
03035 {
03036 rtx note = find_reg_note (insn, REG_CC_USER, NULL_RTX);
03037
03038 if (note)
03039 return XEXP (note, 0);
03040
03041 insn = next_nonnote_insn (insn);
03042 if (insn && NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE)
03043 insn = XVECEXP (PATTERN (insn), 0, 0);
03044
03045 if (insn && INSN_P (insn) && reg_mentioned_p (cc0_rtx, PATTERN (insn)))
03046 return insn;
03047
03048 return 0;
03049 }
03050
03051
03052
03053
03054 rtx
03055 prev_cc0_setter (rtx insn)
03056 {
03057 rtx note = find_reg_note (insn, REG_CC_SETTER, NULL_RTX);
03058
03059 if (note)
03060 return XEXP (note, 0);
03061
03062 insn = prev_nonnote_insn (insn);
03063 gcc_assert (sets_cc0_p (PATTERN (insn)));
03064
03065 return insn;
03066 }
03067 #endif
03068
03069
03070
03071 static void
03072 mark_label_nuses (rtx x)
03073 {
03074 enum rtx_code code;
03075 int i, j;
03076 const char *fmt;
03077
03078 code = GET_CODE (x);
03079 if (code == LABEL_REF && LABEL_P (XEXP (x, 0)))
03080 LABEL_NUSES (XEXP (x, 0))++;
03081
03082 fmt = GET_RTX_FORMAT (code);
03083 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
03084 {
03085 if (fmt[i] == 'e')
03086 mark_label_nuses (XEXP (x, i));
03087 else if (fmt[i] == 'E')
03088 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
03089 mark_label_nuses (XVECEXP (x, i, j));
03090 }
03091 }
03092
03093
03094
03095
03096
03097
03098
03099
03100
03101
03102
03103 rtx
03104 try_split (rtx pat, rtx trial, int last)
03105 {
03106 rtx before = PREV_INSN (trial);
03107 rtx after = NEXT_INSN (trial);
03108 int has_barrier = 0;
03109 rtx tem;
03110 rtx note, seq;
03111 int probability;
03112 rtx insn_last, insn;
03113 int njumps = 0;
03114
03115 if (any_condjump_p (trial)
03116 && (note = find_reg_note (trial, REG_BR_PROB, 0)))
03117 split_branch_probability = INTVAL (XEXP (note, 0));
03118 probability = split_branch_probability;
03119
03120 seq = split_insns (pat, trial);
03121
03122 split_branch_probability = -1;
03123
03124
03125
03126 if (after && BARRIER_P (after))
03127 {
03128 has_barrier = 1;
03129 after = NEXT_INSN (after);
03130 }
03131
03132 if (!seq)
03133 return trial;
03134
03135
03136
03137 insn_last = seq;
03138 while (1)
03139 {
03140 if (INSN_P (insn_last)
03141 && rtx_equal_p (PATTERN (insn_last), pat))
03142 return trial;
03143 if (!NEXT_INSN (insn_last))
03144 break;
03145 insn_last = NEXT_INSN (insn_last);
03146 }
03147
03148
03149 for (insn = insn_last; insn ; insn = PREV_INSN (insn))
03150 {
03151 if (JUMP_P (insn))
03152 {
03153 mark_jump_label (PATTERN (insn), insn, 0);
03154 njumps++;
03155 if (probability != -1
03156 && any_condjump_p (insn)
03157 && !find_reg_note (insn, REG_BR_PROB, 0))
03158 {
03159
03160
03161
03162
03163 gcc_assert (njumps == 1);
03164 REG_NOTES (insn)
03165 = gen_rtx_EXPR_LIST (REG_BR_PROB,
03166 GEN_INT (probability),
03167 REG_NOTES (insn));
03168 }
03169 }
03170 }
03171
03172
03173
03174 if (CALL_P (trial))
03175 {
03176 for (insn = insn_last; insn ; insn = PREV_INSN (insn))
03177 if (CALL_P (insn))
03178 {
03179 rtx *p = &CALL_INSN_FUNCTION_USAGE (insn);
03180 while (*p)
03181 p = &XEXP (*p, 1);
03182 *p = CALL_INSN_FUNCTION_USAGE (trial);
03183 SIBLING_CALL_P (insn) = SIBLING_CALL_P (trial);
03184 }
03185 }
03186
03187
03188 for (note = REG_NOTES (trial); note; note = XEXP (note, 1))
03189 {
03190 switch (REG_NOTE_KIND (note))
03191 {
03192 case REG_EH_REGION:
03193 insn = insn_last;
03194 while (insn != NULL_RTX)
03195 {
03196 if (CALL_P (insn)
03197 || (flag_non_call_exceptions && INSN_P (insn)
03198 && may_trap_p (PATTERN (insn))))
03199 REG_NOTES (insn)
03200 = gen_rtx_EXPR_LIST (REG_EH_REGION,
03201 XEXP (note, 0),
03202 REG_NOTES (insn));
03203 insn = PREV_INSN (insn);
03204 }
03205 break;
03206
03207 case REG_NORETURN:
03208 case REG_SETJMP:
03209 case REG_ALWAYS_RETURN:
03210 insn = insn_last;
03211 while (insn != NULL_RTX)
03212 {
03213 if (CALL_P (insn))
03214 REG_NOTES (insn)
03215 = gen_rtx_EXPR_LIST (REG_NOTE_KIND (note),
03216 XEXP (note, 0),
03217 REG_NOTES (insn));
03218 insn = PREV_INSN (insn);
03219 }
03220 break;
03221
03222 case REG_NON_LOCAL_GOTO:
03223 insn = insn_last;
03224 while (insn != NULL_RTX)
03225 {
03226 if (JUMP_P (insn))
03227 REG_NOTES (insn)
03228 = gen_rtx_EXPR_LIST (REG_NOTE_KIND (note),
03229 XEXP (note, 0),
03230 REG_NOTES (insn));
03231 insn = PREV_INSN (insn);
03232 }
03233 break;
03234
03235 default:
03236 break;
03237 }
03238 }
03239
03240
03241
03242 if (NONJUMP_INSN_P (trial))
03243 {
03244 insn = insn_last;
03245 while (insn != NULL_RTX)
03246 {
03247 if (NONJUMP_INSN_P (insn))
03248 mark_label_nuses (PATTERN (insn));
03249
03250 insn = PREV_INSN (insn);
03251 }
03252 }
03253
03254 tem = emit_insn_after_setloc (seq, trial, INSN_LOCATOR (trial));
03255
03256 delete_insn (trial);
03257 if (has_barrier)
03258 emit_barrier_after (tem);
03259
03260
03261
03262
03263
03264
03265 for (tem = NEXT_INSN (before); tem != after; tem = NEXT_INSN (tem))
03266 if (! INSN_DELETED_P (tem) && INSN_P (tem))
03267 tem = try_split (PATTERN (tem), tem, 1);
03268
03269
03270
03271 return last
03272 ? (after ? PREV_INSN (after) : last_insn)
03273 : NEXT_INSN (before);
03274 }
03275
03276
03277
03278
03279 rtx
03280 make_insn_raw (rtx pattern)
03281 {
03282 rtx insn;
03283
03284 insn = rtx_alloc (INSN);
03285
03286 INSN_UID (insn) = cur_insn_uid++;
03287 PATTERN (insn) = pattern;
03288 INSN_CODE (insn) = -1;
03289 LOG_LINKS (insn) = NULL;
03290 REG_NOTES (insn) = NULL;
03291 INSN_LOCATOR (insn) = 0;
03292 BLOCK_FOR_INSN (insn) = NULL;
03293
03294 #ifdef ENABLE_RTL_CHECKING
03295 if (insn
03296 && INSN_P (insn)
03297 && (returnjump_p (insn)
03298 || (GET_CODE (insn) == SET
03299 && SET_DEST (insn) == pc_rtx)))
03300 {
03301 warning ("ICE: emit_insn used where emit_jump_insn needed:\n");
03302 debug_rtx (insn);
03303 }
03304 #endif
03305
03306 return insn;
03307 }
03308
03309
03310
03311 static rtx
03312 make_jump_insn_raw (rtx pattern)
03313 {
03314 rtx insn;
03315
03316 insn = rtx_alloc (JUMP_INSN);
03317 INSN_UID (insn) = cur_insn_uid++;
03318
03319 PATTERN (insn) = pattern;
03320 INSN_CODE (insn) = -1;
03321 LOG_LINKS (insn) = NULL;
03322 REG_NOTES (insn) = NULL;
03323 JUMP_LABEL (insn) = NULL;
03324 INSN_LOCATOR (insn) = 0;
03325 BLOCK_FOR_INSN (insn) = NULL;
03326
03327 return insn;
03328 }
03329
03330
03331
03332 static rtx
03333 make_call_insn_raw (rtx pattern)
03334 {
03335 rtx insn;
03336
03337 insn = rtx_alloc (CALL_INSN);
03338 INSN_UID (insn) = cur_insn_uid++;
03339
03340 PATTERN (insn) = pattern;
03341 INSN_CODE (insn) = -1;
03342 LOG_LINKS (insn) = NULL;
03343 REG_NOTES (insn) = NULL;
03344 CALL_INSN_FUNCTION_USAGE (insn) = NULL;
03345 INSN_LOCATOR (insn) = 0;
03346 BLOCK_FOR_INSN (insn) = NULL;
03347
03348 return insn;
03349 }
03350
03351
03352
03353
03354 void
03355 add_insn (rtx insn)
03356 {
03357 PREV_INSN (insn) = last_insn;
03358 NEXT_INSN (insn) = 0;
03359
03360 if (NULL != last_insn)
03361 NEXT_INSN (last_insn) = insn;
03362
03363 if (NULL == first_insn)
03364 first_insn = insn;
03365
03366 last_insn = insn;
03367 }
03368
03369
03370
03371
03372
03373
03374 void
03375 add_insn_after (rtx insn, rtx after)
03376 {
03377 rtx next = NEXT_INSN (after);
03378 basic_block bb;
03379
03380 gcc_assert (!optimize || !INSN_DELETED_P (after));
03381
03382 NEXT_INSN (insn) = next;
03383 PREV_INSN (insn) = after;
03384
03385 if (next)
03386 {
03387 PREV_INSN (next) = insn;
03388 if (NONJUMP_INSN_P (next) && GET_CODE (PATTERN (next)) == SEQUENCE)
03389 PREV_INSN (XVECEXP (PATTERN (next), 0, 0)) = insn;
03390 }
03391 else if (last_insn == after)
03392 last_insn = insn;
03393 else
03394 {
03395 struct sequence_stack *stack = seq_stack;
03396
03397 for (; stack; stack = stack->next)
03398 if (after == stack->last)
03399 {
03400 stack->last = insn;
03401 break;
03402 }
03403
03404 gcc_assert (stack);
03405 }
03406
03407 if (!BARRIER_P (after)
03408 && !BARRIER_P (insn)
03409 && (bb = BLOCK_FOR_INSN (after)))
03410 {
03411 set_block_for_insn (insn, bb);
03412 if (INSN_P (insn))
03413 bb->flags |= BB_DIRTY;
03414
03415
03416 if (BB_END (bb) == after
03417
03418 && !BARRIER_P (insn)
03419 && (!NOTE_P (insn)
03420 || NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK))
03421 BB_END (bb) = insn;
03422 }
03423
03424 NEXT_INSN (after) = insn;
03425 if (NONJUMP_INSN_P (after) && GET_CODE (PATTERN (after)) == SEQUENCE)
03426 {
03427 rtx sequence = PATTERN (after);
03428 NEXT_INSN (XVECEXP (sequence, 0, XVECLEN (sequence, 0) - 1)) = insn;
03429 }
03430 }
03431
03432
03433
03434
03435
03436
03437 void
03438 add_insn_before (rtx insn, rtx before)
03439 {
03440 rtx prev = PREV_INSN (before);
03441 basic_block bb;
03442
03443 gcc_assert (!optimize || !INSN_DELETED_P (before));
03444
03445 PREV_INSN (insn) = prev;
03446 NEXT_INSN (insn) = before;
03447
03448 if (prev)
03449 {
03450 NEXT_INSN (prev) = insn;
03451 if (NONJUMP_INSN_P (prev) && GET_CODE (PATTERN (prev)) == SEQUENCE)
03452 {
03453 rtx sequence = PATTERN (prev);
03454 NEXT_INSN (XVECEXP (sequence, 0, XVECLEN (sequence, 0) - 1)) = insn;
03455 }
03456 }
03457 else if (first_insn == before)
03458 first_insn = insn;
03459 else
03460 {
03461 struct sequence_stack *stack = seq_stack;
03462
03463 for (; stack; stack = stack->next)
03464 if (before == stack->first)
03465 {
03466 stack->first = insn;
03467 break;
03468 }
03469
03470 gcc_assert (stack);
03471 }
03472
03473 if (!BARRIER_P (before)
03474 && !BARRIER_P (insn)
03475 && (bb = BLOCK_FOR_INSN (before)))
03476 {
03477 set_block_for_insn (insn, bb);
03478 if (INSN_P (insn))
03479 bb->flags |= BB_DIRTY;
03480
03481
03482 gcc_assert (BB_HEAD (bb) != insn
03483
03484 || BARRIER_P (insn)
03485 || (NOTE_P (insn)
03486 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_BASIC_BLOCK));
03487 }
03488
03489 PREV_INSN (before) = insn;
03490 if (NONJUMP_INSN_P (before) && GET_CODE (PATTERN (before)) == SEQUENCE)
03491 PREV_INSN (XVECEXP (PATTERN (before), 0, 0)) = insn;
03492 }
03493
03494
03495
03496 void
03497 remove_insn (rtx insn)
03498 {
03499 rtx next = NEXT_INSN (insn);
03500 rtx prev = PREV_INSN (insn);
03501 basic_block bb;
03502
03503 if (prev)
03504 {
03505 NEXT_INSN (prev) = next;
03506 if (NONJUMP_INSN_P (prev) && GET_CODE (PATTERN (prev)) == SEQUENCE)
03507 {
03508 rtx sequence = PATTERN (prev);
03509 NEXT_INSN (XVECEXP (sequence, 0, XVECLEN (sequence, 0) - 1)) = next;
03510 }
03511 }
03512 else if (first_insn == insn)
03513 first_insn = next;
03514 else
03515 {
03516 struct sequence_stack *stack = seq_stack;
03517
03518 for (; stack; stack = stack->next)
03519 if (insn == stack->first)
03520 {
03521 stack->first = next;
03522 break;
03523 }
03524
03525 gcc_assert (stack);
03526 }
03527
03528 if (next)
03529 {
03530 PREV_INSN (next) = prev;
03531 if (NONJUMP_INSN_P (next) && GET_CODE (PATTERN (next)) == SEQUENCE)
03532 PREV_INSN (XVECEXP (PATTERN (next), 0, 0)) = prev;
03533 }
03534 else if (last_insn == insn)
03535 last_insn = prev;
03536 else
03537 {
03538 struct sequence_stack *stack = seq_stack;
03539
03540 for (; stack; stack = stack->next)
03541 if (insn == stack->last)
03542 {
03543 stack->last = prev;
03544 break;
03545 }
03546
03547 gcc_assert (stack);
03548 }
03549 if (!BARRIER_P (insn)
03550 && (bb = BLOCK_FOR_INSN (insn)))
03551 {
03552 if (INSN_P (insn))
03553 bb->flags |= BB_DIRTY;
03554 if (BB_HEAD (bb) == insn)
03555 {
03556
03557
03558 gcc_assert (!NOTE_P (insn));
03559 BB_HEAD (bb) = next;
03560 }
03561 if (BB_END (bb) == insn)
03562 BB_END (bb) = prev;
03563 }
03564 }
03565
03566
03567
03568 void
03569 add_function_usage_to (rtx call_insn, rtx call_fusage)
03570 {
03571 gcc_assert (call_insn && CALL_P (call_insn));
03572
03573
03574
03575 if (CALL_INSN_FUNCTION_USAGE (call_insn))
03576 {
03577 rtx link;
03578
03579 for (link = CALL_INSN_FUNCTION_USAGE (call_insn); XEXP (link, 1) != 0;
03580 link = XEXP (link, 1))
03581 ;
03582
03583 XEXP (link, 1) = call_fusage;
03584 }
03585 else
03586 CALL_INSN_FUNCTION_USAGE (call_insn) = call_fusage;
03587 }
03588
03589
03590
03591
03592 void
03593 delete_insns_since (rtx from)
03594 {
03595 if (from == 0)
03596 first_insn = 0;
03597 else
03598 NEXT_INSN (from) = 0;
03599 last_insn = from;
03600 }
03601
03602
03603
03604
03605
03606
03607
03608
03609
03610
03611
03612 void
03613 reorder_insns_nobb (rtx from, rtx to, rtx after)
03614 {
03615
03616 if (PREV_INSN (from))
03617 NEXT_INSN (PREV_INSN (from)) = NEXT_INSN (to);
03618 if (NEXT_INSN (to))
03619 PREV_INSN (NEXT_INSN (to)) = PREV_INSN (from);
03620 if (last_insn == to)
03621 last_insn = PREV_INSN (from);
03622 if (first_insn == from)
03623 first_insn = NEXT_INSN (to);
03624
03625
03626 if (NEXT_INSN (after))
03627 PREV_INSN (NEXT_INSN (after)) = to;
03628
03629 NEXT_INSN (to) = NEXT_INSN (after);
03630 PREV_INSN (from) = after;
03631 NEXT_INSN (after) = from;
03632 if (after == last_insn)
03633 last_insn = to;
03634 }
03635
03636
03637 void
03638 reorder_insns (rtx from, rtx to, rtx after)
03639 {
03640 rtx prev = PREV_INSN (from);
03641 basic_block bb, bb2;
03642
03643 reorder_insns_nobb (from, to, after);
03644
03645 if (!BARRIER_P (after)
03646 && (bb = BLOCK_FOR_INSN (after)))
03647 {
03648 rtx x;
03649 bb->flags |= BB_DIRTY;
03650
03651 if (!BARRIER_P (from)
03652 && (bb2 = BLOCK_FOR_INSN (from)))
03653 {
03654 if (BB_END (bb2) == to)
03655 BB_END (bb2) = prev;
03656 bb2->flags |= BB_DIRTY;
03657 }
03658
03659 if (BB_END (bb) == after)
03660 BB_END (bb) = to;
03661
03662 for (x = from; x != NEXT_INSN (to); x = NEXT_INSN (x))
03663 if (!BARRIER_P (x))
03664 set_block_for_insn (x, bb);
03665 }
03666 }
03667
03668
03669
03670 static rtx
03671 find_line_note (rtx insn)
03672 {
03673 if (no_line_numbers)
03674 return 0;
03675
03676 for (; insn; insn = PREV_INSN (insn))
03677 if (NOTE_P (insn)
03678 && NOTE_LINE_NUMBER (insn) >= 0)
03679 break;
03680
03681 return insn;
03682 }
03683
03684
03685
03686 void
03687 remove_unnecessary_notes (void)
03688 {
03689 rtx eh_stack = NULL_RTX;
03690 rtx insn;
03691 rtx next;
03692 rtx tmp;
03693
03694
03695
03696 for (insn = NEXT_INSN (get_insns ()); insn; insn = next)
03697 {
03698
03699 next = NEXT_INSN (insn);
03700
03701
03702 if (!NOTE_P (insn))
03703 continue;
03704
03705 switch (NOTE_LINE_NUMBER (insn))
03706 {
03707 case NOTE_INSN_DELETED:
03708 remove_insn (insn);
03709 break;
03710
03711 case NOTE_INSN_EH_REGION_BEG:
03712 eh_stack = alloc_INSN_LIST (insn, eh_stack);
03713 break;
03714
03715 case NOTE_INSN_EH_REGION_END:
03716
03717 gcc_assert (eh_stack);
03718
03719 gcc_assert (NOTE_EH_HANDLER (XEXP (eh_stack, 0))
03720 == NOTE_EH_HANDLER (insn));
03721 tmp = eh_stack;
03722 eh_stack = XEXP (eh_stack, 1);
03723 free_INSN_LIST_node (tmp);
03724 break;
03725
03726 case NOTE_INSN_BLOCK_BEG:
03727 case NOTE_INSN_BLOCK_END:
03728
03729 gcc_unreachable ();
03730
03731 default:
03732 break;
03733 }
03734 }
03735
03736
03737 gcc_assert (!eh_stack);
03738 }
03739
03740
03741
03742
03743
03744
03745
03746
03747
03748
03749
03750
03751
03752
03753
03754
03755
03756
03757
03758
03759
03760
03761
03762
03763
03764
03765
03766
03767
03768 rtx
03769 emit_insn_before_noloc (rtx x, rtx before)
03770 {
03771 rtx last = before;
03772 rtx insn;
03773
03774 gcc_assert (before);
03775
03776 if (x == NULL_RTX)
03777 return last;
03778
03779 switch (GET_CODE (x))
03780 {
03781 case INSN:
03782 case JUMP_INSN:
03783 case CALL_INSN:
03784 case CODE_LABEL:
03785 case BARRIER:
03786 case NOTE:
03787 insn = x;
03788 while (insn)
03789 {
03790 rtx next = NEXT_INSN (insn);
03791 add_insn_before (insn, before);
03792 last = insn;
03793 insn = next;
03794 }
03795 break;
03796
03797 #ifdef ENABLE_RTL_CHECKING
03798 case SEQUENCE:
03799 gcc_unreachable ();
03800 break;
03801 #endif
03802
03803 default:
03804 last = make_insn_raw (x);
03805 add_insn_before (last, before);
03806 break;
03807 }
03808
03809 return last;
03810 }
03811
03812
03813
03814
03815 rtx
03816 emit_jump_insn_before_noloc (rtx x, rtx before)
03817 {
03818 rtx insn, last = NULL_RTX;
03819
03820 gcc_assert (before);
03821
03822 switch (GET_CODE (x))
03823 {
03824 case INSN:
03825 case JUMP_INSN:
03826 case CALL_INSN:
03827 case CODE_LABEL:
03828 case BARRIER:
03829 case NOTE:
03830 insn = x;
03831 while (insn)
03832 {
03833 rtx next = NEXT_INSN (insn);
03834 add_insn_before (insn, before);
03835 last = insn;
03836 insn = next;
03837 }
03838 break;
03839
03840 #ifdef ENABLE_RTL_CHECKING
03841 case SEQUENCE:
03842 gcc_unreachable ();
03843 break;
03844 #endif
03845
03846 default:
03847 last = make_jump_insn_raw (x);
03848 add_insn_before (last, before);
03849 break;
03850 }
03851
03852 return last;
03853 }
03854
03855
03856
03857
03858 rtx
03859 emit_call_insn_before_noloc (rtx x, rtx before)
03860 {
03861 rtx last = NULL_RTX, insn;
03862
03863 gcc_assert (before);
03864
03865 switch (GET_CODE (x))
03866 {
03867 case INSN:
03868 case JUMP_INSN:
03869 case CALL_INSN:
03870 case CODE_LABEL:
03871 case BARRIER:
03872 case NOTE:
03873 insn = x;
03874 while (insn)
03875 {
03876 rtx next = NEXT_INSN (insn);
03877 add_insn_before (insn, before);
03878 last = insn;
03879 insn = next;
03880 }
03881 break;
03882
03883 #ifdef ENABLE_RTL_CHECKING
03884 case SEQUENCE:
03885 gcc_unreachable ();
03886 break;
03887 #endif
03888
03889 default:
03890 last = make_call_insn_raw (x);
03891 add_insn_before (last, before);
03892 break;
03893 }
03894
03895 return last;
03896 }
03897
03898
03899
03900
03901 rtx
03902 emit_barrier_before (rtx before)
03903 {
03904 rtx insn = rtx_alloc (BARRIER);
03905
03906 INSN_UID (insn) = cur_insn_uid++;
03907
03908 add_insn_before (insn, before);
03909 return insn;
03910 }
03911
03912
03913
03914 rtx
03915 emit_label_before (rtx label, rtx before)
03916 {
03917
03918
03919 if (INSN_UID (label) == 0)
03920 {
03921 INSN_UID (label) = cur_insn_uid++;
03922 add_insn_before (label, before);
03923 }
03924
03925 return label;
03926 }
03927
03928
03929
03930 rtx
03931 emit_note_before (int subtype, rtx before)
03932 {
03933 rtx note = rtx_alloc (NOTE);
03934 INSN_UID (note) = cur_insn_uid++;
03935 #ifndef USE_MAPPED_LOCATION
03936 NOTE_SOURCE_FILE (note) = 0;
03937 #endif
03938 NOTE_LINE_NUMBER (note) = subtype;
03939 BLOCK_FOR_INSN (note) = NULL;
03940
03941 add_insn_before (note, before);
03942 return note;
03943 }
03944
03945
03946
03947
03948 static rtx emit_insn_after_1 (rtx, rtx);
03949
03950 static rtx
03951 emit_insn_after_1 (rtx first, rtx after)
03952 {
03953 rtx last;
03954 rtx after_after;
03955 basic_block bb;
03956
03957 if (!BARRIER_P (after)
03958 && (bb = BLOCK_FOR_INSN (after)))
03959 {
03960 bb->flags |= BB_DIRTY;
03961 for (last = first; NEXT_INSN (last); last = NEXT_INSN (last))
03962 if (!BARRIER_P (last))
03963 set_block_for_insn (last, bb);
03964 if (!BARRIER_P (last))
03965 set_block_for_insn (last, bb);
03966 if (BB_END (bb) == after)
03967 BB_END (bb) = last;
03968 }
03969 else
03970 for (last = first; NEXT_INSN (last); last = NEXT_INSN (last))
03971 continue;
03972
03973 after_after = NEXT_INSN (after);
03974
03975 NEXT_INSN (after) = first;
03976 PREV_INSN (first) = after;
03977 NEXT_INSN (last) = after_after;
03978 if (after_after)
03979 PREV_INSN (after_after) = last;
03980
03981 if (after == last_insn)
03982 last_insn = last;
03983 return last;
03984 }
03985
03986
03987
03988 rtx
03989 emit_insn_after_noloc (rtx x, rtx after)
03990 {
03991 rtx last = after;
03992
03993 gcc_assert (after);
03994
03995 if (x == NULL_RTX)
03996 return last;
03997
03998 switch (GET_CODE (x))
03999 {
04000 case INSN:
04001 case JUMP_INSN:
04002 case CALL_INSN:
04003 case CODE_LABEL:
04004 case BARRIER:
04005 case NOTE:
04006 last = emit_insn_after_1 (x, after);
04007 break;
04008
04009 #ifdef ENABLE_RTL_CHECKING
04010 case SEQUENCE:
04011 gcc_unreachable ();
04012 break;
04013 #endif
04014
04015 default:
04016 last = make_insn_raw (x);
04017 add_insn_after (last, after);
04018 break;
04019 }
04020
04021 return last;
04022 }
04023
04024
04025
04026
04027 void
04028 emit_insn_after_with_line_notes (rtx x, rtx after, rtx from)
04029 {
04030 rtx from_line = find_line_note (from);
04031 rtx after_line = find_line_note (after);
04032 rtx insn = emit_insn_after (x, after);
04033
04034 if (from_line)
04035 emit_note_copy_after (from_line, after);
04036
04037 if (after_line)
04038 emit_note_copy_after (after_line, insn);
04039 }
04040
04041
04042
04043
04044 rtx
04045 emit_jump_insn_after_noloc (rtx x, rtx after)
04046 {
04047 rtx last;
04048
04049 gcc_assert (after);
04050
04051 switch (GET_CODE (x))
04052 {
04053 case INSN:
04054 case JUMP_INSN:
04055 case CALL_INSN:
04056 case CODE_LABEL:
04057 case BARRIER:
04058 case NOTE:
04059 last = emit_insn_after_1 (x, after);
04060 break;
04061
04062 #ifdef ENABLE_RTL_CHECKING
04063 case SEQUENCE:
04064 gcc_unreachable ();
04065 break;
04066 #endif
04067
04068 default:
04069 last = make_jump_insn_raw (x);
04070 add_insn_after (last, after);
04071 break;
04072 }
04073
04074 return last;
04075 }
04076
04077
04078
04079
04080 rtx
04081 emit_call_insn_after_noloc (rtx x, rtx after)
04082 {
04083 rtx last;
04084
04085 gcc_assert (after);
04086
04087 switch (GET_CODE (x))
04088 {
04089 case INSN:
04090 case JUMP_INSN:
04091 case CALL_INSN:
04092 case CODE_LABEL:
04093 case BARRIER:
04094 case NOTE:
04095 last = emit_insn_after_1 (x, after);
04096 break;
04097
04098 #ifdef ENABLE_RTL_CHECKING
04099 case SEQUENCE:
04100 gcc_unreachable ();
04101 break;
04102 #endif
04103
04104 default:
04105 last = make_call_insn_raw (x);
04106 add_insn_after (last, after);
04107 break;
04108 }
04109
04110 return last;
04111 }
04112
04113
04114
04115
04116 rtx
04117 emit_barrier_after (rtx after)
04118 {
04119 rtx insn = rtx_alloc (BARRIER);
04120
04121 INSN_UID (insn) = cur_insn_uid++;
04122
04123 add_insn_after (insn, after);
04124 return insn;
04125 }
04126
04127
04128
04129 rtx
04130 emit_label_after (rtx label, rtx after)
04131 {
04132
04133
04134
04135 if (INSN_UID (label) == 0)
04136 {
04137 INSN_UID (label) = cur_insn_uid++;
04138 add_insn_after (label, after);
04139 }
04140
04141 return label;
04142 }
04143
04144
04145
04146 rtx
04147 emit_note_after (int subtype, rtx after)
04148 {
04149 rtx note = rtx_alloc (NOTE);
04150 INSN_UID (note) = cur_insn_uid++;
04151 #ifndef USE_MAPPED_LOCATION
04152 NOTE_SOURCE_FILE (note) = 0;
04153 #endif
04154 NOTE_LINE_NUMBER (note) = subtype;
04155 BLOCK_FOR_INSN (note) = NULL;
04156 add_insn_after (note, after);
04157 return note;
04158 }
04159
04160
04161
04162 rtx
04163 emit_note_copy_after (rtx orig, rtx after)
04164 {
04165 rtx note;
04166
04167 if (NOTE_LINE_NUMBER (orig) >= 0 && no_line_numbers)
04168 {
04169 cur_insn_uid++;
04170 return 0;
04171 }
04172
04173 note = rtx_alloc (NOTE);
04174 INSN_UID (note) = cur_insn_uid++;
04175 NOTE_LINE_NUMBER (note) = NOTE_LINE_NUMBER (orig);
04176 NOTE_DATA (note) = NOTE_DATA (orig);
04177 BLOCK_FOR_INSN (note) = NULL;
04178 add_insn_after (note, after);
04179 return note;
04180 }
04181
04182
04183 rtx
04184 emit_insn_after_setloc (rtx pattern, rtx after, int loc)
04185 {
04186 rtx last = emit_insn_after_noloc (pattern, after);
04187
04188 if (pattern == NULL_RTX || !loc)
04189 return last;
04190
04191 after = NEXT_INSN (after);
04192 while (1)
04193 {
04194 if (active_insn_p (after) && !INSN_LOCATOR (after))
04195 INSN_LOCATOR (after) = loc;
04196 if (after == last)
04197 break;
04198 after = NEXT_INSN (after);
04199 }
04200 return last;
04201 }
04202
04203
04204 rtx
04205 emit_insn_after (rtx pattern, rtx after)
04206 {
04207 if (INSN_P (after))
04208 return emit_insn_after_setloc (pattern, after, INSN_LOCATOR (after));
04209 else
04210 return emit_insn_after_noloc (pattern, after);
04211 }
04212
04213
04214 rtx
04215 emit_jump_insn_after_setloc (rtx pattern, rtx after, int loc)
04216 {
04217 rtx last = emit_jump_insn_after_noloc (pattern, after);
04218
04219 if (pattern == NULL_RTX || !loc)
04220 return last;
04221
04222 after = NEXT_INSN (after);
04223 while (1)
04224 {
04225 if (active_insn_p (after) && !INSN_LOCATOR (after))
04226 INSN_LOCATOR (after) = loc;
04227 if (after == last)
04228 break;
04229 after = NEXT_INSN (after);
04230 }
04231 return last;
04232 }
04233
04234
04235 rtx
04236 emit_jump_insn_after (rtx pattern, rtx after)
04237 {
04238 if (INSN_P (after))
04239 return emit_jump_insn_after_setloc (pattern, after, INSN_LOCATOR (after));
04240 else
04241 return emit_jump_insn_after_noloc (pattern, after);
04242 }
04243
04244
04245 rtx
04246 emit_call_insn_after_setloc (rtx pattern, rtx after, int loc)
04247 {
04248 rtx last = emit_call_insn_after_noloc (pattern, after);
04249
04250 if (pattern == NULL_RTX || !loc)
04251 return last;
04252
04253 after = NEXT_INSN (after);
04254 while (1)
04255 {
04256 if (active_insn_p (after) && !INSN_LOCATOR (after))
04257 INSN_LOCATOR (after) = loc;
04258 if (after == last)
04259 break;
04260 after = NEXT_INSN (after);
04261 }
04262 return last;
04263 }
04264
04265
04266 rtx
04267 emit_call_insn_after (rtx pattern, rtx after)
04268 {
04269 if (INSN_P (after))
04270 return emit_call_insn_after_setloc (pattern, after, INSN_LOCATOR (after));
04271 else
04272 return emit_call_insn_after_noloc (pattern, after);
04273 }
04274
04275
04276 rtx
04277 emit_insn_before_setloc (rtx pattern, rtx before, int loc)
04278 {
04279 rtx first = PREV_INSN (before);
04280 rtx last = emit_insn_before_noloc (pattern, before);
04281
04282 if (pattern == NULL_RTX || !loc)
04283 return last;
04284
04285 first = NEXT_INSN (first);
04286 while (1)
04287 {
04288 if (active_insn_p (first) && !INSN_LOCATOR (first))
04289 INSN_LOCATOR (first) = loc;
04290 if (first == last)
04291 break;
04292 first = NEXT_INSN (first);
04293 }
04294 return last;
04295 }
04296
04297
04298 rtx
04299 emit_insn_before (rtx pattern, rtx before)
04300 {
04301 if (INSN_P (before))
04302 return emit_insn_before_setloc (pattern, before, INSN_LOCATOR (before));
04303 else
04304 return emit_insn_before_noloc (pattern, before);
04305 }
04306
04307
04308 rtx
04309 emit_jump_insn_before_setloc (rtx pattern, rtx before, int loc)
04310 {
04311 rtx first = PREV_INSN (before);
04312 rtx last = emit_jump_insn_before_noloc (pattern, before);
04313
04314 if (pattern == NULL_RTX)
04315 return last;
04316
04317 first = NEXT_INSN (first);
04318 while (1)
04319 {
04320 if (active_insn_p (first) && !INSN_LOCATOR (first))
04321 INSN_LOCATOR (first) = loc;
04322 if (first == last)
04323 break;
04324 first = NEXT_INSN (first);
04325 }
04326 return last;
04327 }
04328
04329
04330 rtx
04331 emit_jump_insn_before (rtx pattern, rtx before)
04332 {
04333 if (INSN_P (before))
04334 return emit_jump_insn_before_setloc (pattern, before, INSN_LOCATOR (before));
04335 else
04336 return emit_jump_insn_before_noloc (pattern, before);
04337 }
04338
04339
04340 rtx
04341 emit_call_insn_before_setloc (rtx pattern, rtx before, int loc)
04342 {
04343 rtx first = PREV_INSN (before);
04344 rtx last = emit_call_insn_before_noloc (pattern, before);
04345
04346 if (pattern == NULL_RTX)
04347 return last;
04348
04349 first = NEXT_INSN (first);
04350 while (1)
04351 {
04352 if (active_insn_p (first) && !INSN_LOCATOR (first))
04353 INSN_LOCATOR (first) = loc;
04354 if (first == last)
04355 break;
04356 first = NEXT_INSN (first);
04357 }
04358 return last;
04359 }
04360
04361
04362
04363 rtx
04364 emit_call_insn_before (rtx pattern, rtx before)
04365 {
04366 if (INSN_P (before))
04367 return emit_call_insn_before_setloc (pattern, before, INSN_LOCATOR (before));
04368 else
04369 return emit_call_insn_before_noloc (pattern, before);
04370 }
04371
04372
04373
04374
04375
04376
04377 rtx
04378 emit_insn (rtx x)
04379 {
04380 rtx last = last_insn;
04381 rtx insn;
04382
04383 if (x == NULL_RTX)
04384 return last;
04385
04386 switch (GET_CODE (x))
04387 {
04388 case INSN:
04389 case JUMP_INSN:
04390 case CALL_INSN:
04391 case CODE_LABEL:
04392 case BARRIER:
04393 case NOTE:
04394 insn = x;
04395 while (insn)
04396 {
04397 rtx next = NEXT_INSN (insn);
04398 add_insn (insn);
04399 last = insn;
04400 insn = next;
04401 }
04402 break;
04403
04404 #ifdef ENABLE_RTL_CHECKING
04405 case SEQUENCE:
04406 gcc_unreachable ();
04407 break;
04408 #endif
04409
04410 default:
04411 last = make_insn_raw (x);
04412 add_insn (last);
04413 break;
04414 }
04415
04416 return last;
04417 }
04418
04419
04420
04421
04422 rtx
04423 emit_jump_insn (rtx x)
04424 {
04425 rtx last = NULL_RTX, insn;
04426
04427 switch (GET_CODE (x))
04428 {
04429 case INSN:
04430 case JUMP_INSN:
04431 case CALL_INSN:
04432 case CODE_LABEL:
04433 case BARRIER:
04434 case NOTE:
04435 insn = x;
04436 while (insn)
04437 {
04438 rtx next = NEXT_INSN (insn);
04439 add_insn (insn);
04440 last = insn;
04441 insn = next;
04442 }
04443 break;
04444
04445 #ifdef ENABLE_RTL_CHECKING
04446 case SEQUENCE:
04447 gcc_unreachable ();
04448 break;
04449 #endif
04450
04451 default:
04452 last = make_jump_insn_raw (x);
04453 add_insn (last);
04454 break;
04455 }
04456
04457 return last;
04458 }
04459
04460
04461
04462
04463 rtx
04464 emit_call_insn (rtx x)
04465 {
04466 rtx insn;
04467
04468 switch (GET_CODE (x))
04469 {
04470 case INSN:
04471 case JUMP_INSN:
04472 case CALL_INSN:
04473 case CODE_LABEL:
04474 case BARRIER:
04475 case NOTE:
04476 insn = emit_insn (x);
04477 break;
04478
04479 #ifdef ENABLE_RTL_CHECKING
04480 case SEQUENCE:
04481 gcc_unreachable ();
04482 break;
04483 #endif
04484
04485 default:
04486 insn = make_call_insn_raw (x);
04487 add_insn (insn);
04488 break;
04489 }
04490
04491 return insn;
04492 }
04493
04494
04495
04496 rtx
04497 emit_label (rtx label)
04498 {
04499
04500
04501
04502 if (INSN_UID (label) == 0)
04503 {
04504 INSN_UID (label) = cur_insn_uid++;
04505 add_insn (label);
04506 }
04507 return label;
04508 }
04509
04510
04511
04512
04513 rtx
04514 emit_barrier (void)
04515 {
04516 rtx barrier = rtx_alloc (BARRIER);
04517 INSN_UID (barrier) = cur_insn_uid++;
04518 add_insn (barrier);
04519 return barrier;
04520 }
04521
04522
04523
04524
04525
04526 rtx
04527 emit_line_note (location_t location)
04528 {
04529 rtx note;
04530
04531 #ifdef USE_MAPPED_LOCATION
04532 if (location == last_location)
04533 return NULL_RTX;
04534 #else
04535 if (location.file && last_location.file
04536 && !strcmp (location.file, last_location.file)
04537 && location.line == last_location.line)
04538 return NULL_RTX;
04539 #endif
04540 last_location = location;
04541
04542 if (no_line_numbers)
04543 {
04544 cur_insn_uid++;
04545 return NULL_RTX;
04546 }
04547
04548 #ifdef USE_MAPPED_LOCATION
04549 note = emit_note ((int) location);
04550 #else
04551 note = emit_note (location.line);
04552 NOTE_SOURCE_FILE (note) = location.file;
04553 #endif
04554
04555 return note;
04556 }
04557
04558
04559
04560 rtx
04561 emit_note_copy (rtx orig)
04562 {
04563 rtx note;
04564
04565 if (NOTE_LINE_NUMBER (orig) >= 0 && no_line_numbers)
04566 {
04567 cur_insn_uid++;
04568 return NULL_RTX;
04569 }
04570
04571 note = rtx_alloc (NOTE);
04572
04573 INSN_UID (note) = cur_insn_uid++;
04574 NOTE_DATA (note) = NOTE_DATA (orig);
04575 NOTE_LINE_NUMBER (note) = NOTE_LINE_NUMBER (orig);
04576 BLOCK_FOR_INSN (note) = NULL;
04577 add_insn (note);
04578
04579 return note;
04580 }
04581
04582
04583
04584
04585 rtx
04586 emit_note (int note_no)
04587 {
04588 rtx note;
04589
04590 note = rtx_alloc (NOTE);
04591 INSN_UID (note) = cur_insn_uid++;
04592 NOTE_LINE_NUMBER (note) = note_no;
04593 memset (&NOTE_DATA (note), 0, sizeof (NOTE_DATA (note)));
04594 BLOCK_FOR_INSN (note) = NULL;
04595 add_insn (note);
04596 return note;
04597 }
04598
04599
04600
04601
04602 void
04603 force_next_line_note (void)
04604 {
04605 #ifdef USE_MAPPED_LOCATION
04606 last_location = -1;
04607 #else
04608 last_location.line = -1;
04609 #endif
04610 }
04611
04612
04613
04614
04615 rtx
04616 set_unique_reg_note (rtx insn, enum reg_note kind, rtx datum)
04617 {
04618 rtx note = find_reg_note (insn, kind, NULL_RTX);
04619
04620 switch (kind)
04621 {
04622 case REG_EQUAL:
04623 case REG_EQUIV:
04624
04625
04626
04627
04628 if (GET_CODE (PATTERN (insn)) == PARALLEL && multiple_sets (insn))
04629 {
04630 gcc_assert (!note);
04631 return NULL_RTX;
04632 }
04633
04634
04635
04636 if (GET_CODE (datum) == ASM_OPERANDS)
04637 return NULL_RTX;
04638 break;
04639
04640 default:
04641 break;
04642 }
04643
04644 if (note)
04645 {
04646 XEXP (note, 0) = datum;
04647 return note;
04648 }
04649
04650 REG_NOTES (insn) = gen_rtx_EXPR_LIST (kind, datum, REG_NOTES (insn));
04651 return REG_NOTES (insn);
04652 }
04653
04654
04655
04656
04657 static enum rtx_code
04658 classify_insn (rtx x)
04659 {
04660 if (LABEL_P (x))
04661 return CODE_LABEL;
04662 if (GET_CODE (x) == CALL)
04663 return CALL_INSN;
04664 if (GET_CODE (x) == RETURN)
04665 return JUMP_INSN;
04666 if (GET_CODE (x) == SET)
04667 {
04668 if (SET_DEST (x) == pc_rtx)
04669 return JUMP_INSN;
04670 else if (GET_CODE (SET_SRC (x)) == CALL)
04671 return CALL_INSN;
04672 else
04673 return INSN;
04674 }
04675 if (GET_CODE (x) == PARALLEL)
04676 {
04677 int j;
04678 for (j = XVECLEN (x, 0) - 1; j >= 0; j--)
04679 if (GET_CODE (XVECEXP (x, 0, j)) == CALL)
04680 return CALL_INSN;
04681 else if (GET_CODE (XVECEXP (x, 0, j)) == SET
04682 && SET_DEST (XVECEXP (x, 0, j)) == pc_rtx)
04683 return JUMP_INSN;
04684 else if (GET_CODE (XVECEXP (x, 0, j)) == SET
04685 && GET_CODE (SET_SRC (XVECEXP (x, 0, j))) == CALL)
04686 return CALL_INSN;
04687 }
04688 return INSN;
04689 }
04690
04691
04692
04693
04694 rtx
04695 emit (rtx x)
04696 {
04697 enum rtx_code code = classify_insn (x);
04698
04699 switch (code)
04700 {
04701 case CODE_LABEL:
04702 return emit_label (x);
04703 case INSN:
04704 return emit_insn (x);
04705 case JUMP_INSN:
04706 {
04707 rtx insn = emit_jump_insn (x);
04708 if (any_uncondjump_p (insn) || GET_CODE (x) == RETURN)
04709 return emit_barrier ();
04710 return insn;
04711 }
04712 case CALL_INSN:
04713 return emit_call_insn (x);
04714 default:
04715 gcc_unreachable ();
04716 }
04717 }
04718
04719
04720 static GTY ((deletable)) struct sequence_stack *free_sequence_stack;
04721
04722
04723
04724
04725
04726
04727
04728
04729 void
04730 start_sequence (void)
04731 {
04732 struct sequence_stack *tem;
04733
04734 if (free_sequence_stack != NULL)
04735 {
04736 tem = free_sequence_stack;
04737 free_sequence_stack = tem->next;
04738 }
04739 else
04740 tem = ggc_alloc (sizeof (struct sequence_stack));
04741
04742 tem->next = seq_stack;
04743 tem->first = first_insn;
04744 tem->last = last_insn;
04745
04746 seq_stack = tem;
04747
04748 first_insn = 0;
04749 last_insn = 0;
04750 }
04751
04752
04753
04754
04755
04756 void
04757 push_to_sequence (rtx first)
04758 {
04759 rtx last;
04760
04761 start_sequence ();
04762
04763 for (last = first; last && NEXT_INSN (last); last = NEXT_INSN (last));
04764
04765 first_insn = first;
04766 last_insn = last;
04767 }
04768
04769
04770
04771
04772 void
04773 push_topmost_sequence (void)
04774 {
04775 struct sequence_stack *stack, *top = NULL;
04776
04777 start_sequence ();
04778
04779 for (stack = seq_stack; stack; stack = stack->next)
04780 top = stack;
04781
04782 first_insn = top->first;
04783 last_insn = top->last;
04784 }
04785
04786
04787
04788
04789 void
04790 pop_topmost_sequence (void)
04791 {
04792 struct sequence_stack *stack, *top = NULL;
04793
04794 for (stack = seq_stack; stack; stack = stack->next)
04795 top = stack;
04796
04797 top->first = first_insn;
04798 top->last = last_insn;
04799
04800 end_sequence ();
04801 }
04802
04803
04804
04805
04806
04807
04808
04809
04810
04811
04812
04813
04814
04815
04816 void
04817 end_sequence (void)
04818 {
04819 struct sequence_stack *tem = seq_stack;
04820
04821 first_insn = tem->first;
04822 last_insn = tem->last;
04823 seq_stack = tem->next;
04824
04825 memset (tem, 0, sizeof (*tem));
04826 tem->next = free_sequence_stack;
04827 free_sequence_stack = tem;
04828 }
04829
04830
04831
04832 int
04833 in_sequence_p (void)
04834 {
04835 return seq_stack != 0;
04836 }
04837
04838
04839
04840 void
04841 init_virtual_regs (struct emit_status *es)
04842 {
04843 rtx *ptr = es->x_regno_reg_rtx;
04844 ptr[VIRTUAL_INCOMING_ARGS_REGNUM] = virtual_incoming_args_rtx;
04845 ptr[VIRTUAL_STACK_VARS_REGNUM] = virtual_stack_vars_rtx;
04846 ptr[VIRTUAL_STACK_DYNAMIC_REGNUM] = virtual_stack_dynamic_rtx;
04847 ptr[VIRTUAL_OUTGOING_ARGS_REGNUM] = virtual_outgoing_args_rtx;
04848 ptr[VIRTUAL_CFA_REGNUM] = virtual_cfa_rtx;
04849 }
04850
04851
04852
04853 static rtx copy_insn_scratch_in[MAX_RECOG_OPERANDS];
04854 static rtx copy_insn_scratch_out[MAX_RECOG_OPERANDS];
04855 static int copy_insn_n_scratches;
04856
04857
04858
04859
04860 static rtvec orig_asm_operands_vector;
04861
04862
04863
04864
04865 static rtvec copy_asm_operands_vector;
04866
04867
04868 static rtvec orig_asm_constraints_vector;
04869 static rtvec copy_asm_constraints_vector;
04870
04871
04872
04873
04874
04875
04876
04877
04878
04879 rtx
04880 copy_insn_1 (rtx orig)
04881 {
04882 rtx copy;
04883 int i, j;
04884 RTX_CODE code;
04885 const char *format_ptr;
04886
04887 code = GET_CODE (orig);
04888
04889 switch (code)
04890 {
04891 case REG:
04892 case CONST_INT:
04893 case CONST_DOUBLE:
04894 case CONST_VECTOR:
04895 case SYMBOL_REF:
04896 case CODE_LABEL:
04897 case PC:
04898 case CC0:
04899 return orig;
04900 case CLOBBER:
04901 if (REG_P (XEXP (orig, 0)) && REGNO (XEXP (orig, 0)) < FIRST_PSEUDO_REGISTER)
04902 return orig;
04903 break;
04904
04905 case SCRATCH:
04906 for (i = 0; i < copy_insn_n_scratches; i++)
04907 if (copy_insn_scratch_in[i] == orig)
04908 return copy_insn_scratch_out[i];
04909 break;
04910
04911 case CONST:
04912
04913
04914 if (GET_CODE (XEXP (orig, 0)) == PLUS
04915 && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
04916 && GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT)
04917 return orig;
04918 break;
04919
04920
04921
04922
04923
04924
04925 default:
04926 break;
04927 }
04928
04929 copy = rtx_alloc (code);
04930
04931
04932
04933
04934
04935 memcpy (copy, orig, RTX_HDR_SIZE);
04936
04937
04938
04939 RTX_FLAG (copy, used) = 0;
04940
04941
04942 if (INSN_P (orig))
04943 {
04944 RTX_FLAG (copy, jump) = 0;
04945 RTX_FLAG (copy, call) = 0;
04946 RTX_FLAG (copy, frame_related) = 0;
04947 }
04948
04949 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
04950
04951 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
04952 {
04953 copy->u.fld[i] = orig->u.fld[i];
04954 switch (*format_ptr++)
04955 {
04956 case 'e':
04957 if (XEXP (orig, i) != NULL)
04958 XEXP (copy, i) = copy_insn_1 (XEXP (orig, i));
04959 break;
04960
04961 case 'E':
04962 case 'V':
04963 if (XVEC (orig, i) == orig_asm_constraints_vector)
04964 XVEC (copy, i) = copy_asm_constraints_vector;
04965 else if (XVEC (orig, i) == orig_asm_operands_vector)
04966 XVEC (copy, i) = copy_asm_operands_vector;
04967 else if (XVEC (orig, i) != NULL)
04968 {
04969 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
04970 for (j = 0; j < XVECLEN (copy, i); j++)
04971 XVECEXP (copy, i, j) = copy_insn_1 (XVECEXP (orig, i, j));
04972 }
04973 break;
04974
04975 case 't':
04976 case 'w':
04977 case 'i':
04978 case 's':
04979 case 'S':
04980 case 'u':
04981 case '0':
04982
04983 break;
04984
04985 default:
04986 gcc_unreachable ();
04987 }
04988 }
04989
04990 if (code == SCRATCH)
04991 {
04992 i = copy_insn_n_scratches++;
04993 gcc_assert (i < MAX_RECOG_OPERANDS);
04994 copy_insn_scratch_in[i] = orig;
04995 copy_insn_scratch_out[i] = copy;
04996 }
04997 else if (code == ASM_OPERANDS)
04998 {
04999 orig_asm_operands_vector = ASM_OPERANDS_INPUT_VEC (orig);
05000 copy_asm_operands_vector = ASM_OPERANDS_INPUT_VEC (copy);
05001 orig_asm_constraints_vector = ASM_OPERANDS_INPUT_CONSTRAINT_VEC (orig);
05002 copy_asm_constraints_vector = ASM_OPERANDS_INPUT_CONSTRAINT_VEC (copy);
05003 }
05004
05005 return copy;
05006 }
05007
05008
05009
05010
05011
05012
05013 rtx
05014 copy_insn (rtx insn)
05015 {
05016 copy_insn_n_scratches = 0;
05017 orig_asm_operands_vector = 0;
05018 orig_asm_constraints_vector = 0;
05019 copy_asm_operands_vector = 0;
05020 copy_asm_constraints_vector = 0;
05021 return copy_insn_1 (insn);
05022 }
05023
05024
05025
05026
05027 void
05028 init_emit (void)
05029 {
05030 struct function *f = cfun;
05031
05032 f->emit = ggc_alloc (sizeof (struct emit_status));
05033 first_insn = NULL;
05034 last_insn = NULL;
05035 cur_insn_uid = 1;
05036 reg_rtx_no = LAST_VIRTUAL_REGISTER + 1;
05037 last_location = UNKNOWN_LOCATION;
05038 first_label_num = label_num;
05039 seq_stack = NULL;
05040
05041
05042
05043 f->emit->regno_pointer_align_length = LAST_VIRTUAL_REGISTER + 101;
05044
05045 f->emit->regno_pointer_align
05046 = ggc_alloc_cleared (f->emit->regno_pointer_align_length
05047 * sizeof (unsigned char));
05048
05049 regno_reg_rtx
05050 = ggc_alloc (f->emit->regno_pointer_align_length * sizeof (rtx));
05051
05052
05053 memcpy (regno_reg_rtx,
05054 static_regno_reg_rtx,
05055 FIRST_PSEUDO_REGISTER * sizeof (rtx));
05056
05057
05058 init_virtual_regs (f->emit);
05059
05060
05061
05062 REG_POINTER (stack_pointer_rtx) = 1;
05063 REG_POINTER (frame_pointer_rtx) = 1;
05064 REG_POINTER (hard_frame_pointer_rtx) = 1;
05065 REG_POINTER (arg_pointer_rtx) = 1;
05066
05067 REG_POINTER (virtual_incoming_args_rtx) = 1;
05068 REG_POINTER (virtual_stack_vars_rtx) = 1;
05069 REG_POINTER (virtual_stack_dynamic_rtx) = 1;
05070 REG_POINTER (virtual_outgoing_args_rtx) = 1;
05071 REG_POINTER (virtual_cfa_rtx) = 1;
05072
05073 #ifdef STACK_BOUNDARY
05074 REGNO_POINTER_ALIGN (STACK_POINTER_REGNUM) = STACK_BOUNDARY;
05075 REGNO_POINTER_ALIGN (FRAME_POINTER_REGNUM) = STACK_BOUNDARY;
05076 REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = STACK_BOUNDARY;
05077 REGNO_POINTER_ALIGN (ARG_POINTER_REGNUM) = STACK_BOUNDARY;
05078
05079 REGNO_POINTER_ALIGN (VIRTUAL_INCOMING_ARGS_REGNUM) = STACK_BOUNDARY;
05080 REGNO_POINTER_ALIGN (VIRTUAL_STACK_VARS_REGNUM) = STACK_BOUNDARY;
05081 REGNO_POINTER_ALIGN (VIRTUAL_STACK_DYNAMIC_REGNUM) = STACK_BOUNDARY;
05082 REGNO_POINTER_ALIGN (VIRTUAL_OUTGOING_ARGS_REGNUM) = STACK_BOUNDARY;
05083 REGNO_POINTER_ALIGN (VIRTUAL_CFA_REGNUM) = BITS_PER_WORD;
05084 #endif
05085
05086 #ifdef INIT_EXPANDERS
05087 INIT_EXPANDERS;
05088 #endif
05089 }
05090
05091
05092
05093 static rtx
05094 gen_const_vector (enum machine_mode mode, int constant)
05095 {
05096 rtx tem;
05097 rtvec v;
05098 int units, i;
05099 enum machine_mode inner;
05100
05101 units = GET_MODE_NUNITS (mode);
05102 inner = GET_MODE_INNER (mode);
05103
05104 v = rtvec_alloc (units);
05105
05106
05107
05108 gcc_assert (const_tiny_rtx[constant][(int) inner]);
05109
05110 for (i = 0; i < units; ++i)
05111 RTVEC_ELT (v, i) = const_tiny_rtx[constant][(int) inner];
05112
05113 tem = gen_rtx_raw_CONST_VECTOR (mode, v);
05114 return tem;
05115 }
05116
05117
05118
05119 rtx
05120 gen_rtx_CONST_VECTOR (enum machine_mode mode, rtvec v)
05121 {
05122 enum machine_mode inner = GET_MODE_INNER (mode);
05123 int nunits = GET_MODE_NUNITS (mode);
05124 rtx x;
05125 int i;
05126
05127
05128 x = RTVEC_ELT (v, nunits - 1);
05129 for (i = nunits - 2; i >= 0; i--)
05130 if (RTVEC_ELT (v, i) != x)
05131 break;
05132
05133
05134
05135 if (i == -1)
05136 {
05137 if (x == CONST0_RTX (inner))
05138 return CONST0_RTX (mode);
05139 else if (x == CONST1_RTX (inner))
05140 return CONST1_RTX (mode);
05141 }
05142
05143 return gen_rtx_raw_CONST_VECTOR (mode, v);
05144 }
05145
05146
05147
05148
05149 void
05150 init_emit_once (int line_numbers)
05151 {
05152 int i;
05153 enum machine_mode mode;
05154 enum machine_mode double_mode;
05155
05156
05157 init_reg_modes_once ();
05158
05159
05160
05161 const_int_htab = htab_create_ggc (37, const_int_htab_hash,
05162 const_int_htab_eq, NULL);
05163
05164 const_double_htab = htab_create_ggc (37, const_double_htab_hash,
05165 const_double_htab_eq, NULL);
05166
05167 mem_attrs_htab = htab_create_ggc (37, mem_attrs_htab_hash,
05168 mem_attrs_htab_eq, NULL);
05169 reg_attrs_htab = htab_create_ggc (37, reg_attrs_htab_hash,
05170 reg_attrs_htab_eq, NULL);
05171
05172 no_line_numbers = ! line_numbers;
05173
05174
05175
05176 byte_mode = VOIDmode;
05177 word_mode = VOIDmode;
05178 double_mode = VOIDmode;
05179
05180 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
05181 mode = GET_MODE_WIDER_MODE (mode))
05182 {
05183 if (GET_MODE_BITSIZE (mode) == BITS_PER_UNIT
05184 && byte_mode == VOIDmode)
05185 byte_mode = mode;
05186
05187 if (GET_MODE_BITSIZE (mode) == BITS_PER_WORD
05188 && word_mode == VOIDmode)
05189 word_mode = mode;
05190 }
05191
05192 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode;
05193 mode = GET_MODE_WIDER_MODE (mode))
05194 {
05195 if (GET_MODE_BITSIZE (mode) == DOUBLE_TYPE_SIZE
05196 && double_mode == VOIDmode)
05197 double_mode = mode;
05198 }
05199
05200 ptr_mode = mode_for_size (POINTER_SIZE, GET_MODE_CLASS (Pmode), 0);
05201
05202
05203
05204
05205
05206 pc_rtx = gen_rtx_PC (VOIDmode);
05207 cc0_rtx = gen_rtx_CC0 (VOIDmode);
05208 stack_pointer_rtx = gen_raw_REG (Pmode, STACK_POINTER_REGNUM);
05209 frame_pointer_rtx = gen_raw_REG (Pmode, FRAME_POINTER_REGNUM);
05210 if (hard_frame_pointer_rtx == 0)
05211 hard_frame_pointer_rtx = gen_raw_REG (Pmode,
05212 HARD_FRAME_POINTER_REGNUM);
05213 if (arg_pointer_rtx == 0)
05214 arg_pointer_rtx = gen_raw_REG (Pmode, ARG_POINTER_REGNUM);
05215 virtual_incoming_args_rtx =
05216 gen_raw_REG (Pmode, VIRTUAL_INCOMING_ARGS_REGNUM);
05217 virtual_stack_vars_rtx =
05218 gen_raw_REG (Pmode, VIRTUAL_STACK_VARS_REGNUM);
05219 virtual_stack_dynamic_rtx =
05220 gen_raw_REG (Pmode, VIRTUAL_STACK_DYNAMIC_REGNUM);
05221 virtual_outgoing_args_rtx =
05222 gen_raw_REG (Pmode, VIRTUAL_OUTGOING_ARGS_REGNUM);
05223 virtual_cfa_rtx = gen_raw_REG (Pmode, VIRTUAL_CFA_REGNUM);
05224
05225
05226
05227 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
05228 static_regno_reg_rtx[i] = gen_raw_REG (reg_raw_mode[i], i);
05229
05230 #ifdef INIT_EXPANDERS
05231
05232
05233
05234
05235 INIT_EXPANDERS;
05236 #endif
05237
05238
05239
05240
05241
05242 for (i = - MAX_SAVED_CONST_INT; i <= MAX_SAVED_CONST_INT; i++)
05243 const_int_rtx[i + MAX_SAVED_CONST_INT] =
05244 gen_rtx_raw_CONST_INT (VOIDmode, (HOST_WIDE_INT) i);
05245
05246 if (STORE_FLAG_VALUE >= - MAX_SAVED_CONST_INT
05247 && STORE_FLAG_VALUE <= MAX_SAVED_CONST_INT)
05248 const_true_rtx = const_int_rtx[STORE_FLAG_VALUE + MAX_SAVED_CONST_INT];
05249 else
05250 const_true_rtx = gen_rtx_CONST_INT (VOIDmode, STORE_FLAG_VALUE);
05251
05252 REAL_VALUE_FROM_INT (dconst0, 0, 0, double_mode);
05253 REAL_VALUE_FROM_INT (dconst1, 1, 0, double_mode);
05254 REAL_VALUE_FROM_INT (dconst2, 2, 0, double_mode);
05255 REAL_VALUE_FROM_INT (dconst3, 3, 0, double_mode);
05256 REAL_VALUE_FROM_INT (dconst10, 10, 0, double_mode);
05257 REAL_VALUE_FROM_INT (dconstm1, -1, -1, double_mode);
05258 REAL_VALUE_FROM_INT (dconstm2, -2, -1, double_mode);
05259
05260 dconsthalf = dconst1;
05261 SET_REAL_EXP (&dconsthalf, REAL_EXP (&dconsthalf) - 1);
05262
05263 real_arithmetic (&dconstthird, RDIV_EXPR, &dconst1, &dconst3);
05264
05265
05266
05267 real_from_string (&dconstpi,
05268 "3.1415926535897932384626433832795028841971693993751058209749445923078");
05269 real_from_string (&dconste,
05270 "2.7182818284590452353602874713526624977572470936999595749669676277241");
05271
05272 for (i = 0; i < (int) ARRAY_SIZE (const_tiny_rtx); i++)
05273 {
05274 REAL_VALUE_TYPE *r =
05275 (i == 0 ? &dconst0 : i == 1 ? &dconst1 : &dconst2);
05276
05277 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode;
05278 mode = GET_MODE_WIDER_MODE (mode))
05279 const_tiny_rtx[i][(int) mode] =
05280 CONST_DOUBLE_FROM_REAL_VALUE (*r, mode);
05281
05282 const_tiny_rtx[i][(int) VOIDmode] = GEN_INT (i);
05283
05284 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
05285 mode = GET_MODE_WIDER_MODE (mode))
05286 const_tiny_rtx[i][(int) mode] = GEN_INT (i);
05287
05288 for (mode = GET_CLASS_NARROWEST_MODE (MODE_PARTIAL_INT);
05289 mode != VOIDmode;
05290 mode = GET_MODE_WIDER_MODE (mode))
05291 const_tiny_rtx[i][(int) mode] = GEN_INT (i);
05292 }
05293
05294 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
05295 mode != VOIDmode;
05296 mode = GET_MODE_WIDER_MODE (mode))
05297 {
05298 const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
05299 const_tiny_rtx[1][(int) mode] = gen_const_vector (mode, 1);
05300 }
05301
05302 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
05303 mode != VOIDmode;
05304 mode = GET_MODE_WIDER_MODE (mode))
05305 {
05306 const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
05307 const_tiny_rtx[1][(int) mode] = gen_const_vector (mode, 1);
05308 }
05309
05310 for (i = (int) CCmode; i < (int) MAX_MACHINE_MODE; ++i)
05311 if (GET_MODE_CLASS ((enum machine_mode) i) == MODE_CC)
05312 const_tiny_rtx[0][i] = const0_rtx;
05313
05314 const_tiny_rtx[0][(int) BImode] = const0_rtx;
05315 if (STORE_FLAG_VALUE == 1)
05316 const_tiny_rtx[1][(int) BImode] = const1_rtx;
05317
05318 #ifdef RETURN_ADDRESS_POINTER_REGNUM
05319 return_address_pointer_rtx
05320 = gen_raw_REG (Pmode, RETURN_ADDRESS_POINTER_REGNUM);
05321 #endif
05322
05323 #ifdef STATIC_CHAIN_REGNUM
05324 static_chain_rtx = gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM);
05325
05326 #ifdef STATIC_CHAIN_INCOMING_REGNUM
05327 if (STATIC_CHAIN_INCOMING_REGNUM != STATIC_CHAIN_REGNUM)
05328 static_chain_incoming_rtx
05329 = gen_rtx_REG (Pmode, STATIC_CHAIN_INCOMING_REGNUM);
05330 else
05331 #endif
05332 static_chain_incoming_rtx = static_chain_rtx;
05333 #endif
05334
05335 #ifdef STATIC_CHAIN
05336 static_chain_rtx = STATIC_CHAIN;
05337
05338 #ifdef STATIC_CHAIN_INCOMING
05339 static_chain_incoming_rtx = STATIC_CHAIN_INCOMING;
05340 #else
05341 static_chain_incoming_rtx = static_chain_rtx;
05342 #endif
05343 #endif
05344
05345 if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
05346 pic_offset_table_rtx = gen_raw_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
05347 }
05348
05349
05350
05351
05352 rtx
05353 emit_copy_of_insn_after (rtx insn, rtx after)
05354 {
05355 rtx new;
05356 rtx note1, note2, link;
05357
05358 switch (GET_CODE (insn))
05359 {
05360 case INSN:
05361 new = emit_insn_after (copy_insn (PATTERN (insn)), after);
05362 break;
05363
05364 case JUMP_INSN:
05365 new = emit_jump_insn_after (copy_insn (PATTERN (insn)), after);
05366 break;
05367
05368 case CALL_INSN:
05369 new = emit_call_insn_after (copy_insn (PATTERN (insn)), after);
05370 if (CALL_INSN_FUNCTION_USAGE (insn))
05371 CALL_INSN_FUNCTION_USAGE (new)
05372 = copy_insn (CALL_INSN_FUNCTION_USAGE (insn));
05373 SIBLING_CALL_P (new) = SIBLING_CALL_P (insn);
05374 CONST_OR_PURE_CALL_P (new) = CONST_OR_PURE_CALL_P (insn);
05375 break;
05376
05377 default:
05378 gcc_unreachable ();
05379 }
05380
05381
05382 mark_jump_label (PATTERN (new), new, 0);
05383
05384 INSN_LOCATOR (new) = INSN_LOCATOR (insn);
05385
05386
05387
05388
05389 RTX_FRAME_RELATED_P (new) = RTX_FRAME_RELATED_P (insn);
05390
05391
05392
05393 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
05394 if (REG_NOTE_KIND (link) != REG_LABEL)
05395 {
05396 if (GET_CODE (link) == EXPR_LIST)
05397 REG_NOTES (new)
05398 = copy_insn_1 (gen_rtx_EXPR_LIST (REG_NOTE_KIND (link),
05399 XEXP (link, 0),
05400 REG_NOTES (new)));
05401 else
05402 REG_NOTES (new)
05403 = copy_insn_1 (gen_rtx_INSN_LIST (REG_NOTE_KIND (link),
05404 XEXP (link, 0),
05405 REG_NOTES (new)));
05406 }
05407
05408
05409 if ((note1 = find_reg_note (new, REG_RETVAL, NULL_RTX)) != NULL)
05410 {
05411 rtx p = new;
05412 while ((note2 = find_reg_note (p, REG_LIBCALL, NULL_RTX)) == NULL)
05413 p = PREV_INSN (p);
05414 XEXP (note1, 0) = p;
05415 XEXP (note2, 0) = new;
05416 }
05417 INSN_CODE (new) = INSN_CODE (insn);
05418 return new;
05419 }
05420
05421 static GTY((deletable)) rtx hard_reg_clobbers [NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
05422 rtx
05423 gen_hard_reg_clobber (enum machine_mode mode, unsigned int regno)
05424 {
05425 if (hard_reg_clobbers[mode][regno])
05426 return hard_reg_clobbers[mode][regno];
05427 else
05428 return (hard_reg_clobbers[mode][regno] =
05429 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (mode, regno)));
05430 }
05431
05432 #include "gt-emit-rtl.h"