1 /* Subroutines for insn-output.c for Motorola 68000 family.
2 Copyright (C) 1987, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
28 #include "hard-reg-set.h"
30 #include "insn-config.h"
31 #include "conditions.h"
33 #include "insn-attr.h"
40 #include "target-def.h"
43 /* Needed for use_return_insn. */
46 #ifdef SUPPORT_SUN_FPA
48 /* Index into this array by (register number >> 3) to find the
49 smallest class which contains that register. */
50 const enum reg_class regno_reg_class[]
51 = { DATA_REGS, ADDR_REGS, FP_REGS,
52 LO_FPA_REGS, LO_FPA_REGS, FPA_REGS, FPA_REGS };
54 #endif /* defined SUPPORT_SUN_FPA */
56 /* This flag is used to communicate between movhi and ASM_OUTPUT_CASE_END,
57 if SGS_SWITCH_TABLE. */
58 int switch_table_difference_label_flag;
60 static rtx find_addr_reg PARAMS ((rtx));
61 static const char *singlemove_string PARAMS ((rtx *));
62 static void m68k_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
63 static void m68k_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
64 static void m68k_coff_asm_named_section PARAMS ((const char *, unsigned int));
65 #ifdef CTOR_LIST_BEGIN
66 static void m68k_svr3_asm_out_constructor PARAMS ((rtx, int));
70 /* Alignment to use for loops and jumps */
71 /* Specify power of two alignment used for loops. */
72 const char *m68k_align_loops_string;
73 /* Specify power of two alignment used for non-loop jumps. */
74 const char *m68k_align_jumps_string;
75 /* Specify power of two alignment used for functions. */
76 const char *m68k_align_funcs_string;
78 /* Specify power of two alignment used for loops. */
80 /* Specify power of two alignment used for non-loop jumps. */
82 /* Specify power of two alignment used for functions. */
85 /* Nonzero if the last compare/test insn had FP operands. The
86 sCC expanders peek at this to determine what to do for the
87 68060, which has no fsCC instructions. */
88 int m68k_last_compare_had_fp_operands;
90 /* Initialize the GCC target structure. */
92 #if INT_OP_GROUP == INT_OP_DOT_WORD
93 #undef TARGET_ASM_ALIGNED_HI_OP
94 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
97 #if INT_OP_GROUP == INT_OP_NO_DOT
98 #undef TARGET_ASM_BYTE_OP
99 #define TARGET_ASM_BYTE_OP "\tbyte\t"
100 #undef TARGET_ASM_ALIGNED_HI_OP
101 #define TARGET_ASM_ALIGNED_HI_OP "\tshort\t"
102 #undef TARGET_ASM_ALIGNED_SI_OP
103 #define TARGET_ASM_ALIGNED_SI_OP "\tlong\t"
106 #if INT_OP_GROUP == INT_OP_DC
107 #undef TARGET_ASM_BYTE_OP
108 #define TARGET_ASM_BYTE_OP "\tdc.b\t"
109 #undef TARGET_ASM_ALIGNED_HI_OP
110 #define TARGET_ASM_ALIGNED_HI_OP "\tdc.w\t"
111 #undef TARGET_ASM_ALIGNED_SI_OP
112 #define TARGET_ASM_ALIGNED_SI_OP "\tdc.l\t"
115 #undef TARGET_ASM_UNALIGNED_HI_OP
116 #define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP
117 #undef TARGET_ASM_UNALIGNED_SI_OP
118 #define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP
120 #undef TARGET_ASM_FUNCTION_PROLOGUE
121 #define TARGET_ASM_FUNCTION_PROLOGUE m68k_output_function_prologue
122 #undef TARGET_ASM_FUNCTION_EPILOGUE
123 #define TARGET_ASM_FUNCTION_EPILOGUE m68k_output_function_epilogue
125 struct gcc_target targetm = TARGET_INITIALIZER;
127 /* Sometimes certain combinations of command options do not make
128 sense on a particular target machine. You can define a macro
129 `OVERRIDE_OPTIONS' to take account of this. This macro, if
130 defined, is executed once just after all the command options have
133 Don't use this macro to turn on various extra optimizations for
134 `-O'. That is what `OPTIMIZATION_OPTIONS' is for. */
144 /* Validate -malign-loops= value, or provide default */
145 m68k_align_loops = def_align;
146 if (m68k_align_loops_string)
148 i = atoi (m68k_align_loops_string);
149 if (i < 1 || i > MAX_CODE_ALIGN)
150 error ("-malign-loops=%d is not between 1 and %d", i, MAX_CODE_ALIGN);
152 m68k_align_loops = i;
155 /* Validate -malign-jumps= value, or provide default */
156 m68k_align_jumps = def_align;
157 if (m68k_align_jumps_string)
159 i = atoi (m68k_align_jumps_string);
160 if (i < 1 || i > MAX_CODE_ALIGN)
161 error ("-malign-jumps=%d is not between 1 and %d", i, MAX_CODE_ALIGN);
163 m68k_align_jumps = i;
166 /* Validate -malign-functions= value, or provide default */
167 m68k_align_funcs = def_align;
168 if (m68k_align_funcs_string)
170 i = atoi (m68k_align_funcs_string);
171 if (i < 1 || i > MAX_CODE_ALIGN)
172 error ("-malign-functions=%d is not between 1 and %d",
175 m68k_align_funcs = i;
178 /* -fPIC uses 32-bit pc-relative displacements, which don't exist
180 if (! TARGET_68020 && flag_pic == 2)
181 error("-fPIC is not currently supported on the 68000 or 68010\n");
183 /* ??? A historic way of turning on pic, or is this intended to
184 be an embedded thing that doesn't have the same name binding
185 significance that it does on hosted ELF systems? */
186 if (TARGET_PCREL && flag_pic == 0)
189 /* Turn off function cse if we are doing PIC. We always want function call
190 to be done as `bsr foo@PLTPC', so it will force the assembler to create
191 the PLT entry for `foo'. Doing function cse will cause the address of
192 `foo' to be loaded into a register, which is exactly what we want to
193 avoid when we are doing PIC on svr4 m68k. */
195 flag_no_function_cse = 1;
197 SUBTARGET_OVERRIDE_OPTIONS;
199 /* Tell the compiler which flavor of XFmode we're using. */
200 real_format_for_mode[XFmode - QFmode] = &ieee_extended_motorola_format;
203 /* This function generates the assembly code for function entry.
204 STREAM is a stdio stream to output the code to.
205 SIZE is an int: how many units of temporary storage to allocate.
206 Refer to the array `regs_ever_live' to determine which registers
207 to save; `regs_ever_live[I]' is nonzero if register number I
208 is ever used in the function. This function is responsible for
209 knowing which registers should not be saved even if used. */
212 /* Note that the order of the bit mask for fmovem is the opposite
213 of the order for movem! */
218 m68k_output_function_prologue (stream, size)
223 register int mask = 0;
224 HOST_WIDE_INT fsize = ((size) + 3) & -4;
226 /* unos stack probe */
229 fprintf (stream, "\tmovel sp,a0\n");
230 fprintf (stream, "\taddl $-%d,a0\n", 2048 + fsize);
231 fprintf (stream, "\ttstb (a0)\n");
234 fprintf (stream, "\ttstb -%d(sp)\n", 2048 + fsize);
236 if (frame_pointer_needed)
238 if (TARGET_68020 || fsize < 0x8000)
239 fprintf (stream, "\tlink a6,$%d\n", -fsize);
241 fprintf (stream, "\tlink a6,$0\n\tsubl $%d,sp\n", fsize);
245 /* Adding negative number is faster on the 68040. */
246 if (fsize + 4 < 0x8000)
247 fprintf (stream, "\tadd.w #%d,sp\n", - (fsize + 4));
249 fprintf (stream, "\tadd.l #%d,sp\n", - (fsize + 4));
252 for (regno = 16; regno < 24; regno++)
253 if (regs_ever_live[regno] && ! call_used_regs[regno])
254 mask |= 1 << (regno - 16);
256 if ((mask & 0xff) != 0)
257 fprintf (stream, "\tfmovem $0x%x,-(sp)\n", mask & 0xff);
260 for (regno = 0; regno < 16; regno++)
261 if (regs_ever_live[regno] && ! call_used_regs[regno])
262 mask |= 1 << (15 - regno);
263 if (frame_pointer_needed)
264 mask &= ~ (1 << (15-FRAME_POINTER_REGNUM));
266 if (exact_log2 (mask) >= 0)
267 fprintf (stream, "\tmovel %s,-(sp)\n", reg_names[15 - exact_log2 (mask)]);
269 fprintf (stream, "\tmovem $0x%x,-(sp)\n", mask);
275 m68k_output_function_prologue (stream, size)
280 register int mask = 0;
281 int num_saved_regs = 0;
282 HOST_WIDE_INT fsize = (size + 3) & -4;
283 HOST_WIDE_INT cfa_offset = INCOMING_FRAME_SP_OFFSET;
284 HOST_WIDE_INT cfa_store_offset = cfa_offset;
286 /* If the stack limit is a symbol, we can check it here,
287 before actually allocating the space. */
288 if (current_function_limit_stack
289 && GET_CODE (stack_limit_rtx) == SYMBOL_REF)
291 #if defined (MOTOROLA)
292 asm_fprintf (stream, "\tcmp.l %0I%s+%d,%Rsp\n\ttrapcs\n",
293 XSTR (stack_limit_rtx, 0), fsize + 4);
295 asm_fprintf (stream, "\tcmpl %0I%s+%d,%Rsp\n\ttrapcs\n",
296 XSTR (stack_limit_rtx, 0), fsize + 4);
300 if (frame_pointer_needed)
302 if (fsize == 0 && TARGET_68040)
304 /* on the 68040, pea + move is faster than link.w 0 */
306 fprintf (stream, "\tpea (%s)\n\tmove.l %s,%s\n",
307 reg_names[FRAME_POINTER_REGNUM],
308 reg_names[STACK_POINTER_REGNUM],
309 reg_names[FRAME_POINTER_REGNUM]);
311 fprintf (stream, "\tpea %s@\n\tmovel %s,%s\n",
312 reg_names[FRAME_POINTER_REGNUM],
313 reg_names[STACK_POINTER_REGNUM],
314 reg_names[FRAME_POINTER_REGNUM]);
317 else if (fsize < 0x8000)
320 asm_fprintf (stream, "\tlink.w %s,%0I%d\n",
321 reg_names[FRAME_POINTER_REGNUM], -fsize);
323 asm_fprintf (stream, "\tlink %s,%0I%d\n",
324 reg_names[FRAME_POINTER_REGNUM], -fsize);
327 else if (TARGET_68020)
330 asm_fprintf (stream, "\tlink.l %s,%0I%d\n",
331 reg_names[FRAME_POINTER_REGNUM], -fsize);
333 asm_fprintf (stream, "\tlink %s,%0I%d\n",
334 reg_names[FRAME_POINTER_REGNUM], -fsize);
339 /* Adding negative number is faster on the 68040. */
341 asm_fprintf (stream, "\tlink.w %s,%0I0\n\tadd.l %0I%d,%Rsp\n",
342 reg_names[FRAME_POINTER_REGNUM], -fsize);
344 asm_fprintf (stream, "\tlink %s,%0I0\n\taddl %0I%d,%Rsp\n",
345 reg_names[FRAME_POINTER_REGNUM], -fsize);
348 if (dwarf2out_do_frame ())
351 l = (char *) dwarf2out_cfi_label ();
352 cfa_store_offset += 4;
353 cfa_offset = cfa_store_offset;
354 dwarf2out_reg_save (l, FRAME_POINTER_REGNUM, -cfa_store_offset);
355 dwarf2out_def_cfa (l, FRAME_POINTER_REGNUM, cfa_offset);
356 cfa_store_offset += fsize;
361 if (fsize + 4 < 0x8000)
368 /* asm_fprintf() cannot handle %. */
370 asm_fprintf (stream, "\tsubq.w %0I%d,%Rsp\n", fsize + 4);
372 asm_fprintf (stream, "\tsubqw %0I%d,%Rsp\n", fsize + 4);
377 /* asm_fprintf() cannot handle %. */
379 asm_fprintf (stream, "\tsubq.l %0I%d,%Rsp\n", fsize + 4);
381 asm_fprintf (stream, "\tsubql %0I%d,%Rsp\n", fsize + 4);
385 else if (fsize + 4 <= 16 && TARGET_CPU32)
387 /* On the CPU32 it is faster to use two subqw instructions to
388 subtract a small integer (8 < N <= 16) to a register. */
389 /* asm_fprintf() cannot handle %. */
391 asm_fprintf (stream, "\tsubq.w %0I8,%Rsp\n\tsubq.w %0I%d,%Rsp\n",
394 asm_fprintf (stream, "\tsubqw %0I8,%Rsp\n\tsubqw %0I%d,%Rsp\n",
399 #endif /* not NO_ADDSUB_Q */
402 /* Adding negative number is faster on the 68040. */
403 /* asm_fprintf() cannot handle %. */
405 asm_fprintf (stream, "\tadd.w %0I%d,%Rsp\n", - (fsize + 4));
407 asm_fprintf (stream, "\taddw %0I%d,%Rsp\n", - (fsize + 4));
413 asm_fprintf (stream, "\tlea (%d,%Rsp),%Rsp\n", - (fsize + 4));
415 asm_fprintf (stream, "\tlea %Rsp@(%d),%Rsp\n", - (fsize + 4));
421 /* asm_fprintf() cannot handle %. */
423 asm_fprintf (stream, "\tadd.l %0I%d,%Rsp\n", - (fsize + 4));
425 asm_fprintf (stream, "\taddl %0I%d,%Rsp\n", - (fsize + 4));
428 if (dwarf2out_do_frame ())
430 cfa_store_offset += fsize;
431 cfa_offset = cfa_store_offset;
432 dwarf2out_def_cfa ("", STACK_POINTER_REGNUM, cfa_offset);
435 #ifdef SUPPORT_SUN_FPA
436 for (regno = 24; regno < 56; regno++)
437 if (regs_ever_live[regno] && ! call_used_regs[regno])
440 asm_fprintf (stream, "\tfpmovd %s,-(%Rsp)\n",
443 asm_fprintf (stream, "\tfpmoved %s,%Rsp@-\n",
446 if (dwarf2out_do_frame ())
448 char *l = dwarf2out_cfi_label ();
450 cfa_store_offset += 8;
451 if (! frame_pointer_needed)
453 cfa_offset = cfa_store_offset;
454 dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, cfa_offset);
456 dwarf2out_reg_save (l, regno, -cfa_store_offset);
462 for (regno = 16; regno < 24; regno++)
463 if (regs_ever_live[regno] && ! call_used_regs[regno])
465 mask |= 1 << (regno - 16);
468 if ((mask & 0xff) != 0)
471 asm_fprintf (stream, "\tfmovm %0I0x%x,-(%Rsp)\n", mask & 0xff);
473 asm_fprintf (stream, "\tfmovem %0I0x%x,%Rsp@-\n", mask & 0xff);
475 if (dwarf2out_do_frame ())
477 char *l = (char *) dwarf2out_cfi_label ();
480 cfa_store_offset += num_saved_regs * 12;
481 if (! frame_pointer_needed)
483 cfa_offset = cfa_store_offset;
484 dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, cfa_offset);
486 for (regno = 16, n_regs = 0; regno < 24; regno++)
487 if (mask & (1 << (regno - 16)))
488 dwarf2out_reg_save (l, regno,
489 -cfa_store_offset + n_regs++ * 12);
495 for (regno = 0; regno < 16; regno++)
496 if (regs_ever_live[regno] && ! call_used_regs[regno])
498 mask |= 1 << (15 - regno);
501 if (frame_pointer_needed)
503 mask &= ~ (1 << (15 - FRAME_POINTER_REGNUM));
506 if (flag_pic && current_function_uses_pic_offset_table)
508 mask |= 1 << (15 - PIC_OFFSET_TABLE_REGNUM);
514 asm_fprintf (stream, "\ttst.l %d(%Rsp)\n", NEED_PROBE - num_saved_regs * 4);
516 asm_fprintf (stream, "\ttstl %Rsp@(%d)\n", NEED_PROBE - num_saved_regs * 4);
520 /* If the stack limit is not a symbol, check it here.
521 This has the disadvantage that it may be too late... */
522 if (current_function_limit_stack)
524 if (REG_P (stack_limit_rtx))
526 #if defined (MOTOROLA)
527 asm_fprintf (stream, "\tcmp.l %s,%Rsp\n\ttrapcs\n",
528 reg_names[REGNO (stack_limit_rtx)]);
530 asm_fprintf (stream, "\tcmpl %s,%Rsp\n\ttrapcs\n",
531 reg_names[REGNO (stack_limit_rtx)]);
534 else if (GET_CODE (stack_limit_rtx) != SYMBOL_REF)
535 warning ("stack limit expression is not supported");
538 if (num_saved_regs <= 2)
540 /* Store each separately in the same order moveml uses.
541 Using two movel instructions instead of a single moveml
542 is about 15% faster for the 68020 and 68030 at no expense
547 /* Undo the work from above. */
548 for (i = 0; i< 16; i++)
553 "\t%Omove.l %s,-(%Rsp)\n",
555 "\tmovel %s,%Rsp@-\n",
558 if (dwarf2out_do_frame ())
560 char *l = (char *) dwarf2out_cfi_label ();
562 cfa_store_offset += 4;
563 if (! frame_pointer_needed)
565 cfa_offset = cfa_store_offset;
566 dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, cfa_offset);
568 dwarf2out_reg_save (l, 15 - i, -cfa_store_offset);
576 /* The coldfire does not support the predecrement form of the
577 movml instruction, so we must adjust the stack pointer and
578 then use the plain address register indirect mode. We also
579 have to invert the register save mask to use the new mode.
581 FIXME: if num_saved_regs was calculated earlier, we could
582 combine the stack pointer adjustment with any adjustment
583 done when the initial stack frame is created. This would
584 save an instruction */
589 for (i = 0; i < 16; i++)
591 newmask |= (1 << (15-i));
594 asm_fprintf (stream, "\tlea (%d,%Rsp),%Rsp\n", -num_saved_regs*4);
595 asm_fprintf (stream, "\tmovm.l %0I0x%x,(%Rsp)\n", newmask);
597 asm_fprintf (stream, "\tlea %Rsp@(%d),%Rsp\n", -num_saved_regs*4);
598 asm_fprintf (stream, "\tmoveml %0I0x%x,%Rsp@\n", newmask);
604 asm_fprintf (stream, "\tmovm.l %0I0x%x,-(%Rsp)\n", mask);
606 asm_fprintf (stream, "\tmoveml %0I0x%x,%Rsp@-\n", mask);
609 if (dwarf2out_do_frame ())
611 char *l = (char *) dwarf2out_cfi_label ();
614 cfa_store_offset += num_saved_regs * 4;
615 if (! frame_pointer_needed)
617 cfa_offset = cfa_store_offset;
618 dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, cfa_offset);
620 for (regno = 0, n_regs = 0; regno < 16; regno++)
621 if (mask & (1 << (15 - regno)))
622 dwarf2out_reg_save (l, regno,
623 -cfa_store_offset + n_regs++ * 4);
626 if (flag_pic && current_function_uses_pic_offset_table)
629 asm_fprintf (stream, "\t%Olea (%Rpc, %U_GLOBAL_OFFSET_TABLE_@GOTPC), %s\n",
630 reg_names[PIC_OFFSET_TABLE_REGNUM]);
632 asm_fprintf (stream, "\tmovel %0I__GLOBAL_OFFSET_TABLE_, %s\n",
633 reg_names[PIC_OFFSET_TABLE_REGNUM]);
634 asm_fprintf (stream, "\tlea %Rpc@(0,%s:l),%s\n",
635 reg_names[PIC_OFFSET_TABLE_REGNUM],
636 reg_names[PIC_OFFSET_TABLE_REGNUM]);
642 /* Return true if this function's epilogue can be output as RTL. */
649 if (!reload_completed || frame_pointer_needed || get_frame_size () != 0)
652 /* Copied from output_function_epilogue (). We should probably create a
653 separate layout routine to perform the common work. */
655 for (regno = 0 ; regno < FIRST_PSEUDO_REGISTER ; regno++)
656 if (regs_ever_live[regno] && ! call_used_regs[regno])
659 if (flag_pic && current_function_uses_pic_offset_table)
665 /* This function generates the assembly code for function exit,
666 on machines that need it.
668 The function epilogue should not depend on the current stack pointer!
669 It should use the frame pointer only, if there is a frame pointer.
670 This is mandatory because of alloca; we also take advantage of it to
671 omit stack adjustments before returning. */
676 m68k_output_function_epilogue (stream, size)
681 register int mask, fmask;
683 HOST_WIDE_INT offset, foffset, fpoffset;
684 HOST_WIDE_INT fsize = ((size) + 3) & -4;
687 nregs = 0; fmask = 0; fpoffset = 0;
688 for (regno = 16; regno < 24; regno++)
689 if (regs_ever_live[regno] && ! call_used_regs[regno])
692 fmask |= 1 << (23 - regno);
695 foffset = fpoffset + nregs * 12;
697 if (frame_pointer_needed)
698 regs_ever_live[FRAME_POINTER_REGNUM] = 0;
700 for (regno = 0; regno < 16; regno++)
701 if (regs_ever_live[regno] && ! call_used_regs[regno])
707 offset = foffset + nregs * 4;
708 if (offset + fsize >= 0x8000
709 && frame_pointer_needed
710 && (mask || fmask || fpoffset))
712 fprintf (stream, "\tmovel $%d,a0\n", -fsize);
716 if (exact_log2 (mask) >= 0)
719 fprintf (stream, "\tmovel -%d(a6,a0.l),%s\n",
720 offset + fsize, reg_names[exact_log2 (mask)]);
721 else if (! frame_pointer_needed)
722 fprintf (stream, "\tmovel (sp)+,%s\n",
723 reg_names[exact_log2 (mask)]);
725 fprintf (stream, "\tmovel -%d(a6),%s\n",
726 offset + fsize, reg_names[exact_log2 (mask)]);
731 fprintf (stream, "\tmovem -%d(a6,a0.l),$0x%x\n",
732 offset + fsize, mask);
733 else if (! frame_pointer_needed)
734 fprintf (stream, "\tmovem (sp)+,$0x%x\n", mask);
736 fprintf (stream, "\tmovem -%d(a6),$0x%x\n",
737 offset + fsize, mask);
743 fprintf (stream, "\tfmovem -%d(a6,a0.l),$0x%x\n",
744 foffset + fsize, fmask);
745 else if (! frame_pointer_needed)
746 fprintf (stream, "\tfmovem (sp)+,$0x%x\n", fmask);
748 fprintf (stream, "\tfmovem -%d(a6),$0x%x\n",
749 foffset + fsize, fmask);
753 for (regno = 55; regno >= 24; regno--)
754 if (regs_ever_live[regno] && ! call_used_regs[regno])
757 fprintf(stream, "\tfpmoved -%d(a6,a0.l), %s\n",
758 fpoffset + fsize, reg_names[regno]);
759 else if (! frame_pointer_needed)
760 fprintf(stream, "\tfpmoved (sp)+, %s\n",
763 fprintf(stream, "\tfpmoved -%d(a6), %s\n",
764 fpoffset + fsize, reg_names[regno]);
768 if (frame_pointer_needed)
769 fprintf (stream, "\tunlk a6\n");
772 if (fsize + 4 < 0x8000)
773 fprintf (stream, "\tadd.w #%d,sp\n", fsize + 4);
775 fprintf (stream, "\tadd.l #%d,sp\n", fsize + 4);
778 if (current_function_pops_args)
779 fprintf (stream, "\trtd $%d\n", current_function_pops_args);
781 fprintf (stream, "\trts\n");
787 m68k_output_function_epilogue (stream, size)
792 register int mask, fmask;
794 HOST_WIDE_INT offset, foffset, fpoffset;
795 HOST_WIDE_INT fsize = (size + 3) & -4;
797 rtx insn = get_last_insn ();
798 int restore_from_sp = 0;
800 /* If the last insn was a BARRIER, we don't have to write any code. */
801 if (GET_CODE (insn) == NOTE)
802 insn = prev_nonnote_insn (insn);
803 if (insn && GET_CODE (insn) == BARRIER)
805 /* Output just a no-op so that debuggers don't get confused
806 about which function the pc is in at this address. */
807 fprintf (stream, "\tnop\n");
811 #ifdef FUNCTION_EXTRA_EPILOGUE
812 FUNCTION_EXTRA_EPILOGUE (stream, size);
814 nregs = 0; fmask = 0; fpoffset = 0;
815 #ifdef SUPPORT_SUN_FPA
816 for (regno = 24 ; regno < 56 ; regno++)
817 if (regs_ever_live[regno] && ! call_used_regs[regno])
819 fpoffset = nregs * 8;
824 for (regno = 16; regno < 24; regno++)
825 if (regs_ever_live[regno] && ! call_used_regs[regno])
828 fmask |= 1 << (23 - regno);
831 foffset = fpoffset + nregs * 12;
833 if (frame_pointer_needed)
834 regs_ever_live[FRAME_POINTER_REGNUM] = 0;
835 for (regno = 0; regno < 16; regno++)
836 if (regs_ever_live[regno] && ! call_used_regs[regno])
841 if (flag_pic && current_function_uses_pic_offset_table)
844 mask |= 1 << PIC_OFFSET_TABLE_REGNUM;
846 offset = foffset + nregs * 4;
847 /* FIXME : leaf_function_p below is too strong.
848 What we really need to know there is if there could be pending
849 stack adjustment needed at that point. */
850 restore_from_sp = ! frame_pointer_needed
851 || (! current_function_calls_alloca && leaf_function_p ());
852 if (offset + fsize >= 0x8000
854 && (mask || fmask || fpoffset))
857 asm_fprintf (stream, "\t%Omove.l %0I%d,%Ra1\n", -fsize);
859 asm_fprintf (stream, "\tmovel %0I%d,%Ra1\n", -fsize);
863 if (TARGET_5200 || nregs <= 2)
865 /* Restore each separately in the same order moveml does.
866 Using two movel instructions instead of a single moveml
867 is about 15% faster for the 68020 and 68030 at no expense
872 /* Undo the work from above. */
873 for (i = 0; i< 16; i++)
879 asm_fprintf (stream, "\t%Omove.l -%d(%s,%Ra1.l),%s\n",
881 reg_names[FRAME_POINTER_REGNUM],
884 asm_fprintf (stream, "\tmovel %s@(-%d,%Ra1:l),%s\n",
885 reg_names[FRAME_POINTER_REGNUM],
886 offset + fsize, reg_names[i]);
889 else if (restore_from_sp)
892 asm_fprintf (stream, "\t%Omove.l (%Rsp)+,%s\n",
895 asm_fprintf (stream, "\tmovel %Rsp@+,%s\n",
902 asm_fprintf (stream, "\t%Omove.l -%d(%s),%s\n",
904 reg_names[FRAME_POINTER_REGNUM],
907 fprintf (stream, "\tmovel %s@(-%d),%s\n",
908 reg_names[FRAME_POINTER_REGNUM],
909 offset + fsize, reg_names[i]);
920 asm_fprintf (stream, "\tmovm.l -%d(%s,%Ra1.l),%0I0x%x\n",
922 reg_names[FRAME_POINTER_REGNUM],
925 asm_fprintf (stream, "\tmoveml %s@(-%d,%Ra1:l),%0I0x%x\n",
926 reg_names[FRAME_POINTER_REGNUM],
927 offset + fsize, mask);
930 else if (restore_from_sp)
933 asm_fprintf (stream, "\tmovm.l (%Rsp)+,%0I0x%x\n", mask);
935 asm_fprintf (stream, "\tmoveml %Rsp@+,%0I0x%x\n", mask);
941 asm_fprintf (stream, "\tmovm.l -%d(%s),%0I0x%x\n",
943 reg_names[FRAME_POINTER_REGNUM],
946 asm_fprintf (stream, "\tmoveml %s@(-%d),%0I0x%x\n",
947 reg_names[FRAME_POINTER_REGNUM],
948 offset + fsize, mask);
957 asm_fprintf (stream, "\tfmovm -%d(%s,%Ra1.l),%0I0x%x\n",
959 reg_names[FRAME_POINTER_REGNUM],
962 asm_fprintf (stream, "\tfmovem %s@(-%d,%Ra1:l),%0I0x%x\n",
963 reg_names[FRAME_POINTER_REGNUM],
964 foffset + fsize, fmask);
967 else if (restore_from_sp)
970 asm_fprintf (stream, "\tfmovm (%Rsp)+,%0I0x%x\n", fmask);
972 asm_fprintf (stream, "\tfmovem %Rsp@+,%0I0x%x\n", fmask);
978 asm_fprintf (stream, "\tfmovm -%d(%s),%0I0x%x\n",
980 reg_names[FRAME_POINTER_REGNUM],
983 asm_fprintf (stream, "\tfmovem %s@(-%d),%0I0x%x\n",
984 reg_names[FRAME_POINTER_REGNUM],
985 foffset + fsize, fmask);
990 for (regno = 55; regno >= 24; regno--)
991 if (regs_ever_live[regno] && ! call_used_regs[regno])
996 asm_fprintf (stream, "\tfpmovd -%d(%s,%Ra1.l), %s\n",
998 reg_names[FRAME_POINTER_REGNUM],
1001 asm_fprintf (stream, "\tfpmoved %s@(-%d,%Ra1:l), %s\n",
1002 reg_names[FRAME_POINTER_REGNUM],
1003 fpoffset + fsize, reg_names[regno]);
1006 else if (restore_from_sp)
1009 asm_fprintf (stream, "\tfpmovd (%Rsp)+,%s\n",
1012 asm_fprintf (stream, "\tfpmoved %Rsp@+, %s\n",
1019 fprintf (stream, "\tfpmovd -%d(%s), %s\n",
1021 reg_names[FRAME_POINTER_REGNUM],
1024 fprintf (stream, "\tfpmoved %s@(-%d), %s\n",
1025 reg_names[FRAME_POINTER_REGNUM],
1026 fpoffset + fsize, reg_names[regno]);
1031 if (frame_pointer_needed)
1032 fprintf (stream, "\tunlk %s\n",
1033 reg_names[FRAME_POINTER_REGNUM]);
1042 asm_fprintf (stream, "\taddq.w %0I%d,%Rsp\n", fsize + 4);
1044 asm_fprintf (stream, "\taddqw %0I%d,%Rsp\n", fsize + 4);
1050 asm_fprintf (stream, "\taddq.l %0I%d,%Rsp\n", fsize + 4);
1052 asm_fprintf (stream, "\taddql %0I%d,%Rsp\n", fsize + 4);
1056 else if (fsize + 4 <= 16 && TARGET_CPU32)
1058 /* On the CPU32 it is faster to use two addqw instructions to
1059 add a small integer (8 < N <= 16) to a register. */
1060 /* asm_fprintf() cannot handle %. */
1062 asm_fprintf (stream, "\taddq.w %0I8,%Rsp\n\taddq.w %0I%d,%Rsp\n",
1065 asm_fprintf (stream, "\taddqw %0I8,%Rsp\n\taddqw %0I%d,%Rsp\n",
1070 #endif /* not NO_ADDSUB_Q */
1071 if (fsize + 4 < 0x8000)
1075 /* asm_fprintf() cannot handle %. */
1077 asm_fprintf (stream, "\tadd.w %0I%d,%Rsp\n", fsize + 4);
1079 asm_fprintf (stream, "\taddw %0I%d,%Rsp\n", fsize + 4);
1085 asm_fprintf (stream, "\tlea (%d,%Rsp),%Rsp\n", fsize + 4);
1087 asm_fprintf (stream, "\tlea %Rsp@(%d),%Rsp\n", fsize + 4);
1093 /* asm_fprintf() cannot handle %. */
1095 asm_fprintf (stream, "\tadd.l %0I%d,%Rsp\n", fsize + 4);
1097 asm_fprintf (stream, "\taddl %0I%d,%Rsp\n", fsize + 4);
1101 if (current_function_pops_args)
1102 asm_fprintf (stream, "\trtd %0I%d\n", current_function_pops_args);
1104 fprintf (stream, "\trts\n");
1108 /* Similar to general_operand, but exclude stack_pointer_rtx. */
1111 not_sp_operand (op, mode)
1113 enum machine_mode mode;
1115 return op != stack_pointer_rtx && nonimmediate_operand (op, mode);
1118 /* Return TRUE if X is a valid comparison operator for the dbcc
1121 Note it rejects floating point comparison operators.
1122 (In the future we could use Fdbcc).
1124 It also rejects some comparisons when CC_NO_OVERFLOW is set. */
1127 valid_dbcc_comparison_p (x, mode)
1129 enum machine_mode mode ATTRIBUTE_UNUSED;
1131 switch (GET_CODE (x))
1133 case EQ: case NE: case GTU: case LTU:
1137 /* Reject some when CC_NO_OVERFLOW is set. This may be over
1139 case GT: case LT: case GE: case LE:
1140 return ! (cc_prev_status.flags & CC_NO_OVERFLOW);
1146 /* Return nonzero if flags are currently in the 68881 flag register. */
1150 /* We could add support for these in the future */
1151 return cc_status.flags & CC_IN_68881;
1154 /* Output a dbCC; jCC sequence. Note we do not handle the
1155 floating point version of this sequence (Fdbcc). We also
1156 do not handle alternative conditions when CC_NO_OVERFLOW is
1157 set. It is assumed that valid_dbcc_comparison_p and flags_in_68881 will
1158 kick those out before we get here. */
1161 output_dbcc_and_branch (operands)
1164 switch (GET_CODE (operands[3]))
1168 output_asm_insn ("dbeq %0,%l1\n\tjbeq %l2", operands);
1170 output_asm_insn ("dbeq %0,%l1\n\tjeq %l2", operands);
1176 output_asm_insn ("dbne %0,%l1\n\tjbne %l2", operands);
1178 output_asm_insn ("dbne %0,%l1\n\tjne %l2", operands);
1184 output_asm_insn ("dbgt %0,%l1\n\tjbgt %l2", operands);
1186 output_asm_insn ("dbgt %0,%l1\n\tjgt %l2", operands);
1192 output_asm_insn ("dbhi %0,%l1\n\tjbhi %l2", operands);
1194 output_asm_insn ("dbhi %0,%l1\n\tjhi %l2", operands);
1200 output_asm_insn ("dblt %0,%l1\n\tjblt %l2", operands);
1202 output_asm_insn ("dblt %0,%l1\n\tjlt %l2", operands);
1208 output_asm_insn ("dbcs %0,%l1\n\tjbcs %l2", operands);
1210 output_asm_insn ("dbcs %0,%l1\n\tjcs %l2", operands);
1216 output_asm_insn ("dbge %0,%l1\n\tjbge %l2", operands);
1218 output_asm_insn ("dbge %0,%l1\n\tjge %l2", operands);
1224 output_asm_insn ("dbcc %0,%l1\n\tjbcc %l2", operands);
1226 output_asm_insn ("dbcc %0,%l1\n\tjcc %l2", operands);
1232 output_asm_insn ("dble %0,%l1\n\tjble %l2", operands);
1234 output_asm_insn ("dble %0,%l1\n\tjle %l2", operands);
1240 output_asm_insn ("dbls %0,%l1\n\tjbls %l2", operands);
1242 output_asm_insn ("dbls %0,%l1\n\tjls %l2", operands);
1250 /* If the decrement is to be done in SImode, then we have
1251 to compensate for the fact that dbcc decrements in HImode. */
1252 switch (GET_MODE (operands[0]))
1256 output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjbpl %l1", operands);
1258 output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjpl %l1", operands);
1271 output_scc_di(op, operand1, operand2, dest)
1278 enum rtx_code op_code = GET_CODE (op);
1280 /* This does not produce a useful cc. */
1283 /* The m68k cmp.l instruction requires operand1 to be a reg as used
1284 below. Swap the operands and change the op if these requirements
1285 are not fulfilled. */
1286 if (GET_CODE (operand2) == REG && GET_CODE (operand1) != REG)
1290 operand1 = operand2;
1292 op_code = swap_condition (op_code);
1294 loperands[0] = operand1;
1295 if (GET_CODE (operand1) == REG)
1296 loperands[1] = gen_rtx_REG (SImode, REGNO (operand1) + 1);
1298 loperands[1] = adjust_address (operand1, SImode, 4);
1299 if (operand2 != const0_rtx)
1301 loperands[2] = operand2;
1302 if (GET_CODE (operand2) == REG)
1303 loperands[3] = gen_rtx_REG (SImode, REGNO (operand2) + 1);
1305 loperands[3] = adjust_address (operand2, SImode, 4);
1307 loperands[4] = gen_label_rtx();
1308 if (operand2 != const0_rtx)
1311 #ifdef SGS_CMP_ORDER
1312 output_asm_insn ("cmp%.l %0,%2\n\tjbne %l4\n\tcmp%.l %1,%3", loperands);
1314 output_asm_insn ("cmp%.l %2,%0\n\tjbne %l4\n\tcmp%.l %3,%1", loperands);
1317 #ifdef SGS_CMP_ORDER
1318 output_asm_insn ("cmp%.l %0,%2\n\tjne %l4\n\tcmp%.l %1,%3", loperands);
1320 output_asm_insn ("cmp%.l %2,%0\n\tjne %l4\n\tcmp%.l %3,%1", loperands);
1326 if (TARGET_68020 || TARGET_5200 || ! ADDRESS_REG_P (loperands[0]))
1327 output_asm_insn ("tst%.l %0", loperands);
1330 #ifdef SGS_CMP_ORDER
1331 output_asm_insn ("cmp%.w %0,%#0", loperands);
1333 output_asm_insn ("cmp%.w %#0,%0", loperands);
1338 output_asm_insn ("jbne %l4", loperands);
1340 output_asm_insn ("jne %l4", loperands);
1343 if (TARGET_68020 || TARGET_5200 || ! ADDRESS_REG_P (loperands[1]))
1344 output_asm_insn ("tst%.l %1", loperands);
1347 #ifdef SGS_CMP_ORDER
1348 output_asm_insn ("cmp%.w %1,%#0", loperands);
1350 output_asm_insn ("cmp%.w %#0,%1", loperands);
1355 loperands[5] = dest;
1360 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1361 CODE_LABEL_NUMBER (loperands[4]));
1362 output_asm_insn ("seq %5", loperands);
1366 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1367 CODE_LABEL_NUMBER (loperands[4]));
1368 output_asm_insn ("sne %5", loperands);
1372 loperands[6] = gen_label_rtx();
1374 output_asm_insn ("shi %5\n\tjbra %l6", loperands);
1376 output_asm_insn ("shi %5\n\tjra %l6", loperands);
1378 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1379 CODE_LABEL_NUMBER (loperands[4]));
1380 output_asm_insn ("sgt %5", loperands);
1381 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1382 CODE_LABEL_NUMBER (loperands[6]));
1386 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1387 CODE_LABEL_NUMBER (loperands[4]));
1388 output_asm_insn ("shi %5", loperands);
1392 loperands[6] = gen_label_rtx();
1394 output_asm_insn ("scs %5\n\tjbra %l6", loperands);
1396 output_asm_insn ("scs %5\n\tjra %l6", loperands);
1398 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1399 CODE_LABEL_NUMBER (loperands[4]));
1400 output_asm_insn ("slt %5", loperands);
1401 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1402 CODE_LABEL_NUMBER (loperands[6]));
1406 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1407 CODE_LABEL_NUMBER (loperands[4]));
1408 output_asm_insn ("scs %5", loperands);
1412 loperands[6] = gen_label_rtx();
1414 output_asm_insn ("scc %5\n\tjbra %l6", loperands);
1416 output_asm_insn ("scc %5\n\tjra %l6", loperands);
1418 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1419 CODE_LABEL_NUMBER (loperands[4]));
1420 output_asm_insn ("sge %5", loperands);
1421 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1422 CODE_LABEL_NUMBER (loperands[6]));
1426 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1427 CODE_LABEL_NUMBER (loperands[4]));
1428 output_asm_insn ("scc %5", loperands);
1432 loperands[6] = gen_label_rtx();
1434 output_asm_insn ("sls %5\n\tjbra %l6", loperands);
1436 output_asm_insn ("sls %5\n\tjra %l6", loperands);
1438 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1439 CODE_LABEL_NUMBER (loperands[4]));
1440 output_asm_insn ("sle %5", loperands);
1441 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1442 CODE_LABEL_NUMBER (loperands[6]));
1446 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1447 CODE_LABEL_NUMBER (loperands[4]));
1448 output_asm_insn ("sls %5", loperands);
1458 output_btst (operands, countop, dataop, insn, signpos)
1460 rtx countop, dataop;
1464 operands[0] = countop;
1465 operands[1] = dataop;
1467 if (GET_CODE (countop) == CONST_INT)
1469 register int count = INTVAL (countop);
1470 /* If COUNT is bigger than size of storage unit in use,
1471 advance to the containing unit of same size. */
1472 if (count > signpos)
1474 int offset = (count & ~signpos) / 8;
1475 count = count & signpos;
1476 operands[1] = dataop = adjust_address (dataop, QImode, offset);
1478 if (count == signpos)
1479 cc_status.flags = CC_NOT_POSITIVE | CC_Z_IN_NOT_N;
1481 cc_status.flags = CC_NOT_NEGATIVE | CC_Z_IN_NOT_N;
1483 /* These three statements used to use next_insns_test_no...
1484 but it appears that this should do the same job. */
1486 && next_insn_tests_no_inequality (insn))
1489 && next_insn_tests_no_inequality (insn))
1492 && next_insn_tests_no_inequality (insn))
1495 cc_status.flags = CC_NOT_NEGATIVE;
1497 return "btst %0,%1";
1500 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
1501 reference and a constant. */
1504 symbolic_operand (op, mode)
1506 enum machine_mode mode ATTRIBUTE_UNUSED;
1508 switch (GET_CODE (op))
1516 return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
1517 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
1518 && GET_CODE (XEXP (op, 1)) == CONST_INT);
1520 #if 0 /* Deleted, with corresponding change in m68k.h,
1521 so as to fit the specs. No CONST_DOUBLE is ever symbolic. */
1523 return GET_MODE (op) == mode;
1531 /* Check for sign_extend or zero_extend. Used for bit-count operands. */
1534 extend_operator(x, mode)
1536 enum machine_mode mode;
1538 if (mode != VOIDmode && GET_MODE(x) != mode)
1540 switch (GET_CODE(x))
1551 /* Legitimize PIC addresses. If the address is already
1552 position-independent, we return ORIG. Newly generated
1553 position-independent addresses go to REG. If we need more
1554 than one register, we lose.
1556 An address is legitimized by making an indirect reference
1557 through the Global Offset Table with the name of the symbol
1560 The assembler and linker are responsible for placing the
1561 address of the symbol in the GOT. The function prologue
1562 is responsible for initializing a5 to the starting address
1565 The assembler is also responsible for translating a symbol name
1566 into a constant displacement from the start of the GOT.
1568 A quick example may make things a little clearer:
1570 When not generating PIC code to store the value 12345 into _foo
1571 we would generate the following code:
1575 When generating PIC two transformations are made. First, the compiler
1576 loads the address of foo into a register. So the first transformation makes:
1581 The code in movsi will intercept the lea instruction and call this
1582 routine which will transform the instructions into:
1584 movel a5@(_foo:w), a0
1588 That (in a nutshell) is how *all* symbol and label references are
1592 legitimize_pic_address (orig, mode, reg)
1594 enum machine_mode mode ATTRIBUTE_UNUSED;
1598 /* First handle a simple SYMBOL_REF or LABEL_REF */
1599 if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF)
1604 pic_ref = gen_rtx_MEM (Pmode,
1605 gen_rtx_PLUS (Pmode,
1606 pic_offset_table_rtx, orig));
1607 current_function_uses_pic_offset_table = 1;
1608 RTX_UNCHANGING_P (pic_ref) = 1;
1609 emit_move_insn (reg, pic_ref);
1612 else if (GET_CODE (orig) == CONST)
1616 /* Make sure this is CONST has not already been legitimized */
1617 if (GET_CODE (XEXP (orig, 0)) == PLUS
1618 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
1624 /* legitimize both operands of the PLUS */
1625 if (GET_CODE (XEXP (orig, 0)) == PLUS)
1627 base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
1628 orig = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
1629 base == reg ? 0 : reg);
1633 if (GET_CODE (orig) == CONST_INT)
1634 return plus_constant (base, INTVAL (orig));
1635 pic_ref = gen_rtx_PLUS (Pmode, base, orig);
1636 /* Likewise, should we set special REG_NOTEs here? */
1642 typedef enum { MOVL, SWAP, NEGW, NOTW, NOTB, MOVQ } CONST_METHOD;
1644 static CONST_METHOD const_method PARAMS ((rtx));
1646 #define USE_MOVQ(i) ((unsigned)((i) + 128) <= 255)
1649 const_method (constant)
1655 i = INTVAL (constant);
1659 /* The Coldfire doesn't have byte or word operations. */
1660 /* FIXME: This may not be useful for the m68060 either */
1663 /* if -256 < N < 256 but N is not in range for a moveq
1664 N^ff will be, so use moveq #N^ff, dreg; not.b dreg. */
1665 if (USE_MOVQ (i ^ 0xff))
1667 /* Likewise, try with not.w */
1668 if (USE_MOVQ (i ^ 0xffff))
1670 /* This is the only value where neg.w is useful */
1673 /* Try also with swap */
1675 if (USE_MOVQ ((u >> 16) | (u << 16)))
1678 /* Otherwise, use move.l */
1683 const_int_cost (constant)
1686 switch (const_method (constant))
1689 /* Constants between -128 and 127 are cheap due to moveq */
1695 /* Constants easily generated by moveq + not.b/not.w/neg.w/swap */
1705 output_move_const_into_data_reg (operands)
1710 i = INTVAL (operands[1]);
1711 switch (const_method (operands[1]))
1714 #if defined (MOTOROLA) && !defined (CRDS)
1715 return "moveq%.l %1,%0";
1717 return "moveq %1,%0";
1720 operands[1] = GEN_INT (i ^ 0xff);
1721 #if defined (MOTOROLA) && !defined (CRDS)
1722 return "moveq%.l %1,%0\n\tnot%.b %0";
1724 return "moveq %1,%0\n\tnot%.b %0";
1727 operands[1] = GEN_INT (i ^ 0xffff);
1728 #if defined (MOTOROLA) && !defined (CRDS)
1729 return "moveq%.l %1,%0\n\tnot%.w %0";
1731 return "moveq %1,%0\n\tnot%.w %0";
1734 #if defined (MOTOROLA) && !defined (CRDS)
1735 return "moveq%.l %#-128,%0\n\tneg%.w %0";
1737 return "moveq %#-128,%0\n\tneg%.w %0";
1743 operands[1] = GEN_INT ((u << 16) | (u >> 16));
1744 #if defined (MOTOROLA) && !defined (CRDS)
1745 return "moveq%.l %1,%0\n\tswap %0";
1747 return "moveq %1,%0\n\tswap %0";
1751 return "move%.l %1,%0";
1758 output_move_simode_const (operands)
1761 if (operands[1] == const0_rtx
1762 && (DATA_REG_P (operands[0])
1763 || GET_CODE (operands[0]) == MEM)
1764 /* clr insns on 68000 read before writing.
1765 This isn't so on the 68010, but we have no TARGET_68010. */
1766 && ((TARGET_68020 || TARGET_5200)
1767 || !(GET_CODE (operands[0]) == MEM
1768 && MEM_VOLATILE_P (operands[0]))))
1770 else if (operands[1] == const0_rtx
1771 && ADDRESS_REG_P (operands[0]))
1772 return "sub%.l %0,%0";
1773 else if (DATA_REG_P (operands[0]))
1774 return output_move_const_into_data_reg (operands);
1775 else if (ADDRESS_REG_P (operands[0])
1776 && INTVAL (operands[1]) < 0x8000
1777 && INTVAL (operands[1]) >= -0x8000)
1778 return "move%.w %1,%0";
1779 else if (GET_CODE (operands[0]) == MEM
1780 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
1781 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
1782 && INTVAL (operands[1]) < 0x8000
1783 && INTVAL (operands[1]) >= -0x8000)
1785 return "move%.l %1,%0";
1789 output_move_simode (operands)
1792 if (GET_CODE (operands[1]) == CONST_INT)
1793 return output_move_simode_const (operands);
1794 else if ((GET_CODE (operands[1]) == SYMBOL_REF
1795 || GET_CODE (operands[1]) == CONST)
1796 && push_operand (operands[0], SImode))
1798 else if ((GET_CODE (operands[1]) == SYMBOL_REF
1799 || GET_CODE (operands[1]) == CONST)
1800 && ADDRESS_REG_P (operands[0]))
1801 return "lea %a1,%0";
1802 return "move%.l %1,%0";
1806 output_move_himode (operands)
1809 if (GET_CODE (operands[1]) == CONST_INT)
1811 if (operands[1] == const0_rtx
1812 && (DATA_REG_P (operands[0])
1813 || GET_CODE (operands[0]) == MEM)
1814 /* clr insns on 68000 read before writing.
1815 This isn't so on the 68010, but we have no TARGET_68010. */
1816 && ((TARGET_68020 || TARGET_5200)
1817 || !(GET_CODE (operands[0]) == MEM
1818 && MEM_VOLATILE_P (operands[0]))))
1820 else if (operands[1] == const0_rtx
1821 && ADDRESS_REG_P (operands[0]))
1822 return "sub%.l %0,%0";
1823 else if (DATA_REG_P (operands[0])
1824 && INTVAL (operands[1]) < 128
1825 && INTVAL (operands[1]) >= -128)
1827 #if defined(MOTOROLA) && !defined(CRDS)
1828 return "moveq%.l %1,%0";
1830 return "moveq %1,%0";
1833 else if (INTVAL (operands[1]) < 0x8000
1834 && INTVAL (operands[1]) >= -0x8000)
1835 return "move%.w %1,%0";
1837 else if (CONSTANT_P (operands[1]))
1838 return "move%.l %1,%0";
1840 /* Recognize the insn before a tablejump, one that refers
1841 to a table of offsets. Such an insn will need to refer
1842 to a label on the insn. So output one. Use the label-number
1843 of the table of offsets to generate this label. This code,
1844 and similar code below, assumes that there will be at most one
1845 reference to each table. */
1846 if (GET_CODE (operands[1]) == MEM
1847 && GET_CODE (XEXP (operands[1], 0)) == PLUS
1848 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == LABEL_REF
1849 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) != PLUS)
1851 rtx labelref = XEXP (XEXP (operands[1], 0), 1);
1852 #if defined (MOTOROLA) && !defined (SGS_SWITCH_TABLES)
1854 asm_fprintf (asm_out_file, "\tset %LLI%d,.+2\n",
1855 CODE_LABEL_NUMBER (XEXP (labelref, 0)));
1857 asm_fprintf (asm_out_file, "\t.set %LLI%d,.+2\n",
1858 CODE_LABEL_NUMBER (XEXP (labelref, 0)));
1859 #endif /* not SGS */
1860 #else /* SGS_SWITCH_TABLES or not MOTOROLA */
1861 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LI",
1862 CODE_LABEL_NUMBER (XEXP (labelref, 0)));
1863 #ifdef SGS_SWITCH_TABLES
1864 /* Set flag saying we need to define the symbol
1865 LD%n (with value L%n-LI%n) at the end of the switch table. */
1866 switch_table_difference_label_flag = 1;
1867 #endif /* SGS_SWITCH_TABLES */
1868 #endif /* SGS_SWITCH_TABLES or not MOTOROLA */
1870 #endif /* SGS_NO_LI */
1871 return "move%.w %1,%0";
1875 output_move_qimode (operands)
1880 /* This is probably useless, since it loses for pushing a struct
1881 of several bytes a byte at a time. */
1882 /* 68k family always modifies the stack pointer by at least 2, even for
1883 byte pushes. The 5200 (coldfire) does not do this. */
1884 if (GET_CODE (operands[0]) == MEM
1885 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
1886 && XEXP (XEXP (operands[0], 0), 0) == stack_pointer_rtx
1887 && ! ADDRESS_REG_P (operands[1])
1890 xoperands[1] = operands[1];
1892 = gen_rtx_MEM (QImode,
1893 gen_rtx_PLUS (VOIDmode, stack_pointer_rtx, const1_rtx));
1894 /* Just pushing a byte puts it in the high byte of the halfword. */
1895 /* We must put it in the low-order, high-numbered byte. */
1896 if (!reg_mentioned_p (stack_pointer_rtx, operands[1]))
1898 xoperands[3] = stack_pointer_rtx;
1900 output_asm_insn ("subq%.l %#2,%3\n\tmove%.b %1,%2", xoperands);
1902 output_asm_insn ("sub%.l %#2,%3\n\tmove%.b %1,%2", xoperands);
1906 output_asm_insn ("move%.b %1,%-\n\tmove%.b %@,%2", xoperands);
1910 /* clr and st insns on 68000 read before writing.
1911 This isn't so on the 68010, but we have no TARGET_68010. */
1912 if (!ADDRESS_REG_P (operands[0])
1913 && ((TARGET_68020 || TARGET_5200)
1914 || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
1916 if (operands[1] == const0_rtx)
1918 if ((!TARGET_5200 || DATA_REG_P (operands[0]))
1919 && GET_CODE (operands[1]) == CONST_INT
1920 && (INTVAL (operands[1]) & 255) == 255)
1926 if (GET_CODE (operands[1]) == CONST_INT
1927 && DATA_REG_P (operands[0])
1928 && INTVAL (operands[1]) < 128
1929 && INTVAL (operands[1]) >= -128)
1931 #if defined(MOTOROLA) && !defined(CRDS)
1932 return "moveq%.l %1,%0";
1934 return "moveq %1,%0";
1937 if (operands[1] == const0_rtx && ADDRESS_REG_P (operands[0]))
1938 return "sub%.l %0,%0";
1939 if (GET_CODE (operands[1]) != CONST_INT && CONSTANT_P (operands[1]))
1940 return "move%.l %1,%0";
1941 /* 68k family (including the 5200 coldfire) does not support byte moves to
1942 from address registers. */
1943 if (ADDRESS_REG_P (operands[0]) || ADDRESS_REG_P (operands[1]))
1944 return "move%.w %1,%0";
1945 return "move%.b %1,%0";
1949 output_move_stricthi (operands)
1952 if (operands[1] == const0_rtx
1953 /* clr insns on 68000 read before writing.
1954 This isn't so on the 68010, but we have no TARGET_68010. */
1955 && ((TARGET_68020 || TARGET_5200)
1956 || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
1958 return "move%.w %1,%0";
1962 output_move_strictqi (operands)
1965 if (operands[1] == const0_rtx
1966 /* clr insns on 68000 read before writing.
1967 This isn't so on the 68010, but we have no TARGET_68010. */
1968 && ((TARGET_68020 || TARGET_5200)
1969 || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
1971 return "move%.b %1,%0";
1974 /* Return the best assembler insn template
1975 for moving operands[1] into operands[0] as a fullword. */
1978 singlemove_string (operands)
1981 #ifdef SUPPORT_SUN_FPA
1982 if (FPA_REG_P (operands[0]) || FPA_REG_P (operands[1]))
1983 return "fpmoves %1,%0";
1985 if (GET_CODE (operands[1]) == CONST_INT)
1986 return output_move_simode_const (operands);
1987 return "move%.l %1,%0";
1991 /* Output assembler code to perform a doubleword move insn
1992 with operands OPERANDS. */
1995 output_move_double (operands)
2000 REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP
2005 rtx addreg0 = 0, addreg1 = 0;
2006 int dest_overlapped_low = 0;
2007 int size = GET_MODE_SIZE (GET_MODE (operands[0]));
2012 /* First classify both operands. */
2014 if (REG_P (operands[0]))
2016 else if (offsettable_memref_p (operands[0]))
2018 else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
2020 else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
2022 else if (GET_CODE (operands[0]) == MEM)
2027 if (REG_P (operands[1]))
2029 else if (CONSTANT_P (operands[1]))
2031 else if (offsettable_memref_p (operands[1]))
2033 else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
2035 else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
2037 else if (GET_CODE (operands[1]) == MEM)
2042 /* Check for the cases that the operand constraints are not
2043 supposed to allow to happen. Abort if we get one,
2044 because generating code for these cases is painful. */
2046 if (optype0 == RNDOP || optype1 == RNDOP)
2049 /* If one operand is decrementing and one is incrementing
2050 decrement the former register explicitly
2051 and change that operand into ordinary indexing. */
2053 if (optype0 == PUSHOP && optype1 == POPOP)
2055 operands[0] = XEXP (XEXP (operands[0], 0), 0);
2057 output_asm_insn ("sub%.l %#12,%0", operands);
2059 output_asm_insn ("subq%.l %#8,%0", operands);
2060 if (GET_MODE (operands[1]) == XFmode)
2061 operands[0] = gen_rtx_MEM (XFmode, operands[0]);
2062 else if (GET_MODE (operands[0]) == DFmode)
2063 operands[0] = gen_rtx_MEM (DFmode, operands[0]);
2065 operands[0] = gen_rtx_MEM (DImode, operands[0]);
2068 if (optype0 == POPOP && optype1 == PUSHOP)
2070 operands[1] = XEXP (XEXP (operands[1], 0), 0);
2072 output_asm_insn ("sub%.l %#12,%1", operands);
2074 output_asm_insn ("subq%.l %#8,%1", operands);
2075 if (GET_MODE (operands[1]) == XFmode)
2076 operands[1] = gen_rtx_MEM (XFmode, operands[1]);
2077 else if (GET_MODE (operands[1]) == DFmode)
2078 operands[1] = gen_rtx_MEM (DFmode, operands[1]);
2080 operands[1] = gen_rtx_MEM (DImode, operands[1]);
2084 /* If an operand is an unoffsettable memory ref, find a register
2085 we can increment temporarily to make it refer to the second word. */
2087 if (optype0 == MEMOP)
2088 addreg0 = find_addr_reg (XEXP (operands[0], 0));
2090 if (optype1 == MEMOP)
2091 addreg1 = find_addr_reg (XEXP (operands[1], 0));
2093 /* Ok, we can do one word at a time.
2094 Normally we do the low-numbered word first,
2095 but if either operand is autodecrementing then we
2096 do the high-numbered word first.
2098 In either case, set up in LATEHALF the operands to use
2099 for the high-numbered word and in some cases alter the
2100 operands in OPERANDS to be suitable for the low-numbered word. */
2104 if (optype0 == REGOP)
2106 latehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 2);
2107 middlehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
2109 else if (optype0 == OFFSOP)
2111 middlehalf[0] = adjust_address (operands[0], SImode, 4);
2112 latehalf[0] = adjust_address (operands[0], SImode, size - 4);
2116 middlehalf[0] = operands[0];
2117 latehalf[0] = operands[0];
2120 if (optype1 == REGOP)
2122 latehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
2123 middlehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
2125 else if (optype1 == OFFSOP)
2127 middlehalf[1] = adjust_address (operands[1], SImode, 4);
2128 latehalf[1] = adjust_address (operands[1], SImode, size - 4);
2130 else if (optype1 == CNSTOP)
2132 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2137 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2138 REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l);
2139 operands[1] = GEN_INT (l[0]);
2140 middlehalf[1] = GEN_INT (l[1]);
2141 latehalf[1] = GEN_INT (l[2]);
2143 else if (CONSTANT_P (operands[1]))
2145 /* actually, no non-CONST_DOUBLE constant should ever
2148 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
2149 latehalf[1] = constm1_rtx;
2151 latehalf[1] = const0_rtx;
2156 middlehalf[1] = operands[1];
2157 latehalf[1] = operands[1];
2161 /* size is not 12: */
2163 if (optype0 == REGOP)
2164 latehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
2165 else if (optype0 == OFFSOP)
2166 latehalf[0] = adjust_address (operands[0], SImode, size - 4);
2168 latehalf[0] = operands[0];
2170 if (optype1 == REGOP)
2171 latehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
2172 else if (optype1 == OFFSOP)
2173 latehalf[1] = adjust_address (operands[1], SImode, size - 4);
2174 else if (optype1 == CNSTOP)
2175 split_double (operands[1], &operands[1], &latehalf[1]);
2177 latehalf[1] = operands[1];
2180 /* If insn is effectively movd N(sp),-(sp) then we will do the
2181 high word first. We should use the adjusted operand 1 (which is N+4(sp))
2182 for the low word as well, to compensate for the first decrement of sp. */
2183 if (optype0 == PUSHOP
2184 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
2185 && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
2186 operands[1] = middlehalf[1] = latehalf[1];
2188 /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)),
2189 if the upper part of reg N does not appear in the MEM, arrange to
2190 emit the move late-half first. Otherwise, compute the MEM address
2191 into the upper part of N and use that as a pointer to the memory
2193 if (optype0 == REGOP
2194 && (optype1 == OFFSOP || optype1 == MEMOP))
2196 rtx testlow = gen_rtx_REG (SImode, REGNO (operands[0]));
2198 if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0))
2199 && reg_overlap_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
2201 /* If both halves of dest are used in the src memory address,
2202 compute the address into latehalf of dest.
2203 Note that this can't happen if the dest is two data regs. */
2205 xops[0] = latehalf[0];
2206 xops[1] = XEXP (operands[1], 0);
2207 output_asm_insn ("lea %a1,%0", xops);
2208 if (GET_MODE (operands[1]) == XFmode )
2210 operands[1] = gen_rtx_MEM (XFmode, latehalf[0]);
2211 middlehalf[1] = adjust_address (operands[1], DImode, size - 8);
2212 latehalf[1] = adjust_address (operands[1], DImode, size - 4);
2216 operands[1] = gen_rtx_MEM (DImode, latehalf[0]);
2217 latehalf[1] = adjust_address (operands[1], DImode, size - 4);
2221 && reg_overlap_mentioned_p (middlehalf[0],
2222 XEXP (operands[1], 0)))
2224 /* Check for two regs used by both source and dest.
2225 Note that this can't happen if the dest is all data regs.
2226 It can happen if the dest is d6, d7, a0.
2227 But in that case, latehalf is an addr reg, so
2228 the code at compadr does ok. */
2230 if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0))
2231 || reg_overlap_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
2234 /* JRV says this can't happen: */
2235 if (addreg0 || addreg1)
2238 /* Only the middle reg conflicts; simply put it last. */
2239 output_asm_insn (singlemove_string (operands), operands);
2240 output_asm_insn (singlemove_string (latehalf), latehalf);
2241 output_asm_insn (singlemove_string (middlehalf), middlehalf);
2244 else if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0)))
2245 /* If the low half of dest is mentioned in the source memory
2246 address, the arrange to emit the move late half first. */
2247 dest_overlapped_low = 1;
2250 /* If one or both operands autodecrementing,
2251 do the two words, high-numbered first. */
2253 /* Likewise, the first move would clobber the source of the second one,
2254 do them in the other order. This happens only for registers;
2255 such overlap can't happen in memory unless the user explicitly
2256 sets it up, and that is an undefined circumstance. */
2258 if (optype0 == PUSHOP || optype1 == PUSHOP
2259 || (optype0 == REGOP && optype1 == REGOP
2260 && ((middlehalf[1] && REGNO (operands[0]) == REGNO (middlehalf[1]))
2261 || REGNO (operands[0]) == REGNO (latehalf[1])))
2262 || dest_overlapped_low)
2264 /* Make any unoffsettable addresses point at high-numbered word. */
2268 output_asm_insn ("addq%.l %#8,%0", &addreg0);
2270 output_asm_insn ("addq%.l %#4,%0", &addreg0);
2275 output_asm_insn ("addq%.l %#8,%0", &addreg1);
2277 output_asm_insn ("addq%.l %#4,%0", &addreg1);
2281 output_asm_insn (singlemove_string (latehalf), latehalf);
2283 /* Undo the adds we just did. */
2285 output_asm_insn ("subq%.l %#4,%0", &addreg0);
2287 output_asm_insn ("subq%.l %#4,%0", &addreg1);
2291 output_asm_insn (singlemove_string (middlehalf), middlehalf);
2293 output_asm_insn ("subq%.l %#4,%0", &addreg0);
2295 output_asm_insn ("subq%.l %#4,%0", &addreg1);
2298 /* Do low-numbered word. */
2299 return singlemove_string (operands);
2302 /* Normal case: do the two words, low-numbered first. */
2304 output_asm_insn (singlemove_string (operands), operands);
2306 /* Do the middle one of the three words for long double */
2310 output_asm_insn ("addq%.l %#4,%0", &addreg0);
2312 output_asm_insn ("addq%.l %#4,%0", &addreg1);
2314 output_asm_insn (singlemove_string (middlehalf), middlehalf);
2317 /* Make any unoffsettable addresses point at high-numbered word. */
2319 output_asm_insn ("addq%.l %#4,%0", &addreg0);
2321 output_asm_insn ("addq%.l %#4,%0", &addreg1);
2324 output_asm_insn (singlemove_string (latehalf), latehalf);
2326 /* Undo the adds we just did. */
2330 output_asm_insn ("subq%.l %#8,%0", &addreg0);
2332 output_asm_insn ("subq%.l %#4,%0", &addreg0);
2337 output_asm_insn ("subq%.l %#8,%0", &addreg1);
2339 output_asm_insn ("subq%.l %#4,%0", &addreg1);
2345 /* Return a REG that occurs in ADDR with coefficient 1.
2346 ADDR can be effectively incremented by incrementing REG. */
2349 find_addr_reg (addr)
2352 while (GET_CODE (addr) == PLUS)
2354 if (GET_CODE (XEXP (addr, 0)) == REG)
2355 addr = XEXP (addr, 0);
2356 else if (GET_CODE (XEXP (addr, 1)) == REG)
2357 addr = XEXP (addr, 1);
2358 else if (CONSTANT_P (XEXP (addr, 0)))
2359 addr = XEXP (addr, 1);
2360 else if (CONSTANT_P (XEXP (addr, 1)))
2361 addr = XEXP (addr, 0);
2365 if (GET_CODE (addr) == REG)
2370 /* Output assembler code to perform a 32 bit 3 operand add. */
2373 output_addsi3 (operands)
2376 if (! operands_match_p (operands[0], operands[1]))
2378 if (!ADDRESS_REG_P (operands[1]))
2380 rtx tmp = operands[1];
2382 operands[1] = operands[2];
2386 /* These insns can result from reloads to access
2387 stack slots over 64k from the frame pointer. */
2388 if (GET_CODE (operands[2]) == CONST_INT
2389 && INTVAL (operands[2]) + 0x8000 >= (unsigned) 0x10000)
2390 return "move%.l %2,%0\n\tadd%.l %1,%0";
2392 if (GET_CODE (operands[2]) == REG)
2393 return "lea 0(%1,%2.l),%0";
2395 return "lea %c2(%1),%0";
2398 if (GET_CODE (operands[2]) == REG)
2399 return "lea (%1,%2.l),%0";
2401 return "lea (%c2,%1),%0";
2402 #else /* not MOTOROLA (MIT syntax) */
2403 if (GET_CODE (operands[2]) == REG)
2404 return "lea %1@(0,%2:l),%0";
2406 return "lea %1@(%c2),%0";
2407 #endif /* not MOTOROLA */
2408 #endif /* not SGS */
2410 if (GET_CODE (operands[2]) == CONST_INT)
2413 if (INTVAL (operands[2]) > 0
2414 && INTVAL (operands[2]) <= 8)
2415 return "addq%.l %2,%0";
2416 if (INTVAL (operands[2]) < 0
2417 && INTVAL (operands[2]) >= -8)
2419 operands[2] = GEN_INT (- INTVAL (operands[2]));
2420 return "subq%.l %2,%0";
2422 /* On the CPU32 it is faster to use two addql instructions to
2423 add a small integer (8 < N <= 16) to a register.
2424 Likewise for subql. */
2425 if (TARGET_CPU32 && REG_P (operands[0]))
2427 if (INTVAL (operands[2]) > 8
2428 && INTVAL (operands[2]) <= 16)
2430 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
2431 return "addq%.l %#8,%0\n\taddq%.l %2,%0";
2433 if (INTVAL (operands[2]) < -8
2434 && INTVAL (operands[2]) >= -16)
2436 operands[2] = GEN_INT (- INTVAL (operands[2]) - 8);
2437 return "subq%.l %#8,%0\n\tsubq%.l %2,%0";
2441 if (ADDRESS_REG_P (operands[0])
2442 && INTVAL (operands[2]) >= -0x8000
2443 && INTVAL (operands[2]) < 0x8000)
2446 return "add%.w %2,%0";
2449 return "lea (%c2,%0),%0";
2451 return "lea %0@(%c2),%0";
2455 return "add%.l %2,%0";
2458 /* Store in cc_status the expressions that the condition codes will
2459 describe after execution of an instruction whose pattern is EXP.
2460 Do not alter them if the instruction would not alter the cc's. */
2462 /* On the 68000, all the insns to store in an address register fail to
2463 set the cc's. However, in some cases these instructions can make it
2464 possibly invalid to use the saved cc's. In those cases we clear out
2465 some or all of the saved cc's so they won't be used. */
2468 notice_update_cc (exp, insn)
2472 /* If the cc is being set from the fpa and the expression is not an
2473 explicit floating point test instruction (which has code to deal with
2474 this), reinit the CC. */
2475 if (((cc_status.value1 && FPA_REG_P (cc_status.value1))
2476 || (cc_status.value2 && FPA_REG_P (cc_status.value2)))
2477 && !(GET_CODE (exp) == PARALLEL
2478 && GET_CODE (XVECEXP (exp, 0, 0)) == SET
2479 && XEXP (XVECEXP (exp, 0, 0), 0) == cc0_rtx))
2483 else if (GET_CODE (exp) == SET)
2485 if (GET_CODE (SET_SRC (exp)) == CALL)
2489 else if (ADDRESS_REG_P (SET_DEST (exp)))
2491 if (cc_status.value1 && modified_in_p (cc_status.value1, insn))
2492 cc_status.value1 = 0;
2493 if (cc_status.value2 && modified_in_p (cc_status.value2, insn))
2494 cc_status.value2 = 0;
2496 else if (!FP_REG_P (SET_DEST (exp))
2497 && SET_DEST (exp) != cc0_rtx
2498 && (FP_REG_P (SET_SRC (exp))
2499 || GET_CODE (SET_SRC (exp)) == FIX
2500 || GET_CODE (SET_SRC (exp)) == FLOAT_TRUNCATE
2501 || GET_CODE (SET_SRC (exp)) == FLOAT_EXTEND))
2505 /* A pair of move insns doesn't produce a useful overall cc. */
2506 else if (!FP_REG_P (SET_DEST (exp))
2507 && !FP_REG_P (SET_SRC (exp))
2508 && GET_MODE_SIZE (GET_MODE (SET_SRC (exp))) > 4
2509 && (GET_CODE (SET_SRC (exp)) == REG
2510 || GET_CODE (SET_SRC (exp)) == MEM
2511 || GET_CODE (SET_SRC (exp)) == CONST_DOUBLE))
2515 else if (GET_CODE (SET_SRC (exp)) == CALL)
2519 else if (XEXP (exp, 0) != pc_rtx)
2521 cc_status.flags = 0;
2522 cc_status.value1 = XEXP (exp, 0);
2523 cc_status.value2 = XEXP (exp, 1);
2526 else if (GET_CODE (exp) == PARALLEL
2527 && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
2529 if (ADDRESS_REG_P (XEXP (XVECEXP (exp, 0, 0), 0)))
2531 else if (XEXP (XVECEXP (exp, 0, 0), 0) != pc_rtx)
2533 cc_status.flags = 0;
2534 cc_status.value1 = XEXP (XVECEXP (exp, 0, 0), 0);
2535 cc_status.value2 = XEXP (XVECEXP (exp, 0, 0), 1);
2540 if (cc_status.value2 != 0
2541 && ADDRESS_REG_P (cc_status.value2)
2542 && GET_MODE (cc_status.value2) == QImode)
2544 if (cc_status.value2 != 0
2545 && !(cc_status.value1 && FPA_REG_P (cc_status.value1)))
2546 switch (GET_CODE (cc_status.value2))
2548 case PLUS: case MINUS: case MULT:
2549 case DIV: case UDIV: case MOD: case UMOD: case NEG:
2550 #if 0 /* These instructions always clear the overflow bit */
2551 case ASHIFT: case ASHIFTRT: case LSHIFTRT:
2552 case ROTATE: case ROTATERT:
2554 if (GET_MODE (cc_status.value2) != VOIDmode)
2555 cc_status.flags |= CC_NO_OVERFLOW;
2558 /* (SET r1 (ZERO_EXTEND r2)) on this machine
2559 ends with a move insn moving r2 in r2's mode.
2560 Thus, the cc's are set for r2.
2561 This can set N bit spuriously. */
2562 cc_status.flags |= CC_NOT_NEGATIVE;
2567 if (cc_status.value1 && GET_CODE (cc_status.value1) == REG
2569 && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
2570 cc_status.value2 = 0;
2571 if (((cc_status.value1 && FP_REG_P (cc_status.value1))
2572 || (cc_status.value2 && FP_REG_P (cc_status.value2)))
2573 && !((cc_status.value1 && FPA_REG_P (cc_status.value1))
2574 || (cc_status.value2 && FPA_REG_P (cc_status.value2))))
2575 cc_status.flags = CC_IN_68881;
2579 output_move_const_double (operands)
2582 #ifdef SUPPORT_SUN_FPA
2583 if (TARGET_FPA && FPA_REG_P (operands[0]))
2585 int code = standard_sun_fpa_constant_p (operands[1]);
2589 static char buf[40];
2591 sprintf (buf, "fpmove%%.d %%%%%d,%%0", code & 0x1ff);
2594 return "fpmove%.d %1,%0";
2599 int code = standard_68881_constant_p (operands[1]);
2603 static char buf[40];
2605 sprintf (buf, "fmovecr %%#0x%x,%%0", code & 0xff);
2608 return "fmove%.d %1,%0";
2613 output_move_const_single (operands)
2616 #ifdef SUPPORT_SUN_FPA
2619 int code = standard_sun_fpa_constant_p (operands[1]);
2623 static char buf[40];
2625 sprintf (buf, "fpmove%%.s %%%%%d,%%0", code & 0x1ff);
2628 return "fpmove%.s %1,%0";
2631 #endif /* defined SUPPORT_SUN_FPA */
2633 int code = standard_68881_constant_p (operands[1]);
2637 static char buf[40];
2639 sprintf (buf, "fmovecr %%#0x%x,%%0", code & 0xff);
2642 return "fmove%.s %f1,%0";
2646 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
2647 from the "fmovecr" instruction.
2648 The value, anded with 0xff, gives the code to use in fmovecr
2649 to get the desired constant. */
2651 /* This code has been fixed for cross-compilation. */
2653 static int inited_68881_table = 0;
2655 static const char *const strings_68881[7] = {
2665 static const int codes_68881[7] = {
2675 REAL_VALUE_TYPE values_68881[7];
2677 /* Set up values_68881 array by converting the decimal values
2678 strings_68881 to binary. */
2685 enum machine_mode mode;
2688 for (i = 0; i < 7; i++)
2692 r = REAL_VALUE_ATOF (strings_68881[i], mode);
2693 values_68881[i] = r;
2695 inited_68881_table = 1;
2699 standard_68881_constant_p (x)
2705 #ifdef NO_ASM_FMOVECR
2709 /* fmovecr must be emulated on the 68040 and 68060, so it shouldn't be
2710 used at all on those chips. */
2711 if (TARGET_68040 || TARGET_68060)
2714 if (! inited_68881_table)
2715 init_68881_table ();
2717 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2719 /* Use REAL_VALUES_IDENTICAL instead of REAL_VALUES_EQUAL so that -0.0
2721 for (i = 0; i < 6; i++)
2723 if (REAL_VALUES_IDENTICAL (r, values_68881[i]))
2724 return (codes_68881[i]);
2727 if (GET_MODE (x) == SFmode)
2730 if (REAL_VALUES_EQUAL (r, values_68881[6]))
2731 return (codes_68881[6]);
2733 /* larger powers of ten in the constants ram are not used
2734 because they are not equal to a `double' C constant. */
2738 /* If X is a floating-point constant, return the logarithm of X base 2,
2739 or 0 if X is not a power of 2. */
2742 floating_exact_log2 (x)
2745 REAL_VALUE_TYPE r, r1;
2748 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2750 if (REAL_VALUES_LESS (r, dconst1))
2753 exp = real_exponent (&r);
2754 real_2expN (&r1, exp);
2755 if (REAL_VALUES_EQUAL (r1, r))
2761 #ifdef SUPPORT_SUN_FPA
2762 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
2763 from the Sun FPA's constant RAM.
2764 The value returned, anded with 0x1ff, gives the code to use in fpmove
2765 to get the desired constant. */
2767 static int inited_FPA_table = 0;
2769 static const char *const strings_FPA[38] = {
2770 /* small rationals */
2783 /* Decimal equivalents of double precision values */
2784 "2.718281828459045091", /* D_E */
2785 "6.283185307179586477", /* 2 pi */
2786 "3.141592653589793116", /* D_PI */
2787 "1.570796326794896619", /* pi/2 */
2788 "1.414213562373095145", /* D_SQRT2 */
2789 "0.7071067811865475244", /* 1/sqrt(2) */
2790 "-1.570796326794896619", /* -pi/2 */
2791 "1.442695040888963387", /* D_LOG2ofE */
2792 "3.321928024887362182", /* D_LOG2of10 */
2793 "0.6931471805599452862", /* D_LOGEof2 */
2794 "2.302585092994045901", /* D_LOGEof10 */
2795 "0.3010299956639811980", /* D_LOG10of2 */
2796 "0.4342944819032518167", /* D_LOG10ofE */
2797 /* Decimal equivalents of single precision values */
2798 "2.718281745910644531", /* S_E */
2799 "6.283185307179586477", /* 2 pi */
2800 "3.141592741012573242", /* S_PI */
2801 "1.570796326794896619", /* pi/2 */
2802 "1.414213538169860840", /* S_SQRT2 */
2803 "0.7071067811865475244", /* 1/sqrt(2) */
2804 "-1.570796326794896619", /* -pi/2 */
2805 "1.442695021629333496", /* S_LOG2ofE */
2806 "3.321928024291992188", /* S_LOG2of10 */
2807 "0.6931471824645996094", /* S_LOGEof2 */
2808 "2.302585124969482442", /* S_LOGEof10 */
2809 "0.3010300099849700928", /* S_LOG10of2 */
2810 "0.4342944920063018799", /* S_LOG10ofE */
2814 static const int codes_FPA[38] = {
2815 /* small rationals */
2828 /* double precision */
2842 /* single precision */
2858 REAL_VALUE_TYPE values_FPA[38];
2860 /* This code has been fixed for cross-compilation. */
2862 static void init_FPA_table PARAMS ((void));
2866 enum machine_mode mode;
2871 for (i = 0; i < 38; i++)
2875 r = REAL_VALUE_ATOF (strings_FPA[i], mode);
2878 inited_FPA_table = 1;
2883 standard_sun_fpa_constant_p (x)
2889 if (! inited_FPA_table)
2892 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2894 for (i=0; i<12; i++)
2896 if (REAL_VALUES_EQUAL (r, values_FPA[i]))
2897 return (codes_FPA[i]);
2900 if (GET_MODE (x) == SFmode)
2902 for (i=25; i<38; i++)
2904 if (REAL_VALUES_EQUAL (r, values_FPA[i]))
2905 return (codes_FPA[i]);
2910 for (i=12; i<25; i++)
2912 if (REAL_VALUES_EQUAL (r, values_FPA[i]))
2913 return (codes_FPA[i]);
2918 #endif /* define SUPPORT_SUN_FPA */
2920 /* A C compound statement to output to stdio stream STREAM the
2921 assembler syntax for an instruction operand X. X is an RTL
2924 CODE is a value that can be used to specify one of several ways
2925 of printing the operand. It is used when identical operands
2926 must be printed differently depending on the context. CODE
2927 comes from the `%' specification that was used to request
2928 printing of the operand. If the specification was just `%DIGIT'
2929 then CODE is 0; if the specification was `%LTR DIGIT' then CODE
2930 is the ASCII code for LTR.
2932 If X is a register, this macro should print the register's name.
2933 The names can be found in an array `reg_names' whose type is
2934 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
2936 When the machine description has a specification `%PUNCT' (a `%'
2937 followed by a punctuation character), this macro is called with
2938 a null pointer for X and the punctuation character for CODE.
2940 The m68k specific codes are:
2942 '.' for dot needed in Motorola-style opcode names.
2943 '-' for an operand pushing on the stack:
2944 sp@-, -(sp) or -(%sp) depending on the style of syntax.
2945 '+' for an operand pushing on the stack:
2946 sp@+, (sp)+ or (%sp)+ depending on the style of syntax.
2947 '@' for a reference to the top word on the stack:
2948 sp@, (sp) or (%sp) depending on the style of syntax.
2949 '#' for an immediate operand prefix (# in MIT and Motorola syntax
2950 but & in SGS syntax, $ in CRDS/UNOS syntax).
2951 '!' for the cc register (used in an `and to cc' insn).
2952 '$' for the letter `s' in an op code, but only on the 68040.
2953 '&' for the letter `d' in an op code, but only on the 68040.
2954 '/' for register prefix needed by longlong.h.
2956 'b' for byte insn (no effect, on the Sun; this is for the ISI).
2957 'd' to force memory addressing to be absolute, not relative.
2958 'f' for float insn (print a CONST_DOUBLE as a float rather than in hex)
2959 'o' for operands to go directly to output_operand_address (bypassing
2960 print_operand_address--used only for SYMBOL_REFs under TARGET_PCREL)
2961 'w' for FPA insn (print a CONST_DOUBLE as a SunFPA constant rather
2962 than directly). Second part of 'y' below.
2963 'x' for float insn (print a CONST_DOUBLE as a float rather than in hex),
2964 or print pair of registers as rx:ry.
2965 'y' for a FPA insn (print pair of registers as rx:ry). This also outputs
2966 CONST_DOUBLE's as SunFPA constant RAM registers if
2967 possible, so it should not be used except for the SunFPA.
2972 print_operand (file, op, letter)
2973 FILE *file; /* file to write to */
2974 rtx op; /* operand to print */
2975 int letter; /* %<letter> or 0 */
2977 #ifdef SUPPORT_SUN_FPA
2983 #if defined (MOTOROLA) && !defined (CRDS)
2984 fprintf (file, ".");
2987 else if (letter == '#')
2989 asm_fprintf (file, "%0I");
2991 else if (letter == '-')
2994 asm_fprintf (file, "-(%Rsp)");
2996 asm_fprintf (file, "%Rsp@-");
2999 else if (letter == '+')
3002 asm_fprintf (file, "(%Rsp)+");
3004 asm_fprintf (file, "%Rsp@+");
3007 else if (letter == '@')
3010 asm_fprintf (file, "(%Rsp)");
3012 asm_fprintf (file, "%Rsp@");
3015 else if (letter == '!')
3017 asm_fprintf (file, "%Rfpcr");
3019 else if (letter == '$')
3021 if (TARGET_68040_ONLY)
3023 fprintf (file, "s");
3026 else if (letter == '&')
3028 if (TARGET_68040_ONLY)
3030 fprintf (file, "d");
3033 else if (letter == '/')
3035 asm_fprintf (file, "%R");
3037 else if (letter == 'o')
3039 /* This is only for direct addresses with TARGET_PCREL */
3040 if (GET_CODE (op) != MEM || GET_CODE (XEXP (op, 0)) != SYMBOL_REF
3043 output_addr_const (file, XEXP (op, 0));
3045 else if (GET_CODE (op) == REG)
3047 #ifdef SUPPORT_SUN_FPA
3049 && (letter == 'y' || letter == 'x')
3050 && GET_MODE (op) == DFmode)
3052 fprintf (file, "%s:%s", reg_names[REGNO (op)],
3053 reg_names[REGNO (op)+1]);
3059 /* Print out the second register name of a register pair.
3060 I.e., R (6) => 7. */
3061 fputs (reg_names[REGNO (op) + 1], file);
3063 fputs (reg_names[REGNO (op)], file);
3066 else if (GET_CODE (op) == MEM)
3068 output_address (XEXP (op, 0));
3069 if (letter == 'd' && ! TARGET_68020
3070 && CONSTANT_ADDRESS_P (XEXP (op, 0))
3071 && !(GET_CODE (XEXP (op, 0)) == CONST_INT
3072 && INTVAL (XEXP (op, 0)) < 0x8000
3073 && INTVAL (XEXP (op, 0)) >= -0x8000))
3076 fprintf (file, ".l");
3078 fprintf (file, ":l");
3082 #ifdef SUPPORT_SUN_FPA
3083 else if ((letter == 'y' || letter == 'w')
3084 && GET_CODE (op) == CONST_DOUBLE
3085 && (i = standard_sun_fpa_constant_p (op)))
3087 fprintf (file, "%%%d", i & 0x1ff);
3090 else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == SFmode)
3093 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
3094 ASM_OUTPUT_FLOAT_OPERAND (letter, file, r);
3096 else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == XFmode)
3099 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
3100 ASM_OUTPUT_LONG_DOUBLE_OPERAND (file, r);
3102 else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == DFmode)
3105 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
3106 ASM_OUTPUT_DOUBLE_OPERAND (file, r);
3110 /* Use `print_operand_address' instead of `output_addr_const'
3111 to ensure that we print relevant PIC stuff. */
3112 asm_fprintf (file, "%0I");
3114 && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST))
3115 print_operand_address (file, op);
3117 output_addr_const (file, op);
3122 /* A C compound statement to output to stdio stream STREAM the
3123 assembler syntax for an instruction operand that is a memory
3124 reference whose address is ADDR. ADDR is an RTL expression.
3126 Note that this contains a kludge that knows that the only reason
3127 we have an address (plus (label_ref...) (reg...)) when not generating
3128 PIC code is in the insn before a tablejump, and we know that m68k.md
3129 generates a label LInnn: on such an insn.
3131 It is possible for PIC to generate a (plus (label_ref...) (reg...))
3132 and we handle that just like we would a (plus (symbol_ref...) (reg...)).
3134 Some SGS assemblers have a bug such that "Lnnn-LInnn-2.b(pc,d0.l*2)"
3135 fails to assemble. Luckily "Lnnn(pc,d0.l*2)" produces the results
3136 we want. This difference can be accommodated by using an assembler
3137 define such "LDnnn" to be either "Lnnn-LInnn-2.b", "Lnnn", or any other
3138 string, as necessary. This is accomplished via the ASM_OUTPUT_CASE_END
3139 macro. See m68k/sgs.h for an example; for versions without the bug.
3140 Some assemblers refuse all the above solutions. The workaround is to
3141 emit "K(pc,d0.l*2)" with K being a small constant known to give the
3144 They also do not like things like "pea 1.w", so we simple leave off
3145 the .w on small constants.
3147 This routine is responsible for distinguishing between -fpic and -fPIC
3148 style relocations in an address. When generating -fpic code the
3149 offset is output in word mode (eg movel a5@(_foo:w), a0). When generating
3150 -fPIC code the offset is output in long mode (eg movel a5@(_foo:l), a0) */
3152 #ifndef ASM_OUTPUT_CASE_FETCH
3155 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
3156 asm_fprintf (file, "%LLD%d(%Rpc,%s.", labelno, regname)
3158 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
3159 asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.", labelno, labelno, regname)
3162 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
3163 asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:", labelno, labelno, regname)
3165 #endif /* ASM_OUTPUT_CASE_FETCH */
3168 print_operand_address (file, addr)
3172 register rtx reg1, reg2, breg, ireg;
3175 switch (GET_CODE (addr))
3179 fprintf (file, "(%s)", reg_names[REGNO (addr)]);
3181 fprintf (file, "%s@", reg_names[REGNO (addr)]);
3186 fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
3188 fprintf (file, "%s@-", reg_names[REGNO (XEXP (addr, 0))]);
3193 fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
3195 fprintf (file, "%s@+", reg_names[REGNO (XEXP (addr, 0))]);
3199 reg1 = reg2 = ireg = breg = offset = 0;
3200 if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
3202 offset = XEXP (addr, 0);
3203 addr = XEXP (addr, 1);
3205 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
3207 offset = XEXP (addr, 1);
3208 addr = XEXP (addr, 0);
3210 if (GET_CODE (addr) != PLUS)
3214 else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND)
3216 reg1 = XEXP (addr, 0);
3217 addr = XEXP (addr, 1);
3219 else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND)
3221 reg1 = XEXP (addr, 1);
3222 addr = XEXP (addr, 0);
3224 else if (GET_CODE (XEXP (addr, 0)) == MULT)
3226 reg1 = XEXP (addr, 0);
3227 addr = XEXP (addr, 1);
3229 else if (GET_CODE (XEXP (addr, 1)) == MULT)
3231 reg1 = XEXP (addr, 1);
3232 addr = XEXP (addr, 0);
3234 else if (GET_CODE (XEXP (addr, 0)) == REG)
3236 reg1 = XEXP (addr, 0);
3237 addr = XEXP (addr, 1);
3239 else if (GET_CODE (XEXP (addr, 1)) == REG)
3241 reg1 = XEXP (addr, 1);
3242 addr = XEXP (addr, 0);
3244 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT
3245 || GET_CODE (addr) == SIGN_EXTEND)
3257 #if 0 /* for OLD_INDEXING */
3258 else if (GET_CODE (addr) == PLUS)
3260 if (GET_CODE (XEXP (addr, 0)) == REG)
3262 reg2 = XEXP (addr, 0);
3263 addr = XEXP (addr, 1);
3265 else if (GET_CODE (XEXP (addr, 1)) == REG)
3267 reg2 = XEXP (addr, 1);
3268 addr = XEXP (addr, 0);
3280 if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND
3281 || GET_CODE (reg1) == MULT))
3282 || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
3287 else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
3292 if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF
3293 && ! (flag_pic && ireg == pic_offset_table_rtx))
3296 if (GET_CODE (ireg) == MULT)
3298 scale = INTVAL (XEXP (ireg, 1));
3299 ireg = XEXP (ireg, 0);
3301 if (GET_CODE (ireg) == SIGN_EXTEND)
3303 ASM_OUTPUT_CASE_FETCH (file,
3304 CODE_LABEL_NUMBER (XEXP (addr, 0)),
3305 reg_names[REGNO (XEXP (ireg, 0))]);
3306 fprintf (file, "w");
3310 ASM_OUTPUT_CASE_FETCH (file,
3311 CODE_LABEL_NUMBER (XEXP (addr, 0)),
3312 reg_names[REGNO (ireg)]);
3313 fprintf (file, "l");
3318 fprintf (file, "*%d", scale);
3320 fprintf (file, ":%d", scale);
3326 if (breg != 0 && ireg == 0 && GET_CODE (addr) == LABEL_REF
3327 && ! (flag_pic && breg == pic_offset_table_rtx))
3329 ASM_OUTPUT_CASE_FETCH (file,
3330 CODE_LABEL_NUMBER (XEXP (addr, 0)),
3331 reg_names[REGNO (breg)]);
3332 fprintf (file, "l)");
3335 if (ireg != 0 || breg != 0)
3342 if (! flag_pic && addr && GET_CODE (addr) == LABEL_REF)
3349 output_addr_const (file, addr);
3350 if (flag_pic && (breg == pic_offset_table_rtx))
3352 fprintf (file, "@GOT");
3354 fprintf (file, ".w");
3357 fprintf (file, "(%s", reg_names[REGNO (breg)]);
3363 fprintf (file, "%s@(", reg_names[REGNO (breg)]);
3366 output_addr_const (file, addr);
3367 if ((flag_pic == 1) && (breg == pic_offset_table_rtx))
3368 fprintf (file, ":w");
3369 if ((flag_pic == 2) && (breg == pic_offset_table_rtx))
3370 fprintf (file, ":l");
3372 if (addr != 0 && ireg != 0)
3377 if (ireg != 0 && GET_CODE (ireg) == MULT)
3379 scale = INTVAL (XEXP (ireg, 1));
3380 ireg = XEXP (ireg, 0);
3382 if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND)
3385 fprintf (file, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]);
3387 fprintf (file, "%s:w", reg_names[REGNO (XEXP (ireg, 0))]);
3393 fprintf (file, "%s.l", reg_names[REGNO (ireg)]);
3395 fprintf (file, "%s:l", reg_names[REGNO (ireg)]);
3401 fprintf (file, "*%d", scale);
3403 fprintf (file, ":%d", scale);
3409 else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF
3410 && ! (flag_pic && reg1 == pic_offset_table_rtx))
3412 ASM_OUTPUT_CASE_FETCH (file,
3413 CODE_LABEL_NUMBER (XEXP (addr, 0)),
3414 reg_names[REGNO (reg1)]);
3415 fprintf (file, "l)");
3418 /* FALL-THROUGH (is this really what we want?) */
3420 if (GET_CODE (addr) == CONST_INT
3421 && INTVAL (addr) < 0x8000
3422 && INTVAL (addr) >= -0x8000)
3426 /* Many SGS assemblers croak on size specifiers for constants. */
3427 fprintf (file, "%d", (int) INTVAL (addr));
3429 fprintf (file, "%d.w", (int) INTVAL (addr));
3432 fprintf (file, "%d:w", (int) INTVAL (addr));
3435 else if (GET_CODE (addr) == CONST_INT)
3437 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (addr));
3439 else if (TARGET_PCREL)
3442 output_addr_const (file, addr);
3444 asm_fprintf (file, ":w,%Rpc)");
3446 asm_fprintf (file, ":l,%Rpc)");
3450 /* Special case for SYMBOL_REF if the symbol name ends in
3451 `.<letter>', this can be mistaken as a size suffix. Put
3452 the name in parentheses. */
3453 if (GET_CODE (addr) == SYMBOL_REF
3454 && strlen (XSTR (addr, 0)) > 2
3455 && XSTR (addr, 0)[strlen (XSTR (addr, 0)) - 2] == '.')
3458 output_addr_const (file, addr);
3462 output_addr_const (file, addr);
3468 /* Check for cases where a clr insns can be omitted from code using
3469 strict_low_part sets. For example, the second clrl here is not needed:
3470 clrl d0; movw a0@+,d0; use d0; clrl d0; movw a0@+; use d0; ...
3472 MODE is the mode of this STRICT_LOW_PART set. FIRST_INSN is the clear
3473 insn we are checking for redundancy. TARGET is the register set by the
3477 strict_low_part_peephole_ok (mode, first_insn, target)
3478 enum machine_mode mode;
3484 p = prev_nonnote_insn (first_insn);
3488 /* If it isn't an insn, then give up. */
3489 if (GET_CODE (p) != INSN)
3492 if (reg_set_p (target, p))
3494 rtx set = single_set (p);
3497 /* If it isn't an easy to recognize insn, then give up. */
3501 dest = SET_DEST (set);
3503 /* If this sets the entire target register to zero, then our
3504 first_insn is redundant. */
3505 if (rtx_equal_p (dest, target)
3506 && SET_SRC (set) == const0_rtx)
3508 else if (GET_CODE (dest) == STRICT_LOW_PART
3509 && GET_CODE (XEXP (dest, 0)) == REG
3510 && REGNO (XEXP (dest, 0)) == REGNO (target)
3511 && (GET_MODE_SIZE (GET_MODE (XEXP (dest, 0)))
3512 <= GET_MODE_SIZE (mode)))
3513 /* This is a strict low part set which modifies less than
3514 we are using, so it is safe. */
3520 p = prev_nonnote_insn (p);
3527 /* Accept integer operands in the range 0..0xffffffff. We have to check the
3528 range carefully since this predicate is used in DImode contexts. Also, we
3529 need some extra crud to make it work when hosted on 64-bit machines. */
3532 const_uint32_operand (op, mode)
3534 enum machine_mode mode;
3536 /* It doesn't make sense to ask this question with a mode that is
3537 not larger than 32 bits. */
3538 if (GET_MODE_BITSIZE (mode) <= 32)
3541 #if HOST_BITS_PER_WIDE_INT > 32
3542 /* All allowed constants will fit a CONST_INT. */
3543 return (GET_CODE (op) == CONST_INT
3544 && (INTVAL (op) >= 0 && INTVAL (op) <= 0xffffffffL));
3546 return (GET_CODE (op) == CONST_INT
3547 || (GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_HIGH (op) == 0));
3551 /* Accept integer operands in the range -0x80000000..0x7fffffff. We have
3552 to check the range carefully since this predicate is used in DImode
3556 const_sint32_operand (op, mode)
3558 enum machine_mode mode;
3560 /* It doesn't make sense to ask this question with a mode that is
3561 not larger than 32 bits. */
3562 if (GET_MODE_BITSIZE (mode) <= 32)
3565 /* All allowed constants will fit a CONST_INT. */
3566 return (GET_CODE (op) == CONST_INT
3567 && (INTVAL (op) >= (-0x7fffffff - 1) && INTVAL (op) <= 0x7fffffff));
3570 /* Operand predicates for implementing asymmetric pc-relative addressing
3571 on m68k. The m68k supports pc-relative addressing (mode 7, register 2)
3572 when used as a source operand, but not as a destintation operand.
3574 We model this by restricting the meaning of the basic predicates
3575 (general_operand, memory_operand, etc) to forbid the use of this
3576 addressing mode, and then define the following predicates that permit
3577 this addressing mode. These predicates can then be used for the
3578 source operands of the appropriate instructions.
3580 n.b. While it is theoretically possible to change all machine patterns
3581 to use this addressing more where permitted by the architecture,
3582 it has only been implemented for "common" cases: SImode, HImode, and
3583 QImode operands, and only for the principle operations that would
3584 require this addressing mode: data movement and simple integer operations.
3586 In parallel with these new predicates, two new constraint letters
3587 were defined: 'S' and 'T'. 'S' is the -mpcrel analog of 'm'.
3588 'T' replaces 's' in the non-pcrel case. It is a no-op in the pcrel case.
3589 In the pcrel case 's' is only valid in combination with 'a' registers.
3590 See addsi3, subsi3, cmpsi, and movsi patterns for a better understanding
3591 of how these constraints are used.
3593 The use of these predicates is strictly optional, though patterns that
3594 don't will cause an extra reload register to be allocated where one
3597 lea (abc:w,%pc),%a0 ; need to reload address
3598 moveq &1,%d1 ; since write to pc-relative space
3599 movel %d1,%a0@ ; is not allowed
3601 lea (abc:w,%pc),%a1 ; no need to reload address here
3602 movel %a1@,%d0 ; since "movel (abc:w,%pc),%d0" is ok
3604 For more info, consult tiemann@cygnus.com.
3607 All of the ugliness with predicates and constraints is due to the
3608 simple fact that the m68k does not allow a pc-relative addressing
3609 mode as a destination. gcc does not distinguish between source and
3610 destination addresses. Hence, if we claim that pc-relative address
3611 modes are valid, e.g. GO_IF_LEGITIMATE_ADDRESS accepts them, then we
3612 end up with invalid code. To get around this problem, we left
3613 pc-relative modes as invalid addresses, and then added special
3614 predicates and constraints to accept them.
3616 A cleaner way to handle this is to modify gcc to distinguish
3617 between source and destination addresses. We can then say that
3618 pc-relative is a valid source address but not a valid destination
3619 address, and hopefully avoid a lot of the predicate and constraint
3620 hackery. Unfortunately, this would be a pretty big change. It would
3621 be a useful change for a number of ports, but there aren't any current
3622 plans to undertake this.
3624 ***************************************************************************/
3627 /* Special case of a general operand that's used as a source operand.
3628 Use this to permit reads from PC-relative memory when -mpcrel
3632 general_src_operand (op, mode)
3634 enum machine_mode mode;
3637 && GET_CODE (op) == MEM
3638 && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
3639 || GET_CODE (XEXP (op, 0)) == LABEL_REF
3640 || GET_CODE (XEXP (op, 0)) == CONST))
3642 return general_operand (op, mode);
3645 /* Special case of a nonimmediate operand that's used as a source.
3646 Use this to permit reads from PC-relative memory when -mpcrel
3650 nonimmediate_src_operand (op, mode)
3652 enum machine_mode mode;
3654 if (TARGET_PCREL && GET_CODE (op) == MEM
3655 && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
3656 || GET_CODE (XEXP (op, 0)) == LABEL_REF
3657 || GET_CODE (XEXP (op, 0)) == CONST))
3659 return nonimmediate_operand (op, mode);
3662 /* Special case of a memory operand that's used as a source.
3663 Use this to permit reads from PC-relative memory when -mpcrel
3667 memory_src_operand (op, mode)
3669 enum machine_mode mode;
3671 if (TARGET_PCREL && GET_CODE (op) == MEM
3672 && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
3673 || GET_CODE (XEXP (op, 0)) == LABEL_REF
3674 || GET_CODE (XEXP (op, 0)) == CONST))
3676 return memory_operand (op, mode);
3679 /* Predicate that accepts only a pc-relative address. This is needed
3680 because pc-relative addresses don't satisfy the predicate
3681 "general_src_operand". */
3684 pcrel_address (op, mode)
3686 enum machine_mode mode ATTRIBUTE_UNUSED;
3688 return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF
3689 || GET_CODE (op) == CONST);
3693 output_andsi3 (operands)
3697 if (GET_CODE (operands[2]) == CONST_INT
3698 && (INTVAL (operands[2]) | 0xffff) == 0xffffffff
3699 && (DATA_REG_P (operands[0])
3700 || offsettable_memref_p (operands[0]))
3703 if (GET_CODE (operands[0]) != REG)
3704 operands[0] = adjust_address (operands[0], HImode, 2);
3705 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
3706 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3708 if (operands[2] == const0_rtx)
3710 return "and%.w %2,%0";
3712 if (GET_CODE (operands[2]) == CONST_INT
3713 && (logval = exact_log2 (~ INTVAL (operands[2]))) >= 0
3714 && (DATA_REG_P (operands[0])
3715 || offsettable_memref_p (operands[0])))
3717 if (DATA_REG_P (operands[0]))
3719 operands[1] = GEN_INT (logval);
3723 operands[0] = adjust_address (operands[0], SImode, 3 - (logval / 8));
3724 operands[1] = GEN_INT (logval % 8);
3726 /* This does not set condition codes in a standard way. */
3728 return "bclr %1,%0";
3730 return "and%.l %2,%0";
3734 output_iorsi3 (operands)
3737 register int logval;
3738 if (GET_CODE (operands[2]) == CONST_INT
3739 && INTVAL (operands[2]) >> 16 == 0
3740 && (DATA_REG_P (operands[0])
3741 || offsettable_memref_p (operands[0]))
3744 if (GET_CODE (operands[0]) != REG)
3745 operands[0] = adjust_address (operands[0], HImode, 2);
3746 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3748 if (INTVAL (operands[2]) == 0xffff)
3749 return "mov%.w %2,%0";
3750 return "or%.w %2,%0";
3752 if (GET_CODE (operands[2]) == CONST_INT
3753 && (logval = exact_log2 (INTVAL (operands[2]))) >= 0
3754 && (DATA_REG_P (operands[0])
3755 || offsettable_memref_p (operands[0])))
3757 if (DATA_REG_P (operands[0]))
3758 operands[1] = GEN_INT (logval);
3761 operands[0] = adjust_address (operands[0], SImode, 3 - (logval / 8));
3762 operands[1] = GEN_INT (logval % 8);
3765 return "bset %1,%0";
3767 return "or%.l %2,%0";
3771 output_xorsi3 (operands)
3774 register int logval;
3775 if (GET_CODE (operands[2]) == CONST_INT
3776 && INTVAL (operands[2]) >> 16 == 0
3777 && (offsettable_memref_p (operands[0]) || DATA_REG_P (operands[0]))
3780 if (! DATA_REG_P (operands[0]))
3781 operands[0] = adjust_address (operands[0], HImode, 2);
3782 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3784 if (INTVAL (operands[2]) == 0xffff)
3786 return "eor%.w %2,%0";
3788 if (GET_CODE (operands[2]) == CONST_INT
3789 && (logval = exact_log2 (INTVAL (operands[2]))) >= 0
3790 && (DATA_REG_P (operands[0])
3791 || offsettable_memref_p (operands[0])))
3793 if (DATA_REG_P (operands[0]))
3794 operands[1] = GEN_INT (logval);
3797 operands[0] = adjust_address (operands[0], SImode, 3 - (logval / 8));
3798 operands[1] = GEN_INT (logval % 8);
3801 return "bchg %1,%0";
3803 return "eor%.l %2,%0";
3806 /* Output assembly to switch to section NAME with attribute FLAGS. */
3809 m68k_coff_asm_named_section (name, flags)
3815 if (flags & SECTION_WRITE)
3820 fprintf (asm_out_file, "\t.section\t%s,\"%c\"\n", name, flagchar);
3823 #ifdef CTOR_LIST_BEGIN
3825 m68k_svr3_asm_out_constructor (symbol, priority)
3827 int priority ATTRIBUTE_UNUSED;
3832 xop[0] = gen_rtx_MEM (SImode, gen_rtx_PRE_DEC (SImode, stack_pointer_rtx));
3835 output_asm_insn (output_move_simode (xop), xop);
3840 m68k_output_mi_thunk (file, thunk, delta, function)
3842 tree thunk ATTRIBUTE_UNUSED;
3846 if (delta > 0 && delta <= 8)
3847 asm_fprintf (file, "\taddq.l %I%d,4(%Rsp)\n", (int) delta);
3848 else if (delta < 0 && delta >= -8)
3849 asm_fprintf (file, "\tsubq.l %I%d,4(%Rsp)\n", (int) -delta);
3852 asm_fprintf (file, "\tadd.l %I");
3853 fprintf (file, HOST_WIDE_INT_PRINT_DEC, delta);
3854 asm_fprintf (file, ",4(%Rsp)\n", delta);
3859 fprintf (file, "\tbra.l ");
3860 assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
3861 fprintf (file, "@PLTPC\n");
3865 fprintf (file, "\tjmp ");
3866 assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
3867 fprintf (file, "\n");