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