1 /* Copyright (C) 1997-2016 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"
30 #include "stringpool.h"
35 #include "diagnostic-core.h"
36 #include "fold-const.h"
38 #include "stor-layout.h"
40 #include "insn-attr.h"
44 #include "langhooks.h"
50 /* This file should be included last. */
51 #include "target-def.h"
54 #define FRV_INLINE inline
57 /* The maximum number of distinct NOP patterns. There are three:
58 nop, fnop and mnop. */
59 #define NUM_NOP_PATTERNS 3
61 /* Classification of instructions and units: integer, floating-point/media,
62 branch and control. */
63 enum frv_insn_group
{ GROUP_I
, GROUP_FM
, GROUP_B
, GROUP_C
, NUM_GROUPS
};
65 /* The DFA names of the units, in packet order. */
66 static const char *const frv_unit_names
[] =
76 /* The classification of each unit in frv_unit_names[]. */
77 static const enum frv_insn_group frv_unit_groups
[ARRAY_SIZE (frv_unit_names
)] =
87 /* Return the DFA unit code associated with the Nth unit of integer
88 or floating-point group GROUP, */
89 #define NTH_UNIT(GROUP, N) frv_unit_codes[(GROUP) + (N) * 2 + 1]
91 /* Return the number of integer or floating-point unit UNIT
92 (1 for I1, 2 for F2, etc.). */
93 #define UNIT_NUMBER(UNIT) (((UNIT) - 1) / 2)
95 /* The DFA unit number for each unit in frv_unit_names[]. */
96 static int frv_unit_codes
[ARRAY_SIZE (frv_unit_names
)];
98 /* FRV_TYPE_TO_UNIT[T] is the last unit in frv_unit_names[] that can issue
99 an instruction of type T. The value is ARRAY_SIZE (frv_unit_names) if
100 no instruction of type T has been seen. */
101 static unsigned int frv_type_to_unit
[TYPE_UNKNOWN
+ 1];
103 /* An array of dummy nop INSNs, one for each type of nop that the
105 static GTY(()) rtx_insn
*frv_nops
[NUM_NOP_PATTERNS
];
107 /* The number of nop instructions in frv_nops[]. */
108 static unsigned int frv_num_nops
;
110 /* The type of access. FRV_IO_UNKNOWN means the access can be either
111 a read or a write. */
112 enum frv_io_type
{ FRV_IO_UNKNOWN
, FRV_IO_READ
, FRV_IO_WRITE
};
114 /* Information about one __builtin_read or __builtin_write access, or
115 the combination of several such accesses. The most general value
116 is all-zeros (an unknown access to an unknown address). */
118 enum frv_io_type type
;
120 /* The constant address being accessed, or zero if not known. */
121 HOST_WIDE_INT const_address
;
123 /* The run-time address, as used in operand 0 of the membar pattern. */
127 /* Return true if instruction INSN should be packed with the following
129 #define PACKING_FLAG_P(INSN) (GET_MODE (INSN) == TImode)
131 /* Set the value of PACKING_FLAG_P(INSN). */
132 #define SET_PACKING_FLAG(INSN) PUT_MODE (INSN, TImode)
133 #define CLEAR_PACKING_FLAG(INSN) PUT_MODE (INSN, VOIDmode)
135 /* Loop with REG set to each hard register in rtx X. */
136 #define FOR_EACH_REGNO(REG, X) \
137 for (REG = REGNO (X); \
138 REG < REGNO (X) + HARD_REGNO_NREGS (REGNO (X), GET_MODE (X)); \
141 /* This structure contains machine specific function data. */
142 struct GTY(()) machine_function
144 /* True if we have created an rtx that relies on the stack frame. */
147 /* True if this function contains at least one __builtin_{read,write}*. */
151 /* Temporary register allocation support structure. */
152 typedef struct frv_tmp_reg_struct
154 HARD_REG_SET regs
; /* possible registers to allocate */
155 int next_reg
[N_REG_CLASSES
]; /* next register to allocate per class */
159 /* Register state information for VLIW re-packing phase. */
160 #define REGSTATE_CC_MASK 0x07 /* Mask to isolate CCn for cond exec */
161 #define REGSTATE_MODIFIED 0x08 /* reg modified in current VLIW insn */
162 #define REGSTATE_IF_TRUE 0x10 /* reg modified in cond exec true */
163 #define REGSTATE_IF_FALSE 0x20 /* reg modified in cond exec false */
165 #define REGSTATE_IF_EITHER (REGSTATE_IF_TRUE | REGSTATE_IF_FALSE)
167 typedef unsigned char regstate_t
;
169 /* Used in frv_frame_accessor_t to indicate the direction of a register-to-
177 /* Information required by frv_frame_access. */
180 /* This field is FRV_LOAD if registers are to be loaded from the stack and
181 FRV_STORE if they should be stored onto the stack. FRV_STORE implies
182 the move is being done by the prologue code while FRV_LOAD implies it
183 is being done by the epilogue. */
184 enum frv_stack_op op
;
186 /* The base register to use when accessing the stack. This may be the
187 frame pointer, stack pointer, or a temporary. The choice of register
188 depends on which part of the frame is being accessed and how big the
192 /* The offset of BASE from the bottom of the current frame, in bytes. */
194 } frv_frame_accessor_t
;
196 /* Conditional execution support gathered together in one structure. */
199 /* Linked list of insns to add if the conditional execution conversion was
200 successful. Each link points to an EXPR_LIST which points to the pattern
201 of the insn to add, and the insn to be inserted before. */
202 rtx added_insns_list
;
204 /* Identify which registers are safe to allocate for if conversions to
205 conditional execution. We keep the last allocated register in the
206 register classes between COND_EXEC statements. This will mean we allocate
207 different registers for each different COND_EXEC group if we can. This
208 might allow the scheduler to intermix two different COND_EXEC sections. */
209 frv_tmp_reg_t tmp_reg
;
211 /* For nested IFs, identify which CC registers are used outside of setting
212 via a compare isnsn, and using via a check insn. This will allow us to
213 know if we can rewrite the register to use a different register that will
214 be paired with the CR register controlling the nested IF-THEN blocks. */
215 HARD_REG_SET nested_cc_ok_rewrite
;
217 /* Temporary registers allocated to hold constants during conditional
219 rtx scratch_regs
[FIRST_PSEUDO_REGISTER
];
221 /* Current number of temp registers available. */
222 int cur_scratch_regs
;
224 /* Number of nested conditional execution blocks. */
225 int num_nested_cond_exec
;
227 /* Map of insns that set up constants in scratch registers. */
228 bitmap scratch_insns_bitmap
;
230 /* Conditional execution test register (CC0..CC7). */
233 /* Conditional execution compare register that is paired with cr_reg, so that
234 nested compares can be done. The csubcc and caddcc instructions don't
235 have enough bits to specify both a CC register to be set and a CR register
236 to do the test on, so the same bit number is used for both. Needless to
237 say, this is rather inconvenient for GCC. */
240 /* Extra CR registers used for &&, ||. */
244 /* Previous CR used in nested if, to make sure we are dealing with the same
245 nested if as the previous statement. */
246 rtx last_nested_if_cr
;
250 static /* GTY(()) */ frv_ifcvt_t frv_ifcvt
;
252 /* Map register number to smallest register class. */
253 enum reg_class regno_reg_class
[FIRST_PSEUDO_REGISTER
];
255 /* Cached value of frv_stack_info. */
256 static frv_stack_t
*frv_stack_cache
= (frv_stack_t
*)0;
258 /* Forward references */
260 static void frv_option_override (void);
261 static bool frv_legitimate_address_p (machine_mode
, rtx
, bool);
262 static int frv_default_flags_for_cpu (void);
263 static int frv_string_begins_with (const char *, const char *);
264 static FRV_INLINE
bool frv_small_data_reloc_p (rtx
, int);
265 static void frv_print_operand (FILE *, rtx
, int);
266 static void frv_print_operand_address (FILE *, machine_mode
, rtx
);
267 static bool frv_print_operand_punct_valid_p (unsigned char code
);
268 static void frv_print_operand_memory_reference_reg
270 static void frv_print_operand_memory_reference (FILE *, rtx
, int);
271 static int frv_print_operand_jump_hint (rtx_insn
*);
272 static const char *comparison_string (enum rtx_code
, rtx
);
273 static rtx
frv_function_value (const_tree
, const_tree
,
275 static rtx
frv_libcall_value (machine_mode
,
277 static FRV_INLINE
int frv_regno_ok_for_base_p (int, int);
278 static rtx
single_set_pattern (rtx
);
279 static int frv_function_contains_far_jump (void);
280 static rtx
frv_alloc_temp_reg (frv_tmp_reg_t
*,
284 static rtx
frv_frame_offset_rtx (int);
285 static rtx
frv_frame_mem (machine_mode
, rtx
, int);
286 static rtx
frv_dwarf_store (rtx
, int);
287 static void frv_frame_insn (rtx
, rtx
);
288 static void frv_frame_access (frv_frame_accessor_t
*,
290 static void frv_frame_access_multi (frv_frame_accessor_t
*,
292 static void frv_frame_access_standard_regs (enum frv_stack_op
,
294 static struct machine_function
*frv_init_machine_status (void);
295 static rtx
frv_int_to_acc (enum insn_code
, int, rtx
);
296 static machine_mode
frv_matching_accg_mode (machine_mode
);
297 static rtx
frv_read_argument (tree
, unsigned int);
298 static rtx
frv_read_iacc_argument (machine_mode
, tree
, unsigned int);
299 static int frv_check_constant_argument (enum insn_code
, int, rtx
);
300 static rtx
frv_legitimize_target (enum insn_code
, rtx
);
301 static rtx
frv_legitimize_argument (enum insn_code
, int, rtx
);
302 static rtx
frv_legitimize_tls_address (rtx
, enum tls_model
);
303 static rtx
frv_legitimize_address (rtx
, rtx
, machine_mode
);
304 static rtx
frv_expand_set_builtin (enum insn_code
, tree
, rtx
);
305 static rtx
frv_expand_unop_builtin (enum insn_code
, tree
, rtx
);
306 static rtx
frv_expand_binop_builtin (enum insn_code
, tree
, rtx
);
307 static rtx
frv_expand_cut_builtin (enum insn_code
, tree
, rtx
);
308 static rtx
frv_expand_binopimm_builtin (enum insn_code
, tree
, rtx
);
309 static rtx
frv_expand_voidbinop_builtin (enum insn_code
, tree
);
310 static rtx
frv_expand_int_void2arg (enum insn_code
, tree
);
311 static rtx
frv_expand_prefetches (enum insn_code
, tree
);
312 static rtx
frv_expand_voidtriop_builtin (enum insn_code
, tree
);
313 static rtx
frv_expand_voidaccop_builtin (enum insn_code
, tree
);
314 static rtx
frv_expand_mclracc_builtin (tree
);
315 static rtx
frv_expand_mrdacc_builtin (enum insn_code
, tree
);
316 static rtx
frv_expand_mwtacc_builtin (enum insn_code
, tree
);
317 static rtx
frv_expand_noargs_builtin (enum insn_code
);
318 static void frv_split_iacc_move (rtx
, rtx
);
319 static rtx
frv_emit_comparison (enum rtx_code
, rtx
, rtx
);
320 static void frv_ifcvt_add_insn (rtx
, rtx
, int);
321 static rtx
frv_ifcvt_rewrite_mem (rtx
, machine_mode
, rtx
);
322 static rtx
frv_ifcvt_load_value (rtx
, rtx
);
323 static unsigned int frv_insn_unit (rtx_insn
*);
324 static bool frv_issues_to_branch_unit_p (rtx_insn
*);
325 static int frv_cond_flags (rtx
);
326 static bool frv_regstate_conflict_p (regstate_t
, regstate_t
);
327 static bool frv_registers_conflict_p (rtx
);
328 static void frv_registers_update_1 (rtx
, const_rtx
, void *);
329 static void frv_registers_update (rtx
);
330 static void frv_start_packet (void);
331 static void frv_start_packet_block (void);
332 static void frv_finish_packet (void (*) (void));
333 static bool frv_pack_insn_p (rtx_insn
*);
334 static void frv_add_insn_to_packet (rtx_insn
*);
335 static void frv_insert_nop_in_packet (rtx_insn
*);
336 static bool frv_for_each_packet (void (*) (void));
337 static bool frv_sort_insn_group_1 (enum frv_insn_group
,
338 unsigned int, unsigned int,
339 unsigned int, unsigned int,
341 static int frv_compare_insns (const void *, const void *);
342 static void frv_sort_insn_group (enum frv_insn_group
);
343 static void frv_reorder_packet (void);
344 static void frv_fill_unused_units (enum frv_insn_group
);
345 static void frv_align_label (void);
346 static void frv_reorg_packet (void);
347 static void frv_register_nop (rtx
);
348 static void frv_reorg (void);
349 static void frv_pack_insns (void);
350 static void frv_function_prologue (FILE *, HOST_WIDE_INT
);
351 static void frv_function_epilogue (FILE *, HOST_WIDE_INT
);
352 static bool frv_assemble_integer (rtx
, unsigned, int);
353 static void frv_init_builtins (void);
354 static rtx
frv_expand_builtin (tree
, rtx
, rtx
, machine_mode
, int);
355 static void frv_init_libfuncs (void);
356 static bool frv_in_small_data_p (const_tree
);
357 static void frv_asm_output_mi_thunk
358 (FILE *, tree
, HOST_WIDE_INT
, HOST_WIDE_INT
, tree
);
359 static void frv_setup_incoming_varargs (cumulative_args_t
,
362 static rtx
frv_expand_builtin_saveregs (void);
363 static void frv_expand_builtin_va_start (tree
, rtx
);
364 static bool frv_rtx_costs (rtx
, machine_mode
, int, int,
366 static int frv_register_move_cost (machine_mode
,
367 reg_class_t
, reg_class_t
);
368 static int frv_memory_move_cost (machine_mode
,
370 static void frv_asm_out_constructor (rtx
, int);
371 static void frv_asm_out_destructor (rtx
, int);
372 static bool frv_function_symbol_referenced_p (rtx
);
373 static bool frv_legitimate_constant_p (machine_mode
, rtx
);
374 static bool frv_cannot_force_const_mem (machine_mode
, rtx
);
375 static const char *unspec_got_name (int);
376 static void frv_output_const_unspec (FILE *,
377 const struct frv_unspec
*);
378 static bool frv_function_ok_for_sibcall (tree
, tree
);
379 static rtx
frv_struct_value_rtx (tree
, int);
380 static bool frv_must_pass_in_stack (machine_mode mode
, const_tree type
);
381 static int frv_arg_partial_bytes (cumulative_args_t
, machine_mode
,
383 static rtx
frv_function_arg (cumulative_args_t
, machine_mode
,
385 static rtx
frv_function_incoming_arg (cumulative_args_t
, machine_mode
,
387 static void frv_function_arg_advance (cumulative_args_t
, machine_mode
,
389 static unsigned int frv_function_arg_boundary (machine_mode
,
391 static void frv_output_dwarf_dtprel (FILE *, int, rtx
)
393 static reg_class_t
frv_secondary_reload (bool, rtx
, reg_class_t
,
395 secondary_reload_info
*);
396 static bool frv_frame_pointer_required (void);
397 static bool frv_can_eliminate (const int, const int);
398 static void frv_conditional_register_usage (void);
399 static void frv_trampoline_init (rtx
, tree
, rtx
);
400 static bool frv_class_likely_spilled_p (reg_class_t
);
402 /* Initialize the GCC target structure. */
403 #undef TARGET_PRINT_OPERAND
404 #define TARGET_PRINT_OPERAND frv_print_operand
405 #undef TARGET_PRINT_OPERAND_ADDRESS
406 #define TARGET_PRINT_OPERAND_ADDRESS frv_print_operand_address
407 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
408 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P frv_print_operand_punct_valid_p
409 #undef TARGET_ASM_FUNCTION_PROLOGUE
410 #define TARGET_ASM_FUNCTION_PROLOGUE frv_function_prologue
411 #undef TARGET_ASM_FUNCTION_EPILOGUE
412 #define TARGET_ASM_FUNCTION_EPILOGUE frv_function_epilogue
413 #undef TARGET_ASM_INTEGER
414 #define TARGET_ASM_INTEGER frv_assemble_integer
415 #undef TARGET_OPTION_OVERRIDE
416 #define TARGET_OPTION_OVERRIDE frv_option_override
417 #undef TARGET_INIT_BUILTINS
418 #define TARGET_INIT_BUILTINS frv_init_builtins
419 #undef TARGET_EXPAND_BUILTIN
420 #define TARGET_EXPAND_BUILTIN frv_expand_builtin
421 #undef TARGET_INIT_LIBFUNCS
422 #define TARGET_INIT_LIBFUNCS frv_init_libfuncs
423 #undef TARGET_IN_SMALL_DATA_P
424 #define TARGET_IN_SMALL_DATA_P frv_in_small_data_p
425 #undef TARGET_REGISTER_MOVE_COST
426 #define TARGET_REGISTER_MOVE_COST frv_register_move_cost
427 #undef TARGET_MEMORY_MOVE_COST
428 #define TARGET_MEMORY_MOVE_COST frv_memory_move_cost
429 #undef TARGET_RTX_COSTS
430 #define TARGET_RTX_COSTS frv_rtx_costs
431 #undef TARGET_ASM_CONSTRUCTOR
432 #define TARGET_ASM_CONSTRUCTOR frv_asm_out_constructor
433 #undef TARGET_ASM_DESTRUCTOR
434 #define TARGET_ASM_DESTRUCTOR frv_asm_out_destructor
436 #undef TARGET_ASM_OUTPUT_MI_THUNK
437 #define TARGET_ASM_OUTPUT_MI_THUNK frv_asm_output_mi_thunk
438 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
439 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
441 #undef TARGET_SCHED_ISSUE_RATE
442 #define TARGET_SCHED_ISSUE_RATE frv_issue_rate
444 #undef TARGET_LEGITIMIZE_ADDRESS
445 #define TARGET_LEGITIMIZE_ADDRESS frv_legitimize_address
447 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
448 #define TARGET_FUNCTION_OK_FOR_SIBCALL frv_function_ok_for_sibcall
449 #undef TARGET_LEGITIMATE_CONSTANT_P
450 #define TARGET_LEGITIMATE_CONSTANT_P frv_legitimate_constant_p
451 #undef TARGET_CANNOT_FORCE_CONST_MEM
452 #define TARGET_CANNOT_FORCE_CONST_MEM frv_cannot_force_const_mem
454 #undef TARGET_HAVE_TLS
455 #define TARGET_HAVE_TLS HAVE_AS_TLS
457 #undef TARGET_STRUCT_VALUE_RTX
458 #define TARGET_STRUCT_VALUE_RTX frv_struct_value_rtx
459 #undef TARGET_MUST_PASS_IN_STACK
460 #define TARGET_MUST_PASS_IN_STACK frv_must_pass_in_stack
461 #undef TARGET_PASS_BY_REFERENCE
462 #define TARGET_PASS_BY_REFERENCE hook_pass_by_reference_must_pass_in_stack
463 #undef TARGET_ARG_PARTIAL_BYTES
464 #define TARGET_ARG_PARTIAL_BYTES frv_arg_partial_bytes
465 #undef TARGET_FUNCTION_ARG
466 #define TARGET_FUNCTION_ARG frv_function_arg
467 #undef TARGET_FUNCTION_INCOMING_ARG
468 #define TARGET_FUNCTION_INCOMING_ARG frv_function_incoming_arg
469 #undef TARGET_FUNCTION_ARG_ADVANCE
470 #define TARGET_FUNCTION_ARG_ADVANCE frv_function_arg_advance
471 #undef TARGET_FUNCTION_ARG_BOUNDARY
472 #define TARGET_FUNCTION_ARG_BOUNDARY frv_function_arg_boundary
474 #undef TARGET_EXPAND_BUILTIN_SAVEREGS
475 #define TARGET_EXPAND_BUILTIN_SAVEREGS frv_expand_builtin_saveregs
476 #undef TARGET_SETUP_INCOMING_VARARGS
477 #define TARGET_SETUP_INCOMING_VARARGS frv_setup_incoming_varargs
478 #undef TARGET_MACHINE_DEPENDENT_REORG
479 #define TARGET_MACHINE_DEPENDENT_REORG frv_reorg
481 #undef TARGET_EXPAND_BUILTIN_VA_START
482 #define TARGET_EXPAND_BUILTIN_VA_START frv_expand_builtin_va_start
485 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
486 #define TARGET_ASM_OUTPUT_DWARF_DTPREL frv_output_dwarf_dtprel
489 #undef TARGET_CLASS_LIKELY_SPILLED_P
490 #define TARGET_CLASS_LIKELY_SPILLED_P frv_class_likely_spilled_p
492 #undef TARGET_SECONDARY_RELOAD
493 #define TARGET_SECONDARY_RELOAD frv_secondary_reload
496 #define TARGET_LRA_P hook_bool_void_false
498 #undef TARGET_LEGITIMATE_ADDRESS_P
499 #define TARGET_LEGITIMATE_ADDRESS_P frv_legitimate_address_p
501 #undef TARGET_FRAME_POINTER_REQUIRED
502 #define TARGET_FRAME_POINTER_REQUIRED frv_frame_pointer_required
504 #undef TARGET_CAN_ELIMINATE
505 #define TARGET_CAN_ELIMINATE frv_can_eliminate
507 #undef TARGET_CONDITIONAL_REGISTER_USAGE
508 #define TARGET_CONDITIONAL_REGISTER_USAGE frv_conditional_register_usage
510 #undef TARGET_TRAMPOLINE_INIT
511 #define TARGET_TRAMPOLINE_INIT frv_trampoline_init
513 #undef TARGET_FUNCTION_VALUE
514 #define TARGET_FUNCTION_VALUE frv_function_value
515 #undef TARGET_LIBCALL_VALUE
516 #define TARGET_LIBCALL_VALUE frv_libcall_value
518 struct gcc_target targetm
= TARGET_INITIALIZER
;
520 #define FRV_SYMBOL_REF_TLS_P(RTX) \
521 (GET_CODE (RTX) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (RTX) != 0)
524 /* Any function call that satisfies the machine-independent
525 requirements is eligible on FR-V. */
528 frv_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED
,
529 tree exp ATTRIBUTE_UNUSED
)
534 /* Return true if SYMBOL is a small data symbol and relocation RELOC
535 can be used to access it directly in a load or store. */
537 static FRV_INLINE
bool
538 frv_small_data_reloc_p (rtx symbol
, int reloc
)
540 return (GET_CODE (symbol
) == SYMBOL_REF
541 && SYMBOL_REF_SMALL_P (symbol
)
542 && (!TARGET_FDPIC
|| flag_pic
== 1)
543 && (reloc
== R_FRV_GOTOFF12
|| reloc
== R_FRV_GPREL12
));
546 /* Return true if X is a valid relocation unspec. If it is, fill in UNSPEC
550 frv_const_unspec_p (rtx x
, struct frv_unspec
*unspec
)
552 if (GET_CODE (x
) == CONST
)
556 if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == CONST_INT
)
558 unspec
->offset
+= INTVAL (XEXP (x
, 1));
561 if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_GOT
)
563 unspec
->symbol
= XVECEXP (x
, 0, 0);
564 unspec
->reloc
= INTVAL (XVECEXP (x
, 0, 1));
566 if (unspec
->offset
== 0)
569 if (frv_small_data_reloc_p (unspec
->symbol
, unspec
->reloc
)
570 && unspec
->offset
> 0
571 && unspec
->offset
< g_switch_value
)
578 /* Decide whether we can force certain constants to memory. If we
579 decide we can't, the caller should be able to cope with it in
582 We never allow constants to be forced into memory for TARGET_FDPIC.
583 This is necessary for several reasons:
585 1. Since frv_legitimate_constant_p rejects constant pool addresses, the
586 target-independent code will try to force them into the constant
587 pool, thus leading to infinite recursion.
589 2. We can never introduce new constant pool references during reload.
590 Any such reference would require use of the pseudo FDPIC register.
592 3. We can't represent a constant added to a function pointer (which is
593 not the same as a pointer to a function+constant).
595 4. In many cases, it's more efficient to calculate the constant in-line. */
598 frv_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED
,
599 rtx x ATTRIBUTE_UNUSED
)
605 frv_default_flags_for_cpu (void)
607 switch (frv_cpu_type
)
609 case FRV_CPU_GENERIC
:
610 return MASK_DEFAULT_FRV
;
613 return MASK_DEFAULT_FR550
;
617 return MASK_DEFAULT_FR500
;
620 return MASK_DEFAULT_FR450
;
624 return MASK_DEFAULT_FR400
;
628 return MASK_DEFAULT_SIMPLE
;
635 /* Implement TARGET_OPTION_OVERRIDE. */
638 frv_option_override (void)
643 target_flags
|= (frv_default_flags_for_cpu () & ~target_flags_explicit
);
645 /* -mlibrary-pic sets -fPIC and -G0 and also suppresses warnings from the
646 linker about linking pic and non-pic code. */
649 if (!flag_pic
) /* -fPIC */
652 if (!global_options_set
.x_g_switch_value
) /* -G0 */
658 /* A C expression whose value is a register class containing hard
659 register REGNO. In general there is more than one such class;
660 choose a class which is "minimal", meaning that no smaller class
661 also contains the register. */
663 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
665 enum reg_class rclass
;
669 int gpr_reg
= regno
- GPR_FIRST
;
671 if (gpr_reg
== GR8_REG
)
674 else if (gpr_reg
== GR9_REG
)
677 else if (gpr_reg
== GR14_REG
)
678 rclass
= FDPIC_FPTR_REGS
;
680 else if (gpr_reg
== FDPIC_REGNO
)
683 else if ((gpr_reg
& 3) == 0)
686 else if ((gpr_reg
& 1) == 0)
693 else if (FPR_P (regno
))
695 int fpr_reg
= regno
- GPR_FIRST
;
696 if ((fpr_reg
& 3) == 0)
697 rclass
= QUAD_FPR_REGS
;
699 else if ((fpr_reg
& 1) == 0)
706 else if (regno
== LR_REGNO
)
709 else if (regno
== LCR_REGNO
)
712 else if (ICC_P (regno
))
715 else if (FCC_P (regno
))
718 else if (ICR_P (regno
))
721 else if (FCR_P (regno
))
724 else if (ACC_P (regno
))
726 int r
= regno
- ACC_FIRST
;
728 rclass
= QUAD_ACC_REGS
;
729 else if ((r
& 1) == 0)
730 rclass
= EVEN_ACC_REGS
;
735 else if (ACCG_P (regno
))
741 regno_reg_class
[regno
] = rclass
;
744 /* Check for small data option */
745 if (!global_options_set
.x_g_switch_value
&& !TARGET_LIBPIC
)
746 g_switch_value
= SDATA_DEFAULT_SIZE
;
748 /* There is no single unaligned SI op for PIC code. Sometimes we
749 need to use ".4byte" and sometimes we need to use ".picptr".
750 See frv_assemble_integer for details. */
751 if (flag_pic
|| TARGET_FDPIC
)
752 targetm
.asm_out
.unaligned_op
.si
= 0;
754 if ((target_flags_explicit
& MASK_LINKED_FP
) == 0)
755 target_flags
|= MASK_LINKED_FP
;
757 if ((target_flags_explicit
& MASK_OPTIMIZE_MEMBAR
) == 0)
758 target_flags
|= MASK_OPTIMIZE_MEMBAR
;
760 for (i
= 0; i
< ARRAY_SIZE (frv_unit_names
); i
++)
761 frv_unit_codes
[i
] = get_cpu_unit_code (frv_unit_names
[i
]);
763 for (i
= 0; i
< ARRAY_SIZE (frv_type_to_unit
); i
++)
764 frv_type_to_unit
[i
] = ARRAY_SIZE (frv_unit_codes
);
766 init_machine_status
= frv_init_machine_status
;
770 /* Return true if NAME (a STRING_CST node) begins with PREFIX. */
773 frv_string_begins_with (const char *name
, const char *prefix
)
775 const int prefix_len
= strlen (prefix
);
777 /* Remember: NAME's length includes the null terminator. */
778 return (strncmp (name
, prefix
, prefix_len
) == 0);
781 /* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */
784 frv_conditional_register_usage (void)
788 for (i
= GPR_FIRST
+ NUM_GPRS
; i
<= GPR_LAST
; i
++)
789 fixed_regs
[i
] = call_used_regs
[i
] = 1;
791 for (i
= FPR_FIRST
+ NUM_FPRS
; i
<= FPR_LAST
; i
++)
792 fixed_regs
[i
] = call_used_regs
[i
] = 1;
794 /* Reserve the registers used for conditional execution. At present, we need
795 1 ICC and 1 ICR register. */
796 fixed_regs
[ICC_TEMP
] = call_used_regs
[ICC_TEMP
] = 1;
797 fixed_regs
[ICR_TEMP
] = call_used_regs
[ICR_TEMP
] = 1;
801 fixed_regs
[ICC_FIRST
] = call_used_regs
[ICC_FIRST
] = 1;
802 fixed_regs
[FCC_FIRST
] = call_used_regs
[FCC_FIRST
] = 1;
803 fixed_regs
[ICR_FIRST
] = call_used_regs
[ICR_FIRST
] = 1;
804 fixed_regs
[FCR_FIRST
] = call_used_regs
[FCR_FIRST
] = 1;
808 fixed_regs
[GPR_FIRST
+ 16] = fixed_regs
[GPR_FIRST
+ 17] =
809 call_used_regs
[GPR_FIRST
+ 16] = call_used_regs
[GPR_FIRST
+ 17] = 0;
812 /* If -fpic, SDA_BASE_REG is the PIC register. */
813 if (g_switch_value
== 0 && !flag_pic
)
814 fixed_regs
[SDA_BASE_REG
] = call_used_regs
[SDA_BASE_REG
] = 0;
817 fixed_regs
[PIC_REGNO
] = call_used_regs
[PIC_REGNO
] = 0;
823 * Compute the stack frame layout
826 * +---------------+-----------------------+-----------------------+
827 * |Register |type |caller-save/callee-save|
828 * +---------------+-----------------------+-----------------------+
829 * |GR0 |Zero register | - |
830 * |GR1 |Stack pointer(SP) | - |
831 * |GR2 |Frame pointer(FP) | - |
832 * |GR3 |Hidden parameter | caller save |
833 * |GR4-GR7 | - | caller save |
834 * |GR8-GR13 |Argument register | caller save |
835 * |GR14-GR15 | - | caller save |
836 * |GR16-GR31 | - | callee save |
837 * |GR32-GR47 | - | caller save |
838 * |GR48-GR63 | - | callee save |
839 * |FR0-FR15 | - | caller save |
840 * |FR16-FR31 | - | callee save |
841 * |FR32-FR47 | - | caller save |
842 * |FR48-FR63 | - | callee save |
843 * +---------------+-----------------------+-----------------------+
847 * SP-> |-----------------------------------|
849 * |-----------------------------------|
850 * | Register save area |
851 * |-----------------------------------|
852 * | Local variable save area |
853 * FP-> |-----------------------------------|
855 * |-----------------------------------|
856 * | Hidden parameter save area |
857 * |-----------------------------------|
858 * | Return address(LR) storage area |
859 * |-----------------------------------|
860 * | Padding for alignment |
861 * |-----------------------------------|
862 * | Register argument area |
863 * OLD SP-> |-----------------------------------|
865 * |-----------------------------------|
868 * Argument area/Parameter area:
870 * When a function is called, this area is used for argument transfer. When
871 * the argument is set up by the caller function, this area is referred to as
872 * the argument area. When the argument is referenced by the callee function,
873 * this area is referred to as the parameter area. The area is allocated when
874 * all arguments cannot be placed on the argument register at the time of
877 * Register save area:
879 * This is a register save area that must be guaranteed for the caller
880 * function. This area is not secured when the register save operation is not
883 * Local variable save area:
885 * This is the area for local variables and temporary variables.
889 * This area stores the FP value of the caller function.
891 * Hidden parameter save area:
893 * This area stores the start address of the return value storage
894 * area for a struct/union return function.
895 * When a struct/union is used as the return value, the caller
896 * function stores the return value storage area start address in
897 * register GR3 and passes it to the caller function.
898 * The callee function interprets the address stored in the GR3
899 * as the return value storage area start address.
900 * When register GR3 needs to be saved into memory, the callee
901 * function saves it in the hidden parameter save area. This
902 * area is not secured when the save operation is not needed.
904 * Return address(LR) storage area:
906 * This area saves the LR. The LR stores the address of a return to the caller
907 * function for the purpose of function calling.
909 * Argument register area:
911 * This area saves the argument register. This area is not secured when the
912 * save operation is not needed.
916 * Arguments, the count of which equals the count of argument registers (6
917 * words), are positioned in registers GR8 to GR13 and delivered to the callee
918 * function. When a struct/union return function is called, the return value
919 * area address is stored in register GR3. Arguments not placed in the
920 * argument registers will be stored in the stack argument area for transfer
921 * purposes. When an 8-byte type argument is to be delivered using registers,
922 * it is divided into two and placed in two registers for transfer. When
923 * argument registers must be saved to memory, the callee function secures an
924 * argument register save area in the stack. In this case, a continuous
925 * argument register save area must be established in the parameter area. The
926 * argument register save area must be allocated as needed to cover the size of
927 * the argument register to be saved. If the function has a variable count of
928 * arguments, it saves all argument registers in the argument register save
931 * Argument Extension Format:
933 * When an argument is to be stored in the stack, its type is converted to an
934 * extended type in accordance with the individual argument type. The argument
935 * is freed by the caller function after the return from the callee function is
938 * +-----------------------+---------------+------------------------+
939 * | Argument Type |Extended Type |Stack Storage Size(byte)|
940 * +-----------------------+---------------+------------------------+
942 * |signed char |int | 4 |
943 * |unsigned char |int | 4 |
944 * |[signed] short int |int | 4 |
945 * |unsigned short int |int | 4 |
946 * |[signed] int |No extension | 4 |
947 * |unsigned int |No extension | 4 |
948 * |[signed] long int |No extension | 4 |
949 * |unsigned long int |No extension | 4 |
950 * |[signed] long long int |No extension | 8 |
951 * |unsigned long long int |No extension | 8 |
952 * |float |double | 8 |
953 * |double |No extension | 8 |
954 * |long double |No extension | 8 |
955 * |pointer |No extension | 4 |
956 * |struct/union |- | 4 (*1) |
957 * +-----------------------+---------------+------------------------+
959 * When a struct/union is to be delivered as an argument, the caller copies it
960 * to the local variable area and delivers the address of that area.
964 * +-------------------------------+----------------------+
965 * |Return Value Type |Return Value Interface|
966 * +-------------------------------+----------------------+
968 * |[signed|unsigned] char |GR8 |
969 * |[signed|unsigned] short int |GR8 |
970 * |[signed|unsigned] int |GR8 |
971 * |[signed|unsigned] long int |GR8 |
973 * |[signed|unsigned] long long int|GR8 & GR9 |
975 * |double |GR8 & GR9 |
976 * |long double |GR8 & GR9 |
977 * |struct/union |(*1) |
978 * +-------------------------------+----------------------+
980 * When a struct/union is used as the return value, the caller function stores
981 * the start address of the return value storage area into GR3 and then passes
982 * it to the callee function. The callee function interprets GR3 as the start
983 * address of the return value storage area. When this address needs to be
984 * saved in memory, the callee function secures the hidden parameter save area
985 * and saves the address in that area.
989 frv_stack_info (void)
991 static frv_stack_t info
, zero_info
;
992 frv_stack_t
*info_ptr
= &info
;
993 tree fndecl
= current_function_decl
;
1001 /* If we've already calculated the values and reload is complete,
1003 if (frv_stack_cache
)
1004 return frv_stack_cache
;
1006 /* Zero all fields. */
1009 /* Set up the register range information. */
1010 info_ptr
->regs
[STACK_REGS_GPR
].name
= "gpr";
1011 info_ptr
->regs
[STACK_REGS_GPR
].first
= LAST_ARG_REGNUM
+ 1;
1012 info_ptr
->regs
[STACK_REGS_GPR
].last
= GPR_LAST
;
1013 info_ptr
->regs
[STACK_REGS_GPR
].dword_p
= TRUE
;
1015 info_ptr
->regs
[STACK_REGS_FPR
].name
= "fpr";
1016 info_ptr
->regs
[STACK_REGS_FPR
].first
= FPR_FIRST
;
1017 info_ptr
->regs
[STACK_REGS_FPR
].last
= FPR_LAST
;
1018 info_ptr
->regs
[STACK_REGS_FPR
].dword_p
= TRUE
;
1020 info_ptr
->regs
[STACK_REGS_LR
].name
= "lr";
1021 info_ptr
->regs
[STACK_REGS_LR
].first
= LR_REGNO
;
1022 info_ptr
->regs
[STACK_REGS_LR
].last
= LR_REGNO
;
1023 info_ptr
->regs
[STACK_REGS_LR
].special_p
= 1;
1025 info_ptr
->regs
[STACK_REGS_CC
].name
= "cc";
1026 info_ptr
->regs
[STACK_REGS_CC
].first
= CC_FIRST
;
1027 info_ptr
->regs
[STACK_REGS_CC
].last
= CC_LAST
;
1028 info_ptr
->regs
[STACK_REGS_CC
].field_p
= TRUE
;
1030 info_ptr
->regs
[STACK_REGS_LCR
].name
= "lcr";
1031 info_ptr
->regs
[STACK_REGS_LCR
].first
= LCR_REGNO
;
1032 info_ptr
->regs
[STACK_REGS_LCR
].last
= LCR_REGNO
;
1034 info_ptr
->regs
[STACK_REGS_STDARG
].name
= "stdarg";
1035 info_ptr
->regs
[STACK_REGS_STDARG
].first
= FIRST_ARG_REGNUM
;
1036 info_ptr
->regs
[STACK_REGS_STDARG
].last
= LAST_ARG_REGNUM
;
1037 info_ptr
->regs
[STACK_REGS_STDARG
].dword_p
= 1;
1038 info_ptr
->regs
[STACK_REGS_STDARG
].special_p
= 1;
1040 info_ptr
->regs
[STACK_REGS_STRUCT
].name
= "struct";
1041 info_ptr
->regs
[STACK_REGS_STRUCT
].first
= FRV_STRUCT_VALUE_REGNUM
;
1042 info_ptr
->regs
[STACK_REGS_STRUCT
].last
= FRV_STRUCT_VALUE_REGNUM
;
1043 info_ptr
->regs
[STACK_REGS_STRUCT
].special_p
= 1;
1045 info_ptr
->regs
[STACK_REGS_FP
].name
= "fp";
1046 info_ptr
->regs
[STACK_REGS_FP
].first
= FRAME_POINTER_REGNUM
;
1047 info_ptr
->regs
[STACK_REGS_FP
].last
= FRAME_POINTER_REGNUM
;
1048 info_ptr
->regs
[STACK_REGS_FP
].special_p
= 1;
1050 /* Determine if this is a stdarg function. If so, allocate space to store
1057 /* Find the last argument, and see if it is __builtin_va_alist. */
1058 for (cur_arg
= DECL_ARGUMENTS (fndecl
); cur_arg
!= (tree
)0; cur_arg
= next_arg
)
1060 next_arg
= DECL_CHAIN (cur_arg
);
1061 if (next_arg
== (tree
)0)
1063 if (DECL_NAME (cur_arg
)
1064 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg
)), "__builtin_va_alist"))
1072 /* Iterate over all of the register ranges. */
1073 for (range
= 0; range
< STACK_REGS_MAX
; range
++)
1075 frv_stack_regs_t
*reg_ptr
= &(info_ptr
->regs
[range
]);
1076 int first
= reg_ptr
->first
;
1077 int last
= reg_ptr
->last
;
1079 int size_2words
= 0;
1082 /* Calculate which registers need to be saved & save area size. */
1086 for (regno
= first
; regno
<= last
; regno
++)
1088 if ((df_regs_ever_live_p (regno
) && !call_used_regs
[regno
])
1089 || (crtl
->calls_eh_return
1090 && (regno
>= FIRST_EH_REGNUM
&& regno
<= LAST_EH_REGNUM
))
1091 || (!TARGET_FDPIC
&& flag_pic
1092 && crtl
->uses_pic_offset_table
&& regno
== PIC_REGNO
))
1094 info_ptr
->save_p
[regno
] = REG_SAVE_1WORD
;
1095 size_1word
+= UNITS_PER_WORD
;
1100 /* Calculate whether we need to create a frame after everything else
1101 has been processed. */
1106 if (df_regs_ever_live_p (LR_REGNO
)
1108 /* This is set for __builtin_return_address, etc. */
1109 || cfun
->machine
->frame_needed
1110 || (TARGET_LINKED_FP
&& frame_pointer_needed
)
1111 || (!TARGET_FDPIC
&& flag_pic
1112 && crtl
->uses_pic_offset_table
))
1114 info_ptr
->save_p
[LR_REGNO
] = REG_SAVE_1WORD
;
1115 size_1word
+= UNITS_PER_WORD
;
1119 case STACK_REGS_STDARG
:
1122 /* If this is a stdarg function with a non varardic
1123 argument split between registers and the stack,
1124 adjust the saved registers downward. */
1125 last
-= (ADDR_ALIGN (crtl
->args
.pretend_args_size
, UNITS_PER_WORD
)
1128 for (regno
= first
; regno
<= last
; regno
++)
1130 info_ptr
->save_p
[regno
] = REG_SAVE_1WORD
;
1131 size_1word
+= UNITS_PER_WORD
;
1134 info_ptr
->stdarg_size
= size_1word
;
1138 case STACK_REGS_STRUCT
:
1139 if (cfun
->returns_struct
)
1141 info_ptr
->save_p
[FRV_STRUCT_VALUE_REGNUM
] = REG_SAVE_1WORD
;
1142 size_1word
+= UNITS_PER_WORD
;
1150 /* If this is a field, it only takes one word. */
1151 if (reg_ptr
->field_p
)
1152 size_1word
= UNITS_PER_WORD
;
1154 /* Determine which register pairs can be saved together. */
1155 else if (reg_ptr
->dword_p
&& TARGET_DWORD
)
1157 for (regno
= first
; regno
< last
; regno
+= 2)
1159 if (info_ptr
->save_p
[regno
] && info_ptr
->save_p
[regno
+1])
1161 size_2words
+= 2 * UNITS_PER_WORD
;
1162 size_1word
-= 2 * UNITS_PER_WORD
;
1163 info_ptr
->save_p
[regno
] = REG_SAVE_2WORDS
;
1164 info_ptr
->save_p
[regno
+1] = REG_SAVE_NO_SAVE
;
1169 reg_ptr
->size_1word
= size_1word
;
1170 reg_ptr
->size_2words
= size_2words
;
1172 if (! reg_ptr
->special_p
)
1174 info_ptr
->regs_size_1word
+= size_1word
;
1175 info_ptr
->regs_size_2words
+= size_2words
;
1180 /* Set up the sizes of each field in the frame body, making the sizes
1181 of each be divisible by the size of a dword if dword operations might
1182 be used, or the size of a word otherwise. */
1183 alignment
= (TARGET_DWORD
? 2 * UNITS_PER_WORD
: UNITS_PER_WORD
);
1185 info_ptr
->parameter_size
= ADDR_ALIGN (crtl
->outgoing_args_size
, alignment
);
1186 info_ptr
->regs_size
= ADDR_ALIGN (info_ptr
->regs_size_2words
1187 + info_ptr
->regs_size_1word
,
1189 info_ptr
->vars_size
= ADDR_ALIGN (get_frame_size (), alignment
);
1191 info_ptr
->pretend_size
= crtl
->args
.pretend_args_size
;
1193 /* Work out the size of the frame, excluding the header. Both the frame
1194 body and register parameter area will be dword-aligned. */
1195 info_ptr
->total_size
1196 = (ADDR_ALIGN (info_ptr
->parameter_size
1197 + info_ptr
->regs_size
1198 + info_ptr
->vars_size
,
1200 + ADDR_ALIGN (info_ptr
->pretend_size
1201 + info_ptr
->stdarg_size
,
1202 2 * UNITS_PER_WORD
));
1204 /* See if we need to create a frame at all, if so add header area. */
1205 if (info_ptr
->total_size
> 0
1206 || frame_pointer_needed
1207 || info_ptr
->regs
[STACK_REGS_LR
].size_1word
> 0
1208 || info_ptr
->regs
[STACK_REGS_STRUCT
].size_1word
> 0)
1210 offset
= info_ptr
->parameter_size
;
1211 info_ptr
->header_size
= 4 * UNITS_PER_WORD
;
1212 info_ptr
->total_size
+= 4 * UNITS_PER_WORD
;
1214 /* Calculate the offsets to save normal register pairs. */
1215 for (range
= 0; range
< STACK_REGS_MAX
; range
++)
1217 frv_stack_regs_t
*reg_ptr
= &(info_ptr
->regs
[range
]);
1218 if (! reg_ptr
->special_p
)
1220 int first
= reg_ptr
->first
;
1221 int last
= reg_ptr
->last
;
1224 for (regno
= first
; regno
<= last
; regno
++)
1225 if (info_ptr
->save_p
[regno
] == REG_SAVE_2WORDS
1226 && regno
!= FRAME_POINTER_REGNUM
1227 && (regno
< FIRST_ARG_REGNUM
1228 || regno
> LAST_ARG_REGNUM
))
1230 info_ptr
->reg_offset
[regno
] = offset
;
1231 offset
+= 2 * UNITS_PER_WORD
;
1236 /* Calculate the offsets to save normal single registers. */
1237 for (range
= 0; range
< STACK_REGS_MAX
; range
++)
1239 frv_stack_regs_t
*reg_ptr
= &(info_ptr
->regs
[range
]);
1240 if (! reg_ptr
->special_p
)
1242 int first
= reg_ptr
->first
;
1243 int last
= reg_ptr
->last
;
1246 for (regno
= first
; regno
<= last
; regno
++)
1247 if (info_ptr
->save_p
[regno
] == REG_SAVE_1WORD
1248 && regno
!= FRAME_POINTER_REGNUM
1249 && (regno
< FIRST_ARG_REGNUM
1250 || regno
> LAST_ARG_REGNUM
))
1252 info_ptr
->reg_offset
[regno
] = offset
;
1253 offset
+= UNITS_PER_WORD
;
1258 /* Calculate the offset to save the local variables at. */
1259 offset
= ADDR_ALIGN (offset
, alignment
);
1260 if (info_ptr
->vars_size
)
1262 info_ptr
->vars_offset
= offset
;
1263 offset
+= info_ptr
->vars_size
;
1266 /* Align header to a dword-boundary. */
1267 offset
= ADDR_ALIGN (offset
, 2 * UNITS_PER_WORD
);
1269 /* Calculate the offsets in the fixed frame. */
1270 info_ptr
->save_p
[FRAME_POINTER_REGNUM
] = REG_SAVE_1WORD
;
1271 info_ptr
->reg_offset
[FRAME_POINTER_REGNUM
] = offset
;
1272 info_ptr
->regs
[STACK_REGS_FP
].size_1word
= UNITS_PER_WORD
;
1274 info_ptr
->save_p
[LR_REGNO
] = REG_SAVE_1WORD
;
1275 info_ptr
->reg_offset
[LR_REGNO
] = offset
+ 2*UNITS_PER_WORD
;
1276 info_ptr
->regs
[STACK_REGS_LR
].size_1word
= UNITS_PER_WORD
;
1278 if (cfun
->returns_struct
)
1280 info_ptr
->save_p
[FRV_STRUCT_VALUE_REGNUM
] = REG_SAVE_1WORD
;
1281 info_ptr
->reg_offset
[FRV_STRUCT_VALUE_REGNUM
] = offset
+ UNITS_PER_WORD
;
1282 info_ptr
->regs
[STACK_REGS_STRUCT
].size_1word
= UNITS_PER_WORD
;
1285 /* Calculate the offsets to store the arguments passed in registers
1286 for stdarg functions. The register pairs are first and the single
1287 register if any is last. The register save area starts on a
1289 if (info_ptr
->stdarg_size
)
1291 int first
= info_ptr
->regs
[STACK_REGS_STDARG
].first
;
1292 int last
= info_ptr
->regs
[STACK_REGS_STDARG
].last
;
1295 /* Skip the header. */
1296 offset
+= 4 * UNITS_PER_WORD
;
1297 for (regno
= first
; regno
<= last
; regno
++)
1299 if (info_ptr
->save_p
[regno
] == REG_SAVE_2WORDS
)
1301 info_ptr
->reg_offset
[regno
] = offset
;
1302 offset
+= 2 * UNITS_PER_WORD
;
1304 else if (info_ptr
->save_p
[regno
] == REG_SAVE_1WORD
)
1306 info_ptr
->reg_offset
[regno
] = offset
;
1307 offset
+= UNITS_PER_WORD
;
1313 if (reload_completed
)
1314 frv_stack_cache
= info_ptr
;
1320 /* Print the information about the frv stack offsets, etc. when debugging. */
1323 frv_debug_stack (frv_stack_t
*info
)
1328 info
= frv_stack_info ();
1330 fprintf (stderr
, "\nStack information for function %s:\n",
1331 ((current_function_decl
&& DECL_NAME (current_function_decl
))
1332 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl
))
1335 fprintf (stderr
, "\ttotal_size\t= %6d\n", info
->total_size
);
1336 fprintf (stderr
, "\tvars_size\t= %6d\n", info
->vars_size
);
1337 fprintf (stderr
, "\tparam_size\t= %6d\n", info
->parameter_size
);
1338 fprintf (stderr
, "\tregs_size\t= %6d, 1w = %3d, 2w = %3d\n",
1339 info
->regs_size
, info
->regs_size_1word
, info
->regs_size_2words
);
1341 fprintf (stderr
, "\theader_size\t= %6d\n", info
->header_size
);
1342 fprintf (stderr
, "\tpretend_size\t= %6d\n", info
->pretend_size
);
1343 fprintf (stderr
, "\tvars_offset\t= %6d\n", info
->vars_offset
);
1344 fprintf (stderr
, "\tregs_offset\t= %6d\n", info
->regs_offset
);
1346 for (range
= 0; range
< STACK_REGS_MAX
; range
++)
1348 frv_stack_regs_t
*regs
= &(info
->regs
[range
]);
1349 if ((regs
->size_1word
+ regs
->size_2words
) > 0)
1351 int first
= regs
->first
;
1352 int last
= regs
->last
;
1355 fprintf (stderr
, "\t%s\tsize\t= %6d, 1w = %3d, 2w = %3d, save =",
1356 regs
->name
, regs
->size_1word
+ regs
->size_2words
,
1357 regs
->size_1word
, regs
->size_2words
);
1359 for (regno
= first
; regno
<= last
; regno
++)
1361 if (info
->save_p
[regno
] == REG_SAVE_1WORD
)
1362 fprintf (stderr
, " %s (%d)", reg_names
[regno
],
1363 info
->reg_offset
[regno
]);
1365 else if (info
->save_p
[regno
] == REG_SAVE_2WORDS
)
1366 fprintf (stderr
, " %s-%s (%d)", reg_names
[regno
],
1367 reg_names
[regno
+1], info
->reg_offset
[regno
]);
1370 fputc ('\n', stderr
);
1380 /* Used during final to control the packing of insns. The value is
1381 1 if the current instruction should be packed with the next one,
1382 0 if it shouldn't or -1 if packing is disabled altogether. */
1384 static int frv_insn_packing_flag
;
1386 /* True if the current function contains a far jump. */
1389 frv_function_contains_far_jump (void)
1391 rtx_insn
*insn
= get_insns ();
1394 && get_attr_far_jump (insn
) == FAR_JUMP_YES
))
1395 insn
= NEXT_INSN (insn
);
1396 return (insn
!= NULL
);
1399 /* For the FRV, this function makes sure that a function with far jumps
1400 will return correctly. It also does the VLIW packing. */
1403 frv_function_prologue (FILE *file
, HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
1405 rtx_insn
*insn
, *next
, *last_call
;
1407 /* If no frame was created, check whether the function uses a call
1408 instruction to implement a far jump. If so, save the link in gr3 and
1409 replace all returns to LR with returns to GR3. GR3 is used because it
1410 is call-clobbered, because is not available to the register allocator,
1411 and because all functions that take a hidden argument pointer will have
1413 if (frv_stack_info ()->total_size
== 0 && frv_function_contains_far_jump ())
1417 /* Just to check that the above comment is true. */
1418 gcc_assert (!df_regs_ever_live_p (GPR_FIRST
+ 3));
1420 /* Generate the instruction that saves the link register. */
1421 fprintf (file
, "\tmovsg lr,gr3\n");
1423 /* Replace the LR with GR3 in *return_internal patterns. The insn
1424 will now return using jmpl @(gr3,0) rather than bralr. We cannot
1425 simply emit a different assembly directive because bralr and jmpl
1426 execute in different units. */
1427 for (insn
= get_insns(); insn
!= NULL
; insn
= NEXT_INSN (insn
))
1430 rtx pattern
= PATTERN (insn
);
1431 if (GET_CODE (pattern
) == PARALLEL
1432 && XVECLEN (pattern
, 0) >= 2
1433 && GET_CODE (XVECEXP (pattern
, 0, 0)) == RETURN
1434 && GET_CODE (XVECEXP (pattern
, 0, 1)) == USE
)
1436 rtx address
= XEXP (XVECEXP (pattern
, 0, 1), 0);
1437 if (GET_CODE (address
) == REG
&& REGNO (address
) == LR_REGNO
)
1438 SET_REGNO (address
, GPR_FIRST
+ 3);
1445 /* Allow the garbage collector to free the nops created by frv_reorg. */
1446 memset (frv_nops
, 0, sizeof (frv_nops
));
1448 /* Locate CALL_ARG_LOCATION notes that have been misplaced
1449 and move them back to where they should be located. */
1451 for (insn
= get_insns (); insn
; insn
= next
)
1453 next
= NEXT_INSN (insn
);
1455 || (INSN_P (insn
) && GET_CODE (PATTERN (insn
)) == SEQUENCE
1456 && CALL_P (XVECEXP (PATTERN (insn
), 0, 0))))
1459 if (!NOTE_P (insn
) || NOTE_KIND (insn
) != NOTE_INSN_CALL_ARG_LOCATION
)
1462 if (NEXT_INSN (last_call
) == insn
)
1465 SET_NEXT_INSN (PREV_INSN (insn
)) = NEXT_INSN (insn
);
1466 SET_PREV_INSN (NEXT_INSN (insn
)) = PREV_INSN (insn
);
1467 SET_PREV_INSN (insn
) = last_call
;
1468 SET_NEXT_INSN (insn
) = NEXT_INSN (last_call
);
1469 SET_PREV_INSN (NEXT_INSN (insn
)) = insn
;
1470 SET_NEXT_INSN (PREV_INSN (insn
)) = insn
;
1476 /* Return the next available temporary register in a given class. */
1479 frv_alloc_temp_reg (
1480 frv_tmp_reg_t
*info
, /* which registers are available */
1481 enum reg_class rclass
, /* register class desired */
1482 machine_mode mode
, /* mode to allocate register with */
1483 int mark_as_used
, /* register not available after allocation */
1484 int no_abort
) /* return NULL instead of aborting */
1486 int regno
= info
->next_reg
[ (int)rclass
];
1487 int orig_regno
= regno
;
1488 HARD_REG_SET
*reg_in_class
= ®_class_contents
[ (int)rclass
];
1493 if (TEST_HARD_REG_BIT (*reg_in_class
, regno
)
1494 && TEST_HARD_REG_BIT (info
->regs
, regno
))
1497 if (++regno
>= FIRST_PSEUDO_REGISTER
)
1499 if (regno
== orig_regno
)
1501 gcc_assert (no_abort
);
1506 nr
= HARD_REGNO_NREGS (regno
, mode
);
1507 info
->next_reg
[ (int)rclass
] = regno
+ nr
;
1510 for (i
= 0; i
< nr
; i
++)
1511 CLEAR_HARD_REG_BIT (info
->regs
, regno
+i
);
1513 return gen_rtx_REG (mode
, regno
);
1517 /* Return an rtx with the value OFFSET, which will either be a register or a
1518 signed 12-bit integer. It can be used as the second operand in an "add"
1519 instruction, or as the index in a load or store.
1521 The function returns a constant rtx if OFFSET is small enough, otherwise
1522 it loads the constant into register OFFSET_REGNO and returns that. */
1524 frv_frame_offset_rtx (int offset
)
1526 rtx offset_rtx
= GEN_INT (offset
);
1527 if (IN_RANGE (offset
, -2048, 2047))
1531 rtx reg_rtx
= gen_rtx_REG (SImode
, OFFSET_REGNO
);
1532 if (IN_RANGE (offset
, -32768, 32767))
1533 emit_insn (gen_movsi (reg_rtx
, offset_rtx
));
1536 emit_insn (gen_movsi_high (reg_rtx
, offset_rtx
));
1537 emit_insn (gen_movsi_lo_sum (reg_rtx
, offset_rtx
));
1543 /* Generate (mem:MODE (plus:Pmode BASE (frv_frame_offset OFFSET)))). The
1544 prologue and epilogue uses such expressions to access the stack. */
1546 frv_frame_mem (machine_mode mode
, rtx base
, int offset
)
1548 return gen_rtx_MEM (mode
, gen_rtx_PLUS (Pmode
,
1550 frv_frame_offset_rtx (offset
)));
1553 /* Generate a frame-related expression:
1555 (set REG (mem (plus (sp) (const_int OFFSET)))).
1557 Such expressions are used in FRAME_RELATED_EXPR notes for more complex
1558 instructions. Marking the expressions as frame-related is superfluous if
1559 the note contains just a single set. But if the note contains a PARALLEL
1560 or SEQUENCE that has several sets, each set must be individually marked
1561 as frame-related. */
1563 frv_dwarf_store (rtx reg
, int offset
)
1565 rtx set
= gen_rtx_SET (gen_rtx_MEM (GET_MODE (reg
),
1566 plus_constant (Pmode
, stack_pointer_rtx
,
1569 RTX_FRAME_RELATED_P (set
) = 1;
1573 /* Emit a frame-related instruction whose pattern is PATTERN. The
1574 instruction is the last in a sequence that cumulatively performs the
1575 operation described by DWARF_PATTERN. The instruction is marked as
1576 frame-related and has a REG_FRAME_RELATED_EXPR note containing
1579 frv_frame_insn (rtx pattern
, rtx dwarf_pattern
)
1581 rtx insn
= emit_insn (pattern
);
1582 RTX_FRAME_RELATED_P (insn
) = 1;
1583 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
1588 /* Emit instructions that transfer REG to or from the memory location (sp +
1589 STACK_OFFSET). The register is stored in memory if ACCESSOR->OP is
1590 FRV_STORE and loaded if it is FRV_LOAD. Only the prologue uses this
1591 function to store registers and only the epilogue uses it to load them.
1593 The caller sets up ACCESSOR so that BASE is equal to (sp + BASE_OFFSET).
1594 The generated instruction will use BASE as its base register. BASE may
1595 simply be the stack pointer, but if several accesses are being made to a
1596 region far away from the stack pointer, it may be more efficient to set
1597 up a temporary instead.
1599 Store instructions will be frame-related and will be annotated with the
1600 overall effect of the store. Load instructions will be followed by a
1601 (use) to prevent later optimizations from zapping them.
1603 The function takes care of the moves to and from SPRs, using TEMP_REGNO
1604 as a temporary in such cases. */
1606 frv_frame_access (frv_frame_accessor_t
*accessor
, rtx reg
, int stack_offset
)
1608 machine_mode mode
= GET_MODE (reg
);
1609 rtx mem
= frv_frame_mem (mode
,
1611 stack_offset
- accessor
->base_offset
);
1613 if (accessor
->op
== FRV_LOAD
)
1615 if (SPR_P (REGNO (reg
)))
1617 rtx temp
= gen_rtx_REG (mode
, TEMP_REGNO
);
1618 emit_insn (gen_rtx_SET (temp
, mem
));
1619 emit_insn (gen_rtx_SET (reg
, temp
));
1623 /* We cannot use reg+reg addressing for DImode access. */
1625 && GET_CODE (XEXP (mem
, 0)) == PLUS
1626 && GET_CODE (XEXP (XEXP (mem
, 0), 0)) == REG
1627 && GET_CODE (XEXP (XEXP (mem
, 0), 1)) == REG
)
1629 rtx temp
= gen_rtx_REG (SImode
, TEMP_REGNO
);
1631 emit_move_insn (temp
,
1632 gen_rtx_PLUS (SImode
, XEXP (XEXP (mem
, 0), 0),
1633 XEXP (XEXP (mem
, 0), 1)));
1634 mem
= gen_rtx_MEM (DImode
, temp
);
1636 emit_insn (gen_rtx_SET (reg
, mem
));
1642 if (SPR_P (REGNO (reg
)))
1644 rtx temp
= gen_rtx_REG (mode
, TEMP_REGNO
);
1645 emit_insn (gen_rtx_SET (temp
, reg
));
1646 frv_frame_insn (gen_rtx_SET (mem
, temp
),
1647 frv_dwarf_store (reg
, stack_offset
));
1649 else if (mode
== DImode
)
1651 /* For DImode saves, the dwarf2 version needs to be a SEQUENCE
1652 with a separate save for each register. */
1653 rtx reg1
= gen_rtx_REG (SImode
, REGNO (reg
));
1654 rtx reg2
= gen_rtx_REG (SImode
, REGNO (reg
) + 1);
1655 rtx set1
= frv_dwarf_store (reg1
, stack_offset
);
1656 rtx set2
= frv_dwarf_store (reg2
, stack_offset
+ 4);
1658 /* Also we cannot use reg+reg addressing. */
1659 if (GET_CODE (XEXP (mem
, 0)) == PLUS
1660 && GET_CODE (XEXP (XEXP (mem
, 0), 0)) == REG
1661 && GET_CODE (XEXP (XEXP (mem
, 0), 1)) == REG
)
1663 rtx temp
= gen_rtx_REG (SImode
, TEMP_REGNO
);
1664 emit_move_insn (temp
,
1665 gen_rtx_PLUS (SImode
, XEXP (XEXP (mem
, 0), 0),
1666 XEXP (XEXP (mem
, 0), 1)));
1667 mem
= gen_rtx_MEM (DImode
, temp
);
1670 frv_frame_insn (gen_rtx_SET (mem
, reg
),
1671 gen_rtx_PARALLEL (VOIDmode
,
1672 gen_rtvec (2, set1
, set2
)));
1675 frv_frame_insn (gen_rtx_SET (mem
, reg
),
1676 frv_dwarf_store (reg
, stack_offset
));
1680 /* A function that uses frv_frame_access to transfer a group of registers to
1681 or from the stack. ACCESSOR is passed directly to frv_frame_access, INFO
1682 is the stack information generated by frv_stack_info, and REG_SET is the
1683 number of the register set to transfer. */
1685 frv_frame_access_multi (frv_frame_accessor_t
*accessor
,
1689 frv_stack_regs_t
*regs_info
;
1692 regs_info
= &info
->regs
[reg_set
];
1693 for (regno
= regs_info
->first
; regno
<= regs_info
->last
; regno
++)
1694 if (info
->save_p
[regno
])
1695 frv_frame_access (accessor
,
1696 info
->save_p
[regno
] == REG_SAVE_2WORDS
1697 ? gen_rtx_REG (DImode
, regno
)
1698 : gen_rtx_REG (SImode
, regno
),
1699 info
->reg_offset
[regno
]);
1702 /* Save or restore callee-saved registers that are kept outside the frame
1703 header. The function saves the registers if OP is FRV_STORE and restores
1704 them if OP is FRV_LOAD. INFO is the stack information generated by
1707 frv_frame_access_standard_regs (enum frv_stack_op op
, frv_stack_t
*info
)
1709 frv_frame_accessor_t accessor
;
1712 accessor
.base
= stack_pointer_rtx
;
1713 accessor
.base_offset
= 0;
1714 frv_frame_access_multi (&accessor
, info
, STACK_REGS_GPR
);
1715 frv_frame_access_multi (&accessor
, info
, STACK_REGS_FPR
);
1716 frv_frame_access_multi (&accessor
, info
, STACK_REGS_LCR
);
1720 /* Called after register allocation to add any instructions needed for the
1721 prologue. Using a prologue insn is favored compared to putting all of the
1722 instructions in the TARGET_ASM_FUNCTION_PROLOGUE target hook, since
1723 it allows the scheduler to intermix instructions with the saves of
1724 the caller saved registers. In some cases, it might be necessary
1725 to emit a barrier instruction as the last insn to prevent such
1728 Also any insns generated here should have RTX_FRAME_RELATED_P(insn) = 1
1729 so that the debug info generation code can handle them properly. */
1731 frv_expand_prologue (void)
1733 frv_stack_t
*info
= frv_stack_info ();
1734 rtx sp
= stack_pointer_rtx
;
1735 rtx fp
= frame_pointer_rtx
;
1736 frv_frame_accessor_t accessor
;
1738 if (TARGET_DEBUG_STACK
)
1739 frv_debug_stack (info
);
1741 if (flag_stack_usage_info
)
1742 current_function_static_stack_size
= info
->total_size
;
1744 if (info
->total_size
== 0)
1747 /* We're interested in three areas of the frame here:
1749 A: the register save area
1751 C: the header after B
1753 If the frame pointer isn't used, we'll have to set up A, B and C
1754 using the stack pointer. If the frame pointer is used, we'll access
1758 B: set up using sp or a temporary (see below)
1761 We set up B using the stack pointer if the frame is small enough.
1762 Otherwise, it's more efficient to copy the old stack pointer into a
1763 temporary and use that.
1765 Note that it's important to make sure the prologue and epilogue use the
1766 same registers to access A and C, since doing otherwise will confuse
1767 the aliasing code. */
1769 /* Set up ACCESSOR for accessing region B above. If the frame pointer
1770 isn't used, the same method will serve for C. */
1771 accessor
.op
= FRV_STORE
;
1772 if (frame_pointer_needed
&& info
->total_size
> 2048)
1774 accessor
.base
= gen_rtx_REG (Pmode
, OLD_SP_REGNO
);
1775 accessor
.base_offset
= info
->total_size
;
1776 emit_insn (gen_movsi (accessor
.base
, sp
));
1780 accessor
.base
= stack_pointer_rtx
;
1781 accessor
.base_offset
= 0;
1784 /* Allocate the stack space. */
1786 rtx asm_offset
= frv_frame_offset_rtx (-info
->total_size
);
1787 rtx dwarf_offset
= GEN_INT (-info
->total_size
);
1789 frv_frame_insn (gen_stack_adjust (sp
, sp
, asm_offset
),
1790 gen_rtx_SET (sp
, gen_rtx_PLUS (Pmode
, sp
, dwarf_offset
)));
1793 /* If the frame pointer is needed, store the old one at (sp + FP_OFFSET)
1794 and point the new one to that location. */
1795 if (frame_pointer_needed
)
1797 int fp_offset
= info
->reg_offset
[FRAME_POINTER_REGNUM
];
1799 /* ASM_SRC and DWARF_SRC both point to the frame header. ASM_SRC is
1800 based on ACCESSOR.BASE but DWARF_SRC is always based on the stack
1802 rtx asm_src
= plus_constant (Pmode
, accessor
.base
,
1803 fp_offset
- accessor
.base_offset
);
1804 rtx dwarf_src
= plus_constant (Pmode
, sp
, fp_offset
);
1806 /* Store the old frame pointer at (sp + FP_OFFSET). */
1807 frv_frame_access (&accessor
, fp
, fp_offset
);
1809 /* Set up the new frame pointer. */
1810 frv_frame_insn (gen_rtx_SET (fp
, asm_src
),
1811 gen_rtx_SET (fp
, dwarf_src
));
1813 /* Access region C from the frame pointer. */
1815 accessor
.base_offset
= fp_offset
;
1818 /* Set up region C. */
1819 frv_frame_access_multi (&accessor
, info
, STACK_REGS_STRUCT
);
1820 frv_frame_access_multi (&accessor
, info
, STACK_REGS_LR
);
1821 frv_frame_access_multi (&accessor
, info
, STACK_REGS_STDARG
);
1823 /* Set up region A. */
1824 frv_frame_access_standard_regs (FRV_STORE
, info
);
1826 /* If this is a varargs/stdarg function, issue a blockage to prevent the
1827 scheduler from moving loads before the stores saving the registers. */
1828 if (info
->stdarg_size
> 0)
1829 emit_insn (gen_blockage ());
1831 /* Set up pic register/small data register for this function. */
1832 if (!TARGET_FDPIC
&& flag_pic
&& crtl
->uses_pic_offset_table
)
1833 emit_insn (gen_pic_prologue (gen_rtx_REG (Pmode
, PIC_REGNO
),
1834 gen_rtx_REG (Pmode
, LR_REGNO
),
1835 gen_rtx_REG (SImode
, OFFSET_REGNO
)));
1839 /* Under frv, all of the work is done via frv_expand_epilogue, but
1840 this function provides a convenient place to do cleanup. */
1843 frv_function_epilogue (FILE *file ATTRIBUTE_UNUSED
,
1844 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
1846 frv_stack_cache
= (frv_stack_t
*)0;
1848 /* Zap last used registers for conditional execution. */
1849 memset (&frv_ifcvt
.tmp_reg
, 0, sizeof (frv_ifcvt
.tmp_reg
));
1851 /* Release the bitmap of created insns. */
1852 BITMAP_FREE (frv_ifcvt
.scratch_insns_bitmap
);
1856 /* Called after register allocation to add any instructions needed for the
1857 epilogue. Using an epilogue insn is favored compared to putting all of the
1858 instructions in the TARGET_ASM_FUNCTION_PROLOGUE target hook, since
1859 it allows the scheduler to intermix instructions with the saves of
1860 the caller saved registers. In some cases, it might be necessary
1861 to emit a barrier instruction as the last insn to prevent such
1865 frv_expand_epilogue (bool emit_return
)
1867 frv_stack_t
*info
= frv_stack_info ();
1868 rtx fp
= frame_pointer_rtx
;
1869 rtx sp
= stack_pointer_rtx
;
1873 fp_offset
= info
->reg_offset
[FRAME_POINTER_REGNUM
];
1875 /* Restore the stack pointer to its original value if alloca or the like
1877 if (! crtl
->sp_is_unchanging
)
1878 emit_insn (gen_addsi3 (sp
, fp
, frv_frame_offset_rtx (-fp_offset
)));
1880 /* Restore the callee-saved registers that were used in this function. */
1881 frv_frame_access_standard_regs (FRV_LOAD
, info
);
1883 /* Set RETURN_ADDR to the address we should return to. Set it to NULL if
1884 no return instruction should be emitted. */
1885 if (info
->save_p
[LR_REGNO
])
1890 /* Use the same method to access the link register's slot as we did in
1891 the prologue. In other words, use the frame pointer if available,
1892 otherwise use the stack pointer.
1894 LR_OFFSET is the offset of the link register's slot from the start
1895 of the frame and MEM is a memory rtx for it. */
1896 lr_offset
= info
->reg_offset
[LR_REGNO
];
1897 if (frame_pointer_needed
)
1898 mem
= frv_frame_mem (Pmode
, fp
, lr_offset
- fp_offset
);
1900 mem
= frv_frame_mem (Pmode
, sp
, lr_offset
);
1902 /* Load the old link register into a GPR. */
1903 return_addr
= gen_rtx_REG (Pmode
, TEMP_REGNO
);
1904 emit_insn (gen_rtx_SET (return_addr
, mem
));
1907 return_addr
= gen_rtx_REG (Pmode
, LR_REGNO
);
1909 /* Restore the old frame pointer. Emit a USE afterwards to make sure
1910 the load is preserved. */
1911 if (frame_pointer_needed
)
1913 emit_insn (gen_rtx_SET (fp
, gen_rtx_MEM (Pmode
, fp
)));
1917 /* Deallocate the stack frame. */
1918 if (info
->total_size
!= 0)
1920 rtx offset
= frv_frame_offset_rtx (info
->total_size
);
1921 emit_insn (gen_stack_adjust (sp
, sp
, offset
));
1924 /* If this function uses eh_return, add the final stack adjustment now. */
1925 if (crtl
->calls_eh_return
)
1926 emit_insn (gen_stack_adjust (sp
, sp
, EH_RETURN_STACKADJ_RTX
));
1929 emit_jump_insn (gen_epilogue_return (return_addr
));
1932 rtx lr
= return_addr
;
1934 if (REGNO (return_addr
) != LR_REGNO
)
1936 lr
= gen_rtx_REG (Pmode
, LR_REGNO
);
1937 emit_move_insn (lr
, return_addr
);
1945 /* Worker function for TARGET_ASM_OUTPUT_MI_THUNK. */
1948 frv_asm_output_mi_thunk (FILE *file
,
1949 tree thunk_fndecl ATTRIBUTE_UNUSED
,
1950 HOST_WIDE_INT delta
,
1951 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED
,
1954 const char *name_func
= XSTR (XEXP (DECL_RTL (function
), 0), 0);
1955 const char *name_arg0
= reg_names
[FIRST_ARG_REGNUM
];
1956 const char *name_jmp
= reg_names
[JUMP_REGNO
];
1957 const char *parallel
= (frv_issue_rate () > 1 ? ".p" : "");
1959 /* Do the add using an addi if possible. */
1960 if (IN_RANGE (delta
, -2048, 2047))
1961 fprintf (file
, "\taddi %s,#%d,%s\n", name_arg0
, (int) delta
, name_arg0
);
1964 const char *const name_add
= reg_names
[TEMP_REGNO
];
1965 fprintf (file
, "\tsethi%s #hi(" HOST_WIDE_INT_PRINT_DEC
"),%s\n",
1966 parallel
, delta
, name_add
);
1967 fprintf (file
, "\tsetlo #lo(" HOST_WIDE_INT_PRINT_DEC
"),%s\n",
1969 fprintf (file
, "\tadd %s,%s,%s\n", name_add
, name_arg0
, name_arg0
);
1974 const char *name_pic
= reg_names
[FDPIC_REGNO
];
1975 name_jmp
= reg_names
[FDPIC_FPTR_REGNO
];
1979 fprintf (file
, "\tsethi%s #gotofffuncdeschi(", parallel
);
1980 assemble_name (file
, name_func
);
1981 fprintf (file
, "),%s\n", name_jmp
);
1983 fprintf (file
, "\tsetlo #gotofffuncdesclo(");
1984 assemble_name (file
, name_func
);
1985 fprintf (file
, "),%s\n", name_jmp
);
1987 fprintf (file
, "\tldd @(%s,%s), %s\n", name_jmp
, name_pic
, name_jmp
);
1991 fprintf (file
, "\tlddo @(%s,#gotofffuncdesc12(", name_pic
);
1992 assemble_name (file
, name_func
);
1993 fprintf (file
, "\t)), %s\n", name_jmp
);
1998 fprintf (file
, "\tsethi%s #hi(", parallel
);
1999 assemble_name (file
, name_func
);
2000 fprintf (file
, "),%s\n", name_jmp
);
2002 fprintf (file
, "\tsetlo #lo(");
2003 assemble_name (file
, name_func
);
2004 fprintf (file
, "),%s\n", name_jmp
);
2008 /* Use JUMP_REGNO as a temporary PIC register. */
2009 const char *name_lr
= reg_names
[LR_REGNO
];
2010 const char *name_gppic
= name_jmp
;
2011 const char *name_tmp
= reg_names
[TEMP_REGNO
];
2013 fprintf (file
, "\tmovsg %s,%s\n", name_lr
, name_tmp
);
2014 fprintf (file
, "\tcall 1f\n");
2015 fprintf (file
, "1:\tmovsg %s,%s\n", name_lr
, name_gppic
);
2016 fprintf (file
, "\tmovgs %s,%s\n", name_tmp
, name_lr
);
2017 fprintf (file
, "\tsethi%s #gprelhi(1b),%s\n", parallel
, name_tmp
);
2018 fprintf (file
, "\tsetlo #gprello(1b),%s\n", name_tmp
);
2019 fprintf (file
, "\tsub %s,%s,%s\n", name_gppic
, name_tmp
, name_gppic
);
2021 fprintf (file
, "\tsethi%s #gprelhi(", parallel
);
2022 assemble_name (file
, name_func
);
2023 fprintf (file
, "),%s\n", name_tmp
);
2025 fprintf (file
, "\tsetlo #gprello(");
2026 assemble_name (file
, name_func
);
2027 fprintf (file
, "),%s\n", name_tmp
);
2029 fprintf (file
, "\tadd %s,%s,%s\n", name_gppic
, name_tmp
, name_jmp
);
2032 /* Jump to the function address. */
2033 fprintf (file
, "\tjmpl @(%s,%s)\n", name_jmp
, reg_names
[GPR_FIRST
+0]);
2038 /* On frv, create a frame whenever we need to create stack. */
2041 frv_frame_pointer_required (void)
2043 /* If we forgoing the usual linkage requirements, we only need
2044 a frame pointer if the stack pointer might change. */
2045 if (!TARGET_LINKED_FP
)
2046 return !crtl
->sp_is_unchanging
;
2048 if (! crtl
->is_leaf
)
2051 if (get_frame_size () != 0)
2057 if (!crtl
->sp_is_unchanging
)
2060 if (!TARGET_FDPIC
&& flag_pic
&& crtl
->uses_pic_offset_table
)
2066 if (cfun
->machine
->frame_needed
)
2073 /* Worker function for TARGET_CAN_ELIMINATE. */
2076 frv_can_eliminate (const int from
, const int to
)
2078 return (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
2079 ? ! frame_pointer_needed
2083 /* This function returns the initial difference between the specified
2084 pair of registers. */
2086 /* See frv_stack_info for more details on the frv stack frame. */
2089 frv_initial_elimination_offset (int from
, int to
)
2091 frv_stack_t
*info
= frv_stack_info ();
2094 if (to
== STACK_POINTER_REGNUM
&& from
== ARG_POINTER_REGNUM
)
2095 ret
= info
->total_size
- info
->pretend_size
;
2097 else if (to
== STACK_POINTER_REGNUM
&& from
== FRAME_POINTER_REGNUM
)
2098 ret
= info
->reg_offset
[FRAME_POINTER_REGNUM
];
2100 else if (to
== FRAME_POINTER_REGNUM
&& from
== ARG_POINTER_REGNUM
)
2101 ret
= (info
->total_size
2102 - info
->reg_offset
[FRAME_POINTER_REGNUM
]
2103 - info
->pretend_size
);
2108 if (TARGET_DEBUG_STACK
)
2109 fprintf (stderr
, "Eliminate %s to %s by adding %d\n",
2110 reg_names
[from
], reg_names
[to
], ret
);
2116 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
2119 frv_setup_incoming_varargs (cumulative_args_t cum_v
,
2121 tree type ATTRIBUTE_UNUSED
,
2125 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
2127 if (TARGET_DEBUG_ARG
)
2129 "setup_vararg: words = %2d, mode = %4s, pretend_size = %d, second_time = %d\n",
2130 *cum
, GET_MODE_NAME (mode
), *pretend_size
, second_time
);
2134 /* Worker function for TARGET_EXPAND_BUILTIN_SAVEREGS. */
2137 frv_expand_builtin_saveregs (void)
2139 int offset
= UNITS_PER_WORD
* FRV_NUM_ARG_REGS
;
2141 if (TARGET_DEBUG_ARG
)
2142 fprintf (stderr
, "expand_builtin_saveregs: offset from ap = %d\n",
2145 return gen_rtx_PLUS (Pmode
, virtual_incoming_args_rtx
, GEN_INT (- offset
));
2149 /* Expand __builtin_va_start to do the va_start macro. */
2152 frv_expand_builtin_va_start (tree valist
, rtx nextarg
)
2155 int num
= crtl
->args
.info
- FIRST_ARG_REGNUM
- FRV_NUM_ARG_REGS
;
2157 nextarg
= gen_rtx_PLUS (Pmode
, virtual_incoming_args_rtx
,
2158 GEN_INT (UNITS_PER_WORD
* num
));
2160 if (TARGET_DEBUG_ARG
)
2162 fprintf (stderr
, "va_start: args_info = %d, num = %d\n",
2163 crtl
->args
.info
, num
);
2165 debug_rtx (nextarg
);
2168 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist
,
2169 fold_convert (TREE_TYPE (valist
),
2170 make_tree (sizetype
, nextarg
)));
2171 TREE_SIDE_EFFECTS (t
) = 1;
2173 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2177 /* Expand a block move operation, and return 1 if successful. Return 0
2178 if we should let the compiler generate normal code.
2180 operands[0] is the destination
2181 operands[1] is the source
2182 operands[2] is the length
2183 operands[3] is the alignment */
2185 /* Maximum number of loads to do before doing the stores */
2186 #ifndef MAX_MOVE_REG
2187 #define MAX_MOVE_REG 4
2190 /* Maximum number of total loads to do. */
2191 #ifndef TOTAL_MOVE_REG
2192 #define TOTAL_MOVE_REG 8
2196 frv_expand_block_move (rtx operands
[])
2198 rtx orig_dest
= operands
[0];
2199 rtx orig_src
= operands
[1];
2200 rtx bytes_rtx
= operands
[2];
2201 rtx align_rtx
= operands
[3];
2202 int constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
2215 rtx stores
[MAX_MOVE_REG
];
2219 /* If this is not a fixed size move, just call memcpy. */
2223 /* This should be a fixed size alignment. */
2224 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
2226 align
= INTVAL (align_rtx
);
2228 /* Anything to move? */
2229 bytes
= INTVAL (bytes_rtx
);
2233 /* Don't support real large moves. */
2234 if (bytes
> TOTAL_MOVE_REG
*align
)
2237 /* Move the address into scratch registers. */
2238 dest_reg
= copy_addr_to_reg (XEXP (orig_dest
, 0));
2239 src_reg
= copy_addr_to_reg (XEXP (orig_src
, 0));
2241 num_reg
= offset
= 0;
2242 for ( ; bytes
> 0; (bytes
-= move_bytes
), (offset
+= move_bytes
))
2244 /* Calculate the correct offset for src/dest. */
2248 dest_addr
= dest_reg
;
2252 src_addr
= plus_constant (Pmode
, src_reg
, offset
);
2253 dest_addr
= plus_constant (Pmode
, dest_reg
, offset
);
2256 /* Generate the appropriate load and store, saving the stores
2258 if (bytes
>= 4 && align
>= 4)
2260 else if (bytes
>= 2 && align
>= 2)
2265 move_bytes
= GET_MODE_SIZE (mode
);
2266 tmp_reg
= gen_reg_rtx (mode
);
2267 src_mem
= change_address (orig_src
, mode
, src_addr
);
2268 dest_mem
= change_address (orig_dest
, mode
, dest_addr
);
2269 emit_insn (gen_rtx_SET (tmp_reg
, src_mem
));
2270 stores
[num_reg
++] = gen_rtx_SET (dest_mem
, tmp_reg
);
2272 if (num_reg
>= MAX_MOVE_REG
)
2274 for (i
= 0; i
< num_reg
; i
++)
2275 emit_insn (stores
[i
]);
2280 for (i
= 0; i
< num_reg
; i
++)
2281 emit_insn (stores
[i
]);
2287 /* Expand a block clear operation, and return 1 if successful. Return 0
2288 if we should let the compiler generate normal code.
2290 operands[0] is the destination
2291 operands[1] is the length
2292 operands[3] is the alignment */
2295 frv_expand_block_clear (rtx operands
[])
2297 rtx orig_dest
= operands
[0];
2298 rtx bytes_rtx
= operands
[1];
2299 rtx align_rtx
= operands
[3];
2300 int constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
2310 /* If this is not a fixed size move, just call memcpy. */
2314 /* This should be a fixed size alignment. */
2315 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
2317 align
= INTVAL (align_rtx
);
2319 /* Anything to move? */
2320 bytes
= INTVAL (bytes_rtx
);
2324 /* Don't support real large clears. */
2325 if (bytes
> TOTAL_MOVE_REG
*align
)
2328 /* Move the address into a scratch register. */
2329 dest_reg
= copy_addr_to_reg (XEXP (orig_dest
, 0));
2332 for ( ; bytes
> 0; (bytes
-= clear_bytes
), (offset
+= clear_bytes
))
2334 /* Calculate the correct offset for src/dest. */
2335 dest_addr
= ((offset
== 0)
2337 : plus_constant (Pmode
, dest_reg
, offset
));
2339 /* Generate the appropriate store of gr0. */
2340 if (bytes
>= 4 && align
>= 4)
2342 else if (bytes
>= 2 && align
>= 2)
2347 clear_bytes
= GET_MODE_SIZE (mode
);
2348 dest_mem
= change_address (orig_dest
, mode
, dest_addr
);
2349 emit_insn (gen_rtx_SET (dest_mem
, const0_rtx
));
2356 /* The following variable is used to output modifiers of assembler
2357 code of the current output insn. */
2359 static rtx
*frv_insn_operands
;
2361 /* The following function is used to add assembler insn code suffix .p
2362 if it is necessary. */
2365 frv_asm_output_opcode (FILE *f
, const char *ptr
)
2369 if (frv_insn_packing_flag
<= 0)
2372 for (; *ptr
&& *ptr
!= ' ' && *ptr
!= '\t';)
2375 if (c
== '%' && ((*ptr
>= 'a' && *ptr
<= 'z')
2376 || (*ptr
>= 'A' && *ptr
<= 'Z')))
2378 int letter
= *ptr
++;
2381 frv_print_operand (f
, frv_insn_operands
[c
], letter
);
2382 while ((c
= *ptr
) >= '0' && c
<= '9')
2394 /* Set up the packing bit for the current output insn. Note that this
2395 function is not called for asm insns. */
2398 frv_final_prescan_insn (rtx_insn
*insn
, rtx
*opvec
,
2399 int noperands ATTRIBUTE_UNUSED
)
2403 if (frv_insn_packing_flag
>= 0)
2405 frv_insn_operands
= opvec
;
2406 frv_insn_packing_flag
= PACKING_FLAG_P (insn
);
2408 else if (recog_memoized (insn
) >= 0
2409 && get_attr_acc_group (insn
) == ACC_GROUP_ODD
)
2410 /* Packing optimizations have been disabled, but INSN can only
2411 be issued in M1. Insert an mnop in M0. */
2412 fprintf (asm_out_file
, "\tmnop.p\n");
2418 /* A C expression whose value is RTL representing the address in a stack frame
2419 where the pointer to the caller's frame is stored. Assume that FRAMEADDR is
2420 an RTL expression for the address of the stack frame itself.
2422 If you don't define this macro, the default is to return the value of
2423 FRAMEADDR--that is, the stack frame address is also the address of the stack
2424 word that points to the previous frame. */
2426 /* The default is correct, but we need to make sure the frame gets created. */
2428 frv_dynamic_chain_address (rtx frame
)
2430 cfun
->machine
->frame_needed
= 1;
2435 /* A C expression whose value is RTL representing the value of the return
2436 address for the frame COUNT steps up from the current frame, after the
2437 prologue. FRAMEADDR is the frame pointer of the COUNT frame, or the frame
2438 pointer of the COUNT - 1 frame if `RETURN_ADDR_IN_PREVIOUS_FRAME' is
2441 The value of the expression must always be the correct address when COUNT is
2442 zero, but may be `NULL_RTX' if there is not way to determine the return
2443 address of other frames. */
2446 frv_return_addr_rtx (int count
, rtx frame
)
2450 cfun
->machine
->frame_needed
= 1;
2451 return gen_rtx_MEM (Pmode
, plus_constant (Pmode
, frame
, 8));
2454 /* Given a memory reference MEMREF, interpret the referenced memory as
2455 an array of MODE values, and return a reference to the element
2456 specified by INDEX. Assume that any pre-modification implicit in
2457 MEMREF has already happened.
2459 MEMREF must be a legitimate operand for modes larger than SImode.
2460 frv_legitimate_address_p forbids register+register addresses, which
2461 this function cannot handle. */
2463 frv_index_memory (rtx memref
, machine_mode mode
, int index
)
2465 rtx base
= XEXP (memref
, 0);
2466 if (GET_CODE (base
) == PRE_MODIFY
)
2467 base
= XEXP (base
, 0);
2468 return change_address (memref
, mode
,
2469 plus_constant (Pmode
, base
,
2470 index
* GET_MODE_SIZE (mode
)));
2474 /* Print a memory address as an operand to reference that memory location. */
2476 frv_print_operand_address (FILE * stream
, machine_mode
/* mode */, rtx x
)
2478 if (GET_CODE (x
) == MEM
)
2481 switch (GET_CODE (x
))
2484 fputs (reg_names
[ REGNO (x
)], stream
);
2488 fprintf (stream
, "%ld", (long) INTVAL (x
));
2492 assemble_name (stream
, XSTR (x
, 0));
2497 output_addr_const (stream
, x
);
2501 /* Poorly constructed asm statements can trigger this alternative.
2502 See gcc/testsuite/gcc.dg/asm-4.c for an example. */
2503 frv_print_operand_memory_reference (stream
, x
, 0);
2510 fatal_insn ("bad insn to frv_print_operand_address:", x
);
2515 frv_print_operand_memory_reference_reg (FILE * stream
, rtx x
)
2517 int regno
= true_regnum (x
);
2519 fputs (reg_names
[regno
], stream
);
2521 fatal_insn ("bad register to frv_print_operand_memory_reference_reg:", x
);
2524 /* Print a memory reference suitable for the ld/st instructions. */
2527 frv_print_operand_memory_reference (FILE * stream
, rtx x
, int addr_offset
)
2529 struct frv_unspec unspec
;
2533 switch (GET_CODE (x
))
2540 case PRE_MODIFY
: /* (pre_modify (reg) (plus (reg) (reg))) */
2542 x1
= XEXP (XEXP (x
, 1), 1);
2552 if (GET_CODE (x0
) == CONST_INT
)
2560 fatal_insn ("bad insn to frv_print_operand_memory_reference:", x
);
2569 else if (GET_CODE (x1
) != CONST_INT
)
2570 fatal_insn ("bad insn to frv_print_operand_memory_reference:", x
);
2573 fputs ("@(", stream
);
2575 fputs (reg_names
[GPR_R0
], stream
);
2576 else if (GET_CODE (x0
) == REG
|| GET_CODE (x0
) == SUBREG
)
2577 frv_print_operand_memory_reference_reg (stream
, x0
);
2579 fatal_insn ("bad insn to frv_print_operand_memory_reference:", x
);
2581 fputs (",", stream
);
2583 fputs (reg_names
[GPR_R0
], stream
);
2587 switch (GET_CODE (x1
))
2591 frv_print_operand_memory_reference_reg (stream
, x1
);
2595 fprintf (stream
, "%ld", (long) (INTVAL (x1
) + addr_offset
));
2599 if (!frv_const_unspec_p (x1
, &unspec
))
2600 fatal_insn ("bad insn to frv_print_operand_memory_reference:", x1
);
2601 frv_output_const_unspec (stream
, &unspec
);
2605 fatal_insn ("bad insn to frv_print_operand_memory_reference:", x
);
2609 fputs (")", stream
);
2613 /* Return 2 for likely branches and 0 for non-likely branches */
2615 #define FRV_JUMP_LIKELY 2
2616 #define FRV_JUMP_NOT_LIKELY 0
2619 frv_print_operand_jump_hint (rtx_insn
*insn
)
2625 enum { UNKNOWN
, BACKWARD
, FORWARD
} jump_type
= UNKNOWN
;
2627 gcc_assert (JUMP_P (insn
));
2629 /* Assume any non-conditional jump is likely. */
2630 if (! any_condjump_p (insn
))
2631 ret
= FRV_JUMP_LIKELY
;
2635 labelref
= condjump_label (insn
);
2638 rtx label
= XEXP (labelref
, 0);
2639 jump_type
= (insn_current_address
> INSN_ADDRESSES (INSN_UID (label
))
2644 note
= find_reg_note (insn
, REG_BR_PROB
, 0);
2646 ret
= ((jump_type
== BACKWARD
) ? FRV_JUMP_LIKELY
: FRV_JUMP_NOT_LIKELY
);
2650 prob
= XINT (note
, 0);
2651 ret
= ((prob
>= (REG_BR_PROB_BASE
/ 2))
2653 : FRV_JUMP_NOT_LIKELY
);
2665 case UNKNOWN
: direction
= "unknown jump direction"; break;
2666 case BACKWARD
: direction
= "jump backward"; break;
2667 case FORWARD
: direction
= "jump forward"; break;
2671 "%s: uid %ld, %s, probability = %d, max prob. = %d, hint = %d\n",
2672 IDENTIFIER_POINTER (DECL_NAME (current_function_decl
)),
2673 (long)INSN_UID (insn
), direction
, prob
,
2674 REG_BR_PROB_BASE
, ret
);
2682 /* Return the comparison operator to use for CODE given that the ICC
2686 comparison_string (enum rtx_code code
, rtx op0
)
2688 bool is_nz_p
= GET_MODE (op0
) == CC_NZmode
;
2691 default: output_operand_lossage ("bad condition code");
2692 case EQ
: return "eq";
2693 case NE
: return "ne";
2694 case LT
: return is_nz_p
? "n" : "lt";
2695 case LE
: return "le";
2696 case GT
: return "gt";
2697 case GE
: return is_nz_p
? "p" : "ge";
2698 case LTU
: return is_nz_p
? "no" : "c";
2699 case LEU
: return is_nz_p
? "eq" : "ls";
2700 case GTU
: return is_nz_p
? "ne" : "hi";
2701 case GEU
: return is_nz_p
? "ra" : "nc";
2705 /* Print an operand to an assembler instruction.
2707 `%' followed by a letter and a digit says to output an operand in an
2708 alternate fashion. Four letters have standard, built-in meanings
2709 described below. The hook `TARGET_PRINT_OPERAND' can define
2710 additional letters with nonstandard meanings.
2712 `%cDIGIT' can be used to substitute an operand that is a constant value
2713 without the syntax that normally indicates an immediate operand.
2715 `%nDIGIT' is like `%cDIGIT' except that the value of the constant is negated
2718 `%aDIGIT' can be used to substitute an operand as if it were a memory
2719 reference, with the actual operand treated as the address. This may be
2720 useful when outputting a "load address" instruction, because often the
2721 assembler syntax for such an instruction requires you to write the operand
2722 as if it were a memory reference.
2724 `%lDIGIT' is used to substitute a `label_ref' into a jump instruction.
2726 `%=' outputs a number which is unique to each instruction in the entire
2727 compilation. This is useful for making local labels to be referred to more
2728 than once in a single template that generates multiple assembler
2731 `%' followed by a punctuation character specifies a substitution that
2732 does not use an operand. Only one case is standard: `%%' outputs a
2733 `%' into the assembler code. Other nonstandard cases can be defined
2734 in the `TARGET_PRINT_OPERAND' hook. You must also define which
2735 punctuation characters are valid with the
2736 `TARGET_PRINT_OPERAND_PUNCT_VALID_P' hook. */
2739 frv_print_operand (FILE * file
, rtx x
, int code
)
2741 struct frv_unspec unspec
;
2742 HOST_WIDE_INT value
;
2745 if (code
!= 0 && !ISALPHA (code
))
2748 else if (GET_CODE (x
) == CONST_INT
)
2751 else if (GET_CODE (x
) == CONST_DOUBLE
)
2753 if (GET_MODE (x
) == SFmode
)
2757 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x
), l
);
2761 else if (GET_MODE (x
) == VOIDmode
)
2762 value
= CONST_DOUBLE_LOW (x
);
2765 fatal_insn ("bad insn in frv_print_operand, bad const_double", x
);
2776 fputs (reg_names
[GPR_R0
], file
);
2780 fprintf (file
, "%d", frv_print_operand_jump_hint (current_output_insn
));
2784 /* Output small data area base register (gr16). */
2785 fputs (reg_names
[SDA_BASE_REG
], file
);
2789 /* Output pic register (gr17). */
2790 fputs (reg_names
[PIC_REGNO
], file
);
2794 /* Output the temporary integer CCR register. */
2795 fputs (reg_names
[ICR_TEMP
], file
);
2799 /* Output the temporary integer CC register. */
2800 fputs (reg_names
[ICC_TEMP
], file
);
2803 /* case 'a': print an address. */
2806 /* Print appropriate test for integer branch false operation. */
2807 fputs (comparison_string (reverse_condition (GET_CODE (x
)),
2808 XEXP (x
, 0)), file
);
2812 /* Print appropriate test for integer branch true operation. */
2813 fputs (comparison_string (GET_CODE (x
), XEXP (x
, 0)), file
);
2817 /* Print 1 for a NE and 0 for an EQ to give the final argument
2818 for a conditional instruction. */
2819 if (GET_CODE (x
) == NE
)
2822 else if (GET_CODE (x
) == EQ
)
2826 fatal_insn ("bad insn to frv_print_operand, 'e' modifier:", x
);
2830 /* Print appropriate test for floating point branch false operation. */
2831 switch (GET_CODE (x
))
2834 fatal_insn ("bad insn to frv_print_operand, 'F' modifier:", x
);
2836 case EQ
: fputs ("ne", file
); break;
2837 case NE
: fputs ("eq", file
); break;
2838 case LT
: fputs ("uge", file
); break;
2839 case LE
: fputs ("ug", file
); break;
2840 case GT
: fputs ("ule", file
); break;
2841 case GE
: fputs ("ul", file
); break;
2846 /* Print appropriate test for floating point branch true operation. */
2847 switch (GET_CODE (x
))
2850 fatal_insn ("bad insn to frv_print_operand, 'f' modifier:", x
);
2852 case EQ
: fputs ("eq", file
); break;
2853 case NE
: fputs ("ne", file
); break;
2854 case LT
: fputs ("lt", file
); break;
2855 case LE
: fputs ("le", file
); break;
2856 case GT
: fputs ("gt", file
); break;
2857 case GE
: fputs ("ge", file
); break;
2862 /* Print appropriate GOT function. */
2863 if (GET_CODE (x
) != CONST_INT
)
2864 fatal_insn ("bad insn to frv_print_operand, 'g' modifier:", x
);
2865 fputs (unspec_got_name (INTVAL (x
)), file
);
2869 /* Print 'i' if the operand is a constant, or is a memory reference that
2871 if (GET_CODE (x
) == MEM
)
2872 x
= ((GET_CODE (XEXP (x
, 0)) == PLUS
)
2873 ? XEXP (XEXP (x
, 0), 1)
2875 else if (GET_CODE (x
) == PLUS
)
2878 switch (GET_CODE (x
))
2892 /* For jump instructions, print 'i' if the operand is a constant or
2893 is an expression that adds a constant. */
2894 if (GET_CODE (x
) == CONST_INT
)
2899 if (GET_CODE (x
) == CONST_INT
2900 || (GET_CODE (x
) == PLUS
2901 && (GET_CODE (XEXP (x
, 1)) == CONST_INT
2902 || GET_CODE (XEXP (x
, 0)) == CONST_INT
)))
2908 /* Print the lower register of a double word register pair */
2909 if (GET_CODE (x
) == REG
)
2910 fputs (reg_names
[ REGNO (x
)+1 ], file
);
2912 fatal_insn ("bad insn to frv_print_operand, 'L' modifier:", x
);
2915 /* case 'l': print a LABEL_REF. */
2919 /* Print a memory reference for ld/st/jmp, %N prints a memory reference
2920 for the second word of double memory operations. */
2921 offset
= (code
== 'M') ? 0 : UNITS_PER_WORD
;
2922 switch (GET_CODE (x
))
2925 fatal_insn ("bad insn to frv_print_operand, 'M/N' modifier:", x
);
2928 frv_print_operand_memory_reference (file
, XEXP (x
, 0), offset
);
2936 frv_print_operand_memory_reference (file
, x
, offset
);
2942 /* Print the opcode of a command. */
2943 switch (GET_CODE (x
))
2946 fatal_insn ("bad insn to frv_print_operand, 'O' modifier:", x
);
2948 case PLUS
: fputs ("add", file
); break;
2949 case MINUS
: fputs ("sub", file
); break;
2950 case AND
: fputs ("and", file
); break;
2951 case IOR
: fputs ("or", file
); break;
2952 case XOR
: fputs ("xor", file
); break;
2953 case ASHIFT
: fputs ("sll", file
); break;
2954 case ASHIFTRT
: fputs ("sra", file
); break;
2955 case LSHIFTRT
: fputs ("srl", file
); break;
2959 /* case 'n': negate and print a constant int. */
2962 /* Print PIC label using operand as the number. */
2963 if (GET_CODE (x
) != CONST_INT
)
2964 fatal_insn ("bad insn to frv_print_operand, P modifier:", x
);
2966 fprintf (file
, ".LCF%ld", (long)INTVAL (x
));
2970 /* Print 'u' if the operand is a update load/store. */
2971 if (GET_CODE (x
) == MEM
&& GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
2976 /* If value is 0, print gr0, otherwise it must be a register. */
2977 if (GET_CODE (x
) == CONST_INT
&& INTVAL (x
) == 0)
2978 fputs (reg_names
[GPR_R0
], file
);
2980 else if (GET_CODE (x
) == REG
)
2981 fputs (reg_names
[REGNO (x
)], file
);
2984 fatal_insn ("bad insn in frv_print_operand, z case", x
);
2988 /* Print constant in hex. */
2989 if (GET_CODE (x
) == CONST_INT
|| GET_CODE (x
) == CONST_DOUBLE
)
2991 fprintf (file
, "%s0x%.4lx", IMMEDIATE_PREFIX
, (long) value
);
2998 if (GET_CODE (x
) == REG
)
2999 fputs (reg_names
[REGNO (x
)], file
);
3001 else if (GET_CODE (x
) == CONST_INT
3002 || GET_CODE (x
) == CONST_DOUBLE
)
3003 fprintf (file
, "%s%ld", IMMEDIATE_PREFIX
, (long) value
);
3005 else if (frv_const_unspec_p (x
, &unspec
))
3006 frv_output_const_unspec (file
, &unspec
);
3008 else if (GET_CODE (x
) == MEM
)
3009 frv_print_operand_address (file
, GET_MODE (x
), XEXP (x
, 0));
3011 else if (CONSTANT_ADDRESS_P (x
))
3012 frv_print_operand_address (file
, VOIDmode
, x
);
3015 fatal_insn ("bad insn in frv_print_operand, 0 case", x
);
3020 fatal_insn ("frv_print_operand: unknown code", x
);
3028 frv_print_operand_punct_valid_p (unsigned char code
)
3030 return (code
== '.' || code
== '#' || code
== '@' || code
== '~'
3031 || code
== '*' || code
== '&');
3035 /* A C statement (sans semicolon) for initializing the variable CUM for the
3036 state at the beginning of the argument list. The variable has type
3037 `CUMULATIVE_ARGS'. The value of FNTYPE is the tree node for the data type
3038 of the function which will receive the args, or 0 if the args are to a
3039 compiler support library function. The value of INDIRECT is nonzero when
3040 processing an indirect call, for example a call through a function pointer.
3041 The value of INDIRECT is zero for a call to an explicitly named function, a
3042 library function call, or when `INIT_CUMULATIVE_ARGS' is used to find
3043 arguments for the function being compiled.
3045 When processing a call to a compiler support library function, LIBNAME
3046 identifies which one. It is a `symbol_ref' rtx which contains the name of
3047 the function, as a string. LIBNAME is 0 when an ordinary C function call is
3048 being processed. Thus, each time this macro is called, either LIBNAME or
3049 FNTYPE is nonzero, but never both of them at once. */
3052 frv_init_cumulative_args (CUMULATIVE_ARGS
*cum
,
3058 *cum
= FIRST_ARG_REGNUM
;
3060 if (TARGET_DEBUG_ARG
)
3062 fprintf (stderr
, "\ninit_cumulative_args:");
3063 if (!fndecl
&& fntype
)
3064 fputs (" indirect", stderr
);
3067 fputs (" incoming", stderr
);
3071 tree ret_type
= TREE_TYPE (fntype
);
3072 fprintf (stderr
, " return=%s,",
3073 get_tree_code_name (TREE_CODE (ret_type
)));
3076 if (libname
&& GET_CODE (libname
) == SYMBOL_REF
)
3077 fprintf (stderr
, " libname=%s", XSTR (libname
, 0));
3079 if (cfun
->returns_struct
)
3080 fprintf (stderr
, " return-struct");
3082 putc ('\n', stderr
);
3087 /* Return true if we should pass an argument on the stack rather than
3091 frv_must_pass_in_stack (machine_mode mode
, const_tree type
)
3093 if (mode
== BLKmode
)
3097 return AGGREGATE_TYPE_P (type
);
3100 /* If defined, a C expression that gives the alignment boundary, in bits, of an
3101 argument with the specified mode and type. If it is not defined,
3102 `PARM_BOUNDARY' is used for all arguments. */
3105 frv_function_arg_boundary (machine_mode mode ATTRIBUTE_UNUSED
,
3106 const_tree type ATTRIBUTE_UNUSED
)
3108 return BITS_PER_WORD
;
3112 frv_function_arg_1 (cumulative_args_t cum_v
, machine_mode mode
,
3113 const_tree type ATTRIBUTE_UNUSED
, bool named
,
3114 bool incoming ATTRIBUTE_UNUSED
)
3116 const CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
3118 machine_mode xmode
= (mode
== BLKmode
) ? SImode
: mode
;
3123 /* Return a marker for use in the call instruction. */
3124 if (xmode
== VOIDmode
)
3130 else if (arg_num
<= LAST_ARG_REGNUM
)
3132 ret
= gen_rtx_REG (xmode
, arg_num
);
3133 debstr
= reg_names
[arg_num
];
3142 if (TARGET_DEBUG_ARG
)
3144 "function_arg: words = %2d, mode = %4s, named = %d, size = %3d, arg = %s\n",
3145 arg_num
, GET_MODE_NAME (mode
), named
, GET_MODE_SIZE (mode
), debstr
);
3151 frv_function_arg (cumulative_args_t cum
, machine_mode mode
,
3152 const_tree type
, bool named
)
3154 return frv_function_arg_1 (cum
, mode
, type
, named
, false);
3158 frv_function_incoming_arg (cumulative_args_t cum
, machine_mode mode
,
3159 const_tree type
, bool named
)
3161 return frv_function_arg_1 (cum
, mode
, type
, named
, true);
3165 /* A C statement (sans semicolon) to update the summarizer variable CUM to
3166 advance past an argument in the argument list. The values MODE, TYPE and
3167 NAMED describe that argument. Once this is done, the variable CUM is
3168 suitable for analyzing the *following* argument with `FUNCTION_ARG', etc.
3170 This macro need not do anything if the argument in question was passed on
3171 the stack. The compiler knows how to track the amount of stack space used
3172 for arguments without any special help. */
3175 frv_function_arg_advance (cumulative_args_t cum_v
,
3177 const_tree type ATTRIBUTE_UNUSED
,
3180 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
3182 machine_mode xmode
= (mode
== BLKmode
) ? SImode
: mode
;
3183 int bytes
= GET_MODE_SIZE (xmode
);
3184 int words
= (bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
3187 *cum
= arg_num
+ words
;
3189 if (TARGET_DEBUG_ARG
)
3191 "function_adv: words = %2d, mode = %4s, named = %d, size = %3d\n",
3192 arg_num
, GET_MODE_NAME (mode
), named
, words
* UNITS_PER_WORD
);
3196 /* A C expression for the number of words, at the beginning of an argument,
3197 must be put in registers. The value must be zero for arguments that are
3198 passed entirely in registers or that are entirely pushed on the stack.
3200 On some machines, certain arguments must be passed partially in registers
3201 and partially in memory. On these machines, typically the first N words of
3202 arguments are passed in registers, and the rest on the stack. If a
3203 multi-word argument (a `double' or a structure) crosses that boundary, its
3204 first few words must be passed in registers and the rest must be pushed.
3205 This macro tells the compiler when this occurs, and how many of the words
3206 should go in registers.
3208 `FUNCTION_ARG' for these arguments should return the first register to be
3209 used by the caller for this argument; likewise `FUNCTION_INCOMING_ARG', for
3210 the called function. */
3213 frv_arg_partial_bytes (cumulative_args_t cum
, machine_mode mode
,
3214 tree type ATTRIBUTE_UNUSED
, bool named ATTRIBUTE_UNUSED
)
3217 machine_mode xmode
= (mode
== BLKmode
) ? SImode
: mode
;
3218 int bytes
= GET_MODE_SIZE (xmode
);
3219 int words
= (bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
3220 int arg_num
= *get_cumulative_args (cum
);
3223 ret
= ((arg_num
<= LAST_ARG_REGNUM
&& arg_num
+ words
> LAST_ARG_REGNUM
+1)
3224 ? LAST_ARG_REGNUM
- arg_num
+ 1
3226 ret
*= UNITS_PER_WORD
;
3228 if (TARGET_DEBUG_ARG
&& ret
)
3229 fprintf (stderr
, "frv_arg_partial_bytes: %d\n", ret
);
3235 /* Implements TARGET_FUNCTION_VALUE. */
3238 frv_function_value (const_tree valtype
,
3239 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
3240 bool outgoing ATTRIBUTE_UNUSED
)
3242 return gen_rtx_REG (TYPE_MODE (valtype
), RETURN_VALUE_REGNUM
);
3246 /* Implements TARGET_LIBCALL_VALUE. */
3249 frv_libcall_value (machine_mode mode
,
3250 const_rtx fun ATTRIBUTE_UNUSED
)
3252 return gen_rtx_REG (mode
, RETURN_VALUE_REGNUM
);
3256 /* Implements FUNCTION_VALUE_REGNO_P. */
3259 frv_function_value_regno_p (const unsigned int regno
)
3261 return (regno
== RETURN_VALUE_REGNUM
);
3264 /* Return true if a register is ok to use as a base or index register. */
3266 static FRV_INLINE
int
3267 frv_regno_ok_for_base_p (int regno
, int strict_p
)
3273 return (reg_renumber
[regno
] >= 0 && GPR_P (reg_renumber
[regno
]));
3275 if (regno
== ARG_POINTER_REGNUM
)
3278 return (regno
>= FIRST_PSEUDO_REGISTER
);
3282 /* A C compound statement with a conditional `goto LABEL;' executed if X (an
3283 RTX) is a legitimate memory address on the target machine for a memory
3284 operand of mode MODE.
3286 It usually pays to define several simpler macros to serve as subroutines for
3287 this one. Otherwise it may be too complicated to understand.
3289 This macro must exist in two variants: a strict variant and a non-strict
3290 one. The strict variant is used in the reload pass. It must be defined so
3291 that any pseudo-register that has not been allocated a hard register is
3292 considered a memory reference. In contexts where some kind of register is
3293 required, a pseudo-register with no hard register must be rejected.
3295 The non-strict variant is used in other passes. It must be defined to
3296 accept all pseudo-registers in every context where some kind of register is
3299 Compiler source files that want to use the strict variant of this macro
3300 define the macro `REG_OK_STRICT'. You should use an `#ifdef REG_OK_STRICT'
3301 conditional to define the strict variant in that case and the non-strict
3304 Normally, constant addresses which are the sum of a `symbol_ref' and an
3305 integer are stored inside a `const' RTX to mark them as constant.
3306 Therefore, there is no need to recognize such sums specifically as
3307 legitimate addresses. Normally you would simply recognize any `const' as
3310 Usually `TARGET_PRINT_OPERAND_ADDRESS' is not prepared to handle
3311 constant sums that are not marked with `const'. It assumes that a
3312 naked `plus' indicates indexing. If so, then you *must* reject such
3313 naked constant sums as illegitimate addresses, so that none of them
3314 will be given to `TARGET_PRINT_OPERAND_ADDRESS'. */
3317 frv_legitimate_address_p_1 (machine_mode mode
,
3321 int allow_double_reg_p
)
3325 HOST_WIDE_INT value
;
3328 if (FRV_SYMBOL_REF_TLS_P (x
))
3331 switch (GET_CODE (x
))
3338 if (GET_CODE (x
) != REG
)
3344 ret
= frv_regno_ok_for_base_p (REGNO (x
), strict_p
);
3350 if (GET_CODE (x0
) != REG
3351 || ! frv_regno_ok_for_base_p (REGNO (x0
), strict_p
)
3352 || GET_CODE (x1
) != PLUS
3353 || ! rtx_equal_p (x0
, XEXP (x1
, 0))
3354 || GET_CODE (XEXP (x1
, 1)) != REG
3355 || ! frv_regno_ok_for_base_p (REGNO (XEXP (x1
, 1)), strict_p
))
3362 /* 12-bit immediate */
3367 ret
= IN_RANGE (INTVAL (x
), -2048, 2047);
3369 /* If we can't use load/store double operations, make sure we can
3370 address the second word. */
3371 if (ret
&& GET_MODE_SIZE (mode
) > UNITS_PER_WORD
)
3372 ret
= IN_RANGE (INTVAL (x
) + GET_MODE_SIZE (mode
) - 1,
3381 if (GET_CODE (x0
) == SUBREG
)
3382 x0
= SUBREG_REG (x0
);
3384 if (GET_CODE (x0
) != REG
)
3387 regno0
= REGNO (x0
);
3388 if (!frv_regno_ok_for_base_p (regno0
, strict_p
))
3391 switch (GET_CODE (x1
))
3397 x1
= SUBREG_REG (x1
);
3398 if (GET_CODE (x1
) != REG
)
3404 /* Do not allow reg+reg addressing for modes > 1 word if we
3405 can't depend on having move double instructions. */
3406 if (!allow_double_reg_p
&& GET_MODE_SIZE (mode
) > UNITS_PER_WORD
)
3409 ret
= frv_regno_ok_for_base_p (REGNO (x1
), strict_p
);
3413 /* 12-bit immediate */
3418 value
= INTVAL (x1
);
3419 ret
= IN_RANGE (value
, -2048, 2047);
3421 /* If we can't use load/store double operations, make sure we can
3422 address the second word. */
3423 if (ret
&& GET_MODE_SIZE (mode
) > UNITS_PER_WORD
)
3424 ret
= IN_RANGE (value
+ GET_MODE_SIZE (mode
) - 1, -2048, 2047);
3429 if (!condexec_p
&& got12_operand (x1
, VOIDmode
))
3437 if (TARGET_DEBUG_ADDR
)
3439 fprintf (stderr
, "\n========== legitimate_address_p, mode = %s, result = %d, addresses are %sstrict%s\n",
3440 GET_MODE_NAME (mode
), ret
, (strict_p
) ? "" : "not ",
3441 (condexec_p
) ? ", inside conditional code" : "");
3449 frv_legitimate_address_p (machine_mode mode
, rtx x
, bool strict_p
)
3451 return frv_legitimate_address_p_1 (mode
, x
, strict_p
, FALSE
, FALSE
);
3454 /* Given an ADDR, generate code to inline the PLT. */
3456 gen_inlined_tls_plt (rtx addr
)
3459 rtx picreg
= get_hard_reg_initial_val (Pmode
, FDPIC_REG
);
3462 dest
= gen_reg_rtx (DImode
);
3469 lddi.p @(gr15, #gottlsdesc12(ADDR)), gr8
3470 calll #gettlsoff(ADDR)@(gr8, gr0)
3472 emit_insn (gen_tls_lddi (dest
, addr
, picreg
));
3479 sethi.p #gottlsdeschi(ADDR), gr8
3480 setlo #gottlsdesclo(ADDR), gr8
3481 ldd #tlsdesc(ADDR)@(gr15, gr8), gr8
3482 calll #gettlsoff(ADDR)@(gr8, gr0)
3484 rtx reguse
= gen_reg_rtx (Pmode
);
3485 emit_insn (gen_tlsoff_hilo (reguse
, addr
, GEN_INT (R_FRV_GOTTLSDESCHI
)));
3486 emit_insn (gen_tls_tlsdesc_ldd (dest
, picreg
, reguse
, addr
));
3489 retval
= gen_reg_rtx (Pmode
);
3490 emit_insn (gen_tls_indirect_call (retval
, addr
, dest
, picreg
));
3494 /* Emit a TLSMOFF or TLSMOFF12 offset, depending on -mTLS. Returns
3495 the destination address. */
3497 gen_tlsmoff (rtx addr
, rtx reg
)
3499 rtx dest
= gen_reg_rtx (Pmode
);
3503 /* sethi.p #tlsmoffhi(x), grA
3504 setlo #tlsmofflo(x), grA
3506 dest
= gen_reg_rtx (Pmode
);
3507 emit_insn (gen_tlsoff_hilo (dest
, addr
,
3508 GEN_INT (R_FRV_TLSMOFFHI
)));
3509 dest
= gen_rtx_PLUS (Pmode
, dest
, reg
);
3513 /* addi grB, #tlsmoff12(x), grC
3515 ld/st @(grB, #tlsmoff12(x)), grC
3517 dest
= gen_reg_rtx (Pmode
);
3518 emit_insn (gen_symGOTOFF2reg_i (dest
, addr
, reg
,
3519 GEN_INT (R_FRV_TLSMOFF12
)));
3524 /* Generate code for a TLS address. */
3526 frv_legitimize_tls_address (rtx addr
, enum tls_model model
)
3528 rtx dest
, tp
= gen_rtx_REG (Pmode
, 29);
3529 rtx picreg
= get_hard_reg_initial_val (Pmode
, 15);
3533 case TLS_MODEL_INITIAL_EXEC
:
3537 ldi @(gr15, #gottlsoff12(x)), gr5
3539 dest
= gen_reg_rtx (Pmode
);
3540 emit_insn (gen_tls_load_gottlsoff12 (dest
, addr
, picreg
));
3541 dest
= gen_rtx_PLUS (Pmode
, tp
, dest
);
3545 /* -fPIC or anything else.
3547 sethi.p #gottlsoffhi(x), gr14
3548 setlo #gottlsofflo(x), gr14
3549 ld #tlsoff(x)@(gr15, gr14), gr9
3551 rtx tmp
= gen_reg_rtx (Pmode
);
3552 dest
= gen_reg_rtx (Pmode
);
3553 emit_insn (gen_tlsoff_hilo (tmp
, addr
,
3554 GEN_INT (R_FRV_GOTTLSOFF_HI
)));
3556 emit_insn (gen_tls_tlsoff_ld (dest
, picreg
, tmp
, addr
));
3557 dest
= gen_rtx_PLUS (Pmode
, tp
, dest
);
3560 case TLS_MODEL_LOCAL_DYNAMIC
:
3564 if (TARGET_INLINE_PLT
)
3565 retval
= gen_inlined_tls_plt (GEN_INT (0));
3568 /* call #gettlsoff(0) */
3569 retval
= gen_reg_rtx (Pmode
);
3570 emit_insn (gen_call_gettlsoff (retval
, GEN_INT (0), picreg
));
3573 reg
= gen_reg_rtx (Pmode
);
3574 emit_insn (gen_rtx_SET (reg
, gen_rtx_PLUS (Pmode
, retval
, tp
)));
3576 dest
= gen_tlsmoff (addr
, reg
);
3579 dest = gen_reg_rtx (Pmode);
3580 emit_insn (gen_tlsoff_hilo (dest, addr,
3581 GEN_INT (R_FRV_TLSMOFFHI)));
3582 dest = gen_rtx_PLUS (Pmode, dest, reg);
3586 case TLS_MODEL_LOCAL_EXEC
:
3587 dest
= gen_tlsmoff (addr
, gen_rtx_REG (Pmode
, 29));
3589 case TLS_MODEL_GLOBAL_DYNAMIC
:
3593 if (TARGET_INLINE_PLT
)
3594 retval
= gen_inlined_tls_plt (addr
);
3597 /* call #gettlsoff(x) */
3598 retval
= gen_reg_rtx (Pmode
);
3599 emit_insn (gen_call_gettlsoff (retval
, addr
, picreg
));
3601 dest
= gen_rtx_PLUS (Pmode
, retval
, tp
);
3612 frv_legitimize_address (rtx x
,
3613 rtx oldx ATTRIBUTE_UNUSED
,
3614 machine_mode mode ATTRIBUTE_UNUSED
)
3616 if (GET_CODE (x
) == SYMBOL_REF
)
3618 enum tls_model model
= SYMBOL_REF_TLS_MODEL (x
);
3620 return frv_legitimize_tls_address (x
, model
);
3626 /* Test whether a local function descriptor is canonical, i.e.,
3627 whether we can use FUNCDESC_GOTOFF to compute the address of the
3631 frv_local_funcdesc_p (rtx fnx
)
3634 enum symbol_visibility vis
;
3637 if (! SYMBOL_REF_LOCAL_P (fnx
))
3640 fn
= SYMBOL_REF_DECL (fnx
);
3645 vis
= DECL_VISIBILITY (fn
);
3647 if (vis
== VISIBILITY_PROTECTED
)
3648 /* Private function descriptors for protected functions are not
3649 canonical. Temporarily change the visibility to global. */
3650 vis
= VISIBILITY_DEFAULT
;
3651 else if (flag_shlib
)
3652 /* If we're already compiling for a shared library (that, unlike
3653 executables, can't assume that the existence of a definition
3654 implies local binding), we can skip the re-testing. */
3657 ret
= default_binds_local_p_1 (fn
, flag_pic
);
3659 DECL_VISIBILITY (fn
) = vis
;
3664 /* Load the _gp symbol into DEST. SRC is supposed to be the FDPIC
3668 frv_gen_GPsym2reg (rtx dest
, rtx src
)
3670 tree gp
= get_identifier ("_gp");
3671 rtx gp_sym
= gen_rtx_SYMBOL_REF (Pmode
, IDENTIFIER_POINTER (gp
));
3673 return gen_symGOT2reg (dest
, gp_sym
, src
, GEN_INT (R_FRV_GOT12
));
3677 unspec_got_name (int i
)
3681 case R_FRV_GOT12
: return "got12";
3682 case R_FRV_GOTHI
: return "gothi";
3683 case R_FRV_GOTLO
: return "gotlo";
3684 case R_FRV_FUNCDESC
: return "funcdesc";
3685 case R_FRV_FUNCDESC_GOT12
: return "gotfuncdesc12";
3686 case R_FRV_FUNCDESC_GOTHI
: return "gotfuncdeschi";
3687 case R_FRV_FUNCDESC_GOTLO
: return "gotfuncdesclo";
3688 case R_FRV_FUNCDESC_VALUE
: return "funcdescvalue";
3689 case R_FRV_FUNCDESC_GOTOFF12
: return "gotofffuncdesc12";
3690 case R_FRV_FUNCDESC_GOTOFFHI
: return "gotofffuncdeschi";
3691 case R_FRV_FUNCDESC_GOTOFFLO
: return "gotofffuncdesclo";
3692 case R_FRV_GOTOFF12
: return "gotoff12";
3693 case R_FRV_GOTOFFHI
: return "gotoffhi";
3694 case R_FRV_GOTOFFLO
: return "gotofflo";
3695 case R_FRV_GPREL12
: return "gprel12";
3696 case R_FRV_GPRELHI
: return "gprelhi";
3697 case R_FRV_GPRELLO
: return "gprello";
3698 case R_FRV_GOTTLSOFF_HI
: return "gottlsoffhi";
3699 case R_FRV_GOTTLSOFF_LO
: return "gottlsofflo";
3700 case R_FRV_TLSMOFFHI
: return "tlsmoffhi";
3701 case R_FRV_TLSMOFFLO
: return "tlsmofflo";
3702 case R_FRV_TLSMOFF12
: return "tlsmoff12";
3703 case R_FRV_TLSDESCHI
: return "tlsdeschi";
3704 case R_FRV_TLSDESCLO
: return "tlsdesclo";
3705 case R_FRV_GOTTLSDESCHI
: return "gottlsdeschi";
3706 case R_FRV_GOTTLSDESCLO
: return "gottlsdesclo";
3707 default: gcc_unreachable ();
3711 /* Write the assembler syntax for UNSPEC to STREAM. Note that any offset
3712 is added inside the relocation operator. */
3715 frv_output_const_unspec (FILE *stream
, const struct frv_unspec
*unspec
)
3717 fprintf (stream
, "#%s(", unspec_got_name (unspec
->reloc
));
3718 output_addr_const (stream
, plus_constant (Pmode
, unspec
->symbol
,
3720 fputs (")", stream
);
3723 /* Implement FIND_BASE_TERM. See whether ORIG_X represents #gprel12(foo)
3724 or #gotoff12(foo) for some small data symbol foo. If so, return foo,
3725 otherwise return ORIG_X. */
3728 frv_find_base_term (rtx x
)
3730 struct frv_unspec unspec
;
3732 if (frv_const_unspec_p (x
, &unspec
)
3733 && frv_small_data_reloc_p (unspec
.symbol
, unspec
.reloc
))
3734 return plus_constant (Pmode
, unspec
.symbol
, unspec
.offset
);
3739 /* Return 1 if operand is a valid FRV address. CONDEXEC_P is true if
3740 the operand is used by a predicated instruction. */
3743 frv_legitimate_memory_operand (rtx op
, machine_mode mode
, int condexec_p
)
3745 return ((GET_MODE (op
) == mode
|| mode
== VOIDmode
)
3746 && GET_CODE (op
) == MEM
3747 && frv_legitimate_address_p_1 (mode
, XEXP (op
, 0),
3748 reload_completed
, condexec_p
, FALSE
));
3752 frv_expand_fdpic_call (rtx
*operands
, bool ret_value
, bool sibcall
)
3754 rtx lr
= gen_rtx_REG (Pmode
, LR_REGNO
);
3755 rtx picreg
= get_hard_reg_initial_val (SImode
, FDPIC_REG
);
3761 rvrtx
= operands
[0];
3765 addr
= XEXP (operands
[0], 0);
3767 /* Inline PLTs if we're optimizing for speed. We'd like to inline
3768 any calls that would involve a PLT, but can't tell, since we
3769 don't know whether an extern function is going to be provided by
3770 a separate translation unit or imported from a separate module.
3771 When compiling for shared libraries, if the function has default
3772 visibility, we assume it's overridable, so we inline the PLT, but
3773 for executables, we don't really have a way to make a good
3774 decision: a function is as likely to be imported from a shared
3775 library as it is to be defined in the executable itself. We
3776 assume executables will get global functions defined locally,
3777 whereas shared libraries will have them potentially overridden,
3778 so we only inline PLTs when compiling for shared libraries.
3780 In order to mark a function as local to a shared library, any
3781 non-default visibility attribute suffices. Unfortunately,
3782 there's no simple way to tag a function declaration as ``in a
3783 different module'', which we could then use to trigger PLT
3784 inlining on executables. There's -minline-plt, but it affects
3785 all external functions, so one would have to also mark function
3786 declarations available in the same module with non-default
3787 visibility, which is advantageous in itself. */
3788 if (GET_CODE (addr
) == SYMBOL_REF
3789 && ((!SYMBOL_REF_LOCAL_P (addr
) && TARGET_INLINE_PLT
)
3793 dest
= gen_reg_rtx (SImode
);
3795 x
= gen_symGOTOFF2reg_hilo (dest
, addr
, OUR_FDPIC_REG
,
3796 GEN_INT (R_FRV_FUNCDESC_GOTOFF12
));
3798 x
= gen_symGOTOFF2reg (dest
, addr
, OUR_FDPIC_REG
,
3799 GEN_INT (R_FRV_FUNCDESC_GOTOFF12
));
3801 crtl
->uses_pic_offset_table
= TRUE
;
3804 else if (GET_CODE (addr
) == SYMBOL_REF
)
3806 /* These are always either local, or handled through a local
3809 c
= gen_call_value_fdpicsi (rvrtx
, addr
, operands
[1],
3810 operands
[2], picreg
, lr
);
3812 c
= gen_call_fdpicsi (addr
, operands
[1], operands
[2], picreg
, lr
);
3816 else if (! ldd_address_operand (addr
, Pmode
))
3817 addr
= force_reg (Pmode
, addr
);
3819 picreg
= gen_reg_rtx (DImode
);
3820 emit_insn (gen_movdi_ldd (picreg
, addr
));
3822 if (sibcall
&& ret_value
)
3823 c
= gen_sibcall_value_fdpicdi (rvrtx
, picreg
, const0_rtx
);
3825 c
= gen_sibcall_fdpicdi (picreg
, const0_rtx
);
3827 c
= gen_call_value_fdpicdi (rvrtx
, picreg
, const0_rtx
, lr
);
3829 c
= gen_call_fdpicdi (picreg
, const0_rtx
, lr
);
3833 /* Look for a SYMBOL_REF of a function in an rtx. We always want to
3834 process these separately from any offsets, such that we add any
3835 offsets to the function descriptor (the actual pointer), not to the
3836 function address. */
3839 frv_function_symbol_referenced_p (rtx x
)
3845 if (GET_CODE (x
) == SYMBOL_REF
)
3846 return SYMBOL_REF_FUNCTION_P (x
);
3848 length
= GET_RTX_LENGTH (GET_CODE (x
));
3849 format
= GET_RTX_FORMAT (GET_CODE (x
));
3851 for (j
= 0; j
< length
; ++j
)
3856 if (frv_function_symbol_referenced_p (XEXP (x
, j
)))
3862 if (XVEC (x
, j
) != 0)
3865 for (k
= 0; k
< XVECLEN (x
, j
); ++k
)
3866 if (frv_function_symbol_referenced_p (XVECEXP (x
, j
, k
)))
3872 /* Nothing to do. */
3880 /* Return true if the memory operand is one that can be conditionally
3884 condexec_memory_operand (rtx op
, machine_mode mode
)
3886 machine_mode op_mode
= GET_MODE (op
);
3889 if (mode
!= VOIDmode
&& op_mode
!= mode
)
3904 if (GET_CODE (op
) != MEM
)
3907 addr
= XEXP (op
, 0);
3908 return frv_legitimate_address_p_1 (mode
, addr
, reload_completed
, TRUE
, FALSE
);
3911 /* Return true if the bare return instruction can be used outside of the
3912 epilog code. For frv, we only do it if there was no stack allocation. */
3915 direct_return_p (void)
3919 if (!reload_completed
)
3922 info
= frv_stack_info ();
3923 return (info
->total_size
== 0);
3928 frv_emit_move (machine_mode mode
, rtx dest
, rtx src
)
3930 if (GET_CODE (src
) == SYMBOL_REF
)
3932 enum tls_model model
= SYMBOL_REF_TLS_MODEL (src
);
3934 src
= frv_legitimize_tls_address (src
, model
);
3940 if (frv_emit_movsi (dest
, src
))
3949 if (!reload_in_progress
3950 && !reload_completed
3951 && !register_operand (dest
, mode
)
3952 && !reg_or_0_operand (src
, mode
))
3953 src
= copy_to_mode_reg (mode
, src
);
3960 emit_insn (gen_rtx_SET (dest
, src
));
3963 /* Emit code to handle a MOVSI, adding in the small data register or pic
3964 register if needed to load up addresses. Return TRUE if the appropriate
3965 instructions are emitted. */
3968 frv_emit_movsi (rtx dest
, rtx src
)
3970 int base_regno
= -1;
3973 struct frv_unspec old_unspec
;
3975 if (!reload_in_progress
3976 && !reload_completed
3977 && !register_operand (dest
, SImode
)
3978 && (!reg_or_0_operand (src
, SImode
)
3979 /* Virtual registers will almost always be replaced by an
3980 add instruction, so expose this to CSE by copying to
3981 an intermediate register. */
3982 || (GET_CODE (src
) == REG
3983 && IN_RANGE (REGNO (src
),
3984 FIRST_VIRTUAL_REGISTER
,
3985 LAST_VIRTUAL_POINTER_REGISTER
))))
3987 emit_insn (gen_rtx_SET (dest
, copy_to_mode_reg (SImode
, src
)));
3991 /* Explicitly add in the PIC or small data register if needed. */
3992 switch (GET_CODE (src
))
4001 /* Using GPREL12, we use a single GOT entry for all symbols
4002 in read-only sections, but trade sequences such as:
4004 sethi #gothi(label), gr#
4005 setlo #gotlo(label), gr#
4010 ld @(gr15,#got12(_gp)), gr#
4011 sethi #gprelhi(label), gr##
4012 setlo #gprello(label), gr##
4015 We may often be able to share gr# for multiple
4016 computations of GPREL addresses, and we may often fold
4017 the final add into the pair of registers of a load or
4018 store instruction, so it's often profitable. Even when
4019 optimizing for size, we're trading a GOT entry for an
4020 additional instruction, which trades GOT space
4021 (read-write) for code size (read-only, shareable), as
4022 long as the symbol is not used in more than two different
4025 With -fpie/-fpic, we'd be trading a single load for a
4026 sequence of 4 instructions, because the offset of the
4027 label can't be assumed to be addressable with 12 bits, so
4028 we don't do this. */
4029 if (TARGET_GPREL_RO
)
4030 unspec
= R_FRV_GPREL12
;
4032 unspec
= R_FRV_GOT12
;
4035 base_regno
= PIC_REGNO
;
4040 if (frv_const_unspec_p (src
, &old_unspec
))
4043 if (TARGET_FDPIC
&& frv_function_symbol_referenced_p (XEXP (src
, 0)))
4046 src
= force_reg (GET_MODE (XEXP (src
, 0)), XEXP (src
, 0));
4047 emit_move_insn (dest
, src
);
4052 sym
= XEXP (sym
, 0);
4053 if (GET_CODE (sym
) == PLUS
4054 && GET_CODE (XEXP (sym
, 0)) == SYMBOL_REF
4055 && GET_CODE (XEXP (sym
, 1)) == CONST_INT
)
4056 sym
= XEXP (sym
, 0);
4057 if (GET_CODE (sym
) == SYMBOL_REF
)
4059 else if (GET_CODE (sym
) == LABEL_REF
)
4062 goto handle_whatever
;
4070 enum tls_model model
= SYMBOL_REF_TLS_MODEL (sym
);
4074 src
= frv_legitimize_tls_address (src
, model
);
4075 emit_move_insn (dest
, src
);
4079 if (SYMBOL_REF_FUNCTION_P (sym
))
4081 if (frv_local_funcdesc_p (sym
))
4082 unspec
= R_FRV_FUNCDESC_GOTOFF12
;
4084 unspec
= R_FRV_FUNCDESC_GOT12
;
4088 if (CONSTANT_POOL_ADDRESS_P (sym
))
4089 switch (GET_CODE (get_pool_constant (sym
)))
4096 unspec
= R_FRV_GOTOFF12
;
4101 if (TARGET_GPREL_RO
)
4102 unspec
= R_FRV_GPREL12
;
4104 unspec
= R_FRV_GOT12
;
4107 else if (SYMBOL_REF_LOCAL_P (sym
)
4108 && !SYMBOL_REF_EXTERNAL_P (sym
)
4109 && SYMBOL_REF_DECL (sym
)
4110 && (!DECL_P (SYMBOL_REF_DECL (sym
))
4111 || !DECL_COMMON (SYMBOL_REF_DECL (sym
))))
4113 tree decl
= SYMBOL_REF_DECL (sym
);
4114 tree init
= TREE_CODE (decl
) == VAR_DECL
4115 ? DECL_INITIAL (decl
)
4116 : TREE_CODE (decl
) == CONSTRUCTOR
4119 bool named_section
, readonly
;
4121 if (init
&& init
!= error_mark_node
)
4122 reloc
= compute_reloc_for_constant (init
);
4124 named_section
= TREE_CODE (decl
) == VAR_DECL
4125 && lookup_attribute ("section", DECL_ATTRIBUTES (decl
));
4126 readonly
= decl_readonly_section (decl
, reloc
);
4129 unspec
= R_FRV_GOT12
;
4131 unspec
= R_FRV_GOTOFF12
;
4132 else if (readonly
&& TARGET_GPREL_RO
)
4133 unspec
= R_FRV_GPREL12
;
4135 unspec
= R_FRV_GOT12
;
4138 unspec
= R_FRV_GOT12
;
4142 else if (SYMBOL_REF_SMALL_P (sym
))
4143 base_regno
= SDA_BASE_REG
;
4146 base_regno
= PIC_REGNO
;
4151 if (base_regno
>= 0)
4153 if (GET_CODE (sym
) == SYMBOL_REF
&& SYMBOL_REF_SMALL_P (sym
))
4154 emit_insn (gen_symGOTOFF2reg (dest
, src
,
4155 gen_rtx_REG (Pmode
, base_regno
),
4156 GEN_INT (R_FRV_GPREL12
)));
4158 emit_insn (gen_symGOTOFF2reg_hilo (dest
, src
,
4159 gen_rtx_REG (Pmode
, base_regno
),
4160 GEN_INT (R_FRV_GPREL12
)));
4161 if (base_regno
== PIC_REGNO
)
4162 crtl
->uses_pic_offset_table
= TRUE
;
4170 /* Since OUR_FDPIC_REG is a pseudo register, we can't safely introduce
4171 new uses of it once reload has begun. */
4172 gcc_assert (!reload_in_progress
&& !reload_completed
);
4176 case R_FRV_GOTOFF12
:
4177 if (!frv_small_data_reloc_p (sym
, unspec
))
4178 x
= gen_symGOTOFF2reg_hilo (dest
, src
, OUR_FDPIC_REG
,
4181 x
= gen_symGOTOFF2reg (dest
, src
, OUR_FDPIC_REG
, GEN_INT (unspec
));
4184 if (!frv_small_data_reloc_p (sym
, unspec
))
4185 x
= gen_symGPREL2reg_hilo (dest
, src
, OUR_FDPIC_REG
,
4188 x
= gen_symGPREL2reg (dest
, src
, OUR_FDPIC_REG
, GEN_INT (unspec
));
4190 case R_FRV_FUNCDESC_GOTOFF12
:
4192 x
= gen_symGOTOFF2reg_hilo (dest
, src
, OUR_FDPIC_REG
,
4195 x
= gen_symGOTOFF2reg (dest
, src
, OUR_FDPIC_REG
, GEN_INT (unspec
));
4199 x
= gen_symGOT2reg_hilo (dest
, src
, OUR_FDPIC_REG
,
4202 x
= gen_symGOT2reg (dest
, src
, OUR_FDPIC_REG
, GEN_INT (unspec
));
4206 crtl
->uses_pic_offset_table
= TRUE
;
4215 /* Return a string to output a single word move. */
4218 output_move_single (rtx operands
[], rtx insn
)
4220 rtx dest
= operands
[0];
4221 rtx src
= operands
[1];
4223 if (GET_CODE (dest
) == REG
)
4225 int dest_regno
= REGNO (dest
);
4226 machine_mode mode
= GET_MODE (dest
);
4228 if (GPR_P (dest_regno
))
4230 if (GET_CODE (src
) == REG
)
4232 /* gpr <- some sort of register */
4233 int src_regno
= REGNO (src
);
4235 if (GPR_P (src_regno
))
4236 return "mov %1, %0";
4238 else if (FPR_P (src_regno
))
4239 return "movfg %1, %0";
4241 else if (SPR_P (src_regno
))
4242 return "movsg %1, %0";
4245 else if (GET_CODE (src
) == MEM
)
4254 return "ldsb%I1%U1 %M1,%0";
4257 return "ldsh%I1%U1 %M1,%0";
4261 return "ld%I1%U1 %M1, %0";
4265 else if (GET_CODE (src
) == CONST_INT
4266 || GET_CODE (src
) == CONST_DOUBLE
)
4268 /* gpr <- integer/floating constant */
4269 HOST_WIDE_INT value
;
4271 if (GET_CODE (src
) == CONST_INT
)
4272 value
= INTVAL (src
);
4274 else if (mode
== SFmode
)
4278 REAL_VALUE_TO_TARGET_SINGLE
4279 (*CONST_DOUBLE_REAL_VALUE (src
), l
);
4284 value
= CONST_DOUBLE_LOW (src
);
4286 if (IN_RANGE (value
, -32768, 32767))
4287 return "setlos %1, %0";
4292 else if (GET_CODE (src
) == SYMBOL_REF
4293 || GET_CODE (src
) == LABEL_REF
4294 || GET_CODE (src
) == CONST
)
4300 else if (FPR_P (dest_regno
))
4302 if (GET_CODE (src
) == REG
)
4304 /* fpr <- some sort of register */
4305 int src_regno
= REGNO (src
);
4307 if (GPR_P (src_regno
))
4308 return "movgf %1, %0";
4310 else if (FPR_P (src_regno
))
4312 if (TARGET_HARD_FLOAT
)
4313 return "fmovs %1, %0";
4315 return "mor %1, %1, %0";
4319 else if (GET_CODE (src
) == MEM
)
4328 return "ldbf%I1%U1 %M1,%0";
4331 return "ldhf%I1%U1 %M1,%0";
4335 return "ldf%I1%U1 %M1, %0";
4339 else if (ZERO_P (src
))
4340 return "movgf %., %0";
4343 else if (SPR_P (dest_regno
))
4345 if (GET_CODE (src
) == REG
)
4347 /* spr <- some sort of register */
4348 int src_regno
= REGNO (src
);
4350 if (GPR_P (src_regno
))
4351 return "movgs %1, %0";
4353 else if (ZERO_P (src
))
4354 return "movgs %., %0";
4358 else if (GET_CODE (dest
) == MEM
)
4360 if (GET_CODE (src
) == REG
)
4362 int src_regno
= REGNO (src
);
4363 machine_mode mode
= GET_MODE (dest
);
4365 if (GPR_P (src_regno
))
4373 return "stb%I0%U0 %1, %M0";
4376 return "sth%I0%U0 %1, %M0";
4380 return "st%I0%U0 %1, %M0";
4384 else if (FPR_P (src_regno
))
4392 return "stbf%I0%U0 %1, %M0";
4395 return "sthf%I0%U0 %1, %M0";
4399 return "stf%I0%U0 %1, %M0";
4404 else if (ZERO_P (src
))
4406 switch (GET_MODE (dest
))
4412 return "stb%I0%U0 %., %M0";
4415 return "sth%I0%U0 %., %M0";
4419 return "st%I0%U0 %., %M0";
4424 fatal_insn ("bad output_move_single operand", insn
);
4429 /* Return a string to output a double word move. */
4432 output_move_double (rtx operands
[], rtx insn
)
4434 rtx dest
= operands
[0];
4435 rtx src
= operands
[1];
4436 machine_mode mode
= GET_MODE (dest
);
4438 if (GET_CODE (dest
) == REG
)
4440 int dest_regno
= REGNO (dest
);
4442 if (GPR_P (dest_regno
))
4444 if (GET_CODE (src
) == REG
)
4446 /* gpr <- some sort of register */
4447 int src_regno
= REGNO (src
);
4449 if (GPR_P (src_regno
))
4452 else if (FPR_P (src_regno
))
4454 if (((dest_regno
- GPR_FIRST
) & 1) == 0
4455 && ((src_regno
- FPR_FIRST
) & 1) == 0)
4456 return "movfgd %1, %0";
4462 else if (GET_CODE (src
) == MEM
)
4465 if (dbl_memory_one_insn_operand (src
, mode
))
4466 return "ldd%I1%U1 %M1, %0";
4471 else if (GET_CODE (src
) == CONST_INT
4472 || GET_CODE (src
) == CONST_DOUBLE
)
4476 else if (FPR_P (dest_regno
))
4478 if (GET_CODE (src
) == REG
)
4480 /* fpr <- some sort of register */
4481 int src_regno
= REGNO (src
);
4483 if (GPR_P (src_regno
))
4485 if (((dest_regno
- FPR_FIRST
) & 1) == 0
4486 && ((src_regno
- GPR_FIRST
) & 1) == 0)
4487 return "movgfd %1, %0";
4492 else if (FPR_P (src_regno
))
4495 && ((dest_regno
- FPR_FIRST
) & 1) == 0
4496 && ((src_regno
- FPR_FIRST
) & 1) == 0)
4497 return "fmovd %1, %0";
4503 else if (GET_CODE (src
) == MEM
)
4506 if (dbl_memory_one_insn_operand (src
, mode
))
4507 return "lddf%I1%U1 %M1, %0";
4512 else if (ZERO_P (src
))
4517 else if (GET_CODE (dest
) == MEM
)
4519 if (GET_CODE (src
) == REG
)
4521 int src_regno
= REGNO (src
);
4523 if (GPR_P (src_regno
))
4525 if (((src_regno
- GPR_FIRST
) & 1) == 0
4526 && dbl_memory_one_insn_operand (dest
, mode
))
4527 return "std%I0%U0 %1, %M0";
4532 if (FPR_P (src_regno
))
4534 if (((src_regno
- FPR_FIRST
) & 1) == 0
4535 && dbl_memory_one_insn_operand (dest
, mode
))
4536 return "stdf%I0%U0 %1, %M0";
4542 else if (ZERO_P (src
))
4544 if (dbl_memory_one_insn_operand (dest
, mode
))
4545 return "std%I0%U0 %., %M0";
4551 fatal_insn ("bad output_move_double operand", insn
);
4556 /* Return a string to output a single word conditional move.
4557 Operand0 -- EQ/NE of ccr register and 0
4558 Operand1 -- CCR register
4559 Operand2 -- destination
4560 Operand3 -- source */
4563 output_condmove_single (rtx operands
[], rtx insn
)
4565 rtx dest
= operands
[2];
4566 rtx src
= operands
[3];
4568 if (GET_CODE (dest
) == REG
)
4570 int dest_regno
= REGNO (dest
);
4571 machine_mode mode
= GET_MODE (dest
);
4573 if (GPR_P (dest_regno
))
4575 if (GET_CODE (src
) == REG
)
4577 /* gpr <- some sort of register */
4578 int src_regno
= REGNO (src
);
4580 if (GPR_P (src_regno
))
4581 return "cmov %z3, %2, %1, %e0";
4583 else if (FPR_P (src_regno
))
4584 return "cmovfg %3, %2, %1, %e0";
4587 else if (GET_CODE (src
) == MEM
)
4596 return "cldsb%I3%U3 %M3, %2, %1, %e0";
4599 return "cldsh%I3%U3 %M3, %2, %1, %e0";
4603 return "cld%I3%U3 %M3, %2, %1, %e0";
4607 else if (ZERO_P (src
))
4608 return "cmov %., %2, %1, %e0";
4611 else if (FPR_P (dest_regno
))
4613 if (GET_CODE (src
) == REG
)
4615 /* fpr <- some sort of register */
4616 int src_regno
= REGNO (src
);
4618 if (GPR_P (src_regno
))
4619 return "cmovgf %3, %2, %1, %e0";
4621 else if (FPR_P (src_regno
))
4623 if (TARGET_HARD_FLOAT
)
4624 return "cfmovs %3,%2,%1,%e0";
4626 return "cmor %3, %3, %2, %1, %e0";
4630 else if (GET_CODE (src
) == MEM
)
4633 if (mode
== SImode
|| mode
== SFmode
)
4634 return "cldf%I3%U3 %M3, %2, %1, %e0";
4637 else if (ZERO_P (src
))
4638 return "cmovgf %., %2, %1, %e0";
4642 else if (GET_CODE (dest
) == MEM
)
4644 if (GET_CODE (src
) == REG
)
4646 int src_regno
= REGNO (src
);
4647 machine_mode mode
= GET_MODE (dest
);
4649 if (GPR_P (src_regno
))
4657 return "cstb%I2%U2 %3, %M2, %1, %e0";
4660 return "csth%I2%U2 %3, %M2, %1, %e0";
4664 return "cst%I2%U2 %3, %M2, %1, %e0";
4668 else if (FPR_P (src_regno
) && (mode
== SImode
|| mode
== SFmode
))
4669 return "cstf%I2%U2 %3, %M2, %1, %e0";
4672 else if (ZERO_P (src
))
4674 machine_mode mode
= GET_MODE (dest
);
4681 return "cstb%I2%U2 %., %M2, %1, %e0";
4684 return "csth%I2%U2 %., %M2, %1, %e0";
4688 return "cst%I2%U2 %., %M2, %1, %e0";
4693 fatal_insn ("bad output_condmove_single operand", insn
);
4698 /* Emit the appropriate code to do a comparison, returning the register the
4699 comparison was done it. */
4702 frv_emit_comparison (enum rtx_code test
, rtx op0
, rtx op1
)
4704 machine_mode cc_mode
;
4707 /* Floating point doesn't have comparison against a constant. */
4708 if (GET_MODE (op0
) == CC_FPmode
&& GET_CODE (op1
) != REG
)
4709 op1
= force_reg (GET_MODE (op0
), op1
);
4711 /* Possibly disable using anything but a fixed register in order to work
4712 around cse moving comparisons past function calls. */
4713 cc_mode
= SELECT_CC_MODE (test
, op0
, op1
);
4714 cc_reg
= ((TARGET_ALLOC_CC
)
4715 ? gen_reg_rtx (cc_mode
)
4716 : gen_rtx_REG (cc_mode
,
4717 (cc_mode
== CC_FPmode
) ? FCC_FIRST
: ICC_FIRST
));
4719 emit_insn (gen_rtx_SET (cc_reg
, gen_rtx_COMPARE (cc_mode
, op0
, op1
)));
4725 /* Emit code for a conditional branch.
4726 XXX: I originally wanted to add a clobber of a CCR register to use in
4727 conditional execution, but that confuses the rest of the compiler. */
4730 frv_emit_cond_branch (rtx operands
[])
4735 enum rtx_code test
= GET_CODE (operands
[0]);
4736 rtx cc_reg
= frv_emit_comparison (test
, operands
[1], operands
[2]);
4737 machine_mode cc_mode
= GET_MODE (cc_reg
);
4739 /* Branches generate:
4741 (if_then_else (<test>, <cc_reg>, (const_int 0))
4742 (label_ref <branch_label>)
4744 label_ref
= gen_rtx_LABEL_REF (VOIDmode
, operands
[3]);
4745 test_rtx
= gen_rtx_fmt_ee (test
, cc_mode
, cc_reg
, const0_rtx
);
4746 if_else
= gen_rtx_IF_THEN_ELSE (cc_mode
, test_rtx
, label_ref
, pc_rtx
);
4747 emit_jump_insn (gen_rtx_SET (pc_rtx
, if_else
));
4752 /* Emit code to set a gpr to 1/0 based on a comparison. */
4755 frv_emit_scc (rtx operands
[])
4761 enum rtx_code test
= GET_CODE (operands
[1]);
4762 rtx cc_reg
= frv_emit_comparison (test
, operands
[2], operands
[3]);
4764 /* SCC instructions generate:
4765 (parallel [(set <target> (<test>, <cc_reg>, (const_int 0))
4766 (clobber (<ccr_reg>))]) */
4767 test_rtx
= gen_rtx_fmt_ee (test
, SImode
, cc_reg
, const0_rtx
);
4768 set
= gen_rtx_SET (operands
[0], test_rtx
);
4770 cr_reg
= ((TARGET_ALLOC_CC
)
4771 ? gen_reg_rtx (CC_CCRmode
)
4772 : gen_rtx_REG (CC_CCRmode
,
4773 ((GET_MODE (cc_reg
) == CC_FPmode
)
4777 clobber
= gen_rtx_CLOBBER (VOIDmode
, cr_reg
);
4778 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, set
, clobber
)));
4783 /* Split a SCC instruction into component parts, returning a SEQUENCE to hold
4784 the separate insns. */
4787 frv_split_scc (rtx dest
, rtx test
, rtx cc_reg
, rtx cr_reg
, HOST_WIDE_INT value
)
4793 /* Set the appropriate CCR bit. */
4794 emit_insn (gen_rtx_SET (cr_reg
,
4795 gen_rtx_fmt_ee (GET_CODE (test
),
4800 /* Move the value into the destination. */
4801 emit_move_insn (dest
, GEN_INT (value
));
4803 /* Move 0 into the destination if the test failed */
4804 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
4805 gen_rtx_EQ (GET_MODE (cr_reg
),
4808 gen_rtx_SET (dest
, const0_rtx
)));
4810 /* Finish up, return sequence. */
4817 /* Emit the code for a conditional move, return TRUE if we could do the
4821 frv_emit_cond_move (rtx dest
, rtx test_rtx
, rtx src1
, rtx src2
)
4828 enum rtx_code test
= GET_CODE (test_rtx
);
4829 rtx cc_reg
= frv_emit_comparison (test
,
4830 XEXP (test_rtx
, 0), XEXP (test_rtx
, 1));
4831 machine_mode cc_mode
= GET_MODE (cc_reg
);
4833 /* Conditional move instructions generate:
4834 (parallel [(set <target>
4835 (if_then_else (<test> <cc_reg> (const_int 0))
4838 (clobber (<ccr_reg>))]) */
4840 /* Handle various cases of conditional move involving two constants. */
4841 if (GET_CODE (src1
) == CONST_INT
&& GET_CODE (src2
) == CONST_INT
)
4843 HOST_WIDE_INT value1
= INTVAL (src1
);
4844 HOST_WIDE_INT value2
= INTVAL (src2
);
4846 /* Having 0 as one of the constants can be done by loading the other
4847 constant, and optionally moving in gr0. */
4848 if (value1
== 0 || value2
== 0)
4851 /* If the first value is within an addi range and also the difference
4852 between the two fits in an addi's range, load up the difference, then
4853 conditionally move in 0, and then unconditionally add the first
4855 else if (IN_RANGE (value1
, -2048, 2047)
4856 && IN_RANGE (value2
- value1
, -2048, 2047))
4859 /* If neither condition holds, just force the constant into a
4863 src1
= force_reg (GET_MODE (dest
), src1
);
4864 src2
= force_reg (GET_MODE (dest
), src2
);
4868 /* If one value is a register, insure the other value is either 0 or a
4872 if (GET_CODE (src1
) == CONST_INT
&& INTVAL (src1
) != 0)
4873 src1
= force_reg (GET_MODE (dest
), src1
);
4875 if (GET_CODE (src2
) == CONST_INT
&& INTVAL (src2
) != 0)
4876 src2
= force_reg (GET_MODE (dest
), src2
);
4879 test2
= gen_rtx_fmt_ee (test
, cc_mode
, cc_reg
, const0_rtx
);
4880 if_rtx
= gen_rtx_IF_THEN_ELSE (GET_MODE (dest
), test2
, src1
, src2
);
4882 set
= gen_rtx_SET (dest
, if_rtx
);
4884 cr_reg
= ((TARGET_ALLOC_CC
)
4885 ? gen_reg_rtx (CC_CCRmode
)
4886 : gen_rtx_REG (CC_CCRmode
,
4887 (cc_mode
== CC_FPmode
) ? FCR_FIRST
: ICR_FIRST
));
4889 clobber_cc
= gen_rtx_CLOBBER (VOIDmode
, cr_reg
);
4890 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, set
, clobber_cc
)));
4895 /* Split a conditional move into constituent parts, returning a SEQUENCE
4896 containing all of the insns. */
4899 frv_split_cond_move (rtx operands
[])
4901 rtx dest
= operands
[0];
4902 rtx test
= operands
[1];
4903 rtx cc_reg
= operands
[2];
4904 rtx src1
= operands
[3];
4905 rtx src2
= operands
[4];
4906 rtx cr_reg
= operands
[5];
4908 machine_mode cr_mode
= GET_MODE (cr_reg
);
4912 /* Set the appropriate CCR bit. */
4913 emit_insn (gen_rtx_SET (cr_reg
,
4914 gen_rtx_fmt_ee (GET_CODE (test
),
4919 /* Handle various cases of conditional move involving two constants. */
4920 if (GET_CODE (src1
) == CONST_INT
&& GET_CODE (src2
) == CONST_INT
)
4922 HOST_WIDE_INT value1
= INTVAL (src1
);
4923 HOST_WIDE_INT value2
= INTVAL (src2
);
4925 /* Having 0 as one of the constants can be done by loading the other
4926 constant, and optionally moving in gr0. */
4929 emit_move_insn (dest
, src2
);
4930 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
4931 gen_rtx_NE (cr_mode
, cr_reg
,
4933 gen_rtx_SET (dest
, src1
)));
4936 else if (value2
== 0)
4938 emit_move_insn (dest
, src1
);
4939 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
4940 gen_rtx_EQ (cr_mode
, cr_reg
,
4942 gen_rtx_SET (dest
, src2
)));
4945 /* If the first value is within an addi range and also the difference
4946 between the two fits in an addi's range, load up the difference, then
4947 conditionally move in 0, and then unconditionally add the first
4949 else if (IN_RANGE (value1
, -2048, 2047)
4950 && IN_RANGE (value2
- value1
, -2048, 2047))
4952 rtx dest_si
= ((GET_MODE (dest
) == SImode
)
4954 : gen_rtx_SUBREG (SImode
, dest
, 0));
4956 emit_move_insn (dest_si
, GEN_INT (value2
- value1
));
4957 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
4958 gen_rtx_NE (cr_mode
, cr_reg
,
4960 gen_rtx_SET (dest_si
, const0_rtx
)));
4961 emit_insn (gen_addsi3 (dest_si
, dest_si
, src1
));
4969 /* Emit the conditional move for the test being true if needed. */
4970 if (! rtx_equal_p (dest
, src1
))
4971 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
4972 gen_rtx_NE (cr_mode
, cr_reg
, const0_rtx
),
4973 gen_rtx_SET (dest
, src1
)));
4975 /* Emit the conditional move for the test being false if needed. */
4976 if (! rtx_equal_p (dest
, src2
))
4977 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
4978 gen_rtx_EQ (cr_mode
, cr_reg
, const0_rtx
),
4979 gen_rtx_SET (dest
, src2
)));
4982 /* Finish up, return sequence. */
4989 /* Split (set DEST SOURCE), where DEST is a double register and SOURCE is a
4990 memory location that is not known to be dword-aligned. */
4992 frv_split_double_load (rtx dest
, rtx source
)
4994 int regno
= REGNO (dest
);
4995 rtx dest1
= gen_highpart (SImode
, dest
);
4996 rtx dest2
= gen_lowpart (SImode
, dest
);
4997 rtx address
= XEXP (source
, 0);
4999 /* If the address is pre-modified, load the lower-numbered register
5000 first, then load the other register using an integer offset from
5001 the modified base register. This order should always be safe,
5002 since the pre-modification cannot affect the same registers as the
5005 The situation for other loads is more complicated. Loading one
5006 of the registers could affect the value of ADDRESS, so we must
5007 be careful which order we do them in. */
5008 if (GET_CODE (address
) == PRE_MODIFY
5009 || ! refers_to_regno_p (regno
, address
))
5011 /* It is safe to load the lower-numbered register first. */
5012 emit_move_insn (dest1
, change_address (source
, SImode
, NULL
));
5013 emit_move_insn (dest2
, frv_index_memory (source
, SImode
, 1));
5017 /* ADDRESS is not pre-modified and the address depends on the
5018 lower-numbered register. Load the higher-numbered register
5020 emit_move_insn (dest2
, frv_index_memory (source
, SImode
, 1));
5021 emit_move_insn (dest1
, change_address (source
, SImode
, NULL
));
5025 /* Split (set DEST SOURCE), where DEST refers to a dword memory location
5026 and SOURCE is either a double register or the constant zero. */
5028 frv_split_double_store (rtx dest
, rtx source
)
5030 rtx dest1
= change_address (dest
, SImode
, NULL
);
5031 rtx dest2
= frv_index_memory (dest
, SImode
, 1);
5032 if (ZERO_P (source
))
5034 emit_move_insn (dest1
, CONST0_RTX (SImode
));
5035 emit_move_insn (dest2
, CONST0_RTX (SImode
));
5039 emit_move_insn (dest1
, gen_highpart (SImode
, source
));
5040 emit_move_insn (dest2
, gen_lowpart (SImode
, source
));
5045 /* Split a min/max operation returning a SEQUENCE containing all of the
5049 frv_split_minmax (rtx operands
[])
5051 rtx dest
= operands
[0];
5052 rtx minmax
= operands
[1];
5053 rtx src1
= operands
[2];
5054 rtx src2
= operands
[3];
5055 rtx cc_reg
= operands
[4];
5056 rtx cr_reg
= operands
[5];
5058 enum rtx_code test_code
;
5059 machine_mode cr_mode
= GET_MODE (cr_reg
);
5063 /* Figure out which test to use. */
5064 switch (GET_CODE (minmax
))
5069 case SMIN
: test_code
= LT
; break;
5070 case SMAX
: test_code
= GT
; break;
5071 case UMIN
: test_code
= LTU
; break;
5072 case UMAX
: test_code
= GTU
; break;
5075 /* Issue the compare instruction. */
5076 emit_insn (gen_rtx_SET (cc_reg
, gen_rtx_COMPARE (GET_MODE (cc_reg
),
5079 /* Set the appropriate CCR bit. */
5080 emit_insn (gen_rtx_SET (cr_reg
, gen_rtx_fmt_ee (test_code
,
5085 /* If are taking the min/max of a nonzero constant, load that first, and
5086 then do a conditional move of the other value. */
5087 if (GET_CODE (src2
) == CONST_INT
&& INTVAL (src2
) != 0)
5089 gcc_assert (!rtx_equal_p (dest
, src1
));
5091 emit_move_insn (dest
, src2
);
5092 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
5093 gen_rtx_NE (cr_mode
, cr_reg
, const0_rtx
),
5094 gen_rtx_SET (dest
, src1
)));
5097 /* Otherwise, do each half of the move. */
5100 /* Emit the conditional move for the test being true if needed. */
5101 if (! rtx_equal_p (dest
, src1
))
5102 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
5103 gen_rtx_NE (cr_mode
, cr_reg
, const0_rtx
),
5104 gen_rtx_SET (dest
, src1
)));
5106 /* Emit the conditional move for the test being false if needed. */
5107 if (! rtx_equal_p (dest
, src2
))
5108 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
5109 gen_rtx_EQ (cr_mode
, cr_reg
, const0_rtx
),
5110 gen_rtx_SET (dest
, src2
)));
5113 /* Finish up, return sequence. */
5120 /* Split an integer abs operation returning a SEQUENCE containing all of the
5124 frv_split_abs (rtx operands
[])
5126 rtx dest
= operands
[0];
5127 rtx src
= operands
[1];
5128 rtx cc_reg
= operands
[2];
5129 rtx cr_reg
= operands
[3];
5134 /* Issue the compare < 0 instruction. */
5135 emit_insn (gen_rtx_SET (cc_reg
, gen_rtx_COMPARE (CCmode
, src
, const0_rtx
)));
5137 /* Set the appropriate CCR bit. */
5138 emit_insn (gen_rtx_SET (cr_reg
, gen_rtx_fmt_ee (LT
, CC_CCRmode
,
5139 cc_reg
, const0_rtx
)));
5141 /* Emit the conditional negate if the value is negative. */
5142 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
5143 gen_rtx_NE (CC_CCRmode
, cr_reg
, const0_rtx
),
5144 gen_negsi2 (dest
, src
)));
5146 /* Emit the conditional move for the test being false if needed. */
5147 if (! rtx_equal_p (dest
, src
))
5148 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
5149 gen_rtx_EQ (CC_CCRmode
, cr_reg
, const0_rtx
),
5150 gen_rtx_SET (dest
, src
)));
5152 /* Finish up, return sequence. */
5159 /* Initialize machine-specific if-conversion data.
5160 On the FR-V, we don't have any extra fields per se, but it is useful hook to
5161 initialize the static storage. */
5163 frv_ifcvt_machdep_init (void *ce_info ATTRIBUTE_UNUSED
)
5165 frv_ifcvt
.added_insns_list
= NULL_RTX
;
5166 frv_ifcvt
.cur_scratch_regs
= 0;
5167 frv_ifcvt
.num_nested_cond_exec
= 0;
5168 frv_ifcvt
.cr_reg
= NULL_RTX
;
5169 frv_ifcvt
.nested_cc_reg
= NULL_RTX
;
5170 frv_ifcvt
.extra_int_cr
= NULL_RTX
;
5171 frv_ifcvt
.extra_fp_cr
= NULL_RTX
;
5172 frv_ifcvt
.last_nested_if_cr
= NULL_RTX
;
5176 /* Internal function to add a potential insn to the list of insns to be inserted
5177 if the conditional execution conversion is successful. */
5180 frv_ifcvt_add_insn (rtx pattern
, rtx insn
, int before_p
)
5182 rtx link
= alloc_EXPR_LIST (VOIDmode
, pattern
, insn
);
5184 link
->jump
= before_p
; /* Mark to add this before or after insn. */
5185 frv_ifcvt
.added_insns_list
= alloc_EXPR_LIST (VOIDmode
, link
,
5186 frv_ifcvt
.added_insns_list
);
5188 if (TARGET_DEBUG_COND_EXEC
)
5191 "\n:::::::::: frv_ifcvt_add_insn: add the following %s insn %d:\n",
5192 (before_p
) ? "before" : "after",
5193 (int)INSN_UID (insn
));
5195 debug_rtx (pattern
);
5200 /* A C expression to modify the code described by the conditional if
5201 information CE_INFO, possibly updating the tests in TRUE_EXPR, and
5202 FALSE_EXPR for converting if-then and if-then-else code to conditional
5203 instructions. Set either TRUE_EXPR or FALSE_EXPR to a null pointer if the
5204 tests cannot be converted. */
5207 frv_ifcvt_modify_tests (ce_if_block
*ce_info
, rtx
*p_true
, rtx
*p_false
)
5209 basic_block test_bb
= ce_info
->test_bb
; /* test basic block */
5210 basic_block then_bb
= ce_info
->then_bb
; /* THEN */
5211 basic_block else_bb
= ce_info
->else_bb
; /* ELSE or NULL */
5212 basic_block join_bb
= ce_info
->join_bb
; /* join block or NULL */
5213 rtx true_expr
= *p_true
;
5217 machine_mode mode
= GET_MODE (true_expr
);
5221 frv_tmp_reg_t
*tmp_reg
= &frv_ifcvt
.tmp_reg
;
5223 rtx sub_cond_exec_reg
;
5225 enum rtx_code code_true
;
5226 enum rtx_code code_false
;
5227 enum reg_class cc_class
;
5228 enum reg_class cr_class
;
5231 reg_set_iterator rsi
;
5233 /* Make sure we are only dealing with hard registers. Also honor the
5234 -mno-cond-exec switch, and -mno-nested-cond-exec switches if
5236 if (!reload_completed
|| !TARGET_COND_EXEC
5237 || (!TARGET_NESTED_CE
&& ce_info
->pass
> 1))
5240 /* Figure out which registers we can allocate for our own purposes. Only
5241 consider registers that are not preserved across function calls and are
5242 not fixed. However, allow the ICC/ICR temporary registers to be allocated
5243 if we did not need to use them in reloading other registers. */
5244 memset (&tmp_reg
->regs
, 0, sizeof (tmp_reg
->regs
));
5245 COPY_HARD_REG_SET (tmp_reg
->regs
, call_used_reg_set
);
5246 AND_COMPL_HARD_REG_SET (tmp_reg
->regs
, fixed_reg_set
);
5247 SET_HARD_REG_BIT (tmp_reg
->regs
, ICC_TEMP
);
5248 SET_HARD_REG_BIT (tmp_reg
->regs
, ICR_TEMP
);
5250 /* If this is a nested IF, we need to discover whether the CC registers that
5251 are set/used inside of the block are used anywhere else. If not, we can
5252 change them to be the CC register that is paired with the CR register that
5253 controls the outermost IF block. */
5254 if (ce_info
->pass
> 1)
5256 CLEAR_HARD_REG_SET (frv_ifcvt
.nested_cc_ok_rewrite
);
5257 for (j
= CC_FIRST
; j
<= CC_LAST
; j
++)
5258 if (TEST_HARD_REG_BIT (tmp_reg
->regs
, j
))
5260 if (REGNO_REG_SET_P (df_get_live_in (then_bb
), j
))
5264 && REGNO_REG_SET_P (df_get_live_in (else_bb
), j
))
5268 && REGNO_REG_SET_P (df_get_live_in (join_bb
), j
))
5271 SET_HARD_REG_BIT (frv_ifcvt
.nested_cc_ok_rewrite
, j
);
5275 for (j
= 0; j
< frv_ifcvt
.cur_scratch_regs
; j
++)
5276 frv_ifcvt
.scratch_regs
[j
] = NULL_RTX
;
5278 frv_ifcvt
.added_insns_list
= NULL_RTX
;
5279 frv_ifcvt
.cur_scratch_regs
= 0;
5281 bb
= (basic_block
*) alloca ((2 + ce_info
->num_multiple_test_blocks
)
5282 * sizeof (basic_block
));
5288 /* Remove anything live at the beginning of the join block from being
5289 available for allocation. */
5290 EXECUTE_IF_SET_IN_REG_SET (df_get_live_in (join_bb
), 0, regno
, rsi
)
5292 if (regno
< FIRST_PSEUDO_REGISTER
)
5293 CLEAR_HARD_REG_BIT (tmp_reg
->regs
, regno
);
5297 /* Add in all of the blocks in multiple &&/|| blocks to be scanned. */
5299 if (ce_info
->num_multiple_test_blocks
)
5301 basic_block multiple_test_bb
= ce_info
->last_test_bb
;
5303 while (multiple_test_bb
!= test_bb
)
5305 bb
[num_bb
++] = multiple_test_bb
;
5306 multiple_test_bb
= EDGE_PRED (multiple_test_bb
, 0)->src
;
5310 /* Add in the THEN and ELSE blocks to be scanned. */
5311 bb
[num_bb
++] = then_bb
;
5313 bb
[num_bb
++] = else_bb
;
5315 sub_cond_exec_reg
= NULL_RTX
;
5316 frv_ifcvt
.num_nested_cond_exec
= 0;
5318 /* Scan all of the blocks for registers that must not be allocated. */
5319 for (j
= 0; j
< num_bb
; j
++)
5321 rtx_insn
*last_insn
= BB_END (bb
[j
]);
5322 rtx_insn
*insn
= BB_HEAD (bb
[j
]);
5326 fprintf (dump_file
, "Scanning %s block %d, start %d, end %d\n",
5327 (bb
[j
] == else_bb
) ? "else" : ((bb
[j
] == then_bb
) ? "then" : "test"),
5329 (int) INSN_UID (BB_HEAD (bb
[j
])),
5330 (int) INSN_UID (BB_END (bb
[j
])));
5332 /* Anything live at the beginning of the block is obviously unavailable
5334 EXECUTE_IF_SET_IN_REG_SET (df_get_live_in (bb
[j
]), 0, regno
, rsi
)
5336 if (regno
< FIRST_PSEUDO_REGISTER
)
5337 CLEAR_HARD_REG_BIT (tmp_reg
->regs
, regno
);
5340 /* Loop through the insns in the block. */
5343 /* Mark any new registers that are created as being unavailable for
5344 allocation. Also see if the CC register used in nested IFs can be
5350 int skip_nested_if
= FALSE
;
5351 HARD_REG_SET mentioned_regs
;
5353 CLEAR_HARD_REG_SET (mentioned_regs
);
5354 find_all_hard_regs (PATTERN (insn
), &mentioned_regs
);
5355 AND_COMPL_HARD_REG_SET (tmp_reg
->regs
, mentioned_regs
);
5357 pattern
= PATTERN (insn
);
5358 if (GET_CODE (pattern
) == COND_EXEC
)
5360 rtx reg
= XEXP (COND_EXEC_TEST (pattern
), 0);
5362 if (reg
!= sub_cond_exec_reg
)
5364 sub_cond_exec_reg
= reg
;
5365 frv_ifcvt
.num_nested_cond_exec
++;
5369 set
= single_set_pattern (pattern
);
5372 rtx dest
= SET_DEST (set
);
5373 rtx src
= SET_SRC (set
);
5375 if (GET_CODE (dest
) == REG
)
5377 int regno
= REGNO (dest
);
5378 enum rtx_code src_code
= GET_CODE (src
);
5380 if (CC_P (regno
) && src_code
== COMPARE
)
5381 skip_nested_if
= TRUE
;
5383 else if (CR_P (regno
)
5384 && (src_code
== IF_THEN_ELSE
5385 || COMPARISON_P (src
)))
5386 skip_nested_if
= TRUE
;
5390 if (! skip_nested_if
)
5391 AND_COMPL_HARD_REG_SET (frv_ifcvt
.nested_cc_ok_rewrite
,
5395 if (insn
== last_insn
)
5398 insn
= NEXT_INSN (insn
);
5402 /* If this is a nested if, rewrite the CC registers that are available to
5403 include the ones that can be rewritten, to increase the chance of being
5404 able to allocate a paired CC/CR register combination. */
5405 if (ce_info
->pass
> 1)
5407 for (j
= CC_FIRST
; j
<= CC_LAST
; j
++)
5408 if (TEST_HARD_REG_BIT (frv_ifcvt
.nested_cc_ok_rewrite
, j
))
5409 SET_HARD_REG_BIT (tmp_reg
->regs
, j
);
5411 CLEAR_HARD_REG_BIT (tmp_reg
->regs
, j
);
5417 fprintf (dump_file
, "Available GPRs: ");
5419 for (j
= GPR_FIRST
; j
<= GPR_LAST
; j
++)
5420 if (TEST_HARD_REG_BIT (tmp_reg
->regs
, j
))
5422 fprintf (dump_file
, " %d [%s]", j
, reg_names
[j
]);
5423 if (++num_gprs
> GPR_TEMP_NUM
+2)
5427 fprintf (dump_file
, "%s\nAvailable CRs: ",
5428 (num_gprs
> GPR_TEMP_NUM
+2) ? " ..." : "");
5430 for (j
= CR_FIRST
; j
<= CR_LAST
; j
++)
5431 if (TEST_HARD_REG_BIT (tmp_reg
->regs
, j
))
5432 fprintf (dump_file
, " %d [%s]", j
, reg_names
[j
]);
5434 fputs ("\n", dump_file
);
5436 if (ce_info
->pass
> 1)
5438 fprintf (dump_file
, "Modifiable CCs: ");
5439 for (j
= CC_FIRST
; j
<= CC_LAST
; j
++)
5440 if (TEST_HARD_REG_BIT (tmp_reg
->regs
, j
))
5441 fprintf (dump_file
, " %d [%s]", j
, reg_names
[j
]);
5443 fprintf (dump_file
, "\n%d nested COND_EXEC statements\n",
5444 frv_ifcvt
.num_nested_cond_exec
);
5448 /* Allocate the appropriate temporary condition code register. Try to
5449 allocate the ICR/FCR register that corresponds to the ICC/FCC register so
5450 that conditional cmp's can be done. */
5451 if (mode
== CCmode
|| mode
== CC_UNSmode
|| mode
== CC_NZmode
)
5453 cr_class
= ICR_REGS
;
5454 cc_class
= ICC_REGS
;
5455 cc_first
= ICC_FIRST
;
5458 else if (mode
== CC_FPmode
)
5460 cr_class
= FCR_REGS
;
5461 cc_class
= FCC_REGS
;
5462 cc_first
= FCC_FIRST
;
5467 cc_first
= cc_last
= 0;
5468 cr_class
= cc_class
= NO_REGS
;
5471 cc
= XEXP (true_expr
, 0);
5472 nested_cc
= cr
= NULL_RTX
;
5473 if (cc_class
!= NO_REGS
)
5475 /* For nested IFs and &&/||, see if we can find a CC and CR register pair
5476 so we can execute a csubcc/caddcc/cfcmps instruction. */
5479 for (cc_regno
= cc_first
; cc_regno
<= cc_last
; cc_regno
++)
5481 int cr_regno
= cc_regno
- CC_FIRST
+ CR_FIRST
;
5483 if (TEST_HARD_REG_BIT (frv_ifcvt
.tmp_reg
.regs
, cc_regno
)
5484 && TEST_HARD_REG_BIT (frv_ifcvt
.tmp_reg
.regs
, cr_regno
))
5486 frv_ifcvt
.tmp_reg
.next_reg
[ (int)cr_class
] = cr_regno
;
5487 cr
= frv_alloc_temp_reg (tmp_reg
, cr_class
, CC_CCRmode
, TRUE
,
5490 frv_ifcvt
.tmp_reg
.next_reg
[ (int)cc_class
] = cc_regno
;
5491 nested_cc
= frv_alloc_temp_reg (tmp_reg
, cc_class
, CCmode
,
5501 fprintf (dump_file
, "Could not allocate a CR temporary register\n");
5508 "Will use %s for conditional execution, %s for nested comparisons\n",
5509 reg_names
[ REGNO (cr
)],
5510 (nested_cc
) ? reg_names
[ REGNO (nested_cc
) ] : "<none>");
5512 /* Set the CCR bit. Note for integer tests, we reverse the condition so that
5513 in an IF-THEN-ELSE sequence, we are testing the TRUE case against the CCR
5514 bit being true. We don't do this for floating point, because of NaNs. */
5515 code
= GET_CODE (true_expr
);
5516 if (GET_MODE (cc
) != CC_FPmode
)
5518 code
= reverse_condition (code
);
5528 check_insn
= gen_rtx_SET (cr
, gen_rtx_fmt_ee (code
, CC_CCRmode
,
5531 /* Record the check insn to be inserted later. */
5532 frv_ifcvt_add_insn (check_insn
, BB_END (test_bb
), TRUE
);
5534 /* Update the tests. */
5535 frv_ifcvt
.cr_reg
= cr
;
5536 frv_ifcvt
.nested_cc_reg
= nested_cc
;
5537 *p_true
= gen_rtx_fmt_ee (code_true
, CC_CCRmode
, cr
, const0_rtx
);
5538 *p_false
= gen_rtx_fmt_ee (code_false
, CC_CCRmode
, cr
, const0_rtx
);
5541 /* Fail, don't do this conditional execution. */
5544 *p_false
= NULL_RTX
;
5546 fprintf (dump_file
, "Disabling this conditional execution.\n");
5552 /* A C expression to modify the code described by the conditional if
5553 information CE_INFO, for the basic block BB, possibly updating the tests in
5554 TRUE_EXPR, and FALSE_EXPR for converting the && and || parts of if-then or
5555 if-then-else code to conditional instructions. Set either TRUE_EXPR or
5556 FALSE_EXPR to a null pointer if the tests cannot be converted. */
5558 /* p_true and p_false are given expressions of the form:
5560 (and (eq:CC_CCR (reg:CC_CCR)
5566 frv_ifcvt_modify_multiple_tests (ce_if_block
*ce_info
,
5571 rtx old_true
= XEXP (*p_true
, 0);
5572 rtx old_false
= XEXP (*p_false
, 0);
5573 rtx true_expr
= XEXP (*p_true
, 1);
5574 rtx false_expr
= XEXP (*p_false
, 1);
5577 rtx cr
= XEXP (old_true
, 0);
5579 rtx new_cr
= NULL_RTX
;
5580 rtx
*p_new_cr
= (rtx
*)0;
5584 enum reg_class cr_class
;
5585 machine_mode mode
= GET_MODE (true_expr
);
5586 rtx (*logical_func
)(rtx
, rtx
, rtx
);
5588 if (TARGET_DEBUG_COND_EXEC
)
5591 "\n:::::::::: frv_ifcvt_modify_multiple_tests, before modification for %s\ntrue insn:\n",
5592 ce_info
->and_and_p
? "&&" : "||");
5594 debug_rtx (*p_true
);
5596 fputs ("\nfalse insn:\n", stderr
);
5597 debug_rtx (*p_false
);
5600 if (!TARGET_MULTI_CE
)
5603 if (GET_CODE (cr
) != REG
)
5606 if (mode
== CCmode
|| mode
== CC_UNSmode
|| mode
== CC_NZmode
)
5608 cr_class
= ICR_REGS
;
5609 p_new_cr
= &frv_ifcvt
.extra_int_cr
;
5611 else if (mode
== CC_FPmode
)
5613 cr_class
= FCR_REGS
;
5614 p_new_cr
= &frv_ifcvt
.extra_fp_cr
;
5619 /* Allocate a temp CR, reusing a previously allocated temp CR if we have 3 or
5620 more &&/|| tests. */
5624 new_cr
= *p_new_cr
= frv_alloc_temp_reg (&frv_ifcvt
.tmp_reg
, cr_class
,
5625 CC_CCRmode
, TRUE
, TRUE
);
5630 if (ce_info
->and_and_p
)
5632 old_test
= old_false
;
5633 test_expr
= true_expr
;
5634 logical_func
= (GET_CODE (old_true
) == EQ
) ? gen_andcr
: gen_andncr
;
5635 *p_true
= gen_rtx_NE (CC_CCRmode
, cr
, const0_rtx
);
5636 *p_false
= gen_rtx_EQ (CC_CCRmode
, cr
, const0_rtx
);
5640 old_test
= old_false
;
5641 test_expr
= false_expr
;
5642 logical_func
= (GET_CODE (old_false
) == EQ
) ? gen_orcr
: gen_orncr
;
5643 *p_true
= gen_rtx_EQ (CC_CCRmode
, cr
, const0_rtx
);
5644 *p_false
= gen_rtx_NE (CC_CCRmode
, cr
, const0_rtx
);
5647 /* First add the andcr/andncr/orcr/orncr, which will be added after the
5648 conditional check instruction, due to frv_ifcvt_add_insn being a LIFO
5650 frv_ifcvt_add_insn ((*logical_func
) (cr
, cr
, new_cr
), BB_END (bb
), TRUE
);
5652 /* Now add the conditional check insn. */
5653 cc
= XEXP (test_expr
, 0);
5654 compare
= gen_rtx_fmt_ee (GET_CODE (test_expr
), CC_CCRmode
, cc
, const0_rtx
);
5655 if_else
= gen_rtx_IF_THEN_ELSE (CC_CCRmode
, old_test
, compare
, const0_rtx
);
5657 check_insn
= gen_rtx_SET (new_cr
, if_else
);
5659 /* Add the new check insn to the list of check insns that need to be
5661 frv_ifcvt_add_insn (check_insn
, BB_END (bb
), TRUE
);
5663 if (TARGET_DEBUG_COND_EXEC
)
5665 fputs ("\n:::::::::: frv_ifcvt_modify_multiple_tests, after modification\ntrue insn:\n",
5668 debug_rtx (*p_true
);
5670 fputs ("\nfalse insn:\n", stderr
);
5671 debug_rtx (*p_false
);
5677 *p_true
= *p_false
= NULL_RTX
;
5679 /* If we allocated a CR register, release it. */
5682 CLEAR_HARD_REG_BIT (frv_ifcvt
.tmp_reg
.regs
, REGNO (new_cr
));
5683 *p_new_cr
= NULL_RTX
;
5686 if (TARGET_DEBUG_COND_EXEC
)
5687 fputs ("\n:::::::::: frv_ifcvt_modify_multiple_tests, failed.\n", stderr
);
5693 /* Return a register which will be loaded with a value if an IF block is
5694 converted to conditional execution. This is used to rewrite instructions
5695 that use constants to ones that just use registers. */
5698 frv_ifcvt_load_value (rtx value
, rtx insn ATTRIBUTE_UNUSED
)
5700 int num_alloc
= frv_ifcvt
.cur_scratch_regs
;
5704 /* We know gr0 == 0, so replace any errant uses. */
5705 if (value
== const0_rtx
)
5706 return gen_rtx_REG (SImode
, GPR_FIRST
);
5708 /* First search all registers currently loaded to see if we have an
5709 applicable constant. */
5710 if (CONSTANT_P (value
)
5711 || (GET_CODE (value
) == REG
&& REGNO (value
) == LR_REGNO
))
5713 for (i
= 0; i
< num_alloc
; i
++)
5715 if (rtx_equal_p (SET_SRC (frv_ifcvt
.scratch_regs
[i
]), value
))
5716 return SET_DEST (frv_ifcvt
.scratch_regs
[i
]);
5720 /* Have we exhausted the number of registers available? */
5721 if (num_alloc
>= GPR_TEMP_NUM
)
5724 fprintf (dump_file
, "Too many temporary registers allocated\n");
5729 /* Allocate the new register. */
5730 reg
= frv_alloc_temp_reg (&frv_ifcvt
.tmp_reg
, GPR_REGS
, SImode
, TRUE
, TRUE
);
5734 fputs ("Could not find a scratch register\n", dump_file
);
5739 frv_ifcvt
.cur_scratch_regs
++;
5740 frv_ifcvt
.scratch_regs
[num_alloc
] = gen_rtx_SET (reg
, value
);
5744 if (GET_CODE (value
) == CONST_INT
)
5745 fprintf (dump_file
, "Register %s will hold %ld\n",
5746 reg_names
[ REGNO (reg
)], (long)INTVAL (value
));
5748 else if (GET_CODE (value
) == REG
&& REGNO (value
) == LR_REGNO
)
5749 fprintf (dump_file
, "Register %s will hold LR\n",
5750 reg_names
[ REGNO (reg
)]);
5753 fprintf (dump_file
, "Register %s will hold a saved value\n",
5754 reg_names
[ REGNO (reg
)]);
5761 /* Update a MEM used in conditional code that might contain an offset to put
5762 the offset into a scratch register, so that the conditional load/store
5763 operations can be used. This function returns the original pointer if the
5764 MEM is valid to use in conditional code, NULL if we can't load up the offset
5765 into a temporary register, or the new MEM if we were successful. */
5768 frv_ifcvt_rewrite_mem (rtx mem
, machine_mode mode
, rtx insn
)
5770 rtx addr
= XEXP (mem
, 0);
5772 if (!frv_legitimate_address_p_1 (mode
, addr
, reload_completed
, TRUE
, FALSE
))
5774 if (GET_CODE (addr
) == PLUS
)
5776 rtx addr_op0
= XEXP (addr
, 0);
5777 rtx addr_op1
= XEXP (addr
, 1);
5779 if (GET_CODE (addr_op0
) == REG
&& CONSTANT_P (addr_op1
))
5781 rtx reg
= frv_ifcvt_load_value (addr_op1
, insn
);
5785 addr
= gen_rtx_PLUS (Pmode
, addr_op0
, reg
);
5792 else if (CONSTANT_P (addr
))
5793 addr
= frv_ifcvt_load_value (addr
, insn
);
5798 if (addr
== NULL_RTX
)
5801 else if (XEXP (mem
, 0) != addr
)
5802 return change_address (mem
, mode
, addr
);
5809 /* Given a PATTERN, return a SET expression if this PATTERN has only a single
5810 SET, possibly conditionally executed. It may also have CLOBBERs, USEs. */
5813 single_set_pattern (rtx pattern
)
5818 if (GET_CODE (pattern
) == COND_EXEC
)
5819 pattern
= COND_EXEC_CODE (pattern
);
5821 if (GET_CODE (pattern
) == SET
)
5824 else if (GET_CODE (pattern
) == PARALLEL
)
5826 for (i
= 0, set
= 0; i
< XVECLEN (pattern
, 0); i
++)
5828 rtx sub
= XVECEXP (pattern
, 0, i
);
5830 switch (GET_CODE (sub
))
5854 /* A C expression to modify the code described by the conditional if
5855 information CE_INFO with the new PATTERN in INSN. If PATTERN is a null
5856 pointer after the IFCVT_MODIFY_INSN macro executes, it is assumed that that
5857 insn cannot be converted to be executed conditionally. */
5860 frv_ifcvt_modify_insn (ce_if_block
*ce_info
,
5864 rtx orig_ce_pattern
= pattern
;
5870 gcc_assert (GET_CODE (pattern
) == COND_EXEC
);
5872 test
= COND_EXEC_TEST (pattern
);
5873 if (GET_CODE (test
) == AND
)
5875 rtx cr
= frv_ifcvt
.cr_reg
;
5878 op0
= XEXP (test
, 0);
5879 if (! rtx_equal_p (cr
, XEXP (op0
, 0)))
5882 op1
= XEXP (test
, 1);
5883 test_reg
= XEXP (op1
, 0);
5884 if (GET_CODE (test_reg
) != REG
)
5887 /* Is this the first nested if block in this sequence? If so, generate
5888 an andcr or andncr. */
5889 if (! frv_ifcvt
.last_nested_if_cr
)
5893 frv_ifcvt
.last_nested_if_cr
= test_reg
;
5894 if (GET_CODE (op0
) == NE
)
5895 and_op
= gen_andcr (test_reg
, cr
, test_reg
);
5897 and_op
= gen_andncr (test_reg
, cr
, test_reg
);
5899 frv_ifcvt_add_insn (and_op
, insn
, TRUE
);
5902 /* If this isn't the first statement in the nested if sequence, see if we
5903 are dealing with the same register. */
5904 else if (! rtx_equal_p (test_reg
, frv_ifcvt
.last_nested_if_cr
))
5907 COND_EXEC_TEST (pattern
) = test
= op1
;
5910 /* If this isn't a nested if, reset state variables. */
5913 frv_ifcvt
.last_nested_if_cr
= NULL_RTX
;
5916 set
= single_set_pattern (pattern
);
5919 rtx dest
= SET_DEST (set
);
5920 rtx src
= SET_SRC (set
);
5921 machine_mode mode
= GET_MODE (dest
);
5923 /* Check for normal binary operators. */
5924 if (mode
== SImode
&& ARITHMETIC_P (src
))
5926 op0
= XEXP (src
, 0);
5927 op1
= XEXP (src
, 1);
5929 if (integer_register_operand (op0
, SImode
) && CONSTANT_P (op1
))
5931 op1
= frv_ifcvt_load_value (op1
, insn
);
5933 COND_EXEC_CODE (pattern
)
5934 = gen_rtx_SET (dest
, gen_rtx_fmt_ee (GET_CODE (src
),
5942 /* For multiply by a constant, we need to handle the sign extending
5943 correctly. Add a USE of the value after the multiply to prevent flow
5944 from cratering because only one register out of the two were used. */
5945 else if (mode
== DImode
&& GET_CODE (src
) == MULT
)
5947 op0
= XEXP (src
, 0);
5948 op1
= XEXP (src
, 1);
5949 if (GET_CODE (op0
) == SIGN_EXTEND
&& GET_CODE (op1
) == CONST_INT
)
5951 op1
= frv_ifcvt_load_value (op1
, insn
);
5954 op1
= gen_rtx_SIGN_EXTEND (DImode
, op1
);
5955 COND_EXEC_CODE (pattern
)
5956 = gen_rtx_SET (dest
, gen_rtx_MULT (DImode
, op0
, op1
));
5962 frv_ifcvt_add_insn (gen_use (dest
), insn
, FALSE
);
5965 /* If we are just loading a constant created for a nested conditional
5966 execution statement, just load the constant without any conditional
5967 execution, since we know that the constant will not interfere with any
5969 else if (frv_ifcvt
.scratch_insns_bitmap
5970 && bitmap_bit_p (frv_ifcvt
.scratch_insns_bitmap
,
5972 && REG_P (SET_DEST (set
))
5973 /* We must not unconditionally set a scratch reg chosen
5974 for a nested if-converted block if its incoming
5975 value from the TEST block (or the result of the THEN
5976 branch) could/should propagate to the JOIN block.
5977 It suffices to test whether the register is live at
5978 the JOIN point: if it's live there, we can infer
5979 that we set it in the former JOIN block of the
5980 nested if-converted block (otherwise it wouldn't
5981 have been available as a scratch register), and it
5982 is either propagated through or set in the other
5983 conditional block. It's probably not worth trying
5984 to catch the latter case, and it could actually
5985 limit scheduling of the combined block quite
5988 && ! (REGNO_REG_SET_P (df_get_live_in (ce_info
->join_bb
),
5989 REGNO (SET_DEST (set
))))
5990 /* Similarly, we must not unconditionally set a reg
5991 used as scratch in the THEN branch if the same reg
5992 is live in the ELSE branch. */
5993 && (! ce_info
->else_bb
5994 || BLOCK_FOR_INSN (insn
) == ce_info
->else_bb
5995 || ! (REGNO_REG_SET_P (df_get_live_in (ce_info
->else_bb
),
5996 REGNO (SET_DEST (set
))))))
5999 else if (mode
== QImode
|| mode
== HImode
|| mode
== SImode
6002 int changed_p
= FALSE
;
6004 /* Check for just loading up a constant */
6005 if (CONSTANT_P (src
) && integer_register_operand (dest
, mode
))
6007 src
= frv_ifcvt_load_value (src
, insn
);
6014 /* See if we need to fix up stores */
6015 if (GET_CODE (dest
) == MEM
)
6017 rtx new_mem
= frv_ifcvt_rewrite_mem (dest
, mode
, insn
);
6022 else if (new_mem
!= dest
)
6029 /* See if we need to fix up loads */
6030 if (GET_CODE (src
) == MEM
)
6032 rtx new_mem
= frv_ifcvt_rewrite_mem (src
, mode
, insn
);
6037 else if (new_mem
!= src
)
6044 /* If either src or destination changed, redo SET. */
6046 COND_EXEC_CODE (pattern
) = gen_rtx_SET (dest
, src
);
6049 /* Rewrite a nested set cccr in terms of IF_THEN_ELSE. Also deal with
6050 rewriting the CC register to be the same as the paired CC/CR register
6052 else if (mode
== CC_CCRmode
&& COMPARISON_P (src
))
6054 int regno
= REGNO (XEXP (src
, 0));
6057 if (ce_info
->pass
> 1
6058 && regno
!= (int)REGNO (frv_ifcvt
.nested_cc_reg
)
6059 && TEST_HARD_REG_BIT (frv_ifcvt
.nested_cc_ok_rewrite
, regno
))
6061 src
= gen_rtx_fmt_ee (GET_CODE (src
),
6063 frv_ifcvt
.nested_cc_reg
,
6067 if_else
= gen_rtx_IF_THEN_ELSE (CC_CCRmode
, test
, src
, const0_rtx
);
6068 pattern
= gen_rtx_SET (dest
, if_else
);
6071 /* Remap a nested compare instruction to use the paired CC/CR reg. */
6072 else if (ce_info
->pass
> 1
6073 && GET_CODE (dest
) == REG
6074 && CC_P (REGNO (dest
))
6075 && REGNO (dest
) != REGNO (frv_ifcvt
.nested_cc_reg
)
6076 && TEST_HARD_REG_BIT (frv_ifcvt
.nested_cc_ok_rewrite
,
6078 && GET_CODE (src
) == COMPARE
)
6080 PUT_MODE (frv_ifcvt
.nested_cc_reg
, GET_MODE (dest
));
6081 COND_EXEC_CODE (pattern
)
6082 = gen_rtx_SET (frv_ifcvt
.nested_cc_reg
, copy_rtx (src
));
6086 if (TARGET_DEBUG_COND_EXEC
)
6088 rtx orig_pattern
= PATTERN (insn
);
6090 PATTERN (insn
) = pattern
;
6092 "\n:::::::::: frv_ifcvt_modify_insn: pass = %d, insn after modification:\n",
6096 PATTERN (insn
) = orig_pattern
;
6102 if (TARGET_DEBUG_COND_EXEC
)
6104 rtx orig_pattern
= PATTERN (insn
);
6106 PATTERN (insn
) = orig_ce_pattern
;
6108 "\n:::::::::: frv_ifcvt_modify_insn: pass = %d, insn could not be modified:\n",
6112 PATTERN (insn
) = orig_pattern
;
6119 /* A C expression to perform any final machine dependent modifications in
6120 converting code to conditional execution in the code described by the
6121 conditional if information CE_INFO. */
6124 frv_ifcvt_modify_final (ce_if_block
*ce_info ATTRIBUTE_UNUSED
)
6128 rtx p
= frv_ifcvt
.added_insns_list
;
6131 /* Loop inserting the check insns. The last check insn is the first test,
6132 and is the appropriate place to insert constants. */
6137 rtx check_and_insert_insns
= XEXP (p
, 0);
6140 check_insn
= XEXP (check_and_insert_insns
, 0);
6141 existing_insn
= XEXP (check_and_insert_insns
, 1);
6144 /* The jump bit is used to say that the new insn is to be inserted BEFORE
6145 the existing insn, otherwise it is to be inserted AFTER. */
6146 if (check_and_insert_insns
->jump
)
6148 emit_insn_before (check_insn
, existing_insn
);
6149 check_and_insert_insns
->jump
= 0;
6152 emit_insn_after (check_insn
, existing_insn
);
6154 free_EXPR_LIST_node (check_and_insert_insns
);
6155 free_EXPR_LIST_node (old_p
);
6157 while (p
!= NULL_RTX
);
6159 /* Load up any constants needed into temp gprs */
6160 for (i
= 0; i
< frv_ifcvt
.cur_scratch_regs
; i
++)
6162 rtx insn
= emit_insn_before (frv_ifcvt
.scratch_regs
[i
], existing_insn
);
6163 if (! frv_ifcvt
.scratch_insns_bitmap
)
6164 frv_ifcvt
.scratch_insns_bitmap
= BITMAP_ALLOC (NULL
);
6165 bitmap_set_bit (frv_ifcvt
.scratch_insns_bitmap
, INSN_UID (insn
));
6166 frv_ifcvt
.scratch_regs
[i
] = NULL_RTX
;
6169 frv_ifcvt
.added_insns_list
= NULL_RTX
;
6170 frv_ifcvt
.cur_scratch_regs
= 0;
6174 /* A C expression to cancel any machine dependent modifications in converting
6175 code to conditional execution in the code described by the conditional if
6176 information CE_INFO. */
6179 frv_ifcvt_modify_cancel (ce_if_block
*ce_info ATTRIBUTE_UNUSED
)
6182 rtx p
= frv_ifcvt
.added_insns_list
;
6184 /* Loop freeing up the EXPR_LIST's allocated. */
6185 while (p
!= NULL_RTX
)
6187 rtx check_and_jump
= XEXP (p
, 0);
6191 free_EXPR_LIST_node (check_and_jump
);
6192 free_EXPR_LIST_node (old_p
);
6195 /* Release any temporary gprs allocated. */
6196 for (i
= 0; i
< frv_ifcvt
.cur_scratch_regs
; i
++)
6197 frv_ifcvt
.scratch_regs
[i
] = NULL_RTX
;
6199 frv_ifcvt
.added_insns_list
= NULL_RTX
;
6200 frv_ifcvt
.cur_scratch_regs
= 0;
6204 /* A C expression for the size in bytes of the trampoline, as an integer.
6208 setlo #0, <static_chain>
6210 sethi #0, <static_chain>
6211 jmpl @(gr0,<jmp_reg>) */
6214 frv_trampoline_size (void)
6217 /* Allocate room for the function descriptor and the lddi
6220 return 5 /* instructions */ * 4 /* instruction size. */;
6224 /* A C statement to initialize the variable parts of a trampoline. ADDR is an
6225 RTX for the address of the trampoline; FNADDR is an RTX for the address of
6226 the nested function; STATIC_CHAIN is an RTX for the static chain value that
6227 should be passed to the function when it is called.
6232 setlo #0, <static_chain>
6234 sethi #0, <static_chain>
6235 jmpl @(gr0,<jmp_reg>) */
6238 frv_trampoline_init (rtx m_tramp
, tree fndecl
, rtx static_chain
)
6240 rtx addr
= XEXP (m_tramp
, 0);
6241 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
6242 rtx sc_reg
= force_reg (Pmode
, static_chain
);
6244 emit_library_call (gen_rtx_SYMBOL_REF (SImode
, "__trampoline_setup"),
6245 LCT_NORMAL
, VOIDmode
, 4,
6247 GEN_INT (frv_trampoline_size ()), SImode
,
6253 /* Many machines have some registers that cannot be copied directly to or from
6254 memory or even from other types of registers. An example is the `MQ'
6255 register, which on most machines, can only be copied to or from general
6256 registers, but not memory. Some machines allow copying all registers to and
6257 from memory, but require a scratch register for stores to some memory
6258 locations (e.g., those with symbolic address on the RT, and those with
6259 certain symbolic address on the SPARC when compiling PIC). In some cases,
6260 both an intermediate and a scratch register are required.
6262 You should define these macros to indicate to the reload phase that it may
6263 need to allocate at least one register for a reload in addition to the
6264 register to contain the data. Specifically, if copying X to a register
6265 RCLASS in MODE requires an intermediate register, you should define
6266 `SECONDARY_INPUT_RELOAD_CLASS' to return the largest register class all of
6267 whose registers can be used as intermediate registers or scratch registers.
6269 If copying a register RCLASS in MODE to X requires an intermediate or scratch
6270 register, `SECONDARY_OUTPUT_RELOAD_CLASS' should be defined to return the
6271 largest register class required. If the requirements for input and output
6272 reloads are the same, the macro `SECONDARY_RELOAD_CLASS' should be used
6273 instead of defining both macros identically.
6275 The values returned by these macros are often `GENERAL_REGS'. Return
6276 `NO_REGS' if no spare register is needed; i.e., if X can be directly copied
6277 to or from a register of RCLASS in MODE without requiring a scratch register.
6278 Do not define this macro if it would always return `NO_REGS'.
6280 If a scratch register is required (either with or without an intermediate
6281 register), you should define patterns for `reload_inM' or `reload_outM', as
6282 required.. These patterns, which will normally be implemented with a
6283 `define_expand', should be similar to the `movM' patterns, except that
6284 operand 2 is the scratch register.
6286 Define constraints for the reload register and scratch register that contain
6287 a single register class. If the original reload register (whose class is
6288 RCLASS) can meet the constraint given in the pattern, the value returned by
6289 these macros is used for the class of the scratch register. Otherwise, two
6290 additional reload registers are required. Their classes are obtained from
6291 the constraints in the insn pattern.
6293 X might be a pseudo-register or a `subreg' of a pseudo-register, which could
6294 either be in a hard register or in memory. Use `true_regnum' to find out;
6295 it will return -1 if the pseudo is in memory and the hard register number if
6296 it is in a register.
6298 These macros should not be used in the case where a particular class of
6299 registers can only be copied to memory and not to another class of
6300 registers. In that case, secondary reload registers are not needed and
6301 would not be helpful. Instead, a stack location must be used to perform the
6302 copy and the `movM' pattern should use memory as an intermediate storage.
6303 This case often occurs between floating-point and general registers. */
6306 frv_secondary_reload_class (enum reg_class rclass
,
6307 machine_mode mode ATTRIBUTE_UNUSED
,
6318 /* Accumulators/Accumulator guard registers need to go through floating
6323 if (x
&& GET_CODE (x
) == REG
)
6325 int regno
= REGNO (x
);
6327 if (ACC_P (regno
) || ACCG_P (regno
))
6332 /* Nonzero constants should be loaded into an FPR through a GPR. */
6334 if (x
&& CONSTANT_P (x
) && !ZERO_P (x
))
6340 /* All of these types need gpr registers. */
6352 /* The accumulators need fpr registers. */
6362 /* This hook exists to catch the case where secondary_reload_class() is
6363 called from init_reg_autoinc() in regclass.c - before the reload optabs
6364 have been initialised. */
6367 frv_secondary_reload (bool in_p
, rtx x
, reg_class_t reload_class_i
,
6368 machine_mode reload_mode
,
6369 secondary_reload_info
* sri
)
6371 enum reg_class rclass
= NO_REGS
;
6372 enum reg_class reload_class
= (enum reg_class
) reload_class_i
;
6374 if (sri
->prev_sri
&& sri
->prev_sri
->t_icode
!= CODE_FOR_nothing
)
6376 sri
->icode
= sri
->prev_sri
->t_icode
;
6380 rclass
= frv_secondary_reload_class (reload_class
, reload_mode
, x
);
6382 if (rclass
!= NO_REGS
)
6384 enum insn_code icode
6385 = direct_optab_handler (in_p
? reload_in_optab
: reload_out_optab
,
6389 /* This happens when then the reload_[in|out]_optabs have
6390 not been initialised. */
6391 sri
->t_icode
= CODE_FOR_nothing
;
6396 /* Fall back to the default secondary reload handler. */
6397 return default_secondary_reload (in_p
, x
, reload_class
, reload_mode
, sri
);
6401 /* Worker function for TARGET_CLASS_LIKELY_SPILLED_P. */
6404 frv_class_likely_spilled_p (reg_class_t rclass
)
6414 case FDPIC_FPTR_REGS
:
6434 /* An expression for the alignment of a structure field FIELD if the
6435 alignment computed in the usual way is COMPUTED. GCC uses this
6436 value instead of the value in `BIGGEST_ALIGNMENT' or
6437 `BIGGEST_FIELD_ALIGNMENT', if defined, for structure fields only. */
6439 /* The definition type of the bit field data is either char, short, long or
6440 long long. The maximum bit size is the number of bits of its own type.
6442 The bit field data is assigned to a storage unit that has an adequate size
6443 for bit field data retention and is located at the smallest address.
6445 Consecutive bit field data are packed at consecutive bits having the same
6446 storage unit, with regard to the type, beginning with the MSB and continuing
6449 If a field to be assigned lies over a bit field type boundary, its
6450 assignment is completed by aligning it with a boundary suitable for the
6453 When a bit field having a bit length of 0 is declared, it is forcibly
6454 assigned to the next storage unit.
6467 &x 00000000 00000000 00000000 00000000
6470 &x+4 00000000 00000000 00000000 00000000
6473 &x+8 00000000 00000000 00000000 00000000
6476 &x+12 00000000 00000000 00000000 00000000
6482 frv_adjust_field_align (tree field
, int computed
)
6484 /* Make sure that the bitfield is not wider than the type. */
6485 if (DECL_BIT_FIELD (field
)
6486 && !DECL_ARTIFICIAL (field
))
6488 tree parent
= DECL_CONTEXT (field
);
6489 tree prev
= NULL_TREE
;
6492 for (cur
= TYPE_FIELDS (parent
); cur
&& cur
!= field
; cur
= DECL_CHAIN (cur
))
6494 if (TREE_CODE (cur
) != FIELD_DECL
)
6502 /* If this isn't a :0 field and if the previous element is a bitfield
6503 also, see if the type is different, if so, we will need to align the
6504 bit-field to the next boundary. */
6506 && ! DECL_PACKED (field
)
6507 && ! integer_zerop (DECL_SIZE (field
))
6508 && DECL_BIT_FIELD_TYPE (field
) != DECL_BIT_FIELD_TYPE (prev
))
6510 int prev_align
= TYPE_ALIGN (TREE_TYPE (prev
));
6511 int cur_align
= TYPE_ALIGN (TREE_TYPE (field
));
6512 computed
= (prev_align
> cur_align
) ? prev_align
: cur_align
;
6520 /* A C expression that is nonzero if it is permissible to store a value of mode
6521 MODE in hard register number REGNO (or in several registers starting with
6522 that one). For a machine where all registers are equivalent, a suitable
6525 #define HARD_REGNO_MODE_OK(REGNO, MODE) 1
6527 It is not necessary for this macro to check for the numbers of fixed
6528 registers, because the allocation mechanism considers them to be always
6531 On some machines, double-precision values must be kept in even/odd register
6532 pairs. The way to implement that is to define this macro to reject odd
6533 register numbers for such modes.
6535 The minimum requirement for a mode to be OK in a register is that the
6536 `movMODE' instruction pattern support moves between the register and any
6537 other hard register for which the mode is OK; and that moving a value into
6538 the register and back out not alter it.
6540 Since the same instruction used to move `SImode' will work for all narrower
6541 integer modes, it is not necessary on any machine for `HARD_REGNO_MODE_OK'
6542 to distinguish between these modes, provided you define patterns `movhi',
6543 etc., to take advantage of this. This is useful because of the interaction
6544 between `HARD_REGNO_MODE_OK' and `MODES_TIEABLE_P'; it is very desirable for
6545 all integer modes to be tieable.
6547 Many machines have special registers for floating point arithmetic. Often
6548 people assume that floating point machine modes are allowed only in floating
6549 point registers. This is not true. Any registers that can hold integers
6550 can safely *hold* a floating point machine mode, whether or not floating
6551 arithmetic can be done on it in those registers. Integer move instructions
6552 can be used to move the values.
6554 On some machines, though, the converse is true: fixed-point machine modes
6555 may not go in floating registers. This is true if the floating registers
6556 normalize any value stored in them, because storing a non-floating value
6557 there would garble it. In this case, `HARD_REGNO_MODE_OK' should reject
6558 fixed-point machine modes in floating registers. But if the floating
6559 registers do not automatically normalize, if you can store any bit pattern
6560 in one and retrieve it unchanged without a trap, then any machine mode may
6561 go in a floating register, so you can define this macro to say so.
6563 The primary significance of special floating registers is rather that they
6564 are the registers acceptable in floating point arithmetic instructions.
6565 However, this is of no concern to `HARD_REGNO_MODE_OK'. You handle it by
6566 writing the proper constraints for those instructions.
6568 On some machines, the floating registers are especially slow to access, so
6569 that it is better to store a value in a stack frame than in such a register
6570 if floating point arithmetic is not being done. As long as the floating
6571 registers are not in class `GENERAL_REGS', they will not be used unless some
6572 pattern's constraint asks for one. */
6575 frv_hard_regno_mode_ok (int regno
, machine_mode mode
)
6585 return ICC_P (regno
) || GPR_P (regno
);
6588 return CR_P (regno
) || GPR_P (regno
);
6591 return FCC_P (regno
) || GPR_P (regno
);
6597 /* Set BASE to the first register in REGNO's class. Set MASK to the
6598 bits that must be clear in (REGNO - BASE) for the register to be
6600 if (INTEGRAL_MODE_P (mode
) || FLOAT_MODE_P (mode
) || VECTOR_MODE_P (mode
))
6604 /* ACCGs store one byte. Two-byte quantities must start in
6605 even-numbered registers, four-byte ones in registers whose
6606 numbers are divisible by four, and so on. */
6608 mask
= GET_MODE_SIZE (mode
) - 1;
6612 /* The other registers store one word. */
6613 if (GPR_P (regno
) || regno
== AP_FIRST
)
6616 else if (FPR_P (regno
))
6619 else if (ACC_P (regno
))
6622 else if (SPR_P (regno
))
6623 return mode
== SImode
;
6625 /* Fill in the table. */
6629 /* Anything smaller than an SI is OK in any word-sized register. */
6630 if (GET_MODE_SIZE (mode
) < 4)
6633 mask
= (GET_MODE_SIZE (mode
) / 4) - 1;
6635 return (((regno
- base
) & mask
) == 0);
6642 /* A C expression for the number of consecutive hard registers, starting at
6643 register number REGNO, required to hold a value of mode MODE.
6645 On a machine where all registers are exactly one word, a suitable definition
6648 #define HARD_REGNO_NREGS(REGNO, MODE) \
6649 ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \
6650 / UNITS_PER_WORD)) */
6652 /* On the FRV, make the CC_FP mode take 3 words in the integer registers, so
6653 that we can build the appropriate instructions to properly reload the
6654 values. Also, make the byte-sized accumulator guards use one guard
6658 frv_hard_regno_nregs (int regno
, machine_mode mode
)
6661 return GET_MODE_SIZE (mode
);
6663 return (GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
6667 /* A C expression for the maximum number of consecutive registers of
6668 class RCLASS needed to hold a value of mode MODE.
6670 This is closely related to the macro `HARD_REGNO_NREGS'. In fact, the value
6671 of the macro `CLASS_MAX_NREGS (RCLASS, MODE)' should be the maximum value of
6672 `HARD_REGNO_NREGS (REGNO, MODE)' for all REGNO values in the class RCLASS.
6674 This macro helps control the handling of multiple-word values in
6677 This declaration is required. */
6680 frv_class_max_nregs (enum reg_class rclass
, machine_mode mode
)
6682 if (rclass
== ACCG_REGS
)
6683 /* An N-byte value requires N accumulator guards. */
6684 return GET_MODE_SIZE (mode
);
6686 return (GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
6690 /* A C expression that is nonzero if X is a legitimate constant for an
6691 immediate operand on the target machine. You can assume that X satisfies
6692 `CONSTANT_P', so you need not check this. In fact, `1' is a suitable
6693 definition for this macro on machines where anything `CONSTANT_P' is valid. */
6696 frv_legitimate_constant_p (machine_mode mode
, rtx x
)
6698 /* frv_cannot_force_const_mem always returns true for FDPIC. This
6699 means that the move expanders will be expected to deal with most
6700 kinds of constant, regardless of what we return here.
6702 However, among its other duties, frv_legitimate_constant_p decides whether
6703 a constant can be entered into reg_equiv_constant[]. If we return true,
6704 reload can create new instances of the constant whenever it likes.
6706 The idea is therefore to accept as many constants as possible (to give
6707 reload more freedom) while rejecting constants that can only be created
6708 at certain times. In particular, anything with a symbolic component will
6709 require use of the pseudo FDPIC register, which is only available before
6712 return LEGITIMATE_PIC_OPERAND_P (x
);
6714 /* All of the integer constants are ok. */
6715 if (GET_CODE (x
) != CONST_DOUBLE
)
6718 /* double integer constants are ok. */
6719 if (GET_MODE (x
) == VOIDmode
|| mode
== DImode
)
6722 /* 0 is always ok. */
6723 if (x
== CONST0_RTX (mode
))
6726 /* If floating point is just emulated, allow any constant, since it will be
6727 constructed in the GPRs. */
6728 if (!TARGET_HAS_FPRS
)
6731 if (mode
== DFmode
&& !TARGET_DOUBLE
)
6734 /* Otherwise store the constant away and do a load. */
6738 /* Implement SELECT_CC_MODE. Choose CC_FP for floating-point comparisons,
6739 CC_NZ for comparisons against zero in which a single Z or N flag test
6740 is enough, CC_UNS for other unsigned comparisons, and CC for other
6741 signed comparisons. */
6744 frv_select_cc_mode (enum rtx_code code
, rtx x
, rtx y
)
6746 if (GET_MODE_CLASS (GET_MODE (x
)) == MODE_FLOAT
)
6755 return y
== const0_rtx
? CC_NZmode
: CCmode
;
6761 return y
== const0_rtx
? CC_NZmode
: CC_UNSmode
;
6769 /* Worker function for TARGET_REGISTER_MOVE_COST. */
6771 #define HIGH_COST 40
6772 #define MEDIUM_COST 3
6776 frv_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED
,
6777 reg_class_t from
, reg_class_t to
)
6790 case FDPIC_FPTR_REGS
:
6791 case FDPIC_CALL_REGS
:
6804 case FDPIC_FPTR_REGS
:
6805 case FDPIC_CALL_REGS
:
6830 case FDPIC_FPTR_REGS
:
6831 case FDPIC_CALL_REGS
:
6855 case FDPIC_FPTR_REGS
:
6856 case FDPIC_CALL_REGS
:
6877 /* Worker function for TARGET_MEMORY_MOVE_COST. */
6880 frv_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED
,
6881 reg_class_t rclass ATTRIBUTE_UNUSED
,
6882 bool in ATTRIBUTE_UNUSED
)
6888 /* Implementation of TARGET_ASM_INTEGER. In the FRV case we need to
6889 use ".picptr" to generate safe relocations for PIC code. We also
6890 need a fixup entry for aligned (non-debugging) code. */
6893 frv_assemble_integer (rtx value
, unsigned int size
, int aligned_p
)
6895 if ((flag_pic
|| TARGET_FDPIC
) && size
== UNITS_PER_WORD
)
6897 if (GET_CODE (value
) == CONST
6898 || GET_CODE (value
) == SYMBOL_REF
6899 || GET_CODE (value
) == LABEL_REF
)
6901 if (TARGET_FDPIC
&& GET_CODE (value
) == SYMBOL_REF
6902 && SYMBOL_REF_FUNCTION_P (value
))
6904 fputs ("\t.picptr\tfuncdesc(", asm_out_file
);
6905 output_addr_const (asm_out_file
, value
);
6906 fputs (")\n", asm_out_file
);
6909 else if (TARGET_FDPIC
&& GET_CODE (value
) == CONST
6910 && frv_function_symbol_referenced_p (value
))
6912 if (aligned_p
&& !TARGET_FDPIC
)
6914 static int label_num
= 0;
6918 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCP", label_num
++);
6919 p
= (* targetm
.strip_name_encoding
) (buf
);
6921 fprintf (asm_out_file
, "%s:\n", p
);
6922 fprintf (asm_out_file
, "%s\n", FIXUP_SECTION_ASM_OP
);
6923 fprintf (asm_out_file
, "\t.picptr\t%s\n", p
);
6924 fprintf (asm_out_file
, "\t.previous\n");
6926 assemble_integer_with_op ("\t.picptr\t", value
);
6931 /* We've set the unaligned SI op to NULL, so we always have to
6932 handle the unaligned case here. */
6933 assemble_integer_with_op ("\t.4byte\t", value
);
6937 return default_assemble_integer (value
, size
, aligned_p
);
6940 /* Function to set up the backend function structure. */
6942 static struct machine_function
*
6943 frv_init_machine_status (void)
6945 return ggc_cleared_alloc
<machine_function
> ();
6948 /* Implement TARGET_SCHED_ISSUE_RATE. */
6951 frv_issue_rate (void)
6956 switch (frv_cpu_type
)
6960 case FRV_CPU_SIMPLE
:
6968 case FRV_CPU_GENERIC
:
6970 case FRV_CPU_TOMCAT
:
6978 /* Return the value of INSN's acc_group attribute. */
6981 frv_acc_group (rtx insn
)
6983 /* This distinction only applies to the FR550 packing constraints. */
6984 if (frv_cpu_type
== FRV_CPU_FR550
)
6986 subrtx_iterator::array_type array
;
6987 FOR_EACH_SUBRTX (iter
, array
, PATTERN (insn
), NONCONST
)
6990 unsigned int regno
= REGNO (*iter
);
6991 /* If REGNO refers to an accumulator, return ACC_GROUP_ODD if
6992 the bit 2 of the register number is set and ACC_GROUP_EVEN if
6995 return (regno
- ACC_FIRST
) & 4 ? ACC_GROUP_ODD
: ACC_GROUP_EVEN
;
6997 return (regno
- ACCG_FIRST
) & 4 ? ACC_GROUP_ODD
: ACC_GROUP_EVEN
;
7000 return ACC_GROUP_NONE
;
7003 /* Return the index of the DFA unit in FRV_UNIT_NAMES[] that instruction
7004 INSN will try to claim first. Since this value depends only on the
7005 type attribute, we can cache the results in FRV_TYPE_TO_UNIT[]. */
7008 frv_insn_unit (rtx_insn
*insn
)
7010 enum attr_type type
;
7012 type
= get_attr_type (insn
);
7013 if (frv_type_to_unit
[type
] == ARRAY_SIZE (frv_unit_codes
))
7015 /* We haven't seen this type of instruction before. */
7019 /* Issue the instruction on its own to see which unit it prefers. */
7020 state
= alloca (state_size ());
7021 state_reset (state
);
7022 state_transition (state
, insn
);
7024 /* Find out which unit was taken. */
7025 for (unit
= 0; unit
< ARRAY_SIZE (frv_unit_codes
); unit
++)
7026 if (cpu_unit_reservation_p (state
, frv_unit_codes
[unit
]))
7029 gcc_assert (unit
!= ARRAY_SIZE (frv_unit_codes
));
7031 frv_type_to_unit
[type
] = unit
;
7033 return frv_type_to_unit
[type
];
7036 /* Return true if INSN issues to a branch unit. */
7039 frv_issues_to_branch_unit_p (rtx_insn
*insn
)
7041 return frv_unit_groups
[frv_insn_unit (insn
)] == GROUP_B
;
7044 /* The instructions in the packet, partitioned into groups. */
7045 struct frv_packet_group
{
7046 /* How many instructions in the packet belong to this group. */
7047 unsigned int num_insns
;
7049 /* A list of the instructions that belong to this group, in the order
7050 they appear in the rtl stream. */
7051 rtx_insn
*insns
[ARRAY_SIZE (frv_unit_codes
)];
7053 /* The contents of INSNS after they have been sorted into the correct
7054 assembly-language order. Element X issues to unit X. The list may
7055 contain extra nops. */
7056 rtx_insn
*sorted
[ARRAY_SIZE (frv_unit_codes
)];
7058 /* The member of frv_nops[] to use in sorted[]. */
7062 /* The current state of the packing pass, implemented by frv_pack_insns. */
7064 /* The state of the pipeline DFA. */
7067 /* Which hardware registers are set within the current packet,
7068 and the conditions under which they are set. */
7069 regstate_t regstate
[FIRST_PSEUDO_REGISTER
];
7071 /* The memory locations that have been modified so far in this
7072 packet. MEM is the memref and COND is the regstate_t condition
7073 under which it is set. */
7079 /* The number of valid entries in MEMS. The value is larger than
7080 ARRAY_SIZE (mems) if there were too many mems to record. */
7081 unsigned int num_mems
;
7083 /* The maximum number of instructions that can be packed together. */
7084 unsigned int issue_rate
;
7086 /* The instructions in the packet, partitioned into groups. */
7087 struct frv_packet_group groups
[NUM_GROUPS
];
7089 /* The instructions that make up the current packet. */
7090 rtx_insn
*insns
[ARRAY_SIZE (frv_unit_codes
)];
7091 unsigned int num_insns
;
7094 /* Return the regstate_t flags for the given COND_EXEC condition.
7095 Abort if the condition isn't in the right form. */
7098 frv_cond_flags (rtx cond
)
7100 gcc_assert ((GET_CODE (cond
) == EQ
|| GET_CODE (cond
) == NE
)
7101 && GET_CODE (XEXP (cond
, 0)) == REG
7102 && CR_P (REGNO (XEXP (cond
, 0)))
7103 && XEXP (cond
, 1) == const0_rtx
);
7104 return ((REGNO (XEXP (cond
, 0)) - CR_FIRST
)
7105 | (GET_CODE (cond
) == NE
7107 : REGSTATE_IF_FALSE
));
7111 /* Return true if something accessed under condition COND2 can
7112 conflict with something written under condition COND1. */
7115 frv_regstate_conflict_p (regstate_t cond1
, regstate_t cond2
)
7117 /* If either reference was unconditional, we have a conflict. */
7118 if ((cond1
& REGSTATE_IF_EITHER
) == 0
7119 || (cond2
& REGSTATE_IF_EITHER
) == 0)
7122 /* The references might conflict if they were controlled by
7124 if ((cond1
& REGSTATE_CC_MASK
) != (cond2
& REGSTATE_CC_MASK
))
7127 /* They definitely conflict if they are controlled by the
7129 if ((cond1
& cond2
& REGSTATE_IF_EITHER
) != 0)
7136 /* Return true if an instruction with pattern PAT depends on an
7137 instruction in the current packet. COND describes the condition
7138 under which PAT might be set or used. */
7141 frv_registers_conflict_p_1 (rtx pat
, regstate_t cond
)
7143 subrtx_var_iterator::array_type array
;
7144 FOR_EACH_SUBRTX_VAR (iter
, array
, pat
, NONCONST
)
7147 if (GET_CODE (x
) == REG
)
7150 FOR_EACH_REGNO (regno
, x
)
7151 if ((frv_packet
.regstate
[regno
] & REGSTATE_MODIFIED
) != 0)
7152 if (frv_regstate_conflict_p (frv_packet
.regstate
[regno
], cond
))
7155 else if (GET_CODE (x
) == MEM
)
7157 /* If we ran out of memory slots, assume a conflict. */
7158 if (frv_packet
.num_mems
> ARRAY_SIZE (frv_packet
.mems
))
7161 /* Check for output or true dependencies with earlier MEMs. */
7162 for (unsigned int i
= 0; i
< frv_packet
.num_mems
; i
++)
7163 if (frv_regstate_conflict_p (frv_packet
.mems
[i
].cond
, cond
))
7165 if (true_dependence (frv_packet
.mems
[i
].mem
, VOIDmode
, x
))
7168 if (output_dependence (frv_packet
.mems
[i
].mem
, x
))
7173 /* The return values of calls aren't significant: they describe
7174 the effect of the call as a whole, not of the insn itself. */
7175 else if (GET_CODE (x
) == SET
&& GET_CODE (SET_SRC (x
)) == CALL
)
7176 iter
.substitute (SET_SRC (x
));
7182 /* Return true if something in X might depend on an instruction
7183 in the current packet. */
7186 frv_registers_conflict_p (rtx x
)
7191 if (GET_CODE (x
) == COND_EXEC
)
7193 if (frv_registers_conflict_p_1 (XEXP (x
, 0), flags
))
7196 flags
|= frv_cond_flags (XEXP (x
, 0));
7199 return frv_registers_conflict_p_1 (x
, flags
);
7203 /* A note_stores callback. DATA points to the regstate_t condition
7204 under which X is modified. Update FRV_PACKET accordingly. */
7207 frv_registers_update_1 (rtx x
, const_rtx pat ATTRIBUTE_UNUSED
, void *data
)
7211 if (GET_CODE (x
) == REG
)
7212 FOR_EACH_REGNO (regno
, x
)
7213 frv_packet
.regstate
[regno
] |= *(regstate_t
*) data
;
7215 if (GET_CODE (x
) == MEM
)
7217 if (frv_packet
.num_mems
< ARRAY_SIZE (frv_packet
.mems
))
7219 frv_packet
.mems
[frv_packet
.num_mems
].mem
= x
;
7220 frv_packet
.mems
[frv_packet
.num_mems
].cond
= *(regstate_t
*) data
;
7222 frv_packet
.num_mems
++;
7227 /* Update the register state information for an instruction whose
7231 frv_registers_update (rtx x
)
7235 flags
= REGSTATE_MODIFIED
;
7236 if (GET_CODE (x
) == COND_EXEC
)
7238 flags
|= frv_cond_flags (XEXP (x
, 0));
7241 note_stores (x
, frv_registers_update_1
, &flags
);
7245 /* Initialize frv_packet for the start of a new packet. */
7248 frv_start_packet (void)
7250 enum frv_insn_group group
;
7252 memset (frv_packet
.regstate
, 0, sizeof (frv_packet
.regstate
));
7253 frv_packet
.num_mems
= 0;
7254 frv_packet
.num_insns
= 0;
7255 for (group
= GROUP_I
; group
< NUM_GROUPS
;
7256 group
= (enum frv_insn_group
) (group
+ 1))
7257 frv_packet
.groups
[group
].num_insns
= 0;
7261 /* Likewise for the start of a new basic block. */
7264 frv_start_packet_block (void)
7266 state_reset (frv_packet
.dfa_state
);
7267 frv_start_packet ();
7271 /* Finish the current packet, if any, and start a new one. Call
7272 HANDLE_PACKET with FRV_PACKET describing the completed packet. */
7275 frv_finish_packet (void (*handle_packet
) (void))
7277 if (frv_packet
.num_insns
> 0)
7280 state_transition (frv_packet
.dfa_state
, 0);
7281 frv_start_packet ();
7286 /* Return true if INSN can be added to the current packet. Update
7287 the DFA state on success. */
7290 frv_pack_insn_p (rtx_insn
*insn
)
7292 /* See if the packet is already as long as it can be. */
7293 if (frv_packet
.num_insns
== frv_packet
.issue_rate
)
7296 /* If the scheduler thought that an instruction should start a packet,
7297 it's usually a good idea to believe it. It knows much more about
7298 the latencies than we do.
7300 There are some exceptions though:
7302 - Conditional instructions are scheduled on the assumption that
7303 they will be executed. This is usually a good thing, since it
7304 tends to avoid unnecessary stalls in the conditional code.
7305 But we want to pack conditional instructions as tightly as
7306 possible, in order to optimize the case where they aren't
7309 - The scheduler will always put branches on their own, even
7310 if there's no real dependency.
7312 - There's no point putting a call in its own packet unless
7314 if (frv_packet
.num_insns
> 0
7315 && NONJUMP_INSN_P (insn
)
7316 && GET_MODE (insn
) == TImode
7317 && GET_CODE (PATTERN (insn
)) != COND_EXEC
)
7320 /* Check for register conflicts. Don't do this for setlo since any
7321 conflict will be with the partnering sethi, with which it can
7323 if (get_attr_type (insn
) != TYPE_SETLO
)
7324 if (frv_registers_conflict_p (PATTERN (insn
)))
7327 return state_transition (frv_packet
.dfa_state
, insn
) < 0;
7331 /* Add instruction INSN to the current packet. */
7334 frv_add_insn_to_packet (rtx_insn
*insn
)
7336 struct frv_packet_group
*packet_group
;
7338 packet_group
= &frv_packet
.groups
[frv_unit_groups
[frv_insn_unit (insn
)]];
7339 packet_group
->insns
[packet_group
->num_insns
++] = insn
;
7340 frv_packet
.insns
[frv_packet
.num_insns
++] = insn
;
7342 frv_registers_update (PATTERN (insn
));
7346 /* Insert INSN (a member of frv_nops[]) into the current packet. If the
7347 packet ends in a branch or call, insert the nop before it, otherwise
7351 frv_insert_nop_in_packet (rtx_insn
*insn
)
7353 struct frv_packet_group
*packet_group
;
7356 packet_group
= &frv_packet
.groups
[frv_unit_groups
[frv_insn_unit (insn
)]];
7357 last
= frv_packet
.insns
[frv_packet
.num_insns
- 1];
7358 if (! NONJUMP_INSN_P (last
))
7360 insn
= emit_insn_before (PATTERN (insn
), last
);
7361 frv_packet
.insns
[frv_packet
.num_insns
- 1] = insn
;
7362 frv_packet
.insns
[frv_packet
.num_insns
++] = last
;
7366 insn
= emit_insn_after (PATTERN (insn
), last
);
7367 frv_packet
.insns
[frv_packet
.num_insns
++] = insn
;
7369 packet_group
->insns
[packet_group
->num_insns
++] = insn
;
7373 /* If packing is enabled, divide the instructions into packets and
7374 return true. Call HANDLE_PACKET for each complete packet. */
7377 frv_for_each_packet (void (*handle_packet
) (void))
7379 rtx_insn
*insn
, *next_insn
;
7381 frv_packet
.issue_rate
= frv_issue_rate ();
7383 /* Early exit if we don't want to pack insns. */
7385 || !flag_schedule_insns_after_reload
7386 || !TARGET_VLIW_BRANCH
7387 || frv_packet
.issue_rate
== 1)
7390 /* Set up the initial packing state. */
7392 frv_packet
.dfa_state
= alloca (state_size ());
7394 frv_start_packet_block ();
7395 for (insn
= get_insns (); insn
!= 0; insn
= next_insn
)
7400 code
= GET_CODE (insn
);
7401 next_insn
= NEXT_INSN (insn
);
7403 if (code
== CODE_LABEL
)
7405 frv_finish_packet (handle_packet
);
7406 frv_start_packet_block ();
7410 switch (GET_CODE (PATTERN (insn
)))
7417 /* Calls mustn't be packed on a TOMCAT. */
7418 if (CALL_P (insn
) && frv_cpu_type
== FRV_CPU_TOMCAT
)
7419 frv_finish_packet (handle_packet
);
7421 /* Since the last instruction in a packet determines the EH
7422 region, any exception-throwing instruction must come at
7423 the end of reordered packet. Insns that issue to a
7424 branch unit are bound to come last; for others it's
7425 too hard to predict. */
7426 eh_insn_p
= (find_reg_note (insn
, REG_EH_REGION
, NULL
) != NULL
);
7427 if (eh_insn_p
&& !frv_issues_to_branch_unit_p (insn
))
7428 frv_finish_packet (handle_packet
);
7430 /* Finish the current packet if we can't add INSN to it.
7431 Simulate cycles until INSN is ready to issue. */
7432 if (!frv_pack_insn_p (insn
))
7434 frv_finish_packet (handle_packet
);
7435 while (!frv_pack_insn_p (insn
))
7436 state_transition (frv_packet
.dfa_state
, 0);
7439 /* Add the instruction to the packet. */
7440 frv_add_insn_to_packet (insn
);
7442 /* Calls and jumps end a packet, as do insns that throw
7444 if (code
== CALL_INSN
|| code
== JUMP_INSN
|| eh_insn_p
)
7445 frv_finish_packet (handle_packet
);
7449 frv_finish_packet (handle_packet
);
7454 /* Subroutine of frv_sort_insn_group. We are trying to sort
7455 frv_packet.groups[GROUP].sorted[0...NUM_INSNS-1] into assembly
7456 language order. We have already picked a new position for
7457 frv_packet.groups[GROUP].sorted[X] if bit X of ISSUED is set.
7458 These instructions will occupy elements [0, LOWER_SLOT) and
7459 [UPPER_SLOT, NUM_INSNS) of the final (sorted) array. STATE is
7460 the DFA state after issuing these instructions.
7462 Try filling elements [LOWER_SLOT, UPPER_SLOT) with every permutation
7463 of the unused instructions. Return true if one such permutation gives
7464 a valid ordering, leaving the successful permutation in sorted[].
7465 Do not modify sorted[] until a valid permutation is found. */
7468 frv_sort_insn_group_1 (enum frv_insn_group group
,
7469 unsigned int lower_slot
, unsigned int upper_slot
,
7470 unsigned int issued
, unsigned int num_insns
,
7473 struct frv_packet_group
*packet_group
;
7479 /* Early success if we've filled all the slots. */
7480 if (lower_slot
== upper_slot
)
7483 packet_group
= &frv_packet
.groups
[group
];
7484 dfa_size
= state_size ();
7485 test_state
= alloca (dfa_size
);
7487 /* Try issuing each unused instruction. */
7488 for (i
= num_insns
- 1; i
+ 1 != 0; i
--)
7489 if (~issued
& (1 << i
))
7491 insn
= packet_group
->sorted
[i
];
7492 memcpy (test_state
, state
, dfa_size
);
7493 if (state_transition (test_state
, insn
) < 0
7494 && cpu_unit_reservation_p (test_state
,
7495 NTH_UNIT (group
, upper_slot
- 1))
7496 && frv_sort_insn_group_1 (group
, lower_slot
, upper_slot
- 1,
7497 issued
| (1 << i
), num_insns
,
7500 packet_group
->sorted
[upper_slot
- 1] = insn
;
7508 /* Compare two instructions by their frv_insn_unit. */
7511 frv_compare_insns (const void *first
, const void *second
)
7513 rtx_insn
* const *insn1
= (rtx_insn
* const *) first
;
7514 rtx_insn
* const *insn2
= (rtx_insn
* const *) second
;
7515 return frv_insn_unit (*insn1
) - frv_insn_unit (*insn2
);
7518 /* Copy frv_packet.groups[GROUP].insns[] to frv_packet.groups[GROUP].sorted[]
7519 and sort it into assembly language order. See frv.md for a description of
7523 frv_sort_insn_group (enum frv_insn_group group
)
7525 struct frv_packet_group
*packet_group
;
7526 unsigned int first
, i
, nop
, max_unit
, num_slots
;
7527 state_t state
, test_state
;
7530 packet_group
= &frv_packet
.groups
[group
];
7532 /* Assume no nop is needed. */
7533 packet_group
->nop
= 0;
7535 if (packet_group
->num_insns
== 0)
7538 /* Copy insns[] to sorted[]. */
7539 memcpy (packet_group
->sorted
, packet_group
->insns
,
7540 sizeof (rtx
) * packet_group
->num_insns
);
7542 /* Sort sorted[] by the unit that each insn tries to take first. */
7543 if (packet_group
->num_insns
> 1)
7544 qsort (packet_group
->sorted
, packet_group
->num_insns
,
7545 sizeof (rtx
), frv_compare_insns
);
7547 /* That's always enough for branch and control insns. */
7548 if (group
== GROUP_B
|| group
== GROUP_C
)
7551 dfa_size
= state_size ();
7552 state
= alloca (dfa_size
);
7553 test_state
= alloca (dfa_size
);
7555 /* Find the highest FIRST such that sorted[0...FIRST-1] can issue
7556 consecutively and such that the DFA takes unit X when sorted[X]
7557 is added. Set STATE to the new DFA state. */
7558 state_reset (test_state
);
7559 for (first
= 0; first
< packet_group
->num_insns
; first
++)
7561 memcpy (state
, test_state
, dfa_size
);
7562 if (state_transition (test_state
, packet_group
->sorted
[first
]) >= 0
7563 || !cpu_unit_reservation_p (test_state
, NTH_UNIT (group
, first
)))
7567 /* If all the instructions issued in ascending order, we're done. */
7568 if (first
== packet_group
->num_insns
)
7571 /* Add nops to the end of sorted[] and try each permutation until
7572 we find one that works. */
7573 for (nop
= 0; nop
< frv_num_nops
; nop
++)
7575 max_unit
= frv_insn_unit (frv_nops
[nop
]);
7576 if (frv_unit_groups
[max_unit
] == group
)
7578 packet_group
->nop
= frv_nops
[nop
];
7579 num_slots
= UNIT_NUMBER (max_unit
) + 1;
7580 for (i
= packet_group
->num_insns
; i
< num_slots
; i
++)
7581 packet_group
->sorted
[i
] = frv_nops
[nop
];
7582 if (frv_sort_insn_group_1 (group
, first
, num_slots
,
7583 (1 << first
) - 1, num_slots
, state
))
7590 /* Sort the current packet into assembly-language order. Set packing
7591 flags as appropriate. */
7594 frv_reorder_packet (void)
7596 unsigned int cursor
[NUM_GROUPS
];
7597 rtx insns
[ARRAY_SIZE (frv_unit_groups
)];
7598 unsigned int unit
, to
, from
;
7599 enum frv_insn_group group
;
7600 struct frv_packet_group
*packet_group
;
7602 /* First sort each group individually. */
7603 for (group
= GROUP_I
; group
< NUM_GROUPS
;
7604 group
= (enum frv_insn_group
) (group
+ 1))
7607 frv_sort_insn_group (group
);
7610 /* Go through the unit template and try add an instruction from
7611 that unit's group. */
7613 for (unit
= 0; unit
< ARRAY_SIZE (frv_unit_groups
); unit
++)
7615 group
= frv_unit_groups
[unit
];
7616 packet_group
= &frv_packet
.groups
[group
];
7617 if (cursor
[group
] < packet_group
->num_insns
)
7619 /* frv_reorg should have added nops for us. */
7620 gcc_assert (packet_group
->sorted
[cursor
[group
]]
7621 != packet_group
->nop
);
7622 insns
[to
++] = packet_group
->sorted
[cursor
[group
]++];
7626 gcc_assert (to
== frv_packet
.num_insns
);
7628 /* Clear the last instruction's packing flag, thus marking the end of
7629 a packet. Reorder the other instructions relative to it. */
7630 CLEAR_PACKING_FLAG (insns
[to
- 1]);
7631 for (from
= 0; from
< to
- 1; from
++)
7633 remove_insn (insns
[from
]);
7634 add_insn_before (insns
[from
], insns
[to
- 1], NULL
);
7635 SET_PACKING_FLAG (insns
[from
]);
7640 /* Divide instructions into packets. Reorder the contents of each
7641 packet so that they are in the correct assembly-language order.
7643 Since this pass can change the raw meaning of the rtl stream, it must
7644 only be called at the last minute, just before the instructions are
7648 frv_pack_insns (void)
7650 if (frv_for_each_packet (frv_reorder_packet
))
7651 frv_insn_packing_flag
= 0;
7653 frv_insn_packing_flag
= -1;
7656 /* See whether we need to add nops to group GROUP in order to
7657 make a valid packet. */
7660 frv_fill_unused_units (enum frv_insn_group group
)
7662 unsigned int non_nops
, nops
, i
;
7663 struct frv_packet_group
*packet_group
;
7665 packet_group
= &frv_packet
.groups
[group
];
7667 /* Sort the instructions into assembly-language order.
7668 Use nops to fill slots that are otherwise unused. */
7669 frv_sort_insn_group (group
);
7671 /* See how many nops are needed before the final useful instruction. */
7673 for (non_nops
= 0; non_nops
< packet_group
->num_insns
; non_nops
++)
7674 while (packet_group
->sorted
[i
++] == packet_group
->nop
)
7677 /* Insert that many nops into the instruction stream. */
7679 frv_insert_nop_in_packet (packet_group
->nop
);
7682 /* Return true if accesses IO1 and IO2 refer to the same doubleword. */
7685 frv_same_doubleword_p (const struct frv_io
*io1
, const struct frv_io
*io2
)
7687 if (io1
->const_address
!= 0 && io2
->const_address
!= 0)
7688 return io1
->const_address
== io2
->const_address
;
7690 if (io1
->var_address
!= 0 && io2
->var_address
!= 0)
7691 return rtx_equal_p (io1
->var_address
, io2
->var_address
);
7696 /* Return true if operations IO1 and IO2 are guaranteed to complete
7700 frv_io_fixed_order_p (const struct frv_io
*io1
, const struct frv_io
*io2
)
7702 /* The order of writes is always preserved. */
7703 if (io1
->type
== FRV_IO_WRITE
&& io2
->type
== FRV_IO_WRITE
)
7706 /* The order of reads isn't preserved. */
7707 if (io1
->type
!= FRV_IO_WRITE
&& io2
->type
!= FRV_IO_WRITE
)
7710 /* One operation is a write and the other is (or could be) a read.
7711 The order is only guaranteed if the accesses are to the same
7713 return frv_same_doubleword_p (io1
, io2
);
7716 /* Generalize I/O operation X so that it covers both X and Y. */
7719 frv_io_union (struct frv_io
*x
, const struct frv_io
*y
)
7721 if (x
->type
!= y
->type
)
7722 x
->type
= FRV_IO_UNKNOWN
;
7723 if (!frv_same_doubleword_p (x
, y
))
7725 x
->const_address
= 0;
7730 /* Fill IO with information about the load or store associated with
7731 membar instruction INSN. */
7734 frv_extract_membar (struct frv_io
*io
, rtx_insn
*insn
)
7736 extract_insn (insn
);
7737 io
->type
= (enum frv_io_type
) INTVAL (recog_data
.operand
[2]);
7738 io
->const_address
= INTVAL (recog_data
.operand
[1]);
7739 io
->var_address
= XEXP (recog_data
.operand
[0], 0);
7742 /* A note_stores callback for which DATA points to an rtx. Nullify *DATA
7743 if X is a register and *DATA depends on X. */
7746 frv_io_check_address (rtx x
, const_rtx pat ATTRIBUTE_UNUSED
, void *data
)
7748 rtx
*other
= (rtx
*) data
;
7750 if (REG_P (x
) && *other
!= 0 && reg_overlap_mentioned_p (x
, *other
))
7754 /* A note_stores callback for which DATA points to a HARD_REG_SET.
7755 Remove every modified register from the set. */
7758 frv_io_handle_set (rtx x
, const_rtx pat ATTRIBUTE_UNUSED
, void *data
)
7760 HARD_REG_SET
*set
= (HARD_REG_SET
*) data
;
7764 FOR_EACH_REGNO (regno
, x
)
7765 CLEAR_HARD_REG_BIT (*set
, regno
);
7768 /* A note_uses callback that adds all registers in *X to hard register
7772 frv_io_handle_use (rtx
*x
, void *data
)
7774 find_all_hard_regs (*x
, (HARD_REG_SET
*) data
);
7777 /* Go through block BB looking for membars to remove. There are two
7778 cases where intra-block analysis is enough:
7780 - a membar is redundant if it occurs between two consecutive I/O
7781 operations and if those operations are guaranteed to complete
7784 - a membar for a __builtin_read is redundant if the result is
7785 used before the next I/O operation is issued.
7787 If the last membar in the block could not be removed, and there
7788 are guaranteed to be no I/O operations between that membar and
7789 the end of the block, store the membar in *LAST_MEMBAR, otherwise
7792 Describe the block's first I/O operation in *NEXT_IO. Describe
7793 an unknown operation if the block doesn't do any I/O. */
7796 frv_optimize_membar_local (basic_block bb
, struct frv_io
*next_io
,
7797 rtx_insn
**last_membar
)
7799 HARD_REG_SET used_regs
;
7800 rtx next_membar
, set
;
7804 /* NEXT_IO is the next I/O operation to be performed after the current
7805 instruction. It starts off as being an unknown operation. */
7806 memset (next_io
, 0, sizeof (*next_io
));
7808 /* NEXT_IS_END_P is true if NEXT_IO describes the end of the block. */
7809 next_is_end_p
= true;
7811 /* If the current instruction is a __builtin_read or __builtin_write,
7812 NEXT_MEMBAR is the membar instruction associated with it. NEXT_MEMBAR
7813 is null if the membar has already been deleted.
7815 Note that the initialization here should only be needed to
7816 suppress warnings. */
7819 /* USED_REGS is the set of registers that are used before the
7820 next I/O instruction. */
7821 CLEAR_HARD_REG_SET (used_regs
);
7823 for (insn
= BB_END (bb
); insn
!= BB_HEAD (bb
); insn
= PREV_INSN (insn
))
7826 /* We can't predict what a call will do to volatile memory. */
7827 memset (next_io
, 0, sizeof (struct frv_io
));
7828 next_is_end_p
= false;
7829 CLEAR_HARD_REG_SET (used_regs
);
7831 else if (INSN_P (insn
))
7832 switch (recog_memoized (insn
))
7834 case CODE_FOR_optional_membar_qi
:
7835 case CODE_FOR_optional_membar_hi
:
7836 case CODE_FOR_optional_membar_si
:
7837 case CODE_FOR_optional_membar_di
:
7841 /* Local information isn't enough to decide whether this
7842 membar is needed. Stash it away for later. */
7843 *last_membar
= insn
;
7844 frv_extract_membar (next_io
, insn
);
7845 next_is_end_p
= false;
7849 /* Check whether the I/O operation before INSN could be
7850 reordered with one described by NEXT_IO. If it can't,
7851 INSN will not be needed. */
7852 struct frv_io prev_io
;
7854 frv_extract_membar (&prev_io
, insn
);
7855 if (frv_io_fixed_order_p (&prev_io
, next_io
))
7859 ";; [Local] Removing membar %d since order"
7860 " of accesses is guaranteed\n",
7861 INSN_UID (next_membar
));
7863 insn
= NEXT_INSN (insn
);
7864 delete_insn (next_membar
);
7872 /* Invalidate NEXT_IO's address if it depends on something that
7873 is clobbered by INSN. */
7874 if (next_io
->var_address
)
7875 note_stores (PATTERN (insn
), frv_io_check_address
,
7876 &next_io
->var_address
);
7878 /* If the next membar is associated with a __builtin_read,
7879 see if INSN reads from that address. If it does, and if
7880 the destination register is used before the next I/O access,
7881 there is no need for the membar. */
7882 set
= PATTERN (insn
);
7883 if (next_io
->type
== FRV_IO_READ
7884 && next_io
->var_address
!= 0
7886 && GET_CODE (set
) == SET
7887 && GET_CODE (SET_DEST (set
)) == REG
7888 && TEST_HARD_REG_BIT (used_regs
, REGNO (SET_DEST (set
))))
7892 src
= SET_SRC (set
);
7893 if (GET_CODE (src
) == ZERO_EXTEND
)
7894 src
= XEXP (src
, 0);
7896 if (GET_CODE (src
) == MEM
7897 && rtx_equal_p (XEXP (src
, 0), next_io
->var_address
))
7901 ";; [Local] Removing membar %d since the target"
7902 " of %d is used before the I/O operation\n",
7903 INSN_UID (next_membar
), INSN_UID (insn
));
7905 if (next_membar
== *last_membar
)
7908 delete_insn (next_membar
);
7913 /* If INSN has volatile references, forget about any registers
7914 that are used after it. Otherwise forget about uses that
7915 are (or might be) defined by INSN. */
7916 if (volatile_refs_p (PATTERN (insn
)))
7917 CLEAR_HARD_REG_SET (used_regs
);
7919 note_stores (PATTERN (insn
), frv_io_handle_set
, &used_regs
);
7921 note_uses (&PATTERN (insn
), frv_io_handle_use
, &used_regs
);
7926 /* See if MEMBAR, the last membar instruction in BB, can be removed.
7927 FIRST_IO[X] describes the first operation performed by basic block X. */
7930 frv_optimize_membar_global (basic_block bb
, struct frv_io
*first_io
,
7933 struct frv_io this_io
, next_io
;
7937 /* We need to keep the membar if there is an edge to the exit block. */
7938 FOR_EACH_EDGE (succ
, ei
, bb
->succs
)
7939 /* for (succ = bb->succ; succ != 0; succ = succ->succ_next) */
7940 if (succ
->dest
== EXIT_BLOCK_PTR_FOR_FN (cfun
))
7943 /* Work out the union of all successor blocks. */
7944 ei
= ei_start (bb
->succs
);
7945 ei_cond (ei
, &succ
);
7946 /* next_io = first_io[bb->succ->dest->index]; */
7947 next_io
= first_io
[succ
->dest
->index
];
7948 ei
= ei_start (bb
->succs
);
7949 if (ei_cond (ei
, &succ
))
7951 for (ei_next (&ei
); ei_cond (ei
, &succ
); ei_next (&ei
))
7952 /*for (succ = bb->succ->succ_next; succ != 0; succ = succ->succ_next)*/
7953 frv_io_union (&next_io
, &first_io
[succ
->dest
->index
]);
7958 frv_extract_membar (&this_io
, membar
);
7959 if (frv_io_fixed_order_p (&this_io
, &next_io
))
7963 ";; [Global] Removing membar %d since order of accesses"
7964 " is guaranteed\n", INSN_UID (membar
));
7966 delete_insn (membar
);
7970 /* Remove redundant membars from the current function. */
7973 frv_optimize_membar (void)
7976 struct frv_io
*first_io
;
7977 rtx_insn
**last_membar
;
7979 compute_bb_for_insn ();
7980 first_io
= XCNEWVEC (struct frv_io
, last_basic_block_for_fn (cfun
));
7981 last_membar
= XCNEWVEC (rtx_insn
*, last_basic_block_for_fn (cfun
));
7983 FOR_EACH_BB_FN (bb
, cfun
)
7984 frv_optimize_membar_local (bb
, &first_io
[bb
->index
],
7985 &last_membar
[bb
->index
]);
7987 FOR_EACH_BB_FN (bb
, cfun
)
7988 if (last_membar
[bb
->index
] != 0)
7989 frv_optimize_membar_global (bb
, first_io
, last_membar
[bb
->index
]);
7995 /* Used by frv_reorg to keep track of the current packet's address. */
7996 static unsigned int frv_packet_address
;
7998 /* If the current packet falls through to a label, try to pad the packet
7999 with nops in order to fit the label's alignment requirements. */
8002 frv_align_label (void)
8004 unsigned int alignment
, target
, nop
;
8005 rtx_insn
*x
, *last
, *barrier
, *label
;
8007 /* Walk forward to the start of the next packet. Set ALIGNMENT to the
8008 maximum alignment of that packet, LABEL to the last label between
8009 the packets, and BARRIER to the last barrier. */
8010 last
= frv_packet
.insns
[frv_packet
.num_insns
- 1];
8011 label
= barrier
= 0;
8013 for (x
= NEXT_INSN (last
); x
!= 0 && !INSN_P (x
); x
= NEXT_INSN (x
))
8017 unsigned int subalign
= 1 << label_to_alignment (x
);
8018 alignment
= MAX (alignment
, subalign
);
8025 /* If -malign-labels, and the packet falls through to an unaligned
8026 label, try introducing a nop to align that label to 8 bytes. */
8027 if (TARGET_ALIGN_LABELS
8030 && frv_packet
.num_insns
< frv_packet
.issue_rate
)
8031 alignment
= MAX (alignment
, 8);
8033 /* Advance the address to the end of the current packet. */
8034 frv_packet_address
+= frv_packet
.num_insns
* 4;
8036 /* Work out the target address, after alignment. */
8037 target
= (frv_packet_address
+ alignment
- 1) & -alignment
;
8039 /* If the packet falls through to the label, try to find an efficient
8040 padding sequence. */
8043 /* First try adding nops to the current packet. */
8044 for (nop
= 0; nop
< frv_num_nops
; nop
++)
8045 while (frv_packet_address
< target
&& frv_pack_insn_p (frv_nops
[nop
]))
8047 frv_insert_nop_in_packet (frv_nops
[nop
]);
8048 frv_packet_address
+= 4;
8051 /* If we still haven't reached the target, add some new packets that
8052 contain only nops. If there are two types of nop, insert an
8053 alternating sequence of frv_nops[0] and frv_nops[1], which will
8054 lead to packets like:
8061 etc. Just emit frv_nops[0] if that's the only nop we have. */
8062 last
= frv_packet
.insns
[frv_packet
.num_insns
- 1];
8064 while (frv_packet_address
< target
)
8066 last
= emit_insn_after (PATTERN (frv_nops
[nop
]), last
);
8067 frv_packet_address
+= 4;
8068 if (frv_num_nops
> 1)
8073 frv_packet_address
= target
;
8076 /* Subroutine of frv_reorg, called after each packet has been constructed
8080 frv_reorg_packet (void)
8082 frv_fill_unused_units (GROUP_I
);
8083 frv_fill_unused_units (GROUP_FM
);
8087 /* Add an instruction with pattern NOP to frv_nops[]. */
8090 frv_register_nop (rtx nop
)
8092 rtx_insn
*nop_insn
= make_insn_raw (nop
);
8093 SET_NEXT_INSN (nop_insn
) = 0;
8094 SET_PREV_INSN (nop_insn
) = 0;
8095 frv_nops
[frv_num_nops
++] = nop_insn
;
8098 /* Implement TARGET_MACHINE_DEPENDENT_REORG. Divide the instructions
8099 into packets and check whether we need to insert nops in order to
8100 fulfill the processor's issue requirements. Also, if the user has
8101 requested a certain alignment for a label, try to meet that alignment
8102 by inserting nops in the previous packet. */
8107 if (optimize
> 0 && TARGET_OPTIMIZE_MEMBAR
&& cfun
->machine
->has_membar_p
)
8108 frv_optimize_membar ();
8111 frv_register_nop (gen_nop ());
8113 frv_register_nop (gen_mnop ());
8114 if (TARGET_HARD_FLOAT
)
8115 frv_register_nop (gen_fnop ());
8117 /* Estimate the length of each branch. Although this may change after
8118 we've inserted nops, it will only do so in big functions. */
8119 shorten_branches (get_insns ());
8121 frv_packet_address
= 0;
8122 frv_for_each_packet (frv_reorg_packet
);
8125 #define def_builtin(name, type, code) \
8126 add_builtin_function ((name), (type), (code), BUILT_IN_MD, NULL, NULL)
8128 struct builtin_description
8130 enum insn_code icode
;
8132 enum frv_builtins code
;
8133 enum rtx_code comparison
;
8137 /* Media intrinsics that take a single, constant argument. */
8139 static struct builtin_description bdesc_set
[] =
8141 { CODE_FOR_mhdsets
, "__MHDSETS", FRV_BUILTIN_MHDSETS
, UNKNOWN
, 0 }
8144 /* Media intrinsics that take just one argument. */
8146 static struct builtin_description bdesc_1arg
[] =
8148 { CODE_FOR_mnot
, "__MNOT", FRV_BUILTIN_MNOT
, UNKNOWN
, 0 },
8149 { CODE_FOR_munpackh
, "__MUNPACKH", FRV_BUILTIN_MUNPACKH
, UNKNOWN
, 0 },
8150 { CODE_FOR_mbtoh
, "__MBTOH", FRV_BUILTIN_MBTOH
, UNKNOWN
, 0 },
8151 { CODE_FOR_mhtob
, "__MHTOB", FRV_BUILTIN_MHTOB
, UNKNOWN
, 0},
8152 { CODE_FOR_mabshs
, "__MABSHS", FRV_BUILTIN_MABSHS
, UNKNOWN
, 0 },
8153 { CODE_FOR_scutss
, "__SCUTSS", FRV_BUILTIN_SCUTSS
, UNKNOWN
, 0 }
8156 /* Media intrinsics that take two arguments. */
8158 static struct builtin_description bdesc_2arg
[] =
8160 { CODE_FOR_mand
, "__MAND", FRV_BUILTIN_MAND
, UNKNOWN
, 0},
8161 { CODE_FOR_mor
, "__MOR", FRV_BUILTIN_MOR
, UNKNOWN
, 0},
8162 { CODE_FOR_mxor
, "__MXOR", FRV_BUILTIN_MXOR
, UNKNOWN
, 0},
8163 { CODE_FOR_maveh
, "__MAVEH", FRV_BUILTIN_MAVEH
, UNKNOWN
, 0},
8164 { CODE_FOR_msaths
, "__MSATHS", FRV_BUILTIN_MSATHS
, UNKNOWN
, 0},
8165 { CODE_FOR_msathu
, "__MSATHU", FRV_BUILTIN_MSATHU
, UNKNOWN
, 0},
8166 { CODE_FOR_maddhss
, "__MADDHSS", FRV_BUILTIN_MADDHSS
, UNKNOWN
, 0},
8167 { CODE_FOR_maddhus
, "__MADDHUS", FRV_BUILTIN_MADDHUS
, UNKNOWN
, 0},
8168 { CODE_FOR_msubhss
, "__MSUBHSS", FRV_BUILTIN_MSUBHSS
, UNKNOWN
, 0},
8169 { CODE_FOR_msubhus
, "__MSUBHUS", FRV_BUILTIN_MSUBHUS
, UNKNOWN
, 0},
8170 { CODE_FOR_mqaddhss
, "__MQADDHSS", FRV_BUILTIN_MQADDHSS
, UNKNOWN
, 0},
8171 { CODE_FOR_mqaddhus
, "__MQADDHUS", FRV_BUILTIN_MQADDHUS
, UNKNOWN
, 0},
8172 { CODE_FOR_mqsubhss
, "__MQSUBHSS", FRV_BUILTIN_MQSUBHSS
, UNKNOWN
, 0},
8173 { CODE_FOR_mqsubhus
, "__MQSUBHUS", FRV_BUILTIN_MQSUBHUS
, UNKNOWN
, 0},
8174 { CODE_FOR_mpackh
, "__MPACKH", FRV_BUILTIN_MPACKH
, UNKNOWN
, 0},
8175 { CODE_FOR_mcop1
, "__Mcop1", FRV_BUILTIN_MCOP1
, UNKNOWN
, 0},
8176 { CODE_FOR_mcop2
, "__Mcop2", FRV_BUILTIN_MCOP2
, UNKNOWN
, 0},
8177 { CODE_FOR_mwcut
, "__MWCUT", FRV_BUILTIN_MWCUT
, UNKNOWN
, 0},
8178 { CODE_FOR_mqsaths
, "__MQSATHS", FRV_BUILTIN_MQSATHS
, UNKNOWN
, 0},
8179 { CODE_FOR_mqlclrhs
, "__MQLCLRHS", FRV_BUILTIN_MQLCLRHS
, UNKNOWN
, 0},
8180 { CODE_FOR_mqlmths
, "__MQLMTHS", FRV_BUILTIN_MQLMTHS
, UNKNOWN
, 0},
8181 { CODE_FOR_smul
, "__SMUL", FRV_BUILTIN_SMUL
, UNKNOWN
, 0},
8182 { CODE_FOR_umul
, "__UMUL", FRV_BUILTIN_UMUL
, UNKNOWN
, 0},
8183 { CODE_FOR_addss
, "__ADDSS", FRV_BUILTIN_ADDSS
, UNKNOWN
, 0},
8184 { CODE_FOR_subss
, "__SUBSS", FRV_BUILTIN_SUBSS
, UNKNOWN
, 0},
8185 { CODE_FOR_slass
, "__SLASS", FRV_BUILTIN_SLASS
, UNKNOWN
, 0},
8186 { CODE_FOR_scan
, "__SCAN", FRV_BUILTIN_SCAN
, UNKNOWN
, 0}
8189 /* Integer intrinsics that take two arguments and have no return value. */
8191 static struct builtin_description bdesc_int_void2arg
[] =
8193 { CODE_FOR_smass
, "__SMASS", FRV_BUILTIN_SMASS
, UNKNOWN
, 0},
8194 { CODE_FOR_smsss
, "__SMSSS", FRV_BUILTIN_SMSSS
, UNKNOWN
, 0},
8195 { CODE_FOR_smu
, "__SMU", FRV_BUILTIN_SMU
, UNKNOWN
, 0}
8198 static struct builtin_description bdesc_prefetches
[] =
8200 { CODE_FOR_frv_prefetch0
, "__data_prefetch0", FRV_BUILTIN_PREFETCH0
, UNKNOWN
,
8202 { CODE_FOR_frv_prefetch
, "__data_prefetch", FRV_BUILTIN_PREFETCH
, UNKNOWN
, 0}
8205 /* Media intrinsics that take two arguments, the first being an ACC number. */
8207 static struct builtin_description bdesc_cut
[] =
8209 { CODE_FOR_mcut
, "__MCUT", FRV_BUILTIN_MCUT
, UNKNOWN
, 0},
8210 { CODE_FOR_mcutss
, "__MCUTSS", FRV_BUILTIN_MCUTSS
, UNKNOWN
, 0},
8211 { CODE_FOR_mdcutssi
, "__MDCUTSSI", FRV_BUILTIN_MDCUTSSI
, UNKNOWN
, 0}
8214 /* Two-argument media intrinsics with an immediate second argument. */
8216 static struct builtin_description bdesc_2argimm
[] =
8218 { CODE_FOR_mrotli
, "__MROTLI", FRV_BUILTIN_MROTLI
, UNKNOWN
, 0},
8219 { CODE_FOR_mrotri
, "__MROTRI", FRV_BUILTIN_MROTRI
, UNKNOWN
, 0},
8220 { CODE_FOR_msllhi
, "__MSLLHI", FRV_BUILTIN_MSLLHI
, UNKNOWN
, 0},
8221 { CODE_FOR_msrlhi
, "__MSRLHI", FRV_BUILTIN_MSRLHI
, UNKNOWN
, 0},
8222 { CODE_FOR_msrahi
, "__MSRAHI", FRV_BUILTIN_MSRAHI
, UNKNOWN
, 0},
8223 { CODE_FOR_mexpdhw
, "__MEXPDHW", FRV_BUILTIN_MEXPDHW
, UNKNOWN
, 0},
8224 { CODE_FOR_mexpdhd
, "__MEXPDHD", FRV_BUILTIN_MEXPDHD
, UNKNOWN
, 0},
8225 { CODE_FOR_mdrotli
, "__MDROTLI", FRV_BUILTIN_MDROTLI
, UNKNOWN
, 0},
8226 { CODE_FOR_mcplhi
, "__MCPLHI", FRV_BUILTIN_MCPLHI
, UNKNOWN
, 0},
8227 { CODE_FOR_mcpli
, "__MCPLI", FRV_BUILTIN_MCPLI
, UNKNOWN
, 0},
8228 { CODE_FOR_mhsetlos
, "__MHSETLOS", FRV_BUILTIN_MHSETLOS
, UNKNOWN
, 0},
8229 { CODE_FOR_mhsetloh
, "__MHSETLOH", FRV_BUILTIN_MHSETLOH
, UNKNOWN
, 0},
8230 { CODE_FOR_mhsethis
, "__MHSETHIS", FRV_BUILTIN_MHSETHIS
, UNKNOWN
, 0},
8231 { CODE_FOR_mhsethih
, "__MHSETHIH", FRV_BUILTIN_MHSETHIH
, UNKNOWN
, 0},
8232 { CODE_FOR_mhdseth
, "__MHDSETH", FRV_BUILTIN_MHDSETH
, UNKNOWN
, 0},
8233 { CODE_FOR_mqsllhi
, "__MQSLLHI", FRV_BUILTIN_MQSLLHI
, UNKNOWN
, 0},
8234 { CODE_FOR_mqsrahi
, "__MQSRAHI", FRV_BUILTIN_MQSRAHI
, UNKNOWN
, 0}
8237 /* Media intrinsics that take two arguments and return void, the first argument
8238 being a pointer to 4 words in memory. */
8240 static struct builtin_description bdesc_void2arg
[] =
8242 { CODE_FOR_mdunpackh
, "__MDUNPACKH", FRV_BUILTIN_MDUNPACKH
, UNKNOWN
, 0},
8243 { CODE_FOR_mbtohe
, "__MBTOHE", FRV_BUILTIN_MBTOHE
, UNKNOWN
, 0},
8246 /* Media intrinsics that take three arguments, the first being a const_int that
8247 denotes an accumulator, and that return void. */
8249 static struct builtin_description bdesc_void3arg
[] =
8251 { CODE_FOR_mcpxrs
, "__MCPXRS", FRV_BUILTIN_MCPXRS
, UNKNOWN
, 0},
8252 { CODE_FOR_mcpxru
, "__MCPXRU", FRV_BUILTIN_MCPXRU
, UNKNOWN
, 0},
8253 { CODE_FOR_mcpxis
, "__MCPXIS", FRV_BUILTIN_MCPXIS
, UNKNOWN
, 0},
8254 { CODE_FOR_mcpxiu
, "__MCPXIU", FRV_BUILTIN_MCPXIU
, UNKNOWN
, 0},
8255 { CODE_FOR_mmulhs
, "__MMULHS", FRV_BUILTIN_MMULHS
, UNKNOWN
, 0},
8256 { CODE_FOR_mmulhu
, "__MMULHU", FRV_BUILTIN_MMULHU
, UNKNOWN
, 0},
8257 { CODE_FOR_mmulxhs
, "__MMULXHS", FRV_BUILTIN_MMULXHS
, UNKNOWN
, 0},
8258 { CODE_FOR_mmulxhu
, "__MMULXHU", FRV_BUILTIN_MMULXHU
, UNKNOWN
, 0},
8259 { CODE_FOR_mmachs
, "__MMACHS", FRV_BUILTIN_MMACHS
, UNKNOWN
, 0},
8260 { CODE_FOR_mmachu
, "__MMACHU", FRV_BUILTIN_MMACHU
, UNKNOWN
, 0},
8261 { CODE_FOR_mmrdhs
, "__MMRDHS", FRV_BUILTIN_MMRDHS
, UNKNOWN
, 0},
8262 { CODE_FOR_mmrdhu
, "__MMRDHU", FRV_BUILTIN_MMRDHU
, UNKNOWN
, 0},
8263 { CODE_FOR_mqcpxrs
, "__MQCPXRS", FRV_BUILTIN_MQCPXRS
, UNKNOWN
, 0},
8264 { CODE_FOR_mqcpxru
, "__MQCPXRU", FRV_BUILTIN_MQCPXRU
, UNKNOWN
, 0},
8265 { CODE_FOR_mqcpxis
, "__MQCPXIS", FRV_BUILTIN_MQCPXIS
, UNKNOWN
, 0},
8266 { CODE_FOR_mqcpxiu
, "__MQCPXIU", FRV_BUILTIN_MQCPXIU
, UNKNOWN
, 0},
8267 { CODE_FOR_mqmulhs
, "__MQMULHS", FRV_BUILTIN_MQMULHS
, UNKNOWN
, 0},
8268 { CODE_FOR_mqmulhu
, "__MQMULHU", FRV_BUILTIN_MQMULHU
, UNKNOWN
, 0},
8269 { CODE_FOR_mqmulxhs
, "__MQMULXHS", FRV_BUILTIN_MQMULXHS
, UNKNOWN
, 0},
8270 { CODE_FOR_mqmulxhu
, "__MQMULXHU", FRV_BUILTIN_MQMULXHU
, UNKNOWN
, 0},
8271 { CODE_FOR_mqmachs
, "__MQMACHS", FRV_BUILTIN_MQMACHS
, UNKNOWN
, 0},
8272 { CODE_FOR_mqmachu
, "__MQMACHU", FRV_BUILTIN_MQMACHU
, UNKNOWN
, 0},
8273 { CODE_FOR_mqxmachs
, "__MQXMACHS", FRV_BUILTIN_MQXMACHS
, UNKNOWN
, 0},
8274 { CODE_FOR_mqxmacxhs
, "__MQXMACXHS", FRV_BUILTIN_MQXMACXHS
, UNKNOWN
, 0},
8275 { CODE_FOR_mqmacxhs
, "__MQMACXHS", FRV_BUILTIN_MQMACXHS
, UNKNOWN
, 0}
8278 /* Media intrinsics that take two accumulator numbers as argument and
8281 static struct builtin_description bdesc_voidacc
[] =
8283 { CODE_FOR_maddaccs
, "__MADDACCS", FRV_BUILTIN_MADDACCS
, UNKNOWN
, 0},
8284 { CODE_FOR_msubaccs
, "__MSUBACCS", FRV_BUILTIN_MSUBACCS
, UNKNOWN
, 0},
8285 { CODE_FOR_masaccs
, "__MASACCS", FRV_BUILTIN_MASACCS
, UNKNOWN
, 0},
8286 { CODE_FOR_mdaddaccs
, "__MDADDACCS", FRV_BUILTIN_MDADDACCS
, UNKNOWN
, 0},
8287 { CODE_FOR_mdsubaccs
, "__MDSUBACCS", FRV_BUILTIN_MDSUBACCS
, UNKNOWN
, 0},
8288 { CODE_FOR_mdasaccs
, "__MDASACCS", FRV_BUILTIN_MDASACCS
, UNKNOWN
, 0}
8291 /* Intrinsics that load a value and then issue a MEMBAR. The load is
8292 a normal move and the ICODE is for the membar. */
8294 static struct builtin_description bdesc_loads
[] =
8296 { CODE_FOR_optional_membar_qi
, "__builtin_read8",
8297 FRV_BUILTIN_READ8
, UNKNOWN
, 0},
8298 { CODE_FOR_optional_membar_hi
, "__builtin_read16",
8299 FRV_BUILTIN_READ16
, UNKNOWN
, 0},
8300 { CODE_FOR_optional_membar_si
, "__builtin_read32",
8301 FRV_BUILTIN_READ32
, UNKNOWN
, 0},
8302 { CODE_FOR_optional_membar_di
, "__builtin_read64",
8303 FRV_BUILTIN_READ64
, UNKNOWN
, 0}
8306 /* Likewise stores. */
8308 static struct builtin_description bdesc_stores
[] =
8310 { CODE_FOR_optional_membar_qi
, "__builtin_write8",
8311 FRV_BUILTIN_WRITE8
, UNKNOWN
, 0},
8312 { CODE_FOR_optional_membar_hi
, "__builtin_write16",
8313 FRV_BUILTIN_WRITE16
, UNKNOWN
, 0},
8314 { CODE_FOR_optional_membar_si
, "__builtin_write32",
8315 FRV_BUILTIN_WRITE32
, UNKNOWN
, 0},
8316 { CODE_FOR_optional_membar_di
, "__builtin_write64",
8317 FRV_BUILTIN_WRITE64
, UNKNOWN
, 0},
8320 /* Initialize media builtins. */
8323 frv_init_builtins (void)
8325 tree accumulator
= integer_type_node
;
8326 tree integer
= integer_type_node
;
8327 tree voidt
= void_type_node
;
8328 tree uhalf
= short_unsigned_type_node
;
8329 tree sword1
= long_integer_type_node
;
8330 tree uword1
= long_unsigned_type_node
;
8331 tree sword2
= long_long_integer_type_node
;
8332 tree uword2
= long_long_unsigned_type_node
;
8333 tree uword4
= build_pointer_type (uword1
);
8334 tree vptr
= build_pointer_type (build_type_variant (void_type_node
, 0, 1));
8335 tree ubyte
= unsigned_char_type_node
;
8336 tree iacc
= integer_type_node
;
8338 #define UNARY(RET, T1) \
8339 build_function_type_list (RET, T1, NULL_TREE)
8341 #define BINARY(RET, T1, T2) \
8342 build_function_type_list (RET, T1, T2, NULL_TREE)
8344 #define TRINARY(RET, T1, T2, T3) \
8345 build_function_type_list (RET, T1, T2, T3, NULL_TREE)
8347 #define QUAD(RET, T1, T2, T3, T4) \
8348 build_function_type_list (RET, T1, T2, T3, T4, NULL_TREE)
8350 tree void_ftype_void
= build_function_type_list (voidt
, NULL_TREE
);
8352 tree void_ftype_acc
= UNARY (voidt
, accumulator
);
8353 tree void_ftype_uw4_uw1
= BINARY (voidt
, uword4
, uword1
);
8354 tree void_ftype_uw4_uw2
= BINARY (voidt
, uword4
, uword2
);
8355 tree void_ftype_acc_uw1
= BINARY (voidt
, accumulator
, uword1
);
8356 tree void_ftype_acc_acc
= BINARY (voidt
, accumulator
, accumulator
);
8357 tree void_ftype_acc_uw1_uw1
= TRINARY (voidt
, accumulator
, uword1
, uword1
);
8358 tree void_ftype_acc_sw1_sw1
= TRINARY (voidt
, accumulator
, sword1
, sword1
);
8359 tree void_ftype_acc_uw2_uw2
= TRINARY (voidt
, accumulator
, uword2
, uword2
);
8360 tree void_ftype_acc_sw2_sw2
= TRINARY (voidt
, accumulator
, sword2
, sword2
);
8362 tree uw1_ftype_uw1
= UNARY (uword1
, uword1
);
8363 tree uw1_ftype_sw1
= UNARY (uword1
, sword1
);
8364 tree uw1_ftype_uw2
= UNARY (uword1
, uword2
);
8365 tree uw1_ftype_acc
= UNARY (uword1
, accumulator
);
8366 tree uw1_ftype_uh_uh
= BINARY (uword1
, uhalf
, uhalf
);
8367 tree uw1_ftype_uw1_uw1
= BINARY (uword1
, uword1
, uword1
);
8368 tree uw1_ftype_uw1_int
= BINARY (uword1
, uword1
, integer
);
8369 tree uw1_ftype_acc_uw1
= BINARY (uword1
, accumulator
, uword1
);
8370 tree uw1_ftype_acc_sw1
= BINARY (uword1
, accumulator
, sword1
);
8371 tree uw1_ftype_uw2_uw1
= BINARY (uword1
, uword2
, uword1
);
8372 tree uw1_ftype_uw2_int
= BINARY (uword1
, uword2
, integer
);
8374 tree sw1_ftype_int
= UNARY (sword1
, integer
);
8375 tree sw1_ftype_sw1_sw1
= BINARY (sword1
, sword1
, sword1
);
8376 tree sw1_ftype_sw1_int
= BINARY (sword1
, sword1
, integer
);
8378 tree uw2_ftype_uw1
= UNARY (uword2
, uword1
);
8379 tree uw2_ftype_uw1_int
= BINARY (uword2
, uword1
, integer
);
8380 tree uw2_ftype_uw2_uw2
= BINARY (uword2
, uword2
, uword2
);
8381 tree uw2_ftype_uw2_int
= BINARY (uword2
, uword2
, integer
);
8382 tree uw2_ftype_acc_int
= BINARY (uword2
, accumulator
, integer
);
8383 tree uw2_ftype_uh_uh_uh_uh
= QUAD (uword2
, uhalf
, uhalf
, uhalf
, uhalf
);
8385 tree sw2_ftype_sw2_sw2
= BINARY (sword2
, sword2
, sword2
);
8386 tree sw2_ftype_sw2_int
= BINARY (sword2
, sword2
, integer
);
8387 tree uw2_ftype_uw1_uw1
= BINARY (uword2
, uword1
, uword1
);
8388 tree sw2_ftype_sw1_sw1
= BINARY (sword2
, sword1
, sword1
);
8389 tree void_ftype_sw1_sw1
= BINARY (voidt
, sword1
, sword1
);
8390 tree void_ftype_iacc_sw2
= BINARY (voidt
, iacc
, sword2
);
8391 tree void_ftype_iacc_sw1
= BINARY (voidt
, iacc
, sword1
);
8392 tree sw1_ftype_sw1
= UNARY (sword1
, sword1
);
8393 tree sw2_ftype_iacc
= UNARY (sword2
, iacc
);
8394 tree sw1_ftype_iacc
= UNARY (sword1
, iacc
);
8395 tree void_ftype_ptr
= UNARY (voidt
, const_ptr_type_node
);
8396 tree uw1_ftype_vptr
= UNARY (uword1
, vptr
);
8397 tree uw2_ftype_vptr
= UNARY (uword2
, vptr
);
8398 tree void_ftype_vptr_ub
= BINARY (voidt
, vptr
, ubyte
);
8399 tree void_ftype_vptr_uh
= BINARY (voidt
, vptr
, uhalf
);
8400 tree void_ftype_vptr_uw1
= BINARY (voidt
, vptr
, uword1
);
8401 tree void_ftype_vptr_uw2
= BINARY (voidt
, vptr
, uword2
);
8403 def_builtin ("__MAND", uw1_ftype_uw1_uw1
, FRV_BUILTIN_MAND
);
8404 def_builtin ("__MOR", uw1_ftype_uw1_uw1
, FRV_BUILTIN_MOR
);
8405 def_builtin ("__MXOR", uw1_ftype_uw1_uw1
, FRV_BUILTIN_MXOR
);
8406 def_builtin ("__MNOT", uw1_ftype_uw1
, FRV_BUILTIN_MNOT
);
8407 def_builtin ("__MROTLI", uw1_ftype_uw1_int
, FRV_BUILTIN_MROTLI
);
8408 def_builtin ("__MROTRI", uw1_ftype_uw1_int
, FRV_BUILTIN_MROTRI
);
8409 def_builtin ("__MWCUT", uw1_ftype_uw2_uw1
, FRV_BUILTIN_MWCUT
);
8410 def_builtin ("__MAVEH", uw1_ftype_uw1_uw1
, FRV_BUILTIN_MAVEH
);
8411 def_builtin ("__MSLLHI", uw1_ftype_uw1_int
, FRV_BUILTIN_MSLLHI
);
8412 def_builtin ("__MSRLHI", uw1_ftype_uw1_int
, FRV_BUILTIN_MSRLHI
);
8413 def_builtin ("__MSRAHI", sw1_ftype_sw1_int
, FRV_BUILTIN_MSRAHI
);
8414 def_builtin ("__MSATHS", sw1_ftype_sw1_sw1
, FRV_BUILTIN_MSATHS
);
8415 def_builtin ("__MSATHU", uw1_ftype_uw1_uw1
, FRV_BUILTIN_MSATHU
);
8416 def_builtin ("__MADDHSS", sw1_ftype_sw1_sw1
, FRV_BUILTIN_MADDHSS
);
8417 def_builtin ("__MADDHUS", uw1_ftype_uw1_uw1
, FRV_BUILTIN_MADDHUS
);
8418 def_builtin ("__MSUBHSS", sw1_ftype_sw1_sw1
, FRV_BUILTIN_MSUBHSS
);
8419 def_builtin ("__MSUBHUS", uw1_ftype_uw1_uw1
, FRV_BUILTIN_MSUBHUS
);
8420 def_builtin ("__MMULHS", void_ftype_acc_sw1_sw1
, FRV_BUILTIN_MMULHS
);
8421 def_builtin ("__MMULHU", void_ftype_acc_uw1_uw1
, FRV_BUILTIN_MMULHU
);
8422 def_builtin ("__MMULXHS", void_ftype_acc_sw1_sw1
, FRV_BUILTIN_MMULXHS
);
8423 def_builtin ("__MMULXHU", void_ftype_acc_uw1_uw1
, FRV_BUILTIN_MMULXHU
);
8424 def_builtin ("__MMACHS", void_ftype_acc_sw1_sw1
, FRV_BUILTIN_MMACHS
);
8425 def_builtin ("__MMACHU", void_ftype_acc_uw1_uw1
, FRV_BUILTIN_MMACHU
);
8426 def_builtin ("__MMRDHS", void_ftype_acc_sw1_sw1
, FRV_BUILTIN_MMRDHS
);
8427 def_builtin ("__MMRDHU", void_ftype_acc_uw1_uw1
, FRV_BUILTIN_MMRDHU
);
8428 def_builtin ("__MQADDHSS", sw2_ftype_sw2_sw2
, FRV_BUILTIN_MQADDHSS
);
8429 def_builtin ("__MQADDHUS", uw2_ftype_uw2_uw2
, FRV_BUILTIN_MQADDHUS
);
8430 def_builtin ("__MQSUBHSS", sw2_ftype_sw2_sw2
, FRV_BUILTIN_MQSUBHSS
);
8431 def_builtin ("__MQSUBHUS", uw2_ftype_uw2_uw2
, FRV_BUILTIN_MQSUBHUS
);
8432 def_builtin ("__MQMULHS", void_ftype_acc_sw2_sw2
, FRV_BUILTIN_MQMULHS
);
8433 def_builtin ("__MQMULHU", void_ftype_acc_uw2_uw2
, FRV_BUILTIN_MQMULHU
);
8434 def_builtin ("__MQMULXHS", void_ftype_acc_sw2_sw2
, FRV_BUILTIN_MQMULXHS
);
8435 def_builtin ("__MQMULXHU", void_ftype_acc_uw2_uw2
, FRV_BUILTIN_MQMULXHU
);
8436 def_builtin ("__MQMACHS", void_ftype_acc_sw2_sw2
, FRV_BUILTIN_MQMACHS
);
8437 def_builtin ("__MQMACHU", void_ftype_acc_uw2_uw2
, FRV_BUILTIN_MQMACHU
);
8438 def_builtin ("__MCPXRS", void_ftype_acc_sw1_sw1
, FRV_BUILTIN_MCPXRS
);
8439 def_builtin ("__MCPXRU", void_ftype_acc_uw1_uw1
, FRV_BUILTIN_MCPXRU
);
8440 def_builtin ("__MCPXIS", void_ftype_acc_sw1_sw1
, FRV_BUILTIN_MCPXIS
);
8441 def_builtin ("__MCPXIU", void_ftype_acc_uw1_uw1
, FRV_BUILTIN_MCPXIU
);
8442 def_builtin ("__MQCPXRS", void_ftype_acc_sw2_sw2
, FRV_BUILTIN_MQCPXRS
);
8443 def_builtin ("__MQCPXRU", void_ftype_acc_uw2_uw2
, FRV_BUILTIN_MQCPXRU
);
8444 def_builtin ("__MQCPXIS", void_ftype_acc_sw2_sw2
, FRV_BUILTIN_MQCPXIS
);
8445 def_builtin ("__MQCPXIU", void_ftype_acc_uw2_uw2
, FRV_BUILTIN_MQCPXIU
);
8446 def_builtin ("__MCUT", uw1_ftype_acc_uw1
, FRV_BUILTIN_MCUT
);
8447 def_builtin ("__MCUTSS", uw1_ftype_acc_sw1
, FRV_BUILTIN_MCUTSS
);
8448 def_builtin ("__MEXPDHW", uw1_ftype_uw1_int
, FRV_BUILTIN_MEXPDHW
);
8449 def_builtin ("__MEXPDHD", uw2_ftype_uw1_int
, FRV_BUILTIN_MEXPDHD
);
8450 def_builtin ("__MPACKH", uw1_ftype_uh_uh
, FRV_BUILTIN_MPACKH
);
8451 def_builtin ("__MUNPACKH", uw2_ftype_uw1
, FRV_BUILTIN_MUNPACKH
);
8452 def_builtin ("__MDPACKH", uw2_ftype_uh_uh_uh_uh
, FRV_BUILTIN_MDPACKH
);
8453 def_builtin ("__MDUNPACKH", void_ftype_uw4_uw2
, FRV_BUILTIN_MDUNPACKH
);
8454 def_builtin ("__MBTOH", uw2_ftype_uw1
, FRV_BUILTIN_MBTOH
);
8455 def_builtin ("__MHTOB", uw1_ftype_uw2
, FRV_BUILTIN_MHTOB
);
8456 def_builtin ("__MBTOHE", void_ftype_uw4_uw1
, FRV_BUILTIN_MBTOHE
);
8457 def_builtin ("__MCLRACC", void_ftype_acc
, FRV_BUILTIN_MCLRACC
);
8458 def_builtin ("__MCLRACCA", void_ftype_void
, FRV_BUILTIN_MCLRACCA
);
8459 def_builtin ("__MRDACC", uw1_ftype_acc
, FRV_BUILTIN_MRDACC
);
8460 def_builtin ("__MRDACCG", uw1_ftype_acc
, FRV_BUILTIN_MRDACCG
);
8461 def_builtin ("__MWTACC", void_ftype_acc_uw1
, FRV_BUILTIN_MWTACC
);
8462 def_builtin ("__MWTACCG", void_ftype_acc_uw1
, FRV_BUILTIN_MWTACCG
);
8463 def_builtin ("__Mcop1", uw1_ftype_uw1_uw1
, FRV_BUILTIN_MCOP1
);
8464 def_builtin ("__Mcop2", uw1_ftype_uw1_uw1
, FRV_BUILTIN_MCOP2
);
8465 def_builtin ("__MTRAP", void_ftype_void
, FRV_BUILTIN_MTRAP
);
8466 def_builtin ("__MQXMACHS", void_ftype_acc_sw2_sw2
, FRV_BUILTIN_MQXMACHS
);
8467 def_builtin ("__MQXMACXHS", void_ftype_acc_sw2_sw2
, FRV_BUILTIN_MQXMACXHS
);
8468 def_builtin ("__MQMACXHS", void_ftype_acc_sw2_sw2
, FRV_BUILTIN_MQMACXHS
);
8469 def_builtin ("__MADDACCS", void_ftype_acc_acc
, FRV_BUILTIN_MADDACCS
);
8470 def_builtin ("__MSUBACCS", void_ftype_acc_acc
, FRV_BUILTIN_MSUBACCS
);
8471 def_builtin ("__MASACCS", void_ftype_acc_acc
, FRV_BUILTIN_MASACCS
);
8472 def_builtin ("__MDADDACCS", void_ftype_acc_acc
, FRV_BUILTIN_MDADDACCS
);
8473 def_builtin ("__MDSUBACCS", void_ftype_acc_acc
, FRV_BUILTIN_MDSUBACCS
);
8474 def_builtin ("__MDASACCS", void_ftype_acc_acc
, FRV_BUILTIN_MDASACCS
);
8475 def_builtin ("__MABSHS", uw1_ftype_sw1
, FRV_BUILTIN_MABSHS
);
8476 def_builtin ("__MDROTLI", uw2_ftype_uw2_int
, FRV_BUILTIN_MDROTLI
);
8477 def_builtin ("__MCPLHI", uw1_ftype_uw2_int
, FRV_BUILTIN_MCPLHI
);
8478 def_builtin ("__MCPLI", uw1_ftype_uw2_int
, FRV_BUILTIN_MCPLI
);
8479 def_builtin ("__MDCUTSSI", uw2_ftype_acc_int
, FRV_BUILTIN_MDCUTSSI
);
8480 def_builtin ("__MQSATHS", sw2_ftype_sw2_sw2
, FRV_BUILTIN_MQSATHS
);
8481 def_builtin ("__MHSETLOS", sw1_ftype_sw1_int
, FRV_BUILTIN_MHSETLOS
);
8482 def_builtin ("__MHSETHIS", sw1_ftype_sw1_int
, FRV_BUILTIN_MHSETHIS
);
8483 def_builtin ("__MHDSETS", sw1_ftype_int
, FRV_BUILTIN_MHDSETS
);
8484 def_builtin ("__MHSETLOH", uw1_ftype_uw1_int
, FRV_BUILTIN_MHSETLOH
);
8485 def_builtin ("__MHSETHIH", uw1_ftype_uw1_int
, FRV_BUILTIN_MHSETHIH
);
8486 def_builtin ("__MHDSETH", uw1_ftype_uw1_int
, FRV_BUILTIN_MHDSETH
);
8487 def_builtin ("__MQLCLRHS", sw2_ftype_sw2_sw2
, FRV_BUILTIN_MQLCLRHS
);
8488 def_builtin ("__MQLMTHS", sw2_ftype_sw2_sw2
, FRV_BUILTIN_MQLMTHS
);
8489 def_builtin ("__MQSLLHI", uw2_ftype_uw2_int
, FRV_BUILTIN_MQSLLHI
);
8490 def_builtin ("__MQSRAHI", sw2_ftype_sw2_int
, FRV_BUILTIN_MQSRAHI
);
8491 def_builtin ("__SMUL", sw2_ftype_sw1_sw1
, FRV_BUILTIN_SMUL
);
8492 def_builtin ("__UMUL", uw2_ftype_uw1_uw1
, FRV_BUILTIN_UMUL
);
8493 def_builtin ("__SMASS", void_ftype_sw1_sw1
, FRV_BUILTIN_SMASS
);
8494 def_builtin ("__SMSSS", void_ftype_sw1_sw1
, FRV_BUILTIN_SMSSS
);
8495 def_builtin ("__SMU", void_ftype_sw1_sw1
, FRV_BUILTIN_SMU
);
8496 def_builtin ("__ADDSS", sw1_ftype_sw1_sw1
, FRV_BUILTIN_ADDSS
);
8497 def_builtin ("__SUBSS", sw1_ftype_sw1_sw1
, FRV_BUILTIN_SUBSS
);
8498 def_builtin ("__SLASS", sw1_ftype_sw1_sw1
, FRV_BUILTIN_SLASS
);
8499 def_builtin ("__SCAN", sw1_ftype_sw1_sw1
, FRV_BUILTIN_SCAN
);
8500 def_builtin ("__SCUTSS", sw1_ftype_sw1
, FRV_BUILTIN_SCUTSS
);
8501 def_builtin ("__IACCreadll", sw2_ftype_iacc
, FRV_BUILTIN_IACCreadll
);
8502 def_builtin ("__IACCreadl", sw1_ftype_iacc
, FRV_BUILTIN_IACCreadl
);
8503 def_builtin ("__IACCsetll", void_ftype_iacc_sw2
, FRV_BUILTIN_IACCsetll
);
8504 def_builtin ("__IACCsetl", void_ftype_iacc_sw1
, FRV_BUILTIN_IACCsetl
);
8505 def_builtin ("__data_prefetch0", void_ftype_ptr
, FRV_BUILTIN_PREFETCH0
);
8506 def_builtin ("__data_prefetch", void_ftype_ptr
, FRV_BUILTIN_PREFETCH
);
8507 def_builtin ("__builtin_read8", uw1_ftype_vptr
, FRV_BUILTIN_READ8
);
8508 def_builtin ("__builtin_read16", uw1_ftype_vptr
, FRV_BUILTIN_READ16
);
8509 def_builtin ("__builtin_read32", uw1_ftype_vptr
, FRV_BUILTIN_READ32
);
8510 def_builtin ("__builtin_read64", uw2_ftype_vptr
, FRV_BUILTIN_READ64
);
8512 def_builtin ("__builtin_write8", void_ftype_vptr_ub
, FRV_BUILTIN_WRITE8
);
8513 def_builtin ("__builtin_write16", void_ftype_vptr_uh
, FRV_BUILTIN_WRITE16
);
8514 def_builtin ("__builtin_write32", void_ftype_vptr_uw1
, FRV_BUILTIN_WRITE32
);
8515 def_builtin ("__builtin_write64", void_ftype_vptr_uw2
, FRV_BUILTIN_WRITE64
);
8523 /* Set the names for various arithmetic operations according to the
8526 frv_init_libfuncs (void)
8528 set_optab_libfunc (smod_optab
, SImode
, "__modi");
8529 set_optab_libfunc (umod_optab
, SImode
, "__umodi");
8531 set_optab_libfunc (add_optab
, DImode
, "__addll");
8532 set_optab_libfunc (sub_optab
, DImode
, "__subll");
8533 set_optab_libfunc (smul_optab
, DImode
, "__mulll");
8534 set_optab_libfunc (sdiv_optab
, DImode
, "__divll");
8535 set_optab_libfunc (smod_optab
, DImode
, "__modll");
8536 set_optab_libfunc (umod_optab
, DImode
, "__umodll");
8537 set_optab_libfunc (and_optab
, DImode
, "__andll");
8538 set_optab_libfunc (ior_optab
, DImode
, "__orll");
8539 set_optab_libfunc (xor_optab
, DImode
, "__xorll");
8540 set_optab_libfunc (one_cmpl_optab
, DImode
, "__notll");
8542 set_optab_libfunc (add_optab
, SFmode
, "__addf");
8543 set_optab_libfunc (sub_optab
, SFmode
, "__subf");
8544 set_optab_libfunc (smul_optab
, SFmode
, "__mulf");
8545 set_optab_libfunc (sdiv_optab
, SFmode
, "__divf");
8547 set_optab_libfunc (add_optab
, DFmode
, "__addd");
8548 set_optab_libfunc (sub_optab
, DFmode
, "__subd");
8549 set_optab_libfunc (smul_optab
, DFmode
, "__muld");
8550 set_optab_libfunc (sdiv_optab
, DFmode
, "__divd");
8552 set_conv_libfunc (sext_optab
, DFmode
, SFmode
, "__ftod");
8553 set_conv_libfunc (trunc_optab
, SFmode
, DFmode
, "__dtof");
8555 set_conv_libfunc (sfix_optab
, SImode
, SFmode
, "__ftoi");
8556 set_conv_libfunc (sfix_optab
, DImode
, SFmode
, "__ftoll");
8557 set_conv_libfunc (sfix_optab
, SImode
, DFmode
, "__dtoi");
8558 set_conv_libfunc (sfix_optab
, DImode
, DFmode
, "__dtoll");
8560 set_conv_libfunc (ufix_optab
, SImode
, SFmode
, "__ftoui");
8561 set_conv_libfunc (ufix_optab
, DImode
, SFmode
, "__ftoull");
8562 set_conv_libfunc (ufix_optab
, SImode
, DFmode
, "__dtoui");
8563 set_conv_libfunc (ufix_optab
, DImode
, DFmode
, "__dtoull");
8565 set_conv_libfunc (sfloat_optab
, SFmode
, SImode
, "__itof");
8566 set_conv_libfunc (sfloat_optab
, SFmode
, DImode
, "__lltof");
8567 set_conv_libfunc (sfloat_optab
, DFmode
, SImode
, "__itod");
8568 set_conv_libfunc (sfloat_optab
, DFmode
, DImode
, "__lltod");
8571 /* Convert an integer constant to an accumulator register. ICODE is the
8572 code of the target instruction, OPNUM is the number of the
8573 accumulator operand and OPVAL is the constant integer. Try both
8574 ACC and ACCG registers; only report an error if neither fit the
8578 frv_int_to_acc (enum insn_code icode
, int opnum
, rtx opval
)
8583 /* ACCs and ACCGs are implicit global registers if media intrinsics
8584 are being used. We set up this lazily to avoid creating lots of
8585 unnecessary call_insn rtl in non-media code. */
8586 for (i
= 0; i
<= ACC_MASK
; i
++)
8587 if ((i
& ACC_MASK
) == i
)
8588 global_regs
[i
+ ACC_FIRST
] = global_regs
[i
+ ACCG_FIRST
] = 1;
8590 if (GET_CODE (opval
) != CONST_INT
)
8592 error ("accumulator is not a constant integer");
8595 if ((INTVAL (opval
) & ~ACC_MASK
) != 0)
8597 error ("accumulator number is out of bounds");
8601 reg
= gen_rtx_REG (insn_data
[icode
].operand
[opnum
].mode
,
8602 ACC_FIRST
+ INTVAL (opval
));
8603 if (! (*insn_data
[icode
].operand
[opnum
].predicate
) (reg
, VOIDmode
))
8604 SET_REGNO (reg
, ACCG_FIRST
+ INTVAL (opval
));
8606 if (! (*insn_data
[icode
].operand
[opnum
].predicate
) (reg
, VOIDmode
))
8608 error ("inappropriate accumulator for %qs", insn_data
[icode
].name
);
8614 /* If an ACC rtx has mode MODE, return the mode that the matching ACCG
8618 frv_matching_accg_mode (machine_mode mode
)
8636 /* Given that a __builtin_read or __builtin_write function is accessing
8637 address ADDRESS, return the value that should be used as operand 1
8641 frv_io_address_cookie (rtx address
)
8643 return (GET_CODE (address
) == CONST_INT
8644 ? GEN_INT (INTVAL (address
) / 8 * 8)
8648 /* Return the accumulator guard that should be paired with accumulator
8649 register ACC. The mode of the returned register is in the same
8650 class as ACC, but is four times smaller. */
8653 frv_matching_accg_for_acc (rtx acc
)
8655 return gen_rtx_REG (frv_matching_accg_mode (GET_MODE (acc
)),
8656 REGNO (acc
) - ACC_FIRST
+ ACCG_FIRST
);
8659 /* Read the requested argument from the call EXP given by INDEX.
8660 Return the value as an rtx. */
8663 frv_read_argument (tree exp
, unsigned int index
)
8665 return expand_normal (CALL_EXPR_ARG (exp
, index
));
8668 /* Like frv_read_argument, but interpret the argument as the number
8669 of an IACC register and return a (reg:MODE ...) rtx for it. */
8672 frv_read_iacc_argument (machine_mode mode
, tree call
,
8678 op
= frv_read_argument (call
, index
);
8679 if (GET_CODE (op
) != CONST_INT
8681 || INTVAL (op
) > IACC_LAST
- IACC_FIRST
8682 || ((INTVAL (op
) * 4) & (GET_MODE_SIZE (mode
) - 1)) != 0)
8684 error ("invalid IACC argument");
8688 /* IACCs are implicit global registers. We set up this lazily to
8689 avoid creating lots of unnecessary call_insn rtl when IACCs aren't
8691 regno
= INTVAL (op
) + IACC_FIRST
;
8692 for (i
= 0; i
< HARD_REGNO_NREGS (regno
, mode
); i
++)
8693 global_regs
[regno
+ i
] = 1;
8695 return gen_rtx_REG (mode
, regno
);
8698 /* Return true if OPVAL can be used for operand OPNUM of instruction ICODE.
8699 The instruction should require a constant operand of some sort. The
8700 function prints an error if OPVAL is not valid. */
8703 frv_check_constant_argument (enum insn_code icode
, int opnum
, rtx opval
)
8705 if (GET_CODE (opval
) != CONST_INT
)
8707 error ("%qs expects a constant argument", insn_data
[icode
].name
);
8710 if (! (*insn_data
[icode
].operand
[opnum
].predicate
) (opval
, VOIDmode
))
8712 error ("constant argument out of range for %qs", insn_data
[icode
].name
);
8718 /* Return a legitimate rtx for instruction ICODE's return value. Use TARGET
8719 if it's not null, has the right mode, and satisfies operand 0's
8723 frv_legitimize_target (enum insn_code icode
, rtx target
)
8725 machine_mode mode
= insn_data
[icode
].operand
[0].mode
;
8728 || GET_MODE (target
) != mode
8729 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, mode
))
8730 return gen_reg_rtx (mode
);
8735 /* Given that ARG is being passed as operand OPNUM to instruction ICODE,
8736 check whether ARG satisfies the operand's constraints. If it doesn't,
8737 copy ARG to a temporary register and return that. Otherwise return ARG
8741 frv_legitimize_argument (enum insn_code icode
, int opnum
, rtx arg
)
8743 machine_mode mode
= insn_data
[icode
].operand
[opnum
].mode
;
8745 if ((*insn_data
[icode
].operand
[opnum
].predicate
) (arg
, mode
))
8748 return copy_to_mode_reg (mode
, arg
);
8751 /* Return a volatile memory reference of mode MODE whose address is ARG. */
8754 frv_volatile_memref (machine_mode mode
, rtx arg
)
8758 mem
= gen_rtx_MEM (mode
, memory_address (mode
, arg
));
8759 MEM_VOLATILE_P (mem
) = 1;
8763 /* Expand builtins that take a single, constant argument. At the moment,
8764 only MHDSETS falls into this category. */
8767 frv_expand_set_builtin (enum insn_code icode
, tree call
, rtx target
)
8770 rtx op0
= frv_read_argument (call
, 0);
8772 if (! frv_check_constant_argument (icode
, 1, op0
))
8775 target
= frv_legitimize_target (icode
, target
);
8776 pat
= GEN_FCN (icode
) (target
, op0
);
8784 /* Expand builtins that take one operand. */
8787 frv_expand_unop_builtin (enum insn_code icode
, tree call
, rtx target
)
8790 rtx op0
= frv_read_argument (call
, 0);
8792 target
= frv_legitimize_target (icode
, target
);
8793 op0
= frv_legitimize_argument (icode
, 1, op0
);
8794 pat
= GEN_FCN (icode
) (target
, op0
);
8802 /* Expand builtins that take two operands. */
8805 frv_expand_binop_builtin (enum insn_code icode
, tree call
, rtx target
)
8808 rtx op0
= frv_read_argument (call
, 0);
8809 rtx op1
= frv_read_argument (call
, 1);
8811 target
= frv_legitimize_target (icode
, target
);
8812 op0
= frv_legitimize_argument (icode
, 1, op0
);
8813 op1
= frv_legitimize_argument (icode
, 2, op1
);
8814 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
8822 /* Expand cut-style builtins, which take two operands and an implicit ACCG
8826 frv_expand_cut_builtin (enum insn_code icode
, tree call
, rtx target
)
8829 rtx op0
= frv_read_argument (call
, 0);
8830 rtx op1
= frv_read_argument (call
, 1);
8833 target
= frv_legitimize_target (icode
, target
);
8834 op0
= frv_int_to_acc (icode
, 1, op0
);
8838 if (icode
== CODE_FOR_mdcutssi
|| GET_CODE (op1
) == CONST_INT
)
8840 if (! frv_check_constant_argument (icode
, 2, op1
))
8844 op1
= frv_legitimize_argument (icode
, 2, op1
);
8846 op2
= frv_matching_accg_for_acc (op0
);
8847 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
8855 /* Expand builtins that take two operands and the second is immediate. */
8858 frv_expand_binopimm_builtin (enum insn_code icode
, tree call
, rtx target
)
8861 rtx op0
= frv_read_argument (call
, 0);
8862 rtx op1
= frv_read_argument (call
, 1);
8864 if (! frv_check_constant_argument (icode
, 2, op1
))
8867 target
= frv_legitimize_target (icode
, target
);
8868 op0
= frv_legitimize_argument (icode
, 1, op0
);
8869 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
8877 /* Expand builtins that take two operands, the first operand being a pointer to
8878 ints and return void. */
8881 frv_expand_voidbinop_builtin (enum insn_code icode
, tree call
)
8884 rtx op0
= frv_read_argument (call
, 0);
8885 rtx op1
= frv_read_argument (call
, 1);
8886 machine_mode mode0
= insn_data
[icode
].operand
[0].mode
;
8889 if (GET_CODE (op0
) != MEM
)
8893 if (! offsettable_address_p (0, mode0
, op0
))
8895 reg
= gen_reg_rtx (Pmode
);
8896 emit_insn (gen_rtx_SET (reg
, op0
));
8899 op0
= gen_rtx_MEM (SImode
, reg
);
8902 addr
= XEXP (op0
, 0);
8903 if (! offsettable_address_p (0, mode0
, addr
))
8904 addr
= copy_to_mode_reg (Pmode
, op0
);
8906 op0
= change_address (op0
, V4SImode
, addr
);
8907 op1
= frv_legitimize_argument (icode
, 1, op1
);
8908 pat
= GEN_FCN (icode
) (op0
, op1
);
8916 /* Expand builtins that take two long operands and return void. */
8919 frv_expand_int_void2arg (enum insn_code icode
, tree call
)
8922 rtx op0
= frv_read_argument (call
, 0);
8923 rtx op1
= frv_read_argument (call
, 1);
8925 op0
= frv_legitimize_argument (icode
, 1, op0
);
8926 op1
= frv_legitimize_argument (icode
, 1, op1
);
8927 pat
= GEN_FCN (icode
) (op0
, op1
);
8935 /* Expand prefetch builtins. These take a single address as argument. */
8938 frv_expand_prefetches (enum insn_code icode
, tree call
)
8941 rtx op0
= frv_read_argument (call
, 0);
8943 pat
= GEN_FCN (icode
) (force_reg (Pmode
, op0
));
8951 /* Expand builtins that take three operands and return void. The first
8952 argument must be a constant that describes a pair or quad accumulators. A
8953 fourth argument is created that is the accumulator guard register that
8954 corresponds to the accumulator. */
8957 frv_expand_voidtriop_builtin (enum insn_code icode
, tree call
)
8960 rtx op0
= frv_read_argument (call
, 0);
8961 rtx op1
= frv_read_argument (call
, 1);
8962 rtx op2
= frv_read_argument (call
, 2);
8965 op0
= frv_int_to_acc (icode
, 0, op0
);
8969 op1
= frv_legitimize_argument (icode
, 1, op1
);
8970 op2
= frv_legitimize_argument (icode
, 2, op2
);
8971 op3
= frv_matching_accg_for_acc (op0
);
8972 pat
= GEN_FCN (icode
) (op0
, op1
, op2
, op3
);
8980 /* Expand builtins that perform accumulator-to-accumulator operations.
8981 These builtins take two accumulator numbers as argument and return
8985 frv_expand_voidaccop_builtin (enum insn_code icode
, tree call
)
8988 rtx op0
= frv_read_argument (call
, 0);
8989 rtx op1
= frv_read_argument (call
, 1);
8993 op0
= frv_int_to_acc (icode
, 0, op0
);
8997 op1
= frv_int_to_acc (icode
, 1, op1
);
9001 op2
= frv_matching_accg_for_acc (op0
);
9002 op3
= frv_matching_accg_for_acc (op1
);
9003 pat
= GEN_FCN (icode
) (op0
, op1
, op2
, op3
);
9011 /* Expand a __builtin_read* function. ICODE is the instruction code for the
9012 membar and TARGET_MODE is the mode that the loaded value should have. */
9015 frv_expand_load_builtin (enum insn_code icode
, machine_mode target_mode
,
9016 tree call
, rtx target
)
9018 rtx op0
= frv_read_argument (call
, 0);
9019 rtx cookie
= frv_io_address_cookie (op0
);
9021 if (target
== 0 || !REG_P (target
))
9022 target
= gen_reg_rtx (target_mode
);
9023 op0
= frv_volatile_memref (insn_data
[icode
].operand
[0].mode
, op0
);
9024 convert_move (target
, op0
, 1);
9025 emit_insn (GEN_FCN (icode
) (copy_rtx (op0
), cookie
, GEN_INT (FRV_IO_READ
)));
9026 cfun
->machine
->has_membar_p
= 1;
9030 /* Likewise __builtin_write* functions. */
9033 frv_expand_store_builtin (enum insn_code icode
, tree call
)
9035 rtx op0
= frv_read_argument (call
, 0);
9036 rtx op1
= frv_read_argument (call
, 1);
9037 rtx cookie
= frv_io_address_cookie (op0
);
9039 op0
= frv_volatile_memref (insn_data
[icode
].operand
[0].mode
, op0
);
9040 convert_move (op0
, force_reg (insn_data
[icode
].operand
[0].mode
, op1
), 1);
9041 emit_insn (GEN_FCN (icode
) (copy_rtx (op0
), cookie
, GEN_INT (FRV_IO_WRITE
)));
9042 cfun
->machine
->has_membar_p
= 1;
9046 /* Expand the MDPACKH builtin. It takes four unsigned short arguments and
9047 each argument forms one word of the two double-word input registers.
9048 CALL is the tree for the call and TARGET, if nonnull, suggests a good place
9049 to put the return value. */
9052 frv_expand_mdpackh_builtin (tree call
, rtx target
)
9054 enum insn_code icode
= CODE_FOR_mdpackh
;
9056 rtx arg1
= frv_read_argument (call
, 0);
9057 rtx arg2
= frv_read_argument (call
, 1);
9058 rtx arg3
= frv_read_argument (call
, 2);
9059 rtx arg4
= frv_read_argument (call
, 3);
9061 target
= frv_legitimize_target (icode
, target
);
9062 op0
= gen_reg_rtx (DImode
);
9063 op1
= gen_reg_rtx (DImode
);
9065 /* The high half of each word is not explicitly initialized, so indicate
9066 that the input operands are not live before this point. */
9070 /* Move each argument into the low half of its associated input word. */
9071 emit_move_insn (simplify_gen_subreg (HImode
, op0
, DImode
, 2), arg1
);
9072 emit_move_insn (simplify_gen_subreg (HImode
, op0
, DImode
, 6), arg2
);
9073 emit_move_insn (simplify_gen_subreg (HImode
, op1
, DImode
, 2), arg3
);
9074 emit_move_insn (simplify_gen_subreg (HImode
, op1
, DImode
, 6), arg4
);
9076 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
9084 /* Expand the MCLRACC builtin. This builtin takes a single accumulator
9085 number as argument. */
9088 frv_expand_mclracc_builtin (tree call
)
9090 enum insn_code icode
= CODE_FOR_mclracc
;
9092 rtx op0
= frv_read_argument (call
, 0);
9094 op0
= frv_int_to_acc (icode
, 0, op0
);
9098 pat
= GEN_FCN (icode
) (op0
);
9105 /* Expand builtins that take no arguments. */
9108 frv_expand_noargs_builtin (enum insn_code icode
)
9110 rtx pat
= GEN_FCN (icode
) (const0_rtx
);
9117 /* Expand MRDACC and MRDACCG. These builtins take a single accumulator
9118 number or accumulator guard number as argument and return an SI integer. */
9121 frv_expand_mrdacc_builtin (enum insn_code icode
, tree call
)
9124 rtx target
= gen_reg_rtx (SImode
);
9125 rtx op0
= frv_read_argument (call
, 0);
9127 op0
= frv_int_to_acc (icode
, 1, op0
);
9131 pat
= GEN_FCN (icode
) (target
, op0
);
9139 /* Expand MWTACC and MWTACCG. These builtins take an accumulator or
9140 accumulator guard as their first argument and an SImode value as their
9144 frv_expand_mwtacc_builtin (enum insn_code icode
, tree call
)
9147 rtx op0
= frv_read_argument (call
, 0);
9148 rtx op1
= frv_read_argument (call
, 1);
9150 op0
= frv_int_to_acc (icode
, 0, op0
);
9154 op1
= frv_legitimize_argument (icode
, 1, op1
);
9155 pat
= GEN_FCN (icode
) (op0
, op1
);
9162 /* Emit a move from SRC to DEST in SImode chunks. This can be used
9163 to move DImode values into and out of IACC0. */
9166 frv_split_iacc_move (rtx dest
, rtx src
)
9171 inner
= GET_MODE (dest
);
9172 for (i
= 0; i
< GET_MODE_SIZE (inner
); i
+= GET_MODE_SIZE (SImode
))
9173 emit_move_insn (simplify_gen_subreg (SImode
, dest
, inner
, i
),
9174 simplify_gen_subreg (SImode
, src
, inner
, i
));
9177 /* Expand builtins. */
9180 frv_expand_builtin (tree exp
,
9182 rtx subtarget ATTRIBUTE_UNUSED
,
9183 machine_mode mode ATTRIBUTE_UNUSED
,
9184 int ignore ATTRIBUTE_UNUSED
)
9186 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
9187 unsigned fcode
= (unsigned)DECL_FUNCTION_CODE (fndecl
);
9189 struct builtin_description
*d
;
9191 if (fcode
< FRV_BUILTIN_FIRST_NONMEDIA
&& !TARGET_MEDIA
)
9193 error ("media functions are not available unless -mmedia is used");
9199 case FRV_BUILTIN_MCOP1
:
9200 case FRV_BUILTIN_MCOP2
:
9201 case FRV_BUILTIN_MDUNPACKH
:
9202 case FRV_BUILTIN_MBTOHE
:
9203 if (! TARGET_MEDIA_REV1
)
9205 error ("this media function is only available on the fr500");
9210 case FRV_BUILTIN_MQXMACHS
:
9211 case FRV_BUILTIN_MQXMACXHS
:
9212 case FRV_BUILTIN_MQMACXHS
:
9213 case FRV_BUILTIN_MADDACCS
:
9214 case FRV_BUILTIN_MSUBACCS
:
9215 case FRV_BUILTIN_MASACCS
:
9216 case FRV_BUILTIN_MDADDACCS
:
9217 case FRV_BUILTIN_MDSUBACCS
:
9218 case FRV_BUILTIN_MDASACCS
:
9219 case FRV_BUILTIN_MABSHS
:
9220 case FRV_BUILTIN_MDROTLI
:
9221 case FRV_BUILTIN_MCPLHI
:
9222 case FRV_BUILTIN_MCPLI
:
9223 case FRV_BUILTIN_MDCUTSSI
:
9224 case FRV_BUILTIN_MQSATHS
:
9225 case FRV_BUILTIN_MHSETLOS
:
9226 case FRV_BUILTIN_MHSETLOH
:
9227 case FRV_BUILTIN_MHSETHIS
:
9228 case FRV_BUILTIN_MHSETHIH
:
9229 case FRV_BUILTIN_MHDSETS
:
9230 case FRV_BUILTIN_MHDSETH
:
9231 if (! TARGET_MEDIA_REV2
)
9233 error ("this media function is only available on the fr400"
9239 case FRV_BUILTIN_SMASS
:
9240 case FRV_BUILTIN_SMSSS
:
9241 case FRV_BUILTIN_SMU
:
9242 case FRV_BUILTIN_ADDSS
:
9243 case FRV_BUILTIN_SUBSS
:
9244 case FRV_BUILTIN_SLASS
:
9245 case FRV_BUILTIN_SCUTSS
:
9246 case FRV_BUILTIN_IACCreadll
:
9247 case FRV_BUILTIN_IACCreadl
:
9248 case FRV_BUILTIN_IACCsetll
:
9249 case FRV_BUILTIN_IACCsetl
:
9250 if (!TARGET_FR405_BUILTINS
)
9252 error ("this builtin function is only available"
9253 " on the fr405 and fr450");
9258 case FRV_BUILTIN_PREFETCH
:
9259 if (!TARGET_FR500_FR550_BUILTINS
)
9261 error ("this builtin function is only available on the fr500"
9267 case FRV_BUILTIN_MQLCLRHS
:
9268 case FRV_BUILTIN_MQLMTHS
:
9269 case FRV_BUILTIN_MQSLLHI
:
9270 case FRV_BUILTIN_MQSRAHI
:
9271 if (!TARGET_MEDIA_FR450
)
9273 error ("this builtin function is only available on the fr450");
9282 /* Expand unique builtins. */
9286 case FRV_BUILTIN_MTRAP
:
9287 return frv_expand_noargs_builtin (CODE_FOR_mtrap
);
9289 case FRV_BUILTIN_MCLRACC
:
9290 return frv_expand_mclracc_builtin (exp
);
9292 case FRV_BUILTIN_MCLRACCA
:
9294 return frv_expand_noargs_builtin (CODE_FOR_mclracca8
);
9296 return frv_expand_noargs_builtin (CODE_FOR_mclracca4
);
9298 case FRV_BUILTIN_MRDACC
:
9299 return frv_expand_mrdacc_builtin (CODE_FOR_mrdacc
, exp
);
9301 case FRV_BUILTIN_MRDACCG
:
9302 return frv_expand_mrdacc_builtin (CODE_FOR_mrdaccg
, exp
);
9304 case FRV_BUILTIN_MWTACC
:
9305 return frv_expand_mwtacc_builtin (CODE_FOR_mwtacc
, exp
);
9307 case FRV_BUILTIN_MWTACCG
:
9308 return frv_expand_mwtacc_builtin (CODE_FOR_mwtaccg
, exp
);
9310 case FRV_BUILTIN_MDPACKH
:
9311 return frv_expand_mdpackh_builtin (exp
, target
);
9313 case FRV_BUILTIN_IACCreadll
:
9315 rtx src
= frv_read_iacc_argument (DImode
, exp
, 0);
9316 if (target
== 0 || !REG_P (target
))
9317 target
= gen_reg_rtx (DImode
);
9318 frv_split_iacc_move (target
, src
);
9322 case FRV_BUILTIN_IACCreadl
:
9323 return frv_read_iacc_argument (SImode
, exp
, 0);
9325 case FRV_BUILTIN_IACCsetll
:
9327 rtx dest
= frv_read_iacc_argument (DImode
, exp
, 0);
9328 rtx src
= frv_read_argument (exp
, 1);
9329 frv_split_iacc_move (dest
, force_reg (DImode
, src
));
9333 case FRV_BUILTIN_IACCsetl
:
9335 rtx dest
= frv_read_iacc_argument (SImode
, exp
, 0);
9336 rtx src
= frv_read_argument (exp
, 1);
9337 emit_move_insn (dest
, force_reg (SImode
, src
));
9345 /* Expand groups of builtins. */
9347 for (i
= 0, d
= bdesc_set
; i
< ARRAY_SIZE (bdesc_set
); i
++, d
++)
9348 if (d
->code
== fcode
)
9349 return frv_expand_set_builtin (d
->icode
, exp
, target
);
9351 for (i
= 0, d
= bdesc_1arg
; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
9352 if (d
->code
== fcode
)
9353 return frv_expand_unop_builtin (d
->icode
, exp
, target
);
9355 for (i
= 0, d
= bdesc_2arg
; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
9356 if (d
->code
== fcode
)
9357 return frv_expand_binop_builtin (d
->icode
, exp
, target
);
9359 for (i
= 0, d
= bdesc_cut
; i
< ARRAY_SIZE (bdesc_cut
); i
++, d
++)
9360 if (d
->code
== fcode
)
9361 return frv_expand_cut_builtin (d
->icode
, exp
, target
);
9363 for (i
= 0, d
= bdesc_2argimm
; i
< ARRAY_SIZE (bdesc_2argimm
); i
++, d
++)
9364 if (d
->code
== fcode
)
9365 return frv_expand_binopimm_builtin (d
->icode
, exp
, target
);
9367 for (i
= 0, d
= bdesc_void2arg
; i
< ARRAY_SIZE (bdesc_void2arg
); i
++, d
++)
9368 if (d
->code
== fcode
)
9369 return frv_expand_voidbinop_builtin (d
->icode
, exp
);
9371 for (i
= 0, d
= bdesc_void3arg
; i
< ARRAY_SIZE (bdesc_void3arg
); i
++, d
++)
9372 if (d
->code
== fcode
)
9373 return frv_expand_voidtriop_builtin (d
->icode
, exp
);
9375 for (i
= 0, d
= bdesc_voidacc
; i
< ARRAY_SIZE (bdesc_voidacc
); i
++, d
++)
9376 if (d
->code
== fcode
)
9377 return frv_expand_voidaccop_builtin (d
->icode
, exp
);
9379 for (i
= 0, d
= bdesc_int_void2arg
;
9380 i
< ARRAY_SIZE (bdesc_int_void2arg
); i
++, d
++)
9381 if (d
->code
== fcode
)
9382 return frv_expand_int_void2arg (d
->icode
, exp
);
9384 for (i
= 0, d
= bdesc_prefetches
;
9385 i
< ARRAY_SIZE (bdesc_prefetches
); i
++, d
++)
9386 if (d
->code
== fcode
)
9387 return frv_expand_prefetches (d
->icode
, exp
);
9389 for (i
= 0, d
= bdesc_loads
; i
< ARRAY_SIZE (bdesc_loads
); i
++, d
++)
9390 if (d
->code
== fcode
)
9391 return frv_expand_load_builtin (d
->icode
, TYPE_MODE (TREE_TYPE (exp
)),
9394 for (i
= 0, d
= bdesc_stores
; i
< ARRAY_SIZE (bdesc_stores
); i
++, d
++)
9395 if (d
->code
== fcode
)
9396 return frv_expand_store_builtin (d
->icode
, exp
);
9402 frv_in_small_data_p (const_tree decl
)
9405 const char *section_name
;
9407 /* Don't apply the -G flag to internal compiler structures. We
9408 should leave such structures in the main data section, partly
9409 for efficiency and partly because the size of some of them
9410 (such as C++ typeinfos) is not known until later. */
9411 if (TREE_CODE (decl
) != VAR_DECL
|| DECL_ARTIFICIAL (decl
))
9414 /* If we already know which section the decl should be in, see if
9415 it's a small data section. */
9416 section_name
= DECL_SECTION_NAME (decl
);
9419 if (frv_string_begins_with (section_name
, ".sdata"))
9421 if (frv_string_begins_with (section_name
, ".sbss"))
9426 size
= int_size_in_bytes (TREE_TYPE (decl
));
9427 if (size
> 0 && size
<= g_switch_value
)
9434 frv_rtx_costs (rtx x
,
9437 int opno ATTRIBUTE_UNUSED
,
9439 bool speed ATTRIBUTE_UNUSED
)
9441 int code
= GET_CODE (x
);
9443 if (outer_code
== MEM
)
9445 /* Don't differentiate between memory addresses. All the ones
9446 we accept have equal cost. */
9447 *total
= COSTS_N_INSNS (0);
9454 /* Make 12-bit integers really cheap. */
9455 if (IN_RANGE (INTVAL (x
), -2048, 2047))
9466 *total
= COSTS_N_INSNS (2);
9481 *total
= COSTS_N_INSNS (1);
9482 else if (mode
== DImode
)
9483 *total
= COSTS_N_INSNS (2);
9485 *total
= COSTS_N_INSNS (3);
9490 *total
= COSTS_N_INSNS (2);
9492 *total
= COSTS_N_INSNS (6); /* guess */
9499 *total
= COSTS_N_INSNS (18);
9503 *total
= COSTS_N_INSNS (3);
9512 frv_asm_out_constructor (rtx symbol
, int priority ATTRIBUTE_UNUSED
)
9514 switch_to_section (ctors_section
);
9515 assemble_align (POINTER_SIZE
);
9518 int ok
= frv_assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, 1);
9523 assemble_integer_with_op ("\t.picptr\t", symbol
);
9527 frv_asm_out_destructor (rtx symbol
, int priority ATTRIBUTE_UNUSED
)
9529 switch_to_section (dtors_section
);
9530 assemble_align (POINTER_SIZE
);
9533 int ok
= frv_assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, 1);
9538 assemble_integer_with_op ("\t.picptr\t", symbol
);
9541 /* Worker function for TARGET_STRUCT_VALUE_RTX. */
9544 frv_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED
,
9545 int incoming ATTRIBUTE_UNUSED
)
9547 return gen_rtx_REG (Pmode
, FRV_STRUCT_VALUE_REGNUM
);
9550 #define TLS_BIAS (2048 - 16)
9552 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
9553 We need to emit DTP-relative relocations. */
9556 frv_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
9558 gcc_assert (size
== 4);
9559 fputs ("\t.picptr\ttlsmoff(", file
);
9560 /* We want the unbiased TLS offset, so add the bias to the
9561 expression, such that the implicit biasing cancels out. */
9562 output_addr_const (file
, plus_constant (Pmode
, x
, TLS_BIAS
));