1 /* Subroutines used for MIPS code generation.
2 Copyright (C) 1989, 1990, 1991, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4 Contributed by A. Lichnewsky, lich@inria.inria.fr.
5 Changes by Michael Meissner, meissner@osf.org.
6 64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
7 Brendan Eich, brendan@microunity.com.
9 This file is part of GCC.
11 GCC is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
16 GCC is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with GCC; see the file COPYING. If not, write to
23 the Free Software Foundation, 59 Temple Place - Suite 330,
24 Boston, MA 02111-1307, USA. */
28 #include "coretypes.h"
33 #include "hard-reg-set.h"
35 #include "insn-config.h"
36 #include "conditions.h"
37 #include "insn-attr.h"
53 #include "target-def.h"
54 #include "integrate.h"
55 #include "langhooks.h"
56 #include "cfglayout.h"
57 #include "sched-int.h"
58 #include "tree-gimple.h"
60 /* True if X is an unspec wrapper around a SYMBOL_REF or LABEL_REF. */
61 #define UNSPEC_ADDRESS_P(X) \
62 (GET_CODE (X) == UNSPEC \
63 && XINT (X, 1) >= UNSPEC_ADDRESS_FIRST \
64 && XINT (X, 1) < UNSPEC_ADDRESS_FIRST + NUM_SYMBOL_TYPES)
66 /* Extract the symbol or label from UNSPEC wrapper X. */
67 #define UNSPEC_ADDRESS(X) \
70 /* Extract the symbol type from UNSPEC wrapper X. */
71 #define UNSPEC_ADDRESS_TYPE(X) \
72 ((enum mips_symbol_type) (XINT (X, 1) - UNSPEC_ADDRESS_FIRST))
74 /* The maximum distance between the top of the stack frame and the
75 value $sp has when we save & restore registers.
77 Use a maximum gap of 0x100 in the mips16 case. We can then use
78 unextended instructions to save and restore registers, and to
79 allocate and deallocate the top part of the frame.
81 The value in the !mips16 case must be a SMALL_OPERAND and must
82 preserve the maximum stack alignment. */
83 #define MIPS_MAX_FIRST_STACK_STEP (TARGET_MIPS16 ? 0x100 : 0x7ff0)
85 /* True if INSN is a mips.md pattern or asm statement. */
86 #define USEFUL_INSN_P(INSN) \
88 && GET_CODE (PATTERN (INSN)) != USE \
89 && GET_CODE (PATTERN (INSN)) != CLOBBER \
90 && GET_CODE (PATTERN (INSN)) != ADDR_VEC \
91 && GET_CODE (PATTERN (INSN)) != ADDR_DIFF_VEC)
93 /* If INSN is a delayed branch sequence, return the first instruction
94 in the sequence, otherwise return INSN itself. */
95 #define SEQ_BEGIN(INSN) \
96 (INSN_P (INSN) && GET_CODE (PATTERN (INSN)) == SEQUENCE \
97 ? XVECEXP (PATTERN (INSN), 0, 0) \
100 /* Likewise for the last instruction in a delayed branch sequence. */
101 #define SEQ_END(INSN) \
102 (INSN_P (INSN) && GET_CODE (PATTERN (INSN)) == SEQUENCE \
103 ? XVECEXP (PATTERN (INSN), 0, XVECLEN (PATTERN (INSN), 0) - 1) \
106 /* Execute the following loop body with SUBINSN set to each instruction
107 between SEQ_BEGIN (INSN) and SEQ_END (INSN) inclusive. */
108 #define FOR_EACH_SUBINSN(SUBINSN, INSN) \
109 for ((SUBINSN) = SEQ_BEGIN (INSN); \
110 (SUBINSN) != NEXT_INSN (SEQ_END (INSN)); \
111 (SUBINSN) = NEXT_INSN (SUBINSN))
113 /* Classifies an address.
116 A natural register + offset address. The register satisfies
117 mips_valid_base_register_p and the offset is a const_arith_operand.
120 A LO_SUM rtx. The first operand is a valid base register and
121 the second operand is a symbolic address.
124 A signed 16-bit constant address.
127 A constant symbolic address (equivalent to CONSTANT_SYMBOLIC). */
128 enum mips_address_type {
135 /* A function to save or store a register. The first argument is the
136 register and the second is the stack slot. */
137 typedef void (*mips_save_restore_fn) (rtx, rtx);
139 struct mips16_constant;
140 struct mips_arg_info;
141 struct mips_address_info;
142 struct mips_integer_op;
145 static enum mips_symbol_type mips_classify_symbol (rtx);
146 static void mips_split_const (rtx, rtx *, HOST_WIDE_INT *);
147 static bool mips_offset_within_object_p (rtx, HOST_WIDE_INT);
148 static bool mips_valid_base_register_p (rtx, enum machine_mode, int);
149 static bool mips_symbolic_address_p (enum mips_symbol_type, enum machine_mode);
150 static bool mips_classify_address (struct mips_address_info *, rtx,
151 enum machine_mode, int);
152 static int mips_symbol_insns (enum mips_symbol_type);
153 static bool mips16_unextended_reference_p (enum machine_mode mode, rtx, rtx);
154 static rtx mips_force_temporary (rtx, rtx);
155 static rtx mips_split_symbol (rtx, rtx);
156 static rtx mips_unspec_offset_high (rtx, rtx, rtx, enum mips_symbol_type);
157 static rtx mips_add_offset (rtx, rtx, HOST_WIDE_INT);
158 static unsigned int mips_build_shift (struct mips_integer_op *, HOST_WIDE_INT);
159 static unsigned int mips_build_lower (struct mips_integer_op *,
160 unsigned HOST_WIDE_INT);
161 static unsigned int mips_build_integer (struct mips_integer_op *,
162 unsigned HOST_WIDE_INT);
163 static void mips_move_integer (rtx, unsigned HOST_WIDE_INT);
164 static void mips_legitimize_const_move (enum machine_mode, rtx, rtx);
165 static int m16_check_op (rtx, int, int, int);
166 static bool mips_rtx_costs (rtx, int, int, int *);
167 static int mips_address_cost (rtx);
168 static void mips_emit_compare (enum rtx_code *, rtx *, rtx *, bool);
169 static void mips_load_call_address (rtx, rtx, int);
170 static bool mips_function_ok_for_sibcall (tree, tree);
171 static void mips_block_move_straight (rtx, rtx, HOST_WIDE_INT);
172 static void mips_adjust_block_mem (rtx, HOST_WIDE_INT, rtx *, rtx *);
173 static void mips_block_move_loop (rtx, rtx, HOST_WIDE_INT);
174 static void mips_arg_info (const CUMULATIVE_ARGS *, enum machine_mode,
175 tree, int, struct mips_arg_info *);
176 static bool mips_get_unaligned_mem (rtx *, unsigned int, int, rtx *, rtx *);
177 static void mips_set_architecture (const struct mips_cpu_info *);
178 static void mips_set_tune (const struct mips_cpu_info *);
179 static struct machine_function *mips_init_machine_status (void);
180 static void print_operand_reloc (FILE *, rtx, const char **);
182 static void irix_output_external_libcall (rtx);
184 static void mips_file_start (void);
185 static void mips_file_end (void);
186 static bool mips_rewrite_small_data_p (rtx);
187 static int mips_small_data_pattern_1 (rtx *, void *);
188 static int mips_rewrite_small_data_1 (rtx *, void *);
189 static bool mips_function_has_gp_insn (void);
190 static unsigned int mips_global_pointer (void);
191 static bool mips_save_reg_p (unsigned int);
192 static void mips_save_restore_reg (enum machine_mode, int, HOST_WIDE_INT,
193 mips_save_restore_fn);
194 static void mips_for_each_saved_reg (HOST_WIDE_INT, mips_save_restore_fn);
195 static void mips_output_cplocal (void);
196 static void mips_emit_loadgp (void);
197 static void mips_output_function_prologue (FILE *, HOST_WIDE_INT);
198 static void mips_set_frame_expr (rtx);
199 static rtx mips_frame_set (rtx, rtx);
200 static void mips_save_reg (rtx, rtx);
201 static void mips_output_function_epilogue (FILE *, HOST_WIDE_INT);
202 static void mips_restore_reg (rtx, rtx);
203 static void mips_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
204 HOST_WIDE_INT, tree);
205 static int symbolic_expression_p (rtx);
206 static void mips_select_rtx_section (enum machine_mode, rtx,
207 unsigned HOST_WIDE_INT);
208 static bool mips_in_small_data_p (tree);
209 static int mips_fpr_return_fields (tree, tree *);
210 static bool mips_return_in_msb (tree);
211 static rtx mips_return_fpr_pair (enum machine_mode mode,
212 enum machine_mode mode1, HOST_WIDE_INT,
213 enum machine_mode mode2, HOST_WIDE_INT);
214 static rtx mips16_gp_pseudo_reg (void);
215 static void mips16_fp_args (FILE *, int, int);
216 static void build_mips16_function_stub (FILE *);
217 static rtx dump_constants_1 (enum machine_mode, rtx, rtx);
218 static void dump_constants (struct mips16_constant *, rtx);
219 static int mips16_insn_length (rtx);
220 static int mips16_rewrite_pool_refs (rtx *, void *);
221 static void mips16_lay_out_constants (void);
222 static void mips_sim_reset (struct mips_sim *);
223 static void mips_sim_init (struct mips_sim *, state_t);
224 static void mips_sim_next_cycle (struct mips_sim *);
225 static void mips_sim_wait_reg (struct mips_sim *, rtx, rtx);
226 static int mips_sim_wait_regs_2 (rtx *, void *);
227 static void mips_sim_wait_regs_1 (rtx *, void *);
228 static void mips_sim_wait_regs (struct mips_sim *, rtx);
229 static void mips_sim_wait_units (struct mips_sim *, rtx);
230 static void mips_sim_wait_insn (struct mips_sim *, rtx);
231 static void mips_sim_record_set (rtx, rtx, void *);
232 static void mips_sim_issue_insn (struct mips_sim *, rtx);
233 static void mips_sim_issue_nop (struct mips_sim *);
234 static void mips_sim_finish_insn (struct mips_sim *, rtx);
235 static void vr4130_avoid_branch_rt_conflict (rtx);
236 static void vr4130_align_insns (void);
237 static void mips_avoid_hazard (rtx, rtx, int *, rtx *, rtx);
238 static void mips_avoid_hazards (void);
239 static void mips_reorg (void);
240 static bool mips_strict_matching_cpu_name_p (const char *, const char *);
241 static bool mips_matching_cpu_name_p (const char *, const char *);
242 static const struct mips_cpu_info *mips_parse_cpu (const char *, const char *);
243 static const struct mips_cpu_info *mips_cpu_info_from_isa (int);
244 static bool mips_return_in_memory (tree, tree);
245 static bool mips_strict_argument_naming (CUMULATIVE_ARGS *);
246 static void mips_macc_chains_record (rtx);
247 static void mips_macc_chains_reorder (rtx *, int);
248 static void vr4130_true_reg_dependence_p_1 (rtx, rtx, void *);
249 static bool vr4130_true_reg_dependence_p (rtx);
250 static bool vr4130_swap_insns_p (rtx, rtx);
251 static void vr4130_reorder (rtx *, int);
252 static void mips_promote_ready (rtx *, int, int);
253 static int mips_sched_reorder (FILE *, int, rtx *, int *, int);
254 static int mips_variable_issue (FILE *, int, rtx, int);
255 static int mips_adjust_cost (rtx, rtx, rtx, int);
256 static int mips_issue_rate (void);
257 static int mips_multipass_dfa_lookahead (void);
258 static void mips_init_libfuncs (void);
259 static void mips_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode,
261 static tree mips_build_builtin_va_list (void);
262 static tree mips_gimplify_va_arg_expr (tree, tree, tree *, tree *);
263 static bool mips_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode mode,
265 static bool mips_vector_mode_supported_p (enum machine_mode);
266 static rtx mips_prepare_builtin_arg (enum insn_code, unsigned int, tree *);
267 static rtx mips_prepare_builtin_target (enum insn_code, unsigned int, rtx);
268 static rtx mips_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
269 static void mips_init_builtins (void);
270 static rtx mips_expand_ps_cond_move_builtin (bool, enum insn_code, rtx, tree);
271 static rtx mips_expand_compare_builtin (bool, rtx, rtx, rtx, int);
272 static rtx mips_expand_scalar_compare_builtin (enum insn_code, rtx, tree);
273 static rtx mips_expand_4s_compare_builtin (enum mips_cmp_choice,
274 enum insn_code, rtx, tree);
275 static rtx mips_expand_ps_compare_builtin (enum mips_cmp_choice,
276 enum insn_code, rtx, tree);
278 /* Structure to be filled in by compute_frame_size with register
279 save masks, and offsets for the current function. */
281 struct mips_frame_info GTY(())
283 HOST_WIDE_INT total_size; /* # bytes that the entire frame takes up */
284 HOST_WIDE_INT var_size; /* # bytes that variables take up */
285 HOST_WIDE_INT args_size; /* # bytes that outgoing arguments take up */
286 HOST_WIDE_INT cprestore_size; /* # bytes that the .cprestore slot takes up */
287 HOST_WIDE_INT gp_reg_size; /* # bytes needed to store gp regs */
288 HOST_WIDE_INT fp_reg_size; /* # bytes needed to store fp regs */
289 unsigned int mask; /* mask of saved gp registers */
290 unsigned int fmask; /* mask of saved fp registers */
291 HOST_WIDE_INT gp_save_offset; /* offset from vfp to store gp registers */
292 HOST_WIDE_INT fp_save_offset; /* offset from vfp to store fp registers */
293 HOST_WIDE_INT gp_sp_offset; /* offset from new sp to store gp registers */
294 HOST_WIDE_INT fp_sp_offset; /* offset from new sp to store fp registers */
295 bool initialized; /* true if frame size already calculated */
296 int num_gp; /* number of gp registers saved */
297 int num_fp; /* number of fp registers saved */
300 struct machine_function GTY(()) {
301 /* Pseudo-reg holding the value of $28 in a mips16 function which
302 refers to GP relative global variables. */
303 rtx mips16_gp_pseudo_rtx;
305 /* Current frame information, calculated by compute_frame_size. */
306 struct mips_frame_info frame;
308 /* The register to use as the global pointer within this function. */
309 unsigned int global_pointer;
311 /* True if mips_adjust_insn_length should ignore an instruction's
313 bool ignore_hazard_length_p;
315 /* True if the whole function is suitable for .set noreorder and
317 bool all_noreorder_p;
319 /* True if the function is known to have an instruction that needs $gp. */
323 /* Information about a single argument. */
326 /* True if the argument is passed in a floating-point register, or
327 would have been if we hadn't run out of registers. */
330 /* The number of words passed in registers, rounded up. */
331 unsigned int reg_words;
333 /* The offset of the first register from GP_ARG_FIRST or FP_ARG_FIRST,
334 or MAX_ARGS_IN_REGISTERS if the argument is passed entirely
336 unsigned int reg_offset;
338 /* The number of words that must be passed on the stack, rounded up. */
339 unsigned int stack_words;
341 /* The offset from the start of the stack overflow area of the argument's
342 first stack word. Only meaningful when STACK_WORDS is nonzero. */
343 unsigned int stack_offset;
347 /* Information about an address described by mips_address_type.
353 REG is the base register and OFFSET is the constant offset.
356 REG is the register that contains the high part of the address,
357 OFFSET is the symbolic address being referenced and SYMBOL_TYPE
358 is the type of OFFSET's symbol.
361 SYMBOL_TYPE is the type of symbol being referenced. */
363 struct mips_address_info
365 enum mips_address_type type;
368 enum mips_symbol_type symbol_type;
372 /* One stage in a constant building sequence. These sequences have
376 A = A CODE[1] VALUE[1]
377 A = A CODE[2] VALUE[2]
380 where A is an accumulator, each CODE[i] is a binary rtl operation
381 and each VALUE[i] is a constant integer. */
382 struct mips_integer_op {
384 unsigned HOST_WIDE_INT value;
388 /* The largest number of operations needed to load an integer constant.
389 The worst accepted case for 64-bit constants is LUI,ORI,SLL,ORI,SLL,ORI.
390 When the lowest bit is clear, we can try, but reject a sequence with
391 an extra SLL at the end. */
392 #define MIPS_MAX_INTEGER_OPS 7
395 /* Global variables for machine-dependent things. */
397 /* Threshold for data being put into the small data/bss area, instead
398 of the normal data area. */
399 int mips_section_threshold = -1;
401 /* Count the number of .file directives, so that .loc is up to date. */
402 int num_source_filenames = 0;
404 /* Count the number of sdb related labels are generated (to find block
405 start and end boundaries). */
406 int sdb_label_count = 0;
408 /* Next label # for each statement for Silicon Graphics IRIS systems. */
411 /* Linked list of all externals that are to be emitted when optimizing
412 for the global pointer if they haven't been declared by the end of
413 the program with an appropriate .comm or initialization. */
415 struct extern_list GTY (())
417 struct extern_list *next; /* next external */
418 const char *name; /* name of the external */
419 int size; /* size in bytes */
422 static GTY (()) struct extern_list *extern_head = 0;
424 /* Name of the file containing the current function. */
425 const char *current_function_file = "";
427 /* Number of nested .set noreorder, noat, nomacro, and volatile requests. */
433 /* The next branch instruction is a branch likely, not branch normal. */
434 int mips_branch_likely;
436 /* The operands passed to the last cmpMM expander. */
439 /* The target cpu for code generation. */
440 enum processor_type mips_arch;
441 const struct mips_cpu_info *mips_arch_info;
443 /* The target cpu for optimization and scheduling. */
444 enum processor_type mips_tune;
445 const struct mips_cpu_info *mips_tune_info;
447 /* Which instruction set architecture to use. */
450 /* Which ABI to use. */
453 /* Strings to hold which cpu and instruction set architecture to use. */
454 const char *mips_arch_string; /* for -march=<xxx> */
455 const char *mips_tune_string; /* for -mtune=<xxx> */
456 const char *mips_isa_string; /* for -mips{1,2,3,4} */
457 const char *mips_abi_string; /* for -mabi={32,n32,64,eabi} */
459 /* Whether we are generating mips16 hard float code. In mips16 mode
460 we always set TARGET_SOFT_FLOAT; this variable is nonzero if
461 -msoft-float was not specified by the user, which means that we
462 should arrange to call mips32 hard floating point code. */
463 int mips16_hard_float;
465 const char *mips_cache_flush_func = CACHE_FLUSH_FUNC;
467 /* If TRUE, we split addresses into their high and low parts in the RTL. */
468 int mips_split_addresses;
470 /* Mode used for saving/restoring general purpose registers. */
471 static enum machine_mode gpr_mode;
473 /* Array giving truth value on whether or not a given hard register
474 can support a given mode. */
475 char mips_hard_regno_mode_ok[(int)MAX_MACHINE_MODE][FIRST_PSEUDO_REGISTER];
477 /* List of all MIPS punctuation characters used by print_operand. */
478 char mips_print_operand_punct[256];
480 /* Map GCC register number to debugger register number. */
481 int mips_dbx_regno[FIRST_PSEUDO_REGISTER];
483 /* A copy of the original flag_delayed_branch: see override_options. */
484 static int mips_flag_delayed_branch;
486 static GTY (()) int mips_output_filename_first_time = 1;
488 /* mips_split_p[X] is true if symbols of type X can be split by
489 mips_split_symbol(). */
490 static bool mips_split_p[NUM_SYMBOL_TYPES];
492 /* mips_lo_relocs[X] is the relocation to use when a symbol of type X
493 appears in a LO_SUM. It can be null if such LO_SUMs aren't valid or
494 if they are matched by a special .md file pattern. */
495 static const char *mips_lo_relocs[NUM_SYMBOL_TYPES];
497 /* Likewise for HIGHs. */
498 static const char *mips_hi_relocs[NUM_SYMBOL_TYPES];
500 /* Map hard register number to register class */
501 const enum reg_class mips_regno_to_class[] =
503 LEA_REGS, LEA_REGS, M16_NA_REGS, M16_NA_REGS,
504 M16_REGS, M16_REGS, M16_REGS, M16_REGS,
505 LEA_REGS, LEA_REGS, LEA_REGS, LEA_REGS,
506 LEA_REGS, LEA_REGS, LEA_REGS, LEA_REGS,
507 M16_NA_REGS, M16_NA_REGS, LEA_REGS, LEA_REGS,
508 LEA_REGS, LEA_REGS, LEA_REGS, LEA_REGS,
509 T_REG, PIC_FN_ADDR_REG, LEA_REGS, LEA_REGS,
510 LEA_REGS, LEA_REGS, LEA_REGS, LEA_REGS,
511 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
512 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
513 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
514 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
515 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
516 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
517 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
518 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
519 HI_REG, LO_REG, NO_REGS, ST_REGS,
520 ST_REGS, ST_REGS, ST_REGS, ST_REGS,
521 ST_REGS, ST_REGS, ST_REGS, NO_REGS,
522 NO_REGS, ALL_REGS, ALL_REGS, NO_REGS,
523 COP0_REGS, COP0_REGS, COP0_REGS, COP0_REGS,
524 COP0_REGS, COP0_REGS, COP0_REGS, COP0_REGS,
525 COP0_REGS, COP0_REGS, COP0_REGS, COP0_REGS,
526 COP0_REGS, COP0_REGS, COP0_REGS, COP0_REGS,
527 COP0_REGS, COP0_REGS, COP0_REGS, COP0_REGS,
528 COP0_REGS, COP0_REGS, COP0_REGS, COP0_REGS,
529 COP0_REGS, COP0_REGS, COP0_REGS, COP0_REGS,
530 COP0_REGS, COP0_REGS, COP0_REGS, COP0_REGS,
531 COP2_REGS, COP2_REGS, COP2_REGS, COP2_REGS,
532 COP2_REGS, COP2_REGS, COP2_REGS, COP2_REGS,
533 COP2_REGS, COP2_REGS, COP2_REGS, COP2_REGS,
534 COP2_REGS, COP2_REGS, COP2_REGS, COP2_REGS,
535 COP2_REGS, COP2_REGS, COP2_REGS, COP2_REGS,
536 COP2_REGS, COP2_REGS, COP2_REGS, COP2_REGS,
537 COP2_REGS, COP2_REGS, COP2_REGS, COP2_REGS,
538 COP2_REGS, COP2_REGS, COP2_REGS, COP2_REGS,
539 COP3_REGS, COP3_REGS, COP3_REGS, COP3_REGS,
540 COP3_REGS, COP3_REGS, COP3_REGS, COP3_REGS,
541 COP3_REGS, COP3_REGS, COP3_REGS, COP3_REGS,
542 COP3_REGS, COP3_REGS, COP3_REGS, COP3_REGS,
543 COP3_REGS, COP3_REGS, COP3_REGS, COP3_REGS,
544 COP3_REGS, COP3_REGS, COP3_REGS, COP3_REGS,
545 COP3_REGS, COP3_REGS, COP3_REGS, COP3_REGS,
546 COP3_REGS, COP3_REGS, COP3_REGS, COP3_REGS
549 /* Map register constraint character to register class. */
550 enum reg_class mips_char_to_class[256];
552 /* A table describing all the processors gcc knows about. Names are
553 matched in the order listed. The first mention of an ISA level is
554 taken as the canonical name for that ISA.
556 To ease comparison, please keep this table in the same order as
557 gas's mips_cpu_info_table[]. */
558 const struct mips_cpu_info mips_cpu_info_table[] = {
559 /* Entries for generic ISAs */
560 { "mips1", PROCESSOR_R3000, 1 },
561 { "mips2", PROCESSOR_R6000, 2 },
562 { "mips3", PROCESSOR_R4000, 3 },
563 { "mips4", PROCESSOR_R8000, 4 },
564 { "mips32", PROCESSOR_4KC, 32 },
565 { "mips32r2", PROCESSOR_M4K, 33 },
566 { "mips64", PROCESSOR_5KC, 64 },
569 { "r3000", PROCESSOR_R3000, 1 },
570 { "r2000", PROCESSOR_R3000, 1 }, /* = r3000 */
571 { "r3900", PROCESSOR_R3900, 1 },
574 { "r6000", PROCESSOR_R6000, 2 },
577 { "r4000", PROCESSOR_R4000, 3 },
578 { "vr4100", PROCESSOR_R4100, 3 },
579 { "vr4111", PROCESSOR_R4111, 3 },
580 { "vr4120", PROCESSOR_R4120, 3 },
581 { "vr4130", PROCESSOR_R4130, 3 },
582 { "vr4300", PROCESSOR_R4300, 3 },
583 { "r4400", PROCESSOR_R4000, 3 }, /* = r4000 */
584 { "r4600", PROCESSOR_R4600, 3 },
585 { "orion", PROCESSOR_R4600, 3 }, /* = r4600 */
586 { "r4650", PROCESSOR_R4650, 3 },
589 { "r8000", PROCESSOR_R8000, 4 },
590 { "vr5000", PROCESSOR_R5000, 4 },
591 { "vr5400", PROCESSOR_R5400, 4 },
592 { "vr5500", PROCESSOR_R5500, 4 },
593 { "rm7000", PROCESSOR_R7000, 4 },
594 { "rm9000", PROCESSOR_R9000, 4 },
597 { "4kc", PROCESSOR_4KC, 32 },
598 { "4kp", PROCESSOR_4KC, 32 }, /* = 4kc */
600 /* MIPS32 Release 2 */
601 { "m4k", PROCESSOR_M4K, 33 },
604 { "5kc", PROCESSOR_5KC, 64 },
605 { "20kc", PROCESSOR_20KC, 64 },
606 { "sb1", PROCESSOR_SB1, 64 },
607 { "sr71000", PROCESSOR_SR71000, 64 },
613 /* Nonzero if -march should decide the default value of MASK_SOFT_FLOAT. */
614 #ifndef MIPS_MARCH_CONTROLS_SOFT_FLOAT
615 #define MIPS_MARCH_CONTROLS_SOFT_FLOAT 0
618 /* Initialize the GCC target structure. */
619 #undef TARGET_ASM_ALIGNED_HI_OP
620 #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
621 #undef TARGET_ASM_ALIGNED_SI_OP
622 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
623 #undef TARGET_ASM_ALIGNED_DI_OP
624 #define TARGET_ASM_ALIGNED_DI_OP "\t.dword\t"
626 #undef TARGET_ASM_FUNCTION_PROLOGUE
627 #define TARGET_ASM_FUNCTION_PROLOGUE mips_output_function_prologue
628 #undef TARGET_ASM_FUNCTION_EPILOGUE
629 #define TARGET_ASM_FUNCTION_EPILOGUE mips_output_function_epilogue
630 #undef TARGET_ASM_SELECT_RTX_SECTION
631 #define TARGET_ASM_SELECT_RTX_SECTION mips_select_rtx_section
633 #undef TARGET_SCHED_REORDER
634 #define TARGET_SCHED_REORDER mips_sched_reorder
635 #undef TARGET_SCHED_VARIABLE_ISSUE
636 #define TARGET_SCHED_VARIABLE_ISSUE mips_variable_issue
637 #undef TARGET_SCHED_ADJUST_COST
638 #define TARGET_SCHED_ADJUST_COST mips_adjust_cost
639 #undef TARGET_SCHED_ISSUE_RATE
640 #define TARGET_SCHED_ISSUE_RATE mips_issue_rate
641 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
642 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
643 mips_multipass_dfa_lookahead
645 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
646 #define TARGET_FUNCTION_OK_FOR_SIBCALL mips_function_ok_for_sibcall
648 #undef TARGET_VALID_POINTER_MODE
649 #define TARGET_VALID_POINTER_MODE mips_valid_pointer_mode
650 #undef TARGET_RTX_COSTS
651 #define TARGET_RTX_COSTS mips_rtx_costs
652 #undef TARGET_ADDRESS_COST
653 #define TARGET_ADDRESS_COST mips_address_cost
655 #undef TARGET_IN_SMALL_DATA_P
656 #define TARGET_IN_SMALL_DATA_P mips_in_small_data_p
658 #undef TARGET_MACHINE_DEPENDENT_REORG
659 #define TARGET_MACHINE_DEPENDENT_REORG mips_reorg
661 #undef TARGET_ASM_FILE_START
662 #undef TARGET_ASM_FILE_END
663 #define TARGET_ASM_FILE_START mips_file_start
664 #define TARGET_ASM_FILE_END mips_file_end
665 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
666 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
668 #undef TARGET_INIT_LIBFUNCS
669 #define TARGET_INIT_LIBFUNCS mips_init_libfuncs
671 #undef TARGET_BUILD_BUILTIN_VA_LIST
672 #define TARGET_BUILD_BUILTIN_VA_LIST mips_build_builtin_va_list
673 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
674 #define TARGET_GIMPLIFY_VA_ARG_EXPR mips_gimplify_va_arg_expr
676 #undef TARGET_PROMOTE_FUNCTION_ARGS
677 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
678 #undef TARGET_PROMOTE_FUNCTION_RETURN
679 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
680 #undef TARGET_PROMOTE_PROTOTYPES
681 #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
683 #undef TARGET_RETURN_IN_MEMORY
684 #define TARGET_RETURN_IN_MEMORY mips_return_in_memory
685 #undef TARGET_RETURN_IN_MSB
686 #define TARGET_RETURN_IN_MSB mips_return_in_msb
688 #undef TARGET_ASM_OUTPUT_MI_THUNK
689 #define TARGET_ASM_OUTPUT_MI_THUNK mips_output_mi_thunk
690 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
691 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
693 #undef TARGET_SETUP_INCOMING_VARARGS
694 #define TARGET_SETUP_INCOMING_VARARGS mips_setup_incoming_varargs
695 #undef TARGET_STRICT_ARGUMENT_NAMING
696 #define TARGET_STRICT_ARGUMENT_NAMING mips_strict_argument_naming
697 #undef TARGET_MUST_PASS_IN_STACK
698 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
699 #undef TARGET_PASS_BY_REFERENCE
700 #define TARGET_PASS_BY_REFERENCE mips_pass_by_reference
702 #undef TARGET_VECTOR_MODE_SUPPORTED_P
703 #define TARGET_VECTOR_MODE_SUPPORTED_P mips_vector_mode_supported_p
705 #undef TARGET_INIT_BUILTINS
706 #define TARGET_INIT_BUILTINS mips_init_builtins
707 #undef TARGET_EXPAND_BUILTIN
708 #define TARGET_EXPAND_BUILTIN mips_expand_builtin
710 struct gcc_target targetm = TARGET_INITIALIZER;
712 /* Classify symbol X, which must be a SYMBOL_REF or a LABEL_REF. */
714 static enum mips_symbol_type
715 mips_classify_symbol (rtx x)
717 if (GET_CODE (x) == LABEL_REF)
720 return SYMBOL_CONSTANT_POOL;
722 return SYMBOL_GOT_LOCAL;
723 return SYMBOL_GENERAL;
726 if (GET_CODE (x) != SYMBOL_REF)
729 if (CONSTANT_POOL_ADDRESS_P (x))
732 return SYMBOL_CONSTANT_POOL;
735 return SYMBOL_GOT_LOCAL;
737 if (GET_MODE_SIZE (get_pool_mode (x)) <= mips_section_threshold)
738 return SYMBOL_SMALL_DATA;
740 return SYMBOL_GENERAL;
743 if (SYMBOL_REF_SMALL_P (x))
744 return SYMBOL_SMALL_DATA;
748 if (SYMBOL_REF_DECL (x) == 0)
749 return SYMBOL_REF_LOCAL_P (x) ? SYMBOL_GOT_LOCAL : SYMBOL_GOT_GLOBAL;
751 /* There are three cases to consider:
753 - o32 PIC (either with or without explicit relocs)
754 - n32/n64 PIC without explicit relocs
755 - n32/n64 PIC with explicit relocs
757 In the first case, both local and global accesses will use an
758 R_MIPS_GOT16 relocation. We must correctly predict which of
759 the two semantics (local or global) the assembler and linker
760 will apply. The choice doesn't depend on the symbol's
761 visibility, so we deliberately ignore decl_visibility and
764 In the second case, the assembler will not use R_MIPS_GOT16
765 relocations, but it chooses between local and global accesses
766 in the same way as for o32 PIC.
768 In the third case we have more freedom since both forms of
769 access will work for any kind of symbol. However, there seems
770 little point in doing things differently. */
771 if (DECL_P (SYMBOL_REF_DECL (x)) && TREE_PUBLIC (SYMBOL_REF_DECL (x)))
772 return SYMBOL_GOT_GLOBAL;
774 return SYMBOL_GOT_LOCAL;
777 return SYMBOL_GENERAL;
781 /* Split X into a base and a constant offset, storing them in *BASE
782 and *OFFSET respectively. */
785 mips_split_const (rtx x, rtx *base, HOST_WIDE_INT *offset)
789 if (GET_CODE (x) == CONST)
792 if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
794 *offset += INTVAL (XEXP (x, 1));
801 /* Return true if SYMBOL is a SYMBOL_REF and OFFSET + SYMBOL points
802 to the same object as SYMBOL. */
805 mips_offset_within_object_p (rtx symbol, HOST_WIDE_INT offset)
807 if (GET_CODE (symbol) != SYMBOL_REF)
810 if (CONSTANT_POOL_ADDRESS_P (symbol)
812 && offset < (int) GET_MODE_SIZE (get_pool_mode (symbol)))
815 if (SYMBOL_REF_DECL (symbol) != 0
817 && offset < int_size_in_bytes (TREE_TYPE (SYMBOL_REF_DECL (symbol))))
824 /* Return true if X is a symbolic constant that can be calculated in
825 the same way as a bare symbol. If it is, store the type of the
826 symbol in *SYMBOL_TYPE. */
829 mips_symbolic_constant_p (rtx x, enum mips_symbol_type *symbol_type)
831 HOST_WIDE_INT offset;
833 mips_split_const (x, &x, &offset);
834 if (UNSPEC_ADDRESS_P (x))
835 *symbol_type = UNSPEC_ADDRESS_TYPE (x);
836 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF)
837 *symbol_type = mips_classify_symbol (x);
844 /* Check whether a nonzero offset is valid for the underlying
846 switch (*symbol_type)
852 /* If the target has 64-bit pointers and the object file only
853 supports 32-bit symbols, the values of those symbols will be
854 sign-extended. In this case we can't allow an arbitrary offset
855 in case the 32-bit value X + OFFSET has a different sign from X. */
856 if (Pmode == DImode && !ABI_HAS_64BIT_SYMBOLS)
857 return mips_offset_within_object_p (x, offset);
859 /* In other cases the relocations can handle any offset. */
862 case SYMBOL_CONSTANT_POOL:
863 /* Allow constant pool references to be converted to LABEL+CONSTANT.
864 In this case, we no longer have access to the underlying constant,
865 but the original symbol-based access was known to be valid. */
866 if (GET_CODE (x) == LABEL_REF)
871 case SYMBOL_SMALL_DATA:
872 /* Make sure that the offset refers to something within the
873 underlying object. This should guarantee that the final
874 PC- or GP-relative offset is within the 16-bit limit. */
875 return mips_offset_within_object_p (x, offset);
877 case SYMBOL_GOT_LOCAL:
878 case SYMBOL_GOTOFF_PAGE:
879 /* The linker should provide enough local GOT entries for a
880 16-bit offset. Larger offsets may lead to GOT overflow. */
881 return SMALL_OPERAND (offset);
883 case SYMBOL_GOT_GLOBAL:
884 case SYMBOL_GOTOFF_GLOBAL:
885 case SYMBOL_GOTOFF_CALL:
886 case SYMBOL_GOTOFF_LOADGP:
893 /* Return true if X is a symbolic constant whose value is not split
894 into separate relocations. */
897 mips_atomic_symbolic_constant_p (rtx x)
899 enum mips_symbol_type type;
900 return mips_symbolic_constant_p (x, &type) && !mips_split_p[type];
904 /* This function is used to implement REG_MODE_OK_FOR_BASE_P. */
907 mips_regno_mode_ok_for_base_p (int regno, enum machine_mode mode, int strict)
909 if (regno >= FIRST_PSEUDO_REGISTER)
913 regno = reg_renumber[regno];
916 /* These fake registers will be eliminated to either the stack or
917 hard frame pointer, both of which are usually valid base registers.
918 Reload deals with the cases where the eliminated form isn't valid. */
919 if (regno == ARG_POINTER_REGNUM || regno == FRAME_POINTER_REGNUM)
922 /* In mips16 mode, the stack pointer can only address word and doubleword
923 values, nothing smaller. There are two problems here:
925 (a) Instantiating virtual registers can introduce new uses of the
926 stack pointer. If these virtual registers are valid addresses,
927 the stack pointer should be too.
929 (b) Most uses of the stack pointer are not made explicit until
930 FRAME_POINTER_REGNUM and ARG_POINTER_REGNUM have been eliminated.
931 We don't know until that stage whether we'll be eliminating to the
932 stack pointer (which needs the restriction) or the hard frame
933 pointer (which doesn't).
935 All in all, it seems more consistent to only enforce this restriction
936 during and after reload. */
937 if (TARGET_MIPS16 && regno == STACK_POINTER_REGNUM)
938 return !strict || GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8;
940 return TARGET_MIPS16 ? M16_REG_P (regno) : GP_REG_P (regno);
944 /* Return true if X is a valid base register for the given mode.
945 Allow only hard registers if STRICT. */
948 mips_valid_base_register_p (rtx x, enum machine_mode mode, int strict)
950 if (!strict && GET_CODE (x) == SUBREG)
953 return (GET_CODE (x) == REG
954 && mips_regno_mode_ok_for_base_p (REGNO (x), mode, strict));
958 /* Return true if symbols of type SYMBOL_TYPE can directly address a value
959 with mode MODE. This is used for both symbolic and LO_SUM addresses. */
962 mips_symbolic_address_p (enum mips_symbol_type symbol_type,
963 enum machine_mode mode)
968 return !TARGET_MIPS16;
970 case SYMBOL_SMALL_DATA:
973 case SYMBOL_CONSTANT_POOL:
974 /* PC-relative addressing is only available for lw and ld. */
975 return GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8;
977 case SYMBOL_GOT_LOCAL:
980 case SYMBOL_GOT_GLOBAL:
981 /* The address will have to be loaded from the GOT first. */
984 case SYMBOL_GOTOFF_PAGE:
985 case SYMBOL_GOTOFF_GLOBAL:
986 case SYMBOL_GOTOFF_CALL:
987 case SYMBOL_GOTOFF_LOADGP:
997 /* Return true if X is a valid address for machine mode MODE. If it is,
998 fill in INFO appropriately. STRICT is true if we should only accept
999 hard base registers. */
1002 mips_classify_address (struct mips_address_info *info, rtx x,
1003 enum machine_mode mode, int strict)
1005 switch (GET_CODE (x))
1009 info->type = ADDRESS_REG;
1011 info->offset = const0_rtx;
1012 return mips_valid_base_register_p (info->reg, mode, strict);
1015 info->type = ADDRESS_REG;
1016 info->reg = XEXP (x, 0);
1017 info->offset = XEXP (x, 1);
1018 return (mips_valid_base_register_p (info->reg, mode, strict)
1019 && const_arith_operand (info->offset, VOIDmode));
1022 info->type = ADDRESS_LO_SUM;
1023 info->reg = XEXP (x, 0);
1024 info->offset = XEXP (x, 1);
1025 return (mips_valid_base_register_p (info->reg, mode, strict)
1026 && mips_symbolic_constant_p (info->offset, &info->symbol_type)
1027 && mips_symbolic_address_p (info->symbol_type, mode)
1028 && mips_lo_relocs[info->symbol_type] != 0);
1031 /* Small-integer addresses don't occur very often, but they
1032 are legitimate if $0 is a valid base register. */
1033 info->type = ADDRESS_CONST_INT;
1034 return !TARGET_MIPS16 && SMALL_INT (x);
1039 info->type = ADDRESS_SYMBOLIC;
1040 return (mips_symbolic_constant_p (x, &info->symbol_type)
1041 && mips_symbolic_address_p (info->symbol_type, mode)
1042 && !mips_split_p[info->symbol_type]);
1049 /* Return the number of instructions needed to load a symbol of the
1050 given type into a register. If valid in an address, the same number
1051 of instructions are needed for loads and stores. Treat extended
1052 mips16 instructions as two instructions. */
1055 mips_symbol_insns (enum mips_symbol_type type)
1059 case SYMBOL_GENERAL:
1060 /* In mips16 code, general symbols must be fetched from the
1065 /* When using 64-bit symbols, we need 5 preparatory instructions,
1068 lui $at,%highest(symbol)
1069 daddiu $at,$at,%higher(symbol)
1071 daddiu $at,$at,%hi(symbol)
1074 The final address is then $at + %lo(symbol). With 32-bit
1075 symbols we just need a preparatory lui. */
1076 return (ABI_HAS_64BIT_SYMBOLS ? 6 : 2);
1078 case SYMBOL_SMALL_DATA:
1081 case SYMBOL_CONSTANT_POOL:
1082 /* This case is for mips16 only. Assume we'll need an
1083 extended instruction. */
1086 case SYMBOL_GOT_LOCAL:
1087 case SYMBOL_GOT_GLOBAL:
1088 /* Unless -funit-at-a-time is in effect, we can't be sure whether
1089 the local/global classification is accurate. See override_options
1092 The worst cases are:
1094 (1) For local symbols when generating o32 or o64 code. The assembler
1100 ...and the final address will be $at + %lo(symbol).
1102 (2) For global symbols when -mxgot. The assembler will use:
1104 lui $at,%got_hi(symbol)
1107 ...and the final address will be $at + %got_lo(symbol). */
1110 case SYMBOL_GOTOFF_PAGE:
1111 case SYMBOL_GOTOFF_GLOBAL:
1112 case SYMBOL_GOTOFF_CALL:
1113 case SYMBOL_GOTOFF_LOADGP:
1114 case SYMBOL_64_HIGH:
1117 /* Check whether the offset is a 16- or 32-bit value. */
1118 return mips_split_p[type] ? 2 : 1;
1123 /* Return true if X is a legitimate $sp-based address for mode MDOE. */
1126 mips_stack_address_p (rtx x, enum machine_mode mode)
1128 struct mips_address_info addr;
1130 return (mips_classify_address (&addr, x, mode, false)
1131 && addr.type == ADDRESS_REG
1132 && addr.reg == stack_pointer_rtx);
1135 /* Return true if a value at OFFSET bytes from BASE can be accessed
1136 using an unextended mips16 instruction. MODE is the mode of the
1139 Usually the offset in an unextended instruction is a 5-bit field.
1140 The offset is unsigned and shifted left once for HIs, twice
1141 for SIs, and so on. An exception is SImode accesses off the
1142 stack pointer, which have an 8-bit immediate field. */
1145 mips16_unextended_reference_p (enum machine_mode mode, rtx base, rtx offset)
1148 && GET_CODE (offset) == CONST_INT
1149 && INTVAL (offset) >= 0
1150 && (INTVAL (offset) & (GET_MODE_SIZE (mode) - 1)) == 0)
1152 if (GET_MODE_SIZE (mode) == 4 && base == stack_pointer_rtx)
1153 return INTVAL (offset) < 256 * GET_MODE_SIZE (mode);
1154 return INTVAL (offset) < 32 * GET_MODE_SIZE (mode);
1160 /* Return the number of instructions needed to load or store a value
1161 of mode MODE at X. Return 0 if X isn't valid for MODE.
1163 For mips16 code, count extended instructions as two instructions. */
1166 mips_address_insns (rtx x, enum machine_mode mode)
1168 struct mips_address_info addr;
1171 if (mode == BLKmode)
1172 /* BLKmode is used for single unaligned loads and stores. */
1175 /* Each word of a multi-word value will be accessed individually. */
1176 factor = (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
1178 if (mips_classify_address (&addr, x, mode, false))
1183 && !mips16_unextended_reference_p (mode, addr.reg, addr.offset))
1187 case ADDRESS_LO_SUM:
1188 return (TARGET_MIPS16 ? factor * 2 : factor);
1190 case ADDRESS_CONST_INT:
1193 case ADDRESS_SYMBOLIC:
1194 return factor * mips_symbol_insns (addr.symbol_type);
1200 /* Likewise for constant X. */
1203 mips_const_insns (rtx x)
1205 struct mips_integer_op codes[MIPS_MAX_INTEGER_OPS];
1206 enum mips_symbol_type symbol_type;
1207 HOST_WIDE_INT offset;
1209 switch (GET_CODE (x))
1213 || !mips_symbolic_constant_p (XEXP (x, 0), &symbol_type)
1214 || !mips_split_p[symbol_type])
1221 /* Unsigned 8-bit constants can be loaded using an unextended
1222 LI instruction. Unsigned 16-bit constants can be loaded
1223 using an extended LI. Negative constants must be loaded
1224 using LI and then negated. */
1225 return (INTVAL (x) >= 0 && INTVAL (x) < 256 ? 1
1226 : SMALL_OPERAND_UNSIGNED (INTVAL (x)) ? 2
1227 : INTVAL (x) > -256 && INTVAL (x) < 0 ? 2
1228 : SMALL_OPERAND_UNSIGNED (-INTVAL (x)) ? 3
1231 return mips_build_integer (codes, INTVAL (x));
1235 return (!TARGET_MIPS16 && x == CONST0_RTX (GET_MODE (x)) ? 1 : 0);
1241 /* See if we can refer to X directly. */
1242 if (mips_symbolic_constant_p (x, &symbol_type))
1243 return mips_symbol_insns (symbol_type);
1245 /* Otherwise try splitting the constant into a base and offset.
1246 16-bit offsets can be added using an extra addiu. Larger offsets
1247 must be calculated separately and then added to the base. */
1248 mips_split_const (x, &x, &offset);
1251 int n = mips_const_insns (x);
1254 if (SMALL_OPERAND (offset))
1257 return n + 1 + mips_build_integer (codes, offset);
1264 return mips_symbol_insns (mips_classify_symbol (x));
1272 /* Return the number of instructions needed for memory reference X.
1273 Count extended mips16 instructions as two instructions. */
1276 mips_fetch_insns (rtx x)
1278 if (GET_CODE (x) != MEM)
1281 return mips_address_insns (XEXP (x, 0), GET_MODE (x));
1285 /* Return the number of instructions needed for an integer division. */
1288 mips_idiv_insns (void)
1293 if (TARGET_CHECK_ZERO_DIV)
1295 if (TARGET_FIX_R4000 || TARGET_FIX_R4400)
1300 /* This function is used to implement GO_IF_LEGITIMATE_ADDRESS. It
1301 returns a nonzero value if X is a legitimate address for a memory
1302 operand of the indicated MODE. STRICT is nonzero if this function
1303 is called during reload. */
1306 mips_legitimate_address_p (enum machine_mode mode, rtx x, int strict)
1308 struct mips_address_info addr;
1310 return mips_classify_address (&addr, x, mode, strict);
1314 /* Copy VALUE to a register and return that register. If new psuedos
1315 are allowed, copy it into a new register, otherwise use DEST. */
1318 mips_force_temporary (rtx dest, rtx value)
1320 if (!no_new_pseudos)
1321 return force_reg (Pmode, value);
1324 emit_move_insn (copy_rtx (dest), value);
1330 /* Return a LO_SUM expression for ADDR. TEMP is as for mips_force_temporary
1331 and is used to load the high part into a register. */
1334 mips_split_symbol (rtx temp, rtx addr)
1339 high = mips16_gp_pseudo_reg ();
1341 high = mips_force_temporary (temp, gen_rtx_HIGH (Pmode, copy_rtx (addr)));
1342 return gen_rtx_LO_SUM (Pmode, high, addr);
1346 /* Return an UNSPEC address with underlying address ADDRESS and symbol
1347 type SYMBOL_TYPE. */
1350 mips_unspec_address (rtx address, enum mips_symbol_type symbol_type)
1353 HOST_WIDE_INT offset;
1355 mips_split_const (address, &base, &offset);
1356 base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base),
1357 UNSPEC_ADDRESS_FIRST + symbol_type);
1358 return plus_constant (gen_rtx_CONST (Pmode, base), offset);
1362 /* If mips_unspec_address (ADDR, SYMBOL_TYPE) is a 32-bit value, add the
1363 high part to BASE and return the result. Just return BASE otherwise.
1364 TEMP is available as a temporary register if needed.
1366 The returned expression can be used as the first operand to a LO_SUM. */
1369 mips_unspec_offset_high (rtx temp, rtx base, rtx addr,
1370 enum mips_symbol_type symbol_type)
1372 if (mips_split_p[symbol_type])
1374 addr = gen_rtx_HIGH (Pmode, mips_unspec_address (addr, symbol_type));
1375 addr = mips_force_temporary (temp, addr);
1376 return mips_force_temporary (temp, gen_rtx_PLUS (Pmode, addr, base));
1382 /* Return a legitimate address for REG + OFFSET. TEMP is as for
1383 mips_force_temporary; it is only needed when OFFSET is not a
1387 mips_add_offset (rtx temp, rtx reg, HOST_WIDE_INT offset)
1389 if (!SMALL_OPERAND (offset))
1394 /* Load the full offset into a register so that we can use
1395 an unextended instruction for the address itself. */
1396 high = GEN_INT (offset);
1401 /* Leave OFFSET as a 16-bit offset and put the excess in HIGH. */
1402 high = GEN_INT (CONST_HIGH_PART (offset));
1403 offset = CONST_LOW_PART (offset);
1405 high = mips_force_temporary (temp, high);
1406 reg = mips_force_temporary (temp, gen_rtx_PLUS (Pmode, high, reg));
1408 return plus_constant (reg, offset);
1412 /* This function is used to implement LEGITIMIZE_ADDRESS. If *XLOC can
1413 be legitimized in a way that the generic machinery might not expect,
1414 put the new address in *XLOC and return true. MODE is the mode of
1415 the memory being accessed. */
1418 mips_legitimize_address (rtx *xloc, enum machine_mode mode)
1420 enum mips_symbol_type symbol_type;
1422 /* See if the address can split into a high part and a LO_SUM. */
1423 if (mips_symbolic_constant_p (*xloc, &symbol_type)
1424 && mips_symbolic_address_p (symbol_type, mode)
1425 && mips_split_p[symbol_type])
1427 *xloc = mips_split_symbol (0, *xloc);
1431 if (GET_CODE (*xloc) == PLUS && GET_CODE (XEXP (*xloc, 1)) == CONST_INT)
1433 /* Handle REG + CONSTANT using mips_add_offset. */
1436 reg = XEXP (*xloc, 0);
1437 if (!mips_valid_base_register_p (reg, mode, 0))
1438 reg = copy_to_mode_reg (Pmode, reg);
1439 *xloc = mips_add_offset (0, reg, INTVAL (XEXP (*xloc, 1)));
1447 /* Subroutine of mips_build_integer (with the same interface).
1448 Assume that the final action in the sequence should be a left shift. */
1451 mips_build_shift (struct mips_integer_op *codes, HOST_WIDE_INT value)
1453 unsigned int i, shift;
1455 /* Shift VALUE right until its lowest bit is set. Shift arithmetically
1456 since signed numbers are easier to load than unsigned ones. */
1458 while ((value & 1) == 0)
1459 value /= 2, shift++;
1461 i = mips_build_integer (codes, value);
1462 codes[i].code = ASHIFT;
1463 codes[i].value = shift;
1468 /* As for mips_build_shift, but assume that the final action will be
1469 an IOR or PLUS operation. */
1472 mips_build_lower (struct mips_integer_op *codes, unsigned HOST_WIDE_INT value)
1474 unsigned HOST_WIDE_INT high;
1477 high = value & ~(unsigned HOST_WIDE_INT) 0xffff;
1478 if (!LUI_OPERAND (high) && (value & 0x18000) == 0x18000)
1480 /* The constant is too complex to load with a simple lui/ori pair
1481 so our goal is to clear as many trailing zeros as possible.
1482 In this case, we know bit 16 is set and that the low 16 bits
1483 form a negative number. If we subtract that number from VALUE,
1484 we will clear at least the lowest 17 bits, maybe more. */
1485 i = mips_build_integer (codes, CONST_HIGH_PART (value));
1486 codes[i].code = PLUS;
1487 codes[i].value = CONST_LOW_PART (value);
1491 i = mips_build_integer (codes, high);
1492 codes[i].code = IOR;
1493 codes[i].value = value & 0xffff;
1499 /* Fill CODES with a sequence of rtl operations to load VALUE.
1500 Return the number of operations needed. */
1503 mips_build_integer (struct mips_integer_op *codes,
1504 unsigned HOST_WIDE_INT value)
1506 if (SMALL_OPERAND (value)
1507 || SMALL_OPERAND_UNSIGNED (value)
1508 || LUI_OPERAND (value))
1510 /* The value can be loaded with a single instruction. */
1511 codes[0].code = UNKNOWN;
1512 codes[0].value = value;
1515 else if ((value & 1) != 0 || LUI_OPERAND (CONST_HIGH_PART (value)))
1517 /* Either the constant is a simple LUI/ORI combination or its
1518 lowest bit is set. We don't want to shift in this case. */
1519 return mips_build_lower (codes, value);
1521 else if ((value & 0xffff) == 0)
1523 /* The constant will need at least three actions. The lowest
1524 16 bits are clear, so the final action will be a shift. */
1525 return mips_build_shift (codes, value);
1529 /* The final action could be a shift, add or inclusive OR.
1530 Rather than use a complex condition to select the best
1531 approach, try both mips_build_shift and mips_build_lower
1532 and pick the one that gives the shortest sequence.
1533 Note that this case is only used once per constant. */
1534 struct mips_integer_op alt_codes[MIPS_MAX_INTEGER_OPS];
1535 unsigned int cost, alt_cost;
1537 cost = mips_build_shift (codes, value);
1538 alt_cost = mips_build_lower (alt_codes, value);
1539 if (alt_cost < cost)
1541 memcpy (codes, alt_codes, alt_cost * sizeof (codes[0]));
1549 /* Move VALUE into register DEST. */
1552 mips_move_integer (rtx dest, unsigned HOST_WIDE_INT value)
1554 struct mips_integer_op codes[MIPS_MAX_INTEGER_OPS];
1555 enum machine_mode mode;
1556 unsigned int i, cost;
1559 mode = GET_MODE (dest);
1560 cost = mips_build_integer (codes, value);
1562 /* Apply each binary operation to X. Invariant: X is a legitimate
1563 source operand for a SET pattern. */
1564 x = GEN_INT (codes[0].value);
1565 for (i = 1; i < cost; i++)
1568 emit_move_insn (dest, x), x = dest;
1570 x = force_reg (mode, x);
1571 x = gen_rtx_fmt_ee (codes[i].code, mode, x, GEN_INT (codes[i].value));
1574 emit_insn (gen_rtx_SET (VOIDmode, dest, x));
1578 /* Subroutine of mips_legitimize_move. Move constant SRC into register
1579 DEST given that SRC satisfies immediate_operand but doesn't satisfy
1583 mips_legitimize_const_move (enum machine_mode mode, rtx dest, rtx src)
1586 HOST_WIDE_INT offset;
1587 enum mips_symbol_type symbol_type;
1589 /* Split moves of big integers into smaller pieces. In mips16 code,
1590 it's better to force the constant into memory instead. */
1591 if (GET_CODE (src) == CONST_INT && !TARGET_MIPS16)
1593 mips_move_integer (dest, INTVAL (src));
1597 /* See if the symbol can be split. For mips16, this is often worse than
1598 forcing it in the constant pool since it needs the single-register form
1599 of addiu or daddiu. */
1601 && mips_symbolic_constant_p (src, &symbol_type)
1602 && mips_split_p[symbol_type])
1604 emit_move_insn (dest, mips_split_symbol (dest, src));
1608 /* If we have (const (plus symbol offset)), load the symbol first
1609 and then add in the offset. This is usually better than forcing
1610 the constant into memory, at least in non-mips16 code. */
1611 mips_split_const (src, &base, &offset);
1614 && (!no_new_pseudos || SMALL_OPERAND (offset)))
1616 base = mips_force_temporary (dest, base);
1617 emit_move_insn (dest, mips_add_offset (0, base, offset));
1621 src = force_const_mem (mode, src);
1623 /* When using explicit relocs, constant pool references are sometimes
1624 not legitimate addresses. */
1625 if (!memory_operand (src, VOIDmode))
1626 src = replace_equiv_address (src, mips_split_symbol (dest, XEXP (src, 0)));
1627 emit_move_insn (dest, src);
1631 /* If (set DEST SRC) is not a valid instruction, emit an equivalent
1632 sequence that is valid. */
1635 mips_legitimize_move (enum machine_mode mode, rtx dest, rtx src)
1637 if (!register_operand (dest, mode) && !reg_or_0_operand (src, mode))
1639 emit_move_insn (dest, force_reg (mode, src));
1643 /* Check for individual, fully-reloaded mflo and mfhi instructions. */
1644 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD
1645 && REG_P (src) && MD_REG_P (REGNO (src))
1646 && REG_P (dest) && GP_REG_P (REGNO (dest)))
1648 int other_regno = REGNO (src) == HI_REGNUM ? LO_REGNUM : HI_REGNUM;
1649 if (GET_MODE_SIZE (mode) <= 4)
1650 emit_insn (gen_mfhilo_si (gen_rtx_REG (SImode, REGNO (dest)),
1651 gen_rtx_REG (SImode, REGNO (src)),
1652 gen_rtx_REG (SImode, other_regno)));
1654 emit_insn (gen_mfhilo_di (gen_rtx_REG (DImode, REGNO (dest)),
1655 gen_rtx_REG (DImode, REGNO (src)),
1656 gen_rtx_REG (DImode, other_regno)));
1660 /* We need to deal with constants that would be legitimate
1661 immediate_operands but not legitimate move_operands. */
1662 if (CONSTANT_P (src) && !move_operand (src, mode))
1664 mips_legitimize_const_move (mode, dest, src);
1665 set_unique_reg_note (get_last_insn (), REG_EQUAL, copy_rtx (src));
1671 /* We need a lot of little routines to check constant values on the
1672 mips16. These are used to figure out how long the instruction will
1673 be. It would be much better to do this using constraints, but
1674 there aren't nearly enough letters available. */
1677 m16_check_op (rtx op, int low, int high, int mask)
1679 return (GET_CODE (op) == CONST_INT
1680 && INTVAL (op) >= low
1681 && INTVAL (op) <= high
1682 && (INTVAL (op) & mask) == 0);
1686 m16_uimm3_b (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1688 return m16_check_op (op, 0x1, 0x8, 0);
1692 m16_simm4_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1694 return m16_check_op (op, - 0x8, 0x7, 0);
1698 m16_nsimm4_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1700 return m16_check_op (op, - 0x7, 0x8, 0);
1704 m16_simm5_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1706 return m16_check_op (op, - 0x10, 0xf, 0);
1710 m16_nsimm5_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1712 return m16_check_op (op, - 0xf, 0x10, 0);
1716 m16_uimm5_4 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1718 return m16_check_op (op, (- 0x10) << 2, 0xf << 2, 3);
1722 m16_nuimm5_4 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1724 return m16_check_op (op, (- 0xf) << 2, 0x10 << 2, 3);
1728 m16_simm8_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1730 return m16_check_op (op, - 0x80, 0x7f, 0);
1734 m16_nsimm8_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1736 return m16_check_op (op, - 0x7f, 0x80, 0);
1740 m16_uimm8_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1742 return m16_check_op (op, 0x0, 0xff, 0);
1746 m16_nuimm8_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1748 return m16_check_op (op, - 0xff, 0x0, 0);
1752 m16_uimm8_m1_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1754 return m16_check_op (op, - 0x1, 0xfe, 0);
1758 m16_uimm8_4 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1760 return m16_check_op (op, 0x0, 0xff << 2, 3);
1764 m16_nuimm8_4 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1766 return m16_check_op (op, (- 0xff) << 2, 0x0, 3);
1770 m16_simm8_8 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1772 return m16_check_op (op, (- 0x80) << 3, 0x7f << 3, 7);
1776 m16_nsimm8_8 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1778 return m16_check_op (op, (- 0x7f) << 3, 0x80 << 3, 7);
1782 mips_rtx_costs (rtx x, int code, int outer_code, int *total)
1784 enum machine_mode mode = GET_MODE (x);
1791 /* Always return 0, since we don't have different sized
1792 instructions, hence different costs according to Richard
1798 /* A number between 1 and 8 inclusive is efficient for a shift.
1799 Otherwise, we will need an extended instruction. */
1800 if ((outer_code) == ASHIFT || (outer_code) == ASHIFTRT
1801 || (outer_code) == LSHIFTRT)
1803 if (INTVAL (x) >= 1 && INTVAL (x) <= 8)
1806 *total = COSTS_N_INSNS (1);
1810 /* We can use cmpi for an xor with an unsigned 16 bit value. */
1811 if ((outer_code) == XOR
1812 && INTVAL (x) >= 0 && INTVAL (x) < 0x10000)
1818 /* We may be able to use slt or sltu for a comparison with a
1819 signed 16 bit value. (The boundary conditions aren't quite
1820 right, but this is just a heuristic anyhow.) */
1821 if (((outer_code) == LT || (outer_code) == LE
1822 || (outer_code) == GE || (outer_code) == GT
1823 || (outer_code) == LTU || (outer_code) == LEU
1824 || (outer_code) == GEU || (outer_code) == GTU)
1825 && INTVAL (x) >= -0x8000 && INTVAL (x) < 0x8000)
1831 /* Equality comparisons with 0 are cheap. */
1832 if (((outer_code) == EQ || (outer_code) == NE)
1839 /* Constants in the range 0...255 can be loaded with an unextended
1840 instruction. They are therefore as cheap as a register move.
1842 Given the choice between "li R1,0...255" and "move R1,R2"
1843 (where R2 is a known constant), it is usually better to use "li",
1844 since we do not want to unnessarily extend the lifetime of R2. */
1845 if (outer_code == SET
1847 && INTVAL (x) < 256)
1853 /* Otherwise fall through to the handling below. */
1859 if (LEGITIMATE_CONSTANT_P (x))
1861 *total = COSTS_N_INSNS (1);
1866 /* The value will need to be fetched from the constant pool. */
1867 *total = CONSTANT_POOL_COST;
1873 /* If the address is legitimate, return the number of
1874 instructions it needs, otherwise use the default handling. */
1875 int n = mips_address_insns (XEXP (x, 0), GET_MODE (x));
1878 *total = COSTS_N_INSNS (1 + n);
1885 *total = COSTS_N_INSNS (6);
1889 *total = COSTS_N_INSNS ((mode == DImode && !TARGET_64BIT) ? 2 : 1);
1895 if (mode == DImode && !TARGET_64BIT)
1897 *total = COSTS_N_INSNS (2);
1905 if (mode == DImode && !TARGET_64BIT)
1907 *total = COSTS_N_INSNS ((GET_CODE (XEXP (x, 1)) == CONST_INT)
1914 if (mode == SFmode || mode == DFmode)
1915 *total = COSTS_N_INSNS (1);
1917 *total = COSTS_N_INSNS (4);
1921 *total = COSTS_N_INSNS (1);
1926 if (mode == SFmode || mode == DFmode)
1928 if (TUNE_MIPS3000 || TUNE_MIPS3900)
1929 *total = COSTS_N_INSNS (2);
1930 else if (TUNE_MIPS6000)
1931 *total = COSTS_N_INSNS (3);
1933 *total = COSTS_N_INSNS (4);
1935 *total = COSTS_N_INSNS (6);
1938 if (mode == DImode && !TARGET_64BIT)
1940 *total = COSTS_N_INSNS (4);
1946 if (mode == DImode && !TARGET_64BIT)
1960 *total = COSTS_N_INSNS (4);
1961 else if (TUNE_MIPS6000
1964 *total = COSTS_N_INSNS (5);
1966 *total = COSTS_N_INSNS (7);
1973 *total = COSTS_N_INSNS (4);
1974 else if (TUNE_MIPS3000
1977 *total = COSTS_N_INSNS (5);
1978 else if (TUNE_MIPS6000
1981 *total = COSTS_N_INSNS (6);
1983 *total = COSTS_N_INSNS (8);
1988 *total = COSTS_N_INSNS (12);
1989 else if (TUNE_MIPS3900)
1990 *total = COSTS_N_INSNS (2);
1991 else if (TUNE_MIPS4130)
1992 *total = COSTS_N_INSNS (mode == DImode ? 6 : 4);
1993 else if (TUNE_MIPS5400 || TUNE_SB1)
1994 *total = COSTS_N_INSNS (mode == DImode ? 4 : 3);
1995 else if (TUNE_MIPS5500 || TUNE_MIPS7000)
1996 *total = COSTS_N_INSNS (mode == DImode ? 9 : 5);
1997 else if (TUNE_MIPS9000)
1998 *total = COSTS_N_INSNS (mode == DImode ? 8 : 3);
1999 else if (TUNE_MIPS6000)
2000 *total = COSTS_N_INSNS (17);
2001 else if (TUNE_MIPS5000)
2002 *total = COSTS_N_INSNS (5);
2004 *total = COSTS_N_INSNS (10);
2013 *total = COSTS_N_INSNS (12);
2014 else if (TUNE_MIPS6000)
2015 *total = COSTS_N_INSNS (15);
2017 *total = COSTS_N_INSNS (24);
2018 else if (TUNE_MIPS5400 || TUNE_MIPS5500)
2019 *total = COSTS_N_INSNS (30);
2021 *total = COSTS_N_INSNS (23);
2029 *total = COSTS_N_INSNS (19);
2030 else if (TUNE_MIPS5400 || TUNE_MIPS5500)
2031 *total = COSTS_N_INSNS (59);
2032 else if (TUNE_MIPS6000)
2033 *total = COSTS_N_INSNS (16);
2035 *total = COSTS_N_INSNS (32);
2037 *total = COSTS_N_INSNS (36);
2046 *total = COSTS_N_INSNS (35);
2047 else if (TUNE_MIPS6000)
2048 *total = COSTS_N_INSNS (38);
2049 else if (TUNE_MIPS5000)
2050 *total = COSTS_N_INSNS (36);
2052 *total = COSTS_N_INSNS ((mode == SImode) ? 36 : 68);
2053 else if (TUNE_MIPS5400 || TUNE_MIPS5500)
2054 *total = COSTS_N_INSNS ((mode == SImode) ? 42 : 74);
2056 *total = COSTS_N_INSNS (69);
2060 /* A sign extend from SImode to DImode in 64 bit mode is often
2061 zero instructions, because the result can often be used
2062 directly by another instruction; we'll call it one. */
2063 if (TARGET_64BIT && mode == DImode
2064 && GET_MODE (XEXP (x, 0)) == SImode)
2065 *total = COSTS_N_INSNS (1);
2067 *total = COSTS_N_INSNS (2);
2071 if (TARGET_64BIT && mode == DImode
2072 && GET_MODE (XEXP (x, 0)) == SImode)
2073 *total = COSTS_N_INSNS (2);
2075 *total = COSTS_N_INSNS (1);
2083 /* Provide the costs of an addressing mode that contains ADDR.
2084 If ADDR is not a valid address, its cost is irrelevant. */
2087 mips_address_cost (rtx addr)
2089 return mips_address_insns (addr, SImode);
2092 /* Return one word of double-word value OP, taking into account the fixed
2093 endianness of certain registers. HIGH_P is true to select the high part,
2094 false to select the low part. */
2097 mips_subword (rtx op, int high_p)
2100 enum machine_mode mode;
2102 mode = GET_MODE (op);
2103 if (mode == VOIDmode)
2106 if (TARGET_BIG_ENDIAN ? !high_p : high_p)
2107 byte = UNITS_PER_WORD;
2111 if (GET_CODE (op) == REG)
2113 if (FP_REG_P (REGNO (op)))
2114 return gen_rtx_REG (word_mode, high_p ? REGNO (op) + 1 : REGNO (op));
2115 if (REGNO (op) == HI_REGNUM)
2116 return gen_rtx_REG (word_mode, high_p ? HI_REGNUM : LO_REGNUM);
2119 if (GET_CODE (op) == MEM)
2120 return mips_rewrite_small_data (adjust_address (op, word_mode, byte));
2122 return simplify_gen_subreg (word_mode, op, mode, byte);
2126 /* Return true if a 64-bit move from SRC to DEST should be split into two. */
2129 mips_split_64bit_move_p (rtx dest, rtx src)
2134 /* FP->FP moves can be done in a single instruction. */
2135 if (FP_REG_RTX_P (src) && FP_REG_RTX_P (dest))
2138 /* Check for floating-point loads and stores. They can be done using
2139 ldc1 and sdc1 on MIPS II and above. */
2142 if (FP_REG_RTX_P (dest) && GET_CODE (src) == MEM)
2144 if (FP_REG_RTX_P (src) && GET_CODE (dest) == MEM)
2151 /* Split a 64-bit move from SRC to DEST assuming that
2152 mips_split_64bit_move_p holds.
2154 Moves into and out of FPRs cause some difficulty here. Such moves
2155 will always be DFmode, since paired FPRs are not allowed to store
2156 DImode values. The most natural representation would be two separate
2157 32-bit moves, such as:
2159 (set (reg:SI $f0) (mem:SI ...))
2160 (set (reg:SI $f1) (mem:SI ...))
2162 However, the second insn is invalid because odd-numbered FPRs are
2163 not allowed to store independent values. Use the patterns load_df_low,
2164 load_df_high and store_df_high instead. */
2167 mips_split_64bit_move (rtx dest, rtx src)
2169 if (FP_REG_RTX_P (dest))
2171 /* Loading an FPR from memory or from GPRs. */
2172 emit_insn (gen_load_df_low (copy_rtx (dest), mips_subword (src, 0)));
2173 emit_insn (gen_load_df_high (dest, mips_subword (src, 1),
2176 else if (FP_REG_RTX_P (src))
2178 /* Storing an FPR into memory or GPRs. */
2179 emit_move_insn (mips_subword (dest, 0), mips_subword (src, 0));
2180 emit_insn (gen_store_df_high (mips_subword (dest, 1), src));
2184 /* The operation can be split into two normal moves. Decide in
2185 which order to do them. */
2188 low_dest = mips_subword (dest, 0);
2189 if (GET_CODE (low_dest) == REG
2190 && reg_overlap_mentioned_p (low_dest, src))
2192 emit_move_insn (mips_subword (dest, 1), mips_subword (src, 1));
2193 emit_move_insn (low_dest, mips_subword (src, 0));
2197 emit_move_insn (low_dest, mips_subword (src, 0));
2198 emit_move_insn (mips_subword (dest, 1), mips_subword (src, 1));
2203 /* Return the appropriate instructions to move SRC into DEST. Assume
2204 that SRC is operand 1 and DEST is operand 0. */
2207 mips_output_move (rtx dest, rtx src)
2209 enum rtx_code dest_code, src_code;
2212 dest_code = GET_CODE (dest);
2213 src_code = GET_CODE (src);
2214 dbl_p = (GET_MODE_SIZE (GET_MODE (dest)) == 8);
2216 if (dbl_p && mips_split_64bit_move_p (dest, src))
2219 if ((src_code == REG && GP_REG_P (REGNO (src)))
2220 || (!TARGET_MIPS16 && src == CONST0_RTX (GET_MODE (dest))))
2222 if (dest_code == REG)
2224 if (GP_REG_P (REGNO (dest)))
2225 return "move\t%0,%z1";
2227 if (MD_REG_P (REGNO (dest)))
2230 if (FP_REG_P (REGNO (dest)))
2231 return (dbl_p ? "dmtc1\t%z1,%0" : "mtc1\t%z1,%0");
2233 if (ALL_COP_REG_P (REGNO (dest)))
2235 static char retval[] = "dmtc_\t%z1,%0";
2237 retval[4] = COPNUM_AS_CHAR_FROM_REGNUM (REGNO (dest));
2238 return (dbl_p ? retval : retval + 1);
2241 if (dest_code == MEM)
2242 return (dbl_p ? "sd\t%z1,%0" : "sw\t%z1,%0");
2244 if (dest_code == REG && GP_REG_P (REGNO (dest)))
2246 if (src_code == REG)
2248 if (ST_REG_P (REGNO (src)) && ISA_HAS_8CC)
2249 return "lui\t%0,0x3f80\n\tmovf\t%0,%.,%1";
2251 if (FP_REG_P (REGNO (src)))
2252 return (dbl_p ? "dmfc1\t%0,%1" : "mfc1\t%0,%1");
2254 if (ALL_COP_REG_P (REGNO (src)))
2256 static char retval[] = "dmfc_\t%0,%1";
2258 retval[4] = COPNUM_AS_CHAR_FROM_REGNUM (REGNO (src));
2259 return (dbl_p ? retval : retval + 1);
2263 if (src_code == MEM)
2264 return (dbl_p ? "ld\t%0,%1" : "lw\t%0,%1");
2266 if (src_code == CONST_INT)
2268 /* Don't use the X format, because that will give out of
2269 range numbers for 64 bit hosts and 32 bit targets. */
2271 return "li\t%0,%1\t\t\t# %X1";
2273 if (INTVAL (src) >= 0 && INTVAL (src) <= 0xffff)
2276 if (INTVAL (src) < 0 && INTVAL (src) >= -0xffff)
2280 if (src_code == HIGH)
2281 return "lui\t%0,%h1";
2283 if (CONST_GP_P (src))
2284 return "move\t%0,%1";
2286 if (symbolic_operand (src, VOIDmode))
2287 return (dbl_p ? "dla\t%0,%1" : "la\t%0,%1");
2289 if (src_code == REG && FP_REG_P (REGNO (src)))
2291 if (dest_code == REG && FP_REG_P (REGNO (dest)))
2293 if (GET_MODE (dest) == V2SFmode)
2294 return "mov.ps\t%0,%1";
2296 return (dbl_p ? "mov.d\t%0,%1" : "mov.s\t%0,%1");
2299 if (dest_code == MEM)
2300 return (dbl_p ? "sdc1\t%1,%0" : "swc1\t%1,%0");
2302 if (dest_code == REG && FP_REG_P (REGNO (dest)))
2304 if (src_code == MEM)
2305 return (dbl_p ? "ldc1\t%0,%1" : "lwc1\t%0,%1");
2307 if (dest_code == REG && ALL_COP_REG_P (REGNO (dest)) && src_code == MEM)
2309 static char retval[] = "l_c_\t%0,%1";
2311 retval[1] = (dbl_p ? 'd' : 'w');
2312 retval[3] = COPNUM_AS_CHAR_FROM_REGNUM (REGNO (dest));
2315 if (dest_code == MEM && src_code == REG && ALL_COP_REG_P (REGNO (src)))
2317 static char retval[] = "s_c_\t%1,%0";
2319 retval[1] = (dbl_p ? 'd' : 'w');
2320 retval[3] = COPNUM_AS_CHAR_FROM_REGNUM (REGNO (src));
2326 /* Restore $gp from its save slot. Valid only when using o32 or
2330 mips_restore_gp (void)
2334 if (!TARGET_ABICALLS || !TARGET_OLDABI)
2337 address = mips_add_offset (pic_offset_table_rtx,
2338 frame_pointer_needed
2339 ? hard_frame_pointer_rtx
2340 : stack_pointer_rtx,
2341 current_function_outgoing_args_size);
2342 slot = gen_rtx_MEM (Pmode, address);
2344 emit_move_insn (pic_offset_table_rtx, slot);
2345 if (!TARGET_EXPLICIT_RELOCS)
2346 emit_insn (gen_blockage ());
2349 /* Emit an instruction of the form (set TARGET (CODE OP0 OP1)). */
2352 mips_emit_binary (enum rtx_code code, rtx target, rtx op0, rtx op1)
2354 emit_insn (gen_rtx_SET (VOIDmode, target,
2355 gen_rtx_fmt_ee (code, GET_MODE (target), op0, op1)));
2358 /* Return true if CMP1 is a suitable second operand for relational
2359 operator CODE. See also the *sCC patterns in mips.md. */
2362 mips_relational_operand_ok_p (enum rtx_code code, rtx cmp1)
2368 return reg_or_0_operand (cmp1, VOIDmode);
2372 return !TARGET_MIPS16 && cmp1 == const1_rtx;
2376 return arith_operand (cmp1, VOIDmode);
2379 return sle_operand (cmp1, VOIDmode);
2382 return sleu_operand (cmp1, VOIDmode);
2389 /* Compare CMP0 and CMP1 using relational operator CODE and store the
2390 result in TARGET. CMP0 and TARGET are register_operands that have
2391 the same integer mode. If INVERT_PTR is nonnull, it's OK to set
2392 TARGET to the inverse of the result and flip *INVERT_PTR instead. */
2395 mips_emit_int_relational (enum rtx_code code, bool *invert_ptr,
2396 rtx target, rtx cmp0, rtx cmp1)
2398 /* First see if there is a MIPS instruction that can do this operation
2399 with CMP1 in its current form. If not, try doing the same for the
2400 inverse operation. If that also fails, force CMP1 into a register
2402 if (mips_relational_operand_ok_p (code, cmp1))
2403 mips_emit_binary (code, target, cmp0, cmp1);
2406 enum rtx_code inv_code = reverse_condition (code);
2407 if (!mips_relational_operand_ok_p (inv_code, cmp1))
2409 cmp1 = force_reg (GET_MODE (cmp0), cmp1);
2410 mips_emit_int_relational (code, invert_ptr, target, cmp0, cmp1);
2412 else if (invert_ptr == 0)
2414 rtx inv_target = gen_reg_rtx (GET_MODE (target));
2415 mips_emit_binary (inv_code, inv_target, cmp0, cmp1);
2416 mips_emit_binary (XOR, target, inv_target, const1_rtx);
2420 *invert_ptr = !*invert_ptr;
2421 mips_emit_binary (inv_code, target, cmp0, cmp1);
2426 /* Return a register that is zero iff CMP0 and CMP1 are equal.
2427 The register will have the same mode as CMP0. */
2430 mips_zero_if_equal (rtx cmp0, rtx cmp1)
2432 if (cmp1 == const0_rtx)
2435 if (uns_arith_operand (cmp1, VOIDmode))
2436 return expand_binop (GET_MODE (cmp0), xor_optab,
2437 cmp0, cmp1, 0, 0, OPTAB_DIRECT);
2439 return expand_binop (GET_MODE (cmp0), sub_optab,
2440 cmp0, cmp1, 0, 0, OPTAB_DIRECT);
2443 /* Convert a comparison into something that can be used in a branch or
2444 conditional move. cmp_operands[0] and cmp_operands[1] are the values
2445 being compared and *CODE is the code used to compare them.
2447 Update *CODE, *OP0 and *OP1 so that they describe the final comparison.
2448 If NEED_EQ_NE_P, then only EQ/NE comparisons against zero are possible,
2449 otherwise any standard branch condition can be used. The standard branch
2452 - EQ/NE between two registers.
2453 - any comparison between a register and zero. */
2456 mips_emit_compare (enum rtx_code *code, rtx *op0, rtx *op1, bool need_eq_ne_p)
2458 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) == MODE_INT)
2460 if (!need_eq_ne_p && cmp_operands[1] == const0_rtx)
2462 *op0 = cmp_operands[0];
2463 *op1 = cmp_operands[1];
2465 else if (*code == EQ || *code == NE)
2469 *op0 = mips_zero_if_equal (cmp_operands[0], cmp_operands[1]);
2474 *op0 = cmp_operands[0];
2475 *op1 = force_reg (GET_MODE (*op0), cmp_operands[1]);
2480 /* The comparison needs a separate scc instruction. Store the
2481 result of the scc in *OP0 and compare it against zero. */
2482 bool invert = false;
2483 *op0 = gen_reg_rtx (GET_MODE (cmp_operands[0]));
2485 mips_emit_int_relational (*code, &invert, *op0,
2486 cmp_operands[0], cmp_operands[1]);
2487 *code = (invert ? EQ : NE);
2492 enum rtx_code cmp_code;
2494 /* Floating-point tests use a separate c.cond.fmt comparison to
2495 set a condition code register. The branch or conditional move
2496 will then compare that register against zero.
2498 Set CMP_CODE to the code of the comparison instruction and
2499 *CODE to the code that the branch or move should use. */
2507 cmp_code = reverse_condition_maybe_unordered (*code);
2517 ? gen_reg_rtx (CCmode)
2518 : gen_rtx_REG (CCmode, FPSW_REGNUM));
2520 mips_emit_binary (cmp_code, *op0, cmp_operands[0], cmp_operands[1]);
2524 /* Try comparing cmp_operands[0] and cmp_operands[1] using rtl code CODE.
2525 Store the result in TARGET and return true if successful.
2527 On 64-bit targets, TARGET may be wider than cmp_operands[0]. */
2530 mips_emit_scc (enum rtx_code code, rtx target)
2532 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
2535 target = gen_lowpart (GET_MODE (cmp_operands[0]), target);
2536 if (code == EQ || code == NE)
2538 rtx zie = mips_zero_if_equal (cmp_operands[0], cmp_operands[1]);
2539 mips_emit_binary (code, target, zie, const0_rtx);
2542 mips_emit_int_relational (code, 0, target,
2543 cmp_operands[0], cmp_operands[1]);
2547 /* Emit the common code for doing conditional branches.
2548 operand[0] is the label to jump to.
2549 The comparison operands are saved away by cmp{si,di,sf,df}. */
2552 gen_conditional_branch (rtx *operands, enum rtx_code code)
2554 rtx op0, op1, target;
2556 mips_emit_compare (&code, &op0, &op1, TARGET_MIPS16);
2557 target = gen_rtx_IF_THEN_ELSE (VOIDmode,
2558 gen_rtx_fmt_ee (code, GET_MODE (op0),
2560 gen_rtx_LABEL_REF (VOIDmode, operands[0]),
2562 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, target));
2565 /* Emit the common code for conditional moves. OPERANDS is the array
2566 of operands passed to the conditional move define_expand. */
2569 gen_conditional_move (rtx *operands)
2574 code = GET_CODE (operands[1]);
2575 mips_emit_compare (&code, &op0, &op1, true);
2576 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2577 gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]),
2578 gen_rtx_fmt_ee (code,
2581 operands[2], operands[3])));
2584 /* Emit a conditional trap. OPERANDS is the array of operands passed to
2585 the conditional_trap expander. */
2588 mips_gen_conditional_trap (rtx *operands)
2591 enum rtx_code cmp_code = GET_CODE (operands[0]);
2592 enum machine_mode mode = GET_MODE (cmp_operands[0]);
2594 /* MIPS conditional trap machine instructions don't have GT or LE
2595 flavors, so we must invert the comparison and convert to LT and
2596 GE, respectively. */
2599 case GT: cmp_code = LT; break;
2600 case LE: cmp_code = GE; break;
2601 case GTU: cmp_code = LTU; break;
2602 case LEU: cmp_code = GEU; break;
2605 if (cmp_code == GET_CODE (operands[0]))
2607 op0 = cmp_operands[0];
2608 op1 = cmp_operands[1];
2612 op0 = cmp_operands[1];
2613 op1 = cmp_operands[0];
2615 op0 = force_reg (mode, op0);
2616 if (!arith_operand (op1, mode))
2617 op1 = force_reg (mode, op1);
2619 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
2620 gen_rtx_fmt_ee (cmp_code, mode, op0, op1),
2624 /* Load function address ADDR into register DEST. SIBCALL_P is true
2625 if the address is needed for a sibling call. */
2628 mips_load_call_address (rtx dest, rtx addr, int sibcall_p)
2630 /* If we're generating PIC, and this call is to a global function,
2631 try to allow its address to be resolved lazily. This isn't
2632 possible for NewABI sibcalls since the value of $gp on entry
2633 to the stub would be our caller's gp, not ours. */
2634 if (TARGET_EXPLICIT_RELOCS
2635 && !(sibcall_p && TARGET_NEWABI)
2636 && global_got_operand (addr, VOIDmode))
2638 rtx high, lo_sum_symbol;
2640 high = mips_unspec_offset_high (dest, pic_offset_table_rtx,
2641 addr, SYMBOL_GOTOFF_CALL);
2642 lo_sum_symbol = mips_unspec_address (addr, SYMBOL_GOTOFF_CALL);
2643 if (Pmode == SImode)
2644 emit_insn (gen_load_callsi (dest, high, lo_sum_symbol));
2646 emit_insn (gen_load_calldi (dest, high, lo_sum_symbol));
2649 emit_move_insn (dest, addr);
2653 /* Expand a call or call_value instruction. RESULT is where the
2654 result will go (null for calls), ADDR is the address of the
2655 function, ARGS_SIZE is the size of the arguments and AUX is
2656 the value passed to us by mips_function_arg. SIBCALL_P is true
2657 if we are expanding a sibling call, false if we're expanding
2661 mips_expand_call (rtx result, rtx addr, rtx args_size, rtx aux, int sibcall_p)
2663 rtx orig_addr, pattern, insn;
2666 if (!call_insn_operand (addr, VOIDmode))
2668 addr = gen_reg_rtx (Pmode);
2669 mips_load_call_address (addr, orig_addr, sibcall_p);
2673 && mips16_hard_float
2674 && build_mips16_call_stub (result, addr, args_size,
2675 aux == 0 ? 0 : (int) GET_MODE (aux)))
2679 pattern = (sibcall_p
2680 ? gen_sibcall_internal (addr, args_size)
2681 : gen_call_internal (addr, args_size));
2682 else if (GET_CODE (result) == PARALLEL && XVECLEN (result, 0) == 2)
2686 reg1 = XEXP (XVECEXP (result, 0, 0), 0);
2687 reg2 = XEXP (XVECEXP (result, 0, 1), 0);
2690 ? gen_sibcall_value_multiple_internal (reg1, addr, args_size, reg2)
2691 : gen_call_value_multiple_internal (reg1, addr, args_size, reg2));
2694 pattern = (sibcall_p
2695 ? gen_sibcall_value_internal (result, addr, args_size)
2696 : gen_call_value_internal (result, addr, args_size));
2698 insn = emit_call_insn (pattern);
2700 /* Lazy-binding stubs require $gp to be valid on entry. */
2701 if (global_got_operand (orig_addr, VOIDmode))
2702 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
2706 /* We can handle any sibcall when TARGET_SIBCALLS is true. */
2709 mips_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
2710 tree exp ATTRIBUTE_UNUSED)
2712 return TARGET_SIBCALLS;
2715 /* Emit code to move general operand SRC into condition-code
2716 register DEST. SCRATCH is a scratch TFmode float register.
2723 where FP1 and FP2 are single-precision float registers
2724 taken from SCRATCH. */
2727 mips_emit_fcc_reload (rtx dest, rtx src, rtx scratch)
2731 /* Change the source to SFmode. */
2732 if (GET_CODE (src) == MEM)
2733 src = adjust_address (src, SFmode, 0);
2734 else if (GET_CODE (src) == REG || GET_CODE (src) == SUBREG)
2735 src = gen_rtx_REG (SFmode, true_regnum (src));
2737 fp1 = gen_rtx_REG (SFmode, REGNO (scratch));
2738 fp2 = gen_rtx_REG (SFmode, REGNO (scratch) + FP_INC);
2740 emit_move_insn (copy_rtx (fp1), src);
2741 emit_move_insn (copy_rtx (fp2), CONST0_RTX (SFmode));
2742 emit_insn (gen_slt_sf (dest, fp2, fp1));
2745 /* Emit code to change the current function's return address to
2746 ADDRESS. SCRATCH is available as a scratch register, if needed.
2747 ADDRESS and SCRATCH are both word-mode GPRs. */
2750 mips_set_return_address (rtx address, rtx scratch)
2754 compute_frame_size (get_frame_size ());
2755 if (((cfun->machine->frame.mask >> 31) & 1) == 0)
2757 slot_address = mips_add_offset (scratch, stack_pointer_rtx,
2758 cfun->machine->frame.gp_sp_offset);
2760 emit_move_insn (gen_rtx_MEM (GET_MODE (address), slot_address), address);
2763 /* Emit straight-line code to move LENGTH bytes from SRC to DEST.
2764 Assume that the areas do not overlap. */
2767 mips_block_move_straight (rtx dest, rtx src, HOST_WIDE_INT length)
2769 HOST_WIDE_INT offset, delta;
2770 unsigned HOST_WIDE_INT bits;
2772 enum machine_mode mode;
2775 /* Work out how many bits to move at a time. If both operands have
2776 half-word alignment, it is usually better to move in half words.
2777 For instance, lh/lh/sh/sh is usually better than lwl/lwr/swl/swr
2778 and lw/lw/sw/sw is usually better than ldl/ldr/sdl/sdr.
2779 Otherwise move word-sized chunks. */
2780 if (MEM_ALIGN (src) == BITS_PER_WORD / 2
2781 && MEM_ALIGN (dest) == BITS_PER_WORD / 2)
2782 bits = BITS_PER_WORD / 2;
2784 bits = BITS_PER_WORD;
2786 mode = mode_for_size (bits, MODE_INT, 0);
2787 delta = bits / BITS_PER_UNIT;
2789 /* Allocate a buffer for the temporary registers. */
2790 regs = alloca (sizeof (rtx) * length / delta);
2792 /* Load as many BITS-sized chunks as possible. Use a normal load if
2793 the source has enough alignment, otherwise use left/right pairs. */
2794 for (offset = 0, i = 0; offset + delta <= length; offset += delta, i++)
2796 regs[i] = gen_reg_rtx (mode);
2797 if (MEM_ALIGN (src) >= bits)
2798 emit_move_insn (regs[i], adjust_address (src, mode, offset));
2801 rtx part = adjust_address (src, BLKmode, offset);
2802 if (!mips_expand_unaligned_load (regs[i], part, bits, 0))
2807 /* Copy the chunks to the destination. */
2808 for (offset = 0, i = 0; offset + delta <= length; offset += delta, i++)
2809 if (MEM_ALIGN (dest) >= bits)
2810 emit_move_insn (adjust_address (dest, mode, offset), regs[i]);
2813 rtx part = adjust_address (dest, BLKmode, offset);
2814 if (!mips_expand_unaligned_store (part, regs[i], bits, 0))
2818 /* Mop up any left-over bytes. */
2819 if (offset < length)
2821 src = adjust_address (src, BLKmode, offset);
2822 dest = adjust_address (dest, BLKmode, offset);
2823 move_by_pieces (dest, src, length - offset,
2824 MIN (MEM_ALIGN (src), MEM_ALIGN (dest)), 0);
2828 #define MAX_MOVE_REGS 4
2829 #define MAX_MOVE_BYTES (MAX_MOVE_REGS * UNITS_PER_WORD)
2832 /* Helper function for doing a loop-based block operation on memory
2833 reference MEM. Each iteration of the loop will operate on LENGTH
2836 Create a new base register for use within the loop and point it to
2837 the start of MEM. Create a new memory reference that uses this
2838 register. Store them in *LOOP_REG and *LOOP_MEM respectively. */
2841 mips_adjust_block_mem (rtx mem, HOST_WIDE_INT length,
2842 rtx *loop_reg, rtx *loop_mem)
2844 *loop_reg = copy_addr_to_reg (XEXP (mem, 0));
2846 /* Although the new mem does not refer to a known location,
2847 it does keep up to LENGTH bytes of alignment. */
2848 *loop_mem = change_address (mem, BLKmode, *loop_reg);
2849 set_mem_align (*loop_mem, MIN (MEM_ALIGN (mem), length * BITS_PER_UNIT));
2853 /* Move LENGTH bytes from SRC to DEST using a loop that moves MAX_MOVE_BYTES
2854 per iteration. LENGTH must be at least MAX_MOVE_BYTES. Assume that the
2855 memory regions do not overlap. */
2858 mips_block_move_loop (rtx dest, rtx src, HOST_WIDE_INT length)
2860 rtx label, src_reg, dest_reg, final_src;
2861 HOST_WIDE_INT leftover;
2863 leftover = length % MAX_MOVE_BYTES;
2866 /* Create registers and memory references for use within the loop. */
2867 mips_adjust_block_mem (src, MAX_MOVE_BYTES, &src_reg, &src);
2868 mips_adjust_block_mem (dest, MAX_MOVE_BYTES, &dest_reg, &dest);
2870 /* Calculate the value that SRC_REG should have after the last iteration
2872 final_src = expand_simple_binop (Pmode, PLUS, src_reg, GEN_INT (length),
2875 /* Emit the start of the loop. */
2876 label = gen_label_rtx ();
2879 /* Emit the loop body. */
2880 mips_block_move_straight (dest, src, MAX_MOVE_BYTES);
2882 /* Move on to the next block. */
2883 emit_move_insn (src_reg, plus_constant (src_reg, MAX_MOVE_BYTES));
2884 emit_move_insn (dest_reg, plus_constant (dest_reg, MAX_MOVE_BYTES));
2886 /* Emit the loop condition. */
2887 if (Pmode == DImode)
2888 emit_insn (gen_cmpdi (src_reg, final_src));
2890 emit_insn (gen_cmpsi (src_reg, final_src));
2891 emit_jump_insn (gen_bne (label));
2893 /* Mop up any left-over bytes. */
2895 mips_block_move_straight (dest, src, leftover);
2898 /* Expand a movmemsi instruction. */
2901 mips_expand_block_move (rtx dest, rtx src, rtx length)
2903 if (GET_CODE (length) == CONST_INT)
2905 if (INTVAL (length) <= 2 * MAX_MOVE_BYTES)
2907 mips_block_move_straight (dest, src, INTVAL (length));
2912 mips_block_move_loop (dest, src, INTVAL (length));
2919 /* Argument support functions. */
2921 /* Initialize CUMULATIVE_ARGS for a function. */
2924 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
2925 rtx libname ATTRIBUTE_UNUSED)
2927 static CUMULATIVE_ARGS zero_cum;
2928 tree param, next_param;
2931 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
2933 /* Determine if this function has variable arguments. This is
2934 indicated by the last argument being 'void_type_mode' if there
2935 are no variable arguments. The standard MIPS calling sequence
2936 passes all arguments in the general purpose registers in this case. */
2938 for (param = fntype ? TYPE_ARG_TYPES (fntype) : 0;
2939 param != 0; param = next_param)
2941 next_param = TREE_CHAIN (param);
2942 if (next_param == 0 && TREE_VALUE (param) != void_type_node)
2943 cum->gp_reg_found = 1;
2948 /* Fill INFO with information about a single argument. CUM is the
2949 cumulative state for earlier arguments. MODE is the mode of this
2950 argument and TYPE is its type (if known). NAMED is true if this
2951 is a named (fixed) argument rather than a variable one. */
2954 mips_arg_info (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
2955 tree type, int named, struct mips_arg_info *info)
2958 unsigned int num_bytes, num_words, max_regs;
2960 /* Work out the size of the argument. */
2961 num_bytes = type ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
2962 num_words = (num_bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
2964 /* Decide whether it should go in a floating-point register, assuming
2965 one is free. Later code checks for availability.
2967 The checks against UNITS_PER_FPVALUE handle the soft-float and
2968 single-float cases. */
2972 /* The EABI conventions have traditionally been defined in terms
2973 of TYPE_MODE, regardless of the actual type. */
2974 info->fpr_p = ((GET_MODE_CLASS (mode) == MODE_FLOAT
2975 || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
2976 && GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE);
2981 /* Only leading floating-point scalars are passed in
2982 floating-point registers. We also handle vector floats the same
2983 say, which is OK because they are not covered by the standard ABI. */
2984 info->fpr_p = (!cum->gp_reg_found
2985 && cum->arg_number < 2
2986 && (type == 0 || SCALAR_FLOAT_TYPE_P (type)
2987 || VECTOR_FLOAT_TYPE_P (type))
2988 && (GET_MODE_CLASS (mode) == MODE_FLOAT
2989 || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
2990 && GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE);
2995 /* Scalar and complex floating-point types are passed in
2996 floating-point registers. */
2997 info->fpr_p = (named
2998 && (type == 0 || FLOAT_TYPE_P (type))
2999 && (GET_MODE_CLASS (mode) == MODE_FLOAT
3000 || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
3001 || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
3002 && GET_MODE_UNIT_SIZE (mode) <= UNITS_PER_FPVALUE);
3004 /* ??? According to the ABI documentation, the real and imaginary
3005 parts of complex floats should be passed in individual registers.
3006 The real and imaginary parts of stack arguments are supposed
3007 to be contiguous and there should be an extra word of padding
3010 This has two problems. First, it makes it impossible to use a
3011 single "void *" va_list type, since register and stack arguments
3012 are passed differently. (At the time of writing, MIPSpro cannot
3013 handle complex float varargs correctly.) Second, it's unclear
3014 what should happen when there is only one register free.
3016 For now, we assume that named complex floats should go into FPRs
3017 if there are two FPRs free, otherwise they should be passed in the
3018 same way as a struct containing two floats. */
3020 && GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
3021 && GET_MODE_UNIT_SIZE (mode) < UNITS_PER_FPVALUE)
3023 if (cum->num_gprs >= MAX_ARGS_IN_REGISTERS - 1)
3024 info->fpr_p = false;
3034 /* Now decide whether the argument must go in an even-numbered register.
3035 Usually this is determined by type alignment, but there are two
3038 - Under the O64 ABI, the second float argument goes in $f14 if it
3039 is single precision (doubles go in $f13 as expected).
3041 - Floats passed in FPRs must be in an even-numbered register if
3042 we're using paired FPRs. */
3044 even_reg_p = TYPE_ALIGN (type) > BITS_PER_WORD;
3046 even_reg_p = GET_MODE_UNIT_SIZE (mode) > UNITS_PER_WORD;
3050 if (mips_abi == ABI_O64 && mode == SFmode)
3056 /* Set REG_OFFSET to the register count we're interested in.
3057 The EABI allocates the floating-point registers separately,
3058 but the other ABIs allocate them like integer registers. */
3059 info->reg_offset = (mips_abi == ABI_EABI && info->fpr_p
3064 info->reg_offset += info->reg_offset & 1;
3066 /* The alignment applied to registers is also applied to stack arguments. */
3067 info->stack_offset = cum->stack_words;
3069 info->stack_offset += info->stack_offset & 1;
3071 max_regs = MAX_ARGS_IN_REGISTERS - info->reg_offset;
3073 /* Partition the argument between registers and stack. */
3074 info->reg_words = MIN (num_words, max_regs);
3075 info->stack_words = num_words - info->reg_words;
3079 /* Implement FUNCTION_ARG_ADVANCE. */
3082 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
3083 tree type, int named)
3085 struct mips_arg_info info;
3087 mips_arg_info (cum, mode, type, named, &info);
3090 cum->gp_reg_found = true;
3092 /* See the comment above the cumulative args structure in mips.h
3093 for an explanation of what this code does. It assumes the O32
3094 ABI, which passes at most 2 arguments in float registers. */
3095 if (cum->arg_number < 2 && info.fpr_p)
3096 cum->fp_code += (mode == SFmode ? 1 : 2) << ((cum->arg_number - 1) * 2);
3098 if (mips_abi != ABI_EABI || !info.fpr_p)
3099 cum->num_gprs = info.reg_offset + info.reg_words;
3100 else if (info.reg_words > 0)
3101 cum->num_fprs += FP_INC;
3103 if (info.stack_words > 0)
3104 cum->stack_words = info.stack_offset + info.stack_words;
3109 /* Implement FUNCTION_ARG. */
3112 function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
3113 tree type, int named)
3115 struct mips_arg_info info;
3117 /* We will be called with a mode of VOIDmode after the last argument
3118 has been seen. Whatever we return will be passed to the call
3119 insn. If we need a mips16 fp_code, return a REG with the code
3120 stored as the mode. */
3121 if (mode == VOIDmode)
3123 if (TARGET_MIPS16 && cum->fp_code != 0)
3124 return gen_rtx_REG ((enum machine_mode) cum->fp_code, 0);
3130 mips_arg_info (cum, mode, type, named, &info);
3132 /* Return straight away if the whole argument is passed on the stack. */
3133 if (info.reg_offset == MAX_ARGS_IN_REGISTERS)
3137 && TREE_CODE (type) == RECORD_TYPE
3139 && TYPE_SIZE_UNIT (type)
3140 && host_integerp (TYPE_SIZE_UNIT (type), 1)
3143 /* The Irix 6 n32/n64 ABIs say that if any 64 bit chunk of the
3144 structure contains a double in its entirety, then that 64 bit
3145 chunk is passed in a floating point register. */
3148 /* First check to see if there is any such field. */
3149 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
3150 if (TREE_CODE (field) == FIELD_DECL
3151 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
3152 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD
3153 && host_integerp (bit_position (field), 0)
3154 && int_bit_position (field) % BITS_PER_WORD == 0)
3159 /* Now handle the special case by returning a PARALLEL
3160 indicating where each 64 bit chunk goes. INFO.REG_WORDS
3161 chunks are passed in registers. */
3163 HOST_WIDE_INT bitpos;
3166 /* assign_parms checks the mode of ENTRY_PARM, so we must
3167 use the actual mode here. */
3168 ret = gen_rtx_PARALLEL (mode, rtvec_alloc (info.reg_words));
3171 field = TYPE_FIELDS (type);
3172 for (i = 0; i < info.reg_words; i++)
3176 for (; field; field = TREE_CHAIN (field))
3177 if (TREE_CODE (field) == FIELD_DECL
3178 && int_bit_position (field) >= bitpos)
3182 && int_bit_position (field) == bitpos
3183 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
3184 && !TARGET_SOFT_FLOAT
3185 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD)
3186 reg = gen_rtx_REG (DFmode, FP_ARG_FIRST + info.reg_offset + i);
3188 reg = gen_rtx_REG (DImode, GP_ARG_FIRST + info.reg_offset + i);
3191 = gen_rtx_EXPR_LIST (VOIDmode, reg,
3192 GEN_INT (bitpos / BITS_PER_UNIT));
3194 bitpos += BITS_PER_WORD;
3200 /* Handle the n32/n64 conventions for passing complex floating-point
3201 arguments in FPR pairs. The real part goes in the lower register
3202 and the imaginary part goes in the upper register. */
3205 && GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
3208 enum machine_mode inner;
3211 inner = GET_MODE_INNER (mode);
3212 reg = FP_ARG_FIRST + info.reg_offset;
3213 real = gen_rtx_EXPR_LIST (VOIDmode,
3214 gen_rtx_REG (inner, reg),
3216 imag = gen_rtx_EXPR_LIST (VOIDmode,
3217 gen_rtx_REG (inner, reg + info.reg_words / 2),
3218 GEN_INT (GET_MODE_SIZE (inner)));
3219 return gen_rtx_PARALLEL (mode, gen_rtvec (2, real, imag));
3223 return gen_rtx_REG (mode, FP_ARG_FIRST + info.reg_offset);
3225 return gen_rtx_REG (mode, GP_ARG_FIRST + info.reg_offset);
3229 /* Implement FUNCTION_ARG_PARTIAL_NREGS. */
3232 function_arg_partial_nregs (const CUMULATIVE_ARGS *cum,
3233 enum machine_mode mode, tree type, int named)
3235 struct mips_arg_info info;
3237 mips_arg_info (cum, mode, type, named, &info);
3238 return info.stack_words > 0 ? info.reg_words : 0;
3242 /* Return true if FUNCTION_ARG_PADDING (MODE, TYPE) should return
3243 upward rather than downward. In other words, return true if the
3244 first byte of the stack slot has useful data, false if the last
3248 mips_pad_arg_upward (enum machine_mode mode, tree type)
3250 /* On little-endian targets, the first byte of every stack argument
3251 is passed in the first byte of the stack slot. */
3252 if (!BYTES_BIG_ENDIAN)
3255 /* Otherwise, integral types are padded downward: the last byte of a
3256 stack argument is passed in the last byte of the stack slot. */
3258 ? INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)
3259 : GET_MODE_CLASS (mode) == MODE_INT)
3262 /* Big-endian o64 pads floating-point arguments downward. */
3263 if (mips_abi == ABI_O64)
3264 if (type != 0 ? FLOAT_TYPE_P (type) : GET_MODE_CLASS (mode) == MODE_FLOAT)
3267 /* Other types are padded upward for o32, o64, n32 and n64. */
3268 if (mips_abi != ABI_EABI)
3271 /* Arguments smaller than a stack slot are padded downward. */
3272 if (mode != BLKmode)
3273 return (GET_MODE_BITSIZE (mode) >= PARM_BOUNDARY);
3275 return (int_size_in_bytes (type) >= (PARM_BOUNDARY / BITS_PER_UNIT));
3279 /* Likewise BLOCK_REG_PADDING (MODE, TYPE, ...). Return !BYTES_BIG_ENDIAN
3280 if the least significant byte of the register has useful data. Return
3281 the opposite if the most significant byte does. */
3284 mips_pad_reg_upward (enum machine_mode mode, tree type)
3286 /* No shifting is required for floating-point arguments. */
3287 if (type != 0 ? FLOAT_TYPE_P (type) : GET_MODE_CLASS (mode) == MODE_FLOAT)
3288 return !BYTES_BIG_ENDIAN;
3290 /* Otherwise, apply the same padding to register arguments as we do
3291 to stack arguments. */
3292 return mips_pad_arg_upward (mode, type);
3296 mips_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
3297 tree type, int *pretend_size, int no_rtl)
3299 CUMULATIVE_ARGS local_cum;
3300 int gp_saved, fp_saved;
3302 /* The caller has advanced CUM up to, but not beyond, the last named
3303 argument. Advance a local copy of CUM past the last "real" named
3304 argument, to find out how many registers are left over. */
3307 FUNCTION_ARG_ADVANCE (local_cum, mode, type, 1);
3309 /* Found out how many registers we need to save. */
3310 gp_saved = MAX_ARGS_IN_REGISTERS - local_cum.num_gprs;
3311 fp_saved = (EABI_FLOAT_VARARGS_P
3312 ? MAX_ARGS_IN_REGISTERS - local_cum.num_fprs
3321 ptr = virtual_incoming_args_rtx;
3326 ptr = plus_constant (ptr, local_cum.num_gprs * UNITS_PER_WORD);
3330 ptr = plus_constant (ptr, -gp_saved * UNITS_PER_WORD);
3333 mem = gen_rtx_MEM (BLKmode, ptr);
3334 set_mem_alias_set (mem, get_varargs_alias_set ());
3336 move_block_from_reg (local_cum.num_gprs + GP_ARG_FIRST,
3341 /* We can't use move_block_from_reg, because it will use
3343 enum machine_mode mode;
3346 /* Set OFF to the offset from virtual_incoming_args_rtx of
3347 the first float register. The FP save area lies below
3348 the integer one, and is aligned to UNITS_PER_FPVALUE bytes. */
3349 off = -gp_saved * UNITS_PER_WORD;
3350 off &= ~(UNITS_PER_FPVALUE - 1);
3351 off -= fp_saved * UNITS_PER_FPREG;
3353 mode = TARGET_SINGLE_FLOAT ? SFmode : DFmode;
3355 for (i = local_cum.num_fprs; i < MAX_ARGS_IN_REGISTERS; i += FP_INC)
3359 ptr = plus_constant (virtual_incoming_args_rtx, off);
3360 mem = gen_rtx_MEM (mode, ptr);
3361 set_mem_alias_set (mem, get_varargs_alias_set ());
3362 emit_move_insn (mem, gen_rtx_REG (mode, FP_ARG_FIRST + i));
3363 off += UNITS_PER_HWFPVALUE;
3369 /* No need for pretend arguments: the register parameter area was
3370 allocated by the caller. */
3374 *pretend_size = (gp_saved * UNITS_PER_WORD) + (fp_saved * UNITS_PER_FPREG);
3377 /* Create the va_list data type.
3378 We keep 3 pointers, and two offsets.
3379 Two pointers are to the overflow area, which starts at the CFA.
3380 One of these is constant, for addressing into the GPR save area below it.
3381 The other is advanced up the stack through the overflow region.
3382 The third pointer is to the GPR save area. Since the FPR save area
3383 is just below it, we can address FPR slots off this pointer.
3384 We also keep two one-byte offsets, which are to be subtracted from the
3385 constant pointers to yield addresses in the GPR and FPR save areas.
3386 These are downcounted as float or non-float arguments are used,
3387 and when they get to zero, the argument must be obtained from the
3389 If !EABI_FLOAT_VARARGS_P, then no FPR save area exists, and a single
3390 pointer is enough. It's started at the GPR save area, and is
3392 Note that the GPR save area is not constant size, due to optimization
3393 in the prologue. Hence, we can't use a design with two pointers
3394 and two offsets, although we could have designed this with two pointers
3395 and three offsets. */
3398 mips_build_builtin_va_list (void)
3400 if (EABI_FLOAT_VARARGS_P)
3402 tree f_ovfl, f_gtop, f_ftop, f_goff, f_foff, f_res, record;
3405 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
3407 f_ovfl = build_decl (FIELD_DECL, get_identifier ("__overflow_argptr"),
3409 f_gtop = build_decl (FIELD_DECL, get_identifier ("__gpr_top"),
3411 f_ftop = build_decl (FIELD_DECL, get_identifier ("__fpr_top"),
3413 f_goff = build_decl (FIELD_DECL, get_identifier ("__gpr_offset"),
3414 unsigned_char_type_node);
3415 f_foff = build_decl (FIELD_DECL, get_identifier ("__fpr_offset"),
3416 unsigned_char_type_node);
3417 /* Explicitly pad to the size of a pointer, so that -Wpadded won't
3418 warn on every user file. */
3419 index = build_int_cst (NULL_TREE, GET_MODE_SIZE (ptr_mode) - 2 - 1);
3420 array = build_array_type (unsigned_char_type_node,
3421 build_index_type (index));
3422 f_res = build_decl (FIELD_DECL, get_identifier ("__reserved"), array);
3424 DECL_FIELD_CONTEXT (f_ovfl) = record;
3425 DECL_FIELD_CONTEXT (f_gtop) = record;
3426 DECL_FIELD_CONTEXT (f_ftop) = record;
3427 DECL_FIELD_CONTEXT (f_goff) = record;
3428 DECL_FIELD_CONTEXT (f_foff) = record;
3429 DECL_FIELD_CONTEXT (f_res) = record;
3431 TYPE_FIELDS (record) = f_ovfl;
3432 TREE_CHAIN (f_ovfl) = f_gtop;
3433 TREE_CHAIN (f_gtop) = f_ftop;
3434 TREE_CHAIN (f_ftop) = f_goff;
3435 TREE_CHAIN (f_goff) = f_foff;
3436 TREE_CHAIN (f_foff) = f_res;
3438 layout_type (record);
3441 else if (TARGET_IRIX && TARGET_IRIX6)
3442 /* On IRIX 6, this type is 'char *'. */
3443 return build_pointer_type (char_type_node);
3445 /* Otherwise, we use 'void *'. */
3446 return ptr_type_node;
3449 /* Implement va_start. */
3452 mips_va_start (tree valist, rtx nextarg)
3454 const CUMULATIVE_ARGS *cum = ¤t_function_args_info;
3456 /* ARG_POINTER_REGNUM is initialized to STACK_POINTER_BOUNDARY, but
3457 since the stack is aligned for a pair of argument-passing slots,
3458 and the beginning of a variable argument list may be an odd slot,
3459 we have to decrease its alignment. */
3460 if (cfun && cfun->emit->regno_pointer_align)
3461 while (((current_function_pretend_args_size * BITS_PER_UNIT)
3462 & (REGNO_POINTER_ALIGN (ARG_POINTER_REGNUM) - 1)) != 0)
3463 REGNO_POINTER_ALIGN (ARG_POINTER_REGNUM) /= 2;
3465 if (mips_abi == ABI_EABI)
3467 int gpr_save_area_size;
3470 = (MAX_ARGS_IN_REGISTERS - cum->num_gprs) * UNITS_PER_WORD;
3472 if (EABI_FLOAT_VARARGS_P)
3474 tree f_ovfl, f_gtop, f_ftop, f_goff, f_foff;
3475 tree ovfl, gtop, ftop, goff, foff;
3478 int fpr_save_area_size;
3480 f_ovfl = TYPE_FIELDS (va_list_type_node);
3481 f_gtop = TREE_CHAIN (f_ovfl);
3482 f_ftop = TREE_CHAIN (f_gtop);
3483 f_goff = TREE_CHAIN (f_ftop);
3484 f_foff = TREE_CHAIN (f_goff);
3486 ovfl = build (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl,
3488 gtop = build (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop,
3490 ftop = build (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop,
3492 goff = build (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff,
3494 foff = build (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff,
3497 /* Emit code to initialize OVFL, which points to the next varargs
3498 stack argument. CUM->STACK_WORDS gives the number of stack
3499 words used by named arguments. */
3500 t = make_tree (TREE_TYPE (ovfl), virtual_incoming_args_rtx);
3501 if (cum->stack_words > 0)
3502 t = build (PLUS_EXPR, TREE_TYPE (ovfl), t,
3503 build_int_cst (NULL_TREE,
3504 cum->stack_words * UNITS_PER_WORD));
3505 t = build (MODIFY_EXPR, TREE_TYPE (ovfl), ovfl, t);
3506 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3508 /* Emit code to initialize GTOP, the top of the GPR save area. */
3509 t = make_tree (TREE_TYPE (gtop), virtual_incoming_args_rtx);
3510 t = build (MODIFY_EXPR, TREE_TYPE (gtop), gtop, t);
3511 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3513 /* Emit code to initialize FTOP, the top of the FPR save area.
3514 This address is gpr_save_area_bytes below GTOP, rounded
3515 down to the next fp-aligned boundary. */
3516 t = make_tree (TREE_TYPE (ftop), virtual_incoming_args_rtx);
3517 fpr_offset = gpr_save_area_size + UNITS_PER_FPVALUE - 1;
3518 fpr_offset &= ~(UNITS_PER_FPVALUE - 1);
3520 t = build (PLUS_EXPR, TREE_TYPE (ftop), t,
3521 build_int_cst (NULL_TREE, -fpr_offset));
3522 t = build (MODIFY_EXPR, TREE_TYPE (ftop), ftop, t);
3523 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3525 /* Emit code to initialize GOFF, the offset from GTOP of the
3526 next GPR argument. */
3527 t = build (MODIFY_EXPR, TREE_TYPE (goff), goff,
3528 build_int_cst (NULL_TREE, gpr_save_area_size));
3529 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3531 /* Likewise emit code to initialize FOFF, the offset from FTOP
3532 of the next FPR argument. */
3534 = (MAX_ARGS_IN_REGISTERS - cum->num_fprs) * UNITS_PER_FPREG;
3535 t = build (MODIFY_EXPR, TREE_TYPE (foff), foff,
3536 build_int_cst (NULL_TREE, fpr_save_area_size));
3537 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3541 /* Everything is in the GPR save area, or in the overflow
3542 area which is contiguous with it. */
3543 nextarg = plus_constant (nextarg, -gpr_save_area_size);
3544 std_expand_builtin_va_start (valist, nextarg);
3548 std_expand_builtin_va_start (valist, nextarg);
3551 /* Implement va_arg. */
3554 mips_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
3556 HOST_WIDE_INT size, rsize;
3560 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, 0);
3563 type = build_pointer_type (type);
3565 size = int_size_in_bytes (type);
3566 rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD;
3568 if (mips_abi != ABI_EABI || !EABI_FLOAT_VARARGS_P)
3569 addr = std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
3572 /* Not a simple merged stack. */
3574 tree f_ovfl, f_gtop, f_ftop, f_goff, f_foff;
3575 tree ovfl, top, off, align;
3576 HOST_WIDE_INT osize;
3579 f_ovfl = TYPE_FIELDS (va_list_type_node);
3580 f_gtop = TREE_CHAIN (f_ovfl);
3581 f_ftop = TREE_CHAIN (f_gtop);
3582 f_goff = TREE_CHAIN (f_ftop);
3583 f_foff = TREE_CHAIN (f_goff);
3585 /* We maintain separate pointers and offsets for floating-point
3586 and integer arguments, but we need similar code in both cases.
3589 TOP be the top of the register save area;
3590 OFF be the offset from TOP of the next register;
3591 ADDR_RTX be the address of the argument;
3592 RSIZE be the number of bytes used to store the argument
3593 when it's in the register save area;
3594 OSIZE be the number of bytes used to store it when it's
3595 in the stack overflow area; and
3596 PADDING be (BYTES_BIG_ENDIAN ? OSIZE - RSIZE : 0)
3598 The code we want is:
3600 1: off &= -rsize; // round down
3603 4: addr_rtx = top - off;
3608 9: ovfl += ((intptr_t) ovfl + osize - 1) & -osize;
3609 10: addr_rtx = ovfl + PADDING;
3613 [1] and [9] can sometimes be optimized away. */
3615 ovfl = build (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl,
3618 if (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT
3619 && GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_FPVALUE)
3621 top = build (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop,
3623 off = build (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff,
3626 /* When floating-point registers are saved to the stack,
3627 each one will take up UNITS_PER_HWFPVALUE bytes, regardless
3628 of the float's precision. */
3629 rsize = UNITS_PER_HWFPVALUE;
3631 /* Overflow arguments are padded to UNITS_PER_WORD bytes
3632 (= PARM_BOUNDARY bits). This can be different from RSIZE
3635 (1) On 32-bit targets when TYPE is a structure such as:
3637 struct s { float f; };
3639 Such structures are passed in paired FPRs, so RSIZE
3640 will be 8 bytes. However, the structure only takes
3641 up 4 bytes of memory, so OSIZE will only be 4.
3643 (2) In combinations such as -mgp64 -msingle-float
3644 -fshort-double. Doubles passed in registers
3645 will then take up 4 (UNITS_PER_HWFPVALUE) bytes,
3646 but those passed on the stack take up
3647 UNITS_PER_WORD bytes. */
3648 osize = MAX (GET_MODE_SIZE (TYPE_MODE (type)), UNITS_PER_WORD);
3652 top = build (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop,
3654 off = build (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff,
3656 if (rsize > UNITS_PER_WORD)
3658 /* [1] Emit code for: off &= -rsize. */
3659 t = build (BIT_AND_EXPR, TREE_TYPE (off), off,
3660 build_int_cst (NULL_TREE, -rsize));
3661 t = build (MODIFY_EXPR, TREE_TYPE (off), off, t);
3662 gimplify_and_add (t, pre_p);
3667 /* [2] Emit code to branch if off == 0. */
3668 t = lang_hooks.truthvalue_conversion (off);
3669 addr = build (COND_EXPR, ptr_type_node, t, NULL, NULL);
3671 /* [5] Emit code for: off -= rsize. We do this as a form of
3672 post-increment not available to C. Also widen for the
3673 coming pointer arithmetic. */
3674 t = fold_convert (TREE_TYPE (off), build_int_cst (NULL_TREE, rsize));
3675 t = build (POSTDECREMENT_EXPR, TREE_TYPE (off), off, t);
3676 t = fold_convert (sizetype, t);
3677 t = fold_convert (TREE_TYPE (top), t);
3679 /* [4] Emit code for: addr_rtx = top - off. On big endian machines,
3680 the argument has RSIZE - SIZE bytes of leading padding. */
3681 t = build (MINUS_EXPR, TREE_TYPE (top), top, t);
3682 if (BYTES_BIG_ENDIAN && rsize > size)
3684 u = fold_convert (TREE_TYPE (t), build_int_cst (NULL_TREE,
3686 t = build (PLUS_EXPR, TREE_TYPE (t), t, u);
3688 COND_EXPR_THEN (addr) = t;
3690 if (osize > UNITS_PER_WORD)
3692 /* [9] Emit: ovfl += ((intptr_t) ovfl + osize - 1) & -osize. */
3693 u = fold_convert (TREE_TYPE (ovfl),
3694 build_int_cst (NULL_TREE, osize - 1));
3695 t = build (PLUS_EXPR, TREE_TYPE (ovfl), ovfl, u);
3696 u = fold_convert (TREE_TYPE (ovfl),
3697 build_int_cst (NULL_TREE, -osize));
3698 t = build (BIT_AND_EXPR, TREE_TYPE (ovfl), t, u);
3699 align = build (MODIFY_EXPR, TREE_TYPE (ovfl), ovfl, t);
3704 /* [10, 11]. Emit code to store ovfl in addr_rtx, then
3705 post-increment ovfl by osize. On big-endian machines,
3706 the argument has OSIZE - SIZE bytes of leading padding. */
3707 u = fold_convert (TREE_TYPE (ovfl),
3708 build_int_cst (NULL_TREE, osize));
3709 t = build (POSTINCREMENT_EXPR, TREE_TYPE (ovfl), ovfl, u);
3710 if (BYTES_BIG_ENDIAN && osize > size)
3712 u = fold_convert (TREE_TYPE (t),
3713 build_int_cst (NULL_TREE, osize - size));
3714 t = build (PLUS_EXPR, TREE_TYPE (t), t, u);
3717 /* String [9] and [10,11] together. */
3719 t = build (COMPOUND_EXPR, TREE_TYPE (t), align, t);
3720 COND_EXPR_ELSE (addr) = t;
3722 addr = fold_convert (build_pointer_type (type), addr);
3723 addr = build_fold_indirect_ref (addr);
3727 addr = build_fold_indirect_ref (addr);
3732 /* Return true if it is possible to use left/right accesses for a
3733 bitfield of WIDTH bits starting BITPOS bits into *OP. When
3734 returning true, update *OP, *LEFT and *RIGHT as follows:
3736 *OP is a BLKmode reference to the whole field.
3738 *LEFT is a QImode reference to the first byte if big endian or
3739 the last byte if little endian. This address can be used in the
3740 left-side instructions (lwl, swl, ldl, sdl).
3742 *RIGHT is a QImode reference to the opposite end of the field and
3743 can be used in the parterning right-side instruction. */
3746 mips_get_unaligned_mem (rtx *op, unsigned int width, int bitpos,
3747 rtx *left, rtx *right)
3751 /* Check that the operand really is a MEM. Not all the extv and
3752 extzv predicates are checked. */
3753 if (GET_CODE (*op) != MEM)
3756 /* Check that the size is valid. */
3757 if (width != 32 && (!TARGET_64BIT || width != 64))
3760 /* We can only access byte-aligned values. Since we are always passed
3761 a reference to the first byte of the field, it is not necessary to
3762 do anything with BITPOS after this check. */
3763 if (bitpos % BITS_PER_UNIT != 0)
3766 /* Reject aligned bitfields: we want to use a normal load or store
3767 instead of a left/right pair. */
3768 if (MEM_ALIGN (*op) >= width)
3771 /* Adjust *OP to refer to the whole field. This also has the effect
3772 of legitimizing *OP's address for BLKmode, possibly simplifying it. */
3773 *op = adjust_address (*op, BLKmode, 0);
3774 set_mem_size (*op, GEN_INT (width / BITS_PER_UNIT));
3776 /* Get references to both ends of the field. We deliberately don't
3777 use the original QImode *OP for FIRST since the new BLKmode one
3778 might have a simpler address. */
3779 first = adjust_address (*op, QImode, 0);
3780 last = adjust_address (*op, QImode, width / BITS_PER_UNIT - 1);
3782 /* Allocate to LEFT and RIGHT according to endianness. LEFT should
3783 be the upper word and RIGHT the lower word. */
3784 if (TARGET_BIG_ENDIAN)
3785 *left = first, *right = last;
3787 *left = last, *right = first;
3793 /* Try to emit the equivalent of (set DEST (zero_extract SRC WIDTH BITPOS)).
3794 Return true on success. We only handle cases where zero_extract is
3795 equivalent to sign_extract. */
3798 mips_expand_unaligned_load (rtx dest, rtx src, unsigned int width, int bitpos)
3800 rtx left, right, temp;
3802 /* If TARGET_64BIT, the destination of a 32-bit load will be a
3803 paradoxical word_mode subreg. This is the only case in which
3804 we allow the destination to be larger than the source. */
3805 if (GET_CODE (dest) == SUBREG
3806 && GET_MODE (dest) == DImode
3807 && SUBREG_BYTE (dest) == 0
3808 && GET_MODE (SUBREG_REG (dest)) == SImode)
3809 dest = SUBREG_REG (dest);
3811 /* After the above adjustment, the destination must be the same
3812 width as the source. */
3813 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
3816 if (!mips_get_unaligned_mem (&src, width, bitpos, &left, &right))
3819 temp = gen_reg_rtx (GET_MODE (dest));
3820 if (GET_MODE (dest) == DImode)
3822 emit_insn (gen_mov_ldl (temp, src, left));
3823 emit_insn (gen_mov_ldr (dest, copy_rtx (src), right, temp));
3827 emit_insn (gen_mov_lwl (temp, src, left));
3828 emit_insn (gen_mov_lwr (dest, copy_rtx (src), right, temp));
3834 /* Try to expand (set (zero_extract DEST WIDTH BITPOS) SRC). Return
3838 mips_expand_unaligned_store (rtx dest, rtx src, unsigned int width, int bitpos)
3842 if (!mips_get_unaligned_mem (&dest, width, bitpos, &left, &right))
3845 src = gen_lowpart (mode_for_size (width, MODE_INT, 0), src);
3847 if (GET_MODE (src) == DImode)
3849 emit_insn (gen_mov_sdl (dest, src, left));
3850 emit_insn (gen_mov_sdr (copy_rtx (dest), copy_rtx (src), right));
3854 emit_insn (gen_mov_swl (dest, src, left));
3855 emit_insn (gen_mov_swr (copy_rtx (dest), copy_rtx (src), right));
3860 /* Set up globals to generate code for the ISA or processor
3861 described by INFO. */
3864 mips_set_architecture (const struct mips_cpu_info *info)
3868 mips_arch_info = info;
3869 mips_arch = info->cpu;
3870 mips_isa = info->isa;
3875 /* Likewise for tuning. */
3878 mips_set_tune (const struct mips_cpu_info *info)
3882 mips_tune_info = info;
3883 mips_tune = info->cpu;
3888 /* Set up the threshold for data to go into the small data area, instead
3889 of the normal data area, and detect any conflicts in the switches. */
3892 override_options (void)
3894 int i, start, regno;
3895 enum machine_mode mode;
3897 mips_section_threshold = g_switch_set ? g_switch_value : MIPS_DEFAULT_GVALUE;
3899 /* Interpret -mabi. */
3900 mips_abi = MIPS_ABI_DEFAULT;
3901 if (mips_abi_string != 0)
3903 if (strcmp (mips_abi_string, "32") == 0)
3905 else if (strcmp (mips_abi_string, "o64") == 0)
3907 else if (strcmp (mips_abi_string, "n32") == 0)
3909 else if (strcmp (mips_abi_string, "64") == 0)
3911 else if (strcmp (mips_abi_string, "eabi") == 0)
3912 mips_abi = ABI_EABI;
3914 fatal_error ("bad value (%s) for -mabi= switch", mips_abi_string);
3917 /* The following code determines the architecture and register size.
3918 Similar code was added to GAS 2.14 (see tc-mips.c:md_after_parse_args()).
3919 The GAS and GCC code should be kept in sync as much as possible. */
3921 if (mips_arch_string != 0)
3922 mips_set_architecture (mips_parse_cpu ("-march", mips_arch_string));
3924 if (mips_isa_string != 0)
3926 /* Handle -mipsN. */
3927 char *whole_isa_str = concat ("mips", mips_isa_string, NULL);
3928 const struct mips_cpu_info *isa_info;
3930 isa_info = mips_parse_cpu ("-mips option", whole_isa_str);
3931 free (whole_isa_str);
3933 /* -march takes precedence over -mipsN, since it is more descriptive.
3934 There's no harm in specifying both as long as the ISA levels
3936 if (mips_arch_info != 0 && mips_isa != isa_info->isa)
3937 error ("-mips%s conflicts with the other architecture options, "
3938 "which specify a MIPS%d processor",
3939 mips_isa_string, mips_isa);
3941 /* Set architecture based on the given option. */
3942 mips_set_architecture (isa_info);
3945 if (mips_arch_info == 0)
3947 #ifdef MIPS_CPU_STRING_DEFAULT
3948 mips_set_architecture (mips_parse_cpu ("default CPU",
3949 MIPS_CPU_STRING_DEFAULT));
3951 mips_set_architecture (mips_cpu_info_from_isa (MIPS_ISA_DEFAULT));
3955 if (ABI_NEEDS_64BIT_REGS && !ISA_HAS_64BIT_REGS)
3956 error ("-march=%s is not compatible with the selected ABI",
3957 mips_arch_info->name);
3959 /* Optimize for mips_arch, unless -mtune selects a different processor. */
3960 if (mips_tune_string != 0)
3961 mips_set_tune (mips_parse_cpu ("-mtune", mips_tune_string));
3963 if (mips_tune_info == 0)
3964 mips_set_tune (mips_arch_info);
3966 if ((target_flags_explicit & MASK_64BIT) != 0)
3968 /* The user specified the size of the integer registers. Make sure
3969 it agrees with the ABI and ISA. */
3970 if (TARGET_64BIT && !ISA_HAS_64BIT_REGS)
3971 error ("-mgp64 used with a 32-bit processor");
3972 else if (!TARGET_64BIT && ABI_NEEDS_64BIT_REGS)
3973 error ("-mgp32 used with a 64-bit ABI");
3974 else if (TARGET_64BIT && ABI_NEEDS_32BIT_REGS)
3975 error ("-mgp64 used with a 32-bit ABI");
3979 /* Infer the integer register size from the ABI and processor.
3980 Restrict ourselves to 32-bit registers if that's all the
3981 processor has, or if the ABI cannot handle 64-bit registers. */
3982 if (ABI_NEEDS_32BIT_REGS || !ISA_HAS_64BIT_REGS)
3983 target_flags &= ~MASK_64BIT;
3985 target_flags |= MASK_64BIT;
3988 if ((target_flags_explicit & MASK_FLOAT64) != 0)
3990 /* Really, -mfp32 and -mfp64 are ornamental options. There's
3991 only one right answer here. */
3992 if (TARGET_64BIT && TARGET_DOUBLE_FLOAT && !TARGET_FLOAT64)
3993 error ("unsupported combination: %s", "-mgp64 -mfp32 -mdouble-float");
3994 else if (!TARGET_64BIT && TARGET_FLOAT64)
3995 error ("unsupported combination: %s", "-mgp32 -mfp64");
3996 else if (TARGET_SINGLE_FLOAT && TARGET_FLOAT64)
3997 error ("unsupported combination: %s", "-mfp64 -msingle-float");
4001 /* -msingle-float selects 32-bit float registers. Otherwise the
4002 float registers should be the same size as the integer ones. */
4003 if (TARGET_64BIT && TARGET_DOUBLE_FLOAT)
4004 target_flags |= MASK_FLOAT64;
4006 target_flags &= ~MASK_FLOAT64;
4009 /* End of code shared with GAS. */
4011 if ((target_flags_explicit & MASK_LONG64) == 0)
4013 /* If no type size setting options (-mlong64,-mint64,-mlong32)
4014 were used, then set the type sizes. In the EABI in 64 bit mode,
4015 longs and pointers are 64 bits. Likewise for the SGI Irix6 N64
4017 if ((mips_abi == ABI_EABI && TARGET_64BIT) || mips_abi == ABI_64)
4018 target_flags |= MASK_LONG64;
4020 target_flags &= ~MASK_LONG64;
4023 if (MIPS_MARCH_CONTROLS_SOFT_FLOAT
4024 && (target_flags_explicit & MASK_SOFT_FLOAT) == 0)
4026 /* For some configurations, it is useful to have -march control
4027 the default setting of MASK_SOFT_FLOAT. */
4028 switch ((int) mips_arch)
4030 case PROCESSOR_R4100:
4031 case PROCESSOR_R4111:
4032 case PROCESSOR_R4120:
4033 case PROCESSOR_R4130:
4034 target_flags |= MASK_SOFT_FLOAT;
4038 target_flags &= ~MASK_SOFT_FLOAT;
4044 flag_pcc_struct_return = 0;
4046 if ((target_flags_explicit & MASK_BRANCHLIKELY) == 0)
4048 /* If neither -mbranch-likely nor -mno-branch-likely was given
4049 on the command line, set MASK_BRANCHLIKELY based on the target
4052 By default, we enable use of Branch Likely instructions on
4053 all architectures which support them with the following
4054 exceptions: when creating MIPS32 or MIPS64 code, and when
4055 tuning for architectures where their use tends to hurt
4058 The MIPS32 and MIPS64 architecture specifications say "Software
4059 is strongly encouraged to avoid use of Branch Likely
4060 instructions, as they will be removed from a future revision
4061 of the [MIPS32 and MIPS64] architecture." Therefore, we do not
4062 issue those instructions unless instructed to do so by
4064 if (ISA_HAS_BRANCHLIKELY
4065 && !(ISA_MIPS32 || ISA_MIPS32R2 || ISA_MIPS64)
4066 && !(TUNE_MIPS5500 || TUNE_SB1))
4067 target_flags |= MASK_BRANCHLIKELY;
4069 target_flags &= ~MASK_BRANCHLIKELY;
4071 if (TARGET_BRANCHLIKELY && !ISA_HAS_BRANCHLIKELY)
4072 warning ("generation of Branch Likely instructions enabled, but not supported by architecture");
4074 /* The effect of -mabicalls isn't defined for the EABI. */
4075 if (mips_abi == ABI_EABI && TARGET_ABICALLS)
4077 error ("unsupported combination: %s", "-mabicalls -mabi=eabi");
4078 target_flags &= ~MASK_ABICALLS;
4081 /* -fpic (-KPIC) is the default when TARGET_ABICALLS is defined. We need
4082 to set flag_pic so that the LEGITIMATE_PIC_OPERAND_P macro will work. */
4083 /* ??? -non_shared turns off pic code generation, but this is not
4085 if (TARGET_ABICALLS)
4088 if (mips_section_threshold > 0)
4089 warning ("-G is incompatible with PIC code which is the default");
4092 /* mips_split_addresses is a half-way house between explicit
4093 relocations and the traditional assembler macros. It can
4094 split absolute 32-bit symbolic constants into a high/lo_sum
4095 pair but uses macros for other sorts of access.
4097 Like explicit relocation support for REL targets, it relies
4098 on GNU extensions in the assembler and the linker.
4100 Although this code should work for -O0, it has traditionally
4101 been treated as an optimization. */
4102 if (!TARGET_MIPS16 && TARGET_SPLIT_ADDRESSES
4103 && optimize && !flag_pic
4104 && !ABI_HAS_64BIT_SYMBOLS)
4105 mips_split_addresses = 1;
4107 mips_split_addresses = 0;
4109 /* -mvr4130-align is a "speed over size" optimization: it usually produces
4110 faster code, but at the expense of more nops. Enable it at -O3 and
4112 if (optimize > 2 && (target_flags_explicit & MASK_VR4130_ALIGN) == 0)
4113 target_flags |= MASK_VR4130_ALIGN;
4115 /* When compiling for the mips16, we cannot use floating point. We
4116 record the original hard float value in mips16_hard_float. */
4119 if (TARGET_SOFT_FLOAT)
4120 mips16_hard_float = 0;
4122 mips16_hard_float = 1;
4123 target_flags |= MASK_SOFT_FLOAT;
4125 /* Don't run the scheduler before reload, since it tends to
4126 increase register pressure. */
4127 flag_schedule_insns = 0;
4129 /* Silently disable -mexplicit-relocs since it doesn't apply
4130 to mips16 code. Even so, it would overly pedantic to warn
4131 about "-mips16 -mexplicit-relocs", especially given that
4132 we use a %gprel() operator. */
4133 target_flags &= ~MASK_EXPLICIT_RELOCS;
4136 /* When using explicit relocs, we call dbr_schedule from within
4138 if (TARGET_EXPLICIT_RELOCS)
4140 mips_flag_delayed_branch = flag_delayed_branch;
4141 flag_delayed_branch = 0;
4144 #ifdef MIPS_TFMODE_FORMAT
4145 REAL_MODE_FORMAT (TFmode) = &MIPS_TFMODE_FORMAT;
4148 /* Make sure that the user didn't turn off paired single support when
4149 MIPS-3D support is requested. */
4150 if (TARGET_MIPS3D && (target_flags_explicit & MASK_PAIRED_SINGLE)
4151 && !TARGET_PAIRED_SINGLE_FLOAT)
4152 error ("-mips3d requires -mpaired-single");
4154 /* If TARGET_MIPS3D, enable MASK_PAIRED_SINGLE. */
4156 target_flags |= MASK_PAIRED_SINGLE;
4158 /* Make sure that when TARGET_PAIRED_SINGLE_FLOAT is true, TARGET_FLOAT64
4159 and TARGET_HARD_FLOAT are both true. */
4160 if (TARGET_PAIRED_SINGLE_FLOAT && !(TARGET_FLOAT64 && TARGET_HARD_FLOAT))
4161 error ("-mips3d/-mpaired-single must be used with -mfp64 -mhard-float");
4163 /* Make sure that the ISA supports TARGET_PAIRED_SINGLE_FLOAT when it is
4165 if (TARGET_PAIRED_SINGLE_FLOAT && !ISA_MIPS64)
4166 error ("-mips3d/-mpaired-single must be used with -mips64");
4168 mips_print_operand_punct['?'] = 1;
4169 mips_print_operand_punct['#'] = 1;
4170 mips_print_operand_punct['/'] = 1;
4171 mips_print_operand_punct['&'] = 1;
4172 mips_print_operand_punct['!'] = 1;
4173 mips_print_operand_punct['*'] = 1;
4174 mips_print_operand_punct['@'] = 1;
4175 mips_print_operand_punct['.'] = 1;
4176 mips_print_operand_punct['('] = 1;
4177 mips_print_operand_punct[')'] = 1;
4178 mips_print_operand_punct['['] = 1;
4179 mips_print_operand_punct[']'] = 1;
4180 mips_print_operand_punct['<'] = 1;
4181 mips_print_operand_punct['>'] = 1;
4182 mips_print_operand_punct['{'] = 1;
4183 mips_print_operand_punct['}'] = 1;
4184 mips_print_operand_punct['^'] = 1;
4185 mips_print_operand_punct['$'] = 1;
4186 mips_print_operand_punct['+'] = 1;
4187 mips_print_operand_punct['~'] = 1;
4189 mips_char_to_class['d'] = TARGET_MIPS16 ? M16_REGS : GR_REGS;
4190 mips_char_to_class['t'] = T_REG;
4191 mips_char_to_class['f'] = (TARGET_HARD_FLOAT ? FP_REGS : NO_REGS);
4192 mips_char_to_class['h'] = HI_REG;
4193 mips_char_to_class['l'] = LO_REG;
4194 mips_char_to_class['x'] = MD_REGS;
4195 mips_char_to_class['b'] = ALL_REGS;
4196 mips_char_to_class['c'] = (TARGET_ABICALLS ? PIC_FN_ADDR_REG :
4197 TARGET_MIPS16 ? M16_NA_REGS :
4199 mips_char_to_class['e'] = LEA_REGS;
4200 mips_char_to_class['j'] = PIC_FN_ADDR_REG;
4201 mips_char_to_class['y'] = GR_REGS;
4202 mips_char_to_class['z'] = ST_REGS;
4203 mips_char_to_class['B'] = COP0_REGS;
4204 mips_char_to_class['C'] = COP2_REGS;
4205 mips_char_to_class['D'] = COP3_REGS;
4207 /* Set up array to map GCC register number to debug register number.
4208 Ignore the special purpose register numbers. */
4210 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
4211 mips_dbx_regno[i] = -1;
4213 start = GP_DBX_FIRST - GP_REG_FIRST;
4214 for (i = GP_REG_FIRST; i <= GP_REG_LAST; i++)
4215 mips_dbx_regno[i] = i + start;
4217 start = FP_DBX_FIRST - FP_REG_FIRST;
4218 for (i = FP_REG_FIRST; i <= FP_REG_LAST; i++)
4219 mips_dbx_regno[i] = i + start;
4221 mips_dbx_regno[HI_REGNUM] = MD_DBX_FIRST + 0;
4222 mips_dbx_regno[LO_REGNUM] = MD_DBX_FIRST + 1;
4224 /* Set up array giving whether a given register can hold a given mode. */
4226 for (mode = VOIDmode;
4227 mode != MAX_MACHINE_MODE;
4228 mode = (enum machine_mode) ((int)mode + 1))
4230 register int size = GET_MODE_SIZE (mode);
4231 register enum mode_class class = GET_MODE_CLASS (mode);
4233 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
4237 if (mode == CCV2mode)
4240 && (regno - ST_REG_FIRST) % 2 == 0);
4242 else if (mode == CCV4mode)
4245 && (regno - ST_REG_FIRST) % 4 == 0);
4247 else if (mode == CCmode)
4250 temp = (regno == FPSW_REGNUM);
4252 temp = (ST_REG_P (regno) || GP_REG_P (regno)
4253 || FP_REG_P (regno));
4256 else if (GP_REG_P (regno))
4257 temp = ((regno & 1) == 0 || size <= UNITS_PER_WORD);
4259 else if (FP_REG_P (regno))
4260 temp = ((regno % FP_INC) == 0)
4261 && (((class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT
4262 || class == MODE_VECTOR_FLOAT)
4263 && size <= UNITS_PER_FPVALUE)
4264 /* Allow integer modes that fit into a single
4265 register. We need to put integers into FPRs
4266 when using instructions like cvt and trunc. */
4267 || (class == MODE_INT && size <= UNITS_PER_FPREG)
4268 /* Allow TFmode for CCmode reloads. */
4269 || (ISA_HAS_8CC && mode == TFmode));
4271 else if (MD_REG_P (regno))
4272 temp = (INTEGRAL_MODE_P (mode)
4273 && (size <= UNITS_PER_WORD
4274 || (regno == MD_REG_FIRST
4275 && size == 2 * UNITS_PER_WORD)));
4277 else if (ALL_COP_REG_P (regno))
4278 temp = (class == MODE_INT && size <= UNITS_PER_WORD);
4282 mips_hard_regno_mode_ok[(int)mode][regno] = temp;
4286 /* Save GPR registers in word_mode sized hunks. word_mode hasn't been
4287 initialized yet, so we can't use that here. */
4288 gpr_mode = TARGET_64BIT ? DImode : SImode;
4290 /* Provide default values for align_* for 64-bit targets. */
4291 if (TARGET_64BIT && !TARGET_MIPS16)
4293 if (align_loops == 0)
4295 if (align_jumps == 0)
4297 if (align_functions == 0)
4298 align_functions = 8;
4301 /* Function to allocate machine-dependent function status. */
4302 init_machine_status = &mips_init_machine_status;
4304 if (ABI_HAS_64BIT_SYMBOLS)
4306 if (TARGET_EXPLICIT_RELOCS)
4308 mips_split_p[SYMBOL_64_HIGH] = true;
4309 mips_hi_relocs[SYMBOL_64_HIGH] = "%highest(";
4310 mips_lo_relocs[SYMBOL_64_HIGH] = "%higher(";
4312 mips_split_p[SYMBOL_64_MID] = true;
4313 mips_hi_relocs[SYMBOL_64_MID] = "%higher(";
4314 mips_lo_relocs[SYMBOL_64_MID] = "%hi(";
4316 mips_split_p[SYMBOL_64_LOW] = true;
4317 mips_hi_relocs[SYMBOL_64_LOW] = "%hi(";
4318 mips_lo_relocs[SYMBOL_64_LOW] = "%lo(";
4320 mips_split_p[SYMBOL_GENERAL] = true;
4321 mips_lo_relocs[SYMBOL_GENERAL] = "%lo(";
4326 if (TARGET_EXPLICIT_RELOCS || mips_split_addresses)
4328 mips_split_p[SYMBOL_GENERAL] = true;
4329 mips_hi_relocs[SYMBOL_GENERAL] = "%hi(";
4330 mips_lo_relocs[SYMBOL_GENERAL] = "%lo(";
4336 /* The high part is provided by a pseudo copy of $gp. */
4337 mips_split_p[SYMBOL_SMALL_DATA] = true;
4338 mips_lo_relocs[SYMBOL_SMALL_DATA] = "%gprel(";
4341 if (TARGET_EXPLICIT_RELOCS)
4343 /* Small data constants are kept whole until after reload,
4344 then lowered by mips_rewrite_small_data. */
4345 mips_lo_relocs[SYMBOL_SMALL_DATA] = "%gp_rel(";
4347 mips_split_p[SYMBOL_GOT_LOCAL] = true;
4350 mips_lo_relocs[SYMBOL_GOTOFF_PAGE] = "%got_page(";
4351 mips_lo_relocs[SYMBOL_GOT_LOCAL] = "%got_ofst(";
4355 mips_lo_relocs[SYMBOL_GOTOFF_PAGE] = "%got(";
4356 mips_lo_relocs[SYMBOL_GOT_LOCAL] = "%lo(";
4361 /* The HIGH and LO_SUM are matched by special .md patterns. */
4362 mips_split_p[SYMBOL_GOT_GLOBAL] = true;
4364 mips_split_p[SYMBOL_GOTOFF_GLOBAL] = true;
4365 mips_hi_relocs[SYMBOL_GOTOFF_GLOBAL] = "%got_hi(";
4366 mips_lo_relocs[SYMBOL_GOTOFF_GLOBAL] = "%got_lo(";
4368 mips_split_p[SYMBOL_GOTOFF_CALL] = true;
4369 mips_hi_relocs[SYMBOL_GOTOFF_CALL] = "%call_hi(";
4370 mips_lo_relocs[SYMBOL_GOTOFF_CALL] = "%call_lo(";
4375 mips_lo_relocs[SYMBOL_GOTOFF_GLOBAL] = "%got_disp(";
4377 mips_lo_relocs[SYMBOL_GOTOFF_GLOBAL] = "%got(";
4378 mips_lo_relocs[SYMBOL_GOTOFF_CALL] = "%call16(";
4384 mips_split_p[SYMBOL_GOTOFF_LOADGP] = true;
4385 mips_hi_relocs[SYMBOL_GOTOFF_LOADGP] = "%hi(%neg(%gp_rel(";
4386 mips_lo_relocs[SYMBOL_GOTOFF_LOADGP] = "%lo(%neg(%gp_rel(";
4389 /* Default to working around R4000 errata only if the processor
4390 was selected explicitly. */
4391 if ((target_flags_explicit & MASK_FIX_R4000) == 0
4392 && mips_matching_cpu_name_p (mips_arch_info->name, "r4000"))
4393 target_flags |= MASK_FIX_R4000;
4395 /* Default to working around R4400 errata only if the processor
4396 was selected explicitly. */
4397 if ((target_flags_explicit & MASK_FIX_R4400) == 0
4398 && mips_matching_cpu_name_p (mips_arch_info->name, "r4400"))
4399 target_flags |= MASK_FIX_R4400;
4402 /* Implement CONDITIONAL_REGISTER_USAGE. */
4405 mips_conditional_register_usage (void)
4407 if (!TARGET_HARD_FLOAT)
4411 for (regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
4412 fixed_regs[regno] = call_used_regs[regno] = 1;
4413 for (regno = ST_REG_FIRST; regno <= ST_REG_LAST; regno++)
4414 fixed_regs[regno] = call_used_regs[regno] = 1;
4416 else if (! ISA_HAS_8CC)
4420 /* We only have a single condition code register. We
4421 implement this by hiding all the condition code registers,
4422 and generating RTL that refers directly to ST_REG_FIRST. */
4423 for (regno = ST_REG_FIRST; regno <= ST_REG_LAST; regno++)
4424 fixed_regs[regno] = call_used_regs[regno] = 1;
4426 /* In mips16 mode, we permit the $t temporary registers to be used
4427 for reload. We prohibit the unused $s registers, since they
4428 are caller saved, and saving them via a mips16 register would
4429 probably waste more time than just reloading the value. */
4432 fixed_regs[18] = call_used_regs[18] = 1;
4433 fixed_regs[19] = call_used_regs[19] = 1;
4434 fixed_regs[20] = call_used_regs[20] = 1;
4435 fixed_regs[21] = call_used_regs[21] = 1;
4436 fixed_regs[22] = call_used_regs[22] = 1;
4437 fixed_regs[23] = call_used_regs[23] = 1;
4438 fixed_regs[26] = call_used_regs[26] = 1;
4439 fixed_regs[27] = call_used_regs[27] = 1;
4440 fixed_regs[30] = call_used_regs[30] = 1;
4442 /* fp20-23 are now caller saved. */
4443 if (mips_abi == ABI_64)
4446 for (regno = FP_REG_FIRST + 20; regno < FP_REG_FIRST + 24; regno++)
4447 call_really_used_regs[regno] = call_used_regs[regno] = 1;
4449 /* Odd registers from fp21 to fp31 are now caller saved. */
4450 if (mips_abi == ABI_N32)
4453 for (regno = FP_REG_FIRST + 21; regno <= FP_REG_FIRST + 31; regno+=2)
4454 call_really_used_regs[regno] = call_used_regs[regno] = 1;
4458 /* Allocate a chunk of memory for per-function machine-dependent data. */
4459 static struct machine_function *
4460 mips_init_machine_status (void)
4462 return ((struct machine_function *)
4463 ggc_alloc_cleared (sizeof (struct machine_function)));
4466 /* On the mips16, we want to allocate $24 (T_REG) before other
4467 registers for instructions for which it is possible. This helps
4468 avoid shuffling registers around in order to set up for an xor,
4469 encouraging the compiler to use a cmp instead. */
4472 mips_order_regs_for_local_alloc (void)
4476 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
4477 reg_alloc_order[i] = i;
4481 /* It really doesn't matter where we put register 0, since it is
4482 a fixed register anyhow. */
4483 reg_alloc_order[0] = 24;
4484 reg_alloc_order[24] = 0;
4489 /* The MIPS debug format wants all automatic variables and arguments
4490 to be in terms of the virtual frame pointer (stack pointer before
4491 any adjustment in the function), while the MIPS 3.0 linker wants
4492 the frame pointer to be the stack pointer after the initial
4493 adjustment. So, we do the adjustment here. The arg pointer (which
4494 is eliminated) points to the virtual frame pointer, while the frame
4495 pointer (which may be eliminated) points to the stack pointer after
4496 the initial adjustments. */
4499 mips_debugger_offset (rtx addr, HOST_WIDE_INT offset)
4501 rtx offset2 = const0_rtx;
4502 rtx reg = eliminate_constant_term (addr, &offset2);
4505 offset = INTVAL (offset2);
4507 if (reg == stack_pointer_rtx || reg == frame_pointer_rtx
4508 || reg == hard_frame_pointer_rtx)
4510 HOST_WIDE_INT frame_size = (!cfun->machine->frame.initialized)
4511 ? compute_frame_size (get_frame_size ())
4512 : cfun->machine->frame.total_size;
4514 /* MIPS16 frame is smaller */
4515 if (frame_pointer_needed && TARGET_MIPS16)
4516 frame_size -= cfun->machine->frame.args_size;
4518 offset = offset - frame_size;
4521 /* sdbout_parms does not want this to crash for unrecognized cases. */
4523 else if (reg != arg_pointer_rtx)
4524 fatal_insn ("mips_debugger_offset called with non stack/frame/arg pointer",
4531 /* A helper function for print_operand. This prints out a floating point
4532 condition code register. OP is the operand we are printing. CODE is the
4533 rtx code of OP. ALIGN is the required register alignment for OP. OFFSET
4534 is the index into operand for multiple register operands. If IGNORE is
4535 true, then we only print the register name if it isn't fcc0, and we
4536 follow it with a comma. */
4539 print_fcc_operand (FILE *file, rtx op, enum rtx_code code,
4540 int align, int offset, int ignore)
4547 regnum = REGNO (op);
4548 if (!ST_REG_P (regnum)
4549 || (regnum - ST_REG_FIRST) % align != 0)
4552 if (!ignore || regnum != ST_REG_FIRST)
4553 fprintf (file, "%s%s", reg_names[regnum+offset], (ignore ? "," : ""));
4556 /* Implement the PRINT_OPERAND macro. The MIPS-specific operand codes are:
4558 'X' OP is CONST_INT, prints 32 bits in hexadecimal format = "0x%08x",
4559 'x' OP is CONST_INT, prints 16 bits in hexadecimal format = "0x%04x",
4560 'h' OP is HIGH, prints %hi(X),
4561 'd' output integer constant in decimal,
4562 'z' if the operand is 0, use $0 instead of normal operand.
4563 'D' print second part of double-word register or memory operand.
4564 'L' print low-order register of double-word register operand.
4565 'M' print high-order register of double-word register operand.
4566 'C' print part of opcode for a branch condition.
4567 'F' print part of opcode for a floating-point branch condition.
4568 'N' print part of opcode for a branch condition, inverted.
4569 'W' print part of opcode for a floating-point branch condition, inverted.
4570 'T' print 'f' for (eq:CC ...), 't' for (ne:CC ...),
4571 'z' for (eq:?I ...), 'n' for (ne:?I ...).
4572 't' like 'T', but with the EQ/NE cases reversed
4573 'Z' print register and a comma, but print nothing for $fcc0
4574 'R' print the reloc associated with LO_SUM
4575 'V' Check if the fcc register number divided by 4 is zero. Then print
4576 the fcc register plus 2.
4577 'v' Check if the fcc register number divided by 4 is zero. Then print
4579 'Q' print the fcc register.
4581 The punctuation characters are:
4583 '(' Turn on .set noreorder
4584 ')' Turn on .set reorder
4585 '[' Turn on .set noat
4587 '<' Turn on .set nomacro
4588 '>' Turn on .set macro
4589 '{' Turn on .set volatile (not GAS)
4590 '}' Turn on .set novolatile (not GAS)
4591 '&' Turn on .set noreorder if filling delay slots
4592 '*' Turn on both .set noreorder and .set nomacro if filling delay slots
4593 '!' Turn on .set nomacro if filling delay slots
4594 '#' Print nop if in a .set noreorder section.
4595 '/' Like '#', but does nothing within a delayed branch sequence
4596 '?' Print 'l' if we are to use a branch likely instead of normal branch.
4597 '@' Print the name of the assembler temporary register (at or $1).
4598 '.' Print the name of the register with a hard-wired zero (zero or $0).
4599 '^' Print the name of the pic call-through register (t9 or $25).
4600 '$' Print the name of the stack pointer register (sp or $29).
4601 '+' Print the name of the gp register (usually gp or $28).
4602 '~' Output a branch alignment to LABEL_ALIGN(NULL). */
4605 print_operand (FILE *file, rtx op, int letter)
4607 register enum rtx_code code;
4609 if (PRINT_OPERAND_PUNCT_VALID_P (letter))
4614 if (mips_branch_likely)
4619 fputs (reg_names [GP_REG_FIRST + 1], file);
4623 fputs (reg_names [PIC_FUNCTION_ADDR_REGNUM], file);
4627 fputs (reg_names [GP_REG_FIRST + 0], file);
4631 fputs (reg_names[STACK_POINTER_REGNUM], file);
4635 fputs (reg_names[PIC_OFFSET_TABLE_REGNUM], file);
4639 if (final_sequence != 0 && set_noreorder++ == 0)
4640 fputs (".set\tnoreorder\n\t", file);
4644 if (final_sequence != 0)
4646 if (set_noreorder++ == 0)
4647 fputs (".set\tnoreorder\n\t", file);
4649 if (set_nomacro++ == 0)
4650 fputs (".set\tnomacro\n\t", file);
4655 if (final_sequence != 0 && set_nomacro++ == 0)
4656 fputs ("\n\t.set\tnomacro", file);
4660 if (set_noreorder != 0)
4661 fputs ("\n\tnop", file);
4665 /* Print an extra newline so that the delayed insn is separated
4666 from the following ones. This looks neater and is consistent
4667 with non-nop delayed sequences. */
4668 if (set_noreorder != 0 && final_sequence == 0)
4669 fputs ("\n\tnop\n", file);
4673 if (set_noreorder++ == 0)
4674 fputs (".set\tnoreorder\n\t", file);
4678 if (set_noreorder == 0)
4679 error ("internal error: %%) found without a %%( in assembler pattern");
4681 else if (--set_noreorder == 0)
4682 fputs ("\n\t.set\treorder", file);
4687 if (set_noat++ == 0)
4688 fputs (".set\tnoat\n\t", file);
4693 error ("internal error: %%] found without a %%[ in assembler pattern");
4694 else if (--set_noat == 0)
4695 fputs ("\n\t.set\tat", file);
4700 if (set_nomacro++ == 0)
4701 fputs (".set\tnomacro\n\t", file);
4705 if (set_nomacro == 0)
4706 error ("internal error: %%> found without a %%< in assembler pattern");
4707 else if (--set_nomacro == 0)
4708 fputs ("\n\t.set\tmacro", file);
4713 if (set_volatile++ == 0)
4714 fputs ("#.set\tvolatile\n\t", file);
4718 if (set_volatile == 0)
4719 error ("internal error: %%} found without a %%{ in assembler pattern");
4720 else if (--set_volatile == 0)
4721 fputs ("\n\t#.set\tnovolatile", file);
4727 if (align_labels_log > 0)
4728 ASM_OUTPUT_ALIGN (file, align_labels_log);
4733 error ("PRINT_OPERAND: unknown punctuation '%c'", letter);
4742 error ("PRINT_OPERAND null pointer");
4746 code = GET_CODE (op);
4751 case EQ: fputs ("eq", file); break;
4752 case NE: fputs ("ne", file); break;
4753 case GT: fputs ("gt", file); break;
4754 case GE: fputs ("ge", file); break;
4755 case LT: fputs ("lt", file); break;
4756 case LE: fputs ("le", file); break;
4757 case GTU: fputs ("gtu", file); break;
4758 case GEU: fputs ("geu", file); break;
4759 case LTU: fputs ("ltu", file); break;
4760 case LEU: fputs ("leu", file); break;
4762 fatal_insn ("PRINT_OPERAND, invalid insn for %%C", op);
4765 else if (letter == 'N')
4768 case EQ: fputs ("ne", file); break;
4769 case NE: fputs ("eq", file); break;
4770 case GT: fputs ("le", file); break;
4771 case GE: fputs ("lt", file); break;
4772 case LT: fputs ("ge", file); break;
4773 case LE: fputs ("gt", file); break;
4774 case GTU: fputs ("leu", file); break;
4775 case GEU: fputs ("ltu", file); break;
4776 case LTU: fputs ("geu", file); break;
4777 case LEU: fputs ("gtu", file); break;
4779 fatal_insn ("PRINT_OPERAND, invalid insn for %%N", op);
4782 else if (letter == 'F')
4785 case EQ: fputs ("c1f", file); break;
4786 case NE: fputs ("c1t", file); break;
4788 fatal_insn ("PRINT_OPERAND, invalid insn for %%F", op);
4791 else if (letter == 'W')
4794 case EQ: fputs ("c1t", file); break;
4795 case NE: fputs ("c1f", file); break;
4797 fatal_insn ("PRINT_OPERAND, invalid insn for %%W", op);
4800 else if (letter == 'h')
4802 if (GET_CODE (op) == HIGH)
4805 print_operand_reloc (file, op, mips_hi_relocs);
4808 else if (letter == 'R')
4809 print_operand_reloc (file, op, mips_lo_relocs);
4811 else if (letter == 'Z')
4812 print_fcc_operand (file, op, code, 1, 0, 1);
4814 else if (letter == 'V')
4815 print_fcc_operand (file, op, code, 4, 2, 0);
4817 else if (letter == 'v')
4818 print_fcc_operand (file, op, code, 4, 0, 0);
4820 else if (letter == 'Q')
4821 print_fcc_operand (file, op, code, 1, 0, 0);
4823 else if (code == REG || code == SUBREG)
4825 register int regnum;
4828 regnum = REGNO (op);
4830 regnum = true_regnum (op);
4832 if ((letter == 'M' && ! WORDS_BIG_ENDIAN)
4833 || (letter == 'L' && WORDS_BIG_ENDIAN)
4837 fprintf (file, "%s", reg_names[regnum]);
4840 else if (code == MEM)
4843 output_address (plus_constant (XEXP (op, 0), 4));
4845 output_address (XEXP (op, 0));
4848 else if (letter == 'x' && GET_CODE (op) == CONST_INT)
4849 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & INTVAL(op));
4851 else if (letter == 'X' && GET_CODE(op) == CONST_INT)
4852 fprintf (file, HOST_WIDE_INT_PRINT_HEX, INTVAL (op));
4854 else if (letter == 'd' && GET_CODE(op) == CONST_INT)
4855 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (INTVAL(op)));
4857 else if (letter == 'z' && op == CONST0_RTX (GET_MODE (op)))
4858 fputs (reg_names[GP_REG_FIRST], file);
4860 else if (letter == 'd' || letter == 'x' || letter == 'X')
4861 output_operand_lossage ("invalid use of %%d, %%x, or %%X");
4863 else if (letter == 'T' || letter == 't')
4865 int truth = (code == NE) == (letter == 'T');
4866 fputc ("zfnt"[truth * 2 + (GET_MODE (op) == CCmode)], file);
4869 else if (CONST_GP_P (op))
4870 fputs (reg_names[GLOBAL_POINTER_REGNUM], file);
4873 output_addr_const (file, op);
4877 /* Print symbolic operand OP, which is part of a HIGH or LO_SUM.
4878 RELOCS is the array of relocations to use. */
4881 print_operand_reloc (FILE *file, rtx op, const char **relocs)
4883 enum mips_symbol_type symbol_type;
4886 HOST_WIDE_INT offset;
4888 if (!mips_symbolic_constant_p (op, &symbol_type) || relocs[symbol_type] == 0)
4889 fatal_insn ("PRINT_OPERAND, invalid operand for relocation", op);
4891 /* If OP uses an UNSPEC address, we want to print the inner symbol. */
4892 mips_split_const (op, &base, &offset);
4893 if (UNSPEC_ADDRESS_P (base))
4894 op = plus_constant (UNSPEC_ADDRESS (base), offset);
4896 fputs (relocs[symbol_type], file);
4897 output_addr_const (file, op);
4898 for (p = relocs[symbol_type]; *p != 0; p++)
4903 /* Output address operand X to FILE. */
4906 print_operand_address (FILE *file, rtx x)
4908 struct mips_address_info addr;
4910 if (mips_classify_address (&addr, x, word_mode, true))
4914 print_operand (file, addr.offset, 0);
4915 fprintf (file, "(%s)", reg_names[REGNO (addr.reg)]);
4918 case ADDRESS_LO_SUM:
4919 print_operand (file, addr.offset, 'R');
4920 fprintf (file, "(%s)", reg_names[REGNO (addr.reg)]);
4923 case ADDRESS_CONST_INT:
4924 output_addr_const (file, x);
4925 fprintf (file, "(%s)", reg_names[0]);
4928 case ADDRESS_SYMBOLIC:
4929 output_addr_const (file, x);
4935 /* When using assembler macros, keep track of all of small-data externs
4936 so that mips_file_end can emit the appropriate declarations for them.
4938 In most cases it would be safe (though pointless) to emit .externs
4939 for other symbols too. One exception is when an object is within
4940 the -G limit but declared by the user to be in a section other
4941 than .sbss or .sdata. */
4944 mips_output_external (FILE *file ATTRIBUTE_UNUSED, tree decl, const char *name)
4946 register struct extern_list *p;
4948 if (!TARGET_EXPLICIT_RELOCS && mips_in_small_data_p (decl))
4950 p = (struct extern_list *) ggc_alloc (sizeof (struct extern_list));
4951 p->next = extern_head;
4953 p->size = int_size_in_bytes (TREE_TYPE (decl));
4957 if (TARGET_IRIX && mips_abi == ABI_32 && TREE_CODE (decl) == FUNCTION_DECL)
4959 p = (struct extern_list *) ggc_alloc (sizeof (struct extern_list));
4960 p->next = extern_head;
4971 irix_output_external_libcall (rtx fun)
4973 register struct extern_list *p;
4975 if (mips_abi == ABI_32)
4977 p = (struct extern_list *) ggc_alloc (sizeof (struct extern_list));
4978 p->next = extern_head;
4979 p->name = XSTR (fun, 0);
4986 /* Emit a new filename to a stream. If we are smuggling stabs, try to
4987 put out a MIPS ECOFF file and a stab. */
4990 mips_output_filename (FILE *stream, const char *name)
4992 char ltext_label_name[100];
4994 /* If we are emitting DWARF-2, let dwarf2out handle the ".file"
4996 if (write_symbols == DWARF2_DEBUG)
4998 else if (mips_output_filename_first_time)
5000 mips_output_filename_first_time = 0;
5001 num_source_filenames += 1;
5002 current_function_file = name;
5003 ASM_OUTPUT_FILENAME (stream, num_source_filenames, name);
5006 else if (write_symbols == DBX_DEBUG)
5008 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
5009 fputs ("\t.stabs\t", stream);
5010 output_quoted_string (stream, name);
5011 fprintf (stream, ",%d,0,0,%s\n", N_SOL, <ext_label_name[1]);
5014 else if (name != current_function_file
5015 && strcmp (name, current_function_file) != 0)
5017 num_source_filenames += 1;
5018 current_function_file = name;
5019 ASM_OUTPUT_FILENAME (stream, num_source_filenames, name);
5023 /* Emit a linenumber. For encapsulated stabs, we need to put out a stab
5024 as well as a .loc, since it is possible that MIPS ECOFF might not be
5025 able to represent the location for inlines that come from a different
5029 mips_output_lineno (FILE *stream, int line)
5031 if (write_symbols == DBX_DEBUG)
5034 fprintf (stream, "%sLM%d:\n\t.stabn\t%d,0,%d,%sLM%d\n",
5035 LOCAL_LABEL_PREFIX, sym_lineno, N_SLINE, line,
5036 LOCAL_LABEL_PREFIX, sym_lineno);
5040 fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line);
5044 /* Output an ASCII string, in a space-saving way. PREFIX is the string
5045 that should be written before the opening quote, such as "\t.ascii\t"
5046 for real string data or "\t# " for a comment. */
5049 mips_output_ascii (FILE *stream, const char *string_param, size_t len,
5054 register const unsigned char *string =
5055 (const unsigned char *)string_param;
5057 fprintf (stream, "%s\"", prefix);
5058 for (i = 0; i < len; i++)
5060 register int c = string[i];
5066 putc ('\\', stream);
5071 case TARGET_NEWLINE:
5072 fputs ("\\n", stream);
5074 && (((c = string[i+1]) >= '\040' && c <= '~')
5075 || c == TARGET_TAB))
5076 cur_pos = 32767; /* break right here */
5082 fputs ("\\t", stream);
5087 fputs ("\\f", stream);
5092 fputs ("\\b", stream);
5097 fputs ("\\r", stream);
5102 if (c >= ' ' && c < 0177)
5109 fprintf (stream, "\\%03o", c);
5114 if (cur_pos > 72 && i+1 < len)
5117 fprintf (stream, "\"\n%s\"", prefix);
5120 fprintf (stream, "\"\n");
5123 /* Implement TARGET_ASM_FILE_START. */
5126 mips_file_start (void)
5128 default_file_start ();
5132 /* Generate a special section to describe the ABI switches used to
5133 produce the resultant binary. This used to be done by the assembler
5134 setting bits in the ELF header's flags field, but we have run out of
5135 bits. GDB needs this information in order to be able to correctly
5136 debug these binaries. See the function mips_gdbarch_init() in
5137 gdb/mips-tdep.c. This is unnecessary for the IRIX 5/6 ABIs and
5138 causes unnecessary IRIX 6 ld warnings. */
5139 const char * abi_string = NULL;
5143 case ABI_32: abi_string = "abi32"; break;
5144 case ABI_N32: abi_string = "abiN32"; break;
5145 case ABI_64: abi_string = "abi64"; break;
5146 case ABI_O64: abi_string = "abiO64"; break;
5147 case ABI_EABI: abi_string = TARGET_64BIT ? "eabi64" : "eabi32"; break;
5151 /* Note - we use fprintf directly rather than called named_section()
5152 because in this way we can avoid creating an allocated section. We
5153 do not want this section to take up any space in the running
5155 fprintf (asm_out_file, "\t.section .mdebug.%s\n", abi_string);
5157 /* There is no ELF header flag to distinguish long32 forms of the
5158 EABI from long64 forms. Emit a special section to help tools
5160 if (mips_abi == ABI_EABI)
5161 fprintf (asm_out_file, "\t.section .gcc_compiled_long%d\n",
5162 TARGET_LONG64 ? 64 : 32);
5164 /* Restore the default section. */
5165 fprintf (asm_out_file, "\t.previous\n");
5168 /* Generate the pseudo ops that System V.4 wants. */
5169 if (TARGET_ABICALLS)
5170 /* ??? but do not want this (or want pic0) if -non-shared? */
5171 fprintf (asm_out_file, "\t.abicalls\n");
5174 fprintf (asm_out_file, "\t.set\tmips16\n");
5176 if (flag_verbose_asm)
5177 fprintf (asm_out_file, "\n%s -G value = %d, Arch = %s, ISA = %d\n",
5179 mips_section_threshold, mips_arch_info->name, mips_isa);
5182 #ifdef BSS_SECTION_ASM_OP
5183 /* Implement ASM_OUTPUT_ALIGNED_BSS. This differs from the default only
5184 in the use of sbss. */
5187 mips_output_aligned_bss (FILE *stream, tree decl, const char *name,
5188 unsigned HOST_WIDE_INT size, int align)
5190 extern tree last_assemble_variable_decl;
5192 if (mips_in_small_data_p (decl))
5193 named_section (0, ".sbss", 0);
5196 ASM_OUTPUT_ALIGN (stream, floor_log2 (align / BITS_PER_UNIT));
5197 last_assemble_variable_decl = decl;
5198 ASM_DECLARE_OBJECT_NAME (stream, name, decl);
5199 ASM_OUTPUT_SKIP (stream, size != 0 ? size : 1);
5203 /* Implement TARGET_ASM_FILE_END. When using assembler macros, emit
5204 .externs for any small-data variables that turned out to be external. */
5207 mips_file_end (void)
5210 struct extern_list *p;
5214 fputs ("\n", asm_out_file);
5216 for (p = extern_head; p != 0; p = p->next)
5218 name_tree = get_identifier (p->name);
5220 /* Positively ensure only one .extern for any given symbol. */
5221 if (!TREE_ASM_WRITTEN (name_tree)
5222 && TREE_SYMBOL_REFERENCED (name_tree))
5224 TREE_ASM_WRITTEN (name_tree) = 1;
5225 /* In IRIX 5 or IRIX 6 for the O32 ABI, we must output a
5226 `.global name .text' directive for every used but
5227 undefined function. If we don't, the linker may perform
5228 an optimization (skipping over the insns that set $gp)
5229 when it is unsafe. */
5230 if (TARGET_IRIX && mips_abi == ABI_32 && p->size == -1)
5232 fputs ("\t.globl ", asm_out_file);
5233 assemble_name (asm_out_file, p->name);
5234 fputs (" .text\n", asm_out_file);
5238 fputs ("\t.extern\t", asm_out_file);
5239 assemble_name (asm_out_file, p->name);
5240 fprintf (asm_out_file, ", %d\n", p->size);
5247 /* Implement ASM_OUTPUT_ALIGNED_DECL_COMMON. This is usually the same as the
5248 elfos.h version, but we also need to handle -muninit-const-in-rodata. */
5251 mips_output_aligned_decl_common (FILE *stream, tree decl, const char *name,
5252 unsigned HOST_WIDE_INT size,
5255 /* If the target wants uninitialized const declarations in
5256 .rdata then don't put them in .comm. */
5257 if (TARGET_EMBEDDED_DATA && TARGET_UNINIT_CONST_IN_RODATA
5258 && TREE_CODE (decl) == VAR_DECL && TREE_READONLY (decl)
5259 && (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node))
5261 if (TREE_PUBLIC (decl) && DECL_NAME (decl))
5262 targetm.asm_out.globalize_label (stream, name);
5264 readonly_data_section ();
5265 ASM_OUTPUT_ALIGN (stream, floor_log2 (align / BITS_PER_UNIT));
5266 mips_declare_object (stream, name, "",
5267 ":\n\t.space\t" HOST_WIDE_INT_PRINT_UNSIGNED "\n",
5271 mips_declare_common_object (stream, name, "\n\t.comm\t",
5275 /* Declare a common object of SIZE bytes using asm directive INIT_STRING.
5276 NAME is the name of the object and ALIGN is the required alignment
5277 in bytes. TAKES_ALIGNMENT_P is true if the directive takes a third
5278 alignment argument. */
5281 mips_declare_common_object (FILE *stream, const char *name,
5282 const char *init_string,
5283 unsigned HOST_WIDE_INT size,
5284 unsigned int align, bool takes_alignment_p)
5286 if (!takes_alignment_p)
5288 size += (align / BITS_PER_UNIT) - 1;
5289 size -= size % (align / BITS_PER_UNIT);
5290 mips_declare_object (stream, name, init_string,
5291 "," HOST_WIDE_INT_PRINT_UNSIGNED "\n", size);
5294 mips_declare_object (stream, name, init_string,
5295 "," HOST_WIDE_INT_PRINT_UNSIGNED ",%u\n",
5296 size, align / BITS_PER_UNIT);
5299 /* Emit either a label, .comm, or .lcomm directive. When using assembler
5300 macros, mark the symbol as written so that mips_file_end won't emit an
5301 .extern for it. STREAM is the output file, NAME is the name of the
5302 symbol, INIT_STRING is the string that should be written before the
5303 symbol and FINAL_STRING is the string that should be written after it.
5304 FINAL_STRING is a printf() format that consumes the remaining arguments. */
5307 mips_declare_object (FILE *stream, const char *name, const char *init_string,
5308 const char *final_string, ...)
5312 fputs (init_string, stream);
5313 assemble_name (stream, name);
5314 va_start (ap, final_string);
5315 vfprintf (stream, final_string, ap);
5318 if (!TARGET_EXPLICIT_RELOCS)
5320 tree name_tree = get_identifier (name);
5321 TREE_ASM_WRITTEN (name_tree) = 1;
5325 #ifdef ASM_OUTPUT_SIZE_DIRECTIVE
5326 extern int size_directive_output;
5328 /* Implement ASM_DECLARE_OBJECT_NAME. This is like most of the standard ELF
5329 definitions except that it uses mips_declare_object() to emit the label. */
5332 mips_declare_object_name (FILE *stream, const char *name,
5333 tree decl ATTRIBUTE_UNUSED)
5335 #ifdef ASM_OUTPUT_TYPE_DIRECTIVE
5336 ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "object");
5339 size_directive_output = 0;
5340 if (!flag_inhibit_size_directive && DECL_SIZE (decl))
5344 size_directive_output = 1;
5345 size = int_size_in_bytes (TREE_TYPE (decl));
5346 ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
5349 mips_declare_object (stream, name, "", ":\n", 0);
5352 /* Implement ASM_FINISH_DECLARE_OBJECT. This is generic ELF stuff. */
5355 mips_finish_declare_object (FILE *stream, tree decl, int top_level, int at_end)
5359 name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
5360 if (!flag_inhibit_size_directive
5361 && DECL_SIZE (decl) != 0
5362 && !at_end && top_level
5363 && DECL_INITIAL (decl) == error_mark_node
5364 && !size_directive_output)
5368 size_directive_output = 1;
5369 size = int_size_in_bytes (TREE_TYPE (decl));
5370 ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
5375 /* Return true if X is a small data address that can be rewritten
5379 mips_rewrite_small_data_p (rtx x)
5381 enum mips_symbol_type symbol_type;
5383 return (TARGET_EXPLICIT_RELOCS
5384 && mips_symbolic_constant_p (x, &symbol_type)
5385 && symbol_type == SYMBOL_SMALL_DATA);
5389 /* A for_each_rtx callback for mips_small_data_pattern_p. */
5392 mips_small_data_pattern_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
5394 if (GET_CODE (*loc) == LO_SUM)
5397 return mips_rewrite_small_data_p (*loc);
5400 /* Return true if OP refers to small data symbols directly, not through
5404 mips_small_data_pattern_p (rtx op)
5406 return for_each_rtx (&op, mips_small_data_pattern_1, 0);
5409 /* A for_each_rtx callback, used by mips_rewrite_small_data. */
5412 mips_rewrite_small_data_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
5414 if (mips_rewrite_small_data_p (*loc))
5415 *loc = gen_rtx_LO_SUM (Pmode, pic_offset_table_rtx, *loc);
5417 if (GET_CODE (*loc) == LO_SUM)
5423 /* If possible, rewrite OP so that it refers to small data using
5424 explicit relocations. */
5427 mips_rewrite_small_data (rtx op)
5429 op = copy_insn (op);
5430 for_each_rtx (&op, mips_rewrite_small_data_1, 0);
5434 /* Return true if the current function has an insn that implicitly
5438 mips_function_has_gp_insn (void)
5440 /* Don't bother rechecking if we found one last time. */
5441 if (!cfun->machine->has_gp_insn_p)
5445 push_topmost_sequence ();
5446 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5448 && GET_CODE (PATTERN (insn)) != USE
5449 && GET_CODE (PATTERN (insn)) != CLOBBER
5450 && (get_attr_got (insn) != GOT_UNSET
5451 || small_data_pattern (PATTERN (insn), VOIDmode)))
5453 pop_topmost_sequence ();
5455 cfun->machine->has_gp_insn_p = (insn != 0);
5457 return cfun->machine->has_gp_insn_p;
5461 /* Return the register that should be used as the global pointer
5462 within this function. Return 0 if the function doesn't need
5463 a global pointer. */
5466 mips_global_pointer (void)
5470 /* $gp is always available in non-abicalls code. */
5471 if (!TARGET_ABICALLS)
5472 return GLOBAL_POINTER_REGNUM;
5474 /* We must always provide $gp when it is used implicitly. */
5475 if (!TARGET_EXPLICIT_RELOCS)
5476 return GLOBAL_POINTER_REGNUM;
5478 /* FUNCTION_PROFILER includes a jal macro, so we need to give it
5480 if (current_function_profile)
5481 return GLOBAL_POINTER_REGNUM;
5483 /* If the function has a nonlocal goto, $gp must hold the correct
5484 global pointer for the target function. */
5485 if (current_function_has_nonlocal_goto)
5486 return GLOBAL_POINTER_REGNUM;
5488 /* If the gp is never referenced, there's no need to initialize it.
5489 Note that reload can sometimes introduce constant pool references
5490 into a function that otherwise didn't need them. For example,
5491 suppose we have an instruction like:
5493 (set (reg:DF R1) (float:DF (reg:SI R2)))
5495 If R2 turns out to be constant such as 1, the instruction may have a
5496 REG_EQUAL note saying that R1 == 1.0. Reload then has the option of
5497 using this constant if R2 doesn't get allocated to a register.
5499 In cases like these, reload will have added the constant to the pool
5500 but no instruction will yet refer to it. */
5501 if (!regs_ever_live[GLOBAL_POINTER_REGNUM]
5502 && !current_function_uses_const_pool
5503 && !mips_function_has_gp_insn ())
5506 /* We need a global pointer, but perhaps we can use a call-clobbered
5507 register instead of $gp. */
5508 if (TARGET_NEWABI && current_function_is_leaf)
5509 for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
5510 if (!regs_ever_live[regno]
5511 && call_used_regs[regno]
5512 && !fixed_regs[regno]
5513 && regno != PIC_FUNCTION_ADDR_REGNUM)
5516 return GLOBAL_POINTER_REGNUM;
5520 /* Return true if the current function must save REGNO. */
5523 mips_save_reg_p (unsigned int regno)
5525 /* We only need to save $gp for NewABI PIC. */
5526 if (regno == GLOBAL_POINTER_REGNUM)
5527 return (TARGET_ABICALLS && TARGET_NEWABI
5528 && cfun->machine->global_pointer == regno);
5530 /* Check call-saved registers. */
5531 if (regs_ever_live[regno] && !call_used_regs[regno])
5534 /* We need to save the old frame pointer before setting up a new one. */
5535 if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
5538 /* We need to save the incoming return address if it is ever clobbered
5539 within the function. */
5540 if (regno == GP_REG_FIRST + 31 && regs_ever_live[regno])
5547 return_type = DECL_RESULT (current_function_decl);
5549 /* $18 is a special case in mips16 code. It may be used to call
5550 a function which returns a floating point value, but it is
5551 marked in call_used_regs. */
5552 if (regno == GP_REG_FIRST + 18 && regs_ever_live[regno])
5555 /* $31 is also a special case. It will be used to copy a return
5556 value into the floating point registers if the return value is
5558 if (regno == GP_REG_FIRST + 31
5559 && mips16_hard_float
5560 && !aggregate_value_p (return_type, current_function_decl)
5561 && GET_MODE_CLASS (DECL_MODE (return_type)) == MODE_FLOAT
5562 && GET_MODE_SIZE (DECL_MODE (return_type)) <= UNITS_PER_FPVALUE)
5570 /* Return the bytes needed to compute the frame pointer from the current
5571 stack pointer. SIZE is the size (in bytes) of the local variables.
5573 Mips stack frames look like:
5575 Before call After call
5576 +-----------------------+ +-----------------------+
5579 | caller's temps. | | caller's temps. |
5581 +-----------------------+ +-----------------------+
5583 | arguments on stack. | | arguments on stack. |
5585 +-----------------------+ +-----------------------+
5586 | 4 words to save | | 4 words to save |
5587 | arguments passed | | arguments passed |
5588 | in registers, even | | in registers, even |
5589 SP->| if not passed. | VFP->| if not passed. |
5590 +-----------------------+ +-----------------------+
5592 | fp register save |
5594 +-----------------------+
5596 | gp register save |
5598 +-----------------------+
5602 +-----------------------+
5604 | alloca allocations |
5606 +-----------------------+
5608 | GP save for V.4 abi |
5610 +-----------------------+
5612 | arguments on stack |
5614 +-----------------------+
5616 | arguments passed |
5617 | in registers, even |
5618 low SP->| if not passed. |
5619 memory +-----------------------+
5624 compute_frame_size (HOST_WIDE_INT size)
5627 HOST_WIDE_INT total_size; /* # bytes that the entire frame takes up */
5628 HOST_WIDE_INT var_size; /* # bytes that variables take up */
5629 HOST_WIDE_INT args_size; /* # bytes that outgoing arguments take up */
5630 HOST_WIDE_INT cprestore_size; /* # bytes that the cprestore slot takes up */
5631 HOST_WIDE_INT gp_reg_rounded; /* # bytes needed to store gp after rounding */
5632 HOST_WIDE_INT gp_reg_size; /* # bytes needed to store gp regs */
5633 HOST_WIDE_INT fp_reg_size; /* # bytes needed to store fp regs */
5634 unsigned int mask; /* mask of saved gp registers */
5635 unsigned int fmask; /* mask of saved fp registers */
5637 cfun->machine->global_pointer = mips_global_pointer ();
5643 var_size = MIPS_STACK_ALIGN (size);
5644 args_size = current_function_outgoing_args_size;
5645 cprestore_size = MIPS_STACK_ALIGN (STARTING_FRAME_OFFSET) - args_size;
5647 /* The space set aside by STARTING_FRAME_OFFSET isn't needed in leaf
5648 functions. If the function has local variables, we're committed
5649 to allocating it anyway. Otherwise reclaim it here. */
5650 if (var_size == 0 && current_function_is_leaf)
5651 cprestore_size = args_size = 0;
5653 /* The MIPS 3.0 linker does not like functions that dynamically
5654 allocate the stack and have 0 for STACK_DYNAMIC_OFFSET, since it
5655 looks like we are trying to create a second frame pointer to the
5656 function, so allocate some stack space to make it happy. */
5658 if (args_size == 0 && current_function_calls_alloca)
5659 args_size = 4 * UNITS_PER_WORD;
5661 total_size = var_size + args_size + cprestore_size;
5663 /* Calculate space needed for gp registers. */
5664 for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
5665 if (mips_save_reg_p (regno))
5667 gp_reg_size += GET_MODE_SIZE (gpr_mode);
5668 mask |= 1 << (regno - GP_REG_FIRST);
5671 /* We need to restore these for the handler. */
5672 if (current_function_calls_eh_return)
5677 regno = EH_RETURN_DATA_REGNO (i);
5678 if (regno == INVALID_REGNUM)
5680 gp_reg_size += GET_MODE_SIZE (gpr_mode);
5681 mask |= 1 << (regno - GP_REG_FIRST);
5685 /* This loop must iterate over the same space as its companion in
5686 save_restore_insns. */
5687 for (regno = (FP_REG_LAST - FP_INC + 1);
5688 regno >= FP_REG_FIRST;
5691 if (mips_save_reg_p (regno))
5693 fp_reg_size += FP_INC * UNITS_PER_FPREG;
5694 fmask |= ((1 << FP_INC) - 1) << (regno - FP_REG_FIRST);
5698 gp_reg_rounded = MIPS_STACK_ALIGN (gp_reg_size);
5699 total_size += gp_reg_rounded + MIPS_STACK_ALIGN (fp_reg_size);
5701 /* Add in space reserved on the stack by the callee for storing arguments
5702 passed in registers. */
5704 total_size += MIPS_STACK_ALIGN (current_function_pretend_args_size);
5706 /* Save other computed information. */
5707 cfun->machine->frame.total_size = total_size;
5708 cfun->machine->frame.var_size = var_size;
5709 cfun->machine->frame.args_size = args_size;
5710 cfun->machine->frame.cprestore_size = cprestore_size;
5711 cfun->machine->frame.gp_reg_size = gp_reg_size;
5712 cfun->machine->frame.fp_reg_size = fp_reg_size;
5713 cfun->machine->frame.mask = mask;
5714 cfun->machine->frame.fmask = fmask;
5715 cfun->machine->frame.initialized = reload_completed;
5716 cfun->machine->frame.num_gp = gp_reg_size / UNITS_PER_WORD;
5717 cfun->machine->frame.num_fp = fp_reg_size / (FP_INC * UNITS_PER_FPREG);
5721 HOST_WIDE_INT offset;
5723 offset = (args_size + cprestore_size + var_size
5724 + gp_reg_size - GET_MODE_SIZE (gpr_mode));
5725 cfun->machine->frame.gp_sp_offset = offset;
5726 cfun->machine->frame.gp_save_offset = offset - total_size;
5730 cfun->machine->frame.gp_sp_offset = 0;
5731 cfun->machine->frame.gp_save_offset = 0;
5736 HOST_WIDE_INT offset;
5738 offset = (args_size + cprestore_size + var_size
5739 + gp_reg_rounded + fp_reg_size
5740 - FP_INC * UNITS_PER_FPREG);
5741 cfun->machine->frame.fp_sp_offset = offset;
5742 cfun->machine->frame.fp_save_offset = offset - total_size;
5746 cfun->machine->frame.fp_sp_offset = 0;
5747 cfun->machine->frame.fp_save_offset = 0;
5750 /* Ok, we're done. */
5754 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame
5755 pointer or argument pointer. TO is either the stack pointer or
5756 hard frame pointer. */
5759 mips_initial_elimination_offset (int from, int to)
5761 HOST_WIDE_INT offset;
5763 compute_frame_size (get_frame_size ());
5765 /* Set OFFSET to the offset from the stack pointer. */
5768 case FRAME_POINTER_REGNUM:
5772 case ARG_POINTER_REGNUM:
5773 offset = cfun->machine->frame.total_size;
5775 offset -= current_function_pretend_args_size;
5782 if (TARGET_MIPS16 && to == HARD_FRAME_POINTER_REGNUM)
5783 offset -= cfun->machine->frame.args_size;
5788 /* Implement RETURN_ADDR_RTX. Note, we do not support moving
5789 back to a previous frame. */
5791 mips_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
5796 return get_hard_reg_initial_val (Pmode, GP_REG_FIRST + 31);
5799 /* Use FN to save or restore register REGNO. MODE is the register's
5800 mode and OFFSET is the offset of its save slot from the current
5804 mips_save_restore_reg (enum machine_mode mode, int regno,
5805 HOST_WIDE_INT offset, mips_save_restore_fn fn)
5809 mem = gen_rtx_MEM (mode, plus_constant (stack_pointer_rtx, offset));
5811 fn (gen_rtx_REG (mode, regno), mem);
5815 /* Call FN for each register that is saved by the current function.
5816 SP_OFFSET is the offset of the current stack pointer from the start
5820 mips_for_each_saved_reg (HOST_WIDE_INT sp_offset, mips_save_restore_fn fn)
5822 #define BITSET_P(VALUE, BIT) (((VALUE) & (1L << (BIT))) != 0)
5824 enum machine_mode fpr_mode;
5825 HOST_WIDE_INT offset;
5828 /* Save registers starting from high to low. The debuggers prefer at least
5829 the return register be stored at func+4, and also it allows us not to
5830 need a nop in the epilog if at least one register is reloaded in
5831 addition to return address. */
5832 offset = cfun->machine->frame.gp_sp_offset - sp_offset;
5833 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
5834 if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST))
5836 mips_save_restore_reg (gpr_mode, regno, offset, fn);
5837 offset -= GET_MODE_SIZE (gpr_mode);
5840 /* This loop must iterate over the same space as its companion in
5841 compute_frame_size. */
5842 offset = cfun->machine->frame.fp_sp_offset - sp_offset;
5843 fpr_mode = (TARGET_SINGLE_FLOAT ? SFmode : DFmode);
5844 for (regno = (FP_REG_LAST - FP_INC + 1);
5845 regno >= FP_REG_FIRST;
5847 if (BITSET_P (cfun->machine->frame.fmask, regno - FP_REG_FIRST))
5849 mips_save_restore_reg (fpr_mode, regno, offset, fn);
5850 offset -= GET_MODE_SIZE (fpr_mode);
5855 /* If we're generating n32 or n64 abicalls, and the current function
5856 does not use $28 as its global pointer, emit a cplocal directive.
5857 Use pic_offset_table_rtx as the argument to the directive. */
5860 mips_output_cplocal (void)
5862 if (!TARGET_EXPLICIT_RELOCS
5863 && cfun->machine->global_pointer > 0
5864 && cfun->machine->global_pointer != GLOBAL_POINTER_REGNUM)
5865 output_asm_insn (".cplocal %+", 0);
5868 /* If we're generating n32 or n64 abicalls, emit instructions
5869 to set up the global pointer. */
5872 mips_emit_loadgp (void)
5874 if (TARGET_ABICALLS && TARGET_NEWABI && cfun->machine->global_pointer > 0)
5876 rtx addr, offset, incoming_address;
5878 addr = XEXP (DECL_RTL (current_function_decl), 0);
5879 offset = mips_unspec_address (addr, SYMBOL_GOTOFF_LOADGP);
5880 incoming_address = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
5881 emit_insn (gen_loadgp (offset, incoming_address));
5882 if (!TARGET_EXPLICIT_RELOCS)
5883 emit_insn (gen_loadgp_blockage ());
5887 /* Set up the stack and frame (if desired) for the function. */
5890 mips_output_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
5893 HOST_WIDE_INT tsize = cfun->machine->frame.total_size;
5895 #ifdef SDB_DEBUGGING_INFO
5896 if (debug_info_level != DINFO_LEVEL_TERSE && write_symbols == SDB_DEBUG)
5897 ASM_OUTPUT_SOURCE_LINE (file, DECL_SOURCE_LINE (current_function_decl), 0);
5900 /* In mips16 mode, we may need to generate a 32 bit to handle
5901 floating point arguments. The linker will arrange for any 32 bit
5902 functions to call this stub, which will then jump to the 16 bit
5904 if (TARGET_MIPS16 && !TARGET_SOFT_FLOAT
5905 && current_function_args_info.fp_code != 0)
5906 build_mips16_function_stub (file);
5908 if (!FUNCTION_NAME_ALREADY_DECLARED)
5910 /* Get the function name the same way that toplev.c does before calling
5911 assemble_start_function. This is needed so that the name used here
5912 exactly matches the name used in ASM_DECLARE_FUNCTION_NAME. */
5913 fnname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
5915 if (!flag_inhibit_size_directive)
5917 fputs ("\t.ent\t", file);
5918 assemble_name (file, fnname);
5922 assemble_name (file, fnname);
5923 fputs (":\n", file);
5926 /* Stop mips_file_end from treating this function as external. */
5927 if (TARGET_IRIX && mips_abi == ABI_32)
5928 TREE_ASM_WRITTEN (DECL_NAME (cfun->decl)) = 1;
5930 if (!flag_inhibit_size_directive)
5932 /* .frame FRAMEREG, FRAMESIZE, RETREG */
5934 "\t.frame\t%s," HOST_WIDE_INT_PRINT_DEC ",%s\t\t"
5935 "# vars= " HOST_WIDE_INT_PRINT_DEC ", regs= %d/%d"
5936 ", args= " HOST_WIDE_INT_PRINT_DEC
5937 ", gp= " HOST_WIDE_INT_PRINT_DEC "\n",
5938 (reg_names[(frame_pointer_needed)
5939 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM]),
5940 ((frame_pointer_needed && TARGET_MIPS16)
5941 ? tsize - cfun->machine->frame.args_size
5943 reg_names[GP_REG_FIRST + 31],
5944 cfun->machine->frame.var_size,
5945 cfun->machine->frame.num_gp,
5946 cfun->machine->frame.num_fp,
5947 cfun->machine->frame.args_size,
5948 cfun->machine->frame.cprestore_size);
5950 /* .mask MASK, GPOFFSET; .fmask FPOFFSET */
5951 fprintf (file, "\t.mask\t0x%08x," HOST_WIDE_INT_PRINT_DEC "\n",
5952 cfun->machine->frame.mask,
5953 cfun->machine->frame.gp_save_offset);
5954 fprintf (file, "\t.fmask\t0x%08x," HOST_WIDE_INT_PRINT_DEC "\n",
5955 cfun->machine->frame.fmask,
5956 cfun->machine->frame.fp_save_offset);
5959 OLD_SP == *FRAMEREG + FRAMESIZE => can find old_sp from nominated FP reg.
5960 HIGHEST_GP_SAVED == *FRAMEREG + FRAMESIZE + GPOFFSET => can find saved regs. */
5963 if (TARGET_ABICALLS && !TARGET_NEWABI && cfun->machine->global_pointer > 0)
5965 /* Handle the initialization of $gp for SVR4 PIC. */
5966 if (!cfun->machine->all_noreorder_p)
5967 output_asm_insn ("%(.cpload\t%^%)", 0);
5969 output_asm_insn ("%(.cpload\t%^\n\t%<", 0);
5971 else if (cfun->machine->all_noreorder_p)
5972 output_asm_insn ("%(%<", 0);
5974 /* Tell the assembler which register we're using as the global
5975 pointer. This is needed for thunks, since they can use either
5976 explicit relocs or assembler macros. */
5977 mips_output_cplocal ();
5980 /* Make the last instruction frame related and note that it performs
5981 the operation described by FRAME_PATTERN. */
5984 mips_set_frame_expr (rtx frame_pattern)
5988 insn = get_last_insn ();
5989 RTX_FRAME_RELATED_P (insn) = 1;
5990 REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
5996 /* Return a frame-related rtx that stores REG at MEM.
5997 REG must be a single register. */
6000 mips_frame_set (rtx mem, rtx reg)
6002 rtx set = gen_rtx_SET (VOIDmode, mem, reg);
6003 RTX_FRAME_RELATED_P (set) = 1;
6008 /* Save register REG to MEM. Make the instruction frame-related. */
6011 mips_save_reg (rtx reg, rtx mem)
6013 if (GET_MODE (reg) == DFmode && !TARGET_FLOAT64)
6017 if (mips_split_64bit_move_p (mem, reg))
6018 mips_split_64bit_move (mem, reg);
6020 emit_move_insn (mem, reg);
6022 x1 = mips_frame_set (mips_subword (mem, 0), mips_subword (reg, 0));
6023 x2 = mips_frame_set (mips_subword (mem, 1), mips_subword (reg, 1));
6024 mips_set_frame_expr (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, x1, x2)));
6029 && REGNO (reg) != GP_REG_FIRST + 31
6030 && !M16_REG_P (REGNO (reg)))
6032 /* Save a non-mips16 register by moving it through a temporary.
6033 We don't need to do this for $31 since there's a special
6034 instruction for it. */
6035 emit_move_insn (MIPS_PROLOGUE_TEMP (GET_MODE (reg)), reg);
6036 emit_move_insn (mem, MIPS_PROLOGUE_TEMP (GET_MODE (reg)));
6039 emit_move_insn (mem, reg);
6041 mips_set_frame_expr (mips_frame_set (mem, reg));
6046 /* Expand the prologue into a bunch of separate insns. */
6049 mips_expand_prologue (void)
6053 if (cfun->machine->global_pointer > 0)
6054 REGNO (pic_offset_table_rtx) = cfun->machine->global_pointer;
6056 size = compute_frame_size (get_frame_size ());
6058 /* Save the registers. Allocate up to MIPS_MAX_FIRST_STACK_STEP
6059 bytes beforehand; this is enough to cover the register save area
6060 without going out of range. */
6061 if ((cfun->machine->frame.mask | cfun->machine->frame.fmask) != 0)
6063 HOST_WIDE_INT step1;
6065 step1 = MIN (size, MIPS_MAX_FIRST_STACK_STEP);
6066 RTX_FRAME_RELATED_P (emit_insn (gen_add3_insn (stack_pointer_rtx,
6068 GEN_INT (-step1)))) = 1;
6070 mips_for_each_saved_reg (size, mips_save_reg);
6073 /* Allocate the rest of the frame. */
6076 if (SMALL_OPERAND (-size))
6077 RTX_FRAME_RELATED_P (emit_insn (gen_add3_insn (stack_pointer_rtx,
6079 GEN_INT (-size)))) = 1;
6082 emit_move_insn (MIPS_PROLOGUE_TEMP (Pmode), GEN_INT (size));
6085 /* There are no instructions to add or subtract registers
6086 from the stack pointer, so use the frame pointer as a
6087 temporary. We should always be using a frame pointer
6088 in this case anyway. */
6089 if (!frame_pointer_needed)
6092 emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
6093 emit_insn (gen_sub3_insn (hard_frame_pointer_rtx,
6094 hard_frame_pointer_rtx,
6095 MIPS_PROLOGUE_TEMP (Pmode)));
6096 emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx);
6099 emit_insn (gen_sub3_insn (stack_pointer_rtx,
6101 MIPS_PROLOGUE_TEMP (Pmode)));
6103 /* Describe the combined effect of the previous instructions. */
6105 (gen_rtx_SET (VOIDmode, stack_pointer_rtx,
6106 plus_constant (stack_pointer_rtx, -size)));
6110 /* Set up the frame pointer, if we're using one. In mips16 code,
6111 we point the frame pointer ahead of the outgoing argument area.
6112 This should allow more variables & incoming arguments to be
6113 accessed with unextended instructions. */
6114 if (frame_pointer_needed)
6116 if (TARGET_MIPS16 && cfun->machine->frame.args_size != 0)
6118 rtx offset = GEN_INT (cfun->machine->frame.args_size);
6120 (emit_insn (gen_add3_insn (hard_frame_pointer_rtx,
6125 RTX_FRAME_RELATED_P (emit_move_insn (hard_frame_pointer_rtx,
6126 stack_pointer_rtx)) = 1;
6129 /* If generating o32/o64 abicalls, save $gp on the stack. */
6130 if (TARGET_ABICALLS && !TARGET_NEWABI && !current_function_is_leaf)
6131 emit_insn (gen_cprestore (GEN_INT (current_function_outgoing_args_size)));
6133 mips_emit_loadgp ();
6135 /* If we are profiling, make sure no instructions are scheduled before
6136 the call to mcount. */
6138 if (current_function_profile)
6139 emit_insn (gen_blockage ());
6142 /* Do any necessary cleanup after a function to restore stack, frame,
6145 #define RA_MASK BITMASK_HIGH /* 1 << 31 */
6148 mips_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
6149 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
6151 /* Reinstate the normal $gp. */
6152 REGNO (pic_offset_table_rtx) = GLOBAL_POINTER_REGNUM;
6153 mips_output_cplocal ();
6155 if (cfun->machine->all_noreorder_p)
6157 /* Avoid using %>%) since it adds excess whitespace. */
6158 output_asm_insn (".set\tmacro", 0);
6159 output_asm_insn (".set\treorder", 0);
6160 set_noreorder = set_nomacro = 0;
6163 if (!FUNCTION_NAME_ALREADY_DECLARED && !flag_inhibit_size_directive)
6167 /* Get the function name the same way that toplev.c does before calling
6168 assemble_start_function. This is needed so that the name used here
6169 exactly matches the name used in ASM_DECLARE_FUNCTION_NAME. */
6170 fnname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
6171 fputs ("\t.end\t", file);
6172 assemble_name (file, fnname);
6177 /* Emit instructions to restore register REG from slot MEM. */
6180 mips_restore_reg (rtx reg, rtx mem)
6182 /* There's no mips16 instruction to load $31 directly. Load into
6183 $7 instead and adjust the return insn appropriately. */
6184 if (TARGET_MIPS16 && REGNO (reg) == GP_REG_FIRST + 31)
6185 reg = gen_rtx_REG (GET_MODE (reg), 7);
6187 if (TARGET_MIPS16 && !M16_REG_P (REGNO (reg)))
6189 /* Can't restore directly; move through a temporary. */
6190 emit_move_insn (MIPS_EPILOGUE_TEMP (GET_MODE (reg)), mem);
6191 emit_move_insn (reg, MIPS_EPILOGUE_TEMP (GET_MODE (reg)));
6194 emit_move_insn (reg, mem);
6198 /* Expand the epilogue into a bunch of separate insns. SIBCALL_P is true
6199 if this epilogue precedes a sibling call, false if it is for a normal
6200 "epilogue" pattern. */
6203 mips_expand_epilogue (int sibcall_p)
6205 HOST_WIDE_INT step1, step2;
6208 if (!sibcall_p && mips_can_use_return_insn ())
6210 emit_jump_insn (gen_return ());
6214 /* Split the frame into two. STEP1 is the amount of stack we should
6215 deallocate before restoring the registers. STEP2 is the amount we
6216 should deallocate afterwards.
6218 Start off by assuming that no registers need to be restored. */
6219 step1 = cfun->machine->frame.total_size;
6222 /* Work out which register holds the frame address. Account for the
6223 frame pointer offset used by mips16 code. */
6224 if (!frame_pointer_needed)
6225 base = stack_pointer_rtx;
6228 base = hard_frame_pointer_rtx;
6230 step1 -= cfun->machine->frame.args_size;
6233 /* If we need to restore registers, deallocate as much stack as
6234 possible in the second step without going out of range. */
6235 if ((cfun->machine->frame.mask | cfun->machine->frame.fmask) != 0)
6237 step2 = MIN (step1, MIPS_MAX_FIRST_STACK_STEP);
6241 /* Set TARGET to BASE + STEP1. */
6247 /* Get an rtx for STEP1 that we can add to BASE. */
6248 adjust = GEN_INT (step1);
6249 if (!SMALL_OPERAND (step1))
6251 emit_move_insn (MIPS_EPILOGUE_TEMP (Pmode), adjust);
6252 adjust = MIPS_EPILOGUE_TEMP (Pmode);
6255 /* Normal mode code can copy the result straight into $sp. */
6257 target = stack_pointer_rtx;
6259 emit_insn (gen_add3_insn (target, base, adjust));
6262 /* Copy TARGET into the stack pointer. */
6263 if (target != stack_pointer_rtx)
6264 emit_move_insn (stack_pointer_rtx, target);
6266 /* If we're using addressing macros for n32/n64 abicalls, $gp is
6267 implicitly used by all SYMBOL_REFs. We must emit a blockage
6268 insn before restoring it. */
6269 if (TARGET_ABICALLS && TARGET_NEWABI && !TARGET_EXPLICIT_RELOCS)
6270 emit_insn (gen_blockage ());
6272 /* Restore the registers. */
6273 mips_for_each_saved_reg (cfun->machine->frame.total_size - step2,
6276 /* Deallocate the final bit of the frame. */
6278 emit_insn (gen_add3_insn (stack_pointer_rtx,
6282 /* Add in the __builtin_eh_return stack adjustment. We need to
6283 use a temporary in mips16 code. */
6284 if (current_function_calls_eh_return)
6288 emit_move_insn (MIPS_EPILOGUE_TEMP (Pmode), stack_pointer_rtx);
6289 emit_insn (gen_add3_insn (MIPS_EPILOGUE_TEMP (Pmode),
6290 MIPS_EPILOGUE_TEMP (Pmode),
6291 EH_RETURN_STACKADJ_RTX));
6292 emit_move_insn (stack_pointer_rtx, MIPS_EPILOGUE_TEMP (Pmode));
6295 emit_insn (gen_add3_insn (stack_pointer_rtx,
6297 EH_RETURN_STACKADJ_RTX));
6302 /* The mips16 loads the return address into $7, not $31. */
6303 if (TARGET_MIPS16 && (cfun->machine->frame.mask & RA_MASK) != 0)
6304 emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode,
6305 GP_REG_FIRST + 7)));
6307 emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode,
6308 GP_REG_FIRST + 31)));
6312 /* Return nonzero if this function is known to have a null epilogue.
6313 This allows the optimizer to omit jumps to jumps if no stack
6317 mips_can_use_return_insn (void)
6321 if (! reload_completed)
6324 if (regs_ever_live[31] || current_function_profile)
6327 return_type = DECL_RESULT (current_function_decl);
6329 /* In mips16 mode, a function which returns a floating point value
6330 needs to arrange to copy the return value into the floating point
6333 && mips16_hard_float
6334 && ! aggregate_value_p (return_type, current_function_decl)
6335 && GET_MODE_CLASS (DECL_MODE (return_type)) == MODE_FLOAT
6336 && GET_MODE_SIZE (DECL_MODE (return_type)) <= UNITS_PER_FPVALUE)
6339 if (cfun->machine->frame.initialized)
6340 return cfun->machine->frame.total_size == 0;
6342 return compute_frame_size (get_frame_size ()) == 0;
6345 /* Implement TARGET_ASM_OUTPUT_MI_THUNK. Generate rtl rather than asm text
6346 in order to avoid duplicating too much logic from elsewhere. */
6349 mips_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
6350 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
6353 rtx this, temp1, temp2, insn, fnaddr;
6355 /* Pretend to be a post-reload pass while generating rtl. */
6357 reload_completed = 1;
6358 reset_block_changes ();
6360 /* Pick a global pointer for -mabicalls. Use $15 rather than $28
6361 for TARGET_NEWABI since the latter is a call-saved register. */
6362 if (TARGET_ABICALLS)
6363 cfun->machine->global_pointer
6364 = REGNO (pic_offset_table_rtx)
6365 = TARGET_NEWABI ? 15 : GLOBAL_POINTER_REGNUM;
6367 /* Set up the global pointer for n32 or n64 abicalls. */
6368 mips_emit_loadgp ();
6370 /* We need two temporary registers in some cases. */
6371 temp1 = gen_rtx_REG (Pmode, 2);
6372 temp2 = gen_rtx_REG (Pmode, 3);
6374 /* Find out which register contains the "this" pointer. */
6375 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
6376 this = gen_rtx_REG (Pmode, GP_ARG_FIRST + 1);
6378 this = gen_rtx_REG (Pmode, GP_ARG_FIRST);
6380 /* Add DELTA to THIS. */
6383 rtx offset = GEN_INT (delta);
6384 if (!SMALL_OPERAND (delta))
6386 emit_move_insn (temp1, offset);
6389 emit_insn (gen_add3_insn (this, this, offset));
6392 /* If needed, add *(*THIS + VCALL_OFFSET) to THIS. */
6393 if (vcall_offset != 0)
6397 /* Set TEMP1 to *THIS. */
6398 emit_move_insn (temp1, gen_rtx_MEM (Pmode, this));
6400 /* Set ADDR to a legitimate address for *THIS + VCALL_OFFSET. */
6401 addr = mips_add_offset (temp2, temp1, vcall_offset);
6403 /* Load the offset and add it to THIS. */
6404 emit_move_insn (temp1, gen_rtx_MEM (Pmode, addr));
6405 emit_insn (gen_add3_insn (this, this, temp1));
6408 /* Jump to the target function. Use a sibcall if direct jumps are
6409 allowed, otherwise load the address into a register first. */
6410 fnaddr = XEXP (DECL_RTL (function), 0);
6411 if (TARGET_MIPS16 || TARGET_ABICALLS || TARGET_LONG_CALLS)
6413 /* This is messy. gas treats "la $25,foo" as part of a call
6414 sequence and may allow a global "foo" to be lazily bound.
6415 The general move patterns therefore reject this combination.
6417 In this context, lazy binding would actually be OK for o32 and o64,
6418 but it's still wrong for n32 and n64; see mips_load_call_address.
6419 We must therefore load the address via a temporary register if
6420 mips_dangerous_for_la25_p.
6422 If we jump to the temporary register rather than $25, the assembler
6423 can use the move insn to fill the jump's delay slot. */
6424 if (TARGET_ABICALLS && !mips_dangerous_for_la25_p (fnaddr))
6425 temp1 = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
6426 mips_load_call_address (temp1, fnaddr, true);
6428 if (TARGET_ABICALLS && REGNO (temp1) != PIC_FUNCTION_ADDR_REGNUM)
6429 emit_move_insn (gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM), temp1);
6430 emit_jump_insn (gen_indirect_jump (temp1));
6434 insn = emit_call_insn (gen_sibcall_internal (fnaddr, const0_rtx));
6435 SIBLING_CALL_P (insn) = 1;
6438 /* Run just enough of rest_of_compilation. This sequence was
6439 "borrowed" from alpha.c. */
6440 insn = get_insns ();
6441 insn_locators_initialize ();
6442 split_all_insns_noflow ();
6444 mips16_lay_out_constants ();
6445 shorten_branches (insn);
6446 final_start_function (insn, file, 1);
6447 final (insn, file, 1, 0);
6448 final_end_function ();
6450 /* Clean up the vars set above. Note that final_end_function resets
6451 the global pointer for us. */
6452 reload_completed = 0;
6456 /* Returns nonzero if X contains a SYMBOL_REF. */
6459 symbolic_expression_p (rtx x)
6461 if (GET_CODE (x) == SYMBOL_REF)
6464 if (GET_CODE (x) == CONST)
6465 return symbolic_expression_p (XEXP (x, 0));
6468 return symbolic_expression_p (XEXP (x, 0));
6470 if (ARITHMETIC_P (x))
6471 return (symbolic_expression_p (XEXP (x, 0))
6472 || symbolic_expression_p (XEXP (x, 1)));
6477 /* Choose the section to use for the constant rtx expression X that has
6481 mips_select_rtx_section (enum machine_mode mode, rtx x,
6482 unsigned HOST_WIDE_INT align)
6486 /* In mips16 mode, the constant table always goes in the same section
6487 as the function, so that constants can be loaded using PC relative
6489 function_section (current_function_decl);
6491 else if (TARGET_EMBEDDED_DATA)
6493 /* For embedded applications, always put constants in read-only data,
6494 in order to reduce RAM usage. */
6495 mergeable_constant_section (mode, align, 0);
6499 /* For hosted applications, always put constants in small data if
6500 possible, as this gives the best performance. */
6501 /* ??? Consider using mergeable small data sections. */
6503 if (GET_MODE_SIZE (mode) <= (unsigned) mips_section_threshold
6504 && mips_section_threshold > 0)
6505 named_section (0, ".sdata", 0);
6506 else if (flag_pic && symbolic_expression_p (x))
6507 named_section (0, ".data.rel.ro", 3);
6509 mergeable_constant_section (mode, align, 0);
6513 /* Implement TARGET_IN_SMALL_DATA_P. Return true if it would be safe to
6514 access DECL using %gp_rel(...)($gp). */
6517 mips_in_small_data_p (tree decl)
6521 if (TREE_CODE (decl) == STRING_CST || TREE_CODE (decl) == FUNCTION_DECL)
6524 /* We don't yet generate small-data references for -mabicalls. See related
6525 -G handling in override_options. */
6526 if (TARGET_ABICALLS)
6529 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl) != 0)
6533 /* Reject anything that isn't in a known small-data section. */
6534 name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
6535 if (strcmp (name, ".sdata") != 0 && strcmp (name, ".sbss") != 0)
6538 /* If a symbol is defined externally, the assembler will use the
6539 usual -G rules when deciding how to implement macros. */
6540 if (TARGET_EXPLICIT_RELOCS || !DECL_EXTERNAL (decl))
6543 else if (TARGET_EMBEDDED_DATA)
6545 /* Don't put constants into the small data section: we want them
6546 to be in ROM rather than RAM. */
6547 if (TREE_CODE (decl) != VAR_DECL)
6550 if (TREE_READONLY (decl)
6551 && !TREE_SIDE_EFFECTS (decl)
6552 && (!DECL_INITIAL (decl) || TREE_CONSTANT (DECL_INITIAL (decl))))
6556 size = int_size_in_bytes (TREE_TYPE (decl));
6557 return (size > 0 && size <= mips_section_threshold);
6560 /* See whether VALTYPE is a record whose fields should be returned in
6561 floating-point registers. If so, return the number of fields and
6562 list them in FIELDS (which should have two elements). Return 0
6565 For n32 & n64, a structure with one or two fields is returned in
6566 floating-point registers as long as every field has a floating-point
6570 mips_fpr_return_fields (tree valtype, tree *fields)
6578 if (TREE_CODE (valtype) != RECORD_TYPE)
6582 for (field = TYPE_FIELDS (valtype); field != 0; field = TREE_CHAIN (field))
6584 if (TREE_CODE (field) != FIELD_DECL)
6587 if (TREE_CODE (TREE_TYPE (field)) != REAL_TYPE)
6593 fields[i++] = field;
6599 /* Implement TARGET_RETURN_IN_MSB. For n32 & n64, we should return
6600 a value in the most significant part of $2/$3 if:
6602 - the target is big-endian;
6604 - the value has a structure or union type (we generalize this to
6605 cover aggregates from other languages too); and
6607 - the structure is not returned in floating-point registers. */
6610 mips_return_in_msb (tree valtype)
6614 return (TARGET_NEWABI
6615 && TARGET_BIG_ENDIAN
6616 && AGGREGATE_TYPE_P (valtype)
6617 && mips_fpr_return_fields (valtype, fields) == 0);
6621 /* Return a composite value in a pair of floating-point registers.
6622 MODE1 and OFFSET1 are the mode and byte offset for the first value,
6623 likewise MODE2 and OFFSET2 for the second. MODE is the mode of the
6626 For n32 & n64, $f0 always holds the first value and $f2 the second.
6627 Otherwise the values are packed together as closely as possible. */
6630 mips_return_fpr_pair (enum machine_mode mode,
6631 enum machine_mode mode1, HOST_WIDE_INT offset1,
6632 enum machine_mode mode2, HOST_WIDE_INT offset2)
6636 inc = (TARGET_NEWABI ? 2 : FP_INC);
6637 return gen_rtx_PARALLEL
6640 gen_rtx_EXPR_LIST (VOIDmode,
6641 gen_rtx_REG (mode1, FP_RETURN),
6643 gen_rtx_EXPR_LIST (VOIDmode,
6644 gen_rtx_REG (mode2, FP_RETURN + inc),
6645 GEN_INT (offset2))));
6650 /* Implement FUNCTION_VALUE and LIBCALL_VALUE. For normal calls,
6651 VALTYPE is the return type and MODE is VOIDmode. For libcalls,
6652 VALTYPE is null and MODE is the mode of the return value. */
6655 mips_function_value (tree valtype, tree func ATTRIBUTE_UNUSED,
6656 enum machine_mode mode)
6663 mode = TYPE_MODE (valtype);
6664 unsignedp = TYPE_UNSIGNED (valtype);
6666 /* Since we define TARGET_PROMOTE_FUNCTION_RETURN that returns
6667 true, we must promote the mode just as PROMOTE_MODE does. */
6668 mode = promote_mode (valtype, mode, &unsignedp, 1);
6670 /* Handle structures whose fields are returned in $f0/$f2. */
6671 switch (mips_fpr_return_fields (valtype, fields))
6674 return gen_rtx_REG (mode, FP_RETURN);
6677 return mips_return_fpr_pair (mode,
6678 TYPE_MODE (TREE_TYPE (fields[0])),
6679 int_byte_position (fields[0]),
6680 TYPE_MODE (TREE_TYPE (fields[1])),
6681 int_byte_position (fields[1]));
6684 /* If a value is passed in the most significant part of a register, see
6685 whether we have to round the mode up to a whole number of words. */
6686 if (mips_return_in_msb (valtype))
6688 HOST_WIDE_INT size = int_size_in_bytes (valtype);
6689 if (size % UNITS_PER_WORD != 0)
6691 size += UNITS_PER_WORD - size % UNITS_PER_WORD;
6692 mode = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0);
6697 if ((GET_MODE_CLASS (mode) == MODE_FLOAT
6698 || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
6699 && GET_MODE_SIZE (mode) <= UNITS_PER_HWFPVALUE)
6700 return gen_rtx_REG (mode, FP_RETURN);
6702 /* Handle long doubles for n32 & n64. */
6704 return mips_return_fpr_pair (mode,
6706 DImode, GET_MODE_SIZE (mode) / 2);
6708 if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
6709 && GET_MODE_SIZE (mode) <= UNITS_PER_HWFPVALUE * 2)
6710 return mips_return_fpr_pair (mode,
6711 GET_MODE_INNER (mode), 0,
6712 GET_MODE_INNER (mode),
6713 GET_MODE_SIZE (mode) / 2);
6715 return gen_rtx_REG (mode, GP_RETURN);
6718 /* Return nonzero when an argument must be passed by reference. */
6721 mips_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
6722 enum machine_mode mode, tree type,
6723 bool named ATTRIBUTE_UNUSED)
6725 if (mips_abi == ABI_EABI)
6729 /* ??? How should SCmode be handled? */
6730 if (type == NULL_TREE || mode == DImode || mode == DFmode)
6733 size = int_size_in_bytes (type);
6734 return size == -1 || size > UNITS_PER_WORD;
6738 /* If we have a variable-sized parameter, we have no choice. */
6739 return targetm.calls.must_pass_in_stack (mode, type);
6743 /* Return the class of registers for which a mode change from FROM to TO
6746 In little-endian mode, the hi-lo registers are numbered backwards,
6747 so (subreg:SI (reg:DI hi) 0) gets the high word instead of the low
6750 Similarly, when using paired floating-point registers, the first
6751 register holds the low word, regardless of endianness. So in big
6752 endian mode, (subreg:SI (reg:DF $f0) 0) does not get the high word
6755 Also, loading a 32-bit value into a 64-bit floating-point register
6756 will not sign-extend the value, despite what LOAD_EXTEND_OP says.
6757 We can't allow 64-bit float registers to change from a 32-bit
6758 mode to a 64-bit mode. */
6761 mips_cannot_change_mode_class (enum machine_mode from,
6762 enum machine_mode to, enum reg_class class)
6764 if (GET_MODE_SIZE (from) != GET_MODE_SIZE (to))
6766 if (TARGET_BIG_ENDIAN)
6767 return reg_classes_intersect_p (FP_REGS, class);
6769 return reg_classes_intersect_p (HI_AND_FP_REGS, class);
6770 return reg_classes_intersect_p (HI_REG, class);
6775 /* Return true if X should not be moved directly into register $25.
6776 We need this because many versions of GAS will treat "la $25,foo" as
6777 part of a call sequence and so allow a global "foo" to be lazily bound. */
6780 mips_dangerous_for_la25_p (rtx x)
6782 HOST_WIDE_INT offset;
6784 if (TARGET_EXPLICIT_RELOCS)
6787 mips_split_const (x, &x, &offset);
6788 return global_got_operand (x, VOIDmode);
6791 /* Implement PREFERRED_RELOAD_CLASS. */
6794 mips_preferred_reload_class (rtx x, enum reg_class class)
6796 if (mips_dangerous_for_la25_p (x) && reg_class_subset_p (LEA_REGS, class))
6799 if (TARGET_HARD_FLOAT
6800 && FLOAT_MODE_P (GET_MODE (x))
6801 && reg_class_subset_p (FP_REGS, class))
6804 if (reg_class_subset_p (GR_REGS, class))
6807 if (TARGET_MIPS16 && reg_class_subset_p (M16_REGS, class))
6813 /* This function returns the register class required for a secondary
6814 register when copying between one of the registers in CLASS, and X,
6815 using MODE. If IN_P is nonzero, the copy is going from X to the
6816 register, otherwise the register is the source. A return value of
6817 NO_REGS means that no secondary register is required. */
6820 mips_secondary_reload_class (enum reg_class class,
6821 enum machine_mode mode, rtx x, int in_p)
6823 enum reg_class gr_regs = TARGET_MIPS16 ? M16_REGS : GR_REGS;
6827 if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
6828 regno = true_regnum (x);
6830 gp_reg_p = TARGET_MIPS16 ? M16_REG_P (regno) : GP_REG_P (regno);
6832 if (mips_dangerous_for_la25_p (x))
6835 if (TEST_HARD_REG_BIT (reg_class_contents[(int) class], 25))
6839 /* Copying from HI or LO to anywhere other than a general register
6840 requires a general register. */
6841 if (class == HI_REG || class == LO_REG || class == MD_REGS)
6843 if (TARGET_MIPS16 && in_p)
6845 /* We can't really copy to HI or LO at all in mips16 mode. */
6848 return gp_reg_p ? NO_REGS : gr_regs;
6850 if (MD_REG_P (regno))
6852 if (TARGET_MIPS16 && ! in_p)
6854 /* We can't really copy to HI or LO at all in mips16 mode. */
6857 return class == gr_regs ? NO_REGS : gr_regs;
6860 /* We can only copy a value to a condition code register from a
6861 floating point register, and even then we require a scratch
6862 floating point register. We can only copy a value out of a
6863 condition code register into a general register. */
6864 if (class == ST_REGS)
6868 return gp_reg_p ? NO_REGS : gr_regs;
6870 if (ST_REG_P (regno))
6874 return class == gr_regs ? NO_REGS : gr_regs;
6877 if (class == FP_REGS)
6879 if (GET_CODE (x) == MEM)
6881 /* In this case we can use lwc1, swc1, ldc1 or sdc1. */
6884 else if (CONSTANT_P (x) && GET_MODE_CLASS (mode) == MODE_FLOAT)
6886 /* We can use the l.s and l.d macros to load floating-point
6887 constants. ??? For l.s, we could probably get better
6888 code by returning GR_REGS here. */
6891 else if (gp_reg_p || x == CONST0_RTX (mode))
6893 /* In this case we can use mtc1, mfc1, dmtc1 or dmfc1. */
6896 else if (FP_REG_P (regno))
6898 /* In this case we can use mov.s or mov.d. */
6903 /* Otherwise, we need to reload through an integer register. */
6908 /* In mips16 mode, going between memory and anything but M16_REGS
6909 requires an M16_REG. */
6912 if (class != M16_REGS && class != M16_NA_REGS)
6920 if (class == M16_REGS || class == M16_NA_REGS)
6929 /* Implement CLASS_MAX_NREGS.
6931 Usually all registers are word-sized. The only supported exception
6932 is -mgp64 -msingle-float, which has 64-bit words but 32-bit float
6933 registers. A word-based calculation is correct even in that case,
6934 since -msingle-float disallows multi-FPR values.
6936 The FP status registers are an exception to this rule. They are always
6937 4 bytes wide as they only hold condition code modes, and CCmode is always
6938 considered to be 4 bytes wide. */
6941 mips_class_max_nregs (enum reg_class class ATTRIBUTE_UNUSED,
6942 enum machine_mode mode)
6944 if (class == ST_REGS)
6945 return (GET_MODE_SIZE (mode) + 3) / 4;
6947 return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
6951 mips_valid_pointer_mode (enum machine_mode mode)
6953 return (mode == SImode || (TARGET_64BIT && mode == DImode));
6956 /* Target hook for vector_mode_supported_p. */
6958 mips_vector_mode_supported_p (enum machine_mode mode)
6960 if (mode == V2SFmode && TARGET_PAIRED_SINGLE_FLOAT)
6966 /* If we can access small data directly (using gp-relative relocation
6967 operators) return the small data pointer, otherwise return null.
6969 For each mips16 function which refers to GP relative symbols, we
6970 use a pseudo register, initialized at the start of the function, to
6971 hold the $gp value. */
6974 mips16_gp_pseudo_reg (void)
6976 if (cfun->machine->mips16_gp_pseudo_rtx == NULL_RTX)
6981 cfun->machine->mips16_gp_pseudo_rtx = gen_reg_rtx (Pmode);
6983 /* We want to initialize this to a value which gcc will believe
6986 unspec = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, const0_rtx), UNSPEC_GP);
6987 emit_move_insn (cfun->machine->mips16_gp_pseudo_rtx,
6988 gen_rtx_CONST (Pmode, unspec));
6989 insn = get_insns ();
6992 push_topmost_sequence ();
6993 /* We need to emit the initialization after the FUNCTION_BEG
6994 note, so that it will be integrated. */
6995 for (scan = get_insns (); scan != NULL_RTX; scan = NEXT_INSN (scan))
6996 if (GET_CODE (scan) == NOTE
6997 && NOTE_LINE_NUMBER (scan) == NOTE_INSN_FUNCTION_BEG)
6999 if (scan == NULL_RTX)
7000 scan = get_insns ();
7001 insn = emit_insn_after (insn, scan);
7002 pop_topmost_sequence ();
7005 return cfun->machine->mips16_gp_pseudo_rtx;
7008 /* Write out code to move floating point arguments in or out of
7009 general registers. Output the instructions to FILE. FP_CODE is
7010 the code describing which arguments are present (see the comment at
7011 the definition of CUMULATIVE_ARGS in mips.h). FROM_FP_P is nonzero if
7012 we are copying from the floating point registers. */
7015 mips16_fp_args (FILE *file, int fp_code, int from_fp_p)
7021 /* This code only works for the original 32 bit ABI and the O64 ABI. */
7029 gparg = GP_ARG_FIRST;
7030 fparg = FP_ARG_FIRST;
7031 for (f = (unsigned int) fp_code; f != 0; f >>= 2)
7035 if ((fparg & 1) != 0)
7037 fprintf (file, "\t%s\t%s,%s\n", s,
7038 reg_names[gparg], reg_names[fparg]);
7040 else if ((f & 3) == 2)
7043 fprintf (file, "\td%s\t%s,%s\n", s,
7044 reg_names[gparg], reg_names[fparg]);
7047 if ((fparg & 1) != 0)
7049 if (TARGET_BIG_ENDIAN)
7050 fprintf (file, "\t%s\t%s,%s\n\t%s\t%s,%s\n", s,
7051 reg_names[gparg], reg_names[fparg + 1], s,
7052 reg_names[gparg + 1], reg_names[fparg]);
7054 fprintf (file, "\t%s\t%s,%s\n\t%s\t%s,%s\n", s,
7055 reg_names[gparg], reg_names[fparg], s,
7056 reg_names[gparg + 1], reg_names[fparg + 1]);
7069 /* Build a mips16 function stub. This is used for functions which
7070 take arguments in the floating point registers. It is 32 bit code
7071 that moves the floating point args into the general registers, and
7072 then jumps to the 16 bit code. */
7075 build_mips16_function_stub (FILE *file)
7078 char *secname, *stubname;
7079 tree stubid, stubdecl;
7083 fnname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
7084 secname = (char *) alloca (strlen (fnname) + 20);
7085 sprintf (secname, ".mips16.fn.%s", fnname);
7086 stubname = (char *) alloca (strlen (fnname) + 20);
7087 sprintf (stubname, "__fn_stub_%s", fnname);
7088 stubid = get_identifier (stubname);
7089 stubdecl = build_decl (FUNCTION_DECL, stubid,
7090 build_function_type (void_type_node, NULL_TREE));
7091 DECL_SECTION_NAME (stubdecl) = build_string (strlen (secname), secname);
7093 fprintf (file, "\t# Stub function for %s (", current_function_name ());
7095 for (f = (unsigned int) current_function_args_info.fp_code; f != 0; f >>= 2)
7097 fprintf (file, "%s%s",
7098 need_comma ? ", " : "",
7099 (f & 3) == 1 ? "float" : "double");
7102 fprintf (file, ")\n");
7104 fprintf (file, "\t.set\tnomips16\n");
7105 function_section (stubdecl);
7106 ASM_OUTPUT_ALIGN (file, floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT));
7108 /* ??? If FUNCTION_NAME_ALREADY_DECLARED is defined, then we are
7109 within a .ent, and we cannot emit another .ent. */
7110 if (!FUNCTION_NAME_ALREADY_DECLARED)
7112 fputs ("\t.ent\t", file);
7113 assemble_name (file, stubname);
7117 assemble_name (file, stubname);
7118 fputs (":\n", file);
7120 /* We don't want the assembler to insert any nops here. */
7121 fprintf (file, "\t.set\tnoreorder\n");
7123 mips16_fp_args (file, current_function_args_info.fp_code, 1);
7125 fprintf (asm_out_file, "\t.set\tnoat\n");
7126 fprintf (asm_out_file, "\tla\t%s,", reg_names[GP_REG_FIRST + 1]);
7127 assemble_name (file, fnname);
7128 fprintf (file, "\n");
7129 fprintf (asm_out_file, "\tjr\t%s\n", reg_names[GP_REG_FIRST + 1]);
7130 fprintf (asm_out_file, "\t.set\tat\n");
7132 /* Unfortunately, we can't fill the jump delay slot. We can't fill
7133 with one of the mfc1 instructions, because the result is not
7134 available for one instruction, so if the very first instruction
7135 in the function refers to the register, it will see the wrong
7137 fprintf (file, "\tnop\n");
7139 fprintf (file, "\t.set\treorder\n");
7141 if (!FUNCTION_NAME_ALREADY_DECLARED)
7143 fputs ("\t.end\t", file);
7144 assemble_name (file, stubname);
7148 fprintf (file, "\t.set\tmips16\n");
7150 function_section (current_function_decl);
7153 /* We keep a list of functions for which we have already built stubs
7154 in build_mips16_call_stub. */
7158 struct mips16_stub *next;
7163 static struct mips16_stub *mips16_stubs;
7165 /* Build a call stub for a mips16 call. A stub is needed if we are
7166 passing any floating point values which should go into the floating
7167 point registers. If we are, and the call turns out to be to a 32
7168 bit function, the stub will be used to move the values into the
7169 floating point registers before calling the 32 bit function. The
7170 linker will magically adjust the function call to either the 16 bit
7171 function or the 32 bit stub, depending upon where the function call
7172 is actually defined.
7174 Similarly, we need a stub if the return value might come back in a
7175 floating point register.
7177 RETVAL is the location of the return value, or null if this is
7178 a call rather than a call_value. FN is the address of the
7179 function and ARG_SIZE is the size of the arguments. FP_CODE
7180 is the code built by function_arg. This function returns a nonzero
7181 value if it builds the call instruction itself. */
7184 build_mips16_call_stub (rtx retval, rtx fn, rtx arg_size, int fp_code)
7188 char *secname, *stubname;
7189 struct mips16_stub *l;
7190 tree stubid, stubdecl;
7194 /* We don't need to do anything if we aren't in mips16 mode, or if
7195 we were invoked with the -msoft-float option. */
7196 if (! TARGET_MIPS16 || ! mips16_hard_float)
7199 /* Figure out whether the value might come back in a floating point
7201 fpret = (retval != 0
7202 && GET_MODE_CLASS (GET_MODE (retval)) == MODE_FLOAT
7203 && GET_MODE_SIZE (GET_MODE (retval)) <= UNITS_PER_FPVALUE);
7205 /* We don't need to do anything if there were no floating point
7206 arguments and the value will not be returned in a floating point
7208 if (fp_code == 0 && ! fpret)
7211 /* We don't need to do anything if this is a call to a special
7212 mips16 support function. */
7213 if (GET_CODE (fn) == SYMBOL_REF
7214 && strncmp (XSTR (fn, 0), "__mips16_", 9) == 0)
7217 /* This code will only work for o32 and o64 abis. The other ABI's
7218 require more sophisticated support. */
7222 /* We can only handle SFmode and DFmode floating point return
7224 if (fpret && GET_MODE (retval) != SFmode && GET_MODE (retval) != DFmode)
7227 /* If we're calling via a function pointer, then we must always call
7228 via a stub. There are magic stubs provided in libgcc.a for each
7229 of the required cases. Each of them expects the function address
7230 to arrive in register $2. */
7232 if (GET_CODE (fn) != SYMBOL_REF)
7238 /* ??? If this code is modified to support other ABI's, we need
7239 to handle PARALLEL return values here. */
7241 sprintf (buf, "__mips16_call_stub_%s%d",
7243 ? (GET_MODE (retval) == SFmode ? "sf_" : "df_")
7246 id = get_identifier (buf);
7247 stub_fn = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (id));
7249 emit_move_insn (gen_rtx_REG (Pmode, 2), fn);
7251 if (retval == NULL_RTX)
7252 insn = gen_call_internal (stub_fn, arg_size);
7254 insn = gen_call_value_internal (retval, stub_fn, arg_size);
7255 insn = emit_call_insn (insn);
7257 /* Put the register usage information on the CALL. */
7258 if (GET_CODE (insn) != CALL_INSN)
7260 CALL_INSN_FUNCTION_USAGE (insn) =
7261 gen_rtx_EXPR_LIST (VOIDmode,
7262 gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 2)),
7263 CALL_INSN_FUNCTION_USAGE (insn));
7265 /* If we are handling a floating point return value, we need to
7266 save $18 in the function prologue. Putting a note on the
7267 call will mean that regs_ever_live[$18] will be true if the
7268 call is not eliminated, and we can check that in the prologue
7271 CALL_INSN_FUNCTION_USAGE (insn) =
7272 gen_rtx_EXPR_LIST (VOIDmode,
7273 gen_rtx_USE (VOIDmode,
7274 gen_rtx_REG (word_mode, 18)),
7275 CALL_INSN_FUNCTION_USAGE (insn));
7277 /* Return 1 to tell the caller that we've generated the call
7282 /* We know the function we are going to call. If we have already
7283 built a stub, we don't need to do anything further. */
7285 fnname = XSTR (fn, 0);
7286 for (l = mips16_stubs; l != NULL; l = l->next)
7287 if (strcmp (l->name, fnname) == 0)
7292 /* Build a special purpose stub. When the linker sees a
7293 function call in mips16 code, it will check where the target
7294 is defined. If the target is a 32 bit call, the linker will
7295 search for the section defined here. It can tell which
7296 symbol this section is associated with by looking at the
7297 relocation information (the name is unreliable, since this
7298 might be a static function). If such a section is found, the
7299 linker will redirect the call to the start of the magic
7302 If the function does not return a floating point value, the
7303 special stub section is named
7306 If the function does return a floating point value, the stub
7308 .mips16.call.fp.FNNAME
7311 secname = (char *) alloca (strlen (fnname) + 40);
7312 sprintf (secname, ".mips16.call.%s%s",
7315 stubname = (char *) alloca (strlen (fnname) + 20);
7316 sprintf (stubname, "__call_stub_%s%s",
7319 stubid = get_identifier (stubname);
7320 stubdecl = build_decl (FUNCTION_DECL, stubid,
7321 build_function_type (void_type_node, NULL_TREE));
7322 DECL_SECTION_NAME (stubdecl) = build_string (strlen (secname), secname);
7324 fprintf (asm_out_file, "\t# Stub function to call %s%s (",
7326 ? (GET_MODE (retval) == SFmode ? "float " : "double ")
7330 for (f = (unsigned int) fp_code; f != 0; f >>= 2)
7332 fprintf (asm_out_file, "%s%s",
7333 need_comma ? ", " : "",
7334 (f & 3) == 1 ? "float" : "double");
7337 fprintf (asm_out_file, ")\n");
7339 fprintf (asm_out_file, "\t.set\tnomips16\n");
7340 assemble_start_function (stubdecl, stubname);
7342 if (!FUNCTION_NAME_ALREADY_DECLARED)
7344 fputs ("\t.ent\t", asm_out_file);
7345 assemble_name (asm_out_file, stubname);
7346 fputs ("\n", asm_out_file);
7348 assemble_name (asm_out_file, stubname);
7349 fputs (":\n", asm_out_file);
7352 /* We build the stub code by hand. That's the only way we can
7353 do it, since we can't generate 32 bit code during a 16 bit
7356 /* We don't want the assembler to insert any nops here. */
7357 fprintf (asm_out_file, "\t.set\tnoreorder\n");
7359 mips16_fp_args (asm_out_file, fp_code, 0);
7363 fprintf (asm_out_file, "\t.set\tnoat\n");
7364 fprintf (asm_out_file, "\tla\t%s,%s\n", reg_names[GP_REG_FIRST + 1],
7366 fprintf (asm_out_file, "\tjr\t%s\n", reg_names[GP_REG_FIRST + 1]);
7367 fprintf (asm_out_file, "\t.set\tat\n");
7368 /* Unfortunately, we can't fill the jump delay slot. We
7369 can't fill with one of the mtc1 instructions, because the
7370 result is not available for one instruction, so if the
7371 very first instruction in the function refers to the
7372 register, it will see the wrong value. */
7373 fprintf (asm_out_file, "\tnop\n");
7377 fprintf (asm_out_file, "\tmove\t%s,%s\n",
7378 reg_names[GP_REG_FIRST + 18], reg_names[GP_REG_FIRST + 31]);
7379 fprintf (asm_out_file, "\tjal\t%s\n", fnname);
7380 /* As above, we can't fill the delay slot. */
7381 fprintf (asm_out_file, "\tnop\n");
7382 if (GET_MODE (retval) == SFmode)
7383 fprintf (asm_out_file, "\tmfc1\t%s,%s\n",
7384 reg_names[GP_REG_FIRST + 2], reg_names[FP_REG_FIRST + 0]);
7387 if (TARGET_BIG_ENDIAN)
7389 fprintf (asm_out_file, "\tmfc1\t%s,%s\n",
7390 reg_names[GP_REG_FIRST + 2],
7391 reg_names[FP_REG_FIRST + 1]);
7392 fprintf (asm_out_file, "\tmfc1\t%s,%s\n",
7393 reg_names[GP_REG_FIRST + 3],
7394 reg_names[FP_REG_FIRST + 0]);
7398 fprintf (asm_out_file, "\tmfc1\t%s,%s\n",
7399 reg_names[GP_REG_FIRST + 2],
7400 reg_names[FP_REG_FIRST + 0]);
7401 fprintf (asm_out_file, "\tmfc1\t%s,%s\n",
7402 reg_names[GP_REG_FIRST + 3],
7403 reg_names[FP_REG_FIRST + 1]);
7406 fprintf (asm_out_file, "\tj\t%s\n", reg_names[GP_REG_FIRST + 18]);
7407 /* As above, we can't fill the delay slot. */
7408 fprintf (asm_out_file, "\tnop\n");
7411 fprintf (asm_out_file, "\t.set\treorder\n");
7413 #ifdef ASM_DECLARE_FUNCTION_SIZE
7414 ASM_DECLARE_FUNCTION_SIZE (asm_out_file, stubname, stubdecl);
7417 if (!FUNCTION_NAME_ALREADY_DECLARED)
7419 fputs ("\t.end\t", asm_out_file);
7420 assemble_name (asm_out_file, stubname);
7421 fputs ("\n", asm_out_file);
7424 fprintf (asm_out_file, "\t.set\tmips16\n");
7426 /* Record this stub. */
7427 l = (struct mips16_stub *) xmalloc (sizeof *l);
7428 l->name = xstrdup (fnname);
7430 l->next = mips16_stubs;
7434 /* If we expect a floating point return value, but we've built a
7435 stub which does not expect one, then we're in trouble. We can't
7436 use the existing stub, because it won't handle the floating point
7437 value. We can't build a new stub, because the linker won't know
7438 which stub to use for the various calls in this object file.
7439 Fortunately, this case is illegal, since it means that a function
7440 was declared in two different ways in a single compilation. */
7441 if (fpret && ! l->fpret)
7442 error ("cannot handle inconsistent calls to `%s'", fnname);
7444 /* If we are calling a stub which handles a floating point return
7445 value, we need to arrange to save $18 in the prologue. We do
7446 this by marking the function call as using the register. The
7447 prologue will later see that it is used, and emit code to save
7454 if (retval == NULL_RTX)
7455 insn = gen_call_internal (fn, arg_size);
7457 insn = gen_call_value_internal (retval, fn, arg_size);
7458 insn = emit_call_insn (insn);
7460 if (GET_CODE (insn) != CALL_INSN)
7463 CALL_INSN_FUNCTION_USAGE (insn) =
7464 gen_rtx_EXPR_LIST (VOIDmode,
7465 gen_rtx_USE (VOIDmode, gen_rtx_REG (word_mode, 18)),
7466 CALL_INSN_FUNCTION_USAGE (insn));
7468 /* Return 1 to tell the caller that we've generated the call
7473 /* Return 0 to let the caller generate the call insn. */
7477 /* An entry in the mips16 constant pool. VALUE is the pool constant,
7478 MODE is its mode, and LABEL is the CODE_LABEL associated with it. */
7480 struct mips16_constant {
7481 struct mips16_constant *next;
7484 enum machine_mode mode;
7487 /* Information about an incomplete mips16 constant pool. FIRST is the
7488 first constant, HIGHEST_ADDRESS is the highest address that the first
7489 byte of the pool can have, and INSN_ADDRESS is the current instruction
7492 struct mips16_constant_pool {
7493 struct mips16_constant *first;
7494 int highest_address;
7498 /* Add constant VALUE to POOL and return its label. MODE is the
7499 value's mode (used for CONST_INTs, etc.). */
7502 add_constant (struct mips16_constant_pool *pool,
7503 rtx value, enum machine_mode mode)
7505 struct mips16_constant **p, *c;
7506 bool first_of_size_p;
7508 /* See whether the constant is already in the pool. If so, return the
7509 existing label, otherwise leave P pointing to the place where the
7510 constant should be added.
7512 Keep the pool sorted in increasing order of mode size so that we can
7513 reduce the number of alignments needed. */
7514 first_of_size_p = true;
7515 for (p = &pool->first; *p != 0; p = &(*p)->next)
7517 if (mode == (*p)->mode && rtx_equal_p (value, (*p)->value))
7519 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE ((*p)->mode))
7521 if (GET_MODE_SIZE (mode) == GET_MODE_SIZE ((*p)->mode))
7522 first_of_size_p = false;
7525 /* In the worst case, the constant needed by the earliest instruction
7526 will end up at the end of the pool. The entire pool must then be
7527 accessible from that instruction.
7529 When adding the first constant, set the pool's highest address to
7530 the address of the first out-of-range byte. Adjust this address
7531 downwards each time a new constant is added. */
7532 if (pool->first == 0)
7533 /* For pc-relative lw, addiu and daddiu instructions, the base PC value
7534 is the address of the instruction with the lowest two bits clear.
7535 The base PC value for ld has the lowest three bits clear. Assume
7536 the worst case here. */
7537 pool->highest_address = pool->insn_address - (UNITS_PER_WORD - 2) + 0x8000;
7538 pool->highest_address -= GET_MODE_SIZE (mode);
7539 if (first_of_size_p)
7540 /* Take into account the worst possible padding due to alignment. */
7541 pool->highest_address -= GET_MODE_SIZE (mode) - 1;
7543 /* Create a new entry. */
7544 c = (struct mips16_constant *) xmalloc (sizeof *c);
7547 c->label = gen_label_rtx ();
7554 /* Output constant VALUE after instruction INSN and return the last
7555 instruction emitted. MODE is the mode of the constant. */
7558 dump_constants_1 (enum machine_mode mode, rtx value, rtx insn)
7560 switch (GET_MODE_CLASS (mode))
7564 rtx size = GEN_INT (GET_MODE_SIZE (mode));
7565 return emit_insn_after (gen_consttable_int (value, size), insn);
7569 return emit_insn_after (gen_consttable_float (value), insn);
7571 case MODE_VECTOR_FLOAT:
7572 case MODE_VECTOR_INT:
7575 for (i = 0; i < CONST_VECTOR_NUNITS (value); i++)
7576 insn = dump_constants_1 (GET_MODE_INNER (mode),
7577 CONST_VECTOR_ELT (value, i), insn);
7587 /* Dump out the constants in CONSTANTS after INSN. */
7590 dump_constants (struct mips16_constant *constants, rtx insn)
7592 struct mips16_constant *c, *next;
7596 for (c = constants; c != NULL; c = next)
7598 /* If necessary, increase the alignment of PC. */
7599 if (align < GET_MODE_SIZE (c->mode))
7601 int align_log = floor_log2 (GET_MODE_SIZE (c->mode));
7602 insn = emit_insn_after (gen_align (GEN_INT (align_log)), insn);
7604 align = GET_MODE_SIZE (c->mode);
7606 insn = emit_label_after (c->label, insn);
7607 insn = dump_constants_1 (c->mode, c->value, insn);
7613 emit_barrier_after (insn);
7616 /* Return the length of instruction INSN.
7618 ??? MIPS16 switch tables go in .text, but we don't define
7619 JUMP_TABLES_IN_TEXT_SECTION, so get_attr_length will not
7620 compute their lengths correctly. */
7623 mips16_insn_length (rtx insn)
7625 if (GET_CODE (insn) == JUMP_INSN)
7627 rtx body = PATTERN (insn);
7628 if (GET_CODE (body) == ADDR_VEC)
7629 return GET_MODE_SIZE (GET_MODE (body)) * XVECLEN (body, 0);
7630 if (GET_CODE (body) == ADDR_DIFF_VEC)
7631 return GET_MODE_SIZE (GET_MODE (body)) * XVECLEN (body, 1);
7633 return get_attr_length (insn);
7636 /* Rewrite *X so that constant pool references refer to the constant's
7637 label instead. DATA points to the constant pool structure. */
7640 mips16_rewrite_pool_refs (rtx *x, void *data)
7642 struct mips16_constant_pool *pool = data;
7643 if (GET_CODE (*x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (*x))
7644 *x = gen_rtx_LABEL_REF (Pmode, add_constant (pool,
7645 get_pool_constant (*x),
7646 get_pool_mode (*x)));
7650 /* Build MIPS16 constant pools. */
7653 mips16_lay_out_constants (void)
7655 struct mips16_constant_pool pool;
7659 memset (&pool, 0, sizeof (pool));
7660 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7662 /* Rewrite constant pool references in INSN. */
7664 for_each_rtx (&PATTERN (insn), mips16_rewrite_pool_refs, &pool);
7666 pool.insn_address += mips16_insn_length (insn);
7668 if (pool.first != NULL)
7670 /* If there are no natural barriers between the first user of
7671 the pool and the highest acceptable address, we'll need to
7672 create a new instruction to jump around the constant pool.
7673 In the worst case, this instruction will be 4 bytes long.
7675 If it's too late to do this transformation after INSN,
7676 do it immediately before INSN. */
7677 if (barrier == 0 && pool.insn_address + 4 > pool.highest_address)
7681 label = gen_label_rtx ();
7683 jump = emit_jump_insn_before (gen_jump (label), insn);
7684 JUMP_LABEL (jump) = label;
7685 LABEL_NUSES (label) = 1;
7686 barrier = emit_barrier_after (jump);
7688 emit_label_after (label, barrier);
7689 pool.insn_address += 4;
7692 /* See whether the constant pool is now out of range of the first
7693 user. If so, output the constants after the previous barrier.
7694 Note that any instructions between BARRIER and INSN (inclusive)
7695 will use negative offsets to refer to the pool. */
7696 if (pool.insn_address > pool.highest_address)
7698 dump_constants (pool.first, barrier);
7702 else if (BARRIER_P (insn))
7706 dump_constants (pool.first, get_last_insn ());
7709 /* A temporary variable used by for_each_rtx callbacks, etc. */
7710 static rtx mips_sim_insn;
7712 /* A structure representing the state of the processor pipeline.
7713 Used by the mips_sim_* family of functions. */
7715 /* The maximum number of instructions that can be issued in a cycle.
7716 (Caches mips_issue_rate.) */
7717 unsigned int issue_rate;
7719 /* The current simulation time. */
7722 /* How many more instructions can be issued in the current cycle. */
7723 unsigned int insns_left;
7725 /* LAST_SET[X].INSN is the last instruction to set register X.
7726 LAST_SET[X].TIME is the time at which that instruction was issued.
7727 INSN is null if no instruction has yet set register X. */
7731 } last_set[FIRST_PSEUDO_REGISTER];
7733 /* The pipeline's current DFA state. */
7737 /* Reset STATE to the initial simulation state. */
7740 mips_sim_reset (struct mips_sim *state)
7743 state->insns_left = state->issue_rate;
7744 memset (&state->last_set, 0, sizeof (state->last_set));
7745 state_reset (state->dfa_state);
7748 /* Initialize STATE before its first use. DFA_STATE points to an
7749 allocated but uninitialized DFA state. */
7752 mips_sim_init (struct mips_sim *state, state_t dfa_state)
7754 state->issue_rate = mips_issue_rate ();
7755 state->dfa_state = dfa_state;
7756 mips_sim_reset (state);
7759 /* Advance STATE by one clock cycle. */
7762 mips_sim_next_cycle (struct mips_sim *state)
7765 state->insns_left = state->issue_rate;
7766 state_transition (state->dfa_state, 0);
7769 /* Advance simulation state STATE until instruction INSN can read
7773 mips_sim_wait_reg (struct mips_sim *state, rtx insn, rtx reg)
7777 for (i = 0; i < HARD_REGNO_NREGS (REGNO (reg), GET_MODE (reg)); i++)
7778 if (state->last_set[REGNO (reg) + i].insn != 0)
7782 t = state->last_set[REGNO (reg) + i].time;
7783 t += insn_latency (state->last_set[REGNO (reg) + i].insn, insn);
7784 while (state->time < t)
7785 mips_sim_next_cycle (state);
7789 /* A for_each_rtx callback. If *X is a register, advance simulation state
7790 DATA until mips_sim_insn can read the register's value. */
7793 mips_sim_wait_regs_2 (rtx *x, void *data)
7796 mips_sim_wait_reg (data, mips_sim_insn, *x);
7800 /* Call mips_sim_wait_regs_2 (R, DATA) for each register R mentioned in *X. */
7803 mips_sim_wait_regs_1 (rtx *x, void *data)
7805 for_each_rtx (x, mips_sim_wait_regs_2, data);
7808 /* Advance simulation state STATE until all of INSN's register
7809 dependencies are satisfied. */
7812 mips_sim_wait_regs (struct mips_sim *state, rtx insn)
7814 mips_sim_insn = insn;
7815 note_uses (&PATTERN (insn), mips_sim_wait_regs_1, state);
7818 /* Advance simulation state STATE until the units required by
7819 instruction INSN are available. */
7822 mips_sim_wait_units (struct mips_sim *state, rtx insn)
7826 tmp_state = alloca (state_size ());
7827 while (state->insns_left == 0
7828 || (memcpy (tmp_state, state->dfa_state, state_size ()),
7829 state_transition (tmp_state, insn) >= 0))
7830 mips_sim_next_cycle (state);
7833 /* Advance simulation state STATE until INSN is ready to issue. */
7836 mips_sim_wait_insn (struct mips_sim *state, rtx insn)
7838 mips_sim_wait_regs (state, insn);
7839 mips_sim_wait_units (state, insn);
7842 /* mips_sim_insn has just set X. Update the LAST_SET array
7843 in simulation state DATA. */
7846 mips_sim_record_set (rtx x, rtx pat ATTRIBUTE_UNUSED, void *data)
7848 struct mips_sim *state;
7853 for (i = 0; i < HARD_REGNO_NREGS (REGNO (x), GET_MODE (x)); i++)
7855 state->last_set[REGNO (x) + i].insn = mips_sim_insn;
7856 state->last_set[REGNO (x) + i].time = state->time;
7860 /* Issue instruction INSN in scheduler state STATE. Assume that INSN
7861 can issue immediately (i.e., that mips_sim_wait_insn has already
7865 mips_sim_issue_insn (struct mips_sim *state, rtx insn)
7867 state_transition (state->dfa_state, insn);
7868 state->insns_left--;
7870 mips_sim_insn = insn;
7871 note_stores (PATTERN (insn), mips_sim_record_set, state);
7874 /* Simulate issuing a NOP in state STATE. */
7877 mips_sim_issue_nop (struct mips_sim *state)
7879 if (state->insns_left == 0)
7880 mips_sim_next_cycle (state);
7881 state->insns_left--;
7884 /* Update simulation state STATE so that it's ready to accept the instruction
7885 after INSN. INSN should be part of the main rtl chain, not a member of a
7889 mips_sim_finish_insn (struct mips_sim *state, rtx insn)
7891 /* If INSN is a jump with an implicit delay slot, simulate a nop. */
7893 mips_sim_issue_nop (state);
7895 switch (GET_CODE (SEQ_BEGIN (insn)))
7899 /* We can't predict the processor state after a call or label. */
7900 mips_sim_reset (state);
7904 /* The delay slots of branch likely instructions are only executed
7905 when the branch is taken. Therefore, if the caller has simulated
7906 the delay slot instruction, STATE does not really reflect the state
7907 of the pipeline for the instruction after the delay slot. Also,
7908 branch likely instructions tend to incur a penalty when not taken,
7909 so there will probably be an extra delay between the branch and
7910 the instruction after the delay slot. */
7911 if (INSN_ANNULLED_BRANCH_P (SEQ_BEGIN (insn)))
7912 mips_sim_reset (state);
7920 /* The VR4130 pipeline issues aligned pairs of instructions together,
7921 but it stalls the second instruction if it depends on the first.
7922 In order to cut down the amount of logic required, this dependence
7923 check is not based on a full instruction decode. Instead, any non-SPECIAL
7924 instruction is assumed to modify the register specified by bits 20-16
7925 (which is usually the "rt" field).
7927 In beq, beql, bne and bnel instructions, the rt field is actually an
7928 input, so we can end up with a false dependence between the branch
7929 and its delay slot. If this situation occurs in instruction INSN,
7930 try to avoid it by swapping rs and rt. */
7933 vr4130_avoid_branch_rt_conflict (rtx insn)
7937 first = SEQ_BEGIN (insn);
7938 second = SEQ_END (insn);
7939 if (GET_CODE (first) == JUMP_INSN
7940 && GET_CODE (second) == INSN
7941 && GET_CODE (PATTERN (first)) == SET
7942 && GET_CODE (SET_DEST (PATTERN (first))) == PC
7943 && GET_CODE (SET_SRC (PATTERN (first))) == IF_THEN_ELSE)
7945 /* Check for the right kind of condition. */
7946 rtx cond = XEXP (SET_SRC (PATTERN (first)), 0);
7947 if ((GET_CODE (cond) == EQ || GET_CODE (cond) == NE)
7948 && REG_P (XEXP (cond, 0))
7949 && REG_P (XEXP (cond, 1))
7950 && reg_referenced_p (XEXP (cond, 1), PATTERN (second))
7951 && !reg_referenced_p (XEXP (cond, 0), PATTERN (second)))
7953 /* SECOND mentions the rt register but not the rs register. */
7954 rtx tmp = XEXP (cond, 0);
7955 XEXP (cond, 0) = XEXP (cond, 1);
7956 XEXP (cond, 1) = tmp;
7961 /* Implement -mvr4130-align. Go through each basic block and simulate the
7962 processor pipeline. If we find that a pair of instructions could execute
7963 in parallel, and the first of those instruction is not 8-byte aligned,
7964 insert a nop to make it aligned. */
7967 vr4130_align_insns (void)
7969 struct mips_sim state;
7970 rtx insn, subinsn, last, last2, next;
7975 /* LAST is the last instruction before INSN to have a nonzero length.
7976 LAST2 is the last such instruction before LAST. */
7980 /* ALIGNED_P is true if INSN is known to be at an aligned address. */
7983 mips_sim_init (&state, alloca (state_size ()));
7984 for (insn = get_insns (); insn != 0; insn = next)
7986 unsigned int length;
7988 next = NEXT_INSN (insn);
7990 /* See the comment above vr4130_avoid_branch_rt_conflict for details.
7991 This isn't really related to the alignment pass, but we do it on
7992 the fly to avoid a separate instruction walk. */
7993 vr4130_avoid_branch_rt_conflict (insn);
7995 if (USEFUL_INSN_P (insn))
7996 FOR_EACH_SUBINSN (subinsn, insn)
7998 mips_sim_wait_insn (&state, subinsn);
8000 /* If we want this instruction to issue in parallel with the
8001 previous one, make sure that the previous instruction is
8002 aligned. There are several reasons why this isn't worthwhile
8003 when the second instruction is a call:
8005 - Calls are less likely to be performance critical,
8006 - There's a good chance that the delay slot can execute
8007 in parallel with the call.
8008 - The return address would then be unaligned.
8010 In general, if we're going to insert a nop between instructions
8011 X and Y, it's better to insert it immediately after X. That
8012 way, if the nop makes Y aligned, it will also align any labels
8014 if (state.insns_left != state.issue_rate
8015 && GET_CODE (subinsn) != CALL_INSN)
8017 if (subinsn == SEQ_BEGIN (insn) && aligned_p)
8019 /* SUBINSN is the first instruction in INSN and INSN is
8020 aligned. We want to align the previous instruction
8021 instead, so insert a nop between LAST2 and LAST.
8023 Note that LAST could be either a single instruction
8024 or a branch with a delay slot. In the latter case,
8025 LAST, like INSN, is already aligned, but the delay
8026 slot must have some extra delay that stops it from
8027 issuing at the same time as the branch. We therefore
8028 insert a nop before the branch in order to align its
8030 emit_insn_after (gen_nop (), last2);
8033 else if (subinsn != SEQ_BEGIN (insn) && !aligned_p)
8035 /* SUBINSN is the delay slot of INSN, but INSN is
8036 currently unaligned. Insert a nop between
8037 LAST and INSN to align it. */
8038 emit_insn_after (gen_nop (), last);
8042 mips_sim_issue_insn (&state, subinsn);
8044 mips_sim_finish_insn (&state, insn);
8046 /* Update LAST, LAST2 and ALIGNED_P for the next instruction. */
8047 length = get_attr_length (insn);
8050 /* If the instruction is an asm statement or multi-instruction
8051 mips.md patern, the length is only an estimate. Insert an
8052 8 byte alignment after it so that the following instructions
8053 can be handled correctly. */
8054 if (GET_CODE (SEQ_BEGIN (insn)) == INSN
8055 && (recog_memoized (insn) < 0 || length >= 8))
8057 next = emit_insn_after (gen_align (GEN_INT (3)), insn);
8058 next = NEXT_INSN (next);
8059 mips_sim_next_cycle (&state);
8062 else if (length & 4)
8063 aligned_p = !aligned_p;
8068 /* See whether INSN is an aligned label. */
8069 if (LABEL_P (insn) && label_to_alignment (insn) >= 3)
8075 /* Subroutine of mips_reorg. If there is a hazard between INSN
8076 and a previous instruction, avoid it by inserting nops after
8079 *DELAYED_REG and *HILO_DELAY describe the hazards that apply at
8080 this point. If *DELAYED_REG is non-null, INSN must wait a cycle
8081 before using the value of that register. *HILO_DELAY counts the
8082 number of instructions since the last hilo hazard (that is,
8083 the number of instructions since the last mflo or mfhi).
8085 After inserting nops for INSN, update *DELAYED_REG and *HILO_DELAY
8086 for the next instruction.
8088 LO_REG is an rtx for the LO register, used in dependence checking. */
8091 mips_avoid_hazard (rtx after, rtx insn, int *hilo_delay,
8092 rtx *delayed_reg, rtx lo_reg)
8100 pattern = PATTERN (insn);
8102 /* Do not put the whole function in .set noreorder if it contains
8103 an asm statement. We don't know whether there will be hazards
8104 between the asm statement and the gcc-generated code. */
8105 if (GET_CODE (pattern) == ASM_INPUT || asm_noperands (pattern) >= 0)
8106 cfun->machine->all_noreorder_p = false;
8108 /* Ignore zero-length instructions (barriers and the like). */
8109 ninsns = get_attr_length (insn) / 4;
8113 /* Work out how many nops are needed. Note that we only care about
8114 registers that are explicitly mentioned in the instruction's pattern.
8115 It doesn't matter that calls use the argument registers or that they
8116 clobber hi and lo. */
8117 if (*hilo_delay < 2 && reg_set_p (lo_reg, pattern))
8118 nops = 2 - *hilo_delay;
8119 else if (*delayed_reg != 0 && reg_referenced_p (*delayed_reg, pattern))
8124 /* Insert the nops between this instruction and the previous one.
8125 Each new nop takes us further from the last hilo hazard. */
8126 *hilo_delay += nops;
8128 emit_insn_after (gen_hazard_nop (), after);
8130 /* Set up the state for the next instruction. */
8131 *hilo_delay += ninsns;
8133 if (INSN_CODE (insn) >= 0)
8134 switch (get_attr_hazard (insn))
8144 set = single_set (insn);
8147 *delayed_reg = SET_DEST (set);
8153 /* Go through the instruction stream and insert nops where necessary.
8154 See if the whole function can then be put into .set noreorder &
8158 mips_avoid_hazards (void)
8160 rtx insn, last_insn, lo_reg, delayed_reg;
8163 /* Force all instructions to be split into their final form. */
8164 split_all_insns_noflow ();
8166 /* Recalculate instruction lengths without taking nops into account. */
8167 cfun->machine->ignore_hazard_length_p = true;
8168 shorten_branches (get_insns ());
8170 /* The profiler code uses assembler macros. -mfix-vr4120 relies on
8171 assembler nop insertion. */
8172 cfun->machine->all_noreorder_p = (!current_function_profile
8173 && !TARGET_FIX_VR4120);
8178 lo_reg = gen_rtx_REG (SImode, LO_REGNUM);
8180 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
8183 if (GET_CODE (PATTERN (insn)) == SEQUENCE)
8184 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
8185 mips_avoid_hazard (last_insn, XVECEXP (PATTERN (insn), 0, i),
8186 &hilo_delay, &delayed_reg, lo_reg);
8188 mips_avoid_hazard (last_insn, insn, &hilo_delay,
8189 &delayed_reg, lo_reg);
8196 /* Implement TARGET_MACHINE_DEPENDENT_REORG. */
8202 mips16_lay_out_constants ();
8203 else if (TARGET_EXPLICIT_RELOCS)
8205 if (mips_flag_delayed_branch)
8206 dbr_schedule (get_insns (), dump_file);
8207 mips_avoid_hazards ();
8208 if (TUNE_MIPS4130 && TARGET_VR4130_ALIGN)
8209 vr4130_align_insns ();
8213 /* This function does three things:
8215 - Register the special divsi3 and modsi3 functions if -mfix-vr4120.
8216 - Register the mips16 hardware floating point stubs.
8217 - Register the gofast functions if selected using --enable-gofast. */
8219 #include "config/gofast.h"
8222 mips_init_libfuncs (void)
8224 if (TARGET_FIX_VR4120)
8226 set_optab_libfunc (sdiv_optab, SImode, "__vr4120_divsi3");
8227 set_optab_libfunc (smod_optab, SImode, "__vr4120_modsi3");
8230 if (TARGET_MIPS16 && mips16_hard_float)
8232 set_optab_libfunc (add_optab, SFmode, "__mips16_addsf3");
8233 set_optab_libfunc (sub_optab, SFmode, "__mips16_subsf3");
8234 set_optab_libfunc (smul_optab, SFmode, "__mips16_mulsf3");
8235 set_optab_libfunc (sdiv_optab, SFmode, "__mips16_divsf3");
8237 set_optab_libfunc (eq_optab, SFmode, "__mips16_eqsf2");
8238 set_optab_libfunc (ne_optab, SFmode, "__mips16_nesf2");
8239 set_optab_libfunc (gt_optab, SFmode, "__mips16_gtsf2");
8240 set_optab_libfunc (ge_optab, SFmode, "__mips16_gesf2");
8241 set_optab_libfunc (lt_optab, SFmode, "__mips16_ltsf2");
8242 set_optab_libfunc (le_optab, SFmode, "__mips16_lesf2");
8244 set_conv_libfunc (sfix_optab, SImode, SFmode, "__mips16_fix_truncsfsi");
8245 set_conv_libfunc (sfloat_optab, SFmode, SImode, "__mips16_floatsisf");
8247 if (TARGET_DOUBLE_FLOAT)
8249 set_optab_libfunc (add_optab, DFmode, "__mips16_adddf3");
8250 set_optab_libfunc (sub_optab, DFmode, "__mips16_subdf3");
8251 set_optab_libfunc (smul_optab, DFmode, "__mips16_muldf3");
8252 set_optab_libfunc (sdiv_optab, DFmode, "__mips16_divdf3");
8254 set_optab_libfunc (eq_optab, DFmode, "__mips16_eqdf2");
8255 set_optab_libfunc (ne_optab, DFmode, "__mips16_nedf2");
8256 set_optab_libfunc (gt_optab, DFmode, "__mips16_gtdf2");
8257 set_optab_libfunc (ge_optab, DFmode, "__mips16_gedf2");
8258 set_optab_libfunc (lt_optab, DFmode, "__mips16_ltdf2");
8259 set_optab_libfunc (le_optab, DFmode, "__mips16_ledf2");
8261 set_conv_libfunc (sext_optab, DFmode, SFmode, "__mips16_extendsfdf2");
8262 set_conv_libfunc (trunc_optab, SFmode, DFmode, "__mips16_truncdfsf2");
8264 set_conv_libfunc (sfix_optab, SImode, DFmode, "__mips16_fix_truncdfsi");
8265 set_conv_libfunc (sfloat_optab, DFmode, SImode, "__mips16_floatsidf");
8269 gofast_maybe_init_libfuncs ();
8272 /* Return a number assessing the cost of moving a register in class
8273 FROM to class TO. The classes are expressed using the enumeration
8274 values such as `GENERAL_REGS'. A value of 2 is the default; other
8275 values are interpreted relative to that.
8277 It is not required that the cost always equal 2 when FROM is the
8278 same as TO; on some machines it is expensive to move between
8279 registers if they are not general registers.
8281 If reload sees an insn consisting of a single `set' between two
8282 hard registers, and if `REGISTER_MOVE_COST' applied to their
8283 classes returns a value of 2, reload does not check to ensure that
8284 the constraints of the insn are met. Setting a cost of other than
8285 2 will allow reload to verify that the constraints are met. You
8286 should do this if the `movM' pattern's constraints do not allow
8289 ??? We make the cost of moving from HI/LO into general
8290 registers the same as for one of moving general registers to
8291 HI/LO for TARGET_MIPS16 in order to prevent allocating a
8292 pseudo to HI/LO. This might hurt optimizations though, it
8293 isn't clear if it is wise. And it might not work in all cases. We
8294 could solve the DImode LO reg problem by using a multiply, just
8295 like reload_{in,out}si. We could solve the SImode/HImode HI reg
8296 problem by using divide instructions. divu puts the remainder in
8297 the HI reg, so doing a divide by -1 will move the value in the HI
8298 reg for all values except -1. We could handle that case by using a
8299 signed divide, e.g. -1 / 2 (or maybe 1 / -2?). We'd have to emit
8300 a compare/branch to test the input value to see which instruction
8301 we need to use. This gets pretty messy, but it is feasible. */
8304 mips_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
8305 enum reg_class to, enum reg_class from)
8307 if (from == M16_REGS && GR_REG_CLASS_P (to))
8309 else if (from == M16_NA_REGS && GR_REG_CLASS_P (to))
8311 else if (GR_REG_CLASS_P (from))
8315 else if (to == M16_NA_REGS)
8317 else if (GR_REG_CLASS_P (to))
8324 else if (to == FP_REGS)
8326 else if (to == HI_REG || to == LO_REG || to == MD_REGS)
8333 else if (COP_REG_CLASS_P (to))
8337 } /* GR_REG_CLASS_P (from) */
8338 else if (from == FP_REGS)
8340 if (GR_REG_CLASS_P (to))
8342 else if (to == FP_REGS)
8344 else if (to == ST_REGS)
8346 } /* from == FP_REGS */
8347 else if (from == HI_REG || from == LO_REG || from == MD_REGS)
8349 if (GR_REG_CLASS_P (to))
8356 } /* from == HI_REG, etc. */
8357 else if (from == ST_REGS && GR_REG_CLASS_P (to))
8359 else if (COP_REG_CLASS_P (from))
8362 } /* COP_REG_CLASS_P (from) */
8369 /* Return the length of INSN. LENGTH is the initial length computed by
8370 attributes in the machine-description file. */
8373 mips_adjust_insn_length (rtx insn, int length)
8375 /* A unconditional jump has an unfilled delay slot if it is not part
8376 of a sequence. A conditional jump normally has a delay slot, but
8377 does not on MIPS16. */
8378 if (CALL_P (insn) || (TARGET_MIPS16 ? simplejump_p (insn) : JUMP_P (insn)))
8381 /* See how many nops might be needed to avoid hardware hazards. */
8382 if (!cfun->machine->ignore_hazard_length_p && INSN_CODE (insn) >= 0)
8383 switch (get_attr_hazard (insn))
8397 /* All MIPS16 instructions are a measly two bytes. */
8405 /* Return an asm sequence to start a noat block and load the address
8406 of a label into $1. */
8409 mips_output_load_label (void)
8411 if (TARGET_EXPLICIT_RELOCS)
8415 return "%[lw\t%@,%%got_page(%0)(%+)\n\taddiu\t%@,%@,%%got_ofst(%0)";
8418 return "%[ld\t%@,%%got_page(%0)(%+)\n\tdaddiu\t%@,%@,%%got_ofst(%0)";
8421 if (ISA_HAS_LOAD_DELAY)
8422 return "%[lw\t%@,%%got(%0)(%+)%#\n\taddiu\t%@,%@,%%lo(%0)";
8423 return "%[lw\t%@,%%got(%0)(%+)\n\taddiu\t%@,%@,%%lo(%0)";
8427 if (Pmode == DImode)
8428 return "%[dla\t%@,%0";
8430 return "%[la\t%@,%0";
8435 /* Output assembly instructions to peform a conditional branch.
8437 INSN is the branch instruction. OPERANDS[0] is the condition.
8438 OPERANDS[1] is the target of the branch. OPERANDS[2] is the target
8439 of the first operand to the condition. If TWO_OPERANDS_P is
8440 nonzero the comparison takes two operands; OPERANDS[3] will be the
8443 If INVERTED_P is nonzero we are to branch if the condition does
8444 not hold. If FLOAT_P is nonzero this is a floating-point comparison.
8446 LENGTH is the length (in bytes) of the sequence we are to generate.
8447 That tells us whether to generate a simple conditional branch, or a
8448 reversed conditional branch around a `jr' instruction. */
8450 mips_output_conditional_branch (rtx insn, rtx *operands, int two_operands_p,
8451 int float_p, int inverted_p, int length)
8453 static char buffer[200];
8454 /* The kind of comparison we are doing. */
8455 enum rtx_code code = GET_CODE (operands[0]);
8456 /* Nonzero if the opcode for the comparison needs a `z' indicating
8457 that it is a comparison against zero. */
8459 /* A string to use in the assembly output to represent the first
8461 const char *op1 = "%z2";
8462 /* A string to use in the assembly output to represent the second
8463 operand. Use the hard-wired zero register if there's no second
8465 const char *op2 = (two_operands_p ? ",%z3" : ",%.");
8466 /* The operand-printing string for the comparison. */
8467 const char *const comp = (float_p ? "%F0" : "%C0");
8468 /* The operand-printing string for the inverted comparison. */
8469 const char *const inverted_comp = (float_p ? "%W0" : "%N0");
8471 /* The MIPS processors (for levels of the ISA at least two), have
8472 "likely" variants of each branch instruction. These instructions
8473 annul the instruction in the delay slot if the branch is not
8475 mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
8477 if (!two_operands_p)
8479 /* To compute whether than A > B, for example, we normally
8480 subtract B from A and then look at the sign bit. But, if we
8481 are doing an unsigned comparison, and B is zero, we don't
8482 have to do the subtraction. Instead, we can just check to
8483 see if A is nonzero. Thus, we change the CODE here to
8484 reflect the simpler comparison operation. */
8496 /* A condition which will always be true. */
8502 /* A condition which will always be false. */
8508 /* Not a special case. */
8513 /* Relative comparisons are always done against zero. But
8514 equality comparisons are done between two operands, and therefore
8515 do not require a `z' in the assembly language output. */
8516 need_z_p = (!float_p && code != EQ && code != NE);
8517 /* For comparisons against zero, the zero is not provided
8522 /* Begin by terminating the buffer. That way we can always use
8523 strcat to add to it. */
8530 /* Just a simple conditional branch. */
8532 sprintf (buffer, "%%*b%s%%?\t%%Z2%%1%%/",
8533 inverted_p ? inverted_comp : comp);
8535 sprintf (buffer, "%%*b%s%s%%?\t%s%s,%%1%%/",
8536 inverted_p ? inverted_comp : comp,
8537 need_z_p ? "z" : "",
8547 /* Generate a reversed conditional branch around ` j'
8560 If the original branch was a likely branch, the delay slot
8561 must be executed only if the branch is taken, so generate:
8573 When generating PIC, instead of:
8586 rtx target = gen_label_rtx ();
8588 orig_target = operands[1];
8589 operands[1] = target;
8590 /* Generate the reversed comparison. This takes four
8593 sprintf (buffer, "%%*b%s\t%%Z2%%1",
8594 inverted_p ? comp : inverted_comp);
8596 sprintf (buffer, "%%*b%s%s\t%s%s,%%1",
8597 inverted_p ? comp : inverted_comp,
8598 need_z_p ? "z" : "",
8601 output_asm_insn (buffer, operands);
8603 if (length != 16 && length != 28 && ! mips_branch_likely)
8605 /* Output delay slot instruction. */
8606 rtx insn = final_sequence;
8607 final_scan_insn (XVECEXP (insn, 0, 1), asm_out_file,
8608 optimize, 0, 1, NULL);
8609 INSN_DELETED_P (XVECEXP (insn, 0, 1)) = 1;
8612 output_asm_insn ("%#", 0);
8615 output_asm_insn ("j\t%0", &orig_target);
8618 output_asm_insn (mips_output_load_label (), &orig_target);
8619 output_asm_insn ("jr\t%@%]", 0);
8622 if (length != 16 && length != 28 && mips_branch_likely)
8624 /* Output delay slot instruction. */
8625 rtx insn = final_sequence;
8626 final_scan_insn (XVECEXP (insn, 0, 1), asm_out_file,
8627 optimize, 0, 1, NULL);
8628 INSN_DELETED_P (XVECEXP (insn, 0, 1)) = 1;
8631 output_asm_insn ("%#", 0);
8633 (*targetm.asm_out.internal_label) (asm_out_file, "L",
8634 CODE_LABEL_NUMBER (target));
8647 /* Used to output div or ddiv instruction DIVISION, which has the operands
8648 given by OPERANDS. Add in a divide-by-zero check if needed.
8650 When working around R4000 and R4400 errata, we need to make sure that
8651 the division is not immediately followed by a shift[1][2]. We also
8652 need to stop the division from being put into a branch delay slot[3].
8653 The easiest way to avoid both problems is to add a nop after the
8654 division. When a divide-by-zero check is needed, this nop can be
8655 used to fill the branch delay slot.
8657 [1] If a double-word or a variable shift executes immediately
8658 after starting an integer division, the shift may give an
8659 incorrect result. See quotations of errata #16 and #28 from
8660 "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
8661 in mips.md for details.
8663 [2] A similar bug to [1] exists for all revisions of the
8664 R4000 and the R4400 when run in an MC configuration.
8665 From "MIPS R4000MC Errata, Processor Revision 2.2 and 3.0":
8667 "19. In this following sequence:
8669 ddiv (or ddivu or div or divu)
8670 dsll32 (or dsrl32, dsra32)
8672 if an MPT stall occurs, while the divide is slipping the cpu
8673 pipeline, then the following double shift would end up with an
8676 Workaround: The compiler needs to avoid generating any
8677 sequence with divide followed by extended double shift."
8679 This erratum is also present in "MIPS R4400MC Errata, Processor
8680 Revision 1.0" and "MIPS R4400MC Errata, Processor Revision 2.0
8681 & 3.0" as errata #10 and #4, respectively.
8683 [3] From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
8684 (also valid for MIPS R4000MC processors):
8686 "52. R4000SC: This bug does not apply for the R4000PC.
8688 There are two flavors of this bug:
8690 1) If the instruction just after divide takes an RF exception
8691 (tlb-refill, tlb-invalid) and gets an instruction cache
8692 miss (both primary and secondary) and the line which is
8693 currently in secondary cache at this index had the first
8694 data word, where the bits 5..2 are set, then R4000 would
8695 get a wrong result for the div.
8700 ------------------- # end-of page. -tlb-refill
8705 ------------------- # end-of page. -tlb-invalid
8708 2) If the divide is in the taken branch delay slot, where the
8709 target takes RF exception and gets an I-cache miss for the
8710 exception vector or where I-cache miss occurs for the
8711 target address, under the above mentioned scenarios, the
8712 div would get wrong results.
8715 j r2 # to next page mapped or unmapped
8716 div r8,r9 # this bug would be there as long
8717 # as there is an ICache miss and
8718 nop # the "data pattern" is present
8721 beq r0, r0, NextPage # to Next page
8725 This bug is present for div, divu, ddiv, and ddivu
8728 Workaround: For item 1), OS could make sure that the next page
8729 after the divide instruction is also mapped. For item 2), the
8730 compiler could make sure that the divide instruction is not in
8731 the branch delay slot."
8733 These processors have PRId values of 0x00004220 and 0x00004300 for
8734 the R4000 and 0x00004400, 0x00004500 and 0x00004600 for the R4400. */
8737 mips_output_division (const char *division, rtx *operands)
8742 if (TARGET_FIX_R4000 || TARGET_FIX_R4400)
8744 output_asm_insn (s, operands);
8747 if (TARGET_CHECK_ZERO_DIV)
8751 output_asm_insn (s, operands);
8752 s = "bnez\t%2,1f\n\tbreak\t7\n1:";
8756 output_asm_insn ("%(bne\t%2,%.,1f", operands);
8757 output_asm_insn (s, operands);
8758 s = "break\t7%)\n1:";
8764 /* Return true if GIVEN is the same as CANONICAL, or if it is CANONICAL
8765 with a final "000" replaced by "k". Ignore case.
8767 Note: this function is shared between GCC and GAS. */
8770 mips_strict_matching_cpu_name_p (const char *canonical, const char *given)
8772 while (*given != 0 && TOLOWER (*given) == TOLOWER (*canonical))
8773 given++, canonical++;
8775 return ((*given == 0 && *canonical == 0)
8776 || (strcmp (canonical, "000") == 0 && strcasecmp (given, "k") == 0));
8780 /* Return true if GIVEN matches CANONICAL, where GIVEN is a user-supplied
8781 CPU name. We've traditionally allowed a lot of variation here.
8783 Note: this function is shared between GCC and GAS. */
8786 mips_matching_cpu_name_p (const char *canonical, const char *given)
8788 /* First see if the name matches exactly, or with a final "000"
8790 if (mips_strict_matching_cpu_name_p (canonical, given))
8793 /* If not, try comparing based on numerical designation alone.
8794 See if GIVEN is an unadorned number, or 'r' followed by a number. */
8795 if (TOLOWER (*given) == 'r')
8797 if (!ISDIGIT (*given))
8800 /* Skip over some well-known prefixes in the canonical name,
8801 hoping to find a number there too. */
8802 if (TOLOWER (canonical[0]) == 'v' && TOLOWER (canonical[1]) == 'r')
8804 else if (TOLOWER (canonical[0]) == 'r' && TOLOWER (canonical[1]) == 'm')
8806 else if (TOLOWER (canonical[0]) == 'r')
8809 return mips_strict_matching_cpu_name_p (canonical, given);
8813 /* Parse an option that takes the name of a processor as its argument.
8814 OPTION is the name of the option and CPU_STRING is the argument.
8815 Return the corresponding processor enumeration if the CPU_STRING is
8816 recognized, otherwise report an error and return null.
8818 A similar function exists in GAS. */
8820 static const struct mips_cpu_info *
8821 mips_parse_cpu (const char *option, const char *cpu_string)
8823 const struct mips_cpu_info *p;
8826 /* In the past, we allowed upper-case CPU names, but it doesn't
8827 work well with the multilib machinery. */
8828 for (s = cpu_string; *s != 0; s++)
8831 warning ("the cpu name must be lower case");
8835 /* 'from-abi' selects the most compatible architecture for the given
8836 ABI: MIPS I for 32-bit ABIs and MIPS III for 64-bit ABIs. For the
8837 EABIs, we have to decide whether we're using the 32-bit or 64-bit
8838 version. Look first at the -mgp options, if given, otherwise base
8839 the choice on MASK_64BIT in TARGET_DEFAULT. */
8840 if (strcasecmp (cpu_string, "from-abi") == 0)
8841 return mips_cpu_info_from_isa (ABI_NEEDS_32BIT_REGS ? 1
8842 : ABI_NEEDS_64BIT_REGS ? 3
8843 : (TARGET_64BIT ? 3 : 1));
8845 /* 'default' has traditionally been a no-op. Probably not very useful. */
8846 if (strcasecmp (cpu_string, "default") == 0)
8849 for (p = mips_cpu_info_table; p->name != 0; p++)
8850 if (mips_matching_cpu_name_p (p->name, cpu_string))
8853 error ("bad value (%s) for %s", cpu_string, option);
8858 /* Return the processor associated with the given ISA level, or null
8859 if the ISA isn't valid. */
8861 static const struct mips_cpu_info *
8862 mips_cpu_info_from_isa (int isa)
8864 const struct mips_cpu_info *p;
8866 for (p = mips_cpu_info_table; p->name != 0; p++)
8873 /* Implement HARD_REGNO_NREGS. The size of FP registers is controlled
8874 by UNITS_PER_FPREG. The size of FP status registers is always 4, because
8875 they only hold condition code modes, and CCmode is always considered to
8876 be 4 bytes wide. All other registers are word sized. */
8879 mips_hard_regno_nregs (int regno, enum machine_mode mode)
8881 if (ST_REG_P (regno))
8882 return ((GET_MODE_SIZE (mode) + 3) / 4);
8883 else if (! FP_REG_P (regno))
8884 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
8886 return ((GET_MODE_SIZE (mode) + UNITS_PER_FPREG - 1) / UNITS_PER_FPREG);
8889 /* Implement TARGET_RETURN_IN_MEMORY. Under the old (i.e., 32 and O64 ABIs)
8890 all BLKmode objects are returned in memory. Under the new (N32 and
8891 64-bit MIPS ABIs) small structures are returned in a register.
8892 Objects with varying size must still be returned in memory, of
8896 mips_return_in_memory (tree type, tree fndecl ATTRIBUTE_UNUSED)
8899 return (TYPE_MODE (type) == BLKmode);
8901 return ((int_size_in_bytes (type) > (2 * UNITS_PER_WORD))
8902 || (int_size_in_bytes (type) == -1));
8906 mips_strict_argument_naming (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED)
8908 return !TARGET_OLDABI;
8911 /* Return true if INSN is a multiply-add or multiply-subtract
8912 instruction and PREV assigns to the accumulator operand. */
8915 mips_linked_madd_p (rtx prev, rtx insn)
8919 x = single_set (insn);
8925 if (GET_CODE (x) == PLUS
8926 && GET_CODE (XEXP (x, 0)) == MULT
8927 && reg_set_p (XEXP (x, 1), prev))
8930 if (GET_CODE (x) == MINUS
8931 && GET_CODE (XEXP (x, 1)) == MULT
8932 && reg_set_p (XEXP (x, 0), prev))
8938 /* Used by TUNE_MACC_CHAINS to record the last scheduled instruction
8939 that may clobber hi or lo. */
8941 static rtx mips_macc_chains_last_hilo;
8943 /* A TUNE_MACC_CHAINS helper function. Record that instruction INSN has
8944 been scheduled, updating mips_macc_chains_last_hilo appropriately. */
8947 mips_macc_chains_record (rtx insn)
8949 if (get_attr_may_clobber_hilo (insn))
8950 mips_macc_chains_last_hilo = insn;
8953 /* A TUNE_MACC_CHAINS helper function. Search ready queue READY, which
8954 has NREADY elements, looking for a multiply-add or multiply-subtract
8955 instruction that is cumulative with mips_macc_chains_last_hilo.
8956 If there is one, promote it ahead of anything else that might
8957 clobber hi or lo. */
8960 mips_macc_chains_reorder (rtx *ready, int nready)
8964 if (mips_macc_chains_last_hilo != 0)
8965 for (i = nready - 1; i >= 0; i--)
8966 if (mips_linked_madd_p (mips_macc_chains_last_hilo, ready[i]))
8968 for (j = nready - 1; j > i; j--)
8969 if (recog_memoized (ready[j]) >= 0
8970 && get_attr_may_clobber_hilo (ready[j]))
8972 mips_promote_ready (ready, i, j);
8979 /* The last instruction to be scheduled. */
8981 static rtx vr4130_last_insn;
8983 /* A note_stores callback used by vr4130_true_reg_dependence_p. DATA
8984 points to an rtx that is initially an instruction. Nullify the rtx
8985 if the instruction uses the value of register X. */
8988 vr4130_true_reg_dependence_p_1 (rtx x, rtx pat ATTRIBUTE_UNUSED, void *data)
8990 rtx *insn_ptr = data;
8993 && reg_referenced_p (x, PATTERN (*insn_ptr)))
8997 /* Return true if there is true register dependence between vr4130_last_insn
9001 vr4130_true_reg_dependence_p (rtx insn)
9003 note_stores (PATTERN (vr4130_last_insn),
9004 vr4130_true_reg_dependence_p_1, &insn);
9008 /* A TUNE_MIPS4130 helper function. Given that INSN1 is at the head of
9009 the ready queue and that INSN2 is the instruction after it, return
9010 true if it is worth promoting INSN2 ahead of INSN1. Look for cases
9011 in which INSN1 and INSN2 can probably issue in parallel, but for
9012 which (INSN2, INSN1) should be less sensitive to instruction
9013 alignment than (INSN1, INSN2). See 4130.md for more details. */
9016 vr4130_swap_insns_p (rtx insn1, rtx insn2)
9020 /* Check for the following case:
9022 1) there is some other instruction X with an anti dependence on INSN1;
9023 2) X has a higher priority than INSN2; and
9024 3) X is an arithmetic instruction (and thus has no unit restrictions).
9026 If INSN1 is the last instruction blocking X, it would better to
9027 choose (INSN1, X) over (INSN2, INSN1). */
9028 for (dep = INSN_DEPEND (insn1); dep != 0; dep = XEXP (dep, 1))
9029 if (REG_NOTE_KIND (dep) == REG_DEP_ANTI
9030 && INSN_PRIORITY (XEXP (dep, 0)) > INSN_PRIORITY (insn2)
9031 && recog_memoized (XEXP (dep, 0)) >= 0
9032 && get_attr_vr4130_class (XEXP (dep, 0)) == VR4130_CLASS_ALU)
9035 if (vr4130_last_insn != 0
9036 && recog_memoized (insn1) >= 0
9037 && recog_memoized (insn2) >= 0)
9039 /* See whether INSN1 and INSN2 use different execution units,
9040 or if they are both ALU-type instructions. If so, they can
9041 probably execute in parallel. */
9042 enum attr_vr4130_class class1 = get_attr_vr4130_class (insn1);
9043 enum attr_vr4130_class class2 = get_attr_vr4130_class (insn2);
9044 if (class1 != class2 || class1 == VR4130_CLASS_ALU)
9046 /* If only one of the instructions has a dependence on
9047 vr4130_last_insn, prefer to schedule the other one first. */
9048 bool dep1 = vr4130_true_reg_dependence_p (insn1);
9049 bool dep2 = vr4130_true_reg_dependence_p (insn2);
9053 /* Prefer to schedule INSN2 ahead of INSN1 if vr4130_last_insn
9054 is not an ALU-type instruction and if INSN1 uses the same
9055 execution unit. (Note that if this condition holds, we already
9056 know that INSN2 uses a different execution unit.) */
9057 if (class1 != VR4130_CLASS_ALU
9058 && recog_memoized (vr4130_last_insn) >= 0
9059 && class1 == get_attr_vr4130_class (vr4130_last_insn))
9066 /* A TUNE_MIPS4130 helper function. (READY, NREADY) describes a ready
9067 queue with at least two instructions. Swap the first two if
9068 vr4130_swap_insns_p says that it could be worthwhile. */
9071 vr4130_reorder (rtx *ready, int nready)
9073 if (vr4130_swap_insns_p (ready[nready - 1], ready[nready - 2]))
9074 mips_promote_ready (ready, nready - 2, nready - 1);
9077 /* Remove the instruction at index LOWER from ready queue READY and
9078 reinsert it in front of the instruction at index HIGHER. LOWER must
9082 mips_promote_ready (rtx *ready, int lower, int higher)
9087 new_head = ready[lower];
9088 for (i = lower; i < higher; i++)
9089 ready[i] = ready[i + 1];
9090 ready[i] = new_head;
9093 /* Implement TARGET_SCHED_REORDER. */
9096 mips_sched_reorder (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
9097 rtx *ready, int *nreadyp, int cycle)
9099 if (!reload_completed && TUNE_MACC_CHAINS)
9102 mips_macc_chains_last_hilo = 0;
9104 mips_macc_chains_reorder (ready, *nreadyp);
9106 if (reload_completed && TUNE_MIPS4130 && !TARGET_VR4130_ALIGN)
9109 vr4130_last_insn = 0;
9111 vr4130_reorder (ready, *nreadyp);
9113 return mips_issue_rate ();
9116 /* Implement TARGET_SCHED_VARIABLE_ISSUE. */
9119 mips_variable_issue (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
9122 switch (GET_CODE (PATTERN (insn)))
9126 /* Don't count USEs and CLOBBERs against the issue rate. */
9131 if (!reload_completed && TUNE_MACC_CHAINS)
9132 mips_macc_chains_record (insn);
9133 vr4130_last_insn = insn;
9139 /* Implement TARGET_SCHED_ADJUST_COST. We assume that anti and output
9140 dependencies have no cost. */
9143 mips_adjust_cost (rtx insn ATTRIBUTE_UNUSED, rtx link,
9144 rtx dep ATTRIBUTE_UNUSED, int cost)
9146 if (REG_NOTE_KIND (link) != 0)
9151 /* Return the number of instructions that can be issued per cycle. */
9154 mips_issue_rate (void)
9158 case PROCESSOR_R4130:
9159 case PROCESSOR_R5400:
9160 case PROCESSOR_R5500:
9161 case PROCESSOR_R7000:
9162 case PROCESSOR_R9000:
9166 /* This is actually 4, but we get better performance if we claim 3.
9167 This is partly because of unwanted speculative code motion with the
9168 larger number, and partly because in most common cases we can't
9169 reach the theoretical max of 4. */
9180 /* Implements TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD. This should
9181 be as wide as the scheduling freedom in the DFA. */
9184 mips_multipass_dfa_lookahead (void)
9186 /* Can schedule up to 4 of the 6 function units in any one cycle. */
9187 if (mips_tune == PROCESSOR_SB1)
9193 /* Given that we have an rtx of the form (prefetch ... WRITE LOCALITY),
9194 return the first operand of the associated "pref" or "prefx" insn. */
9197 mips_prefetch_cookie (rtx write, rtx locality)
9199 /* store_streamed / load_streamed. */
9200 if (INTVAL (locality) <= 0)
9201 return GEN_INT (INTVAL (write) + 4);
9204 if (INTVAL (locality) <= 2)
9207 /* store_retained / load_retained. */
9208 return GEN_INT (INTVAL (write) + 6);
9211 /* MIPS builtin function support. */
9213 struct builtin_description
9215 /* Instruction code. */
9216 enum insn_code icode;
9217 /* Builtin function name. */
9220 enum mips_builtins code;
9221 /* Function type. */
9222 enum mips_function_type ftype;
9223 /* The target flag required for this builtin function. */
9227 /* NOTE: The order of mips_bdesc[] must be the same as the order of
9228 enum mips_builtins{} in mips.h. */
9229 static const struct builtin_description mips_bdesc[] =
9231 { CODE_FOR_mips_pll_ps, "__builtin_mips_pll_ps", MIPS_BUILTIN_PLL_PS,
9232 MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
9233 { CODE_FOR_mips_pul_ps, "__builtin_mips_pul_ps", MIPS_BUILTIN_PUL_PS,
9234 MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
9235 { CODE_FOR_mips_plu_ps, "__builtin_mips_plu_ps", MIPS_BUILTIN_PLU_PS,
9236 MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
9237 { CODE_FOR_mips_puu_ps, "__builtin_mips_puu_ps", MIPS_BUILTIN_PUU_PS,
9238 MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
9239 { CODE_FOR_mips_cvt_ps_s, "__builtin_mips_cvt_ps_s", MIPS_BUILTIN_CVT_PS_S,
9240 MIPS_V2SF_FTYPE_SF_SF, MASK_PAIRED_SINGLE },
9241 { CODE_FOR_mips_cvt_s_pl, "__builtin_mips_cvt_s_pl", MIPS_BUILTIN_CVT_S_PL,
9242 MIPS_SF_FTYPE_V2SF, MASK_PAIRED_SINGLE },
9243 { CODE_FOR_mips_cvt_s_pu, "__builtin_mips_cvt_s_pu", MIPS_BUILTIN_CVT_S_PU,
9244 MIPS_SF_FTYPE_V2SF, MASK_PAIRED_SINGLE },
9245 { CODE_FOR_absv2sf2, "__builtin_mips_abs_ps", MIPS_BUILTIN_ABS_PS,
9246 MIPS_V2SF_FTYPE_V2SF, MASK_PAIRED_SINGLE },
9247 { CODE_FOR_mips_alnv_ps, "__builtin_mips_alnv_ps", MIPS_BUILTIN_ALNV_PS,
9248 MIPS_V2SF_FTYPE_V2SF_V2SF_INT, MASK_PAIRED_SINGLE },
9250 { CODE_FOR_mips_addr_ps, "__builtin_mips_addr_ps", MIPS_BUILTIN_ADDR_PS,
9251 MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9252 { CODE_FOR_mips_mulr_ps, "__builtin_mips_mulr_ps", MIPS_BUILTIN_MULR_PS,
9253 MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9254 { CODE_FOR_mips_cvt_pw_ps, "__builtin_mips_cvt_pw_ps",
9255 MIPS_BUILTIN_CVT_PW_PS, MIPS_V2SF_FTYPE_V2SF, MASK_MIPS3D },
9256 { CODE_FOR_mips_cvt_ps_pw, "__builtin_mips_cvt_ps_pw",
9257 MIPS_BUILTIN_CVT_PS_PW, MIPS_V2SF_FTYPE_V2SF, MASK_MIPS3D },
9259 { CODE_FOR_mips_recip1_s, "__builtin_mips_recip1_s", MIPS_BUILTIN_RECIP1_S,
9260 MIPS_SF_FTYPE_SF, MASK_MIPS3D },
9261 { CODE_FOR_mips_recip1_d, "__builtin_mips_recip1_d", MIPS_BUILTIN_RECIP1_D,
9262 MIPS_DF_FTYPE_DF, MASK_MIPS3D },
9263 { CODE_FOR_mips_recip1_ps, "__builtin_mips_recip1_ps",
9264 MIPS_BUILTIN_RECIP1_PS, MIPS_V2SF_FTYPE_V2SF, MASK_MIPS3D },
9265 { CODE_FOR_mips_recip2_s, "__builtin_mips_recip2_s", MIPS_BUILTIN_RECIP2_S,
9266 MIPS_SF_FTYPE_SF_SF, MASK_MIPS3D },
9267 { CODE_FOR_mips_recip2_d, "__builtin_mips_recip2_d", MIPS_BUILTIN_RECIP2_D,
9268 MIPS_DF_FTYPE_DF_DF, MASK_MIPS3D },
9269 { CODE_FOR_mips_recip2_ps, "__builtin_mips_recip2_ps",
9270 MIPS_BUILTIN_RECIP2_PS, MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9272 { CODE_FOR_mips_rsqrt1_s, "__builtin_mips_rsqrt1_s", MIPS_BUILTIN_RSQRT1_S,
9273 MIPS_SF_FTYPE_SF, MASK_MIPS3D },
9274 { CODE_FOR_mips_rsqrt1_d, "__builtin_mips_rsqrt1_d", MIPS_BUILTIN_RSQRT1_D,
9275 MIPS_DF_FTYPE_DF, MASK_MIPS3D },
9276 { CODE_FOR_mips_rsqrt1_ps, "__builtin_mips_rsqrt1_ps",
9277 MIPS_BUILTIN_RSQRT1_PS, MIPS_V2SF_FTYPE_V2SF, MASK_MIPS3D },
9278 { CODE_FOR_mips_rsqrt2_s, "__builtin_mips_rsqrt2_s", MIPS_BUILTIN_RSQRT2_S,
9279 MIPS_SF_FTYPE_SF_SF, MASK_MIPS3D },
9280 { CODE_FOR_mips_rsqrt2_d, "__builtin_mips_rsqrt2_d", MIPS_BUILTIN_RSQRT2_D,
9281 MIPS_DF_FTYPE_DF_DF, MASK_MIPS3D },
9282 { CODE_FOR_mips_rsqrt2_ps, "__builtin_mips_rsqrt2_ps",
9283 MIPS_BUILTIN_RSQRT2_PS, MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9285 { CODE_FOR_mips_c_f_ps, "__builtin_mips_any_c_f_ps", MIPS_BUILTIN_ANY_C_F_PS,
9286 MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9287 { CODE_FOR_mips_c_f_ps, "__builtin_mips_upper_c_f_ps",
9288 MIPS_BUILTIN_UPPER_C_F_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
9289 { CODE_FOR_mips_c_f_ps, "__builtin_mips_lower_c_f_ps",
9290 MIPS_BUILTIN_LOWER_C_F_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
9291 { CODE_FOR_mips_c_f_ps, "__builtin_mips_all_c_f_ps", MIPS_BUILTIN_ALL_C_F_PS,
9292 MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9293 { CODE_FOR_mips_c_un_ps, "__builtin_mips_any_c_un_ps",
9294 MIPS_BUILTIN_ANY_C_UN_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9295 { CODE_FOR_mips_c_un_ps, "__builtin_mips_upper_c_un_ps",
9296 MIPS_BUILTIN_UPPER_C_UN_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
9297 { CODE_FOR_mips_c_un_ps, "__builtin_mips_lower_c_un_ps",
9298 MIPS_BUILTIN_LOWER_C_UN_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
9299 { CODE_FOR_mips_c_un_ps, "__builtin_mips_all_c_un_ps",
9300 MIPS_BUILTIN_ALL_C_UN_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9301 { CODE_FOR_mips_c_eq_ps, "__builtin_mips_any_c_eq_ps",
9302 MIPS_BUILTIN_ANY_C_EQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9303 { CODE_FOR_mips_c_eq_ps, "__builtin_mips_upper_c_eq_ps",
9304 MIPS_BUILTIN_UPPER_C_EQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
9305 { CODE_FOR_mips_c_eq_ps, "__builtin_mips_lower_c_eq_ps",
9306 MIPS_BUILTIN_LOWER_C_EQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
9307 { CODE_FOR_mips_c_eq_ps, "__builtin_mips_all_c_eq_ps",
9308 MIPS_BUILTIN_ALL_C_EQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9309 { CODE_FOR_mips_c_ueq_ps, "__builtin_mips_any_c_ueq_ps",
9310 MIPS_BUILTIN_ANY_C_UEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9311 { CODE_FOR_mips_c_ueq_ps, "__builtin_mips_upper_c_ueq_ps",
9312 MIPS_BUILTIN_UPPER_C_UEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF,
9313 MASK_PAIRED_SINGLE },
9314 { CODE_FOR_mips_c_ueq_ps, "__builtin_mips_lower_c_ueq_ps",
9315 MIPS_BUILTIN_LOWER_C_UEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF,
9316 MASK_PAIRED_SINGLE },
9317 { CODE_FOR_mips_c_ueq_ps, "__builtin_mips_all_c_ueq_ps",
9318 MIPS_BUILTIN_ALL_C_UEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9319 { CODE_FOR_mips_c_olt_ps, "__builtin_mips_any_c_olt_ps",
9320 MIPS_BUILTIN_ANY_C_OLT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9321 { CODE_FOR_mips_c_olt_ps, "__builtin_mips_upper_c_olt_ps",
9322 MIPS_BUILTIN_UPPER_C_OLT_PS, MIPS_INT_FTYPE_V2SF_V2SF,
9323 MASK_PAIRED_SINGLE },
9324 { CODE_FOR_mips_c_olt_ps, "__builtin_mips_lower_c_olt_ps",
9325 MIPS_BUILTIN_LOWER_C_OLT_PS, MIPS_INT_FTYPE_V2SF_V2SF,
9326 MASK_PAIRED_SINGLE },
9327 { CODE_FOR_mips_c_olt_ps, "__builtin_mips_all_c_olt_ps",
9328 MIPS_BUILTIN_ALL_C_OLT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9329 { CODE_FOR_mips_c_ult_ps, "__builtin_mips_any_c_ult_ps",
9330 MIPS_BUILTIN_ANY_C_ULT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9331 { CODE_FOR_mips_c_ult_ps, "__builtin_mips_upper_c_ult_ps",
9332 MIPS_BUILTIN_UPPER_C_ULT_PS, MIPS_INT_FTYPE_V2SF_V2SF,
9333 MASK_PAIRED_SINGLE },
9334 { CODE_FOR_mips_c_ult_ps, "__builtin_mips_lower_c_ult_ps",
9335 MIPS_BUILTIN_LOWER_C_ULT_PS, MIPS_INT_FTYPE_V2SF_V2SF,
9336 MASK_PAIRED_SINGLE },
9337 { CODE_FOR_mips_c_ult_ps, "__builtin_mips_all_c_ult_ps",
9338 MIPS_BUILTIN_ALL_C_ULT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9339 { CODE_FOR_mips_c_ole_ps, "__builtin_mips_any_c_ole_ps",
9340 MIPS_BUILTIN_ANY_C_OLE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9341 { CODE_FOR_mips_c_ole_ps, "__builtin_mips_upper_c_ole_ps",
9342 MIPS_BUILTIN_UPPER_C_OLE_PS, MIPS_INT_FTYPE_V2SF_V2SF,
9343 MASK_PAIRED_SINGLE },
9344 { CODE_FOR_mips_c_ole_ps, "__builtin_mips_lower_c_ole_ps",
9345 MIPS_BUILTIN_LOWER_C_OLE_PS, MIPS_INT_FTYPE_V2SF_V2SF,
9346 MASK_PAIRED_SINGLE },
9347 { CODE_FOR_mips_c_ole_ps, "__builtin_mips_all_c_ole_ps",
9348 MIPS_BUILTIN_ALL_C_OLE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9349 { CODE_FOR_mips_c_ule_ps, "__builtin_mips_any_c_ule_ps",
9350 MIPS_BUILTIN_ANY_C_ULE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9351 { CODE_FOR_mips_c_ule_ps, "__builtin_mips_upper_c_ule_ps",
9352 MIPS_BUILTIN_UPPER_C_ULE_PS, MIPS_INT_FTYPE_V2SF_V2SF,
9353 MASK_PAIRED_SINGLE },
9354 { CODE_FOR_mips_c_ule_ps, "__builtin_mips_lower_c_ule_ps",
9355 MIPS_BUILTIN_LOWER_C_ULE_PS, MIPS_INT_FTYPE_V2SF_V2SF,
9356 MASK_PAIRED_SINGLE },
9357 { CODE_FOR_mips_c_ule_ps, "__builtin_mips_all_c_ule_ps",
9358 MIPS_BUILTIN_ALL_C_ULE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9359 { CODE_FOR_mips_c_sf_ps, "__builtin_mips_any_c_sf_ps",
9360 MIPS_BUILTIN_ANY_C_SF_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9361 { CODE_FOR_mips_c_sf_ps, "__builtin_mips_upper_c_sf_ps",
9362 MIPS_BUILTIN_UPPER_C_SF_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
9363 { CODE_FOR_mips_c_sf_ps, "__builtin_mips_lower_c_sf_ps",
9364 MIPS_BUILTIN_LOWER_C_SF_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
9365 { CODE_FOR_mips_c_sf_ps, "__builtin_mips_all_c_sf_ps",
9366 MIPS_BUILTIN_ALL_C_SF_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9367 { CODE_FOR_mips_c_ngle_ps, "__builtin_mips_any_c_ngle_ps",
9368 MIPS_BUILTIN_ANY_C_NGLE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9369 { CODE_FOR_mips_c_ngle_ps, "__builtin_mips_upper_c_ngle_ps",
9370 MIPS_BUILTIN_UPPER_C_NGLE_PS, MIPS_INT_FTYPE_V2SF_V2SF,
9371 MASK_PAIRED_SINGLE },
9372 { CODE_FOR_mips_c_ngle_ps, "__builtin_mips_lower_c_ngle_ps",
9373 MIPS_BUILTIN_LOWER_C_NGLE_PS, MIPS_INT_FTYPE_V2SF_V2SF,
9374 MASK_PAIRED_SINGLE },
9375 { CODE_FOR_mips_c_ngle_ps, "__builtin_mips_all_c_ngle_ps",
9376 MIPS_BUILTIN_ALL_C_NGLE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9377 { CODE_FOR_mips_c_seq_ps, "__builtin_mips_any_c_seq_ps",
9378 MIPS_BUILTIN_ANY_C_SEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9379 { CODE_FOR_mips_c_seq_ps, "__builtin_mips_upper_c_seq_ps",
9380 MIPS_BUILTIN_UPPER_C_SEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF,
9381 MASK_PAIRED_SINGLE },
9382 { CODE_FOR_mips_c_seq_ps, "__builtin_mips_lower_c_seq_ps",
9383 MIPS_BUILTIN_LOWER_C_SEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF,
9384 MASK_PAIRED_SINGLE },
9385 { CODE_FOR_mips_c_seq_ps, "__builtin_mips_all_c_seq_ps",
9386 MIPS_BUILTIN_ALL_C_SEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9387 { CODE_FOR_mips_c_ngl_ps, "__builtin_mips_any_c_ngl_ps",
9388 MIPS_BUILTIN_ANY_C_NGL_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9389 { CODE_FOR_mips_c_ngl_ps, "__builtin_mips_upper_c_ngl_ps",
9390 MIPS_BUILTIN_UPPER_C_NGL_PS, MIPS_INT_FTYPE_V2SF_V2SF,
9391 MASK_PAIRED_SINGLE },
9392 { CODE_FOR_mips_c_ngl_ps, "__builtin_mips_lower_c_ngl_ps",
9393 MIPS_BUILTIN_LOWER_C_NGL_PS, MIPS_INT_FTYPE_V2SF_V2SF,
9394 MASK_PAIRED_SINGLE },
9395 { CODE_FOR_mips_c_ngl_ps, "__builtin_mips_all_c_ngl_ps",
9396 MIPS_BUILTIN_ALL_C_NGL_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9397 { CODE_FOR_mips_c_lt_ps, "__builtin_mips_any_c_lt_ps",
9398 MIPS_BUILTIN_ANY_C_LT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9399 { CODE_FOR_mips_c_lt_ps, "__builtin_mips_upper_c_lt_ps",
9400 MIPS_BUILTIN_UPPER_C_LT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
9401 { CODE_FOR_mips_c_lt_ps, "__builtin_mips_lower_c_lt_ps",
9402 MIPS_BUILTIN_LOWER_C_LT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
9403 { CODE_FOR_mips_c_lt_ps, "__builtin_mips_all_c_lt_ps",
9404 MIPS_BUILTIN_ALL_C_LT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9405 { CODE_FOR_mips_c_nge_ps, "__builtin_mips_any_c_nge_ps",
9406 MIPS_BUILTIN_ANY_C_NGE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9407 { CODE_FOR_mips_c_nge_ps, "__builtin_mips_upper_c_nge_ps",
9408 MIPS_BUILTIN_UPPER_C_NGE_PS, MIPS_INT_FTYPE_V2SF_V2SF,
9409 MASK_PAIRED_SINGLE },
9410 { CODE_FOR_mips_c_nge_ps, "__builtin_mips_lower_c_nge_ps",
9411 MIPS_BUILTIN_LOWER_C_NGE_PS, MIPS_INT_FTYPE_V2SF_V2SF,
9412 MASK_PAIRED_SINGLE },
9413 { CODE_FOR_mips_c_nge_ps, "__builtin_mips_all_c_nge_ps",
9414 MIPS_BUILTIN_ALL_C_NGE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9415 { CODE_FOR_mips_c_le_ps, "__builtin_mips_any_c_le_ps",
9416 MIPS_BUILTIN_ANY_C_LE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9417 { CODE_FOR_mips_c_le_ps, "__builtin_mips_upper_c_le_ps",
9418 MIPS_BUILTIN_UPPER_C_LE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
9419 { CODE_FOR_mips_c_le_ps, "__builtin_mips_lower_c_le_ps",
9420 MIPS_BUILTIN_LOWER_C_LE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE },
9421 { CODE_FOR_mips_c_le_ps, "__builtin_mips_all_c_le_ps",
9422 MIPS_BUILTIN_ALL_C_LE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9423 { CODE_FOR_mips_c_ngt_ps, "__builtin_mips_any_c_ngt_ps",
9424 MIPS_BUILTIN_ANY_C_NGT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9425 { CODE_FOR_mips_c_ngt_ps, "__builtin_mips_upper_c_ngt_ps",
9426 MIPS_BUILTIN_UPPER_C_NGT_PS, MIPS_INT_FTYPE_V2SF_V2SF,
9427 MASK_PAIRED_SINGLE },
9428 { CODE_FOR_mips_c_ngt_ps, "__builtin_mips_lower_c_ngt_ps",
9429 MIPS_BUILTIN_LOWER_C_NGT_PS, MIPS_INT_FTYPE_V2SF_V2SF,
9430 MASK_PAIRED_SINGLE },
9431 { CODE_FOR_mips_c_ngt_ps, "__builtin_mips_all_c_ngt_ps",
9432 MIPS_BUILTIN_ALL_C_NGT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9434 { CODE_FOR_mips_cabs_f_ps, "__builtin_mips_any_cabs_f_ps",
9435 MIPS_BUILTIN_ANY_CABS_F_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9436 { CODE_FOR_mips_cabs_f_ps, "__builtin_mips_upper_cabs_f_ps",
9437 MIPS_BUILTIN_UPPER_CABS_F_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9438 { CODE_FOR_mips_cabs_f_ps, "__builtin_mips_lower_cabs_f_ps",
9439 MIPS_BUILTIN_LOWER_CABS_F_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9440 { CODE_FOR_mips_cabs_f_ps, "__builtin_mips_all_cabs_f_ps",
9441 MIPS_BUILTIN_ALL_CABS_F_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9442 { CODE_FOR_mips_cabs_un_ps, "__builtin_mips_any_cabs_un_ps",
9443 MIPS_BUILTIN_ANY_CABS_UN_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9444 { CODE_FOR_mips_cabs_un_ps, "__builtin_mips_upper_cabs_un_ps",
9445 MIPS_BUILTIN_UPPER_CABS_UN_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9446 { CODE_FOR_mips_cabs_un_ps, "__builtin_mips_lower_cabs_un_ps",
9447 MIPS_BUILTIN_LOWER_CABS_UN_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9448 { CODE_FOR_mips_cabs_un_ps, "__builtin_mips_all_cabs_un_ps",
9449 MIPS_BUILTIN_ALL_CABS_UN_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9450 { CODE_FOR_mips_cabs_eq_ps, "__builtin_mips_any_cabs_eq_ps",
9451 MIPS_BUILTIN_ANY_CABS_EQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9452 { CODE_FOR_mips_cabs_eq_ps, "__builtin_mips_upper_cabs_eq_ps",
9453 MIPS_BUILTIN_UPPER_CABS_EQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9454 { CODE_FOR_mips_cabs_eq_ps, "__builtin_mips_lower_cabs_eq_ps",
9455 MIPS_BUILTIN_LOWER_CABS_EQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9456 { CODE_FOR_mips_cabs_eq_ps, "__builtin_mips_all_cabs_eq_ps",
9457 MIPS_BUILTIN_ALL_CABS_EQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9458 { CODE_FOR_mips_cabs_ueq_ps, "__builtin_mips_any_cabs_ueq_ps",
9459 MIPS_BUILTIN_ANY_CABS_UEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9460 { CODE_FOR_mips_cabs_ueq_ps, "__builtin_mips_upper_cabs_ueq_ps",
9461 MIPS_BUILTIN_UPPER_CABS_UEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9462 { CODE_FOR_mips_cabs_ueq_ps, "__builtin_mips_lower_cabs_ueq_ps",
9463 MIPS_BUILTIN_LOWER_CABS_UEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9464 { CODE_FOR_mips_cabs_ueq_ps, "__builtin_mips_all_cabs_ueq_ps",
9465 MIPS_BUILTIN_ALL_CABS_UEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9466 { CODE_FOR_mips_cabs_olt_ps, "__builtin_mips_any_cabs_olt_ps",
9467 MIPS_BUILTIN_ANY_CABS_OLT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9468 { CODE_FOR_mips_cabs_olt_ps, "__builtin_mips_upper_cabs_olt_ps",
9469 MIPS_BUILTIN_UPPER_CABS_OLT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9470 { CODE_FOR_mips_cabs_olt_ps, "__builtin_mips_lower_cabs_olt_ps",
9471 MIPS_BUILTIN_LOWER_CABS_OLT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9472 { CODE_FOR_mips_cabs_olt_ps, "__builtin_mips_all_cabs_olt_ps",
9473 MIPS_BUILTIN_ALL_CABS_OLT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9474 { CODE_FOR_mips_cabs_ult_ps, "__builtin_mips_any_cabs_ult_ps",
9475 MIPS_BUILTIN_ANY_CABS_ULT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9476 { CODE_FOR_mips_cabs_ult_ps, "__builtin_mips_upper_cabs_ult_ps",
9477 MIPS_BUILTIN_UPPER_CABS_ULT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9478 { CODE_FOR_mips_cabs_ult_ps, "__builtin_mips_lower_cabs_ult_ps",
9479 MIPS_BUILTIN_LOWER_CABS_ULT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9480 { CODE_FOR_mips_cabs_ult_ps, "__builtin_mips_all_cabs_ult_ps",
9481 MIPS_BUILTIN_ALL_CABS_ULT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9482 { CODE_FOR_mips_cabs_ole_ps, "__builtin_mips_any_cabs_ole_ps",
9483 MIPS_BUILTIN_ANY_CABS_OLE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9484 { CODE_FOR_mips_cabs_ole_ps, "__builtin_mips_upper_cabs_ole_ps",
9485 MIPS_BUILTIN_UPPER_CABS_OLE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9486 { CODE_FOR_mips_cabs_ole_ps, "__builtin_mips_lower_cabs_ole_ps",
9487 MIPS_BUILTIN_LOWER_CABS_OLE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9488 { CODE_FOR_mips_cabs_ole_ps, "__builtin_mips_all_cabs_ole_ps",
9489 MIPS_BUILTIN_ALL_CABS_OLE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9490 { CODE_FOR_mips_cabs_ule_ps, "__builtin_mips_any_cabs_ule_ps",
9491 MIPS_BUILTIN_ANY_CABS_ULE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9492 { CODE_FOR_mips_cabs_ule_ps, "__builtin_mips_upper_cabs_ule_ps",
9493 MIPS_BUILTIN_UPPER_CABS_ULE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9494 { CODE_FOR_mips_cabs_ule_ps, "__builtin_mips_lower_cabs_ule_ps",
9495 MIPS_BUILTIN_LOWER_CABS_ULE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9496 { CODE_FOR_mips_cabs_ule_ps, "__builtin_mips_all_cabs_ule_ps",
9497 MIPS_BUILTIN_ALL_CABS_ULE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9498 { CODE_FOR_mips_cabs_sf_ps, "__builtin_mips_any_cabs_sf_ps",
9499 MIPS_BUILTIN_ANY_CABS_SF_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9500 { CODE_FOR_mips_cabs_sf_ps, "__builtin_mips_upper_cabs_sf_ps",
9501 MIPS_BUILTIN_UPPER_CABS_SF_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9502 { CODE_FOR_mips_cabs_sf_ps, "__builtin_mips_lower_cabs_sf_ps",
9503 MIPS_BUILTIN_LOWER_CABS_SF_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9504 { CODE_FOR_mips_cabs_sf_ps, "__builtin_mips_all_cabs_sf_ps",
9505 MIPS_BUILTIN_ALL_CABS_SF_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9506 { CODE_FOR_mips_cabs_ngle_ps, "__builtin_mips_any_cabs_ngle_ps",
9507 MIPS_BUILTIN_ANY_CABS_NGLE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9508 { CODE_FOR_mips_cabs_ngle_ps, "__builtin_mips_upper_cabs_ngle_ps",
9509 MIPS_BUILTIN_UPPER_CABS_NGLE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9510 { CODE_FOR_mips_cabs_ngle_ps, "__builtin_mips_lower_cabs_ngle_ps",
9511 MIPS_BUILTIN_LOWER_CABS_NGLE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9512 { CODE_FOR_mips_cabs_ngle_ps, "__builtin_mips_all_cabs_ngle_ps",
9513 MIPS_BUILTIN_ALL_CABS_NGLE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9514 { CODE_FOR_mips_cabs_seq_ps, "__builtin_mips_any_cabs_seq_ps",
9515 MIPS_BUILTIN_ANY_CABS_SEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9516 { CODE_FOR_mips_cabs_seq_ps, "__builtin_mips_upper_cabs_seq_ps",
9517 MIPS_BUILTIN_UPPER_CABS_SEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9518 { CODE_FOR_mips_cabs_seq_ps, "__builtin_mips_lower_cabs_seq_ps",
9519 MIPS_BUILTIN_LOWER_CABS_SEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9520 { CODE_FOR_mips_cabs_seq_ps, "__builtin_mips_all_cabs_seq_ps",
9521 MIPS_BUILTIN_ALL_CABS_SEQ_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9522 { CODE_FOR_mips_cabs_ngl_ps, "__builtin_mips_any_cabs_ngl_ps",
9523 MIPS_BUILTIN_ANY_CABS_NGL_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9524 { CODE_FOR_mips_cabs_ngl_ps, "__builtin_mips_upper_cabs_ngl_ps",
9525 MIPS_BUILTIN_UPPER_CABS_NGL_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9526 { CODE_FOR_mips_cabs_ngl_ps, "__builtin_mips_lower_cabs_ngl_ps",
9527 MIPS_BUILTIN_LOWER_CABS_NGL_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9528 { CODE_FOR_mips_cabs_ngl_ps, "__builtin_mips_all_cabs_ngl_ps",
9529 MIPS_BUILTIN_ALL_CABS_NGL_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9530 { CODE_FOR_mips_cabs_lt_ps, "__builtin_mips_any_cabs_lt_ps",
9531 MIPS_BUILTIN_ANY_CABS_LT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9532 { CODE_FOR_mips_cabs_lt_ps, "__builtin_mips_upper_cabs_lt_ps",
9533 MIPS_BUILTIN_UPPER_CABS_LT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9534 { CODE_FOR_mips_cabs_lt_ps, "__builtin_mips_lower_cabs_lt_ps",
9535 MIPS_BUILTIN_LOWER_CABS_LT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9536 { CODE_FOR_mips_cabs_lt_ps, "__builtin_mips_all_cabs_lt_ps",
9537 MIPS_BUILTIN_ALL_CABS_LT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9538 { CODE_FOR_mips_cabs_nge_ps, "__builtin_mips_any_cabs_nge_ps",
9539 MIPS_BUILTIN_ANY_CABS_NGE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9540 { CODE_FOR_mips_cabs_nge_ps, "__builtin_mips_upper_cabs_nge_ps",
9541 MIPS_BUILTIN_UPPER_CABS_NGE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9542 { CODE_FOR_mips_cabs_nge_ps, "__builtin_mips_lower_cabs_nge_ps",
9543 MIPS_BUILTIN_LOWER_CABS_NGE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9544 { CODE_FOR_mips_cabs_nge_ps, "__builtin_mips_all_cabs_nge_ps",
9545 MIPS_BUILTIN_ALL_CABS_NGE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9546 { CODE_FOR_mips_cabs_le_ps, "__builtin_mips_any_cabs_le_ps",
9547 MIPS_BUILTIN_ANY_CABS_LE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9548 { CODE_FOR_mips_cabs_le_ps, "__builtin_mips_upper_cabs_le_ps",
9549 MIPS_BUILTIN_UPPER_CABS_LE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9550 { CODE_FOR_mips_cabs_le_ps, "__builtin_mips_lower_cabs_le_ps",
9551 MIPS_BUILTIN_LOWER_CABS_LE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9552 { CODE_FOR_mips_cabs_le_ps, "__builtin_mips_all_cabs_le_ps",
9553 MIPS_BUILTIN_ALL_CABS_LE_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9554 { CODE_FOR_mips_cabs_ngt_ps, "__builtin_mips_any_cabs_ngt_ps",
9555 MIPS_BUILTIN_ANY_CABS_NGT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9556 { CODE_FOR_mips_cabs_ngt_ps, "__builtin_mips_upper_cabs_ngt_ps",
9557 MIPS_BUILTIN_UPPER_CABS_NGT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9558 { CODE_FOR_mips_cabs_ngt_ps, "__builtin_mips_lower_cabs_ngt_ps",
9559 MIPS_BUILTIN_LOWER_CABS_NGT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9560 { CODE_FOR_mips_cabs_ngt_ps, "__builtin_mips_all_cabs_ngt_ps",
9561 MIPS_BUILTIN_ALL_CABS_NGT_PS, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },
9563 { CODE_FOR_mips_c_f_4s, "__builtin_mips_any_c_f_4s",
9564 MIPS_BUILTIN_ANY_C_F_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF, MASK_MIPS3D },
9565 { CODE_FOR_mips_c_f_4s, "__builtin_mips_all_c_f_4s",
9566 MIPS_BUILTIN_ALL_C_F_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF, MASK_MIPS3D },
9567 { CODE_FOR_mips_c_un_4s, "__builtin_mips_any_c_un_4s",
9568 MIPS_BUILTIN_ANY_C_UN_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9570 { CODE_FOR_mips_c_un_4s, "__builtin_mips_all_c_un_4s",
9571 MIPS_BUILTIN_ALL_C_UN_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9573 { CODE_FOR_mips_c_eq_4s, "__builtin_mips_any_c_eq_4s",
9574 MIPS_BUILTIN_ANY_C_EQ_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9576 { CODE_FOR_mips_c_eq_4s, "__builtin_mips_all_c_eq_4s",
9577 MIPS_BUILTIN_ALL_C_EQ_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9579 { CODE_FOR_mips_c_ueq_4s, "__builtin_mips_any_c_ueq_4s",
9580 MIPS_BUILTIN_ANY_C_UEQ_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9582 { CODE_FOR_mips_c_ueq_4s, "__builtin_mips_all_c_ueq_4s",
9583 MIPS_BUILTIN_ALL_C_UEQ_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9585 { CODE_FOR_mips_c_olt_4s, "__builtin_mips_any_c_olt_4s",
9586 MIPS_BUILTIN_ANY_C_OLT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9588 { CODE_FOR_mips_c_olt_4s, "__builtin_mips_all_c_olt_4s",
9589 MIPS_BUILTIN_ALL_C_OLT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9591 { CODE_FOR_mips_c_ult_4s, "__builtin_mips_any_c_ult_4s",
9592 MIPS_BUILTIN_ANY_C_ULT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9594 { CODE_FOR_mips_c_ult_4s, "__builtin_mips_all_c_ult_4s",
9595 MIPS_BUILTIN_ALL_C_ULT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9597 { CODE_FOR_mips_c_ole_4s, "__builtin_mips_any_c_ole_4s",
9598 MIPS_BUILTIN_ANY_C_OLE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9600 { CODE_FOR_mips_c_ole_4s, "__builtin_mips_all_c_ole_4s",
9601 MIPS_BUILTIN_ALL_C_OLE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9603 { CODE_FOR_mips_c_ule_4s, "__builtin_mips_any_c_ule_4s",
9604 MIPS_BUILTIN_ANY_C_ULE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9606 { CODE_FOR_mips_c_ule_4s, "__builtin_mips_all_c_ule_4s",
9607 MIPS_BUILTIN_ALL_C_ULE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9609 { CODE_FOR_mips_c_sf_4s, "__builtin_mips_any_c_sf_4s",
9610 MIPS_BUILTIN_ANY_C_SF_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9612 { CODE_FOR_mips_c_sf_4s, "__builtin_mips_all_c_sf_4s",
9613 MIPS_BUILTIN_ALL_C_SF_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9615 { CODE_FOR_mips_c_ngle_4s, "__builtin_mips_any_c_ngle_4s",
9616 MIPS_BUILTIN_ANY_C_NGLE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9618 { CODE_FOR_mips_c_ngle_4s, "__builtin_mips_all_c_ngle_4s",
9619 MIPS_BUILTIN_ALL_C_NGLE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9621 { CODE_FOR_mips_c_seq_4s, "__builtin_mips_any_c_seq_4s",
9622 MIPS_BUILTIN_ANY_C_SEQ_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9624 { CODE_FOR_mips_c_seq_4s, "__builtin_mips_all_c_seq_4s",
9625 MIPS_BUILTIN_ALL_C_SEQ_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9627 { CODE_FOR_mips_c_ngl_4s, "__builtin_mips_any_c_ngl_4s",
9628 MIPS_BUILTIN_ANY_C_NGL_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9630 { CODE_FOR_mips_c_ngl_4s, "__builtin_mips_all_c_ngl_4s",
9631 MIPS_BUILTIN_ALL_C_NGL_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9633 { CODE_FOR_mips_c_lt_4s, "__builtin_mips_any_c_lt_4s",
9634 MIPS_BUILTIN_ANY_C_LT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9636 { CODE_FOR_mips_c_lt_4s, "__builtin_mips_all_c_lt_4s",
9637 MIPS_BUILTIN_ALL_C_LT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9639 { CODE_FOR_mips_c_nge_4s, "__builtin_mips_any_c_nge_4s",
9640 MIPS_BUILTIN_ANY_C_NGE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9642 { CODE_FOR_mips_c_nge_4s, "__builtin_mips_all_c_nge_4s",
9643 MIPS_BUILTIN_ALL_C_NGE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9645 { CODE_FOR_mips_c_le_4s, "__builtin_mips_any_c_le_4s",
9646 MIPS_BUILTIN_ANY_C_LE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9648 { CODE_FOR_mips_c_le_4s, "__builtin_mips_all_c_le_4s",
9649 MIPS_BUILTIN_ALL_C_LE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9651 { CODE_FOR_mips_c_ngt_4s, "__builtin_mips_any_c_ngt_4s",
9652 MIPS_BUILTIN_ANY_C_NGT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9654 { CODE_FOR_mips_c_ngt_4s, "__builtin_mips_all_c_ngt_4s",
9655 MIPS_BUILTIN_ALL_C_NGT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9658 { CODE_FOR_mips_cabs_f_4s, "__builtin_mips_any_cabs_f_4s",
9659 MIPS_BUILTIN_ANY_CABS_F_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9661 { CODE_FOR_mips_cabs_f_4s, "__builtin_mips_all_cabs_f_4s",
9662 MIPS_BUILTIN_ALL_CABS_F_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9664 { CODE_FOR_mips_cabs_un_4s, "__builtin_mips_any_cabs_un_4s",
9665 MIPS_BUILTIN_ANY_CABS_UN_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9667 { CODE_FOR_mips_cabs_un_4s, "__builtin_mips_all_cabs_un_4s",
9668 MIPS_BUILTIN_ALL_CABS_UN_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9670 { CODE_FOR_mips_cabs_eq_4s, "__builtin_mips_any_cabs_eq_4s",
9671 MIPS_BUILTIN_ANY_CABS_EQ_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9673 { CODE_FOR_mips_cabs_eq_4s, "__builtin_mips_all_cabs_eq_4s",
9674 MIPS_BUILTIN_ALL_CABS_EQ_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9676 { CODE_FOR_mips_cabs_ueq_4s, "__builtin_mips_any_cabs_ueq_4s",
9677 MIPS_BUILTIN_ANY_CABS_UEQ_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9679 { CODE_FOR_mips_cabs_ueq_4s, "__builtin_mips_all_cabs_ueq_4s",
9680 MIPS_BUILTIN_ALL_CABS_UEQ_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9682 { CODE_FOR_mips_cabs_olt_4s, "__builtin_mips_any_cabs_olt_4s",
9683 MIPS_BUILTIN_ANY_CABS_OLT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9685 { CODE_FOR_mips_cabs_olt_4s, "__builtin_mips_all_cabs_olt_4s",
9686 MIPS_BUILTIN_ALL_CABS_OLT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9688 { CODE_FOR_mips_cabs_ult_4s, "__builtin_mips_any_cabs_ult_4s",
9689 MIPS_BUILTIN_ANY_CABS_ULT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9691 { CODE_FOR_mips_cabs_ult_4s, "__builtin_mips_all_cabs_ult_4s",
9692 MIPS_BUILTIN_ALL_CABS_ULT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9694 { CODE_FOR_mips_cabs_ole_4s, "__builtin_mips_any_cabs_ole_4s",
9695 MIPS_BUILTIN_ANY_CABS_OLE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9697 { CODE_FOR_mips_cabs_ole_4s, "__builtin_mips_all_cabs_ole_4s",
9698 MIPS_BUILTIN_ALL_CABS_OLE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9700 { CODE_FOR_mips_cabs_ule_4s, "__builtin_mips_any_cabs_ule_4s",
9701 MIPS_BUILTIN_ANY_CABS_ULE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9703 { CODE_FOR_mips_cabs_ule_4s, "__builtin_mips_all_cabs_ule_4s",
9704 MIPS_BUILTIN_ALL_CABS_ULE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9706 { CODE_FOR_mips_cabs_sf_4s, "__builtin_mips_any_cabs_sf_4s",
9707 MIPS_BUILTIN_ANY_CABS_SF_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9709 { CODE_FOR_mips_cabs_sf_4s, "__builtin_mips_all_cabs_sf_4s",
9710 MIPS_BUILTIN_ALL_CABS_SF_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9712 { CODE_FOR_mips_cabs_ngle_4s, "__builtin_mips_any_cabs_ngle_4s",
9713 MIPS_BUILTIN_ANY_CABS_NGLE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9715 { CODE_FOR_mips_cabs_ngle_4s, "__builtin_mips_all_cabs_ngle_4s",
9716 MIPS_BUILTIN_ALL_CABS_NGLE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9718 { CODE_FOR_mips_cabs_seq_4s, "__builtin_mips_any_cabs_seq_4s",
9719 MIPS_BUILTIN_ANY_CABS_SEQ_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9721 { CODE_FOR_mips_cabs_seq_4s, "__builtin_mips_all_cabs_seq_4s",
9722 MIPS_BUILTIN_ALL_CABS_SEQ_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9724 { CODE_FOR_mips_cabs_ngl_4s, "__builtin_mips_any_cabs_ngl_4s",
9725 MIPS_BUILTIN_ANY_CABS_NGL_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9727 { CODE_FOR_mips_cabs_ngl_4s, "__builtin_mips_all_cabs_ngl_4s",
9728 MIPS_BUILTIN_ALL_CABS_NGL_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9730 { CODE_FOR_mips_cabs_lt_4s, "__builtin_mips_any_cabs_lt_4s",
9731 MIPS_BUILTIN_ANY_CABS_LT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9733 { CODE_FOR_mips_cabs_lt_4s, "__builtin_mips_all_cabs_lt_4s",
9734 MIPS_BUILTIN_ALL_CABS_LT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9736 { CODE_FOR_mips_cabs_nge_4s, "__builtin_mips_any_cabs_nge_4s",
9737 MIPS_BUILTIN_ANY_CABS_NGE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9739 { CODE_FOR_mips_cabs_nge_4s, "__builtin_mips_all_cabs_nge_4s",
9740 MIPS_BUILTIN_ALL_CABS_NGE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9742 { CODE_FOR_mips_cabs_le_4s, "__builtin_mips_any_cabs_le_4s",
9743 MIPS_BUILTIN_ANY_CABS_LE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9745 { CODE_FOR_mips_cabs_le_4s, "__builtin_mips_all_cabs_le_4s",
9746 MIPS_BUILTIN_ALL_CABS_LE_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9748 { CODE_FOR_mips_cabs_ngt_4s, "__builtin_mips_any_cabs_ngt_4s",
9749 MIPS_BUILTIN_ANY_CABS_NGT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9751 { CODE_FOR_mips_cabs_ngt_4s, "__builtin_mips_all_cabs_ngt_4s",
9752 MIPS_BUILTIN_ALL_CABS_NGT_4S, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
9755 { CODE_FOR_mips_cabs_f_s, "__builtin_mips_cabs_f_s",
9756 MIPS_BUILTIN_CABS_F_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
9757 { CODE_FOR_mips_cabs_un_s, "__builtin_mips_cabs_un_s",
9758 MIPS_BUILTIN_CABS_UN_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
9759 { CODE_FOR_mips_cabs_eq_s, "__builtin_mips_cabs_eq_s",
9760 MIPS_BUILTIN_CABS_EQ_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
9761 { CODE_FOR_mips_cabs_ueq_s, "__builtin_mips_cabs_ueq_s",
9762 MIPS_BUILTIN_CABS_UEQ_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
9763 { CODE_FOR_mips_cabs_olt_s, "__builtin_mips_cabs_olt_s",
9764 MIPS_BUILTIN_CABS_OLT_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
9765 { CODE_FOR_mips_cabs_ult_s, "__builtin_mips_cabs_ult_s",
9766 MIPS_BUILTIN_CABS_ULT_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
9767 { CODE_FOR_mips_cabs_ole_s, "__builtin_mips_cabs_ole_s",
9768 MIPS_BUILTIN_CABS_OLE_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
9769 { CODE_FOR_mips_cabs_ule_s, "__builtin_mips_cabs_ule_s",
9770 MIPS_BUILTIN_CABS_ULE_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
9771 { CODE_FOR_mips_cabs_sf_s, "__builtin_mips_cabs_sf_s",
9772 MIPS_BUILTIN_CABS_SF_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
9773 { CODE_FOR_mips_cabs_ngle_s, "__builtin_mips_cabs_ngle_s",
9774 MIPS_BUILTIN_CABS_NGLE_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
9775 { CODE_FOR_mips_cabs_seq_s, "__builtin_mips_cabs_seq_s",
9776 MIPS_BUILTIN_CABS_SEQ_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
9777 { CODE_FOR_mips_cabs_ngl_s, "__builtin_mips_cabs_ngl_s",
9778 MIPS_BUILTIN_CABS_NGL_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
9779 { CODE_FOR_mips_cabs_lt_s, "__builtin_mips_cabs_lt_s",
9780 MIPS_BUILTIN_CABS_LT_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
9781 { CODE_FOR_mips_cabs_nge_s, "__builtin_mips_cabs_nge_s",
9782 MIPS_BUILTIN_CABS_NGE_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
9783 { CODE_FOR_mips_cabs_le_s, "__builtin_mips_cabs_le_s",
9784 MIPS_BUILTIN_CABS_LE_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
9785 { CODE_FOR_mips_cabs_ngt_s, "__builtin_mips_cabs_ngt_s",
9786 MIPS_BUILTIN_CABS_NGT_S, MIPS_INT_FTYPE_SF_SF, MASK_MIPS3D },
9787 { CODE_FOR_mips_cabs_f_d, "__builtin_mips_cabs_f_d",
9788 MIPS_BUILTIN_CABS_F_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
9789 { CODE_FOR_mips_cabs_un_d, "__builtin_mips_cabs_un_d",
9790 MIPS_BUILTIN_CABS_UN_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
9791 { CODE_FOR_mips_cabs_eq_d, "__builtin_mips_cabs_eq_d",
9792 MIPS_BUILTIN_CABS_EQ_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
9793 { CODE_FOR_mips_cabs_ueq_d, "__builtin_mips_cabs_ueq_d",
9794 MIPS_BUILTIN_CABS_UEQ_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
9795 { CODE_FOR_mips_cabs_olt_d, "__builtin_mips_cabs_olt_d",
9796 MIPS_BUILTIN_CABS_OLT_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
9797 { CODE_FOR_mips_cabs_ult_d, "__builtin_mips_cabs_ult_d",
9798 MIPS_BUILTIN_CABS_ULT_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
9799 { CODE_FOR_mips_cabs_ole_d, "__builtin_mips_cabs_ole_d",
9800 MIPS_BUILTIN_CABS_OLE_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
9801 { CODE_FOR_mips_cabs_ule_d, "__builtin_mips_cabs_ule_d",
9802 MIPS_BUILTIN_CABS_ULE_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
9803 { CODE_FOR_mips_cabs_sf_d, "__builtin_mips_cabs_sf_d",
9804 MIPS_BUILTIN_CABS_SF_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
9805 { CODE_FOR_mips_cabs_ngle_d, "__builtin_mips_cabs_ngle_d",
9806 MIPS_BUILTIN_CABS_NGLE_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
9807 { CODE_FOR_mips_cabs_seq_d, "__builtin_mips_cabs_seq_d",
9808 MIPS_BUILTIN_CABS_SEQ_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
9809 { CODE_FOR_mips_cabs_ngl_d, "__builtin_mips_cabs_ngl_d",
9810 MIPS_BUILTIN_CABS_NGL_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
9811 { CODE_FOR_mips_cabs_lt_d, "__builtin_mips_cabs_lt_d",
9812 MIPS_BUILTIN_CABS_LT_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
9813 { CODE_FOR_mips_cabs_nge_d, "__builtin_mips_cabs_nge_d",
9814 MIPS_BUILTIN_CABS_NGE_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
9815 { CODE_FOR_mips_cabs_le_d, "__builtin_mips_cabs_le_d",
9816 MIPS_BUILTIN_CABS_LE_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
9817 { CODE_FOR_mips_cabs_ngt_d, "__builtin_mips_cabs_ngt_d",
9818 MIPS_BUILTIN_CABS_NGT_D, MIPS_INT_FTYPE_DF_DF, MASK_MIPS3D },
9820 { CODE_FOR_mips_c_f_ps, "__builtin_mips_movt_c_f_ps",
9821 MIPS_BUILTIN_MOVT_C_F_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9822 MASK_PAIRED_SINGLE },
9823 { CODE_FOR_mips_c_un_ps, "__builtin_mips_movt_c_un_ps",
9824 MIPS_BUILTIN_MOVT_C_UN_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9825 MASK_PAIRED_SINGLE },
9826 { CODE_FOR_mips_c_eq_ps, "__builtin_mips_movt_c_eq_ps",
9827 MIPS_BUILTIN_MOVT_C_EQ_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9828 MASK_PAIRED_SINGLE },
9829 { CODE_FOR_mips_c_ueq_ps, "__builtin_mips_movt_c_ueq_ps",
9830 MIPS_BUILTIN_MOVT_C_UEQ_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9831 MASK_PAIRED_SINGLE },
9832 { CODE_FOR_mips_c_olt_ps, "__builtin_mips_movt_c_olt_ps",
9833 MIPS_BUILTIN_MOVT_C_OLT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9834 MASK_PAIRED_SINGLE },
9835 { CODE_FOR_mips_c_ult_ps, "__builtin_mips_movt_c_ult_ps",
9836 MIPS_BUILTIN_MOVT_C_ULT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9837 MASK_PAIRED_SINGLE },
9838 { CODE_FOR_mips_c_ole_ps, "__builtin_mips_movt_c_ole_ps",
9839 MIPS_BUILTIN_MOVT_C_OLE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9840 MASK_PAIRED_SINGLE },
9841 { CODE_FOR_mips_c_ule_ps, "__builtin_mips_movt_c_ule_ps",
9842 MIPS_BUILTIN_MOVT_C_ULE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9843 MASK_PAIRED_SINGLE },
9844 { CODE_FOR_mips_c_sf_ps, "__builtin_mips_movt_c_sf_ps",
9845 MIPS_BUILTIN_MOVT_C_SF_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9846 MASK_PAIRED_SINGLE },
9847 { CODE_FOR_mips_c_ngle_ps, "__builtin_mips_movt_c_ngle_ps",
9848 MIPS_BUILTIN_MOVT_C_NGLE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9849 MASK_PAIRED_SINGLE },
9850 { CODE_FOR_mips_c_seq_ps, "__builtin_mips_movt_c_seq_ps",
9851 MIPS_BUILTIN_MOVT_C_SEQ_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9852 MASK_PAIRED_SINGLE },
9853 { CODE_FOR_mips_c_ngl_ps, "__builtin_mips_movt_c_ngl_ps",
9854 MIPS_BUILTIN_MOVT_C_NGL_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9855 MASK_PAIRED_SINGLE },
9856 { CODE_FOR_mips_c_lt_ps, "__builtin_mips_movt_c_lt_ps",
9857 MIPS_BUILTIN_MOVT_C_LT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9858 MASK_PAIRED_SINGLE },
9859 { CODE_FOR_mips_c_nge_ps, "__builtin_mips_movt_c_nge_ps",
9860 MIPS_BUILTIN_MOVT_C_NGE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9861 MASK_PAIRED_SINGLE },
9862 { CODE_FOR_mips_c_le_ps, "__builtin_mips_movt_c_le_ps",
9863 MIPS_BUILTIN_MOVT_C_LE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9864 MASK_PAIRED_SINGLE },
9865 { CODE_FOR_mips_c_ngt_ps, "__builtin_mips_movt_c_ngt_ps",
9866 MIPS_BUILTIN_MOVT_C_NGT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9867 MASK_PAIRED_SINGLE },
9868 { CODE_FOR_mips_cabs_f_ps, "__builtin_mips_movt_cabs_f_ps",
9869 MIPS_BUILTIN_MOVT_CABS_F_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9871 { CODE_FOR_mips_cabs_un_ps, "__builtin_mips_movt_cabs_un_ps",
9872 MIPS_BUILTIN_MOVT_CABS_UN_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9874 { CODE_FOR_mips_cabs_eq_ps, "__builtin_mips_movt_cabs_eq_ps",
9875 MIPS_BUILTIN_MOVT_CABS_EQ_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9877 { CODE_FOR_mips_cabs_ueq_ps, "__builtin_mips_movt_cabs_ueq_ps",
9878 MIPS_BUILTIN_MOVT_CABS_UEQ_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9880 { CODE_FOR_mips_cabs_olt_ps, "__builtin_mips_movt_cabs_olt_ps",
9881 MIPS_BUILTIN_MOVT_CABS_OLT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9883 { CODE_FOR_mips_cabs_ult_ps, "__builtin_mips_movt_cabs_ult_ps",
9884 MIPS_BUILTIN_MOVT_CABS_ULT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9886 { CODE_FOR_mips_cabs_ole_ps, "__builtin_mips_movt_cabs_ole_ps",
9887 MIPS_BUILTIN_MOVT_CABS_OLE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9889 { CODE_FOR_mips_cabs_ule_ps, "__builtin_mips_movt_cabs_ule_ps",
9890 MIPS_BUILTIN_MOVT_CABS_ULE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9892 { CODE_FOR_mips_cabs_sf_ps, "__builtin_mips_movt_cabs_sf_ps",
9893 MIPS_BUILTIN_MOVT_CABS_SF_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9895 { CODE_FOR_mips_cabs_ngle_ps, "__builtin_mips_movt_cabs_ngle_ps",
9896 MIPS_BUILTIN_MOVT_CABS_NGLE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9898 { CODE_FOR_mips_cabs_seq_ps, "__builtin_mips_movt_cabs_seq_ps",
9899 MIPS_BUILTIN_MOVT_CABS_SEQ_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9901 { CODE_FOR_mips_cabs_ngl_ps, "__builtin_mips_movt_cabs_ngl_ps",
9902 MIPS_BUILTIN_MOVT_CABS_NGL_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9904 { CODE_FOR_mips_cabs_lt_ps, "__builtin_mips_movt_cabs_lt_ps",
9905 MIPS_BUILTIN_MOVT_CABS_LT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9907 { CODE_FOR_mips_cabs_nge_ps, "__builtin_mips_movt_cabs_nge_ps",
9908 MIPS_BUILTIN_MOVT_CABS_NGE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9910 { CODE_FOR_mips_cabs_le_ps, "__builtin_mips_movt_cabs_le_ps",
9911 MIPS_BUILTIN_MOVT_CABS_LE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9913 { CODE_FOR_mips_cabs_ngt_ps, "__builtin_mips_movt_cabs_ngt_ps",
9914 MIPS_BUILTIN_MOVT_CABS_NGT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9916 { CODE_FOR_mips_c_f_ps, "__builtin_mips_movf_c_f_ps",
9917 MIPS_BUILTIN_MOVF_C_F_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9918 MASK_PAIRED_SINGLE },
9919 { CODE_FOR_mips_c_un_ps, "__builtin_mips_movf_c_un_ps",
9920 MIPS_BUILTIN_MOVF_C_UN_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9921 MASK_PAIRED_SINGLE },
9922 { CODE_FOR_mips_c_eq_ps, "__builtin_mips_movf_c_eq_ps",
9923 MIPS_BUILTIN_MOVF_C_EQ_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9924 MASK_PAIRED_SINGLE },
9925 { CODE_FOR_mips_c_ueq_ps, "__builtin_mips_movf_c_ueq_ps",
9926 MIPS_BUILTIN_MOVF_C_UEQ_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9927 MASK_PAIRED_SINGLE },
9928 { CODE_FOR_mips_c_olt_ps, "__builtin_mips_movf_c_olt_ps",
9929 MIPS_BUILTIN_MOVF_C_OLT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9930 MASK_PAIRED_SINGLE },
9931 { CODE_FOR_mips_c_ult_ps, "__builtin_mips_movf_c_ult_ps",
9932 MIPS_BUILTIN_MOVF_C_ULT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9933 MASK_PAIRED_SINGLE },
9934 { CODE_FOR_mips_c_ole_ps, "__builtin_mips_movf_c_ole_ps",
9935 MIPS_BUILTIN_MOVF_C_OLE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9936 MASK_PAIRED_SINGLE },
9937 { CODE_FOR_mips_c_ule_ps, "__builtin_mips_movf_c_ule_ps",
9938 MIPS_BUILTIN_MOVF_C_ULE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9939 MASK_PAIRED_SINGLE },
9940 { CODE_FOR_mips_c_sf_ps, "__builtin_mips_movf_c_sf_ps",
9941 MIPS_BUILTIN_MOVF_C_SF_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9942 MASK_PAIRED_SINGLE },
9943 { CODE_FOR_mips_c_ngle_ps, "__builtin_mips_movf_c_ngle_ps",
9944 MIPS_BUILTIN_MOVF_C_NGLE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9945 MASK_PAIRED_SINGLE },
9946 { CODE_FOR_mips_c_seq_ps, "__builtin_mips_movf_c_seq_ps",
9947 MIPS_BUILTIN_MOVF_C_SEQ_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9948 MASK_PAIRED_SINGLE },
9949 { CODE_FOR_mips_c_ngl_ps, "__builtin_mips_movf_c_ngl_ps",
9950 MIPS_BUILTIN_MOVF_C_NGL_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9951 MASK_PAIRED_SINGLE },
9952 { CODE_FOR_mips_c_lt_ps, "__builtin_mips_movf_c_lt_ps",
9953 MIPS_BUILTIN_MOVF_C_LT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9954 MASK_PAIRED_SINGLE },
9955 { CODE_FOR_mips_c_nge_ps, "__builtin_mips_movf_c_nge_ps",
9956 MIPS_BUILTIN_MOVF_C_NGE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9957 MASK_PAIRED_SINGLE },
9958 { CODE_FOR_mips_c_le_ps, "__builtin_mips_movf_c_le_ps",
9959 MIPS_BUILTIN_MOVF_C_LE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9960 MASK_PAIRED_SINGLE },
9961 { CODE_FOR_mips_c_ngt_ps, "__builtin_mips_movf_c_ngt_ps",
9962 MIPS_BUILTIN_MOVF_C_NGT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9963 MASK_PAIRED_SINGLE },
9964 { CODE_FOR_mips_cabs_f_ps, "__builtin_mips_movf_cabs_f_ps",
9965 MIPS_BUILTIN_MOVF_CABS_F_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9967 { CODE_FOR_mips_cabs_un_ps, "__builtin_mips_movf_cabs_un_ps",
9968 MIPS_BUILTIN_MOVF_CABS_UN_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9970 { CODE_FOR_mips_cabs_eq_ps, "__builtin_mips_movf_cabs_eq_ps",
9971 MIPS_BUILTIN_MOVF_CABS_EQ_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9973 { CODE_FOR_mips_cabs_ueq_ps, "__builtin_mips_movf_cabs_ueq_ps",
9974 MIPS_BUILTIN_MOVF_CABS_UEQ_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9976 { CODE_FOR_mips_cabs_olt_ps, "__builtin_mips_movf_cabs_olt_ps",
9977 MIPS_BUILTIN_MOVF_CABS_OLT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9979 { CODE_FOR_mips_cabs_ult_ps, "__builtin_mips_movf_cabs_ult_ps",
9980 MIPS_BUILTIN_MOVF_CABS_ULT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9982 { CODE_FOR_mips_cabs_ole_ps, "__builtin_mips_movf_cabs_ole_ps",
9983 MIPS_BUILTIN_MOVF_CABS_OLE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9985 { CODE_FOR_mips_cabs_ule_ps, "__builtin_mips_movf_cabs_ule_ps",
9986 MIPS_BUILTIN_MOVF_CABS_ULE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9988 { CODE_FOR_mips_cabs_sf_ps, "__builtin_mips_movf_cabs_sf_ps",
9989 MIPS_BUILTIN_MOVF_CABS_SF_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9991 { CODE_FOR_mips_cabs_ngle_ps, "__builtin_mips_movf_cabs_ngle_ps",
9992 MIPS_BUILTIN_MOVF_CABS_NGLE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9994 { CODE_FOR_mips_cabs_seq_ps, "__builtin_mips_movf_cabs_seq_ps",
9995 MIPS_BUILTIN_MOVF_CABS_SEQ_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
9997 { CODE_FOR_mips_cabs_ngl_ps, "__builtin_mips_movf_cabs_ngl_ps",
9998 MIPS_BUILTIN_MOVF_CABS_NGL_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
10000 { CODE_FOR_mips_cabs_lt_ps, "__builtin_mips_movf_cabs_lt_ps",
10001 MIPS_BUILTIN_MOVF_CABS_LT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
10003 { CODE_FOR_mips_cabs_nge_ps, "__builtin_mips_movf_cabs_nge_ps",
10004 MIPS_BUILTIN_MOVF_CABS_NGE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
10006 { CODE_FOR_mips_cabs_le_ps, "__builtin_mips_movf_cabs_le_ps",
10007 MIPS_BUILTIN_MOVF_CABS_LE_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
10009 { CODE_FOR_mips_cabs_ngt_ps, "__builtin_mips_movf_cabs_ngt_ps",
10010 MIPS_BUILTIN_MOVF_CABS_NGT_PS, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
10016 /* Take the head of argument list *ARGLIST and convert it into a form
10017 suitable for input operand OP of instruction ICODE. Return the value
10018 and point *ARGLIST at the next element of the list. */
10021 mips_prepare_builtin_arg (enum insn_code icode,
10022 unsigned int op, tree *arglist)
10025 enum machine_mode mode;
10027 value = expand_expr (TREE_VALUE (*arglist), NULL_RTX, VOIDmode, 0);
10028 mode = insn_data[icode].operand[op].mode;
10029 if (!insn_data[icode].operand[op].predicate (value, mode))
10030 value = copy_to_mode_reg (mode, value);
10032 *arglist = TREE_CHAIN (*arglist);
10036 /* Return an rtx suitable for output operand OP of instruction ICODE.
10037 If TARGET is non-null, try to use it where possible. */
10040 mips_prepare_builtin_target (enum insn_code icode, unsigned int op, rtx target)
10042 enum machine_mode mode;
10044 mode = insn_data[icode].operand[op].mode;
10045 if (target == 0 || !insn_data[icode].operand[op].predicate (target, mode))
10046 target = gen_reg_rtx (mode);
10051 /* Expand builtin functions. This is called from TARGET_EXPAND_BUILTIN. */
10054 mips_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
10055 enum machine_mode mode ATTRIBUTE_UNUSED,
10056 int ignore ATTRIBUTE_UNUSED)
10059 enum insn_code icode;
10060 tree fndecl, arglist;
10061 unsigned int fcode;
10063 fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
10064 arglist = TREE_OPERAND (exp, 1);
10065 fcode = DECL_FUNCTION_CODE (fndecl);
10066 if (fcode >= ARRAY_SIZE (mips_bdesc))
10069 icode = mips_bdesc[fcode].icode;
10072 /* Two Operands. */
10073 case MIPS_BUILTIN_PLL_PS:
10074 case MIPS_BUILTIN_PUL_PS:
10075 case MIPS_BUILTIN_PLU_PS:
10076 case MIPS_BUILTIN_PUU_PS:
10077 case MIPS_BUILTIN_CVT_PS_S:
10078 case MIPS_BUILTIN_ADDR_PS:
10079 case MIPS_BUILTIN_MULR_PS:
10080 case MIPS_BUILTIN_RECIP2_S:
10081 case MIPS_BUILTIN_RECIP2_D:
10082 case MIPS_BUILTIN_RECIP2_PS:
10083 case MIPS_BUILTIN_RSQRT2_S:
10084 case MIPS_BUILTIN_RSQRT2_D:
10085 case MIPS_BUILTIN_RSQRT2_PS:
10086 target = mips_prepare_builtin_target (icode, 0, target);
10087 op0 = mips_prepare_builtin_arg (icode, 1, &arglist);
10088 op1 = mips_prepare_builtin_arg (icode, 2, &arglist);
10089 emit_insn (GEN_FCN (icode) (target, op0, op1));
10093 case MIPS_BUILTIN_CVT_S_PL:
10094 case MIPS_BUILTIN_CVT_S_PU:
10095 case MIPS_BUILTIN_ABS_PS:
10096 case MIPS_BUILTIN_CVT_PW_PS:
10097 case MIPS_BUILTIN_CVT_PS_PW:
10098 case MIPS_BUILTIN_RECIP1_S:
10099 case MIPS_BUILTIN_RECIP1_D:
10100 case MIPS_BUILTIN_RECIP1_PS:
10101 case MIPS_BUILTIN_RSQRT1_S:
10102 case MIPS_BUILTIN_RSQRT1_D:
10103 case MIPS_BUILTIN_RSQRT1_PS:
10104 target = mips_prepare_builtin_target (icode, 0, target);
10105 op0 = mips_prepare_builtin_arg (icode, 1, &arglist);
10106 emit_insn (GEN_FCN (icode) (target, op0));
10109 /* Three Operands. */
10110 case MIPS_BUILTIN_ALNV_PS:
10111 target = mips_prepare_builtin_target (icode, 0, target);
10112 op0 = mips_prepare_builtin_arg (icode, 1, &arglist);
10113 op1 = mips_prepare_builtin_arg (icode, 2, &arglist);
10114 op2 = mips_prepare_builtin_arg (icode, 3, &arglist);
10115 emit_insn (GEN_FCN (icode) (target, op0, op1, op2));
10118 /* Paired Single Comparison. */
10119 case MIPS_BUILTIN_ANY_C_F_PS:
10120 case MIPS_BUILTIN_ANY_C_UN_PS:
10121 case MIPS_BUILTIN_ANY_C_EQ_PS:
10122 case MIPS_BUILTIN_ANY_C_UEQ_PS:
10123 case MIPS_BUILTIN_ANY_C_OLT_PS:
10124 case MIPS_BUILTIN_ANY_C_ULT_PS:
10125 case MIPS_BUILTIN_ANY_C_OLE_PS:
10126 case MIPS_BUILTIN_ANY_C_ULE_PS:
10127 case MIPS_BUILTIN_ANY_C_SF_PS:
10128 case MIPS_BUILTIN_ANY_C_NGLE_PS:
10129 case MIPS_BUILTIN_ANY_C_SEQ_PS:
10130 case MIPS_BUILTIN_ANY_C_NGL_PS:
10131 case MIPS_BUILTIN_ANY_C_LT_PS:
10132 case MIPS_BUILTIN_ANY_C_NGE_PS:
10133 case MIPS_BUILTIN_ANY_C_LE_PS:
10134 case MIPS_BUILTIN_ANY_C_NGT_PS:
10135 case MIPS_BUILTIN_ANY_CABS_F_PS:
10136 case MIPS_BUILTIN_ANY_CABS_UN_PS:
10137 case MIPS_BUILTIN_ANY_CABS_EQ_PS:
10138 case MIPS_BUILTIN_ANY_CABS_UEQ_PS:
10139 case MIPS_BUILTIN_ANY_CABS_OLT_PS:
10140 case MIPS_BUILTIN_ANY_CABS_ULT_PS:
10141 case MIPS_BUILTIN_ANY_CABS_OLE_PS:
10142 case MIPS_BUILTIN_ANY_CABS_ULE_PS:
10143 case MIPS_BUILTIN_ANY_CABS_SF_PS:
10144 case MIPS_BUILTIN_ANY_CABS_NGLE_PS:
10145 case MIPS_BUILTIN_ANY_CABS_SEQ_PS:
10146 case MIPS_BUILTIN_ANY_CABS_NGL_PS:
10147 case MIPS_BUILTIN_ANY_CABS_LT_PS:
10148 case MIPS_BUILTIN_ANY_CABS_NGE_PS:
10149 case MIPS_BUILTIN_ANY_CABS_LE_PS:
10150 case MIPS_BUILTIN_ANY_CABS_NGT_PS:
10151 return mips_expand_ps_compare_builtin (MIPS_CMP_ANY, icode,
10154 /* Paired Single Comparison. */
10155 case MIPS_BUILTIN_UPPER_C_F_PS:
10156 case MIPS_BUILTIN_UPPER_C_UN_PS:
10157 case MIPS_BUILTIN_UPPER_C_EQ_PS:
10158 case MIPS_BUILTIN_UPPER_C_UEQ_PS:
10159 case MIPS_BUILTIN_UPPER_C_OLT_PS:
10160 case MIPS_BUILTIN_UPPER_C_ULT_PS:
10161 case MIPS_BUILTIN_UPPER_C_OLE_PS:
10162 case MIPS_BUILTIN_UPPER_C_ULE_PS:
10163 case MIPS_BUILTIN_UPPER_C_SF_PS:
10164 case MIPS_BUILTIN_UPPER_C_NGLE_PS:
10165 case MIPS_BUILTIN_UPPER_C_SEQ_PS:
10166 case MIPS_BUILTIN_UPPER_C_NGL_PS:
10167 case MIPS_BUILTIN_UPPER_C_LT_PS:
10168 case MIPS_BUILTIN_UPPER_C_NGE_PS:
10169 case MIPS_BUILTIN_UPPER_C_LE_PS:
10170 case MIPS_BUILTIN_UPPER_C_NGT_PS:
10171 case MIPS_BUILTIN_UPPER_CABS_F_PS:
10172 case MIPS_BUILTIN_UPPER_CABS_UN_PS:
10173 case MIPS_BUILTIN_UPPER_CABS_EQ_PS:
10174 case MIPS_BUILTIN_UPPER_CABS_UEQ_PS:
10175 case MIPS_BUILTIN_UPPER_CABS_OLT_PS:
10176 case MIPS_BUILTIN_UPPER_CABS_ULT_PS:
10177 case MIPS_BUILTIN_UPPER_CABS_OLE_PS:
10178 case MIPS_BUILTIN_UPPER_CABS_ULE_PS:
10179 case MIPS_BUILTIN_UPPER_CABS_SF_PS:
10180 case MIPS_BUILTIN_UPPER_CABS_NGLE_PS:
10181 case MIPS_BUILTIN_UPPER_CABS_SEQ_PS:
10182 case MIPS_BUILTIN_UPPER_CABS_NGL_PS:
10183 case MIPS_BUILTIN_UPPER_CABS_LT_PS:
10184 case MIPS_BUILTIN_UPPER_CABS_NGE_PS:
10185 case MIPS_BUILTIN_UPPER_CABS_LE_PS:
10186 case MIPS_BUILTIN_UPPER_CABS_NGT_PS:
10187 return mips_expand_ps_compare_builtin (MIPS_CMP_UPPER, icode,
10190 /* Paired Single Comparison. */
10191 case MIPS_BUILTIN_LOWER_C_F_PS:
10192 case MIPS_BUILTIN_LOWER_C_UN_PS:
10193 case MIPS_BUILTIN_LOWER_C_EQ_PS:
10194 case MIPS_BUILTIN_LOWER_C_UEQ_PS:
10195 case MIPS_BUILTIN_LOWER_C_OLT_PS:
10196 case MIPS_BUILTIN_LOWER_C_ULT_PS:
10197 case MIPS_BUILTIN_LOWER_C_OLE_PS:
10198 case MIPS_BUILTIN_LOWER_C_ULE_PS:
10199 case MIPS_BUILTIN_LOWER_C_SF_PS:
10200 case MIPS_BUILTIN_LOWER_C_NGLE_PS:
10201 case MIPS_BUILTIN_LOWER_C_SEQ_PS:
10202 case MIPS_BUILTIN_LOWER_C_NGL_PS:
10203 case MIPS_BUILTIN_LOWER_C_LT_PS:
10204 case MIPS_BUILTIN_LOWER_C_NGE_PS:
10205 case MIPS_BUILTIN_LOWER_C_LE_PS:
10206 case MIPS_BUILTIN_LOWER_C_NGT_PS:
10207 case MIPS_BUILTIN_LOWER_CABS_F_PS:
10208 case MIPS_BUILTIN_LOWER_CABS_UN_PS:
10209 case MIPS_BUILTIN_LOWER_CABS_EQ_PS:
10210 case MIPS_BUILTIN_LOWER_CABS_UEQ_PS:
10211 case MIPS_BUILTIN_LOWER_CABS_OLT_PS:
10212 case MIPS_BUILTIN_LOWER_CABS_ULT_PS:
10213 case MIPS_BUILTIN_LOWER_CABS_OLE_PS:
10214 case MIPS_BUILTIN_LOWER_CABS_ULE_PS:
10215 case MIPS_BUILTIN_LOWER_CABS_SF_PS:
10216 case MIPS_BUILTIN_LOWER_CABS_NGLE_PS:
10217 case MIPS_BUILTIN_LOWER_CABS_SEQ_PS:
10218 case MIPS_BUILTIN_LOWER_CABS_NGL_PS:
10219 case MIPS_BUILTIN_LOWER_CABS_LT_PS:
10220 case MIPS_BUILTIN_LOWER_CABS_NGE_PS:
10221 case MIPS_BUILTIN_LOWER_CABS_LE_PS:
10222 case MIPS_BUILTIN_LOWER_CABS_NGT_PS:
10223 return mips_expand_ps_compare_builtin (MIPS_CMP_LOWER, icode,
10226 /* Paired Single Comparison. */
10227 case MIPS_BUILTIN_ALL_C_F_PS:
10228 case MIPS_BUILTIN_ALL_C_UN_PS:
10229 case MIPS_BUILTIN_ALL_C_EQ_PS:
10230 case MIPS_BUILTIN_ALL_C_UEQ_PS:
10231 case MIPS_BUILTIN_ALL_C_OLT_PS:
10232 case MIPS_BUILTIN_ALL_C_ULT_PS:
10233 case MIPS_BUILTIN_ALL_C_OLE_PS:
10234 case MIPS_BUILTIN_ALL_C_ULE_PS:
10235 case MIPS_BUILTIN_ALL_C_SF_PS:
10236 case MIPS_BUILTIN_ALL_C_NGLE_PS:
10237 case MIPS_BUILTIN_ALL_C_SEQ_PS:
10238 case MIPS_BUILTIN_ALL_C_NGL_PS:
10239 case MIPS_BUILTIN_ALL_C_LT_PS:
10240 case MIPS_BUILTIN_ALL_C_NGE_PS:
10241 case MIPS_BUILTIN_ALL_C_LE_PS:
10242 case MIPS_BUILTIN_ALL_C_NGT_PS:
10243 case MIPS_BUILTIN_ALL_CABS_F_PS:
10244 case MIPS_BUILTIN_ALL_CABS_UN_PS:
10245 case MIPS_BUILTIN_ALL_CABS_EQ_PS:
10246 case MIPS_BUILTIN_ALL_CABS_UEQ_PS:
10247 case MIPS_BUILTIN_ALL_CABS_OLT_PS:
10248 case MIPS_BUILTIN_ALL_CABS_ULT_PS:
10249 case MIPS_BUILTIN_ALL_CABS_OLE_PS:
10250 case MIPS_BUILTIN_ALL_CABS_ULE_PS:
10251 case MIPS_BUILTIN_ALL_CABS_SF_PS:
10252 case MIPS_BUILTIN_ALL_CABS_NGLE_PS:
10253 case MIPS_BUILTIN_ALL_CABS_SEQ_PS:
10254 case MIPS_BUILTIN_ALL_CABS_NGL_PS:
10255 case MIPS_BUILTIN_ALL_CABS_LT_PS:
10256 case MIPS_BUILTIN_ALL_CABS_NGE_PS:
10257 case MIPS_BUILTIN_ALL_CABS_LE_PS:
10258 case MIPS_BUILTIN_ALL_CABS_NGT_PS:
10259 return mips_expand_ps_compare_builtin (MIPS_CMP_ALL, icode,
10262 /* Four Single Comparison. */
10263 case MIPS_BUILTIN_ANY_C_F_4S:
10264 case MIPS_BUILTIN_ANY_C_UN_4S:
10265 case MIPS_BUILTIN_ANY_C_EQ_4S:
10266 case MIPS_BUILTIN_ANY_C_UEQ_4S:
10267 case MIPS_BUILTIN_ANY_C_OLT_4S:
10268 case MIPS_BUILTIN_ANY_C_ULT_4S:
10269 case MIPS_BUILTIN_ANY_C_OLE_4S:
10270 case MIPS_BUILTIN_ANY_C_ULE_4S:
10271 case MIPS_BUILTIN_ANY_C_SF_4S:
10272 case MIPS_BUILTIN_ANY_C_NGLE_4S:
10273 case MIPS_BUILTIN_ANY_C_SEQ_4S:
10274 case MIPS_BUILTIN_ANY_C_NGL_4S:
10275 case MIPS_BUILTIN_ANY_C_LT_4S:
10276 case MIPS_BUILTIN_ANY_C_NGE_4S:
10277 case MIPS_BUILTIN_ANY_C_LE_4S:
10278 case MIPS_BUILTIN_ANY_C_NGT_4S:
10279 case MIPS_BUILTIN_ANY_CABS_F_4S:
10280 case MIPS_BUILTIN_ANY_CABS_UN_4S:
10281 case MIPS_BUILTIN_ANY_CABS_EQ_4S:
10282 case MIPS_BUILTIN_ANY_CABS_UEQ_4S:
10283 case MIPS_BUILTIN_ANY_CABS_OLT_4S:
10284 case MIPS_BUILTIN_ANY_CABS_ULT_4S:
10285 case MIPS_BUILTIN_ANY_CABS_OLE_4S:
10286 case MIPS_BUILTIN_ANY_CABS_ULE_4S:
10287 case MIPS_BUILTIN_ANY_CABS_SF_4S:
10288 case MIPS_BUILTIN_ANY_CABS_NGLE_4S:
10289 case MIPS_BUILTIN_ANY_CABS_SEQ_4S:
10290 case MIPS_BUILTIN_ANY_CABS_NGL_4S:
10291 case MIPS_BUILTIN_ANY_CABS_LT_4S:
10292 case MIPS_BUILTIN_ANY_CABS_NGE_4S:
10293 case MIPS_BUILTIN_ANY_CABS_LE_4S:
10294 case MIPS_BUILTIN_ANY_CABS_NGT_4S:
10295 return mips_expand_4s_compare_builtin (MIPS_CMP_ANY, icode,
10298 /* Four Single Comparison. */
10299 case MIPS_BUILTIN_ALL_C_F_4S:
10300 case MIPS_BUILTIN_ALL_C_UN_4S:
10301 case MIPS_BUILTIN_ALL_C_EQ_4S:
10302 case MIPS_BUILTIN_ALL_C_UEQ_4S:
10303 case MIPS_BUILTIN_ALL_C_OLT_4S:
10304 case MIPS_BUILTIN_ALL_C_ULT_4S:
10305 case MIPS_BUILTIN_ALL_C_OLE_4S:
10306 case MIPS_BUILTIN_ALL_C_ULE_4S:
10307 case MIPS_BUILTIN_ALL_C_SF_4S:
10308 case MIPS_BUILTIN_ALL_C_NGLE_4S:
10309 case MIPS_BUILTIN_ALL_C_SEQ_4S:
10310 case MIPS_BUILTIN_ALL_C_NGL_4S:
10311 case MIPS_BUILTIN_ALL_C_LT_4S:
10312 case MIPS_BUILTIN_ALL_C_NGE_4S:
10313 case MIPS_BUILTIN_ALL_C_LE_4S:
10314 case MIPS_BUILTIN_ALL_C_NGT_4S:
10315 case MIPS_BUILTIN_ALL_CABS_F_4S:
10316 case MIPS_BUILTIN_ALL_CABS_UN_4S:
10317 case MIPS_BUILTIN_ALL_CABS_EQ_4S:
10318 case MIPS_BUILTIN_ALL_CABS_UEQ_4S:
10319 case MIPS_BUILTIN_ALL_CABS_OLT_4S:
10320 case MIPS_BUILTIN_ALL_CABS_ULT_4S:
10321 case MIPS_BUILTIN_ALL_CABS_OLE_4S:
10322 case MIPS_BUILTIN_ALL_CABS_ULE_4S:
10323 case MIPS_BUILTIN_ALL_CABS_SF_4S:
10324 case MIPS_BUILTIN_ALL_CABS_NGLE_4S:
10325 case MIPS_BUILTIN_ALL_CABS_SEQ_4S:
10326 case MIPS_BUILTIN_ALL_CABS_NGL_4S:
10327 case MIPS_BUILTIN_ALL_CABS_LT_4S:
10328 case MIPS_BUILTIN_ALL_CABS_NGE_4S:
10329 case MIPS_BUILTIN_ALL_CABS_LE_4S:
10330 case MIPS_BUILTIN_ALL_CABS_NGT_4S:
10331 return mips_expand_4s_compare_builtin (MIPS_CMP_ALL, icode,
10334 /* Single/Double Compare Absolute. */
10335 case MIPS_BUILTIN_CABS_F_S:
10336 case MIPS_BUILTIN_CABS_UN_S:
10337 case MIPS_BUILTIN_CABS_EQ_S:
10338 case MIPS_BUILTIN_CABS_UEQ_S:
10339 case MIPS_BUILTIN_CABS_OLT_S:
10340 case MIPS_BUILTIN_CABS_ULT_S:
10341 case MIPS_BUILTIN_CABS_OLE_S:
10342 case MIPS_BUILTIN_CABS_ULE_S:
10343 case MIPS_BUILTIN_CABS_SF_S:
10344 case MIPS_BUILTIN_CABS_NGLE_S:
10345 case MIPS_BUILTIN_CABS_SEQ_S:
10346 case MIPS_BUILTIN_CABS_NGL_S:
10347 case MIPS_BUILTIN_CABS_LT_S:
10348 case MIPS_BUILTIN_CABS_NGE_S:
10349 case MIPS_BUILTIN_CABS_LE_S:
10350 case MIPS_BUILTIN_CABS_NGT_S:
10351 case MIPS_BUILTIN_CABS_F_D:
10352 case MIPS_BUILTIN_CABS_UN_D:
10353 case MIPS_BUILTIN_CABS_EQ_D:
10354 case MIPS_BUILTIN_CABS_UEQ_D:
10355 case MIPS_BUILTIN_CABS_OLT_D:
10356 case MIPS_BUILTIN_CABS_ULT_D:
10357 case MIPS_BUILTIN_CABS_OLE_D:
10358 case MIPS_BUILTIN_CABS_ULE_D:
10359 case MIPS_BUILTIN_CABS_SF_D:
10360 case MIPS_BUILTIN_CABS_NGLE_D:
10361 case MIPS_BUILTIN_CABS_SEQ_D:
10362 case MIPS_BUILTIN_CABS_NGL_D:
10363 case MIPS_BUILTIN_CABS_LT_D:
10364 case MIPS_BUILTIN_CABS_NGE_D:
10365 case MIPS_BUILTIN_CABS_LE_D:
10366 case MIPS_BUILTIN_CABS_NGT_D:
10367 return mips_expand_scalar_compare_builtin (icode, target, arglist);
10369 /* Conditional Move on True. */
10370 case MIPS_BUILTIN_MOVT_C_F_PS:
10371 case MIPS_BUILTIN_MOVT_C_UN_PS:
10372 case MIPS_BUILTIN_MOVT_C_EQ_PS:
10373 case MIPS_BUILTIN_MOVT_C_UEQ_PS:
10374 case MIPS_BUILTIN_MOVT_C_OLT_PS:
10375 case MIPS_BUILTIN_MOVT_C_ULT_PS:
10376 case MIPS_BUILTIN_MOVT_C_OLE_PS:
10377 case MIPS_BUILTIN_MOVT_C_ULE_PS:
10378 case MIPS_BUILTIN_MOVT_C_SF_PS:
10379 case MIPS_BUILTIN_MOVT_C_NGLE_PS:
10380 case MIPS_BUILTIN_MOVT_C_SEQ_PS:
10381 case MIPS_BUILTIN_MOVT_C_NGL_PS:
10382 case MIPS_BUILTIN_MOVT_C_LT_PS:
10383 case MIPS_BUILTIN_MOVT_C_NGE_PS:
10384 case MIPS_BUILTIN_MOVT_C_LE_PS:
10385 case MIPS_BUILTIN_MOVT_C_NGT_PS:
10386 case MIPS_BUILTIN_MOVT_CABS_F_PS:
10387 case MIPS_BUILTIN_MOVT_CABS_UN_PS:
10388 case MIPS_BUILTIN_MOVT_CABS_EQ_PS:
10389 case MIPS_BUILTIN_MOVT_CABS_UEQ_PS:
10390 case MIPS_BUILTIN_MOVT_CABS_OLT_PS:
10391 case MIPS_BUILTIN_MOVT_CABS_ULT_PS:
10392 case MIPS_BUILTIN_MOVT_CABS_OLE_PS:
10393 case MIPS_BUILTIN_MOVT_CABS_ULE_PS:
10394 case MIPS_BUILTIN_MOVT_CABS_SF_PS:
10395 case MIPS_BUILTIN_MOVT_CABS_NGLE_PS:
10396 case MIPS_BUILTIN_MOVT_CABS_SEQ_PS:
10397 case MIPS_BUILTIN_MOVT_CABS_NGL_PS:
10398 case MIPS_BUILTIN_MOVT_CABS_LT_PS:
10399 case MIPS_BUILTIN_MOVT_CABS_NGE_PS:
10400 case MIPS_BUILTIN_MOVT_CABS_LE_PS:
10401 case MIPS_BUILTIN_MOVT_CABS_NGT_PS:
10402 return mips_expand_ps_cond_move_builtin (true, icode, target, arglist);
10404 /* Conditional Move on False. */
10405 case MIPS_BUILTIN_MOVF_C_F_PS:
10406 case MIPS_BUILTIN_MOVF_C_UN_PS:
10407 case MIPS_BUILTIN_MOVF_C_EQ_PS:
10408 case MIPS_BUILTIN_MOVF_C_UEQ_PS:
10409 case MIPS_BUILTIN_MOVF_C_OLT_PS:
10410 case MIPS_BUILTIN_MOVF_C_ULT_PS:
10411 case MIPS_BUILTIN_MOVF_C_OLE_PS:
10412 case MIPS_BUILTIN_MOVF_C_ULE_PS:
10413 case MIPS_BUILTIN_MOVF_C_SF_PS:
10414 case MIPS_BUILTIN_MOVF_C_NGLE_PS:
10415 case MIPS_BUILTIN_MOVF_C_SEQ_PS:
10416 case MIPS_BUILTIN_MOVF_C_NGL_PS:
10417 case MIPS_BUILTIN_MOVF_C_LT_PS:
10418 case MIPS_BUILTIN_MOVF_C_NGE_PS:
10419 case MIPS_BUILTIN_MOVF_C_LE_PS:
10420 case MIPS_BUILTIN_MOVF_C_NGT_PS:
10421 case MIPS_BUILTIN_MOVF_CABS_F_PS:
10422 case MIPS_BUILTIN_MOVF_CABS_UN_PS:
10423 case MIPS_BUILTIN_MOVF_CABS_EQ_PS:
10424 case MIPS_BUILTIN_MOVF_CABS_UEQ_PS:
10425 case MIPS_BUILTIN_MOVF_CABS_OLT_PS:
10426 case MIPS_BUILTIN_MOVF_CABS_ULT_PS:
10427 case MIPS_BUILTIN_MOVF_CABS_OLE_PS:
10428 case MIPS_BUILTIN_MOVF_CABS_ULE_PS:
10429 case MIPS_BUILTIN_MOVF_CABS_SF_PS:
10430 case MIPS_BUILTIN_MOVF_CABS_NGLE_PS:
10431 case MIPS_BUILTIN_MOVF_CABS_SEQ_PS:
10432 case MIPS_BUILTIN_MOVF_CABS_NGL_PS:
10433 case MIPS_BUILTIN_MOVF_CABS_LT_PS:
10434 case MIPS_BUILTIN_MOVF_CABS_NGE_PS:
10435 case MIPS_BUILTIN_MOVF_CABS_LE_PS:
10436 case MIPS_BUILTIN_MOVF_CABS_NGT_PS:
10437 return mips_expand_ps_cond_move_builtin (false, icode, target, arglist);
10446 /* Init builtin functions. This is called from TARGET_INIT_BUILTIN. */
10449 mips_init_builtins (void)
10451 const struct builtin_description *d;
10452 tree types[(int) MIPS_MAX_FTYPE_MAX];
10453 tree V2SF_type_node;
10455 /* We have only builtins for -mpaired-single and -mips3d. */
10456 if (!TARGET_PAIRED_SINGLE_FLOAT)
10459 V2SF_type_node = build_vector_type_for_mode (float_type_node, V2SFmode);
10461 types[MIPS_V2SF_FTYPE_V2SF]
10462 = build_function_type_list (V2SF_type_node, V2SF_type_node, NULL_TREE);
10464 types[MIPS_V2SF_FTYPE_V2SF_V2SF]
10465 = build_function_type_list (V2SF_type_node,
10466 V2SF_type_node, V2SF_type_node, NULL_TREE);
10468 types[MIPS_V2SF_FTYPE_V2SF_V2SF_INT]
10469 = build_function_type_list (V2SF_type_node,
10470 V2SF_type_node, V2SF_type_node,
10471 integer_type_node, NULL_TREE);
10473 types[MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF]
10474 = build_function_type_list (V2SF_type_node,
10475 V2SF_type_node, V2SF_type_node,
10476 V2SF_type_node, V2SF_type_node, NULL_TREE);
10478 types[MIPS_V2SF_FTYPE_SF_SF]
10479 = build_function_type_list (V2SF_type_node,
10480 float_type_node, float_type_node, NULL_TREE);
10482 types[MIPS_INT_FTYPE_V2SF_V2SF]
10483 = build_function_type_list (integer_type_node,
10484 V2SF_type_node, V2SF_type_node, NULL_TREE);
10486 types[MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF]
10487 = build_function_type_list (integer_type_node,
10488 V2SF_type_node, V2SF_type_node,
10489 V2SF_type_node, V2SF_type_node, NULL_TREE);
10491 types[MIPS_INT_FTYPE_SF_SF]
10492 = build_function_type_list (integer_type_node,
10493 float_type_node, float_type_node, NULL_TREE);
10495 types[MIPS_INT_FTYPE_DF_DF]
10496 = build_function_type_list (integer_type_node,
10497 double_type_node, double_type_node, NULL_TREE);
10499 types[MIPS_SF_FTYPE_V2SF]
10500 = build_function_type_list (float_type_node, V2SF_type_node, NULL_TREE);
10502 types[MIPS_SF_FTYPE_SF]
10503 = build_function_type_list (float_type_node,
10504 float_type_node, NULL_TREE);
10506 types[MIPS_SF_FTYPE_SF_SF]
10507 = build_function_type_list (float_type_node,
10508 float_type_node, float_type_node, NULL_TREE);
10510 types[MIPS_DF_FTYPE_DF]
10511 = build_function_type_list (double_type_node,
10512 double_type_node, NULL_TREE);
10514 types[MIPS_DF_FTYPE_DF_DF]
10515 = build_function_type_list (double_type_node,
10516 double_type_node, double_type_node, NULL_TREE);
10518 for (d = mips_bdesc; d < &mips_bdesc[ARRAY_SIZE (mips_bdesc)]; d++)
10519 if ((d->target_flags & target_flags) == d->target_flags)
10520 lang_hooks.builtin_function (d->name, types[d->ftype],
10521 d->code, BUILT_IN_MD, NULL, NULL_TREE);
10524 /* Expand a __builtin_mips_movt_*_ps() or __builtin_mips_movf_*_ps()
10525 function (MOVE_ON_TRUE says which). ARGLIST is the list of arguments
10526 to the function and ICODE says which instruction should be used to
10527 compare the first two arguments. TARGET, if nonnull, suggests a
10528 good place to put the result. */
10531 mips_expand_ps_cond_move_builtin (bool move_on_true, enum insn_code icode,
10532 rtx target, tree arglist)
10534 rtx cmp_result, op0, op1;
10536 cmp_result = mips_prepare_builtin_target (icode, 0, 0);
10537 op0 = mips_prepare_builtin_arg (icode, 1, &arglist);
10538 op1 = mips_prepare_builtin_arg (icode, 2, &arglist);
10539 emit_insn (GEN_FCN (icode) (cmp_result, op0, op1));
10541 icode = CODE_FOR_mips_cond_move_tf_ps;
10542 target = mips_prepare_builtin_target (icode, 0, target);
10545 op1 = mips_prepare_builtin_arg (icode, 2, &arglist);
10546 op0 = mips_prepare_builtin_arg (icode, 1, &arglist);
10550 op0 = mips_prepare_builtin_arg (icode, 1, &arglist);
10551 op1 = mips_prepare_builtin_arg (icode, 2, &arglist);
10553 emit_insn (gen_mips_cond_move_tf_ps (target, op0, op1, cmp_result));
10557 /* Use comparison instruction PAT to set condition-code register REG.
10558 If NONZERO_IF_EQUAL_P, return an rtx that is 1 if the new value of
10559 REG equals CONSTANT and 0 otherwise. Return the inverse if
10560 !NONZERO_IF_EQUAL_P. TARGET, if nonnull, suggests a good place
10564 mips_expand_compare_builtin (bool nonzero_if_equal_p, rtx target,
10565 rtx pat, rtx reg, int constant)
10567 rtx label1, label2, if_then_else;
10569 if (target == 0 || GET_MODE (target) != SImode)
10570 target = gen_reg_rtx (SImode);
10572 /* First assume that REG == CONSTANT. */
10573 emit_move_insn (target, nonzero_if_equal_p ? const1_rtx : const0_rtx);
10575 /* Branch to LABEL1 if REG != CONSTANT. */
10577 label1 = gen_label_rtx ();
10578 label2 = gen_label_rtx ();
10580 = gen_rtx_IF_THEN_ELSE (VOIDmode,
10581 gen_rtx_fmt_ee (NE, GET_MODE (reg),
10582 reg, GEN_INT (constant)),
10583 gen_rtx_LABEL_REF (VOIDmode, label1), pc_rtx);
10584 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, if_then_else));
10585 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
10586 gen_rtx_LABEL_REF (VOIDmode, label2)));
10588 emit_label (label1);
10590 /* Fix TARGET for REG != CONSTANT. */
10591 emit_move_insn (target, nonzero_if_equal_p ? const0_rtx : const1_rtx);
10592 emit_label (label2);
10597 /* Read two scalar arguments from ARGLIST and use instruction ICODE to
10598 compare them. Return the result as a boolean SImode value. TARGET,
10599 if nonnull, suggests a good place to put the result. */
10602 mips_expand_scalar_compare_builtin (enum insn_code icode, rtx target,
10605 rtx pat, cmp_result, op0, op1;
10607 cmp_result = mips_prepare_builtin_target (icode, 0, 0);
10608 op0 = mips_prepare_builtin_arg (icode, 1, &arglist);
10609 op1 = mips_prepare_builtin_arg (icode, 2, &arglist);
10610 pat = GEN_FCN (icode) (cmp_result, op0, op1);
10612 return mips_expand_compare_builtin (false, target, pat, cmp_result, 0);
10615 /* Read four V2SF arguments from ARGLIST and use instruction ICODE to
10616 compare them. Use CMP_CHOICE to convert the four condition codes
10617 into an SImode value. TARGET, if nonnull, suggests a good place
10618 to put this value. */
10621 mips_expand_4s_compare_builtin (enum mips_cmp_choice cmp_choice,
10622 enum insn_code icode, rtx target,
10625 rtx pat, cmp_result, op0, op1, op2, op3;
10628 cmp_result = mips_prepare_builtin_target (icode, 0, 0);
10629 op0 = mips_prepare_builtin_arg (icode, 1, &arglist);
10630 op1 = mips_prepare_builtin_arg (icode, 2, &arglist);
10631 op2 = mips_prepare_builtin_arg (icode, 3, &arglist);
10632 op3 = mips_prepare_builtin_arg (icode, 4, &arglist);
10633 pat = GEN_FCN (icode) (cmp_result, op0, op1, op2, op3);
10635 /* We fake the value of CCV4 to be:
10636 0 if all registers are false.
10637 -1 if all registers are true.
10638 an indeterminate value otherse.
10640 Thus, we can map "enum mips_cmp_choice" to RTL comparison operators:
10641 MIPS_CMP_ANY -> (NE 0)
10642 MIPS_CMP_ALL -> (EQ -1).
10644 However, because MIPS doesn't have "branch_all" instructions,
10645 for MIPS_CMP_ALL, we will use (NE -1) and reverse the assignment of
10646 the target to 1 first and then 0. */
10647 switch (cmp_choice)
10654 compare_value = -1;
10661 return mips_expand_compare_builtin (cmp_choice == MIPS_CMP_ALL,
10662 target, pat, cmp_result, compare_value);
10665 /* Like mips_expand_4s_compare_builtin, but compares two V2SF vectors rather
10666 than four. The arguments and return type are otherwise the same. */
10669 mips_expand_ps_compare_builtin (enum mips_cmp_choice cmp_choice,
10670 enum insn_code icode, rtx target,
10673 rtx pat, cmp_result, op0, op1;
10676 cmp_result = mips_prepare_builtin_target (icode, 0, 0);
10677 op0 = mips_prepare_builtin_arg (icode, 1, &arglist);
10678 op1 = mips_prepare_builtin_arg (icode, 2, &arglist);
10679 pat = GEN_FCN (icode) (cmp_result, op0, op1);
10681 /* We fake the value of CCV2 to be:
10682 0 if all registers are false.
10683 -1 if all registers are true.
10684 an indeterminate value otherse.
10686 Thus, we can map "enum mips_cmp_choice" to RTL comparison operators:
10687 MIPS_CMP_ANY -> (NE 0)
10688 MIPS_CMP_ALL -> (EQ -1).
10690 However, because MIPS doesn't have "branch_all" instructions,
10691 for MIPS_CMP_ALL, we will use (NE -1) and reverse the assignment of
10692 the target to 1 first and then 0.
10694 We handle MIPS_CMP_LOWER and MIPS_CMP_UPPER by taking the appropriate
10695 CCmode subreg and comparing against zero in the normal way. */
10696 switch (cmp_choice)
10702 case MIPS_CMP_UPPER:
10703 cmp_result = simplify_gen_subreg (CCmode, cmp_result, CCV2mode, 4);
10707 case MIPS_CMP_LOWER:
10708 cmp_result = simplify_gen_subreg (CCmode, cmp_result, CCV2mode, 0);
10713 compare_value = -1;
10720 return mips_expand_compare_builtin (cmp_choice == MIPS_CMP_ALL,
10721 target, pat, cmp_result, compare_value);
10724 #include "gt-mips.h"