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 "tree.h"
00025 #include "rtl.h"
00026 #include "function.h"
00027 #include "regs.h"
00028 #include "hard-reg-set.h"
00029 #include "real.h"
00030 #include "insn-config.h"
00031 #include "conditions.h"
00032 #include "output.h"
00033 #include "insn-attr.h"
00034 #include "recog.h"
00035 #include "toplev.h"
00036 #include "expr.h"
00037 #include "reload.h"
00038 #include "tm_p.h"
00039 #include "target.h"
00040 #include "target-def.h"
00041 #include "debug.h"
00042
00043
00044 #include "flags.h"
00045
00046 #ifdef SUPPORT_SUN_FPA
00047
00048
00049
00050 const enum reg_class regno_reg_class[]
00051 = { DATA_REGS, ADDR_REGS, FP_REGS,
00052 LO_FPA_REGS, LO_FPA_REGS, FPA_REGS, FPA_REGS };
00053
00054 #endif
00055
00056
00057
00058 int switch_table_difference_label_flag;
00059
00060 static rtx find_addr_reg PARAMS ((rtx));
00061 static const char *singlemove_string PARAMS ((rtx *));
00062 static void m68k_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
00063 static void m68k_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
00064 static void m68k_coff_asm_named_section PARAMS ((const char *, unsigned int));
00065 #ifdef CTOR_LIST_BEGIN
00066 static void m68k_svr3_asm_out_constructor PARAMS ((rtx, int));
00067 #endif
00068
00069
00070
00071
00072 const char *m68k_align_loops_string;
00073
00074 const char *m68k_align_jumps_string;
00075
00076 const char *m68k_align_funcs_string;
00077
00078
00079 int m68k_align_loops;
00080
00081 int m68k_align_jumps;
00082
00083 int m68k_align_funcs;
00084
00085
00086
00087
00088 int m68k_last_compare_had_fp_operands;
00089
00090
00091
00092 #if INT_OP_GROUP == INT_OP_DOT_WORD
00093 #undef TARGET_ASM_ALIGNED_HI_OP
00094 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
00095 #endif
00096
00097 #if INT_OP_GROUP == INT_OP_NO_DOT
00098 #undef TARGET_ASM_BYTE_OP
00099 #define TARGET_ASM_BYTE_OP "\tbyte\t"
00100 #undef TARGET_ASM_ALIGNED_HI_OP
00101 #define TARGET_ASM_ALIGNED_HI_OP "\tshort\t"
00102 #undef TARGET_ASM_ALIGNED_SI_OP
00103 #define TARGET_ASM_ALIGNED_SI_OP "\tlong\t"
00104 #endif
00105
00106 #if INT_OP_GROUP == INT_OP_DC
00107 #undef TARGET_ASM_BYTE_OP
00108 #define TARGET_ASM_BYTE_OP "\tdc.b\t"
00109 #undef TARGET_ASM_ALIGNED_HI_OP
00110 #define TARGET_ASM_ALIGNED_HI_OP "\tdc.w\t"
00111 #undef TARGET_ASM_ALIGNED_SI_OP
00112 #define TARGET_ASM_ALIGNED_SI_OP "\tdc.l\t"
00113 #endif
00114
00115 #undef TARGET_ASM_UNALIGNED_HI_OP
00116 #define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP
00117 #undef TARGET_ASM_UNALIGNED_SI_OP
00118 #define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP
00119
00120 #undef TARGET_ASM_FUNCTION_PROLOGUE
00121 #define TARGET_ASM_FUNCTION_PROLOGUE m68k_output_function_prologue
00122 #undef TARGET_ASM_FUNCTION_EPILOGUE
00123 #define TARGET_ASM_FUNCTION_EPILOGUE m68k_output_function_epilogue
00124
00125 struct gcc_target targetm = TARGET_INITIALIZER;
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 void
00137 override_options ()
00138 {
00139 int def_align;
00140 int i;
00141
00142 def_align = 1;
00143
00144
00145 m68k_align_loops = def_align;
00146 if (m68k_align_loops_string)
00147 {
00148 i = atoi (m68k_align_loops_string);
00149 if (i < 1 || i > MAX_CODE_ALIGN)
00150 error ("-malign-loops=%d is not between 1 and %d", i, MAX_CODE_ALIGN);
00151 else
00152 m68k_align_loops = i;
00153 }
00154
00155
00156 m68k_align_jumps = def_align;
00157 if (m68k_align_jumps_string)
00158 {
00159 i = atoi (m68k_align_jumps_string);
00160 if (i < 1 || i > MAX_CODE_ALIGN)
00161 error ("-malign-jumps=%d is not between 1 and %d", i, MAX_CODE_ALIGN);
00162 else
00163 m68k_align_jumps = i;
00164 }
00165
00166
00167 m68k_align_funcs = def_align;
00168 if (m68k_align_funcs_string)
00169 {
00170 i = atoi (m68k_align_funcs_string);
00171 if (i < 1 || i > MAX_CODE_ALIGN)
00172 error ("-malign-functions=%d is not between 1 and %d",
00173 i, MAX_CODE_ALIGN);
00174 else
00175 m68k_align_funcs = i;
00176 }
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 #ifdef CRDS
00192
00193 static void
00194 m68k_output_function_prologue (stream, size)
00195 FILE *stream;
00196 HOST_WIDE_INT size;
00197 {
00198 register int regno;
00199 register int mask = 0;
00200 HOST_WIDE_INT fsize = ((size) + 3) & -4;
00201
00202
00203 if (fsize > 30000)
00204 {
00205 fprintf (stream, "\tmovel sp,a0\n");
00206 fprintf (stream, "\taddl $-%d,a0\n", 2048 + fsize);
00207 fprintf (stream, "\ttstb (a0)\n");
00208 }
00209 else
00210 fprintf (stream, "\ttstb -%d(sp)\n", 2048 + fsize);
00211
00212 if (frame_pointer_needed)
00213 {
00214 if (TARGET_68020 || fsize < 0x8000)
00215 fprintf (stream, "\tlink a6,$%d\n", -fsize);
00216 else
00217 fprintf (stream, "\tlink a6,$0\n\tsubl $%d,sp\n", fsize);
00218 }
00219 else if (fsize)
00220 {
00221
00222 if (fsize + 4 < 0x8000)
00223 fprintf (stream, "\tadd.w #%d,sp\n", - (fsize + 4));
00224 else
00225 fprintf (stream, "\tadd.l #%d,sp\n", - (fsize + 4));
00226 }
00227
00228 for (regno = 16; regno < 24; regno++)
00229 if (regs_ever_live[regno] && ! call_used_regs[regno])
00230 mask |= 1 << (regno - 16);
00231
00232 if ((mask & 0xff) != 0)
00233 fprintf (stream, "\tfmovem $0x%x,-(sp)\n", mask & 0xff);
00234
00235 mask = 0;
00236 for (regno = 0; regno < 16; regno++)
00237 if (regs_ever_live[regno] && ! call_used_regs[regno])
00238 mask |= 1 << (15 - regno);
00239 if (frame_pointer_needed)
00240 mask &= ~ (1 << (15-FRAME_POINTER_REGNUM));
00241
00242 if (exact_log2 (mask) >= 0)
00243 fprintf (stream, "\tmovel %s,-(sp)\n", reg_names[15 - exact_log2 (mask)]);
00244 else if (mask)
00245 fprintf (stream, "\tmovem $0x%x,-(sp)\n", mask);
00246 }
00247
00248 #else
00249 #if defined (DPX2) && defined (MOTOROLA)
00250
00251 static void
00252 m68k_output_function_prologue (stream, size)
00253 FILE *stream;
00254 HOST_WIDE_INT size;
00255 {
00256 register int regno;
00257 register int mask = 0;
00258 int num_saved_regs = 0, first = 1;
00259 HOST_WIDE_INT fsize = ((size) + 3) & -4;
00260
00261 if (frame_pointer_needed)
00262 {
00263
00264 if (fsize < 0x8000 && !TARGET_68040)
00265 fprintf (stream, "\tlink %s,#%d\n",
00266 reg_names[FRAME_POINTER_REGNUM], -fsize);
00267 else if (TARGET_68020)
00268 fprintf (stream, "\tlink %s,#%d\n",
00269 reg_names[FRAME_POINTER_REGNUM], -fsize);
00270 else
00271 fprintf (stream, "\tlink %s,#0\n\tadd.l #%d,sp\n",
00272 reg_names[FRAME_POINTER_REGNUM], -fsize);
00273 }
00274 else if (fsize)
00275 {
00276
00277 if (fsize + 4 < 0x8000)
00278 fprintf (stream, "\tadd.w #%d,sp\n", - (fsize + 4));
00279 else
00280 fprintf (stream, "\tadd.l #%d,sp\n", - (fsize + 4));
00281 }
00282
00283 for (regno = 23; regno >= 16; regno--)
00284 if (regs_ever_live[regno] && ! call_used_regs[regno])
00285 {
00286 if (first)
00287 {
00288 fprintf (stream, "\tfmovem.x %s", reg_names[regno]);
00289 first = 0;
00290 }
00291 else
00292 fprintf (stream, "/%s", reg_names[regno]);
00293 }
00294 if (!first)
00295 fprintf (stream, ",-(sp)\n");
00296
00297 mask = 0;
00298 for (regno = 0; regno < 16; regno++)
00299 if (regs_ever_live[regno] && ! call_used_regs[regno])
00300 {
00301 mask |= 1 << (15 - regno);
00302 num_saved_regs++;
00303 }
00304
00305 if (frame_pointer_needed)
00306 {
00307 mask &= ~ (1 << (15 - FRAME_POINTER_REGNUM));
00308 num_saved_regs--;
00309 }
00310
00311 if (num_saved_regs <= 2)
00312 {
00313
00314
00315
00316
00317
00318 int i;
00319
00320
00321 for (i = 0; i< 16; i++)
00322 if (mask & (1 << i))
00323 fprintf (stream, "\tmove.l %s,-(sp)\n", reg_names[15 - i]);
00324 }
00325 else if (mask)
00326 {
00327 first = 1;
00328 for (regno = 0; regno < 16; regno++)
00329 if (mask & (1 << regno))
00330 {
00331 if (first)
00332 {
00333 fprintf (stream, "\tmovem.l %s", reg_names[15 - regno]);
00334 first = 0;
00335 }
00336 else
00337 fprintf (stream, "/%s", reg_names[15 - regno]);
00338 }
00339 fprintf (stream, ",-(sp)\n");
00340 }
00341
00342 if (flag_pic && current_function_uses_pic_offset_table)
00343 {
00344 fprintf (stream, "\tmove.l #__GLOBAL_OFFSET_TABLE_, %s\n",
00345 reg_names[PIC_OFFSET_TABLE_REGNUM]);
00346 fprintf (stream, "\tlea.l (pc,%s.l),%s\n",
00347 reg_names[PIC_OFFSET_TABLE_REGNUM],
00348 reg_names[PIC_OFFSET_TABLE_REGNUM]);
00349 }
00350 }
00351
00352 #else
00353 #if defined (NEWS) && defined (MOTOROLA)
00354
00355 static void
00356 m68k_output_function_prologue (stream, size)
00357 FILE *stream;
00358 HOST_WIDE_INT size;
00359 {
00360 register int regno;
00361 register int mask = 0;
00362 HOST_WIDE_INT fsize = ((size) + 3) & -4;
00363
00364 if (frame_pointer_needed)
00365 {
00366 if (fsize < 0x8000)
00367 fprintf (stream, "\tlink fp,#%d\n", -fsize);
00368 else if (TARGET_68020)
00369 fprintf (stream, "\tlink.l fp,#%d\n", -fsize);
00370 else
00371 fprintf (stream, "\tlink fp,#0\n\tsub.l #%d,sp\n", fsize);
00372 }
00373 else if (fsize)
00374 {
00375 int amt = fsize + 4;
00376
00377 if (fsize + 4 < 0x8000)
00378 asm_fprintf (stream, "\tadd.w %0I%d,%Rsp\n", - amt);
00379 else
00380 asm_fprintf (stream, "\tadd.l %0I%d,%Rsp\n", - amt);
00381 }
00382
00383 for (regno = 16; regno < FIRST_PSEUDO_REGISTER; regno++)
00384 if (regs_ever_live[regno] && ! call_used_regs[regno])
00385 mask |= 1 << (regno - 16);
00386
00387 if (mask != 0)
00388 fprintf (stream, "\tfmovem.x #0x%x,-(sp)\n", mask & 0xff);
00389
00390 mask = 0;
00391 for (regno = 0; regno < 16; regno++)
00392 if (regs_ever_live[regno] && ! call_used_regs[regno])
00393 mask |= 1 << (15 - regno);
00394
00395 if (frame_pointer_needed)
00396 mask &= ~ (1 << (15-FRAME_POINTER_REGNUM));
00397
00398 if (exact_log2 (mask) >= 0)
00399 fprintf (stream, "\tmove.l %s,-(sp)\n", reg_names[15 - exact_log2 (mask)]);
00400 else
00401 if (mask) fprintf (stream, "\tmovem.l #0x%x,-(sp)\n", mask);
00402 }
00403
00404 #else
00405
00406 static void
00407 m68k_output_function_prologue (stream, size)
00408 FILE *stream;
00409 HOST_WIDE_INT size;
00410 {
00411 register int regno;
00412 register int mask = 0;
00413 int num_saved_regs = 0;
00414 HOST_WIDE_INT fsize = (size + 3) & -4;
00415 HOST_WIDE_INT cfa_offset = INCOMING_FRAME_SP_OFFSET;
00416 HOST_WIDE_INT cfa_store_offset = cfa_offset;
00417
00418
00419
00420 if (current_function_limit_stack
00421 && GET_CODE (stack_limit_rtx) == SYMBOL_REF)
00422 {
00423 #if defined (MOTOROLA)
00424 asm_fprintf (stream, "\tcmp.l %0I%s+%d,%Rsp\n\ttrapcs\n",
00425 XSTR (stack_limit_rtx, 0), fsize + 4);
00426 #else
00427 asm_fprintf (stream, "\tcmpl %0I%s+%d,%Rsp\n\ttrapcs\n",
00428 XSTR (stack_limit_rtx, 0), fsize + 4);
00429 #endif
00430 }
00431
00432 if (frame_pointer_needed)
00433 {
00434 if (fsize == 0 && TARGET_68040)
00435 {
00436
00437 #ifdef MOTOROLA
00438 asm_fprintf (stream, "\tpea (%s)\n\tmove.l %s,%s\n",
00439 reg_names[FRAME_POINTER_REGNUM], reg_names[STACK_POINTER_REGNUM],
00440 reg_names[FRAME_POINTER_REGNUM]);
00441 #else
00442 asm_fprintf (stream, "\tpea %s@\n\tmovel %s,%s\n",
00443 reg_names[FRAME_POINTER_REGNUM], reg_names[STACK_POINTER_REGNUM],
00444 reg_names[FRAME_POINTER_REGNUM]);
00445 #endif
00446 }
00447 else if (fsize < 0x8000)
00448 {
00449 #ifdef MOTOROLA
00450 asm_fprintf (stream, "\tlink.w %s,%0I%d\n",
00451 reg_names[FRAME_POINTER_REGNUM], -fsize);
00452 #else
00453 asm_fprintf (stream, "\tlink %s,%0I%d\n",
00454 reg_names[FRAME_POINTER_REGNUM], -fsize);
00455 #endif
00456 }
00457 else if (TARGET_68020)
00458 {
00459 #ifdef MOTOROLA
00460 asm_fprintf (stream, "\tlink.l %s,%0I%d\n",
00461 reg_names[FRAME_POINTER_REGNUM], -fsize);
00462 #else
00463 asm_fprintf (stream, "\tlink %s,%0I%d\n",
00464 reg_names[FRAME_POINTER_REGNUM], -fsize);
00465 #endif
00466 }
00467 else
00468 {
00469
00470 #ifdef MOTOROLA
00471 asm_fprintf (stream, "\tlink.w %s,%0I0\n\tadd.l %0I%d,%Rsp\n",
00472 reg_names[FRAME_POINTER_REGNUM], -fsize);
00473 #else
00474 asm_fprintf (stream, "\tlink %s,%0I0\n\taddl %0I%d,%Rsp\n",
00475 reg_names[FRAME_POINTER_REGNUM], -fsize);
00476 #endif
00477 }
00478 if (dwarf2out_do_frame ())
00479 {
00480 char *l;
00481 l = (char *) dwarf2out_cfi_label ();
00482 cfa_store_offset += 4;
00483 cfa_offset = cfa_store_offset;
00484 dwarf2out_reg_save (l, FRAME_POINTER_REGNUM, -cfa_store_offset);
00485 dwarf2out_def_cfa (l, FRAME_POINTER_REGNUM, cfa_offset);
00486 cfa_store_offset += fsize;
00487 }
00488 }
00489 else if (fsize)
00490 {
00491 if (fsize + 4 < 0x8000)
00492 {
00493 #ifndef NO_ADDSUB_Q
00494 if (fsize + 4 <= 8)
00495 {
00496 if (!TARGET_5200)
00497 {
00498
00499 #ifdef MOTOROLA
00500 asm_fprintf (stream, "\tsubq.w %0I%d,%Rsp\n", fsize + 4);
00501 #else
00502 asm_fprintf (stream, "\tsubqw %0I%d,%Rsp\n", fsize + 4);
00503 #endif
00504 }
00505 else
00506 {
00507
00508 #ifdef MOTOROLA
00509 asm_fprintf (stream, "\tsubq.l %0I%d,%Rsp\n", fsize + 4);
00510 #else
00511 asm_fprintf (stream, "\tsubql %0I%d,%Rsp\n", fsize + 4);
00512 #endif
00513 }
00514 }
00515 else if (fsize + 4 <= 16 && TARGET_CPU32)
00516 {
00517
00518
00519
00520 #ifdef MOTOROLA
00521 asm_fprintf (stream, "\tsubq.w %0I8,%Rsp\n\tsubq.w %0I%d,%Rsp\n",
00522 fsize + 4 - 8);
00523 #else
00524 asm_fprintf (stream, "\tsubqw %0I8,%Rsp\n\tsubqw %0I%d,%Rsp\n",
00525 fsize + 4 - 8);
00526 #endif
00527 }
00528 else
00529 #endif
00530 if (TARGET_68040)
00531 {
00532
00533
00534 #ifdef MOTOROLA
00535 asm_fprintf (stream, "\tadd.w %0I%d,%Rsp\n", - (fsize + 4));
00536 #else
00537 asm_fprintf (stream, "\taddw %0I%d,%Rsp\n", - (fsize + 4));
00538 #endif
00539 }
00540 else
00541 {
00542 #ifdef MOTOROLA
00543 asm_fprintf (stream, "\tlea (%d,%Rsp),%Rsp\n", - (fsize + 4));
00544 #else
00545 asm_fprintf (stream, "\tlea %Rsp@(%d),%Rsp\n", - (fsize + 4));
00546 #endif
00547 }
00548 }
00549 else
00550 {
00551
00552 #ifdef MOTOROLA
00553 asm_fprintf (stream, "\tadd.l %0I%d,%Rsp\n", - (fsize + 4));
00554 #else
00555 asm_fprintf (stream, "\taddl %0I%d,%Rsp\n", - (fsize + 4));
00556 #endif
00557 }
00558 if (dwarf2out_do_frame ())
00559 {
00560 cfa_store_offset += fsize;
00561 cfa_offset = cfa_store_offset;
00562 dwarf2out_def_cfa ("", STACK_POINTER_REGNUM, cfa_offset);
00563 }
00564 }
00565 #ifdef SUPPORT_SUN_FPA
00566 for (regno = 24; regno < 56; regno++)
00567 if (regs_ever_live[regno] && ! call_used_regs[regno])
00568 {
00569 #ifdef MOTOROLA
00570 asm_fprintf (stream, "\tfpmovd %s,-(%Rsp)\n",
00571 reg_names[regno]);
00572 #else
00573 asm_fprintf (stream, "\tfpmoved %s,%Rsp@-\n",
00574 reg_names[regno]);
00575 #endif
00576 if (dwarf2out_do_frame ())
00577 {
00578 char *l = dwarf2out_cfi_label ();
00579
00580 cfa_store_offset += 8;
00581 if (! frame_pointer_needed)
00582 {
00583 cfa_offset = cfa_store_offset;
00584 dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, cfa_offset);
00585 }
00586 dwarf2out_reg_save (l, regno, -cfa_store_offset);
00587 }
00588 }
00589 #endif
00590 if (TARGET_68881)
00591 {
00592 for (regno = 16; regno < 24; regno++)
00593 if (regs_ever_live[regno] && ! call_used_regs[regno])
00594 {
00595 mask |= 1 << (regno - 16);
00596 num_saved_regs++;
00597 }
00598 if ((mask & 0xff) != 0)
00599 {
00600 #ifdef MOTOROLA
00601 asm_fprintf (stream, "\tfmovm %0I0x%x,-(%Rsp)\n", mask & 0xff);
00602 #else
00603 asm_fprintf (stream, "\tfmovem %0I0x%x,%Rsp@-\n", mask & 0xff);
00604 #endif
00605 if (dwarf2out_do_frame ())
00606 {
00607 char *l = (char *) dwarf2out_cfi_label ();
00608 int n_regs;
00609
00610 cfa_store_offset += num_saved_regs * 12;
00611 if (! frame_pointer_needed)
00612 {
00613 cfa_offset = cfa_store_offset;
00614 dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, cfa_offset);
00615 }
00616 for (regno = 16, n_regs = 0; regno < 24; regno++)
00617 if (mask & (1 << (regno - 16)))
00618 dwarf2out_reg_save (l, regno,
00619 -cfa_store_offset + n_regs++ * 12);
00620 }
00621 }
00622 mask = 0;
00623 num_saved_regs = 0;
00624 }
00625 for (regno = 0; regno < 16; regno++)
00626 if (regs_ever_live[regno] && ! call_used_regs[regno])
00627 {
00628 mask |= 1 << (15 - regno);
00629 num_saved_regs++;
00630 }
00631 if (frame_pointer_needed)
00632 {
00633 mask &= ~ (1 << (15 - FRAME_POINTER_REGNUM));
00634 num_saved_regs--;
00635 }
00636 if (flag_pic && current_function_uses_pic_offset_table)
00637 {
00638 mask |= 1 << (15 - PIC_OFFSET_TABLE_REGNUM);
00639 num_saved_regs++;
00640 }
00641
00642 #if NEED_PROBE
00643 #ifdef MOTOROLA
00644 asm_fprintf (stream, "\ttst.l %d(%Rsp)\n", NEED_PROBE - num_saved_regs * 4);
00645 #else
00646 asm_fprintf (stream, "\ttstl %Rsp@(%d)\n", NEED_PROBE - num_saved_regs * 4);
00647 #endif
00648 #endif
00649
00650
00651
00652 if (current_function_limit_stack)
00653 {
00654 if (REG_P (stack_limit_rtx))
00655 {
00656 #if defined (MOTOROLA)
00657 asm_fprintf (stream, "\tcmp.l %s,%Rsp\n\ttrapcs\n",
00658 reg_names[REGNO (stack_limit_rtx)]);
00659 #else
00660 asm_fprintf (stream, "\tcmpl %s,%Rsp\n\ttrapcs\n",
00661 reg_names[REGNO (stack_limit_rtx)]);
00662 #endif
00663 }
00664 else if (GET_CODE (stack_limit_rtx) != SYMBOL_REF)
00665 warning ("stack limit expression is not supported");
00666 }
00667
00668 if (num_saved_regs <= 2)
00669 {
00670
00671
00672
00673
00674
00675 int i;
00676
00677
00678 for (i = 0; i< 16; i++)
00679 if (mask & (1 << i))
00680 {
00681 asm_fprintf (stream,
00682 #ifdef MOTOROLA
00683 "\t%Omove.l %s,-(%Rsp)\n",
00684 #else
00685 "\tmovel %s,%Rsp@-\n",
00686 #endif
00687 reg_names[15 - i]);
00688 if (dwarf2out_do_frame ())
00689 {
00690 char *l = (char *) dwarf2out_cfi_label ();
00691
00692 cfa_store_offset += 4;
00693 if (! frame_pointer_needed)
00694 {
00695 cfa_offset = cfa_store_offset;
00696 dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, cfa_offset);
00697 }
00698 dwarf2out_reg_save (l, 15 - i, -cfa_store_offset);
00699 }
00700 }
00701 }
00702 else if (mask)
00703 {
00704 if (TARGET_5200)
00705 {
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716 int newmask = 0;
00717 int i;
00718
00719 for (i = 0; i < 16; i++)
00720 if (mask & (1 << i))
00721 newmask |= (1 << (15-i));
00722
00723 #ifdef MOTOROLA
00724 asm_fprintf (stream, "\tlea (%d,%Rsp),%Rsp\n", -num_saved_regs*4);
00725 asm_fprintf (stream, "\tmovm.l %0I0x%x,(%Rsp)\n", newmask);
00726 #else
00727 asm_fprintf (stream, "\tlea %Rsp@(%d),%Rsp\n", -num_saved_regs*4);
00728 asm_fprintf (stream, "\tmoveml %0I0x%x,%Rsp@\n", newmask);
00729 #endif
00730 }
00731 else
00732 {
00733 #ifdef MOTOROLA
00734 asm_fprintf (stream, "\tmovm.l %0I0x%x,-(%Rsp)\n", mask);
00735 #else
00736 asm_fprintf (stream, "\tmoveml %0I0x%x,%Rsp@-\n", mask);
00737 #endif
00738 }
00739 if (dwarf2out_do_frame ())
00740 {
00741 char *l = (char *) dwarf2out_cfi_label ();
00742 int n_regs;
00743
00744 cfa_store_offset += num_saved_regs * 4;
00745 if (! frame_pointer_needed)
00746 {
00747 cfa_offset = cfa_store_offset;
00748 dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, cfa_offset);
00749 }
00750 for (regno = 0, n_regs = 0; regno < 16; regno++)
00751 if (mask & (1 << (15 - regno)))
00752 dwarf2out_reg_save (l, regno,
00753 -cfa_store_offset + n_regs++ * 4);
00754 }
00755 }
00756 if (flag_pic && current_function_uses_pic_offset_table)
00757 {
00758 #ifdef MOTOROLA
00759 asm_fprintf (stream, "\t%Olea (%Rpc, %U_GLOBAL_OFFSET_TABLE_@GOTPC), %s\n",
00760 reg_names[PIC_OFFSET_TABLE_REGNUM]);
00761 #else
00762 asm_fprintf (stream, "\tmovel %0I__GLOBAL_OFFSET_TABLE_, %s\n",
00763 reg_names[PIC_OFFSET_TABLE_REGNUM]);
00764 asm_fprintf (stream, "\tlea %Rpc@(0,%s:l),%s\n",
00765 reg_names[PIC_OFFSET_TABLE_REGNUM],
00766 reg_names[PIC_OFFSET_TABLE_REGNUM]);
00767 #endif
00768 }
00769 }
00770 #endif
00771 #endif
00772 #endif
00773
00774
00775
00776 int
00777 use_return_insn ()
00778 {
00779 int regno;
00780
00781 if (!reload_completed || frame_pointer_needed || get_frame_size () != 0)
00782 return 0;
00783
00784
00785
00786
00787 for (regno = 0 ; regno < FIRST_PSEUDO_REGISTER ; regno++)
00788 if (regs_ever_live[regno] && ! call_used_regs[regno])
00789 return 0;
00790
00791 if (flag_pic && current_function_uses_pic_offset_table)
00792 return 0;
00793
00794 return 1;
00795 }
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805 #ifdef CRDS
00806
00807 static void
00808 m68k_output_function_epilogue (stream, size)
00809 FILE *stream;
00810 HOST_WIDE_INT size;
00811 {
00812 register int regno;
00813 register int mask, fmask;
00814 register int nregs;
00815 HOST_WIDE_INT offset, foffset, fpoffset;
00816 HOST_WIDE_INT fsize = ((size) + 3) & -4;
00817 int big = 0;
00818
00819 nregs = 0; fmask = 0; fpoffset = 0;
00820 for (regno = 16; regno < 24; regno++)
00821 if (regs_ever_live[regno] && ! call_used_regs[regno])
00822 {
00823 nregs++;
00824 fmask |= 1 << (23 - regno);
00825 }
00826
00827 foffset = fpoffset + nregs * 12;
00828 nregs = 0; mask = 0;
00829 if (frame_pointer_needed)
00830 regs_ever_live[FRAME_POINTER_REGNUM] = 0;
00831
00832 for (regno = 0; regno < 16; regno++)
00833 if (regs_ever_live[regno] && ! call_used_regs[regno])
00834 {
00835 nregs++;
00836 mask |= 1 << regno;
00837 }
00838
00839 offset = foffset + nregs * 4;
00840 if (offset + fsize >= 0x8000
00841 && frame_pointer_needed
00842 && (mask || fmask || fpoffset))
00843 {
00844 fprintf (stream, "\tmovel $%d,a0\n", -fsize);
00845 fsize = 0, big = 1;
00846 }
00847
00848 if (exact_log2 (mask) >= 0)
00849 {
00850 if (big)
00851 fprintf (stream, "\tmovel -%d(a6,a0.l),%s\n",
00852 offset + fsize, reg_names[exact_log2 (mask)]);
00853 else if (! frame_pointer_needed)
00854 fprintf (stream, "\tmovel (sp)+,%s\n",
00855 reg_names[exact_log2 (mask)]);
00856 else
00857 fprintf (stream, "\tmovel -%d(a6),%s\n",
00858 offset + fsize, reg_names[exact_log2 (mask)]);
00859 }
00860 else if (mask)
00861 {
00862 if (big)
00863 fprintf (stream, "\tmovem -%d(a6,a0.l),$0x%x\n",
00864 offset + fsize, mask);
00865 else if (! frame_pointer_needed)
00866 fprintf (stream, "\tmovem (sp)+,$0x%x\n", mask);
00867 else
00868 fprintf (stream, "\tmovem -%d(a6),$0x%x\n",
00869 offset + fsize, mask);
00870 }
00871
00872 if (fmask)
00873 {
00874 if (big)
00875 fprintf (stream, "\tfmovem -%d(a6,a0.l),$0x%x\n",
00876 foffset + fsize, fmask);
00877 else if (! frame_pointer_needed)
00878 fprintf (stream, "\tfmovem (sp)+,$0x%x\n", fmask);
00879 else
00880 fprintf (stream, "\tfmovem -%d(a6),$0x%x\n",
00881 foffset + fsize, fmask);
00882 }
00883
00884 if (fpoffset != 0)
00885 for (regno = 55; regno >= 24; regno--)
00886 if (regs_ever_live[regno] && ! call_used_regs[regno])
00887 {
00888 if (big)
00889 fprintf(stream, "\tfpmoved -%d(a6,a0.l), %s\n",
00890 fpoffset + fsize, reg_names[regno]);
00891 else if (! frame_pointer_needed)
00892 fprintf(stream, "\tfpmoved (sp)+, %s\n",
00893 reg_names[regno]);
00894 else
00895 fprintf(stream, "\tfpmoved -%d(a6), %s\n",
00896 fpoffset + fsize, reg_names[regno]);
00897 fpoffset -= 8;
00898 }
00899
00900 if (frame_pointer_needed)
00901 fprintf (stream, "\tunlk a6\n");
00902 else if (fsize)
00903 {
00904 if (fsize + 4 < 0x8000)
00905 fprintf (stream, "\tadd.w #%d,sp\n", fsize + 4);
00906 else
00907 fprintf (stream, "\tadd.l #%d,sp\n", fsize + 4);
00908 }
00909
00910 if (current_function_pops_args)
00911 fprintf (stream, "\trtd $%d\n", current_function_pops_args);
00912 else
00913 fprintf (stream, "\trts\n");
00914 }
00915
00916 #else
00917 #if defined (DPX2) && defined (MOTOROLA)
00918
00919 static void
00920 m68k_output_function_epilogue (stream, size)
00921 FILE *stream;
00922 HOST_WIDE_INT size;
00923 {
00924 register int regno;
00925 register int mask, fmask;
00926 register int nregs;
00927 HOST_WIDE_INT offset, foffset, fpoffset, first = 1;
00928 HOST_WIDE_INT fsize = ((size) + 3) & -4;
00929 int big = 0;
00930 rtx insn = get_last_insn ();
00931
00932
00933 if (GET_CODE (insn) == NOTE)
00934 insn = prev_nonnote_insn (insn);
00935 if (insn && GET_CODE (insn) == BARRIER)
00936 {
00937
00938
00939 fprintf (stream, "\tnop\n");
00940 return;
00941 }
00942
00943 nregs = 0; fmask = 0; fpoffset = 0;
00944 for (regno = 16; regno < 24; regno++)
00945 if (regs_ever_live[regno] && ! call_used_regs[regno])
00946 {
00947 nregs++;
00948 fmask |= 1 << (23 - regno);
00949 }
00950
00951 foffset = fpoffset + nregs * 12;
00952 nregs = 0; mask = 0;
00953 if (frame_pointer_needed)
00954 regs_ever_live[FRAME_POINTER_REGNUM] = 0;
00955
00956 for (regno = 0; regno < 16; regno++)
00957 if (regs_ever_live[regno] && ! call_used_regs[regno])
00958 {
00959 nregs++;
00960 mask |= 1 << regno;
00961 }
00962
00963 offset = foffset + nregs * 4;
00964 if (offset + fsize >= 0x8000
00965 && frame_pointer_needed
00966 && (mask || fmask || fpoffset))
00967 {
00968 fprintf (stream, "\tmove.l #%d,a0\n", -fsize);
00969 fsize = 0, big = 1;
00970 }
00971
00972 if (nregs <= 2)
00973 {
00974
00975
00976
00977
00978
00979 int i;
00980
00981
00982 for (i = 0; i< 16; i++)
00983 if (mask & (1 << i))
00984 {
00985 if (big)
00986 fprintf (stream, "\tmove.l -%d(%s,a0.l),%s\n",
00987 offset + fsize,
00988 reg_names[FRAME_POINTER_REGNUM],
00989 reg_names[i]);
00990 else if (! frame_pointer_needed)
00991 fprintf (stream, "\tmove.l (sp)+,%s\n",
00992 reg_names[i]);
00993 else
00994 fprintf (stream, "\tmove.l -%d(%s),%s\n",
00995 offset + fsize,
00996 reg_names[FRAME_POINTER_REGNUM],
00997 reg_names[i]);
00998 offset = offset - 4;
00999 }
01000 }
01001 else if (mask)
01002 {
01003 first = 1;
01004 for (regno = 0; regno < 16; regno++)
01005 if (mask & (1 << regno))
01006 {
01007 if (first && big)
01008 {
01009 fprintf (stream, "\tmovem.l -%d(%s,a0.l),%s",
01010 offset + fsize,
01011 reg_names[FRAME_POINTER_REGNUM],
01012 reg_names[regno]);
01013 first = 0;
01014 }
01015 else if (first && ! frame_pointer_needed)
01016 {
01017 fprintf (stream, "\tmovem.l (sp)+,%s",
01018 reg_names[regno]);
01019 first = 0;
01020 }
01021 else if (first)
01022 {
01023 fprintf (stream, "\tmovem.l -%d(%s),%s",
01024 offset + fsize,
01025 reg_names[FRAME_POINTER_REGNUM],
01026 reg_names[regno]);
01027 first = 0;
01028 }
01029 else
01030 fprintf (stream, "/%s", reg_names[regno]);
01031 }
01032 fprintf (stream, "\n");
01033 }
01034
01035 if (fmask)
01036 {
01037 first = 1;
01038 for (regno = 16; regno < 24; regno++)
01039 if (fmask & (1 << (23 - regno)))
01040 {
01041 if (first && big)
01042 {
01043 fprintf (stream, "\tfmovem.x -%d(%s,a0.l),%s",
01044 foffset + fsize,
01045 reg_names[FRAME_POINTER_REGNUM],
01046 reg_names[regno]);
01047 first = 0;
01048 }
01049 else if (first && ! frame_pointer_needed)
01050 {
01051 fprintf (stream, "\tfmovem.x (sp)+,%s",
01052 reg_names[regno]);
01053 first = 0;
01054 }
01055 else if (first)
01056 {
01057 fprintf (stream, "\tfmovem.x -%d(%s),%s",
01058 foffset + fsize,
01059 reg_names[FRAME_POINTER_REGNUM],
01060 reg_names[regno]);
01061 first = 0;
01062 }
01063 else
01064 fprintf (stream, "/%s", reg_names[regno]);
01065 }
01066 fprintf (stream, "\n");
01067 }
01068
01069 if (frame_pointer_needed)
01070 fprintf (stream, "\tunlk %s\n",
01071 reg_names[FRAME_POINTER_REGNUM]);
01072 else if (fsize)
01073 {
01074 if (fsize + 4 < 0x8000)
01075 fprintf (stream, "\tadd.w #%d,sp\n", fsize + 4);
01076 else
01077 fprintf (stream, "\tadd.l #%d,sp\n", fsize + 4);
01078 }
01079
01080 if (current_function_pops_args)
01081 fprintf (stream, "\trtd #%d\n", current_function_pops_args);
01082 else
01083 fprintf (stream, "\trts\n");
01084 }
01085
01086 #else
01087 #if defined (NEWS) && defined (MOTOROLA)
01088
01089 static void
01090 m68k_output_function_epilogue (stream, size)
01091 FILE *stream;
01092 HOST_WIDE_INT size;
01093 {
01094 register int regno;
01095 register int mask, fmask;
01096 register int nregs;
01097 HOST_WIDE_INT offset, foffset;
01098 HOST_WIDE_INT fsize = ((size) + 3) & -4;
01099 int big = 0;
01100
01101 nregs = 0; fmask = 0;
01102 for (regno = 16; regno < FIRST_PSEUDO_REGISTER; regno++)
01103 if (regs_ever_live[regno] && ! call_used_regs[regno])
01104 {
01105 nregs++;
01106 fmask |= 1 << (23 - regno);
01107 }
01108
01109 foffset = nregs * 12;
01110 nregs = 0; mask = 0;
01111 if (frame_pointer_needed)
01112 regs_ever_live[FRAME_POINTER_REGNUM] = 0;
01113
01114 for (regno = 0; regno < 16; regno++)
01115 if (regs_ever_live[regno] && ! call_used_regs[regno])
01116 {
01117 nregs++;
01118 mask |= 1 << regno;
01119 }
01120
01121 offset = foffset + nregs * 4;
01122 if (offset + fsize >= 0x8000
01123 && frame_pointer_needed
01124 && (mask || fmask))
01125 {
01126 fprintf (stream, "\tmove.l #%d,a0\n", -fsize);
01127 fsize = 0, big = 1;
01128 }
01129
01130 if (exact_log2 (mask) >= 0)
01131 {
01132 if (big)
01133 fprintf (stream, "\tmove.l (-%d,fp,a0.l),%s\n",
01134 offset + fsize, reg_names[exact_log2 (mask)]);
01135 else if (! frame_pointer_needed)
01136 fprintf (stream, "\tmove.l (sp)+,%s\n",
01137 reg_names[exact_log2 (mask)]);
01138 else
01139 fprintf (stream, "\tmove.l (-%d,fp),%s\n",
01140 offset + fsize, reg_names[exact_log2 (mask)]);
01141 }
01142 else if (mask)
01143 {
01144 if (big)
01145 fprintf (stream, "\tmovem.l (-%d,fp,a0.l),#0x%x\n",
01146 offset + fsize, mask);
01147 else if (! frame_pointer_needed)
01148 fprintf (stream, "\tmovem.l (sp)+,#0x%x\n", mask);
01149 else
01150 fprintf (stream, "\tmovem.l (-%d,fp),#0x%x\n",
01151 offset + fsize, mask);
01152 }
01153
01154 if (fmask)
01155 {
01156 if (big)
01157 fprintf (stream, "\tfmovem.x (-%d,fp,a0.l),#0x%x\n",
01158 foffset + fsize, fmask);
01159 else if (! frame_pointer_needed)
01160 fprintf (stream, "\tfmovem.x (sp)+,#0x%x\n", fmask);
01161 else
01162 fprintf (stream, "\tfmovem.x (-%d,fp),#0x%x\n",
01163 foffset + fsize, fmask);
01164 }
01165
01166 if (frame_pointer_needed)
01167 fprintf (stream, "\tunlk fp\n");
01168 else if (fsize)
01169 {
01170 if (fsize + 4 < 0x8000)
01171 fprintf (stream, "\tadd.w #%d,sp\n", fsize + 4);
01172 else
01173 fprintf (stream, "\tadd.l #%d,sp\n", fsize + 4);
01174 }
01175
01176 if (current_function_pops_args)
01177 fprintf (stream, "\trtd #%d\n", current_function_pops_args);
01178 else
01179 fprintf (stream, "\trts\n");
01180 }
01181
01182 #else
01183
01184 static void
01185 m68k_output_function_epilogue (stream, size)
01186 FILE *stream;
01187 HOST_WIDE_INT size;
01188 {
01189 register int regno;
01190 register int mask, fmask;
01191 register int nregs;
01192 HOST_WIDE_INT offset, foffset, fpoffset;
01193 HOST_WIDE_INT fsize = (size + 3) & -4;
01194 int big = 0;
01195 rtx insn = get_last_insn ();
01196 int restore_from_sp = 0;
01197
01198
01199 if (GET_CODE (insn) == NOTE)
01200 insn = prev_nonnote_insn (insn);
01201 if (insn && GET_CODE (insn) == BARRIER)
01202 {
01203
01204
01205 asm_fprintf (stream, "\tnop\n");
01206 return;
01207 }
01208
01209 #ifdef FUNCTION_EXTRA_EPILOGUE
01210 FUNCTION_EXTRA_EPILOGUE (stream, size);
01211 #endif
01212 nregs = 0; fmask = 0; fpoffset = 0;
01213 #ifdef SUPPORT_SUN_FPA
01214 for (regno = 24 ; regno < 56 ; regno++)
01215 if (regs_ever_live[regno] && ! call_used_regs[regno])
01216 nregs++;
01217 fpoffset = nregs * 8;
01218 #endif
01219 nregs = 0;
01220 if (TARGET_68881)
01221 {
01222 for (regno = 16; regno < 24; regno++)
01223 if (regs_ever_live[regno] && ! call_used_regs[regno])
01224 {
01225 nregs++;
01226 fmask |= 1 << (23 - regno);
01227 }
01228 }
01229 foffset = fpoffset + nregs * 12;
01230 nregs = 0; mask = 0;
01231 if (frame_pointer_needed)
01232 regs_ever_live[FRAME_POINTER_REGNUM] = 0;
01233 for (regno = 0; regno < 16; regno++)
01234 if (regs_ever_live[regno] && ! call_used_regs[regno])
01235 {
01236 nregs++;
01237 mask |= 1 << regno;
01238 }
01239 if (flag_pic && current_function_uses_pic_offset_table)
01240 {
01241 nregs++;
01242 mask |= 1 << PIC_OFFSET_TABLE_REGNUM;
01243 }
01244 offset = foffset + nregs * 4;
01245
01246
01247
01248 restore_from_sp = ! frame_pointer_needed
01249 || (! current_function_calls_alloca && leaf_function_p ());
01250 if (offset + fsize >= 0x8000
01251 && ! restore_from_sp
01252 && (mask || fmask || fpoffset))
01253 {
01254 #ifdef MOTOROLA
01255 asm_fprintf (stream, "\t%Omove.l %0I%d,%Ra1\n", -fsize);
01256 #else
01257 asm_fprintf (stream, "\tmovel %0I%d,%Ra1\n", -fsize);
01258 #endif
01259 fsize = 0, big = 1;
01260 }
01261 if (TARGET_5200 || nregs <= 2)
01262 {
01263
01264
01265
01266
01267
01268 int i;
01269
01270
01271 for (i = 0; i< 16; i++)
01272 if (mask & (1 << i))
01273 {
01274 if (big)
01275 {
01276 #ifdef MOTOROLA
01277 asm_fprintf (stream, "\t%Omove.l -%d(%s,%Ra1.l),%s\n",
01278 offset + fsize,
01279 reg_names[FRAME_POINTER_REGNUM],
01280 reg_names[i]);
01281 #else
01282 asm_fprintf (stream, "\tmovel %s@(-%d,%Ra1:l),%s\n",
01283 reg_names[FRAME_POINTER_REGNUM],
01284 offset + fsize, reg_names[i]);
01285 #endif
01286 }
01287 else if (restore_from_sp)
01288 {
01289 #ifdef MOTOROLA
01290 asm_fprintf (stream, "\t%Omove.l (%Rsp)+,%s\n",
01291 reg_names[i]);
01292 #else
01293 asm_fprintf (stream, "\tmovel %Rsp@+,%s\n",
01294 reg_names[i]);
01295 #endif
01296 }
01297 else
01298 {
01299 #ifdef MOTOROLA
01300 asm_fprintf (stream, "\t%Omove.l -%d(%s),%s\n",
01301 offset + fsize,
01302 reg_names[FRAME_POINTER_REGNUM],
01303 reg_names[i]);
01304 #else
01305 asm_fprintf (stream, "\tmovel %s@(-%d),%s\n",
01306 reg_names[FRAME_POINTER_REGNUM],
01307 offset + fsize, reg_names[i]);
01308 #endif
01309 }
01310 offset = offset - 4;
01311 }
01312 }
01313 else if (mask)
01314 {
01315 if (big)
01316 {
01317 #ifdef MOTOROLA
01318 asm_fprintf (stream, "\tmovm.l -%d(%s,%Ra1.l),%0I0x%x\n",
01319 offset + fsize,
01320 reg_names[FRAME_POINTER_REGNUM],
01321 mask);
01322 #else
01323 asm_fprintf (stream, "\tmoveml %s@(-%d,%Ra1:l),%0I0x%x\n",
01324 reg_names[FRAME_POINTER_REGNUM],
01325 offset + fsize, mask);
01326 #endif
01327 }
01328 else if (restore_from_sp)
01329 {
01330 #ifdef MOTOROLA
01331 asm_fprintf (stream, "\tmovm.l (%Rsp)+,%0I0x%x\n", mask);
01332 #else
01333 asm_fprintf (stream, "\tmoveml %Rsp@+,%0I0x%x\n", mask);
01334 #endif
01335 }
01336 else
01337 {
01338 #ifdef MOTOROLA
01339 asm_fprintf (stream, "\tmovm.l -%d(%s),%0I0x%x\n",
01340 offset + fsize,
01341 reg_names[FRAME_POINTER_REGNUM],
01342 mask);
01343 #else
01344 asm_fprintf (stream, "\tmoveml %s@(-%d),%0I0x%x\n",
01345 reg_names[FRAME_POINTER_REGNUM],
01346 offset + fsize, mask);
01347 #endif
01348 }
01349 }
01350 if (fmask)
01351 {
01352 if (big)
01353 {
01354 #ifdef MOTOROLA
01355 asm_fprintf (stream, "\tfmovm -%d(%s,%Ra1.l),%0I0x%x\n",
01356 foffset + fsize,
01357 reg_names[FRAME_POINTER_REGNUM],
01358 fmask);
01359 #else
01360 asm_fprintf (stream, "\tfmovem %s@(-%d,%Ra1:l),%0I0x%x\n",
01361 reg_names[FRAME_POINTER_REGNUM],
01362 foffset + fsize, fmask);
01363 #endif
01364 }
01365 else if (restore_from_sp)
01366 {
01367 #ifdef MOTOROLA
01368 asm_fprintf (stream, "\tfmovm (%Rsp)+,%0I0x%x\n", fmask);
01369 #else
01370 asm_fprintf (stream, "\tfmovem %Rsp@+,%0I0x%x\n", fmask);
01371 #endif
01372 }
01373 else
01374 {
01375 #ifdef MOTOROLA
01376 asm_fprintf (stream, "\tfmovm -%d(%s),%0I0x%x\n",
01377 foffset + fsize,
01378 reg_names[FRAME_POINTER_REGNUM],
01379 fmask);
01380 #else
01381 asm_fprintf (stream, "\tfmovem %s@(-%d),%0I0x%x\n",
01382 reg_names[FRAME_POINTER_REGNUM],
01383 foffset + fsize, fmask);
01384 #endif
01385 }
01386 }
01387 if (fpoffset != 0)
01388 for (regno = 55; regno >= 24; regno--)
01389 if (regs_ever_live[regno] && ! call_used_regs[regno])
01390 {
01391 if (big)
01392 {
01393 #ifdef MOTOROLA
01394 asm_fprintf (stream, "\tfpmovd -%d(%s,%Ra1.l), %s\n",
01395 fpoffset + fsize,
01396 reg_names[FRAME_POINTER_REGNUM],
01397 reg_names[regno]);
01398 #else
01399 asm_fprintf (stream, "\tfpmoved %s@(-%d,%Ra1:l), %s\n",
01400 reg_names[FRAME_POINTER_REGNUM],
01401 fpoffset + fsize, reg_names[regno]);
01402 #endif
01403 }
01404 else if (restore_from_sp)
01405 {
01406 #ifdef MOTOROLA
01407 asm_fprintf (stream, "\tfpmovd (%Rsp)+,%s\n",
01408 reg_names[regno]);
01409 #else
01410 asm_fprintf (stream, "\tfpmoved %Rsp@+, %s\n",
01411 reg_names[regno]);
01412 #endif
01413 }
01414 else
01415 {
01416 #ifdef MOTOROLA
01417 asm_fprintf (stream, "\tfpmovd -%d(%s), %s\n",
01418 fpoffset + fsize,
01419 reg_names[FRAME_POINTER_REGNUM],
01420 reg_names[regno]);
01421 #else
01422 asm_fprintf (stream, "\tfpmoved %s@(-%d), %s\n",
01423 reg_names[FRAME_POINTER_REGNUM],
01424 fpoffset + fsize, reg_names[regno]);
01425 #endif
01426 }
01427 fpoffset -= 8;
01428 }
01429 if (frame_pointer_needed)
01430 fprintf (stream, "\tunlk %s\n",
01431 reg_names[FRAME_POINTER_REGNUM]);
01432 else if (fsize)
01433 {
01434 #ifndef NO_ADDSUB_Q
01435 if (fsize + 4 <= 8)
01436 {
01437 if (!TARGET_5200)
01438 {
01439 #ifdef MOTOROLA
01440 asm_fprintf (stream, "\taddq.w %0I%d,%Rsp\n", fsize + 4);
01441 #else
01442 asm_fprintf (stream, "\taddqw %0I%d,%Rsp\n", fsize + 4);
01443 #endif
01444 }
01445 else
01446 {
01447 #ifdef MOTOROLA
01448 asm_fprintf (stream, "\taddq.l %0I%d,%Rsp\n", fsize + 4);
01449 #else
01450 asm_fprintf (stream, "\taddql %0I%d,%Rsp\n", fsize + 4);
01451 #endif
01452 }
01453 }
01454 else if (fsize + 4 <= 16 && TARGET_CPU32)
01455 {
01456
01457
01458
01459 #ifdef MOTOROLA
01460 asm_fprintf (stream, "\taddq.w %0I8,%Rsp\n\taddq.w %0I%d,%Rsp\n",
01461 fsize + 4 - 8);
01462 #else
01463 asm_fprintf (stream, "\taddqw %0I8,%Rsp\n\taddqw %0I%d,%Rsp\n",
01464 fsize + 4 - 8);
01465 #endif
01466 }
01467 else
01468 #endif
01469 if (fsize + 4 < 0x8000)
01470 {
01471 if (TARGET_68040)
01472 {
01473
01474 #ifdef MOTOROLA
01475 asm_fprintf (stream, "\tadd.w %0I%d,%Rsp\n", fsize + 4);
01476 #else
01477 asm_fprintf (stream, "\taddw %0I%d,%Rsp\n", fsize + 4);
01478 #endif
01479 }
01480 else
01481 {
01482 #ifdef MOTOROLA
01483 asm_fprintf (stream, "\tlea (%d,%Rsp),%Rsp\n", fsize + 4);
01484 #else
01485 asm_fprintf (stream, "\tlea %Rsp@(%d),%Rsp\n", fsize + 4);
01486 #endif
01487 }
01488 }
01489 else
01490 {
01491
01492 #ifdef MOTOROLA
01493 asm_fprintf (stream, "\tadd.l %0I%d,%Rsp\n", fsize + 4);
01494 #else
01495 asm_fprintf (stream, "\taddl %0I%d,%Rsp\n", fsize + 4);
01496 #endif
01497 }
01498 }
01499 if (current_function_pops_args)
01500 asm_fprintf (stream, "\trtd %0I%d\n", current_function_pops_args);
01501 else
01502 fprintf (stream, "\trts\n");
01503 }
01504
01505 #endif
01506 #endif
01507 #endif
01508
01509
01510
01511 int
01512 not_sp_operand (op, mode)
01513 register rtx op;
01514 enum machine_mode mode;
01515 {
01516 return op != stack_pointer_rtx && nonimmediate_operand (op, mode);
01517 }
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527 int
01528 valid_dbcc_comparison_p (x, mode)
01529 rtx x;
01530 enum machine_mode mode ATTRIBUTE_UNUSED;
01531 {
01532 switch (GET_CODE (x))
01533 {
01534 case EQ: case NE: case GTU: case LTU:
01535 case GEU: case LEU:
01536 return 1;
01537
01538
01539
01540 case GT: case LT: case GE: case LE:
01541 return ! (cc_prev_status.flags & CC_NO_OVERFLOW);
01542 default:
01543 return 0;
01544 }
01545 }
01546
01547
01548 int
01549 flags_in_68881 ()
01550 {
01551
01552 return cc_status.flags & CC_IN_68881;
01553 }
01554
01555
01556
01557
01558
01559
01560
01561 void
01562 output_dbcc_and_branch (operands)
01563 rtx *operands;
01564 {
01565 switch (GET_CODE (operands[3]))
01566 {
01567 case EQ:
01568 #ifdef MOTOROLA
01569 output_asm_insn ("dbeq %0,%l1\n\tjbeq %l2", operands);
01570 #else
01571 output_asm_insn ("dbeq %0,%l1\n\tjeq %l2", operands);
01572 #endif
01573 break;
01574
01575 case NE:
01576 #ifdef MOTOROLA
01577 output_asm_insn ("dbne %0,%l1\n\tjbne %l2", operands);
01578 #else
01579 output_asm_insn ("dbne %0,%l1\n\tjne %l2", operands);
01580 #endif
01581 break;
01582
01583 case GT:
01584 #ifdef MOTOROLA
01585 output_asm_insn ("dbgt %0,%l1\n\tjbgt %l2", operands);
01586 #else
01587 output_asm_insn ("dbgt %0,%l1\n\tjgt %l2", operands);
01588 #endif
01589 break;
01590
01591 case GTU:
01592 #ifdef MOTOROLA
01593 output_asm_insn ("dbhi %0,%l1\n\tjbhi %l2", operands);
01594 #else
01595 output_asm_insn ("dbhi %0,%l1\n\tjhi %l2", operands);
01596 #endif
01597 break;
01598
01599 case LT:
01600 #ifdef MOTOROLA
01601 output_asm_insn ("dblt %0,%l1\n\tjblt %l2", operands);
01602 #else
01603 output_asm_insn ("dblt %0,%l1\n\tjlt %l2", operands);
01604 #endif
01605 break;
01606
01607 case LTU:
01608 #ifdef MOTOROLA
01609 output_asm_insn ("dbcs %0,%l1\n\tjbcs %l2", operands);
01610 #else
01611 output_asm_insn ("dbcs %0,%l1\n\tjcs %l2", operands);
01612 #endif
01613 break;
01614
01615 case GE:
01616 #ifdef MOTOROLA
01617 output_asm_insn ("dbge %0,%l1\n\tjbge %l2", operands);
01618 #else
01619 output_asm_insn ("dbge %0,%l1\n\tjge %l2", operands);
01620 #endif
01621 break;
01622
01623 case GEU:
01624 #ifdef MOTOROLA
01625 output_asm_insn ("dbcc %0,%l1\n\tjbcc %l2", operands);
01626 #else
01627 output_asm_insn ("dbcc %0,%l1\n\tjcc %l2", operands);
01628 #endif
01629 break;
01630
01631 case LE:
01632 #ifdef MOTOROLA
01633 output_asm_insn ("dble %0,%l1\n\tjble %l2", operands);
01634 #else
01635 output_asm_insn ("dble %0,%l1\n\tjle %l2", operands);
01636 #endif
01637 break;
01638
01639 case LEU:
01640 #ifdef MOTOROLA
01641 output_asm_insn ("dbls %0,%l1\n\tjbls %l2", operands);
01642 #else
01643 output_asm_insn ("dbls %0,%l1\n\tjls %l2", operands);
01644 #endif
01645 break;
01646
01647 default:
01648 abort ();
01649 }
01650
01651
01652
01653 switch (GET_MODE (operands[0]))
01654 {
01655 case SImode:
01656 #ifdef MOTOROLA
01657 output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjbpl %l1", operands);
01658 #else
01659 output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjpl %l1", operands);
01660 #endif
01661 break;
01662
01663 case HImode:
01664 break;
01665
01666 default:
01667 abort ();
01668 }
01669 }
01670
01671 const char *
01672 output_scc_di(op, operand1, operand2, dest)
01673 rtx op;
01674 rtx operand1;
01675 rtx operand2;
01676 rtx dest;
01677 {
01678 rtx loperands[7];
01679 enum rtx_code op_code = GET_CODE (op);
01680
01681
01682 CC_STATUS_INIT;
01683
01684
01685
01686
01687 if (GET_CODE (operand2) == REG && GET_CODE (operand1) != REG)
01688 {
01689 rtx tmp = operand1;
01690
01691 operand1 = operand2;
01692 operand2 = tmp;
01693 op_code = swap_condition (op_code);
01694 }
01695 loperands[0] = operand1;
01696 if (GET_CODE (operand1) == REG)
01697 loperands[1] = gen_rtx_REG (SImode, REGNO (operand1) + 1);
01698 else
01699 loperands[1] = adjust_address (operand1, SImode, 4);
01700 if (operand2 != const0_rtx)
01701 {
01702 loperands[2] = operand2;
01703 if (GET_CODE (operand2) == REG)
01704 loperands[3] = gen_rtx_REG (SImode, REGNO (operand2) + 1);
01705 else
01706 loperands[3] = adjust_address (operand2, SImode, 4);
01707 }
01708 loperands[4] = gen_label_rtx();
01709 if (operand2 != const0_rtx)
01710 {
01711 #ifdef MOTOROLA
01712 #ifdef SGS_CMP_ORDER
01713 output_asm_insn ("cmp%.l %0,%2\n\tjbne %l4\n\tcmp%.l %1,%3", loperands);
01714 #else
01715 output_asm_insn ("cmp%.l %2,%0\n\tjbne %l4\n\tcmp%.l %3,%1", loperands);
01716 #endif
01717 #else
01718 #ifdef SGS_CMP_ORDER
01719 output_asm_insn ("cmp%.l %0,%2\n\tjne %l4\n\tcmp%.l %1,%3", loperands);
01720 #else
01721 output_asm_insn ("cmp%.l %2,%0\n\tjne %l4\n\tcmp%.l %3,%1", loperands);
01722 #endif
01723 #endif
01724 }
01725 else
01726 {
01727 if (TARGET_68020 || TARGET_5200 || ! ADDRESS_REG_P (loperands[0]))
01728 output_asm_insn ("tst%.l %0", loperands);
01729 else
01730 {
01731 #ifdef SGS_CMP_ORDER
01732 output_asm_insn ("cmp%.w %0,%#0", loperands);
01733 #else
01734 output_asm_insn ("cmp%.w %#0,%0", loperands);
01735 #endif
01736 }
01737
01738 #ifdef MOTOROLA
01739 output_asm_insn ("jbne %l4", loperands);
01740 #else
01741 output_asm_insn ("jne %l4", loperands);
01742 #endif
01743
01744 if (TARGET_68020 || TARGET_5200 || ! ADDRESS_REG_P (loperands[1]))
01745 output_asm_insn ("tst%.l %1", loperands);
01746 else
01747 {
01748 #ifdef SGS_CMP_ORDER
01749 output_asm_insn ("cmp%.w %1,%#0", loperands);
01750 #else
01751 output_asm_insn ("cmp%.w %#0,%1", loperands);
01752 #endif
01753 }
01754 }
01755
01756 loperands[5] = dest;
01757
01758 switch (op_code)
01759 {
01760 case EQ:
01761 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
01762 CODE_LABEL_NUMBER (loperands[4]));
01763 output_asm_insn ("seq %5", loperands);
01764 break;
01765
01766 case NE:
01767 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
01768 CODE_LABEL_NUMBER (loperands[4]));
01769 output_asm_insn ("sne %5", loperands);
01770 break;
01771
01772 case GT:
01773 loperands[6] = gen_label_rtx();
01774 #ifdef MOTOROLA
01775 output_asm_insn ("shi %5\n\tjbra %l6", loperands);
01776 #else
01777 output_asm_insn ("shi %5\n\tjra %l6", loperands);
01778 #endif
01779 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
01780 CODE_LABEL_NUMBER (loperands[4]));
01781 output_asm_insn ("sgt %5", loperands);
01782 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
01783 CODE_LABEL_NUMBER (loperands[6]));
01784 break;
01785
01786 case GTU:
01787 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
01788 CODE_LABEL_NUMBER (loperands[4]));
01789 output_asm_insn ("shi %5", loperands);
01790 break;
01791
01792 case LT:
01793 loperands[6] = gen_label_rtx();
01794 #ifdef MOTOROLA
01795 output_asm_insn ("scs %5\n\tjbra %l6", loperands);
01796 #else
01797 output_asm_insn ("scs %5\n\tjra %l6", loperands);
01798 #endif
01799 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
01800 CODE_LABEL_NUMBER (loperands[4]));
01801 output_asm_insn ("slt %5", loperands);
01802 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
01803 CODE_LABEL_NUMBER (loperands[6]));
01804 break;
01805
01806 case LTU:
01807 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
01808 CODE_LABEL_NUMBER (loperands[4]));
01809 output_asm_insn ("scs %5", loperands);
01810 break;
01811
01812 case GE:
01813 loperands[6] = gen_label_rtx();
01814 #ifdef MOTOROLA
01815 output_asm_insn ("scc %5\n\tjbra %l6", loperands);
01816 #else
01817 output_asm_insn ("scc %5\n\tjra %l6", loperands);
01818 #endif
01819 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
01820 CODE_LABEL_NUMBER (loperands[4]));
01821 output_asm_insn ("sge %5", loperands);
01822 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
01823 CODE_LABEL_NUMBER (loperands[6]));
01824 break;
01825
01826 case GEU:
01827 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
01828 CODE_LABEL_NUMBER (loperands[4]));
01829 output_asm_insn ("scc %5", loperands);
01830 break;
01831
01832 case LE:
01833 loperands[6] = gen_label_rtx();
01834 #ifdef MOTOROLA
01835 output_asm_insn ("sls %5\n\tjbra %l6", loperands);
01836 #else
01837 output_asm_insn ("sls %5\n\tjra %l6", loperands);
01838 #endif
01839 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
01840 CODE_LABEL_NUMBER (loperands[4]));
01841 output_asm_insn ("sle %5", loperands);
01842 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
01843 CODE_LABEL_NUMBER (loperands[6]));
01844 break;
01845
01846 case LEU:
01847 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
01848 CODE_LABEL_NUMBER (loperands[4]));
01849 output_asm_insn ("sls %5", loperands);
01850 break;
01851
01852 default:
01853 abort ();
01854 }
01855 return "";
01856 }
01857
01858 const char *
01859 output_btst (operands, countop, dataop, insn, signpos)
01860 rtx *operands;
01861 rtx countop, dataop;
01862 rtx insn;
01863 int signpos;
01864 {
01865 operands[0] = countop;
01866 operands[1] = dataop;
01867
01868 if (GET_CODE (countop) == CONST_INT)
01869 {
01870 register int count = INTVAL (countop);
01871
01872
01873 if (count > signpos)
01874 {
01875 int offset = (count & ~signpos) / 8;
01876 count = count & signpos;
01877 operands[1] = dataop = adjust_address (dataop, QImode, offset);
01878 }
01879 if (count == signpos)
01880 cc_status.flags = CC_NOT_POSITIVE | CC_Z_IN_NOT_N;
01881 else
01882 cc_status.flags = CC_NOT_NEGATIVE | CC_Z_IN_NOT_N;
01883
01884
01885
01886 if (count == 31
01887 && next_insn_tests_no_inequality (insn))
01888 return "tst%.l %1";
01889 if (count == 15
01890 && next_insn_tests_no_inequality (insn))
01891 return "tst%.w %1";
01892 if (count == 7
01893 && next_insn_tests_no_inequality (insn))
01894 return "tst%.b %1";
01895
01896 cc_status.flags = CC_NOT_NEGATIVE;
01897 }
01898 return "btst %0,%1";
01899 }
01900
01901
01902
01903
01904 int
01905 symbolic_operand (op, mode)
01906 register rtx op;
01907 enum machine_mode mode ATTRIBUTE_UNUSED;
01908 {
01909 switch (GET_CODE (op))
01910 {
01911 case SYMBOL_REF:
01912 case LABEL_REF:
01913 return 1;
01914
01915 case CONST:
01916 op = XEXP (op, 0);
01917 return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
01918 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
01919 && GET_CODE (XEXP (op, 1)) == CONST_INT);
01920
01921 #if 0
01922
01923 case CONST_DOUBLE:
01924 return GET_MODE (op) == mode;
01925 #endif
01926
01927 default:
01928 return 0;
01929 }
01930 }
01931
01932
01933
01934 int
01935 extend_operator(x, mode)
01936 rtx x;
01937 enum machine_mode mode;
01938 {
01939 if (mode != VOIDmode && GET_MODE(x) != mode)
01940 return 0;
01941 switch (GET_CODE(x))
01942 {
01943 case SIGN_EXTEND :
01944 case ZERO_EXTEND :
01945 return 1;
01946 default :
01947 return 0;
01948 }
01949 }
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
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 rtx
01993 legitimize_pic_address (orig, mode, reg)
01994 rtx orig, reg;
01995 enum machine_mode mode ATTRIBUTE_UNUSED;
01996 {
01997 rtx pic_ref = orig;
01998
01999
02000 if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF)
02001 {
02002 if (reg == 0)
02003 abort ();
02004
02005 pic_ref = gen_rtx_MEM (Pmode,
02006 gen_rtx_PLUS (Pmode,
02007 pic_offset_table_rtx, orig));
02008 current_function_uses_pic_offset_table = 1;
02009 RTX_UNCHANGING_P (pic_ref) = 1;
02010 emit_move_insn (reg, pic_ref);
02011 return reg;
02012 }
02013 else if (GET_CODE (orig) == CONST)
02014 {
02015 rtx base;
02016
02017
02018 if (GET_CODE (XEXP (orig, 0)) == PLUS
02019 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
02020 return orig;
02021
02022 if (reg == 0)
02023 abort ();
02024
02025
02026 if (GET_CODE (XEXP (orig, 0)) == PLUS)
02027 {
02028 base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
02029 orig = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
02030 base == reg ? 0 : reg);
02031 }
02032 else abort ();
02033
02034 if (GET_CODE (orig) == CONST_INT)
02035 return plus_constant (base, INTVAL (orig));
02036 pic_ref = gen_rtx_PLUS (Pmode, base, orig);
02037
02038 }
02039 return pic_ref;
02040 }
02041
02042
02043 typedef enum { MOVL, SWAP, NEGW, NOTW, NOTB, MOVQ } CONST_METHOD;
02044
02045 static CONST_METHOD const_method PARAMS ((rtx));
02046
02047 #define USE_MOVQ(i) ((unsigned)((i) + 128) <= 255)
02048
02049 static CONST_METHOD
02050 const_method (constant)
02051 rtx constant;
02052 {
02053 int i;
02054 unsigned u;
02055
02056 i = INTVAL (constant);
02057 if (USE_MOVQ (i))
02058 return MOVQ;
02059
02060
02061
02062 if (!TARGET_5200)
02063 {
02064
02065
02066 if (USE_MOVQ (i ^ 0xff))
02067 return NOTB;
02068
02069 if (USE_MOVQ (i ^ 0xffff))
02070 return NOTW;
02071
02072 if (i == -65408)
02073 return NEGW;
02074
02075 u = i;
02076 if (USE_MOVQ ((u >> 16) | (u << 16)))
02077 return SWAP;
02078 }
02079
02080 return MOVL;
02081 }
02082
02083 int
02084 const_int_cost (constant)
02085 rtx constant;
02086 {
02087 switch (const_method (constant))
02088 {
02089 case MOVQ :
02090
02091 return 0;
02092 case NOTB :
02093 case NOTW :
02094 case NEGW :
02095 case SWAP :
02096
02097 return 1;
02098 case MOVL :
02099 return 2;
02100 default :
02101 abort ();
02102 }
02103 }
02104
02105 const char *
02106 output_move_const_into_data_reg (operands)
02107 rtx *operands;
02108 {
02109 int i;
02110
02111 i = INTVAL (operands[1]);
02112 switch (const_method (operands[1]))
02113 {
02114 case MOVQ :
02115 #if defined (MOTOROLA) && !defined (CRDS)
02116 return "moveq%.l %1,%0";
02117 #else
02118 return "moveq %1,%0";
02119 #endif
02120 case NOTB :
02121 operands[1] = GEN_INT (i ^ 0xff);
02122 #if defined (MOTOROLA) && !defined (CRDS)
02123 return "moveq%.l %1,%0\n\tnot%.b %0";
02124 #else
02125 return "moveq %1,%0\n\tnot%.b %0";
02126 #endif
02127 case NOTW :
02128 operands[1] = GEN_INT (i ^ 0xffff);
02129 #if defined (MOTOROLA) && !defined (CRDS)
02130 return "moveq%.l %1,%0\n\tnot%.w %0";
02131 #else
02132 return "moveq %1,%0\n\tnot%.w %0";
02133 #endif
02134 case NEGW :
02135 #if defined (MOTOROLA) && !defined (CRDS)
02136 return "moveq%.l %#-128,%0\n\tneg%.w %0";
02137 #else
02138 return "moveq %#-128,%0\n\tneg%.w %0";
02139 #endif
02140 case SWAP :
02141 {
02142 unsigned u = i;
02143
02144 operands[1] = GEN_INT ((u << 16) | (u >> 16));
02145 #if defined (MOTOROLA) && !defined (CRDS)
02146 return "moveq%.l %1,%0\n\tswap %0";
02147 #else
02148 return "moveq %1,%0\n\tswap %0";
02149 #endif
02150 }
02151 case MOVL :
02152 return "move%.l %1,%0";
02153 default :
02154 abort ();
02155 }
02156 }
02157
02158 const char *
02159 output_move_simode_const (operands)
02160 rtx *operands;
02161 {
02162 if (operands[1] == const0_rtx
02163 && (DATA_REG_P (operands[0])
02164 || GET_CODE (operands[0]) == MEM)
02165
02166
02167 && ((TARGET_68020 || TARGET_5200)
02168 || !(GET_CODE (operands[0]) == MEM
02169 && MEM_VOLATILE_P (operands[0]))))
02170 return "clr%.l %0";
02171 else if (operands[1] == const0_rtx
02172 && ADDRESS_REG_P (operands[0]))
02173 return "sub%.l %0,%0";
02174 else if (DATA_REG_P (operands[0]))
02175 return output_move_const_into_data_reg (operands);
02176 else if (ADDRESS_REG_P (operands[0])
02177 && INTVAL (operands[1]) < 0x8000
02178 && INTVAL (operands[1]) >= -0x8000)
02179 return "move%.w %1,%0";
02180 else if (GET_CODE (operands[0]) == MEM
02181 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
02182 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
02183 && INTVAL (operands[1]) < 0x8000
02184 && INTVAL (operands[1]) >= -0x8000)
02185 return "pea %a1";
02186 return "move%.l %1,%0";
02187 }
02188
02189 const char *
02190 output_move_simode (operands)
02191 rtx *operands;
02192 {
02193 if (GET_CODE (operands[1]) == CONST_INT)
02194 return output_move_simode_const (operands);
02195 else if ((GET_CODE (operands[1]) == SYMBOL_REF
02196 || GET_CODE (operands[1]) == CONST)
02197 && push_operand (operands[0], SImode))
02198 return "pea %a1";
02199 else if ((GET_CODE (operands[1]) == SYMBOL_REF
02200 || GET_CODE (operands[1]) == CONST)
02201 && ADDRESS_REG_P (operands[0]))
02202 return "lea %a1,%0";
02203 return "move%.l %1,%0";
02204 }
02205
02206 const char *
02207 output_move_himode (operands)
02208 rtx *operands;
02209 {
02210 if (GET_CODE (operands[1]) == CONST_INT)
02211 {
02212 if (operands[1] == const0_rtx
02213 && (DATA_REG_P (operands[0])
02214 || GET_CODE (operands[0]) == MEM)
02215
02216
02217 && ((TARGET_68020 || TARGET_5200)
02218 || !(GET_CODE (operands[0]) == MEM
02219 && MEM_VOLATILE_P (operands[0]))))
02220 return "clr%.w %0";
02221 else if (operands[1] == const0_rtx
02222 && ADDRESS_REG_P (operands[0]))
02223 return "sub%.l %0,%0";
02224 else if (DATA_REG_P (operands[0])
02225 && INTVAL (operands[1]) < 128
02226 && INTVAL (operands[1]) >= -128)
02227 {
02228 #if defined(MOTOROLA) && !defined(CRDS)
02229 return "moveq%.l %1,%0";
02230 #else
02231 return "moveq %1,%0";
02232 #endif
02233 }
02234 else if (INTVAL (operands[1]) < 0x8000
02235 && INTVAL (operands[1]) >= -0x8000)
02236 return "move%.w %1,%0";
02237 }
02238 else if (CONSTANT_P (operands[1]))
02239 return "move%.l %1,%0";
02240 #ifndef SGS_NO_LI
02241
02242
02243
02244
02245
02246
02247 if (GET_CODE (operands[1]) == MEM
02248 && GET_CODE (XEXP (operands[1], 0)) == PLUS
02249 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == LABEL_REF
02250 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) != PLUS)
02251 {
02252 rtx labelref = XEXP (XEXP (operands[1], 0), 1);
02253 #if defined (MOTOROLA) && !defined (SGS_SWITCH_TABLES)
02254 #ifdef SGS
02255 asm_fprintf (asm_out_file, "\tset %LLI%d,.+2\n",
02256 CODE_LABEL_NUMBER (XEXP (labelref, 0)));
02257 #else
02258 asm_fprintf (asm_out_file, "\t.set %LLI%d,.+2\n",
02259 CODE_LABEL_NUMBER (XEXP (labelref, 0)));
02260 #endif
02261 #else
02262 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LI",
02263 CODE_LABEL_NUMBER (XEXP (labelref, 0)));
02264 #ifdef SGS_SWITCH_TABLES
02265
02266
02267 switch_table_difference_label_flag = 1;
02268 #endif
02269 #endif
02270 }
02271 #endif
02272 return "move%.w %1,%0";
02273 }
02274
02275 const char *
02276 output_move_qimode (operands)
02277 rtx *operands;
02278 {
02279 rtx xoperands[4];
02280
02281
02282
02283
02284
02285 if (GET_CODE (operands[0]) == MEM
02286 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
02287 && XEXP (XEXP (operands[0], 0), 0) == stack_pointer_rtx
02288 && ! ADDRESS_REG_P (operands[1])
02289 && ! TARGET_5200)
02290 {
02291 xoperands[1] = operands[1];
02292 xoperands[2]
02293 = gen_rtx_MEM (QImode,
02294 gen_rtx_PLUS (VOIDmode, stack_pointer_rtx, const1_rtx));
02295
02296
02297 if (!reg_mentioned_p (stack_pointer_rtx, operands[1]))
02298 {
02299 xoperands[3] = stack_pointer_rtx;
02300 #ifndef NO_ADDSUB_Q
02301 output_asm_insn ("subq%.l %#2,%3\n\tmove%.b %1,%2", xoperands);
02302 #else
02303 output_asm_insn ("sub%.l %#2,%3\n\tmove%.b %1,%2", xoperands);
02304 #endif
02305 }
02306 else
02307 output_asm_insn ("move%.b %1,%-\n\tmove%.b %@,%2", xoperands);
02308 return "";
02309 }
02310
02311
02312
02313 if (!ADDRESS_REG_P (operands[0])
02314 && ((TARGET_68020 || TARGET_5200)
02315 || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
02316 {
02317 if (operands[1] == const0_rtx)
02318 return "clr%.b %0";
02319 if ((!TARGET_5200 || DATA_REG_P (operands[0]))
02320 && GET_CODE (operands[1]) == CONST_INT
02321 && (INTVAL (operands[1]) & 255) == 255)
02322 {
02323 CC_STATUS_INIT;
02324 return "st %0";
02325 }
02326 }
02327 if (GET_CODE (operands[1]) == CONST_INT
02328 && DATA_REG_P (operands[0])
02329 && INTVAL (operands[1]) < 128
02330 && INTVAL (operands[1]) >= -128)
02331 {
02332 #if defined(MOTOROLA) && !defined(CRDS)
02333 return "moveq%.l %1,%0";
02334 #else
02335 return "moveq %1,%0";
02336 #endif
02337 }
02338 if (operands[1] == const0_rtx && ADDRESS_REG_P (operands[0]))
02339 return "sub%.l %0,%0";
02340 if (GET_CODE (operands[1]) != CONST_INT && CONSTANT_P (operands[1]))
02341 return "move%.l %1,%0";
02342
02343
02344 if (ADDRESS_REG_P (operands[0]) || ADDRESS_REG_P (operands[1]))
02345 return "move%.w %1,%0";
02346 return "move%.b %1,%0";
02347 }
02348
02349 const char *
02350 output_move_stricthi (operands)
02351 rtx *operands;
02352 {
02353 if (operands[1] == const0_rtx
02354
02355
02356 && ((TARGET_68020 || TARGET_5200)
02357 || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
02358 return "clr%.w %0";
02359 return "move%.w %1,%0";
02360 }
02361
02362 const char *
02363 output_move_strictqi (operands)
02364 rtx *operands;
02365 {
02366 if (operands[1] == const0_rtx
02367
02368
02369 && ((TARGET_68020 || TARGET_5200)
02370 || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
02371 return "clr%.b %0";
02372 return "move%.b %1,%0";
02373 }
02374
02375
02376
02377
02378 static const char *
02379 singlemove_string (operands)
02380 rtx *operands;
02381 {
02382 #ifdef SUPPORT_SUN_FPA
02383 if (FPA_REG_P (operands[0]) || FPA_REG_P (operands[1]))
02384 return "fpmoves %1,%0";
02385 #endif
02386 if (GET_CODE (operands[1]) == CONST_INT)
02387 return output_move_simode_const (operands);
02388 return "move%.l %1,%0";
02389 }
02390
02391
02392
02393
02394
02395 const char *
02396 output_move_double (operands)
02397 rtx *operands;
02398 {
02399 enum
02400 {
02401 REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP
02402 } optype0, optype1;
02403 rtx latehalf[2];
02404 rtx middlehalf[2];
02405 rtx xops[2];
02406 rtx addreg0 = 0, addreg1 = 0;
02407 int dest_overlapped_low = 0;
02408 int size = GET_MODE_SIZE (GET_MODE (operands[0]));
02409
02410 middlehalf[0] = 0;
02411 middlehalf[1] = 0;
02412
02413
02414
02415 if (REG_P (operands[0]))
02416 optype0 = REGOP;
02417 else if (offsettable_memref_p (operands[0]))
02418 optype0 = OFFSOP;
02419 else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
02420 optype0 = POPOP;
02421 else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
02422 optype0 = PUSHOP;
02423 else if (GET_CODE (operands[0]) == MEM)
02424 optype0 = MEMOP;
02425 else
02426 optype0 = RNDOP;
02427
02428 if (REG_P (operands[1]))
02429 optype1 = REGOP;
02430 else if (CONSTANT_P (operands[1]))
02431 optype1 = CNSTOP;
02432 else if (offsettable_memref_p (operands[1]))
02433 optype1 = OFFSOP;
02434 else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
02435 optype1 = POPOP;
02436 else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
02437 optype1 = PUSHOP;
02438 else if (GET_CODE (operands[1]) == MEM)
02439 optype1 = MEMOP;
02440 else
02441 optype1 = RNDOP;
02442
02443
02444
02445
02446
02447 if (optype0 == RNDOP || optype1 == RNDOP)
02448 abort ();
02449
02450
02451
02452
02453
02454 if (optype0 == PUSHOP && optype1 == POPOP)
02455 {
02456 operands[0] = XEXP (XEXP (operands[0], 0), 0);
02457 if (size == 12)
02458 output_asm_insn ("sub%.l %#12,%0", operands);
02459 else
02460 output_asm_insn ("subq%.l %#8,%0", operands);
02461 if (GET_MODE (operands[1]) == XFmode)
02462 operands[0] = gen_rtx_MEM (XFmode, operands[0]);
02463 else if (GET_MODE (operands[0]) == DFmode)
02464 operands[0] = gen_rtx_MEM (DFmode, operands[0]);
02465 else
02466 operands[0] = gen_rtx_MEM (DImode, operands[0]);
02467 optype0 = OFFSOP;
02468 }
02469 if (optype0 == POPOP && optype1 == PUSHOP)
02470 {
02471 operands[1] = XEXP (XEXP (operands[1], 0), 0);
02472 if (size == 12)
02473 output_asm_insn ("sub%.l %#12,%1", operands);
02474 else
02475 output_asm_insn ("subq%.l %#8,%1", operands);
02476 if (GET_MODE (operands[1]) == XFmode)
02477 operands[1] = gen_rtx_MEM (XFmode, operands[1]);
02478 else if (GET_MODE (operands[1]) == DFmode)
02479 operands[1] = gen_rtx_MEM (DFmode, operands[1]);
02480 else
02481 operands[1] = gen_rtx_MEM (DImode, operands[1]);
02482 optype1 = OFFSOP;
02483 }
02484
02485
02486
02487
02488 if (optype0 == MEMOP)
02489 addreg0 = find_addr_reg (XEXP (operands[0], 0));
02490
02491 if (optype1 == MEMOP)
02492 addreg1 = find_addr_reg (XEXP (operands[1], 0));
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502
02503 if (size == 12)
02504 {
02505 if (optype0 == REGOP)
02506 {
02507 latehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 2);
02508 middlehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
02509 }
02510 else if (optype0 == OFFSOP)
02511 {
02512 middlehalf[0] = adjust_address (operands[0], SImode, 4);
02513 latehalf[0] = adjust_address (operands[0], SImode, size - 4);
02514 }
02515 else
02516 {
02517 middlehalf[0] = operands[0];
02518 latehalf[0] = operands[0];
02519 }
02520
02521 if (optype1 == REGOP)
02522 {
02523 latehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
02524 middlehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
02525 }
02526 else if (optype1 == OFFSOP)
02527 {
02528 middlehalf[1] = adjust_address (operands[1], SImode, 4);
02529 latehalf[1] = adjust_address (operands[1], SImode, size - 4);
02530 }
02531 else if (optype1 == CNSTOP)
02532 {
02533 if (GET_CODE (operands[1]) == CONST_DOUBLE)
02534 {
02535 REAL_VALUE_TYPE r;
02536 long l[3];
02537
02538 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
02539 REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l);
02540 operands[1] = GEN_INT (l[0]);
02541 middlehalf[1] = GEN_INT (l[1]);
02542 latehalf[1] = GEN_INT (l[2]);
02543 }
02544 else if (CONSTANT_P (operands[1]))
02545 {
02546
02547
02548 abort ();
02549 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
02550 latehalf[1] = constm1_rtx;
02551 else
02552 latehalf[1] = const0_rtx;
02553 }
02554 }
02555 else
02556 {
02557 middlehalf[1] = operands[1];
02558 latehalf[1] = operands[1];
02559 }
02560 }
02561 else
02562
02563 {
02564 if (optype0 == REGOP)
02565 latehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
02566 else if (optype0 == OFFSOP)
02567 latehalf[0] = adjust_address (operands[0], SImode, size - 4);
02568 else
02569 latehalf[0] = operands[0];
02570
02571 if (optype1 == REGOP)
02572 latehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
02573 else if (optype1 == OFFSOP)
02574 latehalf[1] = adjust_address (operands[1], SImode, size - 4);
02575 else if (optype1 == CNSTOP)
02576 split_double (operands[1], &operands[1], &latehalf[1]);
02577 else
02578 latehalf[1] = operands[1];
02579 }
02580
02581
02582
02583
02584 if (optype0 == PUSHOP
02585 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
02586 && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
02587 operands[1] = middlehalf[1] = latehalf[1];
02588
02589
02590
02591
02592
02593
02594 if (optype0 == REGOP
02595 && (optype1 == OFFSOP || optype1 == MEMOP))
02596 {
02597 rtx testlow = gen_rtx_REG (SImode, REGNO (operands[0]));
02598
02599 if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0))
02600 && reg_overlap_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
02601 {
02602
02603
02604
02605 compadr:
02606 xops[0] = latehalf[0];
02607 xops[1] = XEXP (operands[1], 0);
02608 output_asm_insn ("lea %a1,%0", xops);
02609 if (GET_MODE (operands[1]) == XFmode )
02610 {
02611 operands[1] = gen_rtx_MEM (XFmode, latehalf[0]);
02612 middlehalf[1] = adjust_address (operands[1], DImode, size - 8);
02613 latehalf[1] = adjust_address (operands[1], DImode, size - 4);
02614 }
02615 else
02616 {
02617 operands[1] = gen_rtx_MEM (DImode, latehalf[0]);
02618 latehalf[1] = adjust_address (operands[1], DImode, size - 4);
02619 }
02620 }
02621 else if (size == 12
02622 && reg_overlap_mentioned_p (middlehalf[0],
02623 XEXP (operands[1], 0)))
02624 {
02625
02626
02627
02628
02629
02630
02631 if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0))
02632 || reg_overlap_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
02633 goto compadr;
02634
02635
02636 if (addreg0 || addreg1)
02637 abort ();
02638
02639
02640 output_asm_insn (singlemove_string (operands), operands);
02641 output_asm_insn (singlemove_string (latehalf), latehalf);
02642 output_asm_insn (singlemove_string (middlehalf), middlehalf);
02643 return "";
02644 }
02645 else if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0)))
02646
02647
02648 dest_overlapped_low = 1;
02649 }
02650
02651
02652
02653
02654
02655
02656
02657
02658
02659 if (optype0 == PUSHOP || optype1 == PUSHOP
02660 || (optype0 == REGOP && optype1 == REGOP
02661 && ((middlehalf[1] && REGNO (operands[0]) == REGNO (middlehalf[1]))
02662 || REGNO (operands[0]) == REGNO (latehalf[1])))
02663 || dest_overlapped_low)
02664 {
02665
02666 if (addreg0)
02667 {
02668 if (size == 12)
02669 output_asm_insn ("addq%.l %#8,%0", &addreg0);
02670 else
02671 output_asm_insn ("addq%.l %#4,%0", &addreg0);
02672 }
02673 if (addreg1)
02674 {
02675 if (size == 12)
02676 output_asm_insn ("addq%.l %#8,%0", &addreg1);
02677 else
02678 output_asm_insn ("addq%.l %#4,%0", &addreg1);
02679 }
02680
02681
02682 output_asm_insn (singlemove_string (latehalf), latehalf);
02683
02684
02685 if (addreg0)
02686 output_asm_insn ("subq%.l %#4,%0", &addreg0);
02687 if (addreg1)
02688 output_asm_insn ("subq%.l %#4,%0", &addreg1);
02689
02690 if (size == 12)
02691 {
02692 output_asm_insn (singlemove_string (middlehalf), middlehalf);
02693 if (addreg0)
02694 output_asm_insn ("subq%.l %#4,%0", &addreg0);
02695 if (addreg1)
02696 output_asm_insn ("subq%.l %#4,%0", &addreg1);
02697 }
02698
02699
02700 return singlemove_string (operands);
02701 }
02702
02703
02704
02705 output_asm_insn (singlemove_string (operands), operands);
02706
02707
02708 if (size == 12)
02709 {
02710 if (addreg0)
02711 output_asm_insn ("addq%.l %#4,%0", &addreg0);
02712 if (addreg1)
02713 output_asm_insn ("addq%.l %#4,%0", &addreg1);
02714
02715 output_asm_insn (singlemove_string (middlehalf), middlehalf);
02716 }
02717
02718
02719 if (addreg0)
02720 output_asm_insn ("addq%.l %#4,%0", &addreg0);
02721 if (addreg1)
02722 output_asm_insn ("addq%.l %#4,%0", &addreg1);
02723
02724
02725 output_asm_insn (singlemove_string (latehalf), latehalf);
02726
02727
02728 if (addreg0)
02729 {
02730 if (size == 12)
02731 output_asm_insn ("subq%.l %#8,%0", &addreg0);
02732 else
02733 output_asm_insn ("subq%.l %#4,%0", &addreg0);
02734 }
02735 if (addreg1)
02736 {
02737 if (size == 12)
02738 output_asm_insn ("subq%.l %#8,%0", &addreg1);
02739 else
02740 output_asm_insn ("subq%.l %#4,%0", &addreg1);
02741 }
02742
02743 return "";
02744 }
02745
02746
02747
02748
02749 static rtx
02750 find_addr_reg (addr)
02751 rtx addr;
02752 {
02753 while (GET_CODE (addr) == PLUS)
02754 {
02755 if (GET_CODE (XEXP (addr, 0)) == REG)
02756 addr = XEXP (addr, 0);
02757 else if (GET_CODE (XEXP (addr, 1)) == REG)
02758 addr = XEXP (addr, 1);
02759 else if (CONSTANT_P (XEXP (addr, 0)))
02760 addr = XEXP (addr, 1);
02761 else if (CONSTANT_P (XEXP (addr, 1)))
02762 addr = XEXP (addr, 0);
02763 else
02764 abort ();
02765 }
02766 if (GET_CODE (addr) == REG)
02767 return addr;
02768 abort ();
02769 }
02770
02771
02772
02773 const char *
02774 output_addsi3 (operands)
02775 rtx *operands;
02776 {
02777 if (! operands_match_p (operands[0], operands[1]))
02778 {
02779 if (!ADDRESS_REG_P (operands[1]))
02780 {
02781 rtx tmp = operands[1];
02782
02783 operands[1] = operands[2];
02784 operands[2] = tmp;
02785 }
02786
02787
02788
02789 if (GET_CODE (operands[2]) == CONST_INT
02790 && INTVAL (operands[2]) + 0x8000 >= (unsigned) 0x10000)
02791 return "move%.l %2,%0\n\tadd%.l %1,%0";
02792 #ifdef SGS
02793 if (GET_CODE (operands[2]) == REG)
02794 return "lea 0(%1,%2.l),%0";
02795 else
02796 return "lea %c2(%1),%0";
02797 #else
02798 #ifdef MOTOROLA
02799 if (GET_CODE (operands[2]) == REG)
02800 return "lea (%1,%2.l),%0";
02801 else
02802 return "lea (%c2,%1),%0";
02803 #else
02804 if (GET_CODE (operands[2]) == REG)
02805 return "lea %1@(0,%2:l),%0";
02806 else
02807 return "lea %1@(%c2),%0";
02808 #endif
02809 #endif
02810 }
02811 if (GET_CODE (operands[2]) == CONST_INT)
02812 {
02813 #ifndef NO_ADDSUB_Q
02814 if (INTVAL (operands[2]) > 0
02815 && INTVAL (operands[2]) <= 8)
02816 return "addq%.l %2,%0";
02817 if (INTVAL (operands[2]) < 0
02818 && INTVAL (operands[2]) >= -8)
02819 {
02820 operands[2] = GEN_INT (- INTVAL (operands[2]));
02821 return "subq%.l %2,%0";
02822 }
02823
02824
02825
02826 if (TARGET_CPU32 && REG_P (operands[0]))
02827 {
02828 if (INTVAL (operands[2]) > 8
02829 && INTVAL (operands[2]) <= 16)
02830 {
02831 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
02832 return "addq%.l %#8,%0\n\taddq%.l %2,%0";
02833 }
02834 if (INTVAL (operands[2]) < -8
02835 && INTVAL (operands[2]) >= -16)
02836 {
02837 operands[2] = GEN_INT (- INTVAL (operands[2]) - 8);
02838 return "subq%.l %#8,%0\n\tsubq%.l %2,%0";
02839 }
02840 }
02841 #endif
02842 if (ADDRESS_REG_P (operands[0])
02843 && INTVAL (operands[2]) >= -0x8000
02844 && INTVAL (operands[2]) < 0x8000)
02845 {
02846 if (TARGET_68040)
02847 return "add%.w %2,%0";
02848 else
02849 #ifdef MOTOROLA
02850 return "lea (%c2,%0),%0";
02851 #else
02852 return "lea %0@(%c2),%0";
02853 #endif
02854 }
02855 }
02856 return "add%.l %2,%0";
02857 }
02858
02859
02860
02861
02862
02863
02864
02865
02866
02867
02868 void
02869 notice_update_cc (exp, insn)
02870 rtx exp;
02871 rtx insn;
02872 {
02873
02874
02875
02876 if (((cc_status.value1 && FPA_REG_P (cc_status.value1))
02877 || (cc_status.value2 && FPA_REG_P (cc_status.value2)))
02878 && !(GET_CODE (exp) == PARALLEL
02879 && GET_CODE (XVECEXP (exp, 0, 0)) == SET
02880 && XEXP (XVECEXP (exp, 0, 0), 0) == cc0_rtx))
02881 {
02882 CC_STATUS_INIT;
02883 }
02884 else if (GET_CODE (exp) == SET)
02885 {
02886 if (GET_CODE (SET_SRC (exp)) == CALL)
02887 {
02888 CC_STATUS_INIT;
02889 }
02890 else if (ADDRESS_REG_P (SET_DEST (exp)))
02891 {
02892 if (cc_status.value1 && modified_in_p (cc_status.value1, insn))
02893 cc_status.value1 = 0;
02894 if (cc_status.value2 && modified_in_p (cc_status.value2, insn))
02895 cc_status.value2 = 0;
02896 }
02897 else if (!FP_REG_P (SET_DEST (exp))
02898 && SET_DEST (exp) != cc0_rtx
02899 && (FP_REG_P (SET_SRC (exp))
02900 || GET_CODE (SET_SRC (exp)) == FIX
02901 || GET_CODE (SET_SRC (exp)) == FLOAT_TRUNCATE
02902 || GET_CODE (SET_SRC (exp)) == FLOAT_EXTEND))
02903 {
02904 CC_STATUS_INIT;
02905 }
02906
02907 else if (!FP_REG_P (SET_DEST (exp))
02908 && !FP_REG_P (SET_SRC (exp))
02909 && GET_MODE_SIZE (GET_MODE (SET_SRC (exp))) > 4
02910 && (GET_CODE (SET_SRC (exp)) == REG
02911 || GET_CODE (SET_SRC (exp)) == MEM
02912 || GET_CODE (SET_SRC (exp)) == CONST_DOUBLE))
02913 {
02914 CC_STATUS_INIT;
02915 }
02916 else if (GET_CODE (SET_SRC (exp)) == CALL)
02917 {
02918 CC_STATUS_INIT;
02919 }
02920 else if (XEXP (exp, 0) != pc_rtx)
02921 {
02922 cc_status.flags = 0;
02923 cc_status.value1 = XEXP (exp, 0);
02924 cc_status.value2 = XEXP (exp, 1);
02925 }
02926 }
02927 else if (GET_CODE (exp) == PARALLEL
02928 && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
02929 {
02930 if (ADDRESS_REG_P (XEXP (XVECEXP (exp, 0, 0), 0)))
02931 CC_STATUS_INIT;
02932 else if (XEXP (XVECEXP (exp, 0, 0), 0) != pc_rtx)
02933 {
02934 cc_status.flags = 0;
02935 cc_status.value1 = XEXP (XVECEXP (exp, 0, 0), 0);
02936 cc_status.value2 = XEXP (XVECEXP (exp, 0, 0), 1);
02937 }
02938 }
02939 else
02940 CC_STATUS_INIT;
02941 if (cc_status.value2 != 0
02942 && ADDRESS_REG_P (cc_status.value2)
02943 && GET_MODE (cc_status.value2) == QImode)
02944 CC_STATUS_INIT;
02945 if (cc_status.value2 != 0
02946 && !(cc_status.value1 && FPA_REG_P (cc_status.value1)))
02947 switch (GET_CODE (cc_status.value2))
02948 {
02949 case PLUS: case MINUS: case MULT:
02950 case DIV: case UDIV: case MOD: case UMOD: case NEG:
02951 #if 0
02952 case ASHIFT: case ASHIFTRT: case LSHIFTRT:
02953 case ROTATE: case ROTATERT:
02954 #endif
02955 if (GET_MODE (cc_status.value2) != VOIDmode)
02956 cc_status.flags |= CC_NO_OVERFLOW;
02957 break;
02958 case ZERO_EXTEND:
02959
02960
02961
02962
02963 cc_status.flags |= CC_NOT_NEGATIVE;
02964
02965 default:
02966 break;
02967 }
02968 if (cc_status.value1 && GET_CODE (cc_status.value1) == REG
02969 && cc_status.value2
02970 && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
02971 cc_status.value2 = 0;
02972 if (((cc_status.value1 && FP_REG_P (cc_status.value1))
02973 || (cc_status.value2 && FP_REG_P (cc_status.value2)))
02974 && !((cc_status.value1 && FPA_REG_P (cc_status.value1))
02975 || (cc_status.value2 && FPA_REG_P (cc_status.value2))))
02976 cc_status.flags = CC_IN_68881;
02977 }
02978
02979 const char *
02980 output_move_const_double (operands)
02981 rtx *operands;
02982 {
02983 #ifdef SUPPORT_SUN_FPA
02984 if (TARGET_FPA && FPA_REG_P (operands[0]))
02985 {
02986 int code = standard_sun_fpa_constant_p (operands[1]);
02987
02988 if (code != 0)
02989 {
02990 static char buf[40];
02991
02992 sprintf (buf, "fpmove%%.d %%%%%d,%%0", code & 0x1ff);
02993 return buf;
02994 }
02995 return "fpmove%.d %1,%0";
02996 }
02997 else
02998 #endif
02999 {
03000 int code = standard_68881_constant_p (operands[1]);
03001
03002 if (code != 0)
03003 {
03004 static char buf[40];
03005
03006 sprintf (buf, "fmovecr %%#0x%x,%%0", code & 0xff);
03007 return buf;
03008 }
03009 return "fmove%.d %1,%0";
03010 }
03011 }
03012
03013 const char *
03014 output_move_const_single (operands)
03015 rtx *operands;
03016 {
03017 #ifdef SUPPORT_SUN_FPA
03018 if (TARGET_FPA)
03019 {
03020 int code = standard_sun_fpa_constant_p (operands[1]);
03021
03022 if (code != 0)
03023 {
03024 static char buf[40];
03025
03026 sprintf (buf, "fpmove%%.s %%%%%d,%%0", code & 0x1ff);
03027 return buf;
03028 }
03029 return "fpmove%.s %1,%0";
03030 }
03031 else
03032 #endif
03033 {
03034 int code = standard_68881_constant_p (operands[1]);
03035
03036 if (code != 0)
03037 {
03038 static char buf[40];
03039
03040 sprintf (buf, "fmovecr %%#0x%x,%%0", code & 0xff);
03041 return buf;
03042 }
03043 return "fmove%.s %f1,%0";
03044 }
03045 }
03046
03047
03048
03049
03050
03051
03052
03053
03054 static int inited_68881_table = 0;
03055
03056 static const char *const strings_68881[7] = {
03057 "0.0",
03058 "1.0",
03059 "10.0",
03060 "100.0",
03061 "10000.0",
03062 "1e8",
03063 "1e16"
03064 };
03065
03066 static const int codes_68881[7] = {
03067 0x0f,
03068 0x32,
03069 0x33,
03070 0x34,
03071 0x35,
03072 0x36,
03073 0x37
03074 };
03075
03076 REAL_VALUE_TYPE values_68881[7];
03077
03078
03079
03080
03081 void
03082 init_68881_table ()
03083 {
03084 int i;
03085 REAL_VALUE_TYPE r;
03086 enum machine_mode mode;
03087
03088 mode = SFmode;
03089 for (i = 0; i < 7; i++)
03090 {
03091 if (i == 6)
03092 mode = DFmode;
03093 r = REAL_VALUE_ATOF (strings_68881[i], mode);
03094 values_68881[i] = r;
03095 }
03096 inited_68881_table = 1;
03097 }
03098
03099 int
03100 standard_68881_constant_p (x)
03101 rtx x;
03102 {
03103 REAL_VALUE_TYPE r;
03104 int i;
03105
03106 #ifdef NO_ASM_FMOVECR
03107 return 0;
03108 #endif
03109
03110
03111
03112 if (TARGET_68040 || TARGET_68060)
03113 return 0;
03114
03115 #ifndef REAL_ARITHMETIC
03116 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
03117 if (! flag_pretend_float)
03118 return 0;
03119 #endif
03120 #endif
03121
03122 if (! inited_68881_table)
03123 init_68881_table ();
03124
03125 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
03126
03127
03128
03129 for (i = 0; i < 6; i++)
03130 {
03131 if (REAL_VALUES_IDENTICAL (r, values_68881[i]))
03132 return (codes_68881[i]);
03133 }
03134
03135 if (GET_MODE (x) == SFmode)
03136 return 0;
03137
03138 if (REAL_VALUES_EQUAL (r, values_68881[6]))
03139 return (codes_68881[6]);
03140
03141
03142
03143 return 0;
03144 }
03145
03146
03147
03148
03149 int
03150 floating_exact_log2 (x)
03151 rtx x;
03152 {
03153 REAL_VALUE_TYPE r, r1;
03154 int i;
03155
03156 #ifndef REAL_ARITHMETIC
03157 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
03158 if (! flag_pretend_float)
03159 return 0;
03160 #endif
03161 #endif
03162
03163 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
03164
03165 if (REAL_VALUES_LESS (r, dconst0))
03166 return 0;
03167
03168 r1 = dconst1;
03169 i = 0;
03170 while (REAL_VALUES_LESS (r1, r))
03171 {
03172 r1 = REAL_VALUE_LDEXP (dconst1, i);
03173 if (REAL_VALUES_EQUAL (r1, r))
03174 return i;
03175 i = i + 1;
03176 }
03177 return 0;
03178 }
03179
03180 #ifdef SUPPORT_SUN_FPA
03181
03182
03183
03184
03185
03186 static int inited_FPA_table = 0;
03187
03188 static const char *const strings_FPA[38] = {
03189
03190 "0.0",
03191 "1.0",
03192 "0.5",
03193 "-1.0",
03194 "2.0",
03195 "3.0",
03196 "4.0",
03197 "8.0",
03198 "0.25",
03199 "0.125",
03200 "10.0",
03201 "-0.5",
03202
03203 "2.718281828459045091",
03204 "6.283185307179586477",
03205 "3.141592653589793116",
03206 "1.570796326794896619",
03207 "1.414213562373095145",
03208 "0.7071067811865475244",
03209 "-1.570796326794896619",
03210 "1.442695040888963387",
03211 "3.321928024887362182",
03212 "0.6931471805599452862",
03213 "2.302585092994045901",
03214 "0.3010299956639811980",
03215 "0.4342944819032518167",
03216
03217 "2.718281745910644531",
03218 "6.283185307179586477",
03219 "3.141592741012573242",
03220 "1.570796326794896619",
03221 "1.414213538169860840",
03222 "0.7071067811865475244",
03223 "-1.570796326794896619",
03224 "1.442695021629333496",
03225 "3.321928024291992188",
03226 "0.6931471824645996094",
03227 "2.302585124969482442",
03228 "0.3010300099849700928",
03229 "0.4342944920063018799",
03230 };
03231
03232
03233 static const int codes_FPA[38] = {
03234
03235 0x200,
03236 0xe,
03237 0xf,
03238 0x10,
03239 0x11,
03240 0xb1,
03241 0x12,
03242 0x13,
03243 0x15,
03244 0x16,
03245 0x17,
03246 0x2e,
03247
03248 0x8,
03249 0x9,
03250 0xa,
03251 0xb,
03252 0xc,
03253 0xd,
03254 0x27,
03255 0x28,
03256 0x29,
03257 0x2a,
03258 0x2b,
03259 0x2c,
03260 0x2d,
03261
03262 0x8,
03263 0x9,
03264 0xa,
03265 0xb,
03266 0xc,
03267 0xd,
03268 0x27,
03269 0x28,
03270 0x29,
03271 0x2a,
03272 0x2b,
03273 0x2c,
03274 0x2d
03275 };
03276
03277 REAL_VALUE_TYPE values_FPA[38];
03278
03279
03280
03281 static void init_FPA_table PARAMS ((void));
03282 static void
03283 init_FPA_table ()
03284 {
03285 enum machine_mode mode;
03286 int i;
03287 REAL_VALUE_TYPE r;
03288
03289 mode = DFmode;
03290 for (i = 0; i < 38; i++)
03291 {
03292 if (i == 25)
03293 mode = SFmode;
03294 r = REAL_VALUE_ATOF (strings_FPA[i], mode);
03295 values_FPA[i] = r;
03296 }
03297 inited_FPA_table = 1;
03298 }
03299
03300
03301 int
03302 standard_sun_fpa_constant_p (x)
03303 rtx x;
03304 {
03305 REAL_VALUE_TYPE r;
03306 int i;
03307
03308 #ifndef REAL_ARITHMETIC
03309 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
03310 if (! flag_pretend_float)
03311 return 0;
03312 #endif
03313 #endif
03314
03315 if (! inited_FPA_table)
03316 init_FPA_table ();
03317
03318 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
03319
03320 for (i=0; i<12; i++)
03321 {
03322 if (REAL_VALUES_EQUAL (r, values_FPA[i]))
03323 return (codes_FPA[i]);
03324 }
03325
03326 if (GET_MODE (x) == SFmode)
03327 {
03328 for (i=25; i<38; i++)
03329 {
03330 if (REAL_VALUES_EQUAL (r, values_FPA[i]))
03331 return (codes_FPA[i]);
03332 }
03333 }
03334 else
03335 {
03336 for (i=12; i<25; i++)
03337 {
03338 if (REAL_VALUES_EQUAL (r, values_FPA[i]))
03339 return (codes_FPA[i]);
03340 }
03341 }
03342 return 0x0;
03343 }
03344 #endif
03345
03346
03347
03348
03349
03350
03351
03352
03353
03354
03355
03356
03357
03358
03359
03360
03361
03362
03363
03364
03365
03366
03367
03368
03369
03370
03371
03372
03373
03374
03375
03376
03377
03378
03379
03380
03381
03382
03383
03384
03385
03386
03387
03388
03389
03390
03391
03392
03393
03394
03395
03396
03397 void
03398 print_operand (file, op, letter)
03399 FILE *file;
03400 rtx op;
03401 int letter;
03402 {
03403 #ifdef SUPPORT_SUN_FPA
03404 int i;
03405 #endif
03406
03407 if (letter == '.')
03408 {
03409 #if defined (MOTOROLA) && !defined (CRDS)
03410 asm_fprintf (file, ".");
03411 #endif
03412 }
03413 else if (letter == '#')
03414 {
03415 asm_fprintf (file, "%0I");
03416 }
03417 else if (letter == '-')
03418 {
03419 #ifdef MOTOROLA
03420 asm_fprintf (file, "-(%Rsp)");
03421 #else
03422 asm_fprintf (file, "%Rsp@-");
03423 #endif
03424 }
03425 else if (letter == '+')
03426 {
03427 #ifdef MOTOROLA
03428 asm_fprintf (file, "(%Rsp)+");
03429 #else
03430 asm_fprintf (file, "%Rsp@+");
03431 #endif
03432 }
03433 else if (letter == '@')
03434 {
03435 #ifdef MOTOROLA
03436 asm_fprintf (file, "(%Rsp)");
03437 #else
03438 asm_fprintf (file, "%Rsp@");
03439 #endif
03440 }
03441 else if (letter == '!')
03442 {
03443 asm_fprintf (file, "%Rfpcr");
03444 }
03445 else if (letter == '$')
03446 {
03447 if (TARGET_68040_ONLY)
03448 {
03449 fprintf (file, "s");
03450 }
03451 }
03452 else if (letter == '&')
03453 {
03454 if (TARGET_68040_ONLY)
03455 {
03456 fprintf (file, "d");
03457 }
03458 }
03459 else if (letter == '/')
03460 {
03461 asm_fprintf (file, "%R");
03462 }
03463 else if (letter == 'o')
03464 {
03465
03466 if (GET_CODE (op) != MEM || GET_CODE (XEXP (op, 0)) != SYMBOL_REF
03467 || !TARGET_PCREL)
03468 abort ();
03469 output_addr_const (file, XEXP (op, 0));
03470 }
03471 else if (GET_CODE (op) == REG)
03472 {
03473 #ifdef SUPPORT_SUN_FPA
03474 if (REGNO (op) < 16
03475 && (letter == 'y' || letter == 'x')
03476 && GET_MODE (op) == DFmode)
03477 {
03478 fprintf (file, "%s:%s", reg_names[REGNO (op)],
03479 reg_names[REGNO (op)+1]);
03480 }
03481 else
03482 #endif
03483 {
03484 if (letter == 'R')
03485
03486
03487 fputs (reg_names[REGNO (op) + 1], file);
03488 else
03489 fputs (reg_names[REGNO (op)], file);
03490 }
03491 }
03492 else if (GET_CODE (op) == MEM)
03493 {
03494 output_address (XEXP (op, 0));
03495 if (letter == 'd' && ! TARGET_68020
03496 && CONSTANT_ADDRESS_P (XEXP (op, 0))
03497 && !(GET_CODE (XEXP (op, 0)) == CONST_INT
03498 && INTVAL (XEXP (op, 0)) < 0x8000
03499 && INTVAL (XEXP (op, 0)) >= -0x8000))
03500 {
03501 #ifdef MOTOROLA
03502 fprintf (file, ".l");
03503 #else
03504 fprintf (file, ":l");
03505 #endif
03506 }
03507 }
03508 #ifdef SUPPORT_SUN_FPA
03509 else if ((letter == 'y' || letter == 'w')
03510 && GET_CODE (op) == CONST_DOUBLE
03511 && (i = standard_sun_fpa_constant_p (op)))
03512 {
03513 fprintf (file, "%%%d", i & 0x1ff);
03514 }
03515 #endif
03516 else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == SFmode)
03517 {
03518 REAL_VALUE_TYPE r;
03519 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
03520 ASM_OUTPUT_FLOAT_OPERAND (letter, file, r);
03521 }
03522 else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == XFmode)
03523 {
03524 REAL_VALUE_TYPE r;
03525 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
03526 ASM_OUTPUT_LONG_DOUBLE_OPERAND (file, r);
03527 }
03528 else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == DFmode)
03529 {
03530 REAL_VALUE_TYPE r;
03531 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
03532 ASM_OUTPUT_DOUBLE_OPERAND (file, r);
03533 }
03534 else
03535 {
03536
03537
03538 asm_fprintf (file, "%0I");
03539 if (TARGET_PCREL
03540 && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST))
03541 print_operand_address (file, op);
03542 else
03543 output_addr_const (file, op);
03544 }
03545 }
03546
03547
03548
03549
03550
03551
03552
03553
03554
03555
03556
03557
03558
03559
03560
03561
03562
03563
03564
03565
03566
03567
03568
03569
03570
03571
03572
03573
03574
03575
03576
03577
03578 #ifndef ASM_OUTPUT_CASE_FETCH
03579 #ifdef MOTOROLA
03580 #ifdef SGS
03581 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
03582 asm_fprintf (file, "%LLD%d(%Rpc,%s.", labelno, regname)
03583 #else
03584 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
03585 asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.", labelno, labelno, regname)
03586 #endif
03587 #else
03588 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
03589 asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:", labelno, labelno, regname)
03590 #endif
03591 #endif
03592
03593 void
03594 print_operand_address (file, addr)
03595 FILE *file;
03596 rtx addr;
03597 {
03598 register rtx reg1, reg2, breg, ireg;
03599 rtx offset;
03600
03601 switch (GET_CODE (addr))
03602 {
03603 case REG:
03604 #ifdef MOTOROLA
03605 fprintf (file, "(%s)", reg_names[REGNO (addr)]);
03606 #else
03607 fprintf (file, "%s@", reg_names[REGNO (addr)]);
03608 #endif
03609 break;
03610 case PRE_DEC:
03611 #ifdef MOTOROLA
03612 fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
03613 #else
03614 fprintf (file, "%s@-", reg_names[REGNO (XEXP (addr, 0))]);
03615 #endif
03616 break;
03617 case POST_INC:
03618 #ifdef MOTOROLA
03619 fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
03620 #else
03621 fprintf (file, "%s@+", reg_names[REGNO (XEXP (addr, 0))]);
03622 #endif
03623 break;
03624 case PLUS:
03625 reg1 = reg2 = ireg = breg = offset = 0;
03626 if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
03627 {
03628 offset = XEXP (addr, 0);
03629 addr = XEXP (addr, 1);
03630 }
03631 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
03632 {
03633 offset = XEXP (addr, 1);
03634 addr = XEXP (addr, 0);
03635 }
03636 if (GET_CODE (addr) != PLUS)
03637 {
03638 ;
03639 }
03640 else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND)
03641 {
03642 reg1 = XEXP (addr, 0);
03643 addr = XEXP (addr, 1);
03644 }
03645 else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND)
03646 {
03647 reg1 = XEXP (addr, 1);
03648 addr = XEXP (addr, 0);
03649 }
03650 else if (GET_CODE (XEXP (addr, 0)) == MULT)
03651 {
03652 reg1 = XEXP (addr, 0);
03653 addr = XEXP (addr, 1);
03654 }
03655 else if (GET_CODE (XEXP (addr, 1)) == MULT)
03656 {
03657 reg1 = XEXP (addr, 1);
03658 addr = XEXP (addr, 0);
03659 }
03660 else if (GET_CODE (XEXP (addr, 0)) == REG)
03661 {
03662 reg1 = XEXP (addr, 0);
03663 addr = XEXP (addr, 1);
03664 }
03665 else if (GET_CODE (XEXP (addr, 1)) == REG)
03666 {
03667 reg1 = XEXP (addr, 1);
03668 addr = XEXP (addr, 0);
03669 }
03670 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT
03671 || GET_CODE (addr) == SIGN_EXTEND)
03672 {
03673 if (reg1 == 0)
03674 {
03675 reg1 = addr;
03676 }
03677 else
03678 {
03679 reg2 = addr;
03680 }
03681 addr = 0;
03682 }
03683 #if 0
03684 else if (GET_CODE (addr) == PLUS)
03685 {
03686 if (GET_CODE (XEXP (addr, 0)) == REG)
03687 {
03688 reg2 = XEXP (addr, 0);
03689 addr = XEXP (addr, 1);
03690 }
03691 else if (GET_CODE (XEXP (addr, 1)) == REG)
03692 {
03693 reg2 = XEXP (addr, 1);
03694 addr = XEXP (addr, 0);
03695 }
03696 }
03697 #endif
03698 if (offset != 0)
03699 {
03700 if (addr != 0)
03701 {
03702 abort ();
03703 }
03704 addr = offset;
03705 }
03706 if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND
03707 || GET_CODE (reg1) == MULT))
03708 || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
03709 {
03710 breg = reg2;
03711 ireg = reg1;
03712 }
03713 else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
03714 {
03715 breg = reg1;
03716 ireg = reg2;
03717 }
03718 if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF
03719 && ! (flag_pic && ireg == pic_offset_table_rtx))
03720 {
03721 int scale = 1;
03722 if (GET_CODE (ireg) == MULT)
03723 {
03724 scale = INTVAL (XEXP (ireg, 1));
03725 ireg = XEXP (ireg, 0);
03726 }
03727 if (GET_CODE (ireg) == SIGN_EXTEND)
03728 {
03729 ASM_OUTPUT_CASE_FETCH (file,
03730 CODE_LABEL_NUMBER (XEXP (addr, 0)),
03731 reg_names[REGNO (XEXP (ireg, 0))]);
03732 fprintf (file, "w");
03733 }
03734 else
03735 {
03736 ASM_OUTPUT_CASE_FETCH (file,
03737 CODE_LABEL_NUMBER (XEXP (addr, 0)),
03738 reg_names[REGNO (ireg)]);
03739 fprintf (file, "l");
03740 }
03741 if (scale != 1)
03742 {
03743 #ifdef MOTOROLA
03744 fprintf (file, "*%d", scale);
03745 #else
03746 fprintf (file, ":%d", scale);
03747 #endif
03748 }
03749 putc (')', file);
03750 break;
03751 }
03752 if (breg != 0 && ireg == 0 && GET_CODE (addr) == LABEL_REF
03753 && ! (flag_pic && breg == pic_offset_table_rtx))
03754 {
03755 ASM_OUTPUT_CASE_FETCH (file,
03756 CODE_LABEL_NUMBER (XEXP (addr, 0)),
03757 reg_names[REGNO (breg)]);
03758 fprintf (file, "l)");
03759 break;
03760 }
03761 if (ireg != 0 || breg != 0)
03762 {
03763 int scale = 1;
03764 if (breg == 0)
03765 {
03766 abort ();
03767 }
03768 if (! flag_pic && addr && GET_CODE (addr) == LABEL_REF)
03769 {
03770 abort ();
03771 }
03772 #ifdef MOTOROLA
03773 if (addr != 0)
03774 {
03775 output_addr_const (file, addr);
03776 if (flag_pic && (breg == pic_offset_table_rtx))
03777 {
03778 fprintf (file, "@GOT");
03779 if (flag_pic == 1)
03780 fprintf (file, ".w");
03781 }
03782 }
03783 fprintf (file, "(%s", reg_names[REGNO (breg)]);
03784 if (ireg != 0)
03785 {
03786 putc (',', file);
03787 }
03788 #else
03789 fprintf (file, "%s@(", reg_names[REGNO (breg)]);
03790 if (addr != 0)
03791 {
03792 output_addr_const (file, addr);
03793 if ((flag_pic == 1) && (breg == pic_offset_table_rtx))
03794 fprintf (file, ":w");
03795 if ((flag_pic == 2) && (breg == pic_offset_table_rtx))
03796 fprintf (file, ":l");
03797 }
03798 if (addr != 0 && ireg != 0)
03799 {
03800 putc (',', file);
03801 }
03802 #endif
03803 if (ireg != 0 && GET_CODE (ireg) == MULT)
03804 {
03805 scale = INTVAL (XEXP (ireg, 1));
03806 ireg = XEXP (ireg, 0);
03807 }
03808 if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND)
03809 {
03810 #ifdef MOTOROLA
03811 fprintf (file, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]);
03812 #else
03813 fprintf (file, "%s:w", reg_names[REGNO (XEXP (ireg, 0))]);
03814 #endif
03815 }
03816 else if (ireg != 0)
03817 {
03818 #ifdef MOTOROLA
03819 fprintf (file, "%s.l", reg_names[REGNO (ireg)]);
03820 #else
03821 fprintf (file, "%s:l", reg_names[REGNO (ireg)]);
03822 #endif
03823 }
03824 if (scale != 1)
03825 {
03826 #ifdef MOTOROLA
03827 fprintf (file, "*%d", scale);
03828 #else
03829 fprintf (file, ":%d", scale);
03830 #endif
03831 }
03832 putc (')', file);
03833 break;
03834 }
03835 else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF
03836 && ! (flag_pic && reg1 == pic_offset_table_rtx))
03837 {
03838 ASM_OUTPUT_CASE_FETCH (file,
03839 CODE_LABEL_NUMBER (XEXP (addr, 0)),
03840 reg_names[REGNO (reg1)]);
03841 fprintf (file, "l)");
03842 break;
03843 }
03844
03845 default:
03846 if (GET_CODE (addr) == CONST_INT
03847 && INTVAL (addr) < 0x8000
03848 && INTVAL (addr) >= -0x8000)
03849 {
03850 #ifdef MOTOROLA
03851 #ifdef SGS
03852
03853 fprintf (file, "%d", (int) INTVAL (addr));
03854 #else
03855 fprintf (file, "%d.w", (int) INTVAL (addr));
03856 #endif
03857 #else
03858 fprintf (file, "%d:w", (int) INTVAL (addr));
03859 #endif
03860 }
03861 else if (GET_CODE (addr) == CONST_INT)
03862 {
03863 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (addr));
03864 }
03865 else if (TARGET_PCREL)
03866 {
03867 fputc ('(', file);
03868 output_addr_const (file, addr);
03869 if (flag_pic == 1)
03870 asm_fprintf (file, ":w,%Rpc)");
03871 else
03872 asm_fprintf (file, ":l,%Rpc)");
03873 }
03874 else
03875 {
03876
03877
03878
03879 if (GET_CODE (addr) == SYMBOL_REF
03880 && strlen (XSTR (addr, 0)) > 2
03881 && XSTR (addr, 0)[strlen (XSTR (addr, 0)) - 2] == '.')
03882 {
03883 putc ('(', file);
03884 output_addr_const (file, addr);
03885 putc (')', file);
03886 }
03887 else
03888 output_addr_const (file, addr);
03889 }
03890 break;
03891 }
03892 }
03893
03894
03895
03896
03897
03898
03899
03900
03901
03902 int
03903 strict_low_part_peephole_ok (mode, first_insn, target)
03904 enum machine_mode mode;
03905 rtx first_insn;
03906 rtx target;
03907 {
03908 rtx p;
03909
03910 p = prev_nonnote_insn (first_insn);
03911
03912 while (p)
03913 {
03914
03915 if (GET_CODE (p) != INSN)
03916 return 0;
03917
03918 if (reg_set_p (target, p))
03919 {
03920 rtx set = single_set (p);
03921 rtx dest;
03922
03923
03924 if (! set)
03925 return 0;
03926
03927 dest = SET_DEST (set);
03928
03929
03930
03931 if (rtx_equal_p (dest, target)
03932 && SET_SRC (set) == const0_rtx)
03933 return 1;
03934 else if (GET_CODE (dest) == STRICT_LOW_PART
03935 && GET_CODE (XEXP (dest, 0)) == REG
03936 && REGNO (XEXP (dest, 0)) == REGNO (target)
03937 && (GET_MODE_SIZE (GET_MODE (XEXP (dest, 0)))
03938 <= GET_MODE_SIZE (mode)))
03939
03940
03941 ;
03942 else
03943 return 0;
03944 }
03945
03946 p = prev_nonnote_insn (p);
03947
03948 }
03949
03950 return 0;
03951 }
03952
03953
03954
03955
03956
03957 int
03958 const_uint32_operand (op, mode)
03959 rtx op;
03960 enum machine_mode mode;
03961 {
03962
03963
03964 if (GET_MODE_BITSIZE (mode) <= 32)
03965 abort ();
03966
03967 #if HOST_BITS_PER_WIDE_INT > 32
03968
03969 return (GET_CODE (op) == CONST_INT
03970 && (INTVAL (op) >= 0 && INTVAL (op) <= 0xffffffffL));
03971 #else
03972 return (GET_CODE (op) == CONST_INT
03973 || (GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_HIGH (op) == 0));
03974 #endif
03975 }
03976
03977
03978
03979
03980
03981 int
03982 const_sint32_operand (op, mode)
03983 rtx op;
03984 enum machine_mode mode;
03985 {
03986
03987
03988 if (GET_MODE_BITSIZE (mode) <= 32)
03989 abort ();
03990
03991
03992 return (GET_CODE (op) == CONST_INT
03993 && (INTVAL (op) >= (-0x7fffffff - 1) && INTVAL (op) <= 0x7fffffff));
03994 }
03995
03996
03997
03998
03999
04000
04001
04002
04003
04004
04005
04006
04007
04008
04009
04010
04011
04012
04013
04014
04015
04016
04017
04018
04019
04020
04021
04022
04023
04024
04025
04026
04027
04028
04029
04030
04031
04032
04033
04034
04035
04036
04037
04038
04039
04040
04041
04042
04043
04044
04045
04046
04047
04048
04049
04050
04051
04052
04053
04054
04055
04056
04057 int
04058 general_src_operand (op, mode)
04059 rtx op;
04060 enum machine_mode mode;
04061 {
04062 if (TARGET_PCREL
04063 && GET_CODE (op) == MEM
04064 && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
04065 || GET_CODE (XEXP (op, 0)) == LABEL_REF
04066 || GET_CODE (XEXP (op, 0)) == CONST))
04067 return 1;
04068 return general_operand (op, mode);
04069 }
04070
04071
04072
04073
04074
04075 int
04076 nonimmediate_src_operand (op, mode)
04077 rtx op;
04078 enum machine_mode mode;
04079 {
04080 if (TARGET_PCREL && GET_CODE (op) == MEM
04081 && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
04082 || GET_CODE (XEXP (op, 0)) == LABEL_REF
04083 || GET_CODE (XEXP (op, 0)) == CONST))
04084 return 1;
04085 return nonimmediate_operand (op, mode);
04086 }
04087
04088
04089
04090
04091
04092 int
04093 memory_src_operand (op, mode)
04094 rtx op;
04095 enum machine_mode mode;
04096 {
04097 if (TARGET_PCREL && GET_CODE (op) == MEM
04098 && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
04099 || GET_CODE (XEXP (op, 0)) == LABEL_REF
04100 || GET_CODE (XEXP (op, 0)) == CONST))
04101 return 1;
04102 return memory_operand (op, mode);
04103 }
04104
04105
04106
04107
04108
04109 int
04110 pcrel_address (op, mode)
04111 rtx op;
04112 enum machine_mode mode ATTRIBUTE_UNUSED;
04113 {
04114 return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF
04115 || GET_CODE (op) == CONST);
04116 }
04117
04118 const char *
04119 output_andsi3 (operands)
04120 rtx *operands;
04121 {
04122 int logval;
04123 if (GET_CODE (operands[2]) == CONST_INT
04124 && (INTVAL (operands[2]) | 0xffff) == 0xffffffff
04125 && (DATA_REG_P (operands[0])
04126 || offsettable_memref_p (operands[0]))
04127 && !TARGET_5200)
04128 {
04129 if (GET_CODE (operands[0]) != REG)
04130 operands[0] = adjust_address (operands[0], HImode, 2);
04131 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
04132
04133 CC_STATUS_INIT;
04134 if (operands[2] == const0_rtx)
04135 return "clr%.w %0";
04136 return "and%.w %2,%0";
04137 }
04138 if (GET_CODE (operands[2]) == CONST_INT
04139 && (logval = exact_log2 (~ INTVAL (operands[2]))) >= 0
04140 && (DATA_REG_P (operands[0])
04141 || offsettable_memref_p (operands[0])))
04142 {
04143 if (DATA_REG_P (operands[0]))
04144 {
04145 operands[1] = GEN_INT (logval);
04146 }
04147 else
04148 {
04149 operands[0] = adjust_address (operands[0], SImode, 3 - (logval / 8));
04150 operands[1] = GEN_INT (logval % 8);
04151 }
04152
04153 CC_STATUS_INIT;
04154 return "bclr %1,%0";
04155 }
04156 return "and%.l %2,%0";
04157 }
04158
04159 const char *
04160 output_iorsi3 (operands)
04161 rtx *operands;
04162 {
04163 register int logval;
04164 if (GET_CODE (operands[2]) == CONST_INT
04165 && INTVAL (operands[2]) >> 16 == 0
04166 && (DATA_REG_P (operands[0])
04167 || offsettable_memref_p (operands[0]))
04168 && !TARGET_5200)
04169 {
04170 if (GET_CODE (operands[0]) != REG)
04171 operands[0] = adjust_address (operands[0], HImode, 2);
04172
04173 CC_STATUS_INIT;
04174 if (INTVAL (operands[2]) == 0xffff)
04175 return "mov%.w %2,%0";
04176 return "or%.w %2,%0";
04177 }
04178 if (GET_CODE (operands[2]) == CONST_INT
04179 && (logval = exact_log2 (INTVAL (operands[2]))) >= 0
04180 && (DATA_REG_P (operands[0])
04181 || offsettable_memref_p (operands[0])))
04182 {
04183 if (DATA_REG_P (operands[0]))
04184 operands[1] = GEN_INT (logval);
04185 else
04186 {
04187 operands[0] = adjust_address (operands[0], SImode, 3 - (logval / 8));
04188 operands[1] = GEN_INT (logval % 8);
04189 }
04190 CC_STATUS_INIT;
04191 return "bset %1,%0";
04192 }
04193 return "or%.l %2,%0";
04194 }
04195
04196 const char *
04197 output_xorsi3 (operands)
04198 rtx *operands;
04199 {
04200 register int logval;
04201 if (GET_CODE (operands[2]) == CONST_INT
04202 && INTVAL (operands[2]) >> 16 == 0
04203 && (offsettable_memref_p (operands[0]) || DATA_REG_P (operands[0]))
04204 && !TARGET_5200)
04205 {
04206 if (! DATA_REG_P (operands[0]))
04207 operands[0] = adjust_address (operands[0], HImode, 2);
04208
04209 CC_STATUS_INIT;
04210 if (INTVAL (operands[2]) == 0xffff)
04211 return "not%.w %0";
04212 return "eor%.w %2,%0";
04213 }
04214 if (GET_CODE (operands[2]) == CONST_INT
04215 && (logval = exact_log2 (INTVAL (operands[2]))) >= 0
04216 && (DATA_REG_P (operands[0])
04217 || offsettable_memref_p (operands[0])))
04218 {
04219 if (DATA_REG_P (operands[0]))
04220 operands[1] = GEN_INT (logval);
04221 else
04222 {
04223 operands[0] = adjust_address (operands[0], SImode, 3 - (logval / 8));
04224 operands[1] = GEN_INT (logval % 8);
04225 }
04226 CC_STATUS_INIT;
04227 return "bchg %1,%0";
04228 }
04229 return "eor%.l %2,%0";
04230 }
04231
04232
04233
04234 static void
04235 m68k_coff_asm_named_section (name, flags)
04236 const char *name;
04237 unsigned int flags;
04238 {
04239 char flagchar;
04240
04241 if (flags & SECTION_WRITE)
04242 flagchar = 'd';
04243 else
04244 flagchar = 'x';
04245
04246 fprintf (asm_out_file, "\t.section\t%s,\"%c\"\n", name, flagchar);
04247 }
04248
04249 #ifdef CTOR_LIST_BEGIN
04250 static void
04251 m68k_svr3_asm_out_constructor (symbol, priority)
04252 rtx symbol;
04253 int priority ATTRIBUTE_UNUSED;
04254 {
04255 rtx xop[2];
04256
04257 xop[1] = symbol;
04258 xop[0] = gen_rtx_MEM (SImode, gen_rtx_PRE_DEC (SImode, stack_pointer_rtx));
04259
04260 init_section ();
04261 output_asm_insn (output_move_simode (xop), xop);
04262 }
04263 #endif