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