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"
32 #include "insn-flags.h"
34 #include "insn-attr.h"
39 /* Needed for use_return_insn. */
42 #ifdef SUPPORT_SUN_FPA
44 /* Index into this array by (register number >> 3) to find the
45 smallest class which contains that register. */
46 enum reg_class regno_reg_class[]
47 = { DATA_REGS, ADDR_REGS, FP_REGS,
48 LO_FPA_REGS, LO_FPA_REGS, FPA_REGS, FPA_REGS };
50 #endif /* defined SUPPORT_SUN_FPA */
52 /* This flag is used to communicate between movhi and ASM_OUTPUT_CASE_END,
53 if SGS_SWITCH_TABLE. */
54 int switch_table_difference_label_flag;
56 static rtx find_addr_reg PARAMS ((rtx));
57 static const char *singlemove_string PARAMS ((rtx *));
60 /* Alignment to use for loops and jumps */
61 /* Specify power of two alignment used for loops. */
62 const char *m68k_align_loops_string;
63 /* Specify power of two alignment used for non-loop jumps. */
64 const char *m68k_align_jumps_string;
65 /* Specify power of two alignment used for functions. */
66 const char *m68k_align_funcs_string;
68 /* Specify power of two alignment used for loops. */
70 /* Specify power of two alignment used for non-loop jumps. */
72 /* Specify power of two alignment used for functions. */
75 /* Nonzero if the last compare/test insn had FP operands. The
76 sCC expanders peek at this to determine what to do for the
77 68060, which has no fsCC instructions. */
78 int m68k_last_compare_had_fp_operands;
80 /* Sometimes certain combinations of command options do not make
81 sense on a particular target machine. You can define a macro
82 `OVERRIDE_OPTIONS' to take account of this. This macro, if
83 defined, is executed once just after all the command options have
86 Don't use this macro to turn on various extra optimizations for
87 `-O'. That is what `OPTIMIZATION_OPTIONS' is for. */
97 /* Validate -malign-loops= value, or provide default */
98 m68k_align_loops = def_align;
99 if (m68k_align_loops_string)
101 i = atoi (m68k_align_loops_string);
102 if (i < 1 || i > MAX_CODE_ALIGN)
103 error ("-malign-loops=%d is not between 1 and %d", i, MAX_CODE_ALIGN);
105 m68k_align_loops = i;
108 /* Validate -malign-jumps= value, or provide default */
109 m68k_align_jumps = def_align;
110 if (m68k_align_jumps_string)
112 i = atoi (m68k_align_jumps_string);
113 if (i < 1 || i > MAX_CODE_ALIGN)
114 error ("-malign-jumps=%d is not between 1 and %d", i, MAX_CODE_ALIGN);
116 m68k_align_jumps = i;
119 /* Validate -malign-functions= value, or provide default */
120 m68k_align_funcs = def_align;
121 if (m68k_align_funcs_string)
123 i = atoi (m68k_align_funcs_string);
124 if (i < 1 || i > MAX_CODE_ALIGN)
125 error ("-malign-functions=%d is not between 1 and %d",
128 m68k_align_funcs = i;
132 /* This function generates the assembly code for function entry.
133 STREAM is a stdio stream to output the code to.
134 SIZE is an int: how many units of temporary storage to allocate.
135 Refer to the array `regs_ever_live' to determine which registers
136 to save; `regs_ever_live[I]' is nonzero if register number I
137 is ever used in the function. This function is responsible for
138 knowing which registers should not be saved even if used. */
141 /* Note that the order of the bit mask for fmovem is the opposite
142 of the order for movem! */
146 output_function_prologue (stream, size)
151 register int mask = 0;
152 int num_saved_regs = 0;
153 extern char call_used_regs[];
154 int fsize = (size + 3) & -4;
155 int cfa_offset = INCOMING_FRAME_SP_OFFSET, cfa_store_offset = cfa_offset;
157 /* If the stack limit is a symbol, we can check it here,
158 before actually allocating the space. */
159 if (current_function_limit_stack
160 && GET_CODE (stack_limit_rtx) == SYMBOL_REF)
162 #if defined (MOTOROLA)
163 asm_fprintf (stream, "\tcmp.l %0I%s+%d,%Rsp\n\ttrapcs\n",
164 XSTR (stack_limit_rtx, 0), fsize + 4);
166 asm_fprintf (stream, "\tcmpl %0I%s+%d,%Rsp\n\ttrapcs\n",
167 XSTR (stack_limit_rtx, 0), fsize + 4);
171 if (frame_pointer_needed)
173 if (fsize == 0 && TARGET_68040)
175 /* on the 68040, pea + move is faster than link.w 0 */
177 asm_fprintf (stream, "\tpea (%s)\n\tmove.l %s,%s\n",
178 reg_names[FRAME_POINTER_REGNUM], reg_names[STACK_POINTER_REGNUM],
179 reg_names[FRAME_POINTER_REGNUM]);
181 asm_fprintf (stream, "\tpea %s@\n\tmovel %s,%s\n",
182 reg_names[FRAME_POINTER_REGNUM], reg_names[STACK_POINTER_REGNUM],
183 reg_names[FRAME_POINTER_REGNUM]);
186 else if (fsize < 0x8000)
189 asm_fprintf (stream, "\tlink.w %s,%0I%d\n",
190 reg_names[FRAME_POINTER_REGNUM], -fsize);
192 asm_fprintf (stream, "\tlink %s,%0I%d\n",
193 reg_names[FRAME_POINTER_REGNUM], -fsize);
196 else if (TARGET_68020)
199 asm_fprintf (stream, "\tlink.l %s,%0I%d\n",
200 reg_names[FRAME_POINTER_REGNUM], -fsize);
202 asm_fprintf (stream, "\tlink %s,%0I%d\n",
203 reg_names[FRAME_POINTER_REGNUM], -fsize);
208 /* Adding negative number is faster on the 68040. */
210 asm_fprintf (stream, "\tlink.w %s,%0I0\n\tadd.l %0I%d,%Rsp\n",
211 reg_names[FRAME_POINTER_REGNUM], -fsize);
213 asm_fprintf (stream, "\tlink %s,%0I0\n\taddl %0I%d,%Rsp\n",
214 reg_names[FRAME_POINTER_REGNUM], -fsize);
217 if (dwarf2out_do_frame ())
220 l = (char *) dwarf2out_cfi_label ();
221 cfa_store_offset += 4;
222 cfa_offset = cfa_store_offset;
223 dwarf2out_reg_save (l, FRAME_POINTER_REGNUM, -cfa_store_offset);
224 dwarf2out_def_cfa (l, FRAME_POINTER_REGNUM, cfa_offset);
225 cfa_store_offset += fsize;
230 if (fsize + 4 < 0x8000)
237 /* asm_fprintf() cannot handle %. */
239 asm_fprintf (stream, "\tsubq.w %0I%d,%Rsp\n", fsize + 4);
241 asm_fprintf (stream, "\tsubqw %0I%d,%Rsp\n", fsize + 4);
246 /* asm_fprintf() cannot handle %. */
248 asm_fprintf (stream, "\tsubq.l %0I%d,%Rsp\n", fsize + 4);
250 asm_fprintf (stream, "\tsubql %0I%d,%Rsp\n", fsize + 4);
254 else if (fsize + 4 <= 16 && TARGET_CPU32)
256 /* On the CPU32 it is faster to use two subqw instructions to
257 subtract a small integer (8 < N <= 16) to a register. */
258 /* asm_fprintf() cannot handle %. */
260 asm_fprintf (stream, "\tsubq.w %0I8,%Rsp\n\tsubq.w %0I%d,%Rsp\n",
263 asm_fprintf (stream, "\tsubqw %0I8,%Rsp\n\tsubqw %0I%d,%Rsp\n",
268 #endif /* not NO_ADDSUB_Q */
271 /* Adding negative number is faster on the 68040. */
272 /* asm_fprintf() cannot handle %. */
274 asm_fprintf (stream, "\tadd.w %0I%d,%Rsp\n", - (fsize + 4));
276 asm_fprintf (stream, "\taddw %0I%d,%Rsp\n", - (fsize + 4));
282 asm_fprintf (stream, "\tlea (%d,%Rsp),%Rsp\n", - (fsize + 4));
284 asm_fprintf (stream, "\tlea %Rsp@(%d),%Rsp\n", - (fsize + 4));
290 /* asm_fprintf() cannot handle %. */
292 asm_fprintf (stream, "\tadd.l %0I%d,%Rsp\n", - (fsize + 4));
294 asm_fprintf (stream, "\taddl %0I%d,%Rsp\n", - (fsize + 4));
297 if (dwarf2out_do_frame ())
299 cfa_store_offset += fsize;
300 cfa_offset = cfa_store_offset;
301 dwarf2out_def_cfa ("", STACK_POINTER_REGNUM, cfa_offset);
304 #ifdef SUPPORT_SUN_FPA
305 for (regno = 24; regno < 56; regno++)
306 if (regs_ever_live[regno] && ! call_used_regs[regno])
309 asm_fprintf (stream, "\tfpmovd %s,-(%Rsp)\n",
312 asm_fprintf (stream, "\tfpmoved %s,%Rsp@-\n",
315 if (dwarf2out_do_frame ())
317 char *l = dwarf2out_cfi_label ();
319 cfa_store_offset += 8;
320 if (! frame_pointer_needed)
322 cfa_offset = cfa_store_offset;
323 dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, cfa_offset);
325 dwarf2out_reg_save (l, regno, -cfa_store_offset);
331 for (regno = 16; regno < 24; regno++)
332 if (regs_ever_live[regno] && ! call_used_regs[regno])
334 mask |= 1 << (regno - 16);
337 if ((mask & 0xff) != 0)
340 asm_fprintf (stream, "\tfmovm %0I0x%x,-(%Rsp)\n", mask & 0xff);
342 asm_fprintf (stream, "\tfmovem %0I0x%x,%Rsp@-\n", mask & 0xff);
344 if (dwarf2out_do_frame ())
346 char *l = (char *) dwarf2out_cfi_label ();
349 cfa_store_offset += num_saved_regs * 12;
350 if (! frame_pointer_needed)
352 cfa_offset = cfa_store_offset;
353 dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, cfa_offset);
355 for (regno = 16, n_regs = 0; regno < 24; regno++)
356 if (mask & (1 << (regno - 16)))
357 dwarf2out_reg_save (l, regno,
358 -cfa_store_offset + n_regs++ * 12);
364 for (regno = 0; regno < 16; regno++)
365 if (regs_ever_live[regno] && ! call_used_regs[regno])
367 mask |= 1 << (15 - regno);
370 if (frame_pointer_needed)
372 mask &= ~ (1 << (15 - FRAME_POINTER_REGNUM));
375 if (flag_pic && current_function_uses_pic_offset_table)
377 mask |= 1 << (15 - PIC_OFFSET_TABLE_REGNUM);
384 asm_fprintf (stream, "\ttstl %d(%Rsp)\n", NEED_PROBE - num_saved_regs * 4);
386 asm_fprintf (stream, "\ttst.l %d(%Rsp)\n", NEED_PROBE - num_saved_regs * 4);
389 asm_fprintf (stream, "\ttstl %Rsp@(%d)\n", NEED_PROBE - num_saved_regs * 4);
393 /* If the stack limit is not a symbol, check it here.
394 This has the disadvantage that it may be too late... */
395 if (current_function_limit_stack)
397 if (REG_P (stack_limit_rtx))
399 #if defined (MOTOROLA)
400 asm_fprintf (stream, "\tcmp.l %s,%Rsp\n\ttrapcs\n",
401 reg_names[REGNO (stack_limit_rtx)]);
403 asm_fprintf (stream, "\tcmpl %s,%Rsp\n\ttrapcs\n",
404 reg_names[REGNO (stack_limit_rtx)]);
407 else if (GET_CODE (stack_limit_rtx) != SYMBOL_REF)
408 warning ("stack limit expression is not supported");
411 if (num_saved_regs <= 2)
413 /* Store each separately in the same order moveml uses.
414 Using two movel instructions instead of a single moveml
415 is about 15% faster for the 68020 and 68030 at no expense
420 /* Undo the work from above. */
421 for (i = 0; i< 16; i++)
426 "\t%Omove.l %s,-(%Rsp)\n",
428 "\tmovel %s,%Rsp@-\n",
431 if (dwarf2out_do_frame ())
433 char *l = (char *) dwarf2out_cfi_label ();
435 cfa_store_offset += 4;
436 if (! frame_pointer_needed)
438 cfa_offset = cfa_store_offset;
439 dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, cfa_offset);
441 dwarf2out_reg_save (l, 15 - i, -cfa_store_offset);
449 /* The coldfire does not support the predecrement form of the
450 movml instruction, so we must adjust the stack pointer and
451 then use the plain address register indirect mode. We also
452 have to invert the register save mask to use the new mode.
454 FIXME: if num_saved_regs was calculated earlier, we could
455 combine the stack pointer adjustment with any adjustment
456 done when the initial stack frame is created. This would
457 save an instruction */
462 for (i = 0; i < 16; i++)
464 newmask |= (1 << (15-i));
467 asm_fprintf (stream, "\tlea (%d,%Rsp),%Rsp\n", -num_saved_regs*4);
468 asm_fprintf (stream, "\tmovm.l %0I0x%x,(%Rsp)\n", newmask);
470 asm_fprintf (stream, "\tlea %Rsp@(%d),%Rsp\n", -num_saved_regs*4);
471 asm_fprintf (stream, "\tmoveml %0I0x%x,%Rsp@\n", newmask);
477 asm_fprintf (stream, "\tmovm.l %0I0x%x,-(%Rsp)\n", mask);
479 asm_fprintf (stream, "\tmoveml %0I0x%x,%Rsp@-\n", mask);
482 if (dwarf2out_do_frame ())
484 char *l = (char *) dwarf2out_cfi_label ();
487 cfa_store_offset += num_saved_regs * 4;
488 if (! frame_pointer_needed)
490 cfa_offset = cfa_store_offset;
491 dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, cfa_offset);
493 for (regno = 0, n_regs = 0; regno < 16; regno++)
494 if (mask & (1 << (15 - regno)))
495 dwarf2out_reg_save (l, regno,
496 -cfa_store_offset + n_regs++ * 4);
499 if (flag_pic && current_function_uses_pic_offset_table)
502 asm_fprintf (stream, "\t%Olea (%Rpc, %U_GLOBAL_OFFSET_TABLE_@GOTPC), %s\n",
503 reg_names[PIC_OFFSET_TABLE_REGNUM]);
505 asm_fprintf (stream, "\tmovel %0I__GLOBAL_OFFSET_TABLE_, %s\n",
506 reg_names[PIC_OFFSET_TABLE_REGNUM]);
507 asm_fprintf (stream, "\tlea %Rpc@(0,%s:l),%s\n",
508 reg_names[PIC_OFFSET_TABLE_REGNUM],
509 reg_names[PIC_OFFSET_TABLE_REGNUM]);
514 /* Return true if this function's epilogue can be output as RTL. */
521 if (!reload_completed || frame_pointer_needed || get_frame_size () != 0)
524 /* Copied from output_function_epilogue (). We should probably create a
525 separate layout routine to perform the common work. */
527 for (regno = 0 ; regno < FIRST_PSEUDO_REGISTER ; regno++)
528 if (regs_ever_live[regno] && ! call_used_regs[regno])
531 if (flag_pic && current_function_uses_pic_offset_table)
537 /* This function generates the assembly code for function exit,
538 on machines that need it. Args are same as for FUNCTION_PROLOGUE.
540 The function epilogue should not depend on the current stack pointer!
541 It should use the frame pointer only, if there is a frame pointer.
542 This is mandatory because of alloca; we also take advantage of it to
543 omit stack adjustments before returning. */
546 output_function_epilogue (stream, size)
551 register int mask, fmask;
553 int offset, foffset, fpoffset;
554 extern char call_used_regs[];
555 int fsize = (size + 3) & -4;
557 rtx insn = get_last_insn ();
558 int restore_from_sp = 0;
560 /* If the last insn was a BARRIER, we don't have to write any code. */
561 if (GET_CODE (insn) == NOTE)
562 insn = prev_nonnote_insn (insn);
563 if (insn && GET_CODE (insn) == BARRIER)
565 /* Output just a no-op so that debuggers don't get confused
566 about which function the pc is in at this address. */
567 asm_fprintf (stream, "\tnop\n");
571 #ifdef FUNCTION_BLOCK_PROFILER_EXIT
572 if (profile_block_flag == 2)
574 FUNCTION_BLOCK_PROFILER_EXIT (stream);
578 #ifdef FUNCTION_EXTRA_EPILOGUE
579 FUNCTION_EXTRA_EPILOGUE (stream, size);
581 nregs = 0; fmask = 0; fpoffset = 0;
582 #ifdef SUPPORT_SUN_FPA
583 for (regno = 24 ; regno < 56 ; regno++)
584 if (regs_ever_live[regno] && ! call_used_regs[regno])
586 fpoffset = nregs * 8;
591 for (regno = 16; regno < 24; regno++)
592 if (regs_ever_live[regno] && ! call_used_regs[regno])
595 fmask |= 1 << (23 - regno);
598 foffset = fpoffset + nregs * 12;
600 if (frame_pointer_needed)
601 regs_ever_live[FRAME_POINTER_REGNUM] = 0;
602 for (regno = 0; regno < 16; regno++)
603 if (regs_ever_live[regno] && ! call_used_regs[regno])
608 if (flag_pic && current_function_uses_pic_offset_table)
611 mask |= 1 << PIC_OFFSET_TABLE_REGNUM;
613 offset = foffset + nregs * 4;
614 /* FIXME : leaf_function_p below is too strong.
615 What we really need to know there is if there could be pending
616 stack adjustment needed at that point. */
617 restore_from_sp = ! frame_pointer_needed
618 || (! current_function_calls_alloca && leaf_function_p ());
619 if (offset + fsize >= 0x8000
621 && (mask || fmask || fpoffset))
624 asm_fprintf (stream, "\t%Omove.l %0I%d,%Ra1\n", -fsize);
626 asm_fprintf (stream, "\tmovel %0I%d,%Ra1\n", -fsize);
630 if (TARGET_5200 || nregs <= 2)
632 /* Restore each separately in the same order moveml does.
633 Using two movel instructions instead of a single moveml
634 is about 15% faster for the 68020 and 68030 at no expense
639 /* Undo the work from above. */
640 for (i = 0; i< 16; i++)
646 asm_fprintf (stream, "\t%Omove.l -%d(%s,%Ra1.l),%s\n",
648 reg_names[FRAME_POINTER_REGNUM],
651 asm_fprintf (stream, "\tmovel %s@(-%d,%Ra1:l),%s\n",
652 reg_names[FRAME_POINTER_REGNUM],
653 offset + fsize, reg_names[i]);
656 else if (restore_from_sp)
659 asm_fprintf (stream, "\t%Omove.l (%Rsp)+,%s\n",
662 asm_fprintf (stream, "\tmovel %Rsp@+,%s\n",
669 asm_fprintf (stream, "\t%Omove.l -%d(%s),%s\n",
671 reg_names[FRAME_POINTER_REGNUM],
674 asm_fprintf (stream, "\tmovel %s@(-%d),%s\n",
675 reg_names[FRAME_POINTER_REGNUM],
676 offset + fsize, reg_names[i]);
687 asm_fprintf (stream, "\tmovm.l -%d(%s,%Ra1.l),%0I0x%x\n",
689 reg_names[FRAME_POINTER_REGNUM],
692 asm_fprintf (stream, "\tmoveml %s@(-%d,%Ra1:l),%0I0x%x\n",
693 reg_names[FRAME_POINTER_REGNUM],
694 offset + fsize, mask);
697 else if (restore_from_sp)
700 asm_fprintf (stream, "\tmovm.l (%Rsp)+,%0I0x%x\n", mask);
702 asm_fprintf (stream, "\tmoveml %Rsp@+,%0I0x%x\n", mask);
708 asm_fprintf (stream, "\tmovm.l -%d(%s),%0I0x%x\n",
710 reg_names[FRAME_POINTER_REGNUM],
713 asm_fprintf (stream, "\tmoveml %s@(-%d),%0I0x%x\n",
714 reg_names[FRAME_POINTER_REGNUM],
715 offset + fsize, mask);
724 asm_fprintf (stream, "\tfmovm -%d(%s,%Ra1.l),%0I0x%x\n",
726 reg_names[FRAME_POINTER_REGNUM],
729 asm_fprintf (stream, "\tfmovem %s@(-%d,%Ra1:l),%0I0x%x\n",
730 reg_names[FRAME_POINTER_REGNUM],
731 foffset + fsize, fmask);
734 else if (restore_from_sp)
737 asm_fprintf (stream, "\tfmovm (%Rsp)+,%0I0x%x\n", fmask);
739 asm_fprintf (stream, "\tfmovem %Rsp@+,%0I0x%x\n", fmask);
745 asm_fprintf (stream, "\tfmovm -%d(%s),%0I0x%x\n",
747 reg_names[FRAME_POINTER_REGNUM],
750 asm_fprintf (stream, "\tfmovem %s@(-%d),%0I0x%x\n",
751 reg_names[FRAME_POINTER_REGNUM],
752 foffset + fsize, fmask);
757 for (regno = 55; regno >= 24; regno--)
758 if (regs_ever_live[regno] && ! call_used_regs[regno])
763 asm_fprintf (stream, "\tfpmovd -%d(%s,%Ra1.l), %s\n",
765 reg_names[FRAME_POINTER_REGNUM],
768 asm_fprintf (stream, "\tfpmoved %s@(-%d,%Ra1:l), %s\n",
769 reg_names[FRAME_POINTER_REGNUM],
770 fpoffset + fsize, reg_names[regno]);
773 else if (restore_from_sp)
776 asm_fprintf (stream, "\tfpmovd (%Rsp)+,%s\n",
779 asm_fprintf (stream, "\tfpmoved %Rsp@+, %s\n",
786 asm_fprintf (stream, "\tfpmovd -%d(%s), %s\n",
788 reg_names[FRAME_POINTER_REGNUM],
791 asm_fprintf (stream, "\tfpmoved %s@(-%d), %s\n",
792 reg_names[FRAME_POINTER_REGNUM],
793 fpoffset + fsize, reg_names[regno]);
798 if (frame_pointer_needed)
799 fprintf (stream, "\tunlk %s\n",
800 reg_names[FRAME_POINTER_REGNUM]);
809 asm_fprintf (stream, "\taddq.w %0I%d,%Rsp\n", fsize + 4);
811 asm_fprintf (stream, "\taddqw %0I%d,%Rsp\n", fsize + 4);
817 asm_fprintf (stream, "\taddq.l %0I%d,%Rsp\n", fsize + 4);
819 asm_fprintf (stream, "\taddql %0I%d,%Rsp\n", fsize + 4);
823 else if (fsize + 4 <= 16 && TARGET_CPU32)
825 /* On the CPU32 it is faster to use two addqw instructions to
826 add a small integer (8 < N <= 16) to a register. */
827 /* asm_fprintf() cannot handle %. */
829 asm_fprintf (stream, "\taddq.w %0I8,%Rsp\n\taddq.w %0I%d,%Rsp\n",
832 asm_fprintf (stream, "\taddqw %0I8,%Rsp\n\taddqw %0I%d,%Rsp\n",
837 #endif /* not NO_ADDSUB_Q */
838 if (fsize + 4 < 0x8000)
842 /* asm_fprintf() cannot handle %. */
844 asm_fprintf (stream, "\tadd.w %0I%d,%Rsp\n", fsize + 4);
846 asm_fprintf (stream, "\taddw %0I%d,%Rsp\n", fsize + 4);
852 asm_fprintf (stream, "\tlea (%d,%Rsp),%Rsp\n", fsize + 4);
854 asm_fprintf (stream, "\tlea %Rsp@(%d),%Rsp\n", fsize + 4);
860 /* asm_fprintf() cannot handle %. */
862 asm_fprintf (stream, "\tadd.l %0I%d,%Rsp\n", fsize + 4);
864 asm_fprintf (stream, "\taddl %0I%d,%Rsp\n", fsize + 4);
868 if (current_function_pops_args)
869 asm_fprintf (stream, "\trtd %0I%d\n", current_function_pops_args);
871 fprintf (stream, "\trts\n");
874 /* Similar to general_operand, but exclude stack_pointer_rtx. */
877 not_sp_operand (op, mode)
879 enum machine_mode mode;
881 return op != stack_pointer_rtx && general_operand (op, mode);
884 /* Return TRUE if X is a valid comparison operator for the dbcc
887 Note it rejects floating point comparison operators.
888 (In the future we could use Fdbcc).
890 It also rejects some comparisons when CC_NO_OVERFLOW is set. */
893 valid_dbcc_comparison_p (x, mode)
895 enum machine_mode mode ATTRIBUTE_UNUSED;
897 switch (GET_CODE (x))
899 case EQ: case NE: case GTU: case LTU:
903 /* Reject some when CC_NO_OVERFLOW is set. This may be over
905 case GT: case LT: case GE: case LE:
906 return ! (cc_prev_status.flags & CC_NO_OVERFLOW);
912 /* Return non-zero if flags are currently in the 68881 flag register. */
916 /* We could add support for these in the future */
917 return cc_status.flags & CC_IN_68881;
920 /* Output a dbCC; jCC sequence. Note we do not handle the
921 floating point version of this sequence (Fdbcc). We also
922 do not handle alternative conditions when CC_NO_OVERFLOW is
923 set. It is assumed that valid_dbcc_comparison_p and flags_in_68881 will
924 kick those out before we get here. */
927 output_dbcc_and_branch (operands)
930 switch (GET_CODE (operands[3]))
934 output_asm_insn ("dbeq %0,%l1\n\tjbeq %l2", operands);
936 output_asm_insn ("dbeq %0,%l1\n\tjeq %l2", operands);
942 output_asm_insn ("dbne %0,%l1\n\tjbne %l2", operands);
944 output_asm_insn ("dbne %0,%l1\n\tjne %l2", operands);
950 output_asm_insn ("dbgt %0,%l1\n\tjbgt %l2", operands);
952 output_asm_insn ("dbgt %0,%l1\n\tjgt %l2", operands);
958 output_asm_insn ("dbhi %0,%l1\n\tjbhi %l2", operands);
960 output_asm_insn ("dbhi %0,%l1\n\tjhi %l2", operands);
966 output_asm_insn ("dblt %0,%l1\n\tjblt %l2", operands);
968 output_asm_insn ("dblt %0,%l1\n\tjlt %l2", operands);
974 output_asm_insn ("dbcs %0,%l1\n\tjbcs %l2", operands);
976 output_asm_insn ("dbcs %0,%l1\n\tjcs %l2", operands);
982 output_asm_insn ("dbge %0,%l1\n\tjbge %l2", operands);
984 output_asm_insn ("dbge %0,%l1\n\tjge %l2", operands);
990 output_asm_insn ("dbcc %0,%l1\n\tjbcc %l2", operands);
992 output_asm_insn ("dbcc %0,%l1\n\tjcc %l2", operands);
998 output_asm_insn ("dble %0,%l1\n\tjble %l2", operands);
1000 output_asm_insn ("dble %0,%l1\n\tjle %l2", operands);
1006 output_asm_insn ("dbls %0,%l1\n\tjbls %l2", operands);
1008 output_asm_insn ("dbls %0,%l1\n\tjls %l2", operands);
1016 /* If the decrement is to be done in SImode, then we have
1017 to compensate for the fact that dbcc decrements in HImode. */
1018 switch (GET_MODE (operands[0]))
1022 output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjbpl %l1", operands);
1024 output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjpl %l1", operands);
1037 output_scc_di(op, operand1, operand2, dest)
1044 enum rtx_code op_code = GET_CODE (op);
1046 /* This does not produce a usefull cc. */
1049 /* The m68k cmp.l instruction requires operand1 to be a reg as used
1050 below. Swap the operands and change the op if these requirements
1051 are not fulfilled. */
1052 if (GET_CODE (operand2) == REG && GET_CODE (operand1) != REG)
1056 operand1 = operand2;
1058 op_code = swap_condition (op_code);
1060 loperands[0] = operand1;
1061 if (GET_CODE (operand1) == REG)
1062 loperands[1] = gen_rtx_REG (SImode, REGNO (operand1) + 1);
1064 loperands[1] = adj_offsettable_operand (operand1, 4);
1065 if (operand2 != const0_rtx)
1067 loperands[2] = operand2;
1068 if (GET_CODE (operand2) == REG)
1069 loperands[3] = gen_rtx_REG (SImode, REGNO (operand2) + 1);
1071 loperands[3] = adj_offsettable_operand (operand2, 4);
1073 loperands[4] = gen_label_rtx();
1074 if (operand2 != const0_rtx)
1077 #ifdef SGS_CMP_ORDER
1078 output_asm_insn ("cmp%.l %0,%2\n\tjbne %l4\n\tcmp%.l %1,%3", loperands);
1080 output_asm_insn ("cmp%.l %2,%0\n\tjbne %l4\n\tcmp%.l %3,%1", loperands);
1083 #ifdef SGS_CMP_ORDER
1084 output_asm_insn ("cmp%.l %0,%2\n\tjne %l4\n\tcmp%.l %1,%3", loperands);
1086 output_asm_insn ("cmp%.l %2,%0\n\tjne %l4\n\tcmp%.l %3,%1", loperands);
1092 if (TARGET_68020 || TARGET_5200 || ! ADDRESS_REG_P (loperands[0]))
1093 output_asm_insn ("tst%.l %0", loperands);
1096 #ifdef SGS_CMP_ORDER
1097 output_asm_insn ("cmp%.w %0,%#0", loperands);
1099 output_asm_insn ("cmp%.w %#0,%0", loperands);
1104 output_asm_insn ("jbne %l4", loperands);
1106 output_asm_insn ("jne %l4", loperands);
1109 if (TARGET_68020 || TARGET_5200 || ! ADDRESS_REG_P (loperands[1]))
1110 output_asm_insn ("tst%.l %1", loperands);
1113 #ifdef SGS_CMP_ORDER
1114 output_asm_insn ("cmp%.w %1,%#0", loperands);
1116 output_asm_insn ("cmp%.w %#0,%1", loperands);
1121 loperands[5] = dest;
1126 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1127 CODE_LABEL_NUMBER (loperands[4]));
1128 output_asm_insn ("seq %5", loperands);
1132 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1133 CODE_LABEL_NUMBER (loperands[4]));
1134 output_asm_insn ("sne %5", loperands);
1138 loperands[6] = gen_label_rtx();
1140 output_asm_insn ("shi %5\n\tjbra %l6", loperands);
1142 output_asm_insn ("shi %5\n\tjra %l6", loperands);
1144 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1145 CODE_LABEL_NUMBER (loperands[4]));
1146 output_asm_insn ("sgt %5", loperands);
1147 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1148 CODE_LABEL_NUMBER (loperands[6]));
1152 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1153 CODE_LABEL_NUMBER (loperands[4]));
1154 output_asm_insn ("shi %5", loperands);
1158 loperands[6] = gen_label_rtx();
1160 output_asm_insn ("scs %5\n\tjbra %l6", loperands);
1162 output_asm_insn ("scs %5\n\tjra %l6", loperands);
1164 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1165 CODE_LABEL_NUMBER (loperands[4]));
1166 output_asm_insn ("slt %5", loperands);
1167 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1168 CODE_LABEL_NUMBER (loperands[6]));
1172 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1173 CODE_LABEL_NUMBER (loperands[4]));
1174 output_asm_insn ("scs %5", loperands);
1178 loperands[6] = gen_label_rtx();
1180 output_asm_insn ("scc %5\n\tjbra %l6", loperands);
1182 output_asm_insn ("scc %5\n\tjra %l6", loperands);
1184 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1185 CODE_LABEL_NUMBER (loperands[4]));
1186 output_asm_insn ("sge %5", loperands);
1187 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1188 CODE_LABEL_NUMBER (loperands[6]));
1192 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1193 CODE_LABEL_NUMBER (loperands[4]));
1194 output_asm_insn ("scc %5", loperands);
1198 loperands[6] = gen_label_rtx();
1200 output_asm_insn ("sls %5\n\tjbra %l6", loperands);
1202 output_asm_insn ("sls %5\n\tjra %l6", loperands);
1204 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1205 CODE_LABEL_NUMBER (loperands[4]));
1206 output_asm_insn ("sle %5", loperands);
1207 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1208 CODE_LABEL_NUMBER (loperands[6]));
1212 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1213 CODE_LABEL_NUMBER (loperands[4]));
1214 output_asm_insn ("sls %5", loperands);
1224 output_btst (operands, countop, dataop, insn, signpos)
1226 rtx countop, dataop;
1230 operands[0] = countop;
1231 operands[1] = dataop;
1233 if (GET_CODE (countop) == CONST_INT)
1235 register int count = INTVAL (countop);
1236 /* If COUNT is bigger than size of storage unit in use,
1237 advance to the containing unit of same size. */
1238 if (count > signpos)
1240 int offset = (count & ~signpos) / 8;
1241 count = count & signpos;
1242 operands[1] = dataop = adj_offsettable_operand (dataop, offset);
1244 if (count == signpos)
1245 cc_status.flags = CC_NOT_POSITIVE | CC_Z_IN_NOT_N;
1247 cc_status.flags = CC_NOT_NEGATIVE | CC_Z_IN_NOT_N;
1249 /* These three statements used to use next_insns_test_no...
1250 but it appears that this should do the same job. */
1252 && next_insn_tests_no_inequality (insn))
1255 && next_insn_tests_no_inequality (insn))
1258 && next_insn_tests_no_inequality (insn))
1261 cc_status.flags = CC_NOT_NEGATIVE;
1263 return "btst %0,%1";
1266 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
1267 reference and a constant. */
1270 symbolic_operand (op, mode)
1272 enum machine_mode mode ATTRIBUTE_UNUSED;
1274 switch (GET_CODE (op))
1282 return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
1283 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
1284 && GET_CODE (XEXP (op, 1)) == CONST_INT);
1286 #if 0 /* Deleted, with corresponding change in m68k.h,
1287 so as to fit the specs. No CONST_DOUBLE is ever symbolic. */
1289 return GET_MODE (op) == mode;
1297 /* Check for sign_extend or zero_extend. Used for bit-count operands. */
1300 extend_operator(x, mode)
1302 enum machine_mode mode;
1304 if (mode != VOIDmode && GET_MODE(x) != mode)
1306 switch (GET_CODE(x))
1317 /* Legitimize PIC addresses. If the address is already
1318 position-independent, we return ORIG. Newly generated
1319 position-independent addresses go to REG. If we need more
1320 than one register, we lose.
1322 An address is legitimized by making an indirect reference
1323 through the Global Offset Table with the name of the symbol
1326 The assembler and linker are responsible for placing the
1327 address of the symbol in the GOT. The function prologue
1328 is responsible for initializing a5 to the starting address
1331 The assembler is also responsible for translating a symbol name
1332 into a constant displacement from the start of the GOT.
1334 A quick example may make things a little clearer:
1336 When not generating PIC code to store the value 12345 into _foo
1337 we would generate the following code:
1341 When generating PIC two transformations are made. First, the compiler
1342 loads the address of foo into a register. So the first transformation makes:
1347 The code in movsi will intercept the lea instruction and call this
1348 routine which will transform the instructions into:
1350 movel a5@(_foo:w), a0
1354 That (in a nutshell) is how *all* symbol and label references are
1358 legitimize_pic_address (orig, mode, reg)
1360 enum machine_mode mode ATTRIBUTE_UNUSED;
1364 /* First handle a simple SYMBOL_REF or LABEL_REF */
1365 if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF)
1370 pic_ref = gen_rtx_MEM (Pmode,
1371 gen_rtx_PLUS (Pmode,
1372 pic_offset_table_rtx, orig));
1373 current_function_uses_pic_offset_table = 1;
1374 RTX_UNCHANGING_P (pic_ref) = 1;
1375 emit_move_insn (reg, pic_ref);
1378 else if (GET_CODE (orig) == CONST)
1382 /* Make sure this is CONST has not already been legitimized */
1383 if (GET_CODE (XEXP (orig, 0)) == PLUS
1384 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
1390 /* legitimize both operands of the PLUS */
1391 if (GET_CODE (XEXP (orig, 0)) == PLUS)
1393 base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
1394 orig = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
1395 base == reg ? 0 : reg);
1399 if (GET_CODE (orig) == CONST_INT)
1400 return plus_constant_for_output (base, INTVAL (orig));
1401 pic_ref = gen_rtx_PLUS (Pmode, base, orig);
1402 /* Likewise, should we set special REG_NOTEs here? */
1408 typedef enum { MOVL, SWAP, NEGW, NOTW, NOTB, MOVQ } CONST_METHOD;
1410 static CONST_METHOD const_method PARAMS ((rtx));
1412 #define USE_MOVQ(i) ((unsigned)((i) + 128) <= 255)
1415 const_method (constant)
1421 i = INTVAL (constant);
1425 /* The Coldfire doesn't have byte or word operations. */
1426 /* FIXME: This may not be useful for the m68060 either */
1429 /* if -256 < N < 256 but N is not in range for a moveq
1430 N^ff will be, so use moveq #N^ff, dreg; not.b dreg. */
1431 if (USE_MOVQ (i ^ 0xff))
1433 /* Likewise, try with not.w */
1434 if (USE_MOVQ (i ^ 0xffff))
1436 /* This is the only value where neg.w is useful */
1439 /* Try also with swap */
1441 if (USE_MOVQ ((u >> 16) | (u << 16)))
1444 /* Otherwise, use move.l */
1449 const_int_cost (constant)
1452 switch (const_method (constant))
1455 /* Constants between -128 and 127 are cheap due to moveq */
1461 /* Constants easily generated by moveq + not.b/not.w/neg.w/swap */
1471 output_move_const_into_data_reg (operands)
1476 i = INTVAL (operands[1]);
1477 switch (const_method (operands[1]))
1480 #if defined (MOTOROLA) && !defined (CRDS)
1481 return "moveq%.l %1,%0";
1483 return "moveq %1,%0";
1486 operands[1] = GEN_INT (i ^ 0xff);
1487 #if defined (MOTOROLA) && !defined (CRDS)
1488 return "moveq%.l %1,%0\n\tnot%.b %0";
1490 return "moveq %1,%0\n\tnot%.b %0";
1493 operands[1] = GEN_INT (i ^ 0xffff);
1494 #if defined (MOTOROLA) && !defined (CRDS)
1495 return "moveq%.l %1,%0\n\tnot%.w %0";
1497 return "moveq %1,%0\n\tnot%.w %0";
1500 #if defined (MOTOROLA) && !defined (CRDS)
1501 return "moveq%.l %#-128,%0\n\tneg%.w %0";
1503 return "moveq %#-128,%0\n\tneg%.w %0";
1509 operands[1] = GEN_INT ((u << 16) | (u >> 16));
1510 #if defined (MOTOROLA) && !defined (CRDS)
1511 return "moveq%.l %1,%0\n\tswap %0";
1513 return "moveq %1,%0\n\tswap %0";
1517 return "move%.l %1,%0";
1524 output_move_simode_const (operands)
1527 if (operands[1] == const0_rtx
1528 && (DATA_REG_P (operands[0])
1529 || GET_CODE (operands[0]) == MEM)
1530 /* clr insns on 68000 read before writing.
1531 This isn't so on the 68010, but we have no TARGET_68010. */
1532 && ((TARGET_68020 || TARGET_5200)
1533 || !(GET_CODE (operands[0]) == MEM
1534 && MEM_VOLATILE_P (operands[0]))))
1536 else if (operands[1] == const0_rtx
1537 && ADDRESS_REG_P (operands[0]))
1538 return "sub%.l %0,%0";
1539 else if (DATA_REG_P (operands[0]))
1540 return output_move_const_into_data_reg (operands);
1541 else if (ADDRESS_REG_P (operands[0])
1542 && INTVAL (operands[1]) < 0x8000
1543 && INTVAL (operands[1]) >= -0x8000)
1544 return "move%.w %1,%0";
1545 else if (GET_CODE (operands[0]) == MEM
1546 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
1547 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
1548 && INTVAL (operands[1]) < 0x8000
1549 && INTVAL (operands[1]) >= -0x8000)
1551 return "move%.l %1,%0";
1555 output_move_simode (operands)
1558 if (GET_CODE (operands[1]) == CONST_INT)
1559 return output_move_simode_const (operands);
1560 else if ((GET_CODE (operands[1]) == SYMBOL_REF
1561 || GET_CODE (operands[1]) == CONST)
1562 && push_operand (operands[0], SImode))
1564 else if ((GET_CODE (operands[1]) == SYMBOL_REF
1565 || GET_CODE (operands[1]) == CONST)
1566 && ADDRESS_REG_P (operands[0]))
1567 return "lea %a1,%0";
1568 return "move%.l %1,%0";
1572 output_move_himode (operands)
1575 if (GET_CODE (operands[1]) == CONST_INT)
1577 if (operands[1] == const0_rtx
1578 && (DATA_REG_P (operands[0])
1579 || GET_CODE (operands[0]) == MEM)
1580 /* clr insns on 68000 read before writing.
1581 This isn't so on the 68010, but we have no TARGET_68010. */
1582 && ((TARGET_68020 || TARGET_5200)
1583 || !(GET_CODE (operands[0]) == MEM
1584 && MEM_VOLATILE_P (operands[0]))))
1586 else if (operands[1] == const0_rtx
1587 && ADDRESS_REG_P (operands[0]))
1588 return "sub%.l %0,%0";
1589 else if (DATA_REG_P (operands[0])
1590 && INTVAL (operands[1]) < 128
1591 && INTVAL (operands[1]) >= -128)
1593 #if defined(MOTOROLA) && !defined(CRDS)
1594 return "moveq%.l %1,%0";
1596 return "moveq %1,%0";
1599 else if (INTVAL (operands[1]) < 0x8000
1600 && INTVAL (operands[1]) >= -0x8000)
1601 return "move%.w %1,%0";
1603 else if (CONSTANT_P (operands[1]))
1604 return "move%.l %1,%0";
1606 /* Recognize the insn before a tablejump, one that refers
1607 to a table of offsets. Such an insn will need to refer
1608 to a label on the insn. So output one. Use the label-number
1609 of the table of offsets to generate this label. This code,
1610 and similar code below, assumes that there will be at most one
1611 reference to each table. */
1612 if (GET_CODE (operands[1]) == MEM
1613 && GET_CODE (XEXP (operands[1], 0)) == PLUS
1614 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == LABEL_REF
1615 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) != PLUS)
1617 rtx labelref = XEXP (XEXP (operands[1], 0), 1);
1618 #if defined (MOTOROLA) && !defined (SGS_SWITCH_TABLES)
1620 asm_fprintf (asm_out_file, "\tset %LLI%d,.+2\n",
1621 CODE_LABEL_NUMBER (XEXP (labelref, 0)));
1623 asm_fprintf (asm_out_file, "\t.set %LLI%d,.+2\n",
1624 CODE_LABEL_NUMBER (XEXP (labelref, 0)));
1625 #endif /* not SGS */
1626 #else /* SGS_SWITCH_TABLES or not MOTOROLA */
1627 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LI",
1628 CODE_LABEL_NUMBER (XEXP (labelref, 0)));
1629 #ifdef SGS_SWITCH_TABLES
1630 /* Set flag saying we need to define the symbol
1631 LD%n (with value L%n-LI%n) at the end of the switch table. */
1632 switch_table_difference_label_flag = 1;
1633 #endif /* SGS_SWITCH_TABLES */
1634 #endif /* SGS_SWITCH_TABLES or not MOTOROLA */
1636 #endif /* SGS_NO_LI */
1637 return "move%.w %1,%0";
1641 output_move_qimode (operands)
1646 /* This is probably useless, since it loses for pushing a struct
1647 of several bytes a byte at a time. */
1648 /* 68k family always modifies the stack pointer by at least 2, even for
1649 byte pushes. The 5200 (coldfire) does not do this. */
1650 if (GET_CODE (operands[0]) == MEM
1651 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
1652 && XEXP (XEXP (operands[0], 0), 0) == stack_pointer_rtx
1653 && ! ADDRESS_REG_P (operands[1])
1656 xoperands[1] = operands[1];
1658 = gen_rtx_MEM (QImode,
1659 gen_rtx_PLUS (VOIDmode, stack_pointer_rtx, const1_rtx));
1660 /* Just pushing a byte puts it in the high byte of the halfword. */
1661 /* We must put it in the low-order, high-numbered byte. */
1662 if (!reg_mentioned_p (stack_pointer_rtx, operands[1]))
1664 xoperands[3] = stack_pointer_rtx;
1666 output_asm_insn ("subq%.l %#2,%3\n\tmove%.b %1,%2", xoperands);
1668 output_asm_insn ("sub%.l %#2,%3\n\tmove%.b %1,%2", xoperands);
1672 output_asm_insn ("move%.b %1,%-\n\tmove%.b %@,%2", xoperands);
1676 /* clr and st insns on 68000 read before writing.
1677 This isn't so on the 68010, but we have no TARGET_68010. */
1678 if (!ADDRESS_REG_P (operands[0])
1679 && ((TARGET_68020 || TARGET_5200)
1680 || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
1682 if (operands[1] == const0_rtx)
1684 if ((!TARGET_5200 || DATA_REG_P (operands[0]))
1685 && GET_CODE (operands[1]) == CONST_INT
1686 && (INTVAL (operands[1]) & 255) == 255)
1692 if (GET_CODE (operands[1]) == CONST_INT
1693 && DATA_REG_P (operands[0])
1694 && INTVAL (operands[1]) < 128
1695 && INTVAL (operands[1]) >= -128)
1697 #if defined(MOTOROLA) && !defined(CRDS)
1698 return "moveq%.l %1,%0";
1700 return "moveq %1,%0";
1703 if (operands[1] == const0_rtx && ADDRESS_REG_P (operands[0]))
1704 return "sub%.l %0,%0";
1705 if (GET_CODE (operands[1]) != CONST_INT && CONSTANT_P (operands[1]))
1706 return "move%.l %1,%0";
1707 /* 68k family (including the 5200 coldfire) does not support byte moves to
1708 from address registers. */
1709 if (ADDRESS_REG_P (operands[0]) || ADDRESS_REG_P (operands[1]))
1710 return "move%.w %1,%0";
1711 return "move%.b %1,%0";
1715 output_move_stricthi (operands)
1718 if (operands[1] == const0_rtx
1719 /* clr insns on 68000 read before writing.
1720 This isn't so on the 68010, but we have no TARGET_68010. */
1721 && ((TARGET_68020 || TARGET_5200)
1722 || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
1724 return "move%.w %1,%0";
1728 output_move_strictqi (operands)
1731 if (operands[1] == const0_rtx
1732 /* clr insns on 68000 read before writing.
1733 This isn't so on the 68010, but we have no TARGET_68010. */
1734 && ((TARGET_68020 || TARGET_5200)
1735 || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
1737 return "move%.b %1,%0";
1740 /* Return the best assembler insn template
1741 for moving operands[1] into operands[0] as a fullword. */
1744 singlemove_string (operands)
1747 #ifdef SUPPORT_SUN_FPA
1748 if (FPA_REG_P (operands[0]) || FPA_REG_P (operands[1]))
1749 return "fpmoves %1,%0";
1751 if (GET_CODE (operands[1]) == CONST_INT)
1752 return output_move_simode_const (operands);
1753 return "move%.l %1,%0";
1757 /* Output assembler code to perform a doubleword move insn
1758 with operands OPERANDS. */
1761 output_move_double (operands)
1766 REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP
1771 rtx addreg0 = 0, addreg1 = 0;
1772 int dest_overlapped_low = 0;
1773 int size = GET_MODE_SIZE (GET_MODE (operands[0]));
1778 /* First classify both operands. */
1780 if (REG_P (operands[0]))
1782 else if (offsettable_memref_p (operands[0]))
1784 else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1786 else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1788 else if (GET_CODE (operands[0]) == MEM)
1793 if (REG_P (operands[1]))
1795 else if (CONSTANT_P (operands[1]))
1797 else if (offsettable_memref_p (operands[1]))
1799 else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
1801 else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
1803 else if (GET_CODE (operands[1]) == MEM)
1808 /* Check for the cases that the operand constraints are not
1809 supposed to allow to happen. Abort if we get one,
1810 because generating code for these cases is painful. */
1812 if (optype0 == RNDOP || optype1 == RNDOP)
1815 /* If one operand is decrementing and one is incrementing
1816 decrement the former register explicitly
1817 and change that operand into ordinary indexing. */
1819 if (optype0 == PUSHOP && optype1 == POPOP)
1821 operands[0] = XEXP (XEXP (operands[0], 0), 0);
1823 output_asm_insn ("sub%.l %#12,%0", operands);
1825 output_asm_insn ("subq%.l %#8,%0", operands);
1826 if (GET_MODE (operands[1]) == XFmode)
1827 operands[0] = gen_rtx_MEM (XFmode, operands[0]);
1828 else if (GET_MODE (operands[0]) == DFmode)
1829 operands[0] = gen_rtx_MEM (DFmode, operands[0]);
1831 operands[0] = gen_rtx_MEM (DImode, operands[0]);
1834 if (optype0 == POPOP && optype1 == PUSHOP)
1836 operands[1] = XEXP (XEXP (operands[1], 0), 0);
1838 output_asm_insn ("sub%.l %#12,%1", operands);
1840 output_asm_insn ("subq%.l %#8,%1", operands);
1841 if (GET_MODE (operands[1]) == XFmode)
1842 operands[1] = gen_rtx_MEM (XFmode, operands[1]);
1843 else if (GET_MODE (operands[1]) == DFmode)
1844 operands[1] = gen_rtx_MEM (DFmode, operands[1]);
1846 operands[1] = gen_rtx_MEM (DImode, operands[1]);
1850 /* If an operand is an unoffsettable memory ref, find a register
1851 we can increment temporarily to make it refer to the second word. */
1853 if (optype0 == MEMOP)
1854 addreg0 = find_addr_reg (XEXP (operands[0], 0));
1856 if (optype1 == MEMOP)
1857 addreg1 = find_addr_reg (XEXP (operands[1], 0));
1859 /* Ok, we can do one word at a time.
1860 Normally we do the low-numbered word first,
1861 but if either operand is autodecrementing then we
1862 do the high-numbered word first.
1864 In either case, set up in LATEHALF the operands to use
1865 for the high-numbered word and in some cases alter the
1866 operands in OPERANDS to be suitable for the low-numbered word. */
1870 if (optype0 == REGOP)
1872 latehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 2);
1873 middlehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1875 else if (optype0 == OFFSOP)
1877 middlehalf[0] = adj_offsettable_operand (operands[0], 4);
1878 latehalf[0] = adj_offsettable_operand (operands[0], size - 4);
1882 middlehalf[0] = operands[0];
1883 latehalf[0] = operands[0];
1886 if (optype1 == REGOP)
1888 latehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
1889 middlehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
1891 else if (optype1 == OFFSOP)
1893 middlehalf[1] = adj_offsettable_operand (operands[1], 4);
1894 latehalf[1] = adj_offsettable_operand (operands[1], size - 4);
1896 else if (optype1 == CNSTOP)
1898 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1903 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1904 REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l);
1905 operands[1] = GEN_INT (l[0]);
1906 middlehalf[1] = GEN_INT (l[1]);
1907 latehalf[1] = GEN_INT (l[2]);
1909 else if (CONSTANT_P (operands[1]))
1911 /* actually, no non-CONST_DOUBLE constant should ever
1914 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
1915 latehalf[1] = constm1_rtx;
1917 latehalf[1] = const0_rtx;
1922 middlehalf[1] = operands[1];
1923 latehalf[1] = operands[1];
1927 /* size is not 12: */
1929 if (optype0 == REGOP)
1930 latehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1931 else if (optype0 == OFFSOP)
1932 latehalf[0] = adj_offsettable_operand (operands[0], size - 4);
1934 latehalf[0] = operands[0];
1936 if (optype1 == REGOP)
1937 latehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
1938 else if (optype1 == OFFSOP)
1939 latehalf[1] = adj_offsettable_operand (operands[1], size - 4);
1940 else if (optype1 == CNSTOP)
1941 split_double (operands[1], &operands[1], &latehalf[1]);
1943 latehalf[1] = operands[1];
1946 /* If insn is effectively movd N(sp),-(sp) then we will do the
1947 high word first. We should use the adjusted operand 1 (which is N+4(sp))
1948 for the low word as well, to compensate for the first decrement of sp. */
1949 if (optype0 == PUSHOP
1950 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
1951 && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
1952 operands[1] = middlehalf[1] = latehalf[1];
1954 /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)),
1955 if the upper part of reg N does not appear in the MEM, arrange to
1956 emit the move late-half first. Otherwise, compute the MEM address
1957 into the upper part of N and use that as a pointer to the memory
1959 if (optype0 == REGOP
1960 && (optype1 == OFFSOP || optype1 == MEMOP))
1962 rtx testlow = gen_rtx_REG (SImode, REGNO (operands[0]));
1964 if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0))
1965 && reg_overlap_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
1967 /* If both halves of dest are used in the src memory address,
1968 compute the address into latehalf of dest.
1969 Note that this can't happen if the dest is two data regs. */
1971 xops[0] = latehalf[0];
1972 xops[1] = XEXP (operands[1], 0);
1973 output_asm_insn ("lea %a1,%0", xops);
1974 if( GET_MODE (operands[1]) == XFmode )
1976 operands[1] = gen_rtx_MEM (XFmode, latehalf[0]);
1977 middlehalf[1] = adj_offsettable_operand (operands[1], size-8);
1978 latehalf[1] = adj_offsettable_operand (operands[1], size-4);
1982 operands[1] = gen_rtx_MEM (DImode, latehalf[0]);
1983 latehalf[1] = adj_offsettable_operand (operands[1], size-4);
1987 && reg_overlap_mentioned_p (middlehalf[0],
1988 XEXP (operands[1], 0)))
1990 /* Check for two regs used by both source and dest.
1991 Note that this can't happen if the dest is all data regs.
1992 It can happen if the dest is d6, d7, a0.
1993 But in that case, latehalf is an addr reg, so
1994 the code at compadr does ok. */
1996 if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0))
1997 || reg_overlap_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
2000 /* JRV says this can't happen: */
2001 if (addreg0 || addreg1)
2004 /* Only the middle reg conflicts; simply put it last. */
2005 output_asm_insn (singlemove_string (operands), operands);
2006 output_asm_insn (singlemove_string (latehalf), latehalf);
2007 output_asm_insn (singlemove_string (middlehalf), middlehalf);
2010 else if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0)))
2011 /* If the low half of dest is mentioned in the source memory
2012 address, the arrange to emit the move late half first. */
2013 dest_overlapped_low = 1;
2016 /* If one or both operands autodecrementing,
2017 do the two words, high-numbered first. */
2019 /* Likewise, the first move would clobber the source of the second one,
2020 do them in the other order. This happens only for registers;
2021 such overlap can't happen in memory unless the user explicitly
2022 sets it up, and that is an undefined circumstance. */
2024 if (optype0 == PUSHOP || optype1 == PUSHOP
2025 || (optype0 == REGOP && optype1 == REGOP
2026 && ((middlehalf[1] && REGNO (operands[0]) == REGNO (middlehalf[1]))
2027 || REGNO (operands[0]) == REGNO (latehalf[1])))
2028 || dest_overlapped_low)
2030 /* Make any unoffsettable addresses point at high-numbered word. */
2034 output_asm_insn ("addq%.l %#8,%0", &addreg0);
2036 output_asm_insn ("addq%.l %#4,%0", &addreg0);
2041 output_asm_insn ("addq%.l %#8,%0", &addreg1);
2043 output_asm_insn ("addq%.l %#4,%0", &addreg1);
2047 output_asm_insn (singlemove_string (latehalf), latehalf);
2049 /* Undo the adds we just did. */
2051 output_asm_insn ("subq%.l %#4,%0", &addreg0);
2053 output_asm_insn ("subq%.l %#4,%0", &addreg1);
2057 output_asm_insn (singlemove_string (middlehalf), middlehalf);
2059 output_asm_insn ("subq%.l %#4,%0", &addreg0);
2061 output_asm_insn ("subq%.l %#4,%0", &addreg1);
2064 /* Do low-numbered word. */
2065 return singlemove_string (operands);
2068 /* Normal case: do the two words, low-numbered first. */
2070 output_asm_insn (singlemove_string (operands), operands);
2072 /* Do the middle one of the three words for long double */
2076 output_asm_insn ("addq%.l %#4,%0", &addreg0);
2078 output_asm_insn ("addq%.l %#4,%0", &addreg1);
2080 output_asm_insn (singlemove_string (middlehalf), middlehalf);
2083 /* Make any unoffsettable addresses point at high-numbered word. */
2085 output_asm_insn ("addq%.l %#4,%0", &addreg0);
2087 output_asm_insn ("addq%.l %#4,%0", &addreg1);
2090 output_asm_insn (singlemove_string (latehalf), latehalf);
2092 /* Undo the adds we just did. */
2096 output_asm_insn ("subq%.l %#8,%0", &addreg0);
2098 output_asm_insn ("subq%.l %#4,%0", &addreg0);
2103 output_asm_insn ("subq%.l %#8,%0", &addreg1);
2105 output_asm_insn ("subq%.l %#4,%0", &addreg1);
2111 /* Return a REG that occurs in ADDR with coefficient 1.
2112 ADDR can be effectively incremented by incrementing REG. */
2115 find_addr_reg (addr)
2118 while (GET_CODE (addr) == PLUS)
2120 if (GET_CODE (XEXP (addr, 0)) == REG)
2121 addr = XEXP (addr, 0);
2122 else if (GET_CODE (XEXP (addr, 1)) == REG)
2123 addr = XEXP (addr, 1);
2124 else if (CONSTANT_P (XEXP (addr, 0)))
2125 addr = XEXP (addr, 1);
2126 else if (CONSTANT_P (XEXP (addr, 1)))
2127 addr = XEXP (addr, 0);
2131 if (GET_CODE (addr) == REG)
2136 /* Output assembler code to perform a 32 bit 3 operand add. */
2139 output_addsi3 (operands)
2142 if (! operands_match_p (operands[0], operands[1]))
2144 if (!ADDRESS_REG_P (operands[1]))
2146 rtx tmp = operands[1];
2148 operands[1] = operands[2];
2152 /* These insns can result from reloads to access
2153 stack slots over 64k from the frame pointer. */
2154 if (GET_CODE (operands[2]) == CONST_INT
2155 && INTVAL (operands[2]) + 0x8000 >= (unsigned) 0x10000)
2156 return "move%.l %2,%0\n\tadd%.l %1,%0";
2158 if (GET_CODE (operands[2]) == REG)
2159 return "lea 0(%1,%2.l),%0";
2161 return "lea %c2(%1),%0";
2164 if (GET_CODE (operands[2]) == REG)
2165 return "lea (%1,%2.l),%0";
2167 return "lea (%c2,%1),%0";
2168 #else /* not MOTOROLA (MIT syntax) */
2169 if (GET_CODE (operands[2]) == REG)
2170 return "lea %1@(0,%2:l),%0";
2172 return "lea %1@(%c2),%0";
2173 #endif /* not MOTOROLA */
2174 #endif /* not SGS */
2176 if (GET_CODE (operands[2]) == CONST_INT)
2179 if (INTVAL (operands[2]) > 0
2180 && INTVAL (operands[2]) <= 8)
2181 return "addq%.l %2,%0";
2182 if (INTVAL (operands[2]) < 0
2183 && INTVAL (operands[2]) >= -8)
2185 operands[2] = GEN_INT (- INTVAL (operands[2]));
2186 return "subq%.l %2,%0";
2188 /* On the CPU32 it is faster to use two addql instructions to
2189 add a small integer (8 < N <= 16) to a register.
2190 Likewise for subql. */
2191 if (TARGET_CPU32 && REG_P (operands[0]))
2193 if (INTVAL (operands[2]) > 8
2194 && INTVAL (operands[2]) <= 16)
2196 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
2197 return "addq%.l %#8,%0\n\taddq%.l %2,%0";
2199 if (INTVAL (operands[2]) < -8
2200 && INTVAL (operands[2]) >= -16)
2202 operands[2] = GEN_INT (- INTVAL (operands[2]) - 8);
2203 return "subq%.l %#8,%0\n\tsubq%.l %2,%0";
2207 if (ADDRESS_REG_P (operands[0])
2208 && INTVAL (operands[2]) >= -0x8000
2209 && INTVAL (operands[2]) < 0x8000)
2212 return "add%.w %2,%0";
2215 return "lea (%c2,%0),%0";
2217 return "lea %0@(%c2),%0";
2221 return "add%.l %2,%0";
2224 /* Store in cc_status the expressions that the condition codes will
2225 describe after execution of an instruction whose pattern is EXP.
2226 Do not alter them if the instruction would not alter the cc's. */
2228 /* On the 68000, all the insns to store in an address register fail to
2229 set the cc's. However, in some cases these instructions can make it
2230 possibly invalid to use the saved cc's. In those cases we clear out
2231 some or all of the saved cc's so they won't be used. */
2234 notice_update_cc (exp, insn)
2238 /* If the cc is being set from the fpa and the expression is not an
2239 explicit floating point test instruction (which has code to deal with
2240 this), reinit the CC. */
2241 if (((cc_status.value1 && FPA_REG_P (cc_status.value1))
2242 || (cc_status.value2 && FPA_REG_P (cc_status.value2)))
2243 && !(GET_CODE (exp) == PARALLEL
2244 && GET_CODE (XVECEXP (exp, 0, 0)) == SET
2245 && XEXP (XVECEXP (exp, 0, 0), 0) == cc0_rtx))
2249 else if (GET_CODE (exp) == SET)
2251 if (GET_CODE (SET_SRC (exp)) == CALL)
2255 else if (ADDRESS_REG_P (SET_DEST (exp)))
2257 if (cc_status.value1 && modified_in_p (cc_status.value1, insn))
2258 cc_status.value1 = 0;
2259 if (cc_status.value2 && modified_in_p (cc_status.value2, insn))
2260 cc_status.value2 = 0;
2262 else if (!FP_REG_P (SET_DEST (exp))
2263 && SET_DEST (exp) != cc0_rtx
2264 && (FP_REG_P (SET_SRC (exp))
2265 || GET_CODE (SET_SRC (exp)) == FIX
2266 || GET_CODE (SET_SRC (exp)) == FLOAT_TRUNCATE
2267 || GET_CODE (SET_SRC (exp)) == FLOAT_EXTEND))
2271 /* A pair of move insns doesn't produce a useful overall cc. */
2272 else if (!FP_REG_P (SET_DEST (exp))
2273 && !FP_REG_P (SET_SRC (exp))
2274 && GET_MODE_SIZE (GET_MODE (SET_SRC (exp))) > 4
2275 && (GET_CODE (SET_SRC (exp)) == REG
2276 || GET_CODE (SET_SRC (exp)) == MEM
2277 || GET_CODE (SET_SRC (exp)) == CONST_DOUBLE))
2281 else if (GET_CODE (SET_SRC (exp)) == CALL)
2285 else if (XEXP (exp, 0) != pc_rtx)
2287 cc_status.flags = 0;
2288 cc_status.value1 = XEXP (exp, 0);
2289 cc_status.value2 = XEXP (exp, 1);
2292 else if (GET_CODE (exp) == PARALLEL
2293 && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
2295 if (ADDRESS_REG_P (XEXP (XVECEXP (exp, 0, 0), 0)))
2297 else if (XEXP (XVECEXP (exp, 0, 0), 0) != pc_rtx)
2299 cc_status.flags = 0;
2300 cc_status.value1 = XEXP (XVECEXP (exp, 0, 0), 0);
2301 cc_status.value2 = XEXP (XVECEXP (exp, 0, 0), 1);
2306 if (cc_status.value2 != 0
2307 && ADDRESS_REG_P (cc_status.value2)
2308 && GET_MODE (cc_status.value2) == QImode)
2310 if (cc_status.value2 != 0
2311 && !(cc_status.value1 && FPA_REG_P (cc_status.value1)))
2312 switch (GET_CODE (cc_status.value2))
2314 case PLUS: case MINUS: case MULT:
2315 case DIV: case UDIV: case MOD: case UMOD: case NEG:
2316 #if 0 /* These instructions always clear the overflow bit */
2317 case ASHIFT: case ASHIFTRT: case LSHIFTRT:
2318 case ROTATE: case ROTATERT:
2320 if (GET_MODE (cc_status.value2) != VOIDmode)
2321 cc_status.flags |= CC_NO_OVERFLOW;
2324 /* (SET r1 (ZERO_EXTEND r2)) on this machine
2325 ends with a move insn moving r2 in r2's mode.
2326 Thus, the cc's are set for r2.
2327 This can set N bit spuriously. */
2328 cc_status.flags |= CC_NOT_NEGATIVE;
2333 if (cc_status.value1 && GET_CODE (cc_status.value1) == REG
2335 && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
2336 cc_status.value2 = 0;
2337 if (((cc_status.value1 && FP_REG_P (cc_status.value1))
2338 || (cc_status.value2 && FP_REG_P (cc_status.value2)))
2339 && !((cc_status.value1 && FPA_REG_P (cc_status.value1))
2340 || (cc_status.value2 && FPA_REG_P (cc_status.value2))))
2341 cc_status.flags = CC_IN_68881;
2345 output_move_const_double (operands)
2348 #ifdef SUPPORT_SUN_FPA
2349 if (TARGET_FPA && FPA_REG_P (operands[0]))
2351 int code = standard_sun_fpa_constant_p (operands[1]);
2355 static char buf[40];
2357 sprintf (buf, "fpmove%%.d %%%%%d,%%0", code & 0x1ff);
2360 return "fpmove%.d %1,%0";
2365 int code = standard_68881_constant_p (operands[1]);
2369 static char buf[40];
2371 sprintf (buf, "fmovecr %%#0x%x,%%0", code & 0xff);
2374 return "fmove%.d %1,%0";
2379 output_move_const_single (operands)
2382 #ifdef SUPPORT_SUN_FPA
2385 int code = standard_sun_fpa_constant_p (operands[1]);
2389 static char buf[40];
2391 sprintf (buf, "fpmove%%.s %%%%%d,%%0", code & 0x1ff);
2394 return "fpmove%.s %1,%0";
2397 #endif /* defined SUPPORT_SUN_FPA */
2399 int code = standard_68881_constant_p (operands[1]);
2403 static char buf[40];
2405 sprintf (buf, "fmovecr %%#0x%x,%%0", code & 0xff);
2408 return "fmove%.s %f1,%0";
2412 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
2413 from the "fmovecr" instruction.
2414 The value, anded with 0xff, gives the code to use in fmovecr
2415 to get the desired constant. */
2417 /* This code has been fixed for cross-compilation. */
2419 static int inited_68881_table = 0;
2421 static const char *const strings_68881[7] = {
2431 int codes_68881[7] = {
2441 REAL_VALUE_TYPE values_68881[7];
2443 /* Set up values_68881 array by converting the decimal values
2444 strings_68881 to binary. */
2451 enum machine_mode mode;
2454 for (i = 0; i < 7; i++)
2458 r = REAL_VALUE_ATOF (strings_68881[i], mode);
2459 values_68881[i] = r;
2461 inited_68881_table = 1;
2465 standard_68881_constant_p (x)
2471 #ifdef NO_ASM_FMOVECR
2475 /* fmovecr must be emulated on the 68040 and 68060, so it shouldn't be
2476 used at all on those chips. */
2477 if (TARGET_68040 || TARGET_68060)
2480 #ifndef REAL_ARITHMETIC
2481 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
2482 if (! flag_pretend_float)
2487 if (! inited_68881_table)
2488 init_68881_table ();
2490 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2492 /* Use REAL_VALUES_IDENTICAL instead of REAL_VALUES_EQUAL so that -0.0
2494 for (i = 0; i < 6; i++)
2496 if (REAL_VALUES_IDENTICAL (r, values_68881[i]))
2497 return (codes_68881[i]);
2500 if (GET_MODE (x) == SFmode)
2503 if (REAL_VALUES_EQUAL (r, values_68881[6]))
2504 return (codes_68881[6]);
2506 /* larger powers of ten in the constants ram are not used
2507 because they are not equal to a `double' C constant. */
2511 /* If X is a floating-point constant, return the logarithm of X base 2,
2512 or 0 if X is not a power of 2. */
2515 floating_exact_log2 (x)
2518 REAL_VALUE_TYPE r, r1;
2521 #ifndef REAL_ARITHMETIC
2522 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
2523 if (! flag_pretend_float)
2528 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2530 if (REAL_VALUES_LESS (r, dconst0))
2535 while (REAL_VALUES_LESS (r1, r))
2537 r1 = REAL_VALUE_LDEXP (dconst1, i);
2538 if (REAL_VALUES_EQUAL (r1, r))
2545 #ifdef SUPPORT_SUN_FPA
2546 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
2547 from the Sun FPA's constant RAM.
2548 The value returned, anded with 0x1ff, gives the code to use in fpmove
2549 to get the desired constant. */
2551 static int inited_FPA_table = 0;
2553 static const char *const strings_FPA[38] = {
2554 /* small rationals */
2567 /* Decimal equivalents of double precision values */
2568 "2.718281828459045091", /* D_E */
2569 "6.283185307179586477", /* 2 pi */
2570 "3.141592653589793116", /* D_PI */
2571 "1.570796326794896619", /* pi/2 */
2572 "1.414213562373095145", /* D_SQRT2 */
2573 "0.7071067811865475244", /* 1/sqrt(2) */
2574 "-1.570796326794896619", /* -pi/2 */
2575 "1.442695040888963387", /* D_LOG2ofE */
2576 "3.321928024887362182", /* D_LOG2of10 */
2577 "0.6931471805599452862", /* D_LOGEof2 */
2578 "2.302585092994045901", /* D_LOGEof10 */
2579 "0.3010299956639811980", /* D_LOG10of2 */
2580 "0.4342944819032518167", /* D_LOG10ofE */
2581 /* Decimal equivalents of single precision values */
2582 "2.718281745910644531", /* S_E */
2583 "6.283185307179586477", /* 2 pi */
2584 "3.141592741012573242", /* S_PI */
2585 "1.570796326794896619", /* pi/2 */
2586 "1.414213538169860840", /* S_SQRT2 */
2587 "0.7071067811865475244", /* 1/sqrt(2) */
2588 "-1.570796326794896619", /* -pi/2 */
2589 "1.442695021629333496", /* S_LOG2ofE */
2590 "3.321928024291992188", /* S_LOG2of10 */
2591 "0.6931471824645996094", /* S_LOGEof2 */
2592 "2.302585124969482442", /* S_LOGEof10 */
2593 "0.3010300099849700928", /* S_LOG10of2 */
2594 "0.4342944920063018799", /* S_LOG10ofE */
2598 int codes_FPA[38] = {
2599 /* small rationals */
2612 /* double precision */
2626 /* single precision */
2642 REAL_VALUE_TYPE values_FPA[38];
2644 /* This code has been fixed for cross-compilation. */
2649 enum machine_mode mode;
2654 for (i = 0; i < 38; i++)
2658 r = REAL_VALUE_ATOF (strings_FPA[i], mode);
2661 inited_FPA_table = 1;
2666 standard_sun_fpa_constant_p (x)
2672 #ifndef REAL_ARITHMETIC
2673 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
2674 if (! flag_pretend_float)
2679 if (! inited_FPA_table)
2682 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2684 for (i=0; i<12; i++)
2686 if (REAL_VALUES_EQUAL (r, values_FPA[i]))
2687 return (codes_FPA[i]);
2690 if (GET_MODE (x) == SFmode)
2692 for (i=25; i<38; i++)
2694 if (REAL_VALUES_EQUAL (r, values_FPA[i]))
2695 return (codes_FPA[i]);
2700 for (i=12; i<25; i++)
2702 if (REAL_VALUES_EQUAL (r, values_FPA[i]))
2703 return (codes_FPA[i]);
2708 #endif /* define SUPPORT_SUN_FPA */
2710 /* A C compound statement to output to stdio stream STREAM the
2711 assembler syntax for an instruction operand X. X is an RTL
2714 CODE is a value that can be used to specify one of several ways
2715 of printing the operand. It is used when identical operands
2716 must be printed differently depending on the context. CODE
2717 comes from the `%' specification that was used to request
2718 printing of the operand. If the specification was just `%DIGIT'
2719 then CODE is 0; if the specification was `%LTR DIGIT' then CODE
2720 is the ASCII code for LTR.
2722 If X is a register, this macro should print the register's name.
2723 The names can be found in an array `reg_names' whose type is
2724 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
2726 When the machine description has a specification `%PUNCT' (a `%'
2727 followed by a punctuation character), this macro is called with
2728 a null pointer for X and the punctuation character for CODE.
2730 The m68k specific codes are:
2732 '.' for dot needed in Motorola-style opcode names.
2733 '-' for an operand pushing on the stack:
2734 sp@-, -(sp) or -(%sp) depending on the style of syntax.
2735 '+' for an operand pushing on the stack:
2736 sp@+, (sp)+ or (%sp)+ depending on the style of syntax.
2737 '@' for a reference to the top word on the stack:
2738 sp@, (sp) or (%sp) depending on the style of syntax.
2739 '#' for an immediate operand prefix (# in MIT and Motorola syntax
2740 but & in SGS syntax, $ in CRDS/UNOS syntax).
2741 '!' for the cc register (used in an `and to cc' insn).
2742 '$' for the letter `s' in an op code, but only on the 68040.
2743 '&' for the letter `d' in an op code, but only on the 68040.
2744 '/' for register prefix needed by longlong.h.
2746 'b' for byte insn (no effect, on the Sun; this is for the ISI).
2747 'd' to force memory addressing to be absolute, not relative.
2748 'f' for float insn (print a CONST_DOUBLE as a float rather than in hex)
2749 'o' for operands to go directly to output_operand_address (bypassing
2750 print_operand_address--used only for SYMBOL_REFs under TARGET_PCREL)
2751 'w' for FPA insn (print a CONST_DOUBLE as a SunFPA constant rather
2752 than directly). Second part of 'y' below.
2753 'x' for float insn (print a CONST_DOUBLE as a float rather than in hex),
2754 or print pair of registers as rx:ry.
2755 'y' for a FPA insn (print pair of registers as rx:ry). This also outputs
2756 CONST_DOUBLE's as SunFPA constant RAM registers if
2757 possible, so it should not be used except for the SunFPA.
2762 print_operand (file, op, letter)
2763 FILE *file; /* file to write to */
2764 rtx op; /* operand to print */
2765 int letter; /* %<letter> or 0 */
2767 #ifdef SUPPORT_SUN_FPA
2773 #if defined (MOTOROLA) && !defined (CRDS)
2774 asm_fprintf (file, ".");
2777 else if (letter == '#')
2779 asm_fprintf (file, "%0I");
2781 else if (letter == '-')
2784 asm_fprintf (file, "-(%Rsp)");
2786 asm_fprintf (file, "%Rsp@-");
2789 else if (letter == '+')
2792 asm_fprintf (file, "(%Rsp)+");
2794 asm_fprintf (file, "%Rsp@+");
2797 else if (letter == '@')
2800 asm_fprintf (file, "(%Rsp)");
2802 asm_fprintf (file, "%Rsp@");
2805 else if (letter == '!')
2807 asm_fprintf (file, "%Rfpcr");
2809 else if (letter == '$')
2811 if (TARGET_68040_ONLY)
2813 fprintf (file, "s");
2816 else if (letter == '&')
2818 if (TARGET_68040_ONLY)
2820 fprintf (file, "d");
2823 else if (letter == '/')
2825 asm_fprintf (file, "%R");
2827 else if (letter == 'o')
2829 /* This is only for direct addresses with TARGET_PCREL */
2830 if (GET_CODE (op) != MEM || GET_CODE (XEXP (op, 0)) != SYMBOL_REF
2833 output_addr_const (file, XEXP (op, 0));
2835 else if (GET_CODE (op) == REG)
2837 #ifdef SUPPORT_SUN_FPA
2839 && (letter == 'y' || letter == 'x')
2840 && GET_MODE (op) == DFmode)
2842 fprintf (file, "%s:%s", reg_names[REGNO (op)],
2843 reg_names[REGNO (op)+1]);
2849 /* Print out the second register name of a register pair.
2850 I.e., R (6) => 7. */
2851 fputs (reg_names[REGNO (op) + 1], file);
2853 fputs (reg_names[REGNO (op)], file);
2856 else if (GET_CODE (op) == MEM)
2858 output_address (XEXP (op, 0));
2859 if (letter == 'd' && ! TARGET_68020
2860 && CONSTANT_ADDRESS_P (XEXP (op, 0))
2861 && !(GET_CODE (XEXP (op, 0)) == CONST_INT
2862 && INTVAL (XEXP (op, 0)) < 0x8000
2863 && INTVAL (XEXP (op, 0)) >= -0x8000))
2866 fprintf (file, ".l");
2868 fprintf (file, ":l");
2872 #ifdef SUPPORT_SUN_FPA
2873 else if ((letter == 'y' || letter == 'w')
2874 && GET_CODE (op) == CONST_DOUBLE
2875 && (i = standard_sun_fpa_constant_p (op)))
2877 fprintf (file, "%%%d", i & 0x1ff);
2880 else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == SFmode)
2883 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
2884 ASM_OUTPUT_FLOAT_OPERAND (letter, file, r);
2886 else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == XFmode)
2889 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
2890 ASM_OUTPUT_LONG_DOUBLE_OPERAND (file, r);
2892 else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == DFmode)
2895 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
2896 ASM_OUTPUT_DOUBLE_OPERAND (file, r);
2900 /* Use `print_operand_address' instead of `output_addr_const'
2901 to ensure that we print relevant PIC stuff. */
2902 asm_fprintf (file, "%0I");
2904 && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST))
2905 print_operand_address (file, op);
2907 output_addr_const (file, op);
2912 /* A C compound statement to output to stdio stream STREAM the
2913 assembler syntax for an instruction operand that is a memory
2914 reference whose address is ADDR. ADDR is an RTL expression.
2916 Note that this contains a kludge that knows that the only reason
2917 we have an address (plus (label_ref...) (reg...)) when not generating
2918 PIC code is in the insn before a tablejump, and we know that m68k.md
2919 generates a label LInnn: on such an insn.
2921 It is possible for PIC to generate a (plus (label_ref...) (reg...))
2922 and we handle that just like we would a (plus (symbol_ref...) (reg...)).
2924 Some SGS assemblers have a bug such that "Lnnn-LInnn-2.b(pc,d0.l*2)"
2925 fails to assemble. Luckily "Lnnn(pc,d0.l*2)" produces the results
2926 we want. This difference can be accommodated by using an assembler
2927 define such "LDnnn" to be either "Lnnn-LInnn-2.b", "Lnnn", or any other
2928 string, as necessary. This is accomplished via the ASM_OUTPUT_CASE_END
2929 macro. See m68k/sgs.h for an example; for versions without the bug.
2930 Some assemblers refuse all the above solutions. The workaround is to
2931 emit "K(pc,d0.l*2)" with K being a small constant known to give the
2934 They also do not like things like "pea 1.w", so we simple leave off
2935 the .w on small constants.
2937 This routine is responsible for distinguishing between -fpic and -fPIC
2938 style relocations in an address. When generating -fpic code the
2939 offset is output in word mode (eg movel a5@(_foo:w), a0). When generating
2940 -fPIC code the offset is output in long mode (eg movel a5@(_foo:l), a0) */
2942 #ifndef ASM_OUTPUT_CASE_FETCH
2945 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2946 asm_fprintf (file, "%LLD%d(%Rpc,%s.", labelno, regname)
2948 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2949 asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.", labelno, labelno, regname)
2952 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2953 asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:", labelno, labelno, regname)
2955 #endif /* ASM_OUTPUT_CASE_FETCH */
2958 print_operand_address (file, addr)
2962 register rtx reg1, reg2, breg, ireg;
2965 switch (GET_CODE (addr))
2969 fprintf (file, "(%s)", reg_names[REGNO (addr)]);
2971 fprintf (file, "%s@", reg_names[REGNO (addr)]);
2976 fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
2978 fprintf (file, "%s@-", reg_names[REGNO (XEXP (addr, 0))]);
2983 fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
2985 fprintf (file, "%s@+", reg_names[REGNO (XEXP (addr, 0))]);
2989 reg1 = reg2 = ireg = breg = offset = 0;
2990 if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
2992 offset = XEXP (addr, 0);
2993 addr = XEXP (addr, 1);
2995 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
2997 offset = XEXP (addr, 1);
2998 addr = XEXP (addr, 0);
3000 if (GET_CODE (addr) != PLUS)
3004 else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND)
3006 reg1 = XEXP (addr, 0);
3007 addr = XEXP (addr, 1);
3009 else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND)
3011 reg1 = XEXP (addr, 1);
3012 addr = XEXP (addr, 0);
3014 else if (GET_CODE (XEXP (addr, 0)) == MULT)
3016 reg1 = XEXP (addr, 0);
3017 addr = XEXP (addr, 1);
3019 else if (GET_CODE (XEXP (addr, 1)) == MULT)
3021 reg1 = XEXP (addr, 1);
3022 addr = XEXP (addr, 0);
3024 else if (GET_CODE (XEXP (addr, 0)) == REG)
3026 reg1 = XEXP (addr, 0);
3027 addr = XEXP (addr, 1);
3029 else if (GET_CODE (XEXP (addr, 1)) == REG)
3031 reg1 = XEXP (addr, 1);
3032 addr = XEXP (addr, 0);
3034 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT
3035 || GET_CODE (addr) == SIGN_EXTEND)
3047 #if 0 /* for OLD_INDEXING */
3048 else if (GET_CODE (addr) == PLUS)
3050 if (GET_CODE (XEXP (addr, 0)) == REG)
3052 reg2 = XEXP (addr, 0);
3053 addr = XEXP (addr, 1);
3055 else if (GET_CODE (XEXP (addr, 1)) == REG)
3057 reg2 = XEXP (addr, 1);
3058 addr = XEXP (addr, 0);
3070 if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND
3071 || GET_CODE (reg1) == MULT))
3072 || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
3077 else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
3082 if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF
3083 && ! (flag_pic && ireg == pic_offset_table_rtx))
3086 if (GET_CODE (ireg) == MULT)
3088 scale = INTVAL (XEXP (ireg, 1));
3089 ireg = XEXP (ireg, 0);
3091 if (GET_CODE (ireg) == SIGN_EXTEND)
3093 ASM_OUTPUT_CASE_FETCH (file,
3094 CODE_LABEL_NUMBER (XEXP (addr, 0)),
3095 reg_names[REGNO (XEXP (ireg, 0))]);
3096 fprintf (file, "w");
3100 ASM_OUTPUT_CASE_FETCH (file,
3101 CODE_LABEL_NUMBER (XEXP (addr, 0)),
3102 reg_names[REGNO (ireg)]);
3103 fprintf (file, "l");
3108 fprintf (file, "*%d", scale);
3110 fprintf (file, ":%d", scale);
3116 if (breg != 0 && ireg == 0 && GET_CODE (addr) == LABEL_REF
3117 && ! (flag_pic && breg == pic_offset_table_rtx))
3119 ASM_OUTPUT_CASE_FETCH (file,
3120 CODE_LABEL_NUMBER (XEXP (addr, 0)),
3121 reg_names[REGNO (breg)]);
3122 fprintf (file, "l)");
3125 if (ireg != 0 || breg != 0)
3132 if (! flag_pic && addr && GET_CODE (addr) == LABEL_REF)
3139 output_addr_const (file, addr);
3140 if (flag_pic && (breg == pic_offset_table_rtx))
3142 fprintf (file, "@GOT");
3144 fprintf (file, ".w");
3147 fprintf (file, "(%s", reg_names[REGNO (breg)]);
3153 fprintf (file, "%s@(", reg_names[REGNO (breg)]);
3156 output_addr_const (file, addr);
3157 if ((flag_pic == 1) && (breg == pic_offset_table_rtx))
3158 fprintf (file, ":w");
3159 if ((flag_pic == 2) && (breg == pic_offset_table_rtx))
3160 fprintf (file, ":l");
3162 if (addr != 0 && ireg != 0)
3167 if (ireg != 0 && GET_CODE (ireg) == MULT)
3169 scale = INTVAL (XEXP (ireg, 1));
3170 ireg = XEXP (ireg, 0);
3172 if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND)
3175 fprintf (file, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]);
3177 fprintf (file, "%s:w", reg_names[REGNO (XEXP (ireg, 0))]);
3183 fprintf (file, "%s.l", reg_names[REGNO (ireg)]);
3185 fprintf (file, "%s:l", reg_names[REGNO (ireg)]);
3191 fprintf (file, "*%d", scale);
3193 fprintf (file, ":%d", scale);
3199 else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF
3200 && ! (flag_pic && reg1 == pic_offset_table_rtx))
3202 ASM_OUTPUT_CASE_FETCH (file,
3203 CODE_LABEL_NUMBER (XEXP (addr, 0)),
3204 reg_names[REGNO (reg1)]);
3205 fprintf (file, "l)");
3208 /* FALL-THROUGH (is this really what we want?) */
3210 if (GET_CODE (addr) == CONST_INT
3211 && INTVAL (addr) < 0x8000
3212 && INTVAL (addr) >= -0x8000)
3216 /* Many SGS assemblers croak on size specifiers for constants. */
3217 fprintf (file, "%d", INTVAL (addr));
3219 fprintf (file, "%d.w", INTVAL (addr));
3222 fprintf (file, "%d:w", INTVAL (addr));
3225 else if (GET_CODE (addr) == CONST_INT)
3228 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
3235 else if (TARGET_PCREL)
3238 output_addr_const (file, addr);
3240 asm_fprintf (file, ":w,%Rpc)");
3242 asm_fprintf (file, ":l,%Rpc)");
3246 /* Special case for SYMBOL_REF if the symbol name ends in
3247 `.<letter>', this can be mistaken as a size suffix. Put
3248 the name in parentheses. */
3249 if (GET_CODE (addr) == SYMBOL_REF
3250 && strlen (XSTR (addr, 0)) > 2
3251 && XSTR (addr, 0)[strlen (XSTR (addr, 0)) - 2] == '.')
3254 output_addr_const (file, addr);
3258 output_addr_const (file, addr);
3264 /* Check for cases where a clr insns can be omitted from code using
3265 strict_low_part sets. For example, the second clrl here is not needed:
3266 clrl d0; movw a0@+,d0; use d0; clrl d0; movw a0@+; use d0; ...
3268 MODE is the mode of this STRICT_LOW_PART set. FIRST_INSN is the clear
3269 insn we are checking for redundancy. TARGET is the register set by the
3273 strict_low_part_peephole_ok (mode, first_insn, target)
3274 enum machine_mode mode;
3280 p = prev_nonnote_insn (first_insn);
3284 /* If it isn't an insn, then give up. */
3285 if (GET_CODE (p) != INSN)
3288 if (reg_set_p (target, p))
3290 rtx set = single_set (p);
3293 /* If it isn't an easy to recognize insn, then give up. */
3297 dest = SET_DEST (set);
3299 /* If this sets the entire target register to zero, then our
3300 first_insn is redundant. */
3301 if (rtx_equal_p (dest, target)
3302 && SET_SRC (set) == const0_rtx)
3304 else if (GET_CODE (dest) == STRICT_LOW_PART
3305 && GET_CODE (XEXP (dest, 0)) == REG
3306 && REGNO (XEXP (dest, 0)) == REGNO (target)
3307 && (GET_MODE_SIZE (GET_MODE (XEXP (dest, 0)))
3308 <= GET_MODE_SIZE (mode)))
3309 /* This is a strict low part set which modifies less than
3310 we are using, so it is safe. */
3316 p = prev_nonnote_insn (p);
3323 /* Accept integer operands in the range 0..0xffffffff. We have to check the
3324 range carefully since this predicate is used in DImode contexts. Also, we
3325 need some extra crud to make it work when hosted on 64-bit machines. */
3328 const_uint32_operand (op, mode)
3330 enum machine_mode mode ATTRIBUTE_UNUSED;
3332 #if HOST_BITS_PER_WIDE_INT > 32
3333 /* All allowed constants will fit a CONST_INT. */
3334 return (GET_CODE (op) == CONST_INT
3335 && (INTVAL (op) >= 0 && INTVAL (op) <= 0xffffffffL));
3337 return (GET_CODE (op) == CONST_INT
3338 || (GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_HIGH (op) == 0));
3342 /* Accept integer operands in the range -0x80000000..0x7fffffff. We have
3343 to check the range carefully since this predicate is used in DImode
3347 const_sint32_operand (op, mode)
3349 enum machine_mode mode ATTRIBUTE_UNUSED;
3351 /* All allowed constants will fit a CONST_INT. */
3352 return (GET_CODE (op) == CONST_INT
3353 && (INTVAL (op) >= (-0x7fffffff - 1) && INTVAL (op) <= 0x7fffffff));
3356 /* Operand predicates for implementing asymmetric pc-relative addressing
3357 on m68k. The m68k supports pc-relative addressing (mode 7, register 2)
3358 when used as a source operand, but not as a destintation operand.
3360 We model this by restricting the meaning of the basic predicates
3361 (general_operand, memory_operand, etc) to forbid the use of this
3362 addressing mode, and then define the following predicates that permit
3363 this addressing mode. These predicates can then be used for the
3364 source operands of the appropriate instructions.
3366 n.b. While it is theoretically possible to change all machine patterns
3367 to use this addressing more where permitted by the architecture,
3368 it has only been implemented for "common" cases: SImode, HImode, and
3369 QImode operands, and only for the principle operations that would
3370 require this addressing mode: data movement and simple integer operations.
3372 In parallel with these new predicates, two new constraint letters
3373 were defined: 'S' and 'T'. 'S' is the -mpcrel analog of 'm'.
3374 'T' replaces 's' in the non-pcrel case. It is a no-op in the pcrel case.
3375 In the pcrel case 's' is only valid in combination with 'a' registers.
3376 See addsi3, subsi3, cmpsi, and movsi patterns for a better understanding
3377 of how these constraints are used.
3379 The use of these predicates is strictly optional, though patterns that
3380 don't will cause an extra reload register to be allocated where one
3383 lea (abc:w,%pc),%a0 ; need to reload address
3384 moveq &1,%d1 ; since write to pc-relative space
3385 movel %d1,%a0@ ; is not allowed
3387 lea (abc:w,%pc),%a1 ; no need to reload address here
3388 movel %a1@,%d0 ; since "movel (abc:w,%pc),%d0" is ok
3390 For more info, consult tiemann@cygnus.com.
3393 All of the ugliness with predicates and constraints is due to the
3394 simple fact that the m68k does not allow a pc-relative addressing
3395 mode as a destination. gcc does not distinguish between source and
3396 destination addresses. Hence, if we claim that pc-relative address
3397 modes are valid, e.g. GO_IF_LEGITIMATE_ADDRESS accepts them, then we
3398 end up with invalid code. To get around this problem, we left
3399 pc-relative modes as invalid addresses, and then added special
3400 predicates and constraints to accept them.
3402 A cleaner way to handle this is to modify gcc to distinguish
3403 between source and destination addresses. We can then say that
3404 pc-relative is a valid source address but not a valid destination
3405 address, and hopefully avoid a lot of the predicate and constraint
3406 hackery. Unfortunately, this would be a pretty big change. It would
3407 be a useful change for a number of ports, but there aren't any current
3408 plans to undertake this.
3410 ***************************************************************************/
3413 /* Special case of a general operand that's used as a source operand.
3414 Use this to permit reads from PC-relative memory when -mpcrel
3418 general_src_operand (op, mode)
3420 enum machine_mode mode;
3423 && GET_CODE (op) == MEM
3424 && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
3425 || GET_CODE (XEXP (op, 0)) == LABEL_REF
3426 || GET_CODE (XEXP (op, 0)) == CONST))
3428 return general_operand (op, mode);
3431 /* Special case of a nonimmediate operand that's used as a source.
3432 Use this to permit reads from PC-relative memory when -mpcrel
3436 nonimmediate_src_operand (op, mode)
3438 enum machine_mode mode;
3440 if (TARGET_PCREL && GET_CODE (op) == MEM
3441 && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
3442 || GET_CODE (XEXP (op, 0)) == LABEL_REF
3443 || GET_CODE (XEXP (op, 0)) == CONST))
3445 return nonimmediate_operand (op, mode);
3448 /* Special case of a memory operand that's used as a source.
3449 Use this to permit reads from PC-relative memory when -mpcrel
3453 memory_src_operand (op, mode)
3455 enum machine_mode mode;
3457 if (TARGET_PCREL && GET_CODE (op) == MEM
3458 && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
3459 || GET_CODE (XEXP (op, 0)) == LABEL_REF
3460 || GET_CODE (XEXP (op, 0)) == CONST))
3462 return memory_operand (op, mode);
3465 /* Predicate that accepts only a pc-relative address. This is needed
3466 because pc-relative addresses don't satisfy the predicate
3467 "general_src_operand". */
3470 pcrel_address (op, mode)
3472 enum machine_mode mode ATTRIBUTE_UNUSED;
3474 return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF
3475 || GET_CODE (op) == CONST);
3479 output_andsi3 (operands)
3483 if (GET_CODE (operands[2]) == CONST_INT
3484 && (INTVAL (operands[2]) | 0xffff) == 0xffffffff
3485 && (DATA_REG_P (operands[0])
3486 || offsettable_memref_p (operands[0]))
3489 if (GET_CODE (operands[0]) != REG)
3490 operands[0] = adj_offsettable_operand (operands[0], 2);
3491 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
3492 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3494 if (operands[2] == const0_rtx)
3496 return "and%.w %2,%0";
3498 if (GET_CODE (operands[2]) == CONST_INT
3499 && (logval = exact_log2 (~ INTVAL (operands[2]))) >= 0
3500 && (DATA_REG_P (operands[0])
3501 || offsettable_memref_p (operands[0])))
3503 if (DATA_REG_P (operands[0]))
3505 operands[1] = GEN_INT (logval);
3509 operands[0] = adj_offsettable_operand (operands[0], 3 - (logval / 8));
3510 operands[1] = GEN_INT (logval % 8);
3512 /* This does not set condition codes in a standard way. */
3514 return "bclr %1,%0";
3516 return "and%.l %2,%0";
3520 output_iorsi3 (operands)
3523 register int logval;
3524 if (GET_CODE (operands[2]) == CONST_INT
3525 && INTVAL (operands[2]) >> 16 == 0
3526 && (DATA_REG_P (operands[0])
3527 || offsettable_memref_p (operands[0]))
3530 if (GET_CODE (operands[0]) != REG)
3531 operands[0] = adj_offsettable_operand (operands[0], 2);
3532 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3534 if (INTVAL (operands[2]) == 0xffff)
3535 return "mov%.w %2,%0";
3536 return "or%.w %2,%0";
3538 if (GET_CODE (operands[2]) == CONST_INT
3539 && (logval = exact_log2 (INTVAL (operands[2]))) >= 0
3540 && (DATA_REG_P (operands[0])
3541 || offsettable_memref_p (operands[0])))
3543 if (DATA_REG_P (operands[0]))
3545 operands[1] = GEN_INT (logval);
3549 operands[0] = adj_offsettable_operand (operands[0], 3 - (logval / 8));
3550 operands[1] = GEN_INT (logval % 8);
3553 return "bset %1,%0";
3555 return "or%.l %2,%0";
3559 output_xorsi3 (operands)
3562 register int logval;
3563 if (GET_CODE (operands[2]) == CONST_INT
3564 && INTVAL (operands[2]) >> 16 == 0
3565 && (offsettable_memref_p (operands[0]) || DATA_REG_P (operands[0]))
3568 if (! DATA_REG_P (operands[0]))
3569 operands[0] = adj_offsettable_operand (operands[0], 2);
3570 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3572 if (INTVAL (operands[2]) == 0xffff)
3574 return "eor%.w %2,%0";
3576 if (GET_CODE (operands[2]) == CONST_INT
3577 && (logval = exact_log2 (INTVAL (operands[2]))) >= 0
3578 && (DATA_REG_P (operands[0])
3579 || offsettable_memref_p (operands[0])))
3581 if (DATA_REG_P (operands[0]))
3583 operands[1] = GEN_INT (logval);
3587 operands[0] = adj_offsettable_operand (operands[0], 3 - (logval / 8));
3588 operands[1] = GEN_INT (logval % 8);
3591 return "bchg %1,%0";
3593 return "eor%.l %2,%0";