* Makefile.in (cse.o): Depend on TARGET_H.
[official-gcc.git] / gcc / config / m68k / m68k.c
blobcb94d2329233044585c31d911c615073eb603f32
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)
10 any later version.
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. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "tree.h"
27 #include "rtl.h"
28 #include "function.h"
29 #include "regs.h"
30 #include "hard-reg-set.h"
31 #include "real.h"
32 #include "insn-config.h"
33 #include "conditions.h"
34 #include "output.h"
35 #include "insn-attr.h"
36 #include "recog.h"
37 #include "toplev.h"
38 #include "expr.h"
39 #include "reload.h"
40 #include "tm_p.h"
41 #include "target.h"
42 #include "target-def.h"
43 #include "debug.h"
45 /* Needed for use_return_insn. */
46 #include "flags.h"
48 #ifdef SUPPORT_SUN_FPA
50 /* Index into this array by (register number >> 3) to find the
51 smallest class which contains that register. */
52 const enum reg_class regno_reg_class[]
53 = { DATA_REGS, ADDR_REGS, FP_REGS,
54 LO_FPA_REGS, LO_FPA_REGS, FPA_REGS, FPA_REGS };
56 #endif /* defined SUPPORT_SUN_FPA */
58 /* This flag is used to communicate between movhi and ASM_OUTPUT_CASE_END,
59 if SGS_SWITCH_TABLE. */
60 int switch_table_difference_label_flag;
62 static rtx find_addr_reg PARAMS ((rtx));
63 static const char *singlemove_string PARAMS ((rtx *));
64 static void m68k_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
65 static void m68k_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
66 static void m68k_coff_asm_named_section PARAMS ((const char *, unsigned int));
67 #ifdef CTOR_LIST_BEGIN
68 static void m68k_svr3_asm_out_constructor PARAMS ((rtx, int));
69 #endif
70 #ifdef HPUX_ASM
71 static void m68k_hp320_internal_label PARAMS ((FILE *, const char *, unsigned long));
72 #endif
73 static void m68k_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
74 HOST_WIDE_INT, tree));
75 static int m68k_save_reg PARAMS ((unsigned int));
76 static int const_int_cost PARAMS ((rtx));
77 static bool m68k_rtx_costs PARAMS ((rtx, int, int, int *));
80 /* Alignment to use for loops and jumps */
81 /* Specify power of two alignment used for loops. */
82 const char *m68k_align_loops_string;
83 /* Specify power of two alignment used for non-loop jumps. */
84 const char *m68k_align_jumps_string;
85 /* Specify power of two alignment used for functions. */
86 const char *m68k_align_funcs_string;
88 /* Specify power of two alignment used for loops. */
89 int m68k_align_loops;
90 /* Specify power of two alignment used for non-loop jumps. */
91 int m68k_align_jumps;
92 /* Specify power of two alignment used for functions. */
93 int m68k_align_funcs;
95 /* Nonzero if the last compare/test insn had FP operands. The
96 sCC expanders peek at this to determine what to do for the
97 68060, which has no fsCC instructions. */
98 int m68k_last_compare_had_fp_operands;
100 /* Initialize the GCC target structure. */
102 #if INT_OP_GROUP == INT_OP_DOT_WORD
103 #undef TARGET_ASM_ALIGNED_HI_OP
104 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
105 #endif
107 #if INT_OP_GROUP == INT_OP_NO_DOT
108 #undef TARGET_ASM_BYTE_OP
109 #define TARGET_ASM_BYTE_OP "\tbyte\t"
110 #undef TARGET_ASM_ALIGNED_HI_OP
111 #define TARGET_ASM_ALIGNED_HI_OP "\tshort\t"
112 #undef TARGET_ASM_ALIGNED_SI_OP
113 #define TARGET_ASM_ALIGNED_SI_OP "\tlong\t"
114 #endif
116 #if INT_OP_GROUP == INT_OP_DC
117 #undef TARGET_ASM_BYTE_OP
118 #define TARGET_ASM_BYTE_OP "\tdc.b\t"
119 #undef TARGET_ASM_ALIGNED_HI_OP
120 #define TARGET_ASM_ALIGNED_HI_OP "\tdc.w\t"
121 #undef TARGET_ASM_ALIGNED_SI_OP
122 #define TARGET_ASM_ALIGNED_SI_OP "\tdc.l\t"
123 #endif
125 #undef TARGET_ASM_UNALIGNED_HI_OP
126 #define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP
127 #undef TARGET_ASM_UNALIGNED_SI_OP
128 #define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP
130 #undef TARGET_ASM_FUNCTION_PROLOGUE
131 #define TARGET_ASM_FUNCTION_PROLOGUE m68k_output_function_prologue
132 #undef TARGET_ASM_FUNCTION_EPILOGUE
133 #define TARGET_ASM_FUNCTION_EPILOGUE m68k_output_function_epilogue
134 #ifdef HPUX_ASM
135 #undef TARGET_ASM_INTERNAL_LABEL
136 #define TARGET_ASM_INTERNAL_LABEL m68k_hp320_internal_label
137 #endif
139 #undef TARGET_ASM_OUTPUT_MI_THUNK
140 #define TARGET_ASM_OUTPUT_MI_THUNK m68k_output_mi_thunk
141 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
142 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
144 #undef TARGET_RTX_COSTS
145 #define TARGET_RTX_COSTS m68k_rtx_costs
147 struct gcc_target targetm = TARGET_INITIALIZER;
149 /* Sometimes certain combinations of command options do not make
150 sense on a particular target machine. You can define a macro
151 `OVERRIDE_OPTIONS' to take account of this. This macro, if
152 defined, is executed once just after all the command options have
153 been parsed.
155 Don't use this macro to turn on various extra optimizations for
156 `-O'. That is what `OPTIMIZATION_OPTIONS' is for. */
158 void
159 override_options ()
161 int def_align;
162 int i;
164 def_align = 1;
166 /* Validate -malign-loops= value, or provide default */
167 m68k_align_loops = def_align;
168 if (m68k_align_loops_string)
170 i = atoi (m68k_align_loops_string);
171 if (i < 1 || i > MAX_CODE_ALIGN)
172 error ("-malign-loops=%d is not between 1 and %d", i, MAX_CODE_ALIGN);
173 else
174 m68k_align_loops = i;
177 /* Validate -malign-jumps= value, or provide default */
178 m68k_align_jumps = def_align;
179 if (m68k_align_jumps_string)
181 i = atoi (m68k_align_jumps_string);
182 if (i < 1 || i > MAX_CODE_ALIGN)
183 error ("-malign-jumps=%d is not between 1 and %d", i, MAX_CODE_ALIGN);
184 else
185 m68k_align_jumps = i;
188 /* Validate -malign-functions= value, or provide default */
189 m68k_align_funcs = def_align;
190 if (m68k_align_funcs_string)
192 i = atoi (m68k_align_funcs_string);
193 if (i < 1 || i > MAX_CODE_ALIGN)
194 error ("-malign-functions=%d is not between 1 and %d",
195 i, MAX_CODE_ALIGN);
196 else
197 m68k_align_funcs = i;
200 /* -fPIC uses 32-bit pc-relative displacements, which don't exist
201 until the 68020. */
202 if (! TARGET_68020 && flag_pic == 2)
203 error("-fPIC is not currently supported on the 68000 or 68010\n");
205 /* ??? A historic way of turning on pic, or is this intended to
206 be an embedded thing that doesn't have the same name binding
207 significance that it does on hosted ELF systems? */
208 if (TARGET_PCREL && flag_pic == 0)
209 flag_pic = 1;
211 /* Turn off function cse if we are doing PIC. We always want function call
212 to be done as `bsr foo@PLTPC', so it will force the assembler to create
213 the PLT entry for `foo'. Doing function cse will cause the address of
214 `foo' to be loaded into a register, which is exactly what we want to
215 avoid when we are doing PIC on svr4 m68k. */
216 if (flag_pic)
217 flag_no_function_cse = 1;
219 SUBTARGET_OVERRIDE_OPTIONS;
221 /* Tell the compiler which flavor of XFmode we're using. */
222 real_format_for_mode[XFmode - QFmode] = &ieee_extended_motorola_format;
225 /* Return 1 if we need to save REGNO. */
226 static int
227 m68k_save_reg (regno)
228 unsigned int regno;
230 if (flag_pic && current_function_uses_pic_offset_table
231 && regno == PIC_OFFSET_TABLE_REGNUM)
232 return 1;
234 if (current_function_calls_eh_return)
236 unsigned int i;
237 for (i = 0; ; i++)
239 unsigned int test = EH_RETURN_DATA_REGNO (i);
240 if (test == INVALID_REGNUM)
241 break;
242 if (test == regno)
243 return 1;
247 return (regs_ever_live[regno]
248 && !call_used_regs[regno]
249 && !fixed_regs[regno]
250 && !(regno == FRAME_POINTER_REGNUM && frame_pointer_needed));
253 /* This function generates the assembly code for function entry.
254 STREAM is a stdio stream to output the code to.
255 SIZE is an int: how many units of temporary storage to allocate.
256 Refer to the array `regs_ever_live' to determine which registers
257 to save; `regs_ever_live[I]' is nonzero if register number I
258 is ever used in the function. This function is responsible for
259 knowing which registers should not be saved even if used. */
262 /* Note that the order of the bit mask for fmovem is the opposite
263 of the order for movem! */
265 #ifdef CRDS
267 static void
268 m68k_output_function_prologue (stream, size)
269 FILE *stream;
270 HOST_WIDE_INT size;
272 register int regno;
273 register int mask = 0;
274 HOST_WIDE_INT fsize = ((size) + 3) & -4;
276 /* unos stack probe */
277 if (fsize > 30000)
279 fprintf (stream, "\tmovel sp,a0\n");
280 fprintf (stream, "\taddl $-%d,a0\n", 2048 + fsize);
281 fprintf (stream, "\ttstb (a0)\n");
283 else
284 fprintf (stream, "\ttstb -%d(sp)\n", 2048 + fsize);
286 if (frame_pointer_needed)
288 if (TARGET_68020 || fsize < 0x8000)
289 fprintf (stream, "\tlink a6,$%d\n", -fsize);
290 else
291 fprintf (stream, "\tlink a6,$0\n\tsubl $%d,sp\n", fsize);
293 else if (fsize)
295 /* Adding negative number is faster on the 68040. */
296 if (fsize + 4 < 0x8000)
297 fprintf (stream, "\tadd.w $%d,sp\n", - (fsize + 4));
298 else
299 fprintf (stream, "\tadd.l $%d,sp\n", - (fsize + 4));
302 for (regno = 16; regno < 24; regno++)
303 if (m68k_save_reg (regno))
304 mask |= 1 << (regno - 16);
306 if ((mask & 0xff) != 0)
307 fprintf (stream, "\tfmovem $0x%x,-(sp)\n", mask & 0xff);
309 mask = 0;
310 for (regno = 0; regno < 16; regno++)
311 if (m68k_save_reg (regno))
312 mask |= 1 << (15 - regno);
314 if (exact_log2 (mask) >= 0)
315 fprintf (stream, "\tmovel %s,-(sp)\n", reg_names[15 - exact_log2 (mask)]);
316 else if (mask)
317 fprintf (stream, "\tmovem $0x%x,-(sp)\n", mask);
320 #else /* !CRDS */
322 static void
323 m68k_output_function_prologue (stream, size)
324 FILE *stream;
325 HOST_WIDE_INT size;
327 register int regno;
328 register int mask = 0;
329 int num_saved_regs = 0;
330 HOST_WIDE_INT fsize = (size + 3) & -4;
331 HOST_WIDE_INT cfa_offset = INCOMING_FRAME_SP_OFFSET;
332 HOST_WIDE_INT cfa_store_offset = cfa_offset;
334 /* If the stack limit is a symbol, we can check it here,
335 before actually allocating the space. */
336 if (current_function_limit_stack
337 && GET_CODE (stack_limit_rtx) == SYMBOL_REF)
339 #if defined (MOTOROLA)
340 asm_fprintf (stream, "\tcmp.l %0I%s+%d,%Rsp\n\ttrapcs\n",
341 XSTR (stack_limit_rtx, 0), fsize + 4);
342 #else
343 asm_fprintf (stream, "\tcmpl %0I%s+%d,%Rsp\n\ttrapcs\n",
344 XSTR (stack_limit_rtx, 0), fsize + 4);
345 #endif
348 if (frame_pointer_needed)
350 if (fsize == 0 && TARGET_68040)
352 /* on the 68040, pea + move is faster than link.w 0 */
353 #ifdef MOTOROLA
354 fprintf (stream, "\tpea (%s)\n\tmove.l %s,%s\n",
355 reg_names[FRAME_POINTER_REGNUM],
356 reg_names[STACK_POINTER_REGNUM],
357 reg_names[FRAME_POINTER_REGNUM]);
358 #else
359 fprintf (stream, "\tpea %s@\n\tmovel %s,%s\n",
360 reg_names[FRAME_POINTER_REGNUM],
361 reg_names[STACK_POINTER_REGNUM],
362 reg_names[FRAME_POINTER_REGNUM]);
363 #endif
365 else if (fsize < 0x8000)
367 #ifdef MOTOROLA
368 asm_fprintf (stream, "\tlink.w %s,%0I%d\n",
369 reg_names[FRAME_POINTER_REGNUM], -fsize);
370 #else
371 asm_fprintf (stream, "\tlink %s,%0I%d\n",
372 reg_names[FRAME_POINTER_REGNUM], -fsize);
373 #endif
375 else if (TARGET_68020)
377 #ifdef MOTOROLA
378 asm_fprintf (stream, "\tlink.l %s,%0I%d\n",
379 reg_names[FRAME_POINTER_REGNUM], -fsize);
380 #else
381 asm_fprintf (stream, "\tlink %s,%0I%d\n",
382 reg_names[FRAME_POINTER_REGNUM], -fsize);
383 #endif
385 else
387 /* Adding negative number is faster on the 68040. */
388 #ifdef MOTOROLA
389 asm_fprintf (stream, "\tlink.w %s,%0I0\n\tadd.l %0I%d,%Rsp\n",
390 reg_names[FRAME_POINTER_REGNUM], -fsize);
391 #else
392 asm_fprintf (stream, "\tlink %s,%0I0\n\taddl %0I%d,%Rsp\n",
393 reg_names[FRAME_POINTER_REGNUM], -fsize);
394 #endif
396 if (dwarf2out_do_frame ())
398 char *l;
399 l = (char *) dwarf2out_cfi_label ();
400 cfa_store_offset += 4;
401 cfa_offset = cfa_store_offset;
402 dwarf2out_reg_save (l, FRAME_POINTER_REGNUM, -cfa_store_offset);
403 dwarf2out_def_cfa (l, FRAME_POINTER_REGNUM, cfa_offset);
404 cfa_store_offset += fsize;
407 else if (fsize)
409 if (fsize + 4 < 0x8000)
411 #ifndef NO_ADDSUB_Q
412 if (fsize + 4 <= 8)
414 if (!TARGET_5200)
416 /* asm_fprintf() cannot handle %. */
417 #ifdef MOTOROLA
418 asm_fprintf (stream, "\tsubq.w %0I%d,%Rsp\n", fsize + 4);
419 #else
420 asm_fprintf (stream, "\tsubqw %0I%d,%Rsp\n", fsize + 4);
421 #endif
423 else
425 /* asm_fprintf() cannot handle %. */
426 #ifdef MOTOROLA
427 asm_fprintf (stream, "\tsubq.l %0I%d,%Rsp\n", fsize + 4);
428 #else
429 asm_fprintf (stream, "\tsubql %0I%d,%Rsp\n", fsize + 4);
430 #endif
433 else if (fsize + 4 <= 16 && TARGET_CPU32)
435 /* On the CPU32 it is faster to use two subqw instructions to
436 subtract a small integer (8 < N <= 16) to a register. */
437 /* asm_fprintf() cannot handle %. */
438 #ifdef MOTOROLA
439 asm_fprintf (stream, "\tsubq.w %0I8,%Rsp\n\tsubq.w %0I%d,%Rsp\n",
440 fsize + 4 - 8);
441 #else
442 asm_fprintf (stream, "\tsubqw %0I8,%Rsp\n\tsubqw %0I%d,%Rsp\n",
443 fsize + 4 - 8);
444 #endif
446 else
447 #endif /* not NO_ADDSUB_Q */
448 if (TARGET_68040)
450 /* Adding negative number is faster on the 68040. */
451 /* asm_fprintf() cannot handle %. */
452 #ifdef MOTOROLA
453 asm_fprintf (stream, "\tadd.w %0I%d,%Rsp\n", - (fsize + 4));
454 #else
455 asm_fprintf (stream, "\taddw %0I%d,%Rsp\n", - (fsize + 4));
456 #endif
458 else
460 #ifdef MOTOROLA
461 asm_fprintf (stream, "\tlea (%d,%Rsp),%Rsp\n", - (fsize + 4));
462 #else
463 asm_fprintf (stream, "\tlea %Rsp@(%d),%Rsp\n", - (fsize + 4));
464 #endif
467 else
469 /* asm_fprintf() cannot handle %. */
470 #ifdef MOTOROLA
471 asm_fprintf (stream, "\tadd.l %0I%d,%Rsp\n", - (fsize + 4));
472 #else
473 asm_fprintf (stream, "\taddl %0I%d,%Rsp\n", - (fsize + 4));
474 #endif
476 if (dwarf2out_do_frame ())
478 cfa_store_offset += fsize;
479 cfa_offset = cfa_store_offset;
480 dwarf2out_def_cfa ("", STACK_POINTER_REGNUM, cfa_offset);
483 #ifdef SUPPORT_SUN_FPA
484 for (regno = 24; regno < 56; regno++)
485 if (m68k_save_reg (regno))
487 #ifdef MOTOROLA
488 asm_fprintf (stream, "\tfpmovd %s,-(%Rsp)\n",
489 reg_names[regno]);
490 #else
491 asm_fprintf (stream, "\tfpmoved %s,%Rsp@-\n",
492 reg_names[regno]);
493 #endif
494 if (dwarf2out_do_frame ())
496 char *l = dwarf2out_cfi_label ();
498 cfa_store_offset += 8;
499 if (! frame_pointer_needed)
501 cfa_offset = cfa_store_offset;
502 dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, cfa_offset);
504 dwarf2out_reg_save (l, regno, -cfa_store_offset);
507 #endif
508 if (TARGET_68881)
510 for (regno = 16; regno < 24; regno++)
511 if (m68k_save_reg (regno))
513 mask |= 1 << (regno - 16);
514 num_saved_regs++;
516 if ((mask & 0xff) != 0)
518 #ifdef MOTOROLA
519 asm_fprintf (stream, "\tfmovm %0I0x%x,-(%Rsp)\n", mask & 0xff);
520 #else
521 asm_fprintf (stream, "\tfmovem %0I0x%x,%Rsp@-\n", mask & 0xff);
522 #endif
523 if (dwarf2out_do_frame ())
525 char *l = (char *) dwarf2out_cfi_label ();
526 int n_regs;
528 cfa_store_offset += num_saved_regs * 12;
529 if (! frame_pointer_needed)
531 cfa_offset = cfa_store_offset;
532 dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, cfa_offset);
534 for (regno = 16, n_regs = 0; regno < 24; regno++)
535 if (mask & (1 << (regno - 16)))
536 dwarf2out_reg_save (l, regno,
537 -cfa_store_offset + n_regs++ * 12);
540 mask = 0;
541 num_saved_regs = 0;
543 for (regno = 0; regno < 16; regno++)
544 if (m68k_save_reg (regno))
546 mask |= 1 << (15 - regno);
547 num_saved_regs++;
550 #if NEED_PROBE
551 #ifdef MOTOROLA
552 asm_fprintf (stream, "\ttst.l %d(%Rsp)\n", NEED_PROBE - num_saved_regs * 4);
553 #else
554 asm_fprintf (stream, "\ttstl %Rsp@(%d)\n", NEED_PROBE - num_saved_regs * 4);
555 #endif
556 #endif
558 /* If the stack limit is not a symbol, check it here.
559 This has the disadvantage that it may be too late... */
560 if (current_function_limit_stack)
562 if (REG_P (stack_limit_rtx))
564 #if defined (MOTOROLA)
565 asm_fprintf (stream, "\tcmp.l %s,%Rsp\n\ttrapcs\n",
566 reg_names[REGNO (stack_limit_rtx)]);
567 #else
568 asm_fprintf (stream, "\tcmpl %s,%Rsp\n\ttrapcs\n",
569 reg_names[REGNO (stack_limit_rtx)]);
570 #endif
572 else if (GET_CODE (stack_limit_rtx) != SYMBOL_REF)
573 warning ("stack limit expression is not supported");
576 if (num_saved_regs <= 2)
578 /* Store each separately in the same order moveml uses.
579 Using two movel instructions instead of a single moveml
580 is about 15% faster for the 68020 and 68030 at no expense
581 in code size */
583 int i;
585 /* Undo the work from above. */
586 for (i = 0; i< 16; i++)
587 if (mask & (1 << i))
589 asm_fprintf (stream,
590 #ifdef MOTOROLA
591 "\t%Omove.l %s,-(%Rsp)\n",
592 #else
593 "\tmovel %s,%Rsp@-\n",
594 #endif
595 reg_names[15 - i]);
596 if (dwarf2out_do_frame ())
598 char *l = (char *) dwarf2out_cfi_label ();
600 cfa_store_offset += 4;
601 if (! frame_pointer_needed)
603 cfa_offset = cfa_store_offset;
604 dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, cfa_offset);
606 dwarf2out_reg_save (l, 15 - i, -cfa_store_offset);
610 else if (mask)
612 if (TARGET_5200)
614 /* The coldfire does not support the predecrement form of the
615 movml instruction, so we must adjust the stack pointer and
616 then use the plain address register indirect mode. We also
617 have to invert the register save mask to use the new mode.
619 FIXME: if num_saved_regs was calculated earlier, we could
620 combine the stack pointer adjustment with any adjustment
621 done when the initial stack frame is created. This would
622 save an instruction */
624 int newmask = 0;
625 int i;
627 for (i = 0; i < 16; i++)
628 if (mask & (1 << i))
629 newmask |= (1 << (15-i));
631 #ifdef MOTOROLA
632 asm_fprintf (stream, "\tlea (%d,%Rsp),%Rsp\n", -num_saved_regs*4);
633 asm_fprintf (stream, "\tmovm.l %0I0x%x,(%Rsp)\n", newmask);
634 #else
635 asm_fprintf (stream, "\tlea %Rsp@(%d),%Rsp\n", -num_saved_regs*4);
636 asm_fprintf (stream, "\tmoveml %0I0x%x,%Rsp@\n", newmask);
637 #endif
639 else
641 #ifdef MOTOROLA
642 asm_fprintf (stream, "\tmovm.l %0I0x%x,-(%Rsp)\n", mask);
643 #else
644 asm_fprintf (stream, "\tmoveml %0I0x%x,%Rsp@-\n", mask);
645 #endif
647 if (dwarf2out_do_frame ())
649 char *l = (char *) dwarf2out_cfi_label ();
650 int n_regs;
652 cfa_store_offset += num_saved_regs * 4;
653 if (! frame_pointer_needed)
655 cfa_offset = cfa_store_offset;
656 dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, cfa_offset);
658 for (regno = 0, n_regs = 0; regno < 16; regno++)
659 if (mask & (1 << (15 - regno)))
660 dwarf2out_reg_save (l, regno,
661 -cfa_store_offset + n_regs++ * 4);
664 if (flag_pic && current_function_uses_pic_offset_table)
666 #ifdef MOTOROLA
667 asm_fprintf (stream, "\t%Olea (%Rpc, %U_GLOBAL_OFFSET_TABLE_@GOTPC), %s\n",
668 reg_names[PIC_OFFSET_TABLE_REGNUM]);
669 #else
670 asm_fprintf (stream, "\tmovel %0I__GLOBAL_OFFSET_TABLE_, %s\n",
671 reg_names[PIC_OFFSET_TABLE_REGNUM]);
672 asm_fprintf (stream, "\tlea %Rpc@(0,%s:l),%s\n",
673 reg_names[PIC_OFFSET_TABLE_REGNUM],
674 reg_names[PIC_OFFSET_TABLE_REGNUM]);
675 #endif
678 #endif /* !CRDS */
680 /* Return true if this function's epilogue can be output as RTL. */
683 use_return_insn ()
685 int regno;
687 if (!reload_completed || frame_pointer_needed || get_frame_size () != 0)
688 return 0;
690 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
691 if (m68k_save_reg (regno))
692 return 0;
694 return 1;
697 /* This function generates the assembly code for function exit,
698 on machines that need it.
700 The function epilogue should not depend on the current stack pointer!
701 It should use the frame pointer only, if there is a frame pointer.
702 This is mandatory because of alloca; we also take advantage of it to
703 omit stack adjustments before returning. */
705 #ifdef CRDS
707 static void
708 m68k_output_function_epilogue (stream, size)
709 FILE *stream;
710 HOST_WIDE_INT size;
712 register int regno;
713 register int mask, fmask;
714 register int nregs;
715 HOST_WIDE_INT offset, foffset, fpoffset;
716 HOST_WIDE_INT fsize = ((size) + 3) & -4;
717 int big = 0;
719 nregs = 0; fmask = 0; fpoffset = 0;
720 for (regno = 16; regno < 24; regno++)
721 if (m68k_save_reg (regno))
723 nregs++;
724 fmask |= 1 << (23 - regno);
727 foffset = fpoffset + nregs * 12;
728 nregs = 0; mask = 0;
730 for (regno = 0; regno < 16; regno++)
731 if (m68k_save_reg (regno))
733 nregs++;
734 mask |= 1 << regno;
737 offset = foffset + nregs * 4;
738 if (offset + fsize >= 0x8000
739 && frame_pointer_needed
740 && (mask || fmask || fpoffset))
742 fprintf (stream, "\tmovel $%d,a0\n", -fsize);
743 fsize = 0, big = 1;
746 if (exact_log2 (mask) >= 0)
748 if (big)
749 fprintf (stream, "\tmovel -%d(a6,a0.l),%s\n",
750 offset + fsize, reg_names[exact_log2 (mask)]);
751 else if (! frame_pointer_needed)
752 fprintf (stream, "\tmovel (sp)+,%s\n",
753 reg_names[exact_log2 (mask)]);
754 else
755 fprintf (stream, "\tmovel -%d(a6),%s\n",
756 offset + fsize, reg_names[exact_log2 (mask)]);
758 else if (mask)
760 if (big)
761 fprintf (stream, "\tmovem -%d(a6,a0.l),$0x%x\n",
762 offset + fsize, mask);
763 else if (! frame_pointer_needed)
764 fprintf (stream, "\tmovem (sp)+,$0x%x\n", mask);
765 else
766 fprintf (stream, "\tmovem -%d(a6),$0x%x\n",
767 offset + fsize, mask);
770 if (fmask)
772 if (big)
773 fprintf (stream, "\tfmovem -%d(a6,a0.l),$0x%x\n",
774 foffset + fsize, fmask);
775 else if (! frame_pointer_needed)
776 fprintf (stream, "\tfmovem (sp)+,$0x%x\n", fmask);
777 else
778 fprintf (stream, "\tfmovem -%d(a6),$0x%x\n",
779 foffset + fsize, fmask);
782 if (fpoffset != 0)
783 for (regno = 55; regno >= 24; regno--)
784 if (m68k_save_reg (regno))
786 if (big)
787 fprintf(stream, "\tfpmoved -%d(a6,a0.l), %s\n",
788 fpoffset + fsize, reg_names[regno]);
789 else if (! frame_pointer_needed)
790 fprintf(stream, "\tfpmoved (sp)+, %s\n",
791 reg_names[regno]);
792 else
793 fprintf(stream, "\tfpmoved -%d(a6), %s\n",
794 fpoffset + fsize, reg_names[regno]);
795 fpoffset -= 8;
798 if (frame_pointer_needed)
799 fprintf (stream, "\tunlk a6\n");
800 else if (fsize)
802 if (fsize + 4 < 0x8000)
803 fprintf (stream, "\tadd.w $%d,sp\n", fsize + 4);
804 else
805 fprintf (stream, "\tadd.l $%d,sp\n", fsize + 4);
808 if (current_function_calls_eh_return)
809 fprintf (stream, "\tadd.l a0,sp\n");
811 if (current_function_pops_args)
812 fprintf (stream, "\trtd $%d\n", current_function_pops_args);
813 else
814 fprintf (stream, "\trts\n");
817 #else /* !CRDS */
819 static void
820 m68k_output_function_epilogue (stream, size)
821 FILE *stream;
822 HOST_WIDE_INT size;
824 register int regno;
825 register int mask, fmask;
826 register int nregs;
827 HOST_WIDE_INT offset, foffset, fpoffset;
828 HOST_WIDE_INT fsize = (size + 3) & -4;
829 int big = 0;
830 rtx insn = get_last_insn ();
831 int restore_from_sp = 0;
833 /* If the last insn was a BARRIER, we don't have to write any code. */
834 if (GET_CODE (insn) == NOTE)
835 insn = prev_nonnote_insn (insn);
836 if (insn && GET_CODE (insn) == BARRIER)
838 /* Output just a no-op so that debuggers don't get confused
839 about which function the pc is in at this address. */
840 fprintf (stream, "\tnop\n");
841 return;
844 #ifdef FUNCTION_EXTRA_EPILOGUE
845 FUNCTION_EXTRA_EPILOGUE (stream, size);
846 #endif
847 nregs = 0; fmask = 0; fpoffset = 0;
848 #ifdef SUPPORT_SUN_FPA
849 for (regno = 24 ; regno < 56 ; regno++)
850 if (m68k_save_reg (regno))
851 nregs++;
852 fpoffset = nregs * 8;
853 #endif
854 nregs = 0;
855 if (TARGET_68881)
857 for (regno = 16; regno < 24; regno++)
858 if (m68k_save_reg (regno))
860 nregs++;
861 fmask |= 1 << (23 - regno);
864 foffset = fpoffset + nregs * 12;
865 nregs = 0; mask = 0;
866 for (regno = 0; regno < 16; regno++)
867 if (m68k_save_reg (regno))
869 nregs++;
870 mask |= 1 << regno;
872 offset = foffset + nregs * 4;
873 /* FIXME : leaf_function_p below is too strong.
874 What we really need to know there is if there could be pending
875 stack adjustment needed at that point. */
876 restore_from_sp = ! frame_pointer_needed
877 || (! current_function_calls_alloca && leaf_function_p ());
878 if (offset + fsize >= 0x8000
879 && ! restore_from_sp
880 && (mask || fmask || fpoffset))
882 #ifdef MOTOROLA
883 asm_fprintf (stream, "\t%Omove.l %0I%d,%Ra1\n", -fsize);
884 #else
885 asm_fprintf (stream, "\tmovel %0I%d,%Ra1\n", -fsize);
886 #endif
887 fsize = 0, big = 1;
889 if (TARGET_5200 || nregs <= 2)
891 /* Restore each separately in the same order moveml does.
892 Using two movel instructions instead of a single moveml
893 is about 15% faster for the 68020 and 68030 at no expense
894 in code size. */
896 int i;
898 /* Undo the work from above. */
899 for (i = 0; i< 16; i++)
900 if (mask & (1 << i))
902 if (big)
904 #ifdef MOTOROLA
905 asm_fprintf (stream, "\t%Omove.l -%d(%s,%Ra1.l),%s\n",
906 offset + fsize,
907 reg_names[FRAME_POINTER_REGNUM],
908 reg_names[i]);
909 #else
910 asm_fprintf (stream, "\tmovel %s@(-%d,%Ra1:l),%s\n",
911 reg_names[FRAME_POINTER_REGNUM],
912 offset + fsize, reg_names[i]);
913 #endif
915 else if (restore_from_sp)
917 #ifdef MOTOROLA
918 asm_fprintf (stream, "\t%Omove.l (%Rsp)+,%s\n",
919 reg_names[i]);
920 #else
921 asm_fprintf (stream, "\tmovel %Rsp@+,%s\n",
922 reg_names[i]);
923 #endif
925 else
927 #ifdef MOTOROLA
928 asm_fprintf (stream, "\t%Omove.l -%d(%s),%s\n",
929 offset + fsize,
930 reg_names[FRAME_POINTER_REGNUM],
931 reg_names[i]);
932 #else
933 fprintf (stream, "\tmovel %s@(-%d),%s\n",
934 reg_names[FRAME_POINTER_REGNUM],
935 offset + fsize, reg_names[i]);
936 #endif
938 offset = offset - 4;
941 else if (mask)
943 if (big)
945 #ifdef MOTOROLA
946 asm_fprintf (stream, "\tmovm.l -%d(%s,%Ra1.l),%0I0x%x\n",
947 offset + fsize,
948 reg_names[FRAME_POINTER_REGNUM],
949 mask);
950 #else
951 asm_fprintf (stream, "\tmoveml %s@(-%d,%Ra1:l),%0I0x%x\n",
952 reg_names[FRAME_POINTER_REGNUM],
953 offset + fsize, mask);
954 #endif
956 else if (restore_from_sp)
958 #ifdef MOTOROLA
959 asm_fprintf (stream, "\tmovm.l (%Rsp)+,%0I0x%x\n", mask);
960 #else
961 asm_fprintf (stream, "\tmoveml %Rsp@+,%0I0x%x\n", mask);
962 #endif
964 else
966 #ifdef MOTOROLA
967 asm_fprintf (stream, "\tmovm.l -%d(%s),%0I0x%x\n",
968 offset + fsize,
969 reg_names[FRAME_POINTER_REGNUM],
970 mask);
971 #else
972 asm_fprintf (stream, "\tmoveml %s@(-%d),%0I0x%x\n",
973 reg_names[FRAME_POINTER_REGNUM],
974 offset + fsize, mask);
975 #endif
978 if (fmask)
980 if (big)
982 #ifdef MOTOROLA
983 asm_fprintf (stream, "\tfmovm -%d(%s,%Ra1.l),%0I0x%x\n",
984 foffset + fsize,
985 reg_names[FRAME_POINTER_REGNUM],
986 fmask);
987 #else
988 asm_fprintf (stream, "\tfmovem %s@(-%d,%Ra1:l),%0I0x%x\n",
989 reg_names[FRAME_POINTER_REGNUM],
990 foffset + fsize, fmask);
991 #endif
993 else if (restore_from_sp)
995 #ifdef MOTOROLA
996 asm_fprintf (stream, "\tfmovm (%Rsp)+,%0I0x%x\n", fmask);
997 #else
998 asm_fprintf (stream, "\tfmovem %Rsp@+,%0I0x%x\n", fmask);
999 #endif
1001 else
1003 #ifdef MOTOROLA
1004 asm_fprintf (stream, "\tfmovm -%d(%s),%0I0x%x\n",
1005 foffset + fsize,
1006 reg_names[FRAME_POINTER_REGNUM],
1007 fmask);
1008 #else
1009 asm_fprintf (stream, "\tfmovem %s@(-%d),%0I0x%x\n",
1010 reg_names[FRAME_POINTER_REGNUM],
1011 foffset + fsize, fmask);
1012 #endif
1015 if (fpoffset != 0)
1016 for (regno = 55; regno >= 24; regno--)
1017 if (m68k_save_reg (regno))
1019 if (big)
1021 #ifdef MOTOROLA
1022 asm_fprintf (stream, "\tfpmovd -%d(%s,%Ra1.l), %s\n",
1023 fpoffset + fsize,
1024 reg_names[FRAME_POINTER_REGNUM],
1025 reg_names[regno]);
1026 #else
1027 asm_fprintf (stream, "\tfpmoved %s@(-%d,%Ra1:l), %s\n",
1028 reg_names[FRAME_POINTER_REGNUM],
1029 fpoffset + fsize, reg_names[regno]);
1030 #endif
1032 else if (restore_from_sp)
1034 #ifdef MOTOROLA
1035 asm_fprintf (stream, "\tfpmovd (%Rsp)+,%s\n",
1036 reg_names[regno]);
1037 #else
1038 asm_fprintf (stream, "\tfpmoved %Rsp@+, %s\n",
1039 reg_names[regno]);
1040 #endif
1042 else
1044 #ifdef MOTOROLA
1045 fprintf (stream, "\tfpmovd -%d(%s), %s\n",
1046 fpoffset + fsize,
1047 reg_names[FRAME_POINTER_REGNUM],
1048 reg_names[regno]);
1049 #else
1050 fprintf (stream, "\tfpmoved %s@(-%d), %s\n",
1051 reg_names[FRAME_POINTER_REGNUM],
1052 fpoffset + fsize, reg_names[regno]);
1053 #endif
1055 fpoffset -= 8;
1057 if (frame_pointer_needed)
1058 fprintf (stream, "\tunlk %s\n",
1059 reg_names[FRAME_POINTER_REGNUM]);
1060 else if (fsize)
1062 #ifndef NO_ADDSUB_Q
1063 if (fsize + 4 <= 8)
1065 if (!TARGET_5200)
1067 #ifdef MOTOROLA
1068 asm_fprintf (stream, "\taddq.w %0I%d,%Rsp\n", fsize + 4);
1069 #else
1070 asm_fprintf (stream, "\taddqw %0I%d,%Rsp\n", fsize + 4);
1071 #endif
1073 else
1075 #ifdef MOTOROLA
1076 asm_fprintf (stream, "\taddq.l %0I%d,%Rsp\n", fsize + 4);
1077 #else
1078 asm_fprintf (stream, "\taddql %0I%d,%Rsp\n", fsize + 4);
1079 #endif
1082 else if (fsize + 4 <= 16 && TARGET_CPU32)
1084 /* On the CPU32 it is faster to use two addqw instructions to
1085 add a small integer (8 < N <= 16) to a register. */
1086 /* asm_fprintf() cannot handle %. */
1087 #ifdef MOTOROLA
1088 asm_fprintf (stream, "\taddq.w %0I8,%Rsp\n\taddq.w %0I%d,%Rsp\n",
1089 fsize + 4 - 8);
1090 #else
1091 asm_fprintf (stream, "\taddqw %0I8,%Rsp\n\taddqw %0I%d,%Rsp\n",
1092 fsize + 4 - 8);
1093 #endif
1095 else
1096 #endif /* not NO_ADDSUB_Q */
1097 if (fsize + 4 < 0x8000)
1099 if (TARGET_68040)
1101 /* asm_fprintf() cannot handle %. */
1102 #ifdef MOTOROLA
1103 asm_fprintf (stream, "\tadd.w %0I%d,%Rsp\n", fsize + 4);
1104 #else
1105 asm_fprintf (stream, "\taddw %0I%d,%Rsp\n", fsize + 4);
1106 #endif
1108 else
1110 #ifdef MOTOROLA
1111 asm_fprintf (stream, "\tlea (%d,%Rsp),%Rsp\n", fsize + 4);
1112 #else
1113 asm_fprintf (stream, "\tlea %Rsp@(%d),%Rsp\n", fsize + 4);
1114 #endif
1117 else
1119 /* asm_fprintf() cannot handle %. */
1120 #ifdef MOTOROLA
1121 asm_fprintf (stream, "\tadd.l %0I%d,%Rsp\n", fsize + 4);
1122 #else
1123 asm_fprintf (stream, "\taddl %0I%d,%Rsp\n", fsize + 4);
1124 #endif
1127 if (current_function_calls_eh_return)
1129 #ifdef MOTOROLA
1130 asm_fprintf (stream, "\tadd.l %Ra0,%Rsp\n");
1131 #else
1132 asm_fprintf (stream, "\taddl %Ra0,%Rsp\n");
1133 #endif
1135 if (current_function_pops_args)
1136 asm_fprintf (stream, "\trtd %0I%d\n", current_function_pops_args);
1137 else
1138 fprintf (stream, "\trts\n");
1140 #endif /* !CRDS */
1142 /* Similar to general_operand, but exclude stack_pointer_rtx. */
1145 not_sp_operand (op, mode)
1146 register rtx op;
1147 enum machine_mode mode;
1149 return op != stack_pointer_rtx && nonimmediate_operand (op, mode);
1152 /* Return TRUE if X is a valid comparison operator for the dbcc
1153 instruction.
1155 Note it rejects floating point comparison operators.
1156 (In the future we could use Fdbcc).
1158 It also rejects some comparisons when CC_NO_OVERFLOW is set. */
1161 valid_dbcc_comparison_p (x, mode)
1162 rtx x;
1163 enum machine_mode mode ATTRIBUTE_UNUSED;
1165 switch (GET_CODE (x))
1167 case EQ: case NE: case GTU: case LTU:
1168 case GEU: case LEU:
1169 return 1;
1171 /* Reject some when CC_NO_OVERFLOW is set. This may be over
1172 conservative */
1173 case GT: case LT: case GE: case LE:
1174 return ! (cc_prev_status.flags & CC_NO_OVERFLOW);
1175 default:
1176 return 0;
1180 /* Return nonzero if flags are currently in the 68881 flag register. */
1182 flags_in_68881 ()
1184 /* We could add support for these in the future */
1185 return cc_status.flags & CC_IN_68881;
1188 /* Output a dbCC; jCC sequence. Note we do not handle the
1189 floating point version of this sequence (Fdbcc). We also
1190 do not handle alternative conditions when CC_NO_OVERFLOW is
1191 set. It is assumed that valid_dbcc_comparison_p and flags_in_68881 will
1192 kick those out before we get here. */
1194 void
1195 output_dbcc_and_branch (operands)
1196 rtx *operands;
1198 switch (GET_CODE (operands[3]))
1200 case EQ:
1201 #ifdef MOTOROLA
1202 output_asm_insn ("dbeq %0,%l1\n\tjbeq %l2", operands);
1203 #else
1204 output_asm_insn ("dbeq %0,%l1\n\tjeq %l2", operands);
1205 #endif
1206 break;
1208 case NE:
1209 #ifdef MOTOROLA
1210 output_asm_insn ("dbne %0,%l1\n\tjbne %l2", operands);
1211 #else
1212 output_asm_insn ("dbne %0,%l1\n\tjne %l2", operands);
1213 #endif
1214 break;
1216 case GT:
1217 #ifdef MOTOROLA
1218 output_asm_insn ("dbgt %0,%l1\n\tjbgt %l2", operands);
1219 #else
1220 output_asm_insn ("dbgt %0,%l1\n\tjgt %l2", operands);
1221 #endif
1222 break;
1224 case GTU:
1225 #ifdef MOTOROLA
1226 output_asm_insn ("dbhi %0,%l1\n\tjbhi %l2", operands);
1227 #else
1228 output_asm_insn ("dbhi %0,%l1\n\tjhi %l2", operands);
1229 #endif
1230 break;
1232 case LT:
1233 #ifdef MOTOROLA
1234 output_asm_insn ("dblt %0,%l1\n\tjblt %l2", operands);
1235 #else
1236 output_asm_insn ("dblt %0,%l1\n\tjlt %l2", operands);
1237 #endif
1238 break;
1240 case LTU:
1241 #ifdef MOTOROLA
1242 output_asm_insn ("dbcs %0,%l1\n\tjbcs %l2", operands);
1243 #else
1244 output_asm_insn ("dbcs %0,%l1\n\tjcs %l2", operands);
1245 #endif
1246 break;
1248 case GE:
1249 #ifdef MOTOROLA
1250 output_asm_insn ("dbge %0,%l1\n\tjbge %l2", operands);
1251 #else
1252 output_asm_insn ("dbge %0,%l1\n\tjge %l2", operands);
1253 #endif
1254 break;
1256 case GEU:
1257 #ifdef MOTOROLA
1258 output_asm_insn ("dbcc %0,%l1\n\tjbcc %l2", operands);
1259 #else
1260 output_asm_insn ("dbcc %0,%l1\n\tjcc %l2", operands);
1261 #endif
1262 break;
1264 case LE:
1265 #ifdef MOTOROLA
1266 output_asm_insn ("dble %0,%l1\n\tjble %l2", operands);
1267 #else
1268 output_asm_insn ("dble %0,%l1\n\tjle %l2", operands);
1269 #endif
1270 break;
1272 case LEU:
1273 #ifdef MOTOROLA
1274 output_asm_insn ("dbls %0,%l1\n\tjbls %l2", operands);
1275 #else
1276 output_asm_insn ("dbls %0,%l1\n\tjls %l2", operands);
1277 #endif
1278 break;
1280 default:
1281 abort ();
1284 /* If the decrement is to be done in SImode, then we have
1285 to compensate for the fact that dbcc decrements in HImode. */
1286 switch (GET_MODE (operands[0]))
1288 case SImode:
1289 #ifdef MOTOROLA
1290 output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjbpl %l1", operands);
1291 #else
1292 output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjpl %l1", operands);
1293 #endif
1294 break;
1296 case HImode:
1297 break;
1299 default:
1300 abort ();
1304 const char *
1305 output_scc_di(op, operand1, operand2, dest)
1306 rtx op;
1307 rtx operand1;
1308 rtx operand2;
1309 rtx dest;
1311 rtx loperands[7];
1312 enum rtx_code op_code = GET_CODE (op);
1314 /* This does not produce a useful cc. */
1315 CC_STATUS_INIT;
1317 /* The m68k cmp.l instruction requires operand1 to be a reg as used
1318 below. Swap the operands and change the op if these requirements
1319 are not fulfilled. */
1320 if (GET_CODE (operand2) == REG && GET_CODE (operand1) != REG)
1322 rtx tmp = operand1;
1324 operand1 = operand2;
1325 operand2 = tmp;
1326 op_code = swap_condition (op_code);
1328 loperands[0] = operand1;
1329 if (GET_CODE (operand1) == REG)
1330 loperands[1] = gen_rtx_REG (SImode, REGNO (operand1) + 1);
1331 else
1332 loperands[1] = adjust_address (operand1, SImode, 4);
1333 if (operand2 != const0_rtx)
1335 loperands[2] = operand2;
1336 if (GET_CODE (operand2) == REG)
1337 loperands[3] = gen_rtx_REG (SImode, REGNO (operand2) + 1);
1338 else
1339 loperands[3] = adjust_address (operand2, SImode, 4);
1341 loperands[4] = gen_label_rtx();
1342 if (operand2 != const0_rtx)
1344 #ifdef MOTOROLA
1345 #ifdef SGS_CMP_ORDER
1346 output_asm_insn ("cmp%.l %0,%2\n\tjbne %l4\n\tcmp%.l %1,%3", loperands);
1347 #else
1348 output_asm_insn ("cmp%.l %2,%0\n\tjbne %l4\n\tcmp%.l %3,%1", loperands);
1349 #endif
1350 #else
1351 #ifdef SGS_CMP_ORDER
1352 output_asm_insn ("cmp%.l %0,%2\n\tjne %l4\n\tcmp%.l %1,%3", loperands);
1353 #else
1354 output_asm_insn ("cmp%.l %2,%0\n\tjne %l4\n\tcmp%.l %3,%1", loperands);
1355 #endif
1356 #endif
1358 else
1360 if (TARGET_68020 || TARGET_5200 || ! ADDRESS_REG_P (loperands[0]))
1361 output_asm_insn ("tst%.l %0", loperands);
1362 else
1364 #ifdef SGS_CMP_ORDER
1365 output_asm_insn ("cmp%.w %0,%#0", loperands);
1366 #else
1367 output_asm_insn ("cmp%.w %#0,%0", loperands);
1368 #endif
1371 #ifdef MOTOROLA
1372 output_asm_insn ("jbne %l4", loperands);
1373 #else
1374 output_asm_insn ("jne %l4", loperands);
1375 #endif
1377 if (TARGET_68020 || TARGET_5200 || ! ADDRESS_REG_P (loperands[1]))
1378 output_asm_insn ("tst%.l %1", loperands);
1379 else
1381 #ifdef SGS_CMP_ORDER
1382 output_asm_insn ("cmp%.w %1,%#0", loperands);
1383 #else
1384 output_asm_insn ("cmp%.w %#0,%1", loperands);
1385 #endif
1389 loperands[5] = dest;
1391 switch (op_code)
1393 case EQ:
1394 (*targetm.asm_out.internal_label) (asm_out_file, "L",
1395 CODE_LABEL_NUMBER (loperands[4]));
1396 output_asm_insn ("seq %5", loperands);
1397 break;
1399 case NE:
1400 (*targetm.asm_out.internal_label) (asm_out_file, "L",
1401 CODE_LABEL_NUMBER (loperands[4]));
1402 output_asm_insn ("sne %5", loperands);
1403 break;
1405 case GT:
1406 loperands[6] = gen_label_rtx();
1407 #ifdef MOTOROLA
1408 output_asm_insn ("shi %5\n\tjbra %l6", loperands);
1409 #else
1410 output_asm_insn ("shi %5\n\tjra %l6", loperands);
1411 #endif
1412 (*targetm.asm_out.internal_label) (asm_out_file, "L",
1413 CODE_LABEL_NUMBER (loperands[4]));
1414 output_asm_insn ("sgt %5", loperands);
1415 (*targetm.asm_out.internal_label) (asm_out_file, "L",
1416 CODE_LABEL_NUMBER (loperands[6]));
1417 break;
1419 case GTU:
1420 (*targetm.asm_out.internal_label) (asm_out_file, "L",
1421 CODE_LABEL_NUMBER (loperands[4]));
1422 output_asm_insn ("shi %5", loperands);
1423 break;
1425 case LT:
1426 loperands[6] = gen_label_rtx();
1427 #ifdef MOTOROLA
1428 output_asm_insn ("scs %5\n\tjbra %l6", loperands);
1429 #else
1430 output_asm_insn ("scs %5\n\tjra %l6", loperands);
1431 #endif
1432 (*targetm.asm_out.internal_label) (asm_out_file, "L",
1433 CODE_LABEL_NUMBER (loperands[4]));
1434 output_asm_insn ("slt %5", loperands);
1435 (*targetm.asm_out.internal_label) (asm_out_file, "L",
1436 CODE_LABEL_NUMBER (loperands[6]));
1437 break;
1439 case LTU:
1440 (*targetm.asm_out.internal_label) (asm_out_file, "L",
1441 CODE_LABEL_NUMBER (loperands[4]));
1442 output_asm_insn ("scs %5", loperands);
1443 break;
1445 case GE:
1446 loperands[6] = gen_label_rtx();
1447 #ifdef MOTOROLA
1448 output_asm_insn ("scc %5\n\tjbra %l6", loperands);
1449 #else
1450 output_asm_insn ("scc %5\n\tjra %l6", loperands);
1451 #endif
1452 (*targetm.asm_out.internal_label) (asm_out_file, "L",
1453 CODE_LABEL_NUMBER (loperands[4]));
1454 output_asm_insn ("sge %5", loperands);
1455 (*targetm.asm_out.internal_label) (asm_out_file, "L",
1456 CODE_LABEL_NUMBER (loperands[6]));
1457 break;
1459 case GEU:
1460 (*targetm.asm_out.internal_label) (asm_out_file, "L",
1461 CODE_LABEL_NUMBER (loperands[4]));
1462 output_asm_insn ("scc %5", loperands);
1463 break;
1465 case LE:
1466 loperands[6] = gen_label_rtx();
1467 #ifdef MOTOROLA
1468 output_asm_insn ("sls %5\n\tjbra %l6", loperands);
1469 #else
1470 output_asm_insn ("sls %5\n\tjra %l6", loperands);
1471 #endif
1472 (*targetm.asm_out.internal_label) (asm_out_file, "L",
1473 CODE_LABEL_NUMBER (loperands[4]));
1474 output_asm_insn ("sle %5", loperands);
1475 (*targetm.asm_out.internal_label) (asm_out_file, "L",
1476 CODE_LABEL_NUMBER (loperands[6]));
1477 break;
1479 case LEU:
1480 (*targetm.asm_out.internal_label) (asm_out_file, "L",
1481 CODE_LABEL_NUMBER (loperands[4]));
1482 output_asm_insn ("sls %5", loperands);
1483 break;
1485 default:
1486 abort ();
1488 return "";
1491 const char *
1492 output_btst (operands, countop, dataop, insn, signpos)
1493 rtx *operands;
1494 rtx countop, dataop;
1495 rtx insn;
1496 int signpos;
1498 operands[0] = countop;
1499 operands[1] = dataop;
1501 if (GET_CODE (countop) == CONST_INT)
1503 register int count = INTVAL (countop);
1504 /* If COUNT is bigger than size of storage unit in use,
1505 advance to the containing unit of same size. */
1506 if (count > signpos)
1508 int offset = (count & ~signpos) / 8;
1509 count = count & signpos;
1510 operands[1] = dataop = adjust_address (dataop, QImode, offset);
1512 if (count == signpos)
1513 cc_status.flags = CC_NOT_POSITIVE | CC_Z_IN_NOT_N;
1514 else
1515 cc_status.flags = CC_NOT_NEGATIVE | CC_Z_IN_NOT_N;
1517 /* These three statements used to use next_insns_test_no...
1518 but it appears that this should do the same job. */
1519 if (count == 31
1520 && next_insn_tests_no_inequality (insn))
1521 return "tst%.l %1";
1522 if (count == 15
1523 && next_insn_tests_no_inequality (insn))
1524 return "tst%.w %1";
1525 if (count == 7
1526 && next_insn_tests_no_inequality (insn))
1527 return "tst%.b %1";
1529 cc_status.flags = CC_NOT_NEGATIVE;
1531 return "btst %0,%1";
1534 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
1535 reference and a constant. */
1538 symbolic_operand (op, mode)
1539 register rtx op;
1540 enum machine_mode mode ATTRIBUTE_UNUSED;
1542 switch (GET_CODE (op))
1544 case SYMBOL_REF:
1545 case LABEL_REF:
1546 return 1;
1548 case CONST:
1549 op = XEXP (op, 0);
1550 return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
1551 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
1552 && GET_CODE (XEXP (op, 1)) == CONST_INT);
1554 #if 0 /* Deleted, with corresponding change in m68k.h,
1555 so as to fit the specs. No CONST_DOUBLE is ever symbolic. */
1556 case CONST_DOUBLE:
1557 return GET_MODE (op) == mode;
1558 #endif
1560 default:
1561 return 0;
1565 /* Check for sign_extend or zero_extend. Used for bit-count operands. */
1568 extend_operator(x, mode)
1569 rtx x;
1570 enum machine_mode mode;
1572 if (mode != VOIDmode && GET_MODE(x) != mode)
1573 return 0;
1574 switch (GET_CODE(x))
1576 case SIGN_EXTEND :
1577 case ZERO_EXTEND :
1578 return 1;
1579 default :
1580 return 0;
1585 /* Legitimize PIC addresses. If the address is already
1586 position-independent, we return ORIG. Newly generated
1587 position-independent addresses go to REG. If we need more
1588 than one register, we lose.
1590 An address is legitimized by making an indirect reference
1591 through the Global Offset Table with the name of the symbol
1592 used as an offset.
1594 The assembler and linker are responsible for placing the
1595 address of the symbol in the GOT. The function prologue
1596 is responsible for initializing a5 to the starting address
1597 of the GOT.
1599 The assembler is also responsible for translating a symbol name
1600 into a constant displacement from the start of the GOT.
1602 A quick example may make things a little clearer:
1604 When not generating PIC code to store the value 12345 into _foo
1605 we would generate the following code:
1607 movel #12345, _foo
1609 When generating PIC two transformations are made. First, the compiler
1610 loads the address of foo into a register. So the first transformation makes:
1612 lea _foo, a0
1613 movel #12345, a0@
1615 The code in movsi will intercept the lea instruction and call this
1616 routine which will transform the instructions into:
1618 movel a5@(_foo:w), a0
1619 movel #12345, a0@
1622 That (in a nutshell) is how *all* symbol and label references are
1623 handled. */
1626 legitimize_pic_address (orig, mode, reg)
1627 rtx orig, reg;
1628 enum machine_mode mode ATTRIBUTE_UNUSED;
1630 rtx pic_ref = orig;
1632 /* First handle a simple SYMBOL_REF or LABEL_REF */
1633 if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF)
1635 if (reg == 0)
1636 abort ();
1638 pic_ref = gen_rtx_MEM (Pmode,
1639 gen_rtx_PLUS (Pmode,
1640 pic_offset_table_rtx, orig));
1641 current_function_uses_pic_offset_table = 1;
1642 RTX_UNCHANGING_P (pic_ref) = 1;
1643 emit_move_insn (reg, pic_ref);
1644 return reg;
1646 else if (GET_CODE (orig) == CONST)
1648 rtx base;
1650 /* Make sure this is CONST has not already been legitimized */
1651 if (GET_CODE (XEXP (orig, 0)) == PLUS
1652 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
1653 return orig;
1655 if (reg == 0)
1656 abort ();
1658 /* legitimize both operands of the PLUS */
1659 if (GET_CODE (XEXP (orig, 0)) == PLUS)
1661 base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
1662 orig = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
1663 base == reg ? 0 : reg);
1665 else abort ();
1667 if (GET_CODE (orig) == CONST_INT)
1668 return plus_constant (base, INTVAL (orig));
1669 pic_ref = gen_rtx_PLUS (Pmode, base, orig);
1670 /* Likewise, should we set special REG_NOTEs here? */
1672 return pic_ref;
1676 typedef enum { MOVL, SWAP, NEGW, NOTW, NOTB, MOVQ } CONST_METHOD;
1678 static CONST_METHOD const_method PARAMS ((rtx));
1680 #define USE_MOVQ(i) ((unsigned)((i) + 128) <= 255)
1682 static CONST_METHOD
1683 const_method (constant)
1684 rtx constant;
1686 int i;
1687 unsigned u;
1689 i = INTVAL (constant);
1690 if (USE_MOVQ (i))
1691 return MOVQ;
1693 /* The Coldfire doesn't have byte or word operations. */
1694 /* FIXME: This may not be useful for the m68060 either */
1695 if (!TARGET_5200)
1697 /* if -256 < N < 256 but N is not in range for a moveq
1698 N^ff will be, so use moveq #N^ff, dreg; not.b dreg. */
1699 if (USE_MOVQ (i ^ 0xff))
1700 return NOTB;
1701 /* Likewise, try with not.w */
1702 if (USE_MOVQ (i ^ 0xffff))
1703 return NOTW;
1704 /* This is the only value where neg.w is useful */
1705 if (i == -65408)
1706 return NEGW;
1707 /* Try also with swap */
1708 u = i;
1709 if (USE_MOVQ ((u >> 16) | (u << 16)))
1710 return SWAP;
1712 /* Otherwise, use move.l */
1713 return MOVL;
1716 static int
1717 const_int_cost (constant)
1718 rtx constant;
1720 switch (const_method (constant))
1722 case MOVQ :
1723 /* Constants between -128 and 127 are cheap due to moveq */
1724 return 0;
1725 case NOTB :
1726 case NOTW :
1727 case NEGW :
1728 case SWAP :
1729 /* Constants easily generated by moveq + not.b/not.w/neg.w/swap */
1730 return 1;
1731 case MOVL :
1732 return 2;
1733 default :
1734 abort ();
1738 static bool
1739 m68k_rtx_costs (x, code, outer_code, total)
1740 rtx x;
1741 int code, outer_code;
1742 int *total;
1744 switch (code)
1746 case CONST_INT:
1747 /* Constant zero is super cheap due to clr instruction. */
1748 if (x == const0_rtx)
1749 *total = 0;
1750 else
1751 *total = const_int_cost (x);
1752 return true;
1754 case CONST:
1755 case LABEL_REF:
1756 case SYMBOL_REF:
1757 *total = 3;
1758 return true;
1760 case CONST_DOUBLE:
1761 /* Make 0.0 cheaper than other floating constants to
1762 encourage creating tstsf and tstdf insns. */
1763 if (outer_code == COMPARE
1764 && (x == CONST0_RTX (SFmode) || x == CONST0_RTX (DFmode)))
1765 *total = 4;
1766 else
1767 *total = 5;
1768 return true;
1770 /* These are vaguely right for a 68020. */
1771 /* The costs for long multiply have been adjusted to work properly
1772 in synth_mult on the 68020, relative to an average of the time
1773 for add and the time for shift, taking away a little more because
1774 sometimes move insns are needed. */
1775 /* div?.w is relatively cheaper on 68000 counted in COSTS_N_INSNS terms. */
1776 #define MULL_COST (TARGET_68060 ? 2 : TARGET_68040 ? 5 : 13)
1777 #define MULW_COST (TARGET_68060 ? 2 : TARGET_68040 ? 3 : TARGET_68020 ? 8 : 5)
1778 #define DIVW_COST (TARGET_68020 ? 27 : 12)
1780 case PLUS:
1781 /* An lea costs about three times as much as a simple add. */
1782 if (GET_MODE (x) == SImode
1783 && GET_CODE (XEXP (x, 1)) == REG
1784 && GET_CODE (XEXP (x, 0)) == MULT
1785 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
1786 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
1787 && (INTVAL (XEXP (XEXP (x, 0), 1)) == 2
1788 || INTVAL (XEXP (XEXP (x, 0), 1)) == 4
1789 || INTVAL (XEXP (XEXP (x, 0), 1)) == 8))
1790 *total = COSTS_N_INSNS (3); /* lea an@(dx:l:i),am */
1791 return false;
1793 case ASHIFT:
1794 case ASHIFTRT:
1795 case LSHIFTRT:
1796 if (TARGET_68060)
1798 *total = COSTS_N_INSNS(1);
1799 return true;
1801 if (! TARGET_68020)
1803 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
1805 if (INTVAL (XEXP (x, 1)) < 16)
1806 *total = COSTS_N_INSNS (2) + INTVAL (XEXP (x, 1)) / 2;
1807 else
1808 /* We're using clrw + swap for these cases. */
1809 *total = COSTS_N_INSNS (4) + (INTVAL (XEXP (x, 1)) - 16) / 2;
1811 else
1812 *total = COSTS_N_INSNS (10); /* worst case */
1813 return true;
1815 /* A shift by a big integer takes an extra instruction. */
1816 if (GET_CODE (XEXP (x, 1)) == CONST_INT
1817 && (INTVAL (XEXP (x, 1)) == 16))
1819 *total = COSTS_N_INSNS (2); /* clrw;swap */
1820 return true;
1822 if (GET_CODE (XEXP (x, 1)) == CONST_INT
1823 && !(INTVAL (XEXP (x, 1)) > 0
1824 && INTVAL (XEXP (x, 1)) <= 8))
1826 *total = COSTS_N_INSNS (3); /* lsr #i,dn */
1827 return true;
1829 return false;
1831 case MULT:
1832 if ((GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
1833 || GET_CODE (XEXP (x, 0)) == SIGN_EXTEND)
1834 && GET_MODE (x) == SImode)
1835 *total = COSTS_N_INSNS (MULW_COST);
1836 else if (GET_MODE (x) == QImode || GET_MODE (x) == HImode)
1837 *total = COSTS_N_INSNS (MULW_COST);
1838 else
1839 *total = COSTS_N_INSNS (MULL_COST);
1840 return true;
1842 case DIV:
1843 case UDIV:
1844 case MOD:
1845 case UMOD:
1846 if (GET_MODE (x) == QImode || GET_MODE (x) == HImode)
1847 *total = COSTS_N_INSNS (DIVW_COST); /* div.w */
1848 else
1849 *total = COSTS_N_INSNS (43); /* div.l */
1850 return true;
1852 default:
1853 return false;
1857 const char *
1858 output_move_const_into_data_reg (operands)
1859 rtx *operands;
1861 int i;
1863 i = INTVAL (operands[1]);
1864 switch (const_method (operands[1]))
1866 case MOVQ :
1867 #if defined (MOTOROLA) && !defined (CRDS)
1868 return "moveq%.l %1,%0";
1869 #else
1870 return "moveq %1,%0";
1871 #endif
1872 case NOTB :
1873 operands[1] = GEN_INT (i ^ 0xff);
1874 #if defined (MOTOROLA) && !defined (CRDS)
1875 return "moveq%.l %1,%0\n\tnot%.b %0";
1876 #else
1877 return "moveq %1,%0\n\tnot%.b %0";
1878 #endif
1879 case NOTW :
1880 operands[1] = GEN_INT (i ^ 0xffff);
1881 #if defined (MOTOROLA) && !defined (CRDS)
1882 return "moveq%.l %1,%0\n\tnot%.w %0";
1883 #else
1884 return "moveq %1,%0\n\tnot%.w %0";
1885 #endif
1886 case NEGW :
1887 #if defined (MOTOROLA) && !defined (CRDS)
1888 return "moveq%.l %#-128,%0\n\tneg%.w %0";
1889 #else
1890 return "moveq %#-128,%0\n\tneg%.w %0";
1891 #endif
1892 case SWAP :
1894 unsigned u = i;
1896 operands[1] = GEN_INT ((u << 16) | (u >> 16));
1897 #if defined (MOTOROLA) && !defined (CRDS)
1898 return "moveq%.l %1,%0\n\tswap %0";
1899 #else
1900 return "moveq %1,%0\n\tswap %0";
1901 #endif
1903 case MOVL :
1904 return "move%.l %1,%0";
1905 default :
1906 abort ();
1910 const char *
1911 output_move_simode_const (operands)
1912 rtx *operands;
1914 if (operands[1] == const0_rtx
1915 && (DATA_REG_P (operands[0])
1916 || GET_CODE (operands[0]) == MEM)
1917 /* clr insns on 68000 read before writing.
1918 This isn't so on the 68010, but we have no TARGET_68010. */
1919 && ((TARGET_68020 || TARGET_5200)
1920 || !(GET_CODE (operands[0]) == MEM
1921 && MEM_VOLATILE_P (operands[0]))))
1922 return "clr%.l %0";
1923 else if (operands[1] == const0_rtx
1924 && ADDRESS_REG_P (operands[0]))
1925 return "sub%.l %0,%0";
1926 else if (DATA_REG_P (operands[0]))
1927 return output_move_const_into_data_reg (operands);
1928 else if (ADDRESS_REG_P (operands[0])
1929 && INTVAL (operands[1]) < 0x8000
1930 && INTVAL (operands[1]) >= -0x8000)
1931 return "move%.w %1,%0";
1932 else if (GET_CODE (operands[0]) == MEM
1933 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
1934 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
1935 && INTVAL (operands[1]) < 0x8000
1936 && INTVAL (operands[1]) >= -0x8000)
1937 return "pea %a1";
1938 return "move%.l %1,%0";
1941 const char *
1942 output_move_simode (operands)
1943 rtx *operands;
1945 if (GET_CODE (operands[1]) == CONST_INT)
1946 return output_move_simode_const (operands);
1947 else if ((GET_CODE (operands[1]) == SYMBOL_REF
1948 || GET_CODE (operands[1]) == CONST)
1949 && push_operand (operands[0], SImode))
1950 return "pea %a1";
1951 else if ((GET_CODE (operands[1]) == SYMBOL_REF
1952 || GET_CODE (operands[1]) == CONST)
1953 && ADDRESS_REG_P (operands[0]))
1954 return "lea %a1,%0";
1955 return "move%.l %1,%0";
1958 const char *
1959 output_move_himode (operands)
1960 rtx *operands;
1962 if (GET_CODE (operands[1]) == CONST_INT)
1964 if (operands[1] == const0_rtx
1965 && (DATA_REG_P (operands[0])
1966 || GET_CODE (operands[0]) == MEM)
1967 /* clr insns on 68000 read before writing.
1968 This isn't so on the 68010, but we have no TARGET_68010. */
1969 && ((TARGET_68020 || TARGET_5200)
1970 || !(GET_CODE (operands[0]) == MEM
1971 && MEM_VOLATILE_P (operands[0]))))
1972 return "clr%.w %0";
1973 else if (operands[1] == const0_rtx
1974 && ADDRESS_REG_P (operands[0]))
1975 return "sub%.l %0,%0";
1976 else if (DATA_REG_P (operands[0])
1977 && INTVAL (operands[1]) < 128
1978 && INTVAL (operands[1]) >= -128)
1980 #if defined(MOTOROLA) && !defined(CRDS)
1981 return "moveq%.l %1,%0";
1982 #else
1983 return "moveq %1,%0";
1984 #endif
1986 else if (INTVAL (operands[1]) < 0x8000
1987 && INTVAL (operands[1]) >= -0x8000)
1988 return "move%.w %1,%0";
1990 else if (CONSTANT_P (operands[1]))
1991 return "move%.l %1,%0";
1992 #ifndef SGS_NO_LI
1993 /* Recognize the insn before a tablejump, one that refers
1994 to a table of offsets. Such an insn will need to refer
1995 to a label on the insn. So output one. Use the label-number
1996 of the table of offsets to generate this label. This code,
1997 and similar code below, assumes that there will be at most one
1998 reference to each table. */
1999 if (GET_CODE (operands[1]) == MEM
2000 && GET_CODE (XEXP (operands[1], 0)) == PLUS
2001 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == LABEL_REF
2002 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) != PLUS)
2004 rtx labelref = XEXP (XEXP (operands[1], 0), 1);
2005 #if defined (MOTOROLA) && !defined (SGS_SWITCH_TABLES)
2006 #ifdef SGS
2007 asm_fprintf (asm_out_file, "\tset %LLI%d,.+2\n",
2008 CODE_LABEL_NUMBER (XEXP (labelref, 0)));
2009 #else /* not SGS */
2010 asm_fprintf (asm_out_file, "\t.set %LLI%d,.+2\n",
2011 CODE_LABEL_NUMBER (XEXP (labelref, 0)));
2012 #endif /* not SGS */
2013 #else /* SGS_SWITCH_TABLES or not MOTOROLA */
2014 (*targetm.asm_out.internal_label) (asm_out_file, "LI",
2015 CODE_LABEL_NUMBER (XEXP (labelref, 0)));
2016 #ifdef SGS_SWITCH_TABLES
2017 /* Set flag saying we need to define the symbol
2018 LD%n (with value L%n-LI%n) at the end of the switch table. */
2019 switch_table_difference_label_flag = 1;
2020 #endif /* SGS_SWITCH_TABLES */
2021 #endif /* SGS_SWITCH_TABLES or not MOTOROLA */
2023 #endif /* SGS_NO_LI */
2024 return "move%.w %1,%0";
2027 const char *
2028 output_move_qimode (operands)
2029 rtx *operands;
2031 rtx xoperands[4];
2033 /* This is probably useless, since it loses for pushing a struct
2034 of several bytes a byte at a time. */
2035 /* 68k family always modifies the stack pointer by at least 2, even for
2036 byte pushes. The 5200 (coldfire) does not do this. */
2037 if (GET_CODE (operands[0]) == MEM
2038 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
2039 && XEXP (XEXP (operands[0], 0), 0) == stack_pointer_rtx
2040 && ! ADDRESS_REG_P (operands[1])
2041 && ! TARGET_5200)
2043 xoperands[1] = operands[1];
2044 xoperands[2]
2045 = gen_rtx_MEM (QImode,
2046 gen_rtx_PLUS (VOIDmode, stack_pointer_rtx, const1_rtx));
2047 /* Just pushing a byte puts it in the high byte of the halfword. */
2048 /* We must put it in the low-order, high-numbered byte. */
2049 if (!reg_mentioned_p (stack_pointer_rtx, operands[1]))
2051 xoperands[3] = stack_pointer_rtx;
2052 #ifndef NO_ADDSUB_Q
2053 output_asm_insn ("subq%.l %#2,%3\n\tmove%.b %1,%2", xoperands);
2054 #else
2055 output_asm_insn ("sub%.l %#2,%3\n\tmove%.b %1,%2", xoperands);
2056 #endif
2058 else
2059 output_asm_insn ("move%.b %1,%-\n\tmove%.b %@,%2", xoperands);
2060 return "";
2063 /* clr and st insns on 68000 read before writing.
2064 This isn't so on the 68010, but we have no TARGET_68010. */
2065 if (!ADDRESS_REG_P (operands[0])
2066 && ((TARGET_68020 || TARGET_5200)
2067 || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
2069 if (operands[1] == const0_rtx)
2070 return "clr%.b %0";
2071 if ((!TARGET_5200 || DATA_REG_P (operands[0]))
2072 && GET_CODE (operands[1]) == CONST_INT
2073 && (INTVAL (operands[1]) & 255) == 255)
2075 CC_STATUS_INIT;
2076 return "st %0";
2079 if (GET_CODE (operands[1]) == CONST_INT
2080 && DATA_REG_P (operands[0])
2081 && INTVAL (operands[1]) < 128
2082 && INTVAL (operands[1]) >= -128)
2084 #if defined(MOTOROLA) && !defined(CRDS)
2085 return "moveq%.l %1,%0";
2086 #else
2087 return "moveq %1,%0";
2088 #endif
2090 if (operands[1] == const0_rtx && ADDRESS_REG_P (operands[0]))
2091 return "sub%.l %0,%0";
2092 if (GET_CODE (operands[1]) != CONST_INT && CONSTANT_P (operands[1]))
2093 return "move%.l %1,%0";
2094 /* 68k family (including the 5200 coldfire) does not support byte moves to
2095 from address registers. */
2096 if (ADDRESS_REG_P (operands[0]) || ADDRESS_REG_P (operands[1]))
2097 return "move%.w %1,%0";
2098 return "move%.b %1,%0";
2101 const char *
2102 output_move_stricthi (operands)
2103 rtx *operands;
2105 if (operands[1] == const0_rtx
2106 /* clr insns on 68000 read before writing.
2107 This isn't so on the 68010, but we have no TARGET_68010. */
2108 && ((TARGET_68020 || TARGET_5200)
2109 || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
2110 return "clr%.w %0";
2111 return "move%.w %1,%0";
2114 const char *
2115 output_move_strictqi (operands)
2116 rtx *operands;
2118 if (operands[1] == const0_rtx
2119 /* clr insns on 68000 read before writing.
2120 This isn't so on the 68010, but we have no TARGET_68010. */
2121 && ((TARGET_68020 || TARGET_5200)
2122 || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
2123 return "clr%.b %0";
2124 return "move%.b %1,%0";
2127 /* Return the best assembler insn template
2128 for moving operands[1] into operands[0] as a fullword. */
2130 static const char *
2131 singlemove_string (operands)
2132 rtx *operands;
2134 #ifdef SUPPORT_SUN_FPA
2135 if (FPA_REG_P (operands[0]) || FPA_REG_P (operands[1]))
2136 return "fpmoves %1,%0";
2137 #endif
2138 if (GET_CODE (operands[1]) == CONST_INT)
2139 return output_move_simode_const (operands);
2140 return "move%.l %1,%0";
2144 /* Output assembler code to perform a doubleword move insn
2145 with operands OPERANDS. */
2147 const char *
2148 output_move_double (operands)
2149 rtx *operands;
2151 enum
2153 REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP
2154 } optype0, optype1;
2155 rtx latehalf[2];
2156 rtx middlehalf[2];
2157 rtx xops[2];
2158 rtx addreg0 = 0, addreg1 = 0;
2159 int dest_overlapped_low = 0;
2160 int size = GET_MODE_SIZE (GET_MODE (operands[0]));
2162 middlehalf[0] = 0;
2163 middlehalf[1] = 0;
2165 /* First classify both operands. */
2167 if (REG_P (operands[0]))
2168 optype0 = REGOP;
2169 else if (offsettable_memref_p (operands[0]))
2170 optype0 = OFFSOP;
2171 else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
2172 optype0 = POPOP;
2173 else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
2174 optype0 = PUSHOP;
2175 else if (GET_CODE (operands[0]) == MEM)
2176 optype0 = MEMOP;
2177 else
2178 optype0 = RNDOP;
2180 if (REG_P (operands[1]))
2181 optype1 = REGOP;
2182 else if (CONSTANT_P (operands[1]))
2183 optype1 = CNSTOP;
2184 else if (offsettable_memref_p (operands[1]))
2185 optype1 = OFFSOP;
2186 else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
2187 optype1 = POPOP;
2188 else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
2189 optype1 = PUSHOP;
2190 else if (GET_CODE (operands[1]) == MEM)
2191 optype1 = MEMOP;
2192 else
2193 optype1 = RNDOP;
2195 /* Check for the cases that the operand constraints are not
2196 supposed to allow to happen. Abort if we get one,
2197 because generating code for these cases is painful. */
2199 if (optype0 == RNDOP || optype1 == RNDOP)
2200 abort ();
2202 /* If one operand is decrementing and one is incrementing
2203 decrement the former register explicitly
2204 and change that operand into ordinary indexing. */
2206 if (optype0 == PUSHOP && optype1 == POPOP)
2208 operands[0] = XEXP (XEXP (operands[0], 0), 0);
2209 if (size == 12)
2210 output_asm_insn ("sub%.l %#12,%0", operands);
2211 else
2212 output_asm_insn ("subq%.l %#8,%0", operands);
2213 if (GET_MODE (operands[1]) == XFmode)
2214 operands[0] = gen_rtx_MEM (XFmode, operands[0]);
2215 else if (GET_MODE (operands[0]) == DFmode)
2216 operands[0] = gen_rtx_MEM (DFmode, operands[0]);
2217 else
2218 operands[0] = gen_rtx_MEM (DImode, operands[0]);
2219 optype0 = OFFSOP;
2221 if (optype0 == POPOP && optype1 == PUSHOP)
2223 operands[1] = XEXP (XEXP (operands[1], 0), 0);
2224 if (size == 12)
2225 output_asm_insn ("sub%.l %#12,%1", operands);
2226 else
2227 output_asm_insn ("subq%.l %#8,%1", operands);
2228 if (GET_MODE (operands[1]) == XFmode)
2229 operands[1] = gen_rtx_MEM (XFmode, operands[1]);
2230 else if (GET_MODE (operands[1]) == DFmode)
2231 operands[1] = gen_rtx_MEM (DFmode, operands[1]);
2232 else
2233 operands[1] = gen_rtx_MEM (DImode, operands[1]);
2234 optype1 = OFFSOP;
2237 /* If an operand is an unoffsettable memory ref, find a register
2238 we can increment temporarily to make it refer to the second word. */
2240 if (optype0 == MEMOP)
2241 addreg0 = find_addr_reg (XEXP (operands[0], 0));
2243 if (optype1 == MEMOP)
2244 addreg1 = find_addr_reg (XEXP (operands[1], 0));
2246 /* Ok, we can do one word at a time.
2247 Normally we do the low-numbered word first,
2248 but if either operand is autodecrementing then we
2249 do the high-numbered word first.
2251 In either case, set up in LATEHALF the operands to use
2252 for the high-numbered word and in some cases alter the
2253 operands in OPERANDS to be suitable for the low-numbered word. */
2255 if (size == 12)
2257 if (optype0 == REGOP)
2259 latehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 2);
2260 middlehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
2262 else if (optype0 == OFFSOP)
2264 middlehalf[0] = adjust_address (operands[0], SImode, 4);
2265 latehalf[0] = adjust_address (operands[0], SImode, size - 4);
2267 else
2269 middlehalf[0] = operands[0];
2270 latehalf[0] = operands[0];
2273 if (optype1 == REGOP)
2275 latehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
2276 middlehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
2278 else if (optype1 == OFFSOP)
2280 middlehalf[1] = adjust_address (operands[1], SImode, 4);
2281 latehalf[1] = adjust_address (operands[1], SImode, size - 4);
2283 else if (optype1 == CNSTOP)
2285 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2287 REAL_VALUE_TYPE r;
2288 long l[3];
2290 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2291 REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l);
2292 operands[1] = GEN_INT (l[0]);
2293 middlehalf[1] = GEN_INT (l[1]);
2294 latehalf[1] = GEN_INT (l[2]);
2296 else if (CONSTANT_P (operands[1]))
2298 /* actually, no non-CONST_DOUBLE constant should ever
2299 appear here. */
2300 abort ();
2301 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
2302 latehalf[1] = constm1_rtx;
2303 else
2304 latehalf[1] = const0_rtx;
2307 else
2309 middlehalf[1] = operands[1];
2310 latehalf[1] = operands[1];
2313 else
2314 /* size is not 12: */
2316 if (optype0 == REGOP)
2317 latehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
2318 else if (optype0 == OFFSOP)
2319 latehalf[0] = adjust_address (operands[0], SImode, size - 4);
2320 else
2321 latehalf[0] = operands[0];
2323 if (optype1 == REGOP)
2324 latehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
2325 else if (optype1 == OFFSOP)
2326 latehalf[1] = adjust_address (operands[1], SImode, size - 4);
2327 else if (optype1 == CNSTOP)
2328 split_double (operands[1], &operands[1], &latehalf[1]);
2329 else
2330 latehalf[1] = operands[1];
2333 /* If insn is effectively movd N(sp),-(sp) then we will do the
2334 high word first. We should use the adjusted operand 1 (which is N+4(sp))
2335 for the low word as well, to compensate for the first decrement of sp. */
2336 if (optype0 == PUSHOP
2337 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
2338 && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
2339 operands[1] = middlehalf[1] = latehalf[1];
2341 /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)),
2342 if the upper part of reg N does not appear in the MEM, arrange to
2343 emit the move late-half first. Otherwise, compute the MEM address
2344 into the upper part of N and use that as a pointer to the memory
2345 operand. */
2346 if (optype0 == REGOP
2347 && (optype1 == OFFSOP || optype1 == MEMOP))
2349 rtx testlow = gen_rtx_REG (SImode, REGNO (operands[0]));
2351 if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0))
2352 && reg_overlap_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
2354 /* If both halves of dest are used in the src memory address,
2355 compute the address into latehalf of dest.
2356 Note that this can't happen if the dest is two data regs. */
2357 compadr:
2358 xops[0] = latehalf[0];
2359 xops[1] = XEXP (operands[1], 0);
2360 output_asm_insn ("lea %a1,%0", xops);
2361 if (GET_MODE (operands[1]) == XFmode )
2363 operands[1] = gen_rtx_MEM (XFmode, latehalf[0]);
2364 middlehalf[1] = adjust_address (operands[1], DImode, size - 8);
2365 latehalf[1] = adjust_address (operands[1], DImode, size - 4);
2367 else
2369 operands[1] = gen_rtx_MEM (DImode, latehalf[0]);
2370 latehalf[1] = adjust_address (operands[1], DImode, size - 4);
2373 else if (size == 12
2374 && reg_overlap_mentioned_p (middlehalf[0],
2375 XEXP (operands[1], 0)))
2377 /* Check for two regs used by both source and dest.
2378 Note that this can't happen if the dest is all data regs.
2379 It can happen if the dest is d6, d7, a0.
2380 But in that case, latehalf is an addr reg, so
2381 the code at compadr does ok. */
2383 if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0))
2384 || reg_overlap_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
2385 goto compadr;
2387 /* JRV says this can't happen: */
2388 if (addreg0 || addreg1)
2389 abort ();
2391 /* Only the middle reg conflicts; simply put it last. */
2392 output_asm_insn (singlemove_string (operands), operands);
2393 output_asm_insn (singlemove_string (latehalf), latehalf);
2394 output_asm_insn (singlemove_string (middlehalf), middlehalf);
2395 return "";
2397 else if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0)))
2398 /* If the low half of dest is mentioned in the source memory
2399 address, the arrange to emit the move late half first. */
2400 dest_overlapped_low = 1;
2403 /* If one or both operands autodecrementing,
2404 do the two words, high-numbered first. */
2406 /* Likewise, the first move would clobber the source of the second one,
2407 do them in the other order. This happens only for registers;
2408 such overlap can't happen in memory unless the user explicitly
2409 sets it up, and that is an undefined circumstance. */
2411 if (optype0 == PUSHOP || optype1 == PUSHOP
2412 || (optype0 == REGOP && optype1 == REGOP
2413 && ((middlehalf[1] && REGNO (operands[0]) == REGNO (middlehalf[1]))
2414 || REGNO (operands[0]) == REGNO (latehalf[1])))
2415 || dest_overlapped_low)
2417 /* Make any unoffsettable addresses point at high-numbered word. */
2418 if (addreg0)
2420 if (size == 12)
2421 output_asm_insn ("addq%.l %#8,%0", &addreg0);
2422 else
2423 output_asm_insn ("addq%.l %#4,%0", &addreg0);
2425 if (addreg1)
2427 if (size == 12)
2428 output_asm_insn ("addq%.l %#8,%0", &addreg1);
2429 else
2430 output_asm_insn ("addq%.l %#4,%0", &addreg1);
2433 /* Do that word. */
2434 output_asm_insn (singlemove_string (latehalf), latehalf);
2436 /* Undo the adds we just did. */
2437 if (addreg0)
2438 output_asm_insn ("subq%.l %#4,%0", &addreg0);
2439 if (addreg1)
2440 output_asm_insn ("subq%.l %#4,%0", &addreg1);
2442 if (size == 12)
2444 output_asm_insn (singlemove_string (middlehalf), middlehalf);
2445 if (addreg0)
2446 output_asm_insn ("subq%.l %#4,%0", &addreg0);
2447 if (addreg1)
2448 output_asm_insn ("subq%.l %#4,%0", &addreg1);
2451 /* Do low-numbered word. */
2452 return singlemove_string (operands);
2455 /* Normal case: do the two words, low-numbered first. */
2457 output_asm_insn (singlemove_string (operands), operands);
2459 /* Do the middle one of the three words for long double */
2460 if (size == 12)
2462 if (addreg0)
2463 output_asm_insn ("addq%.l %#4,%0", &addreg0);
2464 if (addreg1)
2465 output_asm_insn ("addq%.l %#4,%0", &addreg1);
2467 output_asm_insn (singlemove_string (middlehalf), middlehalf);
2470 /* Make any unoffsettable addresses point at high-numbered word. */
2471 if (addreg0)
2472 output_asm_insn ("addq%.l %#4,%0", &addreg0);
2473 if (addreg1)
2474 output_asm_insn ("addq%.l %#4,%0", &addreg1);
2476 /* Do that word. */
2477 output_asm_insn (singlemove_string (latehalf), latehalf);
2479 /* Undo the adds we just did. */
2480 if (addreg0)
2482 if (size == 12)
2483 output_asm_insn ("subq%.l %#8,%0", &addreg0);
2484 else
2485 output_asm_insn ("subq%.l %#4,%0", &addreg0);
2487 if (addreg1)
2489 if (size == 12)
2490 output_asm_insn ("subq%.l %#8,%0", &addreg1);
2491 else
2492 output_asm_insn ("subq%.l %#4,%0", &addreg1);
2495 return "";
2498 /* Return a REG that occurs in ADDR with coefficient 1.
2499 ADDR can be effectively incremented by incrementing REG. */
2501 static rtx
2502 find_addr_reg (addr)
2503 rtx addr;
2505 while (GET_CODE (addr) == PLUS)
2507 if (GET_CODE (XEXP (addr, 0)) == REG)
2508 addr = XEXP (addr, 0);
2509 else if (GET_CODE (XEXP (addr, 1)) == REG)
2510 addr = XEXP (addr, 1);
2511 else if (CONSTANT_P (XEXP (addr, 0)))
2512 addr = XEXP (addr, 1);
2513 else if (CONSTANT_P (XEXP (addr, 1)))
2514 addr = XEXP (addr, 0);
2515 else
2516 abort ();
2518 if (GET_CODE (addr) == REG)
2519 return addr;
2520 abort ();
2523 /* Output assembler code to perform a 32 bit 3 operand add. */
2525 const char *
2526 output_addsi3 (operands)
2527 rtx *operands;
2529 if (! operands_match_p (operands[0], operands[1]))
2531 if (!ADDRESS_REG_P (operands[1]))
2533 rtx tmp = operands[1];
2535 operands[1] = operands[2];
2536 operands[2] = tmp;
2539 /* These insns can result from reloads to access
2540 stack slots over 64k from the frame pointer. */
2541 if (GET_CODE (operands[2]) == CONST_INT
2542 && INTVAL (operands[2]) + 0x8000 >= (unsigned) 0x10000)
2543 return "move%.l %2,%0\n\tadd%.l %1,%0";
2544 #ifdef SGS
2545 if (GET_CODE (operands[2]) == REG)
2546 return "lea 0(%1,%2.l),%0";
2547 else
2548 return "lea %c2(%1),%0";
2549 #else /* not SGS */
2550 #ifdef MOTOROLA
2551 if (GET_CODE (operands[2]) == REG)
2552 return "lea (%1,%2.l),%0";
2553 else
2554 return "lea (%c2,%1),%0";
2555 #else /* not MOTOROLA (MIT syntax) */
2556 if (GET_CODE (operands[2]) == REG)
2557 return "lea %1@(0,%2:l),%0";
2558 else
2559 return "lea %1@(%c2),%0";
2560 #endif /* not MOTOROLA */
2561 #endif /* not SGS */
2563 if (GET_CODE (operands[2]) == CONST_INT)
2565 #ifndef NO_ADDSUB_Q
2566 if (INTVAL (operands[2]) > 0
2567 && INTVAL (operands[2]) <= 8)
2568 return "addq%.l %2,%0";
2569 if (INTVAL (operands[2]) < 0
2570 && INTVAL (operands[2]) >= -8)
2572 operands[2] = GEN_INT (- INTVAL (operands[2]));
2573 return "subq%.l %2,%0";
2575 /* On the CPU32 it is faster to use two addql instructions to
2576 add a small integer (8 < N <= 16) to a register.
2577 Likewise for subql. */
2578 if (TARGET_CPU32 && REG_P (operands[0]))
2580 if (INTVAL (operands[2]) > 8
2581 && INTVAL (operands[2]) <= 16)
2583 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
2584 return "addq%.l %#8,%0\n\taddq%.l %2,%0";
2586 if (INTVAL (operands[2]) < -8
2587 && INTVAL (operands[2]) >= -16)
2589 operands[2] = GEN_INT (- INTVAL (operands[2]) - 8);
2590 return "subq%.l %#8,%0\n\tsubq%.l %2,%0";
2593 #endif
2594 if (ADDRESS_REG_P (operands[0])
2595 && INTVAL (operands[2]) >= -0x8000
2596 && INTVAL (operands[2]) < 0x8000)
2598 if (TARGET_68040)
2599 return "add%.w %2,%0";
2600 else
2601 #ifdef MOTOROLA
2602 return "lea (%c2,%0),%0";
2603 #else
2604 return "lea %0@(%c2),%0";
2605 #endif
2608 return "add%.l %2,%0";
2611 /* Store in cc_status the expressions that the condition codes will
2612 describe after execution of an instruction whose pattern is EXP.
2613 Do not alter them if the instruction would not alter the cc's. */
2615 /* On the 68000, all the insns to store in an address register fail to
2616 set the cc's. However, in some cases these instructions can make it
2617 possibly invalid to use the saved cc's. In those cases we clear out
2618 some or all of the saved cc's so they won't be used. */
2620 void
2621 notice_update_cc (exp, insn)
2622 rtx exp;
2623 rtx insn;
2625 /* If the cc is being set from the fpa and the expression is not an
2626 explicit floating point test instruction (which has code to deal with
2627 this), reinit the CC. */
2628 if (((cc_status.value1 && FPA_REG_P (cc_status.value1))
2629 || (cc_status.value2 && FPA_REG_P (cc_status.value2)))
2630 && !(GET_CODE (exp) == PARALLEL
2631 && GET_CODE (XVECEXP (exp, 0, 0)) == SET
2632 && XEXP (XVECEXP (exp, 0, 0), 0) == cc0_rtx))
2634 CC_STATUS_INIT;
2636 else if (GET_CODE (exp) == SET)
2638 if (GET_CODE (SET_SRC (exp)) == CALL)
2640 CC_STATUS_INIT;
2642 else if (ADDRESS_REG_P (SET_DEST (exp)))
2644 if (cc_status.value1 && modified_in_p (cc_status.value1, insn))
2645 cc_status.value1 = 0;
2646 if (cc_status.value2 && modified_in_p (cc_status.value2, insn))
2647 cc_status.value2 = 0;
2649 else if (!FP_REG_P (SET_DEST (exp))
2650 && SET_DEST (exp) != cc0_rtx
2651 && (FP_REG_P (SET_SRC (exp))
2652 || GET_CODE (SET_SRC (exp)) == FIX
2653 || GET_CODE (SET_SRC (exp)) == FLOAT_TRUNCATE
2654 || GET_CODE (SET_SRC (exp)) == FLOAT_EXTEND))
2656 CC_STATUS_INIT;
2658 /* A pair of move insns doesn't produce a useful overall cc. */
2659 else if (!FP_REG_P (SET_DEST (exp))
2660 && !FP_REG_P (SET_SRC (exp))
2661 && GET_MODE_SIZE (GET_MODE (SET_SRC (exp))) > 4
2662 && (GET_CODE (SET_SRC (exp)) == REG
2663 || GET_CODE (SET_SRC (exp)) == MEM
2664 || GET_CODE (SET_SRC (exp)) == CONST_DOUBLE))
2666 CC_STATUS_INIT;
2668 else if (GET_CODE (SET_SRC (exp)) == CALL)
2670 CC_STATUS_INIT;
2672 else if (XEXP (exp, 0) != pc_rtx)
2674 cc_status.flags = 0;
2675 cc_status.value1 = XEXP (exp, 0);
2676 cc_status.value2 = XEXP (exp, 1);
2679 else if (GET_CODE (exp) == PARALLEL
2680 && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
2682 if (ADDRESS_REG_P (XEXP (XVECEXP (exp, 0, 0), 0)))
2683 CC_STATUS_INIT;
2684 else if (XEXP (XVECEXP (exp, 0, 0), 0) != pc_rtx)
2686 cc_status.flags = 0;
2687 cc_status.value1 = XEXP (XVECEXP (exp, 0, 0), 0);
2688 cc_status.value2 = XEXP (XVECEXP (exp, 0, 0), 1);
2691 else
2692 CC_STATUS_INIT;
2693 if (cc_status.value2 != 0
2694 && ADDRESS_REG_P (cc_status.value2)
2695 && GET_MODE (cc_status.value2) == QImode)
2696 CC_STATUS_INIT;
2697 if (cc_status.value2 != 0
2698 && !(cc_status.value1 && FPA_REG_P (cc_status.value1)))
2699 switch (GET_CODE (cc_status.value2))
2701 case PLUS: case MINUS: case MULT:
2702 case DIV: case UDIV: case MOD: case UMOD: case NEG:
2703 #if 0 /* These instructions always clear the overflow bit */
2704 case ASHIFT: case ASHIFTRT: case LSHIFTRT:
2705 case ROTATE: case ROTATERT:
2706 #endif
2707 if (GET_MODE (cc_status.value2) != VOIDmode)
2708 cc_status.flags |= CC_NO_OVERFLOW;
2709 break;
2710 case ZERO_EXTEND:
2711 /* (SET r1 (ZERO_EXTEND r2)) on this machine
2712 ends with a move insn moving r2 in r2's mode.
2713 Thus, the cc's are set for r2.
2714 This can set N bit spuriously. */
2715 cc_status.flags |= CC_NOT_NEGATIVE;
2717 default:
2718 break;
2720 if (cc_status.value1 && GET_CODE (cc_status.value1) == REG
2721 && cc_status.value2
2722 && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
2723 cc_status.value2 = 0;
2724 if (((cc_status.value1 && FP_REG_P (cc_status.value1))
2725 || (cc_status.value2 && FP_REG_P (cc_status.value2)))
2726 && !((cc_status.value1 && FPA_REG_P (cc_status.value1))
2727 || (cc_status.value2 && FPA_REG_P (cc_status.value2))))
2728 cc_status.flags = CC_IN_68881;
2731 const char *
2732 output_move_const_double (operands)
2733 rtx *operands;
2735 #ifdef SUPPORT_SUN_FPA
2736 if (TARGET_FPA && FPA_REG_P (operands[0]))
2738 int code = standard_sun_fpa_constant_p (operands[1]);
2740 if (code != 0)
2742 static char buf[40];
2744 sprintf (buf, "fpmove%%.d %%%%%d,%%0", code & 0x1ff);
2745 return buf;
2747 return "fpmove%.d %1,%0";
2749 else
2750 #endif
2752 int code = standard_68881_constant_p (operands[1]);
2754 if (code != 0)
2756 static char buf[40];
2758 sprintf (buf, "fmovecr %%#0x%x,%%0", code & 0xff);
2759 return buf;
2761 return "fmove%.d %1,%0";
2765 const char *
2766 output_move_const_single (operands)
2767 rtx *operands;
2769 #ifdef SUPPORT_SUN_FPA
2770 if (TARGET_FPA)
2772 int code = standard_sun_fpa_constant_p (operands[1]);
2774 if (code != 0)
2776 static char buf[40];
2778 sprintf (buf, "fpmove%%.s %%%%%d,%%0", code & 0x1ff);
2779 return buf;
2781 return "fpmove%.s %1,%0";
2783 else
2784 #endif /* defined SUPPORT_SUN_FPA */
2786 int code = standard_68881_constant_p (operands[1]);
2788 if (code != 0)
2790 static char buf[40];
2792 sprintf (buf, "fmovecr %%#0x%x,%%0", code & 0xff);
2793 return buf;
2795 return "fmove%.s %f1,%0";
2799 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
2800 from the "fmovecr" instruction.
2801 The value, anded with 0xff, gives the code to use in fmovecr
2802 to get the desired constant. */
2804 /* This code has been fixed for cross-compilation. */
2806 static int inited_68881_table = 0;
2808 static const char *const strings_68881[7] = {
2809 "0.0",
2810 "1.0",
2811 "10.0",
2812 "100.0",
2813 "10000.0",
2814 "1e8",
2815 "1e16"
2818 static const int codes_68881[7] = {
2819 0x0f,
2820 0x32,
2821 0x33,
2822 0x34,
2823 0x35,
2824 0x36,
2825 0x37
2828 REAL_VALUE_TYPE values_68881[7];
2830 /* Set up values_68881 array by converting the decimal values
2831 strings_68881 to binary. */
2833 void
2834 init_68881_table ()
2836 int i;
2837 REAL_VALUE_TYPE r;
2838 enum machine_mode mode;
2840 mode = SFmode;
2841 for (i = 0; i < 7; i++)
2843 if (i == 6)
2844 mode = DFmode;
2845 r = REAL_VALUE_ATOF (strings_68881[i], mode);
2846 values_68881[i] = r;
2848 inited_68881_table = 1;
2852 standard_68881_constant_p (x)
2853 rtx x;
2855 REAL_VALUE_TYPE r;
2856 int i;
2858 #ifdef NO_ASM_FMOVECR
2859 return 0;
2860 #endif
2862 /* fmovecr must be emulated on the 68040 and 68060, so it shouldn't be
2863 used at all on those chips. */
2864 if (TARGET_68040 || TARGET_68060)
2865 return 0;
2867 if (! inited_68881_table)
2868 init_68881_table ();
2870 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2872 /* Use REAL_VALUES_IDENTICAL instead of REAL_VALUES_EQUAL so that -0.0
2873 is rejected. */
2874 for (i = 0; i < 6; i++)
2876 if (REAL_VALUES_IDENTICAL (r, values_68881[i]))
2877 return (codes_68881[i]);
2880 if (GET_MODE (x) == SFmode)
2881 return 0;
2883 if (REAL_VALUES_EQUAL (r, values_68881[6]))
2884 return (codes_68881[6]);
2886 /* larger powers of ten in the constants ram are not used
2887 because they are not equal to a `double' C constant. */
2888 return 0;
2891 /* If X is a floating-point constant, return the logarithm of X base 2,
2892 or 0 if X is not a power of 2. */
2895 floating_exact_log2 (x)
2896 rtx x;
2898 REAL_VALUE_TYPE r, r1;
2899 int exp;
2901 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2903 if (REAL_VALUES_LESS (r, dconst1))
2904 return 0;
2906 exp = real_exponent (&r);
2907 real_2expN (&r1, exp);
2908 if (REAL_VALUES_EQUAL (r1, r))
2909 return exp;
2911 return 0;
2914 #ifdef SUPPORT_SUN_FPA
2915 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
2916 from the Sun FPA's constant RAM.
2917 The value returned, anded with 0x1ff, gives the code to use in fpmove
2918 to get the desired constant. */
2920 static int inited_FPA_table = 0;
2922 static const char *const strings_FPA[38] = {
2923 /* small rationals */
2924 "0.0",
2925 "1.0",
2926 "0.5",
2927 "-1.0",
2928 "2.0",
2929 "3.0",
2930 "4.0",
2931 "8.0",
2932 "0.25",
2933 "0.125",
2934 "10.0",
2935 "-0.5",
2936 /* Decimal equivalents of double precision values */
2937 "2.718281828459045091", /* D_E */
2938 "6.283185307179586477", /* 2 pi */
2939 "3.141592653589793116", /* D_PI */
2940 "1.570796326794896619", /* pi/2 */
2941 "1.414213562373095145", /* D_SQRT2 */
2942 "0.7071067811865475244", /* 1/sqrt(2) */
2943 "-1.570796326794896619", /* -pi/2 */
2944 "1.442695040888963387", /* D_LOG2ofE */
2945 "3.321928024887362182", /* D_LOG2of10 */
2946 "0.6931471805599452862", /* D_LOGEof2 */
2947 "2.302585092994045901", /* D_LOGEof10 */
2948 "0.3010299956639811980", /* D_LOG10of2 */
2949 "0.4342944819032518167", /* D_LOG10ofE */
2950 /* Decimal equivalents of single precision values */
2951 "2.718281745910644531", /* S_E */
2952 "6.283185307179586477", /* 2 pi */
2953 "3.141592741012573242", /* S_PI */
2954 "1.570796326794896619", /* pi/2 */
2955 "1.414213538169860840", /* S_SQRT2 */
2956 "0.7071067811865475244", /* 1/sqrt(2) */
2957 "-1.570796326794896619", /* -pi/2 */
2958 "1.442695021629333496", /* S_LOG2ofE */
2959 "3.321928024291992188", /* S_LOG2of10 */
2960 "0.6931471824645996094", /* S_LOGEof2 */
2961 "2.302585124969482442", /* S_LOGEof10 */
2962 "0.3010300099849700928", /* S_LOG10of2 */
2963 "0.4342944920063018799", /* S_LOG10ofE */
2967 static const int codes_FPA[38] = {
2968 /* small rationals */
2969 0x200,
2970 0xe,
2971 0xf,
2972 0x10,
2973 0x11,
2974 0xb1,
2975 0x12,
2976 0x13,
2977 0x15,
2978 0x16,
2979 0x17,
2980 0x2e,
2981 /* double precision */
2982 0x8,
2983 0x9,
2984 0xa,
2985 0xb,
2986 0xc,
2987 0xd,
2988 0x27,
2989 0x28,
2990 0x29,
2991 0x2a,
2992 0x2b,
2993 0x2c,
2994 0x2d,
2995 /* single precision */
2996 0x8,
2997 0x9,
2998 0xa,
2999 0xb,
3000 0xc,
3001 0xd,
3002 0x27,
3003 0x28,
3004 0x29,
3005 0x2a,
3006 0x2b,
3007 0x2c,
3008 0x2d
3011 REAL_VALUE_TYPE values_FPA[38];
3013 /* This code has been fixed for cross-compilation. */
3015 static void init_FPA_table PARAMS ((void));
3016 static void
3017 init_FPA_table ()
3019 enum machine_mode mode;
3020 int i;
3021 REAL_VALUE_TYPE r;
3023 mode = DFmode;
3024 for (i = 0; i < 38; i++)
3026 if (i == 25)
3027 mode = SFmode;
3028 r = REAL_VALUE_ATOF (strings_FPA[i], mode);
3029 values_FPA[i] = r;
3031 inited_FPA_table = 1;
3036 standard_sun_fpa_constant_p (x)
3037 rtx x;
3039 REAL_VALUE_TYPE r;
3040 int i;
3042 if (! inited_FPA_table)
3043 init_FPA_table ();
3045 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
3047 for (i=0; i<12; i++)
3049 if (REAL_VALUES_EQUAL (r, values_FPA[i]))
3050 return (codes_FPA[i]);
3053 if (GET_MODE (x) == SFmode)
3055 for (i=25; i<38; i++)
3057 if (REAL_VALUES_EQUAL (r, values_FPA[i]))
3058 return (codes_FPA[i]);
3061 else
3063 for (i=12; i<25; i++)
3065 if (REAL_VALUES_EQUAL (r, values_FPA[i]))
3066 return (codes_FPA[i]);
3069 return 0x0;
3071 #endif /* define SUPPORT_SUN_FPA */
3073 /* A C compound statement to output to stdio stream STREAM the
3074 assembler syntax for an instruction operand X. X is an RTL
3075 expression.
3077 CODE is a value that can be used to specify one of several ways
3078 of printing the operand. It is used when identical operands
3079 must be printed differently depending on the context. CODE
3080 comes from the `%' specification that was used to request
3081 printing of the operand. If the specification was just `%DIGIT'
3082 then CODE is 0; if the specification was `%LTR DIGIT' then CODE
3083 is the ASCII code for LTR.
3085 If X is a register, this macro should print the register's name.
3086 The names can be found in an array `reg_names' whose type is
3087 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
3089 When the machine description has a specification `%PUNCT' (a `%'
3090 followed by a punctuation character), this macro is called with
3091 a null pointer for X and the punctuation character for CODE.
3093 The m68k specific codes are:
3095 '.' for dot needed in Motorola-style opcode names.
3096 '-' for an operand pushing on the stack:
3097 sp@-, -(sp) or -(%sp) depending on the style of syntax.
3098 '+' for an operand pushing on the stack:
3099 sp@+, (sp)+ or (%sp)+ depending on the style of syntax.
3100 '@' for a reference to the top word on the stack:
3101 sp@, (sp) or (%sp) depending on the style of syntax.
3102 '#' for an immediate operand prefix (# in MIT and Motorola syntax
3103 but & in SGS syntax, $ in CRDS/UNOS syntax).
3104 '!' for the cc register (used in an `and to cc' insn).
3105 '$' for the letter `s' in an op code, but only on the 68040.
3106 '&' for the letter `d' in an op code, but only on the 68040.
3107 '/' for register prefix needed by longlong.h.
3109 'b' for byte insn (no effect, on the Sun; this is for the ISI).
3110 'd' to force memory addressing to be absolute, not relative.
3111 'f' for float insn (print a CONST_DOUBLE as a float rather than in hex)
3112 'o' for operands to go directly to output_operand_address (bypassing
3113 print_operand_address--used only for SYMBOL_REFs under TARGET_PCREL)
3114 'w' for FPA insn (print a CONST_DOUBLE as a SunFPA constant rather
3115 than directly). Second part of 'y' below.
3116 'x' for float insn (print a CONST_DOUBLE as a float rather than in hex),
3117 or print pair of registers as rx:ry.
3118 'y' for a FPA insn (print pair of registers as rx:ry). This also outputs
3119 CONST_DOUBLE's as SunFPA constant RAM registers if
3120 possible, so it should not be used except for the SunFPA.
3124 void
3125 print_operand (file, op, letter)
3126 FILE *file; /* file to write to */
3127 rtx op; /* operand to print */
3128 int letter; /* %<letter> or 0 */
3130 #ifdef SUPPORT_SUN_FPA
3131 int i;
3132 #endif
3134 if (letter == '.')
3136 #if defined (MOTOROLA) && !defined (CRDS)
3137 fprintf (file, ".");
3138 #endif
3140 else if (letter == '#')
3142 asm_fprintf (file, "%0I");
3144 else if (letter == '-')
3146 #ifdef MOTOROLA
3147 asm_fprintf (file, "-(%Rsp)");
3148 #else
3149 asm_fprintf (file, "%Rsp@-");
3150 #endif
3152 else if (letter == '+')
3154 #ifdef MOTOROLA
3155 asm_fprintf (file, "(%Rsp)+");
3156 #else
3157 asm_fprintf (file, "%Rsp@+");
3158 #endif
3160 else if (letter == '@')
3162 #ifdef MOTOROLA
3163 asm_fprintf (file, "(%Rsp)");
3164 #else
3165 asm_fprintf (file, "%Rsp@");
3166 #endif
3168 else if (letter == '!')
3170 asm_fprintf (file, "%Rfpcr");
3172 else if (letter == '$')
3174 if (TARGET_68040_ONLY)
3176 fprintf (file, "s");
3179 else if (letter == '&')
3181 if (TARGET_68040_ONLY)
3183 fprintf (file, "d");
3186 else if (letter == '/')
3188 asm_fprintf (file, "%R");
3190 else if (letter == 'o')
3192 /* This is only for direct addresses with TARGET_PCREL */
3193 if (GET_CODE (op) != MEM || GET_CODE (XEXP (op, 0)) != SYMBOL_REF
3194 || !TARGET_PCREL)
3195 abort ();
3196 output_addr_const (file, XEXP (op, 0));
3198 else if (GET_CODE (op) == REG)
3200 #ifdef SUPPORT_SUN_FPA
3201 if (REGNO (op) < 16
3202 && (letter == 'y' || letter == 'x')
3203 && GET_MODE (op) == DFmode)
3205 fprintf (file, "%s:%s", reg_names[REGNO (op)],
3206 reg_names[REGNO (op)+1]);
3208 else
3209 #endif
3211 if (letter == 'R')
3212 /* Print out the second register name of a register pair.
3213 I.e., R (6) => 7. */
3214 fputs (reg_names[REGNO (op) + 1], file);
3215 else
3216 fputs (reg_names[REGNO (op)], file);
3219 else if (GET_CODE (op) == MEM)
3221 output_address (XEXP (op, 0));
3222 if (letter == 'd' && ! TARGET_68020
3223 && CONSTANT_ADDRESS_P (XEXP (op, 0))
3224 && !(GET_CODE (XEXP (op, 0)) == CONST_INT
3225 && INTVAL (XEXP (op, 0)) < 0x8000
3226 && INTVAL (XEXP (op, 0)) >= -0x8000))
3228 #ifdef MOTOROLA
3229 fprintf (file, ".l");
3230 #else
3231 fprintf (file, ":l");
3232 #endif
3235 #ifdef SUPPORT_SUN_FPA
3236 else if ((letter == 'y' || letter == 'w')
3237 && GET_CODE (op) == CONST_DOUBLE
3238 && (i = standard_sun_fpa_constant_p (op)))
3240 fprintf (file, "%%%d", i & 0x1ff);
3242 #endif
3243 else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == SFmode)
3245 REAL_VALUE_TYPE r;
3246 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
3247 ASM_OUTPUT_FLOAT_OPERAND (letter, file, r);
3249 else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == XFmode)
3251 REAL_VALUE_TYPE r;
3252 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
3253 ASM_OUTPUT_LONG_DOUBLE_OPERAND (file, r);
3255 else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == DFmode)
3257 REAL_VALUE_TYPE r;
3258 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
3259 ASM_OUTPUT_DOUBLE_OPERAND (file, r);
3261 else
3263 /* Use `print_operand_address' instead of `output_addr_const'
3264 to ensure that we print relevant PIC stuff. */
3265 asm_fprintf (file, "%0I");
3266 if (TARGET_PCREL
3267 && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST))
3268 print_operand_address (file, op);
3269 else
3270 output_addr_const (file, op);
3275 /* A C compound statement to output to stdio stream STREAM the
3276 assembler syntax for an instruction operand that is a memory
3277 reference whose address is ADDR. ADDR is an RTL expression.
3279 Note that this contains a kludge that knows that the only reason
3280 we have an address (plus (label_ref...) (reg...)) when not generating
3281 PIC code is in the insn before a tablejump, and we know that m68k.md
3282 generates a label LInnn: on such an insn.
3284 It is possible for PIC to generate a (plus (label_ref...) (reg...))
3285 and we handle that just like we would a (plus (symbol_ref...) (reg...)).
3287 Some SGS assemblers have a bug such that "Lnnn-LInnn-2.b(pc,d0.l*2)"
3288 fails to assemble. Luckily "Lnnn(pc,d0.l*2)" produces the results
3289 we want. This difference can be accommodated by using an assembler
3290 define such "LDnnn" to be either "Lnnn-LInnn-2.b", "Lnnn", or any other
3291 string, as necessary. This is accomplished via the ASM_OUTPUT_CASE_END
3292 macro. See m68k/sgs.h for an example; for versions without the bug.
3293 Some assemblers refuse all the above solutions. The workaround is to
3294 emit "K(pc,d0.l*2)" with K being a small constant known to give the
3295 right behavior.
3297 They also do not like things like "pea 1.w", so we simple leave off
3298 the .w on small constants.
3300 This routine is responsible for distinguishing between -fpic and -fPIC
3301 style relocations in an address. When generating -fpic code the
3302 offset is output in word mode (eg movel a5@(_foo:w), a0). When generating
3303 -fPIC code the offset is output in long mode (eg movel a5@(_foo:l), a0) */
3305 #ifndef ASM_OUTPUT_CASE_FETCH
3306 #ifdef MOTOROLA
3307 #ifdef SGS
3308 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
3309 asm_fprintf (file, "%LLD%d(%Rpc,%s.", labelno, regname)
3310 #else
3311 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
3312 asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.", labelno, labelno, regname)
3313 #endif
3314 #else
3315 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
3316 asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:", labelno, labelno, regname)
3317 #endif
3318 #endif /* ASM_OUTPUT_CASE_FETCH */
3320 void
3321 print_operand_address (file, addr)
3322 FILE *file;
3323 rtx addr;
3325 register rtx reg1, reg2, breg, ireg;
3326 rtx offset;
3328 switch (GET_CODE (addr))
3330 case REG:
3331 #ifdef MOTOROLA
3332 fprintf (file, "(%s)", reg_names[REGNO (addr)]);
3333 #else
3334 fprintf (file, "%s@", reg_names[REGNO (addr)]);
3335 #endif
3336 break;
3337 case PRE_DEC:
3338 #ifdef MOTOROLA
3339 fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
3340 #else
3341 fprintf (file, "%s@-", reg_names[REGNO (XEXP (addr, 0))]);
3342 #endif
3343 break;
3344 case POST_INC:
3345 #ifdef MOTOROLA
3346 fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
3347 #else
3348 fprintf (file, "%s@+", reg_names[REGNO (XEXP (addr, 0))]);
3349 #endif
3350 break;
3351 case PLUS:
3352 reg1 = reg2 = ireg = breg = offset = 0;
3353 if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
3355 offset = XEXP (addr, 0);
3356 addr = XEXP (addr, 1);
3358 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
3360 offset = XEXP (addr, 1);
3361 addr = XEXP (addr, 0);
3363 if (GET_CODE (addr) != PLUS)
3367 else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND)
3369 reg1 = XEXP (addr, 0);
3370 addr = XEXP (addr, 1);
3372 else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND)
3374 reg1 = XEXP (addr, 1);
3375 addr = XEXP (addr, 0);
3377 else if (GET_CODE (XEXP (addr, 0)) == MULT)
3379 reg1 = XEXP (addr, 0);
3380 addr = XEXP (addr, 1);
3382 else if (GET_CODE (XEXP (addr, 1)) == MULT)
3384 reg1 = XEXP (addr, 1);
3385 addr = XEXP (addr, 0);
3387 else if (GET_CODE (XEXP (addr, 0)) == REG)
3389 reg1 = XEXP (addr, 0);
3390 addr = XEXP (addr, 1);
3392 else if (GET_CODE (XEXP (addr, 1)) == REG)
3394 reg1 = XEXP (addr, 1);
3395 addr = XEXP (addr, 0);
3397 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT
3398 || GET_CODE (addr) == SIGN_EXTEND)
3400 if (reg1 == 0)
3402 reg1 = addr;
3404 else
3406 reg2 = addr;
3408 addr = 0;
3410 #if 0 /* for OLD_INDEXING */
3411 else if (GET_CODE (addr) == PLUS)
3413 if (GET_CODE (XEXP (addr, 0)) == REG)
3415 reg2 = XEXP (addr, 0);
3416 addr = XEXP (addr, 1);
3418 else if (GET_CODE (XEXP (addr, 1)) == REG)
3420 reg2 = XEXP (addr, 1);
3421 addr = XEXP (addr, 0);
3424 #endif
3425 if (offset != 0)
3427 if (addr != 0)
3429 abort ();
3431 addr = offset;
3433 if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND
3434 || GET_CODE (reg1) == MULT))
3435 || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
3437 breg = reg2;
3438 ireg = reg1;
3440 else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
3442 breg = reg1;
3443 ireg = reg2;
3445 if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF
3446 && ! (flag_pic && ireg == pic_offset_table_rtx))
3448 int scale = 1;
3449 if (GET_CODE (ireg) == MULT)
3451 scale = INTVAL (XEXP (ireg, 1));
3452 ireg = XEXP (ireg, 0);
3454 if (GET_CODE (ireg) == SIGN_EXTEND)
3456 ASM_OUTPUT_CASE_FETCH (file,
3457 CODE_LABEL_NUMBER (XEXP (addr, 0)),
3458 reg_names[REGNO (XEXP (ireg, 0))]);
3459 fprintf (file, "w");
3461 else
3463 ASM_OUTPUT_CASE_FETCH (file,
3464 CODE_LABEL_NUMBER (XEXP (addr, 0)),
3465 reg_names[REGNO (ireg)]);
3466 fprintf (file, "l");
3468 if (scale != 1)
3470 #ifdef MOTOROLA
3471 fprintf (file, "*%d", scale);
3472 #else
3473 fprintf (file, ":%d", scale);
3474 #endif
3476 putc (')', file);
3477 break;
3479 if (breg != 0 && ireg == 0 && GET_CODE (addr) == LABEL_REF
3480 && ! (flag_pic && breg == pic_offset_table_rtx))
3482 ASM_OUTPUT_CASE_FETCH (file,
3483 CODE_LABEL_NUMBER (XEXP (addr, 0)),
3484 reg_names[REGNO (breg)]);
3485 fprintf (file, "l)");
3486 break;
3488 if (ireg != 0 || breg != 0)
3490 int scale = 1;
3491 if (breg == 0)
3493 abort ();
3495 if (! flag_pic && addr && GET_CODE (addr) == LABEL_REF)
3497 abort ();
3499 #ifdef MOTOROLA
3500 if (addr != 0)
3502 output_addr_const (file, addr);
3503 if (flag_pic && (breg == pic_offset_table_rtx))
3505 fprintf (file, "@GOT");
3506 if (flag_pic == 1)
3507 fprintf (file, ".w");
3510 fprintf (file, "(%s", reg_names[REGNO (breg)]);
3511 if (ireg != 0)
3513 putc (',', file);
3515 #else
3516 fprintf (file, "%s@(", reg_names[REGNO (breg)]);
3517 if (addr != 0)
3519 output_addr_const (file, addr);
3520 if ((flag_pic == 1) && (breg == pic_offset_table_rtx))
3521 fprintf (file, ":w");
3522 if ((flag_pic == 2) && (breg == pic_offset_table_rtx))
3523 fprintf (file, ":l");
3525 if (addr != 0 && ireg != 0)
3527 putc (',', file);
3529 #endif
3530 if (ireg != 0 && GET_CODE (ireg) == MULT)
3532 scale = INTVAL (XEXP (ireg, 1));
3533 ireg = XEXP (ireg, 0);
3535 if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND)
3537 #ifdef MOTOROLA
3538 fprintf (file, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]);
3539 #else
3540 fprintf (file, "%s:w", reg_names[REGNO (XEXP (ireg, 0))]);
3541 #endif
3543 else if (ireg != 0)
3545 #ifdef MOTOROLA
3546 fprintf (file, "%s.l", reg_names[REGNO (ireg)]);
3547 #else
3548 fprintf (file, "%s:l", reg_names[REGNO (ireg)]);
3549 #endif
3551 if (scale != 1)
3553 #ifdef MOTOROLA
3554 fprintf (file, "*%d", scale);
3555 #else
3556 fprintf (file, ":%d", scale);
3557 #endif
3559 putc (')', file);
3560 break;
3562 else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF
3563 && ! (flag_pic && reg1 == pic_offset_table_rtx))
3565 ASM_OUTPUT_CASE_FETCH (file,
3566 CODE_LABEL_NUMBER (XEXP (addr, 0)),
3567 reg_names[REGNO (reg1)]);
3568 fprintf (file, "l)");
3569 break;
3571 /* FALL-THROUGH (is this really what we want?) */
3572 default:
3573 if (GET_CODE (addr) == CONST_INT
3574 && INTVAL (addr) < 0x8000
3575 && INTVAL (addr) >= -0x8000)
3577 #ifdef MOTOROLA
3578 #ifdef SGS
3579 /* Many SGS assemblers croak on size specifiers for constants. */
3580 fprintf (file, "%d", (int) INTVAL (addr));
3581 #else
3582 fprintf (file, "%d.w", (int) INTVAL (addr));
3583 #endif
3584 #else
3585 fprintf (file, "%d:w", (int) INTVAL (addr));
3586 #endif
3588 else if (GET_CODE (addr) == CONST_INT)
3590 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (addr));
3592 else if (TARGET_PCREL)
3594 fputc ('(', file);
3595 output_addr_const (file, addr);
3596 if (flag_pic == 1)
3597 asm_fprintf (file, ":w,%Rpc)");
3598 else
3599 asm_fprintf (file, ":l,%Rpc)");
3601 else
3603 /* Special case for SYMBOL_REF if the symbol name ends in
3604 `.<letter>', this can be mistaken as a size suffix. Put
3605 the name in parentheses. */
3606 if (GET_CODE (addr) == SYMBOL_REF
3607 && strlen (XSTR (addr, 0)) > 2
3608 && XSTR (addr, 0)[strlen (XSTR (addr, 0)) - 2] == '.')
3610 putc ('(', file);
3611 output_addr_const (file, addr);
3612 putc (')', file);
3614 else
3615 output_addr_const (file, addr);
3617 break;
3621 /* Check for cases where a clr insns can be omitted from code using
3622 strict_low_part sets. For example, the second clrl here is not needed:
3623 clrl d0; movw a0@+,d0; use d0; clrl d0; movw a0@+; use d0; ...
3625 MODE is the mode of this STRICT_LOW_PART set. FIRST_INSN is the clear
3626 insn we are checking for redundancy. TARGET is the register set by the
3627 clear insn. */
3630 strict_low_part_peephole_ok (mode, first_insn, target)
3631 enum machine_mode mode;
3632 rtx first_insn;
3633 rtx target;
3635 rtx p;
3637 p = prev_nonnote_insn (first_insn);
3639 while (p)
3641 /* If it isn't an insn, then give up. */
3642 if (GET_CODE (p) != INSN)
3643 return 0;
3645 if (reg_set_p (target, p))
3647 rtx set = single_set (p);
3648 rtx dest;
3650 /* If it isn't an easy to recognize insn, then give up. */
3651 if (! set)
3652 return 0;
3654 dest = SET_DEST (set);
3656 /* If this sets the entire target register to zero, then our
3657 first_insn is redundant. */
3658 if (rtx_equal_p (dest, target)
3659 && SET_SRC (set) == const0_rtx)
3660 return 1;
3661 else if (GET_CODE (dest) == STRICT_LOW_PART
3662 && GET_CODE (XEXP (dest, 0)) == REG
3663 && REGNO (XEXP (dest, 0)) == REGNO (target)
3664 && (GET_MODE_SIZE (GET_MODE (XEXP (dest, 0)))
3665 <= GET_MODE_SIZE (mode)))
3666 /* This is a strict low part set which modifies less than
3667 we are using, so it is safe. */
3669 else
3670 return 0;
3673 p = prev_nonnote_insn (p);
3677 return 0;
3680 /* Accept integer operands in the range 0..0xffffffff. We have to check the
3681 range carefully since this predicate is used in DImode contexts. Also, we
3682 need some extra crud to make it work when hosted on 64-bit machines. */
3685 const_uint32_operand (op, mode)
3686 rtx op;
3687 enum machine_mode mode;
3689 /* It doesn't make sense to ask this question with a mode that is
3690 not larger than 32 bits. */
3691 if (GET_MODE_BITSIZE (mode) <= 32)
3692 abort ();
3694 #if HOST_BITS_PER_WIDE_INT > 32
3695 /* All allowed constants will fit a CONST_INT. */
3696 return (GET_CODE (op) == CONST_INT
3697 && (INTVAL (op) >= 0 && INTVAL (op) <= 0xffffffffL));
3698 #else
3699 return (GET_CODE (op) == CONST_INT
3700 || (GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_HIGH (op) == 0));
3701 #endif
3704 /* Accept integer operands in the range -0x80000000..0x7fffffff. We have
3705 to check the range carefully since this predicate is used in DImode
3706 contexts. */
3709 const_sint32_operand (op, mode)
3710 rtx op;
3711 enum machine_mode mode;
3713 /* It doesn't make sense to ask this question with a mode that is
3714 not larger than 32 bits. */
3715 if (GET_MODE_BITSIZE (mode) <= 32)
3716 abort ();
3718 /* All allowed constants will fit a CONST_INT. */
3719 return (GET_CODE (op) == CONST_INT
3720 && (INTVAL (op) >= (-0x7fffffff - 1) && INTVAL (op) <= 0x7fffffff));
3723 /* Operand predicates for implementing asymmetric pc-relative addressing
3724 on m68k. The m68k supports pc-relative addressing (mode 7, register 2)
3725 when used as a source operand, but not as a destintation operand.
3727 We model this by restricting the meaning of the basic predicates
3728 (general_operand, memory_operand, etc) to forbid the use of this
3729 addressing mode, and then define the following predicates that permit
3730 this addressing mode. These predicates can then be used for the
3731 source operands of the appropriate instructions.
3733 n.b. While it is theoretically possible to change all machine patterns
3734 to use this addressing more where permitted by the architecture,
3735 it has only been implemented for "common" cases: SImode, HImode, and
3736 QImode operands, and only for the principle operations that would
3737 require this addressing mode: data movement and simple integer operations.
3739 In parallel with these new predicates, two new constraint letters
3740 were defined: 'S' and 'T'. 'S' is the -mpcrel analog of 'm'.
3741 'T' replaces 's' in the non-pcrel case. It is a no-op in the pcrel case.
3742 In the pcrel case 's' is only valid in combination with 'a' registers.
3743 See addsi3, subsi3, cmpsi, and movsi patterns for a better understanding
3744 of how these constraints are used.
3746 The use of these predicates is strictly optional, though patterns that
3747 don't will cause an extra reload register to be allocated where one
3748 was not necessary:
3750 lea (abc:w,%pc),%a0 ; need to reload address
3751 moveq &1,%d1 ; since write to pc-relative space
3752 movel %d1,%a0@ ; is not allowed
3754 lea (abc:w,%pc),%a1 ; no need to reload address here
3755 movel %a1@,%d0 ; since "movel (abc:w,%pc),%d0" is ok
3757 For more info, consult tiemann@cygnus.com.
3760 All of the ugliness with predicates and constraints is due to the
3761 simple fact that the m68k does not allow a pc-relative addressing
3762 mode as a destination. gcc does not distinguish between source and
3763 destination addresses. Hence, if we claim that pc-relative address
3764 modes are valid, e.g. GO_IF_LEGITIMATE_ADDRESS accepts them, then we
3765 end up with invalid code. To get around this problem, we left
3766 pc-relative modes as invalid addresses, and then added special
3767 predicates and constraints to accept them.
3769 A cleaner way to handle this is to modify gcc to distinguish
3770 between source and destination addresses. We can then say that
3771 pc-relative is a valid source address but not a valid destination
3772 address, and hopefully avoid a lot of the predicate and constraint
3773 hackery. Unfortunately, this would be a pretty big change. It would
3774 be a useful change for a number of ports, but there aren't any current
3775 plans to undertake this.
3777 ***************************************************************************/
3780 /* Special case of a general operand that's used as a source operand.
3781 Use this to permit reads from PC-relative memory when -mpcrel
3782 is specified. */
3785 general_src_operand (op, mode)
3786 rtx op;
3787 enum machine_mode mode;
3789 if (TARGET_PCREL
3790 && GET_CODE (op) == MEM
3791 && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
3792 || GET_CODE (XEXP (op, 0)) == LABEL_REF
3793 || GET_CODE (XEXP (op, 0)) == CONST))
3794 return 1;
3795 return general_operand (op, mode);
3798 /* Special case of a nonimmediate operand that's used as a source.
3799 Use this to permit reads from PC-relative memory when -mpcrel
3800 is specified. */
3803 nonimmediate_src_operand (op, mode)
3804 rtx op;
3805 enum machine_mode mode;
3807 if (TARGET_PCREL && GET_CODE (op) == MEM
3808 && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
3809 || GET_CODE (XEXP (op, 0)) == LABEL_REF
3810 || GET_CODE (XEXP (op, 0)) == CONST))
3811 return 1;
3812 return nonimmediate_operand (op, mode);
3815 /* Special case of a memory operand that's used as a source.
3816 Use this to permit reads from PC-relative memory when -mpcrel
3817 is specified. */
3820 memory_src_operand (op, mode)
3821 rtx op;
3822 enum machine_mode mode;
3824 if (TARGET_PCREL && GET_CODE (op) == MEM
3825 && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
3826 || GET_CODE (XEXP (op, 0)) == LABEL_REF
3827 || GET_CODE (XEXP (op, 0)) == CONST))
3828 return 1;
3829 return memory_operand (op, mode);
3832 /* Predicate that accepts only a pc-relative address. This is needed
3833 because pc-relative addresses don't satisfy the predicate
3834 "general_src_operand". */
3837 pcrel_address (op, mode)
3838 rtx op;
3839 enum machine_mode mode ATTRIBUTE_UNUSED;
3841 return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF
3842 || GET_CODE (op) == CONST);
3845 const char *
3846 output_andsi3 (operands)
3847 rtx *operands;
3849 int logval;
3850 if (GET_CODE (operands[2]) == CONST_INT
3851 && (INTVAL (operands[2]) | 0xffff) == 0xffffffff
3852 && (DATA_REG_P (operands[0])
3853 || offsettable_memref_p (operands[0]))
3854 && !TARGET_5200)
3856 if (GET_CODE (operands[0]) != REG)
3857 operands[0] = adjust_address (operands[0], HImode, 2);
3858 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
3859 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3860 CC_STATUS_INIT;
3861 if (operands[2] == const0_rtx)
3862 return "clr%.w %0";
3863 return "and%.w %2,%0";
3865 if (GET_CODE (operands[2]) == CONST_INT
3866 && (logval = exact_log2 (~ INTVAL (operands[2]))) >= 0
3867 && (DATA_REG_P (operands[0])
3868 || offsettable_memref_p (operands[0])))
3870 if (DATA_REG_P (operands[0]))
3872 operands[1] = GEN_INT (logval);
3874 else
3876 operands[0] = adjust_address (operands[0], SImode, 3 - (logval / 8));
3877 operands[1] = GEN_INT (logval % 8);
3879 /* This does not set condition codes in a standard way. */
3880 CC_STATUS_INIT;
3881 return "bclr %1,%0";
3883 return "and%.l %2,%0";
3886 const char *
3887 output_iorsi3 (operands)
3888 rtx *operands;
3890 register int logval;
3891 if (GET_CODE (operands[2]) == CONST_INT
3892 && INTVAL (operands[2]) >> 16 == 0
3893 && (DATA_REG_P (operands[0])
3894 || offsettable_memref_p (operands[0]))
3895 && !TARGET_5200)
3897 if (GET_CODE (operands[0]) != REG)
3898 operands[0] = adjust_address (operands[0], HImode, 2);
3899 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3900 CC_STATUS_INIT;
3901 if (INTVAL (operands[2]) == 0xffff)
3902 return "mov%.w %2,%0";
3903 return "or%.w %2,%0";
3905 if (GET_CODE (operands[2]) == CONST_INT
3906 && (logval = exact_log2 (INTVAL (operands[2]))) >= 0
3907 && (DATA_REG_P (operands[0])
3908 || offsettable_memref_p (operands[0])))
3910 if (DATA_REG_P (operands[0]))
3911 operands[1] = GEN_INT (logval);
3912 else
3914 operands[0] = adjust_address (operands[0], SImode, 3 - (logval / 8));
3915 operands[1] = GEN_INT (logval % 8);
3917 CC_STATUS_INIT;
3918 return "bset %1,%0";
3920 return "or%.l %2,%0";
3923 const char *
3924 output_xorsi3 (operands)
3925 rtx *operands;
3927 register int logval;
3928 if (GET_CODE (operands[2]) == CONST_INT
3929 && INTVAL (operands[2]) >> 16 == 0
3930 && (offsettable_memref_p (operands[0]) || DATA_REG_P (operands[0]))
3931 && !TARGET_5200)
3933 if (! DATA_REG_P (operands[0]))
3934 operands[0] = adjust_address (operands[0], HImode, 2);
3935 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3936 CC_STATUS_INIT;
3937 if (INTVAL (operands[2]) == 0xffff)
3938 return "not%.w %0";
3939 return "eor%.w %2,%0";
3941 if (GET_CODE (operands[2]) == CONST_INT
3942 && (logval = exact_log2 (INTVAL (operands[2]))) >= 0
3943 && (DATA_REG_P (operands[0])
3944 || offsettable_memref_p (operands[0])))
3946 if (DATA_REG_P (operands[0]))
3947 operands[1] = GEN_INT (logval);
3948 else
3950 operands[0] = adjust_address (operands[0], SImode, 3 - (logval / 8));
3951 operands[1] = GEN_INT (logval % 8);
3953 CC_STATUS_INIT;
3954 return "bchg %1,%0";
3956 return "eor%.l %2,%0";
3959 /* Output assembly to switch to section NAME with attribute FLAGS. */
3961 static void
3962 m68k_coff_asm_named_section (name, flags)
3963 const char *name;
3964 unsigned int flags;
3966 char flagchar;
3968 if (flags & SECTION_WRITE)
3969 flagchar = 'd';
3970 else
3971 flagchar = 'x';
3973 fprintf (asm_out_file, "\t.section\t%s,\"%c\"\n", name, flagchar);
3976 #ifdef CTOR_LIST_BEGIN
3977 static void
3978 m68k_svr3_asm_out_constructor (symbol, priority)
3979 rtx symbol;
3980 int priority ATTRIBUTE_UNUSED;
3982 rtx xop[2];
3984 xop[1] = symbol;
3985 xop[0] = gen_rtx_MEM (SImode, gen_rtx_PRE_DEC (SImode, stack_pointer_rtx));
3987 init_section ();
3988 output_asm_insn (output_move_simode (xop), xop);
3990 #endif
3992 #ifdef HPUX_ASM
3993 static void
3994 m68k_hp320_internal_label (stream, prefix, labelno)
3995 FILE *stream;
3996 const char *prefix;
3997 unsigned long labelno;
3999 if (prefix[0] == 'L' && prefix[1] == 'I')
4000 fprintf(stream, "\tset %s%ld,.+2\n", prefix, labelno);
4001 else
4002 fprintf (stream, "%s%ld:\n", prefix, labelno);
4004 #endif
4006 static void
4007 m68k_output_mi_thunk (file, thunk, delta, vcall_offset, function)
4008 FILE *file;
4009 tree thunk ATTRIBUTE_UNUSED;
4010 HOST_WIDE_INT delta;
4011 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED;
4012 tree function;
4014 rtx xops[1];
4015 const char *fmt;
4017 if (delta > 0 && delta <= 8)
4018 asm_fprintf (file, "\taddq.l %I%d,4(%Rsp)\n", (int) delta);
4019 else if (delta < 0 && delta >= -8)
4020 asm_fprintf (file, "\tsubq.l %I%d,4(%Rsp)\n", (int) -delta);
4021 else
4023 asm_fprintf (file, "\tadd.l %I");
4024 fprintf (file, HOST_WIDE_INT_PRINT_DEC, delta);
4025 asm_fprintf (file, ",4(%Rsp)\n");
4028 xops[0] = DECL_RTL (function);
4030 /* Logic taken from call patterns in m68k.md. */
4031 if (flag_pic)
4033 if (TARGET_PCREL)
4034 fmt = "bra.l %o0";
4035 else
4037 #ifdef MOTOROLA
4038 #ifdef HPUX_ASM
4039 fmt = "bra.l %0";
4040 #else
4041 #ifdef USE_GAS
4042 fmt = "bra.l %0@PLTPC";
4043 #else
4044 fmt = "bra %0@PLTPC";
4045 #endif
4046 #endif
4047 #else
4048 #ifdef USE_GAS
4049 fmt = "bra.l %0";
4050 #else
4051 fmt = "jbra %0,a1";
4052 #endif
4053 #endif
4056 else
4058 #if defined (MOTOROLA) && !defined (USE_GAS)
4059 #ifdef MOTOROLA_BSR
4060 fmt = "bra %0";
4061 #else
4062 fmt = "jmp %0";
4063 #endif
4064 #else
4065 fmt = "jbra %0";
4066 #endif
4069 output_asm_insn (fmt, xops);