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