1 /* Subroutines for insn-output.c for Motorola 68000 family.
2 Copyright (C) 1987, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
3 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
28 #include "hard-reg-set.h"
30 #include "insn-config.h"
31 #include "conditions.h"
32 #include "insn-flags.h"
34 #include "insn-attr.h"
39 /* Needed for use_return_insn. */
42 #ifdef SUPPORT_SUN_FPA
44 /* Index into this array by (register number >> 3) to find the
45 smallest class which contains that register. */
46 enum reg_class regno_reg_class
[]
47 = { DATA_REGS
, ADDR_REGS
, FP_REGS
,
48 LO_FPA_REGS
, LO_FPA_REGS
, FPA_REGS
, FPA_REGS
};
50 #endif /* defined SUPPORT_SUN_FPA */
52 /* This flag is used to communicate between movhi and ASM_OUTPUT_CASE_END,
53 if SGS_SWITCH_TABLE. */
54 int switch_table_difference_label_flag
;
56 static rtx find_addr_reg
PARAMS ((rtx
));
57 static const char *singlemove_string
PARAMS ((rtx
*));
60 /* Alignment to use for loops and jumps */
61 /* Specify power of two alignment used for loops. */
62 const char *m68k_align_loops_string
;
63 /* Specify power of two alignment used for non-loop jumps. */
64 const char *m68k_align_jumps_string
;
65 /* Specify power of two alignment used for functions. */
66 const char *m68k_align_funcs_string
;
68 /* Specify power of two alignment used for loops. */
70 /* Specify power of two alignment used for non-loop jumps. */
72 /* Specify power of two alignment used for functions. */
75 /* Nonzero if the last compare/test insn had FP operands. The
76 sCC expanders peek at this to determine what to do for the
77 68060, which has no fsCC instructions. */
78 int m68k_last_compare_had_fp_operands
;
80 /* Sometimes certain combinations of command options do not make
81 sense on a particular target machine. You can define a macro
82 `OVERRIDE_OPTIONS' to take account of this. This macro, if
83 defined, is executed once just after all the command options have
86 Don't use this macro to turn on various extra optimizations for
87 `-O'. That is what `OPTIMIZATION_OPTIONS' is for. */
96 /* Validate -malign-loops= value, or provide default */
97 if (m68k_align_loops_string
)
99 m68k_align_loops
= atoi (m68k_align_loops_string
);
100 if (m68k_align_loops
< 1 || m68k_align_loops
> MAX_CODE_ALIGN
)
101 fatal ("-malign-loops=%d is not between 1 and %d",
102 m68k_align_loops
, MAX_CODE_ALIGN
);
105 m68k_align_loops
= def_align
;
107 /* Validate -malign-jumps= value, or provide default */
108 if (m68k_align_jumps_string
)
110 m68k_align_jumps
= atoi (m68k_align_jumps_string
);
111 if (m68k_align_jumps
< 1 || m68k_align_jumps
> MAX_CODE_ALIGN
)
112 fatal ("-malign-jumps=%d is not between 1 and %d",
113 m68k_align_jumps
, MAX_CODE_ALIGN
);
116 m68k_align_jumps
= def_align
;
118 /* Validate -malign-functions= value, or provide default */
119 if (m68k_align_funcs_string
)
121 m68k_align_funcs
= atoi (m68k_align_funcs_string
);
122 if (m68k_align_funcs
< 1 || m68k_align_funcs
> MAX_CODE_ALIGN
)
123 fatal ("-malign-functions=%d is not between 1 and %d",
124 m68k_align_funcs
, MAX_CODE_ALIGN
);
127 m68k_align_funcs
= def_align
;
130 /* This function generates the assembly code for function entry.
131 STREAM is a stdio stream to output the code to.
132 SIZE is an int: how many units of temporary storage to allocate.
133 Refer to the array `regs_ever_live' to determine which registers
134 to save; `regs_ever_live[I]' is nonzero if register number I
135 is ever used in the function. This function is responsible for
136 knowing which registers should not be saved even if used. */
139 /* Note that the order of the bit mask for fmovem is the opposite
140 of the order for movem! */
144 output_function_prologue (stream
, size
)
149 register int mask
= 0;
150 int num_saved_regs
= 0;
151 extern char call_used_regs
[];
152 int fsize
= (size
+ 3) & -4;
153 int cfa_offset
= INCOMING_FRAME_SP_OFFSET
, cfa_store_offset
= cfa_offset
;
155 /* If the stack limit is a symbol, we can check it here,
156 before actually allocating the space. */
157 if (current_function_limit_stack
158 && GET_CODE (stack_limit_rtx
) == SYMBOL_REF
)
160 #if defined (MOTOROLA)
161 asm_fprintf (stream
, "\tcmp.l %0I%s+%d,%Rsp\n\ttrapcs\n",
162 XSTR (stack_limit_rtx
, 0), fsize
+ 4);
164 asm_fprintf (stream
, "\tcmpl %0I%s+%d,%Rsp\n\ttrapcs\n",
165 XSTR (stack_limit_rtx
, 0), fsize
+ 4);
169 if (frame_pointer_needed
)
171 if (fsize
== 0 && TARGET_68040
)
173 /* on the 68040, pea + move is faster than link.w 0 */
175 asm_fprintf (stream
, "\tpea (%s)\n\tmove.l %s,%s\n",
176 reg_names
[FRAME_POINTER_REGNUM
], reg_names
[STACK_POINTER_REGNUM
],
177 reg_names
[FRAME_POINTER_REGNUM
]);
179 asm_fprintf (stream
, "\tpea %s@\n\tmovel %s,%s\n",
180 reg_names
[FRAME_POINTER_REGNUM
], reg_names
[STACK_POINTER_REGNUM
],
181 reg_names
[FRAME_POINTER_REGNUM
]);
184 else if (fsize
< 0x8000)
187 asm_fprintf (stream
, "\tlink.w %s,%0I%d\n",
188 reg_names
[FRAME_POINTER_REGNUM
], -fsize
);
190 asm_fprintf (stream
, "\tlink %s,%0I%d\n",
191 reg_names
[FRAME_POINTER_REGNUM
], -fsize
);
194 else if (TARGET_68020
)
197 asm_fprintf (stream
, "\tlink.l %s,%0I%d\n",
198 reg_names
[FRAME_POINTER_REGNUM
], -fsize
);
200 asm_fprintf (stream
, "\tlink %s,%0I%d\n",
201 reg_names
[FRAME_POINTER_REGNUM
], -fsize
);
206 /* Adding negative number is faster on the 68040. */
208 asm_fprintf (stream
, "\tlink.w %s,%0I0\n\tadd.l %0I%d,%Rsp\n",
209 reg_names
[FRAME_POINTER_REGNUM
], -fsize
);
211 asm_fprintf (stream
, "\tlink %s,%0I0\n\taddl %0I%d,%Rsp\n",
212 reg_names
[FRAME_POINTER_REGNUM
], -fsize
);
215 if (dwarf2out_do_frame ())
218 l
= (char *) dwarf2out_cfi_label ();
219 cfa_store_offset
+= 4;
220 cfa_offset
= cfa_store_offset
;
221 dwarf2out_def_cfa (l
, FRAME_POINTER_REGNUM
, cfa_offset
);
222 dwarf2out_reg_save (l
, FRAME_POINTER_REGNUM
, -cfa_store_offset
);
223 cfa_store_offset
+= fsize
;
228 if (fsize
+ 4 < 0x8000)
235 /* asm_fprintf() cannot handle %. */
237 asm_fprintf (stream
, "\tsubq.w %0I%d,%Rsp\n", fsize
+ 4);
239 asm_fprintf (stream
, "\tsubqw %0I%d,%Rsp\n", fsize
+ 4);
244 /* asm_fprintf() cannot handle %. */
246 asm_fprintf (stream
, "\tsubq.l %0I%d,%Rsp\n", fsize
+ 4);
248 asm_fprintf (stream
, "\tsubql %0I%d,%Rsp\n", fsize
+ 4);
252 else if (fsize
+ 4 <= 16 && TARGET_CPU32
)
254 /* On the CPU32 it is faster to use two subqw instructions to
255 subtract a small integer (8 < N <= 16) to a register. */
256 /* asm_fprintf() cannot handle %. */
258 asm_fprintf (stream
, "\tsubq.w %0I8,%Rsp\n\tsubq.w %0I%d,%Rsp\n",
261 asm_fprintf (stream
, "\tsubqw %0I8,%Rsp\n\tsubqw %0I%d,%Rsp\n",
266 #endif /* not NO_ADDSUB_Q */
269 /* Adding negative number is faster on the 68040. */
270 /* asm_fprintf() cannot handle %. */
272 asm_fprintf (stream
, "\tadd.w %0I%d,%Rsp\n", - (fsize
+ 4));
274 asm_fprintf (stream
, "\taddw %0I%d,%Rsp\n", - (fsize
+ 4));
280 asm_fprintf (stream
, "\tlea (%d,%Rsp),%Rsp\n", - (fsize
+ 4));
282 asm_fprintf (stream
, "\tlea %Rsp@(%d),%Rsp\n", - (fsize
+ 4));
288 /* asm_fprintf() cannot handle %. */
290 asm_fprintf (stream
, "\tadd.l %0I%d,%Rsp\n", - (fsize
+ 4));
292 asm_fprintf (stream
, "\taddl %0I%d,%Rsp\n", - (fsize
+ 4));
295 if (dwarf2out_do_frame ())
297 cfa_store_offset
+= fsize
;
298 cfa_offset
= cfa_store_offset
;
299 dwarf2out_def_cfa ("", STACK_POINTER_REGNUM
, cfa_offset
);
302 #ifdef SUPPORT_SUN_FPA
303 for (regno
= 24; regno
< 56; regno
++)
304 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
307 asm_fprintf (stream
, "\tfpmovd %s,-(%Rsp)\n",
310 asm_fprintf (stream
, "\tfpmoved %s,%Rsp@-\n",
313 if (dwarf2out_do_frame ())
315 char *l
= dwarf2out_cfi_label ();
317 cfa_store_offset
+= 8;
318 if (! frame_pointer_needed
)
320 cfa_offset
= cfa_store_offset
;
321 dwarf2out_def_cfa (l
, STACK_POINTER_REGNUM
, cfa_offset
);
323 dwarf2out_reg_save (l
, regno
, -cfa_store_offset
);
329 for (regno
= 16; regno
< 24; regno
++)
330 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
332 mask
|= 1 << (regno
- 16);
335 if ((mask
& 0xff) != 0)
338 asm_fprintf (stream
, "\tfmovm %0I0x%x,-(%Rsp)\n", mask
& 0xff);
340 asm_fprintf (stream
, "\tfmovem %0I0x%x,%Rsp@-\n", mask
& 0xff);
342 if (dwarf2out_do_frame ())
344 char *l
= (char *) dwarf2out_cfi_label ();
347 cfa_store_offset
+= num_saved_regs
* 12;
348 if (! frame_pointer_needed
)
350 cfa_offset
= cfa_store_offset
;
351 dwarf2out_def_cfa (l
, STACK_POINTER_REGNUM
, cfa_offset
);
353 for (regno
= 16, n_regs
= 0; regno
< 24; regno
++)
354 if (mask
& (1 << (regno
- 16)))
355 dwarf2out_reg_save (l
, regno
,
356 -cfa_store_offset
+ n_regs
++ * 12);
362 for (regno
= 0; regno
< 16; regno
++)
363 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
365 mask
|= 1 << (15 - regno
);
368 if (frame_pointer_needed
)
370 mask
&= ~ (1 << (15 - FRAME_POINTER_REGNUM
));
373 if (flag_pic
&& current_function_uses_pic_offset_table
)
375 mask
|= 1 << (15 - PIC_OFFSET_TABLE_REGNUM
);
382 asm_fprintf (stream
, "\ttstl %d(%Rsp)\n", NEED_PROBE
- num_saved_regs
* 4);
384 asm_fprintf (stream
, "\ttst.l %d(%Rsp)\n", NEED_PROBE
- num_saved_regs
* 4);
387 asm_fprintf (stream
, "\ttstl %Rsp@(%d)\n", NEED_PROBE
- num_saved_regs
* 4);
391 /* If the stack limit is not a symbol, check it here.
392 This has the disadvantage that it may be too late... */
393 if (current_function_limit_stack
)
395 if (REG_P (stack_limit_rtx
))
397 #if defined (MOTOROLA)
398 asm_fprintf (stream
, "\tcmp.l %s,%Rsp\n\ttrapcs\n",
399 reg_names
[REGNO (stack_limit_rtx
)]);
401 asm_fprintf (stream
, "\tcmpl %s,%Rsp\n\ttrapcs\n",
402 reg_names
[REGNO (stack_limit_rtx
)]);
405 else if (GET_CODE (stack_limit_rtx
) != SYMBOL_REF
)
406 warning ("stack limit expression is not supported");
409 if (num_saved_regs
<= 2)
411 /* Store each separately in the same order moveml uses.
412 Using two movel instructions instead of a single moveml
413 is about 15% faster for the 68020 and 68030 at no expense
418 /* Undo the work from above. */
419 for (i
= 0; i
< 16; i
++)
424 "\t%Omove.l %s,-(%Rsp)\n",
426 "\tmovel %s,%Rsp@-\n",
429 if (dwarf2out_do_frame ())
431 char *l
= (char *) dwarf2out_cfi_label ();
433 cfa_store_offset
+= 4;
434 if (! frame_pointer_needed
)
436 cfa_offset
= cfa_store_offset
;
437 dwarf2out_def_cfa (l
, STACK_POINTER_REGNUM
, cfa_offset
);
439 dwarf2out_reg_save (l
, 15 - i
, -cfa_store_offset
);
447 /* The coldfire does not support the predecrement form of the
448 movml instruction, so we must adjust the stack pointer and
449 then use the plain address register indirect mode. We also
450 have to invert the register save mask to use the new mode.
452 FIXME: if num_saved_regs was calculated earlier, we could
453 combine the stack pointer adjustment with any adjustment
454 done when the initial stack frame is created. This would
455 save an instruction */
460 for (i
= 0; i
< 16; i
++)
462 newmask
|= (1 << (15-i
));
465 asm_fprintf (stream
, "\tlea (%d,%Rsp),%Rsp\n", -num_saved_regs
*4);
466 asm_fprintf (stream
, "\tmovm.l %0I0x%x,(%Rsp)\n", newmask
);
468 asm_fprintf (stream
, "\tlea %Rsp@(%d),%Rsp\n", -num_saved_regs
*4);
469 asm_fprintf (stream
, "\tmoveml %0I0x%x,%Rsp@\n", newmask
);
475 asm_fprintf (stream
, "\tmovm.l %0I0x%x,-(%Rsp)\n", mask
);
477 asm_fprintf (stream
, "\tmoveml %0I0x%x,%Rsp@-\n", mask
);
480 if (dwarf2out_do_frame ())
482 char *l
= (char *) dwarf2out_cfi_label ();
485 cfa_store_offset
+= num_saved_regs
* 4;
486 if (! frame_pointer_needed
)
488 cfa_offset
= cfa_store_offset
;
489 dwarf2out_def_cfa (l
, STACK_POINTER_REGNUM
, cfa_offset
);
491 for (regno
= 0, n_regs
= 0; regno
< 16; regno
++)
492 if (mask
& (1 << (15 - regno
)))
493 dwarf2out_reg_save (l
, regno
,
494 -cfa_store_offset
+ n_regs
++ * 4);
497 if (flag_pic
&& current_function_uses_pic_offset_table
)
500 asm_fprintf (stream
, "\t%Olea (%Rpc, %U_GLOBAL_OFFSET_TABLE_@GOTPC), %s\n",
501 reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
503 asm_fprintf (stream
, "\tmovel %0I__GLOBAL_OFFSET_TABLE_, %s\n",
504 reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
505 asm_fprintf (stream
, "\tlea %Rpc@(0,%s:l),%s\n",
506 reg_names
[PIC_OFFSET_TABLE_REGNUM
],
507 reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
512 /* Return true if this function's epilogue can be output as RTL. */
519 if (!reload_completed
|| frame_pointer_needed
|| get_frame_size () != 0)
522 /* Copied from output_function_epilogue (). We should probably create a
523 separate layout routine to perform the common work. */
525 for (regno
= 0 ; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
526 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
529 if (flag_pic
&& current_function_uses_pic_offset_table
)
535 /* This function generates the assembly code for function exit,
536 on machines that need it. Args are same as for FUNCTION_PROLOGUE.
538 The function epilogue should not depend on the current stack pointer!
539 It should use the frame pointer only, if there is a frame pointer.
540 This is mandatory because of alloca; we also take advantage of it to
541 omit stack adjustments before returning. */
544 output_function_epilogue (stream
, size
)
549 register int mask
, fmask
;
551 int offset
, foffset
, fpoffset
;
552 extern char call_used_regs
[];
553 int fsize
= (size
+ 3) & -4;
555 rtx insn
= get_last_insn ();
556 int restore_from_sp
= 0;
558 /* If the last insn was a BARRIER, we don't have to write any code. */
559 if (GET_CODE (insn
) == NOTE
)
560 insn
= prev_nonnote_insn (insn
);
561 if (insn
&& GET_CODE (insn
) == BARRIER
)
563 /* Output just a no-op so that debuggers don't get confused
564 about which function the pc is in at this address. */
565 asm_fprintf (stream
, "\tnop\n");
569 #ifdef FUNCTION_BLOCK_PROFILER_EXIT
570 if (profile_block_flag
== 2)
572 FUNCTION_BLOCK_PROFILER_EXIT (stream
);
576 #ifdef FUNCTION_EXTRA_EPILOGUE
577 FUNCTION_EXTRA_EPILOGUE (stream
, size
);
579 nregs
= 0; fmask
= 0; fpoffset
= 0;
580 #ifdef SUPPORT_SUN_FPA
581 for (regno
= 24 ; regno
< 56 ; regno
++)
582 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
584 fpoffset
= nregs
* 8;
589 for (regno
= 16; regno
< 24; regno
++)
590 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
593 fmask
|= 1 << (23 - regno
);
596 foffset
= fpoffset
+ nregs
* 12;
598 if (frame_pointer_needed
)
599 regs_ever_live
[FRAME_POINTER_REGNUM
] = 0;
600 for (regno
= 0; regno
< 16; regno
++)
601 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
606 if (flag_pic
&& current_function_uses_pic_offset_table
)
609 mask
|= 1 << PIC_OFFSET_TABLE_REGNUM
;
611 offset
= foffset
+ nregs
* 4;
612 /* FIXME : leaf_function_p below is too strong.
613 What we really need to know there is if there could be pending
614 stack adjustment needed at that point. */
615 restore_from_sp
= ! frame_pointer_needed
616 || (! current_function_calls_alloca
&& leaf_function_p ());
617 if (offset
+ fsize
>= 0x8000
619 && (mask
|| fmask
|| fpoffset
))
622 asm_fprintf (stream
, "\t%Omove.l %0I%d,%Ra1\n", -fsize
);
624 asm_fprintf (stream
, "\tmovel %0I%d,%Ra1\n", -fsize
);
628 if (TARGET_5200
|| nregs
<= 2)
630 /* Restore each separately in the same order moveml does.
631 Using two movel instructions instead of a single moveml
632 is about 15% faster for the 68020 and 68030 at no expense
637 /* Undo the work from above. */
638 for (i
= 0; i
< 16; i
++)
644 asm_fprintf (stream
, "\t%Omove.l -%d(%s,%Ra1.l),%s\n",
646 reg_names
[FRAME_POINTER_REGNUM
],
649 asm_fprintf (stream
, "\tmovel %s@(-%d,%Ra1:l),%s\n",
650 reg_names
[FRAME_POINTER_REGNUM
],
651 offset
+ fsize
, reg_names
[i
]);
654 else if (restore_from_sp
)
657 asm_fprintf (stream
, "\t%Omove.l (%Rsp)+,%s\n",
660 asm_fprintf (stream
, "\tmovel %Rsp@+,%s\n",
667 asm_fprintf (stream
, "\t%Omove.l -%d(%s),%s\n",
669 reg_names
[FRAME_POINTER_REGNUM
],
672 asm_fprintf (stream
, "\tmovel %s@(-%d),%s\n",
673 reg_names
[FRAME_POINTER_REGNUM
],
674 offset
+ fsize
, reg_names
[i
]);
685 asm_fprintf (stream
, "\tmovm.l -%d(%s,%Ra1.l),%0I0x%x\n",
687 reg_names
[FRAME_POINTER_REGNUM
],
690 asm_fprintf (stream
, "\tmoveml %s@(-%d,%Ra1:l),%0I0x%x\n",
691 reg_names
[FRAME_POINTER_REGNUM
],
692 offset
+ fsize
, mask
);
695 else if (restore_from_sp
)
698 asm_fprintf (stream
, "\tmovm.l (%Rsp)+,%0I0x%x\n", mask
);
700 asm_fprintf (stream
, "\tmoveml %Rsp@+,%0I0x%x\n", mask
);
706 asm_fprintf (stream
, "\tmovm.l -%d(%s),%0I0x%x\n",
708 reg_names
[FRAME_POINTER_REGNUM
],
711 asm_fprintf (stream
, "\tmoveml %s@(-%d),%0I0x%x\n",
712 reg_names
[FRAME_POINTER_REGNUM
],
713 offset
+ fsize
, mask
);
722 asm_fprintf (stream
, "\tfmovm -%d(%s,%Ra1.l),%0I0x%x\n",
724 reg_names
[FRAME_POINTER_REGNUM
],
727 asm_fprintf (stream
, "\tfmovem %s@(-%d,%Ra1:l),%0I0x%x\n",
728 reg_names
[FRAME_POINTER_REGNUM
],
729 foffset
+ fsize
, fmask
);
732 else if (restore_from_sp
)
735 asm_fprintf (stream
, "\tfmovm (%Rsp)+,%0I0x%x\n", fmask
);
737 asm_fprintf (stream
, "\tfmovem %Rsp@+,%0I0x%x\n", fmask
);
743 asm_fprintf (stream
, "\tfmovm -%d(%s),%0I0x%x\n",
745 reg_names
[FRAME_POINTER_REGNUM
],
748 asm_fprintf (stream
, "\tfmovem %s@(-%d),%0I0x%x\n",
749 reg_names
[FRAME_POINTER_REGNUM
],
750 foffset
+ fsize
, fmask
);
755 for (regno
= 55; regno
>= 24; regno
--)
756 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
761 asm_fprintf (stream
, "\tfpmovd -%d(%s,%Ra1.l), %s\n",
763 reg_names
[FRAME_POINTER_REGNUM
],
766 asm_fprintf (stream
, "\tfpmoved %s@(-%d,%Ra1:l), %s\n",
767 reg_names
[FRAME_POINTER_REGNUM
],
768 fpoffset
+ fsize
, reg_names
[regno
]);
771 else if (restore_from_sp
)
774 asm_fprintf (stream
, "\tfpmovd (%Rsp)+,%s\n",
777 asm_fprintf (stream
, "\tfpmoved %Rsp@+, %s\n",
784 asm_fprintf (stream
, "\tfpmovd -%d(%s), %s\n",
786 reg_names
[FRAME_POINTER_REGNUM
],
789 asm_fprintf (stream
, "\tfpmoved %s@(-%d), %s\n",
790 reg_names
[FRAME_POINTER_REGNUM
],
791 fpoffset
+ fsize
, reg_names
[regno
]);
796 if (frame_pointer_needed
)
797 fprintf (stream
, "\tunlk %s\n",
798 reg_names
[FRAME_POINTER_REGNUM
]);
807 asm_fprintf (stream
, "\taddq.w %0I%d,%Rsp\n", fsize
+ 4);
809 asm_fprintf (stream
, "\taddqw %0I%d,%Rsp\n", fsize
+ 4);
815 asm_fprintf (stream
, "\taddq.l %0I%d,%Rsp\n", fsize
+ 4);
817 asm_fprintf (stream
, "\taddql %0I%d,%Rsp\n", fsize
+ 4);
821 else if (fsize
+ 4 <= 16 && TARGET_CPU32
)
823 /* On the CPU32 it is faster to use two addqw instructions to
824 add a small integer (8 < N <= 16) to a register. */
825 /* asm_fprintf() cannot handle %. */
827 asm_fprintf (stream
, "\taddq.w %0I8,%Rsp\n\taddq.w %0I%d,%Rsp\n",
830 asm_fprintf (stream
, "\taddqw %0I8,%Rsp\n\taddqw %0I%d,%Rsp\n",
835 #endif /* not NO_ADDSUB_Q */
836 if (fsize
+ 4 < 0x8000)
840 /* asm_fprintf() cannot handle %. */
842 asm_fprintf (stream
, "\tadd.w %0I%d,%Rsp\n", fsize
+ 4);
844 asm_fprintf (stream
, "\taddw %0I%d,%Rsp\n", fsize
+ 4);
850 asm_fprintf (stream
, "\tlea (%d,%Rsp),%Rsp\n", fsize
+ 4);
852 asm_fprintf (stream
, "\tlea %Rsp@(%d),%Rsp\n", fsize
+ 4);
858 /* asm_fprintf() cannot handle %. */
860 asm_fprintf (stream
, "\tadd.l %0I%d,%Rsp\n", fsize
+ 4);
862 asm_fprintf (stream
, "\taddl %0I%d,%Rsp\n", fsize
+ 4);
866 if (current_function_pops_args
)
867 asm_fprintf (stream
, "\trtd %0I%d\n", current_function_pops_args
);
869 fprintf (stream
, "\trts\n");
872 /* Similar to general_operand, but exclude stack_pointer_rtx. */
875 not_sp_operand (op
, mode
)
877 enum machine_mode mode
;
879 return op
!= stack_pointer_rtx
&& general_operand (op
, mode
);
882 /* Return TRUE if X is a valid comparison operator for the dbcc
885 Note it rejects floating point comparison operators.
886 (In the future we could use Fdbcc).
888 It also rejects some comparisons when CC_NO_OVERFLOW is set. */
891 valid_dbcc_comparison_p (x
, mode
)
893 enum machine_mode mode ATTRIBUTE_UNUSED
;
895 switch (GET_CODE (x
))
897 case EQ
: case NE
: case GTU
: case LTU
:
901 /* Reject some when CC_NO_OVERFLOW is set. This may be over
903 case GT
: case LT
: case GE
: case LE
:
904 return ! (cc_prev_status
.flags
& CC_NO_OVERFLOW
);
910 /* Return non-zero if flags are currently in the 68881 flag register. */
914 /* We could add support for these in the future */
915 return cc_status
.flags
& CC_IN_68881
;
918 /* Output a dbCC; jCC sequence. Note we do not handle the
919 floating point version of this sequence (Fdbcc). We also
920 do not handle alternative conditions when CC_NO_OVERFLOW is
921 set. It is assumed that valid_dbcc_comparison_p and flags_in_68881 will
922 kick those out before we get here. */
925 output_dbcc_and_branch (operands
)
928 switch (GET_CODE (operands
[3]))
932 output_asm_insn ("dbeq %0,%l1\n\tjbeq %l2", operands
);
934 output_asm_insn ("dbeq %0,%l1\n\tjeq %l2", operands
);
940 output_asm_insn ("dbne %0,%l1\n\tjbne %l2", operands
);
942 output_asm_insn ("dbne %0,%l1\n\tjne %l2", operands
);
948 output_asm_insn ("dbgt %0,%l1\n\tjbgt %l2", operands
);
950 output_asm_insn ("dbgt %0,%l1\n\tjgt %l2", operands
);
956 output_asm_insn ("dbhi %0,%l1\n\tjbhi %l2", operands
);
958 output_asm_insn ("dbhi %0,%l1\n\tjhi %l2", operands
);
964 output_asm_insn ("dblt %0,%l1\n\tjblt %l2", operands
);
966 output_asm_insn ("dblt %0,%l1\n\tjlt %l2", operands
);
972 output_asm_insn ("dbcs %0,%l1\n\tjbcs %l2", operands
);
974 output_asm_insn ("dbcs %0,%l1\n\tjcs %l2", operands
);
980 output_asm_insn ("dbge %0,%l1\n\tjbge %l2", operands
);
982 output_asm_insn ("dbge %0,%l1\n\tjge %l2", operands
);
988 output_asm_insn ("dbcc %0,%l1\n\tjbcc %l2", operands
);
990 output_asm_insn ("dbcc %0,%l1\n\tjcc %l2", operands
);
996 output_asm_insn ("dble %0,%l1\n\tjble %l2", operands
);
998 output_asm_insn ("dble %0,%l1\n\tjle %l2", operands
);
1004 output_asm_insn ("dbls %0,%l1\n\tjbls %l2", operands
);
1006 output_asm_insn ("dbls %0,%l1\n\tjls %l2", operands
);
1014 /* If the decrement is to be done in SImode, then we have
1015 to compensate for the fact that dbcc decrements in HImode. */
1016 switch (GET_MODE (operands
[0]))
1020 output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjbpl %l1", operands
);
1022 output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjpl %l1", operands
);
1035 output_scc_di(op
, operand1
, operand2
, dest
)
1042 enum rtx_code op_code
= GET_CODE (op
);
1044 /* This does not produce a usefull cc. */
1047 /* The m68k cmp.l instruction requires operand1 to be a reg as used
1048 below. Swap the operands and change the op if these requirements
1049 are not fulfilled. */
1050 if (GET_CODE (operand2
) == REG
&& GET_CODE (operand1
) != REG
)
1054 operand1
= operand2
;
1056 op_code
= swap_condition (op_code
);
1058 loperands
[0] = operand1
;
1059 if (GET_CODE (operand1
) == REG
)
1060 loperands
[1] = gen_rtx_REG (SImode
, REGNO (operand1
) + 1);
1062 loperands
[1] = adj_offsettable_operand (operand1
, 4);
1063 if (operand2
!= const0_rtx
)
1065 loperands
[2] = operand2
;
1066 if (GET_CODE (operand2
) == REG
)
1067 loperands
[3] = gen_rtx_REG (SImode
, REGNO (operand2
) + 1);
1069 loperands
[3] = adj_offsettable_operand (operand2
, 4);
1071 loperands
[4] = gen_label_rtx();
1072 if (operand2
!= const0_rtx
)
1075 #ifdef SGS_CMP_ORDER
1076 output_asm_insn ("cmp%.l %0,%2\n\tjbne %l4\n\tcmp%.l %1,%3", loperands
);
1078 output_asm_insn ("cmp%.l %2,%0\n\tjbne %l4\n\tcmp%.l %3,%1", loperands
);
1081 #ifdef SGS_CMP_ORDER
1082 output_asm_insn ("cmp%.l %0,%2\n\tjne %l4\n\tcmp%.l %1,%3", loperands
);
1084 output_asm_insn ("cmp%.l %2,%0\n\tjne %l4\n\tcmp%.l %3,%1", loperands
);
1090 if (TARGET_68020
|| TARGET_5200
|| ! ADDRESS_REG_P (loperands
[0]))
1091 output_asm_insn ("tst%.l %0", loperands
);
1094 #ifdef SGS_CMP_ORDER
1095 output_asm_insn ("cmp%.w %0,%#0", loperands
);
1097 output_asm_insn ("cmp%.w %#0,%0", loperands
);
1102 output_asm_insn ("jbne %l4", loperands
);
1104 output_asm_insn ("jne %l4", loperands
);
1107 if (TARGET_68020
|| TARGET_5200
|| ! ADDRESS_REG_P (loperands
[1]))
1108 output_asm_insn ("tst%.l %1", loperands
);
1111 #ifdef SGS_CMP_ORDER
1112 output_asm_insn ("cmp%.w %1,%#0", loperands
);
1114 output_asm_insn ("cmp%.w %#0,%1", loperands
);
1119 loperands
[5] = dest
;
1124 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1125 CODE_LABEL_NUMBER (loperands
[4]));
1126 output_asm_insn ("seq %5", loperands
);
1130 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1131 CODE_LABEL_NUMBER (loperands
[4]));
1132 output_asm_insn ("sne %5", loperands
);
1136 loperands
[6] = gen_label_rtx();
1138 output_asm_insn ("shi %5\n\tjbra %l6", loperands
);
1140 output_asm_insn ("shi %5\n\tjra %l6", loperands
);
1142 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1143 CODE_LABEL_NUMBER (loperands
[4]));
1144 output_asm_insn ("sgt %5", loperands
);
1145 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1146 CODE_LABEL_NUMBER (loperands
[6]));
1150 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1151 CODE_LABEL_NUMBER (loperands
[4]));
1152 output_asm_insn ("shi %5", loperands
);
1156 loperands
[6] = gen_label_rtx();
1158 output_asm_insn ("scs %5\n\tjbra %l6", loperands
);
1160 output_asm_insn ("scs %5\n\tjra %l6", loperands
);
1162 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1163 CODE_LABEL_NUMBER (loperands
[4]));
1164 output_asm_insn ("slt %5", loperands
);
1165 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1166 CODE_LABEL_NUMBER (loperands
[6]));
1170 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1171 CODE_LABEL_NUMBER (loperands
[4]));
1172 output_asm_insn ("scs %5", loperands
);
1176 loperands
[6] = gen_label_rtx();
1178 output_asm_insn ("scc %5\n\tjbra %l6", loperands
);
1180 output_asm_insn ("scc %5\n\tjra %l6", loperands
);
1182 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1183 CODE_LABEL_NUMBER (loperands
[4]));
1184 output_asm_insn ("sge %5", loperands
);
1185 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1186 CODE_LABEL_NUMBER (loperands
[6]));
1190 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1191 CODE_LABEL_NUMBER (loperands
[4]));
1192 output_asm_insn ("scc %5", loperands
);
1196 loperands
[6] = gen_label_rtx();
1198 output_asm_insn ("sls %5\n\tjbra %l6", loperands
);
1200 output_asm_insn ("sls %5\n\tjra %l6", loperands
);
1202 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1203 CODE_LABEL_NUMBER (loperands
[4]));
1204 output_asm_insn ("sle %5", loperands
);
1205 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1206 CODE_LABEL_NUMBER (loperands
[6]));
1210 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1211 CODE_LABEL_NUMBER (loperands
[4]));
1212 output_asm_insn ("sls %5", loperands
);
1222 output_btst (operands
, countop
, dataop
, insn
, signpos
)
1224 rtx countop
, dataop
;
1228 operands
[0] = countop
;
1229 operands
[1] = dataop
;
1231 if (GET_CODE (countop
) == CONST_INT
)
1233 register int count
= INTVAL (countop
);
1234 /* If COUNT is bigger than size of storage unit in use,
1235 advance to the containing unit of same size. */
1236 if (count
> signpos
)
1238 int offset
= (count
& ~signpos
) / 8;
1239 count
= count
& signpos
;
1240 operands
[1] = dataop
= adj_offsettable_operand (dataop
, offset
);
1242 if (count
== signpos
)
1243 cc_status
.flags
= CC_NOT_POSITIVE
| CC_Z_IN_NOT_N
;
1245 cc_status
.flags
= CC_NOT_NEGATIVE
| CC_Z_IN_NOT_N
;
1247 /* These three statements used to use next_insns_test_no...
1248 but it appears that this should do the same job. */
1250 && next_insn_tests_no_inequality (insn
))
1253 && next_insn_tests_no_inequality (insn
))
1256 && next_insn_tests_no_inequality (insn
))
1259 cc_status
.flags
= CC_NOT_NEGATIVE
;
1261 return "btst %0,%1";
1264 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
1265 reference and a constant. */
1268 symbolic_operand (op
, mode
)
1270 enum machine_mode mode ATTRIBUTE_UNUSED
;
1272 switch (GET_CODE (op
))
1280 return ((GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
1281 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
)
1282 && GET_CODE (XEXP (op
, 1)) == CONST_INT
);
1284 #if 0 /* Deleted, with corresponding change in m68k.h,
1285 so as to fit the specs. No CONST_DOUBLE is ever symbolic. */
1287 return GET_MODE (op
) == mode
;
1295 /* Check for sign_extend or zero_extend. Used for bit-count operands. */
1298 extend_operator(x
, mode
)
1300 enum machine_mode mode
;
1302 if (mode
!= VOIDmode
&& GET_MODE(x
) != mode
)
1304 switch (GET_CODE(x
))
1315 /* Legitimize PIC addresses. If the address is already
1316 position-independent, we return ORIG. Newly generated
1317 position-independent addresses go to REG. If we need more
1318 than one register, we lose.
1320 An address is legitimized by making an indirect reference
1321 through the Global Offset Table with the name of the symbol
1324 The assembler and linker are responsible for placing the
1325 address of the symbol in the GOT. The function prologue
1326 is responsible for initializing a5 to the starting address
1329 The assembler is also responsible for translating a symbol name
1330 into a constant displacement from the start of the GOT.
1332 A quick example may make things a little clearer:
1334 When not generating PIC code to store the value 12345 into _foo
1335 we would generate the following code:
1339 When generating PIC two transformations are made. First, the compiler
1340 loads the address of foo into a register. So the first transformation makes:
1345 The code in movsi will intercept the lea instruction and call this
1346 routine which will transform the instructions into:
1348 movel a5@(_foo:w), a0
1352 That (in a nutshell) is how *all* symbol and label references are
1356 legitimize_pic_address (orig
, mode
, reg
)
1358 enum machine_mode mode ATTRIBUTE_UNUSED
;
1362 /* First handle a simple SYMBOL_REF or LABEL_REF */
1363 if (GET_CODE (orig
) == SYMBOL_REF
|| GET_CODE (orig
) == LABEL_REF
)
1368 pic_ref
= gen_rtx_MEM (Pmode
,
1369 gen_rtx_PLUS (Pmode
,
1370 pic_offset_table_rtx
, orig
));
1371 current_function_uses_pic_offset_table
= 1;
1372 RTX_UNCHANGING_P (pic_ref
) = 1;
1373 emit_move_insn (reg
, pic_ref
);
1376 else if (GET_CODE (orig
) == CONST
)
1380 /* Make sure this is CONST has not already been legitimized */
1381 if (GET_CODE (XEXP (orig
, 0)) == PLUS
1382 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
1388 /* legitimize both operands of the PLUS */
1389 if (GET_CODE (XEXP (orig
, 0)) == PLUS
)
1391 base
= legitimize_pic_address (XEXP (XEXP (orig
, 0), 0), Pmode
, reg
);
1392 orig
= legitimize_pic_address (XEXP (XEXP (orig
, 0), 1), Pmode
,
1393 base
== reg
? 0 : reg
);
1397 if (GET_CODE (orig
) == CONST_INT
)
1398 return plus_constant_for_output (base
, INTVAL (orig
));
1399 pic_ref
= gen_rtx_PLUS (Pmode
, base
, orig
);
1400 /* Likewise, should we set special REG_NOTEs here? */
1406 typedef enum { MOVL
, SWAP
, NEGW
, NOTW
, NOTB
, MOVQ
} CONST_METHOD
;
1408 static CONST_METHOD const_method
PARAMS ((rtx
));
1410 #define USE_MOVQ(i) ((unsigned)((i) + 128) <= 255)
1413 const_method (constant
)
1419 i
= INTVAL (constant
);
1423 /* The Coldfire doesn't have byte or word operations. */
1424 /* FIXME: This may not be useful for the m68060 either */
1427 /* if -256 < N < 256 but N is not in range for a moveq
1428 N^ff will be, so use moveq #N^ff, dreg; not.b dreg. */
1429 if (USE_MOVQ (i
^ 0xff))
1431 /* Likewise, try with not.w */
1432 if (USE_MOVQ (i
^ 0xffff))
1434 /* This is the only value where neg.w is useful */
1437 /* Try also with swap */
1439 if (USE_MOVQ ((u
>> 16) | (u
<< 16)))
1442 /* Otherwise, use move.l */
1447 const_int_cost (constant
)
1450 switch (const_method (constant
))
1453 /* Constants between -128 and 127 are cheap due to moveq */
1459 /* Constants easily generated by moveq + not.b/not.w/neg.w/swap */
1469 output_move_const_into_data_reg (operands
)
1474 i
= INTVAL (operands
[1]);
1475 switch (const_method (operands
[1]))
1478 #if defined (MOTOROLA) && !defined (CRDS)
1479 return "moveq%.l %1,%0";
1481 return "moveq %1,%0";
1484 operands
[1] = GEN_INT (i
^ 0xff);
1485 #if defined (MOTOROLA) && !defined (CRDS)
1486 return "moveq%.l %1,%0\n\tnot%.b %0";
1488 return "moveq %1,%0\n\tnot%.b %0";
1491 operands
[1] = GEN_INT (i
^ 0xffff);
1492 #if defined (MOTOROLA) && !defined (CRDS)
1493 return "moveq%.l %1,%0\n\tnot%.w %0";
1495 return "moveq %1,%0\n\tnot%.w %0";
1498 #if defined (MOTOROLA) && !defined (CRDS)
1499 return "moveq%.l %#-128,%0\n\tneg%.w %0";
1501 return "moveq %#-128,%0\n\tneg%.w %0";
1507 operands
[1] = GEN_INT ((u
<< 16) | (u
>> 16));
1508 #if defined (MOTOROLA) && !defined (CRDS)
1509 return "moveq%.l %1,%0\n\tswap %0";
1511 return "moveq %1,%0\n\tswap %0";
1515 return "move%.l %1,%0";
1522 output_move_simode_const (operands
)
1525 if (operands
[1] == const0_rtx
1526 && (DATA_REG_P (operands
[0])
1527 || GET_CODE (operands
[0]) == MEM
)
1528 /* clr insns on 68000 read before writing.
1529 This isn't so on the 68010, but we have no TARGET_68010. */
1530 && ((TARGET_68020
|| TARGET_5200
)
1531 || !(GET_CODE (operands
[0]) == MEM
1532 && MEM_VOLATILE_P (operands
[0]))))
1534 else if (operands
[1] == const0_rtx
1535 && ADDRESS_REG_P (operands
[0]))
1536 return "sub%.l %0,%0";
1537 else if (DATA_REG_P (operands
[0]))
1538 return output_move_const_into_data_reg (operands
);
1539 else if (ADDRESS_REG_P (operands
[0])
1540 && INTVAL (operands
[1]) < 0x8000
1541 && INTVAL (operands
[1]) >= -0x8000)
1542 return "move%.w %1,%0";
1543 else if (GET_CODE (operands
[0]) == MEM
1544 && GET_CODE (XEXP (operands
[0], 0)) == PRE_DEC
1545 && REGNO (XEXP (XEXP (operands
[0], 0), 0)) == STACK_POINTER_REGNUM
1546 && INTVAL (operands
[1]) < 0x8000
1547 && INTVAL (operands
[1]) >= -0x8000)
1549 return "move%.l %1,%0";
1553 output_move_simode (operands
)
1556 if (GET_CODE (operands
[1]) == CONST_INT
)
1557 return output_move_simode_const (operands
);
1558 else if ((GET_CODE (operands
[1]) == SYMBOL_REF
1559 || GET_CODE (operands
[1]) == CONST
)
1560 && push_operand (operands
[0], SImode
))
1562 else if ((GET_CODE (operands
[1]) == SYMBOL_REF
1563 || GET_CODE (operands
[1]) == CONST
)
1564 && ADDRESS_REG_P (operands
[0]))
1565 return "lea %a1,%0";
1566 return "move%.l %1,%0";
1570 output_move_himode (operands
)
1573 if (GET_CODE (operands
[1]) == CONST_INT
)
1575 if (operands
[1] == const0_rtx
1576 && (DATA_REG_P (operands
[0])
1577 || GET_CODE (operands
[0]) == MEM
)
1578 /* clr insns on 68000 read before writing.
1579 This isn't so on the 68010, but we have no TARGET_68010. */
1580 && ((TARGET_68020
|| TARGET_5200
)
1581 || !(GET_CODE (operands
[0]) == MEM
1582 && MEM_VOLATILE_P (operands
[0]))))
1584 else if (operands
[1] == const0_rtx
1585 && ADDRESS_REG_P (operands
[0]))
1586 return "sub%.l %0,%0";
1587 else if (DATA_REG_P (operands
[0])
1588 && INTVAL (operands
[1]) < 128
1589 && INTVAL (operands
[1]) >= -128)
1591 #if defined(MOTOROLA) && !defined(CRDS)
1592 return "moveq%.l %1,%0";
1594 return "moveq %1,%0";
1597 else if (INTVAL (operands
[1]) < 0x8000
1598 && INTVAL (operands
[1]) >= -0x8000)
1599 return "move%.w %1,%0";
1601 else if (CONSTANT_P (operands
[1]))
1602 return "move%.l %1,%0";
1604 /* Recognize the insn before a tablejump, one that refers
1605 to a table of offsets. Such an insn will need to refer
1606 to a label on the insn. So output one. Use the label-number
1607 of the table of offsets to generate this label. This code,
1608 and similar code below, assumes that there will be at most one
1609 reference to each table. */
1610 if (GET_CODE (operands
[1]) == MEM
1611 && GET_CODE (XEXP (operands
[1], 0)) == PLUS
1612 && GET_CODE (XEXP (XEXP (operands
[1], 0), 1)) == LABEL_REF
1613 && GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) != PLUS
)
1615 rtx labelref
= XEXP (XEXP (operands
[1], 0), 1);
1616 #if defined (MOTOROLA) && !defined (SGS_SWITCH_TABLES)
1618 asm_fprintf (asm_out_file
, "\tset %LLI%d,.+2\n",
1619 CODE_LABEL_NUMBER (XEXP (labelref
, 0)));
1621 asm_fprintf (asm_out_file
, "\t.set %LLI%d,.+2\n",
1622 CODE_LABEL_NUMBER (XEXP (labelref
, 0)));
1623 #endif /* not SGS */
1624 #else /* SGS_SWITCH_TABLES or not MOTOROLA */
1625 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "LI",
1626 CODE_LABEL_NUMBER (XEXP (labelref
, 0)));
1627 #ifdef SGS_SWITCH_TABLES
1628 /* Set flag saying we need to define the symbol
1629 LD%n (with value L%n-LI%n) at the end of the switch table. */
1630 switch_table_difference_label_flag
= 1;
1631 #endif /* SGS_SWITCH_TABLES */
1632 #endif /* SGS_SWITCH_TABLES or not MOTOROLA */
1634 #endif /* SGS_NO_LI */
1635 return "move%.w %1,%0";
1639 output_move_qimode (operands
)
1644 /* This is probably useless, since it loses for pushing a struct
1645 of several bytes a byte at a time. */
1646 /* 68k family always modifies the stack pointer by at least 2, even for
1647 byte pushes. The 5200 (coldfire) does not do this. */
1648 if (GET_CODE (operands
[0]) == MEM
1649 && GET_CODE (XEXP (operands
[0], 0)) == PRE_DEC
1650 && XEXP (XEXP (operands
[0], 0), 0) == stack_pointer_rtx
1651 && ! ADDRESS_REG_P (operands
[1])
1654 xoperands
[1] = operands
[1];
1656 = gen_rtx_MEM (QImode
,
1657 gen_rtx_PLUS (VOIDmode
, stack_pointer_rtx
, const1_rtx
));
1658 /* Just pushing a byte puts it in the high byte of the halfword. */
1659 /* We must put it in the low-order, high-numbered byte. */
1660 if (!reg_mentioned_p (stack_pointer_rtx
, operands
[1]))
1662 xoperands
[3] = stack_pointer_rtx
;
1664 output_asm_insn ("subq%.l %#2,%3\n\tmove%.b %1,%2", xoperands
);
1666 output_asm_insn ("sub%.l %#2,%3\n\tmove%.b %1,%2", xoperands
);
1670 output_asm_insn ("move%.b %1,%-\n\tmove%.b %@,%2", xoperands
);
1674 /* clr and st insns on 68000 read before writing.
1675 This isn't so on the 68010, but we have no TARGET_68010. */
1676 if (!ADDRESS_REG_P (operands
[0])
1677 && ((TARGET_68020
|| TARGET_5200
)
1678 || !(GET_CODE (operands
[0]) == MEM
&& MEM_VOLATILE_P (operands
[0]))))
1680 if (operands
[1] == const0_rtx
)
1682 if ((!TARGET_5200
|| DATA_REG_P (operands
[0]))
1683 && GET_CODE (operands
[1]) == CONST_INT
1684 && (INTVAL (operands
[1]) & 255) == 255)
1690 if (GET_CODE (operands
[1]) == CONST_INT
1691 && DATA_REG_P (operands
[0])
1692 && INTVAL (operands
[1]) < 128
1693 && INTVAL (operands
[1]) >= -128)
1695 #if defined(MOTOROLA) && !defined(CRDS)
1696 return "moveq%.l %1,%0";
1698 return "moveq %1,%0";
1701 if (operands
[1] == const0_rtx
&& ADDRESS_REG_P (operands
[0]))
1702 return "sub%.l %0,%0";
1703 if (GET_CODE (operands
[1]) != CONST_INT
&& CONSTANT_P (operands
[1]))
1704 return "move%.l %1,%0";
1705 /* 68k family (including the 5200 coldfire) does not support byte moves to
1706 from address registers. */
1707 if (ADDRESS_REG_P (operands
[0]) || ADDRESS_REG_P (operands
[1]))
1708 return "move%.w %1,%0";
1709 return "move%.b %1,%0";
1713 output_move_stricthi (operands
)
1716 if (operands
[1] == const0_rtx
1717 /* clr insns on 68000 read before writing.
1718 This isn't so on the 68010, but we have no TARGET_68010. */
1719 && ((TARGET_68020
|| TARGET_5200
)
1720 || !(GET_CODE (operands
[0]) == MEM
&& MEM_VOLATILE_P (operands
[0]))))
1722 return "move%.w %1,%0";
1726 output_move_strictqi (operands
)
1729 if (operands
[1] == const0_rtx
1730 /* clr insns on 68000 read before writing.
1731 This isn't so on the 68010, but we have no TARGET_68010. */
1732 && ((TARGET_68020
|| TARGET_5200
)
1733 || !(GET_CODE (operands
[0]) == MEM
&& MEM_VOLATILE_P (operands
[0]))))
1735 return "move%.b %1,%0";
1738 /* Return the best assembler insn template
1739 for moving operands[1] into operands[0] as a fullword. */
1742 singlemove_string (operands
)
1745 #ifdef SUPPORT_SUN_FPA
1746 if (FPA_REG_P (operands
[0]) || FPA_REG_P (operands
[1]))
1747 return "fpmoves %1,%0";
1749 if (GET_CODE (operands
[1]) == CONST_INT
)
1750 return output_move_simode_const (operands
);
1751 return "move%.l %1,%0";
1755 /* Output assembler code to perform a doubleword move insn
1756 with operands OPERANDS. */
1759 output_move_double (operands
)
1764 REGOP
, OFFSOP
, MEMOP
, PUSHOP
, POPOP
, CNSTOP
, RNDOP
1769 rtx addreg0
= 0, addreg1
= 0;
1770 int dest_overlapped_low
= 0;
1771 int size
= GET_MODE_SIZE (GET_MODE (operands
[0]));
1776 /* First classify both operands. */
1778 if (REG_P (operands
[0]))
1780 else if (offsettable_memref_p (operands
[0]))
1782 else if (GET_CODE (XEXP (operands
[0], 0)) == POST_INC
)
1784 else if (GET_CODE (XEXP (operands
[0], 0)) == PRE_DEC
)
1786 else if (GET_CODE (operands
[0]) == MEM
)
1791 if (REG_P (operands
[1]))
1793 else if (CONSTANT_P (operands
[1]))
1795 else if (offsettable_memref_p (operands
[1]))
1797 else if (GET_CODE (XEXP (operands
[1], 0)) == POST_INC
)
1799 else if (GET_CODE (XEXP (operands
[1], 0)) == PRE_DEC
)
1801 else if (GET_CODE (operands
[1]) == MEM
)
1806 /* Check for the cases that the operand constraints are not
1807 supposed to allow to happen. Abort if we get one,
1808 because generating code for these cases is painful. */
1810 if (optype0
== RNDOP
|| optype1
== RNDOP
)
1813 /* If one operand is decrementing and one is incrementing
1814 decrement the former register explicitly
1815 and change that operand into ordinary indexing. */
1817 if (optype0
== PUSHOP
&& optype1
== POPOP
)
1819 operands
[0] = XEXP (XEXP (operands
[0], 0), 0);
1821 output_asm_insn ("sub%.l %#12,%0", operands
);
1823 output_asm_insn ("subq%.l %#8,%0", operands
);
1824 if (GET_MODE (operands
[1]) == XFmode
)
1825 operands
[0] = gen_rtx_MEM (XFmode
, operands
[0]);
1826 else if (GET_MODE (operands
[0]) == DFmode
)
1827 operands
[0] = gen_rtx_MEM (DFmode
, operands
[0]);
1829 operands
[0] = gen_rtx_MEM (DImode
, operands
[0]);
1832 if (optype0
== POPOP
&& optype1
== PUSHOP
)
1834 operands
[1] = XEXP (XEXP (operands
[1], 0), 0);
1836 output_asm_insn ("sub%.l %#12,%1", operands
);
1838 output_asm_insn ("subq%.l %#8,%1", operands
);
1839 if (GET_MODE (operands
[1]) == XFmode
)
1840 operands
[1] = gen_rtx_MEM (XFmode
, operands
[1]);
1841 else if (GET_MODE (operands
[1]) == DFmode
)
1842 operands
[1] = gen_rtx_MEM (DFmode
, operands
[1]);
1844 operands
[1] = gen_rtx_MEM (DImode
, operands
[1]);
1848 /* If an operand is an unoffsettable memory ref, find a register
1849 we can increment temporarily to make it refer to the second word. */
1851 if (optype0
== MEMOP
)
1852 addreg0
= find_addr_reg (XEXP (operands
[0], 0));
1854 if (optype1
== MEMOP
)
1855 addreg1
= find_addr_reg (XEXP (operands
[1], 0));
1857 /* Ok, we can do one word at a time.
1858 Normally we do the low-numbered word first,
1859 but if either operand is autodecrementing then we
1860 do the high-numbered word first.
1862 In either case, set up in LATEHALF the operands to use
1863 for the high-numbered word and in some cases alter the
1864 operands in OPERANDS to be suitable for the low-numbered word. */
1868 if (optype0
== REGOP
)
1870 latehalf
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 2);
1871 middlehalf
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 1);
1873 else if (optype0
== OFFSOP
)
1875 middlehalf
[0] = adj_offsettable_operand (operands
[0], 4);
1876 latehalf
[0] = adj_offsettable_operand (operands
[0], size
- 4);
1880 middlehalf
[0] = operands
[0];
1881 latehalf
[0] = operands
[0];
1884 if (optype1
== REGOP
)
1886 latehalf
[1] = gen_rtx_REG (SImode
, REGNO (operands
[1]) + 2);
1887 middlehalf
[1] = gen_rtx_REG (SImode
, REGNO (operands
[1]) + 1);
1889 else if (optype1
== OFFSOP
)
1891 middlehalf
[1] = adj_offsettable_operand (operands
[1], 4);
1892 latehalf
[1] = adj_offsettable_operand (operands
[1], size
- 4);
1894 else if (optype1
== CNSTOP
)
1896 if (GET_CODE (operands
[1]) == CONST_DOUBLE
)
1901 REAL_VALUE_FROM_CONST_DOUBLE (r
, operands
[1]);
1902 REAL_VALUE_TO_TARGET_LONG_DOUBLE (r
, l
);
1903 operands
[1] = GEN_INT (l
[0]);
1904 middlehalf
[1] = GEN_INT (l
[1]);
1905 latehalf
[1] = GEN_INT (l
[2]);
1907 else if (CONSTANT_P (operands
[1]))
1909 /* actually, no non-CONST_DOUBLE constant should ever
1912 if (GET_CODE (operands
[1]) == CONST_INT
&& INTVAL (operands
[1]) < 0)
1913 latehalf
[1] = constm1_rtx
;
1915 latehalf
[1] = const0_rtx
;
1920 middlehalf
[1] = operands
[1];
1921 latehalf
[1] = operands
[1];
1925 /* size is not 12: */
1927 if (optype0
== REGOP
)
1928 latehalf
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 1);
1929 else if (optype0
== OFFSOP
)
1930 latehalf
[0] = adj_offsettable_operand (operands
[0], size
- 4);
1932 latehalf
[0] = operands
[0];
1934 if (optype1
== REGOP
)
1935 latehalf
[1] = gen_rtx_REG (SImode
, REGNO (operands
[1]) + 1);
1936 else if (optype1
== OFFSOP
)
1937 latehalf
[1] = adj_offsettable_operand (operands
[1], size
- 4);
1938 else if (optype1
== CNSTOP
)
1939 split_double (operands
[1], &operands
[1], &latehalf
[1]);
1941 latehalf
[1] = operands
[1];
1944 /* If insn is effectively movd N(sp),-(sp) then we will do the
1945 high word first. We should use the adjusted operand 1 (which is N+4(sp))
1946 for the low word as well, to compensate for the first decrement of sp. */
1947 if (optype0
== PUSHOP
1948 && REGNO (XEXP (XEXP (operands
[0], 0), 0)) == STACK_POINTER_REGNUM
1949 && reg_overlap_mentioned_p (stack_pointer_rtx
, operands
[1]))
1950 operands
[1] = middlehalf
[1] = latehalf
[1];
1952 /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)),
1953 if the upper part of reg N does not appear in the MEM, arrange to
1954 emit the move late-half first. Otherwise, compute the MEM address
1955 into the upper part of N and use that as a pointer to the memory
1957 if (optype0
== REGOP
1958 && (optype1
== OFFSOP
|| optype1
== MEMOP
))
1960 rtx testlow
= gen_rtx_REG (SImode
, REGNO (operands
[0]));
1962 if (reg_overlap_mentioned_p (testlow
, XEXP (operands
[1], 0))
1963 && reg_overlap_mentioned_p (latehalf
[0], XEXP (operands
[1], 0)))
1965 /* If both halves of dest are used in the src memory address,
1966 compute the address into latehalf of dest.
1967 Note that this can't happen if the dest is two data regs. */
1969 xops
[0] = latehalf
[0];
1970 xops
[1] = XEXP (operands
[1], 0);
1971 output_asm_insn ("lea %a1,%0", xops
);
1972 if( GET_MODE (operands
[1]) == XFmode
)
1974 operands
[1] = gen_rtx_MEM (XFmode
, latehalf
[0]);
1975 middlehalf
[1] = adj_offsettable_operand (operands
[1], size
-8);
1976 latehalf
[1] = adj_offsettable_operand (operands
[1], size
-4);
1980 operands
[1] = gen_rtx_MEM (DImode
, latehalf
[0]);
1981 latehalf
[1] = adj_offsettable_operand (operands
[1], size
-4);
1985 && reg_overlap_mentioned_p (middlehalf
[0],
1986 XEXP (operands
[1], 0)))
1988 /* Check for two regs used by both source and dest.
1989 Note that this can't happen if the dest is all data regs.
1990 It can happen if the dest is d6, d7, a0.
1991 But in that case, latehalf is an addr reg, so
1992 the code at compadr does ok. */
1994 if (reg_overlap_mentioned_p (testlow
, XEXP (operands
[1], 0))
1995 || reg_overlap_mentioned_p (latehalf
[0], XEXP (operands
[1], 0)))
1998 /* JRV says this can't happen: */
1999 if (addreg0
|| addreg1
)
2002 /* Only the middle reg conflicts; simply put it last. */
2003 output_asm_insn (singlemove_string (operands
), operands
);
2004 output_asm_insn (singlemove_string (latehalf
), latehalf
);
2005 output_asm_insn (singlemove_string (middlehalf
), middlehalf
);
2008 else if (reg_overlap_mentioned_p (testlow
, XEXP (operands
[1], 0)))
2009 /* If the low half of dest is mentioned in the source memory
2010 address, the arrange to emit the move late half first. */
2011 dest_overlapped_low
= 1;
2014 /* If one or both operands autodecrementing,
2015 do the two words, high-numbered first. */
2017 /* Likewise, the first move would clobber the source of the second one,
2018 do them in the other order. This happens only for registers;
2019 such overlap can't happen in memory unless the user explicitly
2020 sets it up, and that is an undefined circumstance. */
2022 if (optype0
== PUSHOP
|| optype1
== PUSHOP
2023 || (optype0
== REGOP
&& optype1
== REGOP
2024 && ((middlehalf
[1] && REGNO (operands
[0]) == REGNO (middlehalf
[1]))
2025 || REGNO (operands
[0]) == REGNO (latehalf
[1])))
2026 || dest_overlapped_low
)
2028 /* Make any unoffsettable addresses point at high-numbered word. */
2032 output_asm_insn ("addq%.l %#8,%0", &addreg0
);
2034 output_asm_insn ("addq%.l %#4,%0", &addreg0
);
2039 output_asm_insn ("addq%.l %#8,%0", &addreg1
);
2041 output_asm_insn ("addq%.l %#4,%0", &addreg1
);
2045 output_asm_insn (singlemove_string (latehalf
), latehalf
);
2047 /* Undo the adds we just did. */
2049 output_asm_insn ("subq%.l %#4,%0", &addreg0
);
2051 output_asm_insn ("subq%.l %#4,%0", &addreg1
);
2055 output_asm_insn (singlemove_string (middlehalf
), middlehalf
);
2057 output_asm_insn ("subq%.l %#4,%0", &addreg0
);
2059 output_asm_insn ("subq%.l %#4,%0", &addreg1
);
2062 /* Do low-numbered word. */
2063 return singlemove_string (operands
);
2066 /* Normal case: do the two words, low-numbered first. */
2068 output_asm_insn (singlemove_string (operands
), operands
);
2070 /* Do the middle one of the three words for long double */
2074 output_asm_insn ("addq%.l %#4,%0", &addreg0
);
2076 output_asm_insn ("addq%.l %#4,%0", &addreg1
);
2078 output_asm_insn (singlemove_string (middlehalf
), middlehalf
);
2081 /* Make any unoffsettable addresses point at high-numbered word. */
2083 output_asm_insn ("addq%.l %#4,%0", &addreg0
);
2085 output_asm_insn ("addq%.l %#4,%0", &addreg1
);
2088 output_asm_insn (singlemove_string (latehalf
), latehalf
);
2090 /* Undo the adds we just did. */
2094 output_asm_insn ("subq%.l %#8,%0", &addreg0
);
2096 output_asm_insn ("subq%.l %#4,%0", &addreg0
);
2101 output_asm_insn ("subq%.l %#8,%0", &addreg1
);
2103 output_asm_insn ("subq%.l %#4,%0", &addreg1
);
2109 /* Return a REG that occurs in ADDR with coefficient 1.
2110 ADDR can be effectively incremented by incrementing REG. */
2113 find_addr_reg (addr
)
2116 while (GET_CODE (addr
) == PLUS
)
2118 if (GET_CODE (XEXP (addr
, 0)) == REG
)
2119 addr
= XEXP (addr
, 0);
2120 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
2121 addr
= XEXP (addr
, 1);
2122 else if (CONSTANT_P (XEXP (addr
, 0)))
2123 addr
= XEXP (addr
, 1);
2124 else if (CONSTANT_P (XEXP (addr
, 1)))
2125 addr
= XEXP (addr
, 0);
2129 if (GET_CODE (addr
) == REG
)
2134 /* Output assembler code to perform a 32 bit 3 operand add. */
2137 output_addsi3 (operands
)
2140 if (! operands_match_p (operands
[0], operands
[1]))
2142 if (!ADDRESS_REG_P (operands
[1]))
2144 rtx tmp
= operands
[1];
2146 operands
[1] = operands
[2];
2150 /* These insns can result from reloads to access
2151 stack slots over 64k from the frame pointer. */
2152 if (GET_CODE (operands
[2]) == CONST_INT
2153 && INTVAL (operands
[2]) + 0x8000 >= (unsigned) 0x10000)
2154 return "move%.l %2,%0\n\tadd%.l %1,%0";
2156 if (GET_CODE (operands
[2]) == REG
)
2157 return "lea 0(%1,%2.l),%0";
2159 return "lea %c2(%1),%0";
2162 if (GET_CODE (operands
[2]) == REG
)
2163 return "lea (%1,%2.l),%0";
2165 return "lea (%c2,%1),%0";
2166 #else /* not MOTOROLA (MIT syntax) */
2167 if (GET_CODE (operands
[2]) == REG
)
2168 return "lea %1@(0,%2:l),%0";
2170 return "lea %1@(%c2),%0";
2171 #endif /* not MOTOROLA */
2172 #endif /* not SGS */
2174 if (GET_CODE (operands
[2]) == CONST_INT
)
2177 if (INTVAL (operands
[2]) > 0
2178 && INTVAL (operands
[2]) <= 8)
2179 return "addq%.l %2,%0";
2180 if (INTVAL (operands
[2]) < 0
2181 && INTVAL (operands
[2]) >= -8)
2183 operands
[2] = GEN_INT (- INTVAL (operands
[2]));
2184 return "subq%.l %2,%0";
2186 /* On the CPU32 it is faster to use two addql instructions to
2187 add a small integer (8 < N <= 16) to a register.
2188 Likewise for subql. */
2189 if (TARGET_CPU32
&& REG_P (operands
[0]))
2191 if (INTVAL (operands
[2]) > 8
2192 && INTVAL (operands
[2]) <= 16)
2194 operands
[2] = GEN_INT (INTVAL (operands
[2]) - 8);
2195 return "addq%.l %#8,%0\n\taddq%.l %2,%0";
2197 if (INTVAL (operands
[2]) < -8
2198 && INTVAL (operands
[2]) >= -16)
2200 operands
[2] = GEN_INT (- INTVAL (operands
[2]) - 8);
2201 return "subq%.l %#8,%0\n\tsubq%.l %2,%0";
2205 if (ADDRESS_REG_P (operands
[0])
2206 && INTVAL (operands
[2]) >= -0x8000
2207 && INTVAL (operands
[2]) < 0x8000)
2210 return "add%.w %2,%0";
2213 return "lea (%c2,%0),%0";
2215 return "lea %0@(%c2),%0";
2219 return "add%.l %2,%0";
2222 /* Store in cc_status the expressions that the condition codes will
2223 describe after execution of an instruction whose pattern is EXP.
2224 Do not alter them if the instruction would not alter the cc's. */
2226 /* On the 68000, all the insns to store in an address register fail to
2227 set the cc's. However, in some cases these instructions can make it
2228 possibly invalid to use the saved cc's. In those cases we clear out
2229 some or all of the saved cc's so they won't be used. */
2232 notice_update_cc (exp
, insn
)
2236 /* If the cc is being set from the fpa and the expression is not an
2237 explicit floating point test instruction (which has code to deal with
2238 this), reinit the CC. */
2239 if (((cc_status
.value1
&& FPA_REG_P (cc_status
.value1
))
2240 || (cc_status
.value2
&& FPA_REG_P (cc_status
.value2
)))
2241 && !(GET_CODE (exp
) == PARALLEL
2242 && GET_CODE (XVECEXP (exp
, 0, 0)) == SET
2243 && XEXP (XVECEXP (exp
, 0, 0), 0) == cc0_rtx
))
2247 else if (GET_CODE (exp
) == SET
)
2249 if (GET_CODE (SET_SRC (exp
)) == CALL
)
2253 else if (ADDRESS_REG_P (SET_DEST (exp
)))
2255 if (cc_status
.value1
&& modified_in_p (cc_status
.value1
, insn
))
2256 cc_status
.value1
= 0;
2257 if (cc_status
.value2
&& modified_in_p (cc_status
.value2
, insn
))
2258 cc_status
.value2
= 0;
2260 else if (!FP_REG_P (SET_DEST (exp
))
2261 && SET_DEST (exp
) != cc0_rtx
2262 && (FP_REG_P (SET_SRC (exp
))
2263 || GET_CODE (SET_SRC (exp
)) == FIX
2264 || GET_CODE (SET_SRC (exp
)) == FLOAT_TRUNCATE
2265 || GET_CODE (SET_SRC (exp
)) == FLOAT_EXTEND
))
2269 /* A pair of move insns doesn't produce a useful overall cc. */
2270 else if (!FP_REG_P (SET_DEST (exp
))
2271 && !FP_REG_P (SET_SRC (exp
))
2272 && GET_MODE_SIZE (GET_MODE (SET_SRC (exp
))) > 4
2273 && (GET_CODE (SET_SRC (exp
)) == REG
2274 || GET_CODE (SET_SRC (exp
)) == MEM
2275 || GET_CODE (SET_SRC (exp
)) == CONST_DOUBLE
))
2279 else if (GET_CODE (SET_SRC (exp
)) == CALL
)
2283 else if (XEXP (exp
, 0) != pc_rtx
)
2285 cc_status
.flags
= 0;
2286 cc_status
.value1
= XEXP (exp
, 0);
2287 cc_status
.value2
= XEXP (exp
, 1);
2290 else if (GET_CODE (exp
) == PARALLEL
2291 && GET_CODE (XVECEXP (exp
, 0, 0)) == SET
)
2293 if (ADDRESS_REG_P (XEXP (XVECEXP (exp
, 0, 0), 0)))
2295 else if (XEXP (XVECEXP (exp
, 0, 0), 0) != pc_rtx
)
2297 cc_status
.flags
= 0;
2298 cc_status
.value1
= XEXP (XVECEXP (exp
, 0, 0), 0);
2299 cc_status
.value2
= XEXP (XVECEXP (exp
, 0, 0), 1);
2304 if (cc_status
.value2
!= 0
2305 && ADDRESS_REG_P (cc_status
.value2
)
2306 && GET_MODE (cc_status
.value2
) == QImode
)
2308 if (cc_status
.value2
!= 0
2309 && !(cc_status
.value1
&& FPA_REG_P (cc_status
.value1
)))
2310 switch (GET_CODE (cc_status
.value2
))
2312 case PLUS
: case MINUS
: case MULT
:
2313 case DIV
: case UDIV
: case MOD
: case UMOD
: case NEG
:
2314 #if 0 /* These instructions always clear the overflow bit */
2315 case ASHIFT
: case ASHIFTRT
: case LSHIFTRT
:
2316 case ROTATE
: case ROTATERT
:
2318 if (GET_MODE (cc_status
.value2
) != VOIDmode
)
2319 cc_status
.flags
|= CC_NO_OVERFLOW
;
2322 /* (SET r1 (ZERO_EXTEND r2)) on this machine
2323 ends with a move insn moving r2 in r2's mode.
2324 Thus, the cc's are set for r2.
2325 This can set N bit spuriously. */
2326 cc_status
.flags
|= CC_NOT_NEGATIVE
;
2331 if (cc_status
.value1
&& GET_CODE (cc_status
.value1
) == REG
2333 && reg_overlap_mentioned_p (cc_status
.value1
, cc_status
.value2
))
2334 cc_status
.value2
= 0;
2335 if (((cc_status
.value1
&& FP_REG_P (cc_status
.value1
))
2336 || (cc_status
.value2
&& FP_REG_P (cc_status
.value2
)))
2337 && !((cc_status
.value1
&& FPA_REG_P (cc_status
.value1
))
2338 || (cc_status
.value2
&& FPA_REG_P (cc_status
.value2
))))
2339 cc_status
.flags
= CC_IN_68881
;
2343 output_move_const_double (operands
)
2346 #ifdef SUPPORT_SUN_FPA
2347 if (TARGET_FPA
&& FPA_REG_P (operands
[0]))
2349 int code
= standard_sun_fpa_constant_p (operands
[1]);
2353 static char buf
[40];
2355 sprintf (buf
, "fpmove%%.d %%%%%d,%%0", code
& 0x1ff);
2358 return "fpmove%.d %1,%0";
2363 int code
= standard_68881_constant_p (operands
[1]);
2367 static char buf
[40];
2369 sprintf (buf
, "fmovecr %%#0x%x,%%0", code
& 0xff);
2372 return "fmove%.d %1,%0";
2377 output_move_const_single (operands
)
2380 #ifdef SUPPORT_SUN_FPA
2383 int code
= standard_sun_fpa_constant_p (operands
[1]);
2387 static char buf
[40];
2389 sprintf (buf
, "fpmove%%.s %%%%%d,%%0", code
& 0x1ff);
2392 return "fpmove%.s %1,%0";
2395 #endif /* defined SUPPORT_SUN_FPA */
2397 int code
= standard_68881_constant_p (operands
[1]);
2401 static char buf
[40];
2403 sprintf (buf
, "fmovecr %%#0x%x,%%0", code
& 0xff);
2406 return "fmove%.s %f1,%0";
2410 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
2411 from the "fmovecr" instruction.
2412 The value, anded with 0xff, gives the code to use in fmovecr
2413 to get the desired constant. */
2415 /* This code has been fixed for cross-compilation. */
2417 static int inited_68881_table
= 0;
2419 static const char *const strings_68881
[7] = {
2429 int codes_68881
[7] = {
2439 REAL_VALUE_TYPE values_68881
[7];
2441 /* Set up values_68881 array by converting the decimal values
2442 strings_68881 to binary. */
2449 enum machine_mode mode
;
2452 for (i
= 0; i
< 7; i
++)
2456 r
= REAL_VALUE_ATOF (strings_68881
[i
], mode
);
2457 values_68881
[i
] = r
;
2459 inited_68881_table
= 1;
2463 standard_68881_constant_p (x
)
2469 #ifdef NO_ASM_FMOVECR
2473 /* fmovecr must be emulated on the 68040 and 68060, so it shouldn't be
2474 used at all on those chips. */
2475 if (TARGET_68040
|| TARGET_68060
)
2478 #ifndef REAL_ARITHMETIC
2479 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
2480 if (! flag_pretend_float
)
2485 if (! inited_68881_table
)
2486 init_68881_table ();
2488 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
2490 /* Use REAL_VALUES_IDENTICAL instead of REAL_VALUES_EQUAL so that -0.0
2492 for (i
= 0; i
< 6; i
++)
2494 if (REAL_VALUES_IDENTICAL (r
, values_68881
[i
]))
2495 return (codes_68881
[i
]);
2498 if (GET_MODE (x
) == SFmode
)
2501 if (REAL_VALUES_EQUAL (r
, values_68881
[6]))
2502 return (codes_68881
[6]);
2504 /* larger powers of ten in the constants ram are not used
2505 because they are not equal to a `double' C constant. */
2509 /* If X is a floating-point constant, return the logarithm of X base 2,
2510 or 0 if X is not a power of 2. */
2513 floating_exact_log2 (x
)
2516 REAL_VALUE_TYPE r
, r1
;
2519 #ifndef REAL_ARITHMETIC
2520 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
2521 if (! flag_pretend_float
)
2526 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
2528 if (REAL_VALUES_LESS (r
, dconst0
))
2533 while (REAL_VALUES_LESS (r1
, r
))
2535 r1
= REAL_VALUE_LDEXP (dconst1
, i
);
2536 if (REAL_VALUES_EQUAL (r1
, r
))
2543 #ifdef SUPPORT_SUN_FPA
2544 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
2545 from the Sun FPA's constant RAM.
2546 The value returned, anded with 0x1ff, gives the code to use in fpmove
2547 to get the desired constant. */
2549 static int inited_FPA_table
= 0;
2551 static const char *const strings_FPA
[38] = {
2552 /* small rationals */
2565 /* Decimal equivalents of double precision values */
2566 "2.718281828459045091", /* D_E */
2567 "6.283185307179586477", /* 2 pi */
2568 "3.141592653589793116", /* D_PI */
2569 "1.570796326794896619", /* pi/2 */
2570 "1.414213562373095145", /* D_SQRT2 */
2571 "0.7071067811865475244", /* 1/sqrt(2) */
2572 "-1.570796326794896619", /* -pi/2 */
2573 "1.442695040888963387", /* D_LOG2ofE */
2574 "3.321928024887362182", /* D_LOG2of10 */
2575 "0.6931471805599452862", /* D_LOGEof2 */
2576 "2.302585092994045901", /* D_LOGEof10 */
2577 "0.3010299956639811980", /* D_LOG10of2 */
2578 "0.4342944819032518167", /* D_LOG10ofE */
2579 /* Decimal equivalents of single precision values */
2580 "2.718281745910644531", /* S_E */
2581 "6.283185307179586477", /* 2 pi */
2582 "3.141592741012573242", /* S_PI */
2583 "1.570796326794896619", /* pi/2 */
2584 "1.414213538169860840", /* S_SQRT2 */
2585 "0.7071067811865475244", /* 1/sqrt(2) */
2586 "-1.570796326794896619", /* -pi/2 */
2587 "1.442695021629333496", /* S_LOG2ofE */
2588 "3.321928024291992188", /* S_LOG2of10 */
2589 "0.6931471824645996094", /* S_LOGEof2 */
2590 "2.302585124969482442", /* S_LOGEof10 */
2591 "0.3010300099849700928", /* S_LOG10of2 */
2592 "0.4342944920063018799", /* S_LOG10ofE */
2596 int codes_FPA
[38] = {
2597 /* small rationals */
2610 /* double precision */
2624 /* single precision */
2640 REAL_VALUE_TYPE values_FPA
[38];
2642 /* This code has been fixed for cross-compilation. */
2647 enum machine_mode mode
;
2652 for (i
= 0; i
< 38; i
++)
2656 r
= REAL_VALUE_ATOF (strings_FPA
[i
], mode
);
2659 inited_FPA_table
= 1;
2664 standard_sun_fpa_constant_p (x
)
2670 #ifndef REAL_ARITHMETIC
2671 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
2672 if (! flag_pretend_float
)
2677 if (! inited_FPA_table
)
2680 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
2682 for (i
=0; i
<12; i
++)
2684 if (REAL_VALUES_EQUAL (r
, values_FPA
[i
]))
2685 return (codes_FPA
[i
]);
2688 if (GET_MODE (x
) == SFmode
)
2690 for (i
=25; i
<38; i
++)
2692 if (REAL_VALUES_EQUAL (r
, values_FPA
[i
]))
2693 return (codes_FPA
[i
]);
2698 for (i
=12; i
<25; i
++)
2700 if (REAL_VALUES_EQUAL (r
, values_FPA
[i
]))
2701 return (codes_FPA
[i
]);
2706 #endif /* define SUPPORT_SUN_FPA */
2708 /* A C compound statement to output to stdio stream STREAM the
2709 assembler syntax for an instruction operand X. X is an RTL
2712 CODE is a value that can be used to specify one of several ways
2713 of printing the operand. It is used when identical operands
2714 must be printed differently depending on the context. CODE
2715 comes from the `%' specification that was used to request
2716 printing of the operand. If the specification was just `%DIGIT'
2717 then CODE is 0; if the specification was `%LTR DIGIT' then CODE
2718 is the ASCII code for LTR.
2720 If X is a register, this macro should print the register's name.
2721 The names can be found in an array `reg_names' whose type is
2722 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
2724 When the machine description has a specification `%PUNCT' (a `%'
2725 followed by a punctuation character), this macro is called with
2726 a null pointer for X and the punctuation character for CODE.
2728 The m68k specific codes are:
2730 '.' for dot needed in Motorola-style opcode names.
2731 '-' for an operand pushing on the stack:
2732 sp@-, -(sp) or -(%sp) depending on the style of syntax.
2733 '+' for an operand pushing on the stack:
2734 sp@+, (sp)+ or (%sp)+ depending on the style of syntax.
2735 '@' for a reference to the top word on the stack:
2736 sp@, (sp) or (%sp) depending on the style of syntax.
2737 '#' for an immediate operand prefix (# in MIT and Motorola syntax
2738 but & in SGS syntax, $ in CRDS/UNOS syntax).
2739 '!' for the cc register (used in an `and to cc' insn).
2740 '$' for the letter `s' in an op code, but only on the 68040.
2741 '&' for the letter `d' in an op code, but only on the 68040.
2742 '/' for register prefix needed by longlong.h.
2744 'b' for byte insn (no effect, on the Sun; this is for the ISI).
2745 'd' to force memory addressing to be absolute, not relative.
2746 'f' for float insn (print a CONST_DOUBLE as a float rather than in hex)
2747 'o' for operands to go directly to output_operand_address (bypassing
2748 print_operand_address--used only for SYMBOL_REFs under TARGET_PCREL)
2749 'w' for FPA insn (print a CONST_DOUBLE as a SunFPA constant rather
2750 than directly). Second part of 'y' below.
2751 'x' for float insn (print a CONST_DOUBLE as a float rather than in hex),
2752 or print pair of registers as rx:ry.
2753 'y' for a FPA insn (print pair of registers as rx:ry). This also outputs
2754 CONST_DOUBLE's as SunFPA constant RAM registers if
2755 possible, so it should not be used except for the SunFPA.
2760 print_operand (file
, op
, letter
)
2761 FILE *file
; /* file to write to */
2762 rtx op
; /* operand to print */
2763 int letter
; /* %<letter> or 0 */
2765 #ifdef SUPPORT_SUN_FPA
2771 #if defined (MOTOROLA) && !defined (CRDS)
2772 asm_fprintf (file
, ".");
2775 else if (letter
== '#')
2777 asm_fprintf (file
, "%0I");
2779 else if (letter
== '-')
2782 asm_fprintf (file
, "-(%Rsp)");
2784 asm_fprintf (file
, "%Rsp@-");
2787 else if (letter
== '+')
2790 asm_fprintf (file
, "(%Rsp)+");
2792 asm_fprintf (file
, "%Rsp@+");
2795 else if (letter
== '@')
2798 asm_fprintf (file
, "(%Rsp)");
2800 asm_fprintf (file
, "%Rsp@");
2803 else if (letter
== '!')
2805 asm_fprintf (file
, "%Rfpcr");
2807 else if (letter
== '$')
2809 if (TARGET_68040_ONLY
)
2811 fprintf (file
, "s");
2814 else if (letter
== '&')
2816 if (TARGET_68040_ONLY
)
2818 fprintf (file
, "d");
2821 else if (letter
== '/')
2823 asm_fprintf (file
, "%R");
2825 else if (letter
== 'o')
2827 /* This is only for direct addresses with TARGET_PCREL */
2828 if (GET_CODE (op
) != MEM
|| GET_CODE (XEXP (op
, 0)) != SYMBOL_REF
2831 output_addr_const (file
, XEXP (op
, 0));
2833 else if (GET_CODE (op
) == REG
)
2835 #ifdef SUPPORT_SUN_FPA
2837 && (letter
== 'y' || letter
== 'x')
2838 && GET_MODE (op
) == DFmode
)
2840 fprintf (file
, "%s:%s", reg_names
[REGNO (op
)],
2841 reg_names
[REGNO (op
)+1]);
2847 /* Print out the second register name of a register pair.
2848 I.e., R (6) => 7. */
2849 fputs (reg_names
[REGNO (op
) + 1], file
);
2851 fputs (reg_names
[REGNO (op
)], file
);
2854 else if (GET_CODE (op
) == MEM
)
2856 output_address (XEXP (op
, 0));
2857 if (letter
== 'd' && ! TARGET_68020
2858 && CONSTANT_ADDRESS_P (XEXP (op
, 0))
2859 && !(GET_CODE (XEXP (op
, 0)) == CONST_INT
2860 && INTVAL (XEXP (op
, 0)) < 0x8000
2861 && INTVAL (XEXP (op
, 0)) >= -0x8000))
2864 fprintf (file
, ".l");
2866 fprintf (file
, ":l");
2870 #ifdef SUPPORT_SUN_FPA
2871 else if ((letter
== 'y' || letter
== 'w')
2872 && GET_CODE (op
) == CONST_DOUBLE
2873 && (i
= standard_sun_fpa_constant_p (op
)))
2875 fprintf (file
, "%%%d", i
& 0x1ff);
2878 else if (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == SFmode
)
2881 REAL_VALUE_FROM_CONST_DOUBLE (r
, op
);
2882 ASM_OUTPUT_FLOAT_OPERAND (letter
, file
, r
);
2884 else if (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == XFmode
)
2887 REAL_VALUE_FROM_CONST_DOUBLE (r
, op
);
2888 ASM_OUTPUT_LONG_DOUBLE_OPERAND (file
, r
);
2890 else if (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == DFmode
)
2893 REAL_VALUE_FROM_CONST_DOUBLE (r
, op
);
2894 ASM_OUTPUT_DOUBLE_OPERAND (file
, r
);
2898 /* Use `print_operand_address' instead of `output_addr_const'
2899 to ensure that we print relevant PIC stuff. */
2900 asm_fprintf (file
, "%0I");
2902 && (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == CONST
))
2903 print_operand_address (file
, op
);
2905 output_addr_const (file
, op
);
2910 /* A C compound statement to output to stdio stream STREAM the
2911 assembler syntax for an instruction operand that is a memory
2912 reference whose address is ADDR. ADDR is an RTL expression.
2914 Note that this contains a kludge that knows that the only reason
2915 we have an address (plus (label_ref...) (reg...)) when not generating
2916 PIC code is in the insn before a tablejump, and we know that m68k.md
2917 generates a label LInnn: on such an insn.
2919 It is possible for PIC to generate a (plus (label_ref...) (reg...))
2920 and we handle that just like we would a (plus (symbol_ref...) (reg...)).
2922 Some SGS assemblers have a bug such that "Lnnn-LInnn-2.b(pc,d0.l*2)"
2923 fails to assemble. Luckily "Lnnn(pc,d0.l*2)" produces the results
2924 we want. This difference can be accommodated by using an assembler
2925 define such "LDnnn" to be either "Lnnn-LInnn-2.b", "Lnnn", or any other
2926 string, as necessary. This is accomplished via the ASM_OUTPUT_CASE_END
2927 macro. See m68k/sgs.h for an example; for versions without the bug.
2928 Some assemblers refuse all the above solutions. The workaround is to
2929 emit "K(pc,d0.l*2)" with K being a small constant known to give the
2932 They also do not like things like "pea 1.w", so we simple leave off
2933 the .w on small constants.
2935 This routine is responsible for distinguishing between -fpic and -fPIC
2936 style relocations in an address. When generating -fpic code the
2937 offset is output in word mode (eg movel a5@(_foo:w), a0). When generating
2938 -fPIC code the offset is output in long mode (eg movel a5@(_foo:l), a0) */
2940 #ifndef ASM_OUTPUT_CASE_FETCH
2943 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2944 asm_fprintf (file, "%LLD%d(%Rpc,%s.", labelno, regname)
2946 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2947 asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.", labelno, labelno, regname)
2950 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2951 asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:", labelno, labelno, regname)
2953 #endif /* ASM_OUTPUT_CASE_FETCH */
2956 print_operand_address (file
, addr
)
2960 register rtx reg1
, reg2
, breg
, ireg
;
2963 switch (GET_CODE (addr
))
2967 fprintf (file
, "(%s)", reg_names
[REGNO (addr
)]);
2969 fprintf (file
, "%s@", reg_names
[REGNO (addr
)]);
2974 fprintf (file
, "-(%s)", reg_names
[REGNO (XEXP (addr
, 0))]);
2976 fprintf (file
, "%s@-", reg_names
[REGNO (XEXP (addr
, 0))]);
2981 fprintf (file
, "(%s)+", reg_names
[REGNO (XEXP (addr
, 0))]);
2983 fprintf (file
, "%s@+", reg_names
[REGNO (XEXP (addr
, 0))]);
2987 reg1
= reg2
= ireg
= breg
= offset
= 0;
2988 if (CONSTANT_ADDRESS_P (XEXP (addr
, 0)))
2990 offset
= XEXP (addr
, 0);
2991 addr
= XEXP (addr
, 1);
2993 else if (CONSTANT_ADDRESS_P (XEXP (addr
, 1)))
2995 offset
= XEXP (addr
, 1);
2996 addr
= XEXP (addr
, 0);
2998 if (GET_CODE (addr
) != PLUS
)
3002 else if (GET_CODE (XEXP (addr
, 0)) == SIGN_EXTEND
)
3004 reg1
= XEXP (addr
, 0);
3005 addr
= XEXP (addr
, 1);
3007 else if (GET_CODE (XEXP (addr
, 1)) == SIGN_EXTEND
)
3009 reg1
= XEXP (addr
, 1);
3010 addr
= XEXP (addr
, 0);
3012 else if (GET_CODE (XEXP (addr
, 0)) == MULT
)
3014 reg1
= XEXP (addr
, 0);
3015 addr
= XEXP (addr
, 1);
3017 else if (GET_CODE (XEXP (addr
, 1)) == MULT
)
3019 reg1
= XEXP (addr
, 1);
3020 addr
= XEXP (addr
, 0);
3022 else if (GET_CODE (XEXP (addr
, 0)) == REG
)
3024 reg1
= XEXP (addr
, 0);
3025 addr
= XEXP (addr
, 1);
3027 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
3029 reg1
= XEXP (addr
, 1);
3030 addr
= XEXP (addr
, 0);
3032 if (GET_CODE (addr
) == REG
|| GET_CODE (addr
) == MULT
3033 || GET_CODE (addr
) == SIGN_EXTEND
)
3045 #if 0 /* for OLD_INDEXING */
3046 else if (GET_CODE (addr
) == PLUS
)
3048 if (GET_CODE (XEXP (addr
, 0)) == REG
)
3050 reg2
= XEXP (addr
, 0);
3051 addr
= XEXP (addr
, 1);
3053 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
3055 reg2
= XEXP (addr
, 1);
3056 addr
= XEXP (addr
, 0);
3068 if ((reg1
&& (GET_CODE (reg1
) == SIGN_EXTEND
3069 || GET_CODE (reg1
) == MULT
))
3070 || (reg2
!= 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2
))))
3075 else if (reg1
!= 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1
)))
3080 if (ireg
!= 0 && breg
== 0 && GET_CODE (addr
) == LABEL_REF
3081 && ! (flag_pic
&& ireg
== pic_offset_table_rtx
))
3084 if (GET_CODE (ireg
) == MULT
)
3086 scale
= INTVAL (XEXP (ireg
, 1));
3087 ireg
= XEXP (ireg
, 0);
3089 if (GET_CODE (ireg
) == SIGN_EXTEND
)
3091 ASM_OUTPUT_CASE_FETCH (file
,
3092 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
3093 reg_names
[REGNO (XEXP (ireg
, 0))]);
3094 fprintf (file
, "w");
3098 ASM_OUTPUT_CASE_FETCH (file
,
3099 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
3100 reg_names
[REGNO (ireg
)]);
3101 fprintf (file
, "l");
3106 fprintf (file
, "*%d", scale
);
3108 fprintf (file
, ":%d", scale
);
3114 if (breg
!= 0 && ireg
== 0 && GET_CODE (addr
) == LABEL_REF
3115 && ! (flag_pic
&& breg
== pic_offset_table_rtx
))
3117 ASM_OUTPUT_CASE_FETCH (file
,
3118 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
3119 reg_names
[REGNO (breg
)]);
3120 fprintf (file
, "l)");
3123 if (ireg
!= 0 || breg
!= 0)
3130 if (! flag_pic
&& addr
&& GET_CODE (addr
) == LABEL_REF
)
3137 output_addr_const (file
, addr
);
3138 if (flag_pic
&& (breg
== pic_offset_table_rtx
))
3140 fprintf (file
, "@GOT");
3142 fprintf (file
, ".w");
3145 fprintf (file
, "(%s", reg_names
[REGNO (breg
)]);
3151 fprintf (file
, "%s@(", reg_names
[REGNO (breg
)]);
3154 output_addr_const (file
, addr
);
3155 if ((flag_pic
== 1) && (breg
== pic_offset_table_rtx
))
3156 fprintf (file
, ":w");
3157 if ((flag_pic
== 2) && (breg
== pic_offset_table_rtx
))
3158 fprintf (file
, ":l");
3160 if (addr
!= 0 && ireg
!= 0)
3165 if (ireg
!= 0 && GET_CODE (ireg
) == MULT
)
3167 scale
= INTVAL (XEXP (ireg
, 1));
3168 ireg
= XEXP (ireg
, 0);
3170 if (ireg
!= 0 && GET_CODE (ireg
) == SIGN_EXTEND
)
3173 fprintf (file
, "%s.w", reg_names
[REGNO (XEXP (ireg
, 0))]);
3175 fprintf (file
, "%s:w", reg_names
[REGNO (XEXP (ireg
, 0))]);
3181 fprintf (file
, "%s.l", reg_names
[REGNO (ireg
)]);
3183 fprintf (file
, "%s:l", reg_names
[REGNO (ireg
)]);
3189 fprintf (file
, "*%d", scale
);
3191 fprintf (file
, ":%d", scale
);
3197 else if (reg1
!= 0 && GET_CODE (addr
) == LABEL_REF
3198 && ! (flag_pic
&& reg1
== pic_offset_table_rtx
))
3200 ASM_OUTPUT_CASE_FETCH (file
,
3201 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
3202 reg_names
[REGNO (reg1
)]);
3203 fprintf (file
, "l)");
3206 /* FALL-THROUGH (is this really what we want?) */
3208 if (GET_CODE (addr
) == CONST_INT
3209 && INTVAL (addr
) < 0x8000
3210 && INTVAL (addr
) >= -0x8000)
3214 /* Many SGS assemblers croak on size specifiers for constants. */
3215 fprintf (file
, "%d", INTVAL (addr
));
3217 fprintf (file
, "%d.w", INTVAL (addr
));
3220 fprintf (file
, "%d:w", INTVAL (addr
));
3223 else if (GET_CODE (addr
) == CONST_INT
)
3226 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
3233 else if (TARGET_PCREL
)
3236 output_addr_const (file
, addr
);
3238 asm_fprintf (file
, ":w,%Rpc)");
3240 asm_fprintf (file
, ":l,%Rpc)");
3244 /* Special case for SYMBOL_REF if the symbol name ends in
3245 `.<letter>', this can be mistaken as a size suffix. Put
3246 the name in parentheses. */
3247 if (GET_CODE (addr
) == SYMBOL_REF
3248 && strlen (XSTR (addr
, 0)) > 2
3249 && XSTR (addr
, 0)[strlen (XSTR (addr
, 0)) - 2] == '.')
3252 output_addr_const (file
, addr
);
3256 output_addr_const (file
, addr
);
3262 /* Check for cases where a clr insns can be omitted from code using
3263 strict_low_part sets. For example, the second clrl here is not needed:
3264 clrl d0; movw a0@+,d0; use d0; clrl d0; movw a0@+; use d0; ...
3266 MODE is the mode of this STRICT_LOW_PART set. FIRST_INSN is the clear
3267 insn we are checking for redundancy. TARGET is the register set by the
3271 strict_low_part_peephole_ok (mode
, first_insn
, target
)
3272 enum machine_mode mode
;
3278 p
= prev_nonnote_insn (first_insn
);
3282 /* If it isn't an insn, then give up. */
3283 if (GET_CODE (p
) != INSN
)
3286 if (reg_set_p (target
, p
))
3288 rtx set
= single_set (p
);
3291 /* If it isn't an easy to recognize insn, then give up. */
3295 dest
= SET_DEST (set
);
3297 /* If this sets the entire target register to zero, then our
3298 first_insn is redundant. */
3299 if (rtx_equal_p (dest
, target
)
3300 && SET_SRC (set
) == const0_rtx
)
3302 else if (GET_CODE (dest
) == STRICT_LOW_PART
3303 && GET_CODE (XEXP (dest
, 0)) == REG
3304 && REGNO (XEXP (dest
, 0)) == REGNO (target
)
3305 && (GET_MODE_SIZE (GET_MODE (XEXP (dest
, 0)))
3306 <= GET_MODE_SIZE (mode
)))
3307 /* This is a strict low part set which modifies less than
3308 we are using, so it is safe. */
3314 p
= prev_nonnote_insn (p
);
3321 /* Accept integer operands in the range 0..0xffffffff. We have to check the
3322 range carefully since this predicate is used in DImode contexts. Also, we
3323 need some extra crud to make it work when hosted on 64-bit machines. */
3326 const_uint32_operand (op
, mode
)
3328 enum machine_mode mode ATTRIBUTE_UNUSED
;
3330 #if HOST_BITS_PER_WIDE_INT > 32
3331 /* All allowed constants will fit a CONST_INT. */
3332 return (GET_CODE (op
) == CONST_INT
3333 && (INTVAL (op
) >= 0 && INTVAL (op
) <= 0xffffffffL
));
3335 return ((GET_CODE (op
) == CONST_INT
&& INTVAL (op
) >= 0)
3336 || (GET_CODE (op
) == CONST_DOUBLE
&& CONST_DOUBLE_HIGH (op
) == 0));
3340 /* Accept integer operands in the range -0x80000000..0x7fffffff. We have
3341 to check the range carefully since this predicate is used in DImode
3345 const_sint32_operand (op
, mode
)
3347 enum machine_mode mode ATTRIBUTE_UNUSED
;
3349 /* All allowed constants will fit a CONST_INT. */
3350 return (GET_CODE (op
) == CONST_INT
3351 && (INTVAL (op
) >= (-0x7fffffff - 1) && INTVAL (op
) <= 0x7fffffff));
3354 /* Operand predicates for implementing asymmetric pc-relative addressing
3355 on m68k. The m68k supports pc-relative addressing (mode 7, register 2)
3356 when used as a source operand, but not as a destintation operand.
3358 We model this by restricting the meaning of the basic predicates
3359 (general_operand, memory_operand, etc) to forbid the use of this
3360 addressing mode, and then define the following predicates that permit
3361 this addressing mode. These predicates can then be used for the
3362 source operands of the appropriate instructions.
3364 n.b. While it is theoretically possible to change all machine patterns
3365 to use this addressing more where permitted by the architecture,
3366 it has only been implemented for "common" cases: SImode, HImode, and
3367 QImode operands, and only for the principle operations that would
3368 require this addressing mode: data movement and simple integer operations.
3370 In parallel with these new predicates, two new constraint letters
3371 were defined: 'S' and 'T'. 'S' is the -mpcrel analog of 'm'.
3372 'T' replaces 's' in the non-pcrel case. It is a no-op in the pcrel case.
3373 In the pcrel case 's' is only valid in combination with 'a' registers.
3374 See addsi3, subsi3, cmpsi, and movsi patterns for a better understanding
3375 of how these constraints are used.
3377 The use of these predicates is strictly optional, though patterns that
3378 don't will cause an extra reload register to be allocated where one
3381 lea (abc:w,%pc),%a0 ; need to reload address
3382 moveq &1,%d1 ; since write to pc-relative space
3383 movel %d1,%a0@ ; is not allowed
3385 lea (abc:w,%pc),%a1 ; no need to reload address here
3386 movel %a1@,%d0 ; since "movel (abc:w,%pc),%d0" is ok
3388 For more info, consult tiemann@cygnus.com.
3391 All of the ugliness with predicates and constraints is due to the
3392 simple fact that the m68k does not allow a pc-relative addressing
3393 mode as a destination. gcc does not distinguish between source and
3394 destination addresses. Hence, if we claim that pc-relative address
3395 modes are valid, e.g. GO_IF_LEGITIMATE_ADDRESS accepts them, then we
3396 end up with invalid code. To get around this problem, we left
3397 pc-relative modes as invalid addresses, and then added special
3398 predicates and constraints to accept them.
3400 A cleaner way to handle this is to modify gcc to distinguish
3401 between source and destination addresses. We can then say that
3402 pc-relative is a valid source address but not a valid destination
3403 address, and hopefully avoid a lot of the predicate and constraint
3404 hackery. Unfortunately, this would be a pretty big change. It would
3405 be a useful change for a number of ports, but there aren't any current
3406 plans to undertake this.
3408 ***************************************************************************/
3411 /* Special case of a general operand that's used as a source operand.
3412 Use this to permit reads from PC-relative memory when -mpcrel
3416 general_src_operand (op
, mode
)
3418 enum machine_mode mode
;
3421 && GET_CODE (op
) == MEM
3422 && (GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
3423 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
3424 || GET_CODE (XEXP (op
, 0)) == CONST
))
3426 return general_operand (op
, mode
);
3429 /* Special case of a nonimmediate operand that's used as a source.
3430 Use this to permit reads from PC-relative memory when -mpcrel
3434 nonimmediate_src_operand (op
, mode
)
3436 enum machine_mode mode
;
3438 if (TARGET_PCREL
&& GET_CODE (op
) == MEM
3439 && (GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
3440 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
3441 || GET_CODE (XEXP (op
, 0)) == CONST
))
3443 return nonimmediate_operand (op
, mode
);
3446 /* Special case of a memory operand that's used as a source.
3447 Use this to permit reads from PC-relative memory when -mpcrel
3451 memory_src_operand (op
, mode
)
3453 enum machine_mode mode
;
3455 if (TARGET_PCREL
&& GET_CODE (op
) == MEM
3456 && (GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
3457 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
3458 || GET_CODE (XEXP (op
, 0)) == CONST
))
3460 return memory_operand (op
, mode
);
3463 /* Predicate that accepts only a pc-relative address. This is needed
3464 because pc-relative addresses don't satisfy the predicate
3465 "general_src_operand". */
3468 pcrel_address (op
, mode
)
3470 enum machine_mode mode ATTRIBUTE_UNUSED
;
3472 return (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
3473 || GET_CODE (op
) == CONST
);
3477 output_andsi3 (operands
)
3481 if (GET_CODE (operands
[2]) == CONST_INT
3482 && (INTVAL (operands
[2]) | 0xffff) == 0xffffffff
3483 && (DATA_REG_P (operands
[0])
3484 || offsettable_memref_p (operands
[0]))
3487 if (GET_CODE (operands
[0]) != REG
)
3488 operands
[0] = adj_offsettable_operand (operands
[0], 2);
3489 operands
[2] = GEN_INT (INTVAL (operands
[2]) & 0xffff);
3490 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3492 if (operands
[2] == const0_rtx
)
3494 return "and%.w %2,%0";
3496 if (GET_CODE (operands
[2]) == CONST_INT
3497 && (logval
= exact_log2 (~ INTVAL (operands
[2]))) >= 0
3498 && (DATA_REG_P (operands
[0])
3499 || offsettable_memref_p (operands
[0])))
3501 if (DATA_REG_P (operands
[0]))
3503 operands
[1] = GEN_INT (logval
);
3507 operands
[0] = adj_offsettable_operand (operands
[0], 3 - (logval
/ 8));
3508 operands
[1] = GEN_INT (logval
% 8);
3510 /* This does not set condition codes in a standard way. */
3512 return "bclr %1,%0";
3514 return "and%.l %2,%0";
3518 output_iorsi3 (operands
)
3521 register int logval
;
3522 if (GET_CODE (operands
[2]) == CONST_INT
3523 && INTVAL (operands
[2]) >> 16 == 0
3524 && (DATA_REG_P (operands
[0])
3525 || offsettable_memref_p (operands
[0]))
3528 if (GET_CODE (operands
[0]) != REG
)
3529 operands
[0] = adj_offsettable_operand (operands
[0], 2);
3530 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3532 if (INTVAL (operands
[2]) == 0xffff)
3533 return "mov%.w %2,%0";
3534 return "or%.w %2,%0";
3536 if (GET_CODE (operands
[2]) == CONST_INT
3537 && (logval
= exact_log2 (INTVAL (operands
[2]))) >= 0
3538 && (DATA_REG_P (operands
[0])
3539 || offsettable_memref_p (operands
[0])))
3541 if (DATA_REG_P (operands
[0]))
3543 operands
[1] = GEN_INT (logval
);
3547 operands
[0] = adj_offsettable_operand (operands
[0], 3 - (logval
/ 8));
3548 operands
[1] = GEN_INT (logval
% 8);
3551 return "bset %1,%0";
3553 return "or%.l %2,%0";
3557 output_xorsi3 (operands
)
3560 register int logval
;
3561 if (GET_CODE (operands
[2]) == CONST_INT
3562 && INTVAL (operands
[2]) >> 16 == 0
3563 && (offsettable_memref_p (operands
[0]) || DATA_REG_P (operands
[0]))
3566 if (! DATA_REG_P (operands
[0]))
3567 operands
[0] = adj_offsettable_operand (operands
[0], 2);
3568 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3570 if (INTVAL (operands
[2]) == 0xffff)
3572 return "eor%.w %2,%0";
3574 if (GET_CODE (operands
[2]) == CONST_INT
3575 && (logval
= exact_log2 (INTVAL (operands
[2]))) >= 0
3576 && (DATA_REG_P (operands
[0])
3577 || offsettable_memref_p (operands
[0])))
3579 if (DATA_REG_P (operands
[0]))
3581 operands
[1] = GEN_INT (logval
);
3585 operands
[0] = adj_offsettable_operand (operands
[0], 3 - (logval
/ 8));
3586 operands
[1] = GEN_INT (logval
% 8);
3589 return "bchg %1,%0";
3591 return "eor%.l %2,%0";