]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/frv/frv.c
Make more use of regs_invalidated_by_call
[thirdparty/gcc.git] / gcc / config / frv / frv.c
CommitLineData
a5544970 1/* Copyright (C) 1997-2019 Free Software Foundation, Inc.
36a05131
BS
2 Contributed by Red Hat, Inc.
3
7ec022b2 4This file is part of GCC.
36a05131 5
7ec022b2 6GCC is free software; you can redistribute it and/or modify
36a05131 7it under the terms of the GNU General Public License as published by
2f83c7d6 8the Free Software Foundation; either version 3, or (at your option)
36a05131
BS
9any later version.
10
7ec022b2 11GCC is distributed in the hope that it will be useful,
36a05131
BS
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
2f83c7d6
NC
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
36a05131 19
8fcc61f8
RS
20#define IN_TARGET_CODE 1
21
36a05131
BS
22#include "config.h"
23#include "system.h"
4977bab6 24#include "coretypes.h"
c7131fb2 25#include "backend.h"
e11c4407 26#include "target.h"
c7131fb2 27#include "rtl.h"
e11c4407 28#include "tree.h"
c7131fb2 29#include "df.h"
4d0cdd0c 30#include "memmodel.h"
e11c4407
AM
31#include "tm_p.h"
32#include "stringpool.h"
314e6352 33#include "attribs.h"
e11c4407
AM
34#include "optabs.h"
35#include "regs.h"
36#include "emit-rtl.h"
37#include "recog.h"
38#include "diagnostic-core.h"
40e23961 39#include "fold-const.h"
d8a2d370
DN
40#include "varasm.h"
41#include "stor-layout.h"
36a05131
BS
42#include "output.h"
43#include "insn-attr.h"
36566b39 44#include "explow.h"
36a05131 45#include "expr.h"
60393bbc 46#include "cfgrtl.h"
6e34d3a3 47#include "langhooks.h"
7ee2468b 48#include "dumpfile.h"
9b2b7279 49#include "builtins.h"
893479de 50#include "ifcvt.h"
cc665e56 51#include "rtl-iter.h"
a7c81bc1 52#include "calls.h"
36a05131 53
994c5d85 54/* This file should be included last. */
d58627a0
RS
55#include "target-def.h"
56
36a05131
BS
57#ifndef FRV_INLINE
58#define FRV_INLINE inline
59#endif
60
c557edf4
RS
61/* The maximum number of distinct NOP patterns. There are three:
62 nop, fnop and mnop. */
63#define NUM_NOP_PATTERNS 3
64
65/* Classification of instructions and units: integer, floating-point/media,
66 branch and control. */
67enum frv_insn_group { GROUP_I, GROUP_FM, GROUP_B, GROUP_C, NUM_GROUPS };
68
69/* The DFA names of the units, in packet order. */
70static const char *const frv_unit_names[] =
71{
72 "c",
73 "i0", "f0",
74 "i1", "f1",
75 "i2", "f2",
76 "i3", "f3",
77 "b0", "b1"
78};
79
80/* The classification of each unit in frv_unit_names[]. */
81static const enum frv_insn_group frv_unit_groups[ARRAY_SIZE (frv_unit_names)] =
82{
83 GROUP_C,
84 GROUP_I, GROUP_FM,
85 GROUP_I, GROUP_FM,
86 GROUP_I, GROUP_FM,
87 GROUP_I, GROUP_FM,
88 GROUP_B, GROUP_B
89};
90
91/* Return the DFA unit code associated with the Nth unit of integer
92 or floating-point group GROUP, */
93#define NTH_UNIT(GROUP, N) frv_unit_codes[(GROUP) + (N) * 2 + 1]
94
95/* Return the number of integer or floating-point unit UNIT
96 (1 for I1, 2 for F2, etc.). */
97#define UNIT_NUMBER(UNIT) (((UNIT) - 1) / 2)
98
99/* The DFA unit number for each unit in frv_unit_names[]. */
100static int frv_unit_codes[ARRAY_SIZE (frv_unit_names)];
101
102/* FRV_TYPE_TO_UNIT[T] is the last unit in frv_unit_names[] that can issue
103 an instruction of type T. The value is ARRAY_SIZE (frv_unit_names) if
104 no instruction of type T has been seen. */
105static unsigned int frv_type_to_unit[TYPE_UNKNOWN + 1];
106
107/* An array of dummy nop INSNs, one for each type of nop that the
108 target supports. */
e6eda746 109static GTY(()) rtx_insn *frv_nops[NUM_NOP_PATTERNS];
c557edf4
RS
110
111/* The number of nop instructions in frv_nops[]. */
112static unsigned int frv_num_nops;
113
5c5e8419
JR
114 /* The type of access. FRV_IO_UNKNOWN means the access can be either
115 a read or a write. */
116enum frv_io_type { FRV_IO_UNKNOWN, FRV_IO_READ, FRV_IO_WRITE };
117
38c28a25
AH
118/* Information about one __builtin_read or __builtin_write access, or
119 the combination of several such accesses. The most general value
120 is all-zeros (an unknown access to an unknown address). */
121struct frv_io {
5c5e8419 122 enum frv_io_type type;
38c28a25
AH
123
124 /* The constant address being accessed, or zero if not known. */
125 HOST_WIDE_INT const_address;
126
127 /* The run-time address, as used in operand 0 of the membar pattern. */
128 rtx var_address;
129};
130
c557edf4
RS
131/* Return true if instruction INSN should be packed with the following
132 instruction. */
133#define PACKING_FLAG_P(INSN) (GET_MODE (INSN) == TImode)
134
135/* Set the value of PACKING_FLAG_P(INSN). */
136#define SET_PACKING_FLAG(INSN) PUT_MODE (INSN, TImode)
137#define CLEAR_PACKING_FLAG(INSN) PUT_MODE (INSN, VOIDmode)
138
139/* Loop with REG set to each hard register in rtx X. */
140#define FOR_EACH_REGNO(REG, X) \
036620db 141 for (REG = REGNO (X); REG < END_REGNO (X); REG++)
c557edf4 142
38c28a25 143/* This structure contains machine specific function data. */
d1b38208 144struct GTY(()) machine_function
38c28a25
AH
145{
146 /* True if we have created an rtx that relies on the stack frame. */
147 int frame_needed;
148
149 /* True if this function contains at least one __builtin_{read,write}*. */
150 bool has_membar_p;
151};
152
36a05131
BS
153/* Temporary register allocation support structure. */
154typedef struct frv_tmp_reg_struct
155 {
156 HARD_REG_SET regs; /* possible registers to allocate */
157 int next_reg[N_REG_CLASSES]; /* next register to allocate per class */
158 }
159frv_tmp_reg_t;
160
c557edf4 161/* Register state information for VLIW re-packing phase. */
36a05131 162#define REGSTATE_CC_MASK 0x07 /* Mask to isolate CCn for cond exec */
c557edf4
RS
163#define REGSTATE_MODIFIED 0x08 /* reg modified in current VLIW insn */
164#define REGSTATE_IF_TRUE 0x10 /* reg modified in cond exec true */
165#define REGSTATE_IF_FALSE 0x20 /* reg modified in cond exec false */
166
36a05131
BS
167#define REGSTATE_IF_EITHER (REGSTATE_IF_TRUE | REGSTATE_IF_FALSE)
168
c557edf4 169typedef unsigned char regstate_t;
36a05131
BS
170
171/* Used in frv_frame_accessor_t to indicate the direction of a register-to-
172 memory move. */
173enum frv_stack_op
174{
175 FRV_LOAD,
176 FRV_STORE
177};
178
179/* Information required by frv_frame_access. */
180typedef struct
181{
182 /* This field is FRV_LOAD if registers are to be loaded from the stack and
183 FRV_STORE if they should be stored onto the stack. FRV_STORE implies
184 the move is being done by the prologue code while FRV_LOAD implies it
185 is being done by the epilogue. */
186 enum frv_stack_op op;
187
188 /* The base register to use when accessing the stack. This may be the
189 frame pointer, stack pointer, or a temporary. The choice of register
190 depends on which part of the frame is being accessed and how big the
191 frame is. */
192 rtx base;
193
194 /* The offset of BASE from the bottom of the current frame, in bytes. */
195 int base_offset;
196} frv_frame_accessor_t;
197
87b483a1 198/* Conditional execution support gathered together in one structure. */
36a05131
BS
199typedef struct
200 {
201 /* Linked list of insns to add if the conditional execution conversion was
202 successful. Each link points to an EXPR_LIST which points to the pattern
203 of the insn to add, and the insn to be inserted before. */
204 rtx added_insns_list;
205
206 /* Identify which registers are safe to allocate for if conversions to
207 conditional execution. We keep the last allocated register in the
208 register classes between COND_EXEC statements. This will mean we allocate
209 different registers for each different COND_EXEC group if we can. This
210 might allow the scheduler to intermix two different COND_EXEC sections. */
211 frv_tmp_reg_t tmp_reg;
212
213 /* For nested IFs, identify which CC registers are used outside of setting
214 via a compare isnsn, and using via a check insn. This will allow us to
215 know if we can rewrite the register to use a different register that will
216 be paired with the CR register controlling the nested IF-THEN blocks. */
217 HARD_REG_SET nested_cc_ok_rewrite;
218
219 /* Temporary registers allocated to hold constants during conditional
220 execution. */
221 rtx scratch_regs[FIRST_PSEUDO_REGISTER];
222
223 /* Current number of temp registers available. */
224 int cur_scratch_regs;
225
87b483a1 226 /* Number of nested conditional execution blocks. */
36a05131
BS
227 int num_nested_cond_exec;
228
229 /* Map of insns that set up constants in scratch registers. */
230 bitmap scratch_insns_bitmap;
231
87b483a1 232 /* Conditional execution test register (CC0..CC7). */
36a05131
BS
233 rtx cr_reg;
234
235 /* Conditional execution compare register that is paired with cr_reg, so that
236 nested compares can be done. The csubcc and caddcc instructions don't
237 have enough bits to specify both a CC register to be set and a CR register
238 to do the test on, so the same bit number is used for both. Needless to
839a4992 239 say, this is rather inconvenient for GCC. */
36a05131
BS
240 rtx nested_cc_reg;
241
242 /* Extra CR registers used for &&, ||. */
243 rtx extra_int_cr;
244 rtx extra_fp_cr;
245
246 /* Previous CR used in nested if, to make sure we are dealing with the same
87b483a1 247 nested if as the previous statement. */
36a05131
BS
248 rtx last_nested_if_cr;
249 }
250frv_ifcvt_t;
251
252static /* GTY(()) */ frv_ifcvt_t frv_ifcvt;
253
254/* Map register number to smallest register class. */
255enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
256
87b483a1 257/* Cached value of frv_stack_info. */
36a05131
BS
258static frv_stack_t *frv_stack_cache = (frv_stack_t *)0;
259
36a05131 260/* Forward references */
0b2c18fe 261
c5387660 262static void frv_option_override (void);
ef4bddc2 263static bool frv_legitimate_address_p (machine_mode, rtx, bool);
f2206911 264static int frv_default_flags_for_cpu (void);
f961457f 265static int frv_string_begins_with (const char *, const char *);
34208acf 266static FRV_INLINE bool frv_small_data_reloc_p (rtx, int);
0fb30cb7 267static void frv_print_operand (FILE *, rtx, int);
cc8ca59e 268static void frv_print_operand_address (FILE *, machine_mode, rtx);
0fb30cb7 269static bool frv_print_operand_punct_valid_p (unsigned char code);
36a05131 270static void frv_print_operand_memory_reference_reg
f2206911
KC
271 (FILE *, rtx);
272static void frv_print_operand_memory_reference (FILE *, rtx, int);
68a1a6c0 273static int frv_print_operand_jump_hint (rtx_insn *);
036ff63f 274static const char *comparison_string (enum rtx_code, rtx);
219d92a4
AS
275static rtx frv_function_value (const_tree, const_tree,
276 bool);
ef4bddc2 277static rtx frv_libcall_value (machine_mode,
219d92a4 278 const_rtx);
f2206911
KC
279static FRV_INLINE int frv_regno_ok_for_base_p (int, int);
280static rtx single_set_pattern (rtx);
281static int frv_function_contains_far_jump (void);
282static rtx frv_alloc_temp_reg (frv_tmp_reg_t *,
283 enum reg_class,
ef4bddc2 284 machine_mode,
f2206911
KC
285 int, int);
286static rtx frv_frame_offset_rtx (int);
ef4bddc2 287static rtx frv_frame_mem (machine_mode, rtx, int);
f2206911
KC
288static rtx frv_dwarf_store (rtx, int);
289static void frv_frame_insn (rtx, rtx);
290static void frv_frame_access (frv_frame_accessor_t*,
291 rtx, int);
292static void frv_frame_access_multi (frv_frame_accessor_t*,
293 frv_stack_t *, int);
294static void frv_frame_access_standard_regs (enum frv_stack_op,
295 frv_stack_t *);
296static struct machine_function *frv_init_machine_status (void);
f2206911 297static rtx frv_int_to_acc (enum insn_code, int, rtx);
ef4bddc2 298static machine_mode frv_matching_accg_mode (machine_mode);
2396bce1 299static rtx frv_read_argument (tree, unsigned int);
ef4bddc2 300static rtx frv_read_iacc_argument (machine_mode, tree, unsigned int);
f2206911
KC
301static int frv_check_constant_argument (enum insn_code, int, rtx);
302static rtx frv_legitimize_target (enum insn_code, rtx);
303static rtx frv_legitimize_argument (enum insn_code, int, rtx);
bef8809e 304static rtx frv_legitimize_tls_address (rtx, enum tls_model);
ef4bddc2 305static rtx frv_legitimize_address (rtx, rtx, machine_mode);
f2206911
KC
306static rtx frv_expand_set_builtin (enum insn_code, tree, rtx);
307static rtx frv_expand_unop_builtin (enum insn_code, tree, rtx);
308static rtx frv_expand_binop_builtin (enum insn_code, tree, rtx);
309static rtx frv_expand_cut_builtin (enum insn_code, tree, rtx);
310static rtx frv_expand_binopimm_builtin (enum insn_code, tree, rtx);
311static rtx frv_expand_voidbinop_builtin (enum insn_code, tree);
c557edf4
RS
312static rtx frv_expand_int_void2arg (enum insn_code, tree);
313static rtx frv_expand_prefetches (enum insn_code, tree);
f2206911
KC
314static rtx frv_expand_voidtriop_builtin (enum insn_code, tree);
315static rtx frv_expand_voidaccop_builtin (enum insn_code, tree);
316static rtx frv_expand_mclracc_builtin (tree);
317static rtx frv_expand_mrdacc_builtin (enum insn_code, tree);
318static rtx frv_expand_mwtacc_builtin (enum insn_code, tree);
319static rtx frv_expand_noargs_builtin (enum insn_code);
c557edf4 320static void frv_split_iacc_move (rtx, rtx);
f2206911 321static rtx frv_emit_comparison (enum rtx_code, rtx, rtx);
df0b55f0 322static void frv_ifcvt_add_insn (rtx, rtx_insn *, int);
ef4bddc2 323static rtx frv_ifcvt_rewrite_mem (rtx, machine_mode, rtx);
f2206911 324static rtx frv_ifcvt_load_value (rtx, rtx);
84034c69
DM
325static unsigned int frv_insn_unit (rtx_insn *);
326static bool frv_issues_to_branch_unit_p (rtx_insn *);
c557edf4
RS
327static int frv_cond_flags (rtx);
328static bool frv_regstate_conflict_p (regstate_t, regstate_t);
c557edf4 329static bool frv_registers_conflict_p (rtx);
7bc980e1 330static void frv_registers_update_1 (rtx, const_rtx, void *);
c557edf4
RS
331static void frv_registers_update (rtx);
332static void frv_start_packet (void);
333static void frv_start_packet_block (void);
334static void frv_finish_packet (void (*) (void));
84034c69 335static bool frv_pack_insn_p (rtx_insn *);
b32d5189
DM
336static void frv_add_insn_to_packet (rtx_insn *);
337static void frv_insert_nop_in_packet (rtx_insn *);
c557edf4
RS
338static bool frv_for_each_packet (void (*) (void));
339static bool frv_sort_insn_group_1 (enum frv_insn_group,
340 unsigned int, unsigned int,
341 unsigned int, unsigned int,
342 state_t);
343static int frv_compare_insns (const void *, const void *);
344static void frv_sort_insn_group (enum frv_insn_group);
345static void frv_reorder_packet (void);
346static void frv_fill_unused_units (enum frv_insn_group);
347static void frv_align_label (void);
348static void frv_reorg_packet (void);
349static void frv_register_nop (rtx);
350static void frv_reorg (void);
f2206911 351static void frv_pack_insns (void);
42776416
RS
352static void frv_function_prologue (FILE *);
353static void frv_function_epilogue (FILE *);
f2206911
KC
354static bool frv_assemble_integer (rtx, unsigned, int);
355static void frv_init_builtins (void);
ef4bddc2 356static rtx frv_expand_builtin (tree, rtx, rtx, machine_mode, int);
f2206911 357static void frv_init_libfuncs (void);
3101faab 358static bool frv_in_small_data_p (const_tree);
3961e8fe 359static void frv_asm_output_mi_thunk
f2206911 360 (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree);
d5cc9181 361static void frv_setup_incoming_varargs (cumulative_args_t,
e7056ca4
RS
362 const function_arg_info &,
363 int *, int);
8ac411c7 364static rtx frv_expand_builtin_saveregs (void);
d7bd8aeb 365static void frv_expand_builtin_va_start (tree, rtx);
e548c9df
AM
366static bool frv_rtx_costs (rtx, machine_mode, int, int,
367 int*, bool);
ef4bddc2 368static int frv_register_move_cost (machine_mode,
33124e84 369 reg_class_t, reg_class_t);
ef4bddc2 370static int frv_memory_move_cost (machine_mode,
33124e84 371 reg_class_t, bool);
f2206911
KC
372static void frv_asm_out_constructor (rtx, int);
373static void frv_asm_out_destructor (rtx, int);
34208acf 374static bool frv_function_symbol_referenced_p (rtx);
ef4bddc2
RS
375static bool frv_legitimate_constant_p (machine_mode, rtx);
376static bool frv_cannot_force_const_mem (machine_mode, rtx);
34208acf
AO
377static const char *unspec_got_name (int);
378static void frv_output_const_unspec (FILE *,
379 const struct frv_unspec *);
764678d1 380static bool frv_function_ok_for_sibcall (tree, tree);
8ac411c7 381static rtx frv_struct_value_rtx (tree, int);
0ffef200 382static bool frv_must_pass_in_stack (const function_arg_info &);
a7c81bc1
RS
383static int frv_arg_partial_bytes (cumulative_args_t,
384 const function_arg_info &);
6783fdb7
RS
385static rtx frv_function_arg (cumulative_args_t, const function_arg_info &);
386static rtx frv_function_incoming_arg (cumulative_args_t,
387 const function_arg_info &);
6930c98c
RS
388static void frv_function_arg_advance (cumulative_args_t,
389 const function_arg_info &);
ef4bddc2 390static unsigned int frv_function_arg_boundary (machine_mode,
c2ed6cf8 391 const_tree);
fdbe66f2
EB
392static void frv_output_dwarf_dtprel (FILE *, int, rtx)
393 ATTRIBUTE_UNUSED;
a87cf97e 394static reg_class_t frv_secondary_reload (bool, rtx, reg_class_t,
ef4bddc2 395 machine_mode,
35f2d8ef 396 secondary_reload_info *);
b52b1749 397static bool frv_frame_pointer_required (void);
7b5cbb57 398static bool frv_can_eliminate (const int, const int);
5efd84c5 399static void frv_conditional_register_usage (void);
e9d5fdb2 400static void frv_trampoline_init (rtx, tree, rtx);
c28350ab 401static bool frv_class_likely_spilled_p (reg_class_t);
c43f4279 402static unsigned int frv_hard_regno_nregs (unsigned int, machine_mode);
f939c3e6 403static bool frv_hard_regno_mode_ok (unsigned int, machine_mode);
99e1629f 404static bool frv_modes_tieable_p (machine_mode, machine_mode);
0b2c18fe 405\f
36a05131 406/* Initialize the GCC target structure. */
0fb30cb7
NF
407#undef TARGET_PRINT_OPERAND
408#define TARGET_PRINT_OPERAND frv_print_operand
409#undef TARGET_PRINT_OPERAND_ADDRESS
410#define TARGET_PRINT_OPERAND_ADDRESS frv_print_operand_address
411#undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
412#define TARGET_PRINT_OPERAND_PUNCT_VALID_P frv_print_operand_punct_valid_p
36a05131
BS
413#undef TARGET_ASM_FUNCTION_PROLOGUE
414#define TARGET_ASM_FUNCTION_PROLOGUE frv_function_prologue
415#undef TARGET_ASM_FUNCTION_EPILOGUE
416#define TARGET_ASM_FUNCTION_EPILOGUE frv_function_epilogue
417#undef TARGET_ASM_INTEGER
418#define TARGET_ASM_INTEGER frv_assemble_integer
c5387660
JM
419#undef TARGET_OPTION_OVERRIDE
420#define TARGET_OPTION_OVERRIDE frv_option_override
14966b94
KG
421#undef TARGET_INIT_BUILTINS
422#define TARGET_INIT_BUILTINS frv_init_builtins
423#undef TARGET_EXPAND_BUILTIN
424#define TARGET_EXPAND_BUILTIN frv_expand_builtin
c15c90bb
ZW
425#undef TARGET_INIT_LIBFUNCS
426#define TARGET_INIT_LIBFUNCS frv_init_libfuncs
b3fbfc07
KG
427#undef TARGET_IN_SMALL_DATA_P
428#define TARGET_IN_SMALL_DATA_P frv_in_small_data_p
33124e84
AS
429#undef TARGET_REGISTER_MOVE_COST
430#define TARGET_REGISTER_MOVE_COST frv_register_move_cost
431#undef TARGET_MEMORY_MOVE_COST
432#define TARGET_MEMORY_MOVE_COST frv_memory_move_cost
3c50106f
RH
433#undef TARGET_RTX_COSTS
434#define TARGET_RTX_COSTS frv_rtx_costs
90a63880
RH
435#undef TARGET_ASM_CONSTRUCTOR
436#define TARGET_ASM_CONSTRUCTOR frv_asm_out_constructor
437#undef TARGET_ASM_DESTRUCTOR
438#define TARGET_ASM_DESTRUCTOR frv_asm_out_destructor
36a05131 439
c590b625
RH
440#undef TARGET_ASM_OUTPUT_MI_THUNK
441#define TARGET_ASM_OUTPUT_MI_THUNK frv_asm_output_mi_thunk
3961e8fe
RH
442#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
443#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
c590b625 444
28a60850
RS
445#undef TARGET_SCHED_ISSUE_RATE
446#define TARGET_SCHED_ISSUE_RATE frv_issue_rate
ffb344c1 447
506d7b68
PB
448#undef TARGET_LEGITIMIZE_ADDRESS
449#define TARGET_LEGITIMIZE_ADDRESS frv_legitimize_address
450
764678d1
AO
451#undef TARGET_FUNCTION_OK_FOR_SIBCALL
452#define TARGET_FUNCTION_OK_FOR_SIBCALL frv_function_ok_for_sibcall
1a627b35
RS
453#undef TARGET_LEGITIMATE_CONSTANT_P
454#define TARGET_LEGITIMATE_CONSTANT_P frv_legitimate_constant_p
34208acf
AO
455#undef TARGET_CANNOT_FORCE_CONST_MEM
456#define TARGET_CANNOT_FORCE_CONST_MEM frv_cannot_force_const_mem
457
bef8809e
AH
458#undef TARGET_HAVE_TLS
459#define TARGET_HAVE_TLS HAVE_AS_TLS
460
8ac411c7
KH
461#undef TARGET_STRUCT_VALUE_RTX
462#define TARGET_STRUCT_VALUE_RTX frv_struct_value_rtx
fe984136
RH
463#undef TARGET_MUST_PASS_IN_STACK
464#define TARGET_MUST_PASS_IN_STACK frv_must_pass_in_stack
8cd5a4e0
RH
465#undef TARGET_PASS_BY_REFERENCE
466#define TARGET_PASS_BY_REFERENCE hook_pass_by_reference_must_pass_in_stack
78a52f11
RH
467#undef TARGET_ARG_PARTIAL_BYTES
468#define TARGET_ARG_PARTIAL_BYTES frv_arg_partial_bytes
88a1f47f
NF
469#undef TARGET_FUNCTION_ARG
470#define TARGET_FUNCTION_ARG frv_function_arg
471#undef TARGET_FUNCTION_INCOMING_ARG
472#define TARGET_FUNCTION_INCOMING_ARG frv_function_incoming_arg
473#undef TARGET_FUNCTION_ARG_ADVANCE
474#define TARGET_FUNCTION_ARG_ADVANCE frv_function_arg_advance
c2ed6cf8
NF
475#undef TARGET_FUNCTION_ARG_BOUNDARY
476#define TARGET_FUNCTION_ARG_BOUNDARY frv_function_arg_boundary
8ac411c7
KH
477
478#undef TARGET_EXPAND_BUILTIN_SAVEREGS
479#define TARGET_EXPAND_BUILTIN_SAVEREGS frv_expand_builtin_saveregs
d8c2bed3
KH
480#undef TARGET_SETUP_INCOMING_VARARGS
481#define TARGET_SETUP_INCOMING_VARARGS frv_setup_incoming_varargs
c557edf4
RS
482#undef TARGET_MACHINE_DEPENDENT_REORG
483#define TARGET_MACHINE_DEPENDENT_REORG frv_reorg
8ac411c7 484
d7bd8aeb
JJ
485#undef TARGET_EXPAND_BUILTIN_VA_START
486#define TARGET_EXPAND_BUILTIN_VA_START frv_expand_builtin_va_start
487
fdbe66f2
EB
488#if HAVE_AS_TLS
489#undef TARGET_ASM_OUTPUT_DWARF_DTPREL
490#define TARGET_ASM_OUTPUT_DWARF_DTPREL frv_output_dwarf_dtprel
491#endif
492
c28350ab
AS
493#undef TARGET_CLASS_LIKELY_SPILLED_P
494#define TARGET_CLASS_LIKELY_SPILLED_P frv_class_likely_spilled_p
495
35f2d8ef
NC
496#undef TARGET_SECONDARY_RELOAD
497#define TARGET_SECONDARY_RELOAD frv_secondary_reload
498
d81db636
SB
499#undef TARGET_LRA_P
500#define TARGET_LRA_P hook_bool_void_false
501
c6c3dba9
PB
502#undef TARGET_LEGITIMATE_ADDRESS_P
503#define TARGET_LEGITIMATE_ADDRESS_P frv_legitimate_address_p
504
b52b1749
AS
505#undef TARGET_FRAME_POINTER_REQUIRED
506#define TARGET_FRAME_POINTER_REQUIRED frv_frame_pointer_required
507
7b5cbb57
AS
508#undef TARGET_CAN_ELIMINATE
509#define TARGET_CAN_ELIMINATE frv_can_eliminate
510
5efd84c5
NF
511#undef TARGET_CONDITIONAL_REGISTER_USAGE
512#define TARGET_CONDITIONAL_REGISTER_USAGE frv_conditional_register_usage
513
e9d5fdb2
RH
514#undef TARGET_TRAMPOLINE_INIT
515#define TARGET_TRAMPOLINE_INIT frv_trampoline_init
516
219d92a4
AS
517#undef TARGET_FUNCTION_VALUE
518#define TARGET_FUNCTION_VALUE frv_function_value
519#undef TARGET_LIBCALL_VALUE
520#define TARGET_LIBCALL_VALUE frv_libcall_value
521
c43f4279
RS
522#undef TARGET_HARD_REGNO_NREGS
523#define TARGET_HARD_REGNO_NREGS frv_hard_regno_nregs
f939c3e6
RS
524#undef TARGET_HARD_REGNO_MODE_OK
525#define TARGET_HARD_REGNO_MODE_OK frv_hard_regno_mode_ok
99e1629f
RS
526#undef TARGET_MODES_TIEABLE_P
527#define TARGET_MODES_TIEABLE_P frv_modes_tieable_p
58e17cf8
RS
528#undef TARGET_CONSTANT_ALIGNMENT
529#define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
f939c3e6 530
fd157d13
NC
531#undef TARGET_HAVE_SPECULATION_SAFE_VALUE
532#define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
533
36a05131 534struct gcc_target targetm = TARGET_INITIALIZER;
bef8809e
AH
535
536#define FRV_SYMBOL_REF_TLS_P(RTX) \
537 (GET_CODE (RTX) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (RTX) != 0)
538
36a05131 539\f
764678d1
AO
540/* Any function call that satisfies the machine-independent
541 requirements is eligible on FR-V. */
542
543static bool
544frv_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
545 tree exp ATTRIBUTE_UNUSED)
546{
547 return true;
548}
549
34208acf
AO
550/* Return true if SYMBOL is a small data symbol and relocation RELOC
551 can be used to access it directly in a load or store. */
36a05131 552
34208acf
AO
553static FRV_INLINE bool
554frv_small_data_reloc_p (rtx symbol, int reloc)
36a05131 555{
34208acf
AO
556 return (GET_CODE (symbol) == SYMBOL_REF
557 && SYMBOL_REF_SMALL_P (symbol)
558 && (!TARGET_FDPIC || flag_pic == 1)
559 && (reloc == R_FRV_GOTOFF12 || reloc == R_FRV_GPREL12));
560}
36a05131 561
34208acf
AO
562/* Return true if X is a valid relocation unspec. If it is, fill in UNSPEC
563 appropriately. */
36a05131 564
6d26dc3b 565bool
34208acf
AO
566frv_const_unspec_p (rtx x, struct frv_unspec *unspec)
567{
568 if (GET_CODE (x) == CONST)
569 {
570 unspec->offset = 0;
571 x = XEXP (x, 0);
572 if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
573 {
574 unspec->offset += INTVAL (XEXP (x, 1));
575 x = XEXP (x, 0);
576 }
577 if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_GOT)
578 {
579 unspec->symbol = XVECEXP (x, 0, 0);
580 unspec->reloc = INTVAL (XVECEXP (x, 0, 1));
36a05131 581
34208acf
AO
582 if (unspec->offset == 0)
583 return true;
36a05131 584
34208acf
AO
585 if (frv_small_data_reloc_p (unspec->symbol, unspec->reloc)
586 && unspec->offset > 0
fa37ed29 587 && unspec->offset < g_switch_value)
34208acf
AO
588 return true;
589 }
590 }
591 return false;
36a05131
BS
592}
593
34208acf
AO
594/* Decide whether we can force certain constants to memory. If we
595 decide we can't, the caller should be able to cope with it in
596 another way.
36a05131 597
34208acf
AO
598 We never allow constants to be forced into memory for TARGET_FDPIC.
599 This is necessary for several reasons:
36a05131 600
1a627b35 601 1. Since frv_legitimate_constant_p rejects constant pool addresses, the
34208acf
AO
602 target-independent code will try to force them into the constant
603 pool, thus leading to infinite recursion.
36a05131 604
34208acf
AO
605 2. We can never introduce new constant pool references during reload.
606 Any such reference would require use of the pseudo FDPIC register.
36a05131 607
34208acf
AO
608 3. We can't represent a constant added to a function pointer (which is
609 not the same as a pointer to a function+constant).
610
611 4. In many cases, it's more efficient to calculate the constant in-line. */
612
613static bool
ef4bddc2 614frv_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED,
fbbf66e7 615 rtx x ATTRIBUTE_UNUSED)
34208acf
AO
616{
617 return TARGET_FDPIC;
618}
36a05131
BS
619\f
620static int
f2206911 621frv_default_flags_for_cpu (void)
36a05131
BS
622{
623 switch (frv_cpu_type)
624 {
625 case FRV_CPU_GENERIC:
626 return MASK_DEFAULT_FRV;
627
c557edf4
RS
628 case FRV_CPU_FR550:
629 return MASK_DEFAULT_FR550;
630
36a05131
BS
631 case FRV_CPU_FR500:
632 case FRV_CPU_TOMCAT:
633 return MASK_DEFAULT_FR500;
634
c557edf4
RS
635 case FRV_CPU_FR450:
636 return MASK_DEFAULT_FR450;
637
638 case FRV_CPU_FR405:
36a05131
BS
639 case FRV_CPU_FR400:
640 return MASK_DEFAULT_FR400;
641
642 case FRV_CPU_FR300:
643 case FRV_CPU_SIMPLE:
644 return MASK_DEFAULT_SIMPLE;
44e91694
NS
645
646 default:
647 gcc_unreachable ();
36a05131 648 }
36a05131
BS
649}
650
c5387660 651/* Implement TARGET_OPTION_OVERRIDE. */
36a05131 652
c5387660
JM
653static void
654frv_option_override (void)
36a05131 655{
c557edf4
RS
656 int regno;
657 unsigned int i;
36a05131 658
36a05131
BS
659 target_flags |= (frv_default_flags_for_cpu () & ~target_flags_explicit);
660
661 /* -mlibrary-pic sets -fPIC and -G0 and also suppresses warnings from the
662 linker about linking pic and non-pic code. */
663 if (TARGET_LIBPIC)
664 {
665 if (!flag_pic) /* -fPIC */
666 flag_pic = 2;
667
fa37ed29 668 if (!global_options_set.x_g_switch_value) /* -G0 */
36a05131 669 {
36a05131
BS
670 g_switch_value = 0;
671 }
672 }
673
36a05131
BS
674 /* A C expression whose value is a register class containing hard
675 register REGNO. In general there is more than one such class;
676 choose a class which is "minimal", meaning that no smaller class
87b483a1 677 also contains the register. */
36a05131
BS
678
679 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
680 {
0a2aaacc 681 enum reg_class rclass;
36a05131
BS
682
683 if (GPR_P (regno))
684 {
685 int gpr_reg = regno - GPR_FIRST;
bef8809e
AH
686
687 if (gpr_reg == GR8_REG)
0a2aaacc 688 rclass = GR8_REGS;
bef8809e
AH
689
690 else if (gpr_reg == GR9_REG)
0a2aaacc 691 rclass = GR9_REGS;
bef8809e
AH
692
693 else if (gpr_reg == GR14_REG)
0a2aaacc 694 rclass = FDPIC_FPTR_REGS;
bef8809e
AH
695
696 else if (gpr_reg == FDPIC_REGNO)
0a2aaacc 697 rclass = FDPIC_REGS;
bef8809e
AH
698
699 else if ((gpr_reg & 3) == 0)
0a2aaacc 700 rclass = QUAD_REGS;
36a05131
BS
701
702 else if ((gpr_reg & 1) == 0)
0a2aaacc 703 rclass = EVEN_REGS;
36a05131
BS
704
705 else
0a2aaacc 706 rclass = GPR_REGS;
36a05131
BS
707 }
708
709 else if (FPR_P (regno))
710 {
711 int fpr_reg = regno - GPR_FIRST;
712 if ((fpr_reg & 3) == 0)
0a2aaacc 713 rclass = QUAD_FPR_REGS;
36a05131
BS
714
715 else if ((fpr_reg & 1) == 0)
0a2aaacc 716 rclass = FEVEN_REGS;
36a05131
BS
717
718 else
0a2aaacc 719 rclass = FPR_REGS;
36a05131
BS
720 }
721
722 else if (regno == LR_REGNO)
0a2aaacc 723 rclass = LR_REG;
36a05131
BS
724
725 else if (regno == LCR_REGNO)
0a2aaacc 726 rclass = LCR_REG;
36a05131
BS
727
728 else if (ICC_P (regno))
0a2aaacc 729 rclass = ICC_REGS;
36a05131
BS
730
731 else if (FCC_P (regno))
0a2aaacc 732 rclass = FCC_REGS;
36a05131
BS
733
734 else if (ICR_P (regno))
0a2aaacc 735 rclass = ICR_REGS;
36a05131
BS
736
737 else if (FCR_P (regno))
0a2aaacc 738 rclass = FCR_REGS;
36a05131
BS
739
740 else if (ACC_P (regno))
741 {
742 int r = regno - ACC_FIRST;
743 if ((r & 3) == 0)
0a2aaacc 744 rclass = QUAD_ACC_REGS;
36a05131 745 else if ((r & 1) == 0)
0a2aaacc 746 rclass = EVEN_ACC_REGS;
36a05131 747 else
0a2aaacc 748 rclass = ACC_REGS;
36a05131
BS
749 }
750
751 else if (ACCG_P (regno))
0a2aaacc 752 rclass = ACCG_REGS;
36a05131
BS
753
754 else
0a2aaacc 755 rclass = NO_REGS;
36a05131 756
0a2aaacc 757 regno_reg_class[regno] = rclass;
36a05131
BS
758 }
759
760 /* Check for small data option */
fa37ed29 761 if (!global_options_set.x_g_switch_value && !TARGET_LIBPIC)
36a05131
BS
762 g_switch_value = SDATA_DEFAULT_SIZE;
763
36a05131
BS
764 /* There is no single unaligned SI op for PIC code. Sometimes we
765 need to use ".4byte" and sometimes we need to use ".picptr".
766 See frv_assemble_integer for details. */
34208acf 767 if (flag_pic || TARGET_FDPIC)
36a05131
BS
768 targetm.asm_out.unaligned_op.si = 0;
769
34208acf
AO
770 if ((target_flags_explicit & MASK_LINKED_FP) == 0)
771 target_flags |= MASK_LINKED_FP;
772
38c28a25
AH
773 if ((target_flags_explicit & MASK_OPTIMIZE_MEMBAR) == 0)
774 target_flags |= MASK_OPTIMIZE_MEMBAR;
775
c557edf4
RS
776 for (i = 0; i < ARRAY_SIZE (frv_unit_names); i++)
777 frv_unit_codes[i] = get_cpu_unit_code (frv_unit_names[i]);
778
779 for (i = 0; i < ARRAY_SIZE (frv_type_to_unit); i++)
780 frv_type_to_unit[i] = ARRAY_SIZE (frv_unit_codes);
781
36a05131
BS
782 init_machine_status = frv_init_machine_status;
783}
784
36a05131
BS
785\f
786/* Return true if NAME (a STRING_CST node) begins with PREFIX. */
787
788static int
f961457f 789frv_string_begins_with (const char *name, const char *prefix)
36a05131 790{
3101faab 791 const int prefix_len = strlen (prefix);
36a05131
BS
792
793 /* Remember: NAME's length includes the null terminator. */
f961457f 794 return (strncmp (name, prefix, prefix_len) == 0);
36a05131 795}
36a05131 796\f
b48e9677 797/* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */
36a05131 798
5efd84c5 799static void
f2206911 800frv_conditional_register_usage (void)
36a05131
BS
801{
802 int i;
803
804 for (i = GPR_FIRST + NUM_GPRS; i <= GPR_LAST; i++)
805 fixed_regs[i] = call_used_regs[i] = 1;
806
807 for (i = FPR_FIRST + NUM_FPRS; i <= FPR_LAST; i++)
808 fixed_regs[i] = call_used_regs[i] = 1;
809
36a05131
BS
810 /* Reserve the registers used for conditional execution. At present, we need
811 1 ICC and 1 ICR register. */
812 fixed_regs[ICC_TEMP] = call_used_regs[ICC_TEMP] = 1;
813 fixed_regs[ICR_TEMP] = call_used_regs[ICR_TEMP] = 1;
814
815 if (TARGET_FIXED_CC)
816 {
817 fixed_regs[ICC_FIRST] = call_used_regs[ICC_FIRST] = 1;
818 fixed_regs[FCC_FIRST] = call_used_regs[FCC_FIRST] = 1;
819 fixed_regs[ICR_FIRST] = call_used_regs[ICR_FIRST] = 1;
820 fixed_regs[FCR_FIRST] = call_used_regs[FCR_FIRST] = 1;
821 }
822
34208acf
AO
823 if (TARGET_FDPIC)
824 fixed_regs[GPR_FIRST + 16] = fixed_regs[GPR_FIRST + 17] =
825 call_used_regs[GPR_FIRST + 16] = call_used_regs[GPR_FIRST + 17] = 0;
826
36a05131
BS
827#if 0
828 /* If -fpic, SDA_BASE_REG is the PIC register. */
829 if (g_switch_value == 0 && !flag_pic)
830 fixed_regs[SDA_BASE_REG] = call_used_regs[SDA_BASE_REG] = 0;
831
832 if (!flag_pic)
833 fixed_regs[PIC_REGNO] = call_used_regs[PIC_REGNO] = 0;
834#endif
835}
836
837\f
838/*
839 * Compute the stack frame layout
840 *
841 * Register setup:
842 * +---------------+-----------------------+-----------------------+
843 * |Register |type |caller-save/callee-save|
844 * +---------------+-----------------------+-----------------------+
845 * |GR0 |Zero register | - |
846 * |GR1 |Stack pointer(SP) | - |
847 * |GR2 |Frame pointer(FP) | - |
848 * |GR3 |Hidden parameter | caller save |
849 * |GR4-GR7 | - | caller save |
850 * |GR8-GR13 |Argument register | caller save |
851 * |GR14-GR15 | - | caller save |
852 * |GR16-GR31 | - | callee save |
853 * |GR32-GR47 | - | caller save |
854 * |GR48-GR63 | - | callee save |
855 * |FR0-FR15 | - | caller save |
856 * |FR16-FR31 | - | callee save |
857 * |FR32-FR47 | - | caller save |
858 * |FR48-FR63 | - | callee save |
859 * +---------------+-----------------------+-----------------------+
860 *
861 * Stack frame setup:
862 * Low
863 * SP-> |-----------------------------------|
864 * | Argument area |
865 * |-----------------------------------|
866 * | Register save area |
867 * |-----------------------------------|
868 * | Local variable save area |
869 * FP-> |-----------------------------------|
870 * | Old FP |
871 * |-----------------------------------|
872 * | Hidden parameter save area |
873 * |-----------------------------------|
874 * | Return address(LR) storage area |
875 * |-----------------------------------|
876 * | Padding for alignment |
877 * |-----------------------------------|
878 * | Register argument area |
879 * OLD SP-> |-----------------------------------|
880 * | Parameter area |
881 * |-----------------------------------|
882 * High
883 *
884 * Argument area/Parameter area:
885 *
886 * When a function is called, this area is used for argument transfer. When
887 * the argument is set up by the caller function, this area is referred to as
888 * the argument area. When the argument is referenced by the callee function,
889 * this area is referred to as the parameter area. The area is allocated when
890 * all arguments cannot be placed on the argument register at the time of
891 * argument transfer.
892 *
893 * Register save area:
894 *
895 * This is a register save area that must be guaranteed for the caller
896 * function. This area is not secured when the register save operation is not
897 * needed.
898 *
899 * Local variable save area:
900 *
901 * This is the area for local variables and temporary variables.
902 *
903 * Old FP:
904 *
905 * This area stores the FP value of the caller function.
906 *
907 * Hidden parameter save area:
908 *
909 * This area stores the start address of the return value storage
910 * area for a struct/union return function.
911 * When a struct/union is used as the return value, the caller
912 * function stores the return value storage area start address in
913 * register GR3 and passes it to the caller function.
914 * The callee function interprets the address stored in the GR3
915 * as the return value storage area start address.
916 * When register GR3 needs to be saved into memory, the callee
917 * function saves it in the hidden parameter save area. This
918 * area is not secured when the save operation is not needed.
919 *
920 * Return address(LR) storage area:
921 *
922 * This area saves the LR. The LR stores the address of a return to the caller
923 * function for the purpose of function calling.
924 *
925 * Argument register area:
926 *
927 * This area saves the argument register. This area is not secured when the
928 * save operation is not needed.
929 *
930 * Argument:
931 *
932 * Arguments, the count of which equals the count of argument registers (6
933 * words), are positioned in registers GR8 to GR13 and delivered to the callee
934 * function. When a struct/union return function is called, the return value
935 * area address is stored in register GR3. Arguments not placed in the
936 * argument registers will be stored in the stack argument area for transfer
937 * purposes. When an 8-byte type argument is to be delivered using registers,
938 * it is divided into two and placed in two registers for transfer. When
939 * argument registers must be saved to memory, the callee function secures an
940 * argument register save area in the stack. In this case, a continuous
941 * argument register save area must be established in the parameter area. The
942 * argument register save area must be allocated as needed to cover the size of
943 * the argument register to be saved. If the function has a variable count of
944 * arguments, it saves all argument registers in the argument register save
945 * area.
946 *
947 * Argument Extension Format:
948 *
949 * When an argument is to be stored in the stack, its type is converted to an
950 * extended type in accordance with the individual argument type. The argument
951 * is freed by the caller function after the return from the callee function is
952 * made.
953 *
954 * +-----------------------+---------------+------------------------+
955 * | Argument Type |Extended Type |Stack Storage Size(byte)|
956 * +-----------------------+---------------+------------------------+
957 * |char |int | 4 |
958 * |signed char |int | 4 |
959 * |unsigned char |int | 4 |
960 * |[signed] short int |int | 4 |
961 * |unsigned short int |int | 4 |
962 * |[signed] int |No extension | 4 |
963 * |unsigned int |No extension | 4 |
964 * |[signed] long int |No extension | 4 |
965 * |unsigned long int |No extension | 4 |
966 * |[signed] long long int |No extension | 8 |
967 * |unsigned long long int |No extension | 8 |
968 * |float |double | 8 |
969 * |double |No extension | 8 |
970 * |long double |No extension | 8 |
971 * |pointer |No extension | 4 |
972 * |struct/union |- | 4 (*1) |
973 * +-----------------------+---------------+------------------------+
974 *
975 * When a struct/union is to be delivered as an argument, the caller copies it
976 * to the local variable area and delivers the address of that area.
977 *
978 * Return Value:
979 *
980 * +-------------------------------+----------------------+
981 * |Return Value Type |Return Value Interface|
982 * +-------------------------------+----------------------+
983 * |void |None |
984 * |[signed|unsigned] char |GR8 |
985 * |[signed|unsigned] short int |GR8 |
986 * |[signed|unsigned] int |GR8 |
987 * |[signed|unsigned] long int |GR8 |
988 * |pointer |GR8 |
989 * |[signed|unsigned] long long int|GR8 & GR9 |
990 * |float |GR8 |
991 * |double |GR8 & GR9 |
992 * |long double |GR8 & GR9 |
993 * |struct/union |(*1) |
994 * +-------------------------------+----------------------+
995 *
996 * When a struct/union is used as the return value, the caller function stores
997 * the start address of the return value storage area into GR3 and then passes
998 * it to the callee function. The callee function interprets GR3 as the start
999 * address of the return value storage area. When this address needs to be
1000 * saved in memory, the callee function secures the hidden parameter save area
1001 * and saves the address in that area.
1002 */
1003
1004frv_stack_t *
f2206911 1005frv_stack_info (void)
36a05131
BS
1006{
1007 static frv_stack_t info, zero_info;
1008 frv_stack_t *info_ptr = &info;
1009 tree fndecl = current_function_decl;
1010 int varargs_p = 0;
1011 tree cur_arg;
1012 tree next_arg;
1013 int range;
1014 int alignment;
1015 int offset;
1016
87b483a1
KH
1017 /* If we've already calculated the values and reload is complete,
1018 just return now. */
36a05131
BS
1019 if (frv_stack_cache)
1020 return frv_stack_cache;
1021
87b483a1 1022 /* Zero all fields. */
36a05131
BS
1023 info = zero_info;
1024
87b483a1 1025 /* Set up the register range information. */
36a05131
BS
1026 info_ptr->regs[STACK_REGS_GPR].name = "gpr";
1027 info_ptr->regs[STACK_REGS_GPR].first = LAST_ARG_REGNUM + 1;
1028 info_ptr->regs[STACK_REGS_GPR].last = GPR_LAST;
1029 info_ptr->regs[STACK_REGS_GPR].dword_p = TRUE;
1030
1031 info_ptr->regs[STACK_REGS_FPR].name = "fpr";
1032 info_ptr->regs[STACK_REGS_FPR].first = FPR_FIRST;
1033 info_ptr->regs[STACK_REGS_FPR].last = FPR_LAST;
1034 info_ptr->regs[STACK_REGS_FPR].dword_p = TRUE;
1035
1036 info_ptr->regs[STACK_REGS_LR].name = "lr";
1037 info_ptr->regs[STACK_REGS_LR].first = LR_REGNO;
1038 info_ptr->regs[STACK_REGS_LR].last = LR_REGNO;
1039 info_ptr->regs[STACK_REGS_LR].special_p = 1;
1040
1041 info_ptr->regs[STACK_REGS_CC].name = "cc";
1042 info_ptr->regs[STACK_REGS_CC].first = CC_FIRST;
1043 info_ptr->regs[STACK_REGS_CC].last = CC_LAST;
1044 info_ptr->regs[STACK_REGS_CC].field_p = TRUE;
1045
1046 info_ptr->regs[STACK_REGS_LCR].name = "lcr";
1047 info_ptr->regs[STACK_REGS_LCR].first = LCR_REGNO;
1048 info_ptr->regs[STACK_REGS_LCR].last = LCR_REGNO;
1049
1050 info_ptr->regs[STACK_REGS_STDARG].name = "stdarg";
1051 info_ptr->regs[STACK_REGS_STDARG].first = FIRST_ARG_REGNUM;
1052 info_ptr->regs[STACK_REGS_STDARG].last = LAST_ARG_REGNUM;
1053 info_ptr->regs[STACK_REGS_STDARG].dword_p = 1;
1054 info_ptr->regs[STACK_REGS_STDARG].special_p = 1;
1055
1056 info_ptr->regs[STACK_REGS_STRUCT].name = "struct";
8ac411c7
KH
1057 info_ptr->regs[STACK_REGS_STRUCT].first = FRV_STRUCT_VALUE_REGNUM;
1058 info_ptr->regs[STACK_REGS_STRUCT].last = FRV_STRUCT_VALUE_REGNUM;
36a05131
BS
1059 info_ptr->regs[STACK_REGS_STRUCT].special_p = 1;
1060
1061 info_ptr->regs[STACK_REGS_FP].name = "fp";
1062 info_ptr->regs[STACK_REGS_FP].first = FRAME_POINTER_REGNUM;
1063 info_ptr->regs[STACK_REGS_FP].last = FRAME_POINTER_REGNUM;
1064 info_ptr->regs[STACK_REGS_FP].special_p = 1;
1065
1066 /* Determine if this is a stdarg function. If so, allocate space to store
1067 the 6 arguments. */
1068 if (cfun->stdarg)
1069 varargs_p = 1;
1070
1071 else
1072 {
1073 /* Find the last argument, and see if it is __builtin_va_alist. */
1074 for (cur_arg = DECL_ARGUMENTS (fndecl); cur_arg != (tree)0; cur_arg = next_arg)
1075 {
910ad8de 1076 next_arg = DECL_CHAIN (cur_arg);
36a05131
BS
1077 if (next_arg == (tree)0)
1078 {
1079 if (DECL_NAME (cur_arg)
1080 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)), "__builtin_va_alist"))
1081 varargs_p = 1;
1082
1083 break;
1084 }
1085 }
1086 }
1087
87b483a1 1088 /* Iterate over all of the register ranges. */
36a05131
BS
1089 for (range = 0; range < STACK_REGS_MAX; range++)
1090 {
1091 frv_stack_regs_t *reg_ptr = &(info_ptr->regs[range]);
1092 int first = reg_ptr->first;
1093 int last = reg_ptr->last;
1094 int size_1word = 0;
1095 int size_2words = 0;
1096 int regno;
1097
87b483a1 1098 /* Calculate which registers need to be saved & save area size. */
36a05131
BS
1099 switch (range)
1100 {
1101 default:
1102 for (regno = first; regno <= last; regno++)
1103 {
6fb5fa3c 1104 if ((df_regs_ever_live_p (regno) && !call_used_regs[regno])
e3b5732b 1105 || (crtl->calls_eh_return
36a05131 1106 && (regno >= FIRST_EH_REGNUM && regno <= LAST_EH_REGNUM))
34208acf 1107 || (!TARGET_FDPIC && flag_pic
ad516a74 1108 && crtl->uses_pic_offset_table && regno == PIC_REGNO))
36a05131
BS
1109 {
1110 info_ptr->save_p[regno] = REG_SAVE_1WORD;
1111 size_1word += UNITS_PER_WORD;
1112 }
1113 }
1114 break;
1115
1116 /* Calculate whether we need to create a frame after everything else
1117 has been processed. */
1118 case STACK_REGS_FP:
1119 break;
1120
1121 case STACK_REGS_LR:
6fb5fa3c 1122 if (df_regs_ever_live_p (LR_REGNO)
36a05131 1123 || profile_flag
34208acf
AO
1124 /* This is set for __builtin_return_address, etc. */
1125 || cfun->machine->frame_needed
1126 || (TARGET_LINKED_FP && frame_pointer_needed)
1127 || (!TARGET_FDPIC && flag_pic
ad516a74 1128 && crtl->uses_pic_offset_table))
36a05131
BS
1129 {
1130 info_ptr->save_p[LR_REGNO] = REG_SAVE_1WORD;
1131 size_1word += UNITS_PER_WORD;
1132 }
1133 break;
1134
1135 case STACK_REGS_STDARG:
1136 if (varargs_p)
1137 {
87b483a1
KH
1138 /* If this is a stdarg function with a non varardic
1139 argument split between registers and the stack,
1140 adjust the saved registers downward. */
7dd68986 1141 last -= (ADDR_ALIGN (crtl->args.pretend_args_size, UNITS_PER_WORD)
36a05131
BS
1142 / UNITS_PER_WORD);
1143
1144 for (regno = first; regno <= last; regno++)
1145 {
1146 info_ptr->save_p[regno] = REG_SAVE_1WORD;
1147 size_1word += UNITS_PER_WORD;
1148 }
1149
1150 info_ptr->stdarg_size = size_1word;
1151 }
1152 break;
1153
1154 case STACK_REGS_STRUCT:
1155 if (cfun->returns_struct)
1156 {
8ac411c7 1157 info_ptr->save_p[FRV_STRUCT_VALUE_REGNUM] = REG_SAVE_1WORD;
36a05131
BS
1158 size_1word += UNITS_PER_WORD;
1159 }
1160 break;
1161 }
1162
1163
1164 if (size_1word)
1165 {
87b483a1 1166 /* If this is a field, it only takes one word. */
36a05131
BS
1167 if (reg_ptr->field_p)
1168 size_1word = UNITS_PER_WORD;
1169
87b483a1 1170 /* Determine which register pairs can be saved together. */
36a05131
BS
1171 else if (reg_ptr->dword_p && TARGET_DWORD)
1172 {
1173 for (regno = first; regno < last; regno += 2)
1174 {
1175 if (info_ptr->save_p[regno] && info_ptr->save_p[regno+1])
1176 {
1177 size_2words += 2 * UNITS_PER_WORD;
1178 size_1word -= 2 * UNITS_PER_WORD;
1179 info_ptr->save_p[regno] = REG_SAVE_2WORDS;
1180 info_ptr->save_p[regno+1] = REG_SAVE_NO_SAVE;
1181 }
1182 }
1183 }
1184
1185 reg_ptr->size_1word = size_1word;
1186 reg_ptr->size_2words = size_2words;
1187
1188 if (! reg_ptr->special_p)
1189 {
1190 info_ptr->regs_size_1word += size_1word;
1191 info_ptr->regs_size_2words += size_2words;
1192 }
1193 }
1194 }
1195
026c3cfd 1196 /* Set up the sizes of each field in the frame body, making the sizes
36a05131
BS
1197 of each be divisible by the size of a dword if dword operations might
1198 be used, or the size of a word otherwise. */
1199 alignment = (TARGET_DWORD? 2 * UNITS_PER_WORD : UNITS_PER_WORD);
1200
7dd68986 1201 info_ptr->parameter_size = ADDR_ALIGN (crtl->outgoing_args_size, alignment);
36a05131
BS
1202 info_ptr->regs_size = ADDR_ALIGN (info_ptr->regs_size_2words
1203 + info_ptr->regs_size_1word,
1204 alignment);
1205 info_ptr->vars_size = ADDR_ALIGN (get_frame_size (), alignment);
1206
7dd68986 1207 info_ptr->pretend_size = crtl->args.pretend_args_size;
36a05131
BS
1208
1209 /* Work out the size of the frame, excluding the header. Both the frame
1210 body and register parameter area will be dword-aligned. */
1211 info_ptr->total_size
1212 = (ADDR_ALIGN (info_ptr->parameter_size
1213 + info_ptr->regs_size
1214 + info_ptr->vars_size,
1215 2 * UNITS_PER_WORD)
1216 + ADDR_ALIGN (info_ptr->pretend_size
1217 + info_ptr->stdarg_size,
1218 2 * UNITS_PER_WORD));
1219
1220 /* See if we need to create a frame at all, if so add header area. */
1221 if (info_ptr->total_size > 0
34208acf 1222 || frame_pointer_needed
36a05131
BS
1223 || info_ptr->regs[STACK_REGS_LR].size_1word > 0
1224 || info_ptr->regs[STACK_REGS_STRUCT].size_1word > 0)
1225 {
1226 offset = info_ptr->parameter_size;
1227 info_ptr->header_size = 4 * UNITS_PER_WORD;
1228 info_ptr->total_size += 4 * UNITS_PER_WORD;
1229
87b483a1 1230 /* Calculate the offsets to save normal register pairs. */
36a05131
BS
1231 for (range = 0; range < STACK_REGS_MAX; range++)
1232 {
1233 frv_stack_regs_t *reg_ptr = &(info_ptr->regs[range]);
1234 if (! reg_ptr->special_p)
1235 {
1236 int first = reg_ptr->first;
1237 int last = reg_ptr->last;
1238 int regno;
1239
1240 for (regno = first; regno <= last; regno++)
1241 if (info_ptr->save_p[regno] == REG_SAVE_2WORDS
1242 && regno != FRAME_POINTER_REGNUM
1243 && (regno < FIRST_ARG_REGNUM
1244 || regno > LAST_ARG_REGNUM))
1245 {
1246 info_ptr->reg_offset[regno] = offset;
1247 offset += 2 * UNITS_PER_WORD;
1248 }
1249 }
1250 }
1251
87b483a1 1252 /* Calculate the offsets to save normal single registers. */
36a05131
BS
1253 for (range = 0; range < STACK_REGS_MAX; range++)
1254 {
1255 frv_stack_regs_t *reg_ptr = &(info_ptr->regs[range]);
1256 if (! reg_ptr->special_p)
1257 {
1258 int first = reg_ptr->first;
1259 int last = reg_ptr->last;
1260 int regno;
1261
1262 for (regno = first; regno <= last; regno++)
1263 if (info_ptr->save_p[regno] == REG_SAVE_1WORD
1264 && regno != FRAME_POINTER_REGNUM
1265 && (regno < FIRST_ARG_REGNUM
1266 || regno > LAST_ARG_REGNUM))
1267 {
1268 info_ptr->reg_offset[regno] = offset;
1269 offset += UNITS_PER_WORD;
1270 }
1271 }
1272 }
1273
1274 /* Calculate the offset to save the local variables at. */
1275 offset = ADDR_ALIGN (offset, alignment);
1276 if (info_ptr->vars_size)
1277 {
1278 info_ptr->vars_offset = offset;
1279 offset += info_ptr->vars_size;
1280 }
1281
1282 /* Align header to a dword-boundary. */
1283 offset = ADDR_ALIGN (offset, 2 * UNITS_PER_WORD);
1284
1285 /* Calculate the offsets in the fixed frame. */
1286 info_ptr->save_p[FRAME_POINTER_REGNUM] = REG_SAVE_1WORD;
1287 info_ptr->reg_offset[FRAME_POINTER_REGNUM] = offset;
1288 info_ptr->regs[STACK_REGS_FP].size_1word = UNITS_PER_WORD;
1289
1290 info_ptr->save_p[LR_REGNO] = REG_SAVE_1WORD;
1291 info_ptr->reg_offset[LR_REGNO] = offset + 2*UNITS_PER_WORD;
1292 info_ptr->regs[STACK_REGS_LR].size_1word = UNITS_PER_WORD;
1293
1294 if (cfun->returns_struct)
1295 {
8ac411c7
KH
1296 info_ptr->save_p[FRV_STRUCT_VALUE_REGNUM] = REG_SAVE_1WORD;
1297 info_ptr->reg_offset[FRV_STRUCT_VALUE_REGNUM] = offset + UNITS_PER_WORD;
36a05131
BS
1298 info_ptr->regs[STACK_REGS_STRUCT].size_1word = UNITS_PER_WORD;
1299 }
1300
1301 /* Calculate the offsets to store the arguments passed in registers
1302 for stdarg functions. The register pairs are first and the single
1303 register if any is last. The register save area starts on a
1304 dword-boundary. */
1305 if (info_ptr->stdarg_size)
1306 {
1307 int first = info_ptr->regs[STACK_REGS_STDARG].first;
1308 int last = info_ptr->regs[STACK_REGS_STDARG].last;
1309 int regno;
1310
1311 /* Skip the header. */
1312 offset += 4 * UNITS_PER_WORD;
1313 for (regno = first; regno <= last; regno++)
1314 {
1315 if (info_ptr->save_p[regno] == REG_SAVE_2WORDS)
1316 {
1317 info_ptr->reg_offset[regno] = offset;
1318 offset += 2 * UNITS_PER_WORD;
1319 }
1320 else if (info_ptr->save_p[regno] == REG_SAVE_1WORD)
1321 {
1322 info_ptr->reg_offset[regno] = offset;
1323 offset += UNITS_PER_WORD;
1324 }
1325 }
1326 }
1327 }
1328
1329 if (reload_completed)
1330 frv_stack_cache = info_ptr;
1331
1332 return info_ptr;
1333}
1334
1335\f
87b483a1 1336/* Print the information about the frv stack offsets, etc. when debugging. */
36a05131
BS
1337
1338void
f2206911 1339frv_debug_stack (frv_stack_t *info)
36a05131
BS
1340{
1341 int range;
1342
1343 if (!info)
1344 info = frv_stack_info ();
1345
1346 fprintf (stderr, "\nStack information for function %s:\n",
1347 ((current_function_decl && DECL_NAME (current_function_decl))
1348 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
1349 : "<unknown>"));
1350
1351 fprintf (stderr, "\ttotal_size\t= %6d\n", info->total_size);
1352 fprintf (stderr, "\tvars_size\t= %6d\n", info->vars_size);
1353 fprintf (stderr, "\tparam_size\t= %6d\n", info->parameter_size);
1354 fprintf (stderr, "\tregs_size\t= %6d, 1w = %3d, 2w = %3d\n",
1355 info->regs_size, info->regs_size_1word, info->regs_size_2words);
1356
1357 fprintf (stderr, "\theader_size\t= %6d\n", info->header_size);
1358 fprintf (stderr, "\tpretend_size\t= %6d\n", info->pretend_size);
1359 fprintf (stderr, "\tvars_offset\t= %6d\n", info->vars_offset);
1360 fprintf (stderr, "\tregs_offset\t= %6d\n", info->regs_offset);
1361
1362 for (range = 0; range < STACK_REGS_MAX; range++)
1363 {
1364 frv_stack_regs_t *regs = &(info->regs[range]);
1365 if ((regs->size_1word + regs->size_2words) > 0)
1366 {
1367 int first = regs->first;
1368 int last = regs->last;
1369 int regno;
1370
1371 fprintf (stderr, "\t%s\tsize\t= %6d, 1w = %3d, 2w = %3d, save =",
1372 regs->name, regs->size_1word + regs->size_2words,
1373 regs->size_1word, regs->size_2words);
1374
1375 for (regno = first; regno <= last; regno++)
1376 {
1377 if (info->save_p[regno] == REG_SAVE_1WORD)
1378 fprintf (stderr, " %s (%d)", reg_names[regno],
1379 info->reg_offset[regno]);
1380
1381 else if (info->save_p[regno] == REG_SAVE_2WORDS)
1382 fprintf (stderr, " %s-%s (%d)", reg_names[regno],
1383 reg_names[regno+1], info->reg_offset[regno]);
1384 }
1385
1386 fputc ('\n', stderr);
1387 }
1388 }
1389
1390 fflush (stderr);
1391}
1392
1393
1394\f
1395
c557edf4
RS
1396/* Used during final to control the packing of insns. The value is
1397 1 if the current instruction should be packed with the next one,
1398 0 if it shouldn't or -1 if packing is disabled altogether. */
36a05131
BS
1399
1400static int frv_insn_packing_flag;
1401
1402/* True if the current function contains a far jump. */
1403
1404static int
f2206911 1405frv_function_contains_far_jump (void)
36a05131 1406{
b32d5189 1407 rtx_insn *insn = get_insns ();
36a05131 1408 while (insn != NULL
b64925dc 1409 && !(JUMP_P (insn)
36a05131
BS
1410 && get_attr_far_jump (insn) == FAR_JUMP_YES))
1411 insn = NEXT_INSN (insn);
1412 return (insn != NULL);
1413}
1414
1415/* For the FRV, this function makes sure that a function with far jumps
1416 will return correctly. It also does the VLIW packing. */
1417
1418static void
42776416 1419frv_function_prologue (FILE *file)
36a05131
BS
1420{
1421 /* If no frame was created, check whether the function uses a call
1422 instruction to implement a far jump. If so, save the link in gr3 and
1423 replace all returns to LR with returns to GR3. GR3 is used because it
1424 is call-clobbered, because is not available to the register allocator,
1425 and because all functions that take a hidden argument pointer will have
1426 a stack frame. */
1427 if (frv_stack_info ()->total_size == 0 && frv_function_contains_far_jump ())
1428 {
e6eda746 1429 rtx_insn *insn;
36a05131
BS
1430
1431 /* Just to check that the above comment is true. */
6fb5fa3c 1432 gcc_assert (!df_regs_ever_live_p (GPR_FIRST + 3));
36a05131
BS
1433
1434 /* Generate the instruction that saves the link register. */
1435 fprintf (file, "\tmovsg lr,gr3\n");
1436
1437 /* Replace the LR with GR3 in *return_internal patterns. The insn
1438 will now return using jmpl @(gr3,0) rather than bralr. We cannot
1439 simply emit a different assembly directive because bralr and jmpl
1440 execute in different units. */
1441 for (insn = get_insns(); insn != NULL; insn = NEXT_INSN (insn))
b64925dc 1442 if (JUMP_P (insn))
36a05131
BS
1443 {
1444 rtx pattern = PATTERN (insn);
1445 if (GET_CODE (pattern) == PARALLEL
1446 && XVECLEN (pattern, 0) >= 2
1447 && GET_CODE (XVECEXP (pattern, 0, 0)) == RETURN
1448 && GET_CODE (XVECEXP (pattern, 0, 1)) == USE)
1449 {
1450 rtx address = XEXP (XVECEXP (pattern, 0, 1), 0);
1451 if (GET_CODE (address) == REG && REGNO (address) == LR_REGNO)
6fb5fa3c 1452 SET_REGNO (address, GPR_FIRST + 3);
36a05131
BS
1453 }
1454 }
1455 }
1456
1457 frv_pack_insns ();
c557edf4
RS
1458
1459 /* Allow the garbage collector to free the nops created by frv_reorg. */
1460 memset (frv_nops, 0, sizeof (frv_nops));
36a05131
BS
1461}
1462
1463\f
1464/* Return the next available temporary register in a given class. */
1465
1466static rtx
f2206911
KC
1467frv_alloc_temp_reg (
1468 frv_tmp_reg_t *info, /* which registers are available */
0a2aaacc 1469 enum reg_class rclass, /* register class desired */
ef4bddc2 1470 machine_mode mode, /* mode to allocate register with */
f2206911
KC
1471 int mark_as_used, /* register not available after allocation */
1472 int no_abort) /* return NULL instead of aborting */
36a05131 1473{
0a2aaacc 1474 int regno = info->next_reg[ (int)rclass ];
36a05131 1475 int orig_regno = regno;
0a2aaacc 1476 HARD_REG_SET *reg_in_class = &reg_class_contents[ (int)rclass ];
36a05131
BS
1477 int i, nr;
1478
1479 for (;;)
1480 {
1481 if (TEST_HARD_REG_BIT (*reg_in_class, regno)
1482 && TEST_HARD_REG_BIT (info->regs, regno))
1483 break;
1484
1485 if (++regno >= FIRST_PSEUDO_REGISTER)
1486 regno = 0;
1487 if (regno == orig_regno)
1488 {
44e91694
NS
1489 gcc_assert (no_abort);
1490 return NULL_RTX;
36a05131
BS
1491 }
1492 }
1493
a93072ca 1494 nr = hard_regno_nregs (regno, mode);
0a2aaacc 1495 info->next_reg[ (int)rclass ] = regno + nr;
36a05131
BS
1496
1497 if (mark_as_used)
1498 for (i = 0; i < nr; i++)
1499 CLEAR_HARD_REG_BIT (info->regs, regno+i);
1500
1501 return gen_rtx_REG (mode, regno);
1502}
1503
1504\f
1505/* Return an rtx with the value OFFSET, which will either be a register or a
1506 signed 12-bit integer. It can be used as the second operand in an "add"
1507 instruction, or as the index in a load or store.
1508
1509 The function returns a constant rtx if OFFSET is small enough, otherwise
1510 it loads the constant into register OFFSET_REGNO and returns that. */
1511static rtx
f2206911 1512frv_frame_offset_rtx (int offset)
36a05131
BS
1513{
1514 rtx offset_rtx = GEN_INT (offset);
2f5b1308 1515 if (IN_RANGE (offset, -2048, 2047))
36a05131
BS
1516 return offset_rtx;
1517 else
1518 {
1519 rtx reg_rtx = gen_rtx_REG (SImode, OFFSET_REGNO);
2f5b1308 1520 if (IN_RANGE (offset, -32768, 32767))
36a05131
BS
1521 emit_insn (gen_movsi (reg_rtx, offset_rtx));
1522 else
1523 {
1524 emit_insn (gen_movsi_high (reg_rtx, offset_rtx));
1525 emit_insn (gen_movsi_lo_sum (reg_rtx, offset_rtx));
1526 }
1527 return reg_rtx;
1528 }
1529}
1530
1531/* Generate (mem:MODE (plus:Pmode BASE (frv_frame_offset OFFSET)))). The
1532 prologue and epilogue uses such expressions to access the stack. */
1533static rtx
ef4bddc2 1534frv_frame_mem (machine_mode mode, rtx base, int offset)
36a05131
BS
1535{
1536 return gen_rtx_MEM (mode, gen_rtx_PLUS (Pmode,
1537 base,
1538 frv_frame_offset_rtx (offset)));
1539}
1540
1541/* Generate a frame-related expression:
1542
1543 (set REG (mem (plus (sp) (const_int OFFSET)))).
1544
1545 Such expressions are used in FRAME_RELATED_EXPR notes for more complex
1546 instructions. Marking the expressions as frame-related is superfluous if
1547 the note contains just a single set. But if the note contains a PARALLEL
1548 or SEQUENCE that has several sets, each set must be individually marked
1549 as frame-related. */
1550static rtx
f2206911 1551frv_dwarf_store (rtx reg, int offset)
36a05131 1552{
f7df4a84 1553 rtx set = gen_rtx_SET (gen_rtx_MEM (GET_MODE (reg),
0a81f074 1554 plus_constant (Pmode, stack_pointer_rtx,
36a05131
BS
1555 offset)),
1556 reg);
1557 RTX_FRAME_RELATED_P (set) = 1;
1558 return set;
1559}
1560
1561/* Emit a frame-related instruction whose pattern is PATTERN. The
1562 instruction is the last in a sequence that cumulatively performs the
1563 operation described by DWARF_PATTERN. The instruction is marked as
1564 frame-related and has a REG_FRAME_RELATED_EXPR note containing
1565 DWARF_PATTERN. */
1566static void
f2206911 1567frv_frame_insn (rtx pattern, rtx dwarf_pattern)
36a05131
BS
1568{
1569 rtx insn = emit_insn (pattern);
1570 RTX_FRAME_RELATED_P (insn) = 1;
1571 REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
1572 dwarf_pattern,
1573 REG_NOTES (insn));
1574}
1575
1576/* Emit instructions that transfer REG to or from the memory location (sp +
1577 STACK_OFFSET). The register is stored in memory if ACCESSOR->OP is
1578 FRV_STORE and loaded if it is FRV_LOAD. Only the prologue uses this
1579 function to store registers and only the epilogue uses it to load them.
1580
1581 The caller sets up ACCESSOR so that BASE is equal to (sp + BASE_OFFSET).
1582 The generated instruction will use BASE as its base register. BASE may
1583 simply be the stack pointer, but if several accesses are being made to a
1584 region far away from the stack pointer, it may be more efficient to set
1585 up a temporary instead.
b16c1435 1586
36a05131
BS
1587 Store instructions will be frame-related and will be annotated with the
1588 overall effect of the store. Load instructions will be followed by a
1589 (use) to prevent later optimizations from zapping them.
1590
1591 The function takes care of the moves to and from SPRs, using TEMP_REGNO
1592 as a temporary in such cases. */
1593static void
f2206911 1594frv_frame_access (frv_frame_accessor_t *accessor, rtx reg, int stack_offset)
36a05131 1595{
ef4bddc2 1596 machine_mode mode = GET_MODE (reg);
36a05131
BS
1597 rtx mem = frv_frame_mem (mode,
1598 accessor->base,
1599 stack_offset - accessor->base_offset);
1600
1601 if (accessor->op == FRV_LOAD)
1602 {
1603 if (SPR_P (REGNO (reg)))
1604 {
1605 rtx temp = gen_rtx_REG (mode, TEMP_REGNO);
f7df4a84
RS
1606 emit_insn (gen_rtx_SET (temp, mem));
1607 emit_insn (gen_rtx_SET (reg, temp));
36a05131
BS
1608 }
1609 else
8d8256c1
NC
1610 {
1611 /* We cannot use reg+reg addressing for DImode access. */
1612 if (mode == DImode
1613 && GET_CODE (XEXP (mem, 0)) == PLUS
1614 && GET_CODE (XEXP (XEXP (mem, 0), 0)) == REG
1615 && GET_CODE (XEXP (XEXP (mem, 0), 1)) == REG)
1616 {
1617 rtx temp = gen_rtx_REG (SImode, TEMP_REGNO);
5c5e8419
JR
1618
1619 emit_move_insn (temp,
1620 gen_rtx_PLUS (SImode, XEXP (XEXP (mem, 0), 0),
1621 XEXP (XEXP (mem, 0), 1)));
8d8256c1
NC
1622 mem = gen_rtx_MEM (DImode, temp);
1623 }
f7df4a84 1624 emit_insn (gen_rtx_SET (reg, mem));
8d8256c1 1625 }
c41c1387 1626 emit_use (reg);
36a05131
BS
1627 }
1628 else
1629 {
1630 if (SPR_P (REGNO (reg)))
1631 {
1632 rtx temp = gen_rtx_REG (mode, TEMP_REGNO);
f7df4a84
RS
1633 emit_insn (gen_rtx_SET (temp, reg));
1634 frv_frame_insn (gen_rtx_SET (mem, temp),
36a05131
BS
1635 frv_dwarf_store (reg, stack_offset));
1636 }
8d8256c1 1637 else if (mode == DImode)
36a05131
BS
1638 {
1639 /* For DImode saves, the dwarf2 version needs to be a SEQUENCE
1640 with a separate save for each register. */
1641 rtx reg1 = gen_rtx_REG (SImode, REGNO (reg));
1642 rtx reg2 = gen_rtx_REG (SImode, REGNO (reg) + 1);
1643 rtx set1 = frv_dwarf_store (reg1, stack_offset);
1644 rtx set2 = frv_dwarf_store (reg2, stack_offset + 4);
8d8256c1
NC
1645
1646 /* Also we cannot use reg+reg addressing. */
1647 if (GET_CODE (XEXP (mem, 0)) == PLUS
1648 && GET_CODE (XEXP (XEXP (mem, 0), 0)) == REG
1649 && GET_CODE (XEXP (XEXP (mem, 0), 1)) == REG)
1650 {
1651 rtx temp = gen_rtx_REG (SImode, TEMP_REGNO);
5c5e8419
JR
1652 emit_move_insn (temp,
1653 gen_rtx_PLUS (SImode, XEXP (XEXP (mem, 0), 0),
1654 XEXP (XEXP (mem, 0), 1)));
8d8256c1
NC
1655 mem = gen_rtx_MEM (DImode, temp);
1656 }
1657
f7df4a84 1658 frv_frame_insn (gen_rtx_SET (mem, reg),
36a05131
BS
1659 gen_rtx_PARALLEL (VOIDmode,
1660 gen_rtvec (2, set1, set2)));
1661 }
1662 else
f7df4a84 1663 frv_frame_insn (gen_rtx_SET (mem, reg),
36a05131
BS
1664 frv_dwarf_store (reg, stack_offset));
1665 }
1666}
1667
1668/* A function that uses frv_frame_access to transfer a group of registers to
1669 or from the stack. ACCESSOR is passed directly to frv_frame_access, INFO
1670 is the stack information generated by frv_stack_info, and REG_SET is the
1671 number of the register set to transfer. */
1672static void
f2206911
KC
1673frv_frame_access_multi (frv_frame_accessor_t *accessor,
1674 frv_stack_t *info,
1675 int reg_set)
36a05131
BS
1676{
1677 frv_stack_regs_t *regs_info;
1678 int regno;
1679
1680 regs_info = &info->regs[reg_set];
1681 for (regno = regs_info->first; regno <= regs_info->last; regno++)
1682 if (info->save_p[regno])
1683 frv_frame_access (accessor,
1684 info->save_p[regno] == REG_SAVE_2WORDS
1685 ? gen_rtx_REG (DImode, regno)
1686 : gen_rtx_REG (SImode, regno),
1687 info->reg_offset[regno]);
1688}
1689
1690/* Save or restore callee-saved registers that are kept outside the frame
1691 header. The function saves the registers if OP is FRV_STORE and restores
1692 them if OP is FRV_LOAD. INFO is the stack information generated by
1693 frv_stack_info. */
1694static void
f2206911 1695frv_frame_access_standard_regs (enum frv_stack_op op, frv_stack_t *info)
36a05131
BS
1696{
1697 frv_frame_accessor_t accessor;
1698
1699 accessor.op = op;
1700 accessor.base = stack_pointer_rtx;
1701 accessor.base_offset = 0;
1702 frv_frame_access_multi (&accessor, info, STACK_REGS_GPR);
1703 frv_frame_access_multi (&accessor, info, STACK_REGS_FPR);
1704 frv_frame_access_multi (&accessor, info, STACK_REGS_LCR);
b16c1435 1705}
36a05131
BS
1706
1707
1708/* Called after register allocation to add any instructions needed for the
1709 prologue. Using a prologue insn is favored compared to putting all of the
b88cf82e
KH
1710 instructions in the TARGET_ASM_FUNCTION_PROLOGUE target hook, since
1711 it allows the scheduler to intermix instructions with the saves of
1712 the caller saved registers. In some cases, it might be necessary
1713 to emit a barrier instruction as the last insn to prevent such
1714 scheduling.
36a05131
BS
1715
1716 Also any insns generated here should have RTX_FRAME_RELATED_P(insn) = 1
1717 so that the debug info generation code can handle them properly. */
1718void
f2206911 1719frv_expand_prologue (void)
36a05131
BS
1720{
1721 frv_stack_t *info = frv_stack_info ();
1722 rtx sp = stack_pointer_rtx;
1723 rtx fp = frame_pointer_rtx;
1724 frv_frame_accessor_t accessor;
1725
1726 if (TARGET_DEBUG_STACK)
1727 frv_debug_stack (info);
1728
7027164c
NC
1729 if (flag_stack_usage_info)
1730 current_function_static_stack_size = info->total_size;
1731
36a05131
BS
1732 if (info->total_size == 0)
1733 return;
1734
1735 /* We're interested in three areas of the frame here:
1736
1737 A: the register save area
1738 B: the old FP
1739 C: the header after B
1740
1741 If the frame pointer isn't used, we'll have to set up A, B and C
1742 using the stack pointer. If the frame pointer is used, we'll access
1743 them as follows:
1744
1745 A: set up using sp
1746 B: set up using sp or a temporary (see below)
1747 C: set up using fp
1748
1749 We set up B using the stack pointer if the frame is small enough.
1750 Otherwise, it's more efficient to copy the old stack pointer into a
1751 temporary and use that.
1752
1753 Note that it's important to make sure the prologue and epilogue use the
1754 same registers to access A and C, since doing otherwise will confuse
1755 the aliasing code. */
1756
1757 /* Set up ACCESSOR for accessing region B above. If the frame pointer
1758 isn't used, the same method will serve for C. */
1759 accessor.op = FRV_STORE;
1760 if (frame_pointer_needed && info->total_size > 2048)
1761 {
36a05131
BS
1762 accessor.base = gen_rtx_REG (Pmode, OLD_SP_REGNO);
1763 accessor.base_offset = info->total_size;
5c5e8419 1764 emit_insn (gen_movsi (accessor.base, sp));
36a05131
BS
1765 }
1766 else
1767 {
1768 accessor.base = stack_pointer_rtx;
1769 accessor.base_offset = 0;
1770 }
1771
1772 /* Allocate the stack space. */
1773 {
1774 rtx asm_offset = frv_frame_offset_rtx (-info->total_size);
1775 rtx dwarf_offset = GEN_INT (-info->total_size);
1776
1777 frv_frame_insn (gen_stack_adjust (sp, sp, asm_offset),
f7df4a84 1778 gen_rtx_SET (sp, gen_rtx_PLUS (Pmode, sp, dwarf_offset)));
36a05131
BS
1779 }
1780
1781 /* If the frame pointer is needed, store the old one at (sp + FP_OFFSET)
1782 and point the new one to that location. */
1783 if (frame_pointer_needed)
1784 {
1785 int fp_offset = info->reg_offset[FRAME_POINTER_REGNUM];
1786
1787 /* ASM_SRC and DWARF_SRC both point to the frame header. ASM_SRC is
1788 based on ACCESSOR.BASE but DWARF_SRC is always based on the stack
1789 pointer. */
0a81f074 1790 rtx asm_src = plus_constant (Pmode, accessor.base,
36a05131 1791 fp_offset - accessor.base_offset);
0a81f074 1792 rtx dwarf_src = plus_constant (Pmode, sp, fp_offset);
36a05131
BS
1793
1794 /* Store the old frame pointer at (sp + FP_OFFSET). */
1795 frv_frame_access (&accessor, fp, fp_offset);
1796
1797 /* Set up the new frame pointer. */
f7df4a84
RS
1798 frv_frame_insn (gen_rtx_SET (fp, asm_src),
1799 gen_rtx_SET (fp, dwarf_src));
36a05131
BS
1800
1801 /* Access region C from the frame pointer. */
1802 accessor.base = fp;
1803 accessor.base_offset = fp_offset;
1804 }
1805
1806 /* Set up region C. */
1807 frv_frame_access_multi (&accessor, info, STACK_REGS_STRUCT);
1808 frv_frame_access_multi (&accessor, info, STACK_REGS_LR);
1809 frv_frame_access_multi (&accessor, info, STACK_REGS_STDARG);
1810
1811 /* Set up region A. */
1812 frv_frame_access_standard_regs (FRV_STORE, info);
1813
1814 /* If this is a varargs/stdarg function, issue a blockage to prevent the
1815 scheduler from moving loads before the stores saving the registers. */
1816 if (info->stdarg_size > 0)
1817 emit_insn (gen_blockage ());
1818
87b483a1 1819 /* Set up pic register/small data register for this function. */
ad516a74 1820 if (!TARGET_FDPIC && flag_pic && crtl->uses_pic_offset_table)
36a05131
BS
1821 emit_insn (gen_pic_prologue (gen_rtx_REG (Pmode, PIC_REGNO),
1822 gen_rtx_REG (Pmode, LR_REGNO),
1823 gen_rtx_REG (SImode, OFFSET_REGNO)));
1824}
1825
1826\f
1827/* Under frv, all of the work is done via frv_expand_epilogue, but
839a4992 1828 this function provides a convenient place to do cleanup. */
36a05131
BS
1829
1830static void
42776416 1831frv_function_epilogue (FILE *)
36a05131
BS
1832{
1833 frv_stack_cache = (frv_stack_t *)0;
1834
87b483a1 1835 /* Zap last used registers for conditional execution. */
fad205ff 1836 memset (&frv_ifcvt.tmp_reg, 0, sizeof (frv_ifcvt.tmp_reg));
36a05131 1837
87b483a1 1838 /* Release the bitmap of created insns. */
7b210806 1839 BITMAP_FREE (frv_ifcvt.scratch_insns_bitmap);
36a05131
BS
1840}
1841
1842\f
1843/* Called after register allocation to add any instructions needed for the
43aa4e05 1844 epilogue. Using an epilogue insn is favored compared to putting all of the
b88cf82e
KH
1845 instructions in the TARGET_ASM_FUNCTION_PROLOGUE target hook, since
1846 it allows the scheduler to intermix instructions with the saves of
1847 the caller saved registers. In some cases, it might be necessary
1848 to emit a barrier instruction as the last insn to prevent such
c557edf4 1849 scheduling. */
36a05131
BS
1850
1851void
764678d1 1852frv_expand_epilogue (bool emit_return)
36a05131
BS
1853{
1854 frv_stack_t *info = frv_stack_info ();
1855 rtx fp = frame_pointer_rtx;
1856 rtx sp = stack_pointer_rtx;
1857 rtx return_addr;
1858 int fp_offset;
1859
1860 fp_offset = info->reg_offset[FRAME_POINTER_REGNUM];
1861
1862 /* Restore the stack pointer to its original value if alloca or the like
1863 is used. */
416ff32e 1864 if (! crtl->sp_is_unchanging)
36a05131
BS
1865 emit_insn (gen_addsi3 (sp, fp, frv_frame_offset_rtx (-fp_offset)));
1866
1867 /* Restore the callee-saved registers that were used in this function. */
1868 frv_frame_access_standard_regs (FRV_LOAD, info);
1869
1870 /* Set RETURN_ADDR to the address we should return to. Set it to NULL if
1871 no return instruction should be emitted. */
764678d1 1872 if (info->save_p[LR_REGNO])
36a05131
BS
1873 {
1874 int lr_offset;
1875 rtx mem;
1876
1877 /* Use the same method to access the link register's slot as we did in
1878 the prologue. In other words, use the frame pointer if available,
1879 otherwise use the stack pointer.
1880
1881 LR_OFFSET is the offset of the link register's slot from the start
1882 of the frame and MEM is a memory rtx for it. */
1883 lr_offset = info->reg_offset[LR_REGNO];
1884 if (frame_pointer_needed)
1885 mem = frv_frame_mem (Pmode, fp, lr_offset - fp_offset);
1886 else
1887 mem = frv_frame_mem (Pmode, sp, lr_offset);
1888
1889 /* Load the old link register into a GPR. */
1890 return_addr = gen_rtx_REG (Pmode, TEMP_REGNO);
f7df4a84 1891 emit_insn (gen_rtx_SET (return_addr, mem));
36a05131
BS
1892 }
1893 else
1894 return_addr = gen_rtx_REG (Pmode, LR_REGNO);
1895
1896 /* Restore the old frame pointer. Emit a USE afterwards to make sure
1897 the load is preserved. */
1898 if (frame_pointer_needed)
1899 {
f7df4a84 1900 emit_insn (gen_rtx_SET (fp, gen_rtx_MEM (Pmode, fp)));
c41c1387 1901 emit_use (fp);
36a05131
BS
1902 }
1903
1904 /* Deallocate the stack frame. */
1905 if (info->total_size != 0)
1906 {
1907 rtx offset = frv_frame_offset_rtx (info->total_size);
1908 emit_insn (gen_stack_adjust (sp, sp, offset));
1909 }
1910
1911 /* If this function uses eh_return, add the final stack adjustment now. */
e3b5732b 1912 if (crtl->calls_eh_return)
36a05131
BS
1913 emit_insn (gen_stack_adjust (sp, sp, EH_RETURN_STACKADJ_RTX));
1914
764678d1 1915 if (emit_return)
36a05131 1916 emit_jump_insn (gen_epilogue_return (return_addr));
764678d1
AO
1917 else
1918 {
1919 rtx lr = return_addr;
1920
1921 if (REGNO (return_addr) != LR_REGNO)
1922 {
1923 lr = gen_rtx_REG (Pmode, LR_REGNO);
1924 emit_move_insn (lr, return_addr);
1925 }
1926
c41c1387 1927 emit_use (lr);
764678d1 1928 }
36a05131
BS
1929}
1930
1931\f
b88cf82e 1932/* Worker function for TARGET_ASM_OUTPUT_MI_THUNK. */
36a05131 1933
c590b625 1934static void
f2206911
KC
1935frv_asm_output_mi_thunk (FILE *file,
1936 tree thunk_fndecl ATTRIBUTE_UNUSED,
1937 HOST_WIDE_INT delta,
1938 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
1939 tree function)
36a05131 1940{
f7430263 1941 const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
36a05131
BS
1942 const char *name_func = XSTR (XEXP (DECL_RTL (function), 0), 0);
1943 const char *name_arg0 = reg_names[FIRST_ARG_REGNUM];
1944 const char *name_jmp = reg_names[JUMP_REGNO];
c557edf4 1945 const char *parallel = (frv_issue_rate () > 1 ? ".p" : "");
36a05131 1946
f7430263
MF
1947 assemble_start_function (thunk_fndecl, fnname);
1948
87b483a1 1949 /* Do the add using an addi if possible. */
2f5b1308 1950 if (IN_RANGE (delta, -2048, 2047))
eb0424da 1951 fprintf (file, "\taddi %s,#%d,%s\n", name_arg0, (int) delta, name_arg0);
36a05131
BS
1952 else
1953 {
4a0a75dd
KG
1954 const char *const name_add = reg_names[TEMP_REGNO];
1955 fprintf (file, "\tsethi%s #hi(" HOST_WIDE_INT_PRINT_DEC "),%s\n",
1956 parallel, delta, name_add);
1957 fprintf (file, "\tsetlo #lo(" HOST_WIDE_INT_PRINT_DEC "),%s\n",
1958 delta, name_add);
36a05131
BS
1959 fprintf (file, "\tadd %s,%s,%s\n", name_add, name_arg0, name_arg0);
1960 }
1961
34208acf
AO
1962 if (TARGET_FDPIC)
1963 {
1964 const char *name_pic = reg_names[FDPIC_REGNO];
1965 name_jmp = reg_names[FDPIC_FPTR_REGNO];
1966
1967 if (flag_pic != 1)
1968 {
1969 fprintf (file, "\tsethi%s #gotofffuncdeschi(", parallel);
1970 assemble_name (file, name_func);
1971 fprintf (file, "),%s\n", name_jmp);
1972
1973 fprintf (file, "\tsetlo #gotofffuncdesclo(");
1974 assemble_name (file, name_func);
1975 fprintf (file, "),%s\n", name_jmp);
1976
1977 fprintf (file, "\tldd @(%s,%s), %s\n", name_jmp, name_pic, name_jmp);
1978 }
1979 else
1980 {
1981 fprintf (file, "\tlddo @(%s,#gotofffuncdesc12(", name_pic);
1982 assemble_name (file, name_func);
1983 fprintf (file, "\t)), %s\n", name_jmp);
1984 }
1985 }
1986 else if (!flag_pic)
36a05131
BS
1987 {
1988 fprintf (file, "\tsethi%s #hi(", parallel);
1989 assemble_name (file, name_func);
1990 fprintf (file, "),%s\n", name_jmp);
1991
1992 fprintf (file, "\tsetlo #lo(");
1993 assemble_name (file, name_func);
1994 fprintf (file, "),%s\n", name_jmp);
1995 }
1996 else
1997 {
1998 /* Use JUMP_REGNO as a temporary PIC register. */
1999 const char *name_lr = reg_names[LR_REGNO];
2000 const char *name_gppic = name_jmp;
2001 const char *name_tmp = reg_names[TEMP_REGNO];
2002
2003 fprintf (file, "\tmovsg %s,%s\n", name_lr, name_tmp);
2004 fprintf (file, "\tcall 1f\n");
2005 fprintf (file, "1:\tmovsg %s,%s\n", name_lr, name_gppic);
2006 fprintf (file, "\tmovgs %s,%s\n", name_tmp, name_lr);
2007 fprintf (file, "\tsethi%s #gprelhi(1b),%s\n", parallel, name_tmp);
2008 fprintf (file, "\tsetlo #gprello(1b),%s\n", name_tmp);
2009 fprintf (file, "\tsub %s,%s,%s\n", name_gppic, name_tmp, name_gppic);
2010
2011 fprintf (file, "\tsethi%s #gprelhi(", parallel);
2012 assemble_name (file, name_func);
2013 fprintf (file, "),%s\n", name_tmp);
2014
2015 fprintf (file, "\tsetlo #gprello(");
2016 assemble_name (file, name_func);
2017 fprintf (file, "),%s\n", name_tmp);
2018
2019 fprintf (file, "\tadd %s,%s,%s\n", name_gppic, name_tmp, name_jmp);
2020 }
2021
87b483a1 2022 /* Jump to the function address. */
36a05131 2023 fprintf (file, "\tjmpl @(%s,%s)\n", name_jmp, reg_names[GPR_FIRST+0]);
f7430263 2024 assemble_end_function (thunk_fndecl, fnname);
36a05131
BS
2025}
2026
2027\f
36a05131 2028
87b483a1 2029/* On frv, create a frame whenever we need to create stack. */
36a05131 2030
b52b1749 2031static bool
f2206911 2032frv_frame_pointer_required (void)
36a05131 2033{
34208acf
AO
2034 /* If we forgoing the usual linkage requirements, we only need
2035 a frame pointer if the stack pointer might change. */
2036 if (!TARGET_LINKED_FP)
416ff32e 2037 return !crtl->sp_is_unchanging;
34208acf 2038
416ff32e 2039 if (! crtl->is_leaf)
b52b1749 2040 return true;
36a05131
BS
2041
2042 if (get_frame_size () != 0)
b52b1749 2043 return true;
36a05131
BS
2044
2045 if (cfun->stdarg)
b52b1749 2046 return true;
36a05131 2047
416ff32e 2048 if (!crtl->sp_is_unchanging)
b52b1749 2049 return true;
36a05131 2050
ad516a74 2051 if (!TARGET_FDPIC && flag_pic && crtl->uses_pic_offset_table)
b52b1749 2052 return true;
36a05131
BS
2053
2054 if (profile_flag)
b52b1749 2055 return true;
36a05131
BS
2056
2057 if (cfun->machine->frame_needed)
b52b1749 2058 return true;
36a05131 2059
b52b1749 2060 return false;
36a05131
BS
2061}
2062
2063\f
7b5cbb57
AS
2064/* Worker function for TARGET_CAN_ELIMINATE. */
2065
2066bool
2067frv_can_eliminate (const int from, const int to)
2068{
2069 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
2070 ? ! frame_pointer_needed
2071 : true);
2072}
2073
53680238
BE
2074/* This function returns the initial difference between the specified
2075 pair of registers. */
36a05131
BS
2076
2077/* See frv_stack_info for more details on the frv stack frame. */
2078
2079int
f2206911 2080frv_initial_elimination_offset (int from, int to)
36a05131
BS
2081{
2082 frv_stack_t *info = frv_stack_info ();
2083 int ret = 0;
2084
2085 if (to == STACK_POINTER_REGNUM && from == ARG_POINTER_REGNUM)
2086 ret = info->total_size - info->pretend_size;
2087
2088 else if (to == STACK_POINTER_REGNUM && from == FRAME_POINTER_REGNUM)
88d6a75f 2089 ret = info->reg_offset[FRAME_POINTER_REGNUM];
36a05131
BS
2090
2091 else if (to == FRAME_POINTER_REGNUM && from == ARG_POINTER_REGNUM)
2092 ret = (info->total_size
2093 - info->reg_offset[FRAME_POINTER_REGNUM]
2094 - info->pretend_size);
2095
2096 else
44e91694 2097 gcc_unreachable ();
36a05131
BS
2098
2099 if (TARGET_DEBUG_STACK)
2100 fprintf (stderr, "Eliminate %s to %s by adding %d\n",
2101 reg_names [from], reg_names[to], ret);
2102
2103 return ret;
2104}
2105
2106\f
d8c2bed3 2107/* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
36a05131 2108
d8c2bed3 2109static void
d5cc9181 2110frv_setup_incoming_varargs (cumulative_args_t cum_v,
e7056ca4
RS
2111 const function_arg_info &arg,
2112 int *pretend_size,
2113 int second_time)
36a05131 2114{
d5cc9181
JR
2115 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2116
36a05131
BS
2117 if (TARGET_DEBUG_ARG)
2118 fprintf (stderr,
2119 "setup_vararg: words = %2d, mode = %4s, pretend_size = %d, second_time = %d\n",
e7056ca4 2120 *cum, GET_MODE_NAME (arg.mode), *pretend_size, second_time);
36a05131
BS
2121}
2122
2123\f
b88cf82e 2124/* Worker function for TARGET_EXPAND_BUILTIN_SAVEREGS. */
36a05131 2125
8ac411c7 2126static rtx
f2206911 2127frv_expand_builtin_saveregs (void)
36a05131
BS
2128{
2129 int offset = UNITS_PER_WORD * FRV_NUM_ARG_REGS;
2130
2131 if (TARGET_DEBUG_ARG)
2132 fprintf (stderr, "expand_builtin_saveregs: offset from ap = %d\n",
2133 offset);
2134
f1c25d3b 2135 return gen_rtx_PLUS (Pmode, virtual_incoming_args_rtx, GEN_INT (- offset));
36a05131
BS
2136}
2137
2138\f
2139/* Expand __builtin_va_start to do the va_start macro. */
2140
d7bd8aeb 2141static void
f2206911 2142frv_expand_builtin_va_start (tree valist, rtx nextarg)
36a05131
BS
2143{
2144 tree t;
7dd68986 2145 int num = crtl->args.info - FIRST_ARG_REGNUM - FRV_NUM_ARG_REGS;
36a05131
BS
2146
2147 nextarg = gen_rtx_PLUS (Pmode, virtual_incoming_args_rtx,
2148 GEN_INT (UNITS_PER_WORD * num));
2149
2150 if (TARGET_DEBUG_ARG)
2151 {
2152 fprintf (stderr, "va_start: args_info = %d, num = %d\n",
7dd68986 2153 crtl->args.info, num);
36a05131
BS
2154
2155 debug_rtx (nextarg);
2156 }
2157
726a989a 2158 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
5be014d5
AP
2159 fold_convert (TREE_TYPE (valist),
2160 make_tree (sizetype, nextarg)));
36a05131
BS
2161 TREE_SIDE_EFFECTS (t) = 1;
2162
2163 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2164}
2165
36a05131
BS
2166\f
2167/* Expand a block move operation, and return 1 if successful. Return 0
2168 if we should let the compiler generate normal code.
2169
2170 operands[0] is the destination
2171 operands[1] is the source
2172 operands[2] is the length
2173 operands[3] is the alignment */
2174
2175/* Maximum number of loads to do before doing the stores */
2176#ifndef MAX_MOVE_REG
2177#define MAX_MOVE_REG 4
2178#endif
2179
2180/* Maximum number of total loads to do. */
2181#ifndef TOTAL_MOVE_REG
2182#define TOTAL_MOVE_REG 8
2183#endif
2184
2185int
f2206911 2186frv_expand_block_move (rtx operands[])
36a05131
BS
2187{
2188 rtx orig_dest = operands[0];
2189 rtx orig_src = operands[1];
2190 rtx bytes_rtx = operands[2];
2191 rtx align_rtx = operands[3];
2192 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
2193 int align;
2194 int bytes;
2195 int offset;
2196 int num_reg;
2197 int i;
2198 rtx src_reg;
2199 rtx dest_reg;
2200 rtx src_addr;
2201 rtx dest_addr;
2202 rtx src_mem;
2203 rtx dest_mem;
2204 rtx tmp_reg;
2205 rtx stores[MAX_MOVE_REG];
2206 int move_bytes;
ef4bddc2 2207 machine_mode mode;
36a05131 2208
87b483a1 2209 /* If this is not a fixed size move, just call memcpy. */
36a05131
BS
2210 if (! constp)
2211 return FALSE;
2212
44e91694
NS
2213 /* This should be a fixed size alignment. */
2214 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
36a05131
BS
2215
2216 align = INTVAL (align_rtx);
2217
2218 /* Anything to move? */
2219 bytes = INTVAL (bytes_rtx);
2220 if (bytes <= 0)
2221 return TRUE;
2222
2223 /* Don't support real large moves. */
2224 if (bytes > TOTAL_MOVE_REG*align)
2225 return FALSE;
2226
2227 /* Move the address into scratch registers. */
2228 dest_reg = copy_addr_to_reg (XEXP (orig_dest, 0));
2229 src_reg = copy_addr_to_reg (XEXP (orig_src, 0));
2230
2231 num_reg = offset = 0;
2232 for ( ; bytes > 0; (bytes -= move_bytes), (offset += move_bytes))
2233 {
87b483a1 2234 /* Calculate the correct offset for src/dest. */
36a05131
BS
2235 if (offset == 0)
2236 {
2237 src_addr = src_reg;
2238 dest_addr = dest_reg;
2239 }
2240 else
2241 {
0a81f074
RS
2242 src_addr = plus_constant (Pmode, src_reg, offset);
2243 dest_addr = plus_constant (Pmode, dest_reg, offset);
36a05131
BS
2244 }
2245
2246 /* Generate the appropriate load and store, saving the stores
2247 for later. */
2248 if (bytes >= 4 && align >= 4)
2249 mode = SImode;
2250 else if (bytes >= 2 && align >= 2)
2251 mode = HImode;
2252 else
2253 mode = QImode;
2254
2255 move_bytes = GET_MODE_SIZE (mode);
2256 tmp_reg = gen_reg_rtx (mode);
2257 src_mem = change_address (orig_src, mode, src_addr);
2258 dest_mem = change_address (orig_dest, mode, dest_addr);
f7df4a84
RS
2259 emit_insn (gen_rtx_SET (tmp_reg, src_mem));
2260 stores[num_reg++] = gen_rtx_SET (dest_mem, tmp_reg);
36a05131
BS
2261
2262 if (num_reg >= MAX_MOVE_REG)
2263 {
2264 for (i = 0; i < num_reg; i++)
2265 emit_insn (stores[i]);
2266 num_reg = 0;
2267 }
2268 }
2269
2270 for (i = 0; i < num_reg; i++)
2271 emit_insn (stores[i]);
2272
2273 return TRUE;
2274}
2275
2276\f
2277/* Expand a block clear operation, and return 1 if successful. Return 0
2278 if we should let the compiler generate normal code.
2279
2280 operands[0] is the destination
2281 operands[1] is the length
57e84f18 2282 operands[3] is the alignment */
36a05131
BS
2283
2284int
f2206911 2285frv_expand_block_clear (rtx operands[])
36a05131
BS
2286{
2287 rtx orig_dest = operands[0];
2288 rtx bytes_rtx = operands[1];
57e84f18 2289 rtx align_rtx = operands[3];
36a05131
BS
2290 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
2291 int align;
2292 int bytes;
2293 int offset;
36a05131
BS
2294 rtx dest_reg;
2295 rtx dest_addr;
2296 rtx dest_mem;
2297 int clear_bytes;
ef4bddc2 2298 machine_mode mode;
36a05131 2299
87b483a1 2300 /* If this is not a fixed size move, just call memcpy. */
36a05131
BS
2301 if (! constp)
2302 return FALSE;
2303
44e91694
NS
2304 /* This should be a fixed size alignment. */
2305 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
36a05131
BS
2306
2307 align = INTVAL (align_rtx);
2308
2309 /* Anything to move? */
2310 bytes = INTVAL (bytes_rtx);
2311 if (bytes <= 0)
2312 return TRUE;
2313
2314 /* Don't support real large clears. */
2315 if (bytes > TOTAL_MOVE_REG*align)
2316 return FALSE;
2317
2318 /* Move the address into a scratch register. */
2319 dest_reg = copy_addr_to_reg (XEXP (orig_dest, 0));
2320
5c5e8419 2321 offset = 0;
36a05131
BS
2322 for ( ; bytes > 0; (bytes -= clear_bytes), (offset += clear_bytes))
2323 {
87b483a1 2324 /* Calculate the correct offset for src/dest. */
36a05131
BS
2325 dest_addr = ((offset == 0)
2326 ? dest_reg
0a81f074 2327 : plus_constant (Pmode, dest_reg, offset));
36a05131 2328
87b483a1 2329 /* Generate the appropriate store of gr0. */
36a05131
BS
2330 if (bytes >= 4 && align >= 4)
2331 mode = SImode;
2332 else if (bytes >= 2 && align >= 2)
2333 mode = HImode;
2334 else
2335 mode = QImode;
2336
2337 clear_bytes = GET_MODE_SIZE (mode);
2338 dest_mem = change_address (orig_dest, mode, dest_addr);
f7df4a84 2339 emit_insn (gen_rtx_SET (dest_mem, const0_rtx));
36a05131
BS
2340 }
2341
2342 return TRUE;
2343}
2344
2345\f
2346/* The following variable is used to output modifiers of assembler
87b483a1 2347 code of the current output insn. */
36a05131
BS
2348
2349static rtx *frv_insn_operands;
2350
2351/* The following function is used to add assembler insn code suffix .p
87b483a1 2352 if it is necessary. */
36a05131
BS
2353
2354const char *
f2206911 2355frv_asm_output_opcode (FILE *f, const char *ptr)
36a05131
BS
2356{
2357 int c;
2358
c557edf4 2359 if (frv_insn_packing_flag <= 0)
36a05131
BS
2360 return ptr;
2361
2362 for (; *ptr && *ptr != ' ' && *ptr != '\t';)
2363 {
2364 c = *ptr++;
2365 if (c == '%' && ((*ptr >= 'a' && *ptr <= 'z')
2366 || (*ptr >= 'A' && *ptr <= 'Z')))
2367 {
2368 int letter = *ptr++;
2369
2370 c = atoi (ptr);
2371 frv_print_operand (f, frv_insn_operands [c], letter);
2372 while ((c = *ptr) >= '0' && c <= '9')
2373 ptr++;
2374 }
2375 else
2376 fputc (c, f);
2377 }
2378
c557edf4 2379 fprintf (f, ".p");
36a05131
BS
2380
2381 return ptr;
2382}
2383
c557edf4
RS
2384/* Set up the packing bit for the current output insn. Note that this
2385 function is not called for asm insns. */
36a05131
BS
2386
2387void
647d790d 2388frv_final_prescan_insn (rtx_insn *insn, rtx *opvec,
c557edf4 2389 int noperands ATTRIBUTE_UNUSED)
36a05131 2390{
c557edf4 2391 if (INSN_P (insn))
36a05131 2392 {
c557edf4
RS
2393 if (frv_insn_packing_flag >= 0)
2394 {
2395 frv_insn_operands = opvec;
2396 frv_insn_packing_flag = PACKING_FLAG_P (insn);
2397 }
2398 else if (recog_memoized (insn) >= 0
2399 && get_attr_acc_group (insn) == ACC_GROUP_ODD)
2400 /* Packing optimizations have been disabled, but INSN can only
2401 be issued in M1. Insert an mnop in M0. */
2402 fprintf (asm_out_file, "\tmnop.p\n");
36a05131 2403 }
36a05131
BS
2404}
2405
2406
2407\f
2408/* A C expression whose value is RTL representing the address in a stack frame
2409 where the pointer to the caller's frame is stored. Assume that FRAMEADDR is
2410 an RTL expression for the address of the stack frame itself.
2411
2412 If you don't define this macro, the default is to return the value of
2413 FRAMEADDR--that is, the stack frame address is also the address of the stack
2414 word that points to the previous frame. */
2415
2416/* The default is correct, but we need to make sure the frame gets created. */
2417rtx
f2206911 2418frv_dynamic_chain_address (rtx frame)
36a05131
BS
2419{
2420 cfun->machine->frame_needed = 1;
2421 return frame;
2422}
2423
2424
2425/* A C expression whose value is RTL representing the value of the return
2426 address for the frame COUNT steps up from the current frame, after the
2427 prologue. FRAMEADDR is the frame pointer of the COUNT frame, or the frame
2428 pointer of the COUNT - 1 frame if `RETURN_ADDR_IN_PREVIOUS_FRAME' is
2429 defined.
2430
2431 The value of the expression must always be the correct address when COUNT is
2432 zero, but may be `NULL_RTX' if there is not way to determine the return
2433 address of other frames. */
2434
2435rtx
34208acf 2436frv_return_addr_rtx (int count, rtx frame)
36a05131 2437{
34208acf
AO
2438 if (count != 0)
2439 return const0_rtx;
36a05131 2440 cfun->machine->frame_needed = 1;
0a81f074 2441 return gen_rtx_MEM (Pmode, plus_constant (Pmode, frame, 8));
36a05131
BS
2442}
2443
2444/* Given a memory reference MEMREF, interpret the referenced memory as
2445 an array of MODE values, and return a reference to the element
2446 specified by INDEX. Assume that any pre-modification implicit in
2447 MEMREF has already happened.
2448
2449 MEMREF must be a legitimate operand for modes larger than SImode.
c6c3dba9 2450 frv_legitimate_address_p forbids register+register addresses, which
36a05131
BS
2451 this function cannot handle. */
2452rtx
ef4bddc2 2453frv_index_memory (rtx memref, machine_mode mode, int index)
36a05131
BS
2454{
2455 rtx base = XEXP (memref, 0);
2456 if (GET_CODE (base) == PRE_MODIFY)
2457 base = XEXP (base, 0);
2458 return change_address (memref, mode,
0a81f074
RS
2459 plus_constant (Pmode, base,
2460 index * GET_MODE_SIZE (mode)));
36a05131
BS
2461}
2462
2463\f
2464/* Print a memory address as an operand to reference that memory location. */
0fb30cb7 2465static void
cc8ca59e 2466frv_print_operand_address (FILE * stream, machine_mode /* mode */, rtx x)
36a05131
BS
2467{
2468 if (GET_CODE (x) == MEM)
2469 x = XEXP (x, 0);
2470
2471 switch (GET_CODE (x))
2472 {
2473 case REG:
2474 fputs (reg_names [ REGNO (x)], stream);
2475 return;
2476
2477 case CONST_INT:
2478 fprintf (stream, "%ld", (long) INTVAL (x));
2479 return;
2480
2481 case SYMBOL_REF:
2482 assemble_name (stream, XSTR (x, 0));
2483 return;
2484
2485 case LABEL_REF:
2486 case CONST:
2487 output_addr_const (stream, x);
2488 return;
2489
8d8256c1
NC
2490 case PLUS:
2491 /* Poorly constructed asm statements can trigger this alternative.
2492 See gcc/testsuite/gcc.dg/asm-4.c for an example. */
2493 frv_print_operand_memory_reference (stream, x, 0);
2494 return;
2495
36a05131
BS
2496 default:
2497 break;
2498 }
2499
ab532386 2500 fatal_insn ("bad insn to frv_print_operand_address:", x);
36a05131
BS
2501}
2502
2503\f
2504static void
f2206911 2505frv_print_operand_memory_reference_reg (FILE * stream, rtx x)
36a05131
BS
2506{
2507 int regno = true_regnum (x);
2508 if (GPR_P (regno))
2509 fputs (reg_names[regno], stream);
2510 else
ab532386 2511 fatal_insn ("bad register to frv_print_operand_memory_reference_reg:", x);
36a05131
BS
2512}
2513
2514/* Print a memory reference suitable for the ld/st instructions. */
2515
2516static void
f2206911 2517frv_print_operand_memory_reference (FILE * stream, rtx x, int addr_offset)
36a05131 2518{
34208acf 2519 struct frv_unspec unspec;
36a05131
BS
2520 rtx x0 = NULL_RTX;
2521 rtx x1 = NULL_RTX;
2522
2523 switch (GET_CODE (x))
2524 {
2525 case SUBREG:
2526 case REG:
2527 x0 = x;
2528 break;
2529
2530 case PRE_MODIFY: /* (pre_modify (reg) (plus (reg) (reg))) */
2531 x0 = XEXP (x, 0);
2532 x1 = XEXP (XEXP (x, 1), 1);
2533 break;
2534
2535 case CONST_INT:
2536 x1 = x;
2537 break;
2538
2539 case PLUS:
2540 x0 = XEXP (x, 0);
2541 x1 = XEXP (x, 1);
2542 if (GET_CODE (x0) == CONST_INT)
2543 {
2544 x0 = XEXP (x, 1);
2545 x1 = XEXP (x, 0);
2546 }
2547 break;
2548
2549 default:
ab532386 2550 fatal_insn ("bad insn to frv_print_operand_memory_reference:", x);
36a05131
BS
2551 break;
2552
2553 }
2554
2555 if (addr_offset)
2556 {
2557 if (!x1)
2558 x1 = const0_rtx;
2559 else if (GET_CODE (x1) != CONST_INT)
ab532386 2560 fatal_insn ("bad insn to frv_print_operand_memory_reference:", x);
36a05131
BS
2561 }
2562
2563 fputs ("@(", stream);
2564 if (!x0)
2565 fputs (reg_names[GPR_R0], stream);
2566 else if (GET_CODE (x0) == REG || GET_CODE (x0) == SUBREG)
2567 frv_print_operand_memory_reference_reg (stream, x0);
2568 else
ab532386 2569 fatal_insn ("bad insn to frv_print_operand_memory_reference:", x);
36a05131
BS
2570
2571 fputs (",", stream);
2572 if (!x1)
2573 fputs (reg_names [GPR_R0], stream);
2574
2575 else
2576 {
2577 switch (GET_CODE (x1))
2578 {
2579 case SUBREG:
2580 case REG:
2581 frv_print_operand_memory_reference_reg (stream, x1);
2582 break;
2583
2584 case CONST_INT:
2585 fprintf (stream, "%ld", (long) (INTVAL (x1) + addr_offset));
2586 break;
2587
36a05131 2588 case CONST:
34208acf 2589 if (!frv_const_unspec_p (x1, &unspec))
ab532386 2590 fatal_insn ("bad insn to frv_print_operand_memory_reference:", x1);
34208acf 2591 frv_output_const_unspec (stream, &unspec);
36a05131
BS
2592 break;
2593
2594 default:
ab532386 2595 fatal_insn ("bad insn to frv_print_operand_memory_reference:", x);
36a05131
BS
2596 }
2597 }
2598
2599 fputs (")", stream);
2600}
2601
2602\f
2603/* Return 2 for likely branches and 0 for non-likely branches */
2604
2605#define FRV_JUMP_LIKELY 2
2606#define FRV_JUMP_NOT_LIKELY 0
2607
2608static int
68a1a6c0 2609frv_print_operand_jump_hint (rtx_insn *insn)
36a05131
BS
2610{
2611 rtx note;
2612 rtx labelref;
2613 int ret;
36a05131
BS
2614 enum { UNKNOWN, BACKWARD, FORWARD } jump_type = UNKNOWN;
2615
b64925dc 2616 gcc_assert (JUMP_P (insn));
36a05131
BS
2617
2618 /* Assume any non-conditional jump is likely. */
2619 if (! any_condjump_p (insn))
2620 ret = FRV_JUMP_LIKELY;
2621
2622 else
2623 {
2624 labelref = condjump_label (insn);
2625 if (labelref)
2626 {
2627 rtx label = XEXP (labelref, 0);
2628 jump_type = (insn_current_address > INSN_ADDRESSES (INSN_UID (label))
2629 ? BACKWARD
2630 : FORWARD);
2631 }
2632
2633 note = find_reg_note (insn, REG_BR_PROB, 0);
2634 if (!note)
2635 ret = ((jump_type == BACKWARD) ? FRV_JUMP_LIKELY : FRV_JUMP_NOT_LIKELY);
2636
2637 else
2638 {
5fa396ad
JH
2639 ret = ((profile_probability::from_reg_br_prob_note (XINT (note, 0))
2640 >= profile_probability::even ())
36a05131
BS
2641 ? FRV_JUMP_LIKELY
2642 : FRV_JUMP_NOT_LIKELY);
2643 }
2644 }
2645
2646#if 0
2647 if (TARGET_DEBUG)
2648 {
2649 char *direction;
2650
2651 switch (jump_type)
2652 {
2653 default:
2654 case UNKNOWN: direction = "unknown jump direction"; break;
2655 case BACKWARD: direction = "jump backward"; break;
2656 case FORWARD: direction = "jump forward"; break;
2657 }
2658
2659 fprintf (stderr,
e5af9ddd 2660 "%s: uid %ld, %s, probability = %d, max prob. = %d, hint = %d\n",
36a05131 2661 IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),
e5af9ddd
RS
2662 (long)INSN_UID (insn), direction, prob,
2663 REG_BR_PROB_BASE, ret);
36a05131
BS
2664 }
2665#endif
2666
2667 return ret;
2668}
2669
2670\f
036ff63f
RS
2671/* Return the comparison operator to use for CODE given that the ICC
2672 register is OP0. */
2673
2674static const char *
2675comparison_string (enum rtx_code code, rtx op0)
2676{
2677 bool is_nz_p = GET_MODE (op0) == CC_NZmode;
2678 switch (code)
2679 {
4f4bf94e 2680 default: output_operand_lossage ("bad condition code"); return "";
036ff63f
RS
2681 case EQ: return "eq";
2682 case NE: return "ne";
2683 case LT: return is_nz_p ? "n" : "lt";
2684 case LE: return "le";
2685 case GT: return "gt";
2686 case GE: return is_nz_p ? "p" : "ge";
2687 case LTU: return is_nz_p ? "no" : "c";
2688 case LEU: return is_nz_p ? "eq" : "ls";
2689 case GTU: return is_nz_p ? "ne" : "hi";
2690 case GEU: return is_nz_p ? "ra" : "nc";
2691 }
2692}
2693
43aa4e05 2694/* Print an operand to an assembler instruction.
36a05131
BS
2695
2696 `%' followed by a letter and a digit says to output an operand in an
0fb30cb7
NF
2697 alternate fashion. Four letters have standard, built-in meanings
2698 described below. The hook `TARGET_PRINT_OPERAND' can define
2699 additional letters with nonstandard meanings.
36a05131
BS
2700
2701 `%cDIGIT' can be used to substitute an operand that is a constant value
2702 without the syntax that normally indicates an immediate operand.
2703
2704 `%nDIGIT' is like `%cDIGIT' except that the value of the constant is negated
2705 before printing.
2706
2707 `%aDIGIT' can be used to substitute an operand as if it were a memory
2708 reference, with the actual operand treated as the address. This may be
2709 useful when outputting a "load address" instruction, because often the
2710 assembler syntax for such an instruction requires you to write the operand
2711 as if it were a memory reference.
2712
2713 `%lDIGIT' is used to substitute a `label_ref' into a jump instruction.
2714
2715 `%=' outputs a number which is unique to each instruction in the entire
2716 compilation. This is useful for making local labels to be referred to more
2717 than once in a single template that generates multiple assembler
2718 instructions.
2719
0fb30cb7
NF
2720 `%' followed by a punctuation character specifies a substitution that
2721 does not use an operand. Only one case is standard: `%%' outputs a
2722 `%' into the assembler code. Other nonstandard cases can be defined
2723 in the `TARGET_PRINT_OPERAND' hook. You must also define which
2724 punctuation characters are valid with the
2725 `TARGET_PRINT_OPERAND_PUNCT_VALID_P' hook. */
36a05131 2726
0fb30cb7 2727static void
f2206911 2728frv_print_operand (FILE * file, rtx x, int code)
36a05131 2729{
34208acf 2730 struct frv_unspec unspec;
36a05131
BS
2731 HOST_WIDE_INT value;
2732 int offset;
2733
0a2aaacc 2734 if (code != 0 && !ISALPHA (code))
36a05131
BS
2735 value = 0;
2736
2737 else if (GET_CODE (x) == CONST_INT)
2738 value = INTVAL (x);
2739
2740 else if (GET_CODE (x) == CONST_DOUBLE)
2741 {
2742 if (GET_MODE (x) == SFmode)
2743 {
36a05131
BS
2744 long l;
2745
34a72c33 2746 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l);
36a05131
BS
2747 value = l;
2748 }
2749
2750 else if (GET_MODE (x) == VOIDmode)
2751 value = CONST_DOUBLE_LOW (x);
2752
2753 else
ab532386 2754 fatal_insn ("bad insn in frv_print_operand, bad const_double", x);
36a05131
BS
2755 }
2756
2757 else
2758 value = 0;
2759
2760 switch (code)
2761 {
2762
2763 case '.':
87b483a1 2764 /* Output r0. */
36a05131
BS
2765 fputs (reg_names[GPR_R0], file);
2766 break;
2767
2768 case '#':
2769 fprintf (file, "%d", frv_print_operand_jump_hint (current_output_insn));
2770 break;
2771
0f6e5d45 2772 case '@':
87b483a1 2773 /* Output small data area base register (gr16). */
36a05131
BS
2774 fputs (reg_names[SDA_BASE_REG], file);
2775 break;
2776
2777 case '~':
87b483a1 2778 /* Output pic register (gr17). */
36a05131
BS
2779 fputs (reg_names[PIC_REGNO], file);
2780 break;
2781
2782 case '*':
87b483a1 2783 /* Output the temporary integer CCR register. */
36a05131
BS
2784 fputs (reg_names[ICR_TEMP], file);
2785 break;
2786
2787 case '&':
87b483a1 2788 /* Output the temporary integer CC register. */
36a05131
BS
2789 fputs (reg_names[ICC_TEMP], file);
2790 break;
2791
87b483a1 2792 /* case 'a': print an address. */
36a05131
BS
2793
2794 case 'C':
87b483a1 2795 /* Print appropriate test for integer branch false operation. */
036ff63f
RS
2796 fputs (comparison_string (reverse_condition (GET_CODE (x)),
2797 XEXP (x, 0)), file);
36a05131
BS
2798 break;
2799
36a05131 2800 case 'c':
87b483a1 2801 /* Print appropriate test for integer branch true operation. */
036ff63f 2802 fputs (comparison_string (GET_CODE (x), XEXP (x, 0)), file);
36a05131
BS
2803 break;
2804
2805 case 'e':
2806 /* Print 1 for a NE and 0 for an EQ to give the final argument
2807 for a conditional instruction. */
2808 if (GET_CODE (x) == NE)
2809 fputs ("1", file);
2810
2811 else if (GET_CODE (x) == EQ)
2812 fputs ("0", file);
2813
2814 else
ab532386 2815 fatal_insn ("bad insn to frv_print_operand, 'e' modifier:", x);
36a05131
BS
2816 break;
2817
2818 case 'F':
87b483a1 2819 /* Print appropriate test for floating point branch false operation. */
36a05131
BS
2820 switch (GET_CODE (x))
2821 {
2822 default:
ab532386 2823 fatal_insn ("bad insn to frv_print_operand, 'F' modifier:", x);
36a05131
BS
2824
2825 case EQ: fputs ("ne", file); break;
2826 case NE: fputs ("eq", file); break;
2827 case LT: fputs ("uge", file); break;
2828 case LE: fputs ("ug", file); break;
2829 case GT: fputs ("ule", file); break;
2830 case GE: fputs ("ul", file); break;
2831 }
2832 break;
2833
2834 case 'f':
87b483a1 2835 /* Print appropriate test for floating point branch true operation. */
36a05131
BS
2836 switch (GET_CODE (x))
2837 {
2838 default:
ab532386 2839 fatal_insn ("bad insn to frv_print_operand, 'f' modifier:", x);
36a05131
BS
2840
2841 case EQ: fputs ("eq", file); break;
2842 case NE: fputs ("ne", file); break;
2843 case LT: fputs ("lt", file); break;
2844 case LE: fputs ("le", file); break;
2845 case GT: fputs ("gt", file); break;
2846 case GE: fputs ("ge", file); break;
2847 }
2848 break;
2849
34208acf
AO
2850 case 'g':
2851 /* Print appropriate GOT function. */
2852 if (GET_CODE (x) != CONST_INT)
ab532386 2853 fatal_insn ("bad insn to frv_print_operand, 'g' modifier:", x);
34208acf
AO
2854 fputs (unspec_got_name (INTVAL (x)), file);
2855 break;
2856
36a05131
BS
2857 case 'I':
2858 /* Print 'i' if the operand is a constant, or is a memory reference that
87b483a1 2859 adds a constant. */
36a05131
BS
2860 if (GET_CODE (x) == MEM)
2861 x = ((GET_CODE (XEXP (x, 0)) == PLUS)
2862 ? XEXP (XEXP (x, 0), 1)
2863 : XEXP (x, 0));
34208acf
AO
2864 else if (GET_CODE (x) == PLUS)
2865 x = XEXP (x, 1);
36a05131
BS
2866
2867 switch (GET_CODE (x))
2868 {
2869 default:
2870 break;
2871
2872 case CONST_INT:
2873 case SYMBOL_REF:
2874 case CONST:
2875 fputs ("i", file);
2876 break;
2877 }
2878 break;
2879
2880 case 'i':
2881 /* For jump instructions, print 'i' if the operand is a constant or
87b483a1 2882 is an expression that adds a constant. */
36a05131
BS
2883 if (GET_CODE (x) == CONST_INT)
2884 fputs ("i", file);
2885
2886 else
2887 {
2888 if (GET_CODE (x) == CONST_INT
2889 || (GET_CODE (x) == PLUS
2890 && (GET_CODE (XEXP (x, 1)) == CONST_INT
2891 || GET_CODE (XEXP (x, 0)) == CONST_INT)))
2892 fputs ("i", file);
2893 }
2894 break;
2895
2896 case 'L':
2897 /* Print the lower register of a double word register pair */
2898 if (GET_CODE (x) == REG)
2899 fputs (reg_names[ REGNO (x)+1 ], file);
2900 else
ab532386 2901 fatal_insn ("bad insn to frv_print_operand, 'L' modifier:", x);
36a05131
BS
2902 break;
2903
87b483a1 2904 /* case 'l': print a LABEL_REF. */
36a05131
BS
2905
2906 case 'M':
2907 case 'N':
2908 /* Print a memory reference for ld/st/jmp, %N prints a memory reference
2909 for the second word of double memory operations. */
2910 offset = (code == 'M') ? 0 : UNITS_PER_WORD;
2911 switch (GET_CODE (x))
2912 {
2913 default:
ab532386 2914 fatal_insn ("bad insn to frv_print_operand, 'M/N' modifier:", x);
36a05131
BS
2915
2916 case MEM:
2917 frv_print_operand_memory_reference (file, XEXP (x, 0), offset);
2918 break;
2919
2920 case REG:
2921 case SUBREG:
2922 case CONST_INT:
2923 case PLUS:
2924 case SYMBOL_REF:
2925 frv_print_operand_memory_reference (file, x, offset);
2926 break;
2927 }
2928 break;
2929
2930 case 'O':
2931 /* Print the opcode of a command. */
2932 switch (GET_CODE (x))
2933 {
2934 default:
ab532386 2935 fatal_insn ("bad insn to frv_print_operand, 'O' modifier:", x);
36a05131
BS
2936
2937 case PLUS: fputs ("add", file); break;
2938 case MINUS: fputs ("sub", file); break;
2939 case AND: fputs ("and", file); break;
2940 case IOR: fputs ("or", file); break;
2941 case XOR: fputs ("xor", file); break;
2942 case ASHIFT: fputs ("sll", file); break;
2943 case ASHIFTRT: fputs ("sra", file); break;
2944 case LSHIFTRT: fputs ("srl", file); break;
2945 }
2946 break;
2947
87b483a1 2948 /* case 'n': negate and print a constant int. */
36a05131
BS
2949
2950 case 'P':
2951 /* Print PIC label using operand as the number. */
2952 if (GET_CODE (x) != CONST_INT)
ab532386 2953 fatal_insn ("bad insn to frv_print_operand, P modifier:", x);
36a05131
BS
2954
2955 fprintf (file, ".LCF%ld", (long)INTVAL (x));
2956 break;
2957
2958 case 'U':
87b483a1 2959 /* Print 'u' if the operand is a update load/store. */
36a05131
BS
2960 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
2961 fputs ("u", file);
2962 break;
2963
2964 case 'z':
87b483a1 2965 /* If value is 0, print gr0, otherwise it must be a register. */
36a05131
BS
2966 if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0)
2967 fputs (reg_names[GPR_R0], file);
2968
2969 else if (GET_CODE (x) == REG)
2970 fputs (reg_names [REGNO (x)], file);
2971
2972 else
ab532386 2973 fatal_insn ("bad insn in frv_print_operand, z case", x);
36a05131
BS
2974 break;
2975
2976 case 'x':
87b483a1 2977 /* Print constant in hex. */
36a05131
BS
2978 if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
2979 {
2980 fprintf (file, "%s0x%.4lx", IMMEDIATE_PREFIX, (long) value);
2981 break;
2982 }
2983
87b483a1 2984 /* Fall through. */
36a05131
BS
2985
2986 case '\0':
2987 if (GET_CODE (x) == REG)
2988 fputs (reg_names [REGNO (x)], file);
2989
2990 else if (GET_CODE (x) == CONST_INT
2991 || GET_CODE (x) == CONST_DOUBLE)
2992 fprintf (file, "%s%ld", IMMEDIATE_PREFIX, (long) value);
2993
34208acf
AO
2994 else if (frv_const_unspec_p (x, &unspec))
2995 frv_output_const_unspec (file, &unspec);
2996
36a05131 2997 else if (GET_CODE (x) == MEM)
cc8ca59e 2998 frv_print_operand_address (file, GET_MODE (x), XEXP (x, 0));
36a05131
BS
2999
3000 else if (CONSTANT_ADDRESS_P (x))
cc8ca59e 3001 frv_print_operand_address (file, VOIDmode, x);
36a05131
BS
3002
3003 else
ab532386 3004 fatal_insn ("bad insn in frv_print_operand, 0 case", x);
36a05131
BS
3005
3006 break;
3007
3008 default:
3009 fatal_insn ("frv_print_operand: unknown code", x);
3010 break;
3011 }
3012
3013 return;
3014}
3015
0fb30cb7
NF
3016static bool
3017frv_print_operand_punct_valid_p (unsigned char code)
3018{
3019 return (code == '.' || code == '#' || code == '@' || code == '~'
3020 || code == '*' || code == '&');
3021}
3022
36a05131
BS
3023\f
3024/* A C statement (sans semicolon) for initializing the variable CUM for the
3025 state at the beginning of the argument list. The variable has type
3026 `CUMULATIVE_ARGS'. The value of FNTYPE is the tree node for the data type
3027 of the function which will receive the args, or 0 if the args are to a
3028 compiler support library function. The value of INDIRECT is nonzero when
3029 processing an indirect call, for example a call through a function pointer.
3030 The value of INDIRECT is zero for a call to an explicitly named function, a
3031 library function call, or when `INIT_CUMULATIVE_ARGS' is used to find
3032 arguments for the function being compiled.
3033
3034 When processing a call to a compiler support library function, LIBNAME
3035 identifies which one. It is a `symbol_ref' rtx which contains the name of
3036 the function, as a string. LIBNAME is 0 when an ordinary C function call is
3037 being processed. Thus, each time this macro is called, either LIBNAME or
3038 FNTYPE is nonzero, but never both of them at once. */
3039
3040void
f2206911
KC
3041frv_init_cumulative_args (CUMULATIVE_ARGS *cum,
3042 tree fntype,
3043 rtx libname,
3044 tree fndecl,
3045 int incoming)
36a05131
BS
3046{
3047 *cum = FIRST_ARG_REGNUM;
3048
3049 if (TARGET_DEBUG_ARG)
3050 {
3051 fprintf (stderr, "\ninit_cumulative_args:");
563a317a 3052 if (!fndecl && fntype)
36a05131
BS
3053 fputs (" indirect", stderr);
3054
3055 if (incoming)
3056 fputs (" incoming", stderr);
3057
3058 if (fntype)
3059 {
3060 tree ret_type = TREE_TYPE (fntype);
3061 fprintf (stderr, " return=%s,",
8ad8afaf 3062 get_tree_code_name (TREE_CODE (ret_type)));
36a05131
BS
3063 }
3064
3065 if (libname && GET_CODE (libname) == SYMBOL_REF)
3066 fprintf (stderr, " libname=%s", XSTR (libname, 0));
3067
3068 if (cfun->returns_struct)
3069 fprintf (stderr, " return-struct");
3070
3071 putc ('\n', stderr);
3072 }
3073}
3074
3075\f
fe984136
RH
3076/* Return true if we should pass an argument on the stack rather than
3077 in registers. */
3078
3079static bool
0ffef200 3080frv_must_pass_in_stack (const function_arg_info &arg)
fe984136 3081{
0ffef200 3082 return arg.mode == BLKmode || arg.aggregate_type_p ();
fe984136
RH
3083}
3084
36a05131
BS
3085/* If defined, a C expression that gives the alignment boundary, in bits, of an
3086 argument with the specified mode and type. If it is not defined,
3087 `PARM_BOUNDARY' is used for all arguments. */
3088
c2ed6cf8 3089static unsigned int
ef4bddc2 3090frv_function_arg_boundary (machine_mode mode ATTRIBUTE_UNUSED,
c2ed6cf8 3091 const_tree type ATTRIBUTE_UNUSED)
36a05131
BS
3092{
3093 return BITS_PER_WORD;
3094}
3095
88a1f47f 3096static rtx
6783fdb7 3097frv_function_arg_1 (cumulative_args_t cum_v, const function_arg_info &arg,
88a1f47f 3098 bool incoming ATTRIBUTE_UNUSED)
36a05131 3099{
d5cc9181
JR
3100 const CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
3101
6783fdb7 3102 machine_mode xmode = (arg.mode == BLKmode) ? SImode : arg.mode;
36a05131
BS
3103 int arg_num = *cum;
3104 rtx ret;
3105 const char *debstr;
3106
3107 /* Return a marker for use in the call instruction. */
3108 if (xmode == VOIDmode)
3109 {
3110 ret = const0_rtx;
3111 debstr = "<0>";
3112 }
3113
3114 else if (arg_num <= LAST_ARG_REGNUM)
3115 {
f1c25d3b 3116 ret = gen_rtx_REG (xmode, arg_num);
36a05131
BS
3117 debstr = reg_names[arg_num];
3118 }
3119
3120 else
3121 {
3122 ret = NULL_RTX;
3123 debstr = "memory";
3124 }
3125
3126 if (TARGET_DEBUG_ARG)
3127 fprintf (stderr,
3128 "function_arg: words = %2d, mode = %4s, named = %d, size = %3d, arg = %s\n",
6783fdb7
RS
3129 arg_num, GET_MODE_NAME (arg.mode), arg.named,
3130 GET_MODE_SIZE (arg.mode), debstr);
36a05131
BS
3131
3132 return ret;
3133}
3134
88a1f47f 3135static rtx
6783fdb7 3136frv_function_arg (cumulative_args_t cum, const function_arg_info &arg)
88a1f47f 3137{
6783fdb7 3138 return frv_function_arg_1 (cum, arg, false);
88a1f47f
NF
3139}
3140
3141static rtx
6783fdb7 3142frv_function_incoming_arg (cumulative_args_t cum, const function_arg_info &arg)
88a1f47f 3143{
6783fdb7 3144 return frv_function_arg_1 (cum, arg, true);
88a1f47f
NF
3145}
3146
36a05131 3147\f
6930c98c 3148/* Implement TARGET_FUNCTION_ARG_ADVANCE. */
36a05131 3149
88a1f47f 3150static void
d5cc9181 3151frv_function_arg_advance (cumulative_args_t cum_v,
6930c98c 3152 const function_arg_info &arg)
36a05131 3153{
d5cc9181
JR
3154 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
3155
6930c98c 3156 machine_mode xmode = (arg.mode == BLKmode) ? SImode : arg.mode;
36a05131
BS
3157 int bytes = GET_MODE_SIZE (xmode);
3158 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
3159 int arg_num = *cum;
3160
3161 *cum = arg_num + words;
3162
3163 if (TARGET_DEBUG_ARG)
3164 fprintf (stderr,
3165 "function_adv: words = %2d, mode = %4s, named = %d, size = %3d\n",
6930c98c
RS
3166 arg_num, GET_MODE_NAME (arg.mode), arg.named,
3167 words * UNITS_PER_WORD);
36a05131
BS
3168}
3169
3170\f
a7c81bc1 3171/* Implement TARGET_ARG_PARTIAL_BYTES. */
36a05131 3172
78a52f11 3173static int
a7c81bc1 3174frv_arg_partial_bytes (cumulative_args_t cum, const function_arg_info &arg)
36a05131 3175{
a7c81bc1 3176 machine_mode xmode = (arg.mode == BLKmode) ? SImode : arg.mode;
36a05131
BS
3177 int bytes = GET_MODE_SIZE (xmode);
3178 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
d5cc9181 3179 int arg_num = *get_cumulative_args (cum);
36a05131
BS
3180 int ret;
3181
3182 ret = ((arg_num <= LAST_ARG_REGNUM && arg_num + words > LAST_ARG_REGNUM+1)
3183 ? LAST_ARG_REGNUM - arg_num + 1
3184 : 0);
78a52f11 3185 ret *= UNITS_PER_WORD;
36a05131
BS
3186
3187 if (TARGET_DEBUG_ARG && ret)
78a52f11 3188 fprintf (stderr, "frv_arg_partial_bytes: %d\n", ret);
36a05131
BS
3189
3190 return ret;
36a05131
BS
3191}
3192
219d92a4
AS
3193\f
3194/* Implements TARGET_FUNCTION_VALUE. */
3195
3196static rtx
3197frv_function_value (const_tree valtype,
3198 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
3199 bool outgoing ATTRIBUTE_UNUSED)
3200{
3201 return gen_rtx_REG (TYPE_MODE (valtype), RETURN_VALUE_REGNUM);
3202}
3203
3204\f
3205/* Implements TARGET_LIBCALL_VALUE. */
3206
3207static rtx
ef4bddc2 3208frv_libcall_value (machine_mode mode,
219d92a4
AS
3209 const_rtx fun ATTRIBUTE_UNUSED)
3210{
3211 return gen_rtx_REG (mode, RETURN_VALUE_REGNUM);
3212}
3213
3214\f
3215/* Implements FUNCTION_VALUE_REGNO_P. */
3216
3217bool
3218frv_function_value_regno_p (const unsigned int regno)
3219{
3220 return (regno == RETURN_VALUE_REGNUM);
3221}
36a05131
BS
3222\f
3223/* Return true if a register is ok to use as a base or index register. */
3224
3225static FRV_INLINE int
f2206911 3226frv_regno_ok_for_base_p (int regno, int strict_p)
36a05131
BS
3227{
3228 if (GPR_P (regno))
3229 return TRUE;
3230
3231 if (strict_p)
3232 return (reg_renumber[regno] >= 0 && GPR_P (reg_renumber[regno]));
3233
3234 if (regno == ARG_POINTER_REGNUM)
3235 return TRUE;
3236
3237 return (regno >= FIRST_PSEUDO_REGISTER);
3238}
3239
3240\f
3241/* A C compound statement with a conditional `goto LABEL;' executed if X (an
3242 RTX) is a legitimate memory address on the target machine for a memory
3243 operand of mode MODE.
3244
3245 It usually pays to define several simpler macros to serve as subroutines for
3246 this one. Otherwise it may be too complicated to understand.
3247
3248 This macro must exist in two variants: a strict variant and a non-strict
3249 one. The strict variant is used in the reload pass. It must be defined so
3250 that any pseudo-register that has not been allocated a hard register is
3251 considered a memory reference. In contexts where some kind of register is
3252 required, a pseudo-register with no hard register must be rejected.
3253
3254 The non-strict variant is used in other passes. It must be defined to
3255 accept all pseudo-registers in every context where some kind of register is
3256 required.
3257
3258 Compiler source files that want to use the strict variant of this macro
3259 define the macro `REG_OK_STRICT'. You should use an `#ifdef REG_OK_STRICT'
3260 conditional to define the strict variant in that case and the non-strict
3261 variant otherwise.
3262
36a05131
BS
3263 Normally, constant addresses which are the sum of a `symbol_ref' and an
3264 integer are stored inside a `const' RTX to mark them as constant.
3265 Therefore, there is no need to recognize such sums specifically as
3266 legitimate addresses. Normally you would simply recognize any `const' as
3267 legitimate.
3268
0fb30cb7
NF
3269 Usually `TARGET_PRINT_OPERAND_ADDRESS' is not prepared to handle
3270 constant sums that are not marked with `const'. It assumes that a
3271 naked `plus' indicates indexing. If so, then you *must* reject such
3272 naked constant sums as illegitimate addresses, so that none of them
3273 will be given to `TARGET_PRINT_OPERAND_ADDRESS'. */
36a05131
BS
3274
3275int
ef4bddc2 3276frv_legitimate_address_p_1 (machine_mode mode,
c6c3dba9
PB
3277 rtx x,
3278 int strict_p,
3279 int condexec_p,
3280 int allow_double_reg_p)
36a05131
BS
3281{
3282 rtx x0, x1;
3283 int ret = 0;
3284 HOST_WIDE_INT value;
3285 unsigned regno0;
3286
bef8809e
AH
3287 if (FRV_SYMBOL_REF_TLS_P (x))
3288 return 0;
3289
36a05131
BS
3290 switch (GET_CODE (x))
3291 {
3292 default:
3293 break;
3294
3295 case SUBREG:
3296 x = SUBREG_REG (x);
3297 if (GET_CODE (x) != REG)
3298 break;
3299
87b483a1 3300 /* Fall through. */
36a05131
BS
3301
3302 case REG:
3303 ret = frv_regno_ok_for_base_p (REGNO (x), strict_p);
3304 break;
3305
3306 case PRE_MODIFY:
3307 x0 = XEXP (x, 0);
3308 x1 = XEXP (x, 1);
3309 if (GET_CODE (x0) != REG
3310 || ! frv_regno_ok_for_base_p (REGNO (x0), strict_p)
3311 || GET_CODE (x1) != PLUS
3312 || ! rtx_equal_p (x0, XEXP (x1, 0))
3313 || GET_CODE (XEXP (x1, 1)) != REG
3314 || ! frv_regno_ok_for_base_p (REGNO (XEXP (x1, 1)), strict_p))
3315 break;
3316
3317 ret = 1;
3318 break;
3319
3320 case CONST_INT:
2300b9dd 3321 /* 12-bit immediate */
36a05131
BS
3322 if (condexec_p)
3323 ret = FALSE;
3324 else
3325 {
2f5b1308 3326 ret = IN_RANGE (INTVAL (x), -2048, 2047);
36a05131
BS
3327
3328 /* If we can't use load/store double operations, make sure we can
3329 address the second word. */
3330 if (ret && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
2f5b1308
JR
3331 ret = IN_RANGE (INTVAL (x) + GET_MODE_SIZE (mode) - 1,
3332 -2048, 2047);
36a05131
BS
3333 }
3334 break;
3335
3336 case PLUS:
3337 x0 = XEXP (x, 0);
3338 x1 = XEXP (x, 1);
3339
3340 if (GET_CODE (x0) == SUBREG)
3341 x0 = SUBREG_REG (x0);
3342
3343 if (GET_CODE (x0) != REG)
3344 break;
3345
3346 regno0 = REGNO (x0);
3347 if (!frv_regno_ok_for_base_p (regno0, strict_p))
3348 break;
3349
3350 switch (GET_CODE (x1))
3351 {
3352 default:
3353 break;
3354
3355 case SUBREG:
3356 x1 = SUBREG_REG (x1);
3357 if (GET_CODE (x1) != REG)
3358 break;
3359
87b483a1 3360 /* Fall through. */
36a05131
BS
3361
3362 case REG:
87b483a1
KH
3363 /* Do not allow reg+reg addressing for modes > 1 word if we
3364 can't depend on having move double instructions. */
34208acf 3365 if (!allow_double_reg_p && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
36a05131
BS
3366 ret = FALSE;
3367 else
3368 ret = frv_regno_ok_for_base_p (REGNO (x1), strict_p);
3369 break;
3370
3371 case CONST_INT:
2300b9dd 3372 /* 12-bit immediate */
36a05131
BS
3373 if (condexec_p)
3374 ret = FALSE;
3375 else
3376 {
3377 value = INTVAL (x1);
2f5b1308 3378 ret = IN_RANGE (value, -2048, 2047);
36a05131
BS
3379
3380 /* If we can't use load/store double operations, make sure we can
3381 address the second word. */
3382 if (ret && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
2f5b1308 3383 ret = IN_RANGE (value + GET_MODE_SIZE (mode) - 1, -2048, 2047);
36a05131
BS
3384 }
3385 break;
3386
36a05131 3387 case CONST:
34208acf 3388 if (!condexec_p && got12_operand (x1, VOIDmode))
36a05131
BS
3389 ret = TRUE;
3390 break;
3391
3392 }
3393 break;
3394 }
3395
3396 if (TARGET_DEBUG_ADDR)
3397 {
331d9186 3398 fprintf (stderr, "\n========== legitimate_address_p, mode = %s, result = %d, addresses are %sstrict%s\n",
36a05131
BS
3399 GET_MODE_NAME (mode), ret, (strict_p) ? "" : "not ",
3400 (condexec_p) ? ", inside conditional code" : "");
3401 debug_rtx (x);
3402 }
3403
3404 return ret;
3405}
3406
c6c3dba9 3407bool
ef4bddc2 3408frv_legitimate_address_p (machine_mode mode, rtx x, bool strict_p)
c6c3dba9
PB
3409{
3410 return frv_legitimate_address_p_1 (mode, x, strict_p, FALSE, FALSE);
3411}
3412
bef8809e
AH
3413/* Given an ADDR, generate code to inline the PLT. */
3414static rtx
3415gen_inlined_tls_plt (rtx addr)
3416{
fdbe66f2 3417 rtx retval, dest;
bef8809e
AH
3418 rtx picreg = get_hard_reg_initial_val (Pmode, FDPIC_REG);
3419
3420
3421 dest = gen_reg_rtx (DImode);
3422
3423 if (flag_pic == 1)
3424 {
3425 /*
3426 -fpic version:
3427
3428 lddi.p @(gr15, #gottlsdesc12(ADDR)), gr8
3429 calll #gettlsoff(ADDR)@(gr8, gr0)
3430 */
3431 emit_insn (gen_tls_lddi (dest, addr, picreg));
3432 }
3433 else
3434 {
3435 /*
3436 -fPIC version:
3437
3438 sethi.p #gottlsdeschi(ADDR), gr8
3439 setlo #gottlsdesclo(ADDR), gr8
3440 ldd #tlsdesc(ADDR)@(gr15, gr8), gr8
3441 calll #gettlsoff(ADDR)@(gr8, gr0)
3442 */
3443 rtx reguse = gen_reg_rtx (Pmode);
3444 emit_insn (gen_tlsoff_hilo (reguse, addr, GEN_INT (R_FRV_GOTTLSDESCHI)));
3445 emit_insn (gen_tls_tlsdesc_ldd (dest, picreg, reguse, addr));
3446 }
3447
3448 retval = gen_reg_rtx (Pmode);
a701780f 3449 emit_insn (gen_tls_indirect_call (retval, addr, dest, picreg));
bef8809e
AH
3450 return retval;
3451}
3452
3453/* Emit a TLSMOFF or TLSMOFF12 offset, depending on -mTLS. Returns
3454 the destination address. */
3455static rtx
3456gen_tlsmoff (rtx addr, rtx reg)
3457{
3458 rtx dest = gen_reg_rtx (Pmode);
3459
3460 if (TARGET_BIG_TLS)
3461 {
3462 /* sethi.p #tlsmoffhi(x), grA
3463 setlo #tlsmofflo(x), grA
3464 */
3465 dest = gen_reg_rtx (Pmode);
3466 emit_insn (gen_tlsoff_hilo (dest, addr,
3467 GEN_INT (R_FRV_TLSMOFFHI)));
3468 dest = gen_rtx_PLUS (Pmode, dest, reg);
3469 }
3470 else
3471 {
3472 /* addi grB, #tlsmoff12(x), grC
3473 -or-
3474 ld/st @(grB, #tlsmoff12(x)), grC
3475 */
3476 dest = gen_reg_rtx (Pmode);
3477 emit_insn (gen_symGOTOFF2reg_i (dest, addr, reg,
3478 GEN_INT (R_FRV_TLSMOFF12)));
3479 }
3480 return dest;
3481}
3482
3483/* Generate code for a TLS address. */
3484static rtx
3485frv_legitimize_tls_address (rtx addr, enum tls_model model)
3486{
3487 rtx dest, tp = gen_rtx_REG (Pmode, 29);
3488 rtx picreg = get_hard_reg_initial_val (Pmode, 15);
3489
3490 switch (model)
3491 {
3492 case TLS_MODEL_INITIAL_EXEC:
3493 if (flag_pic == 1)
3494 {
3495 /* -fpic version.
3496 ldi @(gr15, #gottlsoff12(x)), gr5
3497 */
3498 dest = gen_reg_rtx (Pmode);
3499 emit_insn (gen_tls_load_gottlsoff12 (dest, addr, picreg));
3500 dest = gen_rtx_PLUS (Pmode, tp, dest);
3501 }
3502 else
3503 {
3504 /* -fPIC or anything else.
3505
3506 sethi.p #gottlsoffhi(x), gr14
3507 setlo #gottlsofflo(x), gr14
3508 ld #tlsoff(x)@(gr15, gr14), gr9
3509 */
3510 rtx tmp = gen_reg_rtx (Pmode);
3511 dest = gen_reg_rtx (Pmode);
3512 emit_insn (gen_tlsoff_hilo (tmp, addr,
3513 GEN_INT (R_FRV_GOTTLSOFF_HI)));
3514
3515 emit_insn (gen_tls_tlsoff_ld (dest, picreg, tmp, addr));
3516 dest = gen_rtx_PLUS (Pmode, tp, dest);
3517 }
3518 break;
3519 case TLS_MODEL_LOCAL_DYNAMIC:
3520 {
3521 rtx reg, retval;
3522
3523 if (TARGET_INLINE_PLT)
3524 retval = gen_inlined_tls_plt (GEN_INT (0));
3525 else
3526 {
3527 /* call #gettlsoff(0) */
3528 retval = gen_reg_rtx (Pmode);
3529 emit_insn (gen_call_gettlsoff (retval, GEN_INT (0), picreg));
3530 }
3531
3532 reg = gen_reg_rtx (Pmode);
f7df4a84 3533 emit_insn (gen_rtx_SET (reg, gen_rtx_PLUS (Pmode, retval, tp)));
bef8809e
AH
3534
3535 dest = gen_tlsmoff (addr, reg);
3536
3537 /*
3538 dest = gen_reg_rtx (Pmode);
3539 emit_insn (gen_tlsoff_hilo (dest, addr,
3540 GEN_INT (R_FRV_TLSMOFFHI)));
3541 dest = gen_rtx_PLUS (Pmode, dest, reg);
3542 */
3543 break;
3544 }
3545 case TLS_MODEL_LOCAL_EXEC:
3546 dest = gen_tlsmoff (addr, gen_rtx_REG (Pmode, 29));
3547 break;
3548 case TLS_MODEL_GLOBAL_DYNAMIC:
3549 {
3550 rtx retval;
3551
3552 if (TARGET_INLINE_PLT)
3553 retval = gen_inlined_tls_plt (addr);
3554 else
3555 {
3556 /* call #gettlsoff(x) */
3557 retval = gen_reg_rtx (Pmode);
3558 emit_insn (gen_call_gettlsoff (retval, addr, picreg));
3559 }
3560 dest = gen_rtx_PLUS (Pmode, retval, tp);
3561 break;
3562 }
3563 default:
44e91694 3564 gcc_unreachable ();
bef8809e
AH
3565 }
3566
3567 return dest;
3568}
3569
2a2e3f05 3570rtx
bef8809e 3571frv_legitimize_address (rtx x,
2a2e3f05 3572 rtx oldx ATTRIBUTE_UNUSED,
ef4bddc2 3573 machine_mode mode ATTRIBUTE_UNUSED)
2a2e3f05 3574{
bef8809e
AH
3575 if (GET_CODE (x) == SYMBOL_REF)
3576 {
3577 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
3578 if (model != 0)
3579 return frv_legitimize_tls_address (x, model);
3580 }
3581
506d7b68 3582 return x;
2a2e3f05 3583}
36a05131 3584\f
34208acf
AO
3585/* Test whether a local function descriptor is canonical, i.e.,
3586 whether we can use FUNCDESC_GOTOFF to compute the address of the
3587 function. */
3588
3589static bool
3590frv_local_funcdesc_p (rtx fnx)
3591{
3592 tree fn;
3593 enum symbol_visibility vis;
3594 bool ret;
36a05131 3595
34208acf
AO
3596 if (! SYMBOL_REF_LOCAL_P (fnx))
3597 return FALSE;
3598
3599 fn = SYMBOL_REF_DECL (fnx);
3600
3601 if (! fn)
3602 return FALSE;
36a05131 3603
34208acf 3604 vis = DECL_VISIBILITY (fn);
36a05131 3605
34208acf
AO
3606 if (vis == VISIBILITY_PROTECTED)
3607 /* Private function descriptors for protected functions are not
3608 canonical. Temporarily change the visibility to global. */
3609 vis = VISIBILITY_DEFAULT;
3610 else if (flag_shlib)
3611 /* If we're already compiling for a shared library (that, unlike
3612 executables, can't assume that the existence of a definition
3613 implies local binding), we can skip the re-testing. */
3614 return TRUE;
36a05131 3615
34208acf 3616 ret = default_binds_local_p_1 (fn, flag_pic);
36a05131 3617
34208acf
AO
3618 DECL_VISIBILITY (fn) = vis;
3619
3620 return ret;
3621}
3622
3623/* Load the _gp symbol into DEST. SRC is supposed to be the FDPIC
3624 register. */
36a05131
BS
3625
3626rtx
34208acf
AO
3627frv_gen_GPsym2reg (rtx dest, rtx src)
3628{
3629 tree gp = get_identifier ("_gp");
3630 rtx gp_sym = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (gp));
36a05131 3631
34208acf
AO
3632 return gen_symGOT2reg (dest, gp_sym, src, GEN_INT (R_FRV_GOT12));
3633}
3634
3635static const char *
3636unspec_got_name (int i)
3637{
3638 switch (i)
36a05131 3639 {
34208acf
AO
3640 case R_FRV_GOT12: return "got12";
3641 case R_FRV_GOTHI: return "gothi";
3642 case R_FRV_GOTLO: return "gotlo";
3643 case R_FRV_FUNCDESC: return "funcdesc";
3644 case R_FRV_FUNCDESC_GOT12: return "gotfuncdesc12";
3645 case R_FRV_FUNCDESC_GOTHI: return "gotfuncdeschi";
3646 case R_FRV_FUNCDESC_GOTLO: return "gotfuncdesclo";
3647 case R_FRV_FUNCDESC_VALUE: return "funcdescvalue";
3648 case R_FRV_FUNCDESC_GOTOFF12: return "gotofffuncdesc12";
3649 case R_FRV_FUNCDESC_GOTOFFHI: return "gotofffuncdeschi";
3650 case R_FRV_FUNCDESC_GOTOFFLO: return "gotofffuncdesclo";
3651 case R_FRV_GOTOFF12: return "gotoff12";
3652 case R_FRV_GOTOFFHI: return "gotoffhi";
3653 case R_FRV_GOTOFFLO: return "gotofflo";
3654 case R_FRV_GPREL12: return "gprel12";
3655 case R_FRV_GPRELHI: return "gprelhi";
3656 case R_FRV_GPRELLO: return "gprello";
bef8809e
AH
3657 case R_FRV_GOTTLSOFF_HI: return "gottlsoffhi";
3658 case R_FRV_GOTTLSOFF_LO: return "gottlsofflo";
3659 case R_FRV_TLSMOFFHI: return "tlsmoffhi";
3660 case R_FRV_TLSMOFFLO: return "tlsmofflo";
3661 case R_FRV_TLSMOFF12: return "tlsmoff12";
3662 case R_FRV_TLSDESCHI: return "tlsdeschi";
3663 case R_FRV_TLSDESCLO: return "tlsdesclo";
3664 case R_FRV_GOTTLSDESCHI: return "gottlsdeschi";
3665 case R_FRV_GOTTLSDESCLO: return "gottlsdesclo";
44e91694 3666 default: gcc_unreachable ();
36a05131 3667 }
34208acf 3668}
36a05131 3669
34208acf
AO
3670/* Write the assembler syntax for UNSPEC to STREAM. Note that any offset
3671 is added inside the relocation operator. */
3672
3673static void
3674frv_output_const_unspec (FILE *stream, const struct frv_unspec *unspec)
3675{
3676 fprintf (stream, "#%s(", unspec_got_name (unspec->reloc));
0a81f074
RS
3677 output_addr_const (stream, plus_constant (Pmode, unspec->symbol,
3678 unspec->offset));
34208acf
AO
3679 fputs (")", stream);
3680}
3681
3682/* Implement FIND_BASE_TERM. See whether ORIG_X represents #gprel12(foo)
3683 or #gotoff12(foo) for some small data symbol foo. If so, return foo,
3684 otherwise return ORIG_X. */
3685
3686rtx
3687frv_find_base_term (rtx x)
3688{
3689 struct frv_unspec unspec;
3690
3691 if (frv_const_unspec_p (x, &unspec)
3692 && frv_small_data_reloc_p (unspec.symbol, unspec.reloc))
0a81f074 3693 return plus_constant (Pmode, unspec.symbol, unspec.offset);
34208acf
AO
3694
3695 return x;
36a05131
BS
3696}
3697
3698/* Return 1 if operand is a valid FRV address. CONDEXEC_P is true if
3699 the operand is used by a predicated instruction. */
3700
6d26dc3b 3701int
ef4bddc2 3702frv_legitimate_memory_operand (rtx op, machine_mode mode, int condexec_p)
36a05131
BS
3703{
3704 return ((GET_MODE (op) == mode || mode == VOIDmode)
3705 && GET_CODE (op) == MEM
c6c3dba9
PB
3706 && frv_legitimate_address_p_1 (mode, XEXP (op, 0),
3707 reload_completed, condexec_p, FALSE));
34208acf
AO
3708}
3709
3710void
764678d1 3711frv_expand_fdpic_call (rtx *operands, bool ret_value, bool sibcall)
34208acf
AO
3712{
3713 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
3714 rtx picreg = get_hard_reg_initial_val (SImode, FDPIC_REG);
3715 rtx c, rvrtx=0;
3716 rtx addr;
3717
3718 if (ret_value)
3719 {
3720 rvrtx = operands[0];
3721 operands ++;
3722 }
3723
3724 addr = XEXP (operands[0], 0);
3725
3726 /* Inline PLTs if we're optimizing for speed. We'd like to inline
3727 any calls that would involve a PLT, but can't tell, since we
3728 don't know whether an extern function is going to be provided by
3729 a separate translation unit or imported from a separate module.
3730 When compiling for shared libraries, if the function has default
3731 visibility, we assume it's overridable, so we inline the PLT, but
3732 for executables, we don't really have a way to make a good
3733 decision: a function is as likely to be imported from a shared
3734 library as it is to be defined in the executable itself. We
3735 assume executables will get global functions defined locally,
3736 whereas shared libraries will have them potentially overridden,
3737 so we only inline PLTs when compiling for shared libraries.
3738
3739 In order to mark a function as local to a shared library, any
3740 non-default visibility attribute suffices. Unfortunately,
3741 there's no simple way to tag a function declaration as ``in a
3742 different module'', which we could then use to trigger PLT
3743 inlining on executables. There's -minline-plt, but it affects
3744 all external functions, so one would have to also mark function
3745 declarations available in the same module with non-default
3746 visibility, which is advantageous in itself. */
764678d1
AO
3747 if (GET_CODE (addr) == SYMBOL_REF
3748 && ((!SYMBOL_REF_LOCAL_P (addr) && TARGET_INLINE_PLT)
3749 || sibcall))
34208acf
AO
3750 {
3751 rtx x, dest;
3752 dest = gen_reg_rtx (SImode);
3753 if (flag_pic != 1)
3754 x = gen_symGOTOFF2reg_hilo (dest, addr, OUR_FDPIC_REG,
3755 GEN_INT (R_FRV_FUNCDESC_GOTOFF12));
3756 else
3757 x = gen_symGOTOFF2reg (dest, addr, OUR_FDPIC_REG,
3758 GEN_INT (R_FRV_FUNCDESC_GOTOFF12));
3759 emit_insn (x);
ad516a74 3760 crtl->uses_pic_offset_table = TRUE;
34208acf 3761 addr = dest;
2396bce1 3762 }
34208acf
AO
3763 else if (GET_CODE (addr) == SYMBOL_REF)
3764 {
3765 /* These are always either local, or handled through a local
3766 PLT. */
3767 if (ret_value)
3768 c = gen_call_value_fdpicsi (rvrtx, addr, operands[1],
3769 operands[2], picreg, lr);
3770 else
3771 c = gen_call_fdpicsi (addr, operands[1], operands[2], picreg, lr);
3772 emit_call_insn (c);
3773 return;
3774 }
3775 else if (! ldd_address_operand (addr, Pmode))
3776 addr = force_reg (Pmode, addr);
3777
3778 picreg = gen_reg_rtx (DImode);
3779 emit_insn (gen_movdi_ldd (picreg, addr));
3780
764678d1
AO
3781 if (sibcall && ret_value)
3782 c = gen_sibcall_value_fdpicdi (rvrtx, picreg, const0_rtx);
3783 else if (sibcall)
3784 c = gen_sibcall_fdpicdi (picreg, const0_rtx);
3785 else if (ret_value)
34208acf
AO
3786 c = gen_call_value_fdpicdi (rvrtx, picreg, const0_rtx, lr);
3787 else
3788 c = gen_call_fdpicdi (picreg, const0_rtx, lr);
3789 emit_call_insn (c);
36a05131 3790}
36a05131 3791\f
6d26dc3b
KH
3792/* Look for a SYMBOL_REF of a function in an rtx. We always want to
3793 process these separately from any offsets, such that we add any
3794 offsets to the function descriptor (the actual pointer), not to the
3795 function address. */
36a05131 3796
6d26dc3b
KH
3797static bool
3798frv_function_symbol_referenced_p (rtx x)
36a05131 3799{
6d26dc3b
KH
3800 const char *format;
3801 int length;
3802 int j;
36a05131 3803
6d26dc3b
KH
3804 if (GET_CODE (x) == SYMBOL_REF)
3805 return SYMBOL_REF_FUNCTION_P (x);
34208acf 3806
6d26dc3b
KH
3807 length = GET_RTX_LENGTH (GET_CODE (x));
3808 format = GET_RTX_FORMAT (GET_CODE (x));
36a05131 3809
6d26dc3b 3810 for (j = 0; j < length; ++j)
36a05131 3811 {
6d26dc3b
KH
3812 switch (format[j])
3813 {
3814 case 'e':
3815 if (frv_function_symbol_referenced_p (XEXP (x, j)))
3816 return TRUE;
3817 break;
36a05131 3818
6d26dc3b
KH
3819 case 'V':
3820 case 'E':
3821 if (XVEC (x, j) != 0)
3822 {
3823 int k;
3824 for (k = 0; k < XVECLEN (x, j); ++k)
3825 if (frv_function_symbol_referenced_p (XVECEXP (x, j, k)))
3826 return TRUE;
3827 }
3828 break;
36a05131 3829
6d26dc3b
KH
3830 default:
3831 /* Nothing to do. */
3832 break;
3833 }
36a05131
BS
3834 }
3835
36a05131
BS
3836 return FALSE;
3837}
3838
6d26dc3b
KH
3839/* Return true if the memory operand is one that can be conditionally
3840 executed. */
36a05131 3841
f2206911 3842int
ef4bddc2 3843condexec_memory_operand (rtx op, machine_mode mode)
36a05131 3844{
ef4bddc2 3845 machine_mode op_mode = GET_MODE (op);
6d26dc3b 3846 rtx addr;
36a05131 3847
6d26dc3b 3848 if (mode != VOIDmode && op_mode != mode)
36a05131
BS
3849 return FALSE;
3850
6d26dc3b 3851 switch (op_mode)
36a05131
BS
3852 {
3853 default:
6d26dc3b 3854 return FALSE;
36a05131 3855
4e10a5a7
RS
3856 case E_QImode:
3857 case E_HImode:
3858 case E_SImode:
3859 case E_SFmode:
36a05131
BS
3860 break;
3861 }
3862
6d26dc3b 3863 if (GET_CODE (op) != MEM)
36a05131
BS
3864 return FALSE;
3865
6d26dc3b 3866 addr = XEXP (op, 0);
c6c3dba9 3867 return frv_legitimate_address_p_1 (mode, addr, reload_completed, TRUE, FALSE);
36a05131 3868}
36a05131
BS
3869\f
3870/* Return true if the bare return instruction can be used outside of the
3871 epilog code. For frv, we only do it if there was no stack allocation. */
3872
3873int
f2206911 3874direct_return_p (void)
36a05131
BS
3875{
3876 frv_stack_t *info;
3877
3878 if (!reload_completed)
3879 return FALSE;
3880
3881 info = frv_stack_info ();
3882 return (info->total_size == 0);
3883}
3884
3885\f
2a2e3f05 3886void
ef4bddc2 3887frv_emit_move (machine_mode mode, rtx dest, rtx src)
2a2e3f05 3888{
bef8809e
AH
3889 if (GET_CODE (src) == SYMBOL_REF)
3890 {
3891 enum tls_model model = SYMBOL_REF_TLS_MODEL (src);
3892 if (model != 0)
3893 src = frv_legitimize_tls_address (src, model);
3894 }
3895
2a2e3f05
AH
3896 switch (mode)
3897 {
4e10a5a7 3898 case E_SImode:
2a2e3f05
AH
3899 if (frv_emit_movsi (dest, src))
3900 return;
3901 break;
3902
4e10a5a7
RS
3903 case E_QImode:
3904 case E_HImode:
3905 case E_DImode:
3906 case E_SFmode:
3907 case E_DFmode:
2a2e3f05
AH
3908 if (!reload_in_progress
3909 && !reload_completed
3910 && !register_operand (dest, mode)
3911 && !reg_or_0_operand (src, mode))
3912 src = copy_to_mode_reg (mode, src);
3913 break;
3914
3915 default:
44e91694 3916 gcc_unreachable ();
2a2e3f05
AH
3917 }
3918
f7df4a84 3919 emit_insn (gen_rtx_SET (dest, src));
2a2e3f05
AH
3920}
3921
36a05131
BS
3922/* Emit code to handle a MOVSI, adding in the small data register or pic
3923 register if needed to load up addresses. Return TRUE if the appropriate
3924 instructions are emitted. */
3925
3926int
f2206911 3927frv_emit_movsi (rtx dest, rtx src)
36a05131
BS
3928{
3929 int base_regno = -1;
34208acf
AO
3930 int unspec = 0;
3931 rtx sym = src;
3932 struct frv_unspec old_unspec;
36a05131
BS
3933
3934 if (!reload_in_progress
3935 && !reload_completed
3936 && !register_operand (dest, SImode)
3937 && (!reg_or_0_operand (src, SImode)
3938 /* Virtual registers will almost always be replaced by an
3939 add instruction, so expose this to CSE by copying to
87b483a1 3940 an intermediate register. */
36a05131 3941 || (GET_CODE (src) == REG
2f5b1308
JR
3942 && IN_RANGE (REGNO (src),
3943 FIRST_VIRTUAL_REGISTER,
3944 LAST_VIRTUAL_POINTER_REGISTER))))
36a05131 3945 {
f7df4a84 3946 emit_insn (gen_rtx_SET (dest, copy_to_mode_reg (SImode, src)));
36a05131
BS
3947 return TRUE;
3948 }
3949
3950 /* Explicitly add in the PIC or small data register if needed. */
3951 switch (GET_CODE (src))
3952 {
3953 default:
3954 break;
3955
3956 case LABEL_REF:
34208acf
AO
3957 handle_label:
3958 if (TARGET_FDPIC)
3959 {
3960 /* Using GPREL12, we use a single GOT entry for all symbols
3961 in read-only sections, but trade sequences such as:
3962
3963 sethi #gothi(label), gr#
3964 setlo #gotlo(label), gr#
3965 ld @(gr15,gr#), gr#
3966
3967 for
3968
3969 ld @(gr15,#got12(_gp)), gr#
3970 sethi #gprelhi(label), gr##
3971 setlo #gprello(label), gr##
3972 add gr#, gr##, gr##
3973
3974 We may often be able to share gr# for multiple
3975 computations of GPREL addresses, and we may often fold
3976 the final add into the pair of registers of a load or
3977 store instruction, so it's often profitable. Even when
3978 optimizing for size, we're trading a GOT entry for an
3979 additional instruction, which trades GOT space
3980 (read-write) for code size (read-only, shareable), as
3981 long as the symbol is not used in more than two different
3982 locations.
2396bce1 3983
34208acf
AO
3984 With -fpie/-fpic, we'd be trading a single load for a
3985 sequence of 4 instructions, because the offset of the
4ee31f1e 3986 label can't be assumed to be addressable with 12 bits, so
34208acf
AO
3987 we don't do this. */
3988 if (TARGET_GPREL_RO)
3989 unspec = R_FRV_GPREL12;
3990 else
3991 unspec = R_FRV_GOT12;
3992 }
3993 else if (flag_pic)
36a05131
BS
3994 base_regno = PIC_REGNO;
3995
3996 break;
3997
3998 case CONST:
34208acf
AO
3999 if (frv_const_unspec_p (src, &old_unspec))
4000 break;
36a05131 4001
34208acf
AO
4002 if (TARGET_FDPIC && frv_function_symbol_referenced_p (XEXP (src, 0)))
4003 {
4004 handle_whatever:
4005 src = force_reg (GET_MODE (XEXP (src, 0)), XEXP (src, 0));
4006 emit_move_insn (dest, src);
4007 return TRUE;
4008 }
4009 else
4010 {
4011 sym = XEXP (sym, 0);
4012 if (GET_CODE (sym) == PLUS
4013 && GET_CODE (XEXP (sym, 0)) == SYMBOL_REF
4014 && GET_CODE (XEXP (sym, 1)) == CONST_INT)
4015 sym = XEXP (sym, 0);
4016 if (GET_CODE (sym) == SYMBOL_REF)
4017 goto handle_sym;
4018 else if (GET_CODE (sym) == LABEL_REF)
4019 goto handle_label;
4020 else
4021 goto handle_whatever;
4022 }
36a05131
BS
4023 break;
4024
4025 case SYMBOL_REF:
34208acf
AO
4026 handle_sym:
4027 if (TARGET_FDPIC)
4028 {
bef8809e
AH
4029 enum tls_model model = SYMBOL_REF_TLS_MODEL (sym);
4030
4031 if (model != 0)
4032 {
4033 src = frv_legitimize_tls_address (src, model);
4034 emit_move_insn (dest, src);
4035 return TRUE;
4036 }
4037
34208acf
AO
4038 if (SYMBOL_REF_FUNCTION_P (sym))
4039 {
4040 if (frv_local_funcdesc_p (sym))
4041 unspec = R_FRV_FUNCDESC_GOTOFF12;
4042 else
4043 unspec = R_FRV_FUNCDESC_GOT12;
4044 }
4045 else
4046 {
4047 if (CONSTANT_POOL_ADDRESS_P (sym))
4048 switch (GET_CODE (get_pool_constant (sym)))
4049 {
4050 case CONST:
4051 case SYMBOL_REF:
4052 case LABEL_REF:
4053 if (flag_pic)
4054 {
4055 unspec = R_FRV_GOTOFF12;
4056 break;
4057 }
4058 /* Fall through. */
4059 default:
4060 if (TARGET_GPREL_RO)
4061 unspec = R_FRV_GPREL12;
4062 else
4063 unspec = R_FRV_GOT12;
4064 break;
4065 }
4066 else if (SYMBOL_REF_LOCAL_P (sym)
4067 && !SYMBOL_REF_EXTERNAL_P (sym)
4068 && SYMBOL_REF_DECL (sym)
4069 && (!DECL_P (SYMBOL_REF_DECL (sym))
4070 || !DECL_COMMON (SYMBOL_REF_DECL (sym))))
4071 {
4072 tree decl = SYMBOL_REF_DECL (sym);
4073 tree init = TREE_CODE (decl) == VAR_DECL
4074 ? DECL_INITIAL (decl)
4075 : TREE_CODE (decl) == CONSTRUCTOR
4076 ? decl : 0;
4077 int reloc = 0;
4078 bool named_section, readonly;
4079
4080 if (init && init != error_mark_node)
4081 reloc = compute_reloc_for_constant (init);
2396bce1 4082
34208acf
AO
4083 named_section = TREE_CODE (decl) == VAR_DECL
4084 && lookup_attribute ("section", DECL_ATTRIBUTES (decl));
4085 readonly = decl_readonly_section (decl, reloc);
2396bce1 4086
34208acf
AO
4087 if (named_section)
4088 unspec = R_FRV_GOT12;
4089 else if (!readonly)
4090 unspec = R_FRV_GOTOFF12;
4091 else if (readonly && TARGET_GPREL_RO)
4092 unspec = R_FRV_GPREL12;
4093 else
4094 unspec = R_FRV_GOT12;
4095 }
4096 else
4097 unspec = R_FRV_GOT12;
4098 }
4099 }
4100
4101 else if (SYMBOL_REF_SMALL_P (sym))
36a05131
BS
4102 base_regno = SDA_BASE_REG;
4103
4104 else if (flag_pic)
4105 base_regno = PIC_REGNO;
4106
4107 break;
4108 }
4109
4110 if (base_regno >= 0)
4111 {
34208acf
AO
4112 if (GET_CODE (sym) == SYMBOL_REF && SYMBOL_REF_SMALL_P (sym))
4113 emit_insn (gen_symGOTOFF2reg (dest, src,
4114 gen_rtx_REG (Pmode, base_regno),
4115 GEN_INT (R_FRV_GPREL12)));
4116 else
4117 emit_insn (gen_symGOTOFF2reg_hilo (dest, src,
4118 gen_rtx_REG (Pmode, base_regno),
4119 GEN_INT (R_FRV_GPREL12)));
36a05131 4120 if (base_regno == PIC_REGNO)
ad516a74 4121 crtl->uses_pic_offset_table = TRUE;
34208acf
AO
4122 return TRUE;
4123 }
36a05131 4124
34208acf
AO
4125 if (unspec)
4126 {
4127 rtx x;
4128
4129 /* Since OUR_FDPIC_REG is a pseudo register, we can't safely introduce
4130 new uses of it once reload has begun. */
44e91694 4131 gcc_assert (!reload_in_progress && !reload_completed);
34208acf
AO
4132
4133 switch (unspec)
4134 {
4135 case R_FRV_GOTOFF12:
4136 if (!frv_small_data_reloc_p (sym, unspec))
4137 x = gen_symGOTOFF2reg_hilo (dest, src, OUR_FDPIC_REG,
4138 GEN_INT (unspec));
4139 else
4140 x = gen_symGOTOFF2reg (dest, src, OUR_FDPIC_REG, GEN_INT (unspec));
4141 break;
4142 case R_FRV_GPREL12:
4143 if (!frv_small_data_reloc_p (sym, unspec))
4144 x = gen_symGPREL2reg_hilo (dest, src, OUR_FDPIC_REG,
4145 GEN_INT (unspec));
4146 else
4147 x = gen_symGPREL2reg (dest, src, OUR_FDPIC_REG, GEN_INT (unspec));
4148 break;
4149 case R_FRV_FUNCDESC_GOTOFF12:
4150 if (flag_pic != 1)
4151 x = gen_symGOTOFF2reg_hilo (dest, src, OUR_FDPIC_REG,
4152 GEN_INT (unspec));
4153 else
4154 x = gen_symGOTOFF2reg (dest, src, OUR_FDPIC_REG, GEN_INT (unspec));
4155 break;
4156 default:
4157 if (flag_pic != 1)
4158 x = gen_symGOT2reg_hilo (dest, src, OUR_FDPIC_REG,
4159 GEN_INT (unspec));
4160 else
4161 x = gen_symGOT2reg (dest, src, OUR_FDPIC_REG, GEN_INT (unspec));
4162 break;
4163 }
4164 emit_insn (x);
ad516a74 4165 crtl->uses_pic_offset_table = TRUE;
36a05131
BS
4166 return TRUE;
4167 }
4168
34208acf 4169
36a05131
BS
4170 return FALSE;
4171}
4172
4173\f
4174/* Return a string to output a single word move. */
4175
4176const char *
f2206911 4177output_move_single (rtx operands[], rtx insn)
36a05131
BS
4178{
4179 rtx dest = operands[0];
4180 rtx src = operands[1];
4181
4182 if (GET_CODE (dest) == REG)
4183 {
4184 int dest_regno = REGNO (dest);
ef4bddc2 4185 machine_mode mode = GET_MODE (dest);
36a05131
BS
4186
4187 if (GPR_P (dest_regno))
4188 {
4189 if (GET_CODE (src) == REG)
4190 {
4191 /* gpr <- some sort of register */
4192 int src_regno = REGNO (src);
4193
4194 if (GPR_P (src_regno))
4195 return "mov %1, %0";
4196
4197 else if (FPR_P (src_regno))
4198 return "movfg %1, %0";
4199
4200 else if (SPR_P (src_regno))
4201 return "movsg %1, %0";
4202 }
4203
4204 else if (GET_CODE (src) == MEM)
4205 {
4206 /* gpr <- memory */
4207 switch (mode)
4208 {
4209 default:
4210 break;
4211
4e10a5a7 4212 case E_QImode:
36a05131
BS
4213 return "ldsb%I1%U1 %M1,%0";
4214
4e10a5a7 4215 case E_HImode:
36a05131
BS
4216 return "ldsh%I1%U1 %M1,%0";
4217
4e10a5a7
RS
4218 case E_SImode:
4219 case E_SFmode:
36a05131
BS
4220 return "ld%I1%U1 %M1, %0";
4221 }
4222 }
4223
4224 else if (GET_CODE (src) == CONST_INT
4225 || GET_CODE (src) == CONST_DOUBLE)
4226 {
4227 /* gpr <- integer/floating constant */
4228 HOST_WIDE_INT value;
4229
4230 if (GET_CODE (src) == CONST_INT)
4231 value = INTVAL (src);
4232
4233 else if (mode == SFmode)
4234 {
36a05131
BS
4235 long l;
4236
34a72c33
RS
4237 REAL_VALUE_TO_TARGET_SINGLE
4238 (*CONST_DOUBLE_REAL_VALUE (src), l);
36a05131
BS
4239 value = l;
4240 }
4241
4242 else
4243 value = CONST_DOUBLE_LOW (src);
4244
2f5b1308 4245 if (IN_RANGE (value, -32768, 32767))
36a05131
BS
4246 return "setlos %1, %0";
4247
4248 return "#";
4249 }
4250
4251 else if (GET_CODE (src) == SYMBOL_REF
4252 || GET_CODE (src) == LABEL_REF
4253 || GET_CODE (src) == CONST)
4254 {
36a05131
BS
4255 return "#";
4256 }
4257 }
4258
4259 else if (FPR_P (dest_regno))
4260 {
4261 if (GET_CODE (src) == REG)
4262 {
4263 /* fpr <- some sort of register */
4264 int src_regno = REGNO (src);
4265
4266 if (GPR_P (src_regno))
4267 return "movgf %1, %0";
4268
4269 else if (FPR_P (src_regno))
4270 {
4271 if (TARGET_HARD_FLOAT)
4272 return "fmovs %1, %0";
4273 else
4274 return "mor %1, %1, %0";
4275 }
4276 }
4277
4278 else if (GET_CODE (src) == MEM)
4279 {
4280 /* fpr <- memory */
4281 switch (mode)
4282 {
4283 default:
4284 break;
4285
4e10a5a7 4286 case E_QImode:
36a05131
BS
4287 return "ldbf%I1%U1 %M1,%0";
4288
4e10a5a7 4289 case E_HImode:
36a05131
BS
4290 return "ldhf%I1%U1 %M1,%0";
4291
4e10a5a7
RS
4292 case E_SImode:
4293 case E_SFmode:
36a05131
BS
4294 return "ldf%I1%U1 %M1, %0";
4295 }
4296 }
4297
4298 else if (ZERO_P (src))
4299 return "movgf %., %0";
4300 }
4301
4302 else if (SPR_P (dest_regno))
4303 {
4304 if (GET_CODE (src) == REG)
4305 {
4306 /* spr <- some sort of register */
4307 int src_regno = REGNO (src);
4308
4309 if (GPR_P (src_regno))
4310 return "movgs %1, %0";
4311 }
c557edf4
RS
4312 else if (ZERO_P (src))
4313 return "movgs %., %0";
36a05131
BS
4314 }
4315 }
4316
4317 else if (GET_CODE (dest) == MEM)
4318 {
4319 if (GET_CODE (src) == REG)
4320 {
4321 int src_regno = REGNO (src);
ef4bddc2 4322 machine_mode mode = GET_MODE (dest);
36a05131
BS
4323
4324 if (GPR_P (src_regno))
4325 {
4326 switch (mode)
4327 {
4328 default:
4329 break;
4330
4e10a5a7 4331 case E_QImode:
36a05131
BS
4332 return "stb%I0%U0 %1, %M0";
4333
4e10a5a7 4334 case E_HImode:
36a05131
BS
4335 return "sth%I0%U0 %1, %M0";
4336
4e10a5a7
RS
4337 case E_SImode:
4338 case E_SFmode:
36a05131
BS
4339 return "st%I0%U0 %1, %M0";
4340 }
4341 }
4342
4343 else if (FPR_P (src_regno))
4344 {
4345 switch (mode)
4346 {
4347 default:
4348 break;
4349
4e10a5a7 4350 case E_QImode:
36a05131
BS
4351 return "stbf%I0%U0 %1, %M0";
4352
4e10a5a7 4353 case E_HImode:
36a05131
BS
4354 return "sthf%I0%U0 %1, %M0";
4355
4e10a5a7
RS
4356 case E_SImode:
4357 case E_SFmode:
36a05131
BS
4358 return "stf%I0%U0 %1, %M0";
4359 }
4360 }
4361 }
4362
4363 else if (ZERO_P (src))
4364 {
4365 switch (GET_MODE (dest))
4366 {
4367 default:
4368 break;
4369
4e10a5a7 4370 case E_QImode:
36a05131
BS
4371 return "stb%I0%U0 %., %M0";
4372
4e10a5a7 4373 case E_HImode:
36a05131
BS
4374 return "sth%I0%U0 %., %M0";
4375
4e10a5a7
RS
4376 case E_SImode:
4377 case E_SFmode:
36a05131
BS
4378 return "st%I0%U0 %., %M0";
4379 }
4380 }
4381 }
4382
ab532386 4383 fatal_insn ("bad output_move_single operand", insn);
36a05131
BS
4384 return "";
4385}
4386
4387\f
4388/* Return a string to output a double word move. */
4389
4390const char *
f2206911 4391output_move_double (rtx operands[], rtx insn)
36a05131
BS
4392{
4393 rtx dest = operands[0];
4394 rtx src = operands[1];
ef4bddc2 4395 machine_mode mode = GET_MODE (dest);
36a05131
BS
4396
4397 if (GET_CODE (dest) == REG)
4398 {
4399 int dest_regno = REGNO (dest);
4400
4401 if (GPR_P (dest_regno))
4402 {
4403 if (GET_CODE (src) == REG)
4404 {
4405 /* gpr <- some sort of register */
4406 int src_regno = REGNO (src);
4407
4408 if (GPR_P (src_regno))
4409 return "#";
4410
4411 else if (FPR_P (src_regno))
4412 {
4413 if (((dest_regno - GPR_FIRST) & 1) == 0
4414 && ((src_regno - FPR_FIRST) & 1) == 0)
4415 return "movfgd %1, %0";
4416
4417 return "#";
4418 }
4419 }
4420
4421 else if (GET_CODE (src) == MEM)
4422 {
4423 /* gpr <- memory */
4424 if (dbl_memory_one_insn_operand (src, mode))
4425 return "ldd%I1%U1 %M1, %0";
4426
4427 return "#";
4428 }
4429
4430 else if (GET_CODE (src) == CONST_INT
4431 || GET_CODE (src) == CONST_DOUBLE)
4432 return "#";
4433 }
4434
4435 else if (FPR_P (dest_regno))
4436 {
4437 if (GET_CODE (src) == REG)
4438 {
4439 /* fpr <- some sort of register */
4440 int src_regno = REGNO (src);
4441
4442 if (GPR_P (src_regno))
4443 {
4444 if (((dest_regno - FPR_FIRST) & 1) == 0
4445 && ((src_regno - GPR_FIRST) & 1) == 0)
4446 return "movgfd %1, %0";
4447
4448 return "#";
4449 }
4450
4451 else if (FPR_P (src_regno))
4452 {
4453 if (TARGET_DOUBLE
4454 && ((dest_regno - FPR_FIRST) & 1) == 0
4455 && ((src_regno - FPR_FIRST) & 1) == 0)
4456 return "fmovd %1, %0";
4457
4458 return "#";
4459 }
4460 }
4461
4462 else if (GET_CODE (src) == MEM)
4463 {
4464 /* fpr <- memory */
4465 if (dbl_memory_one_insn_operand (src, mode))
4466 return "lddf%I1%U1 %M1, %0";
4467
4468 return "#";
4469 }
4470
4471 else if (ZERO_P (src))
4472 return "#";
4473 }
4474 }
4475
4476 else if (GET_CODE (dest) == MEM)
4477 {
4478 if (GET_CODE (src) == REG)
4479 {
4480 int src_regno = REGNO (src);
4481
4482 if (GPR_P (src_regno))
4483 {
4484 if (((src_regno - GPR_FIRST) & 1) == 0
4485 && dbl_memory_one_insn_operand (dest, mode))
4486 return "std%I0%U0 %1, %M0";
4487
4488 return "#";
4489 }
4490
4491 if (FPR_P (src_regno))
4492 {
4493 if (((src_regno - FPR_FIRST) & 1) == 0
4494 && dbl_memory_one_insn_operand (dest, mode))
4495 return "stdf%I0%U0 %1, %M0";
4496
4497 return "#";
4498 }
4499 }
4500
4501 else if (ZERO_P (src))
4502 {
4503 if (dbl_memory_one_insn_operand (dest, mode))
4504 return "std%I0%U0 %., %M0";
4505
4506 return "#";
4507 }
4508 }
4509
ab532386 4510 fatal_insn ("bad output_move_double operand", insn);
36a05131
BS
4511 return "";
4512}
4513
4514\f
4515/* Return a string to output a single word conditional move.
4516 Operand0 -- EQ/NE of ccr register and 0
4517 Operand1 -- CCR register
4518 Operand2 -- destination
4519 Operand3 -- source */
4520
4521const char *
f2206911 4522output_condmove_single (rtx operands[], rtx insn)
36a05131
BS
4523{
4524 rtx dest = operands[2];
4525 rtx src = operands[3];
4526
4527 if (GET_CODE (dest) == REG)
4528 {
4529 int dest_regno = REGNO (dest);
ef4bddc2 4530 machine_mode mode = GET_MODE (dest);
36a05131
BS
4531
4532 if (GPR_P (dest_regno))
4533 {
4534 if (GET_CODE (src) == REG)
4535 {
4536 /* gpr <- some sort of register */
4537 int src_regno = REGNO (src);
4538
4539 if (GPR_P (src_regno))
4540 return "cmov %z3, %2, %1, %e0";
4541
4542 else if (FPR_P (src_regno))
4543 return "cmovfg %3, %2, %1, %e0";
4544 }
4545
4546 else if (GET_CODE (src) == MEM)
4547 {
4548 /* gpr <- memory */
4549 switch (mode)
4550 {
4551 default:
4552 break;
4553
4e10a5a7 4554 case E_QImode:
36a05131
BS
4555 return "cldsb%I3%U3 %M3, %2, %1, %e0";
4556
4e10a5a7 4557 case E_HImode:
36a05131
BS
4558 return "cldsh%I3%U3 %M3, %2, %1, %e0";
4559
4e10a5a7
RS
4560 case E_SImode:
4561 case E_SFmode:
36a05131
BS
4562 return "cld%I3%U3 %M3, %2, %1, %e0";
4563 }
4564 }
4565
4566 else if (ZERO_P (src))
4567 return "cmov %., %2, %1, %e0";
4568 }
4569
4570 else if (FPR_P (dest_regno))
4571 {
4572 if (GET_CODE (src) == REG)
4573 {
4574 /* fpr <- some sort of register */
4575 int src_regno = REGNO (src);
4576
4577 if (GPR_P (src_regno))
4578 return "cmovgf %3, %2, %1, %e0";
4579
4580 else if (FPR_P (src_regno))
4581 {
4582 if (TARGET_HARD_FLOAT)
4583 return "cfmovs %3,%2,%1,%e0";
4584 else
4585 return "cmor %3, %3, %2, %1, %e0";
4586 }
4587 }
4588
4589 else if (GET_CODE (src) == MEM)
4590 {
4591 /* fpr <- memory */
4592 if (mode == SImode || mode == SFmode)
4593 return "cldf%I3%U3 %M3, %2, %1, %e0";
4594 }
4595
4596 else if (ZERO_P (src))
4597 return "cmovgf %., %2, %1, %e0";
4598 }
4599 }
4600
4601 else if (GET_CODE (dest) == MEM)
4602 {
4603 if (GET_CODE (src) == REG)
4604 {
4605 int src_regno = REGNO (src);
ef4bddc2 4606 machine_mode mode = GET_MODE (dest);
36a05131
BS
4607
4608 if (GPR_P (src_regno))
4609 {
4610 switch (mode)
4611 {
4612 default:
4613 break;
4614
4e10a5a7 4615 case E_QImode:
36a05131
BS
4616 return "cstb%I2%U2 %3, %M2, %1, %e0";
4617
4e10a5a7 4618 case E_HImode:
36a05131
BS
4619 return "csth%I2%U2 %3, %M2, %1, %e0";
4620
4e10a5a7
RS
4621 case E_SImode:
4622 case E_SFmode:
36a05131
BS
4623 return "cst%I2%U2 %3, %M2, %1, %e0";
4624 }
4625 }
4626
4627 else if (FPR_P (src_regno) && (mode == SImode || mode == SFmode))
4628 return "cstf%I2%U2 %3, %M2, %1, %e0";
4629 }
4630
4631 else if (ZERO_P (src))
4632 {
ef4bddc2 4633 machine_mode mode = GET_MODE (dest);
36a05131
BS
4634 switch (mode)
4635 {
4636 default:
4637 break;
4638
4e10a5a7 4639 case E_QImode:
36a05131
BS
4640 return "cstb%I2%U2 %., %M2, %1, %e0";
4641
4e10a5a7 4642 case E_HImode:
36a05131
BS
4643 return "csth%I2%U2 %., %M2, %1, %e0";
4644
4e10a5a7
RS
4645 case E_SImode:
4646 case E_SFmode:
36a05131
BS
4647 return "cst%I2%U2 %., %M2, %1, %e0";
4648 }
4649 }
4650 }
4651
ab532386 4652 fatal_insn ("bad output_condmove_single operand", insn);
36a05131
BS
4653 return "";
4654}
4655
4656\f
4657/* Emit the appropriate code to do a comparison, returning the register the
4658 comparison was done it. */
4659
4660static rtx
f2206911 4661frv_emit_comparison (enum rtx_code test, rtx op0, rtx op1)
36a05131 4662{
ef4bddc2 4663 machine_mode cc_mode;
36a05131
BS
4664 rtx cc_reg;
4665
87b483a1 4666 /* Floating point doesn't have comparison against a constant. */
36a05131
BS
4667 if (GET_MODE (op0) == CC_FPmode && GET_CODE (op1) != REG)
4668 op1 = force_reg (GET_MODE (op0), op1);
4669
4670 /* Possibly disable using anything but a fixed register in order to work
4671 around cse moving comparisons past function calls. */
4672 cc_mode = SELECT_CC_MODE (test, op0, op1);
4673 cc_reg = ((TARGET_ALLOC_CC)
4674 ? gen_reg_rtx (cc_mode)
4675 : gen_rtx_REG (cc_mode,
4676 (cc_mode == CC_FPmode) ? FCC_FIRST : ICC_FIRST));
4677
f7df4a84 4678 emit_insn (gen_rtx_SET (cc_reg, gen_rtx_COMPARE (cc_mode, op0, op1)));
36a05131
BS
4679
4680 return cc_reg;
4681}
4682
4683\f
f90b7a5a 4684/* Emit code for a conditional branch.
36a05131
BS
4685 XXX: I originally wanted to add a clobber of a CCR register to use in
4686 conditional execution, but that confuses the rest of the compiler. */
4687
4688int
f90b7a5a 4689frv_emit_cond_branch (rtx operands[])
36a05131
BS
4690{
4691 rtx test_rtx;
4692 rtx label_ref;
4693 rtx if_else;
f90b7a5a
PB
4694 enum rtx_code test = GET_CODE (operands[0]);
4695 rtx cc_reg = frv_emit_comparison (test, operands[1], operands[2]);
ef4bddc2 4696 machine_mode cc_mode = GET_MODE (cc_reg);
36a05131
BS
4697
4698 /* Branches generate:
4699 (set (pc)
4700 (if_then_else (<test>, <cc_reg>, (const_int 0))
4701 (label_ref <branch_label>)
4702 (pc))) */
f90b7a5a 4703 label_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
1c563bed 4704 test_rtx = gen_rtx_fmt_ee (test, cc_mode, cc_reg, const0_rtx);
36a05131 4705 if_else = gen_rtx_IF_THEN_ELSE (cc_mode, test_rtx, label_ref, pc_rtx);
f7df4a84 4706 emit_jump_insn (gen_rtx_SET (pc_rtx, if_else));
36a05131
BS
4707 return TRUE;
4708}
4709
4710\f
f90b7a5a 4711/* Emit code to set a gpr to 1/0 based on a comparison. */
36a05131
BS
4712
4713int
f90b7a5a 4714frv_emit_scc (rtx operands[])
36a05131
BS
4715{
4716 rtx set;
4717 rtx test_rtx;
4718 rtx clobber;
4719 rtx cr_reg;
f90b7a5a
PB
4720 enum rtx_code test = GET_CODE (operands[1]);
4721 rtx cc_reg = frv_emit_comparison (test, operands[2], operands[3]);
36a05131
BS
4722
4723 /* SCC instructions generate:
4724 (parallel [(set <target> (<test>, <cc_reg>, (const_int 0))
4725 (clobber (<ccr_reg>))]) */
4726 test_rtx = gen_rtx_fmt_ee (test, SImode, cc_reg, const0_rtx);
f7df4a84 4727 set = gen_rtx_SET (operands[0], test_rtx);
36a05131
BS
4728
4729 cr_reg = ((TARGET_ALLOC_CC)
4730 ? gen_reg_rtx (CC_CCRmode)
4731 : gen_rtx_REG (CC_CCRmode,
4732 ((GET_MODE (cc_reg) == CC_FPmode)
4733 ? FCR_FIRST
4734 : ICR_FIRST)));
4735
4736 clobber = gen_rtx_CLOBBER (VOIDmode, cr_reg);
4737 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set, clobber)));
4738 return TRUE;
4739}
4740
4741\f
4742/* Split a SCC instruction into component parts, returning a SEQUENCE to hold
839a4992 4743 the separate insns. */
36a05131
BS
4744
4745rtx
f2206911 4746frv_split_scc (rtx dest, rtx test, rtx cc_reg, rtx cr_reg, HOST_WIDE_INT value)
36a05131
BS
4747{
4748 rtx ret;
4749
4750 start_sequence ();
4751
4752 /* Set the appropriate CCR bit. */
f7df4a84 4753 emit_insn (gen_rtx_SET (cr_reg,
36a05131
BS
4754 gen_rtx_fmt_ee (GET_CODE (test),
4755 GET_MODE (cr_reg),
4756 cc_reg,
4757 const0_rtx)));
4758
4759 /* Move the value into the destination. */
4760 emit_move_insn (dest, GEN_INT (value));
4761
4762 /* Move 0 into the destination if the test failed */
4763 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4764 gen_rtx_EQ (GET_MODE (cr_reg),
4765 cr_reg,
4766 const0_rtx),
f7df4a84 4767 gen_rtx_SET (dest, const0_rtx)));
36a05131
BS
4768
4769 /* Finish up, return sequence. */
4770 ret = get_insns ();
4771 end_sequence ();
4772 return ret;
4773}
4774
4775\f
4776/* Emit the code for a conditional move, return TRUE if we could do the
4777 move. */
4778
4779int
f2206911 4780frv_emit_cond_move (rtx dest, rtx test_rtx, rtx src1, rtx src2)
36a05131
BS
4781{
4782 rtx set;
4783 rtx clobber_cc;
4784 rtx test2;
4785 rtx cr_reg;
4786 rtx if_rtx;
4787 enum rtx_code test = GET_CODE (test_rtx);
f90b7a5a
PB
4788 rtx cc_reg = frv_emit_comparison (test,
4789 XEXP (test_rtx, 0), XEXP (test_rtx, 1));
ef4bddc2 4790 machine_mode cc_mode = GET_MODE (cc_reg);
36a05131
BS
4791
4792 /* Conditional move instructions generate:
4793 (parallel [(set <target>
4794 (if_then_else (<test> <cc_reg> (const_int 0))
4795 <src1>
4796 <src2>))
4797 (clobber (<ccr_reg>))]) */
4798
4799 /* Handle various cases of conditional move involving two constants. */
4800 if (GET_CODE (src1) == CONST_INT && GET_CODE (src2) == CONST_INT)
4801 {
4802 HOST_WIDE_INT value1 = INTVAL (src1);
4803 HOST_WIDE_INT value2 = INTVAL (src2);
4804
87b483a1 4805 /* Having 0 as one of the constants can be done by loading the other
36a05131
BS
4806 constant, and optionally moving in gr0. */
4807 if (value1 == 0 || value2 == 0)
4808 ;
4809
4810 /* If the first value is within an addi range and also the difference
4811 between the two fits in an addi's range, load up the difference, then
4812 conditionally move in 0, and then unconditionally add the first
4813 value. */
2f5b1308
JR
4814 else if (IN_RANGE (value1, -2048, 2047)
4815 && IN_RANGE (value2 - value1, -2048, 2047))
36a05131
BS
4816 ;
4817
4818 /* If neither condition holds, just force the constant into a
4819 register. */
4820 else
4821 {
4822 src1 = force_reg (GET_MODE (dest), src1);
4823 src2 = force_reg (GET_MODE (dest), src2);
4824 }
4825 }
4826
4827 /* If one value is a register, insure the other value is either 0 or a
4828 register. */
4829 else
4830 {
4831 if (GET_CODE (src1) == CONST_INT && INTVAL (src1) != 0)
4832 src1 = force_reg (GET_MODE (dest), src1);
4833
4834 if (GET_CODE (src2) == CONST_INT && INTVAL (src2) != 0)
4835 src2 = force_reg (GET_MODE (dest), src2);
4836 }
4837
4838 test2 = gen_rtx_fmt_ee (test, cc_mode, cc_reg, const0_rtx);
4839 if_rtx = gen_rtx_IF_THEN_ELSE (GET_MODE (dest), test2, src1, src2);
4840
f7df4a84 4841 set = gen_rtx_SET (dest, if_rtx);
36a05131
BS
4842
4843 cr_reg = ((TARGET_ALLOC_CC)
4844 ? gen_reg_rtx (CC_CCRmode)
4845 : gen_rtx_REG (CC_CCRmode,
4846 (cc_mode == CC_FPmode) ? FCR_FIRST : ICR_FIRST));
4847
4848 clobber_cc = gen_rtx_CLOBBER (VOIDmode, cr_reg);
4849 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set, clobber_cc)));
4850 return TRUE;
4851}
4852
4853\f
839a4992 4854/* Split a conditional move into constituent parts, returning a SEQUENCE
36a05131
BS
4855 containing all of the insns. */
4856
4857rtx
f2206911 4858frv_split_cond_move (rtx operands[])
36a05131
BS
4859{
4860 rtx dest = operands[0];
4861 rtx test = operands[1];
4862 rtx cc_reg = operands[2];
4863 rtx src1 = operands[3];
4864 rtx src2 = operands[4];
4865 rtx cr_reg = operands[5];
4866 rtx ret;
ef4bddc2 4867 machine_mode cr_mode = GET_MODE (cr_reg);
36a05131
BS
4868
4869 start_sequence ();
4870
4871 /* Set the appropriate CCR bit. */
f7df4a84 4872 emit_insn (gen_rtx_SET (cr_reg,
36a05131
BS
4873 gen_rtx_fmt_ee (GET_CODE (test),
4874 GET_MODE (cr_reg),
4875 cc_reg,
4876 const0_rtx)));
4877
4878 /* Handle various cases of conditional move involving two constants. */
4879 if (GET_CODE (src1) == CONST_INT && GET_CODE (src2) == CONST_INT)
4880 {
4881 HOST_WIDE_INT value1 = INTVAL (src1);
4882 HOST_WIDE_INT value2 = INTVAL (src2);
4883
87b483a1 4884 /* Having 0 as one of the constants can be done by loading the other
36a05131
BS
4885 constant, and optionally moving in gr0. */
4886 if (value1 == 0)
4887 {
4888 emit_move_insn (dest, src2);
4889 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4890 gen_rtx_NE (cr_mode, cr_reg,
4891 const0_rtx),
f7df4a84 4892 gen_rtx_SET (dest, src1)));
36a05131
BS
4893 }
4894
4895 else if (value2 == 0)
4896 {
4897 emit_move_insn (dest, src1);
4898 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4899 gen_rtx_EQ (cr_mode, cr_reg,
4900 const0_rtx),
f7df4a84 4901 gen_rtx_SET (dest, src2)));
36a05131
BS
4902 }
4903
4904 /* If the first value is within an addi range and also the difference
4905 between the two fits in an addi's range, load up the difference, then
4906 conditionally move in 0, and then unconditionally add the first
4907 value. */
2f5b1308
JR
4908 else if (IN_RANGE (value1, -2048, 2047)
4909 && IN_RANGE (value2 - value1, -2048, 2047))
36a05131
BS
4910 {
4911 rtx dest_si = ((GET_MODE (dest) == SImode)
4912 ? dest
4913 : gen_rtx_SUBREG (SImode, dest, 0));
4914
4915 emit_move_insn (dest_si, GEN_INT (value2 - value1));
4916 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4917 gen_rtx_NE (cr_mode, cr_reg,
4918 const0_rtx),
f7df4a84 4919 gen_rtx_SET (dest_si, const0_rtx)));
36a05131
BS
4920 emit_insn (gen_addsi3 (dest_si, dest_si, src1));
4921 }
4922
4923 else
44e91694 4924 gcc_unreachable ();
36a05131
BS
4925 }
4926 else
4927 {
4928 /* Emit the conditional move for the test being true if needed. */
4929 if (! rtx_equal_p (dest, src1))
4930 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4931 gen_rtx_NE (cr_mode, cr_reg, const0_rtx),
f7df4a84 4932 gen_rtx_SET (dest, src1)));
36a05131
BS
4933
4934 /* Emit the conditional move for the test being false if needed. */
4935 if (! rtx_equal_p (dest, src2))
4936 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4937 gen_rtx_EQ (cr_mode, cr_reg, const0_rtx),
f7df4a84 4938 gen_rtx_SET (dest, src2)));
36a05131
BS
4939 }
4940
4941 /* Finish up, return sequence. */
4942 ret = get_insns ();
4943 end_sequence ();
4944 return ret;
4945}
4946
4947\f
4948/* Split (set DEST SOURCE), where DEST is a double register and SOURCE is a
4949 memory location that is not known to be dword-aligned. */
4950void
f2206911 4951frv_split_double_load (rtx dest, rtx source)
36a05131
BS
4952{
4953 int regno = REGNO (dest);
4954 rtx dest1 = gen_highpart (SImode, dest);
4955 rtx dest2 = gen_lowpart (SImode, dest);
4956 rtx address = XEXP (source, 0);
4957
4958 /* If the address is pre-modified, load the lower-numbered register
4959 first, then load the other register using an integer offset from
4960 the modified base register. This order should always be safe,
4961 since the pre-modification cannot affect the same registers as the
4962 load does.
4963
4964 The situation for other loads is more complicated. Loading one
4965 of the registers could affect the value of ADDRESS, so we must
4966 be careful which order we do them in. */
4967 if (GET_CODE (address) == PRE_MODIFY
c9bd6bcd 4968 || ! refers_to_regno_p (regno, address))
36a05131
BS
4969 {
4970 /* It is safe to load the lower-numbered register first. */
4971 emit_move_insn (dest1, change_address (source, SImode, NULL));
4972 emit_move_insn (dest2, frv_index_memory (source, SImode, 1));
4973 }
4974 else
4975 {
4976 /* ADDRESS is not pre-modified and the address depends on the
4977 lower-numbered register. Load the higher-numbered register
4978 first. */
4979 emit_move_insn (dest2, frv_index_memory (source, SImode, 1));
4980 emit_move_insn (dest1, change_address (source, SImode, NULL));
4981 }
4982}
4983
4984/* Split (set DEST SOURCE), where DEST refers to a dword memory location
4985 and SOURCE is either a double register or the constant zero. */
4986void
f2206911 4987frv_split_double_store (rtx dest, rtx source)
36a05131
BS
4988{
4989 rtx dest1 = change_address (dest, SImode, NULL);
4990 rtx dest2 = frv_index_memory (dest, SImode, 1);
4991 if (ZERO_P (source))
4992 {
4993 emit_move_insn (dest1, CONST0_RTX (SImode));
4994 emit_move_insn (dest2, CONST0_RTX (SImode));
4995 }
4996 else
4997 {
4998 emit_move_insn (dest1, gen_highpart (SImode, source));
4999 emit_move_insn (dest2, gen_lowpart (SImode, source));
5000 }
5001}
5002
5003\f
5004/* Split a min/max operation returning a SEQUENCE containing all of the
5005 insns. */
5006
5007rtx
f2206911 5008frv_split_minmax (rtx operands[])
36a05131
BS
5009{
5010 rtx dest = operands[0];
5011 rtx minmax = operands[1];
5012 rtx src1 = operands[2];
5013 rtx src2 = operands[3];
5014 rtx cc_reg = operands[4];
5015 rtx cr_reg = operands[5];
5016 rtx ret;
5017 enum rtx_code test_code;
ef4bddc2 5018 machine_mode cr_mode = GET_MODE (cr_reg);
36a05131
BS
5019
5020 start_sequence ();
5021
87b483a1 5022 /* Figure out which test to use. */
36a05131
BS
5023 switch (GET_CODE (minmax))
5024 {
5025 default:
44e91694 5026 gcc_unreachable ();
36a05131
BS
5027
5028 case SMIN: test_code = LT; break;
5029 case SMAX: test_code = GT; break;
5030 case UMIN: test_code = LTU; break;
5031 case UMAX: test_code = GTU; break;
5032 }
5033
5034 /* Issue the compare instruction. */
f7df4a84
RS
5035 emit_insn (gen_rtx_SET (cc_reg, gen_rtx_COMPARE (GET_MODE (cc_reg),
5036 src1, src2)));
36a05131
BS
5037
5038 /* Set the appropriate CCR bit. */
f7df4a84
RS
5039 emit_insn (gen_rtx_SET (cr_reg, gen_rtx_fmt_ee (test_code,
5040 GET_MODE (cr_reg),
5041 cc_reg,
5042 const0_rtx)));
36a05131 5043
9cd10576 5044 /* If are taking the min/max of a nonzero constant, load that first, and
36a05131
BS
5045 then do a conditional move of the other value. */
5046 if (GET_CODE (src2) == CONST_INT && INTVAL (src2) != 0)
5047 {
44e91694 5048 gcc_assert (!rtx_equal_p (dest, src1));
36a05131
BS
5049
5050 emit_move_insn (dest, src2);
5051 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
5052 gen_rtx_NE (cr_mode, cr_reg, const0_rtx),
f7df4a84 5053 gen_rtx_SET (dest, src1)));
36a05131
BS
5054 }
5055
5056 /* Otherwise, do each half of the move. */
5057 else
5058 {
5059 /* Emit the conditional move for the test being true if needed. */
5060 if (! rtx_equal_p (dest, src1))
5061 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
5062 gen_rtx_NE (cr_mode, cr_reg, const0_rtx),
f7df4a84 5063 gen_rtx_SET (dest, src1)));
36a05131
BS
5064
5065 /* Emit the conditional move for the test being false if needed. */
5066 if (! rtx_equal_p (dest, src2))
5067 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
5068 gen_rtx_EQ (cr_mode, cr_reg, const0_rtx),
f7df4a84 5069 gen_rtx_SET (dest, src2)));
36a05131
BS
5070 }
5071
5072 /* Finish up, return sequence. */
5073 ret = get_insns ();
5074 end_sequence ();
5075 return ret;
5076}
5077
5078\f
5079/* Split an integer abs operation returning a SEQUENCE containing all of the
5080 insns. */
5081
5082rtx
f2206911 5083frv_split_abs (rtx operands[])
36a05131
BS
5084{
5085 rtx dest = operands[0];
5086 rtx src = operands[1];
5087 rtx cc_reg = operands[2];
5088 rtx cr_reg = operands[3];
5089 rtx ret;
5090
5091 start_sequence ();
5092
5093 /* Issue the compare < 0 instruction. */
f7df4a84 5094 emit_insn (gen_rtx_SET (cc_reg, gen_rtx_COMPARE (CCmode, src, const0_rtx)));
36a05131
BS
5095
5096 /* Set the appropriate CCR bit. */
f7df4a84
RS
5097 emit_insn (gen_rtx_SET (cr_reg, gen_rtx_fmt_ee (LT, CC_CCRmode,
5098 cc_reg, const0_rtx)));
36a05131 5099
87b483a1 5100 /* Emit the conditional negate if the value is negative. */
36a05131
BS
5101 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
5102 gen_rtx_NE (CC_CCRmode, cr_reg, const0_rtx),
5103 gen_negsi2 (dest, src)));
5104
5105 /* Emit the conditional move for the test being false if needed. */
5106 if (! rtx_equal_p (dest, src))
5107 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
5108 gen_rtx_EQ (CC_CCRmode, cr_reg, const0_rtx),
f7df4a84 5109 gen_rtx_SET (dest, src)));
36a05131
BS
5110
5111 /* Finish up, return sequence. */
5112 ret = get_insns ();
5113 end_sequence ();
5114 return ret;
5115}
5116
36a05131 5117\f
67a0732f
SB
5118/* Initialize machine-specific if-conversion data.
5119 On the FR-V, we don't have any extra fields per se, but it is useful hook to
36a05131
BS
5120 initialize the static storage. */
5121void
afa63532 5122frv_ifcvt_machdep_init (void *ce_info ATTRIBUTE_UNUSED)
36a05131
BS
5123{
5124 frv_ifcvt.added_insns_list = NULL_RTX;
5125 frv_ifcvt.cur_scratch_regs = 0;
5126 frv_ifcvt.num_nested_cond_exec = 0;
5127 frv_ifcvt.cr_reg = NULL_RTX;
5128 frv_ifcvt.nested_cc_reg = NULL_RTX;
5129 frv_ifcvt.extra_int_cr = NULL_RTX;
5130 frv_ifcvt.extra_fp_cr = NULL_RTX;
5131 frv_ifcvt.last_nested_if_cr = NULL_RTX;
5132}
5133
5134\f
1ae58c30 5135/* Internal function to add a potential insn to the list of insns to be inserted
36a05131
BS
5136 if the conditional execution conversion is successful. */
5137
5138static void
df0b55f0 5139frv_ifcvt_add_insn (rtx pattern, rtx_insn *insn, int before_p)
36a05131
BS
5140{
5141 rtx link = alloc_EXPR_LIST (VOIDmode, pattern, insn);
5142
87b483a1 5143 link->jump = before_p; /* Mark to add this before or after insn. */
36a05131
BS
5144 frv_ifcvt.added_insns_list = alloc_EXPR_LIST (VOIDmode, link,
5145 frv_ifcvt.added_insns_list);
5146
5147 if (TARGET_DEBUG_COND_EXEC)
5148 {
5149 fprintf (stderr,
5150 "\n:::::::::: frv_ifcvt_add_insn: add the following %s insn %d:\n",
5151 (before_p) ? "before" : "after",
5152 (int)INSN_UID (insn));
5153
5154 debug_rtx (pattern);
5155 }
5156}
5157
5158\f
5159/* A C expression to modify the code described by the conditional if
5160 information CE_INFO, possibly updating the tests in TRUE_EXPR, and
5161 FALSE_EXPR for converting if-then and if-then-else code to conditional
5162 instructions. Set either TRUE_EXPR or FALSE_EXPR to a null pointer if the
5163 tests cannot be converted. */
5164
5165void
84562394 5166frv_ifcvt_modify_tests (ce_if_block *ce_info, rtx *p_true, rtx *p_false)
36a05131
BS
5167{
5168 basic_block test_bb = ce_info->test_bb; /* test basic block */
5169 basic_block then_bb = ce_info->then_bb; /* THEN */
5170 basic_block else_bb = ce_info->else_bb; /* ELSE or NULL */
5171 basic_block join_bb = ce_info->join_bb; /* join block or NULL */
5172 rtx true_expr = *p_true;
5173 rtx cr;
5174 rtx cc;
5175 rtx nested_cc;
ef4bddc2 5176 machine_mode mode = GET_MODE (true_expr);
36a05131
BS
5177 int j;
5178 basic_block *bb;
5179 int num_bb;
5180 frv_tmp_reg_t *tmp_reg = &frv_ifcvt.tmp_reg;
5181 rtx check_insn;
5182 rtx sub_cond_exec_reg;
5183 enum rtx_code code;
5184 enum rtx_code code_true;
5185 enum rtx_code code_false;
5186 enum reg_class cc_class;
5187 enum reg_class cr_class;
5188 int cc_first;
5189 int cc_last;
a2041967 5190 reg_set_iterator rsi;
36a05131
BS
5191
5192 /* Make sure we are only dealing with hard registers. Also honor the
5193 -mno-cond-exec switch, and -mno-nested-cond-exec switches if
5194 applicable. */
0b2c18fe
RS
5195 if (!reload_completed || !TARGET_COND_EXEC
5196 || (!TARGET_NESTED_CE && ce_info->pass > 1))
36a05131
BS
5197 goto fail;
5198
5199 /* Figure out which registers we can allocate for our own purposes. Only
5200 consider registers that are not preserved across function calls and are
5201 not fixed. However, allow the ICC/ICR temporary registers to be allocated
87b483a1 5202 if we did not need to use them in reloading other registers. */
fad205ff 5203 memset (&tmp_reg->regs, 0, sizeof (tmp_reg->regs));
ff18ad15 5204 tmp_reg->regs = regs_invalidated_by_call & ~fixed_reg_set;
36a05131
BS
5205 SET_HARD_REG_BIT (tmp_reg->regs, ICC_TEMP);
5206 SET_HARD_REG_BIT (tmp_reg->regs, ICR_TEMP);
5207
5208 /* If this is a nested IF, we need to discover whether the CC registers that
5209 are set/used inside of the block are used anywhere else. If not, we can
5210 change them to be the CC register that is paired with the CR register that
5211 controls the outermost IF block. */
5212 if (ce_info->pass > 1)
5213 {
5214 CLEAR_HARD_REG_SET (frv_ifcvt.nested_cc_ok_rewrite);
5215 for (j = CC_FIRST; j <= CC_LAST; j++)
5216 if (TEST_HARD_REG_BIT (tmp_reg->regs, j))
5217 {
eedd7243 5218 if (REGNO_REG_SET_P (df_get_live_in (then_bb), j))
36a05131
BS
5219 continue;
5220
5e2d947c 5221 if (else_bb
eedd7243 5222 && REGNO_REG_SET_P (df_get_live_in (else_bb), j))
36a05131
BS
5223 continue;
5224
5e2d947c 5225 if (join_bb
eedd7243 5226 && REGNO_REG_SET_P (df_get_live_in (join_bb), j))
36a05131
BS
5227 continue;
5228
5229 SET_HARD_REG_BIT (frv_ifcvt.nested_cc_ok_rewrite, j);
5230 }
5231 }
5232
5233 for (j = 0; j < frv_ifcvt.cur_scratch_regs; j++)
5234 frv_ifcvt.scratch_regs[j] = NULL_RTX;
5235
5236 frv_ifcvt.added_insns_list = NULL_RTX;
5237 frv_ifcvt.cur_scratch_regs = 0;
5238
5239 bb = (basic_block *) alloca ((2 + ce_info->num_multiple_test_blocks)
5240 * sizeof (basic_block));
5241
5242 if (join_bb)
5243 {
38c28a25 5244 unsigned int regno;
36a05131
BS
5245
5246 /* Remove anything live at the beginning of the join block from being
5247 available for allocation. */
eedd7243 5248 EXECUTE_IF_SET_IN_REG_SET (df_get_live_in (join_bb), 0, regno, rsi)
a2041967
KH
5249 {
5250 if (regno < FIRST_PSEUDO_REGISTER)
5251 CLEAR_HARD_REG_BIT (tmp_reg->regs, regno);
5252 }
36a05131
BS
5253 }
5254
5255 /* Add in all of the blocks in multiple &&/|| blocks to be scanned. */
5256 num_bb = 0;
5257 if (ce_info->num_multiple_test_blocks)
5258 {
5259 basic_block multiple_test_bb = ce_info->last_test_bb;
5260
5261 while (multiple_test_bb != test_bb)
5262 {
5263 bb[num_bb++] = multiple_test_bb;
628f6a4e 5264 multiple_test_bb = EDGE_PRED (multiple_test_bb, 0)->src;
36a05131
BS
5265 }
5266 }
5267
5268 /* Add in the THEN and ELSE blocks to be scanned. */
5269 bb[num_bb++] = then_bb;
5270 if (else_bb)
5271 bb[num_bb++] = else_bb;
5272
5273 sub_cond_exec_reg = NULL_RTX;
5274 frv_ifcvt.num_nested_cond_exec = 0;
5275
5276 /* Scan all of the blocks for registers that must not be allocated. */
5277 for (j = 0; j < num_bb; j++)
5278 {
b32d5189
DM
5279 rtx_insn *last_insn = BB_END (bb[j]);
5280 rtx_insn *insn = BB_HEAD (bb[j]);
38c28a25 5281 unsigned int regno;
36a05131 5282
c263766c
RH
5283 if (dump_file)
5284 fprintf (dump_file, "Scanning %s block %d, start %d, end %d\n",
36a05131
BS
5285 (bb[j] == else_bb) ? "else" : ((bb[j] == then_bb) ? "then" : "test"),
5286 (int) bb[j]->index,
a813c111
SB
5287 (int) INSN_UID (BB_HEAD (bb[j])),
5288 (int) INSN_UID (BB_END (bb[j])));
36a05131
BS
5289
5290 /* Anything live at the beginning of the block is obviously unavailable
5291 for allocation. */
eedd7243 5292 EXECUTE_IF_SET_IN_REG_SET (df_get_live_in (bb[j]), 0, regno, rsi)
a2041967
KH
5293 {
5294 if (regno < FIRST_PSEUDO_REGISTER)
5295 CLEAR_HARD_REG_BIT (tmp_reg->regs, regno);
5296 }
36a05131 5297
87b483a1 5298 /* Loop through the insns in the block. */
36a05131
BS
5299 for (;;)
5300 {
5301 /* Mark any new registers that are created as being unavailable for
5302 allocation. Also see if the CC register used in nested IFs can be
5303 reallocated. */
5304 if (INSN_P (insn))
5305 {
5306 rtx pattern;
5307 rtx set;
5308 int skip_nested_if = FALSE;
7e8e4cf9 5309 HARD_REG_SET mentioned_regs;
36a05131 5310
7e8e4cf9
RS
5311 CLEAR_HARD_REG_SET (mentioned_regs);
5312 find_all_hard_regs (PATTERN (insn), &mentioned_regs);
d15e5131 5313 tmp_reg->regs &= ~mentioned_regs;
36a05131
BS
5314
5315 pattern = PATTERN (insn);
5316 if (GET_CODE (pattern) == COND_EXEC)
5317 {
5318 rtx reg = XEXP (COND_EXEC_TEST (pattern), 0);
5319
5320 if (reg != sub_cond_exec_reg)
5321 {
5322 sub_cond_exec_reg = reg;
5323 frv_ifcvt.num_nested_cond_exec++;
5324 }
5325 }
5326
5327 set = single_set_pattern (pattern);
5328 if (set)
5329 {
5330 rtx dest = SET_DEST (set);
5331 rtx src = SET_SRC (set);
5332
5333 if (GET_CODE (dest) == REG)
5334 {
5335 int regno = REGNO (dest);
5336 enum rtx_code src_code = GET_CODE (src);
5337
5338 if (CC_P (regno) && src_code == COMPARE)
5339 skip_nested_if = TRUE;
5340
5341 else if (CR_P (regno)
5342 && (src_code == IF_THEN_ELSE
ec8e098d 5343 || COMPARISON_P (src)))
36a05131
BS
5344 skip_nested_if = TRUE;
5345 }
5346 }
5347
5348 if (! skip_nested_if)
d15e5131 5349 frv_ifcvt.nested_cc_ok_rewrite &= ~mentioned_regs;
36a05131
BS
5350 }
5351
5352 if (insn == last_insn)
5353 break;
5354
5355 insn = NEXT_INSN (insn);
5356 }
5357 }
5358
5359 /* If this is a nested if, rewrite the CC registers that are available to
5360 include the ones that can be rewritten, to increase the chance of being
5361 able to allocate a paired CC/CR register combination. */
5362 if (ce_info->pass > 1)
5363 {
5364 for (j = CC_FIRST; j <= CC_LAST; j++)
5365 if (TEST_HARD_REG_BIT (frv_ifcvt.nested_cc_ok_rewrite, j))
5366 SET_HARD_REG_BIT (tmp_reg->regs, j);
5367 else
5368 CLEAR_HARD_REG_BIT (tmp_reg->regs, j);
5369 }
5370
c263766c 5371 if (dump_file)
36a05131
BS
5372 {
5373 int num_gprs = 0;
c263766c 5374 fprintf (dump_file, "Available GPRs: ");
36a05131
BS
5375
5376 for (j = GPR_FIRST; j <= GPR_LAST; j++)
5377 if (TEST_HARD_REG_BIT (tmp_reg->regs, j))
5378 {
c263766c 5379 fprintf (dump_file, " %d [%s]", j, reg_names[j]);
36a05131
BS
5380 if (++num_gprs > GPR_TEMP_NUM+2)
5381 break;
5382 }
5383
c263766c 5384 fprintf (dump_file, "%s\nAvailable CRs: ",
36a05131
BS
5385 (num_gprs > GPR_TEMP_NUM+2) ? " ..." : "");
5386
5387 for (j = CR_FIRST; j <= CR_LAST; j++)
5388 if (TEST_HARD_REG_BIT (tmp_reg->regs, j))
c263766c 5389 fprintf (dump_file, " %d [%s]", j, reg_names[j]);
36a05131 5390
c263766c 5391 fputs ("\n", dump_file);
36a05131
BS
5392
5393 if (ce_info->pass > 1)
5394 {
c263766c 5395 fprintf (dump_file, "Modifiable CCs: ");
36a05131
BS
5396 for (j = CC_FIRST; j <= CC_LAST; j++)
5397 if (TEST_HARD_REG_BIT (tmp_reg->regs, j))
c263766c 5398 fprintf (dump_file, " %d [%s]", j, reg_names[j]);
36a05131 5399
c263766c 5400 fprintf (dump_file, "\n%d nested COND_EXEC statements\n",
36a05131
BS
5401 frv_ifcvt.num_nested_cond_exec);
5402 }
5403 }
5404
5405 /* Allocate the appropriate temporary condition code register. Try to
5406 allocate the ICR/FCR register that corresponds to the ICC/FCC register so
5407 that conditional cmp's can be done. */
036ff63f 5408 if (mode == CCmode || mode == CC_UNSmode || mode == CC_NZmode)
36a05131
BS
5409 {
5410 cr_class = ICR_REGS;
5411 cc_class = ICC_REGS;
5412 cc_first = ICC_FIRST;
5413 cc_last = ICC_LAST;
5414 }
5415 else if (mode == CC_FPmode)
5416 {
5417 cr_class = FCR_REGS;
5418 cc_class = FCC_REGS;
5419 cc_first = FCC_FIRST;
5420 cc_last = FCC_LAST;
5421 }
5422 else
5423 {
5424 cc_first = cc_last = 0;
5425 cr_class = cc_class = NO_REGS;
5426 }
5427
5428 cc = XEXP (true_expr, 0);
5429 nested_cc = cr = NULL_RTX;
5430 if (cc_class != NO_REGS)
5431 {
5432 /* For nested IFs and &&/||, see if we can find a CC and CR register pair
5433 so we can execute a csubcc/caddcc/cfcmps instruction. */
5434 int cc_regno;
5435
5436 for (cc_regno = cc_first; cc_regno <= cc_last; cc_regno++)
5437 {
5438 int cr_regno = cc_regno - CC_FIRST + CR_FIRST;
5439
5440 if (TEST_HARD_REG_BIT (frv_ifcvt.tmp_reg.regs, cc_regno)
5441 && TEST_HARD_REG_BIT (frv_ifcvt.tmp_reg.regs, cr_regno))
5442 {
5443 frv_ifcvt.tmp_reg.next_reg[ (int)cr_class ] = cr_regno;
5444 cr = frv_alloc_temp_reg (tmp_reg, cr_class, CC_CCRmode, TRUE,
5445 TRUE);
5446
5447 frv_ifcvt.tmp_reg.next_reg[ (int)cc_class ] = cc_regno;
5448 nested_cc = frv_alloc_temp_reg (tmp_reg, cc_class, CCmode,
5449 TRUE, TRUE);
5450 break;
5451 }
5452 }
5453 }
5454
5455 if (! cr)
5456 {
c263766c
RH
5457 if (dump_file)
5458 fprintf (dump_file, "Could not allocate a CR temporary register\n");
36a05131
BS
5459
5460 goto fail;
5461 }
5462
c263766c
RH
5463 if (dump_file)
5464 fprintf (dump_file,
36a05131
BS
5465 "Will use %s for conditional execution, %s for nested comparisons\n",
5466 reg_names[ REGNO (cr)],
5467 (nested_cc) ? reg_names[ REGNO (nested_cc) ] : "<none>");
5468
5469 /* Set the CCR bit. Note for integer tests, we reverse the condition so that
5470 in an IF-THEN-ELSE sequence, we are testing the TRUE case against the CCR
5471 bit being true. We don't do this for floating point, because of NaNs. */
5472 code = GET_CODE (true_expr);
5473 if (GET_MODE (cc) != CC_FPmode)
5474 {
5475 code = reverse_condition (code);
5476 code_true = EQ;
5477 code_false = NE;
5478 }
5479 else
5480 {
5481 code_true = NE;
5482 code_false = EQ;
5483 }
5484
f7df4a84
RS
5485 check_insn = gen_rtx_SET (cr, gen_rtx_fmt_ee (code, CC_CCRmode,
5486 cc, const0_rtx));
36a05131
BS
5487
5488 /* Record the check insn to be inserted later. */
a813c111 5489 frv_ifcvt_add_insn (check_insn, BB_END (test_bb), TRUE);
36a05131
BS
5490
5491 /* Update the tests. */
5492 frv_ifcvt.cr_reg = cr;
5493 frv_ifcvt.nested_cc_reg = nested_cc;
5494 *p_true = gen_rtx_fmt_ee (code_true, CC_CCRmode, cr, const0_rtx);
5495 *p_false = gen_rtx_fmt_ee (code_false, CC_CCRmode, cr, const0_rtx);
5496 return;
5497
5498 /* Fail, don't do this conditional execution. */
5499 fail:
5500 *p_true = NULL_RTX;
5501 *p_false = NULL_RTX;
c263766c
RH
5502 if (dump_file)
5503 fprintf (dump_file, "Disabling this conditional execution.\n");
36a05131
BS
5504
5505 return;
5506}
5507
5508\f
5509/* A C expression to modify the code described by the conditional if
5510 information CE_INFO, for the basic block BB, possibly updating the tests in
5511 TRUE_EXPR, and FALSE_EXPR for converting the && and || parts of if-then or
5512 if-then-else code to conditional instructions. Set either TRUE_EXPR or
5513 FALSE_EXPR to a null pointer if the tests cannot be converted. */
5514
5515/* p_true and p_false are given expressions of the form:
5516
5517 (and (eq:CC_CCR (reg:CC_CCR)
5518 (const_int 0))
5519 (eq:CC (reg:CC)
5520 (const_int 0))) */
5521
5522void
84562394 5523frv_ifcvt_modify_multiple_tests (ce_if_block *ce_info,
f2206911
KC
5524 basic_block bb,
5525 rtx *p_true,
5526 rtx *p_false)
36a05131
BS
5527{
5528 rtx old_true = XEXP (*p_true, 0);
5529 rtx old_false = XEXP (*p_false, 0);
5530 rtx true_expr = XEXP (*p_true, 1);
5531 rtx false_expr = XEXP (*p_false, 1);
5532 rtx test_expr;
5533 rtx old_test;
5534 rtx cr = XEXP (old_true, 0);
5535 rtx check_insn;
5536 rtx new_cr = NULL_RTX;
5537 rtx *p_new_cr = (rtx *)0;
5538 rtx if_else;
5539 rtx compare;
5540 rtx cc;
5541 enum reg_class cr_class;
ef4bddc2 5542 machine_mode mode = GET_MODE (true_expr);
36a05131
BS
5543 rtx (*logical_func)(rtx, rtx, rtx);
5544
5545 if (TARGET_DEBUG_COND_EXEC)
5546 {
5547 fprintf (stderr,
5548 "\n:::::::::: frv_ifcvt_modify_multiple_tests, before modification for %s\ntrue insn:\n",
5549 ce_info->and_and_p ? "&&" : "||");
5550
5551 debug_rtx (*p_true);
5552
5553 fputs ("\nfalse insn:\n", stderr);
5554 debug_rtx (*p_false);
5555 }
5556
0b2c18fe 5557 if (!TARGET_MULTI_CE)
36a05131
BS
5558 goto fail;
5559
5560 if (GET_CODE (cr) != REG)
5561 goto fail;
b16c1435 5562
036ff63f 5563 if (mode == CCmode || mode == CC_UNSmode || mode == CC_NZmode)
36a05131
BS
5564 {
5565 cr_class = ICR_REGS;
5566 p_new_cr = &frv_ifcvt.extra_int_cr;
5567 }
5568 else if (mode == CC_FPmode)
5569 {
5570 cr_class = FCR_REGS;
5571 p_new_cr = &frv_ifcvt.extra_fp_cr;
5572 }
5573 else
5574 goto fail;
5575
5576 /* Allocate a temp CR, reusing a previously allocated temp CR if we have 3 or
5577 more &&/|| tests. */
5578 new_cr = *p_new_cr;
5579 if (! new_cr)
5580 {
5581 new_cr = *p_new_cr = frv_alloc_temp_reg (&frv_ifcvt.tmp_reg, cr_class,
5582 CC_CCRmode, TRUE, TRUE);
5583 if (! new_cr)
5584 goto fail;
5585 }
5586
5587 if (ce_info->and_and_p)
5588 {
5589 old_test = old_false;
5590 test_expr = true_expr;
5591 logical_func = (GET_CODE (old_true) == EQ) ? gen_andcr : gen_andncr;
5592 *p_true = gen_rtx_NE (CC_CCRmode, cr, const0_rtx);
5593 *p_false = gen_rtx_EQ (CC_CCRmode, cr, const0_rtx);
5594 }
5595 else
5596 {
5597 old_test = old_false;
5598 test_expr = false_expr;
5599 logical_func = (GET_CODE (old_false) == EQ) ? gen_orcr : gen_orncr;
5600 *p_true = gen_rtx_EQ (CC_CCRmode, cr, const0_rtx);
5601 *p_false = gen_rtx_NE (CC_CCRmode, cr, const0_rtx);
5602 }
5603
5604 /* First add the andcr/andncr/orcr/orncr, which will be added after the
5605 conditional check instruction, due to frv_ifcvt_add_insn being a LIFO
5606 stack. */
a813c111 5607 frv_ifcvt_add_insn ((*logical_func) (cr, cr, new_cr), BB_END (bb), TRUE);
36a05131
BS
5608
5609 /* Now add the conditional check insn. */
5610 cc = XEXP (test_expr, 0);
5611 compare = gen_rtx_fmt_ee (GET_CODE (test_expr), CC_CCRmode, cc, const0_rtx);
5612 if_else = gen_rtx_IF_THEN_ELSE (CC_CCRmode, old_test, compare, const0_rtx);
5613
f7df4a84 5614 check_insn = gen_rtx_SET (new_cr, if_else);
36a05131 5615
87b483a1 5616 /* Add the new check insn to the list of check insns that need to be
36a05131 5617 inserted. */
a813c111 5618 frv_ifcvt_add_insn (check_insn, BB_END (bb), TRUE);
36a05131
BS
5619
5620 if (TARGET_DEBUG_COND_EXEC)
5621 {
5622 fputs ("\n:::::::::: frv_ifcvt_modify_multiple_tests, after modification\ntrue insn:\n",
5623 stderr);
5624
5625 debug_rtx (*p_true);
5626
5627 fputs ("\nfalse insn:\n", stderr);
5628 debug_rtx (*p_false);
5629 }
5630
5631 return;
5632
5633 fail:
5634 *p_true = *p_false = NULL_RTX;
5635
87b483a1 5636 /* If we allocated a CR register, release it. */
36a05131
BS
5637 if (new_cr)
5638 {
5639 CLEAR_HARD_REG_BIT (frv_ifcvt.tmp_reg.regs, REGNO (new_cr));
5640 *p_new_cr = NULL_RTX;
5641 }
5642
5643 if (TARGET_DEBUG_COND_EXEC)
5644 fputs ("\n:::::::::: frv_ifcvt_modify_multiple_tests, failed.\n", stderr);
5645
5646 return;
5647}
5648
5649\f
5650/* Return a register which will be loaded with a value if an IF block is
5651 converted to conditional execution. This is used to rewrite instructions
5652 that use constants to ones that just use registers. */
5653
5654static rtx
f2206911 5655frv_ifcvt_load_value (rtx value, rtx insn ATTRIBUTE_UNUSED)
36a05131
BS
5656{
5657 int num_alloc = frv_ifcvt.cur_scratch_regs;
5658 int i;
5659 rtx reg;
5660
5661 /* We know gr0 == 0, so replace any errant uses. */
5662 if (value == const0_rtx)
5663 return gen_rtx_REG (SImode, GPR_FIRST);
5664
5665 /* First search all registers currently loaded to see if we have an
5666 applicable constant. */
5667 if (CONSTANT_P (value)
5668 || (GET_CODE (value) == REG && REGNO (value) == LR_REGNO))
5669 {
5670 for (i = 0; i < num_alloc; i++)
5671 {
5672 if (rtx_equal_p (SET_SRC (frv_ifcvt.scratch_regs[i]), value))
5673 return SET_DEST (frv_ifcvt.scratch_regs[i]);
5674 }
5675 }
5676
87b483a1 5677 /* Have we exhausted the number of registers available? */
36a05131
BS
5678 if (num_alloc >= GPR_TEMP_NUM)
5679 {
c263766c
RH
5680 if (dump_file)
5681 fprintf (dump_file, "Too many temporary registers allocated\n");
36a05131
BS
5682
5683 return NULL_RTX;
5684 }
5685
5686 /* Allocate the new register. */
5687 reg = frv_alloc_temp_reg (&frv_ifcvt.tmp_reg, GPR_REGS, SImode, TRUE, TRUE);
5688 if (! reg)
5689 {
c263766c
RH
5690 if (dump_file)
5691 fputs ("Could not find a scratch register\n", dump_file);
36a05131
BS
5692
5693 return NULL_RTX;
5694 }
5695
5696 frv_ifcvt.cur_scratch_regs++;
f7df4a84 5697 frv_ifcvt.scratch_regs[num_alloc] = gen_rtx_SET (reg, value);
36a05131 5698
c263766c 5699 if (dump_file)
36a05131
BS
5700 {
5701 if (GET_CODE (value) == CONST_INT)
c263766c 5702 fprintf (dump_file, "Register %s will hold %ld\n",
36a05131
BS
5703 reg_names[ REGNO (reg)], (long)INTVAL (value));
5704
5705 else if (GET_CODE (value) == REG && REGNO (value) == LR_REGNO)
c263766c 5706 fprintf (dump_file, "Register %s will hold LR\n",
36a05131
BS
5707 reg_names[ REGNO (reg)]);
5708
5709 else
c263766c 5710 fprintf (dump_file, "Register %s will hold a saved value\n",
36a05131
BS
5711 reg_names[ REGNO (reg)]);
5712 }
5713
5714 return reg;
5715}
5716
5717\f
5718/* Update a MEM used in conditional code that might contain an offset to put
5719 the offset into a scratch register, so that the conditional load/store
5720 operations can be used. This function returns the original pointer if the
5721 MEM is valid to use in conditional code, NULL if we can't load up the offset
5722 into a temporary register, or the new MEM if we were successful. */
5723
5724static rtx
ef4bddc2 5725frv_ifcvt_rewrite_mem (rtx mem, machine_mode mode, rtx insn)
36a05131
BS
5726{
5727 rtx addr = XEXP (mem, 0);
5728
c6c3dba9 5729 if (!frv_legitimate_address_p_1 (mode, addr, reload_completed, TRUE, FALSE))
36a05131
BS
5730 {
5731 if (GET_CODE (addr) == PLUS)
5732 {
5733 rtx addr_op0 = XEXP (addr, 0);
5734 rtx addr_op1 = XEXP (addr, 1);
5735
34208acf 5736 if (GET_CODE (addr_op0) == REG && CONSTANT_P (addr_op1))
36a05131
BS
5737 {
5738 rtx reg = frv_ifcvt_load_value (addr_op1, insn);
5739 if (!reg)
5740 return NULL_RTX;
5741
5742 addr = gen_rtx_PLUS (Pmode, addr_op0, reg);
5743 }
5744
5745 else
5746 return NULL_RTX;
5747 }
5748
5749 else if (CONSTANT_P (addr))
5750 addr = frv_ifcvt_load_value (addr, insn);
5751
5752 else
5753 return NULL_RTX;
5754
5755 if (addr == NULL_RTX)
5756 return NULL_RTX;
5757
5758 else if (XEXP (mem, 0) != addr)
5759 return change_address (mem, mode, addr);
5760 }
5761
5762 return mem;
5763}
5764
5765\f
5766/* Given a PATTERN, return a SET expression if this PATTERN has only a single
5767 SET, possibly conditionally executed. It may also have CLOBBERs, USEs. */
5768
5769static rtx
f2206911 5770single_set_pattern (rtx pattern)
36a05131
BS
5771{
5772 rtx set;
5773 int i;
5774
5775 if (GET_CODE (pattern) == COND_EXEC)
5776 pattern = COND_EXEC_CODE (pattern);
5777
5778 if (GET_CODE (pattern) == SET)
5779 return pattern;
5780
5781 else if (GET_CODE (pattern) == PARALLEL)
5782 {
5783 for (i = 0, set = 0; i < XVECLEN (pattern, 0); i++)
5784 {
5785 rtx sub = XVECEXP (pattern, 0, i);
5786
5787 switch (GET_CODE (sub))
5788 {
5789 case USE:
5790 case CLOBBER:
5791 break;
5792
5793 case SET:
5794 if (set)
5795 return 0;
5796 else
5797 set = sub;
5798 break;
5799
5800 default:
5801 return 0;
5802 }
5803 }
5804 return set;
5805 }
5806
5807 return 0;
5808}
5809
5810\f
5811/* A C expression to modify the code described by the conditional if
5812 information CE_INFO with the new PATTERN in INSN. If PATTERN is a null
5813 pointer after the IFCVT_MODIFY_INSN macro executes, it is assumed that that
5814 insn cannot be converted to be executed conditionally. */
5815
5816rtx
84562394 5817frv_ifcvt_modify_insn (ce_if_block *ce_info,
f2206911 5818 rtx pattern,
df0b55f0 5819 rtx_insn *insn)
36a05131
BS
5820{
5821 rtx orig_ce_pattern = pattern;
5822 rtx set;
5823 rtx op0;
5824 rtx op1;
5825 rtx test;
5826
44e91694 5827 gcc_assert (GET_CODE (pattern) == COND_EXEC);
36a05131
BS
5828
5829 test = COND_EXEC_TEST (pattern);
5830 if (GET_CODE (test) == AND)
5831 {
5832 rtx cr = frv_ifcvt.cr_reg;
5833 rtx test_reg;
5834
5835 op0 = XEXP (test, 0);
5836 if (! rtx_equal_p (cr, XEXP (op0, 0)))
5837 goto fail;
5838
5839 op1 = XEXP (test, 1);
5840 test_reg = XEXP (op1, 0);
5841 if (GET_CODE (test_reg) != REG)
5842 goto fail;
5843
5844 /* Is this the first nested if block in this sequence? If so, generate
5845 an andcr or andncr. */
5846 if (! frv_ifcvt.last_nested_if_cr)
5847 {
5848 rtx and_op;
5849
5850 frv_ifcvt.last_nested_if_cr = test_reg;
5851 if (GET_CODE (op0) == NE)
5852 and_op = gen_andcr (test_reg, cr, test_reg);
5853 else
5854 and_op = gen_andncr (test_reg, cr, test_reg);
5855
5856 frv_ifcvt_add_insn (and_op, insn, TRUE);
5857 }
5858
5859 /* If this isn't the first statement in the nested if sequence, see if we
5860 are dealing with the same register. */
5861 else if (! rtx_equal_p (test_reg, frv_ifcvt.last_nested_if_cr))
5862 goto fail;
5863
5864 COND_EXEC_TEST (pattern) = test = op1;
5865 }
5866
5867 /* If this isn't a nested if, reset state variables. */
5868 else
5869 {
5870 frv_ifcvt.last_nested_if_cr = NULL_RTX;
5871 }
5872
5873 set = single_set_pattern (pattern);
5874 if (set)
5875 {
5876 rtx dest = SET_DEST (set);
5877 rtx src = SET_SRC (set);
ef4bddc2 5878 machine_mode mode = GET_MODE (dest);
36a05131 5879
87b483a1 5880 /* Check for normal binary operators. */
ec8e098d 5881 if (mode == SImode && ARITHMETIC_P (src))
36a05131
BS
5882 {
5883 op0 = XEXP (src, 0);
5884 op1 = XEXP (src, 1);
5885
34208acf 5886 if (integer_register_operand (op0, SImode) && CONSTANT_P (op1))
36a05131
BS
5887 {
5888 op1 = frv_ifcvt_load_value (op1, insn);
5889 if (op1)
5890 COND_EXEC_CODE (pattern)
f7df4a84
RS
5891 = gen_rtx_SET (dest, gen_rtx_fmt_ee (GET_CODE (src),
5892 GET_MODE (src),
5893 op0, op1));
36a05131
BS
5894 else
5895 goto fail;
5896 }
5897 }
5898
5899 /* For multiply by a constant, we need to handle the sign extending
5900 correctly. Add a USE of the value after the multiply to prevent flow
5901 from cratering because only one register out of the two were used. */
5902 else if (mode == DImode && GET_CODE (src) == MULT)
5903 {
5904 op0 = XEXP (src, 0);
5905 op1 = XEXP (src, 1);
5906 if (GET_CODE (op0) == SIGN_EXTEND && GET_CODE (op1) == CONST_INT)
5907 {
5908 op1 = frv_ifcvt_load_value (op1, insn);
5909 if (op1)
5910 {
5911 op1 = gen_rtx_SIGN_EXTEND (DImode, op1);
5912 COND_EXEC_CODE (pattern)
f7df4a84 5913 = gen_rtx_SET (dest, gen_rtx_MULT (DImode, op0, op1));
36a05131
BS
5914 }
5915 else
5916 goto fail;
5917 }
5918
c41c1387 5919 frv_ifcvt_add_insn (gen_use (dest), insn, FALSE);
36a05131
BS
5920 }
5921
5922 /* If we are just loading a constant created for a nested conditional
5923 execution statement, just load the constant without any conditional
5924 execution, since we know that the constant will not interfere with any
5925 other registers. */
5926 else if (frv_ifcvt.scratch_insns_bitmap
5927 && bitmap_bit_p (frv_ifcvt.scratch_insns_bitmap,
5da1fd3d 5928 INSN_UID (insn))
5da1fd3d 5929 && REG_P (SET_DEST (set))
9a228f09
AO
5930 /* We must not unconditionally set a scratch reg chosen
5931 for a nested if-converted block if its incoming
5932 value from the TEST block (or the result of the THEN
5933 branch) could/should propagate to the JOIN block.
5934 It suffices to test whether the register is live at
5935 the JOIN point: if it's live there, we can infer
5936 that we set it in the former JOIN block of the
5937 nested if-converted block (otherwise it wouldn't
5938 have been available as a scratch register), and it
5939 is either propagated through or set in the other
5940 conditional block. It's probably not worth trying
5941 to catch the latter case, and it could actually
5942 limit scheduling of the combined block quite
5943 severely. */
5944 && ce_info->join_bb
eedd7243
RIL
5945 && ! (REGNO_REG_SET_P (df_get_live_in (ce_info->join_bb),
5946 REGNO (SET_DEST (set))))
9a228f09
AO
5947 /* Similarly, we must not unconditionally set a reg
5948 used as scratch in the THEN branch if the same reg
5949 is live in the ELSE branch. */
5da1fd3d
AO
5950 && (! ce_info->else_bb
5951 || BLOCK_FOR_INSN (insn) == ce_info->else_bb
eedd7243
RIL
5952 || ! (REGNO_REG_SET_P (df_get_live_in (ce_info->else_bb),
5953 REGNO (SET_DEST (set))))))
36a05131
BS
5954 pattern = set;
5955
5956 else if (mode == QImode || mode == HImode || mode == SImode
5957 || mode == SFmode)
5958 {
5959 int changed_p = FALSE;
5960
5961 /* Check for just loading up a constant */
5962 if (CONSTANT_P (src) && integer_register_operand (dest, mode))
5963 {
5964 src = frv_ifcvt_load_value (src, insn);
5965 if (!src)
5966 goto fail;
5967
5968 changed_p = TRUE;
5969 }
5970
5971 /* See if we need to fix up stores */
5972 if (GET_CODE (dest) == MEM)
5973 {
5974 rtx new_mem = frv_ifcvt_rewrite_mem (dest, mode, insn);
5975
5976 if (!new_mem)
5977 goto fail;
5978
5979 else if (new_mem != dest)
5980 {
5981 changed_p = TRUE;
5982 dest = new_mem;
5983 }
5984 }
5985
5986 /* See if we need to fix up loads */
5987 if (GET_CODE (src) == MEM)
5988 {
5989 rtx new_mem = frv_ifcvt_rewrite_mem (src, mode, insn);
5990
5991 if (!new_mem)
5992 goto fail;
5993
5994 else if (new_mem != src)
5995 {
5996 changed_p = TRUE;
5997 src = new_mem;
5998 }
5999 }
6000
6001 /* If either src or destination changed, redo SET. */
6002 if (changed_p)
f7df4a84 6003 COND_EXEC_CODE (pattern) = gen_rtx_SET (dest, src);
36a05131
BS
6004 }
6005
6006 /* Rewrite a nested set cccr in terms of IF_THEN_ELSE. Also deal with
6007 rewriting the CC register to be the same as the paired CC/CR register
6008 for nested ifs. */
ec8e098d 6009 else if (mode == CC_CCRmode && COMPARISON_P (src))
36a05131
BS
6010 {
6011 int regno = REGNO (XEXP (src, 0));
6012 rtx if_else;
6013
6014 if (ce_info->pass > 1
6015 && regno != (int)REGNO (frv_ifcvt.nested_cc_reg)
6016 && TEST_HARD_REG_BIT (frv_ifcvt.nested_cc_ok_rewrite, regno))
6017 {
6018 src = gen_rtx_fmt_ee (GET_CODE (src),
6019 CC_CCRmode,
6020 frv_ifcvt.nested_cc_reg,
6021 XEXP (src, 1));
6022 }
6023
6024 if_else = gen_rtx_IF_THEN_ELSE (CC_CCRmode, test, src, const0_rtx);
f7df4a84 6025 pattern = gen_rtx_SET (dest, if_else);
36a05131
BS
6026 }
6027
6028 /* Remap a nested compare instruction to use the paired CC/CR reg. */
6029 else if (ce_info->pass > 1
6030 && GET_CODE (dest) == REG
6031 && CC_P (REGNO (dest))
6032 && REGNO (dest) != REGNO (frv_ifcvt.nested_cc_reg)
6033 && TEST_HARD_REG_BIT (frv_ifcvt.nested_cc_ok_rewrite,
6034 REGNO (dest))
6035 && GET_CODE (src) == COMPARE)
6036 {
6037 PUT_MODE (frv_ifcvt.nested_cc_reg, GET_MODE (dest));
6038 COND_EXEC_CODE (pattern)
f7df4a84 6039 = gen_rtx_SET (frv_ifcvt.nested_cc_reg, copy_rtx (src));
36a05131
BS
6040 }
6041 }
6042
6043 if (TARGET_DEBUG_COND_EXEC)
6044 {
6045 rtx orig_pattern = PATTERN (insn);
6046
6047 PATTERN (insn) = pattern;
6048 fprintf (stderr,
6049 "\n:::::::::: frv_ifcvt_modify_insn: pass = %d, insn after modification:\n",
6050 ce_info->pass);
6051
6052 debug_rtx (insn);
6053 PATTERN (insn) = orig_pattern;
6054 }
6055
6056 return pattern;
6057
6058 fail:
6059 if (TARGET_DEBUG_COND_EXEC)
6060 {
6061 rtx orig_pattern = PATTERN (insn);
6062
6063 PATTERN (insn) = orig_ce_pattern;
6064 fprintf (stderr,
6065 "\n:::::::::: frv_ifcvt_modify_insn: pass = %d, insn could not be modified:\n",
6066 ce_info->pass);
6067
6068 debug_rtx (insn);
6069 PATTERN (insn) = orig_pattern;
6070 }
6071
6072 return NULL_RTX;
6073}
6074
6075\f
6076/* A C expression to perform any final machine dependent modifications in
6077 converting code to conditional execution in the code described by the
6078 conditional if information CE_INFO. */
6079
6080void
84562394 6081frv_ifcvt_modify_final (ce_if_block *ce_info ATTRIBUTE_UNUSED)
36a05131 6082{
df0b55f0 6083 rtx_insn *existing_insn;
36a05131
BS
6084 rtx check_insn;
6085 rtx p = frv_ifcvt.added_insns_list;
6086 int i;
6087
6088 /* Loop inserting the check insns. The last check insn is the first test,
6089 and is the appropriate place to insert constants. */
44e91694 6090 gcc_assert (p);
36a05131
BS
6091
6092 do
6093 {
6094 rtx check_and_insert_insns = XEXP (p, 0);
6095 rtx old_p = p;
6096
6097 check_insn = XEXP (check_and_insert_insns, 0);
df0b55f0 6098 existing_insn = as_a <rtx_insn *> (XEXP (check_and_insert_insns, 1));
36a05131
BS
6099 p = XEXP (p, 1);
6100
6101 /* The jump bit is used to say that the new insn is to be inserted BEFORE
6102 the existing insn, otherwise it is to be inserted AFTER. */
6103 if (check_and_insert_insns->jump)
6104 {
6105 emit_insn_before (check_insn, existing_insn);
6106 check_and_insert_insns->jump = 0;
6107 }
6108 else
6109 emit_insn_after (check_insn, existing_insn);
6110
6111 free_EXPR_LIST_node (check_and_insert_insns);
6112 free_EXPR_LIST_node (old_p);
6113 }
6114 while (p != NULL_RTX);
6115
6116 /* Load up any constants needed into temp gprs */
6117 for (i = 0; i < frv_ifcvt.cur_scratch_regs; i++)
6118 {
df0b55f0 6119 rtx_insn *insn = emit_insn_before (frv_ifcvt.scratch_regs[i], existing_insn);
36a05131 6120 if (! frv_ifcvt.scratch_insns_bitmap)
7b210806 6121 frv_ifcvt.scratch_insns_bitmap = BITMAP_ALLOC (NULL);
36a05131
BS
6122 bitmap_set_bit (frv_ifcvt.scratch_insns_bitmap, INSN_UID (insn));
6123 frv_ifcvt.scratch_regs[i] = NULL_RTX;
6124 }
6125
6126 frv_ifcvt.added_insns_list = NULL_RTX;
6127 frv_ifcvt.cur_scratch_regs = 0;
6128}
6129
6130\f
6131/* A C expression to cancel any machine dependent modifications in converting
6132 code to conditional execution in the code described by the conditional if
6133 information CE_INFO. */
6134
6135void
84562394 6136frv_ifcvt_modify_cancel (ce_if_block *ce_info ATTRIBUTE_UNUSED)
36a05131
BS
6137{
6138 int i;
6139 rtx p = frv_ifcvt.added_insns_list;
6140
6141 /* Loop freeing up the EXPR_LIST's allocated. */
6142 while (p != NULL_RTX)
6143 {
6144 rtx check_and_jump = XEXP (p, 0);
6145 rtx old_p = p;
6146
6147 p = XEXP (p, 1);
6148 free_EXPR_LIST_node (check_and_jump);
6149 free_EXPR_LIST_node (old_p);
6150 }
6151
6152 /* Release any temporary gprs allocated. */
6153 for (i = 0; i < frv_ifcvt.cur_scratch_regs; i++)
6154 frv_ifcvt.scratch_regs[i] = NULL_RTX;
6155
6156 frv_ifcvt.added_insns_list = NULL_RTX;
6157 frv_ifcvt.cur_scratch_regs = 0;
6158 return;
6159}
6160\f
6161/* A C expression for the size in bytes of the trampoline, as an integer.
6162 The template is:
6163
6164 setlo #0, <jmp_reg>
6165 setlo #0, <static_chain>
6166 sethi #0, <jmp_reg>
6167 sethi #0, <static_chain>
6168 jmpl @(gr0,<jmp_reg>) */
6169
6170int
f2206911 6171frv_trampoline_size (void)
36a05131 6172{
34208acf
AO
6173 if (TARGET_FDPIC)
6174 /* Allocate room for the function descriptor and the lddi
6175 instruction. */
6176 return 8 + 6 * 4;
6177 return 5 /* instructions */ * 4 /* instruction size. */;
36a05131
BS
6178}
6179
6180\f
6181/* A C statement to initialize the variable parts of a trampoline. ADDR is an
6182 RTX for the address of the trampoline; FNADDR is an RTX for the address of
6183 the nested function; STATIC_CHAIN is an RTX for the static chain value that
6184 should be passed to the function when it is called.
6185
6186 The template is:
6187
6188 setlo #0, <jmp_reg>
6189 setlo #0, <static_chain>
6190 sethi #0, <jmp_reg>
6191 sethi #0, <static_chain>
6192 jmpl @(gr0,<jmp_reg>) */
6193
e9d5fdb2
RH
6194static void
6195frv_trampoline_init (rtx m_tramp, tree fndecl, rtx static_chain)
36a05131 6196{
e9d5fdb2
RH
6197 rtx addr = XEXP (m_tramp, 0);
6198 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
36a05131
BS
6199 rtx sc_reg = force_reg (Pmode, static_chain);
6200
6201 emit_library_call (gen_rtx_SYMBOL_REF (SImode, "__trampoline_setup"),
db69559b 6202 LCT_NORMAL, VOIDmode,
36a05131
BS
6203 addr, Pmode,
6204 GEN_INT (frv_trampoline_size ()), SImode,
6205 fnaddr, Pmode,
6206 sc_reg, Pmode);
6207}
6208
6209\f
6210/* Many machines have some registers that cannot be copied directly to or from
6211 memory or even from other types of registers. An example is the `MQ'
6212 register, which on most machines, can only be copied to or from general
6213 registers, but not memory. Some machines allow copying all registers to and
6214 from memory, but require a scratch register for stores to some memory
6215 locations (e.g., those with symbolic address on the RT, and those with
981f6289 6216 certain symbolic address on the SPARC when compiling PIC). In some cases,
36a05131
BS
6217 both an intermediate and a scratch register are required.
6218
6219 You should define these macros to indicate to the reload phase that it may
6220 need to allocate at least one register for a reload in addition to the
6221 register to contain the data. Specifically, if copying X to a register
0a2aaacc 6222 RCLASS in MODE requires an intermediate register, you should define
36a05131
BS
6223 `SECONDARY_INPUT_RELOAD_CLASS' to return the largest register class all of
6224 whose registers can be used as intermediate registers or scratch registers.
6225
0a2aaacc 6226 If copying a register RCLASS in MODE to X requires an intermediate or scratch
36a05131
BS
6227 register, `SECONDARY_OUTPUT_RELOAD_CLASS' should be defined to return the
6228 largest register class required. If the requirements for input and output
6229 reloads are the same, the macro `SECONDARY_RELOAD_CLASS' should be used
6230 instead of defining both macros identically.
6231
6232 The values returned by these macros are often `GENERAL_REGS'. Return
6233 `NO_REGS' if no spare register is needed; i.e., if X can be directly copied
0a2aaacc 6234 to or from a register of RCLASS in MODE without requiring a scratch register.
36a05131
BS
6235 Do not define this macro if it would always return `NO_REGS'.
6236
6237 If a scratch register is required (either with or without an intermediate
6238 register), you should define patterns for `reload_inM' or `reload_outM', as
6239 required.. These patterns, which will normally be implemented with a
6240 `define_expand', should be similar to the `movM' patterns, except that
6241 operand 2 is the scratch register.
6242
6243 Define constraints for the reload register and scratch register that contain
6244 a single register class. If the original reload register (whose class is
0a2aaacc 6245 RCLASS) can meet the constraint given in the pattern, the value returned by
36a05131
BS
6246 these macros is used for the class of the scratch register. Otherwise, two
6247 additional reload registers are required. Their classes are obtained from
6248 the constraints in the insn pattern.
6249
6250 X might be a pseudo-register or a `subreg' of a pseudo-register, which could
6251 either be in a hard register or in memory. Use `true_regnum' to find out;
6252 it will return -1 if the pseudo is in memory and the hard register number if
6253 it is in a register.
6254
6255 These macros should not be used in the case where a particular class of
6256 registers can only be copied to memory and not to another class of
6257 registers. In that case, secondary reload registers are not needed and
6258 would not be helpful. Instead, a stack location must be used to perform the
43aa4e05 6259 copy and the `movM' pattern should use memory as an intermediate storage.
36a05131
BS
6260 This case often occurs between floating-point and general registers. */
6261
6262enum reg_class
0a2aaacc 6263frv_secondary_reload_class (enum reg_class rclass,
ef4bddc2 6264 machine_mode mode ATTRIBUTE_UNUSED,
35f2d8ef 6265 rtx x)
36a05131
BS
6266{
6267 enum reg_class ret;
6268
0a2aaacc 6269 switch (rclass)
36a05131
BS
6270 {
6271 default:
6272 ret = NO_REGS;
6273 break;
6274
6275 /* Accumulators/Accumulator guard registers need to go through floating
6276 point registers. */
6277 case QUAD_REGS:
36a05131
BS
6278 case GPR_REGS:
6279 ret = NO_REGS;
6280 if (x && GET_CODE (x) == REG)
6281 {
6282 int regno = REGNO (x);
6283
6284 if (ACC_P (regno) || ACCG_P (regno))
6285 ret = FPR_REGS;
6286 }
6287 break;
6288
9cd10576 6289 /* Nonzero constants should be loaded into an FPR through a GPR. */
36a05131 6290 case QUAD_FPR_REGS:
36a05131
BS
6291 if (x && CONSTANT_P (x) && !ZERO_P (x))
6292 ret = GPR_REGS;
6293 else
6294 ret = NO_REGS;
6295 break;
6296
6297 /* All of these types need gpr registers. */
6298 case ICC_REGS:
6299 case FCC_REGS:
6300 case CC_REGS:
6301 case ICR_REGS:
6302 case FCR_REGS:
6303 case CR_REGS:
6304 case LCR_REG:
6305 case LR_REG:
6306 ret = GPR_REGS;
6307 break;
6308
35f2d8ef 6309 /* The accumulators need fpr registers. */
36a05131
BS
6310 case QUAD_ACC_REGS:
6311 case ACCG_REGS:
6312 ret = FPR_REGS;
6313 break;
6314 }
6315
6316 return ret;
6317}
6318
35f2d8ef
NC
6319/* This hook exists to catch the case where secondary_reload_class() is
6320 called from init_reg_autoinc() in regclass.c - before the reload optabs
6321 have been initialised. */
6322
a87cf97e
JR
6323static reg_class_t
6324frv_secondary_reload (bool in_p, rtx x, reg_class_t reload_class_i,
ef4bddc2 6325 machine_mode reload_mode,
35f2d8ef
NC
6326 secondary_reload_info * sri)
6327{
6328 enum reg_class rclass = NO_REGS;
a87cf97e 6329 enum reg_class reload_class = (enum reg_class) reload_class_i;
35f2d8ef
NC
6330
6331 if (sri->prev_sri && sri->prev_sri->t_icode != CODE_FOR_nothing)
6332 {
6333 sri->icode = sri->prev_sri->t_icode;
6334 return NO_REGS;
6335 }
6336
6337 rclass = frv_secondary_reload_class (reload_class, reload_mode, x);
6338
6339 if (rclass != NO_REGS)
6340 {
f9621cc4
RS
6341 enum insn_code icode
6342 = direct_optab_handler (in_p ? reload_in_optab : reload_out_optab,
6343 reload_mode);
35f2d8ef
NC
6344 if (icode == 0)
6345 {
6346 /* This happens when then the reload_[in|out]_optabs have
6347 not been initialised. */
6348 sri->t_icode = CODE_FOR_nothing;
6349 return rclass;
6350 }
6351 }
6352
6353 /* Fall back to the default secondary reload handler. */
6354 return default_secondary_reload (in_p, x, reload_class, reload_mode, sri);
6355
6356}
36a05131 6357\f
c28350ab 6358/* Worker function for TARGET_CLASS_LIKELY_SPILLED_P. */
36a05131 6359
c28350ab
AS
6360static bool
6361frv_class_likely_spilled_p (reg_class_t rclass)
36a05131 6362{
0a2aaacc 6363 switch (rclass)
36a05131
BS
6364 {
6365 default:
6366 break;
6367
17c21957
AO
6368 case GR8_REGS:
6369 case GR9_REGS:
6370 case GR89_REGS:
6371 case FDPIC_FPTR_REGS:
6372 case FDPIC_REGS:
36a05131
BS
6373 case ICC_REGS:
6374 case FCC_REGS:
6375 case CC_REGS:
6376 case ICR_REGS:
6377 case FCR_REGS:
6378 case CR_REGS:
6379 case LCR_REG:
6380 case LR_REG:
6381 case SPR_REGS:
6382 case QUAD_ACC_REGS:
36a05131 6383 case ACCG_REGS:
c28350ab 6384 return true;
36a05131
BS
6385 }
6386
c28350ab 6387 return false;
36a05131
BS
6388}
6389
6390\f
6391/* An expression for the alignment of a structure field FIELD if the
7ec022b2 6392 alignment computed in the usual way is COMPUTED. GCC uses this
36a05131
BS
6393 value instead of the value in `BIGGEST_ALIGNMENT' or
6394 `BIGGEST_FIELD_ALIGNMENT', if defined, for structure fields only. */
6395
6396/* The definition type of the bit field data is either char, short, long or
6397 long long. The maximum bit size is the number of bits of its own type.
6398
6399 The bit field data is assigned to a storage unit that has an adequate size
6400 for bit field data retention and is located at the smallest address.
6401
6402 Consecutive bit field data are packed at consecutive bits having the same
6403 storage unit, with regard to the type, beginning with the MSB and continuing
6404 toward the LSB.
6405
6406 If a field to be assigned lies over a bit field type boundary, its
6407 assignment is completed by aligning it with a boundary suitable for the
6408 type.
6409
6410 When a bit field having a bit length of 0 is declared, it is forcibly
6411 assigned to the next storage unit.
6412
6413 e.g)
6414 struct {
6415 int a:2;
6416 int b:6;
6417 char c:4;
6418 int d:10;
6419 int :0;
6420 int f:2;
6421 } x;
6422
6423 +0 +1 +2 +3
6424 &x 00000000 00000000 00000000 00000000
6425 MLM----L
6426 a b
6427 &x+4 00000000 00000000 00000000 00000000
6428 M--L
6429 c
6430 &x+8 00000000 00000000 00000000 00000000
6431 M----------L
6432 d
6433 &x+12 00000000 00000000 00000000 00000000
6434 ML
6435 f
6436*/
6437
6438int
f2206911 6439frv_adjust_field_align (tree field, int computed)
36a05131 6440{
b16c1435 6441 /* Make sure that the bitfield is not wider than the type. */
a4cf4b64
RB
6442 if (field
6443 && DECL_BIT_FIELD (field)
25f93e18 6444 && !DECL_ARTIFICIAL (field))
36a05131
BS
6445 {
6446 tree parent = DECL_CONTEXT (field);
6447 tree prev = NULL_TREE;
6448 tree cur;
6449
910ad8de 6450 for (cur = TYPE_FIELDS (parent); cur && cur != field; cur = DECL_CHAIN (cur))
36a05131
BS
6451 {
6452 if (TREE_CODE (cur) != FIELD_DECL)
6453 continue;
6454
6455 prev = cur;
6456 }
6457
44e91694 6458 gcc_assert (cur);
36a05131
BS
6459
6460 /* If this isn't a :0 field and if the previous element is a bitfield
6461 also, see if the type is different, if so, we will need to align the
87b483a1 6462 bit-field to the next boundary. */
36a05131
BS
6463 if (prev
6464 && ! DECL_PACKED (field)
6465 && ! integer_zerop (DECL_SIZE (field))
6466 && DECL_BIT_FIELD_TYPE (field) != DECL_BIT_FIELD_TYPE (prev))
6467 {
6468 int prev_align = TYPE_ALIGN (TREE_TYPE (prev));
6469 int cur_align = TYPE_ALIGN (TREE_TYPE (field));
6470 computed = (prev_align > cur_align) ? prev_align : cur_align;
6471 }
6472 }
6473
6474 return computed;
6475}
6476
6477\f
f939c3e6 6478/* Implement TARGET_HARD_REGNO_MODE_OK. */
36a05131 6479
f939c3e6
RS
6480static bool
6481frv_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
36a05131
BS
6482{
6483 int base;
6484 int mask;
6485
6486 switch (mode)
6487 {
4e10a5a7
RS
6488 case E_CCmode:
6489 case E_CC_UNSmode:
6490 case E_CC_NZmode:
36a05131
BS
6491 return ICC_P (regno) || GPR_P (regno);
6492
4e10a5a7 6493 case E_CC_CCRmode:
36a05131
BS
6494 return CR_P (regno) || GPR_P (regno);
6495
4e10a5a7 6496 case E_CC_FPmode:
36a05131
BS
6497 return FCC_P (regno) || GPR_P (regno);
6498
6499 default:
6500 break;
6501 }
6502
6503 /* Set BASE to the first register in REGNO's class. Set MASK to the
6504 bits that must be clear in (REGNO - BASE) for the register to be
6505 well-aligned. */
6506 if (INTEGRAL_MODE_P (mode) || FLOAT_MODE_P (mode) || VECTOR_MODE_P (mode))
6507 {
6508 if (ACCG_P (regno))
6509 {
6510 /* ACCGs store one byte. Two-byte quantities must start in
6511 even-numbered registers, four-byte ones in registers whose
6512 numbers are divisible by four, and so on. */
6513 base = ACCG_FIRST;
6514 mask = GET_MODE_SIZE (mode) - 1;
6515 }
6516 else
6517 {
b16c1435
EC
6518 /* The other registers store one word. */
6519 if (GPR_P (regno) || regno == AP_FIRST)
36a05131
BS
6520 base = GPR_FIRST;
6521
6522 else if (FPR_P (regno))
6523 base = FPR_FIRST;
6524
6525 else if (ACC_P (regno))
6526 base = ACC_FIRST;
6527
b16c1435
EC
6528 else if (SPR_P (regno))
6529 return mode == SImode;
6530
87b483a1 6531 /* Fill in the table. */
36a05131 6532 else
f939c3e6 6533 return false;
36a05131
BS
6534
6535 /* Anything smaller than an SI is OK in any word-sized register. */
6536 if (GET_MODE_SIZE (mode) < 4)
f939c3e6 6537 return true;
36a05131
BS
6538
6539 mask = (GET_MODE_SIZE (mode) / 4) - 1;
6540 }
6541 return (((regno - base) & mask) == 0);
6542 }
6543
f939c3e6 6544 return false;
36a05131
BS
6545}
6546
99e1629f
RS
6547/* Implement TARGET_MODES_TIEABLE_P. */
6548
6549static bool
6550frv_modes_tieable_p (machine_mode mode1, machine_mode mode2)
6551{
6552 return mode1 == mode2;
6553}
6554
36a05131 6555\f
c43f4279 6556/* Implement TARGET_HARD_REGNO_NREGS.
36a05131 6557
c43f4279 6558 On the FRV, make the CC_FP mode take 3 words in the integer registers, so
36a05131
BS
6559 that we can build the appropriate instructions to properly reload the
6560 values. Also, make the byte-sized accumulator guards use one guard
6561 for each byte. */
6562
c43f4279
RS
6563static unsigned int
6564frv_hard_regno_nregs (unsigned int regno, machine_mode mode)
36a05131
BS
6565{
6566 if (ACCG_P (regno))
6567 return GET_MODE_SIZE (mode);
6568 else
6569 return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
6570}
6571
6572\f
c43f4279 6573/* Implement CLASS_MAX_NREGS. */
36a05131
BS
6574
6575int
ef4bddc2 6576frv_class_max_nregs (enum reg_class rclass, machine_mode mode)
36a05131 6577{
0a2aaacc 6578 if (rclass == ACCG_REGS)
36a05131
BS
6579 /* An N-byte value requires N accumulator guards. */
6580 return GET_MODE_SIZE (mode);
6581 else
6582 return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
6583}
6584
6585\f
6586/* A C expression that is nonzero if X is a legitimate constant for an
6587 immediate operand on the target machine. You can assume that X satisfies
6588 `CONSTANT_P', so you need not check this. In fact, `1' is a suitable
6589 definition for this macro on machines where anything `CONSTANT_P' is valid. */
6590
1a627b35 6591static bool
ef4bddc2 6592frv_legitimate_constant_p (machine_mode mode, rtx x)
36a05131 6593{
34208acf
AO
6594 /* frv_cannot_force_const_mem always returns true for FDPIC. This
6595 means that the move expanders will be expected to deal with most
6596 kinds of constant, regardless of what we return here.
6597
1a627b35 6598 However, among its other duties, frv_legitimate_constant_p decides whether
34208acf
AO
6599 a constant can be entered into reg_equiv_constant[]. If we return true,
6600 reload can create new instances of the constant whenever it likes.
6601
6602 The idea is therefore to accept as many constants as possible (to give
6603 reload more freedom) while rejecting constants that can only be created
6604 at certain times. In particular, anything with a symbolic component will
6605 require use of the pseudo FDPIC register, which is only available before
6606 reload. */
6607 if (TARGET_FDPIC)
6608 return LEGITIMATE_PIC_OPERAND_P (x);
6609
87b483a1 6610 /* All of the integer constants are ok. */
36a05131
BS
6611 if (GET_CODE (x) != CONST_DOUBLE)
6612 return TRUE;
6613
87b483a1 6614 /* double integer constants are ok. */
1a627b35 6615 if (GET_MODE (x) == VOIDmode || mode == DImode)
36a05131
BS
6616 return TRUE;
6617
87b483a1 6618 /* 0 is always ok. */
36a05131
BS
6619 if (x == CONST0_RTX (mode))
6620 return TRUE;
6621
6622 /* If floating point is just emulated, allow any constant, since it will be
87b483a1 6623 constructed in the GPRs. */
36a05131
BS
6624 if (!TARGET_HAS_FPRS)
6625 return TRUE;
6626
6627 if (mode == DFmode && !TARGET_DOUBLE)
6628 return TRUE;
6629
6630 /* Otherwise store the constant away and do a load. */
6631 return FALSE;
6632}
036ff63f
RS
6633
6634/* Implement SELECT_CC_MODE. Choose CC_FP for floating-point comparisons,
6635 CC_NZ for comparisons against zero in which a single Z or N flag test
6636 is enough, CC_UNS for other unsigned comparisons, and CC for other
6637 signed comparisons. */
6638
ef4bddc2 6639machine_mode
036ff63f
RS
6640frv_select_cc_mode (enum rtx_code code, rtx x, rtx y)
6641{
6642 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
6643 return CC_FPmode;
6644
6645 switch (code)
6646 {
6647 case EQ:
6648 case NE:
6649 case LT:
6650 case GE:
6651 return y == const0_rtx ? CC_NZmode : CCmode;
6652
6653 case GTU:
6654 case GEU:
6655 case LTU:
6656 case LEU:
6657 return y == const0_rtx ? CC_NZmode : CC_UNSmode;
6658
6659 default:
6660 return CCmode;
6661 }
6662}
36a05131 6663\f
33124e84
AS
6664
6665/* Worker function for TARGET_REGISTER_MOVE_COST. */
36a05131
BS
6666
6667#define HIGH_COST 40
6668#define MEDIUM_COST 3
6669#define LOW_COST 1
6670
33124e84 6671static int
ef4bddc2 6672frv_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
33124e84 6673 reg_class_t from, reg_class_t to)
36a05131
BS
6674{
6675 switch (from)
6676 {
6677 default:
6678 break;
6679
6680 case QUAD_REGS:
36a05131 6681 case GPR_REGS:
73d7e266
VM
6682 case GR8_REGS:
6683 case GR9_REGS:
6684 case GR89_REGS:
6685 case FDPIC_REGS:
6686 case FDPIC_FPTR_REGS:
6687 case FDPIC_CALL_REGS:
6688
36a05131
BS
6689 switch (to)
6690 {
6691 default:
6692 break;
6693
9b5db25d 6694 case QUAD_REGS:
36a05131 6695 case GPR_REGS:
73d7e266
VM
6696 case GR8_REGS:
6697 case GR9_REGS:
6698 case GR89_REGS:
6699 case FDPIC_REGS:
6700 case FDPIC_FPTR_REGS:
6701 case FDPIC_CALL_REGS:
6702
36a05131
BS
6703 return LOW_COST;
6704
36a05131
BS
6705 case FPR_REGS:
6706 return LOW_COST;
6707
6708 case LCR_REG:
6709 case LR_REG:
6710 case SPR_REGS:
6711 return LOW_COST;
6712 }
6713
9b5db25d 6714 case QUAD_FPR_REGS:
36a05131
BS
6715 switch (to)
6716 {
6717 default:
6718 break;
6719
6720 case QUAD_REGS:
36a05131 6721 case GPR_REGS:
73d7e266
VM
6722 case GR8_REGS:
6723 case GR9_REGS:
6724 case GR89_REGS:
6725 case FDPIC_REGS:
6726 case FDPIC_FPTR_REGS:
6727 case FDPIC_CALL_REGS:
6728
36a05131
BS
6729 case QUAD_ACC_REGS:
6730 case ACCG_REGS:
6731 return MEDIUM_COST;
6732
9b5db25d 6733 case QUAD_FPR_REGS:
36a05131
BS
6734 return LOW_COST;
6735 }
6736
6737 case LCR_REG:
6738 case LR_REG:
6739 case SPR_REGS:
6740 switch (to)
6741 {
6742 default:
6743 break;
6744
6745 case QUAD_REGS:
36a05131 6746 case GPR_REGS:
73d7e266
VM
6747 case GR8_REGS:
6748 case GR9_REGS:
6749 case GR89_REGS:
6750 case FDPIC_REGS:
6751 case FDPIC_FPTR_REGS:
6752 case FDPIC_CALL_REGS:
6753
36a05131
BS
6754 return MEDIUM_COST;
6755 }
6756
36a05131
BS
6757 case QUAD_ACC_REGS:
6758 case ACCG_REGS:
6759 switch (to)
6760 {
6761 default:
6762 break;
6763
9b5db25d 6764 case QUAD_FPR_REGS:
36a05131
BS
6765 return MEDIUM_COST;
6766
6767 }
6768 }
6769
6770 return HIGH_COST;
6771}
33124e84
AS
6772
6773/* Worker function for TARGET_MEMORY_MOVE_COST. */
6774
6775static int
ef4bddc2 6776frv_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
33124e84
AS
6777 reg_class_t rclass ATTRIBUTE_UNUSED,
6778 bool in ATTRIBUTE_UNUSED)
6779{
6780 return 4;
6781}
6782
36a05131
BS
6783\f
6784/* Implementation of TARGET_ASM_INTEGER. In the FRV case we need to
6785 use ".picptr" to generate safe relocations for PIC code. We also
6786 need a fixup entry for aligned (non-debugging) code. */
6787
6788static bool
f2206911 6789frv_assemble_integer (rtx value, unsigned int size, int aligned_p)
36a05131 6790{
34208acf 6791 if ((flag_pic || TARGET_FDPIC) && size == UNITS_PER_WORD)
36a05131
BS
6792 {
6793 if (GET_CODE (value) == CONST
6794 || GET_CODE (value) == SYMBOL_REF
6795 || GET_CODE (value) == LABEL_REF)
6796 {
34208acf
AO
6797 if (TARGET_FDPIC && GET_CODE (value) == SYMBOL_REF
6798 && SYMBOL_REF_FUNCTION_P (value))
6799 {
6800 fputs ("\t.picptr\tfuncdesc(", asm_out_file);
6801 output_addr_const (asm_out_file, value);
6802 fputs (")\n", asm_out_file);
6803 return true;
6804 }
6805 else if (TARGET_FDPIC && GET_CODE (value) == CONST
6806 && frv_function_symbol_referenced_p (value))
6807 return false;
6808 if (aligned_p && !TARGET_FDPIC)
36a05131
BS
6809 {
6810 static int label_num = 0;
6811 char buf[256];
6812 const char *p;
6813
6814 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", label_num++);
14966b94 6815 p = (* targetm.strip_name_encoding) (buf);
36a05131
BS
6816
6817 fprintf (asm_out_file, "%s:\n", p);
6818 fprintf (asm_out_file, "%s\n", FIXUP_SECTION_ASM_OP);
6819 fprintf (asm_out_file, "\t.picptr\t%s\n", p);
6820 fprintf (asm_out_file, "\t.previous\n");
6821 }
6822 assemble_integer_with_op ("\t.picptr\t", value);
6823 return true;
6824 }
6825 if (!aligned_p)
6826 {
6827 /* We've set the unaligned SI op to NULL, so we always have to
6828 handle the unaligned case here. */
6829 assemble_integer_with_op ("\t.4byte\t", value);
6830 return true;
6831 }
6832 }
6833 return default_assemble_integer (value, size, aligned_p);
6834}
6835
6836/* Function to set up the backend function structure. */
6837
6838static struct machine_function *
f2206911 6839frv_init_machine_status (void)
36a05131 6840{
766090c2 6841 return ggc_cleared_alloc<machine_function> ();
36a05131 6842}
ffb344c1 6843\f
28a60850
RS
6844/* Implement TARGET_SCHED_ISSUE_RATE. */
6845
c557edf4 6846int
28a60850
RS
6847frv_issue_rate (void)
6848{
6849 if (!TARGET_PACK)
6850 return 1;
6851
6852 switch (frv_cpu_type)
6853 {
6854 default:
6855 case FRV_CPU_FR300:
6856 case FRV_CPU_SIMPLE:
6857 return 1;
6858
6859 case FRV_CPU_FR400:
c557edf4
RS
6860 case FRV_CPU_FR405:
6861 case FRV_CPU_FR450:
28a60850
RS
6862 return 2;
6863
6864 case FRV_CPU_GENERIC:
6865 case FRV_CPU_FR500:
6866 case FRV_CPU_TOMCAT:
6867 return 4;
c557edf4
RS
6868
6869 case FRV_CPU_FR550:
6870 return 8;
28a60850
RS
6871 }
6872}
36a05131 6873\f
c557edf4 6874/* Return the value of INSN's acc_group attribute. */
36a05131 6875
c557edf4
RS
6876int
6877frv_acc_group (rtx insn)
6878{
6879 /* This distinction only applies to the FR550 packing constraints. */
cc665e56
RS
6880 if (frv_cpu_type == FRV_CPU_FR550)
6881 {
6882 subrtx_iterator::array_type array;
6883 FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
6884 if (REG_P (*iter))
6885 {
6886 unsigned int regno = REGNO (*iter);
6887 /* If REGNO refers to an accumulator, return ACC_GROUP_ODD if
6888 the bit 2 of the register number is set and ACC_GROUP_EVEN if
6889 it is clear. */
6890 if (ACC_P (regno))
6891 return (regno - ACC_FIRST) & 4 ? ACC_GROUP_ODD : ACC_GROUP_EVEN;
6892 if (ACCG_P (regno))
6893 return (regno - ACCG_FIRST) & 4 ? ACC_GROUP_ODD : ACC_GROUP_EVEN;
6894 }
6895 }
6896 return ACC_GROUP_NONE;
c557edf4 6897}
36a05131 6898
c557edf4
RS
6899/* Return the index of the DFA unit in FRV_UNIT_NAMES[] that instruction
6900 INSN will try to claim first. Since this value depends only on the
6901 type attribute, we can cache the results in FRV_TYPE_TO_UNIT[]. */
36a05131 6902
c557edf4 6903static unsigned int
84034c69 6904frv_insn_unit (rtx_insn *insn)
c557edf4
RS
6905{
6906 enum attr_type type;
36a05131 6907
c557edf4
RS
6908 type = get_attr_type (insn);
6909 if (frv_type_to_unit[type] == ARRAY_SIZE (frv_unit_codes))
6910 {
6911 /* We haven't seen this type of instruction before. */
6912 state_t state;
6913 unsigned int unit;
36a05131 6914
c557edf4
RS
6915 /* Issue the instruction on its own to see which unit it prefers. */
6916 state = alloca (state_size ());
6917 state_reset (state);
6918 state_transition (state, insn);
36a05131 6919
c557edf4
RS
6920 /* Find out which unit was taken. */
6921 for (unit = 0; unit < ARRAY_SIZE (frv_unit_codes); unit++)
6922 if (cpu_unit_reservation_p (state, frv_unit_codes[unit]))
6923 break;
36a05131 6924
44e91694 6925 gcc_assert (unit != ARRAY_SIZE (frv_unit_codes));
36a05131 6926
c557edf4 6927 frv_type_to_unit[type] = unit;
36a05131 6928 }
c557edf4
RS
6929 return frv_type_to_unit[type];
6930}
36a05131 6931
c557edf4 6932/* Return true if INSN issues to a branch unit. */
36a05131 6933
c557edf4 6934static bool
84034c69 6935frv_issues_to_branch_unit_p (rtx_insn *insn)
c557edf4
RS
6936{
6937 return frv_unit_groups[frv_insn_unit (insn)] == GROUP_B;
6938}
6939\f
5c5e8419
JR
6940/* The instructions in the packet, partitioned into groups. */
6941struct frv_packet_group {
6942 /* How many instructions in the packet belong to this group. */
6943 unsigned int num_insns;
6944
6945 /* A list of the instructions that belong to this group, in the order
6946 they appear in the rtl stream. */
b32d5189 6947 rtx_insn *insns[ARRAY_SIZE (frv_unit_codes)];
5c5e8419
JR
6948
6949 /* The contents of INSNS after they have been sorted into the correct
6950 assembly-language order. Element X issues to unit X. The list may
6951 contain extra nops. */
b32d5189 6952 rtx_insn *sorted[ARRAY_SIZE (frv_unit_codes)];
5c5e8419
JR
6953
6954 /* The member of frv_nops[] to use in sorted[]. */
b32d5189 6955 rtx_insn *nop;
5c5e8419
JR
6956};
6957
c557edf4
RS
6958/* The current state of the packing pass, implemented by frv_pack_insns. */
6959static struct {
6960 /* The state of the pipeline DFA. */
6961 state_t dfa_state;
6962
6963 /* Which hardware registers are set within the current packet,
6964 and the conditions under which they are set. */
6965 regstate_t regstate[FIRST_PSEUDO_REGISTER];
6966
6967 /* The memory locations that have been modified so far in this
6968 packet. MEM is the memref and COND is the regstate_t condition
6969 under which it is set. */
6970 struct {
6971 rtx mem;
6972 regstate_t cond;
6973 } mems[2];
6974
6975 /* The number of valid entries in MEMS. The value is larger than
6976 ARRAY_SIZE (mems) if there were too many mems to record. */
6977 unsigned int num_mems;
6978
6979 /* The maximum number of instructions that can be packed together. */
6980 unsigned int issue_rate;
6981
6982 /* The instructions in the packet, partitioned into groups. */
5c5e8419 6983 struct frv_packet_group groups[NUM_GROUPS];
c557edf4
RS
6984
6985 /* The instructions that make up the current packet. */
b32d5189 6986 rtx_insn *insns[ARRAY_SIZE (frv_unit_codes)];
c557edf4
RS
6987 unsigned int num_insns;
6988} frv_packet;
6989
6990/* Return the regstate_t flags for the given COND_EXEC condition.
6991 Abort if the condition isn't in the right form. */
36a05131 6992
c557edf4
RS
6993static int
6994frv_cond_flags (rtx cond)
6995{
44e91694
NS
6996 gcc_assert ((GET_CODE (cond) == EQ || GET_CODE (cond) == NE)
6997 && GET_CODE (XEXP (cond, 0)) == REG
6998 && CR_P (REGNO (XEXP (cond, 0)))
6999 && XEXP (cond, 1) == const0_rtx);
7000 return ((REGNO (XEXP (cond, 0)) - CR_FIRST)
7001 | (GET_CODE (cond) == NE
7002 ? REGSTATE_IF_TRUE
7003 : REGSTATE_IF_FALSE));
c557edf4 7004}
36a05131 7005
36a05131 7006
c557edf4
RS
7007/* Return true if something accessed under condition COND2 can
7008 conflict with something written under condition COND1. */
36a05131 7009
c557edf4
RS
7010static bool
7011frv_regstate_conflict_p (regstate_t cond1, regstate_t cond2)
7012{
7013 /* If either reference was unconditional, we have a conflict. */
7014 if ((cond1 & REGSTATE_IF_EITHER) == 0
7015 || (cond2 & REGSTATE_IF_EITHER) == 0)
7016 return true;
7017
7018 /* The references might conflict if they were controlled by
7019 different CRs. */
7020 if ((cond1 & REGSTATE_CC_MASK) != (cond2 & REGSTATE_CC_MASK))
7021 return true;
7022
7023 /* They definitely conflict if they are controlled by the
7024 same condition. */
7025 if ((cond1 & cond2 & REGSTATE_IF_EITHER) != 0)
7026 return true;
7027
7028 return false;
36a05131
BS
7029}
7030
c557edf4 7031
cc6b9196
RS
7032/* Return true if an instruction with pattern PAT depends on an
7033 instruction in the current packet. COND describes the condition
7034 under which PAT might be set or used. */
36a05131 7035
cc6b9196
RS
7036static bool
7037frv_registers_conflict_p_1 (rtx pat, regstate_t cond)
36a05131 7038{
cc6b9196
RS
7039 subrtx_var_iterator::array_type array;
7040 FOR_EACH_SUBRTX_VAR (iter, array, pat, NONCONST)
c557edf4 7041 {
cc6b9196
RS
7042 rtx x = *iter;
7043 if (GET_CODE (x) == REG)
7044 {
7045 unsigned int regno;
7046 FOR_EACH_REGNO (regno, x)
7047 if ((frv_packet.regstate[regno] & REGSTATE_MODIFIED) != 0)
7048 if (frv_regstate_conflict_p (frv_packet.regstate[regno], cond))
7049 return true;
7050 }
7051 else if (GET_CODE (x) == MEM)
7052 {
7053 /* If we ran out of memory slots, assume a conflict. */
7054 if (frv_packet.num_mems > ARRAY_SIZE (frv_packet.mems))
7055 return 1;
36a05131 7056
cc6b9196
RS
7057 /* Check for output or true dependencies with earlier MEMs. */
7058 for (unsigned int i = 0; i < frv_packet.num_mems; i++)
7059 if (frv_regstate_conflict_p (frv_packet.mems[i].cond, cond))
7060 {
7061 if (true_dependence (frv_packet.mems[i].mem, VOIDmode, x))
7062 return true;
36a05131 7063
cc6b9196
RS
7064 if (output_dependence (frv_packet.mems[i].mem, x))
7065 return true;
7066 }
7067 }
36a05131 7068
cc6b9196
RS
7069 /* The return values of calls aren't significant: they describe
7070 the effect of the call as a whole, not of the insn itself. */
7071 else if (GET_CODE (x) == SET && GET_CODE (SET_SRC (x)) == CALL)
7072 iter.substitute (SET_SRC (x));
c557edf4 7073 }
cc6b9196 7074 return false;
c557edf4 7075}
36a05131 7076
36a05131 7077
c557edf4
RS
7078/* Return true if something in X might depend on an instruction
7079 in the current packet. */
36a05131 7080
c557edf4
RS
7081static bool
7082frv_registers_conflict_p (rtx x)
7083{
7084 regstate_t flags;
36a05131 7085
c557edf4
RS
7086 flags = 0;
7087 if (GET_CODE (x) == COND_EXEC)
7088 {
cc6b9196 7089 if (frv_registers_conflict_p_1 (XEXP (x, 0), flags))
c557edf4 7090 return true;
36a05131 7091
c557edf4
RS
7092 flags |= frv_cond_flags (XEXP (x, 0));
7093 x = XEXP (x, 1);
36a05131 7094 }
cc6b9196 7095 return frv_registers_conflict_p_1 (x, flags);
c557edf4 7096}
36a05131
BS
7097
7098
c557edf4
RS
7099/* A note_stores callback. DATA points to the regstate_t condition
7100 under which X is modified. Update FRV_PACKET accordingly. */
36a05131 7101
c557edf4 7102static void
7bc980e1 7103frv_registers_update_1 (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data)
c557edf4
RS
7104{
7105 unsigned int regno;
7106
7107 if (GET_CODE (x) == REG)
7108 FOR_EACH_REGNO (regno, x)
7109 frv_packet.regstate[regno] |= *(regstate_t *) data;
7110
7111 if (GET_CODE (x) == MEM)
36a05131 7112 {
c557edf4 7113 if (frv_packet.num_mems < ARRAY_SIZE (frv_packet.mems))
36a05131 7114 {
c557edf4
RS
7115 frv_packet.mems[frv_packet.num_mems].mem = x;
7116 frv_packet.mems[frv_packet.num_mems].cond = *(regstate_t *) data;
7117 }
7118 frv_packet.num_mems++;
7119 }
7120}
36a05131 7121
36a05131 7122
c557edf4
RS
7123/* Update the register state information for an instruction whose
7124 body is X. */
7125
7126static void
7127frv_registers_update (rtx x)
7128{
7129 regstate_t flags;
7130
7131 flags = REGSTATE_MODIFIED;
7132 if (GET_CODE (x) == COND_EXEC)
7133 {
7134 flags |= frv_cond_flags (XEXP (x, 0));
7135 x = XEXP (x, 1);
36a05131 7136 }
e8448ba5 7137 note_pattern_stores (x, frv_registers_update_1, &flags);
c557edf4 7138}
36a05131 7139
c557edf4
RS
7140
7141/* Initialize frv_packet for the start of a new packet. */
7142
7143static void
7144frv_start_packet (void)
7145{
7146 enum frv_insn_group group;
7147
7148 memset (frv_packet.regstate, 0, sizeof (frv_packet.regstate));
7149 frv_packet.num_mems = 0;
7150 frv_packet.num_insns = 0;
5c5e8419
JR
7151 for (group = GROUP_I; group < NUM_GROUPS;
7152 group = (enum frv_insn_group) (group + 1))
c557edf4 7153 frv_packet.groups[group].num_insns = 0;
36a05131
BS
7154}
7155
36a05131 7156
c557edf4
RS
7157/* Likewise for the start of a new basic block. */
7158
7159static void
7160frv_start_packet_block (void)
36a05131 7161{
c557edf4
RS
7162 state_reset (frv_packet.dfa_state);
7163 frv_start_packet ();
7164}
36a05131 7165
c557edf4
RS
7166
7167/* Finish the current packet, if any, and start a new one. Call
7168 HANDLE_PACKET with FRV_PACKET describing the completed packet. */
7169
7170static void
7171frv_finish_packet (void (*handle_packet) (void))
7172{
7173 if (frv_packet.num_insns > 0)
36a05131 7174 {
c557edf4
RS
7175 handle_packet ();
7176 state_transition (frv_packet.dfa_state, 0);
7177 frv_start_packet ();
7178 }
7179}
36a05131 7180
36a05131 7181
c557edf4
RS
7182/* Return true if INSN can be added to the current packet. Update
7183 the DFA state on success. */
36a05131 7184
c557edf4 7185static bool
84034c69 7186frv_pack_insn_p (rtx_insn *insn)
c557edf4
RS
7187{
7188 /* See if the packet is already as long as it can be. */
7189 if (frv_packet.num_insns == frv_packet.issue_rate)
7190 return false;
36a05131 7191
c557edf4
RS
7192 /* If the scheduler thought that an instruction should start a packet,
7193 it's usually a good idea to believe it. It knows much more about
7194 the latencies than we do.
36a05131 7195
c557edf4 7196 There are some exceptions though:
36a05131 7197
c557edf4
RS
7198 - Conditional instructions are scheduled on the assumption that
7199 they will be executed. This is usually a good thing, since it
c112cf2b 7200 tends to avoid unnecessary stalls in the conditional code.
c557edf4
RS
7201 But we want to pack conditional instructions as tightly as
7202 possible, in order to optimize the case where they aren't
7203 executed.
36a05131 7204
c557edf4
RS
7205 - The scheduler will always put branches on their own, even
7206 if there's no real dependency.
36a05131 7207
c557edf4
RS
7208 - There's no point putting a call in its own packet unless
7209 we have to. */
7210 if (frv_packet.num_insns > 0
b64925dc 7211 && NONJUMP_INSN_P (insn)
c557edf4
RS
7212 && GET_MODE (insn) == TImode
7213 && GET_CODE (PATTERN (insn)) != COND_EXEC)
7214 return false;
36a05131 7215
c557edf4
RS
7216 /* Check for register conflicts. Don't do this for setlo since any
7217 conflict will be with the partnering sethi, with which it can
7218 be packed. */
7219 if (get_attr_type (insn) != TYPE_SETLO)
7220 if (frv_registers_conflict_p (PATTERN (insn)))
7221 return false;
36a05131 7222
c557edf4
RS
7223 return state_transition (frv_packet.dfa_state, insn) < 0;
7224}
36a05131 7225
36a05131 7226
c557edf4 7227/* Add instruction INSN to the current packet. */
36a05131 7228
c557edf4 7229static void
b32d5189 7230frv_add_insn_to_packet (rtx_insn *insn)
c557edf4
RS
7231{
7232 struct frv_packet_group *packet_group;
7233
7234 packet_group = &frv_packet.groups[frv_unit_groups[frv_insn_unit (insn)]];
7235 packet_group->insns[packet_group->num_insns++] = insn;
7236 frv_packet.insns[frv_packet.num_insns++] = insn;
7237
7238 frv_registers_update (PATTERN (insn));
36a05131
BS
7239}
7240
c557edf4
RS
7241
7242/* Insert INSN (a member of frv_nops[]) into the current packet. If the
7243 packet ends in a branch or call, insert the nop before it, otherwise
7244 add to the end. */
36a05131
BS
7245
7246static void
b32d5189 7247frv_insert_nop_in_packet (rtx_insn *insn)
36a05131 7248{
c557edf4 7249 struct frv_packet_group *packet_group;
b32d5189 7250 rtx_insn *last;
c557edf4
RS
7251
7252 packet_group = &frv_packet.groups[frv_unit_groups[frv_insn_unit (insn)]];
7253 last = frv_packet.insns[frv_packet.num_insns - 1];
b64925dc 7254 if (! NONJUMP_INSN_P (last))
c557edf4
RS
7255 {
7256 insn = emit_insn_before (PATTERN (insn), last);
7257 frv_packet.insns[frv_packet.num_insns - 1] = insn;
7258 frv_packet.insns[frv_packet.num_insns++] = last;
7259 }
7260 else
7261 {
7262 insn = emit_insn_after (PATTERN (insn), last);
7263 frv_packet.insns[frv_packet.num_insns++] = insn;
7264 }
7265 packet_group->insns[packet_group->num_insns++] = insn;
7266}
7267
36a05131 7268
c557edf4
RS
7269/* If packing is enabled, divide the instructions into packets and
7270 return true. Call HANDLE_PACKET for each complete packet. */
7271
7272static bool
7273frv_for_each_packet (void (*handle_packet) (void))
7274{
b32d5189 7275 rtx_insn *insn, *next_insn;
c557edf4
RS
7276
7277 frv_packet.issue_rate = frv_issue_rate ();
7278
7279 /* Early exit if we don't want to pack insns. */
28a60850
RS
7280 if (!optimize
7281 || !flag_schedule_insns_after_reload
0b2c18fe 7282 || !TARGET_VLIW_BRANCH
c557edf4
RS
7283 || frv_packet.issue_rate == 1)
7284 return false;
36a05131 7285
c557edf4 7286 /* Set up the initial packing state. */
36a05131 7287 dfa_start ();
c557edf4 7288 frv_packet.dfa_state = alloca (state_size ());
36a05131 7289
c557edf4
RS
7290 frv_start_packet_block ();
7291 for (insn = get_insns (); insn != 0; insn = next_insn)
36a05131 7292 {
c557edf4
RS
7293 enum rtx_code code;
7294 bool eh_insn_p;
36a05131 7295
c557edf4
RS
7296 code = GET_CODE (insn);
7297 next_insn = NEXT_INSN (insn);
7298
7299 if (code == CODE_LABEL)
36a05131 7300 {
c557edf4
RS
7301 frv_finish_packet (handle_packet);
7302 frv_start_packet_block ();
7303 }
36a05131 7304
39718607 7305 if (INSN_P (insn))
c557edf4
RS
7306 switch (GET_CODE (PATTERN (insn)))
7307 {
7308 case USE:
7309 case CLOBBER:
c557edf4 7310 break;
36a05131 7311
c557edf4
RS
7312 default:
7313 /* Calls mustn't be packed on a TOMCAT. */
b64925dc 7314 if (CALL_P (insn) && frv_cpu_type == FRV_CPU_TOMCAT)
c557edf4
RS
7315 frv_finish_packet (handle_packet);
7316
7317 /* Since the last instruction in a packet determines the EH
7318 region, any exception-throwing instruction must come at
7319 the end of reordered packet. Insns that issue to a
7320 branch unit are bound to come last; for others it's
7321 too hard to predict. */
7322 eh_insn_p = (find_reg_note (insn, REG_EH_REGION, NULL) != NULL);
7323 if (eh_insn_p && !frv_issues_to_branch_unit_p (insn))
7324 frv_finish_packet (handle_packet);
7325
7326 /* Finish the current packet if we can't add INSN to it.
7327 Simulate cycles until INSN is ready to issue. */
7328 if (!frv_pack_insn_p (insn))
7329 {
7330 frv_finish_packet (handle_packet);
7331 while (!frv_pack_insn_p (insn))
7332 state_transition (frv_packet.dfa_state, 0);
7333 }
36a05131 7334
c557edf4
RS
7335 /* Add the instruction to the packet. */
7336 frv_add_insn_to_packet (insn);
7337
7338 /* Calls and jumps end a packet, as do insns that throw
7339 an exception. */
7340 if (code == CALL_INSN || code == JUMP_INSN || eh_insn_p)
7341 frv_finish_packet (handle_packet);
7342 break;
7343 }
7344 }
7345 frv_finish_packet (handle_packet);
7346 dfa_finish ();
7347 return true;
7348}
7349\f
7350/* Subroutine of frv_sort_insn_group. We are trying to sort
7351 frv_packet.groups[GROUP].sorted[0...NUM_INSNS-1] into assembly
7352 language order. We have already picked a new position for
7353 frv_packet.groups[GROUP].sorted[X] if bit X of ISSUED is set.
7354 These instructions will occupy elements [0, LOWER_SLOT) and
7355 [UPPER_SLOT, NUM_INSNS) of the final (sorted) array. STATE is
7356 the DFA state after issuing these instructions.
7357
7358 Try filling elements [LOWER_SLOT, UPPER_SLOT) with every permutation
7359 of the unused instructions. Return true if one such permutation gives
7360 a valid ordering, leaving the successful permutation in sorted[].
7361 Do not modify sorted[] until a valid permutation is found. */
7362
7363static bool
7364frv_sort_insn_group_1 (enum frv_insn_group group,
7365 unsigned int lower_slot, unsigned int upper_slot,
7366 unsigned int issued, unsigned int num_insns,
7367 state_t state)
7368{
7369 struct frv_packet_group *packet_group;
7370 unsigned int i;
7371 state_t test_state;
7372 size_t dfa_size;
b32d5189 7373 rtx_insn *insn;
c557edf4
RS
7374
7375 /* Early success if we've filled all the slots. */
7376 if (lower_slot == upper_slot)
7377 return true;
7378
7379 packet_group = &frv_packet.groups[group];
7380 dfa_size = state_size ();
7381 test_state = alloca (dfa_size);
7382
7383 /* Try issuing each unused instruction. */
7384 for (i = num_insns - 1; i + 1 != 0; i--)
7385 if (~issued & (1 << i))
7386 {
7387 insn = packet_group->sorted[i];
7388 memcpy (test_state, state, dfa_size);
7389 if (state_transition (test_state, insn) < 0
7390 && cpu_unit_reservation_p (test_state,
7391 NTH_UNIT (group, upper_slot - 1))
7392 && frv_sort_insn_group_1 (group, lower_slot, upper_slot - 1,
7393 issued | (1 << i), num_insns,
7394 test_state))
7395 {
7396 packet_group->sorted[upper_slot - 1] = insn;
7397 return true;
7398 }
7399 }
7400
7401 return false;
7402}
7403
7404/* Compare two instructions by their frv_insn_unit. */
7405
7406static int
7407frv_compare_insns (const void *first, const void *second)
7408{
84034c69
DM
7409 rtx_insn * const *insn1 = (rtx_insn * const *) first;
7410 rtx_insn * const *insn2 = (rtx_insn * const *) second;
c557edf4
RS
7411 return frv_insn_unit (*insn1) - frv_insn_unit (*insn2);
7412}
7413
7414/* Copy frv_packet.groups[GROUP].insns[] to frv_packet.groups[GROUP].sorted[]
7415 and sort it into assembly language order. See frv.md for a description of
7416 the algorithm. */
7417
7418static void
7419frv_sort_insn_group (enum frv_insn_group group)
7420{
7421 struct frv_packet_group *packet_group;
7422 unsigned int first, i, nop, max_unit, num_slots;
7423 state_t state, test_state;
7424 size_t dfa_size;
7425
7426 packet_group = &frv_packet.groups[group];
75d0ac8d
RS
7427
7428 /* Assume no nop is needed. */
7429 packet_group->nop = 0;
7430
c557edf4
RS
7431 if (packet_group->num_insns == 0)
7432 return;
7433
7434 /* Copy insns[] to sorted[]. */
7435 memcpy (packet_group->sorted, packet_group->insns,
7436 sizeof (rtx) * packet_group->num_insns);
7437
7438 /* Sort sorted[] by the unit that each insn tries to take first. */
7439 if (packet_group->num_insns > 1)
7440 qsort (packet_group->sorted, packet_group->num_insns,
7441 sizeof (rtx), frv_compare_insns);
7442
7443 /* That's always enough for branch and control insns. */
7444 if (group == GROUP_B || group == GROUP_C)
7445 return;
7446
7447 dfa_size = state_size ();
7448 state = alloca (dfa_size);
7449 test_state = alloca (dfa_size);
7450
7451 /* Find the highest FIRST such that sorted[0...FIRST-1] can issue
7452 consecutively and such that the DFA takes unit X when sorted[X]
7453 is added. Set STATE to the new DFA state. */
7454 state_reset (test_state);
7455 for (first = 0; first < packet_group->num_insns; first++)
7456 {
7457 memcpy (state, test_state, dfa_size);
7458 if (state_transition (test_state, packet_group->sorted[first]) >= 0
7459 || !cpu_unit_reservation_p (test_state, NTH_UNIT (group, first)))
7460 break;
7461 }
7462
7463 /* If all the instructions issued in ascending order, we're done. */
7464 if (first == packet_group->num_insns)
7465 return;
36a05131 7466
c557edf4
RS
7467 /* Add nops to the end of sorted[] and try each permutation until
7468 we find one that works. */
7469 for (nop = 0; nop < frv_num_nops; nop++)
7470 {
7471 max_unit = frv_insn_unit (frv_nops[nop]);
7472 if (frv_unit_groups[max_unit] == group)
36a05131 7473 {
c557edf4
RS
7474 packet_group->nop = frv_nops[nop];
7475 num_slots = UNIT_NUMBER (max_unit) + 1;
7476 for (i = packet_group->num_insns; i < num_slots; i++)
7477 packet_group->sorted[i] = frv_nops[nop];
7478 if (frv_sort_insn_group_1 (group, first, num_slots,
7479 (1 << first) - 1, num_slots, state))
7480 return;
36a05131 7481 }
c557edf4 7482 }
44e91694 7483 gcc_unreachable ();
c557edf4
RS
7484}
7485\f
7486/* Sort the current packet into assembly-language order. Set packing
7487 flags as appropriate. */
36a05131 7488
c557edf4
RS
7489static void
7490frv_reorder_packet (void)
7491{
7492 unsigned int cursor[NUM_GROUPS];
9b2ea071 7493 rtx_insn *insns[ARRAY_SIZE (frv_unit_groups)];
c557edf4
RS
7494 unsigned int unit, to, from;
7495 enum frv_insn_group group;
7496 struct frv_packet_group *packet_group;
7497
7498 /* First sort each group individually. */
5c5e8419
JR
7499 for (group = GROUP_I; group < NUM_GROUPS;
7500 group = (enum frv_insn_group) (group + 1))
c557edf4
RS
7501 {
7502 cursor[group] = 0;
7503 frv_sort_insn_group (group);
7504 }
7505
7506 /* Go through the unit template and try add an instruction from
7507 that unit's group. */
7508 to = 0;
7509 for (unit = 0; unit < ARRAY_SIZE (frv_unit_groups); unit++)
7510 {
7511 group = frv_unit_groups[unit];
7512 packet_group = &frv_packet.groups[group];
7513 if (cursor[group] < packet_group->num_insns)
36a05131 7514 {
c557edf4 7515 /* frv_reorg should have added nops for us. */
44e91694
NS
7516 gcc_assert (packet_group->sorted[cursor[group]]
7517 != packet_group->nop);
c557edf4 7518 insns[to++] = packet_group->sorted[cursor[group]++];
36a05131 7519 }
c557edf4 7520 }
36a05131 7521
44e91694 7522 gcc_assert (to == frv_packet.num_insns);
36a05131 7523
c557edf4
RS
7524 /* Clear the last instruction's packing flag, thus marking the end of
7525 a packet. Reorder the other instructions relative to it. */
7526 CLEAR_PACKING_FLAG (insns[to - 1]);
7527 for (from = 0; from < to - 1; from++)
7528 {
7529 remove_insn (insns[from]);
6fb5fa3c 7530 add_insn_before (insns[from], insns[to - 1], NULL);
c557edf4
RS
7531 SET_PACKING_FLAG (insns[from]);
7532 }
7533}
36a05131 7534
36a05131 7535
c557edf4
RS
7536/* Divide instructions into packets. Reorder the contents of each
7537 packet so that they are in the correct assembly-language order.
7538
7539 Since this pass can change the raw meaning of the rtl stream, it must
7540 only be called at the last minute, just before the instructions are
7541 written out. */
7542
7543static void
7544frv_pack_insns (void)
7545{
7546 if (frv_for_each_packet (frv_reorder_packet))
7547 frv_insn_packing_flag = 0;
7548 else
7549 frv_insn_packing_flag = -1;
7550}
7551\f
7552/* See whether we need to add nops to group GROUP in order to
7553 make a valid packet. */
7554
7555static void
7556frv_fill_unused_units (enum frv_insn_group group)
7557{
7558 unsigned int non_nops, nops, i;
7559 struct frv_packet_group *packet_group;
7560
7561 packet_group = &frv_packet.groups[group];
7562
7563 /* Sort the instructions into assembly-language order.
7564 Use nops to fill slots that are otherwise unused. */
7565 frv_sort_insn_group (group);
7566
7567 /* See how many nops are needed before the final useful instruction. */
7568 i = nops = 0;
7569 for (non_nops = 0; non_nops < packet_group->num_insns; non_nops++)
7570 while (packet_group->sorted[i++] == packet_group->nop)
7571 nops++;
7572
7573 /* Insert that many nops into the instruction stream. */
7574 while (nops-- > 0)
7575 frv_insert_nop_in_packet (packet_group->nop);
7576}
7577
38c28a25
AH
7578/* Return true if accesses IO1 and IO2 refer to the same doubleword. */
7579
7580static bool
7581frv_same_doubleword_p (const struct frv_io *io1, const struct frv_io *io2)
7582{
7583 if (io1->const_address != 0 && io2->const_address != 0)
7584 return io1->const_address == io2->const_address;
7585
7586 if (io1->var_address != 0 && io2->var_address != 0)
7587 return rtx_equal_p (io1->var_address, io2->var_address);
7588
7589 return false;
7590}
7591
7592/* Return true if operations IO1 and IO2 are guaranteed to complete
7593 in order. */
7594
7595static bool
7596frv_io_fixed_order_p (const struct frv_io *io1, const struct frv_io *io2)
7597{
7598 /* The order of writes is always preserved. */
7599 if (io1->type == FRV_IO_WRITE && io2->type == FRV_IO_WRITE)
7600 return true;
7601
7602 /* The order of reads isn't preserved. */
7603 if (io1->type != FRV_IO_WRITE && io2->type != FRV_IO_WRITE)
7604 return false;
7605
7606 /* One operation is a write and the other is (or could be) a read.
7607 The order is only guaranteed if the accesses are to the same
7608 doubleword. */
7609 return frv_same_doubleword_p (io1, io2);
7610}
7611
7612/* Generalize I/O operation X so that it covers both X and Y. */
7613
7614static void
7615frv_io_union (struct frv_io *x, const struct frv_io *y)
7616{
7617 if (x->type != y->type)
7618 x->type = FRV_IO_UNKNOWN;
7619 if (!frv_same_doubleword_p (x, y))
7620 {
7621 x->const_address = 0;
7622 x->var_address = 0;
7623 }
7624}
7625
7626/* Fill IO with information about the load or store associated with
7627 membar instruction INSN. */
7628
7629static void
647d790d 7630frv_extract_membar (struct frv_io *io, rtx_insn *insn)
38c28a25
AH
7631{
7632 extract_insn (insn);
5c5e8419 7633 io->type = (enum frv_io_type) INTVAL (recog_data.operand[2]);
38c28a25
AH
7634 io->const_address = INTVAL (recog_data.operand[1]);
7635 io->var_address = XEXP (recog_data.operand[0], 0);
7636}
7637
7638/* A note_stores callback for which DATA points to an rtx. Nullify *DATA
7639 if X is a register and *DATA depends on X. */
7640
7641static void
7bc980e1 7642frv_io_check_address (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data)
38c28a25 7643{
5ead67f6 7644 rtx *other = (rtx *) data;
38c28a25
AH
7645
7646 if (REG_P (x) && *other != 0 && reg_overlap_mentioned_p (x, *other))
7647 *other = 0;
7648}
7649
7650/* A note_stores callback for which DATA points to a HARD_REG_SET.
7651 Remove every modified register from the set. */
7652
7653static void
7bc980e1 7654frv_io_handle_set (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data)
38c28a25 7655{
5ead67f6 7656 HARD_REG_SET *set = (HARD_REG_SET *) data;
38c28a25
AH
7657 unsigned int regno;
7658
7659 if (REG_P (x))
7660 FOR_EACH_REGNO (regno, x)
7661 CLEAR_HARD_REG_BIT (*set, regno);
7662}
7663
de2b09ec
RS
7664/* A note_uses callback that adds all registers in *X to hard register
7665 set *DATA. */
38c28a25
AH
7666
7667static void
7668frv_io_handle_use (rtx *x, void *data)
7669{
de2b09ec 7670 find_all_hard_regs (*x, (HARD_REG_SET *) data);
38c28a25
AH
7671}
7672
7673/* Go through block BB looking for membars to remove. There are two
7674 cases where intra-block analysis is enough:
7675
7676 - a membar is redundant if it occurs between two consecutive I/O
7677 operations and if those operations are guaranteed to complete
7678 in order.
7679
7680 - a membar for a __builtin_read is redundant if the result is
7681 used before the next I/O operation is issued.
7682
7683 If the last membar in the block could not be removed, and there
7684 are guaranteed to be no I/O operations between that membar and
7685 the end of the block, store the membar in *LAST_MEMBAR, otherwise
7686 store null.
7687
7688 Describe the block's first I/O operation in *NEXT_IO. Describe
7689 an unknown operation if the block doesn't do any I/O. */
7690
7691static void
7692frv_optimize_membar_local (basic_block bb, struct frv_io *next_io,
647d790d 7693 rtx_insn **last_membar)
38c28a25
AH
7694{
7695 HARD_REG_SET used_regs;
d8485bdb
TS
7696 rtx set;
7697 rtx_insn *insn, *next_membar;
38c28a25
AH
7698 bool next_is_end_p;
7699
7700 /* NEXT_IO is the next I/O operation to be performed after the current
7701 instruction. It starts off as being an unknown operation. */
7702 memset (next_io, 0, sizeof (*next_io));
7703
7704 /* NEXT_IS_END_P is true if NEXT_IO describes the end of the block. */
7705 next_is_end_p = true;
7706
7707 /* If the current instruction is a __builtin_read or __builtin_write,
7708 NEXT_MEMBAR is the membar instruction associated with it. NEXT_MEMBAR
7709 is null if the membar has already been deleted.
7710
7711 Note that the initialization here should only be needed to
536fa7b7 7712 suppress warnings. */
38c28a25
AH
7713 next_membar = 0;
7714
7715 /* USED_REGS is the set of registers that are used before the
7716 next I/O instruction. */
7717 CLEAR_HARD_REG_SET (used_regs);
7718
7719 for (insn = BB_END (bb); insn != BB_HEAD (bb); insn = PREV_INSN (insn))
b64925dc 7720 if (CALL_P (insn))
38c28a25
AH
7721 {
7722 /* We can't predict what a call will do to volatile memory. */
7723 memset (next_io, 0, sizeof (struct frv_io));
7724 next_is_end_p = false;
7725 CLEAR_HARD_REG_SET (used_regs);
7726 }
7727 else if (INSN_P (insn))
7728 switch (recog_memoized (insn))
7729 {
7730 case CODE_FOR_optional_membar_qi:
7731 case CODE_FOR_optional_membar_hi:
7732 case CODE_FOR_optional_membar_si:
7733 case CODE_FOR_optional_membar_di:
7734 next_membar = insn;
7735 if (next_is_end_p)
7736 {
7737 /* Local information isn't enough to decide whether this
7738 membar is needed. Stash it away for later. */
7739 *last_membar = insn;
7740 frv_extract_membar (next_io, insn);
7741 next_is_end_p = false;
7742 }
7743 else
7744 {
7745 /* Check whether the I/O operation before INSN could be
7746 reordered with one described by NEXT_IO. If it can't,
7747 INSN will not be needed. */
7748 struct frv_io prev_io;
7749
7750 frv_extract_membar (&prev_io, insn);
7751 if (frv_io_fixed_order_p (&prev_io, next_io))
7752 {
7753 if (dump_file)
7754 fprintf (dump_file,
7755 ";; [Local] Removing membar %d since order"
7756 " of accesses is guaranteed\n",
7757 INSN_UID (next_membar));
7758
7759 insn = NEXT_INSN (insn);
7760 delete_insn (next_membar);
7761 next_membar = 0;
7762 }
7763 *next_io = prev_io;
7764 }
7765 break;
7766
7767 default:
7768 /* Invalidate NEXT_IO's address if it depends on something that
7769 is clobbered by INSN. */
7770 if (next_io->var_address)
e8448ba5 7771 note_stores (insn, frv_io_check_address, &next_io->var_address);
38c28a25
AH
7772
7773 /* If the next membar is associated with a __builtin_read,
7774 see if INSN reads from that address. If it does, and if
7775 the destination register is used before the next I/O access,
7776 there is no need for the membar. */
7777 set = PATTERN (insn);
7778 if (next_io->type == FRV_IO_READ
7779 && next_io->var_address != 0
7780 && next_membar != 0
7781 && GET_CODE (set) == SET
7782 && GET_CODE (SET_DEST (set)) == REG
7783 && TEST_HARD_REG_BIT (used_regs, REGNO (SET_DEST (set))))
7784 {
7785 rtx src;
7786
7787 src = SET_SRC (set);
7788 if (GET_CODE (src) == ZERO_EXTEND)
7789 src = XEXP (src, 0);
7790
7791 if (GET_CODE (src) == MEM
7792 && rtx_equal_p (XEXP (src, 0), next_io->var_address))
7793 {
7794 if (dump_file)
7795 fprintf (dump_file,
7796 ";; [Local] Removing membar %d since the target"
7797 " of %d is used before the I/O operation\n",
7798 INSN_UID (next_membar), INSN_UID (insn));
7799
7800 if (next_membar == *last_membar)
7801 *last_membar = 0;
7802
7803 delete_insn (next_membar);
7804 next_membar = 0;
7805 }
7806 }
7807
7808 /* If INSN has volatile references, forget about any registers
7809 that are used after it. Otherwise forget about uses that
7810 are (or might be) defined by INSN. */
7811 if (volatile_refs_p (PATTERN (insn)))
7812 CLEAR_HARD_REG_SET (used_regs);
7813 else
e8448ba5 7814 note_stores (insn, frv_io_handle_set, &used_regs);
38c28a25
AH
7815
7816 note_uses (&PATTERN (insn), frv_io_handle_use, &used_regs);
7817 break;
7818 }
7819}
7820
7821/* See if MEMBAR, the last membar instruction in BB, can be removed.
7822 FIRST_IO[X] describes the first operation performed by basic block X. */
7823
7824static void
7825frv_optimize_membar_global (basic_block bb, struct frv_io *first_io,
647d790d 7826 rtx_insn *membar)
38c28a25
AH
7827{
7828 struct frv_io this_io, next_io;
7829 edge succ;
7830 edge_iterator ei;
7831
7832 /* We need to keep the membar if there is an edge to the exit block. */
7833 FOR_EACH_EDGE (succ, ei, bb->succs)
7834 /* for (succ = bb->succ; succ != 0; succ = succ->succ_next) */
fefa31b5 7835 if (succ->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
38c28a25
AH
7836 return;
7837
7838 /* Work out the union of all successor blocks. */
7839 ei = ei_start (bb->succs);
7840 ei_cond (ei, &succ);
7841 /* next_io = first_io[bb->succ->dest->index]; */
7842 next_io = first_io[succ->dest->index];
7843 ei = ei_start (bb->succs);
7844 if (ei_cond (ei, &succ))
7845 {
7846 for (ei_next (&ei); ei_cond (ei, &succ); ei_next (&ei))
7847 /*for (succ = bb->succ->succ_next; succ != 0; succ = succ->succ_next)*/
7848 frv_io_union (&next_io, &first_io[succ->dest->index]);
7849 }
7850 else
7851 gcc_unreachable ();
7852
7853 frv_extract_membar (&this_io, membar);
7854 if (frv_io_fixed_order_p (&this_io, &next_io))
7855 {
7856 if (dump_file)
7857 fprintf (dump_file,
7858 ";; [Global] Removing membar %d since order of accesses"
7859 " is guaranteed\n", INSN_UID (membar));
7860
7861 delete_insn (membar);
7862 }
7863}
7864
7865/* Remove redundant membars from the current function. */
7866
7867static void
7868frv_optimize_membar (void)
7869{
7870 basic_block bb;
7871 struct frv_io *first_io;
647d790d 7872 rtx_insn **last_membar;
38c28a25
AH
7873
7874 compute_bb_for_insn ();
8b1c6fd7 7875 first_io = XCNEWVEC (struct frv_io, last_basic_block_for_fn (cfun));
647d790d 7876 last_membar = XCNEWVEC (rtx_insn *, last_basic_block_for_fn (cfun));
38c28a25 7877
11cd3bed 7878 FOR_EACH_BB_FN (bb, cfun)
38c28a25
AH
7879 frv_optimize_membar_local (bb, &first_io[bb->index],
7880 &last_membar[bb->index]);
7881
11cd3bed 7882 FOR_EACH_BB_FN (bb, cfun)
38c28a25
AH
7883 if (last_membar[bb->index] != 0)
7884 frv_optimize_membar_global (bb, first_io, last_membar[bb->index]);
7885
7886 free (first_io);
7887 free (last_membar);
7888}
7889\f
c557edf4
RS
7890/* Used by frv_reorg to keep track of the current packet's address. */
7891static unsigned int frv_packet_address;
36a05131 7892
c557edf4
RS
7893/* If the current packet falls through to a label, try to pad the packet
7894 with nops in order to fit the label's alignment requirements. */
7895
7896static void
7897frv_align_label (void)
7898{
7899 unsigned int alignment, target, nop;
b32d5189 7900 rtx_insn *x, *last, *barrier, *label;
c557edf4
RS
7901
7902 /* Walk forward to the start of the next packet. Set ALIGNMENT to the
7903 maximum alignment of that packet, LABEL to the last label between
7904 the packets, and BARRIER to the last barrier. */
7905 last = frv_packet.insns[frv_packet.num_insns - 1];
7906 label = barrier = 0;
7907 alignment = 4;
7908 for (x = NEXT_INSN (last); x != 0 && !INSN_P (x); x = NEXT_INSN (x))
7909 {
7910 if (LABEL_P (x))
36a05131 7911 {
22ab4529 7912 unsigned int subalign = 1 << label_to_alignment (x).levels[0].log;
c557edf4
RS
7913 alignment = MAX (alignment, subalign);
7914 label = x;
36a05131 7915 }
c557edf4
RS
7916 if (BARRIER_P (x))
7917 barrier = x;
7918 }
36a05131 7919
c557edf4
RS
7920 /* If -malign-labels, and the packet falls through to an unaligned
7921 label, try introducing a nop to align that label to 8 bytes. */
7922 if (TARGET_ALIGN_LABELS
7923 && label != 0
7924 && barrier == 0
7925 && frv_packet.num_insns < frv_packet.issue_rate)
7926 alignment = MAX (alignment, 8);
36a05131 7927
c557edf4
RS
7928 /* Advance the address to the end of the current packet. */
7929 frv_packet_address += frv_packet.num_insns * 4;
36a05131 7930
c557edf4
RS
7931 /* Work out the target address, after alignment. */
7932 target = (frv_packet_address + alignment - 1) & -alignment;
7933
7934 /* If the packet falls through to the label, try to find an efficient
7935 padding sequence. */
7936 if (barrier == 0)
7937 {
7938 /* First try adding nops to the current packet. */
7939 for (nop = 0; nop < frv_num_nops; nop++)
7940 while (frv_packet_address < target && frv_pack_insn_p (frv_nops[nop]))
7941 {
7942 frv_insert_nop_in_packet (frv_nops[nop]);
7943 frv_packet_address += 4;
7944 }
7945
7946 /* If we still haven't reached the target, add some new packets that
7947 contain only nops. If there are two types of nop, insert an
7948 alternating sequence of frv_nops[0] and frv_nops[1], which will
7949 lead to packets like:
7950
7951 nop.p
7952 mnop.p/fnop.p
7953 nop.p
7954 mnop/fnop
7955
7956 etc. Just emit frv_nops[0] if that's the only nop we have. */
7957 last = frv_packet.insns[frv_packet.num_insns - 1];
7958 nop = 0;
7959 while (frv_packet_address < target)
7960 {
7961 last = emit_insn_after (PATTERN (frv_nops[nop]), last);
7962 frv_packet_address += 4;
7963 if (frv_num_nops > 1)
7964 nop ^= 1;
36a05131
BS
7965 }
7966 }
7967
c557edf4 7968 frv_packet_address = target;
36a05131
BS
7969}
7970
c557edf4
RS
7971/* Subroutine of frv_reorg, called after each packet has been constructed
7972 in frv_packet. */
7973
7974static void
7975frv_reorg_packet (void)
7976{
7977 frv_fill_unused_units (GROUP_I);
7978 frv_fill_unused_units (GROUP_FM);
7979 frv_align_label ();
7980}
7981
7982/* Add an instruction with pattern NOP to frv_nops[]. */
7983
7984static void
7985frv_register_nop (rtx nop)
7986{
e6eda746
DM
7987 rtx_insn *nop_insn = make_insn_raw (nop);
7988 SET_NEXT_INSN (nop_insn) = 0;
7989 SET_PREV_INSN (nop_insn) = 0;
7990 frv_nops[frv_num_nops++] = nop_insn;
c557edf4
RS
7991}
7992
7993/* Implement TARGET_MACHINE_DEPENDENT_REORG. Divide the instructions
7994 into packets and check whether we need to insert nops in order to
7995 fulfill the processor's issue requirements. Also, if the user has
7996 requested a certain alignment for a label, try to meet that alignment
7997 by inserting nops in the previous packet. */
7998
7999static void
8000frv_reorg (void)
8001{
38c28a25
AH
8002 if (optimize > 0 && TARGET_OPTIMIZE_MEMBAR && cfun->machine->has_membar_p)
8003 frv_optimize_membar ();
8004
c557edf4
RS
8005 frv_num_nops = 0;
8006 frv_register_nop (gen_nop ());
8007 if (TARGET_MEDIA)
8008 frv_register_nop (gen_mnop ());
8009 if (TARGET_HARD_FLOAT)
8010 frv_register_nop (gen_fnop ());
8011
8012 /* Estimate the length of each branch. Although this may change after
8013 we've inserted nops, it will only do so in big functions. */
8014 shorten_branches (get_insns ());
8015
8016 frv_packet_address = 0;
8017 frv_for_each_packet (frv_reorg_packet);
8018}
36a05131
BS
8019\f
8020#define def_builtin(name, type, code) \
c79efc4d 8021 add_builtin_function ((name), (type), (code), BUILT_IN_MD, NULL, NULL)
36a05131
BS
8022
8023struct builtin_description
8024{
8025 enum insn_code icode;
8026 const char *name;
8027 enum frv_builtins code;
8028 enum rtx_code comparison;
8029 unsigned int flag;
8030};
8031
8032/* Media intrinsics that take a single, constant argument. */
8033
8034static struct builtin_description bdesc_set[] =
8035{
5c5e8419 8036 { CODE_FOR_mhdsets, "__MHDSETS", FRV_BUILTIN_MHDSETS, UNKNOWN, 0 }
36a05131
BS
8037};
8038
87b483a1 8039/* Media intrinsics that take just one argument. */
36a05131
BS
8040
8041static struct builtin_description bdesc_1arg[] =
8042{
5c5e8419
JR
8043 { CODE_FOR_mnot, "__MNOT", FRV_BUILTIN_MNOT, UNKNOWN, 0 },
8044 { CODE_FOR_munpackh, "__MUNPACKH", FRV_BUILTIN_MUNPACKH, UNKNOWN, 0 },
8045 { CODE_FOR_mbtoh, "__MBTOH", FRV_BUILTIN_MBTOH, UNKNOWN, 0 },
8046 { CODE_FOR_mhtob, "__MHTOB", FRV_BUILTIN_MHTOB, UNKNOWN, 0},
8047 { CODE_FOR_mabshs, "__MABSHS", FRV_BUILTIN_MABSHS, UNKNOWN, 0 },
8048 { CODE_FOR_scutss, "__SCUTSS", FRV_BUILTIN_SCUTSS, UNKNOWN, 0 }
36a05131
BS
8049};
8050
87b483a1 8051/* Media intrinsics that take two arguments. */
36a05131
BS
8052
8053static struct builtin_description bdesc_2arg[] =
8054{
5c5e8419
JR
8055 { CODE_FOR_mand, "__MAND", FRV_BUILTIN_MAND, UNKNOWN, 0},
8056 { CODE_FOR_mor, "__MOR", FRV_BUILTIN_MOR, UNKNOWN, 0},
8057 { CODE_FOR_mxor, "__MXOR", FRV_BUILTIN_MXOR, UNKNOWN, 0},
8058 { CODE_FOR_maveh, "__MAVEH", FRV_BUILTIN_MAVEH, UNKNOWN, 0},
8059 { CODE_FOR_msaths, "__MSATHS", FRV_BUILTIN_MSATHS, UNKNOWN, 0},
8060 { CODE_FOR_msathu, "__MSATHU", FRV_BUILTIN_MSATHU, UNKNOWN, 0},
8061 { CODE_FOR_maddhss, "__MADDHSS", FRV_BUILTIN_MADDHSS, UNKNOWN, 0},
8062 { CODE_FOR_maddhus, "__MADDHUS", FRV_BUILTIN_MADDHUS, UNKNOWN, 0},
8063 { CODE_FOR_msubhss, "__MSUBHSS", FRV_BUILTIN_MSUBHSS, UNKNOWN, 0},
8064 { CODE_FOR_msubhus, "__MSUBHUS", FRV_BUILTIN_MSUBHUS, UNKNOWN, 0},
8065 { CODE_FOR_mqaddhss, "__MQADDHSS", FRV_BUILTIN_MQADDHSS, UNKNOWN, 0},
8066 { CODE_FOR_mqaddhus, "__MQADDHUS", FRV_BUILTIN_MQADDHUS, UNKNOWN, 0},
8067 { CODE_FOR_mqsubhss, "__MQSUBHSS", FRV_BUILTIN_MQSUBHSS, UNKNOWN, 0},
8068 { CODE_FOR_mqsubhus, "__MQSUBHUS", FRV_BUILTIN_MQSUBHUS, UNKNOWN, 0},
8069 { CODE_FOR_mpackh, "__MPACKH", FRV_BUILTIN_MPACKH, UNKNOWN, 0},
8070 { CODE_FOR_mcop1, "__Mcop1", FRV_BUILTIN_MCOP1, UNKNOWN, 0},
8071 { CODE_FOR_mcop2, "__Mcop2", FRV_BUILTIN_MCOP2, UNKNOWN, 0},
8072 { CODE_FOR_mwcut, "__MWCUT", FRV_BUILTIN_MWCUT, UNKNOWN, 0},
8073 { CODE_FOR_mqsaths, "__MQSATHS", FRV_BUILTIN_MQSATHS, UNKNOWN, 0},
8074 { CODE_FOR_mqlclrhs, "__MQLCLRHS", FRV_BUILTIN_MQLCLRHS, UNKNOWN, 0},
8075 { CODE_FOR_mqlmths, "__MQLMTHS", FRV_BUILTIN_MQLMTHS, UNKNOWN, 0},
8076 { CODE_FOR_smul, "__SMUL", FRV_BUILTIN_SMUL, UNKNOWN, 0},
8077 { CODE_FOR_umul, "__UMUL", FRV_BUILTIN_UMUL, UNKNOWN, 0},
8078 { CODE_FOR_addss, "__ADDSS", FRV_BUILTIN_ADDSS, UNKNOWN, 0},
8079 { CODE_FOR_subss, "__SUBSS", FRV_BUILTIN_SUBSS, UNKNOWN, 0},
8080 { CODE_FOR_slass, "__SLASS", FRV_BUILTIN_SLASS, UNKNOWN, 0},
8081 { CODE_FOR_scan, "__SCAN", FRV_BUILTIN_SCAN, UNKNOWN, 0}
c557edf4
RS
8082};
8083
8084/* Integer intrinsics that take two arguments and have no return value. */
8085
8086static struct builtin_description bdesc_int_void2arg[] =
8087{
5c5e8419
JR
8088 { CODE_FOR_smass, "__SMASS", FRV_BUILTIN_SMASS, UNKNOWN, 0},
8089 { CODE_FOR_smsss, "__SMSSS", FRV_BUILTIN_SMSSS, UNKNOWN, 0},
8090 { CODE_FOR_smu, "__SMU", FRV_BUILTIN_SMU, UNKNOWN, 0}
c557edf4
RS
8091};
8092
8093static struct builtin_description bdesc_prefetches[] =
8094{
5c5e8419
JR
8095 { CODE_FOR_frv_prefetch0, "__data_prefetch0", FRV_BUILTIN_PREFETCH0, UNKNOWN,
8096 0},
8097 { CODE_FOR_frv_prefetch, "__data_prefetch", FRV_BUILTIN_PREFETCH, UNKNOWN, 0}
36a05131
BS
8098};
8099
8100/* Media intrinsics that take two arguments, the first being an ACC number. */
8101
8102static struct builtin_description bdesc_cut[] =
8103{
5c5e8419
JR
8104 { CODE_FOR_mcut, "__MCUT", FRV_BUILTIN_MCUT, UNKNOWN, 0},
8105 { CODE_FOR_mcutss, "__MCUTSS", FRV_BUILTIN_MCUTSS, UNKNOWN, 0},
8106 { CODE_FOR_mdcutssi, "__MDCUTSSI", FRV_BUILTIN_MDCUTSSI, UNKNOWN, 0}
36a05131
BS
8107};
8108
87b483a1 8109/* Two-argument media intrinsics with an immediate second argument. */
36a05131
BS
8110
8111static struct builtin_description bdesc_2argimm[] =
8112{
5c5e8419
JR
8113 { CODE_FOR_mrotli, "__MROTLI", FRV_BUILTIN_MROTLI, UNKNOWN, 0},
8114 { CODE_FOR_mrotri, "__MROTRI", FRV_BUILTIN_MROTRI, UNKNOWN, 0},
8115 { CODE_FOR_msllhi, "__MSLLHI", FRV_BUILTIN_MSLLHI, UNKNOWN, 0},
8116 { CODE_FOR_msrlhi, "__MSRLHI", FRV_BUILTIN_MSRLHI, UNKNOWN, 0},
8117 { CODE_FOR_msrahi, "__MSRAHI", FRV_BUILTIN_MSRAHI, UNKNOWN, 0},
8118 { CODE_FOR_mexpdhw, "__MEXPDHW", FRV_BUILTIN_MEXPDHW, UNKNOWN, 0},
8119 { CODE_FOR_mexpdhd, "__MEXPDHD", FRV_BUILTIN_MEXPDHD, UNKNOWN, 0},
8120 { CODE_FOR_mdrotli, "__MDROTLI", FRV_BUILTIN_MDROTLI, UNKNOWN, 0},
8121 { CODE_FOR_mcplhi, "__MCPLHI", FRV_BUILTIN_MCPLHI, UNKNOWN, 0},
8122 { CODE_FOR_mcpli, "__MCPLI", FRV_BUILTIN_MCPLI, UNKNOWN, 0},
8123 { CODE_FOR_mhsetlos, "__MHSETLOS", FRV_BUILTIN_MHSETLOS, UNKNOWN, 0},
8124 { CODE_FOR_mhsetloh, "__MHSETLOH", FRV_BUILTIN_MHSETLOH, UNKNOWN, 0},
8125 { CODE_FOR_mhsethis, "__MHSETHIS", FRV_BUILTIN_MHSETHIS, UNKNOWN, 0},
8126 { CODE_FOR_mhsethih, "__MHSETHIH", FRV_BUILTIN_MHSETHIH, UNKNOWN, 0},
8127 { CODE_FOR_mhdseth, "__MHDSETH", FRV_BUILTIN_MHDSETH, UNKNOWN, 0},
8128 { CODE_FOR_mqsllhi, "__MQSLLHI", FRV_BUILTIN_MQSLLHI, UNKNOWN, 0},
8129 { CODE_FOR_mqsrahi, "__MQSRAHI", FRV_BUILTIN_MQSRAHI, UNKNOWN, 0}
36a05131
BS
8130};
8131
8132/* Media intrinsics that take two arguments and return void, the first argument
87b483a1 8133 being a pointer to 4 words in memory. */
36a05131
BS
8134
8135static struct builtin_description bdesc_void2arg[] =
8136{
5c5e8419
JR
8137 { CODE_FOR_mdunpackh, "__MDUNPACKH", FRV_BUILTIN_MDUNPACKH, UNKNOWN, 0},
8138 { CODE_FOR_mbtohe, "__MBTOHE", FRV_BUILTIN_MBTOHE, UNKNOWN, 0},
36a05131
BS
8139};
8140
8141/* Media intrinsics that take three arguments, the first being a const_int that
87b483a1 8142 denotes an accumulator, and that return void. */
36a05131
BS
8143
8144static struct builtin_description bdesc_void3arg[] =
8145{
5c5e8419
JR
8146 { CODE_FOR_mcpxrs, "__MCPXRS", FRV_BUILTIN_MCPXRS, UNKNOWN, 0},
8147 { CODE_FOR_mcpxru, "__MCPXRU", FRV_BUILTIN_MCPXRU, UNKNOWN, 0},
8148 { CODE_FOR_mcpxis, "__MCPXIS", FRV_BUILTIN_MCPXIS, UNKNOWN, 0},
8149 { CODE_FOR_mcpxiu, "__MCPXIU", FRV_BUILTIN_MCPXIU, UNKNOWN, 0},
8150 { CODE_FOR_mmulhs, "__MMULHS", FRV_BUILTIN_MMULHS, UNKNOWN, 0},
8151 { CODE_FOR_mmulhu, "__MMULHU", FRV_BUILTIN_MMULHU, UNKNOWN, 0},
8152 { CODE_FOR_mmulxhs, "__MMULXHS", FRV_BUILTIN_MMULXHS, UNKNOWN, 0},
8153 { CODE_FOR_mmulxhu, "__MMULXHU", FRV_BUILTIN_MMULXHU, UNKNOWN, 0},
8154 { CODE_FOR_mmachs, "__MMACHS", FRV_BUILTIN_MMACHS, UNKNOWN, 0},
8155 { CODE_FOR_mmachu, "__MMACHU", FRV_BUILTIN_MMACHU, UNKNOWN, 0},
8156 { CODE_FOR_mmrdhs, "__MMRDHS", FRV_BUILTIN_MMRDHS, UNKNOWN, 0},
8157 { CODE_FOR_mmrdhu, "__MMRDHU", FRV_BUILTIN_MMRDHU, UNKNOWN, 0},
8158 { CODE_FOR_mqcpxrs, "__MQCPXRS", FRV_BUILTIN_MQCPXRS, UNKNOWN, 0},
8159 { CODE_FOR_mqcpxru, "__MQCPXRU", FRV_BUILTIN_MQCPXRU, UNKNOWN, 0},
8160 { CODE_FOR_mqcpxis, "__MQCPXIS", FRV_BUILTIN_MQCPXIS, UNKNOWN, 0},
8161 { CODE_FOR_mqcpxiu, "__MQCPXIU", FRV_BUILTIN_MQCPXIU, UNKNOWN, 0},
8162 { CODE_FOR_mqmulhs, "__MQMULHS", FRV_BUILTIN_MQMULHS, UNKNOWN, 0},
8163 { CODE_FOR_mqmulhu, "__MQMULHU", FRV_BUILTIN_MQMULHU, UNKNOWN, 0},
8164 { CODE_FOR_mqmulxhs, "__MQMULXHS", FRV_BUILTIN_MQMULXHS, UNKNOWN, 0},
8165 { CODE_FOR_mqmulxhu, "__MQMULXHU", FRV_BUILTIN_MQMULXHU, UNKNOWN, 0},
8166 { CODE_FOR_mqmachs, "__MQMACHS", FRV_BUILTIN_MQMACHS, UNKNOWN, 0},
8167 { CODE_FOR_mqmachu, "__MQMACHU", FRV_BUILTIN_MQMACHU, UNKNOWN, 0},
8168 { CODE_FOR_mqxmachs, "__MQXMACHS", FRV_BUILTIN_MQXMACHS, UNKNOWN, 0},
8169 { CODE_FOR_mqxmacxhs, "__MQXMACXHS", FRV_BUILTIN_MQXMACXHS, UNKNOWN, 0},
8170 { CODE_FOR_mqmacxhs, "__MQMACXHS", FRV_BUILTIN_MQMACXHS, UNKNOWN, 0}
36a05131
BS
8171};
8172
8173/* Media intrinsics that take two accumulator numbers as argument and
8174 return void. */
8175
8176static struct builtin_description bdesc_voidacc[] =
8177{
5c5e8419
JR
8178 { CODE_FOR_maddaccs, "__MADDACCS", FRV_BUILTIN_MADDACCS, UNKNOWN, 0},
8179 { CODE_FOR_msubaccs, "__MSUBACCS", FRV_BUILTIN_MSUBACCS, UNKNOWN, 0},
8180 { CODE_FOR_masaccs, "__MASACCS", FRV_BUILTIN_MASACCS, UNKNOWN, 0},
8181 { CODE_FOR_mdaddaccs, "__MDADDACCS", FRV_BUILTIN_MDADDACCS, UNKNOWN, 0},
8182 { CODE_FOR_mdsubaccs, "__MDSUBACCS", FRV_BUILTIN_MDSUBACCS, UNKNOWN, 0},
8183 { CODE_FOR_mdasaccs, "__MDASACCS", FRV_BUILTIN_MDASACCS, UNKNOWN, 0}
36a05131
BS
8184};
8185
38c28a25
AH
8186/* Intrinsics that load a value and then issue a MEMBAR. The load is
8187 a normal move and the ICODE is for the membar. */
c14ff86e
AH
8188
8189static struct builtin_description bdesc_loads[] =
8190{
38c28a25 8191 { CODE_FOR_optional_membar_qi, "__builtin_read8",
5c5e8419 8192 FRV_BUILTIN_READ8, UNKNOWN, 0},
38c28a25 8193 { CODE_FOR_optional_membar_hi, "__builtin_read16",
5c5e8419 8194 FRV_BUILTIN_READ16, UNKNOWN, 0},
38c28a25 8195 { CODE_FOR_optional_membar_si, "__builtin_read32",
5c5e8419 8196 FRV_BUILTIN_READ32, UNKNOWN, 0},
38c28a25 8197 { CODE_FOR_optional_membar_di, "__builtin_read64",
5c5e8419 8198 FRV_BUILTIN_READ64, UNKNOWN, 0}
c14ff86e
AH
8199};
8200
8201/* Likewise stores. */
8202
8203static struct builtin_description bdesc_stores[] =
8204{
38c28a25 8205 { CODE_FOR_optional_membar_qi, "__builtin_write8",
5c5e8419 8206 FRV_BUILTIN_WRITE8, UNKNOWN, 0},
38c28a25 8207 { CODE_FOR_optional_membar_hi, "__builtin_write16",
5c5e8419 8208 FRV_BUILTIN_WRITE16, UNKNOWN, 0},
38c28a25 8209 { CODE_FOR_optional_membar_si, "__builtin_write32",
5c5e8419 8210 FRV_BUILTIN_WRITE32, UNKNOWN, 0},
38c28a25 8211 { CODE_FOR_optional_membar_di, "__builtin_write64",
5c5e8419 8212 FRV_BUILTIN_WRITE64, UNKNOWN, 0},
c14ff86e
AH
8213};
8214
87b483a1 8215/* Initialize media builtins. */
36a05131 8216
14966b94 8217static void
f2206911 8218frv_init_builtins (void)
36a05131 8219{
36a05131
BS
8220 tree accumulator = integer_type_node;
8221 tree integer = integer_type_node;
8222 tree voidt = void_type_node;
8223 tree uhalf = short_unsigned_type_node;
8224 tree sword1 = long_integer_type_node;
8225 tree uword1 = long_unsigned_type_node;
8226 tree sword2 = long_long_integer_type_node;
8227 tree uword2 = long_long_unsigned_type_node;
8228 tree uword4 = build_pointer_type (uword1);
c14ff86e
AH
8229 tree vptr = build_pointer_type (build_type_variant (void_type_node, 0, 1));
8230 tree ubyte = unsigned_char_type_node;
c557edf4 8231 tree iacc = integer_type_node;
36a05131
BS
8232
8233#define UNARY(RET, T1) \
e84a6fcf 8234 build_function_type_list (RET, T1, NULL_TREE)
36a05131
BS
8235
8236#define BINARY(RET, T1, T2) \
e84a6fcf 8237 build_function_type_list (RET, T1, T2, NULL_TREE)
36a05131
BS
8238
8239#define TRINARY(RET, T1, T2, T3) \
e84a6fcf 8240 build_function_type_list (RET, T1, T2, T3, NULL_TREE)
36a05131 8241
a738d848 8242#define QUAD(RET, T1, T2, T3, T4) \
4adf72f1 8243 build_function_type_list (RET, T1, T2, T3, T4, NULL_TREE)
a738d848 8244
e84a6fcf 8245 tree void_ftype_void = build_function_type_list (voidt, NULL_TREE);
36a05131
BS
8246
8247 tree void_ftype_acc = UNARY (voidt, accumulator);
8248 tree void_ftype_uw4_uw1 = BINARY (voidt, uword4, uword1);
8249 tree void_ftype_uw4_uw2 = BINARY (voidt, uword4, uword2);
8250 tree void_ftype_acc_uw1 = BINARY (voidt, accumulator, uword1);
8251 tree void_ftype_acc_acc = BINARY (voidt, accumulator, accumulator);
8252 tree void_ftype_acc_uw1_uw1 = TRINARY (voidt, accumulator, uword1, uword1);
8253 tree void_ftype_acc_sw1_sw1 = TRINARY (voidt, accumulator, sword1, sword1);
8254 tree void_ftype_acc_uw2_uw2 = TRINARY (voidt, accumulator, uword2, uword2);
8255 tree void_ftype_acc_sw2_sw2 = TRINARY (voidt, accumulator, sword2, sword2);
8256
8257 tree uw1_ftype_uw1 = UNARY (uword1, uword1);
8258 tree uw1_ftype_sw1 = UNARY (uword1, sword1);
8259 tree uw1_ftype_uw2 = UNARY (uword1, uword2);
8260 tree uw1_ftype_acc = UNARY (uword1, accumulator);
8261 tree uw1_ftype_uh_uh = BINARY (uword1, uhalf, uhalf);
8262 tree uw1_ftype_uw1_uw1 = BINARY (uword1, uword1, uword1);
8263 tree uw1_ftype_uw1_int = BINARY (uword1, uword1, integer);
8264 tree uw1_ftype_acc_uw1 = BINARY (uword1, accumulator, uword1);
8265 tree uw1_ftype_acc_sw1 = BINARY (uword1, accumulator, sword1);
8266 tree uw1_ftype_uw2_uw1 = BINARY (uword1, uword2, uword1);
8267 tree uw1_ftype_uw2_int = BINARY (uword1, uword2, integer);
8268
8269 tree sw1_ftype_int = UNARY (sword1, integer);
8270 tree sw1_ftype_sw1_sw1 = BINARY (sword1, sword1, sword1);
8271 tree sw1_ftype_sw1_int = BINARY (sword1, sword1, integer);
8272
8273 tree uw2_ftype_uw1 = UNARY (uword2, uword1);
8274 tree uw2_ftype_uw1_int = BINARY (uword2, uword1, integer);
8275 tree uw2_ftype_uw2_uw2 = BINARY (uword2, uword2, uword2);
8276 tree uw2_ftype_uw2_int = BINARY (uword2, uword2, integer);
8277 tree uw2_ftype_acc_int = BINARY (uword2, accumulator, integer);
a738d848 8278 tree uw2_ftype_uh_uh_uh_uh = QUAD (uword2, uhalf, uhalf, uhalf, uhalf);
36a05131
BS
8279
8280 tree sw2_ftype_sw2_sw2 = BINARY (sword2, sword2, sword2);
c557edf4
RS
8281 tree sw2_ftype_sw2_int = BINARY (sword2, sword2, integer);
8282 tree uw2_ftype_uw1_uw1 = BINARY (uword2, uword1, uword1);
8283 tree sw2_ftype_sw1_sw1 = BINARY (sword2, sword1, sword1);
8284 tree void_ftype_sw1_sw1 = BINARY (voidt, sword1, sword1);
8285 tree void_ftype_iacc_sw2 = BINARY (voidt, iacc, sword2);
8286 tree void_ftype_iacc_sw1 = BINARY (voidt, iacc, sword1);
8287 tree sw1_ftype_sw1 = UNARY (sword1, sword1);
8288 tree sw2_ftype_iacc = UNARY (sword2, iacc);
8289 tree sw1_ftype_iacc = UNARY (sword1, iacc);
8290 tree void_ftype_ptr = UNARY (voidt, const_ptr_type_node);
c14ff86e
AH
8291 tree uw1_ftype_vptr = UNARY (uword1, vptr);
8292 tree uw2_ftype_vptr = UNARY (uword2, vptr);
8293 tree void_ftype_vptr_ub = BINARY (voidt, vptr, ubyte);
8294 tree void_ftype_vptr_uh = BINARY (voidt, vptr, uhalf);
8295 tree void_ftype_vptr_uw1 = BINARY (voidt, vptr, uword1);
8296 tree void_ftype_vptr_uw2 = BINARY (voidt, vptr, uword2);
36a05131
BS
8297
8298 def_builtin ("__MAND", uw1_ftype_uw1_uw1, FRV_BUILTIN_MAND);
8299 def_builtin ("__MOR", uw1_ftype_uw1_uw1, FRV_BUILTIN_MOR);
8300 def_builtin ("__MXOR", uw1_ftype_uw1_uw1, FRV_BUILTIN_MXOR);
8301 def_builtin ("__MNOT", uw1_ftype_uw1, FRV_BUILTIN_MNOT);
8302 def_builtin ("__MROTLI", uw1_ftype_uw1_int, FRV_BUILTIN_MROTLI);
8303 def_builtin ("__MROTRI", uw1_ftype_uw1_int, FRV_BUILTIN_MROTRI);
8304 def_builtin ("__MWCUT", uw1_ftype_uw2_uw1, FRV_BUILTIN_MWCUT);
8305 def_builtin ("__MAVEH", uw1_ftype_uw1_uw1, FRV_BUILTIN_MAVEH);
8306 def_builtin ("__MSLLHI", uw1_ftype_uw1_int, FRV_BUILTIN_MSLLHI);
8307 def_builtin ("__MSRLHI", uw1_ftype_uw1_int, FRV_BUILTIN_MSRLHI);
8308 def_builtin ("__MSRAHI", sw1_ftype_sw1_int, FRV_BUILTIN_MSRAHI);
8309 def_builtin ("__MSATHS", sw1_ftype_sw1_sw1, FRV_BUILTIN_MSATHS);
8310 def_builtin ("__MSATHU", uw1_ftype_uw1_uw1, FRV_BUILTIN_MSATHU);
8311 def_builtin ("__MADDHSS", sw1_ftype_sw1_sw1, FRV_BUILTIN_MADDHSS);
8312 def_builtin ("__MADDHUS", uw1_ftype_uw1_uw1, FRV_BUILTIN_MADDHUS);
8313 def_builtin ("__MSUBHSS", sw1_ftype_sw1_sw1, FRV_BUILTIN_MSUBHSS);
8314 def_builtin ("__MSUBHUS", uw1_ftype_uw1_uw1, FRV_BUILTIN_MSUBHUS);
8315 def_builtin ("__MMULHS", void_ftype_acc_sw1_sw1, FRV_BUILTIN_MMULHS);
8316 def_builtin ("__MMULHU", void_ftype_acc_uw1_uw1, FRV_BUILTIN_MMULHU);
8317 def_builtin ("__MMULXHS", void_ftype_acc_sw1_sw1, FRV_BUILTIN_MMULXHS);
8318 def_builtin ("__MMULXHU", void_ftype_acc_uw1_uw1, FRV_BUILTIN_MMULXHU);
8319 def_builtin ("__MMACHS", void_ftype_acc_sw1_sw1, FRV_BUILTIN_MMACHS);
8320 def_builtin ("__MMACHU", void_ftype_acc_uw1_uw1, FRV_BUILTIN_MMACHU);
8321 def_builtin ("__MMRDHS", void_ftype_acc_sw1_sw1, FRV_BUILTIN_MMRDHS);
8322 def_builtin ("__MMRDHU", void_ftype_acc_uw1_uw1, FRV_BUILTIN_MMRDHU);
8323 def_builtin ("__MQADDHSS", sw2_ftype_sw2_sw2, FRV_BUILTIN_MQADDHSS);
8324 def_builtin ("__MQADDHUS", uw2_ftype_uw2_uw2, FRV_BUILTIN_MQADDHUS);
8325 def_builtin ("__MQSUBHSS", sw2_ftype_sw2_sw2, FRV_BUILTIN_MQSUBHSS);
8326 def_builtin ("__MQSUBHUS", uw2_ftype_uw2_uw2, FRV_BUILTIN_MQSUBHUS);
8327 def_builtin ("__MQMULHS", void_ftype_acc_sw2_sw2, FRV_BUILTIN_MQMULHS);
8328 def_builtin ("__MQMULHU", void_ftype_acc_uw2_uw2, FRV_BUILTIN_MQMULHU);
8329 def_builtin ("__MQMULXHS", void_ftype_acc_sw2_sw2, FRV_BUILTIN_MQMULXHS);
8330 def_builtin ("__MQMULXHU", void_ftype_acc_uw2_uw2, FRV_BUILTIN_MQMULXHU);
8331 def_builtin ("__MQMACHS", void_ftype_acc_sw2_sw2, FRV_BUILTIN_MQMACHS);
8332 def_builtin ("__MQMACHU", void_ftype_acc_uw2_uw2, FRV_BUILTIN_MQMACHU);
8333 def_builtin ("__MCPXRS", void_ftype_acc_sw1_sw1, FRV_BUILTIN_MCPXRS);
8334 def_builtin ("__MCPXRU", void_ftype_acc_uw1_uw1, FRV_BUILTIN_MCPXRU);
8335 def_builtin ("__MCPXIS", void_ftype_acc_sw1_sw1, FRV_BUILTIN_MCPXIS);
8336 def_builtin ("__MCPXIU", void_ftype_acc_uw1_uw1, FRV_BUILTIN_MCPXIU);
8337 def_builtin ("__MQCPXRS", void_ftype_acc_sw2_sw2, FRV_BUILTIN_MQCPXRS);
8338 def_builtin ("__MQCPXRU", void_ftype_acc_uw2_uw2, FRV_BUILTIN_MQCPXRU);
8339 def_builtin ("__MQCPXIS", void_ftype_acc_sw2_sw2, FRV_BUILTIN_MQCPXIS);
8340 def_builtin ("__MQCPXIU", void_ftype_acc_uw2_uw2, FRV_BUILTIN_MQCPXIU);
8341 def_builtin ("__MCUT", uw1_ftype_acc_uw1, FRV_BUILTIN_MCUT);
8342 def_builtin ("__MCUTSS", uw1_ftype_acc_sw1, FRV_BUILTIN_MCUTSS);
8343 def_builtin ("__MEXPDHW", uw1_ftype_uw1_int, FRV_BUILTIN_MEXPDHW);
8344 def_builtin ("__MEXPDHD", uw2_ftype_uw1_int, FRV_BUILTIN_MEXPDHD);
8345 def_builtin ("__MPACKH", uw1_ftype_uh_uh, FRV_BUILTIN_MPACKH);
8346 def_builtin ("__MUNPACKH", uw2_ftype_uw1, FRV_BUILTIN_MUNPACKH);
a738d848 8347 def_builtin ("__MDPACKH", uw2_ftype_uh_uh_uh_uh, FRV_BUILTIN_MDPACKH);
b16c1435 8348 def_builtin ("__MDUNPACKH", void_ftype_uw4_uw2, FRV_BUILTIN_MDUNPACKH);
36a05131
BS
8349 def_builtin ("__MBTOH", uw2_ftype_uw1, FRV_BUILTIN_MBTOH);
8350 def_builtin ("__MHTOB", uw1_ftype_uw2, FRV_BUILTIN_MHTOB);
8351 def_builtin ("__MBTOHE", void_ftype_uw4_uw1, FRV_BUILTIN_MBTOHE);
8352 def_builtin ("__MCLRACC", void_ftype_acc, FRV_BUILTIN_MCLRACC);
8353 def_builtin ("__MCLRACCA", void_ftype_void, FRV_BUILTIN_MCLRACCA);
8354 def_builtin ("__MRDACC", uw1_ftype_acc, FRV_BUILTIN_MRDACC);
8355 def_builtin ("__MRDACCG", uw1_ftype_acc, FRV_BUILTIN_MRDACCG);
8356 def_builtin ("__MWTACC", void_ftype_acc_uw1, FRV_BUILTIN_MWTACC);
8357 def_builtin ("__MWTACCG", void_ftype_acc_uw1, FRV_BUILTIN_MWTACCG);
8358 def_builtin ("__Mcop1", uw1_ftype_uw1_uw1, FRV_BUILTIN_MCOP1);
8359 def_builtin ("__Mcop2", uw1_ftype_uw1_uw1, FRV_BUILTIN_MCOP2);
8360 def_builtin ("__MTRAP", void_ftype_void, FRV_BUILTIN_MTRAP);
8361 def_builtin ("__MQXMACHS", void_ftype_acc_sw2_sw2, FRV_BUILTIN_MQXMACHS);
8362 def_builtin ("__MQXMACXHS", void_ftype_acc_sw2_sw2, FRV_BUILTIN_MQXMACXHS);
8363 def_builtin ("__MQMACXHS", void_ftype_acc_sw2_sw2, FRV_BUILTIN_MQMACXHS);
8364 def_builtin ("__MADDACCS", void_ftype_acc_acc, FRV_BUILTIN_MADDACCS);
8365 def_builtin ("__MSUBACCS", void_ftype_acc_acc, FRV_BUILTIN_MSUBACCS);
8366 def_builtin ("__MASACCS", void_ftype_acc_acc, FRV_BUILTIN_MASACCS);
8367 def_builtin ("__MDADDACCS", void_ftype_acc_acc, FRV_BUILTIN_MDADDACCS);
8368 def_builtin ("__MDSUBACCS", void_ftype_acc_acc, FRV_BUILTIN_MDSUBACCS);
8369 def_builtin ("__MDASACCS", void_ftype_acc_acc, FRV_BUILTIN_MDASACCS);
8370 def_builtin ("__MABSHS", uw1_ftype_sw1, FRV_BUILTIN_MABSHS);
8371 def_builtin ("__MDROTLI", uw2_ftype_uw2_int, FRV_BUILTIN_MDROTLI);
8372 def_builtin ("__MCPLHI", uw1_ftype_uw2_int, FRV_BUILTIN_MCPLHI);
8373 def_builtin ("__MCPLI", uw1_ftype_uw2_int, FRV_BUILTIN_MCPLI);
8374 def_builtin ("__MDCUTSSI", uw2_ftype_acc_int, FRV_BUILTIN_MDCUTSSI);
8375 def_builtin ("__MQSATHS", sw2_ftype_sw2_sw2, FRV_BUILTIN_MQSATHS);
8376 def_builtin ("__MHSETLOS", sw1_ftype_sw1_int, FRV_BUILTIN_MHSETLOS);
8377 def_builtin ("__MHSETHIS", sw1_ftype_sw1_int, FRV_BUILTIN_MHSETHIS);
8378 def_builtin ("__MHDSETS", sw1_ftype_int, FRV_BUILTIN_MHDSETS);
8379 def_builtin ("__MHSETLOH", uw1_ftype_uw1_int, FRV_BUILTIN_MHSETLOH);
8380 def_builtin ("__MHSETHIH", uw1_ftype_uw1_int, FRV_BUILTIN_MHSETHIH);
8381 def_builtin ("__MHDSETH", uw1_ftype_uw1_int, FRV_BUILTIN_MHDSETH);
c557edf4
RS
8382 def_builtin ("__MQLCLRHS", sw2_ftype_sw2_sw2, FRV_BUILTIN_MQLCLRHS);
8383 def_builtin ("__MQLMTHS", sw2_ftype_sw2_sw2, FRV_BUILTIN_MQLMTHS);
8384 def_builtin ("__MQSLLHI", uw2_ftype_uw2_int, FRV_BUILTIN_MQSLLHI);
8385 def_builtin ("__MQSRAHI", sw2_ftype_sw2_int, FRV_BUILTIN_MQSRAHI);
8386 def_builtin ("__SMUL", sw2_ftype_sw1_sw1, FRV_BUILTIN_SMUL);
8387 def_builtin ("__UMUL", uw2_ftype_uw1_uw1, FRV_BUILTIN_UMUL);
8388 def_builtin ("__SMASS", void_ftype_sw1_sw1, FRV_BUILTIN_SMASS);
8389 def_builtin ("__SMSSS", void_ftype_sw1_sw1, FRV_BUILTIN_SMSSS);
8390 def_builtin ("__SMU", void_ftype_sw1_sw1, FRV_BUILTIN_SMU);
8391 def_builtin ("__ADDSS", sw1_ftype_sw1_sw1, FRV_BUILTIN_ADDSS);
8392 def_builtin ("__SUBSS", sw1_ftype_sw1_sw1, FRV_BUILTIN_SUBSS);
8393 def_builtin ("__SLASS", sw1_ftype_sw1_sw1, FRV_BUILTIN_SLASS);
8394 def_builtin ("__SCAN", sw1_ftype_sw1_sw1, FRV_BUILTIN_SCAN);
8395 def_builtin ("__SCUTSS", sw1_ftype_sw1, FRV_BUILTIN_SCUTSS);
8396 def_builtin ("__IACCreadll", sw2_ftype_iacc, FRV_BUILTIN_IACCreadll);
8397 def_builtin ("__IACCreadl", sw1_ftype_iacc, FRV_BUILTIN_IACCreadl);
8398 def_builtin ("__IACCsetll", void_ftype_iacc_sw2, FRV_BUILTIN_IACCsetll);
8399 def_builtin ("__IACCsetl", void_ftype_iacc_sw1, FRV_BUILTIN_IACCsetl);
8400 def_builtin ("__data_prefetch0", void_ftype_ptr, FRV_BUILTIN_PREFETCH0);
8401 def_builtin ("__data_prefetch", void_ftype_ptr, FRV_BUILTIN_PREFETCH);
c14ff86e
AH
8402 def_builtin ("__builtin_read8", uw1_ftype_vptr, FRV_BUILTIN_READ8);
8403 def_builtin ("__builtin_read16", uw1_ftype_vptr, FRV_BUILTIN_READ16);
8404 def_builtin ("__builtin_read32", uw1_ftype_vptr, FRV_BUILTIN_READ32);
8405 def_builtin ("__builtin_read64", uw2_ftype_vptr, FRV_BUILTIN_READ64);
8406
8407 def_builtin ("__builtin_write8", void_ftype_vptr_ub, FRV_BUILTIN_WRITE8);
8408 def_builtin ("__builtin_write16", void_ftype_vptr_uh, FRV_BUILTIN_WRITE16);
8409 def_builtin ("__builtin_write32", void_ftype_vptr_uw1, FRV_BUILTIN_WRITE32);
8410 def_builtin ("__builtin_write64", void_ftype_vptr_uw2, FRV_BUILTIN_WRITE64);
36a05131
BS
8411
8412#undef UNARY
8413#undef BINARY
8414#undef TRINARY
a738d848 8415#undef QUAD
36a05131
BS
8416}
8417
c15c90bb
ZW
8418/* Set the names for various arithmetic operations according to the
8419 FRV ABI. */
8420static void
8421frv_init_libfuncs (void)
8422{
8423 set_optab_libfunc (smod_optab, SImode, "__modi");
8424 set_optab_libfunc (umod_optab, SImode, "__umodi");
8425
8426 set_optab_libfunc (add_optab, DImode, "__addll");
8427 set_optab_libfunc (sub_optab, DImode, "__subll");
8428 set_optab_libfunc (smul_optab, DImode, "__mulll");
8429 set_optab_libfunc (sdiv_optab, DImode, "__divll");
8430 set_optab_libfunc (smod_optab, DImode, "__modll");
8431 set_optab_libfunc (umod_optab, DImode, "__umodll");
8432 set_optab_libfunc (and_optab, DImode, "__andll");
8433 set_optab_libfunc (ior_optab, DImode, "__orll");
8434 set_optab_libfunc (xor_optab, DImode, "__xorll");
8435 set_optab_libfunc (one_cmpl_optab, DImode, "__notll");
8436
8437 set_optab_libfunc (add_optab, SFmode, "__addf");
8438 set_optab_libfunc (sub_optab, SFmode, "__subf");
8439 set_optab_libfunc (smul_optab, SFmode, "__mulf");
8440 set_optab_libfunc (sdiv_optab, SFmode, "__divf");
8441
8442 set_optab_libfunc (add_optab, DFmode, "__addd");
8443 set_optab_libfunc (sub_optab, DFmode, "__subd");
8444 set_optab_libfunc (smul_optab, DFmode, "__muld");
8445 set_optab_libfunc (sdiv_optab, DFmode, "__divd");
8446
85363ca0
ZW
8447 set_conv_libfunc (sext_optab, DFmode, SFmode, "__ftod");
8448 set_conv_libfunc (trunc_optab, SFmode, DFmode, "__dtof");
8449
8450 set_conv_libfunc (sfix_optab, SImode, SFmode, "__ftoi");
8451 set_conv_libfunc (sfix_optab, DImode, SFmode, "__ftoll");
8452 set_conv_libfunc (sfix_optab, SImode, DFmode, "__dtoi");
8453 set_conv_libfunc (sfix_optab, DImode, DFmode, "__dtoll");
8454
8455 set_conv_libfunc (ufix_optab, SImode, SFmode, "__ftoui");
09c55720
RS
8456 set_conv_libfunc (ufix_optab, DImode, SFmode, "__ftoull");
8457 set_conv_libfunc (ufix_optab, SImode, DFmode, "__dtoui");
8458 set_conv_libfunc (ufix_optab, DImode, DFmode, "__dtoull");
85363ca0
ZW
8459
8460 set_conv_libfunc (sfloat_optab, SFmode, SImode, "__itof");
8461 set_conv_libfunc (sfloat_optab, SFmode, DImode, "__lltof");
8462 set_conv_libfunc (sfloat_optab, DFmode, SImode, "__itod");
8463 set_conv_libfunc (sfloat_optab, DFmode, DImode, "__lltod");
c15c90bb
ZW
8464}
8465
36a05131
BS
8466/* Convert an integer constant to an accumulator register. ICODE is the
8467 code of the target instruction, OPNUM is the number of the
8468 accumulator operand and OPVAL is the constant integer. Try both
8469 ACC and ACCG registers; only report an error if neither fit the
8470 instruction. */
8471
8472static rtx
f2206911 8473frv_int_to_acc (enum insn_code icode, int opnum, rtx opval)
36a05131
BS
8474{
8475 rtx reg;
c557edf4
RS
8476 int i;
8477
0fa2e4df 8478 /* ACCs and ACCGs are implicit global registers if media intrinsics
c557edf4 8479 are being used. We set up this lazily to avoid creating lots of
c112cf2b 8480 unnecessary call_insn rtl in non-media code. */
c557edf4
RS
8481 for (i = 0; i <= ACC_MASK; i++)
8482 if ((i & ACC_MASK) == i)
8483 global_regs[i + ACC_FIRST] = global_regs[i + ACCG_FIRST] = 1;
36a05131
BS
8484
8485 if (GET_CODE (opval) != CONST_INT)
8486 {
8487 error ("accumulator is not a constant integer");
8488 return NULL_RTX;
8489 }
c557edf4 8490 if ((INTVAL (opval) & ~ACC_MASK) != 0)
36a05131
BS
8491 {
8492 error ("accumulator number is out of bounds");
8493 return NULL_RTX;
8494 }
8495
8496 reg = gen_rtx_REG (insn_data[icode].operand[opnum].mode,
8497 ACC_FIRST + INTVAL (opval));
8498 if (! (*insn_data[icode].operand[opnum].predicate) (reg, VOIDmode))
6fb5fa3c 8499 SET_REGNO (reg, ACCG_FIRST + INTVAL (opval));
36a05131
BS
8500
8501 if (! (*insn_data[icode].operand[opnum].predicate) (reg, VOIDmode))
8502 {
9e637a26 8503 error ("inappropriate accumulator for %qs", insn_data[icode].name);
36a05131
BS
8504 return NULL_RTX;
8505 }
8506 return reg;
8507}
8508
8509/* If an ACC rtx has mode MODE, return the mode that the matching ACCG
8510 should have. */
8511
ef4bddc2
RS
8512static machine_mode
8513frv_matching_accg_mode (machine_mode mode)
36a05131
BS
8514{
8515 switch (mode)
8516 {
4e10a5a7 8517 case E_V4SImode:
36a05131
BS
8518 return V4QImode;
8519
4e10a5a7 8520 case E_DImode:
36a05131
BS
8521 return HImode;
8522
4e10a5a7 8523 case E_SImode:
36a05131
BS
8524 return QImode;
8525
8526 default:
44e91694 8527 gcc_unreachable ();
36a05131
BS
8528 }
8529}
8530
38c28a25
AH
8531/* Given that a __builtin_read or __builtin_write function is accessing
8532 address ADDRESS, return the value that should be used as operand 1
8533 of the membar. */
8534
8535static rtx
8536frv_io_address_cookie (rtx address)
8537{
8538 return (GET_CODE (address) == CONST_INT
8539 ? GEN_INT (INTVAL (address) / 8 * 8)
8540 : const0_rtx);
8541}
8542
36a05131
BS
8543/* Return the accumulator guard that should be paired with accumulator
8544 register ACC. The mode of the returned register is in the same
8545 class as ACC, but is four times smaller. */
8546
8547rtx
f2206911 8548frv_matching_accg_for_acc (rtx acc)
36a05131
BS
8549{
8550 return gen_rtx_REG (frv_matching_accg_mode (GET_MODE (acc)),
8551 REGNO (acc) - ACC_FIRST + ACCG_FIRST);
8552}
8553
2396bce1
EC
8554/* Read the requested argument from the call EXP given by INDEX.
8555 Return the value as an rtx. */
36a05131
BS
8556
8557static rtx
2396bce1 8558frv_read_argument (tree exp, unsigned int index)
36a05131 8559{
5c5e8419 8560 return expand_normal (CALL_EXPR_ARG (exp, index));
36a05131
BS
8561}
8562
c557edf4
RS
8563/* Like frv_read_argument, but interpret the argument as the number
8564 of an IACC register and return a (reg:MODE ...) rtx for it. */
8565
8566static rtx
ef4bddc2 8567frv_read_iacc_argument (machine_mode mode, tree call,
2396bce1 8568 unsigned int index)
c557edf4
RS
8569{
8570 int i, regno;
8571 rtx op;
8572
2396bce1 8573 op = frv_read_argument (call, index);
c557edf4
RS
8574 if (GET_CODE (op) != CONST_INT
8575 || INTVAL (op) < 0
8576 || INTVAL (op) > IACC_LAST - IACC_FIRST
8577 || ((INTVAL (op) * 4) & (GET_MODE_SIZE (mode) - 1)) != 0)
8578 {
8579 error ("invalid IACC argument");
8580 op = const0_rtx;
8581 }
8582
0fa2e4df 8583 /* IACCs are implicit global registers. We set up this lazily to
c112cf2b 8584 avoid creating lots of unnecessary call_insn rtl when IACCs aren't
c557edf4
RS
8585 being used. */
8586 regno = INTVAL (op) + IACC_FIRST;
a93072ca 8587 for (i = 0; i < hard_regno_nregs (regno, mode); i++)
c557edf4
RS
8588 global_regs[regno + i] = 1;
8589
8590 return gen_rtx_REG (mode, regno);
8591}
8592
36a05131
BS
8593/* Return true if OPVAL can be used for operand OPNUM of instruction ICODE.
8594 The instruction should require a constant operand of some sort. The
8595 function prints an error if OPVAL is not valid. */
8596
8597static int
f2206911 8598frv_check_constant_argument (enum insn_code icode, int opnum, rtx opval)
36a05131
BS
8599{
8600 if (GET_CODE (opval) != CONST_INT)
8601 {
9e637a26 8602 error ("%qs expects a constant argument", insn_data[icode].name);
36a05131
BS
8603 return FALSE;
8604 }
8605 if (! (*insn_data[icode].operand[opnum].predicate) (opval, VOIDmode))
8606 {
9e637a26 8607 error ("constant argument out of range for %qs", insn_data[icode].name);
36a05131
BS
8608 return FALSE;
8609 }
8610 return TRUE;
8611}
8612
8613/* Return a legitimate rtx for instruction ICODE's return value. Use TARGET
8614 if it's not null, has the right mode, and satisfies operand 0's
8615 predicate. */
8616
8617static rtx
f2206911 8618frv_legitimize_target (enum insn_code icode, rtx target)
36a05131 8619{
ef4bddc2 8620 machine_mode mode = insn_data[icode].operand[0].mode;
36a05131
BS
8621
8622 if (! target
8623 || GET_MODE (target) != mode
8624 || ! (*insn_data[icode].operand[0].predicate) (target, mode))
8625 return gen_reg_rtx (mode);
8626 else
8627 return target;
8628}
8629
8630/* Given that ARG is being passed as operand OPNUM to instruction ICODE,
839a4992 8631 check whether ARG satisfies the operand's constraints. If it doesn't,
36a05131
BS
8632 copy ARG to a temporary register and return that. Otherwise return ARG
8633 itself. */
8634
8635static rtx
f2206911 8636frv_legitimize_argument (enum insn_code icode, int opnum, rtx arg)
36a05131 8637{
ef4bddc2 8638 machine_mode mode = insn_data[icode].operand[opnum].mode;
36a05131
BS
8639
8640 if ((*insn_data[icode].operand[opnum].predicate) (arg, mode))
8641 return arg;
8642 else
8643 return copy_to_mode_reg (mode, arg);
8644}
8645
c14ff86e
AH
8646/* Return a volatile memory reference of mode MODE whose address is ARG. */
8647
8648static rtx
ef4bddc2 8649frv_volatile_memref (machine_mode mode, rtx arg)
c14ff86e
AH
8650{
8651 rtx mem;
8652
8653 mem = gen_rtx_MEM (mode, memory_address (mode, arg));
8654 MEM_VOLATILE_P (mem) = 1;
8655 return mem;
8656}
8657
36a05131
BS
8658/* Expand builtins that take a single, constant argument. At the moment,
8659 only MHDSETS falls into this category. */
8660
8661static rtx
2396bce1 8662frv_expand_set_builtin (enum insn_code icode, tree call, rtx target)
36a05131
BS
8663{
8664 rtx pat;
2396bce1 8665 rtx op0 = frv_read_argument (call, 0);
36a05131
BS
8666
8667 if (! frv_check_constant_argument (icode, 1, op0))
8668 return NULL_RTX;
8669
8670 target = frv_legitimize_target (icode, target);
8671 pat = GEN_FCN (icode) (target, op0);
8672 if (! pat)
8673 return NULL_RTX;
8674
8675 emit_insn (pat);
8676 return target;
8677}
8678
87b483a1 8679/* Expand builtins that take one operand. */
36a05131
BS
8680
8681static rtx
2396bce1 8682frv_expand_unop_builtin (enum insn_code icode, tree call, rtx target)
36a05131
BS
8683{
8684 rtx pat;
2396bce1 8685 rtx op0 = frv_read_argument (call, 0);
36a05131
BS
8686
8687 target = frv_legitimize_target (icode, target);
8688 op0 = frv_legitimize_argument (icode, 1, op0);
8689 pat = GEN_FCN (icode) (target, op0);
8690 if (! pat)
8691 return NULL_RTX;
8692
8693 emit_insn (pat);
8694 return target;
8695}
8696
87b483a1 8697/* Expand builtins that take two operands. */
36a05131
BS
8698
8699static rtx
2396bce1 8700frv_expand_binop_builtin (enum insn_code icode, tree call, rtx target)
36a05131
BS
8701{
8702 rtx pat;
2396bce1
EC
8703 rtx op0 = frv_read_argument (call, 0);
8704 rtx op1 = frv_read_argument (call, 1);
36a05131
BS
8705
8706 target = frv_legitimize_target (icode, target);
8707 op0 = frv_legitimize_argument (icode, 1, op0);
8708 op1 = frv_legitimize_argument (icode, 2, op1);
8709 pat = GEN_FCN (icode) (target, op0, op1);
8710 if (! pat)
8711 return NULL_RTX;
8712
8713 emit_insn (pat);
8714 return target;
8715}
8716
8717/* Expand cut-style builtins, which take two operands and an implicit ACCG
87b483a1 8718 one. */
36a05131
BS
8719
8720static rtx
2396bce1 8721frv_expand_cut_builtin (enum insn_code icode, tree call, rtx target)
36a05131
BS
8722{
8723 rtx pat;
2396bce1
EC
8724 rtx op0 = frv_read_argument (call, 0);
8725 rtx op1 = frv_read_argument (call, 1);
36a05131
BS
8726 rtx op2;
8727
8728 target = frv_legitimize_target (icode, target);
8729 op0 = frv_int_to_acc (icode, 1, op0);
8730 if (! op0)
8731 return NULL_RTX;
8732
8733 if (icode == CODE_FOR_mdcutssi || GET_CODE (op1) == CONST_INT)
8734 {
8735 if (! frv_check_constant_argument (icode, 2, op1))
8736 return NULL_RTX;
8737 }
8738 else
8739 op1 = frv_legitimize_argument (icode, 2, op1);
8740
8741 op2 = frv_matching_accg_for_acc (op0);
8742 pat = GEN_FCN (icode) (target, op0, op1, op2);
8743 if (! pat)
8744 return NULL_RTX;
8745
8746 emit_insn (pat);
8747 return target;
8748}
8749
87b483a1 8750/* Expand builtins that take two operands and the second is immediate. */
36a05131
BS
8751
8752static rtx
2396bce1 8753frv_expand_binopimm_builtin (enum insn_code icode, tree call, rtx target)
36a05131
BS
8754{
8755 rtx pat;
2396bce1
EC
8756 rtx op0 = frv_read_argument (call, 0);
8757 rtx op1 = frv_read_argument (call, 1);
36a05131
BS
8758
8759 if (! frv_check_constant_argument (icode, 2, op1))
8760 return NULL_RTX;
8761
8762 target = frv_legitimize_target (icode, target);
8763 op0 = frv_legitimize_argument (icode, 1, op0);
8764 pat = GEN_FCN (icode) (target, op0, op1);
8765 if (! pat)
8766 return NULL_RTX;
8767
8768 emit_insn (pat);
8769 return target;
8770}
8771
8772/* Expand builtins that take two operands, the first operand being a pointer to
87b483a1 8773 ints and return void. */
36a05131
BS
8774
8775static rtx
2396bce1 8776frv_expand_voidbinop_builtin (enum insn_code icode, tree call)
36a05131
BS
8777{
8778 rtx pat;
2396bce1
EC
8779 rtx op0 = frv_read_argument (call, 0);
8780 rtx op1 = frv_read_argument (call, 1);
ef4bddc2 8781 machine_mode mode0 = insn_data[icode].operand[0].mode;
36a05131
BS
8782 rtx addr;
8783
8784 if (GET_CODE (op0) != MEM)
8785 {
8786 rtx reg = op0;
8787
8788 if (! offsettable_address_p (0, mode0, op0))
8789 {
8790 reg = gen_reg_rtx (Pmode);
f7df4a84 8791 emit_insn (gen_rtx_SET (reg, op0));
36a05131
BS
8792 }
8793
8794 op0 = gen_rtx_MEM (SImode, reg);
8795 }
8796
8797 addr = XEXP (op0, 0);
8798 if (! offsettable_address_p (0, mode0, addr))
8799 addr = copy_to_mode_reg (Pmode, op0);
8800
8801 op0 = change_address (op0, V4SImode, addr);
8802 op1 = frv_legitimize_argument (icode, 1, op1);
8803 pat = GEN_FCN (icode) (op0, op1);
8804 if (! pat)
8805 return 0;
8806
8807 emit_insn (pat);
8808 return 0;
8809}
8810
c557edf4
RS
8811/* Expand builtins that take two long operands and return void. */
8812
8813static rtx
2396bce1 8814frv_expand_int_void2arg (enum insn_code icode, tree call)
c557edf4
RS
8815{
8816 rtx pat;
2396bce1
EC
8817 rtx op0 = frv_read_argument (call, 0);
8818 rtx op1 = frv_read_argument (call, 1);
c557edf4
RS
8819
8820 op0 = frv_legitimize_argument (icode, 1, op0);
8821 op1 = frv_legitimize_argument (icode, 1, op1);
8822 pat = GEN_FCN (icode) (op0, op1);
8823 if (! pat)
8824 return NULL_RTX;
8825
8826 emit_insn (pat);
8827 return NULL_RTX;
8828}
8829
8830/* Expand prefetch builtins. These take a single address as argument. */
8831
8832static rtx
2396bce1 8833frv_expand_prefetches (enum insn_code icode, tree call)
c557edf4
RS
8834{
8835 rtx pat;
2396bce1 8836 rtx op0 = frv_read_argument (call, 0);
c557edf4
RS
8837
8838 pat = GEN_FCN (icode) (force_reg (Pmode, op0));
8839 if (! pat)
8840 return 0;
8841
8842 emit_insn (pat);
8843 return 0;
8844}
8845
36a05131
BS
8846/* Expand builtins that take three operands and return void. The first
8847 argument must be a constant that describes a pair or quad accumulators. A
8848 fourth argument is created that is the accumulator guard register that
8849 corresponds to the accumulator. */
8850
8851static rtx
2396bce1 8852frv_expand_voidtriop_builtin (enum insn_code icode, tree call)
36a05131
BS
8853{
8854 rtx pat;
2396bce1
EC
8855 rtx op0 = frv_read_argument (call, 0);
8856 rtx op1 = frv_read_argument (call, 1);
8857 rtx op2 = frv_read_argument (call, 2);
36a05131
BS
8858 rtx op3;
8859
8860 op0 = frv_int_to_acc (icode, 0, op0);
8861 if (! op0)
8862 return NULL_RTX;
8863
8864 op1 = frv_legitimize_argument (icode, 1, op1);
8865 op2 = frv_legitimize_argument (icode, 2, op2);
8866 op3 = frv_matching_accg_for_acc (op0);
8867 pat = GEN_FCN (icode) (op0, op1, op2, op3);
8868 if (! pat)
8869 return NULL_RTX;
8870
8871 emit_insn (pat);
8872 return NULL_RTX;
8873}
8874
8875/* Expand builtins that perform accumulator-to-accumulator operations.
8876 These builtins take two accumulator numbers as argument and return
8877 void. */
8878
8879static rtx
2396bce1 8880frv_expand_voidaccop_builtin (enum insn_code icode, tree call)
36a05131
BS
8881{
8882 rtx pat;
2396bce1
EC
8883 rtx op0 = frv_read_argument (call, 0);
8884 rtx op1 = frv_read_argument (call, 1);
36a05131
BS
8885 rtx op2;
8886 rtx op3;
8887
8888 op0 = frv_int_to_acc (icode, 0, op0);
8889 if (! op0)
8890 return NULL_RTX;
8891
8892 op1 = frv_int_to_acc (icode, 1, op1);
8893 if (! op1)
8894 return NULL_RTX;
8895
8896 op2 = frv_matching_accg_for_acc (op0);
8897 op3 = frv_matching_accg_for_acc (op1);
8898 pat = GEN_FCN (icode) (op0, op1, op2, op3);
8899 if (! pat)
8900 return NULL_RTX;
8901
8902 emit_insn (pat);
8903 return NULL_RTX;
8904}
8905
38c28a25
AH
8906/* Expand a __builtin_read* function. ICODE is the instruction code for the
8907 membar and TARGET_MODE is the mode that the loaded value should have. */
c14ff86e
AH
8908
8909static rtx
ef4bddc2 8910frv_expand_load_builtin (enum insn_code icode, machine_mode target_mode,
2396bce1 8911 tree call, rtx target)
c14ff86e 8912{
2396bce1 8913 rtx op0 = frv_read_argument (call, 0);
38c28a25
AH
8914 rtx cookie = frv_io_address_cookie (op0);
8915
8916 if (target == 0 || !REG_P (target))
8917 target = gen_reg_rtx (target_mode);
8918 op0 = frv_volatile_memref (insn_data[icode].operand[0].mode, op0);
8919 convert_move (target, op0, 1);
8920 emit_insn (GEN_FCN (icode) (copy_rtx (op0), cookie, GEN_INT (FRV_IO_READ)));
8921 cfun->machine->has_membar_p = 1;
c14ff86e
AH
8922 return target;
8923}
8924
38c28a25 8925/* Likewise __builtin_write* functions. */
c14ff86e
AH
8926
8927static rtx
2396bce1 8928frv_expand_store_builtin (enum insn_code icode, tree call)
c14ff86e 8929{
2396bce1
EC
8930 rtx op0 = frv_read_argument (call, 0);
8931 rtx op1 = frv_read_argument (call, 1);
38c28a25 8932 rtx cookie = frv_io_address_cookie (op0);
c14ff86e 8933
38c28a25
AH
8934 op0 = frv_volatile_memref (insn_data[icode].operand[0].mode, op0);
8935 convert_move (op0, force_reg (insn_data[icode].operand[0].mode, op1), 1);
8936 emit_insn (GEN_FCN (icode) (copy_rtx (op0), cookie, GEN_INT (FRV_IO_WRITE)));
8937 cfun->machine->has_membar_p = 1;
c14ff86e
AH
8938 return NULL_RTX;
8939}
8940
a738d848
RS
8941/* Expand the MDPACKH builtin. It takes four unsigned short arguments and
8942 each argument forms one word of the two double-word input registers.
2396bce1
EC
8943 CALL is the tree for the call and TARGET, if nonnull, suggests a good place
8944 to put the return value. */
a738d848
RS
8945
8946static rtx
2396bce1 8947frv_expand_mdpackh_builtin (tree call, rtx target)
a738d848
RS
8948{
8949 enum insn_code icode = CODE_FOR_mdpackh;
8950 rtx pat, op0, op1;
2396bce1
EC
8951 rtx arg1 = frv_read_argument (call, 0);
8952 rtx arg2 = frv_read_argument (call, 1);
8953 rtx arg3 = frv_read_argument (call, 2);
8954 rtx arg4 = frv_read_argument (call, 3);
a738d848
RS
8955
8956 target = frv_legitimize_target (icode, target);
8957 op0 = gen_reg_rtx (DImode);
8958 op1 = gen_reg_rtx (DImode);
8959
0fa2e4df 8960 /* The high half of each word is not explicitly initialized, so indicate
a738d848 8961 that the input operands are not live before this point. */
c41c1387
RS
8962 emit_clobber (op0);
8963 emit_clobber (op1);
a738d848
RS
8964
8965 /* Move each argument into the low half of its associated input word. */
8966 emit_move_insn (simplify_gen_subreg (HImode, op0, DImode, 2), arg1);
8967 emit_move_insn (simplify_gen_subreg (HImode, op0, DImode, 6), arg2);
8968 emit_move_insn (simplify_gen_subreg (HImode, op1, DImode, 2), arg3);
8969 emit_move_insn (simplify_gen_subreg (HImode, op1, DImode, 6), arg4);
8970
8971 pat = GEN_FCN (icode) (target, op0, op1);
8972 if (! pat)
8973 return NULL_RTX;
8974
8975 emit_insn (pat);
8976 return target;
8977}
8978
36a05131
BS
8979/* Expand the MCLRACC builtin. This builtin takes a single accumulator
8980 number as argument. */
8981
8982static rtx
2396bce1 8983frv_expand_mclracc_builtin (tree call)
36a05131
BS
8984{
8985 enum insn_code icode = CODE_FOR_mclracc;
8986 rtx pat;
2396bce1 8987 rtx op0 = frv_read_argument (call, 0);
36a05131
BS
8988
8989 op0 = frv_int_to_acc (icode, 0, op0);
8990 if (! op0)
8991 return NULL_RTX;
8992
8993 pat = GEN_FCN (icode) (op0);
8994 if (pat)
8995 emit_insn (pat);
8996
8997 return NULL_RTX;
8998}
8999
9000/* Expand builtins that take no arguments. */
9001
9002static rtx
f2206911 9003frv_expand_noargs_builtin (enum insn_code icode)
36a05131 9004{
a556fd39 9005 rtx pat = GEN_FCN (icode) (const0_rtx);
36a05131
BS
9006 if (pat)
9007 emit_insn (pat);
9008
9009 return NULL_RTX;
9010}
9011
9012/* Expand MRDACC and MRDACCG. These builtins take a single accumulator
9013 number or accumulator guard number as argument and return an SI integer. */
9014
9015static rtx
2396bce1 9016frv_expand_mrdacc_builtin (enum insn_code icode, tree call)
36a05131
BS
9017{
9018 rtx pat;
9019 rtx target = gen_reg_rtx (SImode);
2396bce1 9020 rtx op0 = frv_read_argument (call, 0);
36a05131
BS
9021
9022 op0 = frv_int_to_acc (icode, 1, op0);
9023 if (! op0)
9024 return NULL_RTX;
9025
9026 pat = GEN_FCN (icode) (target, op0);
9027 if (! pat)
9028 return NULL_RTX;
9029
9030 emit_insn (pat);
9031 return target;
9032}
9033
9034/* Expand MWTACC and MWTACCG. These builtins take an accumulator or
9035 accumulator guard as their first argument and an SImode value as their
9036 second. */
9037
9038static rtx
2396bce1 9039frv_expand_mwtacc_builtin (enum insn_code icode, tree call)
36a05131
BS
9040{
9041 rtx pat;
2396bce1
EC
9042 rtx op0 = frv_read_argument (call, 0);
9043 rtx op1 = frv_read_argument (call, 1);
36a05131
BS
9044
9045 op0 = frv_int_to_acc (icode, 0, op0);
9046 if (! op0)
9047 return NULL_RTX;
9048
9049 op1 = frv_legitimize_argument (icode, 1, op1);
9050 pat = GEN_FCN (icode) (op0, op1);
9051 if (pat)
9052 emit_insn (pat);
9053
9054 return NULL_RTX;
9055}
9056
c557edf4
RS
9057/* Emit a move from SRC to DEST in SImode chunks. This can be used
9058 to move DImode values into and out of IACC0. */
9059
9060static void
9061frv_split_iacc_move (rtx dest, rtx src)
9062{
ef4bddc2 9063 machine_mode inner;
c557edf4
RS
9064 int i;
9065
9066 inner = GET_MODE (dest);
9067 for (i = 0; i < GET_MODE_SIZE (inner); i += GET_MODE_SIZE (SImode))
9068 emit_move_insn (simplify_gen_subreg (SImode, dest, inner, i),
9069 simplify_gen_subreg (SImode, src, inner, i));
9070}
9071
87b483a1 9072/* Expand builtins. */
36a05131 9073
14966b94 9074static rtx
f2206911
KC
9075frv_expand_builtin (tree exp,
9076 rtx target,
9077 rtx subtarget ATTRIBUTE_UNUSED,
ef4bddc2 9078 machine_mode mode ATTRIBUTE_UNUSED,
f2206911 9079 int ignore ATTRIBUTE_UNUSED)
36a05131 9080{
5039610b 9081 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
4d732405 9082 unsigned fcode = DECL_MD_FUNCTION_CODE (fndecl);
36a05131
BS
9083 unsigned i;
9084 struct builtin_description *d;
9085
c557edf4 9086 if (fcode < FRV_BUILTIN_FIRST_NONMEDIA && !TARGET_MEDIA)
36a05131 9087 {
a3f9f006 9088 error ("media functions are not available unless %<-mmedia%> is used");
36a05131
BS
9089 return NULL_RTX;
9090 }
9091
9092 switch (fcode)
9093 {
9094 case FRV_BUILTIN_MCOP1:
9095 case FRV_BUILTIN_MCOP2:
9096 case FRV_BUILTIN_MDUNPACKH:
9097 case FRV_BUILTIN_MBTOHE:
9098 if (! TARGET_MEDIA_REV1)
9099 {
9100 error ("this media function is only available on the fr500");
9101 return NULL_RTX;
9102 }
9103 break;
9104
9105 case FRV_BUILTIN_MQXMACHS:
9106 case FRV_BUILTIN_MQXMACXHS:
9107 case FRV_BUILTIN_MQMACXHS:
9108 case FRV_BUILTIN_MADDACCS:
9109 case FRV_BUILTIN_MSUBACCS:
9110 case FRV_BUILTIN_MASACCS:
9111 case FRV_BUILTIN_MDADDACCS:
9112 case FRV_BUILTIN_MDSUBACCS:
9113 case FRV_BUILTIN_MDASACCS:
9114 case FRV_BUILTIN_MABSHS:
9115 case FRV_BUILTIN_MDROTLI:
9116 case FRV_BUILTIN_MCPLHI:
9117 case FRV_BUILTIN_MCPLI:
9118 case FRV_BUILTIN_MDCUTSSI:
9119 case FRV_BUILTIN_MQSATHS:
9120 case FRV_BUILTIN_MHSETLOS:
9121 case FRV_BUILTIN_MHSETLOH:
9122 case FRV_BUILTIN_MHSETHIS:
9123 case FRV_BUILTIN_MHSETHIH:
9124 case FRV_BUILTIN_MHDSETS:
9125 case FRV_BUILTIN_MHDSETH:
9126 if (! TARGET_MEDIA_REV2)
9127 {
c557edf4
RS
9128 error ("this media function is only available on the fr400"
9129 " and fr550");
9130 return NULL_RTX;
9131 }
9132 break;
9133
9134 case FRV_BUILTIN_SMASS:
9135 case FRV_BUILTIN_SMSSS:
9136 case FRV_BUILTIN_SMU:
9137 case FRV_BUILTIN_ADDSS:
9138 case FRV_BUILTIN_SUBSS:
9139 case FRV_BUILTIN_SLASS:
9140 case FRV_BUILTIN_SCUTSS:
9141 case FRV_BUILTIN_IACCreadll:
9142 case FRV_BUILTIN_IACCreadl:
9143 case FRV_BUILTIN_IACCsetll:
9144 case FRV_BUILTIN_IACCsetl:
9145 if (!TARGET_FR405_BUILTINS)
9146 {
9147 error ("this builtin function is only available"
9148 " on the fr405 and fr450");
9149 return NULL_RTX;
9150 }
9151 break;
9152
9153 case FRV_BUILTIN_PREFETCH:
9154 if (!TARGET_FR500_FR550_BUILTINS)
9155 {
9156 error ("this builtin function is only available on the fr500"
9157 " and fr550");
9158 return NULL_RTX;
9159 }
9160 break;
9161
9162 case FRV_BUILTIN_MQLCLRHS:
9163 case FRV_BUILTIN_MQLMTHS:
9164 case FRV_BUILTIN_MQSLLHI:
9165 case FRV_BUILTIN_MQSRAHI:
9166 if (!TARGET_MEDIA_FR450)
9167 {
9168 error ("this builtin function is only available on the fr450");
36a05131
BS
9169 return NULL_RTX;
9170 }
9171 break;
9172
9173 default:
9174 break;
9175 }
9176
87b483a1 9177 /* Expand unique builtins. */
36a05131
BS
9178
9179 switch (fcode)
9180 {
9181 case FRV_BUILTIN_MTRAP:
9182 return frv_expand_noargs_builtin (CODE_FOR_mtrap);
9183
9184 case FRV_BUILTIN_MCLRACC:
2396bce1 9185 return frv_expand_mclracc_builtin (exp);
36a05131
BS
9186
9187 case FRV_BUILTIN_MCLRACCA:
9188 if (TARGET_ACC_8)
9189 return frv_expand_noargs_builtin (CODE_FOR_mclracca8);
9190 else
9191 return frv_expand_noargs_builtin (CODE_FOR_mclracca4);
9192
9193 case FRV_BUILTIN_MRDACC:
2396bce1 9194 return frv_expand_mrdacc_builtin (CODE_FOR_mrdacc, exp);
36a05131
BS
9195
9196 case FRV_BUILTIN_MRDACCG:
2396bce1 9197 return frv_expand_mrdacc_builtin (CODE_FOR_mrdaccg, exp);
36a05131
BS
9198
9199 case FRV_BUILTIN_MWTACC:
2396bce1 9200 return frv_expand_mwtacc_builtin (CODE_FOR_mwtacc, exp);
36a05131
BS
9201
9202 case FRV_BUILTIN_MWTACCG:
2396bce1 9203 return frv_expand_mwtacc_builtin (CODE_FOR_mwtaccg, exp);
36a05131 9204
a738d848 9205 case FRV_BUILTIN_MDPACKH:
2396bce1 9206 return frv_expand_mdpackh_builtin (exp, target);
a738d848 9207
c557edf4
RS
9208 case FRV_BUILTIN_IACCreadll:
9209 {
2396bce1 9210 rtx src = frv_read_iacc_argument (DImode, exp, 0);
c557edf4
RS
9211 if (target == 0 || !REG_P (target))
9212 target = gen_reg_rtx (DImode);
9213 frv_split_iacc_move (target, src);
9214 return target;
9215 }
9216
9217 case FRV_BUILTIN_IACCreadl:
2396bce1 9218 return frv_read_iacc_argument (SImode, exp, 0);
c557edf4
RS
9219
9220 case FRV_BUILTIN_IACCsetll:
9221 {
2396bce1
EC
9222 rtx dest = frv_read_iacc_argument (DImode, exp, 0);
9223 rtx src = frv_read_argument (exp, 1);
c557edf4
RS
9224 frv_split_iacc_move (dest, force_reg (DImode, src));
9225 return 0;
9226 }
9227
9228 case FRV_BUILTIN_IACCsetl:
9229 {
2396bce1
EC
9230 rtx dest = frv_read_iacc_argument (SImode, exp, 0);
9231 rtx src = frv_read_argument (exp, 1);
c557edf4
RS
9232 emit_move_insn (dest, force_reg (SImode, src));
9233 return 0;
9234 }
9235
36a05131
BS
9236 default:
9237 break;
9238 }
9239
87b483a1 9240 /* Expand groups of builtins. */
36a05131 9241
e97a46ce 9242 for (i = 0, d = bdesc_set; i < ARRAY_SIZE (bdesc_set); i++, d++)
36a05131 9243 if (d->code == fcode)
2396bce1 9244 return frv_expand_set_builtin (d->icode, exp, target);
36a05131 9245
e97a46ce 9246 for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
36a05131 9247 if (d->code == fcode)
2396bce1 9248 return frv_expand_unop_builtin (d->icode, exp, target);
36a05131 9249
e97a46ce 9250 for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
36a05131 9251 if (d->code == fcode)
2396bce1 9252 return frv_expand_binop_builtin (d->icode, exp, target);
36a05131 9253
e97a46ce 9254 for (i = 0, d = bdesc_cut; i < ARRAY_SIZE (bdesc_cut); i++, d++)
36a05131 9255 if (d->code == fcode)
2396bce1 9256 return frv_expand_cut_builtin (d->icode, exp, target);
36a05131 9257
e97a46ce
KG
9258 for (i = 0, d = bdesc_2argimm; i < ARRAY_SIZE (bdesc_2argimm); i++, d++)
9259 if (d->code == fcode)
2396bce1 9260 return frv_expand_binopimm_builtin (d->icode, exp, target);
36a05131 9261
e97a46ce
KG
9262 for (i = 0, d = bdesc_void2arg; i < ARRAY_SIZE (bdesc_void2arg); i++, d++)
9263 if (d->code == fcode)
2396bce1 9264 return frv_expand_voidbinop_builtin (d->icode, exp);
36a05131 9265
e97a46ce
KG
9266 for (i = 0, d = bdesc_void3arg; i < ARRAY_SIZE (bdesc_void3arg); i++, d++)
9267 if (d->code == fcode)
2396bce1 9268 return frv_expand_voidtriop_builtin (d->icode, exp);
e97a46ce
KG
9269
9270 for (i = 0, d = bdesc_voidacc; i < ARRAY_SIZE (bdesc_voidacc); i++, d++)
9271 if (d->code == fcode)
2396bce1 9272 return frv_expand_voidaccop_builtin (d->icode, exp);
36a05131 9273
c557edf4
RS
9274 for (i = 0, d = bdesc_int_void2arg;
9275 i < ARRAY_SIZE (bdesc_int_void2arg); i++, d++)
9276 if (d->code == fcode)
2396bce1 9277 return frv_expand_int_void2arg (d->icode, exp);
c557edf4
RS
9278
9279 for (i = 0, d = bdesc_prefetches;
9280 i < ARRAY_SIZE (bdesc_prefetches); i++, d++)
9281 if (d->code == fcode)
2396bce1 9282 return frv_expand_prefetches (d->icode, exp);
c557edf4 9283
c14ff86e
AH
9284 for (i = 0, d = bdesc_loads; i < ARRAY_SIZE (bdesc_loads); i++, d++)
9285 if (d->code == fcode)
38c28a25 9286 return frv_expand_load_builtin (d->icode, TYPE_MODE (TREE_TYPE (exp)),
2396bce1 9287 exp, target);
c14ff86e
AH
9288
9289 for (i = 0, d = bdesc_stores; i < ARRAY_SIZE (bdesc_stores); i++, d++)
9290 if (d->code == fcode)
2396bce1 9291 return frv_expand_store_builtin (d->icode, exp);
c14ff86e 9292
36a05131
BS
9293 return 0;
9294}
14966b94 9295
b3fbfc07 9296static bool
3101faab 9297frv_in_small_data_p (const_tree decl)
b3fbfc07 9298{
0f6e5d45 9299 HOST_WIDE_INT size;
f961457f 9300 const char *section_name;
0f6e5d45
RH
9301
9302 /* Don't apply the -G flag to internal compiler structures. We
9303 should leave such structures in the main data section, partly
9304 for efficiency and partly because the size of some of them
9305 (such as C++ typeinfos) is not known until later. */
9306 if (TREE_CODE (decl) != VAR_DECL || DECL_ARTIFICIAL (decl))
9307 return false;
9308
0f6e5d45
RH
9309 /* If we already know which section the decl should be in, see if
9310 it's a small data section. */
9311 section_name = DECL_SECTION_NAME (decl);
9312 if (section_name)
9313 {
0f6e5d45
RH
9314 if (frv_string_begins_with (section_name, ".sdata"))
9315 return true;
9316 if (frv_string_begins_with (section_name, ".sbss"))
9317 return true;
68c0ab4f 9318 return false;
0f6e5d45 9319 }
b3fbfc07 9320
68c0ab4f 9321 size = int_size_in_bytes (TREE_TYPE (decl));
fa37ed29 9322 if (size > 0 && size <= g_switch_value)
68c0ab4f
RS
9323 return true;
9324
0f6e5d45 9325 return false;
b3fbfc07 9326}
3c50106f
RH
9327\f
9328static bool
f2206911 9329frv_rtx_costs (rtx x,
e548c9df
AM
9330 machine_mode mode,
9331 int outer_code,
68f932c4 9332 int opno ATTRIBUTE_UNUSED,
f40751dd
JH
9333 int *total,
9334 bool speed ATTRIBUTE_UNUSED)
3c50106f 9335{
e548c9df
AM
9336 int code = GET_CODE (x);
9337
34208acf
AO
9338 if (outer_code == MEM)
9339 {
9340 /* Don't differentiate between memory addresses. All the ones
9341 we accept have equal cost. */
9342 *total = COSTS_N_INSNS (0);
9343 return true;
9344 }
9345
3c50106f
RH
9346 switch (code)
9347 {
9348 case CONST_INT:
2300b9dd 9349 /* Make 12-bit integers really cheap. */
2f5b1308 9350 if (IN_RANGE (INTVAL (x), -2048, 2047))
3c50106f
RH
9351 {
9352 *total = 0;
9353 return true;
9354 }
87b483a1 9355 /* Fall through. */
3c50106f
RH
9356
9357 case CONST:
9358 case LABEL_REF:
9359 case SYMBOL_REF:
9360 case CONST_DOUBLE:
9361 *total = COSTS_N_INSNS (2);
9362 return true;
9363
9364 case PLUS:
9365 case MINUS:
9366 case AND:
9367 case IOR:
9368 case XOR:
9369 case ASHIFT:
9370 case ASHIFTRT:
9371 case LSHIFTRT:
9372 case NOT:
9373 case NEG:
9374 case COMPARE:
e548c9df 9375 if (mode == SImode)
3c50106f 9376 *total = COSTS_N_INSNS (1);
e548c9df 9377 else if (mode == DImode)
3c50106f
RH
9378 *total = COSTS_N_INSNS (2);
9379 else
9380 *total = COSTS_N_INSNS (3);
9381 return true;
9382
9383 case MULT:
e548c9df 9384 if (mode == SImode)
3c50106f
RH
9385 *total = COSTS_N_INSNS (2);
9386 else
9387 *total = COSTS_N_INSNS (6); /* guess */
9388 return true;
9389
9390 case DIV:
9391 case UDIV:
9392 case MOD:
9393 case UMOD:
9394 *total = COSTS_N_INSNS (18);
9395 return true;
9396
34208acf
AO
9397 case MEM:
9398 *total = COSTS_N_INSNS (3);
9399 return true;
9400
3c50106f
RH
9401 default:
9402 return false;
9403 }
9404}
90a63880
RH
9405\f
9406static void
f2206911 9407frv_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
90a63880 9408{
d6b5193b 9409 switch_to_section (ctors_section);
90a63880 9410 assemble_align (POINTER_SIZE);
34208acf
AO
9411 if (TARGET_FDPIC)
9412 {
44e91694
NS
9413 int ok = frv_assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, 1);
9414
9415 gcc_assert (ok);
34208acf
AO
9416 return;
9417 }
90a63880
RH
9418 assemble_integer_with_op ("\t.picptr\t", symbol);
9419}
9420
9421static void
f2206911 9422frv_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
90a63880 9423{
d6b5193b 9424 switch_to_section (dtors_section);
90a63880 9425 assemble_align (POINTER_SIZE);
34208acf
AO
9426 if (TARGET_FDPIC)
9427 {
44e91694 9428 int ok = frv_assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, 1);
2396bce1 9429
44e91694 9430 gcc_assert (ok);
34208acf
AO
9431 return;
9432 }
90a63880
RH
9433 assemble_integer_with_op ("\t.picptr\t", symbol);
9434}
8ac411c7
KH
9435
9436/* Worker function for TARGET_STRUCT_VALUE_RTX. */
9437
9438static rtx
9439frv_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
9440 int incoming ATTRIBUTE_UNUSED)
9441{
9442 return gen_rtx_REG (Pmode, FRV_STRUCT_VALUE_REGNUM);
9443}
c557edf4 9444
bef8809e
AH
9445#define TLS_BIAS (2048 - 16)
9446
fdbe66f2 9447/* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
bef8809e
AH
9448 We need to emit DTP-relative relocations. */
9449
fdbe66f2 9450static void
bef8809e
AH
9451frv_output_dwarf_dtprel (FILE *file, int size, rtx x)
9452{
44e91694 9453 gcc_assert (size == 4);
bef8809e
AH
9454 fputs ("\t.picptr\ttlsmoff(", file);
9455 /* We want the unbiased TLS offset, so add the bias to the
9456 expression, such that the implicit biasing cancels out. */
0a81f074 9457 output_addr_const (file, plus_constant (Pmode, x, TLS_BIAS));
bef8809e
AH
9458 fputs (")", file);
9459}
9460
c557edf4 9461#include "gt-frv.h"