1 /* Copyright (C) 1997-2015 Free Software Foundation, Inc.
2 Contributed by Red Hat, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
22 #include "coretypes.h"
29 #include "stringpool.h"
34 #include "diagnostic-core.h"
35 #include "fold-const.h"
37 #include "stor-layout.h"
39 #include "insn-attr.h"
43 #include "langhooks.h"
49 /* This file should be included last. */
50 #include "target-def.h"
53 #define FRV_INLINE inline
56 /* The maximum number of distinct NOP patterns. There are three:
57 nop, fnop and mnop. */
58 #define NUM_NOP_PATTERNS 3
60 /* Classification of instructions and units: integer, floating-point/media,
61 branch and control. */
62 enum frv_insn_group
{ GROUP_I
, GROUP_FM
, GROUP_B
, GROUP_C
, NUM_GROUPS
};
64 /* The DFA names of the units, in packet order. */
65 static const char *const frv_unit_names
[] =
75 /* The classification of each unit in frv_unit_names[]. */
76 static const enum frv_insn_group frv_unit_groups
[ARRAY_SIZE (frv_unit_names
)] =
86 /* Return the DFA unit code associated with the Nth unit of integer
87 or floating-point group GROUP, */
88 #define NTH_UNIT(GROUP, N) frv_unit_codes[(GROUP) + (N) * 2 + 1]
90 /* Return the number of integer or floating-point unit UNIT
91 (1 for I1, 2 for F2, etc.). */
92 #define UNIT_NUMBER(UNIT) (((UNIT) - 1) / 2)
94 /* The DFA unit number for each unit in frv_unit_names[]. */
95 static int frv_unit_codes
[ARRAY_SIZE (frv_unit_names
)];
97 /* FRV_TYPE_TO_UNIT[T] is the last unit in frv_unit_names[] that can issue
98 an instruction of type T. The value is ARRAY_SIZE (frv_unit_names) if
99 no instruction of type T has been seen. */
100 static unsigned int frv_type_to_unit
[TYPE_UNKNOWN
+ 1];
102 /* An array of dummy nop INSNs, one for each type of nop that the
104 static GTY(()) rtx_insn
*frv_nops
[NUM_NOP_PATTERNS
];
106 /* The number of nop instructions in frv_nops[]. */
107 static unsigned int frv_num_nops
;
109 /* The type of access. FRV_IO_UNKNOWN means the access can be either
110 a read or a write. */
111 enum frv_io_type
{ FRV_IO_UNKNOWN
, FRV_IO_READ
, FRV_IO_WRITE
};
113 /* Information about one __builtin_read or __builtin_write access, or
114 the combination of several such accesses. The most general value
115 is all-zeros (an unknown access to an unknown address). */
117 enum frv_io_type type
;
119 /* The constant address being accessed, or zero if not known. */
120 HOST_WIDE_INT const_address
;
122 /* The run-time address, as used in operand 0 of the membar pattern. */
126 /* Return true if instruction INSN should be packed with the following
128 #define PACKING_FLAG_P(INSN) (GET_MODE (INSN) == TImode)
130 /* Set the value of PACKING_FLAG_P(INSN). */
131 #define SET_PACKING_FLAG(INSN) PUT_MODE (INSN, TImode)
132 #define CLEAR_PACKING_FLAG(INSN) PUT_MODE (INSN, VOIDmode)
134 /* Loop with REG set to each hard register in rtx X. */
135 #define FOR_EACH_REGNO(REG, X) \
136 for (REG = REGNO (X); \
137 REG < REGNO (X) + HARD_REGNO_NREGS (REGNO (X), GET_MODE (X)); \
140 /* This structure contains machine specific function data. */
141 struct GTY(()) machine_function
143 /* True if we have created an rtx that relies on the stack frame. */
146 /* True if this function contains at least one __builtin_{read,write}*. */
150 /* Temporary register allocation support structure. */
151 typedef struct frv_tmp_reg_struct
153 HARD_REG_SET regs
; /* possible registers to allocate */
154 int next_reg
[N_REG_CLASSES
]; /* next register to allocate per class */
158 /* Register state information for VLIW re-packing phase. */
159 #define REGSTATE_CC_MASK 0x07 /* Mask to isolate CCn for cond exec */
160 #define REGSTATE_MODIFIED 0x08 /* reg modified in current VLIW insn */
161 #define REGSTATE_IF_TRUE 0x10 /* reg modified in cond exec true */
162 #define REGSTATE_IF_FALSE 0x20 /* reg modified in cond exec false */
164 #define REGSTATE_IF_EITHER (REGSTATE_IF_TRUE | REGSTATE_IF_FALSE)
166 typedef unsigned char regstate_t
;
168 /* Used in frv_frame_accessor_t to indicate the direction of a register-to-
176 /* Information required by frv_frame_access. */
179 /* This field is FRV_LOAD if registers are to be loaded from the stack and
180 FRV_STORE if they should be stored onto the stack. FRV_STORE implies
181 the move is being done by the prologue code while FRV_LOAD implies it
182 is being done by the epilogue. */
183 enum frv_stack_op op
;
185 /* The base register to use when accessing the stack. This may be the
186 frame pointer, stack pointer, or a temporary. The choice of register
187 depends on which part of the frame is being accessed and how big the
191 /* The offset of BASE from the bottom of the current frame, in bytes. */
193 } frv_frame_accessor_t
;
195 /* Conditional execution support gathered together in one structure. */
198 /* Linked list of insns to add if the conditional execution conversion was
199 successful. Each link points to an EXPR_LIST which points to the pattern
200 of the insn to add, and the insn to be inserted before. */
201 rtx added_insns_list
;
203 /* Identify which registers are safe to allocate for if conversions to
204 conditional execution. We keep the last allocated register in the
205 register classes between COND_EXEC statements. This will mean we allocate
206 different registers for each different COND_EXEC group if we can. This
207 might allow the scheduler to intermix two different COND_EXEC sections. */
208 frv_tmp_reg_t tmp_reg
;
210 /* For nested IFs, identify which CC registers are used outside of setting
211 via a compare isnsn, and using via a check insn. This will allow us to
212 know if we can rewrite the register to use a different register that will
213 be paired with the CR register controlling the nested IF-THEN blocks. */
214 HARD_REG_SET nested_cc_ok_rewrite
;
216 /* Temporary registers allocated to hold constants during conditional
218 rtx scratch_regs
[FIRST_PSEUDO_REGISTER
];
220 /* Current number of temp registers available. */
221 int cur_scratch_regs
;
223 /* Number of nested conditional execution blocks. */
224 int num_nested_cond_exec
;
226 /* Map of insns that set up constants in scratch registers. */
227 bitmap scratch_insns_bitmap
;
229 /* Conditional execution test register (CC0..CC7). */
232 /* Conditional execution compare register that is paired with cr_reg, so that
233 nested compares can be done. The csubcc and caddcc instructions don't
234 have enough bits to specify both a CC register to be set and a CR register
235 to do the test on, so the same bit number is used for both. Needless to
236 say, this is rather inconvenient for GCC. */
239 /* Extra CR registers used for &&, ||. */
243 /* Previous CR used in nested if, to make sure we are dealing with the same
244 nested if as the previous statement. */
245 rtx last_nested_if_cr
;
249 static /* GTY(()) */ frv_ifcvt_t frv_ifcvt
;
251 /* Map register number to smallest register class. */
252 enum reg_class regno_reg_class
[FIRST_PSEUDO_REGISTER
];
254 /* Cached value of frv_stack_info. */
255 static frv_stack_t
*frv_stack_cache
= (frv_stack_t
*)0;
257 /* Forward references */
259 static void frv_option_override (void);
260 static bool frv_legitimate_address_p (machine_mode
, rtx
, bool);
261 static int frv_default_flags_for_cpu (void);
262 static int frv_string_begins_with (const char *, const char *);
263 static FRV_INLINE
bool frv_small_data_reloc_p (rtx
, int);
264 static void frv_print_operand (FILE *, rtx
, int);
265 static void frv_print_operand_address (FILE *, machine_mode
, rtx
);
266 static bool frv_print_operand_punct_valid_p (unsigned char code
);
267 static void frv_print_operand_memory_reference_reg
269 static void frv_print_operand_memory_reference (FILE *, rtx
, int);
270 static int frv_print_operand_jump_hint (rtx_insn
*);
271 static const char *comparison_string (enum rtx_code
, rtx
);
272 static rtx
frv_function_value (const_tree
, const_tree
,
274 static rtx
frv_libcall_value (machine_mode
,
276 static FRV_INLINE
int frv_regno_ok_for_base_p (int, int);
277 static rtx
single_set_pattern (rtx
);
278 static int frv_function_contains_far_jump (void);
279 static rtx
frv_alloc_temp_reg (frv_tmp_reg_t
*,
283 static rtx
frv_frame_offset_rtx (int);
284 static rtx
frv_frame_mem (machine_mode
, rtx
, int);
285 static rtx
frv_dwarf_store (rtx
, int);
286 static void frv_frame_insn (rtx
, rtx
);
287 static void frv_frame_access (frv_frame_accessor_t
*,
289 static void frv_frame_access_multi (frv_frame_accessor_t
*,
291 static void frv_frame_access_standard_regs (enum frv_stack_op
,
293 static struct machine_function
*frv_init_machine_status (void);
294 static rtx
frv_int_to_acc (enum insn_code
, int, rtx
);
295 static machine_mode
frv_matching_accg_mode (machine_mode
);
296 static rtx
frv_read_argument (tree
, unsigned int);
297 static rtx
frv_read_iacc_argument (machine_mode
, tree
, unsigned int);
298 static int frv_check_constant_argument (enum insn_code
, int, rtx
);
299 static rtx
frv_legitimize_target (enum insn_code
, rtx
);
300 static rtx
frv_legitimize_argument (enum insn_code
, int, rtx
);
301 static rtx
frv_legitimize_tls_address (rtx
, enum tls_model
);
302 static rtx
frv_legitimize_address (rtx
, rtx
, machine_mode
);
303 static rtx
frv_expand_set_builtin (enum insn_code
, tree
, rtx
);
304 static rtx
frv_expand_unop_builtin (enum insn_code
, tree
, rtx
);
305 static rtx
frv_expand_binop_builtin (enum insn_code
, tree
, rtx
);
306 static rtx
frv_expand_cut_builtin (enum insn_code
, tree
, rtx
);
307 static rtx
frv_expand_binopimm_builtin (enum insn_code
, tree
, rtx
);
308 static rtx
frv_expand_voidbinop_builtin (enum insn_code
, tree
);
309 static rtx
frv_expand_int_void2arg (enum insn_code
, tree
);
310 static rtx
frv_expand_prefetches (enum insn_code
, tree
);
311 static rtx
frv_expand_voidtriop_builtin (enum insn_code
, tree
);
312 static rtx
frv_expand_voidaccop_builtin (enum insn_code
, tree
);
313 static rtx
frv_expand_mclracc_builtin (tree
);
314 static rtx
frv_expand_mrdacc_builtin (enum insn_code
, tree
);
315 static rtx
frv_expand_mwtacc_builtin (enum insn_code
, tree
);
316 static rtx
frv_expand_noargs_builtin (enum insn_code
);
317 static void frv_split_iacc_move (rtx
, rtx
);
318 static rtx
frv_emit_comparison (enum rtx_code
, rtx
, rtx
);
319 static void frv_ifcvt_add_insn (rtx
, rtx
, int);
320 static rtx
frv_ifcvt_rewrite_mem (rtx
, machine_mode
, rtx
);
321 static rtx
frv_ifcvt_load_value (rtx
, rtx
);
322 static unsigned int frv_insn_unit (rtx_insn
*);
323 static bool frv_issues_to_branch_unit_p (rtx_insn
*);
324 static int frv_cond_flags (rtx
);
325 static bool frv_regstate_conflict_p (regstate_t
, regstate_t
);
326 static bool frv_registers_conflict_p (rtx
);
327 static void frv_registers_update_1 (rtx
, const_rtx
, void *);
328 static void frv_registers_update (rtx
);
329 static void frv_start_packet (void);
330 static void frv_start_packet_block (void);
331 static void frv_finish_packet (void (*) (void));
332 static bool frv_pack_insn_p (rtx_insn
*);
333 static void frv_add_insn_to_packet (rtx_insn
*);
334 static void frv_insert_nop_in_packet (rtx_insn
*);
335 static bool frv_for_each_packet (void (*) (void));
336 static bool frv_sort_insn_group_1 (enum frv_insn_group
,
337 unsigned int, unsigned int,
338 unsigned int, unsigned int,
340 static int frv_compare_insns (const void *, const void *);
341 static void frv_sort_insn_group (enum frv_insn_group
);
342 static void frv_reorder_packet (void);
343 static void frv_fill_unused_units (enum frv_insn_group
);
344 static void frv_align_label (void);
345 static void frv_reorg_packet (void);
346 static void frv_register_nop (rtx
);
347 static void frv_reorg (void);
348 static void frv_pack_insns (void);
349 static void frv_function_prologue (FILE *, HOST_WIDE_INT
);
350 static void frv_function_epilogue (FILE *, HOST_WIDE_INT
);
351 static bool frv_assemble_integer (rtx
, unsigned, int);
352 static void frv_init_builtins (void);
353 static rtx
frv_expand_builtin (tree
, rtx
, rtx
, machine_mode
, int);
354 static void frv_init_libfuncs (void);
355 static bool frv_in_small_data_p (const_tree
);
356 static void frv_asm_output_mi_thunk
357 (FILE *, tree
, HOST_WIDE_INT
, HOST_WIDE_INT
, tree
);
358 static void frv_setup_incoming_varargs (cumulative_args_t
,
361 static rtx
frv_expand_builtin_saveregs (void);
362 static void frv_expand_builtin_va_start (tree
, rtx
);
363 static bool frv_rtx_costs (rtx
, machine_mode
, int, int,
365 static int frv_register_move_cost (machine_mode
,
366 reg_class_t
, reg_class_t
);
367 static int frv_memory_move_cost (machine_mode
,
369 static void frv_asm_out_constructor (rtx
, int);
370 static void frv_asm_out_destructor (rtx
, int);
371 static bool frv_function_symbol_referenced_p (rtx
);
372 static bool frv_legitimate_constant_p (machine_mode
, rtx
);
373 static bool frv_cannot_force_const_mem (machine_mode
, rtx
);
374 static const char *unspec_got_name (int);
375 static void frv_output_const_unspec (FILE *,
376 const struct frv_unspec
*);
377 static bool frv_function_ok_for_sibcall (tree
, tree
);
378 static rtx
frv_struct_value_rtx (tree
, int);
379 static bool frv_must_pass_in_stack (machine_mode mode
, const_tree type
);
380 static int frv_arg_partial_bytes (cumulative_args_t
, machine_mode
,
382 static rtx
frv_function_arg (cumulative_args_t
, machine_mode
,
384 static rtx
frv_function_incoming_arg (cumulative_args_t
, machine_mode
,
386 static void frv_function_arg_advance (cumulative_args_t
, machine_mode
,
388 static unsigned int frv_function_arg_boundary (machine_mode
,
390 static void frv_output_dwarf_dtprel (FILE *, int, rtx
)
392 static reg_class_t
frv_secondary_reload (bool, rtx
, reg_class_t
,
394 secondary_reload_info
*);
395 static bool frv_frame_pointer_required (void);
396 static bool frv_can_eliminate (const int, const int);
397 static void frv_conditional_register_usage (void);
398 static void frv_trampoline_init (rtx
, tree
, rtx
);
399 static bool frv_class_likely_spilled_p (reg_class_t
);
401 /* Initialize the GCC target structure. */
402 #undef TARGET_PRINT_OPERAND
403 #define TARGET_PRINT_OPERAND frv_print_operand
404 #undef TARGET_PRINT_OPERAND_ADDRESS
405 #define TARGET_PRINT_OPERAND_ADDRESS frv_print_operand_address
406 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
407 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P frv_print_operand_punct_valid_p
408 #undef TARGET_ASM_FUNCTION_PROLOGUE
409 #define TARGET_ASM_FUNCTION_PROLOGUE frv_function_prologue
410 #undef TARGET_ASM_FUNCTION_EPILOGUE
411 #define TARGET_ASM_FUNCTION_EPILOGUE frv_function_epilogue
412 #undef TARGET_ASM_INTEGER
413 #define TARGET_ASM_INTEGER frv_assemble_integer
414 #undef TARGET_OPTION_OVERRIDE
415 #define TARGET_OPTION_OVERRIDE frv_option_override
416 #undef TARGET_INIT_BUILTINS
417 #define TARGET_INIT_BUILTINS frv_init_builtins
418 #undef TARGET_EXPAND_BUILTIN
419 #define TARGET_EXPAND_BUILTIN frv_expand_builtin
420 #undef TARGET_INIT_LIBFUNCS
421 #define TARGET_INIT_LIBFUNCS frv_init_libfuncs
422 #undef TARGET_IN_SMALL_DATA_P
423 #define TARGET_IN_SMALL_DATA_P frv_in_small_data_p
424 #undef TARGET_REGISTER_MOVE_COST
425 #define TARGET_REGISTER_MOVE_COST frv_register_move_cost
426 #undef TARGET_MEMORY_MOVE_COST
427 #define TARGET_MEMORY_MOVE_COST frv_memory_move_cost
428 #undef TARGET_RTX_COSTS
429 #define TARGET_RTX_COSTS frv_rtx_costs
430 #undef TARGET_ASM_CONSTRUCTOR
431 #define TARGET_ASM_CONSTRUCTOR frv_asm_out_constructor
432 #undef TARGET_ASM_DESTRUCTOR
433 #define TARGET_ASM_DESTRUCTOR frv_asm_out_destructor
435 #undef TARGET_ASM_OUTPUT_MI_THUNK
436 #define TARGET_ASM_OUTPUT_MI_THUNK frv_asm_output_mi_thunk
437 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
438 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
440 #undef TARGET_SCHED_ISSUE_RATE
441 #define TARGET_SCHED_ISSUE_RATE frv_issue_rate
443 #undef TARGET_LEGITIMIZE_ADDRESS
444 #define TARGET_LEGITIMIZE_ADDRESS frv_legitimize_address
446 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
447 #define TARGET_FUNCTION_OK_FOR_SIBCALL frv_function_ok_for_sibcall
448 #undef TARGET_LEGITIMATE_CONSTANT_P
449 #define TARGET_LEGITIMATE_CONSTANT_P frv_legitimate_constant_p
450 #undef TARGET_CANNOT_FORCE_CONST_MEM
451 #define TARGET_CANNOT_FORCE_CONST_MEM frv_cannot_force_const_mem
453 #undef TARGET_HAVE_TLS
454 #define TARGET_HAVE_TLS HAVE_AS_TLS
456 #undef TARGET_STRUCT_VALUE_RTX
457 #define TARGET_STRUCT_VALUE_RTX frv_struct_value_rtx
458 #undef TARGET_MUST_PASS_IN_STACK
459 #define TARGET_MUST_PASS_IN_STACK frv_must_pass_in_stack
460 #undef TARGET_PASS_BY_REFERENCE
461 #define TARGET_PASS_BY_REFERENCE hook_pass_by_reference_must_pass_in_stack
462 #undef TARGET_ARG_PARTIAL_BYTES
463 #define TARGET_ARG_PARTIAL_BYTES frv_arg_partial_bytes
464 #undef TARGET_FUNCTION_ARG
465 #define TARGET_FUNCTION_ARG frv_function_arg
466 #undef TARGET_FUNCTION_INCOMING_ARG
467 #define TARGET_FUNCTION_INCOMING_ARG frv_function_incoming_arg
468 #undef TARGET_FUNCTION_ARG_ADVANCE
469 #define TARGET_FUNCTION_ARG_ADVANCE frv_function_arg_advance
470 #undef TARGET_FUNCTION_ARG_BOUNDARY
471 #define TARGET_FUNCTION_ARG_BOUNDARY frv_function_arg_boundary
473 #undef TARGET_EXPAND_BUILTIN_SAVEREGS
474 #define TARGET_EXPAND_BUILTIN_SAVEREGS frv_expand_builtin_saveregs
475 #undef TARGET_SETUP_INCOMING_VARARGS
476 #define TARGET_SETUP_INCOMING_VARARGS frv_setup_incoming_varargs
477 #undef TARGET_MACHINE_DEPENDENT_REORG
478 #define TARGET_MACHINE_DEPENDENT_REORG frv_reorg
480 #undef TARGET_EXPAND_BUILTIN_VA_START
481 #define TARGET_EXPAND_BUILTIN_VA_START frv_expand_builtin_va_start
484 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
485 #define TARGET_ASM_OUTPUT_DWARF_DTPREL frv_output_dwarf_dtprel
488 #undef TARGET_CLASS_LIKELY_SPILLED_P
489 #define TARGET_CLASS_LIKELY_SPILLED_P frv_class_likely_spilled_p
491 #undef TARGET_SECONDARY_RELOAD
492 #define TARGET_SECONDARY_RELOAD frv_secondary_reload
494 #undef TARGET_LEGITIMATE_ADDRESS_P
495 #define TARGET_LEGITIMATE_ADDRESS_P frv_legitimate_address_p
497 #undef TARGET_FRAME_POINTER_REQUIRED
498 #define TARGET_FRAME_POINTER_REQUIRED frv_frame_pointer_required
500 #undef TARGET_CAN_ELIMINATE
501 #define TARGET_CAN_ELIMINATE frv_can_eliminate
503 #undef TARGET_CONDITIONAL_REGISTER_USAGE
504 #define TARGET_CONDITIONAL_REGISTER_USAGE frv_conditional_register_usage
506 #undef TARGET_TRAMPOLINE_INIT
507 #define TARGET_TRAMPOLINE_INIT frv_trampoline_init
509 #undef TARGET_FUNCTION_VALUE
510 #define TARGET_FUNCTION_VALUE frv_function_value
511 #undef TARGET_LIBCALL_VALUE
512 #define TARGET_LIBCALL_VALUE frv_libcall_value
514 struct gcc_target targetm
= TARGET_INITIALIZER
;
516 #define FRV_SYMBOL_REF_TLS_P(RTX) \
517 (GET_CODE (RTX) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (RTX) != 0)
520 /* Any function call that satisfies the machine-independent
521 requirements is eligible on FR-V. */
524 frv_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED
,
525 tree exp ATTRIBUTE_UNUSED
)
530 /* Return true if SYMBOL is a small data symbol and relocation RELOC
531 can be used to access it directly in a load or store. */
533 static FRV_INLINE
bool
534 frv_small_data_reloc_p (rtx symbol
, int reloc
)
536 return (GET_CODE (symbol
) == SYMBOL_REF
537 && SYMBOL_REF_SMALL_P (symbol
)
538 && (!TARGET_FDPIC
|| flag_pic
== 1)
539 && (reloc
== R_FRV_GOTOFF12
|| reloc
== R_FRV_GPREL12
));
542 /* Return true if X is a valid relocation unspec. If it is, fill in UNSPEC
546 frv_const_unspec_p (rtx x
, struct frv_unspec
*unspec
)
548 if (GET_CODE (x
) == CONST
)
552 if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == CONST_INT
)
554 unspec
->offset
+= INTVAL (XEXP (x
, 1));
557 if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_GOT
)
559 unspec
->symbol
= XVECEXP (x
, 0, 0);
560 unspec
->reloc
= INTVAL (XVECEXP (x
, 0, 1));
562 if (unspec
->offset
== 0)
565 if (frv_small_data_reloc_p (unspec
->symbol
, unspec
->reloc
)
566 && unspec
->offset
> 0
567 && unspec
->offset
< g_switch_value
)
574 /* Decide whether we can force certain constants to memory. If we
575 decide we can't, the caller should be able to cope with it in
578 We never allow constants to be forced into memory for TARGET_FDPIC.
579 This is necessary for several reasons:
581 1. Since frv_legitimate_constant_p rejects constant pool addresses, the
582 target-independent code will try to force them into the constant
583 pool, thus leading to infinite recursion.
585 2. We can never introduce new constant pool references during reload.
586 Any such reference would require use of the pseudo FDPIC register.
588 3. We can't represent a constant added to a function pointer (which is
589 not the same as a pointer to a function+constant).
591 4. In many cases, it's more efficient to calculate the constant in-line. */
594 frv_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED
,
595 rtx x ATTRIBUTE_UNUSED
)
601 frv_default_flags_for_cpu (void)
603 switch (frv_cpu_type
)
605 case FRV_CPU_GENERIC
:
606 return MASK_DEFAULT_FRV
;
609 return MASK_DEFAULT_FR550
;
613 return MASK_DEFAULT_FR500
;
616 return MASK_DEFAULT_FR450
;
620 return MASK_DEFAULT_FR400
;
624 return MASK_DEFAULT_SIMPLE
;
631 /* Implement TARGET_OPTION_OVERRIDE. */
634 frv_option_override (void)
639 target_flags
|= (frv_default_flags_for_cpu () & ~target_flags_explicit
);
641 /* -mlibrary-pic sets -fPIC and -G0 and also suppresses warnings from the
642 linker about linking pic and non-pic code. */
645 if (!flag_pic
) /* -fPIC */
648 if (!global_options_set
.x_g_switch_value
) /* -G0 */
654 /* A C expression whose value is a register class containing hard
655 register REGNO. In general there is more than one such class;
656 choose a class which is "minimal", meaning that no smaller class
657 also contains the register. */
659 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
661 enum reg_class rclass
;
665 int gpr_reg
= regno
- GPR_FIRST
;
667 if (gpr_reg
== GR8_REG
)
670 else if (gpr_reg
== GR9_REG
)
673 else if (gpr_reg
== GR14_REG
)
674 rclass
= FDPIC_FPTR_REGS
;
676 else if (gpr_reg
== FDPIC_REGNO
)
679 else if ((gpr_reg
& 3) == 0)
682 else if ((gpr_reg
& 1) == 0)
689 else if (FPR_P (regno
))
691 int fpr_reg
= regno
- GPR_FIRST
;
692 if ((fpr_reg
& 3) == 0)
693 rclass
= QUAD_FPR_REGS
;
695 else if ((fpr_reg
& 1) == 0)
702 else if (regno
== LR_REGNO
)
705 else if (regno
== LCR_REGNO
)
708 else if (ICC_P (regno
))
711 else if (FCC_P (regno
))
714 else if (ICR_P (regno
))
717 else if (FCR_P (regno
))
720 else if (ACC_P (regno
))
722 int r
= regno
- ACC_FIRST
;
724 rclass
= QUAD_ACC_REGS
;
725 else if ((r
& 1) == 0)
726 rclass
= EVEN_ACC_REGS
;
731 else if (ACCG_P (regno
))
737 regno_reg_class
[regno
] = rclass
;
740 /* Check for small data option */
741 if (!global_options_set
.x_g_switch_value
&& !TARGET_LIBPIC
)
742 g_switch_value
= SDATA_DEFAULT_SIZE
;
744 /* There is no single unaligned SI op for PIC code. Sometimes we
745 need to use ".4byte" and sometimes we need to use ".picptr".
746 See frv_assemble_integer for details. */
747 if (flag_pic
|| TARGET_FDPIC
)
748 targetm
.asm_out
.unaligned_op
.si
= 0;
750 if ((target_flags_explicit
& MASK_LINKED_FP
) == 0)
751 target_flags
|= MASK_LINKED_FP
;
753 if ((target_flags_explicit
& MASK_OPTIMIZE_MEMBAR
) == 0)
754 target_flags
|= MASK_OPTIMIZE_MEMBAR
;
756 for (i
= 0; i
< ARRAY_SIZE (frv_unit_names
); i
++)
757 frv_unit_codes
[i
] = get_cpu_unit_code (frv_unit_names
[i
]);
759 for (i
= 0; i
< ARRAY_SIZE (frv_type_to_unit
); i
++)
760 frv_type_to_unit
[i
] = ARRAY_SIZE (frv_unit_codes
);
762 init_machine_status
= frv_init_machine_status
;
766 /* Return true if NAME (a STRING_CST node) begins with PREFIX. */
769 frv_string_begins_with (const char *name
, const char *prefix
)
771 const int prefix_len
= strlen (prefix
);
773 /* Remember: NAME's length includes the null terminator. */
774 return (strncmp (name
, prefix
, prefix_len
) == 0);
777 /* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */
780 frv_conditional_register_usage (void)
784 for (i
= GPR_FIRST
+ NUM_GPRS
; i
<= GPR_LAST
; i
++)
785 fixed_regs
[i
] = call_used_regs
[i
] = 1;
787 for (i
= FPR_FIRST
+ NUM_FPRS
; i
<= FPR_LAST
; i
++)
788 fixed_regs
[i
] = call_used_regs
[i
] = 1;
790 /* Reserve the registers used for conditional execution. At present, we need
791 1 ICC and 1 ICR register. */
792 fixed_regs
[ICC_TEMP
] = call_used_regs
[ICC_TEMP
] = 1;
793 fixed_regs
[ICR_TEMP
] = call_used_regs
[ICR_TEMP
] = 1;
797 fixed_regs
[ICC_FIRST
] = call_used_regs
[ICC_FIRST
] = 1;
798 fixed_regs
[FCC_FIRST
] = call_used_regs
[FCC_FIRST
] = 1;
799 fixed_regs
[ICR_FIRST
] = call_used_regs
[ICR_FIRST
] = 1;
800 fixed_regs
[FCR_FIRST
] = call_used_regs
[FCR_FIRST
] = 1;
804 fixed_regs
[GPR_FIRST
+ 16] = fixed_regs
[GPR_FIRST
+ 17] =
805 call_used_regs
[GPR_FIRST
+ 16] = call_used_regs
[GPR_FIRST
+ 17] = 0;
808 /* If -fpic, SDA_BASE_REG is the PIC register. */
809 if (g_switch_value
== 0 && !flag_pic
)
810 fixed_regs
[SDA_BASE_REG
] = call_used_regs
[SDA_BASE_REG
] = 0;
813 fixed_regs
[PIC_REGNO
] = call_used_regs
[PIC_REGNO
] = 0;
819 * Compute the stack frame layout
822 * +---------------+-----------------------+-----------------------+
823 * |Register |type |caller-save/callee-save|
824 * +---------------+-----------------------+-----------------------+
825 * |GR0 |Zero register | - |
826 * |GR1 |Stack pointer(SP) | - |
827 * |GR2 |Frame pointer(FP) | - |
828 * |GR3 |Hidden parameter | caller save |
829 * |GR4-GR7 | - | caller save |
830 * |GR8-GR13 |Argument register | caller save |
831 * |GR14-GR15 | - | caller save |
832 * |GR16-GR31 | - | callee save |
833 * |GR32-GR47 | - | caller save |
834 * |GR48-GR63 | - | callee save |
835 * |FR0-FR15 | - | caller save |
836 * |FR16-FR31 | - | callee save |
837 * |FR32-FR47 | - | caller save |
838 * |FR48-FR63 | - | callee save |
839 * +---------------+-----------------------+-----------------------+
843 * SP-> |-----------------------------------|
845 * |-----------------------------------|
846 * | Register save area |
847 * |-----------------------------------|
848 * | Local variable save area |
849 * FP-> |-----------------------------------|
851 * |-----------------------------------|
852 * | Hidden parameter save area |
853 * |-----------------------------------|
854 * | Return address(LR) storage area |
855 * |-----------------------------------|
856 * | Padding for alignment |
857 * |-----------------------------------|
858 * | Register argument area |
859 * OLD SP-> |-----------------------------------|
861 * |-----------------------------------|
864 * Argument area/Parameter area:
866 * When a function is called, this area is used for argument transfer. When
867 * the argument is set up by the caller function, this area is referred to as
868 * the argument area. When the argument is referenced by the callee function,
869 * this area is referred to as the parameter area. The area is allocated when
870 * all arguments cannot be placed on the argument register at the time of
873 * Register save area:
875 * This is a register save area that must be guaranteed for the caller
876 * function. This area is not secured when the register save operation is not
879 * Local variable save area:
881 * This is the area for local variables and temporary variables.
885 * This area stores the FP value of the caller function.
887 * Hidden parameter save area:
889 * This area stores the start address of the return value storage
890 * area for a struct/union return function.
891 * When a struct/union is used as the return value, the caller
892 * function stores the return value storage area start address in
893 * register GR3 and passes it to the caller function.
894 * The callee function interprets the address stored in the GR3
895 * as the return value storage area start address.
896 * When register GR3 needs to be saved into memory, the callee
897 * function saves it in the hidden parameter save area. This
898 * area is not secured when the save operation is not needed.
900 * Return address(LR) storage area:
902 * This area saves the LR. The LR stores the address of a return to the caller
903 * function for the purpose of function calling.
905 * Argument register area:
907 * This area saves the argument register. This area is not secured when the
908 * save operation is not needed.
912 * Arguments, the count of which equals the count of argument registers (6
913 * words), are positioned in registers GR8 to GR13 and delivered to the callee
914 * function. When a struct/union return function is called, the return value
915 * area address is stored in register GR3. Arguments not placed in the
916 * argument registers will be stored in the stack argument area for transfer
917 * purposes. When an 8-byte type argument is to be delivered using registers,
918 * it is divided into two and placed in two registers for transfer. When
919 * argument registers must be saved to memory, the callee function secures an
920 * argument register save area in the stack. In this case, a continuous
921 * argument register save area must be established in the parameter area. The
922 * argument register save area must be allocated as needed to cover the size of
923 * the argument register to be saved. If the function has a variable count of
924 * arguments, it saves all argument registers in the argument register save
927 * Argument Extension Format:
929 * When an argument is to be stored in the stack, its type is converted to an
930 * extended type in accordance with the individual argument type. The argument
931 * is freed by the caller function after the return from the callee function is
934 * +-----------------------+---------------+------------------------+
935 * | Argument Type |Extended Type |Stack Storage Size(byte)|
936 * +-----------------------+---------------+------------------------+
938 * |signed char |int | 4 |
939 * |unsigned char |int | 4 |
940 * |[signed] short int |int | 4 |
941 * |unsigned short int |int | 4 |
942 * |[signed] int |No extension | 4 |
943 * |unsigned int |No extension | 4 |
944 * |[signed] long int |No extension | 4 |
945 * |unsigned long int |No extension | 4 |
946 * |[signed] long long int |No extension | 8 |
947 * |unsigned long long int |No extension | 8 |
948 * |float |double | 8 |
949 * |double |No extension | 8 |
950 * |long double |No extension | 8 |
951 * |pointer |No extension | 4 |
952 * |struct/union |- | 4 (*1) |
953 * +-----------------------+---------------+------------------------+
955 * When a struct/union is to be delivered as an argument, the caller copies it
956 * to the local variable area and delivers the address of that area.
960 * +-------------------------------+----------------------+
961 * |Return Value Type |Return Value Interface|
962 * +-------------------------------+----------------------+
964 * |[signed|unsigned] char |GR8 |
965 * |[signed|unsigned] short int |GR8 |
966 * |[signed|unsigned] int |GR8 |
967 * |[signed|unsigned] long int |GR8 |
969 * |[signed|unsigned] long long int|GR8 & GR9 |
971 * |double |GR8 & GR9 |
972 * |long double |GR8 & GR9 |
973 * |struct/union |(*1) |
974 * +-------------------------------+----------------------+
976 * When a struct/union is used as the return value, the caller function stores
977 * the start address of the return value storage area into GR3 and then passes
978 * it to the callee function. The callee function interprets GR3 as the start
979 * address of the return value storage area. When this address needs to be
980 * saved in memory, the callee function secures the hidden parameter save area
981 * and saves the address in that area.
985 frv_stack_info (void)
987 static frv_stack_t info
, zero_info
;
988 frv_stack_t
*info_ptr
= &info
;
989 tree fndecl
= current_function_decl
;
997 /* If we've already calculated the values and reload is complete,
1000 return frv_stack_cache
;
1002 /* Zero all fields. */
1005 /* Set up the register range information. */
1006 info_ptr
->regs
[STACK_REGS_GPR
].name
= "gpr";
1007 info_ptr
->regs
[STACK_REGS_GPR
].first
= LAST_ARG_REGNUM
+ 1;
1008 info_ptr
->regs
[STACK_REGS_GPR
].last
= GPR_LAST
;
1009 info_ptr
->regs
[STACK_REGS_GPR
].dword_p
= TRUE
;
1011 info_ptr
->regs
[STACK_REGS_FPR
].name
= "fpr";
1012 info_ptr
->regs
[STACK_REGS_FPR
].first
= FPR_FIRST
;
1013 info_ptr
->regs
[STACK_REGS_FPR
].last
= FPR_LAST
;
1014 info_ptr
->regs
[STACK_REGS_FPR
].dword_p
= TRUE
;
1016 info_ptr
->regs
[STACK_REGS_LR
].name
= "lr";
1017 info_ptr
->regs
[STACK_REGS_LR
].first
= LR_REGNO
;
1018 info_ptr
->regs
[STACK_REGS_LR
].last
= LR_REGNO
;
1019 info_ptr
->regs
[STACK_REGS_LR
].special_p
= 1;
1021 info_ptr
->regs
[STACK_REGS_CC
].name
= "cc";
1022 info_ptr
->regs
[STACK_REGS_CC
].first
= CC_FIRST
;
1023 info_ptr
->regs
[STACK_REGS_CC
].last
= CC_LAST
;
1024 info_ptr
->regs
[STACK_REGS_CC
].field_p
= TRUE
;
1026 info_ptr
->regs
[STACK_REGS_LCR
].name
= "lcr";
1027 info_ptr
->regs
[STACK_REGS_LCR
].first
= LCR_REGNO
;
1028 info_ptr
->regs
[STACK_REGS_LCR
].last
= LCR_REGNO
;
1030 info_ptr
->regs
[STACK_REGS_STDARG
].name
= "stdarg";
1031 info_ptr
->regs
[STACK_REGS_STDARG
].first
= FIRST_ARG_REGNUM
;
1032 info_ptr
->regs
[STACK_REGS_STDARG
].last
= LAST_ARG_REGNUM
;
1033 info_ptr
->regs
[STACK_REGS_STDARG
].dword_p
= 1;
1034 info_ptr
->regs
[STACK_REGS_STDARG
].special_p
= 1;
1036 info_ptr
->regs
[STACK_REGS_STRUCT
].name
= "struct";
1037 info_ptr
->regs
[STACK_REGS_STRUCT
].first
= FRV_STRUCT_VALUE_REGNUM
;
1038 info_ptr
->regs
[STACK_REGS_STRUCT
].last
= FRV_STRUCT_VALUE_REGNUM
;
1039 info_ptr
->regs
[STACK_REGS_STRUCT
].special_p
= 1;
1041 info_ptr
->regs
[STACK_REGS_FP
].name
= "fp";
1042 info_ptr
->regs
[STACK_REGS_FP
].first
= FRAME_POINTER_REGNUM
;
1043 info_ptr
->regs
[STACK_REGS_FP
].last
= FRAME_POINTER_REGNUM
;
1044 info_ptr
->regs
[STACK_REGS_FP
].special_p
= 1;
1046 /* Determine if this is a stdarg function. If so, allocate space to store
1053 /* Find the last argument, and see if it is __builtin_va_alist. */
1054 for (cur_arg
= DECL_ARGUMENTS (fndecl
); cur_arg
!= (tree
)0; cur_arg
= next_arg
)
1056 next_arg
= DECL_CHAIN (cur_arg
);
1057 if (next_arg
== (tree
)0)
1059 if (DECL_NAME (cur_arg
)
1060 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg
)), "__builtin_va_alist"))
1068 /* Iterate over all of the register ranges. */
1069 for (range
= 0; range
< STACK_REGS_MAX
; range
++)
1071 frv_stack_regs_t
*reg_ptr
= &(info_ptr
->regs
[range
]);
1072 int first
= reg_ptr
->first
;
1073 int last
= reg_ptr
->last
;
1075 int size_2words
= 0;
1078 /* Calculate which registers need to be saved & save area size. */
1082 for (regno
= first
; regno
<= last
; regno
++)
1084 if ((df_regs_ever_live_p (regno
) && !call_used_regs
[regno
])
1085 || (crtl
->calls_eh_return
1086 && (regno
>= FIRST_EH_REGNUM
&& regno
<= LAST_EH_REGNUM
))
1087 || (!TARGET_FDPIC
&& flag_pic
1088 && crtl
->uses_pic_offset_table
&& regno
== PIC_REGNO
))
1090 info_ptr
->save_p
[regno
] = REG_SAVE_1WORD
;
1091 size_1word
+= UNITS_PER_WORD
;
1096 /* Calculate whether we need to create a frame after everything else
1097 has been processed. */
1102 if (df_regs_ever_live_p (LR_REGNO
)
1104 /* This is set for __builtin_return_address, etc. */
1105 || cfun
->machine
->frame_needed
1106 || (TARGET_LINKED_FP
&& frame_pointer_needed
)
1107 || (!TARGET_FDPIC
&& flag_pic
1108 && crtl
->uses_pic_offset_table
))
1110 info_ptr
->save_p
[LR_REGNO
] = REG_SAVE_1WORD
;
1111 size_1word
+= UNITS_PER_WORD
;
1115 case STACK_REGS_STDARG
:
1118 /* If this is a stdarg function with a non varardic
1119 argument split between registers and the stack,
1120 adjust the saved registers downward. */
1121 last
-= (ADDR_ALIGN (crtl
->args
.pretend_args_size
, UNITS_PER_WORD
)
1124 for (regno
= first
; regno
<= last
; regno
++)
1126 info_ptr
->save_p
[regno
] = REG_SAVE_1WORD
;
1127 size_1word
+= UNITS_PER_WORD
;
1130 info_ptr
->stdarg_size
= size_1word
;
1134 case STACK_REGS_STRUCT
:
1135 if (cfun
->returns_struct
)
1137 info_ptr
->save_p
[FRV_STRUCT_VALUE_REGNUM
] = REG_SAVE_1WORD
;
1138 size_1word
+= UNITS_PER_WORD
;
1146 /* If this is a field, it only takes one word. */
1147 if (reg_ptr
->field_p
)
1148 size_1word
= UNITS_PER_WORD
;
1150 /* Determine which register pairs can be saved together. */
1151 else if (reg_ptr
->dword_p
&& TARGET_DWORD
)
1153 for (regno
= first
; regno
< last
; regno
+= 2)
1155 if (info_ptr
->save_p
[regno
] && info_ptr
->save_p
[regno
+1])
1157 size_2words
+= 2 * UNITS_PER_WORD
;
1158 size_1word
-= 2 * UNITS_PER_WORD
;
1159 info_ptr
->save_p
[regno
] = REG_SAVE_2WORDS
;
1160 info_ptr
->save_p
[regno
+1] = REG_SAVE_NO_SAVE
;
1165 reg_ptr
->size_1word
= size_1word
;
1166 reg_ptr
->size_2words
= size_2words
;
1168 if (! reg_ptr
->special_p
)
1170 info_ptr
->regs_size_1word
+= size_1word
;
1171 info_ptr
->regs_size_2words
+= size_2words
;
1176 /* Set up the sizes of each field in the frame body, making the sizes
1177 of each be divisible by the size of a dword if dword operations might
1178 be used, or the size of a word otherwise. */
1179 alignment
= (TARGET_DWORD
? 2 * UNITS_PER_WORD
: UNITS_PER_WORD
);
1181 info_ptr
->parameter_size
= ADDR_ALIGN (crtl
->outgoing_args_size
, alignment
);
1182 info_ptr
->regs_size
= ADDR_ALIGN (info_ptr
->regs_size_2words
1183 + info_ptr
->regs_size_1word
,
1185 info_ptr
->vars_size
= ADDR_ALIGN (get_frame_size (), alignment
);
1187 info_ptr
->pretend_size
= crtl
->args
.pretend_args_size
;
1189 /* Work out the size of the frame, excluding the header. Both the frame
1190 body and register parameter area will be dword-aligned. */
1191 info_ptr
->total_size
1192 = (ADDR_ALIGN (info_ptr
->parameter_size
1193 + info_ptr
->regs_size
1194 + info_ptr
->vars_size
,
1196 + ADDR_ALIGN (info_ptr
->pretend_size
1197 + info_ptr
->stdarg_size
,
1198 2 * UNITS_PER_WORD
));
1200 /* See if we need to create a frame at all, if so add header area. */
1201 if (info_ptr
->total_size
> 0
1202 || frame_pointer_needed
1203 || info_ptr
->regs
[STACK_REGS_LR
].size_1word
> 0
1204 || info_ptr
->regs
[STACK_REGS_STRUCT
].size_1word
> 0)
1206 offset
= info_ptr
->parameter_size
;
1207 info_ptr
->header_size
= 4 * UNITS_PER_WORD
;
1208 info_ptr
->total_size
+= 4 * UNITS_PER_WORD
;
1210 /* Calculate the offsets to save normal register pairs. */
1211 for (range
= 0; range
< STACK_REGS_MAX
; range
++)
1213 frv_stack_regs_t
*reg_ptr
= &(info_ptr
->regs
[range
]);
1214 if (! reg_ptr
->special_p
)
1216 int first
= reg_ptr
->first
;
1217 int last
= reg_ptr
->last
;
1220 for (regno
= first
; regno
<= last
; regno
++)
1221 if (info_ptr
->save_p
[regno
] == REG_SAVE_2WORDS
1222 && regno
!= FRAME_POINTER_REGNUM
1223 && (regno
< FIRST_ARG_REGNUM
1224 || regno
> LAST_ARG_REGNUM
))
1226 info_ptr
->reg_offset
[regno
] = offset
;
1227 offset
+= 2 * UNITS_PER_WORD
;
1232 /* Calculate the offsets to save normal single registers. */
1233 for (range
= 0; range
< STACK_REGS_MAX
; range
++)
1235 frv_stack_regs_t
*reg_ptr
= &(info_ptr
->regs
[range
]);
1236 if (! reg_ptr
->special_p
)
1238 int first
= reg_ptr
->first
;
1239 int last
= reg_ptr
->last
;
1242 for (regno
= first
; regno
<= last
; regno
++)
1243 if (info_ptr
->save_p
[regno
] == REG_SAVE_1WORD
1244 && regno
!= FRAME_POINTER_REGNUM
1245 && (regno
< FIRST_ARG_REGNUM
1246 || regno
> LAST_ARG_REGNUM
))
1248 info_ptr
->reg_offset
[regno
] = offset
;
1249 offset
+= UNITS_PER_WORD
;
1254 /* Calculate the offset to save the local variables at. */
1255 offset
= ADDR_ALIGN (offset
, alignment
);
1256 if (info_ptr
->vars_size
)
1258 info_ptr
->vars_offset
= offset
;
1259 offset
+= info_ptr
->vars_size
;
1262 /* Align header to a dword-boundary. */
1263 offset
= ADDR_ALIGN (offset
, 2 * UNITS_PER_WORD
);
1265 /* Calculate the offsets in the fixed frame. */
1266 info_ptr
->save_p
[FRAME_POINTER_REGNUM
] = REG_SAVE_1WORD
;
1267 info_ptr
->reg_offset
[FRAME_POINTER_REGNUM
] = offset
;
1268 info_ptr
->regs
[STACK_REGS_FP
].size_1word
= UNITS_PER_WORD
;
1270 info_ptr
->save_p
[LR_REGNO
] = REG_SAVE_1WORD
;
1271 info_ptr
->reg_offset
[LR_REGNO
] = offset
+ 2*UNITS_PER_WORD
;
1272 info_ptr
->regs
[STACK_REGS_LR
].size_1word
= UNITS_PER_WORD
;
1274 if (cfun
->returns_struct
)
1276 info_ptr
->save_p
[FRV_STRUCT_VALUE_REGNUM
] = REG_SAVE_1WORD
;
1277 info_ptr
->reg_offset
[FRV_STRUCT_VALUE_REGNUM
] = offset
+ UNITS_PER_WORD
;
1278 info_ptr
->regs
[STACK_REGS_STRUCT
].size_1word
= UNITS_PER_WORD
;
1281 /* Calculate the offsets to store the arguments passed in registers
1282 for stdarg functions. The register pairs are first and the single
1283 register if any is last. The register save area starts on a
1285 if (info_ptr
->stdarg_size
)
1287 int first
= info_ptr
->regs
[STACK_REGS_STDARG
].first
;
1288 int last
= info_ptr
->regs
[STACK_REGS_STDARG
].last
;
1291 /* Skip the header. */
1292 offset
+= 4 * UNITS_PER_WORD
;
1293 for (regno
= first
; regno
<= last
; regno
++)
1295 if (info_ptr
->save_p
[regno
] == REG_SAVE_2WORDS
)
1297 info_ptr
->reg_offset
[regno
] = offset
;
1298 offset
+= 2 * UNITS_PER_WORD
;
1300 else if (info_ptr
->save_p
[regno
] == REG_SAVE_1WORD
)
1302 info_ptr
->reg_offset
[regno
] = offset
;
1303 offset
+= UNITS_PER_WORD
;
1309 if (reload_completed
)
1310 frv_stack_cache
= info_ptr
;
1316 /* Print the information about the frv stack offsets, etc. when debugging. */
1319 frv_debug_stack (frv_stack_t
*info
)
1324 info
= frv_stack_info ();
1326 fprintf (stderr
, "\nStack information for function %s:\n",
1327 ((current_function_decl
&& DECL_NAME (current_function_decl
))
1328 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl
))
1331 fprintf (stderr
, "\ttotal_size\t= %6d\n", info
->total_size
);
1332 fprintf (stderr
, "\tvars_size\t= %6d\n", info
->vars_size
);
1333 fprintf (stderr
, "\tparam_size\t= %6d\n", info
->parameter_size
);
1334 fprintf (stderr
, "\tregs_size\t= %6d, 1w = %3d, 2w = %3d\n",
1335 info
->regs_size
, info
->regs_size_1word
, info
->regs_size_2words
);
1337 fprintf (stderr
, "\theader_size\t= %6d\n", info
->header_size
);
1338 fprintf (stderr
, "\tpretend_size\t= %6d\n", info
->pretend_size
);
1339 fprintf (stderr
, "\tvars_offset\t= %6d\n", info
->vars_offset
);
1340 fprintf (stderr
, "\tregs_offset\t= %6d\n", info
->regs_offset
);
1342 for (range
= 0; range
< STACK_REGS_MAX
; range
++)
1344 frv_stack_regs_t
*regs
= &(info
->regs
[range
]);
1345 if ((regs
->size_1word
+ regs
->size_2words
) > 0)
1347 int first
= regs
->first
;
1348 int last
= regs
->last
;
1351 fprintf (stderr
, "\t%s\tsize\t= %6d, 1w = %3d, 2w = %3d, save =",
1352 regs
->name
, regs
->size_1word
+ regs
->size_2words
,
1353 regs
->size_1word
, regs
->size_2words
);
1355 for (regno
= first
; regno
<= last
; regno
++)
1357 if (info
->save_p
[regno
] == REG_SAVE_1WORD
)
1358 fprintf (stderr
, " %s (%d)", reg_names
[regno
],
1359 info
->reg_offset
[regno
]);
1361 else if (info
->save_p
[regno
] == REG_SAVE_2WORDS
)
1362 fprintf (stderr
, " %s-%s (%d)", reg_names
[regno
],
1363 reg_names
[regno
+1], info
->reg_offset
[regno
]);
1366 fputc ('\n', stderr
);
1376 /* Used during final to control the packing of insns. The value is
1377 1 if the current instruction should be packed with the next one,
1378 0 if it shouldn't or -1 if packing is disabled altogether. */
1380 static int frv_insn_packing_flag
;
1382 /* True if the current function contains a far jump. */
1385 frv_function_contains_far_jump (void)
1387 rtx_insn
*insn
= get_insns ();
1390 && get_attr_far_jump (insn
) == FAR_JUMP_YES
))
1391 insn
= NEXT_INSN (insn
);
1392 return (insn
!= NULL
);
1395 /* For the FRV, this function makes sure that a function with far jumps
1396 will return correctly. It also does the VLIW packing. */
1399 frv_function_prologue (FILE *file
, HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
1401 rtx_insn
*insn
, *next
, *last_call
;
1403 /* If no frame was created, check whether the function uses a call
1404 instruction to implement a far jump. If so, save the link in gr3 and
1405 replace all returns to LR with returns to GR3. GR3 is used because it
1406 is call-clobbered, because is not available to the register allocator,
1407 and because all functions that take a hidden argument pointer will have
1409 if (frv_stack_info ()->total_size
== 0 && frv_function_contains_far_jump ())
1413 /* Just to check that the above comment is true. */
1414 gcc_assert (!df_regs_ever_live_p (GPR_FIRST
+ 3));
1416 /* Generate the instruction that saves the link register. */
1417 fprintf (file
, "\tmovsg lr,gr3\n");
1419 /* Replace the LR with GR3 in *return_internal patterns. The insn
1420 will now return using jmpl @(gr3,0) rather than bralr. We cannot
1421 simply emit a different assembly directive because bralr and jmpl
1422 execute in different units. */
1423 for (insn
= get_insns(); insn
!= NULL
; insn
= NEXT_INSN (insn
))
1426 rtx pattern
= PATTERN (insn
);
1427 if (GET_CODE (pattern
) == PARALLEL
1428 && XVECLEN (pattern
, 0) >= 2
1429 && GET_CODE (XVECEXP (pattern
, 0, 0)) == RETURN
1430 && GET_CODE (XVECEXP (pattern
, 0, 1)) == USE
)
1432 rtx address
= XEXP (XVECEXP (pattern
, 0, 1), 0);
1433 if (GET_CODE (address
) == REG
&& REGNO (address
) == LR_REGNO
)
1434 SET_REGNO (address
, GPR_FIRST
+ 3);
1441 /* Allow the garbage collector to free the nops created by frv_reorg. */
1442 memset (frv_nops
, 0, sizeof (frv_nops
));
1444 /* Locate CALL_ARG_LOCATION notes that have been misplaced
1445 and move them back to where they should be located. */
1447 for (insn
= get_insns (); insn
; insn
= next
)
1449 next
= NEXT_INSN (insn
);
1451 || (INSN_P (insn
) && GET_CODE (PATTERN (insn
)) == SEQUENCE
1452 && CALL_P (XVECEXP (PATTERN (insn
), 0, 0))))
1455 if (!NOTE_P (insn
) || NOTE_KIND (insn
) != NOTE_INSN_CALL_ARG_LOCATION
)
1458 if (NEXT_INSN (last_call
) == insn
)
1461 SET_NEXT_INSN (PREV_INSN (insn
)) = NEXT_INSN (insn
);
1462 SET_PREV_INSN (NEXT_INSN (insn
)) = PREV_INSN (insn
);
1463 SET_PREV_INSN (insn
) = last_call
;
1464 SET_NEXT_INSN (insn
) = NEXT_INSN (last_call
);
1465 SET_PREV_INSN (NEXT_INSN (insn
)) = insn
;
1466 SET_NEXT_INSN (PREV_INSN (insn
)) = insn
;
1472 /* Return the next available temporary register in a given class. */
1475 frv_alloc_temp_reg (
1476 frv_tmp_reg_t
*info
, /* which registers are available */
1477 enum reg_class rclass
, /* register class desired */
1478 machine_mode mode
, /* mode to allocate register with */
1479 int mark_as_used
, /* register not available after allocation */
1480 int no_abort
) /* return NULL instead of aborting */
1482 int regno
= info
->next_reg
[ (int)rclass
];
1483 int orig_regno
= regno
;
1484 HARD_REG_SET
*reg_in_class
= ®_class_contents
[ (int)rclass
];
1489 if (TEST_HARD_REG_BIT (*reg_in_class
, regno
)
1490 && TEST_HARD_REG_BIT (info
->regs
, regno
))
1493 if (++regno
>= FIRST_PSEUDO_REGISTER
)
1495 if (regno
== orig_regno
)
1497 gcc_assert (no_abort
);
1502 nr
= HARD_REGNO_NREGS (regno
, mode
);
1503 info
->next_reg
[ (int)rclass
] = regno
+ nr
;
1506 for (i
= 0; i
< nr
; i
++)
1507 CLEAR_HARD_REG_BIT (info
->regs
, regno
+i
);
1509 return gen_rtx_REG (mode
, regno
);
1513 /* Return an rtx with the value OFFSET, which will either be a register or a
1514 signed 12-bit integer. It can be used as the second operand in an "add"
1515 instruction, or as the index in a load or store.
1517 The function returns a constant rtx if OFFSET is small enough, otherwise
1518 it loads the constant into register OFFSET_REGNO and returns that. */
1520 frv_frame_offset_rtx (int offset
)
1522 rtx offset_rtx
= GEN_INT (offset
);
1523 if (IN_RANGE (offset
, -2048, 2047))
1527 rtx reg_rtx
= gen_rtx_REG (SImode
, OFFSET_REGNO
);
1528 if (IN_RANGE (offset
, -32768, 32767))
1529 emit_insn (gen_movsi (reg_rtx
, offset_rtx
));
1532 emit_insn (gen_movsi_high (reg_rtx
, offset_rtx
));
1533 emit_insn (gen_movsi_lo_sum (reg_rtx
, offset_rtx
));
1539 /* Generate (mem:MODE (plus:Pmode BASE (frv_frame_offset OFFSET)))). The
1540 prologue and epilogue uses such expressions to access the stack. */
1542 frv_frame_mem (machine_mode mode
, rtx base
, int offset
)
1544 return gen_rtx_MEM (mode
, gen_rtx_PLUS (Pmode
,
1546 frv_frame_offset_rtx (offset
)));
1549 /* Generate a frame-related expression:
1551 (set REG (mem (plus (sp) (const_int OFFSET)))).
1553 Such expressions are used in FRAME_RELATED_EXPR notes for more complex
1554 instructions. Marking the expressions as frame-related is superfluous if
1555 the note contains just a single set. But if the note contains a PARALLEL
1556 or SEQUENCE that has several sets, each set must be individually marked
1557 as frame-related. */
1559 frv_dwarf_store (rtx reg
, int offset
)
1561 rtx set
= gen_rtx_SET (gen_rtx_MEM (GET_MODE (reg
),
1562 plus_constant (Pmode
, stack_pointer_rtx
,
1565 RTX_FRAME_RELATED_P (set
) = 1;
1569 /* Emit a frame-related instruction whose pattern is PATTERN. The
1570 instruction is the last in a sequence that cumulatively performs the
1571 operation described by DWARF_PATTERN. The instruction is marked as
1572 frame-related and has a REG_FRAME_RELATED_EXPR note containing
1575 frv_frame_insn (rtx pattern
, rtx dwarf_pattern
)
1577 rtx insn
= emit_insn (pattern
);
1578 RTX_FRAME_RELATED_P (insn
) = 1;
1579 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
1584 /* Emit instructions that transfer REG to or from the memory location (sp +
1585 STACK_OFFSET). The register is stored in memory if ACCESSOR->OP is
1586 FRV_STORE and loaded if it is FRV_LOAD. Only the prologue uses this
1587 function to store registers and only the epilogue uses it to load them.
1589 The caller sets up ACCESSOR so that BASE is equal to (sp + BASE_OFFSET).
1590 The generated instruction will use BASE as its base register. BASE may
1591 simply be the stack pointer, but if several accesses are being made to a
1592 region far away from the stack pointer, it may be more efficient to set
1593 up a temporary instead.
1595 Store instructions will be frame-related and will be annotated with the
1596 overall effect of the store. Load instructions will be followed by a
1597 (use) to prevent later optimizations from zapping them.
1599 The function takes care of the moves to and from SPRs, using TEMP_REGNO
1600 as a temporary in such cases. */
1602 frv_frame_access (frv_frame_accessor_t
*accessor
, rtx reg
, int stack_offset
)
1604 machine_mode mode
= GET_MODE (reg
);
1605 rtx mem
= frv_frame_mem (mode
,
1607 stack_offset
- accessor
->base_offset
);
1609 if (accessor
->op
== FRV_LOAD
)
1611 if (SPR_P (REGNO (reg
)))
1613 rtx temp
= gen_rtx_REG (mode
, TEMP_REGNO
);
1614 emit_insn (gen_rtx_SET (temp
, mem
));
1615 emit_insn (gen_rtx_SET (reg
, temp
));
1619 /* We cannot use reg+reg addressing for DImode access. */
1621 && GET_CODE (XEXP (mem
, 0)) == PLUS
1622 && GET_CODE (XEXP (XEXP (mem
, 0), 0)) == REG
1623 && GET_CODE (XEXP (XEXP (mem
, 0), 1)) == REG
)
1625 rtx temp
= gen_rtx_REG (SImode
, TEMP_REGNO
);
1627 emit_move_insn (temp
,
1628 gen_rtx_PLUS (SImode
, XEXP (XEXP (mem
, 0), 0),
1629 XEXP (XEXP (mem
, 0), 1)));
1630 mem
= gen_rtx_MEM (DImode
, temp
);
1632 emit_insn (gen_rtx_SET (reg
, mem
));
1638 if (SPR_P (REGNO (reg
)))
1640 rtx temp
= gen_rtx_REG (mode
, TEMP_REGNO
);
1641 emit_insn (gen_rtx_SET (temp
, reg
));
1642 frv_frame_insn (gen_rtx_SET (mem
, temp
),
1643 frv_dwarf_store (reg
, stack_offset
));
1645 else if (mode
== DImode
)
1647 /* For DImode saves, the dwarf2 version needs to be a SEQUENCE
1648 with a separate save for each register. */
1649 rtx reg1
= gen_rtx_REG (SImode
, REGNO (reg
));
1650 rtx reg2
= gen_rtx_REG (SImode
, REGNO (reg
) + 1);
1651 rtx set1
= frv_dwarf_store (reg1
, stack_offset
);
1652 rtx set2
= frv_dwarf_store (reg2
, stack_offset
+ 4);
1654 /* Also we cannot use reg+reg addressing. */
1655 if (GET_CODE (XEXP (mem
, 0)) == PLUS
1656 && GET_CODE (XEXP (XEXP (mem
, 0), 0)) == REG
1657 && GET_CODE (XEXP (XEXP (mem
, 0), 1)) == REG
)
1659 rtx temp
= gen_rtx_REG (SImode
, TEMP_REGNO
);
1660 emit_move_insn (temp
,
1661 gen_rtx_PLUS (SImode
, XEXP (XEXP (mem
, 0), 0),
1662 XEXP (XEXP (mem
, 0), 1)));
1663 mem
= gen_rtx_MEM (DImode
, temp
);
1666 frv_frame_insn (gen_rtx_SET (mem
, reg
),
1667 gen_rtx_PARALLEL (VOIDmode
,
1668 gen_rtvec (2, set1
, set2
)));
1671 frv_frame_insn (gen_rtx_SET (mem
, reg
),
1672 frv_dwarf_store (reg
, stack_offset
));
1676 /* A function that uses frv_frame_access to transfer a group of registers to
1677 or from the stack. ACCESSOR is passed directly to frv_frame_access, INFO
1678 is the stack information generated by frv_stack_info, and REG_SET is the
1679 number of the register set to transfer. */
1681 frv_frame_access_multi (frv_frame_accessor_t
*accessor
,
1685 frv_stack_regs_t
*regs_info
;
1688 regs_info
= &info
->regs
[reg_set
];
1689 for (regno
= regs_info
->first
; regno
<= regs_info
->last
; regno
++)
1690 if (info
->save_p
[regno
])
1691 frv_frame_access (accessor
,
1692 info
->save_p
[regno
] == REG_SAVE_2WORDS
1693 ? gen_rtx_REG (DImode
, regno
)
1694 : gen_rtx_REG (SImode
, regno
),
1695 info
->reg_offset
[regno
]);
1698 /* Save or restore callee-saved registers that are kept outside the frame
1699 header. The function saves the registers if OP is FRV_STORE and restores
1700 them if OP is FRV_LOAD. INFO is the stack information generated by
1703 frv_frame_access_standard_regs (enum frv_stack_op op
, frv_stack_t
*info
)
1705 frv_frame_accessor_t accessor
;
1708 accessor
.base
= stack_pointer_rtx
;
1709 accessor
.base_offset
= 0;
1710 frv_frame_access_multi (&accessor
, info
, STACK_REGS_GPR
);
1711 frv_frame_access_multi (&accessor
, info
, STACK_REGS_FPR
);
1712 frv_frame_access_multi (&accessor
, info
, STACK_REGS_LCR
);
1716 /* Called after register allocation to add any instructions needed for the
1717 prologue. Using a prologue insn is favored compared to putting all of the
1718 instructions in the TARGET_ASM_FUNCTION_PROLOGUE target hook, since
1719 it allows the scheduler to intermix instructions with the saves of
1720 the caller saved registers. In some cases, it might be necessary
1721 to emit a barrier instruction as the last insn to prevent such
1724 Also any insns generated here should have RTX_FRAME_RELATED_P(insn) = 1
1725 so that the debug info generation code can handle them properly. */
1727 frv_expand_prologue (void)
1729 frv_stack_t
*info
= frv_stack_info ();
1730 rtx sp
= stack_pointer_rtx
;
1731 rtx fp
= frame_pointer_rtx
;
1732 frv_frame_accessor_t accessor
;
1734 if (TARGET_DEBUG_STACK
)
1735 frv_debug_stack (info
);
1737 if (flag_stack_usage_info
)
1738 current_function_static_stack_size
= info
->total_size
;
1740 if (info
->total_size
== 0)
1743 /* We're interested in three areas of the frame here:
1745 A: the register save area
1747 C: the header after B
1749 If the frame pointer isn't used, we'll have to set up A, B and C
1750 using the stack pointer. If the frame pointer is used, we'll access
1754 B: set up using sp or a temporary (see below)
1757 We set up B using the stack pointer if the frame is small enough.
1758 Otherwise, it's more efficient to copy the old stack pointer into a
1759 temporary and use that.
1761 Note that it's important to make sure the prologue and epilogue use the
1762 same registers to access A and C, since doing otherwise will confuse
1763 the aliasing code. */
1765 /* Set up ACCESSOR for accessing region B above. If the frame pointer
1766 isn't used, the same method will serve for C. */
1767 accessor
.op
= FRV_STORE
;
1768 if (frame_pointer_needed
&& info
->total_size
> 2048)
1770 accessor
.base
= gen_rtx_REG (Pmode
, OLD_SP_REGNO
);
1771 accessor
.base_offset
= info
->total_size
;
1772 emit_insn (gen_movsi (accessor
.base
, sp
));
1776 accessor
.base
= stack_pointer_rtx
;
1777 accessor
.base_offset
= 0;
1780 /* Allocate the stack space. */
1782 rtx asm_offset
= frv_frame_offset_rtx (-info
->total_size
);
1783 rtx dwarf_offset
= GEN_INT (-info
->total_size
);
1785 frv_frame_insn (gen_stack_adjust (sp
, sp
, asm_offset
),
1786 gen_rtx_SET (sp
, gen_rtx_PLUS (Pmode
, sp
, dwarf_offset
)));
1789 /* If the frame pointer is needed, store the old one at (sp + FP_OFFSET)
1790 and point the new one to that location. */
1791 if (frame_pointer_needed
)
1793 int fp_offset
= info
->reg_offset
[FRAME_POINTER_REGNUM
];
1795 /* ASM_SRC and DWARF_SRC both point to the frame header. ASM_SRC is
1796 based on ACCESSOR.BASE but DWARF_SRC is always based on the stack
1798 rtx asm_src
= plus_constant (Pmode
, accessor
.base
,
1799 fp_offset
- accessor
.base_offset
);
1800 rtx dwarf_src
= plus_constant (Pmode
, sp
, fp_offset
);
1802 /* Store the old frame pointer at (sp + FP_OFFSET). */
1803 frv_frame_access (&accessor
, fp
, fp_offset
);
1805 /* Set up the new frame pointer. */
1806 frv_frame_insn (gen_rtx_SET (fp
, asm_src
),
1807 gen_rtx_SET (fp
, dwarf_src
));
1809 /* Access region C from the frame pointer. */
1811 accessor
.base_offset
= fp_offset
;
1814 /* Set up region C. */
1815 frv_frame_access_multi (&accessor
, info
, STACK_REGS_STRUCT
);
1816 frv_frame_access_multi (&accessor
, info
, STACK_REGS_LR
);
1817 frv_frame_access_multi (&accessor
, info
, STACK_REGS_STDARG
);
1819 /* Set up region A. */
1820 frv_frame_access_standard_regs (FRV_STORE
, info
);
1822 /* If this is a varargs/stdarg function, issue a blockage to prevent the
1823 scheduler from moving loads before the stores saving the registers. */
1824 if (info
->stdarg_size
> 0)
1825 emit_insn (gen_blockage ());
1827 /* Set up pic register/small data register for this function. */
1828 if (!TARGET_FDPIC
&& flag_pic
&& crtl
->uses_pic_offset_table
)
1829 emit_insn (gen_pic_prologue (gen_rtx_REG (Pmode
, PIC_REGNO
),
1830 gen_rtx_REG (Pmode
, LR_REGNO
),
1831 gen_rtx_REG (SImode
, OFFSET_REGNO
)));
1835 /* Under frv, all of the work is done via frv_expand_epilogue, but
1836 this function provides a convenient place to do cleanup. */
1839 frv_function_epilogue (FILE *file ATTRIBUTE_UNUSED
,
1840 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
1842 frv_stack_cache
= (frv_stack_t
*)0;
1844 /* Zap last used registers for conditional execution. */
1845 memset (&frv_ifcvt
.tmp_reg
, 0, sizeof (frv_ifcvt
.tmp_reg
));
1847 /* Release the bitmap of created insns. */
1848 BITMAP_FREE (frv_ifcvt
.scratch_insns_bitmap
);
1852 /* Called after register allocation to add any instructions needed for the
1853 epilogue. Using an epilogue insn is favored compared to putting all of the
1854 instructions in the TARGET_ASM_FUNCTION_PROLOGUE target hook, since
1855 it allows the scheduler to intermix instructions with the saves of
1856 the caller saved registers. In some cases, it might be necessary
1857 to emit a barrier instruction as the last insn to prevent such
1861 frv_expand_epilogue (bool emit_return
)
1863 frv_stack_t
*info
= frv_stack_info ();
1864 rtx fp
= frame_pointer_rtx
;
1865 rtx sp
= stack_pointer_rtx
;
1869 fp_offset
= info
->reg_offset
[FRAME_POINTER_REGNUM
];
1871 /* Restore the stack pointer to its original value if alloca or the like
1873 if (! crtl
->sp_is_unchanging
)
1874 emit_insn (gen_addsi3 (sp
, fp
, frv_frame_offset_rtx (-fp_offset
)));
1876 /* Restore the callee-saved registers that were used in this function. */
1877 frv_frame_access_standard_regs (FRV_LOAD
, info
);
1879 /* Set RETURN_ADDR to the address we should return to. Set it to NULL if
1880 no return instruction should be emitted. */
1881 if (info
->save_p
[LR_REGNO
])
1886 /* Use the same method to access the link register's slot as we did in
1887 the prologue. In other words, use the frame pointer if available,
1888 otherwise use the stack pointer.
1890 LR_OFFSET is the offset of the link register's slot from the start
1891 of the frame and MEM is a memory rtx for it. */
1892 lr_offset
= info
->reg_offset
[LR_REGNO
];
1893 if (frame_pointer_needed
)
1894 mem
= frv_frame_mem (Pmode
, fp
, lr_offset
- fp_offset
);
1896 mem
= frv_frame_mem (Pmode
, sp
, lr_offset
);
1898 /* Load the old link register into a GPR. */
1899 return_addr
= gen_rtx_REG (Pmode
, TEMP_REGNO
);
1900 emit_insn (gen_rtx_SET (return_addr
, mem
));
1903 return_addr
= gen_rtx_REG (Pmode
, LR_REGNO
);
1905 /* Restore the old frame pointer. Emit a USE afterwards to make sure
1906 the load is preserved. */
1907 if (frame_pointer_needed
)
1909 emit_insn (gen_rtx_SET (fp
, gen_rtx_MEM (Pmode
, fp
)));
1913 /* Deallocate the stack frame. */
1914 if (info
->total_size
!= 0)
1916 rtx offset
= frv_frame_offset_rtx (info
->total_size
);
1917 emit_insn (gen_stack_adjust (sp
, sp
, offset
));
1920 /* If this function uses eh_return, add the final stack adjustment now. */
1921 if (crtl
->calls_eh_return
)
1922 emit_insn (gen_stack_adjust (sp
, sp
, EH_RETURN_STACKADJ_RTX
));
1925 emit_jump_insn (gen_epilogue_return (return_addr
));
1928 rtx lr
= return_addr
;
1930 if (REGNO (return_addr
) != LR_REGNO
)
1932 lr
= gen_rtx_REG (Pmode
, LR_REGNO
);
1933 emit_move_insn (lr
, return_addr
);
1941 /* Worker function for TARGET_ASM_OUTPUT_MI_THUNK. */
1944 frv_asm_output_mi_thunk (FILE *file
,
1945 tree thunk_fndecl ATTRIBUTE_UNUSED
,
1946 HOST_WIDE_INT delta
,
1947 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED
,
1950 const char *name_func
= XSTR (XEXP (DECL_RTL (function
), 0), 0);
1951 const char *name_arg0
= reg_names
[FIRST_ARG_REGNUM
];
1952 const char *name_jmp
= reg_names
[JUMP_REGNO
];
1953 const char *parallel
= (frv_issue_rate () > 1 ? ".p" : "");
1955 /* Do the add using an addi if possible. */
1956 if (IN_RANGE (delta
, -2048, 2047))
1957 fprintf (file
, "\taddi %s,#%d,%s\n", name_arg0
, (int) delta
, name_arg0
);
1960 const char *const name_add
= reg_names
[TEMP_REGNO
];
1961 fprintf (file
, "\tsethi%s #hi(" HOST_WIDE_INT_PRINT_DEC
"),%s\n",
1962 parallel
, delta
, name_add
);
1963 fprintf (file
, "\tsetlo #lo(" HOST_WIDE_INT_PRINT_DEC
"),%s\n",
1965 fprintf (file
, "\tadd %s,%s,%s\n", name_add
, name_arg0
, name_arg0
);
1970 const char *name_pic
= reg_names
[FDPIC_REGNO
];
1971 name_jmp
= reg_names
[FDPIC_FPTR_REGNO
];
1975 fprintf (file
, "\tsethi%s #gotofffuncdeschi(", parallel
);
1976 assemble_name (file
, name_func
);
1977 fprintf (file
, "),%s\n", name_jmp
);
1979 fprintf (file
, "\tsetlo #gotofffuncdesclo(");
1980 assemble_name (file
, name_func
);
1981 fprintf (file
, "),%s\n", name_jmp
);
1983 fprintf (file
, "\tldd @(%s,%s), %s\n", name_jmp
, name_pic
, name_jmp
);
1987 fprintf (file
, "\tlddo @(%s,#gotofffuncdesc12(", name_pic
);
1988 assemble_name (file
, name_func
);
1989 fprintf (file
, "\t)), %s\n", name_jmp
);
1994 fprintf (file
, "\tsethi%s #hi(", parallel
);
1995 assemble_name (file
, name_func
);
1996 fprintf (file
, "),%s\n", name_jmp
);
1998 fprintf (file
, "\tsetlo #lo(");
1999 assemble_name (file
, name_func
);
2000 fprintf (file
, "),%s\n", name_jmp
);
2004 /* Use JUMP_REGNO as a temporary PIC register. */
2005 const char *name_lr
= reg_names
[LR_REGNO
];
2006 const char *name_gppic
= name_jmp
;
2007 const char *name_tmp
= reg_names
[TEMP_REGNO
];
2009 fprintf (file
, "\tmovsg %s,%s\n", name_lr
, name_tmp
);
2010 fprintf (file
, "\tcall 1f\n");
2011 fprintf (file
, "1:\tmovsg %s,%s\n", name_lr
, name_gppic
);
2012 fprintf (file
, "\tmovgs %s,%s\n", name_tmp
, name_lr
);
2013 fprintf (file
, "\tsethi%s #gprelhi(1b),%s\n", parallel
, name_tmp
);
2014 fprintf (file
, "\tsetlo #gprello(1b),%s\n", name_tmp
);
2015 fprintf (file
, "\tsub %s,%s,%s\n", name_gppic
, name_tmp
, name_gppic
);
2017 fprintf (file
, "\tsethi%s #gprelhi(", parallel
);
2018 assemble_name (file
, name_func
);
2019 fprintf (file
, "),%s\n", name_tmp
);
2021 fprintf (file
, "\tsetlo #gprello(");
2022 assemble_name (file
, name_func
);
2023 fprintf (file
, "),%s\n", name_tmp
);
2025 fprintf (file
, "\tadd %s,%s,%s\n", name_gppic
, name_tmp
, name_jmp
);
2028 /* Jump to the function address. */
2029 fprintf (file
, "\tjmpl @(%s,%s)\n", name_jmp
, reg_names
[GPR_FIRST
+0]);
2034 /* On frv, create a frame whenever we need to create stack. */
2037 frv_frame_pointer_required (void)
2039 /* If we forgoing the usual linkage requirements, we only need
2040 a frame pointer if the stack pointer might change. */
2041 if (!TARGET_LINKED_FP
)
2042 return !crtl
->sp_is_unchanging
;
2044 if (! crtl
->is_leaf
)
2047 if (get_frame_size () != 0)
2053 if (!crtl
->sp_is_unchanging
)
2056 if (!TARGET_FDPIC
&& flag_pic
&& crtl
->uses_pic_offset_table
)
2062 if (cfun
->machine
->frame_needed
)
2069 /* Worker function for TARGET_CAN_ELIMINATE. */
2072 frv_can_eliminate (const int from
, const int to
)
2074 return (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
2075 ? ! frame_pointer_needed
2079 /* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'. It specifies the
2080 initial difference between the specified pair of registers. This macro must
2081 be defined if `ELIMINABLE_REGS' is defined. */
2083 /* See frv_stack_info for more details on the frv stack frame. */
2086 frv_initial_elimination_offset (int from
, int to
)
2088 frv_stack_t
*info
= frv_stack_info ();
2091 if (to
== STACK_POINTER_REGNUM
&& from
== ARG_POINTER_REGNUM
)
2092 ret
= info
->total_size
- info
->pretend_size
;
2094 else if (to
== STACK_POINTER_REGNUM
&& from
== FRAME_POINTER_REGNUM
)
2095 ret
= info
->reg_offset
[FRAME_POINTER_REGNUM
];
2097 else if (to
== FRAME_POINTER_REGNUM
&& from
== ARG_POINTER_REGNUM
)
2098 ret
= (info
->total_size
2099 - info
->reg_offset
[FRAME_POINTER_REGNUM
]
2100 - info
->pretend_size
);
2105 if (TARGET_DEBUG_STACK
)
2106 fprintf (stderr
, "Eliminate %s to %s by adding %d\n",
2107 reg_names
[from
], reg_names
[to
], ret
);
2113 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
2116 frv_setup_incoming_varargs (cumulative_args_t cum_v
,
2118 tree type ATTRIBUTE_UNUSED
,
2122 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
2124 if (TARGET_DEBUG_ARG
)
2126 "setup_vararg: words = %2d, mode = %4s, pretend_size = %d, second_time = %d\n",
2127 *cum
, GET_MODE_NAME (mode
), *pretend_size
, second_time
);
2131 /* Worker function for TARGET_EXPAND_BUILTIN_SAVEREGS. */
2134 frv_expand_builtin_saveregs (void)
2136 int offset
= UNITS_PER_WORD
* FRV_NUM_ARG_REGS
;
2138 if (TARGET_DEBUG_ARG
)
2139 fprintf (stderr
, "expand_builtin_saveregs: offset from ap = %d\n",
2142 return gen_rtx_PLUS (Pmode
, virtual_incoming_args_rtx
, GEN_INT (- offset
));
2146 /* Expand __builtin_va_start to do the va_start macro. */
2149 frv_expand_builtin_va_start (tree valist
, rtx nextarg
)
2152 int num
= crtl
->args
.info
- FIRST_ARG_REGNUM
- FRV_NUM_ARG_REGS
;
2154 nextarg
= gen_rtx_PLUS (Pmode
, virtual_incoming_args_rtx
,
2155 GEN_INT (UNITS_PER_WORD
* num
));
2157 if (TARGET_DEBUG_ARG
)
2159 fprintf (stderr
, "va_start: args_info = %d, num = %d\n",
2160 crtl
->args
.info
, num
);
2162 debug_rtx (nextarg
);
2165 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist
,
2166 fold_convert (TREE_TYPE (valist
),
2167 make_tree (sizetype
, nextarg
)));
2168 TREE_SIDE_EFFECTS (t
) = 1;
2170 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2174 /* Expand a block move operation, and return 1 if successful. Return 0
2175 if we should let the compiler generate normal code.
2177 operands[0] is the destination
2178 operands[1] is the source
2179 operands[2] is the length
2180 operands[3] is the alignment */
2182 /* Maximum number of loads to do before doing the stores */
2183 #ifndef MAX_MOVE_REG
2184 #define MAX_MOVE_REG 4
2187 /* Maximum number of total loads to do. */
2188 #ifndef TOTAL_MOVE_REG
2189 #define TOTAL_MOVE_REG 8
2193 frv_expand_block_move (rtx operands
[])
2195 rtx orig_dest
= operands
[0];
2196 rtx orig_src
= operands
[1];
2197 rtx bytes_rtx
= operands
[2];
2198 rtx align_rtx
= operands
[3];
2199 int constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
2212 rtx stores
[MAX_MOVE_REG
];
2216 /* If this is not a fixed size move, just call memcpy. */
2220 /* This should be a fixed size alignment. */
2221 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
2223 align
= INTVAL (align_rtx
);
2225 /* Anything to move? */
2226 bytes
= INTVAL (bytes_rtx
);
2230 /* Don't support real large moves. */
2231 if (bytes
> TOTAL_MOVE_REG
*align
)
2234 /* Move the address into scratch registers. */
2235 dest_reg
= copy_addr_to_reg (XEXP (orig_dest
, 0));
2236 src_reg
= copy_addr_to_reg (XEXP (orig_src
, 0));
2238 num_reg
= offset
= 0;
2239 for ( ; bytes
> 0; (bytes
-= move_bytes
), (offset
+= move_bytes
))
2241 /* Calculate the correct offset for src/dest. */
2245 dest_addr
= dest_reg
;
2249 src_addr
= plus_constant (Pmode
, src_reg
, offset
);
2250 dest_addr
= plus_constant (Pmode
, dest_reg
, offset
);
2253 /* Generate the appropriate load and store, saving the stores
2255 if (bytes
>= 4 && align
>= 4)
2257 else if (bytes
>= 2 && align
>= 2)
2262 move_bytes
= GET_MODE_SIZE (mode
);
2263 tmp_reg
= gen_reg_rtx (mode
);
2264 src_mem
= change_address (orig_src
, mode
, src_addr
);
2265 dest_mem
= change_address (orig_dest
, mode
, dest_addr
);
2266 emit_insn (gen_rtx_SET (tmp_reg
, src_mem
));
2267 stores
[num_reg
++] = gen_rtx_SET (dest_mem
, tmp_reg
);
2269 if (num_reg
>= MAX_MOVE_REG
)
2271 for (i
= 0; i
< num_reg
; i
++)
2272 emit_insn (stores
[i
]);
2277 for (i
= 0; i
< num_reg
; i
++)
2278 emit_insn (stores
[i
]);
2284 /* Expand a block clear operation, and return 1 if successful. Return 0
2285 if we should let the compiler generate normal code.
2287 operands[0] is the destination
2288 operands[1] is the length
2289 operands[3] is the alignment */
2292 frv_expand_block_clear (rtx operands
[])
2294 rtx orig_dest
= operands
[0];
2295 rtx bytes_rtx
= operands
[1];
2296 rtx align_rtx
= operands
[3];
2297 int constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
2307 /* If this is not a fixed size move, just call memcpy. */
2311 /* This should be a fixed size alignment. */
2312 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
2314 align
= INTVAL (align_rtx
);
2316 /* Anything to move? */
2317 bytes
= INTVAL (bytes_rtx
);
2321 /* Don't support real large clears. */
2322 if (bytes
> TOTAL_MOVE_REG
*align
)
2325 /* Move the address into a scratch register. */
2326 dest_reg
= copy_addr_to_reg (XEXP (orig_dest
, 0));
2329 for ( ; bytes
> 0; (bytes
-= clear_bytes
), (offset
+= clear_bytes
))
2331 /* Calculate the correct offset for src/dest. */
2332 dest_addr
= ((offset
== 0)
2334 : plus_constant (Pmode
, dest_reg
, offset
));
2336 /* Generate the appropriate store of gr0. */
2337 if (bytes
>= 4 && align
>= 4)
2339 else if (bytes
>= 2 && align
>= 2)
2344 clear_bytes
= GET_MODE_SIZE (mode
);
2345 dest_mem
= change_address (orig_dest
, mode
, dest_addr
);
2346 emit_insn (gen_rtx_SET (dest_mem
, const0_rtx
));
2353 /* The following variable is used to output modifiers of assembler
2354 code of the current output insn. */
2356 static rtx
*frv_insn_operands
;
2358 /* The following function is used to add assembler insn code suffix .p
2359 if it is necessary. */
2362 frv_asm_output_opcode (FILE *f
, const char *ptr
)
2366 if (frv_insn_packing_flag
<= 0)
2369 for (; *ptr
&& *ptr
!= ' ' && *ptr
!= '\t';)
2372 if (c
== '%' && ((*ptr
>= 'a' && *ptr
<= 'z')
2373 || (*ptr
>= 'A' && *ptr
<= 'Z')))
2375 int letter
= *ptr
++;
2378 frv_print_operand (f
, frv_insn_operands
[c
], letter
);
2379 while ((c
= *ptr
) >= '0' && c
<= '9')
2391 /* Set up the packing bit for the current output insn. Note that this
2392 function is not called for asm insns. */
2395 frv_final_prescan_insn (rtx_insn
*insn
, rtx
*opvec
,
2396 int noperands ATTRIBUTE_UNUSED
)
2400 if (frv_insn_packing_flag
>= 0)
2402 frv_insn_operands
= opvec
;
2403 frv_insn_packing_flag
= PACKING_FLAG_P (insn
);
2405 else if (recog_memoized (insn
) >= 0
2406 && get_attr_acc_group (insn
) == ACC_GROUP_ODD
)
2407 /* Packing optimizations have been disabled, but INSN can only
2408 be issued in M1. Insert an mnop in M0. */
2409 fprintf (asm_out_file
, "\tmnop.p\n");
2415 /* A C expression whose value is RTL representing the address in a stack frame
2416 where the pointer to the caller's frame is stored. Assume that FRAMEADDR is
2417 an RTL expression for the address of the stack frame itself.
2419 If you don't define this macro, the default is to return the value of
2420 FRAMEADDR--that is, the stack frame address is also the address of the stack
2421 word that points to the previous frame. */
2423 /* The default is correct, but we need to make sure the frame gets created. */
2425 frv_dynamic_chain_address (rtx frame
)
2427 cfun
->machine
->frame_needed
= 1;
2432 /* A C expression whose value is RTL representing the value of the return
2433 address for the frame COUNT steps up from the current frame, after the
2434 prologue. FRAMEADDR is the frame pointer of the COUNT frame, or the frame
2435 pointer of the COUNT - 1 frame if `RETURN_ADDR_IN_PREVIOUS_FRAME' is
2438 The value of the expression must always be the correct address when COUNT is
2439 zero, but may be `NULL_RTX' if there is not way to determine the return
2440 address of other frames. */
2443 frv_return_addr_rtx (int count
, rtx frame
)
2447 cfun
->machine
->frame_needed
= 1;
2448 return gen_rtx_MEM (Pmode
, plus_constant (Pmode
, frame
, 8));
2451 /* Given a memory reference MEMREF, interpret the referenced memory as
2452 an array of MODE values, and return a reference to the element
2453 specified by INDEX. Assume that any pre-modification implicit in
2454 MEMREF has already happened.
2456 MEMREF must be a legitimate operand for modes larger than SImode.
2457 frv_legitimate_address_p forbids register+register addresses, which
2458 this function cannot handle. */
2460 frv_index_memory (rtx memref
, machine_mode mode
, int index
)
2462 rtx base
= XEXP (memref
, 0);
2463 if (GET_CODE (base
) == PRE_MODIFY
)
2464 base
= XEXP (base
, 0);
2465 return change_address (memref
, mode
,
2466 plus_constant (Pmode
, base
,
2467 index
* GET_MODE_SIZE (mode
)));
2471 /* Print a memory address as an operand to reference that memory location. */
2473 frv_print_operand_address (FILE * stream
, machine_mode
/* mode */, rtx x
)
2475 if (GET_CODE (x
) == MEM
)
2478 switch (GET_CODE (x
))
2481 fputs (reg_names
[ REGNO (x
)], stream
);
2485 fprintf (stream
, "%ld", (long) INTVAL (x
));
2489 assemble_name (stream
, XSTR (x
, 0));
2494 output_addr_const (stream
, x
);
2498 /* Poorly constructed asm statements can trigger this alternative.
2499 See gcc/testsuite/gcc.dg/asm-4.c for an example. */
2500 frv_print_operand_memory_reference (stream
, x
, 0);
2507 fatal_insn ("bad insn to frv_print_operand_address:", x
);
2512 frv_print_operand_memory_reference_reg (FILE * stream
, rtx x
)
2514 int regno
= true_regnum (x
);
2516 fputs (reg_names
[regno
], stream
);
2518 fatal_insn ("bad register to frv_print_operand_memory_reference_reg:", x
);
2521 /* Print a memory reference suitable for the ld/st instructions. */
2524 frv_print_operand_memory_reference (FILE * stream
, rtx x
, int addr_offset
)
2526 struct frv_unspec unspec
;
2530 switch (GET_CODE (x
))
2537 case PRE_MODIFY
: /* (pre_modify (reg) (plus (reg) (reg))) */
2539 x1
= XEXP (XEXP (x
, 1), 1);
2549 if (GET_CODE (x0
) == CONST_INT
)
2557 fatal_insn ("bad insn to frv_print_operand_memory_reference:", x
);
2566 else if (GET_CODE (x1
) != CONST_INT
)
2567 fatal_insn ("bad insn to frv_print_operand_memory_reference:", x
);
2570 fputs ("@(", stream
);
2572 fputs (reg_names
[GPR_R0
], stream
);
2573 else if (GET_CODE (x0
) == REG
|| GET_CODE (x0
) == SUBREG
)
2574 frv_print_operand_memory_reference_reg (stream
, x0
);
2576 fatal_insn ("bad insn to frv_print_operand_memory_reference:", x
);
2578 fputs (",", stream
);
2580 fputs (reg_names
[GPR_R0
], stream
);
2584 switch (GET_CODE (x1
))
2588 frv_print_operand_memory_reference_reg (stream
, x1
);
2592 fprintf (stream
, "%ld", (long) (INTVAL (x1
) + addr_offset
));
2596 if (!frv_const_unspec_p (x1
, &unspec
))
2597 fatal_insn ("bad insn to frv_print_operand_memory_reference:", x1
);
2598 frv_output_const_unspec (stream
, &unspec
);
2602 fatal_insn ("bad insn to frv_print_operand_memory_reference:", x
);
2606 fputs (")", stream
);
2610 /* Return 2 for likely branches and 0 for non-likely branches */
2612 #define FRV_JUMP_LIKELY 2
2613 #define FRV_JUMP_NOT_LIKELY 0
2616 frv_print_operand_jump_hint (rtx_insn
*insn
)
2622 enum { UNKNOWN
, BACKWARD
, FORWARD
} jump_type
= UNKNOWN
;
2624 gcc_assert (JUMP_P (insn
));
2626 /* Assume any non-conditional jump is likely. */
2627 if (! any_condjump_p (insn
))
2628 ret
= FRV_JUMP_LIKELY
;
2632 labelref
= condjump_label (insn
);
2635 rtx label
= XEXP (labelref
, 0);
2636 jump_type
= (insn_current_address
> INSN_ADDRESSES (INSN_UID (label
))
2641 note
= find_reg_note (insn
, REG_BR_PROB
, 0);
2643 ret
= ((jump_type
== BACKWARD
) ? FRV_JUMP_LIKELY
: FRV_JUMP_NOT_LIKELY
);
2647 prob
= XINT (note
, 0);
2648 ret
= ((prob
>= (REG_BR_PROB_BASE
/ 2))
2650 : FRV_JUMP_NOT_LIKELY
);
2662 case UNKNOWN
: direction
= "unknown jump direction"; break;
2663 case BACKWARD
: direction
= "jump backward"; break;
2664 case FORWARD
: direction
= "jump forward"; break;
2668 "%s: uid %ld, %s, probability = %d, max prob. = %d, hint = %d\n",
2669 IDENTIFIER_POINTER (DECL_NAME (current_function_decl
)),
2670 (long)INSN_UID (insn
), direction
, prob
,
2671 REG_BR_PROB_BASE
, ret
);
2679 /* Return the comparison operator to use for CODE given that the ICC
2683 comparison_string (enum rtx_code code
, rtx op0
)
2685 bool is_nz_p
= GET_MODE (op0
) == CC_NZmode
;
2688 default: output_operand_lossage ("bad condition code");
2689 case EQ
: return "eq";
2690 case NE
: return "ne";
2691 case LT
: return is_nz_p
? "n" : "lt";
2692 case LE
: return "le";
2693 case GT
: return "gt";
2694 case GE
: return is_nz_p
? "p" : "ge";
2695 case LTU
: return is_nz_p
? "no" : "c";
2696 case LEU
: return is_nz_p
? "eq" : "ls";
2697 case GTU
: return is_nz_p
? "ne" : "hi";
2698 case GEU
: return is_nz_p
? "ra" : "nc";
2702 /* Print an operand to an assembler instruction.
2704 `%' followed by a letter and a digit says to output an operand in an
2705 alternate fashion. Four letters have standard, built-in meanings
2706 described below. The hook `TARGET_PRINT_OPERAND' can define
2707 additional letters with nonstandard meanings.
2709 `%cDIGIT' can be used to substitute an operand that is a constant value
2710 without the syntax that normally indicates an immediate operand.
2712 `%nDIGIT' is like `%cDIGIT' except that the value of the constant is negated
2715 `%aDIGIT' can be used to substitute an operand as if it were a memory
2716 reference, with the actual operand treated as the address. This may be
2717 useful when outputting a "load address" instruction, because often the
2718 assembler syntax for such an instruction requires you to write the operand
2719 as if it were a memory reference.
2721 `%lDIGIT' is used to substitute a `label_ref' into a jump instruction.
2723 `%=' outputs a number which is unique to each instruction in the entire
2724 compilation. This is useful for making local labels to be referred to more
2725 than once in a single template that generates multiple assembler
2728 `%' followed by a punctuation character specifies a substitution that
2729 does not use an operand. Only one case is standard: `%%' outputs a
2730 `%' into the assembler code. Other nonstandard cases can be defined
2731 in the `TARGET_PRINT_OPERAND' hook. You must also define which
2732 punctuation characters are valid with the
2733 `TARGET_PRINT_OPERAND_PUNCT_VALID_P' hook. */
2736 frv_print_operand (FILE * file
, rtx x
, int code
)
2738 struct frv_unspec unspec
;
2739 HOST_WIDE_INT value
;
2742 if (code
!= 0 && !ISALPHA (code
))
2745 else if (GET_CODE (x
) == CONST_INT
)
2748 else if (GET_CODE (x
) == CONST_DOUBLE
)
2750 if (GET_MODE (x
) == SFmode
)
2754 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x
), l
);
2758 else if (GET_MODE (x
) == VOIDmode
)
2759 value
= CONST_DOUBLE_LOW (x
);
2762 fatal_insn ("bad insn in frv_print_operand, bad const_double", x
);
2773 fputs (reg_names
[GPR_R0
], file
);
2777 fprintf (file
, "%d", frv_print_operand_jump_hint (current_output_insn
));
2781 /* Output small data area base register (gr16). */
2782 fputs (reg_names
[SDA_BASE_REG
], file
);
2786 /* Output pic register (gr17). */
2787 fputs (reg_names
[PIC_REGNO
], file
);
2791 /* Output the temporary integer CCR register. */
2792 fputs (reg_names
[ICR_TEMP
], file
);
2796 /* Output the temporary integer CC register. */
2797 fputs (reg_names
[ICC_TEMP
], file
);
2800 /* case 'a': print an address. */
2803 /* Print appropriate test for integer branch false operation. */
2804 fputs (comparison_string (reverse_condition (GET_CODE (x
)),
2805 XEXP (x
, 0)), file
);
2809 /* Print appropriate test for integer branch true operation. */
2810 fputs (comparison_string (GET_CODE (x
), XEXP (x
, 0)), file
);
2814 /* Print 1 for a NE and 0 for an EQ to give the final argument
2815 for a conditional instruction. */
2816 if (GET_CODE (x
) == NE
)
2819 else if (GET_CODE (x
) == EQ
)
2823 fatal_insn ("bad insn to frv_print_operand, 'e' modifier:", x
);
2827 /* Print appropriate test for floating point branch false operation. */
2828 switch (GET_CODE (x
))
2831 fatal_insn ("bad insn to frv_print_operand, 'F' modifier:", x
);
2833 case EQ
: fputs ("ne", file
); break;
2834 case NE
: fputs ("eq", file
); break;
2835 case LT
: fputs ("uge", file
); break;
2836 case LE
: fputs ("ug", file
); break;
2837 case GT
: fputs ("ule", file
); break;
2838 case GE
: fputs ("ul", file
); break;
2843 /* Print appropriate test for floating point branch true operation. */
2844 switch (GET_CODE (x
))
2847 fatal_insn ("bad insn to frv_print_operand, 'f' modifier:", x
);
2849 case EQ
: fputs ("eq", file
); break;
2850 case NE
: fputs ("ne", file
); break;
2851 case LT
: fputs ("lt", file
); break;
2852 case LE
: fputs ("le", file
); break;
2853 case GT
: fputs ("gt", file
); break;
2854 case GE
: fputs ("ge", file
); break;
2859 /* Print appropriate GOT function. */
2860 if (GET_CODE (x
) != CONST_INT
)
2861 fatal_insn ("bad insn to frv_print_operand, 'g' modifier:", x
);
2862 fputs (unspec_got_name (INTVAL (x
)), file
);
2866 /* Print 'i' if the operand is a constant, or is a memory reference that
2868 if (GET_CODE (x
) == MEM
)
2869 x
= ((GET_CODE (XEXP (x
, 0)) == PLUS
)
2870 ? XEXP (XEXP (x
, 0), 1)
2872 else if (GET_CODE (x
) == PLUS
)
2875 switch (GET_CODE (x
))
2889 /* For jump instructions, print 'i' if the operand is a constant or
2890 is an expression that adds a constant. */
2891 if (GET_CODE (x
) == CONST_INT
)
2896 if (GET_CODE (x
) == CONST_INT
2897 || (GET_CODE (x
) == PLUS
2898 && (GET_CODE (XEXP (x
, 1)) == CONST_INT
2899 || GET_CODE (XEXP (x
, 0)) == CONST_INT
)))
2905 /* Print the lower register of a double word register pair */
2906 if (GET_CODE (x
) == REG
)
2907 fputs (reg_names
[ REGNO (x
)+1 ], file
);
2909 fatal_insn ("bad insn to frv_print_operand, 'L' modifier:", x
);
2912 /* case 'l': print a LABEL_REF. */
2916 /* Print a memory reference for ld/st/jmp, %N prints a memory reference
2917 for the second word of double memory operations. */
2918 offset
= (code
== 'M') ? 0 : UNITS_PER_WORD
;
2919 switch (GET_CODE (x
))
2922 fatal_insn ("bad insn to frv_print_operand, 'M/N' modifier:", x
);
2925 frv_print_operand_memory_reference (file
, XEXP (x
, 0), offset
);
2933 frv_print_operand_memory_reference (file
, x
, offset
);
2939 /* Print the opcode of a command. */
2940 switch (GET_CODE (x
))
2943 fatal_insn ("bad insn to frv_print_operand, 'O' modifier:", x
);
2945 case PLUS
: fputs ("add", file
); break;
2946 case MINUS
: fputs ("sub", file
); break;
2947 case AND
: fputs ("and", file
); break;
2948 case IOR
: fputs ("or", file
); break;
2949 case XOR
: fputs ("xor", file
); break;
2950 case ASHIFT
: fputs ("sll", file
); break;
2951 case ASHIFTRT
: fputs ("sra", file
); break;
2952 case LSHIFTRT
: fputs ("srl", file
); break;
2956 /* case 'n': negate and print a constant int. */
2959 /* Print PIC label using operand as the number. */
2960 if (GET_CODE (x
) != CONST_INT
)
2961 fatal_insn ("bad insn to frv_print_operand, P modifier:", x
);
2963 fprintf (file
, ".LCF%ld", (long)INTVAL (x
));
2967 /* Print 'u' if the operand is a update load/store. */
2968 if (GET_CODE (x
) == MEM
&& GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
2973 /* If value is 0, print gr0, otherwise it must be a register. */
2974 if (GET_CODE (x
) == CONST_INT
&& INTVAL (x
) == 0)
2975 fputs (reg_names
[GPR_R0
], file
);
2977 else if (GET_CODE (x
) == REG
)
2978 fputs (reg_names
[REGNO (x
)], file
);
2981 fatal_insn ("bad insn in frv_print_operand, z case", x
);
2985 /* Print constant in hex. */
2986 if (GET_CODE (x
) == CONST_INT
|| GET_CODE (x
) == CONST_DOUBLE
)
2988 fprintf (file
, "%s0x%.4lx", IMMEDIATE_PREFIX
, (long) value
);
2995 if (GET_CODE (x
) == REG
)
2996 fputs (reg_names
[REGNO (x
)], file
);
2998 else if (GET_CODE (x
) == CONST_INT
2999 || GET_CODE (x
) == CONST_DOUBLE
)
3000 fprintf (file
, "%s%ld", IMMEDIATE_PREFIX
, (long) value
);
3002 else if (frv_const_unspec_p (x
, &unspec
))
3003 frv_output_const_unspec (file
, &unspec
);
3005 else if (GET_CODE (x
) == MEM
)
3006 frv_print_operand_address (file
, GET_MODE (x
), XEXP (x
, 0));
3008 else if (CONSTANT_ADDRESS_P (x
))
3009 frv_print_operand_address (file
, VOIDmode
, x
);
3012 fatal_insn ("bad insn in frv_print_operand, 0 case", x
);
3017 fatal_insn ("frv_print_operand: unknown code", x
);
3025 frv_print_operand_punct_valid_p (unsigned char code
)
3027 return (code
== '.' || code
== '#' || code
== '@' || code
== '~'
3028 || code
== '*' || code
== '&');
3032 /* A C statement (sans semicolon) for initializing the variable CUM for the
3033 state at the beginning of the argument list. The variable has type
3034 `CUMULATIVE_ARGS'. The value of FNTYPE is the tree node for the data type
3035 of the function which will receive the args, or 0 if the args are to a
3036 compiler support library function. The value of INDIRECT is nonzero when
3037 processing an indirect call, for example a call through a function pointer.
3038 The value of INDIRECT is zero for a call to an explicitly named function, a
3039 library function call, or when `INIT_CUMULATIVE_ARGS' is used to find
3040 arguments for the function being compiled.
3042 When processing a call to a compiler support library function, LIBNAME
3043 identifies which one. It is a `symbol_ref' rtx which contains the name of
3044 the function, as a string. LIBNAME is 0 when an ordinary C function call is
3045 being processed. Thus, each time this macro is called, either LIBNAME or
3046 FNTYPE is nonzero, but never both of them at once. */
3049 frv_init_cumulative_args (CUMULATIVE_ARGS
*cum
,
3055 *cum
= FIRST_ARG_REGNUM
;
3057 if (TARGET_DEBUG_ARG
)
3059 fprintf (stderr
, "\ninit_cumulative_args:");
3060 if (!fndecl
&& fntype
)
3061 fputs (" indirect", stderr
);
3064 fputs (" incoming", stderr
);
3068 tree ret_type
= TREE_TYPE (fntype
);
3069 fprintf (stderr
, " return=%s,",
3070 get_tree_code_name (TREE_CODE (ret_type
)));
3073 if (libname
&& GET_CODE (libname
) == SYMBOL_REF
)
3074 fprintf (stderr
, " libname=%s", XSTR (libname
, 0));
3076 if (cfun
->returns_struct
)
3077 fprintf (stderr
, " return-struct");
3079 putc ('\n', stderr
);
3084 /* Return true if we should pass an argument on the stack rather than
3088 frv_must_pass_in_stack (machine_mode mode
, const_tree type
)
3090 if (mode
== BLKmode
)
3094 return AGGREGATE_TYPE_P (type
);
3097 /* If defined, a C expression that gives the alignment boundary, in bits, of an
3098 argument with the specified mode and type. If it is not defined,
3099 `PARM_BOUNDARY' is used for all arguments. */
3102 frv_function_arg_boundary (machine_mode mode ATTRIBUTE_UNUSED
,
3103 const_tree type ATTRIBUTE_UNUSED
)
3105 return BITS_PER_WORD
;
3109 frv_function_arg_1 (cumulative_args_t cum_v
, machine_mode mode
,
3110 const_tree type ATTRIBUTE_UNUSED
, bool named
,
3111 bool incoming ATTRIBUTE_UNUSED
)
3113 const CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
3115 machine_mode xmode
= (mode
== BLKmode
) ? SImode
: mode
;
3120 /* Return a marker for use in the call instruction. */
3121 if (xmode
== VOIDmode
)
3127 else if (arg_num
<= LAST_ARG_REGNUM
)
3129 ret
= gen_rtx_REG (xmode
, arg_num
);
3130 debstr
= reg_names
[arg_num
];
3139 if (TARGET_DEBUG_ARG
)
3141 "function_arg: words = %2d, mode = %4s, named = %d, size = %3d, arg = %s\n",
3142 arg_num
, GET_MODE_NAME (mode
), named
, GET_MODE_SIZE (mode
), debstr
);
3148 frv_function_arg (cumulative_args_t cum
, machine_mode mode
,
3149 const_tree type
, bool named
)
3151 return frv_function_arg_1 (cum
, mode
, type
, named
, false);
3155 frv_function_incoming_arg (cumulative_args_t cum
, machine_mode mode
,
3156 const_tree type
, bool named
)
3158 return frv_function_arg_1 (cum
, mode
, type
, named
, true);
3162 /* A C statement (sans semicolon) to update the summarizer variable CUM to
3163 advance past an argument in the argument list. The values MODE, TYPE and
3164 NAMED describe that argument. Once this is done, the variable CUM is
3165 suitable for analyzing the *following* argument with `FUNCTION_ARG', etc.
3167 This macro need not do anything if the argument in question was passed on
3168 the stack. The compiler knows how to track the amount of stack space used
3169 for arguments without any special help. */
3172 frv_function_arg_advance (cumulative_args_t cum_v
,
3174 const_tree type ATTRIBUTE_UNUSED
,
3177 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
3179 machine_mode xmode
= (mode
== BLKmode
) ? SImode
: mode
;
3180 int bytes
= GET_MODE_SIZE (xmode
);
3181 int words
= (bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
3184 *cum
= arg_num
+ words
;
3186 if (TARGET_DEBUG_ARG
)
3188 "function_adv: words = %2d, mode = %4s, named = %d, size = %3d\n",
3189 arg_num
, GET_MODE_NAME (mode
), named
, words
* UNITS_PER_WORD
);
3193 /* A C expression for the number of words, at the beginning of an argument,
3194 must be put in registers. The value must be zero for arguments that are
3195 passed entirely in registers or that are entirely pushed on the stack.
3197 On some machines, certain arguments must be passed partially in registers
3198 and partially in memory. On these machines, typically the first N words of
3199 arguments are passed in registers, and the rest on the stack. If a
3200 multi-word argument (a `double' or a structure) crosses that boundary, its
3201 first few words must be passed in registers and the rest must be pushed.
3202 This macro tells the compiler when this occurs, and how many of the words
3203 should go in registers.
3205 `FUNCTION_ARG' for these arguments should return the first register to be
3206 used by the caller for this argument; likewise `FUNCTION_INCOMING_ARG', for
3207 the called function. */
3210 frv_arg_partial_bytes (cumulative_args_t cum
, machine_mode mode
,
3211 tree type ATTRIBUTE_UNUSED
, bool named ATTRIBUTE_UNUSED
)
3214 machine_mode xmode
= (mode
== BLKmode
) ? SImode
: mode
;
3215 int bytes
= GET_MODE_SIZE (xmode
);
3216 int words
= (bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
3217 int arg_num
= *get_cumulative_args (cum
);
3220 ret
= ((arg_num
<= LAST_ARG_REGNUM
&& arg_num
+ words
> LAST_ARG_REGNUM
+1)
3221 ? LAST_ARG_REGNUM
- arg_num
+ 1
3223 ret
*= UNITS_PER_WORD
;
3225 if (TARGET_DEBUG_ARG
&& ret
)
3226 fprintf (stderr
, "frv_arg_partial_bytes: %d\n", ret
);
3232 /* Implements TARGET_FUNCTION_VALUE. */
3235 frv_function_value (const_tree valtype
,
3236 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
3237 bool outgoing ATTRIBUTE_UNUSED
)
3239 return gen_rtx_REG (TYPE_MODE (valtype
), RETURN_VALUE_REGNUM
);
3243 /* Implements TARGET_LIBCALL_VALUE. */
3246 frv_libcall_value (machine_mode mode
,
3247 const_rtx fun ATTRIBUTE_UNUSED
)
3249 return gen_rtx_REG (mode
, RETURN_VALUE_REGNUM
);
3253 /* Implements FUNCTION_VALUE_REGNO_P. */
3256 frv_function_value_regno_p (const unsigned int regno
)
3258 return (regno
== RETURN_VALUE_REGNUM
);
3261 /* Return true if a register is ok to use as a base or index register. */
3263 static FRV_INLINE
int
3264 frv_regno_ok_for_base_p (int regno
, int strict_p
)
3270 return (reg_renumber
[regno
] >= 0 && GPR_P (reg_renumber
[regno
]));
3272 if (regno
== ARG_POINTER_REGNUM
)
3275 return (regno
>= FIRST_PSEUDO_REGISTER
);
3279 /* A C compound statement with a conditional `goto LABEL;' executed if X (an
3280 RTX) is a legitimate memory address on the target machine for a memory
3281 operand of mode MODE.
3283 It usually pays to define several simpler macros to serve as subroutines for
3284 this one. Otherwise it may be too complicated to understand.
3286 This macro must exist in two variants: a strict variant and a non-strict
3287 one. The strict variant is used in the reload pass. It must be defined so
3288 that any pseudo-register that has not been allocated a hard register is
3289 considered a memory reference. In contexts where some kind of register is
3290 required, a pseudo-register with no hard register must be rejected.
3292 The non-strict variant is used in other passes. It must be defined to
3293 accept all pseudo-registers in every context where some kind of register is
3296 Compiler source files that want to use the strict variant of this macro
3297 define the macro `REG_OK_STRICT'. You should use an `#ifdef REG_OK_STRICT'
3298 conditional to define the strict variant in that case and the non-strict
3301 Normally, constant addresses which are the sum of a `symbol_ref' and an
3302 integer are stored inside a `const' RTX to mark them as constant.
3303 Therefore, there is no need to recognize such sums specifically as
3304 legitimate addresses. Normally you would simply recognize any `const' as
3307 Usually `TARGET_PRINT_OPERAND_ADDRESS' is not prepared to handle
3308 constant sums that are not marked with `const'. It assumes that a
3309 naked `plus' indicates indexing. If so, then you *must* reject such
3310 naked constant sums as illegitimate addresses, so that none of them
3311 will be given to `TARGET_PRINT_OPERAND_ADDRESS'. */
3314 frv_legitimate_address_p_1 (machine_mode mode
,
3318 int allow_double_reg_p
)
3322 HOST_WIDE_INT value
;
3325 if (FRV_SYMBOL_REF_TLS_P (x
))
3328 switch (GET_CODE (x
))
3335 if (GET_CODE (x
) != REG
)
3341 ret
= frv_regno_ok_for_base_p (REGNO (x
), strict_p
);
3347 if (GET_CODE (x0
) != REG
3348 || ! frv_regno_ok_for_base_p (REGNO (x0
), strict_p
)
3349 || GET_CODE (x1
) != PLUS
3350 || ! rtx_equal_p (x0
, XEXP (x1
, 0))
3351 || GET_CODE (XEXP (x1
, 1)) != REG
3352 || ! frv_regno_ok_for_base_p (REGNO (XEXP (x1
, 1)), strict_p
))
3359 /* 12-bit immediate */
3364 ret
= IN_RANGE (INTVAL (x
), -2048, 2047);
3366 /* If we can't use load/store double operations, make sure we can
3367 address the second word. */
3368 if (ret
&& GET_MODE_SIZE (mode
) > UNITS_PER_WORD
)
3369 ret
= IN_RANGE (INTVAL (x
) + GET_MODE_SIZE (mode
) - 1,
3378 if (GET_CODE (x0
) == SUBREG
)
3379 x0
= SUBREG_REG (x0
);
3381 if (GET_CODE (x0
) != REG
)
3384 regno0
= REGNO (x0
);
3385 if (!frv_regno_ok_for_base_p (regno0
, strict_p
))
3388 switch (GET_CODE (x1
))
3394 x1
= SUBREG_REG (x1
);
3395 if (GET_CODE (x1
) != REG
)
3401 /* Do not allow reg+reg addressing for modes > 1 word if we
3402 can't depend on having move double instructions. */
3403 if (!allow_double_reg_p
&& GET_MODE_SIZE (mode
) > UNITS_PER_WORD
)
3406 ret
= frv_regno_ok_for_base_p (REGNO (x1
), strict_p
);
3410 /* 12-bit immediate */
3415 value
= INTVAL (x1
);
3416 ret
= IN_RANGE (value
, -2048, 2047);
3418 /* If we can't use load/store double operations, make sure we can
3419 address the second word. */
3420 if (ret
&& GET_MODE_SIZE (mode
) > UNITS_PER_WORD
)
3421 ret
= IN_RANGE (value
+ GET_MODE_SIZE (mode
) - 1, -2048, 2047);
3426 if (!condexec_p
&& got12_operand (x1
, VOIDmode
))
3434 if (TARGET_DEBUG_ADDR
)
3436 fprintf (stderr
, "\n========== legitimate_address_p, mode = %s, result = %d, addresses are %sstrict%s\n",
3437 GET_MODE_NAME (mode
), ret
, (strict_p
) ? "" : "not ",
3438 (condexec_p
) ? ", inside conditional code" : "");
3446 frv_legitimate_address_p (machine_mode mode
, rtx x
, bool strict_p
)
3448 return frv_legitimate_address_p_1 (mode
, x
, strict_p
, FALSE
, FALSE
);
3451 /* Given an ADDR, generate code to inline the PLT. */
3453 gen_inlined_tls_plt (rtx addr
)
3456 rtx picreg
= get_hard_reg_initial_val (Pmode
, FDPIC_REG
);
3459 dest
= gen_reg_rtx (DImode
);
3466 lddi.p @(gr15, #gottlsdesc12(ADDR)), gr8
3467 calll #gettlsoff(ADDR)@(gr8, gr0)
3469 emit_insn (gen_tls_lddi (dest
, addr
, picreg
));
3476 sethi.p #gottlsdeschi(ADDR), gr8
3477 setlo #gottlsdesclo(ADDR), gr8
3478 ldd #tlsdesc(ADDR)@(gr15, gr8), gr8
3479 calll #gettlsoff(ADDR)@(gr8, gr0)
3481 rtx reguse
= gen_reg_rtx (Pmode
);
3482 emit_insn (gen_tlsoff_hilo (reguse
, addr
, GEN_INT (R_FRV_GOTTLSDESCHI
)));
3483 emit_insn (gen_tls_tlsdesc_ldd (dest
, picreg
, reguse
, addr
));
3486 retval
= gen_reg_rtx (Pmode
);
3487 emit_insn (gen_tls_indirect_call (retval
, addr
, dest
, picreg
));
3491 /* Emit a TLSMOFF or TLSMOFF12 offset, depending on -mTLS. Returns
3492 the destination address. */
3494 gen_tlsmoff (rtx addr
, rtx reg
)
3496 rtx dest
= gen_reg_rtx (Pmode
);
3500 /* sethi.p #tlsmoffhi(x), grA
3501 setlo #tlsmofflo(x), grA
3503 dest
= gen_reg_rtx (Pmode
);
3504 emit_insn (gen_tlsoff_hilo (dest
, addr
,
3505 GEN_INT (R_FRV_TLSMOFFHI
)));
3506 dest
= gen_rtx_PLUS (Pmode
, dest
, reg
);
3510 /* addi grB, #tlsmoff12(x), grC
3512 ld/st @(grB, #tlsmoff12(x)), grC
3514 dest
= gen_reg_rtx (Pmode
);
3515 emit_insn (gen_symGOTOFF2reg_i (dest
, addr
, reg
,
3516 GEN_INT (R_FRV_TLSMOFF12
)));
3521 /* Generate code for a TLS address. */
3523 frv_legitimize_tls_address (rtx addr
, enum tls_model model
)
3525 rtx dest
, tp
= gen_rtx_REG (Pmode
, 29);
3526 rtx picreg
= get_hard_reg_initial_val (Pmode
, 15);
3530 case TLS_MODEL_INITIAL_EXEC
:
3534 ldi @(gr15, #gottlsoff12(x)), gr5
3536 dest
= gen_reg_rtx (Pmode
);
3537 emit_insn (gen_tls_load_gottlsoff12 (dest
, addr
, picreg
));
3538 dest
= gen_rtx_PLUS (Pmode
, tp
, dest
);
3542 /* -fPIC or anything else.
3544 sethi.p #gottlsoffhi(x), gr14
3545 setlo #gottlsofflo(x), gr14
3546 ld #tlsoff(x)@(gr15, gr14), gr9
3548 rtx tmp
= gen_reg_rtx (Pmode
);
3549 dest
= gen_reg_rtx (Pmode
);
3550 emit_insn (gen_tlsoff_hilo (tmp
, addr
,
3551 GEN_INT (R_FRV_GOTTLSOFF_HI
)));
3553 emit_insn (gen_tls_tlsoff_ld (dest
, picreg
, tmp
, addr
));
3554 dest
= gen_rtx_PLUS (Pmode
, tp
, dest
);
3557 case TLS_MODEL_LOCAL_DYNAMIC
:
3561 if (TARGET_INLINE_PLT
)
3562 retval
= gen_inlined_tls_plt (GEN_INT (0));
3565 /* call #gettlsoff(0) */
3566 retval
= gen_reg_rtx (Pmode
);
3567 emit_insn (gen_call_gettlsoff (retval
, GEN_INT (0), picreg
));
3570 reg
= gen_reg_rtx (Pmode
);
3571 emit_insn (gen_rtx_SET (reg
, gen_rtx_PLUS (Pmode
, retval
, tp
)));
3573 dest
= gen_tlsmoff (addr
, reg
);
3576 dest = gen_reg_rtx (Pmode);
3577 emit_insn (gen_tlsoff_hilo (dest, addr,
3578 GEN_INT (R_FRV_TLSMOFFHI)));
3579 dest = gen_rtx_PLUS (Pmode, dest, reg);
3583 case TLS_MODEL_LOCAL_EXEC
:
3584 dest
= gen_tlsmoff (addr
, gen_rtx_REG (Pmode
, 29));
3586 case TLS_MODEL_GLOBAL_DYNAMIC
:
3590 if (TARGET_INLINE_PLT
)
3591 retval
= gen_inlined_tls_plt (addr
);
3594 /* call #gettlsoff(x) */
3595 retval
= gen_reg_rtx (Pmode
);
3596 emit_insn (gen_call_gettlsoff (retval
, addr
, picreg
));
3598 dest
= gen_rtx_PLUS (Pmode
, retval
, tp
);
3609 frv_legitimize_address (rtx x
,
3610 rtx oldx ATTRIBUTE_UNUSED
,
3611 machine_mode mode ATTRIBUTE_UNUSED
)
3613 if (GET_CODE (x
) == SYMBOL_REF
)
3615 enum tls_model model
= SYMBOL_REF_TLS_MODEL (x
);
3617 return frv_legitimize_tls_address (x
, model
);
3623 /* Test whether a local function descriptor is canonical, i.e.,
3624 whether we can use FUNCDESC_GOTOFF to compute the address of the
3628 frv_local_funcdesc_p (rtx fnx
)
3631 enum symbol_visibility vis
;
3634 if (! SYMBOL_REF_LOCAL_P (fnx
))
3637 fn
= SYMBOL_REF_DECL (fnx
);
3642 vis
= DECL_VISIBILITY (fn
);
3644 if (vis
== VISIBILITY_PROTECTED
)
3645 /* Private function descriptors for protected functions are not
3646 canonical. Temporarily change the visibility to global. */
3647 vis
= VISIBILITY_DEFAULT
;
3648 else if (flag_shlib
)
3649 /* If we're already compiling for a shared library (that, unlike
3650 executables, can't assume that the existence of a definition
3651 implies local binding), we can skip the re-testing. */
3654 ret
= default_binds_local_p_1 (fn
, flag_pic
);
3656 DECL_VISIBILITY (fn
) = vis
;
3661 /* Load the _gp symbol into DEST. SRC is supposed to be the FDPIC
3665 frv_gen_GPsym2reg (rtx dest
, rtx src
)
3667 tree gp
= get_identifier ("_gp");
3668 rtx gp_sym
= gen_rtx_SYMBOL_REF (Pmode
, IDENTIFIER_POINTER (gp
));
3670 return gen_symGOT2reg (dest
, gp_sym
, src
, GEN_INT (R_FRV_GOT12
));
3674 unspec_got_name (int i
)
3678 case R_FRV_GOT12
: return "got12";
3679 case R_FRV_GOTHI
: return "gothi";
3680 case R_FRV_GOTLO
: return "gotlo";
3681 case R_FRV_FUNCDESC
: return "funcdesc";
3682 case R_FRV_FUNCDESC_GOT12
: return "gotfuncdesc12";
3683 case R_FRV_FUNCDESC_GOTHI
: return "gotfuncdeschi";
3684 case R_FRV_FUNCDESC_GOTLO
: return "gotfuncdesclo";
3685 case R_FRV_FUNCDESC_VALUE
: return "funcdescvalue";
3686 case R_FRV_FUNCDESC_GOTOFF12
: return "gotofffuncdesc12";
3687 case R_FRV_FUNCDESC_GOTOFFHI
: return "gotofffuncdeschi";
3688 case R_FRV_FUNCDESC_GOTOFFLO
: return "gotofffuncdesclo";
3689 case R_FRV_GOTOFF12
: return "gotoff12";
3690 case R_FRV_GOTOFFHI
: return "gotoffhi";
3691 case R_FRV_GOTOFFLO
: return "gotofflo";
3692 case R_FRV_GPREL12
: return "gprel12";
3693 case R_FRV_GPRELHI
: return "gprelhi";
3694 case R_FRV_GPRELLO
: return "gprello";
3695 case R_FRV_GOTTLSOFF_HI
: return "gottlsoffhi";
3696 case R_FRV_GOTTLSOFF_LO
: return "gottlsofflo";
3697 case R_FRV_TLSMOFFHI
: return "tlsmoffhi";
3698 case R_FRV_TLSMOFFLO
: return "tlsmofflo";
3699 case R_FRV_TLSMOFF12
: return "tlsmoff12";
3700 case R_FRV_TLSDESCHI
: return "tlsdeschi";
3701 case R_FRV_TLSDESCLO
: return "tlsdesclo";
3702 case R_FRV_GOTTLSDESCHI
: return "gottlsdeschi";
3703 case R_FRV_GOTTLSDESCLO
: return "gottlsdesclo";
3704 default: gcc_unreachable ();
3708 /* Write the assembler syntax for UNSPEC to STREAM. Note that any offset
3709 is added inside the relocation operator. */
3712 frv_output_const_unspec (FILE *stream
, const struct frv_unspec
*unspec
)
3714 fprintf (stream
, "#%s(", unspec_got_name (unspec
->reloc
));
3715 output_addr_const (stream
, plus_constant (Pmode
, unspec
->symbol
,
3717 fputs (")", stream
);
3720 /* Implement FIND_BASE_TERM. See whether ORIG_X represents #gprel12(foo)
3721 or #gotoff12(foo) for some small data symbol foo. If so, return foo,
3722 otherwise return ORIG_X. */
3725 frv_find_base_term (rtx x
)
3727 struct frv_unspec unspec
;
3729 if (frv_const_unspec_p (x
, &unspec
)
3730 && frv_small_data_reloc_p (unspec
.symbol
, unspec
.reloc
))
3731 return plus_constant (Pmode
, unspec
.symbol
, unspec
.offset
);
3736 /* Return 1 if operand is a valid FRV address. CONDEXEC_P is true if
3737 the operand is used by a predicated instruction. */
3740 frv_legitimate_memory_operand (rtx op
, machine_mode mode
, int condexec_p
)
3742 return ((GET_MODE (op
) == mode
|| mode
== VOIDmode
)
3743 && GET_CODE (op
) == MEM
3744 && frv_legitimate_address_p_1 (mode
, XEXP (op
, 0),
3745 reload_completed
, condexec_p
, FALSE
));
3749 frv_expand_fdpic_call (rtx
*operands
, bool ret_value
, bool sibcall
)
3751 rtx lr
= gen_rtx_REG (Pmode
, LR_REGNO
);
3752 rtx picreg
= get_hard_reg_initial_val (SImode
, FDPIC_REG
);
3758 rvrtx
= operands
[0];
3762 addr
= XEXP (operands
[0], 0);
3764 /* Inline PLTs if we're optimizing for speed. We'd like to inline
3765 any calls that would involve a PLT, but can't tell, since we
3766 don't know whether an extern function is going to be provided by
3767 a separate translation unit or imported from a separate module.
3768 When compiling for shared libraries, if the function has default
3769 visibility, we assume it's overridable, so we inline the PLT, but
3770 for executables, we don't really have a way to make a good
3771 decision: a function is as likely to be imported from a shared
3772 library as it is to be defined in the executable itself. We
3773 assume executables will get global functions defined locally,
3774 whereas shared libraries will have them potentially overridden,
3775 so we only inline PLTs when compiling for shared libraries.
3777 In order to mark a function as local to a shared library, any
3778 non-default visibility attribute suffices. Unfortunately,
3779 there's no simple way to tag a function declaration as ``in a
3780 different module'', which we could then use to trigger PLT
3781 inlining on executables. There's -minline-plt, but it affects
3782 all external functions, so one would have to also mark function
3783 declarations available in the same module with non-default
3784 visibility, which is advantageous in itself. */
3785 if (GET_CODE (addr
) == SYMBOL_REF
3786 && ((!SYMBOL_REF_LOCAL_P (addr
) && TARGET_INLINE_PLT
)
3790 dest
= gen_reg_rtx (SImode
);
3792 x
= gen_symGOTOFF2reg_hilo (dest
, addr
, OUR_FDPIC_REG
,
3793 GEN_INT (R_FRV_FUNCDESC_GOTOFF12
));
3795 x
= gen_symGOTOFF2reg (dest
, addr
, OUR_FDPIC_REG
,
3796 GEN_INT (R_FRV_FUNCDESC_GOTOFF12
));
3798 crtl
->uses_pic_offset_table
= TRUE
;
3801 else if (GET_CODE (addr
) == SYMBOL_REF
)
3803 /* These are always either local, or handled through a local
3806 c
= gen_call_value_fdpicsi (rvrtx
, addr
, operands
[1],
3807 operands
[2], picreg
, lr
);
3809 c
= gen_call_fdpicsi (addr
, operands
[1], operands
[2], picreg
, lr
);
3813 else if (! ldd_address_operand (addr
, Pmode
))
3814 addr
= force_reg (Pmode
, addr
);
3816 picreg
= gen_reg_rtx (DImode
);
3817 emit_insn (gen_movdi_ldd (picreg
, addr
));
3819 if (sibcall
&& ret_value
)
3820 c
= gen_sibcall_value_fdpicdi (rvrtx
, picreg
, const0_rtx
);
3822 c
= gen_sibcall_fdpicdi (picreg
, const0_rtx
);
3824 c
= gen_call_value_fdpicdi (rvrtx
, picreg
, const0_rtx
, lr
);
3826 c
= gen_call_fdpicdi (picreg
, const0_rtx
, lr
);
3830 /* Look for a SYMBOL_REF of a function in an rtx. We always want to
3831 process these separately from any offsets, such that we add any
3832 offsets to the function descriptor (the actual pointer), not to the
3833 function address. */
3836 frv_function_symbol_referenced_p (rtx x
)
3842 if (GET_CODE (x
) == SYMBOL_REF
)
3843 return SYMBOL_REF_FUNCTION_P (x
);
3845 length
= GET_RTX_LENGTH (GET_CODE (x
));
3846 format
= GET_RTX_FORMAT (GET_CODE (x
));
3848 for (j
= 0; j
< length
; ++j
)
3853 if (frv_function_symbol_referenced_p (XEXP (x
, j
)))
3859 if (XVEC (x
, j
) != 0)
3862 for (k
= 0; k
< XVECLEN (x
, j
); ++k
)
3863 if (frv_function_symbol_referenced_p (XVECEXP (x
, j
, k
)))
3869 /* Nothing to do. */
3877 /* Return true if the memory operand is one that can be conditionally
3881 condexec_memory_operand (rtx op
, machine_mode mode
)
3883 machine_mode op_mode
= GET_MODE (op
);
3886 if (mode
!= VOIDmode
&& op_mode
!= mode
)
3901 if (GET_CODE (op
) != MEM
)
3904 addr
= XEXP (op
, 0);
3905 return frv_legitimate_address_p_1 (mode
, addr
, reload_completed
, TRUE
, FALSE
);
3908 /* Return true if the bare return instruction can be used outside of the
3909 epilog code. For frv, we only do it if there was no stack allocation. */
3912 direct_return_p (void)
3916 if (!reload_completed
)
3919 info
= frv_stack_info ();
3920 return (info
->total_size
== 0);
3925 frv_emit_move (machine_mode mode
, rtx dest
, rtx src
)
3927 if (GET_CODE (src
) == SYMBOL_REF
)
3929 enum tls_model model
= SYMBOL_REF_TLS_MODEL (src
);
3931 src
= frv_legitimize_tls_address (src
, model
);
3937 if (frv_emit_movsi (dest
, src
))
3946 if (!reload_in_progress
3947 && !reload_completed
3948 && !register_operand (dest
, mode
)
3949 && !reg_or_0_operand (src
, mode
))
3950 src
= copy_to_mode_reg (mode
, src
);
3957 emit_insn (gen_rtx_SET (dest
, src
));
3960 /* Emit code to handle a MOVSI, adding in the small data register or pic
3961 register if needed to load up addresses. Return TRUE if the appropriate
3962 instructions are emitted. */
3965 frv_emit_movsi (rtx dest
, rtx src
)
3967 int base_regno
= -1;
3970 struct frv_unspec old_unspec
;
3972 if (!reload_in_progress
3973 && !reload_completed
3974 && !register_operand (dest
, SImode
)
3975 && (!reg_or_0_operand (src
, SImode
)
3976 /* Virtual registers will almost always be replaced by an
3977 add instruction, so expose this to CSE by copying to
3978 an intermediate register. */
3979 || (GET_CODE (src
) == REG
3980 && IN_RANGE (REGNO (src
),
3981 FIRST_VIRTUAL_REGISTER
,
3982 LAST_VIRTUAL_POINTER_REGISTER
))))
3984 emit_insn (gen_rtx_SET (dest
, copy_to_mode_reg (SImode
, src
)));
3988 /* Explicitly add in the PIC or small data register if needed. */
3989 switch (GET_CODE (src
))
3998 /* Using GPREL12, we use a single GOT entry for all symbols
3999 in read-only sections, but trade sequences such as:
4001 sethi #gothi(label), gr#
4002 setlo #gotlo(label), gr#
4007 ld @(gr15,#got12(_gp)), gr#
4008 sethi #gprelhi(label), gr##
4009 setlo #gprello(label), gr##
4012 We may often be able to share gr# for multiple
4013 computations of GPREL addresses, and we may often fold
4014 the final add into the pair of registers of a load or
4015 store instruction, so it's often profitable. Even when
4016 optimizing for size, we're trading a GOT entry for an
4017 additional instruction, which trades GOT space
4018 (read-write) for code size (read-only, shareable), as
4019 long as the symbol is not used in more than two different
4022 With -fpie/-fpic, we'd be trading a single load for a
4023 sequence of 4 instructions, because the offset of the
4024 label can't be assumed to be addressable with 12 bits, so
4025 we don't do this. */
4026 if (TARGET_GPREL_RO
)
4027 unspec
= R_FRV_GPREL12
;
4029 unspec
= R_FRV_GOT12
;
4032 base_regno
= PIC_REGNO
;
4037 if (frv_const_unspec_p (src
, &old_unspec
))
4040 if (TARGET_FDPIC
&& frv_function_symbol_referenced_p (XEXP (src
, 0)))
4043 src
= force_reg (GET_MODE (XEXP (src
, 0)), XEXP (src
, 0));
4044 emit_move_insn (dest
, src
);
4049 sym
= XEXP (sym
, 0);
4050 if (GET_CODE (sym
) == PLUS
4051 && GET_CODE (XEXP (sym
, 0)) == SYMBOL_REF
4052 && GET_CODE (XEXP (sym
, 1)) == CONST_INT
)
4053 sym
= XEXP (sym
, 0);
4054 if (GET_CODE (sym
) == SYMBOL_REF
)
4056 else if (GET_CODE (sym
) == LABEL_REF
)
4059 goto handle_whatever
;
4067 enum tls_model model
= SYMBOL_REF_TLS_MODEL (sym
);
4071 src
= frv_legitimize_tls_address (src
, model
);
4072 emit_move_insn (dest
, src
);
4076 if (SYMBOL_REF_FUNCTION_P (sym
))
4078 if (frv_local_funcdesc_p (sym
))
4079 unspec
= R_FRV_FUNCDESC_GOTOFF12
;
4081 unspec
= R_FRV_FUNCDESC_GOT12
;
4085 if (CONSTANT_POOL_ADDRESS_P (sym
))
4086 switch (GET_CODE (get_pool_constant (sym
)))
4093 unspec
= R_FRV_GOTOFF12
;
4098 if (TARGET_GPREL_RO
)
4099 unspec
= R_FRV_GPREL12
;
4101 unspec
= R_FRV_GOT12
;
4104 else if (SYMBOL_REF_LOCAL_P (sym
)
4105 && !SYMBOL_REF_EXTERNAL_P (sym
)
4106 && SYMBOL_REF_DECL (sym
)
4107 && (!DECL_P (SYMBOL_REF_DECL (sym
))
4108 || !DECL_COMMON (SYMBOL_REF_DECL (sym
))))
4110 tree decl
= SYMBOL_REF_DECL (sym
);
4111 tree init
= TREE_CODE (decl
) == VAR_DECL
4112 ? DECL_INITIAL (decl
)
4113 : TREE_CODE (decl
) == CONSTRUCTOR
4116 bool named_section
, readonly
;
4118 if (init
&& init
!= error_mark_node
)
4119 reloc
= compute_reloc_for_constant (init
);
4121 named_section
= TREE_CODE (decl
) == VAR_DECL
4122 && lookup_attribute ("section", DECL_ATTRIBUTES (decl
));
4123 readonly
= decl_readonly_section (decl
, reloc
);
4126 unspec
= R_FRV_GOT12
;
4128 unspec
= R_FRV_GOTOFF12
;
4129 else if (readonly
&& TARGET_GPREL_RO
)
4130 unspec
= R_FRV_GPREL12
;
4132 unspec
= R_FRV_GOT12
;
4135 unspec
= R_FRV_GOT12
;
4139 else if (SYMBOL_REF_SMALL_P (sym
))
4140 base_regno
= SDA_BASE_REG
;
4143 base_regno
= PIC_REGNO
;
4148 if (base_regno
>= 0)
4150 if (GET_CODE (sym
) == SYMBOL_REF
&& SYMBOL_REF_SMALL_P (sym
))
4151 emit_insn (gen_symGOTOFF2reg (dest
, src
,
4152 gen_rtx_REG (Pmode
, base_regno
),
4153 GEN_INT (R_FRV_GPREL12
)));
4155 emit_insn (gen_symGOTOFF2reg_hilo (dest
, src
,
4156 gen_rtx_REG (Pmode
, base_regno
),
4157 GEN_INT (R_FRV_GPREL12
)));
4158 if (base_regno
== PIC_REGNO
)
4159 crtl
->uses_pic_offset_table
= TRUE
;
4167 /* Since OUR_FDPIC_REG is a pseudo register, we can't safely introduce
4168 new uses of it once reload has begun. */
4169 gcc_assert (!reload_in_progress
&& !reload_completed
);
4173 case R_FRV_GOTOFF12
:
4174 if (!frv_small_data_reloc_p (sym
, unspec
))
4175 x
= gen_symGOTOFF2reg_hilo (dest
, src
, OUR_FDPIC_REG
,
4178 x
= gen_symGOTOFF2reg (dest
, src
, OUR_FDPIC_REG
, GEN_INT (unspec
));
4181 if (!frv_small_data_reloc_p (sym
, unspec
))
4182 x
= gen_symGPREL2reg_hilo (dest
, src
, OUR_FDPIC_REG
,
4185 x
= gen_symGPREL2reg (dest
, src
, OUR_FDPIC_REG
, GEN_INT (unspec
));
4187 case R_FRV_FUNCDESC_GOTOFF12
:
4189 x
= gen_symGOTOFF2reg_hilo (dest
, src
, OUR_FDPIC_REG
,
4192 x
= gen_symGOTOFF2reg (dest
, src
, OUR_FDPIC_REG
, GEN_INT (unspec
));
4196 x
= gen_symGOT2reg_hilo (dest
, src
, OUR_FDPIC_REG
,
4199 x
= gen_symGOT2reg (dest
, src
, OUR_FDPIC_REG
, GEN_INT (unspec
));
4203 crtl
->uses_pic_offset_table
= TRUE
;
4212 /* Return a string to output a single word move. */
4215 output_move_single (rtx operands
[], rtx insn
)
4217 rtx dest
= operands
[0];
4218 rtx src
= operands
[1];
4220 if (GET_CODE (dest
) == REG
)
4222 int dest_regno
= REGNO (dest
);
4223 machine_mode mode
= GET_MODE (dest
);
4225 if (GPR_P (dest_regno
))
4227 if (GET_CODE (src
) == REG
)
4229 /* gpr <- some sort of register */
4230 int src_regno
= REGNO (src
);
4232 if (GPR_P (src_regno
))
4233 return "mov %1, %0";
4235 else if (FPR_P (src_regno
))
4236 return "movfg %1, %0";
4238 else if (SPR_P (src_regno
))
4239 return "movsg %1, %0";
4242 else if (GET_CODE (src
) == MEM
)
4251 return "ldsb%I1%U1 %M1,%0";
4254 return "ldsh%I1%U1 %M1,%0";
4258 return "ld%I1%U1 %M1, %0";
4262 else if (GET_CODE (src
) == CONST_INT
4263 || GET_CODE (src
) == CONST_DOUBLE
)
4265 /* gpr <- integer/floating constant */
4266 HOST_WIDE_INT value
;
4268 if (GET_CODE (src
) == CONST_INT
)
4269 value
= INTVAL (src
);
4271 else if (mode
== SFmode
)
4275 REAL_VALUE_TO_TARGET_SINGLE
4276 (*CONST_DOUBLE_REAL_VALUE (src
), l
);
4281 value
= CONST_DOUBLE_LOW (src
);
4283 if (IN_RANGE (value
, -32768, 32767))
4284 return "setlos %1, %0";
4289 else if (GET_CODE (src
) == SYMBOL_REF
4290 || GET_CODE (src
) == LABEL_REF
4291 || GET_CODE (src
) == CONST
)
4297 else if (FPR_P (dest_regno
))
4299 if (GET_CODE (src
) == REG
)
4301 /* fpr <- some sort of register */
4302 int src_regno
= REGNO (src
);
4304 if (GPR_P (src_regno
))
4305 return "movgf %1, %0";
4307 else if (FPR_P (src_regno
))
4309 if (TARGET_HARD_FLOAT
)
4310 return "fmovs %1, %0";
4312 return "mor %1, %1, %0";
4316 else if (GET_CODE (src
) == MEM
)
4325 return "ldbf%I1%U1 %M1,%0";
4328 return "ldhf%I1%U1 %M1,%0";
4332 return "ldf%I1%U1 %M1, %0";
4336 else if (ZERO_P (src
))
4337 return "movgf %., %0";
4340 else if (SPR_P (dest_regno
))
4342 if (GET_CODE (src
) == REG
)
4344 /* spr <- some sort of register */
4345 int src_regno
= REGNO (src
);
4347 if (GPR_P (src_regno
))
4348 return "movgs %1, %0";
4350 else if (ZERO_P (src
))
4351 return "movgs %., %0";
4355 else if (GET_CODE (dest
) == MEM
)
4357 if (GET_CODE (src
) == REG
)
4359 int src_regno
= REGNO (src
);
4360 machine_mode mode
= GET_MODE (dest
);
4362 if (GPR_P (src_regno
))
4370 return "stb%I0%U0 %1, %M0";
4373 return "sth%I0%U0 %1, %M0";
4377 return "st%I0%U0 %1, %M0";
4381 else if (FPR_P (src_regno
))
4389 return "stbf%I0%U0 %1, %M0";
4392 return "sthf%I0%U0 %1, %M0";
4396 return "stf%I0%U0 %1, %M0";
4401 else if (ZERO_P (src
))
4403 switch (GET_MODE (dest
))
4409 return "stb%I0%U0 %., %M0";
4412 return "sth%I0%U0 %., %M0";
4416 return "st%I0%U0 %., %M0";
4421 fatal_insn ("bad output_move_single operand", insn
);
4426 /* Return a string to output a double word move. */
4429 output_move_double (rtx operands
[], rtx insn
)
4431 rtx dest
= operands
[0];
4432 rtx src
= operands
[1];
4433 machine_mode mode
= GET_MODE (dest
);
4435 if (GET_CODE (dest
) == REG
)
4437 int dest_regno
= REGNO (dest
);
4439 if (GPR_P (dest_regno
))
4441 if (GET_CODE (src
) == REG
)
4443 /* gpr <- some sort of register */
4444 int src_regno
= REGNO (src
);
4446 if (GPR_P (src_regno
))
4449 else if (FPR_P (src_regno
))
4451 if (((dest_regno
- GPR_FIRST
) & 1) == 0
4452 && ((src_regno
- FPR_FIRST
) & 1) == 0)
4453 return "movfgd %1, %0";
4459 else if (GET_CODE (src
) == MEM
)
4462 if (dbl_memory_one_insn_operand (src
, mode
))
4463 return "ldd%I1%U1 %M1, %0";
4468 else if (GET_CODE (src
) == CONST_INT
4469 || GET_CODE (src
) == CONST_DOUBLE
)
4473 else if (FPR_P (dest_regno
))
4475 if (GET_CODE (src
) == REG
)
4477 /* fpr <- some sort of register */
4478 int src_regno
= REGNO (src
);
4480 if (GPR_P (src_regno
))
4482 if (((dest_regno
- FPR_FIRST
) & 1) == 0
4483 && ((src_regno
- GPR_FIRST
) & 1) == 0)
4484 return "movgfd %1, %0";
4489 else if (FPR_P (src_regno
))
4492 && ((dest_regno
- FPR_FIRST
) & 1) == 0
4493 && ((src_regno
- FPR_FIRST
) & 1) == 0)
4494 return "fmovd %1, %0";
4500 else if (GET_CODE (src
) == MEM
)
4503 if (dbl_memory_one_insn_operand (src
, mode
))
4504 return "lddf%I1%U1 %M1, %0";
4509 else if (ZERO_P (src
))
4514 else if (GET_CODE (dest
) == MEM
)
4516 if (GET_CODE (src
) == REG
)
4518 int src_regno
= REGNO (src
);
4520 if (GPR_P (src_regno
))
4522 if (((src_regno
- GPR_FIRST
) & 1) == 0
4523 && dbl_memory_one_insn_operand (dest
, mode
))
4524 return "std%I0%U0 %1, %M0";
4529 if (FPR_P (src_regno
))
4531 if (((src_regno
- FPR_FIRST
) & 1) == 0
4532 && dbl_memory_one_insn_operand (dest
, mode
))
4533 return "stdf%I0%U0 %1, %M0";
4539 else if (ZERO_P (src
))
4541 if (dbl_memory_one_insn_operand (dest
, mode
))
4542 return "std%I0%U0 %., %M0";
4548 fatal_insn ("bad output_move_double operand", insn
);
4553 /* Return a string to output a single word conditional move.
4554 Operand0 -- EQ/NE of ccr register and 0
4555 Operand1 -- CCR register
4556 Operand2 -- destination
4557 Operand3 -- source */
4560 output_condmove_single (rtx operands
[], rtx insn
)
4562 rtx dest
= operands
[2];
4563 rtx src
= operands
[3];
4565 if (GET_CODE (dest
) == REG
)
4567 int dest_regno
= REGNO (dest
);
4568 machine_mode mode
= GET_MODE (dest
);
4570 if (GPR_P (dest_regno
))
4572 if (GET_CODE (src
) == REG
)
4574 /* gpr <- some sort of register */
4575 int src_regno
= REGNO (src
);
4577 if (GPR_P (src_regno
))
4578 return "cmov %z3, %2, %1, %e0";
4580 else if (FPR_P (src_regno
))
4581 return "cmovfg %3, %2, %1, %e0";
4584 else if (GET_CODE (src
) == MEM
)
4593 return "cldsb%I3%U3 %M3, %2, %1, %e0";
4596 return "cldsh%I3%U3 %M3, %2, %1, %e0";
4600 return "cld%I3%U3 %M3, %2, %1, %e0";
4604 else if (ZERO_P (src
))
4605 return "cmov %., %2, %1, %e0";
4608 else if (FPR_P (dest_regno
))
4610 if (GET_CODE (src
) == REG
)
4612 /* fpr <- some sort of register */
4613 int src_regno
= REGNO (src
);
4615 if (GPR_P (src_regno
))
4616 return "cmovgf %3, %2, %1, %e0";
4618 else if (FPR_P (src_regno
))
4620 if (TARGET_HARD_FLOAT
)
4621 return "cfmovs %3,%2,%1,%e0";
4623 return "cmor %3, %3, %2, %1, %e0";
4627 else if (GET_CODE (src
) == MEM
)
4630 if (mode
== SImode
|| mode
== SFmode
)
4631 return "cldf%I3%U3 %M3, %2, %1, %e0";
4634 else if (ZERO_P (src
))
4635 return "cmovgf %., %2, %1, %e0";
4639 else if (GET_CODE (dest
) == MEM
)
4641 if (GET_CODE (src
) == REG
)
4643 int src_regno
= REGNO (src
);
4644 machine_mode mode
= GET_MODE (dest
);
4646 if (GPR_P (src_regno
))
4654 return "cstb%I2%U2 %3, %M2, %1, %e0";
4657 return "csth%I2%U2 %3, %M2, %1, %e0";
4661 return "cst%I2%U2 %3, %M2, %1, %e0";
4665 else if (FPR_P (src_regno
) && (mode
== SImode
|| mode
== SFmode
))
4666 return "cstf%I2%U2 %3, %M2, %1, %e0";
4669 else if (ZERO_P (src
))
4671 machine_mode mode
= GET_MODE (dest
);
4678 return "cstb%I2%U2 %., %M2, %1, %e0";
4681 return "csth%I2%U2 %., %M2, %1, %e0";
4685 return "cst%I2%U2 %., %M2, %1, %e0";
4690 fatal_insn ("bad output_condmove_single operand", insn
);
4695 /* Emit the appropriate code to do a comparison, returning the register the
4696 comparison was done it. */
4699 frv_emit_comparison (enum rtx_code test
, rtx op0
, rtx op1
)
4701 machine_mode cc_mode
;
4704 /* Floating point doesn't have comparison against a constant. */
4705 if (GET_MODE (op0
) == CC_FPmode
&& GET_CODE (op1
) != REG
)
4706 op1
= force_reg (GET_MODE (op0
), op1
);
4708 /* Possibly disable using anything but a fixed register in order to work
4709 around cse moving comparisons past function calls. */
4710 cc_mode
= SELECT_CC_MODE (test
, op0
, op1
);
4711 cc_reg
= ((TARGET_ALLOC_CC
)
4712 ? gen_reg_rtx (cc_mode
)
4713 : gen_rtx_REG (cc_mode
,
4714 (cc_mode
== CC_FPmode
) ? FCC_FIRST
: ICC_FIRST
));
4716 emit_insn (gen_rtx_SET (cc_reg
, gen_rtx_COMPARE (cc_mode
, op0
, op1
)));
4722 /* Emit code for a conditional branch.
4723 XXX: I originally wanted to add a clobber of a CCR register to use in
4724 conditional execution, but that confuses the rest of the compiler. */
4727 frv_emit_cond_branch (rtx operands
[])
4732 enum rtx_code test
= GET_CODE (operands
[0]);
4733 rtx cc_reg
= frv_emit_comparison (test
, operands
[1], operands
[2]);
4734 machine_mode cc_mode
= GET_MODE (cc_reg
);
4736 /* Branches generate:
4738 (if_then_else (<test>, <cc_reg>, (const_int 0))
4739 (label_ref <branch_label>)
4741 label_ref
= gen_rtx_LABEL_REF (VOIDmode
, operands
[3]);
4742 test_rtx
= gen_rtx_fmt_ee (test
, cc_mode
, cc_reg
, const0_rtx
);
4743 if_else
= gen_rtx_IF_THEN_ELSE (cc_mode
, test_rtx
, label_ref
, pc_rtx
);
4744 emit_jump_insn (gen_rtx_SET (pc_rtx
, if_else
));
4749 /* Emit code to set a gpr to 1/0 based on a comparison. */
4752 frv_emit_scc (rtx operands
[])
4758 enum rtx_code test
= GET_CODE (operands
[1]);
4759 rtx cc_reg
= frv_emit_comparison (test
, operands
[2], operands
[3]);
4761 /* SCC instructions generate:
4762 (parallel [(set <target> (<test>, <cc_reg>, (const_int 0))
4763 (clobber (<ccr_reg>))]) */
4764 test_rtx
= gen_rtx_fmt_ee (test
, SImode
, cc_reg
, const0_rtx
);
4765 set
= gen_rtx_SET (operands
[0], test_rtx
);
4767 cr_reg
= ((TARGET_ALLOC_CC
)
4768 ? gen_reg_rtx (CC_CCRmode
)
4769 : gen_rtx_REG (CC_CCRmode
,
4770 ((GET_MODE (cc_reg
) == CC_FPmode
)
4774 clobber
= gen_rtx_CLOBBER (VOIDmode
, cr_reg
);
4775 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, set
, clobber
)));
4780 /* Split a SCC instruction into component parts, returning a SEQUENCE to hold
4781 the separate insns. */
4784 frv_split_scc (rtx dest
, rtx test
, rtx cc_reg
, rtx cr_reg
, HOST_WIDE_INT value
)
4790 /* Set the appropriate CCR bit. */
4791 emit_insn (gen_rtx_SET (cr_reg
,
4792 gen_rtx_fmt_ee (GET_CODE (test
),
4797 /* Move the value into the destination. */
4798 emit_move_insn (dest
, GEN_INT (value
));
4800 /* Move 0 into the destination if the test failed */
4801 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
4802 gen_rtx_EQ (GET_MODE (cr_reg
),
4805 gen_rtx_SET (dest
, const0_rtx
)));
4807 /* Finish up, return sequence. */
4814 /* Emit the code for a conditional move, return TRUE if we could do the
4818 frv_emit_cond_move (rtx dest
, rtx test_rtx
, rtx src1
, rtx src2
)
4825 enum rtx_code test
= GET_CODE (test_rtx
);
4826 rtx cc_reg
= frv_emit_comparison (test
,
4827 XEXP (test_rtx
, 0), XEXP (test_rtx
, 1));
4828 machine_mode cc_mode
= GET_MODE (cc_reg
);
4830 /* Conditional move instructions generate:
4831 (parallel [(set <target>
4832 (if_then_else (<test> <cc_reg> (const_int 0))
4835 (clobber (<ccr_reg>))]) */
4837 /* Handle various cases of conditional move involving two constants. */
4838 if (GET_CODE (src1
) == CONST_INT
&& GET_CODE (src2
) == CONST_INT
)
4840 HOST_WIDE_INT value1
= INTVAL (src1
);
4841 HOST_WIDE_INT value2
= INTVAL (src2
);
4843 /* Having 0 as one of the constants can be done by loading the other
4844 constant, and optionally moving in gr0. */
4845 if (value1
== 0 || value2
== 0)
4848 /* If the first value is within an addi range and also the difference
4849 between the two fits in an addi's range, load up the difference, then
4850 conditionally move in 0, and then unconditionally add the first
4852 else if (IN_RANGE (value1
, -2048, 2047)
4853 && IN_RANGE (value2
- value1
, -2048, 2047))
4856 /* If neither condition holds, just force the constant into a
4860 src1
= force_reg (GET_MODE (dest
), src1
);
4861 src2
= force_reg (GET_MODE (dest
), src2
);
4865 /* If one value is a register, insure the other value is either 0 or a
4869 if (GET_CODE (src1
) == CONST_INT
&& INTVAL (src1
) != 0)
4870 src1
= force_reg (GET_MODE (dest
), src1
);
4872 if (GET_CODE (src2
) == CONST_INT
&& INTVAL (src2
) != 0)
4873 src2
= force_reg (GET_MODE (dest
), src2
);
4876 test2
= gen_rtx_fmt_ee (test
, cc_mode
, cc_reg
, const0_rtx
);
4877 if_rtx
= gen_rtx_IF_THEN_ELSE (GET_MODE (dest
), test2
, src1
, src2
);
4879 set
= gen_rtx_SET (dest
, if_rtx
);
4881 cr_reg
= ((TARGET_ALLOC_CC
)
4882 ? gen_reg_rtx (CC_CCRmode
)
4883 : gen_rtx_REG (CC_CCRmode
,
4884 (cc_mode
== CC_FPmode
) ? FCR_FIRST
: ICR_FIRST
));
4886 clobber_cc
= gen_rtx_CLOBBER (VOIDmode
, cr_reg
);
4887 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, set
, clobber_cc
)));
4892 /* Split a conditional move into constituent parts, returning a SEQUENCE
4893 containing all of the insns. */
4896 frv_split_cond_move (rtx operands
[])
4898 rtx dest
= operands
[0];
4899 rtx test
= operands
[1];
4900 rtx cc_reg
= operands
[2];
4901 rtx src1
= operands
[3];
4902 rtx src2
= operands
[4];
4903 rtx cr_reg
= operands
[5];
4905 machine_mode cr_mode
= GET_MODE (cr_reg
);
4909 /* Set the appropriate CCR bit. */
4910 emit_insn (gen_rtx_SET (cr_reg
,
4911 gen_rtx_fmt_ee (GET_CODE (test
),
4916 /* Handle various cases of conditional move involving two constants. */
4917 if (GET_CODE (src1
) == CONST_INT
&& GET_CODE (src2
) == CONST_INT
)
4919 HOST_WIDE_INT value1
= INTVAL (src1
);
4920 HOST_WIDE_INT value2
= INTVAL (src2
);
4922 /* Having 0 as one of the constants can be done by loading the other
4923 constant, and optionally moving in gr0. */
4926 emit_move_insn (dest
, src2
);
4927 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
4928 gen_rtx_NE (cr_mode
, cr_reg
,
4930 gen_rtx_SET (dest
, src1
)));
4933 else if (value2
== 0)
4935 emit_move_insn (dest
, src1
);
4936 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
4937 gen_rtx_EQ (cr_mode
, cr_reg
,
4939 gen_rtx_SET (dest
, src2
)));
4942 /* If the first value is within an addi range and also the difference
4943 between the two fits in an addi's range, load up the difference, then
4944 conditionally move in 0, and then unconditionally add the first
4946 else if (IN_RANGE (value1
, -2048, 2047)
4947 && IN_RANGE (value2
- value1
, -2048, 2047))
4949 rtx dest_si
= ((GET_MODE (dest
) == SImode
)
4951 : gen_rtx_SUBREG (SImode
, dest
, 0));
4953 emit_move_insn (dest_si
, GEN_INT (value2
- value1
));
4954 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
4955 gen_rtx_NE (cr_mode
, cr_reg
,
4957 gen_rtx_SET (dest_si
, const0_rtx
)));
4958 emit_insn (gen_addsi3 (dest_si
, dest_si
, src1
));
4966 /* Emit the conditional move for the test being true if needed. */
4967 if (! rtx_equal_p (dest
, src1
))
4968 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
4969 gen_rtx_NE (cr_mode
, cr_reg
, const0_rtx
),
4970 gen_rtx_SET (dest
, src1
)));
4972 /* Emit the conditional move for the test being false if needed. */
4973 if (! rtx_equal_p (dest
, src2
))
4974 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
4975 gen_rtx_EQ (cr_mode
, cr_reg
, const0_rtx
),
4976 gen_rtx_SET (dest
, src2
)));
4979 /* Finish up, return sequence. */
4986 /* Split (set DEST SOURCE), where DEST is a double register and SOURCE is a
4987 memory location that is not known to be dword-aligned. */
4989 frv_split_double_load (rtx dest
, rtx source
)
4991 int regno
= REGNO (dest
);
4992 rtx dest1
= gen_highpart (SImode
, dest
);
4993 rtx dest2
= gen_lowpart (SImode
, dest
);
4994 rtx address
= XEXP (source
, 0);
4996 /* If the address is pre-modified, load the lower-numbered register
4997 first, then load the other register using an integer offset from
4998 the modified base register. This order should always be safe,
4999 since the pre-modification cannot affect the same registers as the
5002 The situation for other loads is more complicated. Loading one
5003 of the registers could affect the value of ADDRESS, so we must
5004 be careful which order we do them in. */
5005 if (GET_CODE (address
) == PRE_MODIFY
5006 || ! refers_to_regno_p (regno
, address
))
5008 /* It is safe to load the lower-numbered register first. */
5009 emit_move_insn (dest1
, change_address (source
, SImode
, NULL
));
5010 emit_move_insn (dest2
, frv_index_memory (source
, SImode
, 1));
5014 /* ADDRESS is not pre-modified and the address depends on the
5015 lower-numbered register. Load the higher-numbered register
5017 emit_move_insn (dest2
, frv_index_memory (source
, SImode
, 1));
5018 emit_move_insn (dest1
, change_address (source
, SImode
, NULL
));
5022 /* Split (set DEST SOURCE), where DEST refers to a dword memory location
5023 and SOURCE is either a double register or the constant zero. */
5025 frv_split_double_store (rtx dest
, rtx source
)
5027 rtx dest1
= change_address (dest
, SImode
, NULL
);
5028 rtx dest2
= frv_index_memory (dest
, SImode
, 1);
5029 if (ZERO_P (source
))
5031 emit_move_insn (dest1
, CONST0_RTX (SImode
));
5032 emit_move_insn (dest2
, CONST0_RTX (SImode
));
5036 emit_move_insn (dest1
, gen_highpart (SImode
, source
));
5037 emit_move_insn (dest2
, gen_lowpart (SImode
, source
));
5042 /* Split a min/max operation returning a SEQUENCE containing all of the
5046 frv_split_minmax (rtx operands
[])
5048 rtx dest
= operands
[0];
5049 rtx minmax
= operands
[1];
5050 rtx src1
= operands
[2];
5051 rtx src2
= operands
[3];
5052 rtx cc_reg
= operands
[4];
5053 rtx cr_reg
= operands
[5];
5055 enum rtx_code test_code
;
5056 machine_mode cr_mode
= GET_MODE (cr_reg
);
5060 /* Figure out which test to use. */
5061 switch (GET_CODE (minmax
))
5066 case SMIN
: test_code
= LT
; break;
5067 case SMAX
: test_code
= GT
; break;
5068 case UMIN
: test_code
= LTU
; break;
5069 case UMAX
: test_code
= GTU
; break;
5072 /* Issue the compare instruction. */
5073 emit_insn (gen_rtx_SET (cc_reg
, gen_rtx_COMPARE (GET_MODE (cc_reg
),
5076 /* Set the appropriate CCR bit. */
5077 emit_insn (gen_rtx_SET (cr_reg
, gen_rtx_fmt_ee (test_code
,
5082 /* If are taking the min/max of a nonzero constant, load that first, and
5083 then do a conditional move of the other value. */
5084 if (GET_CODE (src2
) == CONST_INT
&& INTVAL (src2
) != 0)
5086 gcc_assert (!rtx_equal_p (dest
, src1
));
5088 emit_move_insn (dest
, src2
);
5089 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
5090 gen_rtx_NE (cr_mode
, cr_reg
, const0_rtx
),
5091 gen_rtx_SET (dest
, src1
)));
5094 /* Otherwise, do each half of the move. */
5097 /* Emit the conditional move for the test being true if needed. */
5098 if (! rtx_equal_p (dest
, src1
))
5099 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
5100 gen_rtx_NE (cr_mode
, cr_reg
, const0_rtx
),
5101 gen_rtx_SET (dest
, src1
)));
5103 /* Emit the conditional move for the test being false if needed. */
5104 if (! rtx_equal_p (dest
, src2
))
5105 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
5106 gen_rtx_EQ (cr_mode
, cr_reg
, const0_rtx
),
5107 gen_rtx_SET (dest
, src2
)));
5110 /* Finish up, return sequence. */
5117 /* Split an integer abs operation returning a SEQUENCE containing all of the
5121 frv_split_abs (rtx operands
[])
5123 rtx dest
= operands
[0];
5124 rtx src
= operands
[1];
5125 rtx cc_reg
= operands
[2];
5126 rtx cr_reg
= operands
[3];
5131 /* Issue the compare < 0 instruction. */
5132 emit_insn (gen_rtx_SET (cc_reg
, gen_rtx_COMPARE (CCmode
, src
, const0_rtx
)));
5134 /* Set the appropriate CCR bit. */
5135 emit_insn (gen_rtx_SET (cr_reg
, gen_rtx_fmt_ee (LT
, CC_CCRmode
,
5136 cc_reg
, const0_rtx
)));
5138 /* Emit the conditional negate if the value is negative. */
5139 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
5140 gen_rtx_NE (CC_CCRmode
, cr_reg
, const0_rtx
),
5141 gen_negsi2 (dest
, src
)));
5143 /* Emit the conditional move for the test being false if needed. */
5144 if (! rtx_equal_p (dest
, src
))
5145 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
5146 gen_rtx_EQ (CC_CCRmode
, cr_reg
, const0_rtx
),
5147 gen_rtx_SET (dest
, src
)));
5149 /* Finish up, return sequence. */
5156 /* Initialize machine-specific if-conversion data.
5157 On the FR-V, we don't have any extra fields per se, but it is useful hook to
5158 initialize the static storage. */
5160 frv_ifcvt_machdep_init (void *ce_info ATTRIBUTE_UNUSED
)
5162 frv_ifcvt
.added_insns_list
= NULL_RTX
;
5163 frv_ifcvt
.cur_scratch_regs
= 0;
5164 frv_ifcvt
.num_nested_cond_exec
= 0;
5165 frv_ifcvt
.cr_reg
= NULL_RTX
;
5166 frv_ifcvt
.nested_cc_reg
= NULL_RTX
;
5167 frv_ifcvt
.extra_int_cr
= NULL_RTX
;
5168 frv_ifcvt
.extra_fp_cr
= NULL_RTX
;
5169 frv_ifcvt
.last_nested_if_cr
= NULL_RTX
;
5173 /* Internal function to add a potential insn to the list of insns to be inserted
5174 if the conditional execution conversion is successful. */
5177 frv_ifcvt_add_insn (rtx pattern
, rtx insn
, int before_p
)
5179 rtx link
= alloc_EXPR_LIST (VOIDmode
, pattern
, insn
);
5181 link
->jump
= before_p
; /* Mark to add this before or after insn. */
5182 frv_ifcvt
.added_insns_list
= alloc_EXPR_LIST (VOIDmode
, link
,
5183 frv_ifcvt
.added_insns_list
);
5185 if (TARGET_DEBUG_COND_EXEC
)
5188 "\n:::::::::: frv_ifcvt_add_insn: add the following %s insn %d:\n",
5189 (before_p
) ? "before" : "after",
5190 (int)INSN_UID (insn
));
5192 debug_rtx (pattern
);
5197 /* A C expression to modify the code described by the conditional if
5198 information CE_INFO, possibly updating the tests in TRUE_EXPR, and
5199 FALSE_EXPR for converting if-then and if-then-else code to conditional
5200 instructions. Set either TRUE_EXPR or FALSE_EXPR to a null pointer if the
5201 tests cannot be converted. */
5204 frv_ifcvt_modify_tests (ce_if_block
*ce_info
, rtx
*p_true
, rtx
*p_false
)
5206 basic_block test_bb
= ce_info
->test_bb
; /* test basic block */
5207 basic_block then_bb
= ce_info
->then_bb
; /* THEN */
5208 basic_block else_bb
= ce_info
->else_bb
; /* ELSE or NULL */
5209 basic_block join_bb
= ce_info
->join_bb
; /* join block or NULL */
5210 rtx true_expr
= *p_true
;
5214 machine_mode mode
= GET_MODE (true_expr
);
5218 frv_tmp_reg_t
*tmp_reg
= &frv_ifcvt
.tmp_reg
;
5220 rtx sub_cond_exec_reg
;
5222 enum rtx_code code_true
;
5223 enum rtx_code code_false
;
5224 enum reg_class cc_class
;
5225 enum reg_class cr_class
;
5228 reg_set_iterator rsi
;
5230 /* Make sure we are only dealing with hard registers. Also honor the
5231 -mno-cond-exec switch, and -mno-nested-cond-exec switches if
5233 if (!reload_completed
|| !TARGET_COND_EXEC
5234 || (!TARGET_NESTED_CE
&& ce_info
->pass
> 1))
5237 /* Figure out which registers we can allocate for our own purposes. Only
5238 consider registers that are not preserved across function calls and are
5239 not fixed. However, allow the ICC/ICR temporary registers to be allocated
5240 if we did not need to use them in reloading other registers. */
5241 memset (&tmp_reg
->regs
, 0, sizeof (tmp_reg
->regs
));
5242 COPY_HARD_REG_SET (tmp_reg
->regs
, call_used_reg_set
);
5243 AND_COMPL_HARD_REG_SET (tmp_reg
->regs
, fixed_reg_set
);
5244 SET_HARD_REG_BIT (tmp_reg
->regs
, ICC_TEMP
);
5245 SET_HARD_REG_BIT (tmp_reg
->regs
, ICR_TEMP
);
5247 /* If this is a nested IF, we need to discover whether the CC registers that
5248 are set/used inside of the block are used anywhere else. If not, we can
5249 change them to be the CC register that is paired with the CR register that
5250 controls the outermost IF block. */
5251 if (ce_info
->pass
> 1)
5253 CLEAR_HARD_REG_SET (frv_ifcvt
.nested_cc_ok_rewrite
);
5254 for (j
= CC_FIRST
; j
<= CC_LAST
; j
++)
5255 if (TEST_HARD_REG_BIT (tmp_reg
->regs
, j
))
5257 if (REGNO_REG_SET_P (df_get_live_in (then_bb
), j
))
5261 && REGNO_REG_SET_P (df_get_live_in (else_bb
), j
))
5265 && REGNO_REG_SET_P (df_get_live_in (join_bb
), j
))
5268 SET_HARD_REG_BIT (frv_ifcvt
.nested_cc_ok_rewrite
, j
);
5272 for (j
= 0; j
< frv_ifcvt
.cur_scratch_regs
; j
++)
5273 frv_ifcvt
.scratch_regs
[j
] = NULL_RTX
;
5275 frv_ifcvt
.added_insns_list
= NULL_RTX
;
5276 frv_ifcvt
.cur_scratch_regs
= 0;
5278 bb
= (basic_block
*) alloca ((2 + ce_info
->num_multiple_test_blocks
)
5279 * sizeof (basic_block
));
5285 /* Remove anything live at the beginning of the join block from being
5286 available for allocation. */
5287 EXECUTE_IF_SET_IN_REG_SET (df_get_live_in (join_bb
), 0, regno
, rsi
)
5289 if (regno
< FIRST_PSEUDO_REGISTER
)
5290 CLEAR_HARD_REG_BIT (tmp_reg
->regs
, regno
);
5294 /* Add in all of the blocks in multiple &&/|| blocks to be scanned. */
5296 if (ce_info
->num_multiple_test_blocks
)
5298 basic_block multiple_test_bb
= ce_info
->last_test_bb
;
5300 while (multiple_test_bb
!= test_bb
)
5302 bb
[num_bb
++] = multiple_test_bb
;
5303 multiple_test_bb
= EDGE_PRED (multiple_test_bb
, 0)->src
;
5307 /* Add in the THEN and ELSE blocks to be scanned. */
5308 bb
[num_bb
++] = then_bb
;
5310 bb
[num_bb
++] = else_bb
;
5312 sub_cond_exec_reg
= NULL_RTX
;
5313 frv_ifcvt
.num_nested_cond_exec
= 0;
5315 /* Scan all of the blocks for registers that must not be allocated. */
5316 for (j
= 0; j
< num_bb
; j
++)
5318 rtx_insn
*last_insn
= BB_END (bb
[j
]);
5319 rtx_insn
*insn
= BB_HEAD (bb
[j
]);
5323 fprintf (dump_file
, "Scanning %s block %d, start %d, end %d\n",
5324 (bb
[j
] == else_bb
) ? "else" : ((bb
[j
] == then_bb
) ? "then" : "test"),
5326 (int) INSN_UID (BB_HEAD (bb
[j
])),
5327 (int) INSN_UID (BB_END (bb
[j
])));
5329 /* Anything live at the beginning of the block is obviously unavailable
5331 EXECUTE_IF_SET_IN_REG_SET (df_get_live_in (bb
[j
]), 0, regno
, rsi
)
5333 if (regno
< FIRST_PSEUDO_REGISTER
)
5334 CLEAR_HARD_REG_BIT (tmp_reg
->regs
, regno
);
5337 /* Loop through the insns in the block. */
5340 /* Mark any new registers that are created as being unavailable for
5341 allocation. Also see if the CC register used in nested IFs can be
5347 int skip_nested_if
= FALSE
;
5348 HARD_REG_SET mentioned_regs
;
5350 CLEAR_HARD_REG_SET (mentioned_regs
);
5351 find_all_hard_regs (PATTERN (insn
), &mentioned_regs
);
5352 AND_COMPL_HARD_REG_SET (tmp_reg
->regs
, mentioned_regs
);
5354 pattern
= PATTERN (insn
);
5355 if (GET_CODE (pattern
) == COND_EXEC
)
5357 rtx reg
= XEXP (COND_EXEC_TEST (pattern
), 0);
5359 if (reg
!= sub_cond_exec_reg
)
5361 sub_cond_exec_reg
= reg
;
5362 frv_ifcvt
.num_nested_cond_exec
++;
5366 set
= single_set_pattern (pattern
);
5369 rtx dest
= SET_DEST (set
);
5370 rtx src
= SET_SRC (set
);
5372 if (GET_CODE (dest
) == REG
)
5374 int regno
= REGNO (dest
);
5375 enum rtx_code src_code
= GET_CODE (src
);
5377 if (CC_P (regno
) && src_code
== COMPARE
)
5378 skip_nested_if
= TRUE
;
5380 else if (CR_P (regno
)
5381 && (src_code
== IF_THEN_ELSE
5382 || COMPARISON_P (src
)))
5383 skip_nested_if
= TRUE
;
5387 if (! skip_nested_if
)
5388 AND_COMPL_HARD_REG_SET (frv_ifcvt
.nested_cc_ok_rewrite
,
5392 if (insn
== last_insn
)
5395 insn
= NEXT_INSN (insn
);
5399 /* If this is a nested if, rewrite the CC registers that are available to
5400 include the ones that can be rewritten, to increase the chance of being
5401 able to allocate a paired CC/CR register combination. */
5402 if (ce_info
->pass
> 1)
5404 for (j
= CC_FIRST
; j
<= CC_LAST
; j
++)
5405 if (TEST_HARD_REG_BIT (frv_ifcvt
.nested_cc_ok_rewrite
, j
))
5406 SET_HARD_REG_BIT (tmp_reg
->regs
, j
);
5408 CLEAR_HARD_REG_BIT (tmp_reg
->regs
, j
);
5414 fprintf (dump_file
, "Available GPRs: ");
5416 for (j
= GPR_FIRST
; j
<= GPR_LAST
; j
++)
5417 if (TEST_HARD_REG_BIT (tmp_reg
->regs
, j
))
5419 fprintf (dump_file
, " %d [%s]", j
, reg_names
[j
]);
5420 if (++num_gprs
> GPR_TEMP_NUM
+2)
5424 fprintf (dump_file
, "%s\nAvailable CRs: ",
5425 (num_gprs
> GPR_TEMP_NUM
+2) ? " ..." : "");
5427 for (j
= CR_FIRST
; j
<= CR_LAST
; j
++)
5428 if (TEST_HARD_REG_BIT (tmp_reg
->regs
, j
))
5429 fprintf (dump_file
, " %d [%s]", j
, reg_names
[j
]);
5431 fputs ("\n", dump_file
);
5433 if (ce_info
->pass
> 1)
5435 fprintf (dump_file
, "Modifiable CCs: ");
5436 for (j
= CC_FIRST
; j
<= CC_LAST
; j
++)
5437 if (TEST_HARD_REG_BIT (tmp_reg
->regs
, j
))
5438 fprintf (dump_file
, " %d [%s]", j
, reg_names
[j
]);
5440 fprintf (dump_file
, "\n%d nested COND_EXEC statements\n",
5441 frv_ifcvt
.num_nested_cond_exec
);
5445 /* Allocate the appropriate temporary condition code register. Try to
5446 allocate the ICR/FCR register that corresponds to the ICC/FCC register so
5447 that conditional cmp's can be done. */
5448 if (mode
== CCmode
|| mode
== CC_UNSmode
|| mode
== CC_NZmode
)
5450 cr_class
= ICR_REGS
;
5451 cc_class
= ICC_REGS
;
5452 cc_first
= ICC_FIRST
;
5455 else if (mode
== CC_FPmode
)
5457 cr_class
= FCR_REGS
;
5458 cc_class
= FCC_REGS
;
5459 cc_first
= FCC_FIRST
;
5464 cc_first
= cc_last
= 0;
5465 cr_class
= cc_class
= NO_REGS
;
5468 cc
= XEXP (true_expr
, 0);
5469 nested_cc
= cr
= NULL_RTX
;
5470 if (cc_class
!= NO_REGS
)
5472 /* For nested IFs and &&/||, see if we can find a CC and CR register pair
5473 so we can execute a csubcc/caddcc/cfcmps instruction. */
5476 for (cc_regno
= cc_first
; cc_regno
<= cc_last
; cc_regno
++)
5478 int cr_regno
= cc_regno
- CC_FIRST
+ CR_FIRST
;
5480 if (TEST_HARD_REG_BIT (frv_ifcvt
.tmp_reg
.regs
, cc_regno
)
5481 && TEST_HARD_REG_BIT (frv_ifcvt
.tmp_reg
.regs
, cr_regno
))
5483 frv_ifcvt
.tmp_reg
.next_reg
[ (int)cr_class
] = cr_regno
;
5484 cr
= frv_alloc_temp_reg (tmp_reg
, cr_class
, CC_CCRmode
, TRUE
,
5487 frv_ifcvt
.tmp_reg
.next_reg
[ (int)cc_class
] = cc_regno
;
5488 nested_cc
= frv_alloc_temp_reg (tmp_reg
, cc_class
, CCmode
,
5498 fprintf (dump_file
, "Could not allocate a CR temporary register\n");
5505 "Will use %s for conditional execution, %s for nested comparisons\n",
5506 reg_names
[ REGNO (cr
)],
5507 (nested_cc
) ? reg_names
[ REGNO (nested_cc
) ] : "<none>");
5509 /* Set the CCR bit. Note for integer tests, we reverse the condition so that
5510 in an IF-THEN-ELSE sequence, we are testing the TRUE case against the CCR
5511 bit being true. We don't do this for floating point, because of NaNs. */
5512 code
= GET_CODE (true_expr
);
5513 if (GET_MODE (cc
) != CC_FPmode
)
5515 code
= reverse_condition (code
);
5525 check_insn
= gen_rtx_SET (cr
, gen_rtx_fmt_ee (code
, CC_CCRmode
,
5528 /* Record the check insn to be inserted later. */
5529 frv_ifcvt_add_insn (check_insn
, BB_END (test_bb
), TRUE
);
5531 /* Update the tests. */
5532 frv_ifcvt
.cr_reg
= cr
;
5533 frv_ifcvt
.nested_cc_reg
= nested_cc
;
5534 *p_true
= gen_rtx_fmt_ee (code_true
, CC_CCRmode
, cr
, const0_rtx
);
5535 *p_false
= gen_rtx_fmt_ee (code_false
, CC_CCRmode
, cr
, const0_rtx
);
5538 /* Fail, don't do this conditional execution. */
5541 *p_false
= NULL_RTX
;
5543 fprintf (dump_file
, "Disabling this conditional execution.\n");
5549 /* A C expression to modify the code described by the conditional if
5550 information CE_INFO, for the basic block BB, possibly updating the tests in
5551 TRUE_EXPR, and FALSE_EXPR for converting the && and || parts of if-then or
5552 if-then-else code to conditional instructions. Set either TRUE_EXPR or
5553 FALSE_EXPR to a null pointer if the tests cannot be converted. */
5555 /* p_true and p_false are given expressions of the form:
5557 (and (eq:CC_CCR (reg:CC_CCR)
5563 frv_ifcvt_modify_multiple_tests (ce_if_block
*ce_info
,
5568 rtx old_true
= XEXP (*p_true
, 0);
5569 rtx old_false
= XEXP (*p_false
, 0);
5570 rtx true_expr
= XEXP (*p_true
, 1);
5571 rtx false_expr
= XEXP (*p_false
, 1);
5574 rtx cr
= XEXP (old_true
, 0);
5576 rtx new_cr
= NULL_RTX
;
5577 rtx
*p_new_cr
= (rtx
*)0;
5581 enum reg_class cr_class
;
5582 machine_mode mode
= GET_MODE (true_expr
);
5583 rtx (*logical_func
)(rtx
, rtx
, rtx
);
5585 if (TARGET_DEBUG_COND_EXEC
)
5588 "\n:::::::::: frv_ifcvt_modify_multiple_tests, before modification for %s\ntrue insn:\n",
5589 ce_info
->and_and_p
? "&&" : "||");
5591 debug_rtx (*p_true
);
5593 fputs ("\nfalse insn:\n", stderr
);
5594 debug_rtx (*p_false
);
5597 if (!TARGET_MULTI_CE
)
5600 if (GET_CODE (cr
) != REG
)
5603 if (mode
== CCmode
|| mode
== CC_UNSmode
|| mode
== CC_NZmode
)
5605 cr_class
= ICR_REGS
;
5606 p_new_cr
= &frv_ifcvt
.extra_int_cr
;
5608 else if (mode
== CC_FPmode
)
5610 cr_class
= FCR_REGS
;
5611 p_new_cr
= &frv_ifcvt
.extra_fp_cr
;
5616 /* Allocate a temp CR, reusing a previously allocated temp CR if we have 3 or
5617 more &&/|| tests. */
5621 new_cr
= *p_new_cr
= frv_alloc_temp_reg (&frv_ifcvt
.tmp_reg
, cr_class
,
5622 CC_CCRmode
, TRUE
, TRUE
);
5627 if (ce_info
->and_and_p
)
5629 old_test
= old_false
;
5630 test_expr
= true_expr
;
5631 logical_func
= (GET_CODE (old_true
) == EQ
) ? gen_andcr
: gen_andncr
;
5632 *p_true
= gen_rtx_NE (CC_CCRmode
, cr
, const0_rtx
);
5633 *p_false
= gen_rtx_EQ (CC_CCRmode
, cr
, const0_rtx
);
5637 old_test
= old_false
;
5638 test_expr
= false_expr
;
5639 logical_func
= (GET_CODE (old_false
) == EQ
) ? gen_orcr
: gen_orncr
;
5640 *p_true
= gen_rtx_EQ (CC_CCRmode
, cr
, const0_rtx
);
5641 *p_false
= gen_rtx_NE (CC_CCRmode
, cr
, const0_rtx
);
5644 /* First add the andcr/andncr/orcr/orncr, which will be added after the
5645 conditional check instruction, due to frv_ifcvt_add_insn being a LIFO
5647 frv_ifcvt_add_insn ((*logical_func
) (cr
, cr
, new_cr
), BB_END (bb
), TRUE
);
5649 /* Now add the conditional check insn. */
5650 cc
= XEXP (test_expr
, 0);
5651 compare
= gen_rtx_fmt_ee (GET_CODE (test_expr
), CC_CCRmode
, cc
, const0_rtx
);
5652 if_else
= gen_rtx_IF_THEN_ELSE (CC_CCRmode
, old_test
, compare
, const0_rtx
);
5654 check_insn
= gen_rtx_SET (new_cr
, if_else
);
5656 /* Add the new check insn to the list of check insns that need to be
5658 frv_ifcvt_add_insn (check_insn
, BB_END (bb
), TRUE
);
5660 if (TARGET_DEBUG_COND_EXEC
)
5662 fputs ("\n:::::::::: frv_ifcvt_modify_multiple_tests, after modification\ntrue insn:\n",
5665 debug_rtx (*p_true
);
5667 fputs ("\nfalse insn:\n", stderr
);
5668 debug_rtx (*p_false
);
5674 *p_true
= *p_false
= NULL_RTX
;
5676 /* If we allocated a CR register, release it. */
5679 CLEAR_HARD_REG_BIT (frv_ifcvt
.tmp_reg
.regs
, REGNO (new_cr
));
5680 *p_new_cr
= NULL_RTX
;
5683 if (TARGET_DEBUG_COND_EXEC
)
5684 fputs ("\n:::::::::: frv_ifcvt_modify_multiple_tests, failed.\n", stderr
);
5690 /* Return a register which will be loaded with a value if an IF block is
5691 converted to conditional execution. This is used to rewrite instructions
5692 that use constants to ones that just use registers. */
5695 frv_ifcvt_load_value (rtx value
, rtx insn ATTRIBUTE_UNUSED
)
5697 int num_alloc
= frv_ifcvt
.cur_scratch_regs
;
5701 /* We know gr0 == 0, so replace any errant uses. */
5702 if (value
== const0_rtx
)
5703 return gen_rtx_REG (SImode
, GPR_FIRST
);
5705 /* First search all registers currently loaded to see if we have an
5706 applicable constant. */
5707 if (CONSTANT_P (value
)
5708 || (GET_CODE (value
) == REG
&& REGNO (value
) == LR_REGNO
))
5710 for (i
= 0; i
< num_alloc
; i
++)
5712 if (rtx_equal_p (SET_SRC (frv_ifcvt
.scratch_regs
[i
]), value
))
5713 return SET_DEST (frv_ifcvt
.scratch_regs
[i
]);
5717 /* Have we exhausted the number of registers available? */
5718 if (num_alloc
>= GPR_TEMP_NUM
)
5721 fprintf (dump_file
, "Too many temporary registers allocated\n");
5726 /* Allocate the new register. */
5727 reg
= frv_alloc_temp_reg (&frv_ifcvt
.tmp_reg
, GPR_REGS
, SImode
, TRUE
, TRUE
);
5731 fputs ("Could not find a scratch register\n", dump_file
);
5736 frv_ifcvt
.cur_scratch_regs
++;
5737 frv_ifcvt
.scratch_regs
[num_alloc
] = gen_rtx_SET (reg
, value
);
5741 if (GET_CODE (value
) == CONST_INT
)
5742 fprintf (dump_file
, "Register %s will hold %ld\n",
5743 reg_names
[ REGNO (reg
)], (long)INTVAL (value
));
5745 else if (GET_CODE (value
) == REG
&& REGNO (value
) == LR_REGNO
)
5746 fprintf (dump_file
, "Register %s will hold LR\n",
5747 reg_names
[ REGNO (reg
)]);
5750 fprintf (dump_file
, "Register %s will hold a saved value\n",
5751 reg_names
[ REGNO (reg
)]);
5758 /* Update a MEM used in conditional code that might contain an offset to put
5759 the offset into a scratch register, so that the conditional load/store
5760 operations can be used. This function returns the original pointer if the
5761 MEM is valid to use in conditional code, NULL if we can't load up the offset
5762 into a temporary register, or the new MEM if we were successful. */
5765 frv_ifcvt_rewrite_mem (rtx mem
, machine_mode mode
, rtx insn
)
5767 rtx addr
= XEXP (mem
, 0);
5769 if (!frv_legitimate_address_p_1 (mode
, addr
, reload_completed
, TRUE
, FALSE
))
5771 if (GET_CODE (addr
) == PLUS
)
5773 rtx addr_op0
= XEXP (addr
, 0);
5774 rtx addr_op1
= XEXP (addr
, 1);
5776 if (GET_CODE (addr_op0
) == REG
&& CONSTANT_P (addr_op1
))
5778 rtx reg
= frv_ifcvt_load_value (addr_op1
, insn
);
5782 addr
= gen_rtx_PLUS (Pmode
, addr_op0
, reg
);
5789 else if (CONSTANT_P (addr
))
5790 addr
= frv_ifcvt_load_value (addr
, insn
);
5795 if (addr
== NULL_RTX
)
5798 else if (XEXP (mem
, 0) != addr
)
5799 return change_address (mem
, mode
, addr
);
5806 /* Given a PATTERN, return a SET expression if this PATTERN has only a single
5807 SET, possibly conditionally executed. It may also have CLOBBERs, USEs. */
5810 single_set_pattern (rtx pattern
)
5815 if (GET_CODE (pattern
) == COND_EXEC
)
5816 pattern
= COND_EXEC_CODE (pattern
);
5818 if (GET_CODE (pattern
) == SET
)
5821 else if (GET_CODE (pattern
) == PARALLEL
)
5823 for (i
= 0, set
= 0; i
< XVECLEN (pattern
, 0); i
++)
5825 rtx sub
= XVECEXP (pattern
, 0, i
);
5827 switch (GET_CODE (sub
))
5851 /* A C expression to modify the code described by the conditional if
5852 information CE_INFO with the new PATTERN in INSN. If PATTERN is a null
5853 pointer after the IFCVT_MODIFY_INSN macro executes, it is assumed that that
5854 insn cannot be converted to be executed conditionally. */
5857 frv_ifcvt_modify_insn (ce_if_block
*ce_info
,
5861 rtx orig_ce_pattern
= pattern
;
5867 gcc_assert (GET_CODE (pattern
) == COND_EXEC
);
5869 test
= COND_EXEC_TEST (pattern
);
5870 if (GET_CODE (test
) == AND
)
5872 rtx cr
= frv_ifcvt
.cr_reg
;
5875 op0
= XEXP (test
, 0);
5876 if (! rtx_equal_p (cr
, XEXP (op0
, 0)))
5879 op1
= XEXP (test
, 1);
5880 test_reg
= XEXP (op1
, 0);
5881 if (GET_CODE (test_reg
) != REG
)
5884 /* Is this the first nested if block in this sequence? If so, generate
5885 an andcr or andncr. */
5886 if (! frv_ifcvt
.last_nested_if_cr
)
5890 frv_ifcvt
.last_nested_if_cr
= test_reg
;
5891 if (GET_CODE (op0
) == NE
)
5892 and_op
= gen_andcr (test_reg
, cr
, test_reg
);
5894 and_op
= gen_andncr (test_reg
, cr
, test_reg
);
5896 frv_ifcvt_add_insn (and_op
, insn
, TRUE
);
5899 /* If this isn't the first statement in the nested if sequence, see if we
5900 are dealing with the same register. */
5901 else if (! rtx_equal_p (test_reg
, frv_ifcvt
.last_nested_if_cr
))
5904 COND_EXEC_TEST (pattern
) = test
= op1
;
5907 /* If this isn't a nested if, reset state variables. */
5910 frv_ifcvt
.last_nested_if_cr
= NULL_RTX
;
5913 set
= single_set_pattern (pattern
);
5916 rtx dest
= SET_DEST (set
);
5917 rtx src
= SET_SRC (set
);
5918 machine_mode mode
= GET_MODE (dest
);
5920 /* Check for normal binary operators. */
5921 if (mode
== SImode
&& ARITHMETIC_P (src
))
5923 op0
= XEXP (src
, 0);
5924 op1
= XEXP (src
, 1);
5926 if (integer_register_operand (op0
, SImode
) && CONSTANT_P (op1
))
5928 op1
= frv_ifcvt_load_value (op1
, insn
);
5930 COND_EXEC_CODE (pattern
)
5931 = gen_rtx_SET (dest
, gen_rtx_fmt_ee (GET_CODE (src
),
5939 /* For multiply by a constant, we need to handle the sign extending
5940 correctly. Add a USE of the value after the multiply to prevent flow
5941 from cratering because only one register out of the two were used. */
5942 else if (mode
== DImode
&& GET_CODE (src
) == MULT
)
5944 op0
= XEXP (src
, 0);
5945 op1
= XEXP (src
, 1);
5946 if (GET_CODE (op0
) == SIGN_EXTEND
&& GET_CODE (op1
) == CONST_INT
)
5948 op1
= frv_ifcvt_load_value (op1
, insn
);
5951 op1
= gen_rtx_SIGN_EXTEND (DImode
, op1
);
5952 COND_EXEC_CODE (pattern
)
5953 = gen_rtx_SET (dest
, gen_rtx_MULT (DImode
, op0
, op1
));
5959 frv_ifcvt_add_insn (gen_use (dest
), insn
, FALSE
);
5962 /* If we are just loading a constant created for a nested conditional
5963 execution statement, just load the constant without any conditional
5964 execution, since we know that the constant will not interfere with any
5966 else if (frv_ifcvt
.scratch_insns_bitmap
5967 && bitmap_bit_p (frv_ifcvt
.scratch_insns_bitmap
,
5969 && REG_P (SET_DEST (set
))
5970 /* We must not unconditionally set a scratch reg chosen
5971 for a nested if-converted block if its incoming
5972 value from the TEST block (or the result of the THEN
5973 branch) could/should propagate to the JOIN block.
5974 It suffices to test whether the register is live at
5975 the JOIN point: if it's live there, we can infer
5976 that we set it in the former JOIN block of the
5977 nested if-converted block (otherwise it wouldn't
5978 have been available as a scratch register), and it
5979 is either propagated through or set in the other
5980 conditional block. It's probably not worth trying
5981 to catch the latter case, and it could actually
5982 limit scheduling of the combined block quite
5985 && ! (REGNO_REG_SET_P (df_get_live_in (ce_info
->join_bb
),
5986 REGNO (SET_DEST (set
))))
5987 /* Similarly, we must not unconditionally set a reg
5988 used as scratch in the THEN branch if the same reg
5989 is live in the ELSE branch. */
5990 && (! ce_info
->else_bb
5991 || BLOCK_FOR_INSN (insn
) == ce_info
->else_bb
5992 || ! (REGNO_REG_SET_P (df_get_live_in (ce_info
->else_bb
),
5993 REGNO (SET_DEST (set
))))))
5996 else if (mode
== QImode
|| mode
== HImode
|| mode
== SImode
5999 int changed_p
= FALSE
;
6001 /* Check for just loading up a constant */
6002 if (CONSTANT_P (src
) && integer_register_operand (dest
, mode
))
6004 src
= frv_ifcvt_load_value (src
, insn
);
6011 /* See if we need to fix up stores */
6012 if (GET_CODE (dest
) == MEM
)
6014 rtx new_mem
= frv_ifcvt_rewrite_mem (dest
, mode
, insn
);
6019 else if (new_mem
!= dest
)
6026 /* See if we need to fix up loads */
6027 if (GET_CODE (src
) == MEM
)
6029 rtx new_mem
= frv_ifcvt_rewrite_mem (src
, mode
, insn
);
6034 else if (new_mem
!= src
)
6041 /* If either src or destination changed, redo SET. */
6043 COND_EXEC_CODE (pattern
) = gen_rtx_SET (dest
, src
);
6046 /* Rewrite a nested set cccr in terms of IF_THEN_ELSE. Also deal with
6047 rewriting the CC register to be the same as the paired CC/CR register
6049 else if (mode
== CC_CCRmode
&& COMPARISON_P (src
))
6051 int regno
= REGNO (XEXP (src
, 0));
6054 if (ce_info
->pass
> 1
6055 && regno
!= (int)REGNO (frv_ifcvt
.nested_cc_reg
)
6056 && TEST_HARD_REG_BIT (frv_ifcvt
.nested_cc_ok_rewrite
, regno
))
6058 src
= gen_rtx_fmt_ee (GET_CODE (src
),
6060 frv_ifcvt
.nested_cc_reg
,
6064 if_else
= gen_rtx_IF_THEN_ELSE (CC_CCRmode
, test
, src
, const0_rtx
);
6065 pattern
= gen_rtx_SET (dest
, if_else
);
6068 /* Remap a nested compare instruction to use the paired CC/CR reg. */
6069 else if (ce_info
->pass
> 1
6070 && GET_CODE (dest
) == REG
6071 && CC_P (REGNO (dest
))
6072 && REGNO (dest
) != REGNO (frv_ifcvt
.nested_cc_reg
)
6073 && TEST_HARD_REG_BIT (frv_ifcvt
.nested_cc_ok_rewrite
,
6075 && GET_CODE (src
) == COMPARE
)
6077 PUT_MODE (frv_ifcvt
.nested_cc_reg
, GET_MODE (dest
));
6078 COND_EXEC_CODE (pattern
)
6079 = gen_rtx_SET (frv_ifcvt
.nested_cc_reg
, copy_rtx (src
));
6083 if (TARGET_DEBUG_COND_EXEC
)
6085 rtx orig_pattern
= PATTERN (insn
);
6087 PATTERN (insn
) = pattern
;
6089 "\n:::::::::: frv_ifcvt_modify_insn: pass = %d, insn after modification:\n",
6093 PATTERN (insn
) = orig_pattern
;
6099 if (TARGET_DEBUG_COND_EXEC
)
6101 rtx orig_pattern
= PATTERN (insn
);
6103 PATTERN (insn
) = orig_ce_pattern
;
6105 "\n:::::::::: frv_ifcvt_modify_insn: pass = %d, insn could not be modified:\n",
6109 PATTERN (insn
) = orig_pattern
;
6116 /* A C expression to perform any final machine dependent modifications in
6117 converting code to conditional execution in the code described by the
6118 conditional if information CE_INFO. */
6121 frv_ifcvt_modify_final (ce_if_block
*ce_info ATTRIBUTE_UNUSED
)
6125 rtx p
= frv_ifcvt
.added_insns_list
;
6128 /* Loop inserting the check insns. The last check insn is the first test,
6129 and is the appropriate place to insert constants. */
6134 rtx check_and_insert_insns
= XEXP (p
, 0);
6137 check_insn
= XEXP (check_and_insert_insns
, 0);
6138 existing_insn
= XEXP (check_and_insert_insns
, 1);
6141 /* The jump bit is used to say that the new insn is to be inserted BEFORE
6142 the existing insn, otherwise it is to be inserted AFTER. */
6143 if (check_and_insert_insns
->jump
)
6145 emit_insn_before (check_insn
, existing_insn
);
6146 check_and_insert_insns
->jump
= 0;
6149 emit_insn_after (check_insn
, existing_insn
);
6151 free_EXPR_LIST_node (check_and_insert_insns
);
6152 free_EXPR_LIST_node (old_p
);
6154 while (p
!= NULL_RTX
);
6156 /* Load up any constants needed into temp gprs */
6157 for (i
= 0; i
< frv_ifcvt
.cur_scratch_regs
; i
++)
6159 rtx insn
= emit_insn_before (frv_ifcvt
.scratch_regs
[i
], existing_insn
);
6160 if (! frv_ifcvt
.scratch_insns_bitmap
)
6161 frv_ifcvt
.scratch_insns_bitmap
= BITMAP_ALLOC (NULL
);
6162 bitmap_set_bit (frv_ifcvt
.scratch_insns_bitmap
, INSN_UID (insn
));
6163 frv_ifcvt
.scratch_regs
[i
] = NULL_RTX
;
6166 frv_ifcvt
.added_insns_list
= NULL_RTX
;
6167 frv_ifcvt
.cur_scratch_regs
= 0;
6171 /* A C expression to cancel any machine dependent modifications in converting
6172 code to conditional execution in the code described by the conditional if
6173 information CE_INFO. */
6176 frv_ifcvt_modify_cancel (ce_if_block
*ce_info ATTRIBUTE_UNUSED
)
6179 rtx p
= frv_ifcvt
.added_insns_list
;
6181 /* Loop freeing up the EXPR_LIST's allocated. */
6182 while (p
!= NULL_RTX
)
6184 rtx check_and_jump
= XEXP (p
, 0);
6188 free_EXPR_LIST_node (check_and_jump
);
6189 free_EXPR_LIST_node (old_p
);
6192 /* Release any temporary gprs allocated. */
6193 for (i
= 0; i
< frv_ifcvt
.cur_scratch_regs
; i
++)
6194 frv_ifcvt
.scratch_regs
[i
] = NULL_RTX
;
6196 frv_ifcvt
.added_insns_list
= NULL_RTX
;
6197 frv_ifcvt
.cur_scratch_regs
= 0;
6201 /* A C expression for the size in bytes of the trampoline, as an integer.
6205 setlo #0, <static_chain>
6207 sethi #0, <static_chain>
6208 jmpl @(gr0,<jmp_reg>) */
6211 frv_trampoline_size (void)
6214 /* Allocate room for the function descriptor and the lddi
6217 return 5 /* instructions */ * 4 /* instruction size. */;
6221 /* A C statement to initialize the variable parts of a trampoline. ADDR is an
6222 RTX for the address of the trampoline; FNADDR is an RTX for the address of
6223 the nested function; STATIC_CHAIN is an RTX for the static chain value that
6224 should be passed to the function when it is called.
6229 setlo #0, <static_chain>
6231 sethi #0, <static_chain>
6232 jmpl @(gr0,<jmp_reg>) */
6235 frv_trampoline_init (rtx m_tramp
, tree fndecl
, rtx static_chain
)
6237 rtx addr
= XEXP (m_tramp
, 0);
6238 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
6239 rtx sc_reg
= force_reg (Pmode
, static_chain
);
6241 emit_library_call (gen_rtx_SYMBOL_REF (SImode
, "__trampoline_setup"),
6242 LCT_NORMAL
, VOIDmode
, 4,
6244 GEN_INT (frv_trampoline_size ()), SImode
,
6250 /* Many machines have some registers that cannot be copied directly to or from
6251 memory or even from other types of registers. An example is the `MQ'
6252 register, which on most machines, can only be copied to or from general
6253 registers, but not memory. Some machines allow copying all registers to and
6254 from memory, but require a scratch register for stores to some memory
6255 locations (e.g., those with symbolic address on the RT, and those with
6256 certain symbolic address on the SPARC when compiling PIC). In some cases,
6257 both an intermediate and a scratch register are required.
6259 You should define these macros to indicate to the reload phase that it may
6260 need to allocate at least one register for a reload in addition to the
6261 register to contain the data. Specifically, if copying X to a register
6262 RCLASS in MODE requires an intermediate register, you should define
6263 `SECONDARY_INPUT_RELOAD_CLASS' to return the largest register class all of
6264 whose registers can be used as intermediate registers or scratch registers.
6266 If copying a register RCLASS in MODE to X requires an intermediate or scratch
6267 register, `SECONDARY_OUTPUT_RELOAD_CLASS' should be defined to return the
6268 largest register class required. If the requirements for input and output
6269 reloads are the same, the macro `SECONDARY_RELOAD_CLASS' should be used
6270 instead of defining both macros identically.
6272 The values returned by these macros are often `GENERAL_REGS'. Return
6273 `NO_REGS' if no spare register is needed; i.e., if X can be directly copied
6274 to or from a register of RCLASS in MODE without requiring a scratch register.
6275 Do not define this macro if it would always return `NO_REGS'.
6277 If a scratch register is required (either with or without an intermediate
6278 register), you should define patterns for `reload_inM' or `reload_outM', as
6279 required.. These patterns, which will normally be implemented with a
6280 `define_expand', should be similar to the `movM' patterns, except that
6281 operand 2 is the scratch register.
6283 Define constraints for the reload register and scratch register that contain
6284 a single register class. If the original reload register (whose class is
6285 RCLASS) can meet the constraint given in the pattern, the value returned by
6286 these macros is used for the class of the scratch register. Otherwise, two
6287 additional reload registers are required. Their classes are obtained from
6288 the constraints in the insn pattern.
6290 X might be a pseudo-register or a `subreg' of a pseudo-register, which could
6291 either be in a hard register or in memory. Use `true_regnum' to find out;
6292 it will return -1 if the pseudo is in memory and the hard register number if
6293 it is in a register.
6295 These macros should not be used in the case where a particular class of
6296 registers can only be copied to memory and not to another class of
6297 registers. In that case, secondary reload registers are not needed and
6298 would not be helpful. Instead, a stack location must be used to perform the
6299 copy and the `movM' pattern should use memory as an intermediate storage.
6300 This case often occurs between floating-point and general registers. */
6303 frv_secondary_reload_class (enum reg_class rclass
,
6304 machine_mode mode ATTRIBUTE_UNUSED
,
6315 /* Accumulators/Accumulator guard registers need to go through floating
6320 if (x
&& GET_CODE (x
) == REG
)
6322 int regno
= REGNO (x
);
6324 if (ACC_P (regno
) || ACCG_P (regno
))
6329 /* Nonzero constants should be loaded into an FPR through a GPR. */
6331 if (x
&& CONSTANT_P (x
) && !ZERO_P (x
))
6337 /* All of these types need gpr registers. */
6349 /* The accumulators need fpr registers. */
6359 /* This hook exists to catch the case where secondary_reload_class() is
6360 called from init_reg_autoinc() in regclass.c - before the reload optabs
6361 have been initialised. */
6364 frv_secondary_reload (bool in_p
, rtx x
, reg_class_t reload_class_i
,
6365 machine_mode reload_mode
,
6366 secondary_reload_info
* sri
)
6368 enum reg_class rclass
= NO_REGS
;
6369 enum reg_class reload_class
= (enum reg_class
) reload_class_i
;
6371 if (sri
->prev_sri
&& sri
->prev_sri
->t_icode
!= CODE_FOR_nothing
)
6373 sri
->icode
= sri
->prev_sri
->t_icode
;
6377 rclass
= frv_secondary_reload_class (reload_class
, reload_mode
, x
);
6379 if (rclass
!= NO_REGS
)
6381 enum insn_code icode
6382 = direct_optab_handler (in_p
? reload_in_optab
: reload_out_optab
,
6386 /* This happens when then the reload_[in|out]_optabs have
6387 not been initialised. */
6388 sri
->t_icode
= CODE_FOR_nothing
;
6393 /* Fall back to the default secondary reload handler. */
6394 return default_secondary_reload (in_p
, x
, reload_class
, reload_mode
, sri
);
6398 /* Worker function for TARGET_CLASS_LIKELY_SPILLED_P. */
6401 frv_class_likely_spilled_p (reg_class_t rclass
)
6411 case FDPIC_FPTR_REGS
:
6431 /* An expression for the alignment of a structure field FIELD if the
6432 alignment computed in the usual way is COMPUTED. GCC uses this
6433 value instead of the value in `BIGGEST_ALIGNMENT' or
6434 `BIGGEST_FIELD_ALIGNMENT', if defined, for structure fields only. */
6436 /* The definition type of the bit field data is either char, short, long or
6437 long long. The maximum bit size is the number of bits of its own type.
6439 The bit field data is assigned to a storage unit that has an adequate size
6440 for bit field data retention and is located at the smallest address.
6442 Consecutive bit field data are packed at consecutive bits having the same
6443 storage unit, with regard to the type, beginning with the MSB and continuing
6446 If a field to be assigned lies over a bit field type boundary, its
6447 assignment is completed by aligning it with a boundary suitable for the
6450 When a bit field having a bit length of 0 is declared, it is forcibly
6451 assigned to the next storage unit.
6464 &x 00000000 00000000 00000000 00000000
6467 &x+4 00000000 00000000 00000000 00000000
6470 &x+8 00000000 00000000 00000000 00000000
6473 &x+12 00000000 00000000 00000000 00000000
6479 frv_adjust_field_align (tree field
, int computed
)
6481 /* Make sure that the bitfield is not wider than the type. */
6482 if (DECL_BIT_FIELD (field
)
6483 && !DECL_ARTIFICIAL (field
))
6485 tree parent
= DECL_CONTEXT (field
);
6486 tree prev
= NULL_TREE
;
6489 for (cur
= TYPE_FIELDS (parent
); cur
&& cur
!= field
; cur
= DECL_CHAIN (cur
))
6491 if (TREE_CODE (cur
) != FIELD_DECL
)
6499 /* If this isn't a :0 field and if the previous element is a bitfield
6500 also, see if the type is different, if so, we will need to align the
6501 bit-field to the next boundary. */
6503 && ! DECL_PACKED (field
)
6504 && ! integer_zerop (DECL_SIZE (field
))
6505 && DECL_BIT_FIELD_TYPE (field
) != DECL_BIT_FIELD_TYPE (prev
))
6507 int prev_align
= TYPE_ALIGN (TREE_TYPE (prev
));
6508 int cur_align
= TYPE_ALIGN (TREE_TYPE (field
));
6509 computed
= (prev_align
> cur_align
) ? prev_align
: cur_align
;
6517 /* A C expression that is nonzero if it is permissible to store a value of mode
6518 MODE in hard register number REGNO (or in several registers starting with
6519 that one). For a machine where all registers are equivalent, a suitable
6522 #define HARD_REGNO_MODE_OK(REGNO, MODE) 1
6524 It is not necessary for this macro to check for the numbers of fixed
6525 registers, because the allocation mechanism considers them to be always
6528 On some machines, double-precision values must be kept in even/odd register
6529 pairs. The way to implement that is to define this macro to reject odd
6530 register numbers for such modes.
6532 The minimum requirement for a mode to be OK in a register is that the
6533 `movMODE' instruction pattern support moves between the register and any
6534 other hard register for which the mode is OK; and that moving a value into
6535 the register and back out not alter it.
6537 Since the same instruction used to move `SImode' will work for all narrower
6538 integer modes, it is not necessary on any machine for `HARD_REGNO_MODE_OK'
6539 to distinguish between these modes, provided you define patterns `movhi',
6540 etc., to take advantage of this. This is useful because of the interaction
6541 between `HARD_REGNO_MODE_OK' and `MODES_TIEABLE_P'; it is very desirable for
6542 all integer modes to be tieable.
6544 Many machines have special registers for floating point arithmetic. Often
6545 people assume that floating point machine modes are allowed only in floating
6546 point registers. This is not true. Any registers that can hold integers
6547 can safely *hold* a floating point machine mode, whether or not floating
6548 arithmetic can be done on it in those registers. Integer move instructions
6549 can be used to move the values.
6551 On some machines, though, the converse is true: fixed-point machine modes
6552 may not go in floating registers. This is true if the floating registers
6553 normalize any value stored in them, because storing a non-floating value
6554 there would garble it. In this case, `HARD_REGNO_MODE_OK' should reject
6555 fixed-point machine modes in floating registers. But if the floating
6556 registers do not automatically normalize, if you can store any bit pattern
6557 in one and retrieve it unchanged without a trap, then any machine mode may
6558 go in a floating register, so you can define this macro to say so.
6560 The primary significance of special floating registers is rather that they
6561 are the registers acceptable in floating point arithmetic instructions.
6562 However, this is of no concern to `HARD_REGNO_MODE_OK'. You handle it by
6563 writing the proper constraints for those instructions.
6565 On some machines, the floating registers are especially slow to access, so
6566 that it is better to store a value in a stack frame than in such a register
6567 if floating point arithmetic is not being done. As long as the floating
6568 registers are not in class `GENERAL_REGS', they will not be used unless some
6569 pattern's constraint asks for one. */
6572 frv_hard_regno_mode_ok (int regno
, machine_mode mode
)
6582 return ICC_P (regno
) || GPR_P (regno
);
6585 return CR_P (regno
) || GPR_P (regno
);
6588 return FCC_P (regno
) || GPR_P (regno
);
6594 /* Set BASE to the first register in REGNO's class. Set MASK to the
6595 bits that must be clear in (REGNO - BASE) for the register to be
6597 if (INTEGRAL_MODE_P (mode
) || FLOAT_MODE_P (mode
) || VECTOR_MODE_P (mode
))
6601 /* ACCGs store one byte. Two-byte quantities must start in
6602 even-numbered registers, four-byte ones in registers whose
6603 numbers are divisible by four, and so on. */
6605 mask
= GET_MODE_SIZE (mode
) - 1;
6609 /* The other registers store one word. */
6610 if (GPR_P (regno
) || regno
== AP_FIRST
)
6613 else if (FPR_P (regno
))
6616 else if (ACC_P (regno
))
6619 else if (SPR_P (regno
))
6620 return mode
== SImode
;
6622 /* Fill in the table. */
6626 /* Anything smaller than an SI is OK in any word-sized register. */
6627 if (GET_MODE_SIZE (mode
) < 4)
6630 mask
= (GET_MODE_SIZE (mode
) / 4) - 1;
6632 return (((regno
- base
) & mask
) == 0);
6639 /* A C expression for the number of consecutive hard registers, starting at
6640 register number REGNO, required to hold a value of mode MODE.
6642 On a machine where all registers are exactly one word, a suitable definition
6645 #define HARD_REGNO_NREGS(REGNO, MODE) \
6646 ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \
6647 / UNITS_PER_WORD)) */
6649 /* On the FRV, make the CC_FP mode take 3 words in the integer registers, so
6650 that we can build the appropriate instructions to properly reload the
6651 values. Also, make the byte-sized accumulator guards use one guard
6655 frv_hard_regno_nregs (int regno
, machine_mode mode
)
6658 return GET_MODE_SIZE (mode
);
6660 return (GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
6664 /* A C expression for the maximum number of consecutive registers of
6665 class RCLASS needed to hold a value of mode MODE.
6667 This is closely related to the macro `HARD_REGNO_NREGS'. In fact, the value
6668 of the macro `CLASS_MAX_NREGS (RCLASS, MODE)' should be the maximum value of
6669 `HARD_REGNO_NREGS (REGNO, MODE)' for all REGNO values in the class RCLASS.
6671 This macro helps control the handling of multiple-word values in
6674 This declaration is required. */
6677 frv_class_max_nregs (enum reg_class rclass
, machine_mode mode
)
6679 if (rclass
== ACCG_REGS
)
6680 /* An N-byte value requires N accumulator guards. */
6681 return GET_MODE_SIZE (mode
);
6683 return (GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
6687 /* A C expression that is nonzero if X is a legitimate constant for an
6688 immediate operand on the target machine. You can assume that X satisfies
6689 `CONSTANT_P', so you need not check this. In fact, `1' is a suitable
6690 definition for this macro on machines where anything `CONSTANT_P' is valid. */
6693 frv_legitimate_constant_p (machine_mode mode
, rtx x
)
6695 /* frv_cannot_force_const_mem always returns true for FDPIC. This
6696 means that the move expanders will be expected to deal with most
6697 kinds of constant, regardless of what we return here.
6699 However, among its other duties, frv_legitimate_constant_p decides whether
6700 a constant can be entered into reg_equiv_constant[]. If we return true,
6701 reload can create new instances of the constant whenever it likes.
6703 The idea is therefore to accept as many constants as possible (to give
6704 reload more freedom) while rejecting constants that can only be created
6705 at certain times. In particular, anything with a symbolic component will
6706 require use of the pseudo FDPIC register, which is only available before
6709 return LEGITIMATE_PIC_OPERAND_P (x
);
6711 /* All of the integer constants are ok. */
6712 if (GET_CODE (x
) != CONST_DOUBLE
)
6715 /* double integer constants are ok. */
6716 if (GET_MODE (x
) == VOIDmode
|| mode
== DImode
)
6719 /* 0 is always ok. */
6720 if (x
== CONST0_RTX (mode
))
6723 /* If floating point is just emulated, allow any constant, since it will be
6724 constructed in the GPRs. */
6725 if (!TARGET_HAS_FPRS
)
6728 if (mode
== DFmode
&& !TARGET_DOUBLE
)
6731 /* Otherwise store the constant away and do a load. */
6735 /* Implement SELECT_CC_MODE. Choose CC_FP for floating-point comparisons,
6736 CC_NZ for comparisons against zero in which a single Z or N flag test
6737 is enough, CC_UNS for other unsigned comparisons, and CC for other
6738 signed comparisons. */
6741 frv_select_cc_mode (enum rtx_code code
, rtx x
, rtx y
)
6743 if (GET_MODE_CLASS (GET_MODE (x
)) == MODE_FLOAT
)
6752 return y
== const0_rtx
? CC_NZmode
: CCmode
;
6758 return y
== const0_rtx
? CC_NZmode
: CC_UNSmode
;
6766 /* Worker function for TARGET_REGISTER_MOVE_COST. */
6768 #define HIGH_COST 40
6769 #define MEDIUM_COST 3
6773 frv_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED
,
6774 reg_class_t from
, reg_class_t to
)
6787 case FDPIC_FPTR_REGS
:
6788 case FDPIC_CALL_REGS
:
6801 case FDPIC_FPTR_REGS
:
6802 case FDPIC_CALL_REGS
:
6827 case FDPIC_FPTR_REGS
:
6828 case FDPIC_CALL_REGS
:
6852 case FDPIC_FPTR_REGS
:
6853 case FDPIC_CALL_REGS
:
6874 /* Worker function for TARGET_MEMORY_MOVE_COST. */
6877 frv_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED
,
6878 reg_class_t rclass ATTRIBUTE_UNUSED
,
6879 bool in ATTRIBUTE_UNUSED
)
6885 /* Implementation of TARGET_ASM_INTEGER. In the FRV case we need to
6886 use ".picptr" to generate safe relocations for PIC code. We also
6887 need a fixup entry for aligned (non-debugging) code. */
6890 frv_assemble_integer (rtx value
, unsigned int size
, int aligned_p
)
6892 if ((flag_pic
|| TARGET_FDPIC
) && size
== UNITS_PER_WORD
)
6894 if (GET_CODE (value
) == CONST
6895 || GET_CODE (value
) == SYMBOL_REF
6896 || GET_CODE (value
) == LABEL_REF
)
6898 if (TARGET_FDPIC
&& GET_CODE (value
) == SYMBOL_REF
6899 && SYMBOL_REF_FUNCTION_P (value
))
6901 fputs ("\t.picptr\tfuncdesc(", asm_out_file
);
6902 output_addr_const (asm_out_file
, value
);
6903 fputs (")\n", asm_out_file
);
6906 else if (TARGET_FDPIC
&& GET_CODE (value
) == CONST
6907 && frv_function_symbol_referenced_p (value
))
6909 if (aligned_p
&& !TARGET_FDPIC
)
6911 static int label_num
= 0;
6915 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCP", label_num
++);
6916 p
= (* targetm
.strip_name_encoding
) (buf
);
6918 fprintf (asm_out_file
, "%s:\n", p
);
6919 fprintf (asm_out_file
, "%s\n", FIXUP_SECTION_ASM_OP
);
6920 fprintf (asm_out_file
, "\t.picptr\t%s\n", p
);
6921 fprintf (asm_out_file
, "\t.previous\n");
6923 assemble_integer_with_op ("\t.picptr\t", value
);
6928 /* We've set the unaligned SI op to NULL, so we always have to
6929 handle the unaligned case here. */
6930 assemble_integer_with_op ("\t.4byte\t", value
);
6934 return default_assemble_integer (value
, size
, aligned_p
);
6937 /* Function to set up the backend function structure. */
6939 static struct machine_function
*
6940 frv_init_machine_status (void)
6942 return ggc_cleared_alloc
<machine_function
> ();
6945 /* Implement TARGET_SCHED_ISSUE_RATE. */
6948 frv_issue_rate (void)
6953 switch (frv_cpu_type
)
6957 case FRV_CPU_SIMPLE
:
6965 case FRV_CPU_GENERIC
:
6967 case FRV_CPU_TOMCAT
:
6975 /* Return the value of INSN's acc_group attribute. */
6978 frv_acc_group (rtx insn
)
6980 /* This distinction only applies to the FR550 packing constraints. */
6981 if (frv_cpu_type
== FRV_CPU_FR550
)
6983 subrtx_iterator::array_type array
;
6984 FOR_EACH_SUBRTX (iter
, array
, PATTERN (insn
), NONCONST
)
6987 unsigned int regno
= REGNO (*iter
);
6988 /* If REGNO refers to an accumulator, return ACC_GROUP_ODD if
6989 the bit 2 of the register number is set and ACC_GROUP_EVEN if
6992 return (regno
- ACC_FIRST
) & 4 ? ACC_GROUP_ODD
: ACC_GROUP_EVEN
;
6994 return (regno
- ACCG_FIRST
) & 4 ? ACC_GROUP_ODD
: ACC_GROUP_EVEN
;
6997 return ACC_GROUP_NONE
;
7000 /* Return the index of the DFA unit in FRV_UNIT_NAMES[] that instruction
7001 INSN will try to claim first. Since this value depends only on the
7002 type attribute, we can cache the results in FRV_TYPE_TO_UNIT[]. */
7005 frv_insn_unit (rtx_insn
*insn
)
7007 enum attr_type type
;
7009 type
= get_attr_type (insn
);
7010 if (frv_type_to_unit
[type
] == ARRAY_SIZE (frv_unit_codes
))
7012 /* We haven't seen this type of instruction before. */
7016 /* Issue the instruction on its own to see which unit it prefers. */
7017 state
= alloca (state_size ());
7018 state_reset (state
);
7019 state_transition (state
, insn
);
7021 /* Find out which unit was taken. */
7022 for (unit
= 0; unit
< ARRAY_SIZE (frv_unit_codes
); unit
++)
7023 if (cpu_unit_reservation_p (state
, frv_unit_codes
[unit
]))
7026 gcc_assert (unit
!= ARRAY_SIZE (frv_unit_codes
));
7028 frv_type_to_unit
[type
] = unit
;
7030 return frv_type_to_unit
[type
];
7033 /* Return true if INSN issues to a branch unit. */
7036 frv_issues_to_branch_unit_p (rtx_insn
*insn
)
7038 return frv_unit_groups
[frv_insn_unit (insn
)] == GROUP_B
;
7041 /* The instructions in the packet, partitioned into groups. */
7042 struct frv_packet_group
{
7043 /* How many instructions in the packet belong to this group. */
7044 unsigned int num_insns
;
7046 /* A list of the instructions that belong to this group, in the order
7047 they appear in the rtl stream. */
7048 rtx_insn
*insns
[ARRAY_SIZE (frv_unit_codes
)];
7050 /* The contents of INSNS after they have been sorted into the correct
7051 assembly-language order. Element X issues to unit X. The list may
7052 contain extra nops. */
7053 rtx_insn
*sorted
[ARRAY_SIZE (frv_unit_codes
)];
7055 /* The member of frv_nops[] to use in sorted[]. */
7059 /* The current state of the packing pass, implemented by frv_pack_insns. */
7061 /* The state of the pipeline DFA. */
7064 /* Which hardware registers are set within the current packet,
7065 and the conditions under which they are set. */
7066 regstate_t regstate
[FIRST_PSEUDO_REGISTER
];
7068 /* The memory locations that have been modified so far in this
7069 packet. MEM is the memref and COND is the regstate_t condition
7070 under which it is set. */
7076 /* The number of valid entries in MEMS. The value is larger than
7077 ARRAY_SIZE (mems) if there were too many mems to record. */
7078 unsigned int num_mems
;
7080 /* The maximum number of instructions that can be packed together. */
7081 unsigned int issue_rate
;
7083 /* The instructions in the packet, partitioned into groups. */
7084 struct frv_packet_group groups
[NUM_GROUPS
];
7086 /* The instructions that make up the current packet. */
7087 rtx_insn
*insns
[ARRAY_SIZE (frv_unit_codes
)];
7088 unsigned int num_insns
;
7091 /* Return the regstate_t flags for the given COND_EXEC condition.
7092 Abort if the condition isn't in the right form. */
7095 frv_cond_flags (rtx cond
)
7097 gcc_assert ((GET_CODE (cond
) == EQ
|| GET_CODE (cond
) == NE
)
7098 && GET_CODE (XEXP (cond
, 0)) == REG
7099 && CR_P (REGNO (XEXP (cond
, 0)))
7100 && XEXP (cond
, 1) == const0_rtx
);
7101 return ((REGNO (XEXP (cond
, 0)) - CR_FIRST
)
7102 | (GET_CODE (cond
) == NE
7104 : REGSTATE_IF_FALSE
));
7108 /* Return true if something accessed under condition COND2 can
7109 conflict with something written under condition COND1. */
7112 frv_regstate_conflict_p (regstate_t cond1
, regstate_t cond2
)
7114 /* If either reference was unconditional, we have a conflict. */
7115 if ((cond1
& REGSTATE_IF_EITHER
) == 0
7116 || (cond2
& REGSTATE_IF_EITHER
) == 0)
7119 /* The references might conflict if they were controlled by
7121 if ((cond1
& REGSTATE_CC_MASK
) != (cond2
& REGSTATE_CC_MASK
))
7124 /* They definitely conflict if they are controlled by the
7126 if ((cond1
& cond2
& REGSTATE_IF_EITHER
) != 0)
7133 /* Return true if an instruction with pattern PAT depends on an
7134 instruction in the current packet. COND describes the condition
7135 under which PAT might be set or used. */
7138 frv_registers_conflict_p_1 (rtx pat
, regstate_t cond
)
7140 subrtx_var_iterator::array_type array
;
7141 FOR_EACH_SUBRTX_VAR (iter
, array
, pat
, NONCONST
)
7144 if (GET_CODE (x
) == REG
)
7147 FOR_EACH_REGNO (regno
, x
)
7148 if ((frv_packet
.regstate
[regno
] & REGSTATE_MODIFIED
) != 0)
7149 if (frv_regstate_conflict_p (frv_packet
.regstate
[regno
], cond
))
7152 else if (GET_CODE (x
) == MEM
)
7154 /* If we ran out of memory slots, assume a conflict. */
7155 if (frv_packet
.num_mems
> ARRAY_SIZE (frv_packet
.mems
))
7158 /* Check for output or true dependencies with earlier MEMs. */
7159 for (unsigned int i
= 0; i
< frv_packet
.num_mems
; i
++)
7160 if (frv_regstate_conflict_p (frv_packet
.mems
[i
].cond
, cond
))
7162 if (true_dependence (frv_packet
.mems
[i
].mem
, VOIDmode
, x
))
7165 if (output_dependence (frv_packet
.mems
[i
].mem
, x
))
7170 /* The return values of calls aren't significant: they describe
7171 the effect of the call as a whole, not of the insn itself. */
7172 else if (GET_CODE (x
) == SET
&& GET_CODE (SET_SRC (x
)) == CALL
)
7173 iter
.substitute (SET_SRC (x
));
7179 /* Return true if something in X might depend on an instruction
7180 in the current packet. */
7183 frv_registers_conflict_p (rtx x
)
7188 if (GET_CODE (x
) == COND_EXEC
)
7190 if (frv_registers_conflict_p_1 (XEXP (x
, 0), flags
))
7193 flags
|= frv_cond_flags (XEXP (x
, 0));
7196 return frv_registers_conflict_p_1 (x
, flags
);
7200 /* A note_stores callback. DATA points to the regstate_t condition
7201 under which X is modified. Update FRV_PACKET accordingly. */
7204 frv_registers_update_1 (rtx x
, const_rtx pat ATTRIBUTE_UNUSED
, void *data
)
7208 if (GET_CODE (x
) == REG
)
7209 FOR_EACH_REGNO (regno
, x
)
7210 frv_packet
.regstate
[regno
] |= *(regstate_t
*) data
;
7212 if (GET_CODE (x
) == MEM
)
7214 if (frv_packet
.num_mems
< ARRAY_SIZE (frv_packet
.mems
))
7216 frv_packet
.mems
[frv_packet
.num_mems
].mem
= x
;
7217 frv_packet
.mems
[frv_packet
.num_mems
].cond
= *(regstate_t
*) data
;
7219 frv_packet
.num_mems
++;
7224 /* Update the register state information for an instruction whose
7228 frv_registers_update (rtx x
)
7232 flags
= REGSTATE_MODIFIED
;
7233 if (GET_CODE (x
) == COND_EXEC
)
7235 flags
|= frv_cond_flags (XEXP (x
, 0));
7238 note_stores (x
, frv_registers_update_1
, &flags
);
7242 /* Initialize frv_packet for the start of a new packet. */
7245 frv_start_packet (void)
7247 enum frv_insn_group group
;
7249 memset (frv_packet
.regstate
, 0, sizeof (frv_packet
.regstate
));
7250 frv_packet
.num_mems
= 0;
7251 frv_packet
.num_insns
= 0;
7252 for (group
= GROUP_I
; group
< NUM_GROUPS
;
7253 group
= (enum frv_insn_group
) (group
+ 1))
7254 frv_packet
.groups
[group
].num_insns
= 0;
7258 /* Likewise for the start of a new basic block. */
7261 frv_start_packet_block (void)
7263 state_reset (frv_packet
.dfa_state
);
7264 frv_start_packet ();
7268 /* Finish the current packet, if any, and start a new one. Call
7269 HANDLE_PACKET with FRV_PACKET describing the completed packet. */
7272 frv_finish_packet (void (*handle_packet
) (void))
7274 if (frv_packet
.num_insns
> 0)
7277 state_transition (frv_packet
.dfa_state
, 0);
7278 frv_start_packet ();
7283 /* Return true if INSN can be added to the current packet. Update
7284 the DFA state on success. */
7287 frv_pack_insn_p (rtx_insn
*insn
)
7289 /* See if the packet is already as long as it can be. */
7290 if (frv_packet
.num_insns
== frv_packet
.issue_rate
)
7293 /* If the scheduler thought that an instruction should start a packet,
7294 it's usually a good idea to believe it. It knows much more about
7295 the latencies than we do.
7297 There are some exceptions though:
7299 - Conditional instructions are scheduled on the assumption that
7300 they will be executed. This is usually a good thing, since it
7301 tends to avoid unnecessary stalls in the conditional code.
7302 But we want to pack conditional instructions as tightly as
7303 possible, in order to optimize the case where they aren't
7306 - The scheduler will always put branches on their own, even
7307 if there's no real dependency.
7309 - There's no point putting a call in its own packet unless
7311 if (frv_packet
.num_insns
> 0
7312 && NONJUMP_INSN_P (insn
)
7313 && GET_MODE (insn
) == TImode
7314 && GET_CODE (PATTERN (insn
)) != COND_EXEC
)
7317 /* Check for register conflicts. Don't do this for setlo since any
7318 conflict will be with the partnering sethi, with which it can
7320 if (get_attr_type (insn
) != TYPE_SETLO
)
7321 if (frv_registers_conflict_p (PATTERN (insn
)))
7324 return state_transition (frv_packet
.dfa_state
, insn
) < 0;
7328 /* Add instruction INSN to the current packet. */
7331 frv_add_insn_to_packet (rtx_insn
*insn
)
7333 struct frv_packet_group
*packet_group
;
7335 packet_group
= &frv_packet
.groups
[frv_unit_groups
[frv_insn_unit (insn
)]];
7336 packet_group
->insns
[packet_group
->num_insns
++] = insn
;
7337 frv_packet
.insns
[frv_packet
.num_insns
++] = insn
;
7339 frv_registers_update (PATTERN (insn
));
7343 /* Insert INSN (a member of frv_nops[]) into the current packet. If the
7344 packet ends in a branch or call, insert the nop before it, otherwise
7348 frv_insert_nop_in_packet (rtx_insn
*insn
)
7350 struct frv_packet_group
*packet_group
;
7353 packet_group
= &frv_packet
.groups
[frv_unit_groups
[frv_insn_unit (insn
)]];
7354 last
= frv_packet
.insns
[frv_packet
.num_insns
- 1];
7355 if (! NONJUMP_INSN_P (last
))
7357 insn
= emit_insn_before (PATTERN (insn
), last
);
7358 frv_packet
.insns
[frv_packet
.num_insns
- 1] = insn
;
7359 frv_packet
.insns
[frv_packet
.num_insns
++] = last
;
7363 insn
= emit_insn_after (PATTERN (insn
), last
);
7364 frv_packet
.insns
[frv_packet
.num_insns
++] = insn
;
7366 packet_group
->insns
[packet_group
->num_insns
++] = insn
;
7370 /* If packing is enabled, divide the instructions into packets and
7371 return true. Call HANDLE_PACKET for each complete packet. */
7374 frv_for_each_packet (void (*handle_packet
) (void))
7376 rtx_insn
*insn
, *next_insn
;
7378 frv_packet
.issue_rate
= frv_issue_rate ();
7380 /* Early exit if we don't want to pack insns. */
7382 || !flag_schedule_insns_after_reload
7383 || !TARGET_VLIW_BRANCH
7384 || frv_packet
.issue_rate
== 1)
7387 /* Set up the initial packing state. */
7389 frv_packet
.dfa_state
= alloca (state_size ());
7391 frv_start_packet_block ();
7392 for (insn
= get_insns (); insn
!= 0; insn
= next_insn
)
7397 code
= GET_CODE (insn
);
7398 next_insn
= NEXT_INSN (insn
);
7400 if (code
== CODE_LABEL
)
7402 frv_finish_packet (handle_packet
);
7403 frv_start_packet_block ();
7407 switch (GET_CODE (PATTERN (insn
)))
7414 /* Calls mustn't be packed on a TOMCAT. */
7415 if (CALL_P (insn
) && frv_cpu_type
== FRV_CPU_TOMCAT
)
7416 frv_finish_packet (handle_packet
);
7418 /* Since the last instruction in a packet determines the EH
7419 region, any exception-throwing instruction must come at
7420 the end of reordered packet. Insns that issue to a
7421 branch unit are bound to come last; for others it's
7422 too hard to predict. */
7423 eh_insn_p
= (find_reg_note (insn
, REG_EH_REGION
, NULL
) != NULL
);
7424 if (eh_insn_p
&& !frv_issues_to_branch_unit_p (insn
))
7425 frv_finish_packet (handle_packet
);
7427 /* Finish the current packet if we can't add INSN to it.
7428 Simulate cycles until INSN is ready to issue. */
7429 if (!frv_pack_insn_p (insn
))
7431 frv_finish_packet (handle_packet
);
7432 while (!frv_pack_insn_p (insn
))
7433 state_transition (frv_packet
.dfa_state
, 0);
7436 /* Add the instruction to the packet. */
7437 frv_add_insn_to_packet (insn
);
7439 /* Calls and jumps end a packet, as do insns that throw
7441 if (code
== CALL_INSN
|| code
== JUMP_INSN
|| eh_insn_p
)
7442 frv_finish_packet (handle_packet
);
7446 frv_finish_packet (handle_packet
);
7451 /* Subroutine of frv_sort_insn_group. We are trying to sort
7452 frv_packet.groups[GROUP].sorted[0...NUM_INSNS-1] into assembly
7453 language order. We have already picked a new position for
7454 frv_packet.groups[GROUP].sorted[X] if bit X of ISSUED is set.
7455 These instructions will occupy elements [0, LOWER_SLOT) and
7456 [UPPER_SLOT, NUM_INSNS) of the final (sorted) array. STATE is
7457 the DFA state after issuing these instructions.
7459 Try filling elements [LOWER_SLOT, UPPER_SLOT) with every permutation
7460 of the unused instructions. Return true if one such permutation gives
7461 a valid ordering, leaving the successful permutation in sorted[].
7462 Do not modify sorted[] until a valid permutation is found. */
7465 frv_sort_insn_group_1 (enum frv_insn_group group
,
7466 unsigned int lower_slot
, unsigned int upper_slot
,
7467 unsigned int issued
, unsigned int num_insns
,
7470 struct frv_packet_group
*packet_group
;
7476 /* Early success if we've filled all the slots. */
7477 if (lower_slot
== upper_slot
)
7480 packet_group
= &frv_packet
.groups
[group
];
7481 dfa_size
= state_size ();
7482 test_state
= alloca (dfa_size
);
7484 /* Try issuing each unused instruction. */
7485 for (i
= num_insns
- 1; i
+ 1 != 0; i
--)
7486 if (~issued
& (1 << i
))
7488 insn
= packet_group
->sorted
[i
];
7489 memcpy (test_state
, state
, dfa_size
);
7490 if (state_transition (test_state
, insn
) < 0
7491 && cpu_unit_reservation_p (test_state
,
7492 NTH_UNIT (group
, upper_slot
- 1))
7493 && frv_sort_insn_group_1 (group
, lower_slot
, upper_slot
- 1,
7494 issued
| (1 << i
), num_insns
,
7497 packet_group
->sorted
[upper_slot
- 1] = insn
;
7505 /* Compare two instructions by their frv_insn_unit. */
7508 frv_compare_insns (const void *first
, const void *second
)
7510 rtx_insn
* const *insn1
= (rtx_insn
* const *) first
;
7511 rtx_insn
* const *insn2
= (rtx_insn
* const *) second
;
7512 return frv_insn_unit (*insn1
) - frv_insn_unit (*insn2
);
7515 /* Copy frv_packet.groups[GROUP].insns[] to frv_packet.groups[GROUP].sorted[]
7516 and sort it into assembly language order. See frv.md for a description of
7520 frv_sort_insn_group (enum frv_insn_group group
)
7522 struct frv_packet_group
*packet_group
;
7523 unsigned int first
, i
, nop
, max_unit
, num_slots
;
7524 state_t state
, test_state
;
7527 packet_group
= &frv_packet
.groups
[group
];
7529 /* Assume no nop is needed. */
7530 packet_group
->nop
= 0;
7532 if (packet_group
->num_insns
== 0)
7535 /* Copy insns[] to sorted[]. */
7536 memcpy (packet_group
->sorted
, packet_group
->insns
,
7537 sizeof (rtx
) * packet_group
->num_insns
);
7539 /* Sort sorted[] by the unit that each insn tries to take first. */
7540 if (packet_group
->num_insns
> 1)
7541 qsort (packet_group
->sorted
, packet_group
->num_insns
,
7542 sizeof (rtx
), frv_compare_insns
);
7544 /* That's always enough for branch and control insns. */
7545 if (group
== GROUP_B
|| group
== GROUP_C
)
7548 dfa_size
= state_size ();
7549 state
= alloca (dfa_size
);
7550 test_state
= alloca (dfa_size
);
7552 /* Find the highest FIRST such that sorted[0...FIRST-1] can issue
7553 consecutively and such that the DFA takes unit X when sorted[X]
7554 is added. Set STATE to the new DFA state. */
7555 state_reset (test_state
);
7556 for (first
= 0; first
< packet_group
->num_insns
; first
++)
7558 memcpy (state
, test_state
, dfa_size
);
7559 if (state_transition (test_state
, packet_group
->sorted
[first
]) >= 0
7560 || !cpu_unit_reservation_p (test_state
, NTH_UNIT (group
, first
)))
7564 /* If all the instructions issued in ascending order, we're done. */
7565 if (first
== packet_group
->num_insns
)
7568 /* Add nops to the end of sorted[] and try each permutation until
7569 we find one that works. */
7570 for (nop
= 0; nop
< frv_num_nops
; nop
++)
7572 max_unit
= frv_insn_unit (frv_nops
[nop
]);
7573 if (frv_unit_groups
[max_unit
] == group
)
7575 packet_group
->nop
= frv_nops
[nop
];
7576 num_slots
= UNIT_NUMBER (max_unit
) + 1;
7577 for (i
= packet_group
->num_insns
; i
< num_slots
; i
++)
7578 packet_group
->sorted
[i
] = frv_nops
[nop
];
7579 if (frv_sort_insn_group_1 (group
, first
, num_slots
,
7580 (1 << first
) - 1, num_slots
, state
))
7587 /* Sort the current packet into assembly-language order. Set packing
7588 flags as appropriate. */
7591 frv_reorder_packet (void)
7593 unsigned int cursor
[NUM_GROUPS
];
7594 rtx insns
[ARRAY_SIZE (frv_unit_groups
)];
7595 unsigned int unit
, to
, from
;
7596 enum frv_insn_group group
;
7597 struct frv_packet_group
*packet_group
;
7599 /* First sort each group individually. */
7600 for (group
= GROUP_I
; group
< NUM_GROUPS
;
7601 group
= (enum frv_insn_group
) (group
+ 1))
7604 frv_sort_insn_group (group
);
7607 /* Go through the unit template and try add an instruction from
7608 that unit's group. */
7610 for (unit
= 0; unit
< ARRAY_SIZE (frv_unit_groups
); unit
++)
7612 group
= frv_unit_groups
[unit
];
7613 packet_group
= &frv_packet
.groups
[group
];
7614 if (cursor
[group
] < packet_group
->num_insns
)
7616 /* frv_reorg should have added nops for us. */
7617 gcc_assert (packet_group
->sorted
[cursor
[group
]]
7618 != packet_group
->nop
);
7619 insns
[to
++] = packet_group
->sorted
[cursor
[group
]++];
7623 gcc_assert (to
== frv_packet
.num_insns
);
7625 /* Clear the last instruction's packing flag, thus marking the end of
7626 a packet. Reorder the other instructions relative to it. */
7627 CLEAR_PACKING_FLAG (insns
[to
- 1]);
7628 for (from
= 0; from
< to
- 1; from
++)
7630 remove_insn (insns
[from
]);
7631 add_insn_before (insns
[from
], insns
[to
- 1], NULL
);
7632 SET_PACKING_FLAG (insns
[from
]);
7637 /* Divide instructions into packets. Reorder the contents of each
7638 packet so that they are in the correct assembly-language order.
7640 Since this pass can change the raw meaning of the rtl stream, it must
7641 only be called at the last minute, just before the instructions are
7645 frv_pack_insns (void)
7647 if (frv_for_each_packet (frv_reorder_packet
))
7648 frv_insn_packing_flag
= 0;
7650 frv_insn_packing_flag
= -1;
7653 /* See whether we need to add nops to group GROUP in order to
7654 make a valid packet. */
7657 frv_fill_unused_units (enum frv_insn_group group
)
7659 unsigned int non_nops
, nops
, i
;
7660 struct frv_packet_group
*packet_group
;
7662 packet_group
= &frv_packet
.groups
[group
];
7664 /* Sort the instructions into assembly-language order.
7665 Use nops to fill slots that are otherwise unused. */
7666 frv_sort_insn_group (group
);
7668 /* See how many nops are needed before the final useful instruction. */
7670 for (non_nops
= 0; non_nops
< packet_group
->num_insns
; non_nops
++)
7671 while (packet_group
->sorted
[i
++] == packet_group
->nop
)
7674 /* Insert that many nops into the instruction stream. */
7676 frv_insert_nop_in_packet (packet_group
->nop
);
7679 /* Return true if accesses IO1 and IO2 refer to the same doubleword. */
7682 frv_same_doubleword_p (const struct frv_io
*io1
, const struct frv_io
*io2
)
7684 if (io1
->const_address
!= 0 && io2
->const_address
!= 0)
7685 return io1
->const_address
== io2
->const_address
;
7687 if (io1
->var_address
!= 0 && io2
->var_address
!= 0)
7688 return rtx_equal_p (io1
->var_address
, io2
->var_address
);
7693 /* Return true if operations IO1 and IO2 are guaranteed to complete
7697 frv_io_fixed_order_p (const struct frv_io
*io1
, const struct frv_io
*io2
)
7699 /* The order of writes is always preserved. */
7700 if (io1
->type
== FRV_IO_WRITE
&& io2
->type
== FRV_IO_WRITE
)
7703 /* The order of reads isn't preserved. */
7704 if (io1
->type
!= FRV_IO_WRITE
&& io2
->type
!= FRV_IO_WRITE
)
7707 /* One operation is a write and the other is (or could be) a read.
7708 The order is only guaranteed if the accesses are to the same
7710 return frv_same_doubleword_p (io1
, io2
);
7713 /* Generalize I/O operation X so that it covers both X and Y. */
7716 frv_io_union (struct frv_io
*x
, const struct frv_io
*y
)
7718 if (x
->type
!= y
->type
)
7719 x
->type
= FRV_IO_UNKNOWN
;
7720 if (!frv_same_doubleword_p (x
, y
))
7722 x
->const_address
= 0;
7727 /* Fill IO with information about the load or store associated with
7728 membar instruction INSN. */
7731 frv_extract_membar (struct frv_io
*io
, rtx_insn
*insn
)
7733 extract_insn (insn
);
7734 io
->type
= (enum frv_io_type
) INTVAL (recog_data
.operand
[2]);
7735 io
->const_address
= INTVAL (recog_data
.operand
[1]);
7736 io
->var_address
= XEXP (recog_data
.operand
[0], 0);
7739 /* A note_stores callback for which DATA points to an rtx. Nullify *DATA
7740 if X is a register and *DATA depends on X. */
7743 frv_io_check_address (rtx x
, const_rtx pat ATTRIBUTE_UNUSED
, void *data
)
7745 rtx
*other
= (rtx
*) data
;
7747 if (REG_P (x
) && *other
!= 0 && reg_overlap_mentioned_p (x
, *other
))
7751 /* A note_stores callback for which DATA points to a HARD_REG_SET.
7752 Remove every modified register from the set. */
7755 frv_io_handle_set (rtx x
, const_rtx pat ATTRIBUTE_UNUSED
, void *data
)
7757 HARD_REG_SET
*set
= (HARD_REG_SET
*) data
;
7761 FOR_EACH_REGNO (regno
, x
)
7762 CLEAR_HARD_REG_BIT (*set
, regno
);
7765 /* A note_uses callback that adds all registers in *X to hard register
7769 frv_io_handle_use (rtx
*x
, void *data
)
7771 find_all_hard_regs (*x
, (HARD_REG_SET
*) data
);
7774 /* Go through block BB looking for membars to remove. There are two
7775 cases where intra-block analysis is enough:
7777 - a membar is redundant if it occurs between two consecutive I/O
7778 operations and if those operations are guaranteed to complete
7781 - a membar for a __builtin_read is redundant if the result is
7782 used before the next I/O operation is issued.
7784 If the last membar in the block could not be removed, and there
7785 are guaranteed to be no I/O operations between that membar and
7786 the end of the block, store the membar in *LAST_MEMBAR, otherwise
7789 Describe the block's first I/O operation in *NEXT_IO. Describe
7790 an unknown operation if the block doesn't do any I/O. */
7793 frv_optimize_membar_local (basic_block bb
, struct frv_io
*next_io
,
7794 rtx_insn
**last_membar
)
7796 HARD_REG_SET used_regs
;
7797 rtx next_membar
, set
;
7801 /* NEXT_IO is the next I/O operation to be performed after the current
7802 instruction. It starts off as being an unknown operation. */
7803 memset (next_io
, 0, sizeof (*next_io
));
7805 /* NEXT_IS_END_P is true if NEXT_IO describes the end of the block. */
7806 next_is_end_p
= true;
7808 /* If the current instruction is a __builtin_read or __builtin_write,
7809 NEXT_MEMBAR is the membar instruction associated with it. NEXT_MEMBAR
7810 is null if the membar has already been deleted.
7812 Note that the initialization here should only be needed to
7813 suppress warnings. */
7816 /* USED_REGS is the set of registers that are used before the
7817 next I/O instruction. */
7818 CLEAR_HARD_REG_SET (used_regs
);
7820 for (insn
= BB_END (bb
); insn
!= BB_HEAD (bb
); insn
= PREV_INSN (insn
))
7823 /* We can't predict what a call will do to volatile memory. */
7824 memset (next_io
, 0, sizeof (struct frv_io
));
7825 next_is_end_p
= false;
7826 CLEAR_HARD_REG_SET (used_regs
);
7828 else if (INSN_P (insn
))
7829 switch (recog_memoized (insn
))
7831 case CODE_FOR_optional_membar_qi
:
7832 case CODE_FOR_optional_membar_hi
:
7833 case CODE_FOR_optional_membar_si
:
7834 case CODE_FOR_optional_membar_di
:
7838 /* Local information isn't enough to decide whether this
7839 membar is needed. Stash it away for later. */
7840 *last_membar
= insn
;
7841 frv_extract_membar (next_io
, insn
);
7842 next_is_end_p
= false;
7846 /* Check whether the I/O operation before INSN could be
7847 reordered with one described by NEXT_IO. If it can't,
7848 INSN will not be needed. */
7849 struct frv_io prev_io
;
7851 frv_extract_membar (&prev_io
, insn
);
7852 if (frv_io_fixed_order_p (&prev_io
, next_io
))
7856 ";; [Local] Removing membar %d since order"
7857 " of accesses is guaranteed\n",
7858 INSN_UID (next_membar
));
7860 insn
= NEXT_INSN (insn
);
7861 delete_insn (next_membar
);
7869 /* Invalidate NEXT_IO's address if it depends on something that
7870 is clobbered by INSN. */
7871 if (next_io
->var_address
)
7872 note_stores (PATTERN (insn
), frv_io_check_address
,
7873 &next_io
->var_address
);
7875 /* If the next membar is associated with a __builtin_read,
7876 see if INSN reads from that address. If it does, and if
7877 the destination register is used before the next I/O access,
7878 there is no need for the membar. */
7879 set
= PATTERN (insn
);
7880 if (next_io
->type
== FRV_IO_READ
7881 && next_io
->var_address
!= 0
7883 && GET_CODE (set
) == SET
7884 && GET_CODE (SET_DEST (set
)) == REG
7885 && TEST_HARD_REG_BIT (used_regs
, REGNO (SET_DEST (set
))))
7889 src
= SET_SRC (set
);
7890 if (GET_CODE (src
) == ZERO_EXTEND
)
7891 src
= XEXP (src
, 0);
7893 if (GET_CODE (src
) == MEM
7894 && rtx_equal_p (XEXP (src
, 0), next_io
->var_address
))
7898 ";; [Local] Removing membar %d since the target"
7899 " of %d is used before the I/O operation\n",
7900 INSN_UID (next_membar
), INSN_UID (insn
));
7902 if (next_membar
== *last_membar
)
7905 delete_insn (next_membar
);
7910 /* If INSN has volatile references, forget about any registers
7911 that are used after it. Otherwise forget about uses that
7912 are (or might be) defined by INSN. */
7913 if (volatile_refs_p (PATTERN (insn
)))
7914 CLEAR_HARD_REG_SET (used_regs
);
7916 note_stores (PATTERN (insn
), frv_io_handle_set
, &used_regs
);
7918 note_uses (&PATTERN (insn
), frv_io_handle_use
, &used_regs
);
7923 /* See if MEMBAR, the last membar instruction in BB, can be removed.
7924 FIRST_IO[X] describes the first operation performed by basic block X. */
7927 frv_optimize_membar_global (basic_block bb
, struct frv_io
*first_io
,
7930 struct frv_io this_io
, next_io
;
7934 /* We need to keep the membar if there is an edge to the exit block. */
7935 FOR_EACH_EDGE (succ
, ei
, bb
->succs
)
7936 /* for (succ = bb->succ; succ != 0; succ = succ->succ_next) */
7937 if (succ
->dest
== EXIT_BLOCK_PTR_FOR_FN (cfun
))
7940 /* Work out the union of all successor blocks. */
7941 ei
= ei_start (bb
->succs
);
7942 ei_cond (ei
, &succ
);
7943 /* next_io = first_io[bb->succ->dest->index]; */
7944 next_io
= first_io
[succ
->dest
->index
];
7945 ei
= ei_start (bb
->succs
);
7946 if (ei_cond (ei
, &succ
))
7948 for (ei_next (&ei
); ei_cond (ei
, &succ
); ei_next (&ei
))
7949 /*for (succ = bb->succ->succ_next; succ != 0; succ = succ->succ_next)*/
7950 frv_io_union (&next_io
, &first_io
[succ
->dest
->index
]);
7955 frv_extract_membar (&this_io
, membar
);
7956 if (frv_io_fixed_order_p (&this_io
, &next_io
))
7960 ";; [Global] Removing membar %d since order of accesses"
7961 " is guaranteed\n", INSN_UID (membar
));
7963 delete_insn (membar
);
7967 /* Remove redundant membars from the current function. */
7970 frv_optimize_membar (void)
7973 struct frv_io
*first_io
;
7974 rtx_insn
**last_membar
;
7976 compute_bb_for_insn ();
7977 first_io
= XCNEWVEC (struct frv_io
, last_basic_block_for_fn (cfun
));
7978 last_membar
= XCNEWVEC (rtx_insn
*, last_basic_block_for_fn (cfun
));
7980 FOR_EACH_BB_FN (bb
, cfun
)
7981 frv_optimize_membar_local (bb
, &first_io
[bb
->index
],
7982 &last_membar
[bb
->index
]);
7984 FOR_EACH_BB_FN (bb
, cfun
)
7985 if (last_membar
[bb
->index
] != 0)
7986 frv_optimize_membar_global (bb
, first_io
, last_membar
[bb
->index
]);
7992 /* Used by frv_reorg to keep track of the current packet's address. */
7993 static unsigned int frv_packet_address
;
7995 /* If the current packet falls through to a label, try to pad the packet
7996 with nops in order to fit the label's alignment requirements. */
7999 frv_align_label (void)
8001 unsigned int alignment
, target
, nop
;
8002 rtx_insn
*x
, *last
, *barrier
, *label
;
8004 /* Walk forward to the start of the next packet. Set ALIGNMENT to the
8005 maximum alignment of that packet, LABEL to the last label between
8006 the packets, and BARRIER to the last barrier. */
8007 last
= frv_packet
.insns
[frv_packet
.num_insns
- 1];
8008 label
= barrier
= 0;
8010 for (x
= NEXT_INSN (last
); x
!= 0 && !INSN_P (x
); x
= NEXT_INSN (x
))
8014 unsigned int subalign
= 1 << label_to_alignment (x
);
8015 alignment
= MAX (alignment
, subalign
);
8022 /* If -malign-labels, and the packet falls through to an unaligned
8023 label, try introducing a nop to align that label to 8 bytes. */
8024 if (TARGET_ALIGN_LABELS
8027 && frv_packet
.num_insns
< frv_packet
.issue_rate
)
8028 alignment
= MAX (alignment
, 8);
8030 /* Advance the address to the end of the current packet. */
8031 frv_packet_address
+= frv_packet
.num_insns
* 4;
8033 /* Work out the target address, after alignment. */
8034 target
= (frv_packet_address
+ alignment
- 1) & -alignment
;
8036 /* If the packet falls through to the label, try to find an efficient
8037 padding sequence. */
8040 /* First try adding nops to the current packet. */
8041 for (nop
= 0; nop
< frv_num_nops
; nop
++)
8042 while (frv_packet_address
< target
&& frv_pack_insn_p (frv_nops
[nop
]))
8044 frv_insert_nop_in_packet (frv_nops
[nop
]);
8045 frv_packet_address
+= 4;
8048 /* If we still haven't reached the target, add some new packets that
8049 contain only nops. If there are two types of nop, insert an
8050 alternating sequence of frv_nops[0] and frv_nops[1], which will
8051 lead to packets like:
8058 etc. Just emit frv_nops[0] if that's the only nop we have. */
8059 last
= frv_packet
.insns
[frv_packet
.num_insns
- 1];
8061 while (frv_packet_address
< target
)
8063 last
= emit_insn_after (PATTERN (frv_nops
[nop
]), last
);
8064 frv_packet_address
+= 4;
8065 if (frv_num_nops
> 1)
8070 frv_packet_address
= target
;
8073 /* Subroutine of frv_reorg, called after each packet has been constructed
8077 frv_reorg_packet (void)
8079 frv_fill_unused_units (GROUP_I
);
8080 frv_fill_unused_units (GROUP_FM
);
8084 /* Add an instruction with pattern NOP to frv_nops[]. */
8087 frv_register_nop (rtx nop
)
8089 rtx_insn
*nop_insn
= make_insn_raw (nop
);
8090 SET_NEXT_INSN (nop_insn
) = 0;
8091 SET_PREV_INSN (nop_insn
) = 0;
8092 frv_nops
[frv_num_nops
++] = nop_insn
;
8095 /* Implement TARGET_MACHINE_DEPENDENT_REORG. Divide the instructions
8096 into packets and check whether we need to insert nops in order to
8097 fulfill the processor's issue requirements. Also, if the user has
8098 requested a certain alignment for a label, try to meet that alignment
8099 by inserting nops in the previous packet. */
8104 if (optimize
> 0 && TARGET_OPTIMIZE_MEMBAR
&& cfun
->machine
->has_membar_p
)
8105 frv_optimize_membar ();
8108 frv_register_nop (gen_nop ());
8110 frv_register_nop (gen_mnop ());
8111 if (TARGET_HARD_FLOAT
)
8112 frv_register_nop (gen_fnop ());
8114 /* Estimate the length of each branch. Although this may change after
8115 we've inserted nops, it will only do so in big functions. */
8116 shorten_branches (get_insns ());
8118 frv_packet_address
= 0;
8119 frv_for_each_packet (frv_reorg_packet
);
8122 #define def_builtin(name, type, code) \
8123 add_builtin_function ((name), (type), (code), BUILT_IN_MD, NULL, NULL)
8125 struct builtin_description
8127 enum insn_code icode
;
8129 enum frv_builtins code
;
8130 enum rtx_code comparison
;
8134 /* Media intrinsics that take a single, constant argument. */
8136 static struct builtin_description bdesc_set
[] =
8138 { CODE_FOR_mhdsets
, "__MHDSETS", FRV_BUILTIN_MHDSETS
, UNKNOWN
, 0 }
8141 /* Media intrinsics that take just one argument. */
8143 static struct builtin_description bdesc_1arg
[] =
8145 { CODE_FOR_mnot
, "__MNOT", FRV_BUILTIN_MNOT
, UNKNOWN
, 0 },
8146 { CODE_FOR_munpackh
, "__MUNPACKH", FRV_BUILTIN_MUNPACKH
, UNKNOWN
, 0 },
8147 { CODE_FOR_mbtoh
, "__MBTOH", FRV_BUILTIN_MBTOH
, UNKNOWN
, 0 },
8148 { CODE_FOR_mhtob
, "__MHTOB", FRV_BUILTIN_MHTOB
, UNKNOWN
, 0},
8149 { CODE_FOR_mabshs
, "__MABSHS", FRV_BUILTIN_MABSHS
, UNKNOWN
, 0 },
8150 { CODE_FOR_scutss
, "__SCUTSS", FRV_BUILTIN_SCUTSS
, UNKNOWN
, 0 }
8153 /* Media intrinsics that take two arguments. */
8155 static struct builtin_description bdesc_2arg
[] =
8157 { CODE_FOR_mand
, "__MAND", FRV_BUILTIN_MAND
, UNKNOWN
, 0},
8158 { CODE_FOR_mor
, "__MOR", FRV_BUILTIN_MOR
, UNKNOWN
, 0},
8159 { CODE_FOR_mxor
, "__MXOR", FRV_BUILTIN_MXOR
, UNKNOWN
, 0},
8160 { CODE_FOR_maveh
, "__MAVEH", FRV_BUILTIN_MAVEH
, UNKNOWN
, 0},
8161 { CODE_FOR_msaths
, "__MSATHS", FRV_BUILTIN_MSATHS
, UNKNOWN
, 0},
8162 { CODE_FOR_msathu
, "__MSATHU", FRV_BUILTIN_MSATHU
, UNKNOWN
, 0},
8163 { CODE_FOR_maddhss
, "__MADDHSS", FRV_BUILTIN_MADDHSS
, UNKNOWN
, 0},
8164 { CODE_FOR_maddhus
, "__MADDHUS", FRV_BUILTIN_MADDHUS
, UNKNOWN
, 0},
8165 { CODE_FOR_msubhss
, "__MSUBHSS", FRV_BUILTIN_MSUBHSS
, UNKNOWN
, 0},
8166 { CODE_FOR_msubhus
, "__MSUBHUS", FRV_BUILTIN_MSUBHUS
, UNKNOWN
, 0},
8167 { CODE_FOR_mqaddhss
, "__MQADDHSS", FRV_BUILTIN_MQADDHSS
, UNKNOWN
, 0},
8168 { CODE_FOR_mqaddhus
, "__MQADDHUS", FRV_BUILTIN_MQADDHUS
, UNKNOWN
, 0},
8169 { CODE_FOR_mqsubhss
, "__MQSUBHSS", FRV_BUILTIN_MQSUBHSS
, UNKNOWN
, 0},
8170 { CODE_FOR_mqsubhus
, "__MQSUBHUS", FRV_BUILTIN_MQSUBHUS
, UNKNOWN
, 0},
8171 { CODE_FOR_mpackh
, "__MPACKH", FRV_BUILTIN_MPACKH
, UNKNOWN
, 0},
8172 { CODE_FOR_mcop1
, "__Mcop1", FRV_BUILTIN_MCOP1
, UNKNOWN
, 0},
8173 { CODE_FOR_mcop2
, "__Mcop2", FRV_BUILTIN_MCOP2
, UNKNOWN
, 0},
8174 { CODE_FOR_mwcut
, "__MWCUT", FRV_BUILTIN_MWCUT
, UNKNOWN
, 0},
8175 { CODE_FOR_mqsaths
, "__MQSATHS", FRV_BUILTIN_MQSATHS
, UNKNOWN
, 0},
8176 { CODE_FOR_mqlclrhs
, "__MQLCLRHS", FRV_BUILTIN_MQLCLRHS
, UNKNOWN
, 0},
8177 { CODE_FOR_mqlmths
, "__MQLMTHS", FRV_BUILTIN_MQLMTHS
, UNKNOWN
, 0},
8178 { CODE_FOR_smul
, "__SMUL", FRV_BUILTIN_SMUL
, UNKNOWN
, 0},
8179 { CODE_FOR_umul
, "__UMUL", FRV_BUILTIN_UMUL
, UNKNOWN
, 0},
8180 { CODE_FOR_addss
, "__ADDSS", FRV_BUILTIN_ADDSS
, UNKNOWN
, 0},
8181 { CODE_FOR_subss
, "__SUBSS", FRV_BUILTIN_SUBSS
, UNKNOWN
, 0},
8182 { CODE_FOR_slass
, "__SLASS", FRV_BUILTIN_SLASS
, UNKNOWN
, 0},
8183 { CODE_FOR_scan
, "__SCAN", FRV_BUILTIN_SCAN
, UNKNOWN
, 0}
8186 /* Integer intrinsics that take two arguments and have no return value. */
8188 static struct builtin_description bdesc_int_void2arg
[] =
8190 { CODE_FOR_smass
, "__SMASS", FRV_BUILTIN_SMASS
, UNKNOWN
, 0},
8191 { CODE_FOR_smsss
, "__SMSSS", FRV_BUILTIN_SMSSS
, UNKNOWN
, 0},
8192 { CODE_FOR_smu
, "__SMU", FRV_BUILTIN_SMU
, UNKNOWN
, 0}
8195 static struct builtin_description bdesc_prefetches
[] =
8197 { CODE_FOR_frv_prefetch0
, "__data_prefetch0", FRV_BUILTIN_PREFETCH0
, UNKNOWN
,
8199 { CODE_FOR_frv_prefetch
, "__data_prefetch", FRV_BUILTIN_PREFETCH
, UNKNOWN
, 0}
8202 /* Media intrinsics that take two arguments, the first being an ACC number. */
8204 static struct builtin_description bdesc_cut
[] =
8206 { CODE_FOR_mcut
, "__MCUT", FRV_BUILTIN_MCUT
, UNKNOWN
, 0},
8207 { CODE_FOR_mcutss
, "__MCUTSS", FRV_BUILTIN_MCUTSS
, UNKNOWN
, 0},
8208 { CODE_FOR_mdcutssi
, "__MDCUTSSI", FRV_BUILTIN_MDCUTSSI
, UNKNOWN
, 0}
8211 /* Two-argument media intrinsics with an immediate second argument. */
8213 static struct builtin_description bdesc_2argimm
[] =
8215 { CODE_FOR_mrotli
, "__MROTLI", FRV_BUILTIN_MROTLI
, UNKNOWN
, 0},
8216 { CODE_FOR_mrotri
, "__MROTRI", FRV_BUILTIN_MROTRI
, UNKNOWN
, 0},
8217 { CODE_FOR_msllhi
, "__MSLLHI", FRV_BUILTIN_MSLLHI
, UNKNOWN
, 0},
8218 { CODE_FOR_msrlhi
, "__MSRLHI", FRV_BUILTIN_MSRLHI
, UNKNOWN
, 0},
8219 { CODE_FOR_msrahi
, "__MSRAHI", FRV_BUILTIN_MSRAHI
, UNKNOWN
, 0},
8220 { CODE_FOR_mexpdhw
, "__MEXPDHW", FRV_BUILTIN_MEXPDHW
, UNKNOWN
, 0},
8221 { CODE_FOR_mexpdhd
, "__MEXPDHD", FRV_BUILTIN_MEXPDHD
, UNKNOWN
, 0},
8222 { CODE_FOR_mdrotli
, "__MDROTLI", FRV_BUILTIN_MDROTLI
, UNKNOWN
, 0},
8223 { CODE_FOR_mcplhi
, "__MCPLHI", FRV_BUILTIN_MCPLHI
, UNKNOWN
, 0},
8224 { CODE_FOR_mcpli
, "__MCPLI", FRV_BUILTIN_MCPLI
, UNKNOWN
, 0},
8225 { CODE_FOR_mhsetlos
, "__MHSETLOS", FRV_BUILTIN_MHSETLOS
, UNKNOWN
, 0},
8226 { CODE_FOR_mhsetloh
, "__MHSETLOH", FRV_BUILTIN_MHSETLOH
, UNKNOWN
, 0},
8227 { CODE_FOR_mhsethis
, "__MHSETHIS", FRV_BUILTIN_MHSETHIS
, UNKNOWN
, 0},
8228 { CODE_FOR_mhsethih
, "__MHSETHIH", FRV_BUILTIN_MHSETHIH
, UNKNOWN
, 0},
8229 { CODE_FOR_mhdseth
, "__MHDSETH", FRV_BUILTIN_MHDSETH
, UNKNOWN
, 0},
8230 { CODE_FOR_mqsllhi
, "__MQSLLHI", FRV_BUILTIN_MQSLLHI
, UNKNOWN
, 0},
8231 { CODE_FOR_mqsrahi
, "__MQSRAHI", FRV_BUILTIN_MQSRAHI
, UNKNOWN
, 0}
8234 /* Media intrinsics that take two arguments and return void, the first argument
8235 being a pointer to 4 words in memory. */
8237 static struct builtin_description bdesc_void2arg
[] =
8239 { CODE_FOR_mdunpackh
, "__MDUNPACKH", FRV_BUILTIN_MDUNPACKH
, UNKNOWN
, 0},
8240 { CODE_FOR_mbtohe
, "__MBTOHE", FRV_BUILTIN_MBTOHE
, UNKNOWN
, 0},
8243 /* Media intrinsics that take three arguments, the first being a const_int that
8244 denotes an accumulator, and that return void. */
8246 static struct builtin_description bdesc_void3arg
[] =
8248 { CODE_FOR_mcpxrs
, "__MCPXRS", FRV_BUILTIN_MCPXRS
, UNKNOWN
, 0},
8249 { CODE_FOR_mcpxru
, "__MCPXRU", FRV_BUILTIN_MCPXRU
, UNKNOWN
, 0},
8250 { CODE_FOR_mcpxis
, "__MCPXIS", FRV_BUILTIN_MCPXIS
, UNKNOWN
, 0},
8251 { CODE_FOR_mcpxiu
, "__MCPXIU", FRV_BUILTIN_MCPXIU
, UNKNOWN
, 0},
8252 { CODE_FOR_mmulhs
, "__MMULHS", FRV_BUILTIN_MMULHS
, UNKNOWN
, 0},
8253 { CODE_FOR_mmulhu
, "__MMULHU", FRV_BUILTIN_MMULHU
, UNKNOWN
, 0},
8254 { CODE_FOR_mmulxhs
, "__MMULXHS", FRV_BUILTIN_MMULXHS
, UNKNOWN
, 0},
8255 { CODE_FOR_mmulxhu
, "__MMULXHU", FRV_BUILTIN_MMULXHU
, UNKNOWN
, 0},
8256 { CODE_FOR_mmachs
, "__MMACHS", FRV_BUILTIN_MMACHS
, UNKNOWN
, 0},
8257 { CODE_FOR_mmachu
, "__MMACHU", FRV_BUILTIN_MMACHU
, UNKNOWN
, 0},
8258 { CODE_FOR_mmrdhs
, "__MMRDHS", FRV_BUILTIN_MMRDHS
, UNKNOWN
, 0},
8259 { CODE_FOR_mmrdhu
, "__MMRDHU", FRV_BUILTIN_MMRDHU
, UNKNOWN
, 0},
8260 { CODE_FOR_mqcpxrs
, "__MQCPXRS", FRV_BUILTIN_MQCPXRS
, UNKNOWN
, 0},
8261 { CODE_FOR_mqcpxru
, "__MQCPXRU", FRV_BUILTIN_MQCPXRU
, UNKNOWN
, 0},
8262 { CODE_FOR_mqcpxis
, "__MQCPXIS", FRV_BUILTIN_MQCPXIS
, UNKNOWN
, 0},
8263 { CODE_FOR_mqcpxiu
, "__MQCPXIU", FRV_BUILTIN_MQCPXIU
, UNKNOWN
, 0},
8264 { CODE_FOR_mqmulhs
, "__MQMULHS", FRV_BUILTIN_MQMULHS
, UNKNOWN
, 0},
8265 { CODE_FOR_mqmulhu
, "__MQMULHU", FRV_BUILTIN_MQMULHU
, UNKNOWN
, 0},
8266 { CODE_FOR_mqmulxhs
, "__MQMULXHS", FRV_BUILTIN_MQMULXHS
, UNKNOWN
, 0},
8267 { CODE_FOR_mqmulxhu
, "__MQMULXHU", FRV_BUILTIN_MQMULXHU
, UNKNOWN
, 0},
8268 { CODE_FOR_mqmachs
, "__MQMACHS", FRV_BUILTIN_MQMACHS
, UNKNOWN
, 0},
8269 { CODE_FOR_mqmachu
, "__MQMACHU", FRV_BUILTIN_MQMACHU
, UNKNOWN
, 0},
8270 { CODE_FOR_mqxmachs
, "__MQXMACHS", FRV_BUILTIN_MQXMACHS
, UNKNOWN
, 0},
8271 { CODE_FOR_mqxmacxhs
, "__MQXMACXHS", FRV_BUILTIN_MQXMACXHS
, UNKNOWN
, 0},
8272 { CODE_FOR_mqmacxhs
, "__MQMACXHS", FRV_BUILTIN_MQMACXHS
, UNKNOWN
, 0}
8275 /* Media intrinsics that take two accumulator numbers as argument and
8278 static struct builtin_description bdesc_voidacc
[] =
8280 { CODE_FOR_maddaccs
, "__MADDACCS", FRV_BUILTIN_MADDACCS
, UNKNOWN
, 0},
8281 { CODE_FOR_msubaccs
, "__MSUBACCS", FRV_BUILTIN_MSUBACCS
, UNKNOWN
, 0},
8282 { CODE_FOR_masaccs
, "__MASACCS", FRV_BUILTIN_MASACCS
, UNKNOWN
, 0},
8283 { CODE_FOR_mdaddaccs
, "__MDADDACCS", FRV_BUILTIN_MDADDACCS
, UNKNOWN
, 0},
8284 { CODE_FOR_mdsubaccs
, "__MDSUBACCS", FRV_BUILTIN_MDSUBACCS
, UNKNOWN
, 0},
8285 { CODE_FOR_mdasaccs
, "__MDASACCS", FRV_BUILTIN_MDASACCS
, UNKNOWN
, 0}
8288 /* Intrinsics that load a value and then issue a MEMBAR. The load is
8289 a normal move and the ICODE is for the membar. */
8291 static struct builtin_description bdesc_loads
[] =
8293 { CODE_FOR_optional_membar_qi
, "__builtin_read8",
8294 FRV_BUILTIN_READ8
, UNKNOWN
, 0},
8295 { CODE_FOR_optional_membar_hi
, "__builtin_read16",
8296 FRV_BUILTIN_READ16
, UNKNOWN
, 0},
8297 { CODE_FOR_optional_membar_si
, "__builtin_read32",
8298 FRV_BUILTIN_READ32
, UNKNOWN
, 0},
8299 { CODE_FOR_optional_membar_di
, "__builtin_read64",
8300 FRV_BUILTIN_READ64
, UNKNOWN
, 0}
8303 /* Likewise stores. */
8305 static struct builtin_description bdesc_stores
[] =
8307 { CODE_FOR_optional_membar_qi
, "__builtin_write8",
8308 FRV_BUILTIN_WRITE8
, UNKNOWN
, 0},
8309 { CODE_FOR_optional_membar_hi
, "__builtin_write16",
8310 FRV_BUILTIN_WRITE16
, UNKNOWN
, 0},
8311 { CODE_FOR_optional_membar_si
, "__builtin_write32",
8312 FRV_BUILTIN_WRITE32
, UNKNOWN
, 0},
8313 { CODE_FOR_optional_membar_di
, "__builtin_write64",
8314 FRV_BUILTIN_WRITE64
, UNKNOWN
, 0},
8317 /* Initialize media builtins. */
8320 frv_init_builtins (void)
8322 tree accumulator
= integer_type_node
;
8323 tree integer
= integer_type_node
;
8324 tree voidt
= void_type_node
;
8325 tree uhalf
= short_unsigned_type_node
;
8326 tree sword1
= long_integer_type_node
;
8327 tree uword1
= long_unsigned_type_node
;
8328 tree sword2
= long_long_integer_type_node
;
8329 tree uword2
= long_long_unsigned_type_node
;
8330 tree uword4
= build_pointer_type (uword1
);
8331 tree vptr
= build_pointer_type (build_type_variant (void_type_node
, 0, 1));
8332 tree ubyte
= unsigned_char_type_node
;
8333 tree iacc
= integer_type_node
;
8335 #define UNARY(RET, T1) \
8336 build_function_type_list (RET, T1, NULL_TREE)
8338 #define BINARY(RET, T1, T2) \
8339 build_function_type_list (RET, T1, T2, NULL_TREE)
8341 #define TRINARY(RET, T1, T2, T3) \
8342 build_function_type_list (RET, T1, T2, T3, NULL_TREE)
8344 #define QUAD(RET, T1, T2, T3, T4) \
8345 build_function_type_list (RET, T1, T2, T3, T4, NULL_TREE)
8347 tree void_ftype_void
= build_function_type_list (voidt
, NULL_TREE
);
8349 tree void_ftype_acc
= UNARY (voidt
, accumulator
);
8350 tree void_ftype_uw4_uw1
= BINARY (voidt
, uword4
, uword1
);
8351 tree void_ftype_uw4_uw2
= BINARY (voidt
, uword4
, uword2
);
8352 tree void_ftype_acc_uw1
= BINARY (voidt
, accumulator
, uword1
);
8353 tree void_ftype_acc_acc
= BINARY (voidt
, accumulator
, accumulator
);
8354 tree void_ftype_acc_uw1_uw1
= TRINARY (voidt
, accumulator
, uword1
, uword1
);
8355 tree void_ftype_acc_sw1_sw1
= TRINARY (voidt
, accumulator
, sword1
, sword1
);
8356 tree void_ftype_acc_uw2_uw2
= TRINARY (voidt
, accumulator
, uword2
, uword2
);
8357 tree void_ftype_acc_sw2_sw2
= TRINARY (voidt
, accumulator
, sword2
, sword2
);
8359 tree uw1_ftype_uw1
= UNARY (uword1
, uword1
);
8360 tree uw1_ftype_sw1
= UNARY (uword1
, sword1
);
8361 tree uw1_ftype_uw2
= UNARY (uword1
, uword2
);
8362 tree uw1_ftype_acc
= UNARY (uword1
, accumulator
);
8363 tree uw1_ftype_uh_uh
= BINARY (uword1
, uhalf
, uhalf
);
8364 tree uw1_ftype_uw1_uw1
= BINARY (uword1
, uword1
, uword1
);
8365 tree uw1_ftype_uw1_int
= BINARY (uword1
, uword1
, integer
);
8366 tree uw1_ftype_acc_uw1
= BINARY (uword1
, accumulator
, uword1
);
8367 tree uw1_ftype_acc_sw1
= BINARY (uword1
, accumulator
, sword1
);
8368 tree uw1_ftype_uw2_uw1
= BINARY (uword1
, uword2
, uword1
);
8369 tree uw1_ftype_uw2_int
= BINARY (uword1
, uword2
, integer
);
8371 tree sw1_ftype_int
= UNARY (sword1
, integer
);
8372 tree sw1_ftype_sw1_sw1
= BINARY (sword1
, sword1
, sword1
);
8373 tree sw1_ftype_sw1_int
= BINARY (sword1
, sword1
, integer
);
8375 tree uw2_ftype_uw1
= UNARY (uword2
, uword1
);
8376 tree uw2_ftype_uw1_int
= BINARY (uword2
, uword1
, integer
);
8377 tree uw2_ftype_uw2_uw2
= BINARY (uword2
, uword2
, uword2
);
8378 tree uw2_ftype_uw2_int
= BINARY (uword2
, uword2
, integer
);
8379 tree uw2_ftype_acc_int
= BINARY (uword2
, accumulator
, integer
);
8380 tree uw2_ftype_uh_uh_uh_uh
= QUAD (uword2
, uhalf
, uhalf
, uhalf
, uhalf
);
8382 tree sw2_ftype_sw2_sw2
= BINARY (sword2
, sword2
, sword2
);
8383 tree sw2_ftype_sw2_int
= BINARY (sword2
, sword2
, integer
);
8384 tree uw2_ftype_uw1_uw1
= BINARY (uword2
, uword1
, uword1
);
8385 tree sw2_ftype_sw1_sw1
= BINARY (sword2
, sword1
, sword1
);
8386 tree void_ftype_sw1_sw1
= BINARY (voidt
, sword1
, sword1
);
8387 tree void_ftype_iacc_sw2
= BINARY (voidt
, iacc
, sword2
);
8388 tree void_ftype_iacc_sw1
= BINARY (voidt
, iacc
, sword1
);
8389 tree sw1_ftype_sw1
= UNARY (sword1
, sword1
);
8390 tree sw2_ftype_iacc
= UNARY (sword2
, iacc
);
8391 tree sw1_ftype_iacc
= UNARY (sword1
, iacc
);
8392 tree void_ftype_ptr
= UNARY (voidt
, const_ptr_type_node
);
8393 tree uw1_ftype_vptr
= UNARY (uword1
, vptr
);
8394 tree uw2_ftype_vptr
= UNARY (uword2
, vptr
);
8395 tree void_ftype_vptr_ub
= BINARY (voidt
, vptr
, ubyte
);
8396 tree void_ftype_vptr_uh
= BINARY (voidt
, vptr
, uhalf
);
8397 tree void_ftype_vptr_uw1
= BINARY (voidt
, vptr
, uword1
);
8398 tree void_ftype_vptr_uw2
= BINARY (voidt
, vptr
, uword2
);
8400 def_builtin ("__MAND", uw1_ftype_uw1_uw1
, FRV_BUILTIN_MAND
);
8401 def_builtin ("__MOR", uw1_ftype_uw1_uw1
, FRV_BUILTIN_MOR
);
8402 def_builtin ("__MXOR", uw1_ftype_uw1_uw1
, FRV_BUILTIN_MXOR
);
8403 def_builtin ("__MNOT", uw1_ftype_uw1
, FRV_BUILTIN_MNOT
);
8404 def_builtin ("__MROTLI", uw1_ftype_uw1_int
, FRV_BUILTIN_MROTLI
);
8405 def_builtin ("__MROTRI", uw1_ftype_uw1_int
, FRV_BUILTIN_MROTRI
);
8406 def_builtin ("__MWCUT", uw1_ftype_uw2_uw1
, FRV_BUILTIN_MWCUT
);
8407 def_builtin ("__MAVEH", uw1_ftype_uw1_uw1
, FRV_BUILTIN_MAVEH
);
8408 def_builtin ("__MSLLHI", uw1_ftype_uw1_int
, FRV_BUILTIN_MSLLHI
);
8409 def_builtin ("__MSRLHI", uw1_ftype_uw1_int
, FRV_BUILTIN_MSRLHI
);
8410 def_builtin ("__MSRAHI", sw1_ftype_sw1_int
, FRV_BUILTIN_MSRAHI
);
8411 def_builtin ("__MSATHS", sw1_ftype_sw1_sw1
, FRV_BUILTIN_MSATHS
);
8412 def_builtin ("__MSATHU", uw1_ftype_uw1_uw1
, FRV_BUILTIN_MSATHU
);
8413 def_builtin ("__MADDHSS", sw1_ftype_sw1_sw1
, FRV_BUILTIN_MADDHSS
);
8414 def_builtin ("__MADDHUS", uw1_ftype_uw1_uw1
, FRV_BUILTIN_MADDHUS
);
8415 def_builtin ("__MSUBHSS", sw1_ftype_sw1_sw1
, FRV_BUILTIN_MSUBHSS
);
8416 def_builtin ("__MSUBHUS", uw1_ftype_uw1_uw1
, FRV_BUILTIN_MSUBHUS
);
8417 def_builtin ("__MMULHS", void_ftype_acc_sw1_sw1
, FRV_BUILTIN_MMULHS
);
8418 def_builtin ("__MMULHU", void_ftype_acc_uw1_uw1
, FRV_BUILTIN_MMULHU
);
8419 def_builtin ("__MMULXHS", void_ftype_acc_sw1_sw1
, FRV_BUILTIN_MMULXHS
);
8420 def_builtin ("__MMULXHU", void_ftype_acc_uw1_uw1
, FRV_BUILTIN_MMULXHU
);
8421 def_builtin ("__MMACHS", void_ftype_acc_sw1_sw1
, FRV_BUILTIN_MMACHS
);
8422 def_builtin ("__MMACHU", void_ftype_acc_uw1_uw1
, FRV_BUILTIN_MMACHU
);
8423 def_builtin ("__MMRDHS", void_ftype_acc_sw1_sw1
, FRV_BUILTIN_MMRDHS
);
8424 def_builtin ("__MMRDHU", void_ftype_acc_uw1_uw1
, FRV_BUILTIN_MMRDHU
);
8425 def_builtin ("__MQADDHSS", sw2_ftype_sw2_sw2
, FRV_BUILTIN_MQADDHSS
);
8426 def_builtin ("__MQADDHUS", uw2_ftype_uw2_uw2
, FRV_BUILTIN_MQADDHUS
);
8427 def_builtin ("__MQSUBHSS", sw2_ftype_sw2_sw2
, FRV_BUILTIN_MQSUBHSS
);
8428 def_builtin ("__MQSUBHUS", uw2_ftype_uw2_uw2
, FRV_BUILTIN_MQSUBHUS
);
8429 def_builtin ("__MQMULHS", void_ftype_acc_sw2_sw2
, FRV_BUILTIN_MQMULHS
);
8430 def_builtin ("__MQMULHU", void_ftype_acc_uw2_uw2
, FRV_BUILTIN_MQMULHU
);
8431 def_builtin ("__MQMULXHS", void_ftype_acc_sw2_sw2
, FRV_BUILTIN_MQMULXHS
);
8432 def_builtin ("__MQMULXHU", void_ftype_acc_uw2_uw2
, FRV_BUILTIN_MQMULXHU
);
8433 def_builtin ("__MQMACHS", void_ftype_acc_sw2_sw2
, FRV_BUILTIN_MQMACHS
);
8434 def_builtin ("__MQMACHU", void_ftype_acc_uw2_uw2
, FRV_BUILTIN_MQMACHU
);
8435 def_builtin ("__MCPXRS", void_ftype_acc_sw1_sw1
, FRV_BUILTIN_MCPXRS
);
8436 def_builtin ("__MCPXRU", void_ftype_acc_uw1_uw1
, FRV_BUILTIN_MCPXRU
);
8437 def_builtin ("__MCPXIS", void_ftype_acc_sw1_sw1
, FRV_BUILTIN_MCPXIS
);
8438 def_builtin ("__MCPXIU", void_ftype_acc_uw1_uw1
, FRV_BUILTIN_MCPXIU
);
8439 def_builtin ("__MQCPXRS", void_ftype_acc_sw2_sw2
, FRV_BUILTIN_MQCPXRS
);
8440 def_builtin ("__MQCPXRU", void_ftype_acc_uw2_uw2
, FRV_BUILTIN_MQCPXRU
);
8441 def_builtin ("__MQCPXIS", void_ftype_acc_sw2_sw2
, FRV_BUILTIN_MQCPXIS
);
8442 def_builtin ("__MQCPXIU", void_ftype_acc_uw2_uw2
, FRV_BUILTIN_MQCPXIU
);
8443 def_builtin ("__MCUT", uw1_ftype_acc_uw1
, FRV_BUILTIN_MCUT
);
8444 def_builtin ("__MCUTSS", uw1_ftype_acc_sw1
, FRV_BUILTIN_MCUTSS
);
8445 def_builtin ("__MEXPDHW", uw1_ftype_uw1_int
, FRV_BUILTIN_MEXPDHW
);
8446 def_builtin ("__MEXPDHD", uw2_ftype_uw1_int
, FRV_BUILTIN_MEXPDHD
);
8447 def_builtin ("__MPACKH", uw1_ftype_uh_uh
, FRV_BUILTIN_MPACKH
);
8448 def_builtin ("__MUNPACKH", uw2_ftype_uw1
, FRV_BUILTIN_MUNPACKH
);
8449 def_builtin ("__MDPACKH", uw2_ftype_uh_uh_uh_uh
, FRV_BUILTIN_MDPACKH
);
8450 def_builtin ("__MDUNPACKH", void_ftype_uw4_uw2
, FRV_BUILTIN_MDUNPACKH
);
8451 def_builtin ("__MBTOH", uw2_ftype_uw1
, FRV_BUILTIN_MBTOH
);
8452 def_builtin ("__MHTOB", uw1_ftype_uw2
, FRV_BUILTIN_MHTOB
);
8453 def_builtin ("__MBTOHE", void_ftype_uw4_uw1
, FRV_BUILTIN_MBTOHE
);
8454 def_builtin ("__MCLRACC", void_ftype_acc
, FRV_BUILTIN_MCLRACC
);
8455 def_builtin ("__MCLRACCA", void_ftype_void
, FRV_BUILTIN_MCLRACCA
);
8456 def_builtin ("__MRDACC", uw1_ftype_acc
, FRV_BUILTIN_MRDACC
);
8457 def_builtin ("__MRDACCG", uw1_ftype_acc
, FRV_BUILTIN_MRDACCG
);
8458 def_builtin ("__MWTACC", void_ftype_acc_uw1
, FRV_BUILTIN_MWTACC
);
8459 def_builtin ("__MWTACCG", void_ftype_acc_uw1
, FRV_BUILTIN_MWTACCG
);
8460 def_builtin ("__Mcop1", uw1_ftype_uw1_uw1
, FRV_BUILTIN_MCOP1
);
8461 def_builtin ("__Mcop2", uw1_ftype_uw1_uw1
, FRV_BUILTIN_MCOP2
);
8462 def_builtin ("__MTRAP", void_ftype_void
, FRV_BUILTIN_MTRAP
);
8463 def_builtin ("__MQXMACHS", void_ftype_acc_sw2_sw2
, FRV_BUILTIN_MQXMACHS
);
8464 def_builtin ("__MQXMACXHS", void_ftype_acc_sw2_sw2
, FRV_BUILTIN_MQXMACXHS
);
8465 def_builtin ("__MQMACXHS", void_ftype_acc_sw2_sw2
, FRV_BUILTIN_MQMACXHS
);
8466 def_builtin ("__MADDACCS", void_ftype_acc_acc
, FRV_BUILTIN_MADDACCS
);
8467 def_builtin ("__MSUBACCS", void_ftype_acc_acc
, FRV_BUILTIN_MSUBACCS
);
8468 def_builtin ("__MASACCS", void_ftype_acc_acc
, FRV_BUILTIN_MASACCS
);
8469 def_builtin ("__MDADDACCS", void_ftype_acc_acc
, FRV_BUILTIN_MDADDACCS
);
8470 def_builtin ("__MDSUBACCS", void_ftype_acc_acc
, FRV_BUILTIN_MDSUBACCS
);
8471 def_builtin ("__MDASACCS", void_ftype_acc_acc
, FRV_BUILTIN_MDASACCS
);
8472 def_builtin ("__MABSHS", uw1_ftype_sw1
, FRV_BUILTIN_MABSHS
);
8473 def_builtin ("__MDROTLI", uw2_ftype_uw2_int
, FRV_BUILTIN_MDROTLI
);
8474 def_builtin ("__MCPLHI", uw1_ftype_uw2_int
, FRV_BUILTIN_MCPLHI
);
8475 def_builtin ("__MCPLI", uw1_ftype_uw2_int
, FRV_BUILTIN_MCPLI
);
8476 def_builtin ("__MDCUTSSI", uw2_ftype_acc_int
, FRV_BUILTIN_MDCUTSSI
);
8477 def_builtin ("__MQSATHS", sw2_ftype_sw2_sw2
, FRV_BUILTIN_MQSATHS
);
8478 def_builtin ("__MHSETLOS", sw1_ftype_sw1_int
, FRV_BUILTIN_MHSETLOS
);
8479 def_builtin ("__MHSETHIS", sw1_ftype_sw1_int
, FRV_BUILTIN_MHSETHIS
);
8480 def_builtin ("__MHDSETS", sw1_ftype_int
, FRV_BUILTIN_MHDSETS
);
8481 def_builtin ("__MHSETLOH", uw1_ftype_uw1_int
, FRV_BUILTIN_MHSETLOH
);
8482 def_builtin ("__MHSETHIH", uw1_ftype_uw1_int
, FRV_BUILTIN_MHSETHIH
);
8483 def_builtin ("__MHDSETH", uw1_ftype_uw1_int
, FRV_BUILTIN_MHDSETH
);
8484 def_builtin ("__MQLCLRHS", sw2_ftype_sw2_sw2
, FRV_BUILTIN_MQLCLRHS
);
8485 def_builtin ("__MQLMTHS", sw2_ftype_sw2_sw2
, FRV_BUILTIN_MQLMTHS
);
8486 def_builtin ("__MQSLLHI", uw2_ftype_uw2_int
, FRV_BUILTIN_MQSLLHI
);
8487 def_builtin ("__MQSRAHI", sw2_ftype_sw2_int
, FRV_BUILTIN_MQSRAHI
);
8488 def_builtin ("__SMUL", sw2_ftype_sw1_sw1
, FRV_BUILTIN_SMUL
);
8489 def_builtin ("__UMUL", uw2_ftype_uw1_uw1
, FRV_BUILTIN_UMUL
);
8490 def_builtin ("__SMASS", void_ftype_sw1_sw1
, FRV_BUILTIN_SMASS
);
8491 def_builtin ("__SMSSS", void_ftype_sw1_sw1
, FRV_BUILTIN_SMSSS
);
8492 def_builtin ("__SMU", void_ftype_sw1_sw1
, FRV_BUILTIN_SMU
);
8493 def_builtin ("__ADDSS", sw1_ftype_sw1_sw1
, FRV_BUILTIN_ADDSS
);
8494 def_builtin ("__SUBSS", sw1_ftype_sw1_sw1
, FRV_BUILTIN_SUBSS
);
8495 def_builtin ("__SLASS", sw1_ftype_sw1_sw1
, FRV_BUILTIN_SLASS
);
8496 def_builtin ("__SCAN", sw1_ftype_sw1_sw1
, FRV_BUILTIN_SCAN
);
8497 def_builtin ("__SCUTSS", sw1_ftype_sw1
, FRV_BUILTIN_SCUTSS
);
8498 def_builtin ("__IACCreadll", sw2_ftype_iacc
, FRV_BUILTIN_IACCreadll
);
8499 def_builtin ("__IACCreadl", sw1_ftype_iacc
, FRV_BUILTIN_IACCreadl
);
8500 def_builtin ("__IACCsetll", void_ftype_iacc_sw2
, FRV_BUILTIN_IACCsetll
);
8501 def_builtin ("__IACCsetl", void_ftype_iacc_sw1
, FRV_BUILTIN_IACCsetl
);
8502 def_builtin ("__data_prefetch0", void_ftype_ptr
, FRV_BUILTIN_PREFETCH0
);
8503 def_builtin ("__data_prefetch", void_ftype_ptr
, FRV_BUILTIN_PREFETCH
);
8504 def_builtin ("__builtin_read8", uw1_ftype_vptr
, FRV_BUILTIN_READ8
);
8505 def_builtin ("__builtin_read16", uw1_ftype_vptr
, FRV_BUILTIN_READ16
);
8506 def_builtin ("__builtin_read32", uw1_ftype_vptr
, FRV_BUILTIN_READ32
);
8507 def_builtin ("__builtin_read64", uw2_ftype_vptr
, FRV_BUILTIN_READ64
);
8509 def_builtin ("__builtin_write8", void_ftype_vptr_ub
, FRV_BUILTIN_WRITE8
);
8510 def_builtin ("__builtin_write16", void_ftype_vptr_uh
, FRV_BUILTIN_WRITE16
);
8511 def_builtin ("__builtin_write32", void_ftype_vptr_uw1
, FRV_BUILTIN_WRITE32
);
8512 def_builtin ("__builtin_write64", void_ftype_vptr_uw2
, FRV_BUILTIN_WRITE64
);
8520 /* Set the names for various arithmetic operations according to the
8523 frv_init_libfuncs (void)
8525 set_optab_libfunc (smod_optab
, SImode
, "__modi");
8526 set_optab_libfunc (umod_optab
, SImode
, "__umodi");
8528 set_optab_libfunc (add_optab
, DImode
, "__addll");
8529 set_optab_libfunc (sub_optab
, DImode
, "__subll");
8530 set_optab_libfunc (smul_optab
, DImode
, "__mulll");
8531 set_optab_libfunc (sdiv_optab
, DImode
, "__divll");
8532 set_optab_libfunc (smod_optab
, DImode
, "__modll");
8533 set_optab_libfunc (umod_optab
, DImode
, "__umodll");
8534 set_optab_libfunc (and_optab
, DImode
, "__andll");
8535 set_optab_libfunc (ior_optab
, DImode
, "__orll");
8536 set_optab_libfunc (xor_optab
, DImode
, "__xorll");
8537 set_optab_libfunc (one_cmpl_optab
, DImode
, "__notll");
8539 set_optab_libfunc (add_optab
, SFmode
, "__addf");
8540 set_optab_libfunc (sub_optab
, SFmode
, "__subf");
8541 set_optab_libfunc (smul_optab
, SFmode
, "__mulf");
8542 set_optab_libfunc (sdiv_optab
, SFmode
, "__divf");
8544 set_optab_libfunc (add_optab
, DFmode
, "__addd");
8545 set_optab_libfunc (sub_optab
, DFmode
, "__subd");
8546 set_optab_libfunc (smul_optab
, DFmode
, "__muld");
8547 set_optab_libfunc (sdiv_optab
, DFmode
, "__divd");
8549 set_conv_libfunc (sext_optab
, DFmode
, SFmode
, "__ftod");
8550 set_conv_libfunc (trunc_optab
, SFmode
, DFmode
, "__dtof");
8552 set_conv_libfunc (sfix_optab
, SImode
, SFmode
, "__ftoi");
8553 set_conv_libfunc (sfix_optab
, DImode
, SFmode
, "__ftoll");
8554 set_conv_libfunc (sfix_optab
, SImode
, DFmode
, "__dtoi");
8555 set_conv_libfunc (sfix_optab
, DImode
, DFmode
, "__dtoll");
8557 set_conv_libfunc (ufix_optab
, SImode
, SFmode
, "__ftoui");
8558 set_conv_libfunc (ufix_optab
, DImode
, SFmode
, "__ftoull");
8559 set_conv_libfunc (ufix_optab
, SImode
, DFmode
, "__dtoui");
8560 set_conv_libfunc (ufix_optab
, DImode
, DFmode
, "__dtoull");
8562 set_conv_libfunc (sfloat_optab
, SFmode
, SImode
, "__itof");
8563 set_conv_libfunc (sfloat_optab
, SFmode
, DImode
, "__lltof");
8564 set_conv_libfunc (sfloat_optab
, DFmode
, SImode
, "__itod");
8565 set_conv_libfunc (sfloat_optab
, DFmode
, DImode
, "__lltod");
8568 /* Convert an integer constant to an accumulator register. ICODE is the
8569 code of the target instruction, OPNUM is the number of the
8570 accumulator operand and OPVAL is the constant integer. Try both
8571 ACC and ACCG registers; only report an error if neither fit the
8575 frv_int_to_acc (enum insn_code icode
, int opnum
, rtx opval
)
8580 /* ACCs and ACCGs are implicit global registers if media intrinsics
8581 are being used. We set up this lazily to avoid creating lots of
8582 unnecessary call_insn rtl in non-media code. */
8583 for (i
= 0; i
<= ACC_MASK
; i
++)
8584 if ((i
& ACC_MASK
) == i
)
8585 global_regs
[i
+ ACC_FIRST
] = global_regs
[i
+ ACCG_FIRST
] = 1;
8587 if (GET_CODE (opval
) != CONST_INT
)
8589 error ("accumulator is not a constant integer");
8592 if ((INTVAL (opval
) & ~ACC_MASK
) != 0)
8594 error ("accumulator number is out of bounds");
8598 reg
= gen_rtx_REG (insn_data
[icode
].operand
[opnum
].mode
,
8599 ACC_FIRST
+ INTVAL (opval
));
8600 if (! (*insn_data
[icode
].operand
[opnum
].predicate
) (reg
, VOIDmode
))
8601 SET_REGNO (reg
, ACCG_FIRST
+ INTVAL (opval
));
8603 if (! (*insn_data
[icode
].operand
[opnum
].predicate
) (reg
, VOIDmode
))
8605 error ("inappropriate accumulator for %qs", insn_data
[icode
].name
);
8611 /* If an ACC rtx has mode MODE, return the mode that the matching ACCG
8615 frv_matching_accg_mode (machine_mode mode
)
8633 /* Given that a __builtin_read or __builtin_write function is accessing
8634 address ADDRESS, return the value that should be used as operand 1
8638 frv_io_address_cookie (rtx address
)
8640 return (GET_CODE (address
) == CONST_INT
8641 ? GEN_INT (INTVAL (address
) / 8 * 8)
8645 /* Return the accumulator guard that should be paired with accumulator
8646 register ACC. The mode of the returned register is in the same
8647 class as ACC, but is four times smaller. */
8650 frv_matching_accg_for_acc (rtx acc
)
8652 return gen_rtx_REG (frv_matching_accg_mode (GET_MODE (acc
)),
8653 REGNO (acc
) - ACC_FIRST
+ ACCG_FIRST
);
8656 /* Read the requested argument from the call EXP given by INDEX.
8657 Return the value as an rtx. */
8660 frv_read_argument (tree exp
, unsigned int index
)
8662 return expand_normal (CALL_EXPR_ARG (exp
, index
));
8665 /* Like frv_read_argument, but interpret the argument as the number
8666 of an IACC register and return a (reg:MODE ...) rtx for it. */
8669 frv_read_iacc_argument (machine_mode mode
, tree call
,
8675 op
= frv_read_argument (call
, index
);
8676 if (GET_CODE (op
) != CONST_INT
8678 || INTVAL (op
) > IACC_LAST
- IACC_FIRST
8679 || ((INTVAL (op
) * 4) & (GET_MODE_SIZE (mode
) - 1)) != 0)
8681 error ("invalid IACC argument");
8685 /* IACCs are implicit global registers. We set up this lazily to
8686 avoid creating lots of unnecessary call_insn rtl when IACCs aren't
8688 regno
= INTVAL (op
) + IACC_FIRST
;
8689 for (i
= 0; i
< HARD_REGNO_NREGS (regno
, mode
); i
++)
8690 global_regs
[regno
+ i
] = 1;
8692 return gen_rtx_REG (mode
, regno
);
8695 /* Return true if OPVAL can be used for operand OPNUM of instruction ICODE.
8696 The instruction should require a constant operand of some sort. The
8697 function prints an error if OPVAL is not valid. */
8700 frv_check_constant_argument (enum insn_code icode
, int opnum
, rtx opval
)
8702 if (GET_CODE (opval
) != CONST_INT
)
8704 error ("%qs expects a constant argument", insn_data
[icode
].name
);
8707 if (! (*insn_data
[icode
].operand
[opnum
].predicate
) (opval
, VOIDmode
))
8709 error ("constant argument out of range for %qs", insn_data
[icode
].name
);
8715 /* Return a legitimate rtx for instruction ICODE's return value. Use TARGET
8716 if it's not null, has the right mode, and satisfies operand 0's
8720 frv_legitimize_target (enum insn_code icode
, rtx target
)
8722 machine_mode mode
= insn_data
[icode
].operand
[0].mode
;
8725 || GET_MODE (target
) != mode
8726 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, mode
))
8727 return gen_reg_rtx (mode
);
8732 /* Given that ARG is being passed as operand OPNUM to instruction ICODE,
8733 check whether ARG satisfies the operand's constraints. If it doesn't,
8734 copy ARG to a temporary register and return that. Otherwise return ARG
8738 frv_legitimize_argument (enum insn_code icode
, int opnum
, rtx arg
)
8740 machine_mode mode
= insn_data
[icode
].operand
[opnum
].mode
;
8742 if ((*insn_data
[icode
].operand
[opnum
].predicate
) (arg
, mode
))
8745 return copy_to_mode_reg (mode
, arg
);
8748 /* Return a volatile memory reference of mode MODE whose address is ARG. */
8751 frv_volatile_memref (machine_mode mode
, rtx arg
)
8755 mem
= gen_rtx_MEM (mode
, memory_address (mode
, arg
));
8756 MEM_VOLATILE_P (mem
) = 1;
8760 /* Expand builtins that take a single, constant argument. At the moment,
8761 only MHDSETS falls into this category. */
8764 frv_expand_set_builtin (enum insn_code icode
, tree call
, rtx target
)
8767 rtx op0
= frv_read_argument (call
, 0);
8769 if (! frv_check_constant_argument (icode
, 1, op0
))
8772 target
= frv_legitimize_target (icode
, target
);
8773 pat
= GEN_FCN (icode
) (target
, op0
);
8781 /* Expand builtins that take one operand. */
8784 frv_expand_unop_builtin (enum insn_code icode
, tree call
, rtx target
)
8787 rtx op0
= frv_read_argument (call
, 0);
8789 target
= frv_legitimize_target (icode
, target
);
8790 op0
= frv_legitimize_argument (icode
, 1, op0
);
8791 pat
= GEN_FCN (icode
) (target
, op0
);
8799 /* Expand builtins that take two operands. */
8802 frv_expand_binop_builtin (enum insn_code icode
, tree call
, rtx target
)
8805 rtx op0
= frv_read_argument (call
, 0);
8806 rtx op1
= frv_read_argument (call
, 1);
8808 target
= frv_legitimize_target (icode
, target
);
8809 op0
= frv_legitimize_argument (icode
, 1, op0
);
8810 op1
= frv_legitimize_argument (icode
, 2, op1
);
8811 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
8819 /* Expand cut-style builtins, which take two operands and an implicit ACCG
8823 frv_expand_cut_builtin (enum insn_code icode
, tree call
, rtx target
)
8826 rtx op0
= frv_read_argument (call
, 0);
8827 rtx op1
= frv_read_argument (call
, 1);
8830 target
= frv_legitimize_target (icode
, target
);
8831 op0
= frv_int_to_acc (icode
, 1, op0
);
8835 if (icode
== CODE_FOR_mdcutssi
|| GET_CODE (op1
) == CONST_INT
)
8837 if (! frv_check_constant_argument (icode
, 2, op1
))
8841 op1
= frv_legitimize_argument (icode
, 2, op1
);
8843 op2
= frv_matching_accg_for_acc (op0
);
8844 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
8852 /* Expand builtins that take two operands and the second is immediate. */
8855 frv_expand_binopimm_builtin (enum insn_code icode
, tree call
, rtx target
)
8858 rtx op0
= frv_read_argument (call
, 0);
8859 rtx op1
= frv_read_argument (call
, 1);
8861 if (! frv_check_constant_argument (icode
, 2, op1
))
8864 target
= frv_legitimize_target (icode
, target
);
8865 op0
= frv_legitimize_argument (icode
, 1, op0
);
8866 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
8874 /* Expand builtins that take two operands, the first operand being a pointer to
8875 ints and return void. */
8878 frv_expand_voidbinop_builtin (enum insn_code icode
, tree call
)
8881 rtx op0
= frv_read_argument (call
, 0);
8882 rtx op1
= frv_read_argument (call
, 1);
8883 machine_mode mode0
= insn_data
[icode
].operand
[0].mode
;
8886 if (GET_CODE (op0
) != MEM
)
8890 if (! offsettable_address_p (0, mode0
, op0
))
8892 reg
= gen_reg_rtx (Pmode
);
8893 emit_insn (gen_rtx_SET (reg
, op0
));
8896 op0
= gen_rtx_MEM (SImode
, reg
);
8899 addr
= XEXP (op0
, 0);
8900 if (! offsettable_address_p (0, mode0
, addr
))
8901 addr
= copy_to_mode_reg (Pmode
, op0
);
8903 op0
= change_address (op0
, V4SImode
, addr
);
8904 op1
= frv_legitimize_argument (icode
, 1, op1
);
8905 pat
= GEN_FCN (icode
) (op0
, op1
);
8913 /* Expand builtins that take two long operands and return void. */
8916 frv_expand_int_void2arg (enum insn_code icode
, tree call
)
8919 rtx op0
= frv_read_argument (call
, 0);
8920 rtx op1
= frv_read_argument (call
, 1);
8922 op0
= frv_legitimize_argument (icode
, 1, op0
);
8923 op1
= frv_legitimize_argument (icode
, 1, op1
);
8924 pat
= GEN_FCN (icode
) (op0
, op1
);
8932 /* Expand prefetch builtins. These take a single address as argument. */
8935 frv_expand_prefetches (enum insn_code icode
, tree call
)
8938 rtx op0
= frv_read_argument (call
, 0);
8940 pat
= GEN_FCN (icode
) (force_reg (Pmode
, op0
));
8948 /* Expand builtins that take three operands and return void. The first
8949 argument must be a constant that describes a pair or quad accumulators. A
8950 fourth argument is created that is the accumulator guard register that
8951 corresponds to the accumulator. */
8954 frv_expand_voidtriop_builtin (enum insn_code icode
, tree call
)
8957 rtx op0
= frv_read_argument (call
, 0);
8958 rtx op1
= frv_read_argument (call
, 1);
8959 rtx op2
= frv_read_argument (call
, 2);
8962 op0
= frv_int_to_acc (icode
, 0, op0
);
8966 op1
= frv_legitimize_argument (icode
, 1, op1
);
8967 op2
= frv_legitimize_argument (icode
, 2, op2
);
8968 op3
= frv_matching_accg_for_acc (op0
);
8969 pat
= GEN_FCN (icode
) (op0
, op1
, op2
, op3
);
8977 /* Expand builtins that perform accumulator-to-accumulator operations.
8978 These builtins take two accumulator numbers as argument and return
8982 frv_expand_voidaccop_builtin (enum insn_code icode
, tree call
)
8985 rtx op0
= frv_read_argument (call
, 0);
8986 rtx op1
= frv_read_argument (call
, 1);
8990 op0
= frv_int_to_acc (icode
, 0, op0
);
8994 op1
= frv_int_to_acc (icode
, 1, op1
);
8998 op2
= frv_matching_accg_for_acc (op0
);
8999 op3
= frv_matching_accg_for_acc (op1
);
9000 pat
= GEN_FCN (icode
) (op0
, op1
, op2
, op3
);
9008 /* Expand a __builtin_read* function. ICODE is the instruction code for the
9009 membar and TARGET_MODE is the mode that the loaded value should have. */
9012 frv_expand_load_builtin (enum insn_code icode
, machine_mode target_mode
,
9013 tree call
, rtx target
)
9015 rtx op0
= frv_read_argument (call
, 0);
9016 rtx cookie
= frv_io_address_cookie (op0
);
9018 if (target
== 0 || !REG_P (target
))
9019 target
= gen_reg_rtx (target_mode
);
9020 op0
= frv_volatile_memref (insn_data
[icode
].operand
[0].mode
, op0
);
9021 convert_move (target
, op0
, 1);
9022 emit_insn (GEN_FCN (icode
) (copy_rtx (op0
), cookie
, GEN_INT (FRV_IO_READ
)));
9023 cfun
->machine
->has_membar_p
= 1;
9027 /* Likewise __builtin_write* functions. */
9030 frv_expand_store_builtin (enum insn_code icode
, tree call
)
9032 rtx op0
= frv_read_argument (call
, 0);
9033 rtx op1
= frv_read_argument (call
, 1);
9034 rtx cookie
= frv_io_address_cookie (op0
);
9036 op0
= frv_volatile_memref (insn_data
[icode
].operand
[0].mode
, op0
);
9037 convert_move (op0
, force_reg (insn_data
[icode
].operand
[0].mode
, op1
), 1);
9038 emit_insn (GEN_FCN (icode
) (copy_rtx (op0
), cookie
, GEN_INT (FRV_IO_WRITE
)));
9039 cfun
->machine
->has_membar_p
= 1;
9043 /* Expand the MDPACKH builtin. It takes four unsigned short arguments and
9044 each argument forms one word of the two double-word input registers.
9045 CALL is the tree for the call and TARGET, if nonnull, suggests a good place
9046 to put the return value. */
9049 frv_expand_mdpackh_builtin (tree call
, rtx target
)
9051 enum insn_code icode
= CODE_FOR_mdpackh
;
9053 rtx arg1
= frv_read_argument (call
, 0);
9054 rtx arg2
= frv_read_argument (call
, 1);
9055 rtx arg3
= frv_read_argument (call
, 2);
9056 rtx arg4
= frv_read_argument (call
, 3);
9058 target
= frv_legitimize_target (icode
, target
);
9059 op0
= gen_reg_rtx (DImode
);
9060 op1
= gen_reg_rtx (DImode
);
9062 /* The high half of each word is not explicitly initialized, so indicate
9063 that the input operands are not live before this point. */
9067 /* Move each argument into the low half of its associated input word. */
9068 emit_move_insn (simplify_gen_subreg (HImode
, op0
, DImode
, 2), arg1
);
9069 emit_move_insn (simplify_gen_subreg (HImode
, op0
, DImode
, 6), arg2
);
9070 emit_move_insn (simplify_gen_subreg (HImode
, op1
, DImode
, 2), arg3
);
9071 emit_move_insn (simplify_gen_subreg (HImode
, op1
, DImode
, 6), arg4
);
9073 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
9081 /* Expand the MCLRACC builtin. This builtin takes a single accumulator
9082 number as argument. */
9085 frv_expand_mclracc_builtin (tree call
)
9087 enum insn_code icode
= CODE_FOR_mclracc
;
9089 rtx op0
= frv_read_argument (call
, 0);
9091 op0
= frv_int_to_acc (icode
, 0, op0
);
9095 pat
= GEN_FCN (icode
) (op0
);
9102 /* Expand builtins that take no arguments. */
9105 frv_expand_noargs_builtin (enum insn_code icode
)
9107 rtx pat
= GEN_FCN (icode
) (const0_rtx
);
9114 /* Expand MRDACC and MRDACCG. These builtins take a single accumulator
9115 number or accumulator guard number as argument and return an SI integer. */
9118 frv_expand_mrdacc_builtin (enum insn_code icode
, tree call
)
9121 rtx target
= gen_reg_rtx (SImode
);
9122 rtx op0
= frv_read_argument (call
, 0);
9124 op0
= frv_int_to_acc (icode
, 1, op0
);
9128 pat
= GEN_FCN (icode
) (target
, op0
);
9136 /* Expand MWTACC and MWTACCG. These builtins take an accumulator or
9137 accumulator guard as their first argument and an SImode value as their
9141 frv_expand_mwtacc_builtin (enum insn_code icode
, tree call
)
9144 rtx op0
= frv_read_argument (call
, 0);
9145 rtx op1
= frv_read_argument (call
, 1);
9147 op0
= frv_int_to_acc (icode
, 0, op0
);
9151 op1
= frv_legitimize_argument (icode
, 1, op1
);
9152 pat
= GEN_FCN (icode
) (op0
, op1
);
9159 /* Emit a move from SRC to DEST in SImode chunks. This can be used
9160 to move DImode values into and out of IACC0. */
9163 frv_split_iacc_move (rtx dest
, rtx src
)
9168 inner
= GET_MODE (dest
);
9169 for (i
= 0; i
< GET_MODE_SIZE (inner
); i
+= GET_MODE_SIZE (SImode
))
9170 emit_move_insn (simplify_gen_subreg (SImode
, dest
, inner
, i
),
9171 simplify_gen_subreg (SImode
, src
, inner
, i
));
9174 /* Expand builtins. */
9177 frv_expand_builtin (tree exp
,
9179 rtx subtarget ATTRIBUTE_UNUSED
,
9180 machine_mode mode ATTRIBUTE_UNUSED
,
9181 int ignore ATTRIBUTE_UNUSED
)
9183 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
9184 unsigned fcode
= (unsigned)DECL_FUNCTION_CODE (fndecl
);
9186 struct builtin_description
*d
;
9188 if (fcode
< FRV_BUILTIN_FIRST_NONMEDIA
&& !TARGET_MEDIA
)
9190 error ("media functions are not available unless -mmedia is used");
9196 case FRV_BUILTIN_MCOP1
:
9197 case FRV_BUILTIN_MCOP2
:
9198 case FRV_BUILTIN_MDUNPACKH
:
9199 case FRV_BUILTIN_MBTOHE
:
9200 if (! TARGET_MEDIA_REV1
)
9202 error ("this media function is only available on the fr500");
9207 case FRV_BUILTIN_MQXMACHS
:
9208 case FRV_BUILTIN_MQXMACXHS
:
9209 case FRV_BUILTIN_MQMACXHS
:
9210 case FRV_BUILTIN_MADDACCS
:
9211 case FRV_BUILTIN_MSUBACCS
:
9212 case FRV_BUILTIN_MASACCS
:
9213 case FRV_BUILTIN_MDADDACCS
:
9214 case FRV_BUILTIN_MDSUBACCS
:
9215 case FRV_BUILTIN_MDASACCS
:
9216 case FRV_BUILTIN_MABSHS
:
9217 case FRV_BUILTIN_MDROTLI
:
9218 case FRV_BUILTIN_MCPLHI
:
9219 case FRV_BUILTIN_MCPLI
:
9220 case FRV_BUILTIN_MDCUTSSI
:
9221 case FRV_BUILTIN_MQSATHS
:
9222 case FRV_BUILTIN_MHSETLOS
:
9223 case FRV_BUILTIN_MHSETLOH
:
9224 case FRV_BUILTIN_MHSETHIS
:
9225 case FRV_BUILTIN_MHSETHIH
:
9226 case FRV_BUILTIN_MHDSETS
:
9227 case FRV_BUILTIN_MHDSETH
:
9228 if (! TARGET_MEDIA_REV2
)
9230 error ("this media function is only available on the fr400"
9236 case FRV_BUILTIN_SMASS
:
9237 case FRV_BUILTIN_SMSSS
:
9238 case FRV_BUILTIN_SMU
:
9239 case FRV_BUILTIN_ADDSS
:
9240 case FRV_BUILTIN_SUBSS
:
9241 case FRV_BUILTIN_SLASS
:
9242 case FRV_BUILTIN_SCUTSS
:
9243 case FRV_BUILTIN_IACCreadll
:
9244 case FRV_BUILTIN_IACCreadl
:
9245 case FRV_BUILTIN_IACCsetll
:
9246 case FRV_BUILTIN_IACCsetl
:
9247 if (!TARGET_FR405_BUILTINS
)
9249 error ("this builtin function is only available"
9250 " on the fr405 and fr450");
9255 case FRV_BUILTIN_PREFETCH
:
9256 if (!TARGET_FR500_FR550_BUILTINS
)
9258 error ("this builtin function is only available on the fr500"
9264 case FRV_BUILTIN_MQLCLRHS
:
9265 case FRV_BUILTIN_MQLMTHS
:
9266 case FRV_BUILTIN_MQSLLHI
:
9267 case FRV_BUILTIN_MQSRAHI
:
9268 if (!TARGET_MEDIA_FR450
)
9270 error ("this builtin function is only available on the fr450");
9279 /* Expand unique builtins. */
9283 case FRV_BUILTIN_MTRAP
:
9284 return frv_expand_noargs_builtin (CODE_FOR_mtrap
);
9286 case FRV_BUILTIN_MCLRACC
:
9287 return frv_expand_mclracc_builtin (exp
);
9289 case FRV_BUILTIN_MCLRACCA
:
9291 return frv_expand_noargs_builtin (CODE_FOR_mclracca8
);
9293 return frv_expand_noargs_builtin (CODE_FOR_mclracca4
);
9295 case FRV_BUILTIN_MRDACC
:
9296 return frv_expand_mrdacc_builtin (CODE_FOR_mrdacc
, exp
);
9298 case FRV_BUILTIN_MRDACCG
:
9299 return frv_expand_mrdacc_builtin (CODE_FOR_mrdaccg
, exp
);
9301 case FRV_BUILTIN_MWTACC
:
9302 return frv_expand_mwtacc_builtin (CODE_FOR_mwtacc
, exp
);
9304 case FRV_BUILTIN_MWTACCG
:
9305 return frv_expand_mwtacc_builtin (CODE_FOR_mwtaccg
, exp
);
9307 case FRV_BUILTIN_MDPACKH
:
9308 return frv_expand_mdpackh_builtin (exp
, target
);
9310 case FRV_BUILTIN_IACCreadll
:
9312 rtx src
= frv_read_iacc_argument (DImode
, exp
, 0);
9313 if (target
== 0 || !REG_P (target
))
9314 target
= gen_reg_rtx (DImode
);
9315 frv_split_iacc_move (target
, src
);
9319 case FRV_BUILTIN_IACCreadl
:
9320 return frv_read_iacc_argument (SImode
, exp
, 0);
9322 case FRV_BUILTIN_IACCsetll
:
9324 rtx dest
= frv_read_iacc_argument (DImode
, exp
, 0);
9325 rtx src
= frv_read_argument (exp
, 1);
9326 frv_split_iacc_move (dest
, force_reg (DImode
, src
));
9330 case FRV_BUILTIN_IACCsetl
:
9332 rtx dest
= frv_read_iacc_argument (SImode
, exp
, 0);
9333 rtx src
= frv_read_argument (exp
, 1);
9334 emit_move_insn (dest
, force_reg (SImode
, src
));
9342 /* Expand groups of builtins. */
9344 for (i
= 0, d
= bdesc_set
; i
< ARRAY_SIZE (bdesc_set
); i
++, d
++)
9345 if (d
->code
== fcode
)
9346 return frv_expand_set_builtin (d
->icode
, exp
, target
);
9348 for (i
= 0, d
= bdesc_1arg
; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
9349 if (d
->code
== fcode
)
9350 return frv_expand_unop_builtin (d
->icode
, exp
, target
);
9352 for (i
= 0, d
= bdesc_2arg
; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
9353 if (d
->code
== fcode
)
9354 return frv_expand_binop_builtin (d
->icode
, exp
, target
);
9356 for (i
= 0, d
= bdesc_cut
; i
< ARRAY_SIZE (bdesc_cut
); i
++, d
++)
9357 if (d
->code
== fcode
)
9358 return frv_expand_cut_builtin (d
->icode
, exp
, target
);
9360 for (i
= 0, d
= bdesc_2argimm
; i
< ARRAY_SIZE (bdesc_2argimm
); i
++, d
++)
9361 if (d
->code
== fcode
)
9362 return frv_expand_binopimm_builtin (d
->icode
, exp
, target
);
9364 for (i
= 0, d
= bdesc_void2arg
; i
< ARRAY_SIZE (bdesc_void2arg
); i
++, d
++)
9365 if (d
->code
== fcode
)
9366 return frv_expand_voidbinop_builtin (d
->icode
, exp
);
9368 for (i
= 0, d
= bdesc_void3arg
; i
< ARRAY_SIZE (bdesc_void3arg
); i
++, d
++)
9369 if (d
->code
== fcode
)
9370 return frv_expand_voidtriop_builtin (d
->icode
, exp
);
9372 for (i
= 0, d
= bdesc_voidacc
; i
< ARRAY_SIZE (bdesc_voidacc
); i
++, d
++)
9373 if (d
->code
== fcode
)
9374 return frv_expand_voidaccop_builtin (d
->icode
, exp
);
9376 for (i
= 0, d
= bdesc_int_void2arg
;
9377 i
< ARRAY_SIZE (bdesc_int_void2arg
); i
++, d
++)
9378 if (d
->code
== fcode
)
9379 return frv_expand_int_void2arg (d
->icode
, exp
);
9381 for (i
= 0, d
= bdesc_prefetches
;
9382 i
< ARRAY_SIZE (bdesc_prefetches
); i
++, d
++)
9383 if (d
->code
== fcode
)
9384 return frv_expand_prefetches (d
->icode
, exp
);
9386 for (i
= 0, d
= bdesc_loads
; i
< ARRAY_SIZE (bdesc_loads
); i
++, d
++)
9387 if (d
->code
== fcode
)
9388 return frv_expand_load_builtin (d
->icode
, TYPE_MODE (TREE_TYPE (exp
)),
9391 for (i
= 0, d
= bdesc_stores
; i
< ARRAY_SIZE (bdesc_stores
); i
++, d
++)
9392 if (d
->code
== fcode
)
9393 return frv_expand_store_builtin (d
->icode
, exp
);
9399 frv_in_small_data_p (const_tree decl
)
9402 const char *section_name
;
9404 /* Don't apply the -G flag to internal compiler structures. We
9405 should leave such structures in the main data section, partly
9406 for efficiency and partly because the size of some of them
9407 (such as C++ typeinfos) is not known until later. */
9408 if (TREE_CODE (decl
) != VAR_DECL
|| DECL_ARTIFICIAL (decl
))
9411 /* If we already know which section the decl should be in, see if
9412 it's a small data section. */
9413 section_name
= DECL_SECTION_NAME (decl
);
9416 if (frv_string_begins_with (section_name
, ".sdata"))
9418 if (frv_string_begins_with (section_name
, ".sbss"))
9423 size
= int_size_in_bytes (TREE_TYPE (decl
));
9424 if (size
> 0 && size
<= g_switch_value
)
9431 frv_rtx_costs (rtx x
,
9434 int opno ATTRIBUTE_UNUSED
,
9436 bool speed ATTRIBUTE_UNUSED
)
9438 int code
= GET_CODE (x
);
9440 if (outer_code
== MEM
)
9442 /* Don't differentiate between memory addresses. All the ones
9443 we accept have equal cost. */
9444 *total
= COSTS_N_INSNS (0);
9451 /* Make 12-bit integers really cheap. */
9452 if (IN_RANGE (INTVAL (x
), -2048, 2047))
9463 *total
= COSTS_N_INSNS (2);
9478 *total
= COSTS_N_INSNS (1);
9479 else if (mode
== DImode
)
9480 *total
= COSTS_N_INSNS (2);
9482 *total
= COSTS_N_INSNS (3);
9487 *total
= COSTS_N_INSNS (2);
9489 *total
= COSTS_N_INSNS (6); /* guess */
9496 *total
= COSTS_N_INSNS (18);
9500 *total
= COSTS_N_INSNS (3);
9509 frv_asm_out_constructor (rtx symbol
, int priority ATTRIBUTE_UNUSED
)
9511 switch_to_section (ctors_section
);
9512 assemble_align (POINTER_SIZE
);
9515 int ok
= frv_assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, 1);
9520 assemble_integer_with_op ("\t.picptr\t", symbol
);
9524 frv_asm_out_destructor (rtx symbol
, int priority ATTRIBUTE_UNUSED
)
9526 switch_to_section (dtors_section
);
9527 assemble_align (POINTER_SIZE
);
9530 int ok
= frv_assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, 1);
9535 assemble_integer_with_op ("\t.picptr\t", symbol
);
9538 /* Worker function for TARGET_STRUCT_VALUE_RTX. */
9541 frv_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED
,
9542 int incoming ATTRIBUTE_UNUSED
)
9544 return gen_rtx_REG (Pmode
, FRV_STRUCT_VALUE_REGNUM
);
9547 #define TLS_BIAS (2048 - 16)
9549 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
9550 We need to emit DTP-relative relocations. */
9553 frv_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
9555 gcc_assert (size
== 4);
9556 fputs ("\t.picptr\ttlsmoff(", file
);
9557 /* We want the unbiased TLS offset, so add the bias to the
9558 expression, such that the implicit biasing cancels out. */
9559 output_addr_const (file
, plus_constant (Pmode
, x
, TLS_BIAS
));