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