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