1 /* Subroutines for insn-output.c for Motorola 68000 family.
2 Copyright (C) 1987, 93-98, 1999 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
27 #include "hard-reg-set.h"
29 #include "insn-config.h"
30 #include "conditions.h"
31 #include "insn-flags.h"
33 #include "insn-attr.h"
37 /* Needed for use_return_insn. */
40 #ifdef SUPPORT_SUN_FPA
42 /* Index into this array by (register number >> 3) to find the
43 smallest class which contains that register. */
44 enum reg_class regno_reg_class
[]
45 = { DATA_REGS
, ADDR_REGS
, FP_REGS
,
46 LO_FPA_REGS
, LO_FPA_REGS
, FPA_REGS
, FPA_REGS
};
48 #endif /* defined SUPPORT_SUN_FPA */
50 /* This flag is used to communicate between movhi and ASM_OUTPUT_CASE_END,
51 if SGS_SWITCH_TABLE. */
52 int switch_table_difference_label_flag
;
54 static rtx
find_addr_reg ();
55 rtx
legitimize_pic_address ();
56 void print_operand_address ();
59 /* Alignment to use for loops and jumps */
60 /* Specify power of two alignment used for loops. */
61 const char *m68k_align_loops_string
;
62 /* Specify power of two alignment used for non-loop jumps. */
63 const char *m68k_align_jumps_string
;
64 /* Specify power of two alignment used for functions. */
65 const char *m68k_align_funcs_string
;
67 /* Specify power of two alignment used for loops. */
69 /* Specify power of two alignment used for non-loop jumps. */
71 /* Specify power of two alignment used for functions. */
74 /* Nonzero if the last compare/test insn had FP operands. The
75 sCC expanders peek at this to determine what to do for the
76 68060, which has no fsCC instructions. */
77 int m68k_last_compare_had_fp_operands
;
79 /* Sometimes certain combinations of command options do not make
80 sense on a particular target machine. You can define a macro
81 `OVERRIDE_OPTIONS' to take account of this. This macro, if
82 defined, is executed once just after all the command options have
85 Don't use this macro to turn on various extra optimizations for
86 `-O'. That is what `OPTIMIZATION_OPTIONS' is for. */
95 /* Validate -malign-loops= value, or provide default */
96 if (m68k_align_loops_string
)
98 m68k_align_loops
= atoi (m68k_align_loops_string
);
99 if (m68k_align_loops
< 1 || m68k_align_loops
> MAX_CODE_ALIGN
)
100 fatal ("-malign-loops=%d is not between 1 and %d",
101 m68k_align_loops
, MAX_CODE_ALIGN
);
104 m68k_align_loops
= def_align
;
106 /* Validate -malign-jumps= value, or provide default */
107 if (m68k_align_jumps_string
)
109 m68k_align_jumps
= atoi (m68k_align_jumps_string
);
110 if (m68k_align_jumps
< 1 || m68k_align_jumps
> MAX_CODE_ALIGN
)
111 fatal ("-malign-jumps=%d is not between 1 and %d",
112 m68k_align_jumps
, MAX_CODE_ALIGN
);
115 m68k_align_jumps
= def_align
;
117 /* Validate -malign-functions= value, or provide default */
118 if (m68k_align_funcs_string
)
120 m68k_align_funcs
= atoi (m68k_align_funcs_string
);
121 if (m68k_align_funcs
< 1 || m68k_align_funcs
> MAX_CODE_ALIGN
)
122 fatal ("-malign-functions=%d is not between 1 and %d",
123 m68k_align_funcs
, MAX_CODE_ALIGN
);
126 m68k_align_funcs
= def_align
;
129 /* This function generates the assembly code for function entry.
130 STREAM is a stdio stream to output the code to.
131 SIZE is an int: how many units of temporary storage to allocate.
132 Refer to the array `regs_ever_live' to determine which registers
133 to save; `regs_ever_live[I]' is nonzero if register number I
134 is ever used in the function. This function is responsible for
135 knowing which registers should not be saved even if used. */
138 /* Note that the order of the bit mask for fmovem is the opposite
139 of the order for movem! */
143 output_function_prologue (stream
, size
)
148 register int mask
= 0;
149 int num_saved_regs
= 0;
150 extern char call_used_regs
[];
151 int fsize
= (size
+ 3) & -4;
152 int cfa_offset
= INCOMING_FRAME_SP_OFFSET
, cfa_store_offset
= cfa_offset
;
155 if (frame_pointer_needed
)
157 if (fsize
== 0 && TARGET_68040
)
159 /* on the 68040, pea + move is faster than link.w 0 */
161 asm_fprintf (stream
, "\tpea (%s)\n\tmove.l %s,%s\n",
162 reg_names
[FRAME_POINTER_REGNUM
], reg_names
[STACK_POINTER_REGNUM
],
163 reg_names
[FRAME_POINTER_REGNUM
]);
165 asm_fprintf (stream
, "\tpea %s@\n\tmovel %s,%s\n",
166 reg_names
[FRAME_POINTER_REGNUM
], reg_names
[STACK_POINTER_REGNUM
],
167 reg_names
[FRAME_POINTER_REGNUM
]);
170 else if (fsize
< 0x8000)
173 asm_fprintf (stream
, "\tlink.w %s,%0I%d\n",
174 reg_names
[FRAME_POINTER_REGNUM
], -fsize
);
176 asm_fprintf (stream
, "\tlink %s,%0I%d\n",
177 reg_names
[FRAME_POINTER_REGNUM
], -fsize
);
180 else if (TARGET_68020
)
183 asm_fprintf (stream
, "\tlink.l %s,%0I%d\n",
184 reg_names
[FRAME_POINTER_REGNUM
], -fsize
);
186 asm_fprintf (stream
, "\tlink %s,%0I%d\n",
187 reg_names
[FRAME_POINTER_REGNUM
], -fsize
);
192 /* Adding negative number is faster on the 68040. */
194 asm_fprintf (stream
, "\tlink.w %s,%0I0\n\tadd.l %0I%d,%Rsp\n",
195 reg_names
[FRAME_POINTER_REGNUM
], -fsize
);
197 asm_fprintf (stream
, "\tlink %s,%0I0\n\taddl %0I%d,%Rsp\n",
198 reg_names
[FRAME_POINTER_REGNUM
], -fsize
);
201 if (dwarf2out_do_frame ())
204 l
= (char *) dwarf2out_cfi_label ();
205 cfa_store_offset
+= 4;
206 cfa_offset
= cfa_store_offset
;
207 dwarf2out_def_cfa (l
, FRAME_POINTER_REGNUM
, cfa_offset
);
208 dwarf2out_reg_save (l
, FRAME_POINTER_REGNUM
, -cfa_store_offset
);
209 cfa_store_offset
+= fsize
;
214 if (fsize
+ 4 < 0x8000)
221 /* asm_fprintf() cannot handle %. */
223 asm_fprintf (stream
, "\tsubq.w %0I%d,%Rsp\n", fsize
+ 4);
225 asm_fprintf (stream
, "\tsubqw %0I%d,%Rsp\n", fsize
+ 4);
230 /* asm_fprintf() cannot handle %. */
232 asm_fprintf (stream
, "\tsubq.l %0I%d,%Rsp\n", fsize
+ 4);
234 asm_fprintf (stream
, "\tsubql %0I%d,%Rsp\n", fsize
+ 4);
238 else if (fsize
+ 4 <= 16 && TARGET_CPU32
)
240 /* On the CPU32 it is faster to use two subqw instructions to
241 subtract a small integer (8 < N <= 16) to a register. */
242 /* asm_fprintf() cannot handle %. */
244 asm_fprintf (stream
, "\tsubq.w %0I8,%Rsp\n\tsubq.w %0I%d,%Rsp\n",
247 asm_fprintf (stream
, "\tsubqw %0I8,%Rsp\n\tsubqw %0I%d,%Rsp\n",
252 #endif /* not NO_ADDSUB_Q */
255 /* Adding negative number is faster on the 68040. */
256 /* asm_fprintf() cannot handle %. */
258 asm_fprintf (stream
, "\tadd.w %0I%d,%Rsp\n", - (fsize
+ 4));
260 asm_fprintf (stream
, "\taddw %0I%d,%Rsp\n", - (fsize
+ 4));
266 asm_fprintf (stream
, "\tlea (%d,%Rsp),%Rsp\n", - (fsize
+ 4));
268 asm_fprintf (stream
, "\tlea %Rsp@(%d),%Rsp\n", - (fsize
+ 4));
274 /* asm_fprintf() cannot handle %. */
276 asm_fprintf (stream
, "\tadd.l %0I%d,%Rsp\n", - (fsize
+ 4));
278 asm_fprintf (stream
, "\taddl %0I%d,%Rsp\n", - (fsize
+ 4));
281 if (dwarf2out_do_frame ())
283 cfa_store_offset
+= fsize
;
284 cfa_offset
= cfa_store_offset
;
285 dwarf2out_def_cfa ("", STACK_POINTER_REGNUM
, cfa_offset
);
288 #ifdef SUPPORT_SUN_FPA
289 for (regno
= 24; regno
< 56; regno
++)
290 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
293 asm_fprintf (stream
, "\tfpmovd %s,-(%Rsp)\n",
296 asm_fprintf (stream
, "\tfpmoved %s,%Rsp@-\n",
299 if (dwarf2out_do_frame ())
301 char *l
= dwarf2out_cfi_label ();
303 cfa_store_offset
+= 8;
304 if (! frame_pointer_needed
)
306 cfa_offset
= cfa_store_offset
;
307 dwarf2out_def_cfa (l
, STACK_POINTER_REGNUM
, cfa_offset
);
309 dwarf2out_reg_save (l
, regno
, -cfa_store_offset
);
315 for (regno
= 16; regno
< 24; regno
++)
316 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
318 mask
|= 1 << (regno
- 16);
321 if ((mask
& 0xff) != 0)
324 asm_fprintf (stream
, "\tfmovm %0I0x%x,-(%Rsp)\n", mask
& 0xff);
326 asm_fprintf (stream
, "\tfmovem %0I0x%x,%Rsp@-\n", mask
& 0xff);
328 if (dwarf2out_do_frame ())
330 char *l
= (char *) dwarf2out_cfi_label ();
333 cfa_store_offset
+= num_saved_regs
* 12;
334 if (! frame_pointer_needed
)
336 cfa_offset
= cfa_store_offset
;
337 dwarf2out_def_cfa (l
, STACK_POINTER_REGNUM
, cfa_offset
);
339 for (regno
= 16, n_regs
= 0; regno
< 24; regno
++)
340 if (mask
& (1 << (regno
- 16)))
341 dwarf2out_reg_save (l
, regno
,
342 -cfa_store_offset
+ n_regs
++ * 12);
348 for (regno
= 0; regno
< 16; regno
++)
349 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
351 mask
|= 1 << (15 - regno
);
354 if (frame_pointer_needed
)
356 mask
&= ~ (1 << (15 - FRAME_POINTER_REGNUM
));
359 if (flag_pic
&& regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
])
361 mask
|= 1 << (15 - PIC_OFFSET_TABLE_REGNUM
);
368 asm_fprintf (stream
, "\ttstl %d(%Rsp)\n", NEED_PROBE
- num_saved_regs
* 4);
370 asm_fprintf (stream
, "\ttst.l %d(%Rsp)\n", NEED_PROBE
- num_saved_regs
* 4);
373 asm_fprintf (stream
, "\ttstl %Rsp@(%d)\n", NEED_PROBE
- num_saved_regs
* 4);
377 if (num_saved_regs
<= 2)
379 /* Store each separately in the same order moveml uses.
380 Using two movel instructions instead of a single moveml
381 is about 15% faster for the 68020 and 68030 at no expense
386 /* Undo the work from above. */
387 for (i
= 0; i
< 16; i
++)
392 "\t%Omove.l %s,-(%Rsp)\n",
394 "\tmovel %s,%Rsp@-\n",
397 if (dwarf2out_do_frame ())
399 char *l
= (char *) dwarf2out_cfi_label ();
401 cfa_store_offset
+= 4;
402 if (! frame_pointer_needed
)
404 cfa_offset
= cfa_store_offset
;
405 dwarf2out_def_cfa (l
, STACK_POINTER_REGNUM
, cfa_offset
);
407 dwarf2out_reg_save (l
, 15 - i
, -cfa_store_offset
);
415 /* The coldfire does not support the predecrement form of the
416 movml instruction, so we must adjust the stack pointer and
417 then use the plain address register indirect mode. We also
418 have to invert the register save mask to use the new mode.
420 FIXME: if num_saved_regs was calculated earlier, we could
421 combine the stack pointer adjustment with any adjustment
422 done when the initial stack frame is created. This would
423 save an instruction */
428 for (i
= 0; i
< 16; i
++)
430 newmask
|= (1 << (15-i
));
433 asm_fprintf (stream
, "\tlea (%d,%Rsp),%Rsp\n", -num_saved_regs
*4);
434 asm_fprintf (stream
, "\tmovm.l %0I0x%x,(%Rsp)\n", newmask
);
436 asm_fprintf (stream
, "\tlea %Rsp@(%d),%Rsp\n", -num_saved_regs
*4);
437 asm_fprintf (stream
, "\tmoveml %0I0x%x,%Rsp@\n", newmask
);
443 asm_fprintf (stream
, "\tmovm.l %0I0x%x,-(%Rsp)\n", mask
);
445 asm_fprintf (stream
, "\tmoveml %0I0x%x,%Rsp@-\n", mask
);
448 if (dwarf2out_do_frame ())
450 char *l
= (char *) dwarf2out_cfi_label ();
453 cfa_store_offset
+= num_saved_regs
* 4;
454 if (! frame_pointer_needed
)
456 cfa_offset
= cfa_store_offset
;
457 dwarf2out_def_cfa (l
, STACK_POINTER_REGNUM
, cfa_offset
);
459 for (regno
= 0, n_regs
= 0; regno
< 16; regno
++)
460 if (mask
& (1 << (15 - regno
)))
461 dwarf2out_reg_save (l
, regno
,
462 -cfa_store_offset
+ n_regs
++ * 4);
465 if (flag_pic
&& current_function_uses_pic_offset_table
)
468 asm_fprintf (stream
, "\t%Olea (%Rpc, %U_GLOBAL_OFFSET_TABLE_@GOTPC), %s\n",
469 reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
471 asm_fprintf (stream
, "\tmovel %0I__GLOBAL_OFFSET_TABLE_, %s\n",
472 reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
473 asm_fprintf (stream
, "\tlea %Rpc@(0,%s:l),%s\n",
474 reg_names
[PIC_OFFSET_TABLE_REGNUM
],
475 reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
480 /* Return true if this function's epilogue can be output as RTL. */
487 if (!reload_completed
|| frame_pointer_needed
|| get_frame_size () != 0)
490 /* Copied from output_function_epilogue (). We should probably create a
491 separate layout routine to perform the common work. */
493 for (regno
= 0 ; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
494 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
500 /* This function generates the assembly code for function exit,
501 on machines that need it. Args are same as for FUNCTION_PROLOGUE.
503 The function epilogue should not depend on the current stack pointer!
504 It should use the frame pointer only, if there is a frame pointer.
505 This is mandatory because of alloca; we also take advantage of it to
506 omit stack adjustments before returning. */
509 output_function_epilogue (stream
, size
)
514 register int mask
, fmask
;
516 int offset
, foffset
, fpoffset
;
517 extern char call_used_regs
[];
518 int fsize
= (size
+ 3) & -4;
520 rtx insn
= get_last_insn ();
521 int restore_from_sp
= 0;
523 /* If the last insn was a BARRIER, we don't have to write any code. */
524 if (GET_CODE (insn
) == NOTE
)
525 insn
= prev_nonnote_insn (insn
);
526 if (insn
&& GET_CODE (insn
) == BARRIER
)
528 /* Output just a no-op so that debuggers don't get confused
529 about which function the pc is in at this address. */
530 asm_fprintf (stream
, "\tnop\n");
534 #ifdef FUNCTION_BLOCK_PROFILER_EXIT
535 if (profile_block_flag
== 2)
537 FUNCTION_BLOCK_PROFILER_EXIT (stream
);
541 #ifdef FUNCTION_EXTRA_EPILOGUE
542 FUNCTION_EXTRA_EPILOGUE (stream
, size
);
544 nregs
= 0; fmask
= 0; fpoffset
= 0;
545 #ifdef SUPPORT_SUN_FPA
546 for (regno
= 24 ; regno
< 56 ; regno
++)
547 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
549 fpoffset
= nregs
* 8;
554 for (regno
= 16; regno
< 24; regno
++)
555 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
558 fmask
|= 1 << (23 - regno
);
561 foffset
= fpoffset
+ nregs
* 12;
563 if (frame_pointer_needed
)
564 regs_ever_live
[FRAME_POINTER_REGNUM
] = 0;
565 for (regno
= 0; regno
< 16; regno
++)
566 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
571 if (flag_pic
&& regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
])
574 mask
|= 1 << PIC_OFFSET_TABLE_REGNUM
;
576 offset
= foffset
+ nregs
* 4;
577 /* FIXME : leaf_function_p below is too strong.
578 What we really need to know there is if there could be pending
579 stack adjustment needed at that point. */
580 restore_from_sp
= ! frame_pointer_needed
581 || (! current_function_calls_alloca
&& leaf_function_p ());
582 if (offset
+ fsize
>= 0x8000
584 && (mask
|| fmask
|| fpoffset
))
587 asm_fprintf (stream
, "\t%Omove.l %0I%d,%Ra1\n", -fsize
);
589 asm_fprintf (stream
, "\tmovel %0I%d,%Ra1\n", -fsize
);
593 if (TARGET_5200
|| nregs
<= 2)
595 /* Restore each separately in the same order moveml does.
596 Using two movel instructions instead of a single moveml
597 is about 15% faster for the 68020 and 68030 at no expense
602 /* Undo the work from above. */
603 for (i
= 0; i
< 16; i
++)
609 asm_fprintf (stream
, "\t%Omove.l -%d(%s,%Ra1.l),%s\n",
611 reg_names
[FRAME_POINTER_REGNUM
],
614 asm_fprintf (stream
, "\tmovel %s@(-%d,%Ra1:l),%s\n",
615 reg_names
[FRAME_POINTER_REGNUM
],
616 offset
+ fsize
, reg_names
[i
]);
619 else if (restore_from_sp
)
622 asm_fprintf (stream
, "\t%Omove.l (%Rsp)+,%s\n",
625 asm_fprintf (stream
, "\tmovel %Rsp@+,%s\n",
632 asm_fprintf (stream
, "\t%Omove.l -%d(%s),%s\n",
634 reg_names
[FRAME_POINTER_REGNUM
],
637 asm_fprintf (stream
, "\tmovel %s@(-%d),%s\n",
638 reg_names
[FRAME_POINTER_REGNUM
],
639 offset
+ fsize
, reg_names
[i
]);
650 asm_fprintf (stream
, "\tmovm.l -%d(%s,%Ra1.l),%0I0x%x\n",
652 reg_names
[FRAME_POINTER_REGNUM
],
655 asm_fprintf (stream
, "\tmoveml %s@(-%d,%Ra1:l),%0I0x%x\n",
656 reg_names
[FRAME_POINTER_REGNUM
],
657 offset
+ fsize
, mask
);
660 else if (restore_from_sp
)
663 asm_fprintf (stream
, "\tmovm.l (%Rsp)+,%0I0x%x\n", mask
);
665 asm_fprintf (stream
, "\tmoveml %Rsp@+,%0I0x%x\n", mask
);
671 asm_fprintf (stream
, "\tmovm.l -%d(%s),%0I0x%x\n",
673 reg_names
[FRAME_POINTER_REGNUM
],
676 asm_fprintf (stream
, "\tmoveml %s@(-%d),%0I0x%x\n",
677 reg_names
[FRAME_POINTER_REGNUM
],
678 offset
+ fsize
, mask
);
687 asm_fprintf (stream
, "\tfmovm -%d(%s,%Ra1.l),%0I0x%x\n",
689 reg_names
[FRAME_POINTER_REGNUM
],
692 asm_fprintf (stream
, "\tfmovem %s@(-%d,%Ra1:l),%0I0x%x\n",
693 reg_names
[FRAME_POINTER_REGNUM
],
694 foffset
+ fsize
, fmask
);
697 else if (restore_from_sp
)
700 asm_fprintf (stream
, "\tfmovm (%Rsp)+,%0I0x%x\n", fmask
);
702 asm_fprintf (stream
, "\tfmovem %Rsp@+,%0I0x%x\n", fmask
);
708 asm_fprintf (stream
, "\tfmovm -%d(%s),%0I0x%x\n",
710 reg_names
[FRAME_POINTER_REGNUM
],
713 asm_fprintf (stream
, "\tfmovem %s@(-%d),%0I0x%x\n",
714 reg_names
[FRAME_POINTER_REGNUM
],
715 foffset
+ fsize
, fmask
);
720 for (regno
= 55; regno
>= 24; regno
--)
721 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
726 asm_fprintf (stream
, "\tfpmovd -%d(%s,%Ra1.l), %s\n",
728 reg_names
[FRAME_POINTER_REGNUM
],
731 asm_fprintf (stream
, "\tfpmoved %s@(-%d,%Ra1:l), %s\n",
732 reg_names
[FRAME_POINTER_REGNUM
],
733 fpoffset
+ fsize
, reg_names
[regno
]);
736 else if (restore_from_sp
)
739 asm_fprintf (stream
, "\tfpmovd (%Rsp)+,%s\n",
742 asm_fprintf (stream
, "\tfpmoved %Rsp@+, %s\n",
749 asm_fprintf (stream
, "\tfpmovd -%d(%s), %s\n",
751 reg_names
[FRAME_POINTER_REGNUM
],
754 asm_fprintf (stream
, "\tfpmoved %s@(-%d), %s\n",
755 reg_names
[FRAME_POINTER_REGNUM
],
756 fpoffset
+ fsize
, reg_names
[regno
]);
761 if (frame_pointer_needed
)
762 fprintf (stream
, "\tunlk %s\n",
763 reg_names
[FRAME_POINTER_REGNUM
]);
772 asm_fprintf (stream
, "\taddq.w %0I%d,%Rsp\n", fsize
+ 4);
774 asm_fprintf (stream
, "\taddqw %0I%d,%Rsp\n", fsize
+ 4);
780 asm_fprintf (stream
, "\taddq.l %0I%d,%Rsp\n", fsize
+ 4);
782 asm_fprintf (stream
, "\taddql %0I%d,%Rsp\n", fsize
+ 4);
786 else if (fsize
+ 4 <= 16 && TARGET_CPU32
)
788 /* On the CPU32 it is faster to use two addqw instructions to
789 add a small integer (8 < N <= 16) to a register. */
790 /* asm_fprintf() cannot handle %. */
792 asm_fprintf (stream
, "\taddq.w %0I8,%Rsp\n\taddq.w %0I%d,%Rsp\n",
795 asm_fprintf (stream
, "\taddqw %0I8,%Rsp\n\taddqw %0I%d,%Rsp\n",
800 #endif /* not NO_ADDSUB_Q */
801 if (fsize
+ 4 < 0x8000)
805 /* asm_fprintf() cannot handle %. */
807 asm_fprintf (stream
, "\tadd.w %0I%d,%Rsp\n", fsize
+ 4);
809 asm_fprintf (stream
, "\taddw %0I%d,%Rsp\n", fsize
+ 4);
815 asm_fprintf (stream
, "\tlea (%d,%Rsp),%Rsp\n", fsize
+ 4);
817 asm_fprintf (stream
, "\tlea %Rsp@(%d),%Rsp\n", fsize
+ 4);
823 /* asm_fprintf() cannot handle %. */
825 asm_fprintf (stream
, "\tadd.l %0I%d,%Rsp\n", fsize
+ 4);
827 asm_fprintf (stream
, "\taddl %0I%d,%Rsp\n", fsize
+ 4);
831 if (current_function_pops_args
)
832 asm_fprintf (stream
, "\trtd %0I%d\n", current_function_pops_args
);
834 fprintf (stream
, "\trts\n");
837 /* Similar to general_operand, but exclude stack_pointer_rtx. */
840 not_sp_operand (op
, mode
)
842 enum machine_mode mode
;
844 return op
!= stack_pointer_rtx
&& general_operand (op
, mode
);
847 /* Return TRUE if X is a valid comparison operator for the dbcc
850 Note it rejects floating point comparison operators.
851 (In the future we could use Fdbcc).
853 It also rejects some comparisons when CC_NO_OVERFLOW is set. */
856 valid_dbcc_comparison_p (x
, mode
)
858 enum machine_mode mode ATTRIBUTE_UNUSED
;
860 switch (GET_CODE (x
))
862 case EQ
: case NE
: case GTU
: case LTU
:
866 /* Reject some when CC_NO_OVERFLOW is set. This may be over
868 case GT
: case LT
: case GE
: case LE
:
869 return ! (cc_prev_status
.flags
& CC_NO_OVERFLOW
);
875 /* Return non-zero if flags are currently in the 68881 flag register. */
879 /* We could add support for these in the future */
880 return cc_status
.flags
& CC_IN_68881
;
883 /* Output a dbCC; jCC sequence. Note we do not handle the
884 floating point version of this sequence (Fdbcc). We also
885 do not handle alternative conditions when CC_NO_OVERFLOW is
886 set. It is assumed that valid_dbcc_comparison_p and flags_in_68881 will
887 kick those out before we get here. */
890 output_dbcc_and_branch (operands
)
893 switch (GET_CODE (operands
[3]))
897 output_asm_insn ("dbeq %0,%l1\n\tjbeq %l2", operands
);
899 output_asm_insn ("dbeq %0,%l1\n\tjeq %l2", operands
);
905 output_asm_insn ("dbne %0,%l1\n\tjbne %l2", operands
);
907 output_asm_insn ("dbne %0,%l1\n\tjne %l2", operands
);
913 output_asm_insn ("dbgt %0,%l1\n\tjbgt %l2", operands
);
915 output_asm_insn ("dbgt %0,%l1\n\tjgt %l2", operands
);
921 output_asm_insn ("dbhi %0,%l1\n\tjbhi %l2", operands
);
923 output_asm_insn ("dbhi %0,%l1\n\tjhi %l2", operands
);
929 output_asm_insn ("dblt %0,%l1\n\tjblt %l2", operands
);
931 output_asm_insn ("dblt %0,%l1\n\tjlt %l2", operands
);
937 output_asm_insn ("dbcs %0,%l1\n\tjbcs %l2", operands
);
939 output_asm_insn ("dbcs %0,%l1\n\tjcs %l2", operands
);
945 output_asm_insn ("dbge %0,%l1\n\tjbge %l2", operands
);
947 output_asm_insn ("dbge %0,%l1\n\tjge %l2", operands
);
953 output_asm_insn ("dbcc %0,%l1\n\tjbcc %l2", operands
);
955 output_asm_insn ("dbcc %0,%l1\n\tjcc %l2", operands
);
961 output_asm_insn ("dble %0,%l1\n\tjble %l2", operands
);
963 output_asm_insn ("dble %0,%l1\n\tjle %l2", operands
);
969 output_asm_insn ("dbls %0,%l1\n\tjbls %l2", operands
);
971 output_asm_insn ("dbls %0,%l1\n\tjls %l2", operands
);
979 /* If the decrement is to be done in SImode, then we have
980 to compensate for the fact that dbcc decrements in HImode. */
981 switch (GET_MODE (operands
[0]))
985 output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjbpl %l1", operands
);
987 output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjpl %l1", operands
);
1000 output_scc_di(op
, operand1
, operand2
, dest
)
1007 enum rtx_code op_code
= GET_CODE (op
);
1009 /* This does not produce a usefull cc. */
1012 /* The m68k cmp.l instruction requires operand1 to be a reg as used
1013 below. Swap the operands and change the op if these requirements
1014 are not fulfilled. */
1015 if (GET_CODE (operand2
) == REG
&& GET_CODE (operand1
) != REG
)
1019 operand1
= operand2
;
1021 op_code
= swap_condition (op_code
);
1023 loperands
[0] = operand1
;
1024 if (GET_CODE (operand1
) == REG
)
1025 loperands
[1] = gen_rtx_REG (SImode
, REGNO (operand1
) + 1);
1027 loperands
[1] = adj_offsettable_operand (operand1
, 4);
1028 if (operand2
!= const0_rtx
)
1030 loperands
[2] = operand2
;
1031 if (GET_CODE (operand2
) == REG
)
1032 loperands
[3] = gen_rtx_REG (SImode
, REGNO (operand2
) + 1);
1034 loperands
[3] = adj_offsettable_operand (operand2
, 4);
1036 loperands
[4] = gen_label_rtx();
1037 if (operand2
!= const0_rtx
)
1040 #ifdef SGS_CMP_ORDER
1041 output_asm_insn ("cmp%.l %0,%2\n\tjbne %l4\n\tcmp%.l %1,%3", loperands
);
1043 output_asm_insn ("cmp%.l %2,%0\n\tjbne %l4\n\tcmp%.l %3,%1", loperands
);
1046 #ifdef SGS_CMP_ORDER
1047 output_asm_insn ("cmp%.l %0,%2\n\tjne %l4\n\tcmp%.l %1,%3", loperands
);
1049 output_asm_insn ("cmp%.l %2,%0\n\tjne %l4\n\tcmp%.l %3,%1", loperands
);
1055 if (TARGET_68020
|| TARGET_5200
|| ! ADDRESS_REG_P (loperands
[0]))
1056 output_asm_insn ("tst%.l %0", loperands
);
1059 #ifdef SGS_CMP_ORDER
1060 output_asm_insn ("cmp%.w %0,%#0", loperands
);
1062 output_asm_insn ("cmp%.w %#0,%0", loperands
);
1067 output_asm_insn ("jbne %l4", loperands
);
1069 output_asm_insn ("jne %l4", loperands
);
1072 if (TARGET_68020
|| TARGET_5200
|| ! ADDRESS_REG_P (loperands
[1]))
1073 output_asm_insn ("tst%.l %1", loperands
);
1076 #ifdef SGS_CMP_ORDER
1077 output_asm_insn ("cmp%.w %1,%#0", loperands
);
1079 output_asm_insn ("cmp%.w %#0,%1", loperands
);
1084 loperands
[5] = dest
;
1089 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1090 CODE_LABEL_NUMBER (loperands
[4]));
1091 output_asm_insn ("seq %5", loperands
);
1095 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1096 CODE_LABEL_NUMBER (loperands
[4]));
1097 output_asm_insn ("sne %5", loperands
);
1101 loperands
[6] = gen_label_rtx();
1103 output_asm_insn ("shi %5\n\tjbra %l6", loperands
);
1105 output_asm_insn ("shi %5\n\tjra %l6", loperands
);
1107 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1108 CODE_LABEL_NUMBER (loperands
[4]));
1109 output_asm_insn ("sgt %5", loperands
);
1110 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1111 CODE_LABEL_NUMBER (loperands
[6]));
1115 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1116 CODE_LABEL_NUMBER (loperands
[4]));
1117 output_asm_insn ("shi %5", loperands
);
1121 loperands
[6] = gen_label_rtx();
1123 output_asm_insn ("scs %5\n\tjbra %l6", loperands
);
1125 output_asm_insn ("scs %5\n\tjra %l6", loperands
);
1127 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1128 CODE_LABEL_NUMBER (loperands
[4]));
1129 output_asm_insn ("slt %5", loperands
);
1130 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1131 CODE_LABEL_NUMBER (loperands
[6]));
1135 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1136 CODE_LABEL_NUMBER (loperands
[4]));
1137 output_asm_insn ("scs %5", loperands
);
1141 loperands
[6] = gen_label_rtx();
1143 output_asm_insn ("scc %5\n\tjbra %l6", loperands
);
1145 output_asm_insn ("scc %5\n\tjra %l6", loperands
);
1147 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1148 CODE_LABEL_NUMBER (loperands
[4]));
1149 output_asm_insn ("sge %5", loperands
);
1150 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1151 CODE_LABEL_NUMBER (loperands
[6]));
1155 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1156 CODE_LABEL_NUMBER (loperands
[4]));
1157 output_asm_insn ("scc %5", loperands
);
1161 loperands
[6] = gen_label_rtx();
1163 output_asm_insn ("sls %5\n\tjbra %l6", loperands
);
1165 output_asm_insn ("sls %5\n\tjra %l6", loperands
);
1167 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1168 CODE_LABEL_NUMBER (loperands
[4]));
1169 output_asm_insn ("sle %5", loperands
);
1170 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1171 CODE_LABEL_NUMBER (loperands
[6]));
1175 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1176 CODE_LABEL_NUMBER (loperands
[4]));
1177 output_asm_insn ("sls %5", loperands
);
1187 output_btst (operands
, countop
, dataop
, insn
, signpos
)
1189 rtx countop
, dataop
;
1193 operands
[0] = countop
;
1194 operands
[1] = dataop
;
1196 if (GET_CODE (countop
) == CONST_INT
)
1198 register int count
= INTVAL (countop
);
1199 /* If COUNT is bigger than size of storage unit in use,
1200 advance to the containing unit of same size. */
1201 if (count
> signpos
)
1203 int offset
= (count
& ~signpos
) / 8;
1204 count
= count
& signpos
;
1205 operands
[1] = dataop
= adj_offsettable_operand (dataop
, offset
);
1207 if (count
== signpos
)
1208 cc_status
.flags
= CC_NOT_POSITIVE
| CC_Z_IN_NOT_N
;
1210 cc_status
.flags
= CC_NOT_NEGATIVE
| CC_Z_IN_NOT_N
;
1212 /* These three statements used to use next_insns_test_no...
1213 but it appears that this should do the same job. */
1215 && next_insn_tests_no_inequality (insn
))
1218 && next_insn_tests_no_inequality (insn
))
1221 && next_insn_tests_no_inequality (insn
))
1224 cc_status
.flags
= CC_NOT_NEGATIVE
;
1226 return "btst %0,%1";
1229 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
1230 reference and a constant. */
1233 symbolic_operand (op
, mode
)
1235 enum machine_mode mode ATTRIBUTE_UNUSED
;
1237 switch (GET_CODE (op
))
1245 return ((GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
1246 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
)
1247 && GET_CODE (XEXP (op
, 1)) == CONST_INT
);
1249 #if 0 /* Deleted, with corresponding change in m68k.h,
1250 so as to fit the specs. No CONST_DOUBLE is ever symbolic. */
1252 return GET_MODE (op
) == mode
;
1260 /* Check for sign_extend or zero_extend. Used for bit-count operands. */
1263 extend_operator(x
, mode
)
1265 enum machine_mode mode
;
1267 if (mode
!= VOIDmode
&& GET_MODE(x
) != mode
)
1269 switch (GET_CODE(x
))
1280 /* Legitimize PIC addresses. If the address is already
1281 position-independent, we return ORIG. Newly generated
1282 position-independent addresses go to REG. If we need more
1283 than one register, we lose.
1285 An address is legitimized by making an indirect reference
1286 through the Global Offset Table with the name of the symbol
1289 The assembler and linker are responsible for placing the
1290 address of the symbol in the GOT. The function prologue
1291 is responsible for initializing a5 to the starting address
1294 The assembler is also responsible for translating a symbol name
1295 into a constant displacement from the start of the GOT.
1297 A quick example may make things a little clearer:
1299 When not generating PIC code to store the value 12345 into _foo
1300 we would generate the following code:
1304 When generating PIC two transformations are made. First, the compiler
1305 loads the address of foo into a register. So the first transformation makes:
1310 The code in movsi will intercept the lea instruction and call this
1311 routine which will transform the instructions into:
1313 movel a5@(_foo:w), a0
1317 That (in a nutshell) is how *all* symbol and label references are
1321 legitimize_pic_address (orig
, mode
, reg
)
1323 enum machine_mode mode ATTRIBUTE_UNUSED
;
1327 /* First handle a simple SYMBOL_REF or LABEL_REF */
1328 if (GET_CODE (orig
) == SYMBOL_REF
|| GET_CODE (orig
) == LABEL_REF
)
1333 pic_ref
= gen_rtx_MEM (Pmode
,
1334 gen_rtx_PLUS (Pmode
,
1335 pic_offset_table_rtx
, orig
));
1336 current_function_uses_pic_offset_table
= 1;
1337 if (reload_in_progress
)
1338 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
1339 RTX_UNCHANGING_P (pic_ref
) = 1;
1340 emit_move_insn (reg
, pic_ref
);
1343 else if (GET_CODE (orig
) == CONST
)
1347 /* Make sure this is CONST has not already been legitimized */
1348 if (GET_CODE (XEXP (orig
, 0)) == PLUS
1349 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
1355 /* legitimize both operands of the PLUS */
1356 if (GET_CODE (XEXP (orig
, 0)) == PLUS
)
1358 base
= legitimize_pic_address (XEXP (XEXP (orig
, 0), 0), Pmode
, reg
);
1359 orig
= legitimize_pic_address (XEXP (XEXP (orig
, 0), 1), Pmode
,
1360 base
== reg
? 0 : reg
);
1364 if (GET_CODE (orig
) == CONST_INT
)
1365 return plus_constant_for_output (base
, INTVAL (orig
));
1366 pic_ref
= gen_rtx_PLUS (Pmode
, base
, orig
);
1367 /* Likewise, should we set special REG_NOTEs here? */
1373 typedef enum { MOVL
, SWAP
, NEGW
, NOTW
, NOTB
, MOVQ
} CONST_METHOD
;
1375 #define USE_MOVQ(i) ((unsigned)((i) + 128) <= 255)
1378 const_method (constant
)
1384 i
= INTVAL (constant
);
1388 /* The Coldfire doesn't have byte or word operations. */
1389 /* FIXME: This may not be useful for the m68060 either */
1392 /* if -256 < N < 256 but N is not in range for a moveq
1393 N^ff will be, so use moveq #N^ff, dreg; not.b dreg. */
1394 if (USE_MOVQ (i
^ 0xff))
1396 /* Likewise, try with not.w */
1397 if (USE_MOVQ (i
^ 0xffff))
1399 /* This is the only value where neg.w is useful */
1402 /* Try also with swap */
1404 if (USE_MOVQ ((u
>> 16) | (u
<< 16)))
1407 /* Otherwise, use move.l */
1412 const_int_cost (constant
)
1415 switch (const_method (constant
))
1418 /* Constants between -128 and 127 are cheap due to moveq */
1424 /* Constants easily generated by moveq + not.b/not.w/neg.w/swap */
1434 output_move_const_into_data_reg (operands
)
1439 i
= INTVAL (operands
[1]);
1440 switch (const_method (operands
[1]))
1443 #if defined (MOTOROLA) && !defined (CRDS)
1444 return "moveq%.l %1,%0";
1446 return "moveq %1,%0";
1449 operands
[1] = GEN_INT (i
^ 0xff);
1450 #if defined (MOTOROLA) && !defined (CRDS)
1451 return "moveq%.l %1,%0\n\tnot%.b %0";
1453 return "moveq %1,%0\n\tnot%.b %0";
1456 operands
[1] = GEN_INT (i
^ 0xffff);
1457 #if defined (MOTOROLA) && !defined (CRDS)
1458 return "moveq%.l %1,%0\n\tnot%.w %0";
1460 return "moveq %1,%0\n\tnot%.w %0";
1463 #if defined (MOTOROLA) && !defined (CRDS)
1464 return "moveq%.l %#-128,%0\n\tneg%.w %0";
1466 return "moveq %#-128,%0\n\tneg%.w %0";
1472 operands
[1] = GEN_INT ((u
<< 16) | (u
>> 16));
1473 #if defined (MOTOROLA) && !defined (CRDS)
1474 return "moveq%.l %1,%0\n\tswap %0";
1476 return "moveq %1,%0\n\tswap %0";
1480 return "move%.l %1,%0";
1487 output_move_simode_const (operands
)
1490 if (operands
[1] == const0_rtx
1491 && (DATA_REG_P (operands
[0])
1492 || GET_CODE (operands
[0]) == MEM
)
1493 /* clr insns on 68000 read before writing.
1494 This isn't so on the 68010, but we have no TARGET_68010. */
1495 && ((TARGET_68020
|| TARGET_5200
)
1496 || !(GET_CODE (operands
[0]) == MEM
1497 && MEM_VOLATILE_P (operands
[0]))))
1499 else if (operands
[1] == const0_rtx
1500 && ADDRESS_REG_P (operands
[0]))
1501 return "sub%.l %0,%0";
1502 else if (DATA_REG_P (operands
[0]))
1503 return output_move_const_into_data_reg (operands
);
1504 else if (ADDRESS_REG_P (operands
[0])
1505 && INTVAL (operands
[1]) < 0x8000
1506 && INTVAL (operands
[1]) >= -0x8000)
1507 return "move%.w %1,%0";
1508 else if (GET_CODE (operands
[0]) == MEM
1509 && GET_CODE (XEXP (operands
[0], 0)) == PRE_DEC
1510 && REGNO (XEXP (XEXP (operands
[0], 0), 0)) == STACK_POINTER_REGNUM
1511 && INTVAL (operands
[1]) < 0x8000
1512 && INTVAL (operands
[1]) >= -0x8000)
1514 return "move%.l %1,%0";
1518 output_move_simode (operands
)
1521 if (GET_CODE (operands
[1]) == CONST_INT
)
1522 return output_move_simode_const (operands
);
1523 else if ((GET_CODE (operands
[1]) == SYMBOL_REF
1524 || GET_CODE (operands
[1]) == CONST
)
1525 && push_operand (operands
[0], SImode
))
1527 else if ((GET_CODE (operands
[1]) == SYMBOL_REF
1528 || GET_CODE (operands
[1]) == CONST
)
1529 && ADDRESS_REG_P (operands
[0]))
1530 return "lea %a1,%0";
1531 return "move%.l %1,%0";
1535 output_move_himode (operands
)
1538 if (GET_CODE (operands
[1]) == CONST_INT
)
1540 if (operands
[1] == const0_rtx
1541 && (DATA_REG_P (operands
[0])
1542 || GET_CODE (operands
[0]) == MEM
)
1543 /* clr insns on 68000 read before writing.
1544 This isn't so on the 68010, but we have no TARGET_68010. */
1545 && ((TARGET_68020
|| TARGET_5200
)
1546 || !(GET_CODE (operands
[0]) == MEM
1547 && MEM_VOLATILE_P (operands
[0]))))
1549 else if (operands
[1] == const0_rtx
1550 && ADDRESS_REG_P (operands
[0]))
1551 return "sub%.l %0,%0";
1552 else if (DATA_REG_P (operands
[0])
1553 && INTVAL (operands
[1]) < 128
1554 && INTVAL (operands
[1]) >= -128)
1556 #if defined(MOTOROLA) && !defined(CRDS)
1557 return "moveq%.l %1,%0";
1559 return "moveq %1,%0";
1562 else if (INTVAL (operands
[1]) < 0x8000
1563 && INTVAL (operands
[1]) >= -0x8000)
1564 return "move%.w %1,%0";
1566 else if (CONSTANT_P (operands
[1]))
1567 return "move%.l %1,%0";
1569 /* Recognize the insn before a tablejump, one that refers
1570 to a table of offsets. Such an insn will need to refer
1571 to a label on the insn. So output one. Use the label-number
1572 of the table of offsets to generate this label. This code,
1573 and similar code below, assumes that there will be at most one
1574 reference to each table. */
1575 if (GET_CODE (operands
[1]) == MEM
1576 && GET_CODE (XEXP (operands
[1], 0)) == PLUS
1577 && GET_CODE (XEXP (XEXP (operands
[1], 0), 1)) == LABEL_REF
1578 && GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) != PLUS
)
1580 rtx labelref
= XEXP (XEXP (operands
[1], 0), 1);
1581 #if defined (MOTOROLA) && !defined (SGS_SWITCH_TABLES)
1583 asm_fprintf (asm_out_file
, "\tset %LLI%d,.+2\n",
1584 CODE_LABEL_NUMBER (XEXP (labelref
, 0)));
1586 asm_fprintf (asm_out_file
, "\t.set %LLI%d,.+2\n",
1587 CODE_LABEL_NUMBER (XEXP (labelref
, 0)));
1588 #endif /* not SGS */
1589 #else /* SGS_SWITCH_TABLES or not MOTOROLA */
1590 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "LI",
1591 CODE_LABEL_NUMBER (XEXP (labelref
, 0)));
1592 #ifdef SGS_SWITCH_TABLES
1593 /* Set flag saying we need to define the symbol
1594 LD%n (with value L%n-LI%n) at the end of the switch table. */
1595 switch_table_difference_label_flag
= 1;
1596 #endif /* SGS_SWITCH_TABLES */
1597 #endif /* SGS_SWITCH_TABLES or not MOTOROLA */
1599 #endif /* SGS_NO_LI */
1600 return "move%.w %1,%0";
1604 output_move_qimode (operands
)
1609 /* This is probably useless, since it loses for pushing a struct
1610 of several bytes a byte at a time. */
1611 /* 68k family always modifies the stack pointer by at least 2, even for
1612 byte pushes. The 5200 (coldfire) does not do this. */
1613 if (GET_CODE (operands
[0]) == MEM
1614 && GET_CODE (XEXP (operands
[0], 0)) == PRE_DEC
1615 && XEXP (XEXP (operands
[0], 0), 0) == stack_pointer_rtx
1616 && ! ADDRESS_REG_P (operands
[1])
1619 xoperands
[1] = operands
[1];
1621 = gen_rtx_MEM (QImode
,
1622 gen_rtx_PLUS (VOIDmode
, stack_pointer_rtx
, const1_rtx
));
1623 /* Just pushing a byte puts it in the high byte of the halfword. */
1624 /* We must put it in the low-order, high-numbered byte. */
1625 if (!reg_mentioned_p (stack_pointer_rtx
, operands
[1]))
1627 xoperands
[3] = stack_pointer_rtx
;
1629 output_asm_insn ("subq%.l %#2,%3\n\tmove%.b %1,%2", xoperands
);
1631 output_asm_insn ("sub%.l %#2,%3\n\tmove%.b %1,%2", xoperands
);
1635 output_asm_insn ("move%.b %1,%-\n\tmove%.b %@,%2", xoperands
);
1639 /* clr and st insns on 68000 read before writing.
1640 This isn't so on the 68010, but we have no TARGET_68010. */
1641 if (!ADDRESS_REG_P (operands
[0])
1642 && ((TARGET_68020
|| TARGET_5200
)
1643 || !(GET_CODE (operands
[0]) == MEM
&& MEM_VOLATILE_P (operands
[0]))))
1645 if (operands
[1] == const0_rtx
)
1647 if ((!TARGET_5200
|| DATA_REG_P (operands
[0]))
1648 && GET_CODE (operands
[1]) == CONST_INT
1649 && (INTVAL (operands
[1]) & 255) == 255)
1655 if (GET_CODE (operands
[1]) == CONST_INT
1656 && DATA_REG_P (operands
[0])
1657 && INTVAL (operands
[1]) < 128
1658 && INTVAL (operands
[1]) >= -128)
1660 #if defined(MOTOROLA) && !defined(CRDS)
1661 return "moveq%.l %1,%0";
1663 return "moveq %1,%0";
1666 if (operands
[1] == const0_rtx
&& ADDRESS_REG_P (operands
[0]))
1667 return "sub%.l %0,%0";
1668 if (GET_CODE (operands
[1]) != CONST_INT
&& CONSTANT_P (operands
[1]))
1669 return "move%.l %1,%0";
1670 /* 68k family (including the 5200 coldfire) does not support byte moves to
1671 from address registers. */
1672 if (ADDRESS_REG_P (operands
[0]) || ADDRESS_REG_P (operands
[1]))
1673 return "move%.w %1,%0";
1674 return "move%.b %1,%0";
1678 output_move_stricthi (operands
)
1681 if (operands
[1] == const0_rtx
1682 /* clr insns on 68000 read before writing.
1683 This isn't so on the 68010, but we have no TARGET_68010. */
1684 && ((TARGET_68020
|| TARGET_5200
)
1685 || !(GET_CODE (operands
[0]) == MEM
&& MEM_VOLATILE_P (operands
[0]))))
1687 return "move%.w %1,%0";
1691 output_move_strictqi (operands
)
1694 if (operands
[1] == const0_rtx
1695 /* clr insns on 68000 read before writing.
1696 This isn't so on the 68010, but we have no TARGET_68010. */
1697 && ((TARGET_68020
|| TARGET_5200
)
1698 || !(GET_CODE (operands
[0]) == MEM
&& MEM_VOLATILE_P (operands
[0]))))
1700 return "move%.b %1,%0";
1703 /* Return the best assembler insn template
1704 for moving operands[1] into operands[0] as a fullword. */
1707 singlemove_string (operands
)
1710 #ifdef SUPPORT_SUN_FPA
1711 if (FPA_REG_P (operands
[0]) || FPA_REG_P (operands
[1]))
1712 return "fpmoves %1,%0";
1714 if (GET_CODE (operands
[1]) == CONST_INT
)
1715 return output_move_simode_const (operands
);
1716 return "move%.l %1,%0";
1720 /* Output assembler code to perform a doubleword move insn
1721 with operands OPERANDS. */
1724 output_move_double (operands
)
1729 REGOP
, OFFSOP
, MEMOP
, PUSHOP
, POPOP
, CNSTOP
, RNDOP
1734 rtx addreg0
= 0, addreg1
= 0;
1735 int dest_overlapped_low
= 0;
1736 int size
= GET_MODE_SIZE (GET_MODE (operands
[0]));
1741 /* First classify both operands. */
1743 if (REG_P (operands
[0]))
1745 else if (offsettable_memref_p (operands
[0]))
1747 else if (GET_CODE (XEXP (operands
[0], 0)) == POST_INC
)
1749 else if (GET_CODE (XEXP (operands
[0], 0)) == PRE_DEC
)
1751 else if (GET_CODE (operands
[0]) == MEM
)
1756 if (REG_P (operands
[1]))
1758 else if (CONSTANT_P (operands
[1]))
1760 else if (offsettable_memref_p (operands
[1]))
1762 else if (GET_CODE (XEXP (operands
[1], 0)) == POST_INC
)
1764 else if (GET_CODE (XEXP (operands
[1], 0)) == PRE_DEC
)
1766 else if (GET_CODE (operands
[1]) == MEM
)
1771 /* Check for the cases that the operand constraints are not
1772 supposed to allow to happen. Abort if we get one,
1773 because generating code for these cases is painful. */
1775 if (optype0
== RNDOP
|| optype1
== RNDOP
)
1778 /* If one operand is decrementing and one is incrementing
1779 decrement the former register explicitly
1780 and change that operand into ordinary indexing. */
1782 if (optype0
== PUSHOP
&& optype1
== POPOP
)
1784 operands
[0] = XEXP (XEXP (operands
[0], 0), 0);
1786 output_asm_insn ("sub%.l %#12,%0", operands
);
1788 output_asm_insn ("subq%.l %#8,%0", operands
);
1789 if (GET_MODE (operands
[1]) == XFmode
)
1790 operands
[0] = gen_rtx_MEM (XFmode
, operands
[0]);
1791 else if (GET_MODE (operands
[0]) == DFmode
)
1792 operands
[0] = gen_rtx_MEM (DFmode
, operands
[0]);
1794 operands
[0] = gen_rtx_MEM (DImode
, operands
[0]);
1797 if (optype0
== POPOP
&& optype1
== PUSHOP
)
1799 operands
[1] = XEXP (XEXP (operands
[1], 0), 0);
1801 output_asm_insn ("sub%.l %#12,%1", operands
);
1803 output_asm_insn ("subq%.l %#8,%1", operands
);
1804 if (GET_MODE (operands
[1]) == XFmode
)
1805 operands
[1] = gen_rtx_MEM (XFmode
, operands
[1]);
1806 else if (GET_MODE (operands
[1]) == DFmode
)
1807 operands
[1] = gen_rtx_MEM (DFmode
, operands
[1]);
1809 operands
[1] = gen_rtx_MEM (DImode
, operands
[1]);
1813 /* If an operand is an unoffsettable memory ref, find a register
1814 we can increment temporarily to make it refer to the second word. */
1816 if (optype0
== MEMOP
)
1817 addreg0
= find_addr_reg (XEXP (operands
[0], 0));
1819 if (optype1
== MEMOP
)
1820 addreg1
= find_addr_reg (XEXP (operands
[1], 0));
1822 /* Ok, we can do one word at a time.
1823 Normally we do the low-numbered word first,
1824 but if either operand is autodecrementing then we
1825 do the high-numbered word first.
1827 In either case, set up in LATEHALF the operands to use
1828 for the high-numbered word and in some cases alter the
1829 operands in OPERANDS to be suitable for the low-numbered word. */
1833 if (optype0
== REGOP
)
1835 latehalf
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 2);
1836 middlehalf
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 1);
1838 else if (optype0
== OFFSOP
)
1840 middlehalf
[0] = adj_offsettable_operand (operands
[0], 4);
1841 latehalf
[0] = adj_offsettable_operand (operands
[0], size
- 4);
1845 middlehalf
[0] = operands
[0];
1846 latehalf
[0] = operands
[0];
1849 if (optype1
== REGOP
)
1851 latehalf
[1] = gen_rtx_REG (SImode
, REGNO (operands
[1]) + 2);
1852 middlehalf
[1] = gen_rtx_REG (SImode
, REGNO (operands
[1]) + 1);
1854 else if (optype1
== OFFSOP
)
1856 middlehalf
[1] = adj_offsettable_operand (operands
[1], 4);
1857 latehalf
[1] = adj_offsettable_operand (operands
[1], size
- 4);
1859 else if (optype1
== CNSTOP
)
1861 if (GET_CODE (operands
[1]) == CONST_DOUBLE
)
1866 REAL_VALUE_FROM_CONST_DOUBLE (r
, operands
[1]);
1867 REAL_VALUE_TO_TARGET_LONG_DOUBLE (r
, l
);
1868 operands
[1] = GEN_INT (l
[0]);
1869 middlehalf
[1] = GEN_INT (l
[1]);
1870 latehalf
[1] = GEN_INT (l
[2]);
1872 else if (CONSTANT_P (operands
[1]))
1874 /* actually, no non-CONST_DOUBLE constant should ever
1877 if (GET_CODE (operands
[1]) == CONST_INT
&& INTVAL (operands
[1]) < 0)
1878 latehalf
[1] = constm1_rtx
;
1880 latehalf
[1] = const0_rtx
;
1885 middlehalf
[1] = operands
[1];
1886 latehalf
[1] = operands
[1];
1890 /* size is not 12: */
1892 if (optype0
== REGOP
)
1893 latehalf
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 1);
1894 else if (optype0
== OFFSOP
)
1895 latehalf
[0] = adj_offsettable_operand (operands
[0], size
- 4);
1897 latehalf
[0] = operands
[0];
1899 if (optype1
== REGOP
)
1900 latehalf
[1] = gen_rtx_REG (SImode
, REGNO (operands
[1]) + 1);
1901 else if (optype1
== OFFSOP
)
1902 latehalf
[1] = adj_offsettable_operand (operands
[1], size
- 4);
1903 else if (optype1
== CNSTOP
)
1904 split_double (operands
[1], &operands
[1], &latehalf
[1]);
1906 latehalf
[1] = operands
[1];
1909 /* If insn is effectively movd N(sp),-(sp) then we will do the
1910 high word first. We should use the adjusted operand 1 (which is N+4(sp))
1911 for the low word as well, to compensate for the first decrement of sp. */
1912 if (optype0
== PUSHOP
1913 && REGNO (XEXP (XEXP (operands
[0], 0), 0)) == STACK_POINTER_REGNUM
1914 && reg_overlap_mentioned_p (stack_pointer_rtx
, operands
[1]))
1915 operands
[1] = middlehalf
[1] = latehalf
[1];
1917 /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)),
1918 if the upper part of reg N does not appear in the MEM, arrange to
1919 emit the move late-half first. Otherwise, compute the MEM address
1920 into the upper part of N and use that as a pointer to the memory
1922 if (optype0
== REGOP
1923 && (optype1
== OFFSOP
|| optype1
== MEMOP
))
1925 rtx testlow
= gen_rtx_REG (SImode
, REGNO (operands
[0]));
1927 if (reg_overlap_mentioned_p (testlow
, XEXP (operands
[1], 0))
1928 && reg_overlap_mentioned_p (latehalf
[0], XEXP (operands
[1], 0)))
1930 /* If both halves of dest are used in the src memory address,
1931 compute the address into latehalf of dest.
1932 Note that this can't happen if the dest is two data regs. */
1934 xops
[0] = latehalf
[0];
1935 xops
[1] = XEXP (operands
[1], 0);
1936 output_asm_insn ("lea %a1,%0", xops
);
1937 if( GET_MODE (operands
[1]) == XFmode
)
1939 operands
[1] = gen_rtx_MEM (XFmode
, latehalf
[0]);
1940 middlehalf
[1] = adj_offsettable_operand (operands
[1], size
-8);
1941 latehalf
[1] = adj_offsettable_operand (operands
[1], size
-4);
1945 operands
[1] = gen_rtx_MEM (DImode
, latehalf
[0]);
1946 latehalf
[1] = adj_offsettable_operand (operands
[1], size
-4);
1950 && reg_overlap_mentioned_p (middlehalf
[0],
1951 XEXP (operands
[1], 0)))
1953 /* Check for two regs used by both source and dest.
1954 Note that this can't happen if the dest is all data regs.
1955 It can happen if the dest is d6, d7, a0.
1956 But in that case, latehalf is an addr reg, so
1957 the code at compadr does ok. */
1959 if (reg_overlap_mentioned_p (testlow
, XEXP (operands
[1], 0))
1960 || reg_overlap_mentioned_p (latehalf
[0], XEXP (operands
[1], 0)))
1963 /* JRV says this can't happen: */
1964 if (addreg0
|| addreg1
)
1967 /* Only the middle reg conflicts; simply put it last. */
1968 output_asm_insn (singlemove_string (operands
), operands
);
1969 output_asm_insn (singlemove_string (latehalf
), latehalf
);
1970 output_asm_insn (singlemove_string (middlehalf
), middlehalf
);
1973 else if (reg_overlap_mentioned_p (testlow
, XEXP (operands
[1], 0)))
1974 /* If the low half of dest is mentioned in the source memory
1975 address, the arrange to emit the move late half first. */
1976 dest_overlapped_low
= 1;
1979 /* If one or both operands autodecrementing,
1980 do the two words, high-numbered first. */
1982 /* Likewise, the first move would clobber the source of the second one,
1983 do them in the other order. This happens only for registers;
1984 such overlap can't happen in memory unless the user explicitly
1985 sets it up, and that is an undefined circumstance. */
1987 if (optype0
== PUSHOP
|| optype1
== PUSHOP
1988 || (optype0
== REGOP
&& optype1
== REGOP
1989 && ((middlehalf
[1] && REGNO (operands
[0]) == REGNO (middlehalf
[1]))
1990 || REGNO (operands
[0]) == REGNO (latehalf
[1])))
1991 || dest_overlapped_low
)
1993 /* Make any unoffsettable addresses point at high-numbered word. */
1997 output_asm_insn ("addq%.l %#8,%0", &addreg0
);
1999 output_asm_insn ("addq%.l %#4,%0", &addreg0
);
2004 output_asm_insn ("addq%.l %#8,%0", &addreg1
);
2006 output_asm_insn ("addq%.l %#4,%0", &addreg1
);
2010 output_asm_insn (singlemove_string (latehalf
), latehalf
);
2012 /* Undo the adds we just did. */
2014 output_asm_insn ("subq%.l %#4,%0", &addreg0
);
2016 output_asm_insn ("subq%.l %#4,%0", &addreg1
);
2020 output_asm_insn (singlemove_string (middlehalf
), middlehalf
);
2022 output_asm_insn ("subq%.l %#4,%0", &addreg0
);
2024 output_asm_insn ("subq%.l %#4,%0", &addreg1
);
2027 /* Do low-numbered word. */
2028 return singlemove_string (operands
);
2031 /* Normal case: do the two words, low-numbered first. */
2033 output_asm_insn (singlemove_string (operands
), operands
);
2035 /* Do the middle one of the three words for long double */
2039 output_asm_insn ("addq%.l %#4,%0", &addreg0
);
2041 output_asm_insn ("addq%.l %#4,%0", &addreg1
);
2043 output_asm_insn (singlemove_string (middlehalf
), middlehalf
);
2046 /* Make any unoffsettable addresses point at high-numbered word. */
2048 output_asm_insn ("addq%.l %#4,%0", &addreg0
);
2050 output_asm_insn ("addq%.l %#4,%0", &addreg1
);
2053 output_asm_insn (singlemove_string (latehalf
), latehalf
);
2055 /* Undo the adds we just did. */
2059 output_asm_insn ("subq%.l %#8,%0", &addreg0
);
2061 output_asm_insn ("subq%.l %#4,%0", &addreg0
);
2066 output_asm_insn ("subq%.l %#8,%0", &addreg1
);
2068 output_asm_insn ("subq%.l %#4,%0", &addreg1
);
2074 /* Return a REG that occurs in ADDR with coefficient 1.
2075 ADDR can be effectively incremented by incrementing REG. */
2078 find_addr_reg (addr
)
2081 while (GET_CODE (addr
) == PLUS
)
2083 if (GET_CODE (XEXP (addr
, 0)) == REG
)
2084 addr
= XEXP (addr
, 0);
2085 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
2086 addr
= XEXP (addr
, 1);
2087 else if (CONSTANT_P (XEXP (addr
, 0)))
2088 addr
= XEXP (addr
, 1);
2089 else if (CONSTANT_P (XEXP (addr
, 1)))
2090 addr
= XEXP (addr
, 0);
2094 if (GET_CODE (addr
) == REG
)
2099 /* Output assembler code to perform a 32 bit 3 operand add. */
2102 output_addsi3 (operands
)
2105 if (! operands_match_p (operands
[0], operands
[1]))
2107 if (!ADDRESS_REG_P (operands
[1]))
2109 rtx tmp
= operands
[1];
2111 operands
[1] = operands
[2];
2115 /* These insns can result from reloads to access
2116 stack slots over 64k from the frame pointer. */
2117 if (GET_CODE (operands
[2]) == CONST_INT
2118 && INTVAL (operands
[2]) + 0x8000 >= (unsigned) 0x10000)
2119 return "move%.l %2,%0\n\tadd%.l %1,%0";
2121 if (GET_CODE (operands
[2]) == REG
)
2122 return "lea 0(%1,%2.l),%0";
2124 return "lea %c2(%1),%0";
2127 if (GET_CODE (operands
[2]) == REG
)
2128 return "lea (%1,%2.l),%0";
2130 return "lea (%c2,%1),%0";
2131 #else /* not MOTOROLA (MIT syntax) */
2132 if (GET_CODE (operands
[2]) == REG
)
2133 return "lea %1@(0,%2:l),%0";
2135 return "lea %1@(%c2),%0";
2136 #endif /* not MOTOROLA */
2137 #endif /* not SGS */
2139 if (GET_CODE (operands
[2]) == CONST_INT
)
2142 if (INTVAL (operands
[2]) > 0
2143 && INTVAL (operands
[2]) <= 8)
2144 return "addq%.l %2,%0";
2145 if (INTVAL (operands
[2]) < 0
2146 && INTVAL (operands
[2]) >= -8)
2148 operands
[2] = GEN_INT (- INTVAL (operands
[2]));
2149 return "subq%.l %2,%0";
2151 /* On the CPU32 it is faster to use two addql instructions to
2152 add a small integer (8 < N <= 16) to a register.
2153 Likewise for subql. */
2154 if (TARGET_CPU32
&& REG_P (operands
[0]))
2156 if (INTVAL (operands
[2]) > 8
2157 && INTVAL (operands
[2]) <= 16)
2159 operands
[2] = GEN_INT (INTVAL (operands
[2]) - 8);
2160 return "addq%.l %#8,%0\n\taddq%.l %2,%0";
2162 if (INTVAL (operands
[2]) < -8
2163 && INTVAL (operands
[2]) >= -16)
2165 operands
[2] = GEN_INT (- INTVAL (operands
[2]) - 8);
2166 return "subq%.l %#8,%0\n\tsubq%.l %2,%0";
2170 if (ADDRESS_REG_P (operands
[0])
2171 && INTVAL (operands
[2]) >= -0x8000
2172 && INTVAL (operands
[2]) < 0x8000)
2175 return "add%.w %2,%0";
2178 return "lea (%c2,%0),%0";
2180 return "lea %0@(%c2),%0";
2184 return "add%.l %2,%0";
2187 /* Store in cc_status the expressions that the condition codes will
2188 describe after execution of an instruction whose pattern is EXP.
2189 Do not alter them if the instruction would not alter the cc's. */
2191 /* On the 68000, all the insns to store in an address register fail to
2192 set the cc's. However, in some cases these instructions can make it
2193 possibly invalid to use the saved cc's. In those cases we clear out
2194 some or all of the saved cc's so they won't be used. */
2197 notice_update_cc (exp
, insn
)
2201 /* If the cc is being set from the fpa and the expression is not an
2202 explicit floating point test instruction (which has code to deal with
2203 this), reinit the CC. */
2204 if (((cc_status
.value1
&& FPA_REG_P (cc_status
.value1
))
2205 || (cc_status
.value2
&& FPA_REG_P (cc_status
.value2
)))
2206 && !(GET_CODE (exp
) == PARALLEL
2207 && GET_CODE (XVECEXP (exp
, 0, 0)) == SET
2208 && XEXP (XVECEXP (exp
, 0, 0), 0) == cc0_rtx
))
2212 else if (GET_CODE (exp
) == SET
)
2214 if (GET_CODE (SET_SRC (exp
)) == CALL
)
2218 else if (ADDRESS_REG_P (SET_DEST (exp
)))
2220 if (cc_status
.value1
&& modified_in_p (cc_status
.value1
, insn
))
2221 cc_status
.value1
= 0;
2222 if (cc_status
.value2
&& modified_in_p (cc_status
.value2
, insn
))
2223 cc_status
.value2
= 0;
2225 else if (!FP_REG_P (SET_DEST (exp
))
2226 && SET_DEST (exp
) != cc0_rtx
2227 && (FP_REG_P (SET_SRC (exp
))
2228 || GET_CODE (SET_SRC (exp
)) == FIX
2229 || GET_CODE (SET_SRC (exp
)) == FLOAT_TRUNCATE
2230 || GET_CODE (SET_SRC (exp
)) == FLOAT_EXTEND
))
2234 /* A pair of move insns doesn't produce a useful overall cc. */
2235 else if (!FP_REG_P (SET_DEST (exp
))
2236 && !FP_REG_P (SET_SRC (exp
))
2237 && GET_MODE_SIZE (GET_MODE (SET_SRC (exp
))) > 4
2238 && (GET_CODE (SET_SRC (exp
)) == REG
2239 || GET_CODE (SET_SRC (exp
)) == MEM
2240 || GET_CODE (SET_SRC (exp
)) == CONST_DOUBLE
))
2244 else if (GET_CODE (SET_SRC (exp
)) == CALL
)
2248 else if (XEXP (exp
, 0) != pc_rtx
)
2250 cc_status
.flags
= 0;
2251 cc_status
.value1
= XEXP (exp
, 0);
2252 cc_status
.value2
= XEXP (exp
, 1);
2255 else if (GET_CODE (exp
) == PARALLEL
2256 && GET_CODE (XVECEXP (exp
, 0, 0)) == SET
)
2258 if (ADDRESS_REG_P (XEXP (XVECEXP (exp
, 0, 0), 0)))
2260 else if (XEXP (XVECEXP (exp
, 0, 0), 0) != pc_rtx
)
2262 cc_status
.flags
= 0;
2263 cc_status
.value1
= XEXP (XVECEXP (exp
, 0, 0), 0);
2264 cc_status
.value2
= XEXP (XVECEXP (exp
, 0, 0), 1);
2269 if (cc_status
.value2
!= 0
2270 && ADDRESS_REG_P (cc_status
.value2
)
2271 && GET_MODE (cc_status
.value2
) == QImode
)
2273 if (cc_status
.value2
!= 0
2274 && !(cc_status
.value1
&& FPA_REG_P (cc_status
.value1
)))
2275 switch (GET_CODE (cc_status
.value2
))
2277 case PLUS
: case MINUS
: case MULT
:
2278 case DIV
: case UDIV
: case MOD
: case UMOD
: case NEG
:
2279 #if 0 /* These instructions always clear the overflow bit */
2280 case ASHIFT
: case ASHIFTRT
: case LSHIFTRT
:
2281 case ROTATE
: case ROTATERT
:
2283 if (GET_MODE (cc_status
.value2
) != VOIDmode
)
2284 cc_status
.flags
|= CC_NO_OVERFLOW
;
2287 /* (SET r1 (ZERO_EXTEND r2)) on this machine
2288 ends with a move insn moving r2 in r2's mode.
2289 Thus, the cc's are set for r2.
2290 This can set N bit spuriously. */
2291 cc_status
.flags
|= CC_NOT_NEGATIVE
;
2296 if (cc_status
.value1
&& GET_CODE (cc_status
.value1
) == REG
2298 && reg_overlap_mentioned_p (cc_status
.value1
, cc_status
.value2
))
2299 cc_status
.value2
= 0;
2300 if (((cc_status
.value1
&& FP_REG_P (cc_status
.value1
))
2301 || (cc_status
.value2
&& FP_REG_P (cc_status
.value2
)))
2302 && !((cc_status
.value1
&& FPA_REG_P (cc_status
.value1
))
2303 || (cc_status
.value2
&& FPA_REG_P (cc_status
.value2
))))
2304 cc_status
.flags
= CC_IN_68881
;
2308 output_move_const_double (operands
)
2311 #ifdef SUPPORT_SUN_FPA
2312 if (TARGET_FPA
&& FPA_REG_P (operands
[0]))
2314 int code
= standard_sun_fpa_constant_p (operands
[1]);
2318 static char buf
[40];
2320 sprintf (buf
, "fpmove%%.d %%%%%d,%%0", code
& 0x1ff);
2323 return "fpmove%.d %1,%0";
2328 int code
= standard_68881_constant_p (operands
[1]);
2332 static char buf
[40];
2334 sprintf (buf
, "fmovecr %%#0x%x,%%0", code
& 0xff);
2337 return "fmove%.d %1,%0";
2342 output_move_const_single (operands
)
2345 #ifdef SUPPORT_SUN_FPA
2348 int code
= standard_sun_fpa_constant_p (operands
[1]);
2352 static char buf
[40];
2354 sprintf (buf
, "fpmove%%.s %%%%%d,%%0", code
& 0x1ff);
2357 return "fpmove%.s %1,%0";
2360 #endif /* defined SUPPORT_SUN_FPA */
2362 int code
= standard_68881_constant_p (operands
[1]);
2366 static char buf
[40];
2368 sprintf (buf
, "fmovecr %%#0x%x,%%0", code
& 0xff);
2371 return "fmove%.s %f1,%0";
2375 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
2376 from the "fmovecr" instruction.
2377 The value, anded with 0xff, gives the code to use in fmovecr
2378 to get the desired constant. */
2380 /* This code has been fixed for cross-compilation. */
2382 static int inited_68881_table
= 0;
2384 char *strings_68881
[7] = {
2394 int codes_68881
[7] = {
2404 REAL_VALUE_TYPE values_68881
[7];
2406 /* Set up values_68881 array by converting the decimal values
2407 strings_68881 to binary. */
2414 enum machine_mode mode
;
2417 for (i
= 0; i
< 7; i
++)
2421 r
= REAL_VALUE_ATOF (strings_68881
[i
], mode
);
2422 values_68881
[i
] = r
;
2424 inited_68881_table
= 1;
2428 standard_68881_constant_p (x
)
2434 #ifdef NO_ASM_FMOVECR
2438 /* fmovecr must be emulated on the 68040 and 68060, so it shouldn't be
2439 used at all on those chips. */
2440 if (TARGET_68040
|| TARGET_68060
)
2443 #ifndef REAL_ARITHMETIC
2444 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
2445 if (! flag_pretend_float
)
2450 if (! inited_68881_table
)
2451 init_68881_table ();
2453 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
2455 /* Use REAL_VALUES_IDENTICAL instead of REAL_VALUES_EQUAL so that -0.0
2457 for (i
= 0; i
< 6; i
++)
2459 if (REAL_VALUES_IDENTICAL (r
, values_68881
[i
]))
2460 return (codes_68881
[i
]);
2463 if (GET_MODE (x
) == SFmode
)
2466 if (REAL_VALUES_EQUAL (r
, values_68881
[6]))
2467 return (codes_68881
[6]);
2469 /* larger powers of ten in the constants ram are not used
2470 because they are not equal to a `double' C constant. */
2474 /* If X is a floating-point constant, return the logarithm of X base 2,
2475 or 0 if X is not a power of 2. */
2478 floating_exact_log2 (x
)
2481 REAL_VALUE_TYPE r
, r1
;
2484 #ifndef REAL_ARITHMETIC
2485 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
2486 if (! flag_pretend_float
)
2491 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
2493 if (REAL_VALUES_LESS (r
, dconst0
))
2498 while (REAL_VALUES_LESS (r1
, r
))
2500 r1
= REAL_VALUE_LDEXP (dconst1
, i
);
2501 if (REAL_VALUES_EQUAL (r1
, r
))
2508 #ifdef SUPPORT_SUN_FPA
2509 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
2510 from the Sun FPA's constant RAM.
2511 The value returned, anded with 0x1ff, gives the code to use in fpmove
2512 to get the desired constant. */
2514 static int inited_FPA_table
= 0;
2516 char *strings_FPA
[38] = {
2517 /* small rationals */
2530 /* Decimal equivalents of double precision values */
2531 "2.718281828459045091", /* D_E */
2532 "6.283185307179586477", /* 2 pi */
2533 "3.141592653589793116", /* D_PI */
2534 "1.570796326794896619", /* pi/2 */
2535 "1.414213562373095145", /* D_SQRT2 */
2536 "0.7071067811865475244", /* 1/sqrt(2) */
2537 "-1.570796326794896619", /* -pi/2 */
2538 "1.442695040888963387", /* D_LOG2ofE */
2539 "3.321928024887362182", /* D_LOG2of10 */
2540 "0.6931471805599452862", /* D_LOGEof2 */
2541 "2.302585092994045901", /* D_LOGEof10 */
2542 "0.3010299956639811980", /* D_LOG10of2 */
2543 "0.4342944819032518167", /* D_LOG10ofE */
2544 /* Decimal equivalents of single precision values */
2545 "2.718281745910644531", /* S_E */
2546 "6.283185307179586477", /* 2 pi */
2547 "3.141592741012573242", /* S_PI */
2548 "1.570796326794896619", /* pi/2 */
2549 "1.414213538169860840", /* S_SQRT2 */
2550 "0.7071067811865475244", /* 1/sqrt(2) */
2551 "-1.570796326794896619", /* -pi/2 */
2552 "1.442695021629333496", /* S_LOG2ofE */
2553 "3.321928024291992188", /* S_LOG2of10 */
2554 "0.6931471824645996094", /* S_LOGEof2 */
2555 "2.302585124969482442", /* S_LOGEof10 */
2556 "0.3010300099849700928", /* S_LOG10of2 */
2557 "0.4342944920063018799", /* S_LOG10ofE */
2561 int codes_FPA
[38] = {
2562 /* small rationals */
2575 /* double precision */
2589 /* single precision */
2605 REAL_VALUE_TYPE values_FPA
[38];
2607 /* This code has been fixed for cross-compilation. */
2612 enum machine_mode mode
;
2617 for (i
= 0; i
< 38; i
++)
2621 r
= REAL_VALUE_ATOF (strings_FPA
[i
], mode
);
2624 inited_FPA_table
= 1;
2629 standard_sun_fpa_constant_p (x
)
2635 #ifndef REAL_ARITHMETIC
2636 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
2637 if (! flag_pretend_float
)
2642 if (! inited_FPA_table
)
2645 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
2647 for (i
=0; i
<12; i
++)
2649 if (REAL_VALUES_EQUAL (r
, values_FPA
[i
]))
2650 return (codes_FPA
[i
]);
2653 if (GET_MODE (x
) == SFmode
)
2655 for (i
=25; i
<38; i
++)
2657 if (REAL_VALUES_EQUAL (r
, values_FPA
[i
]))
2658 return (codes_FPA
[i
]);
2663 for (i
=12; i
<25; i
++)
2665 if (REAL_VALUES_EQUAL (r
, values_FPA
[i
]))
2666 return (codes_FPA
[i
]);
2671 #endif /* define SUPPORT_SUN_FPA */
2673 /* A C compound statement to output to stdio stream STREAM the
2674 assembler syntax for an instruction operand X. X is an RTL
2677 CODE is a value that can be used to specify one of several ways
2678 of printing the operand. It is used when identical operands
2679 must be printed differently depending on the context. CODE
2680 comes from the `%' specification that was used to request
2681 printing of the operand. If the specification was just `%DIGIT'
2682 then CODE is 0; if the specification was `%LTR DIGIT' then CODE
2683 is the ASCII code for LTR.
2685 If X is a register, this macro should print the register's name.
2686 The names can be found in an array `reg_names' whose type is
2687 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
2689 When the machine description has a specification `%PUNCT' (a `%'
2690 followed by a punctuation character), this macro is called with
2691 a null pointer for X and the punctuation character for CODE.
2693 The m68k specific codes are:
2695 '.' for dot needed in Motorola-style opcode names.
2696 '-' for an operand pushing on the stack:
2697 sp@-, -(sp) or -(%sp) depending on the style of syntax.
2698 '+' for an operand pushing on the stack:
2699 sp@+, (sp)+ or (%sp)+ depending on the style of syntax.
2700 '@' for a reference to the top word on the stack:
2701 sp@, (sp) or (%sp) depending on the style of syntax.
2702 '#' for an immediate operand prefix (# in MIT and Motorola syntax
2703 but & in SGS syntax, $ in CRDS/UNOS syntax).
2704 '!' for the cc register (used in an `and to cc' insn).
2705 '$' for the letter `s' in an op code, but only on the 68040.
2706 '&' for the letter `d' in an op code, but only on the 68040.
2707 '/' for register prefix needed by longlong.h.
2709 'b' for byte insn (no effect, on the Sun; this is for the ISI).
2710 'd' to force memory addressing to be absolute, not relative.
2711 'f' for float insn (print a CONST_DOUBLE as a float rather than in hex)
2712 'o' for operands to go directly to output_operand_address (bypassing
2713 print_operand_address--used only for SYMBOL_REFs under TARGET_PCREL)
2714 'w' for FPA insn (print a CONST_DOUBLE as a SunFPA constant rather
2715 than directly). Second part of 'y' below.
2716 'x' for float insn (print a CONST_DOUBLE as a float rather than in hex),
2717 or print pair of registers as rx:ry.
2718 'y' for a FPA insn (print pair of registers as rx:ry). This also outputs
2719 CONST_DOUBLE's as SunFPA constant RAM registers if
2720 possible, so it should not be used except for the SunFPA.
2725 print_operand (file
, op
, letter
)
2726 FILE *file
; /* file to write to */
2727 rtx op
; /* operand to print */
2728 int letter
; /* %<letter> or 0 */
2730 #ifdef SUPPORT_SUN_FPA
2736 #if defined (MOTOROLA) && !defined (CRDS)
2737 asm_fprintf (file
, ".");
2740 else if (letter
== '#')
2742 asm_fprintf (file
, "%0I");
2744 else if (letter
== '-')
2747 asm_fprintf (file
, "-(%Rsp)");
2749 asm_fprintf (file
, "%Rsp@-");
2752 else if (letter
== '+')
2755 asm_fprintf (file
, "(%Rsp)+");
2757 asm_fprintf (file
, "%Rsp@+");
2760 else if (letter
== '@')
2763 asm_fprintf (file
, "(%Rsp)");
2765 asm_fprintf (file
, "%Rsp@");
2768 else if (letter
== '!')
2770 asm_fprintf (file
, "%Rfpcr");
2772 else if (letter
== '$')
2774 if (TARGET_68040_ONLY
)
2776 fprintf (file
, "s");
2779 else if (letter
== '&')
2781 if (TARGET_68040_ONLY
)
2783 fprintf (file
, "d");
2786 else if (letter
== '/')
2788 asm_fprintf (file
, "%R");
2790 else if (letter
== 'o')
2792 /* This is only for direct addresses with TARGET_PCREL */
2793 if (GET_CODE (op
) != MEM
|| GET_CODE (XEXP (op
, 0)) != SYMBOL_REF
2796 output_addr_const (file
, XEXP (op
, 0));
2798 else if (GET_CODE (op
) == REG
)
2800 #ifdef SUPPORT_SUN_FPA
2802 && (letter
== 'y' || letter
== 'x')
2803 && GET_MODE (op
) == DFmode
)
2805 fprintf (file
, "%s:%s", reg_names
[REGNO (op
)],
2806 reg_names
[REGNO (op
)+1]);
2812 /* Print out the second register name of a register pair.
2813 I.e., R (6) => 7. */
2814 fputs (reg_names
[REGNO (op
) + 1], file
);
2816 fputs (reg_names
[REGNO (op
)], file
);
2819 else if (GET_CODE (op
) == MEM
)
2821 output_address (XEXP (op
, 0));
2822 if (letter
== 'd' && ! TARGET_68020
2823 && CONSTANT_ADDRESS_P (XEXP (op
, 0))
2824 && !(GET_CODE (XEXP (op
, 0)) == CONST_INT
2825 && INTVAL (XEXP (op
, 0)) < 0x8000
2826 && INTVAL (XEXP (op
, 0)) >= -0x8000))
2829 fprintf (file
, ".l");
2831 fprintf (file
, ":l");
2835 #ifdef SUPPORT_SUN_FPA
2836 else if ((letter
== 'y' || letter
== 'w')
2837 && GET_CODE (op
) == CONST_DOUBLE
2838 && (i
= standard_sun_fpa_constant_p (op
)))
2840 fprintf (file
, "%%%d", i
& 0x1ff);
2843 else if (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == SFmode
)
2846 REAL_VALUE_FROM_CONST_DOUBLE (r
, op
);
2847 ASM_OUTPUT_FLOAT_OPERAND (letter
, file
, r
);
2849 else if (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == XFmode
)
2852 REAL_VALUE_FROM_CONST_DOUBLE (r
, op
);
2853 ASM_OUTPUT_LONG_DOUBLE_OPERAND (file
, r
);
2855 else if (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == DFmode
)
2858 REAL_VALUE_FROM_CONST_DOUBLE (r
, op
);
2859 ASM_OUTPUT_DOUBLE_OPERAND (file
, r
);
2863 /* Use `print_operand_address' instead of `output_addr_const'
2864 to ensure that we print relevant PIC stuff. */
2865 asm_fprintf (file
, "%0I");
2867 && (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == CONST
))
2868 print_operand_address (file
, op
);
2870 output_addr_const (file
, op
);
2875 /* A C compound statement to output to stdio stream STREAM the
2876 assembler syntax for an instruction operand that is a memory
2877 reference whose address is ADDR. ADDR is an RTL expression.
2879 Note that this contains a kludge that knows that the only reason
2880 we have an address (plus (label_ref...) (reg...)) when not generating
2881 PIC code is in the insn before a tablejump, and we know that m68k.md
2882 generates a label LInnn: on such an insn.
2884 It is possible for PIC to generate a (plus (label_ref...) (reg...))
2885 and we handle that just like we would a (plus (symbol_ref...) (reg...)).
2887 Some SGS assemblers have a bug such that "Lnnn-LInnn-2.b(pc,d0.l*2)"
2888 fails to assemble. Luckily "Lnnn(pc,d0.l*2)" produces the results
2889 we want. This difference can be accommodated by using an assembler
2890 define such "LDnnn" to be either "Lnnn-LInnn-2.b", "Lnnn", or any other
2891 string, as necessary. This is accomplished via the ASM_OUTPUT_CASE_END
2892 macro. See m68k/sgs.h for an example; for versions without the bug.
2893 Some assemblers refuse all the above solutions. The workaround is to
2894 emit "K(pc,d0.l*2)" with K being a small constant known to give the
2897 They also do not like things like "pea 1.w", so we simple leave off
2898 the .w on small constants.
2900 This routine is responsible for distinguishing between -fpic and -fPIC
2901 style relocations in an address. When generating -fpic code the
2902 offset is output in word mode (eg movel a5@(_foo:w), a0). When generating
2903 -fPIC code the offset is output in long mode (eg movel a5@(_foo:l), a0) */
2905 #ifndef ASM_OUTPUT_CASE_FETCH
2908 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2909 asm_fprintf (file, "%LLD%d(%Rpc,%s.", labelno, regname)
2911 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2912 asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.", labelno, labelno, regname)
2915 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2916 asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:", labelno, labelno, regname)
2918 #endif /* ASM_OUTPUT_CASE_FETCH */
2921 print_operand_address (file
, addr
)
2925 register rtx reg1
, reg2
, breg
, ireg
;
2928 switch (GET_CODE (addr
))
2932 fprintf (file
, "(%s)", reg_names
[REGNO (addr
)]);
2934 fprintf (file
, "%s@", reg_names
[REGNO (addr
)]);
2939 fprintf (file
, "-(%s)", reg_names
[REGNO (XEXP (addr
, 0))]);
2941 fprintf (file
, "%s@-", reg_names
[REGNO (XEXP (addr
, 0))]);
2946 fprintf (file
, "(%s)+", reg_names
[REGNO (XEXP (addr
, 0))]);
2948 fprintf (file
, "%s@+", reg_names
[REGNO (XEXP (addr
, 0))]);
2952 reg1
= reg2
= ireg
= breg
= offset
= 0;
2953 if (CONSTANT_ADDRESS_P (XEXP (addr
, 0)))
2955 offset
= XEXP (addr
, 0);
2956 addr
= XEXP (addr
, 1);
2958 else if (CONSTANT_ADDRESS_P (XEXP (addr
, 1)))
2960 offset
= XEXP (addr
, 1);
2961 addr
= XEXP (addr
, 0);
2963 if (GET_CODE (addr
) != PLUS
)
2967 else if (GET_CODE (XEXP (addr
, 0)) == SIGN_EXTEND
)
2969 reg1
= XEXP (addr
, 0);
2970 addr
= XEXP (addr
, 1);
2972 else if (GET_CODE (XEXP (addr
, 1)) == SIGN_EXTEND
)
2974 reg1
= XEXP (addr
, 1);
2975 addr
= XEXP (addr
, 0);
2977 else if (GET_CODE (XEXP (addr
, 0)) == MULT
)
2979 reg1
= XEXP (addr
, 0);
2980 addr
= XEXP (addr
, 1);
2982 else if (GET_CODE (XEXP (addr
, 1)) == MULT
)
2984 reg1
= XEXP (addr
, 1);
2985 addr
= XEXP (addr
, 0);
2987 else if (GET_CODE (XEXP (addr
, 0)) == REG
)
2989 reg1
= XEXP (addr
, 0);
2990 addr
= XEXP (addr
, 1);
2992 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
2994 reg1
= XEXP (addr
, 1);
2995 addr
= XEXP (addr
, 0);
2997 if (GET_CODE (addr
) == REG
|| GET_CODE (addr
) == MULT
2998 || GET_CODE (addr
) == SIGN_EXTEND
)
3010 #if 0 /* for OLD_INDEXING */
3011 else if (GET_CODE (addr
) == PLUS
)
3013 if (GET_CODE (XEXP (addr
, 0)) == REG
)
3015 reg2
= XEXP (addr
, 0);
3016 addr
= XEXP (addr
, 1);
3018 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
3020 reg2
= XEXP (addr
, 1);
3021 addr
= XEXP (addr
, 0);
3033 if ((reg1
&& (GET_CODE (reg1
) == SIGN_EXTEND
3034 || GET_CODE (reg1
) == MULT
))
3035 || (reg2
!= 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2
))))
3040 else if (reg1
!= 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1
)))
3045 if (ireg
!= 0 && breg
== 0 && GET_CODE (addr
) == LABEL_REF
3046 && ! (flag_pic
&& ireg
== pic_offset_table_rtx
))
3049 if (GET_CODE (ireg
) == MULT
)
3051 scale
= INTVAL (XEXP (ireg
, 1));
3052 ireg
= XEXP (ireg
, 0);
3054 if (GET_CODE (ireg
) == SIGN_EXTEND
)
3056 ASM_OUTPUT_CASE_FETCH (file
,
3057 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
3058 reg_names
[REGNO (XEXP (ireg
, 0))]);
3059 fprintf (file
, "w");
3063 ASM_OUTPUT_CASE_FETCH (file
,
3064 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
3065 reg_names
[REGNO (ireg
)]);
3066 fprintf (file
, "l");
3071 fprintf (file
, "*%d", scale
);
3073 fprintf (file
, ":%d", scale
);
3079 if (breg
!= 0 && ireg
== 0 && GET_CODE (addr
) == LABEL_REF
3080 && ! (flag_pic
&& breg
== pic_offset_table_rtx
))
3082 ASM_OUTPUT_CASE_FETCH (file
,
3083 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
3084 reg_names
[REGNO (breg
)]);
3085 fprintf (file
, "l)");
3088 if (ireg
!= 0 || breg
!= 0)
3095 if (! flag_pic
&& addr
&& GET_CODE (addr
) == LABEL_REF
)
3102 output_addr_const (file
, addr
);
3103 if (flag_pic
&& (breg
== pic_offset_table_rtx
))
3105 fprintf (file
, "@GOT");
3107 fprintf (file
, ".w");
3110 fprintf (file
, "(%s", reg_names
[REGNO (breg
)]);
3116 fprintf (file
, "%s@(", reg_names
[REGNO (breg
)]);
3119 output_addr_const (file
, addr
);
3120 if ((flag_pic
== 1) && (breg
== pic_offset_table_rtx
))
3121 fprintf (file
, ":w");
3122 if ((flag_pic
== 2) && (breg
== pic_offset_table_rtx
))
3123 fprintf (file
, ":l");
3125 if (addr
!= 0 && ireg
!= 0)
3130 if (ireg
!= 0 && GET_CODE (ireg
) == MULT
)
3132 scale
= INTVAL (XEXP (ireg
, 1));
3133 ireg
= XEXP (ireg
, 0);
3135 if (ireg
!= 0 && GET_CODE (ireg
) == SIGN_EXTEND
)
3138 fprintf (file
, "%s.w", reg_names
[REGNO (XEXP (ireg
, 0))]);
3140 fprintf (file
, "%s:w", reg_names
[REGNO (XEXP (ireg
, 0))]);
3146 fprintf (file
, "%s.l", reg_names
[REGNO (ireg
)]);
3148 fprintf (file
, "%s:l", reg_names
[REGNO (ireg
)]);
3154 fprintf (file
, "*%d", scale
);
3156 fprintf (file
, ":%d", scale
);
3162 else if (reg1
!= 0 && GET_CODE (addr
) == LABEL_REF
3163 && ! (flag_pic
&& reg1
== pic_offset_table_rtx
))
3165 ASM_OUTPUT_CASE_FETCH (file
,
3166 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
3167 reg_names
[REGNO (reg1
)]);
3168 fprintf (file
, "l)");
3171 /* FALL-THROUGH (is this really what we want?) */
3173 if (GET_CODE (addr
) == CONST_INT
3174 && INTVAL (addr
) < 0x8000
3175 && INTVAL (addr
) >= -0x8000)
3179 /* Many SGS assemblers croak on size specifiers for constants. */
3180 fprintf (file
, "%d", INTVAL (addr
));
3182 fprintf (file
, "%d.w", INTVAL (addr
));
3185 fprintf (file
, "%d:w", INTVAL (addr
));
3188 else if (GET_CODE (addr
) == CONST_INT
)
3191 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
3198 else if (TARGET_PCREL
)
3201 output_addr_const (file
, addr
);
3203 asm_fprintf (file
, ":w,%Rpc)");
3205 asm_fprintf (file
, ":l,%Rpc)");
3209 /* Special case for SYMBOL_REF if the symbol name ends in
3210 `.<letter>', this can be mistaken as a size suffix. Put
3211 the name in parentheses. */
3212 if (GET_CODE (addr
) == SYMBOL_REF
3213 && strlen (XSTR (addr
, 0)) > 2
3214 && XSTR (addr
, 0)[strlen (XSTR (addr
, 0)) - 2] == '.')
3217 output_addr_const (file
, addr
);
3221 output_addr_const (file
, addr
);
3227 /* Check for cases where a clr insns can be omitted from code using
3228 strict_low_part sets. For example, the second clrl here is not needed:
3229 clrl d0; movw a0@+,d0; use d0; clrl d0; movw a0@+; use d0; ...
3231 MODE is the mode of this STRICT_LOW_PART set. FIRST_INSN is the clear
3232 insn we are checking for redundancy. TARGET is the register set by the
3236 strict_low_part_peephole_ok (mode
, first_insn
, target
)
3237 enum machine_mode mode
;
3243 p
= prev_nonnote_insn (first_insn
);
3247 /* If it isn't an insn, then give up. */
3248 if (GET_CODE (p
) != INSN
)
3251 if (reg_set_p (target
, p
))
3253 rtx set
= single_set (p
);
3256 /* If it isn't an easy to recognize insn, then give up. */
3260 dest
= SET_DEST (set
);
3262 /* If this sets the entire target register to zero, then our
3263 first_insn is redundant. */
3264 if (rtx_equal_p (dest
, target
)
3265 && SET_SRC (set
) == const0_rtx
)
3267 else if (GET_CODE (dest
) == STRICT_LOW_PART
3268 && GET_CODE (XEXP (dest
, 0)) == REG
3269 && REGNO (XEXP (dest
, 0)) == REGNO (target
)
3270 && (GET_MODE_SIZE (GET_MODE (XEXP (dest
, 0)))
3271 <= GET_MODE_SIZE (mode
)))
3272 /* This is a strict low part set which modifies less than
3273 we are using, so it is safe. */
3279 p
= prev_nonnote_insn (p
);
3286 /* Accept integer operands in the range 0..0xffffffff. We have to check the
3287 range carefully since this predicate is used in DImode contexts. Also, we
3288 need some extra crud to make it work when hosted on 64-bit machines. */
3291 const_uint32_operand (op
, mode
)
3293 enum machine_mode mode ATTRIBUTE_UNUSED
;
3295 #if HOST_BITS_PER_WIDE_INT > 32
3296 /* All allowed constants will fit a CONST_INT. */
3297 return (GET_CODE (op
) == CONST_INT
3298 && (INTVAL (op
) >= 0 && INTVAL (op
) <= 0xffffffffL
));
3300 return ((GET_CODE (op
) == CONST_INT
&& INTVAL (op
) >= 0)
3301 || (GET_CODE (op
) == CONST_DOUBLE
&& CONST_DOUBLE_HIGH (op
) == 0));
3305 /* Accept integer operands in the range -0x80000000..0x7fffffff. We have
3306 to check the range carefully since this predicate is used in DImode
3310 const_sint32_operand (op
, mode
)
3312 enum machine_mode mode ATTRIBUTE_UNUSED
;
3314 /* All allowed constants will fit a CONST_INT. */
3315 return (GET_CODE (op
) == CONST_INT
3316 && (INTVAL (op
) >= (-0x7fffffff - 1) && INTVAL (op
) <= 0x7fffffff));
3319 /* Operand predicates for implementing asymmetric pc-relative addressing
3320 on m68k. The m68k supports pc-relative addressing (mode 7, register 2)
3321 when used as a source operand, but not as a destintation operand.
3323 We model this by restricting the meaning of the basic predicates
3324 (general_operand, memory_operand, etc) to forbid the use of this
3325 addressing mode, and then define the following predicates that permit
3326 this addressing mode. These predicates can then be used for the
3327 source operands of the appropriate instructions.
3329 n.b. While it is theoretically possible to change all machine patterns
3330 to use this addressing more where permitted by the architecture,
3331 it has only been implemented for "common" cases: SImode, HImode, and
3332 QImode operands, and only for the principle operations that would
3333 require this addressing mode: data movement and simple integer operations.
3335 In parallel with these new predicates, two new constraint letters
3336 were defined: 'S' and 'T'. 'S' is the -mpcrel analog of 'm'.
3337 'T' replaces 's' in the non-pcrel case. It is a no-op in the pcrel case.
3338 In the pcrel case 's' is only valid in combination with 'a' registers.
3339 See addsi3, subsi3, cmpsi, and movsi patterns for a better understanding
3340 of how these constraints are used.
3342 The use of these predicates is strictly optional, though patterns that
3343 don't will cause an extra reload register to be allocated where one
3346 lea (abc:w,%pc),%a0 ; need to reload address
3347 moveq &1,%d1 ; since write to pc-relative space
3348 movel %d1,%a0@ ; is not allowed
3350 lea (abc:w,%pc),%a1 ; no need to reload address here
3351 movel %a1@,%d0 ; since "movel (abc:w,%pc),%d0" is ok
3353 For more info, consult tiemann@cygnus.com.
3356 All of the ugliness with predicates and constraints is due to the
3357 simple fact that the m68k does not allow a pc-relative addressing
3358 mode as a destination. gcc does not distinguish between source and
3359 destination addresses. Hence, if we claim that pc-relative address
3360 modes are valid, e.g. GO_IF_LEGITIMATE_ADDRESS accepts them, then we
3361 end up with invalid code. To get around this problem, we left
3362 pc-relative modes as invalid addresses, and then added special
3363 predicates and constraints to accept them.
3365 A cleaner way to handle this is to modify gcc to distinguish
3366 between source and destination addresses. We can then say that
3367 pc-relative is a valid source address but not a valid destination
3368 address, and hopefully avoid a lot of the predicate and constraint
3369 hackery. Unfortunately, this would be a pretty big change. It would
3370 be a useful change for a number of ports, but there aren't any current
3371 plans to undertake this.
3373 ***************************************************************************/
3376 /* Special case of a general operand that's used as a source operand.
3377 Use this to permit reads from PC-relative memory when -mpcrel
3381 general_src_operand (op
, mode
)
3383 enum machine_mode mode
;
3386 && GET_CODE (op
) == MEM
3387 && (GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
3388 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
3389 || GET_CODE (XEXP (op
, 0)) == CONST
))
3391 return general_operand (op
, mode
);
3394 /* Special case of a nonimmediate operand that's used as a source.
3395 Use this to permit reads from PC-relative memory when -mpcrel
3399 nonimmediate_src_operand (op
, mode
)
3401 enum machine_mode mode
;
3403 if (TARGET_PCREL
&& GET_CODE (op
) == MEM
3404 && (GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
3405 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
3406 || GET_CODE (XEXP (op
, 0)) == CONST
))
3408 return nonimmediate_operand (op
, mode
);
3411 /* Special case of a memory operand that's used as a source.
3412 Use this to permit reads from PC-relative memory when -mpcrel
3416 memory_src_operand (op
, mode
)
3418 enum machine_mode mode
;
3420 if (TARGET_PCREL
&& GET_CODE (op
) == MEM
3421 && (GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
3422 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
3423 || GET_CODE (XEXP (op
, 0)) == CONST
))
3425 return memory_operand (op
, mode
);
3428 /* Predicate that accepts only a pc-relative address. This is needed
3429 because pc-relative addresses don't satisfy the predicate
3430 "general_src_operand". */
3433 pcrel_address (op
, mode
)
3435 enum machine_mode mode
;
3437 return (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
3438 || GET_CODE (op
) == CONST
);
3442 output_andsi3 (operands
)
3446 if (GET_CODE (operands
[2]) == CONST_INT
3447 && (INTVAL (operands
[2]) | 0xffff) == 0xffffffff
3448 && (DATA_REG_P (operands
[0])
3449 || offsettable_memref_p (operands
[0]))
3452 if (GET_CODE (operands
[0]) != REG
)
3453 operands
[0] = adj_offsettable_operand (operands
[0], 2);
3454 operands
[2] = GEN_INT (INTVAL (operands
[2]) & 0xffff);
3455 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3457 if (operands
[2] == const0_rtx
)
3459 return "and%.w %2,%0";
3461 if (GET_CODE (operands
[2]) == CONST_INT
3462 && (logval
= exact_log2 (~ INTVAL (operands
[2]))) >= 0
3463 && (DATA_REG_P (operands
[0])
3464 || offsettable_memref_p (operands
[0])))
3466 if (DATA_REG_P (operands
[0]))
3468 operands
[1] = GEN_INT (logval
);
3472 operands
[0] = adj_offsettable_operand (operands
[0], 3 - (logval
/ 8));
3473 operands
[1] = GEN_INT (logval
% 8);
3475 /* This does not set condition codes in a standard way. */
3477 return "bclr %1,%0";
3479 return "and%.l %2,%0";
3483 output_iorsi3 (operands
)
3486 register int logval
;
3487 if (GET_CODE (operands
[2]) == CONST_INT
3488 && INTVAL (operands
[2]) >> 16 == 0
3489 && (DATA_REG_P (operands
[0])
3490 || offsettable_memref_p (operands
[0]))
3493 if (GET_CODE (operands
[0]) != REG
)
3494 operands
[0] = adj_offsettable_operand (operands
[0], 2);
3495 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3497 if (INTVAL (operands
[2]) == 0xffff)
3498 return "mov%.w %2,%0";
3499 return "or%.w %2,%0";
3501 if (GET_CODE (operands
[2]) == CONST_INT
3502 && (logval
= exact_log2 (INTVAL (operands
[2]))) >= 0
3503 && (DATA_REG_P (operands
[0])
3504 || offsettable_memref_p (operands
[0])))
3506 if (DATA_REG_P (operands
[0]))
3508 operands
[1] = GEN_INT (logval
);
3512 operands
[0] = adj_offsettable_operand (operands
[0], 3 - (logval
/ 8));
3513 operands
[1] = GEN_INT (logval
% 8);
3516 return "bset %1,%0";
3518 return "or%.l %2,%0";
3522 output_xorsi3 (operands
)
3525 register int logval
;
3526 if (GET_CODE (operands
[2]) == CONST_INT
3527 && INTVAL (operands
[2]) >> 16 == 0
3528 && (offsettable_memref_p (operands
[0]) || DATA_REG_P (operands
[0]))
3531 if (! DATA_REG_P (operands
[0]))
3532 operands
[0] = adj_offsettable_operand (operands
[0], 2);
3533 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3535 if (INTVAL (operands
[2]) == 0xffff)
3537 return "eor%.w %2,%0";
3539 if (GET_CODE (operands
[2]) == CONST_INT
3540 && (logval
= exact_log2 (INTVAL (operands
[2]))) >= 0
3541 && (DATA_REG_P (operands
[0])
3542 || offsettable_memref_p (operands
[0])))
3544 if (DATA_REG_P (operands
[0]))
3546 operands
[1] = GEN_INT (logval
);
3550 operands
[0] = adj_offsettable_operand (operands
[0], 3 - (logval
/ 8));
3551 operands
[1] = GEN_INT (logval
% 8);
3554 return "bchg %1,%0";
3556 return "eor%.l %2,%0";