1 /* Subroutines for insn-output.c for Motorola 68000 family.
2 Copyright (C) 1987, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
3 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
28 #include "hard-reg-set.h"
30 #include "insn-config.h"
31 #include "conditions.h"
32 #include "insn-flags.h"
34 #include "insn-attr.h"
39 /* Needed for use_return_insn. */
42 #ifdef SUPPORT_SUN_FPA
44 /* Index into this array by (register number >> 3) to find the
45 smallest class which contains that register. */
46 enum reg_class regno_reg_class
[]
47 = { DATA_REGS
, ADDR_REGS
, FP_REGS
,
48 LO_FPA_REGS
, LO_FPA_REGS
, FPA_REGS
, FPA_REGS
};
50 #endif /* defined SUPPORT_SUN_FPA */
52 /* This flag is used to communicate between movhi and ASM_OUTPUT_CASE_END,
53 if SGS_SWITCH_TABLE. */
54 int switch_table_difference_label_flag
;
56 static rtx find_addr_reg
PARAMS ((rtx
));
57 rtx legitimize_pic_address
PARAMS ((rtx
, enum machine_mode
, rtx
));
58 static const char *singlemove_string
PARAMS ((rtx
*));
61 /* Alignment to use for loops and jumps */
62 /* Specify power of two alignment used for loops. */
63 const char *m68k_align_loops_string
;
64 /* Specify power of two alignment used for non-loop jumps. */
65 const char *m68k_align_jumps_string
;
66 /* Specify power of two alignment used for functions. */
67 const char *m68k_align_funcs_string
;
69 /* Specify power of two alignment used for loops. */
71 /* Specify power of two alignment used for non-loop jumps. */
73 /* Specify power of two alignment used for functions. */
76 /* Nonzero if the last compare/test insn had FP operands. The
77 sCC expanders peek at this to determine what to do for the
78 68060, which has no fsCC instructions. */
79 int m68k_last_compare_had_fp_operands
;
81 /* Sometimes certain combinations of command options do not make
82 sense on a particular target machine. You can define a macro
83 `OVERRIDE_OPTIONS' to take account of this. This macro, if
84 defined, is executed once just after all the command options have
87 Don't use this macro to turn on various extra optimizations for
88 `-O'. That is what `OPTIMIZATION_OPTIONS' is for. */
97 /* Validate -malign-loops= value, or provide default */
98 if (m68k_align_loops_string
)
100 m68k_align_loops
= atoi (m68k_align_loops_string
);
101 if (m68k_align_loops
< 1 || m68k_align_loops
> MAX_CODE_ALIGN
)
102 fatal ("-malign-loops=%d is not between 1 and %d",
103 m68k_align_loops
, MAX_CODE_ALIGN
);
106 m68k_align_loops
= def_align
;
108 /* Validate -malign-jumps= value, or provide default */
109 if (m68k_align_jumps_string
)
111 m68k_align_jumps
= atoi (m68k_align_jumps_string
);
112 if (m68k_align_jumps
< 1 || m68k_align_jumps
> MAX_CODE_ALIGN
)
113 fatal ("-malign-jumps=%d is not between 1 and %d",
114 m68k_align_jumps
, MAX_CODE_ALIGN
);
117 m68k_align_jumps
= def_align
;
119 /* Validate -malign-functions= value, or provide default */
120 if (m68k_align_funcs_string
)
122 m68k_align_funcs
= atoi (m68k_align_funcs_string
);
123 if (m68k_align_funcs
< 1 || m68k_align_funcs
> MAX_CODE_ALIGN
)
124 fatal ("-malign-functions=%d is not between 1 and %d",
125 m68k_align_funcs
, MAX_CODE_ALIGN
);
128 m68k_align_funcs
= def_align
;
131 /* This function generates the assembly code for function entry.
132 STREAM is a stdio stream to output the code to.
133 SIZE is an int: how many units of temporary storage to allocate.
134 Refer to the array `regs_ever_live' to determine which registers
135 to save; `regs_ever_live[I]' is nonzero if register number I
136 is ever used in the function. This function is responsible for
137 knowing which registers should not be saved even if used. */
140 /* Note that the order of the bit mask for fmovem is the opposite
141 of the order for movem! */
145 output_function_prologue (stream
, size
)
150 register int mask
= 0;
151 int num_saved_regs
= 0;
152 extern char call_used_regs
[];
153 int fsize
= (size
+ 3) & -4;
154 int cfa_offset
= INCOMING_FRAME_SP_OFFSET
, cfa_store_offset
= cfa_offset
;
156 /* If the stack limit is a symbol, we can check it here,
157 before actually allocating the space. */
158 if (current_function_limit_stack
159 && GET_CODE (stack_limit_rtx
) == SYMBOL_REF
)
161 #if defined (MOTOROLA)
162 asm_fprintf (stream
, "\tcmp.l %0I%s+%d,%Rsp\n\ttrapcs\n",
163 XSTR (stack_limit_rtx
, 0), fsize
+ 4);
165 asm_fprintf (stream
, "\tcmpl %0I%s+%d,%Rsp\n\ttrapcs\n",
166 XSTR (stack_limit_rtx
, 0), fsize
+ 4);
170 if (frame_pointer_needed
)
172 if (fsize
== 0 && TARGET_68040
)
174 /* on the 68040, pea + move is faster than link.w 0 */
176 asm_fprintf (stream
, "\tpea (%s)\n\tmove.l %s,%s\n",
177 reg_names
[FRAME_POINTER_REGNUM
], reg_names
[STACK_POINTER_REGNUM
],
178 reg_names
[FRAME_POINTER_REGNUM
]);
180 asm_fprintf (stream
, "\tpea %s@\n\tmovel %s,%s\n",
181 reg_names
[FRAME_POINTER_REGNUM
], reg_names
[STACK_POINTER_REGNUM
],
182 reg_names
[FRAME_POINTER_REGNUM
]);
185 else if (fsize
< 0x8000)
188 asm_fprintf (stream
, "\tlink.w %s,%0I%d\n",
189 reg_names
[FRAME_POINTER_REGNUM
], -fsize
);
191 asm_fprintf (stream
, "\tlink %s,%0I%d\n",
192 reg_names
[FRAME_POINTER_REGNUM
], -fsize
);
195 else if (TARGET_68020
)
198 asm_fprintf (stream
, "\tlink.l %s,%0I%d\n",
199 reg_names
[FRAME_POINTER_REGNUM
], -fsize
);
201 asm_fprintf (stream
, "\tlink %s,%0I%d\n",
202 reg_names
[FRAME_POINTER_REGNUM
], -fsize
);
207 /* Adding negative number is faster on the 68040. */
209 asm_fprintf (stream
, "\tlink.w %s,%0I0\n\tadd.l %0I%d,%Rsp\n",
210 reg_names
[FRAME_POINTER_REGNUM
], -fsize
);
212 asm_fprintf (stream
, "\tlink %s,%0I0\n\taddl %0I%d,%Rsp\n",
213 reg_names
[FRAME_POINTER_REGNUM
], -fsize
);
216 if (dwarf2out_do_frame ())
219 l
= (char *) dwarf2out_cfi_label ();
220 cfa_store_offset
+= 4;
221 cfa_offset
= cfa_store_offset
;
222 dwarf2out_def_cfa (l
, FRAME_POINTER_REGNUM
, cfa_offset
);
223 dwarf2out_reg_save (l
, FRAME_POINTER_REGNUM
, -cfa_store_offset
);
224 cfa_store_offset
+= fsize
;
229 if (fsize
+ 4 < 0x8000)
236 /* asm_fprintf() cannot handle %. */
238 asm_fprintf (stream
, "\tsubq.w %0I%d,%Rsp\n", fsize
+ 4);
240 asm_fprintf (stream
, "\tsubqw %0I%d,%Rsp\n", fsize
+ 4);
245 /* asm_fprintf() cannot handle %. */
247 asm_fprintf (stream
, "\tsubq.l %0I%d,%Rsp\n", fsize
+ 4);
249 asm_fprintf (stream
, "\tsubql %0I%d,%Rsp\n", fsize
+ 4);
253 else if (fsize
+ 4 <= 16 && TARGET_CPU32
)
255 /* On the CPU32 it is faster to use two subqw instructions to
256 subtract a small integer (8 < N <= 16) to a register. */
257 /* asm_fprintf() cannot handle %. */
259 asm_fprintf (stream
, "\tsubq.w %0I8,%Rsp\n\tsubq.w %0I%d,%Rsp\n",
262 asm_fprintf (stream
, "\tsubqw %0I8,%Rsp\n\tsubqw %0I%d,%Rsp\n",
267 #endif /* not NO_ADDSUB_Q */
270 /* Adding negative number is faster on the 68040. */
271 /* asm_fprintf() cannot handle %. */
273 asm_fprintf (stream
, "\tadd.w %0I%d,%Rsp\n", - (fsize
+ 4));
275 asm_fprintf (stream
, "\taddw %0I%d,%Rsp\n", - (fsize
+ 4));
281 asm_fprintf (stream
, "\tlea (%d,%Rsp),%Rsp\n", - (fsize
+ 4));
283 asm_fprintf (stream
, "\tlea %Rsp@(%d),%Rsp\n", - (fsize
+ 4));
289 /* asm_fprintf() cannot handle %. */
291 asm_fprintf (stream
, "\tadd.l %0I%d,%Rsp\n", - (fsize
+ 4));
293 asm_fprintf (stream
, "\taddl %0I%d,%Rsp\n", - (fsize
+ 4));
296 if (dwarf2out_do_frame ())
298 cfa_store_offset
+= fsize
;
299 cfa_offset
= cfa_store_offset
;
300 dwarf2out_def_cfa ("", STACK_POINTER_REGNUM
, cfa_offset
);
303 #ifdef SUPPORT_SUN_FPA
304 for (regno
= 24; regno
< 56; regno
++)
305 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
308 asm_fprintf (stream
, "\tfpmovd %s,-(%Rsp)\n",
311 asm_fprintf (stream
, "\tfpmoved %s,%Rsp@-\n",
314 if (dwarf2out_do_frame ())
316 char *l
= dwarf2out_cfi_label ();
318 cfa_store_offset
+= 8;
319 if (! frame_pointer_needed
)
321 cfa_offset
= cfa_store_offset
;
322 dwarf2out_def_cfa (l
, STACK_POINTER_REGNUM
, cfa_offset
);
324 dwarf2out_reg_save (l
, regno
, -cfa_store_offset
);
330 for (regno
= 16; regno
< 24; regno
++)
331 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
333 mask
|= 1 << (regno
- 16);
336 if ((mask
& 0xff) != 0)
339 asm_fprintf (stream
, "\tfmovm %0I0x%x,-(%Rsp)\n", mask
& 0xff);
341 asm_fprintf (stream
, "\tfmovem %0I0x%x,%Rsp@-\n", mask
& 0xff);
343 if (dwarf2out_do_frame ())
345 char *l
= (char *) dwarf2out_cfi_label ();
348 cfa_store_offset
+= num_saved_regs
* 12;
349 if (! frame_pointer_needed
)
351 cfa_offset
= cfa_store_offset
;
352 dwarf2out_def_cfa (l
, STACK_POINTER_REGNUM
, cfa_offset
);
354 for (regno
= 16, n_regs
= 0; regno
< 24; regno
++)
355 if (mask
& (1 << (regno
- 16)))
356 dwarf2out_reg_save (l
, regno
,
357 -cfa_store_offset
+ n_regs
++ * 12);
363 for (regno
= 0; regno
< 16; regno
++)
364 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
366 mask
|= 1 << (15 - regno
);
369 if (frame_pointer_needed
)
371 mask
&= ~ (1 << (15 - FRAME_POINTER_REGNUM
));
374 if (flag_pic
&& current_function_uses_pic_offset_table
)
376 mask
|= 1 << (15 - PIC_OFFSET_TABLE_REGNUM
);
383 asm_fprintf (stream
, "\ttstl %d(%Rsp)\n", NEED_PROBE
- num_saved_regs
* 4);
385 asm_fprintf (stream
, "\ttst.l %d(%Rsp)\n", NEED_PROBE
- num_saved_regs
* 4);
388 asm_fprintf (stream
, "\ttstl %Rsp@(%d)\n", NEED_PROBE
- num_saved_regs
* 4);
392 /* If the stack limit is not a symbol, check it here.
393 This has the disadvantage that it may be too late... */
394 if (current_function_limit_stack
)
396 if (REG_P (stack_limit_rtx
))
398 #if defined (MOTOROLA)
399 asm_fprintf (stream
, "\tcmp.l %s,%Rsp\n\ttrapcs\n",
400 reg_names
[REGNO (stack_limit_rtx
)]);
402 asm_fprintf (stream
, "\tcmpl %s,%Rsp\n\ttrapcs\n",
403 reg_names
[REGNO (stack_limit_rtx
)]);
406 else if (GET_CODE (stack_limit_rtx
) != SYMBOL_REF
)
407 warning ("stack limit expression is not supported");
410 if (num_saved_regs
<= 2)
412 /* Store each separately in the same order moveml uses.
413 Using two movel instructions instead of a single moveml
414 is about 15% faster for the 68020 and 68030 at no expense
419 /* Undo the work from above. */
420 for (i
= 0; i
< 16; i
++)
425 "\t%Omove.l %s,-(%Rsp)\n",
427 "\tmovel %s,%Rsp@-\n",
430 if (dwarf2out_do_frame ())
432 char *l
= (char *) dwarf2out_cfi_label ();
434 cfa_store_offset
+= 4;
435 if (! frame_pointer_needed
)
437 cfa_offset
= cfa_store_offset
;
438 dwarf2out_def_cfa (l
, STACK_POINTER_REGNUM
, cfa_offset
);
440 dwarf2out_reg_save (l
, 15 - i
, -cfa_store_offset
);
448 /* The coldfire does not support the predecrement form of the
449 movml instruction, so we must adjust the stack pointer and
450 then use the plain address register indirect mode. We also
451 have to invert the register save mask to use the new mode.
453 FIXME: if num_saved_regs was calculated earlier, we could
454 combine the stack pointer adjustment with any adjustment
455 done when the initial stack frame is created. This would
456 save an instruction */
461 for (i
= 0; i
< 16; i
++)
463 newmask
|= (1 << (15-i
));
466 asm_fprintf (stream
, "\tlea (%d,%Rsp),%Rsp\n", -num_saved_regs
*4);
467 asm_fprintf (stream
, "\tmovm.l %0I0x%x,(%Rsp)\n", newmask
);
469 asm_fprintf (stream
, "\tlea %Rsp@(%d),%Rsp\n", -num_saved_regs
*4);
470 asm_fprintf (stream
, "\tmoveml %0I0x%x,%Rsp@\n", newmask
);
476 asm_fprintf (stream
, "\tmovm.l %0I0x%x,-(%Rsp)\n", mask
);
478 asm_fprintf (stream
, "\tmoveml %0I0x%x,%Rsp@-\n", mask
);
481 if (dwarf2out_do_frame ())
483 char *l
= (char *) dwarf2out_cfi_label ();
486 cfa_store_offset
+= num_saved_regs
* 4;
487 if (! frame_pointer_needed
)
489 cfa_offset
= cfa_store_offset
;
490 dwarf2out_def_cfa (l
, STACK_POINTER_REGNUM
, cfa_offset
);
492 for (regno
= 0, n_regs
= 0; regno
< 16; regno
++)
493 if (mask
& (1 << (15 - regno
)))
494 dwarf2out_reg_save (l
, regno
,
495 -cfa_store_offset
+ n_regs
++ * 4);
498 if (flag_pic
&& current_function_uses_pic_offset_table
)
501 asm_fprintf (stream
, "\t%Olea (%Rpc, %U_GLOBAL_OFFSET_TABLE_@GOTPC), %s\n",
502 reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
504 asm_fprintf (stream
, "\tmovel %0I__GLOBAL_OFFSET_TABLE_, %s\n",
505 reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
506 asm_fprintf (stream
, "\tlea %Rpc@(0,%s:l),%s\n",
507 reg_names
[PIC_OFFSET_TABLE_REGNUM
],
508 reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
513 /* Return true if this function's epilogue can be output as RTL. */
520 if (!reload_completed
|| frame_pointer_needed
|| get_frame_size () != 0)
523 /* Copied from output_function_epilogue (). We should probably create a
524 separate layout routine to perform the common work. */
526 for (regno
= 0 ; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
527 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
530 if (flag_pic
&& current_function_uses_pic_offset_table
)
536 /* This function generates the assembly code for function exit,
537 on machines that need it. Args are same as for FUNCTION_PROLOGUE.
539 The function epilogue should not depend on the current stack pointer!
540 It should use the frame pointer only, if there is a frame pointer.
541 This is mandatory because of alloca; we also take advantage of it to
542 omit stack adjustments before returning. */
545 output_function_epilogue (stream
, size
)
550 register int mask
, fmask
;
552 int offset
, foffset
, fpoffset
;
553 extern char call_used_regs
[];
554 int fsize
= (size
+ 3) & -4;
556 rtx insn
= get_last_insn ();
557 int restore_from_sp
= 0;
559 /* If the last insn was a BARRIER, we don't have to write any code. */
560 if (GET_CODE (insn
) == NOTE
)
561 insn
= prev_nonnote_insn (insn
);
562 if (insn
&& GET_CODE (insn
) == BARRIER
)
564 /* Output just a no-op so that debuggers don't get confused
565 about which function the pc is in at this address. */
566 asm_fprintf (stream
, "\tnop\n");
570 #ifdef FUNCTION_BLOCK_PROFILER_EXIT
571 if (profile_block_flag
== 2)
573 FUNCTION_BLOCK_PROFILER_EXIT (stream
);
577 #ifdef FUNCTION_EXTRA_EPILOGUE
578 FUNCTION_EXTRA_EPILOGUE (stream
, size
);
580 nregs
= 0; fmask
= 0; fpoffset
= 0;
581 #ifdef SUPPORT_SUN_FPA
582 for (regno
= 24 ; regno
< 56 ; regno
++)
583 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
585 fpoffset
= nregs
* 8;
590 for (regno
= 16; regno
< 24; regno
++)
591 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
594 fmask
|= 1 << (23 - regno
);
597 foffset
= fpoffset
+ nregs
* 12;
599 if (frame_pointer_needed
)
600 regs_ever_live
[FRAME_POINTER_REGNUM
] = 0;
601 for (regno
= 0; regno
< 16; regno
++)
602 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
607 if (flag_pic
&& current_function_uses_pic_offset_table
)
610 mask
|= 1 << PIC_OFFSET_TABLE_REGNUM
;
612 offset
= foffset
+ nregs
* 4;
613 /* FIXME : leaf_function_p below is too strong.
614 What we really need to know there is if there could be pending
615 stack adjustment needed at that point. */
616 restore_from_sp
= ! frame_pointer_needed
617 || (! current_function_calls_alloca
&& leaf_function_p ());
618 if (offset
+ fsize
>= 0x8000
620 && (mask
|| fmask
|| fpoffset
))
623 asm_fprintf (stream
, "\t%Omove.l %0I%d,%Ra1\n", -fsize
);
625 asm_fprintf (stream
, "\tmovel %0I%d,%Ra1\n", -fsize
);
629 if (TARGET_5200
|| nregs
<= 2)
631 /* Restore each separately in the same order moveml does.
632 Using two movel instructions instead of a single moveml
633 is about 15% faster for the 68020 and 68030 at no expense
638 /* Undo the work from above. */
639 for (i
= 0; i
< 16; i
++)
645 asm_fprintf (stream
, "\t%Omove.l -%d(%s,%Ra1.l),%s\n",
647 reg_names
[FRAME_POINTER_REGNUM
],
650 asm_fprintf (stream
, "\tmovel %s@(-%d,%Ra1:l),%s\n",
651 reg_names
[FRAME_POINTER_REGNUM
],
652 offset
+ fsize
, reg_names
[i
]);
655 else if (restore_from_sp
)
658 asm_fprintf (stream
, "\t%Omove.l (%Rsp)+,%s\n",
661 asm_fprintf (stream
, "\tmovel %Rsp@+,%s\n",
668 asm_fprintf (stream
, "\t%Omove.l -%d(%s),%s\n",
670 reg_names
[FRAME_POINTER_REGNUM
],
673 asm_fprintf (stream
, "\tmovel %s@(-%d),%s\n",
674 reg_names
[FRAME_POINTER_REGNUM
],
675 offset
+ fsize
, reg_names
[i
]);
686 asm_fprintf (stream
, "\tmovm.l -%d(%s,%Ra1.l),%0I0x%x\n",
688 reg_names
[FRAME_POINTER_REGNUM
],
691 asm_fprintf (stream
, "\tmoveml %s@(-%d,%Ra1:l),%0I0x%x\n",
692 reg_names
[FRAME_POINTER_REGNUM
],
693 offset
+ fsize
, mask
);
696 else if (restore_from_sp
)
699 asm_fprintf (stream
, "\tmovm.l (%Rsp)+,%0I0x%x\n", mask
);
701 asm_fprintf (stream
, "\tmoveml %Rsp@+,%0I0x%x\n", mask
);
707 asm_fprintf (stream
, "\tmovm.l -%d(%s),%0I0x%x\n",
709 reg_names
[FRAME_POINTER_REGNUM
],
712 asm_fprintf (stream
, "\tmoveml %s@(-%d),%0I0x%x\n",
713 reg_names
[FRAME_POINTER_REGNUM
],
714 offset
+ fsize
, mask
);
723 asm_fprintf (stream
, "\tfmovm -%d(%s,%Ra1.l),%0I0x%x\n",
725 reg_names
[FRAME_POINTER_REGNUM
],
728 asm_fprintf (stream
, "\tfmovem %s@(-%d,%Ra1:l),%0I0x%x\n",
729 reg_names
[FRAME_POINTER_REGNUM
],
730 foffset
+ fsize
, fmask
);
733 else if (restore_from_sp
)
736 asm_fprintf (stream
, "\tfmovm (%Rsp)+,%0I0x%x\n", fmask
);
738 asm_fprintf (stream
, "\tfmovem %Rsp@+,%0I0x%x\n", fmask
);
744 asm_fprintf (stream
, "\tfmovm -%d(%s),%0I0x%x\n",
746 reg_names
[FRAME_POINTER_REGNUM
],
749 asm_fprintf (stream
, "\tfmovem %s@(-%d),%0I0x%x\n",
750 reg_names
[FRAME_POINTER_REGNUM
],
751 foffset
+ fsize
, fmask
);
756 for (regno
= 55; regno
>= 24; regno
--)
757 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
762 asm_fprintf (stream
, "\tfpmovd -%d(%s,%Ra1.l), %s\n",
764 reg_names
[FRAME_POINTER_REGNUM
],
767 asm_fprintf (stream
, "\tfpmoved %s@(-%d,%Ra1:l), %s\n",
768 reg_names
[FRAME_POINTER_REGNUM
],
769 fpoffset
+ fsize
, reg_names
[regno
]);
772 else if (restore_from_sp
)
775 asm_fprintf (stream
, "\tfpmovd (%Rsp)+,%s\n",
778 asm_fprintf (stream
, "\tfpmoved %Rsp@+, %s\n",
785 asm_fprintf (stream
, "\tfpmovd -%d(%s), %s\n",
787 reg_names
[FRAME_POINTER_REGNUM
],
790 asm_fprintf (stream
, "\tfpmoved %s@(-%d), %s\n",
791 reg_names
[FRAME_POINTER_REGNUM
],
792 fpoffset
+ fsize
, reg_names
[regno
]);
797 if (frame_pointer_needed
)
798 fprintf (stream
, "\tunlk %s\n",
799 reg_names
[FRAME_POINTER_REGNUM
]);
808 asm_fprintf (stream
, "\taddq.w %0I%d,%Rsp\n", fsize
+ 4);
810 asm_fprintf (stream
, "\taddqw %0I%d,%Rsp\n", fsize
+ 4);
816 asm_fprintf (stream
, "\taddq.l %0I%d,%Rsp\n", fsize
+ 4);
818 asm_fprintf (stream
, "\taddql %0I%d,%Rsp\n", fsize
+ 4);
822 else if (fsize
+ 4 <= 16 && TARGET_CPU32
)
824 /* On the CPU32 it is faster to use two addqw instructions to
825 add a small integer (8 < N <= 16) to a register. */
826 /* asm_fprintf() cannot handle %. */
828 asm_fprintf (stream
, "\taddq.w %0I8,%Rsp\n\taddq.w %0I%d,%Rsp\n",
831 asm_fprintf (stream
, "\taddqw %0I8,%Rsp\n\taddqw %0I%d,%Rsp\n",
836 #endif /* not NO_ADDSUB_Q */
837 if (fsize
+ 4 < 0x8000)
841 /* asm_fprintf() cannot handle %. */
843 asm_fprintf (stream
, "\tadd.w %0I%d,%Rsp\n", fsize
+ 4);
845 asm_fprintf (stream
, "\taddw %0I%d,%Rsp\n", fsize
+ 4);
851 asm_fprintf (stream
, "\tlea (%d,%Rsp),%Rsp\n", fsize
+ 4);
853 asm_fprintf (stream
, "\tlea %Rsp@(%d),%Rsp\n", fsize
+ 4);
859 /* asm_fprintf() cannot handle %. */
861 asm_fprintf (stream
, "\tadd.l %0I%d,%Rsp\n", fsize
+ 4);
863 asm_fprintf (stream
, "\taddl %0I%d,%Rsp\n", fsize
+ 4);
867 if (current_function_pops_args
)
868 asm_fprintf (stream
, "\trtd %0I%d\n", current_function_pops_args
);
870 fprintf (stream
, "\trts\n");
873 /* Similar to general_operand, but exclude stack_pointer_rtx. */
876 not_sp_operand (op
, mode
)
878 enum machine_mode mode
;
880 return op
!= stack_pointer_rtx
&& general_operand (op
, mode
);
883 /* Return TRUE if X is a valid comparison operator for the dbcc
886 Note it rejects floating point comparison operators.
887 (In the future we could use Fdbcc).
889 It also rejects some comparisons when CC_NO_OVERFLOW is set. */
892 valid_dbcc_comparison_p (x
, mode
)
894 enum machine_mode mode ATTRIBUTE_UNUSED
;
896 switch (GET_CODE (x
))
898 case EQ
: case NE
: case GTU
: case LTU
:
902 /* Reject some when CC_NO_OVERFLOW is set. This may be over
904 case GT
: case LT
: case GE
: case LE
:
905 return ! (cc_prev_status
.flags
& CC_NO_OVERFLOW
);
911 /* Return non-zero if flags are currently in the 68881 flag register. */
915 /* We could add support for these in the future */
916 return cc_status
.flags
& CC_IN_68881
;
919 /* Output a dbCC; jCC sequence. Note we do not handle the
920 floating point version of this sequence (Fdbcc). We also
921 do not handle alternative conditions when CC_NO_OVERFLOW is
922 set. It is assumed that valid_dbcc_comparison_p and flags_in_68881 will
923 kick those out before we get here. */
926 output_dbcc_and_branch (operands
)
929 switch (GET_CODE (operands
[3]))
933 output_asm_insn ("dbeq %0,%l1\n\tjbeq %l2", operands
);
935 output_asm_insn ("dbeq %0,%l1\n\tjeq %l2", operands
);
941 output_asm_insn ("dbne %0,%l1\n\tjbne %l2", operands
);
943 output_asm_insn ("dbne %0,%l1\n\tjne %l2", operands
);
949 output_asm_insn ("dbgt %0,%l1\n\tjbgt %l2", operands
);
951 output_asm_insn ("dbgt %0,%l1\n\tjgt %l2", operands
);
957 output_asm_insn ("dbhi %0,%l1\n\tjbhi %l2", operands
);
959 output_asm_insn ("dbhi %0,%l1\n\tjhi %l2", operands
);
965 output_asm_insn ("dblt %0,%l1\n\tjblt %l2", operands
);
967 output_asm_insn ("dblt %0,%l1\n\tjlt %l2", operands
);
973 output_asm_insn ("dbcs %0,%l1\n\tjbcs %l2", operands
);
975 output_asm_insn ("dbcs %0,%l1\n\tjcs %l2", operands
);
981 output_asm_insn ("dbge %0,%l1\n\tjbge %l2", operands
);
983 output_asm_insn ("dbge %0,%l1\n\tjge %l2", operands
);
989 output_asm_insn ("dbcc %0,%l1\n\tjbcc %l2", operands
);
991 output_asm_insn ("dbcc %0,%l1\n\tjcc %l2", operands
);
997 output_asm_insn ("dble %0,%l1\n\tjble %l2", operands
);
999 output_asm_insn ("dble %0,%l1\n\tjle %l2", operands
);
1005 output_asm_insn ("dbls %0,%l1\n\tjbls %l2", operands
);
1007 output_asm_insn ("dbls %0,%l1\n\tjls %l2", operands
);
1015 /* If the decrement is to be done in SImode, then we have
1016 to compensate for the fact that dbcc decrements in HImode. */
1017 switch (GET_MODE (operands
[0]))
1021 output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjbpl %l1", operands
);
1023 output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjpl %l1", operands
);
1036 output_scc_di(op
, operand1
, operand2
, dest
)
1043 enum rtx_code op_code
= GET_CODE (op
);
1045 /* This does not produce a usefull cc. */
1048 /* The m68k cmp.l instruction requires operand1 to be a reg as used
1049 below. Swap the operands and change the op if these requirements
1050 are not fulfilled. */
1051 if (GET_CODE (operand2
) == REG
&& GET_CODE (operand1
) != REG
)
1055 operand1
= operand2
;
1057 op_code
= swap_condition (op_code
);
1059 loperands
[0] = operand1
;
1060 if (GET_CODE (operand1
) == REG
)
1061 loperands
[1] = gen_rtx_REG (SImode
, REGNO (operand1
) + 1);
1063 loperands
[1] = adj_offsettable_operand (operand1
, 4);
1064 if (operand2
!= const0_rtx
)
1066 loperands
[2] = operand2
;
1067 if (GET_CODE (operand2
) == REG
)
1068 loperands
[3] = gen_rtx_REG (SImode
, REGNO (operand2
) + 1);
1070 loperands
[3] = adj_offsettable_operand (operand2
, 4);
1072 loperands
[4] = gen_label_rtx();
1073 if (operand2
!= const0_rtx
)
1076 #ifdef SGS_CMP_ORDER
1077 output_asm_insn ("cmp%.l %0,%2\n\tjbne %l4\n\tcmp%.l %1,%3", loperands
);
1079 output_asm_insn ("cmp%.l %2,%0\n\tjbne %l4\n\tcmp%.l %3,%1", loperands
);
1082 #ifdef SGS_CMP_ORDER
1083 output_asm_insn ("cmp%.l %0,%2\n\tjne %l4\n\tcmp%.l %1,%3", loperands
);
1085 output_asm_insn ("cmp%.l %2,%0\n\tjne %l4\n\tcmp%.l %3,%1", loperands
);
1091 if (TARGET_68020
|| TARGET_5200
|| ! ADDRESS_REG_P (loperands
[0]))
1092 output_asm_insn ("tst%.l %0", loperands
);
1095 #ifdef SGS_CMP_ORDER
1096 output_asm_insn ("cmp%.w %0,%#0", loperands
);
1098 output_asm_insn ("cmp%.w %#0,%0", loperands
);
1103 output_asm_insn ("jbne %l4", loperands
);
1105 output_asm_insn ("jne %l4", loperands
);
1108 if (TARGET_68020
|| TARGET_5200
|| ! ADDRESS_REG_P (loperands
[1]))
1109 output_asm_insn ("tst%.l %1", loperands
);
1112 #ifdef SGS_CMP_ORDER
1113 output_asm_insn ("cmp%.w %1,%#0", loperands
);
1115 output_asm_insn ("cmp%.w %#0,%1", loperands
);
1120 loperands
[5] = dest
;
1125 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1126 CODE_LABEL_NUMBER (loperands
[4]));
1127 output_asm_insn ("seq %5", loperands
);
1131 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1132 CODE_LABEL_NUMBER (loperands
[4]));
1133 output_asm_insn ("sne %5", loperands
);
1137 loperands
[6] = gen_label_rtx();
1139 output_asm_insn ("shi %5\n\tjbra %l6", loperands
);
1141 output_asm_insn ("shi %5\n\tjra %l6", loperands
);
1143 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1144 CODE_LABEL_NUMBER (loperands
[4]));
1145 output_asm_insn ("sgt %5", loperands
);
1146 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1147 CODE_LABEL_NUMBER (loperands
[6]));
1151 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1152 CODE_LABEL_NUMBER (loperands
[4]));
1153 output_asm_insn ("shi %5", loperands
);
1157 loperands
[6] = gen_label_rtx();
1159 output_asm_insn ("scs %5\n\tjbra %l6", loperands
);
1161 output_asm_insn ("scs %5\n\tjra %l6", loperands
);
1163 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1164 CODE_LABEL_NUMBER (loperands
[4]));
1165 output_asm_insn ("slt %5", loperands
);
1166 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1167 CODE_LABEL_NUMBER (loperands
[6]));
1171 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1172 CODE_LABEL_NUMBER (loperands
[4]));
1173 output_asm_insn ("scs %5", loperands
);
1177 loperands
[6] = gen_label_rtx();
1179 output_asm_insn ("scc %5\n\tjbra %l6", loperands
);
1181 output_asm_insn ("scc %5\n\tjra %l6", loperands
);
1183 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1184 CODE_LABEL_NUMBER (loperands
[4]));
1185 output_asm_insn ("sge %5", loperands
);
1186 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1187 CODE_LABEL_NUMBER (loperands
[6]));
1191 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1192 CODE_LABEL_NUMBER (loperands
[4]));
1193 output_asm_insn ("scc %5", loperands
);
1197 loperands
[6] = gen_label_rtx();
1199 output_asm_insn ("sls %5\n\tjbra %l6", loperands
);
1201 output_asm_insn ("sls %5\n\tjra %l6", loperands
);
1203 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1204 CODE_LABEL_NUMBER (loperands
[4]));
1205 output_asm_insn ("sle %5", loperands
);
1206 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1207 CODE_LABEL_NUMBER (loperands
[6]));
1211 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
1212 CODE_LABEL_NUMBER (loperands
[4]));
1213 output_asm_insn ("sls %5", loperands
);
1223 output_btst (operands
, countop
, dataop
, insn
, signpos
)
1225 rtx countop
, dataop
;
1229 operands
[0] = countop
;
1230 operands
[1] = dataop
;
1232 if (GET_CODE (countop
) == CONST_INT
)
1234 register int count
= INTVAL (countop
);
1235 /* If COUNT is bigger than size of storage unit in use,
1236 advance to the containing unit of same size. */
1237 if (count
> signpos
)
1239 int offset
= (count
& ~signpos
) / 8;
1240 count
= count
& signpos
;
1241 operands
[1] = dataop
= adj_offsettable_operand (dataop
, offset
);
1243 if (count
== signpos
)
1244 cc_status
.flags
= CC_NOT_POSITIVE
| CC_Z_IN_NOT_N
;
1246 cc_status
.flags
= CC_NOT_NEGATIVE
| CC_Z_IN_NOT_N
;
1248 /* These three statements used to use next_insns_test_no...
1249 but it appears that this should do the same job. */
1251 && next_insn_tests_no_inequality (insn
))
1254 && next_insn_tests_no_inequality (insn
))
1257 && next_insn_tests_no_inequality (insn
))
1260 cc_status
.flags
= CC_NOT_NEGATIVE
;
1262 return "btst %0,%1";
1265 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
1266 reference and a constant. */
1269 symbolic_operand (op
, mode
)
1271 enum machine_mode mode ATTRIBUTE_UNUSED
;
1273 switch (GET_CODE (op
))
1281 return ((GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
1282 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
)
1283 && GET_CODE (XEXP (op
, 1)) == CONST_INT
);
1285 #if 0 /* Deleted, with corresponding change in m68k.h,
1286 so as to fit the specs. No CONST_DOUBLE is ever symbolic. */
1288 return GET_MODE (op
) == mode
;
1296 /* Check for sign_extend or zero_extend. Used for bit-count operands. */
1299 extend_operator(x
, mode
)
1301 enum machine_mode mode
;
1303 if (mode
!= VOIDmode
&& GET_MODE(x
) != mode
)
1305 switch (GET_CODE(x
))
1316 /* Legitimize PIC addresses. If the address is already
1317 position-independent, we return ORIG. Newly generated
1318 position-independent addresses go to REG. If we need more
1319 than one register, we lose.
1321 An address is legitimized by making an indirect reference
1322 through the Global Offset Table with the name of the symbol
1325 The assembler and linker are responsible for placing the
1326 address of the symbol in the GOT. The function prologue
1327 is responsible for initializing a5 to the starting address
1330 The assembler is also responsible for translating a symbol name
1331 into a constant displacement from the start of the GOT.
1333 A quick example may make things a little clearer:
1335 When not generating PIC code to store the value 12345 into _foo
1336 we would generate the following code:
1340 When generating PIC two transformations are made. First, the compiler
1341 loads the address of foo into a register. So the first transformation makes:
1346 The code in movsi will intercept the lea instruction and call this
1347 routine which will transform the instructions into:
1349 movel a5@(_foo:w), a0
1353 That (in a nutshell) is how *all* symbol and label references are
1357 legitimize_pic_address (orig
, mode
, reg
)
1359 enum machine_mode mode ATTRIBUTE_UNUSED
;
1363 /* First handle a simple SYMBOL_REF or LABEL_REF */
1364 if (GET_CODE (orig
) == SYMBOL_REF
|| GET_CODE (orig
) == LABEL_REF
)
1369 pic_ref
= gen_rtx_MEM (Pmode
,
1370 gen_rtx_PLUS (Pmode
,
1371 pic_offset_table_rtx
, orig
));
1372 current_function_uses_pic_offset_table
= 1;
1373 RTX_UNCHANGING_P (pic_ref
) = 1;
1374 emit_move_insn (reg
, pic_ref
);
1377 else if (GET_CODE (orig
) == CONST
)
1381 /* Make sure this is CONST has not already been legitimized */
1382 if (GET_CODE (XEXP (orig
, 0)) == PLUS
1383 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
1389 /* legitimize both operands of the PLUS */
1390 if (GET_CODE (XEXP (orig
, 0)) == PLUS
)
1392 base
= legitimize_pic_address (XEXP (XEXP (orig
, 0), 0), Pmode
, reg
);
1393 orig
= legitimize_pic_address (XEXP (XEXP (orig
, 0), 1), Pmode
,
1394 base
== reg
? 0 : reg
);
1398 if (GET_CODE (orig
) == CONST_INT
)
1399 return plus_constant_for_output (base
, INTVAL (orig
));
1400 pic_ref
= gen_rtx_PLUS (Pmode
, base
, orig
);
1401 /* Likewise, should we set special REG_NOTEs here? */
1407 typedef enum { MOVL
, SWAP
, NEGW
, NOTW
, NOTB
, MOVQ
} CONST_METHOD
;
1409 static CONST_METHOD const_method
PARAMS ((rtx
));
1411 #define USE_MOVQ(i) ((unsigned)((i) + 128) <= 255)
1414 const_method (constant
)
1420 i
= INTVAL (constant
);
1424 /* The Coldfire doesn't have byte or word operations. */
1425 /* FIXME: This may not be useful for the m68060 either */
1428 /* if -256 < N < 256 but N is not in range for a moveq
1429 N^ff will be, so use moveq #N^ff, dreg; not.b dreg. */
1430 if (USE_MOVQ (i
^ 0xff))
1432 /* Likewise, try with not.w */
1433 if (USE_MOVQ (i
^ 0xffff))
1435 /* This is the only value where neg.w is useful */
1438 /* Try also with swap */
1440 if (USE_MOVQ ((u
>> 16) | (u
<< 16)))
1443 /* Otherwise, use move.l */
1448 const_int_cost (constant
)
1451 switch (const_method (constant
))
1454 /* Constants between -128 and 127 are cheap due to moveq */
1460 /* Constants easily generated by moveq + not.b/not.w/neg.w/swap */
1470 output_move_const_into_data_reg (operands
)
1475 i
= INTVAL (operands
[1]);
1476 switch (const_method (operands
[1]))
1479 #if defined (MOTOROLA) && !defined (CRDS)
1480 return "moveq%.l %1,%0";
1482 return "moveq %1,%0";
1485 operands
[1] = GEN_INT (i
^ 0xff);
1486 #if defined (MOTOROLA) && !defined (CRDS)
1487 return "moveq%.l %1,%0\n\tnot%.b %0";
1489 return "moveq %1,%0\n\tnot%.b %0";
1492 operands
[1] = GEN_INT (i
^ 0xffff);
1493 #if defined (MOTOROLA) && !defined (CRDS)
1494 return "moveq%.l %1,%0\n\tnot%.w %0";
1496 return "moveq %1,%0\n\tnot%.w %0";
1499 #if defined (MOTOROLA) && !defined (CRDS)
1500 return "moveq%.l %#-128,%0\n\tneg%.w %0";
1502 return "moveq %#-128,%0\n\tneg%.w %0";
1508 operands
[1] = GEN_INT ((u
<< 16) | (u
>> 16));
1509 #if defined (MOTOROLA) && !defined (CRDS)
1510 return "moveq%.l %1,%0\n\tswap %0";
1512 return "moveq %1,%0\n\tswap %0";
1516 return "move%.l %1,%0";
1523 output_move_simode_const (operands
)
1526 if (operands
[1] == const0_rtx
1527 && (DATA_REG_P (operands
[0])
1528 || GET_CODE (operands
[0]) == MEM
)
1529 /* clr insns on 68000 read before writing.
1530 This isn't so on the 68010, but we have no TARGET_68010. */
1531 && ((TARGET_68020
|| TARGET_5200
)
1532 || !(GET_CODE (operands
[0]) == MEM
1533 && MEM_VOLATILE_P (operands
[0]))))
1535 else if (operands
[1] == const0_rtx
1536 && ADDRESS_REG_P (operands
[0]))
1537 return "sub%.l %0,%0";
1538 else if (DATA_REG_P (operands
[0]))
1539 return output_move_const_into_data_reg (operands
);
1540 else if (ADDRESS_REG_P (operands
[0])
1541 && INTVAL (operands
[1]) < 0x8000
1542 && INTVAL (operands
[1]) >= -0x8000)
1543 return "move%.w %1,%0";
1544 else if (GET_CODE (operands
[0]) == MEM
1545 && GET_CODE (XEXP (operands
[0], 0)) == PRE_DEC
1546 && REGNO (XEXP (XEXP (operands
[0], 0), 0)) == STACK_POINTER_REGNUM
1547 && INTVAL (operands
[1]) < 0x8000
1548 && INTVAL (operands
[1]) >= -0x8000)
1550 return "move%.l %1,%0";
1554 output_move_simode (operands
)
1557 if (GET_CODE (operands
[1]) == CONST_INT
)
1558 return output_move_simode_const (operands
);
1559 else if ((GET_CODE (operands
[1]) == SYMBOL_REF
1560 || GET_CODE (operands
[1]) == CONST
)
1561 && push_operand (operands
[0], SImode
))
1563 else if ((GET_CODE (operands
[1]) == SYMBOL_REF
1564 || GET_CODE (operands
[1]) == CONST
)
1565 && ADDRESS_REG_P (operands
[0]))
1566 return "lea %a1,%0";
1567 return "move%.l %1,%0";
1571 output_move_himode (operands
)
1574 if (GET_CODE (operands
[1]) == CONST_INT
)
1576 if (operands
[1] == const0_rtx
1577 && (DATA_REG_P (operands
[0])
1578 || GET_CODE (operands
[0]) == MEM
)
1579 /* clr insns on 68000 read before writing.
1580 This isn't so on the 68010, but we have no TARGET_68010. */
1581 && ((TARGET_68020
|| TARGET_5200
)
1582 || !(GET_CODE (operands
[0]) == MEM
1583 && MEM_VOLATILE_P (operands
[0]))))
1585 else if (operands
[1] == const0_rtx
1586 && ADDRESS_REG_P (operands
[0]))
1587 return "sub%.l %0,%0";
1588 else if (DATA_REG_P (operands
[0])
1589 && INTVAL (operands
[1]) < 128
1590 && INTVAL (operands
[1]) >= -128)
1592 #if defined(MOTOROLA) && !defined(CRDS)
1593 return "moveq%.l %1,%0";
1595 return "moveq %1,%0";
1598 else if (INTVAL (operands
[1]) < 0x8000
1599 && INTVAL (operands
[1]) >= -0x8000)
1600 return "move%.w %1,%0";
1602 else if (CONSTANT_P (operands
[1]))
1603 return "move%.l %1,%0";
1605 /* Recognize the insn before a tablejump, one that refers
1606 to a table of offsets. Such an insn will need to refer
1607 to a label on the insn. So output one. Use the label-number
1608 of the table of offsets to generate this label. This code,
1609 and similar code below, assumes that there will be at most one
1610 reference to each table. */
1611 if (GET_CODE (operands
[1]) == MEM
1612 && GET_CODE (XEXP (operands
[1], 0)) == PLUS
1613 && GET_CODE (XEXP (XEXP (operands
[1], 0), 1)) == LABEL_REF
1614 && GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) != PLUS
)
1616 rtx labelref
= XEXP (XEXP (operands
[1], 0), 1);
1617 #if defined (MOTOROLA) && !defined (SGS_SWITCH_TABLES)
1619 asm_fprintf (asm_out_file
, "\tset %LLI%d,.+2\n",
1620 CODE_LABEL_NUMBER (XEXP (labelref
, 0)));
1622 asm_fprintf (asm_out_file
, "\t.set %LLI%d,.+2\n",
1623 CODE_LABEL_NUMBER (XEXP (labelref
, 0)));
1624 #endif /* not SGS */
1625 #else /* SGS_SWITCH_TABLES or not MOTOROLA */
1626 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "LI",
1627 CODE_LABEL_NUMBER (XEXP (labelref
, 0)));
1628 #ifdef SGS_SWITCH_TABLES
1629 /* Set flag saying we need to define the symbol
1630 LD%n (with value L%n-LI%n) at the end of the switch table. */
1631 switch_table_difference_label_flag
= 1;
1632 #endif /* SGS_SWITCH_TABLES */
1633 #endif /* SGS_SWITCH_TABLES or not MOTOROLA */
1635 #endif /* SGS_NO_LI */
1636 return "move%.w %1,%0";
1640 output_move_qimode (operands
)
1645 /* This is probably useless, since it loses for pushing a struct
1646 of several bytes a byte at a time. */
1647 /* 68k family always modifies the stack pointer by at least 2, even for
1648 byte pushes. The 5200 (coldfire) does not do this. */
1649 if (GET_CODE (operands
[0]) == MEM
1650 && GET_CODE (XEXP (operands
[0], 0)) == PRE_DEC
1651 && XEXP (XEXP (operands
[0], 0), 0) == stack_pointer_rtx
1652 && ! ADDRESS_REG_P (operands
[1])
1655 xoperands
[1] = operands
[1];
1657 = gen_rtx_MEM (QImode
,
1658 gen_rtx_PLUS (VOIDmode
, stack_pointer_rtx
, const1_rtx
));
1659 /* Just pushing a byte puts it in the high byte of the halfword. */
1660 /* We must put it in the low-order, high-numbered byte. */
1661 if (!reg_mentioned_p (stack_pointer_rtx
, operands
[1]))
1663 xoperands
[3] = stack_pointer_rtx
;
1665 output_asm_insn ("subq%.l %#2,%3\n\tmove%.b %1,%2", xoperands
);
1667 output_asm_insn ("sub%.l %#2,%3\n\tmove%.b %1,%2", xoperands
);
1671 output_asm_insn ("move%.b %1,%-\n\tmove%.b %@,%2", xoperands
);
1675 /* clr and st insns on 68000 read before writing.
1676 This isn't so on the 68010, but we have no TARGET_68010. */
1677 if (!ADDRESS_REG_P (operands
[0])
1678 && ((TARGET_68020
|| TARGET_5200
)
1679 || !(GET_CODE (operands
[0]) == MEM
&& MEM_VOLATILE_P (operands
[0]))))
1681 if (operands
[1] == const0_rtx
)
1683 if ((!TARGET_5200
|| DATA_REG_P (operands
[0]))
1684 && GET_CODE (operands
[1]) == CONST_INT
1685 && (INTVAL (operands
[1]) & 255) == 255)
1691 if (GET_CODE (operands
[1]) == CONST_INT
1692 && DATA_REG_P (operands
[0])
1693 && INTVAL (operands
[1]) < 128
1694 && INTVAL (operands
[1]) >= -128)
1696 #if defined(MOTOROLA) && !defined(CRDS)
1697 return "moveq%.l %1,%0";
1699 return "moveq %1,%0";
1702 if (operands
[1] == const0_rtx
&& ADDRESS_REG_P (operands
[0]))
1703 return "sub%.l %0,%0";
1704 if (GET_CODE (operands
[1]) != CONST_INT
&& CONSTANT_P (operands
[1]))
1705 return "move%.l %1,%0";
1706 /* 68k family (including the 5200 coldfire) does not support byte moves to
1707 from address registers. */
1708 if (ADDRESS_REG_P (operands
[0]) || ADDRESS_REG_P (operands
[1]))
1709 return "move%.w %1,%0";
1710 return "move%.b %1,%0";
1714 output_move_stricthi (operands
)
1717 if (operands
[1] == const0_rtx
1718 /* clr insns on 68000 read before writing.
1719 This isn't so on the 68010, but we have no TARGET_68010. */
1720 && ((TARGET_68020
|| TARGET_5200
)
1721 || !(GET_CODE (operands
[0]) == MEM
&& MEM_VOLATILE_P (operands
[0]))))
1723 return "move%.w %1,%0";
1727 output_move_strictqi (operands
)
1730 if (operands
[1] == const0_rtx
1731 /* clr insns on 68000 read before writing.
1732 This isn't so on the 68010, but we have no TARGET_68010. */
1733 && ((TARGET_68020
|| TARGET_5200
)
1734 || !(GET_CODE (operands
[0]) == MEM
&& MEM_VOLATILE_P (operands
[0]))))
1736 return "move%.b %1,%0";
1739 /* Return the best assembler insn template
1740 for moving operands[1] into operands[0] as a fullword. */
1743 singlemove_string (operands
)
1746 #ifdef SUPPORT_SUN_FPA
1747 if (FPA_REG_P (operands
[0]) || FPA_REG_P (operands
[1]))
1748 return "fpmoves %1,%0";
1750 if (GET_CODE (operands
[1]) == CONST_INT
)
1751 return output_move_simode_const (operands
);
1752 return "move%.l %1,%0";
1756 /* Output assembler code to perform a doubleword move insn
1757 with operands OPERANDS. */
1760 output_move_double (operands
)
1765 REGOP
, OFFSOP
, MEMOP
, PUSHOP
, POPOP
, CNSTOP
, RNDOP
1770 rtx addreg0
= 0, addreg1
= 0;
1771 int dest_overlapped_low
= 0;
1772 int size
= GET_MODE_SIZE (GET_MODE (operands
[0]));
1777 /* First classify both operands. */
1779 if (REG_P (operands
[0]))
1781 else if (offsettable_memref_p (operands
[0]))
1783 else if (GET_CODE (XEXP (operands
[0], 0)) == POST_INC
)
1785 else if (GET_CODE (XEXP (operands
[0], 0)) == PRE_DEC
)
1787 else if (GET_CODE (operands
[0]) == MEM
)
1792 if (REG_P (operands
[1]))
1794 else if (CONSTANT_P (operands
[1]))
1796 else if (offsettable_memref_p (operands
[1]))
1798 else if (GET_CODE (XEXP (operands
[1], 0)) == POST_INC
)
1800 else if (GET_CODE (XEXP (operands
[1], 0)) == PRE_DEC
)
1802 else if (GET_CODE (operands
[1]) == MEM
)
1807 /* Check for the cases that the operand constraints are not
1808 supposed to allow to happen. Abort if we get one,
1809 because generating code for these cases is painful. */
1811 if (optype0
== RNDOP
|| optype1
== RNDOP
)
1814 /* If one operand is decrementing and one is incrementing
1815 decrement the former register explicitly
1816 and change that operand into ordinary indexing. */
1818 if (optype0
== PUSHOP
&& optype1
== POPOP
)
1820 operands
[0] = XEXP (XEXP (operands
[0], 0), 0);
1822 output_asm_insn ("sub%.l %#12,%0", operands
);
1824 output_asm_insn ("subq%.l %#8,%0", operands
);
1825 if (GET_MODE (operands
[1]) == XFmode
)
1826 operands
[0] = gen_rtx_MEM (XFmode
, operands
[0]);
1827 else if (GET_MODE (operands
[0]) == DFmode
)
1828 operands
[0] = gen_rtx_MEM (DFmode
, operands
[0]);
1830 operands
[0] = gen_rtx_MEM (DImode
, operands
[0]);
1833 if (optype0
== POPOP
&& optype1
== PUSHOP
)
1835 operands
[1] = XEXP (XEXP (operands
[1], 0), 0);
1837 output_asm_insn ("sub%.l %#12,%1", operands
);
1839 output_asm_insn ("subq%.l %#8,%1", operands
);
1840 if (GET_MODE (operands
[1]) == XFmode
)
1841 operands
[1] = gen_rtx_MEM (XFmode
, operands
[1]);
1842 else if (GET_MODE (operands
[1]) == DFmode
)
1843 operands
[1] = gen_rtx_MEM (DFmode
, operands
[1]);
1845 operands
[1] = gen_rtx_MEM (DImode
, operands
[1]);
1849 /* If an operand is an unoffsettable memory ref, find a register
1850 we can increment temporarily to make it refer to the second word. */
1852 if (optype0
== MEMOP
)
1853 addreg0
= find_addr_reg (XEXP (operands
[0], 0));
1855 if (optype1
== MEMOP
)
1856 addreg1
= find_addr_reg (XEXP (operands
[1], 0));
1858 /* Ok, we can do one word at a time.
1859 Normally we do the low-numbered word first,
1860 but if either operand is autodecrementing then we
1861 do the high-numbered word first.
1863 In either case, set up in LATEHALF the operands to use
1864 for the high-numbered word and in some cases alter the
1865 operands in OPERANDS to be suitable for the low-numbered word. */
1869 if (optype0
== REGOP
)
1871 latehalf
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 2);
1872 middlehalf
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 1);
1874 else if (optype0
== OFFSOP
)
1876 middlehalf
[0] = adj_offsettable_operand (operands
[0], 4);
1877 latehalf
[0] = adj_offsettable_operand (operands
[0], size
- 4);
1881 middlehalf
[0] = operands
[0];
1882 latehalf
[0] = operands
[0];
1885 if (optype1
== REGOP
)
1887 latehalf
[1] = gen_rtx_REG (SImode
, REGNO (operands
[1]) + 2);
1888 middlehalf
[1] = gen_rtx_REG (SImode
, REGNO (operands
[1]) + 1);
1890 else if (optype1
== OFFSOP
)
1892 middlehalf
[1] = adj_offsettable_operand (operands
[1], 4);
1893 latehalf
[1] = adj_offsettable_operand (operands
[1], size
- 4);
1895 else if (optype1
== CNSTOP
)
1897 if (GET_CODE (operands
[1]) == CONST_DOUBLE
)
1902 REAL_VALUE_FROM_CONST_DOUBLE (r
, operands
[1]);
1903 REAL_VALUE_TO_TARGET_LONG_DOUBLE (r
, l
);
1904 operands
[1] = GEN_INT (l
[0]);
1905 middlehalf
[1] = GEN_INT (l
[1]);
1906 latehalf
[1] = GEN_INT (l
[2]);
1908 else if (CONSTANT_P (operands
[1]))
1910 /* actually, no non-CONST_DOUBLE constant should ever
1913 if (GET_CODE (operands
[1]) == CONST_INT
&& INTVAL (operands
[1]) < 0)
1914 latehalf
[1] = constm1_rtx
;
1916 latehalf
[1] = const0_rtx
;
1921 middlehalf
[1] = operands
[1];
1922 latehalf
[1] = operands
[1];
1926 /* size is not 12: */
1928 if (optype0
== REGOP
)
1929 latehalf
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 1);
1930 else if (optype0
== OFFSOP
)
1931 latehalf
[0] = adj_offsettable_operand (operands
[0], size
- 4);
1933 latehalf
[0] = operands
[0];
1935 if (optype1
== REGOP
)
1936 latehalf
[1] = gen_rtx_REG (SImode
, REGNO (operands
[1]) + 1);
1937 else if (optype1
== OFFSOP
)
1938 latehalf
[1] = adj_offsettable_operand (operands
[1], size
- 4);
1939 else if (optype1
== CNSTOP
)
1940 split_double (operands
[1], &operands
[1], &latehalf
[1]);
1942 latehalf
[1] = operands
[1];
1945 /* If insn is effectively movd N(sp),-(sp) then we will do the
1946 high word first. We should use the adjusted operand 1 (which is N+4(sp))
1947 for the low word as well, to compensate for the first decrement of sp. */
1948 if (optype0
== PUSHOP
1949 && REGNO (XEXP (XEXP (operands
[0], 0), 0)) == STACK_POINTER_REGNUM
1950 && reg_overlap_mentioned_p (stack_pointer_rtx
, operands
[1]))
1951 operands
[1] = middlehalf
[1] = latehalf
[1];
1953 /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)),
1954 if the upper part of reg N does not appear in the MEM, arrange to
1955 emit the move late-half first. Otherwise, compute the MEM address
1956 into the upper part of N and use that as a pointer to the memory
1958 if (optype0
== REGOP
1959 && (optype1
== OFFSOP
|| optype1
== MEMOP
))
1961 rtx testlow
= gen_rtx_REG (SImode
, REGNO (operands
[0]));
1963 if (reg_overlap_mentioned_p (testlow
, XEXP (operands
[1], 0))
1964 && reg_overlap_mentioned_p (latehalf
[0], XEXP (operands
[1], 0)))
1966 /* If both halves of dest are used in the src memory address,
1967 compute the address into latehalf of dest.
1968 Note that this can't happen if the dest is two data regs. */
1970 xops
[0] = latehalf
[0];
1971 xops
[1] = XEXP (operands
[1], 0);
1972 output_asm_insn ("lea %a1,%0", xops
);
1973 if( GET_MODE (operands
[1]) == XFmode
)
1975 operands
[1] = gen_rtx_MEM (XFmode
, latehalf
[0]);
1976 middlehalf
[1] = adj_offsettable_operand (operands
[1], size
-8);
1977 latehalf
[1] = adj_offsettable_operand (operands
[1], size
-4);
1981 operands
[1] = gen_rtx_MEM (DImode
, latehalf
[0]);
1982 latehalf
[1] = adj_offsettable_operand (operands
[1], size
-4);
1986 && reg_overlap_mentioned_p (middlehalf
[0],
1987 XEXP (operands
[1], 0)))
1989 /* Check for two regs used by both source and dest.
1990 Note that this can't happen if the dest is all data regs.
1991 It can happen if the dest is d6, d7, a0.
1992 But in that case, latehalf is an addr reg, so
1993 the code at compadr does ok. */
1995 if (reg_overlap_mentioned_p (testlow
, XEXP (operands
[1], 0))
1996 || reg_overlap_mentioned_p (latehalf
[0], XEXP (operands
[1], 0)))
1999 /* JRV says this can't happen: */
2000 if (addreg0
|| addreg1
)
2003 /* Only the middle reg conflicts; simply put it last. */
2004 output_asm_insn (singlemove_string (operands
), operands
);
2005 output_asm_insn (singlemove_string (latehalf
), latehalf
);
2006 output_asm_insn (singlemove_string (middlehalf
), middlehalf
);
2009 else if (reg_overlap_mentioned_p (testlow
, XEXP (operands
[1], 0)))
2010 /* If the low half of dest is mentioned in the source memory
2011 address, the arrange to emit the move late half first. */
2012 dest_overlapped_low
= 1;
2015 /* If one or both operands autodecrementing,
2016 do the two words, high-numbered first. */
2018 /* Likewise, the first move would clobber the source of the second one,
2019 do them in the other order. This happens only for registers;
2020 such overlap can't happen in memory unless the user explicitly
2021 sets it up, and that is an undefined circumstance. */
2023 if (optype0
== PUSHOP
|| optype1
== PUSHOP
2024 || (optype0
== REGOP
&& optype1
== REGOP
2025 && ((middlehalf
[1] && REGNO (operands
[0]) == REGNO (middlehalf
[1]))
2026 || REGNO (operands
[0]) == REGNO (latehalf
[1])))
2027 || dest_overlapped_low
)
2029 /* Make any unoffsettable addresses point at high-numbered word. */
2033 output_asm_insn ("addq%.l %#8,%0", &addreg0
);
2035 output_asm_insn ("addq%.l %#4,%0", &addreg0
);
2040 output_asm_insn ("addq%.l %#8,%0", &addreg1
);
2042 output_asm_insn ("addq%.l %#4,%0", &addreg1
);
2046 output_asm_insn (singlemove_string (latehalf
), latehalf
);
2048 /* Undo the adds we just did. */
2050 output_asm_insn ("subq%.l %#4,%0", &addreg0
);
2052 output_asm_insn ("subq%.l %#4,%0", &addreg1
);
2056 output_asm_insn (singlemove_string (middlehalf
), middlehalf
);
2058 output_asm_insn ("subq%.l %#4,%0", &addreg0
);
2060 output_asm_insn ("subq%.l %#4,%0", &addreg1
);
2063 /* Do low-numbered word. */
2064 return singlemove_string (operands
);
2067 /* Normal case: do the two words, low-numbered first. */
2069 output_asm_insn (singlemove_string (operands
), operands
);
2071 /* Do the middle one of the three words for long double */
2075 output_asm_insn ("addq%.l %#4,%0", &addreg0
);
2077 output_asm_insn ("addq%.l %#4,%0", &addreg1
);
2079 output_asm_insn (singlemove_string (middlehalf
), middlehalf
);
2082 /* Make any unoffsettable addresses point at high-numbered word. */
2084 output_asm_insn ("addq%.l %#4,%0", &addreg0
);
2086 output_asm_insn ("addq%.l %#4,%0", &addreg1
);
2089 output_asm_insn (singlemove_string (latehalf
), latehalf
);
2091 /* Undo the adds we just did. */
2095 output_asm_insn ("subq%.l %#8,%0", &addreg0
);
2097 output_asm_insn ("subq%.l %#4,%0", &addreg0
);
2102 output_asm_insn ("subq%.l %#8,%0", &addreg1
);
2104 output_asm_insn ("subq%.l %#4,%0", &addreg1
);
2110 /* Return a REG that occurs in ADDR with coefficient 1.
2111 ADDR can be effectively incremented by incrementing REG. */
2114 find_addr_reg (addr
)
2117 while (GET_CODE (addr
) == PLUS
)
2119 if (GET_CODE (XEXP (addr
, 0)) == REG
)
2120 addr
= XEXP (addr
, 0);
2121 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
2122 addr
= XEXP (addr
, 1);
2123 else if (CONSTANT_P (XEXP (addr
, 0)))
2124 addr
= XEXP (addr
, 1);
2125 else if (CONSTANT_P (XEXP (addr
, 1)))
2126 addr
= XEXP (addr
, 0);
2130 if (GET_CODE (addr
) == REG
)
2135 /* Output assembler code to perform a 32 bit 3 operand add. */
2138 output_addsi3 (operands
)
2141 if (! operands_match_p (operands
[0], operands
[1]))
2143 if (!ADDRESS_REG_P (operands
[1]))
2145 rtx tmp
= operands
[1];
2147 operands
[1] = operands
[2];
2151 /* These insns can result from reloads to access
2152 stack slots over 64k from the frame pointer. */
2153 if (GET_CODE (operands
[2]) == CONST_INT
2154 && INTVAL (operands
[2]) + 0x8000 >= (unsigned) 0x10000)
2155 return "move%.l %2,%0\n\tadd%.l %1,%0";
2157 if (GET_CODE (operands
[2]) == REG
)
2158 return "lea 0(%1,%2.l),%0";
2160 return "lea %c2(%1),%0";
2163 if (GET_CODE (operands
[2]) == REG
)
2164 return "lea (%1,%2.l),%0";
2166 return "lea (%c2,%1),%0";
2167 #else /* not MOTOROLA (MIT syntax) */
2168 if (GET_CODE (operands
[2]) == REG
)
2169 return "lea %1@(0,%2:l),%0";
2171 return "lea %1@(%c2),%0";
2172 #endif /* not MOTOROLA */
2173 #endif /* not SGS */
2175 if (GET_CODE (operands
[2]) == CONST_INT
)
2178 if (INTVAL (operands
[2]) > 0
2179 && INTVAL (operands
[2]) <= 8)
2180 return "addq%.l %2,%0";
2181 if (INTVAL (operands
[2]) < 0
2182 && INTVAL (operands
[2]) >= -8)
2184 operands
[2] = GEN_INT (- INTVAL (operands
[2]));
2185 return "subq%.l %2,%0";
2187 /* On the CPU32 it is faster to use two addql instructions to
2188 add a small integer (8 < N <= 16) to a register.
2189 Likewise for subql. */
2190 if (TARGET_CPU32
&& REG_P (operands
[0]))
2192 if (INTVAL (operands
[2]) > 8
2193 && INTVAL (operands
[2]) <= 16)
2195 operands
[2] = GEN_INT (INTVAL (operands
[2]) - 8);
2196 return "addq%.l %#8,%0\n\taddq%.l %2,%0";
2198 if (INTVAL (operands
[2]) < -8
2199 && INTVAL (operands
[2]) >= -16)
2201 operands
[2] = GEN_INT (- INTVAL (operands
[2]) - 8);
2202 return "subq%.l %#8,%0\n\tsubq%.l %2,%0";
2206 if (ADDRESS_REG_P (operands
[0])
2207 && INTVAL (operands
[2]) >= -0x8000
2208 && INTVAL (operands
[2]) < 0x8000)
2211 return "add%.w %2,%0";
2214 return "lea (%c2,%0),%0";
2216 return "lea %0@(%c2),%0";
2220 return "add%.l %2,%0";
2223 /* Store in cc_status the expressions that the condition codes will
2224 describe after execution of an instruction whose pattern is EXP.
2225 Do not alter them if the instruction would not alter the cc's. */
2227 /* On the 68000, all the insns to store in an address register fail to
2228 set the cc's. However, in some cases these instructions can make it
2229 possibly invalid to use the saved cc's. In those cases we clear out
2230 some or all of the saved cc's so they won't be used. */
2233 notice_update_cc (exp
, insn
)
2237 /* If the cc is being set from the fpa and the expression is not an
2238 explicit floating point test instruction (which has code to deal with
2239 this), reinit the CC. */
2240 if (((cc_status
.value1
&& FPA_REG_P (cc_status
.value1
))
2241 || (cc_status
.value2
&& FPA_REG_P (cc_status
.value2
)))
2242 && !(GET_CODE (exp
) == PARALLEL
2243 && GET_CODE (XVECEXP (exp
, 0, 0)) == SET
2244 && XEXP (XVECEXP (exp
, 0, 0), 0) == cc0_rtx
))
2248 else if (GET_CODE (exp
) == SET
)
2250 if (GET_CODE (SET_SRC (exp
)) == CALL
)
2254 else if (ADDRESS_REG_P (SET_DEST (exp
)))
2256 if (cc_status
.value1
&& modified_in_p (cc_status
.value1
, insn
))
2257 cc_status
.value1
= 0;
2258 if (cc_status
.value2
&& modified_in_p (cc_status
.value2
, insn
))
2259 cc_status
.value2
= 0;
2261 else if (!FP_REG_P (SET_DEST (exp
))
2262 && SET_DEST (exp
) != cc0_rtx
2263 && (FP_REG_P (SET_SRC (exp
))
2264 || GET_CODE (SET_SRC (exp
)) == FIX
2265 || GET_CODE (SET_SRC (exp
)) == FLOAT_TRUNCATE
2266 || GET_CODE (SET_SRC (exp
)) == FLOAT_EXTEND
))
2270 /* A pair of move insns doesn't produce a useful overall cc. */
2271 else if (!FP_REG_P (SET_DEST (exp
))
2272 && !FP_REG_P (SET_SRC (exp
))
2273 && GET_MODE_SIZE (GET_MODE (SET_SRC (exp
))) > 4
2274 && (GET_CODE (SET_SRC (exp
)) == REG
2275 || GET_CODE (SET_SRC (exp
)) == MEM
2276 || GET_CODE (SET_SRC (exp
)) == CONST_DOUBLE
))
2280 else if (GET_CODE (SET_SRC (exp
)) == CALL
)
2284 else if (XEXP (exp
, 0) != pc_rtx
)
2286 cc_status
.flags
= 0;
2287 cc_status
.value1
= XEXP (exp
, 0);
2288 cc_status
.value2
= XEXP (exp
, 1);
2291 else if (GET_CODE (exp
) == PARALLEL
2292 && GET_CODE (XVECEXP (exp
, 0, 0)) == SET
)
2294 if (ADDRESS_REG_P (XEXP (XVECEXP (exp
, 0, 0), 0)))
2296 else if (XEXP (XVECEXP (exp
, 0, 0), 0) != pc_rtx
)
2298 cc_status
.flags
= 0;
2299 cc_status
.value1
= XEXP (XVECEXP (exp
, 0, 0), 0);
2300 cc_status
.value2
= XEXP (XVECEXP (exp
, 0, 0), 1);
2305 if (cc_status
.value2
!= 0
2306 && ADDRESS_REG_P (cc_status
.value2
)
2307 && GET_MODE (cc_status
.value2
) == QImode
)
2309 if (cc_status
.value2
!= 0
2310 && !(cc_status
.value1
&& FPA_REG_P (cc_status
.value1
)))
2311 switch (GET_CODE (cc_status
.value2
))
2313 case PLUS
: case MINUS
: case MULT
:
2314 case DIV
: case UDIV
: case MOD
: case UMOD
: case NEG
:
2315 #if 0 /* These instructions always clear the overflow bit */
2316 case ASHIFT
: case ASHIFTRT
: case LSHIFTRT
:
2317 case ROTATE
: case ROTATERT
:
2319 if (GET_MODE (cc_status
.value2
) != VOIDmode
)
2320 cc_status
.flags
|= CC_NO_OVERFLOW
;
2323 /* (SET r1 (ZERO_EXTEND r2)) on this machine
2324 ends with a move insn moving r2 in r2's mode.
2325 Thus, the cc's are set for r2.
2326 This can set N bit spuriously. */
2327 cc_status
.flags
|= CC_NOT_NEGATIVE
;
2332 if (cc_status
.value1
&& GET_CODE (cc_status
.value1
) == REG
2334 && reg_overlap_mentioned_p (cc_status
.value1
, cc_status
.value2
))
2335 cc_status
.value2
= 0;
2336 if (((cc_status
.value1
&& FP_REG_P (cc_status
.value1
))
2337 || (cc_status
.value2
&& FP_REG_P (cc_status
.value2
)))
2338 && !((cc_status
.value1
&& FPA_REG_P (cc_status
.value1
))
2339 || (cc_status
.value2
&& FPA_REG_P (cc_status
.value2
))))
2340 cc_status
.flags
= CC_IN_68881
;
2344 output_move_const_double (operands
)
2347 #ifdef SUPPORT_SUN_FPA
2348 if (TARGET_FPA
&& FPA_REG_P (operands
[0]))
2350 int code
= standard_sun_fpa_constant_p (operands
[1]);
2354 static char buf
[40];
2356 sprintf (buf
, "fpmove%%.d %%%%%d,%%0", code
& 0x1ff);
2359 return "fpmove%.d %1,%0";
2364 int code
= standard_68881_constant_p (operands
[1]);
2368 static char buf
[40];
2370 sprintf (buf
, "fmovecr %%#0x%x,%%0", code
& 0xff);
2373 return "fmove%.d %1,%0";
2378 output_move_const_single (operands
)
2381 #ifdef SUPPORT_SUN_FPA
2384 int code
= standard_sun_fpa_constant_p (operands
[1]);
2388 static char buf
[40];
2390 sprintf (buf
, "fpmove%%.s %%%%%d,%%0", code
& 0x1ff);
2393 return "fpmove%.s %1,%0";
2396 #endif /* defined SUPPORT_SUN_FPA */
2398 int code
= standard_68881_constant_p (operands
[1]);
2402 static char buf
[40];
2404 sprintf (buf
, "fmovecr %%#0x%x,%%0", code
& 0xff);
2407 return "fmove%.s %f1,%0";
2411 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
2412 from the "fmovecr" instruction.
2413 The value, anded with 0xff, gives the code to use in fmovecr
2414 to get the desired constant. */
2416 /* This code has been fixed for cross-compilation. */
2418 static int inited_68881_table
= 0;
2420 static const char *const strings_68881
[7] = {
2430 int codes_68881
[7] = {
2440 REAL_VALUE_TYPE values_68881
[7];
2442 /* Set up values_68881 array by converting the decimal values
2443 strings_68881 to binary. */
2450 enum machine_mode mode
;
2453 for (i
= 0; i
< 7; i
++)
2457 r
= REAL_VALUE_ATOF (strings_68881
[i
], mode
);
2458 values_68881
[i
] = r
;
2460 inited_68881_table
= 1;
2464 standard_68881_constant_p (x
)
2470 #ifdef NO_ASM_FMOVECR
2474 /* fmovecr must be emulated on the 68040 and 68060, so it shouldn't be
2475 used at all on those chips. */
2476 if (TARGET_68040
|| TARGET_68060
)
2479 #ifndef REAL_ARITHMETIC
2480 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
2481 if (! flag_pretend_float
)
2486 if (! inited_68881_table
)
2487 init_68881_table ();
2489 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
2491 /* Use REAL_VALUES_IDENTICAL instead of REAL_VALUES_EQUAL so that -0.0
2493 for (i
= 0; i
< 6; i
++)
2495 if (REAL_VALUES_IDENTICAL (r
, values_68881
[i
]))
2496 return (codes_68881
[i
]);
2499 if (GET_MODE (x
) == SFmode
)
2502 if (REAL_VALUES_EQUAL (r
, values_68881
[6]))
2503 return (codes_68881
[6]);
2505 /* larger powers of ten in the constants ram are not used
2506 because they are not equal to a `double' C constant. */
2510 /* If X is a floating-point constant, return the logarithm of X base 2,
2511 or 0 if X is not a power of 2. */
2514 floating_exact_log2 (x
)
2517 REAL_VALUE_TYPE r
, r1
;
2520 #ifndef REAL_ARITHMETIC
2521 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
2522 if (! flag_pretend_float
)
2527 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
2529 if (REAL_VALUES_LESS (r
, dconst0
))
2534 while (REAL_VALUES_LESS (r1
, r
))
2536 r1
= REAL_VALUE_LDEXP (dconst1
, i
);
2537 if (REAL_VALUES_EQUAL (r1
, r
))
2544 #ifdef SUPPORT_SUN_FPA
2545 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
2546 from the Sun FPA's constant RAM.
2547 The value returned, anded with 0x1ff, gives the code to use in fpmove
2548 to get the desired constant. */
2550 static int inited_FPA_table
= 0;
2552 static const char *const strings_FPA
[38] = {
2553 /* small rationals */
2566 /* Decimal equivalents of double precision values */
2567 "2.718281828459045091", /* D_E */
2568 "6.283185307179586477", /* 2 pi */
2569 "3.141592653589793116", /* D_PI */
2570 "1.570796326794896619", /* pi/2 */
2571 "1.414213562373095145", /* D_SQRT2 */
2572 "0.7071067811865475244", /* 1/sqrt(2) */
2573 "-1.570796326794896619", /* -pi/2 */
2574 "1.442695040888963387", /* D_LOG2ofE */
2575 "3.321928024887362182", /* D_LOG2of10 */
2576 "0.6931471805599452862", /* D_LOGEof2 */
2577 "2.302585092994045901", /* D_LOGEof10 */
2578 "0.3010299956639811980", /* D_LOG10of2 */
2579 "0.4342944819032518167", /* D_LOG10ofE */
2580 /* Decimal equivalents of single precision values */
2581 "2.718281745910644531", /* S_E */
2582 "6.283185307179586477", /* 2 pi */
2583 "3.141592741012573242", /* S_PI */
2584 "1.570796326794896619", /* pi/2 */
2585 "1.414213538169860840", /* S_SQRT2 */
2586 "0.7071067811865475244", /* 1/sqrt(2) */
2587 "-1.570796326794896619", /* -pi/2 */
2588 "1.442695021629333496", /* S_LOG2ofE */
2589 "3.321928024291992188", /* S_LOG2of10 */
2590 "0.6931471824645996094", /* S_LOGEof2 */
2591 "2.302585124969482442", /* S_LOGEof10 */
2592 "0.3010300099849700928", /* S_LOG10of2 */
2593 "0.4342944920063018799", /* S_LOG10ofE */
2597 int codes_FPA
[38] = {
2598 /* small rationals */
2611 /* double precision */
2625 /* single precision */
2641 REAL_VALUE_TYPE values_FPA
[38];
2643 /* This code has been fixed for cross-compilation. */
2648 enum machine_mode mode
;
2653 for (i
= 0; i
< 38; i
++)
2657 r
= REAL_VALUE_ATOF (strings_FPA
[i
], mode
);
2660 inited_FPA_table
= 1;
2665 standard_sun_fpa_constant_p (x
)
2671 #ifndef REAL_ARITHMETIC
2672 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
2673 if (! flag_pretend_float
)
2678 if (! inited_FPA_table
)
2681 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
2683 for (i
=0; i
<12; i
++)
2685 if (REAL_VALUES_EQUAL (r
, values_FPA
[i
]))
2686 return (codes_FPA
[i
]);
2689 if (GET_MODE (x
) == SFmode
)
2691 for (i
=25; i
<38; i
++)
2693 if (REAL_VALUES_EQUAL (r
, values_FPA
[i
]))
2694 return (codes_FPA
[i
]);
2699 for (i
=12; i
<25; i
++)
2701 if (REAL_VALUES_EQUAL (r
, values_FPA
[i
]))
2702 return (codes_FPA
[i
]);
2707 #endif /* define SUPPORT_SUN_FPA */
2709 /* A C compound statement to output to stdio stream STREAM the
2710 assembler syntax for an instruction operand X. X is an RTL
2713 CODE is a value that can be used to specify one of several ways
2714 of printing the operand. It is used when identical operands
2715 must be printed differently depending on the context. CODE
2716 comes from the `%' specification that was used to request
2717 printing of the operand. If the specification was just `%DIGIT'
2718 then CODE is 0; if the specification was `%LTR DIGIT' then CODE
2719 is the ASCII code for LTR.
2721 If X is a register, this macro should print the register's name.
2722 The names can be found in an array `reg_names' whose type is
2723 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
2725 When the machine description has a specification `%PUNCT' (a `%'
2726 followed by a punctuation character), this macro is called with
2727 a null pointer for X and the punctuation character for CODE.
2729 The m68k specific codes are:
2731 '.' for dot needed in Motorola-style opcode names.
2732 '-' for an operand pushing on the stack:
2733 sp@-, -(sp) or -(%sp) depending on the style of syntax.
2734 '+' for an operand pushing on the stack:
2735 sp@+, (sp)+ or (%sp)+ depending on the style of syntax.
2736 '@' for a reference to the top word on the stack:
2737 sp@, (sp) or (%sp) depending on the style of syntax.
2738 '#' for an immediate operand prefix (# in MIT and Motorola syntax
2739 but & in SGS syntax, $ in CRDS/UNOS syntax).
2740 '!' for the cc register (used in an `and to cc' insn).
2741 '$' for the letter `s' in an op code, but only on the 68040.
2742 '&' for the letter `d' in an op code, but only on the 68040.
2743 '/' for register prefix needed by longlong.h.
2745 'b' for byte insn (no effect, on the Sun; this is for the ISI).
2746 'd' to force memory addressing to be absolute, not relative.
2747 'f' for float insn (print a CONST_DOUBLE as a float rather than in hex)
2748 'o' for operands to go directly to output_operand_address (bypassing
2749 print_operand_address--used only for SYMBOL_REFs under TARGET_PCREL)
2750 'w' for FPA insn (print a CONST_DOUBLE as a SunFPA constant rather
2751 than directly). Second part of 'y' below.
2752 'x' for float insn (print a CONST_DOUBLE as a float rather than in hex),
2753 or print pair of registers as rx:ry.
2754 'y' for a FPA insn (print pair of registers as rx:ry). This also outputs
2755 CONST_DOUBLE's as SunFPA constant RAM registers if
2756 possible, so it should not be used except for the SunFPA.
2761 print_operand (file
, op
, letter
)
2762 FILE *file
; /* file to write to */
2763 rtx op
; /* operand to print */
2764 int letter
; /* %<letter> or 0 */
2766 #ifdef SUPPORT_SUN_FPA
2772 #if defined (MOTOROLA) && !defined (CRDS)
2773 asm_fprintf (file
, ".");
2776 else if (letter
== '#')
2778 asm_fprintf (file
, "%0I");
2780 else if (letter
== '-')
2783 asm_fprintf (file
, "-(%Rsp)");
2785 asm_fprintf (file
, "%Rsp@-");
2788 else if (letter
== '+')
2791 asm_fprintf (file
, "(%Rsp)+");
2793 asm_fprintf (file
, "%Rsp@+");
2796 else if (letter
== '@')
2799 asm_fprintf (file
, "(%Rsp)");
2801 asm_fprintf (file
, "%Rsp@");
2804 else if (letter
== '!')
2806 asm_fprintf (file
, "%Rfpcr");
2808 else if (letter
== '$')
2810 if (TARGET_68040_ONLY
)
2812 fprintf (file
, "s");
2815 else if (letter
== '&')
2817 if (TARGET_68040_ONLY
)
2819 fprintf (file
, "d");
2822 else if (letter
== '/')
2824 asm_fprintf (file
, "%R");
2826 else if (letter
== 'o')
2828 /* This is only for direct addresses with TARGET_PCREL */
2829 if (GET_CODE (op
) != MEM
|| GET_CODE (XEXP (op
, 0)) != SYMBOL_REF
2832 output_addr_const (file
, XEXP (op
, 0));
2834 else if (GET_CODE (op
) == REG
)
2836 #ifdef SUPPORT_SUN_FPA
2838 && (letter
== 'y' || letter
== 'x')
2839 && GET_MODE (op
) == DFmode
)
2841 fprintf (file
, "%s:%s", reg_names
[REGNO (op
)],
2842 reg_names
[REGNO (op
)+1]);
2848 /* Print out the second register name of a register pair.
2849 I.e., R (6) => 7. */
2850 fputs (reg_names
[REGNO (op
) + 1], file
);
2852 fputs (reg_names
[REGNO (op
)], file
);
2855 else if (GET_CODE (op
) == MEM
)
2857 output_address (XEXP (op
, 0));
2858 if (letter
== 'd' && ! TARGET_68020
2859 && CONSTANT_ADDRESS_P (XEXP (op
, 0))
2860 && !(GET_CODE (XEXP (op
, 0)) == CONST_INT
2861 && INTVAL (XEXP (op
, 0)) < 0x8000
2862 && INTVAL (XEXP (op
, 0)) >= -0x8000))
2865 fprintf (file
, ".l");
2867 fprintf (file
, ":l");
2871 #ifdef SUPPORT_SUN_FPA
2872 else if ((letter
== 'y' || letter
== 'w')
2873 && GET_CODE (op
) == CONST_DOUBLE
2874 && (i
= standard_sun_fpa_constant_p (op
)))
2876 fprintf (file
, "%%%d", i
& 0x1ff);
2879 else if (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == SFmode
)
2882 REAL_VALUE_FROM_CONST_DOUBLE (r
, op
);
2883 ASM_OUTPUT_FLOAT_OPERAND (letter
, file
, r
);
2885 else if (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == XFmode
)
2888 REAL_VALUE_FROM_CONST_DOUBLE (r
, op
);
2889 ASM_OUTPUT_LONG_DOUBLE_OPERAND (file
, r
);
2891 else if (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == DFmode
)
2894 REAL_VALUE_FROM_CONST_DOUBLE (r
, op
);
2895 ASM_OUTPUT_DOUBLE_OPERAND (file
, r
);
2899 /* Use `print_operand_address' instead of `output_addr_const'
2900 to ensure that we print relevant PIC stuff. */
2901 asm_fprintf (file
, "%0I");
2903 && (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == CONST
))
2904 print_operand_address (file
, op
);
2906 output_addr_const (file
, op
);
2911 /* A C compound statement to output to stdio stream STREAM the
2912 assembler syntax for an instruction operand that is a memory
2913 reference whose address is ADDR. ADDR is an RTL expression.
2915 Note that this contains a kludge that knows that the only reason
2916 we have an address (plus (label_ref...) (reg...)) when not generating
2917 PIC code is in the insn before a tablejump, and we know that m68k.md
2918 generates a label LInnn: on such an insn.
2920 It is possible for PIC to generate a (plus (label_ref...) (reg...))
2921 and we handle that just like we would a (plus (symbol_ref...) (reg...)).
2923 Some SGS assemblers have a bug such that "Lnnn-LInnn-2.b(pc,d0.l*2)"
2924 fails to assemble. Luckily "Lnnn(pc,d0.l*2)" produces the results
2925 we want. This difference can be accommodated by using an assembler
2926 define such "LDnnn" to be either "Lnnn-LInnn-2.b", "Lnnn", or any other
2927 string, as necessary. This is accomplished via the ASM_OUTPUT_CASE_END
2928 macro. See m68k/sgs.h for an example; for versions without the bug.
2929 Some assemblers refuse all the above solutions. The workaround is to
2930 emit "K(pc,d0.l*2)" with K being a small constant known to give the
2933 They also do not like things like "pea 1.w", so we simple leave off
2934 the .w on small constants.
2936 This routine is responsible for distinguishing between -fpic and -fPIC
2937 style relocations in an address. When generating -fpic code the
2938 offset is output in word mode (eg movel a5@(_foo:w), a0). When generating
2939 -fPIC code the offset is output in long mode (eg movel a5@(_foo:l), a0) */
2941 #ifndef ASM_OUTPUT_CASE_FETCH
2944 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2945 asm_fprintf (file, "%LLD%d(%Rpc,%s.", labelno, regname)
2947 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2948 asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.", labelno, labelno, regname)
2951 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2952 asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:", labelno, labelno, regname)
2954 #endif /* ASM_OUTPUT_CASE_FETCH */
2957 print_operand_address (file
, addr
)
2961 register rtx reg1
, reg2
, breg
, ireg
;
2964 switch (GET_CODE (addr
))
2968 fprintf (file
, "(%s)", reg_names
[REGNO (addr
)]);
2970 fprintf (file
, "%s@", reg_names
[REGNO (addr
)]);
2975 fprintf (file
, "-(%s)", reg_names
[REGNO (XEXP (addr
, 0))]);
2977 fprintf (file
, "%s@-", reg_names
[REGNO (XEXP (addr
, 0))]);
2982 fprintf (file
, "(%s)+", reg_names
[REGNO (XEXP (addr
, 0))]);
2984 fprintf (file
, "%s@+", reg_names
[REGNO (XEXP (addr
, 0))]);
2988 reg1
= reg2
= ireg
= breg
= offset
= 0;
2989 if (CONSTANT_ADDRESS_P (XEXP (addr
, 0)))
2991 offset
= XEXP (addr
, 0);
2992 addr
= XEXP (addr
, 1);
2994 else if (CONSTANT_ADDRESS_P (XEXP (addr
, 1)))
2996 offset
= XEXP (addr
, 1);
2997 addr
= XEXP (addr
, 0);
2999 if (GET_CODE (addr
) != PLUS
)
3003 else if (GET_CODE (XEXP (addr
, 0)) == SIGN_EXTEND
)
3005 reg1
= XEXP (addr
, 0);
3006 addr
= XEXP (addr
, 1);
3008 else if (GET_CODE (XEXP (addr
, 1)) == SIGN_EXTEND
)
3010 reg1
= XEXP (addr
, 1);
3011 addr
= XEXP (addr
, 0);
3013 else if (GET_CODE (XEXP (addr
, 0)) == MULT
)
3015 reg1
= XEXP (addr
, 0);
3016 addr
= XEXP (addr
, 1);
3018 else if (GET_CODE (XEXP (addr
, 1)) == MULT
)
3020 reg1
= XEXP (addr
, 1);
3021 addr
= XEXP (addr
, 0);
3023 else if (GET_CODE (XEXP (addr
, 0)) == REG
)
3025 reg1
= XEXP (addr
, 0);
3026 addr
= XEXP (addr
, 1);
3028 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
3030 reg1
= XEXP (addr
, 1);
3031 addr
= XEXP (addr
, 0);
3033 if (GET_CODE (addr
) == REG
|| GET_CODE (addr
) == MULT
3034 || GET_CODE (addr
) == SIGN_EXTEND
)
3046 #if 0 /* for OLD_INDEXING */
3047 else if (GET_CODE (addr
) == PLUS
)
3049 if (GET_CODE (XEXP (addr
, 0)) == REG
)
3051 reg2
= XEXP (addr
, 0);
3052 addr
= XEXP (addr
, 1);
3054 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
3056 reg2
= XEXP (addr
, 1);
3057 addr
= XEXP (addr
, 0);
3069 if ((reg1
&& (GET_CODE (reg1
) == SIGN_EXTEND
3070 || GET_CODE (reg1
) == MULT
))
3071 || (reg2
!= 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2
))))
3076 else if (reg1
!= 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1
)))
3081 if (ireg
!= 0 && breg
== 0 && GET_CODE (addr
) == LABEL_REF
3082 && ! (flag_pic
&& ireg
== pic_offset_table_rtx
))
3085 if (GET_CODE (ireg
) == MULT
)
3087 scale
= INTVAL (XEXP (ireg
, 1));
3088 ireg
= XEXP (ireg
, 0);
3090 if (GET_CODE (ireg
) == SIGN_EXTEND
)
3092 ASM_OUTPUT_CASE_FETCH (file
,
3093 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
3094 reg_names
[REGNO (XEXP (ireg
, 0))]);
3095 fprintf (file
, "w");
3099 ASM_OUTPUT_CASE_FETCH (file
,
3100 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
3101 reg_names
[REGNO (ireg
)]);
3102 fprintf (file
, "l");
3107 fprintf (file
, "*%d", scale
);
3109 fprintf (file
, ":%d", scale
);
3115 if (breg
!= 0 && ireg
== 0 && GET_CODE (addr
) == LABEL_REF
3116 && ! (flag_pic
&& breg
== pic_offset_table_rtx
))
3118 ASM_OUTPUT_CASE_FETCH (file
,
3119 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
3120 reg_names
[REGNO (breg
)]);
3121 fprintf (file
, "l)");
3124 if (ireg
!= 0 || breg
!= 0)
3131 if (! flag_pic
&& addr
&& GET_CODE (addr
) == LABEL_REF
)
3138 output_addr_const (file
, addr
);
3139 if (flag_pic
&& (breg
== pic_offset_table_rtx
))
3141 fprintf (file
, "@GOT");
3143 fprintf (file
, ".w");
3146 fprintf (file
, "(%s", reg_names
[REGNO (breg
)]);
3152 fprintf (file
, "%s@(", reg_names
[REGNO (breg
)]);
3155 output_addr_const (file
, addr
);
3156 if ((flag_pic
== 1) && (breg
== pic_offset_table_rtx
))
3157 fprintf (file
, ":w");
3158 if ((flag_pic
== 2) && (breg
== pic_offset_table_rtx
))
3159 fprintf (file
, ":l");
3161 if (addr
!= 0 && ireg
!= 0)
3166 if (ireg
!= 0 && GET_CODE (ireg
) == MULT
)
3168 scale
= INTVAL (XEXP (ireg
, 1));
3169 ireg
= XEXP (ireg
, 0);
3171 if (ireg
!= 0 && GET_CODE (ireg
) == SIGN_EXTEND
)
3174 fprintf (file
, "%s.w", reg_names
[REGNO (XEXP (ireg
, 0))]);
3176 fprintf (file
, "%s:w", reg_names
[REGNO (XEXP (ireg
, 0))]);
3182 fprintf (file
, "%s.l", reg_names
[REGNO (ireg
)]);
3184 fprintf (file
, "%s:l", reg_names
[REGNO (ireg
)]);
3190 fprintf (file
, "*%d", scale
);
3192 fprintf (file
, ":%d", scale
);
3198 else if (reg1
!= 0 && GET_CODE (addr
) == LABEL_REF
3199 && ! (flag_pic
&& reg1
== pic_offset_table_rtx
))
3201 ASM_OUTPUT_CASE_FETCH (file
,
3202 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
3203 reg_names
[REGNO (reg1
)]);
3204 fprintf (file
, "l)");
3207 /* FALL-THROUGH (is this really what we want?) */
3209 if (GET_CODE (addr
) == CONST_INT
3210 && INTVAL (addr
) < 0x8000
3211 && INTVAL (addr
) >= -0x8000)
3215 /* Many SGS assemblers croak on size specifiers for constants. */
3216 fprintf (file
, "%d", INTVAL (addr
));
3218 fprintf (file
, "%d.w", INTVAL (addr
));
3221 fprintf (file
, "%d:w", INTVAL (addr
));
3224 else if (GET_CODE (addr
) == CONST_INT
)
3227 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
3234 else if (TARGET_PCREL
)
3237 output_addr_const (file
, addr
);
3239 asm_fprintf (file
, ":w,%Rpc)");
3241 asm_fprintf (file
, ":l,%Rpc)");
3245 /* Special case for SYMBOL_REF if the symbol name ends in
3246 `.<letter>', this can be mistaken as a size suffix. Put
3247 the name in parentheses. */
3248 if (GET_CODE (addr
) == SYMBOL_REF
3249 && strlen (XSTR (addr
, 0)) > 2
3250 && XSTR (addr
, 0)[strlen (XSTR (addr
, 0)) - 2] == '.')
3253 output_addr_const (file
, addr
);
3257 output_addr_const (file
, addr
);
3263 /* Check for cases where a clr insns can be omitted from code using
3264 strict_low_part sets. For example, the second clrl here is not needed:
3265 clrl d0; movw a0@+,d0; use d0; clrl d0; movw a0@+; use d0; ...
3267 MODE is the mode of this STRICT_LOW_PART set. FIRST_INSN is the clear
3268 insn we are checking for redundancy. TARGET is the register set by the
3272 strict_low_part_peephole_ok (mode
, first_insn
, target
)
3273 enum machine_mode mode
;
3279 p
= prev_nonnote_insn (first_insn
);
3283 /* If it isn't an insn, then give up. */
3284 if (GET_CODE (p
) != INSN
)
3287 if (reg_set_p (target
, p
))
3289 rtx set
= single_set (p
);
3292 /* If it isn't an easy to recognize insn, then give up. */
3296 dest
= SET_DEST (set
);
3298 /* If this sets the entire target register to zero, then our
3299 first_insn is redundant. */
3300 if (rtx_equal_p (dest
, target
)
3301 && SET_SRC (set
) == const0_rtx
)
3303 else if (GET_CODE (dest
) == STRICT_LOW_PART
3304 && GET_CODE (XEXP (dest
, 0)) == REG
3305 && REGNO (XEXP (dest
, 0)) == REGNO (target
)
3306 && (GET_MODE_SIZE (GET_MODE (XEXP (dest
, 0)))
3307 <= GET_MODE_SIZE (mode
)))
3308 /* This is a strict low part set which modifies less than
3309 we are using, so it is safe. */
3315 p
= prev_nonnote_insn (p
);
3322 /* Accept integer operands in the range 0..0xffffffff. We have to check the
3323 range carefully since this predicate is used in DImode contexts. Also, we
3324 need some extra crud to make it work when hosted on 64-bit machines. */
3327 const_uint32_operand (op
, mode
)
3329 enum machine_mode mode ATTRIBUTE_UNUSED
;
3331 #if HOST_BITS_PER_WIDE_INT > 32
3332 /* All allowed constants will fit a CONST_INT. */
3333 return (GET_CODE (op
) == CONST_INT
3334 && (INTVAL (op
) >= 0 && INTVAL (op
) <= 0xffffffffL
));
3336 return ((GET_CODE (op
) == CONST_INT
&& INTVAL (op
) >= 0)
3337 || (GET_CODE (op
) == CONST_DOUBLE
&& CONST_DOUBLE_HIGH (op
) == 0));
3341 /* Accept integer operands in the range -0x80000000..0x7fffffff. We have
3342 to check the range carefully since this predicate is used in DImode
3346 const_sint32_operand (op
, mode
)
3348 enum machine_mode mode ATTRIBUTE_UNUSED
;
3350 /* All allowed constants will fit a CONST_INT. */
3351 return (GET_CODE (op
) == CONST_INT
3352 && (INTVAL (op
) >= (-0x7fffffff - 1) && INTVAL (op
) <= 0x7fffffff));
3355 /* Operand predicates for implementing asymmetric pc-relative addressing
3356 on m68k. The m68k supports pc-relative addressing (mode 7, register 2)
3357 when used as a source operand, but not as a destintation operand.
3359 We model this by restricting the meaning of the basic predicates
3360 (general_operand, memory_operand, etc) to forbid the use of this
3361 addressing mode, and then define the following predicates that permit
3362 this addressing mode. These predicates can then be used for the
3363 source operands of the appropriate instructions.
3365 n.b. While it is theoretically possible to change all machine patterns
3366 to use this addressing more where permitted by the architecture,
3367 it has only been implemented for "common" cases: SImode, HImode, and
3368 QImode operands, and only for the principle operations that would
3369 require this addressing mode: data movement and simple integer operations.
3371 In parallel with these new predicates, two new constraint letters
3372 were defined: 'S' and 'T'. 'S' is the -mpcrel analog of 'm'.
3373 'T' replaces 's' in the non-pcrel case. It is a no-op in the pcrel case.
3374 In the pcrel case 's' is only valid in combination with 'a' registers.
3375 See addsi3, subsi3, cmpsi, and movsi patterns for a better understanding
3376 of how these constraints are used.
3378 The use of these predicates is strictly optional, though patterns that
3379 don't will cause an extra reload register to be allocated where one
3382 lea (abc:w,%pc),%a0 ; need to reload address
3383 moveq &1,%d1 ; since write to pc-relative space
3384 movel %d1,%a0@ ; is not allowed
3386 lea (abc:w,%pc),%a1 ; no need to reload address here
3387 movel %a1@,%d0 ; since "movel (abc:w,%pc),%d0" is ok
3389 For more info, consult tiemann@cygnus.com.
3392 All of the ugliness with predicates and constraints is due to the
3393 simple fact that the m68k does not allow a pc-relative addressing
3394 mode as a destination. gcc does not distinguish between source and
3395 destination addresses. Hence, if we claim that pc-relative address
3396 modes are valid, e.g. GO_IF_LEGITIMATE_ADDRESS accepts them, then we
3397 end up with invalid code. To get around this problem, we left
3398 pc-relative modes as invalid addresses, and then added special
3399 predicates and constraints to accept them.
3401 A cleaner way to handle this is to modify gcc to distinguish
3402 between source and destination addresses. We can then say that
3403 pc-relative is a valid source address but not a valid destination
3404 address, and hopefully avoid a lot of the predicate and constraint
3405 hackery. Unfortunately, this would be a pretty big change. It would
3406 be a useful change for a number of ports, but there aren't any current
3407 plans to undertake this.
3409 ***************************************************************************/
3412 /* Special case of a general operand that's used as a source operand.
3413 Use this to permit reads from PC-relative memory when -mpcrel
3417 general_src_operand (op
, mode
)
3419 enum machine_mode mode
;
3422 && GET_CODE (op
) == MEM
3423 && (GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
3424 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
3425 || GET_CODE (XEXP (op
, 0)) == CONST
))
3427 return general_operand (op
, mode
);
3430 /* Special case of a nonimmediate operand that's used as a source.
3431 Use this to permit reads from PC-relative memory when -mpcrel
3435 nonimmediate_src_operand (op
, mode
)
3437 enum machine_mode mode
;
3439 if (TARGET_PCREL
&& GET_CODE (op
) == MEM
3440 && (GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
3441 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
3442 || GET_CODE (XEXP (op
, 0)) == CONST
))
3444 return nonimmediate_operand (op
, mode
);
3447 /* Special case of a memory operand that's used as a source.
3448 Use this to permit reads from PC-relative memory when -mpcrel
3452 memory_src_operand (op
, mode
)
3454 enum machine_mode mode
;
3456 if (TARGET_PCREL
&& GET_CODE (op
) == MEM
3457 && (GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
3458 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
3459 || GET_CODE (XEXP (op
, 0)) == CONST
))
3461 return memory_operand (op
, mode
);
3464 /* Predicate that accepts only a pc-relative address. This is needed
3465 because pc-relative addresses don't satisfy the predicate
3466 "general_src_operand". */
3469 pcrel_address (op
, mode
)
3471 enum machine_mode mode ATTRIBUTE_UNUSED
;
3473 return (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
3474 || GET_CODE (op
) == CONST
);
3478 output_andsi3 (operands
)
3482 if (GET_CODE (operands
[2]) == CONST_INT
3483 && (INTVAL (operands
[2]) | 0xffff) == 0xffffffff
3484 && (DATA_REG_P (operands
[0])
3485 || offsettable_memref_p (operands
[0]))
3488 if (GET_CODE (operands
[0]) != REG
)
3489 operands
[0] = adj_offsettable_operand (operands
[0], 2);
3490 operands
[2] = GEN_INT (INTVAL (operands
[2]) & 0xffff);
3491 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3493 if (operands
[2] == const0_rtx
)
3495 return "and%.w %2,%0";
3497 if (GET_CODE (operands
[2]) == CONST_INT
3498 && (logval
= exact_log2 (~ INTVAL (operands
[2]))) >= 0
3499 && (DATA_REG_P (operands
[0])
3500 || offsettable_memref_p (operands
[0])))
3502 if (DATA_REG_P (operands
[0]))
3504 operands
[1] = GEN_INT (logval
);
3508 operands
[0] = adj_offsettable_operand (operands
[0], 3 - (logval
/ 8));
3509 operands
[1] = GEN_INT (logval
% 8);
3511 /* This does not set condition codes in a standard way. */
3513 return "bclr %1,%0";
3515 return "and%.l %2,%0";
3519 output_iorsi3 (operands
)
3522 register int logval
;
3523 if (GET_CODE (operands
[2]) == CONST_INT
3524 && INTVAL (operands
[2]) >> 16 == 0
3525 && (DATA_REG_P (operands
[0])
3526 || offsettable_memref_p (operands
[0]))
3529 if (GET_CODE (operands
[0]) != REG
)
3530 operands
[0] = adj_offsettable_operand (operands
[0], 2);
3531 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3533 if (INTVAL (operands
[2]) == 0xffff)
3534 return "mov%.w %2,%0";
3535 return "or%.w %2,%0";
3537 if (GET_CODE (operands
[2]) == CONST_INT
3538 && (logval
= exact_log2 (INTVAL (operands
[2]))) >= 0
3539 && (DATA_REG_P (operands
[0])
3540 || offsettable_memref_p (operands
[0])))
3542 if (DATA_REG_P (operands
[0]))
3544 operands
[1] = GEN_INT (logval
);
3548 operands
[0] = adj_offsettable_operand (operands
[0], 3 - (logval
/ 8));
3549 operands
[1] = GEN_INT (logval
% 8);
3552 return "bset %1,%0";
3554 return "or%.l %2,%0";
3558 output_xorsi3 (operands
)
3561 register int logval
;
3562 if (GET_CODE (operands
[2]) == CONST_INT
3563 && INTVAL (operands
[2]) >> 16 == 0
3564 && (offsettable_memref_p (operands
[0]) || DATA_REG_P (operands
[0]))
3567 if (! DATA_REG_P (operands
[0]))
3568 operands
[0] = adj_offsettable_operand (operands
[0], 2);
3569 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3571 if (INTVAL (operands
[2]) == 0xffff)
3573 return "eor%.w %2,%0";
3575 if (GET_CODE (operands
[2]) == CONST_INT
3576 && (logval
= exact_log2 (INTVAL (operands
[2]))) >= 0
3577 && (DATA_REG_P (operands
[0])
3578 || offsettable_memref_p (operands
[0])))
3580 if (DATA_REG_P (operands
[0]))
3582 operands
[1] = GEN_INT (logval
);
3586 operands
[0] = adj_offsettable_operand (operands
[0], 3 - (logval
/ 8));
3587 operands
[1] = GEN_INT (logval
% 8);
3590 return "bchg %1,%0";
3592 return "eor%.l %2,%0";