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