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 void mips_init_builtins (void);
267 static rtx
mips_expand_builtin (tree
, rtx
, rtx
, enum machine_mode
, int);
268 static rtx
mips_expand_compare_builtin (rtx
, unsigned int, tree
);
269 static rtx
mips_expand_ps_compare_builtin (enum mips_cmp_choice
, rtx
,
271 static rtx
mips_expand_4s_compare_builtin (enum mips_cmp_choice
, rtx
,
273 static rtx
mips_expand_ps_cond_move_builtin (enum mips_cmp_choice
, rtx
,
276 /* Structure to be filled in by compute_frame_size with register
277 save masks, and offsets for the current function. */
279 struct mips_frame_info
GTY(())
281 HOST_WIDE_INT total_size
; /* # bytes that the entire frame takes up */
282 HOST_WIDE_INT var_size
; /* # bytes that variables take up */
283 HOST_WIDE_INT args_size
; /* # bytes that outgoing arguments take up */
284 HOST_WIDE_INT cprestore_size
; /* # bytes that the .cprestore slot takes up */
285 HOST_WIDE_INT gp_reg_size
; /* # bytes needed to store gp regs */
286 HOST_WIDE_INT fp_reg_size
; /* # bytes needed to store fp regs */
287 unsigned int mask
; /* mask of saved gp registers */
288 unsigned int fmask
; /* mask of saved fp registers */
289 HOST_WIDE_INT gp_save_offset
; /* offset from vfp to store gp registers */
290 HOST_WIDE_INT fp_save_offset
; /* offset from vfp to store fp registers */
291 HOST_WIDE_INT gp_sp_offset
; /* offset from new sp to store gp registers */
292 HOST_WIDE_INT fp_sp_offset
; /* offset from new sp to store fp registers */
293 bool initialized
; /* true if frame size already calculated */
294 int num_gp
; /* number of gp registers saved */
295 int num_fp
; /* number of fp registers saved */
298 struct machine_function
GTY(()) {
299 /* Pseudo-reg holding the value of $28 in a mips16 function which
300 refers to GP relative global variables. */
301 rtx mips16_gp_pseudo_rtx
;
303 /* Current frame information, calculated by compute_frame_size. */
304 struct mips_frame_info frame
;
306 /* The register to use as the global pointer within this function. */
307 unsigned int global_pointer
;
309 /* True if mips_adjust_insn_length should ignore an instruction's
311 bool ignore_hazard_length_p
;
313 /* True if the whole function is suitable for .set noreorder and
315 bool all_noreorder_p
;
317 /* True if the function is known to have an instruction that needs $gp. */
321 /* Information about a single argument. */
324 /* True if the argument is passed in a floating-point register, or
325 would have been if we hadn't run out of registers. */
328 /* The number of words passed in registers, rounded up. */
329 unsigned int reg_words
;
331 /* The offset of the first register from GP_ARG_FIRST or FP_ARG_FIRST,
332 or MAX_ARGS_IN_REGISTERS if the argument is passed entirely
334 unsigned int reg_offset
;
336 /* The number of words that must be passed on the stack, rounded up. */
337 unsigned int stack_words
;
339 /* The offset from the start of the stack overflow area of the argument's
340 first stack word. Only meaningful when STACK_WORDS is nonzero. */
341 unsigned int stack_offset
;
345 /* Information about an address described by mips_address_type.
351 REG is the base register and OFFSET is the constant offset.
354 REG is the register that contains the high part of the address,
355 OFFSET is the symbolic address being referenced and SYMBOL_TYPE
356 is the type of OFFSET's symbol.
359 SYMBOL_TYPE is the type of symbol being referenced. */
361 struct mips_address_info
363 enum mips_address_type type
;
366 enum mips_symbol_type symbol_type
;
370 /* One stage in a constant building sequence. These sequences have
374 A = A CODE[1] VALUE[1]
375 A = A CODE[2] VALUE[2]
378 where A is an accumulator, each CODE[i] is a binary rtl operation
379 and each VALUE[i] is a constant integer. */
380 struct mips_integer_op
{
382 unsigned HOST_WIDE_INT value
;
386 /* The largest number of operations needed to load an integer constant.
387 The worst accepted case for 64-bit constants is LUI,ORI,SLL,ORI,SLL,ORI.
388 When the lowest bit is clear, we can try, but reject a sequence with
389 an extra SLL at the end. */
390 #define MIPS_MAX_INTEGER_OPS 7
393 /* Global variables for machine-dependent things. */
395 /* Threshold for data being put into the small data/bss area, instead
396 of the normal data area. */
397 int mips_section_threshold
= -1;
399 /* Count the number of .file directives, so that .loc is up to date. */
400 int num_source_filenames
= 0;
402 /* Count the number of sdb related labels are generated (to find block
403 start and end boundaries). */
404 int sdb_label_count
= 0;
406 /* Next label # for each statement for Silicon Graphics IRIS systems. */
409 /* Linked list of all externals that are to be emitted when optimizing
410 for the global pointer if they haven't been declared by the end of
411 the program with an appropriate .comm or initialization. */
413 struct extern_list
GTY (())
415 struct extern_list
*next
; /* next external */
416 const char *name
; /* name of the external */
417 int size
; /* size in bytes */
420 static GTY (()) struct extern_list
*extern_head
= 0;
422 /* Name of the file containing the current function. */
423 const char *current_function_file
= "";
425 /* Number of nested .set noreorder, noat, nomacro, and volatile requests. */
431 /* The next branch instruction is a branch likely, not branch normal. */
432 int mips_branch_likely
;
434 /* The operands passed to the last cmpMM expander. */
437 /* The target cpu for code generation. */
438 enum processor_type mips_arch
;
439 const struct mips_cpu_info
*mips_arch_info
;
441 /* The target cpu for optimization and scheduling. */
442 enum processor_type mips_tune
;
443 const struct mips_cpu_info
*mips_tune_info
;
445 /* Which instruction set architecture to use. */
448 /* Which ABI to use. */
451 /* Strings to hold which cpu and instruction set architecture to use. */
452 const char *mips_arch_string
; /* for -march=<xxx> */
453 const char *mips_tune_string
; /* for -mtune=<xxx> */
454 const char *mips_isa_string
; /* for -mips{1,2,3,4} */
455 const char *mips_abi_string
; /* for -mabi={32,n32,64,eabi} */
457 /* Whether we are generating mips16 hard float code. In mips16 mode
458 we always set TARGET_SOFT_FLOAT; this variable is nonzero if
459 -msoft-float was not specified by the user, which means that we
460 should arrange to call mips32 hard floating point code. */
461 int mips16_hard_float
;
463 const char *mips_cache_flush_func
= CACHE_FLUSH_FUNC
;
465 /* If TRUE, we split addresses into their high and low parts in the RTL. */
466 int mips_split_addresses
;
468 /* Mode used for saving/restoring general purpose registers. */
469 static enum machine_mode gpr_mode
;
471 /* Array giving truth value on whether or not a given hard register
472 can support a given mode. */
473 char mips_hard_regno_mode_ok
[(int)MAX_MACHINE_MODE
][FIRST_PSEUDO_REGISTER
];
475 /* List of all MIPS punctuation characters used by print_operand. */
476 char mips_print_operand_punct
[256];
478 /* Map GCC register number to debugger register number. */
479 int mips_dbx_regno
[FIRST_PSEUDO_REGISTER
];
481 /* A copy of the original flag_delayed_branch: see override_options. */
482 static int mips_flag_delayed_branch
;
484 static GTY (()) int mips_output_filename_first_time
= 1;
486 /* mips_split_p[X] is true if symbols of type X can be split by
487 mips_split_symbol(). */
488 static bool mips_split_p
[NUM_SYMBOL_TYPES
];
490 /* mips_lo_relocs[X] is the relocation to use when a symbol of type X
491 appears in a LO_SUM. It can be null if such LO_SUMs aren't valid or
492 if they are matched by a special .md file pattern. */
493 static const char *mips_lo_relocs
[NUM_SYMBOL_TYPES
];
495 /* Likewise for HIGHs. */
496 static const char *mips_hi_relocs
[NUM_SYMBOL_TYPES
];
498 /* Map hard register number to register class */
499 const enum reg_class mips_regno_to_class
[] =
501 LEA_REGS
, LEA_REGS
, M16_NA_REGS
, M16_NA_REGS
,
502 M16_REGS
, M16_REGS
, M16_REGS
, M16_REGS
,
503 LEA_REGS
, LEA_REGS
, LEA_REGS
, LEA_REGS
,
504 LEA_REGS
, LEA_REGS
, LEA_REGS
, LEA_REGS
,
505 M16_NA_REGS
, M16_NA_REGS
, LEA_REGS
, LEA_REGS
,
506 LEA_REGS
, LEA_REGS
, LEA_REGS
, LEA_REGS
,
507 T_REG
, PIC_FN_ADDR_REG
, LEA_REGS
, LEA_REGS
,
508 LEA_REGS
, LEA_REGS
, LEA_REGS
, LEA_REGS
,
509 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
510 FP_REGS
, FP_REGS
, FP_REGS
, FP_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 HI_REG
, LO_REG
, NO_REGS
, ST_REGS
,
518 ST_REGS
, ST_REGS
, ST_REGS
, ST_REGS
,
519 ST_REGS
, ST_REGS
, ST_REGS
, NO_REGS
,
520 NO_REGS
, ALL_REGS
, ALL_REGS
, NO_REGS
,
521 COP0_REGS
, COP0_REGS
, COP0_REGS
, COP0_REGS
,
522 COP0_REGS
, COP0_REGS
, COP0_REGS
, COP0_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 COP2_REGS
, COP2_REGS
, COP2_REGS
, COP2_REGS
,
530 COP2_REGS
, COP2_REGS
, COP2_REGS
, COP2_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 COP3_REGS
, COP3_REGS
, COP3_REGS
, COP3_REGS
,
538 COP3_REGS
, COP3_REGS
, COP3_REGS
, COP3_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
547 /* Map register constraint character to register class. */
548 enum reg_class mips_char_to_class
[256];
550 /* A table describing all the processors gcc knows about. Names are
551 matched in the order listed. The first mention of an ISA level is
552 taken as the canonical name for that ISA.
554 To ease comparison, please keep this table in the same order as
555 gas's mips_cpu_info_table[]. */
556 const struct mips_cpu_info mips_cpu_info_table
[] = {
557 /* Entries for generic ISAs */
558 { "mips1", PROCESSOR_R3000
, 1 },
559 { "mips2", PROCESSOR_R6000
, 2 },
560 { "mips3", PROCESSOR_R4000
, 3 },
561 { "mips4", PROCESSOR_R8000
, 4 },
562 { "mips32", PROCESSOR_4KC
, 32 },
563 { "mips32r2", PROCESSOR_M4K
, 33 },
564 { "mips64", PROCESSOR_5KC
, 64 },
567 { "r3000", PROCESSOR_R3000
, 1 },
568 { "r2000", PROCESSOR_R3000
, 1 }, /* = r3000 */
569 { "r3900", PROCESSOR_R3900
, 1 },
572 { "r6000", PROCESSOR_R6000
, 2 },
575 { "r4000", PROCESSOR_R4000
, 3 },
576 { "vr4100", PROCESSOR_R4100
, 3 },
577 { "vr4111", PROCESSOR_R4111
, 3 },
578 { "vr4120", PROCESSOR_R4120
, 3 },
579 { "vr4130", PROCESSOR_R4130
, 3 },
580 { "vr4300", PROCESSOR_R4300
, 3 },
581 { "r4400", PROCESSOR_R4000
, 3 }, /* = r4000 */
582 { "r4600", PROCESSOR_R4600
, 3 },
583 { "orion", PROCESSOR_R4600
, 3 }, /* = r4600 */
584 { "r4650", PROCESSOR_R4650
, 3 },
587 { "r8000", PROCESSOR_R8000
, 4 },
588 { "vr5000", PROCESSOR_R5000
, 4 },
589 { "vr5400", PROCESSOR_R5400
, 4 },
590 { "vr5500", PROCESSOR_R5500
, 4 },
591 { "rm7000", PROCESSOR_R7000
, 4 },
592 { "rm9000", PROCESSOR_R9000
, 4 },
595 { "4kc", PROCESSOR_4KC
, 32 },
596 { "4kp", PROCESSOR_4KC
, 32 }, /* = 4kc */
598 /* MIPS32 Release 2 */
599 { "m4k", PROCESSOR_M4K
, 33 },
602 { "5kc", PROCESSOR_5KC
, 64 },
603 { "20kc", PROCESSOR_20KC
, 64 },
604 { "sb1", PROCESSOR_SB1
, 64 },
605 { "sr71000", PROCESSOR_SR71000
, 64 },
611 /* Nonzero if -march should decide the default value of MASK_SOFT_FLOAT. */
612 #ifndef MIPS_MARCH_CONTROLS_SOFT_FLOAT
613 #define MIPS_MARCH_CONTROLS_SOFT_FLOAT 0
616 /* Initialize the GCC target structure. */
617 #undef TARGET_ASM_ALIGNED_HI_OP
618 #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
619 #undef TARGET_ASM_ALIGNED_SI_OP
620 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
621 #undef TARGET_ASM_ALIGNED_DI_OP
622 #define TARGET_ASM_ALIGNED_DI_OP "\t.dword\t"
624 #undef TARGET_ASM_FUNCTION_PROLOGUE
625 #define TARGET_ASM_FUNCTION_PROLOGUE mips_output_function_prologue
626 #undef TARGET_ASM_FUNCTION_EPILOGUE
627 #define TARGET_ASM_FUNCTION_EPILOGUE mips_output_function_epilogue
628 #undef TARGET_ASM_SELECT_RTX_SECTION
629 #define TARGET_ASM_SELECT_RTX_SECTION mips_select_rtx_section
631 #undef TARGET_SCHED_REORDER
632 #define TARGET_SCHED_REORDER mips_sched_reorder
633 #undef TARGET_SCHED_VARIABLE_ISSUE
634 #define TARGET_SCHED_VARIABLE_ISSUE mips_variable_issue
635 #undef TARGET_SCHED_ADJUST_COST
636 #define TARGET_SCHED_ADJUST_COST mips_adjust_cost
637 #undef TARGET_SCHED_ISSUE_RATE
638 #define TARGET_SCHED_ISSUE_RATE mips_issue_rate
639 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
640 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
641 mips_multipass_dfa_lookahead
643 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
644 #define TARGET_FUNCTION_OK_FOR_SIBCALL mips_function_ok_for_sibcall
646 #undef TARGET_VALID_POINTER_MODE
647 #define TARGET_VALID_POINTER_MODE mips_valid_pointer_mode
648 #undef TARGET_RTX_COSTS
649 #define TARGET_RTX_COSTS mips_rtx_costs
650 #undef TARGET_ADDRESS_COST
651 #define TARGET_ADDRESS_COST mips_address_cost
653 #undef TARGET_IN_SMALL_DATA_P
654 #define TARGET_IN_SMALL_DATA_P mips_in_small_data_p
656 #undef TARGET_MACHINE_DEPENDENT_REORG
657 #define TARGET_MACHINE_DEPENDENT_REORG mips_reorg
659 #undef TARGET_ASM_FILE_START
660 #undef TARGET_ASM_FILE_END
661 #define TARGET_ASM_FILE_START mips_file_start
662 #define TARGET_ASM_FILE_END mips_file_end
663 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
664 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
666 #undef TARGET_INIT_LIBFUNCS
667 #define TARGET_INIT_LIBFUNCS mips_init_libfuncs
669 #undef TARGET_BUILD_BUILTIN_VA_LIST
670 #define TARGET_BUILD_BUILTIN_VA_LIST mips_build_builtin_va_list
671 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
672 #define TARGET_GIMPLIFY_VA_ARG_EXPR mips_gimplify_va_arg_expr
674 #undef TARGET_PROMOTE_FUNCTION_ARGS
675 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
676 #undef TARGET_PROMOTE_FUNCTION_RETURN
677 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
678 #undef TARGET_PROMOTE_PROTOTYPES
679 #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
681 #undef TARGET_RETURN_IN_MEMORY
682 #define TARGET_RETURN_IN_MEMORY mips_return_in_memory
683 #undef TARGET_RETURN_IN_MSB
684 #define TARGET_RETURN_IN_MSB mips_return_in_msb
686 #undef TARGET_ASM_OUTPUT_MI_THUNK
687 #define TARGET_ASM_OUTPUT_MI_THUNK mips_output_mi_thunk
688 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
689 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
691 #undef TARGET_SETUP_INCOMING_VARARGS
692 #define TARGET_SETUP_INCOMING_VARARGS mips_setup_incoming_varargs
693 #undef TARGET_STRICT_ARGUMENT_NAMING
694 #define TARGET_STRICT_ARGUMENT_NAMING mips_strict_argument_naming
695 #undef TARGET_MUST_PASS_IN_STACK
696 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
697 #undef TARGET_PASS_BY_REFERENCE
698 #define TARGET_PASS_BY_REFERENCE mips_pass_by_reference
700 #undef TARGET_VECTOR_MODE_SUPPORTED_P
701 #define TARGET_VECTOR_MODE_SUPPORTED_P mips_vector_mode_supported_p
703 #undef TARGET_INIT_BUILTINS
704 #define TARGET_INIT_BUILTINS mips_init_builtins
705 #undef TARGET_EXPAND_BUILTIN
706 #define TARGET_EXPAND_BUILTIN mips_expand_builtin
708 struct gcc_target targetm
= TARGET_INITIALIZER
;
710 /* Classify symbol X, which must be a SYMBOL_REF or a LABEL_REF. */
712 static enum mips_symbol_type
713 mips_classify_symbol (rtx x
)
715 if (GET_CODE (x
) == LABEL_REF
)
718 return SYMBOL_CONSTANT_POOL
;
720 return SYMBOL_GOT_LOCAL
;
721 return SYMBOL_GENERAL
;
724 if (GET_CODE (x
) != SYMBOL_REF
)
727 if (CONSTANT_POOL_ADDRESS_P (x
))
730 return SYMBOL_CONSTANT_POOL
;
733 return SYMBOL_GOT_LOCAL
;
735 if (GET_MODE_SIZE (get_pool_mode (x
)) <= mips_section_threshold
)
736 return SYMBOL_SMALL_DATA
;
738 return SYMBOL_GENERAL
;
741 if (SYMBOL_REF_SMALL_P (x
))
742 return SYMBOL_SMALL_DATA
;
746 if (SYMBOL_REF_DECL (x
) == 0)
747 return SYMBOL_REF_LOCAL_P (x
) ? SYMBOL_GOT_LOCAL
: SYMBOL_GOT_GLOBAL
;
749 /* There are three cases to consider:
751 - o32 PIC (either with or without explicit relocs)
752 - n32/n64 PIC without explicit relocs
753 - n32/n64 PIC with explicit relocs
755 In the first case, both local and global accesses will use an
756 R_MIPS_GOT16 relocation. We must correctly predict which of
757 the two semantics (local or global) the assembler and linker
758 will apply. The choice doesn't depend on the symbol's
759 visibility, so we deliberately ignore decl_visibility and
762 In the second case, the assembler will not use R_MIPS_GOT16
763 relocations, but it chooses between local and global accesses
764 in the same way as for o32 PIC.
766 In the third case we have more freedom since both forms of
767 access will work for any kind of symbol. However, there seems
768 little point in doing things differently. */
769 if (DECL_P (SYMBOL_REF_DECL (x
)) && TREE_PUBLIC (SYMBOL_REF_DECL (x
)))
770 return SYMBOL_GOT_GLOBAL
;
772 return SYMBOL_GOT_LOCAL
;
775 return SYMBOL_GENERAL
;
779 /* Split X into a base and a constant offset, storing them in *BASE
780 and *OFFSET respectively. */
783 mips_split_const (rtx x
, rtx
*base
, HOST_WIDE_INT
*offset
)
787 if (GET_CODE (x
) == CONST
)
790 if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == CONST_INT
)
792 *offset
+= INTVAL (XEXP (x
, 1));
799 /* Return true if SYMBOL is a SYMBOL_REF and OFFSET + SYMBOL points
800 to the same object as SYMBOL. */
803 mips_offset_within_object_p (rtx symbol
, HOST_WIDE_INT offset
)
805 if (GET_CODE (symbol
) != SYMBOL_REF
)
808 if (CONSTANT_POOL_ADDRESS_P (symbol
)
810 && offset
< (int) GET_MODE_SIZE (get_pool_mode (symbol
)))
813 if (SYMBOL_REF_DECL (symbol
) != 0
815 && offset
< int_size_in_bytes (TREE_TYPE (SYMBOL_REF_DECL (symbol
))))
822 /* Return true if X is a symbolic constant that can be calculated in
823 the same way as a bare symbol. If it is, store the type of the
824 symbol in *SYMBOL_TYPE. */
827 mips_symbolic_constant_p (rtx x
, enum mips_symbol_type
*symbol_type
)
829 HOST_WIDE_INT offset
;
831 mips_split_const (x
, &x
, &offset
);
832 if (UNSPEC_ADDRESS_P (x
))
833 *symbol_type
= UNSPEC_ADDRESS_TYPE (x
);
834 else if (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == LABEL_REF
)
835 *symbol_type
= mips_classify_symbol (x
);
842 /* Check whether a nonzero offset is valid for the underlying
844 switch (*symbol_type
)
850 /* If the target has 64-bit pointers and the object file only
851 supports 32-bit symbols, the values of those symbols will be
852 sign-extended. In this case we can't allow an arbitrary offset
853 in case the 32-bit value X + OFFSET has a different sign from X. */
854 if (Pmode
== DImode
&& !ABI_HAS_64BIT_SYMBOLS
)
855 return mips_offset_within_object_p (x
, offset
);
857 /* In other cases the relocations can handle any offset. */
860 case SYMBOL_CONSTANT_POOL
:
861 /* Allow constant pool references to be converted to LABEL+CONSTANT.
862 In this case, we no longer have access to the underlying constant,
863 but the original symbol-based access was known to be valid. */
864 if (GET_CODE (x
) == LABEL_REF
)
869 case SYMBOL_SMALL_DATA
:
870 /* Make sure that the offset refers to something within the
871 underlying object. This should guarantee that the final
872 PC- or GP-relative offset is within the 16-bit limit. */
873 return mips_offset_within_object_p (x
, offset
);
875 case SYMBOL_GOT_LOCAL
:
876 case SYMBOL_GOTOFF_PAGE
:
877 /* The linker should provide enough local GOT entries for a
878 16-bit offset. Larger offsets may lead to GOT overflow. */
879 return SMALL_OPERAND (offset
);
881 case SYMBOL_GOT_GLOBAL
:
882 case SYMBOL_GOTOFF_GLOBAL
:
883 case SYMBOL_GOTOFF_CALL
:
884 case SYMBOL_GOTOFF_LOADGP
:
891 /* Return true if X is a symbolic constant whose value is not split
892 into separate relocations. */
895 mips_atomic_symbolic_constant_p (rtx x
)
897 enum mips_symbol_type type
;
898 return mips_symbolic_constant_p (x
, &type
) && !mips_split_p
[type
];
902 /* This function is used to implement REG_MODE_OK_FOR_BASE_P. */
905 mips_regno_mode_ok_for_base_p (int regno
, enum machine_mode mode
, int strict
)
907 if (regno
>= FIRST_PSEUDO_REGISTER
)
911 regno
= reg_renumber
[regno
];
914 /* These fake registers will be eliminated to either the stack or
915 hard frame pointer, both of which are usually valid base registers.
916 Reload deals with the cases where the eliminated form isn't valid. */
917 if (regno
== ARG_POINTER_REGNUM
|| regno
== FRAME_POINTER_REGNUM
)
920 /* In mips16 mode, the stack pointer can only address word and doubleword
921 values, nothing smaller. There are two problems here:
923 (a) Instantiating virtual registers can introduce new uses of the
924 stack pointer. If these virtual registers are valid addresses,
925 the stack pointer should be too.
927 (b) Most uses of the stack pointer are not made explicit until
928 FRAME_POINTER_REGNUM and ARG_POINTER_REGNUM have been eliminated.
929 We don't know until that stage whether we'll be eliminating to the
930 stack pointer (which needs the restriction) or the hard frame
931 pointer (which doesn't).
933 All in all, it seems more consistent to only enforce this restriction
934 during and after reload. */
935 if (TARGET_MIPS16
&& regno
== STACK_POINTER_REGNUM
)
936 return !strict
|| GET_MODE_SIZE (mode
) == 4 || GET_MODE_SIZE (mode
) == 8;
938 return TARGET_MIPS16
? M16_REG_P (regno
) : GP_REG_P (regno
);
942 /* Return true if X is a valid base register for the given mode.
943 Allow only hard registers if STRICT. */
946 mips_valid_base_register_p (rtx x
, enum machine_mode mode
, int strict
)
948 if (!strict
&& GET_CODE (x
) == SUBREG
)
951 return (GET_CODE (x
) == REG
952 && mips_regno_mode_ok_for_base_p (REGNO (x
), mode
, strict
));
956 /* Return true if symbols of type SYMBOL_TYPE can directly address a value
957 with mode MODE. This is used for both symbolic and LO_SUM addresses. */
960 mips_symbolic_address_p (enum mips_symbol_type symbol_type
,
961 enum machine_mode mode
)
966 return !TARGET_MIPS16
;
968 case SYMBOL_SMALL_DATA
:
971 case SYMBOL_CONSTANT_POOL
:
972 /* PC-relative addressing is only available for lw and ld. */
973 return GET_MODE_SIZE (mode
) == 4 || GET_MODE_SIZE (mode
) == 8;
975 case SYMBOL_GOT_LOCAL
:
978 case SYMBOL_GOT_GLOBAL
:
979 /* The address will have to be loaded from the GOT first. */
982 case SYMBOL_GOTOFF_PAGE
:
983 case SYMBOL_GOTOFF_GLOBAL
:
984 case SYMBOL_GOTOFF_CALL
:
985 case SYMBOL_GOTOFF_LOADGP
:
995 /* Return true if X is a valid address for machine mode MODE. If it is,
996 fill in INFO appropriately. STRICT is true if we should only accept
997 hard base registers. */
1000 mips_classify_address (struct mips_address_info
*info
, rtx x
,
1001 enum machine_mode mode
, int strict
)
1003 switch (GET_CODE (x
))
1007 info
->type
= ADDRESS_REG
;
1009 info
->offset
= const0_rtx
;
1010 return mips_valid_base_register_p (info
->reg
, mode
, strict
);
1013 info
->type
= ADDRESS_REG
;
1014 info
->reg
= XEXP (x
, 0);
1015 info
->offset
= XEXP (x
, 1);
1016 return (mips_valid_base_register_p (info
->reg
, mode
, strict
)
1017 && const_arith_operand (info
->offset
, VOIDmode
));
1020 info
->type
= ADDRESS_LO_SUM
;
1021 info
->reg
= XEXP (x
, 0);
1022 info
->offset
= XEXP (x
, 1);
1023 return (mips_valid_base_register_p (info
->reg
, mode
, strict
)
1024 && mips_symbolic_constant_p (info
->offset
, &info
->symbol_type
)
1025 && mips_symbolic_address_p (info
->symbol_type
, mode
)
1026 && mips_lo_relocs
[info
->symbol_type
] != 0);
1029 /* Small-integer addresses don't occur very often, but they
1030 are legitimate if $0 is a valid base register. */
1031 info
->type
= ADDRESS_CONST_INT
;
1032 return !TARGET_MIPS16
&& SMALL_INT (x
);
1037 info
->type
= ADDRESS_SYMBOLIC
;
1038 return (mips_symbolic_constant_p (x
, &info
->symbol_type
)
1039 && mips_symbolic_address_p (info
->symbol_type
, mode
)
1040 && !mips_split_p
[info
->symbol_type
]);
1047 /* Return the number of instructions needed to load a symbol of the
1048 given type into a register. If valid in an address, the same number
1049 of instructions are needed for loads and stores. Treat extended
1050 mips16 instructions as two instructions. */
1053 mips_symbol_insns (enum mips_symbol_type type
)
1057 case SYMBOL_GENERAL
:
1058 /* In mips16 code, general symbols must be fetched from the
1063 /* When using 64-bit symbols, we need 5 preparatory instructions,
1066 lui $at,%highest(symbol)
1067 daddiu $at,$at,%higher(symbol)
1069 daddiu $at,$at,%hi(symbol)
1072 The final address is then $at + %lo(symbol). With 32-bit
1073 symbols we just need a preparatory lui. */
1074 return (ABI_HAS_64BIT_SYMBOLS
? 6 : 2);
1076 case SYMBOL_SMALL_DATA
:
1079 case SYMBOL_CONSTANT_POOL
:
1080 /* This case is for mips16 only. Assume we'll need an
1081 extended instruction. */
1084 case SYMBOL_GOT_LOCAL
:
1085 case SYMBOL_GOT_GLOBAL
:
1086 /* Unless -funit-at-a-time is in effect, we can't be sure whether
1087 the local/global classification is accurate. See override_options
1090 The worst cases are:
1092 (1) For local symbols when generating o32 or o64 code. The assembler
1098 ...and the final address will be $at + %lo(symbol).
1100 (2) For global symbols when -mxgot. The assembler will use:
1102 lui $at,%got_hi(symbol)
1105 ...and the final address will be $at + %got_lo(symbol). */
1108 case SYMBOL_GOTOFF_PAGE
:
1109 case SYMBOL_GOTOFF_GLOBAL
:
1110 case SYMBOL_GOTOFF_CALL
:
1111 case SYMBOL_GOTOFF_LOADGP
:
1112 case SYMBOL_64_HIGH
:
1115 /* Check whether the offset is a 16- or 32-bit value. */
1116 return mips_split_p
[type
] ? 2 : 1;
1121 /* Return true if X is a legitimate $sp-based address for mode MDOE. */
1124 mips_stack_address_p (rtx x
, enum machine_mode mode
)
1126 struct mips_address_info addr
;
1128 return (mips_classify_address (&addr
, x
, mode
, false)
1129 && addr
.type
== ADDRESS_REG
1130 && addr
.reg
== stack_pointer_rtx
);
1133 /* Return true if a value at OFFSET bytes from BASE can be accessed
1134 using an unextended mips16 instruction. MODE is the mode of the
1137 Usually the offset in an unextended instruction is a 5-bit field.
1138 The offset is unsigned and shifted left once for HIs, twice
1139 for SIs, and so on. An exception is SImode accesses off the
1140 stack pointer, which have an 8-bit immediate field. */
1143 mips16_unextended_reference_p (enum machine_mode mode
, rtx base
, rtx offset
)
1146 && GET_CODE (offset
) == CONST_INT
1147 && INTVAL (offset
) >= 0
1148 && (INTVAL (offset
) & (GET_MODE_SIZE (mode
) - 1)) == 0)
1150 if (GET_MODE_SIZE (mode
) == 4 && base
== stack_pointer_rtx
)
1151 return INTVAL (offset
) < 256 * GET_MODE_SIZE (mode
);
1152 return INTVAL (offset
) < 32 * GET_MODE_SIZE (mode
);
1158 /* Return the number of instructions needed to load or store a value
1159 of mode MODE at X. Return 0 if X isn't valid for MODE.
1161 For mips16 code, count extended instructions as two instructions. */
1164 mips_address_insns (rtx x
, enum machine_mode mode
)
1166 struct mips_address_info addr
;
1169 if (mode
== BLKmode
)
1170 /* BLKmode is used for single unaligned loads and stores. */
1173 /* Each word of a multi-word value will be accessed individually. */
1174 factor
= (GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
1176 if (mips_classify_address (&addr
, x
, mode
, false))
1181 && !mips16_unextended_reference_p (mode
, addr
.reg
, addr
.offset
))
1185 case ADDRESS_LO_SUM
:
1186 return (TARGET_MIPS16
? factor
* 2 : factor
);
1188 case ADDRESS_CONST_INT
:
1191 case ADDRESS_SYMBOLIC
:
1192 return factor
* mips_symbol_insns (addr
.symbol_type
);
1198 /* Likewise for constant X. */
1201 mips_const_insns (rtx x
)
1203 struct mips_integer_op codes
[MIPS_MAX_INTEGER_OPS
];
1204 enum mips_symbol_type symbol_type
;
1205 HOST_WIDE_INT offset
;
1207 switch (GET_CODE (x
))
1211 || !mips_symbolic_constant_p (XEXP (x
, 0), &symbol_type
)
1212 || !mips_split_p
[symbol_type
])
1219 /* Unsigned 8-bit constants can be loaded using an unextended
1220 LI instruction. Unsigned 16-bit constants can be loaded
1221 using an extended LI. Negative constants must be loaded
1222 using LI and then negated. */
1223 return (INTVAL (x
) >= 0 && INTVAL (x
) < 256 ? 1
1224 : SMALL_OPERAND_UNSIGNED (INTVAL (x
)) ? 2
1225 : INTVAL (x
) > -256 && INTVAL (x
) < 0 ? 2
1226 : SMALL_OPERAND_UNSIGNED (-INTVAL (x
)) ? 3
1229 return mips_build_integer (codes
, INTVAL (x
));
1233 return (!TARGET_MIPS16
&& x
== CONST0_RTX (GET_MODE (x
)) ? 1 : 0);
1239 /* See if we can refer to X directly. */
1240 if (mips_symbolic_constant_p (x
, &symbol_type
))
1241 return mips_symbol_insns (symbol_type
);
1243 /* Otherwise try splitting the constant into a base and offset.
1244 16-bit offsets can be added using an extra addiu. Larger offsets
1245 must be calculated separately and then added to the base. */
1246 mips_split_const (x
, &x
, &offset
);
1249 int n
= mips_const_insns (x
);
1252 if (SMALL_OPERAND (offset
))
1255 return n
+ 1 + mips_build_integer (codes
, offset
);
1262 return mips_symbol_insns (mips_classify_symbol (x
));
1270 /* Return the number of instructions needed for memory reference X.
1271 Count extended mips16 instructions as two instructions. */
1274 mips_fetch_insns (rtx x
)
1276 if (GET_CODE (x
) != MEM
)
1279 return mips_address_insns (XEXP (x
, 0), GET_MODE (x
));
1283 /* Return the number of instructions needed for an integer division. */
1286 mips_idiv_insns (void)
1291 if (TARGET_CHECK_ZERO_DIV
)
1293 if (TARGET_FIX_R4000
|| TARGET_FIX_R4400
)
1298 /* This function is used to implement GO_IF_LEGITIMATE_ADDRESS. It
1299 returns a nonzero value if X is a legitimate address for a memory
1300 operand of the indicated MODE. STRICT is nonzero if this function
1301 is called during reload. */
1304 mips_legitimate_address_p (enum machine_mode mode
, rtx x
, int strict
)
1306 struct mips_address_info addr
;
1308 return mips_classify_address (&addr
, x
, mode
, strict
);
1312 /* Copy VALUE to a register and return that register. If new psuedos
1313 are allowed, copy it into a new register, otherwise use DEST. */
1316 mips_force_temporary (rtx dest
, rtx value
)
1318 if (!no_new_pseudos
)
1319 return force_reg (Pmode
, value
);
1322 emit_move_insn (copy_rtx (dest
), value
);
1328 /* Return a LO_SUM expression for ADDR. TEMP is as for mips_force_temporary
1329 and is used to load the high part into a register. */
1332 mips_split_symbol (rtx temp
, rtx addr
)
1337 high
= mips16_gp_pseudo_reg ();
1339 high
= mips_force_temporary (temp
, gen_rtx_HIGH (Pmode
, copy_rtx (addr
)));
1340 return gen_rtx_LO_SUM (Pmode
, high
, addr
);
1344 /* Return an UNSPEC address with underlying address ADDRESS and symbol
1345 type SYMBOL_TYPE. */
1348 mips_unspec_address (rtx address
, enum mips_symbol_type symbol_type
)
1351 HOST_WIDE_INT offset
;
1353 mips_split_const (address
, &base
, &offset
);
1354 base
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, base
),
1355 UNSPEC_ADDRESS_FIRST
+ symbol_type
);
1356 return plus_constant (gen_rtx_CONST (Pmode
, base
), offset
);
1360 /* If mips_unspec_address (ADDR, SYMBOL_TYPE) is a 32-bit value, add the
1361 high part to BASE and return the result. Just return BASE otherwise.
1362 TEMP is available as a temporary register if needed.
1364 The returned expression can be used as the first operand to a LO_SUM. */
1367 mips_unspec_offset_high (rtx temp
, rtx base
, rtx addr
,
1368 enum mips_symbol_type symbol_type
)
1370 if (mips_split_p
[symbol_type
])
1372 addr
= gen_rtx_HIGH (Pmode
, mips_unspec_address (addr
, symbol_type
));
1373 addr
= mips_force_temporary (temp
, addr
);
1374 return mips_force_temporary (temp
, gen_rtx_PLUS (Pmode
, addr
, base
));
1380 /* Return a legitimate address for REG + OFFSET. TEMP is as for
1381 mips_force_temporary; it is only needed when OFFSET is not a
1385 mips_add_offset (rtx temp
, rtx reg
, HOST_WIDE_INT offset
)
1387 if (!SMALL_OPERAND (offset
))
1392 /* Load the full offset into a register so that we can use
1393 an unextended instruction for the address itself. */
1394 high
= GEN_INT (offset
);
1399 /* Leave OFFSET as a 16-bit offset and put the excess in HIGH. */
1400 high
= GEN_INT (CONST_HIGH_PART (offset
));
1401 offset
= CONST_LOW_PART (offset
);
1403 high
= mips_force_temporary (temp
, high
);
1404 reg
= mips_force_temporary (temp
, gen_rtx_PLUS (Pmode
, high
, reg
));
1406 return plus_constant (reg
, offset
);
1410 /* This function is used to implement LEGITIMIZE_ADDRESS. If *XLOC can
1411 be legitimized in a way that the generic machinery might not expect,
1412 put the new address in *XLOC and return true. MODE is the mode of
1413 the memory being accessed. */
1416 mips_legitimize_address (rtx
*xloc
, enum machine_mode mode
)
1418 enum mips_symbol_type symbol_type
;
1420 /* See if the address can split into a high part and a LO_SUM. */
1421 if (mips_symbolic_constant_p (*xloc
, &symbol_type
)
1422 && mips_symbolic_address_p (symbol_type
, mode
)
1423 && mips_split_p
[symbol_type
])
1425 *xloc
= mips_split_symbol (0, *xloc
);
1429 if (GET_CODE (*xloc
) == PLUS
&& GET_CODE (XEXP (*xloc
, 1)) == CONST_INT
)
1431 /* Handle REG + CONSTANT using mips_add_offset. */
1434 reg
= XEXP (*xloc
, 0);
1435 if (!mips_valid_base_register_p (reg
, mode
, 0))
1436 reg
= copy_to_mode_reg (Pmode
, reg
);
1437 *xloc
= mips_add_offset (0, reg
, INTVAL (XEXP (*xloc
, 1)));
1445 /* Subroutine of mips_build_integer (with the same interface).
1446 Assume that the final action in the sequence should be a left shift. */
1449 mips_build_shift (struct mips_integer_op
*codes
, HOST_WIDE_INT value
)
1451 unsigned int i
, shift
;
1453 /* Shift VALUE right until its lowest bit is set. Shift arithmetically
1454 since signed numbers are easier to load than unsigned ones. */
1456 while ((value
& 1) == 0)
1457 value
/= 2, shift
++;
1459 i
= mips_build_integer (codes
, value
);
1460 codes
[i
].code
= ASHIFT
;
1461 codes
[i
].value
= shift
;
1466 /* As for mips_build_shift, but assume that the final action will be
1467 an IOR or PLUS operation. */
1470 mips_build_lower (struct mips_integer_op
*codes
, unsigned HOST_WIDE_INT value
)
1472 unsigned HOST_WIDE_INT high
;
1475 high
= value
& ~(unsigned HOST_WIDE_INT
) 0xffff;
1476 if (!LUI_OPERAND (high
) && (value
& 0x18000) == 0x18000)
1478 /* The constant is too complex to load with a simple lui/ori pair
1479 so our goal is to clear as many trailing zeros as possible.
1480 In this case, we know bit 16 is set and that the low 16 bits
1481 form a negative number. If we subtract that number from VALUE,
1482 we will clear at least the lowest 17 bits, maybe more. */
1483 i
= mips_build_integer (codes
, CONST_HIGH_PART (value
));
1484 codes
[i
].code
= PLUS
;
1485 codes
[i
].value
= CONST_LOW_PART (value
);
1489 i
= mips_build_integer (codes
, high
);
1490 codes
[i
].code
= IOR
;
1491 codes
[i
].value
= value
& 0xffff;
1497 /* Fill CODES with a sequence of rtl operations to load VALUE.
1498 Return the number of operations needed. */
1501 mips_build_integer (struct mips_integer_op
*codes
,
1502 unsigned HOST_WIDE_INT value
)
1504 if (SMALL_OPERAND (value
)
1505 || SMALL_OPERAND_UNSIGNED (value
)
1506 || LUI_OPERAND (value
))
1508 /* The value can be loaded with a single instruction. */
1509 codes
[0].code
= UNKNOWN
;
1510 codes
[0].value
= value
;
1513 else if ((value
& 1) != 0 || LUI_OPERAND (CONST_HIGH_PART (value
)))
1515 /* Either the constant is a simple LUI/ORI combination or its
1516 lowest bit is set. We don't want to shift in this case. */
1517 return mips_build_lower (codes
, value
);
1519 else if ((value
& 0xffff) == 0)
1521 /* The constant will need at least three actions. The lowest
1522 16 bits are clear, so the final action will be a shift. */
1523 return mips_build_shift (codes
, value
);
1527 /* The final action could be a shift, add or inclusive OR.
1528 Rather than use a complex condition to select the best
1529 approach, try both mips_build_shift and mips_build_lower
1530 and pick the one that gives the shortest sequence.
1531 Note that this case is only used once per constant. */
1532 struct mips_integer_op alt_codes
[MIPS_MAX_INTEGER_OPS
];
1533 unsigned int cost
, alt_cost
;
1535 cost
= mips_build_shift (codes
, value
);
1536 alt_cost
= mips_build_lower (alt_codes
, value
);
1537 if (alt_cost
< cost
)
1539 memcpy (codes
, alt_codes
, alt_cost
* sizeof (codes
[0]));
1547 /* Move VALUE into register DEST. */
1550 mips_move_integer (rtx dest
, unsigned HOST_WIDE_INT value
)
1552 struct mips_integer_op codes
[MIPS_MAX_INTEGER_OPS
];
1553 enum machine_mode mode
;
1554 unsigned int i
, cost
;
1557 mode
= GET_MODE (dest
);
1558 cost
= mips_build_integer (codes
, value
);
1560 /* Apply each binary operation to X. Invariant: X is a legitimate
1561 source operand for a SET pattern. */
1562 x
= GEN_INT (codes
[0].value
);
1563 for (i
= 1; i
< cost
; i
++)
1566 emit_move_insn (dest
, x
), x
= dest
;
1568 x
= force_reg (mode
, x
);
1569 x
= gen_rtx_fmt_ee (codes
[i
].code
, mode
, x
, GEN_INT (codes
[i
].value
));
1572 emit_insn (gen_rtx_SET (VOIDmode
, dest
, x
));
1576 /* Subroutine of mips_legitimize_move. Move constant SRC into register
1577 DEST given that SRC satisfies immediate_operand but doesn't satisfy
1581 mips_legitimize_const_move (enum machine_mode mode
, rtx dest
, rtx src
)
1584 HOST_WIDE_INT offset
;
1585 enum mips_symbol_type symbol_type
;
1587 /* Split moves of big integers into smaller pieces. In mips16 code,
1588 it's better to force the constant into memory instead. */
1589 if (GET_CODE (src
) == CONST_INT
&& !TARGET_MIPS16
)
1591 mips_move_integer (dest
, INTVAL (src
));
1595 /* See if the symbol can be split. For mips16, this is often worse than
1596 forcing it in the constant pool since it needs the single-register form
1597 of addiu or daddiu. */
1599 && mips_symbolic_constant_p (src
, &symbol_type
)
1600 && mips_split_p
[symbol_type
])
1602 emit_move_insn (dest
, mips_split_symbol (dest
, src
));
1606 /* If we have (const (plus symbol offset)), load the symbol first
1607 and then add in the offset. This is usually better than forcing
1608 the constant into memory, at least in non-mips16 code. */
1609 mips_split_const (src
, &base
, &offset
);
1612 && (!no_new_pseudos
|| SMALL_OPERAND (offset
)))
1614 base
= mips_force_temporary (dest
, base
);
1615 emit_move_insn (dest
, mips_add_offset (0, base
, offset
));
1619 src
= force_const_mem (mode
, src
);
1621 /* When using explicit relocs, constant pool references are sometimes
1622 not legitimate addresses. */
1623 if (!memory_operand (src
, VOIDmode
))
1624 src
= replace_equiv_address (src
, mips_split_symbol (dest
, XEXP (src
, 0)));
1625 emit_move_insn (dest
, src
);
1629 /* If (set DEST SRC) is not a valid instruction, emit an equivalent
1630 sequence that is valid. */
1633 mips_legitimize_move (enum machine_mode mode
, rtx dest
, rtx src
)
1635 if (!register_operand (dest
, mode
) && !reg_or_0_operand (src
, mode
))
1637 emit_move_insn (dest
, force_reg (mode
, src
));
1641 /* Check for individual, fully-reloaded mflo and mfhi instructions. */
1642 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
1643 && REG_P (src
) && MD_REG_P (REGNO (src
))
1644 && REG_P (dest
) && GP_REG_P (REGNO (dest
)))
1646 int other_regno
= REGNO (src
) == HI_REGNUM
? LO_REGNUM
: HI_REGNUM
;
1647 if (GET_MODE_SIZE (mode
) <= 4)
1648 emit_insn (gen_mfhilo_si (gen_rtx_REG (SImode
, REGNO (dest
)),
1649 gen_rtx_REG (SImode
, REGNO (src
)),
1650 gen_rtx_REG (SImode
, other_regno
)));
1652 emit_insn (gen_mfhilo_di (gen_rtx_REG (DImode
, REGNO (dest
)),
1653 gen_rtx_REG (DImode
, REGNO (src
)),
1654 gen_rtx_REG (DImode
, other_regno
)));
1658 /* We need to deal with constants that would be legitimate
1659 immediate_operands but not legitimate move_operands. */
1660 if (CONSTANT_P (src
) && !move_operand (src
, mode
))
1662 mips_legitimize_const_move (mode
, dest
, src
);
1663 set_unique_reg_note (get_last_insn (), REG_EQUAL
, copy_rtx (src
));
1669 /* We need a lot of little routines to check constant values on the
1670 mips16. These are used to figure out how long the instruction will
1671 be. It would be much better to do this using constraints, but
1672 there aren't nearly enough letters available. */
1675 m16_check_op (rtx op
, int low
, int high
, int mask
)
1677 return (GET_CODE (op
) == CONST_INT
1678 && INTVAL (op
) >= low
1679 && INTVAL (op
) <= high
1680 && (INTVAL (op
) & mask
) == 0);
1684 m16_uimm3_b (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1686 return m16_check_op (op
, 0x1, 0x8, 0);
1690 m16_simm4_1 (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1692 return m16_check_op (op
, - 0x8, 0x7, 0);
1696 m16_nsimm4_1 (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1698 return m16_check_op (op
, - 0x7, 0x8, 0);
1702 m16_simm5_1 (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1704 return m16_check_op (op
, - 0x10, 0xf, 0);
1708 m16_nsimm5_1 (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1710 return m16_check_op (op
, - 0xf, 0x10, 0);
1714 m16_uimm5_4 (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1716 return m16_check_op (op
, (- 0x10) << 2, 0xf << 2, 3);
1720 m16_nuimm5_4 (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1722 return m16_check_op (op
, (- 0xf) << 2, 0x10 << 2, 3);
1726 m16_simm8_1 (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1728 return m16_check_op (op
, - 0x80, 0x7f, 0);
1732 m16_nsimm8_1 (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1734 return m16_check_op (op
, - 0x7f, 0x80, 0);
1738 m16_uimm8_1 (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1740 return m16_check_op (op
, 0x0, 0xff, 0);
1744 m16_nuimm8_1 (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1746 return m16_check_op (op
, - 0xff, 0x0, 0);
1750 m16_uimm8_m1_1 (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1752 return m16_check_op (op
, - 0x1, 0xfe, 0);
1756 m16_uimm8_4 (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1758 return m16_check_op (op
, 0x0, 0xff << 2, 3);
1762 m16_nuimm8_4 (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1764 return m16_check_op (op
, (- 0xff) << 2, 0x0, 3);
1768 m16_simm8_8 (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1770 return m16_check_op (op
, (- 0x80) << 3, 0x7f << 3, 7);
1774 m16_nsimm8_8 (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1776 return m16_check_op (op
, (- 0x7f) << 3, 0x80 << 3, 7);
1780 mips_rtx_costs (rtx x
, int code
, int outer_code
, int *total
)
1782 enum machine_mode mode
= GET_MODE (x
);
1789 /* Always return 0, since we don't have different sized
1790 instructions, hence different costs according to Richard
1796 /* A number between 1 and 8 inclusive is efficient for a shift.
1797 Otherwise, we will need an extended instruction. */
1798 if ((outer_code
) == ASHIFT
|| (outer_code
) == ASHIFTRT
1799 || (outer_code
) == LSHIFTRT
)
1801 if (INTVAL (x
) >= 1 && INTVAL (x
) <= 8)
1804 *total
= COSTS_N_INSNS (1);
1808 /* We can use cmpi for an xor with an unsigned 16 bit value. */
1809 if ((outer_code
) == XOR
1810 && INTVAL (x
) >= 0 && INTVAL (x
) < 0x10000)
1816 /* We may be able to use slt or sltu for a comparison with a
1817 signed 16 bit value. (The boundary conditions aren't quite
1818 right, but this is just a heuristic anyhow.) */
1819 if (((outer_code
) == LT
|| (outer_code
) == LE
1820 || (outer_code
) == GE
|| (outer_code
) == GT
1821 || (outer_code
) == LTU
|| (outer_code
) == LEU
1822 || (outer_code
) == GEU
|| (outer_code
) == GTU
)
1823 && INTVAL (x
) >= -0x8000 && INTVAL (x
) < 0x8000)
1829 /* Equality comparisons with 0 are cheap. */
1830 if (((outer_code
) == EQ
|| (outer_code
) == NE
)
1837 /* Constants in the range 0...255 can be loaded with an unextended
1838 instruction. They are therefore as cheap as a register move.
1840 Given the choice between "li R1,0...255" and "move R1,R2"
1841 (where R2 is a known constant), it is usually better to use "li",
1842 since we do not want to unnessarily extend the lifetime of R2. */
1843 if (outer_code
== SET
1845 && INTVAL (x
) < 256)
1851 /* Otherwise fall through to the handling below. */
1857 if (LEGITIMATE_CONSTANT_P (x
))
1859 *total
= COSTS_N_INSNS (1);
1864 /* The value will need to be fetched from the constant pool. */
1865 *total
= CONSTANT_POOL_COST
;
1871 /* If the address is legitimate, return the number of
1872 instructions it needs, otherwise use the default handling. */
1873 int n
= mips_address_insns (XEXP (x
, 0), GET_MODE (x
));
1876 *total
= COSTS_N_INSNS (1 + n
);
1883 *total
= COSTS_N_INSNS (6);
1887 *total
= COSTS_N_INSNS ((mode
== DImode
&& !TARGET_64BIT
) ? 2 : 1);
1893 if (mode
== DImode
&& !TARGET_64BIT
)
1895 *total
= COSTS_N_INSNS (2);
1903 if (mode
== DImode
&& !TARGET_64BIT
)
1905 *total
= COSTS_N_INSNS ((GET_CODE (XEXP (x
, 1)) == CONST_INT
)
1912 if (mode
== SFmode
|| mode
== DFmode
)
1913 *total
= COSTS_N_INSNS (1);
1915 *total
= COSTS_N_INSNS (4);
1919 *total
= COSTS_N_INSNS (1);
1924 if (mode
== SFmode
|| mode
== DFmode
)
1926 if (TUNE_MIPS3000
|| TUNE_MIPS3900
)
1927 *total
= COSTS_N_INSNS (2);
1928 else if (TUNE_MIPS6000
)
1929 *total
= COSTS_N_INSNS (3);
1931 *total
= COSTS_N_INSNS (4);
1933 *total
= COSTS_N_INSNS (6);
1936 if (mode
== DImode
&& !TARGET_64BIT
)
1938 *total
= COSTS_N_INSNS (4);
1944 if (mode
== DImode
&& !TARGET_64BIT
)
1958 *total
= COSTS_N_INSNS (4);
1959 else if (TUNE_MIPS6000
1962 *total
= COSTS_N_INSNS (5);
1964 *total
= COSTS_N_INSNS (7);
1971 *total
= COSTS_N_INSNS (4);
1972 else if (TUNE_MIPS3000
1975 *total
= COSTS_N_INSNS (5);
1976 else if (TUNE_MIPS6000
1979 *total
= COSTS_N_INSNS (6);
1981 *total
= COSTS_N_INSNS (8);
1986 *total
= COSTS_N_INSNS (12);
1987 else if (TUNE_MIPS3900
)
1988 *total
= COSTS_N_INSNS (2);
1989 else if (TUNE_MIPS4130
)
1990 *total
= COSTS_N_INSNS (mode
== DImode
? 6 : 4);
1991 else if (TUNE_MIPS5400
|| TUNE_SB1
)
1992 *total
= COSTS_N_INSNS (mode
== DImode
? 4 : 3);
1993 else if (TUNE_MIPS5500
|| TUNE_MIPS7000
)
1994 *total
= COSTS_N_INSNS (mode
== DImode
? 9 : 5);
1995 else if (TUNE_MIPS9000
)
1996 *total
= COSTS_N_INSNS (mode
== DImode
? 8 : 3);
1997 else if (TUNE_MIPS6000
)
1998 *total
= COSTS_N_INSNS (17);
1999 else if (TUNE_MIPS5000
)
2000 *total
= COSTS_N_INSNS (5);
2002 *total
= COSTS_N_INSNS (10);
2011 *total
= COSTS_N_INSNS (12);
2012 else if (TUNE_MIPS6000
)
2013 *total
= COSTS_N_INSNS (15);
2015 *total
= COSTS_N_INSNS (24);
2016 else if (TUNE_MIPS5400
|| TUNE_MIPS5500
)
2017 *total
= COSTS_N_INSNS (30);
2019 *total
= COSTS_N_INSNS (23);
2027 *total
= COSTS_N_INSNS (19);
2028 else if (TUNE_MIPS5400
|| TUNE_MIPS5500
)
2029 *total
= COSTS_N_INSNS (59);
2030 else if (TUNE_MIPS6000
)
2031 *total
= COSTS_N_INSNS (16);
2033 *total
= COSTS_N_INSNS (32);
2035 *total
= COSTS_N_INSNS (36);
2044 *total
= COSTS_N_INSNS (35);
2045 else if (TUNE_MIPS6000
)
2046 *total
= COSTS_N_INSNS (38);
2047 else if (TUNE_MIPS5000
)
2048 *total
= COSTS_N_INSNS (36);
2050 *total
= COSTS_N_INSNS ((mode
== SImode
) ? 36 : 68);
2051 else if (TUNE_MIPS5400
|| TUNE_MIPS5500
)
2052 *total
= COSTS_N_INSNS ((mode
== SImode
) ? 42 : 74);
2054 *total
= COSTS_N_INSNS (69);
2058 /* A sign extend from SImode to DImode in 64 bit mode is often
2059 zero instructions, because the result can often be used
2060 directly by another instruction; we'll call it one. */
2061 if (TARGET_64BIT
&& mode
== DImode
2062 && GET_MODE (XEXP (x
, 0)) == SImode
)
2063 *total
= COSTS_N_INSNS (1);
2065 *total
= COSTS_N_INSNS (2);
2069 if (TARGET_64BIT
&& mode
== DImode
2070 && GET_MODE (XEXP (x
, 0)) == SImode
)
2071 *total
= COSTS_N_INSNS (2);
2073 *total
= COSTS_N_INSNS (1);
2081 /* Provide the costs of an addressing mode that contains ADDR.
2082 If ADDR is not a valid address, its cost is irrelevant. */
2085 mips_address_cost (rtx addr
)
2087 return mips_address_insns (addr
, SImode
);
2090 /* Return one word of double-word value OP, taking into account the fixed
2091 endianness of certain registers. HIGH_P is true to select the high part,
2092 false to select the low part. */
2095 mips_subword (rtx op
, int high_p
)
2098 enum machine_mode mode
;
2100 mode
= GET_MODE (op
);
2101 if (mode
== VOIDmode
)
2104 if (TARGET_BIG_ENDIAN
? !high_p
: high_p
)
2105 byte
= UNITS_PER_WORD
;
2109 if (GET_CODE (op
) == REG
)
2111 if (FP_REG_P (REGNO (op
)))
2112 return gen_rtx_REG (word_mode
, high_p
? REGNO (op
) + 1 : REGNO (op
));
2113 if (REGNO (op
) == HI_REGNUM
)
2114 return gen_rtx_REG (word_mode
, high_p
? HI_REGNUM
: LO_REGNUM
);
2117 if (GET_CODE (op
) == MEM
)
2118 return mips_rewrite_small_data (adjust_address (op
, word_mode
, byte
));
2120 return simplify_gen_subreg (word_mode
, op
, mode
, byte
);
2124 /* Return true if a 64-bit move from SRC to DEST should be split into two. */
2127 mips_split_64bit_move_p (rtx dest
, rtx src
)
2132 /* FP->FP moves can be done in a single instruction. */
2133 if (FP_REG_RTX_P (src
) && FP_REG_RTX_P (dest
))
2136 /* Check for floating-point loads and stores. They can be done using
2137 ldc1 and sdc1 on MIPS II and above. */
2140 if (FP_REG_RTX_P (dest
) && GET_CODE (src
) == MEM
)
2142 if (FP_REG_RTX_P (src
) && GET_CODE (dest
) == MEM
)
2149 /* Split a 64-bit move from SRC to DEST assuming that
2150 mips_split_64bit_move_p holds.
2152 Moves into and out of FPRs cause some difficulty here. Such moves
2153 will always be DFmode, since paired FPRs are not allowed to store
2154 DImode values. The most natural representation would be two separate
2155 32-bit moves, such as:
2157 (set (reg:SI $f0) (mem:SI ...))
2158 (set (reg:SI $f1) (mem:SI ...))
2160 However, the second insn is invalid because odd-numbered FPRs are
2161 not allowed to store independent values. Use the patterns load_df_low,
2162 load_df_high and store_df_high instead. */
2165 mips_split_64bit_move (rtx dest
, rtx src
)
2167 if (FP_REG_RTX_P (dest
))
2169 /* Loading an FPR from memory or from GPRs. */
2170 emit_insn (gen_load_df_low (copy_rtx (dest
), mips_subword (src
, 0)));
2171 emit_insn (gen_load_df_high (dest
, mips_subword (src
, 1),
2174 else if (FP_REG_RTX_P (src
))
2176 /* Storing an FPR into memory or GPRs. */
2177 emit_move_insn (mips_subword (dest
, 0), mips_subword (src
, 0));
2178 emit_insn (gen_store_df_high (mips_subword (dest
, 1), src
));
2182 /* The operation can be split into two normal moves. Decide in
2183 which order to do them. */
2186 low_dest
= mips_subword (dest
, 0);
2187 if (GET_CODE (low_dest
) == REG
2188 && reg_overlap_mentioned_p (low_dest
, src
))
2190 emit_move_insn (mips_subword (dest
, 1), mips_subword (src
, 1));
2191 emit_move_insn (low_dest
, mips_subword (src
, 0));
2195 emit_move_insn (low_dest
, mips_subword (src
, 0));
2196 emit_move_insn (mips_subword (dest
, 1), mips_subword (src
, 1));
2201 /* Return the appropriate instructions to move SRC into DEST. Assume
2202 that SRC is operand 1 and DEST is operand 0. */
2205 mips_output_move (rtx dest
, rtx src
)
2207 enum rtx_code dest_code
, src_code
;
2210 dest_code
= GET_CODE (dest
);
2211 src_code
= GET_CODE (src
);
2212 dbl_p
= (GET_MODE_SIZE (GET_MODE (dest
)) == 8);
2214 if (dbl_p
&& mips_split_64bit_move_p (dest
, src
))
2217 if ((src_code
== REG
&& GP_REG_P (REGNO (src
)))
2218 || (!TARGET_MIPS16
&& src
== CONST0_RTX (GET_MODE (dest
))))
2220 if (dest_code
== REG
)
2222 if (GP_REG_P (REGNO (dest
)))
2223 return "move\t%0,%z1";
2225 if (MD_REG_P (REGNO (dest
)))
2228 if (FP_REG_P (REGNO (dest
)))
2229 return (dbl_p
? "dmtc1\t%z1,%0" : "mtc1\t%z1,%0");
2231 if (ALL_COP_REG_P (REGNO (dest
)))
2233 static char retval
[] = "dmtc_\t%z1,%0";
2235 retval
[4] = COPNUM_AS_CHAR_FROM_REGNUM (REGNO (dest
));
2236 return (dbl_p
? retval
: retval
+ 1);
2239 if (dest_code
== MEM
)
2240 return (dbl_p
? "sd\t%z1,%0" : "sw\t%z1,%0");
2242 if (dest_code
== REG
&& GP_REG_P (REGNO (dest
)))
2244 if (src_code
== REG
)
2246 if (ST_REG_P (REGNO (src
)) && ISA_HAS_8CC
)
2247 return "lui\t%0,0x3f80\n\tmovf\t%0,%.,%1";
2249 if (FP_REG_P (REGNO (src
)))
2250 return (dbl_p
? "dmfc1\t%0,%1" : "mfc1\t%0,%1");
2252 if (ALL_COP_REG_P (REGNO (src
)))
2254 static char retval
[] = "dmfc_\t%0,%1";
2256 retval
[4] = COPNUM_AS_CHAR_FROM_REGNUM (REGNO (src
));
2257 return (dbl_p
? retval
: retval
+ 1);
2261 if (src_code
== MEM
)
2262 return (dbl_p
? "ld\t%0,%1" : "lw\t%0,%1");
2264 if (src_code
== CONST_INT
)
2266 /* Don't use the X format, because that will give out of
2267 range numbers for 64 bit hosts and 32 bit targets. */
2269 return "li\t%0,%1\t\t\t# %X1";
2271 if (INTVAL (src
) >= 0 && INTVAL (src
) <= 0xffff)
2274 if (INTVAL (src
) < 0 && INTVAL (src
) >= -0xffff)
2278 if (src_code
== HIGH
)
2279 return "lui\t%0,%h1";
2281 if (CONST_GP_P (src
))
2282 return "move\t%0,%1";
2284 if (symbolic_operand (src
, VOIDmode
))
2285 return (dbl_p
? "dla\t%0,%1" : "la\t%0,%1");
2287 if (src_code
== REG
&& FP_REG_P (REGNO (src
)))
2289 if (dest_code
== REG
&& FP_REG_P (REGNO (dest
)))
2291 if (GET_MODE (dest
) == V2SFmode
)
2292 return "mov.ps\t%0,%1";
2294 return (dbl_p
? "mov.d\t%0,%1" : "mov.s\t%0,%1");
2297 if (dest_code
== MEM
)
2298 return (dbl_p
? "sdc1\t%1,%0" : "swc1\t%1,%0");
2300 if (dest_code
== REG
&& FP_REG_P (REGNO (dest
)))
2302 if (src_code
== MEM
)
2303 return (dbl_p
? "ldc1\t%0,%1" : "lwc1\t%0,%1");
2305 if (dest_code
== REG
&& ALL_COP_REG_P (REGNO (dest
)) && src_code
== MEM
)
2307 static char retval
[] = "l_c_\t%0,%1";
2309 retval
[1] = (dbl_p
? 'd' : 'w');
2310 retval
[3] = COPNUM_AS_CHAR_FROM_REGNUM (REGNO (dest
));
2313 if (dest_code
== MEM
&& src_code
== REG
&& ALL_COP_REG_P (REGNO (src
)))
2315 static char retval
[] = "s_c_\t%1,%0";
2317 retval
[1] = (dbl_p
? 'd' : 'w');
2318 retval
[3] = COPNUM_AS_CHAR_FROM_REGNUM (REGNO (src
));
2324 /* Restore $gp from its save slot. Valid only when using o32 or
2328 mips_restore_gp (void)
2332 if (!TARGET_ABICALLS
|| !TARGET_OLDABI
)
2335 address
= mips_add_offset (pic_offset_table_rtx
,
2336 frame_pointer_needed
2337 ? hard_frame_pointer_rtx
2338 : stack_pointer_rtx
,
2339 current_function_outgoing_args_size
);
2340 slot
= gen_rtx_MEM (Pmode
, address
);
2342 emit_move_insn (pic_offset_table_rtx
, slot
);
2343 if (!TARGET_EXPLICIT_RELOCS
)
2344 emit_insn (gen_blockage ());
2347 /* Emit an instruction of the form (set TARGET (CODE OP0 OP1)). */
2350 mips_emit_binary (enum rtx_code code
, rtx target
, rtx op0
, rtx op1
)
2352 emit_insn (gen_rtx_SET (VOIDmode
, target
,
2353 gen_rtx_fmt_ee (code
, GET_MODE (target
), op0
, op1
)));
2356 /* Return true if CMP1 is a suitable second operand for relational
2357 operator CODE. See also the *sCC patterns in mips.md. */
2360 mips_relational_operand_ok_p (enum rtx_code code
, rtx cmp1
)
2366 return reg_or_0_operand (cmp1
, VOIDmode
);
2370 return !TARGET_MIPS16
&& cmp1
== const1_rtx
;
2374 return arith_operand (cmp1
, VOIDmode
);
2377 return sle_operand (cmp1
, VOIDmode
);
2380 return sleu_operand (cmp1
, VOIDmode
);
2387 /* Compare CMP0 and CMP1 using relational operator CODE and store the
2388 result in TARGET. CMP0 and TARGET are register_operands that have
2389 the same integer mode. If INVERT_PTR is nonnull, it's OK to set
2390 TARGET to the inverse of the result and flip *INVERT_PTR instead. */
2393 mips_emit_int_relational (enum rtx_code code
, bool *invert_ptr
,
2394 rtx target
, rtx cmp0
, rtx cmp1
)
2396 /* First see if there is a MIPS instruction that can do this operation
2397 with CMP1 in its current form. If not, try doing the same for the
2398 inverse operation. If that also fails, force CMP1 into a register
2400 if (mips_relational_operand_ok_p (code
, cmp1
))
2401 mips_emit_binary (code
, target
, cmp0
, cmp1
);
2404 enum rtx_code inv_code
= reverse_condition (code
);
2405 if (!mips_relational_operand_ok_p (inv_code
, cmp1
))
2407 cmp1
= force_reg (GET_MODE (cmp0
), cmp1
);
2408 mips_emit_int_relational (code
, invert_ptr
, target
, cmp0
, cmp1
);
2410 else if (invert_ptr
== 0)
2412 rtx inv_target
= gen_reg_rtx (GET_MODE (target
));
2413 mips_emit_binary (inv_code
, inv_target
, cmp0
, cmp1
);
2414 mips_emit_binary (XOR
, target
, inv_target
, const1_rtx
);
2418 *invert_ptr
= !*invert_ptr
;
2419 mips_emit_binary (inv_code
, target
, cmp0
, cmp1
);
2424 /* Return a register that is zero iff CMP0 and CMP1 are equal.
2425 The register will have the same mode as CMP0. */
2428 mips_zero_if_equal (rtx cmp0
, rtx cmp1
)
2430 if (cmp1
== const0_rtx
)
2433 if (uns_arith_operand (cmp1
, VOIDmode
))
2434 return expand_binop (GET_MODE (cmp0
), xor_optab
,
2435 cmp0
, cmp1
, 0, 0, OPTAB_DIRECT
);
2437 return expand_binop (GET_MODE (cmp0
), sub_optab
,
2438 cmp0
, cmp1
, 0, 0, OPTAB_DIRECT
);
2441 /* Convert a comparison into something that can be used in a branch or
2442 conditional move. cmp_operands[0] and cmp_operands[1] are the values
2443 being compared and *CODE is the code used to compare them.
2445 Update *CODE, *OP0 and *OP1 so that they describe the final comparison.
2446 If NEED_EQ_NE_P, then only EQ/NE comparisons against zero are possible,
2447 otherwise any standard branch condition can be used. The standard branch
2450 - EQ/NE between two registers.
2451 - any comparison between a register and zero. */
2454 mips_emit_compare (enum rtx_code
*code
, rtx
*op0
, rtx
*op1
, bool need_eq_ne_p
)
2456 if (GET_MODE_CLASS (GET_MODE (cmp_operands
[0])) == MODE_INT
)
2458 if (!need_eq_ne_p
&& cmp_operands
[1] == const0_rtx
)
2460 *op0
= cmp_operands
[0];
2461 *op1
= cmp_operands
[1];
2463 else if (*code
== EQ
|| *code
== NE
)
2467 *op0
= mips_zero_if_equal (cmp_operands
[0], cmp_operands
[1]);
2472 *op0
= cmp_operands
[0];
2473 *op1
= force_reg (GET_MODE (*op0
), cmp_operands
[1]);
2478 /* The comparison needs a separate scc instruction. Store the
2479 result of the scc in *OP0 and compare it against zero. */
2480 bool invert
= false;
2481 *op0
= gen_reg_rtx (GET_MODE (cmp_operands
[0]));
2483 mips_emit_int_relational (*code
, &invert
, *op0
,
2484 cmp_operands
[0], cmp_operands
[1]);
2485 *code
= (invert
? EQ
: NE
);
2490 enum rtx_code cmp_code
;
2492 /* Floating-point tests use a separate c.cond.fmt comparison to
2493 set a condition code register. The branch or conditional move
2494 will then compare that register against zero.
2496 Set CMP_CODE to the code of the comparison instruction and
2497 *CODE to the code that the branch or move should use. */
2505 cmp_code
= reverse_condition_maybe_unordered (*code
);
2515 ? gen_reg_rtx (CCmode
)
2516 : gen_rtx_REG (CCmode
, FPSW_REGNUM
));
2518 mips_emit_binary (cmp_code
, *op0
, cmp_operands
[0], cmp_operands
[1]);
2522 /* Try comparing cmp_operands[0] and cmp_operands[1] using rtl code CODE.
2523 Store the result in TARGET and return true if successful.
2525 On 64-bit targets, TARGET may be wider than cmp_operands[0]. */
2528 mips_emit_scc (enum rtx_code code
, rtx target
)
2530 if (GET_MODE_CLASS (GET_MODE (cmp_operands
[0])) != MODE_INT
)
2533 target
= gen_lowpart (GET_MODE (cmp_operands
[0]), target
);
2534 if (code
== EQ
|| code
== NE
)
2536 rtx zie
= mips_zero_if_equal (cmp_operands
[0], cmp_operands
[1]);
2537 mips_emit_binary (code
, target
, zie
, const0_rtx
);
2540 mips_emit_int_relational (code
, 0, target
,
2541 cmp_operands
[0], cmp_operands
[1]);
2545 /* Emit the common code for doing conditional branches.
2546 operand[0] is the label to jump to.
2547 The comparison operands are saved away by cmp{si,di,sf,df}. */
2550 gen_conditional_branch (rtx
*operands
, enum rtx_code code
)
2552 rtx op0
, op1
, target
;
2554 mips_emit_compare (&code
, &op0
, &op1
, TARGET_MIPS16
);
2555 target
= gen_rtx_IF_THEN_ELSE (VOIDmode
,
2556 gen_rtx_fmt_ee (code
, GET_MODE (op0
),
2558 gen_rtx_LABEL_REF (VOIDmode
, operands
[0]),
2560 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
, target
));
2563 /* Emit the common code for conditional moves. OPERANDS is the array
2564 of operands passed to the conditional move define_expand. */
2567 gen_conditional_move (rtx
*operands
)
2572 code
= GET_CODE (operands
[1]);
2573 mips_emit_compare (&code
, &op0
, &op1
, true);
2574 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0],
2575 gen_rtx_IF_THEN_ELSE (GET_MODE (operands
[0]),
2576 gen_rtx_fmt_ee (code
,
2579 operands
[2], operands
[3])));
2582 /* Emit a conditional trap. OPERANDS is the array of operands passed to
2583 the conditional_trap expander. */
2586 mips_gen_conditional_trap (rtx
*operands
)
2589 enum rtx_code cmp_code
= GET_CODE (operands
[0]);
2590 enum machine_mode mode
= GET_MODE (cmp_operands
[0]);
2592 /* MIPS conditional trap machine instructions don't have GT or LE
2593 flavors, so we must invert the comparison and convert to LT and
2594 GE, respectively. */
2597 case GT
: cmp_code
= LT
; break;
2598 case LE
: cmp_code
= GE
; break;
2599 case GTU
: cmp_code
= LTU
; break;
2600 case LEU
: cmp_code
= GEU
; break;
2603 if (cmp_code
== GET_CODE (operands
[0]))
2605 op0
= cmp_operands
[0];
2606 op1
= cmp_operands
[1];
2610 op0
= cmp_operands
[1];
2611 op1
= cmp_operands
[0];
2613 op0
= force_reg (mode
, op0
);
2614 if (!arith_operand (op1
, mode
))
2615 op1
= force_reg (mode
, op1
);
2617 emit_insn (gen_rtx_TRAP_IF (VOIDmode
,
2618 gen_rtx_fmt_ee (cmp_code
, mode
, op0
, op1
),
2622 /* Load function address ADDR into register DEST. SIBCALL_P is true
2623 if the address is needed for a sibling call. */
2626 mips_load_call_address (rtx dest
, rtx addr
, int sibcall_p
)
2628 /* If we're generating PIC, and this call is to a global function,
2629 try to allow its address to be resolved lazily. This isn't
2630 possible for NewABI sibcalls since the value of $gp on entry
2631 to the stub would be our caller's gp, not ours. */
2632 if (TARGET_EXPLICIT_RELOCS
2633 && !(sibcall_p
&& TARGET_NEWABI
)
2634 && global_got_operand (addr
, VOIDmode
))
2636 rtx high
, lo_sum_symbol
;
2638 high
= mips_unspec_offset_high (dest
, pic_offset_table_rtx
,
2639 addr
, SYMBOL_GOTOFF_CALL
);
2640 lo_sum_symbol
= mips_unspec_address (addr
, SYMBOL_GOTOFF_CALL
);
2641 if (Pmode
== SImode
)
2642 emit_insn (gen_load_callsi (dest
, high
, lo_sum_symbol
));
2644 emit_insn (gen_load_calldi (dest
, high
, lo_sum_symbol
));
2647 emit_move_insn (dest
, addr
);
2651 /* Expand a call or call_value instruction. RESULT is where the
2652 result will go (null for calls), ADDR is the address of the
2653 function, ARGS_SIZE is the size of the arguments and AUX is
2654 the value passed to us by mips_function_arg. SIBCALL_P is true
2655 if we are expanding a sibling call, false if we're expanding
2659 mips_expand_call (rtx result
, rtx addr
, rtx args_size
, rtx aux
, int sibcall_p
)
2661 rtx orig_addr
, pattern
, insn
;
2664 if (!call_insn_operand (addr
, VOIDmode
))
2666 addr
= gen_reg_rtx (Pmode
);
2667 mips_load_call_address (addr
, orig_addr
, sibcall_p
);
2671 && mips16_hard_float
2672 && build_mips16_call_stub (result
, addr
, args_size
,
2673 aux
== 0 ? 0 : (int) GET_MODE (aux
)))
2677 pattern
= (sibcall_p
2678 ? gen_sibcall_internal (addr
, args_size
)
2679 : gen_call_internal (addr
, args_size
));
2680 else if (GET_CODE (result
) == PARALLEL
&& XVECLEN (result
, 0) == 2)
2684 reg1
= XEXP (XVECEXP (result
, 0, 0), 0);
2685 reg2
= XEXP (XVECEXP (result
, 0, 1), 0);
2688 ? gen_sibcall_value_multiple_internal (reg1
, addr
, args_size
, reg2
)
2689 : gen_call_value_multiple_internal (reg1
, addr
, args_size
, reg2
));
2692 pattern
= (sibcall_p
2693 ? gen_sibcall_value_internal (result
, addr
, args_size
)
2694 : gen_call_value_internal (result
, addr
, args_size
));
2696 insn
= emit_call_insn (pattern
);
2698 /* Lazy-binding stubs require $gp to be valid on entry. */
2699 if (global_got_operand (orig_addr
, VOIDmode
))
2700 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), pic_offset_table_rtx
);
2704 /* We can handle any sibcall when TARGET_SIBCALLS is true. */
2707 mips_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED
,
2708 tree exp ATTRIBUTE_UNUSED
)
2710 return TARGET_SIBCALLS
;
2713 /* Emit code to move general operand SRC into condition-code
2714 register DEST. SCRATCH is a scratch TFmode float register.
2721 where FP1 and FP2 are single-precision float registers
2722 taken from SCRATCH. */
2725 mips_emit_fcc_reload (rtx dest
, rtx src
, rtx scratch
)
2729 /* Change the source to SFmode. */
2730 if (GET_CODE (src
) == MEM
)
2731 src
= adjust_address (src
, SFmode
, 0);
2732 else if (GET_CODE (src
) == REG
|| GET_CODE (src
) == SUBREG
)
2733 src
= gen_rtx_REG (SFmode
, true_regnum (src
));
2735 fp1
= gen_rtx_REG (SFmode
, REGNO (scratch
));
2736 fp2
= gen_rtx_REG (SFmode
, REGNO (scratch
) + FP_INC
);
2738 emit_move_insn (copy_rtx (fp1
), src
);
2739 emit_move_insn (copy_rtx (fp2
), CONST0_RTX (SFmode
));
2740 emit_insn (gen_slt_sf (dest
, fp2
, fp1
));
2743 /* Emit code to change the current function's return address to
2744 ADDRESS. SCRATCH is available as a scratch register, if needed.
2745 ADDRESS and SCRATCH are both word-mode GPRs. */
2748 mips_set_return_address (rtx address
, rtx scratch
)
2752 compute_frame_size (get_frame_size ());
2753 if (((cfun
->machine
->frame
.mask
>> 31) & 1) == 0)
2755 slot_address
= mips_add_offset (scratch
, stack_pointer_rtx
,
2756 cfun
->machine
->frame
.gp_sp_offset
);
2758 emit_move_insn (gen_rtx_MEM (GET_MODE (address
), slot_address
), address
);
2761 /* Emit straight-line code to move LENGTH bytes from SRC to DEST.
2762 Assume that the areas do not overlap. */
2765 mips_block_move_straight (rtx dest
, rtx src
, HOST_WIDE_INT length
)
2767 HOST_WIDE_INT offset
, delta
;
2768 unsigned HOST_WIDE_INT bits
;
2770 enum machine_mode mode
;
2773 /* Work out how many bits to move at a time. If both operands have
2774 half-word alignment, it is usually better to move in half words.
2775 For instance, lh/lh/sh/sh is usually better than lwl/lwr/swl/swr
2776 and lw/lw/sw/sw is usually better than ldl/ldr/sdl/sdr.
2777 Otherwise move word-sized chunks. */
2778 if (MEM_ALIGN (src
) == BITS_PER_WORD
/ 2
2779 && MEM_ALIGN (dest
) == BITS_PER_WORD
/ 2)
2780 bits
= BITS_PER_WORD
/ 2;
2782 bits
= BITS_PER_WORD
;
2784 mode
= mode_for_size (bits
, MODE_INT
, 0);
2785 delta
= bits
/ BITS_PER_UNIT
;
2787 /* Allocate a buffer for the temporary registers. */
2788 regs
= alloca (sizeof (rtx
) * length
/ delta
);
2790 /* Load as many BITS-sized chunks as possible. Use a normal load if
2791 the source has enough alignment, otherwise use left/right pairs. */
2792 for (offset
= 0, i
= 0; offset
+ delta
<= length
; offset
+= delta
, i
++)
2794 regs
[i
] = gen_reg_rtx (mode
);
2795 if (MEM_ALIGN (src
) >= bits
)
2796 emit_move_insn (regs
[i
], adjust_address (src
, mode
, offset
));
2799 rtx part
= adjust_address (src
, BLKmode
, offset
);
2800 if (!mips_expand_unaligned_load (regs
[i
], part
, bits
, 0))
2805 /* Copy the chunks to the destination. */
2806 for (offset
= 0, i
= 0; offset
+ delta
<= length
; offset
+= delta
, i
++)
2807 if (MEM_ALIGN (dest
) >= bits
)
2808 emit_move_insn (adjust_address (dest
, mode
, offset
), regs
[i
]);
2811 rtx part
= adjust_address (dest
, BLKmode
, offset
);
2812 if (!mips_expand_unaligned_store (part
, regs
[i
], bits
, 0))
2816 /* Mop up any left-over bytes. */
2817 if (offset
< length
)
2819 src
= adjust_address (src
, BLKmode
, offset
);
2820 dest
= adjust_address (dest
, BLKmode
, offset
);
2821 move_by_pieces (dest
, src
, length
- offset
,
2822 MIN (MEM_ALIGN (src
), MEM_ALIGN (dest
)), 0);
2826 #define MAX_MOVE_REGS 4
2827 #define MAX_MOVE_BYTES (MAX_MOVE_REGS * UNITS_PER_WORD)
2830 /* Helper function for doing a loop-based block operation on memory
2831 reference MEM. Each iteration of the loop will operate on LENGTH
2834 Create a new base register for use within the loop and point it to
2835 the start of MEM. Create a new memory reference that uses this
2836 register. Store them in *LOOP_REG and *LOOP_MEM respectively. */
2839 mips_adjust_block_mem (rtx mem
, HOST_WIDE_INT length
,
2840 rtx
*loop_reg
, rtx
*loop_mem
)
2842 *loop_reg
= copy_addr_to_reg (XEXP (mem
, 0));
2844 /* Although the new mem does not refer to a known location,
2845 it does keep up to LENGTH bytes of alignment. */
2846 *loop_mem
= change_address (mem
, BLKmode
, *loop_reg
);
2847 set_mem_align (*loop_mem
, MIN (MEM_ALIGN (mem
), length
* BITS_PER_UNIT
));
2851 /* Move LENGTH bytes from SRC to DEST using a loop that moves MAX_MOVE_BYTES
2852 per iteration. LENGTH must be at least MAX_MOVE_BYTES. Assume that the
2853 memory regions do not overlap. */
2856 mips_block_move_loop (rtx dest
, rtx src
, HOST_WIDE_INT length
)
2858 rtx label
, src_reg
, dest_reg
, final_src
;
2859 HOST_WIDE_INT leftover
;
2861 leftover
= length
% MAX_MOVE_BYTES
;
2864 /* Create registers and memory references for use within the loop. */
2865 mips_adjust_block_mem (src
, MAX_MOVE_BYTES
, &src_reg
, &src
);
2866 mips_adjust_block_mem (dest
, MAX_MOVE_BYTES
, &dest_reg
, &dest
);
2868 /* Calculate the value that SRC_REG should have after the last iteration
2870 final_src
= expand_simple_binop (Pmode
, PLUS
, src_reg
, GEN_INT (length
),
2873 /* Emit the start of the loop. */
2874 label
= gen_label_rtx ();
2877 /* Emit the loop body. */
2878 mips_block_move_straight (dest
, src
, MAX_MOVE_BYTES
);
2880 /* Move on to the next block. */
2881 emit_move_insn (src_reg
, plus_constant (src_reg
, MAX_MOVE_BYTES
));
2882 emit_move_insn (dest_reg
, plus_constant (dest_reg
, MAX_MOVE_BYTES
));
2884 /* Emit the loop condition. */
2885 if (Pmode
== DImode
)
2886 emit_insn (gen_cmpdi (src_reg
, final_src
));
2888 emit_insn (gen_cmpsi (src_reg
, final_src
));
2889 emit_jump_insn (gen_bne (label
));
2891 /* Mop up any left-over bytes. */
2893 mips_block_move_straight (dest
, src
, leftover
);
2896 /* Expand a movmemsi instruction. */
2899 mips_expand_block_move (rtx dest
, rtx src
, rtx length
)
2901 if (GET_CODE (length
) == CONST_INT
)
2903 if (INTVAL (length
) <= 2 * MAX_MOVE_BYTES
)
2905 mips_block_move_straight (dest
, src
, INTVAL (length
));
2910 mips_block_move_loop (dest
, src
, INTVAL (length
));
2917 /* Argument support functions. */
2919 /* Initialize CUMULATIVE_ARGS for a function. */
2922 init_cumulative_args (CUMULATIVE_ARGS
*cum
, tree fntype
,
2923 rtx libname ATTRIBUTE_UNUSED
)
2925 static CUMULATIVE_ARGS zero_cum
;
2926 tree param
, next_param
;
2929 cum
->prototype
= (fntype
&& TYPE_ARG_TYPES (fntype
));
2931 /* Determine if this function has variable arguments. This is
2932 indicated by the last argument being 'void_type_mode' if there
2933 are no variable arguments. The standard MIPS calling sequence
2934 passes all arguments in the general purpose registers in this case. */
2936 for (param
= fntype
? TYPE_ARG_TYPES (fntype
) : 0;
2937 param
!= 0; param
= next_param
)
2939 next_param
= TREE_CHAIN (param
);
2940 if (next_param
== 0 && TREE_VALUE (param
) != void_type_node
)
2941 cum
->gp_reg_found
= 1;
2946 /* Fill INFO with information about a single argument. CUM is the
2947 cumulative state for earlier arguments. MODE is the mode of this
2948 argument and TYPE is its type (if known). NAMED is true if this
2949 is a named (fixed) argument rather than a variable one. */
2952 mips_arg_info (const CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
2953 tree type
, int named
, struct mips_arg_info
*info
)
2956 unsigned int num_bytes
, num_words
, max_regs
;
2958 /* Work out the size of the argument. */
2959 num_bytes
= type
? int_size_in_bytes (type
) : GET_MODE_SIZE (mode
);
2960 num_words
= (num_bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
2962 /* Decide whether it should go in a floating-point register, assuming
2963 one is free. Later code checks for availability.
2965 The checks against UNITS_PER_FPVALUE handle the soft-float and
2966 single-float cases. */
2970 /* The EABI conventions have traditionally been defined in terms
2971 of TYPE_MODE, regardless of the actual type. */
2972 info
->fpr_p
= ((GET_MODE_CLASS (mode
) == MODE_FLOAT
2973 || GET_MODE_CLASS (mode
) == MODE_VECTOR_FLOAT
)
2974 && GET_MODE_SIZE (mode
) <= UNITS_PER_FPVALUE
);
2979 /* Only leading floating-point scalars are passed in
2980 floating-point registers. We also handle vector floats the same
2981 say, which is OK because they are not covered by the standard ABI. */
2982 info
->fpr_p
= (!cum
->gp_reg_found
2983 && cum
->arg_number
< 2
2984 && (type
== 0 || SCALAR_FLOAT_TYPE_P (type
)
2985 || VECTOR_FLOAT_TYPE_P (type
))
2986 && (GET_MODE_CLASS (mode
) == MODE_FLOAT
2987 || GET_MODE_CLASS (mode
) == MODE_VECTOR_FLOAT
)
2988 && GET_MODE_SIZE (mode
) <= UNITS_PER_FPVALUE
);
2993 /* Scalar and complex floating-point types are passed in
2994 floating-point registers. */
2995 info
->fpr_p
= (named
2996 && (type
== 0 || FLOAT_TYPE_P (type
))
2997 && (GET_MODE_CLASS (mode
) == MODE_FLOAT
2998 || GET_MODE_CLASS (mode
) == MODE_COMPLEX_FLOAT
2999 || GET_MODE_CLASS (mode
) == MODE_VECTOR_FLOAT
)
3000 && GET_MODE_UNIT_SIZE (mode
) <= UNITS_PER_FPVALUE
);
3002 /* ??? According to the ABI documentation, the real and imaginary
3003 parts of complex floats should be passed in individual registers.
3004 The real and imaginary parts of stack arguments are supposed
3005 to be contiguous and there should be an extra word of padding
3008 This has two problems. First, it makes it impossible to use a
3009 single "void *" va_list type, since register and stack arguments
3010 are passed differently. (At the time of writing, MIPSpro cannot
3011 handle complex float varargs correctly.) Second, it's unclear
3012 what should happen when there is only one register free.
3014 For now, we assume that named complex floats should go into FPRs
3015 if there are two FPRs free, otherwise they should be passed in the
3016 same way as a struct containing two floats. */
3018 && GET_MODE_CLASS (mode
) == MODE_COMPLEX_FLOAT
3019 && GET_MODE_UNIT_SIZE (mode
) < UNITS_PER_FPVALUE
)
3021 if (cum
->num_gprs
>= MAX_ARGS_IN_REGISTERS
- 1)
3022 info
->fpr_p
= false;
3032 /* Now decide whether the argument must go in an even-numbered register.
3033 Usually this is determined by type alignment, but there are two
3036 - Under the O64 ABI, the second float argument goes in $f14 if it
3037 is single precision (doubles go in $f13 as expected).
3039 - Floats passed in FPRs must be in an even-numbered register if
3040 we're using paired FPRs. */
3042 even_reg_p
= TYPE_ALIGN (type
) > BITS_PER_WORD
;
3044 even_reg_p
= GET_MODE_UNIT_SIZE (mode
) > UNITS_PER_WORD
;
3048 if (mips_abi
== ABI_O64
&& mode
== SFmode
)
3054 /* Set REG_OFFSET to the register count we're interested in.
3055 The EABI allocates the floating-point registers separately,
3056 but the other ABIs allocate them like integer registers. */
3057 info
->reg_offset
= (mips_abi
== ABI_EABI
&& info
->fpr_p
3062 info
->reg_offset
+= info
->reg_offset
& 1;
3064 /* The alignment applied to registers is also applied to stack arguments. */
3065 info
->stack_offset
= cum
->stack_words
;
3067 info
->stack_offset
+= info
->stack_offset
& 1;
3069 max_regs
= MAX_ARGS_IN_REGISTERS
- info
->reg_offset
;
3071 /* Partition the argument between registers and stack. */
3072 info
->reg_words
= MIN (num_words
, max_regs
);
3073 info
->stack_words
= num_words
- info
->reg_words
;
3077 /* Implement FUNCTION_ARG_ADVANCE. */
3080 function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
3081 tree type
, int named
)
3083 struct mips_arg_info info
;
3085 mips_arg_info (cum
, mode
, type
, named
, &info
);
3088 cum
->gp_reg_found
= true;
3090 /* See the comment above the cumulative args structure in mips.h
3091 for an explanation of what this code does. It assumes the O32
3092 ABI, which passes at most 2 arguments in float registers. */
3093 if (cum
->arg_number
< 2 && info
.fpr_p
)
3094 cum
->fp_code
+= (mode
== SFmode
? 1 : 2) << ((cum
->arg_number
- 1) * 2);
3096 if (mips_abi
!= ABI_EABI
|| !info
.fpr_p
)
3097 cum
->num_gprs
= info
.reg_offset
+ info
.reg_words
;
3098 else if (info
.reg_words
> 0)
3099 cum
->num_fprs
+= FP_INC
;
3101 if (info
.stack_words
> 0)
3102 cum
->stack_words
= info
.stack_offset
+ info
.stack_words
;
3107 /* Implement FUNCTION_ARG. */
3110 function_arg (const CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
3111 tree type
, int named
)
3113 struct mips_arg_info info
;
3115 /* We will be called with a mode of VOIDmode after the last argument
3116 has been seen. Whatever we return will be passed to the call
3117 insn. If we need a mips16 fp_code, return a REG with the code
3118 stored as the mode. */
3119 if (mode
== VOIDmode
)
3121 if (TARGET_MIPS16
&& cum
->fp_code
!= 0)
3122 return gen_rtx_REG ((enum machine_mode
) cum
->fp_code
, 0);
3128 mips_arg_info (cum
, mode
, type
, named
, &info
);
3130 /* Return straight away if the whole argument is passed on the stack. */
3131 if (info
.reg_offset
== MAX_ARGS_IN_REGISTERS
)
3135 && TREE_CODE (type
) == RECORD_TYPE
3137 && TYPE_SIZE_UNIT (type
)
3138 && host_integerp (TYPE_SIZE_UNIT (type
), 1)
3141 /* The Irix 6 n32/n64 ABIs say that if any 64 bit chunk of the
3142 structure contains a double in its entirety, then that 64 bit
3143 chunk is passed in a floating point register. */
3146 /* First check to see if there is any such field. */
3147 for (field
= TYPE_FIELDS (type
); field
; field
= TREE_CHAIN (field
))
3148 if (TREE_CODE (field
) == FIELD_DECL
3149 && TREE_CODE (TREE_TYPE (field
)) == REAL_TYPE
3150 && TYPE_PRECISION (TREE_TYPE (field
)) == BITS_PER_WORD
3151 && host_integerp (bit_position (field
), 0)
3152 && int_bit_position (field
) % BITS_PER_WORD
== 0)
3157 /* Now handle the special case by returning a PARALLEL
3158 indicating where each 64 bit chunk goes. INFO.REG_WORDS
3159 chunks are passed in registers. */
3161 HOST_WIDE_INT bitpos
;
3164 /* assign_parms checks the mode of ENTRY_PARM, so we must
3165 use the actual mode here. */
3166 ret
= gen_rtx_PARALLEL (mode
, rtvec_alloc (info
.reg_words
));
3169 field
= TYPE_FIELDS (type
);
3170 for (i
= 0; i
< info
.reg_words
; i
++)
3174 for (; field
; field
= TREE_CHAIN (field
))
3175 if (TREE_CODE (field
) == FIELD_DECL
3176 && int_bit_position (field
) >= bitpos
)
3180 && int_bit_position (field
) == bitpos
3181 && TREE_CODE (TREE_TYPE (field
)) == REAL_TYPE
3182 && !TARGET_SOFT_FLOAT
3183 && TYPE_PRECISION (TREE_TYPE (field
)) == BITS_PER_WORD
)
3184 reg
= gen_rtx_REG (DFmode
, FP_ARG_FIRST
+ info
.reg_offset
+ i
);
3186 reg
= gen_rtx_REG (DImode
, GP_ARG_FIRST
+ info
.reg_offset
+ i
);
3189 = gen_rtx_EXPR_LIST (VOIDmode
, reg
,
3190 GEN_INT (bitpos
/ BITS_PER_UNIT
));
3192 bitpos
+= BITS_PER_WORD
;
3198 /* Handle the n32/n64 conventions for passing complex floating-point
3199 arguments in FPR pairs. The real part goes in the lower register
3200 and the imaginary part goes in the upper register. */
3203 && GET_MODE_CLASS (mode
) == MODE_COMPLEX_FLOAT
)
3206 enum machine_mode inner
;
3209 inner
= GET_MODE_INNER (mode
);
3210 reg
= FP_ARG_FIRST
+ info
.reg_offset
;
3211 real
= gen_rtx_EXPR_LIST (VOIDmode
,
3212 gen_rtx_REG (inner
, reg
),
3214 imag
= gen_rtx_EXPR_LIST (VOIDmode
,
3215 gen_rtx_REG (inner
, reg
+ info
.reg_words
/ 2),
3216 GEN_INT (GET_MODE_SIZE (inner
)));
3217 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, real
, imag
));
3221 return gen_rtx_REG (mode
, FP_ARG_FIRST
+ info
.reg_offset
);
3223 return gen_rtx_REG (mode
, GP_ARG_FIRST
+ info
.reg_offset
);
3227 /* Implement FUNCTION_ARG_PARTIAL_NREGS. */
3230 function_arg_partial_nregs (const CUMULATIVE_ARGS
*cum
,
3231 enum machine_mode mode
, tree type
, int named
)
3233 struct mips_arg_info info
;
3235 mips_arg_info (cum
, mode
, type
, named
, &info
);
3236 return info
.stack_words
> 0 ? info
.reg_words
: 0;
3240 /* Return true if FUNCTION_ARG_PADDING (MODE, TYPE) should return
3241 upward rather than downward. In other words, return true if the
3242 first byte of the stack slot has useful data, false if the last
3246 mips_pad_arg_upward (enum machine_mode mode
, tree type
)
3248 /* On little-endian targets, the first byte of every stack argument
3249 is passed in the first byte of the stack slot. */
3250 if (!BYTES_BIG_ENDIAN
)
3253 /* Otherwise, integral types are padded downward: the last byte of a
3254 stack argument is passed in the last byte of the stack slot. */
3256 ? INTEGRAL_TYPE_P (type
) || POINTER_TYPE_P (type
)
3257 : GET_MODE_CLASS (mode
) == MODE_INT
)
3260 /* Big-endian o64 pads floating-point arguments downward. */
3261 if (mips_abi
== ABI_O64
)
3262 if (type
!= 0 ? FLOAT_TYPE_P (type
) : GET_MODE_CLASS (mode
) == MODE_FLOAT
)
3265 /* Other types are padded upward for o32, o64, n32 and n64. */
3266 if (mips_abi
!= ABI_EABI
)
3269 /* Arguments smaller than a stack slot are padded downward. */
3270 if (mode
!= BLKmode
)
3271 return (GET_MODE_BITSIZE (mode
) >= PARM_BOUNDARY
);
3273 return (int_size_in_bytes (type
) >= (PARM_BOUNDARY
/ BITS_PER_UNIT
));
3277 /* Likewise BLOCK_REG_PADDING (MODE, TYPE, ...). Return !BYTES_BIG_ENDIAN
3278 if the least significant byte of the register has useful data. Return
3279 the opposite if the most significant byte does. */
3282 mips_pad_reg_upward (enum machine_mode mode
, tree type
)
3284 /* No shifting is required for floating-point arguments. */
3285 if (type
!= 0 ? FLOAT_TYPE_P (type
) : GET_MODE_CLASS (mode
) == MODE_FLOAT
)
3286 return !BYTES_BIG_ENDIAN
;
3288 /* Otherwise, apply the same padding to register arguments as we do
3289 to stack arguments. */
3290 return mips_pad_arg_upward (mode
, type
);
3294 mips_setup_incoming_varargs (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
3295 tree type
, int *pretend_size
, int no_rtl
)
3297 CUMULATIVE_ARGS local_cum
;
3298 int gp_saved
, fp_saved
;
3300 /* The caller has advanced CUM up to, but not beyond, the last named
3301 argument. Advance a local copy of CUM past the last "real" named
3302 argument, to find out how many registers are left over. */
3305 FUNCTION_ARG_ADVANCE (local_cum
, mode
, type
, 1);
3307 /* Found out how many registers we need to save. */
3308 gp_saved
= MAX_ARGS_IN_REGISTERS
- local_cum
.num_gprs
;
3309 fp_saved
= (EABI_FLOAT_VARARGS_P
3310 ? MAX_ARGS_IN_REGISTERS
- local_cum
.num_fprs
3319 ptr
= virtual_incoming_args_rtx
;
3324 ptr
= plus_constant (ptr
, local_cum
.num_gprs
* UNITS_PER_WORD
);
3328 ptr
= plus_constant (ptr
, -gp_saved
* UNITS_PER_WORD
);
3331 mem
= gen_rtx_MEM (BLKmode
, ptr
);
3332 set_mem_alias_set (mem
, get_varargs_alias_set ());
3334 move_block_from_reg (local_cum
.num_gprs
+ GP_ARG_FIRST
,
3339 /* We can't use move_block_from_reg, because it will use
3341 enum machine_mode mode
;
3344 /* Set OFF to the offset from virtual_incoming_args_rtx of
3345 the first float register. The FP save area lies below
3346 the integer one, and is aligned to UNITS_PER_FPVALUE bytes. */
3347 off
= -gp_saved
* UNITS_PER_WORD
;
3348 off
&= ~(UNITS_PER_FPVALUE
- 1);
3349 off
-= fp_saved
* UNITS_PER_FPREG
;
3351 mode
= TARGET_SINGLE_FLOAT
? SFmode
: DFmode
;
3353 for (i
= local_cum
.num_fprs
; i
< MAX_ARGS_IN_REGISTERS
; i
+= FP_INC
)
3357 ptr
= plus_constant (virtual_incoming_args_rtx
, off
);
3358 mem
= gen_rtx_MEM (mode
, ptr
);
3359 set_mem_alias_set (mem
, get_varargs_alias_set ());
3360 emit_move_insn (mem
, gen_rtx_REG (mode
, FP_ARG_FIRST
+ i
));
3361 off
+= UNITS_PER_HWFPVALUE
;
3367 /* No need for pretend arguments: the register parameter area was
3368 allocated by the caller. */
3372 *pretend_size
= (gp_saved
* UNITS_PER_WORD
) + (fp_saved
* UNITS_PER_FPREG
);
3375 /* Create the va_list data type.
3376 We keep 3 pointers, and two offsets.
3377 Two pointers are to the overflow area, which starts at the CFA.
3378 One of these is constant, for addressing into the GPR save area below it.
3379 The other is advanced up the stack through the overflow region.
3380 The third pointer is to the GPR save area. Since the FPR save area
3381 is just below it, we can address FPR slots off this pointer.
3382 We also keep two one-byte offsets, which are to be subtracted from the
3383 constant pointers to yield addresses in the GPR and FPR save areas.
3384 These are downcounted as float or non-float arguments are used,
3385 and when they get to zero, the argument must be obtained from the
3387 If !EABI_FLOAT_VARARGS_P, then no FPR save area exists, and a single
3388 pointer is enough. It's started at the GPR save area, and is
3390 Note that the GPR save area is not constant size, due to optimization
3391 in the prologue. Hence, we can't use a design with two pointers
3392 and two offsets, although we could have designed this with two pointers
3393 and three offsets. */
3396 mips_build_builtin_va_list (void)
3398 if (EABI_FLOAT_VARARGS_P
)
3400 tree f_ovfl
, f_gtop
, f_ftop
, f_goff
, f_foff
, f_res
, record
;
3403 record
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
3405 f_ovfl
= build_decl (FIELD_DECL
, get_identifier ("__overflow_argptr"),
3407 f_gtop
= build_decl (FIELD_DECL
, get_identifier ("__gpr_top"),
3409 f_ftop
= build_decl (FIELD_DECL
, get_identifier ("__fpr_top"),
3411 f_goff
= build_decl (FIELD_DECL
, get_identifier ("__gpr_offset"),
3412 unsigned_char_type_node
);
3413 f_foff
= build_decl (FIELD_DECL
, get_identifier ("__fpr_offset"),
3414 unsigned_char_type_node
);
3415 /* Explicitly pad to the size of a pointer, so that -Wpadded won't
3416 warn on every user file. */
3417 index
= build_int_cst (NULL_TREE
, GET_MODE_SIZE (ptr_mode
) - 2 - 1);
3418 array
= build_array_type (unsigned_char_type_node
,
3419 build_index_type (index
));
3420 f_res
= build_decl (FIELD_DECL
, get_identifier ("__reserved"), array
);
3422 DECL_FIELD_CONTEXT (f_ovfl
) = record
;
3423 DECL_FIELD_CONTEXT (f_gtop
) = record
;
3424 DECL_FIELD_CONTEXT (f_ftop
) = record
;
3425 DECL_FIELD_CONTEXT (f_goff
) = record
;
3426 DECL_FIELD_CONTEXT (f_foff
) = record
;
3427 DECL_FIELD_CONTEXT (f_res
) = record
;
3429 TYPE_FIELDS (record
) = f_ovfl
;
3430 TREE_CHAIN (f_ovfl
) = f_gtop
;
3431 TREE_CHAIN (f_gtop
) = f_ftop
;
3432 TREE_CHAIN (f_ftop
) = f_goff
;
3433 TREE_CHAIN (f_goff
) = f_foff
;
3434 TREE_CHAIN (f_foff
) = f_res
;
3436 layout_type (record
);
3439 else if (TARGET_IRIX
&& TARGET_IRIX6
)
3440 /* On IRIX 6, this type is 'char *'. */
3441 return build_pointer_type (char_type_node
);
3443 /* Otherwise, we use 'void *'. */
3444 return ptr_type_node
;
3447 /* Implement va_start. */
3450 mips_va_start (tree valist
, rtx nextarg
)
3452 const CUMULATIVE_ARGS
*cum
= ¤t_function_args_info
;
3454 /* ARG_POINTER_REGNUM is initialized to STACK_POINTER_BOUNDARY, but
3455 since the stack is aligned for a pair of argument-passing slots,
3456 and the beginning of a variable argument list may be an odd slot,
3457 we have to decrease its alignment. */
3458 if (cfun
&& cfun
->emit
->regno_pointer_align
)
3459 while (((current_function_pretend_args_size
* BITS_PER_UNIT
)
3460 & (REGNO_POINTER_ALIGN (ARG_POINTER_REGNUM
) - 1)) != 0)
3461 REGNO_POINTER_ALIGN (ARG_POINTER_REGNUM
) /= 2;
3463 if (mips_abi
== ABI_EABI
)
3465 int gpr_save_area_size
;
3468 = (MAX_ARGS_IN_REGISTERS
- cum
->num_gprs
) * UNITS_PER_WORD
;
3470 if (EABI_FLOAT_VARARGS_P
)
3472 tree f_ovfl
, f_gtop
, f_ftop
, f_goff
, f_foff
;
3473 tree ovfl
, gtop
, ftop
, goff
, foff
;
3476 int fpr_save_area_size
;
3478 f_ovfl
= TYPE_FIELDS (va_list_type_node
);
3479 f_gtop
= TREE_CHAIN (f_ovfl
);
3480 f_ftop
= TREE_CHAIN (f_gtop
);
3481 f_goff
= TREE_CHAIN (f_ftop
);
3482 f_foff
= TREE_CHAIN (f_goff
);
3484 ovfl
= build (COMPONENT_REF
, TREE_TYPE (f_ovfl
), valist
, f_ovfl
,
3486 gtop
= build (COMPONENT_REF
, TREE_TYPE (f_gtop
), valist
, f_gtop
,
3488 ftop
= build (COMPONENT_REF
, TREE_TYPE (f_ftop
), valist
, f_ftop
,
3490 goff
= build (COMPONENT_REF
, TREE_TYPE (f_goff
), valist
, f_goff
,
3492 foff
= build (COMPONENT_REF
, TREE_TYPE (f_foff
), valist
, f_foff
,
3495 /* Emit code to initialize OVFL, which points to the next varargs
3496 stack argument. CUM->STACK_WORDS gives the number of stack
3497 words used by named arguments. */
3498 t
= make_tree (TREE_TYPE (ovfl
), virtual_incoming_args_rtx
);
3499 if (cum
->stack_words
> 0)
3500 t
= build (PLUS_EXPR
, TREE_TYPE (ovfl
), t
,
3501 build_int_cst (NULL_TREE
,
3502 cum
->stack_words
* UNITS_PER_WORD
));
3503 t
= build (MODIFY_EXPR
, TREE_TYPE (ovfl
), ovfl
, t
);
3504 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3506 /* Emit code to initialize GTOP, the top of the GPR save area. */
3507 t
= make_tree (TREE_TYPE (gtop
), virtual_incoming_args_rtx
);
3508 t
= build (MODIFY_EXPR
, TREE_TYPE (gtop
), gtop
, t
);
3509 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3511 /* Emit code to initialize FTOP, the top of the FPR save area.
3512 This address is gpr_save_area_bytes below GTOP, rounded
3513 down to the next fp-aligned boundary. */
3514 t
= make_tree (TREE_TYPE (ftop
), virtual_incoming_args_rtx
);
3515 fpr_offset
= gpr_save_area_size
+ UNITS_PER_FPVALUE
- 1;
3516 fpr_offset
&= ~(UNITS_PER_FPVALUE
- 1);
3518 t
= build (PLUS_EXPR
, TREE_TYPE (ftop
), t
,
3519 build_int_cst (NULL_TREE
, -fpr_offset
));
3520 t
= build (MODIFY_EXPR
, TREE_TYPE (ftop
), ftop
, t
);
3521 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3523 /* Emit code to initialize GOFF, the offset from GTOP of the
3524 next GPR argument. */
3525 t
= build (MODIFY_EXPR
, TREE_TYPE (goff
), goff
,
3526 build_int_cst (NULL_TREE
, gpr_save_area_size
));
3527 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3529 /* Likewise emit code to initialize FOFF, the offset from FTOP
3530 of the next FPR argument. */
3532 = (MAX_ARGS_IN_REGISTERS
- cum
->num_fprs
) * UNITS_PER_FPREG
;
3533 t
= build (MODIFY_EXPR
, TREE_TYPE (foff
), foff
,
3534 build_int_cst (NULL_TREE
, fpr_save_area_size
));
3535 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3539 /* Everything is in the GPR save area, or in the overflow
3540 area which is contiguous with it. */
3541 nextarg
= plus_constant (nextarg
, -gpr_save_area_size
);
3542 std_expand_builtin_va_start (valist
, nextarg
);
3546 std_expand_builtin_va_start (valist
, nextarg
);
3549 /* Implement va_arg. */
3552 mips_gimplify_va_arg_expr (tree valist
, tree type
, tree
*pre_p
, tree
*post_p
)
3554 HOST_WIDE_INT size
, rsize
;
3558 indirect
= pass_by_reference (NULL
, TYPE_MODE (type
), type
, 0);
3561 type
= build_pointer_type (type
);
3563 size
= int_size_in_bytes (type
);
3564 rsize
= (size
+ UNITS_PER_WORD
- 1) & -UNITS_PER_WORD
;
3566 if (mips_abi
!= ABI_EABI
|| !EABI_FLOAT_VARARGS_P
)
3567 addr
= std_gimplify_va_arg_expr (valist
, type
, pre_p
, post_p
);
3570 /* Not a simple merged stack. */
3572 tree f_ovfl
, f_gtop
, f_ftop
, f_goff
, f_foff
;
3573 tree ovfl
, top
, off
, align
;
3574 HOST_WIDE_INT osize
;
3577 f_ovfl
= TYPE_FIELDS (va_list_type_node
);
3578 f_gtop
= TREE_CHAIN (f_ovfl
);
3579 f_ftop
= TREE_CHAIN (f_gtop
);
3580 f_goff
= TREE_CHAIN (f_ftop
);
3581 f_foff
= TREE_CHAIN (f_goff
);
3583 /* We maintain separate pointers and offsets for floating-point
3584 and integer arguments, but we need similar code in both cases.
3587 TOP be the top of the register save area;
3588 OFF be the offset from TOP of the next register;
3589 ADDR_RTX be the address of the argument;
3590 RSIZE be the number of bytes used to store the argument
3591 when it's in the register save area;
3592 OSIZE be the number of bytes used to store it when it's
3593 in the stack overflow area; and
3594 PADDING be (BYTES_BIG_ENDIAN ? OSIZE - RSIZE : 0)
3596 The code we want is:
3598 1: off &= -rsize; // round down
3601 4: addr_rtx = top - off;
3606 9: ovfl += ((intptr_t) ovfl + osize - 1) & -osize;
3607 10: addr_rtx = ovfl + PADDING;
3611 [1] and [9] can sometimes be optimized away. */
3613 ovfl
= build (COMPONENT_REF
, TREE_TYPE (f_ovfl
), valist
, f_ovfl
,
3616 if (GET_MODE_CLASS (TYPE_MODE (type
)) == MODE_FLOAT
3617 && GET_MODE_SIZE (TYPE_MODE (type
)) <= UNITS_PER_FPVALUE
)
3619 top
= build (COMPONENT_REF
, TREE_TYPE (f_ftop
), valist
, f_ftop
,
3621 off
= build (COMPONENT_REF
, TREE_TYPE (f_foff
), valist
, f_foff
,
3624 /* When floating-point registers are saved to the stack,
3625 each one will take up UNITS_PER_HWFPVALUE bytes, regardless
3626 of the float's precision. */
3627 rsize
= UNITS_PER_HWFPVALUE
;
3629 /* Overflow arguments are padded to UNITS_PER_WORD bytes
3630 (= PARM_BOUNDARY bits). This can be different from RSIZE
3633 (1) On 32-bit targets when TYPE is a structure such as:
3635 struct s { float f; };
3637 Such structures are passed in paired FPRs, so RSIZE
3638 will be 8 bytes. However, the structure only takes
3639 up 4 bytes of memory, so OSIZE will only be 4.
3641 (2) In combinations such as -mgp64 -msingle-float
3642 -fshort-double. Doubles passed in registers
3643 will then take up 4 (UNITS_PER_HWFPVALUE) bytes,
3644 but those passed on the stack take up
3645 UNITS_PER_WORD bytes. */
3646 osize
= MAX (GET_MODE_SIZE (TYPE_MODE (type
)), UNITS_PER_WORD
);
3650 top
= build (COMPONENT_REF
, TREE_TYPE (f_gtop
), valist
, f_gtop
,
3652 off
= build (COMPONENT_REF
, TREE_TYPE (f_goff
), valist
, f_goff
,
3654 if (rsize
> UNITS_PER_WORD
)
3656 /* [1] Emit code for: off &= -rsize. */
3657 t
= build (BIT_AND_EXPR
, TREE_TYPE (off
), off
,
3658 build_int_cst (NULL_TREE
, -rsize
));
3659 t
= build (MODIFY_EXPR
, TREE_TYPE (off
), off
, t
);
3660 gimplify_and_add (t
, pre_p
);
3665 /* [2] Emit code to branch if off == 0. */
3666 t
= lang_hooks
.truthvalue_conversion (off
);
3667 addr
= build (COND_EXPR
, ptr_type_node
, t
, NULL
, NULL
);
3669 /* [5] Emit code for: off -= rsize. We do this as a form of
3670 post-increment not available to C. Also widen for the
3671 coming pointer arithmetic. */
3672 t
= fold_convert (TREE_TYPE (off
), build_int_cst (NULL_TREE
, rsize
));
3673 t
= build (POSTDECREMENT_EXPR
, TREE_TYPE (off
), off
, t
);
3674 t
= fold_convert (sizetype
, t
);
3675 t
= fold_convert (TREE_TYPE (top
), t
);
3677 /* [4] Emit code for: addr_rtx = top - off. On big endian machines,
3678 the argument has RSIZE - SIZE bytes of leading padding. */
3679 t
= build (MINUS_EXPR
, TREE_TYPE (top
), top
, t
);
3680 if (BYTES_BIG_ENDIAN
&& rsize
> size
)
3682 u
= fold_convert (TREE_TYPE (t
), build_int_cst (NULL_TREE
,
3684 t
= build (PLUS_EXPR
, TREE_TYPE (t
), t
, u
);
3686 COND_EXPR_THEN (addr
) = t
;
3688 if (osize
> UNITS_PER_WORD
)
3690 /* [9] Emit: ovfl += ((intptr_t) ovfl + osize - 1) & -osize. */
3691 u
= fold_convert (TREE_TYPE (ovfl
),
3692 build_int_cst (NULL_TREE
, osize
- 1));
3693 t
= build (PLUS_EXPR
, TREE_TYPE (ovfl
), ovfl
, u
);
3694 u
= fold_convert (TREE_TYPE (ovfl
),
3695 build_int_cst (NULL_TREE
, -osize
));
3696 t
= build (BIT_AND_EXPR
, TREE_TYPE (ovfl
), t
, u
);
3697 align
= build (MODIFY_EXPR
, TREE_TYPE (ovfl
), ovfl
, t
);
3702 /* [10, 11]. Emit code to store ovfl in addr_rtx, then
3703 post-increment ovfl by osize. On big-endian machines,
3704 the argument has OSIZE - SIZE bytes of leading padding. */
3705 u
= fold_convert (TREE_TYPE (ovfl
),
3706 build_int_cst (NULL_TREE
, osize
));
3707 t
= build (POSTINCREMENT_EXPR
, TREE_TYPE (ovfl
), ovfl
, u
);
3708 if (BYTES_BIG_ENDIAN
&& osize
> size
)
3710 u
= fold_convert (TREE_TYPE (t
),
3711 build_int_cst (NULL_TREE
, osize
- size
));
3712 t
= build (PLUS_EXPR
, TREE_TYPE (t
), t
, u
);
3715 /* String [9] and [10,11] together. */
3717 t
= build (COMPOUND_EXPR
, TREE_TYPE (t
), align
, t
);
3718 COND_EXPR_ELSE (addr
) = t
;
3720 addr
= fold_convert (build_pointer_type (type
), addr
);
3721 addr
= build_fold_indirect_ref (addr
);
3725 addr
= build_fold_indirect_ref (addr
);
3730 /* Return true if it is possible to use left/right accesses for a
3731 bitfield of WIDTH bits starting BITPOS bits into *OP. When
3732 returning true, update *OP, *LEFT and *RIGHT as follows:
3734 *OP is a BLKmode reference to the whole field.
3736 *LEFT is a QImode reference to the first byte if big endian or
3737 the last byte if little endian. This address can be used in the
3738 left-side instructions (lwl, swl, ldl, sdl).
3740 *RIGHT is a QImode reference to the opposite end of the field and
3741 can be used in the parterning right-side instruction. */
3744 mips_get_unaligned_mem (rtx
*op
, unsigned int width
, int bitpos
,
3745 rtx
*left
, rtx
*right
)
3749 /* Check that the operand really is a MEM. Not all the extv and
3750 extzv predicates are checked. */
3751 if (GET_CODE (*op
) != MEM
)
3754 /* Check that the size is valid. */
3755 if (width
!= 32 && (!TARGET_64BIT
|| width
!= 64))
3758 /* We can only access byte-aligned values. Since we are always passed
3759 a reference to the first byte of the field, it is not necessary to
3760 do anything with BITPOS after this check. */
3761 if (bitpos
% BITS_PER_UNIT
!= 0)
3764 /* Reject aligned bitfields: we want to use a normal load or store
3765 instead of a left/right pair. */
3766 if (MEM_ALIGN (*op
) >= width
)
3769 /* Adjust *OP to refer to the whole field. This also has the effect
3770 of legitimizing *OP's address for BLKmode, possibly simplifying it. */
3771 *op
= adjust_address (*op
, BLKmode
, 0);
3772 set_mem_size (*op
, GEN_INT (width
/ BITS_PER_UNIT
));
3774 /* Get references to both ends of the field. We deliberately don't
3775 use the original QImode *OP for FIRST since the new BLKmode one
3776 might have a simpler address. */
3777 first
= adjust_address (*op
, QImode
, 0);
3778 last
= adjust_address (*op
, QImode
, width
/ BITS_PER_UNIT
- 1);
3780 /* Allocate to LEFT and RIGHT according to endianness. LEFT should
3781 be the upper word and RIGHT the lower word. */
3782 if (TARGET_BIG_ENDIAN
)
3783 *left
= first
, *right
= last
;
3785 *left
= last
, *right
= first
;
3791 /* Try to emit the equivalent of (set DEST (zero_extract SRC WIDTH BITPOS)).
3792 Return true on success. We only handle cases where zero_extract is
3793 equivalent to sign_extract. */
3796 mips_expand_unaligned_load (rtx dest
, rtx src
, unsigned int width
, int bitpos
)
3798 rtx left
, right
, temp
;
3800 /* If TARGET_64BIT, the destination of a 32-bit load will be a
3801 paradoxical word_mode subreg. This is the only case in which
3802 we allow the destination to be larger than the source. */
3803 if (GET_CODE (dest
) == SUBREG
3804 && GET_MODE (dest
) == DImode
3805 && SUBREG_BYTE (dest
) == 0
3806 && GET_MODE (SUBREG_REG (dest
)) == SImode
)
3807 dest
= SUBREG_REG (dest
);
3809 /* After the above adjustment, the destination must be the same
3810 width as the source. */
3811 if (GET_MODE_BITSIZE (GET_MODE (dest
)) != width
)
3814 if (!mips_get_unaligned_mem (&src
, width
, bitpos
, &left
, &right
))
3817 temp
= gen_reg_rtx (GET_MODE (dest
));
3818 if (GET_MODE (dest
) == DImode
)
3820 emit_insn (gen_mov_ldl (temp
, src
, left
));
3821 emit_insn (gen_mov_ldr (dest
, copy_rtx (src
), right
, temp
));
3825 emit_insn (gen_mov_lwl (temp
, src
, left
));
3826 emit_insn (gen_mov_lwr (dest
, copy_rtx (src
), right
, temp
));
3832 /* Try to expand (set (zero_extract DEST WIDTH BITPOS) SRC). Return
3836 mips_expand_unaligned_store (rtx dest
, rtx src
, unsigned int width
, int bitpos
)
3840 if (!mips_get_unaligned_mem (&dest
, width
, bitpos
, &left
, &right
))
3843 src
= gen_lowpart (mode_for_size (width
, MODE_INT
, 0), src
);
3845 if (GET_MODE (src
) == DImode
)
3847 emit_insn (gen_mov_sdl (dest
, src
, left
));
3848 emit_insn (gen_mov_sdr (copy_rtx (dest
), copy_rtx (src
), right
));
3852 emit_insn (gen_mov_swl (dest
, src
, left
));
3853 emit_insn (gen_mov_swr (copy_rtx (dest
), copy_rtx (src
), right
));
3858 /* Set up globals to generate code for the ISA or processor
3859 described by INFO. */
3862 mips_set_architecture (const struct mips_cpu_info
*info
)
3866 mips_arch_info
= info
;
3867 mips_arch
= info
->cpu
;
3868 mips_isa
= info
->isa
;
3873 /* Likewise for tuning. */
3876 mips_set_tune (const struct mips_cpu_info
*info
)
3880 mips_tune_info
= info
;
3881 mips_tune
= info
->cpu
;
3886 /* Set up the threshold for data to go into the small data area, instead
3887 of the normal data area, and detect any conflicts in the switches. */
3890 override_options (void)
3892 int i
, start
, regno
;
3893 enum machine_mode mode
;
3895 mips_section_threshold
= g_switch_set
? g_switch_value
: MIPS_DEFAULT_GVALUE
;
3897 /* Interpret -mabi. */
3898 mips_abi
= MIPS_ABI_DEFAULT
;
3899 if (mips_abi_string
!= 0)
3901 if (strcmp (mips_abi_string
, "32") == 0)
3903 else if (strcmp (mips_abi_string
, "o64") == 0)
3905 else if (strcmp (mips_abi_string
, "n32") == 0)
3907 else if (strcmp (mips_abi_string
, "64") == 0)
3909 else if (strcmp (mips_abi_string
, "eabi") == 0)
3910 mips_abi
= ABI_EABI
;
3912 fatal_error ("bad value (%s) for -mabi= switch", mips_abi_string
);
3915 /* The following code determines the architecture and register size.
3916 Similar code was added to GAS 2.14 (see tc-mips.c:md_after_parse_args()).
3917 The GAS and GCC code should be kept in sync as much as possible. */
3919 if (mips_arch_string
!= 0)
3920 mips_set_architecture (mips_parse_cpu ("-march", mips_arch_string
));
3922 if (mips_isa_string
!= 0)
3924 /* Handle -mipsN. */
3925 char *whole_isa_str
= concat ("mips", mips_isa_string
, NULL
);
3926 const struct mips_cpu_info
*isa_info
;
3928 isa_info
= mips_parse_cpu ("-mips option", whole_isa_str
);
3929 free (whole_isa_str
);
3931 /* -march takes precedence over -mipsN, since it is more descriptive.
3932 There's no harm in specifying both as long as the ISA levels
3934 if (mips_arch_info
!= 0 && mips_isa
!= isa_info
->isa
)
3935 error ("-mips%s conflicts with the other architecture options, "
3936 "which specify a MIPS%d processor",
3937 mips_isa_string
, mips_isa
);
3939 /* Set architecture based on the given option. */
3940 mips_set_architecture (isa_info
);
3943 if (mips_arch_info
== 0)
3945 #ifdef MIPS_CPU_STRING_DEFAULT
3946 mips_set_architecture (mips_parse_cpu ("default CPU",
3947 MIPS_CPU_STRING_DEFAULT
));
3949 mips_set_architecture (mips_cpu_info_from_isa (MIPS_ISA_DEFAULT
));
3953 if (ABI_NEEDS_64BIT_REGS
&& !ISA_HAS_64BIT_REGS
)
3954 error ("-march=%s is not compatible with the selected ABI",
3955 mips_arch_info
->name
);
3957 /* Optimize for mips_arch, unless -mtune selects a different processor. */
3958 if (mips_tune_string
!= 0)
3959 mips_set_tune (mips_parse_cpu ("-mtune", mips_tune_string
));
3961 if (mips_tune_info
== 0)
3962 mips_set_tune (mips_arch_info
);
3964 if ((target_flags_explicit
& MASK_64BIT
) != 0)
3966 /* The user specified the size of the integer registers. Make sure
3967 it agrees with the ABI and ISA. */
3968 if (TARGET_64BIT
&& !ISA_HAS_64BIT_REGS
)
3969 error ("-mgp64 used with a 32-bit processor");
3970 else if (!TARGET_64BIT
&& ABI_NEEDS_64BIT_REGS
)
3971 error ("-mgp32 used with a 64-bit ABI");
3972 else if (TARGET_64BIT
&& ABI_NEEDS_32BIT_REGS
)
3973 error ("-mgp64 used with a 32-bit ABI");
3977 /* Infer the integer register size from the ABI and processor.
3978 Restrict ourselves to 32-bit registers if that's all the
3979 processor has, or if the ABI cannot handle 64-bit registers. */
3980 if (ABI_NEEDS_32BIT_REGS
|| !ISA_HAS_64BIT_REGS
)
3981 target_flags
&= ~MASK_64BIT
;
3983 target_flags
|= MASK_64BIT
;
3986 if ((target_flags_explicit
& MASK_FLOAT64
) != 0)
3988 /* Really, -mfp32 and -mfp64 are ornamental options. There's
3989 only one right answer here. */
3990 if (TARGET_64BIT
&& TARGET_DOUBLE_FLOAT
&& !TARGET_FLOAT64
)
3991 error ("unsupported combination: %s", "-mgp64 -mfp32 -mdouble-float");
3992 else if (!TARGET_64BIT
&& TARGET_FLOAT64
)
3993 error ("unsupported combination: %s", "-mgp32 -mfp64");
3994 else if (TARGET_SINGLE_FLOAT
&& TARGET_FLOAT64
)
3995 error ("unsupported combination: %s", "-mfp64 -msingle-float");
3999 /* -msingle-float selects 32-bit float registers. Otherwise the
4000 float registers should be the same size as the integer ones. */
4001 if (TARGET_64BIT
&& TARGET_DOUBLE_FLOAT
)
4002 target_flags
|= MASK_FLOAT64
;
4004 target_flags
&= ~MASK_FLOAT64
;
4007 /* End of code shared with GAS. */
4009 if ((target_flags_explicit
& MASK_LONG64
) == 0)
4011 /* If no type size setting options (-mlong64,-mint64,-mlong32)
4012 were used, then set the type sizes. In the EABI in 64 bit mode,
4013 longs and pointers are 64 bits. Likewise for the SGI Irix6 N64
4015 if ((mips_abi
== ABI_EABI
&& TARGET_64BIT
) || mips_abi
== ABI_64
)
4016 target_flags
|= MASK_LONG64
;
4018 target_flags
&= ~MASK_LONG64
;
4021 if (MIPS_MARCH_CONTROLS_SOFT_FLOAT
4022 && (target_flags_explicit
& MASK_SOFT_FLOAT
) == 0)
4024 /* For some configurations, it is useful to have -march control
4025 the default setting of MASK_SOFT_FLOAT. */
4026 switch ((int) mips_arch
)
4028 case PROCESSOR_R4100
:
4029 case PROCESSOR_R4111
:
4030 case PROCESSOR_R4120
:
4031 case PROCESSOR_R4130
:
4032 target_flags
|= MASK_SOFT_FLOAT
;
4036 target_flags
&= ~MASK_SOFT_FLOAT
;
4042 flag_pcc_struct_return
= 0;
4044 if ((target_flags_explicit
& MASK_BRANCHLIKELY
) == 0)
4046 /* If neither -mbranch-likely nor -mno-branch-likely was given
4047 on the command line, set MASK_BRANCHLIKELY based on the target
4050 By default, we enable use of Branch Likely instructions on
4051 all architectures which support them with the following
4052 exceptions: when creating MIPS32 or MIPS64 code, and when
4053 tuning for architectures where their use tends to hurt
4056 The MIPS32 and MIPS64 architecture specifications say "Software
4057 is strongly encouraged to avoid use of Branch Likely
4058 instructions, as they will be removed from a future revision
4059 of the [MIPS32 and MIPS64] architecture." Therefore, we do not
4060 issue those instructions unless instructed to do so by
4062 if (ISA_HAS_BRANCHLIKELY
4063 && !(ISA_MIPS32
|| ISA_MIPS32R2
|| ISA_MIPS64
)
4064 && !(TUNE_MIPS5500
|| TUNE_SB1
))
4065 target_flags
|= MASK_BRANCHLIKELY
;
4067 target_flags
&= ~MASK_BRANCHLIKELY
;
4069 if (TARGET_BRANCHLIKELY
&& !ISA_HAS_BRANCHLIKELY
)
4070 warning ("generation of Branch Likely instructions enabled, but not supported by architecture");
4072 /* The effect of -mabicalls isn't defined for the EABI. */
4073 if (mips_abi
== ABI_EABI
&& TARGET_ABICALLS
)
4075 error ("unsupported combination: %s", "-mabicalls -mabi=eabi");
4076 target_flags
&= ~MASK_ABICALLS
;
4079 /* -fpic (-KPIC) is the default when TARGET_ABICALLS is defined. We need
4080 to set flag_pic so that the LEGITIMATE_PIC_OPERAND_P macro will work. */
4081 /* ??? -non_shared turns off pic code generation, but this is not
4083 if (TARGET_ABICALLS
)
4086 if (mips_section_threshold
> 0)
4087 warning ("-G is incompatible with PIC code which is the default");
4090 /* mips_split_addresses is a half-way house between explicit
4091 relocations and the traditional assembler macros. It can
4092 split absolute 32-bit symbolic constants into a high/lo_sum
4093 pair but uses macros for other sorts of access.
4095 Like explicit relocation support for REL targets, it relies
4096 on GNU extensions in the assembler and the linker.
4098 Although this code should work for -O0, it has traditionally
4099 been treated as an optimization. */
4100 if (!TARGET_MIPS16
&& TARGET_SPLIT_ADDRESSES
4101 && optimize
&& !flag_pic
4102 && !ABI_HAS_64BIT_SYMBOLS
)
4103 mips_split_addresses
= 1;
4105 mips_split_addresses
= 0;
4107 /* -mvr4130-align is a "speed over size" optimization: it usually produces
4108 faster code, but at the expense of more nops. Enable it at -O3 and
4110 if (optimize
> 2 && (target_flags_explicit
& MASK_VR4130_ALIGN
) == 0)
4111 target_flags
|= MASK_VR4130_ALIGN
;
4113 /* When compiling for the mips16, we cannot use floating point. We
4114 record the original hard float value in mips16_hard_float. */
4117 if (TARGET_SOFT_FLOAT
)
4118 mips16_hard_float
= 0;
4120 mips16_hard_float
= 1;
4121 target_flags
|= MASK_SOFT_FLOAT
;
4123 /* Don't run the scheduler before reload, since it tends to
4124 increase register pressure. */
4125 flag_schedule_insns
= 0;
4127 /* Silently disable -mexplicit-relocs since it doesn't apply
4128 to mips16 code. Even so, it would overly pedantic to warn
4129 about "-mips16 -mexplicit-relocs", especially given that
4130 we use a %gprel() operator. */
4131 target_flags
&= ~MASK_EXPLICIT_RELOCS
;
4134 /* When using explicit relocs, we call dbr_schedule from within
4136 if (TARGET_EXPLICIT_RELOCS
)
4138 mips_flag_delayed_branch
= flag_delayed_branch
;
4139 flag_delayed_branch
= 0;
4142 #ifdef MIPS_TFMODE_FORMAT
4143 REAL_MODE_FORMAT (TFmode
) = &MIPS_TFMODE_FORMAT
;
4146 /* Make sure that the user didn't turn off paired single support when
4147 MIPS-3D support is requested. */
4148 if (TARGET_MIPS3D
&& (target_flags_explicit
& MASK_PAIRED_SINGLE
)
4149 && !TARGET_PAIRED_SINGLE_FLOAT
)
4150 error ("-mips3d requires -mpaired-single");
4152 /* If TARGET_MIPS3D, enable MASK_PAIRED_SINGLE. */
4154 target_flags
|= MASK_PAIRED_SINGLE
;
4156 /* Make sure that when TARGET_PAIRED_SINGLE_FLOAT is true, TARGET_FLOAT64
4157 and TARGET_HARD_FLOAT are both true. */
4158 if (TARGET_PAIRED_SINGLE_FLOAT
&& !(TARGET_FLOAT64
&& TARGET_HARD_FLOAT
))
4159 error ("-mips3d/-mpaired-single must be used with -mfp64 -mhard-float");
4161 /* Make sure that the ISA supports TARGET_PAIRED_SINGLE_FLOAT when it is
4163 if (TARGET_PAIRED_SINGLE_FLOAT
&& !ISA_MIPS64
)
4164 error ("-mips3d/-mpaired-single must be used with -mips64");
4166 mips_print_operand_punct
['?'] = 1;
4167 mips_print_operand_punct
['#'] = 1;
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;
4187 mips_char_to_class
['d'] = TARGET_MIPS16
? M16_REGS
: GR_REGS
;
4188 mips_char_to_class
['t'] = T_REG
;
4189 mips_char_to_class
['f'] = (TARGET_HARD_FLOAT
? FP_REGS
: NO_REGS
);
4190 mips_char_to_class
['h'] = HI_REG
;
4191 mips_char_to_class
['l'] = LO_REG
;
4192 mips_char_to_class
['x'] = MD_REGS
;
4193 mips_char_to_class
['b'] = ALL_REGS
;
4194 mips_char_to_class
['c'] = (TARGET_ABICALLS
? PIC_FN_ADDR_REG
:
4195 TARGET_MIPS16
? M16_NA_REGS
:
4197 mips_char_to_class
['e'] = LEA_REGS
;
4198 mips_char_to_class
['j'] = PIC_FN_ADDR_REG
;
4199 mips_char_to_class
['y'] = GR_REGS
;
4200 mips_char_to_class
['z'] = ST_REGS
;
4201 mips_char_to_class
['B'] = COP0_REGS
;
4202 mips_char_to_class
['C'] = COP2_REGS
;
4203 mips_char_to_class
['D'] = COP3_REGS
;
4205 /* Set up array to map GCC register number to debug register number.
4206 Ignore the special purpose register numbers. */
4208 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
4209 mips_dbx_regno
[i
] = -1;
4211 start
= GP_DBX_FIRST
- GP_REG_FIRST
;
4212 for (i
= GP_REG_FIRST
; i
<= GP_REG_LAST
; i
++)
4213 mips_dbx_regno
[i
] = i
+ start
;
4215 start
= FP_DBX_FIRST
- FP_REG_FIRST
;
4216 for (i
= FP_REG_FIRST
; i
<= FP_REG_LAST
; i
++)
4217 mips_dbx_regno
[i
] = i
+ start
;
4219 mips_dbx_regno
[HI_REGNUM
] = MD_DBX_FIRST
+ 0;
4220 mips_dbx_regno
[LO_REGNUM
] = MD_DBX_FIRST
+ 1;
4222 /* Set up array giving whether a given register can hold a given mode. */
4224 for (mode
= VOIDmode
;
4225 mode
!= MAX_MACHINE_MODE
;
4226 mode
= (enum machine_mode
) ((int)mode
+ 1))
4228 register int size
= GET_MODE_SIZE (mode
);
4229 register enum mode_class
class = GET_MODE_CLASS (mode
);
4231 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
4235 if (mode
== CCV2mode
)
4238 && (regno
- ST_REG_FIRST
) % 2 == 0);
4240 else if (mode
== CCV4mode
)
4243 && (regno
- ST_REG_FIRST
) % 4 == 0);
4245 else if (mode
== CCmode
)
4248 temp
= (regno
== FPSW_REGNUM
);
4250 temp
= (ST_REG_P (regno
) || GP_REG_P (regno
)
4251 || FP_REG_P (regno
));
4254 else if (GP_REG_P (regno
))
4255 temp
= ((regno
& 1) == 0 || size
<= UNITS_PER_WORD
);
4257 else if (FP_REG_P (regno
))
4258 temp
= ((regno
% FP_INC
) == 0)
4259 && (((class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
4260 || class == MODE_VECTOR_FLOAT
)
4261 && size
<= UNITS_PER_FPVALUE
)
4262 /* Allow integer modes that fit into a single
4263 register. We need to put integers into FPRs
4264 when using instructions like cvt and trunc. */
4265 || (class == MODE_INT
&& size
<= UNITS_PER_FPREG
)
4266 /* Allow TFmode for CCmode reloads. */
4267 || (ISA_HAS_8CC
&& mode
== TFmode
));
4269 else if (MD_REG_P (regno
))
4270 temp
= (INTEGRAL_MODE_P (mode
)
4271 && (size
<= UNITS_PER_WORD
4272 || (regno
== MD_REG_FIRST
4273 && size
== 2 * UNITS_PER_WORD
)));
4275 else if (ALL_COP_REG_P (regno
))
4276 temp
= (class == MODE_INT
&& size
<= UNITS_PER_WORD
);
4280 mips_hard_regno_mode_ok
[(int)mode
][regno
] = temp
;
4284 /* Save GPR registers in word_mode sized hunks. word_mode hasn't been
4285 initialized yet, so we can't use that here. */
4286 gpr_mode
= TARGET_64BIT
? DImode
: SImode
;
4288 /* Provide default values for align_* for 64-bit targets. */
4289 if (TARGET_64BIT
&& !TARGET_MIPS16
)
4291 if (align_loops
== 0)
4293 if (align_jumps
== 0)
4295 if (align_functions
== 0)
4296 align_functions
= 8;
4299 /* Function to allocate machine-dependent function status. */
4300 init_machine_status
= &mips_init_machine_status
;
4302 if (ABI_HAS_64BIT_SYMBOLS
)
4304 if (TARGET_EXPLICIT_RELOCS
)
4306 mips_split_p
[SYMBOL_64_HIGH
] = true;
4307 mips_hi_relocs
[SYMBOL_64_HIGH
] = "%highest(";
4308 mips_lo_relocs
[SYMBOL_64_HIGH
] = "%higher(";
4310 mips_split_p
[SYMBOL_64_MID
] = true;
4311 mips_hi_relocs
[SYMBOL_64_MID
] = "%higher(";
4312 mips_lo_relocs
[SYMBOL_64_MID
] = "%hi(";
4314 mips_split_p
[SYMBOL_64_LOW
] = true;
4315 mips_hi_relocs
[SYMBOL_64_LOW
] = "%hi(";
4316 mips_lo_relocs
[SYMBOL_64_LOW
] = "%lo(";
4318 mips_split_p
[SYMBOL_GENERAL
] = true;
4319 mips_lo_relocs
[SYMBOL_GENERAL
] = "%lo(";
4324 if (TARGET_EXPLICIT_RELOCS
|| mips_split_addresses
)
4326 mips_split_p
[SYMBOL_GENERAL
] = true;
4327 mips_hi_relocs
[SYMBOL_GENERAL
] = "%hi(";
4328 mips_lo_relocs
[SYMBOL_GENERAL
] = "%lo(";
4334 /* The high part is provided by a pseudo copy of $gp. */
4335 mips_split_p
[SYMBOL_SMALL_DATA
] = true;
4336 mips_lo_relocs
[SYMBOL_SMALL_DATA
] = "%gprel(";
4339 if (TARGET_EXPLICIT_RELOCS
)
4341 /* Small data constants are kept whole until after reload,
4342 then lowered by mips_rewrite_small_data. */
4343 mips_lo_relocs
[SYMBOL_SMALL_DATA
] = "%gp_rel(";
4345 mips_split_p
[SYMBOL_GOT_LOCAL
] = true;
4348 mips_lo_relocs
[SYMBOL_GOTOFF_PAGE
] = "%got_page(";
4349 mips_lo_relocs
[SYMBOL_GOT_LOCAL
] = "%got_ofst(";
4353 mips_lo_relocs
[SYMBOL_GOTOFF_PAGE
] = "%got(";
4354 mips_lo_relocs
[SYMBOL_GOT_LOCAL
] = "%lo(";
4359 /* The HIGH and LO_SUM are matched by special .md patterns. */
4360 mips_split_p
[SYMBOL_GOT_GLOBAL
] = true;
4362 mips_split_p
[SYMBOL_GOTOFF_GLOBAL
] = true;
4363 mips_hi_relocs
[SYMBOL_GOTOFF_GLOBAL
] = "%got_hi(";
4364 mips_lo_relocs
[SYMBOL_GOTOFF_GLOBAL
] = "%got_lo(";
4366 mips_split_p
[SYMBOL_GOTOFF_CALL
] = true;
4367 mips_hi_relocs
[SYMBOL_GOTOFF_CALL
] = "%call_hi(";
4368 mips_lo_relocs
[SYMBOL_GOTOFF_CALL
] = "%call_lo(";
4373 mips_lo_relocs
[SYMBOL_GOTOFF_GLOBAL
] = "%got_disp(";
4375 mips_lo_relocs
[SYMBOL_GOTOFF_GLOBAL
] = "%got(";
4376 mips_lo_relocs
[SYMBOL_GOTOFF_CALL
] = "%call16(";
4382 mips_split_p
[SYMBOL_GOTOFF_LOADGP
] = true;
4383 mips_hi_relocs
[SYMBOL_GOTOFF_LOADGP
] = "%hi(%neg(%gp_rel(";
4384 mips_lo_relocs
[SYMBOL_GOTOFF_LOADGP
] = "%lo(%neg(%gp_rel(";
4387 /* Default to working around R4000 errata only if the processor
4388 was selected explicitly. */
4389 if ((target_flags_explicit
& MASK_FIX_R4000
) == 0
4390 && mips_matching_cpu_name_p (mips_arch_info
->name
, "r4000"))
4391 target_flags
|= MASK_FIX_R4000
;
4393 /* Default to working around R4400 errata only if the processor
4394 was selected explicitly. */
4395 if ((target_flags_explicit
& MASK_FIX_R4400
) == 0
4396 && mips_matching_cpu_name_p (mips_arch_info
->name
, "r4400"))
4397 target_flags
|= MASK_FIX_R4400
;
4400 /* Implement CONDITIONAL_REGISTER_USAGE. */
4403 mips_conditional_register_usage (void)
4405 if (!TARGET_HARD_FLOAT
)
4409 for (regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
++)
4410 fixed_regs
[regno
] = call_used_regs
[regno
] = 1;
4411 for (regno
= ST_REG_FIRST
; regno
<= ST_REG_LAST
; regno
++)
4412 fixed_regs
[regno
] = call_used_regs
[regno
] = 1;
4414 else if (! ISA_HAS_8CC
)
4418 /* We only have a single condition code register. We
4419 implement this by hiding all the condition code registers,
4420 and generating RTL that refers directly to ST_REG_FIRST. */
4421 for (regno
= ST_REG_FIRST
; regno
<= ST_REG_LAST
; regno
++)
4422 fixed_regs
[regno
] = call_used_regs
[regno
] = 1;
4424 /* In mips16 mode, we permit the $t temporary registers to be used
4425 for reload. We prohibit the unused $s registers, since they
4426 are caller saved, and saving them via a mips16 register would
4427 probably waste more time than just reloading the value. */
4430 fixed_regs
[18] = call_used_regs
[18] = 1;
4431 fixed_regs
[19] = call_used_regs
[19] = 1;
4432 fixed_regs
[20] = call_used_regs
[20] = 1;
4433 fixed_regs
[21] = call_used_regs
[21] = 1;
4434 fixed_regs
[22] = call_used_regs
[22] = 1;
4435 fixed_regs
[23] = call_used_regs
[23] = 1;
4436 fixed_regs
[26] = call_used_regs
[26] = 1;
4437 fixed_regs
[27] = call_used_regs
[27] = 1;
4438 fixed_regs
[30] = call_used_regs
[30] = 1;
4440 /* fp20-23 are now caller saved. */
4441 if (mips_abi
== ABI_64
)
4444 for (regno
= FP_REG_FIRST
+ 20; regno
< FP_REG_FIRST
+ 24; regno
++)
4445 call_really_used_regs
[regno
] = call_used_regs
[regno
] = 1;
4447 /* Odd registers from fp21 to fp31 are now caller saved. */
4448 if (mips_abi
== ABI_N32
)
4451 for (regno
= FP_REG_FIRST
+ 21; regno
<= FP_REG_FIRST
+ 31; regno
+=2)
4452 call_really_used_regs
[regno
] = call_used_regs
[regno
] = 1;
4456 /* Allocate a chunk of memory for per-function machine-dependent data. */
4457 static struct machine_function
*
4458 mips_init_machine_status (void)
4460 return ((struct machine_function
*)
4461 ggc_alloc_cleared (sizeof (struct machine_function
)));
4464 /* On the mips16, we want to allocate $24 (T_REG) before other
4465 registers for instructions for which it is possible. This helps
4466 avoid shuffling registers around in order to set up for an xor,
4467 encouraging the compiler to use a cmp instead. */
4470 mips_order_regs_for_local_alloc (void)
4474 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
4475 reg_alloc_order
[i
] = i
;
4479 /* It really doesn't matter where we put register 0, since it is
4480 a fixed register anyhow. */
4481 reg_alloc_order
[0] = 24;
4482 reg_alloc_order
[24] = 0;
4487 /* The MIPS debug format wants all automatic variables and arguments
4488 to be in terms of the virtual frame pointer (stack pointer before
4489 any adjustment in the function), while the MIPS 3.0 linker wants
4490 the frame pointer to be the stack pointer after the initial
4491 adjustment. So, we do the adjustment here. The arg pointer (which
4492 is eliminated) points to the virtual frame pointer, while the frame
4493 pointer (which may be eliminated) points to the stack pointer after
4494 the initial adjustments. */
4497 mips_debugger_offset (rtx addr
, HOST_WIDE_INT offset
)
4499 rtx offset2
= const0_rtx
;
4500 rtx reg
= eliminate_constant_term (addr
, &offset2
);
4503 offset
= INTVAL (offset2
);
4505 if (reg
== stack_pointer_rtx
|| reg
== frame_pointer_rtx
4506 || reg
== hard_frame_pointer_rtx
)
4508 HOST_WIDE_INT frame_size
= (!cfun
->machine
->frame
.initialized
)
4509 ? compute_frame_size (get_frame_size ())
4510 : cfun
->machine
->frame
.total_size
;
4512 /* MIPS16 frame is smaller */
4513 if (frame_pointer_needed
&& TARGET_MIPS16
)
4514 frame_size
-= cfun
->machine
->frame
.args_size
;
4516 offset
= offset
- frame_size
;
4519 /* sdbout_parms does not want this to crash for unrecognized cases. */
4521 else if (reg
!= arg_pointer_rtx
)
4522 fatal_insn ("mips_debugger_offset called with non stack/frame/arg pointer",
4529 /* A helper function for print_operand. This prints out a floating point
4530 condition code register. OP is the operand we are printing. CODE is the
4531 rtx code of OP. ALIGN is the required register alignment for OP. OFFSET
4532 is the index into operand for multiple register operands. If IGNORE is
4533 true, then we only print the register name if it isn't fcc0, and we
4534 follow it with a comma. */
4537 print_fcc_operand (FILE *file
, rtx op
, enum rtx_code code
,
4538 int align
, int offset
, int ignore
)
4545 regnum
= REGNO (op
);
4546 if (!ST_REG_P (regnum
)
4547 || (regnum
- ST_REG_FIRST
) % align
!= 0)
4550 if (!ignore
|| regnum
!= ST_REG_FIRST
)
4551 fprintf (file
, "%s%s", reg_names
[regnum
+offset
], (ignore
? "," : ""));
4554 /* Implement the PRINT_OPERAND macro. The MIPS-specific operand codes are:
4556 'X' OP is CONST_INT, prints 32 bits in hexadecimal format = "0x%08x",
4557 'x' OP is CONST_INT, prints 16 bits in hexadecimal format = "0x%04x",
4558 'h' OP is HIGH, prints %hi(X),
4559 'd' output integer constant in decimal,
4560 'z' if the operand is 0, use $0 instead of normal operand.
4561 'D' print second part of double-word register or memory operand.
4562 'L' print low-order register of double-word register operand.
4563 'M' print high-order register of double-word register operand.
4564 'C' print part of opcode for a branch condition.
4565 'F' print part of opcode for a floating-point branch condition.
4566 'N' print part of opcode for a branch condition, inverted.
4567 'W' print part of opcode for a floating-point branch condition, inverted.
4568 'T' print 'f' for (eq:CC ...), 't' for (ne:CC ...),
4569 'z' for (eq:?I ...), 'n' for (ne:?I ...).
4570 't' like 'T', but with the EQ/NE cases reversed
4571 'Z' print register and a comma, but print nothing for $fcc0
4572 'R' print the reloc associated with LO_SUM
4573 'Y' Check if the fcc register number is even. Then print the fcc register
4575 'y' Check if the fcc register number is even. Then print the fcc register.
4576 'V' Check if the fcc register number divided by 4 is zero. Then print
4577 the fcc register plus 2.
4578 'v' Check if the fcc register number divided by 4 is zero. Then print
4580 'Q' print the fcc register.
4582 The punctuation characters are:
4584 '(' Turn on .set noreorder
4585 ')' Turn on .set reorder
4586 '[' Turn on .set noat
4588 '<' Turn on .set nomacro
4589 '>' Turn on .set macro
4590 '{' Turn on .set volatile (not GAS)
4591 '}' Turn on .set novolatile (not GAS)
4592 '&' Turn on .set noreorder if filling delay slots
4593 '*' Turn on both .set noreorder and .set nomacro if filling delay slots
4594 '!' Turn on .set nomacro if filling delay slots
4595 '#' Print nop if in a .set noreorder section.
4596 '/' Like '#', but does nothing within a delayed branch sequence
4597 '?' Print 'l' if we are to use a branch likely instead of normal branch.
4598 '@' Print the name of the assembler temporary register (at or $1).
4599 '.' Print the name of the register with a hard-wired zero (zero or $0).
4600 '^' Print the name of the pic call-through register (t9 or $25).
4601 '$' Print the name of the stack pointer register (sp or $29).
4602 '+' Print the name of the gp register (usually gp or $28).
4603 '~' Output a branch alignment to LABEL_ALIGN(NULL). */
4606 print_operand (FILE *file
, rtx op
, int letter
)
4608 register enum rtx_code code
;
4610 if (PRINT_OPERAND_PUNCT_VALID_P (letter
))
4615 if (mips_branch_likely
)
4620 fputs (reg_names
[GP_REG_FIRST
+ 1], file
);
4624 fputs (reg_names
[PIC_FUNCTION_ADDR_REGNUM
], file
);
4628 fputs (reg_names
[GP_REG_FIRST
+ 0], file
);
4632 fputs (reg_names
[STACK_POINTER_REGNUM
], file
);
4636 fputs (reg_names
[PIC_OFFSET_TABLE_REGNUM
], file
);
4640 if (final_sequence
!= 0 && set_noreorder
++ == 0)
4641 fputs (".set\tnoreorder\n\t", file
);
4645 if (final_sequence
!= 0)
4647 if (set_noreorder
++ == 0)
4648 fputs (".set\tnoreorder\n\t", file
);
4650 if (set_nomacro
++ == 0)
4651 fputs (".set\tnomacro\n\t", file
);
4656 if (final_sequence
!= 0 && set_nomacro
++ == 0)
4657 fputs ("\n\t.set\tnomacro", file
);
4661 if (set_noreorder
!= 0)
4662 fputs ("\n\tnop", file
);
4666 /* Print an extra newline so that the delayed insn is separated
4667 from the following ones. This looks neater and is consistent
4668 with non-nop delayed sequences. */
4669 if (set_noreorder
!= 0 && final_sequence
== 0)
4670 fputs ("\n\tnop\n", file
);
4674 if (set_noreorder
++ == 0)
4675 fputs (".set\tnoreorder\n\t", file
);
4679 if (set_noreorder
== 0)
4680 error ("internal error: %%) found without a %%( in assembler pattern");
4682 else if (--set_noreorder
== 0)
4683 fputs ("\n\t.set\treorder", file
);
4688 if (set_noat
++ == 0)
4689 fputs (".set\tnoat\n\t", file
);
4694 error ("internal error: %%] found without a %%[ in assembler pattern");
4695 else if (--set_noat
== 0)
4696 fputs ("\n\t.set\tat", file
);
4701 if (set_nomacro
++ == 0)
4702 fputs (".set\tnomacro\n\t", file
);
4706 if (set_nomacro
== 0)
4707 error ("internal error: %%> found without a %%< in assembler pattern");
4708 else if (--set_nomacro
== 0)
4709 fputs ("\n\t.set\tmacro", file
);
4714 if (set_volatile
++ == 0)
4715 fputs ("#.set\tvolatile\n\t", file
);
4719 if (set_volatile
== 0)
4720 error ("internal error: %%} found without a %%{ in assembler pattern");
4721 else if (--set_volatile
== 0)
4722 fputs ("\n\t#.set\tnovolatile", file
);
4728 if (align_labels_log
> 0)
4729 ASM_OUTPUT_ALIGN (file
, align_labels_log
);
4734 error ("PRINT_OPERAND: unknown punctuation '%c'", letter
);
4743 error ("PRINT_OPERAND null pointer");
4747 code
= GET_CODE (op
);
4752 case EQ
: fputs ("eq", file
); break;
4753 case NE
: fputs ("ne", file
); break;
4754 case GT
: fputs ("gt", file
); break;
4755 case GE
: fputs ("ge", file
); break;
4756 case LT
: fputs ("lt", file
); break;
4757 case LE
: fputs ("le", file
); break;
4758 case GTU
: fputs ("gtu", file
); break;
4759 case GEU
: fputs ("geu", file
); break;
4760 case LTU
: fputs ("ltu", file
); break;
4761 case LEU
: fputs ("leu", file
); break;
4763 fatal_insn ("PRINT_OPERAND, invalid insn for %%C", op
);
4766 else if (letter
== 'N')
4769 case EQ
: fputs ("ne", file
); break;
4770 case NE
: fputs ("eq", file
); break;
4771 case GT
: fputs ("le", file
); break;
4772 case GE
: fputs ("lt", file
); break;
4773 case LT
: fputs ("ge", file
); break;
4774 case LE
: fputs ("gt", file
); break;
4775 case GTU
: fputs ("leu", file
); break;
4776 case GEU
: fputs ("ltu", file
); break;
4777 case LTU
: fputs ("geu", file
); break;
4778 case LEU
: fputs ("gtu", file
); break;
4780 fatal_insn ("PRINT_OPERAND, invalid insn for %%N", op
);
4783 else if (letter
== 'F')
4786 case EQ
: fputs ("c1f", file
); break;
4787 case NE
: fputs ("c1t", file
); break;
4789 fatal_insn ("PRINT_OPERAND, invalid insn for %%F", op
);
4792 else if (letter
== 'W')
4795 case EQ
: fputs ("c1t", file
); break;
4796 case NE
: fputs ("c1f", file
); break;
4798 fatal_insn ("PRINT_OPERAND, invalid insn for %%W", op
);
4801 else if (letter
== 'h')
4803 if (GET_CODE (op
) == HIGH
)
4806 print_operand_reloc (file
, op
, mips_hi_relocs
);
4809 else if (letter
== 'R')
4810 print_operand_reloc (file
, op
, mips_lo_relocs
);
4812 else if (letter
== 'Z')
4813 print_fcc_operand (file
, op
, code
, 1, 0, 1);
4815 else if (letter
== 'Y')
4816 print_fcc_operand (file
, op
, code
, 2, 1, 0);
4818 else if (letter
== 'y')
4819 print_fcc_operand (file
, op
, code
, 2, 0, 0);
4821 else if (letter
== 'V')
4822 print_fcc_operand (file
, op
, code
, 4, 2, 0);
4824 else if (letter
== 'v')
4825 print_fcc_operand (file
, op
, code
, 4, 0, 0);
4827 else if (letter
== 'Q')
4828 print_fcc_operand (file
, op
, code
, 1, 0, 0);
4830 else if (code
== REG
|| code
== SUBREG
)
4832 register int regnum
;
4835 regnum
= REGNO (op
);
4837 regnum
= true_regnum (op
);
4839 if ((letter
== 'M' && ! WORDS_BIG_ENDIAN
)
4840 || (letter
== 'L' && WORDS_BIG_ENDIAN
)
4844 fprintf (file
, "%s", reg_names
[regnum
]);
4847 else if (code
== MEM
)
4850 output_address (plus_constant (XEXP (op
, 0), 4));
4852 output_address (XEXP (op
, 0));
4855 else if (letter
== 'x' && GET_CODE (op
) == CONST_INT
)
4856 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, 0xffff & INTVAL(op
));
4858 else if (letter
== 'X' && GET_CODE(op
) == CONST_INT
)
4859 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, INTVAL (op
));
4861 else if (letter
== 'd' && GET_CODE(op
) == CONST_INT
)
4862 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (INTVAL(op
)));
4864 else if (letter
== 'z' && op
== CONST0_RTX (GET_MODE (op
)))
4865 fputs (reg_names
[GP_REG_FIRST
], file
);
4867 else if (letter
== 'd' || letter
== 'x' || letter
== 'X')
4868 output_operand_lossage ("invalid use of %%d, %%x, or %%X");
4870 else if (letter
== 'T' || letter
== 't')
4872 int truth
= (code
== NE
) == (letter
== 'T');
4873 fputc ("zfnt"[truth
* 2 + (GET_MODE (op
) == CCmode
)], file
);
4876 else if (CONST_GP_P (op
))
4877 fputs (reg_names
[GLOBAL_POINTER_REGNUM
], file
);
4880 output_addr_const (file
, op
);
4884 /* Print symbolic operand OP, which is part of a HIGH or LO_SUM.
4885 RELOCS is the array of relocations to use. */
4888 print_operand_reloc (FILE *file
, rtx op
, const char **relocs
)
4890 enum mips_symbol_type symbol_type
;
4893 HOST_WIDE_INT offset
;
4895 if (!mips_symbolic_constant_p (op
, &symbol_type
) || relocs
[symbol_type
] == 0)
4896 fatal_insn ("PRINT_OPERAND, invalid operand for relocation", op
);
4898 /* If OP uses an UNSPEC address, we want to print the inner symbol. */
4899 mips_split_const (op
, &base
, &offset
);
4900 if (UNSPEC_ADDRESS_P (base
))
4901 op
= plus_constant (UNSPEC_ADDRESS (base
), offset
);
4903 fputs (relocs
[symbol_type
], file
);
4904 output_addr_const (file
, op
);
4905 for (p
= relocs
[symbol_type
]; *p
!= 0; p
++)
4910 /* Output address operand X to FILE. */
4913 print_operand_address (FILE *file
, rtx x
)
4915 struct mips_address_info addr
;
4917 if (mips_classify_address (&addr
, x
, word_mode
, true))
4921 print_operand (file
, addr
.offset
, 0);
4922 fprintf (file
, "(%s)", reg_names
[REGNO (addr
.reg
)]);
4925 case ADDRESS_LO_SUM
:
4926 print_operand (file
, addr
.offset
, 'R');
4927 fprintf (file
, "(%s)", reg_names
[REGNO (addr
.reg
)]);
4930 case ADDRESS_CONST_INT
:
4931 output_addr_const (file
, x
);
4932 fprintf (file
, "(%s)", reg_names
[0]);
4935 case ADDRESS_SYMBOLIC
:
4936 output_addr_const (file
, x
);
4942 /* When using assembler macros, keep track of all of small-data externs
4943 so that mips_file_end can emit the appropriate declarations for them.
4945 In most cases it would be safe (though pointless) to emit .externs
4946 for other symbols too. One exception is when an object is within
4947 the -G limit but declared by the user to be in a section other
4948 than .sbss or .sdata. */
4951 mips_output_external (FILE *file ATTRIBUTE_UNUSED
, tree decl
, const char *name
)
4953 register struct extern_list
*p
;
4955 if (!TARGET_EXPLICIT_RELOCS
&& mips_in_small_data_p (decl
))
4957 p
= (struct extern_list
*) ggc_alloc (sizeof (struct extern_list
));
4958 p
->next
= extern_head
;
4960 p
->size
= int_size_in_bytes (TREE_TYPE (decl
));
4964 if (TARGET_IRIX
&& mips_abi
== ABI_32
&& TREE_CODE (decl
) == FUNCTION_DECL
)
4966 p
= (struct extern_list
*) ggc_alloc (sizeof (struct extern_list
));
4967 p
->next
= extern_head
;
4978 irix_output_external_libcall (rtx fun
)
4980 register struct extern_list
*p
;
4982 if (mips_abi
== ABI_32
)
4984 p
= (struct extern_list
*) ggc_alloc (sizeof (struct extern_list
));
4985 p
->next
= extern_head
;
4986 p
->name
= XSTR (fun
, 0);
4993 /* Emit a new filename to a stream. If we are smuggling stabs, try to
4994 put out a MIPS ECOFF file and a stab. */
4997 mips_output_filename (FILE *stream
, const char *name
)
4999 char ltext_label_name
[100];
5001 /* If we are emitting DWARF-2, let dwarf2out handle the ".file"
5003 if (write_symbols
== DWARF2_DEBUG
)
5005 else if (mips_output_filename_first_time
)
5007 mips_output_filename_first_time
= 0;
5008 num_source_filenames
+= 1;
5009 current_function_file
= name
;
5010 ASM_OUTPUT_FILENAME (stream
, num_source_filenames
, name
);
5013 else if (write_symbols
== DBX_DEBUG
)
5015 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name
, "Ltext", 0);
5016 fputs ("\t.stabs\t", stream
);
5017 output_quoted_string (stream
, name
);
5018 fprintf (stream
, ",%d,0,0,%s\n", N_SOL
, <ext_label_name
[1]);
5021 else if (name
!= current_function_file
5022 && strcmp (name
, current_function_file
) != 0)
5024 num_source_filenames
+= 1;
5025 current_function_file
= name
;
5026 ASM_OUTPUT_FILENAME (stream
, num_source_filenames
, name
);
5030 /* Emit a linenumber. For encapsulated stabs, we need to put out a stab
5031 as well as a .loc, since it is possible that MIPS ECOFF might not be
5032 able to represent the location for inlines that come from a different
5036 mips_output_lineno (FILE *stream
, int line
)
5038 if (write_symbols
== DBX_DEBUG
)
5041 fprintf (stream
, "%sLM%d:\n\t.stabn\t%d,0,%d,%sLM%d\n",
5042 LOCAL_LABEL_PREFIX
, sym_lineno
, N_SLINE
, line
,
5043 LOCAL_LABEL_PREFIX
, sym_lineno
);
5047 fprintf (stream
, "\n\t.loc\t%d %d\n", num_source_filenames
, line
);
5051 /* Output an ASCII string, in a space-saving way. PREFIX is the string
5052 that should be written before the opening quote, such as "\t.ascii\t"
5053 for real string data or "\t# " for a comment. */
5056 mips_output_ascii (FILE *stream
, const char *string_param
, size_t len
,
5061 register const unsigned char *string
=
5062 (const unsigned char *)string_param
;
5064 fprintf (stream
, "%s\"", prefix
);
5065 for (i
= 0; i
< len
; i
++)
5067 register int c
= string
[i
];
5073 putc ('\\', stream
);
5078 case TARGET_NEWLINE
:
5079 fputs ("\\n", stream
);
5081 && (((c
= string
[i
+1]) >= '\040' && c
<= '~')
5082 || c
== TARGET_TAB
))
5083 cur_pos
= 32767; /* break right here */
5089 fputs ("\\t", stream
);
5094 fputs ("\\f", stream
);
5099 fputs ("\\b", stream
);
5104 fputs ("\\r", stream
);
5109 if (c
>= ' ' && c
< 0177)
5116 fprintf (stream
, "\\%03o", c
);
5121 if (cur_pos
> 72 && i
+1 < len
)
5124 fprintf (stream
, "\"\n%s\"", prefix
);
5127 fprintf (stream
, "\"\n");
5130 /* Implement TARGET_ASM_FILE_START. */
5133 mips_file_start (void)
5135 default_file_start ();
5139 /* Generate a special section to describe the ABI switches used to
5140 produce the resultant binary. This used to be done by the assembler
5141 setting bits in the ELF header's flags field, but we have run out of
5142 bits. GDB needs this information in order to be able to correctly
5143 debug these binaries. See the function mips_gdbarch_init() in
5144 gdb/mips-tdep.c. This is unnecessary for the IRIX 5/6 ABIs and
5145 causes unnecessary IRIX 6 ld warnings. */
5146 const char * abi_string
= NULL
;
5150 case ABI_32
: abi_string
= "abi32"; break;
5151 case ABI_N32
: abi_string
= "abiN32"; break;
5152 case ABI_64
: abi_string
= "abi64"; break;
5153 case ABI_O64
: abi_string
= "abiO64"; break;
5154 case ABI_EABI
: abi_string
= TARGET_64BIT
? "eabi64" : "eabi32"; break;
5158 /* Note - we use fprintf directly rather than called named_section()
5159 because in this way we can avoid creating an allocated section. We
5160 do not want this section to take up any space in the running
5162 fprintf (asm_out_file
, "\t.section .mdebug.%s\n", abi_string
);
5164 /* There is no ELF header flag to distinguish long32 forms of the
5165 EABI from long64 forms. Emit a special section to help tools
5167 if (mips_abi
== ABI_EABI
)
5168 fprintf (asm_out_file
, "\t.section .gcc_compiled_long%d\n",
5169 TARGET_LONG64
? 64 : 32);
5171 /* Restore the default section. */
5172 fprintf (asm_out_file
, "\t.previous\n");
5175 /* Generate the pseudo ops that System V.4 wants. */
5176 if (TARGET_ABICALLS
)
5177 /* ??? but do not want this (or want pic0) if -non-shared? */
5178 fprintf (asm_out_file
, "\t.abicalls\n");
5181 fprintf (asm_out_file
, "\t.set\tmips16\n");
5183 if (flag_verbose_asm
)
5184 fprintf (asm_out_file
, "\n%s -G value = %d, Arch = %s, ISA = %d\n",
5186 mips_section_threshold
, mips_arch_info
->name
, mips_isa
);
5189 #ifdef BSS_SECTION_ASM_OP
5190 /* Implement ASM_OUTPUT_ALIGNED_BSS. This differs from the default only
5191 in the use of sbss. */
5194 mips_output_aligned_bss (FILE *stream
, tree decl
, const char *name
,
5195 unsigned HOST_WIDE_INT size
, int align
)
5197 extern tree last_assemble_variable_decl
;
5199 if (mips_in_small_data_p (decl
))
5200 named_section (0, ".sbss", 0);
5203 ASM_OUTPUT_ALIGN (stream
, floor_log2 (align
/ BITS_PER_UNIT
));
5204 last_assemble_variable_decl
= decl
;
5205 ASM_DECLARE_OBJECT_NAME (stream
, name
, decl
);
5206 ASM_OUTPUT_SKIP (stream
, size
!= 0 ? size
: 1);
5210 /* Implement TARGET_ASM_FILE_END. When using assembler macros, emit
5211 .externs for any small-data variables that turned out to be external. */
5214 mips_file_end (void)
5217 struct extern_list
*p
;
5221 fputs ("\n", asm_out_file
);
5223 for (p
= extern_head
; p
!= 0; p
= p
->next
)
5225 name_tree
= get_identifier (p
->name
);
5227 /* Positively ensure only one .extern for any given symbol. */
5228 if (!TREE_ASM_WRITTEN (name_tree
)
5229 && TREE_SYMBOL_REFERENCED (name_tree
))
5231 TREE_ASM_WRITTEN (name_tree
) = 1;
5232 /* In IRIX 5 or IRIX 6 for the O32 ABI, we must output a
5233 `.global name .text' directive for every used but
5234 undefined function. If we don't, the linker may perform
5235 an optimization (skipping over the insns that set $gp)
5236 when it is unsafe. */
5237 if (TARGET_IRIX
&& mips_abi
== ABI_32
&& p
->size
== -1)
5239 fputs ("\t.globl ", asm_out_file
);
5240 assemble_name (asm_out_file
, p
->name
);
5241 fputs (" .text\n", asm_out_file
);
5245 fputs ("\t.extern\t", asm_out_file
);
5246 assemble_name (asm_out_file
, p
->name
);
5247 fprintf (asm_out_file
, ", %d\n", p
->size
);
5254 /* Implement ASM_OUTPUT_ALIGNED_DECL_COMMON. This is usually the same as the
5255 elfos.h version, but we also need to handle -muninit-const-in-rodata. */
5258 mips_output_aligned_decl_common (FILE *stream
, tree decl
, const char *name
,
5259 unsigned HOST_WIDE_INT size
,
5262 /* If the target wants uninitialized const declarations in
5263 .rdata then don't put them in .comm. */
5264 if (TARGET_EMBEDDED_DATA
&& TARGET_UNINIT_CONST_IN_RODATA
5265 && TREE_CODE (decl
) == VAR_DECL
&& TREE_READONLY (decl
)
5266 && (DECL_INITIAL (decl
) == 0 || DECL_INITIAL (decl
) == error_mark_node
))
5268 if (TREE_PUBLIC (decl
) && DECL_NAME (decl
))
5269 targetm
.asm_out
.globalize_label (stream
, name
);
5271 readonly_data_section ();
5272 ASM_OUTPUT_ALIGN (stream
, floor_log2 (align
/ BITS_PER_UNIT
));
5273 mips_declare_object (stream
, name
, "",
5274 ":\n\t.space\t" HOST_WIDE_INT_PRINT_UNSIGNED
"\n",
5278 mips_declare_common_object (stream
, name
, "\n\t.comm\t",
5282 /* Declare a common object of SIZE bytes using asm directive INIT_STRING.
5283 NAME is the name of the object and ALIGN is the required alignment
5284 in bytes. TAKES_ALIGNMENT_P is true if the directive takes a third
5285 alignment argument. */
5288 mips_declare_common_object (FILE *stream
, const char *name
,
5289 const char *init_string
,
5290 unsigned HOST_WIDE_INT size
,
5291 unsigned int align
, bool takes_alignment_p
)
5293 if (!takes_alignment_p
)
5295 size
+= (align
/ BITS_PER_UNIT
) - 1;
5296 size
-= size
% (align
/ BITS_PER_UNIT
);
5297 mips_declare_object (stream
, name
, init_string
,
5298 "," HOST_WIDE_INT_PRINT_UNSIGNED
"\n", size
);
5301 mips_declare_object (stream
, name
, init_string
,
5302 "," HOST_WIDE_INT_PRINT_UNSIGNED
",%u\n",
5303 size
, align
/ BITS_PER_UNIT
);
5306 /* Emit either a label, .comm, or .lcomm directive. When using assembler
5307 macros, mark the symbol as written so that mips_file_end won't emit an
5308 .extern for it. STREAM is the output file, NAME is the name of the
5309 symbol, INIT_STRING is the string that should be written before the
5310 symbol and FINAL_STRING is the string that should be written after it.
5311 FINAL_STRING is a printf() format that consumes the remaining arguments. */
5314 mips_declare_object (FILE *stream
, const char *name
, const char *init_string
,
5315 const char *final_string
, ...)
5319 fputs (init_string
, stream
);
5320 assemble_name (stream
, name
);
5321 va_start (ap
, final_string
);
5322 vfprintf (stream
, final_string
, ap
);
5325 if (!TARGET_EXPLICIT_RELOCS
)
5327 tree name_tree
= get_identifier (name
);
5328 TREE_ASM_WRITTEN (name_tree
) = 1;
5332 #ifdef ASM_OUTPUT_SIZE_DIRECTIVE
5333 extern int size_directive_output
;
5335 /* Implement ASM_DECLARE_OBJECT_NAME. This is like most of the standard ELF
5336 definitions except that it uses mips_declare_object() to emit the label. */
5339 mips_declare_object_name (FILE *stream
, const char *name
,
5340 tree decl ATTRIBUTE_UNUSED
)
5342 #ifdef ASM_OUTPUT_TYPE_DIRECTIVE
5343 ASM_OUTPUT_TYPE_DIRECTIVE (stream
, name
, "object");
5346 size_directive_output
= 0;
5347 if (!flag_inhibit_size_directive
&& DECL_SIZE (decl
))
5351 size_directive_output
= 1;
5352 size
= int_size_in_bytes (TREE_TYPE (decl
));
5353 ASM_OUTPUT_SIZE_DIRECTIVE (stream
, name
, size
);
5356 mips_declare_object (stream
, name
, "", ":\n", 0);
5359 /* Implement ASM_FINISH_DECLARE_OBJECT. This is generic ELF stuff. */
5362 mips_finish_declare_object (FILE *stream
, tree decl
, int top_level
, int at_end
)
5366 name
= XSTR (XEXP (DECL_RTL (decl
), 0), 0);
5367 if (!flag_inhibit_size_directive
5368 && DECL_SIZE (decl
) != 0
5369 && !at_end
&& top_level
5370 && DECL_INITIAL (decl
) == error_mark_node
5371 && !size_directive_output
)
5375 size_directive_output
= 1;
5376 size
= int_size_in_bytes (TREE_TYPE (decl
));
5377 ASM_OUTPUT_SIZE_DIRECTIVE (stream
, name
, size
);
5382 /* Return true if X is a small data address that can be rewritten
5386 mips_rewrite_small_data_p (rtx x
)
5388 enum mips_symbol_type symbol_type
;
5390 return (TARGET_EXPLICIT_RELOCS
5391 && mips_symbolic_constant_p (x
, &symbol_type
)
5392 && symbol_type
== SYMBOL_SMALL_DATA
);
5396 /* A for_each_rtx callback for mips_small_data_pattern_p. */
5399 mips_small_data_pattern_1 (rtx
*loc
, void *data ATTRIBUTE_UNUSED
)
5401 if (GET_CODE (*loc
) == LO_SUM
)
5404 return mips_rewrite_small_data_p (*loc
);
5407 /* Return true if OP refers to small data symbols directly, not through
5411 mips_small_data_pattern_p (rtx op
)
5413 return for_each_rtx (&op
, mips_small_data_pattern_1
, 0);
5416 /* A for_each_rtx callback, used by mips_rewrite_small_data. */
5419 mips_rewrite_small_data_1 (rtx
*loc
, void *data ATTRIBUTE_UNUSED
)
5421 if (mips_rewrite_small_data_p (*loc
))
5422 *loc
= gen_rtx_LO_SUM (Pmode
, pic_offset_table_rtx
, *loc
);
5424 if (GET_CODE (*loc
) == LO_SUM
)
5430 /* If possible, rewrite OP so that it refers to small data using
5431 explicit relocations. */
5434 mips_rewrite_small_data (rtx op
)
5436 op
= copy_insn (op
);
5437 for_each_rtx (&op
, mips_rewrite_small_data_1
, 0);
5441 /* Return true if the current function has an insn that implicitly
5445 mips_function_has_gp_insn (void)
5447 /* Don't bother rechecking if we found one last time. */
5448 if (!cfun
->machine
->has_gp_insn_p
)
5452 push_topmost_sequence ();
5453 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5455 && GET_CODE (PATTERN (insn
)) != USE
5456 && GET_CODE (PATTERN (insn
)) != CLOBBER
5457 && (get_attr_got (insn
) != GOT_UNSET
5458 || small_data_pattern (PATTERN (insn
), VOIDmode
)))
5460 pop_topmost_sequence ();
5462 cfun
->machine
->has_gp_insn_p
= (insn
!= 0);
5464 return cfun
->machine
->has_gp_insn_p
;
5468 /* Return the register that should be used as the global pointer
5469 within this function. Return 0 if the function doesn't need
5470 a global pointer. */
5473 mips_global_pointer (void)
5477 /* $gp is always available in non-abicalls code. */
5478 if (!TARGET_ABICALLS
)
5479 return GLOBAL_POINTER_REGNUM
;
5481 /* We must always provide $gp when it is used implicitly. */
5482 if (!TARGET_EXPLICIT_RELOCS
)
5483 return GLOBAL_POINTER_REGNUM
;
5485 /* FUNCTION_PROFILER includes a jal macro, so we need to give it
5487 if (current_function_profile
)
5488 return GLOBAL_POINTER_REGNUM
;
5490 /* If the function has a nonlocal goto, $gp must hold the correct
5491 global pointer for the target function. */
5492 if (current_function_has_nonlocal_goto
)
5493 return GLOBAL_POINTER_REGNUM
;
5495 /* If the gp is never referenced, there's no need to initialize it.
5496 Note that reload can sometimes introduce constant pool references
5497 into a function that otherwise didn't need them. For example,
5498 suppose we have an instruction like:
5500 (set (reg:DF R1) (float:DF (reg:SI R2)))
5502 If R2 turns out to be constant such as 1, the instruction may have a
5503 REG_EQUAL note saying that R1 == 1.0. Reload then has the option of
5504 using this constant if R2 doesn't get allocated to a register.
5506 In cases like these, reload will have added the constant to the pool
5507 but no instruction will yet refer to it. */
5508 if (!regs_ever_live
[GLOBAL_POINTER_REGNUM
]
5509 && !current_function_uses_const_pool
5510 && !mips_function_has_gp_insn ())
5513 /* We need a global pointer, but perhaps we can use a call-clobbered
5514 register instead of $gp. */
5515 if (TARGET_NEWABI
&& current_function_is_leaf
)
5516 for (regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
5517 if (!regs_ever_live
[regno
]
5518 && call_used_regs
[regno
]
5519 && !fixed_regs
[regno
]
5520 && regno
!= PIC_FUNCTION_ADDR_REGNUM
)
5523 return GLOBAL_POINTER_REGNUM
;
5527 /* Return true if the current function must save REGNO. */
5530 mips_save_reg_p (unsigned int regno
)
5532 /* We only need to save $gp for NewABI PIC. */
5533 if (regno
== GLOBAL_POINTER_REGNUM
)
5534 return (TARGET_ABICALLS
&& TARGET_NEWABI
5535 && cfun
->machine
->global_pointer
== regno
);
5537 /* Check call-saved registers. */
5538 if (regs_ever_live
[regno
] && !call_used_regs
[regno
])
5541 /* We need to save the old frame pointer before setting up a new one. */
5542 if (regno
== HARD_FRAME_POINTER_REGNUM
&& frame_pointer_needed
)
5545 /* We need to save the incoming return address if it is ever clobbered
5546 within the function. */
5547 if (regno
== GP_REG_FIRST
+ 31 && regs_ever_live
[regno
])
5554 return_type
= DECL_RESULT (current_function_decl
);
5556 /* $18 is a special case in mips16 code. It may be used to call
5557 a function which returns a floating point value, but it is
5558 marked in call_used_regs. */
5559 if (regno
== GP_REG_FIRST
+ 18 && regs_ever_live
[regno
])
5562 /* $31 is also a special case. It will be used to copy a return
5563 value into the floating point registers if the return value is
5565 if (regno
== GP_REG_FIRST
+ 31
5566 && mips16_hard_float
5567 && !aggregate_value_p (return_type
, current_function_decl
)
5568 && GET_MODE_CLASS (DECL_MODE (return_type
)) == MODE_FLOAT
5569 && GET_MODE_SIZE (DECL_MODE (return_type
)) <= UNITS_PER_FPVALUE
)
5577 /* Return the bytes needed to compute the frame pointer from the current
5578 stack pointer. SIZE is the size (in bytes) of the local variables.
5580 Mips stack frames look like:
5582 Before call After call
5583 +-----------------------+ +-----------------------+
5586 | caller's temps. | | caller's temps. |
5588 +-----------------------+ +-----------------------+
5590 | arguments on stack. | | arguments on stack. |
5592 +-----------------------+ +-----------------------+
5593 | 4 words to save | | 4 words to save |
5594 | arguments passed | | arguments passed |
5595 | in registers, even | | in registers, even |
5596 SP->| if not passed. | VFP->| if not passed. |
5597 +-----------------------+ +-----------------------+
5599 | fp register save |
5601 +-----------------------+
5603 | gp register save |
5605 +-----------------------+
5609 +-----------------------+
5611 | alloca allocations |
5613 +-----------------------+
5615 | GP save for V.4 abi |
5617 +-----------------------+
5619 | arguments on stack |
5621 +-----------------------+
5623 | arguments passed |
5624 | in registers, even |
5625 low SP->| if not passed. |
5626 memory +-----------------------+
5631 compute_frame_size (HOST_WIDE_INT size
)
5634 HOST_WIDE_INT total_size
; /* # bytes that the entire frame takes up */
5635 HOST_WIDE_INT var_size
; /* # bytes that variables take up */
5636 HOST_WIDE_INT args_size
; /* # bytes that outgoing arguments take up */
5637 HOST_WIDE_INT cprestore_size
; /* # bytes that the cprestore slot takes up */
5638 HOST_WIDE_INT gp_reg_rounded
; /* # bytes needed to store gp after rounding */
5639 HOST_WIDE_INT gp_reg_size
; /* # bytes needed to store gp regs */
5640 HOST_WIDE_INT fp_reg_size
; /* # bytes needed to store fp regs */
5641 unsigned int mask
; /* mask of saved gp registers */
5642 unsigned int fmask
; /* mask of saved fp registers */
5644 cfun
->machine
->global_pointer
= mips_global_pointer ();
5650 var_size
= MIPS_STACK_ALIGN (size
);
5651 args_size
= current_function_outgoing_args_size
;
5652 cprestore_size
= MIPS_STACK_ALIGN (STARTING_FRAME_OFFSET
) - args_size
;
5654 /* The space set aside by STARTING_FRAME_OFFSET isn't needed in leaf
5655 functions. If the function has local variables, we're committed
5656 to allocating it anyway. Otherwise reclaim it here. */
5657 if (var_size
== 0 && current_function_is_leaf
)
5658 cprestore_size
= args_size
= 0;
5660 /* The MIPS 3.0 linker does not like functions that dynamically
5661 allocate the stack and have 0 for STACK_DYNAMIC_OFFSET, since it
5662 looks like we are trying to create a second frame pointer to the
5663 function, so allocate some stack space to make it happy. */
5665 if (args_size
== 0 && current_function_calls_alloca
)
5666 args_size
= 4 * UNITS_PER_WORD
;
5668 total_size
= var_size
+ args_size
+ cprestore_size
;
5670 /* Calculate space needed for gp registers. */
5671 for (regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
5672 if (mips_save_reg_p (regno
))
5674 gp_reg_size
+= GET_MODE_SIZE (gpr_mode
);
5675 mask
|= 1 << (regno
- GP_REG_FIRST
);
5678 /* We need to restore these for the handler. */
5679 if (current_function_calls_eh_return
)
5684 regno
= EH_RETURN_DATA_REGNO (i
);
5685 if (regno
== INVALID_REGNUM
)
5687 gp_reg_size
+= GET_MODE_SIZE (gpr_mode
);
5688 mask
|= 1 << (regno
- GP_REG_FIRST
);
5692 /* This loop must iterate over the same space as its companion in
5693 save_restore_insns. */
5694 for (regno
= (FP_REG_LAST
- FP_INC
+ 1);
5695 regno
>= FP_REG_FIRST
;
5698 if (mips_save_reg_p (regno
))
5700 fp_reg_size
+= FP_INC
* UNITS_PER_FPREG
;
5701 fmask
|= ((1 << FP_INC
) - 1) << (regno
- FP_REG_FIRST
);
5705 gp_reg_rounded
= MIPS_STACK_ALIGN (gp_reg_size
);
5706 total_size
+= gp_reg_rounded
+ MIPS_STACK_ALIGN (fp_reg_size
);
5708 /* Add in space reserved on the stack by the callee for storing arguments
5709 passed in registers. */
5711 total_size
+= MIPS_STACK_ALIGN (current_function_pretend_args_size
);
5713 /* Save other computed information. */
5714 cfun
->machine
->frame
.total_size
= total_size
;
5715 cfun
->machine
->frame
.var_size
= var_size
;
5716 cfun
->machine
->frame
.args_size
= args_size
;
5717 cfun
->machine
->frame
.cprestore_size
= cprestore_size
;
5718 cfun
->machine
->frame
.gp_reg_size
= gp_reg_size
;
5719 cfun
->machine
->frame
.fp_reg_size
= fp_reg_size
;
5720 cfun
->machine
->frame
.mask
= mask
;
5721 cfun
->machine
->frame
.fmask
= fmask
;
5722 cfun
->machine
->frame
.initialized
= reload_completed
;
5723 cfun
->machine
->frame
.num_gp
= gp_reg_size
/ UNITS_PER_WORD
;
5724 cfun
->machine
->frame
.num_fp
= fp_reg_size
/ (FP_INC
* UNITS_PER_FPREG
);
5728 HOST_WIDE_INT offset
;
5730 offset
= (args_size
+ cprestore_size
+ var_size
5731 + gp_reg_size
- GET_MODE_SIZE (gpr_mode
));
5732 cfun
->machine
->frame
.gp_sp_offset
= offset
;
5733 cfun
->machine
->frame
.gp_save_offset
= offset
- total_size
;
5737 cfun
->machine
->frame
.gp_sp_offset
= 0;
5738 cfun
->machine
->frame
.gp_save_offset
= 0;
5743 HOST_WIDE_INT offset
;
5745 offset
= (args_size
+ cprestore_size
+ var_size
5746 + gp_reg_rounded
+ fp_reg_size
5747 - FP_INC
* UNITS_PER_FPREG
);
5748 cfun
->machine
->frame
.fp_sp_offset
= offset
;
5749 cfun
->machine
->frame
.fp_save_offset
= offset
- total_size
;
5753 cfun
->machine
->frame
.fp_sp_offset
= 0;
5754 cfun
->machine
->frame
.fp_save_offset
= 0;
5757 /* Ok, we're done. */
5761 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame
5762 pointer or argument pointer. TO is either the stack pointer or
5763 hard frame pointer. */
5766 mips_initial_elimination_offset (int from
, int to
)
5768 HOST_WIDE_INT offset
;
5770 compute_frame_size (get_frame_size ());
5772 /* Set OFFSET to the offset from the stack pointer. */
5775 case FRAME_POINTER_REGNUM
:
5779 case ARG_POINTER_REGNUM
:
5780 offset
= cfun
->machine
->frame
.total_size
;
5782 offset
-= current_function_pretend_args_size
;
5789 if (TARGET_MIPS16
&& to
== HARD_FRAME_POINTER_REGNUM
)
5790 offset
-= cfun
->machine
->frame
.args_size
;
5795 /* Implement RETURN_ADDR_RTX. Note, we do not support moving
5796 back to a previous frame. */
5798 mips_return_addr (int count
, rtx frame ATTRIBUTE_UNUSED
)
5803 return get_hard_reg_initial_val (Pmode
, GP_REG_FIRST
+ 31);
5806 /* Use FN to save or restore register REGNO. MODE is the register's
5807 mode and OFFSET is the offset of its save slot from the current
5811 mips_save_restore_reg (enum machine_mode mode
, int regno
,
5812 HOST_WIDE_INT offset
, mips_save_restore_fn fn
)
5816 mem
= gen_rtx_MEM (mode
, plus_constant (stack_pointer_rtx
, offset
));
5818 fn (gen_rtx_REG (mode
, regno
), mem
);
5822 /* Call FN for each register that is saved by the current function.
5823 SP_OFFSET is the offset of the current stack pointer from the start
5827 mips_for_each_saved_reg (HOST_WIDE_INT sp_offset
, mips_save_restore_fn fn
)
5829 #define BITSET_P(VALUE, BIT) (((VALUE) & (1L << (BIT))) != 0)
5831 enum machine_mode fpr_mode
;
5832 HOST_WIDE_INT offset
;
5835 /* Save registers starting from high to low. The debuggers prefer at least
5836 the return register be stored at func+4, and also it allows us not to
5837 need a nop in the epilog if at least one register is reloaded in
5838 addition to return address. */
5839 offset
= cfun
->machine
->frame
.gp_sp_offset
- sp_offset
;
5840 for (regno
= GP_REG_LAST
; regno
>= GP_REG_FIRST
; regno
--)
5841 if (BITSET_P (cfun
->machine
->frame
.mask
, regno
- GP_REG_FIRST
))
5843 mips_save_restore_reg (gpr_mode
, regno
, offset
, fn
);
5844 offset
-= GET_MODE_SIZE (gpr_mode
);
5847 /* This loop must iterate over the same space as its companion in
5848 compute_frame_size. */
5849 offset
= cfun
->machine
->frame
.fp_sp_offset
- sp_offset
;
5850 fpr_mode
= (TARGET_SINGLE_FLOAT
? SFmode
: DFmode
);
5851 for (regno
= (FP_REG_LAST
- FP_INC
+ 1);
5852 regno
>= FP_REG_FIRST
;
5854 if (BITSET_P (cfun
->machine
->frame
.fmask
, regno
- FP_REG_FIRST
))
5856 mips_save_restore_reg (fpr_mode
, regno
, offset
, fn
);
5857 offset
-= GET_MODE_SIZE (fpr_mode
);
5862 /* If we're generating n32 or n64 abicalls, and the current function
5863 does not use $28 as its global pointer, emit a cplocal directive.
5864 Use pic_offset_table_rtx as the argument to the directive. */
5867 mips_output_cplocal (void)
5869 if (!TARGET_EXPLICIT_RELOCS
5870 && cfun
->machine
->global_pointer
> 0
5871 && cfun
->machine
->global_pointer
!= GLOBAL_POINTER_REGNUM
)
5872 output_asm_insn (".cplocal %+", 0);
5875 /* If we're generating n32 or n64 abicalls, emit instructions
5876 to set up the global pointer. */
5879 mips_emit_loadgp (void)
5881 if (TARGET_ABICALLS
&& TARGET_NEWABI
&& cfun
->machine
->global_pointer
> 0)
5883 rtx addr
, offset
, incoming_address
;
5885 addr
= XEXP (DECL_RTL (current_function_decl
), 0);
5886 offset
= mips_unspec_address (addr
, SYMBOL_GOTOFF_LOADGP
);
5887 incoming_address
= gen_rtx_REG (Pmode
, PIC_FUNCTION_ADDR_REGNUM
);
5888 emit_insn (gen_loadgp (offset
, incoming_address
));
5889 if (!TARGET_EXPLICIT_RELOCS
)
5890 emit_insn (gen_loadgp_blockage ());
5894 /* Set up the stack and frame (if desired) for the function. */
5897 mips_output_function_prologue (FILE *file
, HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
5900 HOST_WIDE_INT tsize
= cfun
->machine
->frame
.total_size
;
5902 #ifdef SDB_DEBUGGING_INFO
5903 if (debug_info_level
!= DINFO_LEVEL_TERSE
&& write_symbols
== SDB_DEBUG
)
5904 ASM_OUTPUT_SOURCE_LINE (file
, DECL_SOURCE_LINE (current_function_decl
), 0);
5907 /* In mips16 mode, we may need to generate a 32 bit to handle
5908 floating point arguments. The linker will arrange for any 32 bit
5909 functions to call this stub, which will then jump to the 16 bit
5911 if (TARGET_MIPS16
&& !TARGET_SOFT_FLOAT
5912 && current_function_args_info
.fp_code
!= 0)
5913 build_mips16_function_stub (file
);
5915 if (!FUNCTION_NAME_ALREADY_DECLARED
)
5917 /* Get the function name the same way that toplev.c does before calling
5918 assemble_start_function. This is needed so that the name used here
5919 exactly matches the name used in ASM_DECLARE_FUNCTION_NAME. */
5920 fnname
= XSTR (XEXP (DECL_RTL (current_function_decl
), 0), 0);
5922 if (!flag_inhibit_size_directive
)
5924 fputs ("\t.ent\t", file
);
5925 assemble_name (file
, fnname
);
5929 assemble_name (file
, fnname
);
5930 fputs (":\n", file
);
5933 /* Stop mips_file_end from treating this function as external. */
5934 if (TARGET_IRIX
&& mips_abi
== ABI_32
)
5935 TREE_ASM_WRITTEN (DECL_NAME (cfun
->decl
)) = 1;
5937 if (!flag_inhibit_size_directive
)
5939 /* .frame FRAMEREG, FRAMESIZE, RETREG */
5941 "\t.frame\t%s," HOST_WIDE_INT_PRINT_DEC
",%s\t\t"
5942 "# vars= " HOST_WIDE_INT_PRINT_DEC
", regs= %d/%d"
5943 ", args= " HOST_WIDE_INT_PRINT_DEC
5944 ", gp= " HOST_WIDE_INT_PRINT_DEC
"\n",
5945 (reg_names
[(frame_pointer_needed
)
5946 ? HARD_FRAME_POINTER_REGNUM
: STACK_POINTER_REGNUM
]),
5947 ((frame_pointer_needed
&& TARGET_MIPS16
)
5948 ? tsize
- cfun
->machine
->frame
.args_size
5950 reg_names
[GP_REG_FIRST
+ 31],
5951 cfun
->machine
->frame
.var_size
,
5952 cfun
->machine
->frame
.num_gp
,
5953 cfun
->machine
->frame
.num_fp
,
5954 cfun
->machine
->frame
.args_size
,
5955 cfun
->machine
->frame
.cprestore_size
);
5957 /* .mask MASK, GPOFFSET; .fmask FPOFFSET */
5958 fprintf (file
, "\t.mask\t0x%08x," HOST_WIDE_INT_PRINT_DEC
"\n",
5959 cfun
->machine
->frame
.mask
,
5960 cfun
->machine
->frame
.gp_save_offset
);
5961 fprintf (file
, "\t.fmask\t0x%08x," HOST_WIDE_INT_PRINT_DEC
"\n",
5962 cfun
->machine
->frame
.fmask
,
5963 cfun
->machine
->frame
.fp_save_offset
);
5966 OLD_SP == *FRAMEREG + FRAMESIZE => can find old_sp from nominated FP reg.
5967 HIGHEST_GP_SAVED == *FRAMEREG + FRAMESIZE + GPOFFSET => can find saved regs. */
5970 if (TARGET_ABICALLS
&& !TARGET_NEWABI
&& cfun
->machine
->global_pointer
> 0)
5972 /* Handle the initialization of $gp for SVR4 PIC. */
5973 if (!cfun
->machine
->all_noreorder_p
)
5974 output_asm_insn ("%(.cpload\t%^%)", 0);
5976 output_asm_insn ("%(.cpload\t%^\n\t%<", 0);
5978 else if (cfun
->machine
->all_noreorder_p
)
5979 output_asm_insn ("%(%<", 0);
5981 /* Tell the assembler which register we're using as the global
5982 pointer. This is needed for thunks, since they can use either
5983 explicit relocs or assembler macros. */
5984 mips_output_cplocal ();
5987 /* Make the last instruction frame related and note that it performs
5988 the operation described by FRAME_PATTERN. */
5991 mips_set_frame_expr (rtx frame_pattern
)
5995 insn
= get_last_insn ();
5996 RTX_FRAME_RELATED_P (insn
) = 1;
5997 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
6003 /* Return a frame-related rtx that stores REG at MEM.
6004 REG must be a single register. */
6007 mips_frame_set (rtx mem
, rtx reg
)
6009 rtx set
= gen_rtx_SET (VOIDmode
, mem
, reg
);
6010 RTX_FRAME_RELATED_P (set
) = 1;
6015 /* Save register REG to MEM. Make the instruction frame-related. */
6018 mips_save_reg (rtx reg
, rtx mem
)
6020 if (GET_MODE (reg
) == DFmode
&& !TARGET_FLOAT64
)
6024 if (mips_split_64bit_move_p (mem
, reg
))
6025 mips_split_64bit_move (mem
, reg
);
6027 emit_move_insn (mem
, reg
);
6029 x1
= mips_frame_set (mips_subword (mem
, 0), mips_subword (reg
, 0));
6030 x2
= mips_frame_set (mips_subword (mem
, 1), mips_subword (reg
, 1));
6031 mips_set_frame_expr (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, x1
, x2
)));
6036 && REGNO (reg
) != GP_REG_FIRST
+ 31
6037 && !M16_REG_P (REGNO (reg
)))
6039 /* Save a non-mips16 register by moving it through a temporary.
6040 We don't need to do this for $31 since there's a special
6041 instruction for it. */
6042 emit_move_insn (MIPS_PROLOGUE_TEMP (GET_MODE (reg
)), reg
);
6043 emit_move_insn (mem
, MIPS_PROLOGUE_TEMP (GET_MODE (reg
)));
6046 emit_move_insn (mem
, reg
);
6048 mips_set_frame_expr (mips_frame_set (mem
, reg
));
6053 /* Expand the prologue into a bunch of separate insns. */
6056 mips_expand_prologue (void)
6060 if (cfun
->machine
->global_pointer
> 0)
6061 REGNO (pic_offset_table_rtx
) = cfun
->machine
->global_pointer
;
6063 size
= compute_frame_size (get_frame_size ());
6065 /* Save the registers. Allocate up to MIPS_MAX_FIRST_STACK_STEP
6066 bytes beforehand; this is enough to cover the register save area
6067 without going out of range. */
6068 if ((cfun
->machine
->frame
.mask
| cfun
->machine
->frame
.fmask
) != 0)
6070 HOST_WIDE_INT step1
;
6072 step1
= MIN (size
, MIPS_MAX_FIRST_STACK_STEP
);
6073 RTX_FRAME_RELATED_P (emit_insn (gen_add3_insn (stack_pointer_rtx
,
6075 GEN_INT (-step1
)))) = 1;
6077 mips_for_each_saved_reg (size
, mips_save_reg
);
6080 /* Allocate the rest of the frame. */
6083 if (SMALL_OPERAND (-size
))
6084 RTX_FRAME_RELATED_P (emit_insn (gen_add3_insn (stack_pointer_rtx
,
6086 GEN_INT (-size
)))) = 1;
6089 emit_move_insn (MIPS_PROLOGUE_TEMP (Pmode
), GEN_INT (size
));
6092 /* There are no instructions to add or subtract registers
6093 from the stack pointer, so use the frame pointer as a
6094 temporary. We should always be using a frame pointer
6095 in this case anyway. */
6096 if (!frame_pointer_needed
)
6099 emit_move_insn (hard_frame_pointer_rtx
, stack_pointer_rtx
);
6100 emit_insn (gen_sub3_insn (hard_frame_pointer_rtx
,
6101 hard_frame_pointer_rtx
,
6102 MIPS_PROLOGUE_TEMP (Pmode
)));
6103 emit_move_insn (stack_pointer_rtx
, hard_frame_pointer_rtx
);
6106 emit_insn (gen_sub3_insn (stack_pointer_rtx
,
6108 MIPS_PROLOGUE_TEMP (Pmode
)));
6110 /* Describe the combined effect of the previous instructions. */
6112 (gen_rtx_SET (VOIDmode
, stack_pointer_rtx
,
6113 plus_constant (stack_pointer_rtx
, -size
)));
6117 /* Set up the frame pointer, if we're using one. In mips16 code,
6118 we point the frame pointer ahead of the outgoing argument area.
6119 This should allow more variables & incoming arguments to be
6120 accessed with unextended instructions. */
6121 if (frame_pointer_needed
)
6123 if (TARGET_MIPS16
&& cfun
->machine
->frame
.args_size
!= 0)
6125 rtx offset
= GEN_INT (cfun
->machine
->frame
.args_size
);
6127 (emit_insn (gen_add3_insn (hard_frame_pointer_rtx
,
6132 RTX_FRAME_RELATED_P (emit_move_insn (hard_frame_pointer_rtx
,
6133 stack_pointer_rtx
)) = 1;
6136 /* If generating o32/o64 abicalls, save $gp on the stack. */
6137 if (TARGET_ABICALLS
&& !TARGET_NEWABI
&& !current_function_is_leaf
)
6138 emit_insn (gen_cprestore (GEN_INT (current_function_outgoing_args_size
)));
6140 mips_emit_loadgp ();
6142 /* If we are profiling, make sure no instructions are scheduled before
6143 the call to mcount. */
6145 if (current_function_profile
)
6146 emit_insn (gen_blockage ());
6149 /* Do any necessary cleanup after a function to restore stack, frame,
6152 #define RA_MASK BITMASK_HIGH /* 1 << 31 */
6155 mips_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED
,
6156 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
6158 /* Reinstate the normal $gp. */
6159 REGNO (pic_offset_table_rtx
) = GLOBAL_POINTER_REGNUM
;
6160 mips_output_cplocal ();
6162 if (cfun
->machine
->all_noreorder_p
)
6164 /* Avoid using %>%) since it adds excess whitespace. */
6165 output_asm_insn (".set\tmacro", 0);
6166 output_asm_insn (".set\treorder", 0);
6167 set_noreorder
= set_nomacro
= 0;
6170 if (!FUNCTION_NAME_ALREADY_DECLARED
&& !flag_inhibit_size_directive
)
6174 /* Get the function name the same way that toplev.c does before calling
6175 assemble_start_function. This is needed so that the name used here
6176 exactly matches the name used in ASM_DECLARE_FUNCTION_NAME. */
6177 fnname
= XSTR (XEXP (DECL_RTL (current_function_decl
), 0), 0);
6178 fputs ("\t.end\t", file
);
6179 assemble_name (file
, fnname
);
6184 /* Emit instructions to restore register REG from slot MEM. */
6187 mips_restore_reg (rtx reg
, rtx mem
)
6189 /* There's no mips16 instruction to load $31 directly. Load into
6190 $7 instead and adjust the return insn appropriately. */
6191 if (TARGET_MIPS16
&& REGNO (reg
) == GP_REG_FIRST
+ 31)
6192 reg
= gen_rtx_REG (GET_MODE (reg
), 7);
6194 if (TARGET_MIPS16
&& !M16_REG_P (REGNO (reg
)))
6196 /* Can't restore directly; move through a temporary. */
6197 emit_move_insn (MIPS_EPILOGUE_TEMP (GET_MODE (reg
)), mem
);
6198 emit_move_insn (reg
, MIPS_EPILOGUE_TEMP (GET_MODE (reg
)));
6201 emit_move_insn (reg
, mem
);
6205 /* Expand the epilogue into a bunch of separate insns. SIBCALL_P is true
6206 if this epilogue precedes a sibling call, false if it is for a normal
6207 "epilogue" pattern. */
6210 mips_expand_epilogue (int sibcall_p
)
6212 HOST_WIDE_INT step1
, step2
;
6215 if (!sibcall_p
&& mips_can_use_return_insn ())
6217 emit_jump_insn (gen_return ());
6221 /* Split the frame into two. STEP1 is the amount of stack we should
6222 deallocate before restoring the registers. STEP2 is the amount we
6223 should deallocate afterwards.
6225 Start off by assuming that no registers need to be restored. */
6226 step1
= cfun
->machine
->frame
.total_size
;
6229 /* Work out which register holds the frame address. Account for the
6230 frame pointer offset used by mips16 code. */
6231 if (!frame_pointer_needed
)
6232 base
= stack_pointer_rtx
;
6235 base
= hard_frame_pointer_rtx
;
6237 step1
-= cfun
->machine
->frame
.args_size
;
6240 /* If we need to restore registers, deallocate as much stack as
6241 possible in the second step without going out of range. */
6242 if ((cfun
->machine
->frame
.mask
| cfun
->machine
->frame
.fmask
) != 0)
6244 step2
= MIN (step1
, MIPS_MAX_FIRST_STACK_STEP
);
6248 /* Set TARGET to BASE + STEP1. */
6254 /* Get an rtx for STEP1 that we can add to BASE. */
6255 adjust
= GEN_INT (step1
);
6256 if (!SMALL_OPERAND (step1
))
6258 emit_move_insn (MIPS_EPILOGUE_TEMP (Pmode
), adjust
);
6259 adjust
= MIPS_EPILOGUE_TEMP (Pmode
);
6262 /* Normal mode code can copy the result straight into $sp. */
6264 target
= stack_pointer_rtx
;
6266 emit_insn (gen_add3_insn (target
, base
, adjust
));
6269 /* Copy TARGET into the stack pointer. */
6270 if (target
!= stack_pointer_rtx
)
6271 emit_move_insn (stack_pointer_rtx
, target
);
6273 /* If we're using addressing macros for n32/n64 abicalls, $gp is
6274 implicitly used by all SYMBOL_REFs. We must emit a blockage
6275 insn before restoring it. */
6276 if (TARGET_ABICALLS
&& TARGET_NEWABI
&& !TARGET_EXPLICIT_RELOCS
)
6277 emit_insn (gen_blockage ());
6279 /* Restore the registers. */
6280 mips_for_each_saved_reg (cfun
->machine
->frame
.total_size
- step2
,
6283 /* Deallocate the final bit of the frame. */
6285 emit_insn (gen_add3_insn (stack_pointer_rtx
,
6289 /* Add in the __builtin_eh_return stack adjustment. We need to
6290 use a temporary in mips16 code. */
6291 if (current_function_calls_eh_return
)
6295 emit_move_insn (MIPS_EPILOGUE_TEMP (Pmode
), stack_pointer_rtx
);
6296 emit_insn (gen_add3_insn (MIPS_EPILOGUE_TEMP (Pmode
),
6297 MIPS_EPILOGUE_TEMP (Pmode
),
6298 EH_RETURN_STACKADJ_RTX
));
6299 emit_move_insn (stack_pointer_rtx
, MIPS_EPILOGUE_TEMP (Pmode
));
6302 emit_insn (gen_add3_insn (stack_pointer_rtx
,
6304 EH_RETURN_STACKADJ_RTX
));
6309 /* The mips16 loads the return address into $7, not $31. */
6310 if (TARGET_MIPS16
&& (cfun
->machine
->frame
.mask
& RA_MASK
) != 0)
6311 emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode
,
6312 GP_REG_FIRST
+ 7)));
6314 emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode
,
6315 GP_REG_FIRST
+ 31)));
6319 /* Return nonzero if this function is known to have a null epilogue.
6320 This allows the optimizer to omit jumps to jumps if no stack
6324 mips_can_use_return_insn (void)
6328 if (! reload_completed
)
6331 if (regs_ever_live
[31] || current_function_profile
)
6334 return_type
= DECL_RESULT (current_function_decl
);
6336 /* In mips16 mode, a function which returns a floating point value
6337 needs to arrange to copy the return value into the floating point
6340 && mips16_hard_float
6341 && ! aggregate_value_p (return_type
, current_function_decl
)
6342 && GET_MODE_CLASS (DECL_MODE (return_type
)) == MODE_FLOAT
6343 && GET_MODE_SIZE (DECL_MODE (return_type
)) <= UNITS_PER_FPVALUE
)
6346 if (cfun
->machine
->frame
.initialized
)
6347 return cfun
->machine
->frame
.total_size
== 0;
6349 return compute_frame_size (get_frame_size ()) == 0;
6352 /* Implement TARGET_ASM_OUTPUT_MI_THUNK. Generate rtl rather than asm text
6353 in order to avoid duplicating too much logic from elsewhere. */
6356 mips_output_mi_thunk (FILE *file
, tree thunk_fndecl ATTRIBUTE_UNUSED
,
6357 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
6360 rtx
this, temp1
, temp2
, insn
, fnaddr
;
6362 /* Pretend to be a post-reload pass while generating rtl. */
6364 reload_completed
= 1;
6365 reset_block_changes ();
6367 /* Pick a global pointer for -mabicalls. Use $15 rather than $28
6368 for TARGET_NEWABI since the latter is a call-saved register. */
6369 if (TARGET_ABICALLS
)
6370 cfun
->machine
->global_pointer
6371 = REGNO (pic_offset_table_rtx
)
6372 = TARGET_NEWABI
? 15 : GLOBAL_POINTER_REGNUM
;
6374 /* Set up the global pointer for n32 or n64 abicalls. */
6375 mips_emit_loadgp ();
6377 /* We need two temporary registers in some cases. */
6378 temp1
= gen_rtx_REG (Pmode
, 2);
6379 temp2
= gen_rtx_REG (Pmode
, 3);
6381 /* Find out which register contains the "this" pointer. */
6382 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
6383 this = gen_rtx_REG (Pmode
, GP_ARG_FIRST
+ 1);
6385 this = gen_rtx_REG (Pmode
, GP_ARG_FIRST
);
6387 /* Add DELTA to THIS. */
6390 rtx offset
= GEN_INT (delta
);
6391 if (!SMALL_OPERAND (delta
))
6393 emit_move_insn (temp1
, offset
);
6396 emit_insn (gen_add3_insn (this, this, offset
));
6399 /* If needed, add *(*THIS + VCALL_OFFSET) to THIS. */
6400 if (vcall_offset
!= 0)
6404 /* Set TEMP1 to *THIS. */
6405 emit_move_insn (temp1
, gen_rtx_MEM (Pmode
, this));
6407 /* Set ADDR to a legitimate address for *THIS + VCALL_OFFSET. */
6408 addr
= mips_add_offset (temp2
, temp1
, vcall_offset
);
6410 /* Load the offset and add it to THIS. */
6411 emit_move_insn (temp1
, gen_rtx_MEM (Pmode
, addr
));
6412 emit_insn (gen_add3_insn (this, this, temp1
));
6415 /* Jump to the target function. Use a sibcall if direct jumps are
6416 allowed, otherwise load the address into a register first. */
6417 fnaddr
= XEXP (DECL_RTL (function
), 0);
6418 if (TARGET_MIPS16
|| TARGET_ABICALLS
|| TARGET_LONG_CALLS
)
6420 /* This is messy. gas treats "la $25,foo" as part of a call
6421 sequence and may allow a global "foo" to be lazily bound.
6422 The general move patterns therefore reject this combination.
6424 In this context, lazy binding would actually be OK for o32 and o64,
6425 but it's still wrong for n32 and n64; see mips_load_call_address.
6426 We must therefore load the address via a temporary register if
6427 mips_dangerous_for_la25_p.
6429 If we jump to the temporary register rather than $25, the assembler
6430 can use the move insn to fill the jump's delay slot. */
6431 if (TARGET_ABICALLS
&& !mips_dangerous_for_la25_p (fnaddr
))
6432 temp1
= gen_rtx_REG (Pmode
, PIC_FUNCTION_ADDR_REGNUM
);
6433 mips_load_call_address (temp1
, fnaddr
, true);
6435 if (TARGET_ABICALLS
&& REGNO (temp1
) != PIC_FUNCTION_ADDR_REGNUM
)
6436 emit_move_insn (gen_rtx_REG (Pmode
, PIC_FUNCTION_ADDR_REGNUM
), temp1
);
6437 emit_jump_insn (gen_indirect_jump (temp1
));
6441 insn
= emit_call_insn (gen_sibcall_internal (fnaddr
, const0_rtx
));
6442 SIBLING_CALL_P (insn
) = 1;
6445 /* Run just enough of rest_of_compilation. This sequence was
6446 "borrowed" from alpha.c. */
6447 insn
= get_insns ();
6448 insn_locators_initialize ();
6449 split_all_insns_noflow ();
6451 mips16_lay_out_constants ();
6452 shorten_branches (insn
);
6453 final_start_function (insn
, file
, 1);
6454 final (insn
, file
, 1, 0);
6455 final_end_function ();
6457 /* Clean up the vars set above. Note that final_end_function resets
6458 the global pointer for us. */
6459 reload_completed
= 0;
6463 /* Returns nonzero if X contains a SYMBOL_REF. */
6466 symbolic_expression_p (rtx x
)
6468 if (GET_CODE (x
) == SYMBOL_REF
)
6471 if (GET_CODE (x
) == CONST
)
6472 return symbolic_expression_p (XEXP (x
, 0));
6475 return symbolic_expression_p (XEXP (x
, 0));
6477 if (ARITHMETIC_P (x
))
6478 return (symbolic_expression_p (XEXP (x
, 0))
6479 || symbolic_expression_p (XEXP (x
, 1)));
6484 /* Choose the section to use for the constant rtx expression X that has
6488 mips_select_rtx_section (enum machine_mode mode
, rtx x
,
6489 unsigned HOST_WIDE_INT align
)
6493 /* In mips16 mode, the constant table always goes in the same section
6494 as the function, so that constants can be loaded using PC relative
6496 function_section (current_function_decl
);
6498 else if (TARGET_EMBEDDED_DATA
)
6500 /* For embedded applications, always put constants in read-only data,
6501 in order to reduce RAM usage. */
6502 mergeable_constant_section (mode
, align
, 0);
6506 /* For hosted applications, always put constants in small data if
6507 possible, as this gives the best performance. */
6508 /* ??? Consider using mergeable small data sections. */
6510 if (GET_MODE_SIZE (mode
) <= (unsigned) mips_section_threshold
6511 && mips_section_threshold
> 0)
6512 named_section (0, ".sdata", 0);
6513 else if (flag_pic
&& symbolic_expression_p (x
))
6514 named_section (0, ".data.rel.ro", 3);
6516 mergeable_constant_section (mode
, align
, 0);
6520 /* Implement TARGET_IN_SMALL_DATA_P. Return true if it would be safe to
6521 access DECL using %gp_rel(...)($gp). */
6524 mips_in_small_data_p (tree decl
)
6528 if (TREE_CODE (decl
) == STRING_CST
|| TREE_CODE (decl
) == FUNCTION_DECL
)
6531 /* We don't yet generate small-data references for -mabicalls. See related
6532 -G handling in override_options. */
6533 if (TARGET_ABICALLS
)
6536 if (TREE_CODE (decl
) == VAR_DECL
&& DECL_SECTION_NAME (decl
) != 0)
6540 /* Reject anything that isn't in a known small-data section. */
6541 name
= TREE_STRING_POINTER (DECL_SECTION_NAME (decl
));
6542 if (strcmp (name
, ".sdata") != 0 && strcmp (name
, ".sbss") != 0)
6545 /* If a symbol is defined externally, the assembler will use the
6546 usual -G rules when deciding how to implement macros. */
6547 if (TARGET_EXPLICIT_RELOCS
|| !DECL_EXTERNAL (decl
))
6550 else if (TARGET_EMBEDDED_DATA
)
6552 /* Don't put constants into the small data section: we want them
6553 to be in ROM rather than RAM. */
6554 if (TREE_CODE (decl
) != VAR_DECL
)
6557 if (TREE_READONLY (decl
)
6558 && !TREE_SIDE_EFFECTS (decl
)
6559 && (!DECL_INITIAL (decl
) || TREE_CONSTANT (DECL_INITIAL (decl
))))
6563 size
= int_size_in_bytes (TREE_TYPE (decl
));
6564 return (size
> 0 && size
<= mips_section_threshold
);
6567 /* See whether VALTYPE is a record whose fields should be returned in
6568 floating-point registers. If so, return the number of fields and
6569 list them in FIELDS (which should have two elements). Return 0
6572 For n32 & n64, a structure with one or two fields is returned in
6573 floating-point registers as long as every field has a floating-point
6577 mips_fpr_return_fields (tree valtype
, tree
*fields
)
6585 if (TREE_CODE (valtype
) != RECORD_TYPE
)
6589 for (field
= TYPE_FIELDS (valtype
); field
!= 0; field
= TREE_CHAIN (field
))
6591 if (TREE_CODE (field
) != FIELD_DECL
)
6594 if (TREE_CODE (TREE_TYPE (field
)) != REAL_TYPE
)
6600 fields
[i
++] = field
;
6606 /* Implement TARGET_RETURN_IN_MSB. For n32 & n64, we should return
6607 a value in the most significant part of $2/$3 if:
6609 - the target is big-endian;
6611 - the value has a structure or union type (we generalize this to
6612 cover aggregates from other languages too); and
6614 - the structure is not returned in floating-point registers. */
6617 mips_return_in_msb (tree valtype
)
6621 return (TARGET_NEWABI
6622 && TARGET_BIG_ENDIAN
6623 && AGGREGATE_TYPE_P (valtype
)
6624 && mips_fpr_return_fields (valtype
, fields
) == 0);
6628 /* Return a composite value in a pair of floating-point registers.
6629 MODE1 and OFFSET1 are the mode and byte offset for the first value,
6630 likewise MODE2 and OFFSET2 for the second. MODE is the mode of the
6633 For n32 & n64, $f0 always holds the first value and $f2 the second.
6634 Otherwise the values are packed together as closely as possible. */
6637 mips_return_fpr_pair (enum machine_mode mode
,
6638 enum machine_mode mode1
, HOST_WIDE_INT offset1
,
6639 enum machine_mode mode2
, HOST_WIDE_INT offset2
)
6643 inc
= (TARGET_NEWABI
? 2 : FP_INC
);
6644 return gen_rtx_PARALLEL
6647 gen_rtx_EXPR_LIST (VOIDmode
,
6648 gen_rtx_REG (mode1
, FP_RETURN
),
6650 gen_rtx_EXPR_LIST (VOIDmode
,
6651 gen_rtx_REG (mode2
, FP_RETURN
+ inc
),
6652 GEN_INT (offset2
))));
6657 /* Implement FUNCTION_VALUE and LIBCALL_VALUE. For normal calls,
6658 VALTYPE is the return type and MODE is VOIDmode. For libcalls,
6659 VALTYPE is null and MODE is the mode of the return value. */
6662 mips_function_value (tree valtype
, tree func ATTRIBUTE_UNUSED
,
6663 enum machine_mode mode
)
6670 mode
= TYPE_MODE (valtype
);
6671 unsignedp
= TYPE_UNSIGNED (valtype
);
6673 /* Since we define TARGET_PROMOTE_FUNCTION_RETURN that returns
6674 true, we must promote the mode just as PROMOTE_MODE does. */
6675 mode
= promote_mode (valtype
, mode
, &unsignedp
, 1);
6677 /* Handle structures whose fields are returned in $f0/$f2. */
6678 switch (mips_fpr_return_fields (valtype
, fields
))
6681 return gen_rtx_REG (mode
, FP_RETURN
);
6684 return mips_return_fpr_pair (mode
,
6685 TYPE_MODE (TREE_TYPE (fields
[0])),
6686 int_byte_position (fields
[0]),
6687 TYPE_MODE (TREE_TYPE (fields
[1])),
6688 int_byte_position (fields
[1]));
6691 /* If a value is passed in the most significant part of a register, see
6692 whether we have to round the mode up to a whole number of words. */
6693 if (mips_return_in_msb (valtype
))
6695 HOST_WIDE_INT size
= int_size_in_bytes (valtype
);
6696 if (size
% UNITS_PER_WORD
!= 0)
6698 size
+= UNITS_PER_WORD
- size
% UNITS_PER_WORD
;
6699 mode
= mode_for_size (size
* BITS_PER_UNIT
, MODE_INT
, 0);
6704 if ((GET_MODE_CLASS (mode
) == MODE_FLOAT
6705 || GET_MODE_CLASS (mode
) == MODE_VECTOR_FLOAT
)
6706 && GET_MODE_SIZE (mode
) <= UNITS_PER_HWFPVALUE
)
6707 return gen_rtx_REG (mode
, FP_RETURN
);
6709 /* Handle long doubles for n32 & n64. */
6711 return mips_return_fpr_pair (mode
,
6713 DImode
, GET_MODE_SIZE (mode
) / 2);
6715 if (GET_MODE_CLASS (mode
) == MODE_COMPLEX_FLOAT
6716 && GET_MODE_SIZE (mode
) <= UNITS_PER_HWFPVALUE
* 2)
6717 return mips_return_fpr_pair (mode
,
6718 GET_MODE_INNER (mode
), 0,
6719 GET_MODE_INNER (mode
),
6720 GET_MODE_SIZE (mode
) / 2);
6722 return gen_rtx_REG (mode
, GP_RETURN
);
6725 /* Return nonzero when an argument must be passed by reference. */
6728 mips_pass_by_reference (CUMULATIVE_ARGS
*cum ATTRIBUTE_UNUSED
,
6729 enum machine_mode mode
, tree type
,
6730 bool named ATTRIBUTE_UNUSED
)
6732 if (mips_abi
== ABI_EABI
)
6736 /* ??? How should SCmode be handled? */
6737 if (type
== NULL_TREE
|| mode
== DImode
|| mode
== DFmode
)
6740 size
= int_size_in_bytes (type
);
6741 return size
== -1 || size
> UNITS_PER_WORD
;
6745 /* If we have a variable-sized parameter, we have no choice. */
6746 return targetm
.calls
.must_pass_in_stack (mode
, type
);
6750 /* Return the class of registers for which a mode change from FROM to TO
6753 In little-endian mode, the hi-lo registers are numbered backwards,
6754 so (subreg:SI (reg:DI hi) 0) gets the high word instead of the low
6757 Similarly, when using paired floating-point registers, the first
6758 register holds the low word, regardless of endianness. So in big
6759 endian mode, (subreg:SI (reg:DF $f0) 0) does not get the high word
6762 Also, loading a 32-bit value into a 64-bit floating-point register
6763 will not sign-extend the value, despite what LOAD_EXTEND_OP says.
6764 We can't allow 64-bit float registers to change from a 32-bit
6765 mode to a 64-bit mode. */
6768 mips_cannot_change_mode_class (enum machine_mode from
,
6769 enum machine_mode to
, enum reg_class
class)
6771 if (GET_MODE_SIZE (from
) != GET_MODE_SIZE (to
))
6773 if (TARGET_BIG_ENDIAN
)
6774 return reg_classes_intersect_p (FP_REGS
, class);
6776 return reg_classes_intersect_p (HI_AND_FP_REGS
, class);
6777 return reg_classes_intersect_p (HI_REG
, class);
6782 /* Return true if X should not be moved directly into register $25.
6783 We need this because many versions of GAS will treat "la $25,foo" as
6784 part of a call sequence and so allow a global "foo" to be lazily bound. */
6787 mips_dangerous_for_la25_p (rtx x
)
6789 HOST_WIDE_INT offset
;
6791 if (TARGET_EXPLICIT_RELOCS
)
6794 mips_split_const (x
, &x
, &offset
);
6795 return global_got_operand (x
, VOIDmode
);
6798 /* Implement PREFERRED_RELOAD_CLASS. */
6801 mips_preferred_reload_class (rtx x
, enum reg_class
class)
6803 if (mips_dangerous_for_la25_p (x
) && reg_class_subset_p (LEA_REGS
, class))
6806 if (TARGET_HARD_FLOAT
6807 && FLOAT_MODE_P (GET_MODE (x
))
6808 && reg_class_subset_p (FP_REGS
, class))
6811 if (reg_class_subset_p (GR_REGS
, class))
6814 if (TARGET_MIPS16
&& reg_class_subset_p (M16_REGS
, class))
6820 /* This function returns the register class required for a secondary
6821 register when copying between one of the registers in CLASS, and X,
6822 using MODE. If IN_P is nonzero, the copy is going from X to the
6823 register, otherwise the register is the source. A return value of
6824 NO_REGS means that no secondary register is required. */
6827 mips_secondary_reload_class (enum reg_class
class,
6828 enum machine_mode mode
, rtx x
, int in_p
)
6830 enum reg_class gr_regs
= TARGET_MIPS16
? M16_REGS
: GR_REGS
;
6834 if (GET_CODE (x
) == REG
|| GET_CODE (x
) == SUBREG
)
6835 regno
= true_regnum (x
);
6837 gp_reg_p
= TARGET_MIPS16
? M16_REG_P (regno
) : GP_REG_P (regno
);
6839 if (mips_dangerous_for_la25_p (x
))
6842 if (TEST_HARD_REG_BIT (reg_class_contents
[(int) class], 25))
6846 /* Copying from HI or LO to anywhere other than a general register
6847 requires a general register. */
6848 if (class == HI_REG
|| class == LO_REG
|| class == MD_REGS
)
6850 if (TARGET_MIPS16
&& in_p
)
6852 /* We can't really copy to HI or LO at all in mips16 mode. */
6855 return gp_reg_p
? NO_REGS
: gr_regs
;
6857 if (MD_REG_P (regno
))
6859 if (TARGET_MIPS16
&& ! in_p
)
6861 /* We can't really copy to HI or LO at all in mips16 mode. */
6864 return class == gr_regs
? NO_REGS
: gr_regs
;
6867 /* We can only copy a value to a condition code register from a
6868 floating point register, and even then we require a scratch
6869 floating point register. We can only copy a value out of a
6870 condition code register into a general register. */
6871 if (class == ST_REGS
)
6875 return gp_reg_p
? NO_REGS
: gr_regs
;
6877 if (ST_REG_P (regno
))
6881 return class == gr_regs
? NO_REGS
: gr_regs
;
6884 if (class == FP_REGS
)
6886 if (GET_CODE (x
) == MEM
)
6888 /* In this case we can use lwc1, swc1, ldc1 or sdc1. */
6891 else if (CONSTANT_P (x
) && GET_MODE_CLASS (mode
) == MODE_FLOAT
)
6893 /* We can use the l.s and l.d macros to load floating-point
6894 constants. ??? For l.s, we could probably get better
6895 code by returning GR_REGS here. */
6898 else if (gp_reg_p
|| x
== CONST0_RTX (mode
))
6900 /* In this case we can use mtc1, mfc1, dmtc1 or dmfc1. */
6903 else if (FP_REG_P (regno
))
6905 /* In this case we can use mov.s or mov.d. */
6910 /* Otherwise, we need to reload through an integer register. */
6915 /* In mips16 mode, going between memory and anything but M16_REGS
6916 requires an M16_REG. */
6919 if (class != M16_REGS
&& class != M16_NA_REGS
)
6927 if (class == M16_REGS
|| class == M16_NA_REGS
)
6936 /* Implement CLASS_MAX_NREGS.
6938 Usually all registers are word-sized. The only supported exception
6939 is -mgp64 -msingle-float, which has 64-bit words but 32-bit float
6940 registers. A word-based calculation is correct even in that case,
6941 since -msingle-float disallows multi-FPR values.
6943 The FP status registers are an exception to this rule. They are always
6944 4 bytes wide as they only hold condition code modes, and CCmode is always
6945 considered to be 4 bytes wide. */
6948 mips_class_max_nregs (enum reg_class
class ATTRIBUTE_UNUSED
,
6949 enum machine_mode mode
)
6951 if (class == ST_REGS
)
6952 return (GET_MODE_SIZE (mode
) + 3) / 4;
6954 return (GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
6958 mips_valid_pointer_mode (enum machine_mode mode
)
6960 return (mode
== SImode
|| (TARGET_64BIT
&& mode
== DImode
));
6963 /* Target hook for vector_mode_supported_p. */
6965 mips_vector_mode_supported_p (enum machine_mode mode
)
6967 if (mode
== V2SFmode
&& TARGET_PAIRED_SINGLE_FLOAT
)
6973 /* If we can access small data directly (using gp-relative relocation
6974 operators) return the small data pointer, otherwise return null.
6976 For each mips16 function which refers to GP relative symbols, we
6977 use a pseudo register, initialized at the start of the function, to
6978 hold the $gp value. */
6981 mips16_gp_pseudo_reg (void)
6983 if (cfun
->machine
->mips16_gp_pseudo_rtx
== NULL_RTX
)
6988 cfun
->machine
->mips16_gp_pseudo_rtx
= gen_reg_rtx (Pmode
);
6990 /* We want to initialize this to a value which gcc will believe
6993 unspec
= gen_rtx_UNSPEC (VOIDmode
, gen_rtvec (1, const0_rtx
), UNSPEC_GP
);
6994 emit_move_insn (cfun
->machine
->mips16_gp_pseudo_rtx
,
6995 gen_rtx_CONST (Pmode
, unspec
));
6996 insn
= get_insns ();
6999 push_topmost_sequence ();
7000 /* We need to emit the initialization after the FUNCTION_BEG
7001 note, so that it will be integrated. */
7002 for (scan
= get_insns (); scan
!= NULL_RTX
; scan
= NEXT_INSN (scan
))
7003 if (GET_CODE (scan
) == NOTE
7004 && NOTE_LINE_NUMBER (scan
) == NOTE_INSN_FUNCTION_BEG
)
7006 if (scan
== NULL_RTX
)
7007 scan
= get_insns ();
7008 insn
= emit_insn_after (insn
, scan
);
7009 pop_topmost_sequence ();
7012 return cfun
->machine
->mips16_gp_pseudo_rtx
;
7015 /* Write out code to move floating point arguments in or out of
7016 general registers. Output the instructions to FILE. FP_CODE is
7017 the code describing which arguments are present (see the comment at
7018 the definition of CUMULATIVE_ARGS in mips.h). FROM_FP_P is nonzero if
7019 we are copying from the floating point registers. */
7022 mips16_fp_args (FILE *file
, int fp_code
, int from_fp_p
)
7028 /* This code only works for the original 32 bit ABI and the O64 ABI. */
7036 gparg
= GP_ARG_FIRST
;
7037 fparg
= FP_ARG_FIRST
;
7038 for (f
= (unsigned int) fp_code
; f
!= 0; f
>>= 2)
7042 if ((fparg
& 1) != 0)
7044 fprintf (file
, "\t%s\t%s,%s\n", s
,
7045 reg_names
[gparg
], reg_names
[fparg
]);
7047 else if ((f
& 3) == 2)
7050 fprintf (file
, "\td%s\t%s,%s\n", s
,
7051 reg_names
[gparg
], reg_names
[fparg
]);
7054 if ((fparg
& 1) != 0)
7056 if (TARGET_BIG_ENDIAN
)
7057 fprintf (file
, "\t%s\t%s,%s\n\t%s\t%s,%s\n", s
,
7058 reg_names
[gparg
], reg_names
[fparg
+ 1], s
,
7059 reg_names
[gparg
+ 1], reg_names
[fparg
]);
7061 fprintf (file
, "\t%s\t%s,%s\n\t%s\t%s,%s\n", s
,
7062 reg_names
[gparg
], reg_names
[fparg
], s
,
7063 reg_names
[gparg
+ 1], reg_names
[fparg
+ 1]);
7076 /* Build a mips16 function stub. This is used for functions which
7077 take arguments in the floating point registers. It is 32 bit code
7078 that moves the floating point args into the general registers, and
7079 then jumps to the 16 bit code. */
7082 build_mips16_function_stub (FILE *file
)
7085 char *secname
, *stubname
;
7086 tree stubid
, stubdecl
;
7090 fnname
= XSTR (XEXP (DECL_RTL (current_function_decl
), 0), 0);
7091 secname
= (char *) alloca (strlen (fnname
) + 20);
7092 sprintf (secname
, ".mips16.fn.%s", fnname
);
7093 stubname
= (char *) alloca (strlen (fnname
) + 20);
7094 sprintf (stubname
, "__fn_stub_%s", fnname
);
7095 stubid
= get_identifier (stubname
);
7096 stubdecl
= build_decl (FUNCTION_DECL
, stubid
,
7097 build_function_type (void_type_node
, NULL_TREE
));
7098 DECL_SECTION_NAME (stubdecl
) = build_string (strlen (secname
), secname
);
7100 fprintf (file
, "\t# Stub function for %s (", current_function_name ());
7102 for (f
= (unsigned int) current_function_args_info
.fp_code
; f
!= 0; f
>>= 2)
7104 fprintf (file
, "%s%s",
7105 need_comma
? ", " : "",
7106 (f
& 3) == 1 ? "float" : "double");
7109 fprintf (file
, ")\n");
7111 fprintf (file
, "\t.set\tnomips16\n");
7112 function_section (stubdecl
);
7113 ASM_OUTPUT_ALIGN (file
, floor_log2 (FUNCTION_BOUNDARY
/ BITS_PER_UNIT
));
7115 /* ??? If FUNCTION_NAME_ALREADY_DECLARED is defined, then we are
7116 within a .ent, and we cannot emit another .ent. */
7117 if (!FUNCTION_NAME_ALREADY_DECLARED
)
7119 fputs ("\t.ent\t", file
);
7120 assemble_name (file
, stubname
);
7124 assemble_name (file
, stubname
);
7125 fputs (":\n", file
);
7127 /* We don't want the assembler to insert any nops here. */
7128 fprintf (file
, "\t.set\tnoreorder\n");
7130 mips16_fp_args (file
, current_function_args_info
.fp_code
, 1);
7132 fprintf (asm_out_file
, "\t.set\tnoat\n");
7133 fprintf (asm_out_file
, "\tla\t%s,", reg_names
[GP_REG_FIRST
+ 1]);
7134 assemble_name (file
, fnname
);
7135 fprintf (file
, "\n");
7136 fprintf (asm_out_file
, "\tjr\t%s\n", reg_names
[GP_REG_FIRST
+ 1]);
7137 fprintf (asm_out_file
, "\t.set\tat\n");
7139 /* Unfortunately, we can't fill the jump delay slot. We can't fill
7140 with one of the mfc1 instructions, because the result is not
7141 available for one instruction, so if the very first instruction
7142 in the function refers to the register, it will see the wrong
7144 fprintf (file
, "\tnop\n");
7146 fprintf (file
, "\t.set\treorder\n");
7148 if (!FUNCTION_NAME_ALREADY_DECLARED
)
7150 fputs ("\t.end\t", file
);
7151 assemble_name (file
, stubname
);
7155 fprintf (file
, "\t.set\tmips16\n");
7157 function_section (current_function_decl
);
7160 /* We keep a list of functions for which we have already built stubs
7161 in build_mips16_call_stub. */
7165 struct mips16_stub
*next
;
7170 static struct mips16_stub
*mips16_stubs
;
7172 /* Build a call stub for a mips16 call. A stub is needed if we are
7173 passing any floating point values which should go into the floating
7174 point registers. If we are, and the call turns out to be to a 32
7175 bit function, the stub will be used to move the values into the
7176 floating point registers before calling the 32 bit function. The
7177 linker will magically adjust the function call to either the 16 bit
7178 function or the 32 bit stub, depending upon where the function call
7179 is actually defined.
7181 Similarly, we need a stub if the return value might come back in a
7182 floating point register.
7184 RETVAL is the location of the return value, or null if this is
7185 a call rather than a call_value. FN is the address of the
7186 function and ARG_SIZE is the size of the arguments. FP_CODE
7187 is the code built by function_arg. This function returns a nonzero
7188 value if it builds the call instruction itself. */
7191 build_mips16_call_stub (rtx retval
, rtx fn
, rtx arg_size
, int fp_code
)
7195 char *secname
, *stubname
;
7196 struct mips16_stub
*l
;
7197 tree stubid
, stubdecl
;
7201 /* We don't need to do anything if we aren't in mips16 mode, or if
7202 we were invoked with the -msoft-float option. */
7203 if (! TARGET_MIPS16
|| ! mips16_hard_float
)
7206 /* Figure out whether the value might come back in a floating point
7208 fpret
= (retval
!= 0
7209 && GET_MODE_CLASS (GET_MODE (retval
)) == MODE_FLOAT
7210 && GET_MODE_SIZE (GET_MODE (retval
)) <= UNITS_PER_FPVALUE
);
7212 /* We don't need to do anything if there were no floating point
7213 arguments and the value will not be returned in a floating point
7215 if (fp_code
== 0 && ! fpret
)
7218 /* We don't need to do anything if this is a call to a special
7219 mips16 support function. */
7220 if (GET_CODE (fn
) == SYMBOL_REF
7221 && strncmp (XSTR (fn
, 0), "__mips16_", 9) == 0)
7224 /* This code will only work for o32 and o64 abis. The other ABI's
7225 require more sophisticated support. */
7229 /* We can only handle SFmode and DFmode floating point return
7231 if (fpret
&& GET_MODE (retval
) != SFmode
&& GET_MODE (retval
) != DFmode
)
7234 /* If we're calling via a function pointer, then we must always call
7235 via a stub. There are magic stubs provided in libgcc.a for each
7236 of the required cases. Each of them expects the function address
7237 to arrive in register $2. */
7239 if (GET_CODE (fn
) != SYMBOL_REF
)
7245 /* ??? If this code is modified to support other ABI's, we need
7246 to handle PARALLEL return values here. */
7248 sprintf (buf
, "__mips16_call_stub_%s%d",
7250 ? (GET_MODE (retval
) == SFmode
? "sf_" : "df_")
7253 id
= get_identifier (buf
);
7254 stub_fn
= gen_rtx_SYMBOL_REF (Pmode
, IDENTIFIER_POINTER (id
));
7256 emit_move_insn (gen_rtx_REG (Pmode
, 2), fn
);
7258 if (retval
== NULL_RTX
)
7259 insn
= gen_call_internal (stub_fn
, arg_size
);
7261 insn
= gen_call_value_internal (retval
, stub_fn
, arg_size
);
7262 insn
= emit_call_insn (insn
);
7264 /* Put the register usage information on the CALL. */
7265 if (GET_CODE (insn
) != CALL_INSN
)
7267 CALL_INSN_FUNCTION_USAGE (insn
) =
7268 gen_rtx_EXPR_LIST (VOIDmode
,
7269 gen_rtx_USE (VOIDmode
, gen_rtx_REG (Pmode
, 2)),
7270 CALL_INSN_FUNCTION_USAGE (insn
));
7272 /* If we are handling a floating point return value, we need to
7273 save $18 in the function prologue. Putting a note on the
7274 call will mean that regs_ever_live[$18] will be true if the
7275 call is not eliminated, and we can check that in the prologue
7278 CALL_INSN_FUNCTION_USAGE (insn
) =
7279 gen_rtx_EXPR_LIST (VOIDmode
,
7280 gen_rtx_USE (VOIDmode
,
7281 gen_rtx_REG (word_mode
, 18)),
7282 CALL_INSN_FUNCTION_USAGE (insn
));
7284 /* Return 1 to tell the caller that we've generated the call
7289 /* We know the function we are going to call. If we have already
7290 built a stub, we don't need to do anything further. */
7292 fnname
= XSTR (fn
, 0);
7293 for (l
= mips16_stubs
; l
!= NULL
; l
= l
->next
)
7294 if (strcmp (l
->name
, fnname
) == 0)
7299 /* Build a special purpose stub. When the linker sees a
7300 function call in mips16 code, it will check where the target
7301 is defined. If the target is a 32 bit call, the linker will
7302 search for the section defined here. It can tell which
7303 symbol this section is associated with by looking at the
7304 relocation information (the name is unreliable, since this
7305 might be a static function). If such a section is found, the
7306 linker will redirect the call to the start of the magic
7309 If the function does not return a floating point value, the
7310 special stub section is named
7313 If the function does return a floating point value, the stub
7315 .mips16.call.fp.FNNAME
7318 secname
= (char *) alloca (strlen (fnname
) + 40);
7319 sprintf (secname
, ".mips16.call.%s%s",
7322 stubname
= (char *) alloca (strlen (fnname
) + 20);
7323 sprintf (stubname
, "__call_stub_%s%s",
7326 stubid
= get_identifier (stubname
);
7327 stubdecl
= build_decl (FUNCTION_DECL
, stubid
,
7328 build_function_type (void_type_node
, NULL_TREE
));
7329 DECL_SECTION_NAME (stubdecl
) = build_string (strlen (secname
), secname
);
7331 fprintf (asm_out_file
, "\t# Stub function to call %s%s (",
7333 ? (GET_MODE (retval
) == SFmode
? "float " : "double ")
7337 for (f
= (unsigned int) fp_code
; f
!= 0; f
>>= 2)
7339 fprintf (asm_out_file
, "%s%s",
7340 need_comma
? ", " : "",
7341 (f
& 3) == 1 ? "float" : "double");
7344 fprintf (asm_out_file
, ")\n");
7346 fprintf (asm_out_file
, "\t.set\tnomips16\n");
7347 assemble_start_function (stubdecl
, stubname
);
7349 if (!FUNCTION_NAME_ALREADY_DECLARED
)
7351 fputs ("\t.ent\t", asm_out_file
);
7352 assemble_name (asm_out_file
, stubname
);
7353 fputs ("\n", asm_out_file
);
7355 assemble_name (asm_out_file
, stubname
);
7356 fputs (":\n", asm_out_file
);
7359 /* We build the stub code by hand. That's the only way we can
7360 do it, since we can't generate 32 bit code during a 16 bit
7363 /* We don't want the assembler to insert any nops here. */
7364 fprintf (asm_out_file
, "\t.set\tnoreorder\n");
7366 mips16_fp_args (asm_out_file
, fp_code
, 0);
7370 fprintf (asm_out_file
, "\t.set\tnoat\n");
7371 fprintf (asm_out_file
, "\tla\t%s,%s\n", reg_names
[GP_REG_FIRST
+ 1],
7373 fprintf (asm_out_file
, "\tjr\t%s\n", reg_names
[GP_REG_FIRST
+ 1]);
7374 fprintf (asm_out_file
, "\t.set\tat\n");
7375 /* Unfortunately, we can't fill the jump delay slot. We
7376 can't fill with one of the mtc1 instructions, because the
7377 result is not available for one instruction, so if the
7378 very first instruction in the function refers to the
7379 register, it will see the wrong value. */
7380 fprintf (asm_out_file
, "\tnop\n");
7384 fprintf (asm_out_file
, "\tmove\t%s,%s\n",
7385 reg_names
[GP_REG_FIRST
+ 18], reg_names
[GP_REG_FIRST
+ 31]);
7386 fprintf (asm_out_file
, "\tjal\t%s\n", fnname
);
7387 /* As above, we can't fill the delay slot. */
7388 fprintf (asm_out_file
, "\tnop\n");
7389 if (GET_MODE (retval
) == SFmode
)
7390 fprintf (asm_out_file
, "\tmfc1\t%s,%s\n",
7391 reg_names
[GP_REG_FIRST
+ 2], reg_names
[FP_REG_FIRST
+ 0]);
7394 if (TARGET_BIG_ENDIAN
)
7396 fprintf (asm_out_file
, "\tmfc1\t%s,%s\n",
7397 reg_names
[GP_REG_FIRST
+ 2],
7398 reg_names
[FP_REG_FIRST
+ 1]);
7399 fprintf (asm_out_file
, "\tmfc1\t%s,%s\n",
7400 reg_names
[GP_REG_FIRST
+ 3],
7401 reg_names
[FP_REG_FIRST
+ 0]);
7405 fprintf (asm_out_file
, "\tmfc1\t%s,%s\n",
7406 reg_names
[GP_REG_FIRST
+ 2],
7407 reg_names
[FP_REG_FIRST
+ 0]);
7408 fprintf (asm_out_file
, "\tmfc1\t%s,%s\n",
7409 reg_names
[GP_REG_FIRST
+ 3],
7410 reg_names
[FP_REG_FIRST
+ 1]);
7413 fprintf (asm_out_file
, "\tj\t%s\n", reg_names
[GP_REG_FIRST
+ 18]);
7414 /* As above, we can't fill the delay slot. */
7415 fprintf (asm_out_file
, "\tnop\n");
7418 fprintf (asm_out_file
, "\t.set\treorder\n");
7420 #ifdef ASM_DECLARE_FUNCTION_SIZE
7421 ASM_DECLARE_FUNCTION_SIZE (asm_out_file
, stubname
, stubdecl
);
7424 if (!FUNCTION_NAME_ALREADY_DECLARED
)
7426 fputs ("\t.end\t", asm_out_file
);
7427 assemble_name (asm_out_file
, stubname
);
7428 fputs ("\n", asm_out_file
);
7431 fprintf (asm_out_file
, "\t.set\tmips16\n");
7433 /* Record this stub. */
7434 l
= (struct mips16_stub
*) xmalloc (sizeof *l
);
7435 l
->name
= xstrdup (fnname
);
7437 l
->next
= mips16_stubs
;
7441 /* If we expect a floating point return value, but we've built a
7442 stub which does not expect one, then we're in trouble. We can't
7443 use the existing stub, because it won't handle the floating point
7444 value. We can't build a new stub, because the linker won't know
7445 which stub to use for the various calls in this object file.
7446 Fortunately, this case is illegal, since it means that a function
7447 was declared in two different ways in a single compilation. */
7448 if (fpret
&& ! l
->fpret
)
7449 error ("cannot handle inconsistent calls to `%s'", fnname
);
7451 /* If we are calling a stub which handles a floating point return
7452 value, we need to arrange to save $18 in the prologue. We do
7453 this by marking the function call as using the register. The
7454 prologue will later see that it is used, and emit code to save
7461 if (retval
== NULL_RTX
)
7462 insn
= gen_call_internal (fn
, arg_size
);
7464 insn
= gen_call_value_internal (retval
, fn
, arg_size
);
7465 insn
= emit_call_insn (insn
);
7467 if (GET_CODE (insn
) != CALL_INSN
)
7470 CALL_INSN_FUNCTION_USAGE (insn
) =
7471 gen_rtx_EXPR_LIST (VOIDmode
,
7472 gen_rtx_USE (VOIDmode
, gen_rtx_REG (word_mode
, 18)),
7473 CALL_INSN_FUNCTION_USAGE (insn
));
7475 /* Return 1 to tell the caller that we've generated the call
7480 /* Return 0 to let the caller generate the call insn. */
7484 /* An entry in the mips16 constant pool. VALUE is the pool constant,
7485 MODE is its mode, and LABEL is the CODE_LABEL associated with it. */
7487 struct mips16_constant
{
7488 struct mips16_constant
*next
;
7491 enum machine_mode mode
;
7494 /* Information about an incomplete mips16 constant pool. FIRST is the
7495 first constant, HIGHEST_ADDRESS is the highest address that the first
7496 byte of the pool can have, and INSN_ADDRESS is the current instruction
7499 struct mips16_constant_pool
{
7500 struct mips16_constant
*first
;
7501 int highest_address
;
7505 /* Add constant VALUE to POOL and return its label. MODE is the
7506 value's mode (used for CONST_INTs, etc.). */
7509 add_constant (struct mips16_constant_pool
*pool
,
7510 rtx value
, enum machine_mode mode
)
7512 struct mips16_constant
**p
, *c
;
7513 bool first_of_size_p
;
7515 /* See whether the constant is already in the pool. If so, return the
7516 existing label, otherwise leave P pointing to the place where the
7517 constant should be added.
7519 Keep the pool sorted in increasing order of mode size so that we can
7520 reduce the number of alignments needed. */
7521 first_of_size_p
= true;
7522 for (p
= &pool
->first
; *p
!= 0; p
= &(*p
)->next
)
7524 if (mode
== (*p
)->mode
&& rtx_equal_p (value
, (*p
)->value
))
7526 if (GET_MODE_SIZE (mode
) < GET_MODE_SIZE ((*p
)->mode
))
7528 if (GET_MODE_SIZE (mode
) == GET_MODE_SIZE ((*p
)->mode
))
7529 first_of_size_p
= false;
7532 /* In the worst case, the constant needed by the earliest instruction
7533 will end up at the end of the pool. The entire pool must then be
7534 accessible from that instruction.
7536 When adding the first constant, set the pool's highest address to
7537 the address of the first out-of-range byte. Adjust this address
7538 downwards each time a new constant is added. */
7539 if (pool
->first
== 0)
7540 /* For pc-relative lw, addiu and daddiu instructions, the base PC value
7541 is the address of the instruction with the lowest two bits clear.
7542 The base PC value for ld has the lowest three bits clear. Assume
7543 the worst case here. */
7544 pool
->highest_address
= pool
->insn_address
- (UNITS_PER_WORD
- 2) + 0x8000;
7545 pool
->highest_address
-= GET_MODE_SIZE (mode
);
7546 if (first_of_size_p
)
7547 /* Take into account the worst possible padding due to alignment. */
7548 pool
->highest_address
-= GET_MODE_SIZE (mode
) - 1;
7550 /* Create a new entry. */
7551 c
= (struct mips16_constant
*) xmalloc (sizeof *c
);
7554 c
->label
= gen_label_rtx ();
7561 /* Output constant VALUE after instruction INSN and return the last
7562 instruction emitted. MODE is the mode of the constant. */
7565 dump_constants_1 (enum machine_mode mode
, rtx value
, rtx insn
)
7567 switch (GET_MODE_CLASS (mode
))
7571 rtx size
= GEN_INT (GET_MODE_SIZE (mode
));
7572 return emit_insn_after (gen_consttable_int (value
, size
), insn
);
7576 return emit_insn_after (gen_consttable_float (value
), insn
);
7578 case MODE_VECTOR_FLOAT
:
7579 case MODE_VECTOR_INT
:
7582 for (i
= 0; i
< CONST_VECTOR_NUNITS (value
); i
++)
7583 insn
= dump_constants_1 (GET_MODE_INNER (mode
),
7584 CONST_VECTOR_ELT (value
, i
), insn
);
7594 /* Dump out the constants in CONSTANTS after INSN. */
7597 dump_constants (struct mips16_constant
*constants
, rtx insn
)
7599 struct mips16_constant
*c
, *next
;
7603 for (c
= constants
; c
!= NULL
; c
= next
)
7605 /* If necessary, increase the alignment of PC. */
7606 if (align
< GET_MODE_SIZE (c
->mode
))
7608 int align_log
= floor_log2 (GET_MODE_SIZE (c
->mode
));
7609 insn
= emit_insn_after (gen_align (GEN_INT (align_log
)), insn
);
7611 align
= GET_MODE_SIZE (c
->mode
);
7613 insn
= emit_label_after (c
->label
, insn
);
7614 insn
= dump_constants_1 (c
->mode
, c
->value
, insn
);
7620 emit_barrier_after (insn
);
7623 /* Return the length of instruction INSN.
7625 ??? MIPS16 switch tables go in .text, but we don't define
7626 JUMP_TABLES_IN_TEXT_SECTION, so get_attr_length will not
7627 compute their lengths correctly. */
7630 mips16_insn_length (rtx insn
)
7632 if (GET_CODE (insn
) == JUMP_INSN
)
7634 rtx body
= PATTERN (insn
);
7635 if (GET_CODE (body
) == ADDR_VEC
)
7636 return GET_MODE_SIZE (GET_MODE (body
)) * XVECLEN (body
, 0);
7637 if (GET_CODE (body
) == ADDR_DIFF_VEC
)
7638 return GET_MODE_SIZE (GET_MODE (body
)) * XVECLEN (body
, 1);
7640 return get_attr_length (insn
);
7643 /* Rewrite *X so that constant pool references refer to the constant's
7644 label instead. DATA points to the constant pool structure. */
7647 mips16_rewrite_pool_refs (rtx
*x
, void *data
)
7649 struct mips16_constant_pool
*pool
= data
;
7650 if (GET_CODE (*x
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (*x
))
7651 *x
= gen_rtx_LABEL_REF (Pmode
, add_constant (pool
,
7652 get_pool_constant (*x
),
7653 get_pool_mode (*x
)));
7657 /* Build MIPS16 constant pools. */
7660 mips16_lay_out_constants (void)
7662 struct mips16_constant_pool pool
;
7666 memset (&pool
, 0, sizeof (pool
));
7667 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
7669 /* Rewrite constant pool references in INSN. */
7671 for_each_rtx (&PATTERN (insn
), mips16_rewrite_pool_refs
, &pool
);
7673 pool
.insn_address
+= mips16_insn_length (insn
);
7675 if (pool
.first
!= NULL
)
7677 /* If there are no natural barriers between the first user of
7678 the pool and the highest acceptable address, we'll need to
7679 create a new instruction to jump around the constant pool.
7680 In the worst case, this instruction will be 4 bytes long.
7682 If it's too late to do this transformation after INSN,
7683 do it immediately before INSN. */
7684 if (barrier
== 0 && pool
.insn_address
+ 4 > pool
.highest_address
)
7688 label
= gen_label_rtx ();
7690 jump
= emit_jump_insn_before (gen_jump (label
), insn
);
7691 JUMP_LABEL (jump
) = label
;
7692 LABEL_NUSES (label
) = 1;
7693 barrier
= emit_barrier_after (jump
);
7695 emit_label_after (label
, barrier
);
7696 pool
.insn_address
+= 4;
7699 /* See whether the constant pool is now out of range of the first
7700 user. If so, output the constants after the previous barrier.
7701 Note that any instructions between BARRIER and INSN (inclusive)
7702 will use negative offsets to refer to the pool. */
7703 if (pool
.insn_address
> pool
.highest_address
)
7705 dump_constants (pool
.first
, barrier
);
7709 else if (BARRIER_P (insn
))
7713 dump_constants (pool
.first
, get_last_insn ());
7716 /* A temporary variable used by for_each_rtx callbacks, etc. */
7717 static rtx mips_sim_insn
;
7719 /* A structure representing the state of the processor pipeline.
7720 Used by the mips_sim_* family of functions. */
7722 /* The maximum number of instructions that can be issued in a cycle.
7723 (Caches mips_issue_rate.) */
7724 unsigned int issue_rate
;
7726 /* The current simulation time. */
7729 /* How many more instructions can be issued in the current cycle. */
7730 unsigned int insns_left
;
7732 /* LAST_SET[X].INSN is the last instruction to set register X.
7733 LAST_SET[X].TIME is the time at which that instruction was issued.
7734 INSN is null if no instruction has yet set register X. */
7738 } last_set
[FIRST_PSEUDO_REGISTER
];
7740 /* The pipeline's current DFA state. */
7744 /* Reset STATE to the initial simulation state. */
7747 mips_sim_reset (struct mips_sim
*state
)
7750 state
->insns_left
= state
->issue_rate
;
7751 memset (&state
->last_set
, 0, sizeof (state
->last_set
));
7752 state_reset (state
->dfa_state
);
7755 /* Initialize STATE before its first use. DFA_STATE points to an
7756 allocated but uninitialized DFA state. */
7759 mips_sim_init (struct mips_sim
*state
, state_t dfa_state
)
7761 state
->issue_rate
= mips_issue_rate ();
7762 state
->dfa_state
= dfa_state
;
7763 mips_sim_reset (state
);
7766 /* Advance STATE by one clock cycle. */
7769 mips_sim_next_cycle (struct mips_sim
*state
)
7772 state
->insns_left
= state
->issue_rate
;
7773 state_transition (state
->dfa_state
, 0);
7776 /* Advance simulation state STATE until instruction INSN can read
7780 mips_sim_wait_reg (struct mips_sim
*state
, rtx insn
, rtx reg
)
7784 for (i
= 0; i
< HARD_REGNO_NREGS (REGNO (reg
), GET_MODE (reg
)); i
++)
7785 if (state
->last_set
[REGNO (reg
) + i
].insn
!= 0)
7789 t
= state
->last_set
[REGNO (reg
) + i
].time
;
7790 t
+= insn_latency (state
->last_set
[REGNO (reg
) + i
].insn
, insn
);
7791 while (state
->time
< t
)
7792 mips_sim_next_cycle (state
);
7796 /* A for_each_rtx callback. If *X is a register, advance simulation state
7797 DATA until mips_sim_insn can read the register's value. */
7800 mips_sim_wait_regs_2 (rtx
*x
, void *data
)
7803 mips_sim_wait_reg (data
, mips_sim_insn
, *x
);
7807 /* Call mips_sim_wait_regs_2 (R, DATA) for each register R mentioned in *X. */
7810 mips_sim_wait_regs_1 (rtx
*x
, void *data
)
7812 for_each_rtx (x
, mips_sim_wait_regs_2
, data
);
7815 /* Advance simulation state STATE until all of INSN's register
7816 dependencies are satisfied. */
7819 mips_sim_wait_regs (struct mips_sim
*state
, rtx insn
)
7821 mips_sim_insn
= insn
;
7822 note_uses (&PATTERN (insn
), mips_sim_wait_regs_1
, state
);
7825 /* Advance simulation state STATE until the units required by
7826 instruction INSN are available. */
7829 mips_sim_wait_units (struct mips_sim
*state
, rtx insn
)
7833 tmp_state
= alloca (state_size ());
7834 while (state
->insns_left
== 0
7835 || (memcpy (tmp_state
, state
->dfa_state
, state_size ()),
7836 state_transition (tmp_state
, insn
) >= 0))
7837 mips_sim_next_cycle (state
);
7840 /* Advance simulation state STATE until INSN is ready to issue. */
7843 mips_sim_wait_insn (struct mips_sim
*state
, rtx insn
)
7845 mips_sim_wait_regs (state
, insn
);
7846 mips_sim_wait_units (state
, insn
);
7849 /* mips_sim_insn has just set X. Update the LAST_SET array
7850 in simulation state DATA. */
7853 mips_sim_record_set (rtx x
, rtx pat ATTRIBUTE_UNUSED
, void *data
)
7855 struct mips_sim
*state
;
7860 for (i
= 0; i
< HARD_REGNO_NREGS (REGNO (x
), GET_MODE (x
)); i
++)
7862 state
->last_set
[REGNO (x
) + i
].insn
= mips_sim_insn
;
7863 state
->last_set
[REGNO (x
) + i
].time
= state
->time
;
7867 /* Issue instruction INSN in scheduler state STATE. Assume that INSN
7868 can issue immediately (i.e., that mips_sim_wait_insn has already
7872 mips_sim_issue_insn (struct mips_sim
*state
, rtx insn
)
7874 state_transition (state
->dfa_state
, insn
);
7875 state
->insns_left
--;
7877 mips_sim_insn
= insn
;
7878 note_stores (PATTERN (insn
), mips_sim_record_set
, state
);
7881 /* Simulate issuing a NOP in state STATE. */
7884 mips_sim_issue_nop (struct mips_sim
*state
)
7886 if (state
->insns_left
== 0)
7887 mips_sim_next_cycle (state
);
7888 state
->insns_left
--;
7891 /* Update simulation state STATE so that it's ready to accept the instruction
7892 after INSN. INSN should be part of the main rtl chain, not a member of a
7896 mips_sim_finish_insn (struct mips_sim
*state
, rtx insn
)
7898 /* If INSN is a jump with an implicit delay slot, simulate a nop. */
7900 mips_sim_issue_nop (state
);
7902 switch (GET_CODE (SEQ_BEGIN (insn
)))
7906 /* We can't predict the processor state after a call or label. */
7907 mips_sim_reset (state
);
7911 /* The delay slots of branch likely instructions are only executed
7912 when the branch is taken. Therefore, if the caller has simulated
7913 the delay slot instruction, STATE does not really reflect the state
7914 of the pipeline for the instruction after the delay slot. Also,
7915 branch likely instructions tend to incur a penalty when not taken,
7916 so there will probably be an extra delay between the branch and
7917 the instruction after the delay slot. */
7918 if (INSN_ANNULLED_BRANCH_P (SEQ_BEGIN (insn
)))
7919 mips_sim_reset (state
);
7927 /* The VR4130 pipeline issues aligned pairs of instructions together,
7928 but it stalls the second instruction if it depends on the first.
7929 In order to cut down the amount of logic required, this dependence
7930 check is not based on a full instruction decode. Instead, any non-SPECIAL
7931 instruction is assumed to modify the register specified by bits 20-16
7932 (which is usually the "rt" field).
7934 In beq, beql, bne and bnel instructions, the rt field is actually an
7935 input, so we can end up with a false dependence between the branch
7936 and its delay slot. If this situation occurs in instruction INSN,
7937 try to avoid it by swapping rs and rt. */
7940 vr4130_avoid_branch_rt_conflict (rtx insn
)
7944 first
= SEQ_BEGIN (insn
);
7945 second
= SEQ_END (insn
);
7946 if (GET_CODE (first
) == JUMP_INSN
7947 && GET_CODE (second
) == INSN
7948 && GET_CODE (PATTERN (first
)) == SET
7949 && GET_CODE (SET_DEST (PATTERN (first
))) == PC
7950 && GET_CODE (SET_SRC (PATTERN (first
))) == IF_THEN_ELSE
)
7952 /* Check for the right kind of condition. */
7953 rtx cond
= XEXP (SET_SRC (PATTERN (first
)), 0);
7954 if ((GET_CODE (cond
) == EQ
|| GET_CODE (cond
) == NE
)
7955 && REG_P (XEXP (cond
, 0))
7956 && REG_P (XEXP (cond
, 1))
7957 && reg_referenced_p (XEXP (cond
, 1), PATTERN (second
))
7958 && !reg_referenced_p (XEXP (cond
, 0), PATTERN (second
)))
7960 /* SECOND mentions the rt register but not the rs register. */
7961 rtx tmp
= XEXP (cond
, 0);
7962 XEXP (cond
, 0) = XEXP (cond
, 1);
7963 XEXP (cond
, 1) = tmp
;
7968 /* Implement -mvr4130-align. Go through each basic block and simulate the
7969 processor pipeline. If we find that a pair of instructions could execute
7970 in parallel, and the first of those instruction is not 8-byte aligned,
7971 insert a nop to make it aligned. */
7974 vr4130_align_insns (void)
7976 struct mips_sim state
;
7977 rtx insn
, subinsn
, last
, last2
, next
;
7982 /* LAST is the last instruction before INSN to have a nonzero length.
7983 LAST2 is the last such instruction before LAST. */
7987 /* ALIGNED_P is true if INSN is known to be at an aligned address. */
7990 mips_sim_init (&state
, alloca (state_size ()));
7991 for (insn
= get_insns (); insn
!= 0; insn
= next
)
7993 unsigned int length
;
7995 next
= NEXT_INSN (insn
);
7997 /* See the comment above vr4130_avoid_branch_rt_conflict for details.
7998 This isn't really related to the alignment pass, but we do it on
7999 the fly to avoid a separate instruction walk. */
8000 vr4130_avoid_branch_rt_conflict (insn
);
8002 if (USEFUL_INSN_P (insn
))
8003 FOR_EACH_SUBINSN (subinsn
, insn
)
8005 mips_sim_wait_insn (&state
, subinsn
);
8007 /* If we want this instruction to issue in parallel with the
8008 previous one, make sure that the previous instruction is
8009 aligned. There are several reasons why this isn't worthwhile
8010 when the second instruction is a call:
8012 - Calls are less likely to be performance critical,
8013 - There's a good chance that the delay slot can execute
8014 in parallel with the call.
8015 - The return address would then be unaligned.
8017 In general, if we're going to insert a nop between instructions
8018 X and Y, it's better to insert it immediately after X. That
8019 way, if the nop makes Y aligned, it will also align any labels
8021 if (state
.insns_left
!= state
.issue_rate
8022 && GET_CODE (subinsn
) != CALL_INSN
)
8024 if (subinsn
== SEQ_BEGIN (insn
) && aligned_p
)
8026 /* SUBINSN is the first instruction in INSN and INSN is
8027 aligned. We want to align the previous instruction
8028 instead, so insert a nop between LAST2 and LAST.
8030 Note that LAST could be either a single instruction
8031 or a branch with a delay slot. In the latter case,
8032 LAST, like INSN, is already aligned, but the delay
8033 slot must have some extra delay that stops it from
8034 issuing at the same time as the branch. We therefore
8035 insert a nop before the branch in order to align its
8037 emit_insn_after (gen_nop (), last2
);
8040 else if (subinsn
!= SEQ_BEGIN (insn
) && !aligned_p
)
8042 /* SUBINSN is the delay slot of INSN, but INSN is
8043 currently unaligned. Insert a nop between
8044 LAST and INSN to align it. */
8045 emit_insn_after (gen_nop (), last
);
8049 mips_sim_issue_insn (&state
, subinsn
);
8051 mips_sim_finish_insn (&state
, insn
);
8053 /* Update LAST, LAST2 and ALIGNED_P for the next instruction. */
8054 length
= get_attr_length (insn
);
8057 /* If the instruction is an asm statement or multi-instruction
8058 mips.md patern, the length is only an estimate. Insert an
8059 8 byte alignment after it so that the following instructions
8060 can be handled correctly. */
8061 if (GET_CODE (SEQ_BEGIN (insn
)) == INSN
8062 && (recog_memoized (insn
) < 0 || length
>= 8))
8064 next
= emit_insn_after (gen_align (GEN_INT (3)), insn
);
8065 next
= NEXT_INSN (next
);
8066 mips_sim_next_cycle (&state
);
8069 else if (length
& 4)
8070 aligned_p
= !aligned_p
;
8075 /* See whether INSN is an aligned label. */
8076 if (LABEL_P (insn
) && label_to_alignment (insn
) >= 3)
8082 /* Subroutine of mips_reorg. If there is a hazard between INSN
8083 and a previous instruction, avoid it by inserting nops after
8086 *DELAYED_REG and *HILO_DELAY describe the hazards that apply at
8087 this point. If *DELAYED_REG is non-null, INSN must wait a cycle
8088 before using the value of that register. *HILO_DELAY counts the
8089 number of instructions since the last hilo hazard (that is,
8090 the number of instructions since the last mflo or mfhi).
8092 After inserting nops for INSN, update *DELAYED_REG and *HILO_DELAY
8093 for the next instruction.
8095 LO_REG is an rtx for the LO register, used in dependence checking. */
8098 mips_avoid_hazard (rtx after
, rtx insn
, int *hilo_delay
,
8099 rtx
*delayed_reg
, rtx lo_reg
)
8107 pattern
= PATTERN (insn
);
8109 /* Do not put the whole function in .set noreorder if it contains
8110 an asm statement. We don't know whether there will be hazards
8111 between the asm statement and the gcc-generated code. */
8112 if (GET_CODE (pattern
) == ASM_INPUT
|| asm_noperands (pattern
) >= 0)
8113 cfun
->machine
->all_noreorder_p
= false;
8115 /* Ignore zero-length instructions (barriers and the like). */
8116 ninsns
= get_attr_length (insn
) / 4;
8120 /* Work out how many nops are needed. Note that we only care about
8121 registers that are explicitly mentioned in the instruction's pattern.
8122 It doesn't matter that calls use the argument registers or that they
8123 clobber hi and lo. */
8124 if (*hilo_delay
< 2 && reg_set_p (lo_reg
, pattern
))
8125 nops
= 2 - *hilo_delay
;
8126 else if (*delayed_reg
!= 0 && reg_referenced_p (*delayed_reg
, pattern
))
8131 /* Insert the nops between this instruction and the previous one.
8132 Each new nop takes us further from the last hilo hazard. */
8133 *hilo_delay
+= nops
;
8135 emit_insn_after (gen_hazard_nop (), after
);
8137 /* Set up the state for the next instruction. */
8138 *hilo_delay
+= ninsns
;
8140 if (INSN_CODE (insn
) >= 0)
8141 switch (get_attr_hazard (insn
))
8151 set
= single_set (insn
);
8154 *delayed_reg
= SET_DEST (set
);
8160 /* Go through the instruction stream and insert nops where necessary.
8161 See if the whole function can then be put into .set noreorder &
8165 mips_avoid_hazards (void)
8167 rtx insn
, last_insn
, lo_reg
, delayed_reg
;
8170 /* Force all instructions to be split into their final form. */
8171 split_all_insns_noflow ();
8173 /* Recalculate instruction lengths without taking nops into account. */
8174 cfun
->machine
->ignore_hazard_length_p
= true;
8175 shorten_branches (get_insns ());
8177 /* The profiler code uses assembler macros. -mfix-vr4120 relies on
8178 assembler nop insertion. */
8179 cfun
->machine
->all_noreorder_p
= (!current_function_profile
8180 && !TARGET_FIX_VR4120
);
8185 lo_reg
= gen_rtx_REG (SImode
, LO_REGNUM
);
8187 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
8190 if (GET_CODE (PATTERN (insn
)) == SEQUENCE
)
8191 for (i
= 0; i
< XVECLEN (PATTERN (insn
), 0); i
++)
8192 mips_avoid_hazard (last_insn
, XVECEXP (PATTERN (insn
), 0, i
),
8193 &hilo_delay
, &delayed_reg
, lo_reg
);
8195 mips_avoid_hazard (last_insn
, insn
, &hilo_delay
,
8196 &delayed_reg
, lo_reg
);
8203 /* Implement TARGET_MACHINE_DEPENDENT_REORG. */
8209 mips16_lay_out_constants ();
8210 else if (TARGET_EXPLICIT_RELOCS
)
8212 if (mips_flag_delayed_branch
)
8213 dbr_schedule (get_insns (), dump_file
);
8214 mips_avoid_hazards ();
8215 if (TUNE_MIPS4130
&& TARGET_VR4130_ALIGN
)
8216 vr4130_align_insns ();
8220 /* This function does three things:
8222 - Register the special divsi3 and modsi3 functions if -mfix-vr4120.
8223 - Register the mips16 hardware floating point stubs.
8224 - Register the gofast functions if selected using --enable-gofast. */
8226 #include "config/gofast.h"
8229 mips_init_libfuncs (void)
8231 if (TARGET_FIX_VR4120
)
8233 set_optab_libfunc (sdiv_optab
, SImode
, "__vr4120_divsi3");
8234 set_optab_libfunc (smod_optab
, SImode
, "__vr4120_modsi3");
8237 if (TARGET_MIPS16
&& mips16_hard_float
)
8239 set_optab_libfunc (add_optab
, SFmode
, "__mips16_addsf3");
8240 set_optab_libfunc (sub_optab
, SFmode
, "__mips16_subsf3");
8241 set_optab_libfunc (smul_optab
, SFmode
, "__mips16_mulsf3");
8242 set_optab_libfunc (sdiv_optab
, SFmode
, "__mips16_divsf3");
8244 set_optab_libfunc (eq_optab
, SFmode
, "__mips16_eqsf2");
8245 set_optab_libfunc (ne_optab
, SFmode
, "__mips16_nesf2");
8246 set_optab_libfunc (gt_optab
, SFmode
, "__mips16_gtsf2");
8247 set_optab_libfunc (ge_optab
, SFmode
, "__mips16_gesf2");
8248 set_optab_libfunc (lt_optab
, SFmode
, "__mips16_ltsf2");
8249 set_optab_libfunc (le_optab
, SFmode
, "__mips16_lesf2");
8251 set_conv_libfunc (sfix_optab
, SImode
, SFmode
, "__mips16_fix_truncsfsi");
8252 set_conv_libfunc (sfloat_optab
, SFmode
, SImode
, "__mips16_floatsisf");
8254 if (TARGET_DOUBLE_FLOAT
)
8256 set_optab_libfunc (add_optab
, DFmode
, "__mips16_adddf3");
8257 set_optab_libfunc (sub_optab
, DFmode
, "__mips16_subdf3");
8258 set_optab_libfunc (smul_optab
, DFmode
, "__mips16_muldf3");
8259 set_optab_libfunc (sdiv_optab
, DFmode
, "__mips16_divdf3");
8261 set_optab_libfunc (eq_optab
, DFmode
, "__mips16_eqdf2");
8262 set_optab_libfunc (ne_optab
, DFmode
, "__mips16_nedf2");
8263 set_optab_libfunc (gt_optab
, DFmode
, "__mips16_gtdf2");
8264 set_optab_libfunc (ge_optab
, DFmode
, "__mips16_gedf2");
8265 set_optab_libfunc (lt_optab
, DFmode
, "__mips16_ltdf2");
8266 set_optab_libfunc (le_optab
, DFmode
, "__mips16_ledf2");
8268 set_conv_libfunc (sext_optab
, DFmode
, SFmode
, "__mips16_extendsfdf2");
8269 set_conv_libfunc (trunc_optab
, SFmode
, DFmode
, "__mips16_truncdfsf2");
8271 set_conv_libfunc (sfix_optab
, SImode
, DFmode
, "__mips16_fix_truncdfsi");
8272 set_conv_libfunc (sfloat_optab
, DFmode
, SImode
, "__mips16_floatsidf");
8276 gofast_maybe_init_libfuncs ();
8279 /* Return a number assessing the cost of moving a register in class
8280 FROM to class TO. The classes are expressed using the enumeration
8281 values such as `GENERAL_REGS'. A value of 2 is the default; other
8282 values are interpreted relative to that.
8284 It is not required that the cost always equal 2 when FROM is the
8285 same as TO; on some machines it is expensive to move between
8286 registers if they are not general registers.
8288 If reload sees an insn consisting of a single `set' between two
8289 hard registers, and if `REGISTER_MOVE_COST' applied to their
8290 classes returns a value of 2, reload does not check to ensure that
8291 the constraints of the insn are met. Setting a cost of other than
8292 2 will allow reload to verify that the constraints are met. You
8293 should do this if the `movM' pattern's constraints do not allow
8296 ??? We make the cost of moving from HI/LO into general
8297 registers the same as for one of moving general registers to
8298 HI/LO for TARGET_MIPS16 in order to prevent allocating a
8299 pseudo to HI/LO. This might hurt optimizations though, it
8300 isn't clear if it is wise. And it might not work in all cases. We
8301 could solve the DImode LO reg problem by using a multiply, just
8302 like reload_{in,out}si. We could solve the SImode/HImode HI reg
8303 problem by using divide instructions. divu puts the remainder in
8304 the HI reg, so doing a divide by -1 will move the value in the HI
8305 reg for all values except -1. We could handle that case by using a
8306 signed divide, e.g. -1 / 2 (or maybe 1 / -2?). We'd have to emit
8307 a compare/branch to test the input value to see which instruction
8308 we need to use. This gets pretty messy, but it is feasible. */
8311 mips_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED
,
8312 enum reg_class to
, enum reg_class from
)
8314 if (from
== M16_REGS
&& GR_REG_CLASS_P (to
))
8316 else if (from
== M16_NA_REGS
&& GR_REG_CLASS_P (to
))
8318 else if (GR_REG_CLASS_P (from
))
8322 else if (to
== M16_NA_REGS
)
8324 else if (GR_REG_CLASS_P (to
))
8331 else if (to
== FP_REGS
)
8333 else if (to
== HI_REG
|| to
== LO_REG
|| to
== MD_REGS
)
8340 else if (COP_REG_CLASS_P (to
))
8344 } /* GR_REG_CLASS_P (from) */
8345 else if (from
== FP_REGS
)
8347 if (GR_REG_CLASS_P (to
))
8349 else if (to
== FP_REGS
)
8351 else if (to
== ST_REGS
)
8353 } /* from == FP_REGS */
8354 else if (from
== HI_REG
|| from
== LO_REG
|| from
== MD_REGS
)
8356 if (GR_REG_CLASS_P (to
))
8363 } /* from == HI_REG, etc. */
8364 else if (from
== ST_REGS
&& GR_REG_CLASS_P (to
))
8366 else if (COP_REG_CLASS_P (from
))
8369 } /* COP_REG_CLASS_P (from) */
8376 /* Return the length of INSN. LENGTH is the initial length computed by
8377 attributes in the machine-description file. */
8380 mips_adjust_insn_length (rtx insn
, int length
)
8382 /* A unconditional jump has an unfilled delay slot if it is not part
8383 of a sequence. A conditional jump normally has a delay slot, but
8384 does not on MIPS16. */
8385 if (CALL_P (insn
) || (TARGET_MIPS16
? simplejump_p (insn
) : JUMP_P (insn
)))
8388 /* See how many nops might be needed to avoid hardware hazards. */
8389 if (!cfun
->machine
->ignore_hazard_length_p
&& INSN_CODE (insn
) >= 0)
8390 switch (get_attr_hazard (insn
))
8404 /* All MIPS16 instructions are a measly two bytes. */
8412 /* Return an asm sequence to start a noat block and load the address
8413 of a label into $1. */
8416 mips_output_load_label (void)
8418 if (TARGET_EXPLICIT_RELOCS
)
8422 return "%[lw\t%@,%%got_page(%0)(%+)\n\taddiu\t%@,%@,%%got_ofst(%0)";
8425 return "%[ld\t%@,%%got_page(%0)(%+)\n\tdaddiu\t%@,%@,%%got_ofst(%0)";
8428 if (ISA_HAS_LOAD_DELAY
)
8429 return "%[lw\t%@,%%got(%0)(%+)%#\n\taddiu\t%@,%@,%%lo(%0)";
8430 return "%[lw\t%@,%%got(%0)(%+)\n\taddiu\t%@,%@,%%lo(%0)";
8434 if (Pmode
== DImode
)
8435 return "%[dla\t%@,%0";
8437 return "%[la\t%@,%0";
8442 /* Output assembly instructions to peform a conditional branch.
8444 INSN is the branch instruction. OPERANDS[0] is the condition.
8445 OPERANDS[1] is the target of the branch. OPERANDS[2] is the target
8446 of the first operand to the condition. If TWO_OPERANDS_P is
8447 nonzero the comparison takes two operands; OPERANDS[3] will be the
8450 If INVERTED_P is nonzero we are to branch if the condition does
8451 not hold. If FLOAT_P is nonzero this is a floating-point comparison.
8453 LENGTH is the length (in bytes) of the sequence we are to generate.
8454 That tells us whether to generate a simple conditional branch, or a
8455 reversed conditional branch around a `jr' instruction. */
8457 mips_output_conditional_branch (rtx insn
, rtx
*operands
, int two_operands_p
,
8458 int float_p
, int inverted_p
, int length
)
8460 static char buffer
[200];
8461 /* The kind of comparison we are doing. */
8462 enum rtx_code code
= GET_CODE (operands
[0]);
8463 /* Nonzero if the opcode for the comparison needs a `z' indicating
8464 that it is a comparison against zero. */
8466 /* A string to use in the assembly output to represent the first
8468 const char *op1
= "%z2";
8469 /* A string to use in the assembly output to represent the second
8470 operand. Use the hard-wired zero register if there's no second
8472 const char *op2
= (two_operands_p
? ",%z3" : ",%.");
8473 /* The operand-printing string for the comparison. */
8474 const char *const comp
= (float_p
? "%F0" : "%C0");
8475 /* The operand-printing string for the inverted comparison. */
8476 const char *const inverted_comp
= (float_p
? "%W0" : "%N0");
8478 /* The MIPS processors (for levels of the ISA at least two), have
8479 "likely" variants of each branch instruction. These instructions
8480 annul the instruction in the delay slot if the branch is not
8482 mips_branch_likely
= (final_sequence
&& INSN_ANNULLED_BRANCH_P (insn
));
8484 if (!two_operands_p
)
8486 /* To compute whether than A > B, for example, we normally
8487 subtract B from A and then look at the sign bit. But, if we
8488 are doing an unsigned comparison, and B is zero, we don't
8489 have to do the subtraction. Instead, we can just check to
8490 see if A is nonzero. Thus, we change the CODE here to
8491 reflect the simpler comparison operation. */
8503 /* A condition which will always be true. */
8509 /* A condition which will always be false. */
8515 /* Not a special case. */
8520 /* Relative comparisons are always done against zero. But
8521 equality comparisons are done between two operands, and therefore
8522 do not require a `z' in the assembly language output. */
8523 need_z_p
= (!float_p
&& code
!= EQ
&& code
!= NE
);
8524 /* For comparisons against zero, the zero is not provided
8529 /* Begin by terminating the buffer. That way we can always use
8530 strcat to add to it. */
8537 /* Just a simple conditional branch. */
8539 sprintf (buffer
, "%%*b%s%%?\t%%Z2%%1%%/",
8540 inverted_p
? inverted_comp
: comp
);
8542 sprintf (buffer
, "%%*b%s%s%%?\t%s%s,%%1%%/",
8543 inverted_p
? inverted_comp
: comp
,
8544 need_z_p
? "z" : "",
8554 /* Generate a reversed conditional branch around ` j'
8567 If the original branch was a likely branch, the delay slot
8568 must be executed only if the branch is taken, so generate:
8580 When generating PIC, instead of:
8593 rtx target
= gen_label_rtx ();
8595 orig_target
= operands
[1];
8596 operands
[1] = target
;
8597 /* Generate the reversed comparison. This takes four
8600 sprintf (buffer
, "%%*b%s\t%%Z2%%1",
8601 inverted_p
? comp
: inverted_comp
);
8603 sprintf (buffer
, "%%*b%s%s\t%s%s,%%1",
8604 inverted_p
? comp
: inverted_comp
,
8605 need_z_p
? "z" : "",
8608 output_asm_insn (buffer
, operands
);
8610 if (length
!= 16 && length
!= 28 && ! mips_branch_likely
)
8612 /* Output delay slot instruction. */
8613 rtx insn
= final_sequence
;
8614 final_scan_insn (XVECEXP (insn
, 0, 1), asm_out_file
,
8615 optimize
, 0, 1, NULL
);
8616 INSN_DELETED_P (XVECEXP (insn
, 0, 1)) = 1;
8619 output_asm_insn ("%#", 0);
8622 output_asm_insn ("j\t%0", &orig_target
);
8625 output_asm_insn (mips_output_load_label (), &orig_target
);
8626 output_asm_insn ("jr\t%@%]", 0);
8629 if (length
!= 16 && length
!= 28 && mips_branch_likely
)
8631 /* Output delay slot instruction. */
8632 rtx insn
= final_sequence
;
8633 final_scan_insn (XVECEXP (insn
, 0, 1), asm_out_file
,
8634 optimize
, 0, 1, NULL
);
8635 INSN_DELETED_P (XVECEXP (insn
, 0, 1)) = 1;
8638 output_asm_insn ("%#", 0);
8640 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "L",
8641 CODE_LABEL_NUMBER (target
));
8654 /* Used to output div or ddiv instruction DIVISION, which has the operands
8655 given by OPERANDS. Add in a divide-by-zero check if needed.
8657 When working around R4000 and R4400 errata, we need to make sure that
8658 the division is not immediately followed by a shift[1][2]. We also
8659 need to stop the division from being put into a branch delay slot[3].
8660 The easiest way to avoid both problems is to add a nop after the
8661 division. When a divide-by-zero check is needed, this nop can be
8662 used to fill the branch delay slot.
8664 [1] If a double-word or a variable shift executes immediately
8665 after starting an integer division, the shift may give an
8666 incorrect result. See quotations of errata #16 and #28 from
8667 "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
8668 in mips.md for details.
8670 [2] A similar bug to [1] exists for all revisions of the
8671 R4000 and the R4400 when run in an MC configuration.
8672 From "MIPS R4000MC Errata, Processor Revision 2.2 and 3.0":
8674 "19. In this following sequence:
8676 ddiv (or ddivu or div or divu)
8677 dsll32 (or dsrl32, dsra32)
8679 if an MPT stall occurs, while the divide is slipping the cpu
8680 pipeline, then the following double shift would end up with an
8683 Workaround: The compiler needs to avoid generating any
8684 sequence with divide followed by extended double shift."
8686 This erratum is also present in "MIPS R4400MC Errata, Processor
8687 Revision 1.0" and "MIPS R4400MC Errata, Processor Revision 2.0
8688 & 3.0" as errata #10 and #4, respectively.
8690 [3] From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
8691 (also valid for MIPS R4000MC processors):
8693 "52. R4000SC: This bug does not apply for the R4000PC.
8695 There are two flavors of this bug:
8697 1) If the instruction just after divide takes an RF exception
8698 (tlb-refill, tlb-invalid) and gets an instruction cache
8699 miss (both primary and secondary) and the line which is
8700 currently in secondary cache at this index had the first
8701 data word, where the bits 5..2 are set, then R4000 would
8702 get a wrong result for the div.
8707 ------------------- # end-of page. -tlb-refill
8712 ------------------- # end-of page. -tlb-invalid
8715 2) If the divide is in the taken branch delay slot, where the
8716 target takes RF exception and gets an I-cache miss for the
8717 exception vector or where I-cache miss occurs for the
8718 target address, under the above mentioned scenarios, the
8719 div would get wrong results.
8722 j r2 # to next page mapped or unmapped
8723 div r8,r9 # this bug would be there as long
8724 # as there is an ICache miss and
8725 nop # the "data pattern" is present
8728 beq r0, r0, NextPage # to Next page
8732 This bug is present for div, divu, ddiv, and ddivu
8735 Workaround: For item 1), OS could make sure that the next page
8736 after the divide instruction is also mapped. For item 2), the
8737 compiler could make sure that the divide instruction is not in
8738 the branch delay slot."
8740 These processors have PRId values of 0x00004220 and 0x00004300 for
8741 the R4000 and 0x00004400, 0x00004500 and 0x00004600 for the R4400. */
8744 mips_output_division (const char *division
, rtx
*operands
)
8749 if (TARGET_FIX_R4000
|| TARGET_FIX_R4400
)
8751 output_asm_insn (s
, operands
);
8754 if (TARGET_CHECK_ZERO_DIV
)
8758 output_asm_insn (s
, operands
);
8759 s
= "bnez\t%2,1f\n\tbreak\t7\n1:";
8763 output_asm_insn ("%(bne\t%2,%.,1f", operands
);
8764 output_asm_insn (s
, operands
);
8765 s
= "break\t7%)\n1:";
8771 /* Return true if GIVEN is the same as CANONICAL, or if it is CANONICAL
8772 with a final "000" replaced by "k". Ignore case.
8774 Note: this function is shared between GCC and GAS. */
8777 mips_strict_matching_cpu_name_p (const char *canonical
, const char *given
)
8779 while (*given
!= 0 && TOLOWER (*given
) == TOLOWER (*canonical
))
8780 given
++, canonical
++;
8782 return ((*given
== 0 && *canonical
== 0)
8783 || (strcmp (canonical
, "000") == 0 && strcasecmp (given
, "k") == 0));
8787 /* Return true if GIVEN matches CANONICAL, where GIVEN is a user-supplied
8788 CPU name. We've traditionally allowed a lot of variation here.
8790 Note: this function is shared between GCC and GAS. */
8793 mips_matching_cpu_name_p (const char *canonical
, const char *given
)
8795 /* First see if the name matches exactly, or with a final "000"
8797 if (mips_strict_matching_cpu_name_p (canonical
, given
))
8800 /* If not, try comparing based on numerical designation alone.
8801 See if GIVEN is an unadorned number, or 'r' followed by a number. */
8802 if (TOLOWER (*given
) == 'r')
8804 if (!ISDIGIT (*given
))
8807 /* Skip over some well-known prefixes in the canonical name,
8808 hoping to find a number there too. */
8809 if (TOLOWER (canonical
[0]) == 'v' && TOLOWER (canonical
[1]) == 'r')
8811 else if (TOLOWER (canonical
[0]) == 'r' && TOLOWER (canonical
[1]) == 'm')
8813 else if (TOLOWER (canonical
[0]) == 'r')
8816 return mips_strict_matching_cpu_name_p (canonical
, given
);
8820 /* Parse an option that takes the name of a processor as its argument.
8821 OPTION is the name of the option and CPU_STRING is the argument.
8822 Return the corresponding processor enumeration if the CPU_STRING is
8823 recognized, otherwise report an error and return null.
8825 A similar function exists in GAS. */
8827 static const struct mips_cpu_info
*
8828 mips_parse_cpu (const char *option
, const char *cpu_string
)
8830 const struct mips_cpu_info
*p
;
8833 /* In the past, we allowed upper-case CPU names, but it doesn't
8834 work well with the multilib machinery. */
8835 for (s
= cpu_string
; *s
!= 0; s
++)
8838 warning ("the cpu name must be lower case");
8842 /* 'from-abi' selects the most compatible architecture for the given
8843 ABI: MIPS I for 32-bit ABIs and MIPS III for 64-bit ABIs. For the
8844 EABIs, we have to decide whether we're using the 32-bit or 64-bit
8845 version. Look first at the -mgp options, if given, otherwise base
8846 the choice on MASK_64BIT in TARGET_DEFAULT. */
8847 if (strcasecmp (cpu_string
, "from-abi") == 0)
8848 return mips_cpu_info_from_isa (ABI_NEEDS_32BIT_REGS
? 1
8849 : ABI_NEEDS_64BIT_REGS
? 3
8850 : (TARGET_64BIT
? 3 : 1));
8852 /* 'default' has traditionally been a no-op. Probably not very useful. */
8853 if (strcasecmp (cpu_string
, "default") == 0)
8856 for (p
= mips_cpu_info_table
; p
->name
!= 0; p
++)
8857 if (mips_matching_cpu_name_p (p
->name
, cpu_string
))
8860 error ("bad value (%s) for %s", cpu_string
, option
);
8865 /* Return the processor associated with the given ISA level, or null
8866 if the ISA isn't valid. */
8868 static const struct mips_cpu_info
*
8869 mips_cpu_info_from_isa (int isa
)
8871 const struct mips_cpu_info
*p
;
8873 for (p
= mips_cpu_info_table
; p
->name
!= 0; p
++)
8880 /* Implement HARD_REGNO_NREGS. The size of FP registers is controlled
8881 by UNITS_PER_FPREG. The size of FP status registers is always 4, because
8882 they only hold condition code modes, and CCmode is always considered to
8883 be 4 bytes wide. All other registers are word sized. */
8886 mips_hard_regno_nregs (int regno
, enum machine_mode mode
)
8888 if (ST_REG_P (regno
))
8889 return ((GET_MODE_SIZE (mode
) + 3) / 4);
8890 else if (! FP_REG_P (regno
))
8891 return ((GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
);
8893 return ((GET_MODE_SIZE (mode
) + UNITS_PER_FPREG
- 1) / UNITS_PER_FPREG
);
8896 /* Implement TARGET_RETURN_IN_MEMORY. Under the old (i.e., 32 and O64 ABIs)
8897 all BLKmode objects are returned in memory. Under the new (N32 and
8898 64-bit MIPS ABIs) small structures are returned in a register.
8899 Objects with varying size must still be returned in memory, of
8903 mips_return_in_memory (tree type
, tree fndecl ATTRIBUTE_UNUSED
)
8906 return (TYPE_MODE (type
) == BLKmode
);
8908 return ((int_size_in_bytes (type
) > (2 * UNITS_PER_WORD
))
8909 || (int_size_in_bytes (type
) == -1));
8913 mips_strict_argument_naming (CUMULATIVE_ARGS
*ca ATTRIBUTE_UNUSED
)
8915 return !TARGET_OLDABI
;
8918 /* Return true if INSN is a multiply-add or multiply-subtract
8919 instruction and PREV assigns to the accumulator operand. */
8922 mips_linked_madd_p (rtx prev
, rtx insn
)
8926 x
= single_set (insn
);
8932 if (GET_CODE (x
) == PLUS
8933 && GET_CODE (XEXP (x
, 0)) == MULT
8934 && reg_set_p (XEXP (x
, 1), prev
))
8937 if (GET_CODE (x
) == MINUS
8938 && GET_CODE (XEXP (x
, 1)) == MULT
8939 && reg_set_p (XEXP (x
, 0), prev
))
8945 /* Used by TUNE_MACC_CHAINS to record the last scheduled instruction
8946 that may clobber hi or lo. */
8948 static rtx mips_macc_chains_last_hilo
;
8950 /* A TUNE_MACC_CHAINS helper function. Record that instruction INSN has
8951 been scheduled, updating mips_macc_chains_last_hilo appropriately. */
8954 mips_macc_chains_record (rtx insn
)
8956 if (get_attr_may_clobber_hilo (insn
))
8957 mips_macc_chains_last_hilo
= insn
;
8960 /* A TUNE_MACC_CHAINS helper function. Search ready queue READY, which
8961 has NREADY elements, looking for a multiply-add or multiply-subtract
8962 instruction that is cumulative with mips_macc_chains_last_hilo.
8963 If there is one, promote it ahead of anything else that might
8964 clobber hi or lo. */
8967 mips_macc_chains_reorder (rtx
*ready
, int nready
)
8971 if (mips_macc_chains_last_hilo
!= 0)
8972 for (i
= nready
- 1; i
>= 0; i
--)
8973 if (mips_linked_madd_p (mips_macc_chains_last_hilo
, ready
[i
]))
8975 for (j
= nready
- 1; j
> i
; j
--)
8976 if (recog_memoized (ready
[j
]) >= 0
8977 && get_attr_may_clobber_hilo (ready
[j
]))
8979 mips_promote_ready (ready
, i
, j
);
8986 /* The last instruction to be scheduled. */
8988 static rtx vr4130_last_insn
;
8990 /* A note_stores callback used by vr4130_true_reg_dependence_p. DATA
8991 points to an rtx that is initially an instruction. Nullify the rtx
8992 if the instruction uses the value of register X. */
8995 vr4130_true_reg_dependence_p_1 (rtx x
, rtx pat ATTRIBUTE_UNUSED
, void *data
)
8997 rtx
*insn_ptr
= data
;
9000 && reg_referenced_p (x
, PATTERN (*insn_ptr
)))
9004 /* Return true if there is true register dependence between vr4130_last_insn
9008 vr4130_true_reg_dependence_p (rtx insn
)
9010 note_stores (PATTERN (vr4130_last_insn
),
9011 vr4130_true_reg_dependence_p_1
, &insn
);
9015 /* A TUNE_MIPS4130 helper function. Given that INSN1 is at the head of
9016 the ready queue and that INSN2 is the instruction after it, return
9017 true if it is worth promoting INSN2 ahead of INSN1. Look for cases
9018 in which INSN1 and INSN2 can probably issue in parallel, but for
9019 which (INSN2, INSN1) should be less sensitive to instruction
9020 alignment than (INSN1, INSN2). See 4130.md for more details. */
9023 vr4130_swap_insns_p (rtx insn1
, rtx insn2
)
9027 /* Check for the following case:
9029 1) there is some other instruction X with an anti dependence on INSN1;
9030 2) X has a higher priority than INSN2; and
9031 3) X is an arithmetic instruction (and thus has no unit restrictions).
9033 If INSN1 is the last instruction blocking X, it would better to
9034 choose (INSN1, X) over (INSN2, INSN1). */
9035 for (dep
= INSN_DEPEND (insn1
); dep
!= 0; dep
= XEXP (dep
, 1))
9036 if (REG_NOTE_KIND (dep
) == REG_DEP_ANTI
9037 && INSN_PRIORITY (XEXP (dep
, 0)) > INSN_PRIORITY (insn2
)
9038 && recog_memoized (XEXP (dep
, 0)) >= 0
9039 && get_attr_vr4130_class (XEXP (dep
, 0)) == VR4130_CLASS_ALU
)
9042 if (vr4130_last_insn
!= 0
9043 && recog_memoized (insn1
) >= 0
9044 && recog_memoized (insn2
) >= 0)
9046 /* See whether INSN1 and INSN2 use different execution units,
9047 or if they are both ALU-type instructions. If so, they can
9048 probably execute in parallel. */
9049 enum attr_vr4130_class class1
= get_attr_vr4130_class (insn1
);
9050 enum attr_vr4130_class class2
= get_attr_vr4130_class (insn2
);
9051 if (class1
!= class2
|| class1
== VR4130_CLASS_ALU
)
9053 /* If only one of the instructions has a dependence on
9054 vr4130_last_insn, prefer to schedule the other one first. */
9055 bool dep1
= vr4130_true_reg_dependence_p (insn1
);
9056 bool dep2
= vr4130_true_reg_dependence_p (insn2
);
9060 /* Prefer to schedule INSN2 ahead of INSN1 if vr4130_last_insn
9061 is not an ALU-type instruction and if INSN1 uses the same
9062 execution unit. (Note that if this condition holds, we already
9063 know that INSN2 uses a different execution unit.) */
9064 if (class1
!= VR4130_CLASS_ALU
9065 && recog_memoized (vr4130_last_insn
) >= 0
9066 && class1
== get_attr_vr4130_class (vr4130_last_insn
))
9073 /* A TUNE_MIPS4130 helper function. (READY, NREADY) describes a ready
9074 queue with at least two instructions. Swap the first two if
9075 vr4130_swap_insns_p says that it could be worthwhile. */
9078 vr4130_reorder (rtx
*ready
, int nready
)
9080 if (vr4130_swap_insns_p (ready
[nready
- 1], ready
[nready
- 2]))
9081 mips_promote_ready (ready
, nready
- 2, nready
- 1);
9084 /* Remove the instruction at index LOWER from ready queue READY and
9085 reinsert it in front of the instruction at index HIGHER. LOWER must
9089 mips_promote_ready (rtx
*ready
, int lower
, int higher
)
9094 new_head
= ready
[lower
];
9095 for (i
= lower
; i
< higher
; i
++)
9096 ready
[i
] = ready
[i
+ 1];
9097 ready
[i
] = new_head
;
9100 /* Implement TARGET_SCHED_REORDER. */
9103 mips_sched_reorder (FILE *file ATTRIBUTE_UNUSED
, int verbose ATTRIBUTE_UNUSED
,
9104 rtx
*ready
, int *nreadyp
, int cycle
)
9106 if (!reload_completed
&& TUNE_MACC_CHAINS
)
9109 mips_macc_chains_last_hilo
= 0;
9111 mips_macc_chains_reorder (ready
, *nreadyp
);
9113 if (reload_completed
&& TUNE_MIPS4130
&& !TARGET_VR4130_ALIGN
)
9116 vr4130_last_insn
= 0;
9118 vr4130_reorder (ready
, *nreadyp
);
9120 return mips_issue_rate ();
9123 /* Implement TARGET_SCHED_VARIABLE_ISSUE. */
9126 mips_variable_issue (FILE *file ATTRIBUTE_UNUSED
, int verbose ATTRIBUTE_UNUSED
,
9129 switch (GET_CODE (PATTERN (insn
)))
9133 /* Don't count USEs and CLOBBERs against the issue rate. */
9138 if (!reload_completed
&& TUNE_MACC_CHAINS
)
9139 mips_macc_chains_record (insn
);
9140 vr4130_last_insn
= insn
;
9146 /* Implement TARGET_SCHED_ADJUST_COST. We assume that anti and output
9147 dependencies have no cost. */
9150 mips_adjust_cost (rtx insn ATTRIBUTE_UNUSED
, rtx link
,
9151 rtx dep ATTRIBUTE_UNUSED
, int cost
)
9153 if (REG_NOTE_KIND (link
) != 0)
9158 /* Return the number of instructions that can be issued per cycle. */
9161 mips_issue_rate (void)
9165 case PROCESSOR_R4130
:
9166 case PROCESSOR_R5400
:
9167 case PROCESSOR_R5500
:
9168 case PROCESSOR_R7000
:
9169 case PROCESSOR_R9000
:
9173 /* This is actually 4, but we get better performance if we claim 3.
9174 This is partly because of unwanted speculative code motion with the
9175 larger number, and partly because in most common cases we can't
9176 reach the theoretical max of 4. */
9187 /* Implements TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD. This should
9188 be as wide as the scheduling freedom in the DFA. */
9191 mips_multipass_dfa_lookahead (void)
9193 /* Can schedule up to 4 of the 6 function units in any one cycle. */
9194 if (mips_tune
== PROCESSOR_SB1
)
9200 /* Given that we have an rtx of the form (prefetch ... WRITE LOCALITY),
9201 return the first operand of the associated "pref" or "prefx" insn. */
9204 mips_prefetch_cookie (rtx write
, rtx locality
)
9206 /* store_streamed / load_streamed. */
9207 if (INTVAL (locality
) <= 0)
9208 return GEN_INT (INTVAL (write
) + 4);
9211 if (INTVAL (locality
) <= 2)
9214 /* store_retained / load_retained. */
9215 return GEN_INT (INTVAL (write
) + 6);
9218 /* MIPS builtin function support. */
9220 struct builtin_description
9222 /* Instruction code. */
9223 enum insn_code icode
;
9224 /* Builtin function name. */
9227 enum mips_builtins code
;
9228 /* Function type. */
9229 enum mips_function_type ftype
;
9230 /* The target flag required for this builtin function. */
9234 /* NOTE: The order of mips_bdesc[] must be the same as the order of
9235 enum mips_builtins{} in mips.h. */
9236 static const struct builtin_description mips_bdesc
[] =
9238 { CODE_FOR_mips_pll_ps
, "__builtin_mips_pll_ps", MIPS_BUILTIN_PLL_PS
,
9239 MIPS_V2SF_FTYPE_V2SF_V2SF
, MASK_PAIRED_SINGLE
},
9240 { CODE_FOR_mips_pul_ps
, "__builtin_mips_pul_ps", MIPS_BUILTIN_PUL_PS
,
9241 MIPS_V2SF_FTYPE_V2SF_V2SF
, MASK_PAIRED_SINGLE
},
9242 { CODE_FOR_mips_plu_ps
, "__builtin_mips_plu_ps", MIPS_BUILTIN_PLU_PS
,
9243 MIPS_V2SF_FTYPE_V2SF_V2SF
, MASK_PAIRED_SINGLE
},
9244 { CODE_FOR_mips_puu_ps
, "__builtin_mips_puu_ps", MIPS_BUILTIN_PUU_PS
,
9245 MIPS_V2SF_FTYPE_V2SF_V2SF
, MASK_PAIRED_SINGLE
},
9246 { CODE_FOR_mips_cvt_ps_s
, "__builtin_mips_cvt_ps_s", MIPS_BUILTIN_CVT_PS_S
,
9247 MIPS_V2SF_FTYPE_SF_SF
, MASK_PAIRED_SINGLE
},
9248 { CODE_FOR_mips_cvt_s_pl
, "__builtin_mips_cvt_s_pl", MIPS_BUILTIN_CVT_S_PL
,
9249 MIPS_SF_FTYPE_V2SF
, MASK_PAIRED_SINGLE
},
9250 { CODE_FOR_mips_cvt_s_pu
, "__builtin_mips_cvt_s_pu", MIPS_BUILTIN_CVT_S_PU
,
9251 MIPS_SF_FTYPE_V2SF
, MASK_PAIRED_SINGLE
},
9252 { CODE_FOR_absv2sf2
, "__builtin_mips_abs_ps", MIPS_BUILTIN_ABS_PS
,
9253 MIPS_V2SF_FTYPE_V2SF
, MASK_PAIRED_SINGLE
},
9254 { CODE_FOR_mips_alnv_ps
, "__builtin_mips_alnv_ps", MIPS_BUILTIN_ALNV_PS
,
9255 MIPS_V2SF_FTYPE_V2SF_V2SF_INT
, MASK_PAIRED_SINGLE
},
9257 { CODE_FOR_mips_addr_ps
, "__builtin_mips_addr_ps", MIPS_BUILTIN_ADDR_PS
,
9258 MIPS_V2SF_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9259 { CODE_FOR_mips_mulr_ps
, "__builtin_mips_mulr_ps", MIPS_BUILTIN_MULR_PS
,
9260 MIPS_V2SF_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9261 { CODE_FOR_mips_cvt_pw_ps
, "__builtin_mips_cvt_pw_ps",
9262 MIPS_BUILTIN_CVT_PW_PS
, MIPS_V2SF_FTYPE_V2SF
, MASK_MIPS3D
},
9263 { CODE_FOR_mips_cvt_ps_pw
, "__builtin_mips_cvt_ps_pw",
9264 MIPS_BUILTIN_CVT_PS_PW
, MIPS_V2SF_FTYPE_V2SF
, MASK_MIPS3D
},
9266 { CODE_FOR_mips_recip1_s
, "__builtin_mips_recip1_s", MIPS_BUILTIN_RECIP1_S
,
9267 MIPS_SF_FTYPE_SF
, MASK_MIPS3D
},
9268 { CODE_FOR_mips_recip1_d
, "__builtin_mips_recip1_d", MIPS_BUILTIN_RECIP1_D
,
9269 MIPS_DF_FTYPE_DF
, MASK_MIPS3D
},
9270 { CODE_FOR_mips_recip1_ps
, "__builtin_mips_recip1_ps",
9271 MIPS_BUILTIN_RECIP1_PS
, MIPS_V2SF_FTYPE_V2SF
, MASK_MIPS3D
},
9272 { CODE_FOR_mips_recip2_s
, "__builtin_mips_recip2_s", MIPS_BUILTIN_RECIP2_S
,
9273 MIPS_SF_FTYPE_SF_SF
, MASK_MIPS3D
},
9274 { CODE_FOR_mips_recip2_d
, "__builtin_mips_recip2_d", MIPS_BUILTIN_RECIP2_D
,
9275 MIPS_DF_FTYPE_DF_DF
, MASK_MIPS3D
},
9276 { CODE_FOR_mips_recip2_ps
, "__builtin_mips_recip2_ps",
9277 MIPS_BUILTIN_RECIP2_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9279 { CODE_FOR_mips_rsqrt1_s
, "__builtin_mips_rsqrt1_s", MIPS_BUILTIN_RSQRT1_S
,
9280 MIPS_SF_FTYPE_SF
, MASK_MIPS3D
},
9281 { CODE_FOR_mips_rsqrt1_d
, "__builtin_mips_rsqrt1_d", MIPS_BUILTIN_RSQRT1_D
,
9282 MIPS_DF_FTYPE_DF
, MASK_MIPS3D
},
9283 { CODE_FOR_mips_rsqrt1_ps
, "__builtin_mips_rsqrt1_ps",
9284 MIPS_BUILTIN_RSQRT1_PS
, MIPS_V2SF_FTYPE_V2SF
, MASK_MIPS3D
},
9285 { CODE_FOR_mips_rsqrt2_s
, "__builtin_mips_rsqrt2_s", MIPS_BUILTIN_RSQRT2_S
,
9286 MIPS_SF_FTYPE_SF_SF
, MASK_MIPS3D
},
9287 { CODE_FOR_mips_rsqrt2_d
, "__builtin_mips_rsqrt2_d", MIPS_BUILTIN_RSQRT2_D
,
9288 MIPS_DF_FTYPE_DF_DF
, MASK_MIPS3D
},
9289 { CODE_FOR_mips_rsqrt2_ps
, "__builtin_mips_rsqrt2_ps",
9290 MIPS_BUILTIN_RSQRT2_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9292 { CODE_FOR_mips_c_f_ps
, "__builtin_mips_any_c_f_ps", MIPS_BUILTIN_ANY_C_F_PS
,
9293 MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9294 { CODE_FOR_mips_c_f_ps
, "__builtin_mips_upper_c_f_ps",
9295 MIPS_BUILTIN_UPPER_C_F_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_PAIRED_SINGLE
},
9296 { CODE_FOR_mips_c_f_ps
, "__builtin_mips_lower_c_f_ps",
9297 MIPS_BUILTIN_LOWER_C_F_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_PAIRED_SINGLE
},
9298 { CODE_FOR_mips_c_f_ps
, "__builtin_mips_all_c_f_ps", MIPS_BUILTIN_ALL_C_F_PS
,
9299 MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9300 { CODE_FOR_mips_c_un_ps
, "__builtin_mips_any_c_un_ps",
9301 MIPS_BUILTIN_ANY_C_UN_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9302 { CODE_FOR_mips_c_un_ps
, "__builtin_mips_upper_c_un_ps",
9303 MIPS_BUILTIN_UPPER_C_UN_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_PAIRED_SINGLE
},
9304 { CODE_FOR_mips_c_un_ps
, "__builtin_mips_lower_c_un_ps",
9305 MIPS_BUILTIN_LOWER_C_UN_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_PAIRED_SINGLE
},
9306 { CODE_FOR_mips_c_un_ps
, "__builtin_mips_all_c_un_ps",
9307 MIPS_BUILTIN_ALL_C_UN_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9308 { CODE_FOR_mips_c_eq_ps
, "__builtin_mips_any_c_eq_ps",
9309 MIPS_BUILTIN_ANY_C_EQ_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9310 { CODE_FOR_mips_c_eq_ps
, "__builtin_mips_upper_c_eq_ps",
9311 MIPS_BUILTIN_UPPER_C_EQ_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_PAIRED_SINGLE
},
9312 { CODE_FOR_mips_c_eq_ps
, "__builtin_mips_lower_c_eq_ps",
9313 MIPS_BUILTIN_LOWER_C_EQ_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_PAIRED_SINGLE
},
9314 { CODE_FOR_mips_c_eq_ps
, "__builtin_mips_all_c_eq_ps",
9315 MIPS_BUILTIN_ALL_C_EQ_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9316 { CODE_FOR_mips_c_ueq_ps
, "__builtin_mips_any_c_ueq_ps",
9317 MIPS_BUILTIN_ANY_C_UEQ_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9318 { CODE_FOR_mips_c_ueq_ps
, "__builtin_mips_upper_c_ueq_ps",
9319 MIPS_BUILTIN_UPPER_C_UEQ_PS
, MIPS_INT_FTYPE_V2SF_V2SF
,
9320 MASK_PAIRED_SINGLE
},
9321 { CODE_FOR_mips_c_ueq_ps
, "__builtin_mips_lower_c_ueq_ps",
9322 MIPS_BUILTIN_LOWER_C_UEQ_PS
, MIPS_INT_FTYPE_V2SF_V2SF
,
9323 MASK_PAIRED_SINGLE
},
9324 { CODE_FOR_mips_c_ueq_ps
, "__builtin_mips_all_c_ueq_ps",
9325 MIPS_BUILTIN_ALL_C_UEQ_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9326 { CODE_FOR_mips_c_olt_ps
, "__builtin_mips_any_c_olt_ps",
9327 MIPS_BUILTIN_ANY_C_OLT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9328 { CODE_FOR_mips_c_olt_ps
, "__builtin_mips_upper_c_olt_ps",
9329 MIPS_BUILTIN_UPPER_C_OLT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
,
9330 MASK_PAIRED_SINGLE
},
9331 { CODE_FOR_mips_c_olt_ps
, "__builtin_mips_lower_c_olt_ps",
9332 MIPS_BUILTIN_LOWER_C_OLT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
,
9333 MASK_PAIRED_SINGLE
},
9334 { CODE_FOR_mips_c_olt_ps
, "__builtin_mips_all_c_olt_ps",
9335 MIPS_BUILTIN_ALL_C_OLT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9336 { CODE_FOR_mips_c_ult_ps
, "__builtin_mips_any_c_ult_ps",
9337 MIPS_BUILTIN_ANY_C_ULT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9338 { CODE_FOR_mips_c_ult_ps
, "__builtin_mips_upper_c_ult_ps",
9339 MIPS_BUILTIN_UPPER_C_ULT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
,
9340 MASK_PAIRED_SINGLE
},
9341 { CODE_FOR_mips_c_ult_ps
, "__builtin_mips_lower_c_ult_ps",
9342 MIPS_BUILTIN_LOWER_C_ULT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
,
9343 MASK_PAIRED_SINGLE
},
9344 { CODE_FOR_mips_c_ult_ps
, "__builtin_mips_all_c_ult_ps",
9345 MIPS_BUILTIN_ALL_C_ULT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9346 { CODE_FOR_mips_c_ole_ps
, "__builtin_mips_any_c_ole_ps",
9347 MIPS_BUILTIN_ANY_C_OLE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9348 { CODE_FOR_mips_c_ole_ps
, "__builtin_mips_upper_c_ole_ps",
9349 MIPS_BUILTIN_UPPER_C_OLE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
,
9350 MASK_PAIRED_SINGLE
},
9351 { CODE_FOR_mips_c_ole_ps
, "__builtin_mips_lower_c_ole_ps",
9352 MIPS_BUILTIN_LOWER_C_OLE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
,
9353 MASK_PAIRED_SINGLE
},
9354 { CODE_FOR_mips_c_ole_ps
, "__builtin_mips_all_c_ole_ps",
9355 MIPS_BUILTIN_ALL_C_OLE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9356 { CODE_FOR_mips_c_ule_ps
, "__builtin_mips_any_c_ule_ps",
9357 MIPS_BUILTIN_ANY_C_ULE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9358 { CODE_FOR_mips_c_ule_ps
, "__builtin_mips_upper_c_ule_ps",
9359 MIPS_BUILTIN_UPPER_C_ULE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
,
9360 MASK_PAIRED_SINGLE
},
9361 { CODE_FOR_mips_c_ule_ps
, "__builtin_mips_lower_c_ule_ps",
9362 MIPS_BUILTIN_LOWER_C_ULE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
,
9363 MASK_PAIRED_SINGLE
},
9364 { CODE_FOR_mips_c_ule_ps
, "__builtin_mips_all_c_ule_ps",
9365 MIPS_BUILTIN_ALL_C_ULE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9366 { CODE_FOR_mips_c_sf_ps
, "__builtin_mips_any_c_sf_ps",
9367 MIPS_BUILTIN_ANY_C_SF_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9368 { CODE_FOR_mips_c_sf_ps
, "__builtin_mips_upper_c_sf_ps",
9369 MIPS_BUILTIN_UPPER_C_SF_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_PAIRED_SINGLE
},
9370 { CODE_FOR_mips_c_sf_ps
, "__builtin_mips_lower_c_sf_ps",
9371 MIPS_BUILTIN_LOWER_C_SF_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_PAIRED_SINGLE
},
9372 { CODE_FOR_mips_c_sf_ps
, "__builtin_mips_all_c_sf_ps",
9373 MIPS_BUILTIN_ALL_C_SF_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9374 { CODE_FOR_mips_c_ngle_ps
, "__builtin_mips_any_c_ngle_ps",
9375 MIPS_BUILTIN_ANY_C_NGLE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9376 { CODE_FOR_mips_c_ngle_ps
, "__builtin_mips_upper_c_ngle_ps",
9377 MIPS_BUILTIN_UPPER_C_NGLE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
,
9378 MASK_PAIRED_SINGLE
},
9379 { CODE_FOR_mips_c_ngle_ps
, "__builtin_mips_lower_c_ngle_ps",
9380 MIPS_BUILTIN_LOWER_C_NGLE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
,
9381 MASK_PAIRED_SINGLE
},
9382 { CODE_FOR_mips_c_ngle_ps
, "__builtin_mips_all_c_ngle_ps",
9383 MIPS_BUILTIN_ALL_C_NGLE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9384 { CODE_FOR_mips_c_seq_ps
, "__builtin_mips_any_c_seq_ps",
9385 MIPS_BUILTIN_ANY_C_SEQ_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9386 { CODE_FOR_mips_c_seq_ps
, "__builtin_mips_upper_c_seq_ps",
9387 MIPS_BUILTIN_UPPER_C_SEQ_PS
, MIPS_INT_FTYPE_V2SF_V2SF
,
9388 MASK_PAIRED_SINGLE
},
9389 { CODE_FOR_mips_c_seq_ps
, "__builtin_mips_lower_c_seq_ps",
9390 MIPS_BUILTIN_LOWER_C_SEQ_PS
, MIPS_INT_FTYPE_V2SF_V2SF
,
9391 MASK_PAIRED_SINGLE
},
9392 { CODE_FOR_mips_c_seq_ps
, "__builtin_mips_all_c_seq_ps",
9393 MIPS_BUILTIN_ALL_C_SEQ_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9394 { CODE_FOR_mips_c_ngl_ps
, "__builtin_mips_any_c_ngl_ps",
9395 MIPS_BUILTIN_ANY_C_NGL_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9396 { CODE_FOR_mips_c_ngl_ps
, "__builtin_mips_upper_c_ngl_ps",
9397 MIPS_BUILTIN_UPPER_C_NGL_PS
, MIPS_INT_FTYPE_V2SF_V2SF
,
9398 MASK_PAIRED_SINGLE
},
9399 { CODE_FOR_mips_c_ngl_ps
, "__builtin_mips_lower_c_ngl_ps",
9400 MIPS_BUILTIN_LOWER_C_NGL_PS
, MIPS_INT_FTYPE_V2SF_V2SF
,
9401 MASK_PAIRED_SINGLE
},
9402 { CODE_FOR_mips_c_ngl_ps
, "__builtin_mips_all_c_ngl_ps",
9403 MIPS_BUILTIN_ALL_C_NGL_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9404 { CODE_FOR_mips_c_lt_ps
, "__builtin_mips_any_c_lt_ps",
9405 MIPS_BUILTIN_ANY_C_LT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9406 { CODE_FOR_mips_c_lt_ps
, "__builtin_mips_upper_c_lt_ps",
9407 MIPS_BUILTIN_UPPER_C_LT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_PAIRED_SINGLE
},
9408 { CODE_FOR_mips_c_lt_ps
, "__builtin_mips_lower_c_lt_ps",
9409 MIPS_BUILTIN_LOWER_C_LT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_PAIRED_SINGLE
},
9410 { CODE_FOR_mips_c_lt_ps
, "__builtin_mips_all_c_lt_ps",
9411 MIPS_BUILTIN_ALL_C_LT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9412 { CODE_FOR_mips_c_nge_ps
, "__builtin_mips_any_c_nge_ps",
9413 MIPS_BUILTIN_ANY_C_NGE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9414 { CODE_FOR_mips_c_nge_ps
, "__builtin_mips_upper_c_nge_ps",
9415 MIPS_BUILTIN_UPPER_C_NGE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
,
9416 MASK_PAIRED_SINGLE
},
9417 { CODE_FOR_mips_c_nge_ps
, "__builtin_mips_lower_c_nge_ps",
9418 MIPS_BUILTIN_LOWER_C_NGE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
,
9419 MASK_PAIRED_SINGLE
},
9420 { CODE_FOR_mips_c_nge_ps
, "__builtin_mips_all_c_nge_ps",
9421 MIPS_BUILTIN_ALL_C_NGE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9422 { CODE_FOR_mips_c_le_ps
, "__builtin_mips_any_c_le_ps",
9423 MIPS_BUILTIN_ANY_C_LE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9424 { CODE_FOR_mips_c_le_ps
, "__builtin_mips_upper_c_le_ps",
9425 MIPS_BUILTIN_UPPER_C_LE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_PAIRED_SINGLE
},
9426 { CODE_FOR_mips_c_le_ps
, "__builtin_mips_lower_c_le_ps",
9427 MIPS_BUILTIN_LOWER_C_LE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_PAIRED_SINGLE
},
9428 { CODE_FOR_mips_c_le_ps
, "__builtin_mips_all_c_le_ps",
9429 MIPS_BUILTIN_ALL_C_LE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9430 { CODE_FOR_mips_c_ngt_ps
, "__builtin_mips_any_c_ngt_ps",
9431 MIPS_BUILTIN_ANY_C_NGT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9432 { CODE_FOR_mips_c_ngt_ps
, "__builtin_mips_upper_c_ngt_ps",
9433 MIPS_BUILTIN_UPPER_C_NGT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
,
9434 MASK_PAIRED_SINGLE
},
9435 { CODE_FOR_mips_c_ngt_ps
, "__builtin_mips_lower_c_ngt_ps",
9436 MIPS_BUILTIN_LOWER_C_NGT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
,
9437 MASK_PAIRED_SINGLE
},
9438 { CODE_FOR_mips_c_ngt_ps
, "__builtin_mips_all_c_ngt_ps",
9439 MIPS_BUILTIN_ALL_C_NGT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9441 { CODE_FOR_mips_cabs_f_ps
, "__builtin_mips_any_cabs_f_ps",
9442 MIPS_BUILTIN_ANY_CABS_F_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9443 { CODE_FOR_mips_cabs_f_ps
, "__builtin_mips_upper_cabs_f_ps",
9444 MIPS_BUILTIN_UPPER_CABS_F_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9445 { CODE_FOR_mips_cabs_f_ps
, "__builtin_mips_lower_cabs_f_ps",
9446 MIPS_BUILTIN_LOWER_CABS_F_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9447 { CODE_FOR_mips_cabs_f_ps
, "__builtin_mips_all_cabs_f_ps",
9448 MIPS_BUILTIN_ALL_CABS_F_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9449 { CODE_FOR_mips_cabs_un_ps
, "__builtin_mips_any_cabs_un_ps",
9450 MIPS_BUILTIN_ANY_CABS_UN_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9451 { CODE_FOR_mips_cabs_un_ps
, "__builtin_mips_upper_cabs_un_ps",
9452 MIPS_BUILTIN_UPPER_CABS_UN_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9453 { CODE_FOR_mips_cabs_un_ps
, "__builtin_mips_lower_cabs_un_ps",
9454 MIPS_BUILTIN_LOWER_CABS_UN_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9455 { CODE_FOR_mips_cabs_un_ps
, "__builtin_mips_all_cabs_un_ps",
9456 MIPS_BUILTIN_ALL_CABS_UN_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9457 { CODE_FOR_mips_cabs_eq_ps
, "__builtin_mips_any_cabs_eq_ps",
9458 MIPS_BUILTIN_ANY_CABS_EQ_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9459 { CODE_FOR_mips_cabs_eq_ps
, "__builtin_mips_upper_cabs_eq_ps",
9460 MIPS_BUILTIN_UPPER_CABS_EQ_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9461 { CODE_FOR_mips_cabs_eq_ps
, "__builtin_mips_lower_cabs_eq_ps",
9462 MIPS_BUILTIN_LOWER_CABS_EQ_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9463 { CODE_FOR_mips_cabs_eq_ps
, "__builtin_mips_all_cabs_eq_ps",
9464 MIPS_BUILTIN_ALL_CABS_EQ_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9465 { CODE_FOR_mips_cabs_ueq_ps
, "__builtin_mips_any_cabs_ueq_ps",
9466 MIPS_BUILTIN_ANY_CABS_UEQ_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9467 { CODE_FOR_mips_cabs_ueq_ps
, "__builtin_mips_upper_cabs_ueq_ps",
9468 MIPS_BUILTIN_UPPER_CABS_UEQ_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9469 { CODE_FOR_mips_cabs_ueq_ps
, "__builtin_mips_lower_cabs_ueq_ps",
9470 MIPS_BUILTIN_LOWER_CABS_UEQ_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9471 { CODE_FOR_mips_cabs_ueq_ps
, "__builtin_mips_all_cabs_ueq_ps",
9472 MIPS_BUILTIN_ALL_CABS_UEQ_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9473 { CODE_FOR_mips_cabs_olt_ps
, "__builtin_mips_any_cabs_olt_ps",
9474 MIPS_BUILTIN_ANY_CABS_OLT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9475 { CODE_FOR_mips_cabs_olt_ps
, "__builtin_mips_upper_cabs_olt_ps",
9476 MIPS_BUILTIN_UPPER_CABS_OLT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9477 { CODE_FOR_mips_cabs_olt_ps
, "__builtin_mips_lower_cabs_olt_ps",
9478 MIPS_BUILTIN_LOWER_CABS_OLT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9479 { CODE_FOR_mips_cabs_olt_ps
, "__builtin_mips_all_cabs_olt_ps",
9480 MIPS_BUILTIN_ALL_CABS_OLT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9481 { CODE_FOR_mips_cabs_ult_ps
, "__builtin_mips_any_cabs_ult_ps",
9482 MIPS_BUILTIN_ANY_CABS_ULT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9483 { CODE_FOR_mips_cabs_ult_ps
, "__builtin_mips_upper_cabs_ult_ps",
9484 MIPS_BUILTIN_UPPER_CABS_ULT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9485 { CODE_FOR_mips_cabs_ult_ps
, "__builtin_mips_lower_cabs_ult_ps",
9486 MIPS_BUILTIN_LOWER_CABS_ULT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9487 { CODE_FOR_mips_cabs_ult_ps
, "__builtin_mips_all_cabs_ult_ps",
9488 MIPS_BUILTIN_ALL_CABS_ULT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9489 { CODE_FOR_mips_cabs_ole_ps
, "__builtin_mips_any_cabs_ole_ps",
9490 MIPS_BUILTIN_ANY_CABS_OLE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9491 { CODE_FOR_mips_cabs_ole_ps
, "__builtin_mips_upper_cabs_ole_ps",
9492 MIPS_BUILTIN_UPPER_CABS_OLE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9493 { CODE_FOR_mips_cabs_ole_ps
, "__builtin_mips_lower_cabs_ole_ps",
9494 MIPS_BUILTIN_LOWER_CABS_OLE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9495 { CODE_FOR_mips_cabs_ole_ps
, "__builtin_mips_all_cabs_ole_ps",
9496 MIPS_BUILTIN_ALL_CABS_OLE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9497 { CODE_FOR_mips_cabs_ule_ps
, "__builtin_mips_any_cabs_ule_ps",
9498 MIPS_BUILTIN_ANY_CABS_ULE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9499 { CODE_FOR_mips_cabs_ule_ps
, "__builtin_mips_upper_cabs_ule_ps",
9500 MIPS_BUILTIN_UPPER_CABS_ULE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9501 { CODE_FOR_mips_cabs_ule_ps
, "__builtin_mips_lower_cabs_ule_ps",
9502 MIPS_BUILTIN_LOWER_CABS_ULE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9503 { CODE_FOR_mips_cabs_ule_ps
, "__builtin_mips_all_cabs_ule_ps",
9504 MIPS_BUILTIN_ALL_CABS_ULE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9505 { CODE_FOR_mips_cabs_sf_ps
, "__builtin_mips_any_cabs_sf_ps",
9506 MIPS_BUILTIN_ANY_CABS_SF_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9507 { CODE_FOR_mips_cabs_sf_ps
, "__builtin_mips_upper_cabs_sf_ps",
9508 MIPS_BUILTIN_UPPER_CABS_SF_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9509 { CODE_FOR_mips_cabs_sf_ps
, "__builtin_mips_lower_cabs_sf_ps",
9510 MIPS_BUILTIN_LOWER_CABS_SF_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9511 { CODE_FOR_mips_cabs_sf_ps
, "__builtin_mips_all_cabs_sf_ps",
9512 MIPS_BUILTIN_ALL_CABS_SF_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9513 { CODE_FOR_mips_cabs_ngle_ps
, "__builtin_mips_any_cabs_ngle_ps",
9514 MIPS_BUILTIN_ANY_CABS_NGLE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9515 { CODE_FOR_mips_cabs_ngle_ps
, "__builtin_mips_upper_cabs_ngle_ps",
9516 MIPS_BUILTIN_UPPER_CABS_NGLE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9517 { CODE_FOR_mips_cabs_ngle_ps
, "__builtin_mips_lower_cabs_ngle_ps",
9518 MIPS_BUILTIN_LOWER_CABS_NGLE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9519 { CODE_FOR_mips_cabs_ngle_ps
, "__builtin_mips_all_cabs_ngle_ps",
9520 MIPS_BUILTIN_ALL_CABS_NGLE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9521 { CODE_FOR_mips_cabs_seq_ps
, "__builtin_mips_any_cabs_seq_ps",
9522 MIPS_BUILTIN_ANY_CABS_SEQ_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9523 { CODE_FOR_mips_cabs_seq_ps
, "__builtin_mips_upper_cabs_seq_ps",
9524 MIPS_BUILTIN_UPPER_CABS_SEQ_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9525 { CODE_FOR_mips_cabs_seq_ps
, "__builtin_mips_lower_cabs_seq_ps",
9526 MIPS_BUILTIN_LOWER_CABS_SEQ_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9527 { CODE_FOR_mips_cabs_seq_ps
, "__builtin_mips_all_cabs_seq_ps",
9528 MIPS_BUILTIN_ALL_CABS_SEQ_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9529 { CODE_FOR_mips_cabs_ngl_ps
, "__builtin_mips_any_cabs_ngl_ps",
9530 MIPS_BUILTIN_ANY_CABS_NGL_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9531 { CODE_FOR_mips_cabs_ngl_ps
, "__builtin_mips_upper_cabs_ngl_ps",
9532 MIPS_BUILTIN_UPPER_CABS_NGL_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9533 { CODE_FOR_mips_cabs_ngl_ps
, "__builtin_mips_lower_cabs_ngl_ps",
9534 MIPS_BUILTIN_LOWER_CABS_NGL_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9535 { CODE_FOR_mips_cabs_ngl_ps
, "__builtin_mips_all_cabs_ngl_ps",
9536 MIPS_BUILTIN_ALL_CABS_NGL_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9537 { CODE_FOR_mips_cabs_lt_ps
, "__builtin_mips_any_cabs_lt_ps",
9538 MIPS_BUILTIN_ANY_CABS_LT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9539 { CODE_FOR_mips_cabs_lt_ps
, "__builtin_mips_upper_cabs_lt_ps",
9540 MIPS_BUILTIN_UPPER_CABS_LT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9541 { CODE_FOR_mips_cabs_lt_ps
, "__builtin_mips_lower_cabs_lt_ps",
9542 MIPS_BUILTIN_LOWER_CABS_LT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9543 { CODE_FOR_mips_cabs_lt_ps
, "__builtin_mips_all_cabs_lt_ps",
9544 MIPS_BUILTIN_ALL_CABS_LT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9545 { CODE_FOR_mips_cabs_nge_ps
, "__builtin_mips_any_cabs_nge_ps",
9546 MIPS_BUILTIN_ANY_CABS_NGE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9547 { CODE_FOR_mips_cabs_nge_ps
, "__builtin_mips_upper_cabs_nge_ps",
9548 MIPS_BUILTIN_UPPER_CABS_NGE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9549 { CODE_FOR_mips_cabs_nge_ps
, "__builtin_mips_lower_cabs_nge_ps",
9550 MIPS_BUILTIN_LOWER_CABS_NGE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9551 { CODE_FOR_mips_cabs_nge_ps
, "__builtin_mips_all_cabs_nge_ps",
9552 MIPS_BUILTIN_ALL_CABS_NGE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9553 { CODE_FOR_mips_cabs_le_ps
, "__builtin_mips_any_cabs_le_ps",
9554 MIPS_BUILTIN_ANY_CABS_LE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9555 { CODE_FOR_mips_cabs_le_ps
, "__builtin_mips_upper_cabs_le_ps",
9556 MIPS_BUILTIN_UPPER_CABS_LE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9557 { CODE_FOR_mips_cabs_le_ps
, "__builtin_mips_lower_cabs_le_ps",
9558 MIPS_BUILTIN_LOWER_CABS_LE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9559 { CODE_FOR_mips_cabs_le_ps
, "__builtin_mips_all_cabs_le_ps",
9560 MIPS_BUILTIN_ALL_CABS_LE_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9561 { CODE_FOR_mips_cabs_ngt_ps
, "__builtin_mips_any_cabs_ngt_ps",
9562 MIPS_BUILTIN_ANY_CABS_NGT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9563 { CODE_FOR_mips_cabs_ngt_ps
, "__builtin_mips_upper_cabs_ngt_ps",
9564 MIPS_BUILTIN_UPPER_CABS_NGT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9565 { CODE_FOR_mips_cabs_ngt_ps
, "__builtin_mips_lower_cabs_ngt_ps",
9566 MIPS_BUILTIN_LOWER_CABS_NGT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9567 { CODE_FOR_mips_cabs_ngt_ps
, "__builtin_mips_all_cabs_ngt_ps",
9568 MIPS_BUILTIN_ALL_CABS_NGT_PS
, MIPS_INT_FTYPE_V2SF_V2SF
, MASK_MIPS3D
},
9570 { CODE_FOR_mips_c_f_4s
, "__builtin_mips_any_c_f_4s",
9571 MIPS_BUILTIN_ANY_C_F_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
, MASK_MIPS3D
},
9572 { CODE_FOR_mips_c_f_4s
, "__builtin_mips_all_c_f_4s",
9573 MIPS_BUILTIN_ALL_C_F_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
, MASK_MIPS3D
},
9574 { CODE_FOR_mips_c_un_4s
, "__builtin_mips_any_c_un_4s",
9575 MIPS_BUILTIN_ANY_C_UN_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9577 { CODE_FOR_mips_c_un_4s
, "__builtin_mips_all_c_un_4s",
9578 MIPS_BUILTIN_ALL_C_UN_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9580 { CODE_FOR_mips_c_eq_4s
, "__builtin_mips_any_c_eq_4s",
9581 MIPS_BUILTIN_ANY_C_EQ_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9583 { CODE_FOR_mips_c_eq_4s
, "__builtin_mips_all_c_eq_4s",
9584 MIPS_BUILTIN_ALL_C_EQ_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9586 { CODE_FOR_mips_c_ueq_4s
, "__builtin_mips_any_c_ueq_4s",
9587 MIPS_BUILTIN_ANY_C_UEQ_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9589 { CODE_FOR_mips_c_ueq_4s
, "__builtin_mips_all_c_ueq_4s",
9590 MIPS_BUILTIN_ALL_C_UEQ_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9592 { CODE_FOR_mips_c_olt_4s
, "__builtin_mips_any_c_olt_4s",
9593 MIPS_BUILTIN_ANY_C_OLT_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9595 { CODE_FOR_mips_c_olt_4s
, "__builtin_mips_all_c_olt_4s",
9596 MIPS_BUILTIN_ALL_C_OLT_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9598 { CODE_FOR_mips_c_ult_4s
, "__builtin_mips_any_c_ult_4s",
9599 MIPS_BUILTIN_ANY_C_ULT_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9601 { CODE_FOR_mips_c_ult_4s
, "__builtin_mips_all_c_ult_4s",
9602 MIPS_BUILTIN_ALL_C_ULT_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9604 { CODE_FOR_mips_c_ole_4s
, "__builtin_mips_any_c_ole_4s",
9605 MIPS_BUILTIN_ANY_C_OLE_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9607 { CODE_FOR_mips_c_ole_4s
, "__builtin_mips_all_c_ole_4s",
9608 MIPS_BUILTIN_ALL_C_OLE_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9610 { CODE_FOR_mips_c_ule_4s
, "__builtin_mips_any_c_ule_4s",
9611 MIPS_BUILTIN_ANY_C_ULE_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9613 { CODE_FOR_mips_c_ule_4s
, "__builtin_mips_all_c_ule_4s",
9614 MIPS_BUILTIN_ALL_C_ULE_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9616 { CODE_FOR_mips_c_sf_4s
, "__builtin_mips_any_c_sf_4s",
9617 MIPS_BUILTIN_ANY_C_SF_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9619 { CODE_FOR_mips_c_sf_4s
, "__builtin_mips_all_c_sf_4s",
9620 MIPS_BUILTIN_ALL_C_SF_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9622 { CODE_FOR_mips_c_ngle_4s
, "__builtin_mips_any_c_ngle_4s",
9623 MIPS_BUILTIN_ANY_C_NGLE_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9625 { CODE_FOR_mips_c_ngle_4s
, "__builtin_mips_all_c_ngle_4s",
9626 MIPS_BUILTIN_ALL_C_NGLE_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9628 { CODE_FOR_mips_c_seq_4s
, "__builtin_mips_any_c_seq_4s",
9629 MIPS_BUILTIN_ANY_C_SEQ_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9631 { CODE_FOR_mips_c_seq_4s
, "__builtin_mips_all_c_seq_4s",
9632 MIPS_BUILTIN_ALL_C_SEQ_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9634 { CODE_FOR_mips_c_ngl_4s
, "__builtin_mips_any_c_ngl_4s",
9635 MIPS_BUILTIN_ANY_C_NGL_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9637 { CODE_FOR_mips_c_ngl_4s
, "__builtin_mips_all_c_ngl_4s",
9638 MIPS_BUILTIN_ALL_C_NGL_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9640 { CODE_FOR_mips_c_lt_4s
, "__builtin_mips_any_c_lt_4s",
9641 MIPS_BUILTIN_ANY_C_LT_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9643 { CODE_FOR_mips_c_lt_4s
, "__builtin_mips_all_c_lt_4s",
9644 MIPS_BUILTIN_ALL_C_LT_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9646 { CODE_FOR_mips_c_nge_4s
, "__builtin_mips_any_c_nge_4s",
9647 MIPS_BUILTIN_ANY_C_NGE_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9649 { CODE_FOR_mips_c_nge_4s
, "__builtin_mips_all_c_nge_4s",
9650 MIPS_BUILTIN_ALL_C_NGE_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9652 { CODE_FOR_mips_c_le_4s
, "__builtin_mips_any_c_le_4s",
9653 MIPS_BUILTIN_ANY_C_LE_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9655 { CODE_FOR_mips_c_le_4s
, "__builtin_mips_all_c_le_4s",
9656 MIPS_BUILTIN_ALL_C_LE_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9658 { CODE_FOR_mips_c_ngt_4s
, "__builtin_mips_any_c_ngt_4s",
9659 MIPS_BUILTIN_ANY_C_NGT_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9661 { CODE_FOR_mips_c_ngt_4s
, "__builtin_mips_all_c_ngt_4s",
9662 MIPS_BUILTIN_ALL_C_NGT_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9665 { CODE_FOR_mips_cabs_f_4s
, "__builtin_mips_any_cabs_f_4s",
9666 MIPS_BUILTIN_ANY_CABS_F_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9668 { CODE_FOR_mips_cabs_f_4s
, "__builtin_mips_all_cabs_f_4s",
9669 MIPS_BUILTIN_ALL_CABS_F_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9671 { CODE_FOR_mips_cabs_un_4s
, "__builtin_mips_any_cabs_un_4s",
9672 MIPS_BUILTIN_ANY_CABS_UN_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9674 { CODE_FOR_mips_cabs_un_4s
, "__builtin_mips_all_cabs_un_4s",
9675 MIPS_BUILTIN_ALL_CABS_UN_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9677 { CODE_FOR_mips_cabs_eq_4s
, "__builtin_mips_any_cabs_eq_4s",
9678 MIPS_BUILTIN_ANY_CABS_EQ_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9680 { CODE_FOR_mips_cabs_eq_4s
, "__builtin_mips_all_cabs_eq_4s",
9681 MIPS_BUILTIN_ALL_CABS_EQ_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9683 { CODE_FOR_mips_cabs_ueq_4s
, "__builtin_mips_any_cabs_ueq_4s",
9684 MIPS_BUILTIN_ANY_CABS_UEQ_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9686 { CODE_FOR_mips_cabs_ueq_4s
, "__builtin_mips_all_cabs_ueq_4s",
9687 MIPS_BUILTIN_ALL_CABS_UEQ_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9689 { CODE_FOR_mips_cabs_olt_4s
, "__builtin_mips_any_cabs_olt_4s",
9690 MIPS_BUILTIN_ANY_CABS_OLT_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9692 { CODE_FOR_mips_cabs_olt_4s
, "__builtin_mips_all_cabs_olt_4s",
9693 MIPS_BUILTIN_ALL_CABS_OLT_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9695 { CODE_FOR_mips_cabs_ult_4s
, "__builtin_mips_any_cabs_ult_4s",
9696 MIPS_BUILTIN_ANY_CABS_ULT_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9698 { CODE_FOR_mips_cabs_ult_4s
, "__builtin_mips_all_cabs_ult_4s",
9699 MIPS_BUILTIN_ALL_CABS_ULT_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9701 { CODE_FOR_mips_cabs_ole_4s
, "__builtin_mips_any_cabs_ole_4s",
9702 MIPS_BUILTIN_ANY_CABS_OLE_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9704 { CODE_FOR_mips_cabs_ole_4s
, "__builtin_mips_all_cabs_ole_4s",
9705 MIPS_BUILTIN_ALL_CABS_OLE_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9707 { CODE_FOR_mips_cabs_ule_4s
, "__builtin_mips_any_cabs_ule_4s",
9708 MIPS_BUILTIN_ANY_CABS_ULE_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9710 { CODE_FOR_mips_cabs_ule_4s
, "__builtin_mips_all_cabs_ule_4s",
9711 MIPS_BUILTIN_ALL_CABS_ULE_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9713 { CODE_FOR_mips_cabs_sf_4s
, "__builtin_mips_any_cabs_sf_4s",
9714 MIPS_BUILTIN_ANY_CABS_SF_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9716 { CODE_FOR_mips_cabs_sf_4s
, "__builtin_mips_all_cabs_sf_4s",
9717 MIPS_BUILTIN_ALL_CABS_SF_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9719 { CODE_FOR_mips_cabs_ngle_4s
, "__builtin_mips_any_cabs_ngle_4s",
9720 MIPS_BUILTIN_ANY_CABS_NGLE_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9722 { CODE_FOR_mips_cabs_ngle_4s
, "__builtin_mips_all_cabs_ngle_4s",
9723 MIPS_BUILTIN_ALL_CABS_NGLE_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9725 { CODE_FOR_mips_cabs_seq_4s
, "__builtin_mips_any_cabs_seq_4s",
9726 MIPS_BUILTIN_ANY_CABS_SEQ_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9728 { CODE_FOR_mips_cabs_seq_4s
, "__builtin_mips_all_cabs_seq_4s",
9729 MIPS_BUILTIN_ALL_CABS_SEQ_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9731 { CODE_FOR_mips_cabs_ngl_4s
, "__builtin_mips_any_cabs_ngl_4s",
9732 MIPS_BUILTIN_ANY_CABS_NGL_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9734 { CODE_FOR_mips_cabs_ngl_4s
, "__builtin_mips_all_cabs_ngl_4s",
9735 MIPS_BUILTIN_ALL_CABS_NGL_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9737 { CODE_FOR_mips_cabs_lt_4s
, "__builtin_mips_any_cabs_lt_4s",
9738 MIPS_BUILTIN_ANY_CABS_LT_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9740 { CODE_FOR_mips_cabs_lt_4s
, "__builtin_mips_all_cabs_lt_4s",
9741 MIPS_BUILTIN_ALL_CABS_LT_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9743 { CODE_FOR_mips_cabs_nge_4s
, "__builtin_mips_any_cabs_nge_4s",
9744 MIPS_BUILTIN_ANY_CABS_NGE_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9746 { CODE_FOR_mips_cabs_nge_4s
, "__builtin_mips_all_cabs_nge_4s",
9747 MIPS_BUILTIN_ALL_CABS_NGE_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9749 { CODE_FOR_mips_cabs_le_4s
, "__builtin_mips_any_cabs_le_4s",
9750 MIPS_BUILTIN_ANY_CABS_LE_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9752 { CODE_FOR_mips_cabs_le_4s
, "__builtin_mips_all_cabs_le_4s",
9753 MIPS_BUILTIN_ALL_CABS_LE_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9755 { CODE_FOR_mips_cabs_ngt_4s
, "__builtin_mips_any_cabs_ngt_4s",
9756 MIPS_BUILTIN_ANY_CABS_NGT_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9758 { CODE_FOR_mips_cabs_ngt_4s
, "__builtin_mips_all_cabs_ngt_4s",
9759 MIPS_BUILTIN_ALL_CABS_NGT_4S
, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9762 { CODE_FOR_mips_cabs_f_s
, "__builtin_mips_cabs_f_s",
9763 MIPS_BUILTIN_CABS_F_S
, MIPS_INT_FTYPE_SF_SF
, MASK_MIPS3D
},
9764 { CODE_FOR_mips_cabs_un_s
, "__builtin_mips_cabs_un_s",
9765 MIPS_BUILTIN_CABS_UN_S
, MIPS_INT_FTYPE_SF_SF
, MASK_MIPS3D
},
9766 { CODE_FOR_mips_cabs_eq_s
, "__builtin_mips_cabs_eq_s",
9767 MIPS_BUILTIN_CABS_EQ_S
, MIPS_INT_FTYPE_SF_SF
, MASK_MIPS3D
},
9768 { CODE_FOR_mips_cabs_ueq_s
, "__builtin_mips_cabs_ueq_s",
9769 MIPS_BUILTIN_CABS_UEQ_S
, MIPS_INT_FTYPE_SF_SF
, MASK_MIPS3D
},
9770 { CODE_FOR_mips_cabs_olt_s
, "__builtin_mips_cabs_olt_s",
9771 MIPS_BUILTIN_CABS_OLT_S
, MIPS_INT_FTYPE_SF_SF
, MASK_MIPS3D
},
9772 { CODE_FOR_mips_cabs_ult_s
, "__builtin_mips_cabs_ult_s",
9773 MIPS_BUILTIN_CABS_ULT_S
, MIPS_INT_FTYPE_SF_SF
, MASK_MIPS3D
},
9774 { CODE_FOR_mips_cabs_ole_s
, "__builtin_mips_cabs_ole_s",
9775 MIPS_BUILTIN_CABS_OLE_S
, MIPS_INT_FTYPE_SF_SF
, MASK_MIPS3D
},
9776 { CODE_FOR_mips_cabs_ule_s
, "__builtin_mips_cabs_ule_s",
9777 MIPS_BUILTIN_CABS_ULE_S
, MIPS_INT_FTYPE_SF_SF
, MASK_MIPS3D
},
9778 { CODE_FOR_mips_cabs_sf_s
, "__builtin_mips_cabs_sf_s",
9779 MIPS_BUILTIN_CABS_SF_S
, MIPS_INT_FTYPE_SF_SF
, MASK_MIPS3D
},
9780 { CODE_FOR_mips_cabs_ngle_s
, "__builtin_mips_cabs_ngle_s",
9781 MIPS_BUILTIN_CABS_NGLE_S
, MIPS_INT_FTYPE_SF_SF
, MASK_MIPS3D
},
9782 { CODE_FOR_mips_cabs_seq_s
, "__builtin_mips_cabs_seq_s",
9783 MIPS_BUILTIN_CABS_SEQ_S
, MIPS_INT_FTYPE_SF_SF
, MASK_MIPS3D
},
9784 { CODE_FOR_mips_cabs_ngl_s
, "__builtin_mips_cabs_ngl_s",
9785 MIPS_BUILTIN_CABS_NGL_S
, MIPS_INT_FTYPE_SF_SF
, MASK_MIPS3D
},
9786 { CODE_FOR_mips_cabs_lt_s
, "__builtin_mips_cabs_lt_s",
9787 MIPS_BUILTIN_CABS_LT_S
, MIPS_INT_FTYPE_SF_SF
, MASK_MIPS3D
},
9788 { CODE_FOR_mips_cabs_nge_s
, "__builtin_mips_cabs_nge_s",
9789 MIPS_BUILTIN_CABS_NGE_S
, MIPS_INT_FTYPE_SF_SF
, MASK_MIPS3D
},
9790 { CODE_FOR_mips_cabs_le_s
, "__builtin_mips_cabs_le_s",
9791 MIPS_BUILTIN_CABS_LE_S
, MIPS_INT_FTYPE_SF_SF
, MASK_MIPS3D
},
9792 { CODE_FOR_mips_cabs_ngt_s
, "__builtin_mips_cabs_ngt_s",
9793 MIPS_BUILTIN_CABS_NGT_S
, MIPS_INT_FTYPE_SF_SF
, MASK_MIPS3D
},
9794 { CODE_FOR_mips_cabs_f_d
, "__builtin_mips_cabs_f_d",
9795 MIPS_BUILTIN_CABS_F_D
, MIPS_INT_FTYPE_DF_DF
, MASK_MIPS3D
},
9796 { CODE_FOR_mips_cabs_un_d
, "__builtin_mips_cabs_un_d",
9797 MIPS_BUILTIN_CABS_UN_D
, MIPS_INT_FTYPE_DF_DF
, MASK_MIPS3D
},
9798 { CODE_FOR_mips_cabs_eq_d
, "__builtin_mips_cabs_eq_d",
9799 MIPS_BUILTIN_CABS_EQ_D
, MIPS_INT_FTYPE_DF_DF
, MASK_MIPS3D
},
9800 { CODE_FOR_mips_cabs_ueq_d
, "__builtin_mips_cabs_ueq_d",
9801 MIPS_BUILTIN_CABS_UEQ_D
, MIPS_INT_FTYPE_DF_DF
, MASK_MIPS3D
},
9802 { CODE_FOR_mips_cabs_olt_d
, "__builtin_mips_cabs_olt_d",
9803 MIPS_BUILTIN_CABS_OLT_D
, MIPS_INT_FTYPE_DF_DF
, MASK_MIPS3D
},
9804 { CODE_FOR_mips_cabs_ult_d
, "__builtin_mips_cabs_ult_d",
9805 MIPS_BUILTIN_CABS_ULT_D
, MIPS_INT_FTYPE_DF_DF
, MASK_MIPS3D
},
9806 { CODE_FOR_mips_cabs_ole_d
, "__builtin_mips_cabs_ole_d",
9807 MIPS_BUILTIN_CABS_OLE_D
, MIPS_INT_FTYPE_DF_DF
, MASK_MIPS3D
},
9808 { CODE_FOR_mips_cabs_ule_d
, "__builtin_mips_cabs_ule_d",
9809 MIPS_BUILTIN_CABS_ULE_D
, MIPS_INT_FTYPE_DF_DF
, MASK_MIPS3D
},
9810 { CODE_FOR_mips_cabs_sf_d
, "__builtin_mips_cabs_sf_d",
9811 MIPS_BUILTIN_CABS_SF_D
, MIPS_INT_FTYPE_DF_DF
, MASK_MIPS3D
},
9812 { CODE_FOR_mips_cabs_ngle_d
, "__builtin_mips_cabs_ngle_d",
9813 MIPS_BUILTIN_CABS_NGLE_D
, MIPS_INT_FTYPE_DF_DF
, MASK_MIPS3D
},
9814 { CODE_FOR_mips_cabs_seq_d
, "__builtin_mips_cabs_seq_d",
9815 MIPS_BUILTIN_CABS_SEQ_D
, MIPS_INT_FTYPE_DF_DF
, MASK_MIPS3D
},
9816 { CODE_FOR_mips_cabs_ngl_d
, "__builtin_mips_cabs_ngl_d",
9817 MIPS_BUILTIN_CABS_NGL_D
, MIPS_INT_FTYPE_DF_DF
, MASK_MIPS3D
},
9818 { CODE_FOR_mips_cabs_lt_d
, "__builtin_mips_cabs_lt_d",
9819 MIPS_BUILTIN_CABS_LT_D
, MIPS_INT_FTYPE_DF_DF
, MASK_MIPS3D
},
9820 { CODE_FOR_mips_cabs_nge_d
, "__builtin_mips_cabs_nge_d",
9821 MIPS_BUILTIN_CABS_NGE_D
, MIPS_INT_FTYPE_DF_DF
, MASK_MIPS3D
},
9822 { CODE_FOR_mips_cabs_le_d
, "__builtin_mips_cabs_le_d",
9823 MIPS_BUILTIN_CABS_LE_D
, MIPS_INT_FTYPE_DF_DF
, MASK_MIPS3D
},
9824 { CODE_FOR_mips_cabs_ngt_d
, "__builtin_mips_cabs_ngt_d",
9825 MIPS_BUILTIN_CABS_NGT_D
, MIPS_INT_FTYPE_DF_DF
, MASK_MIPS3D
},
9827 { CODE_FOR_mips_c_f_ps
, "__builtin_mips_movt_c_f_ps",
9828 MIPS_BUILTIN_MOVT_C_F_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9829 MASK_PAIRED_SINGLE
},
9830 { CODE_FOR_mips_c_un_ps
, "__builtin_mips_movt_c_un_ps",
9831 MIPS_BUILTIN_MOVT_C_UN_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9832 MASK_PAIRED_SINGLE
},
9833 { CODE_FOR_mips_c_eq_ps
, "__builtin_mips_movt_c_eq_ps",
9834 MIPS_BUILTIN_MOVT_C_EQ_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9835 MASK_PAIRED_SINGLE
},
9836 { CODE_FOR_mips_c_ueq_ps
, "__builtin_mips_movt_c_ueq_ps",
9837 MIPS_BUILTIN_MOVT_C_UEQ_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9838 MASK_PAIRED_SINGLE
},
9839 { CODE_FOR_mips_c_olt_ps
, "__builtin_mips_movt_c_olt_ps",
9840 MIPS_BUILTIN_MOVT_C_OLT_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9841 MASK_PAIRED_SINGLE
},
9842 { CODE_FOR_mips_c_ult_ps
, "__builtin_mips_movt_c_ult_ps",
9843 MIPS_BUILTIN_MOVT_C_ULT_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9844 MASK_PAIRED_SINGLE
},
9845 { CODE_FOR_mips_c_ole_ps
, "__builtin_mips_movt_c_ole_ps",
9846 MIPS_BUILTIN_MOVT_C_OLE_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9847 MASK_PAIRED_SINGLE
},
9848 { CODE_FOR_mips_c_ule_ps
, "__builtin_mips_movt_c_ule_ps",
9849 MIPS_BUILTIN_MOVT_C_ULE_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9850 MASK_PAIRED_SINGLE
},
9851 { CODE_FOR_mips_c_sf_ps
, "__builtin_mips_movt_c_sf_ps",
9852 MIPS_BUILTIN_MOVT_C_SF_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9853 MASK_PAIRED_SINGLE
},
9854 { CODE_FOR_mips_c_ngle_ps
, "__builtin_mips_movt_c_ngle_ps",
9855 MIPS_BUILTIN_MOVT_C_NGLE_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9856 MASK_PAIRED_SINGLE
},
9857 { CODE_FOR_mips_c_seq_ps
, "__builtin_mips_movt_c_seq_ps",
9858 MIPS_BUILTIN_MOVT_C_SEQ_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9859 MASK_PAIRED_SINGLE
},
9860 { CODE_FOR_mips_c_ngl_ps
, "__builtin_mips_movt_c_ngl_ps",
9861 MIPS_BUILTIN_MOVT_C_NGL_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9862 MASK_PAIRED_SINGLE
},
9863 { CODE_FOR_mips_c_lt_ps
, "__builtin_mips_movt_c_lt_ps",
9864 MIPS_BUILTIN_MOVT_C_LT_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9865 MASK_PAIRED_SINGLE
},
9866 { CODE_FOR_mips_c_nge_ps
, "__builtin_mips_movt_c_nge_ps",
9867 MIPS_BUILTIN_MOVT_C_NGE_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9868 MASK_PAIRED_SINGLE
},
9869 { CODE_FOR_mips_c_le_ps
, "__builtin_mips_movt_c_le_ps",
9870 MIPS_BUILTIN_MOVT_C_LE_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9871 MASK_PAIRED_SINGLE
},
9872 { CODE_FOR_mips_c_ngt_ps
, "__builtin_mips_movt_c_ngt_ps",
9873 MIPS_BUILTIN_MOVT_C_NGT_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9874 MASK_PAIRED_SINGLE
},
9875 { CODE_FOR_mips_cabs_f_ps
, "__builtin_mips_movt_cabs_f_ps",
9876 MIPS_BUILTIN_MOVT_CABS_F_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9878 { CODE_FOR_mips_cabs_un_ps
, "__builtin_mips_movt_cabs_un_ps",
9879 MIPS_BUILTIN_MOVT_CABS_UN_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9881 { CODE_FOR_mips_cabs_eq_ps
, "__builtin_mips_movt_cabs_eq_ps",
9882 MIPS_BUILTIN_MOVT_CABS_EQ_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9884 { CODE_FOR_mips_cabs_ueq_ps
, "__builtin_mips_movt_cabs_ueq_ps",
9885 MIPS_BUILTIN_MOVT_CABS_UEQ_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9887 { CODE_FOR_mips_cabs_olt_ps
, "__builtin_mips_movt_cabs_olt_ps",
9888 MIPS_BUILTIN_MOVT_CABS_OLT_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9890 { CODE_FOR_mips_cabs_ult_ps
, "__builtin_mips_movt_cabs_ult_ps",
9891 MIPS_BUILTIN_MOVT_CABS_ULT_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9893 { CODE_FOR_mips_cabs_ole_ps
, "__builtin_mips_movt_cabs_ole_ps",
9894 MIPS_BUILTIN_MOVT_CABS_OLE_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9896 { CODE_FOR_mips_cabs_ule_ps
, "__builtin_mips_movt_cabs_ule_ps",
9897 MIPS_BUILTIN_MOVT_CABS_ULE_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9899 { CODE_FOR_mips_cabs_sf_ps
, "__builtin_mips_movt_cabs_sf_ps",
9900 MIPS_BUILTIN_MOVT_CABS_SF_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9902 { CODE_FOR_mips_cabs_ngle_ps
, "__builtin_mips_movt_cabs_ngle_ps",
9903 MIPS_BUILTIN_MOVT_CABS_NGLE_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9905 { CODE_FOR_mips_cabs_seq_ps
, "__builtin_mips_movt_cabs_seq_ps",
9906 MIPS_BUILTIN_MOVT_CABS_SEQ_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9908 { CODE_FOR_mips_cabs_ngl_ps
, "__builtin_mips_movt_cabs_ngl_ps",
9909 MIPS_BUILTIN_MOVT_CABS_NGL_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9911 { CODE_FOR_mips_cabs_lt_ps
, "__builtin_mips_movt_cabs_lt_ps",
9912 MIPS_BUILTIN_MOVT_CABS_LT_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9914 { CODE_FOR_mips_cabs_nge_ps
, "__builtin_mips_movt_cabs_nge_ps",
9915 MIPS_BUILTIN_MOVT_CABS_NGE_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9917 { CODE_FOR_mips_cabs_le_ps
, "__builtin_mips_movt_cabs_le_ps",
9918 MIPS_BUILTIN_MOVT_CABS_LE_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9920 { CODE_FOR_mips_cabs_ngt_ps
, "__builtin_mips_movt_cabs_ngt_ps",
9921 MIPS_BUILTIN_MOVT_CABS_NGT_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9923 { CODE_FOR_mips_c_f_ps
, "__builtin_mips_movf_c_f_ps",
9924 MIPS_BUILTIN_MOVF_C_F_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9925 MASK_PAIRED_SINGLE
},
9926 { CODE_FOR_mips_c_un_ps
, "__builtin_mips_movf_c_un_ps",
9927 MIPS_BUILTIN_MOVF_C_UN_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9928 MASK_PAIRED_SINGLE
},
9929 { CODE_FOR_mips_c_eq_ps
, "__builtin_mips_movf_c_eq_ps",
9930 MIPS_BUILTIN_MOVF_C_EQ_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9931 MASK_PAIRED_SINGLE
},
9932 { CODE_FOR_mips_c_ueq_ps
, "__builtin_mips_movf_c_ueq_ps",
9933 MIPS_BUILTIN_MOVF_C_UEQ_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9934 MASK_PAIRED_SINGLE
},
9935 { CODE_FOR_mips_c_olt_ps
, "__builtin_mips_movf_c_olt_ps",
9936 MIPS_BUILTIN_MOVF_C_OLT_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9937 MASK_PAIRED_SINGLE
},
9938 { CODE_FOR_mips_c_ult_ps
, "__builtin_mips_movf_c_ult_ps",
9939 MIPS_BUILTIN_MOVF_C_ULT_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9940 MASK_PAIRED_SINGLE
},
9941 { CODE_FOR_mips_c_ole_ps
, "__builtin_mips_movf_c_ole_ps",
9942 MIPS_BUILTIN_MOVF_C_OLE_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9943 MASK_PAIRED_SINGLE
},
9944 { CODE_FOR_mips_c_ule_ps
, "__builtin_mips_movf_c_ule_ps",
9945 MIPS_BUILTIN_MOVF_C_ULE_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9946 MASK_PAIRED_SINGLE
},
9947 { CODE_FOR_mips_c_sf_ps
, "__builtin_mips_movf_c_sf_ps",
9948 MIPS_BUILTIN_MOVF_C_SF_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9949 MASK_PAIRED_SINGLE
},
9950 { CODE_FOR_mips_c_ngle_ps
, "__builtin_mips_movf_c_ngle_ps",
9951 MIPS_BUILTIN_MOVF_C_NGLE_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9952 MASK_PAIRED_SINGLE
},
9953 { CODE_FOR_mips_c_seq_ps
, "__builtin_mips_movf_c_seq_ps",
9954 MIPS_BUILTIN_MOVF_C_SEQ_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9955 MASK_PAIRED_SINGLE
},
9956 { CODE_FOR_mips_c_ngl_ps
, "__builtin_mips_movf_c_ngl_ps",
9957 MIPS_BUILTIN_MOVF_C_NGL_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9958 MASK_PAIRED_SINGLE
},
9959 { CODE_FOR_mips_c_lt_ps
, "__builtin_mips_movf_c_lt_ps",
9960 MIPS_BUILTIN_MOVF_C_LT_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9961 MASK_PAIRED_SINGLE
},
9962 { CODE_FOR_mips_c_nge_ps
, "__builtin_mips_movf_c_nge_ps",
9963 MIPS_BUILTIN_MOVF_C_NGE_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9964 MASK_PAIRED_SINGLE
},
9965 { CODE_FOR_mips_c_le_ps
, "__builtin_mips_movf_c_le_ps",
9966 MIPS_BUILTIN_MOVF_C_LE_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9967 MASK_PAIRED_SINGLE
},
9968 { CODE_FOR_mips_c_ngt_ps
, "__builtin_mips_movf_c_ngt_ps",
9969 MIPS_BUILTIN_MOVF_C_NGT_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9970 MASK_PAIRED_SINGLE
},
9971 { CODE_FOR_mips_cabs_f_ps
, "__builtin_mips_movf_cabs_f_ps",
9972 MIPS_BUILTIN_MOVF_CABS_F_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9974 { CODE_FOR_mips_cabs_un_ps
, "__builtin_mips_movf_cabs_un_ps",
9975 MIPS_BUILTIN_MOVF_CABS_UN_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9977 { CODE_FOR_mips_cabs_eq_ps
, "__builtin_mips_movf_cabs_eq_ps",
9978 MIPS_BUILTIN_MOVF_CABS_EQ_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9980 { CODE_FOR_mips_cabs_ueq_ps
, "__builtin_mips_movf_cabs_ueq_ps",
9981 MIPS_BUILTIN_MOVF_CABS_UEQ_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9983 { CODE_FOR_mips_cabs_olt_ps
, "__builtin_mips_movf_cabs_olt_ps",
9984 MIPS_BUILTIN_MOVF_CABS_OLT_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9986 { CODE_FOR_mips_cabs_ult_ps
, "__builtin_mips_movf_cabs_ult_ps",
9987 MIPS_BUILTIN_MOVF_CABS_ULT_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9989 { CODE_FOR_mips_cabs_ole_ps
, "__builtin_mips_movf_cabs_ole_ps",
9990 MIPS_BUILTIN_MOVF_CABS_OLE_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9992 { CODE_FOR_mips_cabs_ule_ps
, "__builtin_mips_movf_cabs_ule_ps",
9993 MIPS_BUILTIN_MOVF_CABS_ULE_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9995 { CODE_FOR_mips_cabs_sf_ps
, "__builtin_mips_movf_cabs_sf_ps",
9996 MIPS_BUILTIN_MOVF_CABS_SF_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
9998 { CODE_FOR_mips_cabs_ngle_ps
, "__builtin_mips_movf_cabs_ngle_ps",
9999 MIPS_BUILTIN_MOVF_CABS_NGLE_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
10001 { CODE_FOR_mips_cabs_seq_ps
, "__builtin_mips_movf_cabs_seq_ps",
10002 MIPS_BUILTIN_MOVF_CABS_SEQ_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
10004 { CODE_FOR_mips_cabs_ngl_ps
, "__builtin_mips_movf_cabs_ngl_ps",
10005 MIPS_BUILTIN_MOVF_CABS_NGL_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
10007 { CODE_FOR_mips_cabs_lt_ps
, "__builtin_mips_movf_cabs_lt_ps",
10008 MIPS_BUILTIN_MOVF_CABS_LT_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
10010 { CODE_FOR_mips_cabs_nge_ps
, "__builtin_mips_movf_cabs_nge_ps",
10011 MIPS_BUILTIN_MOVF_CABS_NGE_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
10013 { CODE_FOR_mips_cabs_le_ps
, "__builtin_mips_movf_cabs_le_ps",
10014 MIPS_BUILTIN_MOVF_CABS_LE_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
10016 { CODE_FOR_mips_cabs_ngt_ps
, "__builtin_mips_movf_cabs_ngt_ps",
10017 MIPS_BUILTIN_MOVF_CABS_NGT_PS
, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
,
10023 /* Expand builtin functions. This is called from TARGET_EXPAND_BUILTIN. */
10026 mips_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
10027 enum machine_mode mode ATTRIBUTE_UNUSED
,
10028 int ignore ATTRIBUTE_UNUSED
)
10031 enum insn_code icode
;
10032 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
10033 tree arglist
= TREE_OPERAND (exp
, 1);
10034 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
10038 enum machine_mode tmode
;
10039 enum machine_mode mode0
;
10040 enum machine_mode mode1
;
10041 enum machine_mode mode2
;
10048 /* Two Operands. */
10049 case MIPS_BUILTIN_PLL_PS
:
10050 case MIPS_BUILTIN_PUL_PS
:
10051 case MIPS_BUILTIN_PLU_PS
:
10052 case MIPS_BUILTIN_PUU_PS
:
10053 case MIPS_BUILTIN_CVT_PS_S
:
10054 case MIPS_BUILTIN_ADDR_PS
:
10055 case MIPS_BUILTIN_MULR_PS
:
10056 case MIPS_BUILTIN_RECIP2_S
:
10057 case MIPS_BUILTIN_RECIP2_D
:
10058 case MIPS_BUILTIN_RECIP2_PS
:
10059 case MIPS_BUILTIN_RSQRT2_S
:
10060 case MIPS_BUILTIN_RSQRT2_D
:
10061 case MIPS_BUILTIN_RSQRT2_PS
:
10063 icode
= mips_bdesc
[fcode
].icode
;
10064 arg0
= TREE_VALUE (arglist
);
10065 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
10066 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
10067 op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
10068 tmode
= insn_data
[icode
].operand
[0].mode
;
10069 mode0
= insn_data
[icode
].operand
[1].mode
;
10070 mode1
= insn_data
[icode
].operand
[2].mode
;
10073 || GET_MODE (target
) != tmode
10074 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10075 target
= gen_reg_rtx (tmode
);
10077 if (!(*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
10078 op0
= copy_to_mode_reg (mode0
, op0
);
10079 if (!(*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
10080 op1
= copy_to_mode_reg (mode1
, op1
);
10082 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
10090 case MIPS_BUILTIN_CVT_S_PL
:
10091 case MIPS_BUILTIN_CVT_S_PU
:
10092 case MIPS_BUILTIN_ABS_PS
:
10093 case MIPS_BUILTIN_CVT_PW_PS
:
10094 case MIPS_BUILTIN_CVT_PS_PW
:
10095 case MIPS_BUILTIN_RECIP1_S
:
10096 case MIPS_BUILTIN_RECIP1_D
:
10097 case MIPS_BUILTIN_RECIP1_PS
:
10098 case MIPS_BUILTIN_RSQRT1_S
:
10099 case MIPS_BUILTIN_RSQRT1_D
:
10100 case MIPS_BUILTIN_RSQRT1_PS
:
10102 icode
= mips_bdesc
[fcode
].icode
;
10103 arg0
= TREE_VALUE (arglist
);
10104 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
10105 tmode
= insn_data
[icode
].operand
[0].mode
;
10106 mode0
= insn_data
[icode
].operand
[1].mode
;
10109 || GET_MODE (target
) != tmode
10110 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10111 target
= gen_reg_rtx (tmode
);
10113 if (!(*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
10114 op0
= copy_to_mode_reg (mode0
, op0
);
10116 pat
= GEN_FCN (icode
) (target
, op0
);
10123 /* Three Operands. */
10124 case MIPS_BUILTIN_ALNV_PS
:
10126 icode
= mips_bdesc
[fcode
].icode
;
10127 arg0
= TREE_VALUE (arglist
);
10128 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
10129 arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10130 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
10131 op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
10132 op2
= expand_expr (arg2
, NULL_RTX
, VOIDmode
, 0);
10133 tmode
= insn_data
[icode
].operand
[0].mode
;
10134 mode0
= insn_data
[icode
].operand
[1].mode
;
10135 mode1
= insn_data
[icode
].operand
[2].mode
;
10136 mode2
= insn_data
[icode
].operand
[3].mode
;
10139 || GET_MODE (target
) != tmode
10140 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10141 target
= gen_reg_rtx (tmode
);
10143 if (!(*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
10144 op0
= copy_to_mode_reg (mode0
, op0
);
10146 if (!(*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
10147 op1
= copy_to_mode_reg (mode1
, op1
);
10149 if (!(*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
10150 op2
= copy_to_mode_reg (mode2
, op2
);
10152 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
10159 /* Paired Single Comparison. */
10160 case MIPS_BUILTIN_ANY_C_F_PS
:
10161 case MIPS_BUILTIN_ANY_C_UN_PS
:
10162 case MIPS_BUILTIN_ANY_C_EQ_PS
:
10163 case MIPS_BUILTIN_ANY_C_UEQ_PS
:
10164 case MIPS_BUILTIN_ANY_C_OLT_PS
:
10165 case MIPS_BUILTIN_ANY_C_ULT_PS
:
10166 case MIPS_BUILTIN_ANY_C_OLE_PS
:
10167 case MIPS_BUILTIN_ANY_C_ULE_PS
:
10168 case MIPS_BUILTIN_ANY_C_SF_PS
:
10169 case MIPS_BUILTIN_ANY_C_NGLE_PS
:
10170 case MIPS_BUILTIN_ANY_C_SEQ_PS
:
10171 case MIPS_BUILTIN_ANY_C_NGL_PS
:
10172 case MIPS_BUILTIN_ANY_C_LT_PS
:
10173 case MIPS_BUILTIN_ANY_C_NGE_PS
:
10174 case MIPS_BUILTIN_ANY_C_LE_PS
:
10175 case MIPS_BUILTIN_ANY_C_NGT_PS
:
10176 case MIPS_BUILTIN_ANY_CABS_F_PS
:
10177 case MIPS_BUILTIN_ANY_CABS_UN_PS
:
10178 case MIPS_BUILTIN_ANY_CABS_EQ_PS
:
10179 case MIPS_BUILTIN_ANY_CABS_UEQ_PS
:
10180 case MIPS_BUILTIN_ANY_CABS_OLT_PS
:
10181 case MIPS_BUILTIN_ANY_CABS_ULT_PS
:
10182 case MIPS_BUILTIN_ANY_CABS_OLE_PS
:
10183 case MIPS_BUILTIN_ANY_CABS_ULE_PS
:
10184 case MIPS_BUILTIN_ANY_CABS_SF_PS
:
10185 case MIPS_BUILTIN_ANY_CABS_NGLE_PS
:
10186 case MIPS_BUILTIN_ANY_CABS_SEQ_PS
:
10187 case MIPS_BUILTIN_ANY_CABS_NGL_PS
:
10188 case MIPS_BUILTIN_ANY_CABS_LT_PS
:
10189 case MIPS_BUILTIN_ANY_CABS_NGE_PS
:
10190 case MIPS_BUILTIN_ANY_CABS_LE_PS
:
10191 case MIPS_BUILTIN_ANY_CABS_NGT_PS
:
10192 return mips_expand_ps_compare_builtin (MIPS_CMP_ANY
, target
,
10195 /* Paired Single Comparison. */
10196 case MIPS_BUILTIN_UPPER_C_F_PS
:
10197 case MIPS_BUILTIN_UPPER_C_UN_PS
:
10198 case MIPS_BUILTIN_UPPER_C_EQ_PS
:
10199 case MIPS_BUILTIN_UPPER_C_UEQ_PS
:
10200 case MIPS_BUILTIN_UPPER_C_OLT_PS
:
10201 case MIPS_BUILTIN_UPPER_C_ULT_PS
:
10202 case MIPS_BUILTIN_UPPER_C_OLE_PS
:
10203 case MIPS_BUILTIN_UPPER_C_ULE_PS
:
10204 case MIPS_BUILTIN_UPPER_C_SF_PS
:
10205 case MIPS_BUILTIN_UPPER_C_NGLE_PS
:
10206 case MIPS_BUILTIN_UPPER_C_SEQ_PS
:
10207 case MIPS_BUILTIN_UPPER_C_NGL_PS
:
10208 case MIPS_BUILTIN_UPPER_C_LT_PS
:
10209 case MIPS_BUILTIN_UPPER_C_NGE_PS
:
10210 case MIPS_BUILTIN_UPPER_C_LE_PS
:
10211 case MIPS_BUILTIN_UPPER_C_NGT_PS
:
10212 case MIPS_BUILTIN_UPPER_CABS_F_PS
:
10213 case MIPS_BUILTIN_UPPER_CABS_UN_PS
:
10214 case MIPS_BUILTIN_UPPER_CABS_EQ_PS
:
10215 case MIPS_BUILTIN_UPPER_CABS_UEQ_PS
:
10216 case MIPS_BUILTIN_UPPER_CABS_OLT_PS
:
10217 case MIPS_BUILTIN_UPPER_CABS_ULT_PS
:
10218 case MIPS_BUILTIN_UPPER_CABS_OLE_PS
:
10219 case MIPS_BUILTIN_UPPER_CABS_ULE_PS
:
10220 case MIPS_BUILTIN_UPPER_CABS_SF_PS
:
10221 case MIPS_BUILTIN_UPPER_CABS_NGLE_PS
:
10222 case MIPS_BUILTIN_UPPER_CABS_SEQ_PS
:
10223 case MIPS_BUILTIN_UPPER_CABS_NGL_PS
:
10224 case MIPS_BUILTIN_UPPER_CABS_LT_PS
:
10225 case MIPS_BUILTIN_UPPER_CABS_NGE_PS
:
10226 case MIPS_BUILTIN_UPPER_CABS_LE_PS
:
10227 case MIPS_BUILTIN_UPPER_CABS_NGT_PS
:
10228 return mips_expand_ps_compare_builtin (MIPS_CMP_UPPER
, target
,
10231 /* Paired Single Comparison. */
10232 case MIPS_BUILTIN_LOWER_C_F_PS
:
10233 case MIPS_BUILTIN_LOWER_C_UN_PS
:
10234 case MIPS_BUILTIN_LOWER_C_EQ_PS
:
10235 case MIPS_BUILTIN_LOWER_C_UEQ_PS
:
10236 case MIPS_BUILTIN_LOWER_C_OLT_PS
:
10237 case MIPS_BUILTIN_LOWER_C_ULT_PS
:
10238 case MIPS_BUILTIN_LOWER_C_OLE_PS
:
10239 case MIPS_BUILTIN_LOWER_C_ULE_PS
:
10240 case MIPS_BUILTIN_LOWER_C_SF_PS
:
10241 case MIPS_BUILTIN_LOWER_C_NGLE_PS
:
10242 case MIPS_BUILTIN_LOWER_C_SEQ_PS
:
10243 case MIPS_BUILTIN_LOWER_C_NGL_PS
:
10244 case MIPS_BUILTIN_LOWER_C_LT_PS
:
10245 case MIPS_BUILTIN_LOWER_C_NGE_PS
:
10246 case MIPS_BUILTIN_LOWER_C_LE_PS
:
10247 case MIPS_BUILTIN_LOWER_C_NGT_PS
:
10248 case MIPS_BUILTIN_LOWER_CABS_F_PS
:
10249 case MIPS_BUILTIN_LOWER_CABS_UN_PS
:
10250 case MIPS_BUILTIN_LOWER_CABS_EQ_PS
:
10251 case MIPS_BUILTIN_LOWER_CABS_UEQ_PS
:
10252 case MIPS_BUILTIN_LOWER_CABS_OLT_PS
:
10253 case MIPS_BUILTIN_LOWER_CABS_ULT_PS
:
10254 case MIPS_BUILTIN_LOWER_CABS_OLE_PS
:
10255 case MIPS_BUILTIN_LOWER_CABS_ULE_PS
:
10256 case MIPS_BUILTIN_LOWER_CABS_SF_PS
:
10257 case MIPS_BUILTIN_LOWER_CABS_NGLE_PS
:
10258 case MIPS_BUILTIN_LOWER_CABS_SEQ_PS
:
10259 case MIPS_BUILTIN_LOWER_CABS_NGL_PS
:
10260 case MIPS_BUILTIN_LOWER_CABS_LT_PS
:
10261 case MIPS_BUILTIN_LOWER_CABS_NGE_PS
:
10262 case MIPS_BUILTIN_LOWER_CABS_LE_PS
:
10263 case MIPS_BUILTIN_LOWER_CABS_NGT_PS
:
10264 return mips_expand_ps_compare_builtin (MIPS_CMP_LOWER
, target
,
10267 /* Paired Single Comparison. */
10268 case MIPS_BUILTIN_ALL_C_F_PS
:
10269 case MIPS_BUILTIN_ALL_C_UN_PS
:
10270 case MIPS_BUILTIN_ALL_C_EQ_PS
:
10271 case MIPS_BUILTIN_ALL_C_UEQ_PS
:
10272 case MIPS_BUILTIN_ALL_C_OLT_PS
:
10273 case MIPS_BUILTIN_ALL_C_ULT_PS
:
10274 case MIPS_BUILTIN_ALL_C_OLE_PS
:
10275 case MIPS_BUILTIN_ALL_C_ULE_PS
:
10276 case MIPS_BUILTIN_ALL_C_SF_PS
:
10277 case MIPS_BUILTIN_ALL_C_NGLE_PS
:
10278 case MIPS_BUILTIN_ALL_C_SEQ_PS
:
10279 case MIPS_BUILTIN_ALL_C_NGL_PS
:
10280 case MIPS_BUILTIN_ALL_C_LT_PS
:
10281 case MIPS_BUILTIN_ALL_C_NGE_PS
:
10282 case MIPS_BUILTIN_ALL_C_LE_PS
:
10283 case MIPS_BUILTIN_ALL_C_NGT_PS
:
10284 case MIPS_BUILTIN_ALL_CABS_F_PS
:
10285 case MIPS_BUILTIN_ALL_CABS_UN_PS
:
10286 case MIPS_BUILTIN_ALL_CABS_EQ_PS
:
10287 case MIPS_BUILTIN_ALL_CABS_UEQ_PS
:
10288 case MIPS_BUILTIN_ALL_CABS_OLT_PS
:
10289 case MIPS_BUILTIN_ALL_CABS_ULT_PS
:
10290 case MIPS_BUILTIN_ALL_CABS_OLE_PS
:
10291 case MIPS_BUILTIN_ALL_CABS_ULE_PS
:
10292 case MIPS_BUILTIN_ALL_CABS_SF_PS
:
10293 case MIPS_BUILTIN_ALL_CABS_NGLE_PS
:
10294 case MIPS_BUILTIN_ALL_CABS_SEQ_PS
:
10295 case MIPS_BUILTIN_ALL_CABS_NGL_PS
:
10296 case MIPS_BUILTIN_ALL_CABS_LT_PS
:
10297 case MIPS_BUILTIN_ALL_CABS_NGE_PS
:
10298 case MIPS_BUILTIN_ALL_CABS_LE_PS
:
10299 case MIPS_BUILTIN_ALL_CABS_NGT_PS
:
10300 return mips_expand_ps_compare_builtin (MIPS_CMP_ALL
, target
,
10303 /* Four Single Comparison. */
10304 case MIPS_BUILTIN_ANY_C_F_4S
:
10305 case MIPS_BUILTIN_ANY_C_UN_4S
:
10306 case MIPS_BUILTIN_ANY_C_EQ_4S
:
10307 case MIPS_BUILTIN_ANY_C_UEQ_4S
:
10308 case MIPS_BUILTIN_ANY_C_OLT_4S
:
10309 case MIPS_BUILTIN_ANY_C_ULT_4S
:
10310 case MIPS_BUILTIN_ANY_C_OLE_4S
:
10311 case MIPS_BUILTIN_ANY_C_ULE_4S
:
10312 case MIPS_BUILTIN_ANY_C_SF_4S
:
10313 case MIPS_BUILTIN_ANY_C_NGLE_4S
:
10314 case MIPS_BUILTIN_ANY_C_SEQ_4S
:
10315 case MIPS_BUILTIN_ANY_C_NGL_4S
:
10316 case MIPS_BUILTIN_ANY_C_LT_4S
:
10317 case MIPS_BUILTIN_ANY_C_NGE_4S
:
10318 case MIPS_BUILTIN_ANY_C_LE_4S
:
10319 case MIPS_BUILTIN_ANY_C_NGT_4S
:
10320 case MIPS_BUILTIN_ANY_CABS_F_4S
:
10321 case MIPS_BUILTIN_ANY_CABS_UN_4S
:
10322 case MIPS_BUILTIN_ANY_CABS_EQ_4S
:
10323 case MIPS_BUILTIN_ANY_CABS_UEQ_4S
:
10324 case MIPS_BUILTIN_ANY_CABS_OLT_4S
:
10325 case MIPS_BUILTIN_ANY_CABS_ULT_4S
:
10326 case MIPS_BUILTIN_ANY_CABS_OLE_4S
:
10327 case MIPS_BUILTIN_ANY_CABS_ULE_4S
:
10328 case MIPS_BUILTIN_ANY_CABS_SF_4S
:
10329 case MIPS_BUILTIN_ANY_CABS_NGLE_4S
:
10330 case MIPS_BUILTIN_ANY_CABS_SEQ_4S
:
10331 case MIPS_BUILTIN_ANY_CABS_NGL_4S
:
10332 case MIPS_BUILTIN_ANY_CABS_LT_4S
:
10333 case MIPS_BUILTIN_ANY_CABS_NGE_4S
:
10334 case MIPS_BUILTIN_ANY_CABS_LE_4S
:
10335 case MIPS_BUILTIN_ANY_CABS_NGT_4S
:
10336 return mips_expand_4s_compare_builtin (MIPS_CMP_ANY
, target
,
10339 /* Four Single Comparison. */
10340 case MIPS_BUILTIN_ALL_C_F_4S
:
10341 case MIPS_BUILTIN_ALL_C_UN_4S
:
10342 case MIPS_BUILTIN_ALL_C_EQ_4S
:
10343 case MIPS_BUILTIN_ALL_C_UEQ_4S
:
10344 case MIPS_BUILTIN_ALL_C_OLT_4S
:
10345 case MIPS_BUILTIN_ALL_C_ULT_4S
:
10346 case MIPS_BUILTIN_ALL_C_OLE_4S
:
10347 case MIPS_BUILTIN_ALL_C_ULE_4S
:
10348 case MIPS_BUILTIN_ALL_C_SF_4S
:
10349 case MIPS_BUILTIN_ALL_C_NGLE_4S
:
10350 case MIPS_BUILTIN_ALL_C_SEQ_4S
:
10351 case MIPS_BUILTIN_ALL_C_NGL_4S
:
10352 case MIPS_BUILTIN_ALL_C_LT_4S
:
10353 case MIPS_BUILTIN_ALL_C_NGE_4S
:
10354 case MIPS_BUILTIN_ALL_C_LE_4S
:
10355 case MIPS_BUILTIN_ALL_C_NGT_4S
:
10356 case MIPS_BUILTIN_ALL_CABS_F_4S
:
10357 case MIPS_BUILTIN_ALL_CABS_UN_4S
:
10358 case MIPS_BUILTIN_ALL_CABS_EQ_4S
:
10359 case MIPS_BUILTIN_ALL_CABS_UEQ_4S
:
10360 case MIPS_BUILTIN_ALL_CABS_OLT_4S
:
10361 case MIPS_BUILTIN_ALL_CABS_ULT_4S
:
10362 case MIPS_BUILTIN_ALL_CABS_OLE_4S
:
10363 case MIPS_BUILTIN_ALL_CABS_ULE_4S
:
10364 case MIPS_BUILTIN_ALL_CABS_SF_4S
:
10365 case MIPS_BUILTIN_ALL_CABS_NGLE_4S
:
10366 case MIPS_BUILTIN_ALL_CABS_SEQ_4S
:
10367 case MIPS_BUILTIN_ALL_CABS_NGL_4S
:
10368 case MIPS_BUILTIN_ALL_CABS_LT_4S
:
10369 case MIPS_BUILTIN_ALL_CABS_NGE_4S
:
10370 case MIPS_BUILTIN_ALL_CABS_LE_4S
:
10371 case MIPS_BUILTIN_ALL_CABS_NGT_4S
:
10372 return mips_expand_4s_compare_builtin (MIPS_CMP_ALL
, target
,
10375 /* Single/Double Compare Absolute. */
10376 case MIPS_BUILTIN_CABS_F_S
:
10377 case MIPS_BUILTIN_CABS_UN_S
:
10378 case MIPS_BUILTIN_CABS_EQ_S
:
10379 case MIPS_BUILTIN_CABS_UEQ_S
:
10380 case MIPS_BUILTIN_CABS_OLT_S
:
10381 case MIPS_BUILTIN_CABS_ULT_S
:
10382 case MIPS_BUILTIN_CABS_OLE_S
:
10383 case MIPS_BUILTIN_CABS_ULE_S
:
10384 case MIPS_BUILTIN_CABS_SF_S
:
10385 case MIPS_BUILTIN_CABS_NGLE_S
:
10386 case MIPS_BUILTIN_CABS_SEQ_S
:
10387 case MIPS_BUILTIN_CABS_NGL_S
:
10388 case MIPS_BUILTIN_CABS_LT_S
:
10389 case MIPS_BUILTIN_CABS_NGE_S
:
10390 case MIPS_BUILTIN_CABS_LE_S
:
10391 case MIPS_BUILTIN_CABS_NGT_S
:
10392 case MIPS_BUILTIN_CABS_F_D
:
10393 case MIPS_BUILTIN_CABS_UN_D
:
10394 case MIPS_BUILTIN_CABS_EQ_D
:
10395 case MIPS_BUILTIN_CABS_UEQ_D
:
10396 case MIPS_BUILTIN_CABS_OLT_D
:
10397 case MIPS_BUILTIN_CABS_ULT_D
:
10398 case MIPS_BUILTIN_CABS_OLE_D
:
10399 case MIPS_BUILTIN_CABS_ULE_D
:
10400 case MIPS_BUILTIN_CABS_SF_D
:
10401 case MIPS_BUILTIN_CABS_NGLE_D
:
10402 case MIPS_BUILTIN_CABS_SEQ_D
:
10403 case MIPS_BUILTIN_CABS_NGL_D
:
10404 case MIPS_BUILTIN_CABS_LT_D
:
10405 case MIPS_BUILTIN_CABS_NGE_D
:
10406 case MIPS_BUILTIN_CABS_LE_D
:
10407 case MIPS_BUILTIN_CABS_NGT_D
:
10408 return mips_expand_compare_builtin (target
, fcode
, arglist
);
10410 /* Conditional Move on True. */
10411 case MIPS_BUILTIN_MOVT_C_F_PS
:
10412 case MIPS_BUILTIN_MOVT_C_UN_PS
:
10413 case MIPS_BUILTIN_MOVT_C_EQ_PS
:
10414 case MIPS_BUILTIN_MOVT_C_UEQ_PS
:
10415 case MIPS_BUILTIN_MOVT_C_OLT_PS
:
10416 case MIPS_BUILTIN_MOVT_C_ULT_PS
:
10417 case MIPS_BUILTIN_MOVT_C_OLE_PS
:
10418 case MIPS_BUILTIN_MOVT_C_ULE_PS
:
10419 case MIPS_BUILTIN_MOVT_C_SF_PS
:
10420 case MIPS_BUILTIN_MOVT_C_NGLE_PS
:
10421 case MIPS_BUILTIN_MOVT_C_SEQ_PS
:
10422 case MIPS_BUILTIN_MOVT_C_NGL_PS
:
10423 case MIPS_BUILTIN_MOVT_C_LT_PS
:
10424 case MIPS_BUILTIN_MOVT_C_NGE_PS
:
10425 case MIPS_BUILTIN_MOVT_C_LE_PS
:
10426 case MIPS_BUILTIN_MOVT_C_NGT_PS
:
10427 case MIPS_BUILTIN_MOVT_CABS_F_PS
:
10428 case MIPS_BUILTIN_MOVT_CABS_UN_PS
:
10429 case MIPS_BUILTIN_MOVT_CABS_EQ_PS
:
10430 case MIPS_BUILTIN_MOVT_CABS_UEQ_PS
:
10431 case MIPS_BUILTIN_MOVT_CABS_OLT_PS
:
10432 case MIPS_BUILTIN_MOVT_CABS_ULT_PS
:
10433 case MIPS_BUILTIN_MOVT_CABS_OLE_PS
:
10434 case MIPS_BUILTIN_MOVT_CABS_ULE_PS
:
10435 case MIPS_BUILTIN_MOVT_CABS_SF_PS
:
10436 case MIPS_BUILTIN_MOVT_CABS_NGLE_PS
:
10437 case MIPS_BUILTIN_MOVT_CABS_SEQ_PS
:
10438 case MIPS_BUILTIN_MOVT_CABS_NGL_PS
:
10439 case MIPS_BUILTIN_MOVT_CABS_LT_PS
:
10440 case MIPS_BUILTIN_MOVT_CABS_NGE_PS
:
10441 case MIPS_BUILTIN_MOVT_CABS_LE_PS
:
10442 case MIPS_BUILTIN_MOVT_CABS_NGT_PS
:
10443 return mips_expand_ps_cond_move_builtin (MIPS_CMP_MOVT
, target
,
10446 /* Conditional Move on False. */
10447 case MIPS_BUILTIN_MOVF_C_F_PS
:
10448 case MIPS_BUILTIN_MOVF_C_UN_PS
:
10449 case MIPS_BUILTIN_MOVF_C_EQ_PS
:
10450 case MIPS_BUILTIN_MOVF_C_UEQ_PS
:
10451 case MIPS_BUILTIN_MOVF_C_OLT_PS
:
10452 case MIPS_BUILTIN_MOVF_C_ULT_PS
:
10453 case MIPS_BUILTIN_MOVF_C_OLE_PS
:
10454 case MIPS_BUILTIN_MOVF_C_ULE_PS
:
10455 case MIPS_BUILTIN_MOVF_C_SF_PS
:
10456 case MIPS_BUILTIN_MOVF_C_NGLE_PS
:
10457 case MIPS_BUILTIN_MOVF_C_SEQ_PS
:
10458 case MIPS_BUILTIN_MOVF_C_NGL_PS
:
10459 case MIPS_BUILTIN_MOVF_C_LT_PS
:
10460 case MIPS_BUILTIN_MOVF_C_NGE_PS
:
10461 case MIPS_BUILTIN_MOVF_C_LE_PS
:
10462 case MIPS_BUILTIN_MOVF_C_NGT_PS
:
10463 case MIPS_BUILTIN_MOVF_CABS_F_PS
:
10464 case MIPS_BUILTIN_MOVF_CABS_UN_PS
:
10465 case MIPS_BUILTIN_MOVF_CABS_EQ_PS
:
10466 case MIPS_BUILTIN_MOVF_CABS_UEQ_PS
:
10467 case MIPS_BUILTIN_MOVF_CABS_OLT_PS
:
10468 case MIPS_BUILTIN_MOVF_CABS_ULT_PS
:
10469 case MIPS_BUILTIN_MOVF_CABS_OLE_PS
:
10470 case MIPS_BUILTIN_MOVF_CABS_ULE_PS
:
10471 case MIPS_BUILTIN_MOVF_CABS_SF_PS
:
10472 case MIPS_BUILTIN_MOVF_CABS_NGLE_PS
:
10473 case MIPS_BUILTIN_MOVF_CABS_SEQ_PS
:
10474 case MIPS_BUILTIN_MOVF_CABS_NGL_PS
:
10475 case MIPS_BUILTIN_MOVF_CABS_LT_PS
:
10476 case MIPS_BUILTIN_MOVF_CABS_NGE_PS
:
10477 case MIPS_BUILTIN_MOVF_CABS_LE_PS
:
10478 case MIPS_BUILTIN_MOVF_CABS_NGT_PS
:
10479 return mips_expand_ps_cond_move_builtin (MIPS_CMP_MOVF
, target
,
10489 /* Init builtin functions. This is called from TARGET_INIT_BUILTIN. */
10492 mips_init_builtins (void)
10494 const struct builtin_description
*d
;
10496 tree v2sf_ftype_v2sf_v2sf
;
10497 tree v2sf_ftype_sf_sf
;
10498 tree sf_ftype_v2sf
;
10499 tree v2sf_ftype_v2sf
;
10500 tree int_ftype_v2sf_v2sf
;
10501 tree int_ftype_v2sf_v2sf_v2sf_v2sf
;
10502 tree v2sf_ftype_v2sf_v2sf_int
;
10503 tree int_ftype_sf_sf
;
10504 tree int_ftype_df_df
;
10507 tree sf_ftype_sf_sf
;
10508 tree df_ftype_df_df
;
10509 tree v2sf_ftype_v2sf_v2sf_v2sf_v2sf
;
10510 tree V2SF_type_node
= build_vector_type_for_mode (float_type_node
, V2SFmode
);
10512 /* We have only builtins for -mpaired-single and -mips3d. */
10513 if (!TARGET_PAIRED_SINGLE_FLOAT
)
10517 = build_function_type_list (integer_type_node
,
10518 float_type_node
, float_type_node
,
10522 = build_function_type_list (integer_type_node
,
10523 double_type_node
, double_type_node
,
10526 v2sf_ftype_v2sf_v2sf
10527 = build_function_type_list (V2SF_type_node
,
10528 V2SF_type_node
, V2SF_type_node
, NULL_TREE
);
10531 = build_function_type_list (V2SF_type_node
,
10532 float_type_node
, float_type_node
,
10536 = build_function_type_list (float_type_node
, V2SF_type_node
, NULL_TREE
);
10539 = build_function_type_list (V2SF_type_node
, V2SF_type_node
, NULL_TREE
);
10541 int_ftype_v2sf_v2sf
10542 = build_function_type_list (integer_type_node
,
10543 V2SF_type_node
, V2SF_type_node
, NULL_TREE
);
10545 int_ftype_v2sf_v2sf_v2sf_v2sf
10546 = build_function_type_list (integer_type_node
,
10547 V2SF_type_node
, V2SF_type_node
,
10548 V2SF_type_node
, V2SF_type_node
, NULL_TREE
);
10550 v2sf_ftype_v2sf_v2sf_v2sf_v2sf
10551 = build_function_type_list (V2SF_type_node
,
10552 V2SF_type_node
, V2SF_type_node
,
10553 V2SF_type_node
, V2SF_type_node
, NULL_TREE
);
10555 v2sf_ftype_v2sf_v2sf_int
10556 = build_function_type_list (V2SF_type_node
,
10557 V2SF_type_node
, V2SF_type_node
,
10558 integer_type_node
, NULL_TREE
);
10561 = build_function_type_list (float_type_node
,
10562 float_type_node
, NULL_TREE
);
10565 = build_function_type_list (double_type_node
,
10566 double_type_node
, NULL_TREE
);
10569 = build_function_type_list (float_type_node
,
10570 float_type_node
, float_type_node
,
10574 = build_function_type_list (double_type_node
,
10575 double_type_node
, double_type_node
,
10578 for (i
= 0, d
= mips_bdesc
; i
< ARRAY_SIZE (mips_bdesc
); i
++, d
++)
10580 if ((d
->target_flags
& MASK_PAIRED_SINGLE
)
10581 && !TARGET_PAIRED_SINGLE_FLOAT
)
10584 if ((d
->target_flags
& MASK_MIPS3D
)
10590 case MIPS_V2SF_FTYPE_V2SF_V2SF
:
10591 lang_hooks
.builtin_function (d
->name
, v2sf_ftype_v2sf_v2sf
,
10592 d
->code
, BUILT_IN_MD
, NULL
, NULL_TREE
);
10595 case MIPS_V2SF_FTYPE_SF_SF
:
10596 lang_hooks
.builtin_function (d
->name
, v2sf_ftype_sf_sf
,
10597 d
->code
, BUILT_IN_MD
, NULL
, NULL_TREE
);
10600 case MIPS_SF_FTYPE_V2SF
:
10601 lang_hooks
.builtin_function (d
->name
, sf_ftype_v2sf
,
10602 d
->code
, BUILT_IN_MD
, NULL
, NULL_TREE
);
10605 case MIPS_V2SF_FTYPE_V2SF
:
10606 lang_hooks
.builtin_function (d
->name
, v2sf_ftype_v2sf
,
10607 d
->code
, BUILT_IN_MD
, NULL
, NULL_TREE
);
10610 case MIPS_INT_FTYPE_V2SF_V2SF
:
10611 lang_hooks
.builtin_function (d
->name
, int_ftype_v2sf_v2sf
,
10612 d
->code
, BUILT_IN_MD
, NULL
, NULL_TREE
);
10615 case MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF
:
10616 lang_hooks
.builtin_function (d
->name
, int_ftype_v2sf_v2sf_v2sf_v2sf
,
10617 d
->code
, BUILT_IN_MD
, NULL
, NULL_TREE
);
10620 case MIPS_V2SF_FTYPE_V2SF_V2SF_INT
:
10621 lang_hooks
.builtin_function (d
->name
, v2sf_ftype_v2sf_v2sf_int
,
10622 d
->code
, BUILT_IN_MD
, NULL
, NULL_TREE
);
10625 case MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF
:
10626 lang_hooks
.builtin_function (d
->name
, v2sf_ftype_v2sf_v2sf_v2sf_v2sf
,
10627 d
->code
, BUILT_IN_MD
, NULL
, NULL_TREE
);
10630 case MIPS_SF_FTYPE_SF
:
10631 lang_hooks
.builtin_function (d
->name
, sf_ftype_sf
,
10632 d
->code
, BUILT_IN_MD
, NULL
, NULL_TREE
);
10635 case MIPS_DF_FTYPE_DF
:
10636 lang_hooks
.builtin_function (d
->name
, df_ftype_df
,
10637 d
->code
, BUILT_IN_MD
, NULL
, NULL_TREE
);
10640 case MIPS_INT_FTYPE_SF_SF
:
10641 lang_hooks
.builtin_function (d
->name
, int_ftype_sf_sf
,
10642 d
->code
, BUILT_IN_MD
, NULL
, NULL_TREE
);
10645 case MIPS_INT_FTYPE_DF_DF
:
10646 lang_hooks
.builtin_function (d
->name
, int_ftype_df_df
,
10647 d
->code
, BUILT_IN_MD
, NULL
, NULL_TREE
);
10650 case MIPS_SF_FTYPE_SF_SF
:
10651 lang_hooks
.builtin_function (d
->name
, sf_ftype_sf_sf
,
10652 d
->code
, BUILT_IN_MD
, NULL
, NULL_TREE
);
10655 case MIPS_DF_FTYPE_DF_DF
:
10656 lang_hooks
.builtin_function (d
->name
, df_ftype_df_df
,
10657 d
->code
, BUILT_IN_MD
, NULL
, NULL_TREE
);
10666 /* This performs a paired single compare, and then a conditional move based
10667 on the result of that compare. CMP_CHOICE is the kind of comparison we
10668 want. TARGET is a suggestion of where to put the result. FCODE is the
10669 function code. ARGLIST is the list of arguments. The return value is
10670 the result of the conditional move. */
10673 mips_expand_ps_cond_move_builtin (enum mips_cmp_choice cmp_choice
,
10674 rtx target
, unsigned int fcode
,
10678 enum insn_code icode
;
10687 enum machine_mode tmode
;
10688 enum machine_mode mode0
;
10689 enum machine_mode mode1
;
10693 enum rtx_code test_code
;
10696 arg0
= TREE_VALUE (arglist
);
10697 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
10698 arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10699 arg3
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
10700 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
10701 op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
10702 op2
= expand_expr (arg2
, NULL_RTX
, VOIDmode
, 0);
10703 op3
= expand_expr (arg3
, NULL_RTX
, VOIDmode
, 0);
10705 icode
= mips_bdesc
[fcode
].icode
;
10706 tmode
= insn_data
[icode
].operand
[0].mode
;
10707 mode0
= insn_data
[icode
].operand
[1].mode
;
10708 mode1
= insn_data
[icode
].operand
[2].mode
;
10710 if (!(*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
10711 op0
= copy_to_mode_reg (mode0
, op0
);
10713 if (!(*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
10714 op1
= copy_to_mode_reg (mode1
, op1
);
10716 /* temp_target is the result of the comparison. */
10717 temp_target
= gen_reg_rtx (tmode
);
10719 pat
= GEN_FCN (icode
) (temp_target
, op0
, op1
);
10725 icode
= CODE_FOR_mips_cond_move_tf_ps
;
10726 tmode
= insn_data
[icode
].operand
[0].mode
;
10729 || GET_MODE (target
) != tmode
10730 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10731 target
= gen_reg_rtx (tmode
);
10733 /* Let op2 be the same as the tmode */
10734 if (!(*insn_data
[icode
].operand
[0].predicate
) (op2
, tmode
))
10735 op2
= copy_to_mode_reg (tmode
, op2
);
10737 /* Let op3 be the same as the tmode */
10738 if (!(*insn_data
[icode
].operand
[0].predicate
) (op3
, tmode
))
10739 op3
= copy_to_mode_reg (tmode
, op3
);
10741 /* Copy op2 to target */
10742 emit_insn (gen_rtx_SET (tmode
, target
, op2
));
10746 switch (cmp_choice
)
10748 case MIPS_CMP_MOVT
:
10753 case MIPS_CMP_MOVF
:
10762 emit_insn (gen_mips_cond_move_tf_ps (target
, src1
, src2
, temp_target
));
10767 /* This performs two paired single compares, and returns an boolean value to
10768 represent the result of the compare. CMP_CHOICE is the kind of comparison
10769 we want. TARGET is a suggestion of where to put the result. FCODE is
10770 the builtin function code. ARGLIST is the list of arguments. The
10771 return value is the result of the compare. */
10774 mips_expand_4s_compare_builtin (enum mips_cmp_choice cmp_choice
, rtx target
,
10775 unsigned int fcode
, tree arglist
)
10778 enum insn_code icode
;
10787 enum machine_mode tmode
;
10788 enum machine_mode mode0
;
10789 enum machine_mode mode1
;
10790 enum machine_mode mode2
;
10791 enum machine_mode mode3
;
10796 enum rtx_code test_code
;
10799 if (target
== 0 || GET_MODE (target
) != SImode
)
10800 target
= gen_reg_rtx (SImode
);
10802 icode
= mips_bdesc
[fcode
].icode
;
10803 arg0
= TREE_VALUE (arglist
);
10804 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
10805 arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10806 arg3
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
10807 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
10808 op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
10809 op2
= expand_expr (arg2
, NULL_RTX
, VOIDmode
, 0);
10810 op3
= expand_expr (arg3
, NULL_RTX
, VOIDmode
, 0);
10811 tmode
= insn_data
[icode
].operand
[0].mode
;
10812 mode0
= insn_data
[icode
].operand
[1].mode
;
10813 mode1
= insn_data
[icode
].operand
[2].mode
;
10814 mode2
= insn_data
[icode
].operand
[3].mode
;
10815 mode3
= insn_data
[icode
].operand
[4].mode
;
10817 temp_target
= gen_reg_rtx (tmode
);
10819 if (!(*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
10820 op0
= copy_to_mode_reg (mode0
, op0
);
10822 if (!(*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
10823 op1
= copy_to_mode_reg (mode1
, op1
);
10825 if (!(*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
10826 op2
= copy_to_mode_reg (mode2
, op2
);
10828 if (!(*insn_data
[icode
].operand
[4].predicate
) (op3
, mode3
))
10829 op3
= copy_to_mode_reg (mode3
, op3
);
10831 pat
= GEN_FCN (icode
) (temp_target
, op0
, op1
, op2
, op3
);
10835 /* We fake the value of CCV4 to be
10836 0, if ANY is true <--> NOT 0, if ALL is false
10837 1, if ALL is true <--> NOT 1, if ANY is false
10839 Thus, we can map "enum mips_cmp_choice" to RTL comparison operators:
10840 MIPS_CMP_ANY -> (EQ 0)
10841 MIPS_CMP_ALL -> (EQ 1)
10843 However, because MIPS doesn't have "branch_all" instructions,
10844 for MIPS_CMP_ALL, we will use (NE 1) and reverse the assignment of
10845 the target to 1 first and then 0. */
10846 switch (cmp_choice
)
10862 if (cmp_choice
== MIPS_CMP_ALL
)
10863 emit_move_insn (target
, const1_rtx
);
10865 emit_move_insn (target
, const0_rtx
);
10869 label1
= gen_label_rtx ();
10870 label2
= gen_label_rtx ();
10872 = gen_rtx_IF_THEN_ELSE (VOIDmode
,
10873 gen_rtx_fmt_ee (test_code
, CCV4mode
, temp_target
,
10874 GEN_INT (compare_value
)),
10875 gen_rtx_LABEL_REF (VOIDmode
, label1
), pc_rtx
);
10877 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
, if_then_else
));
10878 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
,
10879 gen_rtx_LABEL_REF (VOIDmode
, label2
)));
10882 emit_label (label1
);
10884 if (cmp_choice
== MIPS_CMP_ALL
)
10885 emit_move_insn (target
, const0_rtx
);
10887 emit_move_insn (target
, const1_rtx
);
10889 emit_label (label2
);
10894 /* This performs a single float or double float comparison. TARGET is a
10895 suggestion of where to put the result. FCODE is the builtin function code.
10896 ARGLIST is the list of arguments. The return value is the result of the
10900 mips_expand_compare_builtin (rtx target
, unsigned int fcode
, tree arglist
)
10903 enum insn_code icode
;
10908 enum machine_mode tmode
;
10909 enum machine_mode mode0
;
10910 enum machine_mode mode1
;
10915 enum rtx_code test_code
;
10917 if (target
== 0 || GET_MODE (target
) != SImode
)
10918 target
= gen_reg_rtx (SImode
);
10920 icode
= mips_bdesc
[fcode
].icode
;
10921 arg0
= TREE_VALUE (arglist
);
10922 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
10923 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
10924 op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
10925 tmode
= insn_data
[icode
].operand
[0].mode
;
10926 mode0
= insn_data
[icode
].operand
[1].mode
;
10927 mode1
= insn_data
[icode
].operand
[2].mode
;
10929 temp_target
= gen_reg_rtx (tmode
);
10931 if (!(*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
10932 op0
= copy_to_mode_reg (mode0
, op0
);
10934 if (!(*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
10935 op1
= copy_to_mode_reg (mode1
, op1
);
10937 pat
= GEN_FCN (icode
) (temp_target
, op0
, op1
);
10941 emit_move_insn (target
, const0_rtx
);
10944 label1
= gen_label_rtx ();
10945 label2
= gen_label_rtx ();
10949 = gen_rtx_IF_THEN_ELSE (VOIDmode
,
10950 gen_rtx_fmt_ee (test_code
, CCmode
,
10951 temp_target
, const0_rtx
),
10952 gen_rtx_LABEL_REF (VOIDmode
, label1
), pc_rtx
);
10954 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
, if_then_else
));
10955 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
,
10956 gen_rtx_LABEL_REF (VOIDmode
, label2
)));
10959 emit_label (label1
);
10960 emit_move_insn (target
, const1_rtx
);
10961 emit_label (label2
);
10966 /* This performs a paired single compare, and returns an boolean value to
10967 represent the result of the compare. CMP_CHOICE is the kind of comparison
10968 we want. TARGET is a suggestion of where to put the result. FCODE is
10969 the builtin function code. ARGLIST is the list of arguments. The
10970 return value is the result of the compare. */
10973 mips_expand_ps_compare_builtin (enum mips_cmp_choice cmp_choice
, rtx target
,
10974 unsigned int fcode
, tree arglist
)
10977 enum insn_code icode
;
10982 enum machine_mode tmode
;
10983 enum machine_mode mode0
;
10984 enum machine_mode mode1
;
10989 enum rtx_code test_code
;
10992 if (target
== 0 || GET_MODE (target
) != SImode
)
10993 target
= gen_reg_rtx (SImode
);
10995 icode
= mips_bdesc
[fcode
].icode
;
10996 arg0
= TREE_VALUE (arglist
);
10997 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
10998 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
10999 op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
11000 tmode
= insn_data
[icode
].operand
[0].mode
;
11001 mode0
= insn_data
[icode
].operand
[1].mode
;
11002 mode1
= insn_data
[icode
].operand
[2].mode
;
11004 temp_target
= gen_reg_rtx (tmode
);
11006 if (!(*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
11007 op0
= copy_to_mode_reg (mode0
, op0
);
11009 if (!(*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
11010 op1
= copy_to_mode_reg (mode1
, op1
);
11012 pat
= GEN_FCN (icode
) (temp_target
, op0
, op1
);
11016 /* We fake the value of CCV2 to be
11017 0, if ANY is true <--> NOT 0, if ALL is false
11018 1, if UPPER is true <--> NOT 1, if UPPER is false
11019 2, if LOWER is true <--> NOT 2, if LOWER is false
11020 3, if ALL is true <--> NOT 3, if ANY is false
11022 Thus, we can map "enum mips_cmp_choice" to RTL comparison operators:
11023 MIPS_CMP_ANY -> (EQ 0)
11024 MIPS_CMP_UPPER -> (EQ 1)
11025 MIPS_CMP_LOWER -> (EQ 2)
11026 MIPS_CMP_ALL -> (EQ 3)
11028 However, because MIPS doesn't have "branch_all" instructions,
11029 for MIPS_CMP_ALL, we will use (NE 3) and reverse the assignment of
11030 the target to 1 fisrt and then 0. */
11031 switch (cmp_choice
)
11038 case MIPS_CMP_UPPER
:
11043 case MIPS_CMP_LOWER
:
11057 if (cmp_choice
== MIPS_CMP_ALL
)
11058 emit_move_insn (target
, const1_rtx
);
11060 emit_move_insn (target
, const0_rtx
);
11064 label1
= gen_label_rtx ();
11065 label2
= gen_label_rtx ();
11068 = gen_rtx_IF_THEN_ELSE (VOIDmode
,
11069 gen_rtx_fmt_ee (test_code
, CCV2mode
, temp_target
,
11070 GEN_INT (compare_value
)),
11071 gen_rtx_LABEL_REF (VOIDmode
, label1
), pc_rtx
);
11073 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
, if_then_else
));
11074 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
,
11075 gen_rtx_LABEL_REF (VOIDmode
, label2
)));
11078 emit_label (label1
);
11080 if (cmp_choice
== MIPS_CMP_ALL
)
11081 emit_move_insn (target
, const0_rtx
);
11083 emit_move_insn (target
, const1_rtx
);
11085 emit_label (label2
);
11090 #include "gt-mips.h"