00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "config.h"
00025 #include "system.h"
00026 #include "coretypes.h"
00027 #include "tm.h"
00028 #include "toplev.h"
00029 #include "rtl.h"
00030 #include "hard-reg-set.h"
00031 #include "insn-config.h"
00032 #include "recog.h"
00033 #include "target.h"
00034 #include "output.h"
00035 #include "tm_p.h"
00036 #include "flags.h"
00037 #include "real.h"
00038 #include "regs.h"
00039 #include "function.h"
00040
00041
00042 static void set_of_1 (rtx, rtx, void *);
00043 static bool covers_regno_p (rtx, unsigned int);
00044 static bool covers_regno_no_parallel_p (rtx, unsigned int);
00045 static int rtx_referenced_p_1 (rtx *, void *);
00046 static int computed_jump_p_1 (rtx);
00047 static void parms_set (rtx, rtx, void *);
00048
00049 static unsigned HOST_WIDE_INT cached_nonzero_bits (rtx, enum machine_mode,
00050 rtx, enum machine_mode,
00051 unsigned HOST_WIDE_INT);
00052 static unsigned HOST_WIDE_INT nonzero_bits1 (rtx, enum machine_mode, rtx,
00053 enum machine_mode,
00054 unsigned HOST_WIDE_INT);
00055 static unsigned int cached_num_sign_bit_copies (rtx, enum machine_mode, rtx,
00056 enum machine_mode,
00057 unsigned int);
00058 static unsigned int num_sign_bit_copies1 (rtx, enum machine_mode, rtx,
00059 enum machine_mode, unsigned int);
00060
00061
00062
00063 static int non_rtx_starting_operands[NUM_RTX_CODE];
00064
00065
00066
00067
00068
00069 int target_flags;
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 static unsigned int
00085 num_sign_bit_copies_in_rep[MAX_MODE_INT + 1][MAX_MODE_INT + 1];
00086
00087
00088
00089
00090
00091
00092 int
00093 rtx_unstable_p (rtx x)
00094 {
00095 RTX_CODE code = GET_CODE (x);
00096 int i;
00097 const char *fmt;
00098
00099 switch (code)
00100 {
00101 case MEM:
00102 return !MEM_READONLY_P (x) || rtx_unstable_p (XEXP (x, 0));
00103
00104 case CONST:
00105 case CONST_INT:
00106 case CONST_DOUBLE:
00107 case CONST_VECTOR:
00108 case SYMBOL_REF:
00109 case LABEL_REF:
00110 return 0;
00111
00112 case REG:
00113
00114 if (x == frame_pointer_rtx || x == hard_frame_pointer_rtx
00115
00116 || (x == arg_pointer_rtx && fixed_regs[ARG_POINTER_REGNUM]))
00117 return 0;
00118 #ifndef PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
00119
00120
00121
00122 if (x == pic_offset_table_rtx)
00123 return 0;
00124 #endif
00125 return 1;
00126
00127 case ASM_OPERANDS:
00128 if (MEM_VOLATILE_P (x))
00129 return 1;
00130
00131
00132
00133 default:
00134 break;
00135 }
00136
00137 fmt = GET_RTX_FORMAT (code);
00138 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
00139 if (fmt[i] == 'e')
00140 {
00141 if (rtx_unstable_p (XEXP (x, i)))
00142 return 1;
00143 }
00144 else if (fmt[i] == 'E')
00145 {
00146 int j;
00147 for (j = 0; j < XVECLEN (x, i); j++)
00148 if (rtx_unstable_p (XVECEXP (x, i, j)))
00149 return 1;
00150 }
00151
00152 return 0;
00153 }
00154
00155
00156
00157
00158
00159
00160
00161
00162 int
00163 rtx_varies_p (rtx x, int for_alias)
00164 {
00165 RTX_CODE code;
00166 int i;
00167 const char *fmt;
00168
00169 if (!x)
00170 return 0;
00171
00172 code = GET_CODE (x);
00173 switch (code)
00174 {
00175 case MEM:
00176 return !MEM_READONLY_P (x) || rtx_varies_p (XEXP (x, 0), for_alias);
00177
00178 case CONST:
00179 case CONST_INT:
00180 case CONST_DOUBLE:
00181 case CONST_VECTOR:
00182 case SYMBOL_REF:
00183 case LABEL_REF:
00184 return 0;
00185
00186 case REG:
00187
00188
00189
00190
00191 if (x == frame_pointer_rtx || x == hard_frame_pointer_rtx
00192
00193 || (x == arg_pointer_rtx && fixed_regs[ARG_POINTER_REGNUM]))
00194 return 0;
00195 if (x == pic_offset_table_rtx
00196 #ifdef PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
00197
00198
00199
00200
00201 && for_alias
00202 #endif
00203 )
00204 return 0;
00205 return 1;
00206
00207 case LO_SUM:
00208
00209
00210
00211 return (! for_alias && rtx_varies_p (XEXP (x, 0), for_alias))
00212 || rtx_varies_p (XEXP (x, 1), for_alias);
00213
00214 case ASM_OPERANDS:
00215 if (MEM_VOLATILE_P (x))
00216 return 1;
00217
00218
00219
00220 default:
00221 break;
00222 }
00223
00224 fmt = GET_RTX_FORMAT (code);
00225 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
00226 if (fmt[i] == 'e')
00227 {
00228 if (rtx_varies_p (XEXP (x, i), for_alias))
00229 return 1;
00230 }
00231 else if (fmt[i] == 'E')
00232 {
00233 int j;
00234 for (j = 0; j < XVECLEN (x, i); j++)
00235 if (rtx_varies_p (XVECEXP (x, i, j), for_alias))
00236 return 1;
00237 }
00238
00239 return 0;
00240 }
00241
00242
00243
00244
00245
00246
00247 static int
00248 rtx_addr_can_trap_p_1 (rtx x, enum machine_mode mode, bool unaligned_mems)
00249 {
00250 enum rtx_code code = GET_CODE (x);
00251
00252 switch (code)
00253 {
00254 case SYMBOL_REF:
00255 return SYMBOL_REF_WEAK (x);
00256
00257 case LABEL_REF:
00258 return 0;
00259
00260 case REG:
00261
00262 if (x == frame_pointer_rtx || x == hard_frame_pointer_rtx
00263 || x == stack_pointer_rtx
00264
00265 || (x == arg_pointer_rtx && fixed_regs[ARG_POINTER_REGNUM]))
00266 return 0;
00267
00268 if (REGNO (x) >= FIRST_VIRTUAL_REGISTER
00269 && REGNO (x) <= LAST_VIRTUAL_REGISTER)
00270 return 0;
00271 return 1;
00272
00273 case CONST:
00274 return rtx_addr_can_trap_p_1 (XEXP (x, 0), mode, unaligned_mems);
00275
00276 case PLUS:
00277
00278
00279
00280
00281 if (!rtx_addr_can_trap_p_1 (XEXP (x, 0), mode, unaligned_mems)
00282 && GET_CODE (XEXP (x, 1)) == CONST_INT)
00283 {
00284 HOST_WIDE_INT offset;
00285
00286 if (!STRICT_ALIGNMENT
00287 || !unaligned_mems
00288 || GET_MODE_SIZE (mode) == 0)
00289 return 0;
00290
00291 offset = INTVAL (XEXP (x, 1));
00292
00293 #ifdef SPARC_STACK_BOUNDARY_HACK
00294
00295
00296
00297 if (SPARC_STACK_BOUNDARY_HACK
00298 && (XEXP (x, 0) == stack_pointer_rtx
00299 || XEXP (x, 0) == hard_frame_pointer_rtx))
00300 offset -= STACK_POINTER_OFFSET;
00301 #endif
00302
00303 return offset % GET_MODE_SIZE (mode) != 0;
00304 }
00305
00306
00307 if (XEXP (x, 0) == pic_offset_table_rtx && CONSTANT_P (XEXP (x, 1)))
00308 return 0;
00309
00310 return 1;
00311
00312 case LO_SUM:
00313 case PRE_MODIFY:
00314 return rtx_addr_can_trap_p_1 (XEXP (x, 1), mode, unaligned_mems);
00315
00316 case PRE_DEC:
00317 case PRE_INC:
00318 case POST_DEC:
00319 case POST_INC:
00320 case POST_MODIFY:
00321 return rtx_addr_can_trap_p_1 (XEXP (x, 0), mode, unaligned_mems);
00322
00323 default:
00324 break;
00325 }
00326
00327
00328 return 1;
00329 }
00330
00331
00332
00333 int
00334 rtx_addr_can_trap_p (rtx x)
00335 {
00336 return rtx_addr_can_trap_p_1 (x, VOIDmode, false);
00337 }
00338
00339
00340
00341 bool
00342 nonzero_address_p (rtx x)
00343 {
00344 enum rtx_code code = GET_CODE (x);
00345
00346 switch (code)
00347 {
00348 case SYMBOL_REF:
00349 return !SYMBOL_REF_WEAK (x);
00350
00351 case LABEL_REF:
00352 return true;
00353
00354 case REG:
00355
00356 if (x == frame_pointer_rtx || x == hard_frame_pointer_rtx
00357 || x == stack_pointer_rtx
00358 || (x == arg_pointer_rtx && fixed_regs[ARG_POINTER_REGNUM]))
00359 return true;
00360
00361 if (REGNO (x) >= FIRST_VIRTUAL_REGISTER
00362 && REGNO (x) <= LAST_VIRTUAL_REGISTER)
00363 return true;
00364 return false;
00365
00366 case CONST:
00367 return nonzero_address_p (XEXP (x, 0));
00368
00369 case PLUS:
00370 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
00371 return nonzero_address_p (XEXP (x, 0));
00372
00373 else if (XEXP (x, 0) == pic_offset_table_rtx
00374 && CONSTANT_P (XEXP (x, 1)))
00375 return true;
00376 return false;
00377
00378 case PRE_MODIFY:
00379
00380
00381
00382 if (GET_CODE (XEXP (x, 1)) == CONST_INT
00383 && INTVAL (XEXP (x, 1)) > 0)
00384 return true;
00385 return nonzero_address_p (XEXP (x, 0));
00386
00387 case PRE_INC:
00388
00389 return true;
00390
00391 case PRE_DEC:
00392 case POST_DEC:
00393 case POST_INC:
00394 case POST_MODIFY:
00395 return nonzero_address_p (XEXP (x, 0));
00396
00397 case LO_SUM:
00398 return nonzero_address_p (XEXP (x, 1));
00399
00400 default:
00401 break;
00402 }
00403
00404
00405 return false;
00406 }
00407
00408
00409
00410
00411
00412
00413
00414 int
00415 rtx_addr_varies_p (rtx x, int for_alias)
00416 {
00417 enum rtx_code code;
00418 int i;
00419 const char *fmt;
00420
00421 if (x == 0)
00422 return 0;
00423
00424 code = GET_CODE (x);
00425 if (code == MEM)
00426 return GET_MODE (x) == BLKmode || rtx_varies_p (XEXP (x, 0), for_alias);
00427
00428 fmt = GET_RTX_FORMAT (code);
00429 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
00430 if (fmt[i] == 'e')
00431 {
00432 if (rtx_addr_varies_p (XEXP (x, i), for_alias))
00433 return 1;
00434 }
00435 else if (fmt[i] == 'E')
00436 {
00437 int j;
00438 for (j = 0; j < XVECLEN (x, i); j++)
00439 if (rtx_addr_varies_p (XVECEXP (x, i, j), for_alias))
00440 return 1;
00441 }
00442 return 0;
00443 }
00444
00445
00446
00447
00448
00449
00450 HOST_WIDE_INT
00451 get_integer_term (rtx x)
00452 {
00453 if (GET_CODE (x) == CONST)
00454 x = XEXP (x, 0);
00455
00456 if (GET_CODE (x) == MINUS
00457 && GET_CODE (XEXP (x, 1)) == CONST_INT)
00458 return - INTVAL (XEXP (x, 1));
00459 if (GET_CODE (x) == PLUS
00460 && GET_CODE (XEXP (x, 1)) == CONST_INT)
00461 return INTVAL (XEXP (x, 1));
00462 return 0;
00463 }
00464
00465
00466
00467
00468
00469 rtx
00470 get_related_value (rtx x)
00471 {
00472 if (GET_CODE (x) != CONST)
00473 return 0;
00474 x = XEXP (x, 0);
00475 if (GET_CODE (x) == PLUS
00476 && GET_CODE (XEXP (x, 1)) == CONST_INT)
00477 return XEXP (x, 0);
00478 else if (GET_CODE (x) == MINUS
00479 && GET_CODE (XEXP (x, 1)) == CONST_INT)
00480 return XEXP (x, 0);
00481 return 0;
00482 }
00483
00484
00485
00486
00487 int
00488 count_occurrences (rtx x, rtx find, int count_dest)
00489 {
00490 int i, j;
00491 enum rtx_code code;
00492 const char *format_ptr;
00493 int count;
00494
00495 if (x == find)
00496 return 1;
00497
00498 code = GET_CODE (x);
00499
00500 switch (code)
00501 {
00502 case REG:
00503 case CONST_INT:
00504 case CONST_DOUBLE:
00505 case CONST_VECTOR:
00506 case SYMBOL_REF:
00507 case CODE_LABEL:
00508 case PC:
00509 case CC0:
00510 return 0;
00511
00512 case MEM:
00513 if (MEM_P (find) && rtx_equal_p (x, find))
00514 return 1;
00515 break;
00516
00517 case SET:
00518 if (SET_DEST (x) == find && ! count_dest)
00519 return count_occurrences (SET_SRC (x), find, count_dest);
00520 break;
00521
00522 default:
00523 break;
00524 }
00525
00526 format_ptr = GET_RTX_FORMAT (code);
00527 count = 0;
00528
00529 for (i = 0; i < GET_RTX_LENGTH (code); i++)
00530 {
00531 switch (*format_ptr++)
00532 {
00533 case 'e':
00534 count += count_occurrences (XEXP (x, i), find, count_dest);
00535 break;
00536
00537 case 'E':
00538 for (j = 0; j < XVECLEN (x, i); j++)
00539 count += count_occurrences (XVECEXP (x, i, j), find, count_dest);
00540 break;
00541 }
00542 }
00543 return count;
00544 }
00545
00546
00547
00548
00549
00550 int
00551 reg_mentioned_p (rtx reg, rtx in)
00552 {
00553 const char *fmt;
00554 int i;
00555 enum rtx_code code;
00556
00557 if (in == 0)
00558 return 0;
00559
00560 if (reg == in)
00561 return 1;
00562
00563 if (GET_CODE (in) == LABEL_REF)
00564 return reg == XEXP (in, 0);
00565
00566 code = GET_CODE (in);
00567
00568 switch (code)
00569 {
00570
00571 case REG:
00572 return REG_P (reg) && REGNO (in) == REGNO (reg);
00573
00574
00575
00576 case SCRATCH:
00577 case CC0:
00578 case PC:
00579 return 0;
00580
00581 case CONST_INT:
00582 case CONST_VECTOR:
00583 case CONST_DOUBLE:
00584
00585 return 0;
00586
00587 default:
00588 break;
00589 }
00590
00591 if (GET_CODE (reg) == code && rtx_equal_p (reg, in))
00592 return 1;
00593
00594 fmt = GET_RTX_FORMAT (code);
00595
00596 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
00597 {
00598 if (fmt[i] == 'E')
00599 {
00600 int j;
00601 for (j = XVECLEN (in, i) - 1; j >= 0; j--)
00602 if (reg_mentioned_p (reg, XVECEXP (in, i, j)))
00603 return 1;
00604 }
00605 else if (fmt[i] == 'e'
00606 && reg_mentioned_p (reg, XEXP (in, i)))
00607 return 1;
00608 }
00609 return 0;
00610 }
00611
00612
00613
00614
00615 int
00616 no_labels_between_p (rtx beg, rtx end)
00617 {
00618 rtx p;
00619 if (beg == end)
00620 return 0;
00621 for (p = NEXT_INSN (beg); p != end; p = NEXT_INSN (p))
00622 if (LABEL_P (p))
00623 return 0;
00624 return 1;
00625 }
00626
00627
00628
00629
00630 int
00631 reg_used_between_p (rtx reg, rtx from_insn, rtx to_insn)
00632 {
00633 rtx insn;
00634
00635 if (from_insn == to_insn)
00636 return 0;
00637
00638 for (insn = NEXT_INSN (from_insn); insn != to_insn; insn = NEXT_INSN (insn))
00639 if (INSN_P (insn)
00640 && (reg_overlap_mentioned_p (reg, PATTERN (insn))
00641 || (CALL_P (insn) && find_reg_fusage (insn, USE, reg))))
00642 return 1;
00643 return 0;
00644 }
00645
00646
00647
00648
00649
00650 int
00651 reg_referenced_p (rtx x, rtx body)
00652 {
00653 int i;
00654
00655 switch (GET_CODE (body))
00656 {
00657 case SET:
00658 if (reg_overlap_mentioned_p (x, SET_SRC (body)))
00659 return 1;
00660
00661
00662
00663
00664 if (GET_CODE (SET_DEST (body)) != CC0
00665 && GET_CODE (SET_DEST (body)) != PC
00666 && !REG_P (SET_DEST (body))
00667 && ! (GET_CODE (SET_DEST (body)) == SUBREG
00668 && REG_P (SUBREG_REG (SET_DEST (body)))
00669 && (((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (body))))
00670 + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
00671 == ((GET_MODE_SIZE (GET_MODE (SET_DEST (body)))
00672 + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)))
00673 && reg_overlap_mentioned_p (x, SET_DEST (body)))
00674 return 1;
00675 return 0;
00676
00677 case ASM_OPERANDS:
00678 for (i = ASM_OPERANDS_INPUT_LENGTH (body) - 1; i >= 0; i--)
00679 if (reg_overlap_mentioned_p (x, ASM_OPERANDS_INPUT (body, i)))
00680 return 1;
00681 return 0;
00682
00683 case CALL:
00684 case USE:
00685 case IF_THEN_ELSE:
00686 return reg_overlap_mentioned_p (x, body);
00687
00688 case TRAP_IF:
00689 return reg_overlap_mentioned_p (x, TRAP_CONDITION (body));
00690
00691 case PREFETCH:
00692 return reg_overlap_mentioned_p (x, XEXP (body, 0));
00693
00694 case UNSPEC:
00695 case UNSPEC_VOLATILE:
00696 for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
00697 if (reg_overlap_mentioned_p (x, XVECEXP (body, 0, i)))
00698 return 1;
00699 return 0;
00700
00701 case PARALLEL:
00702 for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
00703 if (reg_referenced_p (x, XVECEXP (body, 0, i)))
00704 return 1;
00705 return 0;
00706
00707 case CLOBBER:
00708 if (MEM_P (XEXP (body, 0)))
00709 if (reg_overlap_mentioned_p (x, XEXP (XEXP (body, 0), 0)))
00710 return 1;
00711 return 0;
00712
00713 case COND_EXEC:
00714 if (reg_overlap_mentioned_p (x, COND_EXEC_TEST (body)))
00715 return 1;
00716 return reg_referenced_p (x, COND_EXEC_CODE (body));
00717
00718 default:
00719 return 0;
00720 }
00721 }
00722
00723
00724
00725
00726 int
00727 reg_set_between_p (rtx reg, rtx from_insn, rtx to_insn)
00728 {
00729 rtx insn;
00730
00731 if (from_insn == to_insn)
00732 return 0;
00733
00734 for (insn = NEXT_INSN (from_insn); insn != to_insn; insn = NEXT_INSN (insn))
00735 if (INSN_P (insn) && reg_set_p (reg, insn))
00736 return 1;
00737 return 0;
00738 }
00739
00740
00741 int
00742 reg_set_p (rtx reg, rtx insn)
00743 {
00744
00745
00746 if (INSN_P (insn)
00747 && (FIND_REG_INC_NOTE (insn, reg)
00748 || (CALL_P (insn)
00749 && ((REG_P (reg)
00750 && REGNO (reg) < FIRST_PSEUDO_REGISTER
00751 && TEST_HARD_REG_BIT (regs_invalidated_by_call,
00752 REGNO (reg)))
00753 || MEM_P (reg)
00754 || find_reg_fusage (insn, CLOBBER, reg)))))
00755 return 1;
00756
00757 return set_of (reg, insn) != NULL_RTX;
00758 }
00759
00760
00761
00762
00763
00764 int
00765 modified_between_p (rtx x, rtx start, rtx end)
00766 {
00767 enum rtx_code code = GET_CODE (x);
00768 const char *fmt;
00769 int i, j;
00770 rtx insn;
00771
00772 if (start == end)
00773 return 0;
00774
00775 switch (code)
00776 {
00777 case CONST_INT:
00778 case CONST_DOUBLE:
00779 case CONST_VECTOR:
00780 case CONST:
00781 case SYMBOL_REF:
00782 case LABEL_REF:
00783 return 0;
00784
00785 case PC:
00786 case CC0:
00787 return 1;
00788
00789 case MEM:
00790 if (modified_between_p (XEXP (x, 0), start, end))
00791 return 1;
00792 if (MEM_READONLY_P (x))
00793 return 0;
00794 for (insn = NEXT_INSN (start); insn != end; insn = NEXT_INSN (insn))
00795 if (memory_modified_in_insn_p (x, insn))
00796 return 1;
00797 return 0;
00798 break;
00799
00800 case REG:
00801 return reg_set_between_p (x, start, end);
00802
00803 default:
00804 break;
00805 }
00806
00807 fmt = GET_RTX_FORMAT (code);
00808 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
00809 {
00810 if (fmt[i] == 'e' && modified_between_p (XEXP (x, i), start, end))
00811 return 1;
00812
00813 else if (fmt[i] == 'E')
00814 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
00815 if (modified_between_p (XVECEXP (x, i, j), start, end))
00816 return 1;
00817 }
00818
00819 return 0;
00820 }
00821
00822
00823
00824
00825
00826 int
00827 modified_in_p (rtx x, rtx insn)
00828 {
00829 enum rtx_code code = GET_CODE (x);
00830 const char *fmt;
00831 int i, j;
00832
00833 switch (code)
00834 {
00835 case CONST_INT:
00836 case CONST_DOUBLE:
00837 case CONST_VECTOR:
00838 case CONST:
00839 case SYMBOL_REF:
00840 case LABEL_REF:
00841 return 0;
00842
00843 case PC:
00844 case CC0:
00845 return 1;
00846
00847 case MEM:
00848 if (modified_in_p (XEXP (x, 0), insn))
00849 return 1;
00850 if (MEM_READONLY_P (x))
00851 return 0;
00852 if (memory_modified_in_insn_p (x, insn))
00853 return 1;
00854 return 0;
00855 break;
00856
00857 case REG:
00858 return reg_set_p (x, insn);
00859
00860 default:
00861 break;
00862 }
00863
00864 fmt = GET_RTX_FORMAT (code);
00865 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
00866 {
00867 if (fmt[i] == 'e' && modified_in_p (XEXP (x, i), insn))
00868 return 1;
00869
00870 else if (fmt[i] == 'E')
00871 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
00872 if (modified_in_p (XVECEXP (x, i, j), insn))
00873 return 1;
00874 }
00875
00876 return 0;
00877 }
00878
00879
00880 struct set_of_data
00881 {
00882 rtx found;
00883 rtx pat;
00884 };
00885
00886 static void
00887 set_of_1 (rtx x, rtx pat, void *data1)
00888 {
00889 struct set_of_data *data = (struct set_of_data *) (data1);
00890 if (rtx_equal_p (x, data->pat)
00891 || (!MEM_P (x) && reg_overlap_mentioned_p (data->pat, x)))
00892 data->found = pat;
00893 }
00894
00895
00896
00897 rtx
00898 set_of (rtx pat, rtx insn)
00899 {
00900 struct set_of_data data;
00901 data.found = NULL_RTX;
00902 data.pat = pat;
00903 note_stores (INSN_P (insn) ? PATTERN (insn) : insn, set_of_1, &data);
00904 return data.found;
00905 }
00906
00907
00908
00909
00910
00911 rtx
00912 single_set_2 (rtx insn, rtx pat)
00913 {
00914 rtx set = NULL;
00915 int set_verified = 1;
00916 int i;
00917
00918 if (GET_CODE (pat) == PARALLEL)
00919 {
00920 for (i = 0; i < XVECLEN (pat, 0); i++)
00921 {
00922 rtx sub = XVECEXP (pat, 0, i);
00923 switch (GET_CODE (sub))
00924 {
00925 case USE:
00926 case CLOBBER:
00927 break;
00928
00929 case SET:
00930
00931
00932
00933
00934
00935
00936
00937
00938 if (!set_verified)
00939 {
00940 if (find_reg_note (insn, REG_UNUSED, SET_DEST (set))
00941 && !side_effects_p (set))
00942 set = NULL;
00943 else
00944 set_verified = 1;
00945 }
00946 if (!set)
00947 set = sub, set_verified = 0;
00948 else if (!find_reg_note (insn, REG_UNUSED, SET_DEST (sub))
00949 || side_effects_p (sub))
00950 return NULL_RTX;
00951 break;
00952
00953 default:
00954 return NULL_RTX;
00955 }
00956 }
00957 }
00958 return set;
00959 }
00960
00961
00962
00963
00964 int
00965 multiple_sets (rtx insn)
00966 {
00967 int found;
00968 int i;
00969
00970
00971 if (! INSN_P (insn))
00972 return 0;
00973
00974
00975 if (GET_CODE (PATTERN (insn)) == PARALLEL)
00976 {
00977 for (i = 0, found = 0; i < XVECLEN (PATTERN (insn), 0); i++)
00978 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
00979 {
00980
00981 if (found)
00982 return 1;
00983 else
00984 found = 1;
00985 }
00986 }
00987
00988
00989 return 0;
00990 }
00991
00992
00993
00994
00995 int
00996 set_noop_p (rtx set)
00997 {
00998 rtx src = SET_SRC (set);
00999 rtx dst = SET_DEST (set);
01000
01001 if (dst == pc_rtx && src == pc_rtx)
01002 return 1;
01003
01004 if (MEM_P (dst) && MEM_P (src))
01005 return rtx_equal_p (dst, src) && !side_effects_p (dst);
01006
01007 if (GET_CODE (dst) == ZERO_EXTRACT)
01008 return rtx_equal_p (XEXP (dst, 0), src)
01009 && ! BYTES_BIG_ENDIAN && XEXP (dst, 2) == const0_rtx
01010 && !side_effects_p (src);
01011
01012 if (GET_CODE (dst) == STRICT_LOW_PART)
01013 dst = XEXP (dst, 0);
01014
01015 if (GET_CODE (src) == SUBREG && GET_CODE (dst) == SUBREG)
01016 {
01017 if (SUBREG_BYTE (src) != SUBREG_BYTE (dst))
01018 return 0;
01019 src = SUBREG_REG (src);
01020 dst = SUBREG_REG (dst);
01021 }
01022
01023 return (REG_P (src) && REG_P (dst)
01024 && REGNO (src) == REGNO (dst));
01025 }
01026
01027
01028
01029
01030 int
01031 noop_move_p (rtx insn)
01032 {
01033 rtx pat = PATTERN (insn);
01034
01035 if (INSN_CODE (insn) == NOOP_MOVE_INSN_CODE)
01036 return 1;
01037
01038
01039 if (find_reg_note (insn, REG_EQUAL, NULL_RTX))
01040 return 0;
01041
01042
01043
01044 if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
01045 return 0;
01046
01047 if (GET_CODE (pat) == SET && set_noop_p (pat))
01048 return 1;
01049
01050 if (GET_CODE (pat) == PARALLEL)
01051 {
01052 int i;
01053
01054
01055 for (i = 0; i < XVECLEN (pat, 0); i++)
01056 {
01057 rtx tem = XVECEXP (pat, 0, i);
01058
01059 if (GET_CODE (tem) == USE
01060 || GET_CODE (tem) == CLOBBER)
01061 continue;
01062
01063 if (GET_CODE (tem) != SET || ! set_noop_p (tem))
01064 return 0;
01065 }
01066
01067 return 1;
01068 }
01069 return 0;
01070 }
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080 rtx
01081 find_last_value (rtx x, rtx *pinsn, rtx valid_to, int allow_hwreg)
01082 {
01083 rtx p;
01084
01085 for (p = PREV_INSN (*pinsn); p && !LABEL_P (p);
01086 p = PREV_INSN (p))
01087 if (INSN_P (p))
01088 {
01089 rtx set = single_set (p);
01090 rtx note = find_reg_note (p, REG_EQUAL, NULL_RTX);
01091
01092 if (set && rtx_equal_p (x, SET_DEST (set)))
01093 {
01094 rtx src = SET_SRC (set);
01095
01096 if (note && GET_CODE (XEXP (note, 0)) != EXPR_LIST)
01097 src = XEXP (note, 0);
01098
01099 if ((valid_to == NULL_RTX
01100 || ! modified_between_p (src, PREV_INSN (p), valid_to))
01101
01102
01103 && (! (REG_P (src)
01104 && REGNO (src) < FIRST_PSEUDO_REGISTER) || allow_hwreg))
01105 {
01106 *pinsn = p;
01107 return src;
01108 }
01109 }
01110
01111
01112 if (reg_set_p (x, p))
01113 break;
01114 }
01115
01116 return x;
01117 }
01118
01119
01120
01121
01122
01123
01124
01125
01126 int
01127 refers_to_regno_p (unsigned int regno, unsigned int endregno, rtx x,
01128 rtx *loc)
01129 {
01130 int i;
01131 unsigned int x_regno;
01132 RTX_CODE code;
01133 const char *fmt;
01134
01135 repeat:
01136
01137
01138 if (x == 0)
01139 return 0;
01140
01141 code = GET_CODE (x);
01142
01143 switch (code)
01144 {
01145 case REG:
01146 x_regno = REGNO (x);
01147
01148
01149
01150
01151 if ((x_regno == STACK_POINTER_REGNUM
01152 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
01153 || x_regno == ARG_POINTER_REGNUM
01154 #endif
01155 || x_regno == FRAME_POINTER_REGNUM)
01156 && regno >= FIRST_VIRTUAL_REGISTER && regno <= LAST_VIRTUAL_REGISTER)
01157 return 1;
01158
01159 return (endregno > x_regno
01160 && regno < x_regno + (x_regno < FIRST_PSEUDO_REGISTER
01161 ? hard_regno_nregs[x_regno][GET_MODE (x)]
01162 : 1));
01163
01164 case SUBREG:
01165
01166
01167 if (REG_P (SUBREG_REG (x))
01168 && REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER)
01169 {
01170 unsigned int inner_regno = subreg_regno (x);
01171 unsigned int inner_endregno
01172 = inner_regno + (inner_regno < FIRST_PSEUDO_REGISTER
01173 ? hard_regno_nregs[inner_regno][GET_MODE (x)] : 1);
01174
01175 return endregno > inner_regno && regno < inner_endregno;
01176 }
01177 break;
01178
01179 case CLOBBER:
01180 case SET:
01181 if (&SET_DEST (x) != loc
01182
01183
01184
01185 && ((GET_CODE (SET_DEST (x)) == SUBREG
01186 && loc != &SUBREG_REG (SET_DEST (x))
01187 && REG_P (SUBREG_REG (SET_DEST (x)))
01188 && REGNO (SUBREG_REG (SET_DEST (x))) >= FIRST_PSEUDO_REGISTER
01189 && refers_to_regno_p (regno, endregno,
01190 SUBREG_REG (SET_DEST (x)), loc))
01191 || (!REG_P (SET_DEST (x))
01192 && refers_to_regno_p (regno, endregno, SET_DEST (x), loc))))
01193 return 1;
01194
01195 if (code == CLOBBER || loc == &SET_SRC (x))
01196 return 0;
01197 x = SET_SRC (x);
01198 goto repeat;
01199
01200 default:
01201 break;
01202 }
01203
01204
01205
01206 fmt = GET_RTX_FORMAT (code);
01207 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
01208 {
01209 if (fmt[i] == 'e' && loc != &XEXP (x, i))
01210 {
01211 if (i == 0)
01212 {
01213 x = XEXP (x, 0);
01214 goto repeat;
01215 }
01216 else
01217 if (refers_to_regno_p (regno, endregno, XEXP (x, i), loc))
01218 return 1;
01219 }
01220 else if (fmt[i] == 'E')
01221 {
01222 int j;
01223 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
01224 if (loc != &XVECEXP (x, i, j)
01225 && refers_to_regno_p (regno, endregno, XVECEXP (x, i, j), loc))
01226 return 1;
01227 }
01228 }
01229 return 0;
01230 }
01231
01232
01233
01234
01235
01236
01237
01238 int
01239 reg_overlap_mentioned_p (rtx x, rtx in)
01240 {
01241 unsigned int regno, endregno;
01242
01243
01244
01245
01246 if (CONSTANT_P (in))
01247 return 0;
01248
01249 recurse:
01250 switch (GET_CODE (x))
01251 {
01252 case STRICT_LOW_PART:
01253 case ZERO_EXTRACT:
01254 case SIGN_EXTRACT:
01255
01256 x = XEXP (x, 0);
01257 goto recurse;
01258
01259 case SUBREG:
01260 regno = REGNO (SUBREG_REG (x));
01261 if (regno < FIRST_PSEUDO_REGISTER)
01262 regno = subreg_regno (x);
01263 goto do_reg;
01264
01265 case REG:
01266 regno = REGNO (x);
01267 do_reg:
01268 endregno = regno + (regno < FIRST_PSEUDO_REGISTER
01269 ? hard_regno_nregs[regno][GET_MODE (x)] : 1);
01270 return refers_to_regno_p (regno, endregno, in, (rtx*) 0);
01271
01272 case MEM:
01273 {
01274 const char *fmt;
01275 int i;
01276
01277 if (MEM_P (in))
01278 return 1;
01279
01280 fmt = GET_RTX_FORMAT (GET_CODE (in));
01281 for (i = GET_RTX_LENGTH (GET_CODE (in)) - 1; i >= 0; i--)
01282 if (fmt[i] == 'e')
01283 {
01284 if (reg_overlap_mentioned_p (x, XEXP (in, i)))
01285 return 1;
01286 }
01287 else if (fmt[i] == 'E')
01288 {
01289 int j;
01290 for (j = XVECLEN (in, i) - 1; j >= 0; --j)
01291 if (reg_overlap_mentioned_p (x, XVECEXP (in, i, j)))
01292 return 1;
01293 }
01294
01295 return 0;
01296 }
01297
01298 case SCRATCH:
01299 case PC:
01300 case CC0:
01301 return reg_mentioned_p (x, in);
01302
01303 case PARALLEL:
01304 {
01305 int i;
01306
01307
01308 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
01309 if (XEXP (XVECEXP (x, 0, i), 0) != 0
01310 && reg_overlap_mentioned_p (XEXP (XVECEXP (x, 0, i), 0), in))
01311 return 1;
01312 return 0;
01313 }
01314
01315 default:
01316 gcc_assert (CONSTANT_P (x));
01317 return 0;
01318 }
01319 }
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330 void
01331 note_stores (rtx x, void (*fun) (rtx, rtx, void *), void *data)
01332 {
01333 int i;
01334
01335 if (GET_CODE (x) == COND_EXEC)
01336 x = COND_EXEC_CODE (x);
01337
01338 if (GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
01339 {
01340 rtx dest = SET_DEST (x);
01341
01342 while ((GET_CODE (dest) == SUBREG
01343 && (!REG_P (SUBREG_REG (dest))
01344 || REGNO (SUBREG_REG (dest)) >= FIRST_PSEUDO_REGISTER))
01345 || GET_CODE (dest) == ZERO_EXTRACT
01346 || GET_CODE (dest) == STRICT_LOW_PART)
01347 dest = XEXP (dest, 0);
01348
01349
01350
01351 if (GET_CODE (dest) == PARALLEL)
01352 {
01353 for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
01354 if (XEXP (XVECEXP (dest, 0, i), 0) != 0)
01355 (*fun) (XEXP (XVECEXP (dest, 0, i), 0), x, data);
01356 }
01357 else
01358 (*fun) (dest, x, data);
01359 }
01360
01361 else if (GET_CODE (x) == PARALLEL)
01362 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
01363 note_stores (XVECEXP (x, 0, i), fun, data);
01364 }
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375 void
01376 note_uses (rtx *pbody, void (*fun) (rtx *, void *), void *data)
01377 {
01378 rtx body = *pbody;
01379 int i;
01380
01381 switch (GET_CODE (body))
01382 {
01383 case COND_EXEC:
01384 (*fun) (&COND_EXEC_TEST (body), data);
01385 note_uses (&COND_EXEC_CODE (body), fun, data);
01386 return;
01387
01388 case PARALLEL:
01389 for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
01390 note_uses (&XVECEXP (body, 0, i), fun, data);
01391 return;
01392
01393 case USE:
01394 (*fun) (&XEXP (body, 0), data);
01395 return;
01396
01397 case ASM_OPERANDS:
01398 for (i = ASM_OPERANDS_INPUT_LENGTH (body) - 1; i >= 0; i--)
01399 (*fun) (&ASM_OPERANDS_INPUT (body, i), data);
01400 return;
01401
01402 case TRAP_IF:
01403 (*fun) (&TRAP_CONDITION (body), data);
01404 return;
01405
01406 case PREFETCH:
01407 (*fun) (&XEXP (body, 0), data);
01408 return;
01409
01410 case UNSPEC:
01411 case UNSPEC_VOLATILE:
01412 for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
01413 (*fun) (&XVECEXP (body, 0, i), data);
01414 return;
01415
01416 case CLOBBER:
01417 if (MEM_P (XEXP (body, 0)))
01418 (*fun) (&XEXP (XEXP (body, 0), 0), data);
01419 return;
01420
01421 case SET:
01422 {
01423 rtx dest = SET_DEST (body);
01424
01425
01426
01427 (*fun) (&SET_SRC (body), data);
01428
01429 if (GET_CODE (dest) == ZERO_EXTRACT)
01430 {
01431 (*fun) (&XEXP (dest, 1), data);
01432 (*fun) (&XEXP (dest, 2), data);
01433 }
01434
01435 while (GET_CODE (dest) == SUBREG || GET_CODE (dest) == STRICT_LOW_PART)
01436 dest = XEXP (dest, 0);
01437
01438 if (MEM_P (dest))
01439 (*fun) (&XEXP (dest, 0), data);
01440 }
01441 return;
01442
01443 default:
01444
01445 (*fun) (pbody, data);
01446 return;
01447 }
01448 }
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467 int
01468 dead_or_set_p (rtx insn, rtx x)
01469 {
01470 unsigned int regno, last_regno;
01471 unsigned int i;
01472
01473
01474 if (GET_CODE (x) == CC0)
01475 return 1;
01476
01477 gcc_assert (REG_P (x));
01478
01479 regno = REGNO (x);
01480 last_regno = (regno >= FIRST_PSEUDO_REGISTER ? regno
01481 : regno + hard_regno_nregs[regno][GET_MODE (x)] - 1);
01482
01483 for (i = regno; i <= last_regno; i++)
01484 if (! dead_or_set_regno_p (insn, i))
01485 return 0;
01486
01487 return 1;
01488 }
01489
01490
01491
01492
01493
01494 static bool
01495 covers_regno_no_parallel_p (rtx dest, unsigned int test_regno)
01496 {
01497 unsigned int regno, endregno;
01498
01499 if (GET_CODE (dest) == SUBREG
01500 && (((GET_MODE_SIZE (GET_MODE (dest))
01501 + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
01502 == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))
01503 + UNITS_PER_WORD - 1) / UNITS_PER_WORD)))
01504 dest = SUBREG_REG (dest);
01505
01506 if (!REG_P (dest))
01507 return false;
01508
01509 regno = REGNO (dest);
01510 endregno = (regno >= FIRST_PSEUDO_REGISTER ? regno + 1
01511 : regno + hard_regno_nregs[regno][GET_MODE (dest)]);
01512 return (test_regno >= regno && test_regno < endregno);
01513 }
01514
01515
01516
01517
01518 static bool
01519 covers_regno_p (rtx dest, unsigned int test_regno)
01520 {
01521 if (GET_CODE (dest) == PARALLEL)
01522 {
01523
01524
01525
01526 int i;
01527
01528 for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
01529 {
01530 rtx inner = XEXP (XVECEXP (dest, 0, i), 0);
01531 if (inner != NULL_RTX
01532 && covers_regno_no_parallel_p (inner, test_regno))
01533 return true;
01534 }
01535
01536 return false;
01537 }
01538 else
01539 return covers_regno_no_parallel_p (dest, test_regno);
01540 }
01541
01542
01543
01544
01545 int
01546 dead_or_set_regno_p (rtx insn, unsigned int test_regno)
01547 {
01548 rtx pattern;
01549
01550
01551 if (find_regno_note (insn, REG_DEAD, test_regno))
01552 return 1;
01553
01554 if (CALL_P (insn)
01555 && find_regno_fusage (insn, CLOBBER, test_regno))
01556 return 1;
01557
01558 pattern = PATTERN (insn);
01559
01560 if (GET_CODE (pattern) == COND_EXEC)
01561 pattern = COND_EXEC_CODE (pattern);
01562
01563 if (GET_CODE (pattern) == SET)
01564 return covers_regno_p (SET_DEST (pattern), test_regno);
01565 else if (GET_CODE (pattern) == PARALLEL)
01566 {
01567 int i;
01568
01569 for (i = XVECLEN (pattern, 0) - 1; i >= 0; i--)
01570 {
01571 rtx body = XVECEXP (pattern, 0, i);
01572
01573 if (GET_CODE (body) == COND_EXEC)
01574 body = COND_EXEC_CODE (body);
01575
01576 if ((GET_CODE (body) == SET || GET_CODE (body) == CLOBBER)
01577 && covers_regno_p (SET_DEST (body), test_regno))
01578 return 1;
01579 }
01580 }
01581
01582 return 0;
01583 }
01584
01585
01586
01587
01588 rtx
01589 find_reg_note (rtx insn, enum reg_note kind, rtx datum)
01590 {
01591 rtx link;
01592
01593 gcc_assert (insn);
01594
01595
01596 if (! INSN_P (insn))
01597 return 0;
01598 if (datum == 0)
01599 {
01600 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
01601 if (REG_NOTE_KIND (link) == kind)
01602 return link;
01603 return 0;
01604 }
01605
01606 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
01607 if (REG_NOTE_KIND (link) == kind && datum == XEXP (link, 0))
01608 return link;
01609 return 0;
01610 }
01611
01612
01613
01614
01615
01616
01617 rtx
01618 find_regno_note (rtx insn, enum reg_note kind, unsigned int regno)
01619 {
01620 rtx link;
01621
01622
01623 if (! INSN_P (insn))
01624 return 0;
01625
01626 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
01627 if (REG_NOTE_KIND (link) == kind
01628
01629
01630 && REG_P (XEXP (link, 0))
01631 && REGNO (XEXP (link, 0)) <= regno
01632 && ((REGNO (XEXP (link, 0))
01633 + (REGNO (XEXP (link, 0)) >= FIRST_PSEUDO_REGISTER ? 1
01634 : hard_regno_nregs[REGNO (XEXP (link, 0))]
01635 [GET_MODE (XEXP (link, 0))]))
01636 > regno))
01637 return link;
01638 return 0;
01639 }
01640
01641
01642
01643
01644 rtx
01645 find_reg_equal_equiv_note (rtx insn)
01646 {
01647 rtx link;
01648
01649 if (!INSN_P (insn))
01650 return 0;
01651 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
01652 if (REG_NOTE_KIND (link) == REG_EQUAL
01653 || REG_NOTE_KIND (link) == REG_EQUIV)
01654 {
01655 if (single_set (insn) == 0)
01656 return 0;
01657 return link;
01658 }
01659 return NULL;
01660 }
01661
01662
01663
01664
01665 int
01666 find_reg_fusage (rtx insn, enum rtx_code code, rtx datum)
01667 {
01668
01669
01670 if (!CALL_P (insn))
01671 return 0;
01672
01673 gcc_assert (datum);
01674
01675 if (!REG_P (datum))
01676 {
01677 rtx link;
01678
01679 for (link = CALL_INSN_FUNCTION_USAGE (insn);
01680 link;
01681 link = XEXP (link, 1))
01682 if (GET_CODE (XEXP (link, 0)) == code
01683 && rtx_equal_p (datum, XEXP (XEXP (link, 0), 0)))
01684 return 1;
01685 }
01686 else
01687 {
01688 unsigned int regno = REGNO (datum);
01689
01690
01691
01692
01693 if (regno < FIRST_PSEUDO_REGISTER)
01694 {
01695 unsigned int end_regno
01696 = regno + hard_regno_nregs[regno][GET_MODE (datum)];
01697 unsigned int i;
01698
01699 for (i = regno; i < end_regno; i++)
01700 if (find_regno_fusage (insn, code, i))
01701 return 1;
01702 }
01703 }
01704
01705 return 0;
01706 }
01707
01708
01709
01710
01711 int
01712 find_regno_fusage (rtx insn, enum rtx_code code, unsigned int regno)
01713 {
01714 rtx link;
01715
01716
01717
01718
01719 if (regno >= FIRST_PSEUDO_REGISTER
01720 || !CALL_P (insn) )
01721 return 0;
01722
01723 for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
01724 {
01725 unsigned int regnote;
01726 rtx op, reg;
01727
01728 if (GET_CODE (op = XEXP (link, 0)) == code
01729 && REG_P (reg = XEXP (op, 0))
01730 && (regnote = REGNO (reg)) <= regno
01731 && regnote + hard_regno_nregs[regnote][GET_MODE (reg)] > regno)
01732 return 1;
01733 }
01734
01735 return 0;
01736 }
01737
01738
01739
01740 int
01741 pure_call_p (rtx insn)
01742 {
01743 rtx link;
01744
01745 if (!CALL_P (insn) || ! CONST_OR_PURE_CALL_P (insn))
01746 return 0;
01747
01748
01749 for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
01750 {
01751 rtx u, m;
01752
01753 if (GET_CODE (u = XEXP (link, 0)) == USE
01754 && MEM_P (m = XEXP (u, 0)) && GET_MODE (m) == BLKmode
01755 && GET_CODE (XEXP (m, 0)) == SCRATCH)
01756 return 1;
01757 }
01758
01759 return 0;
01760 }
01761
01762
01763
01764 void
01765 remove_note (rtx insn, rtx note)
01766 {
01767 rtx link;
01768
01769 if (note == NULL_RTX)
01770 return;
01771
01772 if (REG_NOTES (insn) == note)
01773 {
01774 REG_NOTES (insn) = XEXP (note, 1);
01775 return;
01776 }
01777
01778 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
01779 if (XEXP (link, 1) == note)
01780 {
01781 XEXP (link, 1) = XEXP (note, 1);
01782 return;
01783 }
01784
01785 gcc_unreachable ();
01786 }
01787
01788
01789
01790
01791
01792 int
01793 in_expr_list_p (rtx listp, rtx node)
01794 {
01795 rtx x;
01796
01797 for (x = listp; x; x = XEXP (x, 1))
01798 if (node == XEXP (x, 0))
01799 return 1;
01800
01801 return 0;
01802 }
01803
01804
01805
01806
01807
01808
01809 void
01810 remove_node_from_expr_list (rtx node, rtx *listp)
01811 {
01812 rtx temp = *listp;
01813 rtx prev = NULL_RTX;
01814
01815 while (temp)
01816 {
01817 if (node == XEXP (temp, 0))
01818 {
01819
01820 if (prev)
01821 XEXP (prev, 1) = XEXP (temp, 1);
01822 else
01823 *listp = XEXP (temp, 1);
01824
01825 return;
01826 }
01827
01828 prev = temp;
01829 temp = XEXP (temp, 1);
01830 }
01831 }
01832
01833
01834
01835
01836
01837
01838 int
01839 volatile_insn_p (rtx x)
01840 {
01841 RTX_CODE code;
01842
01843 code = GET_CODE (x);
01844 switch (code)
01845 {
01846 case LABEL_REF:
01847 case SYMBOL_REF:
01848 case CONST_INT:
01849 case CONST:
01850 case CONST_DOUBLE:
01851 case CONST_VECTOR:
01852 case CC0:
01853 case PC:
01854 case REG:
01855 case SCRATCH:
01856 case CLOBBER:
01857 case ADDR_VEC:
01858 case ADDR_DIFF_VEC:
01859 case CALL:
01860 case MEM:
01861 return 0;
01862
01863 case UNSPEC_VOLATILE:
01864
01865 return 1;
01866
01867 case ASM_INPUT:
01868 case ASM_OPERANDS:
01869 if (MEM_VOLATILE_P (x))
01870 return 1;
01871
01872 default:
01873 break;
01874 }
01875
01876
01877
01878 {
01879 const char *fmt = GET_RTX_FORMAT (code);
01880 int i;
01881
01882 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
01883 {
01884 if (fmt[i] == 'e')
01885 {
01886 if (volatile_insn_p (XEXP (x, i)))
01887 return 1;
01888 }
01889 else if (fmt[i] == 'E')
01890 {
01891 int j;
01892 for (j = 0; j < XVECLEN (x, i); j++)
01893 if (volatile_insn_p (XVECEXP (x, i, j)))
01894 return 1;
01895 }
01896 }
01897 }
01898 return 0;
01899 }
01900
01901
01902
01903
01904 int
01905 volatile_refs_p (rtx x)
01906 {
01907 RTX_CODE code;
01908
01909 code = GET_CODE (x);
01910 switch (code)
01911 {
01912 case LABEL_REF:
01913 case SYMBOL_REF:
01914 case CONST_INT:
01915 case CONST:
01916 case CONST_DOUBLE:
01917 case CONST_VECTOR:
01918 case CC0:
01919 case PC:
01920 case REG:
01921 case SCRATCH:
01922 case CLOBBER:
01923 case ADDR_VEC:
01924 case ADDR_DIFF_VEC:
01925 return 0;
01926
01927 case UNSPEC_VOLATILE:
01928 return 1;
01929
01930 case MEM:
01931 case ASM_INPUT:
01932 case ASM_OPERANDS:
01933 if (MEM_VOLATILE_P (x))
01934 return 1;
01935
01936 default:
01937 break;
01938 }
01939
01940
01941
01942 {
01943 const char *fmt = GET_RTX_FORMAT (code);
01944 int i;
01945
01946 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
01947 {
01948 if (fmt[i] == 'e')
01949 {
01950 if (volatile_refs_p (XEXP (x, i)))
01951 return 1;
01952 }
01953 else if (fmt[i] == 'E')
01954 {
01955 int j;
01956 for (j = 0; j < XVECLEN (x, i); j++)
01957 if (volatile_refs_p (XVECEXP (x, i, j)))
01958 return 1;
01959 }
01960 }
01961 }
01962 return 0;
01963 }
01964
01965
01966
01967
01968 int
01969 side_effects_p (rtx x)
01970 {
01971 RTX_CODE code;
01972
01973 code = GET_CODE (x);
01974 switch (code)
01975 {
01976 case LABEL_REF:
01977 case SYMBOL_REF:
01978 case CONST_INT:
01979 case CONST:
01980 case CONST_DOUBLE:
01981 case CONST_VECTOR:
01982 case CC0:
01983 case PC:
01984 case REG:
01985 case SCRATCH:
01986 case ADDR_VEC:
01987 case ADDR_DIFF_VEC:
01988 return 0;
01989
01990 case CLOBBER:
01991
01992
01993
01994 return (GET_MODE (x) != VOIDmode);
01995
01996 case PRE_INC:
01997 case PRE_DEC:
01998 case POST_INC:
01999 case POST_DEC:
02000 case PRE_MODIFY:
02001 case POST_MODIFY:
02002 case CALL:
02003 case UNSPEC_VOLATILE:
02004
02005 return 1;
02006
02007 case MEM:
02008 case ASM_INPUT:
02009 case ASM_OPERANDS:
02010 if (MEM_VOLATILE_P (x))
02011 return 1;
02012
02013 default:
02014 break;
02015 }
02016
02017
02018
02019 {
02020 const char *fmt = GET_RTX_FORMAT (code);
02021 int i;
02022
02023 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
02024 {
02025 if (fmt[i] == 'e')
02026 {
02027 if (side_effects_p (XEXP (x, i)))
02028 return 1;
02029 }
02030 else if (fmt[i] == 'E')
02031 {
02032 int j;
02033 for (j = 0; j < XVECLEN (x, i); j++)
02034 if (side_effects_p (XVECEXP (x, i, j)))
02035 return 1;
02036 }
02037 }
02038 }
02039 return 0;
02040 }
02041
02042 enum may_trap_p_flags
02043 {
02044 MTP_UNALIGNED_MEMS = 1,
02045 MTP_AFTER_MOVE = 2
02046 };
02047
02048
02049
02050
02051
02052
02053
02054 static int
02055 may_trap_p_1 (rtx x, unsigned flags)
02056 {
02057 int i;
02058 enum rtx_code code;
02059 const char *fmt;
02060 bool unaligned_mems = (flags & MTP_UNALIGNED_MEMS) != 0;
02061
02062 if (x == 0)
02063 return 0;
02064 code = GET_CODE (x);
02065 switch (code)
02066 {
02067
02068 case CONST_INT:
02069 case CONST_DOUBLE:
02070 case CONST_VECTOR:
02071 case SYMBOL_REF:
02072 case LABEL_REF:
02073 case CONST:
02074 case PC:
02075 case CC0:
02076 case REG:
02077 case SCRATCH:
02078 return 0;
02079
02080 case ASM_INPUT:
02081 case UNSPEC_VOLATILE:
02082 case TRAP_IF:
02083 return 1;
02084
02085 case ASM_OPERANDS:
02086 return MEM_VOLATILE_P (x);
02087
02088
02089 case MEM:
02090 if (
02091
02092
02093 !(flags & MTP_AFTER_MOVE)
02094 && MEM_NOTRAP_P (x)
02095 && (!STRICT_ALIGNMENT || !unaligned_mems))
02096 return 0;
02097 return
02098 rtx_addr_can_trap_p_1 (XEXP (x, 0), GET_MODE (x), unaligned_mems);
02099
02100
02101 case DIV:
02102 case MOD:
02103 case UDIV:
02104 case UMOD:
02105 if (HONOR_SNANS (GET_MODE (x)))
02106 return 1;
02107 if (SCALAR_FLOAT_MODE_P (GET_MODE (x)))
02108 return flag_trapping_math;
02109 if (!CONSTANT_P (XEXP (x, 1)) || (XEXP (x, 1) == const0_rtx))
02110 return 1;
02111 break;
02112
02113 case EXPR_LIST:
02114
02115
02116 return 1;
02117
02118 case GE:
02119 case GT:
02120 case LE:
02121 case LT:
02122 case LTGT:
02123 case COMPARE:
02124
02125 if (!flag_trapping_math)
02126 break;
02127
02128
02129
02130
02131 if (HONOR_NANS (GET_MODE (x)))
02132 return 1;
02133
02134
02135 if (HONOR_NANS (GET_MODE (XEXP (x, 0)))
02136 || HONOR_NANS (GET_MODE (XEXP (x, 1))))
02137 return 1;
02138 break;
02139
02140 case EQ:
02141 case NE:
02142 if (HONOR_SNANS (GET_MODE (x)))
02143 return 1;
02144
02145 if (HONOR_SNANS (GET_MODE (XEXP (x, 0)))
02146 || HONOR_SNANS (GET_MODE (XEXP (x, 1))))
02147 return 1;
02148 break;
02149
02150 case FIX:
02151
02152 if (flag_trapping_math && HONOR_NANS (GET_MODE (XEXP (x, 0))))
02153 return 1;
02154 break;
02155
02156 case NEG:
02157 case ABS:
02158 case SUBREG:
02159
02160 break;
02161
02162 default:
02163
02164 if (SCALAR_FLOAT_MODE_P (GET_MODE (x))
02165 && flag_trapping_math)
02166 return 1;
02167 }
02168
02169 fmt = GET_RTX_FORMAT (code);
02170 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
02171 {
02172 if (fmt[i] == 'e')
02173 {
02174 if (may_trap_p_1 (XEXP (x, i), flags))
02175 return 1;
02176 }
02177 else if (fmt[i] == 'E')
02178 {
02179 int j;
02180 for (j = 0; j < XVECLEN (x, i); j++)
02181 if (may_trap_p_1 (XVECEXP (x, i, j), flags))
02182 return 1;
02183 }
02184 }
02185 return 0;
02186 }
02187
02188
02189
02190 int
02191 may_trap_p (rtx x)
02192 {
02193 return may_trap_p_1 (x, 0);
02194 }
02195
02196
02197
02198
02199 int
02200 may_trap_after_code_motion_p (rtx x)
02201 {
02202 return may_trap_p_1 (x, MTP_AFTER_MOVE);
02203 }
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237
02238
02239
02240
02241
02242
02243
02244
02245 int
02246 may_trap_or_fault_p (rtx x)
02247 {
02248 return may_trap_p_1 (x, MTP_UNALIGNED_MEMS);
02249 }
02250
02251
02252
02253
02254 int
02255 inequality_comparisons_p (rtx x)
02256 {
02257 const char *fmt;
02258 int len, i;
02259 enum rtx_code code = GET_CODE (x);
02260
02261 switch (code)
02262 {
02263 case REG:
02264 case SCRATCH:
02265 case PC:
02266 case CC0:
02267 case CONST_INT:
02268 case CONST_DOUBLE:
02269 case CONST_VECTOR:
02270 case CONST:
02271 case LABEL_REF:
02272 case SYMBOL_REF:
02273 return 0;
02274
02275 case LT:
02276 case LTU:
02277 case GT:
02278 case GTU:
02279 case LE:
02280 case LEU:
02281 case GE:
02282 case GEU:
02283 return 1;
02284
02285 default:
02286 break;
02287 }
02288
02289 len = GET_RTX_LENGTH (code);
02290 fmt = GET_RTX_FORMAT (code);
02291
02292 for (i = 0; i < len; i++)
02293 {
02294 if (fmt[i] == 'e')
02295 {
02296 if (inequality_comparisons_p (XEXP (x, i)))
02297 return 1;
02298 }
02299 else if (fmt[i] == 'E')
02300 {
02301 int j;
02302 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
02303 if (inequality_comparisons_p (XVECEXP (x, i, j)))
02304 return 1;
02305 }
02306 }
02307
02308 return 0;
02309 }
02310
02311
02312
02313
02314
02315
02316
02317 rtx
02318 replace_rtx (rtx x, rtx from, rtx to)
02319 {
02320 int i, j;
02321 const char *fmt;
02322
02323
02324
02325 if (x != 0 && GET_CODE (x) == CONST_DOUBLE)
02326 return x;
02327
02328 if (x == from)
02329 return to;
02330
02331
02332 if (x == 0)
02333 return 0;
02334
02335 if (GET_CODE (x) == SUBREG)
02336 {
02337 rtx new = replace_rtx (SUBREG_REG (x), from, to);
02338
02339 if (GET_CODE (new) == CONST_INT)
02340 {
02341 x = simplify_subreg (GET_MODE (x), new,
02342 GET_MODE (SUBREG_REG (x)),
02343 SUBREG_BYTE (x));
02344 gcc_assert (x);
02345 }
02346 else
02347 SUBREG_REG (x) = new;
02348
02349 return x;
02350 }
02351 else if (GET_CODE (x) == ZERO_EXTEND)
02352 {
02353 rtx new = replace_rtx (XEXP (x, 0), from, to);
02354
02355 if (GET_CODE (new) == CONST_INT)
02356 {
02357 x = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x),
02358 new, GET_MODE (XEXP (x, 0)));
02359 gcc_assert (x);
02360 }
02361 else
02362 XEXP (x, 0) = new;
02363
02364 return x;
02365 }
02366
02367 fmt = GET_RTX_FORMAT (GET_CODE (x));
02368 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
02369 {
02370 if (fmt[i] == 'e')
02371 XEXP (x, i) = replace_rtx (XEXP (x, i), from, to);
02372 else if (fmt[i] == 'E')
02373 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
02374 XVECEXP (x, i, j) = replace_rtx (XVECEXP (x, i, j), from, to);
02375 }
02376
02377 return x;
02378 }
02379
02380
02381
02382
02383 int
02384 replace_label (rtx *x, void *data)
02385 {
02386 rtx l = *x;
02387 rtx old_label = ((replace_label_data *) data)->r1;
02388 rtx new_label = ((replace_label_data *) data)->r2;
02389 bool update_label_nuses = ((replace_label_data *) data)->update_label_nuses;
02390
02391 if (l == NULL_RTX)
02392 return 0;
02393
02394 if (GET_CODE (l) == SYMBOL_REF
02395 && CONSTANT_POOL_ADDRESS_P (l))
02396 {
02397 rtx c = get_pool_constant (l);
02398 if (rtx_referenced_p (old_label, c))
02399 {
02400 rtx new_c, new_l;
02401 replace_label_data *d = (replace_label_data *) data;
02402
02403
02404
02405
02406 new_c = copy_rtx (c);
02407 d->update_label_nuses = false;
02408 for_each_rtx (&new_c, replace_label, data);
02409 d->update_label_nuses = update_label_nuses;
02410
02411
02412
02413 new_l = XEXP (force_const_mem (get_pool_mode (l), new_c), 0);
02414 *x = replace_rtx (l, l, new_l);
02415 }
02416 return 0;
02417 }
02418
02419
02420
02421
02422 if (JUMP_P (l) && JUMP_LABEL (l) == old_label)
02423 JUMP_LABEL (l) = new_label;
02424
02425 if ((GET_CODE (l) == LABEL_REF
02426 || GET_CODE (l) == INSN_LIST)
02427 && XEXP (l, 0) == old_label)
02428 {
02429 XEXP (l, 0) = new_label;
02430 if (update_label_nuses)
02431 {
02432 ++LABEL_NUSES (new_label);
02433 --LABEL_NUSES (old_label);
02434 }
02435 return 0;
02436 }
02437
02438 return 0;
02439 }
02440
02441
02442
02443
02444
02445 static int
02446 rtx_referenced_p_1 (rtx *body, void *x)
02447 {
02448 rtx y = (rtx) x;
02449
02450 if (*body == NULL_RTX)
02451 return y == NULL_RTX;
02452
02453
02454 if (GET_CODE (*body) == LABEL_REF && LABEL_P (y))
02455 return XEXP (*body, 0) == y;
02456
02457
02458 if (GET_CODE (*body) == SYMBOL_REF
02459 && CONSTANT_POOL_ADDRESS_P (*body))
02460 return rtx_referenced_p (y, get_pool_constant (*body));
02461
02462
02463 return rtx_equal_p (*body, y);
02464 }
02465
02466
02467
02468 int
02469 rtx_referenced_p (rtx x, rtx body)
02470 {
02471 return for_each_rtx (&body, rtx_referenced_p_1, x);
02472 }
02473
02474
02475
02476
02477 bool
02478 tablejump_p (rtx insn, rtx *labelp, rtx *tablep)
02479 {
02480 rtx label, table;
02481
02482 if (JUMP_P (insn)
02483 && (label = JUMP_LABEL (insn)) != NULL_RTX
02484 && (table = next_active_insn (label)) != NULL_RTX
02485 && JUMP_P (table)
02486 && (GET_CODE (PATTERN (table)) == ADDR_VEC
02487 || GET_CODE (PATTERN (table)) == ADDR_DIFF_VEC))
02488 {
02489 if (labelp)
02490 *labelp = label;
02491 if (tablep)
02492 *tablep = table;
02493 return true;
02494 }
02495 return false;
02496 }
02497
02498
02499
02500
02501
02502 static int
02503 computed_jump_p_1 (rtx x)
02504 {
02505 enum rtx_code code = GET_CODE (x);
02506 int i, j;
02507 const char *fmt;
02508
02509 switch (code)
02510 {
02511 case LABEL_REF:
02512 case PC:
02513 return 0;
02514
02515 case CONST:
02516 case CONST_INT:
02517 case CONST_DOUBLE:
02518 case CONST_VECTOR:
02519 case SYMBOL_REF:
02520 case REG:
02521 return 1;
02522
02523 case MEM:
02524 return ! (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
02525 && CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)));
02526
02527 case IF_THEN_ELSE:
02528 return (computed_jump_p_1 (XEXP (x, 1))
02529 || computed_jump_p_1 (XEXP (x, 2)));
02530
02531 default:
02532 break;
02533 }
02534
02535 fmt = GET_RTX_FORMAT (code);
02536 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
02537 {
02538 if (fmt[i] == 'e'
02539 && computed_jump_p_1 (XEXP (x, i)))
02540 return 1;
02541
02542 else if (fmt[i] == 'E')
02543 for (j = 0; j < XVECLEN (x, i); j++)
02544 if (computed_jump_p_1 (XVECEXP (x, i, j)))
02545 return 1;
02546 }
02547
02548 return 0;
02549 }
02550
02551
02552
02553
02554
02555
02556 int
02557 computed_jump_p (rtx insn)
02558 {
02559 int i;
02560 if (JUMP_P (insn))
02561 {
02562 rtx pat = PATTERN (insn);
02563
02564 if (find_reg_note (insn, REG_LABEL, NULL_RTX))
02565 return 0;
02566 else if (GET_CODE (pat) == PARALLEL)
02567 {
02568 int len = XVECLEN (pat, 0);
02569 int has_use_labelref = 0;
02570
02571 for (i = len - 1; i >= 0; i--)
02572 if (GET_CODE (XVECEXP (pat, 0, i)) == USE
02573 && (GET_CODE (XEXP (XVECEXP (pat, 0, i), 0))
02574 == LABEL_REF))
02575 has_use_labelref = 1;
02576
02577 if (! has_use_labelref)
02578 for (i = len - 1; i >= 0; i--)
02579 if (GET_CODE (XVECEXP (pat, 0, i)) == SET
02580 && SET_DEST (XVECEXP (pat, 0, i)) == pc_rtx
02581 && computed_jump_p_1 (SET_SRC (XVECEXP (pat, 0, i))))
02582 return 1;
02583 }
02584 else if (GET_CODE (pat) == SET
02585 && SET_DEST (pat) == pc_rtx
02586 && computed_jump_p_1 (SET_SRC (pat)))
02587 return 1;
02588 }
02589 return 0;
02590 }
02591
02592
02593
02594 static int
02595 for_each_rtx_1 (rtx exp, int n, rtx_function f, void *data)
02596 {
02597 int result, i, j;
02598 const char *format = GET_RTX_FORMAT (GET_CODE (exp));
02599 rtx *x;
02600
02601 for (; format[n] != '\0'; n++)
02602 {
02603 switch (format[n])
02604 {
02605 case 'e':
02606
02607 x = &XEXP (exp, n);
02608 result = (*f) (x, data);
02609 if (result == -1)
02610
02611 continue;
02612 else if (result != 0)
02613
02614 return result;
02615
02616 if (*x == NULL_RTX)
02617
02618 continue;
02619
02620 i = non_rtx_starting_operands[GET_CODE (*x)];
02621 if (i >= 0)
02622 {
02623 result = for_each_rtx_1 (*x, i, f, data);
02624 if (result != 0)
02625 return result;
02626 }
02627 break;
02628
02629 case 'V':
02630 case 'E':
02631 if (XVEC (exp, n) == 0)
02632 continue;
02633 for (j = 0; j < XVECLEN (exp, n); ++j)
02634 {
02635
02636 x = &XVECEXP (exp, n, j);
02637 result = (*f) (x, data);
02638 if (result == -1)
02639
02640 continue;
02641 else if (result != 0)
02642
02643 return result;
02644
02645 if (*x == NULL_RTX)
02646
02647 continue;
02648
02649 i = non_rtx_starting_operands[GET_CODE (*x)];
02650 if (i >= 0)
02651 {
02652 result = for_each_rtx_1 (*x, i, f, data);
02653 if (result != 0)
02654 return result;
02655 }
02656 }
02657 break;
02658
02659 default:
02660
02661 break;
02662 }
02663 }
02664
02665 return 0;
02666 }
02667
02668
02669
02670
02671
02672
02673
02674
02675
02676
02677
02678
02679
02680
02681 int
02682 for_each_rtx (rtx *x, rtx_function f, void *data)
02683 {
02684 int result;
02685 int i;
02686
02687
02688 result = (*f) (x, data);
02689 if (result == -1)
02690
02691 return 0;
02692 else if (result != 0)
02693
02694 return result;
02695
02696 if (*x == NULL_RTX)
02697
02698 return 0;
02699
02700 i = non_rtx_starting_operands[GET_CODE (*x)];
02701 if (i < 0)
02702 return 0;
02703
02704 return for_each_rtx_1 (*x, i, f, data);
02705 }
02706
02707
02708
02709
02710
02711 rtx
02712 regno_use_in (unsigned int regno, rtx x)
02713 {
02714 const char *fmt;
02715 int i, j;
02716 rtx tem;
02717
02718 if (REG_P (x) && REGNO (x) == regno)
02719 return x;
02720
02721 fmt = GET_RTX_FORMAT (GET_CODE (x));
02722 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
02723 {
02724 if (fmt[i] == 'e')
02725 {
02726 if ((tem = regno_use_in (regno, XEXP (x, i))))
02727 return tem;
02728 }
02729 else if (fmt[i] == 'E')
02730 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
02731 if ((tem = regno_use_in (regno , XVECEXP (x, i, j))))
02732 return tem;
02733 }
02734
02735 return NULL_RTX;
02736 }
02737
02738
02739
02740
02741
02742
02743
02744 int
02745 commutative_operand_precedence (rtx op)
02746 {
02747 enum rtx_code code = GET_CODE (op);
02748
02749
02750 if (code == CONST_INT)
02751 return -7;
02752 if (code == CONST_DOUBLE)
02753 return -6;
02754 op = avoid_constant_pool_reference (op);
02755 code = GET_CODE (op);
02756
02757 switch (GET_RTX_CLASS (code))
02758 {
02759 case RTX_CONST_OBJ:
02760 if (code == CONST_INT)
02761 return -5;
02762 if (code == CONST_DOUBLE)
02763 return -4;
02764 return -3;
02765
02766 case RTX_EXTRA:
02767
02768 if (code == SUBREG && OBJECT_P (SUBREG_REG (op)))
02769 return -2;
02770
02771 if (!CONSTANT_P (op))
02772 return 0;
02773 else
02774
02775 return -3;
02776
02777 case RTX_OBJ:
02778
02779
02780 return -1;
02781
02782 case RTX_COMM_ARITH:
02783
02784
02785
02786 return 4;
02787
02788 case RTX_BIN_ARITH:
02789
02790
02791
02792 return 2;
02793
02794 case RTX_UNARY:
02795
02796 if (code == NEG || code == NOT)
02797 return 1;
02798
02799 default:
02800 return 0;
02801 }
02802 }
02803
02804
02805
02806
02807 int
02808 swap_commutative_operands_p (rtx x, rtx y)
02809 {
02810 return (commutative_operand_precedence (x)
02811 < commutative_operand_precedence (y));
02812 }
02813
02814
02815
02816 int
02817 auto_inc_p (rtx x)
02818 {
02819 switch (GET_CODE (x))
02820 {
02821 case PRE_INC:
02822 case POST_INC:
02823 case PRE_DEC:
02824 case POST_DEC:
02825 case PRE_MODIFY:
02826 case POST_MODIFY:
02827
02828 if (XEXP (x, 0) != stack_pointer_rtx)
02829 return 1;
02830 default:
02831 break;
02832 }
02833 return 0;
02834 }
02835
02836
02837 int
02838 loc_mentioned_in_p (rtx *loc, rtx in)
02839 {
02840 enum rtx_code code = GET_CODE (in);
02841 const char *fmt = GET_RTX_FORMAT (code);
02842 int i, j;
02843
02844 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
02845 {
02846 if (loc == &in->u.fld[i].rt_rtx)
02847 return 1;
02848 if (fmt[i] == 'e')
02849 {
02850 if (loc_mentioned_in_p (loc, XEXP (in, i)))
02851 return 1;
02852 }
02853 else if (fmt[i] == 'E')
02854 for (j = XVECLEN (in, i) - 1; j >= 0; j--)
02855 if (loc_mentioned_in_p (loc, XVECEXP (in, i, j)))
02856 return 1;
02857 }
02858 return 0;
02859 }
02860
02861
02862
02863
02864
02865 unsigned int
02866 subreg_lsb_1 (enum machine_mode outer_mode,
02867 enum machine_mode inner_mode,
02868 unsigned int subreg_byte)
02869 {
02870 unsigned int bitpos;
02871 unsigned int byte;
02872 unsigned int word;
02873
02874
02875 if (GET_MODE_BITSIZE (outer_mode) > GET_MODE_BITSIZE (inner_mode))
02876 return 0;
02877
02878 if (WORDS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
02879
02880
02881 gcc_assert (!((subreg_byte % UNITS_PER_WORD
02882 + GET_MODE_SIZE (outer_mode)) > UNITS_PER_WORD
02883 && (subreg_byte % UNITS_PER_WORD
02884 || GET_MODE_SIZE (outer_mode) % UNITS_PER_WORD)));
02885
02886 if (WORDS_BIG_ENDIAN)
02887 word = (GET_MODE_SIZE (inner_mode)
02888 - (subreg_byte + GET_MODE_SIZE (outer_mode))) / UNITS_PER_WORD;
02889 else
02890 word = subreg_byte / UNITS_PER_WORD;
02891 bitpos = word * BITS_PER_WORD;
02892
02893 if (BYTES_BIG_ENDIAN)
02894 byte = (GET_MODE_SIZE (inner_mode)
02895 - (subreg_byte + GET_MODE_SIZE (outer_mode))) % UNITS_PER_WORD;
02896 else
02897 byte = subreg_byte % UNITS_PER_WORD;
02898 bitpos += byte * BITS_PER_UNIT;
02899
02900 return bitpos;
02901 }
02902
02903
02904
02905
02906 unsigned int
02907 subreg_lsb (rtx x)
02908 {
02909 return subreg_lsb_1 (GET_MODE (x), GET_MODE (SUBREG_REG (x)),
02910 SUBREG_BYTE (x));
02911 }
02912
02913
02914
02915
02916
02917
02918
02919 unsigned int
02920 subreg_regno_offset (unsigned int xregno, enum machine_mode xmode,
02921 unsigned int offset, enum machine_mode ymode)
02922 {
02923 int nregs_xmode, nregs_ymode;
02924 int mode_multiple, nregs_multiple;
02925 int y_offset;
02926
02927 gcc_assert (xregno < FIRST_PSEUDO_REGISTER);
02928
02929
02930 if (HARD_REGNO_NREGS_HAS_PADDING (xregno, xmode))
02931 nregs_xmode = HARD_REGNO_NREGS_WITH_PADDING (xregno, xmode);
02932 else
02933 nregs_xmode = hard_regno_nregs[xregno][xmode];
02934
02935 nregs_ymode = hard_regno_nregs[xregno][ymode];
02936
02937
02938
02939
02940 if (offset == 0
02941 && nregs_ymode > nregs_xmode
02942 && (GET_MODE_SIZE (ymode) > UNITS_PER_WORD
02943 ? WORDS_BIG_ENDIAN : BYTES_BIG_ENDIAN))
02944 return nregs_xmode - nregs_ymode;
02945
02946 if (offset == 0 || nregs_xmode == nregs_ymode)
02947 return 0;
02948
02949
02950 mode_multiple = GET_MODE_SIZE (xmode) / GET_MODE_SIZE (ymode);
02951 gcc_assert (mode_multiple != 0);
02952
02953 y_offset = offset / GET_MODE_SIZE (ymode);
02954 nregs_multiple = nregs_xmode / nregs_ymode;
02955 return (y_offset / (mode_multiple / nregs_multiple)) * nregs_ymode;
02956 }
02957
02958
02959
02960
02961
02962
02963
02964
02965 bool
02966 subreg_offset_representable_p (unsigned int xregno, enum machine_mode xmode,
02967 unsigned int offset, enum machine_mode ymode)
02968 {
02969 int nregs_xmode, nregs_ymode;
02970 int mode_multiple, nregs_multiple;
02971 int y_offset;
02972 int regsize_xmode, regsize_ymode;
02973
02974 gcc_assert (xregno < FIRST_PSEUDO_REGISTER);
02975
02976
02977
02978 if (HARD_REGNO_NREGS_HAS_PADDING (xregno, xmode))
02979 {
02980 enum machine_mode xmode_unit;
02981
02982 nregs_xmode = HARD_REGNO_NREGS_WITH_PADDING (xregno, xmode);
02983 if (GET_MODE_INNER (xmode) == VOIDmode)
02984 xmode_unit = xmode;
02985 else
02986 xmode_unit = GET_MODE_INNER (xmode);
02987 gcc_assert (HARD_REGNO_NREGS_HAS_PADDING (xregno, xmode_unit));
02988 gcc_assert (nregs_xmode
02989 == (GET_MODE_NUNITS (xmode)
02990 * HARD_REGNO_NREGS_WITH_PADDING (xregno, xmode_unit)));
02991 gcc_assert (hard_regno_nregs[xregno][xmode]
02992 == (hard_regno_nregs[xregno][xmode_unit]
02993 * GET_MODE_NUNITS (xmode)));
02994
02995
02996
02997
02998
02999
03000
03001
03002
03003 if ((offset / GET_MODE_SIZE (xmode_unit) + 1
03004 < GET_MODE_NUNITS (xmode))
03005 && (offset / GET_MODE_SIZE (xmode_unit)
03006 != ((offset + GET_MODE_SIZE (ymode) - 1)
03007 / GET_MODE_SIZE (xmode_unit))))
03008 return false;
03009 }
03010 else
03011 nregs_xmode = hard_regno_nregs[xregno][xmode];
03012
03013 nregs_ymode = hard_regno_nregs[xregno][ymode];
03014
03015
03016 if (offset == 0
03017 && nregs_ymode > nregs_xmode
03018 && (GET_MODE_SIZE (ymode) > UNITS_PER_WORD
03019 ? WORDS_BIG_ENDIAN : BYTES_BIG_ENDIAN))
03020 return true;
03021
03022
03023
03024 regsize_xmode = GET_MODE_SIZE (xmode) / nregs_xmode;
03025 regsize_ymode = GET_MODE_SIZE (ymode) / nregs_ymode;
03026 if (regsize_xmode > regsize_ymode && nregs_ymode > 1)
03027 return false;
03028 if (regsize_ymode > regsize_xmode && nregs_xmode > 1)
03029 return false;
03030
03031
03032 if (offset == subreg_lowpart_offset (ymode, xmode))
03033 return true;
03034
03035
03036
03037
03038 gcc_assert ((GET_MODE_SIZE (xmode) % GET_MODE_SIZE (ymode)) == 0);
03039 gcc_assert ((nregs_xmode % nregs_ymode) == 0);
03040
03041
03042
03043
03044 offset -= subreg_lowpart_offset (ymode,
03045 mode_for_size (GET_MODE_BITSIZE (xmode)
03046 / nregs_xmode,
03047 MODE_INT, 0));
03048
03049
03050 mode_multiple = GET_MODE_SIZE (xmode) / GET_MODE_SIZE (ymode);
03051 gcc_assert (mode_multiple != 0);
03052
03053 y_offset = offset / GET_MODE_SIZE (ymode);
03054 nregs_multiple = nregs_xmode / nregs_ymode;
03055
03056 gcc_assert ((offset % GET_MODE_SIZE (ymode)) == 0);
03057 gcc_assert ((mode_multiple % nregs_multiple) == 0);
03058
03059 return (!(y_offset % (mode_multiple / nregs_multiple)));
03060 }
03061
03062
03063 unsigned int
03064 subreg_regno (rtx x)
03065 {
03066 unsigned int ret;
03067 rtx subreg = SUBREG_REG (x);
03068 int regno = REGNO (subreg);
03069
03070 ret = regno + subreg_regno_offset (regno,
03071 GET_MODE (subreg),
03072 SUBREG_BYTE (x),
03073 GET_MODE (x));
03074 return ret;
03075
03076 }
03077 struct parms_set_data
03078 {
03079 int nregs;
03080 HARD_REG_SET regs;
03081 };
03082
03083
03084 static void
03085 parms_set (rtx x, rtx pat ATTRIBUTE_UNUSED, void *data)
03086 {
03087 struct parms_set_data *d = data;
03088 if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER
03089 && TEST_HARD_REG_BIT (d->regs, REGNO (x)))
03090 {
03091 CLEAR_HARD_REG_BIT (d->regs, REGNO (x));
03092 d->nregs--;
03093 }
03094 }
03095
03096
03097
03098
03099
03100
03101 rtx
03102 find_first_parameter_load (rtx call_insn, rtx boundary)
03103 {
03104 struct parms_set_data parm;
03105 rtx p, before, first_set;
03106
03107
03108
03109
03110 CLEAR_HARD_REG_SET (parm.regs);
03111 parm.nregs = 0;
03112 for (p = CALL_INSN_FUNCTION_USAGE (call_insn); p; p = XEXP (p, 1))
03113 if (GET_CODE (XEXP (p, 0)) == USE
03114 && REG_P (XEXP (XEXP (p, 0), 0)))
03115 {
03116 gcc_assert (REGNO (XEXP (XEXP (p, 0), 0)) < FIRST_PSEUDO_REGISTER);
03117
03118
03119
03120 if (!FUNCTION_ARG_REGNO_P (REGNO (XEXP (XEXP (p, 0), 0))))
03121 continue;
03122
03123 SET_HARD_REG_BIT (parm.regs, REGNO (XEXP (XEXP (p, 0), 0)));
03124 parm.nregs++;
03125 }
03126 before = call_insn;
03127 first_set = call_insn;
03128
03129
03130 while (parm.nregs && before != boundary)
03131 {
03132 before = PREV_INSN (before);
03133
03134
03135
03136 if (CALL_P (before))
03137 break;
03138
03139
03140
03141
03142
03143 if (LABEL_P (before))
03144 {
03145 gcc_assert (before == boundary);
03146 break;
03147 }
03148
03149 if (INSN_P (before))
03150 {
03151 int nregs_old = parm.nregs;
03152 note_stores (PATTERN (before), parms_set, &parm);
03153
03154
03155
03156
03157 if (nregs_old != parm.nregs)
03158 first_set = before;
03159 else
03160 break;
03161 }
03162 }
03163 return first_set;
03164 }
03165
03166
03167
03168
03169 bool
03170 keep_with_call_p (rtx insn)
03171 {
03172 rtx set;
03173
03174 if (INSN_P (insn) && (set = single_set (insn)) != NULL)
03175 {
03176 if (REG_P (SET_DEST (set))
03177 && REGNO (SET_DEST (set)) < FIRST_PSEUDO_REGISTER
03178 && fixed_regs[REGNO (SET_DEST (set))]
03179 && general_operand (SET_SRC (set), VOIDmode))
03180 return true;
03181 if (REG_P (SET_SRC (set))
03182 && FUNCTION_VALUE_REGNO_P (REGNO (SET_SRC (set)))
03183 && REG_P (SET_DEST (set))
03184 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
03185 return true;
03186
03187
03188
03189 if (SET_DEST (set) == stack_pointer_rtx)
03190 {
03191 rtx i2 = next_nonnote_insn (insn);
03192 if (i2 && keep_with_call_p (i2))
03193 return true;
03194 }
03195 }
03196 return false;
03197 }
03198
03199
03200
03201
03202
03203
03204 bool
03205 label_is_jump_target_p (rtx label, rtx jump_insn)
03206 {
03207 rtx tmp = JUMP_LABEL (jump_insn);
03208
03209 if (label == tmp)
03210 return true;
03211
03212 if (tablejump_p (jump_insn, NULL, &tmp))
03213 {
03214 rtvec vec = XVEC (PATTERN (tmp),
03215 GET_CODE (PATTERN (tmp)) == ADDR_DIFF_VEC);
03216 int i, veclen = GET_NUM_ELEM (vec);
03217
03218 for (i = 0; i < veclen; ++i)
03219 if (XEXP (RTVEC_ELT (vec, i), 0) == label)
03220 return true;
03221 }
03222
03223 return false;
03224 }
03225
03226
03227
03228
03229
03230
03231
03232 int
03233 rtx_cost (rtx x, enum rtx_code outer_code ATTRIBUTE_UNUSED)
03234 {
03235 int i, j;
03236 enum rtx_code code;
03237 const char *fmt;
03238 int total;
03239
03240 if (x == 0)
03241 return 0;
03242
03243
03244
03245
03246 code = GET_CODE (x);
03247 switch (code)
03248 {
03249 case MULT:
03250 total = COSTS_N_INSNS (5);
03251 break;
03252 case DIV:
03253 case UDIV:
03254 case MOD:
03255 case UMOD:
03256 total = COSTS_N_INSNS (7);
03257 break;
03258 case USE:
03259
03260 total = 0;
03261 break;
03262 default:
03263 total = COSTS_N_INSNS (1);
03264 }
03265
03266 switch (code)
03267 {
03268 case REG:
03269 return 0;
03270
03271 case SUBREG:
03272 total = 0;
03273
03274
03275 if (! MODES_TIEABLE_P (GET_MODE (x), GET_MODE (SUBREG_REG (x))))
03276 return COSTS_N_INSNS (2
03277 + GET_MODE_SIZE (GET_MODE (x)) / UNITS_PER_WORD);
03278 break;
03279
03280 default:
03281 if (targetm.rtx_costs (x, code, outer_code, &total))
03282 return total;
03283 break;
03284 }
03285
03286
03287
03288
03289 fmt = GET_RTX_FORMAT (code);
03290 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
03291 if (fmt[i] == 'e')
03292 total += rtx_cost (XEXP (x, i), code);
03293 else if (fmt[i] == 'E')
03294 for (j = 0; j < XVECLEN (x, i); j++)
03295 total += rtx_cost (XVECEXP (x, i, j), code);
03296
03297 return total;
03298 }
03299
03300
03301
03302
03303 int
03304 address_cost (rtx x, enum machine_mode mode)
03305 {
03306
03307
03308
03309
03310 if (!memory_address_p (mode, x))
03311 return 1000;
03312
03313 return targetm.address_cost (x);
03314 }
03315
03316
03317
03318 int
03319 default_address_cost (rtx x)
03320 {
03321 return rtx_cost (x, MEM);
03322 }
03323
03324
03325 unsigned HOST_WIDE_INT
03326 nonzero_bits (rtx x, enum machine_mode mode)
03327 {
03328 return cached_nonzero_bits (x, mode, NULL_RTX, VOIDmode, 0);
03329 }
03330
03331 unsigned int
03332 num_sign_bit_copies (rtx x, enum machine_mode mode)
03333 {
03334 return cached_num_sign_bit_copies (x, mode, NULL_RTX, VOIDmode, 0);
03335 }
03336
03337
03338
03339
03340
03341 static unsigned HOST_WIDE_INT
03342 cached_nonzero_bits (rtx x, enum machine_mode mode, rtx known_x,
03343 enum machine_mode known_mode,
03344 unsigned HOST_WIDE_INT known_ret)
03345 {
03346 if (x == known_x && mode == known_mode)
03347 return known_ret;
03348
03349
03350
03351
03352
03353 if (ARITHMETIC_P (x))
03354 {
03355 rtx x0 = XEXP (x, 0);
03356 rtx x1 = XEXP (x, 1);
03357
03358
03359 if (x0 == x1)
03360 return nonzero_bits1 (x, mode, x0, mode,
03361 cached_nonzero_bits (x0, mode, known_x,
03362 known_mode, known_ret));
03363
03364
03365 if (ARITHMETIC_P (x0)
03366 && (x1 == XEXP (x0, 0) || x1 == XEXP (x0, 1)))
03367 return nonzero_bits1 (x, mode, x1, mode,
03368 cached_nonzero_bits (x1, mode, known_x,
03369 known_mode, known_ret));
03370
03371 if (ARITHMETIC_P (x1)
03372 && (x0 == XEXP (x1, 0) || x0 == XEXP (x1, 1)))
03373 return nonzero_bits1 (x, mode, x0, mode,
03374 cached_nonzero_bits (x0, mode, known_x,
03375 known_mode, known_ret));
03376 }
03377
03378 return nonzero_bits1 (x, mode, known_x, known_mode, known_ret);
03379 }
03380
03381
03382
03383
03384
03385
03386 #define cached_num_sign_bit_copies sorry_i_am_preventing_exponential_behavior
03387
03388
03389
03390
03391
03392
03393
03394 static unsigned HOST_WIDE_INT
03395 nonzero_bits1 (rtx x, enum machine_mode mode, rtx known_x,
03396 enum machine_mode known_mode,
03397 unsigned HOST_WIDE_INT known_ret)
03398 {
03399 unsigned HOST_WIDE_INT nonzero = GET_MODE_MASK (mode);
03400 unsigned HOST_WIDE_INT inner_nz;
03401 enum rtx_code code;
03402 unsigned int mode_width = GET_MODE_BITSIZE (mode);
03403
03404
03405 if (FLOAT_MODE_P (GET_MODE (x)) || FLOAT_MODE_P (mode))
03406 return nonzero;
03407
03408
03409 if (GET_MODE_BITSIZE (GET_MODE (x)) > mode_width)
03410 {
03411 mode = GET_MODE (x);
03412 nonzero = GET_MODE_MASK (mode);
03413 mode_width = GET_MODE_BITSIZE (mode);
03414 }
03415
03416 if (mode_width > HOST_BITS_PER_WIDE_INT)
03417
03418
03419 return nonzero;
03420
03421 #ifndef WORD_REGISTER_OPERATIONS
03422
03423
03424
03425
03426
03427
03428
03429 if (GET_MODE (x) != VOIDmode && GET_MODE (x) != mode
03430 && GET_MODE_BITSIZE (GET_MODE (x)) <= BITS_PER_WORD
03431 && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT
03432 && GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (GET_MODE (x)))
03433 {
03434 nonzero &= cached_nonzero_bits (x, GET_MODE (x),
03435 known_x, known_mode, known_ret);
03436 nonzero |= GET_MODE_MASK (mode) & ~GET_MODE_MASK (GET_MODE (x));
03437 return nonzero;
03438 }
03439 #endif
03440
03441 code = GET_CODE (x);
03442 switch (code)
03443 {
03444 case REG:
03445 #if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
03446
03447
03448 if (POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode
03449 && REG_POINTER (x))
03450 nonzero &= GET_MODE_MASK (ptr_mode);
03451 #endif
03452
03453
03454
03455
03456
03457 if ((x == stack_pointer_rtx
03458 || x == frame_pointer_rtx
03459 || x == arg_pointer_rtx)
03460 && REGNO_POINTER_ALIGN (REGNO (x)))
03461 {
03462 unsigned HOST_WIDE_INT alignment
03463 = REGNO_POINTER_ALIGN (REGNO (x)) / BITS_PER_UNIT;
03464
03465 #ifdef PUSH_ROUNDING
03466
03467
03468
03469 if (x == stack_pointer_rtx && PUSH_ARGS)
03470 alignment = MIN ((unsigned HOST_WIDE_INT) PUSH_ROUNDING (1),
03471 alignment);
03472 #endif
03473
03474 nonzero &= ~(alignment - 1);
03475 }
03476
03477 {
03478 unsigned HOST_WIDE_INT nonzero_for_hook = nonzero;
03479 rtx new = rtl_hooks.reg_nonzero_bits (x, mode, known_x,
03480 known_mode, known_ret,
03481 &nonzero_for_hook);
03482
03483 if (new)
03484 nonzero_for_hook &= cached_nonzero_bits (new, mode, known_x,
03485 known_mode, known_ret);
03486
03487 return nonzero_for_hook;
03488 }
03489
03490 case CONST_INT:
03491 #ifdef SHORT_IMMEDIATES_SIGN_EXTEND
03492
03493 if (INTVAL (x) > 0 && mode_width < BITS_PER_WORD
03494 && 0 != (INTVAL (x) & ((HOST_WIDE_INT) 1 << (mode_width - 1))))
03495 return (INTVAL (x) | ((HOST_WIDE_INT) (-1) << mode_width));
03496 #endif
03497
03498 return INTVAL (x);
03499
03500 case MEM:
03501 #ifdef LOAD_EXTEND_OP
03502
03503
03504
03505 if (LOAD_EXTEND_OP (GET_MODE (x)) == ZERO_EXTEND)
03506 nonzero &= GET_MODE_MASK (GET_MODE (x));
03507 #endif
03508 break;
03509
03510 case EQ: case NE:
03511 case UNEQ: case LTGT:
03512 case GT: case GTU: case UNGT:
03513 case LT: case LTU: case UNLT:
03514 case GE: case GEU: case UNGE:
03515 case LE: case LEU: case UNLE:
03516 case UNORDERED: case ORDERED:
03517
03518
03519
03520
03521
03522
03523
03524 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT
03525 && mode_width <= HOST_BITS_PER_WIDE_INT)
03526 nonzero = STORE_FLAG_VALUE;
03527 break;
03528
03529 case NEG:
03530 #if 0
03531
03532
03533 if (num_sign_bit_copies (XEXP (x, 0), GET_MODE (x))
03534 == GET_MODE_BITSIZE (GET_MODE (x)))
03535 nonzero = 1;
03536 #endif
03537
03538 if (GET_MODE_SIZE (GET_MODE (x)) < mode_width)
03539 nonzero |= (GET_MODE_MASK (mode) & ~GET_MODE_MASK (GET_MODE (x)));
03540 break;
03541
03542 case ABS:
03543 #if 0
03544
03545
03546 if (num_sign_bit_copies (XEXP (x, 0), GET_MODE (x))
03547 == GET_MODE_BITSIZE (GET_MODE (x)))
03548 nonzero = 1;
03549 #endif
03550 break;
03551
03552 case TRUNCATE:
03553 nonzero &= (cached_nonzero_bits (XEXP (x, 0), mode,
03554 known_x, known_mode, known_ret)
03555 & GET_MODE_MASK (mode));
03556 break;
03557
03558 case ZERO_EXTEND:
03559 nonzero &= cached_nonzero_bits (XEXP (x, 0), mode,
03560 known_x, known_mode, known_ret);
03561 if (GET_MODE (XEXP (x, 0)) != VOIDmode)
03562 nonzero &= GET_MODE_MASK (GET_MODE (XEXP (x, 0)));
03563 break;
03564
03565 case SIGN_EXTEND:
03566
03567
03568
03569 inner_nz = cached_nonzero_bits (XEXP (x, 0), mode,
03570 known_x, known_mode, known_ret);
03571 if (GET_MODE (XEXP (x, 0)) != VOIDmode)
03572 {
03573 inner_nz &= GET_MODE_MASK (GET_MODE (XEXP (x, 0)));
03574 if (inner_nz
03575 & (((HOST_WIDE_INT) 1
03576 << (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) - 1))))
03577 inner_nz |= (GET_MODE_MASK (mode)
03578 & ~GET_MODE_MASK (GET_MODE (XEXP (x, 0))));
03579 }
03580
03581 nonzero &= inner_nz;
03582 break;
03583
03584 case AND:
03585 nonzero &= cached_nonzero_bits (XEXP (x, 0), mode,
03586 known_x, known_mode, known_ret)
03587 & cached_nonzero_bits (XEXP (x, 1), mode,
03588 known_x, known_mode, known_ret);
03589 break;
03590
03591 case XOR: case IOR:
03592 case UMIN: case UMAX: case SMIN: case SMAX:
03593 {
03594 unsigned HOST_WIDE_INT nonzero0 =
03595 cached_nonzero_bits (XEXP (x, 0), mode,
03596 known_x, known_mode, known_ret);
03597
03598
03599
03600 if ((nonzero & nonzero0) != nonzero)
03601 nonzero &= nonzero0
03602 | cached_nonzero_bits (XEXP (x, 1), mode,
03603 known_x, known_mode, known_ret);
03604 }
03605 break;
03606
03607 case PLUS: case MINUS:
03608 case MULT:
03609 case DIV: case UDIV:
03610 case MOD: case UMOD:
03611
03612
03613
03614
03615 {
03616 unsigned HOST_WIDE_INT nz0 =
03617 cached_nonzero_bits (XEXP (x, 0), mode,
03618 known_x, known_mode, known_ret);
03619 unsigned HOST_WIDE_INT nz1 =
03620 cached_nonzero_bits (XEXP (x, 1), mode,
03621 known_x, known_mode, known_ret);
03622 int sign_index = GET_MODE_BITSIZE (GET_MODE (x)) - 1;
03623 int width0 = floor_log2 (nz0) + 1;
03624 int width1 = floor_log2 (nz1) + 1;
03625 int low0 = floor_log2 (nz0 & -nz0);
03626 int low1 = floor_log2 (nz1 & -nz1);
03627 HOST_WIDE_INT op0_maybe_minusp
03628 = (nz0 & ((HOST_WIDE_INT) 1 << sign_index));
03629 HOST_WIDE_INT op1_maybe_minusp
03630 = (nz1 & ((HOST_WIDE_INT) 1 << sign_index));
03631 unsigned int result_width = mode_width;
03632 int result_low = 0;
03633
03634 switch (code)
03635 {
03636 case PLUS:
03637 result_width = MAX (width0, width1) + 1;
03638 result_low = MIN (low0, low1);
03639 break;
03640 case MINUS:
03641 result_low = MIN (low0, low1);
03642 break;
03643 case MULT:
03644 result_width = width0 + width1;
03645 result_low = low0 + low1;
03646 break;
03647 case DIV:
03648 if (width1 == 0)
03649 break;
03650 if (! op0_maybe_minusp && ! op1_maybe_minusp)
03651 result_width = width0;
03652 break;
03653 case UDIV:
03654 if (width1 == 0)
03655 break;
03656 result_width = width0;
03657 break;
03658 case MOD:
03659 if (width1 == 0)
03660 break;
03661 if (! op0_maybe_minusp && ! op1_maybe_minusp)
03662 result_width = MIN (width0, width1);
03663 result_low = MIN (low0, low1);
03664 break;
03665 case UMOD:
03666 if (width1 == 0)
03667 break;
03668 result_width = MIN (width0, width1);
03669 result_low = MIN (low0, low1);
03670 break;
03671 default:
03672 gcc_unreachable ();
03673 }
03674
03675 if (result_width < mode_width)
03676 nonzero &= ((HOST_WIDE_INT) 1 << result_width) - 1;
03677
03678 if (result_low > 0)
03679 nonzero &= ~(((HOST_WIDE_INT) 1 << result_low) - 1);
03680
03681 #ifdef POINTERS_EXTEND_UNSIGNED
03682
03683
03684
03685 if (POINTERS_EXTEND_UNSIGNED > 0 && GET_MODE (x) == Pmode
03686 && (code == PLUS || code == MINUS)
03687 && REG_P (XEXP (x, 0)) && REG_POINTER (XEXP (x, 0)))
03688 nonzero &= GET_MODE_MASK (ptr_mode);
03689 #endif
03690 }
03691 break;
03692
03693 case ZERO_EXTRACT:
03694 if (GET_CODE (XEXP (x, 1)) == CONST_INT
03695 && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT)
03696 nonzero &= ((HOST_WIDE_INT) 1 << INTVAL (XEXP (x, 1))) - 1;
03697 break;
03698
03699 case SUBREG:
03700
03701
03702
03703
03704 if (SUBREG_PROMOTED_VAR_P (x) && SUBREG_PROMOTED_UNSIGNED_P (x) > 0)
03705 nonzero = GET_MODE_MASK (GET_MODE (x))
03706 & cached_nonzero_bits (SUBREG_REG (x), GET_MODE (x),
03707 known_x, known_mode, known_ret);
03708
03709
03710
03711
03712 if (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))) <= BITS_PER_WORD
03713 && (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x)))
03714 <= HOST_BITS_PER_WIDE_INT))
03715 {
03716 nonzero &= cached_nonzero_bits (SUBREG_REG (x), mode,
03717 known_x, known_mode, known_ret);
03718
03719 #if defined (WORD_REGISTER_OPERATIONS) && defined (LOAD_EXTEND_OP)
03720
03721
03722 if ((LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (x))) == SIGN_EXTEND
03723 ? (((nonzero
03724 & (((unsigned HOST_WIDE_INT) 1
03725 << (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))) - 1))))
03726 != 0))
03727 : LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (x))) != ZERO_EXTEND)
03728 || !MEM_P (SUBREG_REG (x)))
03729 #endif
03730 {
03731
03732
03733
03734 if (GET_MODE_SIZE (GET_MODE (x))
03735 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
03736 nonzero |= (GET_MODE_MASK (GET_MODE (x))
03737 & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (x))));
03738 }
03739 }
03740 break;
03741
03742 case ASHIFTRT:
03743 case LSHIFTRT:
03744 case ASHIFT:
03745 case ROTATE:
03746
03747
03748
03749
03750
03751
03752 if (GET_CODE (XEXP (x, 1)) == CONST_INT
03753 && INTVAL (XEXP (x, 1)) >= 0
03754 && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT)
03755 {
03756 enum machine_mode inner_mode = GET_MODE (x);
03757 unsigned int width = GET_MODE_BITSIZE (inner_mode);
03758 int count = INTVAL (XEXP (x, 1));
03759 unsigned HOST_WIDE_INT mode_mask = GET_MODE_MASK (inner_mode);
03760 unsigned HOST_WIDE_INT op_nonzero =
03761 cached_nonzero_bits (XEXP (x, 0), mode,
03762 known_x, known_mode, known_ret);
03763 unsigned HOST_WIDE_INT inner = op_nonzero & mode_mask;
03764 unsigned HOST_WIDE_INT outer = 0;
03765
03766 if (mode_width > width)
03767 outer = (op_nonzero & nonzero & ~mode_mask);
03768
03769 if (code == LSHIFTRT)
03770 inner >>= count;
03771 else if (code == ASHIFTRT)
03772 {
03773 inner >>= count;
03774
03775
03776
03777
03778 if (inner & ((HOST_WIDE_INT) 1 << (width - 1 - count)))
03779 inner |= (((HOST_WIDE_INT) 1 << count) - 1) << (width - count);
03780 }
03781 else if (code == ASHIFT)
03782 inner <<= count;
03783 else
03784 inner = ((inner << (count % width)
03785 | (inner >> (width - (count % width)))) & mode_mask);
03786
03787 nonzero &= (outer | inner);
03788 }
03789 break;
03790
03791 case FFS:
03792 case POPCOUNT:
03793
03794 nonzero = ((HOST_WIDE_INT) 2 << (floor_log2 (mode_width))) - 1;
03795 break;
03796
03797 case CLZ:
03798
03799
03800 if (CLZ_DEFINED_VALUE_AT_ZERO (mode, nonzero))
03801 nonzero |= ((HOST_WIDE_INT) 1 << (floor_log2 (mode_width))) - 1;
03802 else
03803 nonzero = -1;
03804 break;
03805
03806 case CTZ:
03807
03808
03809 if (CTZ_DEFINED_VALUE_AT_ZERO (mode, nonzero))
03810 nonzero |= ((HOST_WIDE_INT) 1 << (floor_log2 (mode_width))) - 1;
03811 else
03812 nonzero = -1;
03813 break;
03814
03815 case PARITY:
03816 nonzero = 1;
03817 break;
03818
03819 case IF_THEN_ELSE:
03820 {
03821 unsigned HOST_WIDE_INT nonzero_true =
03822 cached_nonzero_bits (XEXP (x, 1), mode,
03823 known_x, known_mode, known_ret);
03824
03825
03826
03827 if ((nonzero & nonzero_true) != nonzero)
03828 nonzero &= nonzero_true
03829 | cached_nonzero_bits (XEXP (x, 2), mode,
03830 known_x, known_mode, known_ret);
03831 }
03832 break;
03833
03834 default:
03835 break;
03836 }
03837
03838 return nonzero;
03839 }
03840
03841
03842 #undef cached_num_sign_bit_copies
03843
03844
03845
03846
03847
03848
03849
03850 static unsigned int
03851 cached_num_sign_bit_copies (rtx x, enum machine_mode mode, rtx known_x,
03852 enum machine_mode known_mode,
03853 unsigned int known_ret)
03854 {
03855 if (x == known_x && mode == known_mode)
03856 return known_ret;
03857
03858
03859
03860
03861
03862 if (ARITHMETIC_P (x))
03863 {
03864 rtx x0 = XEXP (x, 0);
03865 rtx x1 = XEXP (x, 1);
03866
03867
03868 if (x0 == x1)
03869 return
03870 num_sign_bit_copies1 (x, mode, x0, mode,
03871 cached_num_sign_bit_copies (x0, mode, known_x,
03872 known_mode,
03873 known_ret));
03874
03875
03876 if (ARITHMETIC_P (x0)
03877 && (x1 == XEXP (x0, 0) || x1 == XEXP (x0, 1)))
03878 return
03879 num_sign_bit_copies1 (x, mode, x1, mode,
03880 cached_num_sign_bit_copies (x1, mode, known_x,
03881 known_mode,
03882 known_ret));
03883
03884 if (ARITHMETIC_P (x1)
03885 && (x0 == XEXP (x1, 0) || x0 == XEXP (x1, 1)))
03886 return
03887 num_sign_bit_copies1 (x, mode, x0, mode,
03888 cached_num_sign_bit_copies (x0, mode, known_x,
03889 known_mode,
03890 known_ret));
03891 }
03892
03893 return num_sign_bit_copies1 (x, mode, known_x, known_mode, known_ret);
03894 }
03895
03896
03897
03898
03899
03900
03901 static unsigned int
03902 num_sign_bit_copies1 (rtx x, enum machine_mode mode, rtx known_x,
03903 enum machine_mode known_mode,
03904 unsigned int known_ret)
03905 {
03906 enum rtx_code code = GET_CODE (x);
03907 unsigned int bitwidth = GET_MODE_BITSIZE (mode);
03908 int num0, num1, result;
03909 unsigned HOST_WIDE_INT nonzero;
03910
03911
03912
03913
03914
03915 if (mode == VOIDmode)
03916 mode = GET_MODE (x);
03917
03918 if (mode == VOIDmode || FLOAT_MODE_P (mode) || FLOAT_MODE_P (GET_MODE (x)))
03919 return 1;
03920
03921
03922 if (bitwidth < GET_MODE_BITSIZE (GET_MODE (x)))
03923 {
03924 num0 = cached_num_sign_bit_copies (x, GET_MODE (x),
03925 known_x, known_mode, known_ret);
03926 return MAX (1,
03927 num0 - (int) (GET_MODE_BITSIZE (GET_MODE (x)) - bitwidth));
03928 }
03929
03930 if (GET_MODE (x) != VOIDmode && bitwidth > GET_MODE_BITSIZE (GET_MODE (x)))
03931 {
03932 #ifndef WORD_REGISTER_OPERATIONS
03933
03934
03935
03936 return 1;
03937 #else
03938
03939
03940
03941 if (GET_MODE_BITSIZE (GET_MODE (x)) < BITS_PER_WORD
03942 #ifdef LOAD_EXTEND_OP
03943 && LOAD_EXTEND_OP (GET_MODE (x)) != SIGN_EXTEND
03944 #endif
03945 )
03946 return 1;
03947 #endif
03948 }
03949
03950 switch (code)
03951 {
03952 case REG:
03953
03954 #if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
03955
03956
03957 if (! POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode && mode == Pmode
03958 && REG_POINTER (x))
03959 return GET_MODE_BITSIZE (Pmode) - GET_MODE_BITSIZE (ptr_mode) + 1;
03960 #endif
03961
03962 {
03963 unsigned int copies_for_hook = 1, copies = 1;
03964 rtx new = rtl_hooks.reg_num_sign_bit_copies (x, mode, known_x,
03965 known_mode, known_ret,
03966 &copies_for_hook);
03967
03968 if (new)
03969 copies = cached_num_sign_bit_copies (new, mode, known_x,
03970 known_mode, known_ret);
03971
03972 if (copies > 1 || copies_for_hook > 1)
03973 return MAX (copies, copies_for_hook);
03974
03975
03976 }
03977 break;
03978
03979 case MEM:
03980 #ifdef LOAD_EXTEND_OP
03981
03982 if (LOAD_EXTEND_OP (GET_MODE (x)) == SIGN_EXTEND)
03983 return MAX (1, ((int) bitwidth
03984 - (int) GET_MODE_BITSIZE (GET_MODE (x)) + 1));
03985 #endif
03986 break;
03987
03988 case CONST_INT:
03989
03990
03991 nonzero = INTVAL (x) & GET_MODE_MASK (mode);
03992 if (bitwidth <= HOST_BITS_PER_WIDE_INT
03993 && (nonzero & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
03994 nonzero = (~nonzero) & GET_MODE_MASK (mode);
03995
03996 return (nonzero == 0 ? bitwidth : bitwidth - floor_log2 (nonzero) - 1);
03997
03998 case SUBREG:
03999
04000
04001
04002
04003 if (SUBREG_PROMOTED_VAR_P (x) && ! SUBREG_PROMOTED_UNSIGNED_P (x))
04004 {
04005 num0 = cached_num_sign_bit_copies (SUBREG_REG (x), mode,
04006 known_x, known_mode, known_ret);
04007 return MAX ((int) bitwidth
04008 - (int) GET_MODE_BITSIZE (GET_MODE (x)) + 1,
04009 num0);
04010 }
04011
04012
04013 if (bitwidth <= GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))))
04014 {
04015 num0 = cached_num_sign_bit_copies (SUBREG_REG (x), VOIDmode,
04016 known_x, known_mode, known_ret);
04017 return MAX (1, (num0
04018 - (int) (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x)))
04019 - bitwidth)));
04020 }
04021
04022 #ifdef WORD_REGISTER_OPERATIONS
04023 #ifdef LOAD_EXTEND_OP
04024
04025
04026
04027
04028
04029
04030
04031
04032
04033
04034 if ((GET_MODE_SIZE (GET_MODE (x))
04035 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
04036 && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (x))) == SIGN_EXTEND
04037 && MEM_P (SUBREG_REG (x)))
04038 return cached_num_sign_bit_copies (SUBREG_REG (x), mode,
04039 known_x, known_mode, known_ret);
04040 #endif
04041 #endif
04042 break;
04043
04044 case SIGN_EXTRACT:
04045 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
04046 return MAX (1, (int) bitwidth - INTVAL (XEXP (x, 1)));
04047 break;
04048
04049 case SIGN_EXTEND:
04050 return (bitwidth - GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))
04051 + cached_num_sign_bit_copies (XEXP (x, 0), VOIDmode,
04052 known_x, known_mode, known_ret));
04053
04054 case TRUNCATE:
04055
04056 num0 = cached_num_sign_bit_copies (XEXP (x, 0), VOIDmode,
04057 known_x, known_mode, known_ret);
04058 return MAX (1, (num0 - (int) (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))
04059 - bitwidth)));
04060
04061 case NOT:
04062 return cached_num_sign_bit_copies (XEXP (x, 0), mode,
04063 known_x, known_mode, known_ret);
04064
04065 case ROTATE: case ROTATERT:
04066
04067
04068
04069 if (GET_CODE (XEXP (x, 1)) == CONST_INT
04070 && INTVAL (XEXP (x, 1)) >= 0
04071 && INTVAL (XEXP (x, 1)) < (int) bitwidth)
04072 {
04073 num0 = cached_num_sign_bit_copies (XEXP (x, 0), mode,
04074 known_x, known_mode, known_ret);
04075 return MAX (1, num0 - (code == ROTATE ? INTVAL (XEXP (x, 1))
04076 : (int) bitwidth - INTVAL (XEXP (x, 1))));
04077 }
04078 break;
04079
04080 case NEG:
04081
04082
04083
04084
04085 num0 = cached_num_sign_bit_copies (XEXP (x, 0), mode,
04086 known_x, known_mode, known_ret);
04087 if (bitwidth > HOST_BITS_PER_WIDE_INT)
04088 return num0 > 1 ? num0 - 1 : 1;
04089
04090 nonzero = nonzero_bits (XEXP (x, 0), mode);
04091 if (nonzero == 1)
04092 return bitwidth;
04093
04094 if (num0 > 1
04095 && (((HOST_WIDE_INT) 1 << (bitwidth - 1)) & nonzero))
04096 num0--;
04097
04098 return num0;
04099
04100 case IOR: case AND: case XOR:
04101 case SMIN: case SMAX: case UMIN: case UMAX:
04102
04103
04104 num0 = cached_num_sign_bit_copies (XEXP (x, 0), mode,
04105 known_x, known_mode, known_ret);
04106 num1 = cached_num_sign_bit_copies (XEXP (x, 1), mode,
04107 known_x, known_mode, known_ret);
04108 return MIN (num0, num1);
04109
04110 case PLUS: case MINUS:
04111
04112
04113
04114
04115
04116 if (code == PLUS && XEXP (x, 1) == constm1_rtx
04117 && bitwidth <= HOST_BITS_PER_WIDE_INT)
04118 {
04119 nonzero = nonzero_bits (XEXP (x, 0), mode);
04120 if ((((HOST_WIDE_INT) 1 << (bitwidth - 1)) & nonzero) == 0)
04121 return (nonzero == 1 || nonzero == 0 ? bitwidth
04122 : bitwidth - floor_log2 (nonzero) - 1);
04123 }
04124
04125 num0 = cached_num_sign_bit_copies (XEXP (x, 0), mode,
04126 known_x, known_mode, known_ret);
04127 num1 = cached_num_sign_bit_copies (XEXP (x, 1), mode,
04128 known_x, known_mode, known_ret);
04129 result = MAX (1, MIN (num0, num1) - 1);
04130
04131 #ifdef POINTERS_EXTEND_UNSIGNED
04132
04133
04134
04135 if (! POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode
04136 && (code == PLUS || code == MINUS)
04137 && REG_P (XEXP (x, 0)) && REG_POINTER (XEXP (x, 0)))
04138 result = MAX ((int) (GET_MODE_BITSIZE (Pmode)
04139 - GET_MODE_BITSIZE (ptr_mode) + 1),
04140 result);
04141 #endif
04142 return result;
04143
04144 case MULT:
04145
04146
04147
04148
04149
04150 num0 = cached_num_sign_bit_copies (XEXP (x, 0), mode,
04151 known_x, known_mode, known_ret);
04152 num1 = cached_num_sign_bit_copies (XEXP (x, 1), mode,
04153 known_x, known_mode, known_ret);
04154
04155 result = bitwidth - (bitwidth - num0) - (bitwidth - num1);
04156 if (result > 0
04157 && (bitwidth > HOST_BITS_PER_WIDE_INT
04158 || (((nonzero_bits (XEXP (x, 0), mode)
04159 & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
04160 && ((nonzero_bits (XEXP (x, 1), mode)
04161 & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0))))
04162 result--;
04163
04164 return MAX (1, result);
04165
04166 case UDIV:
04167
04168
04169
04170 if (bitwidth > HOST_BITS_PER_WIDE_INT)
04171 return 1;
04172 else if ((nonzero_bits (XEXP (x, 0), mode)
04173 & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
04174 return 1;
04175 else
04176 return cached_num_sign_bit_copies (XEXP (x, 0), mode,
04177 known_x, known_mode, known_ret);
04178
04179 case UMOD:
04180
04181 return cached_num_sign_bit_copies (XEXP (x, 1), mode,
04182 known_x, known_mode, known_ret);
04183
04184 case DIV:
04185
04186
04187
04188 result = cached_num_sign_bit_copies (XEXP (x, 0), mode,
04189 known_x, known_mode, known_ret);
04190 if (result > 1
04191 && (bitwidth > HOST_BITS_PER_WIDE_INT
04192 || (nonzero_bits (XEXP (x, 1), mode)
04193 & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0))
04194 result--;
04195
04196 return result;
04197
04198 case MOD:
04199 result = cached_num_sign_bit_copies (XEXP (x, 1), mode,
04200 known_x, known_mode, known_ret);
04201 if (result > 1
04202 && (bitwidth > HOST_BITS_PER_WIDE_INT
04203 || (nonzero_bits (XEXP (x, 1), mode)
04204 & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0))
04205 result--;
04206
04207 return result;
04208
04209 case ASHIFTRT:
04210
04211
04212 num0 = cached_num_sign_bit_copies (XEXP (x, 0), mode,
04213 known_x, known_mode, known_ret);
04214 if (GET_CODE (XEXP (x, 1)) == CONST_INT
04215 && INTVAL (XEXP (x, 1)) > 0)
04216 num0 = MIN ((int) bitwidth, num0 + INTVAL (XEXP (x, 1)));
04217
04218 return num0;
04219
04220 case ASHIFT:
04221
04222 if (GET_CODE (XEXP (x, 1)) != CONST_INT
04223 || INTVAL (XEXP (x, 1)) < 0
04224 || INTVAL (XEXP (x, 1)) >= (int) bitwidth)
04225 return 1;
04226
04227 num0 = cached_num_sign_bit_copies (XEXP (x, 0), mode,
04228 known_x, known_mode, known_ret);
04229 return MAX (1, num0 - INTVAL (XEXP (x, 1)));
04230
04231 case IF_THEN_ELSE:
04232 num0 = cached_num_sign_bit_copies (XEXP (x, 1), mode,
04233 known_x, known_mode, known_ret);
04234 num1 = cached_num_sign_bit_copies (XEXP (x, 2), mode,
04235 known_x, known_mode, known_ret);
04236 return MIN (num0, num1);
04237
04238 case EQ: case NE: case GE: case GT: case LE: case LT:
04239 case UNEQ: case LTGT: case UNGE: case UNGT: case UNLE: case UNLT:
04240 case GEU: case GTU: case LEU: case LTU:
04241 case UNORDERED: case ORDERED:
04242
04243
04244 nonzero = STORE_FLAG_VALUE;
04245 if (bitwidth <= HOST_BITS_PER_WIDE_INT
04246 && (nonzero & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
04247 nonzero = (~nonzero) & GET_MODE_MASK (mode);
04248
04249 return (nonzero == 0 ? bitwidth : bitwidth - floor_log2 (nonzero) - 1);
04250
04251 default:
04252 break;
04253 }
04254
04255
04256
04257
04258
04259
04260 bitwidth = GET_MODE_BITSIZE (mode);
04261 if (bitwidth > HOST_BITS_PER_WIDE_INT)
04262 return 1;
04263
04264 nonzero = nonzero_bits (x, mode);
04265 return nonzero & ((HOST_WIDE_INT) 1 << (bitwidth - 1))
04266 ? 1 : bitwidth - floor_log2 (nonzero) - 1;
04267 }
04268
04269
04270
04271
04272 int
04273 insn_rtx_cost (rtx pat)
04274 {
04275 int i, cost;
04276 rtx set;
04277
04278
04279
04280 if (GET_CODE (pat) == SET)
04281 set = pat;
04282 else if (GET_CODE (pat) == PARALLEL)
04283 {
04284 set = NULL_RTX;
04285 for (i = 0; i < XVECLEN (pat, 0); i++)
04286 {
04287 rtx x = XVECEXP (pat, 0, i);
04288 if (GET_CODE (x) == SET)
04289 {
04290 if (set)
04291 return 0;
04292 set = x;
04293 }
04294 }
04295 if (!set)
04296 return 0;
04297 }
04298 else
04299 return 0;
04300
04301 cost = rtx_cost (SET_SRC (set), SET);
04302 return cost > 0 ? cost : COSTS_N_INSNS (1);
04303 }
04304
04305
04306
04307
04308
04309
04310
04311
04312
04313
04314
04315
04316
04317
04318
04319
04320
04321
04322
04323
04324
04325
04326
04327
04328
04329
04330
04331
04332 rtx
04333 canonicalize_condition (rtx insn, rtx cond, int reverse, rtx *earliest,
04334 rtx want_reg, int allow_cc_mode, int valid_at_insn_p)
04335 {
04336 enum rtx_code code;
04337 rtx prev = insn;
04338 rtx set;
04339 rtx tem;
04340 rtx op0, op1;
04341 int reverse_code = 0;
04342 enum machine_mode mode;
04343 basic_block bb = BLOCK_FOR_INSN (insn);
04344
04345 code = GET_CODE (cond);
04346 mode = GET_MODE (cond);
04347 op0 = XEXP (cond, 0);
04348 op1 = XEXP (cond, 1);
04349
04350 if (reverse)
04351 code = reversed_comparison_code (cond, insn);
04352 if (code == UNKNOWN)
04353 return 0;
04354
04355 if (earliest)
04356 *earliest = insn;
04357
04358
04359
04360
04361
04362
04363 while ((GET_RTX_CLASS (code) == RTX_COMPARE
04364 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
04365 && op1 == CONST0_RTX (GET_MODE (op0))
04366 && op0 != want_reg)
04367 {
04368
04369 rtx x = 0;
04370
04371 #ifdef HAVE_cc0
04372
04373
04374 if (op0 == cc0_rtx)
04375 {
04376 if ((prev = prev_nonnote_insn (prev)) == 0
04377 || !NONJUMP_INSN_P (prev)
04378 || (set = single_set (prev)) == 0
04379 || SET_DEST (set) != cc0_rtx)
04380 return 0;
04381
04382 op0 = SET_SRC (set);
04383 op1 = CONST0_RTX (GET_MODE (op0));
04384 if (earliest)
04385 *earliest = prev;
04386 }
04387 #endif
04388
04389
04390 if (GET_CODE (op0) == COMPARE)
04391 {
04392 op1 = XEXP (op0, 1);
04393 op0 = XEXP (op0, 0);
04394 continue;
04395 }
04396 else if (!REG_P (op0))
04397 break;
04398
04399
04400
04401
04402
04403 if ((prev = prev_nonnote_insn (prev)) == 0
04404 || !NONJUMP_INSN_P (prev)
04405 || FIND_REG_INC_NOTE (prev, NULL_RTX)
04406
04407
04408
04409 || BLOCK_FOR_INSN (prev) != bb)
04410 break;
04411
04412 set = set_of (op0, prev);
04413
04414 if (set
04415 && (GET_CODE (set) != SET
04416 || !rtx_equal_p (SET_DEST (set), op0)))
04417 break;
04418
04419
04420
04421 if (set)
04422 {
04423 enum machine_mode inner_mode = GET_MODE (SET_DEST (set));
04424 #ifdef FLOAT_STORE_FLAG_VALUE
04425 REAL_VALUE_TYPE fsfv;
04426 #endif
04427
04428
04429
04430
04431
04432
04433
04434
04435
04436
04437
04438
04439
04440
04441
04442 if ((GET_CODE (SET_SRC (set)) == COMPARE
04443 || (((code == NE
04444 || (code == LT
04445 && GET_MODE_CLASS (inner_mode) == MODE_INT
04446 && (GET_MODE_BITSIZE (inner_mode)
04447 <= HOST_BITS_PER_WIDE_INT)
04448 && (STORE_FLAG_VALUE
04449 & ((HOST_WIDE_INT) 1
04450 << (GET_MODE_BITSIZE (inner_mode) - 1))))
04451 #ifdef FLOAT_STORE_FLAG_VALUE
04452 || (code == LT
04453 && SCALAR_FLOAT_MODE_P (inner_mode)
04454 && (fsfv = FLOAT_STORE_FLAG_VALUE (inner_mode),
04455 REAL_VALUE_NEGATIVE (fsfv)))
04456 #endif
04457 ))
04458 && COMPARISON_P (SET_SRC (set))))
04459 && (((GET_MODE_CLASS (mode) == MODE_CC)
04460 == (GET_MODE_CLASS (inner_mode) == MODE_CC))
04461 || mode == VOIDmode || inner_mode == VOIDmode))
04462 x = SET_SRC (set);
04463 else if (((code == EQ
04464 || (code == GE
04465 && (GET_MODE_BITSIZE (inner_mode)
04466 <= HOST_BITS_PER_WIDE_INT)
04467 && GET_MODE_CLASS (inner_mode) == MODE_INT
04468 && (STORE_FLAG_VALUE
04469 & ((HOST_WIDE_INT) 1
04470 << (GET_MODE_BITSIZE (inner_mode) - 1))))
04471 #ifdef FLOAT_STORE_FLAG_VALUE
04472 || (code == GE
04473 && SCALAR_FLOAT_MODE_P (inner_mode)
04474 && (fsfv = FLOAT_STORE_FLAG_VALUE (inner_mode),
04475 REAL_VALUE_NEGATIVE (fsfv)))
04476 #endif
04477 ))
04478 && COMPARISON_P (SET_SRC (set))
04479 && (((GET_MODE_CLASS (mode) == MODE_CC)
04480 == (GET_MODE_CLASS (inner_mode) == MODE_CC))
04481 || mode == VOIDmode || inner_mode == VOIDmode))
04482
04483 {
04484 reverse_code = 1;
04485 x = SET_SRC (set);
04486 }
04487 else
04488 break;
04489 }
04490
04491 else if (reg_set_p (op0, prev))
04492
04493 break;
04494
04495 if (x)
04496 {
04497
04498
04499 if (valid_at_insn_p)
04500 if (modified_in_p (x, prev) || modified_between_p (x, prev, insn))
04501 break;
04502 if (COMPARISON_P (x))
04503 code = GET_CODE (x);
04504 if (reverse_code)
04505 {
04506 code = reversed_comparison_code (x, prev);
04507 if (code == UNKNOWN)
04508 return 0;
04509 reverse_code = 0;
04510 }
04511
04512 op0 = XEXP (x, 0), op1 = XEXP (x, 1);
04513 if (earliest)
04514 *earliest = prev;
04515 }
04516 }
04517
04518
04519 if (CONSTANT_P (op0))
04520 code = swap_condition (code), tem = op0, op0 = op1, op1 = tem;
04521
04522
04523
04524 if (!allow_cc_mode
04525 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
04526 return 0;
04527
04528
04529
04530
04531
04532 if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_CC
04533 && GET_CODE (op1) == CONST_INT
04534 && GET_MODE (op0) != VOIDmode
04535 && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT)
04536 {
04537 HOST_WIDE_INT const_val = INTVAL (op1);
04538 unsigned HOST_WIDE_INT uconst_val = const_val;
04539 unsigned HOST_WIDE_INT max_val
04540 = (unsigned HOST_WIDE_INT) GET_MODE_MASK (GET_MODE (op0));
04541
04542 switch (code)
04543 {
04544 case LE:
04545 if ((unsigned HOST_WIDE_INT) const_val != max_val >> 1)
04546 code = LT, op1 = gen_int_mode (const_val + 1, GET_MODE (op0));
04547 break;
04548
04549
04550
04551 case GE:
04552 if ((HOST_WIDE_INT) (const_val & max_val)
04553 != (((HOST_WIDE_INT) 1
04554 << (GET_MODE_BITSIZE (GET_MODE (op0)) - 1))))
04555 code = GT, op1 = gen_int_mode (const_val - 1, GET_MODE (op0));
04556 break;
04557
04558 case LEU:
04559 if (uconst_val < max_val)
04560 code = LTU, op1 = gen_int_mode (uconst_val + 1, GET_MODE (op0));
04561 break;
04562
04563 case GEU:
04564 if (uconst_val != 0)
04565 code = GTU, op1 = gen_int_mode (uconst_val - 1, GET_MODE (op0));
04566 break;
04567
04568 default:
04569 break;
04570 }
04571 }
04572
04573
04574 if (CC0_P (op0))
04575 return 0;
04576
04577 return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
04578 }
04579
04580
04581
04582
04583
04584
04585
04586
04587
04588
04589
04590
04591
04592
04593
04594
04595
04596 rtx
04597 get_condition (rtx jump, rtx *earliest, int allow_cc_mode, int valid_at_insn_p)
04598 {
04599 rtx cond;
04600 int reverse;
04601 rtx set;
04602
04603
04604 if (!JUMP_P (jump)
04605 || ! any_condjump_p (jump))
04606 return 0;
04607 set = pc_set (jump);
04608
04609 cond = XEXP (SET_SRC (set), 0);
04610
04611
04612
04613 reverse
04614 = GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
04615 && XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (jump);
04616
04617 return canonicalize_condition (jump, cond, reverse, earliest, NULL_RTX,
04618 allow_cc_mode, valid_at_insn_p);
04619 }
04620
04621
04622
04623
04624
04625
04626
04627
04628
04629
04630 static void
04631 init_num_sign_bit_copies_in_rep (void)
04632 {
04633 enum machine_mode mode, in_mode;
04634
04635 for (in_mode = GET_CLASS_NARROWEST_MODE (MODE_INT); in_mode != VOIDmode;
04636 in_mode = GET_MODE_WIDER_MODE (mode))
04637 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != in_mode;
04638 mode = GET_MODE_WIDER_MODE (mode))
04639 {
04640 enum machine_mode i;
04641
04642
04643
04644 gcc_assert (targetm.mode_rep_extended (mode, in_mode) == UNKNOWN
04645 || GET_MODE_WIDER_MODE (mode) == in_mode);
04646
04647
04648
04649 for (i = mode; i != in_mode; i = GET_MODE_WIDER_MODE (i))
04650 {
04651 enum machine_mode wider = GET_MODE_WIDER_MODE (i);
04652
04653 if (targetm.mode_rep_extended (i, wider) == SIGN_EXTEND
04654
04655
04656
04657
04658 || num_sign_bit_copies_in_rep [in_mode][mode])
04659 num_sign_bit_copies_in_rep [in_mode][mode]
04660 += GET_MODE_BITSIZE (wider) - GET_MODE_BITSIZE (i);
04661 }
04662 }
04663 }
04664
04665
04666
04667
04668
04669 bool
04670 truncated_to_mode (enum machine_mode mode, rtx x)
04671 {
04672
04673
04674 if (REG_P (x) && rtl_hooks.reg_truncated_to_mode (mode, x))
04675 return true;
04676
04677
04678
04679 if (num_sign_bit_copies_in_rep[GET_MODE (x)][mode]
04680 && (num_sign_bit_copies (x, GET_MODE (x))
04681 >= num_sign_bit_copies_in_rep[GET_MODE (x)][mode] + 1))
04682 return true;
04683
04684 return false;
04685 }
04686
04687
04688
04689 void
04690 init_rtlanal (void)
04691 {
04692 int i;
04693 for (i = 0; i < NUM_RTX_CODE; i++)
04694 {
04695 const char *format = GET_RTX_FORMAT (i);
04696 const char *first = strpbrk (format, "eEV");
04697 non_rtx_starting_operands[i] = first ? first - format : -1;
04698 }
04699
04700 init_num_sign_bit_copies_in_rep ();
04701 }
04702
04703
04704 bool
04705 constant_pool_constant_p (rtx x)
04706 {
04707 x = avoid_constant_pool_reference (x);
04708 return GET_CODE (x) == CONST_DOUBLE;
04709 }
04710