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));
68 static void m68k_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
69 HOST_WIDE_INT, tree));
70 static int m68k_save_reg PARAMS ((unsigned int));
73 /* Alignment to use for loops and jumps */
74 /* Specify power of two alignment used for loops. */
75 const char *m68k_align_loops_string;
76 /* Specify power of two alignment used for non-loop jumps. */
77 const char *m68k_align_jumps_string;
78 /* Specify power of two alignment used for functions. */
79 const char *m68k_align_funcs_string;
81 /* Specify power of two alignment used for loops. */
83 /* Specify power of two alignment used for non-loop jumps. */
85 /* Specify power of two alignment used for functions. */
88 /* Nonzero if the last compare/test insn had FP operands. The
89 sCC expanders peek at this to determine what to do for the
90 68060, which has no fsCC instructions. */
91 int m68k_last_compare_had_fp_operands;
93 /* Initialize the GCC target structure. */
95 #if INT_OP_GROUP == INT_OP_DOT_WORD
96 #undef TARGET_ASM_ALIGNED_HI_OP
97 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
100 #if INT_OP_GROUP == INT_OP_NO_DOT
101 #undef TARGET_ASM_BYTE_OP
102 #define TARGET_ASM_BYTE_OP "\tbyte\t"
103 #undef TARGET_ASM_ALIGNED_HI_OP
104 #define TARGET_ASM_ALIGNED_HI_OP "\tshort\t"
105 #undef TARGET_ASM_ALIGNED_SI_OP
106 #define TARGET_ASM_ALIGNED_SI_OP "\tlong\t"
109 #if INT_OP_GROUP == INT_OP_DC
110 #undef TARGET_ASM_BYTE_OP
111 #define TARGET_ASM_BYTE_OP "\tdc.b\t"
112 #undef TARGET_ASM_ALIGNED_HI_OP
113 #define TARGET_ASM_ALIGNED_HI_OP "\tdc.w\t"
114 #undef TARGET_ASM_ALIGNED_SI_OP
115 #define TARGET_ASM_ALIGNED_SI_OP "\tdc.l\t"
118 #undef TARGET_ASM_UNALIGNED_HI_OP
119 #define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP
120 #undef TARGET_ASM_UNALIGNED_SI_OP
121 #define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP
123 #undef TARGET_ASM_FUNCTION_PROLOGUE
124 #define TARGET_ASM_FUNCTION_PROLOGUE m68k_output_function_prologue
125 #undef TARGET_ASM_FUNCTION_EPILOGUE
126 #define TARGET_ASM_FUNCTION_EPILOGUE m68k_output_function_epilogue
128 #undef TARGET_ASM_OUTPUT_MI_THUNK
129 #define TARGET_ASM_OUTPUT_MI_THUNK m68k_output_mi_thunk
130 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
131 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
133 struct gcc_target targetm = TARGET_INITIALIZER;
135 /* Sometimes certain combinations of command options do not make
136 sense on a particular target machine. You can define a macro
137 `OVERRIDE_OPTIONS' to take account of this. This macro, if
138 defined, is executed once just after all the command options have
141 Don't use this macro to turn on various extra optimizations for
142 `-O'. That is what `OPTIMIZATION_OPTIONS' is for. */
152 /* Validate -malign-loops= value, or provide default */
153 m68k_align_loops = def_align;
154 if (m68k_align_loops_string)
156 i = atoi (m68k_align_loops_string);
157 if (i < 1 || i > MAX_CODE_ALIGN)
158 error ("-malign-loops=%d is not between 1 and %d", i, MAX_CODE_ALIGN);
160 m68k_align_loops = i;
163 /* Validate -malign-jumps= value, or provide default */
164 m68k_align_jumps = def_align;
165 if (m68k_align_jumps_string)
167 i = atoi (m68k_align_jumps_string);
168 if (i < 1 || i > MAX_CODE_ALIGN)
169 error ("-malign-jumps=%d is not between 1 and %d", i, MAX_CODE_ALIGN);
171 m68k_align_jumps = i;
174 /* Validate -malign-functions= value, or provide default */
175 m68k_align_funcs = def_align;
176 if (m68k_align_funcs_string)
178 i = atoi (m68k_align_funcs_string);
179 if (i < 1 || i > MAX_CODE_ALIGN)
180 error ("-malign-functions=%d is not between 1 and %d",
183 m68k_align_funcs = i;
186 /* -fPIC uses 32-bit pc-relative displacements, which don't exist
188 if (! TARGET_68020 && flag_pic == 2)
189 error("-fPIC is not currently supported on the 68000 or 68010\n");
191 /* ??? A historic way of turning on pic, or is this intended to
192 be an embedded thing that doesn't have the same name binding
193 significance that it does on hosted ELF systems? */
194 if (TARGET_PCREL && flag_pic == 0)
197 /* Turn off function cse if we are doing PIC. We always want function call
198 to be done as `bsr foo@PLTPC', so it will force the assembler to create
199 the PLT entry for `foo'. Doing function cse will cause the address of
200 `foo' to be loaded into a register, which is exactly what we want to
201 avoid when we are doing PIC on svr4 m68k. */
203 flag_no_function_cse = 1;
205 SUBTARGET_OVERRIDE_OPTIONS;
207 /* Tell the compiler which flavor of XFmode we're using. */
208 real_format_for_mode[XFmode - QFmode] = &ieee_extended_motorola_format;
211 /* Return 1 if we need to save REGNO. */
213 m68k_save_reg (regno)
216 if (flag_pic && current_function_uses_pic_offset_table
217 && regno == PIC_OFFSET_TABLE_REGNUM)
220 if (current_function_calls_eh_return)
225 unsigned int test = EH_RETURN_DATA_REGNO (i);
226 if (test == INVALID_REGNUM)
233 return (regs_ever_live[regno]
234 && !call_used_regs[regno]
235 && !fixed_regs[regno]
236 && !(regno == FRAME_POINTER_REGNUM && frame_pointer_needed));
239 /* This function generates the assembly code for function entry.
240 STREAM is a stdio stream to output the code to.
241 SIZE is an int: how many units of temporary storage to allocate.
242 Refer to the array `regs_ever_live' to determine which registers
243 to save; `regs_ever_live[I]' is nonzero if register number I
244 is ever used in the function. This function is responsible for
245 knowing which registers should not be saved even if used. */
248 /* Note that the order of the bit mask for fmovem is the opposite
249 of the order for movem! */
254 m68k_output_function_prologue (stream, size)
259 register int mask = 0;
260 HOST_WIDE_INT fsize = ((size) + 3) & -4;
262 /* unos stack probe */
265 fprintf (stream, "\tmovel sp,a0\n");
266 fprintf (stream, "\taddl $-%d,a0\n", 2048 + fsize);
267 fprintf (stream, "\ttstb (a0)\n");
270 fprintf (stream, "\ttstb -%d(sp)\n", 2048 + fsize);
272 if (frame_pointer_needed)
274 if (TARGET_68020 || fsize < 0x8000)
275 fprintf (stream, "\tlink a6,$%d\n", -fsize);
277 fprintf (stream, "\tlink a6,$0\n\tsubl $%d,sp\n", fsize);
281 /* Adding negative number is faster on the 68040. */
282 if (fsize + 4 < 0x8000)
283 fprintf (stream, "\tadd.w $%d,sp\n", - (fsize + 4));
285 fprintf (stream, "\tadd.l $%d,sp\n", - (fsize + 4));
288 for (regno = 16; regno < 24; regno++)
289 if (m68k_save_reg (regno))
290 mask |= 1 << (regno - 16);
292 if ((mask & 0xff) != 0)
293 fprintf (stream, "\tfmovem $0x%x,-(sp)\n", mask & 0xff);
296 for (regno = 0; regno < 16; regno++)
297 if (m68k_save_reg (regno))
298 mask |= 1 << (15 - regno);
300 if (exact_log2 (mask) >= 0)
301 fprintf (stream, "\tmovel %s,-(sp)\n", reg_names[15 - exact_log2 (mask)]);
303 fprintf (stream, "\tmovem $0x%x,-(sp)\n", mask);
309 m68k_output_function_prologue (stream, size)
314 register int mask = 0;
315 int num_saved_regs = 0;
316 HOST_WIDE_INT fsize = (size + 3) & -4;
317 HOST_WIDE_INT cfa_offset = INCOMING_FRAME_SP_OFFSET;
318 HOST_WIDE_INT cfa_store_offset = cfa_offset;
320 /* If the stack limit is a symbol, we can check it here,
321 before actually allocating the space. */
322 if (current_function_limit_stack
323 && GET_CODE (stack_limit_rtx) == SYMBOL_REF)
325 #if defined (MOTOROLA)
326 asm_fprintf (stream, "\tcmp.l %0I%s+%d,%Rsp\n\ttrapcs\n",
327 XSTR (stack_limit_rtx, 0), fsize + 4);
329 asm_fprintf (stream, "\tcmpl %0I%s+%d,%Rsp\n\ttrapcs\n",
330 XSTR (stack_limit_rtx, 0), fsize + 4);
334 if (frame_pointer_needed)
336 if (fsize == 0 && TARGET_68040)
338 /* on the 68040, pea + move is faster than link.w 0 */
340 fprintf (stream, "\tpea (%s)\n\tmove.l %s,%s\n",
341 reg_names[FRAME_POINTER_REGNUM],
342 reg_names[STACK_POINTER_REGNUM],
343 reg_names[FRAME_POINTER_REGNUM]);
345 fprintf (stream, "\tpea %s@\n\tmovel %s,%s\n",
346 reg_names[FRAME_POINTER_REGNUM],
347 reg_names[STACK_POINTER_REGNUM],
348 reg_names[FRAME_POINTER_REGNUM]);
351 else if (fsize < 0x8000)
354 asm_fprintf (stream, "\tlink.w %s,%0I%d\n",
355 reg_names[FRAME_POINTER_REGNUM], -fsize);
357 asm_fprintf (stream, "\tlink %s,%0I%d\n",
358 reg_names[FRAME_POINTER_REGNUM], -fsize);
361 else if (TARGET_68020)
364 asm_fprintf (stream, "\tlink.l %s,%0I%d\n",
365 reg_names[FRAME_POINTER_REGNUM], -fsize);
367 asm_fprintf (stream, "\tlink %s,%0I%d\n",
368 reg_names[FRAME_POINTER_REGNUM], -fsize);
373 /* Adding negative number is faster on the 68040. */
375 asm_fprintf (stream, "\tlink.w %s,%0I0\n\tadd.l %0I%d,%Rsp\n",
376 reg_names[FRAME_POINTER_REGNUM], -fsize);
378 asm_fprintf (stream, "\tlink %s,%0I0\n\taddl %0I%d,%Rsp\n",
379 reg_names[FRAME_POINTER_REGNUM], -fsize);
382 if (dwarf2out_do_frame ())
385 l = (char *) dwarf2out_cfi_label ();
386 cfa_store_offset += 4;
387 cfa_offset = cfa_store_offset;
388 dwarf2out_reg_save (l, FRAME_POINTER_REGNUM, -cfa_store_offset);
389 dwarf2out_def_cfa (l, FRAME_POINTER_REGNUM, cfa_offset);
390 cfa_store_offset += fsize;
395 if (fsize + 4 < 0x8000)
402 /* asm_fprintf() cannot handle %. */
404 asm_fprintf (stream, "\tsubq.w %0I%d,%Rsp\n", fsize + 4);
406 asm_fprintf (stream, "\tsubqw %0I%d,%Rsp\n", fsize + 4);
411 /* asm_fprintf() cannot handle %. */
413 asm_fprintf (stream, "\tsubq.l %0I%d,%Rsp\n", fsize + 4);
415 asm_fprintf (stream, "\tsubql %0I%d,%Rsp\n", fsize + 4);
419 else if (fsize + 4 <= 16 && TARGET_CPU32)
421 /* On the CPU32 it is faster to use two subqw instructions to
422 subtract a small integer (8 < N <= 16) to a register. */
423 /* asm_fprintf() cannot handle %. */
425 asm_fprintf (stream, "\tsubq.w %0I8,%Rsp\n\tsubq.w %0I%d,%Rsp\n",
428 asm_fprintf (stream, "\tsubqw %0I8,%Rsp\n\tsubqw %0I%d,%Rsp\n",
433 #endif /* not NO_ADDSUB_Q */
436 /* Adding negative number is faster on the 68040. */
437 /* asm_fprintf() cannot handle %. */
439 asm_fprintf (stream, "\tadd.w %0I%d,%Rsp\n", - (fsize + 4));
441 asm_fprintf (stream, "\taddw %0I%d,%Rsp\n", - (fsize + 4));
447 asm_fprintf (stream, "\tlea (%d,%Rsp),%Rsp\n", - (fsize + 4));
449 asm_fprintf (stream, "\tlea %Rsp@(%d),%Rsp\n", - (fsize + 4));
455 /* asm_fprintf() cannot handle %. */
457 asm_fprintf (stream, "\tadd.l %0I%d,%Rsp\n", - (fsize + 4));
459 asm_fprintf (stream, "\taddl %0I%d,%Rsp\n", - (fsize + 4));
462 if (dwarf2out_do_frame ())
464 cfa_store_offset += fsize;
465 cfa_offset = cfa_store_offset;
466 dwarf2out_def_cfa ("", STACK_POINTER_REGNUM, cfa_offset);
469 #ifdef SUPPORT_SUN_FPA
470 for (regno = 24; regno < 56; regno++)
471 if (m68k_save_reg (regno))
474 asm_fprintf (stream, "\tfpmovd %s,-(%Rsp)\n",
477 asm_fprintf (stream, "\tfpmoved %s,%Rsp@-\n",
480 if (dwarf2out_do_frame ())
482 char *l = dwarf2out_cfi_label ();
484 cfa_store_offset += 8;
485 if (! frame_pointer_needed)
487 cfa_offset = cfa_store_offset;
488 dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, cfa_offset);
490 dwarf2out_reg_save (l, regno, -cfa_store_offset);
496 for (regno = 16; regno < 24; regno++)
497 if (m68k_save_reg (regno))
499 mask |= 1 << (regno - 16);
502 if ((mask & 0xff) != 0)
505 asm_fprintf (stream, "\tfmovm %0I0x%x,-(%Rsp)\n", mask & 0xff);
507 asm_fprintf (stream, "\tfmovem %0I0x%x,%Rsp@-\n", mask & 0xff);
509 if (dwarf2out_do_frame ())
511 char *l = (char *) dwarf2out_cfi_label ();
514 cfa_store_offset += num_saved_regs * 12;
515 if (! frame_pointer_needed)
517 cfa_offset = cfa_store_offset;
518 dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, cfa_offset);
520 for (regno = 16, n_regs = 0; regno < 24; regno++)
521 if (mask & (1 << (regno - 16)))
522 dwarf2out_reg_save (l, regno,
523 -cfa_store_offset + n_regs++ * 12);
529 for (regno = 0; regno < 16; regno++)
530 if (m68k_save_reg (regno))
532 mask |= 1 << (15 - regno);
538 asm_fprintf (stream, "\ttst.l %d(%Rsp)\n", NEED_PROBE - num_saved_regs * 4);
540 asm_fprintf (stream, "\ttstl %Rsp@(%d)\n", NEED_PROBE - num_saved_regs * 4);
544 /* If the stack limit is not a symbol, check it here.
545 This has the disadvantage that it may be too late... */
546 if (current_function_limit_stack)
548 if (REG_P (stack_limit_rtx))
550 #if defined (MOTOROLA)
551 asm_fprintf (stream, "\tcmp.l %s,%Rsp\n\ttrapcs\n",
552 reg_names[REGNO (stack_limit_rtx)]);
554 asm_fprintf (stream, "\tcmpl %s,%Rsp\n\ttrapcs\n",
555 reg_names[REGNO (stack_limit_rtx)]);
558 else if (GET_CODE (stack_limit_rtx) != SYMBOL_REF)
559 warning ("stack limit expression is not supported");
562 if (num_saved_regs <= 2)
564 /* Store each separately in the same order moveml uses.
565 Using two movel instructions instead of a single moveml
566 is about 15% faster for the 68020 and 68030 at no expense
571 /* Undo the work from above. */
572 for (i = 0; i< 16; i++)
577 "\t%Omove.l %s,-(%Rsp)\n",
579 "\tmovel %s,%Rsp@-\n",
582 if (dwarf2out_do_frame ())
584 char *l = (char *) dwarf2out_cfi_label ();
586 cfa_store_offset += 4;
587 if (! frame_pointer_needed)
589 cfa_offset = cfa_store_offset;
590 dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, cfa_offset);
592 dwarf2out_reg_save (l, 15 - i, -cfa_store_offset);
600 /* The coldfire does not support the predecrement form of the
601 movml instruction, so we must adjust the stack pointer and
602 then use the plain address register indirect mode. We also
603 have to invert the register save mask to use the new mode.
605 FIXME: if num_saved_regs was calculated earlier, we could
606 combine the stack pointer adjustment with any adjustment
607 done when the initial stack frame is created. This would
608 save an instruction */
613 for (i = 0; i < 16; i++)
615 newmask |= (1 << (15-i));
618 asm_fprintf (stream, "\tlea (%d,%Rsp),%Rsp\n", -num_saved_regs*4);
619 asm_fprintf (stream, "\tmovm.l %0I0x%x,(%Rsp)\n", newmask);
621 asm_fprintf (stream, "\tlea %Rsp@(%d),%Rsp\n", -num_saved_regs*4);
622 asm_fprintf (stream, "\tmoveml %0I0x%x,%Rsp@\n", newmask);
628 asm_fprintf (stream, "\tmovm.l %0I0x%x,-(%Rsp)\n", mask);
630 asm_fprintf (stream, "\tmoveml %0I0x%x,%Rsp@-\n", mask);
633 if (dwarf2out_do_frame ())
635 char *l = (char *) dwarf2out_cfi_label ();
638 cfa_store_offset += num_saved_regs * 4;
639 if (! frame_pointer_needed)
641 cfa_offset = cfa_store_offset;
642 dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, cfa_offset);
644 for (regno = 0, n_regs = 0; regno < 16; regno++)
645 if (mask & (1 << (15 - regno)))
646 dwarf2out_reg_save (l, regno,
647 -cfa_store_offset + n_regs++ * 4);
650 if (flag_pic && current_function_uses_pic_offset_table)
653 asm_fprintf (stream, "\t%Olea (%Rpc, %U_GLOBAL_OFFSET_TABLE_@GOTPC), %s\n",
654 reg_names[PIC_OFFSET_TABLE_REGNUM]);
656 asm_fprintf (stream, "\tmovel %0I__GLOBAL_OFFSET_TABLE_, %s\n",
657 reg_names[PIC_OFFSET_TABLE_REGNUM]);
658 asm_fprintf (stream, "\tlea %Rpc@(0,%s:l),%s\n",
659 reg_names[PIC_OFFSET_TABLE_REGNUM],
660 reg_names[PIC_OFFSET_TABLE_REGNUM]);
666 /* Return true if this function's epilogue can be output as RTL. */
673 if (!reload_completed || frame_pointer_needed || get_frame_size () != 0)
676 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
677 if (m68k_save_reg (regno))
683 /* This function generates the assembly code for function exit,
684 on machines that need it.
686 The function epilogue should not depend on the current stack pointer!
687 It should use the frame pointer only, if there is a frame pointer.
688 This is mandatory because of alloca; we also take advantage of it to
689 omit stack adjustments before returning. */
694 m68k_output_function_epilogue (stream, size)
699 register int mask, fmask;
701 HOST_WIDE_INT offset, foffset, fpoffset;
702 HOST_WIDE_INT fsize = ((size) + 3) & -4;
705 nregs = 0; fmask = 0; fpoffset = 0;
706 for (regno = 16; regno < 24; regno++)
707 if (m68k_save_reg (regno))
710 fmask |= 1 << (23 - regno);
713 foffset = fpoffset + nregs * 12;
716 for (regno = 0; regno < 16; regno++)
717 if (m68k_save_reg (regno))
723 offset = foffset + nregs * 4;
724 if (offset + fsize >= 0x8000
725 && frame_pointer_needed
726 && (mask || fmask || fpoffset))
728 fprintf (stream, "\tmovel $%d,a0\n", -fsize);
732 if (exact_log2 (mask) >= 0)
735 fprintf (stream, "\tmovel -%d(a6,a0.l),%s\n",
736 offset + fsize, reg_names[exact_log2 (mask)]);
737 else if (! frame_pointer_needed)
738 fprintf (stream, "\tmovel (sp)+,%s\n",
739 reg_names[exact_log2 (mask)]);
741 fprintf (stream, "\tmovel -%d(a6),%s\n",
742 offset + fsize, reg_names[exact_log2 (mask)]);
747 fprintf (stream, "\tmovem -%d(a6,a0.l),$0x%x\n",
748 offset + fsize, mask);
749 else if (! frame_pointer_needed)
750 fprintf (stream, "\tmovem (sp)+,$0x%x\n", mask);
752 fprintf (stream, "\tmovem -%d(a6),$0x%x\n",
753 offset + fsize, mask);
759 fprintf (stream, "\tfmovem -%d(a6,a0.l),$0x%x\n",
760 foffset + fsize, fmask);
761 else if (! frame_pointer_needed)
762 fprintf (stream, "\tfmovem (sp)+,$0x%x\n", fmask);
764 fprintf (stream, "\tfmovem -%d(a6),$0x%x\n",
765 foffset + fsize, fmask);
769 for (regno = 55; regno >= 24; regno--)
770 if (m68k_save_reg (regno))
773 fprintf(stream, "\tfpmoved -%d(a6,a0.l), %s\n",
774 fpoffset + fsize, reg_names[regno]);
775 else if (! frame_pointer_needed)
776 fprintf(stream, "\tfpmoved (sp)+, %s\n",
779 fprintf(stream, "\tfpmoved -%d(a6), %s\n",
780 fpoffset + fsize, reg_names[regno]);
784 if (frame_pointer_needed)
785 fprintf (stream, "\tunlk a6\n");
788 if (fsize + 4 < 0x8000)
789 fprintf (stream, "\tadd.w $%d,sp\n", fsize + 4);
791 fprintf (stream, "\tadd.l $%d,sp\n", fsize + 4);
794 if (current_function_calls_eh_return)
795 fprintf (stream, "\tadd.l a0,sp\n");
797 if (current_function_pops_args)
798 fprintf (stream, "\trtd $%d\n", current_function_pops_args);
800 fprintf (stream, "\trts\n");
806 m68k_output_function_epilogue (stream, size)
811 register int mask, fmask;
813 HOST_WIDE_INT offset, foffset, fpoffset;
814 HOST_WIDE_INT fsize = (size + 3) & -4;
816 rtx insn = get_last_insn ();
817 int restore_from_sp = 0;
819 /* If the last insn was a BARRIER, we don't have to write any code. */
820 if (GET_CODE (insn) == NOTE)
821 insn = prev_nonnote_insn (insn);
822 if (insn && GET_CODE (insn) == BARRIER)
824 /* Output just a no-op so that debuggers don't get confused
825 about which function the pc is in at this address. */
826 fprintf (stream, "\tnop\n");
830 #ifdef FUNCTION_EXTRA_EPILOGUE
831 FUNCTION_EXTRA_EPILOGUE (stream, size);
833 nregs = 0; fmask = 0; fpoffset = 0;
834 #ifdef SUPPORT_SUN_FPA
835 for (regno = 24 ; regno < 56 ; regno++)
836 if (m68k_save_reg (regno))
838 fpoffset = nregs * 8;
843 for (regno = 16; regno < 24; regno++)
844 if (m68k_save_reg (regno))
847 fmask |= 1 << (23 - regno);
850 foffset = fpoffset + nregs * 12;
852 for (regno = 0; regno < 16; regno++)
853 if (m68k_save_reg (regno))
858 offset = foffset + nregs * 4;
859 /* FIXME : leaf_function_p below is too strong.
860 What we really need to know there is if there could be pending
861 stack adjustment needed at that point. */
862 restore_from_sp = ! frame_pointer_needed
863 || (! current_function_calls_alloca && leaf_function_p ());
864 if (offset + fsize >= 0x8000
866 && (mask || fmask || fpoffset))
869 asm_fprintf (stream, "\t%Omove.l %0I%d,%Ra1\n", -fsize);
871 asm_fprintf (stream, "\tmovel %0I%d,%Ra1\n", -fsize);
875 if (TARGET_5200 || nregs <= 2)
877 /* Restore each separately in the same order moveml does.
878 Using two movel instructions instead of a single moveml
879 is about 15% faster for the 68020 and 68030 at no expense
884 /* Undo the work from above. */
885 for (i = 0; i< 16; i++)
891 asm_fprintf (stream, "\t%Omove.l -%d(%s,%Ra1.l),%s\n",
893 reg_names[FRAME_POINTER_REGNUM],
896 asm_fprintf (stream, "\tmovel %s@(-%d,%Ra1:l),%s\n",
897 reg_names[FRAME_POINTER_REGNUM],
898 offset + fsize, reg_names[i]);
901 else if (restore_from_sp)
904 asm_fprintf (stream, "\t%Omove.l (%Rsp)+,%s\n",
907 asm_fprintf (stream, "\tmovel %Rsp@+,%s\n",
914 asm_fprintf (stream, "\t%Omove.l -%d(%s),%s\n",
916 reg_names[FRAME_POINTER_REGNUM],
919 fprintf (stream, "\tmovel %s@(-%d),%s\n",
920 reg_names[FRAME_POINTER_REGNUM],
921 offset + fsize, reg_names[i]);
932 asm_fprintf (stream, "\tmovm.l -%d(%s,%Ra1.l),%0I0x%x\n",
934 reg_names[FRAME_POINTER_REGNUM],
937 asm_fprintf (stream, "\tmoveml %s@(-%d,%Ra1:l),%0I0x%x\n",
938 reg_names[FRAME_POINTER_REGNUM],
939 offset + fsize, mask);
942 else if (restore_from_sp)
945 asm_fprintf (stream, "\tmovm.l (%Rsp)+,%0I0x%x\n", mask);
947 asm_fprintf (stream, "\tmoveml %Rsp@+,%0I0x%x\n", mask);
953 asm_fprintf (stream, "\tmovm.l -%d(%s),%0I0x%x\n",
955 reg_names[FRAME_POINTER_REGNUM],
958 asm_fprintf (stream, "\tmoveml %s@(-%d),%0I0x%x\n",
959 reg_names[FRAME_POINTER_REGNUM],
960 offset + fsize, mask);
969 asm_fprintf (stream, "\tfmovm -%d(%s,%Ra1.l),%0I0x%x\n",
971 reg_names[FRAME_POINTER_REGNUM],
974 asm_fprintf (stream, "\tfmovem %s@(-%d,%Ra1:l),%0I0x%x\n",
975 reg_names[FRAME_POINTER_REGNUM],
976 foffset + fsize, fmask);
979 else if (restore_from_sp)
982 asm_fprintf (stream, "\tfmovm (%Rsp)+,%0I0x%x\n", fmask);
984 asm_fprintf (stream, "\tfmovem %Rsp@+,%0I0x%x\n", fmask);
990 asm_fprintf (stream, "\tfmovm -%d(%s),%0I0x%x\n",
992 reg_names[FRAME_POINTER_REGNUM],
995 asm_fprintf (stream, "\tfmovem %s@(-%d),%0I0x%x\n",
996 reg_names[FRAME_POINTER_REGNUM],
997 foffset + fsize, fmask);
1002 for (regno = 55; regno >= 24; regno--)
1003 if (m68k_save_reg (regno))
1008 asm_fprintf (stream, "\tfpmovd -%d(%s,%Ra1.l), %s\n",
1010 reg_names[FRAME_POINTER_REGNUM],
1013 asm_fprintf (stream, "\tfpmoved %s@(-%d,%Ra1:l), %s\n",
1014 reg_names[FRAME_POINTER_REGNUM],
1015 fpoffset + fsize, reg_names[regno]);
1018 else if (restore_from_sp)
1021 asm_fprintf (stream, "\tfpmovd (%Rsp)+,%s\n",
1024 asm_fprintf (stream, "\tfpmoved %Rsp@+, %s\n",
1031 fprintf (stream, "\tfpmovd -%d(%s), %s\n",
1033 reg_names[FRAME_POINTER_REGNUM],
1036 fprintf (stream, "\tfpmoved %s@(-%d), %s\n",
1037 reg_names[FRAME_POINTER_REGNUM],
1038 fpoffset + fsize, reg_names[regno]);
1043 if (frame_pointer_needed)
1044 fprintf (stream, "\tunlk %s\n",
1045 reg_names[FRAME_POINTER_REGNUM]);
1054 asm_fprintf (stream, "\taddq.w %0I%d,%Rsp\n", fsize + 4);
1056 asm_fprintf (stream, "\taddqw %0I%d,%Rsp\n", fsize + 4);
1062 asm_fprintf (stream, "\taddq.l %0I%d,%Rsp\n", fsize + 4);
1064 asm_fprintf (stream, "\taddql %0I%d,%Rsp\n", fsize + 4);
1068 else if (fsize + 4 <= 16 && TARGET_CPU32)
1070 /* On the CPU32 it is faster to use two addqw instructions to
1071 add a small integer (8 < N <= 16) to a register. */
1072 /* asm_fprintf() cannot handle %. */
1074 asm_fprintf (stream, "\taddq.w %0I8,%Rsp\n\taddq.w %0I%d,%Rsp\n",
1077 asm_fprintf (stream, "\taddqw %0I8,%Rsp\n\taddqw %0I%d,%Rsp\n",
1082 #endif /* not NO_ADDSUB_Q */
1083 if (fsize + 4 < 0x8000)
1087 /* asm_fprintf() cannot handle %. */
1089 asm_fprintf (stream, "\tadd.w %0I%d,%Rsp\n", fsize + 4);
1091 asm_fprintf (stream, "\taddw %0I%d,%Rsp\n", fsize + 4);
1097 asm_fprintf (stream, "\tlea (%d,%Rsp),%Rsp\n", fsize + 4);
1099 asm_fprintf (stream, "\tlea %Rsp@(%d),%Rsp\n", fsize + 4);
1105 /* asm_fprintf() cannot handle %. */
1107 asm_fprintf (stream, "\tadd.l %0I%d,%Rsp\n", fsize + 4);
1109 asm_fprintf (stream, "\taddl %0I%d,%Rsp\n", fsize + 4);
1113 if (current_function_calls_eh_return)
1116 asm_fprintf (stream, "\tadd.l %Ra0,%Rsp\n");
1118 asm_fprintf (stream, "\taddl %Ra0,%Rsp\n");
1121 if (current_function_pops_args)
1122 asm_fprintf (stream, "\trtd %0I%d\n", current_function_pops_args);
1124 fprintf (stream, "\trts\n");
1128 /* Similar to general_operand, but exclude stack_pointer_rtx. */
1131 not_sp_operand (op, mode)
1133 enum machine_mode mode;
1135 return op != stack_pointer_rtx && nonimmediate_operand (op, mode);
1138 /* Return TRUE if X is a valid comparison operator for the dbcc
1141 Note it rejects floating point comparison operators.
1142 (In the future we could use Fdbcc).
1144 It also rejects some comparisons when CC_NO_OVERFLOW is set. */
1147 valid_dbcc_comparison_p (x, mode)
1149 enum machine_mode mode ATTRIBUTE_UNUSED;
1151 switch (GET_CODE (x))
1153 case EQ: case NE: case GTU: case LTU:
1157 /* Reject some when CC_NO_OVERFLOW is set. This may be over
1159 case GT: case LT: case GE: case LE:
1160 return ! (cc_prev_status.flags & CC_NO_OVERFLOW);
1166 /* Return nonzero if flags are currently in the 68881 flag register. */
1170 /* We could add support for these in the future */
1171 return cc_status.flags & CC_IN_68881;
1174 /* Output a dbCC; jCC sequence. Note we do not handle the
1175 floating point version of this sequence (Fdbcc). We also
1176 do not handle alternative conditions when CC_NO_OVERFLOW is
1177 set. It is assumed that valid_dbcc_comparison_p and flags_in_68881 will
1178 kick those out before we get here. */
1181 output_dbcc_and_branch (operands)
1184 switch (GET_CODE (operands[3]))
1188 output_asm_insn ("dbeq %0,%l1\n\tjbeq %l2", operands);
1190 output_asm_insn ("dbeq %0,%l1\n\tjeq %l2", operands);
1196 output_asm_insn ("dbne %0,%l1\n\tjbne %l2", operands);
1198 output_asm_insn ("dbne %0,%l1\n\tjne %l2", operands);
1204 output_asm_insn ("dbgt %0,%l1\n\tjbgt %l2", operands);
1206 output_asm_insn ("dbgt %0,%l1\n\tjgt %l2", operands);
1212 output_asm_insn ("dbhi %0,%l1\n\tjbhi %l2", operands);
1214 output_asm_insn ("dbhi %0,%l1\n\tjhi %l2", operands);
1220 output_asm_insn ("dblt %0,%l1\n\tjblt %l2", operands);
1222 output_asm_insn ("dblt %0,%l1\n\tjlt %l2", operands);
1228 output_asm_insn ("dbcs %0,%l1\n\tjbcs %l2", operands);
1230 output_asm_insn ("dbcs %0,%l1\n\tjcs %l2", operands);
1236 output_asm_insn ("dbge %0,%l1\n\tjbge %l2", operands);
1238 output_asm_insn ("dbge %0,%l1\n\tjge %l2", operands);
1244 output_asm_insn ("dbcc %0,%l1\n\tjbcc %l2", operands);
1246 output_asm_insn ("dbcc %0,%l1\n\tjcc %l2", operands);
1252 output_asm_insn ("dble %0,%l1\n\tjble %l2", operands);
1254 output_asm_insn ("dble %0,%l1\n\tjle %l2", operands);
1260 output_asm_insn ("dbls %0,%l1\n\tjbls %l2", operands);
1262 output_asm_insn ("dbls %0,%l1\n\tjls %l2", operands);
1270 /* If the decrement is to be done in SImode, then we have
1271 to compensate for the fact that dbcc decrements in HImode. */
1272 switch (GET_MODE (operands[0]))
1276 output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjbpl %l1", operands);
1278 output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjpl %l1", operands);
1291 output_scc_di(op, operand1, operand2, dest)
1298 enum rtx_code op_code = GET_CODE (op);
1300 /* This does not produce a useful cc. */
1303 /* The m68k cmp.l instruction requires operand1 to be a reg as used
1304 below. Swap the operands and change the op if these requirements
1305 are not fulfilled. */
1306 if (GET_CODE (operand2) == REG && GET_CODE (operand1) != REG)
1310 operand1 = operand2;
1312 op_code = swap_condition (op_code);
1314 loperands[0] = operand1;
1315 if (GET_CODE (operand1) == REG)
1316 loperands[1] = gen_rtx_REG (SImode, REGNO (operand1) + 1);
1318 loperands[1] = adjust_address (operand1, SImode, 4);
1319 if (operand2 != const0_rtx)
1321 loperands[2] = operand2;
1322 if (GET_CODE (operand2) == REG)
1323 loperands[3] = gen_rtx_REG (SImode, REGNO (operand2) + 1);
1325 loperands[3] = adjust_address (operand2, SImode, 4);
1327 loperands[4] = gen_label_rtx();
1328 if (operand2 != const0_rtx)
1331 #ifdef SGS_CMP_ORDER
1332 output_asm_insn ("cmp%.l %0,%2\n\tjbne %l4\n\tcmp%.l %1,%3", loperands);
1334 output_asm_insn ("cmp%.l %2,%0\n\tjbne %l4\n\tcmp%.l %3,%1", loperands);
1337 #ifdef SGS_CMP_ORDER
1338 output_asm_insn ("cmp%.l %0,%2\n\tjne %l4\n\tcmp%.l %1,%3", loperands);
1340 output_asm_insn ("cmp%.l %2,%0\n\tjne %l4\n\tcmp%.l %3,%1", loperands);
1346 if (TARGET_68020 || TARGET_5200 || ! ADDRESS_REG_P (loperands[0]))
1347 output_asm_insn ("tst%.l %0", loperands);
1350 #ifdef SGS_CMP_ORDER
1351 output_asm_insn ("cmp%.w %0,%#0", loperands);
1353 output_asm_insn ("cmp%.w %#0,%0", loperands);
1358 output_asm_insn ("jbne %l4", loperands);
1360 output_asm_insn ("jne %l4", loperands);
1363 if (TARGET_68020 || TARGET_5200 || ! ADDRESS_REG_P (loperands[1]))
1364 output_asm_insn ("tst%.l %1", loperands);
1367 #ifdef SGS_CMP_ORDER
1368 output_asm_insn ("cmp%.w %1,%#0", loperands);
1370 output_asm_insn ("cmp%.w %#0,%1", loperands);
1375 loperands[5] = dest;
1380 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1381 CODE_LABEL_NUMBER (loperands[4]));
1382 output_asm_insn ("seq %5", loperands);
1386 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1387 CODE_LABEL_NUMBER (loperands[4]));
1388 output_asm_insn ("sne %5", loperands);
1392 loperands[6] = gen_label_rtx();
1394 output_asm_insn ("shi %5\n\tjbra %l6", loperands);
1396 output_asm_insn ("shi %5\n\tjra %l6", loperands);
1398 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1399 CODE_LABEL_NUMBER (loperands[4]));
1400 output_asm_insn ("sgt %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 ("shi %5", loperands);
1412 loperands[6] = gen_label_rtx();
1414 output_asm_insn ("scs %5\n\tjbra %l6", loperands);
1416 output_asm_insn ("scs %5\n\tjra %l6", loperands);
1418 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1419 CODE_LABEL_NUMBER (loperands[4]));
1420 output_asm_insn ("slt %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 ("scs %5", loperands);
1432 loperands[6] = gen_label_rtx();
1434 output_asm_insn ("scc %5\n\tjbra %l6", loperands);
1436 output_asm_insn ("scc %5\n\tjra %l6", loperands);
1438 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1439 CODE_LABEL_NUMBER (loperands[4]));
1440 output_asm_insn ("sge %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 ("scc %5", loperands);
1452 loperands[6] = gen_label_rtx();
1454 output_asm_insn ("sls %5\n\tjbra %l6", loperands);
1456 output_asm_insn ("sls %5\n\tjra %l6", loperands);
1458 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1459 CODE_LABEL_NUMBER (loperands[4]));
1460 output_asm_insn ("sle %5", loperands);
1461 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1462 CODE_LABEL_NUMBER (loperands[6]));
1466 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1467 CODE_LABEL_NUMBER (loperands[4]));
1468 output_asm_insn ("sls %5", loperands);
1478 output_btst (operands, countop, dataop, insn, signpos)
1480 rtx countop, dataop;
1484 operands[0] = countop;
1485 operands[1] = dataop;
1487 if (GET_CODE (countop) == CONST_INT)
1489 register int count = INTVAL (countop);
1490 /* If COUNT is bigger than size of storage unit in use,
1491 advance to the containing unit of same size. */
1492 if (count > signpos)
1494 int offset = (count & ~signpos) / 8;
1495 count = count & signpos;
1496 operands[1] = dataop = adjust_address (dataop, QImode, offset);
1498 if (count == signpos)
1499 cc_status.flags = CC_NOT_POSITIVE | CC_Z_IN_NOT_N;
1501 cc_status.flags = CC_NOT_NEGATIVE | CC_Z_IN_NOT_N;
1503 /* These three statements used to use next_insns_test_no...
1504 but it appears that this should do the same job. */
1506 && next_insn_tests_no_inequality (insn))
1509 && next_insn_tests_no_inequality (insn))
1512 && next_insn_tests_no_inequality (insn))
1515 cc_status.flags = CC_NOT_NEGATIVE;
1517 return "btst %0,%1";
1520 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
1521 reference and a constant. */
1524 symbolic_operand (op, mode)
1526 enum machine_mode mode ATTRIBUTE_UNUSED;
1528 switch (GET_CODE (op))
1536 return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
1537 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
1538 && GET_CODE (XEXP (op, 1)) == CONST_INT);
1540 #if 0 /* Deleted, with corresponding change in m68k.h,
1541 so as to fit the specs. No CONST_DOUBLE is ever symbolic. */
1543 return GET_MODE (op) == mode;
1551 /* Check for sign_extend or zero_extend. Used for bit-count operands. */
1554 extend_operator(x, mode)
1556 enum machine_mode mode;
1558 if (mode != VOIDmode && GET_MODE(x) != mode)
1560 switch (GET_CODE(x))
1571 /* Legitimize PIC addresses. If the address is already
1572 position-independent, we return ORIG. Newly generated
1573 position-independent addresses go to REG. If we need more
1574 than one register, we lose.
1576 An address is legitimized by making an indirect reference
1577 through the Global Offset Table with the name of the symbol
1580 The assembler and linker are responsible for placing the
1581 address of the symbol in the GOT. The function prologue
1582 is responsible for initializing a5 to the starting address
1585 The assembler is also responsible for translating a symbol name
1586 into a constant displacement from the start of the GOT.
1588 A quick example may make things a little clearer:
1590 When not generating PIC code to store the value 12345 into _foo
1591 we would generate the following code:
1595 When generating PIC two transformations are made. First, the compiler
1596 loads the address of foo into a register. So the first transformation makes:
1601 The code in movsi will intercept the lea instruction and call this
1602 routine which will transform the instructions into:
1604 movel a5@(_foo:w), a0
1608 That (in a nutshell) is how *all* symbol and label references are
1612 legitimize_pic_address (orig, mode, reg)
1614 enum machine_mode mode ATTRIBUTE_UNUSED;
1618 /* First handle a simple SYMBOL_REF or LABEL_REF */
1619 if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF)
1624 pic_ref = gen_rtx_MEM (Pmode,
1625 gen_rtx_PLUS (Pmode,
1626 pic_offset_table_rtx, orig));
1627 current_function_uses_pic_offset_table = 1;
1628 RTX_UNCHANGING_P (pic_ref) = 1;
1629 emit_move_insn (reg, pic_ref);
1632 else if (GET_CODE (orig) == CONST)
1636 /* Make sure this is CONST has not already been legitimized */
1637 if (GET_CODE (XEXP (orig, 0)) == PLUS
1638 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
1644 /* legitimize both operands of the PLUS */
1645 if (GET_CODE (XEXP (orig, 0)) == PLUS)
1647 base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
1648 orig = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
1649 base == reg ? 0 : reg);
1653 if (GET_CODE (orig) == CONST_INT)
1654 return plus_constant (base, INTVAL (orig));
1655 pic_ref = gen_rtx_PLUS (Pmode, base, orig);
1656 /* Likewise, should we set special REG_NOTEs here? */
1662 typedef enum { MOVL, SWAP, NEGW, NOTW, NOTB, MOVQ } CONST_METHOD;
1664 static CONST_METHOD const_method PARAMS ((rtx));
1666 #define USE_MOVQ(i) ((unsigned)((i) + 128) <= 255)
1669 const_method (constant)
1675 i = INTVAL (constant);
1679 /* The Coldfire doesn't have byte or word operations. */
1680 /* FIXME: This may not be useful for the m68060 either */
1683 /* if -256 < N < 256 but N is not in range for a moveq
1684 N^ff will be, so use moveq #N^ff, dreg; not.b dreg. */
1685 if (USE_MOVQ (i ^ 0xff))
1687 /* Likewise, try with not.w */
1688 if (USE_MOVQ (i ^ 0xffff))
1690 /* This is the only value where neg.w is useful */
1693 /* Try also with swap */
1695 if (USE_MOVQ ((u >> 16) | (u << 16)))
1698 /* Otherwise, use move.l */
1703 const_int_cost (constant)
1706 switch (const_method (constant))
1709 /* Constants between -128 and 127 are cheap due to moveq */
1715 /* Constants easily generated by moveq + not.b/not.w/neg.w/swap */
1725 output_move_const_into_data_reg (operands)
1730 i = INTVAL (operands[1]);
1731 switch (const_method (operands[1]))
1734 #if defined (MOTOROLA) && !defined (CRDS)
1735 return "moveq%.l %1,%0";
1737 return "moveq %1,%0";
1740 operands[1] = GEN_INT (i ^ 0xff);
1741 #if defined (MOTOROLA) && !defined (CRDS)
1742 return "moveq%.l %1,%0\n\tnot%.b %0";
1744 return "moveq %1,%0\n\tnot%.b %0";
1747 operands[1] = GEN_INT (i ^ 0xffff);
1748 #if defined (MOTOROLA) && !defined (CRDS)
1749 return "moveq%.l %1,%0\n\tnot%.w %0";
1751 return "moveq %1,%0\n\tnot%.w %0";
1754 #if defined (MOTOROLA) && !defined (CRDS)
1755 return "moveq%.l %#-128,%0\n\tneg%.w %0";
1757 return "moveq %#-128,%0\n\tneg%.w %0";
1763 operands[1] = GEN_INT ((u << 16) | (u >> 16));
1764 #if defined (MOTOROLA) && !defined (CRDS)
1765 return "moveq%.l %1,%0\n\tswap %0";
1767 return "moveq %1,%0\n\tswap %0";
1771 return "move%.l %1,%0";
1778 output_move_simode_const (operands)
1781 if (operands[1] == const0_rtx
1782 && (DATA_REG_P (operands[0])
1783 || GET_CODE (operands[0]) == MEM)
1784 /* clr insns on 68000 read before writing.
1785 This isn't so on the 68010, but we have no TARGET_68010. */
1786 && ((TARGET_68020 || TARGET_5200)
1787 || !(GET_CODE (operands[0]) == MEM
1788 && MEM_VOLATILE_P (operands[0]))))
1790 else if (operands[1] == const0_rtx
1791 && ADDRESS_REG_P (operands[0]))
1792 return "sub%.l %0,%0";
1793 else if (DATA_REG_P (operands[0]))
1794 return output_move_const_into_data_reg (operands);
1795 else if (ADDRESS_REG_P (operands[0])
1796 && INTVAL (operands[1]) < 0x8000
1797 && INTVAL (operands[1]) >= -0x8000)
1798 return "move%.w %1,%0";
1799 else if (GET_CODE (operands[0]) == MEM
1800 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
1801 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
1802 && INTVAL (operands[1]) < 0x8000
1803 && INTVAL (operands[1]) >= -0x8000)
1805 return "move%.l %1,%0";
1809 output_move_simode (operands)
1812 if (GET_CODE (operands[1]) == CONST_INT)
1813 return output_move_simode_const (operands);
1814 else if ((GET_CODE (operands[1]) == SYMBOL_REF
1815 || GET_CODE (operands[1]) == CONST)
1816 && push_operand (operands[0], SImode))
1818 else if ((GET_CODE (operands[1]) == SYMBOL_REF
1819 || GET_CODE (operands[1]) == CONST)
1820 && ADDRESS_REG_P (operands[0]))
1821 return "lea %a1,%0";
1822 return "move%.l %1,%0";
1826 output_move_himode (operands)
1829 if (GET_CODE (operands[1]) == CONST_INT)
1831 if (operands[1] == const0_rtx
1832 && (DATA_REG_P (operands[0])
1833 || GET_CODE (operands[0]) == MEM)
1834 /* clr insns on 68000 read before writing.
1835 This isn't so on the 68010, but we have no TARGET_68010. */
1836 && ((TARGET_68020 || TARGET_5200)
1837 || !(GET_CODE (operands[0]) == MEM
1838 && MEM_VOLATILE_P (operands[0]))))
1840 else if (operands[1] == const0_rtx
1841 && ADDRESS_REG_P (operands[0]))
1842 return "sub%.l %0,%0";
1843 else if (DATA_REG_P (operands[0])
1844 && INTVAL (operands[1]) < 128
1845 && INTVAL (operands[1]) >= -128)
1847 #if defined(MOTOROLA) && !defined(CRDS)
1848 return "moveq%.l %1,%0";
1850 return "moveq %1,%0";
1853 else if (INTVAL (operands[1]) < 0x8000
1854 && INTVAL (operands[1]) >= -0x8000)
1855 return "move%.w %1,%0";
1857 else if (CONSTANT_P (operands[1]))
1858 return "move%.l %1,%0";
1860 /* Recognize the insn before a tablejump, one that refers
1861 to a table of offsets. Such an insn will need to refer
1862 to a label on the insn. So output one. Use the label-number
1863 of the table of offsets to generate this label. This code,
1864 and similar code below, assumes that there will be at most one
1865 reference to each table. */
1866 if (GET_CODE (operands[1]) == MEM
1867 && GET_CODE (XEXP (operands[1], 0)) == PLUS
1868 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == LABEL_REF
1869 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) != PLUS)
1871 rtx labelref = XEXP (XEXP (operands[1], 0), 1);
1872 #if defined (MOTOROLA) && !defined (SGS_SWITCH_TABLES)
1874 asm_fprintf (asm_out_file, "\tset %LLI%d,.+2\n",
1875 CODE_LABEL_NUMBER (XEXP (labelref, 0)));
1877 asm_fprintf (asm_out_file, "\t.set %LLI%d,.+2\n",
1878 CODE_LABEL_NUMBER (XEXP (labelref, 0)));
1879 #endif /* not SGS */
1880 #else /* SGS_SWITCH_TABLES or not MOTOROLA */
1881 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LI",
1882 CODE_LABEL_NUMBER (XEXP (labelref, 0)));
1883 #ifdef SGS_SWITCH_TABLES
1884 /* Set flag saying we need to define the symbol
1885 LD%n (with value L%n-LI%n) at the end of the switch table. */
1886 switch_table_difference_label_flag = 1;
1887 #endif /* SGS_SWITCH_TABLES */
1888 #endif /* SGS_SWITCH_TABLES or not MOTOROLA */
1890 #endif /* SGS_NO_LI */
1891 return "move%.w %1,%0";
1895 output_move_qimode (operands)
1900 /* This is probably useless, since it loses for pushing a struct
1901 of several bytes a byte at a time. */
1902 /* 68k family always modifies the stack pointer by at least 2, even for
1903 byte pushes. The 5200 (coldfire) does not do this. */
1904 if (GET_CODE (operands[0]) == MEM
1905 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
1906 && XEXP (XEXP (operands[0], 0), 0) == stack_pointer_rtx
1907 && ! ADDRESS_REG_P (operands[1])
1910 xoperands[1] = operands[1];
1912 = gen_rtx_MEM (QImode,
1913 gen_rtx_PLUS (VOIDmode, stack_pointer_rtx, const1_rtx));
1914 /* Just pushing a byte puts it in the high byte of the halfword. */
1915 /* We must put it in the low-order, high-numbered byte. */
1916 if (!reg_mentioned_p (stack_pointer_rtx, operands[1]))
1918 xoperands[3] = stack_pointer_rtx;
1920 output_asm_insn ("subq%.l %#2,%3\n\tmove%.b %1,%2", xoperands);
1922 output_asm_insn ("sub%.l %#2,%3\n\tmove%.b %1,%2", xoperands);
1926 output_asm_insn ("move%.b %1,%-\n\tmove%.b %@,%2", xoperands);
1930 /* clr and st insns on 68000 read before writing.
1931 This isn't so on the 68010, but we have no TARGET_68010. */
1932 if (!ADDRESS_REG_P (operands[0])
1933 && ((TARGET_68020 || TARGET_5200)
1934 || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
1936 if (operands[1] == const0_rtx)
1938 if ((!TARGET_5200 || DATA_REG_P (operands[0]))
1939 && GET_CODE (operands[1]) == CONST_INT
1940 && (INTVAL (operands[1]) & 255) == 255)
1946 if (GET_CODE (operands[1]) == CONST_INT
1947 && DATA_REG_P (operands[0])
1948 && INTVAL (operands[1]) < 128
1949 && INTVAL (operands[1]) >= -128)
1951 #if defined(MOTOROLA) && !defined(CRDS)
1952 return "moveq%.l %1,%0";
1954 return "moveq %1,%0";
1957 if (operands[1] == const0_rtx && ADDRESS_REG_P (operands[0]))
1958 return "sub%.l %0,%0";
1959 if (GET_CODE (operands[1]) != CONST_INT && CONSTANT_P (operands[1]))
1960 return "move%.l %1,%0";
1961 /* 68k family (including the 5200 coldfire) does not support byte moves to
1962 from address registers. */
1963 if (ADDRESS_REG_P (operands[0]) || ADDRESS_REG_P (operands[1]))
1964 return "move%.w %1,%0";
1965 return "move%.b %1,%0";
1969 output_move_stricthi (operands)
1972 if (operands[1] == const0_rtx
1973 /* clr insns on 68000 read before writing.
1974 This isn't so on the 68010, but we have no TARGET_68010. */
1975 && ((TARGET_68020 || TARGET_5200)
1976 || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
1978 return "move%.w %1,%0";
1982 output_move_strictqi (operands)
1985 if (operands[1] == const0_rtx
1986 /* clr insns on 68000 read before writing.
1987 This isn't so on the 68010, but we have no TARGET_68010. */
1988 && ((TARGET_68020 || TARGET_5200)
1989 || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
1991 return "move%.b %1,%0";
1994 /* Return the best assembler insn template
1995 for moving operands[1] into operands[0] as a fullword. */
1998 singlemove_string (operands)
2001 #ifdef SUPPORT_SUN_FPA
2002 if (FPA_REG_P (operands[0]) || FPA_REG_P (operands[1]))
2003 return "fpmoves %1,%0";
2005 if (GET_CODE (operands[1]) == CONST_INT)
2006 return output_move_simode_const (operands);
2007 return "move%.l %1,%0";
2011 /* Output assembler code to perform a doubleword move insn
2012 with operands OPERANDS. */
2015 output_move_double (operands)
2020 REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP
2025 rtx addreg0 = 0, addreg1 = 0;
2026 int dest_overlapped_low = 0;
2027 int size = GET_MODE_SIZE (GET_MODE (operands[0]));
2032 /* First classify both operands. */
2034 if (REG_P (operands[0]))
2036 else if (offsettable_memref_p (operands[0]))
2038 else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
2040 else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
2042 else if (GET_CODE (operands[0]) == MEM)
2047 if (REG_P (operands[1]))
2049 else if (CONSTANT_P (operands[1]))
2051 else if (offsettable_memref_p (operands[1]))
2053 else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
2055 else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
2057 else if (GET_CODE (operands[1]) == MEM)
2062 /* Check for the cases that the operand constraints are not
2063 supposed to allow to happen. Abort if we get one,
2064 because generating code for these cases is painful. */
2066 if (optype0 == RNDOP || optype1 == RNDOP)
2069 /* If one operand is decrementing and one is incrementing
2070 decrement the former register explicitly
2071 and change that operand into ordinary indexing. */
2073 if (optype0 == PUSHOP && optype1 == POPOP)
2075 operands[0] = XEXP (XEXP (operands[0], 0), 0);
2077 output_asm_insn ("sub%.l %#12,%0", operands);
2079 output_asm_insn ("subq%.l %#8,%0", operands);
2080 if (GET_MODE (operands[1]) == XFmode)
2081 operands[0] = gen_rtx_MEM (XFmode, operands[0]);
2082 else if (GET_MODE (operands[0]) == DFmode)
2083 operands[0] = gen_rtx_MEM (DFmode, operands[0]);
2085 operands[0] = gen_rtx_MEM (DImode, operands[0]);
2088 if (optype0 == POPOP && optype1 == PUSHOP)
2090 operands[1] = XEXP (XEXP (operands[1], 0), 0);
2092 output_asm_insn ("sub%.l %#12,%1", operands);
2094 output_asm_insn ("subq%.l %#8,%1", operands);
2095 if (GET_MODE (operands[1]) == XFmode)
2096 operands[1] = gen_rtx_MEM (XFmode, operands[1]);
2097 else if (GET_MODE (operands[1]) == DFmode)
2098 operands[1] = gen_rtx_MEM (DFmode, operands[1]);
2100 operands[1] = gen_rtx_MEM (DImode, operands[1]);
2104 /* If an operand is an unoffsettable memory ref, find a register
2105 we can increment temporarily to make it refer to the second word. */
2107 if (optype0 == MEMOP)
2108 addreg0 = find_addr_reg (XEXP (operands[0], 0));
2110 if (optype1 == MEMOP)
2111 addreg1 = find_addr_reg (XEXP (operands[1], 0));
2113 /* Ok, we can do one word at a time.
2114 Normally we do the low-numbered word first,
2115 but if either operand is autodecrementing then we
2116 do the high-numbered word first.
2118 In either case, set up in LATEHALF the operands to use
2119 for the high-numbered word and in some cases alter the
2120 operands in OPERANDS to be suitable for the low-numbered word. */
2124 if (optype0 == REGOP)
2126 latehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 2);
2127 middlehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
2129 else if (optype0 == OFFSOP)
2131 middlehalf[0] = adjust_address (operands[0], SImode, 4);
2132 latehalf[0] = adjust_address (operands[0], SImode, size - 4);
2136 middlehalf[0] = operands[0];
2137 latehalf[0] = operands[0];
2140 if (optype1 == REGOP)
2142 latehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
2143 middlehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
2145 else if (optype1 == OFFSOP)
2147 middlehalf[1] = adjust_address (operands[1], SImode, 4);
2148 latehalf[1] = adjust_address (operands[1], SImode, size - 4);
2150 else if (optype1 == CNSTOP)
2152 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2157 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2158 REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l);
2159 operands[1] = GEN_INT (l[0]);
2160 middlehalf[1] = GEN_INT (l[1]);
2161 latehalf[1] = GEN_INT (l[2]);
2163 else if (CONSTANT_P (operands[1]))
2165 /* actually, no non-CONST_DOUBLE constant should ever
2168 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
2169 latehalf[1] = constm1_rtx;
2171 latehalf[1] = const0_rtx;
2176 middlehalf[1] = operands[1];
2177 latehalf[1] = operands[1];
2181 /* size is not 12: */
2183 if (optype0 == REGOP)
2184 latehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
2185 else if (optype0 == OFFSOP)
2186 latehalf[0] = adjust_address (operands[0], SImode, size - 4);
2188 latehalf[0] = operands[0];
2190 if (optype1 == REGOP)
2191 latehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
2192 else if (optype1 == OFFSOP)
2193 latehalf[1] = adjust_address (operands[1], SImode, size - 4);
2194 else if (optype1 == CNSTOP)
2195 split_double (operands[1], &operands[1], &latehalf[1]);
2197 latehalf[1] = operands[1];
2200 /* If insn is effectively movd N(sp),-(sp) then we will do the
2201 high word first. We should use the adjusted operand 1 (which is N+4(sp))
2202 for the low word as well, to compensate for the first decrement of sp. */
2203 if (optype0 == PUSHOP
2204 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
2205 && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
2206 operands[1] = middlehalf[1] = latehalf[1];
2208 /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)),
2209 if the upper part of reg N does not appear in the MEM, arrange to
2210 emit the move late-half first. Otherwise, compute the MEM address
2211 into the upper part of N and use that as a pointer to the memory
2213 if (optype0 == REGOP
2214 && (optype1 == OFFSOP || optype1 == MEMOP))
2216 rtx testlow = gen_rtx_REG (SImode, REGNO (operands[0]));
2218 if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0))
2219 && reg_overlap_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
2221 /* If both halves of dest are used in the src memory address,
2222 compute the address into latehalf of dest.
2223 Note that this can't happen if the dest is two data regs. */
2225 xops[0] = latehalf[0];
2226 xops[1] = XEXP (operands[1], 0);
2227 output_asm_insn ("lea %a1,%0", xops);
2228 if (GET_MODE (operands[1]) == XFmode )
2230 operands[1] = gen_rtx_MEM (XFmode, latehalf[0]);
2231 middlehalf[1] = adjust_address (operands[1], DImode, size - 8);
2232 latehalf[1] = adjust_address (operands[1], DImode, size - 4);
2236 operands[1] = gen_rtx_MEM (DImode, latehalf[0]);
2237 latehalf[1] = adjust_address (operands[1], DImode, size - 4);
2241 && reg_overlap_mentioned_p (middlehalf[0],
2242 XEXP (operands[1], 0)))
2244 /* Check for two regs used by both source and dest.
2245 Note that this can't happen if the dest is all data regs.
2246 It can happen if the dest is d6, d7, a0.
2247 But in that case, latehalf is an addr reg, so
2248 the code at compadr does ok. */
2250 if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0))
2251 || reg_overlap_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
2254 /* JRV says this can't happen: */
2255 if (addreg0 || addreg1)
2258 /* Only the middle reg conflicts; simply put it last. */
2259 output_asm_insn (singlemove_string (operands), operands);
2260 output_asm_insn (singlemove_string (latehalf), latehalf);
2261 output_asm_insn (singlemove_string (middlehalf), middlehalf);
2264 else if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0)))
2265 /* If the low half of dest is mentioned in the source memory
2266 address, the arrange to emit the move late half first. */
2267 dest_overlapped_low = 1;
2270 /* If one or both operands autodecrementing,
2271 do the two words, high-numbered first. */
2273 /* Likewise, the first move would clobber the source of the second one,
2274 do them in the other order. This happens only for registers;
2275 such overlap can't happen in memory unless the user explicitly
2276 sets it up, and that is an undefined circumstance. */
2278 if (optype0 == PUSHOP || optype1 == PUSHOP
2279 || (optype0 == REGOP && optype1 == REGOP
2280 && ((middlehalf[1] && REGNO (operands[0]) == REGNO (middlehalf[1]))
2281 || REGNO (operands[0]) == REGNO (latehalf[1])))
2282 || dest_overlapped_low)
2284 /* Make any unoffsettable addresses point at high-numbered word. */
2288 output_asm_insn ("addq%.l %#8,%0", &addreg0);
2290 output_asm_insn ("addq%.l %#4,%0", &addreg0);
2295 output_asm_insn ("addq%.l %#8,%0", &addreg1);
2297 output_asm_insn ("addq%.l %#4,%0", &addreg1);
2301 output_asm_insn (singlemove_string (latehalf), latehalf);
2303 /* Undo the adds we just did. */
2305 output_asm_insn ("subq%.l %#4,%0", &addreg0);
2307 output_asm_insn ("subq%.l %#4,%0", &addreg1);
2311 output_asm_insn (singlemove_string (middlehalf), middlehalf);
2313 output_asm_insn ("subq%.l %#4,%0", &addreg0);
2315 output_asm_insn ("subq%.l %#4,%0", &addreg1);
2318 /* Do low-numbered word. */
2319 return singlemove_string (operands);
2322 /* Normal case: do the two words, low-numbered first. */
2324 output_asm_insn (singlemove_string (operands), operands);
2326 /* Do the middle one of the three words for long double */
2330 output_asm_insn ("addq%.l %#4,%0", &addreg0);
2332 output_asm_insn ("addq%.l %#4,%0", &addreg1);
2334 output_asm_insn (singlemove_string (middlehalf), middlehalf);
2337 /* Make any unoffsettable addresses point at high-numbered word. */
2339 output_asm_insn ("addq%.l %#4,%0", &addreg0);
2341 output_asm_insn ("addq%.l %#4,%0", &addreg1);
2344 output_asm_insn (singlemove_string (latehalf), latehalf);
2346 /* Undo the adds we just did. */
2350 output_asm_insn ("subq%.l %#8,%0", &addreg0);
2352 output_asm_insn ("subq%.l %#4,%0", &addreg0);
2357 output_asm_insn ("subq%.l %#8,%0", &addreg1);
2359 output_asm_insn ("subq%.l %#4,%0", &addreg1);
2365 /* Return a REG that occurs in ADDR with coefficient 1.
2366 ADDR can be effectively incremented by incrementing REG. */
2369 find_addr_reg (addr)
2372 while (GET_CODE (addr) == PLUS)
2374 if (GET_CODE (XEXP (addr, 0)) == REG)
2375 addr = XEXP (addr, 0);
2376 else if (GET_CODE (XEXP (addr, 1)) == REG)
2377 addr = XEXP (addr, 1);
2378 else if (CONSTANT_P (XEXP (addr, 0)))
2379 addr = XEXP (addr, 1);
2380 else if (CONSTANT_P (XEXP (addr, 1)))
2381 addr = XEXP (addr, 0);
2385 if (GET_CODE (addr) == REG)
2390 /* Output assembler code to perform a 32 bit 3 operand add. */
2393 output_addsi3 (operands)
2396 if (! operands_match_p (operands[0], operands[1]))
2398 if (!ADDRESS_REG_P (operands[1]))
2400 rtx tmp = operands[1];
2402 operands[1] = operands[2];
2406 /* These insns can result from reloads to access
2407 stack slots over 64k from the frame pointer. */
2408 if (GET_CODE (operands[2]) == CONST_INT
2409 && INTVAL (operands[2]) + 0x8000 >= (unsigned) 0x10000)
2410 return "move%.l %2,%0\n\tadd%.l %1,%0";
2412 if (GET_CODE (operands[2]) == REG)
2413 return "lea 0(%1,%2.l),%0";
2415 return "lea %c2(%1),%0";
2418 if (GET_CODE (operands[2]) == REG)
2419 return "lea (%1,%2.l),%0";
2421 return "lea (%c2,%1),%0";
2422 #else /* not MOTOROLA (MIT syntax) */
2423 if (GET_CODE (operands[2]) == REG)
2424 return "lea %1@(0,%2:l),%0";
2426 return "lea %1@(%c2),%0";
2427 #endif /* not MOTOROLA */
2428 #endif /* not SGS */
2430 if (GET_CODE (operands[2]) == CONST_INT)
2433 if (INTVAL (operands[2]) > 0
2434 && INTVAL (operands[2]) <= 8)
2435 return "addq%.l %2,%0";
2436 if (INTVAL (operands[2]) < 0
2437 && INTVAL (operands[2]) >= -8)
2439 operands[2] = GEN_INT (- INTVAL (operands[2]));
2440 return "subq%.l %2,%0";
2442 /* On the CPU32 it is faster to use two addql instructions to
2443 add a small integer (8 < N <= 16) to a register.
2444 Likewise for subql. */
2445 if (TARGET_CPU32 && REG_P (operands[0]))
2447 if (INTVAL (operands[2]) > 8
2448 && INTVAL (operands[2]) <= 16)
2450 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
2451 return "addq%.l %#8,%0\n\taddq%.l %2,%0";
2453 if (INTVAL (operands[2]) < -8
2454 && INTVAL (operands[2]) >= -16)
2456 operands[2] = GEN_INT (- INTVAL (operands[2]) - 8);
2457 return "subq%.l %#8,%0\n\tsubq%.l %2,%0";
2461 if (ADDRESS_REG_P (operands[0])
2462 && INTVAL (operands[2]) >= -0x8000
2463 && INTVAL (operands[2]) < 0x8000)
2466 return "add%.w %2,%0";
2469 return "lea (%c2,%0),%0";
2471 return "lea %0@(%c2),%0";
2475 return "add%.l %2,%0";
2478 /* Store in cc_status the expressions that the condition codes will
2479 describe after execution of an instruction whose pattern is EXP.
2480 Do not alter them if the instruction would not alter the cc's. */
2482 /* On the 68000, all the insns to store in an address register fail to
2483 set the cc's. However, in some cases these instructions can make it
2484 possibly invalid to use the saved cc's. In those cases we clear out
2485 some or all of the saved cc's so they won't be used. */
2488 notice_update_cc (exp, insn)
2492 /* If the cc is being set from the fpa and the expression is not an
2493 explicit floating point test instruction (which has code to deal with
2494 this), reinit the CC. */
2495 if (((cc_status.value1 && FPA_REG_P (cc_status.value1))
2496 || (cc_status.value2 && FPA_REG_P (cc_status.value2)))
2497 && !(GET_CODE (exp) == PARALLEL
2498 && GET_CODE (XVECEXP (exp, 0, 0)) == SET
2499 && XEXP (XVECEXP (exp, 0, 0), 0) == cc0_rtx))
2503 else if (GET_CODE (exp) == SET)
2505 if (GET_CODE (SET_SRC (exp)) == CALL)
2509 else if (ADDRESS_REG_P (SET_DEST (exp)))
2511 if (cc_status.value1 && modified_in_p (cc_status.value1, insn))
2512 cc_status.value1 = 0;
2513 if (cc_status.value2 && modified_in_p (cc_status.value2, insn))
2514 cc_status.value2 = 0;
2516 else if (!FP_REG_P (SET_DEST (exp))
2517 && SET_DEST (exp) != cc0_rtx
2518 && (FP_REG_P (SET_SRC (exp))
2519 || GET_CODE (SET_SRC (exp)) == FIX
2520 || GET_CODE (SET_SRC (exp)) == FLOAT_TRUNCATE
2521 || GET_CODE (SET_SRC (exp)) == FLOAT_EXTEND))
2525 /* A pair of move insns doesn't produce a useful overall cc. */
2526 else if (!FP_REG_P (SET_DEST (exp))
2527 && !FP_REG_P (SET_SRC (exp))
2528 && GET_MODE_SIZE (GET_MODE (SET_SRC (exp))) > 4
2529 && (GET_CODE (SET_SRC (exp)) == REG
2530 || GET_CODE (SET_SRC (exp)) == MEM
2531 || GET_CODE (SET_SRC (exp)) == CONST_DOUBLE))
2535 else if (GET_CODE (SET_SRC (exp)) == CALL)
2539 else if (XEXP (exp, 0) != pc_rtx)
2541 cc_status.flags = 0;
2542 cc_status.value1 = XEXP (exp, 0);
2543 cc_status.value2 = XEXP (exp, 1);
2546 else if (GET_CODE (exp) == PARALLEL
2547 && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
2549 if (ADDRESS_REG_P (XEXP (XVECEXP (exp, 0, 0), 0)))
2551 else if (XEXP (XVECEXP (exp, 0, 0), 0) != pc_rtx)
2553 cc_status.flags = 0;
2554 cc_status.value1 = XEXP (XVECEXP (exp, 0, 0), 0);
2555 cc_status.value2 = XEXP (XVECEXP (exp, 0, 0), 1);
2560 if (cc_status.value2 != 0
2561 && ADDRESS_REG_P (cc_status.value2)
2562 && GET_MODE (cc_status.value2) == QImode)
2564 if (cc_status.value2 != 0
2565 && !(cc_status.value1 && FPA_REG_P (cc_status.value1)))
2566 switch (GET_CODE (cc_status.value2))
2568 case PLUS: case MINUS: case MULT:
2569 case DIV: case UDIV: case MOD: case UMOD: case NEG:
2570 #if 0 /* These instructions always clear the overflow bit */
2571 case ASHIFT: case ASHIFTRT: case LSHIFTRT:
2572 case ROTATE: case ROTATERT:
2574 if (GET_MODE (cc_status.value2) != VOIDmode)
2575 cc_status.flags |= CC_NO_OVERFLOW;
2578 /* (SET r1 (ZERO_EXTEND r2)) on this machine
2579 ends with a move insn moving r2 in r2's mode.
2580 Thus, the cc's are set for r2.
2581 This can set N bit spuriously. */
2582 cc_status.flags |= CC_NOT_NEGATIVE;
2587 if (cc_status.value1 && GET_CODE (cc_status.value1) == REG
2589 && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
2590 cc_status.value2 = 0;
2591 if (((cc_status.value1 && FP_REG_P (cc_status.value1))
2592 || (cc_status.value2 && FP_REG_P (cc_status.value2)))
2593 && !((cc_status.value1 && FPA_REG_P (cc_status.value1))
2594 || (cc_status.value2 && FPA_REG_P (cc_status.value2))))
2595 cc_status.flags = CC_IN_68881;
2599 output_move_const_double (operands)
2602 #ifdef SUPPORT_SUN_FPA
2603 if (TARGET_FPA && FPA_REG_P (operands[0]))
2605 int code = standard_sun_fpa_constant_p (operands[1]);
2609 static char buf[40];
2611 sprintf (buf, "fpmove%%.d %%%%%d,%%0", code & 0x1ff);
2614 return "fpmove%.d %1,%0";
2619 int code = standard_68881_constant_p (operands[1]);
2623 static char buf[40];
2625 sprintf (buf, "fmovecr %%#0x%x,%%0", code & 0xff);
2628 return "fmove%.d %1,%0";
2633 output_move_const_single (operands)
2636 #ifdef SUPPORT_SUN_FPA
2639 int code = standard_sun_fpa_constant_p (operands[1]);
2643 static char buf[40];
2645 sprintf (buf, "fpmove%%.s %%%%%d,%%0", code & 0x1ff);
2648 return "fpmove%.s %1,%0";
2651 #endif /* defined SUPPORT_SUN_FPA */
2653 int code = standard_68881_constant_p (operands[1]);
2657 static char buf[40];
2659 sprintf (buf, "fmovecr %%#0x%x,%%0", code & 0xff);
2662 return "fmove%.s %f1,%0";
2666 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
2667 from the "fmovecr" instruction.
2668 The value, anded with 0xff, gives the code to use in fmovecr
2669 to get the desired constant. */
2671 /* This code has been fixed for cross-compilation. */
2673 static int inited_68881_table = 0;
2675 static const char *const strings_68881[7] = {
2685 static const int codes_68881[7] = {
2695 REAL_VALUE_TYPE values_68881[7];
2697 /* Set up values_68881 array by converting the decimal values
2698 strings_68881 to binary. */
2705 enum machine_mode mode;
2708 for (i = 0; i < 7; i++)
2712 r = REAL_VALUE_ATOF (strings_68881[i], mode);
2713 values_68881[i] = r;
2715 inited_68881_table = 1;
2719 standard_68881_constant_p (x)
2725 #ifdef NO_ASM_FMOVECR
2729 /* fmovecr must be emulated on the 68040 and 68060, so it shouldn't be
2730 used at all on those chips. */
2731 if (TARGET_68040 || TARGET_68060)
2734 if (! inited_68881_table)
2735 init_68881_table ();
2737 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2739 /* Use REAL_VALUES_IDENTICAL instead of REAL_VALUES_EQUAL so that -0.0
2741 for (i = 0; i < 6; i++)
2743 if (REAL_VALUES_IDENTICAL (r, values_68881[i]))
2744 return (codes_68881[i]);
2747 if (GET_MODE (x) == SFmode)
2750 if (REAL_VALUES_EQUAL (r, values_68881[6]))
2751 return (codes_68881[6]);
2753 /* larger powers of ten in the constants ram are not used
2754 because they are not equal to a `double' C constant. */
2758 /* If X is a floating-point constant, return the logarithm of X base 2,
2759 or 0 if X is not a power of 2. */
2762 floating_exact_log2 (x)
2765 REAL_VALUE_TYPE r, r1;
2768 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2770 if (REAL_VALUES_LESS (r, dconst1))
2773 exp = real_exponent (&r);
2774 real_2expN (&r1, exp);
2775 if (REAL_VALUES_EQUAL (r1, r))
2781 #ifdef SUPPORT_SUN_FPA
2782 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
2783 from the Sun FPA's constant RAM.
2784 The value returned, anded with 0x1ff, gives the code to use in fpmove
2785 to get the desired constant. */
2787 static int inited_FPA_table = 0;
2789 static const char *const strings_FPA[38] = {
2790 /* small rationals */
2803 /* Decimal equivalents of double precision values */
2804 "2.718281828459045091", /* D_E */
2805 "6.283185307179586477", /* 2 pi */
2806 "3.141592653589793116", /* D_PI */
2807 "1.570796326794896619", /* pi/2 */
2808 "1.414213562373095145", /* D_SQRT2 */
2809 "0.7071067811865475244", /* 1/sqrt(2) */
2810 "-1.570796326794896619", /* -pi/2 */
2811 "1.442695040888963387", /* D_LOG2ofE */
2812 "3.321928024887362182", /* D_LOG2of10 */
2813 "0.6931471805599452862", /* D_LOGEof2 */
2814 "2.302585092994045901", /* D_LOGEof10 */
2815 "0.3010299956639811980", /* D_LOG10of2 */
2816 "0.4342944819032518167", /* D_LOG10ofE */
2817 /* Decimal equivalents of single precision values */
2818 "2.718281745910644531", /* S_E */
2819 "6.283185307179586477", /* 2 pi */
2820 "3.141592741012573242", /* S_PI */
2821 "1.570796326794896619", /* pi/2 */
2822 "1.414213538169860840", /* S_SQRT2 */
2823 "0.7071067811865475244", /* 1/sqrt(2) */
2824 "-1.570796326794896619", /* -pi/2 */
2825 "1.442695021629333496", /* S_LOG2ofE */
2826 "3.321928024291992188", /* S_LOG2of10 */
2827 "0.6931471824645996094", /* S_LOGEof2 */
2828 "2.302585124969482442", /* S_LOGEof10 */
2829 "0.3010300099849700928", /* S_LOG10of2 */
2830 "0.4342944920063018799", /* S_LOG10ofE */
2834 static const int codes_FPA[38] = {
2835 /* small rationals */
2848 /* double precision */
2862 /* single precision */
2878 REAL_VALUE_TYPE values_FPA[38];
2880 /* This code has been fixed for cross-compilation. */
2882 static void init_FPA_table PARAMS ((void));
2886 enum machine_mode mode;
2891 for (i = 0; i < 38; i++)
2895 r = REAL_VALUE_ATOF (strings_FPA[i], mode);
2898 inited_FPA_table = 1;
2903 standard_sun_fpa_constant_p (x)
2909 if (! inited_FPA_table)
2912 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2914 for (i=0; i<12; i++)
2916 if (REAL_VALUES_EQUAL (r, values_FPA[i]))
2917 return (codes_FPA[i]);
2920 if (GET_MODE (x) == SFmode)
2922 for (i=25; i<38; i++)
2924 if (REAL_VALUES_EQUAL (r, values_FPA[i]))
2925 return (codes_FPA[i]);
2930 for (i=12; i<25; i++)
2932 if (REAL_VALUES_EQUAL (r, values_FPA[i]))
2933 return (codes_FPA[i]);
2938 #endif /* define SUPPORT_SUN_FPA */
2940 /* A C compound statement to output to stdio stream STREAM the
2941 assembler syntax for an instruction operand X. X is an RTL
2944 CODE is a value that can be used to specify one of several ways
2945 of printing the operand. It is used when identical operands
2946 must be printed differently depending on the context. CODE
2947 comes from the `%' specification that was used to request
2948 printing of the operand. If the specification was just `%DIGIT'
2949 then CODE is 0; if the specification was `%LTR DIGIT' then CODE
2950 is the ASCII code for LTR.
2952 If X is a register, this macro should print the register's name.
2953 The names can be found in an array `reg_names' whose type is
2954 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
2956 When the machine description has a specification `%PUNCT' (a `%'
2957 followed by a punctuation character), this macro is called with
2958 a null pointer for X and the punctuation character for CODE.
2960 The m68k specific codes are:
2962 '.' for dot needed in Motorola-style opcode names.
2963 '-' for an operand pushing on the stack:
2964 sp@-, -(sp) or -(%sp) depending on the style of syntax.
2965 '+' for an operand pushing on the stack:
2966 sp@+, (sp)+ or (%sp)+ depending on the style of syntax.
2967 '@' for a reference to the top word on the stack:
2968 sp@, (sp) or (%sp) depending on the style of syntax.
2969 '#' for an immediate operand prefix (# in MIT and Motorola syntax
2970 but & in SGS syntax, $ in CRDS/UNOS syntax).
2971 '!' for the cc register (used in an `and to cc' insn).
2972 '$' for the letter `s' in an op code, but only on the 68040.
2973 '&' for the letter `d' in an op code, but only on the 68040.
2974 '/' for register prefix needed by longlong.h.
2976 'b' for byte insn (no effect, on the Sun; this is for the ISI).
2977 'd' to force memory addressing to be absolute, not relative.
2978 'f' for float insn (print a CONST_DOUBLE as a float rather than in hex)
2979 'o' for operands to go directly to output_operand_address (bypassing
2980 print_operand_address--used only for SYMBOL_REFs under TARGET_PCREL)
2981 'w' for FPA insn (print a CONST_DOUBLE as a SunFPA constant rather
2982 than directly). Second part of 'y' below.
2983 'x' for float insn (print a CONST_DOUBLE as a float rather than in hex),
2984 or print pair of registers as rx:ry.
2985 'y' for a FPA insn (print pair of registers as rx:ry). This also outputs
2986 CONST_DOUBLE's as SunFPA constant RAM registers if
2987 possible, so it should not be used except for the SunFPA.
2992 print_operand (file, op, letter)
2993 FILE *file; /* file to write to */
2994 rtx op; /* operand to print */
2995 int letter; /* %<letter> or 0 */
2997 #ifdef SUPPORT_SUN_FPA
3003 #if defined (MOTOROLA) && !defined (CRDS)
3004 fprintf (file, ".");
3007 else if (letter == '#')
3009 asm_fprintf (file, "%0I");
3011 else if (letter == '-')
3014 asm_fprintf (file, "-(%Rsp)");
3016 asm_fprintf (file, "%Rsp@-");
3019 else if (letter == '+')
3022 asm_fprintf (file, "(%Rsp)+");
3024 asm_fprintf (file, "%Rsp@+");
3027 else if (letter == '@')
3030 asm_fprintf (file, "(%Rsp)");
3032 asm_fprintf (file, "%Rsp@");
3035 else if (letter == '!')
3037 asm_fprintf (file, "%Rfpcr");
3039 else if (letter == '$')
3041 if (TARGET_68040_ONLY)
3043 fprintf (file, "s");
3046 else if (letter == '&')
3048 if (TARGET_68040_ONLY)
3050 fprintf (file, "d");
3053 else if (letter == '/')
3055 asm_fprintf (file, "%R");
3057 else if (letter == 'o')
3059 /* This is only for direct addresses with TARGET_PCREL */
3060 if (GET_CODE (op) != MEM || GET_CODE (XEXP (op, 0)) != SYMBOL_REF
3063 output_addr_const (file, XEXP (op, 0));
3065 else if (GET_CODE (op) == REG)
3067 #ifdef SUPPORT_SUN_FPA
3069 && (letter == 'y' || letter == 'x')
3070 && GET_MODE (op) == DFmode)
3072 fprintf (file, "%s:%s", reg_names[REGNO (op)],
3073 reg_names[REGNO (op)+1]);
3079 /* Print out the second register name of a register pair.
3080 I.e., R (6) => 7. */
3081 fputs (reg_names[REGNO (op) + 1], file);
3083 fputs (reg_names[REGNO (op)], file);
3086 else if (GET_CODE (op) == MEM)
3088 output_address (XEXP (op, 0));
3089 if (letter == 'd' && ! TARGET_68020
3090 && CONSTANT_ADDRESS_P (XEXP (op, 0))
3091 && !(GET_CODE (XEXP (op, 0)) == CONST_INT
3092 && INTVAL (XEXP (op, 0)) < 0x8000
3093 && INTVAL (XEXP (op, 0)) >= -0x8000))
3096 fprintf (file, ".l");
3098 fprintf (file, ":l");
3102 #ifdef SUPPORT_SUN_FPA
3103 else if ((letter == 'y' || letter == 'w')
3104 && GET_CODE (op) == CONST_DOUBLE
3105 && (i = standard_sun_fpa_constant_p (op)))
3107 fprintf (file, "%%%d", i & 0x1ff);
3110 else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == SFmode)
3113 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
3114 ASM_OUTPUT_FLOAT_OPERAND (letter, file, r);
3116 else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == XFmode)
3119 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
3120 ASM_OUTPUT_LONG_DOUBLE_OPERAND (file, r);
3122 else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == DFmode)
3125 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
3126 ASM_OUTPUT_DOUBLE_OPERAND (file, r);
3130 /* Use `print_operand_address' instead of `output_addr_const'
3131 to ensure that we print relevant PIC stuff. */
3132 asm_fprintf (file, "%0I");
3134 && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST))
3135 print_operand_address (file, op);
3137 output_addr_const (file, op);
3142 /* A C compound statement to output to stdio stream STREAM the
3143 assembler syntax for an instruction operand that is a memory
3144 reference whose address is ADDR. ADDR is an RTL expression.
3146 Note that this contains a kludge that knows that the only reason
3147 we have an address (plus (label_ref...) (reg...)) when not generating
3148 PIC code is in the insn before a tablejump, and we know that m68k.md
3149 generates a label LInnn: on such an insn.
3151 It is possible for PIC to generate a (plus (label_ref...) (reg...))
3152 and we handle that just like we would a (plus (symbol_ref...) (reg...)).
3154 Some SGS assemblers have a bug such that "Lnnn-LInnn-2.b(pc,d0.l*2)"
3155 fails to assemble. Luckily "Lnnn(pc,d0.l*2)" produces the results
3156 we want. This difference can be accommodated by using an assembler
3157 define such "LDnnn" to be either "Lnnn-LInnn-2.b", "Lnnn", or any other
3158 string, as necessary. This is accomplished via the ASM_OUTPUT_CASE_END
3159 macro. See m68k/sgs.h for an example; for versions without the bug.
3160 Some assemblers refuse all the above solutions. The workaround is to
3161 emit "K(pc,d0.l*2)" with K being a small constant known to give the
3164 They also do not like things like "pea 1.w", so we simple leave off
3165 the .w on small constants.
3167 This routine is responsible for distinguishing between -fpic and -fPIC
3168 style relocations in an address. When generating -fpic code the
3169 offset is output in word mode (eg movel a5@(_foo:w), a0). When generating
3170 -fPIC code the offset is output in long mode (eg movel a5@(_foo:l), a0) */
3172 #ifndef ASM_OUTPUT_CASE_FETCH
3175 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
3176 asm_fprintf (file, "%LLD%d(%Rpc,%s.", labelno, regname)
3178 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
3179 asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.", labelno, labelno, regname)
3182 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
3183 asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:", labelno, labelno, regname)
3185 #endif /* ASM_OUTPUT_CASE_FETCH */
3188 print_operand_address (file, addr)
3192 register rtx reg1, reg2, breg, ireg;
3195 switch (GET_CODE (addr))
3199 fprintf (file, "(%s)", reg_names[REGNO (addr)]);
3201 fprintf (file, "%s@", reg_names[REGNO (addr)]);
3206 fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
3208 fprintf (file, "%s@-", reg_names[REGNO (XEXP (addr, 0))]);
3213 fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
3215 fprintf (file, "%s@+", reg_names[REGNO (XEXP (addr, 0))]);
3219 reg1 = reg2 = ireg = breg = offset = 0;
3220 if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
3222 offset = XEXP (addr, 0);
3223 addr = XEXP (addr, 1);
3225 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
3227 offset = XEXP (addr, 1);
3228 addr = XEXP (addr, 0);
3230 if (GET_CODE (addr) != PLUS)
3234 else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND)
3236 reg1 = XEXP (addr, 0);
3237 addr = XEXP (addr, 1);
3239 else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND)
3241 reg1 = XEXP (addr, 1);
3242 addr = XEXP (addr, 0);
3244 else if (GET_CODE (XEXP (addr, 0)) == MULT)
3246 reg1 = XEXP (addr, 0);
3247 addr = XEXP (addr, 1);
3249 else if (GET_CODE (XEXP (addr, 1)) == MULT)
3251 reg1 = XEXP (addr, 1);
3252 addr = XEXP (addr, 0);
3254 else if (GET_CODE (XEXP (addr, 0)) == REG)
3256 reg1 = XEXP (addr, 0);
3257 addr = XEXP (addr, 1);
3259 else if (GET_CODE (XEXP (addr, 1)) == REG)
3261 reg1 = XEXP (addr, 1);
3262 addr = XEXP (addr, 0);
3264 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT
3265 || GET_CODE (addr) == SIGN_EXTEND)
3277 #if 0 /* for OLD_INDEXING */
3278 else if (GET_CODE (addr) == PLUS)
3280 if (GET_CODE (XEXP (addr, 0)) == REG)
3282 reg2 = XEXP (addr, 0);
3283 addr = XEXP (addr, 1);
3285 else if (GET_CODE (XEXP (addr, 1)) == REG)
3287 reg2 = XEXP (addr, 1);
3288 addr = XEXP (addr, 0);
3300 if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND
3301 || GET_CODE (reg1) == MULT))
3302 || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
3307 else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
3312 if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF
3313 && ! (flag_pic && ireg == pic_offset_table_rtx))
3316 if (GET_CODE (ireg) == MULT)
3318 scale = INTVAL (XEXP (ireg, 1));
3319 ireg = XEXP (ireg, 0);
3321 if (GET_CODE (ireg) == SIGN_EXTEND)
3323 ASM_OUTPUT_CASE_FETCH (file,
3324 CODE_LABEL_NUMBER (XEXP (addr, 0)),
3325 reg_names[REGNO (XEXP (ireg, 0))]);
3326 fprintf (file, "w");
3330 ASM_OUTPUT_CASE_FETCH (file,
3331 CODE_LABEL_NUMBER (XEXP (addr, 0)),
3332 reg_names[REGNO (ireg)]);
3333 fprintf (file, "l");
3338 fprintf (file, "*%d", scale);
3340 fprintf (file, ":%d", scale);
3346 if (breg != 0 && ireg == 0 && GET_CODE (addr) == LABEL_REF
3347 && ! (flag_pic && breg == pic_offset_table_rtx))
3349 ASM_OUTPUT_CASE_FETCH (file,
3350 CODE_LABEL_NUMBER (XEXP (addr, 0)),
3351 reg_names[REGNO (breg)]);
3352 fprintf (file, "l)");
3355 if (ireg != 0 || breg != 0)
3362 if (! flag_pic && addr && GET_CODE (addr) == LABEL_REF)
3369 output_addr_const (file, addr);
3370 if (flag_pic && (breg == pic_offset_table_rtx))
3372 fprintf (file, "@GOT");
3374 fprintf (file, ".w");
3377 fprintf (file, "(%s", reg_names[REGNO (breg)]);
3383 fprintf (file, "%s@(", reg_names[REGNO (breg)]);
3386 output_addr_const (file, addr);
3387 if ((flag_pic == 1) && (breg == pic_offset_table_rtx))
3388 fprintf (file, ":w");
3389 if ((flag_pic == 2) && (breg == pic_offset_table_rtx))
3390 fprintf (file, ":l");
3392 if (addr != 0 && ireg != 0)
3397 if (ireg != 0 && GET_CODE (ireg) == MULT)
3399 scale = INTVAL (XEXP (ireg, 1));
3400 ireg = XEXP (ireg, 0);
3402 if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND)
3405 fprintf (file, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]);
3407 fprintf (file, "%s:w", reg_names[REGNO (XEXP (ireg, 0))]);
3413 fprintf (file, "%s.l", reg_names[REGNO (ireg)]);
3415 fprintf (file, "%s:l", reg_names[REGNO (ireg)]);
3421 fprintf (file, "*%d", scale);
3423 fprintf (file, ":%d", scale);
3429 else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF
3430 && ! (flag_pic && reg1 == pic_offset_table_rtx))
3432 ASM_OUTPUT_CASE_FETCH (file,
3433 CODE_LABEL_NUMBER (XEXP (addr, 0)),
3434 reg_names[REGNO (reg1)]);
3435 fprintf (file, "l)");
3438 /* FALL-THROUGH (is this really what we want?) */
3440 if (GET_CODE (addr) == CONST_INT
3441 && INTVAL (addr) < 0x8000
3442 && INTVAL (addr) >= -0x8000)
3446 /* Many SGS assemblers croak on size specifiers for constants. */
3447 fprintf (file, "%d", (int) INTVAL (addr));
3449 fprintf (file, "%d.w", (int) INTVAL (addr));
3452 fprintf (file, "%d:w", (int) INTVAL (addr));
3455 else if (GET_CODE (addr) == CONST_INT)
3457 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (addr));
3459 else if (TARGET_PCREL)
3462 output_addr_const (file, addr);
3464 asm_fprintf (file, ":w,%Rpc)");
3466 asm_fprintf (file, ":l,%Rpc)");
3470 /* Special case for SYMBOL_REF if the symbol name ends in
3471 `.<letter>', this can be mistaken as a size suffix. Put
3472 the name in parentheses. */
3473 if (GET_CODE (addr) == SYMBOL_REF
3474 && strlen (XSTR (addr, 0)) > 2
3475 && XSTR (addr, 0)[strlen (XSTR (addr, 0)) - 2] == '.')
3478 output_addr_const (file, addr);
3482 output_addr_const (file, addr);
3488 /* Check for cases where a clr insns can be omitted from code using
3489 strict_low_part sets. For example, the second clrl here is not needed:
3490 clrl d0; movw a0@+,d0; use d0; clrl d0; movw a0@+; use d0; ...
3492 MODE is the mode of this STRICT_LOW_PART set. FIRST_INSN is the clear
3493 insn we are checking for redundancy. TARGET is the register set by the
3497 strict_low_part_peephole_ok (mode, first_insn, target)
3498 enum machine_mode mode;
3504 p = prev_nonnote_insn (first_insn);
3508 /* If it isn't an insn, then give up. */
3509 if (GET_CODE (p) != INSN)
3512 if (reg_set_p (target, p))
3514 rtx set = single_set (p);
3517 /* If it isn't an easy to recognize insn, then give up. */
3521 dest = SET_DEST (set);
3523 /* If this sets the entire target register to zero, then our
3524 first_insn is redundant. */
3525 if (rtx_equal_p (dest, target)
3526 && SET_SRC (set) == const0_rtx)
3528 else if (GET_CODE (dest) == STRICT_LOW_PART
3529 && GET_CODE (XEXP (dest, 0)) == REG
3530 && REGNO (XEXP (dest, 0)) == REGNO (target)
3531 && (GET_MODE_SIZE (GET_MODE (XEXP (dest, 0)))
3532 <= GET_MODE_SIZE (mode)))
3533 /* This is a strict low part set which modifies less than
3534 we are using, so it is safe. */
3540 p = prev_nonnote_insn (p);
3547 /* Accept integer operands in the range 0..0xffffffff. We have to check the
3548 range carefully since this predicate is used in DImode contexts. Also, we
3549 need some extra crud to make it work when hosted on 64-bit machines. */
3552 const_uint32_operand (op, mode)
3554 enum machine_mode mode;
3556 /* It doesn't make sense to ask this question with a mode that is
3557 not larger than 32 bits. */
3558 if (GET_MODE_BITSIZE (mode) <= 32)
3561 #if HOST_BITS_PER_WIDE_INT > 32
3562 /* All allowed constants will fit a CONST_INT. */
3563 return (GET_CODE (op) == CONST_INT
3564 && (INTVAL (op) >= 0 && INTVAL (op) <= 0xffffffffL));
3566 return (GET_CODE (op) == CONST_INT
3567 || (GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_HIGH (op) == 0));
3571 /* Accept integer operands in the range -0x80000000..0x7fffffff. We have
3572 to check the range carefully since this predicate is used in DImode
3576 const_sint32_operand (op, mode)
3578 enum machine_mode mode;
3580 /* It doesn't make sense to ask this question with a mode that is
3581 not larger than 32 bits. */
3582 if (GET_MODE_BITSIZE (mode) <= 32)
3585 /* All allowed constants will fit a CONST_INT. */
3586 return (GET_CODE (op) == CONST_INT
3587 && (INTVAL (op) >= (-0x7fffffff - 1) && INTVAL (op) <= 0x7fffffff));
3590 /* Operand predicates for implementing asymmetric pc-relative addressing
3591 on m68k. The m68k supports pc-relative addressing (mode 7, register 2)
3592 when used as a source operand, but not as a destintation operand.
3594 We model this by restricting the meaning of the basic predicates
3595 (general_operand, memory_operand, etc) to forbid the use of this
3596 addressing mode, and then define the following predicates that permit
3597 this addressing mode. These predicates can then be used for the
3598 source operands of the appropriate instructions.
3600 n.b. While it is theoretically possible to change all machine patterns
3601 to use this addressing more where permitted by the architecture,
3602 it has only been implemented for "common" cases: SImode, HImode, and
3603 QImode operands, and only for the principle operations that would
3604 require this addressing mode: data movement and simple integer operations.
3606 In parallel with these new predicates, two new constraint letters
3607 were defined: 'S' and 'T'. 'S' is the -mpcrel analog of 'm'.
3608 'T' replaces 's' in the non-pcrel case. It is a no-op in the pcrel case.
3609 In the pcrel case 's' is only valid in combination with 'a' registers.
3610 See addsi3, subsi3, cmpsi, and movsi patterns for a better understanding
3611 of how these constraints are used.
3613 The use of these predicates is strictly optional, though patterns that
3614 don't will cause an extra reload register to be allocated where one
3617 lea (abc:w,%pc),%a0 ; need to reload address
3618 moveq &1,%d1 ; since write to pc-relative space
3619 movel %d1,%a0@ ; is not allowed
3621 lea (abc:w,%pc),%a1 ; no need to reload address here
3622 movel %a1@,%d0 ; since "movel (abc:w,%pc),%d0" is ok
3624 For more info, consult tiemann@cygnus.com.
3627 All of the ugliness with predicates and constraints is due to the
3628 simple fact that the m68k does not allow a pc-relative addressing
3629 mode as a destination. gcc does not distinguish between source and
3630 destination addresses. Hence, if we claim that pc-relative address
3631 modes are valid, e.g. GO_IF_LEGITIMATE_ADDRESS accepts them, then we
3632 end up with invalid code. To get around this problem, we left
3633 pc-relative modes as invalid addresses, and then added special
3634 predicates and constraints to accept them.
3636 A cleaner way to handle this is to modify gcc to distinguish
3637 between source and destination addresses. We can then say that
3638 pc-relative is a valid source address but not a valid destination
3639 address, and hopefully avoid a lot of the predicate and constraint
3640 hackery. Unfortunately, this would be a pretty big change. It would
3641 be a useful change for a number of ports, but there aren't any current
3642 plans to undertake this.
3644 ***************************************************************************/
3647 /* Special case of a general operand that's used as a source operand.
3648 Use this to permit reads from PC-relative memory when -mpcrel
3652 general_src_operand (op, mode)
3654 enum machine_mode mode;
3657 && GET_CODE (op) == MEM
3658 && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
3659 || GET_CODE (XEXP (op, 0)) == LABEL_REF
3660 || GET_CODE (XEXP (op, 0)) == CONST))
3662 return general_operand (op, mode);
3665 /* Special case of a nonimmediate operand that's used as a source.
3666 Use this to permit reads from PC-relative memory when -mpcrel
3670 nonimmediate_src_operand (op, mode)
3672 enum machine_mode mode;
3674 if (TARGET_PCREL && GET_CODE (op) == MEM
3675 && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
3676 || GET_CODE (XEXP (op, 0)) == LABEL_REF
3677 || GET_CODE (XEXP (op, 0)) == CONST))
3679 return nonimmediate_operand (op, mode);
3682 /* Special case of a memory operand that's used as a source.
3683 Use this to permit reads from PC-relative memory when -mpcrel
3687 memory_src_operand (op, mode)
3689 enum machine_mode mode;
3691 if (TARGET_PCREL && GET_CODE (op) == MEM
3692 && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
3693 || GET_CODE (XEXP (op, 0)) == LABEL_REF
3694 || GET_CODE (XEXP (op, 0)) == CONST))
3696 return memory_operand (op, mode);
3699 /* Predicate that accepts only a pc-relative address. This is needed
3700 because pc-relative addresses don't satisfy the predicate
3701 "general_src_operand". */
3704 pcrel_address (op, mode)
3706 enum machine_mode mode ATTRIBUTE_UNUSED;
3708 return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF
3709 || GET_CODE (op) == CONST);
3713 output_andsi3 (operands)
3717 if (GET_CODE (operands[2]) == CONST_INT
3718 && (INTVAL (operands[2]) | 0xffff) == 0xffffffff
3719 && (DATA_REG_P (operands[0])
3720 || offsettable_memref_p (operands[0]))
3723 if (GET_CODE (operands[0]) != REG)
3724 operands[0] = adjust_address (operands[0], HImode, 2);
3725 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
3726 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3728 if (operands[2] == const0_rtx)
3730 return "and%.w %2,%0";
3732 if (GET_CODE (operands[2]) == CONST_INT
3733 && (logval = exact_log2 (~ INTVAL (operands[2]))) >= 0
3734 && (DATA_REG_P (operands[0])
3735 || offsettable_memref_p (operands[0])))
3737 if (DATA_REG_P (operands[0]))
3739 operands[1] = GEN_INT (logval);
3743 operands[0] = adjust_address (operands[0], SImode, 3 - (logval / 8));
3744 operands[1] = GEN_INT (logval % 8);
3746 /* This does not set condition codes in a standard way. */
3748 return "bclr %1,%0";
3750 return "and%.l %2,%0";
3754 output_iorsi3 (operands)
3757 register int logval;
3758 if (GET_CODE (operands[2]) == CONST_INT
3759 && INTVAL (operands[2]) >> 16 == 0
3760 && (DATA_REG_P (operands[0])
3761 || offsettable_memref_p (operands[0]))
3764 if (GET_CODE (operands[0]) != REG)
3765 operands[0] = adjust_address (operands[0], HImode, 2);
3766 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3768 if (INTVAL (operands[2]) == 0xffff)
3769 return "mov%.w %2,%0";
3770 return "or%.w %2,%0";
3772 if (GET_CODE (operands[2]) == CONST_INT
3773 && (logval = exact_log2 (INTVAL (operands[2]))) >= 0
3774 && (DATA_REG_P (operands[0])
3775 || offsettable_memref_p (operands[0])))
3777 if (DATA_REG_P (operands[0]))
3778 operands[1] = GEN_INT (logval);
3781 operands[0] = adjust_address (operands[0], SImode, 3 - (logval / 8));
3782 operands[1] = GEN_INT (logval % 8);
3785 return "bset %1,%0";
3787 return "or%.l %2,%0";
3791 output_xorsi3 (operands)
3794 register int logval;
3795 if (GET_CODE (operands[2]) == CONST_INT
3796 && INTVAL (operands[2]) >> 16 == 0
3797 && (offsettable_memref_p (operands[0]) || DATA_REG_P (operands[0]))
3800 if (! DATA_REG_P (operands[0]))
3801 operands[0] = adjust_address (operands[0], HImode, 2);
3802 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3804 if (INTVAL (operands[2]) == 0xffff)
3806 return "eor%.w %2,%0";
3808 if (GET_CODE (operands[2]) == CONST_INT
3809 && (logval = exact_log2 (INTVAL (operands[2]))) >= 0
3810 && (DATA_REG_P (operands[0])
3811 || offsettable_memref_p (operands[0])))
3813 if (DATA_REG_P (operands[0]))
3814 operands[1] = GEN_INT (logval);
3817 operands[0] = adjust_address (operands[0], SImode, 3 - (logval / 8));
3818 operands[1] = GEN_INT (logval % 8);
3821 return "bchg %1,%0";
3823 return "eor%.l %2,%0";
3826 /* Output assembly to switch to section NAME with attribute FLAGS. */
3829 m68k_coff_asm_named_section (name, flags)
3835 if (flags & SECTION_WRITE)
3840 fprintf (asm_out_file, "\t.section\t%s,\"%c\"\n", name, flagchar);
3843 #ifdef CTOR_LIST_BEGIN
3845 m68k_svr3_asm_out_constructor (symbol, priority)
3847 int priority ATTRIBUTE_UNUSED;
3852 xop[0] = gen_rtx_MEM (SImode, gen_rtx_PRE_DEC (SImode, stack_pointer_rtx));
3855 output_asm_insn (output_move_simode (xop), xop);
3860 m68k_output_mi_thunk (file, thunk, delta, vcall_offset, function)
3862 tree thunk ATTRIBUTE_UNUSED;
3863 HOST_WIDE_INT delta;
3864 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED;
3870 if (delta > 0 && delta <= 8)
3871 asm_fprintf (file, "\taddq.l %I%d,4(%Rsp)\n", (int) delta);
3872 else if (delta < 0 && delta >= -8)
3873 asm_fprintf (file, "\tsubq.l %I%d,4(%Rsp)\n", (int) -delta);
3876 asm_fprintf (file, "\tadd.l %I");
3877 fprintf (file, HOST_WIDE_INT_PRINT_DEC, delta);
3878 asm_fprintf (file, ",4(%Rsp)\n");
3881 xops[0] = DECL_RTL (function);
3883 /* Logic taken from call patterns in m68k.md. */
3895 fmt = "bra.l %0@PLTPC";
3897 fmt = "bra %0@PLTPC";
3911 #if defined (MOTOROLA) && !defined (USE_GAS)
3922 output_asm_insn (fmt, xops);