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