1 /* Subroutines for insn-output.c for Motorola 68000 family.
2 Copyright (C) 1987, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
28 #include "hard-reg-set.h"
30 #include "insn-config.h"
31 #include "conditions.h"
33 #include "insn-attr.h"
38 #include "target-def.h"
40 /* Needed for use_return_insn. */
43 #ifdef SUPPORT_SUN_FPA
45 /* Index into this array by (register number >> 3) to find the
46 smallest class which contains that register. */
47 enum reg_class regno_reg_class
[]
48 = { DATA_REGS
, ADDR_REGS
, FP_REGS
,
49 LO_FPA_REGS
, LO_FPA_REGS
, FPA_REGS
, FPA_REGS
};
51 #endif /* defined SUPPORT_SUN_FPA */
53 /* This flag is used to communicate between movhi and ASM_OUTPUT_CASE_END,
54 if SGS_SWITCH_TABLE. */
55 int switch_table_difference_label_flag
;
57 static rtx find_addr_reg
PARAMS ((rtx
));
58 static const char *singlemove_string
PARAMS ((rtx
*));
61 /* Alignment to use for loops and jumps */
62 /* Specify power of two alignment used for loops. */
63 const char *m68k_align_loops_string
;
64 /* Specify power of two alignment used for non-loop jumps. */
65 const char *m68k_align_jumps_string
;
66 /* Specify power of two alignment used for functions. */
67 const char *m68k_align_funcs_string
;
69 /* Specify power of two alignment used for loops. */
71 /* Specify power of two alignment used for non-loop jumps. */
73 /* Specify power of two alignment used for functions. */
76 /* Nonzero if the last compare/test insn had FP operands. The
77 sCC expanders peek at this to determine what to do for the
78 68060, which has no fsCC instructions. */
79 int m68k_last_compare_had_fp_operands
;
81 /* Initialize the GCC target structure. */
83 struct gcc_target target
= TARGET_INITIALIZER
;
85 /* Sometimes certain combinations of command options do not make
86 sense on a particular target machine. You can define a macro
87 `OVERRIDE_OPTIONS' to take account of this. This macro, if
88 defined, is executed once just after all the command options have
91 Don't use this macro to turn on various extra optimizations for
92 `-O'. That is what `OPTIMIZATION_OPTIONS' is for. */
102 /* Validate -malign-loops= value, or provide default */
103 m68k_align_loops
= def_align
;
104 if (m68k_align_loops_string
)
106 i
= atoi (m68k_align_loops_string
);
107 if (i
< 1 || i
> MAX_CODE_ALIGN
)
108 error ("-malign-loops=%d is not between 1 and %d", i
, MAX_CODE_ALIGN
);
110 m68k_align_loops
= i
;
113 /* Validate -malign-jumps= value, or provide default */
114 m68k_align_jumps
= def_align
;
115 if (m68k_align_jumps_string
)
117 i
= atoi (m68k_align_jumps_string
);
118 if (i
< 1 || i
> MAX_CODE_ALIGN
)
119 error ("-malign-jumps=%d is not between 1 and %d", i
, MAX_CODE_ALIGN
);
121 m68k_align_jumps
= i
;
124 /* Validate -malign-functions= value, or provide default */
125 m68k_align_funcs
= def_align
;
126 if (m68k_align_funcs_string
)
128 i
= atoi (m68k_align_funcs_string
);
129 if (i
< 1 || i
> MAX_CODE_ALIGN
)
130 error ("-malign-functions=%d is not between 1 and %d",
133 m68k_align_funcs
= i
;
137 /* This function generates the assembly code for function entry.
138 STREAM is a stdio stream to output the code to.
139 SIZE is an int: how many units of temporary storage to allocate.
140 Refer to the array `regs_ever_live' to determine which registers
141 to save; `regs_ever_live[I]' is nonzero if register number I
142 is ever used in the function. This function is responsible for
143 knowing which registers should not be saved even if used. */
146 /* Note that the order of the bit mask for fmovem is the opposite
147 of the order for movem! */
151 output_function_prologue (stream
, size
)
156 register int mask
= 0;
157 int num_saved_regs
= 0;
158 extern char call_used_regs
[];
159 int fsize
= (size
+ 3) & -4;
160 int cfa_offset
= INCOMING_FRAME_SP_OFFSET
, cfa_store_offset
= cfa_offset
;
162 /* If the stack limit is a symbol, we can check it here,
163 before actually allocating the space. */
164 if (current_function_limit_stack
165 && GET_CODE (stack_limit_rtx
) == SYMBOL_REF
)
167 #if defined (MOTOROLA)
168 asm_fprintf (stream
, "\tcmp.l %0I%s+%d,%Rsp\n\ttrapcs\n",
169 XSTR (stack_limit_rtx
, 0), fsize
+ 4);
171 asm_fprintf (stream
, "\tcmpl %0I%s+%d,%Rsp\n\ttrapcs\n",
172 XSTR (stack_limit_rtx
, 0), fsize
+ 4);
176 if (frame_pointer_needed
)
178 if (fsize
== 0 && TARGET_68040
)
180 /* on the 68040, pea + move is faster than link.w 0 */
182 asm_fprintf (stream
, "\tpea (%s)\n\tmove.l %s,%s\n",
183 reg_names
[FRAME_POINTER_REGNUM
], reg_names
[STACK_POINTER_REGNUM
],
184 reg_names
[FRAME_POINTER_REGNUM
]);
186 asm_fprintf (stream
, "\tpea %s@\n\tmovel %s,%s\n",
187 reg_names
[FRAME_POINTER_REGNUM
], reg_names
[STACK_POINTER_REGNUM
],
188 reg_names
[FRAME_POINTER_REGNUM
]);
191 else if (fsize
< 0x8000)
194 asm_fprintf (stream
, "\tlink.w %s,%0I%d\n",
195 reg_names
[FRAME_POINTER_REGNUM
], -fsize
);
197 asm_fprintf (stream
, "\tlink %s,%0I%d\n",
198 reg_names
[FRAME_POINTER_REGNUM
], -fsize
);
201 else if (TARGET_68020
)
204 asm_fprintf (stream
, "\tlink.l %s,%0I%d\n",
205 reg_names
[FRAME_POINTER_REGNUM
], -fsize
);
207 asm_fprintf (stream
, "\tlink %s,%0I%d\n",
208 reg_names
[FRAME_POINTER_REGNUM
], -fsize
);
213 /* Adding negative number is faster on the 68040. */
215 asm_fprintf (stream
, "\tlink.w %s,%0I0\n\tadd.l %0I%d,%Rsp\n",
216 reg_names
[FRAME_POINTER_REGNUM
], -fsize
);
218 asm_fprintf (stream
, "\tlink %s,%0I0\n\taddl %0I%d,%Rsp\n",
219 reg_names
[FRAME_POINTER_REGNUM
], -fsize
);
222 if (dwarf2out_do_frame ())
225 l
= (char *) dwarf2out_cfi_label ();
226 cfa_store_offset
+= 4;
227 cfa_offset
= cfa_store_offset
;
228 dwarf2out_reg_save (l
, FRAME_POINTER_REGNUM
, -cfa_store_offset
);
229 dwarf2out_def_cfa (l
, FRAME_POINTER_REGNUM
, cfa_offset
);
230 cfa_store_offset
+= fsize
;
235 if (fsize
+ 4 < 0x8000)
242 /* asm_fprintf() cannot handle %. */
244 asm_fprintf (stream
, "\tsubq.w %0I%d,%Rsp\n", fsize
+ 4);
246 asm_fprintf (stream
, "\tsubqw %0I%d,%Rsp\n", fsize
+ 4);
251 /* asm_fprintf() cannot handle %. */
253 asm_fprintf (stream
, "\tsubq.l %0I%d,%Rsp\n", fsize
+ 4);
255 asm_fprintf (stream
, "\tsubql %0I%d,%Rsp\n", fsize
+ 4);
259 else if (fsize
+ 4 <= 16 && TARGET_CPU32
)
261 /* On the CPU32 it is faster to use two subqw instructions to
262 subtract a small integer (8 < N <= 16) to a register. */
263 /* asm_fprintf() cannot handle %. */
265 asm_fprintf (stream
, "\tsubq.w %0I8,%Rsp\n\tsubq.w %0I%d,%Rsp\n",
268 asm_fprintf (stream
, "\tsubqw %0I8,%Rsp\n\tsubqw %0I%d,%Rsp\n",
273 #endif /* not NO_ADDSUB_Q */
276 /* Adding negative number is faster on the 68040. */
277 /* asm_fprintf() cannot handle %. */
279 asm_fprintf (stream
, "\tadd.w %0I%d,%Rsp\n", - (fsize
+ 4));
281 asm_fprintf (stream
, "\taddw %0I%d,%Rsp\n", - (fsize
+ 4));
287 asm_fprintf (stream
, "\tlea (%d,%Rsp),%Rsp\n", - (fsize
+ 4));
289 asm_fprintf (stream
, "\tlea %Rsp@(%d),%Rsp\n", - (fsize
+ 4));
295 /* asm_fprintf() cannot handle %. */
297 asm_fprintf (stream
, "\tadd.l %0I%d,%Rsp\n", - (fsize
+ 4));
299 asm_fprintf (stream
, "\taddl %0I%d,%Rsp\n", - (fsize
+ 4));
302 if (dwarf2out_do_frame ())
304 cfa_store_offset
+= fsize
;
305 cfa_offset
= cfa_store_offset
;
306 dwarf2out_def_cfa ("", STACK_POINTER_REGNUM
, cfa_offset
);
309 #ifdef SUPPORT_SUN_FPA
310 for (regno
= 24; regno
< 56; regno
++)
311 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
314 asm_fprintf (stream
, "\tfpmovd %s,-(%Rsp)\n",
317 asm_fprintf (stream
, "\tfpmoved %s,%Rsp@-\n",
320 if (dwarf2out_do_frame ())
322 char *l
= dwarf2out_cfi_label ();
324 cfa_store_offset
+= 8;
325 if (! frame_pointer_needed
)
327 cfa_offset
= cfa_store_offset
;
328 dwarf2out_def_cfa (l
, STACK_POINTER_REGNUM
, cfa_offset
);
330 dwarf2out_reg_save (l
, regno
, -cfa_store_offset
);
336 for (regno
= 16; regno
< 24; regno
++)
337 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
339 mask
|= 1 << (regno
- 16);
342 if ((mask
& 0xff) != 0)
345 asm_fprintf (stream
, "\tfmovm %0I0x%x,-(%Rsp)\n", mask
& 0xff);
347 asm_fprintf (stream
, "\tfmovem %0I0x%x,%Rsp@-\n", mask
& 0xff);
349 if (dwarf2out_do_frame ())
351 char *l
= (char *) dwarf2out_cfi_label ();
354 cfa_store_offset
+= num_saved_regs
* 12;
355 if (! frame_pointer_needed
)
357 cfa_offset
= cfa_store_offset
;
358 dwarf2out_def_cfa (l
, STACK_POINTER_REGNUM
, cfa_offset
);
360 for (regno
= 16, n_regs
= 0; regno
< 24; regno
++)
361 if (mask
& (1 << (regno
- 16)))
362 dwarf2out_reg_save (l
, regno
,
363 -cfa_store_offset
+ n_regs
++ * 12);
369 for (regno
= 0; regno
< 16; regno
++)
370 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
372 mask
|= 1 << (15 - regno
);
375 if (frame_pointer_needed
)
377 mask
&= ~ (1 << (15 - FRAME_POINTER_REGNUM
));
380 if (flag_pic
&& current_function_uses_pic_offset_table
)
382 mask
|= 1 << (15 - PIC_OFFSET_TABLE_REGNUM
);
389 asm_fprintf (stream
, "\ttstl %d(%Rsp)\n", NEED_PROBE
- num_saved_regs
* 4);
391 asm_fprintf (stream
, "\ttst.l %d(%Rsp)\n", NEED_PROBE
- num_saved_regs
* 4);
394 asm_fprintf (stream
, "\ttstl %Rsp@(%d)\n", NEED_PROBE
- num_saved_regs
* 4);
398 /* If the stack limit is not a symbol, check it here.
399 This has the disadvantage that it may be too late... */
400 if (current_function_limit_stack
)
402 if (REG_P (stack_limit_rtx
))
404 #if defined (MOTOROLA)
405 asm_fprintf (stream
, "\tcmp.l %s,%Rsp\n\ttrapcs\n",
406 reg_names
[REGNO (stack_limit_rtx
)]);
408 asm_fprintf (stream
, "\tcmpl %s,%Rsp\n\ttrapcs\n",
409 reg_names
[REGNO (stack_limit_rtx
)]);
412 else if (GET_CODE (stack_limit_rtx
) != SYMBOL_REF
)
413 warning ("stack limit expression is not supported");
416 if (num_saved_regs
<= 2)
418 /* Store each separately in the same order moveml uses.
419 Using two movel instructions instead of a single moveml
420 is about 15% faster for the 68020 and 68030 at no expense
425 /* Undo the work from above. */
426 for (i
= 0; i
< 16; i
++)
431 "\t%Omove.l %s,-(%Rsp)\n",
433 "\tmovel %s,%Rsp@-\n",
436 if (dwarf2out_do_frame ())
438 char *l
= (char *) dwarf2out_cfi_label ();
440 cfa_store_offset
+= 4;
441 if (! frame_pointer_needed
)
443 cfa_offset
= cfa_store_offset
;
444 dwarf2out_def_cfa (l
, STACK_POINTER_REGNUM
, cfa_offset
);
446 dwarf2out_reg_save (l
, 15 - i
, -cfa_store_offset
);
454 /* The coldfire does not support the predecrement form of the
455 movml instruction, so we must adjust the stack pointer and
456 then use the plain address register indirect mode. We also
457 have to invert the register save mask to use the new mode.
459 FIXME: if num_saved_regs was calculated earlier, we could
460 combine the stack pointer adjustment with any adjustment
461 done when the initial stack frame is created. This would
462 save an instruction */
467 for (i
= 0; i
< 16; i
++)
469 newmask
|= (1 << (15-i
));
472 asm_fprintf (stream
, "\tlea (%d,%Rsp),%Rsp\n", -num_saved_regs
*4);
473 asm_fprintf (stream
, "\tmovm.l %0I0x%x,(%Rsp)\n", newmask
);
475 asm_fprintf (stream
, "\tlea %Rsp@(%d),%Rsp\n", -num_saved_regs
*4);
476 asm_fprintf (stream
, "\tmoveml %0I0x%x,%Rsp@\n", newmask
);
482 asm_fprintf (stream
, "\tmovm.l %0I0x%x,-(%Rsp)\n", mask
);
484 asm_fprintf (stream
, "\tmoveml %0I0x%x,%Rsp@-\n", mask
);
487 if (dwarf2out_do_frame ())
489 char *l
= (char *) dwarf2out_cfi_label ();
492 cfa_store_offset
+= num_saved_regs
* 4;
493 if (! frame_pointer_needed
)
495 cfa_offset
= cfa_store_offset
;
496 dwarf2out_def_cfa (l
, STACK_POINTER_REGNUM
, cfa_offset
);
498 for (regno
= 0, n_regs
= 0; regno
< 16; regno
++)
499 if (mask
& (1 << (15 - regno
)))
500 dwarf2out_reg_save (l
, regno
,
501 -cfa_store_offset
+ n_regs
++ * 4);
504 if (flag_pic
&& current_function_uses_pic_offset_table
)
507 asm_fprintf (stream
, "\t%Olea (%Rpc, %U_GLOBAL_OFFSET_TABLE_@GOTPC), %s\n",
508 reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
510 asm_fprintf (stream
, "\tmovel %0I__GLOBAL_OFFSET_TABLE_, %s\n",
511 reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
512 asm_fprintf (stream
, "\tlea %Rpc@(0,%s:l),%s\n",
513 reg_names
[PIC_OFFSET_TABLE_REGNUM
],
514 reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
519 /* Return true if this function's epilogue can be output as RTL. */
526 if (!reload_completed
|| frame_pointer_needed
|| get_frame_size () != 0)
529 /* Copied from output_function_epilogue (). We should probably create a
530 separate layout routine to perform the common work. */
532 for (regno
= 0 ; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
533 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
536 if (flag_pic
&& current_function_uses_pic_offset_table
)
542 /* This function generates the assembly code for function exit,
543 on machines that need it. Args are same as for FUNCTION_PROLOGUE.
545 The function epilogue should not depend on the current stack pointer!
546 It should use the frame pointer only, if there is a frame pointer.
547 This is mandatory because of alloca; we also take advantage of it to
548 omit stack adjustments before returning. */
551 output_function_epilogue (stream
, size
)
556 register int mask
, fmask
;
558 int offset
, foffset
, fpoffset
;
559 extern char call_used_regs
[];
560 int fsize
= (size
+ 3) & -4;
562 rtx insn
= get_last_insn ();
563 int restore_from_sp
= 0;
565 /* If the last insn was a BARRIER, we don't have to write any code. */
566 if (GET_CODE (insn
) == NOTE
)
567 insn
= prev_nonnote_insn (insn
);
568 if (insn
&& GET_CODE (insn
) == BARRIER
)
570 /* Output just a no-op so that debuggers don't get confused
571 about which function the pc is in at this address. */
572 asm_fprintf (stream
, "\tnop\n");
576 #ifdef FUNCTION_BLOCK_PROFILER_EXIT
577 if (profile_block_flag
== 2)
579 FUNCTION_BLOCK_PROFILER_EXIT (stream
);
583 #ifdef FUNCTION_EXTRA_EPILOGUE
584 FUNCTION_EXTRA_EPILOGUE (stream
, size
);
586 nregs
= 0; fmask
= 0; fpoffset
= 0;
587 #ifdef SUPPORT_SUN_FPA
588 for (regno
= 24 ; regno
< 56 ; regno
++)
589 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
591 fpoffset
= nregs
* 8;
596 for (regno
= 16; regno
< 24; regno
++)
597 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
600 fmask
|= 1 << (23 - regno
);
603 foffset
= fpoffset
+ nregs
* 12;
605 if (frame_pointer_needed
)
606 regs_ever_live
[FRAME_POINTER_REGNUM
] = 0;
607 for (regno
= 0; regno
< 16; regno
++)
608 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
613 if (flag_pic
&& current_function_uses_pic_offset_table
)
616 mask
|= 1 << PIC_OFFSET_TABLE_REGNUM
;
618 offset
= foffset
+ nregs
* 4;
619 /* FIXME : leaf_function_p below is too strong.
620 What we really need to know there is if there could be pending
621 stack adjustment needed at that point. */
622 restore_from_sp
= ! frame_pointer_needed
623 || (! current_function_calls_alloca
&& leaf_function_p ());
624 if (offset
+ fsize
>= 0x8000
626 && (mask
|| fmask
|| fpoffset
))
629 asm_fprintf (stream
, "\t%Omove.l %0I%d,%Ra1\n", -fsize
);
631 asm_fprintf (stream
, "\tmovel %0I%d,%Ra1\n", -fsize
);
635 if (TARGET_5200
|| nregs
<= 2)
637 /* Restore each separately in the same order moveml does.
638 Using two movel instructions instead of a single moveml
639 is about 15% faster for the 68020 and 68030 at no expense
644 /* Undo the work from above. */
645 for (i
= 0; i
< 16; i
++)
651 asm_fprintf (stream
, "\t%Omove.l -%d(%s,%Ra1.l),%s\n",
653 reg_names
[FRAME_POINTER_REGNUM
],
656 asm_fprintf (stream
, "\tmovel %s@(-%d,%Ra1:l),%s\n",
657 reg_names
[FRAME_POINTER_REGNUM
],
658 offset
+ fsize
, reg_names
[i
]);
661 else if (restore_from_sp
)
664 asm_fprintf (stream
, "\t%Omove.l (%Rsp)+,%s\n",
667 asm_fprintf (stream
, "\tmovel %Rsp@+,%s\n",
674 asm_fprintf (stream
, "\t%Omove.l -%d(%s),%s\n",
676 reg_names
[FRAME_POINTER_REGNUM
],
679 asm_fprintf (stream
, "\tmovel %s@(-%d),%s\n",
680 reg_names
[FRAME_POINTER_REGNUM
],
681 offset
+ fsize
, reg_names
[i
]);
692 asm_fprintf (stream
, "\tmovm.l -%d(%s,%Ra1.l),%0I0x%x\n",
694 reg_names
[FRAME_POINTER_REGNUM
],
697 asm_fprintf (stream
, "\tmoveml %s@(-%d,%Ra1:l),%0I0x%x\n",
698 reg_names
[FRAME_POINTER_REGNUM
],
699 offset
+ fsize
, mask
);
702 else if (restore_from_sp
)
705 asm_fprintf (stream
, "\tmovm.l (%Rsp)+,%0I0x%x\n", mask
);
707 asm_fprintf (stream
, "\tmoveml %Rsp@+,%0I0x%x\n", mask
);
713 asm_fprintf (stream
, "\tmovm.l -%d(%s),%0I0x%x\n",
715 reg_names
[FRAME_POINTER_REGNUM
],
718 asm_fprintf (stream
, "\tmoveml %s@(-%d),%0I0x%x\n",
719 reg_names
[FRAME_POINTER_REGNUM
],
720 offset
+ fsize
, mask
);
729 asm_fprintf (stream
, "\tfmovm -%d(%s,%Ra1.l),%0I0x%x\n",
731 reg_names
[FRAME_POINTER_REGNUM
],
734 asm_fprintf (stream
, "\tfmovem %s@(-%d,%Ra1:l),%0I0x%x\n",
735 reg_names
[FRAME_POINTER_REGNUM
],
736 foffset
+ fsize
, fmask
);
739 else if (restore_from_sp
)
742 asm_fprintf (stream
, "\tfmovm (%Rsp)+,%0I0x%x\n", fmask
);
744 asm_fprintf (stream
, "\tfmovem %Rsp@+,%0I0x%x\n", fmask
);
750 asm_fprintf (stream
, "\tfmovm -%d(%s),%0I0x%x\n",
752 reg_names
[FRAME_POINTER_REGNUM
],
755 asm_fprintf (stream
, "\tfmovem %s@(-%d),%0I0x%x\n",
756 reg_names
[FRAME_POINTER_REGNUM
],
757 foffset
+ fsize
, fmask
);
762 for (regno
= 55; regno
>= 24; regno
--)
763 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
768 asm_fprintf (stream
, "\tfpmovd -%d(%s,%Ra1.l), %s\n",
770 reg_names
[FRAME_POINTER_REGNUM
],
773 asm_fprintf (stream
, "\tfpmoved %s@(-%d,%Ra1:l), %s\n",
774 reg_names
[FRAME_POINTER_REGNUM
],
775 fpoffset
+ fsize
, reg_names
[regno
]);
778 else if (restore_from_sp
)
781 asm_fprintf (stream
, "\tfpmovd (%Rsp)+,%s\n",
784 asm_fprintf (stream
, "\tfpmoved %Rsp@+, %s\n",
791 asm_fprintf (stream
, "\tfpmovd -%d(%s), %s\n",
793 reg_names
[FRAME_POINTER_REGNUM
],
796 asm_fprintf (stream
, "\tfpmoved %s@(-%d), %s\n",
797 reg_names
[FRAME_POINTER_REGNUM
],
798 fpoffset
+ fsize
, reg_names
[regno
]);
803 if (frame_pointer_needed
)
804 fprintf (stream
, "\tunlk %s\n",
805 reg_names
[FRAME_POINTER_REGNUM
]);
814 asm_fprintf (stream
, "\taddq.w %0I%d,%Rsp\n", fsize
+ 4);
816 asm_fprintf (stream
, "\taddqw %0I%d,%Rsp\n", fsize
+ 4);
822 asm_fprintf (stream
, "\taddq.l %0I%d,%Rsp\n", fsize
+ 4);
824 asm_fprintf (stream
, "\taddql %0I%d,%Rsp\n", fsize
+ 4);
828 else if (fsize
+ 4 <= 16 && TARGET_CPU32
)
830 /* On the CPU32 it is faster to use two addqw instructions to
831 add a small integer (8 < N <= 16) to a register. */
832 /* asm_fprintf() cannot handle %. */
834 asm_fprintf (stream
, "\taddq.w %0I8,%Rsp\n\taddq.w %0I%d,%Rsp\n",
837 asm_fprintf (stream
, "\taddqw %0I8,%Rsp\n\taddqw %0I%d,%Rsp\n",
842 #endif /* not NO_ADDSUB_Q */
843 if (fsize
+ 4 < 0x8000)
847 /* asm_fprintf() cannot handle %. */
849 asm_fprintf (stream
, "\tadd.w %0I%d,%Rsp\n", fsize
+ 4);
851 asm_fprintf (stream
, "\taddw %0I%d,%Rsp\n", fsize
+ 4);
857 asm_fprintf (stream
, "\tlea (%d,%Rsp),%Rsp\n", fsize
+ 4);
859 asm_fprintf (stream
, "\tlea %Rsp@(%d),%Rsp\n", fsize
+ 4);
865 /* asm_fprintf() cannot handle %. */
867 asm_fprintf (stream
, "\tadd.l %0I%d,%Rsp\n", fsize
+ 4);
869 asm_fprintf (stream
, "\taddl %0I%d,%Rsp\n", fsize
+ 4);
873 if (current_function_pops_args
)
874 asm_fprintf (stream
, "\trtd %0I%d\n", current_function_pops_args
);
876 fprintf (stream
, "\trts\n");
879 /* Similar to general_operand, but exclude stack_pointer_rtx. */
882 not_sp_operand (op
, mode
)
884 enum machine_mode mode
;
886 return op
!= stack_pointer_rtx
&& general_operand (op
, mode
);
889 /* Return TRUE if X is a valid comparison operator for the dbcc
892 Note it rejects floating point comparison operators.
893 (In the future we could use Fdbcc).
895 It also rejects some comparisons when CC_NO_OVERFLOW is set. */
898 valid_dbcc_comparison_p (x
, mode
)
900 enum machine_mode mode ATTRIBUTE_UNUSED
;
902 switch (GET_CODE (x
))
904 case EQ
: case NE
: case GTU
: case LTU
:
908 /* Reject some when CC_NO_OVERFLOW is set. This may be over
910 case GT
: case LT
: case GE
: case LE
:
911 return ! (cc_prev_status
.flags
& CC_NO_OVERFLOW
);
917 /* Return non-zero if flags are currently in the 68881 flag register. */
921 /* We could add support for these in the future */
922 return cc_status
.flags
& CC_IN_68881
;
925 /* Output a dbCC; jCC sequence. Note we do not handle the
926 floating point version of this sequence (Fdbcc). We also
927 do not handle alternative conditions when CC_NO_OVERFLOW is
928 set. It is assumed that valid_dbcc_comparison_p and flags_in_68881 will
929 kick those out before we get here. */
932 output_dbcc_and_branch (operands
)
935 switch (GET_CODE (operands
[3]))
939 output_asm_insn ("dbeq %0,%l1\n\tjbeq %l2", operands
);
941 output_asm_insn ("dbeq %0,%l1\n\tjeq %l2", operands
);
947 output_asm_insn ("dbne %0,%l1\n\tjbne %l2", operands
);
949 output_asm_insn ("dbne %0,%l1\n\tjne %l2", operands
);
955 output_asm_insn ("dbgt %0,%l1\n\tjbgt %l2", operands
);
957 output_asm_insn ("dbgt %0,%l1\n\tjgt %l2", operands
);
963 output_asm_insn ("dbhi %0,%l1\n\tjbhi %l2", operands
);
965 output_asm_insn ("dbhi %0,%l1\n\tjhi %l2", operands
);
971 output_asm_insn ("dblt %0,%l1\n\tjblt %l2", operands
);
973 output_asm_insn ("dblt %0,%l1\n\tjlt %l2", operands
);
979 output_asm_insn ("dbcs %0,%l1\n\tjbcs %l2", operands
);
981 output_asm_insn ("dbcs %0,%l1\n\tjcs %l2", operands
);
987 output_asm_insn ("dbge %0,%l1\n\tjbge %l2", operands
);
989 output_asm_insn ("dbge %0,%l1\n\tjge %l2", operands
);
995 output_asm_insn ("dbcc %0,%l1\n\tjbcc %l2", operands
);
997 output_asm_insn ("dbcc %0,%l1\n\tjcc %l2", operands
);
1003 output_asm_insn ("dble %0,%l1\n\tjble %l2", operands
);
1005 output_asm_insn ("dble %0,%l1\n\tjle %l2", operands
);
1011 output_asm_insn ("dbls %0,%l1\n\tjbls %l2", operands
);
1013 output_asm_insn ("dbls %0,%l1\n\tjls %l2", operands
);
1021 /* If the decrement is to be done in SImode, then we have
1022 to compensate for the fact that dbcc decrements in HImode. */
1023 switch (GET_MODE (operands
[0]))
1027 output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjbpl %l1", operands
);
1029 output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjpl %l1", operands
);
1042 output_scc_di(op
, operand1
, operand2
, dest
)
1049 enum rtx_code op_code
= GET_CODE (op
);
1051 /* This does not produce a usefull cc. */
1054 /* The m68k cmp.l instruction requires operand1 to be a reg as used
1055 below. Swap the operands and change the op if these requirements
1056 are not fulfilled. */
1057 if (GET_CODE (operand2
) == REG
&& GET_CODE (operand1
) != REG
)
1061 operand1
= operand2
;
1063 op_code
= swap_condition (op_code
);
1065 loperands
[0] = operand1
;
1066 if (GET_CODE (operand1
) == REG
)
1067 loperands
[1] = gen_rtx_REG (SImode
, REGNO (operand1
) + 1);
1069 loperands
[1] = adj_offsettable_operand (operand1
, 4);
1070 if (operand2
!= const0_rtx
)
1072 loperands
[2] = operand2
;
1073 if (GET_CODE (operand2
) == REG
)
1074 loperands
[3] = gen_rtx_REG (SImode
, REGNO (operand2
) + 1);
1076 loperands
[3] = adj_offsettable_operand (operand2
, 4);
1078 loperands
[4] = gen_label_rtx();
1079 if (operand2
!= const0_rtx
)
1082 #ifdef SGS_CMP_ORDER
1083 output_asm_insn ("cmp%.l %0,%2\n\tjbne %l4\n\tcmp%.l %1,%3", loperands
);
1085 output_asm_insn ("cmp%.l %2,%0\n\tjbne %l4\n\tcmp%.l %3,%1", loperands
);
1088 #ifdef SGS_CMP_ORDER
1089 output_asm_insn ("cmp%.l %0,%2\n\tjne %l4\n\tcmp%.l %1,%3", loperands
);
1091 output_asm_insn ("cmp%.l %2,%0\n\tjne %l4\n\tcmp%.l %3,%1", loperands
);
1097 if (TARGET_68020
|| TARGET_5200
|| ! ADDRESS_REG_P (loperands
[0]))
1098 output_asm_insn ("tst%.l %0", loperands
);
1101 #ifdef SGS_CMP_ORDER
1102 output_asm_insn ("cmp%.w %0,%#0", loperands
);
1104 output_asm_insn ("cmp%.w %#0,%0", loperands
);
1109 output_asm_insn ("jbne %l4", loperands
);
1111 output_asm_insn ("jne %l4", loperands
);
1114 if (TARGET_68020
|| TARGET_5200
|| ! ADDRESS_REG_P (loperands
[1]))
1115 output_asm_insn ("tst%.l %1", loperands
);
1118 #ifdef SGS_CMP_ORDER
1119 output_asm_insn ("cmp%.w %1,%#0", loperands
);
1121 output_asm_insn ("cmp%.w %#0,%1", loperands
);
1126 loperands
[5] = dest
;
1131 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1132 CODE_LABEL_NUMBER (loperands
[4]));
1133 output_asm_insn ("seq %5", loperands
);
1137 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1138 CODE_LABEL_NUMBER (loperands
[4]));
1139 output_asm_insn ("sne %5", loperands
);
1143 loperands
[6] = gen_label_rtx();
1145 output_asm_insn ("shi %5\n\tjbra %l6", loperands
);
1147 output_asm_insn ("shi %5\n\tjra %l6", loperands
);
1149 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1150 CODE_LABEL_NUMBER (loperands
[4]));
1151 output_asm_insn ("sgt %5", loperands
);
1152 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1153 CODE_LABEL_NUMBER (loperands
[6]));
1157 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1158 CODE_LABEL_NUMBER (loperands
[4]));
1159 output_asm_insn ("shi %5", loperands
);
1163 loperands
[6] = gen_label_rtx();
1165 output_asm_insn ("scs %5\n\tjbra %l6", loperands
);
1167 output_asm_insn ("scs %5\n\tjra %l6", loperands
);
1169 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1170 CODE_LABEL_NUMBER (loperands
[4]));
1171 output_asm_insn ("slt %5", loperands
);
1172 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1173 CODE_LABEL_NUMBER (loperands
[6]));
1177 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1178 CODE_LABEL_NUMBER (loperands
[4]));
1179 output_asm_insn ("scs %5", loperands
);
1183 loperands
[6] = gen_label_rtx();
1185 output_asm_insn ("scc %5\n\tjbra %l6", loperands
);
1187 output_asm_insn ("scc %5\n\tjra %l6", loperands
);
1189 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1190 CODE_LABEL_NUMBER (loperands
[4]));
1191 output_asm_insn ("sge %5", loperands
);
1192 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1193 CODE_LABEL_NUMBER (loperands
[6]));
1197 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1198 CODE_LABEL_NUMBER (loperands
[4]));
1199 output_asm_insn ("scc %5", loperands
);
1203 loperands
[6] = gen_label_rtx();
1205 output_asm_insn ("sls %5\n\tjbra %l6", loperands
);
1207 output_asm_insn ("sls %5\n\tjra %l6", loperands
);
1209 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1210 CODE_LABEL_NUMBER (loperands
[4]));
1211 output_asm_insn ("sle %5", loperands
);
1212 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1213 CODE_LABEL_NUMBER (loperands
[6]));
1217 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1218 CODE_LABEL_NUMBER (loperands
[4]));
1219 output_asm_insn ("sls %5", loperands
);
1229 output_btst (operands
, countop
, dataop
, insn
, signpos
)
1231 rtx countop
, dataop
;
1235 operands
[0] = countop
;
1236 operands
[1] = dataop
;
1238 if (GET_CODE (countop
) == CONST_INT
)
1240 register int count
= INTVAL (countop
);
1241 /* If COUNT is bigger than size of storage unit in use,
1242 advance to the containing unit of same size. */
1243 if (count
> signpos
)
1245 int offset
= (count
& ~signpos
) / 8;
1246 count
= count
& signpos
;
1247 operands
[1] = dataop
= adj_offsettable_operand (dataop
, offset
);
1249 if (count
== signpos
)
1250 cc_status
.flags
= CC_NOT_POSITIVE
| CC_Z_IN_NOT_N
;
1252 cc_status
.flags
= CC_NOT_NEGATIVE
| CC_Z_IN_NOT_N
;
1254 /* These three statements used to use next_insns_test_no...
1255 but it appears that this should do the same job. */
1257 && next_insn_tests_no_inequality (insn
))
1260 && next_insn_tests_no_inequality (insn
))
1263 && next_insn_tests_no_inequality (insn
))
1266 cc_status
.flags
= CC_NOT_NEGATIVE
;
1268 return "btst %0,%1";
1271 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
1272 reference and a constant. */
1275 symbolic_operand (op
, mode
)
1277 enum machine_mode mode ATTRIBUTE_UNUSED
;
1279 switch (GET_CODE (op
))
1287 return ((GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
1288 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
)
1289 && GET_CODE (XEXP (op
, 1)) == CONST_INT
);
1291 #if 0 /* Deleted, with corresponding change in m68k.h,
1292 so as to fit the specs. No CONST_DOUBLE is ever symbolic. */
1294 return GET_MODE (op
) == mode
;
1302 /* Check for sign_extend or zero_extend. Used for bit-count operands. */
1305 extend_operator(x
, mode
)
1307 enum machine_mode mode
;
1309 if (mode
!= VOIDmode
&& GET_MODE(x
) != mode
)
1311 switch (GET_CODE(x
))
1322 /* Legitimize PIC addresses. If the address is already
1323 position-independent, we return ORIG. Newly generated
1324 position-independent addresses go to REG. If we need more
1325 than one register, we lose.
1327 An address is legitimized by making an indirect reference
1328 through the Global Offset Table with the name of the symbol
1331 The assembler and linker are responsible for placing the
1332 address of the symbol in the GOT. The function prologue
1333 is responsible for initializing a5 to the starting address
1336 The assembler is also responsible for translating a symbol name
1337 into a constant displacement from the start of the GOT.
1339 A quick example may make things a little clearer:
1341 When not generating PIC code to store the value 12345 into _foo
1342 we would generate the following code:
1346 When generating PIC two transformations are made. First, the compiler
1347 loads the address of foo into a register. So the first transformation makes:
1352 The code in movsi will intercept the lea instruction and call this
1353 routine which will transform the instructions into:
1355 movel a5@(_foo:w), a0
1359 That (in a nutshell) is how *all* symbol and label references are
1363 legitimize_pic_address (orig
, mode
, reg
)
1365 enum machine_mode mode ATTRIBUTE_UNUSED
;
1369 /* First handle a simple SYMBOL_REF or LABEL_REF */
1370 if (GET_CODE (orig
) == SYMBOL_REF
|| GET_CODE (orig
) == LABEL_REF
)
1375 pic_ref
= gen_rtx_MEM (Pmode
,
1376 gen_rtx_PLUS (Pmode
,
1377 pic_offset_table_rtx
, orig
));
1378 current_function_uses_pic_offset_table
= 1;
1379 RTX_UNCHANGING_P (pic_ref
) = 1;
1380 emit_move_insn (reg
, pic_ref
);
1383 else if (GET_CODE (orig
) == CONST
)
1387 /* Make sure this is CONST has not already been legitimized */
1388 if (GET_CODE (XEXP (orig
, 0)) == PLUS
1389 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
1395 /* legitimize both operands of the PLUS */
1396 if (GET_CODE (XEXP (orig
, 0)) == PLUS
)
1398 base
= legitimize_pic_address (XEXP (XEXP (orig
, 0), 0), Pmode
, reg
);
1399 orig
= legitimize_pic_address (XEXP (XEXP (orig
, 0), 1), Pmode
,
1400 base
== reg
? 0 : reg
);
1404 if (GET_CODE (orig
) == CONST_INT
)
1405 return plus_constant_for_output (base
, INTVAL (orig
));
1406 pic_ref
= gen_rtx_PLUS (Pmode
, base
, orig
);
1407 /* Likewise, should we set special REG_NOTEs here? */
1413 typedef enum { MOVL
, SWAP
, NEGW
, NOTW
, NOTB
, MOVQ
} CONST_METHOD
;
1415 static CONST_METHOD const_method
PARAMS ((rtx
));
1417 #define USE_MOVQ(i) ((unsigned)((i) + 128) <= 255)
1420 const_method (constant
)
1426 i
= INTVAL (constant
);
1430 /* The Coldfire doesn't have byte or word operations. */
1431 /* FIXME: This may not be useful for the m68060 either */
1434 /* if -256 < N < 256 but N is not in range for a moveq
1435 N^ff will be, so use moveq #N^ff, dreg; not.b dreg. */
1436 if (USE_MOVQ (i
^ 0xff))
1438 /* Likewise, try with not.w */
1439 if (USE_MOVQ (i
^ 0xffff))
1441 /* This is the only value where neg.w is useful */
1444 /* Try also with swap */
1446 if (USE_MOVQ ((u
>> 16) | (u
<< 16)))
1449 /* Otherwise, use move.l */
1454 const_int_cost (constant
)
1457 switch (const_method (constant
))
1460 /* Constants between -128 and 127 are cheap due to moveq */
1466 /* Constants easily generated by moveq + not.b/not.w/neg.w/swap */
1476 output_move_const_into_data_reg (operands
)
1481 i
= INTVAL (operands
[1]);
1482 switch (const_method (operands
[1]))
1485 #if defined (MOTOROLA) && !defined (CRDS)
1486 return "moveq%.l %1,%0";
1488 return "moveq %1,%0";
1491 operands
[1] = GEN_INT (i
^ 0xff);
1492 #if defined (MOTOROLA) && !defined (CRDS)
1493 return "moveq%.l %1,%0\n\tnot%.b %0";
1495 return "moveq %1,%0\n\tnot%.b %0";
1498 operands
[1] = GEN_INT (i
^ 0xffff);
1499 #if defined (MOTOROLA) && !defined (CRDS)
1500 return "moveq%.l %1,%0\n\tnot%.w %0";
1502 return "moveq %1,%0\n\tnot%.w %0";
1505 #if defined (MOTOROLA) && !defined (CRDS)
1506 return "moveq%.l %#-128,%0\n\tneg%.w %0";
1508 return "moveq %#-128,%0\n\tneg%.w %0";
1514 operands
[1] = GEN_INT ((u
<< 16) | (u
>> 16));
1515 #if defined (MOTOROLA) && !defined (CRDS)
1516 return "moveq%.l %1,%0\n\tswap %0";
1518 return "moveq %1,%0\n\tswap %0";
1522 return "move%.l %1,%0";
1529 output_move_simode_const (operands
)
1532 if (operands
[1] == const0_rtx
1533 && (DATA_REG_P (operands
[0])
1534 || GET_CODE (operands
[0]) == MEM
)
1535 /* clr insns on 68000 read before writing.
1536 This isn't so on the 68010, but we have no TARGET_68010. */
1537 && ((TARGET_68020
|| TARGET_5200
)
1538 || !(GET_CODE (operands
[0]) == MEM
1539 && MEM_VOLATILE_P (operands
[0]))))
1541 else if (operands
[1] == const0_rtx
1542 && ADDRESS_REG_P (operands
[0]))
1543 return "sub%.l %0,%0";
1544 else if (DATA_REG_P (operands
[0]))
1545 return output_move_const_into_data_reg (operands
);
1546 else if (ADDRESS_REG_P (operands
[0])
1547 && INTVAL (operands
[1]) < 0x8000
1548 && INTVAL (operands
[1]) >= -0x8000)
1549 return "move%.w %1,%0";
1550 else if (GET_CODE (operands
[0]) == MEM
1551 && GET_CODE (XEXP (operands
[0], 0)) == PRE_DEC
1552 && REGNO (XEXP (XEXP (operands
[0], 0), 0)) == STACK_POINTER_REGNUM
1553 && INTVAL (operands
[1]) < 0x8000
1554 && INTVAL (operands
[1]) >= -0x8000)
1556 return "move%.l %1,%0";
1560 output_move_simode (operands
)
1563 if (GET_CODE (operands
[1]) == CONST_INT
)
1564 return output_move_simode_const (operands
);
1565 else if ((GET_CODE (operands
[1]) == SYMBOL_REF
1566 || GET_CODE (operands
[1]) == CONST
)
1567 && push_operand (operands
[0], SImode
))
1569 else if ((GET_CODE (operands
[1]) == SYMBOL_REF
1570 || GET_CODE (operands
[1]) == CONST
)
1571 && ADDRESS_REG_P (operands
[0]))
1572 return "lea %a1,%0";
1573 return "move%.l %1,%0";
1577 output_move_himode (operands
)
1580 if (GET_CODE (operands
[1]) == CONST_INT
)
1582 if (operands
[1] == const0_rtx
1583 && (DATA_REG_P (operands
[0])
1584 || GET_CODE (operands
[0]) == MEM
)
1585 /* clr insns on 68000 read before writing.
1586 This isn't so on the 68010, but we have no TARGET_68010. */
1587 && ((TARGET_68020
|| TARGET_5200
)
1588 || !(GET_CODE (operands
[0]) == MEM
1589 && MEM_VOLATILE_P (operands
[0]))))
1591 else if (operands
[1] == const0_rtx
1592 && ADDRESS_REG_P (operands
[0]))
1593 return "sub%.l %0,%0";
1594 else if (DATA_REG_P (operands
[0])
1595 && INTVAL (operands
[1]) < 128
1596 && INTVAL (operands
[1]) >= -128)
1598 #if defined(MOTOROLA) && !defined(CRDS)
1599 return "moveq%.l %1,%0";
1601 return "moveq %1,%0";
1604 else if (INTVAL (operands
[1]) < 0x8000
1605 && INTVAL (operands
[1]) >= -0x8000)
1606 return "move%.w %1,%0";
1608 else if (CONSTANT_P (operands
[1]))
1609 return "move%.l %1,%0";
1611 /* Recognize the insn before a tablejump, one that refers
1612 to a table of offsets. Such an insn will need to refer
1613 to a label on the insn. So output one. Use the label-number
1614 of the table of offsets to generate this label. This code,
1615 and similar code below, assumes that there will be at most one
1616 reference to each table. */
1617 if (GET_CODE (operands
[1]) == MEM
1618 && GET_CODE (XEXP (operands
[1], 0)) == PLUS
1619 && GET_CODE (XEXP (XEXP (operands
[1], 0), 1)) == LABEL_REF
1620 && GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) != PLUS
)
1622 rtx labelref
= XEXP (XEXP (operands
[1], 0), 1);
1623 #if defined (MOTOROLA) && !defined (SGS_SWITCH_TABLES)
1625 asm_fprintf (asm_out_file
, "\tset %LLI%d,.+2\n",
1626 CODE_LABEL_NUMBER (XEXP (labelref
, 0)));
1628 asm_fprintf (asm_out_file
, "\t.set %LLI%d,.+2\n",
1629 CODE_LABEL_NUMBER (XEXP (labelref
, 0)));
1630 #endif /* not SGS */
1631 #else /* SGS_SWITCH_TABLES or not MOTOROLA */
1632 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "LI",
1633 CODE_LABEL_NUMBER (XEXP (labelref
, 0)));
1634 #ifdef SGS_SWITCH_TABLES
1635 /* Set flag saying we need to define the symbol
1636 LD%n (with value L%n-LI%n) at the end of the switch table. */
1637 switch_table_difference_label_flag
= 1;
1638 #endif /* SGS_SWITCH_TABLES */
1639 #endif /* SGS_SWITCH_TABLES or not MOTOROLA */
1641 #endif /* SGS_NO_LI */
1642 return "move%.w %1,%0";
1646 output_move_qimode (operands
)
1651 /* This is probably useless, since it loses for pushing a struct
1652 of several bytes a byte at a time. */
1653 /* 68k family always modifies the stack pointer by at least 2, even for
1654 byte pushes. The 5200 (coldfire) does not do this. */
1655 if (GET_CODE (operands
[0]) == MEM
1656 && GET_CODE (XEXP (operands
[0], 0)) == PRE_DEC
1657 && XEXP (XEXP (operands
[0], 0), 0) == stack_pointer_rtx
1658 && ! ADDRESS_REG_P (operands
[1])
1661 xoperands
[1] = operands
[1];
1663 = gen_rtx_MEM (QImode
,
1664 gen_rtx_PLUS (VOIDmode
, stack_pointer_rtx
, const1_rtx
));
1665 /* Just pushing a byte puts it in the high byte of the halfword. */
1666 /* We must put it in the low-order, high-numbered byte. */
1667 if (!reg_mentioned_p (stack_pointer_rtx
, operands
[1]))
1669 xoperands
[3] = stack_pointer_rtx
;
1671 output_asm_insn ("subq%.l %#2,%3\n\tmove%.b %1,%2", xoperands
);
1673 output_asm_insn ("sub%.l %#2,%3\n\tmove%.b %1,%2", xoperands
);
1677 output_asm_insn ("move%.b %1,%-\n\tmove%.b %@,%2", xoperands
);
1681 /* clr and st insns on 68000 read before writing.
1682 This isn't so on the 68010, but we have no TARGET_68010. */
1683 if (!ADDRESS_REG_P (operands
[0])
1684 && ((TARGET_68020
|| TARGET_5200
)
1685 || !(GET_CODE (operands
[0]) == MEM
&& MEM_VOLATILE_P (operands
[0]))))
1687 if (operands
[1] == const0_rtx
)
1689 if ((!TARGET_5200
|| DATA_REG_P (operands
[0]))
1690 && GET_CODE (operands
[1]) == CONST_INT
1691 && (INTVAL (operands
[1]) & 255) == 255)
1697 if (GET_CODE (operands
[1]) == CONST_INT
1698 && DATA_REG_P (operands
[0])
1699 && INTVAL (operands
[1]) < 128
1700 && INTVAL (operands
[1]) >= -128)
1702 #if defined(MOTOROLA) && !defined(CRDS)
1703 return "moveq%.l %1,%0";
1705 return "moveq %1,%0";
1708 if (operands
[1] == const0_rtx
&& ADDRESS_REG_P (operands
[0]))
1709 return "sub%.l %0,%0";
1710 if (GET_CODE (operands
[1]) != CONST_INT
&& CONSTANT_P (operands
[1]))
1711 return "move%.l %1,%0";
1712 /* 68k family (including the 5200 coldfire) does not support byte moves to
1713 from address registers. */
1714 if (ADDRESS_REG_P (operands
[0]) || ADDRESS_REG_P (operands
[1]))
1715 return "move%.w %1,%0";
1716 return "move%.b %1,%0";
1720 output_move_stricthi (operands
)
1723 if (operands
[1] == const0_rtx
1724 /* clr insns on 68000 read before writing.
1725 This isn't so on the 68010, but we have no TARGET_68010. */
1726 && ((TARGET_68020
|| TARGET_5200
)
1727 || !(GET_CODE (operands
[0]) == MEM
&& MEM_VOLATILE_P (operands
[0]))))
1729 return "move%.w %1,%0";
1733 output_move_strictqi (operands
)
1736 if (operands
[1] == const0_rtx
1737 /* clr insns on 68000 read before writing.
1738 This isn't so on the 68010, but we have no TARGET_68010. */
1739 && ((TARGET_68020
|| TARGET_5200
)
1740 || !(GET_CODE (operands
[0]) == MEM
&& MEM_VOLATILE_P (operands
[0]))))
1742 return "move%.b %1,%0";
1745 /* Return the best assembler insn template
1746 for moving operands[1] into operands[0] as a fullword. */
1749 singlemove_string (operands
)
1752 #ifdef SUPPORT_SUN_FPA
1753 if (FPA_REG_P (operands
[0]) || FPA_REG_P (operands
[1]))
1754 return "fpmoves %1,%0";
1756 if (GET_CODE (operands
[1]) == CONST_INT
)
1757 return output_move_simode_const (operands
);
1758 return "move%.l %1,%0";
1762 /* Output assembler code to perform a doubleword move insn
1763 with operands OPERANDS. */
1766 output_move_double (operands
)
1771 REGOP
, OFFSOP
, MEMOP
, PUSHOP
, POPOP
, CNSTOP
, RNDOP
1776 rtx addreg0
= 0, addreg1
= 0;
1777 int dest_overlapped_low
= 0;
1778 int size
= GET_MODE_SIZE (GET_MODE (operands
[0]));
1783 /* First classify both operands. */
1785 if (REG_P (operands
[0]))
1787 else if (offsettable_memref_p (operands
[0]))
1789 else if (GET_CODE (XEXP (operands
[0], 0)) == POST_INC
)
1791 else if (GET_CODE (XEXP (operands
[0], 0)) == PRE_DEC
)
1793 else if (GET_CODE (operands
[0]) == MEM
)
1798 if (REG_P (operands
[1]))
1800 else if (CONSTANT_P (operands
[1]))
1802 else if (offsettable_memref_p (operands
[1]))
1804 else if (GET_CODE (XEXP (operands
[1], 0)) == POST_INC
)
1806 else if (GET_CODE (XEXP (operands
[1], 0)) == PRE_DEC
)
1808 else if (GET_CODE (operands
[1]) == MEM
)
1813 /* Check for the cases that the operand constraints are not
1814 supposed to allow to happen. Abort if we get one,
1815 because generating code for these cases is painful. */
1817 if (optype0
== RNDOP
|| optype1
== RNDOP
)
1820 /* If one operand is decrementing and one is incrementing
1821 decrement the former register explicitly
1822 and change that operand into ordinary indexing. */
1824 if (optype0
== PUSHOP
&& optype1
== POPOP
)
1826 operands
[0] = XEXP (XEXP (operands
[0], 0), 0);
1828 output_asm_insn ("sub%.l %#12,%0", operands
);
1830 output_asm_insn ("subq%.l %#8,%0", operands
);
1831 if (GET_MODE (operands
[1]) == XFmode
)
1832 operands
[0] = gen_rtx_MEM (XFmode
, operands
[0]);
1833 else if (GET_MODE (operands
[0]) == DFmode
)
1834 operands
[0] = gen_rtx_MEM (DFmode
, operands
[0]);
1836 operands
[0] = gen_rtx_MEM (DImode
, operands
[0]);
1839 if (optype0
== POPOP
&& optype1
== PUSHOP
)
1841 operands
[1] = XEXP (XEXP (operands
[1], 0), 0);
1843 output_asm_insn ("sub%.l %#12,%1", operands
);
1845 output_asm_insn ("subq%.l %#8,%1", operands
);
1846 if (GET_MODE (operands
[1]) == XFmode
)
1847 operands
[1] = gen_rtx_MEM (XFmode
, operands
[1]);
1848 else if (GET_MODE (operands
[1]) == DFmode
)
1849 operands
[1] = gen_rtx_MEM (DFmode
, operands
[1]);
1851 operands
[1] = gen_rtx_MEM (DImode
, operands
[1]);
1855 /* If an operand is an unoffsettable memory ref, find a register
1856 we can increment temporarily to make it refer to the second word. */
1858 if (optype0
== MEMOP
)
1859 addreg0
= find_addr_reg (XEXP (operands
[0], 0));
1861 if (optype1
== MEMOP
)
1862 addreg1
= find_addr_reg (XEXP (operands
[1], 0));
1864 /* Ok, we can do one word at a time.
1865 Normally we do the low-numbered word first,
1866 but if either operand is autodecrementing then we
1867 do the high-numbered word first.
1869 In either case, set up in LATEHALF the operands to use
1870 for the high-numbered word and in some cases alter the
1871 operands in OPERANDS to be suitable for the low-numbered word. */
1875 if (optype0
== REGOP
)
1877 latehalf
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 2);
1878 middlehalf
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 1);
1880 else if (optype0
== OFFSOP
)
1882 middlehalf
[0] = adj_offsettable_operand (operands
[0], 4);
1883 latehalf
[0] = adj_offsettable_operand (operands
[0], size
- 4);
1887 middlehalf
[0] = operands
[0];
1888 latehalf
[0] = operands
[0];
1891 if (optype1
== REGOP
)
1893 latehalf
[1] = gen_rtx_REG (SImode
, REGNO (operands
[1]) + 2);
1894 middlehalf
[1] = gen_rtx_REG (SImode
, REGNO (operands
[1]) + 1);
1896 else if (optype1
== OFFSOP
)
1898 middlehalf
[1] = adj_offsettable_operand (operands
[1], 4);
1899 latehalf
[1] = adj_offsettable_operand (operands
[1], size
- 4);
1901 else if (optype1
== CNSTOP
)
1903 if (GET_CODE (operands
[1]) == CONST_DOUBLE
)
1908 REAL_VALUE_FROM_CONST_DOUBLE (r
, operands
[1]);
1909 REAL_VALUE_TO_TARGET_LONG_DOUBLE (r
, l
);
1910 operands
[1] = GEN_INT (l
[0]);
1911 middlehalf
[1] = GEN_INT (l
[1]);
1912 latehalf
[1] = GEN_INT (l
[2]);
1914 else if (CONSTANT_P (operands
[1]))
1916 /* actually, no non-CONST_DOUBLE constant should ever
1919 if (GET_CODE (operands
[1]) == CONST_INT
&& INTVAL (operands
[1]) < 0)
1920 latehalf
[1] = constm1_rtx
;
1922 latehalf
[1] = const0_rtx
;
1927 middlehalf
[1] = operands
[1];
1928 latehalf
[1] = operands
[1];
1932 /* size is not 12: */
1934 if (optype0
== REGOP
)
1935 latehalf
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 1);
1936 else if (optype0
== OFFSOP
)
1937 latehalf
[0] = adj_offsettable_operand (operands
[0], size
- 4);
1939 latehalf
[0] = operands
[0];
1941 if (optype1
== REGOP
)
1942 latehalf
[1] = gen_rtx_REG (SImode
, REGNO (operands
[1]) + 1);
1943 else if (optype1
== OFFSOP
)
1944 latehalf
[1] = adj_offsettable_operand (operands
[1], size
- 4);
1945 else if (optype1
== CNSTOP
)
1946 split_double (operands
[1], &operands
[1], &latehalf
[1]);
1948 latehalf
[1] = operands
[1];
1951 /* If insn is effectively movd N(sp),-(sp) then we will do the
1952 high word first. We should use the adjusted operand 1 (which is N+4(sp))
1953 for the low word as well, to compensate for the first decrement of sp. */
1954 if (optype0
== PUSHOP
1955 && REGNO (XEXP (XEXP (operands
[0], 0), 0)) == STACK_POINTER_REGNUM
1956 && reg_overlap_mentioned_p (stack_pointer_rtx
, operands
[1]))
1957 operands
[1] = middlehalf
[1] = latehalf
[1];
1959 /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)),
1960 if the upper part of reg N does not appear in the MEM, arrange to
1961 emit the move late-half first. Otherwise, compute the MEM address
1962 into the upper part of N and use that as a pointer to the memory
1964 if (optype0
== REGOP
1965 && (optype1
== OFFSOP
|| optype1
== MEMOP
))
1967 rtx testlow
= gen_rtx_REG (SImode
, REGNO (operands
[0]));
1969 if (reg_overlap_mentioned_p (testlow
, XEXP (operands
[1], 0))
1970 && reg_overlap_mentioned_p (latehalf
[0], XEXP (operands
[1], 0)))
1972 /* If both halves of dest are used in the src memory address,
1973 compute the address into latehalf of dest.
1974 Note that this can't happen if the dest is two data regs. */
1976 xops
[0] = latehalf
[0];
1977 xops
[1] = XEXP (operands
[1], 0);
1978 output_asm_insn ("lea %a1,%0", xops
);
1979 if( GET_MODE (operands
[1]) == XFmode
)
1981 operands
[1] = gen_rtx_MEM (XFmode
, latehalf
[0]);
1982 middlehalf
[1] = adj_offsettable_operand (operands
[1], size
-8);
1983 latehalf
[1] = adj_offsettable_operand (operands
[1], size
-4);
1987 operands
[1] = gen_rtx_MEM (DImode
, latehalf
[0]);
1988 latehalf
[1] = adj_offsettable_operand (operands
[1], size
-4);
1992 && reg_overlap_mentioned_p (middlehalf
[0],
1993 XEXP (operands
[1], 0)))
1995 /* Check for two regs used by both source and dest.
1996 Note that this can't happen if the dest is all data regs.
1997 It can happen if the dest is d6, d7, a0.
1998 But in that case, latehalf is an addr reg, so
1999 the code at compadr does ok. */
2001 if (reg_overlap_mentioned_p (testlow
, XEXP (operands
[1], 0))
2002 || reg_overlap_mentioned_p (latehalf
[0], XEXP (operands
[1], 0)))
2005 /* JRV says this can't happen: */
2006 if (addreg0
|| addreg1
)
2009 /* Only the middle reg conflicts; simply put it last. */
2010 output_asm_insn (singlemove_string (operands
), operands
);
2011 output_asm_insn (singlemove_string (latehalf
), latehalf
);
2012 output_asm_insn (singlemove_string (middlehalf
), middlehalf
);
2015 else if (reg_overlap_mentioned_p (testlow
, XEXP (operands
[1], 0)))
2016 /* If the low half of dest is mentioned in the source memory
2017 address, the arrange to emit the move late half first. */
2018 dest_overlapped_low
= 1;
2021 /* If one or both operands autodecrementing,
2022 do the two words, high-numbered first. */
2024 /* Likewise, the first move would clobber the source of the second one,
2025 do them in the other order. This happens only for registers;
2026 such overlap can't happen in memory unless the user explicitly
2027 sets it up, and that is an undefined circumstance. */
2029 if (optype0
== PUSHOP
|| optype1
== PUSHOP
2030 || (optype0
== REGOP
&& optype1
== REGOP
2031 && ((middlehalf
[1] && REGNO (operands
[0]) == REGNO (middlehalf
[1]))
2032 || REGNO (operands
[0]) == REGNO (latehalf
[1])))
2033 || dest_overlapped_low
)
2035 /* Make any unoffsettable addresses point at high-numbered word. */
2039 output_asm_insn ("addq%.l %#8,%0", &addreg0
);
2041 output_asm_insn ("addq%.l %#4,%0", &addreg0
);
2046 output_asm_insn ("addq%.l %#8,%0", &addreg1
);
2048 output_asm_insn ("addq%.l %#4,%0", &addreg1
);
2052 output_asm_insn (singlemove_string (latehalf
), latehalf
);
2054 /* Undo the adds we just did. */
2056 output_asm_insn ("subq%.l %#4,%0", &addreg0
);
2058 output_asm_insn ("subq%.l %#4,%0", &addreg1
);
2062 output_asm_insn (singlemove_string (middlehalf
), middlehalf
);
2064 output_asm_insn ("subq%.l %#4,%0", &addreg0
);
2066 output_asm_insn ("subq%.l %#4,%0", &addreg1
);
2069 /* Do low-numbered word. */
2070 return singlemove_string (operands
);
2073 /* Normal case: do the two words, low-numbered first. */
2075 output_asm_insn (singlemove_string (operands
), operands
);
2077 /* Do the middle one of the three words for long double */
2081 output_asm_insn ("addq%.l %#4,%0", &addreg0
);
2083 output_asm_insn ("addq%.l %#4,%0", &addreg1
);
2085 output_asm_insn (singlemove_string (middlehalf
), middlehalf
);
2088 /* Make any unoffsettable addresses point at high-numbered word. */
2090 output_asm_insn ("addq%.l %#4,%0", &addreg0
);
2092 output_asm_insn ("addq%.l %#4,%0", &addreg1
);
2095 output_asm_insn (singlemove_string (latehalf
), latehalf
);
2097 /* Undo the adds we just did. */
2101 output_asm_insn ("subq%.l %#8,%0", &addreg0
);
2103 output_asm_insn ("subq%.l %#4,%0", &addreg0
);
2108 output_asm_insn ("subq%.l %#8,%0", &addreg1
);
2110 output_asm_insn ("subq%.l %#4,%0", &addreg1
);
2116 /* Return a REG that occurs in ADDR with coefficient 1.
2117 ADDR can be effectively incremented by incrementing REG. */
2120 find_addr_reg (addr
)
2123 while (GET_CODE (addr
) == PLUS
)
2125 if (GET_CODE (XEXP (addr
, 0)) == REG
)
2126 addr
= XEXP (addr
, 0);
2127 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
2128 addr
= XEXP (addr
, 1);
2129 else if (CONSTANT_P (XEXP (addr
, 0)))
2130 addr
= XEXP (addr
, 1);
2131 else if (CONSTANT_P (XEXP (addr
, 1)))
2132 addr
= XEXP (addr
, 0);
2136 if (GET_CODE (addr
) == REG
)
2141 /* Output assembler code to perform a 32 bit 3 operand add. */
2144 output_addsi3 (operands
)
2147 if (! operands_match_p (operands
[0], operands
[1]))
2149 if (!ADDRESS_REG_P (operands
[1]))
2151 rtx tmp
= operands
[1];
2153 operands
[1] = operands
[2];
2157 /* These insns can result from reloads to access
2158 stack slots over 64k from the frame pointer. */
2159 if (GET_CODE (operands
[2]) == CONST_INT
2160 && INTVAL (operands
[2]) + 0x8000 >= (unsigned) 0x10000)
2161 return "move%.l %2,%0\n\tadd%.l %1,%0";
2163 if (GET_CODE (operands
[2]) == REG
)
2164 return "lea 0(%1,%2.l),%0";
2166 return "lea %c2(%1),%0";
2169 if (GET_CODE (operands
[2]) == REG
)
2170 return "lea (%1,%2.l),%0";
2172 return "lea (%c2,%1),%0";
2173 #else /* not MOTOROLA (MIT syntax) */
2174 if (GET_CODE (operands
[2]) == REG
)
2175 return "lea %1@(0,%2:l),%0";
2177 return "lea %1@(%c2),%0";
2178 #endif /* not MOTOROLA */
2179 #endif /* not SGS */
2181 if (GET_CODE (operands
[2]) == CONST_INT
)
2184 if (INTVAL (operands
[2]) > 0
2185 && INTVAL (operands
[2]) <= 8)
2186 return "addq%.l %2,%0";
2187 if (INTVAL (operands
[2]) < 0
2188 && INTVAL (operands
[2]) >= -8)
2190 operands
[2] = GEN_INT (- INTVAL (operands
[2]));
2191 return "subq%.l %2,%0";
2193 /* On the CPU32 it is faster to use two addql instructions to
2194 add a small integer (8 < N <= 16) to a register.
2195 Likewise for subql. */
2196 if (TARGET_CPU32
&& REG_P (operands
[0]))
2198 if (INTVAL (operands
[2]) > 8
2199 && INTVAL (operands
[2]) <= 16)
2201 operands
[2] = GEN_INT (INTVAL (operands
[2]) - 8);
2202 return "addq%.l %#8,%0\n\taddq%.l %2,%0";
2204 if (INTVAL (operands
[2]) < -8
2205 && INTVAL (operands
[2]) >= -16)
2207 operands
[2] = GEN_INT (- INTVAL (operands
[2]) - 8);
2208 return "subq%.l %#8,%0\n\tsubq%.l %2,%0";
2212 if (ADDRESS_REG_P (operands
[0])
2213 && INTVAL (operands
[2]) >= -0x8000
2214 && INTVAL (operands
[2]) < 0x8000)
2217 return "add%.w %2,%0";
2220 return "lea (%c2,%0),%0";
2222 return "lea %0@(%c2),%0";
2226 return "add%.l %2,%0";
2229 /* Store in cc_status the expressions that the condition codes will
2230 describe after execution of an instruction whose pattern is EXP.
2231 Do not alter them if the instruction would not alter the cc's. */
2233 /* On the 68000, all the insns to store in an address register fail to
2234 set the cc's. However, in some cases these instructions can make it
2235 possibly invalid to use the saved cc's. In those cases we clear out
2236 some or all of the saved cc's so they won't be used. */
2239 notice_update_cc (exp
, insn
)
2243 /* If the cc is being set from the fpa and the expression is not an
2244 explicit floating point test instruction (which has code to deal with
2245 this), reinit the CC. */
2246 if (((cc_status
.value1
&& FPA_REG_P (cc_status
.value1
))
2247 || (cc_status
.value2
&& FPA_REG_P (cc_status
.value2
)))
2248 && !(GET_CODE (exp
) == PARALLEL
2249 && GET_CODE (XVECEXP (exp
, 0, 0)) == SET
2250 && XEXP (XVECEXP (exp
, 0, 0), 0) == cc0_rtx
))
2254 else if (GET_CODE (exp
) == SET
)
2256 if (GET_CODE (SET_SRC (exp
)) == CALL
)
2260 else if (ADDRESS_REG_P (SET_DEST (exp
)))
2262 if (cc_status
.value1
&& modified_in_p (cc_status
.value1
, insn
))
2263 cc_status
.value1
= 0;
2264 if (cc_status
.value2
&& modified_in_p (cc_status
.value2
, insn
))
2265 cc_status
.value2
= 0;
2267 else if (!FP_REG_P (SET_DEST (exp
))
2268 && SET_DEST (exp
) != cc0_rtx
2269 && (FP_REG_P (SET_SRC (exp
))
2270 || GET_CODE (SET_SRC (exp
)) == FIX
2271 || GET_CODE (SET_SRC (exp
)) == FLOAT_TRUNCATE
2272 || GET_CODE (SET_SRC (exp
)) == FLOAT_EXTEND
))
2276 /* A pair of move insns doesn't produce a useful overall cc. */
2277 else if (!FP_REG_P (SET_DEST (exp
))
2278 && !FP_REG_P (SET_SRC (exp
))
2279 && GET_MODE_SIZE (GET_MODE (SET_SRC (exp
))) > 4
2280 && (GET_CODE (SET_SRC (exp
)) == REG
2281 || GET_CODE (SET_SRC (exp
)) == MEM
2282 || GET_CODE (SET_SRC (exp
)) == CONST_DOUBLE
))
2286 else if (GET_CODE (SET_SRC (exp
)) == CALL
)
2290 else if (XEXP (exp
, 0) != pc_rtx
)
2292 cc_status
.flags
= 0;
2293 cc_status
.value1
= XEXP (exp
, 0);
2294 cc_status
.value2
= XEXP (exp
, 1);
2297 else if (GET_CODE (exp
) == PARALLEL
2298 && GET_CODE (XVECEXP (exp
, 0, 0)) == SET
)
2300 if (ADDRESS_REG_P (XEXP (XVECEXP (exp
, 0, 0), 0)))
2302 else if (XEXP (XVECEXP (exp
, 0, 0), 0) != pc_rtx
)
2304 cc_status
.flags
= 0;
2305 cc_status
.value1
= XEXP (XVECEXP (exp
, 0, 0), 0);
2306 cc_status
.value2
= XEXP (XVECEXP (exp
, 0, 0), 1);
2311 if (cc_status
.value2
!= 0
2312 && ADDRESS_REG_P (cc_status
.value2
)
2313 && GET_MODE (cc_status
.value2
) == QImode
)
2315 if (cc_status
.value2
!= 0
2316 && !(cc_status
.value1
&& FPA_REG_P (cc_status
.value1
)))
2317 switch (GET_CODE (cc_status
.value2
))
2319 case PLUS
: case MINUS
: case MULT
:
2320 case DIV
: case UDIV
: case MOD
: case UMOD
: case NEG
:
2321 #if 0 /* These instructions always clear the overflow bit */
2322 case ASHIFT
: case ASHIFTRT
: case LSHIFTRT
:
2323 case ROTATE
: case ROTATERT
:
2325 if (GET_MODE (cc_status
.value2
) != VOIDmode
)
2326 cc_status
.flags
|= CC_NO_OVERFLOW
;
2329 /* (SET r1 (ZERO_EXTEND r2)) on this machine
2330 ends with a move insn moving r2 in r2's mode.
2331 Thus, the cc's are set for r2.
2332 This can set N bit spuriously. */
2333 cc_status
.flags
|= CC_NOT_NEGATIVE
;
2338 if (cc_status
.value1
&& GET_CODE (cc_status
.value1
) == REG
2340 && reg_overlap_mentioned_p (cc_status
.value1
, cc_status
.value2
))
2341 cc_status
.value2
= 0;
2342 if (((cc_status
.value1
&& FP_REG_P (cc_status
.value1
))
2343 || (cc_status
.value2
&& FP_REG_P (cc_status
.value2
)))
2344 && !((cc_status
.value1
&& FPA_REG_P (cc_status
.value1
))
2345 || (cc_status
.value2
&& FPA_REG_P (cc_status
.value2
))))
2346 cc_status
.flags
= CC_IN_68881
;
2350 output_move_const_double (operands
)
2353 #ifdef SUPPORT_SUN_FPA
2354 if (TARGET_FPA
&& FPA_REG_P (operands
[0]))
2356 int code
= standard_sun_fpa_constant_p (operands
[1]);
2360 static char buf
[40];
2362 sprintf (buf
, "fpmove%%.d %%%%%d,%%0", code
& 0x1ff);
2365 return "fpmove%.d %1,%0";
2370 int code
= standard_68881_constant_p (operands
[1]);
2374 static char buf
[40];
2376 sprintf (buf
, "fmovecr %%#0x%x,%%0", code
& 0xff);
2379 return "fmove%.d %1,%0";
2384 output_move_const_single (operands
)
2387 #ifdef SUPPORT_SUN_FPA
2390 int code
= standard_sun_fpa_constant_p (operands
[1]);
2394 static char buf
[40];
2396 sprintf (buf
, "fpmove%%.s %%%%%d,%%0", code
& 0x1ff);
2399 return "fpmove%.s %1,%0";
2402 #endif /* defined SUPPORT_SUN_FPA */
2404 int code
= standard_68881_constant_p (operands
[1]);
2408 static char buf
[40];
2410 sprintf (buf
, "fmovecr %%#0x%x,%%0", code
& 0xff);
2413 return "fmove%.s %f1,%0";
2417 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
2418 from the "fmovecr" instruction.
2419 The value, anded with 0xff, gives the code to use in fmovecr
2420 to get the desired constant. */
2422 /* This code has been fixed for cross-compilation. */
2424 static int inited_68881_table
= 0;
2426 static const char *const strings_68881
[7] = {
2436 int codes_68881
[7] = {
2446 REAL_VALUE_TYPE values_68881
[7];
2448 /* Set up values_68881 array by converting the decimal values
2449 strings_68881 to binary. */
2456 enum machine_mode mode
;
2459 for (i
= 0; i
< 7; i
++)
2463 r
= REAL_VALUE_ATOF (strings_68881
[i
], mode
);
2464 values_68881
[i
] = r
;
2466 inited_68881_table
= 1;
2470 standard_68881_constant_p (x
)
2476 #ifdef NO_ASM_FMOVECR
2480 /* fmovecr must be emulated on the 68040 and 68060, so it shouldn't be
2481 used at all on those chips. */
2482 if (TARGET_68040
|| TARGET_68060
)
2485 #ifndef REAL_ARITHMETIC
2486 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
2487 if (! flag_pretend_float
)
2492 if (! inited_68881_table
)
2493 init_68881_table ();
2495 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
2497 /* Use REAL_VALUES_IDENTICAL instead of REAL_VALUES_EQUAL so that -0.0
2499 for (i
= 0; i
< 6; i
++)
2501 if (REAL_VALUES_IDENTICAL (r
, values_68881
[i
]))
2502 return (codes_68881
[i
]);
2505 if (GET_MODE (x
) == SFmode
)
2508 if (REAL_VALUES_EQUAL (r
, values_68881
[6]))
2509 return (codes_68881
[6]);
2511 /* larger powers of ten in the constants ram are not used
2512 because they are not equal to a `double' C constant. */
2516 /* If X is a floating-point constant, return the logarithm of X base 2,
2517 or 0 if X is not a power of 2. */
2520 floating_exact_log2 (x
)
2523 REAL_VALUE_TYPE r
, r1
;
2526 #ifndef REAL_ARITHMETIC
2527 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
2528 if (! flag_pretend_float
)
2533 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
2535 if (REAL_VALUES_LESS (r
, dconst0
))
2540 while (REAL_VALUES_LESS (r1
, r
))
2542 r1
= REAL_VALUE_LDEXP (dconst1
, i
);
2543 if (REAL_VALUES_EQUAL (r1
, r
))
2550 #ifdef SUPPORT_SUN_FPA
2551 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
2552 from the Sun FPA's constant RAM.
2553 The value returned, anded with 0x1ff, gives the code to use in fpmove
2554 to get the desired constant. */
2556 static int inited_FPA_table
= 0;
2558 static const char *const strings_FPA
[38] = {
2559 /* small rationals */
2572 /* Decimal equivalents of double precision values */
2573 "2.718281828459045091", /* D_E */
2574 "6.283185307179586477", /* 2 pi */
2575 "3.141592653589793116", /* D_PI */
2576 "1.570796326794896619", /* pi/2 */
2577 "1.414213562373095145", /* D_SQRT2 */
2578 "0.7071067811865475244", /* 1/sqrt(2) */
2579 "-1.570796326794896619", /* -pi/2 */
2580 "1.442695040888963387", /* D_LOG2ofE */
2581 "3.321928024887362182", /* D_LOG2of10 */
2582 "0.6931471805599452862", /* D_LOGEof2 */
2583 "2.302585092994045901", /* D_LOGEof10 */
2584 "0.3010299956639811980", /* D_LOG10of2 */
2585 "0.4342944819032518167", /* D_LOG10ofE */
2586 /* Decimal equivalents of single precision values */
2587 "2.718281745910644531", /* S_E */
2588 "6.283185307179586477", /* 2 pi */
2589 "3.141592741012573242", /* S_PI */
2590 "1.570796326794896619", /* pi/2 */
2591 "1.414213538169860840", /* S_SQRT2 */
2592 "0.7071067811865475244", /* 1/sqrt(2) */
2593 "-1.570796326794896619", /* -pi/2 */
2594 "1.442695021629333496", /* S_LOG2ofE */
2595 "3.321928024291992188", /* S_LOG2of10 */
2596 "0.6931471824645996094", /* S_LOGEof2 */
2597 "2.302585124969482442", /* S_LOGEof10 */
2598 "0.3010300099849700928", /* S_LOG10of2 */
2599 "0.4342944920063018799", /* S_LOG10ofE */
2603 int codes_FPA
[38] = {
2604 /* small rationals */
2617 /* double precision */
2631 /* single precision */
2647 REAL_VALUE_TYPE values_FPA
[38];
2649 /* This code has been fixed for cross-compilation. */
2654 enum machine_mode mode
;
2659 for (i
= 0; i
< 38; i
++)
2663 r
= REAL_VALUE_ATOF (strings_FPA
[i
], mode
);
2666 inited_FPA_table
= 1;
2671 standard_sun_fpa_constant_p (x
)
2677 #ifndef REAL_ARITHMETIC
2678 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
2679 if (! flag_pretend_float
)
2684 if (! inited_FPA_table
)
2687 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
2689 for (i
=0; i
<12; i
++)
2691 if (REAL_VALUES_EQUAL (r
, values_FPA
[i
]))
2692 return (codes_FPA
[i
]);
2695 if (GET_MODE (x
) == SFmode
)
2697 for (i
=25; i
<38; i
++)
2699 if (REAL_VALUES_EQUAL (r
, values_FPA
[i
]))
2700 return (codes_FPA
[i
]);
2705 for (i
=12; i
<25; i
++)
2707 if (REAL_VALUES_EQUAL (r
, values_FPA
[i
]))
2708 return (codes_FPA
[i
]);
2713 #endif /* define SUPPORT_SUN_FPA */
2715 /* A C compound statement to output to stdio stream STREAM the
2716 assembler syntax for an instruction operand X. X is an RTL
2719 CODE is a value that can be used to specify one of several ways
2720 of printing the operand. It is used when identical operands
2721 must be printed differently depending on the context. CODE
2722 comes from the `%' specification that was used to request
2723 printing of the operand. If the specification was just `%DIGIT'
2724 then CODE is 0; if the specification was `%LTR DIGIT' then CODE
2725 is the ASCII code for LTR.
2727 If X is a register, this macro should print the register's name.
2728 The names can be found in an array `reg_names' whose type is
2729 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
2731 When the machine description has a specification `%PUNCT' (a `%'
2732 followed by a punctuation character), this macro is called with
2733 a null pointer for X and the punctuation character for CODE.
2735 The m68k specific codes are:
2737 '.' for dot needed in Motorola-style opcode names.
2738 '-' for an operand pushing on the stack:
2739 sp@-, -(sp) or -(%sp) depending on the style of syntax.
2740 '+' for an operand pushing on the stack:
2741 sp@+, (sp)+ or (%sp)+ depending on the style of syntax.
2742 '@' for a reference to the top word on the stack:
2743 sp@, (sp) or (%sp) depending on the style of syntax.
2744 '#' for an immediate operand prefix (# in MIT and Motorola syntax
2745 but & in SGS syntax, $ in CRDS/UNOS syntax).
2746 '!' for the cc register (used in an `and to cc' insn).
2747 '$' for the letter `s' in an op code, but only on the 68040.
2748 '&' for the letter `d' in an op code, but only on the 68040.
2749 '/' for register prefix needed by longlong.h.
2751 'b' for byte insn (no effect, on the Sun; this is for the ISI).
2752 'd' to force memory addressing to be absolute, not relative.
2753 'f' for float insn (print a CONST_DOUBLE as a float rather than in hex)
2754 'o' for operands to go directly to output_operand_address (bypassing
2755 print_operand_address--used only for SYMBOL_REFs under TARGET_PCREL)
2756 'w' for FPA insn (print a CONST_DOUBLE as a SunFPA constant rather
2757 than directly). Second part of 'y' below.
2758 'x' for float insn (print a CONST_DOUBLE as a float rather than in hex),
2759 or print pair of registers as rx:ry.
2760 'y' for a FPA insn (print pair of registers as rx:ry). This also outputs
2761 CONST_DOUBLE's as SunFPA constant RAM registers if
2762 possible, so it should not be used except for the SunFPA.
2767 print_operand (file
, op
, letter
)
2768 FILE *file
; /* file to write to */
2769 rtx op
; /* operand to print */
2770 int letter
; /* %<letter> or 0 */
2772 #ifdef SUPPORT_SUN_FPA
2778 #if defined (MOTOROLA) && !defined (CRDS)
2779 asm_fprintf (file
, ".");
2782 else if (letter
== '#')
2784 asm_fprintf (file
, "%0I");
2786 else if (letter
== '-')
2789 asm_fprintf (file
, "-(%Rsp)");
2791 asm_fprintf (file
, "%Rsp@-");
2794 else if (letter
== '+')
2797 asm_fprintf (file
, "(%Rsp)+");
2799 asm_fprintf (file
, "%Rsp@+");
2802 else if (letter
== '@')
2805 asm_fprintf (file
, "(%Rsp)");
2807 asm_fprintf (file
, "%Rsp@");
2810 else if (letter
== '!')
2812 asm_fprintf (file
, "%Rfpcr");
2814 else if (letter
== '$')
2816 if (TARGET_68040_ONLY
)
2818 fprintf (file
, "s");
2821 else if (letter
== '&')
2823 if (TARGET_68040_ONLY
)
2825 fprintf (file
, "d");
2828 else if (letter
== '/')
2830 asm_fprintf (file
, "%R");
2832 else if (letter
== 'o')
2834 /* This is only for direct addresses with TARGET_PCREL */
2835 if (GET_CODE (op
) != MEM
|| GET_CODE (XEXP (op
, 0)) != SYMBOL_REF
2838 output_addr_const (file
, XEXP (op
, 0));
2840 else if (GET_CODE (op
) == REG
)
2842 #ifdef SUPPORT_SUN_FPA
2844 && (letter
== 'y' || letter
== 'x')
2845 && GET_MODE (op
) == DFmode
)
2847 fprintf (file
, "%s:%s", reg_names
[REGNO (op
)],
2848 reg_names
[REGNO (op
)+1]);
2854 /* Print out the second register name of a register pair.
2855 I.e., R (6) => 7. */
2856 fputs (reg_names
[REGNO (op
) + 1], file
);
2858 fputs (reg_names
[REGNO (op
)], file
);
2861 else if (GET_CODE (op
) == MEM
)
2863 output_address (XEXP (op
, 0));
2864 if (letter
== 'd' && ! TARGET_68020
2865 && CONSTANT_ADDRESS_P (XEXP (op
, 0))
2866 && !(GET_CODE (XEXP (op
, 0)) == CONST_INT
2867 && INTVAL (XEXP (op
, 0)) < 0x8000
2868 && INTVAL (XEXP (op
, 0)) >= -0x8000))
2871 fprintf (file
, ".l");
2873 fprintf (file
, ":l");
2877 #ifdef SUPPORT_SUN_FPA
2878 else if ((letter
== 'y' || letter
== 'w')
2879 && GET_CODE (op
) == CONST_DOUBLE
2880 && (i
= standard_sun_fpa_constant_p (op
)))
2882 fprintf (file
, "%%%d", i
& 0x1ff);
2885 else if (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == SFmode
)
2888 REAL_VALUE_FROM_CONST_DOUBLE (r
, op
);
2889 ASM_OUTPUT_FLOAT_OPERAND (letter
, file
, r
);
2891 else if (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == XFmode
)
2894 REAL_VALUE_FROM_CONST_DOUBLE (r
, op
);
2895 ASM_OUTPUT_LONG_DOUBLE_OPERAND (file
, r
);
2897 else if (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == DFmode
)
2900 REAL_VALUE_FROM_CONST_DOUBLE (r
, op
);
2901 ASM_OUTPUT_DOUBLE_OPERAND (file
, r
);
2905 /* Use `print_operand_address' instead of `output_addr_const'
2906 to ensure that we print relevant PIC stuff. */
2907 asm_fprintf (file
, "%0I");
2909 && (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == CONST
))
2910 print_operand_address (file
, op
);
2912 output_addr_const (file
, op
);
2917 /* A C compound statement to output to stdio stream STREAM the
2918 assembler syntax for an instruction operand that is a memory
2919 reference whose address is ADDR. ADDR is an RTL expression.
2921 Note that this contains a kludge that knows that the only reason
2922 we have an address (plus (label_ref...) (reg...)) when not generating
2923 PIC code is in the insn before a tablejump, and we know that m68k.md
2924 generates a label LInnn: on such an insn.
2926 It is possible for PIC to generate a (plus (label_ref...) (reg...))
2927 and we handle that just like we would a (plus (symbol_ref...) (reg...)).
2929 Some SGS assemblers have a bug such that "Lnnn-LInnn-2.b(pc,d0.l*2)"
2930 fails to assemble. Luckily "Lnnn(pc,d0.l*2)" produces the results
2931 we want. This difference can be accommodated by using an assembler
2932 define such "LDnnn" to be either "Lnnn-LInnn-2.b", "Lnnn", or any other
2933 string, as necessary. This is accomplished via the ASM_OUTPUT_CASE_END
2934 macro. See m68k/sgs.h for an example; for versions without the bug.
2935 Some assemblers refuse all the above solutions. The workaround is to
2936 emit "K(pc,d0.l*2)" with K being a small constant known to give the
2939 They also do not like things like "pea 1.w", so we simple leave off
2940 the .w on small constants.
2942 This routine is responsible for distinguishing between -fpic and -fPIC
2943 style relocations in an address. When generating -fpic code the
2944 offset is output in word mode (eg movel a5@(_foo:w), a0). When generating
2945 -fPIC code the offset is output in long mode (eg movel a5@(_foo:l), a0) */
2947 #ifndef ASM_OUTPUT_CASE_FETCH
2950 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2951 asm_fprintf (file, "%LLD%d(%Rpc,%s.", labelno, regname)
2953 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2954 asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.", labelno, labelno, regname)
2957 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2958 asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:", labelno, labelno, regname)
2960 #endif /* ASM_OUTPUT_CASE_FETCH */
2963 print_operand_address (file
, addr
)
2967 register rtx reg1
, reg2
, breg
, ireg
;
2970 switch (GET_CODE (addr
))
2974 fprintf (file
, "(%s)", reg_names
[REGNO (addr
)]);
2976 fprintf (file
, "%s@", reg_names
[REGNO (addr
)]);
2981 fprintf (file
, "-(%s)", reg_names
[REGNO (XEXP (addr
, 0))]);
2983 fprintf (file
, "%s@-", reg_names
[REGNO (XEXP (addr
, 0))]);
2988 fprintf (file
, "(%s)+", reg_names
[REGNO (XEXP (addr
, 0))]);
2990 fprintf (file
, "%s@+", reg_names
[REGNO (XEXP (addr
, 0))]);
2994 reg1
= reg2
= ireg
= breg
= offset
= 0;
2995 if (CONSTANT_ADDRESS_P (XEXP (addr
, 0)))
2997 offset
= XEXP (addr
, 0);
2998 addr
= XEXP (addr
, 1);
3000 else if (CONSTANT_ADDRESS_P (XEXP (addr
, 1)))
3002 offset
= XEXP (addr
, 1);
3003 addr
= XEXP (addr
, 0);
3005 if (GET_CODE (addr
) != PLUS
)
3009 else if (GET_CODE (XEXP (addr
, 0)) == SIGN_EXTEND
)
3011 reg1
= XEXP (addr
, 0);
3012 addr
= XEXP (addr
, 1);
3014 else if (GET_CODE (XEXP (addr
, 1)) == SIGN_EXTEND
)
3016 reg1
= XEXP (addr
, 1);
3017 addr
= XEXP (addr
, 0);
3019 else if (GET_CODE (XEXP (addr
, 0)) == MULT
)
3021 reg1
= XEXP (addr
, 0);
3022 addr
= XEXP (addr
, 1);
3024 else if (GET_CODE (XEXP (addr
, 1)) == MULT
)
3026 reg1
= XEXP (addr
, 1);
3027 addr
= XEXP (addr
, 0);
3029 else if (GET_CODE (XEXP (addr
, 0)) == REG
)
3031 reg1
= XEXP (addr
, 0);
3032 addr
= XEXP (addr
, 1);
3034 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
3036 reg1
= XEXP (addr
, 1);
3037 addr
= XEXP (addr
, 0);
3039 if (GET_CODE (addr
) == REG
|| GET_CODE (addr
) == MULT
3040 || GET_CODE (addr
) == SIGN_EXTEND
)
3052 #if 0 /* for OLD_INDEXING */
3053 else if (GET_CODE (addr
) == PLUS
)
3055 if (GET_CODE (XEXP (addr
, 0)) == REG
)
3057 reg2
= XEXP (addr
, 0);
3058 addr
= XEXP (addr
, 1);
3060 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
3062 reg2
= XEXP (addr
, 1);
3063 addr
= XEXP (addr
, 0);
3075 if ((reg1
&& (GET_CODE (reg1
) == SIGN_EXTEND
3076 || GET_CODE (reg1
) == MULT
))
3077 || (reg2
!= 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2
))))
3082 else if (reg1
!= 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1
)))
3087 if (ireg
!= 0 && breg
== 0 && GET_CODE (addr
) == LABEL_REF
3088 && ! (flag_pic
&& ireg
== pic_offset_table_rtx
))
3091 if (GET_CODE (ireg
) == MULT
)
3093 scale
= INTVAL (XEXP (ireg
, 1));
3094 ireg
= XEXP (ireg
, 0);
3096 if (GET_CODE (ireg
) == SIGN_EXTEND
)
3098 ASM_OUTPUT_CASE_FETCH (file
,
3099 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
3100 reg_names
[REGNO (XEXP (ireg
, 0))]);
3101 fprintf (file
, "w");
3105 ASM_OUTPUT_CASE_FETCH (file
,
3106 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
3107 reg_names
[REGNO (ireg
)]);
3108 fprintf (file
, "l");
3113 fprintf (file
, "*%d", scale
);
3115 fprintf (file
, ":%d", scale
);
3121 if (breg
!= 0 && ireg
== 0 && GET_CODE (addr
) == LABEL_REF
3122 && ! (flag_pic
&& breg
== pic_offset_table_rtx
))
3124 ASM_OUTPUT_CASE_FETCH (file
,
3125 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
3126 reg_names
[REGNO (breg
)]);
3127 fprintf (file
, "l)");
3130 if (ireg
!= 0 || breg
!= 0)
3137 if (! flag_pic
&& addr
&& GET_CODE (addr
) == LABEL_REF
)
3144 output_addr_const (file
, addr
);
3145 if (flag_pic
&& (breg
== pic_offset_table_rtx
))
3147 fprintf (file
, "@GOT");
3149 fprintf (file
, ".w");
3152 fprintf (file
, "(%s", reg_names
[REGNO (breg
)]);
3158 fprintf (file
, "%s@(", reg_names
[REGNO (breg
)]);
3161 output_addr_const (file
, addr
);
3162 if ((flag_pic
== 1) && (breg
== pic_offset_table_rtx
))
3163 fprintf (file
, ":w");
3164 if ((flag_pic
== 2) && (breg
== pic_offset_table_rtx
))
3165 fprintf (file
, ":l");
3167 if (addr
!= 0 && ireg
!= 0)
3172 if (ireg
!= 0 && GET_CODE (ireg
) == MULT
)
3174 scale
= INTVAL (XEXP (ireg
, 1));
3175 ireg
= XEXP (ireg
, 0);
3177 if (ireg
!= 0 && GET_CODE (ireg
) == SIGN_EXTEND
)
3180 fprintf (file
, "%s.w", reg_names
[REGNO (XEXP (ireg
, 0))]);
3182 fprintf (file
, "%s:w", reg_names
[REGNO (XEXP (ireg
, 0))]);
3188 fprintf (file
, "%s.l", reg_names
[REGNO (ireg
)]);
3190 fprintf (file
, "%s:l", reg_names
[REGNO (ireg
)]);
3196 fprintf (file
, "*%d", scale
);
3198 fprintf (file
, ":%d", scale
);
3204 else if (reg1
!= 0 && GET_CODE (addr
) == LABEL_REF
3205 && ! (flag_pic
&& reg1
== pic_offset_table_rtx
))
3207 ASM_OUTPUT_CASE_FETCH (file
,
3208 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
3209 reg_names
[REGNO (reg1
)]);
3210 fprintf (file
, "l)");
3213 /* FALL-THROUGH (is this really what we want?) */
3215 if (GET_CODE (addr
) == CONST_INT
3216 && INTVAL (addr
) < 0x8000
3217 && INTVAL (addr
) >= -0x8000)
3221 /* Many SGS assemblers croak on size specifiers for constants. */
3222 fprintf (file
, "%d", INTVAL (addr
));
3224 fprintf (file
, "%d.w", INTVAL (addr
));
3227 fprintf (file
, "%d:w", INTVAL (addr
));
3230 else if (GET_CODE (addr
) == CONST_INT
)
3233 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
3240 else if (TARGET_PCREL
)
3243 output_addr_const (file
, addr
);
3245 asm_fprintf (file
, ":w,%Rpc)");
3247 asm_fprintf (file
, ":l,%Rpc)");
3251 /* Special case for SYMBOL_REF if the symbol name ends in
3252 `.<letter>', this can be mistaken as a size suffix. Put
3253 the name in parentheses. */
3254 if (GET_CODE (addr
) == SYMBOL_REF
3255 && strlen (XSTR (addr
, 0)) > 2
3256 && XSTR (addr
, 0)[strlen (XSTR (addr
, 0)) - 2] == '.')
3259 output_addr_const (file
, addr
);
3263 output_addr_const (file
, addr
);
3269 /* Check for cases where a clr insns can be omitted from code using
3270 strict_low_part sets. For example, the second clrl here is not needed:
3271 clrl d0; movw a0@+,d0; use d0; clrl d0; movw a0@+; use d0; ...
3273 MODE is the mode of this STRICT_LOW_PART set. FIRST_INSN is the clear
3274 insn we are checking for redundancy. TARGET is the register set by the
3278 strict_low_part_peephole_ok (mode
, first_insn
, target
)
3279 enum machine_mode mode
;
3285 p
= prev_nonnote_insn (first_insn
);
3289 /* If it isn't an insn, then give up. */
3290 if (GET_CODE (p
) != INSN
)
3293 if (reg_set_p (target
, p
))
3295 rtx set
= single_set (p
);
3298 /* If it isn't an easy to recognize insn, then give up. */
3302 dest
= SET_DEST (set
);
3304 /* If this sets the entire target register to zero, then our
3305 first_insn is redundant. */
3306 if (rtx_equal_p (dest
, target
)
3307 && SET_SRC (set
) == const0_rtx
)
3309 else if (GET_CODE (dest
) == STRICT_LOW_PART
3310 && GET_CODE (XEXP (dest
, 0)) == REG
3311 && REGNO (XEXP (dest
, 0)) == REGNO (target
)
3312 && (GET_MODE_SIZE (GET_MODE (XEXP (dest
, 0)))
3313 <= GET_MODE_SIZE (mode
)))
3314 /* This is a strict low part set which modifies less than
3315 we are using, so it is safe. */
3321 p
= prev_nonnote_insn (p
);
3328 /* Accept integer operands in the range 0..0xffffffff. We have to check the
3329 range carefully since this predicate is used in DImode contexts. Also, we
3330 need some extra crud to make it work when hosted on 64-bit machines. */
3333 const_uint32_operand (op
, mode
)
3335 enum machine_mode mode ATTRIBUTE_UNUSED
;
3337 #if HOST_BITS_PER_WIDE_INT > 32
3338 /* All allowed constants will fit a CONST_INT. */
3339 return (GET_CODE (op
) == CONST_INT
3340 && (INTVAL (op
) >= 0 && INTVAL (op
) <= 0xffffffffL
));
3342 return (GET_CODE (op
) == CONST_INT
3343 || (GET_CODE (op
) == CONST_DOUBLE
&& CONST_DOUBLE_HIGH (op
) == 0));
3347 /* Accept integer operands in the range -0x80000000..0x7fffffff. We have
3348 to check the range carefully since this predicate is used in DImode
3352 const_sint32_operand (op
, mode
)
3354 enum machine_mode mode ATTRIBUTE_UNUSED
;
3356 /* All allowed constants will fit a CONST_INT. */
3357 return (GET_CODE (op
) == CONST_INT
3358 && (INTVAL (op
) >= (-0x7fffffff - 1) && INTVAL (op
) <= 0x7fffffff));
3361 /* Operand predicates for implementing asymmetric pc-relative addressing
3362 on m68k. The m68k supports pc-relative addressing (mode 7, register 2)
3363 when used as a source operand, but not as a destintation operand.
3365 We model this by restricting the meaning of the basic predicates
3366 (general_operand, memory_operand, etc) to forbid the use of this
3367 addressing mode, and then define the following predicates that permit
3368 this addressing mode. These predicates can then be used for the
3369 source operands of the appropriate instructions.
3371 n.b. While it is theoretically possible to change all machine patterns
3372 to use this addressing more where permitted by the architecture,
3373 it has only been implemented for "common" cases: SImode, HImode, and
3374 QImode operands, and only for the principle operations that would
3375 require this addressing mode: data movement and simple integer operations.
3377 In parallel with these new predicates, two new constraint letters
3378 were defined: 'S' and 'T'. 'S' is the -mpcrel analog of 'm'.
3379 'T' replaces 's' in the non-pcrel case. It is a no-op in the pcrel case.
3380 In the pcrel case 's' is only valid in combination with 'a' registers.
3381 See addsi3, subsi3, cmpsi, and movsi patterns for a better understanding
3382 of how these constraints are used.
3384 The use of these predicates is strictly optional, though patterns that
3385 don't will cause an extra reload register to be allocated where one
3388 lea (abc:w,%pc),%a0 ; need to reload address
3389 moveq &1,%d1 ; since write to pc-relative space
3390 movel %d1,%a0@ ; is not allowed
3392 lea (abc:w,%pc),%a1 ; no need to reload address here
3393 movel %a1@,%d0 ; since "movel (abc:w,%pc),%d0" is ok
3395 For more info, consult tiemann@cygnus.com.
3398 All of the ugliness with predicates and constraints is due to the
3399 simple fact that the m68k does not allow a pc-relative addressing
3400 mode as a destination. gcc does not distinguish between source and
3401 destination addresses. Hence, if we claim that pc-relative address
3402 modes are valid, e.g. GO_IF_LEGITIMATE_ADDRESS accepts them, then we
3403 end up with invalid code. To get around this problem, we left
3404 pc-relative modes as invalid addresses, and then added special
3405 predicates and constraints to accept them.
3407 A cleaner way to handle this is to modify gcc to distinguish
3408 between source and destination addresses. We can then say that
3409 pc-relative is a valid source address but not a valid destination
3410 address, and hopefully avoid a lot of the predicate and constraint
3411 hackery. Unfortunately, this would be a pretty big change. It would
3412 be a useful change for a number of ports, but there aren't any current
3413 plans to undertake this.
3415 ***************************************************************************/
3418 /* Special case of a general operand that's used as a source operand.
3419 Use this to permit reads from PC-relative memory when -mpcrel
3423 general_src_operand (op
, mode
)
3425 enum machine_mode mode
;
3428 && GET_CODE (op
) == MEM
3429 && (GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
3430 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
3431 || GET_CODE (XEXP (op
, 0)) == CONST
))
3433 return general_operand (op
, mode
);
3436 /* Special case of a nonimmediate operand that's used as a source.
3437 Use this to permit reads from PC-relative memory when -mpcrel
3441 nonimmediate_src_operand (op
, mode
)
3443 enum machine_mode mode
;
3445 if (TARGET_PCREL
&& GET_CODE (op
) == MEM
3446 && (GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
3447 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
3448 || GET_CODE (XEXP (op
, 0)) == CONST
))
3450 return nonimmediate_operand (op
, mode
);
3453 /* Special case of a memory operand that's used as a source.
3454 Use this to permit reads from PC-relative memory when -mpcrel
3458 memory_src_operand (op
, mode
)
3460 enum machine_mode mode
;
3462 if (TARGET_PCREL
&& GET_CODE (op
) == MEM
3463 && (GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
3464 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
3465 || GET_CODE (XEXP (op
, 0)) == CONST
))
3467 return memory_operand (op
, mode
);
3470 /* Predicate that accepts only a pc-relative address. This is needed
3471 because pc-relative addresses don't satisfy the predicate
3472 "general_src_operand". */
3475 pcrel_address (op
, mode
)
3477 enum machine_mode mode ATTRIBUTE_UNUSED
;
3479 return (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
3480 || GET_CODE (op
) == CONST
);
3484 output_andsi3 (operands
)
3488 if (GET_CODE (operands
[2]) == CONST_INT
3489 && (INTVAL (operands
[2]) | 0xffff) == 0xffffffff
3490 && (DATA_REG_P (operands
[0])
3491 || offsettable_memref_p (operands
[0]))
3494 if (GET_CODE (operands
[0]) != REG
)
3495 operands
[0] = adj_offsettable_operand (operands
[0], 2);
3496 operands
[2] = GEN_INT (INTVAL (operands
[2]) & 0xffff);
3497 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3499 if (operands
[2] == const0_rtx
)
3501 return "and%.w %2,%0";
3503 if (GET_CODE (operands
[2]) == CONST_INT
3504 && (logval
= exact_log2 (~ INTVAL (operands
[2]))) >= 0
3505 && (DATA_REG_P (operands
[0])
3506 || offsettable_memref_p (operands
[0])))
3508 if (DATA_REG_P (operands
[0]))
3510 operands
[1] = GEN_INT (logval
);
3514 operands
[0] = adj_offsettable_operand (operands
[0], 3 - (logval
/ 8));
3515 operands
[1] = GEN_INT (logval
% 8);
3517 /* This does not set condition codes in a standard way. */
3519 return "bclr %1,%0";
3521 return "and%.l %2,%0";
3525 output_iorsi3 (operands
)
3528 register int logval
;
3529 if (GET_CODE (operands
[2]) == CONST_INT
3530 && INTVAL (operands
[2]) >> 16 == 0
3531 && (DATA_REG_P (operands
[0])
3532 || offsettable_memref_p (operands
[0]))
3535 if (GET_CODE (operands
[0]) != REG
)
3536 operands
[0] = adj_offsettable_operand (operands
[0], 2);
3537 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3539 if (INTVAL (operands
[2]) == 0xffff)
3540 return "mov%.w %2,%0";
3541 return "or%.w %2,%0";
3543 if (GET_CODE (operands
[2]) == CONST_INT
3544 && (logval
= exact_log2 (INTVAL (operands
[2]))) >= 0
3545 && (DATA_REG_P (operands
[0])
3546 || offsettable_memref_p (operands
[0])))
3548 if (DATA_REG_P (operands
[0]))
3550 operands
[1] = GEN_INT (logval
);
3554 operands
[0] = adj_offsettable_operand (operands
[0], 3 - (logval
/ 8));
3555 operands
[1] = GEN_INT (logval
% 8);
3558 return "bset %1,%0";
3560 return "or%.l %2,%0";
3564 output_xorsi3 (operands
)
3567 register int logval
;
3568 if (GET_CODE (operands
[2]) == CONST_INT
3569 && INTVAL (operands
[2]) >> 16 == 0
3570 && (offsettable_memref_p (operands
[0]) || DATA_REG_P (operands
[0]))
3573 if (! DATA_REG_P (operands
[0]))
3574 operands
[0] = adj_offsettable_operand (operands
[0], 2);
3575 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3577 if (INTVAL (operands
[2]) == 0xffff)
3579 return "eor%.w %2,%0";
3581 if (GET_CODE (operands
[2]) == CONST_INT
3582 && (logval
= exact_log2 (INTVAL (operands
[2]))) >= 0
3583 && (DATA_REG_P (operands
[0])
3584 || offsettable_memref_p (operands
[0])))
3586 if (DATA_REG_P (operands
[0]))
3588 operands
[1] = GEN_INT (logval
);
3592 operands
[0] = adj_offsettable_operand (operands
[0], 3 - (logval
/ 8));
3593 operands
[1] = GEN_INT (logval
% 8);
3596 return "bchg %1,%0";
3598 return "eor%.l %2,%0";