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