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