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