1 /* Subroutines for insn-output.c for Motorola 68000 family.
2 Copyright (C) 1987, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2003, 2004, 2005, 2006
4 Free Software Foundation, Inc.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to
20 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
25 #include "coretypes.h"
31 #include "hard-reg-set.h"
33 #include "insn-config.h"
34 #include "conditions.h"
36 #include "insn-attr.h"
43 #include "target-def.h"
47 enum reg_class regno_reg_class
[] =
49 DATA_REGS
, DATA_REGS
, DATA_REGS
, DATA_REGS
,
50 DATA_REGS
, DATA_REGS
, DATA_REGS
, DATA_REGS
,
51 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
52 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
53 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
54 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
59 /* The ASM_DOT macro allows easy string pasting to handle the differences
60 between MOTOROLA and MIT syntaxes in asm_fprintf(), which doesn't
61 support the %. option. */
64 # define ASM_DOTW ".w"
65 # define ASM_DOTL ".l"
73 /* Structure describing stack frame layout. */
76 /* Stack pointer to frame pointer offset. */
79 /* Offset of FPU registers. */
80 HOST_WIDE_INT foffset
;
82 /* Frame size in bytes (rounded up). */
85 /* Data and address register. */
87 unsigned int reg_mask
;
88 unsigned int reg_rev_mask
;
92 unsigned int fpu_mask
;
93 unsigned int fpu_rev_mask
;
95 /* Offsets relative to ARG_POINTER. */
96 HOST_WIDE_INT frame_pointer_offset
;
97 HOST_WIDE_INT stack_pointer_offset
;
99 /* Function which the above information refers to. */
103 /* Current frame information calculated by m68k_compute_frame_layout(). */
104 static struct m68k_frame current_frame
;
106 static bool m68k_handle_option (size_t, const char *, int);
107 static rtx
find_addr_reg (rtx
);
108 static const char *singlemove_string (rtx
*);
109 static void m68k_output_function_prologue (FILE *, HOST_WIDE_INT
);
110 static void m68k_output_function_epilogue (FILE *, HOST_WIDE_INT
);
111 #ifdef M68K_TARGET_COFF
112 static void m68k_coff_asm_named_section (const char *, unsigned int, tree
);
113 #endif /* M68K_TARGET_COFF */
114 static void m68k_output_mi_thunk (FILE *, tree
, HOST_WIDE_INT
,
115 HOST_WIDE_INT
, tree
);
116 static rtx
m68k_struct_value_rtx (tree
, int);
117 static bool m68k_interrupt_function_p (tree func
);
118 static tree
m68k_handle_fndecl_attribute (tree
*node
, tree name
,
119 tree args
, int flags
,
121 static void m68k_compute_frame_layout (void);
122 static bool m68k_save_reg (unsigned int regno
, bool interrupt_handler
);
123 static int const_int_cost (rtx
);
124 static bool m68k_rtx_costs (rtx
, int, int, int *);
127 /* Specify the identification number of the library being built */
128 const char *m68k_library_id_string
= "_current_shared_library_a5_offset_";
130 /* Nonzero if the last compare/test insn had FP operands. The
131 sCC expanders peek at this to determine what to do for the
132 68060, which has no fsCC instructions. */
133 int m68k_last_compare_had_fp_operands
;
135 /* Initialize the GCC target structure. */
137 #if INT_OP_GROUP == INT_OP_DOT_WORD
138 #undef TARGET_ASM_ALIGNED_HI_OP
139 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
142 #if INT_OP_GROUP == INT_OP_NO_DOT
143 #undef TARGET_ASM_BYTE_OP
144 #define TARGET_ASM_BYTE_OP "\tbyte\t"
145 #undef TARGET_ASM_ALIGNED_HI_OP
146 #define TARGET_ASM_ALIGNED_HI_OP "\tshort\t"
147 #undef TARGET_ASM_ALIGNED_SI_OP
148 #define TARGET_ASM_ALIGNED_SI_OP "\tlong\t"
151 #if INT_OP_GROUP == INT_OP_DC
152 #undef TARGET_ASM_BYTE_OP
153 #define TARGET_ASM_BYTE_OP "\tdc.b\t"
154 #undef TARGET_ASM_ALIGNED_HI_OP
155 #define TARGET_ASM_ALIGNED_HI_OP "\tdc.w\t"
156 #undef TARGET_ASM_ALIGNED_SI_OP
157 #define TARGET_ASM_ALIGNED_SI_OP "\tdc.l\t"
160 #undef TARGET_ASM_UNALIGNED_HI_OP
161 #define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP
162 #undef TARGET_ASM_UNALIGNED_SI_OP
163 #define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP
165 #undef TARGET_ASM_FUNCTION_PROLOGUE
166 #define TARGET_ASM_FUNCTION_PROLOGUE m68k_output_function_prologue
167 #undef TARGET_ASM_FUNCTION_EPILOGUE
168 #define TARGET_ASM_FUNCTION_EPILOGUE m68k_output_function_epilogue
170 #undef TARGET_ASM_OUTPUT_MI_THUNK
171 #define TARGET_ASM_OUTPUT_MI_THUNK m68k_output_mi_thunk
172 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
173 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
175 #undef TARGET_ASM_FILE_START_APP_OFF
176 #define TARGET_ASM_FILE_START_APP_OFF true
178 #undef TARGET_DEFAULT_TARGET_FLAGS
179 #define TARGET_DEFAULT_TARGET_FLAGS MASK_STRICT_ALIGNMENT
180 #undef TARGET_HANDLE_OPTION
181 #define TARGET_HANDLE_OPTION m68k_handle_option
183 #undef TARGET_RTX_COSTS
184 #define TARGET_RTX_COSTS m68k_rtx_costs
186 #undef TARGET_ATTRIBUTE_TABLE
187 #define TARGET_ATTRIBUTE_TABLE m68k_attribute_table
189 #undef TARGET_PROMOTE_PROTOTYPES
190 #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
192 #undef TARGET_STRUCT_VALUE_RTX
193 #define TARGET_STRUCT_VALUE_RTX m68k_struct_value_rtx
195 static const struct attribute_spec m68k_attribute_table
[] =
197 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
198 { "interrupt_handler", 0, 0, true, false, false, m68k_handle_fndecl_attribute
},
199 { NULL
, 0, 0, false, false, false, NULL
}
202 struct gcc_target targetm
= TARGET_INITIALIZER
;
204 /* Base flags for 68k ISAs. */
205 #define FL_FOR_isa_00 FL_ISA_68000
206 #define FL_FOR_isa_10 (FL_FOR_isa_00 | FL_ISA_68010)
207 /* FL_68881 controls the default setting of -m68881. gcc has traditionally
208 generated 68881 code for 68020 and 68030 targets unless explicitly told
210 #define FL_FOR_isa_20 (FL_FOR_isa_10 | FL_ISA_68020 \
211 | FL_BITFIELD | FL_68881)
212 #define FL_FOR_isa_40 (FL_FOR_isa_20 | FL_ISA_68040)
213 #define FL_FOR_isa_cpu32 (FL_FOR_isa_10 | FL_ISA_68020)
215 /* Base flags for ColdFire ISAs. */
216 #define FL_FOR_isa_a (FL_COLDFIRE | FL_ISA_A)
217 #define FL_FOR_isa_aplus (FL_FOR_isa_a | FL_ISA_APLUS | FL_CF_USP)
218 /* Note ISA_B doesn't necessarily include USP (user stack pointer) support. */
219 #define FL_FOR_isa_b (FL_FOR_isa_a | FL_ISA_B | FL_CF_HWDIV)
220 #define FL_FOR_isa_c (FL_FOR_isa_b | FL_ISA_C | FL_CF_USP)
224 /* Traditional 68000 instruction sets. */
230 /* ColdFire instruction set variants. */
238 /* Information about one of the -march, -mcpu or -mtune arguments. */
239 struct m68k_target_selection
241 /* The argument being described. */
244 /* For -mcpu, this is the device selected by the option.
245 For -mtune and -march, it is a representative device
246 for the microarchitecture or ISA respectively. */
247 enum target_device device
;
249 /* The M68K_DEVICE fields associated with DEVICE. See the comment
250 in m68k-devices.def for details. FAMILY is only valid for -mcpu. */
252 enum uarch_type microarch
;
257 /* A list of all devices in m68k-devices.def. Used for -mcpu selection. */
258 static const struct m68k_target_selection all_devices
[] =
260 #define M68K_DEVICE(NAME,ENUM_VALUE,FAMILY,MULTILIB,MICROARCH,ISA,FLAGS) \
261 { NAME, ENUM_VALUE, FAMILY, u##MICROARCH, ISA, FLAGS | FL_FOR_##ISA },
262 #include "m68k-devices.def"
264 { NULL
, unk_device
, NULL
, unk_arch
, isa_max
, 0 }
267 /* A list of all ISAs, mapping each one to a representative device.
268 Used for -march selection. */
269 static const struct m68k_target_selection all_isas
[] =
271 { "68000", m68000
, NULL
, u68000
, isa_00
, FL_FOR_isa_00
},
272 { "68010", m68010
, NULL
, u68010
, isa_10
, FL_FOR_isa_10
},
273 { "68020", m68020
, NULL
, u68020
, isa_20
, FL_FOR_isa_20
},
274 { "68030", m68030
, NULL
, u68030
, isa_20
, FL_FOR_isa_20
},
275 { "68040", m68040
, NULL
, u68040
, isa_40
, FL_FOR_isa_40
},
276 { "68060", m68060
, NULL
, u68060
, isa_40
, FL_FOR_isa_40
},
277 { "cpu32", cpu32
, NULL
, ucpu32
, isa_20
, FL_FOR_isa_cpu32
},
278 { "isaa", mcf5206e
, NULL
, ucfv2
, isa_a
, (FL_FOR_isa_a
280 { "isaaplus", mcf5271
, NULL
, ucfv2
, isa_aplus
, (FL_FOR_isa_aplus
282 { "isab", mcf5407
, NULL
, ucfv4
, isa_b
, FL_FOR_isa_b
},
283 { "isac", unk_device
, NULL
, ucfv4
, isa_c
, (FL_FOR_isa_c
286 { NULL
, unk_device
, NULL
, unk_arch
, isa_max
, 0 }
289 /* A list of all microarchitectures, mapping each one to a representative
290 device. Used for -mtune selection. */
291 static const struct m68k_target_selection all_microarchs
[] =
293 { "68000", m68000
, NULL
, u68000
, isa_00
, FL_FOR_isa_00
},
294 { "68010", m68010
, NULL
, u68010
, isa_10
, FL_FOR_isa_10
},
295 { "68020", m68020
, NULL
, u68020
, isa_20
, FL_FOR_isa_20
},
296 { "68020-40", m68020
, NULL
, u68020_40
, isa_20
, FL_FOR_isa_20
},
297 { "68020-60", m68020
, NULL
, u68020_60
, isa_20
, FL_FOR_isa_20
},
298 { "68030", m68030
, NULL
, u68030
, isa_20
, FL_FOR_isa_20
},
299 { "68040", m68040
, NULL
, u68040
, isa_40
, FL_FOR_isa_40
},
300 { "68060", m68060
, NULL
, u68060
, isa_40
, FL_FOR_isa_40
},
301 { "cpu32", cpu32
, NULL
, ucpu32
, isa_20
, FL_FOR_isa_cpu32
},
302 { "cfv2", mcf5206
, NULL
, ucfv2
, isa_a
, FL_FOR_isa_a
},
303 { "cfv3", mcf5307
, NULL
, ucfv3
, isa_a
, (FL_FOR_isa_a
305 { "cfv4", mcf5407
, NULL
, ucfv4
, isa_b
, FL_FOR_isa_b
},
306 { "cfv4e", mcf547x
, NULL
, ucfv4e
, isa_b
, (FL_FOR_isa_b
310 { NULL
, unk_device
, NULL
, unk_arch
, isa_max
, 0 }
313 /* The entries associated with the -mcpu, -march and -mtune settings,
314 or null for options that have not been used. */
315 const struct m68k_target_selection
*m68k_cpu_entry
;
316 const struct m68k_target_selection
*m68k_arch_entry
;
317 const struct m68k_target_selection
*m68k_tune_entry
;
319 /* Which CPU we are generating code for. */
320 enum target_device m68k_cpu
;
322 /* Which microarchitecture to tune for. */
323 enum uarch_type m68k_tune
;
325 /* Which FPU to use. */
326 enum fpu_type m68k_fpu
;
328 /* The set of FL_* flags that apply to the target processor. */
329 unsigned int m68k_cpu_flags
;
331 /* Asm templates for calling or jumping to an arbitrary symbolic address,
332 or NULL if such calls or jumps are not supported. The address is held
334 const char *m68k_symbolic_call
;
335 const char *m68k_symbolic_jump
;
337 /* See whether TABLE has an entry with name NAME. Return true and
338 store the entry in *ENTRY if so, otherwise return false and
339 leave *ENTRY alone. */
342 m68k_find_selection (const struct m68k_target_selection
**entry
,
343 const struct m68k_target_selection
*table
,
348 for (i
= 0; table
[i
].name
; i
++)
349 if (strcmp (table
[i
].name
, name
) == 0)
357 /* Implement TARGET_HANDLE_OPTION. */
360 m68k_handle_option (size_t code
, const char *arg
, int value
)
365 return m68k_find_selection (&m68k_arch_entry
, all_isas
, arg
);
368 return m68k_find_selection (&m68k_cpu_entry
, all_devices
, arg
);
371 return m68k_find_selection (&m68k_tune_entry
, all_microarchs
, arg
);
374 return m68k_find_selection (&m68k_cpu_entry
, all_devices
, "5206");
377 return m68k_find_selection (&m68k_cpu_entry
, all_devices
, "5206e");
380 return m68k_find_selection (&m68k_cpu_entry
, all_devices
, "528x");
383 return m68k_find_selection (&m68k_cpu_entry
, all_devices
, "5307");
386 return m68k_find_selection (&m68k_cpu_entry
, all_devices
, "5407");
389 return m68k_find_selection (&m68k_cpu_entry
, all_devices
, "547x");
393 return m68k_find_selection (&m68k_cpu_entry
, all_devices
, "68000");
396 return m68k_find_selection (&m68k_cpu_entry
, all_devices
, "68010");
400 return m68k_find_selection (&m68k_cpu_entry
, all_devices
, "68020");
403 return (m68k_find_selection (&m68k_tune_entry
, all_microarchs
,
405 && m68k_find_selection (&m68k_cpu_entry
, all_devices
, "68020"));
408 return (m68k_find_selection (&m68k_tune_entry
, all_microarchs
,
410 && m68k_find_selection (&m68k_cpu_entry
, all_devices
, "68020"));
413 return m68k_find_selection (&m68k_cpu_entry
, all_devices
, "68030");
416 return m68k_find_selection (&m68k_cpu_entry
, all_devices
, "68040");
419 return m68k_find_selection (&m68k_cpu_entry
, all_devices
, "68060");
422 return m68k_find_selection (&m68k_cpu_entry
, all_devices
, "68302");
426 return m68k_find_selection (&m68k_cpu_entry
, all_devices
, "68332");
428 case OPT_mshared_library_id_
:
429 if (value
> MAX_LIBRARY_ID
)
430 error ("-mshared-library-id=%s is not between 0 and %d",
431 arg
, MAX_LIBRARY_ID
);
433 asprintf ((char **) &m68k_library_id_string
, "%d", (value
* -4) - 4);
441 /* Sometimes certain combinations of command options do not make
442 sense on a particular target machine. You can define a macro
443 `OVERRIDE_OPTIONS' to take account of this. This macro, if
444 defined, is executed once just after all the command options have
447 Don't use this macro to turn on various extra optimizations for
448 `-O'. That is what `OPTIMIZATION_OPTIONS' is for. */
451 override_options (void)
453 const struct m68k_target_selection
*entry
;
454 unsigned long target_mask
;
462 -march=ARCH should generate code that runs any processor
463 implementing architecture ARCH. -mcpu=CPU should override -march
464 and should generate code that runs on processor CPU, making free
465 use of any instructions that CPU understands. -mtune=UARCH applies
466 on top of -mcpu or -march and optimises the code for UARCH. It does
467 not change the target architecture. */
470 /* Complain if the -march setting is for a different microarchitecture,
471 or includes flags that the -mcpu setting doesn't. */
473 && (m68k_arch_entry
->microarch
!= m68k_cpu_entry
->microarch
474 || (m68k_arch_entry
->flags
& ~m68k_cpu_entry
->flags
) != 0))
475 warning (0, "-mcpu=%s conflicts with -march=%s",
476 m68k_cpu_entry
->name
, m68k_arch_entry
->name
);
478 entry
= m68k_cpu_entry
;
481 entry
= m68k_arch_entry
;
484 entry
= all_devices
+ TARGET_CPU_DEFAULT
;
486 m68k_cpu_flags
= entry
->flags
;
488 /* Use the architecture setting to derive default values for
491 if ((m68k_cpu_flags
& FL_BITFIELD
) != 0)
492 target_mask
|= MASK_BITFIELD
;
493 if ((m68k_cpu_flags
& FL_CF_HWDIV
) != 0)
494 target_mask
|= MASK_CF_HWDIV
;
495 if ((m68k_cpu_flags
& (FL_68881
| FL_CF_FPU
)) != 0)
496 target_mask
|= MASK_HARD_FLOAT
;
497 target_flags
|= target_mask
& ~target_flags_explicit
;
499 /* Set the directly-usable versions of the -mcpu and -mtune settings. */
500 m68k_cpu
= entry
->device
;
502 m68k_tune
= m68k_tune_entry
->microarch
;
503 #ifdef M68K_DEFAULT_TUNE
504 else if (!m68k_cpu_entry
&& !m68k_arch_entry
)
505 m68k_tune
= M68K_DEFAULT_TUNE
;
508 m68k_tune
= entry
->microarch
;
510 /* Set the type of FPU. */
511 m68k_fpu
= (!TARGET_HARD_FLOAT
? FPUTYPE_NONE
512 : (m68k_cpu_flags
& FL_COLDFIRE
) != 0 ? FPUTYPE_COLDFIRE
515 if (TARGET_COLDFIRE_FPU
)
517 REAL_MODE_FORMAT (SFmode
) = &coldfire_single_format
;
518 REAL_MODE_FORMAT (DFmode
) = &coldfire_double_format
;
521 /* Sanity check to ensure that msep-data and mid-sahred-library are not
522 * both specified together. Doing so simply doesn't make sense.
524 if (TARGET_SEP_DATA
&& TARGET_ID_SHARED_LIBRARY
)
525 error ("cannot specify both -msep-data and -mid-shared-library");
527 /* If we're generating code for a separate A5 relative data segment,
528 * we've got to enable -fPIC as well. This might be relaxable to
529 * -fpic but it hasn't been tested properly.
531 if (TARGET_SEP_DATA
|| TARGET_ID_SHARED_LIBRARY
)
534 /* -mpcrel -fPIC uses 32-bit pc-relative displacements. Raise an
535 error if the target does not support them. */
536 if (TARGET_PCREL
&& !TARGET_68020
&& flag_pic
== 2)
537 error ("-mpcrel -fPIC is not currently supported on selected cpu");
539 /* ??? A historic way of turning on pic, or is this intended to
540 be an embedded thing that doesn't have the same name binding
541 significance that it does on hosted ELF systems? */
542 if (TARGET_PCREL
&& flag_pic
== 0)
547 #if MOTOROLA && !defined (USE_GAS)
548 m68k_symbolic_call
= "jsr %a0";
549 m68k_symbolic_jump
= "jmp %a0";
551 m68k_symbolic_call
= "jbsr %a0";
552 m68k_symbolic_jump
= "jra %a0";
555 else if (TARGET_ID_SHARED_LIBRARY
)
556 /* All addresses must be loaded from the GOT. */
558 else if (TARGET_68020
|| TARGET_ISAB
)
562 m68k_symbolic_call
= "bsr.l %c0";
563 m68k_symbolic_jump
= "bra.l %c0";
568 m68k_symbolic_call
= "bsr.l %p0";
569 m68k_symbolic_jump
= "bra.l %p0";
571 m68k_symbolic_call
= "bsr %p0";
572 m68k_symbolic_jump
= "bra %p0";
575 /* Turn off function cse if we are doing PIC. We always want
576 function call to be done as `bsr foo@PLTPC'. */
577 /* ??? It's traditional to do this for -mpcrel too, but it isn't
578 clear how intentional that is. */
579 flag_no_function_cse
= 1;
582 SUBTARGET_OVERRIDE_OPTIONS
;
585 /* Generate a macro of the form __mPREFIX_cpu_NAME, where PREFIX is the
586 given argument and NAME is the argument passed to -mcpu. Return NULL
587 if -mcpu was not passed. */
590 m68k_cpp_cpu_ident (const char *prefix
)
594 return concat ("__m", prefix
, "_cpu_", m68k_cpu_entry
->name
, NULL
);
597 /* Generate a macro of the form __mPREFIX_family_NAME, where PREFIX is the
598 given argument and NAME is the name of the representative device for
599 the -mcpu argument's family. Return NULL if -mcpu was not passed. */
602 m68k_cpp_cpu_family (const char *prefix
)
606 return concat ("__m", prefix
, "_family_", m68k_cpu_entry
->family
, NULL
);
609 /* Return nonzero if FUNC is an interrupt function as specified by the
610 "interrupt_handler" attribute. */
612 m68k_interrupt_function_p(tree func
)
616 if (TREE_CODE (func
) != FUNCTION_DECL
)
619 a
= lookup_attribute ("interrupt_handler", DECL_ATTRIBUTES (func
));
620 return (a
!= NULL_TREE
);
623 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
624 struct attribute_spec.handler. */
626 m68k_handle_fndecl_attribute (tree
*node
, tree name
,
627 tree args ATTRIBUTE_UNUSED
,
628 int flags ATTRIBUTE_UNUSED
,
631 if (TREE_CODE (*node
) != FUNCTION_DECL
)
633 warning (OPT_Wattributes
, "%qs attribute only applies to functions",
634 IDENTIFIER_POINTER (name
));
635 *no_add_attrs
= true;
642 m68k_compute_frame_layout (void)
645 unsigned int mask
, rmask
;
646 bool interrupt_handler
= m68k_interrupt_function_p (current_function_decl
);
648 /* Only compute the frame once per function.
649 Don't cache information until reload has been completed. */
650 if (current_frame
.funcdef_no
== current_function_funcdef_no
654 current_frame
.size
= (get_frame_size () + 3) & -4;
656 mask
= rmask
= saved
= 0;
657 for (regno
= 0; regno
< 16; regno
++)
658 if (m68k_save_reg (regno
, interrupt_handler
))
661 rmask
|= 1 << (15 - regno
);
664 current_frame
.offset
= saved
* 4;
665 current_frame
.reg_no
= saved
;
666 current_frame
.reg_mask
= mask
;
667 current_frame
.reg_rev_mask
= rmask
;
669 current_frame
.foffset
= 0;
670 mask
= rmask
= saved
= 0;
671 if (TARGET_HARD_FLOAT
)
673 for (regno
= 16; regno
< 24; regno
++)
674 if (m68k_save_reg (regno
, interrupt_handler
))
676 mask
|= 1 << (regno
- 16);
677 rmask
|= 1 << (23 - regno
);
680 current_frame
.foffset
= saved
* TARGET_FP_REG_SIZE
;
681 current_frame
.offset
+= current_frame
.foffset
;
683 current_frame
.fpu_no
= saved
;
684 current_frame
.fpu_mask
= mask
;
685 current_frame
.fpu_rev_mask
= rmask
;
687 /* Remember what function this frame refers to. */
688 current_frame
.funcdef_no
= current_function_funcdef_no
;
692 m68k_initial_elimination_offset (int from
, int to
)
695 /* The arg pointer points 8 bytes before the start of the arguments,
696 as defined by FIRST_PARM_OFFSET. This makes it coincident with the
697 frame pointer in most frames. */
698 argptr_offset
= frame_pointer_needed
? 0 : UNITS_PER_WORD
;
699 if (from
== ARG_POINTER_REGNUM
&& to
== FRAME_POINTER_REGNUM
)
700 return argptr_offset
;
702 m68k_compute_frame_layout ();
704 gcc_assert (to
== STACK_POINTER_REGNUM
);
707 case ARG_POINTER_REGNUM
:
708 return current_frame
.offset
+ current_frame
.size
- argptr_offset
;
709 case FRAME_POINTER_REGNUM
:
710 return current_frame
.offset
+ current_frame
.size
;
716 /* Refer to the array `regs_ever_live' to determine which registers
717 to save; `regs_ever_live[I]' is nonzero if register number I
718 is ever used in the function. This function is responsible for
719 knowing which registers should not be saved even if used.
720 Return true if we need to save REGNO. */
723 m68k_save_reg (unsigned int regno
, bool interrupt_handler
)
725 if (flag_pic
&& regno
== PIC_OFFSET_TABLE_REGNUM
)
727 if (current_function_uses_pic_offset_table
)
729 if (!current_function_is_leaf
&& TARGET_ID_SHARED_LIBRARY
)
733 if (current_function_calls_eh_return
)
738 unsigned int test
= EH_RETURN_DATA_REGNO (i
);
739 if (test
== INVALID_REGNUM
)
746 /* Fixed regs we never touch. */
747 if (fixed_regs
[regno
])
750 /* The frame pointer (if it is such) is handled specially. */
751 if (regno
== FRAME_POINTER_REGNUM
&& frame_pointer_needed
)
754 /* Interrupt handlers must also save call_used_regs
755 if they are live or when calling nested functions. */
756 if (interrupt_handler
)
758 if (regs_ever_live
[regno
])
761 if (!current_function_is_leaf
&& call_used_regs
[regno
])
765 /* Never need to save registers that aren't touched. */
766 if (!regs_ever_live
[regno
])
769 /* Otherwise save everything that isn't call-clobbered. */
770 return !call_used_regs
[regno
];
773 /* This function generates the assembly code for function entry.
774 STREAM is a stdio stream to output the code to.
775 SIZE is an int: how many units of temporary storage to allocate. */
778 m68k_output_function_prologue (FILE *stream
,
779 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
781 HOST_WIDE_INT fsize_with_regs
;
782 HOST_WIDE_INT cfa_offset
= INCOMING_FRAME_SP_OFFSET
;
784 m68k_compute_frame_layout();
786 /* If the stack limit is a symbol, we can check it here,
787 before actually allocating the space. */
788 if (current_function_limit_stack
789 && GET_CODE (stack_limit_rtx
) == SYMBOL_REF
)
790 asm_fprintf (stream
, "\tcmp" ASM_DOT
"l %I%s+%wd,%Rsp\n\ttrapcs\n",
791 XSTR (stack_limit_rtx
, 0), current_frame
.size
+ 4);
793 /* On ColdFire add register save into initial stack frame setup, if possible. */
794 fsize_with_regs
= current_frame
.size
;
797 if (current_frame
.reg_no
> 2)
798 fsize_with_regs
+= current_frame
.reg_no
* 4;
799 if (current_frame
.fpu_no
)
800 fsize_with_regs
+= current_frame
.fpu_no
* 8;
803 if (frame_pointer_needed
)
805 if (current_frame
.size
== 0 && TUNE_68040
)
806 /* on the 68040, pea + move is faster than link.w 0 */
807 fprintf (stream
, (MOTOROLA
808 ? "\tpea (%s)\n\tmove.l %s,%s\n"
809 : "\tpea %s@\n\tmovel %s,%s\n"),
810 M68K_REGNAME (FRAME_POINTER_REGNUM
),
811 M68K_REGNAME (STACK_POINTER_REGNUM
),
812 M68K_REGNAME (FRAME_POINTER_REGNUM
));
813 else if (fsize_with_regs
< 0x8000)
814 asm_fprintf (stream
, "\tlink" ASM_DOTW
" %s,%I%wd\n",
815 M68K_REGNAME (FRAME_POINTER_REGNUM
), -fsize_with_regs
);
816 else if (TARGET_68020
)
817 asm_fprintf (stream
, "\tlink" ASM_DOTL
" %s,%I%wd\n",
818 M68K_REGNAME (FRAME_POINTER_REGNUM
), -fsize_with_regs
);
820 /* Adding negative number is faster on the 68040. */
822 "\tlink" ASM_DOTW
" %s,%I0\n"
823 "\tadd" ASM_DOT
"l %I%wd,%Rsp\n",
824 M68K_REGNAME (FRAME_POINTER_REGNUM
), -fsize_with_regs
);
826 else if (fsize_with_regs
) /* !frame_pointer_needed */
828 if (fsize_with_regs
< 0x8000)
830 if (fsize_with_regs
<= 8)
832 if (!TARGET_COLDFIRE
)
833 asm_fprintf (stream
, "\tsubq" ASM_DOT
"w %I%wd,%Rsp\n",
836 asm_fprintf (stream
, "\tsubq" ASM_DOT
"l %I%wd,%Rsp\n",
839 else if (fsize_with_regs
<= 16 && TUNE_CPU32
)
840 /* On the CPU32 it is faster to use two subqw instructions to
841 subtract a small integer (8 < N <= 16) to a register. */
843 "\tsubq" ASM_DOT
"w %I8,%Rsp\n"
844 "\tsubq" ASM_DOT
"w %I%wd,%Rsp\n",
845 fsize_with_regs
- 8);
847 /* Adding negative number is faster on the 68040. */
848 asm_fprintf (stream
, "\tadd" ASM_DOT
"w %I%wd,%Rsp\n",
851 asm_fprintf (stream
, (MOTOROLA
852 ? "\tlea (%wd,%Rsp),%Rsp\n"
853 : "\tlea %Rsp@(%wd),%Rsp\n"),
856 else /* fsize_with_regs >= 0x8000 */
857 asm_fprintf (stream
, "\tadd" ASM_DOT
"l %I%wd,%Rsp\n",
859 } /* !frame_pointer_needed */
861 if (dwarf2out_do_frame ())
863 if (frame_pointer_needed
)
866 l
= (char *) dwarf2out_cfi_label ();
868 dwarf2out_reg_save (l
, FRAME_POINTER_REGNUM
, -cfa_offset
);
869 dwarf2out_def_cfa (l
, FRAME_POINTER_REGNUM
, cfa_offset
);
870 cfa_offset
+= current_frame
.size
;
874 cfa_offset
+= current_frame
.size
;
875 dwarf2out_def_cfa ("", STACK_POINTER_REGNUM
, cfa_offset
);
879 if (current_frame
.fpu_mask
)
883 asm_fprintf (stream
, (MOTOROLA
884 ? "\tfmovm %I0x%x,-(%Rsp)\n"
885 : "\tfmovem %I0x%x,%Rsp@-\n"),
886 current_frame
.fpu_mask
);
892 /* stack already has registers in it. Find the offset from
893 the bottom of stack to where the FP registers go */
894 if (current_frame
.reg_no
<= 2)
897 offset
= current_frame
.reg_no
* 4;
900 "\tfmovem %I0x%x,%d(%Rsp)\n",
901 current_frame
.fpu_rev_mask
,
905 "\tfmovem %I0x%x,(%Rsp)\n",
906 current_frame
.fpu_rev_mask
);
909 if (dwarf2out_do_frame ())
911 char *l
= (char *) dwarf2out_cfi_label ();
914 cfa_offset
+= current_frame
.fpu_no
* TARGET_FP_REG_SIZE
;
915 if (! frame_pointer_needed
)
916 dwarf2out_def_cfa (l
, STACK_POINTER_REGNUM
, cfa_offset
);
917 for (regno
= 16, n_regs
= 0; regno
< 24; regno
++)
918 if (current_frame
.fpu_mask
& (1 << (regno
- 16)))
919 dwarf2out_reg_save (l
, regno
, -cfa_offset
920 + n_regs
++ * TARGET_FP_REG_SIZE
);
924 /* If the stack limit is not a symbol, check it here.
925 This has the disadvantage that it may be too late... */
926 if (current_function_limit_stack
)
928 if (REG_P (stack_limit_rtx
))
929 asm_fprintf (stream
, "\tcmp" ASM_DOT
"l %s,%Rsp\n\ttrapcs\n",
930 M68K_REGNAME (REGNO (stack_limit_rtx
)));
931 else if (GET_CODE (stack_limit_rtx
) != SYMBOL_REF
)
932 warning (0, "stack limit expression is not supported");
935 if (current_frame
.reg_no
<= 2)
937 /* Store each separately in the same order moveml uses.
938 Using two movel instructions instead of a single moveml
939 is about 15% faster for the 68020 and 68030 at no expense
944 for (i
= 0; i
< 16; i
++)
945 if (current_frame
.reg_rev_mask
& (1 << i
))
947 asm_fprintf (stream
, (MOTOROLA
948 ? "\t%Omove.l %s,-(%Rsp)\n"
949 : "\tmovel %s,%Rsp@-\n"),
950 M68K_REGNAME (15 - i
));
951 if (dwarf2out_do_frame ())
953 char *l
= (char *) dwarf2out_cfi_label ();
956 if (! frame_pointer_needed
)
957 dwarf2out_def_cfa (l
, STACK_POINTER_REGNUM
, cfa_offset
);
958 dwarf2out_reg_save (l
, 15 - i
, -cfa_offset
);
962 else if (current_frame
.reg_rev_mask
)
965 /* The ColdFire does not support the predecrement form of the
966 MOVEM instruction, so we must adjust the stack pointer and
967 then use the plain address register indirect mode.
968 The required register save space was combined earlier with
969 the fsize_with_regs amount. */
971 asm_fprintf (stream
, (MOTOROLA
972 ? "\tmovm.l %I0x%x,(%Rsp)\n"
973 : "\tmoveml %I0x%x,%Rsp@\n"),
974 current_frame
.reg_mask
);
976 asm_fprintf (stream
, (MOTOROLA
977 ? "\tmovm.l %I0x%x,-(%Rsp)\n"
978 : "\tmoveml %I0x%x,%Rsp@-\n"),
979 current_frame
.reg_rev_mask
);
980 if (dwarf2out_do_frame ())
982 char *l
= (char *) dwarf2out_cfi_label ();
985 cfa_offset
+= current_frame
.reg_no
* 4;
986 if (! frame_pointer_needed
)
987 dwarf2out_def_cfa (l
, STACK_POINTER_REGNUM
, cfa_offset
);
988 for (regno
= 0, n_regs
= 0; regno
< 16; regno
++)
989 if (current_frame
.reg_mask
& (1 << regno
))
990 dwarf2out_reg_save (l
, regno
, -cfa_offset
+ n_regs
++ * 4);
993 if (!TARGET_SEP_DATA
&& flag_pic
994 && (current_function_uses_pic_offset_table
995 || (!current_function_is_leaf
&& TARGET_ID_SHARED_LIBRARY
)))
997 if (TARGET_ID_SHARED_LIBRARY
)
999 asm_fprintf (stream
, "\tmovel %s@(%s), %s\n",
1000 M68K_REGNAME (PIC_OFFSET_TABLE_REGNUM
),
1001 m68k_library_id_string
,
1002 M68K_REGNAME (PIC_OFFSET_TABLE_REGNUM
));
1007 asm_fprintf (stream
,
1008 "\t%Olea (%Rpc, %U_GLOBAL_OFFSET_TABLE_@GOTPC), %s\n",
1009 M68K_REGNAME (PIC_OFFSET_TABLE_REGNUM
));
1012 asm_fprintf (stream
, "\tmovel %I%U_GLOBAL_OFFSET_TABLE_, %s\n",
1013 M68K_REGNAME (PIC_OFFSET_TABLE_REGNUM
));
1014 asm_fprintf (stream
, "\tlea %Rpc@(0,%s:l),%s\n",
1015 M68K_REGNAME (PIC_OFFSET_TABLE_REGNUM
),
1016 M68K_REGNAME (PIC_OFFSET_TABLE_REGNUM
));
1022 /* Return true if this function's epilogue can be output as RTL. */
1025 m68k_use_return_insn (void)
1027 if (!reload_completed
|| frame_pointer_needed
|| get_frame_size () != 0)
1030 /* We can output the epilogue as RTL only if no registers need to be
1032 m68k_compute_frame_layout ();
1033 return current_frame
.reg_no
? false : true;
1036 /* This function generates the assembly code for function exit,
1037 on machines that need it.
1039 The function epilogue should not depend on the current stack pointer!
1040 It should use the frame pointer only, if there is a frame pointer.
1041 This is mandatory because of alloca; we also take advantage of it to
1042 omit stack adjustments before returning. */
1045 m68k_output_function_epilogue (FILE *stream
,
1046 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
1048 HOST_WIDE_INT fsize
, fsize_with_regs
;
1050 bool restore_from_sp
= false;
1051 rtx insn
= get_last_insn ();
1053 m68k_compute_frame_layout ();
1055 /* If the last insn was a BARRIER, we don't have to write any code. */
1056 if (GET_CODE (insn
) == NOTE
)
1057 insn
= prev_nonnote_insn (insn
);
1058 if (insn
&& GET_CODE (insn
) == BARRIER
)
1060 /* Output just a no-op so that debuggers don't get confused
1061 about which function the pc is in at this address. */
1062 fprintf (stream
, "\tnop\n");
1066 #ifdef FUNCTION_EXTRA_EPILOGUE
1067 FUNCTION_EXTRA_EPILOGUE (stream
, size
);
1070 fsize
= current_frame
.size
;
1072 /* FIXME: leaf_function_p below is too strong.
1073 What we really need to know there is if there could be pending
1074 stack adjustment needed at that point. */
1076 = (! frame_pointer_needed
1077 || (! current_function_calls_alloca
&& leaf_function_p ()));
1079 /* fsize_with_regs is the size we need to adjust the sp when
1080 popping the frame. */
1081 fsize_with_regs
= fsize
;
1083 /* Because the ColdFire doesn't support moveml with
1084 complex address modes, we must adjust the stack manually
1085 after restoring registers. When the frame pointer isn't used,
1086 we can merge movem adjustment into frame unlinking
1087 made immediately after it. */
1088 if (TARGET_COLDFIRE
&& restore_from_sp
)
1090 if (current_frame
.reg_no
> 2)
1091 fsize_with_regs
+= current_frame
.reg_no
* 4;
1092 if (current_frame
.fpu_no
)
1093 fsize_with_regs
+= current_frame
.fpu_no
* 8;
1096 if (current_frame
.offset
+ fsize
>= 0x8000
1097 && ! restore_from_sp
1098 && (current_frame
.reg_mask
|| current_frame
.fpu_mask
))
1100 /* Because the ColdFire doesn't support moveml with
1101 complex address modes we make an extra correction here. */
1102 if (TARGET_COLDFIRE
)
1103 fsize
+= current_frame
.offset
;
1105 asm_fprintf (stream
, "\t%Omove" ASM_DOT
"l %I%wd,%Ra1\n", -fsize
);
1106 fsize
= 0, big
= true;
1108 if (current_frame
.reg_no
<= 2)
1110 /* Restore each separately in the same order moveml does.
1111 Using two movel instructions instead of a single moveml
1112 is about 15% faster for the 68020 and 68030 at no expense
1116 HOST_WIDE_INT offset
= current_frame
.offset
+ fsize
;
1118 for (i
= 0; i
< 16; i
++)
1119 if (current_frame
.reg_mask
& (1 << i
))
1124 asm_fprintf (stream
, "\t%Omove.l -%wd(%s,%Ra1.l),%s\n",
1126 M68K_REGNAME (FRAME_POINTER_REGNUM
),
1129 asm_fprintf (stream
, "\tmovel %s@(-%wd,%Ra1:l),%s\n",
1130 M68K_REGNAME (FRAME_POINTER_REGNUM
),
1134 else if (restore_from_sp
)
1135 asm_fprintf (stream
, (MOTOROLA
1136 ? "\t%Omove.l (%Rsp)+,%s\n"
1137 : "\tmovel %Rsp@+,%s\n"),
1142 asm_fprintf (stream
, "\t%Omove.l -%wd(%s),%s\n",
1144 M68K_REGNAME (FRAME_POINTER_REGNUM
),
1147 asm_fprintf (stream
, "\tmovel %s@(-%wd),%s\n",
1148 M68K_REGNAME (FRAME_POINTER_REGNUM
),
1155 else if (current_frame
.reg_mask
)
1157 /* The ColdFire requires special handling due to its limited moveml
1159 if (TARGET_COLDFIRE
)
1163 asm_fprintf (stream
, "\tadd" ASM_DOT
"l %s,%Ra1\n",
1164 M68K_REGNAME (FRAME_POINTER_REGNUM
));
1165 asm_fprintf (stream
, (MOTOROLA
1166 ? "\tmovm.l (%Ra1),%I0x%x\n"
1167 : "\tmoveml %Ra1@,%I0x%x\n"),
1168 current_frame
.reg_mask
);
1170 else if (restore_from_sp
)
1171 asm_fprintf (stream
, (MOTOROLA
1172 ? "\tmovm.l (%Rsp),%I0x%x\n"
1173 : "\tmoveml %Rsp@,%I0x%x\n"),
1174 current_frame
.reg_mask
);
1178 asm_fprintf (stream
, "\tmovm.l -%wd(%s),%I0x%x\n",
1179 current_frame
.offset
+ fsize
,
1180 M68K_REGNAME (FRAME_POINTER_REGNUM
),
1181 current_frame
.reg_mask
);
1183 asm_fprintf (stream
, "\tmoveml %s@(-%wd),%I0x%x\n",
1184 M68K_REGNAME (FRAME_POINTER_REGNUM
),
1185 current_frame
.offset
+ fsize
,
1186 current_frame
.reg_mask
);
1189 else /* !TARGET_COLDFIRE */
1194 asm_fprintf (stream
, "\tmovm.l -%wd(%s,%Ra1.l),%I0x%x\n",
1195 current_frame
.offset
+ fsize
,
1196 M68K_REGNAME (FRAME_POINTER_REGNUM
),
1197 current_frame
.reg_mask
);
1199 asm_fprintf (stream
, "\tmoveml %s@(-%wd,%Ra1:l),%I0x%x\n",
1200 M68K_REGNAME (FRAME_POINTER_REGNUM
),
1201 current_frame
.offset
+ fsize
,
1202 current_frame
.reg_mask
);
1204 else if (restore_from_sp
)
1206 asm_fprintf (stream
, (MOTOROLA
1207 ? "\tmovm.l (%Rsp)+,%I0x%x\n"
1208 : "\tmoveml %Rsp@+,%I0x%x\n"),
1209 current_frame
.reg_mask
);
1214 asm_fprintf (stream
, "\tmovm.l -%wd(%s),%I0x%x\n",
1215 current_frame
.offset
+ fsize
,
1216 M68K_REGNAME (FRAME_POINTER_REGNUM
),
1217 current_frame
.reg_mask
);
1219 asm_fprintf (stream
, "\tmoveml %s@(-%wd),%I0x%x\n",
1220 M68K_REGNAME (FRAME_POINTER_REGNUM
),
1221 current_frame
.offset
+ fsize
,
1222 current_frame
.reg_mask
);
1226 if (current_frame
.fpu_rev_mask
)
1230 if (TARGET_COLDFIRE
)
1232 if (current_frame
.reg_no
)
1233 asm_fprintf (stream
, MOTOROLA
?
1234 "\tfmovem.d %d(%Ra1),%I0x%x\n" :
1235 "\tfmovmd (%d,%Ra1),%I0x%x\n",
1236 current_frame
.reg_no
* 4,
1237 current_frame
.fpu_rev_mask
);
1239 asm_fprintf (stream
, MOTOROLA
?
1240 "\tfmovem.d (%Ra1),%I0x%x\n" :
1241 "\tfmovmd (%Ra1),%I0x%x\n",
1242 current_frame
.fpu_rev_mask
);
1245 asm_fprintf (stream
, "\tfmovm -%wd(%s,%Ra1.l),%I0x%x\n",
1246 current_frame
.foffset
+ fsize
,
1247 M68K_REGNAME (FRAME_POINTER_REGNUM
),
1248 current_frame
.fpu_rev_mask
);
1250 asm_fprintf (stream
, "\tfmovem %s@(-%wd,%Ra1:l),%I0x%x\n",
1251 M68K_REGNAME (FRAME_POINTER_REGNUM
),
1252 current_frame
.foffset
+ fsize
,
1253 current_frame
.fpu_rev_mask
);
1255 else if (restore_from_sp
)
1257 if (TARGET_COLDFIRE
)
1261 /* Stack already has registers in it. Find the offset from
1262 the bottom of stack to where the FP registers go. */
1263 if (current_frame
.reg_no
<= 2)
1266 offset
= current_frame
.reg_no
* 4;
1268 asm_fprintf (stream
,
1269 "\tfmovem %Rsp@(%d), %I0x%x\n",
1270 offset
, current_frame
.fpu_rev_mask
);
1272 asm_fprintf (stream
,
1273 "\tfmovem %Rsp@, %I0x%x\n",
1274 current_frame
.fpu_rev_mask
);
1277 asm_fprintf (stream
, MOTOROLA
?
1278 "\tfmovm (%Rsp)+,%I0x%x\n" :
1279 "\tfmovem %Rsp@+,%I0x%x\n",
1280 current_frame
.fpu_rev_mask
);
1284 if (MOTOROLA
&& !TARGET_COLDFIRE
)
1285 asm_fprintf (stream
, "\tfmovm -%wd(%s),%I0x%x\n",
1286 current_frame
.foffset
+ fsize
,
1287 M68K_REGNAME (FRAME_POINTER_REGNUM
),
1288 current_frame
.fpu_rev_mask
);
1290 asm_fprintf (stream
, "\tfmovem %s@(-%wd),%I0x%x\n",
1291 M68K_REGNAME (FRAME_POINTER_REGNUM
),
1292 current_frame
.foffset
+ fsize
,
1293 current_frame
.fpu_rev_mask
);
1296 if (frame_pointer_needed
)
1297 fprintf (stream
, "\tunlk %s\n", M68K_REGNAME (FRAME_POINTER_REGNUM
));
1298 else if (fsize_with_regs
)
1300 if (fsize_with_regs
<= 8)
1302 if (!TARGET_COLDFIRE
)
1303 asm_fprintf (stream
, "\taddq" ASM_DOT
"w %I%wd,%Rsp\n",
1306 asm_fprintf (stream
, "\taddq" ASM_DOT
"l %I%wd,%Rsp\n",
1309 else if (fsize_with_regs
<= 16 && TUNE_CPU32
)
1311 /* On the CPU32 it is faster to use two addqw instructions to
1312 add a small integer (8 < N <= 16) to a register. */
1313 asm_fprintf (stream
,
1314 "\taddq" ASM_DOT
"w %I8,%Rsp\n"
1315 "\taddq" ASM_DOT
"w %I%wd,%Rsp\n",
1316 fsize_with_regs
- 8);
1318 else if (fsize_with_regs
< 0x8000)
1321 asm_fprintf (stream
, "\tadd" ASM_DOT
"w %I%wd,%Rsp\n",
1324 asm_fprintf (stream
, (MOTOROLA
1325 ? "\tlea (%wd,%Rsp),%Rsp\n"
1326 : "\tlea %Rsp@(%wd),%Rsp\n"),
1330 asm_fprintf (stream
, "\tadd" ASM_DOT
"l %I%wd,%Rsp\n", fsize_with_regs
);
1332 if (current_function_calls_eh_return
)
1333 asm_fprintf (stream
, "\tadd" ASM_DOT
"l %Ra0,%Rsp\n");
1334 if (m68k_interrupt_function_p (current_function_decl
))
1335 fprintf (stream
, "\trte\n");
1336 else if (current_function_pops_args
)
1337 asm_fprintf (stream
, "\trtd %I%d\n", current_function_pops_args
);
1339 fprintf (stream
, "\trts\n");
1342 /* Return true if X is a valid comparison operator for the dbcc
1345 Note it rejects floating point comparison operators.
1346 (In the future we could use Fdbcc).
1348 It also rejects some comparisons when CC_NO_OVERFLOW is set. */
1351 valid_dbcc_comparison_p_2 (rtx x
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1353 switch (GET_CODE (x
))
1355 case EQ
: case NE
: case GTU
: case LTU
:
1359 /* Reject some when CC_NO_OVERFLOW is set. This may be over
1361 case GT
: case LT
: case GE
: case LE
:
1362 return ! (cc_prev_status
.flags
& CC_NO_OVERFLOW
);
1368 /* Return nonzero if flags are currently in the 68881 flag register. */
1370 flags_in_68881 (void)
1372 /* We could add support for these in the future */
1373 return cc_status
.flags
& CC_IN_68881
;
1376 /* Convert X to a legitimate function call memory reference and return the
1380 m68k_legitimize_call_address (rtx x
)
1382 gcc_assert (MEM_P (x
));
1383 if (call_operand (XEXP (x
, 0), VOIDmode
))
1385 return replace_equiv_address (x
, force_reg (Pmode
, XEXP (x
, 0)));
1388 /* Output a dbCC; jCC sequence. Note we do not handle the
1389 floating point version of this sequence (Fdbcc). We also
1390 do not handle alternative conditions when CC_NO_OVERFLOW is
1391 set. It is assumed that valid_dbcc_comparison_p and flags_in_68881 will
1392 kick those out before we get here. */
1395 output_dbcc_and_branch (rtx
*operands
)
1397 switch (GET_CODE (operands
[3]))
1400 output_asm_insn (MOTOROLA
1401 ? "dbeq %0,%l1\n\tjbeq %l2"
1402 : "dbeq %0,%l1\n\tjeq %l2",
1407 output_asm_insn (MOTOROLA
1408 ? "dbne %0,%l1\n\tjbne %l2"
1409 : "dbne %0,%l1\n\tjne %l2",
1414 output_asm_insn (MOTOROLA
1415 ? "dbgt %0,%l1\n\tjbgt %l2"
1416 : "dbgt %0,%l1\n\tjgt %l2",
1421 output_asm_insn (MOTOROLA
1422 ? "dbhi %0,%l1\n\tjbhi %l2"
1423 : "dbhi %0,%l1\n\tjhi %l2",
1428 output_asm_insn (MOTOROLA
1429 ? "dblt %0,%l1\n\tjblt %l2"
1430 : "dblt %0,%l1\n\tjlt %l2",
1435 output_asm_insn (MOTOROLA
1436 ? "dbcs %0,%l1\n\tjbcs %l2"
1437 : "dbcs %0,%l1\n\tjcs %l2",
1442 output_asm_insn (MOTOROLA
1443 ? "dbge %0,%l1\n\tjbge %l2"
1444 : "dbge %0,%l1\n\tjge %l2",
1449 output_asm_insn (MOTOROLA
1450 ? "dbcc %0,%l1\n\tjbcc %l2"
1451 : "dbcc %0,%l1\n\tjcc %l2",
1456 output_asm_insn (MOTOROLA
1457 ? "dble %0,%l1\n\tjble %l2"
1458 : "dble %0,%l1\n\tjle %l2",
1463 output_asm_insn (MOTOROLA
1464 ? "dbls %0,%l1\n\tjbls %l2"
1465 : "dbls %0,%l1\n\tjls %l2",
1473 /* If the decrement is to be done in SImode, then we have
1474 to compensate for the fact that dbcc decrements in HImode. */
1475 switch (GET_MODE (operands
[0]))
1478 output_asm_insn (MOTOROLA
1479 ? "clr%.w %0\n\tsubq%.l #1,%0\n\tjbpl %l1"
1480 : "clr%.w %0\n\tsubq%.l #1,%0\n\tjpl %l1",
1493 output_scc_di (rtx op
, rtx operand1
, rtx operand2
, rtx dest
)
1496 enum rtx_code op_code
= GET_CODE (op
);
1498 /* This does not produce a useful cc. */
1501 /* The m68k cmp.l instruction requires operand1 to be a reg as used
1502 below. Swap the operands and change the op if these requirements
1503 are not fulfilled. */
1504 if (GET_CODE (operand2
) == REG
&& GET_CODE (operand1
) != REG
)
1508 operand1
= operand2
;
1510 op_code
= swap_condition (op_code
);
1512 loperands
[0] = operand1
;
1513 if (GET_CODE (operand1
) == REG
)
1514 loperands
[1] = gen_rtx_REG (SImode
, REGNO (operand1
) + 1);
1516 loperands
[1] = adjust_address (operand1
, SImode
, 4);
1517 if (operand2
!= const0_rtx
)
1519 loperands
[2] = operand2
;
1520 if (GET_CODE (operand2
) == REG
)
1521 loperands
[3] = gen_rtx_REG (SImode
, REGNO (operand2
) + 1);
1523 loperands
[3] = adjust_address (operand2
, SImode
, 4);
1525 loperands
[4] = gen_label_rtx ();
1526 if (operand2
!= const0_rtx
)
1528 output_asm_insn (MOTOROLA
1529 ? "cmp%.l %2,%0\n\tjbne %l4\n\tcmp%.l %3,%1"
1530 : "cmp%.l %2,%0\n\tjne %l4\n\tcmp%.l %3,%1",
1535 if (TARGET_68020
|| TARGET_COLDFIRE
|| ! ADDRESS_REG_P (loperands
[0]))
1536 output_asm_insn ("tst%.l %0", loperands
);
1538 output_asm_insn ("cmp%.w #0,%0", loperands
);
1540 output_asm_insn (MOTOROLA
? "jbne %l4" : "jne %l4", loperands
);
1542 if (TARGET_68020
|| TARGET_COLDFIRE
|| ! ADDRESS_REG_P (loperands
[1]))
1543 output_asm_insn ("tst%.l %1", loperands
);
1545 output_asm_insn ("cmp%.w #0,%1", loperands
);
1548 loperands
[5] = dest
;
1553 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1554 CODE_LABEL_NUMBER (loperands
[4]));
1555 output_asm_insn ("seq %5", loperands
);
1559 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1560 CODE_LABEL_NUMBER (loperands
[4]));
1561 output_asm_insn ("sne %5", loperands
);
1565 loperands
[6] = gen_label_rtx ();
1566 output_asm_insn (MOTOROLA
? "shi %5\n\tjbra %l6" : "shi %5\n\tjra %l6",
1568 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1569 CODE_LABEL_NUMBER (loperands
[4]));
1570 output_asm_insn ("sgt %5", loperands
);
1571 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1572 CODE_LABEL_NUMBER (loperands
[6]));
1576 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1577 CODE_LABEL_NUMBER (loperands
[4]));
1578 output_asm_insn ("shi %5", loperands
);
1582 loperands
[6] = gen_label_rtx ();
1583 output_asm_insn (MOTOROLA
? "scs %5\n\tjbra %l6" : "scs %5\n\tjra %l6",
1585 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1586 CODE_LABEL_NUMBER (loperands
[4]));
1587 output_asm_insn ("slt %5", loperands
);
1588 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1589 CODE_LABEL_NUMBER (loperands
[6]));
1593 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1594 CODE_LABEL_NUMBER (loperands
[4]));
1595 output_asm_insn ("scs %5", loperands
);
1599 loperands
[6] = gen_label_rtx ();
1600 output_asm_insn (MOTOROLA
? "scc %5\n\tjbra %l6" : "scc %5\n\tjra %l6",
1602 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1603 CODE_LABEL_NUMBER (loperands
[4]));
1604 output_asm_insn ("sge %5", loperands
);
1605 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1606 CODE_LABEL_NUMBER (loperands
[6]));
1610 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1611 CODE_LABEL_NUMBER (loperands
[4]));
1612 output_asm_insn ("scc %5", loperands
);
1616 loperands
[6] = gen_label_rtx ();
1617 output_asm_insn (MOTOROLA
? "sls %5\n\tjbra %l6" : "sls %5\n\tjra %l6",
1619 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1620 CODE_LABEL_NUMBER (loperands
[4]));
1621 output_asm_insn ("sle %5", loperands
);
1622 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1623 CODE_LABEL_NUMBER (loperands
[6]));
1627 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
1628 CODE_LABEL_NUMBER (loperands
[4]));
1629 output_asm_insn ("sls %5", loperands
);
1639 output_btst (rtx
*operands
, rtx countop
, rtx dataop
, rtx insn
, int signpos
)
1641 operands
[0] = countop
;
1642 operands
[1] = dataop
;
1644 if (GET_CODE (countop
) == CONST_INT
)
1646 register int count
= INTVAL (countop
);
1647 /* If COUNT is bigger than size of storage unit in use,
1648 advance to the containing unit of same size. */
1649 if (count
> signpos
)
1651 int offset
= (count
& ~signpos
) / 8;
1652 count
= count
& signpos
;
1653 operands
[1] = dataop
= adjust_address (dataop
, QImode
, offset
);
1655 if (count
== signpos
)
1656 cc_status
.flags
= CC_NOT_POSITIVE
| CC_Z_IN_NOT_N
;
1658 cc_status
.flags
= CC_NOT_NEGATIVE
| CC_Z_IN_NOT_N
;
1660 /* These three statements used to use next_insns_test_no...
1661 but it appears that this should do the same job. */
1663 && next_insn_tests_no_inequality (insn
))
1666 && next_insn_tests_no_inequality (insn
))
1669 && next_insn_tests_no_inequality (insn
))
1672 cc_status
.flags
= CC_NOT_NEGATIVE
;
1674 return "btst %0,%1";
1677 /* Legitimize PIC addresses. If the address is already
1678 position-independent, we return ORIG. Newly generated
1679 position-independent addresses go to REG. If we need more
1680 than one register, we lose.
1682 An address is legitimized by making an indirect reference
1683 through the Global Offset Table with the name of the symbol
1686 The assembler and linker are responsible for placing the
1687 address of the symbol in the GOT. The function prologue
1688 is responsible for initializing a5 to the starting address
1691 The assembler is also responsible for translating a symbol name
1692 into a constant displacement from the start of the GOT.
1694 A quick example may make things a little clearer:
1696 When not generating PIC code to store the value 12345 into _foo
1697 we would generate the following code:
1701 When generating PIC two transformations are made. First, the compiler
1702 loads the address of foo into a register. So the first transformation makes:
1707 The code in movsi will intercept the lea instruction and call this
1708 routine which will transform the instructions into:
1710 movel a5@(_foo:w), a0
1714 That (in a nutshell) is how *all* symbol and label references are
1718 legitimize_pic_address (rtx orig
, enum machine_mode mode ATTRIBUTE_UNUSED
,
1723 /* First handle a simple SYMBOL_REF or LABEL_REF */
1724 if (GET_CODE (orig
) == SYMBOL_REF
|| GET_CODE (orig
) == LABEL_REF
)
1728 pic_ref
= gen_rtx_MEM (Pmode
,
1729 gen_rtx_PLUS (Pmode
,
1730 pic_offset_table_rtx
, orig
));
1731 current_function_uses_pic_offset_table
= 1;
1732 MEM_READONLY_P (pic_ref
) = 1;
1733 emit_move_insn (reg
, pic_ref
);
1736 else if (GET_CODE (orig
) == CONST
)
1740 /* Make sure this has not already been legitimized. */
1741 if (GET_CODE (XEXP (orig
, 0)) == PLUS
1742 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
1747 /* legitimize both operands of the PLUS */
1748 gcc_assert (GET_CODE (XEXP (orig
, 0)) == PLUS
);
1750 base
= legitimize_pic_address (XEXP (XEXP (orig
, 0), 0), Pmode
, reg
);
1751 orig
= legitimize_pic_address (XEXP (XEXP (orig
, 0), 1), Pmode
,
1752 base
== reg
? 0 : reg
);
1754 if (GET_CODE (orig
) == CONST_INT
)
1755 return plus_constant (base
, INTVAL (orig
));
1756 pic_ref
= gen_rtx_PLUS (Pmode
, base
, orig
);
1757 /* Likewise, should we set special REG_NOTEs here? */
1763 typedef enum { MOVL
, SWAP
, NEGW
, NOTW
, NOTB
, MOVQ
, MVS
, MVZ
} CONST_METHOD
;
1765 static CONST_METHOD
const_method (rtx
);
1767 #define USE_MOVQ(i) ((unsigned) ((i) + 128) <= 255)
1770 const_method (rtx constant
)
1775 i
= INTVAL (constant
);
1779 /* The ColdFire doesn't have byte or word operations. */
1780 /* FIXME: This may not be useful for the m68060 either. */
1781 if (!TARGET_COLDFIRE
)
1783 /* if -256 < N < 256 but N is not in range for a moveq
1784 N^ff will be, so use moveq #N^ff, dreg; not.b dreg. */
1785 if (USE_MOVQ (i
^ 0xff))
1787 /* Likewise, try with not.w */
1788 if (USE_MOVQ (i
^ 0xffff))
1790 /* This is the only value where neg.w is useful */
1795 /* Try also with swap. */
1797 if (USE_MOVQ ((u
>> 16) | (u
<< 16)))
1802 /* Try using MVZ/MVS with an immediate value to load constants. */
1803 if (i
>= 0 && i
<= 65535)
1805 if (i
>= -32768 && i
<= 32767)
1809 /* Otherwise, use move.l */
1814 const_int_cost (rtx constant
)
1816 switch (const_method (constant
))
1819 /* Constants between -128 and 127 are cheap due to moveq. */
1827 /* Constants easily generated by moveq + not.b/not.w/neg.w/swap. */
1837 m68k_rtx_costs (rtx x
, int code
, int outer_code
, int *total
)
1842 /* Constant zero is super cheap due to clr instruction. */
1843 if (x
== const0_rtx
)
1846 *total
= const_int_cost (x
);
1856 /* Make 0.0 cheaper than other floating constants to
1857 encourage creating tstsf and tstdf insns. */
1858 if (outer_code
== COMPARE
1859 && (x
== CONST0_RTX (SFmode
) || x
== CONST0_RTX (DFmode
)))
1865 /* These are vaguely right for a 68020. */
1866 /* The costs for long multiply have been adjusted to work properly
1867 in synth_mult on the 68020, relative to an average of the time
1868 for add and the time for shift, taking away a little more because
1869 sometimes move insns are needed. */
1870 /* div?.w is relatively cheaper on 68000 counted in COSTS_N_INSNS
1876 : TARGET_COLDFIRE ? 3 : 13)
1881 : TUNE_68000_10 || TUNE_CFV2 ? 5 \
1882 : TARGET_COLDFIRE ? 2 : 8)
1885 (TARGET_CF_HWDIV ? 11 \
1886 : TUNE_68000_10 || TARGET_COLDFIRE ? 12 : 27)
1889 /* An lea costs about three times as much as a simple add. */
1890 if (GET_MODE (x
) == SImode
1891 && GET_CODE (XEXP (x
, 1)) == REG
1892 && GET_CODE (XEXP (x
, 0)) == MULT
1893 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
1894 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
1895 && (INTVAL (XEXP (XEXP (x
, 0), 1)) == 2
1896 || INTVAL (XEXP (XEXP (x
, 0), 1)) == 4
1897 || INTVAL (XEXP (XEXP (x
, 0), 1)) == 8))
1899 /* lea an@(dx:l:i),am */
1900 *total
= COSTS_N_INSNS (TARGET_COLDFIRE
? 2 : 3);
1910 *total
= COSTS_N_INSNS(1);
1915 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
1917 if (INTVAL (XEXP (x
, 1)) < 16)
1918 *total
= COSTS_N_INSNS (2) + INTVAL (XEXP (x
, 1)) / 2;
1920 /* We're using clrw + swap for these cases. */
1921 *total
= COSTS_N_INSNS (4) + (INTVAL (XEXP (x
, 1)) - 16) / 2;
1924 *total
= COSTS_N_INSNS (10); /* Worst case. */
1927 /* A shift by a big integer takes an extra instruction. */
1928 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
1929 && (INTVAL (XEXP (x
, 1)) == 16))
1931 *total
= COSTS_N_INSNS (2); /* clrw;swap */
1934 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
1935 && !(INTVAL (XEXP (x
, 1)) > 0
1936 && INTVAL (XEXP (x
, 1)) <= 8))
1938 *total
= COSTS_N_INSNS (TARGET_COLDFIRE
? 1 : 3); /* lsr #i,dn */
1944 if ((GET_CODE (XEXP (x
, 0)) == ZERO_EXTEND
1945 || GET_CODE (XEXP (x
, 0)) == SIGN_EXTEND
)
1946 && GET_MODE (x
) == SImode
)
1947 *total
= COSTS_N_INSNS (MULW_COST
);
1948 else if (GET_MODE (x
) == QImode
|| GET_MODE (x
) == HImode
)
1949 *total
= COSTS_N_INSNS (MULW_COST
);
1951 *total
= COSTS_N_INSNS (MULL_COST
);
1958 if (GET_MODE (x
) == QImode
|| GET_MODE (x
) == HImode
)
1959 *total
= COSTS_N_INSNS (DIVW_COST
); /* div.w */
1960 else if (TARGET_CF_HWDIV
)
1961 *total
= COSTS_N_INSNS (18);
1963 *total
= COSTS_N_INSNS (43); /* div.l */
1972 output_move_const_into_data_reg (rtx
*operands
)
1976 i
= INTVAL (operands
[1]);
1977 switch (const_method (operands
[1]))
1980 return "mvzw %1,%0";
1982 return "mvsw %1,%0";
1984 return "moveq %1,%0";
1987 operands
[1] = GEN_INT (i
^ 0xff);
1988 return "moveq %1,%0\n\tnot%.b %0";
1991 operands
[1] = GEN_INT (i
^ 0xffff);
1992 return "moveq %1,%0\n\tnot%.w %0";
1995 return "moveq #-128,%0\n\tneg%.w %0";
2000 operands
[1] = GEN_INT ((u
<< 16) | (u
>> 16));
2001 return "moveq %1,%0\n\tswap %0";
2004 return "move%.l %1,%0";
2010 /* Return 1 if 'constant' can be represented by
2011 mov3q on a ColdFire V4 core. */
2013 valid_mov3q_const (rtx constant
)
2017 if (TARGET_ISAB
&& GET_CODE (constant
) == CONST_INT
)
2019 i
= INTVAL (constant
);
2020 if (i
== -1 || (i
>= 1 && i
<= 7))
2028 output_move_simode_const (rtx
*operands
)
2030 if (operands
[1] == const0_rtx
2031 && (DATA_REG_P (operands
[0])
2032 || GET_CODE (operands
[0]) == MEM
)
2033 /* clr insns on 68000 read before writing. */
2034 && ((TARGET_68010
|| TARGET_COLDFIRE
)
2035 || !(GET_CODE (operands
[0]) == MEM
2036 && MEM_VOLATILE_P (operands
[0]))))
2038 else if ((GET_MODE (operands
[0]) == SImode
)
2039 && valid_mov3q_const (operands
[1]))
2040 return "mov3q%.l %1,%0";
2041 else if (operands
[1] == const0_rtx
2042 && ADDRESS_REG_P (operands
[0]))
2043 return "sub%.l %0,%0";
2044 else if (DATA_REG_P (operands
[0]))
2045 return output_move_const_into_data_reg (operands
);
2046 else if (ADDRESS_REG_P (operands
[0])
2047 && INTVAL (operands
[1]) < 0x8000
2048 && INTVAL (operands
[1]) >= -0x8000)
2050 if (valid_mov3q_const (operands
[1]))
2051 return "mov3q%.l %1,%0";
2052 return "move%.w %1,%0";
2054 else if (GET_CODE (operands
[0]) == MEM
2055 && GET_CODE (XEXP (operands
[0], 0)) == PRE_DEC
2056 && REGNO (XEXP (XEXP (operands
[0], 0), 0)) == STACK_POINTER_REGNUM
2057 && INTVAL (operands
[1]) < 0x8000
2058 && INTVAL (operands
[1]) >= -0x8000)
2060 if (valid_mov3q_const (operands
[1]))
2061 return "mov3q%.l %1,%-";
2064 return "move%.l %1,%0";
2068 output_move_simode (rtx
*operands
)
2070 if (GET_CODE (operands
[1]) == CONST_INT
)
2071 return output_move_simode_const (operands
);
2072 else if ((GET_CODE (operands
[1]) == SYMBOL_REF
2073 || GET_CODE (operands
[1]) == CONST
)
2074 && push_operand (operands
[0], SImode
))
2076 else if ((GET_CODE (operands
[1]) == SYMBOL_REF
2077 || GET_CODE (operands
[1]) == CONST
)
2078 && ADDRESS_REG_P (operands
[0]))
2079 return "lea %a1,%0";
2080 return "move%.l %1,%0";
2084 output_move_himode (rtx
*operands
)
2086 if (GET_CODE (operands
[1]) == CONST_INT
)
2088 if (operands
[1] == const0_rtx
2089 && (DATA_REG_P (operands
[0])
2090 || GET_CODE (operands
[0]) == MEM
)
2091 /* clr insns on 68000 read before writing. */
2092 && ((TARGET_68010
|| TARGET_COLDFIRE
)
2093 || !(GET_CODE (operands
[0]) == MEM
2094 && MEM_VOLATILE_P (operands
[0]))))
2096 else if (operands
[1] == const0_rtx
2097 && ADDRESS_REG_P (operands
[0]))
2098 return "sub%.l %0,%0";
2099 else if (DATA_REG_P (operands
[0])
2100 && INTVAL (operands
[1]) < 128
2101 && INTVAL (operands
[1]) >= -128)
2102 return "moveq %1,%0";
2103 else if (INTVAL (operands
[1]) < 0x8000
2104 && INTVAL (operands
[1]) >= -0x8000)
2105 return "move%.w %1,%0";
2107 else if (CONSTANT_P (operands
[1]))
2108 return "move%.l %1,%0";
2109 /* Recognize the insn before a tablejump, one that refers
2110 to a table of offsets. Such an insn will need to refer
2111 to a label on the insn. So output one. Use the label-number
2112 of the table of offsets to generate this label. This code,
2113 and similar code below, assumes that there will be at most one
2114 reference to each table. */
2115 if (GET_CODE (operands
[1]) == MEM
2116 && GET_CODE (XEXP (operands
[1], 0)) == PLUS
2117 && GET_CODE (XEXP (XEXP (operands
[1], 0), 1)) == LABEL_REF
2118 && GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) != PLUS
)
2120 rtx labelref
= XEXP (XEXP (operands
[1], 0), 1);
2122 asm_fprintf (asm_out_file
, "\t.set %LLI%d,.+2\n",
2123 CODE_LABEL_NUMBER (XEXP (labelref
, 0)));
2125 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "LI",
2126 CODE_LABEL_NUMBER (XEXP (labelref
, 0)));
2128 return "move%.w %1,%0";
2132 output_move_qimode (rtx
*operands
)
2134 /* 68k family always modifies the stack pointer by at least 2, even for
2135 byte pushes. The 5200 (ColdFire) does not do this. */
2137 /* This case is generated by pushqi1 pattern now. */
2138 gcc_assert (!(GET_CODE (operands
[0]) == MEM
2139 && GET_CODE (XEXP (operands
[0], 0)) == PRE_DEC
2140 && XEXP (XEXP (operands
[0], 0), 0) == stack_pointer_rtx
2141 && ! ADDRESS_REG_P (operands
[1])
2142 && ! TARGET_COLDFIRE
));
2144 /* clr and st insns on 68000 read before writing. */
2145 if (!ADDRESS_REG_P (operands
[0])
2146 && ((TARGET_68010
|| TARGET_COLDFIRE
)
2147 || !(GET_CODE (operands
[0]) == MEM
&& MEM_VOLATILE_P (operands
[0]))))
2149 if (operands
[1] == const0_rtx
)
2151 if ((!TARGET_COLDFIRE
|| DATA_REG_P (operands
[0]))
2152 && GET_CODE (operands
[1]) == CONST_INT
2153 && (INTVAL (operands
[1]) & 255) == 255)
2159 if (GET_CODE (operands
[1]) == CONST_INT
2160 && DATA_REG_P (operands
[0])
2161 && INTVAL (operands
[1]) < 128
2162 && INTVAL (operands
[1]) >= -128)
2163 return "moveq %1,%0";
2164 if (operands
[1] == const0_rtx
&& ADDRESS_REG_P (operands
[0]))
2165 return "sub%.l %0,%0";
2166 if (GET_CODE (operands
[1]) != CONST_INT
&& CONSTANT_P (operands
[1]))
2167 return "move%.l %1,%0";
2168 /* 68k family (including the 5200 ColdFire) does not support byte moves to
2169 from address registers. */
2170 if (ADDRESS_REG_P (operands
[0]) || ADDRESS_REG_P (operands
[1]))
2171 return "move%.w %1,%0";
2172 return "move%.b %1,%0";
2176 output_move_stricthi (rtx
*operands
)
2178 if (operands
[1] == const0_rtx
2179 /* clr insns on 68000 read before writing. */
2180 && ((TARGET_68010
|| TARGET_COLDFIRE
)
2181 || !(GET_CODE (operands
[0]) == MEM
&& MEM_VOLATILE_P (operands
[0]))))
2183 return "move%.w %1,%0";
2187 output_move_strictqi (rtx
*operands
)
2189 if (operands
[1] == const0_rtx
2190 /* clr insns on 68000 read before writing. */
2191 && ((TARGET_68010
|| TARGET_COLDFIRE
)
2192 || !(GET_CODE (operands
[0]) == MEM
&& MEM_VOLATILE_P (operands
[0]))))
2194 return "move%.b %1,%0";
2197 /* Return the best assembler insn template
2198 for moving operands[1] into operands[0] as a fullword. */
2201 singlemove_string (rtx
*operands
)
2203 if (GET_CODE (operands
[1]) == CONST_INT
)
2204 return output_move_simode_const (operands
);
2205 return "move%.l %1,%0";
2209 /* Output assembler code to perform a doubleword move insn
2210 with operands OPERANDS. */
2213 output_move_double (rtx
*operands
)
2217 REGOP
, OFFSOP
, MEMOP
, PUSHOP
, POPOP
, CNSTOP
, RNDOP
2222 rtx addreg0
= 0, addreg1
= 0;
2223 int dest_overlapped_low
= 0;
2224 int size
= GET_MODE_SIZE (GET_MODE (operands
[0]));
2229 /* First classify both operands. */
2231 if (REG_P (operands
[0]))
2233 else if (offsettable_memref_p (operands
[0]))
2235 else if (GET_CODE (XEXP (operands
[0], 0)) == POST_INC
)
2237 else if (GET_CODE (XEXP (operands
[0], 0)) == PRE_DEC
)
2239 else if (GET_CODE (operands
[0]) == MEM
)
2244 if (REG_P (operands
[1]))
2246 else if (CONSTANT_P (operands
[1]))
2248 else if (offsettable_memref_p (operands
[1]))
2250 else if (GET_CODE (XEXP (operands
[1], 0)) == POST_INC
)
2252 else if (GET_CODE (XEXP (operands
[1], 0)) == PRE_DEC
)
2254 else if (GET_CODE (operands
[1]) == MEM
)
2259 /* Check for the cases that the operand constraints are not supposed
2260 to allow to happen. Generating code for these cases is
2262 gcc_assert (optype0
!= RNDOP
&& optype1
!= RNDOP
);
2264 /* If one operand is decrementing and one is incrementing
2265 decrement the former register explicitly
2266 and change that operand into ordinary indexing. */
2268 if (optype0
== PUSHOP
&& optype1
== POPOP
)
2270 operands
[0] = XEXP (XEXP (operands
[0], 0), 0);
2272 output_asm_insn ("sub%.l #12,%0", operands
);
2274 output_asm_insn ("subq%.l #8,%0", operands
);
2275 if (GET_MODE (operands
[1]) == XFmode
)
2276 operands
[0] = gen_rtx_MEM (XFmode
, operands
[0]);
2277 else if (GET_MODE (operands
[0]) == DFmode
)
2278 operands
[0] = gen_rtx_MEM (DFmode
, operands
[0]);
2280 operands
[0] = gen_rtx_MEM (DImode
, operands
[0]);
2283 if (optype0
== POPOP
&& optype1
== PUSHOP
)
2285 operands
[1] = XEXP (XEXP (operands
[1], 0), 0);
2287 output_asm_insn ("sub%.l #12,%1", operands
);
2289 output_asm_insn ("subq%.l #8,%1", operands
);
2290 if (GET_MODE (operands
[1]) == XFmode
)
2291 operands
[1] = gen_rtx_MEM (XFmode
, operands
[1]);
2292 else if (GET_MODE (operands
[1]) == DFmode
)
2293 operands
[1] = gen_rtx_MEM (DFmode
, operands
[1]);
2295 operands
[1] = gen_rtx_MEM (DImode
, operands
[1]);
2299 /* If an operand is an unoffsettable memory ref, find a register
2300 we can increment temporarily to make it refer to the second word. */
2302 if (optype0
== MEMOP
)
2303 addreg0
= find_addr_reg (XEXP (operands
[0], 0));
2305 if (optype1
== MEMOP
)
2306 addreg1
= find_addr_reg (XEXP (operands
[1], 0));
2308 /* Ok, we can do one word at a time.
2309 Normally we do the low-numbered word first,
2310 but if either operand is autodecrementing then we
2311 do the high-numbered word first.
2313 In either case, set up in LATEHALF the operands to use
2314 for the high-numbered word and in some cases alter the
2315 operands in OPERANDS to be suitable for the low-numbered word. */
2319 if (optype0
== REGOP
)
2321 latehalf
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 2);
2322 middlehalf
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 1);
2324 else if (optype0
== OFFSOP
)
2326 middlehalf
[0] = adjust_address (operands
[0], SImode
, 4);
2327 latehalf
[0] = adjust_address (operands
[0], SImode
, size
- 4);
2331 middlehalf
[0] = operands
[0];
2332 latehalf
[0] = operands
[0];
2335 if (optype1
== REGOP
)
2337 latehalf
[1] = gen_rtx_REG (SImode
, REGNO (operands
[1]) + 2);
2338 middlehalf
[1] = gen_rtx_REG (SImode
, REGNO (operands
[1]) + 1);
2340 else if (optype1
== OFFSOP
)
2342 middlehalf
[1] = adjust_address (operands
[1], SImode
, 4);
2343 latehalf
[1] = adjust_address (operands
[1], SImode
, size
- 4);
2345 else if (optype1
== CNSTOP
)
2347 if (GET_CODE (operands
[1]) == CONST_DOUBLE
)
2352 REAL_VALUE_FROM_CONST_DOUBLE (r
, operands
[1]);
2353 REAL_VALUE_TO_TARGET_LONG_DOUBLE (r
, l
);
2354 operands
[1] = GEN_INT (l
[0]);
2355 middlehalf
[1] = GEN_INT (l
[1]);
2356 latehalf
[1] = GEN_INT (l
[2]);
2360 /* No non-CONST_DOUBLE constant should ever appear
2362 gcc_assert (!CONSTANT_P (operands
[1]));
2367 middlehalf
[1] = operands
[1];
2368 latehalf
[1] = operands
[1];
2372 /* size is not 12: */
2374 if (optype0
== REGOP
)
2375 latehalf
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 1);
2376 else if (optype0
== OFFSOP
)
2377 latehalf
[0] = adjust_address (operands
[0], SImode
, size
- 4);
2379 latehalf
[0] = operands
[0];
2381 if (optype1
== REGOP
)
2382 latehalf
[1] = gen_rtx_REG (SImode
, REGNO (operands
[1]) + 1);
2383 else if (optype1
== OFFSOP
)
2384 latehalf
[1] = adjust_address (operands
[1], SImode
, size
- 4);
2385 else if (optype1
== CNSTOP
)
2386 split_double (operands
[1], &operands
[1], &latehalf
[1]);
2388 latehalf
[1] = operands
[1];
2391 /* If insn is effectively movd N(sp),-(sp) then we will do the
2392 high word first. We should use the adjusted operand 1 (which is N+4(sp))
2393 for the low word as well, to compensate for the first decrement of sp. */
2394 if (optype0
== PUSHOP
2395 && REGNO (XEXP (XEXP (operands
[0], 0), 0)) == STACK_POINTER_REGNUM
2396 && reg_overlap_mentioned_p (stack_pointer_rtx
, operands
[1]))
2397 operands
[1] = middlehalf
[1] = latehalf
[1];
2399 /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)),
2400 if the upper part of reg N does not appear in the MEM, arrange to
2401 emit the move late-half first. Otherwise, compute the MEM address
2402 into the upper part of N and use that as a pointer to the memory
2404 if (optype0
== REGOP
2405 && (optype1
== OFFSOP
|| optype1
== MEMOP
))
2407 rtx testlow
= gen_rtx_REG (SImode
, REGNO (operands
[0]));
2409 if (reg_overlap_mentioned_p (testlow
, XEXP (operands
[1], 0))
2410 && reg_overlap_mentioned_p (latehalf
[0], XEXP (operands
[1], 0)))
2412 /* If both halves of dest are used in the src memory address,
2413 compute the address into latehalf of dest.
2414 Note that this can't happen if the dest is two data regs. */
2416 xops
[0] = latehalf
[0];
2417 xops
[1] = XEXP (operands
[1], 0);
2418 output_asm_insn ("lea %a1,%0", xops
);
2419 if (GET_MODE (operands
[1]) == XFmode
)
2421 operands
[1] = gen_rtx_MEM (XFmode
, latehalf
[0]);
2422 middlehalf
[1] = adjust_address (operands
[1], DImode
, size
- 8);
2423 latehalf
[1] = adjust_address (operands
[1], DImode
, size
- 4);
2427 operands
[1] = gen_rtx_MEM (DImode
, latehalf
[0]);
2428 latehalf
[1] = adjust_address (operands
[1], DImode
, size
- 4);
2432 && reg_overlap_mentioned_p (middlehalf
[0],
2433 XEXP (operands
[1], 0)))
2435 /* Check for two regs used by both source and dest.
2436 Note that this can't happen if the dest is all data regs.
2437 It can happen if the dest is d6, d7, a0.
2438 But in that case, latehalf is an addr reg, so
2439 the code at compadr does ok. */
2441 if (reg_overlap_mentioned_p (testlow
, XEXP (operands
[1], 0))
2442 || reg_overlap_mentioned_p (latehalf
[0], XEXP (operands
[1], 0)))
2445 /* JRV says this can't happen: */
2446 gcc_assert (!addreg0
&& !addreg1
);
2448 /* Only the middle reg conflicts; simply put it last. */
2449 output_asm_insn (singlemove_string (operands
), operands
);
2450 output_asm_insn (singlemove_string (latehalf
), latehalf
);
2451 output_asm_insn (singlemove_string (middlehalf
), middlehalf
);
2454 else if (reg_overlap_mentioned_p (testlow
, XEXP (operands
[1], 0)))
2455 /* If the low half of dest is mentioned in the source memory
2456 address, the arrange to emit the move late half first. */
2457 dest_overlapped_low
= 1;
2460 /* If one or both operands autodecrementing,
2461 do the two words, high-numbered first. */
2463 /* Likewise, the first move would clobber the source of the second one,
2464 do them in the other order. This happens only for registers;
2465 such overlap can't happen in memory unless the user explicitly
2466 sets it up, and that is an undefined circumstance. */
2468 if (optype0
== PUSHOP
|| optype1
== PUSHOP
2469 || (optype0
== REGOP
&& optype1
== REGOP
2470 && ((middlehalf
[1] && REGNO (operands
[0]) == REGNO (middlehalf
[1]))
2471 || REGNO (operands
[0]) == REGNO (latehalf
[1])))
2472 || dest_overlapped_low
)
2474 /* Make any unoffsettable addresses point at high-numbered word. */
2478 output_asm_insn ("addq%.l #8,%0", &addreg0
);
2480 output_asm_insn ("addq%.l #4,%0", &addreg0
);
2485 output_asm_insn ("addq%.l #8,%0", &addreg1
);
2487 output_asm_insn ("addq%.l #4,%0", &addreg1
);
2491 output_asm_insn (singlemove_string (latehalf
), latehalf
);
2493 /* Undo the adds we just did. */
2495 output_asm_insn ("subq%.l #4,%0", &addreg0
);
2497 output_asm_insn ("subq%.l #4,%0", &addreg1
);
2501 output_asm_insn (singlemove_string (middlehalf
), middlehalf
);
2503 output_asm_insn ("subq%.l #4,%0", &addreg0
);
2505 output_asm_insn ("subq%.l #4,%0", &addreg1
);
2508 /* Do low-numbered word. */
2509 return singlemove_string (operands
);
2512 /* Normal case: do the two words, low-numbered first. */
2514 output_asm_insn (singlemove_string (operands
), operands
);
2516 /* Do the middle one of the three words for long double */
2520 output_asm_insn ("addq%.l #4,%0", &addreg0
);
2522 output_asm_insn ("addq%.l #4,%0", &addreg1
);
2524 output_asm_insn (singlemove_string (middlehalf
), middlehalf
);
2527 /* Make any unoffsettable addresses point at high-numbered word. */
2529 output_asm_insn ("addq%.l #4,%0", &addreg0
);
2531 output_asm_insn ("addq%.l #4,%0", &addreg1
);
2534 output_asm_insn (singlemove_string (latehalf
), latehalf
);
2536 /* Undo the adds we just did. */
2540 output_asm_insn ("subq%.l #8,%0", &addreg0
);
2542 output_asm_insn ("subq%.l #4,%0", &addreg0
);
2547 output_asm_insn ("subq%.l #8,%0", &addreg1
);
2549 output_asm_insn ("subq%.l #4,%0", &addreg1
);
2556 /* Ensure mode of ORIG, a REG rtx, is MODE. Returns either ORIG or a
2557 new rtx with the correct mode. */
2560 force_mode (enum machine_mode mode
, rtx orig
)
2562 if (mode
== GET_MODE (orig
))
2565 if (REGNO (orig
) >= FIRST_PSEUDO_REGISTER
)
2568 return gen_rtx_REG (mode
, REGNO (orig
));
2572 fp_reg_operand (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
2574 return reg_renumber
&& FP_REG_P (op
);
2577 /* Emit insns to move operands[1] into operands[0].
2579 Return 1 if we have written out everything that needs to be done to
2580 do the move. Otherwise, return 0 and the caller will emit the move
2583 Note SCRATCH_REG may not be in the proper mode depending on how it
2584 will be used. This routine is responsible for creating a new copy
2585 of SCRATCH_REG in the proper mode. */
2588 emit_move_sequence (rtx
*operands
, enum machine_mode mode
, rtx scratch_reg
)
2590 register rtx operand0
= operands
[0];
2591 register rtx operand1
= operands
[1];
2595 && reload_in_progress
&& GET_CODE (operand0
) == REG
2596 && REGNO (operand0
) >= FIRST_PSEUDO_REGISTER
)
2597 operand0
= reg_equiv_mem
[REGNO (operand0
)];
2598 else if (scratch_reg
2599 && reload_in_progress
&& GET_CODE (operand0
) == SUBREG
2600 && GET_CODE (SUBREG_REG (operand0
)) == REG
2601 && REGNO (SUBREG_REG (operand0
)) >= FIRST_PSEUDO_REGISTER
)
2603 /* We must not alter SUBREG_BYTE (operand0) since that would confuse
2604 the code which tracks sets/uses for delete_output_reload. */
2605 rtx temp
= gen_rtx_SUBREG (GET_MODE (operand0
),
2606 reg_equiv_mem
[REGNO (SUBREG_REG (operand0
))],
2607 SUBREG_BYTE (operand0
));
2608 operand0
= alter_subreg (&temp
);
2612 && reload_in_progress
&& GET_CODE (operand1
) == REG
2613 && REGNO (operand1
) >= FIRST_PSEUDO_REGISTER
)
2614 operand1
= reg_equiv_mem
[REGNO (operand1
)];
2615 else if (scratch_reg
2616 && reload_in_progress
&& GET_CODE (operand1
) == SUBREG
2617 && GET_CODE (SUBREG_REG (operand1
)) == REG
2618 && REGNO (SUBREG_REG (operand1
)) >= FIRST_PSEUDO_REGISTER
)
2620 /* We must not alter SUBREG_BYTE (operand0) since that would confuse
2621 the code which tracks sets/uses for delete_output_reload. */
2622 rtx temp
= gen_rtx_SUBREG (GET_MODE (operand1
),
2623 reg_equiv_mem
[REGNO (SUBREG_REG (operand1
))],
2624 SUBREG_BYTE (operand1
));
2625 operand1
= alter_subreg (&temp
);
2628 if (scratch_reg
&& reload_in_progress
&& GET_CODE (operand0
) == MEM
2629 && ((tem
= find_replacement (&XEXP (operand0
, 0)))
2630 != XEXP (operand0
, 0)))
2631 operand0
= gen_rtx_MEM (GET_MODE (operand0
), tem
);
2632 if (scratch_reg
&& reload_in_progress
&& GET_CODE (operand1
) == MEM
2633 && ((tem
= find_replacement (&XEXP (operand1
, 0)))
2634 != XEXP (operand1
, 0)))
2635 operand1
= gen_rtx_MEM (GET_MODE (operand1
), tem
);
2637 /* Handle secondary reloads for loads/stores of FP registers where
2638 the address is symbolic by using the scratch register */
2639 if (fp_reg_operand (operand0
, mode
)
2640 && ((GET_CODE (operand1
) == MEM
2641 && ! memory_address_p (DFmode
, XEXP (operand1
, 0)))
2642 || ((GET_CODE (operand1
) == SUBREG
2643 && GET_CODE (XEXP (operand1
, 0)) == MEM
2644 && !memory_address_p (DFmode
, XEXP (XEXP (operand1
, 0), 0)))))
2647 if (GET_CODE (operand1
) == SUBREG
)
2648 operand1
= XEXP (operand1
, 0);
2650 /* SCRATCH_REG will hold an address. We want
2651 it in SImode regardless of what mode it was originally given
2653 scratch_reg
= force_mode (SImode
, scratch_reg
);
2655 /* D might not fit in 14 bits either; for such cases load D into
2657 if (!memory_address_p (Pmode
, XEXP (operand1
, 0)))
2659 emit_move_insn (scratch_reg
, XEXP (XEXP (operand1
, 0), 1));
2660 emit_move_insn (scratch_reg
, gen_rtx_fmt_ee (GET_CODE (XEXP (operand1
, 0)),
2662 XEXP (XEXP (operand1
, 0), 0),
2666 emit_move_insn (scratch_reg
, XEXP (operand1
, 0));
2667 emit_insn (gen_rtx_SET (VOIDmode
, operand0
,
2668 gen_rtx_MEM (mode
, scratch_reg
)));
2671 else if (fp_reg_operand (operand1
, mode
)
2672 && ((GET_CODE (operand0
) == MEM
2673 && ! memory_address_p (DFmode
, XEXP (operand0
, 0)))
2674 || ((GET_CODE (operand0
) == SUBREG
)
2675 && GET_CODE (XEXP (operand0
, 0)) == MEM
2676 && !memory_address_p (DFmode
, XEXP (XEXP (operand0
, 0), 0))))
2679 if (GET_CODE (operand0
) == SUBREG
)
2680 operand0
= XEXP (operand0
, 0);
2682 /* SCRATCH_REG will hold an address and maybe the actual data. We want
2683 it in SIMODE regardless of what mode it was originally given
2685 scratch_reg
= force_mode (SImode
, scratch_reg
);
2687 /* D might not fit in 14 bits either; for such cases load D into
2689 if (!memory_address_p (Pmode
, XEXP (operand0
, 0)))
2691 emit_move_insn (scratch_reg
, XEXP (XEXP (operand0
, 0), 1));
2692 emit_move_insn (scratch_reg
, gen_rtx_fmt_ee (GET_CODE (XEXP (operand0
,
2695 XEXP (XEXP (operand0
, 0),
2700 emit_move_insn (scratch_reg
, XEXP (operand0
, 0));
2701 emit_insn (gen_rtx_SET (VOIDmode
, gen_rtx_MEM (mode
, scratch_reg
),
2705 /* Handle secondary reloads for loads of FP registers from constant
2706 expressions by forcing the constant into memory.
2708 use scratch_reg to hold the address of the memory location.
2710 The proper fix is to change PREFERRED_RELOAD_CLASS to return
2711 NO_REGS when presented with a const_int and an register class
2712 containing only FP registers. Doing so unfortunately creates
2713 more problems than it solves. Fix this for 2.5. */
2714 else if (fp_reg_operand (operand0
, mode
)
2715 && CONSTANT_P (operand1
)
2720 /* SCRATCH_REG will hold an address and maybe the actual data. We want
2721 it in SIMODE regardless of what mode it was originally given
2723 scratch_reg
= force_mode (SImode
, scratch_reg
);
2725 /* Force the constant into memory and put the address of the
2726 memory location into scratch_reg. */
2727 xoperands
[0] = scratch_reg
;
2728 xoperands
[1] = XEXP (force_const_mem (mode
, operand1
), 0);
2729 emit_insn (gen_rtx_SET (mode
, scratch_reg
, xoperands
[1]));
2731 /* Now load the destination register. */
2732 emit_insn (gen_rtx_SET (mode
, operand0
,
2733 gen_rtx_MEM (mode
, scratch_reg
)));
2737 /* Now have insn-emit do whatever it normally does. */
2741 /* Return a REG that occurs in ADDR with coefficient 1.
2742 ADDR can be effectively incremented by incrementing REG. */
2745 find_addr_reg (rtx addr
)
2747 while (GET_CODE (addr
) == PLUS
)
2749 if (GET_CODE (XEXP (addr
, 0)) == REG
)
2750 addr
= XEXP (addr
, 0);
2751 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
2752 addr
= XEXP (addr
, 1);
2753 else if (CONSTANT_P (XEXP (addr
, 0)))
2754 addr
= XEXP (addr
, 1);
2755 else if (CONSTANT_P (XEXP (addr
, 1)))
2756 addr
= XEXP (addr
, 0);
2760 gcc_assert (GET_CODE (addr
) == REG
);
2764 /* Output assembler code to perform a 32-bit 3-operand add. */
2767 output_addsi3 (rtx
*operands
)
2769 if (! operands_match_p (operands
[0], operands
[1]))
2771 if (!ADDRESS_REG_P (operands
[1]))
2773 rtx tmp
= operands
[1];
2775 operands
[1] = operands
[2];
2779 /* These insns can result from reloads to access
2780 stack slots over 64k from the frame pointer. */
2781 if (GET_CODE (operands
[2]) == CONST_INT
2782 && (INTVAL (operands
[2]) < -32768 || INTVAL (operands
[2]) > 32767))
2783 return "move%.l %2,%0\n\tadd%.l %1,%0";
2784 if (GET_CODE (operands
[2]) == REG
)
2785 return MOTOROLA
? "lea (%1,%2.l),%0" : "lea %1@(0,%2:l),%0";
2786 return MOTOROLA
? "lea (%c2,%1),%0" : "lea %1@(%c2),%0";
2788 if (GET_CODE (operands
[2]) == CONST_INT
)
2790 if (INTVAL (operands
[2]) > 0
2791 && INTVAL (operands
[2]) <= 8)
2792 return "addq%.l %2,%0";
2793 if (INTVAL (operands
[2]) < 0
2794 && INTVAL (operands
[2]) >= -8)
2796 operands
[2] = GEN_INT (- INTVAL (operands
[2]));
2797 return "subq%.l %2,%0";
2799 /* On the CPU32 it is faster to use two addql instructions to
2800 add a small integer (8 < N <= 16) to a register.
2801 Likewise for subql. */
2802 if (TUNE_CPU32
&& REG_P (operands
[0]))
2804 if (INTVAL (operands
[2]) > 8
2805 && INTVAL (operands
[2]) <= 16)
2807 operands
[2] = GEN_INT (INTVAL (operands
[2]) - 8);
2808 return "addq%.l #8,%0\n\taddq%.l %2,%0";
2810 if (INTVAL (operands
[2]) < -8
2811 && INTVAL (operands
[2]) >= -16)
2813 operands
[2] = GEN_INT (- INTVAL (operands
[2]) - 8);
2814 return "subq%.l #8,%0\n\tsubq%.l %2,%0";
2817 if (ADDRESS_REG_P (operands
[0])
2818 && INTVAL (operands
[2]) >= -0x8000
2819 && INTVAL (operands
[2]) < 0x8000)
2822 return "add%.w %2,%0";
2824 return MOTOROLA
? "lea (%c2,%0),%0" : "lea %0@(%c2),%0";
2827 return "add%.l %2,%0";
2830 /* Store in cc_status the expressions that the condition codes will
2831 describe after execution of an instruction whose pattern is EXP.
2832 Do not alter them if the instruction would not alter the cc's. */
2834 /* On the 68000, all the insns to store in an address register fail to
2835 set the cc's. However, in some cases these instructions can make it
2836 possibly invalid to use the saved cc's. In those cases we clear out
2837 some or all of the saved cc's so they won't be used. */
2840 notice_update_cc (rtx exp
, rtx insn
)
2842 if (GET_CODE (exp
) == SET
)
2844 if (GET_CODE (SET_SRC (exp
)) == CALL
)
2846 else if (ADDRESS_REG_P (SET_DEST (exp
)))
2848 if (cc_status
.value1
&& modified_in_p (cc_status
.value1
, insn
))
2849 cc_status
.value1
= 0;
2850 if (cc_status
.value2
&& modified_in_p (cc_status
.value2
, insn
))
2851 cc_status
.value2
= 0;
2853 else if (!FP_REG_P (SET_DEST (exp
))
2854 && SET_DEST (exp
) != cc0_rtx
2855 && (FP_REG_P (SET_SRC (exp
))
2856 || GET_CODE (SET_SRC (exp
)) == FIX
2857 || GET_CODE (SET_SRC (exp
)) == FLOAT_TRUNCATE
2858 || GET_CODE (SET_SRC (exp
)) == FLOAT_EXTEND
))
2860 /* A pair of move insns doesn't produce a useful overall cc. */
2861 else if (!FP_REG_P (SET_DEST (exp
))
2862 && !FP_REG_P (SET_SRC (exp
))
2863 && GET_MODE_SIZE (GET_MODE (SET_SRC (exp
))) > 4
2864 && (GET_CODE (SET_SRC (exp
)) == REG
2865 || GET_CODE (SET_SRC (exp
)) == MEM
2866 || GET_CODE (SET_SRC (exp
)) == CONST_DOUBLE
))
2868 else if (SET_DEST (exp
) != pc_rtx
)
2870 cc_status
.flags
= 0;
2871 cc_status
.value1
= SET_DEST (exp
);
2872 cc_status
.value2
= SET_SRC (exp
);
2875 else if (GET_CODE (exp
) == PARALLEL
2876 && GET_CODE (XVECEXP (exp
, 0, 0)) == SET
)
2878 rtx dest
= SET_DEST (XVECEXP (exp
, 0, 0));
2879 rtx src
= SET_SRC (XVECEXP (exp
, 0, 0));
2881 if (ADDRESS_REG_P (dest
))
2883 else if (dest
!= pc_rtx
)
2885 cc_status
.flags
= 0;
2886 cc_status
.value1
= dest
;
2887 cc_status
.value2
= src
;
2892 if (cc_status
.value2
!= 0
2893 && ADDRESS_REG_P (cc_status
.value2
)
2894 && GET_MODE (cc_status
.value2
) == QImode
)
2896 if (cc_status
.value2
!= 0)
2897 switch (GET_CODE (cc_status
.value2
))
2899 case ASHIFT
: case ASHIFTRT
: case LSHIFTRT
:
2900 case ROTATE
: case ROTATERT
:
2901 /* These instructions always clear the overflow bit, and set
2902 the carry to the bit shifted out. */
2903 /* ??? We don't currently have a way to signal carry not valid,
2904 nor do we check for it in the branch insns. */
2908 case PLUS
: case MINUS
: case MULT
:
2909 case DIV
: case UDIV
: case MOD
: case UMOD
: case NEG
:
2910 if (GET_MODE (cc_status
.value2
) != VOIDmode
)
2911 cc_status
.flags
|= CC_NO_OVERFLOW
;
2914 /* (SET r1 (ZERO_EXTEND r2)) on this machine
2915 ends with a move insn moving r2 in r2's mode.
2916 Thus, the cc's are set for r2.
2917 This can set N bit spuriously. */
2918 cc_status
.flags
|= CC_NOT_NEGATIVE
;
2923 if (cc_status
.value1
&& GET_CODE (cc_status
.value1
) == REG
2925 && reg_overlap_mentioned_p (cc_status
.value1
, cc_status
.value2
))
2926 cc_status
.value2
= 0;
2927 if (((cc_status
.value1
&& FP_REG_P (cc_status
.value1
))
2928 || (cc_status
.value2
&& FP_REG_P (cc_status
.value2
))))
2929 cc_status
.flags
= CC_IN_68881
;
2933 output_move_const_double (rtx
*operands
)
2935 int code
= standard_68881_constant_p (operands
[1]);
2939 static char buf
[40];
2941 sprintf (buf
, "fmovecr #0x%x,%%0", code
& 0xff);
2944 return "fmove%.d %1,%0";
2948 output_move_const_single (rtx
*operands
)
2950 int code
= standard_68881_constant_p (operands
[1]);
2954 static char buf
[40];
2956 sprintf (buf
, "fmovecr #0x%x,%%0", code
& 0xff);
2959 return "fmove%.s %f1,%0";
2962 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
2963 from the "fmovecr" instruction.
2964 The value, anded with 0xff, gives the code to use in fmovecr
2965 to get the desired constant. */
2967 /* This code has been fixed for cross-compilation. */
2969 static int inited_68881_table
= 0;
2971 static const char *const strings_68881
[7] = {
2981 static const int codes_68881
[7] = {
2991 REAL_VALUE_TYPE values_68881
[7];
2993 /* Set up values_68881 array by converting the decimal values
2994 strings_68881 to binary. */
2997 init_68881_table (void)
3001 enum machine_mode mode
;
3004 for (i
= 0; i
< 7; i
++)
3008 r
= REAL_VALUE_ATOF (strings_68881
[i
], mode
);
3009 values_68881
[i
] = r
;
3011 inited_68881_table
= 1;
3015 standard_68881_constant_p (rtx x
)
3020 /* fmovecr must be emulated on the 68040 and 68060, so it shouldn't be
3021 used at all on those chips. */
3025 if (! inited_68881_table
)
3026 init_68881_table ();
3028 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
3030 /* Use REAL_VALUES_IDENTICAL instead of REAL_VALUES_EQUAL so that -0.0
3032 for (i
= 0; i
< 6; i
++)
3034 if (REAL_VALUES_IDENTICAL (r
, values_68881
[i
]))
3035 return (codes_68881
[i
]);
3038 if (GET_MODE (x
) == SFmode
)
3041 if (REAL_VALUES_EQUAL (r
, values_68881
[6]))
3042 return (codes_68881
[6]);
3044 /* larger powers of ten in the constants ram are not used
3045 because they are not equal to a `double' C constant. */
3049 /* If X is a floating-point constant, return the logarithm of X base 2,
3050 or 0 if X is not a power of 2. */
3053 floating_exact_log2 (rtx x
)
3055 REAL_VALUE_TYPE r
, r1
;
3058 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
3060 if (REAL_VALUES_LESS (r
, dconst1
))
3063 exp
= real_exponent (&r
);
3064 real_2expN (&r1
, exp
);
3065 if (REAL_VALUES_EQUAL (r1
, r
))
3071 /* A C compound statement to output to stdio stream STREAM the
3072 assembler syntax for an instruction operand X. X is an RTL
3075 CODE is a value that can be used to specify one of several ways
3076 of printing the operand. It is used when identical operands
3077 must be printed differently depending on the context. CODE
3078 comes from the `%' specification that was used to request
3079 printing of the operand. If the specification was just `%DIGIT'
3080 then CODE is 0; if the specification was `%LTR DIGIT' then CODE
3081 is the ASCII code for LTR.
3083 If X is a register, this macro should print the register's name.
3084 The names can be found in an array `reg_names' whose type is
3085 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
3087 When the machine description has a specification `%PUNCT' (a `%'
3088 followed by a punctuation character), this macro is called with
3089 a null pointer for X and the punctuation character for CODE.
3091 The m68k specific codes are:
3093 '.' for dot needed in Motorola-style opcode names.
3094 '-' for an operand pushing on the stack:
3095 sp@-, -(sp) or -(%sp) depending on the style of syntax.
3096 '+' for an operand pushing on the stack:
3097 sp@+, (sp)+ or (%sp)+ depending on the style of syntax.
3098 '@' for a reference to the top word on the stack:
3099 sp@, (sp) or (%sp) depending on the style of syntax.
3100 '#' for an immediate operand prefix (# in MIT and Motorola syntax
3101 but & in SGS syntax).
3102 '!' for the cc register (used in an `and to cc' insn).
3103 '$' for the letter `s' in an op code, but only on the 68040.
3104 '&' for the letter `d' in an op code, but only on the 68040.
3105 '/' for register prefix needed by longlong.h.
3107 'b' for byte insn (no effect, on the Sun; this is for the ISI).
3108 'd' to force memory addressing to be absolute, not relative.
3109 'f' for float insn (print a CONST_DOUBLE as a float rather than in hex)
3110 'x' for float insn (print a CONST_DOUBLE as a float rather than in hex),
3111 or print pair of registers as rx:ry.
3112 'p' print an address with @PLTPC attached, but only if the operand
3113 is not locally-bound. */
3116 print_operand (FILE *file
, rtx op
, int letter
)
3121 fprintf (file
, ".");
3123 else if (letter
== '#')
3124 asm_fprintf (file
, "%I");
3125 else if (letter
== '-')
3126 asm_fprintf (file
, MOTOROLA
? "-(%Rsp)" : "%Rsp@-");
3127 else if (letter
== '+')
3128 asm_fprintf (file
, MOTOROLA
? "(%Rsp)+" : "%Rsp@+");
3129 else if (letter
== '@')
3130 asm_fprintf (file
, MOTOROLA
? "(%Rsp)" : "%Rsp@");
3131 else if (letter
== '!')
3132 asm_fprintf (file
, "%Rfpcr");
3133 else if (letter
== '$')
3136 fprintf (file
, "s");
3138 else if (letter
== '&')
3141 fprintf (file
, "d");
3143 else if (letter
== '/')
3144 asm_fprintf (file
, "%R");
3145 else if (letter
== 'p')
3147 output_addr_const (file
, op
);
3148 if (!(GET_CODE (op
) == SYMBOL_REF
&& SYMBOL_REF_LOCAL_P (op
)))
3149 fprintf (file
, "@PLTPC");
3151 else if (GET_CODE (op
) == REG
)
3154 /* Print out the second register name of a register pair.
3155 I.e., R (6) => 7. */
3156 fputs (M68K_REGNAME(REGNO (op
) + 1), file
);
3158 fputs (M68K_REGNAME(REGNO (op
)), file
);
3160 else if (GET_CODE (op
) == MEM
)
3162 output_address (XEXP (op
, 0));
3163 if (letter
== 'd' && ! TARGET_68020
3164 && CONSTANT_ADDRESS_P (XEXP (op
, 0))
3165 && !(GET_CODE (XEXP (op
, 0)) == CONST_INT
3166 && INTVAL (XEXP (op
, 0)) < 0x8000
3167 && INTVAL (XEXP (op
, 0)) >= -0x8000))
3168 fprintf (file
, MOTOROLA
? ".l" : ":l");
3170 else if (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == SFmode
)
3173 REAL_VALUE_FROM_CONST_DOUBLE (r
, op
);
3174 ASM_OUTPUT_FLOAT_OPERAND (letter
, file
, r
);
3176 else if (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == XFmode
)
3179 REAL_VALUE_FROM_CONST_DOUBLE (r
, op
);
3180 ASM_OUTPUT_LONG_DOUBLE_OPERAND (file
, r
);
3182 else if (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == DFmode
)
3185 REAL_VALUE_FROM_CONST_DOUBLE (r
, op
);
3186 ASM_OUTPUT_DOUBLE_OPERAND (file
, r
);
3190 /* Use `print_operand_address' instead of `output_addr_const'
3191 to ensure that we print relevant PIC stuff. */
3192 asm_fprintf (file
, "%I");
3194 && (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == CONST
))
3195 print_operand_address (file
, op
);
3197 output_addr_const (file
, op
);
3202 /* A C compound statement to output to stdio stream STREAM the
3203 assembler syntax for an instruction operand that is a memory
3204 reference whose address is ADDR. ADDR is an RTL expression.
3206 Note that this contains a kludge that knows that the only reason
3207 we have an address (plus (label_ref...) (reg...)) when not generating
3208 PIC code is in the insn before a tablejump, and we know that m68k.md
3209 generates a label LInnn: on such an insn.
3211 It is possible for PIC to generate a (plus (label_ref...) (reg...))
3212 and we handle that just like we would a (plus (symbol_ref...) (reg...)).
3214 Some SGS assemblers have a bug such that "Lnnn-LInnn-2.b(pc,d0.l*2)"
3215 fails to assemble. Luckily "Lnnn(pc,d0.l*2)" produces the results
3216 we want. This difference can be accommodated by using an assembler
3217 define such "LDnnn" to be either "Lnnn-LInnn-2.b", "Lnnn", or any other
3218 string, as necessary. This is accomplished via the ASM_OUTPUT_CASE_END
3219 macro. See m68k/sgs.h for an example; for versions without the bug.
3220 Some assemblers refuse all the above solutions. The workaround is to
3221 emit "K(pc,d0.l*2)" with K being a small constant known to give the
3224 They also do not like things like "pea 1.w", so we simple leave off
3225 the .w on small constants.
3227 This routine is responsible for distinguishing between -fpic and -fPIC
3228 style relocations in an address. When generating -fpic code the
3229 offset is output in word mode (e.g. movel a5@(_foo:w), a0). When generating
3230 -fPIC code the offset is output in long mode (e.g. movel a5@(_foo:l), a0) */
3233 # define ASM_OUTPUT_CASE_FETCH(file, labelno, regname) \
3234 asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.", labelno, labelno, regname)
3235 #else /* !MOTOROLA */
3236 # define ASM_OUTPUT_CASE_FETCH(file, labelno, regname) \
3237 asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:", labelno, labelno, regname)
3238 #endif /* !MOTOROLA */
3241 print_operand_address (FILE *file
, rtx addr
)
3243 register rtx reg1
, reg2
, breg
, ireg
;
3246 switch (GET_CODE (addr
))
3249 fprintf (file
, MOTOROLA
? "(%s)" : "%s@", M68K_REGNAME (REGNO (addr
)));
3252 fprintf (file
, MOTOROLA
? "-(%s)" : "%s@-",
3253 M68K_REGNAME (REGNO (XEXP (addr
, 0))));
3256 fprintf (file
, MOTOROLA
? "(%s)+" : "%s@+",
3257 M68K_REGNAME (REGNO (XEXP (addr
, 0))));
3260 reg1
= reg2
= ireg
= breg
= offset
= 0;
3261 if (CONSTANT_ADDRESS_P (XEXP (addr
, 0)))
3263 offset
= XEXP (addr
, 0);
3264 addr
= XEXP (addr
, 1);
3266 else if (CONSTANT_ADDRESS_P (XEXP (addr
, 1)))
3268 offset
= XEXP (addr
, 1);
3269 addr
= XEXP (addr
, 0);
3271 if (GET_CODE (addr
) != PLUS
)
3275 else if (GET_CODE (XEXP (addr
, 0)) == SIGN_EXTEND
)
3277 reg1
= XEXP (addr
, 0);
3278 addr
= XEXP (addr
, 1);
3280 else if (GET_CODE (XEXP (addr
, 1)) == SIGN_EXTEND
)
3282 reg1
= XEXP (addr
, 1);
3283 addr
= XEXP (addr
, 0);
3285 else if (GET_CODE (XEXP (addr
, 0)) == MULT
)
3287 reg1
= XEXP (addr
, 0);
3288 addr
= XEXP (addr
, 1);
3290 else if (GET_CODE (XEXP (addr
, 1)) == MULT
)
3292 reg1
= XEXP (addr
, 1);
3293 addr
= XEXP (addr
, 0);
3295 else if (GET_CODE (XEXP (addr
, 0)) == REG
)
3297 reg1
= XEXP (addr
, 0);
3298 addr
= XEXP (addr
, 1);
3300 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
3302 reg1
= XEXP (addr
, 1);
3303 addr
= XEXP (addr
, 0);
3305 if (GET_CODE (addr
) == REG
|| GET_CODE (addr
) == MULT
3306 || GET_CODE (addr
) == SIGN_EXTEND
)
3314 #if 0 /* for OLD_INDEXING */
3315 else if (GET_CODE (addr
) == PLUS
)
3317 if (GET_CODE (XEXP (addr
, 0)) == REG
)
3319 reg2
= XEXP (addr
, 0);
3320 addr
= XEXP (addr
, 1);
3322 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
3324 reg2
= XEXP (addr
, 1);
3325 addr
= XEXP (addr
, 0);
3334 if ((reg1
&& (GET_CODE (reg1
) == SIGN_EXTEND
3335 || GET_CODE (reg1
) == MULT
))
3336 || (reg2
!= 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2
))))
3341 else if (reg1
!= 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1
)))
3346 if (ireg
!= 0 && breg
== 0 && GET_CODE (addr
) == LABEL_REF
3347 && ! (flag_pic
&& ireg
== pic_offset_table_rtx
))
3350 if (GET_CODE (ireg
) == MULT
)
3352 scale
= INTVAL (XEXP (ireg
, 1));
3353 ireg
= XEXP (ireg
, 0);
3355 if (GET_CODE (ireg
) == SIGN_EXTEND
)
3357 ASM_OUTPUT_CASE_FETCH (file
,
3358 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
3359 M68K_REGNAME (REGNO (XEXP (ireg
, 0))));
3360 fprintf (file
, "w");
3364 ASM_OUTPUT_CASE_FETCH (file
,
3365 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
3366 M68K_REGNAME (REGNO (ireg
)));
3367 fprintf (file
, "l");
3370 fprintf (file
, MOTOROLA
? "*%d" : ":%d", scale
);
3374 if (breg
!= 0 && ireg
== 0 && GET_CODE (addr
) == LABEL_REF
3375 && ! (flag_pic
&& breg
== pic_offset_table_rtx
))
3377 ASM_OUTPUT_CASE_FETCH (file
,
3378 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
3379 M68K_REGNAME (REGNO (breg
)));
3380 fprintf (file
, "l)");
3383 if (ireg
!= 0 || breg
!= 0)
3388 gcc_assert (flag_pic
|| !addr
|| GET_CODE (addr
) != LABEL_REF
);
3394 output_addr_const (file
, addr
);
3395 if (flag_pic
&& (breg
== pic_offset_table_rtx
))
3397 fprintf (file
, "@GOT");
3399 fprintf (file
, ".w");
3402 fprintf (file
, "(%s", M68K_REGNAME (REGNO (breg
)));
3406 else /* !MOTOROLA */
3408 fprintf (file
, "%s@(", M68K_REGNAME (REGNO (breg
)));
3411 output_addr_const (file
, addr
);
3412 if (breg
== pic_offset_table_rtx
)
3416 fprintf (file
, ":w");
3419 fprintf (file
, ":l");
3428 if (ireg
!= 0 && GET_CODE (ireg
) == MULT
)
3430 scale
= INTVAL (XEXP (ireg
, 1));
3431 ireg
= XEXP (ireg
, 0);
3433 if (ireg
!= 0 && GET_CODE (ireg
) == SIGN_EXTEND
)
3434 fprintf (file
, MOTOROLA
? "%s.w" : "%s:w",
3435 M68K_REGNAME (REGNO (XEXP (ireg
, 0))));
3437 fprintf (file
, MOTOROLA
? "%s.l" : "%s:l",
3438 M68K_REGNAME (REGNO (ireg
)));
3440 fprintf (file
, MOTOROLA
? "*%d" : ":%d", scale
);
3444 else if (reg1
!= 0 && GET_CODE (addr
) == LABEL_REF
3445 && ! (flag_pic
&& reg1
== pic_offset_table_rtx
))
3447 ASM_OUTPUT_CASE_FETCH (file
,
3448 CODE_LABEL_NUMBER (XEXP (addr
, 0)),
3449 M68K_REGNAME (REGNO (reg1
)));
3450 fprintf (file
, "l)");
3453 /* FALL-THROUGH (is this really what we want?) */
3455 if (GET_CODE (addr
) == CONST_INT
3456 && INTVAL (addr
) < 0x8000
3457 && INTVAL (addr
) >= -0x8000)
3459 fprintf (file
, MOTOROLA
? "%d.w" : "%d:w", (int) INTVAL (addr
));
3461 else if (GET_CODE (addr
) == CONST_INT
)
3463 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (addr
));
3465 else if (TARGET_PCREL
)
3468 output_addr_const (file
, addr
);
3470 asm_fprintf (file
, ":w,%Rpc)");
3472 asm_fprintf (file
, ":l,%Rpc)");
3476 /* Special case for SYMBOL_REF if the symbol name ends in
3477 `.<letter>', this can be mistaken as a size suffix. Put
3478 the name in parentheses. */
3479 if (GET_CODE (addr
) == SYMBOL_REF
3480 && strlen (XSTR (addr
, 0)) > 2
3481 && XSTR (addr
, 0)[strlen (XSTR (addr
, 0)) - 2] == '.')
3484 output_addr_const (file
, addr
);
3488 output_addr_const (file
, addr
);
3494 /* Check for cases where a clr insns can be omitted from code using
3495 strict_low_part sets. For example, the second clrl here is not needed:
3496 clrl d0; movw a0@+,d0; use d0; clrl d0; movw a0@+; use d0; ...
3498 MODE is the mode of this STRICT_LOW_PART set. FIRST_INSN is the clear
3499 insn we are checking for redundancy. TARGET is the register set by the
3503 strict_low_part_peephole_ok (enum machine_mode mode
, rtx first_insn
,
3508 p
= prev_nonnote_insn (first_insn
);
3512 /* If it isn't an insn, then give up. */
3513 if (GET_CODE (p
) != INSN
)
3516 if (reg_set_p (target
, p
))
3518 rtx set
= single_set (p
);
3521 /* If it isn't an easy to recognize insn, then give up. */
3525 dest
= SET_DEST (set
);
3527 /* If this sets the entire target register to zero, then our
3528 first_insn is redundant. */
3529 if (rtx_equal_p (dest
, target
)
3530 && SET_SRC (set
) == const0_rtx
)
3532 else if (GET_CODE (dest
) == STRICT_LOW_PART
3533 && GET_CODE (XEXP (dest
, 0)) == REG
3534 && REGNO (XEXP (dest
, 0)) == REGNO (target
)
3535 && (GET_MODE_SIZE (GET_MODE (XEXP (dest
, 0)))
3536 <= GET_MODE_SIZE (mode
)))
3537 /* This is a strict low part set which modifies less than
3538 we are using, so it is safe. */
3544 p
= prev_nonnote_insn (p
);
3550 /* Operand predicates for implementing asymmetric pc-relative addressing
3551 on m68k. The m68k supports pc-relative addressing (mode 7, register 2)
3552 when used as a source operand, but not as a destination operand.
3554 We model this by restricting the meaning of the basic predicates
3555 (general_operand, memory_operand, etc) to forbid the use of this
3556 addressing mode, and then define the following predicates that permit
3557 this addressing mode. These predicates can then be used for the
3558 source operands of the appropriate instructions.
3560 n.b. While it is theoretically possible to change all machine patterns
3561 to use this addressing more where permitted by the architecture,
3562 it has only been implemented for "common" cases: SImode, HImode, and
3563 QImode operands, and only for the principle operations that would
3564 require this addressing mode: data movement and simple integer operations.
3566 In parallel with these new predicates, two new constraint letters
3567 were defined: 'S' and 'T'. 'S' is the -mpcrel analog of 'm'.
3568 'T' replaces 's' in the non-pcrel case. It is a no-op in the pcrel case.
3569 In the pcrel case 's' is only valid in combination with 'a' registers.
3570 See addsi3, subsi3, cmpsi, and movsi patterns for a better understanding
3571 of how these constraints are used.
3573 The use of these predicates is strictly optional, though patterns that
3574 don't will cause an extra reload register to be allocated where one
3577 lea (abc:w,%pc),%a0 ; need to reload address
3578 moveq &1,%d1 ; since write to pc-relative space
3579 movel %d1,%a0@ ; is not allowed
3581 lea (abc:w,%pc),%a1 ; no need to reload address here
3582 movel %a1@,%d0 ; since "movel (abc:w,%pc),%d0" is ok
3584 For more info, consult tiemann@cygnus.com.
3587 All of the ugliness with predicates and constraints is due to the
3588 simple fact that the m68k does not allow a pc-relative addressing
3589 mode as a destination. gcc does not distinguish between source and
3590 destination addresses. Hence, if we claim that pc-relative address
3591 modes are valid, e.g. GO_IF_LEGITIMATE_ADDRESS accepts them, then we
3592 end up with invalid code. To get around this problem, we left
3593 pc-relative modes as invalid addresses, and then added special
3594 predicates and constraints to accept them.
3596 A cleaner way to handle this is to modify gcc to distinguish
3597 between source and destination addresses. We can then say that
3598 pc-relative is a valid source address but not a valid destination
3599 address, and hopefully avoid a lot of the predicate and constraint
3600 hackery. Unfortunately, this would be a pretty big change. It would
3601 be a useful change for a number of ports, but there aren't any current
3602 plans to undertake this.
3604 ***************************************************************************/
3608 output_andsi3 (rtx
*operands
)
3611 if (GET_CODE (operands
[2]) == CONST_INT
3612 && (INTVAL (operands
[2]) | 0xffff) == -1
3613 && (DATA_REG_P (operands
[0])
3614 || offsettable_memref_p (operands
[0]))
3615 && !TARGET_COLDFIRE
)
3617 if (GET_CODE (operands
[0]) != REG
)
3618 operands
[0] = adjust_address (operands
[0], HImode
, 2);
3619 operands
[2] = GEN_INT (INTVAL (operands
[2]) & 0xffff);
3620 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3622 if (operands
[2] == const0_rtx
)
3624 return "and%.w %2,%0";
3626 if (GET_CODE (operands
[2]) == CONST_INT
3627 && (logval
= exact_log2 (~ INTVAL (operands
[2]))) >= 0
3628 && (DATA_REG_P (operands
[0])
3629 || offsettable_memref_p (operands
[0])))
3631 if (DATA_REG_P (operands
[0]))
3632 operands
[1] = GEN_INT (logval
);
3635 operands
[0] = adjust_address (operands
[0], SImode
, 3 - (logval
/ 8));
3636 operands
[1] = GEN_INT (logval
% 8);
3638 /* This does not set condition codes in a standard way. */
3640 return "bclr %1,%0";
3642 return "and%.l %2,%0";
3646 output_iorsi3 (rtx
*operands
)
3648 register int logval
;
3649 if (GET_CODE (operands
[2]) == CONST_INT
3650 && INTVAL (operands
[2]) >> 16 == 0
3651 && (DATA_REG_P (operands
[0])
3652 || offsettable_memref_p (operands
[0]))
3653 && !TARGET_COLDFIRE
)
3655 if (GET_CODE (operands
[0]) != REG
)
3656 operands
[0] = adjust_address (operands
[0], HImode
, 2);
3657 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3659 if (INTVAL (operands
[2]) == 0xffff)
3660 return "mov%.w %2,%0";
3661 return "or%.w %2,%0";
3663 if (GET_CODE (operands
[2]) == CONST_INT
3664 && (logval
= exact_log2 (INTVAL (operands
[2]))) >= 0
3665 && (DATA_REG_P (operands
[0])
3666 || offsettable_memref_p (operands
[0])))
3668 if (DATA_REG_P (operands
[0]))
3669 operands
[1] = GEN_INT (logval
);
3672 operands
[0] = adjust_address (operands
[0], SImode
, 3 - (logval
/ 8));
3673 operands
[1] = GEN_INT (logval
% 8);
3676 return "bset %1,%0";
3678 return "or%.l %2,%0";
3682 output_xorsi3 (rtx
*operands
)
3684 register int logval
;
3685 if (GET_CODE (operands
[2]) == CONST_INT
3686 && INTVAL (operands
[2]) >> 16 == 0
3687 && (offsettable_memref_p (operands
[0]) || DATA_REG_P (operands
[0]))
3688 && !TARGET_COLDFIRE
)
3690 if (! DATA_REG_P (operands
[0]))
3691 operands
[0] = adjust_address (operands
[0], HImode
, 2);
3692 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3694 if (INTVAL (operands
[2]) == 0xffff)
3696 return "eor%.w %2,%0";
3698 if (GET_CODE (operands
[2]) == CONST_INT
3699 && (logval
= exact_log2 (INTVAL (operands
[2]))) >= 0
3700 && (DATA_REG_P (operands
[0])
3701 || offsettable_memref_p (operands
[0])))
3703 if (DATA_REG_P (operands
[0]))
3704 operands
[1] = GEN_INT (logval
);
3707 operands
[0] = adjust_address (operands
[0], SImode
, 3 - (logval
/ 8));
3708 operands
[1] = GEN_INT (logval
% 8);
3711 return "bchg %1,%0";
3713 return "eor%.l %2,%0";
3716 /* Return the instruction that should be used for a call to address X,
3717 which is known to be in operand 0. */
3722 if (symbolic_operand (x
, VOIDmode
))
3723 return m68k_symbolic_call
;
3728 #ifdef M68K_TARGET_COFF
3730 /* Output assembly to switch to section NAME with attribute FLAGS. */
3733 m68k_coff_asm_named_section (const char *name
, unsigned int flags
,
3734 tree decl ATTRIBUTE_UNUSED
)
3738 if (flags
& SECTION_WRITE
)
3743 fprintf (asm_out_file
, "\t.section\t%s,\"%c\"\n", name
, flagchar
);
3746 #endif /* M68K_TARGET_COFF */
3749 m68k_output_mi_thunk (FILE *file
, tree thunk ATTRIBUTE_UNUSED
,
3750 HOST_WIDE_INT delta
,
3751 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED
,
3757 if (delta
> 0 && delta
<= 8)
3758 asm_fprintf (file
, (MOTOROLA
3759 ? "\taddq.l %I%d,4(%Rsp)\n"
3760 : "\taddql %I%d,%Rsp@(4)\n"),
3762 else if (delta
< 0 && delta
>= -8)
3763 asm_fprintf (file
, (MOTOROLA
3764 ? "\tsubq.l %I%d,4(%Rsp)\n"
3765 : "\tsubql %I%d,%Rsp@(4)\n"),
3767 else if (TARGET_COLDFIRE
)
3769 /* ColdFire can't add/sub a constant to memory unless it is in
3770 the range of addq/subq. So load the value into %d0 and
3771 then add it to 4(%sp). */
3772 if (delta
>= -128 && delta
<= 127)
3773 asm_fprintf (file
, (MOTOROLA
3774 ? "\tmoveq.l %I%wd,%Rd0\n"
3775 : "\tmoveql %I%wd,%Rd0\n"),
3778 asm_fprintf (file
, (MOTOROLA
3779 ? "\tmove.l %I%wd,%Rd0\n"
3780 : "\tmovel %I%wd,%Rd0\n"),
3782 asm_fprintf (file
, (MOTOROLA
3783 ? "\tadd.l %Rd0,4(%Rsp)\n"
3784 : "\taddl %Rd0,%Rsp@(4)\n"));
3787 asm_fprintf (file
, (MOTOROLA
3788 ? "\tadd.l %I%wd,4(%Rsp)\n"
3789 : "\taddl %I%wd,%Rsp@(4)\n"),
3792 xops
[0] = DECL_RTL (function
);
3794 gcc_assert (MEM_P (xops
[0])
3795 && symbolic_operand (XEXP (xops
[0], 0), VOIDmode
));
3796 xops
[0] = XEXP (xops
[0], 0);
3798 fmt
= m68k_symbolic_jump
;
3799 if (m68k_symbolic_jump
== NULL
)
3800 fmt
= "move.l %%a1@GOT(%%a5), %%a1\n\tjmp (%%a1)";
3802 output_asm_insn (fmt
, xops
);
3805 /* Worker function for TARGET_STRUCT_VALUE_RTX. */
3808 m68k_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED
,
3809 int incoming ATTRIBUTE_UNUSED
)
3811 return gen_rtx_REG (Pmode
, M68K_STRUCT_VALUE_REGNUM
);
3814 /* Return nonzero if register old_reg can be renamed to register new_reg. */
3816 m68k_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED
,
3817 unsigned int new_reg
)
3820 /* Interrupt functions can only use registers that have already been
3821 saved by the prologue, even if they would normally be
3824 if (m68k_interrupt_function_p (current_function_decl
)
3825 && !regs_ever_live
[new_reg
])
3831 /* Value is true if hard register REGNO can hold a value of machine-mode MODE.
3832 On the 68000, the cpu registers can hold any mode except bytes in address
3833 registers, but the 68881 registers can hold only SFmode or DFmode. */
3835 m68k_regno_mode_ok (int regno
, enum machine_mode mode
)
3837 if (DATA_REGNO_P (regno
))
3839 /* Data Registers, can hold aggregate if fits in. */
3840 if (regno
+ GET_MODE_SIZE (mode
) / 4 <= 8)
3843 else if (ADDRESS_REGNO_P (regno
))
3845 /* Address Registers, can't hold bytes, can hold aggregate if
3847 if (GET_MODE_SIZE (mode
) == 1)
3849 if (regno
+ GET_MODE_SIZE (mode
) / 4 <= 16)
3852 else if (FP_REGNO_P (regno
))
3854 /* FPU registers, hold float or complex float of long double or
3856 if ((GET_MODE_CLASS (mode
) == MODE_FLOAT
3857 || GET_MODE_CLASS (mode
) == MODE_COMPLEX_FLOAT
)
3858 && GET_MODE_UNIT_SIZE (mode
) <= TARGET_FP_REG_SIZE
)
3864 /* Return floating point values in a 68881 register. This makes 68881 code
3865 a little bit faster. It also makes -msoft-float code incompatible with
3866 hard-float code, so people have to be careful not to mix the two.
3867 For ColdFire it was decided the ABI incompatibility is undesirable.
3868 If there is need for a hard-float ABI it is probably worth doing it
3869 properly and also passing function arguments in FP registers. */
3871 m68k_libcall_value (enum machine_mode mode
)
3878 return gen_rtx_REG (mode
, 16);
3883 return gen_rtx_REG (mode
, 0);
3887 m68k_function_value (tree valtype
, tree func ATTRIBUTE_UNUSED
)
3889 enum machine_mode mode
;
3891 mode
= TYPE_MODE (valtype
);
3897 return gen_rtx_REG (mode
, 16);
3903 /* If the function returns a pointer, push that into %a0 */
3904 if (POINTER_TYPE_P (valtype
))
3905 return gen_rtx_REG (mode
, 8);
3907 return gen_rtx_REG (mode
, 0);