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