1 /* Subroutines for insn-output.c for Motorola 68000 family.
2 Copyright (C) 1987, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003
3 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC 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 GCC 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 GCC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
24 #include "coretypes.h"
30 #include "hard-reg-set.h"
32 #include "insn-config.h"
33 #include "conditions.h"
35 #include "insn-attr.h"
42 #include "target-def.h"
45 /* Needed for use_return_insn. */
48 /* Structure describing stack frame layout. */
52 /* data and address register */
54 unsigned int reg_mask
;
55 unsigned int reg_rev_mask
;
58 unsigned int fpu_mask
;
59 unsigned int fpu_rev_mask
;
60 /* offsets relative to ARG_POINTER. */
61 HOST_WIDE_INT frame_pointer_offset
;
62 HOST_WIDE_INT stack_pointer_offset
;
65 /* This flag is used to communicate between movhi and ASM_OUTPUT_CASE_END,
66 if SGS_SWITCH_TABLE. */
67 int switch_table_difference_label_flag
;
69 static rtx
find_addr_reg (rtx
);
70 static const char *singlemove_string (rtx
*);
71 static void m68k_output_function_prologue (FILE *, HOST_WIDE_INT
);
72 static void m68k_output_function_epilogue (FILE *, HOST_WIDE_INT
);
73 #ifdef M68K_TARGET_COFF
74 static void m68k_coff_asm_named_section (const char *, unsigned int);
75 #endif /* M68K_TARGET_COFF */
77 static void m68k_hp320_internal_label (FILE *, const char *, unsigned long);
78 static void m68k_hp320_file_start (void);
80 static void m68k_output_mi_thunk (FILE *, tree
, HOST_WIDE_INT
,
82 static bool m68k_interrupt_function_p (tree func
);
83 static tree
m68k_handle_fndecl_attribute (tree
*node
, tree name
,
86 static void m68k_compute_frame_layout (struct m68k_frame
*frame
);
87 static bool m68k_save_reg (unsigned int regno
, bool interrupt_handler
);
88 static int const_int_cost (rtx
);
89 static bool m68k_rtx_costs (rtx
, int, int, int *);
92 /* Alignment to use for loops and jumps */
93 /* Specify power of two alignment used for loops. */
94 const char *m68k_align_loops_string
;
95 /* Specify power of two alignment used for non-loop jumps. */
96 const char *m68k_align_jumps_string
;
97 /* Specify power of two alignment used for functions. */
98 const char *m68k_align_funcs_string
;
99 /* Specify the identification number of the library being built */
100 const char *m68k_library_id_string
;
102 /* Specify power of two alignment used for loops. */
103 int m68k_align_loops
;
104 /* Specify power of two alignment used for non-loop jumps. */
105 int m68k_align_jumps
;
106 /* Specify power of two alignment used for functions. */
107 int m68k_align_funcs
;
109 /* Nonzero if the last compare/test insn had FP operands. The
110 sCC expanders peek at this to determine what to do for the
111 68060, which has no fsCC instructions. */
112 int m68k_last_compare_had_fp_operands
;
114 /* Initialize the GCC target structure. */
116 #if INT_OP_GROUP == INT_OP_DOT_WORD
117 #undef TARGET_ASM_ALIGNED_HI_OP
118 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
121 #if INT_OP_GROUP == INT_OP_NO_DOT
122 #undef TARGET_ASM_BYTE_OP
123 #define TARGET_ASM_BYTE_OP "\tbyte\t"
124 #undef TARGET_ASM_ALIGNED_HI_OP
125 #define TARGET_ASM_ALIGNED_HI_OP "\tshort\t"
126 #undef TARGET_ASM_ALIGNED_SI_OP
127 #define TARGET_ASM_ALIGNED_SI_OP "\tlong\t"
130 #if INT_OP_GROUP == INT_OP_DC
131 #undef TARGET_ASM_BYTE_OP
132 #define TARGET_ASM_BYTE_OP "\tdc.b\t"
133 #undef TARGET_ASM_ALIGNED_HI_OP
134 #define TARGET_ASM_ALIGNED_HI_OP "\tdc.w\t"
135 #undef TARGET_ASM_ALIGNED_SI_OP
136 #define TARGET_ASM_ALIGNED_SI_OP "\tdc.l\t"
139 #undef TARGET_ASM_UNALIGNED_HI_OP
140 #define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP
141 #undef TARGET_ASM_UNALIGNED_SI_OP
142 #define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP
144 #undef TARGET_ASM_FUNCTION_PROLOGUE
145 #define TARGET_ASM_FUNCTION_PROLOGUE m68k_output_function_prologue
146 #undef TARGET_ASM_FUNCTION_EPILOGUE
147 #define TARGET_ASM_FUNCTION_EPILOGUE m68k_output_function_epilogue
149 #undef TARGET_ASM_INTERNAL_LABEL
150 #define TARGET_ASM_INTERNAL_LABEL m68k_hp320_internal_label
153 #undef TARGET_ASM_OUTPUT_MI_THUNK
154 #define TARGET_ASM_OUTPUT_MI_THUNK m68k_output_mi_thunk
155 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
156 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
158 #undef TARGET_ASM_FILE_START_APP_OFF
159 #define TARGET_ASM_FILE_START_APP_OFF true
161 #undef TARGET_RTX_COSTS
162 #define TARGET_RTX_COSTS m68k_rtx_costs
164 #undef TARGET_ATTRIBUTE_TABLE
165 #define TARGET_ATTRIBUTE_TABLE m68k_attribute_table
167 static const struct attribute_spec m68k_attribute_table
[] =
169 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
170 { "interrupt_handler", 0, 0, true, false, false, m68k_handle_fndecl_attribute
},
171 { NULL
, 0, 0, false, false, false, NULL
}
174 struct gcc_target targetm
= TARGET_INITIALIZER
;
176 /* Sometimes certain combinations of command options do not make
177 sense on a particular target machine. You can define a macro
178 `OVERRIDE_OPTIONS' to take account of this. This macro, if
179 defined, is executed once just after all the command options have
182 Don't use this macro to turn on various extra optimizations for
183 `-O'. That is what `OPTIMIZATION_OPTIONS' is for. */
186 override_options (void)
193 /* Validate -malign-loops= value, or provide default */
194 m68k_align_loops
= def_align
;
195 if (m68k_align_loops_string
)
197 i
= atoi (m68k_align_loops_string
);
198 if (i
< 1 || i
> MAX_CODE_ALIGN
)
199 error ("-malign-loops=%d is not between 1 and %d", i
, MAX_CODE_ALIGN
);
201 m68k_align_loops
= i
;
204 /* Library identification */
205 if (m68k_library_id_string
)
209 if (! TARGET_ID_SHARED_LIBRARY
)
210 error ("-mshared-library-id= specified without -mid-shared-library");
211 id
= atoi (m68k_library_id_string
);
212 if (id
< 0 || id
> MAX_LIBRARY_ID
)
213 error ("-mshared-library-id=%d is not between 0 and %d", id
, MAX_LIBRARY_ID
);
215 /* From now on, m68k_library_id_string will contain the library offset. */
216 asprintf ((char **)&m68k_library_id_string
, "%d", (id
* -4) - 4);
219 /* If TARGET_ID_SHARED_LIBRARY is enabled, this will point to the
221 m68k_library_id_string
= "_current_shared_library_a5_offset_";
223 /* Sanity check to ensure that msep-data and mid-sahred-library are not
224 * both specified together. Doing so simply doesn't make sense.
226 if (TARGET_SEP_DATA
&& TARGET_ID_SHARED_LIBRARY
)
227 error ("cannot specify both -msep-data and -mid-shared-library");
229 /* If we're generating code for a separate A5 relative data segment,
230 * we've got to enable -fPIC as well. This might be relaxable to
231 * -fpic but it hasn't been tested properly.
233 if (TARGET_SEP_DATA
|| TARGET_ID_SHARED_LIBRARY
)
236 /* Validate -malign-jumps= value, or provide default */
237 m68k_align_jumps
= def_align
;
238 if (m68k_align_jumps_string
)
240 i
= atoi (m68k_align_jumps_string
);
241 if (i
< 1 || i
> MAX_CODE_ALIGN
)
242 error ("-malign-jumps=%d is not between 1 and %d", i
, MAX_CODE_ALIGN
);
244 m68k_align_jumps
= i
;
247 /* Validate -malign-functions= value, or provide default */
248 m68k_align_funcs
= def_align
;
249 if (m68k_align_funcs_string
)
251 i
= atoi (m68k_align_funcs_string
);
252 if (i
< 1 || i
> MAX_CODE_ALIGN
)
253 error ("-malign-functions=%d is not between 1 and %d",
256 m68k_align_funcs
= i
;
259 /* -fPIC uses 32-bit pc-relative displacements, which don't exist
261 if (!TARGET_68020
&& !TARGET_COLDFIRE
&& (flag_pic
== 2))
262 error("-fPIC is not currently supported on the 68000 or 68010\n");
264 /* ??? A historic way of turning on pic, or is this intended to
265 be an embedded thing that doesn't have the same name binding
266 significance that it does on hosted ELF systems? */
267 if (TARGET_PCREL
&& flag_pic
== 0)
270 /* Turn off function cse if we are doing PIC. We always want function call
271 to be done as `bsr foo@PLTPC', so it will force the assembler to create
272 the PLT entry for `foo'. Doing function cse will cause the address of
273 `foo' to be loaded into a register, which is exactly what we want to
274 avoid when we are doing PIC on svr4 m68k. */
276 flag_no_function_cse
= 1;
278 SUBTARGET_OVERRIDE_OPTIONS
;
280 /* Tell the compiler which flavor of XFmode we're using. */
281 REAL_MODE_FORMAT (XFmode
) = &ieee_extended_motorola_format
;
284 /* Return nonzero if FUNC is an interrupt function as specified by the
285 "interrupt_handler" attribute. */
287 m68k_interrupt_function_p(tree func
)
291 if (TREE_CODE (func
) != FUNCTION_DECL
)
294 a
= lookup_attribute ("interrupt_handler", DECL_ATTRIBUTES (func
));
295 return (a
!= NULL_TREE
);
298 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
299 struct attribute_spec.handler. */
301 m68k_handle_fndecl_attribute (tree
*node
, tree name
,
302 tree args ATTRIBUTE_UNUSED
,
303 int flags ATTRIBUTE_UNUSED
,
306 if (TREE_CODE (*node
) != FUNCTION_DECL
)
308 warning ("`%s' attribute only applies to functions",
309 IDENTIFIER_POINTER (name
));
310 *no_add_attrs
= true;
317 m68k_compute_frame_layout (struct m68k_frame
*frame
)
320 unsigned int mask
, rmask
;
321 bool interrupt_handler
= m68k_interrupt_function_p (current_function_decl
);
323 frame
->size
= (get_frame_size () + 3) & -4;
325 mask
= rmask
= saved
= 0;
326 for (regno
= 0; regno
< 16; regno
++)
327 if (m68k_save_reg (regno
, interrupt_handler
))
330 rmask
|= 1 << (15 - regno
);
333 frame
->offset
= saved
* 4;
334 frame
->reg_no
= saved
;
335 frame
->reg_mask
= mask
;
336 frame
->reg_rev_mask
= rmask
;
338 if (TARGET_68881
/* || TARGET_CFV4E */)
340 mask
= rmask
= saved
= 0;
341 for (regno
= 16; regno
< 24; regno
++)
342 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
344 mask
|= 1 << (23 - regno
);
345 rmask
|= 1 << (regno
- 16);
348 frame
->offset
+= saved
* 12 /* (TARGET_CFV4E ? 8 : 12) */;
349 frame
->fpu_no
= saved
;
350 frame
->fpu_mask
= mask
;
351 frame
->fpu_rev_mask
= rmask
;
356 m68k_initial_elimination_offset (int from
, int to
)
358 struct m68k_frame frame
;
360 /* FIXME: The correct offset to compute here would appear to be
361 (frame_pointer_needed ? -UNITS_PER_WORD * 2 : -UNITS_PER_WORD);
362 but for some obscure reason, this must be 0 to get correct code. */
363 if (from
== ARG_POINTER_REGNUM
&& to
== FRAME_POINTER_REGNUM
)
366 m68k_compute_frame_layout (&frame
);
368 if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
369 return frame
.offset
+ frame
.size
+ (frame_pointer_needed
? -UNITS_PER_WORD
* 2 : -UNITS_PER_WORD
);
370 else if (from
== FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
371 return frame
.offset
+ frame
.size
;
376 /* Return true if we need to save REGNO. */
378 m68k_save_reg (unsigned int regno
, bool interrupt_handler
)
380 if (flag_pic
&& current_function_uses_pic_offset_table
381 && regno
== PIC_OFFSET_TABLE_REGNUM
)
384 if (current_function_calls_eh_return
)
389 unsigned int test
= EH_RETURN_DATA_REGNO (i
);
390 if (test
== INVALID_REGNUM
)
397 /* Fixed regs we never touch. */
398 if (fixed_regs
[regno
])
401 /* The frame pointer (if it is such) is handled specially. */
402 if (regno
== FRAME_POINTER_REGNUM
&& frame_pointer_needed
)
405 /* Interrupt handlers must also save call_used_regs
406 if they are live or when calling nested functions. */
407 if (interrupt_handler
)
409 if (regs_ever_live
[regno
])
412 if (!current_function_is_leaf
&& call_used_regs
[regno
])
416 /* Never need to save registers that aren't touched. */
417 if (!regs_ever_live
[regno
])
420 /* Otherwise save everthing that isn't call-clobbered. */
421 return !call_used_regs
[regno
];
424 /* This function generates the assembly code for function entry.
425 STREAM is a stdio stream to output the code to.
426 SIZE is an int: how many units of temporary storage to allocate.
427 Refer to the array `regs_ever_live' to determine which registers
428 to save; `regs_ever_live[I]' is nonzero if register number I
429 is ever used in the function. This function is responsible for
430 knowing which registers should not be saved even if used. */
433 /* Note that the order of the bit mask for fmovem is the opposite
434 of the order for movem! */
437 m68k_output_function_prologue (FILE *stream
, HOST_WIDE_INT size
)
440 register int mask
= 0;
441 int num_saved_regs
= 0;
442 HOST_WIDE_INT fsize
= (size
+ 3) & -4;
443 HOST_WIDE_INT fsize_with_regs
;
444 HOST_WIDE_INT cfa_offset
= INCOMING_FRAME_SP_OFFSET
;
445 bool interrupt_handler
= m68k_interrupt_function_p (current_function_decl
);
447 /* If the stack limit is a symbol, we can check it here,
448 before actually allocating the space. */
449 if (current_function_limit_stack
450 && GET_CODE (stack_limit_rtx
) == SYMBOL_REF
)
452 #if defined (MOTOROLA)
453 asm_fprintf (stream
, "\tcmp.l %I%s+%wd,%Rsp\n\ttrapcs\n",
454 XSTR (stack_limit_rtx
, 0), fsize
+ 4);
456 asm_fprintf (stream
, "\tcmpl %I%s+%wd,%Rsp\n\ttrapcs\n",
457 XSTR (stack_limit_rtx
, 0), fsize
+ 4);
463 /* on Coldfire add register save into initial stack frame setup, if possible */
464 for (regno
= 0; regno
< 16; regno
++)
465 if (m68k_save_reg (regno
, interrupt_handler
))
468 if (num_saved_regs
<= 2)
474 fsize_with_regs
= fsize
+ num_saved_regs
* 4;
476 if (frame_pointer_needed
)
478 if (fsize
== 0 && TARGET_68040
)
480 /* on the 68040, pea + move is faster than link.w 0 */
482 fprintf (stream
, "\tpea (%s)\n\tmove.l %s,%s\n",
483 reg_names
[FRAME_POINTER_REGNUM
],
484 reg_names
[STACK_POINTER_REGNUM
],
485 reg_names
[FRAME_POINTER_REGNUM
]);
487 fprintf (stream
, "\tpea %s@\n\tmovel %s,%s\n",
488 reg_names
[FRAME_POINTER_REGNUM
],
489 reg_names
[STACK_POINTER_REGNUM
],
490 reg_names
[FRAME_POINTER_REGNUM
]);
493 else if (fsize_with_regs
< 0x8000)
496 asm_fprintf (stream
, "\tlink.w %s,%I%wd\n",
497 reg_names
[FRAME_POINTER_REGNUM
], -fsize_with_regs
);
499 asm_fprintf (stream
, "\tlink %s,%I%wd\n",
500 reg_names
[FRAME_POINTER_REGNUM
], -fsize_with_regs
);
503 else if (TARGET_68020
)
506 asm_fprintf (stream
, "\tlink.l %s,%I%wd\n",
507 reg_names
[FRAME_POINTER_REGNUM
], -fsize_with_regs
);
509 asm_fprintf (stream
, "\tlink %s,%I%wd\n",
510 reg_names
[FRAME_POINTER_REGNUM
], -fsize_with_regs
);
515 /* Adding negative number is faster on the 68040. */
517 asm_fprintf (stream
, "\tlink.w %s,%I0\n\tadd.l %I%wd,%Rsp\n",
518 reg_names
[FRAME_POINTER_REGNUM
], -fsize_with_regs
);
520 asm_fprintf (stream
, "\tlink %s,%I0\n\taddl %I%wd,%Rsp\n",
521 reg_names
[FRAME_POINTER_REGNUM
], -fsize_with_regs
);
524 if (dwarf2out_do_frame ())
527 l
= (char *) dwarf2out_cfi_label ();
529 dwarf2out_reg_save (l
, FRAME_POINTER_REGNUM
, -cfa_offset
);
530 dwarf2out_def_cfa (l
, FRAME_POINTER_REGNUM
, cfa_offset
);
534 else if (fsize_with_regs
) /* !frame_pointer_needed */
536 if (fsize_with_regs
< 0x8000)
538 if (fsize_with_regs
<= 8)
540 if (!TARGET_COLDFIRE
)
542 /* asm_fprintf() cannot handle %. */
544 asm_fprintf (stream
, "\tsubq.w %I%wd,%Rsp\n", fsize_with_regs
);
546 asm_fprintf (stream
, "\tsubqw %I%wd,%Rsp\n", fsize_with_regs
);
551 /* asm_fprintf() cannot handle %. */
553 asm_fprintf (stream
, "\tsubq.l %I%wd,%Rsp\n", fsize_with_regs
);
555 asm_fprintf (stream
, "\tsubql %I%wd,%Rsp\n", fsize_with_regs
);
559 else if (fsize_with_regs
<= 16 && TARGET_CPU32
)
561 /* On the CPU32 it is faster to use two subqw instructions to
562 subtract a small integer (8 < N <= 16) to a register. */
563 /* asm_fprintf() cannot handle %. */
566 "\tsubq.w %I8,%Rsp\n\tsubq.w %I%wd,%Rsp\n",
567 fsize_with_regs
- 8);
569 asm_fprintf (stream
, "\tsubqw %I8,%Rsp\n\tsubqw %I%wd,%Rsp\n",
570 fsize_with_regs
- 8);
573 else if (TARGET_68040
)
575 /* Adding negative number is faster on the 68040. */
576 /* asm_fprintf() cannot handle %. */
578 asm_fprintf (stream
, "\tadd.w %I%wd,%Rsp\n", -fsize_with_regs
);
580 asm_fprintf (stream
, "\taddw %I%wd,%Rsp\n", -fsize_with_regs
);
586 asm_fprintf (stream
, "\tlea (%wd,%Rsp),%Rsp\n", -fsize_with_regs
);
588 asm_fprintf (stream
, "\tlea %Rsp@(%wd),%Rsp\n", -fsize_with_regs
);
592 else /* fsize_with_regs >= 0x8000 */
595 asm_fprintf (stream
, "\tadd.l %I%wd,%Rsp\n", -fsize_with_regs
);
597 asm_fprintf (stream
, "\taddl %I%wd,%Rsp\n", -fsize_with_regs
);
600 if (dwarf2out_do_frame ())
602 cfa_offset
+= fsize
+ 4;
603 dwarf2out_def_cfa ("", STACK_POINTER_REGNUM
, cfa_offset
);
605 } /* !frame_pointer_needed */
611 for (regno
= 16; regno
< 24; regno
++)
612 if (m68k_save_reg (regno
, interrupt_handler
))
614 mask
|= 1 << (regno
- 16);
617 if ((mask
& 0xff) != 0)
620 asm_fprintf (stream
, "\tfmovm %I0x%x,-(%Rsp)\n", mask
& 0xff);
622 asm_fprintf (stream
, "\tfmovem %I0x%x,%Rsp@-\n", mask
& 0xff);
624 if (dwarf2out_do_frame ())
626 char *l
= (char *) dwarf2out_cfi_label ();
629 cfa_offset
+= num_saved_regs
* 12;
630 if (! frame_pointer_needed
)
631 dwarf2out_def_cfa (l
, STACK_POINTER_REGNUM
, cfa_offset
);
632 for (regno
= 16, n_regs
= 0; regno
< 24; regno
++)
633 if (mask
& (1 << (regno
- 16)))
634 dwarf2out_reg_save (l
, regno
,
635 -cfa_offset
+ n_regs
++ * 12);
641 for (regno
= 0; regno
< 16; regno
++)
642 if (m68k_save_reg (regno
, interrupt_handler
))
644 mask
|= 1 << (15 - regno
);
648 /* If the stack limit is not a symbol, check it here.
649 This has the disadvantage that it may be too late... */
650 if (current_function_limit_stack
)
652 if (REG_P (stack_limit_rtx
))
654 #if defined (MOTOROLA)
655 asm_fprintf (stream
, "\tcmp.l %s,%Rsp\n\ttrapcs\n",
656 reg_names
[REGNO (stack_limit_rtx
)]);
658 asm_fprintf (stream
, "\tcmpl %s,%Rsp\n\ttrapcs\n",
659 reg_names
[REGNO (stack_limit_rtx
)]);
662 else if (GET_CODE (stack_limit_rtx
) != SYMBOL_REF
)
663 warning ("stack limit expression is not supported");
666 if (num_saved_regs
<= 2)
668 /* Store each separately in the same order moveml uses.
669 Using two movel instructions instead of a single moveml
670 is about 15% faster for the 68020 and 68030 at no expense
675 /* Undo the work from above. */
676 for (i
= 0; i
< 16; i
++)
681 "\t%Omove.l %s,-(%Rsp)\n",
683 "\tmovel %s,%Rsp@-\n",
686 if (dwarf2out_do_frame ())
688 char *l
= (char *) dwarf2out_cfi_label ();
691 if (! frame_pointer_needed
)
692 dwarf2out_def_cfa (l
, STACK_POINTER_REGNUM
, cfa_offset
);
693 dwarf2out_reg_save (l
, 15 - i
, -cfa_offset
);
701 /* The coldfire does not support the predecrement form of the
702 movml instruction, so we must adjust the stack pointer and
703 then use the plain address register indirect mode. We also
704 have to invert the register save mask to use the new mode.
706 The required register save space was combined earlier with
707 the fsize amount. Don't add it again. */
712 for (i
= 0; i
< 16; i
++)
714 newmask
|= (1 << (15-i
));
717 asm_fprintf (stream
, "\tmovm.l %I0x%x,(%Rsp)\n", newmask
);
719 asm_fprintf (stream
, "\tmoveml %I0x%x,%Rsp@\n", newmask
);
725 asm_fprintf (stream
, "\tmovm.l %I0x%x,-(%Rsp)\n", mask
);
727 asm_fprintf (stream
, "\tmoveml %I0x%x,%Rsp@-\n", mask
);
730 if (dwarf2out_do_frame ())
732 char *l
= (char *) dwarf2out_cfi_label ();
735 cfa_offset
+= num_saved_regs
* 4;
736 if (! frame_pointer_needed
)
737 dwarf2out_def_cfa (l
, STACK_POINTER_REGNUM
, cfa_offset
);
738 for (regno
= 0, n_regs
= 0; regno
< 16; regno
++)
739 if (mask
& (1 << (15 - regno
)))
740 dwarf2out_reg_save (l
, regno
,
741 -cfa_offset
+ n_regs
++ * 4);
744 if (!TARGET_SEP_DATA
&& flag_pic
&&
745 (current_function_uses_pic_offset_table
||
746 (!current_function_is_leaf
&& TARGET_ID_SHARED_LIBRARY
)))
748 if (TARGET_ID_SHARED_LIBRARY
)
750 asm_fprintf (stream
, "\tmovel %s@(%s), %s\n",
751 reg_names
[PIC_OFFSET_TABLE_REGNUM
],
752 m68k_library_id_string
,
753 reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
758 asm_fprintf (stream
, "\t%Olea (%Rpc, %U_GLOBAL_OFFSET_TABLE_@GOTPC), %s\n",
759 reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
761 asm_fprintf (stream
, "\tmovel %I%U_GLOBAL_OFFSET_TABLE_, %s\n",
762 reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
763 asm_fprintf (stream
, "\tlea %Rpc@(0,%s:l),%s\n",
764 reg_names
[PIC_OFFSET_TABLE_REGNUM
],
765 reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
771 /* Return true if this function's epilogue can be output as RTL. */
777 bool interrupt_handler
;
779 if (!reload_completed
|| frame_pointer_needed
|| get_frame_size () != 0)
782 interrupt_handler
= m68k_interrupt_function_p (current_function_decl
);
784 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
785 if (m68k_save_reg (regno
, interrupt_handler
))
791 /* This function generates the assembly code for function exit,
792 on machines that need it.
794 The function epilogue should not depend on the current stack pointer!
795 It should use the frame pointer only, if there is a frame pointer.
796 This is mandatory because of alloca; we also take advantage of it to
797 omit stack adjustments before returning. */
800 m68k_output_function_epilogue (FILE *stream
, HOST_WIDE_INT size
)
803 register int mask
, fmask
;
805 HOST_WIDE_INT offset
, foffset
;
806 HOST_WIDE_INT fsize
= (size
+ 3) & -4;
807 HOST_WIDE_INT fsize_with_regs
;
809 rtx insn
= get_last_insn ();
810 int restore_from_sp
= 0;
811 bool interrupt_handler
= m68k_interrupt_function_p (current_function_decl
);
813 /* If the last insn was a BARRIER, we don't have to write any code. */
814 if (GET_CODE (insn
) == NOTE
)
815 insn
= prev_nonnote_insn (insn
);
816 if (insn
&& GET_CODE (insn
) == BARRIER
)
818 /* Output just a no-op so that debuggers don't get confused
819 about which function the pc is in at this address. */
820 fprintf (stream
, "\tnop\n");
824 #ifdef FUNCTION_EXTRA_EPILOGUE
825 FUNCTION_EXTRA_EPILOGUE (stream
, size
);
827 nregs
= 0; fmask
= 0;
830 for (regno
= 16; regno
< 24; regno
++)
831 if (m68k_save_reg (regno
, interrupt_handler
))
834 fmask
|= 1 << (23 - regno
);
837 foffset
= nregs
* 12;
839 for (regno
= 0; regno
< 16; regno
++)
840 if (m68k_save_reg (regno
, interrupt_handler
))
845 offset
= foffset
+ nregs
* 4;
846 /* FIXME : leaf_function_p below is too strong.
847 What we really need to know there is if there could be pending
848 stack adjustment needed at that point. */
849 restore_from_sp
= ! frame_pointer_needed
850 || (! current_function_calls_alloca
&& leaf_function_p ());
852 /* fsize_with_regs is the size we need to adjust the sp when
854 fsize_with_regs
= fsize
;
856 /* Because the ColdFire doesn't support moveml with
857 complex address modes, we must adjust the stack manually
858 after restoring registers. When the frame pointer isn't used,
859 we can merge movem adjustment into frame unlinking
860 made immediately after it. */
861 if (TARGET_COLDFIRE
&& restore_from_sp
&& (nregs
> 2))
862 fsize_with_regs
+= nregs
* 4;
864 if (offset
+ fsize
>= 0x8000
868 /* Because the ColdFire doesn't support moveml with
869 complex address modes we make an extra correction here */
873 asm_fprintf (stream
, "\t%Omove.l %I%d,%Ra1\n", -fsize
- offset
);
875 asm_fprintf (stream
, "\tmovel %I%d,%Ra1\n", -fsize
- offset
);
881 asm_fprintf (stream
, "\t%Omove.l %I%wd,%Ra1\n", -fsize
);
883 asm_fprintf (stream
, "\tmovel %I%wd,%Ra1\n", -fsize
);
891 /* Restore each separately in the same order moveml does.
892 Using two movel instructions instead of a single moveml
893 is about 15% faster for the 68020 and 68030 at no expense
898 /* Undo the work from above. */
899 for (i
= 0; i
< 16; i
++)
905 asm_fprintf (stream
, "\t%Omove.l -%wd(%s,%Ra1.l),%s\n",
907 reg_names
[FRAME_POINTER_REGNUM
],
910 asm_fprintf (stream
, "\tmovel %s@(-%wd,%Ra1:l),%s\n",
911 reg_names
[FRAME_POINTER_REGNUM
],
912 offset
+ fsize
, reg_names
[i
]);
915 else if (restore_from_sp
)
918 asm_fprintf (stream
, "\t%Omove.l (%Rsp)+,%s\n",
921 asm_fprintf (stream
, "\tmovel %Rsp@+,%s\n",
928 asm_fprintf (stream
, "\t%Omove.l -%wd(%s),%s\n",
930 reg_names
[FRAME_POINTER_REGNUM
],
933 asm_fprintf (stream
, "\tmovel %s@(-%wd),%s\n",
934 reg_names
[FRAME_POINTER_REGNUM
],
935 offset
+ fsize
, reg_names
[i
]);
943 /* The ColdFire requires special handling due to its limited moveml insn */
949 asm_fprintf (stream
, "\tadd.l %s,%Ra1\n", reg_names
[FRAME_POINTER_REGNUM
]);
950 asm_fprintf (stream
, "\tmovm.l (%Ra1),%I0x%x\n", mask
);
952 asm_fprintf (stream
, "\taddl %s,%Ra1\n", reg_names
[FRAME_POINTER_REGNUM
]);
953 asm_fprintf (stream
, "\tmoveml %Ra1@,%I0x%x\n", mask
);
956 else if (restore_from_sp
)
959 asm_fprintf (stream
, "\tmovm.l (%Rsp),%I0x%x\n", mask
);
961 asm_fprintf (stream
, "\tmoveml %Rsp@,%I0x%x\n", mask
);
967 asm_fprintf (stream
, "\tmovm.l -%wd(%s),%I0x%x\n",
969 reg_names
[FRAME_POINTER_REGNUM
],
972 asm_fprintf (stream
, "\tmoveml %s@(-%wd),%I0x%x\n",
973 reg_names
[FRAME_POINTER_REGNUM
],
974 offset
+ fsize
, mask
);
978 else /* !TARGET_COLDFIRE */
983 asm_fprintf (stream
, "\tmovm.l -%wd(%s,%Ra1.l),%I0x%x\n",
985 reg_names
[FRAME_POINTER_REGNUM
],
988 asm_fprintf (stream
, "\tmoveml %s@(-%wd,%Ra1:l),%I0x%x\n",
989 reg_names
[FRAME_POINTER_REGNUM
],
990 offset
+ fsize
, mask
);
993 else if (restore_from_sp
)
996 asm_fprintf (stream
, "\tmovm.l (%Rsp)+,%I0x%x\n", mask
);
998 asm_fprintf (stream
, "\tmoveml %Rsp@+,%I0x%x\n", mask
);
1004 asm_fprintf (stream
, "\tmovm.l -%wd(%s),%I0x%x\n",
1006 reg_names
[FRAME_POINTER_REGNUM
],
1009 asm_fprintf (stream
, "\tmoveml %s@(-%wd),%I0x%x\n",
1010 reg_names
[FRAME_POINTER_REGNUM
],
1011 offset
+ fsize
, mask
);
1021 asm_fprintf (stream
, "\tfmovm -%wd(%s,%Ra1.l),%I0x%x\n",
1023 reg_names
[FRAME_POINTER_REGNUM
],
1026 asm_fprintf (stream
, "\tfmovem %s@(-%wd,%Ra1:l),%I0x%x\n",
1027 reg_names
[FRAME_POINTER_REGNUM
],
1028 foffset
+ fsize
, fmask
);
1031 else if (restore_from_sp
)
1034 asm_fprintf (stream
, "\tfmovm (%Rsp)+,%I0x%x\n", fmask
);
1036 asm_fprintf (stream
, "\tfmovem %Rsp@+,%I0x%x\n", fmask
);
1042 asm_fprintf (stream
, "\tfmovm -%wd(%s),%I0x%x\n",
1044 reg_names
[FRAME_POINTER_REGNUM
],
1047 asm_fprintf (stream
, "\tfmovem %s@(-%wd),%I0x%x\n",
1048 reg_names
[FRAME_POINTER_REGNUM
],
1049 foffset
+ fsize
, fmask
);
1053 if (frame_pointer_needed
)
1054 fprintf (stream
, "\tunlk %s\n",
1055 reg_names
[FRAME_POINTER_REGNUM
]);
1056 else if (fsize_with_regs
)
1058 if (fsize_with_regs
<= 8)
1060 if (!TARGET_COLDFIRE
)
1063 asm_fprintf (stream
, "\taddq.w %I%wd,%Rsp\n", fsize_with_regs
);
1065 asm_fprintf (stream
, "\taddqw %I%wd,%Rsp\n", fsize_with_regs
);
1068 else /* TARGET_COLDFIRE */
1071 asm_fprintf (stream
, "\taddq.l %I%wd,%Rsp\n", fsize_with_regs
);
1073 asm_fprintf (stream
, "\taddql %I%wd,%Rsp\n", fsize_with_regs
);
1077 else if (fsize_with_regs
<= 16 && TARGET_CPU32
)
1079 /* On the CPU32 it is faster to use two addqw instructions to
1080 add a small integer (8 < N <= 16) to a register. */
1081 /* asm_fprintf() cannot handle %. */
1083 asm_fprintf (stream
, "\taddq.w %I8,%Rsp\n\taddq.w %I%wd,%Rsp\n",
1084 fsize_with_regs
- 8);
1086 asm_fprintf (stream
, "\taddqw %I8,%Rsp\n\taddqw %I%wd,%Rsp\n",
1087 fsize_with_regs
- 8);
1090 else if (fsize_with_regs
< 0x8000)
1094 /* asm_fprintf() cannot handle %. */
1096 asm_fprintf (stream
, "\tadd.w %I%wd,%Rsp\n", fsize_with_regs
);
1098 asm_fprintf (stream
, "\taddw %I%wd,%Rsp\n", fsize_with_regs
);
1104 asm_fprintf (stream
, "\tlea (%wd,%Rsp),%Rsp\n", fsize_with_regs
);
1106 asm_fprintf (stream
, "\tlea %Rsp@(%wd),%Rsp\n", fsize_with_regs
);
1112 /* asm_fprintf() cannot handle %. */
1114 asm_fprintf (stream
, "\tadd.l %I%wd,%Rsp\n", fsize_with_regs
);
1116 asm_fprintf (stream
, "\taddl %I%wd,%Rsp\n", fsize_with_regs
);
1120 if (current_function_calls_eh_return
)
1123 asm_fprintf (stream
, "\tadd.l %Ra0,%Rsp\n");
1125 asm_fprintf (stream
, "\taddl %Ra0,%Rsp\n");
1128 if (interrupt_handler
)
1129 fprintf (stream
, "\trte\n");
1130 else if (current_function_pops_args
)
1131 asm_fprintf (stream
, "\trtd %I%d\n", current_function_pops_args
);
1133 fprintf (stream
, "\trts\n");
1136 /* Similar to general_operand, but exclude stack_pointer_rtx. */
1139 not_sp_operand (rtx op
, enum machine_mode mode
)
1141 return op
!= stack_pointer_rtx
&& nonimmediate_operand (op
, mode
);
1144 /* Return true if X is a valid comparison operator for the dbcc
1147 Note it rejects floating point comparison operators.
1148 (In the future we could use Fdbcc).
1150 It also rejects some comparisons when CC_NO_OVERFLOW is set. */
1153 valid_dbcc_comparison_p (rtx x
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1155 switch (GET_CODE (x
))
1157 case EQ
: case NE
: case GTU
: case LTU
:
1161 /* Reject some when CC_NO_OVERFLOW is set. This may be over
1163 case GT
: case LT
: case GE
: case LE
:
1164 return ! (cc_prev_status
.flags
& CC_NO_OVERFLOW
);
1170 /* Return nonzero if flags are currently in the 68881 flag register. */
1172 flags_in_68881 (void)
1174 /* We could add support for these in the future */
1175 return cc_status
.flags
& CC_IN_68881
;
1178 /* Output a BSR instruction suitable for PIC code. */
1180 m68k_output_pic_call(rtx dest
)
1184 if (!(GET_CODE (dest
) == MEM
&& GET_CODE (XEXP (dest
, 0)) == SYMBOL_REF
))
1186 /* We output a BSR instruction if we've using -fpic or we're building for
1187 * a target that supports long branches. If we're building -fPIC on the
1188 * 68000, 68010 or ColdFire we generate one of two sequences:
1189 * a shorter one that uses a GOT entry or a longer one that doesn't.
1190 * We'll use the -Os command-line flag to decide which to generate.
1191 * Both sequences take the same time to execute on the ColdFire.
1193 else if (TARGET_PCREL
)
1195 else if ((flag_pic
== 1) || TARGET_68020
)
1198 #elif defined(USE_GAS)
1199 out
= "bsr.l %0@PLTPC";
1201 out
= "bsr %0@PLTPC";
1203 else if (optimize_size
|| TARGET_ID_SHARED_LIBRARY
)
1204 out
= "move.l %0@GOT(%%a5), %%a1\n\tjsr (%%a1)";
1206 out
= "lea %0-.-8,%%a1\n\tjsr 0(%%pc,%%a1)";
1208 output_asm_insn(out
, &dest
);
1211 /* Output a dbCC; jCC sequence. Note we do not handle the
1212 floating point version of this sequence (Fdbcc). We also
1213 do not handle alternative conditions when CC_NO_OVERFLOW is
1214 set. It is assumed that valid_dbcc_comparison_p and flags_in_68881 will
1215 kick those out before we get here. */
1218 output_dbcc_and_branch (rtx
*operands
)
1220 switch (GET_CODE (operands
[3]))
1224 output_asm_insn ("dbeq %0,%l1\n\tjbeq %l2", operands
);
1226 output_asm_insn ("dbeq %0,%l1\n\tjeq %l2", operands
);
1232 output_asm_insn ("dbne %0,%l1\n\tjbne %l2", operands
);
1234 output_asm_insn ("dbne %0,%l1\n\tjne %l2", operands
);
1240 output_asm_insn ("dbgt %0,%l1\n\tjbgt %l2", operands
);
1242 output_asm_insn ("dbgt %0,%l1\n\tjgt %l2", operands
);
1248 output_asm_insn ("dbhi %0,%l1\n\tjbhi %l2", operands
);
1250 output_asm_insn ("dbhi %0,%l1\n\tjhi %l2", operands
);
1256 output_asm_insn ("dblt %0,%l1\n\tjblt %l2", operands
);
1258 output_asm_insn ("dblt %0,%l1\n\tjlt %l2", operands
);
1264 output_asm_insn ("dbcs %0,%l1\n\tjbcs %l2", operands
);
1266 output_asm_insn ("dbcs %0,%l1\n\tjcs %l2", operands
);
1272 output_asm_insn ("dbge %0,%l1\n\tjbge %l2", operands
);
1274 output_asm_insn ("dbge %0,%l1\n\tjge %l2", operands
);
1280 output_asm_insn ("dbcc %0,%l1\n\tjbcc %l2", operands
);
1282 output_asm_insn ("dbcc %0,%l1\n\tjcc %l2", operands
);
1288 output_asm_insn ("dble %0,%l1\n\tjble %l2", operands
);
1290 output_asm_insn ("dble %0,%l1\n\tjle %l2", operands
);
1296 output_asm_insn ("dbls %0,%l1\n\tjbls %l2", operands
);
1298 output_asm_insn ("dbls %0,%l1\n\tjls %l2", operands
);
1306 /* If the decrement is to be done in SImode, then we have
1307 to compensate for the fact that dbcc decrements in HImode. */
1308 switch (GET_MODE (operands
[0]))
1312 output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjbpl %l1", operands
);
1314 output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjpl %l1", operands
);
1327 output_scc_di(rtx op
, rtx operand1
, rtx operand2
, rtx dest
)
1330 enum rtx_code op_code
= GET_CODE (op
);
1332 /* This does not produce a useful cc. */
1335 /* The m68k cmp.l instruction requires operand1 to be a reg as used
1336 below. Swap the operands and change the op if these requirements
1337 are not fulfilled. */
1338 if (GET_CODE (operand2
) == REG
&& GET_CODE (operand1
) != REG
)
1342 operand1
= operand2
;
1344 op_code
= swap_condition (op_code
);
1346 loperands
[0] = operand1
;
1347 if (GET_CODE (operand1
) == REG
)
1348 loperands
[1] = gen_rtx_REG (SImode
, REGNO (operand1
) + 1);
1350 loperands
[1] = adjust_address (operand1
, SImode
, 4);
1351 if (operand2
!= const0_rtx
)
1353 loperands
[2] = operand2
;
1354 if (GET_CODE (operand2
) == REG
)
1355 loperands
[3] = gen_rtx_REG (SImode
, REGNO (operand2
) + 1);
1357 loperands
[3] = adjust_address (operand2
, SImode
, 4);
1359 loperands
[4] = gen_label_rtx();
1360 if (operand2
!= const0_rtx
)
1363 #ifdef SGS_CMP_ORDER
1364 output_asm_insn ("cmp%.l %0,%2\n\tjbne %l4\n\tcmp%.l %1,%3", loperands
);
1366 output_asm_insn ("cmp%.l %2,%0\n\tjbne %l4\n\tcmp%.l %3,%1", loperands
);
1369 #ifdef SGS_CMP_ORDER
1370 output_asm_insn ("cmp%.l %0,%2\n\tjne %l4\n\tcmp%.l %1,%3", loperands
);
1372 output_asm_insn ("cmp%.l %2,%0\n\tjne %l4\n\tcmp%.l %3,%1", loperands
);
1378 if (TARGET_68020
|| TARGET_COLDFIRE
|| ! ADDRESS_REG_P (loperands
[0]))
1379 output_asm_insn ("tst%.l %0", loperands
);
1382 #ifdef SGS_CMP_ORDER
1383 output_asm_insn ("cmp%.w %0,%#0", loperands
);
1385 output_asm_insn ("cmp%.w %#0,%0", loperands
);
1390 output_asm_insn ("jbne %l4", loperands
);
1392 output_asm_insn ("jne %l4", loperands
);
1395 if (TARGET_68020
|| TARGET_COLDFIRE
|| ! ADDRESS_REG_P (loperands
[1]))
1396 output_asm_insn ("tst%.l %1", loperands
);
1399 #ifdef SGS_CMP_ORDER
1400 output_asm_insn ("cmp%.w %1,%#0", loperands
);
1402 output_asm_insn ("cmp%.w %#0,%1", loperands
);
1407 loperands
[5] = dest
;
1412 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1413 CODE_LABEL_NUMBER (loperands
[4]));
1414 output_asm_insn ("seq %5", loperands
);
1418 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1419 CODE_LABEL_NUMBER (loperands
[4]));
1420 output_asm_insn ("sne %5", loperands
);
1424 loperands
[6] = gen_label_rtx();
1426 output_asm_insn ("shi %5\n\tjbra %l6", loperands
);
1428 output_asm_insn ("shi %5\n\tjra %l6", loperands
);
1430 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1431 CODE_LABEL_NUMBER (loperands
[4]));
1432 output_asm_insn ("sgt %5", loperands
);
1433 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1434 CODE_LABEL_NUMBER (loperands
[6]));
1438 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1439 CODE_LABEL_NUMBER (loperands
[4]));
1440 output_asm_insn ("shi %5", loperands
);
1444 loperands
[6] = gen_label_rtx();
1446 output_asm_insn ("scs %5\n\tjbra %l6", loperands
);
1448 output_asm_insn ("scs %5\n\tjra %l6", loperands
);
1450 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1451 CODE_LABEL_NUMBER (loperands
[4]));
1452 output_asm_insn ("slt %5", loperands
);
1453 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1454 CODE_LABEL_NUMBER (loperands
[6]));
1458 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1459 CODE_LABEL_NUMBER (loperands
[4]));
1460 output_asm_insn ("scs %5", loperands
);
1464 loperands
[6] = gen_label_rtx();
1466 output_asm_insn ("scc %5\n\tjbra %l6", loperands
);
1468 output_asm_insn ("scc %5\n\tjra %l6", loperands
);
1470 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1471 CODE_LABEL_NUMBER (loperands
[4]));
1472 output_asm_insn ("sge %5", loperands
);
1473 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1474 CODE_LABEL_NUMBER (loperands
[6]));
1478 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1479 CODE_LABEL_NUMBER (loperands
[4]));
1480 output_asm_insn ("scc %5", loperands
);
1484 loperands
[6] = gen_label_rtx();
1486 output_asm_insn ("sls %5\n\tjbra %l6", loperands
);
1488 output_asm_insn ("sls %5\n\tjra %l6", loperands
);
1490 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1491 CODE_LABEL_NUMBER (loperands
[4]));
1492 output_asm_insn ("sle %5", loperands
);
1493 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1494 CODE_LABEL_NUMBER (loperands
[6]));
1498 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1499 CODE_LABEL_NUMBER (loperands
[4]));
1500 output_asm_insn ("sls %5", loperands
);
1510 output_btst (rtx
*operands
, rtx countop
, rtx dataop
, rtx insn
, int signpos
)
1512 operands
[0] = countop
;
1513 operands
[1] = dataop
;
1515 if (GET_CODE (countop
) == CONST_INT
)
1517 register int count
= INTVAL (countop
);
1518 /* If COUNT is bigger than size of storage unit in use,
1519 advance to the containing unit of same size. */
1520 if (count
> signpos
)
1522 int offset
= (count
& ~signpos
) / 8;
1523 count
= count
& signpos
;
1524 operands
[1] = dataop
= adjust_address (dataop
, QImode
, offset
);
1526 if (count
== signpos
)
1527 cc_status
.flags
= CC_NOT_POSITIVE
| CC_Z_IN_NOT_N
;
1529 cc_status
.flags
= CC_NOT_NEGATIVE
| CC_Z_IN_NOT_N
;
1531 /* These three statements used to use next_insns_test_no...
1532 but it appears that this should do the same job. */
1534 && next_insn_tests_no_inequality (insn
))
1537 && next_insn_tests_no_inequality (insn
))
1540 && next_insn_tests_no_inequality (insn
))
1543 cc_status
.flags
= CC_NOT_NEGATIVE
;
1545 return "btst %0,%1";
1548 /* Returns true if OP is either a symbol reference or a sum of a symbol
1549 reference and a constant. */
1552 symbolic_operand (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1554 switch (GET_CODE (op
))
1562 return ((GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
1563 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
)
1564 && GET_CODE (XEXP (op
, 1)) == CONST_INT
);
1566 #if 0 /* Deleted, with corresponding change in m68k.h,
1567 so as to fit the specs. No CONST_DOUBLE is ever symbolic. */
1569 return GET_MODE (op
) == mode
;
1577 /* Check for sign_extend or zero_extend. Used for bit-count operands. */
1580 extend_operator(rtx x
, enum machine_mode mode
)
1582 if (mode
!= VOIDmode
&& GET_MODE(x
) != mode
)
1584 switch (GET_CODE(x
))
1595 /* Legitimize PIC addresses. If the address is already
1596 position-independent, we return ORIG. Newly generated
1597 position-independent addresses go to REG. If we need more
1598 than one register, we lose.
1600 An address is legitimized by making an indirect reference
1601 through the Global Offset Table with the name of the symbol
1604 The assembler and linker are responsible for placing the
1605 address of the symbol in the GOT. The function prologue
1606 is responsible for initializing a5 to the starting address
1609 The assembler is also responsible for translating a symbol name
1610 into a constant displacement from the start of the GOT.
1612 A quick example may make things a little clearer:
1614 When not generating PIC code to store the value 12345 into _foo
1615 we would generate the following code:
1619 When generating PIC two transformations are made. First, the compiler
1620 loads the address of foo into a register. So the first transformation makes:
1625 The code in movsi will intercept the lea instruction and call this
1626 routine which will transform the instructions into:
1628 movel a5@(_foo:w), a0
1632 That (in a nutshell) is how *all* symbol and label references are
1636 legitimize_pic_address (rtx orig
, enum machine_mode mode ATTRIBUTE_UNUSED
,
1641 /* First handle a simple SYMBOL_REF or LABEL_REF */
1642 if (GET_CODE (orig
) == SYMBOL_REF
|| GET_CODE (orig
) == LABEL_REF
)
1647 pic_ref
= gen_rtx_MEM (Pmode
,
1648 gen_rtx_PLUS (Pmode
,
1649 pic_offset_table_rtx
, orig
));
1650 current_function_uses_pic_offset_table
= 1;
1651 RTX_UNCHANGING_P (pic_ref
) = 1;
1652 emit_move_insn (reg
, pic_ref
);
1655 else if (GET_CODE (orig
) == CONST
)
1659 /* Make sure this is CONST has not already been legitimized */
1660 if (GET_CODE (XEXP (orig
, 0)) == PLUS
1661 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
1667 /* legitimize both operands of the PLUS */
1668 if (GET_CODE (XEXP (orig
, 0)) == PLUS
)
1670 base
= legitimize_pic_address (XEXP (XEXP (orig
, 0), 0), Pmode
, reg
);
1671 orig
= legitimize_pic_address (XEXP (XEXP (orig
, 0), 1), Pmode
,
1672 base
== reg
? 0 : reg
);
1676 if (GET_CODE (orig
) == CONST_INT
)
1677 return plus_constant (base
, INTVAL (orig
));
1678 pic_ref
= gen_rtx_PLUS (Pmode
, base
, orig
);
1679 /* Likewise, should we set special REG_NOTEs here? */
1685 typedef enum { MOVL
, SWAP
, NEGW
, NOTW
, NOTB
, MOVQ
} CONST_METHOD
;
1687 static CONST_METHOD
const_method (rtx
);
1689 #define USE_MOVQ(i) ((unsigned)((i) + 128) <= 255)
1692 const_method (rtx constant
)
1697 i
= INTVAL (constant
);
1701 /* The Coldfire doesn't have byte or word operations. */
1702 /* FIXME: This may not be useful for the m68060 either */
1703 if (!TARGET_COLDFIRE
)
1705 /* if -256 < N < 256 but N is not in range for a moveq
1706 N^ff will be, so use moveq #N^ff, dreg; not.b dreg. */
1707 if (USE_MOVQ (i
^ 0xff))
1709 /* Likewise, try with not.w */
1710 if (USE_MOVQ (i
^ 0xffff))
1712 /* This is the only value where neg.w is useful */
1715 /* Try also with swap */
1717 if (USE_MOVQ ((u
>> 16) | (u
<< 16)))
1720 /* Otherwise, use move.l */
1725 const_int_cost (rtx constant
)
1727 switch (const_method (constant
))
1730 /* Constants between -128 and 127 are cheap due to moveq */
1736 /* Constants easily generated by moveq + not.b/not.w/neg.w/swap */
1746 m68k_rtx_costs (rtx x
, int code
, int outer_code
, int *total
)
1751 /* Constant zero is super cheap due to clr instruction. */
1752 if (x
== const0_rtx
)
1755 *total
= const_int_cost (x
);
1765 /* Make 0.0 cheaper than other floating constants to
1766 encourage creating tstsf and tstdf insns. */
1767 if (outer_code
== COMPARE
1768 && (x
== CONST0_RTX (SFmode
) || x
== CONST0_RTX (DFmode
)))
1774 /* These are vaguely right for a 68020. */
1775 /* The costs for long multiply have been adjusted to work properly
1776 in synth_mult on the 68020, relative to an average of the time
1777 for add and the time for shift, taking away a little more because
1778 sometimes move insns are needed. */
1779 /* div?.w is relatively cheaper on 68000 counted in COSTS_N_INSNS terms. */
1780 #define MULL_COST (TARGET_68060 ? 2 : TARGET_68040 ? 5 : TARGET_CFV3 ? 3 : TARGET_COLDFIRE ? 10 : 13)
1781 #define MULW_COST (TARGET_68060 ? 2 : TARGET_68040 ? 3 : TARGET_68020 ? 8 : \
1782 TARGET_CFV3 ? 2 : 5)
1783 #define DIVW_COST (TARGET_68020 ? 27 : TARGET_CF_HWDIV ? 11 : 12)
1786 /* An lea costs about three times as much as a simple add. */
1787 if (GET_MODE (x
) == SImode
1788 && GET_CODE (XEXP (x
, 1)) == REG
1789 && GET_CODE (XEXP (x
, 0)) == MULT
1790 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
1791 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
1792 && (INTVAL (XEXP (XEXP (x
, 0), 1)) == 2
1793 || INTVAL (XEXP (XEXP (x
, 0), 1)) == 4
1794 || INTVAL (XEXP (XEXP (x
, 0), 1)) == 8))
1796 /* lea an@(dx:l:i),am */
1797 *total
= COSTS_N_INSNS (TARGET_COLDFIRE
? 2 : 3);
1807 *total
= COSTS_N_INSNS(1);
1810 if (! TARGET_68020
&& ! TARGET_COLDFIRE
)
1812 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
1814 if (INTVAL (XEXP (x
, 1)) < 16)
1815 *total
= COSTS_N_INSNS (2) + INTVAL (XEXP (x
, 1)) / 2;
1817 /* We're using clrw + swap for these cases. */
1818 *total
= COSTS_N_INSNS (4) + (INTVAL (XEXP (x
, 1)) - 16) / 2;
1821 *total
= COSTS_N_INSNS (10); /* worst case */
1824 /* A shift by a big integer takes an extra instruction. */
1825 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
1826 && (INTVAL (XEXP (x
, 1)) == 16))
1828 *total
= COSTS_N_INSNS (2); /* clrw;swap */
1831 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
1832 && !(INTVAL (XEXP (x
, 1)) > 0
1833 && INTVAL (XEXP (x
, 1)) <= 8))
1835 *total
= COSTS_N_INSNS (TARGET_COLDFIRE
? 1 : 3); /* lsr #i,dn */
1841 if ((GET_CODE (XEXP (x
, 0)) == ZERO_EXTEND
1842 || GET_CODE (XEXP (x
, 0)) == SIGN_EXTEND
)
1843 && GET_MODE (x
) == SImode
)
1844 *total
= COSTS_N_INSNS (MULW_COST
);
1845 else if (GET_MODE (x
) == QImode
|| GET_MODE (x
) == HImode
)
1846 *total
= COSTS_N_INSNS (MULW_COST
);
1848 *total
= COSTS_N_INSNS (MULL_COST
);
1855 if (GET_MODE (x
) == QImode
|| GET_MODE (x
) == HImode
)
1856 *total
= COSTS_N_INSNS (DIVW_COST
); /* div.w */
1857 else if (TARGET_CF_HWDIV
)
1858 *total
= COSTS_N_INSNS (18);
1860 *total
= COSTS_N_INSNS (43); /* div.l */
1869 output_move_const_into_data_reg (rtx
*operands
)
1873 i
= INTVAL (operands
[1]);
1874 switch (const_method (operands
[1]))
1877 return "moveq %1,%0";
1879 operands
[1] = GEN_INT (i
^ 0xff);
1880 return "moveq %1,%0\n\tnot%.b %0";
1882 operands
[1] = GEN_INT (i
^ 0xffff);
1883 return "moveq %1,%0\n\tnot%.w %0";
1885 return "moveq %#-128,%0\n\tneg%.w %0";
1890 operands
[1] = GEN_INT ((u
<< 16) | (u
>> 16));
1891 return "moveq %1,%0\n\tswap %0";
1894 return "move%.l %1,%0";
1901 output_move_simode_const (rtx
*operands
)
1903 if (operands
[1] == const0_rtx
1904 && (DATA_REG_P (operands
[0])
1905 || GET_CODE (operands
[0]) == MEM
)
1906 /* clr insns on 68000 read before writing.
1907 This isn't so on the 68010, but we have no TARGET_68010. */
1908 && ((TARGET_68020
|| TARGET_COLDFIRE
)
1909 || !(GET_CODE (operands
[0]) == MEM
1910 && MEM_VOLATILE_P (operands
[0]))))
1912 else if (operands
[1] == const0_rtx
1913 && ADDRESS_REG_P (operands
[0]))
1914 return "sub%.l %0,%0";
1915 else if (DATA_REG_P (operands
[0]))
1916 return output_move_const_into_data_reg (operands
);
1917 else if (ADDRESS_REG_P (operands
[0])
1918 && INTVAL (operands
[1]) < 0x8000
1919 && INTVAL (operands
[1]) >= -0x8000)
1920 return "move%.w %1,%0";
1921 else if (GET_CODE (operands
[0]) == MEM
1922 && GET_CODE (XEXP (operands
[0], 0)) == PRE_DEC
1923 && REGNO (XEXP (XEXP (operands
[0], 0), 0)) == STACK_POINTER_REGNUM
1924 && INTVAL (operands
[1]) < 0x8000
1925 && INTVAL (operands
[1]) >= -0x8000)
1927 return "move%.l %1,%0";
1931 output_move_simode (rtx
*operands
)
1933 if (GET_CODE (operands
[1]) == CONST_INT
)
1934 return output_move_simode_const (operands
);
1935 else if ((GET_CODE (operands
[1]) == SYMBOL_REF
1936 || GET_CODE (operands
[1]) == CONST
)
1937 && push_operand (operands
[0], SImode
))
1939 else if ((GET_CODE (operands
[1]) == SYMBOL_REF
1940 || GET_CODE (operands
[1]) == CONST
)
1941 && ADDRESS_REG_P (operands
[0]))
1942 return "lea %a1,%0";
1943 return "move%.l %1,%0";
1947 output_move_himode (rtx
*operands
)
1949 if (GET_CODE (operands
[1]) == CONST_INT
)
1951 if (operands
[1] == const0_rtx
1952 && (DATA_REG_P (operands
[0])
1953 || GET_CODE (operands
[0]) == MEM
)
1954 /* clr insns on 68000 read before writing.
1955 This isn't so on the 68010, but we have no TARGET_68010. */
1956 && ((TARGET_68020
|| TARGET_COLDFIRE
)
1957 || !(GET_CODE (operands
[0]) == MEM
1958 && MEM_VOLATILE_P (operands
[0]))))
1960 else if (operands
[1] == const0_rtx
1961 && ADDRESS_REG_P (operands
[0]))
1962 return "sub%.l %0,%0";
1963 else if (DATA_REG_P (operands
[0])
1964 && INTVAL (operands
[1]) < 128
1965 && INTVAL (operands
[1]) >= -128)
1967 return "moveq %1,%0";
1969 else if (INTVAL (operands
[1]) < 0x8000
1970 && INTVAL (operands
[1]) >= -0x8000)
1971 return "move%.w %1,%0";
1973 else if (CONSTANT_P (operands
[1]))
1974 return "move%.l %1,%0";
1975 /* Recognize the insn before a tablejump, one that refers
1976 to a table of offsets. Such an insn will need to refer
1977 to a label on the insn. So output one. Use the label-number
1978 of the table of offsets to generate this label. This code,
1979 and similar code below, assumes that there will be at most one
1980 reference to each table. */
1981 if (GET_CODE (operands
[1]) == MEM
1982 && GET_CODE (XEXP (operands
[1], 0)) == PLUS
1983 && GET_CODE (XEXP (XEXP (operands
[1], 0), 1)) == LABEL_REF
1984 && GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) != PLUS
)
1986 rtx labelref
= XEXP (XEXP (operands
[1], 0), 1);
1987 #if defined (MOTOROLA) && !defined (SGS_SWITCH_TABLES)
1989 asm_fprintf (asm_out_file
, "\tset %LLI%d,.+2\n",
1990 CODE_LABEL_NUMBER (XEXP (labelref
, 0)));
1992 asm_fprintf (asm_out_file
, "\t.set %LLI%d,.+2\n",
1993 CODE_LABEL_NUMBER (XEXP (labelref
, 0)));
1994 #endif /* not SGS */
1995 #else /* SGS_SWITCH_TABLES or not MOTOROLA */
1996 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "LI",
1997 CODE_LABEL_NUMBER (XEXP (labelref
, 0)));
1998 #ifdef SGS_SWITCH_TABLES
1999 /* Set flag saying we need to define the symbol
2000 LD%n (with value L%n-LI%n) at the end of the switch table. */
2001 switch_table_difference_label_flag
= 1;
2002 #endif /* SGS_SWITCH_TABLES */
2003 #endif /* SGS_SWITCH_TABLES or not MOTOROLA */
2005 return "move%.w %1,%0";
2009 output_move_qimode (rtx
*operands
)
2013 /* This is probably useless, since it loses for pushing a struct
2014 of several bytes a byte at a time. */
2015 /* 68k family always modifies the stack pointer by at least 2, even for
2016 byte pushes. The 5200 (coldfire) does not do this. */
2017 if (GET_CODE (operands
[0]) == MEM
2018 && GET_CODE (XEXP (operands
[0], 0)) == PRE_DEC
2019 && XEXP (XEXP (operands
[0], 0), 0) == stack_pointer_rtx
2020 && ! ADDRESS_REG_P (operands
[1])
2021 && ! TARGET_COLDFIRE
)
2023 xoperands
[1] = operands
[1];
2025 = gen_rtx_MEM (QImode
,
2026 gen_rtx_PLUS (VOIDmode
, stack_pointer_rtx
, const1_rtx
));
2027 /* Just pushing a byte puts it in the high byte of the halfword. */
2028 /* We must put it in the low-order, high-numbered byte. */
2029 if (!reg_mentioned_p (stack_pointer_rtx
, operands
[1]))
2031 xoperands
[3] = stack_pointer_rtx
;
2032 output_asm_insn ("subq%.l %#2,%3\n\tmove%.b %1,%2", xoperands
);
2035 output_asm_insn ("move%.b %1,%-\n\tmove%.b %@,%2", xoperands
);
2039 /* clr and st insns on 68000 read before writing.
2040 This isn't so on the 68010, but we have no TARGET_68010. */
2041 if (!ADDRESS_REG_P (operands
[0])
2042 && ((TARGET_68020
|| TARGET_COLDFIRE
)
2043 || !(GET_CODE (operands
[0]) == MEM
&& MEM_VOLATILE_P (operands
[0]))))
2045 if (operands
[1] == const0_rtx
)
2047 if ((!TARGET_COLDFIRE
|| DATA_REG_P (operands
[0]))
2048 && GET_CODE (operands
[1]) == CONST_INT
2049 && (INTVAL (operands
[1]) & 255) == 255)
2055 if (GET_CODE (operands
[1]) == CONST_INT
2056 && DATA_REG_P (operands
[0])
2057 && INTVAL (operands
[1]) < 128
2058 && INTVAL (operands
[1]) >= -128)
2060 return "moveq %1,%0";
2062 if (operands
[1] == const0_rtx
&& ADDRESS_REG_P (operands
[0]))
2063 return "sub%.l %0,%0";
2064 if (GET_CODE (operands
[1]) != CONST_INT
&& CONSTANT_P (operands
[1]))
2065 return "move%.l %1,%0";
2066 /* 68k family (including the 5200 coldfire) does not support byte moves to
2067 from address registers. */
2068 if (ADDRESS_REG_P (operands
[0]) || ADDRESS_REG_P (operands
[1]))
2069 return "move%.w %1,%0";
2070 return "move%.b %1,%0";
2074 output_move_stricthi (rtx
*operands
)
2076 if (operands
[1] == const0_rtx
2077 /* clr insns on 68000 read before writing.
2078 This isn't so on the 68010, but we have no TARGET_68010. */
2079 && ((TARGET_68020
|| TARGET_COLDFIRE
)
2080 || !(GET_CODE (operands
[0]) == MEM
&& MEM_VOLATILE_P (operands
[0]))))
2082 return "move%.w %1,%0";
2086 output_move_strictqi (rtx
*operands
)
2088 if (operands
[1] == const0_rtx
2089 /* clr insns on 68000 read before writing.
2090 This isn't so on the 68010, but we have no TARGET_68010. */
2091 && ((TARGET_68020
|| TARGET_COLDFIRE
)
2092 || !(GET_CODE (operands
[0]) == MEM
&& MEM_VOLATILE_P (operands
[0]))))
2094 return "move%.b %1,%0";
2097 /* Return the best assembler insn template
2098 for moving operands[1] into operands[0] as a fullword. */
2101 singlemove_string (rtx
*operands
)
2103 if (GET_CODE (operands
[1]) == CONST_INT
)
2104 return output_move_simode_const (operands
);
2105 return "move%.l %1,%0";
2109 /* Output assembler code to perform a doubleword move insn
2110 with operands OPERANDS. */
2113 output_move_double (rtx
*operands
)
2117 REGOP
, OFFSOP
, MEMOP
, PUSHOP
, POPOP
, CNSTOP
, RNDOP
2122 rtx addreg0
= 0, addreg1
= 0;
2123 int dest_overlapped_low
= 0;
2124 int size
= GET_MODE_SIZE (GET_MODE (operands
[0]));
2129 /* First classify both operands. */
2131 if (REG_P (operands
[0]))
2133 else if (offsettable_memref_p (operands
[0]))
2135 else if (GET_CODE (XEXP (operands
[0], 0)) == POST_INC
)
2137 else if (GET_CODE (XEXP (operands
[0], 0)) == PRE_DEC
)
2139 else if (GET_CODE (operands
[0]) == MEM
)
2144 if (REG_P (operands
[1]))
2146 else if (CONSTANT_P (operands
[1]))
2148 else if (offsettable_memref_p (operands
[1]))
2150 else if (GET_CODE (XEXP (operands
[1], 0)) == POST_INC
)
2152 else if (GET_CODE (XEXP (operands
[1], 0)) == PRE_DEC
)
2154 else if (GET_CODE (operands
[1]) == MEM
)
2159 /* Check for the cases that the operand constraints are not
2160 supposed to allow to happen. Abort if we get one,
2161 because generating code for these cases is painful. */
2163 if (optype0
== RNDOP
|| optype1
== RNDOP
)
2166 /* If one operand is decrementing and one is incrementing
2167 decrement the former register explicitly
2168 and change that operand into ordinary indexing. */
2170 if (optype0
== PUSHOP
&& optype1
== POPOP
)
2172 operands
[0] = XEXP (XEXP (operands
[0], 0), 0);
2174 output_asm_insn ("sub%.l %#12,%0", operands
);
2176 output_asm_insn ("subq%.l %#8,%0", operands
);
2177 if (GET_MODE (operands
[1]) == XFmode
)
2178 operands
[0] = gen_rtx_MEM (XFmode
, operands
[0]);
2179 else if (GET_MODE (operands
[0]) == DFmode
)
2180 operands
[0] = gen_rtx_MEM (DFmode
, operands
[0]);
2182 operands
[0] = gen_rtx_MEM (DImode
, operands
[0]);
2185 if (optype0
== POPOP
&& optype1
== PUSHOP
)
2187 operands
[1] = XEXP (XEXP (operands
[1], 0), 0);
2189 output_asm_insn ("sub%.l %#12,%1", operands
);
2191 output_asm_insn ("subq%.l %#8,%1", operands
);
2192 if (GET_MODE (operands
[1]) == XFmode
)
2193 operands
[1] = gen_rtx_MEM (XFmode
, operands
[1]);
2194 else if (GET_MODE (operands
[1]) == DFmode
)
2195 operands
[1] = gen_rtx_MEM (DFmode
, operands
[1]);
2197 operands
[1] = gen_rtx_MEM (DImode
, operands
[1]);
2201 /* If an operand is an unoffsettable memory ref, find a register
2202 we can increment temporarily to make it refer to the second word. */
2204 if (optype0
== MEMOP
)
2205 addreg0
= find_addr_reg (XEXP (operands
[0], 0));
2207 if (optype1
== MEMOP
)
2208 addreg1
= find_addr_reg (XEXP (operands
[1], 0));
2210 /* Ok, we can do one word at a time.
2211 Normally we do the low-numbered word first,
2212 but if either operand is autodecrementing then we
2213 do the high-numbered word first.
2215 In either case, set up in LATEHALF the operands to use
2216 for the high-numbered word and in some cases alter the
2217 operands in OPERANDS to be suitable for the low-numbered word. */
2221 if (optype0
== REGOP
)
2223 latehalf
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 2);
2224 middlehalf
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 1);
2226 else if (optype0
== OFFSOP
)
2228 middlehalf
[0] = adjust_address (operands
[0], SImode
, 4);
2229 latehalf
[0] = adjust_address (operands
[0], SImode
, size
- 4);
2233 middlehalf
[0] = operands
[0];
2234 latehalf
[0] = operands
[0];
2237 if (optype1
== REGOP
)
2239 latehalf
[1] = gen_rtx_REG (SImode
, REGNO (operands
[1]) + 2);
2240 middlehalf
[1] = gen_rtx_REG (SImode
, REGNO (operands
[1]) + 1);
2242 else if (optype1
== OFFSOP
)
2244 middlehalf
[1] = adjust_address (operands
[1], SImode
, 4);
2245 latehalf
[1] = adjust_address (operands
[1], SImode
, size
- 4);
2247 else if (optype1
== CNSTOP
)
2249 if (GET_CODE (operands
[1]) == CONST_DOUBLE
)
2254 REAL_VALUE_FROM_CONST_DOUBLE (r
, operands
[1]);
2255 REAL_VALUE_TO_TARGET_LONG_DOUBLE (r
, l
);
2256 operands
[1] = GEN_INT (l
[0]);
2257 middlehalf
[1] = GEN_INT (l
[1]);
2258 latehalf
[1] = GEN_INT (l
[2]);
2260 else if (CONSTANT_P (operands
[1]))
2262 /* actually, no non-CONST_DOUBLE constant should ever
2265 if (GET_CODE (operands
[1]) == CONST_INT
&& INTVAL (operands
[1]) < 0)
2266 latehalf
[1] = constm1_rtx
;
2268 latehalf
[1] = const0_rtx
;
2273 middlehalf
[1] = operands
[1];
2274 latehalf
[1] = operands
[1];
2278 /* size is not 12: */
2280 if (optype0
== REGOP
)
2281 latehalf
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 1);
2282 else if (optype0
== OFFSOP
)
2283 latehalf
[0] = adjust_address (operands
[0], SImode
, size
- 4);
2285 latehalf
[0] = operands
[0];
2287 if (optype1
== REGOP
)
2288 latehalf
[1] = gen_rtx_REG (SImode
, REGNO (operands
[1]) + 1);
2289 else if (optype1
== OFFSOP
)
2290 latehalf
[1] = adjust_address (operands
[1], SImode
, size
- 4);
2291 else if (optype1
== CNSTOP
)
2292 split_double (operands
[1], &operands
[1], &latehalf
[1]);
2294 latehalf
[1] = operands
[1];
2297 /* If insn is effectively movd N(sp),-(sp) then we will do the
2298 high word first. We should use the adjusted operand 1 (which is N+4(sp))
2299 for the low word as well, to compensate for the first decrement of sp. */
2300 if (optype0
== PUSHOP
2301 && REGNO (XEXP (XEXP (operands
[0], 0), 0)) == STACK_POINTER_REGNUM
2302 && reg_overlap_mentioned_p (stack_pointer_rtx
, operands
[1]))
2303 operands
[1] = middlehalf
[1] = latehalf
[1];
2305 /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)),
2306 if the upper part of reg N does not appear in the MEM, arrange to
2307 emit the move late-half first. Otherwise, compute the MEM address
2308 into the upper part of N and use that as a pointer to the memory
2310 if (optype0
== REGOP
2311 && (optype1
== OFFSOP
|| optype1
== MEMOP
))
2313 rtx testlow
= gen_rtx_REG (SImode
, REGNO (operands
[0]));
2315 if (reg_overlap_mentioned_p (testlow
, XEXP (operands
[1], 0))
2316 && reg_overlap_mentioned_p (latehalf
[0], XEXP (operands
[1], 0)))
2318 /* If both halves of dest are used in the src memory address,
2319 compute the address into latehalf of dest.
2320 Note that this can't happen if the dest is two data regs. */
2322 xops
[0] = latehalf
[0];
2323 xops
[1] = XEXP (operands
[1], 0);
2324 output_asm_insn ("lea %a1,%0", xops
);
2325 if (GET_MODE (operands
[1]) == XFmode
)
2327 operands
[1] = gen_rtx_MEM (XFmode
, latehalf
[0]);
2328 middlehalf
[1] = adjust_address (operands
[1], DImode
, size
- 8);
2329 latehalf
[1] = adjust_address (operands
[1], DImode
, size
- 4);
2333 operands
[1] = gen_rtx_MEM (DImode
, latehalf
[0]);
2334 latehalf
[1] = adjust_address (operands
[1], DImode
, size
- 4);
2338 && reg_overlap_mentioned_p (middlehalf
[0],
2339 XEXP (operands
[1], 0)))
2341 /* Check for two regs used by both source and dest.
2342 Note that this can't happen if the dest is all data regs.
2343 It can happen if the dest is d6, d7, a0.
2344 But in that case, latehalf is an addr reg, so
2345 the code at compadr does ok. */
2347 if (reg_overlap_mentioned_p (testlow
, XEXP (operands
[1], 0))
2348 || reg_overlap_mentioned_p (latehalf
[0], XEXP (operands
[1], 0)))
2351 /* JRV says this can't happen: */
2352 if (addreg0
|| addreg1
)
2355 /* Only the middle reg conflicts; simply put it last. */
2356 output_asm_insn (singlemove_string (operands
), operands
);
2357 output_asm_insn (singlemove_string (latehalf
), latehalf
);
2358 output_asm_insn (singlemove_string (middlehalf
), middlehalf
);
2361 else if (reg_overlap_mentioned_p (testlow
, XEXP (operands
[1], 0)))
2362 /* If the low half of dest is mentioned in the source memory
2363 address, the arrange to emit the move late half first. */
2364 dest_overlapped_low
= 1;
2367 /* If one or both operands autodecrementing,
2368 do the two words, high-numbered first. */
2370 /* Likewise, the first move would clobber the source of the second one,
2371 do them in the other order. This happens only for registers;
2372 such overlap can't happen in memory unless the user explicitly
2373 sets it up, and that is an undefined circumstance. */
2375 if (optype0
== PUSHOP
|| optype1
== PUSHOP
2376 || (optype0
== REGOP
&& optype1
== REGOP
2377 && ((middlehalf
[1] && REGNO (operands
[0]) == REGNO (middlehalf
[1]))
2378 || REGNO (operands
[0]) == REGNO (latehalf
[1])))
2379 || dest_overlapped_low
)
2381 /* Make any unoffsettable addresses point at high-numbered word. */
2385 output_asm_insn ("addq%.l %#8,%0", &addreg0
);
2387 output_asm_insn ("addq%.l %#4,%0", &addreg0
);
2392 output_asm_insn ("addq%.l %#8,%0", &addreg1
);
2394 output_asm_insn ("addq%.l %#4,%0", &addreg1
);
2398 output_asm_insn (singlemove_string (latehalf
), latehalf
);
2400 /* Undo the adds we just did. */
2402 output_asm_insn ("subq%.l %#4,%0", &addreg0
);
2404 output_asm_insn ("subq%.l %#4,%0", &addreg1
);
2408 output_asm_insn (singlemove_string (middlehalf
), middlehalf
);
2410 output_asm_insn ("subq%.l %#4,%0", &addreg0
);
2412 output_asm_insn ("subq%.l %#4,%0", &addreg1
);
2415 /* Do low-numbered word. */
2416 return singlemove_string (operands
);
2419 /* Normal case: do the two words, low-numbered first. */
2421 output_asm_insn (singlemove_string (operands
), operands
);
2423 /* Do the middle one of the three words for long double */
2427 output_asm_insn ("addq%.l %#4,%0", &addreg0
);
2429 output_asm_insn ("addq%.l %#4,%0", &addreg1
);
2431 output_asm_insn (singlemove_string (middlehalf
), middlehalf
);
2434 /* Make any unoffsettable addresses point at high-numbered word. */
2436 output_asm_insn ("addq%.l %#4,%0", &addreg0
);
2438 output_asm_insn ("addq%.l %#4,%0", &addreg1
);
2441 output_asm_insn (singlemove_string (latehalf
), latehalf
);
2443 /* Undo the adds we just did. */
2447 output_asm_insn ("subq%.l %#8,%0", &addreg0
);
2449 output_asm_insn ("subq%.l %#4,%0", &addreg0
);
2454 output_asm_insn ("subq%.l %#8,%0", &addreg1
);
2456 output_asm_insn ("subq%.l %#4,%0", &addreg1
);
2462 /* Return a REG that occurs in ADDR with coefficient 1.
2463 ADDR can be effectively incremented by incrementing REG. */
2466 find_addr_reg (rtx addr
)
2468 while (GET_CODE (addr
) == PLUS
)
2470 if (GET_CODE (XEXP (addr
, 0)) == REG
)
2471 addr
= XEXP (addr
, 0);
2472 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
2473 addr
= XEXP (addr
, 1);
2474 else if (CONSTANT_P (XEXP (addr
, 0)))
2475 addr
= XEXP (addr
, 1);
2476 else if (CONSTANT_P (XEXP (addr
, 1)))
2477 addr
= XEXP (addr
, 0);
2481 if (GET_CODE (addr
) == REG
)
2486 /* Output assembler code to perform a 32 bit 3 operand add. */
2489 output_addsi3 (rtx
*operands
)
2491 if (! operands_match_p (operands
[0], operands
[1]))
2493 if (!ADDRESS_REG_P (operands
[1]))
2495 rtx tmp
= operands
[1];
2497 operands
[1] = operands
[2];
2501 /* These insns can result from reloads to access
2502 stack slots over 64k from the frame pointer. */
2503 if (GET_CODE (operands
[2]) == CONST_INT
2504 && INTVAL (operands
[2]) + 0x8000 >= (unsigned) 0x10000)
2505 return "move%.l %2,%0\n\tadd%.l %1,%0";
2507 if (GET_CODE (operands
[2]) == REG
)
2508 return "lea 0(%1,%2.l),%0";
2510 return "lea %c2(%1),%0";
2511 #elif defined(MOTOROLA)
2512 if (GET_CODE (operands
[2]) == REG
)
2513 return "lea (%1,%2.l),%0";
2515 return "lea (%c2,%1),%0";
2516 #else /* not MOTOROLA (MIT syntax) */
2517 if (GET_CODE (operands
[2]) == REG
)
2518 return "lea %1@(0,%2:l),%0";
2520 return "lea %1@(%c2),%0";
2521 #endif /* not MOTOROLA */
2523 if (GET_CODE (operands
[2]) == CONST_INT
)
2525 if (INTVAL (operands
[2]) > 0
2526 && INTVAL (operands
[2]) <= 8)
2527 return "addq%.l %2,%0";
2528 if (INTVAL (operands
[2]) < 0
2529 && INTVAL (operands
[2]) >= -8)
2531 operands
[2] = GEN_INT (- INTVAL (operands
[2]));
2532 return "subq%.l %2,%0";
2534 /* On the CPU32 it is faster to use two addql instructions to
2535 add a small integer (8 < N <= 16) to a register.
2536 Likewise for subql. */
2537 if (TARGET_CPU32
&& REG_P (operands
[0]))
2539 if (INTVAL (operands
[2]) > 8
2540 && INTVAL (operands
[2]) <= 16)
2542 operands
[2] = GEN_INT (INTVAL (operands
[2]) - 8);
2543 return "addq%.l %#8,%0\n\taddq%.l %2,%0";
2545 if (INTVAL (operands
[2]) < -8
2546 && INTVAL (operands
[2]) >= -16)
2548 operands
[2] = GEN_INT (- INTVAL (operands
[2]) - 8);
2549 return "subq%.l %#8,%0\n\tsubq%.l %2,%0";
2552 if (ADDRESS_REG_P (operands
[0])
2553 && INTVAL (operands
[2]) >= -0x8000
2554 && INTVAL (operands
[2]) < 0x8000)
2557 return "add%.w %2,%0";
2560 return "lea (%c2,%0),%0";
2562 return "lea %0@(%c2),%0";
2566 return "add%.l %2,%0";
2569 /* Store in cc_status the expressions that the condition codes will
2570 describe after execution of an instruction whose pattern is EXP.
2571 Do not alter them if the instruction would not alter the cc's. */
2573 /* On the 68000, all the insns to store in an address register fail to
2574 set the cc's. However, in some cases these instructions can make it
2575 possibly invalid to use the saved cc's. In those cases we clear out
2576 some or all of the saved cc's so they won't be used. */
2579 notice_update_cc (rtx exp
, rtx insn
)
2581 if (GET_CODE (exp
) == SET
)
2583 if (GET_CODE (SET_SRC (exp
)) == CALL
)
2587 else if (ADDRESS_REG_P (SET_DEST (exp
)))
2589 if (cc_status
.value1
&& modified_in_p (cc_status
.value1
, insn
))
2590 cc_status
.value1
= 0;
2591 if (cc_status
.value2
&& modified_in_p (cc_status
.value2
, insn
))
2592 cc_status
.value2
= 0;
2594 else if (!FP_REG_P (SET_DEST (exp
))
2595 && SET_DEST (exp
) != cc0_rtx
2596 && (FP_REG_P (SET_SRC (exp
))
2597 || GET_CODE (SET_SRC (exp
)) == FIX
2598 || GET_CODE (SET_SRC (exp
)) == FLOAT_TRUNCATE
2599 || GET_CODE (SET_SRC (exp
)) == FLOAT_EXTEND
))
2603 /* A pair of move insns doesn't produce a useful overall cc. */
2604 else if (!FP_REG_P (SET_DEST (exp
))
2605 && !FP_REG_P (SET_SRC (exp
))
2606 && GET_MODE_SIZE (GET_MODE (SET_SRC (exp
))) > 4
2607 && (GET_CODE (SET_SRC (exp
)) == REG
2608 || GET_CODE (SET_SRC (exp
)) == MEM
2609 || GET_CODE (SET_SRC (exp
)) == CONST_DOUBLE
))
2613 else if (GET_CODE (SET_SRC (exp
)) == CALL
)
2617 else if (XEXP (exp
, 0) != pc_rtx
)
2619 cc_status
.flags
= 0;
2620 cc_status
.value1
= XEXP (exp
, 0);
2621 cc_status
.value2
= XEXP (exp
, 1);
2624 else if (GET_CODE (exp
) == PARALLEL
2625 && GET_CODE (XVECEXP (exp
, 0, 0)) == SET
)
2627 if (ADDRESS_REG_P (XEXP (XVECEXP (exp
, 0, 0), 0)))
2629 else if (XEXP (XVECEXP (exp
, 0, 0), 0) != pc_rtx
)
2631 cc_status
.flags
= 0;
2632 cc_status
.value1
= XEXP (XVECEXP (exp
, 0, 0), 0);
2633 cc_status
.value2
= XEXP (XVECEXP (exp
, 0, 0), 1);
2638 if (cc_status
.value2
!= 0
2639 && ADDRESS_REG_P (cc_status
.value2
)
2640 && GET_MODE (cc_status
.value2
) == QImode
)
2642 if (cc_status
.value2
!= 0)
2643 switch (GET_CODE (cc_status
.value2
))
2645 case PLUS
: case MINUS
: case MULT
:
2646 case DIV
: case UDIV
: case MOD
: case UMOD
: case NEG
:
2647 #if 0 /* These instructions always clear the overflow bit */
2648 case ASHIFT
: case ASHIFTRT
: case LSHIFTRT
:
2649 case ROTATE
: case ROTATERT
:
2651 if (GET_MODE (cc_status
.value2
) != VOIDmode
)
2652 cc_status
.flags
|= CC_NO_OVERFLOW
;
2655 /* (SET r1 (ZERO_EXTEND r2)) on this machine
2656 ends with a move insn moving r2 in r2's mode.
2657 Thus, the cc's are set for r2.
2658 This can set N bit spuriously. */
2659 cc_status
.flags
|= CC_NOT_NEGATIVE
;
2664 if (cc_status
.value1
&& GET_CODE (cc_status
.value1
) == REG
2666 && reg_overlap_mentioned_p (cc_status
.value1
, cc_status
.value2
))
2667 cc_status
.value2
= 0;
2668 if (((cc_status
.value1
&& FP_REG_P (cc_status
.value1
))
2669 || (cc_status
.value2
&& FP_REG_P (cc_status
.value2
))))
2670 cc_status
.flags
= CC_IN_68881
;
2674 output_move_const_double (rtx
*operands
)
2676 int code
= standard_68881_constant_p (operands
[1]);
2680 static char buf
[40];
2682 sprintf (buf
, "fmovecr %%#0x%x,%%0", code
& 0xff);
2685 return "fmove%.d %1,%0";
2689 output_move_const_single (rtx
*operands
)
2691 int code
= standard_68881_constant_p (operands
[1]);
2695 static char buf
[40];
2697 sprintf (buf
, "fmovecr %%#0x%x,%%0", code
& 0xff);
2700 return "fmove%.s %f1,%0";
2703 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
2704 from the "fmovecr" instruction.
2705 The value, anded with 0xff, gives the code to use in fmovecr
2706 to get the desired constant. */
2708 /* This code has been fixed for cross-compilation. */
2710 static int inited_68881_table
= 0;
2712 static const char *const strings_68881
[7] = {
2722 static const int codes_68881
[7] = {
2732 REAL_VALUE_TYPE values_68881
[7];
2734 /* Set up values_68881 array by converting the decimal values
2735 strings_68881 to binary. */
2738 init_68881_table (void)
2742 enum machine_mode mode
;
2745 for (i
= 0; i
< 7; i
++)
2749 r
= REAL_VALUE_ATOF (strings_68881
[i
], mode
);
2750 values_68881
[i
] = r
;
2752 inited_68881_table
= 1;
2756 standard_68881_constant_p (rtx x
)
2761 /* fmovecr must be emulated on the 68040 and 68060, so it shouldn't be
2762 used at all on those chips. */
2763 if (TARGET_68040
|| TARGET_68060
)
2766 if (! inited_68881_table
)
2767 init_68881_table ();
2769 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
2771 /* Use REAL_VALUES_IDENTICAL instead of REAL_VALUES_EQUAL so that -0.0
2773 for (i
= 0; i
< 6; i
++)
2775 if (REAL_VALUES_IDENTICAL (r
, values_68881
[i
]))
2776 return (codes_68881
[i
]);
2779 if (GET_MODE (x
) == SFmode
)
2782 if (REAL_VALUES_EQUAL (r
, values_68881
[6]))
2783 return (codes_68881
[6]);
2785 /* larger powers of ten in the constants ram are not used
2786 because they are not equal to a `double' C constant. */
2790 /* If X is a floating-point constant, return the logarithm of X base 2,
2791 or 0 if X is not a power of 2. */
2794 floating_exact_log2 (rtx x
)
2796 REAL_VALUE_TYPE r
, r1
;
2799 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
2801 if (REAL_VALUES_LESS (r
, dconst1
))
2804 exp
= real_exponent (&r
);
2805 real_2expN (&r1
, exp
);
2806 if (REAL_VALUES_EQUAL (r1
, r
))
2812 /* A C compound statement to output to stdio stream STREAM the
2813 assembler syntax for an instruction operand X. X is an RTL
2816 CODE is a value that can be used to specify one of several ways
2817 of printing the operand. It is used when identical operands
2818 must be printed differently depending on the context. CODE
2819 comes from the `%' specification that was used to request
2820 printing of the operand. If the specification was just `%DIGIT'
2821 then CODE is 0; if the specification was `%LTR DIGIT' then CODE
2822 is the ASCII code for LTR.
2824 If X is a register, this macro should print the register's name.
2825 The names can be found in an array `reg_names' whose type is
2826 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
2828 When the machine description has a specification `%PUNCT' (a `%'
2829 followed by a punctuation character), this macro is called with
2830 a null pointer for X and the punctuation character for CODE.
2832 The m68k specific codes are:
2834 '.' for dot needed in Motorola-style opcode names.
2835 '-' for an operand pushing on the stack:
2836 sp@-, -(sp) or -(%sp) depending on the style of syntax.
2837 '+' for an operand pushing on the stack:
2838 sp@+, (sp)+ or (%sp)+ depending on the style of syntax.
2839 '@' for a reference to the top word on the stack:
2840 sp@, (sp) or (%sp) depending on the style of syntax.
2841 '#' for an immediate operand prefix (# in MIT and Motorola syntax
2842 but & in SGS syntax).
2843 '!' for the cc register (used in an `and to cc' insn).
2844 '$' for the letter `s' in an op code, but only on the 68040.
2845 '&' for the letter `d' in an op code, but only on the 68040.
2846 '/' for register prefix needed by longlong.h.
2848 'b' for byte insn (no effect, on the Sun; this is for the ISI).
2849 'd' to force memory addressing to be absolute, not relative.
2850 'f' for float insn (print a CONST_DOUBLE as a float rather than in hex)
2851 'o' for operands to go directly to output_operand_address (bypassing
2852 print_operand_address--used only for SYMBOL_REFs under TARGET_PCREL)
2853 'x' for float insn (print a CONST_DOUBLE as a float rather than in hex),
2854 or print pair of registers as rx:ry.
2859 print_operand (FILE *file
, rtx op
, int letter
)
2863 #if defined (MOTOROLA)
2864 fprintf (file
, ".");
2867 else if (letter
== '#')
2869 asm_fprintf (file
, "%I");
2871 else if (letter
== '-')
2874 asm_fprintf (file
, "-(%Rsp)");
2876 asm_fprintf (file
, "%Rsp@-");
2879 else if (letter
== '+')
2882 asm_fprintf (file
, "(%Rsp)+");
2884 asm_fprintf (file
, "%Rsp@+");
2887 else if (letter
== '@')
2890 asm_fprintf (file
, "(%Rsp)");
2892 asm_fprintf (file
, "%Rsp@");
2895 else if (letter
== '!')
2897 asm_fprintf (file
, "%Rfpcr");
2899 else if (letter
== '$')
2901 if (TARGET_68040_ONLY
)
2903 fprintf (file
, "s");
2906 else if (letter
== '&')
2908 if (TARGET_68040_ONLY
)
2910 fprintf (file
, "d");
2913 else if (letter
== '/')
2915 asm_fprintf (file
, "%R");
2917 else if (letter
== 'o')
2919 /* This is only for direct addresses with TARGET_PCREL */
2920 if (GET_CODE (op
) != MEM
|| GET_CODE (XEXP (op
, 0)) != SYMBOL_REF
2923 output_addr_const (file
, XEXP (op
, 0));
2925 else if (GET_CODE (op
) == REG
)
2928 /* Print out the second register name of a register pair.
2929 I.e., R (6) => 7. */
2930 fputs (reg_names
[REGNO (op
) + 1], file
);
2932 fputs (reg_names
[REGNO (op
)], file
);
2934 else if (GET_CODE (op
) == MEM
)
2936 output_address (XEXP (op
, 0));
2937 if (letter
== 'd' && ! TARGET_68020
2938 && CONSTANT_ADDRESS_P (XEXP (op
, 0))
2939 && !(GET_CODE (XEXP (op
, 0)) == CONST_INT
2940 && INTVAL (XEXP (op
, 0)) < 0x8000
2941 && INTVAL (XEXP (op
, 0)) >= -0x8000))
2944 fprintf (file
, ".l");
2946 fprintf (file
, ":l");
2950 else if (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == SFmode
)
2953 REAL_VALUE_FROM_CONST_DOUBLE (r
, op
);
2954 ASM_OUTPUT_FLOAT_OPERAND (letter
, file
, r
);
2956 else if (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == XFmode
)
2959 REAL_VALUE_FROM_CONST_DOUBLE (r
, op
);
2960 ASM_OUTPUT_LONG_DOUBLE_OPERAND (file
, r
);
2962 else if (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == DFmode
)
2965 REAL_VALUE_FROM_CONST_DOUBLE (r
, op
);
2966 ASM_OUTPUT_DOUBLE_OPERAND (file
, r
);
2970 /* Use `print_operand_address' instead of `output_addr_const'
2971 to ensure that we print relevant PIC stuff. */
2972 asm_fprintf (file
, "%I");
2974 && (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == CONST
))
2975 print_operand_address (file
, op
);
2977 output_addr_const (file
, op
);
2982 /* A C compound statement to output to stdio stream STREAM the
2983 assembler syntax for an instruction operand that is a memory
2984 reference whose address is ADDR. ADDR is an RTL expression.
2986 Note that this contains a kludge that knows that the only reason
2987 we have an address (plus (label_ref...) (reg...)) when not generating
2988 PIC code is in the insn before a tablejump, and we know that m68k.md
2989 generates a label LInnn: on such an insn.
2991 It is possible for PIC to generate a (plus (label_ref...) (reg...))
2992 and we handle that just like we would a (plus (symbol_ref...) (reg...)).
2994 Some SGS assemblers have a bug such that "Lnnn-LInnn-2.b(pc,d0.l*2)"
2995 fails to assemble. Luckily "Lnnn(pc,d0.l*2)" produces the results
2996 we want. This difference can be accommodated by using an assembler
2997 define such "LDnnn" to be either "Lnnn-LInnn-2.b", "Lnnn", or any other
2998 string, as necessary. This is accomplished via the ASM_OUTPUT_CASE_END
2999 macro. See m68k/sgs.h for an example; for versions without the bug.
3000 Some assemblers refuse all the above solutions. The workaround is to
3001 emit "K(pc,d0.l*2)" with K being a small constant known to give the
3004 They also do not like things like "pea 1.w", so we simple leave off
3005 the .w on small constants.
3007 This routine is responsible for distinguishing between -fpic and -fPIC
3008 style relocations in an address. When generating -fpic code the
3009 offset is output in word mode (eg movel a5@(_foo:w), a0). When generating
3010 -fPIC code the offset is output in long mode (eg movel a5@(_foo:l), a0) */
3012 #ifndef ASM_OUTPUT_CASE_FETCH
3015 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
3016 asm_fprintf (file, "%LLD%d(%Rpc,%s.", labelno, regname)
3018 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
3019 asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.", labelno, labelno, regname)
3022 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
3023 asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:", labelno, labelno, regname)
3025 #endif /* ASM_OUTPUT_CASE_FETCH */
3028 print_operand_address (FILE *file
, rtx addr
)
3030 register rtx reg1
, reg2
, breg
, ireg
;
3033 switch (GET_CODE (addr
))
3037 fprintf (file
, "(%s)", reg_names
[REGNO (addr
)]);
3039 fprintf (file
, "%s@", reg_names
[REGNO (addr
)]);
3044 fprintf (file
, "-(%s)", reg_names
[REGNO (XEXP (addr
, 0))]);
3046 fprintf (file
, "%s@-", reg_names
[REGNO (XEXP (addr
, 0))]);
3051 fprintf (file
, "(%s)+", reg_names
[REGNO (XEXP (addr
, 0))]);
3053 fprintf (file
, "%s@+", reg_names
[REGNO (XEXP (addr
, 0))]);
3057 reg1
= reg2
= ireg
= breg
= offset
= 0;
3058 if (CONSTANT_ADDRESS_P (XEXP (addr
, 0)))
3060 offset
= XEXP (addr
, 0);
3061 addr
= XEXP (addr
, 1);
3063 else if (CONSTANT_ADDRESS_P (XEXP (addr
, 1)))
3065 offset
= XEXP (addr
, 1);
3066 addr
= XEXP (addr
, 0);
3068 if (GET_CODE (addr
) != PLUS
)
3072 else if (GET_CODE (XEXP (addr
, 0)) == SIGN_EXTEND
)
3074 reg1
= XEXP (addr
, 0);
3075 addr
= XEXP (addr
, 1);
3077 else if (GET_CODE (XEXP (addr
, 1)) == SIGN_EXTEND
)
3079 reg1
= XEXP (addr
, 1);
3080 addr
= XEXP (addr
, 0);
3082 else if (GET_CODE (XEXP (addr
, 0)) == MULT
)
3084 reg1
= XEXP (addr
, 0);
3085 addr
= XEXP (addr
, 1);
3087 else if (GET_CODE (XEXP (addr
, 1)) == MULT
)
3089 reg1
= XEXP (addr
, 1);
3090 addr
= XEXP (addr
, 0);
3092 else if (GET_CODE (XEXP (addr
, 0)) == REG
)
3094 reg1
= XEXP (addr
, 0);
3095 addr
= XEXP (addr
, 1);
3097 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
3099 reg1
= XEXP (addr
, 1);
3100 addr
= XEXP (addr
, 0);
3102 if (GET_CODE (addr
) == REG
|| GET_CODE (addr
) == MULT
3103 || GET_CODE (addr
) == SIGN_EXTEND
)
3115 #if 0 /* for OLD_INDEXING */
3116 else if (GET_CODE (addr
) == PLUS
)
3118 if (GET_CODE (XEXP (addr
, 0)) == REG
)
3120 reg2
= XEXP (addr
, 0);
3121 addr
= XEXP (addr
, 1);
3123 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
3125 reg2
= XEXP (addr
, 1);
3126 addr
= XEXP (addr
, 0);
3138 if ((reg1
&& (GET_CODE (reg1
) == SIGN_EXTEND
3139 || GET_CODE (reg1
) == MULT
))
3140 || (reg2
!= 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2
))))
3145 else if (reg1
!= 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1
)))
3150 if (ireg
!= 0 && breg
== 0 && GET_CODE (addr
) == LABEL_REF
3151 && ! (flag_pic
&& ireg
== pic_offset_table_rtx
))
3154 if (GET_CODE (ireg
) == MULT
)
3156 scale
= INTVAL (XEXP (ireg
, 1));
3157 ireg
= XEXP (ireg
, 0);
3159 if (GET_CODE (ireg
) == SIGN_EXTEND
)
3161 ASM_OUTPUT_CASE_FETCH (file
,
3162 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
3163 reg_names
[REGNO (XEXP (ireg
, 0))]);
3164 fprintf (file
, "w");
3168 ASM_OUTPUT_CASE_FETCH (file
,
3169 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
3170 reg_names
[REGNO (ireg
)]);
3171 fprintf (file
, "l");
3176 fprintf (file
, "*%d", scale
);
3178 fprintf (file
, ":%d", scale
);
3184 if (breg
!= 0 && ireg
== 0 && GET_CODE (addr
) == LABEL_REF
3185 && ! (flag_pic
&& breg
== pic_offset_table_rtx
))
3187 ASM_OUTPUT_CASE_FETCH (file
,
3188 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
3189 reg_names
[REGNO (breg
)]);
3190 fprintf (file
, "l)");
3193 if (ireg
!= 0 || breg
!= 0)
3200 if (! flag_pic
&& addr
&& GET_CODE (addr
) == LABEL_REF
)
3207 output_addr_const (file
, addr
);
3208 if (flag_pic
&& (breg
== pic_offset_table_rtx
))
3210 fprintf (file
, "@GOT");
3212 fprintf (file
, ".w");
3215 fprintf (file
, "(%s", reg_names
[REGNO (breg
)]);
3221 fprintf (file
, "%s@(", reg_names
[REGNO (breg
)]);
3224 output_addr_const (file
, addr
);
3225 if ((flag_pic
== 1) && (breg
== pic_offset_table_rtx
))
3226 fprintf (file
, ":w");
3227 if ((flag_pic
== 2) && (breg
== pic_offset_table_rtx
))
3228 fprintf (file
, ":l");
3230 if (addr
!= 0 && ireg
!= 0)
3235 if (ireg
!= 0 && GET_CODE (ireg
) == MULT
)
3237 scale
= INTVAL (XEXP (ireg
, 1));
3238 ireg
= XEXP (ireg
, 0);
3240 if (ireg
!= 0 && GET_CODE (ireg
) == SIGN_EXTEND
)
3243 fprintf (file
, "%s.w", reg_names
[REGNO (XEXP (ireg
, 0))]);
3245 fprintf (file
, "%s:w", reg_names
[REGNO (XEXP (ireg
, 0))]);
3251 fprintf (file
, "%s.l", reg_names
[REGNO (ireg
)]);
3253 fprintf (file
, "%s:l", reg_names
[REGNO (ireg
)]);
3259 fprintf (file
, "*%d", scale
);
3261 fprintf (file
, ":%d", scale
);
3267 else if (reg1
!= 0 && GET_CODE (addr
) == LABEL_REF
3268 && ! (flag_pic
&& reg1
== pic_offset_table_rtx
))
3270 ASM_OUTPUT_CASE_FETCH (file
,
3271 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
3272 reg_names
[REGNO (reg1
)]);
3273 fprintf (file
, "l)");
3276 /* FALL-THROUGH (is this really what we want?) */
3278 if (GET_CODE (addr
) == CONST_INT
3279 && INTVAL (addr
) < 0x8000
3280 && INTVAL (addr
) >= -0x8000)
3284 /* Many SGS assemblers croak on size specifiers for constants. */
3285 fprintf (file
, "%d", (int) INTVAL (addr
));
3287 fprintf (file
, "%d.w", (int) INTVAL (addr
));
3290 fprintf (file
, "%d:w", (int) INTVAL (addr
));
3293 else if (GET_CODE (addr
) == CONST_INT
)
3295 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (addr
));
3297 else if (TARGET_PCREL
)
3300 output_addr_const (file
, addr
);
3302 asm_fprintf (file
, ":w,%Rpc)");
3304 asm_fprintf (file
, ":l,%Rpc)");
3308 /* Special case for SYMBOL_REF if the symbol name ends in
3309 `.<letter>', this can be mistaken as a size suffix. Put
3310 the name in parentheses. */
3311 if (GET_CODE (addr
) == SYMBOL_REF
3312 && strlen (XSTR (addr
, 0)) > 2
3313 && XSTR (addr
, 0)[strlen (XSTR (addr
, 0)) - 2] == '.')
3316 output_addr_const (file
, addr
);
3320 output_addr_const (file
, addr
);
3326 /* Check for cases where a clr insns can be omitted from code using
3327 strict_low_part sets. For example, the second clrl here is not needed:
3328 clrl d0; movw a0@+,d0; use d0; clrl d0; movw a0@+; use d0; ...
3330 MODE is the mode of this STRICT_LOW_PART set. FIRST_INSN is the clear
3331 insn we are checking for redundancy. TARGET is the register set by the
3335 strict_low_part_peephole_ok (enum machine_mode mode
, rtx first_insn
,
3340 p
= prev_nonnote_insn (first_insn
);
3344 /* If it isn't an insn, then give up. */
3345 if (GET_CODE (p
) != INSN
)
3348 if (reg_set_p (target
, p
))
3350 rtx set
= single_set (p
);
3353 /* If it isn't an easy to recognize insn, then give up. */
3357 dest
= SET_DEST (set
);
3359 /* If this sets the entire target register to zero, then our
3360 first_insn is redundant. */
3361 if (rtx_equal_p (dest
, target
)
3362 && SET_SRC (set
) == const0_rtx
)
3364 else if (GET_CODE (dest
) == STRICT_LOW_PART
3365 && GET_CODE (XEXP (dest
, 0)) == REG
3366 && REGNO (XEXP (dest
, 0)) == REGNO (target
)
3367 && (GET_MODE_SIZE (GET_MODE (XEXP (dest
, 0)))
3368 <= GET_MODE_SIZE (mode
)))
3369 /* This is a strict low part set which modifies less than
3370 we are using, so it is safe. */
3376 p
= prev_nonnote_insn (p
);
3383 /* Accept integer operands in the range 0..0xffffffff. We have to check the
3384 range carefully since this predicate is used in DImode contexts. Also, we
3385 need some extra crud to make it work when hosted on 64-bit machines. */
3388 const_uint32_operand (rtx op
, enum machine_mode mode
)
3390 /* It doesn't make sense to ask this question with a mode that is
3391 not larger than 32 bits. */
3392 if (GET_MODE_BITSIZE (mode
) <= 32)
3395 #if HOST_BITS_PER_WIDE_INT > 32
3396 /* All allowed constants will fit a CONST_INT. */
3397 return (GET_CODE (op
) == CONST_INT
3398 && (INTVAL (op
) >= 0 && INTVAL (op
) <= 0xffffffffL
));
3400 return (GET_CODE (op
) == CONST_INT
3401 || (GET_CODE (op
) == CONST_DOUBLE
&& CONST_DOUBLE_HIGH (op
) == 0));
3405 /* Accept integer operands in the range -0x80000000..0x7fffffff. We have
3406 to check the range carefully since this predicate is used in DImode
3410 const_sint32_operand (rtx op
, enum machine_mode mode
)
3412 /* It doesn't make sense to ask this question with a mode that is
3413 not larger than 32 bits. */
3414 if (GET_MODE_BITSIZE (mode
) <= 32)
3417 /* All allowed constants will fit a CONST_INT. */
3418 return (GET_CODE (op
) == CONST_INT
3419 && (INTVAL (op
) >= (-0x7fffffff - 1) && INTVAL (op
) <= 0x7fffffff));
3422 /* Operand predicates for implementing asymmetric pc-relative addressing
3423 on m68k. The m68k supports pc-relative addressing (mode 7, register 2)
3424 when used as a source operand, but not as a destination operand.
3426 We model this by restricting the meaning of the basic predicates
3427 (general_operand, memory_operand, etc) to forbid the use of this
3428 addressing mode, and then define the following predicates that permit
3429 this addressing mode. These predicates can then be used for the
3430 source operands of the appropriate instructions.
3432 n.b. While it is theoretically possible to change all machine patterns
3433 to use this addressing more where permitted by the architecture,
3434 it has only been implemented for "common" cases: SImode, HImode, and
3435 QImode operands, and only for the principle operations that would
3436 require this addressing mode: data movement and simple integer operations.
3438 In parallel with these new predicates, two new constraint letters
3439 were defined: 'S' and 'T'. 'S' is the -mpcrel analog of 'm'.
3440 'T' replaces 's' in the non-pcrel case. It is a no-op in the pcrel case.
3441 In the pcrel case 's' is only valid in combination with 'a' registers.
3442 See addsi3, subsi3, cmpsi, and movsi patterns for a better understanding
3443 of how these constraints are used.
3445 The use of these predicates is strictly optional, though patterns that
3446 don't will cause an extra reload register to be allocated where one
3449 lea (abc:w,%pc),%a0 ; need to reload address
3450 moveq &1,%d1 ; since write to pc-relative space
3451 movel %d1,%a0@ ; is not allowed
3453 lea (abc:w,%pc),%a1 ; no need to reload address here
3454 movel %a1@,%d0 ; since "movel (abc:w,%pc),%d0" is ok
3456 For more info, consult tiemann@cygnus.com.
3459 All of the ugliness with predicates and constraints is due to the
3460 simple fact that the m68k does not allow a pc-relative addressing
3461 mode as a destination. gcc does not distinguish between source and
3462 destination addresses. Hence, if we claim that pc-relative address
3463 modes are valid, e.g. GO_IF_LEGITIMATE_ADDRESS accepts them, then we
3464 end up with invalid code. To get around this problem, we left
3465 pc-relative modes as invalid addresses, and then added special
3466 predicates and constraints to accept them.
3468 A cleaner way to handle this is to modify gcc to distinguish
3469 between source and destination addresses. We can then say that
3470 pc-relative is a valid source address but not a valid destination
3471 address, and hopefully avoid a lot of the predicate and constraint
3472 hackery. Unfortunately, this would be a pretty big change. It would
3473 be a useful change for a number of ports, but there aren't any current
3474 plans to undertake this.
3476 ***************************************************************************/
3479 /* Special case of a general operand that's used as a source operand.
3480 Use this to permit reads from PC-relative memory when -mpcrel
3484 general_src_operand (rtx op
, enum machine_mode mode
)
3487 && GET_CODE (op
) == MEM
3488 && (GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
3489 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
3490 || GET_CODE (XEXP (op
, 0)) == CONST
))
3492 return general_operand (op
, mode
);
3495 /* Special case of a nonimmediate operand that's used as a source.
3496 Use this to permit reads from PC-relative memory when -mpcrel
3500 nonimmediate_src_operand (rtx op
, enum machine_mode mode
)
3502 if (TARGET_PCREL
&& GET_CODE (op
) == MEM
3503 && (GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
3504 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
3505 || GET_CODE (XEXP (op
, 0)) == CONST
))
3507 return nonimmediate_operand (op
, mode
);
3510 /* Special case of a memory operand that's used as a source.
3511 Use this to permit reads from PC-relative memory when -mpcrel
3515 memory_src_operand (rtx op
, enum machine_mode mode
)
3517 if (TARGET_PCREL
&& GET_CODE (op
) == MEM
3518 && (GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
3519 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
3520 || GET_CODE (XEXP (op
, 0)) == CONST
))
3522 return memory_operand (op
, mode
);
3525 /* Predicate that accepts only a pc-relative address. This is needed
3526 because pc-relative addresses don't satisfy the predicate
3527 "general_src_operand". */
3530 pcrel_address (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
3532 return (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
3533 || GET_CODE (op
) == CONST
);
3537 output_andsi3 (rtx
*operands
)
3540 if (GET_CODE (operands
[2]) == CONST_INT
3541 && (INTVAL (operands
[2]) | 0xffff) == 0xffffffff
3542 && (DATA_REG_P (operands
[0])
3543 || offsettable_memref_p (operands
[0]))
3544 && !TARGET_COLDFIRE
)
3546 if (GET_CODE (operands
[0]) != REG
)
3547 operands
[0] = adjust_address (operands
[0], HImode
, 2);
3548 operands
[2] = GEN_INT (INTVAL (operands
[2]) & 0xffff);
3549 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3551 if (operands
[2] == const0_rtx
)
3553 return "and%.w %2,%0";
3555 if (GET_CODE (operands
[2]) == CONST_INT
3556 && (logval
= exact_log2 (~ INTVAL (operands
[2]))) >= 0
3557 && (DATA_REG_P (operands
[0])
3558 || offsettable_memref_p (operands
[0])))
3560 if (DATA_REG_P (operands
[0]))
3562 operands
[1] = GEN_INT (logval
);
3566 operands
[0] = adjust_address (operands
[0], SImode
, 3 - (logval
/ 8));
3567 operands
[1] = GEN_INT (logval
% 8);
3569 /* This does not set condition codes in a standard way. */
3571 return "bclr %1,%0";
3573 return "and%.l %2,%0";
3577 output_iorsi3 (rtx
*operands
)
3579 register int logval
;
3580 if (GET_CODE (operands
[2]) == CONST_INT
3581 && INTVAL (operands
[2]) >> 16 == 0
3582 && (DATA_REG_P (operands
[0])
3583 || offsettable_memref_p (operands
[0]))
3584 && !TARGET_COLDFIRE
)
3586 if (GET_CODE (operands
[0]) != REG
)
3587 operands
[0] = adjust_address (operands
[0], HImode
, 2);
3588 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3590 if (INTVAL (operands
[2]) == 0xffff)
3591 return "mov%.w %2,%0";
3592 return "or%.w %2,%0";
3594 if (GET_CODE (operands
[2]) == CONST_INT
3595 && (logval
= exact_log2 (INTVAL (operands
[2]))) >= 0
3596 && (DATA_REG_P (operands
[0])
3597 || offsettable_memref_p (operands
[0])))
3599 if (DATA_REG_P (operands
[0]))
3600 operands
[1] = GEN_INT (logval
);
3603 operands
[0] = adjust_address (operands
[0], SImode
, 3 - (logval
/ 8));
3604 operands
[1] = GEN_INT (logval
% 8);
3607 return "bset %1,%0";
3609 return "or%.l %2,%0";
3613 output_xorsi3 (rtx
*operands
)
3615 register int logval
;
3616 if (GET_CODE (operands
[2]) == CONST_INT
3617 && INTVAL (operands
[2]) >> 16 == 0
3618 && (offsettable_memref_p (operands
[0]) || DATA_REG_P (operands
[0]))
3619 && !TARGET_COLDFIRE
)
3621 if (! DATA_REG_P (operands
[0]))
3622 operands
[0] = adjust_address (operands
[0], HImode
, 2);
3623 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3625 if (INTVAL (operands
[2]) == 0xffff)
3627 return "eor%.w %2,%0";
3629 if (GET_CODE (operands
[2]) == CONST_INT
3630 && (logval
= exact_log2 (INTVAL (operands
[2]))) >= 0
3631 && (DATA_REG_P (operands
[0])
3632 || offsettable_memref_p (operands
[0])))
3634 if (DATA_REG_P (operands
[0]))
3635 operands
[1] = GEN_INT (logval
);
3638 operands
[0] = adjust_address (operands
[0], SImode
, 3 - (logval
/ 8));
3639 operands
[1] = GEN_INT (logval
% 8);
3642 return "bchg %1,%0";
3644 return "eor%.l %2,%0";
3647 #ifdef M68K_TARGET_COFF
3649 /* Output assembly to switch to section NAME with attribute FLAGS. */
3652 m68k_coff_asm_named_section (const char *name
, unsigned int flags
)
3656 if (flags
& SECTION_WRITE
)
3661 fprintf (asm_out_file
, "\t.section\t%s,\"%c\"\n", name
, flagchar
);
3664 #endif /* M68K_TARGET_COFF */
3668 m68k_hp320_internal_label (FILE *stream
, const char *prefix
,
3669 unsigned long labelno
)
3671 if (prefix
[0] == 'L' && prefix
[1] == 'I')
3672 fprintf(stream
, "\tset %s%ld,.+2\n", prefix
, labelno
);
3674 fprintf (stream
, "%s%ld:\n", prefix
, labelno
);
3678 m68k_hp320_file_start (void)
3680 /* version 1: 68010.
3681 2: 68020 without FPU.
3682 3: 68020 with FPU. */
3683 fprintf (asm_out_file
, "\tversion %d\n",
3684 TARGET_68020
? (TARGET_68881
? 3 : 2) : 1);
3689 m68k_output_mi_thunk (FILE *file
, tree thunk ATTRIBUTE_UNUSED
,
3690 HOST_WIDE_INT delta
,
3691 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED
,
3697 if (delta
> 0 && delta
<= 8)
3699 asm_fprintf (file
, "\taddq.l %I%d,4(%Rsp)\n", (int) delta
);
3701 asm_fprintf (file
, "\taddql %I%d,%Rsp@(4)\n", (int) delta
);
3703 else if (delta
< 0 && delta
>= -8)
3705 asm_fprintf (file
, "\tsubq.l %I%d,4(%Rsp)\n", (int) -delta
);
3707 asm_fprintf (file
, "\tsubql %I%d,%Rsp@(4)\n", (int) -delta
);
3711 asm_fprintf (file
, "\tadd.l %I%wd,4(%Rsp)\n", delta
);
3713 asm_fprintf (file
, "\taddl %I%wd,%Rsp@(4)\n", delta
);
3716 xops
[0] = DECL_RTL (function
);
3718 /* Logic taken from call patterns in m68k.md. */
3723 else if ((flag_pic
== 1) || TARGET_68020
)
3730 fmt
= "bra.l %0@PLTPC";
3732 fmt
= "bra %0@PLTPC";
3743 else if (optimize_size
|| TARGET_ID_SHARED_LIBRARY
)
3744 fmt
= "move.l %0@GOT(%%a5), %%a1\n\tjmp (%%a1)";
3746 fmt
= "lea %0-.-8,%%a1\n\tjsr 0(%%pc,%%a1)";
3750 #if defined (MOTOROLA) && !defined (USE_GAS)
3757 output_asm_insn (fmt
, xops
);