1 /* Copyright (C) 1997-2015 Free Software Foundation, Inc.
2 Contributed by Red Hat, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
22 #include "coretypes.h"
27 #include "double-int.h"
34 #include "fold-const.h"
36 #include "stor-layout.h"
37 #include "stringpool.h"
39 #include "hard-reg-set.h"
41 #include "insn-config.h"
42 #include "conditions.h"
43 #include "insn-flags.h"
45 #include "insn-attr.h"
51 #include "statistics.h"
53 #include "fixed-value.h"
63 #include "insn-codes.h"
65 #include "diagnostic-core.h"
67 #include "dominance.h"
73 #include "cfgcleanup.h"
74 #include "basic-block.h"
78 #include "target-def.h"
79 #include "targhooks.h"
80 #include "langhooks.h"
88 #define FRV_INLINE inline
91 /* The maximum number of distinct NOP patterns. There are three:
92 nop, fnop and mnop. */
93 #define NUM_NOP_PATTERNS 3
95 /* Classification of instructions and units: integer, floating-point/media,
96 branch and control. */
97 enum frv_insn_group
{ GROUP_I
, GROUP_FM
, GROUP_B
, GROUP_C
, NUM_GROUPS
};
99 /* The DFA names of the units, in packet order. */
100 static const char *const frv_unit_names
[] =
110 /* The classification of each unit in frv_unit_names[]. */
111 static const enum frv_insn_group frv_unit_groups
[ARRAY_SIZE (frv_unit_names
)] =
121 /* Return the DFA unit code associated with the Nth unit of integer
122 or floating-point group GROUP, */
123 #define NTH_UNIT(GROUP, N) frv_unit_codes[(GROUP) + (N) * 2 + 1]
125 /* Return the number of integer or floating-point unit UNIT
126 (1 for I1, 2 for F2, etc.). */
127 #define UNIT_NUMBER(UNIT) (((UNIT) - 1) / 2)
129 /* The DFA unit number for each unit in frv_unit_names[]. */
130 static int frv_unit_codes
[ARRAY_SIZE (frv_unit_names
)];
132 /* FRV_TYPE_TO_UNIT[T] is the last unit in frv_unit_names[] that can issue
133 an instruction of type T. The value is ARRAY_SIZE (frv_unit_names) if
134 no instruction of type T has been seen. */
135 static unsigned int frv_type_to_unit
[TYPE_UNKNOWN
+ 1];
137 /* An array of dummy nop INSNs, one for each type of nop that the
139 static GTY(()) rtx_insn
*frv_nops
[NUM_NOP_PATTERNS
];
141 /* The number of nop instructions in frv_nops[]. */
142 static unsigned int frv_num_nops
;
144 /* The type of access. FRV_IO_UNKNOWN means the access can be either
145 a read or a write. */
146 enum frv_io_type
{ FRV_IO_UNKNOWN
, FRV_IO_READ
, FRV_IO_WRITE
};
148 /* Information about one __builtin_read or __builtin_write access, or
149 the combination of several such accesses. The most general value
150 is all-zeros (an unknown access to an unknown address). */
152 enum frv_io_type type
;
154 /* The constant address being accessed, or zero if not known. */
155 HOST_WIDE_INT const_address
;
157 /* The run-time address, as used in operand 0 of the membar pattern. */
161 /* Return true if instruction INSN should be packed with the following
163 #define PACKING_FLAG_P(INSN) (GET_MODE (INSN) == TImode)
165 /* Set the value of PACKING_FLAG_P(INSN). */
166 #define SET_PACKING_FLAG(INSN) PUT_MODE (INSN, TImode)
167 #define CLEAR_PACKING_FLAG(INSN) PUT_MODE (INSN, VOIDmode)
169 /* Loop with REG set to each hard register in rtx X. */
170 #define FOR_EACH_REGNO(REG, X) \
171 for (REG = REGNO (X); \
172 REG < REGNO (X) + HARD_REGNO_NREGS (REGNO (X), GET_MODE (X)); \
175 /* This structure contains machine specific function data. */
176 struct GTY(()) machine_function
178 /* True if we have created an rtx that relies on the stack frame. */
181 /* True if this function contains at least one __builtin_{read,write}*. */
185 /* Temporary register allocation support structure. */
186 typedef struct frv_tmp_reg_struct
188 HARD_REG_SET regs
; /* possible registers to allocate */
189 int next_reg
[N_REG_CLASSES
]; /* next register to allocate per class */
193 /* Register state information for VLIW re-packing phase. */
194 #define REGSTATE_CC_MASK 0x07 /* Mask to isolate CCn for cond exec */
195 #define REGSTATE_MODIFIED 0x08 /* reg modified in current VLIW insn */
196 #define REGSTATE_IF_TRUE 0x10 /* reg modified in cond exec true */
197 #define REGSTATE_IF_FALSE 0x20 /* reg modified in cond exec false */
199 #define REGSTATE_IF_EITHER (REGSTATE_IF_TRUE | REGSTATE_IF_FALSE)
201 typedef unsigned char regstate_t
;
203 /* Used in frv_frame_accessor_t to indicate the direction of a register-to-
211 /* Information required by frv_frame_access. */
214 /* This field is FRV_LOAD if registers are to be loaded from the stack and
215 FRV_STORE if they should be stored onto the stack. FRV_STORE implies
216 the move is being done by the prologue code while FRV_LOAD implies it
217 is being done by the epilogue. */
218 enum frv_stack_op op
;
220 /* The base register to use when accessing the stack. This may be the
221 frame pointer, stack pointer, or a temporary. The choice of register
222 depends on which part of the frame is being accessed and how big the
226 /* The offset of BASE from the bottom of the current frame, in bytes. */
228 } frv_frame_accessor_t
;
230 /* Conditional execution support gathered together in one structure. */
233 /* Linked list of insns to add if the conditional execution conversion was
234 successful. Each link points to an EXPR_LIST which points to the pattern
235 of the insn to add, and the insn to be inserted before. */
236 rtx added_insns_list
;
238 /* Identify which registers are safe to allocate for if conversions to
239 conditional execution. We keep the last allocated register in the
240 register classes between COND_EXEC statements. This will mean we allocate
241 different registers for each different COND_EXEC group if we can. This
242 might allow the scheduler to intermix two different COND_EXEC sections. */
243 frv_tmp_reg_t tmp_reg
;
245 /* For nested IFs, identify which CC registers are used outside of setting
246 via a compare isnsn, and using via a check insn. This will allow us to
247 know if we can rewrite the register to use a different register that will
248 be paired with the CR register controlling the nested IF-THEN blocks. */
249 HARD_REG_SET nested_cc_ok_rewrite
;
251 /* Temporary registers allocated to hold constants during conditional
253 rtx scratch_regs
[FIRST_PSEUDO_REGISTER
];
255 /* Current number of temp registers available. */
256 int cur_scratch_regs
;
258 /* Number of nested conditional execution blocks. */
259 int num_nested_cond_exec
;
261 /* Map of insns that set up constants in scratch registers. */
262 bitmap scratch_insns_bitmap
;
264 /* Conditional execution test register (CC0..CC7). */
267 /* Conditional execution compare register that is paired with cr_reg, so that
268 nested compares can be done. The csubcc and caddcc instructions don't
269 have enough bits to specify both a CC register to be set and a CR register
270 to do the test on, so the same bit number is used for both. Needless to
271 say, this is rather inconvenient for GCC. */
274 /* Extra CR registers used for &&, ||. */
278 /* Previous CR used in nested if, to make sure we are dealing with the same
279 nested if as the previous statement. */
280 rtx last_nested_if_cr
;
284 static /* GTY(()) */ frv_ifcvt_t frv_ifcvt
;
286 /* Map register number to smallest register class. */
287 enum reg_class regno_reg_class
[FIRST_PSEUDO_REGISTER
];
289 /* Cached value of frv_stack_info. */
290 static frv_stack_t
*frv_stack_cache
= (frv_stack_t
*)0;
292 /* Forward references */
294 static void frv_option_override (void);
295 static bool frv_legitimate_address_p (machine_mode
, rtx
, bool);
296 static int frv_default_flags_for_cpu (void);
297 static int frv_string_begins_with (const char *, const char *);
298 static FRV_INLINE
bool frv_small_data_reloc_p (rtx
, int);
299 static void frv_print_operand (FILE *, rtx
, int);
300 static void frv_print_operand_address (FILE *, rtx
);
301 static bool frv_print_operand_punct_valid_p (unsigned char code
);
302 static void frv_print_operand_memory_reference_reg
304 static void frv_print_operand_memory_reference (FILE *, rtx
, int);
305 static int frv_print_operand_jump_hint (rtx_insn
*);
306 static const char *comparison_string (enum rtx_code
, rtx
);
307 static rtx
frv_function_value (const_tree
, const_tree
,
309 static rtx
frv_libcall_value (machine_mode
,
311 static FRV_INLINE
int frv_regno_ok_for_base_p (int, int);
312 static rtx
single_set_pattern (rtx
);
313 static int frv_function_contains_far_jump (void);
314 static rtx
frv_alloc_temp_reg (frv_tmp_reg_t
*,
318 static rtx
frv_frame_offset_rtx (int);
319 static rtx
frv_frame_mem (machine_mode
, rtx
, int);
320 static rtx
frv_dwarf_store (rtx
, int);
321 static void frv_frame_insn (rtx
, rtx
);
322 static void frv_frame_access (frv_frame_accessor_t
*,
324 static void frv_frame_access_multi (frv_frame_accessor_t
*,
326 static void frv_frame_access_standard_regs (enum frv_stack_op
,
328 static struct machine_function
*frv_init_machine_status (void);
329 static rtx
frv_int_to_acc (enum insn_code
, int, rtx
);
330 static machine_mode
frv_matching_accg_mode (machine_mode
);
331 static rtx
frv_read_argument (tree
, unsigned int);
332 static rtx
frv_read_iacc_argument (machine_mode
, tree
, unsigned int);
333 static int frv_check_constant_argument (enum insn_code
, int, rtx
);
334 static rtx
frv_legitimize_target (enum insn_code
, rtx
);
335 static rtx
frv_legitimize_argument (enum insn_code
, int, rtx
);
336 static rtx
frv_legitimize_tls_address (rtx
, enum tls_model
);
337 static rtx
frv_legitimize_address (rtx
, rtx
, machine_mode
);
338 static rtx
frv_expand_set_builtin (enum insn_code
, tree
, rtx
);
339 static rtx
frv_expand_unop_builtin (enum insn_code
, tree
, rtx
);
340 static rtx
frv_expand_binop_builtin (enum insn_code
, tree
, rtx
);
341 static rtx
frv_expand_cut_builtin (enum insn_code
, tree
, rtx
);
342 static rtx
frv_expand_binopimm_builtin (enum insn_code
, tree
, rtx
);
343 static rtx
frv_expand_voidbinop_builtin (enum insn_code
, tree
);
344 static rtx
frv_expand_int_void2arg (enum insn_code
, tree
);
345 static rtx
frv_expand_prefetches (enum insn_code
, tree
);
346 static rtx
frv_expand_voidtriop_builtin (enum insn_code
, tree
);
347 static rtx
frv_expand_voidaccop_builtin (enum insn_code
, tree
);
348 static rtx
frv_expand_mclracc_builtin (tree
);
349 static rtx
frv_expand_mrdacc_builtin (enum insn_code
, tree
);
350 static rtx
frv_expand_mwtacc_builtin (enum insn_code
, tree
);
351 static rtx
frv_expand_noargs_builtin (enum insn_code
);
352 static void frv_split_iacc_move (rtx
, rtx
);
353 static rtx
frv_emit_comparison (enum rtx_code
, rtx
, rtx
);
354 static void frv_ifcvt_add_insn (rtx
, rtx
, int);
355 static rtx
frv_ifcvt_rewrite_mem (rtx
, machine_mode
, rtx
);
356 static rtx
frv_ifcvt_load_value (rtx
, rtx
);
357 static unsigned int frv_insn_unit (rtx_insn
*);
358 static bool frv_issues_to_branch_unit_p (rtx_insn
*);
359 static int frv_cond_flags (rtx
);
360 static bool frv_regstate_conflict_p (regstate_t
, regstate_t
);
361 static bool frv_registers_conflict_p (rtx
);
362 static void frv_registers_update_1 (rtx
, const_rtx
, void *);
363 static void frv_registers_update (rtx
);
364 static void frv_start_packet (void);
365 static void frv_start_packet_block (void);
366 static void frv_finish_packet (void (*) (void));
367 static bool frv_pack_insn_p (rtx_insn
*);
368 static void frv_add_insn_to_packet (rtx_insn
*);
369 static void frv_insert_nop_in_packet (rtx_insn
*);
370 static bool frv_for_each_packet (void (*) (void));
371 static bool frv_sort_insn_group_1 (enum frv_insn_group
,
372 unsigned int, unsigned int,
373 unsigned int, unsigned int,
375 static int frv_compare_insns (const void *, const void *);
376 static void frv_sort_insn_group (enum frv_insn_group
);
377 static void frv_reorder_packet (void);
378 static void frv_fill_unused_units (enum frv_insn_group
);
379 static void frv_align_label (void);
380 static void frv_reorg_packet (void);
381 static void frv_register_nop (rtx
);
382 static void frv_reorg (void);
383 static void frv_pack_insns (void);
384 static void frv_function_prologue (FILE *, HOST_WIDE_INT
);
385 static void frv_function_epilogue (FILE *, HOST_WIDE_INT
);
386 static bool frv_assemble_integer (rtx
, unsigned, int);
387 static void frv_init_builtins (void);
388 static rtx
frv_expand_builtin (tree
, rtx
, rtx
, machine_mode
, int);
389 static void frv_init_libfuncs (void);
390 static bool frv_in_small_data_p (const_tree
);
391 static void frv_asm_output_mi_thunk
392 (FILE *, tree
, HOST_WIDE_INT
, HOST_WIDE_INT
, tree
);
393 static void frv_setup_incoming_varargs (cumulative_args_t
,
396 static rtx
frv_expand_builtin_saveregs (void);
397 static void frv_expand_builtin_va_start (tree
, rtx
);
398 static bool frv_rtx_costs (rtx
, int, int, int, int*,
400 static int frv_register_move_cost (machine_mode
,
401 reg_class_t
, reg_class_t
);
402 static int frv_memory_move_cost (machine_mode
,
404 static void frv_asm_out_constructor (rtx
, int);
405 static void frv_asm_out_destructor (rtx
, int);
406 static bool frv_function_symbol_referenced_p (rtx
);
407 static bool frv_legitimate_constant_p (machine_mode
, rtx
);
408 static bool frv_cannot_force_const_mem (machine_mode
, rtx
);
409 static const char *unspec_got_name (int);
410 static void frv_output_const_unspec (FILE *,
411 const struct frv_unspec
*);
412 static bool frv_function_ok_for_sibcall (tree
, tree
);
413 static rtx
frv_struct_value_rtx (tree
, int);
414 static bool frv_must_pass_in_stack (machine_mode mode
, const_tree type
);
415 static int frv_arg_partial_bytes (cumulative_args_t
, machine_mode
,
417 static rtx
frv_function_arg (cumulative_args_t
, machine_mode
,
419 static rtx
frv_function_incoming_arg (cumulative_args_t
, machine_mode
,
421 static void frv_function_arg_advance (cumulative_args_t
, machine_mode
,
423 static unsigned int frv_function_arg_boundary (machine_mode
,
425 static void frv_output_dwarf_dtprel (FILE *, int, rtx
)
427 static reg_class_t
frv_secondary_reload (bool, rtx
, reg_class_t
,
429 secondary_reload_info
*);
430 static bool frv_frame_pointer_required (void);
431 static bool frv_can_eliminate (const int, const int);
432 static void frv_conditional_register_usage (void);
433 static void frv_trampoline_init (rtx
, tree
, rtx
);
434 static bool frv_class_likely_spilled_p (reg_class_t
);
436 /* Initialize the GCC target structure. */
437 #undef TARGET_PRINT_OPERAND
438 #define TARGET_PRINT_OPERAND frv_print_operand
439 #undef TARGET_PRINT_OPERAND_ADDRESS
440 #define TARGET_PRINT_OPERAND_ADDRESS frv_print_operand_address
441 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
442 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P frv_print_operand_punct_valid_p
443 #undef TARGET_ASM_FUNCTION_PROLOGUE
444 #define TARGET_ASM_FUNCTION_PROLOGUE frv_function_prologue
445 #undef TARGET_ASM_FUNCTION_EPILOGUE
446 #define TARGET_ASM_FUNCTION_EPILOGUE frv_function_epilogue
447 #undef TARGET_ASM_INTEGER
448 #define TARGET_ASM_INTEGER frv_assemble_integer
449 #undef TARGET_OPTION_OVERRIDE
450 #define TARGET_OPTION_OVERRIDE frv_option_override
451 #undef TARGET_INIT_BUILTINS
452 #define TARGET_INIT_BUILTINS frv_init_builtins
453 #undef TARGET_EXPAND_BUILTIN
454 #define TARGET_EXPAND_BUILTIN frv_expand_builtin
455 #undef TARGET_INIT_LIBFUNCS
456 #define TARGET_INIT_LIBFUNCS frv_init_libfuncs
457 #undef TARGET_IN_SMALL_DATA_P
458 #define TARGET_IN_SMALL_DATA_P frv_in_small_data_p
459 #undef TARGET_REGISTER_MOVE_COST
460 #define TARGET_REGISTER_MOVE_COST frv_register_move_cost
461 #undef TARGET_MEMORY_MOVE_COST
462 #define TARGET_MEMORY_MOVE_COST frv_memory_move_cost
463 #undef TARGET_RTX_COSTS
464 #define TARGET_RTX_COSTS frv_rtx_costs
465 #undef TARGET_ASM_CONSTRUCTOR
466 #define TARGET_ASM_CONSTRUCTOR frv_asm_out_constructor
467 #undef TARGET_ASM_DESTRUCTOR
468 #define TARGET_ASM_DESTRUCTOR frv_asm_out_destructor
470 #undef TARGET_ASM_OUTPUT_MI_THUNK
471 #define TARGET_ASM_OUTPUT_MI_THUNK frv_asm_output_mi_thunk
472 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
473 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
475 #undef TARGET_SCHED_ISSUE_RATE
476 #define TARGET_SCHED_ISSUE_RATE frv_issue_rate
478 #undef TARGET_LEGITIMIZE_ADDRESS
479 #define TARGET_LEGITIMIZE_ADDRESS frv_legitimize_address
481 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
482 #define TARGET_FUNCTION_OK_FOR_SIBCALL frv_function_ok_for_sibcall
483 #undef TARGET_LEGITIMATE_CONSTANT_P
484 #define TARGET_LEGITIMATE_CONSTANT_P frv_legitimate_constant_p
485 #undef TARGET_CANNOT_FORCE_CONST_MEM
486 #define TARGET_CANNOT_FORCE_CONST_MEM frv_cannot_force_const_mem
488 #undef TARGET_HAVE_TLS
489 #define TARGET_HAVE_TLS HAVE_AS_TLS
491 #undef TARGET_STRUCT_VALUE_RTX
492 #define TARGET_STRUCT_VALUE_RTX frv_struct_value_rtx
493 #undef TARGET_MUST_PASS_IN_STACK
494 #define TARGET_MUST_PASS_IN_STACK frv_must_pass_in_stack
495 #undef TARGET_PASS_BY_REFERENCE
496 #define TARGET_PASS_BY_REFERENCE hook_pass_by_reference_must_pass_in_stack
497 #undef TARGET_ARG_PARTIAL_BYTES
498 #define TARGET_ARG_PARTIAL_BYTES frv_arg_partial_bytes
499 #undef TARGET_FUNCTION_ARG
500 #define TARGET_FUNCTION_ARG frv_function_arg
501 #undef TARGET_FUNCTION_INCOMING_ARG
502 #define TARGET_FUNCTION_INCOMING_ARG frv_function_incoming_arg
503 #undef TARGET_FUNCTION_ARG_ADVANCE
504 #define TARGET_FUNCTION_ARG_ADVANCE frv_function_arg_advance
505 #undef TARGET_FUNCTION_ARG_BOUNDARY
506 #define TARGET_FUNCTION_ARG_BOUNDARY frv_function_arg_boundary
508 #undef TARGET_EXPAND_BUILTIN_SAVEREGS
509 #define TARGET_EXPAND_BUILTIN_SAVEREGS frv_expand_builtin_saveregs
510 #undef TARGET_SETUP_INCOMING_VARARGS
511 #define TARGET_SETUP_INCOMING_VARARGS frv_setup_incoming_varargs
512 #undef TARGET_MACHINE_DEPENDENT_REORG
513 #define TARGET_MACHINE_DEPENDENT_REORG frv_reorg
515 #undef TARGET_EXPAND_BUILTIN_VA_START
516 #define TARGET_EXPAND_BUILTIN_VA_START frv_expand_builtin_va_start
519 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
520 #define TARGET_ASM_OUTPUT_DWARF_DTPREL frv_output_dwarf_dtprel
523 #undef TARGET_CLASS_LIKELY_SPILLED_P
524 #define TARGET_CLASS_LIKELY_SPILLED_P frv_class_likely_spilled_p
526 #undef TARGET_SECONDARY_RELOAD
527 #define TARGET_SECONDARY_RELOAD frv_secondary_reload
529 #undef TARGET_LEGITIMATE_ADDRESS_P
530 #define TARGET_LEGITIMATE_ADDRESS_P frv_legitimate_address_p
532 #undef TARGET_FRAME_POINTER_REQUIRED
533 #define TARGET_FRAME_POINTER_REQUIRED frv_frame_pointer_required
535 #undef TARGET_CAN_ELIMINATE
536 #define TARGET_CAN_ELIMINATE frv_can_eliminate
538 #undef TARGET_CONDITIONAL_REGISTER_USAGE
539 #define TARGET_CONDITIONAL_REGISTER_USAGE frv_conditional_register_usage
541 #undef TARGET_TRAMPOLINE_INIT
542 #define TARGET_TRAMPOLINE_INIT frv_trampoline_init
544 #undef TARGET_FUNCTION_VALUE
545 #define TARGET_FUNCTION_VALUE frv_function_value
546 #undef TARGET_LIBCALL_VALUE
547 #define TARGET_LIBCALL_VALUE frv_libcall_value
549 struct gcc_target targetm
= TARGET_INITIALIZER
;
551 #define FRV_SYMBOL_REF_TLS_P(RTX) \
552 (GET_CODE (RTX) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (RTX) != 0)
555 /* Any function call that satisfies the machine-independent
556 requirements is eligible on FR-V. */
559 frv_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED
,
560 tree exp ATTRIBUTE_UNUSED
)
565 /* Return true if SYMBOL is a small data symbol and relocation RELOC
566 can be used to access it directly in a load or store. */
568 static FRV_INLINE
bool
569 frv_small_data_reloc_p (rtx symbol
, int reloc
)
571 return (GET_CODE (symbol
) == SYMBOL_REF
572 && SYMBOL_REF_SMALL_P (symbol
)
573 && (!TARGET_FDPIC
|| flag_pic
== 1)
574 && (reloc
== R_FRV_GOTOFF12
|| reloc
== R_FRV_GPREL12
));
577 /* Return true if X is a valid relocation unspec. If it is, fill in UNSPEC
581 frv_const_unspec_p (rtx x
, struct frv_unspec
*unspec
)
583 if (GET_CODE (x
) == CONST
)
587 if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == CONST_INT
)
589 unspec
->offset
+= INTVAL (XEXP (x
, 1));
592 if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_GOT
)
594 unspec
->symbol
= XVECEXP (x
, 0, 0);
595 unspec
->reloc
= INTVAL (XVECEXP (x
, 0, 1));
597 if (unspec
->offset
== 0)
600 if (frv_small_data_reloc_p (unspec
->symbol
, unspec
->reloc
)
601 && unspec
->offset
> 0
602 && unspec
->offset
< g_switch_value
)
609 /* Decide whether we can force certain constants to memory. If we
610 decide we can't, the caller should be able to cope with it in
613 We never allow constants to be forced into memory for TARGET_FDPIC.
614 This is necessary for several reasons:
616 1. Since frv_legitimate_constant_p rejects constant pool addresses, the
617 target-independent code will try to force them into the constant
618 pool, thus leading to infinite recursion.
620 2. We can never introduce new constant pool references during reload.
621 Any such reference would require use of the pseudo FDPIC register.
623 3. We can't represent a constant added to a function pointer (which is
624 not the same as a pointer to a function+constant).
626 4. In many cases, it's more efficient to calculate the constant in-line. */
629 frv_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED
,
630 rtx x ATTRIBUTE_UNUSED
)
636 frv_default_flags_for_cpu (void)
638 switch (frv_cpu_type
)
640 case FRV_CPU_GENERIC
:
641 return MASK_DEFAULT_FRV
;
644 return MASK_DEFAULT_FR550
;
648 return MASK_DEFAULT_FR500
;
651 return MASK_DEFAULT_FR450
;
655 return MASK_DEFAULT_FR400
;
659 return MASK_DEFAULT_SIMPLE
;
666 /* Implement TARGET_OPTION_OVERRIDE. */
669 frv_option_override (void)
674 target_flags
|= (frv_default_flags_for_cpu () & ~target_flags_explicit
);
676 /* -mlibrary-pic sets -fPIC and -G0 and also suppresses warnings from the
677 linker about linking pic and non-pic code. */
680 if (!flag_pic
) /* -fPIC */
683 if (!global_options_set
.x_g_switch_value
) /* -G0 */
689 /* A C expression whose value is a register class containing hard
690 register REGNO. In general there is more than one such class;
691 choose a class which is "minimal", meaning that no smaller class
692 also contains the register. */
694 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
696 enum reg_class rclass
;
700 int gpr_reg
= regno
- GPR_FIRST
;
702 if (gpr_reg
== GR8_REG
)
705 else if (gpr_reg
== GR9_REG
)
708 else if (gpr_reg
== GR14_REG
)
709 rclass
= FDPIC_FPTR_REGS
;
711 else if (gpr_reg
== FDPIC_REGNO
)
714 else if ((gpr_reg
& 3) == 0)
717 else if ((gpr_reg
& 1) == 0)
724 else if (FPR_P (regno
))
726 int fpr_reg
= regno
- GPR_FIRST
;
727 if ((fpr_reg
& 3) == 0)
728 rclass
= QUAD_FPR_REGS
;
730 else if ((fpr_reg
& 1) == 0)
737 else if (regno
== LR_REGNO
)
740 else if (regno
== LCR_REGNO
)
743 else if (ICC_P (regno
))
746 else if (FCC_P (regno
))
749 else if (ICR_P (regno
))
752 else if (FCR_P (regno
))
755 else if (ACC_P (regno
))
757 int r
= regno
- ACC_FIRST
;
759 rclass
= QUAD_ACC_REGS
;
760 else if ((r
& 1) == 0)
761 rclass
= EVEN_ACC_REGS
;
766 else if (ACCG_P (regno
))
772 regno_reg_class
[regno
] = rclass
;
775 /* Check for small data option */
776 if (!global_options_set
.x_g_switch_value
&& !TARGET_LIBPIC
)
777 g_switch_value
= SDATA_DEFAULT_SIZE
;
779 /* There is no single unaligned SI op for PIC code. Sometimes we
780 need to use ".4byte" and sometimes we need to use ".picptr".
781 See frv_assemble_integer for details. */
782 if (flag_pic
|| TARGET_FDPIC
)
783 targetm
.asm_out
.unaligned_op
.si
= 0;
785 if ((target_flags_explicit
& MASK_LINKED_FP
) == 0)
786 target_flags
|= MASK_LINKED_FP
;
788 if ((target_flags_explicit
& MASK_OPTIMIZE_MEMBAR
) == 0)
789 target_flags
|= MASK_OPTIMIZE_MEMBAR
;
791 for (i
= 0; i
< ARRAY_SIZE (frv_unit_names
); i
++)
792 frv_unit_codes
[i
] = get_cpu_unit_code (frv_unit_names
[i
]);
794 for (i
= 0; i
< ARRAY_SIZE (frv_type_to_unit
); i
++)
795 frv_type_to_unit
[i
] = ARRAY_SIZE (frv_unit_codes
);
797 init_machine_status
= frv_init_machine_status
;
801 /* Return true if NAME (a STRING_CST node) begins with PREFIX. */
804 frv_string_begins_with (const char *name
, const char *prefix
)
806 const int prefix_len
= strlen (prefix
);
808 /* Remember: NAME's length includes the null terminator. */
809 return (strncmp (name
, prefix
, prefix_len
) == 0);
812 /* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */
815 frv_conditional_register_usage (void)
819 for (i
= GPR_FIRST
+ NUM_GPRS
; i
<= GPR_LAST
; i
++)
820 fixed_regs
[i
] = call_used_regs
[i
] = 1;
822 for (i
= FPR_FIRST
+ NUM_FPRS
; i
<= FPR_LAST
; i
++)
823 fixed_regs
[i
] = call_used_regs
[i
] = 1;
825 /* Reserve the registers used for conditional execution. At present, we need
826 1 ICC and 1 ICR register. */
827 fixed_regs
[ICC_TEMP
] = call_used_regs
[ICC_TEMP
] = 1;
828 fixed_regs
[ICR_TEMP
] = call_used_regs
[ICR_TEMP
] = 1;
832 fixed_regs
[ICC_FIRST
] = call_used_regs
[ICC_FIRST
] = 1;
833 fixed_regs
[FCC_FIRST
] = call_used_regs
[FCC_FIRST
] = 1;
834 fixed_regs
[ICR_FIRST
] = call_used_regs
[ICR_FIRST
] = 1;
835 fixed_regs
[FCR_FIRST
] = call_used_regs
[FCR_FIRST
] = 1;
839 fixed_regs
[GPR_FIRST
+ 16] = fixed_regs
[GPR_FIRST
+ 17] =
840 call_used_regs
[GPR_FIRST
+ 16] = call_used_regs
[GPR_FIRST
+ 17] = 0;
843 /* If -fpic, SDA_BASE_REG is the PIC register. */
844 if (g_switch_value
== 0 && !flag_pic
)
845 fixed_regs
[SDA_BASE_REG
] = call_used_regs
[SDA_BASE_REG
] = 0;
848 fixed_regs
[PIC_REGNO
] = call_used_regs
[PIC_REGNO
] = 0;
854 * Compute the stack frame layout
857 * +---------------+-----------------------+-----------------------+
858 * |Register |type |caller-save/callee-save|
859 * +---------------+-----------------------+-----------------------+
860 * |GR0 |Zero register | - |
861 * |GR1 |Stack pointer(SP) | - |
862 * |GR2 |Frame pointer(FP) | - |
863 * |GR3 |Hidden parameter | caller save |
864 * |GR4-GR7 | - | caller save |
865 * |GR8-GR13 |Argument register | caller save |
866 * |GR14-GR15 | - | caller save |
867 * |GR16-GR31 | - | callee save |
868 * |GR32-GR47 | - | caller save |
869 * |GR48-GR63 | - | callee save |
870 * |FR0-FR15 | - | caller save |
871 * |FR16-FR31 | - | callee save |
872 * |FR32-FR47 | - | caller save |
873 * |FR48-FR63 | - | callee save |
874 * +---------------+-----------------------+-----------------------+
878 * SP-> |-----------------------------------|
880 * |-----------------------------------|
881 * | Register save area |
882 * |-----------------------------------|
883 * | Local variable save area |
884 * FP-> |-----------------------------------|
886 * |-----------------------------------|
887 * | Hidden parameter save area |
888 * |-----------------------------------|
889 * | Return address(LR) storage area |
890 * |-----------------------------------|
891 * | Padding for alignment |
892 * |-----------------------------------|
893 * | Register argument area |
894 * OLD SP-> |-----------------------------------|
896 * |-----------------------------------|
899 * Argument area/Parameter area:
901 * When a function is called, this area is used for argument transfer. When
902 * the argument is set up by the caller function, this area is referred to as
903 * the argument area. When the argument is referenced by the callee function,
904 * this area is referred to as the parameter area. The area is allocated when
905 * all arguments cannot be placed on the argument register at the time of
908 * Register save area:
910 * This is a register save area that must be guaranteed for the caller
911 * function. This area is not secured when the register save operation is not
914 * Local variable save area:
916 * This is the area for local variables and temporary variables.
920 * This area stores the FP value of the caller function.
922 * Hidden parameter save area:
924 * This area stores the start address of the return value storage
925 * area for a struct/union return function.
926 * When a struct/union is used as the return value, the caller
927 * function stores the return value storage area start address in
928 * register GR3 and passes it to the caller function.
929 * The callee function interprets the address stored in the GR3
930 * as the return value storage area start address.
931 * When register GR3 needs to be saved into memory, the callee
932 * function saves it in the hidden parameter save area. This
933 * area is not secured when the save operation is not needed.
935 * Return address(LR) storage area:
937 * This area saves the LR. The LR stores the address of a return to the caller
938 * function for the purpose of function calling.
940 * Argument register area:
942 * This area saves the argument register. This area is not secured when the
943 * save operation is not needed.
947 * Arguments, the count of which equals the count of argument registers (6
948 * words), are positioned in registers GR8 to GR13 and delivered to the callee
949 * function. When a struct/union return function is called, the return value
950 * area address is stored in register GR3. Arguments not placed in the
951 * argument registers will be stored in the stack argument area for transfer
952 * purposes. When an 8-byte type argument is to be delivered using registers,
953 * it is divided into two and placed in two registers for transfer. When
954 * argument registers must be saved to memory, the callee function secures an
955 * argument register save area in the stack. In this case, a continuous
956 * argument register save area must be established in the parameter area. The
957 * argument register save area must be allocated as needed to cover the size of
958 * the argument register to be saved. If the function has a variable count of
959 * arguments, it saves all argument registers in the argument register save
962 * Argument Extension Format:
964 * When an argument is to be stored in the stack, its type is converted to an
965 * extended type in accordance with the individual argument type. The argument
966 * is freed by the caller function after the return from the callee function is
969 * +-----------------------+---------------+------------------------+
970 * | Argument Type |Extended Type |Stack Storage Size(byte)|
971 * +-----------------------+---------------+------------------------+
973 * |signed char |int | 4 |
974 * |unsigned char |int | 4 |
975 * |[signed] short int |int | 4 |
976 * |unsigned short int |int | 4 |
977 * |[signed] int |No extension | 4 |
978 * |unsigned int |No extension | 4 |
979 * |[signed] long int |No extension | 4 |
980 * |unsigned long int |No extension | 4 |
981 * |[signed] long long int |No extension | 8 |
982 * |unsigned long long int |No extension | 8 |
983 * |float |double | 8 |
984 * |double |No extension | 8 |
985 * |long double |No extension | 8 |
986 * |pointer |No extension | 4 |
987 * |struct/union |- | 4 (*1) |
988 * +-----------------------+---------------+------------------------+
990 * When a struct/union is to be delivered as an argument, the caller copies it
991 * to the local variable area and delivers the address of that area.
995 * +-------------------------------+----------------------+
996 * |Return Value Type |Return Value Interface|
997 * +-------------------------------+----------------------+
999 * |[signed|unsigned] char |GR8 |
1000 * |[signed|unsigned] short int |GR8 |
1001 * |[signed|unsigned] int |GR8 |
1002 * |[signed|unsigned] long int |GR8 |
1004 * |[signed|unsigned] long long int|GR8 & GR9 |
1006 * |double |GR8 & GR9 |
1007 * |long double |GR8 & GR9 |
1008 * |struct/union |(*1) |
1009 * +-------------------------------+----------------------+
1011 * When a struct/union is used as the return value, the caller function stores
1012 * the start address of the return value storage area into GR3 and then passes
1013 * it to the callee function. The callee function interprets GR3 as the start
1014 * address of the return value storage area. When this address needs to be
1015 * saved in memory, the callee function secures the hidden parameter save area
1016 * and saves the address in that area.
1020 frv_stack_info (void)
1022 static frv_stack_t info
, zero_info
;
1023 frv_stack_t
*info_ptr
= &info
;
1024 tree fndecl
= current_function_decl
;
1032 /* If we've already calculated the values and reload is complete,
1034 if (frv_stack_cache
)
1035 return frv_stack_cache
;
1037 /* Zero all fields. */
1040 /* Set up the register range information. */
1041 info_ptr
->regs
[STACK_REGS_GPR
].name
= "gpr";
1042 info_ptr
->regs
[STACK_REGS_GPR
].first
= LAST_ARG_REGNUM
+ 1;
1043 info_ptr
->regs
[STACK_REGS_GPR
].last
= GPR_LAST
;
1044 info_ptr
->regs
[STACK_REGS_GPR
].dword_p
= TRUE
;
1046 info_ptr
->regs
[STACK_REGS_FPR
].name
= "fpr";
1047 info_ptr
->regs
[STACK_REGS_FPR
].first
= FPR_FIRST
;
1048 info_ptr
->regs
[STACK_REGS_FPR
].last
= FPR_LAST
;
1049 info_ptr
->regs
[STACK_REGS_FPR
].dword_p
= TRUE
;
1051 info_ptr
->regs
[STACK_REGS_LR
].name
= "lr";
1052 info_ptr
->regs
[STACK_REGS_LR
].first
= LR_REGNO
;
1053 info_ptr
->regs
[STACK_REGS_LR
].last
= LR_REGNO
;
1054 info_ptr
->regs
[STACK_REGS_LR
].special_p
= 1;
1056 info_ptr
->regs
[STACK_REGS_CC
].name
= "cc";
1057 info_ptr
->regs
[STACK_REGS_CC
].first
= CC_FIRST
;
1058 info_ptr
->regs
[STACK_REGS_CC
].last
= CC_LAST
;
1059 info_ptr
->regs
[STACK_REGS_CC
].field_p
= TRUE
;
1061 info_ptr
->regs
[STACK_REGS_LCR
].name
= "lcr";
1062 info_ptr
->regs
[STACK_REGS_LCR
].first
= LCR_REGNO
;
1063 info_ptr
->regs
[STACK_REGS_LCR
].last
= LCR_REGNO
;
1065 info_ptr
->regs
[STACK_REGS_STDARG
].name
= "stdarg";
1066 info_ptr
->regs
[STACK_REGS_STDARG
].first
= FIRST_ARG_REGNUM
;
1067 info_ptr
->regs
[STACK_REGS_STDARG
].last
= LAST_ARG_REGNUM
;
1068 info_ptr
->regs
[STACK_REGS_STDARG
].dword_p
= 1;
1069 info_ptr
->regs
[STACK_REGS_STDARG
].special_p
= 1;
1071 info_ptr
->regs
[STACK_REGS_STRUCT
].name
= "struct";
1072 info_ptr
->regs
[STACK_REGS_STRUCT
].first
= FRV_STRUCT_VALUE_REGNUM
;
1073 info_ptr
->regs
[STACK_REGS_STRUCT
].last
= FRV_STRUCT_VALUE_REGNUM
;
1074 info_ptr
->regs
[STACK_REGS_STRUCT
].special_p
= 1;
1076 info_ptr
->regs
[STACK_REGS_FP
].name
= "fp";
1077 info_ptr
->regs
[STACK_REGS_FP
].first
= FRAME_POINTER_REGNUM
;
1078 info_ptr
->regs
[STACK_REGS_FP
].last
= FRAME_POINTER_REGNUM
;
1079 info_ptr
->regs
[STACK_REGS_FP
].special_p
= 1;
1081 /* Determine if this is a stdarg function. If so, allocate space to store
1088 /* Find the last argument, and see if it is __builtin_va_alist. */
1089 for (cur_arg
= DECL_ARGUMENTS (fndecl
); cur_arg
!= (tree
)0; cur_arg
= next_arg
)
1091 next_arg
= DECL_CHAIN (cur_arg
);
1092 if (next_arg
== (tree
)0)
1094 if (DECL_NAME (cur_arg
)
1095 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg
)), "__builtin_va_alist"))
1103 /* Iterate over all of the register ranges. */
1104 for (range
= 0; range
< STACK_REGS_MAX
; range
++)
1106 frv_stack_regs_t
*reg_ptr
= &(info_ptr
->regs
[range
]);
1107 int first
= reg_ptr
->first
;
1108 int last
= reg_ptr
->last
;
1110 int size_2words
= 0;
1113 /* Calculate which registers need to be saved & save area size. */
1117 for (regno
= first
; regno
<= last
; regno
++)
1119 if ((df_regs_ever_live_p (regno
) && !call_used_regs
[regno
])
1120 || (crtl
->calls_eh_return
1121 && (regno
>= FIRST_EH_REGNUM
&& regno
<= LAST_EH_REGNUM
))
1122 || (!TARGET_FDPIC
&& flag_pic
1123 && crtl
->uses_pic_offset_table
&& regno
== PIC_REGNO
))
1125 info_ptr
->save_p
[regno
] = REG_SAVE_1WORD
;
1126 size_1word
+= UNITS_PER_WORD
;
1131 /* Calculate whether we need to create a frame after everything else
1132 has been processed. */
1137 if (df_regs_ever_live_p (LR_REGNO
)
1139 /* This is set for __builtin_return_address, etc. */
1140 || cfun
->machine
->frame_needed
1141 || (TARGET_LINKED_FP
&& frame_pointer_needed
)
1142 || (!TARGET_FDPIC
&& flag_pic
1143 && crtl
->uses_pic_offset_table
))
1145 info_ptr
->save_p
[LR_REGNO
] = REG_SAVE_1WORD
;
1146 size_1word
+= UNITS_PER_WORD
;
1150 case STACK_REGS_STDARG
:
1153 /* If this is a stdarg function with a non varardic
1154 argument split between registers and the stack,
1155 adjust the saved registers downward. */
1156 last
-= (ADDR_ALIGN (crtl
->args
.pretend_args_size
, UNITS_PER_WORD
)
1159 for (regno
= first
; regno
<= last
; regno
++)
1161 info_ptr
->save_p
[regno
] = REG_SAVE_1WORD
;
1162 size_1word
+= UNITS_PER_WORD
;
1165 info_ptr
->stdarg_size
= size_1word
;
1169 case STACK_REGS_STRUCT
:
1170 if (cfun
->returns_struct
)
1172 info_ptr
->save_p
[FRV_STRUCT_VALUE_REGNUM
] = REG_SAVE_1WORD
;
1173 size_1word
+= UNITS_PER_WORD
;
1181 /* If this is a field, it only takes one word. */
1182 if (reg_ptr
->field_p
)
1183 size_1word
= UNITS_PER_WORD
;
1185 /* Determine which register pairs can be saved together. */
1186 else if (reg_ptr
->dword_p
&& TARGET_DWORD
)
1188 for (regno
= first
; regno
< last
; regno
+= 2)
1190 if (info_ptr
->save_p
[regno
] && info_ptr
->save_p
[regno
+1])
1192 size_2words
+= 2 * UNITS_PER_WORD
;
1193 size_1word
-= 2 * UNITS_PER_WORD
;
1194 info_ptr
->save_p
[regno
] = REG_SAVE_2WORDS
;
1195 info_ptr
->save_p
[regno
+1] = REG_SAVE_NO_SAVE
;
1200 reg_ptr
->size_1word
= size_1word
;
1201 reg_ptr
->size_2words
= size_2words
;
1203 if (! reg_ptr
->special_p
)
1205 info_ptr
->regs_size_1word
+= size_1word
;
1206 info_ptr
->regs_size_2words
+= size_2words
;
1211 /* Set up the sizes of each each field in the frame body, making the sizes
1212 of each be divisible by the size of a dword if dword operations might
1213 be used, or the size of a word otherwise. */
1214 alignment
= (TARGET_DWORD
? 2 * UNITS_PER_WORD
: UNITS_PER_WORD
);
1216 info_ptr
->parameter_size
= ADDR_ALIGN (crtl
->outgoing_args_size
, alignment
);
1217 info_ptr
->regs_size
= ADDR_ALIGN (info_ptr
->regs_size_2words
1218 + info_ptr
->regs_size_1word
,
1220 info_ptr
->vars_size
= ADDR_ALIGN (get_frame_size (), alignment
);
1222 info_ptr
->pretend_size
= crtl
->args
.pretend_args_size
;
1224 /* Work out the size of the frame, excluding the header. Both the frame
1225 body and register parameter area will be dword-aligned. */
1226 info_ptr
->total_size
1227 = (ADDR_ALIGN (info_ptr
->parameter_size
1228 + info_ptr
->regs_size
1229 + info_ptr
->vars_size
,
1231 + ADDR_ALIGN (info_ptr
->pretend_size
1232 + info_ptr
->stdarg_size
,
1233 2 * UNITS_PER_WORD
));
1235 /* See if we need to create a frame at all, if so add header area. */
1236 if (info_ptr
->total_size
> 0
1237 || frame_pointer_needed
1238 || info_ptr
->regs
[STACK_REGS_LR
].size_1word
> 0
1239 || info_ptr
->regs
[STACK_REGS_STRUCT
].size_1word
> 0)
1241 offset
= info_ptr
->parameter_size
;
1242 info_ptr
->header_size
= 4 * UNITS_PER_WORD
;
1243 info_ptr
->total_size
+= 4 * UNITS_PER_WORD
;
1245 /* Calculate the offsets to save normal register pairs. */
1246 for (range
= 0; range
< STACK_REGS_MAX
; range
++)
1248 frv_stack_regs_t
*reg_ptr
= &(info_ptr
->regs
[range
]);
1249 if (! reg_ptr
->special_p
)
1251 int first
= reg_ptr
->first
;
1252 int last
= reg_ptr
->last
;
1255 for (regno
= first
; regno
<= last
; regno
++)
1256 if (info_ptr
->save_p
[regno
] == REG_SAVE_2WORDS
1257 && regno
!= FRAME_POINTER_REGNUM
1258 && (regno
< FIRST_ARG_REGNUM
1259 || regno
> LAST_ARG_REGNUM
))
1261 info_ptr
->reg_offset
[regno
] = offset
;
1262 offset
+= 2 * UNITS_PER_WORD
;
1267 /* Calculate the offsets to save normal single registers. */
1268 for (range
= 0; range
< STACK_REGS_MAX
; range
++)
1270 frv_stack_regs_t
*reg_ptr
= &(info_ptr
->regs
[range
]);
1271 if (! reg_ptr
->special_p
)
1273 int first
= reg_ptr
->first
;
1274 int last
= reg_ptr
->last
;
1277 for (regno
= first
; regno
<= last
; regno
++)
1278 if (info_ptr
->save_p
[regno
] == REG_SAVE_1WORD
1279 && regno
!= FRAME_POINTER_REGNUM
1280 && (regno
< FIRST_ARG_REGNUM
1281 || regno
> LAST_ARG_REGNUM
))
1283 info_ptr
->reg_offset
[regno
] = offset
;
1284 offset
+= UNITS_PER_WORD
;
1289 /* Calculate the offset to save the local variables at. */
1290 offset
= ADDR_ALIGN (offset
, alignment
);
1291 if (info_ptr
->vars_size
)
1293 info_ptr
->vars_offset
= offset
;
1294 offset
+= info_ptr
->vars_size
;
1297 /* Align header to a dword-boundary. */
1298 offset
= ADDR_ALIGN (offset
, 2 * UNITS_PER_WORD
);
1300 /* Calculate the offsets in the fixed frame. */
1301 info_ptr
->save_p
[FRAME_POINTER_REGNUM
] = REG_SAVE_1WORD
;
1302 info_ptr
->reg_offset
[FRAME_POINTER_REGNUM
] = offset
;
1303 info_ptr
->regs
[STACK_REGS_FP
].size_1word
= UNITS_PER_WORD
;
1305 info_ptr
->save_p
[LR_REGNO
] = REG_SAVE_1WORD
;
1306 info_ptr
->reg_offset
[LR_REGNO
] = offset
+ 2*UNITS_PER_WORD
;
1307 info_ptr
->regs
[STACK_REGS_LR
].size_1word
= UNITS_PER_WORD
;
1309 if (cfun
->returns_struct
)
1311 info_ptr
->save_p
[FRV_STRUCT_VALUE_REGNUM
] = REG_SAVE_1WORD
;
1312 info_ptr
->reg_offset
[FRV_STRUCT_VALUE_REGNUM
] = offset
+ UNITS_PER_WORD
;
1313 info_ptr
->regs
[STACK_REGS_STRUCT
].size_1word
= UNITS_PER_WORD
;
1316 /* Calculate the offsets to store the arguments passed in registers
1317 for stdarg functions. The register pairs are first and the single
1318 register if any is last. The register save area starts on a
1320 if (info_ptr
->stdarg_size
)
1322 int first
= info_ptr
->regs
[STACK_REGS_STDARG
].first
;
1323 int last
= info_ptr
->regs
[STACK_REGS_STDARG
].last
;
1326 /* Skip the header. */
1327 offset
+= 4 * UNITS_PER_WORD
;
1328 for (regno
= first
; regno
<= last
; regno
++)
1330 if (info_ptr
->save_p
[regno
] == REG_SAVE_2WORDS
)
1332 info_ptr
->reg_offset
[regno
] = offset
;
1333 offset
+= 2 * UNITS_PER_WORD
;
1335 else if (info_ptr
->save_p
[regno
] == REG_SAVE_1WORD
)
1337 info_ptr
->reg_offset
[regno
] = offset
;
1338 offset
+= UNITS_PER_WORD
;
1344 if (reload_completed
)
1345 frv_stack_cache
= info_ptr
;
1351 /* Print the information about the frv stack offsets, etc. when debugging. */
1354 frv_debug_stack (frv_stack_t
*info
)
1359 info
= frv_stack_info ();
1361 fprintf (stderr
, "\nStack information for function %s:\n",
1362 ((current_function_decl
&& DECL_NAME (current_function_decl
))
1363 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl
))
1366 fprintf (stderr
, "\ttotal_size\t= %6d\n", info
->total_size
);
1367 fprintf (stderr
, "\tvars_size\t= %6d\n", info
->vars_size
);
1368 fprintf (stderr
, "\tparam_size\t= %6d\n", info
->parameter_size
);
1369 fprintf (stderr
, "\tregs_size\t= %6d, 1w = %3d, 2w = %3d\n",
1370 info
->regs_size
, info
->regs_size_1word
, info
->regs_size_2words
);
1372 fprintf (stderr
, "\theader_size\t= %6d\n", info
->header_size
);
1373 fprintf (stderr
, "\tpretend_size\t= %6d\n", info
->pretend_size
);
1374 fprintf (stderr
, "\tvars_offset\t= %6d\n", info
->vars_offset
);
1375 fprintf (stderr
, "\tregs_offset\t= %6d\n", info
->regs_offset
);
1377 for (range
= 0; range
< STACK_REGS_MAX
; range
++)
1379 frv_stack_regs_t
*regs
= &(info
->regs
[range
]);
1380 if ((regs
->size_1word
+ regs
->size_2words
) > 0)
1382 int first
= regs
->first
;
1383 int last
= regs
->last
;
1386 fprintf (stderr
, "\t%s\tsize\t= %6d, 1w = %3d, 2w = %3d, save =",
1387 regs
->name
, regs
->size_1word
+ regs
->size_2words
,
1388 regs
->size_1word
, regs
->size_2words
);
1390 for (regno
= first
; regno
<= last
; regno
++)
1392 if (info
->save_p
[regno
] == REG_SAVE_1WORD
)
1393 fprintf (stderr
, " %s (%d)", reg_names
[regno
],
1394 info
->reg_offset
[regno
]);
1396 else if (info
->save_p
[regno
] == REG_SAVE_2WORDS
)
1397 fprintf (stderr
, " %s-%s (%d)", reg_names
[regno
],
1398 reg_names
[regno
+1], info
->reg_offset
[regno
]);
1401 fputc ('\n', stderr
);
1411 /* Used during final to control the packing of insns. The value is
1412 1 if the current instruction should be packed with the next one,
1413 0 if it shouldn't or -1 if packing is disabled altogether. */
1415 static int frv_insn_packing_flag
;
1417 /* True if the current function contains a far jump. */
1420 frv_function_contains_far_jump (void)
1422 rtx_insn
*insn
= get_insns ();
1425 && get_attr_far_jump (insn
) == FAR_JUMP_YES
))
1426 insn
= NEXT_INSN (insn
);
1427 return (insn
!= NULL
);
1430 /* For the FRV, this function makes sure that a function with far jumps
1431 will return correctly. It also does the VLIW packing. */
1434 frv_function_prologue (FILE *file
, HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
1436 rtx_insn
*insn
, *next
, *last_call
;
1438 /* If no frame was created, check whether the function uses a call
1439 instruction to implement a far jump. If so, save the link in gr3 and
1440 replace all returns to LR with returns to GR3. GR3 is used because it
1441 is call-clobbered, because is not available to the register allocator,
1442 and because all functions that take a hidden argument pointer will have
1444 if (frv_stack_info ()->total_size
== 0 && frv_function_contains_far_jump ())
1448 /* Just to check that the above comment is true. */
1449 gcc_assert (!df_regs_ever_live_p (GPR_FIRST
+ 3));
1451 /* Generate the instruction that saves the link register. */
1452 fprintf (file
, "\tmovsg lr,gr3\n");
1454 /* Replace the LR with GR3 in *return_internal patterns. The insn
1455 will now return using jmpl @(gr3,0) rather than bralr. We cannot
1456 simply emit a different assembly directive because bralr and jmpl
1457 execute in different units. */
1458 for (insn
= get_insns(); insn
!= NULL
; insn
= NEXT_INSN (insn
))
1461 rtx pattern
= PATTERN (insn
);
1462 if (GET_CODE (pattern
) == PARALLEL
1463 && XVECLEN (pattern
, 0) >= 2
1464 && GET_CODE (XVECEXP (pattern
, 0, 0)) == RETURN
1465 && GET_CODE (XVECEXP (pattern
, 0, 1)) == USE
)
1467 rtx address
= XEXP (XVECEXP (pattern
, 0, 1), 0);
1468 if (GET_CODE (address
) == REG
&& REGNO (address
) == LR_REGNO
)
1469 SET_REGNO (address
, GPR_FIRST
+ 3);
1476 /* Allow the garbage collector to free the nops created by frv_reorg. */
1477 memset (frv_nops
, 0, sizeof (frv_nops
));
1479 /* Locate CALL_ARG_LOCATION notes that have been misplaced
1480 and move them back to where they should be located. */
1482 for (insn
= get_insns (); insn
; insn
= next
)
1484 next
= NEXT_INSN (insn
);
1486 || (INSN_P (insn
) && GET_CODE (PATTERN (insn
)) == SEQUENCE
1487 && CALL_P (XVECEXP (PATTERN (insn
), 0, 0))))
1490 if (!NOTE_P (insn
) || NOTE_KIND (insn
) != NOTE_INSN_CALL_ARG_LOCATION
)
1493 if (NEXT_INSN (last_call
) == insn
)
1496 SET_NEXT_INSN (PREV_INSN (insn
)) = NEXT_INSN (insn
);
1497 SET_PREV_INSN (NEXT_INSN (insn
)) = PREV_INSN (insn
);
1498 SET_PREV_INSN (insn
) = last_call
;
1499 SET_NEXT_INSN (insn
) = NEXT_INSN (last_call
);
1500 SET_PREV_INSN (NEXT_INSN (insn
)) = insn
;
1501 SET_NEXT_INSN (PREV_INSN (insn
)) = insn
;
1507 /* Return the next available temporary register in a given class. */
1510 frv_alloc_temp_reg (
1511 frv_tmp_reg_t
*info
, /* which registers are available */
1512 enum reg_class rclass
, /* register class desired */
1513 machine_mode mode
, /* mode to allocate register with */
1514 int mark_as_used
, /* register not available after allocation */
1515 int no_abort
) /* return NULL instead of aborting */
1517 int regno
= info
->next_reg
[ (int)rclass
];
1518 int orig_regno
= regno
;
1519 HARD_REG_SET
*reg_in_class
= ®_class_contents
[ (int)rclass
];
1524 if (TEST_HARD_REG_BIT (*reg_in_class
, regno
)
1525 && TEST_HARD_REG_BIT (info
->regs
, regno
))
1528 if (++regno
>= FIRST_PSEUDO_REGISTER
)
1530 if (regno
== orig_regno
)
1532 gcc_assert (no_abort
);
1537 nr
= HARD_REGNO_NREGS (regno
, mode
);
1538 info
->next_reg
[ (int)rclass
] = regno
+ nr
;
1541 for (i
= 0; i
< nr
; i
++)
1542 CLEAR_HARD_REG_BIT (info
->regs
, regno
+i
);
1544 return gen_rtx_REG (mode
, regno
);
1548 /* Return an rtx with the value OFFSET, which will either be a register or a
1549 signed 12-bit integer. It can be used as the second operand in an "add"
1550 instruction, or as the index in a load or store.
1552 The function returns a constant rtx if OFFSET is small enough, otherwise
1553 it loads the constant into register OFFSET_REGNO and returns that. */
1555 frv_frame_offset_rtx (int offset
)
1557 rtx offset_rtx
= GEN_INT (offset
);
1558 if (IN_RANGE (offset
, -2048, 2047))
1562 rtx reg_rtx
= gen_rtx_REG (SImode
, OFFSET_REGNO
);
1563 if (IN_RANGE (offset
, -32768, 32767))
1564 emit_insn (gen_movsi (reg_rtx
, offset_rtx
));
1567 emit_insn (gen_movsi_high (reg_rtx
, offset_rtx
));
1568 emit_insn (gen_movsi_lo_sum (reg_rtx
, offset_rtx
));
1574 /* Generate (mem:MODE (plus:Pmode BASE (frv_frame_offset OFFSET)))). The
1575 prologue and epilogue uses such expressions to access the stack. */
1577 frv_frame_mem (machine_mode mode
, rtx base
, int offset
)
1579 return gen_rtx_MEM (mode
, gen_rtx_PLUS (Pmode
,
1581 frv_frame_offset_rtx (offset
)));
1584 /* Generate a frame-related expression:
1586 (set REG (mem (plus (sp) (const_int OFFSET)))).
1588 Such expressions are used in FRAME_RELATED_EXPR notes for more complex
1589 instructions. Marking the expressions as frame-related is superfluous if
1590 the note contains just a single set. But if the note contains a PARALLEL
1591 or SEQUENCE that has several sets, each set must be individually marked
1592 as frame-related. */
1594 frv_dwarf_store (rtx reg
, int offset
)
1596 rtx set
= gen_rtx_SET (gen_rtx_MEM (GET_MODE (reg
),
1597 plus_constant (Pmode
, stack_pointer_rtx
,
1600 RTX_FRAME_RELATED_P (set
) = 1;
1604 /* Emit a frame-related instruction whose pattern is PATTERN. The
1605 instruction is the last in a sequence that cumulatively performs the
1606 operation described by DWARF_PATTERN. The instruction is marked as
1607 frame-related and has a REG_FRAME_RELATED_EXPR note containing
1610 frv_frame_insn (rtx pattern
, rtx dwarf_pattern
)
1612 rtx insn
= emit_insn (pattern
);
1613 RTX_FRAME_RELATED_P (insn
) = 1;
1614 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
1619 /* Emit instructions that transfer REG to or from the memory location (sp +
1620 STACK_OFFSET). The register is stored in memory if ACCESSOR->OP is
1621 FRV_STORE and loaded if it is FRV_LOAD. Only the prologue uses this
1622 function to store registers and only the epilogue uses it to load them.
1624 The caller sets up ACCESSOR so that BASE is equal to (sp + BASE_OFFSET).
1625 The generated instruction will use BASE as its base register. BASE may
1626 simply be the stack pointer, but if several accesses are being made to a
1627 region far away from the stack pointer, it may be more efficient to set
1628 up a temporary instead.
1630 Store instructions will be frame-related and will be annotated with the
1631 overall effect of the store. Load instructions will be followed by a
1632 (use) to prevent later optimizations from zapping them.
1634 The function takes care of the moves to and from SPRs, using TEMP_REGNO
1635 as a temporary in such cases. */
1637 frv_frame_access (frv_frame_accessor_t
*accessor
, rtx reg
, int stack_offset
)
1639 machine_mode mode
= GET_MODE (reg
);
1640 rtx mem
= frv_frame_mem (mode
,
1642 stack_offset
- accessor
->base_offset
);
1644 if (accessor
->op
== FRV_LOAD
)
1646 if (SPR_P (REGNO (reg
)))
1648 rtx temp
= gen_rtx_REG (mode
, TEMP_REGNO
);
1649 emit_insn (gen_rtx_SET (temp
, mem
));
1650 emit_insn (gen_rtx_SET (reg
, temp
));
1654 /* We cannot use reg+reg addressing for DImode access. */
1656 && GET_CODE (XEXP (mem
, 0)) == PLUS
1657 && GET_CODE (XEXP (XEXP (mem
, 0), 0)) == REG
1658 && GET_CODE (XEXP (XEXP (mem
, 0), 1)) == REG
)
1660 rtx temp
= gen_rtx_REG (SImode
, TEMP_REGNO
);
1662 emit_move_insn (temp
,
1663 gen_rtx_PLUS (SImode
, XEXP (XEXP (mem
, 0), 0),
1664 XEXP (XEXP (mem
, 0), 1)));
1665 mem
= gen_rtx_MEM (DImode
, temp
);
1667 emit_insn (gen_rtx_SET (reg
, mem
));
1673 if (SPR_P (REGNO (reg
)))
1675 rtx temp
= gen_rtx_REG (mode
, TEMP_REGNO
);
1676 emit_insn (gen_rtx_SET (temp
, reg
));
1677 frv_frame_insn (gen_rtx_SET (mem
, temp
),
1678 frv_dwarf_store (reg
, stack_offset
));
1680 else if (mode
== DImode
)
1682 /* For DImode saves, the dwarf2 version needs to be a SEQUENCE
1683 with a separate save for each register. */
1684 rtx reg1
= gen_rtx_REG (SImode
, REGNO (reg
));
1685 rtx reg2
= gen_rtx_REG (SImode
, REGNO (reg
) + 1);
1686 rtx set1
= frv_dwarf_store (reg1
, stack_offset
);
1687 rtx set2
= frv_dwarf_store (reg2
, stack_offset
+ 4);
1689 /* Also we cannot use reg+reg addressing. */
1690 if (GET_CODE (XEXP (mem
, 0)) == PLUS
1691 && GET_CODE (XEXP (XEXP (mem
, 0), 0)) == REG
1692 && GET_CODE (XEXP (XEXP (mem
, 0), 1)) == REG
)
1694 rtx temp
= gen_rtx_REG (SImode
, TEMP_REGNO
);
1695 emit_move_insn (temp
,
1696 gen_rtx_PLUS (SImode
, XEXP (XEXP (mem
, 0), 0),
1697 XEXP (XEXP (mem
, 0), 1)));
1698 mem
= gen_rtx_MEM (DImode
, temp
);
1701 frv_frame_insn (gen_rtx_SET (mem
, reg
),
1702 gen_rtx_PARALLEL (VOIDmode
,
1703 gen_rtvec (2, set1
, set2
)));
1706 frv_frame_insn (gen_rtx_SET (mem
, reg
),
1707 frv_dwarf_store (reg
, stack_offset
));
1711 /* A function that uses frv_frame_access to transfer a group of registers to
1712 or from the stack. ACCESSOR is passed directly to frv_frame_access, INFO
1713 is the stack information generated by frv_stack_info, and REG_SET is the
1714 number of the register set to transfer. */
1716 frv_frame_access_multi (frv_frame_accessor_t
*accessor
,
1720 frv_stack_regs_t
*regs_info
;
1723 regs_info
= &info
->regs
[reg_set
];
1724 for (regno
= regs_info
->first
; regno
<= regs_info
->last
; regno
++)
1725 if (info
->save_p
[regno
])
1726 frv_frame_access (accessor
,
1727 info
->save_p
[regno
] == REG_SAVE_2WORDS
1728 ? gen_rtx_REG (DImode
, regno
)
1729 : gen_rtx_REG (SImode
, regno
),
1730 info
->reg_offset
[regno
]);
1733 /* Save or restore callee-saved registers that are kept outside the frame
1734 header. The function saves the registers if OP is FRV_STORE and restores
1735 them if OP is FRV_LOAD. INFO is the stack information generated by
1738 frv_frame_access_standard_regs (enum frv_stack_op op
, frv_stack_t
*info
)
1740 frv_frame_accessor_t accessor
;
1743 accessor
.base
= stack_pointer_rtx
;
1744 accessor
.base_offset
= 0;
1745 frv_frame_access_multi (&accessor
, info
, STACK_REGS_GPR
);
1746 frv_frame_access_multi (&accessor
, info
, STACK_REGS_FPR
);
1747 frv_frame_access_multi (&accessor
, info
, STACK_REGS_LCR
);
1751 /* Called after register allocation to add any instructions needed for the
1752 prologue. Using a prologue insn is favored compared to putting all of the
1753 instructions in the TARGET_ASM_FUNCTION_PROLOGUE target hook, since
1754 it allows the scheduler to intermix instructions with the saves of
1755 the caller saved registers. In some cases, it might be necessary
1756 to emit a barrier instruction as the last insn to prevent such
1759 Also any insns generated here should have RTX_FRAME_RELATED_P(insn) = 1
1760 so that the debug info generation code can handle them properly. */
1762 frv_expand_prologue (void)
1764 frv_stack_t
*info
= frv_stack_info ();
1765 rtx sp
= stack_pointer_rtx
;
1766 rtx fp
= frame_pointer_rtx
;
1767 frv_frame_accessor_t accessor
;
1769 if (TARGET_DEBUG_STACK
)
1770 frv_debug_stack (info
);
1772 if (flag_stack_usage_info
)
1773 current_function_static_stack_size
= info
->total_size
;
1775 if (info
->total_size
== 0)
1778 /* We're interested in three areas of the frame here:
1780 A: the register save area
1782 C: the header after B
1784 If the frame pointer isn't used, we'll have to set up A, B and C
1785 using the stack pointer. If the frame pointer is used, we'll access
1789 B: set up using sp or a temporary (see below)
1792 We set up B using the stack pointer if the frame is small enough.
1793 Otherwise, it's more efficient to copy the old stack pointer into a
1794 temporary and use that.
1796 Note that it's important to make sure the prologue and epilogue use the
1797 same registers to access A and C, since doing otherwise will confuse
1798 the aliasing code. */
1800 /* Set up ACCESSOR for accessing region B above. If the frame pointer
1801 isn't used, the same method will serve for C. */
1802 accessor
.op
= FRV_STORE
;
1803 if (frame_pointer_needed
&& info
->total_size
> 2048)
1805 accessor
.base
= gen_rtx_REG (Pmode
, OLD_SP_REGNO
);
1806 accessor
.base_offset
= info
->total_size
;
1807 emit_insn (gen_movsi (accessor
.base
, sp
));
1811 accessor
.base
= stack_pointer_rtx
;
1812 accessor
.base_offset
= 0;
1815 /* Allocate the stack space. */
1817 rtx asm_offset
= frv_frame_offset_rtx (-info
->total_size
);
1818 rtx dwarf_offset
= GEN_INT (-info
->total_size
);
1820 frv_frame_insn (gen_stack_adjust (sp
, sp
, asm_offset
),
1821 gen_rtx_SET (sp
, gen_rtx_PLUS (Pmode
, sp
, dwarf_offset
)));
1824 /* If the frame pointer is needed, store the old one at (sp + FP_OFFSET)
1825 and point the new one to that location. */
1826 if (frame_pointer_needed
)
1828 int fp_offset
= info
->reg_offset
[FRAME_POINTER_REGNUM
];
1830 /* ASM_SRC and DWARF_SRC both point to the frame header. ASM_SRC is
1831 based on ACCESSOR.BASE but DWARF_SRC is always based on the stack
1833 rtx asm_src
= plus_constant (Pmode
, accessor
.base
,
1834 fp_offset
- accessor
.base_offset
);
1835 rtx dwarf_src
= plus_constant (Pmode
, sp
, fp_offset
);
1837 /* Store the old frame pointer at (sp + FP_OFFSET). */
1838 frv_frame_access (&accessor
, fp
, fp_offset
);
1840 /* Set up the new frame pointer. */
1841 frv_frame_insn (gen_rtx_SET (fp
, asm_src
),
1842 gen_rtx_SET (fp
, dwarf_src
));
1844 /* Access region C from the frame pointer. */
1846 accessor
.base_offset
= fp_offset
;
1849 /* Set up region C. */
1850 frv_frame_access_multi (&accessor
, info
, STACK_REGS_STRUCT
);
1851 frv_frame_access_multi (&accessor
, info
, STACK_REGS_LR
);
1852 frv_frame_access_multi (&accessor
, info
, STACK_REGS_STDARG
);
1854 /* Set up region A. */
1855 frv_frame_access_standard_regs (FRV_STORE
, info
);
1857 /* If this is a varargs/stdarg function, issue a blockage to prevent the
1858 scheduler from moving loads before the stores saving the registers. */
1859 if (info
->stdarg_size
> 0)
1860 emit_insn (gen_blockage ());
1862 /* Set up pic register/small data register for this function. */
1863 if (!TARGET_FDPIC
&& flag_pic
&& crtl
->uses_pic_offset_table
)
1864 emit_insn (gen_pic_prologue (gen_rtx_REG (Pmode
, PIC_REGNO
),
1865 gen_rtx_REG (Pmode
, LR_REGNO
),
1866 gen_rtx_REG (SImode
, OFFSET_REGNO
)));
1870 /* Under frv, all of the work is done via frv_expand_epilogue, but
1871 this function provides a convenient place to do cleanup. */
1874 frv_function_epilogue (FILE *file ATTRIBUTE_UNUSED
,
1875 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
1877 frv_stack_cache
= (frv_stack_t
*)0;
1879 /* Zap last used registers for conditional execution. */
1880 memset (&frv_ifcvt
.tmp_reg
, 0, sizeof (frv_ifcvt
.tmp_reg
));
1882 /* Release the bitmap of created insns. */
1883 BITMAP_FREE (frv_ifcvt
.scratch_insns_bitmap
);
1887 /* Called after register allocation to add any instructions needed for the
1888 epilogue. Using an epilogue insn is favored compared to putting all of the
1889 instructions in the TARGET_ASM_FUNCTION_PROLOGUE target hook, since
1890 it allows the scheduler to intermix instructions with the saves of
1891 the caller saved registers. In some cases, it might be necessary
1892 to emit a barrier instruction as the last insn to prevent such
1896 frv_expand_epilogue (bool emit_return
)
1898 frv_stack_t
*info
= frv_stack_info ();
1899 rtx fp
= frame_pointer_rtx
;
1900 rtx sp
= stack_pointer_rtx
;
1904 fp_offset
= info
->reg_offset
[FRAME_POINTER_REGNUM
];
1906 /* Restore the stack pointer to its original value if alloca or the like
1908 if (! crtl
->sp_is_unchanging
)
1909 emit_insn (gen_addsi3 (sp
, fp
, frv_frame_offset_rtx (-fp_offset
)));
1911 /* Restore the callee-saved registers that were used in this function. */
1912 frv_frame_access_standard_regs (FRV_LOAD
, info
);
1914 /* Set RETURN_ADDR to the address we should return to. Set it to NULL if
1915 no return instruction should be emitted. */
1916 if (info
->save_p
[LR_REGNO
])
1921 /* Use the same method to access the link register's slot as we did in
1922 the prologue. In other words, use the frame pointer if available,
1923 otherwise use the stack pointer.
1925 LR_OFFSET is the offset of the link register's slot from the start
1926 of the frame and MEM is a memory rtx for it. */
1927 lr_offset
= info
->reg_offset
[LR_REGNO
];
1928 if (frame_pointer_needed
)
1929 mem
= frv_frame_mem (Pmode
, fp
, lr_offset
- fp_offset
);
1931 mem
= frv_frame_mem (Pmode
, sp
, lr_offset
);
1933 /* Load the old link register into a GPR. */
1934 return_addr
= gen_rtx_REG (Pmode
, TEMP_REGNO
);
1935 emit_insn (gen_rtx_SET (return_addr
, mem
));
1938 return_addr
= gen_rtx_REG (Pmode
, LR_REGNO
);
1940 /* Restore the old frame pointer. Emit a USE afterwards to make sure
1941 the load is preserved. */
1942 if (frame_pointer_needed
)
1944 emit_insn (gen_rtx_SET (fp
, gen_rtx_MEM (Pmode
, fp
)));
1948 /* Deallocate the stack frame. */
1949 if (info
->total_size
!= 0)
1951 rtx offset
= frv_frame_offset_rtx (info
->total_size
);
1952 emit_insn (gen_stack_adjust (sp
, sp
, offset
));
1955 /* If this function uses eh_return, add the final stack adjustment now. */
1956 if (crtl
->calls_eh_return
)
1957 emit_insn (gen_stack_adjust (sp
, sp
, EH_RETURN_STACKADJ_RTX
));
1960 emit_jump_insn (gen_epilogue_return (return_addr
));
1963 rtx lr
= return_addr
;
1965 if (REGNO (return_addr
) != LR_REGNO
)
1967 lr
= gen_rtx_REG (Pmode
, LR_REGNO
);
1968 emit_move_insn (lr
, return_addr
);
1976 /* Worker function for TARGET_ASM_OUTPUT_MI_THUNK. */
1979 frv_asm_output_mi_thunk (FILE *file
,
1980 tree thunk_fndecl ATTRIBUTE_UNUSED
,
1981 HOST_WIDE_INT delta
,
1982 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED
,
1985 const char *name_func
= XSTR (XEXP (DECL_RTL (function
), 0), 0);
1986 const char *name_arg0
= reg_names
[FIRST_ARG_REGNUM
];
1987 const char *name_jmp
= reg_names
[JUMP_REGNO
];
1988 const char *parallel
= (frv_issue_rate () > 1 ? ".p" : "");
1990 /* Do the add using an addi if possible. */
1991 if (IN_RANGE (delta
, -2048, 2047))
1992 fprintf (file
, "\taddi %s,#%d,%s\n", name_arg0
, (int) delta
, name_arg0
);
1995 const char *const name_add
= reg_names
[TEMP_REGNO
];
1996 fprintf (file
, "\tsethi%s #hi(" HOST_WIDE_INT_PRINT_DEC
"),%s\n",
1997 parallel
, delta
, name_add
);
1998 fprintf (file
, "\tsetlo #lo(" HOST_WIDE_INT_PRINT_DEC
"),%s\n",
2000 fprintf (file
, "\tadd %s,%s,%s\n", name_add
, name_arg0
, name_arg0
);
2005 const char *name_pic
= reg_names
[FDPIC_REGNO
];
2006 name_jmp
= reg_names
[FDPIC_FPTR_REGNO
];
2010 fprintf (file
, "\tsethi%s #gotofffuncdeschi(", parallel
);
2011 assemble_name (file
, name_func
);
2012 fprintf (file
, "),%s\n", name_jmp
);
2014 fprintf (file
, "\tsetlo #gotofffuncdesclo(");
2015 assemble_name (file
, name_func
);
2016 fprintf (file
, "),%s\n", name_jmp
);
2018 fprintf (file
, "\tldd @(%s,%s), %s\n", name_jmp
, name_pic
, name_jmp
);
2022 fprintf (file
, "\tlddo @(%s,#gotofffuncdesc12(", name_pic
);
2023 assemble_name (file
, name_func
);
2024 fprintf (file
, "\t)), %s\n", name_jmp
);
2029 fprintf (file
, "\tsethi%s #hi(", parallel
);
2030 assemble_name (file
, name_func
);
2031 fprintf (file
, "),%s\n", name_jmp
);
2033 fprintf (file
, "\tsetlo #lo(");
2034 assemble_name (file
, name_func
);
2035 fprintf (file
, "),%s\n", name_jmp
);
2039 /* Use JUMP_REGNO as a temporary PIC register. */
2040 const char *name_lr
= reg_names
[LR_REGNO
];
2041 const char *name_gppic
= name_jmp
;
2042 const char *name_tmp
= reg_names
[TEMP_REGNO
];
2044 fprintf (file
, "\tmovsg %s,%s\n", name_lr
, name_tmp
);
2045 fprintf (file
, "\tcall 1f\n");
2046 fprintf (file
, "1:\tmovsg %s,%s\n", name_lr
, name_gppic
);
2047 fprintf (file
, "\tmovgs %s,%s\n", name_tmp
, name_lr
);
2048 fprintf (file
, "\tsethi%s #gprelhi(1b),%s\n", parallel
, name_tmp
);
2049 fprintf (file
, "\tsetlo #gprello(1b),%s\n", name_tmp
);
2050 fprintf (file
, "\tsub %s,%s,%s\n", name_gppic
, name_tmp
, name_gppic
);
2052 fprintf (file
, "\tsethi%s #gprelhi(", parallel
);
2053 assemble_name (file
, name_func
);
2054 fprintf (file
, "),%s\n", name_tmp
);
2056 fprintf (file
, "\tsetlo #gprello(");
2057 assemble_name (file
, name_func
);
2058 fprintf (file
, "),%s\n", name_tmp
);
2060 fprintf (file
, "\tadd %s,%s,%s\n", name_gppic
, name_tmp
, name_jmp
);
2063 /* Jump to the function address. */
2064 fprintf (file
, "\tjmpl @(%s,%s)\n", name_jmp
, reg_names
[GPR_FIRST
+0]);
2069 /* On frv, create a frame whenever we need to create stack. */
2072 frv_frame_pointer_required (void)
2074 /* If we forgoing the usual linkage requirements, we only need
2075 a frame pointer if the stack pointer might change. */
2076 if (!TARGET_LINKED_FP
)
2077 return !crtl
->sp_is_unchanging
;
2079 if (! crtl
->is_leaf
)
2082 if (get_frame_size () != 0)
2088 if (!crtl
->sp_is_unchanging
)
2091 if (!TARGET_FDPIC
&& flag_pic
&& crtl
->uses_pic_offset_table
)
2097 if (cfun
->machine
->frame_needed
)
2104 /* Worker function for TARGET_CAN_ELIMINATE. */
2107 frv_can_eliminate (const int from
, const int to
)
2109 return (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
2110 ? ! frame_pointer_needed
2114 /* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'. It specifies the
2115 initial difference between the specified pair of registers. This macro must
2116 be defined if `ELIMINABLE_REGS' is defined. */
2118 /* See frv_stack_info for more details on the frv stack frame. */
2121 frv_initial_elimination_offset (int from
, int to
)
2123 frv_stack_t
*info
= frv_stack_info ();
2126 if (to
== STACK_POINTER_REGNUM
&& from
== ARG_POINTER_REGNUM
)
2127 ret
= info
->total_size
- info
->pretend_size
;
2129 else if (to
== STACK_POINTER_REGNUM
&& from
== FRAME_POINTER_REGNUM
)
2130 ret
= info
->reg_offset
[FRAME_POINTER_REGNUM
];
2132 else if (to
== FRAME_POINTER_REGNUM
&& from
== ARG_POINTER_REGNUM
)
2133 ret
= (info
->total_size
2134 - info
->reg_offset
[FRAME_POINTER_REGNUM
]
2135 - info
->pretend_size
);
2140 if (TARGET_DEBUG_STACK
)
2141 fprintf (stderr
, "Eliminate %s to %s by adding %d\n",
2142 reg_names
[from
], reg_names
[to
], ret
);
2148 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
2151 frv_setup_incoming_varargs (cumulative_args_t cum_v
,
2153 tree type ATTRIBUTE_UNUSED
,
2157 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
2159 if (TARGET_DEBUG_ARG
)
2161 "setup_vararg: words = %2d, mode = %4s, pretend_size = %d, second_time = %d\n",
2162 *cum
, GET_MODE_NAME (mode
), *pretend_size
, second_time
);
2166 /* Worker function for TARGET_EXPAND_BUILTIN_SAVEREGS. */
2169 frv_expand_builtin_saveregs (void)
2171 int offset
= UNITS_PER_WORD
* FRV_NUM_ARG_REGS
;
2173 if (TARGET_DEBUG_ARG
)
2174 fprintf (stderr
, "expand_builtin_saveregs: offset from ap = %d\n",
2177 return gen_rtx_PLUS (Pmode
, virtual_incoming_args_rtx
, GEN_INT (- offset
));
2181 /* Expand __builtin_va_start to do the va_start macro. */
2184 frv_expand_builtin_va_start (tree valist
, rtx nextarg
)
2187 int num
= crtl
->args
.info
- FIRST_ARG_REGNUM
- FRV_NUM_ARG_REGS
;
2189 nextarg
= gen_rtx_PLUS (Pmode
, virtual_incoming_args_rtx
,
2190 GEN_INT (UNITS_PER_WORD
* num
));
2192 if (TARGET_DEBUG_ARG
)
2194 fprintf (stderr
, "va_start: args_info = %d, num = %d\n",
2195 crtl
->args
.info
, num
);
2197 debug_rtx (nextarg
);
2200 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist
,
2201 fold_convert (TREE_TYPE (valist
),
2202 make_tree (sizetype
, nextarg
)));
2203 TREE_SIDE_EFFECTS (t
) = 1;
2205 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2209 /* Expand a block move operation, and return 1 if successful. Return 0
2210 if we should let the compiler generate normal code.
2212 operands[0] is the destination
2213 operands[1] is the source
2214 operands[2] is the length
2215 operands[3] is the alignment */
2217 /* Maximum number of loads to do before doing the stores */
2218 #ifndef MAX_MOVE_REG
2219 #define MAX_MOVE_REG 4
2222 /* Maximum number of total loads to do. */
2223 #ifndef TOTAL_MOVE_REG
2224 #define TOTAL_MOVE_REG 8
2228 frv_expand_block_move (rtx operands
[])
2230 rtx orig_dest
= operands
[0];
2231 rtx orig_src
= operands
[1];
2232 rtx bytes_rtx
= operands
[2];
2233 rtx align_rtx
= operands
[3];
2234 int constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
2247 rtx stores
[MAX_MOVE_REG
];
2251 /* If this is not a fixed size move, just call memcpy. */
2255 /* This should be a fixed size alignment. */
2256 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
2258 align
= INTVAL (align_rtx
);
2260 /* Anything to move? */
2261 bytes
= INTVAL (bytes_rtx
);
2265 /* Don't support real large moves. */
2266 if (bytes
> TOTAL_MOVE_REG
*align
)
2269 /* Move the address into scratch registers. */
2270 dest_reg
= copy_addr_to_reg (XEXP (orig_dest
, 0));
2271 src_reg
= copy_addr_to_reg (XEXP (orig_src
, 0));
2273 num_reg
= offset
= 0;
2274 for ( ; bytes
> 0; (bytes
-= move_bytes
), (offset
+= move_bytes
))
2276 /* Calculate the correct offset for src/dest. */
2280 dest_addr
= dest_reg
;
2284 src_addr
= plus_constant (Pmode
, src_reg
, offset
);
2285 dest_addr
= plus_constant (Pmode
, dest_reg
, offset
);
2288 /* Generate the appropriate load and store, saving the stores
2290 if (bytes
>= 4 && align
>= 4)
2292 else if (bytes
>= 2 && align
>= 2)
2297 move_bytes
= GET_MODE_SIZE (mode
);
2298 tmp_reg
= gen_reg_rtx (mode
);
2299 src_mem
= change_address (orig_src
, mode
, src_addr
);
2300 dest_mem
= change_address (orig_dest
, mode
, dest_addr
);
2301 emit_insn (gen_rtx_SET (tmp_reg
, src_mem
));
2302 stores
[num_reg
++] = gen_rtx_SET (dest_mem
, tmp_reg
);
2304 if (num_reg
>= MAX_MOVE_REG
)
2306 for (i
= 0; i
< num_reg
; i
++)
2307 emit_insn (stores
[i
]);
2312 for (i
= 0; i
< num_reg
; i
++)
2313 emit_insn (stores
[i
]);
2319 /* Expand a block clear operation, and return 1 if successful. Return 0
2320 if we should let the compiler generate normal code.
2322 operands[0] is the destination
2323 operands[1] is the length
2324 operands[3] is the alignment */
2327 frv_expand_block_clear (rtx operands
[])
2329 rtx orig_dest
= operands
[0];
2330 rtx bytes_rtx
= operands
[1];
2331 rtx align_rtx
= operands
[3];
2332 int constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
2342 /* If this is not a fixed size move, just call memcpy. */
2346 /* This should be a fixed size alignment. */
2347 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
2349 align
= INTVAL (align_rtx
);
2351 /* Anything to move? */
2352 bytes
= INTVAL (bytes_rtx
);
2356 /* Don't support real large clears. */
2357 if (bytes
> TOTAL_MOVE_REG
*align
)
2360 /* Move the address into a scratch register. */
2361 dest_reg
= copy_addr_to_reg (XEXP (orig_dest
, 0));
2364 for ( ; bytes
> 0; (bytes
-= clear_bytes
), (offset
+= clear_bytes
))
2366 /* Calculate the correct offset for src/dest. */
2367 dest_addr
= ((offset
== 0)
2369 : plus_constant (Pmode
, dest_reg
, offset
));
2371 /* Generate the appropriate store of gr0. */
2372 if (bytes
>= 4 && align
>= 4)
2374 else if (bytes
>= 2 && align
>= 2)
2379 clear_bytes
= GET_MODE_SIZE (mode
);
2380 dest_mem
= change_address (orig_dest
, mode
, dest_addr
);
2381 emit_insn (gen_rtx_SET (dest_mem
, const0_rtx
));
2388 /* The following variable is used to output modifiers of assembler
2389 code of the current output insn. */
2391 static rtx
*frv_insn_operands
;
2393 /* The following function is used to add assembler insn code suffix .p
2394 if it is necessary. */
2397 frv_asm_output_opcode (FILE *f
, const char *ptr
)
2401 if (frv_insn_packing_flag
<= 0)
2404 for (; *ptr
&& *ptr
!= ' ' && *ptr
!= '\t';)
2407 if (c
== '%' && ((*ptr
>= 'a' && *ptr
<= 'z')
2408 || (*ptr
>= 'A' && *ptr
<= 'Z')))
2410 int letter
= *ptr
++;
2413 frv_print_operand (f
, frv_insn_operands
[c
], letter
);
2414 while ((c
= *ptr
) >= '0' && c
<= '9')
2426 /* Set up the packing bit for the current output insn. Note that this
2427 function is not called for asm insns. */
2430 frv_final_prescan_insn (rtx_insn
*insn
, rtx
*opvec
,
2431 int noperands ATTRIBUTE_UNUSED
)
2435 if (frv_insn_packing_flag
>= 0)
2437 frv_insn_operands
= opvec
;
2438 frv_insn_packing_flag
= PACKING_FLAG_P (insn
);
2440 else if (recog_memoized (insn
) >= 0
2441 && get_attr_acc_group (insn
) == ACC_GROUP_ODD
)
2442 /* Packing optimizations have been disabled, but INSN can only
2443 be issued in M1. Insert an mnop in M0. */
2444 fprintf (asm_out_file
, "\tmnop.p\n");
2450 /* A C expression whose value is RTL representing the address in a stack frame
2451 where the pointer to the caller's frame is stored. Assume that FRAMEADDR is
2452 an RTL expression for the address of the stack frame itself.
2454 If you don't define this macro, the default is to return the value of
2455 FRAMEADDR--that is, the stack frame address is also the address of the stack
2456 word that points to the previous frame. */
2458 /* The default is correct, but we need to make sure the frame gets created. */
2460 frv_dynamic_chain_address (rtx frame
)
2462 cfun
->machine
->frame_needed
= 1;
2467 /* A C expression whose value is RTL representing the value of the return
2468 address for the frame COUNT steps up from the current frame, after the
2469 prologue. FRAMEADDR is the frame pointer of the COUNT frame, or the frame
2470 pointer of the COUNT - 1 frame if `RETURN_ADDR_IN_PREVIOUS_FRAME' is
2473 The value of the expression must always be the correct address when COUNT is
2474 zero, but may be `NULL_RTX' if there is not way to determine the return
2475 address of other frames. */
2478 frv_return_addr_rtx (int count
, rtx frame
)
2482 cfun
->machine
->frame_needed
= 1;
2483 return gen_rtx_MEM (Pmode
, plus_constant (Pmode
, frame
, 8));
2486 /* Given a memory reference MEMREF, interpret the referenced memory as
2487 an array of MODE values, and return a reference to the element
2488 specified by INDEX. Assume that any pre-modification implicit in
2489 MEMREF has already happened.
2491 MEMREF must be a legitimate operand for modes larger than SImode.
2492 frv_legitimate_address_p forbids register+register addresses, which
2493 this function cannot handle. */
2495 frv_index_memory (rtx memref
, machine_mode mode
, int index
)
2497 rtx base
= XEXP (memref
, 0);
2498 if (GET_CODE (base
) == PRE_MODIFY
)
2499 base
= XEXP (base
, 0);
2500 return change_address (memref
, mode
,
2501 plus_constant (Pmode
, base
,
2502 index
* GET_MODE_SIZE (mode
)));
2506 /* Print a memory address as an operand to reference that memory location. */
2508 frv_print_operand_address (FILE * stream
, rtx x
)
2510 if (GET_CODE (x
) == MEM
)
2513 switch (GET_CODE (x
))
2516 fputs (reg_names
[ REGNO (x
)], stream
);
2520 fprintf (stream
, "%ld", (long) INTVAL (x
));
2524 assemble_name (stream
, XSTR (x
, 0));
2529 output_addr_const (stream
, x
);
2533 /* Poorly constructed asm statements can trigger this alternative.
2534 See gcc/testsuite/gcc.dg/asm-4.c for an example. */
2535 frv_print_operand_memory_reference (stream
, x
, 0);
2542 fatal_insn ("bad insn to frv_print_operand_address:", x
);
2547 frv_print_operand_memory_reference_reg (FILE * stream
, rtx x
)
2549 int regno
= true_regnum (x
);
2551 fputs (reg_names
[regno
], stream
);
2553 fatal_insn ("bad register to frv_print_operand_memory_reference_reg:", x
);
2556 /* Print a memory reference suitable for the ld/st instructions. */
2559 frv_print_operand_memory_reference (FILE * stream
, rtx x
, int addr_offset
)
2561 struct frv_unspec unspec
;
2565 switch (GET_CODE (x
))
2572 case PRE_MODIFY
: /* (pre_modify (reg) (plus (reg) (reg))) */
2574 x1
= XEXP (XEXP (x
, 1), 1);
2584 if (GET_CODE (x0
) == CONST_INT
)
2592 fatal_insn ("bad insn to frv_print_operand_memory_reference:", x
);
2601 else if (GET_CODE (x1
) != CONST_INT
)
2602 fatal_insn ("bad insn to frv_print_operand_memory_reference:", x
);
2605 fputs ("@(", stream
);
2607 fputs (reg_names
[GPR_R0
], stream
);
2608 else if (GET_CODE (x0
) == REG
|| GET_CODE (x0
) == SUBREG
)
2609 frv_print_operand_memory_reference_reg (stream
, x0
);
2611 fatal_insn ("bad insn to frv_print_operand_memory_reference:", x
);
2613 fputs (",", stream
);
2615 fputs (reg_names
[GPR_R0
], stream
);
2619 switch (GET_CODE (x1
))
2623 frv_print_operand_memory_reference_reg (stream
, x1
);
2627 fprintf (stream
, "%ld", (long) (INTVAL (x1
) + addr_offset
));
2631 if (!frv_const_unspec_p (x1
, &unspec
))
2632 fatal_insn ("bad insn to frv_print_operand_memory_reference:", x1
);
2633 frv_output_const_unspec (stream
, &unspec
);
2637 fatal_insn ("bad insn to frv_print_operand_memory_reference:", x
);
2641 fputs (")", stream
);
2645 /* Return 2 for likely branches and 0 for non-likely branches */
2647 #define FRV_JUMP_LIKELY 2
2648 #define FRV_JUMP_NOT_LIKELY 0
2651 frv_print_operand_jump_hint (rtx_insn
*insn
)
2657 enum { UNKNOWN
, BACKWARD
, FORWARD
} jump_type
= UNKNOWN
;
2659 gcc_assert (JUMP_P (insn
));
2661 /* Assume any non-conditional jump is likely. */
2662 if (! any_condjump_p (insn
))
2663 ret
= FRV_JUMP_LIKELY
;
2667 labelref
= condjump_label (insn
);
2670 rtx label
= XEXP (labelref
, 0);
2671 jump_type
= (insn_current_address
> INSN_ADDRESSES (INSN_UID (label
))
2676 note
= find_reg_note (insn
, REG_BR_PROB
, 0);
2678 ret
= ((jump_type
== BACKWARD
) ? FRV_JUMP_LIKELY
: FRV_JUMP_NOT_LIKELY
);
2682 prob
= XINT (note
, 0);
2683 ret
= ((prob
>= (REG_BR_PROB_BASE
/ 2))
2685 : FRV_JUMP_NOT_LIKELY
);
2697 case UNKNOWN
: direction
= "unknown jump direction"; break;
2698 case BACKWARD
: direction
= "jump backward"; break;
2699 case FORWARD
: direction
= "jump forward"; break;
2703 "%s: uid %ld, %s, probability = %d, max prob. = %d, hint = %d\n",
2704 IDENTIFIER_POINTER (DECL_NAME (current_function_decl
)),
2705 (long)INSN_UID (insn
), direction
, prob
,
2706 REG_BR_PROB_BASE
, ret
);
2714 /* Return the comparison operator to use for CODE given that the ICC
2718 comparison_string (enum rtx_code code
, rtx op0
)
2720 bool is_nz_p
= GET_MODE (op0
) == CC_NZmode
;
2723 default: output_operand_lossage ("bad condition code");
2724 case EQ
: return "eq";
2725 case NE
: return "ne";
2726 case LT
: return is_nz_p
? "n" : "lt";
2727 case LE
: return "le";
2728 case GT
: return "gt";
2729 case GE
: return is_nz_p
? "p" : "ge";
2730 case LTU
: return is_nz_p
? "no" : "c";
2731 case LEU
: return is_nz_p
? "eq" : "ls";
2732 case GTU
: return is_nz_p
? "ne" : "hi";
2733 case GEU
: return is_nz_p
? "ra" : "nc";
2737 /* Print an operand to an assembler instruction.
2739 `%' followed by a letter and a digit says to output an operand in an
2740 alternate fashion. Four letters have standard, built-in meanings
2741 described below. The hook `TARGET_PRINT_OPERAND' can define
2742 additional letters with nonstandard meanings.
2744 `%cDIGIT' can be used to substitute an operand that is a constant value
2745 without the syntax that normally indicates an immediate operand.
2747 `%nDIGIT' is like `%cDIGIT' except that the value of the constant is negated
2750 `%aDIGIT' can be used to substitute an operand as if it were a memory
2751 reference, with the actual operand treated as the address. This may be
2752 useful when outputting a "load address" instruction, because often the
2753 assembler syntax for such an instruction requires you to write the operand
2754 as if it were a memory reference.
2756 `%lDIGIT' is used to substitute a `label_ref' into a jump instruction.
2758 `%=' outputs a number which is unique to each instruction in the entire
2759 compilation. This is useful for making local labels to be referred to more
2760 than once in a single template that generates multiple assembler
2763 `%' followed by a punctuation character specifies a substitution that
2764 does not use an operand. Only one case is standard: `%%' outputs a
2765 `%' into the assembler code. Other nonstandard cases can be defined
2766 in the `TARGET_PRINT_OPERAND' hook. You must also define which
2767 punctuation characters are valid with the
2768 `TARGET_PRINT_OPERAND_PUNCT_VALID_P' hook. */
2771 frv_print_operand (FILE * file
, rtx x
, int code
)
2773 struct frv_unspec unspec
;
2774 HOST_WIDE_INT value
;
2777 if (code
!= 0 && !ISALPHA (code
))
2780 else if (GET_CODE (x
) == CONST_INT
)
2783 else if (GET_CODE (x
) == CONST_DOUBLE
)
2785 if (GET_MODE (x
) == SFmode
)
2790 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
2791 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
2795 else if (GET_MODE (x
) == VOIDmode
)
2796 value
= CONST_DOUBLE_LOW (x
);
2799 fatal_insn ("bad insn in frv_print_operand, bad const_double", x
);
2810 fputs (reg_names
[GPR_R0
], file
);
2814 fprintf (file
, "%d", frv_print_operand_jump_hint (current_output_insn
));
2818 /* Output small data area base register (gr16). */
2819 fputs (reg_names
[SDA_BASE_REG
], file
);
2823 /* Output pic register (gr17). */
2824 fputs (reg_names
[PIC_REGNO
], file
);
2828 /* Output the temporary integer CCR register. */
2829 fputs (reg_names
[ICR_TEMP
], file
);
2833 /* Output the temporary integer CC register. */
2834 fputs (reg_names
[ICC_TEMP
], file
);
2837 /* case 'a': print an address. */
2840 /* Print appropriate test for integer branch false operation. */
2841 fputs (comparison_string (reverse_condition (GET_CODE (x
)),
2842 XEXP (x
, 0)), file
);
2846 /* Print appropriate test for integer branch true operation. */
2847 fputs (comparison_string (GET_CODE (x
), XEXP (x
, 0)), file
);
2851 /* Print 1 for a NE and 0 for an EQ to give the final argument
2852 for a conditional instruction. */
2853 if (GET_CODE (x
) == NE
)
2856 else if (GET_CODE (x
) == EQ
)
2860 fatal_insn ("bad insn to frv_print_operand, 'e' modifier:", x
);
2864 /* Print appropriate test for floating point branch false operation. */
2865 switch (GET_CODE (x
))
2868 fatal_insn ("bad insn to frv_print_operand, 'F' modifier:", x
);
2870 case EQ
: fputs ("ne", file
); break;
2871 case NE
: fputs ("eq", file
); break;
2872 case LT
: fputs ("uge", file
); break;
2873 case LE
: fputs ("ug", file
); break;
2874 case GT
: fputs ("ule", file
); break;
2875 case GE
: fputs ("ul", file
); break;
2880 /* Print appropriate test for floating point branch true operation. */
2881 switch (GET_CODE (x
))
2884 fatal_insn ("bad insn to frv_print_operand, 'f' modifier:", x
);
2886 case EQ
: fputs ("eq", file
); break;
2887 case NE
: fputs ("ne", file
); break;
2888 case LT
: fputs ("lt", file
); break;
2889 case LE
: fputs ("le", file
); break;
2890 case GT
: fputs ("gt", file
); break;
2891 case GE
: fputs ("ge", file
); break;
2896 /* Print appropriate GOT function. */
2897 if (GET_CODE (x
) != CONST_INT
)
2898 fatal_insn ("bad insn to frv_print_operand, 'g' modifier:", x
);
2899 fputs (unspec_got_name (INTVAL (x
)), file
);
2903 /* Print 'i' if the operand is a constant, or is a memory reference that
2905 if (GET_CODE (x
) == MEM
)
2906 x
= ((GET_CODE (XEXP (x
, 0)) == PLUS
)
2907 ? XEXP (XEXP (x
, 0), 1)
2909 else if (GET_CODE (x
) == PLUS
)
2912 switch (GET_CODE (x
))
2926 /* For jump instructions, print 'i' if the operand is a constant or
2927 is an expression that adds a constant. */
2928 if (GET_CODE (x
) == CONST_INT
)
2933 if (GET_CODE (x
) == CONST_INT
2934 || (GET_CODE (x
) == PLUS
2935 && (GET_CODE (XEXP (x
, 1)) == CONST_INT
2936 || GET_CODE (XEXP (x
, 0)) == CONST_INT
)))
2942 /* Print the lower register of a double word register pair */
2943 if (GET_CODE (x
) == REG
)
2944 fputs (reg_names
[ REGNO (x
)+1 ], file
);
2946 fatal_insn ("bad insn to frv_print_operand, 'L' modifier:", x
);
2949 /* case 'l': print a LABEL_REF. */
2953 /* Print a memory reference for ld/st/jmp, %N prints a memory reference
2954 for the second word of double memory operations. */
2955 offset
= (code
== 'M') ? 0 : UNITS_PER_WORD
;
2956 switch (GET_CODE (x
))
2959 fatal_insn ("bad insn to frv_print_operand, 'M/N' modifier:", x
);
2962 frv_print_operand_memory_reference (file
, XEXP (x
, 0), offset
);
2970 frv_print_operand_memory_reference (file
, x
, offset
);
2976 /* Print the opcode of a command. */
2977 switch (GET_CODE (x
))
2980 fatal_insn ("bad insn to frv_print_operand, 'O' modifier:", x
);
2982 case PLUS
: fputs ("add", file
); break;
2983 case MINUS
: fputs ("sub", file
); break;
2984 case AND
: fputs ("and", file
); break;
2985 case IOR
: fputs ("or", file
); break;
2986 case XOR
: fputs ("xor", file
); break;
2987 case ASHIFT
: fputs ("sll", file
); break;
2988 case ASHIFTRT
: fputs ("sra", file
); break;
2989 case LSHIFTRT
: fputs ("srl", file
); break;
2993 /* case 'n': negate and print a constant int. */
2996 /* Print PIC label using operand as the number. */
2997 if (GET_CODE (x
) != CONST_INT
)
2998 fatal_insn ("bad insn to frv_print_operand, P modifier:", x
);
3000 fprintf (file
, ".LCF%ld", (long)INTVAL (x
));
3004 /* Print 'u' if the operand is a update load/store. */
3005 if (GET_CODE (x
) == MEM
&& GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
3010 /* If value is 0, print gr0, otherwise it must be a register. */
3011 if (GET_CODE (x
) == CONST_INT
&& INTVAL (x
) == 0)
3012 fputs (reg_names
[GPR_R0
], file
);
3014 else if (GET_CODE (x
) == REG
)
3015 fputs (reg_names
[REGNO (x
)], file
);
3018 fatal_insn ("bad insn in frv_print_operand, z case", x
);
3022 /* Print constant in hex. */
3023 if (GET_CODE (x
) == CONST_INT
|| GET_CODE (x
) == CONST_DOUBLE
)
3025 fprintf (file
, "%s0x%.4lx", IMMEDIATE_PREFIX
, (long) value
);
3032 if (GET_CODE (x
) == REG
)
3033 fputs (reg_names
[REGNO (x
)], file
);
3035 else if (GET_CODE (x
) == CONST_INT
3036 || GET_CODE (x
) == CONST_DOUBLE
)
3037 fprintf (file
, "%s%ld", IMMEDIATE_PREFIX
, (long) value
);
3039 else if (frv_const_unspec_p (x
, &unspec
))
3040 frv_output_const_unspec (file
, &unspec
);
3042 else if (GET_CODE (x
) == MEM
)
3043 frv_print_operand_address (file
, XEXP (x
, 0));
3045 else if (CONSTANT_ADDRESS_P (x
))
3046 frv_print_operand_address (file
, x
);
3049 fatal_insn ("bad insn in frv_print_operand, 0 case", x
);
3054 fatal_insn ("frv_print_operand: unknown code", x
);
3062 frv_print_operand_punct_valid_p (unsigned char code
)
3064 return (code
== '.' || code
== '#' || code
== '@' || code
== '~'
3065 || code
== '*' || code
== '&');
3069 /* A C statement (sans semicolon) for initializing the variable CUM for the
3070 state at the beginning of the argument list. The variable has type
3071 `CUMULATIVE_ARGS'. The value of FNTYPE is the tree node for the data type
3072 of the function which will receive the args, or 0 if the args are to a
3073 compiler support library function. The value of INDIRECT is nonzero when
3074 processing an indirect call, for example a call through a function pointer.
3075 The value of INDIRECT is zero for a call to an explicitly named function, a
3076 library function call, or when `INIT_CUMULATIVE_ARGS' is used to find
3077 arguments for the function being compiled.
3079 When processing a call to a compiler support library function, LIBNAME
3080 identifies which one. It is a `symbol_ref' rtx which contains the name of
3081 the function, as a string. LIBNAME is 0 when an ordinary C function call is
3082 being processed. Thus, each time this macro is called, either LIBNAME or
3083 FNTYPE is nonzero, but never both of them at once. */
3086 frv_init_cumulative_args (CUMULATIVE_ARGS
*cum
,
3092 *cum
= FIRST_ARG_REGNUM
;
3094 if (TARGET_DEBUG_ARG
)
3096 fprintf (stderr
, "\ninit_cumulative_args:");
3097 if (!fndecl
&& fntype
)
3098 fputs (" indirect", stderr
);
3101 fputs (" incoming", stderr
);
3105 tree ret_type
= TREE_TYPE (fntype
);
3106 fprintf (stderr
, " return=%s,",
3107 get_tree_code_name (TREE_CODE (ret_type
)));
3110 if (libname
&& GET_CODE (libname
) == SYMBOL_REF
)
3111 fprintf (stderr
, " libname=%s", XSTR (libname
, 0));
3113 if (cfun
->returns_struct
)
3114 fprintf (stderr
, " return-struct");
3116 putc ('\n', stderr
);
3121 /* Return true if we should pass an argument on the stack rather than
3125 frv_must_pass_in_stack (machine_mode mode
, const_tree type
)
3127 if (mode
== BLKmode
)
3131 return AGGREGATE_TYPE_P (type
);
3134 /* If defined, a C expression that gives the alignment boundary, in bits, of an
3135 argument with the specified mode and type. If it is not defined,
3136 `PARM_BOUNDARY' is used for all arguments. */
3139 frv_function_arg_boundary (machine_mode mode ATTRIBUTE_UNUSED
,
3140 const_tree type ATTRIBUTE_UNUSED
)
3142 return BITS_PER_WORD
;
3146 frv_function_arg_1 (cumulative_args_t cum_v
, machine_mode mode
,
3147 const_tree type ATTRIBUTE_UNUSED
, bool named
,
3148 bool incoming ATTRIBUTE_UNUSED
)
3150 const CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
3152 machine_mode xmode
= (mode
== BLKmode
) ? SImode
: mode
;
3157 /* Return a marker for use in the call instruction. */
3158 if (xmode
== VOIDmode
)
3164 else if (arg_num
<= LAST_ARG_REGNUM
)
3166 ret
= gen_rtx_REG (xmode
, arg_num
);
3167 debstr
= reg_names
[arg_num
];
3176 if (TARGET_DEBUG_ARG
)
3178 "function_arg: words = %2d, mode = %4s, named = %d, size = %3d, arg = %s\n",
3179 arg_num
, GET_MODE_NAME (mode
), named
, GET_MODE_SIZE (mode
), debstr
);
3185 frv_function_arg (cumulative_args_t cum
, machine_mode mode
,
3186 const_tree type
, bool named
)
3188 return frv_function_arg_1 (cum
, mode
, type
, named
, false);
3192 frv_function_incoming_arg (cumulative_args_t cum
, machine_mode mode
,
3193 const_tree type
, bool named
)
3195 return frv_function_arg_1 (cum
, mode
, type
, named
, true);
3199 /* A C statement (sans semicolon) to update the summarizer variable CUM to
3200 advance past an argument in the argument list. The values MODE, TYPE and
3201 NAMED describe that argument. Once this is done, the variable CUM is
3202 suitable for analyzing the *following* argument with `FUNCTION_ARG', etc.
3204 This macro need not do anything if the argument in question was passed on
3205 the stack. The compiler knows how to track the amount of stack space used
3206 for arguments without any special help. */
3209 frv_function_arg_advance (cumulative_args_t cum_v
,
3211 const_tree type ATTRIBUTE_UNUSED
,
3214 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
3216 machine_mode xmode
= (mode
== BLKmode
) ? SImode
: mode
;
3217 int bytes
= GET_MODE_SIZE (xmode
);
3218 int words
= (bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
3221 *cum
= arg_num
+ words
;
3223 if (TARGET_DEBUG_ARG
)
3225 "function_adv: words = %2d, mode = %4s, named = %d, size = %3d\n",
3226 arg_num
, GET_MODE_NAME (mode
), named
, words
* UNITS_PER_WORD
);
3230 /* A C expression for the number of words, at the beginning of an argument,
3231 must be put in registers. The value must be zero for arguments that are
3232 passed entirely in registers or that are entirely pushed on the stack.
3234 On some machines, certain arguments must be passed partially in registers
3235 and partially in memory. On these machines, typically the first N words of
3236 arguments are passed in registers, and the rest on the stack. If a
3237 multi-word argument (a `double' or a structure) crosses that boundary, its
3238 first few words must be passed in registers and the rest must be pushed.
3239 This macro tells the compiler when this occurs, and how many of the words
3240 should go in registers.
3242 `FUNCTION_ARG' for these arguments should return the first register to be
3243 used by the caller for this argument; likewise `FUNCTION_INCOMING_ARG', for
3244 the called function. */
3247 frv_arg_partial_bytes (cumulative_args_t cum
, machine_mode mode
,
3248 tree type ATTRIBUTE_UNUSED
, bool named ATTRIBUTE_UNUSED
)
3251 machine_mode xmode
= (mode
== BLKmode
) ? SImode
: mode
;
3252 int bytes
= GET_MODE_SIZE (xmode
);
3253 int words
= (bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
3254 int arg_num
= *get_cumulative_args (cum
);
3257 ret
= ((arg_num
<= LAST_ARG_REGNUM
&& arg_num
+ words
> LAST_ARG_REGNUM
+1)
3258 ? LAST_ARG_REGNUM
- arg_num
+ 1
3260 ret
*= UNITS_PER_WORD
;
3262 if (TARGET_DEBUG_ARG
&& ret
)
3263 fprintf (stderr
, "frv_arg_partial_bytes: %d\n", ret
);
3269 /* Implements TARGET_FUNCTION_VALUE. */
3272 frv_function_value (const_tree valtype
,
3273 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
3274 bool outgoing ATTRIBUTE_UNUSED
)
3276 return gen_rtx_REG (TYPE_MODE (valtype
), RETURN_VALUE_REGNUM
);
3280 /* Implements TARGET_LIBCALL_VALUE. */
3283 frv_libcall_value (machine_mode mode
,
3284 const_rtx fun ATTRIBUTE_UNUSED
)
3286 return gen_rtx_REG (mode
, RETURN_VALUE_REGNUM
);
3290 /* Implements FUNCTION_VALUE_REGNO_P. */
3293 frv_function_value_regno_p (const unsigned int regno
)
3295 return (regno
== RETURN_VALUE_REGNUM
);
3298 /* Return true if a register is ok to use as a base or index register. */
3300 static FRV_INLINE
int
3301 frv_regno_ok_for_base_p (int regno
, int strict_p
)
3307 return (reg_renumber
[regno
] >= 0 && GPR_P (reg_renumber
[regno
]));
3309 if (regno
== ARG_POINTER_REGNUM
)
3312 return (regno
>= FIRST_PSEUDO_REGISTER
);
3316 /* A C compound statement with a conditional `goto LABEL;' executed if X (an
3317 RTX) is a legitimate memory address on the target machine for a memory
3318 operand of mode MODE.
3320 It usually pays to define several simpler macros to serve as subroutines for
3321 this one. Otherwise it may be too complicated to understand.
3323 This macro must exist in two variants: a strict variant and a non-strict
3324 one. The strict variant is used in the reload pass. It must be defined so
3325 that any pseudo-register that has not been allocated a hard register is
3326 considered a memory reference. In contexts where some kind of register is
3327 required, a pseudo-register with no hard register must be rejected.
3329 The non-strict variant is used in other passes. It must be defined to
3330 accept all pseudo-registers in every context where some kind of register is
3333 Compiler source files that want to use the strict variant of this macro
3334 define the macro `REG_OK_STRICT'. You should use an `#ifdef REG_OK_STRICT'
3335 conditional to define the strict variant in that case and the non-strict
3338 Normally, constant addresses which are the sum of a `symbol_ref' and an
3339 integer are stored inside a `const' RTX to mark them as constant.
3340 Therefore, there is no need to recognize such sums specifically as
3341 legitimate addresses. Normally you would simply recognize any `const' as
3344 Usually `TARGET_PRINT_OPERAND_ADDRESS' is not prepared to handle
3345 constant sums that are not marked with `const'. It assumes that a
3346 naked `plus' indicates indexing. If so, then you *must* reject such
3347 naked constant sums as illegitimate addresses, so that none of them
3348 will be given to `TARGET_PRINT_OPERAND_ADDRESS'. */
3351 frv_legitimate_address_p_1 (machine_mode mode
,
3355 int allow_double_reg_p
)
3359 HOST_WIDE_INT value
;
3362 if (FRV_SYMBOL_REF_TLS_P (x
))
3365 switch (GET_CODE (x
))
3372 if (GET_CODE (x
) != REG
)
3378 ret
= frv_regno_ok_for_base_p (REGNO (x
), strict_p
);
3384 if (GET_CODE (x0
) != REG
3385 || ! frv_regno_ok_for_base_p (REGNO (x0
), strict_p
)
3386 || GET_CODE (x1
) != PLUS
3387 || ! rtx_equal_p (x0
, XEXP (x1
, 0))
3388 || GET_CODE (XEXP (x1
, 1)) != REG
3389 || ! frv_regno_ok_for_base_p (REGNO (XEXP (x1
, 1)), strict_p
))
3396 /* 12-bit immediate */
3401 ret
= IN_RANGE (INTVAL (x
), -2048, 2047);
3403 /* If we can't use load/store double operations, make sure we can
3404 address the second word. */
3405 if (ret
&& GET_MODE_SIZE (mode
) > UNITS_PER_WORD
)
3406 ret
= IN_RANGE (INTVAL (x
) + GET_MODE_SIZE (mode
) - 1,
3415 if (GET_CODE (x0
) == SUBREG
)
3416 x0
= SUBREG_REG (x0
);
3418 if (GET_CODE (x0
) != REG
)
3421 regno0
= REGNO (x0
);
3422 if (!frv_regno_ok_for_base_p (regno0
, strict_p
))
3425 switch (GET_CODE (x1
))
3431 x1
= SUBREG_REG (x1
);
3432 if (GET_CODE (x1
) != REG
)
3438 /* Do not allow reg+reg addressing for modes > 1 word if we
3439 can't depend on having move double instructions. */
3440 if (!allow_double_reg_p
&& GET_MODE_SIZE (mode
) > UNITS_PER_WORD
)
3443 ret
= frv_regno_ok_for_base_p (REGNO (x1
), strict_p
);
3447 /* 12-bit immediate */
3452 value
= INTVAL (x1
);
3453 ret
= IN_RANGE (value
, -2048, 2047);
3455 /* If we can't use load/store double operations, make sure we can
3456 address the second word. */
3457 if (ret
&& GET_MODE_SIZE (mode
) > UNITS_PER_WORD
)
3458 ret
= IN_RANGE (value
+ GET_MODE_SIZE (mode
) - 1, -2048, 2047);
3463 if (!condexec_p
&& got12_operand (x1
, VOIDmode
))
3471 if (TARGET_DEBUG_ADDR
)
3473 fprintf (stderr
, "\n========== legitimate_address_p, mode = %s, result = %d, addresses are %sstrict%s\n",
3474 GET_MODE_NAME (mode
), ret
, (strict_p
) ? "" : "not ",
3475 (condexec_p
) ? ", inside conditional code" : "");
3483 frv_legitimate_address_p (machine_mode mode
, rtx x
, bool strict_p
)
3485 return frv_legitimate_address_p_1 (mode
, x
, strict_p
, FALSE
, FALSE
);
3488 /* Given an ADDR, generate code to inline the PLT. */
3490 gen_inlined_tls_plt (rtx addr
)
3493 rtx picreg
= get_hard_reg_initial_val (Pmode
, FDPIC_REG
);
3496 dest
= gen_reg_rtx (DImode
);
3503 lddi.p @(gr15, #gottlsdesc12(ADDR)), gr8
3504 calll #gettlsoff(ADDR)@(gr8, gr0)
3506 emit_insn (gen_tls_lddi (dest
, addr
, picreg
));
3513 sethi.p #gottlsdeschi(ADDR), gr8
3514 setlo #gottlsdesclo(ADDR), gr8
3515 ldd #tlsdesc(ADDR)@(gr15, gr8), gr8
3516 calll #gettlsoff(ADDR)@(gr8, gr0)
3518 rtx reguse
= gen_reg_rtx (Pmode
);
3519 emit_insn (gen_tlsoff_hilo (reguse
, addr
, GEN_INT (R_FRV_GOTTLSDESCHI
)));
3520 emit_insn (gen_tls_tlsdesc_ldd (dest
, picreg
, reguse
, addr
));
3523 retval
= gen_reg_rtx (Pmode
);
3524 emit_insn (gen_tls_indirect_call (retval
, addr
, dest
, picreg
));
3528 /* Emit a TLSMOFF or TLSMOFF12 offset, depending on -mTLS. Returns
3529 the destination address. */
3531 gen_tlsmoff (rtx addr
, rtx reg
)
3533 rtx dest
= gen_reg_rtx (Pmode
);
3537 /* sethi.p #tlsmoffhi(x), grA
3538 setlo #tlsmofflo(x), grA
3540 dest
= gen_reg_rtx (Pmode
);
3541 emit_insn (gen_tlsoff_hilo (dest
, addr
,
3542 GEN_INT (R_FRV_TLSMOFFHI
)));
3543 dest
= gen_rtx_PLUS (Pmode
, dest
, reg
);
3547 /* addi grB, #tlsmoff12(x), grC
3549 ld/st @(grB, #tlsmoff12(x)), grC
3551 dest
= gen_reg_rtx (Pmode
);
3552 emit_insn (gen_symGOTOFF2reg_i (dest
, addr
, reg
,
3553 GEN_INT (R_FRV_TLSMOFF12
)));
3558 /* Generate code for a TLS address. */
3560 frv_legitimize_tls_address (rtx addr
, enum tls_model model
)
3562 rtx dest
, tp
= gen_rtx_REG (Pmode
, 29);
3563 rtx picreg
= get_hard_reg_initial_val (Pmode
, 15);
3567 case TLS_MODEL_INITIAL_EXEC
:
3571 ldi @(gr15, #gottlsoff12(x)), gr5
3573 dest
= gen_reg_rtx (Pmode
);
3574 emit_insn (gen_tls_load_gottlsoff12 (dest
, addr
, picreg
));
3575 dest
= gen_rtx_PLUS (Pmode
, tp
, dest
);
3579 /* -fPIC or anything else.
3581 sethi.p #gottlsoffhi(x), gr14
3582 setlo #gottlsofflo(x), gr14
3583 ld #tlsoff(x)@(gr15, gr14), gr9
3585 rtx tmp
= gen_reg_rtx (Pmode
);
3586 dest
= gen_reg_rtx (Pmode
);
3587 emit_insn (gen_tlsoff_hilo (tmp
, addr
,
3588 GEN_INT (R_FRV_GOTTLSOFF_HI
)));
3590 emit_insn (gen_tls_tlsoff_ld (dest
, picreg
, tmp
, addr
));
3591 dest
= gen_rtx_PLUS (Pmode
, tp
, dest
);
3594 case TLS_MODEL_LOCAL_DYNAMIC
:
3598 if (TARGET_INLINE_PLT
)
3599 retval
= gen_inlined_tls_plt (GEN_INT (0));
3602 /* call #gettlsoff(0) */
3603 retval
= gen_reg_rtx (Pmode
);
3604 emit_insn (gen_call_gettlsoff (retval
, GEN_INT (0), picreg
));
3607 reg
= gen_reg_rtx (Pmode
);
3608 emit_insn (gen_rtx_SET (reg
, gen_rtx_PLUS (Pmode
, retval
, tp
)));
3610 dest
= gen_tlsmoff (addr
, reg
);
3613 dest = gen_reg_rtx (Pmode);
3614 emit_insn (gen_tlsoff_hilo (dest, addr,
3615 GEN_INT (R_FRV_TLSMOFFHI)));
3616 dest = gen_rtx_PLUS (Pmode, dest, reg);
3620 case TLS_MODEL_LOCAL_EXEC
:
3621 dest
= gen_tlsmoff (addr
, gen_rtx_REG (Pmode
, 29));
3623 case TLS_MODEL_GLOBAL_DYNAMIC
:
3627 if (TARGET_INLINE_PLT
)
3628 retval
= gen_inlined_tls_plt (addr
);
3631 /* call #gettlsoff(x) */
3632 retval
= gen_reg_rtx (Pmode
);
3633 emit_insn (gen_call_gettlsoff (retval
, addr
, picreg
));
3635 dest
= gen_rtx_PLUS (Pmode
, retval
, tp
);
3646 frv_legitimize_address (rtx x
,
3647 rtx oldx ATTRIBUTE_UNUSED
,
3648 machine_mode mode ATTRIBUTE_UNUSED
)
3650 if (GET_CODE (x
) == SYMBOL_REF
)
3652 enum tls_model model
= SYMBOL_REF_TLS_MODEL (x
);
3654 return frv_legitimize_tls_address (x
, model
);
3660 /* Test whether a local function descriptor is canonical, i.e.,
3661 whether we can use FUNCDESC_GOTOFF to compute the address of the
3665 frv_local_funcdesc_p (rtx fnx
)
3668 enum symbol_visibility vis
;
3671 if (! SYMBOL_REF_LOCAL_P (fnx
))
3674 fn
= SYMBOL_REF_DECL (fnx
);
3679 vis
= DECL_VISIBILITY (fn
);
3681 if (vis
== VISIBILITY_PROTECTED
)
3682 /* Private function descriptors for protected functions are not
3683 canonical. Temporarily change the visibility to global. */
3684 vis
= VISIBILITY_DEFAULT
;
3685 else if (flag_shlib
)
3686 /* If we're already compiling for a shared library (that, unlike
3687 executables, can't assume that the existence of a definition
3688 implies local binding), we can skip the re-testing. */
3691 ret
= default_binds_local_p_1 (fn
, flag_pic
);
3693 DECL_VISIBILITY (fn
) = vis
;
3698 /* Load the _gp symbol into DEST. SRC is supposed to be the FDPIC
3702 frv_gen_GPsym2reg (rtx dest
, rtx src
)
3704 tree gp
= get_identifier ("_gp");
3705 rtx gp_sym
= gen_rtx_SYMBOL_REF (Pmode
, IDENTIFIER_POINTER (gp
));
3707 return gen_symGOT2reg (dest
, gp_sym
, src
, GEN_INT (R_FRV_GOT12
));
3711 unspec_got_name (int i
)
3715 case R_FRV_GOT12
: return "got12";
3716 case R_FRV_GOTHI
: return "gothi";
3717 case R_FRV_GOTLO
: return "gotlo";
3718 case R_FRV_FUNCDESC
: return "funcdesc";
3719 case R_FRV_FUNCDESC_GOT12
: return "gotfuncdesc12";
3720 case R_FRV_FUNCDESC_GOTHI
: return "gotfuncdeschi";
3721 case R_FRV_FUNCDESC_GOTLO
: return "gotfuncdesclo";
3722 case R_FRV_FUNCDESC_VALUE
: return "funcdescvalue";
3723 case R_FRV_FUNCDESC_GOTOFF12
: return "gotofffuncdesc12";
3724 case R_FRV_FUNCDESC_GOTOFFHI
: return "gotofffuncdeschi";
3725 case R_FRV_FUNCDESC_GOTOFFLO
: return "gotofffuncdesclo";
3726 case R_FRV_GOTOFF12
: return "gotoff12";
3727 case R_FRV_GOTOFFHI
: return "gotoffhi";
3728 case R_FRV_GOTOFFLO
: return "gotofflo";
3729 case R_FRV_GPREL12
: return "gprel12";
3730 case R_FRV_GPRELHI
: return "gprelhi";
3731 case R_FRV_GPRELLO
: return "gprello";
3732 case R_FRV_GOTTLSOFF_HI
: return "gottlsoffhi";
3733 case R_FRV_GOTTLSOFF_LO
: return "gottlsofflo";
3734 case R_FRV_TLSMOFFHI
: return "tlsmoffhi";
3735 case R_FRV_TLSMOFFLO
: return "tlsmofflo";
3736 case R_FRV_TLSMOFF12
: return "tlsmoff12";
3737 case R_FRV_TLSDESCHI
: return "tlsdeschi";
3738 case R_FRV_TLSDESCLO
: return "tlsdesclo";
3739 case R_FRV_GOTTLSDESCHI
: return "gottlsdeschi";
3740 case R_FRV_GOTTLSDESCLO
: return "gottlsdesclo";
3741 default: gcc_unreachable ();
3745 /* Write the assembler syntax for UNSPEC to STREAM. Note that any offset
3746 is added inside the relocation operator. */
3749 frv_output_const_unspec (FILE *stream
, const struct frv_unspec
*unspec
)
3751 fprintf (stream
, "#%s(", unspec_got_name (unspec
->reloc
));
3752 output_addr_const (stream
, plus_constant (Pmode
, unspec
->symbol
,
3754 fputs (")", stream
);
3757 /* Implement FIND_BASE_TERM. See whether ORIG_X represents #gprel12(foo)
3758 or #gotoff12(foo) for some small data symbol foo. If so, return foo,
3759 otherwise return ORIG_X. */
3762 frv_find_base_term (rtx x
)
3764 struct frv_unspec unspec
;
3766 if (frv_const_unspec_p (x
, &unspec
)
3767 && frv_small_data_reloc_p (unspec
.symbol
, unspec
.reloc
))
3768 return plus_constant (Pmode
, unspec
.symbol
, unspec
.offset
);
3773 /* Return 1 if operand is a valid FRV address. CONDEXEC_P is true if
3774 the operand is used by a predicated instruction. */
3777 frv_legitimate_memory_operand (rtx op
, machine_mode mode
, int condexec_p
)
3779 return ((GET_MODE (op
) == mode
|| mode
== VOIDmode
)
3780 && GET_CODE (op
) == MEM
3781 && frv_legitimate_address_p_1 (mode
, XEXP (op
, 0),
3782 reload_completed
, condexec_p
, FALSE
));
3786 frv_expand_fdpic_call (rtx
*operands
, bool ret_value
, bool sibcall
)
3788 rtx lr
= gen_rtx_REG (Pmode
, LR_REGNO
);
3789 rtx picreg
= get_hard_reg_initial_val (SImode
, FDPIC_REG
);
3795 rvrtx
= operands
[0];
3799 addr
= XEXP (operands
[0], 0);
3801 /* Inline PLTs if we're optimizing for speed. We'd like to inline
3802 any calls that would involve a PLT, but can't tell, since we
3803 don't know whether an extern function is going to be provided by
3804 a separate translation unit or imported from a separate module.
3805 When compiling for shared libraries, if the function has default
3806 visibility, we assume it's overridable, so we inline the PLT, but
3807 for executables, we don't really have a way to make a good
3808 decision: a function is as likely to be imported from a shared
3809 library as it is to be defined in the executable itself. We
3810 assume executables will get global functions defined locally,
3811 whereas shared libraries will have them potentially overridden,
3812 so we only inline PLTs when compiling for shared libraries.
3814 In order to mark a function as local to a shared library, any
3815 non-default visibility attribute suffices. Unfortunately,
3816 there's no simple way to tag a function declaration as ``in a
3817 different module'', which we could then use to trigger PLT
3818 inlining on executables. There's -minline-plt, but it affects
3819 all external functions, so one would have to also mark function
3820 declarations available in the same module with non-default
3821 visibility, which is advantageous in itself. */
3822 if (GET_CODE (addr
) == SYMBOL_REF
3823 && ((!SYMBOL_REF_LOCAL_P (addr
) && TARGET_INLINE_PLT
)
3827 dest
= gen_reg_rtx (SImode
);
3829 x
= gen_symGOTOFF2reg_hilo (dest
, addr
, OUR_FDPIC_REG
,
3830 GEN_INT (R_FRV_FUNCDESC_GOTOFF12
));
3832 x
= gen_symGOTOFF2reg (dest
, addr
, OUR_FDPIC_REG
,
3833 GEN_INT (R_FRV_FUNCDESC_GOTOFF12
));
3835 crtl
->uses_pic_offset_table
= TRUE
;
3838 else if (GET_CODE (addr
) == SYMBOL_REF
)
3840 /* These are always either local, or handled through a local
3843 c
= gen_call_value_fdpicsi (rvrtx
, addr
, operands
[1],
3844 operands
[2], picreg
, lr
);
3846 c
= gen_call_fdpicsi (addr
, operands
[1], operands
[2], picreg
, lr
);
3850 else if (! ldd_address_operand (addr
, Pmode
))
3851 addr
= force_reg (Pmode
, addr
);
3853 picreg
= gen_reg_rtx (DImode
);
3854 emit_insn (gen_movdi_ldd (picreg
, addr
));
3856 if (sibcall
&& ret_value
)
3857 c
= gen_sibcall_value_fdpicdi (rvrtx
, picreg
, const0_rtx
);
3859 c
= gen_sibcall_fdpicdi (picreg
, const0_rtx
);
3861 c
= gen_call_value_fdpicdi (rvrtx
, picreg
, const0_rtx
, lr
);
3863 c
= gen_call_fdpicdi (picreg
, const0_rtx
, lr
);
3867 /* Look for a SYMBOL_REF of a function in an rtx. We always want to
3868 process these separately from any offsets, such that we add any
3869 offsets to the function descriptor (the actual pointer), not to the
3870 function address. */
3873 frv_function_symbol_referenced_p (rtx x
)
3879 if (GET_CODE (x
) == SYMBOL_REF
)
3880 return SYMBOL_REF_FUNCTION_P (x
);
3882 length
= GET_RTX_LENGTH (GET_CODE (x
));
3883 format
= GET_RTX_FORMAT (GET_CODE (x
));
3885 for (j
= 0; j
< length
; ++j
)
3890 if (frv_function_symbol_referenced_p (XEXP (x
, j
)))
3896 if (XVEC (x
, j
) != 0)
3899 for (k
= 0; k
< XVECLEN (x
, j
); ++k
)
3900 if (frv_function_symbol_referenced_p (XVECEXP (x
, j
, k
)))
3906 /* Nothing to do. */
3914 /* Return true if the memory operand is one that can be conditionally
3918 condexec_memory_operand (rtx op
, machine_mode mode
)
3920 machine_mode op_mode
= GET_MODE (op
);
3923 if (mode
!= VOIDmode
&& op_mode
!= mode
)
3938 if (GET_CODE (op
) != MEM
)
3941 addr
= XEXP (op
, 0);
3942 return frv_legitimate_address_p_1 (mode
, addr
, reload_completed
, TRUE
, FALSE
);
3945 /* Return true if the bare return instruction can be used outside of the
3946 epilog code. For frv, we only do it if there was no stack allocation. */
3949 direct_return_p (void)
3953 if (!reload_completed
)
3956 info
= frv_stack_info ();
3957 return (info
->total_size
== 0);
3962 frv_emit_move (machine_mode mode
, rtx dest
, rtx src
)
3964 if (GET_CODE (src
) == SYMBOL_REF
)
3966 enum tls_model model
= SYMBOL_REF_TLS_MODEL (src
);
3968 src
= frv_legitimize_tls_address (src
, model
);
3974 if (frv_emit_movsi (dest
, src
))
3983 if (!reload_in_progress
3984 && !reload_completed
3985 && !register_operand (dest
, mode
)
3986 && !reg_or_0_operand (src
, mode
))
3987 src
= copy_to_mode_reg (mode
, src
);
3994 emit_insn (gen_rtx_SET (dest
, src
));
3997 /* Emit code to handle a MOVSI, adding in the small data register or pic
3998 register if needed to load up addresses. Return TRUE if the appropriate
3999 instructions are emitted. */
4002 frv_emit_movsi (rtx dest
, rtx src
)
4004 int base_regno
= -1;
4007 struct frv_unspec old_unspec
;
4009 if (!reload_in_progress
4010 && !reload_completed
4011 && !register_operand (dest
, SImode
)
4012 && (!reg_or_0_operand (src
, SImode
)
4013 /* Virtual registers will almost always be replaced by an
4014 add instruction, so expose this to CSE by copying to
4015 an intermediate register. */
4016 || (GET_CODE (src
) == REG
4017 && IN_RANGE (REGNO (src
),
4018 FIRST_VIRTUAL_REGISTER
,
4019 LAST_VIRTUAL_POINTER_REGISTER
))))
4021 emit_insn (gen_rtx_SET (dest
, copy_to_mode_reg (SImode
, src
)));
4025 /* Explicitly add in the PIC or small data register if needed. */
4026 switch (GET_CODE (src
))
4035 /* Using GPREL12, we use a single GOT entry for all symbols
4036 in read-only sections, but trade sequences such as:
4038 sethi #gothi(label), gr#
4039 setlo #gotlo(label), gr#
4044 ld @(gr15,#got12(_gp)), gr#
4045 sethi #gprelhi(label), gr##
4046 setlo #gprello(label), gr##
4049 We may often be able to share gr# for multiple
4050 computations of GPREL addresses, and we may often fold
4051 the final add into the pair of registers of a load or
4052 store instruction, so it's often profitable. Even when
4053 optimizing for size, we're trading a GOT entry for an
4054 additional instruction, which trades GOT space
4055 (read-write) for code size (read-only, shareable), as
4056 long as the symbol is not used in more than two different
4059 With -fpie/-fpic, we'd be trading a single load for a
4060 sequence of 4 instructions, because the offset of the
4061 label can't be assumed to be addressable with 12 bits, so
4062 we don't do this. */
4063 if (TARGET_GPREL_RO
)
4064 unspec
= R_FRV_GPREL12
;
4066 unspec
= R_FRV_GOT12
;
4069 base_regno
= PIC_REGNO
;
4074 if (frv_const_unspec_p (src
, &old_unspec
))
4077 if (TARGET_FDPIC
&& frv_function_symbol_referenced_p (XEXP (src
, 0)))
4080 src
= force_reg (GET_MODE (XEXP (src
, 0)), XEXP (src
, 0));
4081 emit_move_insn (dest
, src
);
4086 sym
= XEXP (sym
, 0);
4087 if (GET_CODE (sym
) == PLUS
4088 && GET_CODE (XEXP (sym
, 0)) == SYMBOL_REF
4089 && GET_CODE (XEXP (sym
, 1)) == CONST_INT
)
4090 sym
= XEXP (sym
, 0);
4091 if (GET_CODE (sym
) == SYMBOL_REF
)
4093 else if (GET_CODE (sym
) == LABEL_REF
)
4096 goto handle_whatever
;
4104 enum tls_model model
= SYMBOL_REF_TLS_MODEL (sym
);
4108 src
= frv_legitimize_tls_address (src
, model
);
4109 emit_move_insn (dest
, src
);
4113 if (SYMBOL_REF_FUNCTION_P (sym
))
4115 if (frv_local_funcdesc_p (sym
))
4116 unspec
= R_FRV_FUNCDESC_GOTOFF12
;
4118 unspec
= R_FRV_FUNCDESC_GOT12
;
4122 if (CONSTANT_POOL_ADDRESS_P (sym
))
4123 switch (GET_CODE (get_pool_constant (sym
)))
4130 unspec
= R_FRV_GOTOFF12
;
4135 if (TARGET_GPREL_RO
)
4136 unspec
= R_FRV_GPREL12
;
4138 unspec
= R_FRV_GOT12
;
4141 else if (SYMBOL_REF_LOCAL_P (sym
)
4142 && !SYMBOL_REF_EXTERNAL_P (sym
)
4143 && SYMBOL_REF_DECL (sym
)
4144 && (!DECL_P (SYMBOL_REF_DECL (sym
))
4145 || !DECL_COMMON (SYMBOL_REF_DECL (sym
))))
4147 tree decl
= SYMBOL_REF_DECL (sym
);
4148 tree init
= TREE_CODE (decl
) == VAR_DECL
4149 ? DECL_INITIAL (decl
)
4150 : TREE_CODE (decl
) == CONSTRUCTOR
4153 bool named_section
, readonly
;
4155 if (init
&& init
!= error_mark_node
)
4156 reloc
= compute_reloc_for_constant (init
);
4158 named_section
= TREE_CODE (decl
) == VAR_DECL
4159 && lookup_attribute ("section", DECL_ATTRIBUTES (decl
));
4160 readonly
= decl_readonly_section (decl
, reloc
);
4163 unspec
= R_FRV_GOT12
;
4165 unspec
= R_FRV_GOTOFF12
;
4166 else if (readonly
&& TARGET_GPREL_RO
)
4167 unspec
= R_FRV_GPREL12
;
4169 unspec
= R_FRV_GOT12
;
4172 unspec
= R_FRV_GOT12
;
4176 else if (SYMBOL_REF_SMALL_P (sym
))
4177 base_regno
= SDA_BASE_REG
;
4180 base_regno
= PIC_REGNO
;
4185 if (base_regno
>= 0)
4187 if (GET_CODE (sym
) == SYMBOL_REF
&& SYMBOL_REF_SMALL_P (sym
))
4188 emit_insn (gen_symGOTOFF2reg (dest
, src
,
4189 gen_rtx_REG (Pmode
, base_regno
),
4190 GEN_INT (R_FRV_GPREL12
)));
4192 emit_insn (gen_symGOTOFF2reg_hilo (dest
, src
,
4193 gen_rtx_REG (Pmode
, base_regno
),
4194 GEN_INT (R_FRV_GPREL12
)));
4195 if (base_regno
== PIC_REGNO
)
4196 crtl
->uses_pic_offset_table
= TRUE
;
4204 /* Since OUR_FDPIC_REG is a pseudo register, we can't safely introduce
4205 new uses of it once reload has begun. */
4206 gcc_assert (!reload_in_progress
&& !reload_completed
);
4210 case R_FRV_GOTOFF12
:
4211 if (!frv_small_data_reloc_p (sym
, unspec
))
4212 x
= gen_symGOTOFF2reg_hilo (dest
, src
, OUR_FDPIC_REG
,
4215 x
= gen_symGOTOFF2reg (dest
, src
, OUR_FDPIC_REG
, GEN_INT (unspec
));
4218 if (!frv_small_data_reloc_p (sym
, unspec
))
4219 x
= gen_symGPREL2reg_hilo (dest
, src
, OUR_FDPIC_REG
,
4222 x
= gen_symGPREL2reg (dest
, src
, OUR_FDPIC_REG
, GEN_INT (unspec
));
4224 case R_FRV_FUNCDESC_GOTOFF12
:
4226 x
= gen_symGOTOFF2reg_hilo (dest
, src
, OUR_FDPIC_REG
,
4229 x
= gen_symGOTOFF2reg (dest
, src
, OUR_FDPIC_REG
, GEN_INT (unspec
));
4233 x
= gen_symGOT2reg_hilo (dest
, src
, OUR_FDPIC_REG
,
4236 x
= gen_symGOT2reg (dest
, src
, OUR_FDPIC_REG
, GEN_INT (unspec
));
4240 crtl
->uses_pic_offset_table
= TRUE
;
4249 /* Return a string to output a single word move. */
4252 output_move_single (rtx operands
[], rtx insn
)
4254 rtx dest
= operands
[0];
4255 rtx src
= operands
[1];
4257 if (GET_CODE (dest
) == REG
)
4259 int dest_regno
= REGNO (dest
);
4260 machine_mode mode
= GET_MODE (dest
);
4262 if (GPR_P (dest_regno
))
4264 if (GET_CODE (src
) == REG
)
4266 /* gpr <- some sort of register */
4267 int src_regno
= REGNO (src
);
4269 if (GPR_P (src_regno
))
4270 return "mov %1, %0";
4272 else if (FPR_P (src_regno
))
4273 return "movfg %1, %0";
4275 else if (SPR_P (src_regno
))
4276 return "movsg %1, %0";
4279 else if (GET_CODE (src
) == MEM
)
4288 return "ldsb%I1%U1 %M1,%0";
4291 return "ldsh%I1%U1 %M1,%0";
4295 return "ld%I1%U1 %M1, %0";
4299 else if (GET_CODE (src
) == CONST_INT
4300 || GET_CODE (src
) == CONST_DOUBLE
)
4302 /* gpr <- integer/floating constant */
4303 HOST_WIDE_INT value
;
4305 if (GET_CODE (src
) == CONST_INT
)
4306 value
= INTVAL (src
);
4308 else if (mode
== SFmode
)
4313 REAL_VALUE_FROM_CONST_DOUBLE (rv
, src
);
4314 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
4319 value
= CONST_DOUBLE_LOW (src
);
4321 if (IN_RANGE (value
, -32768, 32767))
4322 return "setlos %1, %0";
4327 else if (GET_CODE (src
) == SYMBOL_REF
4328 || GET_CODE (src
) == LABEL_REF
4329 || GET_CODE (src
) == CONST
)
4335 else if (FPR_P (dest_regno
))
4337 if (GET_CODE (src
) == REG
)
4339 /* fpr <- some sort of register */
4340 int src_regno
= REGNO (src
);
4342 if (GPR_P (src_regno
))
4343 return "movgf %1, %0";
4345 else if (FPR_P (src_regno
))
4347 if (TARGET_HARD_FLOAT
)
4348 return "fmovs %1, %0";
4350 return "mor %1, %1, %0";
4354 else if (GET_CODE (src
) == MEM
)
4363 return "ldbf%I1%U1 %M1,%0";
4366 return "ldhf%I1%U1 %M1,%0";
4370 return "ldf%I1%U1 %M1, %0";
4374 else if (ZERO_P (src
))
4375 return "movgf %., %0";
4378 else if (SPR_P (dest_regno
))
4380 if (GET_CODE (src
) == REG
)
4382 /* spr <- some sort of register */
4383 int src_regno
= REGNO (src
);
4385 if (GPR_P (src_regno
))
4386 return "movgs %1, %0";
4388 else if (ZERO_P (src
))
4389 return "movgs %., %0";
4393 else if (GET_CODE (dest
) == MEM
)
4395 if (GET_CODE (src
) == REG
)
4397 int src_regno
= REGNO (src
);
4398 machine_mode mode
= GET_MODE (dest
);
4400 if (GPR_P (src_regno
))
4408 return "stb%I0%U0 %1, %M0";
4411 return "sth%I0%U0 %1, %M0";
4415 return "st%I0%U0 %1, %M0";
4419 else if (FPR_P (src_regno
))
4427 return "stbf%I0%U0 %1, %M0";
4430 return "sthf%I0%U0 %1, %M0";
4434 return "stf%I0%U0 %1, %M0";
4439 else if (ZERO_P (src
))
4441 switch (GET_MODE (dest
))
4447 return "stb%I0%U0 %., %M0";
4450 return "sth%I0%U0 %., %M0";
4454 return "st%I0%U0 %., %M0";
4459 fatal_insn ("bad output_move_single operand", insn
);
4464 /* Return a string to output a double word move. */
4467 output_move_double (rtx operands
[], rtx insn
)
4469 rtx dest
= operands
[0];
4470 rtx src
= operands
[1];
4471 machine_mode mode
= GET_MODE (dest
);
4473 if (GET_CODE (dest
) == REG
)
4475 int dest_regno
= REGNO (dest
);
4477 if (GPR_P (dest_regno
))
4479 if (GET_CODE (src
) == REG
)
4481 /* gpr <- some sort of register */
4482 int src_regno
= REGNO (src
);
4484 if (GPR_P (src_regno
))
4487 else if (FPR_P (src_regno
))
4489 if (((dest_regno
- GPR_FIRST
) & 1) == 0
4490 && ((src_regno
- FPR_FIRST
) & 1) == 0)
4491 return "movfgd %1, %0";
4497 else if (GET_CODE (src
) == MEM
)
4500 if (dbl_memory_one_insn_operand (src
, mode
))
4501 return "ldd%I1%U1 %M1, %0";
4506 else if (GET_CODE (src
) == CONST_INT
4507 || GET_CODE (src
) == CONST_DOUBLE
)
4511 else if (FPR_P (dest_regno
))
4513 if (GET_CODE (src
) == REG
)
4515 /* fpr <- some sort of register */
4516 int src_regno
= REGNO (src
);
4518 if (GPR_P (src_regno
))
4520 if (((dest_regno
- FPR_FIRST
) & 1) == 0
4521 && ((src_regno
- GPR_FIRST
) & 1) == 0)
4522 return "movgfd %1, %0";
4527 else if (FPR_P (src_regno
))
4530 && ((dest_regno
- FPR_FIRST
) & 1) == 0
4531 && ((src_regno
- FPR_FIRST
) & 1) == 0)
4532 return "fmovd %1, %0";
4538 else if (GET_CODE (src
) == MEM
)
4541 if (dbl_memory_one_insn_operand (src
, mode
))
4542 return "lddf%I1%U1 %M1, %0";
4547 else if (ZERO_P (src
))
4552 else if (GET_CODE (dest
) == MEM
)
4554 if (GET_CODE (src
) == REG
)
4556 int src_regno
= REGNO (src
);
4558 if (GPR_P (src_regno
))
4560 if (((src_regno
- GPR_FIRST
) & 1) == 0
4561 && dbl_memory_one_insn_operand (dest
, mode
))
4562 return "std%I0%U0 %1, %M0";
4567 if (FPR_P (src_regno
))
4569 if (((src_regno
- FPR_FIRST
) & 1) == 0
4570 && dbl_memory_one_insn_operand (dest
, mode
))
4571 return "stdf%I0%U0 %1, %M0";
4577 else if (ZERO_P (src
))
4579 if (dbl_memory_one_insn_operand (dest
, mode
))
4580 return "std%I0%U0 %., %M0";
4586 fatal_insn ("bad output_move_double operand", insn
);
4591 /* Return a string to output a single word conditional move.
4592 Operand0 -- EQ/NE of ccr register and 0
4593 Operand1 -- CCR register
4594 Operand2 -- destination
4595 Operand3 -- source */
4598 output_condmove_single (rtx operands
[], rtx insn
)
4600 rtx dest
= operands
[2];
4601 rtx src
= operands
[3];
4603 if (GET_CODE (dest
) == REG
)
4605 int dest_regno
= REGNO (dest
);
4606 machine_mode mode
= GET_MODE (dest
);
4608 if (GPR_P (dest_regno
))
4610 if (GET_CODE (src
) == REG
)
4612 /* gpr <- some sort of register */
4613 int src_regno
= REGNO (src
);
4615 if (GPR_P (src_regno
))
4616 return "cmov %z3, %2, %1, %e0";
4618 else if (FPR_P (src_regno
))
4619 return "cmovfg %3, %2, %1, %e0";
4622 else if (GET_CODE (src
) == MEM
)
4631 return "cldsb%I3%U3 %M3, %2, %1, %e0";
4634 return "cldsh%I3%U3 %M3, %2, %1, %e0";
4638 return "cld%I3%U3 %M3, %2, %1, %e0";
4642 else if (ZERO_P (src
))
4643 return "cmov %., %2, %1, %e0";
4646 else if (FPR_P (dest_regno
))
4648 if (GET_CODE (src
) == REG
)
4650 /* fpr <- some sort of register */
4651 int src_regno
= REGNO (src
);
4653 if (GPR_P (src_regno
))
4654 return "cmovgf %3, %2, %1, %e0";
4656 else if (FPR_P (src_regno
))
4658 if (TARGET_HARD_FLOAT
)
4659 return "cfmovs %3,%2,%1,%e0";
4661 return "cmor %3, %3, %2, %1, %e0";
4665 else if (GET_CODE (src
) == MEM
)
4668 if (mode
== SImode
|| mode
== SFmode
)
4669 return "cldf%I3%U3 %M3, %2, %1, %e0";
4672 else if (ZERO_P (src
))
4673 return "cmovgf %., %2, %1, %e0";
4677 else if (GET_CODE (dest
) == MEM
)
4679 if (GET_CODE (src
) == REG
)
4681 int src_regno
= REGNO (src
);
4682 machine_mode mode
= GET_MODE (dest
);
4684 if (GPR_P (src_regno
))
4692 return "cstb%I2%U2 %3, %M2, %1, %e0";
4695 return "csth%I2%U2 %3, %M2, %1, %e0";
4699 return "cst%I2%U2 %3, %M2, %1, %e0";
4703 else if (FPR_P (src_regno
) && (mode
== SImode
|| mode
== SFmode
))
4704 return "cstf%I2%U2 %3, %M2, %1, %e0";
4707 else if (ZERO_P (src
))
4709 machine_mode mode
= GET_MODE (dest
);
4716 return "cstb%I2%U2 %., %M2, %1, %e0";
4719 return "csth%I2%U2 %., %M2, %1, %e0";
4723 return "cst%I2%U2 %., %M2, %1, %e0";
4728 fatal_insn ("bad output_condmove_single operand", insn
);
4733 /* Emit the appropriate code to do a comparison, returning the register the
4734 comparison was done it. */
4737 frv_emit_comparison (enum rtx_code test
, rtx op0
, rtx op1
)
4739 machine_mode cc_mode
;
4742 /* Floating point doesn't have comparison against a constant. */
4743 if (GET_MODE (op0
) == CC_FPmode
&& GET_CODE (op1
) != REG
)
4744 op1
= force_reg (GET_MODE (op0
), op1
);
4746 /* Possibly disable using anything but a fixed register in order to work
4747 around cse moving comparisons past function calls. */
4748 cc_mode
= SELECT_CC_MODE (test
, op0
, op1
);
4749 cc_reg
= ((TARGET_ALLOC_CC
)
4750 ? gen_reg_rtx (cc_mode
)
4751 : gen_rtx_REG (cc_mode
,
4752 (cc_mode
== CC_FPmode
) ? FCC_FIRST
: ICC_FIRST
));
4754 emit_insn (gen_rtx_SET (cc_reg
, gen_rtx_COMPARE (cc_mode
, op0
, op1
)));
4760 /* Emit code for a conditional branch.
4761 XXX: I originally wanted to add a clobber of a CCR register to use in
4762 conditional execution, but that confuses the rest of the compiler. */
4765 frv_emit_cond_branch (rtx operands
[])
4770 enum rtx_code test
= GET_CODE (operands
[0]);
4771 rtx cc_reg
= frv_emit_comparison (test
, operands
[1], operands
[2]);
4772 machine_mode cc_mode
= GET_MODE (cc_reg
);
4774 /* Branches generate:
4776 (if_then_else (<test>, <cc_reg>, (const_int 0))
4777 (label_ref <branch_label>)
4779 label_ref
= gen_rtx_LABEL_REF (VOIDmode
, operands
[3]);
4780 test_rtx
= gen_rtx_fmt_ee (test
, cc_mode
, cc_reg
, const0_rtx
);
4781 if_else
= gen_rtx_IF_THEN_ELSE (cc_mode
, test_rtx
, label_ref
, pc_rtx
);
4782 emit_jump_insn (gen_rtx_SET (pc_rtx
, if_else
));
4787 /* Emit code to set a gpr to 1/0 based on a comparison. */
4790 frv_emit_scc (rtx operands
[])
4796 enum rtx_code test
= GET_CODE (operands
[1]);
4797 rtx cc_reg
= frv_emit_comparison (test
, operands
[2], operands
[3]);
4799 /* SCC instructions generate:
4800 (parallel [(set <target> (<test>, <cc_reg>, (const_int 0))
4801 (clobber (<ccr_reg>))]) */
4802 test_rtx
= gen_rtx_fmt_ee (test
, SImode
, cc_reg
, const0_rtx
);
4803 set
= gen_rtx_SET (operands
[0], test_rtx
);
4805 cr_reg
= ((TARGET_ALLOC_CC
)
4806 ? gen_reg_rtx (CC_CCRmode
)
4807 : gen_rtx_REG (CC_CCRmode
,
4808 ((GET_MODE (cc_reg
) == CC_FPmode
)
4812 clobber
= gen_rtx_CLOBBER (VOIDmode
, cr_reg
);
4813 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, set
, clobber
)));
4818 /* Split a SCC instruction into component parts, returning a SEQUENCE to hold
4819 the separate insns. */
4822 frv_split_scc (rtx dest
, rtx test
, rtx cc_reg
, rtx cr_reg
, HOST_WIDE_INT value
)
4828 /* Set the appropriate CCR bit. */
4829 emit_insn (gen_rtx_SET (cr_reg
,
4830 gen_rtx_fmt_ee (GET_CODE (test
),
4835 /* Move the value into the destination. */
4836 emit_move_insn (dest
, GEN_INT (value
));
4838 /* Move 0 into the destination if the test failed */
4839 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
4840 gen_rtx_EQ (GET_MODE (cr_reg
),
4843 gen_rtx_SET (dest
, const0_rtx
)));
4845 /* Finish up, return sequence. */
4852 /* Emit the code for a conditional move, return TRUE if we could do the
4856 frv_emit_cond_move (rtx dest
, rtx test_rtx
, rtx src1
, rtx src2
)
4863 enum rtx_code test
= GET_CODE (test_rtx
);
4864 rtx cc_reg
= frv_emit_comparison (test
,
4865 XEXP (test_rtx
, 0), XEXP (test_rtx
, 1));
4866 machine_mode cc_mode
= GET_MODE (cc_reg
);
4868 /* Conditional move instructions generate:
4869 (parallel [(set <target>
4870 (if_then_else (<test> <cc_reg> (const_int 0))
4873 (clobber (<ccr_reg>))]) */
4875 /* Handle various cases of conditional move involving two constants. */
4876 if (GET_CODE (src1
) == CONST_INT
&& GET_CODE (src2
) == CONST_INT
)
4878 HOST_WIDE_INT value1
= INTVAL (src1
);
4879 HOST_WIDE_INT value2
= INTVAL (src2
);
4881 /* Having 0 as one of the constants can be done by loading the other
4882 constant, and optionally moving in gr0. */
4883 if (value1
== 0 || value2
== 0)
4886 /* If the first value is within an addi range and also the difference
4887 between the two fits in an addi's range, load up the difference, then
4888 conditionally move in 0, and then unconditionally add the first
4890 else if (IN_RANGE (value1
, -2048, 2047)
4891 && IN_RANGE (value2
- value1
, -2048, 2047))
4894 /* If neither condition holds, just force the constant into a
4898 src1
= force_reg (GET_MODE (dest
), src1
);
4899 src2
= force_reg (GET_MODE (dest
), src2
);
4903 /* If one value is a register, insure the other value is either 0 or a
4907 if (GET_CODE (src1
) == CONST_INT
&& INTVAL (src1
) != 0)
4908 src1
= force_reg (GET_MODE (dest
), src1
);
4910 if (GET_CODE (src2
) == CONST_INT
&& INTVAL (src2
) != 0)
4911 src2
= force_reg (GET_MODE (dest
), src2
);
4914 test2
= gen_rtx_fmt_ee (test
, cc_mode
, cc_reg
, const0_rtx
);
4915 if_rtx
= gen_rtx_IF_THEN_ELSE (GET_MODE (dest
), test2
, src1
, src2
);
4917 set
= gen_rtx_SET (dest
, if_rtx
);
4919 cr_reg
= ((TARGET_ALLOC_CC
)
4920 ? gen_reg_rtx (CC_CCRmode
)
4921 : gen_rtx_REG (CC_CCRmode
,
4922 (cc_mode
== CC_FPmode
) ? FCR_FIRST
: ICR_FIRST
));
4924 clobber_cc
= gen_rtx_CLOBBER (VOIDmode
, cr_reg
);
4925 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, set
, clobber_cc
)));
4930 /* Split a conditional move into constituent parts, returning a SEQUENCE
4931 containing all of the insns. */
4934 frv_split_cond_move (rtx operands
[])
4936 rtx dest
= operands
[0];
4937 rtx test
= operands
[1];
4938 rtx cc_reg
= operands
[2];
4939 rtx src1
= operands
[3];
4940 rtx src2
= operands
[4];
4941 rtx cr_reg
= operands
[5];
4943 machine_mode cr_mode
= GET_MODE (cr_reg
);
4947 /* Set the appropriate CCR bit. */
4948 emit_insn (gen_rtx_SET (cr_reg
,
4949 gen_rtx_fmt_ee (GET_CODE (test
),
4954 /* Handle various cases of conditional move involving two constants. */
4955 if (GET_CODE (src1
) == CONST_INT
&& GET_CODE (src2
) == CONST_INT
)
4957 HOST_WIDE_INT value1
= INTVAL (src1
);
4958 HOST_WIDE_INT value2
= INTVAL (src2
);
4960 /* Having 0 as one of the constants can be done by loading the other
4961 constant, and optionally moving in gr0. */
4964 emit_move_insn (dest
, src2
);
4965 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
4966 gen_rtx_NE (cr_mode
, cr_reg
,
4968 gen_rtx_SET (dest
, src1
)));
4971 else if (value2
== 0)
4973 emit_move_insn (dest
, src1
);
4974 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
4975 gen_rtx_EQ (cr_mode
, cr_reg
,
4977 gen_rtx_SET (dest
, src2
)));
4980 /* If the first value is within an addi range and also the difference
4981 between the two fits in an addi's range, load up the difference, then
4982 conditionally move in 0, and then unconditionally add the first
4984 else if (IN_RANGE (value1
, -2048, 2047)
4985 && IN_RANGE (value2
- value1
, -2048, 2047))
4987 rtx dest_si
= ((GET_MODE (dest
) == SImode
)
4989 : gen_rtx_SUBREG (SImode
, dest
, 0));
4991 emit_move_insn (dest_si
, GEN_INT (value2
- value1
));
4992 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
4993 gen_rtx_NE (cr_mode
, cr_reg
,
4995 gen_rtx_SET (dest_si
, const0_rtx
)));
4996 emit_insn (gen_addsi3 (dest_si
, dest_si
, src1
));
5004 /* Emit the conditional move for the test being true if needed. */
5005 if (! rtx_equal_p (dest
, src1
))
5006 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
5007 gen_rtx_NE (cr_mode
, cr_reg
, const0_rtx
),
5008 gen_rtx_SET (dest
, src1
)));
5010 /* Emit the conditional move for the test being false if needed. */
5011 if (! rtx_equal_p (dest
, src2
))
5012 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
5013 gen_rtx_EQ (cr_mode
, cr_reg
, const0_rtx
),
5014 gen_rtx_SET (dest
, src2
)));
5017 /* Finish up, return sequence. */
5024 /* Split (set DEST SOURCE), where DEST is a double register and SOURCE is a
5025 memory location that is not known to be dword-aligned. */
5027 frv_split_double_load (rtx dest
, rtx source
)
5029 int regno
= REGNO (dest
);
5030 rtx dest1
= gen_highpart (SImode
, dest
);
5031 rtx dest2
= gen_lowpart (SImode
, dest
);
5032 rtx address
= XEXP (source
, 0);
5034 /* If the address is pre-modified, load the lower-numbered register
5035 first, then load the other register using an integer offset from
5036 the modified base register. This order should always be safe,
5037 since the pre-modification cannot affect the same registers as the
5040 The situation for other loads is more complicated. Loading one
5041 of the registers could affect the value of ADDRESS, so we must
5042 be careful which order we do them in. */
5043 if (GET_CODE (address
) == PRE_MODIFY
5044 || ! refers_to_regno_p (regno
, address
))
5046 /* It is safe to load the lower-numbered register first. */
5047 emit_move_insn (dest1
, change_address (source
, SImode
, NULL
));
5048 emit_move_insn (dest2
, frv_index_memory (source
, SImode
, 1));
5052 /* ADDRESS is not pre-modified and the address depends on the
5053 lower-numbered register. Load the higher-numbered register
5055 emit_move_insn (dest2
, frv_index_memory (source
, SImode
, 1));
5056 emit_move_insn (dest1
, change_address (source
, SImode
, NULL
));
5060 /* Split (set DEST SOURCE), where DEST refers to a dword memory location
5061 and SOURCE is either a double register or the constant zero. */
5063 frv_split_double_store (rtx dest
, rtx source
)
5065 rtx dest1
= change_address (dest
, SImode
, NULL
);
5066 rtx dest2
= frv_index_memory (dest
, SImode
, 1);
5067 if (ZERO_P (source
))
5069 emit_move_insn (dest1
, CONST0_RTX (SImode
));
5070 emit_move_insn (dest2
, CONST0_RTX (SImode
));
5074 emit_move_insn (dest1
, gen_highpart (SImode
, source
));
5075 emit_move_insn (dest2
, gen_lowpart (SImode
, source
));
5080 /* Split a min/max operation returning a SEQUENCE containing all of the
5084 frv_split_minmax (rtx operands
[])
5086 rtx dest
= operands
[0];
5087 rtx minmax
= operands
[1];
5088 rtx src1
= operands
[2];
5089 rtx src2
= operands
[3];
5090 rtx cc_reg
= operands
[4];
5091 rtx cr_reg
= operands
[5];
5093 enum rtx_code test_code
;
5094 machine_mode cr_mode
= GET_MODE (cr_reg
);
5098 /* Figure out which test to use. */
5099 switch (GET_CODE (minmax
))
5104 case SMIN
: test_code
= LT
; break;
5105 case SMAX
: test_code
= GT
; break;
5106 case UMIN
: test_code
= LTU
; break;
5107 case UMAX
: test_code
= GTU
; break;
5110 /* Issue the compare instruction. */
5111 emit_insn (gen_rtx_SET (cc_reg
, gen_rtx_COMPARE (GET_MODE (cc_reg
),
5114 /* Set the appropriate CCR bit. */
5115 emit_insn (gen_rtx_SET (cr_reg
, gen_rtx_fmt_ee (test_code
,
5120 /* If are taking the min/max of a nonzero constant, load that first, and
5121 then do a conditional move of the other value. */
5122 if (GET_CODE (src2
) == CONST_INT
&& INTVAL (src2
) != 0)
5124 gcc_assert (!rtx_equal_p (dest
, src1
));
5126 emit_move_insn (dest
, src2
);
5127 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
5128 gen_rtx_NE (cr_mode
, cr_reg
, const0_rtx
),
5129 gen_rtx_SET (dest
, src1
)));
5132 /* Otherwise, do each half of the move. */
5135 /* Emit the conditional move for the test being true if needed. */
5136 if (! rtx_equal_p (dest
, src1
))
5137 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
5138 gen_rtx_NE (cr_mode
, cr_reg
, const0_rtx
),
5139 gen_rtx_SET (dest
, src1
)));
5141 /* Emit the conditional move for the test being false if needed. */
5142 if (! rtx_equal_p (dest
, src2
))
5143 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
5144 gen_rtx_EQ (cr_mode
, cr_reg
, const0_rtx
),
5145 gen_rtx_SET (dest
, src2
)));
5148 /* Finish up, return sequence. */
5155 /* Split an integer abs operation returning a SEQUENCE containing all of the
5159 frv_split_abs (rtx operands
[])
5161 rtx dest
= operands
[0];
5162 rtx src
= operands
[1];
5163 rtx cc_reg
= operands
[2];
5164 rtx cr_reg
= operands
[3];
5169 /* Issue the compare < 0 instruction. */
5170 emit_insn (gen_rtx_SET (cc_reg
, gen_rtx_COMPARE (CCmode
, src
, const0_rtx
)));
5172 /* Set the appropriate CCR bit. */
5173 emit_insn (gen_rtx_SET (cr_reg
, gen_rtx_fmt_ee (LT
, CC_CCRmode
,
5174 cc_reg
, const0_rtx
)));
5176 /* Emit the conditional negate if the value is negative. */
5177 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
5178 gen_rtx_NE (CC_CCRmode
, cr_reg
, const0_rtx
),
5179 gen_negsi2 (dest
, src
)));
5181 /* Emit the conditional move for the test being false if needed. */
5182 if (! rtx_equal_p (dest
, src
))
5183 emit_insn (gen_rtx_COND_EXEC (VOIDmode
,
5184 gen_rtx_EQ (CC_CCRmode
, cr_reg
, const0_rtx
),
5185 gen_rtx_SET (dest
, src
)));
5187 /* Finish up, return sequence. */
5194 /* Initialize machine-specific if-conversion data.
5195 On the FR-V, we don't have any extra fields per se, but it is useful hook to
5196 initialize the static storage. */
5198 frv_ifcvt_machdep_init (void *ce_info ATTRIBUTE_UNUSED
)
5200 frv_ifcvt
.added_insns_list
= NULL_RTX
;
5201 frv_ifcvt
.cur_scratch_regs
= 0;
5202 frv_ifcvt
.num_nested_cond_exec
= 0;
5203 frv_ifcvt
.cr_reg
= NULL_RTX
;
5204 frv_ifcvt
.nested_cc_reg
= NULL_RTX
;
5205 frv_ifcvt
.extra_int_cr
= NULL_RTX
;
5206 frv_ifcvt
.extra_fp_cr
= NULL_RTX
;
5207 frv_ifcvt
.last_nested_if_cr
= NULL_RTX
;
5211 /* Internal function to add a potential insn to the list of insns to be inserted
5212 if the conditional execution conversion is successful. */
5215 frv_ifcvt_add_insn (rtx pattern
, rtx insn
, int before_p
)
5217 rtx link
= alloc_EXPR_LIST (VOIDmode
, pattern
, insn
);
5219 link
->jump
= before_p
; /* Mark to add this before or after insn. */
5220 frv_ifcvt
.added_insns_list
= alloc_EXPR_LIST (VOIDmode
, link
,
5221 frv_ifcvt
.added_insns_list
);
5223 if (TARGET_DEBUG_COND_EXEC
)
5226 "\n:::::::::: frv_ifcvt_add_insn: add the following %s insn %d:\n",
5227 (before_p
) ? "before" : "after",
5228 (int)INSN_UID (insn
));
5230 debug_rtx (pattern
);
5235 /* A C expression to modify the code described by the conditional if
5236 information CE_INFO, possibly updating the tests in TRUE_EXPR, and
5237 FALSE_EXPR for converting if-then and if-then-else code to conditional
5238 instructions. Set either TRUE_EXPR or FALSE_EXPR to a null pointer if the
5239 tests cannot be converted. */
5242 frv_ifcvt_modify_tests (ce_if_block
*ce_info
, rtx
*p_true
, rtx
*p_false
)
5244 basic_block test_bb
= ce_info
->test_bb
; /* test basic block */
5245 basic_block then_bb
= ce_info
->then_bb
; /* THEN */
5246 basic_block else_bb
= ce_info
->else_bb
; /* ELSE or NULL */
5247 basic_block join_bb
= ce_info
->join_bb
; /* join block or NULL */
5248 rtx true_expr
= *p_true
;
5252 machine_mode mode
= GET_MODE (true_expr
);
5256 frv_tmp_reg_t
*tmp_reg
= &frv_ifcvt
.tmp_reg
;
5258 rtx sub_cond_exec_reg
;
5260 enum rtx_code code_true
;
5261 enum rtx_code code_false
;
5262 enum reg_class cc_class
;
5263 enum reg_class cr_class
;
5266 reg_set_iterator rsi
;
5268 /* Make sure we are only dealing with hard registers. Also honor the
5269 -mno-cond-exec switch, and -mno-nested-cond-exec switches if
5271 if (!reload_completed
|| !TARGET_COND_EXEC
5272 || (!TARGET_NESTED_CE
&& ce_info
->pass
> 1))
5275 /* Figure out which registers we can allocate for our own purposes. Only
5276 consider registers that are not preserved across function calls and are
5277 not fixed. However, allow the ICC/ICR temporary registers to be allocated
5278 if we did not need to use them in reloading other registers. */
5279 memset (&tmp_reg
->regs
, 0, sizeof (tmp_reg
->regs
));
5280 COPY_HARD_REG_SET (tmp_reg
->regs
, call_used_reg_set
);
5281 AND_COMPL_HARD_REG_SET (tmp_reg
->regs
, fixed_reg_set
);
5282 SET_HARD_REG_BIT (tmp_reg
->regs
, ICC_TEMP
);
5283 SET_HARD_REG_BIT (tmp_reg
->regs
, ICR_TEMP
);
5285 /* If this is a nested IF, we need to discover whether the CC registers that
5286 are set/used inside of the block are used anywhere else. If not, we can
5287 change them to be the CC register that is paired with the CR register that
5288 controls the outermost IF block. */
5289 if (ce_info
->pass
> 1)
5291 CLEAR_HARD_REG_SET (frv_ifcvt
.nested_cc_ok_rewrite
);
5292 for (j
= CC_FIRST
; j
<= CC_LAST
; j
++)
5293 if (TEST_HARD_REG_BIT (tmp_reg
->regs
, j
))
5295 if (REGNO_REG_SET_P (df_get_live_in (then_bb
), j
))
5299 && REGNO_REG_SET_P (df_get_live_in (else_bb
), j
))
5303 && REGNO_REG_SET_P (df_get_live_in (join_bb
), j
))
5306 SET_HARD_REG_BIT (frv_ifcvt
.nested_cc_ok_rewrite
, j
);
5310 for (j
= 0; j
< frv_ifcvt
.cur_scratch_regs
; j
++)
5311 frv_ifcvt
.scratch_regs
[j
] = NULL_RTX
;
5313 frv_ifcvt
.added_insns_list
= NULL_RTX
;
5314 frv_ifcvt
.cur_scratch_regs
= 0;
5316 bb
= (basic_block
*) alloca ((2 + ce_info
->num_multiple_test_blocks
)
5317 * sizeof (basic_block
));
5323 /* Remove anything live at the beginning of the join block from being
5324 available for allocation. */
5325 EXECUTE_IF_SET_IN_REG_SET (df_get_live_in (join_bb
), 0, regno
, rsi
)
5327 if (regno
< FIRST_PSEUDO_REGISTER
)
5328 CLEAR_HARD_REG_BIT (tmp_reg
->regs
, regno
);
5332 /* Add in all of the blocks in multiple &&/|| blocks to be scanned. */
5334 if (ce_info
->num_multiple_test_blocks
)
5336 basic_block multiple_test_bb
= ce_info
->last_test_bb
;
5338 while (multiple_test_bb
!= test_bb
)
5340 bb
[num_bb
++] = multiple_test_bb
;
5341 multiple_test_bb
= EDGE_PRED (multiple_test_bb
, 0)->src
;
5345 /* Add in the THEN and ELSE blocks to be scanned. */
5346 bb
[num_bb
++] = then_bb
;
5348 bb
[num_bb
++] = else_bb
;
5350 sub_cond_exec_reg
= NULL_RTX
;
5351 frv_ifcvt
.num_nested_cond_exec
= 0;
5353 /* Scan all of the blocks for registers that must not be allocated. */
5354 for (j
= 0; j
< num_bb
; j
++)
5356 rtx_insn
*last_insn
= BB_END (bb
[j
]);
5357 rtx_insn
*insn
= BB_HEAD (bb
[j
]);
5361 fprintf (dump_file
, "Scanning %s block %d, start %d, end %d\n",
5362 (bb
[j
] == else_bb
) ? "else" : ((bb
[j
] == then_bb
) ? "then" : "test"),
5364 (int) INSN_UID (BB_HEAD (bb
[j
])),
5365 (int) INSN_UID (BB_END (bb
[j
])));
5367 /* Anything live at the beginning of the block is obviously unavailable
5369 EXECUTE_IF_SET_IN_REG_SET (df_get_live_in (bb
[j
]), 0, regno
, rsi
)
5371 if (regno
< FIRST_PSEUDO_REGISTER
)
5372 CLEAR_HARD_REG_BIT (tmp_reg
->regs
, regno
);
5375 /* Loop through the insns in the block. */
5378 /* Mark any new registers that are created as being unavailable for
5379 allocation. Also see if the CC register used in nested IFs can be
5385 int skip_nested_if
= FALSE
;
5386 HARD_REG_SET mentioned_regs
;
5388 CLEAR_HARD_REG_SET (mentioned_regs
);
5389 find_all_hard_regs (PATTERN (insn
), &mentioned_regs
);
5390 AND_COMPL_HARD_REG_SET (tmp_reg
->regs
, mentioned_regs
);
5392 pattern
= PATTERN (insn
);
5393 if (GET_CODE (pattern
) == COND_EXEC
)
5395 rtx reg
= XEXP (COND_EXEC_TEST (pattern
), 0);
5397 if (reg
!= sub_cond_exec_reg
)
5399 sub_cond_exec_reg
= reg
;
5400 frv_ifcvt
.num_nested_cond_exec
++;
5404 set
= single_set_pattern (pattern
);
5407 rtx dest
= SET_DEST (set
);
5408 rtx src
= SET_SRC (set
);
5410 if (GET_CODE (dest
) == REG
)
5412 int regno
= REGNO (dest
);
5413 enum rtx_code src_code
= GET_CODE (src
);
5415 if (CC_P (regno
) && src_code
== COMPARE
)
5416 skip_nested_if
= TRUE
;
5418 else if (CR_P (regno
)
5419 && (src_code
== IF_THEN_ELSE
5420 || COMPARISON_P (src
)))
5421 skip_nested_if
= TRUE
;
5425 if (! skip_nested_if
)
5426 AND_COMPL_HARD_REG_SET (frv_ifcvt
.nested_cc_ok_rewrite
,
5430 if (insn
== last_insn
)
5433 insn
= NEXT_INSN (insn
);
5437 /* If this is a nested if, rewrite the CC registers that are available to
5438 include the ones that can be rewritten, to increase the chance of being
5439 able to allocate a paired CC/CR register combination. */
5440 if (ce_info
->pass
> 1)
5442 for (j
= CC_FIRST
; j
<= CC_LAST
; j
++)
5443 if (TEST_HARD_REG_BIT (frv_ifcvt
.nested_cc_ok_rewrite
, j
))
5444 SET_HARD_REG_BIT (tmp_reg
->regs
, j
);
5446 CLEAR_HARD_REG_BIT (tmp_reg
->regs
, j
);
5452 fprintf (dump_file
, "Available GPRs: ");
5454 for (j
= GPR_FIRST
; j
<= GPR_LAST
; j
++)
5455 if (TEST_HARD_REG_BIT (tmp_reg
->regs
, j
))
5457 fprintf (dump_file
, " %d [%s]", j
, reg_names
[j
]);
5458 if (++num_gprs
> GPR_TEMP_NUM
+2)
5462 fprintf (dump_file
, "%s\nAvailable CRs: ",
5463 (num_gprs
> GPR_TEMP_NUM
+2) ? " ..." : "");
5465 for (j
= CR_FIRST
; j
<= CR_LAST
; j
++)
5466 if (TEST_HARD_REG_BIT (tmp_reg
->regs
, j
))
5467 fprintf (dump_file
, " %d [%s]", j
, reg_names
[j
]);
5469 fputs ("\n", dump_file
);
5471 if (ce_info
->pass
> 1)
5473 fprintf (dump_file
, "Modifiable CCs: ");
5474 for (j
= CC_FIRST
; j
<= CC_LAST
; j
++)
5475 if (TEST_HARD_REG_BIT (tmp_reg
->regs
, j
))
5476 fprintf (dump_file
, " %d [%s]", j
, reg_names
[j
]);
5478 fprintf (dump_file
, "\n%d nested COND_EXEC statements\n",
5479 frv_ifcvt
.num_nested_cond_exec
);
5483 /* Allocate the appropriate temporary condition code register. Try to
5484 allocate the ICR/FCR register that corresponds to the ICC/FCC register so
5485 that conditional cmp's can be done. */
5486 if (mode
== CCmode
|| mode
== CC_UNSmode
|| mode
== CC_NZmode
)
5488 cr_class
= ICR_REGS
;
5489 cc_class
= ICC_REGS
;
5490 cc_first
= ICC_FIRST
;
5493 else if (mode
== CC_FPmode
)
5495 cr_class
= FCR_REGS
;
5496 cc_class
= FCC_REGS
;
5497 cc_first
= FCC_FIRST
;
5502 cc_first
= cc_last
= 0;
5503 cr_class
= cc_class
= NO_REGS
;
5506 cc
= XEXP (true_expr
, 0);
5507 nested_cc
= cr
= NULL_RTX
;
5508 if (cc_class
!= NO_REGS
)
5510 /* For nested IFs and &&/||, see if we can find a CC and CR register pair
5511 so we can execute a csubcc/caddcc/cfcmps instruction. */
5514 for (cc_regno
= cc_first
; cc_regno
<= cc_last
; cc_regno
++)
5516 int cr_regno
= cc_regno
- CC_FIRST
+ CR_FIRST
;
5518 if (TEST_HARD_REG_BIT (frv_ifcvt
.tmp_reg
.regs
, cc_regno
)
5519 && TEST_HARD_REG_BIT (frv_ifcvt
.tmp_reg
.regs
, cr_regno
))
5521 frv_ifcvt
.tmp_reg
.next_reg
[ (int)cr_class
] = cr_regno
;
5522 cr
= frv_alloc_temp_reg (tmp_reg
, cr_class
, CC_CCRmode
, TRUE
,
5525 frv_ifcvt
.tmp_reg
.next_reg
[ (int)cc_class
] = cc_regno
;
5526 nested_cc
= frv_alloc_temp_reg (tmp_reg
, cc_class
, CCmode
,
5536 fprintf (dump_file
, "Could not allocate a CR temporary register\n");
5543 "Will use %s for conditional execution, %s for nested comparisons\n",
5544 reg_names
[ REGNO (cr
)],
5545 (nested_cc
) ? reg_names
[ REGNO (nested_cc
) ] : "<none>");
5547 /* Set the CCR bit. Note for integer tests, we reverse the condition so that
5548 in an IF-THEN-ELSE sequence, we are testing the TRUE case against the CCR
5549 bit being true. We don't do this for floating point, because of NaNs. */
5550 code
= GET_CODE (true_expr
);
5551 if (GET_MODE (cc
) != CC_FPmode
)
5553 code
= reverse_condition (code
);
5563 check_insn
= gen_rtx_SET (cr
, gen_rtx_fmt_ee (code
, CC_CCRmode
,
5566 /* Record the check insn to be inserted later. */
5567 frv_ifcvt_add_insn (check_insn
, BB_END (test_bb
), TRUE
);
5569 /* Update the tests. */
5570 frv_ifcvt
.cr_reg
= cr
;
5571 frv_ifcvt
.nested_cc_reg
= nested_cc
;
5572 *p_true
= gen_rtx_fmt_ee (code_true
, CC_CCRmode
, cr
, const0_rtx
);
5573 *p_false
= gen_rtx_fmt_ee (code_false
, CC_CCRmode
, cr
, const0_rtx
);
5576 /* Fail, don't do this conditional execution. */
5579 *p_false
= NULL_RTX
;
5581 fprintf (dump_file
, "Disabling this conditional execution.\n");
5587 /* A C expression to modify the code described by the conditional if
5588 information CE_INFO, for the basic block BB, possibly updating the tests in
5589 TRUE_EXPR, and FALSE_EXPR for converting the && and || parts of if-then or
5590 if-then-else code to conditional instructions. Set either TRUE_EXPR or
5591 FALSE_EXPR to a null pointer if the tests cannot be converted. */
5593 /* p_true and p_false are given expressions of the form:
5595 (and (eq:CC_CCR (reg:CC_CCR)
5601 frv_ifcvt_modify_multiple_tests (ce_if_block
*ce_info
,
5606 rtx old_true
= XEXP (*p_true
, 0);
5607 rtx old_false
= XEXP (*p_false
, 0);
5608 rtx true_expr
= XEXP (*p_true
, 1);
5609 rtx false_expr
= XEXP (*p_false
, 1);
5612 rtx cr
= XEXP (old_true
, 0);
5614 rtx new_cr
= NULL_RTX
;
5615 rtx
*p_new_cr
= (rtx
*)0;
5619 enum reg_class cr_class
;
5620 machine_mode mode
= GET_MODE (true_expr
);
5621 rtx (*logical_func
)(rtx
, rtx
, rtx
);
5623 if (TARGET_DEBUG_COND_EXEC
)
5626 "\n:::::::::: frv_ifcvt_modify_multiple_tests, before modification for %s\ntrue insn:\n",
5627 ce_info
->and_and_p
? "&&" : "||");
5629 debug_rtx (*p_true
);
5631 fputs ("\nfalse insn:\n", stderr
);
5632 debug_rtx (*p_false
);
5635 if (!TARGET_MULTI_CE
)
5638 if (GET_CODE (cr
) != REG
)
5641 if (mode
== CCmode
|| mode
== CC_UNSmode
|| mode
== CC_NZmode
)
5643 cr_class
= ICR_REGS
;
5644 p_new_cr
= &frv_ifcvt
.extra_int_cr
;
5646 else if (mode
== CC_FPmode
)
5648 cr_class
= FCR_REGS
;
5649 p_new_cr
= &frv_ifcvt
.extra_fp_cr
;
5654 /* Allocate a temp CR, reusing a previously allocated temp CR if we have 3 or
5655 more &&/|| tests. */
5659 new_cr
= *p_new_cr
= frv_alloc_temp_reg (&frv_ifcvt
.tmp_reg
, cr_class
,
5660 CC_CCRmode
, TRUE
, TRUE
);
5665 if (ce_info
->and_and_p
)
5667 old_test
= old_false
;
5668 test_expr
= true_expr
;
5669 logical_func
= (GET_CODE (old_true
) == EQ
) ? gen_andcr
: gen_andncr
;
5670 *p_true
= gen_rtx_NE (CC_CCRmode
, cr
, const0_rtx
);
5671 *p_false
= gen_rtx_EQ (CC_CCRmode
, cr
, const0_rtx
);
5675 old_test
= old_false
;
5676 test_expr
= false_expr
;
5677 logical_func
= (GET_CODE (old_false
) == EQ
) ? gen_orcr
: gen_orncr
;
5678 *p_true
= gen_rtx_EQ (CC_CCRmode
, cr
, const0_rtx
);
5679 *p_false
= gen_rtx_NE (CC_CCRmode
, cr
, const0_rtx
);
5682 /* First add the andcr/andncr/orcr/orncr, which will be added after the
5683 conditional check instruction, due to frv_ifcvt_add_insn being a LIFO
5685 frv_ifcvt_add_insn ((*logical_func
) (cr
, cr
, new_cr
), BB_END (bb
), TRUE
);
5687 /* Now add the conditional check insn. */
5688 cc
= XEXP (test_expr
, 0);
5689 compare
= gen_rtx_fmt_ee (GET_CODE (test_expr
), CC_CCRmode
, cc
, const0_rtx
);
5690 if_else
= gen_rtx_IF_THEN_ELSE (CC_CCRmode
, old_test
, compare
, const0_rtx
);
5692 check_insn
= gen_rtx_SET (new_cr
, if_else
);
5694 /* Add the new check insn to the list of check insns that need to be
5696 frv_ifcvt_add_insn (check_insn
, BB_END (bb
), TRUE
);
5698 if (TARGET_DEBUG_COND_EXEC
)
5700 fputs ("\n:::::::::: frv_ifcvt_modify_multiple_tests, after modification\ntrue insn:\n",
5703 debug_rtx (*p_true
);
5705 fputs ("\nfalse insn:\n", stderr
);
5706 debug_rtx (*p_false
);
5712 *p_true
= *p_false
= NULL_RTX
;
5714 /* If we allocated a CR register, release it. */
5717 CLEAR_HARD_REG_BIT (frv_ifcvt
.tmp_reg
.regs
, REGNO (new_cr
));
5718 *p_new_cr
= NULL_RTX
;
5721 if (TARGET_DEBUG_COND_EXEC
)
5722 fputs ("\n:::::::::: frv_ifcvt_modify_multiple_tests, failed.\n", stderr
);
5728 /* Return a register which will be loaded with a value if an IF block is
5729 converted to conditional execution. This is used to rewrite instructions
5730 that use constants to ones that just use registers. */
5733 frv_ifcvt_load_value (rtx value
, rtx insn ATTRIBUTE_UNUSED
)
5735 int num_alloc
= frv_ifcvt
.cur_scratch_regs
;
5739 /* We know gr0 == 0, so replace any errant uses. */
5740 if (value
== const0_rtx
)
5741 return gen_rtx_REG (SImode
, GPR_FIRST
);
5743 /* First search all registers currently loaded to see if we have an
5744 applicable constant. */
5745 if (CONSTANT_P (value
)
5746 || (GET_CODE (value
) == REG
&& REGNO (value
) == LR_REGNO
))
5748 for (i
= 0; i
< num_alloc
; i
++)
5750 if (rtx_equal_p (SET_SRC (frv_ifcvt
.scratch_regs
[i
]), value
))
5751 return SET_DEST (frv_ifcvt
.scratch_regs
[i
]);
5755 /* Have we exhausted the number of registers available? */
5756 if (num_alloc
>= GPR_TEMP_NUM
)
5759 fprintf (dump_file
, "Too many temporary registers allocated\n");
5764 /* Allocate the new register. */
5765 reg
= frv_alloc_temp_reg (&frv_ifcvt
.tmp_reg
, GPR_REGS
, SImode
, TRUE
, TRUE
);
5769 fputs ("Could not find a scratch register\n", dump_file
);
5774 frv_ifcvt
.cur_scratch_regs
++;
5775 frv_ifcvt
.scratch_regs
[num_alloc
] = gen_rtx_SET (reg
, value
);
5779 if (GET_CODE (value
) == CONST_INT
)
5780 fprintf (dump_file
, "Register %s will hold %ld\n",
5781 reg_names
[ REGNO (reg
)], (long)INTVAL (value
));
5783 else if (GET_CODE (value
) == REG
&& REGNO (value
) == LR_REGNO
)
5784 fprintf (dump_file
, "Register %s will hold LR\n",
5785 reg_names
[ REGNO (reg
)]);
5788 fprintf (dump_file
, "Register %s will hold a saved value\n",
5789 reg_names
[ REGNO (reg
)]);
5796 /* Update a MEM used in conditional code that might contain an offset to put
5797 the offset into a scratch register, so that the conditional load/store
5798 operations can be used. This function returns the original pointer if the
5799 MEM is valid to use in conditional code, NULL if we can't load up the offset
5800 into a temporary register, or the new MEM if we were successful. */
5803 frv_ifcvt_rewrite_mem (rtx mem
, machine_mode mode
, rtx insn
)
5805 rtx addr
= XEXP (mem
, 0);
5807 if (!frv_legitimate_address_p_1 (mode
, addr
, reload_completed
, TRUE
, FALSE
))
5809 if (GET_CODE (addr
) == PLUS
)
5811 rtx addr_op0
= XEXP (addr
, 0);
5812 rtx addr_op1
= XEXP (addr
, 1);
5814 if (GET_CODE (addr_op0
) == REG
&& CONSTANT_P (addr_op1
))
5816 rtx reg
= frv_ifcvt_load_value (addr_op1
, insn
);
5820 addr
= gen_rtx_PLUS (Pmode
, addr_op0
, reg
);
5827 else if (CONSTANT_P (addr
))
5828 addr
= frv_ifcvt_load_value (addr
, insn
);
5833 if (addr
== NULL_RTX
)
5836 else if (XEXP (mem
, 0) != addr
)
5837 return change_address (mem
, mode
, addr
);
5844 /* Given a PATTERN, return a SET expression if this PATTERN has only a single
5845 SET, possibly conditionally executed. It may also have CLOBBERs, USEs. */
5848 single_set_pattern (rtx pattern
)
5853 if (GET_CODE (pattern
) == COND_EXEC
)
5854 pattern
= COND_EXEC_CODE (pattern
);
5856 if (GET_CODE (pattern
) == SET
)
5859 else if (GET_CODE (pattern
) == PARALLEL
)
5861 for (i
= 0, set
= 0; i
< XVECLEN (pattern
, 0); i
++)
5863 rtx sub
= XVECEXP (pattern
, 0, i
);
5865 switch (GET_CODE (sub
))
5889 /* A C expression to modify the code described by the conditional if
5890 information CE_INFO with the new PATTERN in INSN. If PATTERN is a null
5891 pointer after the IFCVT_MODIFY_INSN macro executes, it is assumed that that
5892 insn cannot be converted to be executed conditionally. */
5895 frv_ifcvt_modify_insn (ce_if_block
*ce_info
,
5899 rtx orig_ce_pattern
= pattern
;
5905 gcc_assert (GET_CODE (pattern
) == COND_EXEC
);
5907 test
= COND_EXEC_TEST (pattern
);
5908 if (GET_CODE (test
) == AND
)
5910 rtx cr
= frv_ifcvt
.cr_reg
;
5913 op0
= XEXP (test
, 0);
5914 if (! rtx_equal_p (cr
, XEXP (op0
, 0)))
5917 op1
= XEXP (test
, 1);
5918 test_reg
= XEXP (op1
, 0);
5919 if (GET_CODE (test_reg
) != REG
)
5922 /* Is this the first nested if block in this sequence? If so, generate
5923 an andcr or andncr. */
5924 if (! frv_ifcvt
.last_nested_if_cr
)
5928 frv_ifcvt
.last_nested_if_cr
= test_reg
;
5929 if (GET_CODE (op0
) == NE
)
5930 and_op
= gen_andcr (test_reg
, cr
, test_reg
);
5932 and_op
= gen_andncr (test_reg
, cr
, test_reg
);
5934 frv_ifcvt_add_insn (and_op
, insn
, TRUE
);
5937 /* If this isn't the first statement in the nested if sequence, see if we
5938 are dealing with the same register. */
5939 else if (! rtx_equal_p (test_reg
, frv_ifcvt
.last_nested_if_cr
))
5942 COND_EXEC_TEST (pattern
) = test
= op1
;
5945 /* If this isn't a nested if, reset state variables. */
5948 frv_ifcvt
.last_nested_if_cr
= NULL_RTX
;
5951 set
= single_set_pattern (pattern
);
5954 rtx dest
= SET_DEST (set
);
5955 rtx src
= SET_SRC (set
);
5956 machine_mode mode
= GET_MODE (dest
);
5958 /* Check for normal binary operators. */
5959 if (mode
== SImode
&& ARITHMETIC_P (src
))
5961 op0
= XEXP (src
, 0);
5962 op1
= XEXP (src
, 1);
5964 if (integer_register_operand (op0
, SImode
) && CONSTANT_P (op1
))
5966 op1
= frv_ifcvt_load_value (op1
, insn
);
5968 COND_EXEC_CODE (pattern
)
5969 = gen_rtx_SET (dest
, gen_rtx_fmt_ee (GET_CODE (src
),
5977 /* For multiply by a constant, we need to handle the sign extending
5978 correctly. Add a USE of the value after the multiply to prevent flow
5979 from cratering because only one register out of the two were used. */
5980 else if (mode
== DImode
&& GET_CODE (src
) == MULT
)
5982 op0
= XEXP (src
, 0);
5983 op1
= XEXP (src
, 1);
5984 if (GET_CODE (op0
) == SIGN_EXTEND
&& GET_CODE (op1
) == CONST_INT
)
5986 op1
= frv_ifcvt_load_value (op1
, insn
);
5989 op1
= gen_rtx_SIGN_EXTEND (DImode
, op1
);
5990 COND_EXEC_CODE (pattern
)
5991 = gen_rtx_SET (dest
, gen_rtx_MULT (DImode
, op0
, op1
));
5997 frv_ifcvt_add_insn (gen_use (dest
), insn
, FALSE
);
6000 /* If we are just loading a constant created for a nested conditional
6001 execution statement, just load the constant without any conditional
6002 execution, since we know that the constant will not interfere with any
6004 else if (frv_ifcvt
.scratch_insns_bitmap
6005 && bitmap_bit_p (frv_ifcvt
.scratch_insns_bitmap
,
6007 && REG_P (SET_DEST (set
))
6008 /* We must not unconditionally set a scratch reg chosen
6009 for a nested if-converted block if its incoming
6010 value from the TEST block (or the result of the THEN
6011 branch) could/should propagate to the JOIN block.
6012 It suffices to test whether the register is live at
6013 the JOIN point: if it's live there, we can infer
6014 that we set it in the former JOIN block of the
6015 nested if-converted block (otherwise it wouldn't
6016 have been available as a scratch register), and it
6017 is either propagated through or set in the other
6018 conditional block. It's probably not worth trying
6019 to catch the latter case, and it could actually
6020 limit scheduling of the combined block quite
6023 && ! (REGNO_REG_SET_P (df_get_live_in (ce_info
->join_bb
),
6024 REGNO (SET_DEST (set
))))
6025 /* Similarly, we must not unconditionally set a reg
6026 used as scratch in the THEN branch if the same reg
6027 is live in the ELSE branch. */
6028 && (! ce_info
->else_bb
6029 || BLOCK_FOR_INSN (insn
) == ce_info
->else_bb
6030 || ! (REGNO_REG_SET_P (df_get_live_in (ce_info
->else_bb
),
6031 REGNO (SET_DEST (set
))))))
6034 else if (mode
== QImode
|| mode
== HImode
|| mode
== SImode
6037 int changed_p
= FALSE
;
6039 /* Check for just loading up a constant */
6040 if (CONSTANT_P (src
) && integer_register_operand (dest
, mode
))
6042 src
= frv_ifcvt_load_value (src
, insn
);
6049 /* See if we need to fix up stores */
6050 if (GET_CODE (dest
) == MEM
)
6052 rtx new_mem
= frv_ifcvt_rewrite_mem (dest
, mode
, insn
);
6057 else if (new_mem
!= dest
)
6064 /* See if we need to fix up loads */
6065 if (GET_CODE (src
) == MEM
)
6067 rtx new_mem
= frv_ifcvt_rewrite_mem (src
, mode
, insn
);
6072 else if (new_mem
!= src
)
6079 /* If either src or destination changed, redo SET. */
6081 COND_EXEC_CODE (pattern
) = gen_rtx_SET (dest
, src
);
6084 /* Rewrite a nested set cccr in terms of IF_THEN_ELSE. Also deal with
6085 rewriting the CC register to be the same as the paired CC/CR register
6087 else if (mode
== CC_CCRmode
&& COMPARISON_P (src
))
6089 int regno
= REGNO (XEXP (src
, 0));
6092 if (ce_info
->pass
> 1
6093 && regno
!= (int)REGNO (frv_ifcvt
.nested_cc_reg
)
6094 && TEST_HARD_REG_BIT (frv_ifcvt
.nested_cc_ok_rewrite
, regno
))
6096 src
= gen_rtx_fmt_ee (GET_CODE (src
),
6098 frv_ifcvt
.nested_cc_reg
,
6102 if_else
= gen_rtx_IF_THEN_ELSE (CC_CCRmode
, test
, src
, const0_rtx
);
6103 pattern
= gen_rtx_SET (dest
, if_else
);
6106 /* Remap a nested compare instruction to use the paired CC/CR reg. */
6107 else if (ce_info
->pass
> 1
6108 && GET_CODE (dest
) == REG
6109 && CC_P (REGNO (dest
))
6110 && REGNO (dest
) != REGNO (frv_ifcvt
.nested_cc_reg
)
6111 && TEST_HARD_REG_BIT (frv_ifcvt
.nested_cc_ok_rewrite
,
6113 && GET_CODE (src
) == COMPARE
)
6115 PUT_MODE (frv_ifcvt
.nested_cc_reg
, GET_MODE (dest
));
6116 COND_EXEC_CODE (pattern
)
6117 = gen_rtx_SET (frv_ifcvt
.nested_cc_reg
, copy_rtx (src
));
6121 if (TARGET_DEBUG_COND_EXEC
)
6123 rtx orig_pattern
= PATTERN (insn
);
6125 PATTERN (insn
) = pattern
;
6127 "\n:::::::::: frv_ifcvt_modify_insn: pass = %d, insn after modification:\n",
6131 PATTERN (insn
) = orig_pattern
;
6137 if (TARGET_DEBUG_COND_EXEC
)
6139 rtx orig_pattern
= PATTERN (insn
);
6141 PATTERN (insn
) = orig_ce_pattern
;
6143 "\n:::::::::: frv_ifcvt_modify_insn: pass = %d, insn could not be modified:\n",
6147 PATTERN (insn
) = orig_pattern
;
6154 /* A C expression to perform any final machine dependent modifications in
6155 converting code to conditional execution in the code described by the
6156 conditional if information CE_INFO. */
6159 frv_ifcvt_modify_final (ce_if_block
*ce_info ATTRIBUTE_UNUSED
)
6163 rtx p
= frv_ifcvt
.added_insns_list
;
6166 /* Loop inserting the check insns. The last check insn is the first test,
6167 and is the appropriate place to insert constants. */
6172 rtx check_and_insert_insns
= XEXP (p
, 0);
6175 check_insn
= XEXP (check_and_insert_insns
, 0);
6176 existing_insn
= XEXP (check_and_insert_insns
, 1);
6179 /* The jump bit is used to say that the new insn is to be inserted BEFORE
6180 the existing insn, otherwise it is to be inserted AFTER. */
6181 if (check_and_insert_insns
->jump
)
6183 emit_insn_before (check_insn
, existing_insn
);
6184 check_and_insert_insns
->jump
= 0;
6187 emit_insn_after (check_insn
, existing_insn
);
6189 free_EXPR_LIST_node (check_and_insert_insns
);
6190 free_EXPR_LIST_node (old_p
);
6192 while (p
!= NULL_RTX
);
6194 /* Load up any constants needed into temp gprs */
6195 for (i
= 0; i
< frv_ifcvt
.cur_scratch_regs
; i
++)
6197 rtx insn
= emit_insn_before (frv_ifcvt
.scratch_regs
[i
], existing_insn
);
6198 if (! frv_ifcvt
.scratch_insns_bitmap
)
6199 frv_ifcvt
.scratch_insns_bitmap
= BITMAP_ALLOC (NULL
);
6200 bitmap_set_bit (frv_ifcvt
.scratch_insns_bitmap
, INSN_UID (insn
));
6201 frv_ifcvt
.scratch_regs
[i
] = NULL_RTX
;
6204 frv_ifcvt
.added_insns_list
= NULL_RTX
;
6205 frv_ifcvt
.cur_scratch_regs
= 0;
6209 /* A C expression to cancel any machine dependent modifications in converting
6210 code to conditional execution in the code described by the conditional if
6211 information CE_INFO. */
6214 frv_ifcvt_modify_cancel (ce_if_block
*ce_info ATTRIBUTE_UNUSED
)
6217 rtx p
= frv_ifcvt
.added_insns_list
;
6219 /* Loop freeing up the EXPR_LIST's allocated. */
6220 while (p
!= NULL_RTX
)
6222 rtx check_and_jump
= XEXP (p
, 0);
6226 free_EXPR_LIST_node (check_and_jump
);
6227 free_EXPR_LIST_node (old_p
);
6230 /* Release any temporary gprs allocated. */
6231 for (i
= 0; i
< frv_ifcvt
.cur_scratch_regs
; i
++)
6232 frv_ifcvt
.scratch_regs
[i
] = NULL_RTX
;
6234 frv_ifcvt
.added_insns_list
= NULL_RTX
;
6235 frv_ifcvt
.cur_scratch_regs
= 0;
6239 /* A C expression for the size in bytes of the trampoline, as an integer.
6243 setlo #0, <static_chain>
6245 sethi #0, <static_chain>
6246 jmpl @(gr0,<jmp_reg>) */
6249 frv_trampoline_size (void)
6252 /* Allocate room for the function descriptor and the lddi
6255 return 5 /* instructions */ * 4 /* instruction size. */;
6259 /* A C statement to initialize the variable parts of a trampoline. ADDR is an
6260 RTX for the address of the trampoline; FNADDR is an RTX for the address of
6261 the nested function; STATIC_CHAIN is an RTX for the static chain value that
6262 should be passed to the function when it is called.
6267 setlo #0, <static_chain>
6269 sethi #0, <static_chain>
6270 jmpl @(gr0,<jmp_reg>) */
6273 frv_trampoline_init (rtx m_tramp
, tree fndecl
, rtx static_chain
)
6275 rtx addr
= XEXP (m_tramp
, 0);
6276 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
6277 rtx sc_reg
= force_reg (Pmode
, static_chain
);
6279 emit_library_call (gen_rtx_SYMBOL_REF (SImode
, "__trampoline_setup"),
6280 LCT_NORMAL
, VOIDmode
, 4,
6282 GEN_INT (frv_trampoline_size ()), SImode
,
6288 /* Many machines have some registers that cannot be copied directly to or from
6289 memory or even from other types of registers. An example is the `MQ'
6290 register, which on most machines, can only be copied to or from general
6291 registers, but not memory. Some machines allow copying all registers to and
6292 from memory, but require a scratch register for stores to some memory
6293 locations (e.g., those with symbolic address on the RT, and those with
6294 certain symbolic address on the SPARC when compiling PIC). In some cases,
6295 both an intermediate and a scratch register are required.
6297 You should define these macros to indicate to the reload phase that it may
6298 need to allocate at least one register for a reload in addition to the
6299 register to contain the data. Specifically, if copying X to a register
6300 RCLASS in MODE requires an intermediate register, you should define
6301 `SECONDARY_INPUT_RELOAD_CLASS' to return the largest register class all of
6302 whose registers can be used as intermediate registers or scratch registers.
6304 If copying a register RCLASS in MODE to X requires an intermediate or scratch
6305 register, `SECONDARY_OUTPUT_RELOAD_CLASS' should be defined to return the
6306 largest register class required. If the requirements for input and output
6307 reloads are the same, the macro `SECONDARY_RELOAD_CLASS' should be used
6308 instead of defining both macros identically.
6310 The values returned by these macros are often `GENERAL_REGS'. Return
6311 `NO_REGS' if no spare register is needed; i.e., if X can be directly copied
6312 to or from a register of RCLASS in MODE without requiring a scratch register.
6313 Do not define this macro if it would always return `NO_REGS'.
6315 If a scratch register is required (either with or without an intermediate
6316 register), you should define patterns for `reload_inM' or `reload_outM', as
6317 required.. These patterns, which will normally be implemented with a
6318 `define_expand', should be similar to the `movM' patterns, except that
6319 operand 2 is the scratch register.
6321 Define constraints for the reload register and scratch register that contain
6322 a single register class. If the original reload register (whose class is
6323 RCLASS) can meet the constraint given in the pattern, the value returned by
6324 these macros is used for the class of the scratch register. Otherwise, two
6325 additional reload registers are required. Their classes are obtained from
6326 the constraints in the insn pattern.
6328 X might be a pseudo-register or a `subreg' of a pseudo-register, which could
6329 either be in a hard register or in memory. Use `true_regnum' to find out;
6330 it will return -1 if the pseudo is in memory and the hard register number if
6331 it is in a register.
6333 These macros should not be used in the case where a particular class of
6334 registers can only be copied to memory and not to another class of
6335 registers. In that case, secondary reload registers are not needed and
6336 would not be helpful. Instead, a stack location must be used to perform the
6337 copy and the `movM' pattern should use memory as an intermediate storage.
6338 This case often occurs between floating-point and general registers. */
6341 frv_secondary_reload_class (enum reg_class rclass
,
6342 machine_mode mode ATTRIBUTE_UNUSED
,
6353 /* Accumulators/Accumulator guard registers need to go through floating
6358 if (x
&& GET_CODE (x
) == REG
)
6360 int regno
= REGNO (x
);
6362 if (ACC_P (regno
) || ACCG_P (regno
))
6367 /* Nonzero constants should be loaded into an FPR through a GPR. */
6369 if (x
&& CONSTANT_P (x
) && !ZERO_P (x
))
6375 /* All of these types need gpr registers. */
6387 /* The accumulators need fpr registers. */
6397 /* This hook exists to catch the case where secondary_reload_class() is
6398 called from init_reg_autoinc() in regclass.c - before the reload optabs
6399 have been initialised. */
6402 frv_secondary_reload (bool in_p
, rtx x
, reg_class_t reload_class_i
,
6403 machine_mode reload_mode
,
6404 secondary_reload_info
* sri
)
6406 enum reg_class rclass
= NO_REGS
;
6407 enum reg_class reload_class
= (enum reg_class
) reload_class_i
;
6409 if (sri
->prev_sri
&& sri
->prev_sri
->t_icode
!= CODE_FOR_nothing
)
6411 sri
->icode
= sri
->prev_sri
->t_icode
;
6415 rclass
= frv_secondary_reload_class (reload_class
, reload_mode
, x
);
6417 if (rclass
!= NO_REGS
)
6419 enum insn_code icode
6420 = direct_optab_handler (in_p
? reload_in_optab
: reload_out_optab
,
6424 /* This happens when then the reload_[in|out]_optabs have
6425 not been initialised. */
6426 sri
->t_icode
= CODE_FOR_nothing
;
6431 /* Fall back to the default secondary reload handler. */
6432 return default_secondary_reload (in_p
, x
, reload_class
, reload_mode
, sri
);
6436 /* Worker function for TARGET_CLASS_LIKELY_SPILLED_P. */
6439 frv_class_likely_spilled_p (reg_class_t rclass
)
6449 case FDPIC_FPTR_REGS
:
6469 /* An expression for the alignment of a structure field FIELD if the
6470 alignment computed in the usual way is COMPUTED. GCC uses this
6471 value instead of the value in `BIGGEST_ALIGNMENT' or
6472 `BIGGEST_FIELD_ALIGNMENT', if defined, for structure fields only. */
6474 /* The definition type of the bit field data is either char, short, long or
6475 long long. The maximum bit size is the number of bits of its own type.
6477 The bit field data is assigned to a storage unit that has an adequate size
6478 for bit field data retention and is located at the smallest address.
6480 Consecutive bit field data are packed at consecutive bits having the same
6481 storage unit, with regard to the type, beginning with the MSB and continuing
6484 If a field to be assigned lies over a bit field type boundary, its
6485 assignment is completed by aligning it with a boundary suitable for the
6488 When a bit field having a bit length of 0 is declared, it is forcibly
6489 assigned to the next storage unit.
6502 &x 00000000 00000000 00000000 00000000
6505 &x+4 00000000 00000000 00000000 00000000
6508 &x+8 00000000 00000000 00000000 00000000
6511 &x+12 00000000 00000000 00000000 00000000
6517 frv_adjust_field_align (tree field
, int computed
)
6519 /* Make sure that the bitfield is not wider than the type. */
6520 if (DECL_BIT_FIELD (field
)
6521 && !DECL_ARTIFICIAL (field
))
6523 tree parent
= DECL_CONTEXT (field
);
6524 tree prev
= NULL_TREE
;
6527 for (cur
= TYPE_FIELDS (parent
); cur
&& cur
!= field
; cur
= DECL_CHAIN (cur
))
6529 if (TREE_CODE (cur
) != FIELD_DECL
)
6537 /* If this isn't a :0 field and if the previous element is a bitfield
6538 also, see if the type is different, if so, we will need to align the
6539 bit-field to the next boundary. */
6541 && ! DECL_PACKED (field
)
6542 && ! integer_zerop (DECL_SIZE (field
))
6543 && DECL_BIT_FIELD_TYPE (field
) != DECL_BIT_FIELD_TYPE (prev
))
6545 int prev_align
= TYPE_ALIGN (TREE_TYPE (prev
));
6546 int cur_align
= TYPE_ALIGN (TREE_TYPE (field
));
6547 computed
= (prev_align
> cur_align
) ? prev_align
: cur_align
;
6555 /* A C expression that is nonzero if it is permissible to store a value of mode
6556 MODE in hard register number REGNO (or in several registers starting with
6557 that one). For a machine where all registers are equivalent, a suitable
6560 #define HARD_REGNO_MODE_OK(REGNO, MODE) 1
6562 It is not necessary for this macro to check for the numbers of fixed
6563 registers, because the allocation mechanism considers them to be always
6566 On some machines, double-precision values must be kept in even/odd register
6567 pairs. The way to implement that is to define this macro to reject odd
6568 register numbers for such modes.
6570 The minimum requirement for a mode to be OK in a register is that the
6571 `movMODE' instruction pattern support moves between the register and any
6572 other hard register for which the mode is OK; and that moving a value into
6573 the register and back out not alter it.
6575 Since the same instruction used to move `SImode' will work for all narrower
6576 integer modes, it is not necessary on any machine for `HARD_REGNO_MODE_OK'
6577 to distinguish between these modes, provided you define patterns `movhi',
6578 etc., to take advantage of this. This is useful because of the interaction
6579 between `HARD_REGNO_MODE_OK' and `MODES_TIEABLE_P'; it is very desirable for
6580 all integer modes to be tieable.
6582 Many machines have special registers for floating point arithmetic. Often
6583 people assume that floating point machine modes are allowed only in floating
6584 point registers. This is not true. Any registers that can hold integers
6585 can safely *hold* a floating point machine mode, whether or not floating
6586 arithmetic can be done on it in those registers. Integer move instructions
6587 can be used to move the values.
6589 On some machines, though, the converse is true: fixed-point machine modes
6590 may not go in floating registers. This is true if the floating registers
6591 normalize any value stored in them, because storing a non-floating value
6592 there would garble it. In this case, `HARD_REGNO_MODE_OK' should reject
6593 fixed-point machine modes in floating registers. But if the floating
6594 registers do not automatically normalize, if you can store any bit pattern
6595 in one and retrieve it unchanged without a trap, then any machine mode may
6596 go in a floating register, so you can define this macro to say so.
6598 The primary significance of special floating registers is rather that they
6599 are the registers acceptable in floating point arithmetic instructions.
6600 However, this is of no concern to `HARD_REGNO_MODE_OK'. You handle it by
6601 writing the proper constraints for those instructions.
6603 On some machines, the floating registers are especially slow to access, so
6604 that it is better to store a value in a stack frame than in such a register
6605 if floating point arithmetic is not being done. As long as the floating
6606 registers are not in class `GENERAL_REGS', they will not be used unless some
6607 pattern's constraint asks for one. */
6610 frv_hard_regno_mode_ok (int regno
, machine_mode mode
)
6620 return ICC_P (regno
) || GPR_P (regno
);
6623 return CR_P (regno
) || GPR_P (regno
);
6626 return FCC_P (regno
) || GPR_P (regno
);
6632 /* Set BASE to the first register in REGNO's class. Set MASK to the
6633 bits that must be clear in (REGNO - BASE) for the register to be
6635 if (INTEGRAL_MODE_P (mode
) || FLOAT_MODE_P (mode
) || VECTOR_MODE_P (mode
))
6639 /* ACCGs store one byte. Two-byte quantities must start in
6640 even-numbered registers, four-byte ones in registers whose
6641 numbers are divisible by four, and so on. */
6643 mask
= GET_MODE_SIZE (mode
) - 1;
6647 /* The other registers store one word. */
6648 if (GPR_P (regno
) || regno
== AP_FIRST
)
6651 else if (FPR_P (regno
))
6654 else if (ACC_P (regno
))
6657 else if (SPR_P (regno
))
6658 return mode
== SImode
;
6660 /* Fill in the table. */
6664 /* Anything smaller than an SI is OK in any word-sized register. */
6665 if (GET_MODE_SIZE (mode
) < 4)
6668 mask
= (GET_MODE_SIZE (mode
) / 4) - 1;
6670 return (((regno
- base
) & mask
) == 0);
6677 /* A C expression for the number of consecutive hard registers, starting at
6678 register number REGNO, required to hold a value of mode MODE.
6680 On a machine where all registers are exactly one word, a suitable definition
6683 #define HARD_REGNO_NREGS(REGNO, MODE) \
6684 ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \
6685 / UNITS_PER_WORD)) */
6687 /* On the FRV, make the CC_FP mode take 3 words in the integer registers, so
6688 that we can build the appropriate instructions to properly reload the
6689 values. Also, make the byte-sized accumulator guards use one guard
6693 frv_hard_regno_nregs (int regno
, machine_mode mode
)
6696 return GET_MODE_SIZE (mode
);
6698 return (GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
6702 /* A C expression for the maximum number of consecutive registers of
6703 class RCLASS needed to hold a value of mode MODE.
6705 This is closely related to the macro `HARD_REGNO_NREGS'. In fact, the value
6706 of the macro `CLASS_MAX_NREGS (RCLASS, MODE)' should be the maximum value of
6707 `HARD_REGNO_NREGS (REGNO, MODE)' for all REGNO values in the class RCLASS.
6709 This macro helps control the handling of multiple-word values in
6712 This declaration is required. */
6715 frv_class_max_nregs (enum reg_class rclass
, machine_mode mode
)
6717 if (rclass
== ACCG_REGS
)
6718 /* An N-byte value requires N accumulator guards. */
6719 return GET_MODE_SIZE (mode
);
6721 return (GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
6725 /* A C expression that is nonzero if X is a legitimate constant for an
6726 immediate operand on the target machine. You can assume that X satisfies
6727 `CONSTANT_P', so you need not check this. In fact, `1' is a suitable
6728 definition for this macro on machines where anything `CONSTANT_P' is valid. */
6731 frv_legitimate_constant_p (machine_mode mode
, rtx x
)
6733 /* frv_cannot_force_const_mem always returns true for FDPIC. This
6734 means that the move expanders will be expected to deal with most
6735 kinds of constant, regardless of what we return here.
6737 However, among its other duties, frv_legitimate_constant_p decides whether
6738 a constant can be entered into reg_equiv_constant[]. If we return true,
6739 reload can create new instances of the constant whenever it likes.
6741 The idea is therefore to accept as many constants as possible (to give
6742 reload more freedom) while rejecting constants that can only be created
6743 at certain times. In particular, anything with a symbolic component will
6744 require use of the pseudo FDPIC register, which is only available before
6747 return LEGITIMATE_PIC_OPERAND_P (x
);
6749 /* All of the integer constants are ok. */
6750 if (GET_CODE (x
) != CONST_DOUBLE
)
6753 /* double integer constants are ok. */
6754 if (GET_MODE (x
) == VOIDmode
|| mode
== DImode
)
6757 /* 0 is always ok. */
6758 if (x
== CONST0_RTX (mode
))
6761 /* If floating point is just emulated, allow any constant, since it will be
6762 constructed in the GPRs. */
6763 if (!TARGET_HAS_FPRS
)
6766 if (mode
== DFmode
&& !TARGET_DOUBLE
)
6769 /* Otherwise store the constant away and do a load. */
6773 /* Implement SELECT_CC_MODE. Choose CC_FP for floating-point comparisons,
6774 CC_NZ for comparisons against zero in which a single Z or N flag test
6775 is enough, CC_UNS for other unsigned comparisons, and CC for other
6776 signed comparisons. */
6779 frv_select_cc_mode (enum rtx_code code
, rtx x
, rtx y
)
6781 if (GET_MODE_CLASS (GET_MODE (x
)) == MODE_FLOAT
)
6790 return y
== const0_rtx
? CC_NZmode
: CCmode
;
6796 return y
== const0_rtx
? CC_NZmode
: CC_UNSmode
;
6804 /* Worker function for TARGET_REGISTER_MOVE_COST. */
6806 #define HIGH_COST 40
6807 #define MEDIUM_COST 3
6811 frv_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED
,
6812 reg_class_t from
, reg_class_t to
)
6825 case FDPIC_FPTR_REGS
:
6826 case FDPIC_CALL_REGS
:
6839 case FDPIC_FPTR_REGS
:
6840 case FDPIC_CALL_REGS
:
6865 case FDPIC_FPTR_REGS
:
6866 case FDPIC_CALL_REGS
:
6890 case FDPIC_FPTR_REGS
:
6891 case FDPIC_CALL_REGS
:
6912 /* Worker function for TARGET_MEMORY_MOVE_COST. */
6915 frv_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED
,
6916 reg_class_t rclass ATTRIBUTE_UNUSED
,
6917 bool in ATTRIBUTE_UNUSED
)
6923 /* Implementation of TARGET_ASM_INTEGER. In the FRV case we need to
6924 use ".picptr" to generate safe relocations for PIC code. We also
6925 need a fixup entry for aligned (non-debugging) code. */
6928 frv_assemble_integer (rtx value
, unsigned int size
, int aligned_p
)
6930 if ((flag_pic
|| TARGET_FDPIC
) && size
== UNITS_PER_WORD
)
6932 if (GET_CODE (value
) == CONST
6933 || GET_CODE (value
) == SYMBOL_REF
6934 || GET_CODE (value
) == LABEL_REF
)
6936 if (TARGET_FDPIC
&& GET_CODE (value
) == SYMBOL_REF
6937 && SYMBOL_REF_FUNCTION_P (value
))
6939 fputs ("\t.picptr\tfuncdesc(", asm_out_file
);
6940 output_addr_const (asm_out_file
, value
);
6941 fputs (")\n", asm_out_file
);
6944 else if (TARGET_FDPIC
&& GET_CODE (value
) == CONST
6945 && frv_function_symbol_referenced_p (value
))
6947 if (aligned_p
&& !TARGET_FDPIC
)
6949 static int label_num
= 0;
6953 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCP", label_num
++);
6954 p
= (* targetm
.strip_name_encoding
) (buf
);
6956 fprintf (asm_out_file
, "%s:\n", p
);
6957 fprintf (asm_out_file
, "%s\n", FIXUP_SECTION_ASM_OP
);
6958 fprintf (asm_out_file
, "\t.picptr\t%s\n", p
);
6959 fprintf (asm_out_file
, "\t.previous\n");
6961 assemble_integer_with_op ("\t.picptr\t", value
);
6966 /* We've set the unaligned SI op to NULL, so we always have to
6967 handle the unaligned case here. */
6968 assemble_integer_with_op ("\t.4byte\t", value
);
6972 return default_assemble_integer (value
, size
, aligned_p
);
6975 /* Function to set up the backend function structure. */
6977 static struct machine_function
*
6978 frv_init_machine_status (void)
6980 return ggc_cleared_alloc
<machine_function
> ();
6983 /* Implement TARGET_SCHED_ISSUE_RATE. */
6986 frv_issue_rate (void)
6991 switch (frv_cpu_type
)
6995 case FRV_CPU_SIMPLE
:
7003 case FRV_CPU_GENERIC
:
7005 case FRV_CPU_TOMCAT
:
7013 /* Return the value of INSN's acc_group attribute. */
7016 frv_acc_group (rtx insn
)
7018 /* This distinction only applies to the FR550 packing constraints. */
7019 if (frv_cpu_type
== FRV_CPU_FR550
)
7021 subrtx_iterator::array_type array
;
7022 FOR_EACH_SUBRTX (iter
, array
, PATTERN (insn
), NONCONST
)
7025 unsigned int regno
= REGNO (*iter
);
7026 /* If REGNO refers to an accumulator, return ACC_GROUP_ODD if
7027 the bit 2 of the register number is set and ACC_GROUP_EVEN if
7030 return (regno
- ACC_FIRST
) & 4 ? ACC_GROUP_ODD
: ACC_GROUP_EVEN
;
7032 return (regno
- ACCG_FIRST
) & 4 ? ACC_GROUP_ODD
: ACC_GROUP_EVEN
;
7035 return ACC_GROUP_NONE
;
7038 /* Return the index of the DFA unit in FRV_UNIT_NAMES[] that instruction
7039 INSN will try to claim first. Since this value depends only on the
7040 type attribute, we can cache the results in FRV_TYPE_TO_UNIT[]. */
7043 frv_insn_unit (rtx_insn
*insn
)
7045 enum attr_type type
;
7047 type
= get_attr_type (insn
);
7048 if (frv_type_to_unit
[type
] == ARRAY_SIZE (frv_unit_codes
))
7050 /* We haven't seen this type of instruction before. */
7054 /* Issue the instruction on its own to see which unit it prefers. */
7055 state
= alloca (state_size ());
7056 state_reset (state
);
7057 state_transition (state
, insn
);
7059 /* Find out which unit was taken. */
7060 for (unit
= 0; unit
< ARRAY_SIZE (frv_unit_codes
); unit
++)
7061 if (cpu_unit_reservation_p (state
, frv_unit_codes
[unit
]))
7064 gcc_assert (unit
!= ARRAY_SIZE (frv_unit_codes
));
7066 frv_type_to_unit
[type
] = unit
;
7068 return frv_type_to_unit
[type
];
7071 /* Return true if INSN issues to a branch unit. */
7074 frv_issues_to_branch_unit_p (rtx_insn
*insn
)
7076 return frv_unit_groups
[frv_insn_unit (insn
)] == GROUP_B
;
7079 /* The instructions in the packet, partitioned into groups. */
7080 struct frv_packet_group
{
7081 /* How many instructions in the packet belong to this group. */
7082 unsigned int num_insns
;
7084 /* A list of the instructions that belong to this group, in the order
7085 they appear in the rtl stream. */
7086 rtx_insn
*insns
[ARRAY_SIZE (frv_unit_codes
)];
7088 /* The contents of INSNS after they have been sorted into the correct
7089 assembly-language order. Element X issues to unit X. The list may
7090 contain extra nops. */
7091 rtx_insn
*sorted
[ARRAY_SIZE (frv_unit_codes
)];
7093 /* The member of frv_nops[] to use in sorted[]. */
7097 /* The current state of the packing pass, implemented by frv_pack_insns. */
7099 /* The state of the pipeline DFA. */
7102 /* Which hardware registers are set within the current packet,
7103 and the conditions under which they are set. */
7104 regstate_t regstate
[FIRST_PSEUDO_REGISTER
];
7106 /* The memory locations that have been modified so far in this
7107 packet. MEM is the memref and COND is the regstate_t condition
7108 under which it is set. */
7114 /* The number of valid entries in MEMS. The value is larger than
7115 ARRAY_SIZE (mems) if there were too many mems to record. */
7116 unsigned int num_mems
;
7118 /* The maximum number of instructions that can be packed together. */
7119 unsigned int issue_rate
;
7121 /* The instructions in the packet, partitioned into groups. */
7122 struct frv_packet_group groups
[NUM_GROUPS
];
7124 /* The instructions that make up the current packet. */
7125 rtx_insn
*insns
[ARRAY_SIZE (frv_unit_codes
)];
7126 unsigned int num_insns
;
7129 /* Return the regstate_t flags for the given COND_EXEC condition.
7130 Abort if the condition isn't in the right form. */
7133 frv_cond_flags (rtx cond
)
7135 gcc_assert ((GET_CODE (cond
) == EQ
|| GET_CODE (cond
) == NE
)
7136 && GET_CODE (XEXP (cond
, 0)) == REG
7137 && CR_P (REGNO (XEXP (cond
, 0)))
7138 && XEXP (cond
, 1) == const0_rtx
);
7139 return ((REGNO (XEXP (cond
, 0)) - CR_FIRST
)
7140 | (GET_CODE (cond
) == NE
7142 : REGSTATE_IF_FALSE
));
7146 /* Return true if something accessed under condition COND2 can
7147 conflict with something written under condition COND1. */
7150 frv_regstate_conflict_p (regstate_t cond1
, regstate_t cond2
)
7152 /* If either reference was unconditional, we have a conflict. */
7153 if ((cond1
& REGSTATE_IF_EITHER
) == 0
7154 || (cond2
& REGSTATE_IF_EITHER
) == 0)
7157 /* The references might conflict if they were controlled by
7159 if ((cond1
& REGSTATE_CC_MASK
) != (cond2
& REGSTATE_CC_MASK
))
7162 /* They definitely conflict if they are controlled by the
7164 if ((cond1
& cond2
& REGSTATE_IF_EITHER
) != 0)
7171 /* Return true if an instruction with pattern PAT depends on an
7172 instruction in the current packet. COND describes the condition
7173 under which PAT might be set or used. */
7176 frv_registers_conflict_p_1 (rtx pat
, regstate_t cond
)
7178 subrtx_var_iterator::array_type array
;
7179 FOR_EACH_SUBRTX_VAR (iter
, array
, pat
, NONCONST
)
7182 if (GET_CODE (x
) == REG
)
7185 FOR_EACH_REGNO (regno
, x
)
7186 if ((frv_packet
.regstate
[regno
] & REGSTATE_MODIFIED
) != 0)
7187 if (frv_regstate_conflict_p (frv_packet
.regstate
[regno
], cond
))
7190 else if (GET_CODE (x
) == MEM
)
7192 /* If we ran out of memory slots, assume a conflict. */
7193 if (frv_packet
.num_mems
> ARRAY_SIZE (frv_packet
.mems
))
7196 /* Check for output or true dependencies with earlier MEMs. */
7197 for (unsigned int i
= 0; i
< frv_packet
.num_mems
; i
++)
7198 if (frv_regstate_conflict_p (frv_packet
.mems
[i
].cond
, cond
))
7200 if (true_dependence (frv_packet
.mems
[i
].mem
, VOIDmode
, x
))
7203 if (output_dependence (frv_packet
.mems
[i
].mem
, x
))
7208 /* The return values of calls aren't significant: they describe
7209 the effect of the call as a whole, not of the insn itself. */
7210 else if (GET_CODE (x
) == SET
&& GET_CODE (SET_SRC (x
)) == CALL
)
7211 iter
.substitute (SET_SRC (x
));
7217 /* Return true if something in X might depend on an instruction
7218 in the current packet. */
7221 frv_registers_conflict_p (rtx x
)
7226 if (GET_CODE (x
) == COND_EXEC
)
7228 if (frv_registers_conflict_p_1 (XEXP (x
, 0), flags
))
7231 flags
|= frv_cond_flags (XEXP (x
, 0));
7234 return frv_registers_conflict_p_1 (x
, flags
);
7238 /* A note_stores callback. DATA points to the regstate_t condition
7239 under which X is modified. Update FRV_PACKET accordingly. */
7242 frv_registers_update_1 (rtx x
, const_rtx pat ATTRIBUTE_UNUSED
, void *data
)
7246 if (GET_CODE (x
) == REG
)
7247 FOR_EACH_REGNO (regno
, x
)
7248 frv_packet
.regstate
[regno
] |= *(regstate_t
*) data
;
7250 if (GET_CODE (x
) == MEM
)
7252 if (frv_packet
.num_mems
< ARRAY_SIZE (frv_packet
.mems
))
7254 frv_packet
.mems
[frv_packet
.num_mems
].mem
= x
;
7255 frv_packet
.mems
[frv_packet
.num_mems
].cond
= *(regstate_t
*) data
;
7257 frv_packet
.num_mems
++;
7262 /* Update the register state information for an instruction whose
7266 frv_registers_update (rtx x
)
7270 flags
= REGSTATE_MODIFIED
;
7271 if (GET_CODE (x
) == COND_EXEC
)
7273 flags
|= frv_cond_flags (XEXP (x
, 0));
7276 note_stores (x
, frv_registers_update_1
, &flags
);
7280 /* Initialize frv_packet for the start of a new packet. */
7283 frv_start_packet (void)
7285 enum frv_insn_group group
;
7287 memset (frv_packet
.regstate
, 0, sizeof (frv_packet
.regstate
));
7288 frv_packet
.num_mems
= 0;
7289 frv_packet
.num_insns
= 0;
7290 for (group
= GROUP_I
; group
< NUM_GROUPS
;
7291 group
= (enum frv_insn_group
) (group
+ 1))
7292 frv_packet
.groups
[group
].num_insns
= 0;
7296 /* Likewise for the start of a new basic block. */
7299 frv_start_packet_block (void)
7301 state_reset (frv_packet
.dfa_state
);
7302 frv_start_packet ();
7306 /* Finish the current packet, if any, and start a new one. Call
7307 HANDLE_PACKET with FRV_PACKET describing the completed packet. */
7310 frv_finish_packet (void (*handle_packet
) (void))
7312 if (frv_packet
.num_insns
> 0)
7315 state_transition (frv_packet
.dfa_state
, 0);
7316 frv_start_packet ();
7321 /* Return true if INSN can be added to the current packet. Update
7322 the DFA state on success. */
7325 frv_pack_insn_p (rtx_insn
*insn
)
7327 /* See if the packet is already as long as it can be. */
7328 if (frv_packet
.num_insns
== frv_packet
.issue_rate
)
7331 /* If the scheduler thought that an instruction should start a packet,
7332 it's usually a good idea to believe it. It knows much more about
7333 the latencies than we do.
7335 There are some exceptions though:
7337 - Conditional instructions are scheduled on the assumption that
7338 they will be executed. This is usually a good thing, since it
7339 tends to avoid unnecessary stalls in the conditional code.
7340 But we want to pack conditional instructions as tightly as
7341 possible, in order to optimize the case where they aren't
7344 - The scheduler will always put branches on their own, even
7345 if there's no real dependency.
7347 - There's no point putting a call in its own packet unless
7349 if (frv_packet
.num_insns
> 0
7350 && NONJUMP_INSN_P (insn
)
7351 && GET_MODE (insn
) == TImode
7352 && GET_CODE (PATTERN (insn
)) != COND_EXEC
)
7355 /* Check for register conflicts. Don't do this for setlo since any
7356 conflict will be with the partnering sethi, with which it can
7358 if (get_attr_type (insn
) != TYPE_SETLO
)
7359 if (frv_registers_conflict_p (PATTERN (insn
)))
7362 return state_transition (frv_packet
.dfa_state
, insn
) < 0;
7366 /* Add instruction INSN to the current packet. */
7369 frv_add_insn_to_packet (rtx_insn
*insn
)
7371 struct frv_packet_group
*packet_group
;
7373 packet_group
= &frv_packet
.groups
[frv_unit_groups
[frv_insn_unit (insn
)]];
7374 packet_group
->insns
[packet_group
->num_insns
++] = insn
;
7375 frv_packet
.insns
[frv_packet
.num_insns
++] = insn
;
7377 frv_registers_update (PATTERN (insn
));
7381 /* Insert INSN (a member of frv_nops[]) into the current packet. If the
7382 packet ends in a branch or call, insert the nop before it, otherwise
7386 frv_insert_nop_in_packet (rtx_insn
*insn
)
7388 struct frv_packet_group
*packet_group
;
7391 packet_group
= &frv_packet
.groups
[frv_unit_groups
[frv_insn_unit (insn
)]];
7392 last
= frv_packet
.insns
[frv_packet
.num_insns
- 1];
7393 if (! NONJUMP_INSN_P (last
))
7395 insn
= emit_insn_before (PATTERN (insn
), last
);
7396 frv_packet
.insns
[frv_packet
.num_insns
- 1] = insn
;
7397 frv_packet
.insns
[frv_packet
.num_insns
++] = last
;
7401 insn
= emit_insn_after (PATTERN (insn
), last
);
7402 frv_packet
.insns
[frv_packet
.num_insns
++] = insn
;
7404 packet_group
->insns
[packet_group
->num_insns
++] = insn
;
7408 /* If packing is enabled, divide the instructions into packets and
7409 return true. Call HANDLE_PACKET for each complete packet. */
7412 frv_for_each_packet (void (*handle_packet
) (void))
7414 rtx_insn
*insn
, *next_insn
;
7416 frv_packet
.issue_rate
= frv_issue_rate ();
7418 /* Early exit if we don't want to pack insns. */
7420 || !flag_schedule_insns_after_reload
7421 || !TARGET_VLIW_BRANCH
7422 || frv_packet
.issue_rate
== 1)
7425 /* Set up the initial packing state. */
7427 frv_packet
.dfa_state
= alloca (state_size ());
7429 frv_start_packet_block ();
7430 for (insn
= get_insns (); insn
!= 0; insn
= next_insn
)
7435 code
= GET_CODE (insn
);
7436 next_insn
= NEXT_INSN (insn
);
7438 if (code
== CODE_LABEL
)
7440 frv_finish_packet (handle_packet
);
7441 frv_start_packet_block ();
7445 switch (GET_CODE (PATTERN (insn
)))
7452 /* Calls mustn't be packed on a TOMCAT. */
7453 if (CALL_P (insn
) && frv_cpu_type
== FRV_CPU_TOMCAT
)
7454 frv_finish_packet (handle_packet
);
7456 /* Since the last instruction in a packet determines the EH
7457 region, any exception-throwing instruction must come at
7458 the end of reordered packet. Insns that issue to a
7459 branch unit are bound to come last; for others it's
7460 too hard to predict. */
7461 eh_insn_p
= (find_reg_note (insn
, REG_EH_REGION
, NULL
) != NULL
);
7462 if (eh_insn_p
&& !frv_issues_to_branch_unit_p (insn
))
7463 frv_finish_packet (handle_packet
);
7465 /* Finish the current packet if we can't add INSN to it.
7466 Simulate cycles until INSN is ready to issue. */
7467 if (!frv_pack_insn_p (insn
))
7469 frv_finish_packet (handle_packet
);
7470 while (!frv_pack_insn_p (insn
))
7471 state_transition (frv_packet
.dfa_state
, 0);
7474 /* Add the instruction to the packet. */
7475 frv_add_insn_to_packet (insn
);
7477 /* Calls and jumps end a packet, as do insns that throw
7479 if (code
== CALL_INSN
|| code
== JUMP_INSN
|| eh_insn_p
)
7480 frv_finish_packet (handle_packet
);
7484 frv_finish_packet (handle_packet
);
7489 /* Subroutine of frv_sort_insn_group. We are trying to sort
7490 frv_packet.groups[GROUP].sorted[0...NUM_INSNS-1] into assembly
7491 language order. We have already picked a new position for
7492 frv_packet.groups[GROUP].sorted[X] if bit X of ISSUED is set.
7493 These instructions will occupy elements [0, LOWER_SLOT) and
7494 [UPPER_SLOT, NUM_INSNS) of the final (sorted) array. STATE is
7495 the DFA state after issuing these instructions.
7497 Try filling elements [LOWER_SLOT, UPPER_SLOT) with every permutation
7498 of the unused instructions. Return true if one such permutation gives
7499 a valid ordering, leaving the successful permutation in sorted[].
7500 Do not modify sorted[] until a valid permutation is found. */
7503 frv_sort_insn_group_1 (enum frv_insn_group group
,
7504 unsigned int lower_slot
, unsigned int upper_slot
,
7505 unsigned int issued
, unsigned int num_insns
,
7508 struct frv_packet_group
*packet_group
;
7514 /* Early success if we've filled all the slots. */
7515 if (lower_slot
== upper_slot
)
7518 packet_group
= &frv_packet
.groups
[group
];
7519 dfa_size
= state_size ();
7520 test_state
= alloca (dfa_size
);
7522 /* Try issuing each unused instruction. */
7523 for (i
= num_insns
- 1; i
+ 1 != 0; i
--)
7524 if (~issued
& (1 << i
))
7526 insn
= packet_group
->sorted
[i
];
7527 memcpy (test_state
, state
, dfa_size
);
7528 if (state_transition (test_state
, insn
) < 0
7529 && cpu_unit_reservation_p (test_state
,
7530 NTH_UNIT (group
, upper_slot
- 1))
7531 && frv_sort_insn_group_1 (group
, lower_slot
, upper_slot
- 1,
7532 issued
| (1 << i
), num_insns
,
7535 packet_group
->sorted
[upper_slot
- 1] = insn
;
7543 /* Compare two instructions by their frv_insn_unit. */
7546 frv_compare_insns (const void *first
, const void *second
)
7548 rtx_insn
* const *insn1
= (rtx_insn
* const *) first
;
7549 rtx_insn
* const *insn2
= (rtx_insn
* const *) second
;
7550 return frv_insn_unit (*insn1
) - frv_insn_unit (*insn2
);
7553 /* Copy frv_packet.groups[GROUP].insns[] to frv_packet.groups[GROUP].sorted[]
7554 and sort it into assembly language order. See frv.md for a description of
7558 frv_sort_insn_group (enum frv_insn_group group
)
7560 struct frv_packet_group
*packet_group
;
7561 unsigned int first
, i
, nop
, max_unit
, num_slots
;
7562 state_t state
, test_state
;
7565 packet_group
= &frv_packet
.groups
[group
];
7567 /* Assume no nop is needed. */
7568 packet_group
->nop
= 0;
7570 if (packet_group
->num_insns
== 0)
7573 /* Copy insns[] to sorted[]. */
7574 memcpy (packet_group
->sorted
, packet_group
->insns
,
7575 sizeof (rtx
) * packet_group
->num_insns
);
7577 /* Sort sorted[] by the unit that each insn tries to take first. */
7578 if (packet_group
->num_insns
> 1)
7579 qsort (packet_group
->sorted
, packet_group
->num_insns
,
7580 sizeof (rtx
), frv_compare_insns
);
7582 /* That's always enough for branch and control insns. */
7583 if (group
== GROUP_B
|| group
== GROUP_C
)
7586 dfa_size
= state_size ();
7587 state
= alloca (dfa_size
);
7588 test_state
= alloca (dfa_size
);
7590 /* Find the highest FIRST such that sorted[0...FIRST-1] can issue
7591 consecutively and such that the DFA takes unit X when sorted[X]
7592 is added. Set STATE to the new DFA state. */
7593 state_reset (test_state
);
7594 for (first
= 0; first
< packet_group
->num_insns
; first
++)
7596 memcpy (state
, test_state
, dfa_size
);
7597 if (state_transition (test_state
, packet_group
->sorted
[first
]) >= 0
7598 || !cpu_unit_reservation_p (test_state
, NTH_UNIT (group
, first
)))
7602 /* If all the instructions issued in ascending order, we're done. */
7603 if (first
== packet_group
->num_insns
)
7606 /* Add nops to the end of sorted[] and try each permutation until
7607 we find one that works. */
7608 for (nop
= 0; nop
< frv_num_nops
; nop
++)
7610 max_unit
= frv_insn_unit (frv_nops
[nop
]);
7611 if (frv_unit_groups
[max_unit
] == group
)
7613 packet_group
->nop
= frv_nops
[nop
];
7614 num_slots
= UNIT_NUMBER (max_unit
) + 1;
7615 for (i
= packet_group
->num_insns
; i
< num_slots
; i
++)
7616 packet_group
->sorted
[i
] = frv_nops
[nop
];
7617 if (frv_sort_insn_group_1 (group
, first
, num_slots
,
7618 (1 << first
) - 1, num_slots
, state
))
7625 /* Sort the current packet into assembly-language order. Set packing
7626 flags as appropriate. */
7629 frv_reorder_packet (void)
7631 unsigned int cursor
[NUM_GROUPS
];
7632 rtx insns
[ARRAY_SIZE (frv_unit_groups
)];
7633 unsigned int unit
, to
, from
;
7634 enum frv_insn_group group
;
7635 struct frv_packet_group
*packet_group
;
7637 /* First sort each group individually. */
7638 for (group
= GROUP_I
; group
< NUM_GROUPS
;
7639 group
= (enum frv_insn_group
) (group
+ 1))
7642 frv_sort_insn_group (group
);
7645 /* Go through the unit template and try add an instruction from
7646 that unit's group. */
7648 for (unit
= 0; unit
< ARRAY_SIZE (frv_unit_groups
); unit
++)
7650 group
= frv_unit_groups
[unit
];
7651 packet_group
= &frv_packet
.groups
[group
];
7652 if (cursor
[group
] < packet_group
->num_insns
)
7654 /* frv_reorg should have added nops for us. */
7655 gcc_assert (packet_group
->sorted
[cursor
[group
]]
7656 != packet_group
->nop
);
7657 insns
[to
++] = packet_group
->sorted
[cursor
[group
]++];
7661 gcc_assert (to
== frv_packet
.num_insns
);
7663 /* Clear the last instruction's packing flag, thus marking the end of
7664 a packet. Reorder the other instructions relative to it. */
7665 CLEAR_PACKING_FLAG (insns
[to
- 1]);
7666 for (from
= 0; from
< to
- 1; from
++)
7668 remove_insn (insns
[from
]);
7669 add_insn_before (insns
[from
], insns
[to
- 1], NULL
);
7670 SET_PACKING_FLAG (insns
[from
]);
7675 /* Divide instructions into packets. Reorder the contents of each
7676 packet so that they are in the correct assembly-language order.
7678 Since this pass can change the raw meaning of the rtl stream, it must
7679 only be called at the last minute, just before the instructions are
7683 frv_pack_insns (void)
7685 if (frv_for_each_packet (frv_reorder_packet
))
7686 frv_insn_packing_flag
= 0;
7688 frv_insn_packing_flag
= -1;
7691 /* See whether we need to add nops to group GROUP in order to
7692 make a valid packet. */
7695 frv_fill_unused_units (enum frv_insn_group group
)
7697 unsigned int non_nops
, nops
, i
;
7698 struct frv_packet_group
*packet_group
;
7700 packet_group
= &frv_packet
.groups
[group
];
7702 /* Sort the instructions into assembly-language order.
7703 Use nops to fill slots that are otherwise unused. */
7704 frv_sort_insn_group (group
);
7706 /* See how many nops are needed before the final useful instruction. */
7708 for (non_nops
= 0; non_nops
< packet_group
->num_insns
; non_nops
++)
7709 while (packet_group
->sorted
[i
++] == packet_group
->nop
)
7712 /* Insert that many nops into the instruction stream. */
7714 frv_insert_nop_in_packet (packet_group
->nop
);
7717 /* Return true if accesses IO1 and IO2 refer to the same doubleword. */
7720 frv_same_doubleword_p (const struct frv_io
*io1
, const struct frv_io
*io2
)
7722 if (io1
->const_address
!= 0 && io2
->const_address
!= 0)
7723 return io1
->const_address
== io2
->const_address
;
7725 if (io1
->var_address
!= 0 && io2
->var_address
!= 0)
7726 return rtx_equal_p (io1
->var_address
, io2
->var_address
);
7731 /* Return true if operations IO1 and IO2 are guaranteed to complete
7735 frv_io_fixed_order_p (const struct frv_io
*io1
, const struct frv_io
*io2
)
7737 /* The order of writes is always preserved. */
7738 if (io1
->type
== FRV_IO_WRITE
&& io2
->type
== FRV_IO_WRITE
)
7741 /* The order of reads isn't preserved. */
7742 if (io1
->type
!= FRV_IO_WRITE
&& io2
->type
!= FRV_IO_WRITE
)
7745 /* One operation is a write and the other is (or could be) a read.
7746 The order is only guaranteed if the accesses are to the same
7748 return frv_same_doubleword_p (io1
, io2
);
7751 /* Generalize I/O operation X so that it covers both X and Y. */
7754 frv_io_union (struct frv_io
*x
, const struct frv_io
*y
)
7756 if (x
->type
!= y
->type
)
7757 x
->type
= FRV_IO_UNKNOWN
;
7758 if (!frv_same_doubleword_p (x
, y
))
7760 x
->const_address
= 0;
7765 /* Fill IO with information about the load or store associated with
7766 membar instruction INSN. */
7769 frv_extract_membar (struct frv_io
*io
, rtx_insn
*insn
)
7771 extract_insn (insn
);
7772 io
->type
= (enum frv_io_type
) INTVAL (recog_data
.operand
[2]);
7773 io
->const_address
= INTVAL (recog_data
.operand
[1]);
7774 io
->var_address
= XEXP (recog_data
.operand
[0], 0);
7777 /* A note_stores callback for which DATA points to an rtx. Nullify *DATA
7778 if X is a register and *DATA depends on X. */
7781 frv_io_check_address (rtx x
, const_rtx pat ATTRIBUTE_UNUSED
, void *data
)
7783 rtx
*other
= (rtx
*) data
;
7785 if (REG_P (x
) && *other
!= 0 && reg_overlap_mentioned_p (x
, *other
))
7789 /* A note_stores callback for which DATA points to a HARD_REG_SET.
7790 Remove every modified register from the set. */
7793 frv_io_handle_set (rtx x
, const_rtx pat ATTRIBUTE_UNUSED
, void *data
)
7795 HARD_REG_SET
*set
= (HARD_REG_SET
*) data
;
7799 FOR_EACH_REGNO (regno
, x
)
7800 CLEAR_HARD_REG_BIT (*set
, regno
);
7803 /* A note_uses callback that adds all registers in *X to hard register
7807 frv_io_handle_use (rtx
*x
, void *data
)
7809 find_all_hard_regs (*x
, (HARD_REG_SET
*) data
);
7812 /* Go through block BB looking for membars to remove. There are two
7813 cases where intra-block analysis is enough:
7815 - a membar is redundant if it occurs between two consecutive I/O
7816 operations and if those operations are guaranteed to complete
7819 - a membar for a __builtin_read is redundant if the result is
7820 used before the next I/O operation is issued.
7822 If the last membar in the block could not be removed, and there
7823 are guaranteed to be no I/O operations between that membar and
7824 the end of the block, store the membar in *LAST_MEMBAR, otherwise
7827 Describe the block's first I/O operation in *NEXT_IO. Describe
7828 an unknown operation if the block doesn't do any I/O. */
7831 frv_optimize_membar_local (basic_block bb
, struct frv_io
*next_io
,
7832 rtx_insn
**last_membar
)
7834 HARD_REG_SET used_regs
;
7835 rtx next_membar
, set
;
7839 /* NEXT_IO is the next I/O operation to be performed after the current
7840 instruction. It starts off as being an unknown operation. */
7841 memset (next_io
, 0, sizeof (*next_io
));
7843 /* NEXT_IS_END_P is true if NEXT_IO describes the end of the block. */
7844 next_is_end_p
= true;
7846 /* If the current instruction is a __builtin_read or __builtin_write,
7847 NEXT_MEMBAR is the membar instruction associated with it. NEXT_MEMBAR
7848 is null if the membar has already been deleted.
7850 Note that the initialization here should only be needed to
7851 suppress warnings. */
7854 /* USED_REGS is the set of registers that are used before the
7855 next I/O instruction. */
7856 CLEAR_HARD_REG_SET (used_regs
);
7858 for (insn
= BB_END (bb
); insn
!= BB_HEAD (bb
); insn
= PREV_INSN (insn
))
7861 /* We can't predict what a call will do to volatile memory. */
7862 memset (next_io
, 0, sizeof (struct frv_io
));
7863 next_is_end_p
= false;
7864 CLEAR_HARD_REG_SET (used_regs
);
7866 else if (INSN_P (insn
))
7867 switch (recog_memoized (insn
))
7869 case CODE_FOR_optional_membar_qi
:
7870 case CODE_FOR_optional_membar_hi
:
7871 case CODE_FOR_optional_membar_si
:
7872 case CODE_FOR_optional_membar_di
:
7876 /* Local information isn't enough to decide whether this
7877 membar is needed. Stash it away for later. */
7878 *last_membar
= insn
;
7879 frv_extract_membar (next_io
, insn
);
7880 next_is_end_p
= false;
7884 /* Check whether the I/O operation before INSN could be
7885 reordered with one described by NEXT_IO. If it can't,
7886 INSN will not be needed. */
7887 struct frv_io prev_io
;
7889 frv_extract_membar (&prev_io
, insn
);
7890 if (frv_io_fixed_order_p (&prev_io
, next_io
))
7894 ";; [Local] Removing membar %d since order"
7895 " of accesses is guaranteed\n",
7896 INSN_UID (next_membar
));
7898 insn
= NEXT_INSN (insn
);
7899 delete_insn (next_membar
);
7907 /* Invalidate NEXT_IO's address if it depends on something that
7908 is clobbered by INSN. */
7909 if (next_io
->var_address
)
7910 note_stores (PATTERN (insn
), frv_io_check_address
,
7911 &next_io
->var_address
);
7913 /* If the next membar is associated with a __builtin_read,
7914 see if INSN reads from that address. If it does, and if
7915 the destination register is used before the next I/O access,
7916 there is no need for the membar. */
7917 set
= PATTERN (insn
);
7918 if (next_io
->type
== FRV_IO_READ
7919 && next_io
->var_address
!= 0
7921 && GET_CODE (set
) == SET
7922 && GET_CODE (SET_DEST (set
)) == REG
7923 && TEST_HARD_REG_BIT (used_regs
, REGNO (SET_DEST (set
))))
7927 src
= SET_SRC (set
);
7928 if (GET_CODE (src
) == ZERO_EXTEND
)
7929 src
= XEXP (src
, 0);
7931 if (GET_CODE (src
) == MEM
7932 && rtx_equal_p (XEXP (src
, 0), next_io
->var_address
))
7936 ";; [Local] Removing membar %d since the target"
7937 " of %d is used before the I/O operation\n",
7938 INSN_UID (next_membar
), INSN_UID (insn
));
7940 if (next_membar
== *last_membar
)
7943 delete_insn (next_membar
);
7948 /* If INSN has volatile references, forget about any registers
7949 that are used after it. Otherwise forget about uses that
7950 are (or might be) defined by INSN. */
7951 if (volatile_refs_p (PATTERN (insn
)))
7952 CLEAR_HARD_REG_SET (used_regs
);
7954 note_stores (PATTERN (insn
), frv_io_handle_set
, &used_regs
);
7956 note_uses (&PATTERN (insn
), frv_io_handle_use
, &used_regs
);
7961 /* See if MEMBAR, the last membar instruction in BB, can be removed.
7962 FIRST_IO[X] describes the first operation performed by basic block X. */
7965 frv_optimize_membar_global (basic_block bb
, struct frv_io
*first_io
,
7968 struct frv_io this_io
, next_io
;
7972 /* We need to keep the membar if there is an edge to the exit block. */
7973 FOR_EACH_EDGE (succ
, ei
, bb
->succs
)
7974 /* for (succ = bb->succ; succ != 0; succ = succ->succ_next) */
7975 if (succ
->dest
== EXIT_BLOCK_PTR_FOR_FN (cfun
))
7978 /* Work out the union of all successor blocks. */
7979 ei
= ei_start (bb
->succs
);
7980 ei_cond (ei
, &succ
);
7981 /* next_io = first_io[bb->succ->dest->index]; */
7982 next_io
= first_io
[succ
->dest
->index
];
7983 ei
= ei_start (bb
->succs
);
7984 if (ei_cond (ei
, &succ
))
7986 for (ei_next (&ei
); ei_cond (ei
, &succ
); ei_next (&ei
))
7987 /*for (succ = bb->succ->succ_next; succ != 0; succ = succ->succ_next)*/
7988 frv_io_union (&next_io
, &first_io
[succ
->dest
->index
]);
7993 frv_extract_membar (&this_io
, membar
);
7994 if (frv_io_fixed_order_p (&this_io
, &next_io
))
7998 ";; [Global] Removing membar %d since order of accesses"
7999 " is guaranteed\n", INSN_UID (membar
));
8001 delete_insn (membar
);
8005 /* Remove redundant membars from the current function. */
8008 frv_optimize_membar (void)
8011 struct frv_io
*first_io
;
8012 rtx_insn
**last_membar
;
8014 compute_bb_for_insn ();
8015 first_io
= XCNEWVEC (struct frv_io
, last_basic_block_for_fn (cfun
));
8016 last_membar
= XCNEWVEC (rtx_insn
*, last_basic_block_for_fn (cfun
));
8018 FOR_EACH_BB_FN (bb
, cfun
)
8019 frv_optimize_membar_local (bb
, &first_io
[bb
->index
],
8020 &last_membar
[bb
->index
]);
8022 FOR_EACH_BB_FN (bb
, cfun
)
8023 if (last_membar
[bb
->index
] != 0)
8024 frv_optimize_membar_global (bb
, first_io
, last_membar
[bb
->index
]);
8030 /* Used by frv_reorg to keep track of the current packet's address. */
8031 static unsigned int frv_packet_address
;
8033 /* If the current packet falls through to a label, try to pad the packet
8034 with nops in order to fit the label's alignment requirements. */
8037 frv_align_label (void)
8039 unsigned int alignment
, target
, nop
;
8040 rtx_insn
*x
, *last
, *barrier
, *label
;
8042 /* Walk forward to the start of the next packet. Set ALIGNMENT to the
8043 maximum alignment of that packet, LABEL to the last label between
8044 the packets, and BARRIER to the last barrier. */
8045 last
= frv_packet
.insns
[frv_packet
.num_insns
- 1];
8046 label
= barrier
= 0;
8048 for (x
= NEXT_INSN (last
); x
!= 0 && !INSN_P (x
); x
= NEXT_INSN (x
))
8052 unsigned int subalign
= 1 << label_to_alignment (x
);
8053 alignment
= MAX (alignment
, subalign
);
8060 /* If -malign-labels, and the packet falls through to an unaligned
8061 label, try introducing a nop to align that label to 8 bytes. */
8062 if (TARGET_ALIGN_LABELS
8065 && frv_packet
.num_insns
< frv_packet
.issue_rate
)
8066 alignment
= MAX (alignment
, 8);
8068 /* Advance the address to the end of the current packet. */
8069 frv_packet_address
+= frv_packet
.num_insns
* 4;
8071 /* Work out the target address, after alignment. */
8072 target
= (frv_packet_address
+ alignment
- 1) & -alignment
;
8074 /* If the packet falls through to the label, try to find an efficient
8075 padding sequence. */
8078 /* First try adding nops to the current packet. */
8079 for (nop
= 0; nop
< frv_num_nops
; nop
++)
8080 while (frv_packet_address
< target
&& frv_pack_insn_p (frv_nops
[nop
]))
8082 frv_insert_nop_in_packet (frv_nops
[nop
]);
8083 frv_packet_address
+= 4;
8086 /* If we still haven't reached the target, add some new packets that
8087 contain only nops. If there are two types of nop, insert an
8088 alternating sequence of frv_nops[0] and frv_nops[1], which will
8089 lead to packets like:
8096 etc. Just emit frv_nops[0] if that's the only nop we have. */
8097 last
= frv_packet
.insns
[frv_packet
.num_insns
- 1];
8099 while (frv_packet_address
< target
)
8101 last
= emit_insn_after (PATTERN (frv_nops
[nop
]), last
);
8102 frv_packet_address
+= 4;
8103 if (frv_num_nops
> 1)
8108 frv_packet_address
= target
;
8111 /* Subroutine of frv_reorg, called after each packet has been constructed
8115 frv_reorg_packet (void)
8117 frv_fill_unused_units (GROUP_I
);
8118 frv_fill_unused_units (GROUP_FM
);
8122 /* Add an instruction with pattern NOP to frv_nops[]. */
8125 frv_register_nop (rtx nop
)
8127 rtx_insn
*nop_insn
= make_insn_raw (nop
);
8128 SET_NEXT_INSN (nop_insn
) = 0;
8129 SET_PREV_INSN (nop_insn
) = 0;
8130 frv_nops
[frv_num_nops
++] = nop_insn
;
8133 /* Implement TARGET_MACHINE_DEPENDENT_REORG. Divide the instructions
8134 into packets and check whether we need to insert nops in order to
8135 fulfill the processor's issue requirements. Also, if the user has
8136 requested a certain alignment for a label, try to meet that alignment
8137 by inserting nops in the previous packet. */
8142 if (optimize
> 0 && TARGET_OPTIMIZE_MEMBAR
&& cfun
->machine
->has_membar_p
)
8143 frv_optimize_membar ();
8146 frv_register_nop (gen_nop ());
8148 frv_register_nop (gen_mnop ());
8149 if (TARGET_HARD_FLOAT
)
8150 frv_register_nop (gen_fnop ());
8152 /* Estimate the length of each branch. Although this may change after
8153 we've inserted nops, it will only do so in big functions. */
8154 shorten_branches (get_insns ());
8156 frv_packet_address
= 0;
8157 frv_for_each_packet (frv_reorg_packet
);
8160 #define def_builtin(name, type, code) \
8161 add_builtin_function ((name), (type), (code), BUILT_IN_MD, NULL, NULL)
8163 struct builtin_description
8165 enum insn_code icode
;
8167 enum frv_builtins code
;
8168 enum rtx_code comparison
;
8172 /* Media intrinsics that take a single, constant argument. */
8174 static struct builtin_description bdesc_set
[] =
8176 { CODE_FOR_mhdsets
, "__MHDSETS", FRV_BUILTIN_MHDSETS
, UNKNOWN
, 0 }
8179 /* Media intrinsics that take just one argument. */
8181 static struct builtin_description bdesc_1arg
[] =
8183 { CODE_FOR_mnot
, "__MNOT", FRV_BUILTIN_MNOT
, UNKNOWN
, 0 },
8184 { CODE_FOR_munpackh
, "__MUNPACKH", FRV_BUILTIN_MUNPACKH
, UNKNOWN
, 0 },
8185 { CODE_FOR_mbtoh
, "__MBTOH", FRV_BUILTIN_MBTOH
, UNKNOWN
, 0 },
8186 { CODE_FOR_mhtob
, "__MHTOB", FRV_BUILTIN_MHTOB
, UNKNOWN
, 0},
8187 { CODE_FOR_mabshs
, "__MABSHS", FRV_BUILTIN_MABSHS
, UNKNOWN
, 0 },
8188 { CODE_FOR_scutss
, "__SCUTSS", FRV_BUILTIN_SCUTSS
, UNKNOWN
, 0 }
8191 /* Media intrinsics that take two arguments. */
8193 static struct builtin_description bdesc_2arg
[] =
8195 { CODE_FOR_mand
, "__MAND", FRV_BUILTIN_MAND
, UNKNOWN
, 0},
8196 { CODE_FOR_mor
, "__MOR", FRV_BUILTIN_MOR
, UNKNOWN
, 0},
8197 { CODE_FOR_mxor
, "__MXOR", FRV_BUILTIN_MXOR
, UNKNOWN
, 0},
8198 { CODE_FOR_maveh
, "__MAVEH", FRV_BUILTIN_MAVEH
, UNKNOWN
, 0},
8199 { CODE_FOR_msaths
, "__MSATHS", FRV_BUILTIN_MSATHS
, UNKNOWN
, 0},
8200 { CODE_FOR_msathu
, "__MSATHU", FRV_BUILTIN_MSATHU
, UNKNOWN
, 0},
8201 { CODE_FOR_maddhss
, "__MADDHSS", FRV_BUILTIN_MADDHSS
, UNKNOWN
, 0},
8202 { CODE_FOR_maddhus
, "__MADDHUS", FRV_BUILTIN_MADDHUS
, UNKNOWN
, 0},
8203 { CODE_FOR_msubhss
, "__MSUBHSS", FRV_BUILTIN_MSUBHSS
, UNKNOWN
, 0},
8204 { CODE_FOR_msubhus
, "__MSUBHUS", FRV_BUILTIN_MSUBHUS
, UNKNOWN
, 0},
8205 { CODE_FOR_mqaddhss
, "__MQADDHSS", FRV_BUILTIN_MQADDHSS
, UNKNOWN
, 0},
8206 { CODE_FOR_mqaddhus
, "__MQADDHUS", FRV_BUILTIN_MQADDHUS
, UNKNOWN
, 0},
8207 { CODE_FOR_mqsubhss
, "__MQSUBHSS", FRV_BUILTIN_MQSUBHSS
, UNKNOWN
, 0},
8208 { CODE_FOR_mqsubhus
, "__MQSUBHUS", FRV_BUILTIN_MQSUBHUS
, UNKNOWN
, 0},
8209 { CODE_FOR_mpackh
, "__MPACKH", FRV_BUILTIN_MPACKH
, UNKNOWN
, 0},
8210 { CODE_FOR_mcop1
, "__Mcop1", FRV_BUILTIN_MCOP1
, UNKNOWN
, 0},
8211 { CODE_FOR_mcop2
, "__Mcop2", FRV_BUILTIN_MCOP2
, UNKNOWN
, 0},
8212 { CODE_FOR_mwcut
, "__MWCUT", FRV_BUILTIN_MWCUT
, UNKNOWN
, 0},
8213 { CODE_FOR_mqsaths
, "__MQSATHS", FRV_BUILTIN_MQSATHS
, UNKNOWN
, 0},
8214 { CODE_FOR_mqlclrhs
, "__MQLCLRHS", FRV_BUILTIN_MQLCLRHS
, UNKNOWN
, 0},
8215 { CODE_FOR_mqlmths
, "__MQLMTHS", FRV_BUILTIN_MQLMTHS
, UNKNOWN
, 0},
8216 { CODE_FOR_smul
, "__SMUL", FRV_BUILTIN_SMUL
, UNKNOWN
, 0},
8217 { CODE_FOR_umul
, "__UMUL", FRV_BUILTIN_UMUL
, UNKNOWN
, 0},
8218 { CODE_FOR_addss
, "__ADDSS", FRV_BUILTIN_ADDSS
, UNKNOWN
, 0},
8219 { CODE_FOR_subss
, "__SUBSS", FRV_BUILTIN_SUBSS
, UNKNOWN
, 0},
8220 { CODE_FOR_slass
, "__SLASS", FRV_BUILTIN_SLASS
, UNKNOWN
, 0},
8221 { CODE_FOR_scan
, "__SCAN", FRV_BUILTIN_SCAN
, UNKNOWN
, 0}
8224 /* Integer intrinsics that take two arguments and have no return value. */
8226 static struct builtin_description bdesc_int_void2arg
[] =
8228 { CODE_FOR_smass
, "__SMASS", FRV_BUILTIN_SMASS
, UNKNOWN
, 0},
8229 { CODE_FOR_smsss
, "__SMSSS", FRV_BUILTIN_SMSSS
, UNKNOWN
, 0},
8230 { CODE_FOR_smu
, "__SMU", FRV_BUILTIN_SMU
, UNKNOWN
, 0}
8233 static struct builtin_description bdesc_prefetches
[] =
8235 { CODE_FOR_frv_prefetch0
, "__data_prefetch0", FRV_BUILTIN_PREFETCH0
, UNKNOWN
,
8237 { CODE_FOR_frv_prefetch
, "__data_prefetch", FRV_BUILTIN_PREFETCH
, UNKNOWN
, 0}
8240 /* Media intrinsics that take two arguments, the first being an ACC number. */
8242 static struct builtin_description bdesc_cut
[] =
8244 { CODE_FOR_mcut
, "__MCUT", FRV_BUILTIN_MCUT
, UNKNOWN
, 0},
8245 { CODE_FOR_mcutss
, "__MCUTSS", FRV_BUILTIN_MCUTSS
, UNKNOWN
, 0},
8246 { CODE_FOR_mdcutssi
, "__MDCUTSSI", FRV_BUILTIN_MDCUTSSI
, UNKNOWN
, 0}
8249 /* Two-argument media intrinsics with an immediate second argument. */
8251 static struct builtin_description bdesc_2argimm
[] =
8253 { CODE_FOR_mrotli
, "__MROTLI", FRV_BUILTIN_MROTLI
, UNKNOWN
, 0},
8254 { CODE_FOR_mrotri
, "__MROTRI", FRV_BUILTIN_MROTRI
, UNKNOWN
, 0},
8255 { CODE_FOR_msllhi
, "__MSLLHI", FRV_BUILTIN_MSLLHI
, UNKNOWN
, 0},
8256 { CODE_FOR_msrlhi
, "__MSRLHI", FRV_BUILTIN_MSRLHI
, UNKNOWN
, 0},
8257 { CODE_FOR_msrahi
, "__MSRAHI", FRV_BUILTIN_MSRAHI
, UNKNOWN
, 0},
8258 { CODE_FOR_mexpdhw
, "__MEXPDHW", FRV_BUILTIN_MEXPDHW
, UNKNOWN
, 0},
8259 { CODE_FOR_mexpdhd
, "__MEXPDHD", FRV_BUILTIN_MEXPDHD
, UNKNOWN
, 0},
8260 { CODE_FOR_mdrotli
, "__MDROTLI", FRV_BUILTIN_MDROTLI
, UNKNOWN
, 0},
8261 { CODE_FOR_mcplhi
, "__MCPLHI", FRV_BUILTIN_MCPLHI
, UNKNOWN
, 0},
8262 { CODE_FOR_mcpli
, "__MCPLI", FRV_BUILTIN_MCPLI
, UNKNOWN
, 0},
8263 { CODE_FOR_mhsetlos
, "__MHSETLOS", FRV_BUILTIN_MHSETLOS
, UNKNOWN
, 0},
8264 { CODE_FOR_mhsetloh
, "__MHSETLOH", FRV_BUILTIN_MHSETLOH
, UNKNOWN
, 0},
8265 { CODE_FOR_mhsethis
, "__MHSETHIS", FRV_BUILTIN_MHSETHIS
, UNKNOWN
, 0},
8266 { CODE_FOR_mhsethih
, "__MHSETHIH", FRV_BUILTIN_MHSETHIH
, UNKNOWN
, 0},
8267 { CODE_FOR_mhdseth
, "__MHDSETH", FRV_BUILTIN_MHDSETH
, UNKNOWN
, 0},
8268 { CODE_FOR_mqsllhi
, "__MQSLLHI", FRV_BUILTIN_MQSLLHI
, UNKNOWN
, 0},
8269 { CODE_FOR_mqsrahi
, "__MQSRAHI", FRV_BUILTIN_MQSRAHI
, UNKNOWN
, 0}
8272 /* Media intrinsics that take two arguments and return void, the first argument
8273 being a pointer to 4 words in memory. */
8275 static struct builtin_description bdesc_void2arg
[] =
8277 { CODE_FOR_mdunpackh
, "__MDUNPACKH", FRV_BUILTIN_MDUNPACKH
, UNKNOWN
, 0},
8278 { CODE_FOR_mbtohe
, "__MBTOHE", FRV_BUILTIN_MBTOHE
, UNKNOWN
, 0},
8281 /* Media intrinsics that take three arguments, the first being a const_int that
8282 denotes an accumulator, and that return void. */
8284 static struct builtin_description bdesc_void3arg
[] =
8286 { CODE_FOR_mcpxrs
, "__MCPXRS", FRV_BUILTIN_MCPXRS
, UNKNOWN
, 0},
8287 { CODE_FOR_mcpxru
, "__MCPXRU", FRV_BUILTIN_MCPXRU
, UNKNOWN
, 0},
8288 { CODE_FOR_mcpxis
, "__MCPXIS", FRV_BUILTIN_MCPXIS
, UNKNOWN
, 0},
8289 { CODE_FOR_mcpxiu
, "__MCPXIU", FRV_BUILTIN_MCPXIU
, UNKNOWN
, 0},
8290 { CODE_FOR_mmulhs
, "__MMULHS", FRV_BUILTIN_MMULHS
, UNKNOWN
, 0},
8291 { CODE_FOR_mmulhu
, "__MMULHU", FRV_BUILTIN_MMULHU
, UNKNOWN
, 0},
8292 { CODE_FOR_mmulxhs
, "__MMULXHS", FRV_BUILTIN_MMULXHS
, UNKNOWN
, 0},
8293 { CODE_FOR_mmulxhu
, "__MMULXHU", FRV_BUILTIN_MMULXHU
, UNKNOWN
, 0},
8294 { CODE_FOR_mmachs
, "__MMACHS", FRV_BUILTIN_MMACHS
, UNKNOWN
, 0},
8295 { CODE_FOR_mmachu
, "__MMACHU", FRV_BUILTIN_MMACHU
, UNKNOWN
, 0},
8296 { CODE_FOR_mmrdhs
, "__MMRDHS", FRV_BUILTIN_MMRDHS
, UNKNOWN
, 0},
8297 { CODE_FOR_mmrdhu
, "__MMRDHU", FRV_BUILTIN_MMRDHU
, UNKNOWN
, 0},
8298 { CODE_FOR_mqcpxrs
, "__MQCPXRS", FRV_BUILTIN_MQCPXRS
, UNKNOWN
, 0},
8299 { CODE_FOR_mqcpxru
, "__MQCPXRU", FRV_BUILTIN_MQCPXRU
, UNKNOWN
, 0},
8300 { CODE_FOR_mqcpxis
, "__MQCPXIS", FRV_BUILTIN_MQCPXIS
, UNKNOWN
, 0},
8301 { CODE_FOR_mqcpxiu
, "__MQCPXIU", FRV_BUILTIN_MQCPXIU
, UNKNOWN
, 0},
8302 { CODE_FOR_mqmulhs
, "__MQMULHS", FRV_BUILTIN_MQMULHS
, UNKNOWN
, 0},
8303 { CODE_FOR_mqmulhu
, "__MQMULHU", FRV_BUILTIN_MQMULHU
, UNKNOWN
, 0},
8304 { CODE_FOR_mqmulxhs
, "__MQMULXHS", FRV_BUILTIN_MQMULXHS
, UNKNOWN
, 0},
8305 { CODE_FOR_mqmulxhu
, "__MQMULXHU", FRV_BUILTIN_MQMULXHU
, UNKNOWN
, 0},
8306 { CODE_FOR_mqmachs
, "__MQMACHS", FRV_BUILTIN_MQMACHS
, UNKNOWN
, 0},
8307 { CODE_FOR_mqmachu
, "__MQMACHU", FRV_BUILTIN_MQMACHU
, UNKNOWN
, 0},
8308 { CODE_FOR_mqxmachs
, "__MQXMACHS", FRV_BUILTIN_MQXMACHS
, UNKNOWN
, 0},
8309 { CODE_FOR_mqxmacxhs
, "__MQXMACXHS", FRV_BUILTIN_MQXMACXHS
, UNKNOWN
, 0},
8310 { CODE_FOR_mqmacxhs
, "__MQMACXHS", FRV_BUILTIN_MQMACXHS
, UNKNOWN
, 0}
8313 /* Media intrinsics that take two accumulator numbers as argument and
8316 static struct builtin_description bdesc_voidacc
[] =
8318 { CODE_FOR_maddaccs
, "__MADDACCS", FRV_BUILTIN_MADDACCS
, UNKNOWN
, 0},
8319 { CODE_FOR_msubaccs
, "__MSUBACCS", FRV_BUILTIN_MSUBACCS
, UNKNOWN
, 0},
8320 { CODE_FOR_masaccs
, "__MASACCS", FRV_BUILTIN_MASACCS
, UNKNOWN
, 0},
8321 { CODE_FOR_mdaddaccs
, "__MDADDACCS", FRV_BUILTIN_MDADDACCS
, UNKNOWN
, 0},
8322 { CODE_FOR_mdsubaccs
, "__MDSUBACCS", FRV_BUILTIN_MDSUBACCS
, UNKNOWN
, 0},
8323 { CODE_FOR_mdasaccs
, "__MDASACCS", FRV_BUILTIN_MDASACCS
, UNKNOWN
, 0}
8326 /* Intrinsics that load a value and then issue a MEMBAR. The load is
8327 a normal move and the ICODE is for the membar. */
8329 static struct builtin_description bdesc_loads
[] =
8331 { CODE_FOR_optional_membar_qi
, "__builtin_read8",
8332 FRV_BUILTIN_READ8
, UNKNOWN
, 0},
8333 { CODE_FOR_optional_membar_hi
, "__builtin_read16",
8334 FRV_BUILTIN_READ16
, UNKNOWN
, 0},
8335 { CODE_FOR_optional_membar_si
, "__builtin_read32",
8336 FRV_BUILTIN_READ32
, UNKNOWN
, 0},
8337 { CODE_FOR_optional_membar_di
, "__builtin_read64",
8338 FRV_BUILTIN_READ64
, UNKNOWN
, 0}
8341 /* Likewise stores. */
8343 static struct builtin_description bdesc_stores
[] =
8345 { CODE_FOR_optional_membar_qi
, "__builtin_write8",
8346 FRV_BUILTIN_WRITE8
, UNKNOWN
, 0},
8347 { CODE_FOR_optional_membar_hi
, "__builtin_write16",
8348 FRV_BUILTIN_WRITE16
, UNKNOWN
, 0},
8349 { CODE_FOR_optional_membar_si
, "__builtin_write32",
8350 FRV_BUILTIN_WRITE32
, UNKNOWN
, 0},
8351 { CODE_FOR_optional_membar_di
, "__builtin_write64",
8352 FRV_BUILTIN_WRITE64
, UNKNOWN
, 0},
8355 /* Initialize media builtins. */
8358 frv_init_builtins (void)
8360 tree accumulator
= integer_type_node
;
8361 tree integer
= integer_type_node
;
8362 tree voidt
= void_type_node
;
8363 tree uhalf
= short_unsigned_type_node
;
8364 tree sword1
= long_integer_type_node
;
8365 tree uword1
= long_unsigned_type_node
;
8366 tree sword2
= long_long_integer_type_node
;
8367 tree uword2
= long_long_unsigned_type_node
;
8368 tree uword4
= build_pointer_type (uword1
);
8369 tree vptr
= build_pointer_type (build_type_variant (void_type_node
, 0, 1));
8370 tree ubyte
= unsigned_char_type_node
;
8371 tree iacc
= integer_type_node
;
8373 #define UNARY(RET, T1) \
8374 build_function_type_list (RET, T1, NULL_TREE)
8376 #define BINARY(RET, T1, T2) \
8377 build_function_type_list (RET, T1, T2, NULL_TREE)
8379 #define TRINARY(RET, T1, T2, T3) \
8380 build_function_type_list (RET, T1, T2, T3, NULL_TREE)
8382 #define QUAD(RET, T1, T2, T3, T4) \
8383 build_function_type_list (RET, T1, T2, T3, T4, NULL_TREE)
8385 tree void_ftype_void
= build_function_type_list (voidt
, NULL_TREE
);
8387 tree void_ftype_acc
= UNARY (voidt
, accumulator
);
8388 tree void_ftype_uw4_uw1
= BINARY (voidt
, uword4
, uword1
);
8389 tree void_ftype_uw4_uw2
= BINARY (voidt
, uword4
, uword2
);
8390 tree void_ftype_acc_uw1
= BINARY (voidt
, accumulator
, uword1
);
8391 tree void_ftype_acc_acc
= BINARY (voidt
, accumulator
, accumulator
);
8392 tree void_ftype_acc_uw1_uw1
= TRINARY (voidt
, accumulator
, uword1
, uword1
);
8393 tree void_ftype_acc_sw1_sw1
= TRINARY (voidt
, accumulator
, sword1
, sword1
);
8394 tree void_ftype_acc_uw2_uw2
= TRINARY (voidt
, accumulator
, uword2
, uword2
);
8395 tree void_ftype_acc_sw2_sw2
= TRINARY (voidt
, accumulator
, sword2
, sword2
);
8397 tree uw1_ftype_uw1
= UNARY (uword1
, uword1
);
8398 tree uw1_ftype_sw1
= UNARY (uword1
, sword1
);
8399 tree uw1_ftype_uw2
= UNARY (uword1
, uword2
);
8400 tree uw1_ftype_acc
= UNARY (uword1
, accumulator
);
8401 tree uw1_ftype_uh_uh
= BINARY (uword1
, uhalf
, uhalf
);
8402 tree uw1_ftype_uw1_uw1
= BINARY (uword1
, uword1
, uword1
);
8403 tree uw1_ftype_uw1_int
= BINARY (uword1
, uword1
, integer
);
8404 tree uw1_ftype_acc_uw1
= BINARY (uword1
, accumulator
, uword1
);
8405 tree uw1_ftype_acc_sw1
= BINARY (uword1
, accumulator
, sword1
);
8406 tree uw1_ftype_uw2_uw1
= BINARY (uword1
, uword2
, uword1
);
8407 tree uw1_ftype_uw2_int
= BINARY (uword1
, uword2
, integer
);
8409 tree sw1_ftype_int
= UNARY (sword1
, integer
);
8410 tree sw1_ftype_sw1_sw1
= BINARY (sword1
, sword1
, sword1
);
8411 tree sw1_ftype_sw1_int
= BINARY (sword1
, sword1
, integer
);
8413 tree uw2_ftype_uw1
= UNARY (uword2
, uword1
);
8414 tree uw2_ftype_uw1_int
= BINARY (uword2
, uword1
, integer
);
8415 tree uw2_ftype_uw2_uw2
= BINARY (uword2
, uword2
, uword2
);
8416 tree uw2_ftype_uw2_int
= BINARY (uword2
, uword2
, integer
);
8417 tree uw2_ftype_acc_int
= BINARY (uword2
, accumulator
, integer
);
8418 tree uw2_ftype_uh_uh_uh_uh
= QUAD (uword2
, uhalf
, uhalf
, uhalf
, uhalf
);
8420 tree sw2_ftype_sw2_sw2
= BINARY (sword2
, sword2
, sword2
);
8421 tree sw2_ftype_sw2_int
= BINARY (sword2
, sword2
, integer
);
8422 tree uw2_ftype_uw1_uw1
= BINARY (uword2
, uword1
, uword1
);
8423 tree sw2_ftype_sw1_sw1
= BINARY (sword2
, sword1
, sword1
);
8424 tree void_ftype_sw1_sw1
= BINARY (voidt
, sword1
, sword1
);
8425 tree void_ftype_iacc_sw2
= BINARY (voidt
, iacc
, sword2
);
8426 tree void_ftype_iacc_sw1
= BINARY (voidt
, iacc
, sword1
);
8427 tree sw1_ftype_sw1
= UNARY (sword1
, sword1
);
8428 tree sw2_ftype_iacc
= UNARY (sword2
, iacc
);
8429 tree sw1_ftype_iacc
= UNARY (sword1
, iacc
);
8430 tree void_ftype_ptr
= UNARY (voidt
, const_ptr_type_node
);
8431 tree uw1_ftype_vptr
= UNARY (uword1
, vptr
);
8432 tree uw2_ftype_vptr
= UNARY (uword2
, vptr
);
8433 tree void_ftype_vptr_ub
= BINARY (voidt
, vptr
, ubyte
);
8434 tree void_ftype_vptr_uh
= BINARY (voidt
, vptr
, uhalf
);
8435 tree void_ftype_vptr_uw1
= BINARY (voidt
, vptr
, uword1
);
8436 tree void_ftype_vptr_uw2
= BINARY (voidt
, vptr
, uword2
);
8438 def_builtin ("__MAND", uw1_ftype_uw1_uw1
, FRV_BUILTIN_MAND
);
8439 def_builtin ("__MOR", uw1_ftype_uw1_uw1
, FRV_BUILTIN_MOR
);
8440 def_builtin ("__MXOR", uw1_ftype_uw1_uw1
, FRV_BUILTIN_MXOR
);
8441 def_builtin ("__MNOT", uw1_ftype_uw1
, FRV_BUILTIN_MNOT
);
8442 def_builtin ("__MROTLI", uw1_ftype_uw1_int
, FRV_BUILTIN_MROTLI
);
8443 def_builtin ("__MROTRI", uw1_ftype_uw1_int
, FRV_BUILTIN_MROTRI
);
8444 def_builtin ("__MWCUT", uw1_ftype_uw2_uw1
, FRV_BUILTIN_MWCUT
);
8445 def_builtin ("__MAVEH", uw1_ftype_uw1_uw1
, FRV_BUILTIN_MAVEH
);
8446 def_builtin ("__MSLLHI", uw1_ftype_uw1_int
, FRV_BUILTIN_MSLLHI
);
8447 def_builtin ("__MSRLHI", uw1_ftype_uw1_int
, FRV_BUILTIN_MSRLHI
);
8448 def_builtin ("__MSRAHI", sw1_ftype_sw1_int
, FRV_BUILTIN_MSRAHI
);
8449 def_builtin ("__MSATHS", sw1_ftype_sw1_sw1
, FRV_BUILTIN_MSATHS
);
8450 def_builtin ("__MSATHU", uw1_ftype_uw1_uw1
, FRV_BUILTIN_MSATHU
);
8451 def_builtin ("__MADDHSS", sw1_ftype_sw1_sw1
, FRV_BUILTIN_MADDHSS
);
8452 def_builtin ("__MADDHUS", uw1_ftype_uw1_uw1
, FRV_BUILTIN_MADDHUS
);
8453 def_builtin ("__MSUBHSS", sw1_ftype_sw1_sw1
, FRV_BUILTIN_MSUBHSS
);
8454 def_builtin ("__MSUBHUS", uw1_ftype_uw1_uw1
, FRV_BUILTIN_MSUBHUS
);
8455 def_builtin ("__MMULHS", void_ftype_acc_sw1_sw1
, FRV_BUILTIN_MMULHS
);
8456 def_builtin ("__MMULHU", void_ftype_acc_uw1_uw1
, FRV_BUILTIN_MMULHU
);
8457 def_builtin ("__MMULXHS", void_ftype_acc_sw1_sw1
, FRV_BUILTIN_MMULXHS
);
8458 def_builtin ("__MMULXHU", void_ftype_acc_uw1_uw1
, FRV_BUILTIN_MMULXHU
);
8459 def_builtin ("__MMACHS", void_ftype_acc_sw1_sw1
, FRV_BUILTIN_MMACHS
);
8460 def_builtin ("__MMACHU", void_ftype_acc_uw1_uw1
, FRV_BUILTIN_MMACHU
);
8461 def_builtin ("__MMRDHS", void_ftype_acc_sw1_sw1
, FRV_BUILTIN_MMRDHS
);
8462 def_builtin ("__MMRDHU", void_ftype_acc_uw1_uw1
, FRV_BUILTIN_MMRDHU
);
8463 def_builtin ("__MQADDHSS", sw2_ftype_sw2_sw2
, FRV_BUILTIN_MQADDHSS
);
8464 def_builtin ("__MQADDHUS", uw2_ftype_uw2_uw2
, FRV_BUILTIN_MQADDHUS
);
8465 def_builtin ("__MQSUBHSS", sw2_ftype_sw2_sw2
, FRV_BUILTIN_MQSUBHSS
);
8466 def_builtin ("__MQSUBHUS", uw2_ftype_uw2_uw2
, FRV_BUILTIN_MQSUBHUS
);
8467 def_builtin ("__MQMULHS", void_ftype_acc_sw2_sw2
, FRV_BUILTIN_MQMULHS
);
8468 def_builtin ("__MQMULHU", void_ftype_acc_uw2_uw2
, FRV_BUILTIN_MQMULHU
);
8469 def_builtin ("__MQMULXHS", void_ftype_acc_sw2_sw2
, FRV_BUILTIN_MQMULXHS
);
8470 def_builtin ("__MQMULXHU", void_ftype_acc_uw2_uw2
, FRV_BUILTIN_MQMULXHU
);
8471 def_builtin ("__MQMACHS", void_ftype_acc_sw2_sw2
, FRV_BUILTIN_MQMACHS
);
8472 def_builtin ("__MQMACHU", void_ftype_acc_uw2_uw2
, FRV_BUILTIN_MQMACHU
);
8473 def_builtin ("__MCPXRS", void_ftype_acc_sw1_sw1
, FRV_BUILTIN_MCPXRS
);
8474 def_builtin ("__MCPXRU", void_ftype_acc_uw1_uw1
, FRV_BUILTIN_MCPXRU
);
8475 def_builtin ("__MCPXIS", void_ftype_acc_sw1_sw1
, FRV_BUILTIN_MCPXIS
);
8476 def_builtin ("__MCPXIU", void_ftype_acc_uw1_uw1
, FRV_BUILTIN_MCPXIU
);
8477 def_builtin ("__MQCPXRS", void_ftype_acc_sw2_sw2
, FRV_BUILTIN_MQCPXRS
);
8478 def_builtin ("__MQCPXRU", void_ftype_acc_uw2_uw2
, FRV_BUILTIN_MQCPXRU
);
8479 def_builtin ("__MQCPXIS", void_ftype_acc_sw2_sw2
, FRV_BUILTIN_MQCPXIS
);
8480 def_builtin ("__MQCPXIU", void_ftype_acc_uw2_uw2
, FRV_BUILTIN_MQCPXIU
);
8481 def_builtin ("__MCUT", uw1_ftype_acc_uw1
, FRV_BUILTIN_MCUT
);
8482 def_builtin ("__MCUTSS", uw1_ftype_acc_sw1
, FRV_BUILTIN_MCUTSS
);
8483 def_builtin ("__MEXPDHW", uw1_ftype_uw1_int
, FRV_BUILTIN_MEXPDHW
);
8484 def_builtin ("__MEXPDHD", uw2_ftype_uw1_int
, FRV_BUILTIN_MEXPDHD
);
8485 def_builtin ("__MPACKH", uw1_ftype_uh_uh
, FRV_BUILTIN_MPACKH
);
8486 def_builtin ("__MUNPACKH", uw2_ftype_uw1
, FRV_BUILTIN_MUNPACKH
);
8487 def_builtin ("__MDPACKH", uw2_ftype_uh_uh_uh_uh
, FRV_BUILTIN_MDPACKH
);
8488 def_builtin ("__MDUNPACKH", void_ftype_uw4_uw2
, FRV_BUILTIN_MDUNPACKH
);
8489 def_builtin ("__MBTOH", uw2_ftype_uw1
, FRV_BUILTIN_MBTOH
);
8490 def_builtin ("__MHTOB", uw1_ftype_uw2
, FRV_BUILTIN_MHTOB
);
8491 def_builtin ("__MBTOHE", void_ftype_uw4_uw1
, FRV_BUILTIN_MBTOHE
);
8492 def_builtin ("__MCLRACC", void_ftype_acc
, FRV_BUILTIN_MCLRACC
);
8493 def_builtin ("__MCLRACCA", void_ftype_void
, FRV_BUILTIN_MCLRACCA
);
8494 def_builtin ("__MRDACC", uw1_ftype_acc
, FRV_BUILTIN_MRDACC
);
8495 def_builtin ("__MRDACCG", uw1_ftype_acc
, FRV_BUILTIN_MRDACCG
);
8496 def_builtin ("__MWTACC", void_ftype_acc_uw1
, FRV_BUILTIN_MWTACC
);
8497 def_builtin ("__MWTACCG", void_ftype_acc_uw1
, FRV_BUILTIN_MWTACCG
);
8498 def_builtin ("__Mcop1", uw1_ftype_uw1_uw1
, FRV_BUILTIN_MCOP1
);
8499 def_builtin ("__Mcop2", uw1_ftype_uw1_uw1
, FRV_BUILTIN_MCOP2
);
8500 def_builtin ("__MTRAP", void_ftype_void
, FRV_BUILTIN_MTRAP
);
8501 def_builtin ("__MQXMACHS", void_ftype_acc_sw2_sw2
, FRV_BUILTIN_MQXMACHS
);
8502 def_builtin ("__MQXMACXHS", void_ftype_acc_sw2_sw2
, FRV_BUILTIN_MQXMACXHS
);
8503 def_builtin ("__MQMACXHS", void_ftype_acc_sw2_sw2
, FRV_BUILTIN_MQMACXHS
);
8504 def_builtin ("__MADDACCS", void_ftype_acc_acc
, FRV_BUILTIN_MADDACCS
);
8505 def_builtin ("__MSUBACCS", void_ftype_acc_acc
, FRV_BUILTIN_MSUBACCS
);
8506 def_builtin ("__MASACCS", void_ftype_acc_acc
, FRV_BUILTIN_MASACCS
);
8507 def_builtin ("__MDADDACCS", void_ftype_acc_acc
, FRV_BUILTIN_MDADDACCS
);
8508 def_builtin ("__MDSUBACCS", void_ftype_acc_acc
, FRV_BUILTIN_MDSUBACCS
);
8509 def_builtin ("__MDASACCS", void_ftype_acc_acc
, FRV_BUILTIN_MDASACCS
);
8510 def_builtin ("__MABSHS", uw1_ftype_sw1
, FRV_BUILTIN_MABSHS
);
8511 def_builtin ("__MDROTLI", uw2_ftype_uw2_int
, FRV_BUILTIN_MDROTLI
);
8512 def_builtin ("__MCPLHI", uw1_ftype_uw2_int
, FRV_BUILTIN_MCPLHI
);
8513 def_builtin ("__MCPLI", uw1_ftype_uw2_int
, FRV_BUILTIN_MCPLI
);
8514 def_builtin ("__MDCUTSSI", uw2_ftype_acc_int
, FRV_BUILTIN_MDCUTSSI
);
8515 def_builtin ("__MQSATHS", sw2_ftype_sw2_sw2
, FRV_BUILTIN_MQSATHS
);
8516 def_builtin ("__MHSETLOS", sw1_ftype_sw1_int
, FRV_BUILTIN_MHSETLOS
);
8517 def_builtin ("__MHSETHIS", sw1_ftype_sw1_int
, FRV_BUILTIN_MHSETHIS
);
8518 def_builtin ("__MHDSETS", sw1_ftype_int
, FRV_BUILTIN_MHDSETS
);
8519 def_builtin ("__MHSETLOH", uw1_ftype_uw1_int
, FRV_BUILTIN_MHSETLOH
);
8520 def_builtin ("__MHSETHIH", uw1_ftype_uw1_int
, FRV_BUILTIN_MHSETHIH
);
8521 def_builtin ("__MHDSETH", uw1_ftype_uw1_int
, FRV_BUILTIN_MHDSETH
);
8522 def_builtin ("__MQLCLRHS", sw2_ftype_sw2_sw2
, FRV_BUILTIN_MQLCLRHS
);
8523 def_builtin ("__MQLMTHS", sw2_ftype_sw2_sw2
, FRV_BUILTIN_MQLMTHS
);
8524 def_builtin ("__MQSLLHI", uw2_ftype_uw2_int
, FRV_BUILTIN_MQSLLHI
);
8525 def_builtin ("__MQSRAHI", sw2_ftype_sw2_int
, FRV_BUILTIN_MQSRAHI
);
8526 def_builtin ("__SMUL", sw2_ftype_sw1_sw1
, FRV_BUILTIN_SMUL
);
8527 def_builtin ("__UMUL", uw2_ftype_uw1_uw1
, FRV_BUILTIN_UMUL
);
8528 def_builtin ("__SMASS", void_ftype_sw1_sw1
, FRV_BUILTIN_SMASS
);
8529 def_builtin ("__SMSSS", void_ftype_sw1_sw1
, FRV_BUILTIN_SMSSS
);
8530 def_builtin ("__SMU", void_ftype_sw1_sw1
, FRV_BUILTIN_SMU
);
8531 def_builtin ("__ADDSS", sw1_ftype_sw1_sw1
, FRV_BUILTIN_ADDSS
);
8532 def_builtin ("__SUBSS", sw1_ftype_sw1_sw1
, FRV_BUILTIN_SUBSS
);
8533 def_builtin ("__SLASS", sw1_ftype_sw1_sw1
, FRV_BUILTIN_SLASS
);
8534 def_builtin ("__SCAN", sw1_ftype_sw1_sw1
, FRV_BUILTIN_SCAN
);
8535 def_builtin ("__SCUTSS", sw1_ftype_sw1
, FRV_BUILTIN_SCUTSS
);
8536 def_builtin ("__IACCreadll", sw2_ftype_iacc
, FRV_BUILTIN_IACCreadll
);
8537 def_builtin ("__IACCreadl", sw1_ftype_iacc
, FRV_BUILTIN_IACCreadl
);
8538 def_builtin ("__IACCsetll", void_ftype_iacc_sw2
, FRV_BUILTIN_IACCsetll
);
8539 def_builtin ("__IACCsetl", void_ftype_iacc_sw1
, FRV_BUILTIN_IACCsetl
);
8540 def_builtin ("__data_prefetch0", void_ftype_ptr
, FRV_BUILTIN_PREFETCH0
);
8541 def_builtin ("__data_prefetch", void_ftype_ptr
, FRV_BUILTIN_PREFETCH
);
8542 def_builtin ("__builtin_read8", uw1_ftype_vptr
, FRV_BUILTIN_READ8
);
8543 def_builtin ("__builtin_read16", uw1_ftype_vptr
, FRV_BUILTIN_READ16
);
8544 def_builtin ("__builtin_read32", uw1_ftype_vptr
, FRV_BUILTIN_READ32
);
8545 def_builtin ("__builtin_read64", uw2_ftype_vptr
, FRV_BUILTIN_READ64
);
8547 def_builtin ("__builtin_write8", void_ftype_vptr_ub
, FRV_BUILTIN_WRITE8
);
8548 def_builtin ("__builtin_write16", void_ftype_vptr_uh
, FRV_BUILTIN_WRITE16
);
8549 def_builtin ("__builtin_write32", void_ftype_vptr_uw1
, FRV_BUILTIN_WRITE32
);
8550 def_builtin ("__builtin_write64", void_ftype_vptr_uw2
, FRV_BUILTIN_WRITE64
);
8558 /* Set the names for various arithmetic operations according to the
8561 frv_init_libfuncs (void)
8563 set_optab_libfunc (smod_optab
, SImode
, "__modi");
8564 set_optab_libfunc (umod_optab
, SImode
, "__umodi");
8566 set_optab_libfunc (add_optab
, DImode
, "__addll");
8567 set_optab_libfunc (sub_optab
, DImode
, "__subll");
8568 set_optab_libfunc (smul_optab
, DImode
, "__mulll");
8569 set_optab_libfunc (sdiv_optab
, DImode
, "__divll");
8570 set_optab_libfunc (smod_optab
, DImode
, "__modll");
8571 set_optab_libfunc (umod_optab
, DImode
, "__umodll");
8572 set_optab_libfunc (and_optab
, DImode
, "__andll");
8573 set_optab_libfunc (ior_optab
, DImode
, "__orll");
8574 set_optab_libfunc (xor_optab
, DImode
, "__xorll");
8575 set_optab_libfunc (one_cmpl_optab
, DImode
, "__notll");
8577 set_optab_libfunc (add_optab
, SFmode
, "__addf");
8578 set_optab_libfunc (sub_optab
, SFmode
, "__subf");
8579 set_optab_libfunc (smul_optab
, SFmode
, "__mulf");
8580 set_optab_libfunc (sdiv_optab
, SFmode
, "__divf");
8582 set_optab_libfunc (add_optab
, DFmode
, "__addd");
8583 set_optab_libfunc (sub_optab
, DFmode
, "__subd");
8584 set_optab_libfunc (smul_optab
, DFmode
, "__muld");
8585 set_optab_libfunc (sdiv_optab
, DFmode
, "__divd");
8587 set_conv_libfunc (sext_optab
, DFmode
, SFmode
, "__ftod");
8588 set_conv_libfunc (trunc_optab
, SFmode
, DFmode
, "__dtof");
8590 set_conv_libfunc (sfix_optab
, SImode
, SFmode
, "__ftoi");
8591 set_conv_libfunc (sfix_optab
, DImode
, SFmode
, "__ftoll");
8592 set_conv_libfunc (sfix_optab
, SImode
, DFmode
, "__dtoi");
8593 set_conv_libfunc (sfix_optab
, DImode
, DFmode
, "__dtoll");
8595 set_conv_libfunc (ufix_optab
, SImode
, SFmode
, "__ftoui");
8596 set_conv_libfunc (ufix_optab
, DImode
, SFmode
, "__ftoull");
8597 set_conv_libfunc (ufix_optab
, SImode
, DFmode
, "__dtoui");
8598 set_conv_libfunc (ufix_optab
, DImode
, DFmode
, "__dtoull");
8600 set_conv_libfunc (sfloat_optab
, SFmode
, SImode
, "__itof");
8601 set_conv_libfunc (sfloat_optab
, SFmode
, DImode
, "__lltof");
8602 set_conv_libfunc (sfloat_optab
, DFmode
, SImode
, "__itod");
8603 set_conv_libfunc (sfloat_optab
, DFmode
, DImode
, "__lltod");
8606 /* Convert an integer constant to an accumulator register. ICODE is the
8607 code of the target instruction, OPNUM is the number of the
8608 accumulator operand and OPVAL is the constant integer. Try both
8609 ACC and ACCG registers; only report an error if neither fit the
8613 frv_int_to_acc (enum insn_code icode
, int opnum
, rtx opval
)
8618 /* ACCs and ACCGs are implicit global registers if media intrinsics
8619 are being used. We set up this lazily to avoid creating lots of
8620 unnecessary call_insn rtl in non-media code. */
8621 for (i
= 0; i
<= ACC_MASK
; i
++)
8622 if ((i
& ACC_MASK
) == i
)
8623 global_regs
[i
+ ACC_FIRST
] = global_regs
[i
+ ACCG_FIRST
] = 1;
8625 if (GET_CODE (opval
) != CONST_INT
)
8627 error ("accumulator is not a constant integer");
8630 if ((INTVAL (opval
) & ~ACC_MASK
) != 0)
8632 error ("accumulator number is out of bounds");
8636 reg
= gen_rtx_REG (insn_data
[icode
].operand
[opnum
].mode
,
8637 ACC_FIRST
+ INTVAL (opval
));
8638 if (! (*insn_data
[icode
].operand
[opnum
].predicate
) (reg
, VOIDmode
))
8639 SET_REGNO (reg
, ACCG_FIRST
+ INTVAL (opval
));
8641 if (! (*insn_data
[icode
].operand
[opnum
].predicate
) (reg
, VOIDmode
))
8643 error ("inappropriate accumulator for %qs", insn_data
[icode
].name
);
8649 /* If an ACC rtx has mode MODE, return the mode that the matching ACCG
8653 frv_matching_accg_mode (machine_mode mode
)
8671 /* Given that a __builtin_read or __builtin_write function is accessing
8672 address ADDRESS, return the value that should be used as operand 1
8676 frv_io_address_cookie (rtx address
)
8678 return (GET_CODE (address
) == CONST_INT
8679 ? GEN_INT (INTVAL (address
) / 8 * 8)
8683 /* Return the accumulator guard that should be paired with accumulator
8684 register ACC. The mode of the returned register is in the same
8685 class as ACC, but is four times smaller. */
8688 frv_matching_accg_for_acc (rtx acc
)
8690 return gen_rtx_REG (frv_matching_accg_mode (GET_MODE (acc
)),
8691 REGNO (acc
) - ACC_FIRST
+ ACCG_FIRST
);
8694 /* Read the requested argument from the call EXP given by INDEX.
8695 Return the value as an rtx. */
8698 frv_read_argument (tree exp
, unsigned int index
)
8700 return expand_normal (CALL_EXPR_ARG (exp
, index
));
8703 /* Like frv_read_argument, but interpret the argument as the number
8704 of an IACC register and return a (reg:MODE ...) rtx for it. */
8707 frv_read_iacc_argument (machine_mode mode
, tree call
,
8713 op
= frv_read_argument (call
, index
);
8714 if (GET_CODE (op
) != CONST_INT
8716 || INTVAL (op
) > IACC_LAST
- IACC_FIRST
8717 || ((INTVAL (op
) * 4) & (GET_MODE_SIZE (mode
) - 1)) != 0)
8719 error ("invalid IACC argument");
8723 /* IACCs are implicit global registers. We set up this lazily to
8724 avoid creating lots of unnecessary call_insn rtl when IACCs aren't
8726 regno
= INTVAL (op
) + IACC_FIRST
;
8727 for (i
= 0; i
< HARD_REGNO_NREGS (regno
, mode
); i
++)
8728 global_regs
[regno
+ i
] = 1;
8730 return gen_rtx_REG (mode
, regno
);
8733 /* Return true if OPVAL can be used for operand OPNUM of instruction ICODE.
8734 The instruction should require a constant operand of some sort. The
8735 function prints an error if OPVAL is not valid. */
8738 frv_check_constant_argument (enum insn_code icode
, int opnum
, rtx opval
)
8740 if (GET_CODE (opval
) != CONST_INT
)
8742 error ("%qs expects a constant argument", insn_data
[icode
].name
);
8745 if (! (*insn_data
[icode
].operand
[opnum
].predicate
) (opval
, VOIDmode
))
8747 error ("constant argument out of range for %qs", insn_data
[icode
].name
);
8753 /* Return a legitimate rtx for instruction ICODE's return value. Use TARGET
8754 if it's not null, has the right mode, and satisfies operand 0's
8758 frv_legitimize_target (enum insn_code icode
, rtx target
)
8760 machine_mode mode
= insn_data
[icode
].operand
[0].mode
;
8763 || GET_MODE (target
) != mode
8764 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, mode
))
8765 return gen_reg_rtx (mode
);
8770 /* Given that ARG is being passed as operand OPNUM to instruction ICODE,
8771 check whether ARG satisfies the operand's constraints. If it doesn't,
8772 copy ARG to a temporary register and return that. Otherwise return ARG
8776 frv_legitimize_argument (enum insn_code icode
, int opnum
, rtx arg
)
8778 machine_mode mode
= insn_data
[icode
].operand
[opnum
].mode
;
8780 if ((*insn_data
[icode
].operand
[opnum
].predicate
) (arg
, mode
))
8783 return copy_to_mode_reg (mode
, arg
);
8786 /* Return a volatile memory reference of mode MODE whose address is ARG. */
8789 frv_volatile_memref (machine_mode mode
, rtx arg
)
8793 mem
= gen_rtx_MEM (mode
, memory_address (mode
, arg
));
8794 MEM_VOLATILE_P (mem
) = 1;
8798 /* Expand builtins that take a single, constant argument. At the moment,
8799 only MHDSETS falls into this category. */
8802 frv_expand_set_builtin (enum insn_code icode
, tree call
, rtx target
)
8805 rtx op0
= frv_read_argument (call
, 0);
8807 if (! frv_check_constant_argument (icode
, 1, op0
))
8810 target
= frv_legitimize_target (icode
, target
);
8811 pat
= GEN_FCN (icode
) (target
, op0
);
8819 /* Expand builtins that take one operand. */
8822 frv_expand_unop_builtin (enum insn_code icode
, tree call
, rtx target
)
8825 rtx op0
= frv_read_argument (call
, 0);
8827 target
= frv_legitimize_target (icode
, target
);
8828 op0
= frv_legitimize_argument (icode
, 1, op0
);
8829 pat
= GEN_FCN (icode
) (target
, op0
);
8837 /* Expand builtins that take two operands. */
8840 frv_expand_binop_builtin (enum insn_code icode
, tree call
, rtx target
)
8843 rtx op0
= frv_read_argument (call
, 0);
8844 rtx op1
= frv_read_argument (call
, 1);
8846 target
= frv_legitimize_target (icode
, target
);
8847 op0
= frv_legitimize_argument (icode
, 1, op0
);
8848 op1
= frv_legitimize_argument (icode
, 2, op1
);
8849 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
8857 /* Expand cut-style builtins, which take two operands and an implicit ACCG
8861 frv_expand_cut_builtin (enum insn_code icode
, tree call
, rtx target
)
8864 rtx op0
= frv_read_argument (call
, 0);
8865 rtx op1
= frv_read_argument (call
, 1);
8868 target
= frv_legitimize_target (icode
, target
);
8869 op0
= frv_int_to_acc (icode
, 1, op0
);
8873 if (icode
== CODE_FOR_mdcutssi
|| GET_CODE (op1
) == CONST_INT
)
8875 if (! frv_check_constant_argument (icode
, 2, op1
))
8879 op1
= frv_legitimize_argument (icode
, 2, op1
);
8881 op2
= frv_matching_accg_for_acc (op0
);
8882 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
8890 /* Expand builtins that take two operands and the second is immediate. */
8893 frv_expand_binopimm_builtin (enum insn_code icode
, tree call
, rtx target
)
8896 rtx op0
= frv_read_argument (call
, 0);
8897 rtx op1
= frv_read_argument (call
, 1);
8899 if (! frv_check_constant_argument (icode
, 2, op1
))
8902 target
= frv_legitimize_target (icode
, target
);
8903 op0
= frv_legitimize_argument (icode
, 1, op0
);
8904 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
8912 /* Expand builtins that take two operands, the first operand being a pointer to
8913 ints and return void. */
8916 frv_expand_voidbinop_builtin (enum insn_code icode
, tree call
)
8919 rtx op0
= frv_read_argument (call
, 0);
8920 rtx op1
= frv_read_argument (call
, 1);
8921 machine_mode mode0
= insn_data
[icode
].operand
[0].mode
;
8924 if (GET_CODE (op0
) != MEM
)
8928 if (! offsettable_address_p (0, mode0
, op0
))
8930 reg
= gen_reg_rtx (Pmode
);
8931 emit_insn (gen_rtx_SET (reg
, op0
));
8934 op0
= gen_rtx_MEM (SImode
, reg
);
8937 addr
= XEXP (op0
, 0);
8938 if (! offsettable_address_p (0, mode0
, addr
))
8939 addr
= copy_to_mode_reg (Pmode
, op0
);
8941 op0
= change_address (op0
, V4SImode
, addr
);
8942 op1
= frv_legitimize_argument (icode
, 1, op1
);
8943 pat
= GEN_FCN (icode
) (op0
, op1
);
8951 /* Expand builtins that take two long operands and return void. */
8954 frv_expand_int_void2arg (enum insn_code icode
, tree call
)
8957 rtx op0
= frv_read_argument (call
, 0);
8958 rtx op1
= frv_read_argument (call
, 1);
8960 op0
= frv_legitimize_argument (icode
, 1, op0
);
8961 op1
= frv_legitimize_argument (icode
, 1, op1
);
8962 pat
= GEN_FCN (icode
) (op0
, op1
);
8970 /* Expand prefetch builtins. These take a single address as argument. */
8973 frv_expand_prefetches (enum insn_code icode
, tree call
)
8976 rtx op0
= frv_read_argument (call
, 0);
8978 pat
= GEN_FCN (icode
) (force_reg (Pmode
, op0
));
8986 /* Expand builtins that take three operands and return void. The first
8987 argument must be a constant that describes a pair or quad accumulators. A
8988 fourth argument is created that is the accumulator guard register that
8989 corresponds to the accumulator. */
8992 frv_expand_voidtriop_builtin (enum insn_code icode
, tree call
)
8995 rtx op0
= frv_read_argument (call
, 0);
8996 rtx op1
= frv_read_argument (call
, 1);
8997 rtx op2
= frv_read_argument (call
, 2);
9000 op0
= frv_int_to_acc (icode
, 0, op0
);
9004 op1
= frv_legitimize_argument (icode
, 1, op1
);
9005 op2
= frv_legitimize_argument (icode
, 2, op2
);
9006 op3
= frv_matching_accg_for_acc (op0
);
9007 pat
= GEN_FCN (icode
) (op0
, op1
, op2
, op3
);
9015 /* Expand builtins that perform accumulator-to-accumulator operations.
9016 These builtins take two accumulator numbers as argument and return
9020 frv_expand_voidaccop_builtin (enum insn_code icode
, tree call
)
9023 rtx op0
= frv_read_argument (call
, 0);
9024 rtx op1
= frv_read_argument (call
, 1);
9028 op0
= frv_int_to_acc (icode
, 0, op0
);
9032 op1
= frv_int_to_acc (icode
, 1, op1
);
9036 op2
= frv_matching_accg_for_acc (op0
);
9037 op3
= frv_matching_accg_for_acc (op1
);
9038 pat
= GEN_FCN (icode
) (op0
, op1
, op2
, op3
);
9046 /* Expand a __builtin_read* function. ICODE is the instruction code for the
9047 membar and TARGET_MODE is the mode that the loaded value should have. */
9050 frv_expand_load_builtin (enum insn_code icode
, machine_mode target_mode
,
9051 tree call
, rtx target
)
9053 rtx op0
= frv_read_argument (call
, 0);
9054 rtx cookie
= frv_io_address_cookie (op0
);
9056 if (target
== 0 || !REG_P (target
))
9057 target
= gen_reg_rtx (target_mode
);
9058 op0
= frv_volatile_memref (insn_data
[icode
].operand
[0].mode
, op0
);
9059 convert_move (target
, op0
, 1);
9060 emit_insn (GEN_FCN (icode
) (copy_rtx (op0
), cookie
, GEN_INT (FRV_IO_READ
)));
9061 cfun
->machine
->has_membar_p
= 1;
9065 /* Likewise __builtin_write* functions. */
9068 frv_expand_store_builtin (enum insn_code icode
, tree call
)
9070 rtx op0
= frv_read_argument (call
, 0);
9071 rtx op1
= frv_read_argument (call
, 1);
9072 rtx cookie
= frv_io_address_cookie (op0
);
9074 op0
= frv_volatile_memref (insn_data
[icode
].operand
[0].mode
, op0
);
9075 convert_move (op0
, force_reg (insn_data
[icode
].operand
[0].mode
, op1
), 1);
9076 emit_insn (GEN_FCN (icode
) (copy_rtx (op0
), cookie
, GEN_INT (FRV_IO_WRITE
)));
9077 cfun
->machine
->has_membar_p
= 1;
9081 /* Expand the MDPACKH builtin. It takes four unsigned short arguments and
9082 each argument forms one word of the two double-word input registers.
9083 CALL is the tree for the call and TARGET, if nonnull, suggests a good place
9084 to put the return value. */
9087 frv_expand_mdpackh_builtin (tree call
, rtx target
)
9089 enum insn_code icode
= CODE_FOR_mdpackh
;
9091 rtx arg1
= frv_read_argument (call
, 0);
9092 rtx arg2
= frv_read_argument (call
, 1);
9093 rtx arg3
= frv_read_argument (call
, 2);
9094 rtx arg4
= frv_read_argument (call
, 3);
9096 target
= frv_legitimize_target (icode
, target
);
9097 op0
= gen_reg_rtx (DImode
);
9098 op1
= gen_reg_rtx (DImode
);
9100 /* The high half of each word is not explicitly initialized, so indicate
9101 that the input operands are not live before this point. */
9105 /* Move each argument into the low half of its associated input word. */
9106 emit_move_insn (simplify_gen_subreg (HImode
, op0
, DImode
, 2), arg1
);
9107 emit_move_insn (simplify_gen_subreg (HImode
, op0
, DImode
, 6), arg2
);
9108 emit_move_insn (simplify_gen_subreg (HImode
, op1
, DImode
, 2), arg3
);
9109 emit_move_insn (simplify_gen_subreg (HImode
, op1
, DImode
, 6), arg4
);
9111 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
9119 /* Expand the MCLRACC builtin. This builtin takes a single accumulator
9120 number as argument. */
9123 frv_expand_mclracc_builtin (tree call
)
9125 enum insn_code icode
= CODE_FOR_mclracc
;
9127 rtx op0
= frv_read_argument (call
, 0);
9129 op0
= frv_int_to_acc (icode
, 0, op0
);
9133 pat
= GEN_FCN (icode
) (op0
);
9140 /* Expand builtins that take no arguments. */
9143 frv_expand_noargs_builtin (enum insn_code icode
)
9145 rtx pat
= GEN_FCN (icode
) (const0_rtx
);
9152 /* Expand MRDACC and MRDACCG. These builtins take a single accumulator
9153 number or accumulator guard number as argument and return an SI integer. */
9156 frv_expand_mrdacc_builtin (enum insn_code icode
, tree call
)
9159 rtx target
= gen_reg_rtx (SImode
);
9160 rtx op0
= frv_read_argument (call
, 0);
9162 op0
= frv_int_to_acc (icode
, 1, op0
);
9166 pat
= GEN_FCN (icode
) (target
, op0
);
9174 /* Expand MWTACC and MWTACCG. These builtins take an accumulator or
9175 accumulator guard as their first argument and an SImode value as their
9179 frv_expand_mwtacc_builtin (enum insn_code icode
, tree call
)
9182 rtx op0
= frv_read_argument (call
, 0);
9183 rtx op1
= frv_read_argument (call
, 1);
9185 op0
= frv_int_to_acc (icode
, 0, op0
);
9189 op1
= frv_legitimize_argument (icode
, 1, op1
);
9190 pat
= GEN_FCN (icode
) (op0
, op1
);
9197 /* Emit a move from SRC to DEST in SImode chunks. This can be used
9198 to move DImode values into and out of IACC0. */
9201 frv_split_iacc_move (rtx dest
, rtx src
)
9206 inner
= GET_MODE (dest
);
9207 for (i
= 0; i
< GET_MODE_SIZE (inner
); i
+= GET_MODE_SIZE (SImode
))
9208 emit_move_insn (simplify_gen_subreg (SImode
, dest
, inner
, i
),
9209 simplify_gen_subreg (SImode
, src
, inner
, i
));
9212 /* Expand builtins. */
9215 frv_expand_builtin (tree exp
,
9217 rtx subtarget ATTRIBUTE_UNUSED
,
9218 machine_mode mode ATTRIBUTE_UNUSED
,
9219 int ignore ATTRIBUTE_UNUSED
)
9221 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
9222 unsigned fcode
= (unsigned)DECL_FUNCTION_CODE (fndecl
);
9224 struct builtin_description
*d
;
9226 if (fcode
< FRV_BUILTIN_FIRST_NONMEDIA
&& !TARGET_MEDIA
)
9228 error ("media functions are not available unless -mmedia is used");
9234 case FRV_BUILTIN_MCOP1
:
9235 case FRV_BUILTIN_MCOP2
:
9236 case FRV_BUILTIN_MDUNPACKH
:
9237 case FRV_BUILTIN_MBTOHE
:
9238 if (! TARGET_MEDIA_REV1
)
9240 error ("this media function is only available on the fr500");
9245 case FRV_BUILTIN_MQXMACHS
:
9246 case FRV_BUILTIN_MQXMACXHS
:
9247 case FRV_BUILTIN_MQMACXHS
:
9248 case FRV_BUILTIN_MADDACCS
:
9249 case FRV_BUILTIN_MSUBACCS
:
9250 case FRV_BUILTIN_MASACCS
:
9251 case FRV_BUILTIN_MDADDACCS
:
9252 case FRV_BUILTIN_MDSUBACCS
:
9253 case FRV_BUILTIN_MDASACCS
:
9254 case FRV_BUILTIN_MABSHS
:
9255 case FRV_BUILTIN_MDROTLI
:
9256 case FRV_BUILTIN_MCPLHI
:
9257 case FRV_BUILTIN_MCPLI
:
9258 case FRV_BUILTIN_MDCUTSSI
:
9259 case FRV_BUILTIN_MQSATHS
:
9260 case FRV_BUILTIN_MHSETLOS
:
9261 case FRV_BUILTIN_MHSETLOH
:
9262 case FRV_BUILTIN_MHSETHIS
:
9263 case FRV_BUILTIN_MHSETHIH
:
9264 case FRV_BUILTIN_MHDSETS
:
9265 case FRV_BUILTIN_MHDSETH
:
9266 if (! TARGET_MEDIA_REV2
)
9268 error ("this media function is only available on the fr400"
9274 case FRV_BUILTIN_SMASS
:
9275 case FRV_BUILTIN_SMSSS
:
9276 case FRV_BUILTIN_SMU
:
9277 case FRV_BUILTIN_ADDSS
:
9278 case FRV_BUILTIN_SUBSS
:
9279 case FRV_BUILTIN_SLASS
:
9280 case FRV_BUILTIN_SCUTSS
:
9281 case FRV_BUILTIN_IACCreadll
:
9282 case FRV_BUILTIN_IACCreadl
:
9283 case FRV_BUILTIN_IACCsetll
:
9284 case FRV_BUILTIN_IACCsetl
:
9285 if (!TARGET_FR405_BUILTINS
)
9287 error ("this builtin function is only available"
9288 " on the fr405 and fr450");
9293 case FRV_BUILTIN_PREFETCH
:
9294 if (!TARGET_FR500_FR550_BUILTINS
)
9296 error ("this builtin function is only available on the fr500"
9302 case FRV_BUILTIN_MQLCLRHS
:
9303 case FRV_BUILTIN_MQLMTHS
:
9304 case FRV_BUILTIN_MQSLLHI
:
9305 case FRV_BUILTIN_MQSRAHI
:
9306 if (!TARGET_MEDIA_FR450
)
9308 error ("this builtin function is only available on the fr450");
9317 /* Expand unique builtins. */
9321 case FRV_BUILTIN_MTRAP
:
9322 return frv_expand_noargs_builtin (CODE_FOR_mtrap
);
9324 case FRV_BUILTIN_MCLRACC
:
9325 return frv_expand_mclracc_builtin (exp
);
9327 case FRV_BUILTIN_MCLRACCA
:
9329 return frv_expand_noargs_builtin (CODE_FOR_mclracca8
);
9331 return frv_expand_noargs_builtin (CODE_FOR_mclracca4
);
9333 case FRV_BUILTIN_MRDACC
:
9334 return frv_expand_mrdacc_builtin (CODE_FOR_mrdacc
, exp
);
9336 case FRV_BUILTIN_MRDACCG
:
9337 return frv_expand_mrdacc_builtin (CODE_FOR_mrdaccg
, exp
);
9339 case FRV_BUILTIN_MWTACC
:
9340 return frv_expand_mwtacc_builtin (CODE_FOR_mwtacc
, exp
);
9342 case FRV_BUILTIN_MWTACCG
:
9343 return frv_expand_mwtacc_builtin (CODE_FOR_mwtaccg
, exp
);
9345 case FRV_BUILTIN_MDPACKH
:
9346 return frv_expand_mdpackh_builtin (exp
, target
);
9348 case FRV_BUILTIN_IACCreadll
:
9350 rtx src
= frv_read_iacc_argument (DImode
, exp
, 0);
9351 if (target
== 0 || !REG_P (target
))
9352 target
= gen_reg_rtx (DImode
);
9353 frv_split_iacc_move (target
, src
);
9357 case FRV_BUILTIN_IACCreadl
:
9358 return frv_read_iacc_argument (SImode
, exp
, 0);
9360 case FRV_BUILTIN_IACCsetll
:
9362 rtx dest
= frv_read_iacc_argument (DImode
, exp
, 0);
9363 rtx src
= frv_read_argument (exp
, 1);
9364 frv_split_iacc_move (dest
, force_reg (DImode
, src
));
9368 case FRV_BUILTIN_IACCsetl
:
9370 rtx dest
= frv_read_iacc_argument (SImode
, exp
, 0);
9371 rtx src
= frv_read_argument (exp
, 1);
9372 emit_move_insn (dest
, force_reg (SImode
, src
));
9380 /* Expand groups of builtins. */
9382 for (i
= 0, d
= bdesc_set
; i
< ARRAY_SIZE (bdesc_set
); i
++, d
++)
9383 if (d
->code
== fcode
)
9384 return frv_expand_set_builtin (d
->icode
, exp
, target
);
9386 for (i
= 0, d
= bdesc_1arg
; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
9387 if (d
->code
== fcode
)
9388 return frv_expand_unop_builtin (d
->icode
, exp
, target
);
9390 for (i
= 0, d
= bdesc_2arg
; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
9391 if (d
->code
== fcode
)
9392 return frv_expand_binop_builtin (d
->icode
, exp
, target
);
9394 for (i
= 0, d
= bdesc_cut
; i
< ARRAY_SIZE (bdesc_cut
); i
++, d
++)
9395 if (d
->code
== fcode
)
9396 return frv_expand_cut_builtin (d
->icode
, exp
, target
);
9398 for (i
= 0, d
= bdesc_2argimm
; i
< ARRAY_SIZE (bdesc_2argimm
); i
++, d
++)
9399 if (d
->code
== fcode
)
9400 return frv_expand_binopimm_builtin (d
->icode
, exp
, target
);
9402 for (i
= 0, d
= bdesc_void2arg
; i
< ARRAY_SIZE (bdesc_void2arg
); i
++, d
++)
9403 if (d
->code
== fcode
)
9404 return frv_expand_voidbinop_builtin (d
->icode
, exp
);
9406 for (i
= 0, d
= bdesc_void3arg
; i
< ARRAY_SIZE (bdesc_void3arg
); i
++, d
++)
9407 if (d
->code
== fcode
)
9408 return frv_expand_voidtriop_builtin (d
->icode
, exp
);
9410 for (i
= 0, d
= bdesc_voidacc
; i
< ARRAY_SIZE (bdesc_voidacc
); i
++, d
++)
9411 if (d
->code
== fcode
)
9412 return frv_expand_voidaccop_builtin (d
->icode
, exp
);
9414 for (i
= 0, d
= bdesc_int_void2arg
;
9415 i
< ARRAY_SIZE (bdesc_int_void2arg
); i
++, d
++)
9416 if (d
->code
== fcode
)
9417 return frv_expand_int_void2arg (d
->icode
, exp
);
9419 for (i
= 0, d
= bdesc_prefetches
;
9420 i
< ARRAY_SIZE (bdesc_prefetches
); i
++, d
++)
9421 if (d
->code
== fcode
)
9422 return frv_expand_prefetches (d
->icode
, exp
);
9424 for (i
= 0, d
= bdesc_loads
; i
< ARRAY_SIZE (bdesc_loads
); i
++, d
++)
9425 if (d
->code
== fcode
)
9426 return frv_expand_load_builtin (d
->icode
, TYPE_MODE (TREE_TYPE (exp
)),
9429 for (i
= 0, d
= bdesc_stores
; i
< ARRAY_SIZE (bdesc_stores
); i
++, d
++)
9430 if (d
->code
== fcode
)
9431 return frv_expand_store_builtin (d
->icode
, exp
);
9437 frv_in_small_data_p (const_tree decl
)
9440 const char *section_name
;
9442 /* Don't apply the -G flag to internal compiler structures. We
9443 should leave such structures in the main data section, partly
9444 for efficiency and partly because the size of some of them
9445 (such as C++ typeinfos) is not known until later. */
9446 if (TREE_CODE (decl
) != VAR_DECL
|| DECL_ARTIFICIAL (decl
))
9449 /* If we already know which section the decl should be in, see if
9450 it's a small data section. */
9451 section_name
= DECL_SECTION_NAME (decl
);
9454 if (frv_string_begins_with (section_name
, ".sdata"))
9456 if (frv_string_begins_with (section_name
, ".sbss"))
9461 size
= int_size_in_bytes (TREE_TYPE (decl
));
9462 if (size
> 0 && size
<= g_switch_value
)
9469 frv_rtx_costs (rtx x
,
9470 int code ATTRIBUTE_UNUSED
,
9471 int outer_code ATTRIBUTE_UNUSED
,
9472 int opno ATTRIBUTE_UNUSED
,
9474 bool speed ATTRIBUTE_UNUSED
)
9476 if (outer_code
== MEM
)
9478 /* Don't differentiate between memory addresses. All the ones
9479 we accept have equal cost. */
9480 *total
= COSTS_N_INSNS (0);
9487 /* Make 12-bit integers really cheap. */
9488 if (IN_RANGE (INTVAL (x
), -2048, 2047))
9499 *total
= COSTS_N_INSNS (2);
9513 if (GET_MODE (x
) == SImode
)
9514 *total
= COSTS_N_INSNS (1);
9515 else if (GET_MODE (x
) == DImode
)
9516 *total
= COSTS_N_INSNS (2);
9518 *total
= COSTS_N_INSNS (3);
9522 if (GET_MODE (x
) == SImode
)
9523 *total
= COSTS_N_INSNS (2);
9525 *total
= COSTS_N_INSNS (6); /* guess */
9532 *total
= COSTS_N_INSNS (18);
9536 *total
= COSTS_N_INSNS (3);
9545 frv_asm_out_constructor (rtx symbol
, int priority ATTRIBUTE_UNUSED
)
9547 switch_to_section (ctors_section
);
9548 assemble_align (POINTER_SIZE
);
9551 int ok
= frv_assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, 1);
9556 assemble_integer_with_op ("\t.picptr\t", symbol
);
9560 frv_asm_out_destructor (rtx symbol
, int priority ATTRIBUTE_UNUSED
)
9562 switch_to_section (dtors_section
);
9563 assemble_align (POINTER_SIZE
);
9566 int ok
= frv_assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, 1);
9571 assemble_integer_with_op ("\t.picptr\t", symbol
);
9574 /* Worker function for TARGET_STRUCT_VALUE_RTX. */
9577 frv_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED
,
9578 int incoming ATTRIBUTE_UNUSED
)
9580 return gen_rtx_REG (Pmode
, FRV_STRUCT_VALUE_REGNUM
);
9583 #define TLS_BIAS (2048 - 16)
9585 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
9586 We need to emit DTP-relative relocations. */
9589 frv_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
9591 gcc_assert (size
== 4);
9592 fputs ("\t.picptr\ttlsmoff(", file
);
9593 /* We want the unbiased TLS offset, so add the bias to the
9594 expression, such that the implicit biasing cancels out. */
9595 output_addr_const (file
, plus_constant (Pmode
, x
, TLS_BIAS
));