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 "rtl.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 "tree.h"
00034 #include "expr.h"
00035 #include "function.h"
00036 #include "flags.h"
00037 #include "ggc.h"
00038 #include "toplev.h"
00039 #include "recog.h"
00040 #include "tm_p.h"
00041 #include "target.h"
00042 #include "target-def.h"
00043
00044 const char *text_seg_name;
00045 const char *rsect_text;
00046 const char *data_seg_name;
00047 const char *rsect_data;
00048 const char *bss_seg_name;
00049 const char *rsect_bss;
00050 const char *const_seg_name;
00051 const char *rsect_const;
00052
00053 const char *chip_name;
00054 const char *save_chip_name;
00055
00056
00057
00058
00059 rtx dsp16xx_compare_op0;
00060 rtx dsp16xx_compare_op1;
00061 rtx (*dsp16xx_compare_gen) PARAMS (());
00062
00063 static const char *fp;
00064 static const char *sp;
00065 static const char *rr;
00066 static const char *a1h;
00067
00068 struct dsp16xx_frame_info current_frame_info;
00069 struct dsp16xx_frame_info zero_frame_info;
00070
00071 rtx dsp16xx_addhf3_libcall = (rtx) 0;
00072 rtx dsp16xx_subhf3_libcall = (rtx) 0;
00073 rtx dsp16xx_mulhf3_libcall = (rtx) 0;
00074 rtx dsp16xx_divhf3_libcall = (rtx) 0;
00075 rtx dsp16xx_cmphf3_libcall = (rtx) 0;
00076 rtx dsp16xx_fixhfhi2_libcall = (rtx) 0;
00077 rtx dsp16xx_floathihf2_libcall = (rtx) 0;
00078 rtx dsp16xx_neghf2_libcall = (rtx) 0;
00079
00080 rtx dsp16xx_mulhi3_libcall = (rtx) 0;
00081 rtx dsp16xx_udivqi3_libcall = (rtx) 0;
00082 rtx dsp16xx_udivhi3_libcall = (rtx) 0;
00083 rtx dsp16xx_divqi3_libcall = (rtx) 0;
00084 rtx dsp16xx_divhi3_libcall = (rtx) 0;
00085 rtx dsp16xx_modqi3_libcall = (rtx) 0;
00086 rtx dsp16xx_modhi3_libcall = (rtx) 0;
00087 rtx dsp16xx_umodqi3_libcall = (rtx) 0;
00088 rtx dsp16xx_umodhi3_libcall = (rtx) 0;
00089 rtx dsp16xx_ashrhi3_libcall = (rtx) 0;
00090 rtx dsp16xx_ashlhi3_libcall = (rtx) 0;
00091 rtx dsp16xx_ucmphi2_libcall = (rtx) 0;
00092 rtx dsp16xx_lshrhi3_libcall = (rtx) 0;
00093
00094 static const char *const himode_reg_name[] = HIMODE_REGISTER_NAMES;
00095
00096 #define SHIFT_INDEX_1 0
00097 #define SHIFT_INDEX_4 1
00098 #define SHIFT_INDEX_8 2
00099 #define SHIFT_INDEX_16 3
00100
00101 static const char *const ashift_right_asm[] =
00102 {
00103 "%0=%0>>1",
00104 "%0=%0>>4",
00105 "%0=%0>>8",
00106 "%0=%0>>16"
00107 };
00108
00109 static const char *const ashift_right_asm_first[] =
00110 {
00111 "%0=%1>>1",
00112 "%0=%1>>4",
00113 "%0=%1>>8",
00114 "%0=%1>>16"
00115 };
00116
00117 static const char *const ashift_left_asm[] =
00118 {
00119 "%0=%0<<1",
00120 "%0=%0<<4",
00121 "%0=%0<<8",
00122 "%0=%0<<16"
00123 };
00124
00125 static const char *const ashift_left_asm_first[] =
00126 {
00127 "%0=%1<<1",
00128 "%0=%1<<4",
00129 "%0=%1<<8",
00130 "%0=%1<<16"
00131 };
00132
00133 static const char *const lshift_right_asm[] =
00134 {
00135 "%0=%0>>1\n\t%0=%b0&0x7fff",
00136 "%0=%0>>4\n\t%0=%b0&0x0fff",
00137 "%0=%0>>8\n\t%0=%b0&0x00ff",
00138 "%0=%0>>16\n\t%0=%b0&0x0000"
00139 };
00140
00141 static const char *const lshift_right_asm_first[] =
00142 {
00143 "%0=%1>>1\n\t%0=%b0&0x7fff",
00144 "%0=%1>>4\n\t%0=%b0&0x0fff",
00145 "%0=%1>>8\n\t%0=%b0&0x00ff",
00146 "%0=%1>>16\n\t%0=%b0&0x0000"
00147 };
00148
00149 static int reg_save_size PARAMS ((void));
00150 static void dsp16xx_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
00151 static void dsp16xx_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
00152
00153
00154 #undef TARGET_ASM_BYTE_OP
00155 #define TARGET_ASM_BYTE_OP "\tint\t"
00156 #undef TARGET_ASM_ALIGNED_HI_OP
00157 #define TARGET_ASM_ALIGNED_HI_OP NULL
00158 #undef TARGET_ASM_ALIGNED_SI_OP
00159 #define TARGET_ASM_ALIGNED_SI_OP NULL
00160
00161 #undef TARGET_ASM_FUNCTION_PROLOGUE
00162 #define TARGET_ASM_FUNCTION_PROLOGUE dsp16xx_output_function_prologue
00163 #undef TARGET_ASM_FUNCTION_EPILOGUE
00164 #define TARGET_ASM_FUNCTION_EPILOGUE dsp16xx_output_function_epilogue
00165
00166 struct gcc_target targetm = TARGET_INITIALIZER;
00167
00168 int
00169 hard_regno_mode_ok (regno, mode)
00170 int regno;
00171 enum machine_mode mode;
00172 {
00173 switch ((int) mode)
00174 {
00175 case VOIDmode:
00176 return 1;
00177
00178
00179
00180
00181 case QImode:
00182 if (regno != REG_C0 && regno != REG_C1 && regno != REG_C2)
00183 return 1;
00184 else
00185 return 0;
00186
00187
00188
00189
00190
00191 case HFmode:
00192 case SFmode:
00193 case DFmode:
00194 case XFmode:
00195 case HImode:
00196 case SImode:
00197 case DImode:
00198 if (regno == REG_A0 || regno == REG_A1 || regno == REG_Y || regno == REG_PROD
00199 || (IS_YBASE_REGISTER_WINDOW(regno) && ((regno & 1) == 0)))
00200 return 1;
00201 else
00202 return 0;
00203
00204 default:
00205 return 0;
00206 }
00207 }
00208
00209 enum reg_class
00210 dsp16xx_reg_class_from_letter (c)
00211 int c;
00212 {
00213 switch (c)
00214 {
00215 case 'A':
00216 return ACCUM_REGS;
00217
00218 case 'l':
00219 return A0_REG;
00220
00221 case 'C':
00222 return A1_REG;
00223
00224 case 'h':
00225 return ACCUM_HIGH_REGS;
00226
00227 case 'j':
00228 return A0H_REG;
00229
00230 case 'k':
00231 return A0L_REG;
00232
00233 case 'q':
00234 return A1H_REG;
00235
00236 case 'u':
00237 return A1L_REG;
00238
00239 case 'x':
00240 return X_REG;
00241
00242 case 'y':
00243 return YH_REG;
00244
00245 case 'z':
00246 return YL_REG;
00247
00248 case 't':
00249 return P_REG;
00250
00251 case 'Z':
00252 return Y_OR_P_REGS;
00253
00254 case 'd':
00255 return ACCUM_Y_OR_P_REGS;
00256
00257 case 'a':
00258 return Y_ADDR_REGS;
00259
00260 case 'B':
00261 return (TARGET_BMU ? BMU_REGS : NO_REGS);
00262
00263 case 'Y':
00264 return YBASE_VIRT_REGS;
00265
00266 case 'v':
00267 return PH_REG;
00268
00269 case 'w':
00270 return PL_REG;
00271
00272 case 'W':
00273 return J_REG;
00274
00275 case 'e':
00276 return YBASE_ELIGIBLE_REGS;
00277
00278 case 'b':
00279 return ACCUM_LOW_REGS;
00280
00281 case 'c':
00282 return NON_YBASE_REGS;
00283
00284 case 'f':
00285 return Y_REG;
00286
00287 case 'D':
00288 return SLOW_MEM_LOAD_REGS;
00289
00290 default:
00291 return NO_REGS;
00292 }
00293 }
00294
00295
00296
00297
00298 int
00299 regno_reg_class(regno)
00300 int regno;
00301 {
00302 switch (regno)
00303 {
00304 case REG_A0L:
00305 return (int) A0L_REG;
00306 case REG_A1L:
00307 return (int) A1L_REG;
00308
00309 case REG_A0:
00310 return (int) A0H_REG;
00311 case REG_A1:
00312 return (int) A1H_REG;
00313
00314 case REG_X:
00315 return (int) X_REG;
00316
00317 case REG_Y:
00318 return (int) YH_REG;
00319 case REG_YL:
00320 return (int) YL_REG;
00321
00322 case REG_PROD:
00323 return (int) PH_REG;
00324 case REG_PRODL:
00325 return (int) PL_REG;
00326
00327 case REG_R0: case REG_R1: case REG_R2: case REG_R3:
00328 return (int) Y_ADDR_REGS;
00329
00330 case REG_J:
00331 return (int) J_REG;
00332 case REG_K:
00333 return (int) GENERAL_REGS;
00334
00335 case REG_YBASE:
00336 return (int) GENERAL_REGS;
00337
00338 case REG_PT:
00339 return (int) GENERAL_REGS;
00340
00341 case REG_AR0: case REG_AR1: case REG_AR2: case REG_AR3:
00342 return (int) BMU_REGS;
00343
00344 case REG_C0: case REG_C1: case REG_C2:
00345 return (int) GENERAL_REGS;
00346
00347 case REG_PR:
00348 return (int) GENERAL_REGS;
00349
00350 case REG_RB:
00351 return (int) GENERAL_REGS;
00352
00353 case REG_YBASE0: case REG_YBASE1: case REG_YBASE2: case REG_YBASE3:
00354 case REG_YBASE4: case REG_YBASE5: case REG_YBASE6: case REG_YBASE7:
00355 case REG_YBASE8: case REG_YBASE9: case REG_YBASE10: case REG_YBASE11:
00356 case REG_YBASE12: case REG_YBASE13: case REG_YBASE14: case REG_YBASE15:
00357 case REG_YBASE16: case REG_YBASE17: case REG_YBASE18: case REG_YBASE19:
00358 case REG_YBASE20: case REG_YBASE21: case REG_YBASE22: case REG_YBASE23:
00359 case REG_YBASE24: case REG_YBASE25: case REG_YBASE26: case REG_YBASE27:
00360 case REG_YBASE28: case REG_YBASE29: case REG_YBASE30: case REG_YBASE31:
00361 return (int) YBASE_VIRT_REGS;
00362
00363 default:
00364 return (int) NO_REGS;
00365 }
00366 }
00367
00368
00369
00370
00371 int
00372 class_max_nregs(class, mode)
00373 enum reg_class class ATTRIBUTE_UNUSED;
00374 enum machine_mode mode;
00375 {
00376 return (GET_MODE_SIZE(mode));
00377 }
00378
00379 enum reg_class
00380 limit_reload_class (mode, class)
00381 enum machine_mode mode ATTRIBUTE_UNUSED;
00382 enum reg_class class;
00383 {
00384 return class;
00385 }
00386
00387 int
00388 dsp16xx_register_move_cost (from, to)
00389 enum reg_class from, to;
00390 {
00391 if (from == A0H_REG || from == A0L_REG || from == A0_REG ||
00392 from == A1H_REG || from == ACCUM_HIGH_REGS || from == A1L_REG ||
00393 from == ACCUM_LOW_REGS || from == A1_REG || from == ACCUM_REGS)
00394 {
00395 if (to == Y_REG || to == P_REG)
00396 return 4;
00397 else
00398 return 2;
00399 }
00400
00401 if (to == A0H_REG || to == A0L_REG || to == A0_REG ||
00402 to == A1H_REG || to == ACCUM_HIGH_REGS || to == A1L_REG ||
00403 to == ACCUM_LOW_REGS || to == A1_REG || to == ACCUM_REGS)
00404 {
00405 return 2;
00406 }
00407
00408 if (from == YBASE_VIRT_REGS)
00409 {
00410 if (to == YBASE_VIRT_REGS)
00411 return 16;
00412
00413 if (to == X_REG || to == YH_REG || to == YL_REG ||
00414 to == Y_REG || to == PL_REG || to == PH_REG ||
00415 to == P_REG || to == Y_ADDR_REGS || to == YBASE_ELIGIBLE_REGS ||
00416 to == Y_OR_P_REGS)
00417 {
00418 return 8;
00419 }
00420 else
00421 return 10;
00422 }
00423
00424 if (to == YBASE_VIRT_REGS)
00425 {
00426 if (from == X_REG || from == YH_REG || from == YL_REG ||
00427 from == Y_REG || from == PL_REG || from == PH_REG ||
00428 from == P_REG || from == Y_ADDR_REGS || from == YBASE_ELIGIBLE_REGS ||
00429 from == Y_OR_P_REGS)
00430 {
00431 return 8;
00432 }
00433 else
00434 return 10;
00435 }
00436
00437 return 8;
00438 }
00439
00440
00441
00442
00443
00444
00445
00446
00447 enum reg_class
00448 preferred_reload_class (x, class)
00449 rtx x;
00450 enum reg_class class;
00451 {
00452
00453
00454
00455 if (CONSTANT_P (x))
00456 {
00457 switch ((int) class)
00458 {
00459 case YBASE_VIRT_REGS:
00460 return (!reload_in_progress ? NO_REGS : class);
00461
00462 case ACCUM_LOW_OR_YBASE_REGS:
00463 return ACCUM_LOW_REGS;
00464
00465 case ACCUM_OR_YBASE_REGS:
00466 return ACCUM_REGS;
00467
00468 case X_OR_YBASE_REGS:
00469 return X_REG;
00470
00471 case Y_OR_YBASE_REGS:
00472 return Y_REG;
00473
00474 case ACCUM_LOW_YL_PL_OR_YBASE_REGS:
00475 return YL_OR_PL_OR_ACCUM_LOW_REGS;
00476
00477 case P_OR_YBASE_REGS:
00478 return P_REG;
00479
00480 case ACCUM_Y_P_OR_YBASE_REGS:
00481 return ACCUM_Y_OR_P_REGS;
00482
00483 case Y_ADDR_OR_YBASE_REGS:
00484 return Y_ADDR_REGS;
00485
00486 case YBASE_OR_NOHIGH_YBASE_ELIGIBLE_REGS:
00487 return NON_HIGH_YBASE_ELIGIBLE_REGS;;
00488
00489 case YBASE_OR_YBASE_ELIGIBLE_REGS:
00490 return YBASE_ELIGIBLE_REGS;
00491
00492 case NO_HIGH_ALL_REGS:
00493 return NOHIGH_NON_YBASE_REGS;
00494
00495 case ALL_REGS:
00496 return NON_YBASE_REGS;
00497
00498 default:
00499 return class;
00500 }
00501 }
00502
00503
00504
00505
00506 if (REG_P (x) && !IS_ACCUM_REG (REGNO (x)) && !IS_YBASE_REGISTER_WINDOW (REGNO (x)))
00507 {
00508 switch ((int) class)
00509 {
00510 case NO_REGS:
00511 case A0H_REG: case A0L_REG: case A0_REG: case A1H_REG:
00512 case ACCUM_HIGH_REGS: case A1L_REG: case ACCUM_LOW_REGS:
00513 case A1_REG: case ACCUM_REGS:
00514 return class;
00515
00516 case X_REG:
00517 return (!reload_in_progress ? NO_REGS : class);
00518
00519 case X_OR_ACCUM_LOW_REGS:
00520 return ACCUM_LOW_REGS;
00521
00522 case X_OR_ACCUM_REGS:
00523 return ACCUM_REGS;
00524
00525 case YH_REG:
00526 return (!reload_in_progress ? NO_REGS : class);
00527
00528 case YH_OR_ACCUM_HIGH_REGS:
00529 return ACCUM_HIGH_REGS;
00530
00531 case X_OR_YH_REGS:
00532 case YL_REG:
00533 return (!reload_in_progress ? NO_REGS : class);
00534
00535 case YL_OR_ACCUM_LOW_REGS:
00536 return ACCUM_LOW_REGS;
00537
00538 case X_OR_YL_REGS:
00539 case X_OR_Y_REGS: case Y_REG:
00540 return (!reload_in_progress ? NO_REGS : class);
00541
00542 case ACCUM_OR_Y_REGS:
00543 return ACCUM_REGS;
00544
00545 case PH_REG:
00546 case X_OR_PH_REGS: case PL_REG:
00547 return (!reload_in_progress ? NO_REGS : class);
00548
00549 case PL_OR_ACCUM_LOW_REGS:
00550 return ACCUM_LOW_REGS;
00551
00552 case X_OR_PL_REGS:
00553 return (!reload_in_progress ? NO_REGS : class);
00554
00555 case YL_OR_PL_OR_ACCUM_LOW_REGS:
00556 return ACCUM_LOW_REGS;
00557
00558 case P_REG:
00559 return (!reload_in_progress ? NO_REGS : class);
00560
00561 case ACCUM_OR_P_REGS:
00562 return ACCUM_REGS;
00563
00564 case YL_OR_P_REGS:
00565 return (!reload_in_progress ? NO_REGS : class);
00566
00567 case ACCUM_LOW_OR_YL_OR_P_REGS:
00568 return ACCUM_LOW_REGS;
00569
00570 case Y_OR_P_REGS:
00571 return (!reload_in_progress ? NO_REGS : class);
00572
00573 case ACCUM_Y_OR_P_REGS:
00574 return ACCUM_REGS;
00575
00576 case NO_FRAME_Y_ADDR_REGS:
00577 case Y_ADDR_REGS:
00578 return (!reload_in_progress ? NO_REGS : class);
00579
00580 case ACCUM_LOW_OR_Y_ADDR_REGS:
00581 return ACCUM_LOW_REGS;
00582
00583 case ACCUM_OR_Y_ADDR_REGS:
00584 return ACCUM_REGS;
00585
00586 case X_OR_Y_ADDR_REGS:
00587 case Y_OR_Y_ADDR_REGS:
00588 case P_OR_Y_ADDR_REGS:
00589 return (!reload_in_progress ? NO_REGS : class);
00590
00591 case NON_HIGH_YBASE_ELIGIBLE_REGS:
00592 return ACCUM_LOW_REGS;
00593
00594 case YBASE_ELIGIBLE_REGS:
00595 return ACCUM_REGS;
00596
00597 case J_REG:
00598 case J_OR_DAU_16_BIT_REGS:
00599 case BMU_REGS:
00600 return (!reload_in_progress ? NO_REGS : class);
00601
00602 case YBASE_VIRT_REGS:
00603 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
00604 return class;
00605 else
00606 return (!reload_in_progress ? NO_REGS : class);
00607
00608 case ACCUM_LOW_OR_YBASE_REGS:
00609 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
00610 return class;
00611 else
00612 return ACCUM_LOW_REGS;
00613
00614 case ACCUM_OR_YBASE_REGS:
00615 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
00616 return class;
00617 else
00618 return ACCUM_REGS;
00619
00620 case X_OR_YBASE_REGS:
00621 case Y_OR_YBASE_REGS:
00622 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
00623 return YBASE_VIRT_REGS;
00624 else
00625 return (!reload_in_progress ? NO_REGS : class);
00626
00627 case ACCUM_LOW_YL_PL_OR_YBASE_REGS:
00628 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
00629 return ACCUM_LOW_OR_YBASE_REGS;
00630 else
00631 return ACCUM_LOW_REGS;
00632
00633 case P_OR_YBASE_REGS:
00634 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
00635 return YBASE_VIRT_REGS;
00636 else
00637 return (!reload_in_progress ? NO_REGS : class);
00638
00639 case ACCUM_Y_P_OR_YBASE_REGS:
00640 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
00641 return ACCUM_OR_YBASE_REGS;
00642 else
00643 return ACCUM_REGS;
00644
00645 case Y_ADDR_OR_YBASE_REGS:
00646 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
00647 return YBASE_VIRT_REGS;
00648 else
00649 return (!reload_in_progress ? NO_REGS : class);
00650
00651 case YBASE_OR_NOHIGH_YBASE_ELIGIBLE_REGS:
00652 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
00653 return ACCUM_LOW_OR_YBASE_REGS;
00654 else
00655 return ACCUM_LOW_REGS;
00656
00657 case YBASE_OR_YBASE_ELIGIBLE_REGS:
00658 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
00659 return ACCUM_OR_YBASE_REGS;
00660 else
00661 return ACCUM_REGS;
00662
00663 case NO_HIGH_ALL_REGS:
00664 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
00665 return ACCUM_LOW_OR_YBASE_REGS;
00666 else
00667 return ACCUM_LOW_REGS;
00668
00669 case ALL_REGS:
00670 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
00671 return ACCUM_OR_YBASE_REGS;
00672 else
00673 return ACCUM_REGS;
00674
00675 case NOHIGH_NON_ADDR_REGS:
00676 return ACCUM_LOW_REGS;
00677
00678 case NON_ADDR_REGS:
00679 case SLOW_MEM_LOAD_REGS:
00680 return ACCUM_REGS;
00681
00682 case NOHIGH_NON_YBASE_REGS:
00683 return ACCUM_LOW_REGS;
00684
00685 case NO_ACCUM_NON_YBASE_REGS:
00686 return (!reload_in_progress ? NO_REGS : class);
00687
00688 case NON_YBASE_REGS:
00689 return ACCUM_REGS;
00690
00691 default:
00692 return class;
00693 }
00694 }
00695
00696
00697
00698
00699 if (REG_P (x) && !TARGET_RESERVE_YBASE
00700 && IS_YBASE_REGISTER_WINDOW (REGNO(x)))
00701 {
00702 switch ((int) class)
00703 {
00704 case NO_REGS:
00705 case A0H_REG: case A0L_REG: case A0_REG: case A1H_REG:
00706 case ACCUM_HIGH_REGS: case A1L_REG: case ACCUM_LOW_REGS:
00707 case A1_REG: case ACCUM_REGS: case X_REG:
00708 case X_OR_ACCUM_LOW_REGS: case X_OR_ACCUM_REGS:
00709 case YH_REG: case YH_OR_ACCUM_HIGH_REGS:
00710 case X_OR_YH_REGS: case YL_REG:
00711 case YL_OR_ACCUM_LOW_REGS: case X_OR_YL_REGS:
00712 case X_OR_Y_REGS: case Y_REG:
00713 case ACCUM_OR_Y_REGS: case PH_REG:
00714 case X_OR_PH_REGS: case PL_REG:
00715 case PL_OR_ACCUM_LOW_REGS: case X_OR_PL_REGS:
00716 case YL_OR_PL_OR_ACCUM_LOW_REGS: case P_REG:
00717 case ACCUM_OR_P_REGS: case YL_OR_P_REGS:
00718 case ACCUM_LOW_OR_YL_OR_P_REGS: case Y_OR_P_REGS:
00719 case ACCUM_Y_OR_P_REGS: case NO_FRAME_Y_ADDR_REGS:
00720 case Y_ADDR_REGS: case ACCUM_LOW_OR_Y_ADDR_REGS:
00721 case ACCUM_OR_Y_ADDR_REGS: case X_OR_Y_ADDR_REGS:
00722 case Y_OR_Y_ADDR_REGS: case P_OR_Y_ADDR_REGS:
00723 case NON_HIGH_YBASE_ELIGIBLE_REGS: case YBASE_ELIGIBLE_REGS:
00724 default:
00725 return class;
00726
00727 case J_REG:
00728 return (!reload_in_progress ? NO_REGS : class);
00729
00730 case J_OR_DAU_16_BIT_REGS:
00731 return ACCUM_HIGH_REGS;
00732
00733 case BMU_REGS:
00734 case YBASE_VIRT_REGS:
00735 return (!reload_in_progress ? NO_REGS : class);
00736
00737 case ACCUM_LOW_OR_YBASE_REGS:
00738 return ACCUM_LOW_REGS;
00739
00740 case ACCUM_OR_YBASE_REGS:
00741 return ACCUM_REGS;
00742
00743 case X_OR_YBASE_REGS:
00744 return X_REG;
00745
00746 case Y_OR_YBASE_REGS:
00747 return Y_REG;
00748
00749 case ACCUM_LOW_YL_PL_OR_YBASE_REGS:
00750 return YL_OR_PL_OR_ACCUM_LOW_REGS;
00751
00752 case P_OR_YBASE_REGS:
00753 return P_REG;
00754
00755 case ACCUM_Y_P_OR_YBASE_REGS:
00756 return ACCUM_Y_OR_P_REGS;
00757
00758 case Y_ADDR_OR_YBASE_REGS:
00759 return Y_ADDR_REGS;
00760
00761 case YBASE_OR_NOHIGH_YBASE_ELIGIBLE_REGS:
00762 return NON_HIGH_YBASE_ELIGIBLE_REGS;
00763
00764 case YBASE_OR_YBASE_ELIGIBLE_REGS:
00765 return YBASE_ELIGIBLE_REGS;
00766
00767 case NO_HIGH_ALL_REGS:
00768 return NON_HIGH_YBASE_ELIGIBLE_REGS;
00769
00770 case ALL_REGS:
00771 return YBASE_ELIGIBLE_REGS;
00772
00773 case NOHIGH_NON_ADDR_REGS:
00774 return ACCUM_LOW_OR_YL_OR_P_REGS;
00775
00776 case NON_ADDR_REGS:
00777 return ACCUM_Y_OR_P_REGS;
00778
00779 case SLOW_MEM_LOAD_REGS:
00780 return ACCUM_OR_Y_ADDR_REGS;
00781
00782 case NOHIGH_NON_YBASE_REGS:
00783 return NON_HIGH_YBASE_ELIGIBLE_REGS;
00784
00785 case NO_ACCUM_NON_YBASE_REGS:
00786 return Y_ADDR_REGS;
00787
00788 case NON_YBASE_REGS:
00789 return YBASE_ELIGIBLE_REGS;
00790 }
00791 }
00792
00793 if (GET_CODE (x) == PLUS)
00794 {
00795 if (GET_MODE (x) == QImode
00796 && REG_P (XEXP (x,0))
00797 && (XEXP (x,0) == frame_pointer_rtx
00798 || XEXP (x,0) == stack_pointer_rtx)
00799 && (GET_CODE (XEXP (x,1)) == CONST_INT))
00800 {
00801 if (class == ACCUM_HIGH_REGS)
00802 return class;
00803
00804
00805
00806 #if 0
00807 if (!reg_class_subset_p (ACCUM_REGS, class))
00808 return (!reload_in_progress ? NO_REGS : class);
00809 #endif
00810 if (reg_class_subset_p (ACCUM_HIGH_REGS, class))
00811 return ACCUM_HIGH_REGS;
00812
00813
00814
00815
00816
00817
00818 else if (class == ACCUM_LOW_REGS)
00819 return A1L_REG;
00820 else if (class == A0L_REG)
00821 return NO_REGS;
00822 else
00823 return class;
00824 }
00825
00826 if (class == NON_YBASE_REGS || class == YBASE_ELIGIBLE_REGS)
00827 return Y_ADDR_REGS;
00828 else
00829 return class;
00830 }
00831 else if (GET_CODE (x) == MEM)
00832 {
00833
00834
00835 if (reg_class_subset_p(YBASE_VIRT_REGS, class))
00836 {
00837 switch ((int) class)
00838 {
00839 case YBASE_VIRT_REGS:
00840 return (!reload_in_progress ? NO_REGS : class);
00841
00842 case ACCUM_LOW_OR_YBASE_REGS:
00843 return ACCUM_LOW_REGS;
00844
00845 case ACCUM_OR_YBASE_REGS:
00846 return ACCUM_REGS;
00847
00848 case X_OR_YBASE_REGS:
00849 return X_REG;
00850
00851 case Y_OR_YBASE_REGS:
00852 return Y_REG;
00853
00854 case ACCUM_LOW_YL_PL_OR_YBASE_REGS:
00855 return YL_OR_PL_OR_ACCUM_LOW_REGS;
00856
00857 case P_OR_YBASE_REGS:
00858 return P_REG;
00859
00860 case ACCUM_Y_P_OR_YBASE_REGS:
00861 return ACCUM_Y_OR_P_REGS;
00862
00863 case Y_ADDR_OR_YBASE_REGS:
00864 return Y_ADDR_REGS;
00865
00866 case YBASE_OR_NOHIGH_YBASE_ELIGIBLE_REGS:
00867 return NON_HIGH_YBASE_ELIGIBLE_REGS;
00868
00869 case YBASE_OR_YBASE_ELIGIBLE_REGS:
00870 return YBASE_ELIGIBLE_REGS;
00871
00872 case NO_HIGH_ALL_REGS:
00873 return NOHIGH_NON_YBASE_REGS;
00874
00875 case ALL_REGS:
00876 return NON_YBASE_REGS;
00877
00878 default:
00879 return class;
00880 }
00881 }
00882 else
00883 return class;
00884 }
00885 else
00886 return class;
00887 }
00888
00889
00890
00891
00892
00893 enum reg_class
00894 secondary_reload_class (class, mode, in)
00895 enum reg_class class;
00896 enum machine_mode mode;
00897 rtx in;
00898 {
00899 int regno = -1;
00900
00901 if (GET_CODE (in) == REG || GET_CODE (in) == SUBREG)
00902 regno = true_regnum (in);
00903
00904
00905
00906
00907
00908 if (class == ACCUM_HIGH_REGS
00909 || class == A1H_REG
00910 || class == A0H_REG)
00911 {
00912 if (GET_CODE (in) == PLUS && mode == QImode)
00913 return ACCUM_LOW_REGS;
00914 }
00915
00916 if (class == ACCUM_HIGH_REGS
00917 || class == ACCUM_LOW_REGS
00918 || class == A1L_REG
00919 || class == A0L_REG
00920 || class == A1H_REG
00921 || class == A0H_REG)
00922 {
00923 if (GET_CODE (in) == PLUS && mode == QImode)
00924 {
00925 rtx addr0 = XEXP (in, 0);
00926 rtx addr1 = XEXP (in, 1);
00927
00928
00929
00930 if (REG_P (addr0) && REG_P (addr1))
00931 return NO_REGS;
00932 }
00933 }
00934
00935
00936
00937
00938 if ((class == ACCUM_REGS || class == ACCUM_HIGH_REGS ||
00939 class == ACCUM_LOW_REGS || class == A0H_REG || class == A0L_REG ||
00940 class == A1H_REG || class == A1_REG) ||
00941 (regno >= REG_A0 && regno < REG_A1L + 1))
00942 return NO_REGS;
00943
00944 if (class == ACCUM_OR_YBASE_REGS && REG_P(in)
00945 && IS_YBASE_ELIGIBLE_REG(regno))
00946 {
00947 return NO_REGS;
00948 }
00949
00950
00951
00952
00953
00954 if (!TARGET_RESERVE_YBASE && IS_YBASE_REGISTER_WINDOW(regno))
00955 {
00956 switch ((int) class)
00957 {
00958 case (int) X_REG:
00959 case (int) X_OR_ACCUM_LOW_REGS:
00960 case (int) X_OR_ACCUM_REGS:
00961 case (int) YH_REG:
00962 case (int) YH_OR_ACCUM_HIGH_REGS:
00963 case (int) X_OR_YH_REGS:
00964 case (int) YL_REG:
00965 case (int) YL_OR_ACCUM_LOW_REGS:
00966 case (int) X_OR_Y_REGS:
00967 case (int) X_OR_YL_REGS:
00968 case (int) Y_REG:
00969 case (int) ACCUM_OR_Y_REGS:
00970 case (int) PH_REG:
00971 case (int) X_OR_PH_REGS:
00972 case (int) PL_REG:
00973 case (int) PL_OR_ACCUM_LOW_REGS:
00974 case (int) X_OR_PL_REGS:
00975 case (int) YL_OR_PL_OR_ACCUM_LOW_REGS:
00976 case (int) P_REG:
00977 case (int) ACCUM_OR_P_REGS:
00978 case (int) YL_OR_P_REGS:
00979 case (int) ACCUM_LOW_OR_YL_OR_P_REGS:
00980 case (int) Y_OR_P_REGS:
00981 case (int) ACCUM_Y_OR_P_REGS:
00982 case (int) Y_ADDR_REGS:
00983 case (int) ACCUM_LOW_OR_Y_ADDR_REGS:
00984 case (int) ACCUM_OR_Y_ADDR_REGS:
00985 case (int) X_OR_Y_ADDR_REGS:
00986 case (int) Y_OR_Y_ADDR_REGS:
00987 case (int) P_OR_Y_ADDR_REGS:
00988 case (int) YBASE_ELIGIBLE_REGS:
00989 return NO_REGS;
00990
00991 default:
00992 return ACCUM_HIGH_REGS;
00993 }
00994 }
00995
00996
00997
00998
00999
01000
01001
01002 if (!TARGET_RESERVE_YBASE && regno != -1)
01003 {
01004 switch (regno)
01005 {
01006 case REG_A0:
01007 case REG_A0L:
01008 case REG_A1:
01009 case REG_A1L:
01010 case REG_X:
01011 case REG_Y:
01012 case REG_YL:
01013 case REG_PROD:
01014 case REG_PRODL:
01015 case REG_R0:
01016 case REG_R1:
01017 case REG_R2:
01018 case REG_R3:
01019 if (class == YBASE_VIRT_REGS)
01020 return NO_REGS;
01021 else
01022 {
01023 switch ((int) class)
01024 {
01025 case (int) X_REG:
01026 case (int) X_OR_ACCUM_LOW_REGS:
01027 case (int) X_OR_ACCUM_REGS:
01028 case (int) YH_REG:
01029 case (int) YH_OR_ACCUM_HIGH_REGS:
01030 case (int) X_OR_YH_REGS:
01031 case (int) YL_REG:
01032 case (int) YL_OR_ACCUM_LOW_REGS:
01033 case (int) X_OR_Y_REGS:
01034 case (int) X_OR_YL_REGS:
01035 case (int) Y_REG:
01036 case (int) ACCUM_OR_Y_REGS:
01037 case (int) PH_REG:
01038 case (int) X_OR_PH_REGS:
01039 case (int) PL_REG:
01040 case (int) PL_OR_ACCUM_LOW_REGS:
01041 case (int) X_OR_PL_REGS:
01042 case (int) YL_OR_PL_OR_ACCUM_LOW_REGS:
01043 case (int) P_REG:
01044 case (int) ACCUM_OR_P_REGS:
01045 case (int) YL_OR_P_REGS:
01046 case (int) ACCUM_LOW_OR_YL_OR_P_REGS:
01047 case (int) Y_OR_P_REGS:
01048 case (int) ACCUM_Y_OR_P_REGS:
01049 case (int) Y_ADDR_REGS:
01050 case (int) ACCUM_LOW_OR_Y_ADDR_REGS:
01051 case (int) ACCUM_OR_Y_ADDR_REGS:
01052 case (int) X_OR_Y_ADDR_REGS:
01053 case (int) Y_OR_Y_ADDR_REGS:
01054 case (int) P_OR_Y_ADDR_REGS:
01055 case (int) YBASE_ELIGIBLE_REGS:
01056 return YBASE_VIRT_REGS;
01057
01058 default:
01059 break;
01060 }
01061 }
01062 }
01063 }
01064
01065
01066
01067 if (regno == -1 && GET_CODE(in) != PLUS)
01068 {
01069 if (class == YBASE_VIRT_REGS)
01070 return NON_YBASE_REGS;
01071 else
01072 return NO_REGS;
01073 }
01074
01075 if (GET_CODE (in) == PLUS && mode == QImode)
01076 {
01077 rtx addr0 = XEXP (in, 0);
01078 rtx addr1 = XEXP (in, 1);
01079
01080
01081
01082 if (REG_P (addr0) && REG_P (addr1))
01083 return ACCUM_LOW_REGS;
01084 }
01085
01086 #if 0
01087 if (REG_P(in))
01088 return ACCUM_REGS;
01089 #endif
01090
01091
01092 return ACCUM_HIGH_REGS;
01093 }
01094
01095 int
01096 symbolic_address_operand (op, mode)
01097 rtx op;
01098 enum machine_mode mode ATTRIBUTE_UNUSED;
01099 {
01100 return (symbolic_address_p (op));
01101 }
01102
01103 int
01104 symbolic_address_p (op)
01105 rtx op;
01106 {
01107 switch (GET_CODE (op))
01108 {
01109 case SYMBOL_REF:
01110 case LABEL_REF:
01111 return 1;
01112
01113 case CONST:
01114 op = XEXP (op, 0);
01115 return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
01116 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
01117 && GET_CODE (XEXP (op, 1)) == CONST_INT
01118 && INTVAL (XEXP (op,1)) < 0x20);
01119
01120 default:
01121 return 0;
01122 }
01123 }
01124
01125
01126
01127
01128
01129 int
01130 Y_address_operand (op, mode)
01131 rtx op;
01132 enum machine_mode mode;
01133 {
01134 return (memory_address_p (mode, op) && !symbolic_address_p (op));
01135 }
01136
01137 int
01138 sp_operand (op, mode)
01139 rtx op;
01140 enum machine_mode mode ATTRIBUTE_UNUSED;
01141 {
01142 return (GET_CODE (op) == PLUS
01143 && (XEXP (op, 0) == stack_pointer_rtx
01144 || XEXP (op, 0) == frame_pointer_rtx)
01145 && GET_CODE (XEXP (op,1)) == CONST_INT);
01146 }
01147
01148 int
01149 sp_operand2 (op, mode)
01150 rtx op;
01151 enum machine_mode mode ATTRIBUTE_UNUSED;
01152 {
01153 if ((GET_CODE (op) == PLUS
01154 && (XEXP (op, 0) == stack_pointer_rtx
01155 || XEXP (op, 0) == frame_pointer_rtx)
01156 && (REG_P (XEXP (op,1))
01157 && IS_ADDRESS_REGISTER (REGNO (XEXP(op, 1))))))
01158 return 1;
01159 else if ((GET_CODE (op) == PLUS
01160 && (XEXP (op, 1) == stack_pointer_rtx
01161 || XEXP (op, 1) == frame_pointer_rtx)
01162 && (REG_P (XEXP (op,0))
01163 && IS_ADDRESS_REGISTER (REGNO (XEXP(op, 1))))))
01164 return 1;
01165 else
01166 return 0;
01167 }
01168
01169 int
01170 nonmemory_arith_operand (op, mode)
01171 rtx op;
01172 enum machine_mode mode;
01173 {
01174 return (immediate_operand (op, mode) || arith_reg_operand (op, mode));
01175 }
01176
01177 int
01178 arith_reg_operand (op, mode)
01179 rtx op;
01180 enum machine_mode mode;
01181 {
01182 return (register_operand (op, mode)
01183 && (GET_CODE (op) != REG
01184 || REGNO (op) >= FIRST_PSEUDO_REGISTER
01185 || (!(IS_YBASE_REGISTER_WINDOW (REGNO (op)))
01186 && REGNO (op) != FRAME_POINTER_REGNUM)));
01187 }
01188
01189 int
01190 call_address_operand (op, mode)
01191 rtx op;
01192 enum machine_mode mode ATTRIBUTE_UNUSED;
01193 {
01194 if (symbolic_address_p (op) || REG_P(op))
01195 {
01196 return 1;
01197 }
01198
01199 return 0;
01200 }
01201
01202 int
01203 dsp16xx_comparison_operator (op, mode)
01204 register rtx op;
01205 enum machine_mode mode;
01206 {
01207 return ((mode == VOIDmode || GET_MODE (op) == mode)
01208 && GET_RTX_CLASS (GET_CODE (op)) == '<'
01209 && (GET_CODE(op) != GE && GET_CODE (op) != LT &&
01210 GET_CODE (op) != GEU && GET_CODE (op) != LTU));
01211 }
01212
01213 void
01214 notice_update_cc(exp)
01215 rtx exp;
01216 {
01217 if (GET_CODE (exp) == SET)
01218 {
01219
01220
01221 if (SET_DEST (exp) == pc_rtx)
01222 return;
01223
01224
01225
01226
01227
01228 if (REG_P (SET_DEST (exp))
01229 && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM))
01230 {
01231 if (cc_status.value1
01232 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
01233 cc_status.value1 = 0;
01234 if (cc_status.value2
01235 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
01236 cc_status.value2 = 0;
01237 return;
01238 }
01239
01240
01241 if (GET_CODE (SET_DEST (exp)) == MEM && REG_P (SET_SRC (exp)))
01242 {
01243 if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM)
01244 cc_status.value1 = 0;
01245 if (cc_status.value2 && GET_CODE (cc_status.value2) == MEM)
01246 cc_status.value2 = 0;
01247 return;
01248 }
01249
01250 else if (GET_CODE (SET_SRC (exp)) == CALL)
01251 {
01252 CC_STATUS_INIT;
01253 return;
01254 }
01255
01256 else if (SET_DEST (exp) == cc0_rtx)
01257 {
01258 CC_STATUS_INIT;
01259 cc_status.value1 = SET_SRC (exp);
01260 return;
01261 }
01262
01263 else if (GET_MODE_CLASS (GET_MODE (SET_SRC (exp))) == MODE_INT)
01264 switch (GET_CODE (SET_SRC (exp)))
01265 {
01266 case PLUS:
01267 case MINUS:
01268 if (REG_P (SET_DEST (exp)))
01269 {
01270
01271 if (IS_ADDRESS_REGISTER (REGNO (SET_DEST (exp))))
01272 {
01273 CC_STATUS_INIT;
01274 break;
01275 }
01276 }
01277 case ASHIFTRT:
01278 case LSHIFTRT:
01279 case ASHIFT:
01280 case AND:
01281 case IOR:
01282 case XOR:
01283 case MULT:
01284 case NEG:
01285 case NOT:
01286 cc_status.value1 = SET_SRC (exp);
01287 cc_status.value2 = SET_DEST (exp);
01288 break;
01289
01290 default:
01291 CC_STATUS_INIT;
01292 }
01293 else
01294 {
01295 CC_STATUS_INIT;
01296 }
01297 }
01298 else if (GET_CODE (exp) == PARALLEL
01299 && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
01300 {
01301 if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
01302 return;
01303
01304 if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
01305 {
01306 CC_STATUS_INIT;
01307 cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
01308 return;
01309 }
01310
01311 CC_STATUS_INIT;
01312 }
01313 else
01314 {
01315 CC_STATUS_INIT;
01316 }
01317 }
01318
01319 int
01320 dsp16xx_makes_calls ()
01321 {
01322 rtx insn;
01323
01324 for (insn = get_insns (); insn; insn = next_insn (insn))
01325 if (GET_CODE (insn) == CALL_INSN)
01326 return (1);
01327
01328 return 0;
01329 }
01330
01331 long
01332 compute_frame_size (size)
01333 int size;
01334 {
01335 long total_size;
01336 long var_size;
01337 long args_size;
01338 long extra_size;
01339 long reg_size;
01340
01341
01342 current_frame_info.function_makes_calls = !leaf_function_p ();
01343
01344 reg_size = 0;
01345 extra_size = 0;
01346 var_size = size;
01347 args_size = current_function_outgoing_args_size;
01348 reg_size = reg_save_size ();
01349
01350 total_size = var_size + args_size + extra_size + reg_size;
01351
01352
01353
01354 current_frame_info.total_size = total_size;
01355 current_frame_info.var_size = var_size;
01356 current_frame_info.args_size = args_size;
01357 current_frame_info.extra_size = extra_size;
01358 current_frame_info.reg_size = reg_size;
01359 current_frame_info.initialized = reload_completed;
01360 current_frame_info.reg_size = reg_size / UNITS_PER_WORD;
01361
01362 if (reg_size)
01363 {
01364 unsigned long offset = args_size + var_size + reg_size;
01365 current_frame_info.sp_save_offset = offset;
01366 current_frame_info.fp_save_offset = offset - total_size;
01367 }
01368
01369 return total_size;
01370 }
01371
01372 int
01373 dsp16xx_call_saved_register (regno)
01374 int regno;
01375 {
01376 #if 0
01377 if (regno == REG_PR && current_frame_info.function_makes_calls)
01378 return 1;
01379 #endif
01380 return (regs_ever_live[regno] && !call_used_regs[regno] &&
01381 !IS_YBASE_REGISTER_WINDOW(regno));
01382 }
01383
01384 int
01385 ybase_regs_ever_used ()
01386 {
01387 int regno;
01388 int live = 0;
01389
01390 for (regno = REG_YBASE0; regno <= REG_YBASE31; regno++)
01391 if (regs_ever_live[regno])
01392 {
01393 live = 1;
01394 break;
01395 }
01396
01397 return live;
01398 }
01399
01400 static void
01401 dsp16xx_output_function_prologue (file, size)
01402 FILE *file;
01403 HOST_WIDE_INT size;
01404 {
01405 int regno;
01406 long total_size;
01407 fp = reg_names[FRAME_POINTER_REGNUM];
01408 sp = reg_names[STACK_POINTER_REGNUM];
01409 rr = reg_names[RETURN_ADDRESS_REGNUM];
01410 a1h = reg_names[REG_A1];
01411
01412 total_size = compute_frame_size (size);
01413
01414 fprintf (file, "\t/* FUNCTION PROLOGUE: */\n");
01415 fprintf (file, "\t/* total=%ld, vars= %ld, regs= %d, args=%d, extra= %ld */\n",
01416 current_frame_info.total_size,
01417 current_frame_info.var_size,
01418 current_frame_info.reg_size,
01419 current_function_outgoing_args_size,
01420 current_frame_info.extra_size);
01421
01422 fprintf (file, "\t/* fp save offset= %ld, sp save_offset= %ld */\n\n",
01423 current_frame_info.fp_save_offset,
01424 current_frame_info.sp_save_offset);
01425
01426
01427 if (ybase_regs_ever_used())
01428 {
01429 fprintf (file, "\t%s=%s\n", a1h, reg_names[REG_YBASE]);
01430 if (TARGET_YBASE_HIGH)
01431 fprintf (file, "\t%s=%sh-32\n", reg_names[REG_A1], a1h);
01432 else
01433 fprintf (file, "\t%s=%sh+32\n", reg_names[REG_A1], a1h);
01434 fprintf (file, "\t%s=%s\n", reg_names[REG_YBASE], a1h);
01435 }
01436
01437 if (current_frame_info.var_size)
01438 {
01439 if (current_frame_info.var_size == 1)
01440 fprintf (file, "\t*%s++\n", sp);
01441 else
01442 {
01443 if (SMALL_INTVAL(current_frame_info.var_size) && ((current_frame_info.var_size & 0x8000) == 0))
01444 fprintf (file, "\t%s=%ld\n\t*%s++%s\n", reg_names[REG_J], current_frame_info.var_size, sp, reg_names[REG_J]);
01445 else
01446 fatal_error ("stack size > 32k");
01447 }
01448 }
01449
01450
01451
01452
01453 for(regno = 0; regno < FIRST_PSEUDO_REGISTER; ++ regno)
01454 if (dsp16xx_call_saved_register (regno))
01455 {
01456 fprintf (file, "\tpush(*%s)=%s\n", sp, reg_names[regno]);
01457 }
01458
01459
01460
01461 if (current_frame_info.function_makes_calls)
01462 fprintf (file, "\tpush(*%s)=%s\n", sp, reg_names[RETURN_ADDRESS_REGNUM]);
01463
01464 if (current_frame_info.args_size)
01465 {
01466 if (current_frame_info.args_size == 1)
01467 fprintf (file, "\t*%s++\n", sp);
01468 else
01469 error ("stack size > 32k");
01470 }
01471
01472 if (frame_pointer_needed)
01473 {
01474 fprintf (file, "\t%s=%s\n", a1h, sp);
01475 fprintf (file, "\t%s=%s\n", fp, a1h);
01476 fprintf (file, "\t%s=%ld\n", reg_names[REG_J], -total_size);
01477 fprintf (file, "\t*%s++%s\n", fp, reg_names[REG_J]);
01478 }
01479
01480 fprintf (file, "\t/* END FUNCTION PROLOGUE: */\n\n");
01481 }
01482
01483 void
01484 init_emulation_routines ()
01485 {
01486 dsp16xx_addhf3_libcall = (rtx) 0;
01487 dsp16xx_subhf3_libcall = (rtx) 0;
01488 dsp16xx_mulhf3_libcall = (rtx) 0;
01489 dsp16xx_divhf3_libcall = (rtx) 0;
01490 dsp16xx_cmphf3_libcall = (rtx) 0;
01491 dsp16xx_fixhfhi2_libcall = (rtx) 0;
01492 dsp16xx_floathihf2_libcall = (rtx) 0;
01493 dsp16xx_neghf2_libcall = (rtx) 0;
01494
01495 dsp16xx_mulhi3_libcall = (rtx) 0;
01496 dsp16xx_udivqi3_libcall = (rtx) 0;
01497 dsp16xx_udivhi3_libcall = (rtx) 0;
01498 dsp16xx_divqi3_libcall = (rtx) 0;
01499 dsp16xx_divhi3_libcall = (rtx) 0;
01500 dsp16xx_modqi3_libcall = (rtx) 0;
01501 dsp16xx_modhi3_libcall = (rtx) 0;
01502 dsp16xx_umodqi3_libcall = (rtx) 0;
01503 dsp16xx_umodhi3_libcall = (rtx) 0;
01504 dsp16xx_ashrhi3_libcall = (rtx) 0;
01505 dsp16xx_ashlhi3_libcall = (rtx) 0;
01506 dsp16xx_ucmphi2_libcall = (rtx) 0;
01507 dsp16xx_lshrhi3_libcall = (rtx) 0;
01508
01509 }
01510 static void
01511 dsp16xx_output_function_epilogue (file, size)
01512 FILE *file;
01513 HOST_WIDE_INT size ATTRIBUTE_UNUSED;
01514 {
01515 int regno;
01516
01517 fp = reg_names[FRAME_POINTER_REGNUM];
01518 sp = reg_names[STACK_POINTER_REGNUM];
01519 rr = reg_names[RETURN_ADDRESS_REGNUM];
01520 a1h = reg_names[REG_A1];
01521
01522 fprintf (file, "\n\t/* FUNCTION EPILOGUE: */\n");
01523
01524 if (current_frame_info.args_size)
01525 {
01526 if (current_frame_info.args_size == 1)
01527 fprintf (file, "\t*%s--\n", sp);
01528 else
01529 {
01530 fprintf (file, "\t%s=%ld\n\t*%s++%s\n",
01531 reg_names[REG_J], -current_frame_info.args_size, sp, reg_names[REG_J]);
01532 }
01533 }
01534
01535 if (ybase_regs_ever_used())
01536 {
01537 fprintf (file, "\t%s=%s\n", a1h, reg_names[REG_YBASE]);
01538 if (TARGET_YBASE_HIGH)
01539 fprintf (file, "\t%s=%sh+32\n", reg_names[REG_A1], a1h);
01540 else
01541 fprintf (file, "\t%s=%sh-32\n", reg_names[REG_A1], a1h);
01542 fprintf (file, "\t%s=%s\n", reg_names[REG_YBASE], a1h);
01543 }
01544
01545 if (current_frame_info.function_makes_calls)
01546 fprintf (file, "\t%s=pop(*%s)\n", reg_names[RETURN_ADDRESS_REGNUM], sp);
01547
01548 for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; --regno)
01549 if (dsp16xx_call_saved_register(regno))
01550 {
01551 fprintf (file, "\t%s=pop(*%s)\n", reg_names[regno], sp);
01552 }
01553
01554 if (current_frame_info.var_size)
01555 {
01556 if (current_frame_info.var_size == 1)
01557 fprintf (file, "\t*%s--\n", sp);
01558 else
01559 {
01560 fprintf (file, "\t%s=%ld\n\t*%s++%s\n",
01561 reg_names[REG_J], -current_frame_info.var_size, sp, reg_names[REG_J]);
01562 }
01563 }
01564
01565 fprintf (file, "\treturn\n");
01566
01567 current_frame_info = zero_frame_info;
01568 init_emulation_routines ();
01569 }
01570
01571
01572
01573
01574
01575
01576
01577 int
01578 emit_move_sequence (operands, mode)
01579 rtx *operands;
01580 enum machine_mode mode;
01581 {
01582 register rtx operand0 = operands[0];
01583 register rtx operand1 = operands[1];
01584
01585
01586
01587 if (GET_CODE (operand0) == MEM && GET_CODE (operand1) != REG)
01588 operands[1] = force_reg (mode, operand1);
01589
01590 return 0;
01591 }
01592
01593 void
01594 double_reg_from_memory (operands)
01595 rtx operands[];
01596 {
01597 rtx xoperands[4];
01598
01599 if (GET_CODE(XEXP(operands[1],0)) == POST_INC)
01600 {
01601 output_asm_insn ("%u0=%1", operands);
01602 output_asm_insn ("%w0=%1", operands);
01603 }
01604 else if (GET_CODE(XEXP(operands[1],0)) == POST_DEC)
01605 {
01606 xoperands[1] = XEXP (XEXP (operands[1], 0), 0);
01607 xoperands[0] = operands[0];
01608
01609
01610
01611 output_asm_insn ("%u0=*%1++\n\t%w0=*%1--\n\t*%1--\n\t*%1--", xoperands);
01612 }
01613 else if (GET_CODE(XEXP(operands[1],0)) == PLUS)
01614 {
01615 rtx addr;
01616 int offset = 0;
01617
01618 output_asm_insn ("%u0=%1", operands);
01619
01620
01621
01622
01623 addr = XEXP (operands[1], 0);
01624 if (GET_CODE (XEXP(addr,0)) == CONST_INT)
01625 offset = INTVAL(XEXP(addr,0)) + 1;
01626 else if (GET_CODE (XEXP(addr,1)) == CONST_INT)
01627 offset = INTVAL(XEXP(addr,1)) + 1;
01628
01629 fprintf (asm_out_file, "\t%s=*(%d)\n", reg_names[REGNO(operands[0]) + 1], offset + 31);
01630 }
01631 else
01632 {
01633 xoperands[1] = XEXP(operands[1],0);
01634 xoperands[0] = operands[0];
01635
01636 output_asm_insn ("%u0=*%1++\n\t%w0=*%1--", xoperands);
01637 }
01638 }
01639
01640
01641 void
01642 double_reg_to_memory (operands)
01643 rtx operands[];
01644 {
01645 rtx xoperands[4];
01646
01647 if (GET_CODE(XEXP(operands[0],0)) == POST_INC)
01648 {
01649 output_asm_insn ("%0=%u1", operands);
01650 output_asm_insn ("%0=%w1", operands);
01651 }
01652 else if (GET_CODE(XEXP(operands[0],0)) == POST_DEC)
01653 {
01654 xoperands[0] = XEXP (XEXP (operands[0], 0), 0);
01655 xoperands[1] = operands[1];
01656
01657
01658
01659
01660 output_asm_insn ("*%0++=%u1\n\t*%0--=%w1\n\t*%0--\n\t*%0--", xoperands);
01661
01662 }
01663 else if (GET_CODE(XEXP(operands[0],0)) == PLUS)
01664 {
01665 rtx addr;
01666 int offset = 0;
01667
01668 output_asm_insn ("%0=%u1", operands);
01669
01670
01671
01672 addr = XEXP (operands[0], 0);
01673 if (GET_CODE (XEXP(addr,0)) == CONST_INT)
01674 offset = INTVAL(XEXP(addr,0)) + 1;
01675 else if (GET_CODE (XEXP(addr,1)) == CONST_INT)
01676 offset = INTVAL(XEXP(addr,1)) + 1;
01677 else
01678 fatal_error ("invalid addressing mode");
01679
01680 fprintf (asm_out_file, "\t*(%d)=%s\n", offset + 31, reg_names[REGNO(operands[1]) + 1]);
01681 }
01682 else
01683 {
01684 xoperands[0] = XEXP(operands[0],0);
01685 xoperands[1] = operands[1];
01686
01687 output_asm_insn ("*%0++=%u1\n\t*%0--=%w1", xoperands);
01688 }
01689 }
01690
01691 void
01692 override_options ()
01693 {
01694 char *tmp;
01695
01696 if (chip_name == (char *) 0)
01697 chip_name = DEFAULT_CHIP_NAME;
01698
01699 if (text_seg_name == (char *) 0)
01700 text_seg_name = DEFAULT_TEXT_SEG_NAME;
01701
01702 if (data_seg_name == (char *) 0)
01703 data_seg_name = DEFAULT_DATA_SEG_NAME;
01704
01705 if (bss_seg_name == (char *) 0)
01706 bss_seg_name = DEFAULT_BSS_SEG_NAME;
01707
01708 if (const_seg_name == (char *) 0)
01709 const_seg_name = DEFAULT_CONST_SEG_NAME;
01710
01711 save_chip_name = xstrdup (chip_name);
01712
01713 rsect_text = tmp = (char *) xmalloc (strlen(".rsect ") +
01714 strlen(text_seg_name) + 3);
01715 sprintf (tmp, ".rsect \"%s\"", text_seg_name);
01716
01717 rsect_data = tmp = (char *) xmalloc (strlen(".rsect ") +
01718 strlen(data_seg_name) + 3);
01719 sprintf (tmp, ".rsect \"%s\"", data_seg_name);
01720
01721 rsect_bss = tmp = (char *) xmalloc (strlen(".rsect ") +
01722 strlen(bss_seg_name) + 3);
01723 sprintf (tmp, ".rsect \"%s\"", bss_seg_name);
01724
01725 rsect_const = tmp = (char *) xmalloc (strlen(".rsect ") +
01726 strlen(const_seg_name) + 3);
01727 sprintf (tmp, ".rsect \"%s\"", const_seg_name);
01728
01729
01730 ggc_add_rtx_root (&dsp16xx_addhf3_libcall, 1);
01731 ggc_add_rtx_root (&dsp16xx_subhf3_libcall, 1);
01732 ggc_add_rtx_root (&dsp16xx_mulhf3_libcall, 1);
01733 ggc_add_rtx_root (&dsp16xx_divhf3_libcall, 1);
01734 ggc_add_rtx_root (&dsp16xx_cmphf3_libcall, 1);
01735 ggc_add_rtx_root (&dsp16xx_fixhfhi2_libcall, 1);
01736 ggc_add_rtx_root (&dsp16xx_floathihf2_libcall, 1);
01737 ggc_add_rtx_root (&dsp16xx_neghf2_libcall, 1);
01738 ggc_add_rtx_root (&dsp16xx_mulhi3_libcall, 1);
01739 ggc_add_rtx_root (&dsp16xx_udivqi3_libcall, 1);
01740 ggc_add_rtx_root (&dsp16xx_udivhi3_libcall, 1);
01741 ggc_add_rtx_root (&dsp16xx_divqi3_libcall, 1);
01742 ggc_add_rtx_root (&dsp16xx_divhi3_libcall, 1);
01743 ggc_add_rtx_root (&dsp16xx_modqi3_libcall, 1);
01744 ggc_add_rtx_root (&dsp16xx_modhi3_libcall, 1);
01745 ggc_add_rtx_root (&dsp16xx_umodqi3_libcall, 1);
01746 ggc_add_rtx_root (&dsp16xx_umodhi3_libcall, 1);
01747 ggc_add_rtx_root (&dsp16xx_ashrhi3_libcall, 1);
01748 ggc_add_rtx_root (&dsp16xx_ashlhi3_libcall, 1);
01749 ggc_add_rtx_root (&dsp16xx_ucmphi2_libcall, 1);
01750 ggc_add_rtx_root (&dsp16xx_lshrhi3_libcall, 1);
01751 }
01752
01753 int
01754 next_cc_user_unsigned (insn)
01755 rtx insn;
01756 {
01757 switch (next_cc_user_code (insn))
01758 {
01759 case GTU:
01760 case GEU:
01761 case LTU:
01762 case LEU:
01763 return 1;
01764 default:
01765 return 0;
01766 }
01767 }
01768
01769 enum rtx_code
01770 next_cc_user_code (insn)
01771 rtx insn;
01772 {
01773
01774
01775
01776 if (!(insn = next_cc0_user (insn)))
01777 return (enum rtx_code) 0;
01778 else if (GET_CODE (insn) == JUMP_INSN
01779 && GET_CODE (PATTERN (insn)) == SET
01780 && GET_CODE (SET_SRC (PATTERN (insn))) == IF_THEN_ELSE)
01781 return GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0));
01782 else if (GET_CODE (insn) == INSN
01783 && GET_CODE (PATTERN (insn)) == SET
01784 && comparison_operator (SET_SRC (PATTERN (insn)), VOIDmode))
01785 return GET_CODE (SET_SRC (PATTERN (insn)));
01786 else
01787 abort ();
01788 }
01789
01790 void
01791 print_operand(file, op, letter)
01792 FILE *file;
01793 rtx op;
01794 int letter;
01795 {
01796 enum rtx_code code;
01797
01798 code = GET_CODE(op);
01799
01800 switch (letter)
01801 {
01802 case 'I':
01803 code = reverse_condition (code);
01804
01805
01806 case 'C':
01807 if (code == EQ)
01808 {
01809 fputs ("eq", file);
01810 return;
01811 }
01812 else if (code == NE)
01813 {
01814 fputs ("ne", file);
01815 return;
01816 }
01817 else if (code == GT || code == GTU)
01818 {
01819 fputs ("gt", file);
01820 return;
01821 }
01822 else if (code == LT || code == LTU)
01823 {
01824 fputs ("mi", file);
01825 return;
01826 }
01827 else if (code == GE || code == GEU)
01828 {
01829 fputs ("pl", file);
01830 return;
01831 }
01832 else if (code == LE || code == LEU)
01833 {
01834 fputs ("le", file);
01835 return;
01836 }
01837 else
01838 abort ();
01839 break;
01840
01841 default:
01842 break;
01843 }
01844
01845 if (code == REG)
01846 {
01847
01848 if (letter == 'w')
01849 fprintf (file, "%s", reg_names[REGNO (op) + 1]);
01850 else if (letter == 'u' || !letter)
01851 fprintf (file, "%s", reg_names[REGNO (op)]);
01852 else if (letter == 'b')
01853 fprintf (file, "%sh", reg_names[REGNO (op)]);
01854 else if (letter == 'm')
01855 fprintf (file, "%s", himode_reg_name[REGNO (op)]);
01856 else
01857 output_operand_lossage ("bad register extension code");
01858 }
01859 else if (code == MEM)
01860 output_address (XEXP(op,0));
01861 else if (code == CONST_INT)
01862 {
01863 HOST_WIDE_INT val = INTVAL (op);
01864
01865 if (letter == 'H')
01866 fprintf (file, HOST_WIDE_INT_PRINT_HEX, val & 0xffff);
01867 else if (letter == 'h')
01868 fprintf (file, HOST_WIDE_INT_PRINT_DEC, val);
01869 else if (letter == 'U')
01870 fprintf (file, HOST_WIDE_INT_PRINT_HEX, (val >> 16) & 0xffff);
01871 else
01872 output_addr_const(file, op);
01873 }
01874 else if (code == CONST_DOUBLE && GET_MODE(op) != DImode)
01875 {
01876 union { double d; int i[2]; } u;
01877 union { float f; int i; } u1;
01878 u.i[0] = CONST_DOUBLE_LOW (op);
01879 u.i[1] = CONST_DOUBLE_HIGH (op);
01880 u1.f = u.d;
01881 fprintf (file, "0x%x", u1.i);
01882 }
01883 else if (code == CONST)
01884 {
01885 rtx addr = XEXP (op, 0);
01886
01887 if (GET_CODE (addr) != PLUS)
01888 {
01889 output_addr_const(file, op);
01890 return;
01891 }
01892
01893 if ((GET_CODE (XEXP (addr, 0)) == SYMBOL_REF
01894 || GET_CODE (XEXP (addr, 0)) == LABEL_REF)
01895 && (GET_CODE (XEXP (addr, 1)) == CONST_INT))
01896 {
01897 int n = INTVAL (XEXP(addr, 1));
01898 output_addr_const (file, XEXP (addr, 0));
01899
01900 if (n >= 0)
01901 fprintf (file, "+");
01902
01903 n = (int) (short) n;
01904 fprintf (file, "%d", n);
01905 }
01906 else if ((GET_CODE (XEXP (addr, 1)) == SYMBOL_REF
01907 || GET_CODE (XEXP (addr, 1)) == LABEL_REF)
01908 && (GET_CODE (XEXP (addr, 0)) == CONST_INT))
01909 {
01910 int n = INTVAL (XEXP(addr, 0));
01911 output_addr_const (file, XEXP (addr, 1));
01912
01913 if (n >= 0)
01914 fprintf (file, "+");
01915
01916 n = (int) (short) n;
01917 fprintf (file, "%d", n);
01918 }
01919 else
01920 output_addr_const(file, op);
01921 }
01922 else
01923 output_addr_const (file, op);
01924 }
01925
01926
01927 void
01928 print_operand_address(file, addr)
01929 FILE *file;
01930 rtx addr;
01931 {
01932 rtx base;
01933 int offset = 0;;
01934
01935 switch (GET_CODE (addr))
01936 {
01937 case REG:
01938 fprintf (file, "*%s", reg_names[REGNO (addr)]);
01939 break;
01940 case POST_DEC:
01941 fprintf (file, "*%s--", reg_names[REGNO (XEXP (addr, 0))]);
01942 break;
01943 case POST_INC:
01944 fprintf (file, "*%s++", reg_names[REGNO (XEXP (addr, 0))]);
01945 break;
01946 case PLUS:
01947 if (GET_CODE (XEXP(addr,0)) == CONST_INT)
01948 offset = INTVAL(XEXP(addr,0)), base = XEXP(addr,1);
01949 else if (GET_CODE (XEXP(addr,1)) == CONST_INT)
01950 offset = INTVAL(XEXP(addr,1)), base = XEXP(addr,0);
01951 else
01952 abort();
01953 if (GET_CODE (base) == REG && REGNO(base) == STACK_POINTER_REGNUM)
01954 {
01955 if (offset >= -31 && offset <= 0)
01956 offset = 31 + offset;
01957 else
01958 fatal_error ("invalid offset in ybase addressing");
01959 }
01960 else
01961 fatal_error ("invalid register in ybase addressing");
01962
01963 fprintf (file, "*(%d)", offset);
01964 break;
01965
01966 default:
01967 if (FITS_5_BITS (addr))
01968 fprintf (file, "*(0x%x)", (INTVAL (addr) & 0x20));
01969 else
01970 output_addr_const (file, addr);
01971 }
01972 }
01973
01974 void
01975 output_dsp16xx_float_const (operands)
01976 rtx *operands;
01977 {
01978 rtx src = operands[1];
01979
01980 #if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
01981 REAL_VALUE_TYPE d;
01982 long value;
01983
01984 REAL_VALUE_FROM_CONST_DOUBLE (d, src);
01985 REAL_VALUE_TO_TARGET_SINGLE (d, value);
01986
01987 operands[1] = GEN_INT (value);
01988 output_asm_insn ("%u0=%U1\n\t%w0=%H1", operands);
01989 #else
01990 fatal_error ("inline float constants not supported on this host");
01991 #endif
01992 }
01993
01994 static int
01995 reg_save_size ()
01996 {
01997 int reg_save_size = 0;
01998 int regno;
01999
02000 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
02001 if (dsp16xx_call_saved_register (regno))
02002 {
02003 reg_save_size += UNITS_PER_WORD;
02004 }
02005
02006
02007 if (current_frame_info.function_makes_calls)
02008 reg_save_size += 1;
02009
02010 return (reg_save_size);
02011 }
02012
02013 #if 0
02014 int
02015 dsp16xx_starting_frame_offset()
02016 {
02017 int reg_save_size = 0;
02018 int regno;
02019
02020 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
02021 if (dsp16xx_call_saved_register (regno))
02022 {
02023 reg_save_size += UNITS_PER_WORD;
02024 }
02025
02026 return (reg_save_size);
02027 }
02028 #endif
02029
02030 int
02031 initial_frame_pointer_offset()
02032 {
02033 int offset = 0;
02034
02035 offset = compute_frame_size (get_frame_size());
02036
02037 #ifdef STACK_GROWS_DOWNWARD
02038 return (offset);
02039 #else
02040 return (-offset);
02041 #endif
02042 }
02043
02044
02045
02046
02047 #if 0
02048 void
02049 emit_1600_core_shift (shift_op, operands, shift_amount, mode)
02050 enum rtx_code shift_op;
02051 rtx *operands;
02052 int shift_amount;
02053 enum machine_mode mode;
02054 {
02055 int quotient;
02056 int i;
02057 int first_shift_emitted = 0;
02058
02059 while (shift_amount != 0)
02060 {
02061 if (shift_amount/16)
02062 {
02063 quotient = shift_amount/16;
02064 shift_amount = shift_amount - (quotient * 16);
02065 for (i = 0; i < quotient; i++)
02066 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
02067 gen_rtx (shift_op, mode,
02068 first_shift_emitted
02069 ? operands[0] : operands[1],
02070 GEN_INT (16))));
02071 first_shift_emitted = 1;
02072 }
02073 else if (shift_amount/8)
02074 {
02075 quotient = shift_amount/8;
02076 shift_amount = shift_amount - (quotient * 8);
02077 for (i = 0; i < quotient; i++)
02078 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
02079 gen_rtx (shift_op, mode,
02080 first_shift_emitted
02081 ? operands[0] : operands[1],
02082 GEN_INT (8))));
02083 first_shift_emitted = 1;
02084 }
02085 else if (shift_amount/4)
02086 {
02087 quotient = shift_amount/4;
02088 shift_amount = shift_amount - (quotient * 4);
02089 for (i = 0; i < quotient; i++)
02090 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
02091 gen_rtx (shift_op, mode,
02092 first_shift_emitted
02093 ? operands[0] : operands[1],
02094 GEN_INT (4))));
02095 first_shift_emitted = 1;
02096 }
02097 else if (shift_amount/1)
02098 {
02099 quotient = shift_amount/1;
02100 shift_amount = shift_amount - (quotient * 1);
02101 for (i = 0; i < quotient; i++)
02102 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
02103 gen_rtx (shift_op, mode,
02104 first_shift_emitted
02105 ? operands[0] : operands[1],
02106 GEN_INT (1))));
02107 first_shift_emitted = 1;
02108 }
02109 }
02110 }
02111 #else
02112 void
02113 emit_1600_core_shift (shift_op, operands, shift_amount)
02114 enum rtx_code shift_op;
02115 rtx *operands;
02116 int shift_amount;
02117 {
02118 int quotient;
02119 int i;
02120 int first_shift_emitted = 0;
02121 const char * const *shift_asm_ptr;
02122 const char * const *shift_asm_ptr_first;
02123
02124 if (shift_op == ASHIFT)
02125 {
02126 shift_asm_ptr = ashift_left_asm;
02127 shift_asm_ptr_first = ashift_left_asm_first;
02128 }
02129 else if (shift_op == ASHIFTRT)
02130 {
02131 shift_asm_ptr = ashift_right_asm;
02132 shift_asm_ptr_first = ashift_right_asm_first;
02133 }
02134 else if (shift_op == LSHIFTRT)
02135 {
02136 shift_asm_ptr = lshift_right_asm;
02137 shift_asm_ptr_first = lshift_right_asm_first;
02138 }
02139 else
02140 fatal_error ("invalid shift operator in emit_1600_core_shift");
02141
02142 while (shift_amount != 0)
02143 {
02144 if (shift_amount/16)
02145 {
02146 quotient = shift_amount/16;
02147 shift_amount = shift_amount - (quotient * 16);
02148 for (i = 0; i < quotient; i++)
02149 output_asm_insn ((first_shift_emitted ? shift_asm_ptr[SHIFT_INDEX_16]
02150 : shift_asm_ptr_first[SHIFT_INDEX_16]), operands);
02151 first_shift_emitted = 1;
02152 }
02153 else if (shift_amount/8)
02154 {
02155 quotient = shift_amount/8;
02156 shift_amount = shift_amount - (quotient * 8);
02157 for (i = 0; i < quotient; i++)
02158 output_asm_insn ((first_shift_emitted ? shift_asm_ptr[SHIFT_INDEX_8]
02159 : shift_asm_ptr_first[SHIFT_INDEX_8]), operands);
02160 first_shift_emitted = 1;
02161 }
02162 else if (shift_amount/4)
02163 {
02164 quotient = shift_amount/4;
02165 shift_amount = shift_amount - (quotient * 4);
02166 for (i = 0; i < quotient; i++)
02167 output_asm_insn ((first_shift_emitted ? shift_asm_ptr[SHIFT_INDEX_4]
02168 : shift_asm_ptr_first[SHIFT_INDEX_4]), operands);
02169 first_shift_emitted = 1;
02170 }
02171 else if (shift_amount/1)
02172 {
02173 quotient = shift_amount/1;
02174 shift_amount = shift_amount - (quotient * 1);
02175 for (i = 0; i < quotient; i++)
02176 output_asm_insn ((first_shift_emitted ? shift_asm_ptr[SHIFT_INDEX_1]
02177 : shift_asm_ptr_first[SHIFT_INDEX_1]), operands);
02178 first_shift_emitted = 1;
02179 }
02180 }
02181 }
02182 #endif
02183
02184 int
02185 num_1600_core_shifts (shift_amount)
02186 int shift_amount;
02187 {
02188 int quotient;
02189 int i;
02190 int first_shift_emitted = 0;
02191 int num_shifts = 0;
02192
02193 while (shift_amount != 0)
02194 {
02195 if (shift_amount/16)
02196 {
02197 quotient = shift_amount/16;
02198 shift_amount = shift_amount - (quotient * 16);
02199 for (i = 0; i < quotient; i++)
02200 num_shifts++;
02201 first_shift_emitted = 1;
02202 }
02203 else if (shift_amount/8)
02204 {
02205 quotient = shift_amount/8;
02206 shift_amount = shift_amount - (quotient * 8);
02207 for (i = 0; i < quotient; i++)
02208 num_shifts++;
02209
02210 first_shift_emitted = 1;
02211 }
02212 else if (shift_amount/4)
02213 {
02214 quotient = shift_amount/4;
02215 shift_amount = shift_amount - (quotient * 4);
02216 for (i = 0; i < quotient; i++)
02217 num_shifts++;
02218
02219 first_shift_emitted = 1;
02220 }
02221 else if (shift_amount/1)
02222 {
02223 quotient = shift_amount/1;
02224 shift_amount = shift_amount - (quotient * 1);
02225 for (i = 0; i < quotient; i++)
02226 num_shifts++;
02227
02228 first_shift_emitted = 1;
02229 }
02230 }
02231 return num_shifts;
02232 }
02233
02234 void
02235 asm_output_common(file, name, size, rounded)
02236 FILE *file;
02237 const char *name;
02238 int size ATTRIBUTE_UNUSED;
02239 int rounded;
02240 {
02241 bss_section ();
02242 ASM_GLOBALIZE_LABEL (file, name);
02243 assemble_name (file, name);
02244 fputs (":", file);
02245 if (rounded > 1)
02246 fprintf (file, "%d * int\n", rounded);
02247 else
02248 fprintf (file, "int\n");
02249 }
02250
02251 void
02252 asm_output_local(file, name, size, rounded)
02253 FILE *file;
02254 const char *name;
02255 int size ATTRIBUTE_UNUSED;
02256 int rounded;
02257 {
02258 bss_section ();
02259 assemble_name (file, name);
02260 fputs (":", file);
02261 if (rounded > 1)
02262 fprintf (file, "%d * int\n", rounded);
02263 else
02264 fprintf (file, "int\n");
02265 }
02266
02267 int
02268 dsp16xx_address_cost (addr)
02269 rtx addr;
02270 {
02271 switch (GET_CODE (addr))
02272 {
02273 default:
02274 break;
02275
02276 case REG:
02277 return 1;
02278
02279 case CONST:
02280 {
02281 rtx offset = const0_rtx;
02282 addr = eliminate_constant_term (addr, &offset);
02283
02284 if (GET_CODE (addr) == LABEL_REF)
02285 return 2;
02286
02287 if (GET_CODE (addr) != SYMBOL_REF)
02288 return 4;
02289
02290 if (INTVAL (offset) == 0)
02291 return 2;
02292 }
02293
02294
02295 case POST_INC: case POST_DEC:
02296 return (GET_MODE (addr) == QImode ? 1 : 2);
02297
02298 case SYMBOL_REF: case LABEL_REF:
02299 return 2;
02300
02301 case PLUS:
02302 {
02303 register rtx plus0 = XEXP (addr, 0);
02304 register rtx plus1 = XEXP (addr, 1);
02305
02306 if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)
02307 {
02308 plus0 = XEXP (addr, 1);
02309 plus1 = XEXP (addr, 0);
02310 }
02311
02312 if (GET_CODE (plus0) != REG)
02313 break;
02314
02315 switch (GET_CODE (plus1))
02316 {
02317 default:
02318 break;
02319
02320 case CONST_INT:
02321 return 4;
02322
02323 case CONST:
02324 case SYMBOL_REF:
02325 case LABEL_REF:
02326 return dsp16xx_address_cost (plus1) + 1;
02327 }
02328 }
02329 }
02330
02331 return 4;
02332 }
02333
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353
02354
02355
02356
02357
02358
02359
02360 struct rtx_def *
02361 dsp16xx_function_arg (args_so_far, mode, type, named)
02362 CUMULATIVE_ARGS args_so_far;
02363 enum machine_mode mode;
02364 tree type;
02365 int named;
02366 {
02367 if (TARGET_REGPARM)
02368 {
02369 if ((args_so_far & 1) != 0
02370 && (mode == HImode || GET_MODE_CLASS(mode) == MODE_FLOAT))
02371 args_so_far++;
02372
02373 if (type == void_type_node)
02374 return (struct rtx_def *) 0;
02375
02376 if (named && args_so_far < 4 && !MUST_PASS_IN_STACK (mode,type))
02377 return gen_rtx_REG (mode, args_so_far + FIRST_REG_FOR_FUNCTION_ARG);
02378 else
02379 return (struct rtx_def *) 0;
02380 }
02381 else
02382 return (struct rtx_def *) 0;
02383 }
02384
02385
02386
02387 void
02388 dsp16xx_function_arg_advance (cum, mode, type, named)
02389 CUMULATIVE_ARGS *cum;
02390 enum machine_mode mode;
02391 tree type;
02392 int named ATTRIBUTE_UNUSED;
02393 {
02394 if (TARGET_REGPARM)
02395 {
02396 if ((*cum & 1) != 0
02397 && (mode == HImode || GET_MODE_CLASS(mode) == MODE_FLOAT))
02398 *cum += 1;
02399
02400 if (mode != BLKmode)
02401 *cum += GET_MODE_SIZE (mode);
02402 else
02403 *cum += int_size_in_bytes (type);
02404 }
02405 }
02406
02407 void
02408 coff_dsp16xx_file_start (file)
02409 FILE *file;
02410 {
02411 fprintf (file, "#include <%s.h>\n", save_chip_name);
02412 }
02413
02414 void
02415 luxworks_dsp16xx_file_start (file)
02416 FILE *file;
02417 {
02418 char *temp_filename;
02419 int len, err_code;
02420
02421
02422 fprintf (file, "\t.debug ");
02423 err_code = (TARGET_DEBUG) ? fprintf (file, "yes, ") : fprintf (file, "no, ");
02424 err_code = (TARGET_SAVE_TEMPS) ? fprintf (file, "asm, ") : fprintf (file, "temp, ");
02425 len = strlen (main_input_filename);
02426 temp_filename = (char *) xmalloc (len + 2);
02427 strcpy (temp_filename, main_input_filename);
02428 #ifdef __CYGWIN32__
02429 p = temp_filename;
02430 while (*p != '\0') {
02431 if (*p == '\\')
02432 *p = '/';
02433 p++;
02434 }
02435 #endif
02436 fprintf (file, "\"%s\"\n", temp_filename);
02437
02438 fprintf (file, "#include <%s.h>\n", save_chip_name);
02439
02440
02441
02442
02443
02444
02445
02446 fprintf (file, "\t.rsect \".text\" , nodelete\n");
02447 fprintf (file, "\t.rsect \".data\" , nodelete\n");
02448 fprintf (file, "\t.rsect \".const\" , nodelete\n");
02449 fprintf (file, "\t.rsect \".bss\" , nodelete\n");
02450 }
02451
02452 rtx
02453 gen_tst_reg (x)
02454 rtx x;
02455 {
02456 enum machine_mode mode;
02457
02458 mode = GET_MODE (x);
02459
02460 if (mode == QImode)
02461 emit_insn (gen_rtx_PARALLEL
02462 (VOIDmode,
02463 gen_rtvec (2, gen_rtx_SET (VOIDmode, cc0_rtx, x),
02464 gen_rtx_CLOBBER (VOIDmode,
02465 gen_rtx_SCRATCH (QImode)))));
02466 else if (mode == HImode)
02467 emit_insn (gen_rtx_SET (VOIDmode, cc0_rtx, x));
02468 else
02469 fatal_error ("invalid mode for gen_tst_reg");
02470
02471 return cc0_rtx;
02472 }
02473
02474 rtx
02475 gen_compare_reg (code, x, y)
02476 enum rtx_code code;
02477 rtx x, y;
02478 {
02479 enum machine_mode mode;
02480
02481 mode = GET_MODE (x);
02482
02483
02484
02485 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
02486 return cc0_rtx;
02487
02488 if (mode == QImode)
02489 {
02490 if (code == GTU || code == GEU
02491 || code == LTU || code == LEU)
02492 {
02493 emit_insn (gen_rtx_PARALLEL
02494 (VOIDmode,
02495 gen_rtvec (3,
02496 gen_rtx_SET (VOIDmode, cc0_rtx,
02497 gen_rtx_COMPARE (mode, x, y)),
02498 gen_rtx_CLOBBER (VOIDmode,
02499 gen_rtx_SCRATCH (QImode)),
02500 gen_rtx_CLOBBER (VOIDmode,
02501 gen_rtx_SCRATCH (QImode)))));
02502 }
02503 else
02504 {
02505 emit_insn (gen_rtx_PARALLEL
02506 (VOIDmode,
02507 gen_rtvec (3, gen_rtx_SET (VOIDmode, cc0_rtx,
02508 gen_rtx_COMPARE (mode, x, y)),
02509 gen_rtx_CLOBBER (VOIDmode,
02510 gen_rtx_SCRATCH (QImode)),
02511 gen_rtx_CLOBBER (VOIDmode,
02512 gen_rtx_SCRATCH (QImode)))));
02513 }
02514 }
02515 else if (mode == HImode)
02516 {
02517 if (code == GTU || code == GEU
02518 || code == LTU || code == LEU)
02519 {
02520 emit_insn (gen_rtx_PARALLEL
02521 (VOIDmode,
02522 gen_rtvec (5,
02523 gen_rtx_SET (VOIDmode, cc0_rtx,
02524 gen_rtx_COMPARE (VOIDmode, x, y)),
02525 gen_rtx_CLOBBER (VOIDmode,
02526 gen_rtx_SCRATCH (QImode)),
02527 gen_rtx_CLOBBER (VOIDmode,
02528 gen_rtx_SCRATCH (QImode)),
02529 gen_rtx_CLOBBER (VOIDmode,
02530 gen_rtx_SCRATCH (QImode)),
02531 gen_rtx_CLOBBER (VOIDmode,
02532 gen_rtx_SCRATCH (QImode)))));
02533 }
02534 else
02535 emit_insn (gen_rtx_SET (VOIDmode, cc0_rtx,
02536 gen_rtx_COMPARE (VOIDmode,
02537 force_reg (HImode, x),
02538 force_reg (HImode,y))));
02539 }
02540 else
02541 fatal_error ("invalid mode for integer comparison in gen_compare_reg");
02542
02543 return cc0_rtx;
02544 }
02545
02546 const char *
02547 output_block_move (operands)
02548 rtx operands[];
02549 {
02550 int loop_count = INTVAL(operands[2]);
02551 rtx xoperands[4];
02552
02553 fprintf (asm_out_file, "\tdo %d {\n", loop_count);
02554 xoperands[0] = operands[4];
02555 xoperands[1] = operands[1];
02556 output_asm_insn ("%0=*%1++", xoperands);
02557
02558 xoperands[0] = operands[0];
02559 xoperands[1] = operands[4];
02560 output_asm_insn ("*%0++=%1", xoperands);
02561
02562 fprintf (asm_out_file, "\t}\n");
02563 return "";
02564 }
02565
02566 int
02567 uns_comparison_operator (op, mode)
02568 rtx op;
02569 enum machine_mode mode;
02570 {
02571 if (mode == VOIDmode || GET_MODE (op) == mode)
02572 {
02573 enum rtx_code code;
02574
02575 code = GET_CODE(op);
02576
02577 if (code == LEU || code == LTU || code == GEU
02578 || code == GTU)
02579 {
02580 return 1;
02581 }
02582 else
02583 return 0;
02584 }
02585
02586 return 0;
02587 }
02588
02589 int
02590 signed_comparison_operator (op, mode)
02591 rtx op;
02592 enum machine_mode mode;
02593 {
02594 if (mode == VOIDmode || GET_MODE (op) == mode)
02595 {
02596 enum rtx_code code;
02597
02598 code = GET_CODE(op);
02599
02600 if (!(code == LEU || code == LTU || code == GEU
02601 || code == GTU))
02602 {
02603 return 1;
02604 }
02605 else
02606 return 0;
02607 }
02608
02609 return 0;
02610 }