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