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"
46 /* Structure describing stack frame layout. */
49 /* Stack pointer to frame pointer offset. */
52 /* Offset of FPU registers. */
53 HOST_WIDE_INT foffset
;
55 /* Frame size in bytes (rounded up). */
58 /* Data and address register. */
60 unsigned int reg_mask
;
61 unsigned int reg_rev_mask
;
65 unsigned int fpu_mask
;
66 unsigned int fpu_rev_mask
;
68 /* Offsets relative to ARG_POINTER. */
69 HOST_WIDE_INT frame_pointer_offset
;
70 HOST_WIDE_INT stack_pointer_offset
;
72 /* Function which the above information refers to. */
76 /* Current frame information calculated by m68k_compute_frame_layout(). */
77 static struct m68k_frame current_frame
;
79 /* This flag is used to communicate between movhi and ASM_OUTPUT_CASE_END,
80 if SGS_SWITCH_TABLE. */
81 int switch_table_difference_label_flag
;
83 static rtx
find_addr_reg (rtx
);
84 static const char *singlemove_string (rtx
*);
85 static void m68k_output_function_prologue (FILE *, HOST_WIDE_INT
);
86 static void m68k_output_function_epilogue (FILE *, HOST_WIDE_INT
);
87 #ifdef M68K_TARGET_COFF
88 static void m68k_coff_asm_named_section (const char *, unsigned int);
89 #endif /* M68K_TARGET_COFF */
91 static void m68k_hp320_internal_label (FILE *, const char *, unsigned long);
92 static void m68k_hp320_file_start (void);
94 static void m68k_output_mi_thunk (FILE *, tree
, HOST_WIDE_INT
,
96 static bool m68k_interrupt_function_p (tree func
);
97 static tree
m68k_handle_fndecl_attribute (tree
*node
, tree name
,
100 static void m68k_compute_frame_layout (void);
101 static bool m68k_save_reg (unsigned int regno
, bool interrupt_handler
);
102 static int const_int_cost (rtx
);
103 static bool m68k_rtx_costs (rtx
, int, int, int *);
106 /* Alignment to use for loops and jumps */
107 /* Specify power of two alignment used for loops. */
108 const char *m68k_align_loops_string
;
109 /* Specify power of two alignment used for non-loop jumps. */
110 const char *m68k_align_jumps_string
;
111 /* Specify power of two alignment used for functions. */
112 const char *m68k_align_funcs_string
;
113 /* Specify the identification number of the library being built */
114 const char *m68k_library_id_string
;
116 /* Specify power of two alignment used for loops. */
117 int m68k_align_loops
;
118 /* Specify power of two alignment used for non-loop jumps. */
119 int m68k_align_jumps
;
120 /* Specify power of two alignment used for functions. */
121 int m68k_align_funcs
;
123 /* Nonzero if the last compare/test insn had FP operands. The
124 sCC expanders peek at this to determine what to do for the
125 68060, which has no fsCC instructions. */
126 int m68k_last_compare_had_fp_operands
;
128 /* Initialize the GCC target structure. */
130 #if INT_OP_GROUP == INT_OP_DOT_WORD
131 #undef TARGET_ASM_ALIGNED_HI_OP
132 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
135 #if INT_OP_GROUP == INT_OP_NO_DOT
136 #undef TARGET_ASM_BYTE_OP
137 #define TARGET_ASM_BYTE_OP "\tbyte\t"
138 #undef TARGET_ASM_ALIGNED_HI_OP
139 #define TARGET_ASM_ALIGNED_HI_OP "\tshort\t"
140 #undef TARGET_ASM_ALIGNED_SI_OP
141 #define TARGET_ASM_ALIGNED_SI_OP "\tlong\t"
144 #if INT_OP_GROUP == INT_OP_DC
145 #undef TARGET_ASM_BYTE_OP
146 #define TARGET_ASM_BYTE_OP "\tdc.b\t"
147 #undef TARGET_ASM_ALIGNED_HI_OP
148 #define TARGET_ASM_ALIGNED_HI_OP "\tdc.w\t"
149 #undef TARGET_ASM_ALIGNED_SI_OP
150 #define TARGET_ASM_ALIGNED_SI_OP "\tdc.l\t"
153 #undef TARGET_ASM_UNALIGNED_HI_OP
154 #define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP
155 #undef TARGET_ASM_UNALIGNED_SI_OP
156 #define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP
158 #undef TARGET_ASM_FUNCTION_PROLOGUE
159 #define TARGET_ASM_FUNCTION_PROLOGUE m68k_output_function_prologue
160 #undef TARGET_ASM_FUNCTION_EPILOGUE
161 #define TARGET_ASM_FUNCTION_EPILOGUE m68k_output_function_epilogue
163 #undef TARGET_ASM_INTERNAL_LABEL
164 #define TARGET_ASM_INTERNAL_LABEL m68k_hp320_internal_label
167 #undef TARGET_ASM_OUTPUT_MI_THUNK
168 #define TARGET_ASM_OUTPUT_MI_THUNK m68k_output_mi_thunk
169 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
170 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
172 #undef TARGET_ASM_FILE_START_APP_OFF
173 #define TARGET_ASM_FILE_START_APP_OFF true
175 #undef TARGET_RTX_COSTS
176 #define TARGET_RTX_COSTS m68k_rtx_costs
178 #undef TARGET_ATTRIBUTE_TABLE
179 #define TARGET_ATTRIBUTE_TABLE m68k_attribute_table
181 static const struct attribute_spec m68k_attribute_table
[] =
183 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
184 { "interrupt_handler", 0, 0, true, false, false, m68k_handle_fndecl_attribute
},
185 { NULL
, 0, 0, false, false, false, NULL
}
188 struct gcc_target targetm
= TARGET_INITIALIZER
;
190 /* Sometimes certain combinations of command options do not make
191 sense on a particular target machine. You can define a macro
192 `OVERRIDE_OPTIONS' to take account of this. This macro, if
193 defined, is executed once just after all the command options have
196 Don't use this macro to turn on various extra optimizations for
197 `-O'. That is what `OPTIMIZATION_OPTIONS' is for. */
200 override_options (void)
207 /* Validate -malign-loops= value, or provide default */
208 m68k_align_loops
= def_align
;
209 if (m68k_align_loops_string
)
211 i
= atoi (m68k_align_loops_string
);
212 if (i
< 1 || i
> MAX_CODE_ALIGN
)
213 error ("-malign-loops=%d is not between 1 and %d", i
, MAX_CODE_ALIGN
);
215 m68k_align_loops
= i
;
218 /* Library identification */
219 if (m68k_library_id_string
)
223 if (! TARGET_ID_SHARED_LIBRARY
)
224 error ("-mshared-library-id= specified without -mid-shared-library");
225 id
= atoi (m68k_library_id_string
);
226 if (id
< 0 || id
> MAX_LIBRARY_ID
)
227 error ("-mshared-library-id=%d is not between 0 and %d", id
, MAX_LIBRARY_ID
);
229 /* From now on, m68k_library_id_string will contain the library offset. */
230 asprintf ((char **)&m68k_library_id_string
, "%d", (id
* -4) - 4);
233 /* If TARGET_ID_SHARED_LIBRARY is enabled, this will point to the
235 m68k_library_id_string
= "_current_shared_library_a5_offset_";
237 /* Sanity check to ensure that msep-data and mid-sahred-library are not
238 * both specified together. Doing so simply doesn't make sense.
240 if (TARGET_SEP_DATA
&& TARGET_ID_SHARED_LIBRARY
)
241 error ("cannot specify both -msep-data and -mid-shared-library");
243 /* If we're generating code for a separate A5 relative data segment,
244 * we've got to enable -fPIC as well. This might be relaxable to
245 * -fpic but it hasn't been tested properly.
247 if (TARGET_SEP_DATA
|| TARGET_ID_SHARED_LIBRARY
)
250 /* Validate -malign-jumps= value, or provide default */
251 m68k_align_jumps
= def_align
;
252 if (m68k_align_jumps_string
)
254 i
= atoi (m68k_align_jumps_string
);
255 if (i
< 1 || i
> MAX_CODE_ALIGN
)
256 error ("-malign-jumps=%d is not between 1 and %d", i
, MAX_CODE_ALIGN
);
258 m68k_align_jumps
= i
;
261 /* Validate -malign-functions= value, or provide default */
262 m68k_align_funcs
= def_align
;
263 if (m68k_align_funcs_string
)
265 i
= atoi (m68k_align_funcs_string
);
266 if (i
< 1 || i
> MAX_CODE_ALIGN
)
267 error ("-malign-functions=%d is not between 1 and %d",
270 m68k_align_funcs
= i
;
273 /* -fPIC uses 32-bit pc-relative displacements, which don't exist
275 if (!TARGET_68020
&& !TARGET_COLDFIRE
&& (flag_pic
== 2))
276 error("-fPIC is not currently supported on the 68000 or 68010\n");
278 /* ??? A historic way of turning on pic, or is this intended to
279 be an embedded thing that doesn't have the same name binding
280 significance that it does on hosted ELF systems? */
281 if (TARGET_PCREL
&& flag_pic
== 0)
284 /* Turn off function cse if we are doing PIC. We always want function call
285 to be done as `bsr foo@PLTPC', so it will force the assembler to create
286 the PLT entry for `foo'. Doing function cse will cause the address of
287 `foo' to be loaded into a register, which is exactly what we want to
288 avoid when we are doing PIC on svr4 m68k. */
290 flag_no_function_cse
= 1;
292 SUBTARGET_OVERRIDE_OPTIONS
;
295 /* Return nonzero if FUNC is an interrupt function as specified by the
296 "interrupt_handler" attribute. */
298 m68k_interrupt_function_p(tree func
)
302 if (TREE_CODE (func
) != FUNCTION_DECL
)
305 a
= lookup_attribute ("interrupt_handler", DECL_ATTRIBUTES (func
));
306 return (a
!= NULL_TREE
);
309 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
310 struct attribute_spec.handler. */
312 m68k_handle_fndecl_attribute (tree
*node
, tree name
,
313 tree args ATTRIBUTE_UNUSED
,
314 int flags ATTRIBUTE_UNUSED
,
317 if (TREE_CODE (*node
) != FUNCTION_DECL
)
319 warning ("`%s' attribute only applies to functions",
320 IDENTIFIER_POINTER (name
));
321 *no_add_attrs
= true;
328 m68k_compute_frame_layout (void)
331 unsigned int mask
, rmask
;
332 bool interrupt_handler
= m68k_interrupt_function_p (current_function_decl
);
334 /* Only compute the frame once per function.
335 Don't cache information until reload has been completed. */
336 if (current_frame
.funcdef_no
== current_function_funcdef_no
340 current_frame
.size
= (get_frame_size () + 3) & -4;
342 mask
= rmask
= saved
= 0;
343 for (regno
= 0; regno
< 16; regno
++)
344 if (m68k_save_reg (regno
, interrupt_handler
))
347 rmask
|= 1 << (15 - regno
);
350 current_frame
.offset
= saved
* 4;
351 current_frame
.reg_no
= saved
;
352 current_frame
.reg_mask
= mask
;
353 current_frame
.reg_rev_mask
= rmask
;
355 if (TARGET_68881
/* || TARGET_CFV4E */)
357 mask
= rmask
= saved
= 0;
358 for (regno
= 16; regno
< 24; regno
++)
359 if (m68k_save_reg (regno
, interrupt_handler
))
361 mask
|= 1 << (23 - regno
);
362 rmask
|= 1 << (regno
- 16);
365 current_frame
.foffset
= saved
* 12 /* (TARGET_CFV4E ? 8 : 12) */;
366 current_frame
.offset
+= current_frame
.foffset
;
367 current_frame
.fpu_no
= saved
;
368 current_frame
.fpu_mask
= mask
;
369 current_frame
.fpu_rev_mask
= rmask
;
372 /* Remember what function this frame refers to. */
373 current_frame
.funcdef_no
= current_function_funcdef_no
;
377 m68k_initial_elimination_offset (int from
, int to
)
379 /* FIXME: The correct offset to compute here would appear to be
380 (frame_pointer_needed ? -UNITS_PER_WORD * 2 : -UNITS_PER_WORD);
381 but for some obscure reason, this must be 0 to get correct code. */
382 if (from
== ARG_POINTER_REGNUM
&& to
== FRAME_POINTER_REGNUM
)
385 m68k_compute_frame_layout ();
387 if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
388 return current_frame
.offset
+ current_frame
.size
+ (frame_pointer_needed
? -UNITS_PER_WORD
* 2 : -UNITS_PER_WORD
);
389 else if (from
== FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
390 return current_frame
.offset
+ current_frame
.size
;
395 /* Return true if we need to save REGNO. */
397 m68k_save_reg (unsigned int regno
, bool interrupt_handler
)
399 if (flag_pic
&& current_function_uses_pic_offset_table
400 && regno
== PIC_OFFSET_TABLE_REGNUM
)
403 if (current_function_calls_eh_return
)
408 unsigned int test
= EH_RETURN_DATA_REGNO (i
);
409 if (test
== INVALID_REGNUM
)
416 /* Fixed regs we never touch. */
417 if (fixed_regs
[regno
])
420 /* The frame pointer (if it is such) is handled specially. */
421 if (regno
== FRAME_POINTER_REGNUM
&& frame_pointer_needed
)
424 /* Interrupt handlers must also save call_used_regs
425 if they are live or when calling nested functions. */
426 if (interrupt_handler
)
428 if (regs_ever_live
[regno
])
431 if (!current_function_is_leaf
&& call_used_regs
[regno
])
435 /* Never need to save registers that aren't touched. */
436 if (!regs_ever_live
[regno
])
439 /* Otherwise save everything that isn't call-clobbered. */
440 return !call_used_regs
[regno
];
443 /* This function generates the assembly code for function entry.
444 STREAM is a stdio stream to output the code to.
445 SIZE is an int: how many units of temporary storage to allocate.
446 Refer to the array `regs_ever_live' to determine which registers
447 to save; `regs_ever_live[I]' is nonzero if register number I
448 is ever used in the function. This function is responsible for
449 knowing which registers should not be saved even if used. */
452 /* Note that the order of the bit mask for fmovem is the opposite
453 of the order for movem! */
456 m68k_output_function_prologue (FILE *stream
, HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
458 int num_saved_regs
= 0;
459 HOST_WIDE_INT fsize_with_regs
;
460 HOST_WIDE_INT cfa_offset
= INCOMING_FRAME_SP_OFFSET
;
462 m68k_compute_frame_layout();
464 /* If the stack limit is a symbol, we can check it here,
465 before actually allocating the space. */
466 if (current_function_limit_stack
467 && GET_CODE (stack_limit_rtx
) == SYMBOL_REF
)
469 #if defined (MOTOROLA)
470 asm_fprintf (stream
, "\tcmp.l %I%s+%wd,%Rsp\n\ttrapcs\n",
471 XSTR (stack_limit_rtx
, 0), current_frame
.size
+ 4);
473 asm_fprintf (stream
, "\tcmpl %I%s+%wd,%Rsp\n\ttrapcs\n",
474 XSTR (stack_limit_rtx
, 0), current_frame
.size
+ 4);
478 /* on ColdFire add register save into initial stack frame setup, if possible */
480 if (TARGET_COLDFIRE
&& current_frame
.reg_no
> 2)
481 num_saved_regs
= current_frame
.reg_no
;
483 fsize_with_regs
= current_frame
.size
+ num_saved_regs
* 4;
485 if (frame_pointer_needed
)
487 if (current_frame
.size
== 0 && TARGET_68040
)
489 /* on the 68040, pea + move is faster than link.w 0 */
491 fprintf (stream
, "\tpea (%s)\n\tmove.l %s,%s\n",
492 reg_names
[FRAME_POINTER_REGNUM
],
493 reg_names
[STACK_POINTER_REGNUM
],
494 reg_names
[FRAME_POINTER_REGNUM
]);
496 fprintf (stream
, "\tpea %s@\n\tmovel %s,%s\n",
497 reg_names
[FRAME_POINTER_REGNUM
],
498 reg_names
[STACK_POINTER_REGNUM
],
499 reg_names
[FRAME_POINTER_REGNUM
]);
502 else if (fsize_with_regs
< 0x8000)
505 asm_fprintf (stream
, "\tlink.w %s,%I%wd\n",
506 reg_names
[FRAME_POINTER_REGNUM
], -fsize_with_regs
);
508 asm_fprintf (stream
, "\tlink %s,%I%wd\n",
509 reg_names
[FRAME_POINTER_REGNUM
], -fsize_with_regs
);
512 else if (TARGET_68020
)
515 asm_fprintf (stream
, "\tlink.l %s,%I%wd\n",
516 reg_names
[FRAME_POINTER_REGNUM
], -fsize_with_regs
);
518 asm_fprintf (stream
, "\tlink %s,%I%wd\n",
519 reg_names
[FRAME_POINTER_REGNUM
], -fsize_with_regs
);
524 /* Adding negative number is faster on the 68040. */
526 asm_fprintf (stream
, "\tlink.w %s,%I0\n\tadd.l %I%wd,%Rsp\n",
527 reg_names
[FRAME_POINTER_REGNUM
], -fsize_with_regs
);
529 asm_fprintf (stream
, "\tlink %s,%I0\n\taddl %I%wd,%Rsp\n",
530 reg_names
[FRAME_POINTER_REGNUM
], -fsize_with_regs
);
533 if (dwarf2out_do_frame ())
536 l
= (char *) dwarf2out_cfi_label ();
538 dwarf2out_reg_save (l
, FRAME_POINTER_REGNUM
, -cfa_offset
);
539 dwarf2out_def_cfa (l
, FRAME_POINTER_REGNUM
, cfa_offset
);
540 cfa_offset
+= current_frame
.size
;
543 else if (fsize_with_regs
) /* !frame_pointer_needed */
545 if (fsize_with_regs
< 0x8000)
547 if (fsize_with_regs
<= 8)
549 if (!TARGET_COLDFIRE
)
551 /* asm_fprintf() cannot handle %. */
553 asm_fprintf (stream
, "\tsubq.w %I%wd,%Rsp\n", fsize_with_regs
);
555 asm_fprintf (stream
, "\tsubqw %I%wd,%Rsp\n", fsize_with_regs
);
560 /* asm_fprintf() cannot handle %. */
562 asm_fprintf (stream
, "\tsubq.l %I%wd,%Rsp\n", fsize_with_regs
);
564 asm_fprintf (stream
, "\tsubql %I%wd,%Rsp\n", fsize_with_regs
);
568 else if (fsize_with_regs
<= 16 && TARGET_CPU32
)
570 /* On the CPU32 it is faster to use two subqw instructions to
571 subtract a small integer (8 < N <= 16) to a register. */
572 /* asm_fprintf() cannot handle %. */
575 "\tsubq.w %I8,%Rsp\n\tsubq.w %I%wd,%Rsp\n",
576 fsize_with_regs
- 8);
578 asm_fprintf (stream
, "\tsubqw %I8,%Rsp\n\tsubqw %I%wd,%Rsp\n",
579 fsize_with_regs
- 8);
582 else if (TARGET_68040
)
584 /* Adding negative number is faster on the 68040. */
585 /* asm_fprintf() cannot handle %. */
587 asm_fprintf (stream
, "\tadd.w %I%wd,%Rsp\n", -fsize_with_regs
);
589 asm_fprintf (stream
, "\taddw %I%wd,%Rsp\n", -fsize_with_regs
);
595 asm_fprintf (stream
, "\tlea (%wd,%Rsp),%Rsp\n", -fsize_with_regs
);
597 asm_fprintf (stream
, "\tlea %Rsp@(%wd),%Rsp\n", -fsize_with_regs
);
601 else /* fsize_with_regs >= 0x8000 */
604 asm_fprintf (stream
, "\tadd.l %I%wd,%Rsp\n", -fsize_with_regs
);
606 asm_fprintf (stream
, "\taddl %I%wd,%Rsp\n", -fsize_with_regs
);
609 if (dwarf2out_do_frame ())
611 cfa_offset
+= current_frame
.size
+ 4;
612 dwarf2out_def_cfa ("", STACK_POINTER_REGNUM
, cfa_offset
);
614 } /* !frame_pointer_needed */
618 if (current_frame
.fpu_mask
)
621 asm_fprintf (stream
, "\tfmovm %I0x%x,-(%Rsp)\n", current_frame
.fpu_mask
);
623 asm_fprintf (stream
, "\tfmovem %I0x%x,%Rsp@-\n", current_frmae
.fpu_mask
);
625 if (dwarf2out_do_frame ())
627 char *l
= (char *) dwarf2out_cfi_label ();
630 cfa_offset
+= current_frame
.fpu_no
* 12;
631 if (! frame_pointer_needed
)
632 dwarf2out_def_cfa (l
, STACK_POINTER_REGNUM
, cfa_offset
);
633 for (regno
= 16, n_regs
= 0; regno
< 24; regno
++)
634 if (current_frame
.fpu_mask
& (1 << (regno
- 16)))
635 dwarf2out_reg_save (l
, regno
,
636 -cfa_offset
+ n_regs
++ * 12);
641 /* If the stack limit is not a symbol, check it here.
642 This has the disadvantage that it may be too late... */
643 if (current_function_limit_stack
)
645 if (REG_P (stack_limit_rtx
))
647 #if defined (MOTOROLA)
648 asm_fprintf (stream
, "\tcmp.l %s,%Rsp\n\ttrapcs\n",
649 reg_names
[REGNO (stack_limit_rtx
)]);
651 asm_fprintf (stream
, "\tcmpl %s,%Rsp\n\ttrapcs\n",
652 reg_names
[REGNO (stack_limit_rtx
)]);
655 else if (GET_CODE (stack_limit_rtx
) != SYMBOL_REF
)
656 warning ("stack limit expression is not supported");
659 if (num_saved_regs
<= 2)
661 /* Store each separately in the same order moveml uses.
662 Using two movel instructions instead of a single moveml
663 is about 15% faster for the 68020 and 68030 at no expense
668 for (i
= 0; i
< 16; i
++)
669 if (current_frame
.reg_rev_mask
& (1 << i
))
673 "\t%Omove.l %s,-(%Rsp)\n",
675 "\tmovel %s,%Rsp@-\n",
678 if (dwarf2out_do_frame ())
680 char *l
= (char *) dwarf2out_cfi_label ();
683 if (! frame_pointer_needed
)
684 dwarf2out_def_cfa (l
, STACK_POINTER_REGNUM
, cfa_offset
);
685 dwarf2out_reg_save (l
, 15 - i
, -cfa_offset
);
689 else if (current_frame
.reg_rev_mask
)
693 /* The ColdFire does not support the predecrement form of the
694 MOVEM instruction, so we must adjust the stack pointer and
695 then use the plain address register indirect mode.
696 The required register save space was combined earlier with
697 the fsize_with_regs amount. */
700 asm_fprintf (stream
, "\tmovm.l %I0x%x,(%Rsp)\n", current_frame
.reg_mask
);
702 asm_fprintf (stream
, "\tmoveml %I0x%x,%Rsp@\n", current_frame
.reg_mask
);
708 asm_fprintf (stream
, "\tmovm.l %I0x%x,-(%Rsp)\n", current_frame
.reg_mask
);
710 asm_fprintf (stream
, "\tmoveml %I0x%x,%Rsp@-\n", current_frame
.reg_mask
);
713 if (dwarf2out_do_frame ())
715 char *l
= (char *) dwarf2out_cfi_label ();
718 cfa_offset
+= current_frame
.reg_no
* 4;
719 if (! frame_pointer_needed
)
720 dwarf2out_def_cfa (l
, STACK_POINTER_REGNUM
, cfa_offset
);
721 for (regno
= 0, n_regs
= 0; regno
< 16; regno
++)
722 if (current_frame
.reg_mask
& (1 << regno
))
723 dwarf2out_reg_save (l
, regno
,
724 -cfa_offset
+ n_regs
++ * 4);
727 if (!TARGET_SEP_DATA
&& flag_pic
&&
728 (current_function_uses_pic_offset_table
||
729 (!current_function_is_leaf
&& TARGET_ID_SHARED_LIBRARY
)))
731 if (TARGET_ID_SHARED_LIBRARY
)
733 asm_fprintf (stream
, "\tmovel %s@(%s), %s\n",
734 reg_names
[PIC_OFFSET_TABLE_REGNUM
],
735 m68k_library_id_string
,
736 reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
741 asm_fprintf (stream
, "\t%Olea (%Rpc, %U_GLOBAL_OFFSET_TABLE_@GOTPC), %s\n",
742 reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
744 asm_fprintf (stream
, "\tmovel %I%U_GLOBAL_OFFSET_TABLE_, %s\n",
745 reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
746 asm_fprintf (stream
, "\tlea %Rpc@(0,%s:l),%s\n",
747 reg_names
[PIC_OFFSET_TABLE_REGNUM
],
748 reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
754 /* Return true if this function's epilogue can be output as RTL. */
757 use_return_insn (void)
759 if (!reload_completed
|| frame_pointer_needed
|| get_frame_size () != 0)
762 /* We can output the epilogue as RTL only if no registers need to be
764 m68k_compute_frame_layout();
765 return current_frame
.reg_no
? false : true;
768 /* This function generates the assembly code for function exit,
769 on machines that need it.
771 The function epilogue should not depend on the current stack pointer!
772 It should use the frame pointer only, if there is a frame pointer.
773 This is mandatory because of alloca; we also take advantage of it to
774 omit stack adjustments before returning. */
777 m68k_output_function_epilogue (FILE *stream
, HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
779 HOST_WIDE_INT fsize
, fsize_with_regs
;
781 bool restore_from_sp
= false;
782 rtx insn
= get_last_insn ();
784 m68k_compute_frame_layout();
786 /* If the last insn was a BARRIER, we don't have to write any code. */
787 if (GET_CODE (insn
) == NOTE
)
788 insn
= prev_nonnote_insn (insn
);
789 if (insn
&& GET_CODE (insn
) == BARRIER
)
791 /* Output just a no-op so that debuggers don't get confused
792 about which function the pc is in at this address. */
793 fprintf (stream
, "\tnop\n");
797 #ifdef FUNCTION_EXTRA_EPILOGUE
798 FUNCTION_EXTRA_EPILOGUE (stream
, size
);
801 fsize
= current_frame
.size
;
803 /* FIXME : leaf_function_p below is too strong.
804 What we really need to know there is if there could be pending
805 stack adjustment needed at that point. */
806 restore_from_sp
= ! frame_pointer_needed
807 || (! current_function_calls_alloca
&& leaf_function_p ());
809 /* fsize_with_regs is the size we need to adjust the sp when
811 fsize_with_regs
= fsize
;
813 /* Because the ColdFire doesn't support moveml with
814 complex address modes, we must adjust the stack manually
815 after restoring registers. When the frame pointer isn't used,
816 we can merge movem adjustment into frame unlinking
817 made immediately after it. */
818 if (TARGET_COLDFIRE
&& restore_from_sp
&& (current_frame
.reg_no
> 2))
819 fsize_with_regs
+= current_frame
.reg_no
* 4;
821 if (current_frame
.offset
+ fsize
>= 0x8000
823 && (current_frame
.reg_mask
|| current_frame
.fpu_mask
))
825 /* Because the ColdFire doesn't support moveml with
826 complex address modes we make an extra correction here */
830 asm_fprintf (stream
, "\t%Omove.l %I%d,%Ra1\n",
831 -fsize
- current_frame
.offset
);
833 asm_fprintf (stream
, "\tmovel %I%d,%Ra1\n",
834 -fsize
- current_frame
.offset
);
840 asm_fprintf (stream
, "\t%Omove.l %I%wd,%Ra1\n", -fsize
);
842 asm_fprintf (stream
, "\tmovel %I%wd,%Ra1\n", -fsize
);
846 fsize
= 0, big
= true;
848 if (current_frame
.reg_no
<= 2)
850 /* Restore each separately in the same order moveml does.
851 Using two movel instructions instead of a single moveml
852 is about 15% faster for the 68020 and 68030 at no expense
856 HOST_WIDE_INT offset
= current_frame
.offset
+ fsize
;
858 for (i
= 0; i
< 16; i
++)
859 if (current_frame
.reg_mask
& (1 << i
))
864 asm_fprintf (stream
, "\t%Omove.l -%wd(%s,%Ra1.l),%s\n",
866 reg_names
[FRAME_POINTER_REGNUM
],
869 asm_fprintf (stream
, "\tmovel %s@(-%wd,%Ra1:l),%s\n",
870 reg_names
[FRAME_POINTER_REGNUM
],
875 else if (restore_from_sp
)
878 asm_fprintf (stream
, "\t%Omove.l (%Rsp)+,%s\n",
881 asm_fprintf (stream
, "\tmovel %Rsp@+,%s\n",
888 asm_fprintf (stream
, "\t%Omove.l -%wd(%s),%s\n",
890 reg_names
[FRAME_POINTER_REGNUM
],
893 asm_fprintf (stream
, "\tmovel %s@(-%wd),%s\n",
894 reg_names
[FRAME_POINTER_REGNUM
],
902 else if (current_frame
.reg_mask
)
904 /* The ColdFire requires special handling due to its limited moveml insn */
910 asm_fprintf (stream
, "\tadd.l %s,%Ra1\n", reg_names
[FRAME_POINTER_REGNUM
]);
911 asm_fprintf (stream
, "\tmovm.l (%Ra1),%I0x%x\n", current_frame
.reg_mask
);
913 asm_fprintf (stream
, "\taddl %s,%Ra1\n", reg_names
[FRAME_POINTER_REGNUM
]);
914 asm_fprintf (stream
, "\tmoveml %Ra1@,%I0x%x\n", current_frame
.reg_mask
);
917 else if (restore_from_sp
)
920 asm_fprintf (stream
, "\tmovm.l (%Rsp),%I0x%x\n", current_frame
.reg_mask
);
922 asm_fprintf (stream
, "\tmoveml %Rsp@,%I0x%x\n", current_frame
.reg_mask
);
928 asm_fprintf (stream
, "\tmovm.l -%wd(%s),%I0x%x\n",
929 current_frame
.offset
+ fsize
,
930 reg_names
[FRAME_POINTER_REGNUM
],
931 current_frame
.reg_mask
);
933 asm_fprintf (stream
, "\tmoveml %s@(-%wd),%I0x%x\n",
934 reg_names
[FRAME_POINTER_REGNUM
],
936 current_frame
.reg_mask
);
940 else /* !TARGET_COLDFIRE */
945 asm_fprintf (stream
, "\tmovm.l -%wd(%s,%Ra1.l),%I0x%x\n",
946 current_frame
.offset
+ fsize
,
947 reg_names
[FRAME_POINTER_REGNUM
],
948 current_frame
.reg_mask
);
950 asm_fprintf (stream
, "\tmoveml %s@(-%wd,%Ra1:l),%I0x%x\n",
951 reg_names
[FRAME_POINTER_REGNUM
],
952 current_frame
.offset
+ fsize
,
953 current_frame
.reg_mask
);
956 else if (restore_from_sp
)
959 asm_fprintf (stream
, "\tmovm.l (%Rsp)+,%I0x%x\n",
960 current_frame
.reg_mask
);
962 asm_fprintf (stream
, "\tmoveml %Rsp@+,%I0x%x\n",
963 current_frame
.reg_mask
);
969 asm_fprintf (stream
, "\tmovm.l -%wd(%s),%I0x%x\n",
970 current_frame
.offset
+ fsize
,
971 reg_names
[FRAME_POINTER_REGNUM
],
972 current_frame
.reg_mask
);
974 asm_fprintf (stream
, "\tmoveml %s@(-%wd),%I0x%x\n",
975 reg_names
[FRAME_POINTER_REGNUM
],
976 current_frame
.offset
+ fsize
,
977 current_frame
.reg_mask
);
982 if (current_frame
.fpu_rev_mask
)
987 asm_fprintf (stream
, "\tfmovm -%wd(%s,%Ra1.l),%I0x%x\n",
988 current_frame
.foffset
+ fsize
,
989 reg_names
[FRAME_POINTER_REGNUM
],
990 current_frame
.fpu_rev_mask
);
992 asm_fprintf (stream
, "\tfmovem %s@(-%wd,%Ra1:l),%I0x%x\n",
993 reg_names
[FRAME_POINTER_REGNUM
],
994 current_frame
.foffset
+ fsize
,
995 current_frame
.fpu_rev_mask
);
998 else if (restore_from_sp
)
1001 asm_fprintf (stream
, "\tfmovm (%Rsp)+,%I0x%x\n",
1002 current_frame
.fpu_rev_mask
);
1004 asm_fprintf (stream
, "\tfmovem %Rsp@+,%I0x%x\n",
1005 current_frame
.fpu_rev_mask
);
1011 asm_fprintf (stream
, "\tfmovm -%wd(%s),%I0x%x\n",
1012 current_frame
.foffset
+ fsize
,
1013 reg_names
[FRAME_POINTER_REGNUM
],
1014 current_frame
.fpu_mask
);
1016 asm_fprintf (stream
, "\tfmovem %s@(-%wd),%I0x%x\n",
1017 reg_names
[FRAME_POINTER_REGNUM
],
1018 current_frame
.foffset
+ fsize
,
1019 current_frame
.fpu_rev_mask
);
1023 if (frame_pointer_needed
)
1024 fprintf (stream
, "\tunlk %s\n",
1025 reg_names
[FRAME_POINTER_REGNUM
]);
1026 else if (fsize_with_regs
)
1028 if (fsize_with_regs
<= 8)
1030 if (!TARGET_COLDFIRE
)
1033 asm_fprintf (stream
, "\taddq.w %I%wd,%Rsp\n", fsize_with_regs
);
1035 asm_fprintf (stream
, "\taddqw %I%wd,%Rsp\n", fsize_with_regs
);
1038 else /* TARGET_COLDFIRE */
1041 asm_fprintf (stream
, "\taddq.l %I%wd,%Rsp\n", fsize_with_regs
);
1043 asm_fprintf (stream
, "\taddql %I%wd,%Rsp\n", fsize_with_regs
);
1047 else if (fsize_with_regs
<= 16 && TARGET_CPU32
)
1049 /* On the CPU32 it is faster to use two addqw instructions to
1050 add a small integer (8 < N <= 16) to a register. */
1052 asm_fprintf (stream
, "\taddq.w %I8,%Rsp\n\taddq.w %I%wd,%Rsp\n",
1053 fsize_with_regs
- 8);
1055 asm_fprintf (stream
, "\taddqw %I8,%Rsp\n\taddqw %I%wd,%Rsp\n",
1056 fsize_with_regs
- 8);
1059 else if (fsize_with_regs
< 0x8000)
1064 asm_fprintf (stream
, "\tadd.w %I%wd,%Rsp\n", fsize_with_regs
);
1066 asm_fprintf (stream
, "\taddw %I%wd,%Rsp\n", fsize_with_regs
);
1072 asm_fprintf (stream
, "\tlea (%wd,%Rsp),%Rsp\n", fsize_with_regs
);
1074 asm_fprintf (stream
, "\tlea %Rsp@(%wd),%Rsp\n", fsize_with_regs
);
1081 asm_fprintf (stream
, "\tadd.l %I%wd,%Rsp\n", fsize_with_regs
);
1083 asm_fprintf (stream
, "\taddl %I%wd,%Rsp\n", fsize_with_regs
);
1087 if (current_function_calls_eh_return
)
1090 asm_fprintf (stream
, "\tadd.l %Ra0,%Rsp\n");
1092 asm_fprintf (stream
, "\taddl %Ra0,%Rsp\n");
1095 if (m68k_interrupt_function_p (current_function_decl
))
1096 fprintf (stream
, "\trte\n");
1097 else if (current_function_pops_args
)
1098 asm_fprintf (stream
, "\trtd %I%d\n", current_function_pops_args
);
1100 fprintf (stream
, "\trts\n");
1103 /* Similar to general_operand, but exclude stack_pointer_rtx. */
1106 not_sp_operand (rtx op
, enum machine_mode mode
)
1108 return op
!= stack_pointer_rtx
&& nonimmediate_operand (op
, mode
);
1111 /* Return true if X is a valid comparison operator for the dbcc
1114 Note it rejects floating point comparison operators.
1115 (In the future we could use Fdbcc).
1117 It also rejects some comparisons when CC_NO_OVERFLOW is set. */
1120 valid_dbcc_comparison_p (rtx x
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1122 switch (GET_CODE (x
))
1124 case EQ
: case NE
: case GTU
: case LTU
:
1128 /* Reject some when CC_NO_OVERFLOW is set. This may be over
1130 case GT
: case LT
: case GE
: case LE
:
1131 return ! (cc_prev_status
.flags
& CC_NO_OVERFLOW
);
1137 /* Return nonzero if flags are currently in the 68881 flag register. */
1139 flags_in_68881 (void)
1141 /* We could add support for these in the future */
1142 return cc_status
.flags
& CC_IN_68881
;
1145 /* Output a BSR instruction suitable for PIC code. */
1147 m68k_output_pic_call(rtx dest
)
1151 if (!(GET_CODE (dest
) == MEM
&& GET_CODE (XEXP (dest
, 0)) == SYMBOL_REF
))
1153 /* We output a BSR instruction if we're using -fpic or we're building for
1154 * a target that supports long branches. If we're building -fPIC on the
1155 * 68000, 68010 or ColdFire we generate one of two sequences:
1156 * a shorter one that uses a GOT entry or a longer one that doesn't.
1157 * We'll use the -Os command-line flag to decide which to generate.
1158 * Both sequences take the same time to execute on the ColdFire.
1160 else if (TARGET_PCREL
)
1162 else if ((flag_pic
== 1) || TARGET_68020
)
1165 #elif defined(USE_GAS)
1166 out
= "bsr.l %0@PLTPC";
1168 out
= "bsr %0@PLTPC";
1170 else if (optimize_size
|| TARGET_ID_SHARED_LIBRARY
)
1171 out
= "move.l %0@GOT(%%a5), %%a1\n\tjsr (%%a1)";
1173 out
= "lea %0-.-8,%%a1\n\tjsr 0(%%pc,%%a1)";
1175 output_asm_insn(out
, &dest
);
1178 /* Output a dbCC; jCC sequence. Note we do not handle the
1179 floating point version of this sequence (Fdbcc). We also
1180 do not handle alternative conditions when CC_NO_OVERFLOW is
1181 set. It is assumed that valid_dbcc_comparison_p and flags_in_68881 will
1182 kick those out before we get here. */
1185 output_dbcc_and_branch (rtx
*operands
)
1187 switch (GET_CODE (operands
[3]))
1191 output_asm_insn ("dbeq %0,%l1\n\tjbeq %l2", operands
);
1193 output_asm_insn ("dbeq %0,%l1\n\tjeq %l2", operands
);
1199 output_asm_insn ("dbne %0,%l1\n\tjbne %l2", operands
);
1201 output_asm_insn ("dbne %0,%l1\n\tjne %l2", operands
);
1207 output_asm_insn ("dbgt %0,%l1\n\tjbgt %l2", operands
);
1209 output_asm_insn ("dbgt %0,%l1\n\tjgt %l2", operands
);
1215 output_asm_insn ("dbhi %0,%l1\n\tjbhi %l2", operands
);
1217 output_asm_insn ("dbhi %0,%l1\n\tjhi %l2", operands
);
1223 output_asm_insn ("dblt %0,%l1\n\tjblt %l2", operands
);
1225 output_asm_insn ("dblt %0,%l1\n\tjlt %l2", operands
);
1231 output_asm_insn ("dbcs %0,%l1\n\tjbcs %l2", operands
);
1233 output_asm_insn ("dbcs %0,%l1\n\tjcs %l2", operands
);
1239 output_asm_insn ("dbge %0,%l1\n\tjbge %l2", operands
);
1241 output_asm_insn ("dbge %0,%l1\n\tjge %l2", operands
);
1247 output_asm_insn ("dbcc %0,%l1\n\tjbcc %l2", operands
);
1249 output_asm_insn ("dbcc %0,%l1\n\tjcc %l2", operands
);
1255 output_asm_insn ("dble %0,%l1\n\tjble %l2", operands
);
1257 output_asm_insn ("dble %0,%l1\n\tjle %l2", operands
);
1263 output_asm_insn ("dbls %0,%l1\n\tjbls %l2", operands
);
1265 output_asm_insn ("dbls %0,%l1\n\tjls %l2", operands
);
1273 /* If the decrement is to be done in SImode, then we have
1274 to compensate for the fact that dbcc decrements in HImode. */
1275 switch (GET_MODE (operands
[0]))
1279 output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjbpl %l1", operands
);
1281 output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjpl %l1", operands
);
1294 output_scc_di(rtx op
, rtx operand1
, rtx operand2
, rtx dest
)
1297 enum rtx_code op_code
= GET_CODE (op
);
1299 /* This does not produce a useful cc. */
1302 /* The m68k cmp.l instruction requires operand1 to be a reg as used
1303 below. Swap the operands and change the op if these requirements
1304 are not fulfilled. */
1305 if (GET_CODE (operand2
) == REG
&& GET_CODE (operand1
) != REG
)
1309 operand1
= operand2
;
1311 op_code
= swap_condition (op_code
);
1313 loperands
[0] = operand1
;
1314 if (GET_CODE (operand1
) == REG
)
1315 loperands
[1] = gen_rtx_REG (SImode
, REGNO (operand1
) + 1);
1317 loperands
[1] = adjust_address (operand1
, SImode
, 4);
1318 if (operand2
!= const0_rtx
)
1320 loperands
[2] = operand2
;
1321 if (GET_CODE (operand2
) == REG
)
1322 loperands
[3] = gen_rtx_REG (SImode
, REGNO (operand2
) + 1);
1324 loperands
[3] = adjust_address (operand2
, SImode
, 4);
1326 loperands
[4] = gen_label_rtx();
1327 if (operand2
!= const0_rtx
)
1330 #ifdef SGS_CMP_ORDER
1331 output_asm_insn ("cmp%.l %0,%2\n\tjbne %l4\n\tcmp%.l %1,%3", loperands
);
1333 output_asm_insn ("cmp%.l %2,%0\n\tjbne %l4\n\tcmp%.l %3,%1", loperands
);
1336 #ifdef SGS_CMP_ORDER
1337 output_asm_insn ("cmp%.l %0,%2\n\tjne %l4\n\tcmp%.l %1,%3", loperands
);
1339 output_asm_insn ("cmp%.l %2,%0\n\tjne %l4\n\tcmp%.l %3,%1", loperands
);
1345 if (TARGET_68020
|| TARGET_COLDFIRE
|| ! ADDRESS_REG_P (loperands
[0]))
1346 output_asm_insn ("tst%.l %0", loperands
);
1349 #ifdef SGS_CMP_ORDER
1350 output_asm_insn ("cmp%.w %0,%#0", loperands
);
1352 output_asm_insn ("cmp%.w %#0,%0", loperands
);
1357 output_asm_insn ("jbne %l4", loperands
);
1359 output_asm_insn ("jne %l4", loperands
);
1362 if (TARGET_68020
|| TARGET_COLDFIRE
|| ! ADDRESS_REG_P (loperands
[1]))
1363 output_asm_insn ("tst%.l %1", loperands
);
1366 #ifdef SGS_CMP_ORDER
1367 output_asm_insn ("cmp%.w %1,%#0", loperands
);
1369 output_asm_insn ("cmp%.w %#0,%1", loperands
);
1374 loperands
[5] = dest
;
1379 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1380 CODE_LABEL_NUMBER (loperands
[4]));
1381 output_asm_insn ("seq %5", loperands
);
1385 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1386 CODE_LABEL_NUMBER (loperands
[4]));
1387 output_asm_insn ("sne %5", loperands
);
1391 loperands
[6] = gen_label_rtx();
1393 output_asm_insn ("shi %5\n\tjbra %l6", loperands
);
1395 output_asm_insn ("shi %5\n\tjra %l6", loperands
);
1397 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1398 CODE_LABEL_NUMBER (loperands
[4]));
1399 output_asm_insn ("sgt %5", loperands
);
1400 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1401 CODE_LABEL_NUMBER (loperands
[6]));
1405 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1406 CODE_LABEL_NUMBER (loperands
[4]));
1407 output_asm_insn ("shi %5", loperands
);
1411 loperands
[6] = gen_label_rtx();
1413 output_asm_insn ("scs %5\n\tjbra %l6", loperands
);
1415 output_asm_insn ("scs %5\n\tjra %l6", loperands
);
1417 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1418 CODE_LABEL_NUMBER (loperands
[4]));
1419 output_asm_insn ("slt %5", loperands
);
1420 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1421 CODE_LABEL_NUMBER (loperands
[6]));
1425 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1426 CODE_LABEL_NUMBER (loperands
[4]));
1427 output_asm_insn ("scs %5", loperands
);
1431 loperands
[6] = gen_label_rtx();
1433 output_asm_insn ("scc %5\n\tjbra %l6", loperands
);
1435 output_asm_insn ("scc %5\n\tjra %l6", loperands
);
1437 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1438 CODE_LABEL_NUMBER (loperands
[4]));
1439 output_asm_insn ("sge %5", loperands
);
1440 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1441 CODE_LABEL_NUMBER (loperands
[6]));
1445 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1446 CODE_LABEL_NUMBER (loperands
[4]));
1447 output_asm_insn ("scc %5", loperands
);
1451 loperands
[6] = gen_label_rtx();
1453 output_asm_insn ("sls %5\n\tjbra %l6", loperands
);
1455 output_asm_insn ("sls %5\n\tjra %l6", loperands
);
1457 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1458 CODE_LABEL_NUMBER (loperands
[4]));
1459 output_asm_insn ("sle %5", loperands
);
1460 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1461 CODE_LABEL_NUMBER (loperands
[6]));
1465 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1466 CODE_LABEL_NUMBER (loperands
[4]));
1467 output_asm_insn ("sls %5", loperands
);
1477 output_btst (rtx
*operands
, rtx countop
, rtx dataop
, rtx insn
, int signpos
)
1479 operands
[0] = countop
;
1480 operands
[1] = dataop
;
1482 if (GET_CODE (countop
) == CONST_INT
)
1484 register int count
= INTVAL (countop
);
1485 /* If COUNT is bigger than size of storage unit in use,
1486 advance to the containing unit of same size. */
1487 if (count
> signpos
)
1489 int offset
= (count
& ~signpos
) / 8;
1490 count
= count
& signpos
;
1491 operands
[1] = dataop
= adjust_address (dataop
, QImode
, offset
);
1493 if (count
== signpos
)
1494 cc_status
.flags
= CC_NOT_POSITIVE
| CC_Z_IN_NOT_N
;
1496 cc_status
.flags
= CC_NOT_NEGATIVE
| CC_Z_IN_NOT_N
;
1498 /* These three statements used to use next_insns_test_no...
1499 but it appears that this should do the same job. */
1501 && next_insn_tests_no_inequality (insn
))
1504 && next_insn_tests_no_inequality (insn
))
1507 && next_insn_tests_no_inequality (insn
))
1510 cc_status
.flags
= CC_NOT_NEGATIVE
;
1512 return "btst %0,%1";
1515 /* Returns true if OP is either a symbol reference or a sum of a symbol
1516 reference and a constant. */
1519 symbolic_operand (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1521 switch (GET_CODE (op
))
1529 return ((GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
1530 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
)
1531 && GET_CODE (XEXP (op
, 1)) == CONST_INT
);
1533 #if 0 /* Deleted, with corresponding change in m68k.h,
1534 so as to fit the specs. No CONST_DOUBLE is ever symbolic. */
1536 return GET_MODE (op
) == mode
;
1544 /* Check for sign_extend or zero_extend. Used for bit-count operands. */
1547 extend_operator(rtx x
, enum machine_mode mode
)
1549 if (mode
!= VOIDmode
&& GET_MODE(x
) != mode
)
1551 switch (GET_CODE(x
))
1562 /* Legitimize PIC addresses. If the address is already
1563 position-independent, we return ORIG. Newly generated
1564 position-independent addresses go to REG. If we need more
1565 than one register, we lose.
1567 An address is legitimized by making an indirect reference
1568 through the Global Offset Table with the name of the symbol
1571 The assembler and linker are responsible for placing the
1572 address of the symbol in the GOT. The function prologue
1573 is responsible for initializing a5 to the starting address
1576 The assembler is also responsible for translating a symbol name
1577 into a constant displacement from the start of the GOT.
1579 A quick example may make things a little clearer:
1581 When not generating PIC code to store the value 12345 into _foo
1582 we would generate the following code:
1586 When generating PIC two transformations are made. First, the compiler
1587 loads the address of foo into a register. So the first transformation makes:
1592 The code in movsi will intercept the lea instruction and call this
1593 routine which will transform the instructions into:
1595 movel a5@(_foo:w), a0
1599 That (in a nutshell) is how *all* symbol and label references are
1603 legitimize_pic_address (rtx orig
, enum machine_mode mode ATTRIBUTE_UNUSED
,
1608 /* First handle a simple SYMBOL_REF or LABEL_REF */
1609 if (GET_CODE (orig
) == SYMBOL_REF
|| GET_CODE (orig
) == LABEL_REF
)
1614 pic_ref
= gen_rtx_MEM (Pmode
,
1615 gen_rtx_PLUS (Pmode
,
1616 pic_offset_table_rtx
, orig
));
1617 current_function_uses_pic_offset_table
= 1;
1618 RTX_UNCHANGING_P (pic_ref
) = 1;
1619 emit_move_insn (reg
, pic_ref
);
1622 else if (GET_CODE (orig
) == CONST
)
1626 /* Make sure this has not already been legitimized. */
1627 if (GET_CODE (XEXP (orig
, 0)) == PLUS
1628 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
1634 /* legitimize both operands of the PLUS */
1635 if (GET_CODE (XEXP (orig
, 0)) == PLUS
)
1637 base
= legitimize_pic_address (XEXP (XEXP (orig
, 0), 0), Pmode
, reg
);
1638 orig
= legitimize_pic_address (XEXP (XEXP (orig
, 0), 1), Pmode
,
1639 base
== reg
? 0 : reg
);
1643 if (GET_CODE (orig
) == CONST_INT
)
1644 return plus_constant (base
, INTVAL (orig
));
1645 pic_ref
= gen_rtx_PLUS (Pmode
, base
, orig
);
1646 /* Likewise, should we set special REG_NOTEs here? */
1652 typedef enum { MOVL
, SWAP
, NEGW
, NOTW
, NOTB
, MOVQ
} CONST_METHOD
;
1654 static CONST_METHOD
const_method (rtx
);
1656 #define USE_MOVQ(i) ((unsigned)((i) + 128) <= 255)
1659 const_method (rtx constant
)
1664 i
= INTVAL (constant
);
1668 /* The ColdFire doesn't have byte or word operations. */
1669 /* FIXME: This may not be useful for the m68060 either */
1670 if (!TARGET_COLDFIRE
)
1672 /* if -256 < N < 256 but N is not in range for a moveq
1673 N^ff will be, so use moveq #N^ff, dreg; not.b dreg. */
1674 if (USE_MOVQ (i
^ 0xff))
1676 /* Likewise, try with not.w */
1677 if (USE_MOVQ (i
^ 0xffff))
1679 /* This is the only value where neg.w is useful */
1682 /* Try also with swap */
1684 if (USE_MOVQ ((u
>> 16) | (u
<< 16)))
1687 /* Otherwise, use move.l */
1692 const_int_cost (rtx constant
)
1694 switch (const_method (constant
))
1697 /* Constants between -128 and 127 are cheap due to moveq */
1703 /* Constants easily generated by moveq + not.b/not.w/neg.w/swap */
1713 m68k_rtx_costs (rtx x
, int code
, int outer_code
, int *total
)
1718 /* Constant zero is super cheap due to clr instruction. */
1719 if (x
== const0_rtx
)
1722 *total
= const_int_cost (x
);
1732 /* Make 0.0 cheaper than other floating constants to
1733 encourage creating tstsf and tstdf insns. */
1734 if (outer_code
== COMPARE
1735 && (x
== CONST0_RTX (SFmode
) || x
== CONST0_RTX (DFmode
)))
1741 /* These are vaguely right for a 68020. */
1742 /* The costs for long multiply have been adjusted to work properly
1743 in synth_mult on the 68020, relative to an average of the time
1744 for add and the time for shift, taking away a little more because
1745 sometimes move insns are needed. */
1746 /* div?.w is relatively cheaper on 68000 counted in COSTS_N_INSNS terms. */
1747 #define MULL_COST (TARGET_68060 ? 2 : TARGET_68040 ? 5 : TARGET_CFV3 ? 3 : TARGET_COLDFIRE ? 10 : 13)
1748 #define MULW_COST (TARGET_68060 ? 2 : TARGET_68040 ? 3 : TARGET_68020 ? 8 : \
1749 TARGET_CFV3 ? 2 : 5)
1750 #define DIVW_COST (TARGET_68020 ? 27 : TARGET_CF_HWDIV ? 11 : 12)
1753 /* An lea costs about three times as much as a simple add. */
1754 if (GET_MODE (x
) == SImode
1755 && GET_CODE (XEXP (x
, 1)) == REG
1756 && GET_CODE (XEXP (x
, 0)) == MULT
1757 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
1758 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
1759 && (INTVAL (XEXP (XEXP (x
, 0), 1)) == 2
1760 || INTVAL (XEXP (XEXP (x
, 0), 1)) == 4
1761 || INTVAL (XEXP (XEXP (x
, 0), 1)) == 8))
1763 /* lea an@(dx:l:i),am */
1764 *total
= COSTS_N_INSNS (TARGET_COLDFIRE
? 2 : 3);
1774 *total
= COSTS_N_INSNS(1);
1777 if (! TARGET_68020
&& ! TARGET_COLDFIRE
)
1779 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
1781 if (INTVAL (XEXP (x
, 1)) < 16)
1782 *total
= COSTS_N_INSNS (2) + INTVAL (XEXP (x
, 1)) / 2;
1784 /* We're using clrw + swap for these cases. */
1785 *total
= COSTS_N_INSNS (4) + (INTVAL (XEXP (x
, 1)) - 16) / 2;
1788 *total
= COSTS_N_INSNS (10); /* worst case */
1791 /* A shift by a big integer takes an extra instruction. */
1792 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
1793 && (INTVAL (XEXP (x
, 1)) == 16))
1795 *total
= COSTS_N_INSNS (2); /* clrw;swap */
1798 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
1799 && !(INTVAL (XEXP (x
, 1)) > 0
1800 && INTVAL (XEXP (x
, 1)) <= 8))
1802 *total
= COSTS_N_INSNS (TARGET_COLDFIRE
? 1 : 3); /* lsr #i,dn */
1808 if ((GET_CODE (XEXP (x
, 0)) == ZERO_EXTEND
1809 || GET_CODE (XEXP (x
, 0)) == SIGN_EXTEND
)
1810 && GET_MODE (x
) == SImode
)
1811 *total
= COSTS_N_INSNS (MULW_COST
);
1812 else if (GET_MODE (x
) == QImode
|| GET_MODE (x
) == HImode
)
1813 *total
= COSTS_N_INSNS (MULW_COST
);
1815 *total
= COSTS_N_INSNS (MULL_COST
);
1822 if (GET_MODE (x
) == QImode
|| GET_MODE (x
) == HImode
)
1823 *total
= COSTS_N_INSNS (DIVW_COST
); /* div.w */
1824 else if (TARGET_CF_HWDIV
)
1825 *total
= COSTS_N_INSNS (18);
1827 *total
= COSTS_N_INSNS (43); /* div.l */
1836 output_move_const_into_data_reg (rtx
*operands
)
1840 i
= INTVAL (operands
[1]);
1841 switch (const_method (operands
[1]))
1844 return "moveq %1,%0";
1846 operands
[1] = GEN_INT (i
^ 0xff);
1847 return "moveq %1,%0\n\tnot%.b %0";
1849 operands
[1] = GEN_INT (i
^ 0xffff);
1850 return "moveq %1,%0\n\tnot%.w %0";
1852 return "moveq %#-128,%0\n\tneg%.w %0";
1857 operands
[1] = GEN_INT ((u
<< 16) | (u
>> 16));
1858 return "moveq %1,%0\n\tswap %0";
1861 return "move%.l %1,%0";
1868 output_move_simode_const (rtx
*operands
)
1870 if (operands
[1] == const0_rtx
1871 && (DATA_REG_P (operands
[0])
1872 || GET_CODE (operands
[0]) == MEM
)
1873 /* clr insns on 68000 read before writing.
1874 This isn't so on the 68010, but we have no TARGET_68010. */
1875 && ((TARGET_68020
|| TARGET_COLDFIRE
)
1876 || !(GET_CODE (operands
[0]) == MEM
1877 && MEM_VOLATILE_P (operands
[0]))))
1879 else if (operands
[1] == const0_rtx
1880 && ADDRESS_REG_P (operands
[0]))
1881 return "sub%.l %0,%0";
1882 else if (DATA_REG_P (operands
[0]))
1883 return output_move_const_into_data_reg (operands
);
1884 else if (ADDRESS_REG_P (operands
[0])
1885 && INTVAL (operands
[1]) < 0x8000
1886 && INTVAL (operands
[1]) >= -0x8000)
1887 return "move%.w %1,%0";
1888 else if (GET_CODE (operands
[0]) == MEM
1889 && GET_CODE (XEXP (operands
[0], 0)) == PRE_DEC
1890 && REGNO (XEXP (XEXP (operands
[0], 0), 0)) == STACK_POINTER_REGNUM
1891 && INTVAL (operands
[1]) < 0x8000
1892 && INTVAL (operands
[1]) >= -0x8000)
1894 return "move%.l %1,%0";
1898 output_move_simode (rtx
*operands
)
1900 if (GET_CODE (operands
[1]) == CONST_INT
)
1901 return output_move_simode_const (operands
);
1902 else if ((GET_CODE (operands
[1]) == SYMBOL_REF
1903 || GET_CODE (operands
[1]) == CONST
)
1904 && push_operand (operands
[0], SImode
))
1906 else if ((GET_CODE (operands
[1]) == SYMBOL_REF
1907 || GET_CODE (operands
[1]) == CONST
)
1908 && ADDRESS_REG_P (operands
[0]))
1909 return "lea %a1,%0";
1910 return "move%.l %1,%0";
1914 output_move_himode (rtx
*operands
)
1916 if (GET_CODE (operands
[1]) == CONST_INT
)
1918 if (operands
[1] == const0_rtx
1919 && (DATA_REG_P (operands
[0])
1920 || GET_CODE (operands
[0]) == MEM
)
1921 /* clr insns on 68000 read before writing.
1922 This isn't so on the 68010, but we have no TARGET_68010. */
1923 && ((TARGET_68020
|| TARGET_COLDFIRE
)
1924 || !(GET_CODE (operands
[0]) == MEM
1925 && MEM_VOLATILE_P (operands
[0]))))
1927 else if (operands
[1] == const0_rtx
1928 && ADDRESS_REG_P (operands
[0]))
1929 return "sub%.l %0,%0";
1930 else if (DATA_REG_P (operands
[0])
1931 && INTVAL (operands
[1]) < 128
1932 && INTVAL (operands
[1]) >= -128)
1934 return "moveq %1,%0";
1936 else if (INTVAL (operands
[1]) < 0x8000
1937 && INTVAL (operands
[1]) >= -0x8000)
1938 return "move%.w %1,%0";
1940 else if (CONSTANT_P (operands
[1]))
1941 return "move%.l %1,%0";
1942 /* Recognize the insn before a tablejump, one that refers
1943 to a table of offsets. Such an insn will need to refer
1944 to a label on the insn. So output one. Use the label-number
1945 of the table of offsets to generate this label. This code,
1946 and similar code below, assumes that there will be at most one
1947 reference to each table. */
1948 if (GET_CODE (operands
[1]) == MEM
1949 && GET_CODE (XEXP (operands
[1], 0)) == PLUS
1950 && GET_CODE (XEXP (XEXP (operands
[1], 0), 1)) == LABEL_REF
1951 && GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) != PLUS
)
1953 rtx labelref
= XEXP (XEXP (operands
[1], 0), 1);
1954 #if defined (MOTOROLA) && !defined (SGS_SWITCH_TABLES)
1956 asm_fprintf (asm_out_file
, "\tset %LLI%d,.+2\n",
1957 CODE_LABEL_NUMBER (XEXP (labelref
, 0)));
1959 asm_fprintf (asm_out_file
, "\t.set %LLI%d,.+2\n",
1960 CODE_LABEL_NUMBER (XEXP (labelref
, 0)));
1961 #endif /* not SGS */
1962 #else /* SGS_SWITCH_TABLES or not MOTOROLA */
1963 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "LI",
1964 CODE_LABEL_NUMBER (XEXP (labelref
, 0)));
1965 #ifdef SGS_SWITCH_TABLES
1966 /* Set flag saying we need to define the symbol
1967 LD%n (with value L%n-LI%n) at the end of the switch table. */
1968 switch_table_difference_label_flag
= 1;
1969 #endif /* SGS_SWITCH_TABLES */
1970 #endif /* SGS_SWITCH_TABLES or not MOTOROLA */
1972 return "move%.w %1,%0";
1976 output_move_qimode (rtx
*operands
)
1980 /* This is probably useless, since it loses for pushing a struct
1981 of several bytes a byte at a time. */
1982 /* 68k family always modifies the stack pointer by at least 2, even for
1983 byte pushes. The 5200 (ColdFire) does not do this. */
1984 if (GET_CODE (operands
[0]) == MEM
1985 && GET_CODE (XEXP (operands
[0], 0)) == PRE_DEC
1986 && XEXP (XEXP (operands
[0], 0), 0) == stack_pointer_rtx
1987 && ! ADDRESS_REG_P (operands
[1])
1988 && ! TARGET_COLDFIRE
)
1990 xoperands
[1] = operands
[1];
1992 = gen_rtx_MEM (QImode
,
1993 gen_rtx_PLUS (VOIDmode
, stack_pointer_rtx
, const1_rtx
));
1994 /* Just pushing a byte puts it in the high byte of the halfword. */
1995 /* We must put it in the low-order, high-numbered byte. */
1996 if (!reg_mentioned_p (stack_pointer_rtx
, operands
[1]))
1998 xoperands
[3] = stack_pointer_rtx
;
1999 output_asm_insn ("subq%.l %#2,%3\n\tmove%.b %1,%2", xoperands
);
2002 output_asm_insn ("move%.b %1,%-\n\tmove%.b %@,%2", xoperands
);
2006 /* clr and st insns on 68000 read before writing.
2007 This isn't so on the 68010, but we have no TARGET_68010. */
2008 if (!ADDRESS_REG_P (operands
[0])
2009 && ((TARGET_68020
|| TARGET_COLDFIRE
)
2010 || !(GET_CODE (operands
[0]) == MEM
&& MEM_VOLATILE_P (operands
[0]))))
2012 if (operands
[1] == const0_rtx
)
2014 if ((!TARGET_COLDFIRE
|| DATA_REG_P (operands
[0]))
2015 && GET_CODE (operands
[1]) == CONST_INT
2016 && (INTVAL (operands
[1]) & 255) == 255)
2022 if (GET_CODE (operands
[1]) == CONST_INT
2023 && DATA_REG_P (operands
[0])
2024 && INTVAL (operands
[1]) < 128
2025 && INTVAL (operands
[1]) >= -128)
2027 return "moveq %1,%0";
2029 if (operands
[1] == const0_rtx
&& ADDRESS_REG_P (operands
[0]))
2030 return "sub%.l %0,%0";
2031 if (GET_CODE (operands
[1]) != CONST_INT
&& CONSTANT_P (operands
[1]))
2032 return "move%.l %1,%0";
2033 /* 68k family (including the 5200 ColdFire) does not support byte moves to
2034 from address registers. */
2035 if (ADDRESS_REG_P (operands
[0]) || ADDRESS_REG_P (operands
[1]))
2036 return "move%.w %1,%0";
2037 return "move%.b %1,%0";
2041 output_move_stricthi (rtx
*operands
)
2043 if (operands
[1] == const0_rtx
2044 /* clr insns on 68000 read before writing.
2045 This isn't so on the 68010, but we have no TARGET_68010. */
2046 && ((TARGET_68020
|| TARGET_COLDFIRE
)
2047 || !(GET_CODE (operands
[0]) == MEM
&& MEM_VOLATILE_P (operands
[0]))))
2049 return "move%.w %1,%0";
2053 output_move_strictqi (rtx
*operands
)
2055 if (operands
[1] == const0_rtx
2056 /* clr insns on 68000 read before writing.
2057 This isn't so on the 68010, but we have no TARGET_68010. */
2058 && ((TARGET_68020
|| TARGET_COLDFIRE
)
2059 || !(GET_CODE (operands
[0]) == MEM
&& MEM_VOLATILE_P (operands
[0]))))
2061 return "move%.b %1,%0";
2064 /* Return the best assembler insn template
2065 for moving operands[1] into operands[0] as a fullword. */
2068 singlemove_string (rtx
*operands
)
2070 if (GET_CODE (operands
[1]) == CONST_INT
)
2071 return output_move_simode_const (operands
);
2072 return "move%.l %1,%0";
2076 /* Output assembler code to perform a doubleword move insn
2077 with operands OPERANDS. */
2080 output_move_double (rtx
*operands
)
2084 REGOP
, OFFSOP
, MEMOP
, PUSHOP
, POPOP
, CNSTOP
, RNDOP
2089 rtx addreg0
= 0, addreg1
= 0;
2090 int dest_overlapped_low
= 0;
2091 int size
= GET_MODE_SIZE (GET_MODE (operands
[0]));
2096 /* First classify both operands. */
2098 if (REG_P (operands
[0]))
2100 else if (offsettable_memref_p (operands
[0]))
2102 else if (GET_CODE (XEXP (operands
[0], 0)) == POST_INC
)
2104 else if (GET_CODE (XEXP (operands
[0], 0)) == PRE_DEC
)
2106 else if (GET_CODE (operands
[0]) == MEM
)
2111 if (REG_P (operands
[1]))
2113 else if (CONSTANT_P (operands
[1]))
2115 else if (offsettable_memref_p (operands
[1]))
2117 else if (GET_CODE (XEXP (operands
[1], 0)) == POST_INC
)
2119 else if (GET_CODE (XEXP (operands
[1], 0)) == PRE_DEC
)
2121 else if (GET_CODE (operands
[1]) == MEM
)
2126 /* Check for the cases that the operand constraints are not
2127 supposed to allow to happen. Abort if we get one,
2128 because generating code for these cases is painful. */
2130 if (optype0
== RNDOP
|| optype1
== RNDOP
)
2133 /* If one operand is decrementing and one is incrementing
2134 decrement the former register explicitly
2135 and change that operand into ordinary indexing. */
2137 if (optype0
== PUSHOP
&& optype1
== POPOP
)
2139 operands
[0] = XEXP (XEXP (operands
[0], 0), 0);
2141 output_asm_insn ("sub%.l %#12,%0", operands
);
2143 output_asm_insn ("subq%.l %#8,%0", operands
);
2144 if (GET_MODE (operands
[1]) == XFmode
)
2145 operands
[0] = gen_rtx_MEM (XFmode
, operands
[0]);
2146 else if (GET_MODE (operands
[0]) == DFmode
)
2147 operands
[0] = gen_rtx_MEM (DFmode
, operands
[0]);
2149 operands
[0] = gen_rtx_MEM (DImode
, operands
[0]);
2152 if (optype0
== POPOP
&& optype1
== PUSHOP
)
2154 operands
[1] = XEXP (XEXP (operands
[1], 0), 0);
2156 output_asm_insn ("sub%.l %#12,%1", operands
);
2158 output_asm_insn ("subq%.l %#8,%1", operands
);
2159 if (GET_MODE (operands
[1]) == XFmode
)
2160 operands
[1] = gen_rtx_MEM (XFmode
, operands
[1]);
2161 else if (GET_MODE (operands
[1]) == DFmode
)
2162 operands
[1] = gen_rtx_MEM (DFmode
, operands
[1]);
2164 operands
[1] = gen_rtx_MEM (DImode
, operands
[1]);
2168 /* If an operand is an unoffsettable memory ref, find a register
2169 we can increment temporarily to make it refer to the second word. */
2171 if (optype0
== MEMOP
)
2172 addreg0
= find_addr_reg (XEXP (operands
[0], 0));
2174 if (optype1
== MEMOP
)
2175 addreg1
= find_addr_reg (XEXP (operands
[1], 0));
2177 /* Ok, we can do one word at a time.
2178 Normally we do the low-numbered word first,
2179 but if either operand is autodecrementing then we
2180 do the high-numbered word first.
2182 In either case, set up in LATEHALF the operands to use
2183 for the high-numbered word and in some cases alter the
2184 operands in OPERANDS to be suitable for the low-numbered word. */
2188 if (optype0
== REGOP
)
2190 latehalf
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 2);
2191 middlehalf
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 1);
2193 else if (optype0
== OFFSOP
)
2195 middlehalf
[0] = adjust_address (operands
[0], SImode
, 4);
2196 latehalf
[0] = adjust_address (operands
[0], SImode
, size
- 4);
2200 middlehalf
[0] = operands
[0];
2201 latehalf
[0] = operands
[0];
2204 if (optype1
== REGOP
)
2206 latehalf
[1] = gen_rtx_REG (SImode
, REGNO (operands
[1]) + 2);
2207 middlehalf
[1] = gen_rtx_REG (SImode
, REGNO (operands
[1]) + 1);
2209 else if (optype1
== OFFSOP
)
2211 middlehalf
[1] = adjust_address (operands
[1], SImode
, 4);
2212 latehalf
[1] = adjust_address (operands
[1], SImode
, size
- 4);
2214 else if (optype1
== CNSTOP
)
2216 if (GET_CODE (operands
[1]) == CONST_DOUBLE
)
2221 REAL_VALUE_FROM_CONST_DOUBLE (r
, operands
[1]);
2222 REAL_VALUE_TO_TARGET_LONG_DOUBLE (r
, l
);
2223 operands
[1] = GEN_INT (l
[0]);
2224 middlehalf
[1] = GEN_INT (l
[1]);
2225 latehalf
[1] = GEN_INT (l
[2]);
2227 else if (CONSTANT_P (operands
[1]))
2229 /* actually, no non-CONST_DOUBLE constant should ever
2232 if (GET_CODE (operands
[1]) == CONST_INT
&& INTVAL (operands
[1]) < 0)
2233 latehalf
[1] = constm1_rtx
;
2235 latehalf
[1] = const0_rtx
;
2240 middlehalf
[1] = operands
[1];
2241 latehalf
[1] = operands
[1];
2245 /* size is not 12: */
2247 if (optype0
== REGOP
)
2248 latehalf
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 1);
2249 else if (optype0
== OFFSOP
)
2250 latehalf
[0] = adjust_address (operands
[0], SImode
, size
- 4);
2252 latehalf
[0] = operands
[0];
2254 if (optype1
== REGOP
)
2255 latehalf
[1] = gen_rtx_REG (SImode
, REGNO (operands
[1]) + 1);
2256 else if (optype1
== OFFSOP
)
2257 latehalf
[1] = adjust_address (operands
[1], SImode
, size
- 4);
2258 else if (optype1
== CNSTOP
)
2259 split_double (operands
[1], &operands
[1], &latehalf
[1]);
2261 latehalf
[1] = operands
[1];
2264 /* If insn is effectively movd N(sp),-(sp) then we will do the
2265 high word first. We should use the adjusted operand 1 (which is N+4(sp))
2266 for the low word as well, to compensate for the first decrement of sp. */
2267 if (optype0
== PUSHOP
2268 && REGNO (XEXP (XEXP (operands
[0], 0), 0)) == STACK_POINTER_REGNUM
2269 && reg_overlap_mentioned_p (stack_pointer_rtx
, operands
[1]))
2270 operands
[1] = middlehalf
[1] = latehalf
[1];
2272 /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)),
2273 if the upper part of reg N does not appear in the MEM, arrange to
2274 emit the move late-half first. Otherwise, compute the MEM address
2275 into the upper part of N and use that as a pointer to the memory
2277 if (optype0
== REGOP
2278 && (optype1
== OFFSOP
|| optype1
== MEMOP
))
2280 rtx testlow
= gen_rtx_REG (SImode
, REGNO (operands
[0]));
2282 if (reg_overlap_mentioned_p (testlow
, XEXP (operands
[1], 0))
2283 && reg_overlap_mentioned_p (latehalf
[0], XEXP (operands
[1], 0)))
2285 /* If both halves of dest are used in the src memory address,
2286 compute the address into latehalf of dest.
2287 Note that this can't happen if the dest is two data regs. */
2289 xops
[0] = latehalf
[0];
2290 xops
[1] = XEXP (operands
[1], 0);
2291 output_asm_insn ("lea %a1,%0", xops
);
2292 if (GET_MODE (operands
[1]) == XFmode
)
2294 operands
[1] = gen_rtx_MEM (XFmode
, latehalf
[0]);
2295 middlehalf
[1] = adjust_address (operands
[1], DImode
, size
- 8);
2296 latehalf
[1] = adjust_address (operands
[1], DImode
, size
- 4);
2300 operands
[1] = gen_rtx_MEM (DImode
, latehalf
[0]);
2301 latehalf
[1] = adjust_address (operands
[1], DImode
, size
- 4);
2305 && reg_overlap_mentioned_p (middlehalf
[0],
2306 XEXP (operands
[1], 0)))
2308 /* Check for two regs used by both source and dest.
2309 Note that this can't happen if the dest is all data regs.
2310 It can happen if the dest is d6, d7, a0.
2311 But in that case, latehalf is an addr reg, so
2312 the code at compadr does ok. */
2314 if (reg_overlap_mentioned_p (testlow
, XEXP (operands
[1], 0))
2315 || reg_overlap_mentioned_p (latehalf
[0], XEXP (operands
[1], 0)))
2318 /* JRV says this can't happen: */
2319 if (addreg0
|| addreg1
)
2322 /* Only the middle reg conflicts; simply put it last. */
2323 output_asm_insn (singlemove_string (operands
), operands
);
2324 output_asm_insn (singlemove_string (latehalf
), latehalf
);
2325 output_asm_insn (singlemove_string (middlehalf
), middlehalf
);
2328 else if (reg_overlap_mentioned_p (testlow
, XEXP (operands
[1], 0)))
2329 /* If the low half of dest is mentioned in the source memory
2330 address, the arrange to emit the move late half first. */
2331 dest_overlapped_low
= 1;
2334 /* If one or both operands autodecrementing,
2335 do the two words, high-numbered first. */
2337 /* Likewise, the first move would clobber the source of the second one,
2338 do them in the other order. This happens only for registers;
2339 such overlap can't happen in memory unless the user explicitly
2340 sets it up, and that is an undefined circumstance. */
2342 if (optype0
== PUSHOP
|| optype1
== PUSHOP
2343 || (optype0
== REGOP
&& optype1
== REGOP
2344 && ((middlehalf
[1] && REGNO (operands
[0]) == REGNO (middlehalf
[1]))
2345 || REGNO (operands
[0]) == REGNO (latehalf
[1])))
2346 || dest_overlapped_low
)
2348 /* Make any unoffsettable addresses point at high-numbered word. */
2352 output_asm_insn ("addq%.l %#8,%0", &addreg0
);
2354 output_asm_insn ("addq%.l %#4,%0", &addreg0
);
2359 output_asm_insn ("addq%.l %#8,%0", &addreg1
);
2361 output_asm_insn ("addq%.l %#4,%0", &addreg1
);
2365 output_asm_insn (singlemove_string (latehalf
), latehalf
);
2367 /* Undo the adds we just did. */
2369 output_asm_insn ("subq%.l %#4,%0", &addreg0
);
2371 output_asm_insn ("subq%.l %#4,%0", &addreg1
);
2375 output_asm_insn (singlemove_string (middlehalf
), middlehalf
);
2377 output_asm_insn ("subq%.l %#4,%0", &addreg0
);
2379 output_asm_insn ("subq%.l %#4,%0", &addreg1
);
2382 /* Do low-numbered word. */
2383 return singlemove_string (operands
);
2386 /* Normal case: do the two words, low-numbered first. */
2388 output_asm_insn (singlemove_string (operands
), operands
);
2390 /* Do the middle one of the three words for long double */
2394 output_asm_insn ("addq%.l %#4,%0", &addreg0
);
2396 output_asm_insn ("addq%.l %#4,%0", &addreg1
);
2398 output_asm_insn (singlemove_string (middlehalf
), middlehalf
);
2401 /* Make any unoffsettable addresses point at high-numbered word. */
2403 output_asm_insn ("addq%.l %#4,%0", &addreg0
);
2405 output_asm_insn ("addq%.l %#4,%0", &addreg1
);
2408 output_asm_insn (singlemove_string (latehalf
), latehalf
);
2410 /* Undo the adds we just did. */
2414 output_asm_insn ("subq%.l %#8,%0", &addreg0
);
2416 output_asm_insn ("subq%.l %#4,%0", &addreg0
);
2421 output_asm_insn ("subq%.l %#8,%0", &addreg1
);
2423 output_asm_insn ("subq%.l %#4,%0", &addreg1
);
2429 /* Return a REG that occurs in ADDR with coefficient 1.
2430 ADDR can be effectively incremented by incrementing REG. */
2433 find_addr_reg (rtx addr
)
2435 while (GET_CODE (addr
) == PLUS
)
2437 if (GET_CODE (XEXP (addr
, 0)) == REG
)
2438 addr
= XEXP (addr
, 0);
2439 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
2440 addr
= XEXP (addr
, 1);
2441 else if (CONSTANT_P (XEXP (addr
, 0)))
2442 addr
= XEXP (addr
, 1);
2443 else if (CONSTANT_P (XEXP (addr
, 1)))
2444 addr
= XEXP (addr
, 0);
2448 if (GET_CODE (addr
) == REG
)
2453 /* Output assembler code to perform a 32-bit 3-operand add. */
2456 output_addsi3 (rtx
*operands
)
2458 if (! operands_match_p (operands
[0], operands
[1]))
2460 if (!ADDRESS_REG_P (operands
[1]))
2462 rtx tmp
= operands
[1];
2464 operands
[1] = operands
[2];
2468 /* These insns can result from reloads to access
2469 stack slots over 64k from the frame pointer. */
2470 if (GET_CODE (operands
[2]) == CONST_INT
2471 && INTVAL (operands
[2]) + 0x8000 >= (unsigned) 0x10000)
2472 return "move%.l %2,%0\n\tadd%.l %1,%0";
2474 if (GET_CODE (operands
[2]) == REG
)
2475 return "lea 0(%1,%2.l),%0";
2477 return "lea %c2(%1),%0";
2478 #elif defined(MOTOROLA)
2479 if (GET_CODE (operands
[2]) == REG
)
2480 return "lea (%1,%2.l),%0";
2482 return "lea (%c2,%1),%0";
2483 #else /* not MOTOROLA (MIT syntax) */
2484 if (GET_CODE (operands
[2]) == REG
)
2485 return "lea %1@(0,%2:l),%0";
2487 return "lea %1@(%c2),%0";
2488 #endif /* not MOTOROLA */
2490 if (GET_CODE (operands
[2]) == CONST_INT
)
2492 if (INTVAL (operands
[2]) > 0
2493 && INTVAL (operands
[2]) <= 8)
2494 return "addq%.l %2,%0";
2495 if (INTVAL (operands
[2]) < 0
2496 && INTVAL (operands
[2]) >= -8)
2498 operands
[2] = GEN_INT (- INTVAL (operands
[2]));
2499 return "subq%.l %2,%0";
2501 /* On the CPU32 it is faster to use two addql instructions to
2502 add a small integer (8 < N <= 16) to a register.
2503 Likewise for subql. */
2504 if (TARGET_CPU32
&& REG_P (operands
[0]))
2506 if (INTVAL (operands
[2]) > 8
2507 && INTVAL (operands
[2]) <= 16)
2509 operands
[2] = GEN_INT (INTVAL (operands
[2]) - 8);
2510 return "addq%.l %#8,%0\n\taddq%.l %2,%0";
2512 if (INTVAL (operands
[2]) < -8
2513 && INTVAL (operands
[2]) >= -16)
2515 operands
[2] = GEN_INT (- INTVAL (operands
[2]) - 8);
2516 return "subq%.l %#8,%0\n\tsubq%.l %2,%0";
2519 if (ADDRESS_REG_P (operands
[0])
2520 && INTVAL (operands
[2]) >= -0x8000
2521 && INTVAL (operands
[2]) < 0x8000)
2524 return "add%.w %2,%0";
2527 return "lea (%c2,%0),%0";
2529 return "lea %0@(%c2),%0";
2533 return "add%.l %2,%0";
2536 /* Store in cc_status the expressions that the condition codes will
2537 describe after execution of an instruction whose pattern is EXP.
2538 Do not alter them if the instruction would not alter the cc's. */
2540 /* On the 68000, all the insns to store in an address register fail to
2541 set the cc's. However, in some cases these instructions can make it
2542 possibly invalid to use the saved cc's. In those cases we clear out
2543 some or all of the saved cc's so they won't be used. */
2546 notice_update_cc (rtx exp
, rtx insn
)
2548 if (GET_CODE (exp
) == SET
)
2550 if (GET_CODE (SET_SRC (exp
)) == CALL
)
2554 else if (ADDRESS_REG_P (SET_DEST (exp
)))
2556 if (cc_status
.value1
&& modified_in_p (cc_status
.value1
, insn
))
2557 cc_status
.value1
= 0;
2558 if (cc_status
.value2
&& modified_in_p (cc_status
.value2
, insn
))
2559 cc_status
.value2
= 0;
2561 else if (!FP_REG_P (SET_DEST (exp
))
2562 && SET_DEST (exp
) != cc0_rtx
2563 && (FP_REG_P (SET_SRC (exp
))
2564 || GET_CODE (SET_SRC (exp
)) == FIX
2565 || GET_CODE (SET_SRC (exp
)) == FLOAT_TRUNCATE
2566 || GET_CODE (SET_SRC (exp
)) == FLOAT_EXTEND
))
2570 /* A pair of move insns doesn't produce a useful overall cc. */
2571 else if (!FP_REG_P (SET_DEST (exp
))
2572 && !FP_REG_P (SET_SRC (exp
))
2573 && GET_MODE_SIZE (GET_MODE (SET_SRC (exp
))) > 4
2574 && (GET_CODE (SET_SRC (exp
)) == REG
2575 || GET_CODE (SET_SRC (exp
)) == MEM
2576 || GET_CODE (SET_SRC (exp
)) == CONST_DOUBLE
))
2580 else if (GET_CODE (SET_SRC (exp
)) == CALL
)
2584 else if (XEXP (exp
, 0) != pc_rtx
)
2586 cc_status
.flags
= 0;
2587 cc_status
.value1
= XEXP (exp
, 0);
2588 cc_status
.value2
= XEXP (exp
, 1);
2591 else if (GET_CODE (exp
) == PARALLEL
2592 && GET_CODE (XVECEXP (exp
, 0, 0)) == SET
)
2594 if (ADDRESS_REG_P (XEXP (XVECEXP (exp
, 0, 0), 0)))
2596 else if (XEXP (XVECEXP (exp
, 0, 0), 0) != pc_rtx
)
2598 cc_status
.flags
= 0;
2599 cc_status
.value1
= XEXP (XVECEXP (exp
, 0, 0), 0);
2600 cc_status
.value2
= XEXP (XVECEXP (exp
, 0, 0), 1);
2605 if (cc_status
.value2
!= 0
2606 && ADDRESS_REG_P (cc_status
.value2
)
2607 && GET_MODE (cc_status
.value2
) == QImode
)
2609 if (cc_status
.value2
!= 0)
2610 switch (GET_CODE (cc_status
.value2
))
2612 case PLUS
: case MINUS
: case MULT
:
2613 case DIV
: case UDIV
: case MOD
: case UMOD
: case NEG
:
2614 #if 0 /* These instructions always clear the overflow bit */
2615 case ASHIFT
: case ASHIFTRT
: case LSHIFTRT
:
2616 case ROTATE
: case ROTATERT
:
2618 if (GET_MODE (cc_status
.value2
) != VOIDmode
)
2619 cc_status
.flags
|= CC_NO_OVERFLOW
;
2622 /* (SET r1 (ZERO_EXTEND r2)) on this machine
2623 ends with a move insn moving r2 in r2's mode.
2624 Thus, the cc's are set for r2.
2625 This can set N bit spuriously. */
2626 cc_status
.flags
|= CC_NOT_NEGATIVE
;
2631 if (cc_status
.value1
&& GET_CODE (cc_status
.value1
) == REG
2633 && reg_overlap_mentioned_p (cc_status
.value1
, cc_status
.value2
))
2634 cc_status
.value2
= 0;
2635 if (((cc_status
.value1
&& FP_REG_P (cc_status
.value1
))
2636 || (cc_status
.value2
&& FP_REG_P (cc_status
.value2
))))
2637 cc_status
.flags
= CC_IN_68881
;
2641 output_move_const_double (rtx
*operands
)
2643 int code
= standard_68881_constant_p (operands
[1]);
2647 static char buf
[40];
2649 sprintf (buf
, "fmovecr %%#0x%x,%%0", code
& 0xff);
2652 return "fmove%.d %1,%0";
2656 output_move_const_single (rtx
*operands
)
2658 int code
= standard_68881_constant_p (operands
[1]);
2662 static char buf
[40];
2664 sprintf (buf
, "fmovecr %%#0x%x,%%0", code
& 0xff);
2667 return "fmove%.s %f1,%0";
2670 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
2671 from the "fmovecr" instruction.
2672 The value, anded with 0xff, gives the code to use in fmovecr
2673 to get the desired constant. */
2675 /* This code has been fixed for cross-compilation. */
2677 static int inited_68881_table
= 0;
2679 static const char *const strings_68881
[7] = {
2689 static const int codes_68881
[7] = {
2699 REAL_VALUE_TYPE values_68881
[7];
2701 /* Set up values_68881 array by converting the decimal values
2702 strings_68881 to binary. */
2705 init_68881_table (void)
2709 enum machine_mode mode
;
2712 for (i
= 0; i
< 7; i
++)
2716 r
= REAL_VALUE_ATOF (strings_68881
[i
], mode
);
2717 values_68881
[i
] = r
;
2719 inited_68881_table
= 1;
2723 standard_68881_constant_p (rtx x
)
2728 /* fmovecr must be emulated on the 68040 and 68060, so it shouldn't be
2729 used at all on those chips. */
2730 if (TARGET_68040
|| TARGET_68060
)
2733 if (! inited_68881_table
)
2734 init_68881_table ();
2736 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
2738 /* Use REAL_VALUES_IDENTICAL instead of REAL_VALUES_EQUAL so that -0.0
2740 for (i
= 0; i
< 6; i
++)
2742 if (REAL_VALUES_IDENTICAL (r
, values_68881
[i
]))
2743 return (codes_68881
[i
]);
2746 if (GET_MODE (x
) == SFmode
)
2749 if (REAL_VALUES_EQUAL (r
, values_68881
[6]))
2750 return (codes_68881
[6]);
2752 /* larger powers of ten in the constants ram are not used
2753 because they are not equal to a `double' C constant. */
2757 /* If X is a floating-point constant, return the logarithm of X base 2,
2758 or 0 if X is not a power of 2. */
2761 floating_exact_log2 (rtx x
)
2763 REAL_VALUE_TYPE r
, r1
;
2766 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
2768 if (REAL_VALUES_LESS (r
, dconst1
))
2771 exp
= real_exponent (&r
);
2772 real_2expN (&r1
, exp
);
2773 if (REAL_VALUES_EQUAL (r1
, r
))
2779 /* A C compound statement to output to stdio stream STREAM the
2780 assembler syntax for an instruction operand X. X is an RTL
2783 CODE is a value that can be used to specify one of several ways
2784 of printing the operand. It is used when identical operands
2785 must be printed differently depending on the context. CODE
2786 comes from the `%' specification that was used to request
2787 printing of the operand. If the specification was just `%DIGIT'
2788 then CODE is 0; if the specification was `%LTR DIGIT' then CODE
2789 is the ASCII code for LTR.
2791 If X is a register, this macro should print the register's name.
2792 The names can be found in an array `reg_names' whose type is
2793 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
2795 When the machine description has a specification `%PUNCT' (a `%'
2796 followed by a punctuation character), this macro is called with
2797 a null pointer for X and the punctuation character for CODE.
2799 The m68k specific codes are:
2801 '.' for dot needed in Motorola-style opcode names.
2802 '-' for an operand pushing on the stack:
2803 sp@-, -(sp) or -(%sp) depending on the style of syntax.
2804 '+' for an operand pushing on the stack:
2805 sp@+, (sp)+ or (%sp)+ depending on the style of syntax.
2806 '@' for a reference to the top word on the stack:
2807 sp@, (sp) or (%sp) depending on the style of syntax.
2808 '#' for an immediate operand prefix (# in MIT and Motorola syntax
2809 but & in SGS syntax).
2810 '!' for the cc register (used in an `and to cc' insn).
2811 '$' for the letter `s' in an op code, but only on the 68040.
2812 '&' for the letter `d' in an op code, but only on the 68040.
2813 '/' for register prefix needed by longlong.h.
2815 'b' for byte insn (no effect, on the Sun; this is for the ISI).
2816 'd' to force memory addressing to be absolute, not relative.
2817 'f' for float insn (print a CONST_DOUBLE as a float rather than in hex)
2818 'o' for operands to go directly to output_operand_address (bypassing
2819 print_operand_address--used only for SYMBOL_REFs under TARGET_PCREL)
2820 'x' for float insn (print a CONST_DOUBLE as a float rather than in hex),
2821 or print pair of registers as rx:ry.
2826 print_operand (FILE *file
, rtx op
, int letter
)
2830 #if defined (MOTOROLA)
2831 fprintf (file
, ".");
2834 else if (letter
== '#')
2836 asm_fprintf (file
, "%I");
2838 else if (letter
== '-')
2841 asm_fprintf (file
, "-(%Rsp)");
2843 asm_fprintf (file
, "%Rsp@-");
2846 else if (letter
== '+')
2849 asm_fprintf (file
, "(%Rsp)+");
2851 asm_fprintf (file
, "%Rsp@+");
2854 else if (letter
== '@')
2857 asm_fprintf (file
, "(%Rsp)");
2859 asm_fprintf (file
, "%Rsp@");
2862 else if (letter
== '!')
2864 asm_fprintf (file
, "%Rfpcr");
2866 else if (letter
== '$')
2868 if (TARGET_68040_ONLY
)
2870 fprintf (file
, "s");
2873 else if (letter
== '&')
2875 if (TARGET_68040_ONLY
)
2877 fprintf (file
, "d");
2880 else if (letter
== '/')
2882 asm_fprintf (file
, "%R");
2884 else if (letter
== 'o')
2886 /* This is only for direct addresses with TARGET_PCREL */
2887 if (GET_CODE (op
) != MEM
|| GET_CODE (XEXP (op
, 0)) != SYMBOL_REF
2890 output_addr_const (file
, XEXP (op
, 0));
2892 else if (GET_CODE (op
) == REG
)
2895 /* Print out the second register name of a register pair.
2896 I.e., R (6) => 7. */
2897 fputs (reg_names
[REGNO (op
) + 1], file
);
2899 fputs (reg_names
[REGNO (op
)], file
);
2901 else if (GET_CODE (op
) == MEM
)
2903 output_address (XEXP (op
, 0));
2904 if (letter
== 'd' && ! TARGET_68020
2905 && CONSTANT_ADDRESS_P (XEXP (op
, 0))
2906 && !(GET_CODE (XEXP (op
, 0)) == CONST_INT
2907 && INTVAL (XEXP (op
, 0)) < 0x8000
2908 && INTVAL (XEXP (op
, 0)) >= -0x8000))
2911 fprintf (file
, ".l");
2913 fprintf (file
, ":l");
2917 else if (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == SFmode
)
2920 REAL_VALUE_FROM_CONST_DOUBLE (r
, op
);
2921 ASM_OUTPUT_FLOAT_OPERAND (letter
, file
, r
);
2923 else if (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == XFmode
)
2926 REAL_VALUE_FROM_CONST_DOUBLE (r
, op
);
2927 ASM_OUTPUT_LONG_DOUBLE_OPERAND (file
, r
);
2929 else if (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == DFmode
)
2932 REAL_VALUE_FROM_CONST_DOUBLE (r
, op
);
2933 ASM_OUTPUT_DOUBLE_OPERAND (file
, r
);
2937 /* Use `print_operand_address' instead of `output_addr_const'
2938 to ensure that we print relevant PIC stuff. */
2939 asm_fprintf (file
, "%I");
2941 && (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == CONST
))
2942 print_operand_address (file
, op
);
2944 output_addr_const (file
, op
);
2949 /* A C compound statement to output to stdio stream STREAM the
2950 assembler syntax for an instruction operand that is a memory
2951 reference whose address is ADDR. ADDR is an RTL expression.
2953 Note that this contains a kludge that knows that the only reason
2954 we have an address (plus (label_ref...) (reg...)) when not generating
2955 PIC code is in the insn before a tablejump, and we know that m68k.md
2956 generates a label LInnn: on such an insn.
2958 It is possible for PIC to generate a (plus (label_ref...) (reg...))
2959 and we handle that just like we would a (plus (symbol_ref...) (reg...)).
2961 Some SGS assemblers have a bug such that "Lnnn-LInnn-2.b(pc,d0.l*2)"
2962 fails to assemble. Luckily "Lnnn(pc,d0.l*2)" produces the results
2963 we want. This difference can be accommodated by using an assembler
2964 define such "LDnnn" to be either "Lnnn-LInnn-2.b", "Lnnn", or any other
2965 string, as necessary. This is accomplished via the ASM_OUTPUT_CASE_END
2966 macro. See m68k/sgs.h for an example; for versions without the bug.
2967 Some assemblers refuse all the above solutions. The workaround is to
2968 emit "K(pc,d0.l*2)" with K being a small constant known to give the
2971 They also do not like things like "pea 1.w", so we simple leave off
2972 the .w on small constants.
2974 This routine is responsible for distinguishing between -fpic and -fPIC
2975 style relocations in an address. When generating -fpic code the
2976 offset is output in word mode (eg movel a5@(_foo:w), a0). When generating
2977 -fPIC code the offset is output in long mode (eg movel a5@(_foo:l), a0) */
2979 #ifndef ASM_OUTPUT_CASE_FETCH
2982 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2983 asm_fprintf (file, "%LLD%d(%Rpc,%s.", labelno, regname)
2985 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2986 asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.", labelno, labelno, regname)
2989 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2990 asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:", labelno, labelno, regname)
2992 #endif /* ASM_OUTPUT_CASE_FETCH */
2995 print_operand_address (FILE *file
, rtx addr
)
2997 register rtx reg1
, reg2
, breg
, ireg
;
3000 switch (GET_CODE (addr
))
3004 fprintf (file
, "(%s)", reg_names
[REGNO (addr
)]);
3006 fprintf (file
, "%s@", reg_names
[REGNO (addr
)]);
3011 fprintf (file
, "-(%s)", reg_names
[REGNO (XEXP (addr
, 0))]);
3013 fprintf (file
, "%s@-", reg_names
[REGNO (XEXP (addr
, 0))]);
3018 fprintf (file
, "(%s)+", reg_names
[REGNO (XEXP (addr
, 0))]);
3020 fprintf (file
, "%s@+", reg_names
[REGNO (XEXP (addr
, 0))]);
3024 reg1
= reg2
= ireg
= breg
= offset
= 0;
3025 if (CONSTANT_ADDRESS_P (XEXP (addr
, 0)))
3027 offset
= XEXP (addr
, 0);
3028 addr
= XEXP (addr
, 1);
3030 else if (CONSTANT_ADDRESS_P (XEXP (addr
, 1)))
3032 offset
= XEXP (addr
, 1);
3033 addr
= XEXP (addr
, 0);
3035 if (GET_CODE (addr
) != PLUS
)
3039 else if (GET_CODE (XEXP (addr
, 0)) == SIGN_EXTEND
)
3041 reg1
= XEXP (addr
, 0);
3042 addr
= XEXP (addr
, 1);
3044 else if (GET_CODE (XEXP (addr
, 1)) == SIGN_EXTEND
)
3046 reg1
= XEXP (addr
, 1);
3047 addr
= XEXP (addr
, 0);
3049 else if (GET_CODE (XEXP (addr
, 0)) == MULT
)
3051 reg1
= XEXP (addr
, 0);
3052 addr
= XEXP (addr
, 1);
3054 else if (GET_CODE (XEXP (addr
, 1)) == MULT
)
3056 reg1
= XEXP (addr
, 1);
3057 addr
= XEXP (addr
, 0);
3059 else if (GET_CODE (XEXP (addr
, 0)) == REG
)
3061 reg1
= XEXP (addr
, 0);
3062 addr
= XEXP (addr
, 1);
3064 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
3066 reg1
= XEXP (addr
, 1);
3067 addr
= XEXP (addr
, 0);
3069 if (GET_CODE (addr
) == REG
|| GET_CODE (addr
) == MULT
3070 || GET_CODE (addr
) == SIGN_EXTEND
)
3082 #if 0 /* for OLD_INDEXING */
3083 else if (GET_CODE (addr
) == PLUS
)
3085 if (GET_CODE (XEXP (addr
, 0)) == REG
)
3087 reg2
= XEXP (addr
, 0);
3088 addr
= XEXP (addr
, 1);
3090 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
3092 reg2
= XEXP (addr
, 1);
3093 addr
= XEXP (addr
, 0);
3105 if ((reg1
&& (GET_CODE (reg1
) == SIGN_EXTEND
3106 || GET_CODE (reg1
) == MULT
))
3107 || (reg2
!= 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2
))))
3112 else if (reg1
!= 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1
)))
3117 if (ireg
!= 0 && breg
== 0 && GET_CODE (addr
) == LABEL_REF
3118 && ! (flag_pic
&& ireg
== pic_offset_table_rtx
))
3121 if (GET_CODE (ireg
) == MULT
)
3123 scale
= INTVAL (XEXP (ireg
, 1));
3124 ireg
= XEXP (ireg
, 0);
3126 if (GET_CODE (ireg
) == SIGN_EXTEND
)
3128 ASM_OUTPUT_CASE_FETCH (file
,
3129 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
3130 reg_names
[REGNO (XEXP (ireg
, 0))]);
3131 fprintf (file
, "w");
3135 ASM_OUTPUT_CASE_FETCH (file
,
3136 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
3137 reg_names
[REGNO (ireg
)]);
3138 fprintf (file
, "l");
3143 fprintf (file
, "*%d", scale
);
3145 fprintf (file
, ":%d", scale
);
3151 if (breg
!= 0 && ireg
== 0 && GET_CODE (addr
) == LABEL_REF
3152 && ! (flag_pic
&& breg
== pic_offset_table_rtx
))
3154 ASM_OUTPUT_CASE_FETCH (file
,
3155 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
3156 reg_names
[REGNO (breg
)]);
3157 fprintf (file
, "l)");
3160 if (ireg
!= 0 || breg
!= 0)
3167 if (! flag_pic
&& addr
&& GET_CODE (addr
) == LABEL_REF
)
3174 output_addr_const (file
, addr
);
3175 if (flag_pic
&& (breg
== pic_offset_table_rtx
))
3177 fprintf (file
, "@GOT");
3179 fprintf (file
, ".w");
3182 fprintf (file
, "(%s", reg_names
[REGNO (breg
)]);
3188 fprintf (file
, "%s@(", reg_names
[REGNO (breg
)]);
3191 output_addr_const (file
, addr
);
3192 if ((flag_pic
== 1) && (breg
== pic_offset_table_rtx
))
3193 fprintf (file
, ":w");
3194 if ((flag_pic
== 2) && (breg
== pic_offset_table_rtx
))
3195 fprintf (file
, ":l");
3197 if (addr
!= 0 && ireg
!= 0)
3202 if (ireg
!= 0 && GET_CODE (ireg
) == MULT
)
3204 scale
= INTVAL (XEXP (ireg
, 1));
3205 ireg
= XEXP (ireg
, 0);
3207 if (ireg
!= 0 && GET_CODE (ireg
) == SIGN_EXTEND
)
3210 fprintf (file
, "%s.w", reg_names
[REGNO (XEXP (ireg
, 0))]);
3212 fprintf (file
, "%s:w", reg_names
[REGNO (XEXP (ireg
, 0))]);
3218 fprintf (file
, "%s.l", reg_names
[REGNO (ireg
)]);
3220 fprintf (file
, "%s:l", reg_names
[REGNO (ireg
)]);
3226 fprintf (file
, "*%d", scale
);
3228 fprintf (file
, ":%d", scale
);
3234 else if (reg1
!= 0 && GET_CODE (addr
) == LABEL_REF
3235 && ! (flag_pic
&& reg1
== pic_offset_table_rtx
))
3237 ASM_OUTPUT_CASE_FETCH (file
,
3238 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
3239 reg_names
[REGNO (reg1
)]);
3240 fprintf (file
, "l)");
3243 /* FALL-THROUGH (is this really what we want?) */
3245 if (GET_CODE (addr
) == CONST_INT
3246 && INTVAL (addr
) < 0x8000
3247 && INTVAL (addr
) >= -0x8000)
3251 /* Many SGS assemblers croak on size specifiers for constants. */
3252 fprintf (file
, "%d", (int) INTVAL (addr
));
3254 fprintf (file
, "%d.w", (int) INTVAL (addr
));
3257 fprintf (file
, "%d:w", (int) INTVAL (addr
));
3260 else if (GET_CODE (addr
) == CONST_INT
)
3262 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (addr
));
3264 else if (TARGET_PCREL
)
3267 output_addr_const (file
, addr
);
3269 asm_fprintf (file
, ":w,%Rpc)");
3271 asm_fprintf (file
, ":l,%Rpc)");
3275 /* Special case for SYMBOL_REF if the symbol name ends in
3276 `.<letter>', this can be mistaken as a size suffix. Put
3277 the name in parentheses. */
3278 if (GET_CODE (addr
) == SYMBOL_REF
3279 && strlen (XSTR (addr
, 0)) > 2
3280 && XSTR (addr
, 0)[strlen (XSTR (addr
, 0)) - 2] == '.')
3283 output_addr_const (file
, addr
);
3287 output_addr_const (file
, addr
);
3293 /* Check for cases where a clr insns can be omitted from code using
3294 strict_low_part sets. For example, the second clrl here is not needed:
3295 clrl d0; movw a0@+,d0; use d0; clrl d0; movw a0@+; use d0; ...
3297 MODE is the mode of this STRICT_LOW_PART set. FIRST_INSN is the clear
3298 insn we are checking for redundancy. TARGET is the register set by the
3302 strict_low_part_peephole_ok (enum machine_mode mode
, rtx first_insn
,
3307 p
= prev_nonnote_insn (first_insn
);
3311 /* If it isn't an insn, then give up. */
3312 if (GET_CODE (p
) != INSN
)
3315 if (reg_set_p (target
, p
))
3317 rtx set
= single_set (p
);
3320 /* If it isn't an easy to recognize insn, then give up. */
3324 dest
= SET_DEST (set
);
3326 /* If this sets the entire target register to zero, then our
3327 first_insn is redundant. */
3328 if (rtx_equal_p (dest
, target
)
3329 && SET_SRC (set
) == const0_rtx
)
3331 else if (GET_CODE (dest
) == STRICT_LOW_PART
3332 && GET_CODE (XEXP (dest
, 0)) == REG
3333 && REGNO (XEXP (dest
, 0)) == REGNO (target
)
3334 && (GET_MODE_SIZE (GET_MODE (XEXP (dest
, 0)))
3335 <= GET_MODE_SIZE (mode
)))
3336 /* This is a strict low part set which modifies less than
3337 we are using, so it is safe. */
3343 p
= prev_nonnote_insn (p
);
3350 /* Accept integer operands in the range 0..0xffffffff. We have to check the
3351 range carefully since this predicate is used in DImode contexts. Also, we
3352 need some extra crud to make it work when hosted on 64-bit machines. */
3355 const_uint32_operand (rtx op
, enum machine_mode mode
)
3357 /* It doesn't make sense to ask this question with a mode that is
3358 not larger than 32 bits. */
3359 if (GET_MODE_BITSIZE (mode
) <= 32)
3362 #if HOST_BITS_PER_WIDE_INT > 32
3363 /* All allowed constants will fit a CONST_INT. */
3364 return (GET_CODE (op
) == CONST_INT
3365 && (INTVAL (op
) >= 0 && INTVAL (op
) <= 0xffffffffL
));
3367 return (GET_CODE (op
) == CONST_INT
3368 || (GET_CODE (op
) == CONST_DOUBLE
&& CONST_DOUBLE_HIGH (op
) == 0));
3372 /* Accept integer operands in the range -0x80000000..0x7fffffff. We have
3373 to check the range carefully since this predicate is used in DImode
3377 const_sint32_operand (rtx op
, enum machine_mode mode
)
3379 /* It doesn't make sense to ask this question with a mode that is
3380 not larger than 32 bits. */
3381 if (GET_MODE_BITSIZE (mode
) <= 32)
3384 /* All allowed constants will fit a CONST_INT. */
3385 return (GET_CODE (op
) == CONST_INT
3386 && (INTVAL (op
) >= (-0x7fffffff - 1) && INTVAL (op
) <= 0x7fffffff));
3389 /* Operand predicates for implementing asymmetric pc-relative addressing
3390 on m68k. The m68k supports pc-relative addressing (mode 7, register 2)
3391 when used as a source operand, but not as a destination operand.
3393 We model this by restricting the meaning of the basic predicates
3394 (general_operand, memory_operand, etc) to forbid the use of this
3395 addressing mode, and then define the following predicates that permit
3396 this addressing mode. These predicates can then be used for the
3397 source operands of the appropriate instructions.
3399 n.b. While it is theoretically possible to change all machine patterns
3400 to use this addressing more where permitted by the architecture,
3401 it has only been implemented for "common" cases: SImode, HImode, and
3402 QImode operands, and only for the principle operations that would
3403 require this addressing mode: data movement and simple integer operations.
3405 In parallel with these new predicates, two new constraint letters
3406 were defined: 'S' and 'T'. 'S' is the -mpcrel analog of 'm'.
3407 'T' replaces 's' in the non-pcrel case. It is a no-op in the pcrel case.
3408 In the pcrel case 's' is only valid in combination with 'a' registers.
3409 See addsi3, subsi3, cmpsi, and movsi patterns for a better understanding
3410 of how these constraints are used.
3412 The use of these predicates is strictly optional, though patterns that
3413 don't will cause an extra reload register to be allocated where one
3416 lea (abc:w,%pc),%a0 ; need to reload address
3417 moveq &1,%d1 ; since write to pc-relative space
3418 movel %d1,%a0@ ; is not allowed
3420 lea (abc:w,%pc),%a1 ; no need to reload address here
3421 movel %a1@,%d0 ; since "movel (abc:w,%pc),%d0" is ok
3423 For more info, consult tiemann@cygnus.com.
3426 All of the ugliness with predicates and constraints is due to the
3427 simple fact that the m68k does not allow a pc-relative addressing
3428 mode as a destination. gcc does not distinguish between source and
3429 destination addresses. Hence, if we claim that pc-relative address
3430 modes are valid, e.g. GO_IF_LEGITIMATE_ADDRESS accepts them, then we
3431 end up with invalid code. To get around this problem, we left
3432 pc-relative modes as invalid addresses, and then added special
3433 predicates and constraints to accept them.
3435 A cleaner way to handle this is to modify gcc to distinguish
3436 between source and destination addresses. We can then say that
3437 pc-relative is a valid source address but not a valid destination
3438 address, and hopefully avoid a lot of the predicate and constraint
3439 hackery. Unfortunately, this would be a pretty big change. It would
3440 be a useful change for a number of ports, but there aren't any current
3441 plans to undertake this.
3443 ***************************************************************************/
3446 /* Special case of a general operand that's used as a source operand.
3447 Use this to permit reads from PC-relative memory when -mpcrel
3451 general_src_operand (rtx op
, enum machine_mode mode
)
3454 && GET_CODE (op
) == MEM
3455 && (GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
3456 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
3457 || GET_CODE (XEXP (op
, 0)) == CONST
))
3459 return general_operand (op
, mode
);
3462 /* Special case of a nonimmediate operand that's used as a source.
3463 Use this to permit reads from PC-relative memory when -mpcrel
3467 nonimmediate_src_operand (rtx op
, enum machine_mode mode
)
3469 if (TARGET_PCREL
&& GET_CODE (op
) == MEM
3470 && (GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
3471 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
3472 || GET_CODE (XEXP (op
, 0)) == CONST
))
3474 return nonimmediate_operand (op
, mode
);
3477 /* Special case of a memory operand that's used as a source.
3478 Use this to permit reads from PC-relative memory when -mpcrel
3482 memory_src_operand (rtx op
, enum machine_mode mode
)
3484 if (TARGET_PCREL
&& GET_CODE (op
) == MEM
3485 && (GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
3486 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
3487 || GET_CODE (XEXP (op
, 0)) == CONST
))
3489 return memory_operand (op
, mode
);
3492 /* Predicate that accepts only a pc-relative address. This is needed
3493 because pc-relative addresses don't satisfy the predicate
3494 "general_src_operand". */
3497 pcrel_address (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
3499 return (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
3500 || GET_CODE (op
) == CONST
);
3504 output_andsi3 (rtx
*operands
)
3507 if (GET_CODE (operands
[2]) == CONST_INT
3508 && (INTVAL (operands
[2]) | 0xffff) == 0xffffffff
3509 && (DATA_REG_P (operands
[0])
3510 || offsettable_memref_p (operands
[0]))
3511 && !TARGET_COLDFIRE
)
3513 if (GET_CODE (operands
[0]) != REG
)
3514 operands
[0] = adjust_address (operands
[0], HImode
, 2);
3515 operands
[2] = GEN_INT (INTVAL (operands
[2]) & 0xffff);
3516 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3518 if (operands
[2] == const0_rtx
)
3520 return "and%.w %2,%0";
3522 if (GET_CODE (operands
[2]) == CONST_INT
3523 && (logval
= exact_log2 (~ INTVAL (operands
[2]))) >= 0
3524 && (DATA_REG_P (operands
[0])
3525 || offsettable_memref_p (operands
[0])))
3527 if (DATA_REG_P (operands
[0]))
3529 operands
[1] = GEN_INT (logval
);
3533 operands
[0] = adjust_address (operands
[0], SImode
, 3 - (logval
/ 8));
3534 operands
[1] = GEN_INT (logval
% 8);
3536 /* This does not set condition codes in a standard way. */
3538 return "bclr %1,%0";
3540 return "and%.l %2,%0";
3544 output_iorsi3 (rtx
*operands
)
3546 register int logval
;
3547 if (GET_CODE (operands
[2]) == CONST_INT
3548 && INTVAL (operands
[2]) >> 16 == 0
3549 && (DATA_REG_P (operands
[0])
3550 || offsettable_memref_p (operands
[0]))
3551 && !TARGET_COLDFIRE
)
3553 if (GET_CODE (operands
[0]) != REG
)
3554 operands
[0] = adjust_address (operands
[0], HImode
, 2);
3555 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3557 if (INTVAL (operands
[2]) == 0xffff)
3558 return "mov%.w %2,%0";
3559 return "or%.w %2,%0";
3561 if (GET_CODE (operands
[2]) == CONST_INT
3562 && (logval
= exact_log2 (INTVAL (operands
[2]))) >= 0
3563 && (DATA_REG_P (operands
[0])
3564 || offsettable_memref_p (operands
[0])))
3566 if (DATA_REG_P (operands
[0]))
3567 operands
[1] = GEN_INT (logval
);
3570 operands
[0] = adjust_address (operands
[0], SImode
, 3 - (logval
/ 8));
3571 operands
[1] = GEN_INT (logval
% 8);
3574 return "bset %1,%0";
3576 return "or%.l %2,%0";
3580 output_xorsi3 (rtx
*operands
)
3582 register int logval
;
3583 if (GET_CODE (operands
[2]) == CONST_INT
3584 && INTVAL (operands
[2]) >> 16 == 0
3585 && (offsettable_memref_p (operands
[0]) || DATA_REG_P (operands
[0]))
3586 && !TARGET_COLDFIRE
)
3588 if (! DATA_REG_P (operands
[0]))
3589 operands
[0] = adjust_address (operands
[0], HImode
, 2);
3590 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3592 if (INTVAL (operands
[2]) == 0xffff)
3594 return "eor%.w %2,%0";
3596 if (GET_CODE (operands
[2]) == CONST_INT
3597 && (logval
= exact_log2 (INTVAL (operands
[2]))) >= 0
3598 && (DATA_REG_P (operands
[0])
3599 || offsettable_memref_p (operands
[0])))
3601 if (DATA_REG_P (operands
[0]))
3602 operands
[1] = GEN_INT (logval
);
3605 operands
[0] = adjust_address (operands
[0], SImode
, 3 - (logval
/ 8));
3606 operands
[1] = GEN_INT (logval
% 8);
3609 return "bchg %1,%0";
3611 return "eor%.l %2,%0";
3614 #ifdef M68K_TARGET_COFF
3616 /* Output assembly to switch to section NAME with attribute FLAGS. */
3619 m68k_coff_asm_named_section (const char *name
, unsigned int flags
)
3623 if (flags
& SECTION_WRITE
)
3628 fprintf (asm_out_file
, "\t.section\t%s,\"%c\"\n", name
, flagchar
);
3631 #endif /* M68K_TARGET_COFF */
3635 m68k_hp320_internal_label (FILE *stream
, const char *prefix
,
3636 unsigned long labelno
)
3638 if (prefix
[0] == 'L' && prefix
[1] == 'I')
3639 fprintf(stream
, "\tset %s%ld,.+2\n", prefix
, labelno
);
3641 fprintf (stream
, "%s%ld:\n", prefix
, labelno
);
3645 m68k_hp320_file_start (void)
3647 /* version 1: 68010.
3648 2: 68020 without FPU.
3649 3: 68020 with FPU. */
3650 fprintf (asm_out_file
, "\tversion %d\n",
3651 TARGET_68020
? (TARGET_68881
? 3 : 2) : 1);
3656 m68k_output_mi_thunk (FILE *file
, tree thunk ATTRIBUTE_UNUSED
,
3657 HOST_WIDE_INT delta
,
3658 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED
,
3664 if (delta
> 0 && delta
<= 8)
3666 asm_fprintf (file
, "\taddq.l %I%d,4(%Rsp)\n", (int) delta
);
3668 asm_fprintf (file
, "\taddql %I%d,%Rsp@(4)\n", (int) delta
);
3670 else if (delta
< 0 && delta
>= -8)
3672 asm_fprintf (file
, "\tsubq.l %I%d,4(%Rsp)\n", (int) -delta
);
3674 asm_fprintf (file
, "\tsubql %I%d,%Rsp@(4)\n", (int) -delta
);
3678 asm_fprintf (file
, "\tadd.l %I%wd,4(%Rsp)\n", delta
);
3680 asm_fprintf (file
, "\taddl %I%wd,%Rsp@(4)\n", delta
);
3683 xops
[0] = DECL_RTL (function
);
3685 /* Logic taken from call patterns in m68k.md. */
3690 else if ((flag_pic
== 1) || TARGET_68020
)
3697 fmt
= "bra.l %0@PLTPC";
3699 fmt
= "bra %0@PLTPC";
3710 else if (optimize_size
|| TARGET_ID_SHARED_LIBRARY
)
3711 fmt
= "move.l %0@GOT(%%a5), %%a1\n\tjmp (%%a1)";
3713 fmt
= "lea %0-.-8,%%a1\n\tjsr 0(%%pc,%%a1)";
3717 #if defined (MOTOROLA) && !defined (USE_GAS)
3724 output_asm_insn (fmt
, xops
);