00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023 #include "system.h"
00024 #include "rtl.h"
00025 #include "tree.h"
00026 #include "regs.h"
00027 #include "hard-reg-set.h"
00028 #include "real.h"
00029 #include "insn-config.h"
00030 #include "conditions.h"
00031 #include "output.h"
00032 #include "insn-attr.h"
00033 #include "flags.h"
00034 #include "recog.h"
00035 #include "expr.h"
00036 #include "obstack.h"
00037 #include "tm_p.h"
00038 #include "except.h"
00039 #include "function.h"
00040 #include "toplev.h"
00041 #include "integrate.h"
00042 #include "ggc.h"
00043 #include "target.h"
00044 #include "target-def.h"
00045
00046 static void d30v_print_operand_memory_reference PARAMS ((FILE *, rtx));
00047 static void d30v_build_long_insn PARAMS ((HOST_WIDE_INT, HOST_WIDE_INT,
00048 rtx, rtx));
00049 static void d30v_add_gc_roots PARAMS ((void));
00050 static void d30v_init_machine_status PARAMS ((struct function *));
00051 static void d30v_mark_machine_status PARAMS ((struct function *));
00052 static void d30v_free_machine_status PARAMS ((struct function *));
00053 static void d30v_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
00054 static void d30v_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
00055 static int d30v_adjust_cost PARAMS ((rtx, rtx, rtx, int));
00056 static int d30v_issue_rate PARAMS ((void));
00057
00058
00059
00060
00061 struct rtx_def *d30v_compare_op0;
00062 struct rtx_def *d30v_compare_op1;
00063
00064
00065 static d30v_stack_t *d30v_stack_cache = (d30v_stack_t *)0;
00066
00067
00068 int d30v_branch_cost = D30V_DEFAULT_BRANCH_COST;
00069 const char *d30v_branch_cost_string = (const char *)0;
00070
00071
00072 int d30v_cond_exec = D30V_DEFAULT_MAX_CONDITIONAL_EXECUTE;
00073 const char *d30v_cond_exec_string = (const char *)0;
00074
00075
00076 unsigned char hard_regno_mode_ok[ (int)MAX_MACHINE_MODE ][FIRST_PSEUDO_REGISTER];
00077
00078
00079 unsigned char modes_tieable_p[ (NUM_MACHINE_MODES) * (NUM_MACHINE_MODES) ];
00080
00081
00082 enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
00083
00084
00085 enum reg_class reg_class_from_letter[256];
00086
00087
00088 #undef TARGET_ASM_ALIGNED_HI_OP
00089 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
00090 #undef TARGET_ASM_ALIGNED_SI_OP
00091 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
00092
00093 #undef TARGET_ASM_FUNCTION_PROLOGUE
00094 #define TARGET_ASM_FUNCTION_PROLOGUE d30v_output_function_prologue
00095 #undef TARGET_ASM_FUNCTION_EPILOGUE
00096 #define TARGET_ASM_FUNCTION_EPILOGUE d30v_output_function_epilogue
00097 #undef TARGET_SCHED_ADJUST_COST
00098 #define TARGET_SCHED_ADJUST_COST d30v_adjust_cost
00099 #undef TARGET_SCHED_ISSUE_RATE
00100 #define TARGET_SCHED_ISSUE_RATE d30v_issue_rate
00101
00102 struct gcc_target targetm = TARGET_INITIALIZER;
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 void
00114 override_options ()
00115 {
00116 int regno, i, ok_p;
00117 enum machine_mode mode1, mode2;
00118
00119
00120 if (d30v_branch_cost_string)
00121 d30v_branch_cost = atoi (d30v_branch_cost_string);
00122
00123
00124 if (d30v_cond_exec_string)
00125 d30v_cond_exec = atoi (d30v_cond_exec_string);
00126
00127
00128 for (mode1 = VOIDmode;
00129 (int)mode1 < NUM_MACHINE_MODES;
00130 mode1 = (enum machine_mode)((int)mode1 + 1))
00131 {
00132 int size = GET_MODE_SIZE (mode1);
00133 int large_p = size > UNITS_PER_WORD;
00134 int int_p = GET_MODE_CLASS (mode1) == MODE_INT;
00135
00136 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
00137 {
00138 if (mode1 == VOIDmode)
00139 ok_p = FALSE;
00140
00141 else if (GPR_P (regno))
00142 {
00143 if (!large_p)
00144 ok_p = TRUE;
00145 else
00146 ok_p = (((regno - GPR_FIRST) & 1) == 0);
00147 }
00148
00149 else if (FLAG_P (regno))
00150 ok_p = (mode1 == CCmode);
00151
00152 else if (CR_P (regno))
00153 ok_p = int_p && !large_p;
00154
00155 else if (ACCUM_P (regno))
00156 ok_p = (mode1 == DImode);
00157
00158 else if (SPECIAL_REG_P (regno))
00159 ok_p = (mode1 == SImode);
00160
00161 else
00162 ok_p = FALSE;
00163
00164 hard_regno_mode_ok[ (int)mode1 ][ regno ] = ok_p;
00165 }
00166
00167
00168
00169
00170
00171
00172
00173
00174 for (mode2 = VOIDmode;
00175 (int)mode2 <= NUM_MACHINE_MODES;
00176 mode2 = (enum machine_mode)((int)mode2 + 1))
00177 {
00178 if (mode1 == mode2)
00179 ok_p = TRUE;
00180
00181 #if 0
00182 else if (GET_MODE_CLASS (mode1) == MODE_INT
00183 && GET_MODE_SIZE (mode1) <= UNITS_PER_WORD
00184 && GET_MODE_CLASS (mode2) == MODE_INT
00185 && GET_MODE_SIZE (mode2) <= UNITS_PER_WORD)
00186 ok_p = TRUE;
00187 #endif
00188
00189 else
00190 ok_p = FALSE;
00191
00192 modes_tieable_p[ ((int)mode1 * (NUM_MACHINE_MODES)) + (int)mode2 ] = ok_p;
00193 }
00194 }
00195
00196 #if 0
00197 for (mode1 = VOIDmode;
00198 (int)mode1 < NUM_MACHINE_MODES;
00199 mode1 = (enum machine_mode)((int)mode1 + 1))
00200 {
00201 for (mode2 = VOIDmode;
00202 (int)mode2 <= NUM_MACHINE_MODES;
00203 mode2 = (enum machine_mode)((int)mode2 + 1))
00204 {
00205 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
00206 if (ok_p
00207 && (hard_regno_mode_ok[(int)mode1][regno]
00208 != hard_regno_mode_ok[(int)mode2][regno]))
00209 error ("bad modes_tieable_p for register %s, mode1 %s, mode2 %s",
00210 reg_names[regno], GET_MODE_NAME (mode1),
00211 GET_MODE_NAME (mode2));
00212 }
00213 }
00214 #endif
00215
00216
00217
00218
00219
00220 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
00221 {
00222 enum reg_class class;
00223
00224 if (GPR_P (regno))
00225 class = (IN_RANGE_P (regno, GPR_FIRST+2, GPR_FIRST+62)
00226 && ((regno - GPR_FIRST) & 1) == 0) ? EVEN_REGS : GPR_REGS;
00227
00228 else if (regno == FLAG_F0)
00229 class = F0_REGS;
00230
00231 else if (regno == FLAG_F1)
00232 class = F1_REGS;
00233
00234 else if (FLAG_P (regno))
00235 class = OTHER_FLAG_REGS;
00236
00237 else if (ACCUM_P (regno))
00238 class = ACCUM_REGS;
00239
00240 else if (regno == CR_RPT_C)
00241 class = REPEAT_REGS;
00242
00243 else if (CR_P (regno))
00244 class = CR_REGS;
00245
00246 else if (SPECIAL_REG_P (regno))
00247 class = GPR_REGS;
00248
00249 else
00250 class = NO_REGS;
00251
00252 regno_reg_class[regno] = class;
00253
00254 #if 0
00255 {
00256 static const char *const names[] = REG_CLASS_NAMES;
00257 fprintf (stderr, "Register %s class is %s, can hold modes", reg_names[regno], names[class]);
00258 for (mode1 = VOIDmode;
00259 (int)mode1 < NUM_MACHINE_MODES;
00260 mode1 = (enum machine_mode)((int)mode1 + 1))
00261 {
00262 if (hard_regno_mode_ok[ (int)mode1 ][ regno ])
00263 fprintf (stderr, " %s", GET_MODE_NAME (mode1));
00264 }
00265 fprintf (stderr, "\n");
00266 }
00267 #endif
00268 }
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287 for (i = 0; i < 256; i++)
00288 reg_class_from_letter[i] = NO_REGS;
00289
00290 reg_class_from_letter['a'] = ACCUM_REGS;
00291 reg_class_from_letter['b'] = BR_FLAG_REGS;
00292 reg_class_from_letter['c'] = CR_REGS;
00293 reg_class_from_letter['d'] = GPR_REGS;
00294 reg_class_from_letter['e'] = EVEN_REGS;
00295 reg_class_from_letter['f'] = FLAG_REGS;
00296 reg_class_from_letter['l'] = REPEAT_REGS;
00297 reg_class_from_letter['x'] = F0_REGS;
00298 reg_class_from_letter['y'] = F1_REGS;
00299 reg_class_from_letter['z'] = OTHER_FLAG_REGS;
00300
00301 d30v_add_gc_roots ();
00302 }
00303
00304
00305
00306
00307 int
00308 short_memory_operand (op, mode)
00309 register rtx op;
00310 enum machine_mode mode;
00311 {
00312 if (GET_CODE (op) != MEM)
00313 return FALSE;
00314
00315 if (GET_MODE (op) != mode && mode != VOIDmode)
00316 return FALSE;
00317
00318 return (d30v_legitimate_address_p (mode, XEXP (op, 0), reload_completed)
00319 == 1);
00320 }
00321
00322
00323
00324 int
00325 long_memory_operand (op, mode)
00326 rtx op;
00327 enum machine_mode mode;
00328 {
00329 if (GET_CODE (op) != MEM)
00330 return FALSE;
00331
00332 if (GET_MODE (op) != mode && mode != VOIDmode)
00333 return FALSE;
00334
00335 return (d30v_legitimate_address_p (mode, XEXP (op, 0), reload_completed)
00336 == 2);
00337 }
00338
00339
00340
00341 int
00342 d30v_memory_operand (op, mode)
00343 rtx op;
00344 enum machine_mode mode;
00345 {
00346 if (GET_CODE (op) != MEM)
00347 return FALSE;
00348
00349 if (GET_MODE (op) != mode && mode != VOIDmode)
00350 return FALSE;
00351
00352 return (d30v_legitimate_address_p (mode, XEXP (op, 0), reload_completed)
00353 != 0);
00354 }
00355
00356
00357
00358
00359 int
00360 single_reg_memory_operand (op, mode)
00361 rtx op;
00362 enum machine_mode mode;
00363 {
00364 rtx addr;
00365
00366 if (GET_CODE (op) != MEM)
00367 return FALSE;
00368
00369 if (GET_MODE (op) != mode && mode != VOIDmode)
00370 return FALSE;
00371
00372 addr = XEXP (op, 0);
00373 if (! d30v_legitimate_address_p (mode, addr, reload_completed))
00374 return FALSE;
00375
00376 if (GET_CODE (addr) == SUBREG)
00377 addr = SUBREG_REG (addr);
00378
00379 return (GET_CODE (addr) == REG);
00380 }
00381
00382
00383
00384 int
00385 const_addr_memory_operand (op, mode)
00386 rtx op;
00387 enum machine_mode mode;
00388 {
00389 if (GET_CODE (op) != MEM)
00390 return FALSE;
00391
00392 if (GET_MODE (op) != mode && mode != VOIDmode)
00393 return FALSE;
00394
00395 if (! d30v_legitimate_address_p (mode, XEXP (op, 0), reload_completed))
00396 return FALSE;
00397
00398 switch (GET_CODE (XEXP (op, 0)))
00399 {
00400 default:
00401 break;
00402
00403 case SYMBOL_REF:
00404 case LABEL_REF:
00405 case CONST_INT:
00406 case CONST:
00407 return TRUE;
00408 }
00409
00410 return FALSE;
00411 }
00412
00413
00414
00415 int
00416 call_operand (op, mode)
00417 rtx op;
00418 enum machine_mode mode;
00419 {
00420 if (GET_CODE (op) != MEM)
00421 return FALSE;
00422
00423 if (GET_MODE (op) != mode && mode != VOIDmode)
00424 return FALSE;
00425
00426 if (! d30v_legitimate_address_p (mode, XEXP (op, 0), reload_completed))
00427 return FALSE;
00428
00429 switch (GET_CODE (XEXP (op, 0)))
00430 {
00431 default:
00432 break;
00433
00434 case SUBREG:
00435 op = SUBREG_REG (op);
00436 if (GET_CODE (op) != REG)
00437 return FALSE;
00438
00439
00440
00441 case REG:
00442 return (GPR_OR_PSEUDO_P (REGNO (XEXP (op, 0))));
00443
00444 case SYMBOL_REF:
00445 case LABEL_REF:
00446 case CONST_INT:
00447 case CONST:
00448 return TRUE;
00449 }
00450
00451 return FALSE;
00452 }
00453
00454
00455
00456 int
00457 gpr_operand (op, mode)
00458 rtx op;
00459 enum machine_mode mode;
00460 {
00461 if (GET_MODE (op) != mode && mode != VOIDmode)
00462 return FALSE;
00463
00464 if (GET_CODE (op) == SUBREG)
00465 {
00466 if (GET_CODE (SUBREG_REG (op)) != REG)
00467 return register_operand (op, mode);
00468
00469 op = SUBREG_REG (op);
00470 }
00471
00472 if (GET_CODE (op) != REG)
00473 return FALSE;
00474
00475 return GPR_OR_PSEUDO_P (REGNO (op));
00476 }
00477
00478
00479
00480 int
00481 accum_operand (op, mode)
00482 rtx op;
00483 enum machine_mode mode;
00484 {
00485 if (GET_MODE (op) != mode && mode != VOIDmode)
00486 return FALSE;
00487
00488 if (GET_CODE (op) == SUBREG)
00489 {
00490 if (GET_CODE (SUBREG_REG (op)) != REG)
00491 return register_operand (op, mode);
00492
00493 op = SUBREG_REG (op);
00494 }
00495
00496 if (GET_CODE (op) != REG)
00497 return FALSE;
00498
00499 return ACCUM_OR_PSEUDO_P (REGNO (op));
00500 }
00501
00502
00503
00504 int
00505 gpr_or_accum_operand (op, mode)
00506 rtx op;
00507 enum machine_mode mode;
00508 {
00509 if (GET_MODE (op) != mode && mode != VOIDmode)
00510 return FALSE;
00511
00512 if (GET_CODE (op) == SUBREG)
00513 {
00514 if (GET_CODE (SUBREG_REG (op)) != REG)
00515 return register_operand (op, mode);
00516
00517 op = SUBREG_REG (op);
00518 }
00519
00520 if (GET_CODE (op) != REG)
00521 return FALSE;
00522
00523 if (ACCUM_P (REGNO (op)))
00524 return TRUE;
00525
00526 return GPR_OR_PSEUDO_P (REGNO (op));
00527 }
00528
00529
00530
00531 int
00532 cr_operand (op, mode)
00533 rtx op;
00534 enum machine_mode mode;
00535 {
00536 if (GET_MODE (op) != mode && mode != VOIDmode)
00537 return FALSE;
00538
00539 if (GET_CODE (op) == SUBREG)
00540 {
00541 if (GET_CODE (SUBREG_REG (op)) != REG)
00542 return register_operand (op, mode);
00543
00544 op = SUBREG_REG (op);
00545 }
00546
00547 if (GET_CODE (op) != REG)
00548 return FALSE;
00549
00550 return CR_OR_PSEUDO_P (REGNO (op));
00551 }
00552
00553
00554
00555 int
00556 repeat_operand (op, mode)
00557 rtx op;
00558 enum machine_mode mode;
00559 {
00560 if (GET_MODE (op) != mode && mode != VOIDmode)
00561 return FALSE;
00562
00563 if (GET_CODE (op) == SUBREG)
00564 {
00565 if (GET_CODE (SUBREG_REG (op)) != REG)
00566 return register_operand (op, mode);
00567
00568 op = SUBREG_REG (op);
00569 }
00570
00571 if (GET_CODE (op) != REG)
00572 return FALSE;
00573
00574 return (REGNO (op) == CR_RPT_C || REGNO (op) >= FIRST_PSEUDO_REGISTER);
00575 }
00576
00577
00578
00579 int
00580 flag_operand (op, mode)
00581 rtx op;
00582 enum machine_mode mode;
00583 {
00584 if (GET_MODE (op) != mode && mode != VOIDmode)
00585 return FALSE;
00586
00587 if (GET_CODE (op) == SUBREG)
00588 {
00589 if (GET_CODE (SUBREG_REG (op)) != REG)
00590 return register_operand (op, mode);
00591
00592 op = SUBREG_REG (op);
00593 }
00594
00595 if (GET_CODE (op) != REG)
00596 return FALSE;
00597
00598 return FLAG_OR_PSEUDO_P (REGNO (op));
00599 }
00600
00601
00602
00603 int
00604 br_flag_operand (op, mode)
00605 rtx op;
00606 enum machine_mode mode;
00607 {
00608 if (GET_MODE (op) != mode && mode != VOIDmode)
00609 return FALSE;
00610
00611 if (GET_CODE (op) == SUBREG)
00612 {
00613 if (GET_CODE (SUBREG_REG (op)) != REG)
00614 return register_operand (op, mode);
00615
00616 op = SUBREG_REG (op);
00617 }
00618
00619 if (GET_CODE (op) != REG)
00620 return FALSE;
00621
00622 return BR_FLAG_OR_PSEUDO_P (REGNO (op));
00623 }
00624
00625
00626
00627 int
00628 br_flag_or_constant_operand (op, mode)
00629 rtx op;
00630 enum machine_mode mode;
00631 {
00632 if (GET_MODE (op) != mode && mode != VOIDmode)
00633 return FALSE;
00634
00635 if (GET_CODE (op) == SUBREG)
00636 {
00637 if (GET_CODE (SUBREG_REG (op)) != REG)
00638 return register_operand (op, mode);
00639
00640 op = SUBREG_REG (op);
00641 }
00642
00643 if (GET_CODE (op) == CONST_INT)
00644 return (INTVAL (op) == 0 || INTVAL (op) == 1);
00645
00646 if (GET_CODE (op) != REG)
00647 return FALSE;
00648
00649 return BR_FLAG_OR_PSEUDO_P (REGNO (op));
00650 }
00651
00652
00653
00654 int
00655 gpr_or_br_flag_operand (op, mode)
00656 rtx op;
00657 enum machine_mode mode;
00658 {
00659 if (GET_MODE (op) != mode && mode != VOIDmode)
00660 return FALSE;
00661
00662 if (GET_CODE (op) == SUBREG)
00663 {
00664 if (GET_CODE (SUBREG_REG (op)) != REG)
00665 return register_operand (op, mode);
00666
00667 op = SUBREG_REG (op);
00668 }
00669
00670 if (GET_CODE (op) != REG)
00671 return FALSE;
00672
00673 return GPR_OR_PSEUDO_P (REGNO (op)) || BR_FLAG_P (REGNO (op));
00674 }
00675
00676
00677
00678 int
00679 f0_operand (op, mode)
00680 rtx op;
00681 enum machine_mode mode;
00682 {
00683 if (GET_MODE (op) != mode && mode != VOIDmode)
00684 return FALSE;
00685
00686 if (GET_CODE (op) == SUBREG)
00687 {
00688 if (GET_CODE (SUBREG_REG (op)) != REG)
00689 return register_operand (op, mode);
00690
00691 op = SUBREG_REG (op);
00692 }
00693
00694 if (GET_CODE (op) != REG)
00695 return FALSE;
00696
00697 return (REGNO (op) == FLAG_F0 || REGNO (op) >= FIRST_PSEUDO_REGISTER);
00698 }
00699
00700
00701
00702 int
00703 f1_operand (op, mode)
00704 rtx op;
00705 enum machine_mode mode;
00706 {
00707 if (GET_MODE (op) != mode && mode != VOIDmode)
00708 return FALSE;
00709
00710 if (GET_CODE (op) == SUBREG)
00711 {
00712 if (GET_CODE (SUBREG_REG (op)) != REG)
00713 return register_operand (op, mode);
00714
00715 op = SUBREG_REG (op);
00716 }
00717
00718 if (GET_CODE (op) != REG)
00719 return FALSE;
00720
00721 return (REGNO (op) == FLAG_F1 || REGNO (op) >= FIRST_PSEUDO_REGISTER);
00722 }
00723
00724
00725
00726 int
00727 carry_operand (op, mode)
00728 rtx op;
00729 enum machine_mode mode;
00730 {
00731 if (GET_MODE (op) != mode && mode != VOIDmode)
00732 return FALSE;
00733
00734 if (GET_CODE (op) == SUBREG)
00735 {
00736 if (GET_CODE (SUBREG_REG (op)) != REG)
00737 return register_operand (op, mode);
00738
00739 op = SUBREG_REG (op);
00740 }
00741
00742 if (GET_CODE (op) != REG)
00743 return FALSE;
00744
00745 return (REGNO (op) == FLAG_CARRY || REGNO (op) >= FIRST_PSEUDO_REGISTER);
00746 }
00747
00748
00749
00750
00751 int
00752 reg_or_0_operand (op, mode)
00753 rtx op;
00754 enum machine_mode mode;
00755 {
00756 switch (GET_CODE (op))
00757 {
00758 default:
00759 break;
00760
00761 case REG:
00762 case SUBREG:
00763 if (GET_MODE (op) != mode && mode != VOIDmode)
00764 return FALSE;
00765
00766 return register_operand (op, mode);
00767
00768 case CONST_INT:
00769 return INTVAL (op) == 0;
00770
00771 case CONST_DOUBLE:
00772 return CONST_DOUBLE_HIGH (op) == 0 && CONST_DOUBLE_LOW (op) == 0;
00773 }
00774
00775 return FALSE;
00776 }
00777
00778
00779
00780 int
00781 gpr_or_signed6_operand (op, mode)
00782 rtx op;
00783 enum machine_mode mode;
00784 {
00785 if (GET_CODE (op) == SUBREG)
00786 {
00787 if (GET_CODE (SUBREG_REG (op)) != REG)
00788 return register_operand (op, mode);
00789
00790 op = SUBREG_REG (op);
00791 }
00792
00793 if (GET_CODE (op) == CONST_INT)
00794 return IN_RANGE_P (INTVAL (op), -32, 31);
00795
00796 if (GET_CODE (op) != REG)
00797 return FALSE;
00798
00799 if (GET_MODE (op) != mode && mode != VOIDmode)
00800 return FALSE;
00801
00802 return GPR_OR_PSEUDO_P (REGNO (op));
00803 }
00804
00805
00806
00807 int
00808 gpr_or_unsigned5_operand (op, mode)
00809 rtx op;
00810 enum machine_mode mode;
00811 {
00812 if (GET_CODE (op) == SUBREG)
00813 {
00814 if (GET_CODE (SUBREG_REG (op)) != REG)
00815 return register_operand (op, mode);
00816
00817 op = SUBREG_REG (op);
00818 }
00819
00820 if (GET_CODE (op) == CONST_INT)
00821 return IN_RANGE_P (INTVAL (op), 0, 31);
00822
00823 if (GET_CODE (op) != REG)
00824 return FALSE;
00825
00826 if (GET_MODE (op) != mode && mode != VOIDmode)
00827 return FALSE;
00828
00829 return GPR_OR_PSEUDO_P (REGNO (op));
00830 }
00831
00832
00833
00834 int
00835 gpr_or_unsigned6_operand (op, mode)
00836 rtx op;
00837 enum machine_mode mode;
00838 {
00839 if (GET_CODE (op) == SUBREG)
00840 {
00841 if (GET_CODE (SUBREG_REG (op)) != REG)
00842 return register_operand (op, mode);
00843
00844 op = SUBREG_REG (op);
00845 }
00846
00847 if (GET_CODE (op) == CONST_INT)
00848 return IN_RANGE_P (INTVAL (op), 0, 63);
00849
00850 if (GET_CODE (op) != REG)
00851 return FALSE;
00852
00853 if (GET_MODE (op) != mode && mode != VOIDmode)
00854 return FALSE;
00855
00856 return GPR_OR_PSEUDO_P (REGNO (op));
00857 }
00858
00859
00860
00861 int
00862 gpr_or_constant_operand (op, mode)
00863 rtx op;
00864 enum machine_mode mode;
00865 {
00866 switch (GET_CODE (op))
00867 {
00868 default:
00869 break;
00870
00871 case CONST_INT:
00872 case SYMBOL_REF:
00873 case LABEL_REF:
00874 case CONST:
00875 return TRUE;
00876
00877 case SUBREG:
00878 if (GET_CODE (SUBREG_REG (op)) != REG)
00879 return register_operand (op, mode);
00880
00881 op = SUBREG_REG (op);
00882
00883
00884 case REG:
00885 if (GET_MODE (op) != mode && mode != VOIDmode)
00886 return FALSE;
00887
00888 return GPR_OR_PSEUDO_P (REGNO (op));
00889 }
00890
00891 return FALSE;
00892 }
00893
00894
00895
00896
00897 int
00898 gpr_or_dbl_const_operand (op, mode)
00899 rtx op;
00900 enum machine_mode mode;
00901 {
00902 switch (GET_CODE (op))
00903 {
00904 default:
00905 break;
00906
00907 case CONST_INT:
00908 case CONST_DOUBLE:
00909 case SYMBOL_REF:
00910 case LABEL_REF:
00911 case CONST:
00912 return TRUE;
00913
00914 case SUBREG:
00915 if (GET_CODE (SUBREG_REG (op)) != REG)
00916 return register_operand (op, mode);
00917
00918 op = SUBREG_REG (op);
00919
00920
00921 case REG:
00922 if (GET_MODE (op) != mode && mode != VOIDmode)
00923 return FALSE;
00924
00925 return GPR_OR_PSEUDO_P (REGNO (op));
00926 }
00927
00928 return FALSE;
00929 }
00930
00931
00932
00933 int
00934 gpr_or_memory_operand (op, mode)
00935 rtx op;
00936 enum machine_mode mode;
00937 {
00938 switch (GET_CODE (op))
00939 {
00940 default:
00941 break;
00942
00943 case SUBREG:
00944 if (GET_CODE (SUBREG_REG (op)) != REG)
00945 return register_operand (op, mode);
00946
00947 op = SUBREG_REG (op);
00948
00949
00950 case REG:
00951 if (GET_MODE (op) != mode && mode != VOIDmode)
00952 return FALSE;
00953
00954 return GPR_OR_PSEUDO_P (REGNO (op));
00955
00956 case MEM:
00957 return d30v_legitimate_address_p (mode, XEXP (op, 0), reload_completed);
00958 }
00959
00960 return FALSE;
00961 }
00962
00963
00964
00965
00966 int
00967 move_input_operand (op, mode)
00968 rtx op;
00969 enum machine_mode mode;
00970 {
00971 rtx subreg;
00972 enum rtx_code code;
00973
00974 switch (GET_CODE (op))
00975 {
00976 default:
00977 break;
00978
00979 case CONST_INT:
00980 case CONST_DOUBLE:
00981 case SYMBOL_REF:
00982 case LABEL_REF:
00983 case CONST:
00984 return TRUE;
00985
00986 case SUBREG:
00987 if (GET_MODE (op) != mode && mode != VOIDmode)
00988 return FALSE;
00989
00990 subreg = SUBREG_REG (op);
00991 code = GET_CODE (subreg);
00992 if (code == MEM)
00993 return d30v_legitimate_address_p ((int)mode, XEXP (subreg, 0),
00994 reload_completed);
00995
00996 return (code == REG);
00997
00998 case REG:
00999 if (GET_MODE (op) != mode && mode != VOIDmode)
01000 return FALSE;
01001
01002 return TRUE;
01003
01004 case MEM:
01005 if (GET_CODE (XEXP (op, 0)) == ADDRESSOF)
01006 return TRUE;
01007 return d30v_legitimate_address_p (mode, XEXP (op, 0),
01008 reload_completed);
01009 }
01010
01011 return FALSE;
01012 }
01013
01014
01015
01016
01017 int
01018 move_output_operand (op, mode)
01019 rtx op;
01020 enum machine_mode mode;
01021 {
01022 rtx subreg;
01023 enum rtx_code code;
01024
01025 switch (GET_CODE (op))
01026 {
01027 default:
01028 break;
01029
01030 case SUBREG:
01031 if (GET_MODE (op) != mode && mode != VOIDmode)
01032 return FALSE;
01033
01034 subreg = SUBREG_REG (op);
01035 code = GET_CODE (subreg);
01036 if (code == MEM)
01037 return d30v_legitimate_address_p ((int)mode, XEXP (subreg, 0),
01038 reload_completed);
01039
01040 return (code == REG);
01041
01042 case REG:
01043 if (GET_MODE (op) != mode && mode != VOIDmode)
01044 return FALSE;
01045
01046 return TRUE;
01047
01048 case MEM:
01049 if (GET_CODE (XEXP (op, 0)) == ADDRESSOF)
01050 return TRUE;
01051 return d30v_legitimate_address_p (mode, XEXP (op, 0),
01052 reload_completed);
01053 }
01054
01055 return FALSE;
01056 }
01057
01058
01059
01060 int
01061 signed6_operand (op, mode)
01062 rtx op;
01063 enum machine_mode mode ATTRIBUTE_UNUSED;
01064 {
01065 if (GET_CODE (op) == CONST_INT)
01066 return IN_RANGE_P (INTVAL (op), -32, 31);
01067
01068 return FALSE;
01069 }
01070
01071
01072
01073 int
01074 unsigned5_operand (op, mode)
01075 rtx op;
01076 enum machine_mode mode ATTRIBUTE_UNUSED;
01077 {
01078 if (GET_CODE (op) == CONST_INT)
01079 return IN_RANGE_P (INTVAL (op), 0, 31);
01080
01081 return FALSE;
01082 }
01083
01084
01085
01086 int
01087 unsigned6_operand (op, mode)
01088 rtx op;
01089 enum machine_mode mode ATTRIBUTE_UNUSED;
01090 {
01091 if (GET_CODE (op) == CONST_INT)
01092 return IN_RANGE_P (INTVAL (op), 0, 63);
01093
01094 return FALSE;
01095 }
01096
01097
01098
01099 int
01100 bitset_operand (op, mode)
01101 rtx op;
01102 enum machine_mode mode ATTRIBUTE_UNUSED;
01103 {
01104 if (GET_CODE (op) == CONST_INT)
01105 return IN_RANGE_P (exact_log2 (INTVAL (op)), 0, 31);
01106
01107 return FALSE;
01108 }
01109
01110
01111
01112
01113 int
01114 condexec_test_operator (op, mode)
01115 rtx op;
01116 enum machine_mode mode;
01117 {
01118 rtx x0, x1;
01119
01120 if (GET_MODE (op) != mode && mode != VOIDmode)
01121 return FALSE;
01122
01123 if (GET_CODE (op) != EQ && GET_CODE (op) != NE)
01124 return FALSE;
01125
01126 x0 = XEXP (op, 0);
01127 if (GET_CODE (x0) != REG || !BR_FLAG_OR_PSEUDO_P (REGNO (x0)))
01128 return FALSE;
01129
01130 x1 = XEXP (op, 1);
01131 if (GET_CODE (x1) != CONST_INT || INTVAL (x1) != 0)
01132 return FALSE;
01133
01134 return TRUE;
01135 }
01136
01137
01138
01139
01140 int
01141 condexec_branch_operator (op, mode)
01142 rtx op;
01143 enum machine_mode mode;
01144 {
01145 rtx x0, x1;
01146
01147 if (GET_MODE (op) != mode && mode != VOIDmode)
01148 return FALSE;
01149
01150 if (GET_CODE (op) != EQ && GET_CODE (op) != NE)
01151 return FALSE;
01152
01153 x0 = XEXP (op, 0);
01154 if (GET_CODE (x0) == REG)
01155 {
01156 int regno = REGNO (x0);
01157 if (!GPR_OR_PSEUDO_P (regno) && !BR_FLAG_P (regno))
01158 return FALSE;
01159 }
01160
01161
01162 else if (GET_CODE (x0) != CONST_INT)
01163 return FALSE;
01164
01165 x1 = XEXP (op, 1);
01166 if (GET_CODE (x1) != CONST_INT || INTVAL (x1) != 0)
01167 return FALSE;
01168
01169 return TRUE;
01170 }
01171
01172
01173
01174
01175 int
01176 condexec_unary_operator (op, mode)
01177 rtx op;
01178 enum machine_mode mode ATTRIBUTE_UNUSED;
01179 {
01180 rtx op0;
01181
01182
01183 if (!reload_completed)
01184 return FALSE;
01185
01186 if (GET_RTX_CLASS (GET_CODE (op)) != '1')
01187 return FALSE;
01188
01189 op0 = XEXP (op, 0);
01190 if (GET_CODE (op0) == SUBREG)
01191 op0 = SUBREG_REG (op0);
01192
01193 switch (GET_CODE (op))
01194 {
01195 default:
01196 break;
01197
01198 case ABS:
01199 case NOT:
01200 if (GET_MODE (op) == SImode && GET_CODE (op0) == REG && GPR_P (REGNO (op0)))
01201 return TRUE;
01202
01203 break;
01204 }
01205
01206 return FALSE;
01207 }
01208
01209
01210
01211
01212 int
01213 condexec_addsub_operator (op, mode)
01214 rtx op;
01215 enum machine_mode mode ATTRIBUTE_UNUSED;
01216 {
01217 rtx op0, op1;
01218
01219
01220 if (!reload_completed)
01221 return FALSE;
01222
01223 if (GET_RTX_CLASS (GET_CODE (op)) != '2' && GET_RTX_CLASS (GET_CODE (op)) != 'c')
01224 return FALSE;
01225
01226 op0 = XEXP (op, 0);
01227 op1 = XEXP (op, 1);
01228
01229 if (GET_CODE (op0) == SUBREG)
01230 op0 = SUBREG_REG (op0);
01231
01232 if (GET_CODE (op1) == SUBREG)
01233 op1 = SUBREG_REG (op1);
01234
01235 if (GET_CODE (op0) != REG)
01236 return FALSE;
01237
01238 switch (GET_CODE (op))
01239 {
01240 default:
01241 break;
01242
01243 case PLUS:
01244 case MINUS:
01245 return (GET_MODE (op) == SImode && GPR_P (REGNO (op0))
01246 && gpr_or_constant_operand (op1, SImode));
01247 }
01248
01249 return FALSE;
01250 }
01251
01252
01253
01254
01255
01256 int
01257 condexec_binary_operator (op, mode)
01258 rtx op;
01259 enum machine_mode mode ATTRIBUTE_UNUSED;
01260 {
01261 rtx op0, op1;
01262
01263
01264 if (!reload_completed)
01265 return FALSE;
01266
01267 if (GET_RTX_CLASS (GET_CODE (op)) != '2' && GET_RTX_CLASS (GET_CODE (op)) != 'c')
01268 return FALSE;
01269
01270 op0 = XEXP (op, 0);
01271 op1 = XEXP (op, 1);
01272
01273 if (GET_CODE (op0) == SUBREG)
01274 op0 = SUBREG_REG (op0);
01275
01276 if (GET_CODE (op1) == SUBREG)
01277 op1 = SUBREG_REG (op1);
01278
01279 if (GET_CODE (op0) != REG)
01280 return FALSE;
01281
01282
01283 switch (GET_CODE (op))
01284 {
01285 default:
01286 break;
01287
01288 case AND:
01289 case IOR:
01290 case XOR:
01291 case ASHIFTRT:
01292 case LSHIFTRT:
01293 case ROTATERT:
01294 return (GET_MODE (op) == SImode && GPR_P (REGNO (op0))
01295 && gpr_or_constant_operand (op1, SImode));
01296
01297 case ASHIFT:
01298 case ROTATE:
01299 return (GET_MODE (op) == SImode && GPR_P (REGNO (op0))
01300 && GET_CODE (op1) == CONST_INT);
01301 }
01302
01303 return FALSE;
01304 }
01305
01306
01307
01308
01309 int
01310 condexec_shiftl_operator (op, mode)
01311 rtx op;
01312 enum machine_mode mode ATTRIBUTE_UNUSED;
01313 {
01314 rtx op0, op1;
01315
01316
01317 if (!reload_completed)
01318 return FALSE;
01319
01320 if (GET_RTX_CLASS (GET_CODE (op)) != '2' && GET_RTX_CLASS (GET_CODE (op)) != 'c')
01321 return FALSE;
01322
01323 op0 = XEXP (op, 0);
01324 op1 = XEXP (op, 1);
01325
01326 if (GET_CODE (op0) == SUBREG)
01327 op0 = SUBREG_REG (op0);
01328
01329 if (GET_CODE (op1) == SUBREG)
01330 op1 = SUBREG_REG (op1);
01331
01332 if (GET_CODE (op0) != REG)
01333 return FALSE;
01334
01335 switch (GET_CODE (op))
01336 {
01337 default:
01338 break;
01339
01340 case ASHIFT:
01341 case ROTATE:
01342 return (GET_MODE (op) == SImode && GPR_P (REGNO (op0))
01343 && GET_CODE (op1) == NEG
01344 && GET_CODE (XEXP (op1, 0)) == REG
01345 && GPR_P (REGNO (XEXP (op1, 0))));
01346 }
01347
01348 return FALSE;
01349 }
01350
01351
01352
01353
01354 int
01355 condexec_extend_operator (op, mode)
01356 rtx op;
01357 enum machine_mode mode ATTRIBUTE_UNUSED;
01358 {
01359
01360 if (!reload_completed)
01361 return FALSE;
01362
01363 if (GET_RTX_CLASS (GET_CODE (op)) != '1')
01364 return FALSE;
01365
01366 switch (GET_CODE (op))
01367 {
01368 default:
01369 break;
01370
01371 case SIGN_EXTEND:
01372 case ZERO_EXTEND:
01373 if ((GET_MODE (op) == SImode && GET_MODE (XEXP (op, 0)) == QImode)
01374 || (GET_MODE (op) == SImode && GET_MODE (XEXP (op, 0)) == HImode)
01375 || (GET_MODE (op) == HImode && GET_MODE (XEXP (op, 0)) == QImode))
01376 return TRUE;
01377
01378 break;
01379 }
01380
01381 return FALSE;
01382 }
01383
01384
01385
01386
01387 int
01388 branch_zero_operator (op, mode)
01389 rtx op;
01390 enum machine_mode mode;
01391 {
01392 rtx x0, x1;
01393
01394 if (GET_MODE (op) != mode && mode != VOIDmode)
01395 return FALSE;
01396
01397 if (GET_CODE (op) != EQ && GET_CODE (op) != NE)
01398 return FALSE;
01399
01400 x0 = XEXP (op, 0);
01401 if (GET_CODE (x0) != REG || !GPR_OR_PSEUDO_P (REGNO (x0)))
01402 return FALSE;
01403
01404 x1 = XEXP (op, 1);
01405 if (GET_CODE (x1) != CONST_INT || INTVAL (x1) != 0)
01406 return FALSE;
01407
01408 return TRUE;
01409 }
01410
01411
01412
01413
01414 int
01415 cond_move_dest_operand (op, mode)
01416 register rtx op;
01417 enum machine_mode mode ATTRIBUTE_UNUSED;
01418 {
01419 rtx addr;
01420
01421 if (mode != QImode && mode != HImode && mode != SImode && mode != SFmode)
01422 return FALSE;
01423
01424 switch (GET_CODE (op))
01425 {
01426 default:
01427 break;
01428
01429 case REG:
01430 case SUBREG:
01431 return gpr_operand (op, mode);
01432
01433
01434 case MEM:
01435 addr = XEXP (op, 0);
01436 return (GET_CODE (addr) != POST_DEC
01437 && GET_CODE (addr) != POST_INC
01438 && d30v_legitimate_address_p (mode, addr, reload_completed));
01439 }
01440
01441 return FALSE;
01442 }
01443
01444
01445
01446 int
01447 cond_move_operand (op, mode)
01448 register rtx op;
01449 enum machine_mode mode ATTRIBUTE_UNUSED;
01450 {
01451 rtx addr;
01452
01453 if (mode != QImode && mode != HImode && mode != SImode && mode != SFmode)
01454 return FALSE;
01455
01456 switch (GET_CODE (op))
01457 {
01458 default:
01459 break;
01460
01461 case REG:
01462 case SUBREG:
01463 return gpr_operand (op, mode);
01464
01465 case CONST_DOUBLE:
01466 return GET_MODE (op) == SFmode;
01467
01468 case CONST_INT:
01469 case SYMBOL_REF:
01470 case LABEL_REF:
01471 case CONST:
01472 return TRUE;
01473
01474
01475 case MEM:
01476 addr = XEXP (op, 0);
01477 return (GET_CODE (addr) != POST_DEC
01478 && GET_CODE (addr) != POST_INC
01479 && d30v_legitimate_address_p (mode, addr, reload_completed));
01480 }
01481
01482 return FALSE;
01483 }
01484
01485
01486
01487
01488 int
01489 cond_exec_operand (op, mode)
01490 register rtx op;
01491 enum machine_mode mode;
01492 {
01493 if (mode != QImode && mode != HImode && mode != SImode && mode != SFmode)
01494 return FALSE;
01495
01496 switch (GET_CODE (op))
01497 {
01498 default:
01499 break;
01500
01501 case REG:
01502 case SUBREG:
01503 return gpr_operand (op, mode);
01504
01505 case CONST_DOUBLE:
01506 return GET_MODE (op) == SFmode;
01507
01508 case CONST_INT:
01509 case SYMBOL_REF:
01510 case LABEL_REF:
01511 case CONST:
01512 return TRUE;
01513
01514 case MEM:
01515 return memory_operand (op, mode);
01516 }
01517
01518 return FALSE;
01519 }
01520
01521
01522
01523 int
01524 srelational_si_operator (op, mode)
01525 register rtx op;
01526 enum machine_mode mode;
01527 {
01528 rtx x0, x1;
01529
01530 if (GET_MODE (op) != mode && mode != VOIDmode)
01531 return FALSE;
01532
01533 switch (GET_CODE (op))
01534 {
01535 default:
01536 return FALSE;
01537
01538 case EQ:
01539 case NE:
01540 case LT:
01541 case LE:
01542 case GT:
01543 case GE:
01544 break;
01545 }
01546
01547 x0 = XEXP (op, 0);
01548 if (GET_CODE (x0) != REG && GET_CODE (x0) != SUBREG)
01549 return FALSE;
01550
01551 if (GET_MODE (x0) != SImode)
01552 return FALSE;
01553
01554 x1 = XEXP (op, 1);
01555 switch (GET_CODE (x1))
01556 {
01557 default:
01558 return FALSE;
01559
01560 case REG:
01561 case SUBREG:
01562 case CONST_INT:
01563 case LABEL_REF:
01564 case SYMBOL_REF:
01565 case CONST:
01566 break;
01567 }
01568
01569 return TRUE;
01570 }
01571
01572
01573
01574 int
01575 urelational_si_operator (op, mode)
01576 register rtx op;
01577 enum machine_mode mode;
01578 {
01579 rtx x0, x1;
01580
01581 if (GET_MODE (op) != mode && mode != VOIDmode)
01582 return FALSE;
01583
01584 switch (GET_CODE (op))
01585 {
01586 default:
01587 return FALSE;
01588
01589 case LTU:
01590 case LEU:
01591 case GTU:
01592 case GEU:
01593 break;
01594 }
01595
01596 x0 = XEXP (op, 0);
01597 if (GET_CODE (x0) != REG && GET_CODE (x0) != SUBREG)
01598 return FALSE;
01599
01600 if (GET_MODE (x0) != SImode)
01601 return FALSE;
01602
01603 x1 = XEXP (op, 1);
01604 switch (GET_CODE (x1))
01605 {
01606 default:
01607 return FALSE;
01608
01609 case REG:
01610 case SUBREG:
01611 case CONST_INT:
01612 case LABEL_REF:
01613 case SYMBOL_REF:
01614 case CONST:
01615 break;
01616 }
01617
01618 return TRUE;
01619 }
01620
01621
01622
01623 int
01624 relational_di_operator (op, mode)
01625 register rtx op;
01626 enum machine_mode mode;
01627 {
01628 rtx x0, x1;
01629
01630 if (GET_MODE (op) != mode && mode != VOIDmode)
01631 return FALSE;
01632
01633 if (GET_RTX_CLASS (GET_CODE (op)) != '<')
01634 return FALSE;
01635
01636 x0 = XEXP (op, 0);
01637 if (GET_CODE (x0) != REG && GET_CODE (x0) != SUBREG)
01638 return FALSE;
01639
01640 if (GET_MODE (x0) != DImode)
01641 return FALSE;
01642
01643 x1 = XEXP (op, 1);
01644 if (GET_CODE (x1) != REG && GET_CODE (x1) != SUBREG
01645 && GET_CODE (x1) != CONST_INT && GET_CODE (x1) != CONST_DOUBLE)
01646 return FALSE;
01647
01648 return TRUE;
01649 }
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693 d30v_stack_t *
01694 d30v_stack_info ()
01695 {
01696 static d30v_stack_t info, zero_info;
01697 d30v_stack_t *info_ptr = &info;
01698 tree fndecl = current_function_decl;
01699 tree fntype = TREE_TYPE (fndecl);
01700 int varargs_p = 0;
01701 tree cur_arg;
01702 tree next_arg;
01703 int saved_gprs;
01704 int saved_accs;
01705 int memrefs_2words;
01706 int memrefs_1word;
01707 unsigned char save_gpr_p[GPR_LAST];
01708 int i;
01709
01710
01711 if (d30v_stack_cache)
01712 return d30v_stack_cache;
01713
01714
01715 info = zero_info;
01716
01717 if (current_function_profile)
01718 regs_ever_live[GPR_LINK] = 1;
01719
01720
01721 if (TYPE_ARG_TYPES (fntype) != 0
01722 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) != void_type_node))
01723 varargs_p = 1;
01724 else
01725 {
01726
01727 for (cur_arg = DECL_ARGUMENTS (fndecl); cur_arg != (tree)0; cur_arg = next_arg)
01728 {
01729 next_arg = TREE_CHAIN (cur_arg);
01730 if (next_arg == (tree)0)
01731 {
01732 if (DECL_NAME (cur_arg)
01733 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)), "__builtin_va_alist"))
01734 varargs_p = 1;
01735
01736 break;
01737 }
01738 }
01739 }
01740
01741
01742 saved_accs = 0;
01743 memrefs_2words = 0;
01744 memrefs_1word = 0;
01745 for (i = ACCUM_FIRST; i <= ACCUM_LAST; i++)
01746 {
01747 if (regs_ever_live[i] && !call_used_regs[i])
01748 {
01749 info_ptr->save_p[i] = 2;
01750 saved_accs++;
01751 memrefs_2words++;
01752 }
01753 }
01754
01755 saved_gprs = 0;
01756 for (i = GPR_FIRST; i <= GPR_LAST; i++)
01757 {
01758 if (regs_ever_live[i] && (!call_used_regs[i] || i == GPR_LINK))
01759 {
01760 save_gpr_p[i] = 1;
01761 saved_gprs++;
01762 }
01763 else
01764 save_gpr_p[i] = 0;
01765 }
01766
01767
01768 for (i = GPR_FIRST; i <= GPR_LAST; i++)
01769 {
01770 if (((i - GPR_FIRST) & 1) == 0 && save_gpr_p[i] && save_gpr_p[i+1])
01771 {
01772 memrefs_2words++;
01773 info_ptr->save_p[i++] = 2;
01774 }
01775 else if (save_gpr_p[i])
01776 {
01777 memrefs_1word++;
01778 info_ptr->save_p[i] = 1;
01779 }
01780 }
01781
01782
01783 info_ptr->varargs_p = varargs_p;
01784 info_ptr->varargs_size = ((varargs_p)
01785 ? (GPR_ARG_LAST + 1 - GPR_ARG_FIRST) * UNITS_PER_WORD
01786 : 0);
01787
01788 info_ptr->accum_size = 2 * UNITS_PER_WORD * saved_accs;
01789 info_ptr->gpr_size = D30V_ALIGN (UNITS_PER_WORD * saved_gprs,
01790 2 * UNITS_PER_WORD);
01791 info_ptr->vars_size = D30V_ALIGN (get_frame_size (), 2 * UNITS_PER_WORD);
01792 info_ptr->parm_size = D30V_ALIGN (current_function_outgoing_args_size,
01793 2 * UNITS_PER_WORD);
01794
01795 info_ptr->total_size = D30V_ALIGN ((info_ptr->gpr_size
01796 + info_ptr->accum_size
01797 + info_ptr->vars_size
01798 + info_ptr->parm_size
01799 + info_ptr->varargs_size
01800 + current_function_pretend_args_size),
01801 (STACK_BOUNDARY / BITS_PER_UNIT));
01802
01803 info_ptr->save_offset = (info_ptr->total_size
01804 - (current_function_pretend_args_size
01805 + info_ptr->varargs_size
01806 + info_ptr->gpr_size
01807 + info_ptr->accum_size));
01808
01809
01810
01811 info_ptr->link_offset = (info_ptr->total_size
01812 - (current_function_pretend_args_size
01813 + info_ptr->varargs_size
01814 + (info_ptr->gpr_size
01815 - UNITS_PER_WORD * saved_gprs)
01816 + UNITS_PER_WORD));
01817
01818 info_ptr->memrefs_varargs = info_ptr->varargs_size / (2 * UNITS_PER_WORD);
01819 info_ptr->memrefs_2words = memrefs_2words;
01820 info_ptr->memrefs_1word = memrefs_1word;
01821
01822 if (reload_completed)
01823 d30v_stack_cache = info_ptr;
01824
01825 return info_ptr;
01826 }
01827
01828
01829
01830
01831 void
01832 debug_stack_info (info)
01833 d30v_stack_t *info;
01834 {
01835 int i;
01836
01837 if (!info)
01838 info = d30v_stack_info ();
01839
01840 fprintf (stderr, "\nStack information for function %s:\n",
01841 ((current_function_decl && DECL_NAME (current_function_decl))
01842 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
01843 : "<unknown>"));
01844
01845 fprintf (stderr, "\tsave_offset = %d\n", info->save_offset);
01846 fprintf (stderr, "\tmemrefs_varargs = %d\n", info->memrefs_varargs);
01847 fprintf (stderr, "\tmemrefs_2words = %d\n", info->memrefs_2words);
01848 fprintf (stderr, "\tmemrefs_1word = %d\n", info->memrefs_1word);
01849 fprintf (stderr, "\tvarargs_p = %d\n", info->varargs_p);
01850 fprintf (stderr, "\tvarargs_size = %d\n", info->varargs_size);
01851 fprintf (stderr, "\tvars_size = %d\n", info->vars_size);
01852 fprintf (stderr, "\tparm_size = %d\n", info->parm_size);
01853 fprintf (stderr, "\tgpr_size = %d\n", info->gpr_size);
01854 fprintf (stderr, "\taccum_size = %d\n", info->accum_size);
01855 fprintf (stderr, "\ttotal_size = %d\n", info->total_size);
01856 fprintf (stderr, "\tsaved registers =");
01857
01858 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
01859 {
01860 if (info->save_p[i] == 2)
01861 {
01862 fprintf (stderr, " %s-%s", reg_names[i], reg_names[i+1]);
01863 i++;
01864 }
01865 else if (info->save_p[i])
01866 fprintf (stderr, " %s", reg_names[i]);
01867 }
01868
01869 putc ('\n', stderr);
01870 fflush (stderr);
01871 }
01872
01873
01874
01875
01876 int
01877 direct_return ()
01878 {
01879 if (reload_completed)
01880 {
01881 d30v_stack_t *info = d30v_stack_info ();
01882
01883
01884 if (info->total_size == 0)
01885 return 1;
01886
01887 #if 0
01888
01889
01890 if (info->total_size == info->vars_size
01891 && IN_RANGE_P (info->total_size, 1, 31))
01892 return 1;
01893 #endif
01894 }
01895
01896 return 0;
01897 }
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916 void
01917 d30v_init_cumulative_args (cum, fntype, libname, indirect, incoming)
01918 CUMULATIVE_ARGS *cum;
01919 tree fntype;
01920 rtx libname;
01921 int indirect;
01922 int incoming;
01923 {
01924 *cum = GPR_ARG_FIRST;
01925
01926 if (TARGET_DEBUG_ARG)
01927 {
01928 fprintf (stderr, "\ninit_cumulative_args:");
01929 if (indirect)
01930 fputs (" indirect", stderr);
01931
01932 if (incoming)
01933 fputs (" incoming", stderr);
01934
01935 if (fntype)
01936 {
01937 tree ret_type = TREE_TYPE (fntype);
01938 fprintf (stderr, " return=%s,",
01939 tree_code_name[ (int)TREE_CODE (ret_type) ]);
01940 }
01941
01942 if (libname && GET_CODE (libname) == SYMBOL_REF)
01943 fprintf (stderr, " libname=%s", XSTR (libname, 0));
01944
01945 putc ('\n', stderr);
01946 }
01947 }
01948
01949
01950
01951
01952
01953
01954 int
01955 d30v_function_arg_boundary (mode, type)
01956 enum machine_mode mode;
01957 tree type;
01958 {
01959 int size = ((mode == BLKmode && type)
01960 ? int_size_in_bytes (type)
01961 : (int) GET_MODE_SIZE (mode));
01962
01963 return (size > UNITS_PER_WORD) ? 2*UNITS_PER_WORD : UNITS_PER_WORD;
01964 }
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996 rtx
01997 d30v_function_arg (cum, mode, type, named, incoming)
01998 CUMULATIVE_ARGS *cum;
01999 enum machine_mode mode;
02000 tree type;
02001 int named;
02002 int incoming ATTRIBUTE_UNUSED;
02003 {
02004 int size = ((mode == BLKmode && type)
02005 ? int_size_in_bytes (type)
02006 : (int) GET_MODE_SIZE (mode));
02007 int adjust = (size > UNITS_PER_WORD && (*cum & 1) != 0);
02008 rtx ret;
02009
02010
02011 if (mode == VOIDmode)
02012 ret = const0_rtx;
02013
02014 else if (*cum + adjust <= GPR_ARG_LAST)
02015 ret = gen_rtx (REG, mode, *cum + adjust);
02016
02017 else
02018 ret = NULL_RTX;
02019
02020 if (TARGET_DEBUG_ARG)
02021 fprintf (stderr,
02022 "function_arg: words = %2d, mode = %4s, named = %d, size = %3d, adjust = %1d, arg = %s\n",
02023 *cum, GET_MODE_NAME (mode), named, size, adjust,
02024 (ret) ? ((ret == const0_rtx) ? "<0>" : reg_names[ REGNO (ret) ]) : "memory");
02025
02026 return ret;
02027 }
02028
02029
02030
02031
02032
02033
02034
02035
02036
02037
02038
02039
02040
02041
02042
02043
02044
02045
02046 int
02047 d30v_function_arg_partial_nregs (cum, mode, type, named)
02048 CUMULATIVE_ARGS *cum;
02049 enum machine_mode mode;
02050 tree type;
02051 int named ATTRIBUTE_UNUSED;
02052 {
02053 int bytes = ((mode == BLKmode)
02054 ? int_size_in_bytes (type)
02055 : (int) GET_MODE_SIZE (mode));
02056 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
02057 int adjust = (bytes > UNITS_PER_WORD && (*cum & 1) != 0);
02058 int arg_num = *cum + adjust;
02059 int ret;
02060
02061 ret = ((arg_num <= GPR_ARG_LAST && arg_num + words > GPR_ARG_LAST+1)
02062 ? GPR_ARG_LAST - arg_num + 1
02063 : 0);
02064
02065 if (TARGET_DEBUG_ARG && ret)
02066 fprintf (stderr, "function_arg_partial_nregs: %d\n", ret);
02067
02068 return ret;
02069 }
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084 int
02085 d30v_function_arg_pass_by_reference (cum, mode, type, named)
02086 CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
02087 enum machine_mode mode;
02088 tree type;
02089 int named ATTRIBUTE_UNUSED;
02090 {
02091 int ret = MUST_PASS_IN_STACK (mode, type);
02092
02093 if (TARGET_DEBUG_ARG && ret)
02094 fprintf (stderr, "function_arg_pass_by_reference: %d\n", ret);
02095
02096 return ret;
02097 }
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109 void
02110 d30v_function_arg_advance (cum, mode, type, named)
02111 CUMULATIVE_ARGS *cum;
02112 enum machine_mode mode;
02113 tree type;
02114 int named;
02115 {
02116 int bytes = ((mode == BLKmode)
02117 ? int_size_in_bytes (type)
02118 : (int) GET_MODE_SIZE (mode));
02119 int words = D30V_ALIGN (bytes, UNITS_PER_WORD) / UNITS_PER_WORD;
02120 int adjust = (bytes > UNITS_PER_WORD && (*cum & 1) != 0);
02121
02122 *cum += words + adjust;
02123
02124 if (TARGET_DEBUG_ARG)
02125 fprintf (stderr,
02126 "function_adv: words = %2d, mode = %4s, named = %d, size = %3d, adjust = %1d\n",
02127 *cum, GET_MODE_NAME (mode), named, words * UNITS_PER_WORD, adjust);
02128 }
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140 rtx
02141 d30v_expand_builtin_saveregs ()
02142 {
02143 int offset = UNITS_PER_WORD * (GPR_ARG_LAST + 1 - GPR_ARG_FIRST);
02144
02145 if (TARGET_DEBUG_ARG)
02146 fprintf (stderr, "expand_builtin_saveregs: offset from ap = %d\n",
02147 offset);
02148
02149 return gen_rtx (PLUS, Pmode, virtual_incoming_args_rtx, GEN_INT (- offset));
02150 }
02151
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182 void
02183 d30v_setup_incoming_varargs (cum, mode, type, pretend_size, second_time)
02184 CUMULATIVE_ARGS *cum;
02185 enum machine_mode mode;
02186 tree type ATTRIBUTE_UNUSED;
02187 int *pretend_size ATTRIBUTE_UNUSED;
02188 int second_time;
02189 {
02190 if (TARGET_DEBUG_ARG)
02191 fprintf (stderr,
02192 "setup_vararg: words = %2d, mode = %4s, second_time = %d\n",
02193 *cum, GET_MODE_NAME (mode), second_time);
02194 }
02195
02196
02197
02198
02199 tree
02200 d30v_build_va_list ()
02201 {
02202 tree f_arg_ptr, f_arg_num, record, type_decl;
02203 tree int_type_node;
02204
02205 record = make_lang_type (RECORD_TYPE);
02206 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
02207 int_type_node = make_signed_type (INT_TYPE_SIZE);
02208
02209 f_arg_ptr = build_decl (FIELD_DECL, get_identifier ("__va_arg_ptr"),
02210 ptr_type_node);
02211 f_arg_num = build_decl (FIELD_DECL, get_identifier ("__va_arg_num"),
02212 int_type_node);
02213
02214 DECL_FIELD_CONTEXT (f_arg_ptr) = record;
02215 DECL_FIELD_CONTEXT (f_arg_num) = record;
02216
02217 TREE_CHAIN (record) = type_decl;
02218 TYPE_NAME (record) = type_decl;
02219 TYPE_FIELDS (record) = f_arg_ptr;
02220 TREE_CHAIN (f_arg_ptr) = f_arg_num;
02221
02222 layout_type (record);
02223
02224
02225 return build_array_type (record, build_index_type (size_zero_node));
02226 }
02227
02228
02229
02230
02231 void
02232 d30v_expand_builtin_va_start (stdarg_p, valist, nextarg)
02233 int stdarg_p ATTRIBUTE_UNUSED;
02234 tree valist;
02235 rtx nextarg ATTRIBUTE_UNUSED;
02236 {
02237 HOST_WIDE_INT words;
02238 tree f_arg_ptr, f_arg_num;
02239 tree arg_ptr, arg_num, saveregs, t;
02240
02241 f_arg_ptr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
02242 f_arg_num = TREE_CHAIN (f_arg_ptr);
02243
02244 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
02245 arg_ptr = build (COMPONENT_REF, TREE_TYPE (f_arg_ptr), valist, f_arg_ptr);
02246 arg_num = build (COMPONENT_REF, TREE_TYPE (f_arg_num), valist, f_arg_num);
02247
02248 words = current_function_args_info;
02249
02250
02251 saveregs = make_tree (TREE_TYPE (arg_ptr), d30v_expand_builtin_saveregs ());
02252 t = build (MODIFY_EXPR, TREE_TYPE (arg_ptr), arg_ptr, saveregs);
02253 TREE_SIDE_EFFECTS (t) = 1;
02254 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
02255
02256
02257 t = build (PLUS_EXPR, TREE_TYPE (arg_num), build_int_2 (words, 0),
02258 build_int_2 (-GPR_ARG_FIRST, 0));
02259 t = build (MODIFY_EXPR, TREE_TYPE (arg_num), arg_num, t);
02260 TREE_SIDE_EFFECTS (t) = 1;
02261 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
02262 }
02263
02264
02265
02266
02267 rtx
02268 d30v_expand_builtin_va_arg(valist, type)
02269 tree valist;
02270 tree type;
02271 {
02272 tree f_arg_ptr, f_arg_num;
02273 tree arg_ptr, arg_num, t, ptr;
02274 int num, size;
02275 rtx lab_false, ptr_rtx, r;
02276
02277 f_arg_ptr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
02278 f_arg_num = TREE_CHAIN (f_arg_ptr);
02279
02280 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
02281 arg_ptr = build (COMPONENT_REF, TREE_TYPE (f_arg_ptr), valist, f_arg_ptr);
02282 arg_num = build (COMPONENT_REF, TREE_TYPE (f_arg_num), valist, f_arg_num);
02283
02284 size = int_size_in_bytes (type);
02285
02286 lab_false = gen_label_rtx ();
02287 ptr_rtx = gen_reg_rtx (Pmode);
02288
02289
02290
02291
02292 if (size > UNITS_PER_WORD)
02293 {
02294 t = build (BIT_AND_EXPR, TREE_TYPE (arg_num), arg_num,
02295 build_int_2 (1, 0));
02296
02297 emit_cmp_and_jump_insns (expand_expr (t, NULL_RTX, QImode, EXPAND_NORMAL),
02298 GEN_INT (0), EQ, const1_rtx, QImode, 1,
02299 lab_false);
02300
02301 t = build (POSTINCREMENT_EXPR, TREE_TYPE (arg_num), arg_num,
02302 build_int_2 (1, 0));
02303 TREE_SIDE_EFFECTS (t) = 1;
02304 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
02305
02306 emit_label (lab_false);
02307 }
02308
02309
02310
02311
02312
02313 t = build (MULT_EXPR, TREE_TYPE (arg_num), arg_num, build_int_2 (4, 0));
02314 t = build (PLUS_EXPR, ptr_type_node, arg_ptr, t);
02315
02316
02317
02318
02319 if (size < UNITS_PER_WORD)
02320 t = build (PLUS_EXPR, ptr_type_node, t,
02321 build_int_2 (UNITS_PER_WORD - size, 0));
02322
02323 TREE_SIDE_EFFECTS (t) = 1;
02324
02325 ptr = build1 (NOP_EXPR, build_pointer_type (type), t);
02326 t = build (MODIFY_EXPR, type, ptr, t);
02327
02328 r = expand_expr (t, ptr_rtx, Pmode, EXPAND_NORMAL);
02329 if (r != ptr_rtx)
02330 emit_move_insn (ptr_rtx, r);
02331
02332
02333
02334 num = (size + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
02335 t = build (POSTINCREMENT_EXPR, TREE_TYPE (arg_num), arg_num,
02336 build_int_2 (num, 0));
02337 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
02338
02339 return ptr_rtx;
02340 }
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351 static void
02352 d30v_output_function_prologue (stream, size)
02353 FILE *stream ATTRIBUTE_UNUSED;
02354 HOST_WIDE_INT size ATTRIBUTE_UNUSED;
02355 {
02356
02357
02358 }
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368
02369 void
02370 d30v_expand_prologue ()
02371 {
02372 rtx sp = stack_pointer_rtx;
02373 d30v_stack_t *info = d30v_stack_info ();
02374 int i;
02375 rtx mem_di = NULL_RTX;
02376 rtx mem_si = NULL_RTX;
02377 int num_memrefs = (info->memrefs_2words
02378 + info->memrefs_1word
02379 + info->memrefs_varargs);
02380
02381 if (TARGET_DEBUG_STACK)
02382 debug_stack_info (info);
02383
02384
02385 if (info->total_size)
02386 emit_insn (gen_addsi3 (sp, sp, GEN_INT (- info->total_size)));
02387
02388
02389
02390
02391
02392 if (num_memrefs > 1)
02393 {
02394 rtx save_tmp = gen_rtx (REG, Pmode, GPR_STACK_TMP);
02395 rtx post_inc = gen_rtx (POST_INC, Pmode, save_tmp);
02396 mem_di = gen_rtx (MEM, DImode, post_inc);
02397 mem_si = gen_rtx (MEM, SImode, post_inc);
02398 emit_insn (gen_addsi3 (save_tmp, sp, GEN_INT (info->save_offset)));
02399 }
02400 else if (num_memrefs == 1)
02401 {
02402 rtx addr = plus_constant (sp, info->save_offset);
02403 mem_di = gen_rtx (MEM, DImode, addr);
02404 mem_si = gen_rtx (MEM, SImode, addr);
02405 }
02406
02407
02408 for (i = ACCUM_FIRST; i <= ACCUM_LAST; i++)
02409 if (info->save_p[i])
02410 {
02411 rtx acc_tmp = gen_rtx (REG, DImode, GPR_ATMP_FIRST);
02412 emit_insn (gen_movdi (acc_tmp, gen_rtx (REG, DImode, i)));
02413 emit_insn (gen_movdi (mem_di, acc_tmp));
02414 }
02415
02416
02417 for (i = GPR_FIRST; i <= GPR_LAST; i += 2)
02418 if (info->save_p[i] == 2)
02419 emit_insn (gen_movdi (mem_di, gen_rtx (REG, DImode, i)));
02420
02421
02422 for (i = GPR_FIRST; i <= GPR_LAST; i++)
02423 if (info->save_p[i] == 1)
02424 emit_insn (gen_movsi (mem_si, gen_rtx (REG, SImode, i)));
02425
02426
02427 if (info->varargs_p)
02428 {
02429
02430 if ((info->memrefs_1word & 1) != 0)
02431 {
02432 rtx save_tmp = XEXP (XEXP (mem_si, 0), 0);
02433 emit_insn (gen_addsi3 (save_tmp, save_tmp, GEN_INT (UNITS_PER_WORD)));
02434 }
02435
02436 for (i = GPR_ARG_FIRST; i <= GPR_ARG_LAST; i += 2)
02437 emit_insn (gen_movdi (mem_di, gen_rtx (REG, DImode, i)));
02438 }
02439
02440
02441 if (frame_pointer_needed)
02442 emit_move_insn (frame_pointer_rtx, sp);
02443
02444
02445 emit_insn (gen_blockage ());
02446 }
02447
02448
02449
02450
02451
02452
02453
02454
02455
02456
02457 static void
02458 d30v_output_function_epilogue (stream, size)
02459 FILE *stream ATTRIBUTE_UNUSED;
02460 HOST_WIDE_INT size ATTRIBUTE_UNUSED;
02461 {
02462
02463
02464 d30v_stack_cache = (d30v_stack_t *)0;
02465 }
02466
02467
02468
02469
02470
02471
02472
02473
02474
02475
02476
02477 void
02478 d30v_expand_epilogue ()
02479 {
02480 rtx sp = stack_pointer_rtx;
02481 d30v_stack_t *info = d30v_stack_info ();
02482 int i;
02483 rtx mem_di = NULL_RTX;
02484 rtx mem_si = NULL_RTX;
02485 rtx post_inc;
02486 int extra_stack;
02487
02488
02489 emit_insn (gen_blockage ());
02490
02491
02492 if (frame_pointer_needed)
02493 emit_move_insn (sp, frame_pointer_rtx);
02494
02495
02496
02497
02498 if (info->save_offset)
02499 emit_insn (gen_addsi3 (sp, sp, GEN_INT (info->save_offset)));
02500
02501 post_inc = gen_rtx (POST_INC, Pmode, sp);
02502 mem_di = gen_rtx (MEM, DImode, post_inc);
02503 mem_si = gen_rtx (MEM, SImode, post_inc);
02504
02505
02506 for (i = ACCUM_FIRST; i <= ACCUM_LAST; i++)
02507 if (info->save_p[i])
02508 {
02509 rtx acc_tmp = gen_rtx (REG, DImode, GPR_ATMP_FIRST);
02510 emit_insn (gen_movdi (acc_tmp, mem_di));
02511 emit_insn (gen_movdi (gen_rtx (REG, DImode, i), acc_tmp));
02512 }
02513
02514
02515 for (i = GPR_FIRST; i <= GPR_LAST; i += 2)
02516 if (info->save_p[i] == 2)
02517 emit_insn (gen_movdi (gen_rtx (REG, DImode, i), mem_di));
02518
02519
02520 extra_stack = 0;
02521 for (i = GPR_FIRST; i <= GPR_LAST; i++)
02522 if (info->save_p[i] == 1)
02523 {
02524 if (cfun->machine->eh_epilogue_sp_ofs && i == GPR_LINK)
02525 extra_stack = 4;
02526 else
02527 {
02528 if (extra_stack)
02529 {
02530 emit_insn (gen_addsi3 (sp, sp, GEN_INT (extra_stack)));
02531 extra_stack = 0;
02532 }
02533 emit_insn (gen_movsi (gen_rtx (REG, SImode, i), mem_si));
02534 }
02535 }
02536
02537
02538
02539 if ((info->memrefs_1word & 1) != 0)
02540 extra_stack += UNITS_PER_WORD;
02541 extra_stack += current_function_pretend_args_size + info->varargs_size;
02542
02543 if (extra_stack)
02544 {
02545 if (cfun->machine->eh_epilogue_sp_ofs)
02546 emit_insn (gen_addsi3 (cfun->machine->eh_epilogue_sp_ofs,
02547 cfun->machine->eh_epilogue_sp_ofs,
02548 GEN_INT (extra_stack)));
02549 else
02550 emit_insn (gen_addsi3 (sp, sp, GEN_INT (extra_stack)));
02551 }
02552 if (cfun->machine->eh_epilogue_sp_ofs)
02553 emit_insn (gen_addsi3 (sp, sp, cfun->machine->eh_epilogue_sp_ofs));
02554
02555
02556 emit_jump_insn (gen_rtx_RETURN (VOIDmode));
02557 }
02558
02559
02560
02561
02562
02563
02564
02565
02566
02567
02568
02569
02570
02571
02572 void
02573 d30v_function_profiler (stream, labelno)
02574 FILE *stream;
02575 int labelno ATTRIBUTE_UNUSED;
02576 {
02577 fprintf (stream, "# profile\n");
02578 }
02579
02580
02581
02582
02583
02584
02585
02586
02587 void
02588 d30v_split_double (value, p_high, p_low)
02589 rtx value;
02590 rtx *p_high;
02591 rtx *p_low;
02592 {
02593 int offset = 0;
02594 int regno;
02595
02596 if (!reload_completed)
02597 abort ();
02598
02599 switch (GET_CODE (value))
02600 {
02601 case SUBREG:
02602 if (GET_CODE (SUBREG_REG (value)) != REG)
02603 abort ();
02604 offset = subreg_regno_offset (REGNO (SUBREG_REG (value)),
02605 GET_MODE (SUBREG_REG (value)),
02606 SUBREG_BYTE (value),
02607 GET_MODE (value));
02608 value = SUBREG_REG (value);
02609
02610
02611
02612 case REG:
02613 regno = REGNO (value) + offset;
02614 if (!GPR_P (regno))
02615 abort ();
02616
02617 *p_high = gen_rtx (REG, SImode, regno);
02618 *p_low = gen_rtx (REG, SImode, regno+1);
02619 break;
02620
02621 case CONST_INT:
02622 case CONST_DOUBLE:
02623 split_double (value, p_high, p_low);
02624 break;
02625
02626 default:
02627 abort ();
02628 }
02629 }
02630
02631
02632
02633
02634
02635
02636
02637
02638
02639
02640
02641 void
02642 d30v_print_operand_address (stream, x)
02643 FILE *stream;
02644 rtx x;
02645 {
02646 if (GET_CODE (x) == MEM)
02647 x = XEXP (x, 0);
02648
02649 switch (GET_CODE (x))
02650 {
02651 default:
02652 break;
02653
02654 case REG:
02655 fputs (reg_names[ REGNO (x) ], stream);
02656 return;
02657
02658 case CONST_INT:
02659 fprintf (stream, "%ld", (long) INTVAL (x));
02660 return;
02661
02662
02663
02664 case SYMBOL_REF:
02665 fputs ("(", stream);
02666 assemble_name (stream, XSTR (x, 0));
02667 fputs (")", stream);
02668 return;
02669
02670 case LABEL_REF:
02671 case CONST:
02672 output_addr_const (stream, x);
02673 return;
02674 }
02675
02676 fatal_insn ("bad insn to d30v_print_operand_address:", x);
02677 }
02678
02679
02680
02681
02682 static void
02683 d30v_print_operand_memory_reference (stream, x)
02684 FILE *stream;
02685 rtx x;
02686 {
02687 rtx x0 = NULL_RTX;
02688 rtx x1 = NULL_RTX;
02689
02690 switch (GET_CODE (x))
02691 {
02692 default:
02693 fatal_insn ("bad insn to d30v_print_operand_memory_reference:", x);
02694 break;
02695
02696 case SUBREG:
02697 case REG:
02698 case POST_DEC:
02699 case POST_INC:
02700 x0 = x;
02701 break;
02702
02703 case CONST_INT:
02704 case SYMBOL_REF:
02705 case LABEL_REF:
02706 case CONST:
02707 x1 = x;
02708 break;
02709
02710 case PLUS:
02711 x0 = XEXP (x, 0);
02712 x1 = XEXP (x, 1);
02713 if (GET_CODE (x0) == CONST_INT || GET_CODE (x0) == SYMBOL_REF
02714 || GET_CODE (x0) == CONST || GET_CODE (x0) == LABEL_REF)
02715 {
02716 x0 = XEXP (x, 1);
02717 x1 = XEXP (x, 0);
02718 }
02719 break;
02720 }
02721
02722 fputs ("@(", stream);
02723 if (!x0)
02724 fputs (reg_names[GPR_R0], stream);
02725
02726 else
02727 {
02728 const char *suffix = "";
02729 int offset0 = 0;
02730
02731 if (GET_CODE (x0) == SUBREG)
02732 {
02733 offset0 = subreg_regno_offset (REGNO (SUBREG_REG (x0)),
02734 GET_MODE (SUBREG_REG (x0)),
02735 SUBREG_BYTE (x0),
02736 GET_MODE (x0));
02737 x0 = SUBREG_REG (x0);
02738 }
02739
02740 if (GET_CODE (x0) == POST_INC)
02741 {
02742 x0 = XEXP (x0, 0);
02743 suffix = "+";
02744 }
02745 else if (GET_CODE (x0) == POST_DEC)
02746 {
02747 x0 = XEXP (x0, 0);
02748 suffix = "-";
02749 }
02750
02751 if (GET_CODE (x0) == REG && GPR_P (REGNO (x0)))
02752 fprintf (stream, "%s%s", reg_names[REGNO (x0) + offset0], suffix);
02753 else
02754 fatal_insn ("bad insn to d30v_print_operand_memory_reference:", x);
02755 }
02756
02757 fputs (",", stream);
02758
02759 if (!x1)
02760 fputs (reg_names[GPR_R0], stream);
02761
02762 else
02763 {
02764 int offset1 = 0;
02765
02766 switch (GET_CODE (x1))
02767 {
02768 case SUBREG:
02769 offset1 = subreg_regno_offset (REGNO (SUBREG_REG (x1)),
02770 GET_MODE (SUBREG_REG (x1)),
02771 SUBREG_BYTE (x1),
02772 GET_MODE (x1));
02773 x1 = SUBREG_REG (x1);
02774 if (GET_CODE (x1) != REG)
02775 fatal_insn ("bad insn to d30v_print_operand_memory_reference:", x);
02776
02777
02778 case REG:
02779 fputs (reg_names[REGNO (x1) + offset1], stream);
02780 break;
02781
02782 case CONST_INT:
02783 fprintf (stream, "%ld", (long) INTVAL (x1));
02784 break;
02785
02786 case SYMBOL_REF:
02787 case LABEL_REF:
02788 case CONST:
02789 d30v_print_operand_address (stream, x1);
02790 break;
02791
02792 default:
02793 fatal_insn ("bad insn to d30v_print_operand_memory_reference:", x);
02794 }
02795 }
02796
02797 fputs (")", stream);
02798 }
02799
02800
02801
02802
02803
02804
02805
02806
02807
02808
02809
02810
02811
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821
02822
02823
02824
02825
02826
02827
02828
02829
02830
02831
02832
02833
02834
02835
02836
02837
02838
02839
02840
02841 void
02842 d30v_print_operand (stream, x, letter)
02843 FILE *stream;
02844 rtx x;
02845 int letter;
02846 {
02847 enum rtx_code code = (x) ? GET_CODE (x) : NIL;
02848 rtx split_values[2];
02849 REAL_VALUE_TYPE rv;
02850 long num;
02851 int log;
02852
02853 switch (letter)
02854 {
02855 case '.':
02856 fputs (reg_names[GPR_R0], stream);
02857 break;
02858
02859 case 'f':
02860 if (GET_CODE (x) != CONST_DOUBLE)
02861 fatal_insn ("bad insn to d30v_print_operand, 'f' modifier:", x);
02862
02863 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
02864 REAL_VALUE_TO_TARGET_SINGLE (rv, num);
02865 fprintf (stream, "%ld", num);
02866 break;
02867
02868 case 'A':
02869 if (GET_CODE (x) != REG || !ACCUM_P (REGNO (x)))
02870 fatal_insn ("bad insn to d30v_print_operand, 'A' modifier:", x);
02871
02872 putc ('0' + REGNO (x) - ACCUM_FIRST, stream);
02873 break;
02874
02875 case 'M':
02876 if (GET_CODE (x) != MEM)
02877 fatal_insn ("bad insn to d30v_print_operand, 'M' modifier:", x);
02878
02879 d30v_print_operand_memory_reference (stream, XEXP (x, 0));
02880 break;
02881
02882 case 'L':
02883 case 'U':
02884 d30v_split_double (x, &split_values[0], &split_values[1]);
02885 d30v_print_operand (stream, split_values[ letter == 'L' ], '\0');
02886 break;
02887
02888 case ':':
02889 x = current_insn_predicate;
02890 if (x == NULL_RTX)
02891 break;
02892 letter = 'T';
02893
02894
02895 case 'F':
02896 case 'T':
02897
02898
02899
02900 if ((GET_CODE (x) == NE || GET_CODE (x) == EQ)
02901 && GET_MODE (x) == CCmode
02902 && GET_CODE (XEXP (x, 0)) == REG
02903 && (GPR_P (REGNO (XEXP (x, 0))) || BR_FLAG_P (REGNO (XEXP (x, 0))))
02904 && GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) == 0)
02905 {
02906 int true_false = (letter == 'T');
02907
02908 if (GET_CODE (x) == EQ)
02909 true_false = !true_false;
02910
02911 if (REGNO (XEXP (x, 0)) == FLAG_F0)
02912 fprintf (stream, "/%cx", (true_false) ? 'f' : 't');
02913
02914 else if (REGNO (XEXP (x, 0)) == FLAG_F1)
02915 fprintf (stream, "/x%c", (true_false) ? 'f' : 't');
02916
02917 else
02918 fputs ((true_false) ? "tnz" : "tzr", stream);
02919 }
02920
02921 else if (GET_CODE (x) == REG && REGNO (x) == FLAG_F0)
02922 fprintf (stream, "/%cx", (letter == 'T') ? 't' : 'f');
02923
02924 else if (GET_CODE (x) == REG && REGNO (x) == FLAG_F1)
02925 fprintf (stream, "/x%c", (letter == 'T') ? 't' : 'f');
02926
02927 else if (GET_CODE (x) == REG && GPR_P (REGNO (x)))
02928 fputs ((letter == 'T') ? "tnz" : "tzr", stream);
02929
02930 else
02931 fatal_insn ("bad insn to print_operand, 'F' or 'T' modifier:", x);
02932 break;
02933
02934 case 'B':
02935 if (GET_CODE (x) == CONST_INT && (log = exact_log2 (INTVAL (x))) >= 0)
02936 fprintf (stream, "%d", 31 - log);
02937
02938 else if (GET_CODE (x) == CONST_INT && (log = exact_log2 (~ INTVAL (x))) >= 0)
02939 fprintf (stream, "%d", 31 - log);
02940
02941 else
02942 fatal_insn ("bad insn to print_operand, 'B' modifier:", x);
02943 break;
02944
02945 case 'E':
02946 if (GET_CODE (x) == ZERO_EXTEND)
02947 putc ('u', stream);
02948 else if (GET_CODE (x) != SIGN_EXTEND)
02949 fatal_insn ("bad insn to print_operand, 'E' modifier:", x);
02950 break;
02951
02952 case 'R':
02953 switch (GET_CODE (x))
02954 {
02955 case EQ: fputs ("cmpeq", stream); break;
02956 case NE: fputs ("cmpne", stream); break;
02957 case LT: fputs ("cmplt", stream); break;
02958 case LE: fputs ("cmple", stream); break;
02959 case GT: fputs ("cmpgt", stream); break;
02960 case GE: fputs ("cmpge", stream); break;
02961 case LTU: fputs ("cmpult", stream); break;
02962 case LEU: fputs ("cmpule", stream); break;
02963 case GTU: fputs ("cmpugt", stream); break;
02964 case GEU: fputs ("cmpuge", stream); break;
02965
02966 default:
02967 fatal_insn ("bad insn to print_operand, 'R' modifier:", x);
02968 }
02969 break;
02970
02971 case 's':
02972 if (GET_CODE (x) == CONST_INT)
02973 fprintf (stream, "%d", (int) (32 - INTVAL (x)));
02974
02975 else
02976 fatal_insn ("bad insn to print_operand, 's' modifier:", x);
02977 break;
02978
02979 case 'S':
02980 if (GET_CODE (x) == CONST_INT)
02981 fprintf (stream, "%d", (int)(INTVAL (x) - 32));
02982
02983 else
02984 fatal_insn ("bad insn to print_operand, 's' modifier:", x);
02985 break;
02986
02987
02988 case 'z':
02989 if ((GET_CODE (x) == CONST_INT && INTVAL (x) == 0)
02990 || (GET_CODE (x) == CONST_DOUBLE && CONST_DOUBLE_LOW (x) == 0
02991 && CONST_DOUBLE_HIGH (x) == 0))
02992 {
02993 fputs (reg_names[GPR_FIRST], stream);
02994 return;
02995 }
02996
02997
02998
02999 case '\0':
03000 if (code == REG)
03001 fputs (reg_names[ REGNO (x) ], stream);
03002
03003 else if (code == CONST_INT)
03004 fprintf (stream, "%d", (int)INTVAL (x));
03005
03006 else if (code == MEM)
03007 d30v_print_operand_address (stream, XEXP (x, 0));
03008
03009 else if (CONSTANT_ADDRESS_P (x))
03010 d30v_print_operand_address (stream, x);
03011
03012 else
03013 fatal_insn ("bad insn in d30v_print_operand, 0 case", x);
03014
03015 return;
03016
03017 default:
03018 {
03019 char buf[80];
03020
03021 sprintf (buf, "invalid asm template character '%%%c'", letter);
03022 fatal_insn (buf, x);
03023 }
03024 }
03025 }
03026
03027
03028
03029
03030 int
03031 d30v_trampoline_size ()
03032 {
03033 return 16;
03034 }
03035
03036
03037
03038
03039 static void
03040 d30v_build_long_insn (high_bits, low_bits, imm, mem)
03041 HOST_WIDE_INT high_bits;
03042 HOST_WIDE_INT low_bits;
03043 rtx imm;
03044 rtx mem;
03045 {
03046 rtx reg = gen_reg_rtx (DImode);
03047 rtx high_word = gen_highpart (SImode, reg);
03048 rtx low_word = gen_lowpart (SImode, reg);
03049 rtx tmp1 = gen_reg_rtx (SImode);
03050 rtx tmp2 = gen_reg_rtx (SImode);
03051 rtx tmp3 = gen_reg_rtx (SImode);
03052 rtx tmp4 = gen_reg_rtx (SImode);
03053 rtx tmp5 = gen_reg_rtx (SImode);
03054 rtx tmp6 = gen_reg_rtx (SImode);
03055
03056 imm = force_reg (SImode, imm);
03057
03058
03059 emit_insn (gen_lshrsi3 (tmp1, imm, GEN_INT (26)));
03060 emit_insn (gen_andsi3 (tmp2, tmp1, GEN_INT (0x3F)));
03061 emit_insn (gen_iorsi3 (high_word, tmp2, GEN_INT (high_bits)));
03062
03063
03064 emit_insn (gen_andsi3 (tmp3, imm, GEN_INT (0x03FC0000)));
03065 emit_insn (gen_ashlsi3 (tmp4, tmp3, GEN_INT (2)));
03066
03067
03068 emit_insn (gen_andsi3 (tmp5, imm, GEN_INT (0x0003FFFF)));
03069 emit_insn (gen_iorsi3 (tmp6, tmp4, tmp5));
03070 emit_insn (gen_iorsi3 (low_word, tmp6, GEN_INT (low_bits)));
03071
03072
03073 emit_insn (gen_movdi (mem, reg));
03074 }
03075
03076
03077
03078
03079
03080
03081
03082 void
03083 d30v_initialize_trampoline (addr, fnaddr, static_chain)
03084 rtx addr;
03085 rtx fnaddr;
03086 rtx static_chain;
03087 {
03088
03089
03090
03091
03092 d30v_build_long_insn (0x83A80000 | ((STATIC_CHAIN_REGNUM - GPR_FIRST) << 12),
03093 0x80000000, static_chain,
03094 gen_rtx (MEM, DImode, addr));
03095
03096 d30v_build_long_insn (0x80180000, 0x80000000, fnaddr,
03097 gen_rtx (MEM, DImode, plus_constant (addr, 8)));
03098 }
03099
03100
03101
03102
03103
03104
03105
03106
03107
03108
03109
03110
03111
03112
03113
03114
03115
03116
03117
03118
03119
03120
03121
03122
03123
03124
03125
03126
03127
03128
03129
03130
03131
03132
03133
03134
03135
03136
03137
03138
03139
03140
03141
03142
03143
03144
03145
03146
03147
03148
03149
03150
03151
03152
03153
03154
03155
03156
03157
03158
03159
03160
03161
03162 #define XREGNO_OK_FOR_BASE_P(REGNO, STRICT_P) \
03163 ((STRICT_P) \
03164 ? REGNO_OK_FOR_BASE_P (REGNO) \
03165 : GPR_OR_PSEUDO_P (REGNO))
03166
03167 int
03168 d30v_legitimate_address_p (mode, x, strict_p)
03169 enum machine_mode mode;
03170 rtx x;
03171 int strict_p;
03172 {
03173 rtx x0, x1;
03174 int ret = 0;
03175
03176 switch (GET_CODE (x))
03177 {
03178 default:
03179 break;
03180
03181 case SUBREG:
03182 x = SUBREG_REG (x);
03183 if (GET_CODE (x) != REG)
03184 break;
03185
03186
03187
03188 case REG:
03189 ret = XREGNO_OK_FOR_BASE_P (REGNO (x), strict_p);
03190 break;
03191
03192 case PLUS:
03193 x0 = XEXP (x, 0);
03194 x1 = XEXP (x, 1);
03195
03196 if (GET_CODE (x0) == SUBREG)
03197 x0 = SUBREG_REG (x0);
03198
03199 if (GET_CODE (x0) == POST_INC || GET_CODE (x0) == POST_DEC)
03200 x0 = XEXP (x0, 0);
03201
03202 if (GET_CODE (x0) != REG || !XREGNO_OK_FOR_BASE_P (REGNO (x0), strict_p))
03203 break;
03204
03205 switch (GET_CODE (x1))
03206 {
03207 default:
03208 break;
03209
03210 case SUBREG:
03211 x1 = SUBREG_REG (x1);
03212 if (GET_CODE (x1) != REG)
03213 break;
03214
03215
03216
03217 case REG:
03218 ret = XREGNO_OK_FOR_BASE_P (REGNO (x1), strict_p);
03219 break;
03220
03221 case CONST_INT:
03222 ret = (IN_RANGE_P (INTVAL (x1), -32, 31)) ? 1 : 2;
03223 break;
03224
03225 case SYMBOL_REF:
03226 case LABEL_REF:
03227 case CONST:
03228 ret = 2;
03229 break;
03230 }
03231 break;
03232
03233 case CONST_INT:
03234 ret = (IN_RANGE_P (INTVAL (x), -32, 31)) ? 1 : 2;
03235 break;
03236
03237 case SYMBOL_REF:
03238 case LABEL_REF:
03239 case CONST:
03240 ret = 2;
03241 break;
03242
03243 case POST_INC:
03244 case POST_DEC:
03245 x0 = XEXP (x, 0);
03246 if (GET_CODE (x0) == REG && XREGNO_OK_FOR_BASE_P (REGNO (x0), strict_p))
03247 ret = 1;
03248 break;
03249 }
03250
03251 if (TARGET_DEBUG_ADDR)
03252 {
03253 fprintf (stderr, "\n========== GO_IF_LEGITIMATE_ADDRESS, mode = %s, result = %d, addresses are %sstrict\n",
03254 GET_MODE_NAME (mode), ret, (strict_p) ? "" : "not ");
03255 debug_rtx (x);
03256 }
03257
03258 return ret;
03259 }
03260
03261
03262
03263
03264
03265
03266
03267
03268
03269
03270
03271
03272
03273
03274
03275
03276
03277
03278
03279
03280
03281
03282 rtx
03283 d30v_legitimize_address (x, oldx, mode, strict_p)
03284 rtx x;
03285 rtx oldx ATTRIBUTE_UNUSED;
03286 enum machine_mode mode ATTRIBUTE_UNUSED;
03287 int strict_p ATTRIBUTE_UNUSED;
03288 {
03289 rtx ret = NULL_RTX;
03290
03291 if (TARGET_DEBUG_ADDR)
03292 {
03293 if (ret)
03294 {
03295 fprintf (stderr, "\n========== LEGITIMIZE_ADDRESS, transformed:\n");
03296 debug_rtx (x);
03297 fprintf (stderr, "\ninto:\n");
03298 debug_rtx (ret);
03299 }
03300 else
03301 {
03302 fprintf (stderr, "\n========== LEGITIMIZE_ADDRESS, did nothing with:\n");
03303 debug_rtx (x);
03304 }
03305 }
03306
03307 return ret;
03308 }
03309
03310
03311
03312
03313
03314
03315
03316
03317
03318
03319
03320
03321
03322
03323 int
03324 d30v_mode_dependent_address_p (addr)
03325 rtx addr;
03326 {
03327 switch (GET_CODE (addr))
03328 {
03329 default:
03330 break;
03331
03332 case POST_INC:
03333 case POST_DEC:
03334 return TRUE;
03335 }
03336
03337 return FALSE;
03338 }
03339
03340
03341
03342
03343 rtx
03344 d30v_emit_comparison (test_int, result, arg1, arg2)
03345 int test_int;
03346 rtx result;
03347 rtx arg1;
03348 rtx arg2;
03349 {
03350 enum rtx_code test = (enum rtx_code) test_int;
03351 enum machine_mode mode = GET_MODE (arg1);
03352 rtx rtx_test = gen_rtx (SET, VOIDmode, result, gen_rtx (test, CCmode, arg1, arg2));
03353
03354 if (mode == SImode
03355 || (mode == DImode && (test == EQ || test == NE))
03356 || (mode == DImode && (test == LT || test == GE)
03357 && GET_CODE (arg2) == CONST_INT && INTVAL (arg2) == 0))
03358 return rtx_test;
03359
03360 else if (mode == DImode)
03361 return gen_rtx (PARALLEL, VOIDmode,
03362 gen_rtvec (2,
03363 rtx_test,
03364 gen_rtx (CLOBBER, VOIDmode,
03365 gen_reg_rtx (CCmode))));
03366
03367 else
03368 fatal_insn ("d30v_emit_comparison", rtx_test);
03369 }
03370
03371
03372
03373
03374
03375 const char *
03376 d30v_move_2words (operands, insn)
03377 rtx operands[];
03378 rtx insn;
03379 {
03380 if (GET_CODE (operands[0]) == REG && GPR_P (REGNO (operands[0])))
03381 {
03382 if (GET_CODE (operands[1]) == REG && GPR_P (REGNO (operands[1])))
03383 return "or %U0,%.,%U1\n\tor %L0,%.,%L1";
03384
03385 else if (GET_CODE (operands[1]) == REG && ACCUM_P (REGNO (operands[1])))
03386 return "mvfacc %L0,%1,%.\n\tmvfacc %U0,%1,32";
03387
03388 else if (GET_CODE (operands[1]) == MEM)
03389 return "ld2w %0,%M1";
03390
03391 else if (GET_CODE (operands[1]) == CONST_INT
03392 || GET_CODE (operands[1]) == CONST_DOUBLE)
03393 return "or %U0,%.,%U1\n\tor %L0,%.,%L1";
03394 }
03395
03396 else if (GET_CODE (operands[0]) == REG && ACCUM_P (REGNO (operands[0])))
03397 {
03398 if (GET_CODE (operands[1]) == REG
03399 && GPR_P (REGNO (operands[1])))
03400 return "mvtacc %0,%U1,%L1";
03401
03402 if (GET_CODE (operands[1]) == CONST_INT
03403 && INTVAL (operands[1]) == 0)
03404 return "mvtacc %0,%.,%.";
03405 }
03406
03407 else if (GET_CODE (operands[0]) == MEM
03408 && GET_CODE (operands[1]) == REG
03409 && GPR_P (REGNO (operands[1])))
03410 return "st2w %1,%M0";
03411
03412 fatal_insn ("bad call to d30v_move_2words", insn);
03413 }
03414
03415
03416
03417
03418
03419 int
03420 d30v_emit_cond_move (dest, test, true_value, false_value)
03421 rtx dest;
03422 rtx test;
03423 rtx true_value;
03424 rtx false_value;
03425 {
03426 rtx br_reg;
03427 enum machine_mode mode = GET_MODE (dest);
03428 int two_mem_moves_p = FALSE;
03429
03430 if (GET_CODE (dest) == MEM)
03431 {
03432 if (!reg_or_0_operand (true_value, mode))
03433 return FALSE;
03434
03435 if (rtx_equal_p (dest, false_value))
03436 two_mem_moves_p = TRUE;
03437
03438 else if (!reg_or_0_operand (false_value, mode))
03439 return FALSE;
03440 }
03441
03442
03443
03444
03445 br_reg = gen_reg_rtx (CCmode);
03446 emit_insn (d30v_emit_comparison (GET_CODE (test), br_reg,
03447 d30v_compare_op0, d30v_compare_op1));
03448
03449 if (!two_mem_moves_p)
03450 emit_insn (gen_rtx_SET (VOIDmode,
03451 dest,
03452 gen_rtx_IF_THEN_ELSE (mode,
03453 gen_rtx_NE (CCmode, br_reg,
03454 const0_rtx),
03455 true_value,
03456 false_value)));
03457 else
03458 {
03459
03460
03461
03462 emit_insn (gen_rtx_SET (VOIDmode,
03463 dest,
03464 gen_rtx_IF_THEN_ELSE (mode,
03465 gen_rtx_NE (CCmode, br_reg,
03466 const0_rtx),
03467 true_value,
03468 dest)));
03469
03470 emit_insn (gen_rtx_SET (VOIDmode,
03471 dest,
03472 gen_rtx_IF_THEN_ELSE (mode,
03473 gen_rtx_EQ (CCmode, br_reg,
03474 const0_rtx),
03475 false_value,
03476 dest)));
03477
03478 }
03479
03480 return TRUE;
03481 }
03482
03483
03484
03485
03486
03487
03488
03489 void
03490 d30v_machine_dependent_reorg (insn)
03491 rtx insn ATTRIBUTE_UNUSED;
03492 {
03493 }
03494
03495
03496
03497
03498
03499
03500
03501
03502
03503
03504
03505 static int
03506 d30v_adjust_cost (insn, link, dep_insn, cost)
03507 rtx insn;
03508 rtx link ATTRIBUTE_UNUSED;
03509 rtx dep_insn;
03510 int cost;
03511 {
03512 rtx set_dep = single_set (dep_insn);
03513 rtx set_insn = single_set (insn);
03514
03515 if (set_dep != NULL_RTX && set_insn != NULL_RTX
03516 && GET_CODE (SET_DEST (set_dep)) == REG)
03517 {
03518 rtx reg = SET_DEST (set_dep);
03519 rtx mem;
03520
03521 if ((GET_CODE (mem = SET_SRC (set_insn)) == MEM
03522 && reg_mentioned_p (reg, XEXP (mem, 0)))
03523 || (GET_CODE (mem = SET_DEST (set_insn)) == MEM
03524 && reg_mentioned_p (reg, XEXP (mem, 0))))
03525 {
03526 return cost + 2;
03527 }
03528 }
03529
03530 return cost;
03531 }
03532
03533
03534
03535
03536 static int
03537 d30v_issue_rate ()
03538 {
03539 return 2;
03540 }
03541
03542
03543
03544
03545
03546 static void
03547 d30v_init_machine_status (p)
03548 struct function *p;
03549 {
03550 p->machine =
03551 (machine_function *) xcalloc (1, sizeof (machine_function));
03552 }
03553
03554 static void
03555 d30v_mark_machine_status (p)
03556 struct function * p;
03557 {
03558 if (p->machine == NULL)
03559 return;
03560
03561 ggc_mark_rtx (p->machine->eh_epilogue_sp_ofs);
03562 }
03563
03564 static void
03565 d30v_free_machine_status (p)
03566 struct function *p;
03567 {
03568 struct machine_function *machine = p->machine;
03569
03570 if (machine == NULL)
03571 return;
03572
03573 free (machine);
03574 p->machine = NULL;
03575 }
03576
03577
03578
03579 void
03580 d30v_init_expanders ()
03581 {
03582
03583 init_machine_status = d30v_init_machine_status;
03584 mark_machine_status = d30v_mark_machine_status;
03585 free_machine_status = d30v_free_machine_status;
03586 }
03587
03588
03589
03590
03591
03592
03593
03594
03595 rtx
03596 d30v_return_addr ()
03597 {
03598 return get_hard_reg_initial_val (Pmode, GPR_LINK);
03599 }
03600
03601
03602
03603
03604 static void
03605 d30v_add_gc_roots ()
03606 {
03607 ggc_add_rtx_root (&d30v_compare_op0, 1);
03608 ggc_add_rtx_root (&d30v_compare_op1, 1);
03609 }