]> gcc.gnu.org Git - gcc.git/blob - gcc/config/mips/mips.c
mips.md (UNSPEC_MOVE_TF_PS): New.
[gcc.git] / gcc / config / mips / mips.c
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.
8
9 This file is part of GCC.
10
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)
14 any later version.
15
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.
20
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. */
25
26 #include "config.h"
27 #include "system.h"
28 #include "coretypes.h"
29 #include "tm.h"
30 #include <signal.h>
31 #include "rtl.h"
32 #include "regs.h"
33 #include "hard-reg-set.h"
34 #include "real.h"
35 #include "insn-config.h"
36 #include "conditions.h"
37 #include "insn-attr.h"
38 #include "recog.h"
39 #include "toplev.h"
40 #include "output.h"
41 #include "tree.h"
42 #include "function.h"
43 #include "expr.h"
44 #include "optabs.h"
45 #include "flags.h"
46 #include "reload.h"
47 #include "tm_p.h"
48 #include "ggc.h"
49 #include "gstab.h"
50 #include "hashtab.h"
51 #include "debug.h"
52 #include "target.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"
59
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)
65
66 /* Extract the symbol or label from UNSPEC wrapper X. */
67 #define UNSPEC_ADDRESS(X) \
68 XVECEXP (X, 0, 0)
69
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))
73
74 /* The maximum distance between the top of the stack frame and the
75 value $sp has when we save & restore registers.
76
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.
80
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)
84
85 /* True if INSN is a mips.md pattern or asm statement. */
86 #define USEFUL_INSN_P(INSN) \
87 (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)
92
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) \
98 : (INSN))
99
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) \
104 : (INSN))
105
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))
112
113 /* Classifies an address.
114
115 ADDRESS_REG
116 A natural register + offset address. The register satisfies
117 mips_valid_base_register_p and the offset is a const_arith_operand.
118
119 ADDRESS_LO_SUM
120 A LO_SUM rtx. The first operand is a valid base register and
121 the second operand is a symbolic address.
122
123 ADDRESS_CONST_INT
124 A signed 16-bit constant address.
125
126 ADDRESS_SYMBOLIC:
127 A constant symbolic address (equivalent to CONSTANT_SYMBOLIC). */
128 enum mips_address_type {
129 ADDRESS_REG,
130 ADDRESS_LO_SUM,
131 ADDRESS_CONST_INT,
132 ADDRESS_SYMBOLIC
133 };
134
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);
138
139 struct mips16_constant;
140 struct mips_arg_info;
141 struct mips_address_info;
142 struct mips_integer_op;
143 struct mips_sim;
144
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 **);
181 #if TARGET_IRIX
182 static void irix_output_external_libcall (rtx);
183 #endif
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,
260 tree, int *, int);
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,
264 tree, bool);
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,
270 unsigned int, tree);
271 static rtx mips_expand_4s_compare_builtin (enum mips_cmp_choice, rtx,
272 unsigned int, tree);
273 static rtx mips_expand_ps_cond_move_builtin (enum mips_cmp_choice, rtx,
274 unsigned int, tree);
275
276 /* Structure to be filled in by compute_frame_size with register
277 save masks, and offsets for the current function. */
278
279 struct mips_frame_info GTY(())
280 {
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 */
296 };
297
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;
302
303 /* Current frame information, calculated by compute_frame_size. */
304 struct mips_frame_info frame;
305
306 /* The register to use as the global pointer within this function. */
307 unsigned int global_pointer;
308
309 /* True if mips_adjust_insn_length should ignore an instruction's
310 hazard attribute. */
311 bool ignore_hazard_length_p;
312
313 /* True if the whole function is suitable for .set noreorder and
314 .set nomacro. */
315 bool all_noreorder_p;
316
317 /* True if the function is known to have an instruction that needs $gp. */
318 bool has_gp_insn_p;
319 };
320
321 /* Information about a single argument. */
322 struct mips_arg_info
323 {
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. */
326 bool fpr_p;
327
328 /* The number of words passed in registers, rounded up. */
329 unsigned int reg_words;
330
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
333 on the stack. */
334 unsigned int reg_offset;
335
336 /* The number of words that must be passed on the stack, rounded up. */
337 unsigned int stack_words;
338
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;
342 };
343
344
345 /* Information about an address described by mips_address_type.
346
347 ADDRESS_CONST_INT
348 No fields are used.
349
350 ADDRESS_REG
351 REG is the base register and OFFSET is the constant offset.
352
353 ADDRESS_LO_SUM
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.
357
358 ADDRESS_SYMBOLIC
359 SYMBOL_TYPE is the type of symbol being referenced. */
360
361 struct mips_address_info
362 {
363 enum mips_address_type type;
364 rtx reg;
365 rtx offset;
366 enum mips_symbol_type symbol_type;
367 };
368
369
370 /* One stage in a constant building sequence. These sequences have
371 the form:
372
373 A = VALUE[0]
374 A = A CODE[1] VALUE[1]
375 A = A CODE[2] VALUE[2]
376 ...
377
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 {
381 enum rtx_code code;
382 unsigned HOST_WIDE_INT value;
383 };
384
385
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
391
392
393 /* Global variables for machine-dependent things. */
394
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;
398
399 /* Count the number of .file directives, so that .loc is up to date. */
400 int num_source_filenames = 0;
401
402 /* Count the number of sdb related labels are generated (to find block
403 start and end boundaries). */
404 int sdb_label_count = 0;
405
406 /* Next label # for each statement for Silicon Graphics IRIS systems. */
407 int sym_lineno = 0;
408
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. */
412
413 struct extern_list GTY (())
414 {
415 struct extern_list *next; /* next external */
416 const char *name; /* name of the external */
417 int size; /* size in bytes */
418 };
419
420 static GTY (()) struct extern_list *extern_head = 0;
421
422 /* Name of the file containing the current function. */
423 const char *current_function_file = "";
424
425 /* Number of nested .set noreorder, noat, nomacro, and volatile requests. */
426 int set_noreorder;
427 int set_noat;
428 int set_nomacro;
429 int set_volatile;
430
431 /* The next branch instruction is a branch likely, not branch normal. */
432 int mips_branch_likely;
433
434 /* The operands passed to the last cmpMM expander. */
435 rtx cmp_operands[2];
436
437 /* The target cpu for code generation. */
438 enum processor_type mips_arch;
439 const struct mips_cpu_info *mips_arch_info;
440
441 /* The target cpu for optimization and scheduling. */
442 enum processor_type mips_tune;
443 const struct mips_cpu_info *mips_tune_info;
444
445 /* Which instruction set architecture to use. */
446 int mips_isa;
447
448 /* Which ABI to use. */
449 int mips_abi;
450
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} */
456
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;
462
463 const char *mips_cache_flush_func = CACHE_FLUSH_FUNC;
464
465 /* If TRUE, we split addresses into their high and low parts in the RTL. */
466 int mips_split_addresses;
467
468 /* Mode used for saving/restoring general purpose registers. */
469 static enum machine_mode gpr_mode;
470
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];
474
475 /* List of all MIPS punctuation characters used by print_operand. */
476 char mips_print_operand_punct[256];
477
478 /* Map GCC register number to debugger register number. */
479 int mips_dbx_regno[FIRST_PSEUDO_REGISTER];
480
481 /* A copy of the original flag_delayed_branch: see override_options. */
482 static int mips_flag_delayed_branch;
483
484 static GTY (()) int mips_output_filename_first_time = 1;
485
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];
489
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];
494
495 /* Likewise for HIGHs. */
496 static const char *mips_hi_relocs[NUM_SYMBOL_TYPES];
497
498 /* Map hard register number to register class */
499 const enum reg_class mips_regno_to_class[] =
500 {
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
545 };
546
547 /* Map register constraint character to register class. */
548 enum reg_class mips_char_to_class[256];
549 \f
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.
553
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 },
565
566 /* MIPS I */
567 { "r3000", PROCESSOR_R3000, 1 },
568 { "r2000", PROCESSOR_R3000, 1 }, /* = r3000 */
569 { "r3900", PROCESSOR_R3900, 1 },
570
571 /* MIPS II */
572 { "r6000", PROCESSOR_R6000, 2 },
573
574 /* MIPS III */
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 },
585
586 /* MIPS IV */
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 },
593
594 /* MIPS32 */
595 { "4kc", PROCESSOR_4KC, 32 },
596 { "4kp", PROCESSOR_4KC, 32 }, /* = 4kc */
597
598 /* MIPS32 Release 2 */
599 { "m4k", PROCESSOR_M4K, 33 },
600
601 /* MIPS64 */
602 { "5kc", PROCESSOR_5KC, 64 },
603 { "20kc", PROCESSOR_20KC, 64 },
604 { "sb1", PROCESSOR_SB1, 64 },
605 { "sr71000", PROCESSOR_SR71000, 64 },
606
607 /* End marker */
608 { 0, 0, 0 }
609 };
610 \f
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
614 #endif
615 \f
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"
623
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
630
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
642
643 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
644 #define TARGET_FUNCTION_OK_FOR_SIBCALL mips_function_ok_for_sibcall
645
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
652
653 #undef TARGET_IN_SMALL_DATA_P
654 #define TARGET_IN_SMALL_DATA_P mips_in_small_data_p
655
656 #undef TARGET_MACHINE_DEPENDENT_REORG
657 #define TARGET_MACHINE_DEPENDENT_REORG mips_reorg
658
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
665
666 #undef TARGET_INIT_LIBFUNCS
667 #define TARGET_INIT_LIBFUNCS mips_init_libfuncs
668
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
673
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
680
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
685
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
690
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
699
700 #undef TARGET_VECTOR_MODE_SUPPORTED_P
701 #define TARGET_VECTOR_MODE_SUPPORTED_P mips_vector_mode_supported_p
702
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
707
708 struct gcc_target targetm = TARGET_INITIALIZER;
709 \f
710 /* Classify symbol X, which must be a SYMBOL_REF or a LABEL_REF. */
711
712 static enum mips_symbol_type
713 mips_classify_symbol (rtx x)
714 {
715 if (GET_CODE (x) == LABEL_REF)
716 {
717 if (TARGET_MIPS16)
718 return SYMBOL_CONSTANT_POOL;
719 if (TARGET_ABICALLS)
720 return SYMBOL_GOT_LOCAL;
721 return SYMBOL_GENERAL;
722 }
723
724 if (GET_CODE (x) != SYMBOL_REF)
725 abort ();
726
727 if (CONSTANT_POOL_ADDRESS_P (x))
728 {
729 if (TARGET_MIPS16)
730 return SYMBOL_CONSTANT_POOL;
731
732 if (TARGET_ABICALLS)
733 return SYMBOL_GOT_LOCAL;
734
735 if (GET_MODE_SIZE (get_pool_mode (x)) <= mips_section_threshold)
736 return SYMBOL_SMALL_DATA;
737
738 return SYMBOL_GENERAL;
739 }
740
741 if (SYMBOL_REF_SMALL_P (x))
742 return SYMBOL_SMALL_DATA;
743
744 if (TARGET_ABICALLS)
745 {
746 if (SYMBOL_REF_DECL (x) == 0)
747 return SYMBOL_REF_LOCAL_P (x) ? SYMBOL_GOT_LOCAL : SYMBOL_GOT_GLOBAL;
748
749 /* There are three cases to consider:
750
751 - o32 PIC (either with or without explicit relocs)
752 - n32/n64 PIC without explicit relocs
753 - n32/n64 PIC with explicit relocs
754
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
760 binds_local_p here.
761
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.
765
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;
771
772 return SYMBOL_GOT_LOCAL;
773 }
774
775 return SYMBOL_GENERAL;
776 }
777
778
779 /* Split X into a base and a constant offset, storing them in *BASE
780 and *OFFSET respectively. */
781
782 static void
783 mips_split_const (rtx x, rtx *base, HOST_WIDE_INT *offset)
784 {
785 *offset = 0;
786
787 if (GET_CODE (x) == CONST)
788 x = XEXP (x, 0);
789
790 if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
791 {
792 *offset += INTVAL (XEXP (x, 1));
793 x = XEXP (x, 0);
794 }
795 *base = x;
796 }
797
798
799 /* Return true if SYMBOL is a SYMBOL_REF and OFFSET + SYMBOL points
800 to the same object as SYMBOL. */
801
802 static bool
803 mips_offset_within_object_p (rtx symbol, HOST_WIDE_INT offset)
804 {
805 if (GET_CODE (symbol) != SYMBOL_REF)
806 return false;
807
808 if (CONSTANT_POOL_ADDRESS_P (symbol)
809 && offset >= 0
810 && offset < (int) GET_MODE_SIZE (get_pool_mode (symbol)))
811 return true;
812
813 if (SYMBOL_REF_DECL (symbol) != 0
814 && offset >= 0
815 && offset < int_size_in_bytes (TREE_TYPE (SYMBOL_REF_DECL (symbol))))
816 return true;
817
818 return false;
819 }
820
821
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. */
825
826 bool
827 mips_symbolic_constant_p (rtx x, enum mips_symbol_type *symbol_type)
828 {
829 HOST_WIDE_INT offset;
830
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);
836 else
837 return false;
838
839 if (offset == 0)
840 return true;
841
842 /* Check whether a nonzero offset is valid for the underlying
843 relocations. */
844 switch (*symbol_type)
845 {
846 case SYMBOL_GENERAL:
847 case SYMBOL_64_HIGH:
848 case SYMBOL_64_MID:
849 case SYMBOL_64_LOW:
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);
856
857 /* In other cases the relocations can handle any offset. */
858 return true;
859
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)
865 return true;
866
867 /* Fall through. */
868
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);
874
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);
880
881 case SYMBOL_GOT_GLOBAL:
882 case SYMBOL_GOTOFF_GLOBAL:
883 case SYMBOL_GOTOFF_CALL:
884 case SYMBOL_GOTOFF_LOADGP:
885 return false;
886 }
887 abort ();
888 }
889
890
891 /* Return true if X is a symbolic constant whose value is not split
892 into separate relocations. */
893
894 bool
895 mips_atomic_symbolic_constant_p (rtx x)
896 {
897 enum mips_symbol_type type;
898 return mips_symbolic_constant_p (x, &type) && !mips_split_p[type];
899 }
900
901
902 /* This function is used to implement REG_MODE_OK_FOR_BASE_P. */
903
904 int
905 mips_regno_mode_ok_for_base_p (int regno, enum machine_mode mode, int strict)
906 {
907 if (regno >= FIRST_PSEUDO_REGISTER)
908 {
909 if (!strict)
910 return true;
911 regno = reg_renumber[regno];
912 }
913
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)
918 return true;
919
920 /* In mips16 mode, the stack pointer can only address word and doubleword
921 values, nothing smaller. There are two problems here:
922
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.
926
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).
932
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;
937
938 return TARGET_MIPS16 ? M16_REG_P (regno) : GP_REG_P (regno);
939 }
940
941
942 /* Return true if X is a valid base register for the given mode.
943 Allow only hard registers if STRICT. */
944
945 static bool
946 mips_valid_base_register_p (rtx x, enum machine_mode mode, int strict)
947 {
948 if (!strict && GET_CODE (x) == SUBREG)
949 x = SUBREG_REG (x);
950
951 return (GET_CODE (x) == REG
952 && mips_regno_mode_ok_for_base_p (REGNO (x), mode, strict));
953 }
954
955
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. */
958
959 static bool
960 mips_symbolic_address_p (enum mips_symbol_type symbol_type,
961 enum machine_mode mode)
962 {
963 switch (symbol_type)
964 {
965 case SYMBOL_GENERAL:
966 return !TARGET_MIPS16;
967
968 case SYMBOL_SMALL_DATA:
969 return true;
970
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;
974
975 case SYMBOL_GOT_LOCAL:
976 return true;
977
978 case SYMBOL_GOT_GLOBAL:
979 /* The address will have to be loaded from the GOT first. */
980 return false;
981
982 case SYMBOL_GOTOFF_PAGE:
983 case SYMBOL_GOTOFF_GLOBAL:
984 case SYMBOL_GOTOFF_CALL:
985 case SYMBOL_GOTOFF_LOADGP:
986 case SYMBOL_64_HIGH:
987 case SYMBOL_64_MID:
988 case SYMBOL_64_LOW:
989 return true;
990 }
991 abort ();
992 }
993
994
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. */
998
999 static bool
1000 mips_classify_address (struct mips_address_info *info, rtx x,
1001 enum machine_mode mode, int strict)
1002 {
1003 switch (GET_CODE (x))
1004 {
1005 case REG:
1006 case SUBREG:
1007 info->type = ADDRESS_REG;
1008 info->reg = x;
1009 info->offset = const0_rtx;
1010 return mips_valid_base_register_p (info->reg, mode, strict);
1011
1012 case PLUS:
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));
1018
1019 case LO_SUM:
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);
1027
1028 case CONST_INT:
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);
1033
1034 case CONST:
1035 case LABEL_REF:
1036 case SYMBOL_REF:
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]);
1041
1042 default:
1043 return false;
1044 }
1045 }
1046 \f
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. */
1051
1052 static int
1053 mips_symbol_insns (enum mips_symbol_type type)
1054 {
1055 switch (type)
1056 {
1057 case SYMBOL_GENERAL:
1058 /* In mips16 code, general symbols must be fetched from the
1059 constant pool. */
1060 if (TARGET_MIPS16)
1061 return 0;
1062
1063 /* When using 64-bit symbols, we need 5 preparatory instructions,
1064 such as:
1065
1066 lui $at,%highest(symbol)
1067 daddiu $at,$at,%higher(symbol)
1068 dsll $at,$at,16
1069 daddiu $at,$at,%hi(symbol)
1070 dsll $at,$at,16
1071
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);
1075
1076 case SYMBOL_SMALL_DATA:
1077 return 1;
1078
1079 case SYMBOL_CONSTANT_POOL:
1080 /* This case is for mips16 only. Assume we'll need an
1081 extended instruction. */
1082 return 2;
1083
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
1088 for details.
1089
1090 The worst cases are:
1091
1092 (1) For local symbols when generating o32 or o64 code. The assembler
1093 will use:
1094
1095 lw $at,%got(symbol)
1096 nop
1097
1098 ...and the final address will be $at + %lo(symbol).
1099
1100 (2) For global symbols when -mxgot. The assembler will use:
1101
1102 lui $at,%got_hi(symbol)
1103 (d)addu $at,$at,$gp
1104
1105 ...and the final address will be $at + %got_lo(symbol). */
1106 return 3;
1107
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:
1113 case SYMBOL_64_MID:
1114 case SYMBOL_64_LOW:
1115 /* Check whether the offset is a 16- or 32-bit value. */
1116 return mips_split_p[type] ? 2 : 1;
1117 }
1118 abort ();
1119 }
1120
1121 /* Return true if X is a legitimate $sp-based address for mode MDOE. */
1122
1123 bool
1124 mips_stack_address_p (rtx x, enum machine_mode mode)
1125 {
1126 struct mips_address_info addr;
1127
1128 return (mips_classify_address (&addr, x, mode, false)
1129 && addr.type == ADDRESS_REG
1130 && addr.reg == stack_pointer_rtx);
1131 }
1132
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
1135 value.
1136
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. */
1141
1142 static bool
1143 mips16_unextended_reference_p (enum machine_mode mode, rtx base, rtx offset)
1144 {
1145 if (TARGET_MIPS16
1146 && GET_CODE (offset) == CONST_INT
1147 && INTVAL (offset) >= 0
1148 && (INTVAL (offset) & (GET_MODE_SIZE (mode) - 1)) == 0)
1149 {
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);
1153 }
1154 return false;
1155 }
1156
1157
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.
1160
1161 For mips16 code, count extended instructions as two instructions. */
1162
1163 int
1164 mips_address_insns (rtx x, enum machine_mode mode)
1165 {
1166 struct mips_address_info addr;
1167 int factor;
1168
1169 if (mode == BLKmode)
1170 /* BLKmode is used for single unaligned loads and stores. */
1171 factor = 1;
1172 else
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;
1175
1176 if (mips_classify_address (&addr, x, mode, false))
1177 switch (addr.type)
1178 {
1179 case ADDRESS_REG:
1180 if (TARGET_MIPS16
1181 && !mips16_unextended_reference_p (mode, addr.reg, addr.offset))
1182 return factor * 2;
1183 return factor;
1184
1185 case ADDRESS_LO_SUM:
1186 return (TARGET_MIPS16 ? factor * 2 : factor);
1187
1188 case ADDRESS_CONST_INT:
1189 return factor;
1190
1191 case ADDRESS_SYMBOLIC:
1192 return factor * mips_symbol_insns (addr.symbol_type);
1193 }
1194 return 0;
1195 }
1196
1197
1198 /* Likewise for constant X. */
1199
1200 int
1201 mips_const_insns (rtx x)
1202 {
1203 struct mips_integer_op codes[MIPS_MAX_INTEGER_OPS];
1204 enum mips_symbol_type symbol_type;
1205 HOST_WIDE_INT offset;
1206
1207 switch (GET_CODE (x))
1208 {
1209 case HIGH:
1210 if (TARGET_MIPS16
1211 || !mips_symbolic_constant_p (XEXP (x, 0), &symbol_type)
1212 || !mips_split_p[symbol_type])
1213 return 0;
1214
1215 return 1;
1216
1217 case CONST_INT:
1218 if (TARGET_MIPS16)
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
1227 : 0);
1228
1229 return mips_build_integer (codes, INTVAL (x));
1230
1231 case CONST_DOUBLE:
1232 case CONST_VECTOR:
1233 return (!TARGET_MIPS16 && x == CONST0_RTX (GET_MODE (x)) ? 1 : 0);
1234
1235 case CONST:
1236 if (CONST_GP_P (x))
1237 return 1;
1238
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);
1242
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);
1247 if (offset != 0)
1248 {
1249 int n = mips_const_insns (x);
1250 if (n != 0)
1251 {
1252 if (SMALL_OPERAND (offset))
1253 return n + 1;
1254 else
1255 return n + 1 + mips_build_integer (codes, offset);
1256 }
1257 }
1258 return 0;
1259
1260 case SYMBOL_REF:
1261 case LABEL_REF:
1262 return mips_symbol_insns (mips_classify_symbol (x));
1263
1264 default:
1265 return 0;
1266 }
1267 }
1268
1269
1270 /* Return the number of instructions needed for memory reference X.
1271 Count extended mips16 instructions as two instructions. */
1272
1273 int
1274 mips_fetch_insns (rtx x)
1275 {
1276 if (GET_CODE (x) != MEM)
1277 abort ();
1278
1279 return mips_address_insns (XEXP (x, 0), GET_MODE (x));
1280 }
1281
1282
1283 /* Return the number of instructions needed for an integer division. */
1284
1285 int
1286 mips_idiv_insns (void)
1287 {
1288 int count;
1289
1290 count = 1;
1291 if (TARGET_CHECK_ZERO_DIV)
1292 count += 2;
1293 if (TARGET_FIX_R4000 || TARGET_FIX_R4400)
1294 count++;
1295 return count;
1296 }
1297 \f
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. */
1302
1303 bool
1304 mips_legitimate_address_p (enum machine_mode mode, rtx x, int strict)
1305 {
1306 struct mips_address_info addr;
1307
1308 return mips_classify_address (&addr, x, mode, strict);
1309 }
1310
1311
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. */
1314
1315 static rtx
1316 mips_force_temporary (rtx dest, rtx value)
1317 {
1318 if (!no_new_pseudos)
1319 return force_reg (Pmode, value);
1320 else
1321 {
1322 emit_move_insn (copy_rtx (dest), value);
1323 return dest;
1324 }
1325 }
1326
1327
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. */
1330
1331 static rtx
1332 mips_split_symbol (rtx temp, rtx addr)
1333 {
1334 rtx high;
1335
1336 if (TARGET_MIPS16)
1337 high = mips16_gp_pseudo_reg ();
1338 else
1339 high = mips_force_temporary (temp, gen_rtx_HIGH (Pmode, copy_rtx (addr)));
1340 return gen_rtx_LO_SUM (Pmode, high, addr);
1341 }
1342
1343
1344 /* Return an UNSPEC address with underlying address ADDRESS and symbol
1345 type SYMBOL_TYPE. */
1346
1347 rtx
1348 mips_unspec_address (rtx address, enum mips_symbol_type symbol_type)
1349 {
1350 rtx base;
1351 HOST_WIDE_INT offset;
1352
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);
1357 }
1358
1359
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.
1363
1364 The returned expression can be used as the first operand to a LO_SUM. */
1365
1366 static rtx
1367 mips_unspec_offset_high (rtx temp, rtx base, rtx addr,
1368 enum mips_symbol_type symbol_type)
1369 {
1370 if (mips_split_p[symbol_type])
1371 {
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));
1375 }
1376 return base;
1377 }
1378
1379
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
1382 SMALL_OPERAND. */
1383
1384 static rtx
1385 mips_add_offset (rtx temp, rtx reg, HOST_WIDE_INT offset)
1386 {
1387 if (!SMALL_OPERAND (offset))
1388 {
1389 rtx high;
1390 if (TARGET_MIPS16)
1391 {
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);
1395 offset = 0;
1396 }
1397 else
1398 {
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);
1402 }
1403 high = mips_force_temporary (temp, high);
1404 reg = mips_force_temporary (temp, gen_rtx_PLUS (Pmode, high, reg));
1405 }
1406 return plus_constant (reg, offset);
1407 }
1408
1409
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. */
1414
1415 bool
1416 mips_legitimize_address (rtx *xloc, enum machine_mode mode)
1417 {
1418 enum mips_symbol_type symbol_type;
1419
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])
1424 {
1425 *xloc = mips_split_symbol (0, *xloc);
1426 return true;
1427 }
1428
1429 if (GET_CODE (*xloc) == PLUS && GET_CODE (XEXP (*xloc, 1)) == CONST_INT)
1430 {
1431 /* Handle REG + CONSTANT using mips_add_offset. */
1432 rtx reg;
1433
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)));
1438 return true;
1439 }
1440
1441 return false;
1442 }
1443
1444
1445 /* Subroutine of mips_build_integer (with the same interface).
1446 Assume that the final action in the sequence should be a left shift. */
1447
1448 static unsigned int
1449 mips_build_shift (struct mips_integer_op *codes, HOST_WIDE_INT value)
1450 {
1451 unsigned int i, shift;
1452
1453 /* Shift VALUE right until its lowest bit is set. Shift arithmetically
1454 since signed numbers are easier to load than unsigned ones. */
1455 shift = 0;
1456 while ((value & 1) == 0)
1457 value /= 2, shift++;
1458
1459 i = mips_build_integer (codes, value);
1460 codes[i].code = ASHIFT;
1461 codes[i].value = shift;
1462 return i + 1;
1463 }
1464
1465
1466 /* As for mips_build_shift, but assume that the final action will be
1467 an IOR or PLUS operation. */
1468
1469 static unsigned int
1470 mips_build_lower (struct mips_integer_op *codes, unsigned HOST_WIDE_INT value)
1471 {
1472 unsigned HOST_WIDE_INT high;
1473 unsigned int i;
1474
1475 high = value & ~(unsigned HOST_WIDE_INT) 0xffff;
1476 if (!LUI_OPERAND (high) && (value & 0x18000) == 0x18000)
1477 {
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);
1486 }
1487 else
1488 {
1489 i = mips_build_integer (codes, high);
1490 codes[i].code = IOR;
1491 codes[i].value = value & 0xffff;
1492 }
1493 return i + 1;
1494 }
1495
1496
1497 /* Fill CODES with a sequence of rtl operations to load VALUE.
1498 Return the number of operations needed. */
1499
1500 static unsigned int
1501 mips_build_integer (struct mips_integer_op *codes,
1502 unsigned HOST_WIDE_INT value)
1503 {
1504 if (SMALL_OPERAND (value)
1505 || SMALL_OPERAND_UNSIGNED (value)
1506 || LUI_OPERAND (value))
1507 {
1508 /* The value can be loaded with a single instruction. */
1509 codes[0].code = UNKNOWN;
1510 codes[0].value = value;
1511 return 1;
1512 }
1513 else if ((value & 1) != 0 || LUI_OPERAND (CONST_HIGH_PART (value)))
1514 {
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);
1518 }
1519 else if ((value & 0xffff) == 0)
1520 {
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);
1524 }
1525 else
1526 {
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;
1534
1535 cost = mips_build_shift (codes, value);
1536 alt_cost = mips_build_lower (alt_codes, value);
1537 if (alt_cost < cost)
1538 {
1539 memcpy (codes, alt_codes, alt_cost * sizeof (codes[0]));
1540 cost = alt_cost;
1541 }
1542 return cost;
1543 }
1544 }
1545
1546
1547 /* Move VALUE into register DEST. */
1548
1549 static void
1550 mips_move_integer (rtx dest, unsigned HOST_WIDE_INT value)
1551 {
1552 struct mips_integer_op codes[MIPS_MAX_INTEGER_OPS];
1553 enum machine_mode mode;
1554 unsigned int i, cost;
1555 rtx x;
1556
1557 mode = GET_MODE (dest);
1558 cost = mips_build_integer (codes, value);
1559
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++)
1564 {
1565 if (no_new_pseudos)
1566 emit_move_insn (dest, x), x = dest;
1567 else
1568 x = force_reg (mode, x);
1569 x = gen_rtx_fmt_ee (codes[i].code, mode, x, GEN_INT (codes[i].value));
1570 }
1571
1572 emit_insn (gen_rtx_SET (VOIDmode, dest, x));
1573 }
1574
1575
1576 /* Subroutine of mips_legitimize_move. Move constant SRC into register
1577 DEST given that SRC satisfies immediate_operand but doesn't satisfy
1578 move_operand. */
1579
1580 static void
1581 mips_legitimize_const_move (enum machine_mode mode, rtx dest, rtx src)
1582 {
1583 rtx base;
1584 HOST_WIDE_INT offset;
1585 enum mips_symbol_type symbol_type;
1586
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)
1590 {
1591 mips_move_integer (dest, INTVAL (src));
1592 return;
1593 }
1594
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. */
1598 if (!TARGET_MIPS16
1599 && mips_symbolic_constant_p (src, &symbol_type)
1600 && mips_split_p[symbol_type])
1601 {
1602 emit_move_insn (dest, mips_split_symbol (dest, src));
1603 return;
1604 }
1605
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);
1610 if (!TARGET_MIPS16
1611 && offset != 0
1612 && (!no_new_pseudos || SMALL_OPERAND (offset)))
1613 {
1614 base = mips_force_temporary (dest, base);
1615 emit_move_insn (dest, mips_add_offset (0, base, offset));
1616 return;
1617 }
1618
1619 src = force_const_mem (mode, src);
1620
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);
1626 }
1627
1628
1629 /* If (set DEST SRC) is not a valid instruction, emit an equivalent
1630 sequence that is valid. */
1631
1632 bool
1633 mips_legitimize_move (enum machine_mode mode, rtx dest, rtx src)
1634 {
1635 if (!register_operand (dest, mode) && !reg_or_0_operand (src, mode))
1636 {
1637 emit_move_insn (dest, force_reg (mode, src));
1638 return true;
1639 }
1640
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)))
1645 {
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)));
1651 else
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)));
1655 return true;
1656 }
1657
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))
1661 {
1662 mips_legitimize_const_move (mode, dest, src);
1663 set_unique_reg_note (get_last_insn (), REG_EQUAL, copy_rtx (src));
1664 return true;
1665 }
1666 return false;
1667 }
1668 \f
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. */
1673
1674 static int
1675 m16_check_op (rtx op, int low, int high, int mask)
1676 {
1677 return (GET_CODE (op) == CONST_INT
1678 && INTVAL (op) >= low
1679 && INTVAL (op) <= high
1680 && (INTVAL (op) & mask) == 0);
1681 }
1682
1683 int
1684 m16_uimm3_b (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1685 {
1686 return m16_check_op (op, 0x1, 0x8, 0);
1687 }
1688
1689 int
1690 m16_simm4_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1691 {
1692 return m16_check_op (op, - 0x8, 0x7, 0);
1693 }
1694
1695 int
1696 m16_nsimm4_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1697 {
1698 return m16_check_op (op, - 0x7, 0x8, 0);
1699 }
1700
1701 int
1702 m16_simm5_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1703 {
1704 return m16_check_op (op, - 0x10, 0xf, 0);
1705 }
1706
1707 int
1708 m16_nsimm5_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1709 {
1710 return m16_check_op (op, - 0xf, 0x10, 0);
1711 }
1712
1713 int
1714 m16_uimm5_4 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1715 {
1716 return m16_check_op (op, (- 0x10) << 2, 0xf << 2, 3);
1717 }
1718
1719 int
1720 m16_nuimm5_4 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1721 {
1722 return m16_check_op (op, (- 0xf) << 2, 0x10 << 2, 3);
1723 }
1724
1725 int
1726 m16_simm8_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1727 {
1728 return m16_check_op (op, - 0x80, 0x7f, 0);
1729 }
1730
1731 int
1732 m16_nsimm8_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1733 {
1734 return m16_check_op (op, - 0x7f, 0x80, 0);
1735 }
1736
1737 int
1738 m16_uimm8_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1739 {
1740 return m16_check_op (op, 0x0, 0xff, 0);
1741 }
1742
1743 int
1744 m16_nuimm8_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1745 {
1746 return m16_check_op (op, - 0xff, 0x0, 0);
1747 }
1748
1749 int
1750 m16_uimm8_m1_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1751 {
1752 return m16_check_op (op, - 0x1, 0xfe, 0);
1753 }
1754
1755 int
1756 m16_uimm8_4 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1757 {
1758 return m16_check_op (op, 0x0, 0xff << 2, 3);
1759 }
1760
1761 int
1762 m16_nuimm8_4 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1763 {
1764 return m16_check_op (op, (- 0xff) << 2, 0x0, 3);
1765 }
1766
1767 int
1768 m16_simm8_8 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1769 {
1770 return m16_check_op (op, (- 0x80) << 3, 0x7f << 3, 7);
1771 }
1772
1773 int
1774 m16_nsimm8_8 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1775 {
1776 return m16_check_op (op, (- 0x7f) << 3, 0x80 << 3, 7);
1777 }
1778 \f
1779 static bool
1780 mips_rtx_costs (rtx x, int code, int outer_code, int *total)
1781 {
1782 enum machine_mode mode = GET_MODE (x);
1783
1784 switch (code)
1785 {
1786 case CONST_INT:
1787 if (!TARGET_MIPS16)
1788 {
1789 /* Always return 0, since we don't have different sized
1790 instructions, hence different costs according to Richard
1791 Kenner */
1792 *total = 0;
1793 return true;
1794 }
1795
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)
1800 {
1801 if (INTVAL (x) >= 1 && INTVAL (x) <= 8)
1802 *total = 0;
1803 else
1804 *total = COSTS_N_INSNS (1);
1805 return true;
1806 }
1807
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)
1811 {
1812 *total = 0;
1813 return true;
1814 }
1815
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)
1824 {
1825 *total = 0;
1826 return true;
1827 }
1828
1829 /* Equality comparisons with 0 are cheap. */
1830 if (((outer_code) == EQ || (outer_code) == NE)
1831 && INTVAL (x) == 0)
1832 {
1833 *total = 0;
1834 return true;
1835 }
1836
1837 /* Constants in the range 0...255 can be loaded with an unextended
1838 instruction. They are therefore as cheap as a register move.
1839
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
1844 && INTVAL (x) >= 0
1845 && INTVAL (x) < 256)
1846 {
1847 *total = 0;
1848 return true;
1849 }
1850
1851 /* Otherwise fall through to the handling below. */
1852
1853 case CONST:
1854 case SYMBOL_REF:
1855 case LABEL_REF:
1856 case CONST_DOUBLE:
1857 if (LEGITIMATE_CONSTANT_P (x))
1858 {
1859 *total = COSTS_N_INSNS (1);
1860 return true;
1861 }
1862 else
1863 {
1864 /* The value will need to be fetched from the constant pool. */
1865 *total = CONSTANT_POOL_COST;
1866 return true;
1867 }
1868
1869 case MEM:
1870 {
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));
1874 if (n > 0)
1875 {
1876 *total = COSTS_N_INSNS (1 + n);
1877 return true;
1878 }
1879 return false;
1880 }
1881
1882 case FFS:
1883 *total = COSTS_N_INSNS (6);
1884 return true;
1885
1886 case NOT:
1887 *total = COSTS_N_INSNS ((mode == DImode && !TARGET_64BIT) ? 2 : 1);
1888 return true;
1889
1890 case AND:
1891 case IOR:
1892 case XOR:
1893 if (mode == DImode && !TARGET_64BIT)
1894 {
1895 *total = COSTS_N_INSNS (2);
1896 return true;
1897 }
1898 return false;
1899
1900 case ASHIFT:
1901 case ASHIFTRT:
1902 case LSHIFTRT:
1903 if (mode == DImode && !TARGET_64BIT)
1904 {
1905 *total = COSTS_N_INSNS ((GET_CODE (XEXP (x, 1)) == CONST_INT)
1906 ? 4 : 12);
1907 return true;
1908 }
1909 return false;
1910
1911 case ABS:
1912 if (mode == SFmode || mode == DFmode)
1913 *total = COSTS_N_INSNS (1);
1914 else
1915 *total = COSTS_N_INSNS (4);
1916 return true;
1917
1918 case LO_SUM:
1919 *total = COSTS_N_INSNS (1);
1920 return true;
1921
1922 case PLUS:
1923 case MINUS:
1924 if (mode == SFmode || mode == DFmode)
1925 {
1926 if (TUNE_MIPS3000 || TUNE_MIPS3900)
1927 *total = COSTS_N_INSNS (2);
1928 else if (TUNE_MIPS6000)
1929 *total = COSTS_N_INSNS (3);
1930 else if (TUNE_SB1)
1931 *total = COSTS_N_INSNS (4);
1932 else
1933 *total = COSTS_N_INSNS (6);
1934 return true;
1935 }
1936 if (mode == DImode && !TARGET_64BIT)
1937 {
1938 *total = COSTS_N_INSNS (4);
1939 return true;
1940 }
1941 return false;
1942
1943 case NEG:
1944 if (mode == DImode && !TARGET_64BIT)
1945 {
1946 *total = 4;
1947 return true;
1948 }
1949 return false;
1950
1951 case MULT:
1952 if (mode == SFmode)
1953 {
1954 if (TUNE_MIPS3000
1955 || TUNE_MIPS3900
1956 || TUNE_MIPS5000
1957 || TUNE_SB1)
1958 *total = COSTS_N_INSNS (4);
1959 else if (TUNE_MIPS6000
1960 || TUNE_MIPS5400
1961 || TUNE_MIPS5500)
1962 *total = COSTS_N_INSNS (5);
1963 else
1964 *total = COSTS_N_INSNS (7);
1965 return true;
1966 }
1967
1968 if (mode == DFmode)
1969 {
1970 if (TUNE_SB1)
1971 *total = COSTS_N_INSNS (4);
1972 else if (TUNE_MIPS3000
1973 || TUNE_MIPS3900
1974 || TUNE_MIPS5000)
1975 *total = COSTS_N_INSNS (5);
1976 else if (TUNE_MIPS6000
1977 || TUNE_MIPS5400
1978 || TUNE_MIPS5500)
1979 *total = COSTS_N_INSNS (6);
1980 else
1981 *total = COSTS_N_INSNS (8);
1982 return true;
1983 }
1984
1985 if (TUNE_MIPS3000)
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);
2001 else
2002 *total = COSTS_N_INSNS (10);
2003 return true;
2004
2005 case DIV:
2006 case MOD:
2007 if (mode == SFmode)
2008 {
2009 if (TUNE_MIPS3000
2010 || TUNE_MIPS3900)
2011 *total = COSTS_N_INSNS (12);
2012 else if (TUNE_MIPS6000)
2013 *total = COSTS_N_INSNS (15);
2014 else if (TUNE_SB1)
2015 *total = COSTS_N_INSNS (24);
2016 else if (TUNE_MIPS5400 || TUNE_MIPS5500)
2017 *total = COSTS_N_INSNS (30);
2018 else
2019 *total = COSTS_N_INSNS (23);
2020 return true;
2021 }
2022
2023 if (mode == DFmode)
2024 {
2025 if (TUNE_MIPS3000
2026 || TUNE_MIPS3900)
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);
2032 else if (TUNE_SB1)
2033 *total = COSTS_N_INSNS (32);
2034 else
2035 *total = COSTS_N_INSNS (36);
2036 return true;
2037 }
2038 /* Fall through. */
2039
2040 case UDIV:
2041 case UMOD:
2042 if (TUNE_MIPS3000
2043 || TUNE_MIPS3900)
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);
2049 else if (TUNE_SB1)
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);
2053 else
2054 *total = COSTS_N_INSNS (69);
2055 return true;
2056
2057 case SIGN_EXTEND:
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);
2064 else
2065 *total = COSTS_N_INSNS (2);
2066 return true;
2067
2068 case ZERO_EXTEND:
2069 if (TARGET_64BIT && mode == DImode
2070 && GET_MODE (XEXP (x, 0)) == SImode)
2071 *total = COSTS_N_INSNS (2);
2072 else
2073 *total = COSTS_N_INSNS (1);
2074 return true;
2075
2076 default:
2077 return false;
2078 }
2079 }
2080
2081 /* Provide the costs of an addressing mode that contains ADDR.
2082 If ADDR is not a valid address, its cost is irrelevant. */
2083
2084 static int
2085 mips_address_cost (rtx addr)
2086 {
2087 return mips_address_insns (addr, SImode);
2088 }
2089 \f
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. */
2093
2094 rtx
2095 mips_subword (rtx op, int high_p)
2096 {
2097 unsigned int byte;
2098 enum machine_mode mode;
2099
2100 mode = GET_MODE (op);
2101 if (mode == VOIDmode)
2102 mode = DImode;
2103
2104 if (TARGET_BIG_ENDIAN ? !high_p : high_p)
2105 byte = UNITS_PER_WORD;
2106 else
2107 byte = 0;
2108
2109 if (GET_CODE (op) == REG)
2110 {
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);
2115 }
2116
2117 if (GET_CODE (op) == MEM)
2118 return mips_rewrite_small_data (adjust_address (op, word_mode, byte));
2119
2120 return simplify_gen_subreg (word_mode, op, mode, byte);
2121 }
2122
2123
2124 /* Return true if a 64-bit move from SRC to DEST should be split into two. */
2125
2126 bool
2127 mips_split_64bit_move_p (rtx dest, rtx src)
2128 {
2129 if (TARGET_64BIT)
2130 return false;
2131
2132 /* FP->FP moves can be done in a single instruction. */
2133 if (FP_REG_RTX_P (src) && FP_REG_RTX_P (dest))
2134 return false;
2135
2136 /* Check for floating-point loads and stores. They can be done using
2137 ldc1 and sdc1 on MIPS II and above. */
2138 if (mips_isa > 1)
2139 {
2140 if (FP_REG_RTX_P (dest) && GET_CODE (src) == MEM)
2141 return false;
2142 if (FP_REG_RTX_P (src) && GET_CODE (dest) == MEM)
2143 return false;
2144 }
2145 return true;
2146 }
2147
2148
2149 /* Split a 64-bit move from SRC to DEST assuming that
2150 mips_split_64bit_move_p holds.
2151
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:
2156
2157 (set (reg:SI $f0) (mem:SI ...))
2158 (set (reg:SI $f1) (mem:SI ...))
2159
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. */
2163
2164 void
2165 mips_split_64bit_move (rtx dest, rtx src)
2166 {
2167 if (FP_REG_RTX_P (dest))
2168 {
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),
2172 copy_rtx (dest)));
2173 }
2174 else if (FP_REG_RTX_P (src))
2175 {
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));
2179 }
2180 else
2181 {
2182 /* The operation can be split into two normal moves. Decide in
2183 which order to do them. */
2184 rtx low_dest;
2185
2186 low_dest = mips_subword (dest, 0);
2187 if (GET_CODE (low_dest) == REG
2188 && reg_overlap_mentioned_p (low_dest, src))
2189 {
2190 emit_move_insn (mips_subword (dest, 1), mips_subword (src, 1));
2191 emit_move_insn (low_dest, mips_subword (src, 0));
2192 }
2193 else
2194 {
2195 emit_move_insn (low_dest, mips_subword (src, 0));
2196 emit_move_insn (mips_subword (dest, 1), mips_subword (src, 1));
2197 }
2198 }
2199 }
2200 \f
2201 /* Return the appropriate instructions to move SRC into DEST. Assume
2202 that SRC is operand 1 and DEST is operand 0. */
2203
2204 const char *
2205 mips_output_move (rtx dest, rtx src)
2206 {
2207 enum rtx_code dest_code, src_code;
2208 bool dbl_p;
2209
2210 dest_code = GET_CODE (dest);
2211 src_code = GET_CODE (src);
2212 dbl_p = (GET_MODE_SIZE (GET_MODE (dest)) == 8);
2213
2214 if (dbl_p && mips_split_64bit_move_p (dest, src))
2215 return "#";
2216
2217 if ((src_code == REG && GP_REG_P (REGNO (src)))
2218 || (!TARGET_MIPS16 && src == CONST0_RTX (GET_MODE (dest))))
2219 {
2220 if (dest_code == REG)
2221 {
2222 if (GP_REG_P (REGNO (dest)))
2223 return "move\t%0,%z1";
2224
2225 if (MD_REG_P (REGNO (dest)))
2226 return "mt%0\t%z1";
2227
2228 if (FP_REG_P (REGNO (dest)))
2229 return (dbl_p ? "dmtc1\t%z1,%0" : "mtc1\t%z1,%0");
2230
2231 if (ALL_COP_REG_P (REGNO (dest)))
2232 {
2233 static char retval[] = "dmtc_\t%z1,%0";
2234
2235 retval[4] = COPNUM_AS_CHAR_FROM_REGNUM (REGNO (dest));
2236 return (dbl_p ? retval : retval + 1);
2237 }
2238 }
2239 if (dest_code == MEM)
2240 return (dbl_p ? "sd\t%z1,%0" : "sw\t%z1,%0");
2241 }
2242 if (dest_code == REG && GP_REG_P (REGNO (dest)))
2243 {
2244 if (src_code == REG)
2245 {
2246 if (ST_REG_P (REGNO (src)) && ISA_HAS_8CC)
2247 return "lui\t%0,0x3f80\n\tmovf\t%0,%.,%1";
2248
2249 if (FP_REG_P (REGNO (src)))
2250 return (dbl_p ? "dmfc1\t%0,%1" : "mfc1\t%0,%1");
2251
2252 if (ALL_COP_REG_P (REGNO (src)))
2253 {
2254 static char retval[] = "dmfc_\t%0,%1";
2255
2256 retval[4] = COPNUM_AS_CHAR_FROM_REGNUM (REGNO (src));
2257 return (dbl_p ? retval : retval + 1);
2258 }
2259 }
2260
2261 if (src_code == MEM)
2262 return (dbl_p ? "ld\t%0,%1" : "lw\t%0,%1");
2263
2264 if (src_code == CONST_INT)
2265 {
2266 /* Don't use the X format, because that will give out of
2267 range numbers for 64 bit hosts and 32 bit targets. */
2268 if (!TARGET_MIPS16)
2269 return "li\t%0,%1\t\t\t# %X1";
2270
2271 if (INTVAL (src) >= 0 && INTVAL (src) <= 0xffff)
2272 return "li\t%0,%1";
2273
2274 if (INTVAL (src) < 0 && INTVAL (src) >= -0xffff)
2275 return "#";
2276 }
2277
2278 if (src_code == HIGH)
2279 return "lui\t%0,%h1";
2280
2281 if (CONST_GP_P (src))
2282 return "move\t%0,%1";
2283
2284 if (symbolic_operand (src, VOIDmode))
2285 return (dbl_p ? "dla\t%0,%1" : "la\t%0,%1");
2286 }
2287 if (src_code == REG && FP_REG_P (REGNO (src)))
2288 {
2289 if (dest_code == REG && FP_REG_P (REGNO (dest)))
2290 {
2291 if (GET_MODE (dest) == V2SFmode)
2292 return "mov.ps\t%0,%1";
2293 else
2294 return (dbl_p ? "mov.d\t%0,%1" : "mov.s\t%0,%1");
2295 }
2296
2297 if (dest_code == MEM)
2298 return (dbl_p ? "sdc1\t%1,%0" : "swc1\t%1,%0");
2299 }
2300 if (dest_code == REG && FP_REG_P (REGNO (dest)))
2301 {
2302 if (src_code == MEM)
2303 return (dbl_p ? "ldc1\t%0,%1" : "lwc1\t%0,%1");
2304 }
2305 if (dest_code == REG && ALL_COP_REG_P (REGNO (dest)) && src_code == MEM)
2306 {
2307 static char retval[] = "l_c_\t%0,%1";
2308
2309 retval[1] = (dbl_p ? 'd' : 'w');
2310 retval[3] = COPNUM_AS_CHAR_FROM_REGNUM (REGNO (dest));
2311 return retval;
2312 }
2313 if (dest_code == MEM && src_code == REG && ALL_COP_REG_P (REGNO (src)))
2314 {
2315 static char retval[] = "s_c_\t%1,%0";
2316
2317 retval[1] = (dbl_p ? 'd' : 'w');
2318 retval[3] = COPNUM_AS_CHAR_FROM_REGNUM (REGNO (src));
2319 return retval;
2320 }
2321 abort ();
2322 }
2323 \f
2324 /* Restore $gp from its save slot. Valid only when using o32 or
2325 o64 abicalls. */
2326
2327 void
2328 mips_restore_gp (void)
2329 {
2330 rtx address, slot;
2331
2332 if (!TARGET_ABICALLS || !TARGET_OLDABI)
2333 abort ();
2334
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);
2341
2342 emit_move_insn (pic_offset_table_rtx, slot);
2343 if (!TARGET_EXPLICIT_RELOCS)
2344 emit_insn (gen_blockage ());
2345 }
2346 \f
2347 /* Emit an instruction of the form (set TARGET (CODE OP0 OP1)). */
2348
2349 static void
2350 mips_emit_binary (enum rtx_code code, rtx target, rtx op0, rtx op1)
2351 {
2352 emit_insn (gen_rtx_SET (VOIDmode, target,
2353 gen_rtx_fmt_ee (code, GET_MODE (target), op0, op1)));
2354 }
2355
2356 /* Return true if CMP1 is a suitable second operand for relational
2357 operator CODE. See also the *sCC patterns in mips.md. */
2358
2359 static bool
2360 mips_relational_operand_ok_p (enum rtx_code code, rtx cmp1)
2361 {
2362 switch (code)
2363 {
2364 case GT:
2365 case GTU:
2366 return reg_or_0_operand (cmp1, VOIDmode);
2367
2368 case GE:
2369 case GEU:
2370 return !TARGET_MIPS16 && cmp1 == const1_rtx;
2371
2372 case LT:
2373 case LTU:
2374 return arith_operand (cmp1, VOIDmode);
2375
2376 case LE:
2377 return sle_operand (cmp1, VOIDmode);
2378
2379 case LEU:
2380 return sleu_operand (cmp1, VOIDmode);
2381
2382 default:
2383 abort ();
2384 }
2385 }
2386
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. */
2391
2392 static void
2393 mips_emit_int_relational (enum rtx_code code, bool *invert_ptr,
2394 rtx target, rtx cmp0, rtx cmp1)
2395 {
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
2399 and try again. */
2400 if (mips_relational_operand_ok_p (code, cmp1))
2401 mips_emit_binary (code, target, cmp0, cmp1);
2402 else
2403 {
2404 enum rtx_code inv_code = reverse_condition (code);
2405 if (!mips_relational_operand_ok_p (inv_code, cmp1))
2406 {
2407 cmp1 = force_reg (GET_MODE (cmp0), cmp1);
2408 mips_emit_int_relational (code, invert_ptr, target, cmp0, cmp1);
2409 }
2410 else if (invert_ptr == 0)
2411 {
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);
2415 }
2416 else
2417 {
2418 *invert_ptr = !*invert_ptr;
2419 mips_emit_binary (inv_code, target, cmp0, cmp1);
2420 }
2421 }
2422 }
2423
2424 /* Return a register that is zero iff CMP0 and CMP1 are equal.
2425 The register will have the same mode as CMP0. */
2426
2427 static rtx
2428 mips_zero_if_equal (rtx cmp0, rtx cmp1)
2429 {
2430 if (cmp1 == const0_rtx)
2431 return cmp0;
2432
2433 if (uns_arith_operand (cmp1, VOIDmode))
2434 return expand_binop (GET_MODE (cmp0), xor_optab,
2435 cmp0, cmp1, 0, 0, OPTAB_DIRECT);
2436
2437 return expand_binop (GET_MODE (cmp0), sub_optab,
2438 cmp0, cmp1, 0, 0, OPTAB_DIRECT);
2439 }
2440
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.
2444
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
2448 conditions are:
2449
2450 - EQ/NE between two registers.
2451 - any comparison between a register and zero. */
2452
2453 static void
2454 mips_emit_compare (enum rtx_code *code, rtx *op0, rtx *op1, bool need_eq_ne_p)
2455 {
2456 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) == MODE_INT)
2457 {
2458 if (!need_eq_ne_p && cmp_operands[1] == const0_rtx)
2459 {
2460 *op0 = cmp_operands[0];
2461 *op1 = cmp_operands[1];
2462 }
2463 else if (*code == EQ || *code == NE)
2464 {
2465 if (need_eq_ne_p)
2466 {
2467 *op0 = mips_zero_if_equal (cmp_operands[0], cmp_operands[1]);
2468 *op1 = const0_rtx;
2469 }
2470 else
2471 {
2472 *op0 = cmp_operands[0];
2473 *op1 = force_reg (GET_MODE (*op0), cmp_operands[1]);
2474 }
2475 }
2476 else
2477 {
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]));
2482 *op1 = const0_rtx;
2483 mips_emit_int_relational (*code, &invert, *op0,
2484 cmp_operands[0], cmp_operands[1]);
2485 *code = (invert ? EQ : NE);
2486 }
2487 }
2488 else
2489 {
2490 enum rtx_code cmp_code;
2491
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.
2495
2496 Set CMP_CODE to the code of the comparison instruction and
2497 *CODE to the code that the branch or move should use. */
2498 switch (*code)
2499 {
2500 case NE:
2501 case UNGE:
2502 case UNGT:
2503 case LTGT:
2504 case ORDERED:
2505 cmp_code = reverse_condition_maybe_unordered (*code);
2506 *code = EQ;
2507 break;
2508
2509 default:
2510 cmp_code = *code;
2511 *code = NE;
2512 break;
2513 }
2514 *op0 = (ISA_HAS_8CC
2515 ? gen_reg_rtx (CCmode)
2516 : gen_rtx_REG (CCmode, FPSW_REGNUM));
2517 *op1 = const0_rtx;
2518 mips_emit_binary (cmp_code, *op0, cmp_operands[0], cmp_operands[1]);
2519 }
2520 }
2521 \f
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.
2524
2525 On 64-bit targets, TARGET may be wider than cmp_operands[0]. */
2526
2527 bool
2528 mips_emit_scc (enum rtx_code code, rtx target)
2529 {
2530 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
2531 return false;
2532
2533 target = gen_lowpart (GET_MODE (cmp_operands[0]), target);
2534 if (code == EQ || code == NE)
2535 {
2536 rtx zie = mips_zero_if_equal (cmp_operands[0], cmp_operands[1]);
2537 mips_emit_binary (code, target, zie, const0_rtx);
2538 }
2539 else
2540 mips_emit_int_relational (code, 0, target,
2541 cmp_operands[0], cmp_operands[1]);
2542 return true;
2543 }
2544
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}. */
2548
2549 void
2550 gen_conditional_branch (rtx *operands, enum rtx_code code)
2551 {
2552 rtx op0, op1, target;
2553
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),
2557 op0, op1),
2558 gen_rtx_LABEL_REF (VOIDmode, operands[0]),
2559 pc_rtx);
2560 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, target));
2561 }
2562
2563 /* Emit the common code for conditional moves. OPERANDS is the array
2564 of operands passed to the conditional move define_expand. */
2565
2566 void
2567 gen_conditional_move (rtx *operands)
2568 {
2569 enum rtx_code code;
2570 rtx op0, op1;
2571
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,
2577 GET_MODE (op0),
2578 op0, op1),
2579 operands[2], operands[3])));
2580 }
2581
2582 /* Emit a conditional trap. OPERANDS is the array of operands passed to
2583 the conditional_trap expander. */
2584
2585 void
2586 mips_gen_conditional_trap (rtx *operands)
2587 {
2588 rtx op0, op1;
2589 enum rtx_code cmp_code = GET_CODE (operands[0]);
2590 enum machine_mode mode = GET_MODE (cmp_operands[0]);
2591
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. */
2595 switch (cmp_code)
2596 {
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;
2601 default: break;
2602 }
2603 if (cmp_code == GET_CODE (operands[0]))
2604 {
2605 op0 = cmp_operands[0];
2606 op1 = cmp_operands[1];
2607 }
2608 else
2609 {
2610 op0 = cmp_operands[1];
2611 op1 = cmp_operands[0];
2612 }
2613 op0 = force_reg (mode, op0);
2614 if (!arith_operand (op1, mode))
2615 op1 = force_reg (mode, op1);
2616
2617 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
2618 gen_rtx_fmt_ee (cmp_code, mode, op0, op1),
2619 operands[1]));
2620 }
2621 \f
2622 /* Load function address ADDR into register DEST. SIBCALL_P is true
2623 if the address is needed for a sibling call. */
2624
2625 static void
2626 mips_load_call_address (rtx dest, rtx addr, int sibcall_p)
2627 {
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))
2635 {
2636 rtx high, lo_sum_symbol;
2637
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));
2643 else
2644 emit_insn (gen_load_calldi (dest, high, lo_sum_symbol));
2645 }
2646 else
2647 emit_move_insn (dest, addr);
2648 }
2649
2650
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
2656 a normal call. */
2657
2658 void
2659 mips_expand_call (rtx result, rtx addr, rtx args_size, rtx aux, int sibcall_p)
2660 {
2661 rtx orig_addr, pattern, insn;
2662
2663 orig_addr = addr;
2664 if (!call_insn_operand (addr, VOIDmode))
2665 {
2666 addr = gen_reg_rtx (Pmode);
2667 mips_load_call_address (addr, orig_addr, sibcall_p);
2668 }
2669
2670 if (TARGET_MIPS16
2671 && mips16_hard_float
2672 && build_mips16_call_stub (result, addr, args_size,
2673 aux == 0 ? 0 : (int) GET_MODE (aux)))
2674 return;
2675
2676 if (result == 0)
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)
2681 {
2682 rtx reg1, reg2;
2683
2684 reg1 = XEXP (XVECEXP (result, 0, 0), 0);
2685 reg2 = XEXP (XVECEXP (result, 0, 1), 0);
2686 pattern =
2687 (sibcall_p
2688 ? gen_sibcall_value_multiple_internal (reg1, addr, args_size, reg2)
2689 : gen_call_value_multiple_internal (reg1, addr, args_size, reg2));
2690 }
2691 else
2692 pattern = (sibcall_p
2693 ? gen_sibcall_value_internal (result, addr, args_size)
2694 : gen_call_value_internal (result, addr, args_size));
2695
2696 insn = emit_call_insn (pattern);
2697
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);
2701 }
2702
2703
2704 /* We can handle any sibcall when TARGET_SIBCALLS is true. */
2705
2706 static bool
2707 mips_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
2708 tree exp ATTRIBUTE_UNUSED)
2709 {
2710 return TARGET_SIBCALLS;
2711 }
2712 \f
2713 /* Emit code to move general operand SRC into condition-code
2714 register DEST. SCRATCH is a scratch TFmode float register.
2715 The sequence is:
2716
2717 FP1 = SRC
2718 FP2 = 0.0f
2719 DEST = FP2 < FP1
2720
2721 where FP1 and FP2 are single-precision float registers
2722 taken from SCRATCH. */
2723
2724 void
2725 mips_emit_fcc_reload (rtx dest, rtx src, rtx scratch)
2726 {
2727 rtx fp1, fp2;
2728
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));
2734
2735 fp1 = gen_rtx_REG (SFmode, REGNO (scratch));
2736 fp2 = gen_rtx_REG (SFmode, REGNO (scratch) + FP_INC);
2737
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));
2741 }
2742 \f
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. */
2746
2747 void
2748 mips_set_return_address (rtx address, rtx scratch)
2749 {
2750 rtx slot_address;
2751
2752 compute_frame_size (get_frame_size ());
2753 if (((cfun->machine->frame.mask >> 31) & 1) == 0)
2754 abort ();
2755 slot_address = mips_add_offset (scratch, stack_pointer_rtx,
2756 cfun->machine->frame.gp_sp_offset);
2757
2758 emit_move_insn (gen_rtx_MEM (GET_MODE (address), slot_address), address);
2759 }
2760 \f
2761 /* Emit straight-line code to move LENGTH bytes from SRC to DEST.
2762 Assume that the areas do not overlap. */
2763
2764 static void
2765 mips_block_move_straight (rtx dest, rtx src, HOST_WIDE_INT length)
2766 {
2767 HOST_WIDE_INT offset, delta;
2768 unsigned HOST_WIDE_INT bits;
2769 int i;
2770 enum machine_mode mode;
2771 rtx *regs;
2772
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;
2781 else
2782 bits = BITS_PER_WORD;
2783
2784 mode = mode_for_size (bits, MODE_INT, 0);
2785 delta = bits / BITS_PER_UNIT;
2786
2787 /* Allocate a buffer for the temporary registers. */
2788 regs = alloca (sizeof (rtx) * length / delta);
2789
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++)
2793 {
2794 regs[i] = gen_reg_rtx (mode);
2795 if (MEM_ALIGN (src) >= bits)
2796 emit_move_insn (regs[i], adjust_address (src, mode, offset));
2797 else
2798 {
2799 rtx part = adjust_address (src, BLKmode, offset);
2800 if (!mips_expand_unaligned_load (regs[i], part, bits, 0))
2801 abort ();
2802 }
2803 }
2804
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]);
2809 else
2810 {
2811 rtx part = adjust_address (dest, BLKmode, offset);
2812 if (!mips_expand_unaligned_store (part, regs[i], bits, 0))
2813 abort ();
2814 }
2815
2816 /* Mop up any left-over bytes. */
2817 if (offset < length)
2818 {
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);
2823 }
2824 }
2825 \f
2826 #define MAX_MOVE_REGS 4
2827 #define MAX_MOVE_BYTES (MAX_MOVE_REGS * UNITS_PER_WORD)
2828
2829
2830 /* Helper function for doing a loop-based block operation on memory
2831 reference MEM. Each iteration of the loop will operate on LENGTH
2832 bytes of MEM.
2833
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. */
2837
2838 static void
2839 mips_adjust_block_mem (rtx mem, HOST_WIDE_INT length,
2840 rtx *loop_reg, rtx *loop_mem)
2841 {
2842 *loop_reg = copy_addr_to_reg (XEXP (mem, 0));
2843
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));
2848 }
2849
2850
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. */
2854
2855 static void
2856 mips_block_move_loop (rtx dest, rtx src, HOST_WIDE_INT length)
2857 {
2858 rtx label, src_reg, dest_reg, final_src;
2859 HOST_WIDE_INT leftover;
2860
2861 leftover = length % MAX_MOVE_BYTES;
2862 length -= leftover;
2863
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);
2867
2868 /* Calculate the value that SRC_REG should have after the last iteration
2869 of the loop. */
2870 final_src = expand_simple_binop (Pmode, PLUS, src_reg, GEN_INT (length),
2871 0, 0, OPTAB_WIDEN);
2872
2873 /* Emit the start of the loop. */
2874 label = gen_label_rtx ();
2875 emit_label (label);
2876
2877 /* Emit the loop body. */
2878 mips_block_move_straight (dest, src, MAX_MOVE_BYTES);
2879
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));
2883
2884 /* Emit the loop condition. */
2885 if (Pmode == DImode)
2886 emit_insn (gen_cmpdi (src_reg, final_src));
2887 else
2888 emit_insn (gen_cmpsi (src_reg, final_src));
2889 emit_jump_insn (gen_bne (label));
2890
2891 /* Mop up any left-over bytes. */
2892 if (leftover)
2893 mips_block_move_straight (dest, src, leftover);
2894 }
2895 \f
2896 /* Expand a movmemsi instruction. */
2897
2898 bool
2899 mips_expand_block_move (rtx dest, rtx src, rtx length)
2900 {
2901 if (GET_CODE (length) == CONST_INT)
2902 {
2903 if (INTVAL (length) <= 2 * MAX_MOVE_BYTES)
2904 {
2905 mips_block_move_straight (dest, src, INTVAL (length));
2906 return true;
2907 }
2908 else if (optimize)
2909 {
2910 mips_block_move_loop (dest, src, INTVAL (length));
2911 return true;
2912 }
2913 }
2914 return false;
2915 }
2916 \f
2917 /* Argument support functions. */
2918
2919 /* Initialize CUMULATIVE_ARGS for a function. */
2920
2921 void
2922 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
2923 rtx libname ATTRIBUTE_UNUSED)
2924 {
2925 static CUMULATIVE_ARGS zero_cum;
2926 tree param, next_param;
2927
2928 *cum = zero_cum;
2929 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
2930
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. */
2935
2936 for (param = fntype ? TYPE_ARG_TYPES (fntype) : 0;
2937 param != 0; param = next_param)
2938 {
2939 next_param = TREE_CHAIN (param);
2940 if (next_param == 0 && TREE_VALUE (param) != void_type_node)
2941 cum->gp_reg_found = 1;
2942 }
2943 }
2944
2945
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. */
2950
2951 static void
2952 mips_arg_info (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
2953 tree type, int named, struct mips_arg_info *info)
2954 {
2955 bool even_reg_p;
2956 unsigned int num_bytes, num_words, max_regs;
2957
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;
2961
2962 /* Decide whether it should go in a floating-point register, assuming
2963 one is free. Later code checks for availability.
2964
2965 The checks against UNITS_PER_FPVALUE handle the soft-float and
2966 single-float cases. */
2967 switch (mips_abi)
2968 {
2969 case ABI_EABI:
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);
2975 break;
2976
2977 case ABI_32:
2978 case ABI_O64:
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);
2989 break;
2990
2991 case ABI_N32:
2992 case ABI_64:
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);
3001
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
3006 at the end.
3007
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.
3013
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. */
3017 if (info->fpr_p
3018 && GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
3019 && GET_MODE_UNIT_SIZE (mode) < UNITS_PER_FPVALUE)
3020 {
3021 if (cum->num_gprs >= MAX_ARGS_IN_REGISTERS - 1)
3022 info->fpr_p = false;
3023 else
3024 num_words = 2;
3025 }
3026 break;
3027
3028 default:
3029 abort ();
3030 }
3031
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
3034 exceptions:
3035
3036 - Under the O64 ABI, the second float argument goes in $f14 if it
3037 is single precision (doubles go in $f13 as expected).
3038
3039 - Floats passed in FPRs must be in an even-numbered register if
3040 we're using paired FPRs. */
3041 if (type)
3042 even_reg_p = TYPE_ALIGN (type) > BITS_PER_WORD;
3043 else
3044 even_reg_p = GET_MODE_UNIT_SIZE (mode) > UNITS_PER_WORD;
3045
3046 if (info->fpr_p)
3047 {
3048 if (mips_abi == ABI_O64 && mode == SFmode)
3049 even_reg_p = true;
3050 if (FP_INC > 1)
3051 even_reg_p = true;
3052 }
3053
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
3058 ? cum->num_fprs
3059 : cum->num_gprs);
3060
3061 if (even_reg_p)
3062 info->reg_offset += info->reg_offset & 1;
3063
3064 /* The alignment applied to registers is also applied to stack arguments. */
3065 info->stack_offset = cum->stack_words;
3066 if (even_reg_p)
3067 info->stack_offset += info->stack_offset & 1;
3068
3069 max_regs = MAX_ARGS_IN_REGISTERS - info->reg_offset;
3070
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;
3074 }
3075
3076
3077 /* Implement FUNCTION_ARG_ADVANCE. */
3078
3079 void
3080 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
3081 tree type, int named)
3082 {
3083 struct mips_arg_info info;
3084
3085 mips_arg_info (cum, mode, type, named, &info);
3086
3087 if (!info.fpr_p)
3088 cum->gp_reg_found = true;
3089
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);
3095
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;
3100
3101 if (info.stack_words > 0)
3102 cum->stack_words = info.stack_offset + info.stack_words;
3103
3104 cum->arg_number++;
3105 }
3106
3107 /* Implement FUNCTION_ARG. */
3108
3109 struct rtx_def *
3110 function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
3111 tree type, int named)
3112 {
3113 struct mips_arg_info info;
3114
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)
3120 {
3121 if (TARGET_MIPS16 && cum->fp_code != 0)
3122 return gen_rtx_REG ((enum machine_mode) cum->fp_code, 0);
3123
3124 else
3125 return 0;
3126 }
3127
3128 mips_arg_info (cum, mode, type, named, &info);
3129
3130 /* Return straight away if the whole argument is passed on the stack. */
3131 if (info.reg_offset == MAX_ARGS_IN_REGISTERS)
3132 return 0;
3133
3134 if (type != 0
3135 && TREE_CODE (type) == RECORD_TYPE
3136 && TARGET_NEWABI
3137 && TYPE_SIZE_UNIT (type)
3138 && host_integerp (TYPE_SIZE_UNIT (type), 1)
3139 && named)
3140 {
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. */
3144 tree field;
3145
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)
3153 break;
3154
3155 if (field != 0)
3156 {
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. */
3160 unsigned int i;
3161 HOST_WIDE_INT bitpos;
3162 rtx ret;
3163
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));
3167
3168 bitpos = 0;
3169 field = TYPE_FIELDS (type);
3170 for (i = 0; i < info.reg_words; i++)
3171 {
3172 rtx reg;
3173
3174 for (; field; field = TREE_CHAIN (field))
3175 if (TREE_CODE (field) == FIELD_DECL
3176 && int_bit_position (field) >= bitpos)
3177 break;
3178
3179 if (field
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);
3185 else
3186 reg = gen_rtx_REG (DImode, GP_ARG_FIRST + info.reg_offset + i);
3187
3188 XVECEXP (ret, 0, i)
3189 = gen_rtx_EXPR_LIST (VOIDmode, reg,
3190 GEN_INT (bitpos / BITS_PER_UNIT));
3191
3192 bitpos += BITS_PER_WORD;
3193 }
3194 return ret;
3195 }
3196 }
3197
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. */
3201 if (TARGET_NEWABI
3202 && info.fpr_p
3203 && GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
3204 {
3205 rtx real, imag;
3206 enum machine_mode inner;
3207 int reg;
3208
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),
3213 const0_rtx);
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));
3218 }
3219
3220 if (info.fpr_p)
3221 return gen_rtx_REG (mode, FP_ARG_FIRST + info.reg_offset);
3222 else
3223 return gen_rtx_REG (mode, GP_ARG_FIRST + info.reg_offset);
3224 }
3225
3226
3227 /* Implement FUNCTION_ARG_PARTIAL_NREGS. */
3228
3229 int
3230 function_arg_partial_nregs (const CUMULATIVE_ARGS *cum,
3231 enum machine_mode mode, tree type, int named)
3232 {
3233 struct mips_arg_info info;
3234
3235 mips_arg_info (cum, mode, type, named, &info);
3236 return info.stack_words > 0 ? info.reg_words : 0;
3237 }
3238
3239
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
3243 byte does. */
3244
3245 bool
3246 mips_pad_arg_upward (enum machine_mode mode, tree type)
3247 {
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)
3251 return true;
3252
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. */
3255 if (type != 0
3256 ? INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)
3257 : GET_MODE_CLASS (mode) == MODE_INT)
3258 return false;
3259
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)
3263 return false;
3264
3265 /* Other types are padded upward for o32, o64, n32 and n64. */
3266 if (mips_abi != ABI_EABI)
3267 return true;
3268
3269 /* Arguments smaller than a stack slot are padded downward. */
3270 if (mode != BLKmode)
3271 return (GET_MODE_BITSIZE (mode) >= PARM_BOUNDARY);
3272 else
3273 return (int_size_in_bytes (type) >= (PARM_BOUNDARY / BITS_PER_UNIT));
3274 }
3275
3276
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. */
3280
3281 bool
3282 mips_pad_reg_upward (enum machine_mode mode, tree type)
3283 {
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;
3287
3288 /* Otherwise, apply the same padding to register arguments as we do
3289 to stack arguments. */
3290 return mips_pad_arg_upward (mode, type);
3291 }
3292 \f
3293 static void
3294 mips_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
3295 tree type, int *pretend_size, int no_rtl)
3296 {
3297 CUMULATIVE_ARGS local_cum;
3298 int gp_saved, fp_saved;
3299
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. */
3303
3304 local_cum = *cum;
3305 FUNCTION_ARG_ADVANCE (local_cum, mode, type, 1);
3306
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
3311 : 0);
3312
3313 if (!no_rtl)
3314 {
3315 if (gp_saved > 0)
3316 {
3317 rtx ptr, mem;
3318
3319 ptr = virtual_incoming_args_rtx;
3320 switch (mips_abi)
3321 {
3322 case ABI_32:
3323 case ABI_O64:
3324 ptr = plus_constant (ptr, local_cum.num_gprs * UNITS_PER_WORD);
3325 break;
3326
3327 case ABI_EABI:
3328 ptr = plus_constant (ptr, -gp_saved * UNITS_PER_WORD);
3329 break;
3330 }
3331 mem = gen_rtx_MEM (BLKmode, ptr);
3332 set_mem_alias_set (mem, get_varargs_alias_set ());
3333
3334 move_block_from_reg (local_cum.num_gprs + GP_ARG_FIRST,
3335 mem, gp_saved);
3336 }
3337 if (fp_saved > 0)
3338 {
3339 /* We can't use move_block_from_reg, because it will use
3340 the wrong mode. */
3341 enum machine_mode mode;
3342 int off, i;
3343
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;
3350
3351 mode = TARGET_SINGLE_FLOAT ? SFmode : DFmode;
3352
3353 for (i = local_cum.num_fprs; i < MAX_ARGS_IN_REGISTERS; i += FP_INC)
3354 {
3355 rtx ptr, mem;
3356
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;
3362 }
3363 }
3364 }
3365 if (TARGET_OLDABI)
3366 {
3367 /* No need for pretend arguments: the register parameter area was
3368 allocated by the caller. */
3369 *pretend_size = 0;
3370 return;
3371 }
3372 *pretend_size = (gp_saved * UNITS_PER_WORD) + (fp_saved * UNITS_PER_FPREG);
3373 }
3374
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
3386 overflow region.
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
3389 advanced, period.
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. */
3394
3395 static tree
3396 mips_build_builtin_va_list (void)
3397 {
3398 if (EABI_FLOAT_VARARGS_P)
3399 {
3400 tree f_ovfl, f_gtop, f_ftop, f_goff, f_foff, f_res, record;
3401 tree array, index;
3402
3403 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
3404
3405 f_ovfl = build_decl (FIELD_DECL, get_identifier ("__overflow_argptr"),
3406 ptr_type_node);
3407 f_gtop = build_decl (FIELD_DECL, get_identifier ("__gpr_top"),
3408 ptr_type_node);
3409 f_ftop = build_decl (FIELD_DECL, get_identifier ("__fpr_top"),
3410 ptr_type_node);
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);
3421
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;
3428
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;
3435
3436 layout_type (record);
3437 return record;
3438 }
3439 else if (TARGET_IRIX && TARGET_IRIX6)
3440 /* On IRIX 6, this type is 'char *'. */
3441 return build_pointer_type (char_type_node);
3442 else
3443 /* Otherwise, we use 'void *'. */
3444 return ptr_type_node;
3445 }
3446
3447 /* Implement va_start. */
3448
3449 void
3450 mips_va_start (tree valist, rtx nextarg)
3451 {
3452 const CUMULATIVE_ARGS *cum = &current_function_args_info;
3453
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;
3462
3463 if (mips_abi == ABI_EABI)
3464 {
3465 int gpr_save_area_size;
3466
3467 gpr_save_area_size
3468 = (MAX_ARGS_IN_REGISTERS - cum->num_gprs) * UNITS_PER_WORD;
3469
3470 if (EABI_FLOAT_VARARGS_P)
3471 {
3472 tree f_ovfl, f_gtop, f_ftop, f_goff, f_foff;
3473 tree ovfl, gtop, ftop, goff, foff;
3474 tree t;
3475 int fpr_offset;
3476 int fpr_save_area_size;
3477
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);
3483
3484 ovfl = build (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl,
3485 NULL_TREE);
3486 gtop = build (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop,
3487 NULL_TREE);
3488 ftop = build (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop,
3489 NULL_TREE);
3490 goff = build (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff,
3491 NULL_TREE);
3492 foff = build (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff,
3493 NULL_TREE);
3494
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);
3505
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);
3510
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);
3517 if (fpr_offset)
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);
3522
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);
3528
3529 /* Likewise emit code to initialize FOFF, the offset from FTOP
3530 of the next FPR argument. */
3531 fpr_save_area_size
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);
3536 }
3537 else
3538 {
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);
3543 }
3544 }
3545 else
3546 std_expand_builtin_va_start (valist, nextarg);
3547 }
3548 \f
3549 /* Implement va_arg. */
3550
3551 static tree
3552 mips_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
3553 {
3554 HOST_WIDE_INT size, rsize;
3555 tree addr;
3556 bool indirect;
3557
3558 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, 0);
3559
3560 if (indirect)
3561 type = build_pointer_type (type);
3562
3563 size = int_size_in_bytes (type);
3564 rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD;
3565
3566 if (mips_abi != ABI_EABI || !EABI_FLOAT_VARARGS_P)
3567 addr = std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
3568 else
3569 {
3570 /* Not a simple merged stack. */
3571
3572 tree f_ovfl, f_gtop, f_ftop, f_goff, f_foff;
3573 tree ovfl, top, off, align;
3574 HOST_WIDE_INT osize;
3575 tree t, u;
3576
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);
3582
3583 /* We maintain separate pointers and offsets for floating-point
3584 and integer arguments, but we need similar code in both cases.
3585 Let:
3586
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)
3595
3596 The code we want is:
3597
3598 1: off &= -rsize; // round down
3599 2: if (off != 0)
3600 3: {
3601 4: addr_rtx = top - off;
3602 5: off -= rsize;
3603 6: }
3604 7: else
3605 8: {
3606 9: ovfl += ((intptr_t) ovfl + osize - 1) & -osize;
3607 10: addr_rtx = ovfl + PADDING;
3608 11: ovfl += osize;
3609 14: }
3610
3611 [1] and [9] can sometimes be optimized away. */
3612
3613 ovfl = build (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl,
3614 NULL_TREE);
3615
3616 if (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT
3617 && GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_FPVALUE)
3618 {
3619 top = build (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop,
3620 NULL_TREE);
3621 off = build (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff,
3622 NULL_TREE);
3623
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;
3628
3629 /* Overflow arguments are padded to UNITS_PER_WORD bytes
3630 (= PARM_BOUNDARY bits). This can be different from RSIZE
3631 in two cases:
3632
3633 (1) On 32-bit targets when TYPE is a structure such as:
3634
3635 struct s { float f; };
3636
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.
3640
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);
3647 }
3648 else
3649 {
3650 top = build (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop,
3651 NULL_TREE);
3652 off = build (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff,
3653 NULL_TREE);
3654 if (rsize > UNITS_PER_WORD)
3655 {
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);
3661 }
3662 osize = rsize;
3663 }
3664
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);
3668
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);
3676
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)
3681 {
3682 u = fold_convert (TREE_TYPE (t), build_int_cst (NULL_TREE,
3683 rsize - size));
3684 t = build (PLUS_EXPR, TREE_TYPE (t), t, u);
3685 }
3686 COND_EXPR_THEN (addr) = t;
3687
3688 if (osize > UNITS_PER_WORD)
3689 {
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);
3698 }
3699 else
3700 align = NULL;
3701
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)
3709 {
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);
3713 }
3714
3715 /* String [9] and [10,11] together. */
3716 if (align)
3717 t = build (COMPOUND_EXPR, TREE_TYPE (t), align, t);
3718 COND_EXPR_ELSE (addr) = t;
3719
3720 addr = fold_convert (build_pointer_type (type), addr);
3721 addr = build_fold_indirect_ref (addr);
3722 }
3723
3724 if (indirect)
3725 addr = build_fold_indirect_ref (addr);
3726
3727 return addr;
3728 }
3729 \f
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:
3733
3734 *OP is a BLKmode reference to the whole field.
3735
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).
3739
3740 *RIGHT is a QImode reference to the opposite end of the field and
3741 can be used in the parterning right-side instruction. */
3742
3743 static bool
3744 mips_get_unaligned_mem (rtx *op, unsigned int width, int bitpos,
3745 rtx *left, rtx *right)
3746 {
3747 rtx first, last;
3748
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)
3752 return false;
3753
3754 /* Check that the size is valid. */
3755 if (width != 32 && (!TARGET_64BIT || width != 64))
3756 return false;
3757
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)
3762 return false;
3763
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)
3767 return false;
3768
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));
3773
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);
3779
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;
3784 else
3785 *left = last, *right = first;
3786
3787 return true;
3788 }
3789
3790
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. */
3794
3795 bool
3796 mips_expand_unaligned_load (rtx dest, rtx src, unsigned int width, int bitpos)
3797 {
3798 rtx left, right, temp;
3799
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);
3808
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)
3812 return false;
3813
3814 if (!mips_get_unaligned_mem (&src, width, bitpos, &left, &right))
3815 return false;
3816
3817 temp = gen_reg_rtx (GET_MODE (dest));
3818 if (GET_MODE (dest) == DImode)
3819 {
3820 emit_insn (gen_mov_ldl (temp, src, left));
3821 emit_insn (gen_mov_ldr (dest, copy_rtx (src), right, temp));
3822 }
3823 else
3824 {
3825 emit_insn (gen_mov_lwl (temp, src, left));
3826 emit_insn (gen_mov_lwr (dest, copy_rtx (src), right, temp));
3827 }
3828 return true;
3829 }
3830
3831
3832 /* Try to expand (set (zero_extract DEST WIDTH BITPOS) SRC). Return
3833 true on success. */
3834
3835 bool
3836 mips_expand_unaligned_store (rtx dest, rtx src, unsigned int width, int bitpos)
3837 {
3838 rtx left, right;
3839
3840 if (!mips_get_unaligned_mem (&dest, width, bitpos, &left, &right))
3841 return false;
3842
3843 src = gen_lowpart (mode_for_size (width, MODE_INT, 0), src);
3844
3845 if (GET_MODE (src) == DImode)
3846 {
3847 emit_insn (gen_mov_sdl (dest, src, left));
3848 emit_insn (gen_mov_sdr (copy_rtx (dest), copy_rtx (src), right));
3849 }
3850 else
3851 {
3852 emit_insn (gen_mov_swl (dest, src, left));
3853 emit_insn (gen_mov_swr (copy_rtx (dest), copy_rtx (src), right));
3854 }
3855 return true;
3856 }
3857 \f
3858 /* Set up globals to generate code for the ISA or processor
3859 described by INFO. */
3860
3861 static void
3862 mips_set_architecture (const struct mips_cpu_info *info)
3863 {
3864 if (info != 0)
3865 {
3866 mips_arch_info = info;
3867 mips_arch = info->cpu;
3868 mips_isa = info->isa;
3869 }
3870 }
3871
3872
3873 /* Likewise for tuning. */
3874
3875 static void
3876 mips_set_tune (const struct mips_cpu_info *info)
3877 {
3878 if (info != 0)
3879 {
3880 mips_tune_info = info;
3881 mips_tune = info->cpu;
3882 }
3883 }
3884
3885
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. */
3888
3889 void
3890 override_options (void)
3891 {
3892 int i, start, regno;
3893 enum machine_mode mode;
3894
3895 mips_section_threshold = g_switch_set ? g_switch_value : MIPS_DEFAULT_GVALUE;
3896
3897 /* Interpret -mabi. */
3898 mips_abi = MIPS_ABI_DEFAULT;
3899 if (mips_abi_string != 0)
3900 {
3901 if (strcmp (mips_abi_string, "32") == 0)
3902 mips_abi = ABI_32;
3903 else if (strcmp (mips_abi_string, "o64") == 0)
3904 mips_abi = ABI_O64;
3905 else if (strcmp (mips_abi_string, "n32") == 0)
3906 mips_abi = ABI_N32;
3907 else if (strcmp (mips_abi_string, "64") == 0)
3908 mips_abi = ABI_64;
3909 else if (strcmp (mips_abi_string, "eabi") == 0)
3910 mips_abi = ABI_EABI;
3911 else
3912 fatal_error ("bad value (%s) for -mabi= switch", mips_abi_string);
3913 }
3914
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. */
3918
3919 if (mips_arch_string != 0)
3920 mips_set_architecture (mips_parse_cpu ("-march", mips_arch_string));
3921
3922 if (mips_isa_string != 0)
3923 {
3924 /* Handle -mipsN. */
3925 char *whole_isa_str = concat ("mips", mips_isa_string, NULL);
3926 const struct mips_cpu_info *isa_info;
3927
3928 isa_info = mips_parse_cpu ("-mips option", whole_isa_str);
3929 free (whole_isa_str);
3930
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
3933 are the same. */
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);
3938
3939 /* Set architecture based on the given option. */
3940 mips_set_architecture (isa_info);
3941 }
3942
3943 if (mips_arch_info == 0)
3944 {
3945 #ifdef MIPS_CPU_STRING_DEFAULT
3946 mips_set_architecture (mips_parse_cpu ("default CPU",
3947 MIPS_CPU_STRING_DEFAULT));
3948 #else
3949 mips_set_architecture (mips_cpu_info_from_isa (MIPS_ISA_DEFAULT));
3950 #endif
3951 }
3952
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);
3956
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));
3960
3961 if (mips_tune_info == 0)
3962 mips_set_tune (mips_arch_info);
3963
3964 if ((target_flags_explicit & MASK_64BIT) != 0)
3965 {
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");
3974 }
3975 else
3976 {
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;
3982 else
3983 target_flags |= MASK_64BIT;
3984 }
3985
3986 if ((target_flags_explicit & MASK_FLOAT64) != 0)
3987 {
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");
3996 }
3997 else
3998 {
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;
4003 else
4004 target_flags &= ~MASK_FLOAT64;
4005 }
4006
4007 /* End of code shared with GAS. */
4008
4009 if ((target_flags_explicit & MASK_LONG64) == 0)
4010 {
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
4014 ABI. */
4015 if ((mips_abi == ABI_EABI && TARGET_64BIT) || mips_abi == ABI_64)
4016 target_flags |= MASK_LONG64;
4017 else
4018 target_flags &= ~MASK_LONG64;
4019 }
4020
4021 if (MIPS_MARCH_CONTROLS_SOFT_FLOAT
4022 && (target_flags_explicit & MASK_SOFT_FLOAT) == 0)
4023 {
4024 /* For some configurations, it is useful to have -march control
4025 the default setting of MASK_SOFT_FLOAT. */
4026 switch ((int) mips_arch)
4027 {
4028 case PROCESSOR_R4100:
4029 case PROCESSOR_R4111:
4030 case PROCESSOR_R4120:
4031 case PROCESSOR_R4130:
4032 target_flags |= MASK_SOFT_FLOAT;
4033 break;
4034
4035 default:
4036 target_flags &= ~MASK_SOFT_FLOAT;
4037 break;
4038 }
4039 }
4040
4041 if (!TARGET_OLDABI)
4042 flag_pcc_struct_return = 0;
4043
4044 if ((target_flags_explicit & MASK_BRANCHLIKELY) == 0)
4045 {
4046 /* If neither -mbranch-likely nor -mno-branch-likely was given
4047 on the command line, set MASK_BRANCHLIKELY based on the target
4048 architecture.
4049
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
4054 performance.
4055
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
4061 -mbranch-likely. */
4062 if (ISA_HAS_BRANCHLIKELY
4063 && !(ISA_MIPS32 || ISA_MIPS32R2 || ISA_MIPS64)
4064 && !(TUNE_MIPS5500 || TUNE_SB1))
4065 target_flags |= MASK_BRANCHLIKELY;
4066 else
4067 target_flags &= ~MASK_BRANCHLIKELY;
4068 }
4069 if (TARGET_BRANCHLIKELY && !ISA_HAS_BRANCHLIKELY)
4070 warning ("generation of Branch Likely instructions enabled, but not supported by architecture");
4071
4072 /* The effect of -mabicalls isn't defined for the EABI. */
4073 if (mips_abi == ABI_EABI && TARGET_ABICALLS)
4074 {
4075 error ("unsupported combination: %s", "-mabicalls -mabi=eabi");
4076 target_flags &= ~MASK_ABICALLS;
4077 }
4078
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
4082 implemented. */
4083 if (TARGET_ABICALLS)
4084 {
4085 flag_pic = 1;
4086 if (mips_section_threshold > 0)
4087 warning ("-G is incompatible with PIC code which is the default");
4088 }
4089
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.
4094
4095 Like explicit relocation support for REL targets, it relies
4096 on GNU extensions in the assembler and the linker.
4097
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;
4104 else
4105 mips_split_addresses = 0;
4106
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
4109 above. */
4110 if (optimize > 2 && (target_flags_explicit & MASK_VR4130_ALIGN) == 0)
4111 target_flags |= MASK_VR4130_ALIGN;
4112
4113 /* When compiling for the mips16, we cannot use floating point. We
4114 record the original hard float value in mips16_hard_float. */
4115 if (TARGET_MIPS16)
4116 {
4117 if (TARGET_SOFT_FLOAT)
4118 mips16_hard_float = 0;
4119 else
4120 mips16_hard_float = 1;
4121 target_flags |= MASK_SOFT_FLOAT;
4122
4123 /* Don't run the scheduler before reload, since it tends to
4124 increase register pressure. */
4125 flag_schedule_insns = 0;
4126
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;
4132 }
4133
4134 /* When using explicit relocs, we call dbr_schedule from within
4135 mips_reorg. */
4136 if (TARGET_EXPLICIT_RELOCS)
4137 {
4138 mips_flag_delayed_branch = flag_delayed_branch;
4139 flag_delayed_branch = 0;
4140 }
4141
4142 #ifdef MIPS_TFMODE_FORMAT
4143 REAL_MODE_FORMAT (TFmode) = &MIPS_TFMODE_FORMAT;
4144 #endif
4145
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");
4151
4152 /* If TARGET_MIPS3D, enable MASK_PAIRED_SINGLE. */
4153 if (TARGET_MIPS3D)
4154 target_flags |= MASK_PAIRED_SINGLE;
4155
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");
4160
4161 /* Make sure that the ISA supports TARGET_PAIRED_SINGLE_FLOAT when it is
4162 enabled. */
4163 if (TARGET_PAIRED_SINGLE_FLOAT && !ISA_MIPS64)
4164 error ("-mips3d/-mpaired-single must be used with -mips64");
4165
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;
4186
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 :
4196 GR_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;
4204
4205 /* Set up array to map GCC register number to debug register number.
4206 Ignore the special purpose register numbers. */
4207
4208 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
4209 mips_dbx_regno[i] = -1;
4210
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;
4214
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;
4218
4219 mips_dbx_regno[HI_REGNUM] = MD_DBX_FIRST + 0;
4220 mips_dbx_regno[LO_REGNUM] = MD_DBX_FIRST + 1;
4221
4222 /* Set up array giving whether a given register can hold a given mode. */
4223
4224 for (mode = VOIDmode;
4225 mode != MAX_MACHINE_MODE;
4226 mode = (enum machine_mode) ((int)mode + 1))
4227 {
4228 register int size = GET_MODE_SIZE (mode);
4229 register enum mode_class class = GET_MODE_CLASS (mode);
4230
4231 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
4232 {
4233 register int temp;
4234
4235 if (mode == CCV2mode)
4236 temp = (ISA_HAS_8CC
4237 && ST_REG_P (regno)
4238 && (regno - ST_REG_FIRST) % 2 == 0);
4239
4240 else if (mode == CCV4mode)
4241 temp = (ISA_HAS_8CC
4242 && ST_REG_P (regno)
4243 && (regno - ST_REG_FIRST) % 4 == 0);
4244
4245 else if (mode == CCmode)
4246 {
4247 if (! ISA_HAS_8CC)
4248 temp = (regno == FPSW_REGNUM);
4249 else
4250 temp = (ST_REG_P (regno) || GP_REG_P (regno)
4251 || FP_REG_P (regno));
4252 }
4253
4254 else if (GP_REG_P (regno))
4255 temp = ((regno & 1) == 0 || size <= UNITS_PER_WORD);
4256
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));
4268
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)));
4274
4275 else if (ALL_COP_REG_P (regno))
4276 temp = (class == MODE_INT && size <= UNITS_PER_WORD);
4277 else
4278 temp = 0;
4279
4280 mips_hard_regno_mode_ok[(int)mode][regno] = temp;
4281 }
4282 }
4283
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;
4287
4288 /* Provide default values for align_* for 64-bit targets. */
4289 if (TARGET_64BIT && !TARGET_MIPS16)
4290 {
4291 if (align_loops == 0)
4292 align_loops = 8;
4293 if (align_jumps == 0)
4294 align_jumps = 8;
4295 if (align_functions == 0)
4296 align_functions = 8;
4297 }
4298
4299 /* Function to allocate machine-dependent function status. */
4300 init_machine_status = &mips_init_machine_status;
4301
4302 if (ABI_HAS_64BIT_SYMBOLS)
4303 {
4304 if (TARGET_EXPLICIT_RELOCS)
4305 {
4306 mips_split_p[SYMBOL_64_HIGH] = true;
4307 mips_hi_relocs[SYMBOL_64_HIGH] = "%highest(";
4308 mips_lo_relocs[SYMBOL_64_HIGH] = "%higher(";
4309
4310 mips_split_p[SYMBOL_64_MID] = true;
4311 mips_hi_relocs[SYMBOL_64_MID] = "%higher(";
4312 mips_lo_relocs[SYMBOL_64_MID] = "%hi(";
4313
4314 mips_split_p[SYMBOL_64_LOW] = true;
4315 mips_hi_relocs[SYMBOL_64_LOW] = "%hi(";
4316 mips_lo_relocs[SYMBOL_64_LOW] = "%lo(";
4317
4318 mips_split_p[SYMBOL_GENERAL] = true;
4319 mips_lo_relocs[SYMBOL_GENERAL] = "%lo(";
4320 }
4321 }
4322 else
4323 {
4324 if (TARGET_EXPLICIT_RELOCS || mips_split_addresses)
4325 {
4326 mips_split_p[SYMBOL_GENERAL] = true;
4327 mips_hi_relocs[SYMBOL_GENERAL] = "%hi(";
4328 mips_lo_relocs[SYMBOL_GENERAL] = "%lo(";
4329 }
4330 }
4331
4332 if (TARGET_MIPS16)
4333 {
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(";
4337 }
4338
4339 if (TARGET_EXPLICIT_RELOCS)
4340 {
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(";
4344
4345 mips_split_p[SYMBOL_GOT_LOCAL] = true;
4346 if (TARGET_NEWABI)
4347 {
4348 mips_lo_relocs[SYMBOL_GOTOFF_PAGE] = "%got_page(";
4349 mips_lo_relocs[SYMBOL_GOT_LOCAL] = "%got_ofst(";
4350 }
4351 else
4352 {
4353 mips_lo_relocs[SYMBOL_GOTOFF_PAGE] = "%got(";
4354 mips_lo_relocs[SYMBOL_GOT_LOCAL] = "%lo(";
4355 }
4356
4357 if (TARGET_XGOT)
4358 {
4359 /* The HIGH and LO_SUM are matched by special .md patterns. */
4360 mips_split_p[SYMBOL_GOT_GLOBAL] = true;
4361
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(";
4365
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(";
4369 }
4370 else
4371 {
4372 if (TARGET_NEWABI)
4373 mips_lo_relocs[SYMBOL_GOTOFF_GLOBAL] = "%got_disp(";
4374 else
4375 mips_lo_relocs[SYMBOL_GOTOFF_GLOBAL] = "%got(";
4376 mips_lo_relocs[SYMBOL_GOTOFF_CALL] = "%call16(";
4377 }
4378 }
4379
4380 if (TARGET_NEWABI)
4381 {
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(";
4385 }
4386
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;
4392
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;
4398 }
4399
4400 /* Implement CONDITIONAL_REGISTER_USAGE. */
4401
4402 void
4403 mips_conditional_register_usage (void)
4404 {
4405 if (!TARGET_HARD_FLOAT)
4406 {
4407 int regno;
4408
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;
4413 }
4414 else if (! ISA_HAS_8CC)
4415 {
4416 int regno;
4417
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;
4423 }
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. */
4428 if (TARGET_MIPS16)
4429 {
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;
4439 }
4440 /* fp20-23 are now caller saved. */
4441 if (mips_abi == ABI_64)
4442 {
4443 int regno;
4444 for (regno = FP_REG_FIRST + 20; regno < FP_REG_FIRST + 24; regno++)
4445 call_really_used_regs[regno] = call_used_regs[regno] = 1;
4446 }
4447 /* Odd registers from fp21 to fp31 are now caller saved. */
4448 if (mips_abi == ABI_N32)
4449 {
4450 int regno;
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;
4453 }
4454 }
4455
4456 /* Allocate a chunk of memory for per-function machine-dependent data. */
4457 static struct machine_function *
4458 mips_init_machine_status (void)
4459 {
4460 return ((struct machine_function *)
4461 ggc_alloc_cleared (sizeof (struct machine_function)));
4462 }
4463
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. */
4468
4469 void
4470 mips_order_regs_for_local_alloc (void)
4471 {
4472 register int i;
4473
4474 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
4475 reg_alloc_order[i] = i;
4476
4477 if (TARGET_MIPS16)
4478 {
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;
4483 }
4484 }
4485
4486 \f
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. */
4495
4496 HOST_WIDE_INT
4497 mips_debugger_offset (rtx addr, HOST_WIDE_INT offset)
4498 {
4499 rtx offset2 = const0_rtx;
4500 rtx reg = eliminate_constant_term (addr, &offset2);
4501
4502 if (offset == 0)
4503 offset = INTVAL (offset2);
4504
4505 if (reg == stack_pointer_rtx || reg == frame_pointer_rtx
4506 || reg == hard_frame_pointer_rtx)
4507 {
4508 HOST_WIDE_INT frame_size = (!cfun->machine->frame.initialized)
4509 ? compute_frame_size (get_frame_size ())
4510 : cfun->machine->frame.total_size;
4511
4512 /* MIPS16 frame is smaller */
4513 if (frame_pointer_needed && TARGET_MIPS16)
4514 frame_size -= cfun->machine->frame.args_size;
4515
4516 offset = offset - frame_size;
4517 }
4518
4519 /* sdbout_parms does not want this to crash for unrecognized cases. */
4520 #if 0
4521 else if (reg != arg_pointer_rtx)
4522 fatal_insn ("mips_debugger_offset called with non stack/frame/arg pointer",
4523 addr);
4524 #endif
4525
4526 return offset;
4527 }
4528 \f
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. */
4535
4536 static void
4537 print_fcc_operand (FILE *file, rtx op, enum rtx_code code,
4538 int align, int offset, int ignore)
4539 {
4540 int regnum;
4541
4542 if (code != REG)
4543 abort ();
4544
4545 regnum = REGNO (op);
4546 if (!ST_REG_P (regnum)
4547 || (regnum - ST_REG_FIRST) % align != 0)
4548 abort ();
4549
4550 if (!ignore || regnum != ST_REG_FIRST)
4551 fprintf (file, "%s%s", reg_names[regnum+offset], (ignore ? "," : ""));
4552 }
4553
4554 /* Implement the PRINT_OPERAND macro. The MIPS-specific operand codes are:
4555
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
4574 plus 1.
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
4579 the fcc register.
4580 'Q' print the fcc register.
4581
4582 The punctuation characters are:
4583
4584 '(' Turn on .set noreorder
4585 ')' Turn on .set reorder
4586 '[' Turn on .set noat
4587 ']' Turn on .set at
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). */
4604
4605 void
4606 print_operand (FILE *file, rtx op, int letter)
4607 {
4608 register enum rtx_code code;
4609
4610 if (PRINT_OPERAND_PUNCT_VALID_P (letter))
4611 {
4612 switch (letter)
4613 {
4614 case '?':
4615 if (mips_branch_likely)
4616 putc ('l', file);
4617 break;
4618
4619 case '@':
4620 fputs (reg_names [GP_REG_FIRST + 1], file);
4621 break;
4622
4623 case '^':
4624 fputs (reg_names [PIC_FUNCTION_ADDR_REGNUM], file);
4625 break;
4626
4627 case '.':
4628 fputs (reg_names [GP_REG_FIRST + 0], file);
4629 break;
4630
4631 case '$':
4632 fputs (reg_names[STACK_POINTER_REGNUM], file);
4633 break;
4634
4635 case '+':
4636 fputs (reg_names[PIC_OFFSET_TABLE_REGNUM], file);
4637 break;
4638
4639 case '&':
4640 if (final_sequence != 0 && set_noreorder++ == 0)
4641 fputs (".set\tnoreorder\n\t", file);
4642 break;
4643
4644 case '*':
4645 if (final_sequence != 0)
4646 {
4647 if (set_noreorder++ == 0)
4648 fputs (".set\tnoreorder\n\t", file);
4649
4650 if (set_nomacro++ == 0)
4651 fputs (".set\tnomacro\n\t", file);
4652 }
4653 break;
4654
4655 case '!':
4656 if (final_sequence != 0 && set_nomacro++ == 0)
4657 fputs ("\n\t.set\tnomacro", file);
4658 break;
4659
4660 case '#':
4661 if (set_noreorder != 0)
4662 fputs ("\n\tnop", file);
4663 break;
4664
4665 case '/':
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);
4671 break;
4672
4673 case '(':
4674 if (set_noreorder++ == 0)
4675 fputs (".set\tnoreorder\n\t", file);
4676 break;
4677
4678 case ')':
4679 if (set_noreorder == 0)
4680 error ("internal error: %%) found without a %%( in assembler pattern");
4681
4682 else if (--set_noreorder == 0)
4683 fputs ("\n\t.set\treorder", file);
4684
4685 break;
4686
4687 case '[':
4688 if (set_noat++ == 0)
4689 fputs (".set\tnoat\n\t", file);
4690 break;
4691
4692 case ']':
4693 if (set_noat == 0)
4694 error ("internal error: %%] found without a %%[ in assembler pattern");
4695 else if (--set_noat == 0)
4696 fputs ("\n\t.set\tat", file);
4697
4698 break;
4699
4700 case '<':
4701 if (set_nomacro++ == 0)
4702 fputs (".set\tnomacro\n\t", file);
4703 break;
4704
4705 case '>':
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);
4710
4711 break;
4712
4713 case '{':
4714 if (set_volatile++ == 0)
4715 fputs ("#.set\tvolatile\n\t", file);
4716 break;
4717
4718 case '}':
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);
4723
4724 break;
4725
4726 case '~':
4727 {
4728 if (align_labels_log > 0)
4729 ASM_OUTPUT_ALIGN (file, align_labels_log);
4730 }
4731 break;
4732
4733 default:
4734 error ("PRINT_OPERAND: unknown punctuation '%c'", letter);
4735 break;
4736 }
4737
4738 return;
4739 }
4740
4741 if (! op)
4742 {
4743 error ("PRINT_OPERAND null pointer");
4744 return;
4745 }
4746
4747 code = GET_CODE (op);
4748
4749 if (letter == 'C')
4750 switch (code)
4751 {
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;
4762 default:
4763 fatal_insn ("PRINT_OPERAND, invalid insn for %%C", op);
4764 }
4765
4766 else if (letter == 'N')
4767 switch (code)
4768 {
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;
4779 default:
4780 fatal_insn ("PRINT_OPERAND, invalid insn for %%N", op);
4781 }
4782
4783 else if (letter == 'F')
4784 switch (code)
4785 {
4786 case EQ: fputs ("c1f", file); break;
4787 case NE: fputs ("c1t", file); break;
4788 default:
4789 fatal_insn ("PRINT_OPERAND, invalid insn for %%F", op);
4790 }
4791
4792 else if (letter == 'W')
4793 switch (code)
4794 {
4795 case EQ: fputs ("c1t", file); break;
4796 case NE: fputs ("c1f", file); break;
4797 default:
4798 fatal_insn ("PRINT_OPERAND, invalid insn for %%W", op);
4799 }
4800
4801 else if (letter == 'h')
4802 {
4803 if (GET_CODE (op) == HIGH)
4804 op = XEXP (op, 0);
4805
4806 print_operand_reloc (file, op, mips_hi_relocs);
4807 }
4808
4809 else if (letter == 'R')
4810 print_operand_reloc (file, op, mips_lo_relocs);
4811
4812 else if (letter == 'Z')
4813 print_fcc_operand (file, op, code, 1, 0, 1);
4814
4815 else if (letter == 'Y')
4816 print_fcc_operand (file, op, code, 2, 1, 0);
4817
4818 else if (letter == 'y')
4819 print_fcc_operand (file, op, code, 2, 0, 0);
4820
4821 else if (letter == 'V')
4822 print_fcc_operand (file, op, code, 4, 2, 0);
4823
4824 else if (letter == 'v')
4825 print_fcc_operand (file, op, code, 4, 0, 0);
4826
4827 else if (letter == 'Q')
4828 print_fcc_operand (file, op, code, 1, 0, 0);
4829
4830 else if (code == REG || code == SUBREG)
4831 {
4832 register int regnum;
4833
4834 if (code == REG)
4835 regnum = REGNO (op);
4836 else
4837 regnum = true_regnum (op);
4838
4839 if ((letter == 'M' && ! WORDS_BIG_ENDIAN)
4840 || (letter == 'L' && WORDS_BIG_ENDIAN)
4841 || letter == 'D')
4842 regnum++;
4843
4844 fprintf (file, "%s", reg_names[regnum]);
4845 }
4846
4847 else if (code == MEM)
4848 {
4849 if (letter == 'D')
4850 output_address (plus_constant (XEXP (op, 0), 4));
4851 else
4852 output_address (XEXP (op, 0));
4853 }
4854
4855 else if (letter == 'x' && GET_CODE (op) == CONST_INT)
4856 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & INTVAL(op));
4857
4858 else if (letter == 'X' && GET_CODE(op) == CONST_INT)
4859 fprintf (file, HOST_WIDE_INT_PRINT_HEX, INTVAL (op));
4860
4861 else if (letter == 'd' && GET_CODE(op) == CONST_INT)
4862 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (INTVAL(op)));
4863
4864 else if (letter == 'z' && op == CONST0_RTX (GET_MODE (op)))
4865 fputs (reg_names[GP_REG_FIRST], file);
4866
4867 else if (letter == 'd' || letter == 'x' || letter == 'X')
4868 output_operand_lossage ("invalid use of %%d, %%x, or %%X");
4869
4870 else if (letter == 'T' || letter == 't')
4871 {
4872 int truth = (code == NE) == (letter == 'T');
4873 fputc ("zfnt"[truth * 2 + (GET_MODE (op) == CCmode)], file);
4874 }
4875
4876 else if (CONST_GP_P (op))
4877 fputs (reg_names[GLOBAL_POINTER_REGNUM], file);
4878
4879 else
4880 output_addr_const (file, op);
4881 }
4882
4883
4884 /* Print symbolic operand OP, which is part of a HIGH or LO_SUM.
4885 RELOCS is the array of relocations to use. */
4886
4887 static void
4888 print_operand_reloc (FILE *file, rtx op, const char **relocs)
4889 {
4890 enum mips_symbol_type symbol_type;
4891 const char *p;
4892 rtx base;
4893 HOST_WIDE_INT offset;
4894
4895 if (!mips_symbolic_constant_p (op, &symbol_type) || relocs[symbol_type] == 0)
4896 fatal_insn ("PRINT_OPERAND, invalid operand for relocation", op);
4897
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);
4902
4903 fputs (relocs[symbol_type], file);
4904 output_addr_const (file, op);
4905 for (p = relocs[symbol_type]; *p != 0; p++)
4906 if (*p == '(')
4907 fputc (')', file);
4908 }
4909 \f
4910 /* Output address operand X to FILE. */
4911
4912 void
4913 print_operand_address (FILE *file, rtx x)
4914 {
4915 struct mips_address_info addr;
4916
4917 if (mips_classify_address (&addr, x, word_mode, true))
4918 switch (addr.type)
4919 {
4920 case ADDRESS_REG:
4921 print_operand (file, addr.offset, 0);
4922 fprintf (file, "(%s)", reg_names[REGNO (addr.reg)]);
4923 return;
4924
4925 case ADDRESS_LO_SUM:
4926 print_operand (file, addr.offset, 'R');
4927 fprintf (file, "(%s)", reg_names[REGNO (addr.reg)]);
4928 return;
4929
4930 case ADDRESS_CONST_INT:
4931 output_addr_const (file, x);
4932 fprintf (file, "(%s)", reg_names[0]);
4933 return;
4934
4935 case ADDRESS_SYMBOLIC:
4936 output_addr_const (file, x);
4937 return;
4938 }
4939 abort ();
4940 }
4941 \f
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.
4944
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. */
4949
4950 int
4951 mips_output_external (FILE *file ATTRIBUTE_UNUSED, tree decl, const char *name)
4952 {
4953 register struct extern_list *p;
4954
4955 if (!TARGET_EXPLICIT_RELOCS && mips_in_small_data_p (decl))
4956 {
4957 p = (struct extern_list *) ggc_alloc (sizeof (struct extern_list));
4958 p->next = extern_head;
4959 p->name = name;
4960 p->size = int_size_in_bytes (TREE_TYPE (decl));
4961 extern_head = p;
4962 }
4963
4964 if (TARGET_IRIX && mips_abi == ABI_32 && TREE_CODE (decl) == FUNCTION_DECL)
4965 {
4966 p = (struct extern_list *) ggc_alloc (sizeof (struct extern_list));
4967 p->next = extern_head;
4968 p->name = name;
4969 p->size = -1;
4970 extern_head = p;
4971 }
4972
4973 return 0;
4974 }
4975
4976 #if TARGET_IRIX
4977 static void
4978 irix_output_external_libcall (rtx fun)
4979 {
4980 register struct extern_list *p;
4981
4982 if (mips_abi == ABI_32)
4983 {
4984 p = (struct extern_list *) ggc_alloc (sizeof (struct extern_list));
4985 p->next = extern_head;
4986 p->name = XSTR (fun, 0);
4987 p->size = -1;
4988 extern_head = p;
4989 }
4990 }
4991 #endif
4992 \f
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. */
4995
4996 void
4997 mips_output_filename (FILE *stream, const char *name)
4998 {
4999 char ltext_label_name[100];
5000
5001 /* If we are emitting DWARF-2, let dwarf2out handle the ".file"
5002 directives. */
5003 if (write_symbols == DWARF2_DEBUG)
5004 return;
5005 else if (mips_output_filename_first_time)
5006 {
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);
5011 }
5012
5013 else if (write_symbols == DBX_DEBUG)
5014 {
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, &ltext_label_name[1]);
5019 }
5020
5021 else if (name != current_function_file
5022 && strcmp (name, current_function_file) != 0)
5023 {
5024 num_source_filenames += 1;
5025 current_function_file = name;
5026 ASM_OUTPUT_FILENAME (stream, num_source_filenames, name);
5027 }
5028 }
5029 \f
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
5033 file. */
5034
5035 void
5036 mips_output_lineno (FILE *stream, int line)
5037 {
5038 if (write_symbols == DBX_DEBUG)
5039 {
5040 ++sym_lineno;
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);
5044 }
5045 else
5046 {
5047 fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line);
5048 }
5049 }
5050 \f
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. */
5054
5055 void
5056 mips_output_ascii (FILE *stream, const char *string_param, size_t len,
5057 const char *prefix)
5058 {
5059 size_t i;
5060 int cur_pos = 17;
5061 register const unsigned char *string =
5062 (const unsigned char *)string_param;
5063
5064 fprintf (stream, "%s\"", prefix);
5065 for (i = 0; i < len; i++)
5066 {
5067 register int c = string[i];
5068
5069 switch (c)
5070 {
5071 case '\"':
5072 case '\\':
5073 putc ('\\', stream);
5074 putc (c, stream);
5075 cur_pos += 2;
5076 break;
5077
5078 case TARGET_NEWLINE:
5079 fputs ("\\n", stream);
5080 if (i+1 < len
5081 && (((c = string[i+1]) >= '\040' && c <= '~')
5082 || c == TARGET_TAB))
5083 cur_pos = 32767; /* break right here */
5084 else
5085 cur_pos += 2;
5086 break;
5087
5088 case TARGET_TAB:
5089 fputs ("\\t", stream);
5090 cur_pos += 2;
5091 break;
5092
5093 case TARGET_FF:
5094 fputs ("\\f", stream);
5095 cur_pos += 2;
5096 break;
5097
5098 case TARGET_BS:
5099 fputs ("\\b", stream);
5100 cur_pos += 2;
5101 break;
5102
5103 case TARGET_CR:
5104 fputs ("\\r", stream);
5105 cur_pos += 2;
5106 break;
5107
5108 default:
5109 if (c >= ' ' && c < 0177)
5110 {
5111 putc (c, stream);
5112 cur_pos++;
5113 }
5114 else
5115 {
5116 fprintf (stream, "\\%03o", c);
5117 cur_pos += 4;
5118 }
5119 }
5120
5121 if (cur_pos > 72 && i+1 < len)
5122 {
5123 cur_pos = 17;
5124 fprintf (stream, "\"\n%s\"", prefix);
5125 }
5126 }
5127 fprintf (stream, "\"\n");
5128 }
5129 \f
5130 /* Implement TARGET_ASM_FILE_START. */
5131
5132 static void
5133 mips_file_start (void)
5134 {
5135 default_file_start ();
5136
5137 if (!TARGET_IRIX)
5138 {
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;
5147
5148 switch (mips_abi)
5149 {
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;
5155 default:
5156 abort ();
5157 }
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
5161 executable. */
5162 fprintf (asm_out_file, "\t.section .mdebug.%s\n", abi_string);
5163
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
5166 such as GDB. */
5167 if (mips_abi == ABI_EABI)
5168 fprintf (asm_out_file, "\t.section .gcc_compiled_long%d\n",
5169 TARGET_LONG64 ? 64 : 32);
5170
5171 /* Restore the default section. */
5172 fprintf (asm_out_file, "\t.previous\n");
5173 }
5174
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");
5179
5180 if (TARGET_MIPS16)
5181 fprintf (asm_out_file, "\t.set\tmips16\n");
5182
5183 if (flag_verbose_asm)
5184 fprintf (asm_out_file, "\n%s -G value = %d, Arch = %s, ISA = %d\n",
5185 ASM_COMMENT_START,
5186 mips_section_threshold, mips_arch_info->name, mips_isa);
5187 }
5188
5189 #ifdef BSS_SECTION_ASM_OP
5190 /* Implement ASM_OUTPUT_ALIGNED_BSS. This differs from the default only
5191 in the use of sbss. */
5192
5193 void
5194 mips_output_aligned_bss (FILE *stream, tree decl, const char *name,
5195 unsigned HOST_WIDE_INT size, int align)
5196 {
5197 extern tree last_assemble_variable_decl;
5198
5199 if (mips_in_small_data_p (decl))
5200 named_section (0, ".sbss", 0);
5201 else
5202 bss_section ();
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);
5207 }
5208 #endif
5209 \f
5210 /* Implement TARGET_ASM_FILE_END. When using assembler macros, emit
5211 .externs for any small-data variables that turned out to be external. */
5212
5213 static void
5214 mips_file_end (void)
5215 {
5216 tree name_tree;
5217 struct extern_list *p;
5218
5219 if (extern_head)
5220 {
5221 fputs ("\n", asm_out_file);
5222
5223 for (p = extern_head; p != 0; p = p->next)
5224 {
5225 name_tree = get_identifier (p->name);
5226
5227 /* Positively ensure only one .extern for any given symbol. */
5228 if (!TREE_ASM_WRITTEN (name_tree)
5229 && TREE_SYMBOL_REFERENCED (name_tree))
5230 {
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)
5238 {
5239 fputs ("\t.globl ", asm_out_file);
5240 assemble_name (asm_out_file, p->name);
5241 fputs (" .text\n", asm_out_file);
5242 }
5243 else
5244 {
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);
5248 }
5249 }
5250 }
5251 }
5252 }
5253
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. */
5256
5257 void
5258 mips_output_aligned_decl_common (FILE *stream, tree decl, const char *name,
5259 unsigned HOST_WIDE_INT size,
5260 unsigned int align)
5261 {
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))
5267 {
5268 if (TREE_PUBLIC (decl) && DECL_NAME (decl))
5269 targetm.asm_out.globalize_label (stream, name);
5270
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",
5275 size);
5276 }
5277 else
5278 mips_declare_common_object (stream, name, "\n\t.comm\t",
5279 size, align, true);
5280 }
5281
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. */
5286
5287 void
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)
5292 {
5293 if (!takes_alignment_p)
5294 {
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);
5299 }
5300 else
5301 mips_declare_object (stream, name, init_string,
5302 "," HOST_WIDE_INT_PRINT_UNSIGNED ",%u\n",
5303 size, align / BITS_PER_UNIT);
5304 }
5305
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. */
5312
5313 void
5314 mips_declare_object (FILE *stream, const char *name, const char *init_string,
5315 const char *final_string, ...)
5316 {
5317 va_list ap;
5318
5319 fputs (init_string, stream);
5320 assemble_name (stream, name);
5321 va_start (ap, final_string);
5322 vfprintf (stream, final_string, ap);
5323 va_end (ap);
5324
5325 if (!TARGET_EXPLICIT_RELOCS)
5326 {
5327 tree name_tree = get_identifier (name);
5328 TREE_ASM_WRITTEN (name_tree) = 1;
5329 }
5330 }
5331
5332 #ifdef ASM_OUTPUT_SIZE_DIRECTIVE
5333 extern int size_directive_output;
5334
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. */
5337
5338 void
5339 mips_declare_object_name (FILE *stream, const char *name,
5340 tree decl ATTRIBUTE_UNUSED)
5341 {
5342 #ifdef ASM_OUTPUT_TYPE_DIRECTIVE
5343 ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "object");
5344 #endif
5345
5346 size_directive_output = 0;
5347 if (!flag_inhibit_size_directive && DECL_SIZE (decl))
5348 {
5349 HOST_WIDE_INT size;
5350
5351 size_directive_output = 1;
5352 size = int_size_in_bytes (TREE_TYPE (decl));
5353 ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
5354 }
5355
5356 mips_declare_object (stream, name, "", ":\n", 0);
5357 }
5358
5359 /* Implement ASM_FINISH_DECLARE_OBJECT. This is generic ELF stuff. */
5360
5361 void
5362 mips_finish_declare_object (FILE *stream, tree decl, int top_level, int at_end)
5363 {
5364 const char *name;
5365
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)
5372 {
5373 HOST_WIDE_INT size;
5374
5375 size_directive_output = 1;
5376 size = int_size_in_bytes (TREE_TYPE (decl));
5377 ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
5378 }
5379 }
5380 #endif
5381 \f
5382 /* Return true if X is a small data address that can be rewritten
5383 as a LO_SUM. */
5384
5385 static bool
5386 mips_rewrite_small_data_p (rtx x)
5387 {
5388 enum mips_symbol_type symbol_type;
5389
5390 return (TARGET_EXPLICIT_RELOCS
5391 && mips_symbolic_constant_p (x, &symbol_type)
5392 && symbol_type == SYMBOL_SMALL_DATA);
5393 }
5394
5395
5396 /* A for_each_rtx callback for mips_small_data_pattern_p. */
5397
5398 static int
5399 mips_small_data_pattern_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
5400 {
5401 if (GET_CODE (*loc) == LO_SUM)
5402 return -1;
5403
5404 return mips_rewrite_small_data_p (*loc);
5405 }
5406
5407 /* Return true if OP refers to small data symbols directly, not through
5408 a LO_SUM. */
5409
5410 bool
5411 mips_small_data_pattern_p (rtx op)
5412 {
5413 return for_each_rtx (&op, mips_small_data_pattern_1, 0);
5414 }
5415 \f
5416 /* A for_each_rtx callback, used by mips_rewrite_small_data. */
5417
5418 static int
5419 mips_rewrite_small_data_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
5420 {
5421 if (mips_rewrite_small_data_p (*loc))
5422 *loc = gen_rtx_LO_SUM (Pmode, pic_offset_table_rtx, *loc);
5423
5424 if (GET_CODE (*loc) == LO_SUM)
5425 return -1;
5426
5427 return 0;
5428 }
5429
5430 /* If possible, rewrite OP so that it refers to small data using
5431 explicit relocations. */
5432
5433 rtx
5434 mips_rewrite_small_data (rtx op)
5435 {
5436 op = copy_insn (op);
5437 for_each_rtx (&op, mips_rewrite_small_data_1, 0);
5438 return op;
5439 }
5440 \f
5441 /* Return true if the current function has an insn that implicitly
5442 refers to $gp. */
5443
5444 static bool
5445 mips_function_has_gp_insn (void)
5446 {
5447 /* Don't bother rechecking if we found one last time. */
5448 if (!cfun->machine->has_gp_insn_p)
5449 {
5450 rtx insn;
5451
5452 push_topmost_sequence ();
5453 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5454 if (INSN_P (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)))
5459 break;
5460 pop_topmost_sequence ();
5461
5462 cfun->machine->has_gp_insn_p = (insn != 0);
5463 }
5464 return cfun->machine->has_gp_insn_p;
5465 }
5466
5467
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. */
5471
5472 static unsigned int
5473 mips_global_pointer (void)
5474 {
5475 unsigned int regno;
5476
5477 /* $gp is always available in non-abicalls code. */
5478 if (!TARGET_ABICALLS)
5479 return GLOBAL_POINTER_REGNUM;
5480
5481 /* We must always provide $gp when it is used implicitly. */
5482 if (!TARGET_EXPLICIT_RELOCS)
5483 return GLOBAL_POINTER_REGNUM;
5484
5485 /* FUNCTION_PROFILER includes a jal macro, so we need to give it
5486 a valid gp. */
5487 if (current_function_profile)
5488 return GLOBAL_POINTER_REGNUM;
5489
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;
5494
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:
5499
5500 (set (reg:DF R1) (float:DF (reg:SI R2)))
5501
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.
5505
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 ())
5511 return 0;
5512
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)
5521 return regno;
5522
5523 return GLOBAL_POINTER_REGNUM;
5524 }
5525
5526
5527 /* Return true if the current function must save REGNO. */
5528
5529 static bool
5530 mips_save_reg_p (unsigned int regno)
5531 {
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);
5536
5537 /* Check call-saved registers. */
5538 if (regs_ever_live[regno] && !call_used_regs[regno])
5539 return true;
5540
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)
5543 return true;
5544
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])
5548 return true;
5549
5550 if (TARGET_MIPS16)
5551 {
5552 tree return_type;
5553
5554 return_type = DECL_RESULT (current_function_decl);
5555
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])
5560 return true;
5561
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
5564 floating point. */
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)
5570 return true;
5571 }
5572
5573 return false;
5574 }
5575
5576
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.
5579
5580 Mips stack frames look like:
5581
5582 Before call After call
5583 +-----------------------+ +-----------------------+
5584 high | | | |
5585 mem. | | | |
5586 | caller's temps. | | caller's temps. |
5587 | | | |
5588 +-----------------------+ +-----------------------+
5589 | | | |
5590 | arguments on stack. | | arguments on stack. |
5591 | | | |
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 +-----------------------+ +-----------------------+
5598 | |
5599 | fp register save |
5600 | |
5601 +-----------------------+
5602 | |
5603 | gp register save |
5604 | |
5605 +-----------------------+
5606 | |
5607 | local variables |
5608 | |
5609 +-----------------------+
5610 | |
5611 | alloca allocations |
5612 | |
5613 +-----------------------+
5614 | |
5615 | GP save for V.4 abi |
5616 | |
5617 +-----------------------+
5618 | |
5619 | arguments on stack |
5620 | |
5621 +-----------------------+
5622 | 4 words to save |
5623 | arguments passed |
5624 | in registers, even |
5625 low SP->| if not passed. |
5626 memory +-----------------------+
5627
5628 */
5629
5630 HOST_WIDE_INT
5631 compute_frame_size (HOST_WIDE_INT size)
5632 {
5633 unsigned int regno;
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 */
5643
5644 cfun->machine->global_pointer = mips_global_pointer ();
5645
5646 gp_reg_size = 0;
5647 fp_reg_size = 0;
5648 mask = 0;
5649 fmask = 0;
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;
5653
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;
5659
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. */
5664
5665 if (args_size == 0 && current_function_calls_alloca)
5666 args_size = 4 * UNITS_PER_WORD;
5667
5668 total_size = var_size + args_size + cprestore_size;
5669
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))
5673 {
5674 gp_reg_size += GET_MODE_SIZE (gpr_mode);
5675 mask |= 1 << (regno - GP_REG_FIRST);
5676 }
5677
5678 /* We need to restore these for the handler. */
5679 if (current_function_calls_eh_return)
5680 {
5681 unsigned int i;
5682 for (i = 0; ; ++i)
5683 {
5684 regno = EH_RETURN_DATA_REGNO (i);
5685 if (regno == INVALID_REGNUM)
5686 break;
5687 gp_reg_size += GET_MODE_SIZE (gpr_mode);
5688 mask |= 1 << (regno - GP_REG_FIRST);
5689 }
5690 }
5691
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;
5696 regno -= FP_INC)
5697 {
5698 if (mips_save_reg_p (regno))
5699 {
5700 fp_reg_size += FP_INC * UNITS_PER_FPREG;
5701 fmask |= ((1 << FP_INC) - 1) << (regno - FP_REG_FIRST);
5702 }
5703 }
5704
5705 gp_reg_rounded = MIPS_STACK_ALIGN (gp_reg_size);
5706 total_size += gp_reg_rounded + MIPS_STACK_ALIGN (fp_reg_size);
5707
5708 /* Add in space reserved on the stack by the callee for storing arguments
5709 passed in registers. */
5710 if (!TARGET_OLDABI)
5711 total_size += MIPS_STACK_ALIGN (current_function_pretend_args_size);
5712
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);
5725
5726 if (mask)
5727 {
5728 HOST_WIDE_INT offset;
5729
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;
5734 }
5735 else
5736 {
5737 cfun->machine->frame.gp_sp_offset = 0;
5738 cfun->machine->frame.gp_save_offset = 0;
5739 }
5740
5741 if (fmask)
5742 {
5743 HOST_WIDE_INT offset;
5744
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;
5750 }
5751 else
5752 {
5753 cfun->machine->frame.fp_sp_offset = 0;
5754 cfun->machine->frame.fp_save_offset = 0;
5755 }
5756
5757 /* Ok, we're done. */
5758 return total_size;
5759 }
5760 \f
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. */
5764
5765 HOST_WIDE_INT
5766 mips_initial_elimination_offset (int from, int to)
5767 {
5768 HOST_WIDE_INT offset;
5769
5770 compute_frame_size (get_frame_size ());
5771
5772 /* Set OFFSET to the offset from the stack pointer. */
5773 switch (from)
5774 {
5775 case FRAME_POINTER_REGNUM:
5776 offset = 0;
5777 break;
5778
5779 case ARG_POINTER_REGNUM:
5780 offset = cfun->machine->frame.total_size;
5781 if (TARGET_NEWABI)
5782 offset -= current_function_pretend_args_size;
5783 break;
5784
5785 default:
5786 abort ();
5787 }
5788
5789 if (TARGET_MIPS16 && to == HARD_FRAME_POINTER_REGNUM)
5790 offset -= cfun->machine->frame.args_size;
5791
5792 return offset;
5793 }
5794 \f
5795 /* Implement RETURN_ADDR_RTX. Note, we do not support moving
5796 back to a previous frame. */
5797 rtx
5798 mips_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
5799 {
5800 if (count != 0)
5801 return const0_rtx;
5802
5803 return get_hard_reg_initial_val (Pmode, GP_REG_FIRST + 31);
5804 }
5805 \f
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
5808 stack pointer. */
5809
5810 static void
5811 mips_save_restore_reg (enum machine_mode mode, int regno,
5812 HOST_WIDE_INT offset, mips_save_restore_fn fn)
5813 {
5814 rtx mem;
5815
5816 mem = gen_rtx_MEM (mode, plus_constant (stack_pointer_rtx, offset));
5817
5818 fn (gen_rtx_REG (mode, regno), mem);
5819 }
5820
5821
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
5824 of the frame. */
5825
5826 static void
5827 mips_for_each_saved_reg (HOST_WIDE_INT sp_offset, mips_save_restore_fn fn)
5828 {
5829 #define BITSET_P(VALUE, BIT) (((VALUE) & (1L << (BIT))) != 0)
5830
5831 enum machine_mode fpr_mode;
5832 HOST_WIDE_INT offset;
5833 int regno;
5834
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))
5842 {
5843 mips_save_restore_reg (gpr_mode, regno, offset, fn);
5844 offset -= GET_MODE_SIZE (gpr_mode);
5845 }
5846
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;
5853 regno -= FP_INC)
5854 if (BITSET_P (cfun->machine->frame.fmask, regno - FP_REG_FIRST))
5855 {
5856 mips_save_restore_reg (fpr_mode, regno, offset, fn);
5857 offset -= GET_MODE_SIZE (fpr_mode);
5858 }
5859 #undef BITSET_P
5860 }
5861 \f
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. */
5865
5866 static void
5867 mips_output_cplocal (void)
5868 {
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);
5873 }
5874
5875 /* If we're generating n32 or n64 abicalls, emit instructions
5876 to set up the global pointer. */
5877
5878 static void
5879 mips_emit_loadgp (void)
5880 {
5881 if (TARGET_ABICALLS && TARGET_NEWABI && cfun->machine->global_pointer > 0)
5882 {
5883 rtx addr, offset, incoming_address;
5884
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 ());
5891 }
5892 }
5893
5894 /* Set up the stack and frame (if desired) for the function. */
5895
5896 static void
5897 mips_output_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
5898 {
5899 const char *fnname;
5900 HOST_WIDE_INT tsize = cfun->machine->frame.total_size;
5901
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);
5905 #endif
5906
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
5910 function proper. */
5911 if (TARGET_MIPS16 && !TARGET_SOFT_FLOAT
5912 && current_function_args_info.fp_code != 0)
5913 build_mips16_function_stub (file);
5914
5915 if (!FUNCTION_NAME_ALREADY_DECLARED)
5916 {
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);
5921
5922 if (!flag_inhibit_size_directive)
5923 {
5924 fputs ("\t.ent\t", file);
5925 assemble_name (file, fnname);
5926 fputs ("\n", file);
5927 }
5928
5929 assemble_name (file, fnname);
5930 fputs (":\n", file);
5931 }
5932
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;
5936
5937 if (!flag_inhibit_size_directive)
5938 {
5939 /* .frame FRAMEREG, FRAMESIZE, RETREG */
5940 fprintf (file,
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
5949 : tsize),
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);
5956
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);
5964
5965 /* Require:
5966 OLD_SP == *FRAMEREG + FRAMESIZE => can find old_sp from nominated FP reg.
5967 HIGHEST_GP_SAVED == *FRAMEREG + FRAMESIZE + GPOFFSET => can find saved regs. */
5968 }
5969
5970 if (TARGET_ABICALLS && !TARGET_NEWABI && cfun->machine->global_pointer > 0)
5971 {
5972 /* Handle the initialization of $gp for SVR4 PIC. */
5973 if (!cfun->machine->all_noreorder_p)
5974 output_asm_insn ("%(.cpload\t%^%)", 0);
5975 else
5976 output_asm_insn ("%(.cpload\t%^\n\t%<", 0);
5977 }
5978 else if (cfun->machine->all_noreorder_p)
5979 output_asm_insn ("%(%<", 0);
5980
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 ();
5985 }
5986 \f
5987 /* Make the last instruction frame related and note that it performs
5988 the operation described by FRAME_PATTERN. */
5989
5990 static void
5991 mips_set_frame_expr (rtx frame_pattern)
5992 {
5993 rtx insn;
5994
5995 insn = get_last_insn ();
5996 RTX_FRAME_RELATED_P (insn) = 1;
5997 REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
5998 frame_pattern,
5999 REG_NOTES (insn));
6000 }
6001
6002
6003 /* Return a frame-related rtx that stores REG at MEM.
6004 REG must be a single register. */
6005
6006 static rtx
6007 mips_frame_set (rtx mem, rtx reg)
6008 {
6009 rtx set = gen_rtx_SET (VOIDmode, mem, reg);
6010 RTX_FRAME_RELATED_P (set) = 1;
6011 return set;
6012 }
6013
6014
6015 /* Save register REG to MEM. Make the instruction frame-related. */
6016
6017 static void
6018 mips_save_reg (rtx reg, rtx mem)
6019 {
6020 if (GET_MODE (reg) == DFmode && !TARGET_FLOAT64)
6021 {
6022 rtx x1, x2;
6023
6024 if (mips_split_64bit_move_p (mem, reg))
6025 mips_split_64bit_move (mem, reg);
6026 else
6027 emit_move_insn (mem, reg);
6028
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)));
6032 }
6033 else
6034 {
6035 if (TARGET_MIPS16
6036 && REGNO (reg) != GP_REG_FIRST + 31
6037 && !M16_REG_P (REGNO (reg)))
6038 {
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)));
6044 }
6045 else
6046 emit_move_insn (mem, reg);
6047
6048 mips_set_frame_expr (mips_frame_set (mem, reg));
6049 }
6050 }
6051
6052
6053 /* Expand the prologue into a bunch of separate insns. */
6054
6055 void
6056 mips_expand_prologue (void)
6057 {
6058 HOST_WIDE_INT size;
6059
6060 if (cfun->machine->global_pointer > 0)
6061 REGNO (pic_offset_table_rtx) = cfun->machine->global_pointer;
6062
6063 size = compute_frame_size (get_frame_size ());
6064
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)
6069 {
6070 HOST_WIDE_INT step1;
6071
6072 step1 = MIN (size, MIPS_MAX_FIRST_STACK_STEP);
6073 RTX_FRAME_RELATED_P (emit_insn (gen_add3_insn (stack_pointer_rtx,
6074 stack_pointer_rtx,
6075 GEN_INT (-step1)))) = 1;
6076 size -= step1;
6077 mips_for_each_saved_reg (size, mips_save_reg);
6078 }
6079
6080 /* Allocate the rest of the frame. */
6081 if (size > 0)
6082 {
6083 if (SMALL_OPERAND (-size))
6084 RTX_FRAME_RELATED_P (emit_insn (gen_add3_insn (stack_pointer_rtx,
6085 stack_pointer_rtx,
6086 GEN_INT (-size)))) = 1;
6087 else
6088 {
6089 emit_move_insn (MIPS_PROLOGUE_TEMP (Pmode), GEN_INT (size));
6090 if (TARGET_MIPS16)
6091 {
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)
6097 abort ();
6098
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);
6104 }
6105 else
6106 emit_insn (gen_sub3_insn (stack_pointer_rtx,
6107 stack_pointer_rtx,
6108 MIPS_PROLOGUE_TEMP (Pmode)));
6109
6110 /* Describe the combined effect of the previous instructions. */
6111 mips_set_frame_expr
6112 (gen_rtx_SET (VOIDmode, stack_pointer_rtx,
6113 plus_constant (stack_pointer_rtx, -size)));
6114 }
6115 }
6116
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)
6122 {
6123 if (TARGET_MIPS16 && cfun->machine->frame.args_size != 0)
6124 {
6125 rtx offset = GEN_INT (cfun->machine->frame.args_size);
6126 RTX_FRAME_RELATED_P
6127 (emit_insn (gen_add3_insn (hard_frame_pointer_rtx,
6128 stack_pointer_rtx,
6129 offset))) = 1;
6130 }
6131 else
6132 RTX_FRAME_RELATED_P (emit_move_insn (hard_frame_pointer_rtx,
6133 stack_pointer_rtx)) = 1;
6134 }
6135
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)));
6139
6140 mips_emit_loadgp ();
6141
6142 /* If we are profiling, make sure no instructions are scheduled before
6143 the call to mcount. */
6144
6145 if (current_function_profile)
6146 emit_insn (gen_blockage ());
6147 }
6148 \f
6149 /* Do any necessary cleanup after a function to restore stack, frame,
6150 and regs. */
6151
6152 #define RA_MASK BITMASK_HIGH /* 1 << 31 */
6153
6154 static void
6155 mips_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
6156 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
6157 {
6158 /* Reinstate the normal $gp. */
6159 REGNO (pic_offset_table_rtx) = GLOBAL_POINTER_REGNUM;
6160 mips_output_cplocal ();
6161
6162 if (cfun->machine->all_noreorder_p)
6163 {
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;
6168 }
6169
6170 if (!FUNCTION_NAME_ALREADY_DECLARED && !flag_inhibit_size_directive)
6171 {
6172 const char *fnname;
6173
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);
6180 fputs ("\n", file);
6181 }
6182 }
6183 \f
6184 /* Emit instructions to restore register REG from slot MEM. */
6185
6186 static void
6187 mips_restore_reg (rtx reg, rtx mem)
6188 {
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);
6193
6194 if (TARGET_MIPS16 && !M16_REG_P (REGNO (reg)))
6195 {
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)));
6199 }
6200 else
6201 emit_move_insn (reg, mem);
6202 }
6203
6204
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. */
6208
6209 void
6210 mips_expand_epilogue (int sibcall_p)
6211 {
6212 HOST_WIDE_INT step1, step2;
6213 rtx base, target;
6214
6215 if (!sibcall_p && mips_can_use_return_insn ())
6216 {
6217 emit_jump_insn (gen_return ());
6218 return;
6219 }
6220
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.
6224
6225 Start off by assuming that no registers need to be restored. */
6226 step1 = cfun->machine->frame.total_size;
6227 step2 = 0;
6228
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;
6233 else
6234 {
6235 base = hard_frame_pointer_rtx;
6236 if (TARGET_MIPS16)
6237 step1 -= cfun->machine->frame.args_size;
6238 }
6239
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)
6243 {
6244 step2 = MIN (step1, MIPS_MAX_FIRST_STACK_STEP);
6245 step1 -= step2;
6246 }
6247
6248 /* Set TARGET to BASE + STEP1. */
6249 target = base;
6250 if (step1 > 0)
6251 {
6252 rtx adjust;
6253
6254 /* Get an rtx for STEP1 that we can add to BASE. */
6255 adjust = GEN_INT (step1);
6256 if (!SMALL_OPERAND (step1))
6257 {
6258 emit_move_insn (MIPS_EPILOGUE_TEMP (Pmode), adjust);
6259 adjust = MIPS_EPILOGUE_TEMP (Pmode);
6260 }
6261
6262 /* Normal mode code can copy the result straight into $sp. */
6263 if (!TARGET_MIPS16)
6264 target = stack_pointer_rtx;
6265
6266 emit_insn (gen_add3_insn (target, base, adjust));
6267 }
6268
6269 /* Copy TARGET into the stack pointer. */
6270 if (target != stack_pointer_rtx)
6271 emit_move_insn (stack_pointer_rtx, target);
6272
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 ());
6278
6279 /* Restore the registers. */
6280 mips_for_each_saved_reg (cfun->machine->frame.total_size - step2,
6281 mips_restore_reg);
6282
6283 /* Deallocate the final bit of the frame. */
6284 if (step2 > 0)
6285 emit_insn (gen_add3_insn (stack_pointer_rtx,
6286 stack_pointer_rtx,
6287 GEN_INT (step2)));
6288
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)
6292 {
6293 if (TARGET_MIPS16)
6294 {
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));
6300 }
6301 else
6302 emit_insn (gen_add3_insn (stack_pointer_rtx,
6303 stack_pointer_rtx,
6304 EH_RETURN_STACKADJ_RTX));
6305 }
6306
6307 if (!sibcall_p)
6308 {
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)));
6313 else
6314 emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode,
6315 GP_REG_FIRST + 31)));
6316 }
6317 }
6318 \f
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
6321 was created. */
6322
6323 int
6324 mips_can_use_return_insn (void)
6325 {
6326 tree return_type;
6327
6328 if (! reload_completed)
6329 return 0;
6330
6331 if (regs_ever_live[31] || current_function_profile)
6332 return 0;
6333
6334 return_type = DECL_RESULT (current_function_decl);
6335
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
6338 registers. */
6339 if (TARGET_MIPS16
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)
6344 return 0;
6345
6346 if (cfun->machine->frame.initialized)
6347 return cfun->machine->frame.total_size == 0;
6348
6349 return compute_frame_size (get_frame_size ()) == 0;
6350 }
6351 \f
6352 /* Implement TARGET_ASM_OUTPUT_MI_THUNK. Generate rtl rather than asm text
6353 in order to avoid duplicating too much logic from elsewhere. */
6354
6355 static void
6356 mips_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
6357 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
6358 tree function)
6359 {
6360 rtx this, temp1, temp2, insn, fnaddr;
6361
6362 /* Pretend to be a post-reload pass while generating rtl. */
6363 no_new_pseudos = 1;
6364 reload_completed = 1;
6365 reset_block_changes ();
6366
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;
6373
6374 /* Set up the global pointer for n32 or n64 abicalls. */
6375 mips_emit_loadgp ();
6376
6377 /* We need two temporary registers in some cases. */
6378 temp1 = gen_rtx_REG (Pmode, 2);
6379 temp2 = gen_rtx_REG (Pmode, 3);
6380
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);
6384 else
6385 this = gen_rtx_REG (Pmode, GP_ARG_FIRST);
6386
6387 /* Add DELTA to THIS. */
6388 if (delta != 0)
6389 {
6390 rtx offset = GEN_INT (delta);
6391 if (!SMALL_OPERAND (delta))
6392 {
6393 emit_move_insn (temp1, offset);
6394 offset = temp1;
6395 }
6396 emit_insn (gen_add3_insn (this, this, offset));
6397 }
6398
6399 /* If needed, add *(*THIS + VCALL_OFFSET) to THIS. */
6400 if (vcall_offset != 0)
6401 {
6402 rtx addr;
6403
6404 /* Set TEMP1 to *THIS. */
6405 emit_move_insn (temp1, gen_rtx_MEM (Pmode, this));
6406
6407 /* Set ADDR to a legitimate address for *THIS + VCALL_OFFSET. */
6408 addr = mips_add_offset (temp2, temp1, vcall_offset);
6409
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));
6413 }
6414
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)
6419 {
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.
6423
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.
6428
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);
6434
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));
6438 }
6439 else
6440 {
6441 insn = emit_call_insn (gen_sibcall_internal (fnaddr, const0_rtx));
6442 SIBLING_CALL_P (insn) = 1;
6443 }
6444
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 ();
6450 if (TARGET_MIPS16)
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 ();
6456
6457 /* Clean up the vars set above. Note that final_end_function resets
6458 the global pointer for us. */
6459 reload_completed = 0;
6460 no_new_pseudos = 0;
6461 }
6462 \f
6463 /* Returns nonzero if X contains a SYMBOL_REF. */
6464
6465 static int
6466 symbolic_expression_p (rtx x)
6467 {
6468 if (GET_CODE (x) == SYMBOL_REF)
6469 return 1;
6470
6471 if (GET_CODE (x) == CONST)
6472 return symbolic_expression_p (XEXP (x, 0));
6473
6474 if (UNARY_P (x))
6475 return symbolic_expression_p (XEXP (x, 0));
6476
6477 if (ARITHMETIC_P (x))
6478 return (symbolic_expression_p (XEXP (x, 0))
6479 || symbolic_expression_p (XEXP (x, 1)));
6480
6481 return 0;
6482 }
6483
6484 /* Choose the section to use for the constant rtx expression X that has
6485 mode MODE. */
6486
6487 static void
6488 mips_select_rtx_section (enum machine_mode mode, rtx x,
6489 unsigned HOST_WIDE_INT align)
6490 {
6491 if (TARGET_MIPS16)
6492 {
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
6495 addressing. */
6496 function_section (current_function_decl);
6497 }
6498 else if (TARGET_EMBEDDED_DATA)
6499 {
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);
6503 }
6504 else
6505 {
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. */
6509
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);
6515 else
6516 mergeable_constant_section (mode, align, 0);
6517 }
6518 }
6519
6520 /* Implement TARGET_IN_SMALL_DATA_P. Return true if it would be safe to
6521 access DECL using %gp_rel(...)($gp). */
6522
6523 static bool
6524 mips_in_small_data_p (tree decl)
6525 {
6526 HOST_WIDE_INT size;
6527
6528 if (TREE_CODE (decl) == STRING_CST || TREE_CODE (decl) == FUNCTION_DECL)
6529 return false;
6530
6531 /* We don't yet generate small-data references for -mabicalls. See related
6532 -G handling in override_options. */
6533 if (TARGET_ABICALLS)
6534 return false;
6535
6536 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl) != 0)
6537 {
6538 const char *name;
6539
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)
6543 return false;
6544
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))
6548 return true;
6549 }
6550 else if (TARGET_EMBEDDED_DATA)
6551 {
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)
6555 return false;
6556
6557 if (TREE_READONLY (decl)
6558 && !TREE_SIDE_EFFECTS (decl)
6559 && (!DECL_INITIAL (decl) || TREE_CONSTANT (DECL_INITIAL (decl))))
6560 return false;
6561 }
6562
6563 size = int_size_in_bytes (TREE_TYPE (decl));
6564 return (size > 0 && size <= mips_section_threshold);
6565 }
6566 \f
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
6570 otherwise.
6571
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
6574 type. */
6575
6576 static int
6577 mips_fpr_return_fields (tree valtype, tree *fields)
6578 {
6579 tree field;
6580 int i;
6581
6582 if (!TARGET_NEWABI)
6583 return 0;
6584
6585 if (TREE_CODE (valtype) != RECORD_TYPE)
6586 return 0;
6587
6588 i = 0;
6589 for (field = TYPE_FIELDS (valtype); field != 0; field = TREE_CHAIN (field))
6590 {
6591 if (TREE_CODE (field) != FIELD_DECL)
6592 continue;
6593
6594 if (TREE_CODE (TREE_TYPE (field)) != REAL_TYPE)
6595 return 0;
6596
6597 if (i == 2)
6598 return 0;
6599
6600 fields[i++] = field;
6601 }
6602 return i;
6603 }
6604
6605
6606 /* Implement TARGET_RETURN_IN_MSB. For n32 & n64, we should return
6607 a value in the most significant part of $2/$3 if:
6608
6609 - the target is big-endian;
6610
6611 - the value has a structure or union type (we generalize this to
6612 cover aggregates from other languages too); and
6613
6614 - the structure is not returned in floating-point registers. */
6615
6616 static bool
6617 mips_return_in_msb (tree valtype)
6618 {
6619 tree fields[2];
6620
6621 return (TARGET_NEWABI
6622 && TARGET_BIG_ENDIAN
6623 && AGGREGATE_TYPE_P (valtype)
6624 && mips_fpr_return_fields (valtype, fields) == 0);
6625 }
6626
6627
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
6631 complete value.
6632
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. */
6635
6636 static rtx
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)
6640 {
6641 int inc;
6642
6643 inc = (TARGET_NEWABI ? 2 : FP_INC);
6644 return gen_rtx_PARALLEL
6645 (mode,
6646 gen_rtvec (2,
6647 gen_rtx_EXPR_LIST (VOIDmode,
6648 gen_rtx_REG (mode1, FP_RETURN),
6649 GEN_INT (offset1)),
6650 gen_rtx_EXPR_LIST (VOIDmode,
6651 gen_rtx_REG (mode2, FP_RETURN + inc),
6652 GEN_INT (offset2))));
6653
6654 }
6655
6656
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. */
6660
6661 rtx
6662 mips_function_value (tree valtype, tree func ATTRIBUTE_UNUSED,
6663 enum machine_mode mode)
6664 {
6665 if (valtype)
6666 {
6667 tree fields[2];
6668 int unsignedp;
6669
6670 mode = TYPE_MODE (valtype);
6671 unsignedp = TYPE_UNSIGNED (valtype);
6672
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);
6676
6677 /* Handle structures whose fields are returned in $f0/$f2. */
6678 switch (mips_fpr_return_fields (valtype, fields))
6679 {
6680 case 1:
6681 return gen_rtx_REG (mode, FP_RETURN);
6682
6683 case 2:
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]));
6689 }
6690
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))
6694 {
6695 HOST_WIDE_INT size = int_size_in_bytes (valtype);
6696 if (size % UNITS_PER_WORD != 0)
6697 {
6698 size += UNITS_PER_WORD - size % UNITS_PER_WORD;
6699 mode = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0);
6700 }
6701 }
6702 }
6703
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);
6708
6709 /* Handle long doubles for n32 & n64. */
6710 if (mode == TFmode)
6711 return mips_return_fpr_pair (mode,
6712 DImode, 0,
6713 DImode, GET_MODE_SIZE (mode) / 2);
6714
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);
6721
6722 return gen_rtx_REG (mode, GP_RETURN);
6723 }
6724
6725 /* Return nonzero when an argument must be passed by reference. */
6726
6727 static bool
6728 mips_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
6729 enum machine_mode mode, tree type,
6730 bool named ATTRIBUTE_UNUSED)
6731 {
6732 if (mips_abi == ABI_EABI)
6733 {
6734 int size;
6735
6736 /* ??? How should SCmode be handled? */
6737 if (type == NULL_TREE || mode == DImode || mode == DFmode)
6738 return 0;
6739
6740 size = int_size_in_bytes (type);
6741 return size == -1 || size > UNITS_PER_WORD;
6742 }
6743 else
6744 {
6745 /* If we have a variable-sized parameter, we have no choice. */
6746 return targetm.calls.must_pass_in_stack (mode, type);
6747 }
6748 }
6749
6750 /* Return the class of registers for which a mode change from FROM to TO
6751 is invalid.
6752
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
6755 word as intended.
6756
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
6760 as intended.
6761
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. */
6766
6767 bool
6768 mips_cannot_change_mode_class (enum machine_mode from,
6769 enum machine_mode to, enum reg_class class)
6770 {
6771 if (GET_MODE_SIZE (from) != GET_MODE_SIZE (to))
6772 {
6773 if (TARGET_BIG_ENDIAN)
6774 return reg_classes_intersect_p (FP_REGS, class);
6775 if (TARGET_FLOAT64)
6776 return reg_classes_intersect_p (HI_AND_FP_REGS, class);
6777 return reg_classes_intersect_p (HI_REG, class);
6778 }
6779 return false;
6780 }
6781
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. */
6785
6786 bool
6787 mips_dangerous_for_la25_p (rtx x)
6788 {
6789 HOST_WIDE_INT offset;
6790
6791 if (TARGET_EXPLICIT_RELOCS)
6792 return false;
6793
6794 mips_split_const (x, &x, &offset);
6795 return global_got_operand (x, VOIDmode);
6796 }
6797
6798 /* Implement PREFERRED_RELOAD_CLASS. */
6799
6800 enum reg_class
6801 mips_preferred_reload_class (rtx x, enum reg_class class)
6802 {
6803 if (mips_dangerous_for_la25_p (x) && reg_class_subset_p (LEA_REGS, class))
6804 return LEA_REGS;
6805
6806 if (TARGET_HARD_FLOAT
6807 && FLOAT_MODE_P (GET_MODE (x))
6808 && reg_class_subset_p (FP_REGS, class))
6809 return FP_REGS;
6810
6811 if (reg_class_subset_p (GR_REGS, class))
6812 class = GR_REGS;
6813
6814 if (TARGET_MIPS16 && reg_class_subset_p (M16_REGS, class))
6815 class = M16_REGS;
6816
6817 return class;
6818 }
6819
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. */
6825
6826 enum reg_class
6827 mips_secondary_reload_class (enum reg_class class,
6828 enum machine_mode mode, rtx x, int in_p)
6829 {
6830 enum reg_class gr_regs = TARGET_MIPS16 ? M16_REGS : GR_REGS;
6831 int regno = -1;
6832 int gp_reg_p;
6833
6834 if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
6835 regno = true_regnum (x);
6836
6837 gp_reg_p = TARGET_MIPS16 ? M16_REG_P (regno) : GP_REG_P (regno);
6838
6839 if (mips_dangerous_for_la25_p (x))
6840 {
6841 gr_regs = LEA_REGS;
6842 if (TEST_HARD_REG_BIT (reg_class_contents[(int) class], 25))
6843 return gr_regs;
6844 }
6845
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)
6849 {
6850 if (TARGET_MIPS16 && in_p)
6851 {
6852 /* We can't really copy to HI or LO at all in mips16 mode. */
6853 return M16_REGS;
6854 }
6855 return gp_reg_p ? NO_REGS : gr_regs;
6856 }
6857 if (MD_REG_P (regno))
6858 {
6859 if (TARGET_MIPS16 && ! in_p)
6860 {
6861 /* We can't really copy to HI or LO at all in mips16 mode. */
6862 return M16_REGS;
6863 }
6864 return class == gr_regs ? NO_REGS : gr_regs;
6865 }
6866
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)
6872 {
6873 if (in_p)
6874 return FP_REGS;
6875 return gp_reg_p ? NO_REGS : gr_regs;
6876 }
6877 if (ST_REG_P (regno))
6878 {
6879 if (! in_p)
6880 return FP_REGS;
6881 return class == gr_regs ? NO_REGS : gr_regs;
6882 }
6883
6884 if (class == FP_REGS)
6885 {
6886 if (GET_CODE (x) == MEM)
6887 {
6888 /* In this case we can use lwc1, swc1, ldc1 or sdc1. */
6889 return NO_REGS;
6890 }
6891 else if (CONSTANT_P (x) && GET_MODE_CLASS (mode) == MODE_FLOAT)
6892 {
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. */
6896 return NO_REGS;
6897 }
6898 else if (gp_reg_p || x == CONST0_RTX (mode))
6899 {
6900 /* In this case we can use mtc1, mfc1, dmtc1 or dmfc1. */
6901 return NO_REGS;
6902 }
6903 else if (FP_REG_P (regno))
6904 {
6905 /* In this case we can use mov.s or mov.d. */
6906 return NO_REGS;
6907 }
6908 else
6909 {
6910 /* Otherwise, we need to reload through an integer register. */
6911 return gr_regs;
6912 }
6913 }
6914
6915 /* In mips16 mode, going between memory and anything but M16_REGS
6916 requires an M16_REG. */
6917 if (TARGET_MIPS16)
6918 {
6919 if (class != M16_REGS && class != M16_NA_REGS)
6920 {
6921 if (gp_reg_p)
6922 return NO_REGS;
6923 return M16_REGS;
6924 }
6925 if (! gp_reg_p)
6926 {
6927 if (class == M16_REGS || class == M16_NA_REGS)
6928 return NO_REGS;
6929 return M16_REGS;
6930 }
6931 }
6932
6933 return NO_REGS;
6934 }
6935
6936 /* Implement CLASS_MAX_NREGS.
6937
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.
6942
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. */
6946
6947 int
6948 mips_class_max_nregs (enum reg_class class ATTRIBUTE_UNUSED,
6949 enum machine_mode mode)
6950 {
6951 if (class == ST_REGS)
6952 return (GET_MODE_SIZE (mode) + 3) / 4;
6953 else
6954 return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
6955 }
6956
6957 bool
6958 mips_valid_pointer_mode (enum machine_mode mode)
6959 {
6960 return (mode == SImode || (TARGET_64BIT && mode == DImode));
6961 }
6962
6963 /* Target hook for vector_mode_supported_p. */
6964 static bool
6965 mips_vector_mode_supported_p (enum machine_mode mode)
6966 {
6967 if (mode == V2SFmode && TARGET_PAIRED_SINGLE_FLOAT)
6968 return true;
6969 else
6970 return false;
6971 }
6972 \f
6973 /* If we can access small data directly (using gp-relative relocation
6974 operators) return the small data pointer, otherwise return null.
6975
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. */
6979
6980 static rtx
6981 mips16_gp_pseudo_reg (void)
6982 {
6983 if (cfun->machine->mips16_gp_pseudo_rtx == NULL_RTX)
6984 {
6985 rtx unspec;
6986 rtx insn, scan;
6987
6988 cfun->machine->mips16_gp_pseudo_rtx = gen_reg_rtx (Pmode);
6989
6990 /* We want to initialize this to a value which gcc will believe
6991 is constant. */
6992 start_sequence ();
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 ();
6997 end_sequence ();
6998
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)
7005 break;
7006 if (scan == NULL_RTX)
7007 scan = get_insns ();
7008 insn = emit_insn_after (insn, scan);
7009 pop_topmost_sequence ();
7010 }
7011
7012 return cfun->machine->mips16_gp_pseudo_rtx;
7013 }
7014
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. */
7020
7021 static void
7022 mips16_fp_args (FILE *file, int fp_code, int from_fp_p)
7023 {
7024 const char *s;
7025 int gparg, fparg;
7026 unsigned int f;
7027
7028 /* This code only works for the original 32 bit ABI and the O64 ABI. */
7029 if (!TARGET_OLDABI)
7030 abort ();
7031
7032 if (from_fp_p)
7033 s = "mfc1";
7034 else
7035 s = "mtc1";
7036 gparg = GP_ARG_FIRST;
7037 fparg = FP_ARG_FIRST;
7038 for (f = (unsigned int) fp_code; f != 0; f >>= 2)
7039 {
7040 if ((f & 3) == 1)
7041 {
7042 if ((fparg & 1) != 0)
7043 ++fparg;
7044 fprintf (file, "\t%s\t%s,%s\n", s,
7045 reg_names[gparg], reg_names[fparg]);
7046 }
7047 else if ((f & 3) == 2)
7048 {
7049 if (TARGET_64BIT)
7050 fprintf (file, "\td%s\t%s,%s\n", s,
7051 reg_names[gparg], reg_names[fparg]);
7052 else
7053 {
7054 if ((fparg & 1) != 0)
7055 ++fparg;
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]);
7060 else
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]);
7064 ++gparg;
7065 ++fparg;
7066 }
7067 }
7068 else
7069 abort ();
7070
7071 ++gparg;
7072 ++fparg;
7073 }
7074 }
7075
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. */
7080
7081 static void
7082 build_mips16_function_stub (FILE *file)
7083 {
7084 const char *fnname;
7085 char *secname, *stubname;
7086 tree stubid, stubdecl;
7087 int need_comma;
7088 unsigned int f;
7089
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);
7099
7100 fprintf (file, "\t# Stub function for %s (", current_function_name ());
7101 need_comma = 0;
7102 for (f = (unsigned int) current_function_args_info.fp_code; f != 0; f >>= 2)
7103 {
7104 fprintf (file, "%s%s",
7105 need_comma ? ", " : "",
7106 (f & 3) == 1 ? "float" : "double");
7107 need_comma = 1;
7108 }
7109 fprintf (file, ")\n");
7110
7111 fprintf (file, "\t.set\tnomips16\n");
7112 function_section (stubdecl);
7113 ASM_OUTPUT_ALIGN (file, floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT));
7114
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)
7118 {
7119 fputs ("\t.ent\t", file);
7120 assemble_name (file, stubname);
7121 fputs ("\n", file);
7122 }
7123
7124 assemble_name (file, stubname);
7125 fputs (":\n", file);
7126
7127 /* We don't want the assembler to insert any nops here. */
7128 fprintf (file, "\t.set\tnoreorder\n");
7129
7130 mips16_fp_args (file, current_function_args_info.fp_code, 1);
7131
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");
7138
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
7143 value. */
7144 fprintf (file, "\tnop\n");
7145
7146 fprintf (file, "\t.set\treorder\n");
7147
7148 if (!FUNCTION_NAME_ALREADY_DECLARED)
7149 {
7150 fputs ("\t.end\t", file);
7151 assemble_name (file, stubname);
7152 fputs ("\n", file);
7153 }
7154
7155 fprintf (file, "\t.set\tmips16\n");
7156
7157 function_section (current_function_decl);
7158 }
7159
7160 /* We keep a list of functions for which we have already built stubs
7161 in build_mips16_call_stub. */
7162
7163 struct mips16_stub
7164 {
7165 struct mips16_stub *next;
7166 char *name;
7167 int fpret;
7168 };
7169
7170 static struct mips16_stub *mips16_stubs;
7171
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.
7180
7181 Similarly, we need a stub if the return value might come back in a
7182 floating point register.
7183
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. */
7189
7190 int
7191 build_mips16_call_stub (rtx retval, rtx fn, rtx arg_size, int fp_code)
7192 {
7193 int fpret;
7194 const char *fnname;
7195 char *secname, *stubname;
7196 struct mips16_stub *l;
7197 tree stubid, stubdecl;
7198 int need_comma;
7199 unsigned int f;
7200
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)
7204 return 0;
7205
7206 /* Figure out whether the value might come back in a floating point
7207 register. */
7208 fpret = (retval != 0
7209 && GET_MODE_CLASS (GET_MODE (retval)) == MODE_FLOAT
7210 && GET_MODE_SIZE (GET_MODE (retval)) <= UNITS_PER_FPVALUE);
7211
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
7214 register. */
7215 if (fp_code == 0 && ! fpret)
7216 return 0;
7217
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)
7222 return 0;
7223
7224 /* This code will only work for o32 and o64 abis. The other ABI's
7225 require more sophisticated support. */
7226 if (!TARGET_OLDABI)
7227 abort ();
7228
7229 /* We can only handle SFmode and DFmode floating point return
7230 values. */
7231 if (fpret && GET_MODE (retval) != SFmode && GET_MODE (retval) != DFmode)
7232 abort ();
7233
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. */
7238
7239 if (GET_CODE (fn) != SYMBOL_REF)
7240 {
7241 char buf[30];
7242 tree id;
7243 rtx stub_fn, insn;
7244
7245 /* ??? If this code is modified to support other ABI's, we need
7246 to handle PARALLEL return values here. */
7247
7248 sprintf (buf, "__mips16_call_stub_%s%d",
7249 (fpret
7250 ? (GET_MODE (retval) == SFmode ? "sf_" : "df_")
7251 : ""),
7252 fp_code);
7253 id = get_identifier (buf);
7254 stub_fn = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (id));
7255
7256 emit_move_insn (gen_rtx_REG (Pmode, 2), fn);
7257
7258 if (retval == NULL_RTX)
7259 insn = gen_call_internal (stub_fn, arg_size);
7260 else
7261 insn = gen_call_value_internal (retval, stub_fn, arg_size);
7262 insn = emit_call_insn (insn);
7263
7264 /* Put the register usage information on the CALL. */
7265 if (GET_CODE (insn) != CALL_INSN)
7266 abort ();
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));
7271
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
7276 code. */
7277 if (fpret)
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));
7283
7284 /* Return 1 to tell the caller that we've generated the call
7285 insn. */
7286 return 1;
7287 }
7288
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. */
7291
7292 fnname = XSTR (fn, 0);
7293 for (l = mips16_stubs; l != NULL; l = l->next)
7294 if (strcmp (l->name, fnname) == 0)
7295 break;
7296
7297 if (l == NULL)
7298 {
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
7307 section.
7308
7309 If the function does not return a floating point value, the
7310 special stub section is named
7311 .mips16.call.FNNAME
7312
7313 If the function does return a floating point value, the stub
7314 section is named
7315 .mips16.call.fp.FNNAME
7316 */
7317
7318 secname = (char *) alloca (strlen (fnname) + 40);
7319 sprintf (secname, ".mips16.call.%s%s",
7320 fpret ? "fp." : "",
7321 fnname);
7322 stubname = (char *) alloca (strlen (fnname) + 20);
7323 sprintf (stubname, "__call_stub_%s%s",
7324 fpret ? "fp_" : "",
7325 fnname);
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);
7330
7331 fprintf (asm_out_file, "\t# Stub function to call %s%s (",
7332 (fpret
7333 ? (GET_MODE (retval) == SFmode ? "float " : "double ")
7334 : ""),
7335 fnname);
7336 need_comma = 0;
7337 for (f = (unsigned int) fp_code; f != 0; f >>= 2)
7338 {
7339 fprintf (asm_out_file, "%s%s",
7340 need_comma ? ", " : "",
7341 (f & 3) == 1 ? "float" : "double");
7342 need_comma = 1;
7343 }
7344 fprintf (asm_out_file, ")\n");
7345
7346 fprintf (asm_out_file, "\t.set\tnomips16\n");
7347 assemble_start_function (stubdecl, stubname);
7348
7349 if (!FUNCTION_NAME_ALREADY_DECLARED)
7350 {
7351 fputs ("\t.ent\t", asm_out_file);
7352 assemble_name (asm_out_file, stubname);
7353 fputs ("\n", asm_out_file);
7354
7355 assemble_name (asm_out_file, stubname);
7356 fputs (":\n", asm_out_file);
7357 }
7358
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
7361 compilation. */
7362
7363 /* We don't want the assembler to insert any nops here. */
7364 fprintf (asm_out_file, "\t.set\tnoreorder\n");
7365
7366 mips16_fp_args (asm_out_file, fp_code, 0);
7367
7368 if (! fpret)
7369 {
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],
7372 fnname);
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");
7381 }
7382 else
7383 {
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]);
7392 else
7393 {
7394 if (TARGET_BIG_ENDIAN)
7395 {
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]);
7402 }
7403 else
7404 {
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]);
7411 }
7412 }
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");
7416 }
7417
7418 fprintf (asm_out_file, "\t.set\treorder\n");
7419
7420 #ifdef ASM_DECLARE_FUNCTION_SIZE
7421 ASM_DECLARE_FUNCTION_SIZE (asm_out_file, stubname, stubdecl);
7422 #endif
7423
7424 if (!FUNCTION_NAME_ALREADY_DECLARED)
7425 {
7426 fputs ("\t.end\t", asm_out_file);
7427 assemble_name (asm_out_file, stubname);
7428 fputs ("\n", asm_out_file);
7429 }
7430
7431 fprintf (asm_out_file, "\t.set\tmips16\n");
7432
7433 /* Record this stub. */
7434 l = (struct mips16_stub *) xmalloc (sizeof *l);
7435 l->name = xstrdup (fnname);
7436 l->fpret = fpret;
7437 l->next = mips16_stubs;
7438 mips16_stubs = l;
7439 }
7440
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);
7450
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
7455 it. */
7456
7457 if (l->fpret)
7458 {
7459 rtx insn;
7460
7461 if (retval == NULL_RTX)
7462 insn = gen_call_internal (fn, arg_size);
7463 else
7464 insn = gen_call_value_internal (retval, fn, arg_size);
7465 insn = emit_call_insn (insn);
7466
7467 if (GET_CODE (insn) != CALL_INSN)
7468 abort ();
7469
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));
7474
7475 /* Return 1 to tell the caller that we've generated the call
7476 insn. */
7477 return 1;
7478 }
7479
7480 /* Return 0 to let the caller generate the call insn. */
7481 return 0;
7482 }
7483
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. */
7486
7487 struct mips16_constant {
7488 struct mips16_constant *next;
7489 rtx value;
7490 rtx label;
7491 enum machine_mode mode;
7492 };
7493
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
7497 address. */
7498
7499 struct mips16_constant_pool {
7500 struct mips16_constant *first;
7501 int highest_address;
7502 int insn_address;
7503 };
7504
7505 /* Add constant VALUE to POOL and return its label. MODE is the
7506 value's mode (used for CONST_INTs, etc.). */
7507
7508 static rtx
7509 add_constant (struct mips16_constant_pool *pool,
7510 rtx value, enum machine_mode mode)
7511 {
7512 struct mips16_constant **p, *c;
7513 bool first_of_size_p;
7514
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.
7518
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)
7523 {
7524 if (mode == (*p)->mode && rtx_equal_p (value, (*p)->value))
7525 return (*p)->label;
7526 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE ((*p)->mode))
7527 break;
7528 if (GET_MODE_SIZE (mode) == GET_MODE_SIZE ((*p)->mode))
7529 first_of_size_p = false;
7530 }
7531
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.
7535
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;
7549
7550 /* Create a new entry. */
7551 c = (struct mips16_constant *) xmalloc (sizeof *c);
7552 c->value = value;
7553 c->mode = mode;
7554 c->label = gen_label_rtx ();
7555 c->next = *p;
7556 *p = c;
7557
7558 return c->label;
7559 }
7560
7561 /* Output constant VALUE after instruction INSN and return the last
7562 instruction emitted. MODE is the mode of the constant. */
7563
7564 static rtx
7565 dump_constants_1 (enum machine_mode mode, rtx value, rtx insn)
7566 {
7567 switch (GET_MODE_CLASS (mode))
7568 {
7569 case MODE_INT:
7570 {
7571 rtx size = GEN_INT (GET_MODE_SIZE (mode));
7572 return emit_insn_after (gen_consttable_int (value, size), insn);
7573 }
7574
7575 case MODE_FLOAT:
7576 return emit_insn_after (gen_consttable_float (value), insn);
7577
7578 case MODE_VECTOR_FLOAT:
7579 case MODE_VECTOR_INT:
7580 {
7581 int i;
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);
7585 return insn;
7586 }
7587
7588 default:
7589 abort ();
7590 }
7591 }
7592
7593
7594 /* Dump out the constants in CONSTANTS after INSN. */
7595
7596 static void
7597 dump_constants (struct mips16_constant *constants, rtx insn)
7598 {
7599 struct mips16_constant *c, *next;
7600 int align;
7601
7602 align = 0;
7603 for (c = constants; c != NULL; c = next)
7604 {
7605 /* If necessary, increase the alignment of PC. */
7606 if (align < GET_MODE_SIZE (c->mode))
7607 {
7608 int align_log = floor_log2 (GET_MODE_SIZE (c->mode));
7609 insn = emit_insn_after (gen_align (GEN_INT (align_log)), insn);
7610 }
7611 align = GET_MODE_SIZE (c->mode);
7612
7613 insn = emit_label_after (c->label, insn);
7614 insn = dump_constants_1 (c->mode, c->value, insn);
7615
7616 next = c->next;
7617 free (c);
7618 }
7619
7620 emit_barrier_after (insn);
7621 }
7622
7623 /* Return the length of instruction INSN.
7624
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. */
7628
7629 static int
7630 mips16_insn_length (rtx insn)
7631 {
7632 if (GET_CODE (insn) == JUMP_INSN)
7633 {
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);
7639 }
7640 return get_attr_length (insn);
7641 }
7642
7643 /* Rewrite *X so that constant pool references refer to the constant's
7644 label instead. DATA points to the constant pool structure. */
7645
7646 static int
7647 mips16_rewrite_pool_refs (rtx *x, void *data)
7648 {
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)));
7654 return 0;
7655 }
7656
7657 /* Build MIPS16 constant pools. */
7658
7659 static void
7660 mips16_lay_out_constants (void)
7661 {
7662 struct mips16_constant_pool pool;
7663 rtx insn, barrier;
7664
7665 barrier = 0;
7666 memset (&pool, 0, sizeof (pool));
7667 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7668 {
7669 /* Rewrite constant pool references in INSN. */
7670 if (INSN_P (insn))
7671 for_each_rtx (&PATTERN (insn), mips16_rewrite_pool_refs, &pool);
7672
7673 pool.insn_address += mips16_insn_length (insn);
7674
7675 if (pool.first != NULL)
7676 {
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.
7681
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)
7685 {
7686 rtx label, jump;
7687
7688 label = gen_label_rtx ();
7689
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);
7694
7695 emit_label_after (label, barrier);
7696 pool.insn_address += 4;
7697 }
7698
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)
7704 {
7705 dump_constants (pool.first, barrier);
7706 pool.first = NULL;
7707 barrier = 0;
7708 }
7709 else if (BARRIER_P (insn))
7710 barrier = insn;
7711 }
7712 }
7713 dump_constants (pool.first, get_last_insn ());
7714 }
7715 \f
7716 /* A temporary variable used by for_each_rtx callbacks, etc. */
7717 static rtx mips_sim_insn;
7718
7719 /* A structure representing the state of the processor pipeline.
7720 Used by the mips_sim_* family of functions. */
7721 struct mips_sim {
7722 /* The maximum number of instructions that can be issued in a cycle.
7723 (Caches mips_issue_rate.) */
7724 unsigned int issue_rate;
7725
7726 /* The current simulation time. */
7727 unsigned int time;
7728
7729 /* How many more instructions can be issued in the current cycle. */
7730 unsigned int insns_left;
7731
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. */
7735 struct {
7736 rtx insn;
7737 unsigned int time;
7738 } last_set[FIRST_PSEUDO_REGISTER];
7739
7740 /* The pipeline's current DFA state. */
7741 state_t dfa_state;
7742 };
7743
7744 /* Reset STATE to the initial simulation state. */
7745
7746 static void
7747 mips_sim_reset (struct mips_sim *state)
7748 {
7749 state->time = 0;
7750 state->insns_left = state->issue_rate;
7751 memset (&state->last_set, 0, sizeof (state->last_set));
7752 state_reset (state->dfa_state);
7753 }
7754
7755 /* Initialize STATE before its first use. DFA_STATE points to an
7756 allocated but uninitialized DFA state. */
7757
7758 static void
7759 mips_sim_init (struct mips_sim *state, state_t dfa_state)
7760 {
7761 state->issue_rate = mips_issue_rate ();
7762 state->dfa_state = dfa_state;
7763 mips_sim_reset (state);
7764 }
7765
7766 /* Advance STATE by one clock cycle. */
7767
7768 static void
7769 mips_sim_next_cycle (struct mips_sim *state)
7770 {
7771 state->time++;
7772 state->insns_left = state->issue_rate;
7773 state_transition (state->dfa_state, 0);
7774 }
7775
7776 /* Advance simulation state STATE until instruction INSN can read
7777 register REG. */
7778
7779 static void
7780 mips_sim_wait_reg (struct mips_sim *state, rtx insn, rtx reg)
7781 {
7782 unsigned int i;
7783
7784 for (i = 0; i < HARD_REGNO_NREGS (REGNO (reg), GET_MODE (reg)); i++)
7785 if (state->last_set[REGNO (reg) + i].insn != 0)
7786 {
7787 unsigned int t;
7788
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);
7793 }
7794 }
7795
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. */
7798
7799 static int
7800 mips_sim_wait_regs_2 (rtx *x, void *data)
7801 {
7802 if (REG_P (*x))
7803 mips_sim_wait_reg (data, mips_sim_insn, *x);
7804 return 0;
7805 }
7806
7807 /* Call mips_sim_wait_regs_2 (R, DATA) for each register R mentioned in *X. */
7808
7809 static void
7810 mips_sim_wait_regs_1 (rtx *x, void *data)
7811 {
7812 for_each_rtx (x, mips_sim_wait_regs_2, data);
7813 }
7814
7815 /* Advance simulation state STATE until all of INSN's register
7816 dependencies are satisfied. */
7817
7818 static void
7819 mips_sim_wait_regs (struct mips_sim *state, rtx insn)
7820 {
7821 mips_sim_insn = insn;
7822 note_uses (&PATTERN (insn), mips_sim_wait_regs_1, state);
7823 }
7824
7825 /* Advance simulation state STATE until the units required by
7826 instruction INSN are available. */
7827
7828 static void
7829 mips_sim_wait_units (struct mips_sim *state, rtx insn)
7830 {
7831 state_t tmp_state;
7832
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);
7838 }
7839
7840 /* Advance simulation state STATE until INSN is ready to issue. */
7841
7842 static void
7843 mips_sim_wait_insn (struct mips_sim *state, rtx insn)
7844 {
7845 mips_sim_wait_regs (state, insn);
7846 mips_sim_wait_units (state, insn);
7847 }
7848
7849 /* mips_sim_insn has just set X. Update the LAST_SET array
7850 in simulation state DATA. */
7851
7852 static void
7853 mips_sim_record_set (rtx x, rtx pat ATTRIBUTE_UNUSED, void *data)
7854 {
7855 struct mips_sim *state;
7856 unsigned int i;
7857
7858 state = data;
7859 if (REG_P (x))
7860 for (i = 0; i < HARD_REGNO_NREGS (REGNO (x), GET_MODE (x)); i++)
7861 {
7862 state->last_set[REGNO (x) + i].insn = mips_sim_insn;
7863 state->last_set[REGNO (x) + i].time = state->time;
7864 }
7865 }
7866
7867 /* Issue instruction INSN in scheduler state STATE. Assume that INSN
7868 can issue immediately (i.e., that mips_sim_wait_insn has already
7869 been called). */
7870
7871 static void
7872 mips_sim_issue_insn (struct mips_sim *state, rtx insn)
7873 {
7874 state_transition (state->dfa_state, insn);
7875 state->insns_left--;
7876
7877 mips_sim_insn = insn;
7878 note_stores (PATTERN (insn), mips_sim_record_set, state);
7879 }
7880
7881 /* Simulate issuing a NOP in state STATE. */
7882
7883 static void
7884 mips_sim_issue_nop (struct mips_sim *state)
7885 {
7886 if (state->insns_left == 0)
7887 mips_sim_next_cycle (state);
7888 state->insns_left--;
7889 }
7890
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
7893 SEQUENCE. */
7894
7895 static void
7896 mips_sim_finish_insn (struct mips_sim *state, rtx insn)
7897 {
7898 /* If INSN is a jump with an implicit delay slot, simulate a nop. */
7899 if (JUMP_P (insn))
7900 mips_sim_issue_nop (state);
7901
7902 switch (GET_CODE (SEQ_BEGIN (insn)))
7903 {
7904 case CODE_LABEL:
7905 case CALL_INSN:
7906 /* We can't predict the processor state after a call or label. */
7907 mips_sim_reset (state);
7908 break;
7909
7910 case JUMP_INSN:
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);
7920 break;
7921
7922 default:
7923 break;
7924 }
7925 }
7926 \f
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).
7933
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. */
7938
7939 static void
7940 vr4130_avoid_branch_rt_conflict (rtx insn)
7941 {
7942 rtx first, second;
7943
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)
7951 {
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)))
7959 {
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;
7964 }
7965 }
7966 }
7967
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. */
7972
7973 static void
7974 vr4130_align_insns (void)
7975 {
7976 struct mips_sim state;
7977 rtx insn, subinsn, last, last2, next;
7978 bool aligned_p;
7979
7980 dfa_start ();
7981
7982 /* LAST is the last instruction before INSN to have a nonzero length.
7983 LAST2 is the last such instruction before LAST. */
7984 last = 0;
7985 last2 = 0;
7986
7987 /* ALIGNED_P is true if INSN is known to be at an aligned address. */
7988 aligned_p = true;
7989
7990 mips_sim_init (&state, alloca (state_size ()));
7991 for (insn = get_insns (); insn != 0; insn = next)
7992 {
7993 unsigned int length;
7994
7995 next = NEXT_INSN (insn);
7996
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);
8001
8002 if (USEFUL_INSN_P (insn))
8003 FOR_EACH_SUBINSN (subinsn, insn)
8004 {
8005 mips_sim_wait_insn (&state, subinsn);
8006
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:
8011
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.
8016
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
8020 between X and Y. */
8021 if (state.insns_left != state.issue_rate
8022 && GET_CODE (subinsn) != CALL_INSN)
8023 {
8024 if (subinsn == SEQ_BEGIN (insn) && aligned_p)
8025 {
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.
8029
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
8036 delay slot. */
8037 emit_insn_after (gen_nop (), last2);
8038 aligned_p = false;
8039 }
8040 else if (subinsn != SEQ_BEGIN (insn) && !aligned_p)
8041 {
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);
8046 aligned_p = true;
8047 }
8048 }
8049 mips_sim_issue_insn (&state, subinsn);
8050 }
8051 mips_sim_finish_insn (&state, insn);
8052
8053 /* Update LAST, LAST2 and ALIGNED_P for the next instruction. */
8054 length = get_attr_length (insn);
8055 if (length > 0)
8056 {
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))
8063 {
8064 next = emit_insn_after (gen_align (GEN_INT (3)), insn);
8065 next = NEXT_INSN (next);
8066 mips_sim_next_cycle (&state);
8067 aligned_p = true;
8068 }
8069 else if (length & 4)
8070 aligned_p = !aligned_p;
8071 last2 = last;
8072 last = insn;
8073 }
8074
8075 /* See whether INSN is an aligned label. */
8076 if (LABEL_P (insn) && label_to_alignment (insn) >= 3)
8077 aligned_p = true;
8078 }
8079 dfa_finish ();
8080 }
8081 \f
8082 /* Subroutine of mips_reorg. If there is a hazard between INSN
8083 and a previous instruction, avoid it by inserting nops after
8084 instruction AFTER.
8085
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).
8091
8092 After inserting nops for INSN, update *DELAYED_REG and *HILO_DELAY
8093 for the next instruction.
8094
8095 LO_REG is an rtx for the LO register, used in dependence checking. */
8096
8097 static void
8098 mips_avoid_hazard (rtx after, rtx insn, int *hilo_delay,
8099 rtx *delayed_reg, rtx lo_reg)
8100 {
8101 rtx pattern, set;
8102 int nops, ninsns;
8103
8104 if (!INSN_P (insn))
8105 return;
8106
8107 pattern = PATTERN (insn);
8108
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;
8114
8115 /* Ignore zero-length instructions (barriers and the like). */
8116 ninsns = get_attr_length (insn) / 4;
8117 if (ninsns == 0)
8118 return;
8119
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))
8127 nops = 1;
8128 else
8129 nops = 0;
8130
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;
8134 while (nops-- > 0)
8135 emit_insn_after (gen_hazard_nop (), after);
8136
8137 /* Set up the state for the next instruction. */
8138 *hilo_delay += ninsns;
8139 *delayed_reg = 0;
8140 if (INSN_CODE (insn) >= 0)
8141 switch (get_attr_hazard (insn))
8142 {
8143 case HAZARD_NONE:
8144 break;
8145
8146 case HAZARD_HILO:
8147 *hilo_delay = 0;
8148 break;
8149
8150 case HAZARD_DELAY:
8151 set = single_set (insn);
8152 if (set == 0)
8153 abort ();
8154 *delayed_reg = SET_DEST (set);
8155 break;
8156 }
8157 }
8158
8159
8160 /* Go through the instruction stream and insert nops where necessary.
8161 See if the whole function can then be put into .set noreorder &
8162 .set nomacro. */
8163
8164 static void
8165 mips_avoid_hazards (void)
8166 {
8167 rtx insn, last_insn, lo_reg, delayed_reg;
8168 int hilo_delay, i;
8169
8170 /* Force all instructions to be split into their final form. */
8171 split_all_insns_noflow ();
8172
8173 /* Recalculate instruction lengths without taking nops into account. */
8174 cfun->machine->ignore_hazard_length_p = true;
8175 shorten_branches (get_insns ());
8176
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);
8181
8182 last_insn = 0;
8183 hilo_delay = 2;
8184 delayed_reg = 0;
8185 lo_reg = gen_rtx_REG (SImode, LO_REGNUM);
8186
8187 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
8188 if (INSN_P (insn))
8189 {
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);
8194 else
8195 mips_avoid_hazard (last_insn, insn, &hilo_delay,
8196 &delayed_reg, lo_reg);
8197
8198 last_insn = insn;
8199 }
8200 }
8201
8202
8203 /* Implement TARGET_MACHINE_DEPENDENT_REORG. */
8204
8205 static void
8206 mips_reorg (void)
8207 {
8208 if (TARGET_MIPS16)
8209 mips16_lay_out_constants ();
8210 else if (TARGET_EXPLICIT_RELOCS)
8211 {
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 ();
8217 }
8218 }
8219
8220 /* This function does three things:
8221
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. */
8225
8226 #include "config/gofast.h"
8227
8228 static void
8229 mips_init_libfuncs (void)
8230 {
8231 if (TARGET_FIX_VR4120)
8232 {
8233 set_optab_libfunc (sdiv_optab, SImode, "__vr4120_divsi3");
8234 set_optab_libfunc (smod_optab, SImode, "__vr4120_modsi3");
8235 }
8236
8237 if (TARGET_MIPS16 && mips16_hard_float)
8238 {
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");
8243
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");
8250
8251 set_conv_libfunc (sfix_optab, SImode, SFmode, "__mips16_fix_truncsfsi");
8252 set_conv_libfunc (sfloat_optab, SFmode, SImode, "__mips16_floatsisf");
8253
8254 if (TARGET_DOUBLE_FLOAT)
8255 {
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");
8260
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");
8267
8268 set_conv_libfunc (sext_optab, DFmode, SFmode, "__mips16_extendsfdf2");
8269 set_conv_libfunc (trunc_optab, SFmode, DFmode, "__mips16_truncdfsf2");
8270
8271 set_conv_libfunc (sfix_optab, SImode, DFmode, "__mips16_fix_truncdfsi");
8272 set_conv_libfunc (sfloat_optab, DFmode, SImode, "__mips16_floatsidf");
8273 }
8274 }
8275 else
8276 gofast_maybe_init_libfuncs ();
8277 }
8278
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.
8283
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.
8287
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
8294 such copying.
8295
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. */
8309
8310 int
8311 mips_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
8312 enum reg_class to, enum reg_class from)
8313 {
8314 if (from == M16_REGS && GR_REG_CLASS_P (to))
8315 return 2;
8316 else if (from == M16_NA_REGS && GR_REG_CLASS_P (to))
8317 return 2;
8318 else if (GR_REG_CLASS_P (from))
8319 {
8320 if (to == M16_REGS)
8321 return 2;
8322 else if (to == M16_NA_REGS)
8323 return 2;
8324 else if (GR_REG_CLASS_P (to))
8325 {
8326 if (TARGET_MIPS16)
8327 return 4;
8328 else
8329 return 2;
8330 }
8331 else if (to == FP_REGS)
8332 return 4;
8333 else if (to == HI_REG || to == LO_REG || to == MD_REGS)
8334 {
8335 if (TARGET_MIPS16)
8336 return 12;
8337 else
8338 return 6;
8339 }
8340 else if (COP_REG_CLASS_P (to))
8341 {
8342 return 5;
8343 }
8344 } /* GR_REG_CLASS_P (from) */
8345 else if (from == FP_REGS)
8346 {
8347 if (GR_REG_CLASS_P (to))
8348 return 4;
8349 else if (to == FP_REGS)
8350 return 2;
8351 else if (to == ST_REGS)
8352 return 8;
8353 } /* from == FP_REGS */
8354 else if (from == HI_REG || from == LO_REG || from == MD_REGS)
8355 {
8356 if (GR_REG_CLASS_P (to))
8357 {
8358 if (TARGET_MIPS16)
8359 return 12;
8360 else
8361 return 6;
8362 }
8363 } /* from == HI_REG, etc. */
8364 else if (from == ST_REGS && GR_REG_CLASS_P (to))
8365 return 4;
8366 else if (COP_REG_CLASS_P (from))
8367 {
8368 return 5;
8369 } /* COP_REG_CLASS_P (from) */
8370
8371 /* Fall through. */
8372
8373 return 12;
8374 }
8375
8376 /* Return the length of INSN. LENGTH is the initial length computed by
8377 attributes in the machine-description file. */
8378
8379 int
8380 mips_adjust_insn_length (rtx insn, int length)
8381 {
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)))
8386 length += 4;
8387
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))
8391 {
8392 case HAZARD_NONE:
8393 break;
8394
8395 case HAZARD_DELAY:
8396 length += 4;
8397 break;
8398
8399 case HAZARD_HILO:
8400 length += 8;
8401 break;
8402 }
8403
8404 /* All MIPS16 instructions are a measly two bytes. */
8405 if (TARGET_MIPS16)
8406 length /= 2;
8407
8408 return length;
8409 }
8410
8411
8412 /* Return an asm sequence to start a noat block and load the address
8413 of a label into $1. */
8414
8415 const char *
8416 mips_output_load_label (void)
8417 {
8418 if (TARGET_EXPLICIT_RELOCS)
8419 switch (mips_abi)
8420 {
8421 case ABI_N32:
8422 return "%[lw\t%@,%%got_page(%0)(%+)\n\taddiu\t%@,%@,%%got_ofst(%0)";
8423
8424 case ABI_64:
8425 return "%[ld\t%@,%%got_page(%0)(%+)\n\tdaddiu\t%@,%@,%%got_ofst(%0)";
8426
8427 default:
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)";
8431 }
8432 else
8433 {
8434 if (Pmode == DImode)
8435 return "%[dla\t%@,%0";
8436 else
8437 return "%[la\t%@,%0";
8438 }
8439 }
8440
8441
8442 /* Output assembly instructions to peform a conditional branch.
8443
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
8448 second operand.
8449
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.
8452
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. */
8456 const char *
8457 mips_output_conditional_branch (rtx insn, rtx *operands, int two_operands_p,
8458 int float_p, int inverted_p, int length)
8459 {
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. */
8465 int need_z_p;
8466 /* A string to use in the assembly output to represent the first
8467 operand. */
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
8471 operand. */
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");
8477
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
8481 taken. */
8482 mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
8483
8484 if (!two_operands_p)
8485 {
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. */
8492 switch (code)
8493 {
8494 case GTU:
8495 code = NE;
8496 break;
8497
8498 case LEU:
8499 code = EQ;
8500 break;
8501
8502 case GEU:
8503 /* A condition which will always be true. */
8504 code = EQ;
8505 op1 = "%.";
8506 break;
8507
8508 case LTU:
8509 /* A condition which will always be false. */
8510 code = NE;
8511 op1 = "%.";
8512 break;
8513
8514 default:
8515 /* Not a special case. */
8516 break;
8517 }
8518 }
8519
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
8525 explicitly. */
8526 if (need_z_p)
8527 op2 = "";
8528
8529 /* Begin by terminating the buffer. That way we can always use
8530 strcat to add to it. */
8531 buffer[0] = '\0';
8532
8533 switch (length)
8534 {
8535 case 4:
8536 case 8:
8537 /* Just a simple conditional branch. */
8538 if (float_p)
8539 sprintf (buffer, "%%*b%s%%?\t%%Z2%%1%%/",
8540 inverted_p ? inverted_comp : comp);
8541 else
8542 sprintf (buffer, "%%*b%s%s%%?\t%s%s,%%1%%/",
8543 inverted_p ? inverted_comp : comp,
8544 need_z_p ? "z" : "",
8545 op1,
8546 op2);
8547 return buffer;
8548
8549 case 12:
8550 case 16:
8551 case 24:
8552 case 28:
8553 {
8554 /* Generate a reversed conditional branch around ` j'
8555 instruction:
8556
8557 .set noreorder
8558 .set nomacro
8559 bc l
8560 delay_slot or #nop
8561 j target
8562 #nop
8563 l:
8564 .set macro
8565 .set reorder
8566
8567 If the original branch was a likely branch, the delay slot
8568 must be executed only if the branch is taken, so generate:
8569
8570 .set noreorder
8571 .set nomacro
8572 bc l
8573 #nop
8574 j target
8575 delay slot or #nop
8576 l:
8577 .set macro
8578 .set reorder
8579
8580 When generating PIC, instead of:
8581
8582 j target
8583
8584 we emit:
8585
8586 .set noat
8587 la $at, target
8588 jr $at
8589 .set at
8590 */
8591
8592 rtx orig_target;
8593 rtx target = gen_label_rtx ();
8594
8595 orig_target = operands[1];
8596 operands[1] = target;
8597 /* Generate the reversed comparison. This takes four
8598 bytes. */
8599 if (float_p)
8600 sprintf (buffer, "%%*b%s\t%%Z2%%1",
8601 inverted_p ? comp : inverted_comp);
8602 else
8603 sprintf (buffer, "%%*b%s%s\t%s%s,%%1",
8604 inverted_p ? comp : inverted_comp,
8605 need_z_p ? "z" : "",
8606 op1,
8607 op2);
8608 output_asm_insn (buffer, operands);
8609
8610 if (length != 16 && length != 28 && ! mips_branch_likely)
8611 {
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;
8617 }
8618 else
8619 output_asm_insn ("%#", 0);
8620
8621 if (length <= 16)
8622 output_asm_insn ("j\t%0", &orig_target);
8623 else
8624 {
8625 output_asm_insn (mips_output_load_label (), &orig_target);
8626 output_asm_insn ("jr\t%@%]", 0);
8627 }
8628
8629 if (length != 16 && length != 28 && mips_branch_likely)
8630 {
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;
8636 }
8637 else
8638 output_asm_insn ("%#", 0);
8639
8640 (*targetm.asm_out.internal_label) (asm_out_file, "L",
8641 CODE_LABEL_NUMBER (target));
8642
8643 return "";
8644 }
8645
8646 default:
8647 abort ();
8648 }
8649
8650 /* NOTREACHED */
8651 return 0;
8652 }
8653 \f
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.
8656
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.
8663
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.
8669
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":
8673
8674 "19. In this following sequence:
8675
8676 ddiv (or ddivu or div or divu)
8677 dsll32 (or dsrl32, dsra32)
8678
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
8681 incorrect result.
8682
8683 Workaround: The compiler needs to avoid generating any
8684 sequence with divide followed by extended double shift."
8685
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.
8689
8690 [3] From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
8691 (also valid for MIPS R4000MC processors):
8692
8693 "52. R4000SC: This bug does not apply for the R4000PC.
8694
8695 There are two flavors of this bug:
8696
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.
8703
8704 ##1
8705 nop
8706 div r8, r9
8707 ------------------- # end-of page. -tlb-refill
8708 nop
8709 ##2
8710 nop
8711 div r8, r9
8712 ------------------- # end-of page. -tlb-invalid
8713 nop
8714
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.
8720
8721 ##1
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
8726
8727 ##2
8728 beq r0, r0, NextPage # to Next page
8729 div r8,r9
8730 nop
8731
8732 This bug is present for div, divu, ddiv, and ddivu
8733 instructions.
8734
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."
8739
8740 These processors have PRId values of 0x00004220 and 0x00004300 for
8741 the R4000 and 0x00004400, 0x00004500 and 0x00004600 for the R4400. */
8742
8743 const char *
8744 mips_output_division (const char *division, rtx *operands)
8745 {
8746 const char *s;
8747
8748 s = division;
8749 if (TARGET_FIX_R4000 || TARGET_FIX_R4400)
8750 {
8751 output_asm_insn (s, operands);
8752 s = "nop";
8753 }
8754 if (TARGET_CHECK_ZERO_DIV)
8755 {
8756 if (TARGET_MIPS16)
8757 {
8758 output_asm_insn (s, operands);
8759 s = "bnez\t%2,1f\n\tbreak\t7\n1:";
8760 }
8761 else
8762 {
8763 output_asm_insn ("%(bne\t%2,%.,1f", operands);
8764 output_asm_insn (s, operands);
8765 s = "break\t7%)\n1:";
8766 }
8767 }
8768 return s;
8769 }
8770 \f
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.
8773
8774 Note: this function is shared between GCC and GAS. */
8775
8776 static bool
8777 mips_strict_matching_cpu_name_p (const char *canonical, const char *given)
8778 {
8779 while (*given != 0 && TOLOWER (*given) == TOLOWER (*canonical))
8780 given++, canonical++;
8781
8782 return ((*given == 0 && *canonical == 0)
8783 || (strcmp (canonical, "000") == 0 && strcasecmp (given, "k") == 0));
8784 }
8785
8786
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.
8789
8790 Note: this function is shared between GCC and GAS. */
8791
8792 static bool
8793 mips_matching_cpu_name_p (const char *canonical, const char *given)
8794 {
8795 /* First see if the name matches exactly, or with a final "000"
8796 turned into "k". */
8797 if (mips_strict_matching_cpu_name_p (canonical, given))
8798 return true;
8799
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')
8803 given++;
8804 if (!ISDIGIT (*given))
8805 return false;
8806
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')
8810 canonical += 2;
8811 else if (TOLOWER (canonical[0]) == 'r' && TOLOWER (canonical[1]) == 'm')
8812 canonical += 2;
8813 else if (TOLOWER (canonical[0]) == 'r')
8814 canonical += 1;
8815
8816 return mips_strict_matching_cpu_name_p (canonical, given);
8817 }
8818
8819
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.
8824
8825 A similar function exists in GAS. */
8826
8827 static const struct mips_cpu_info *
8828 mips_parse_cpu (const char *option, const char *cpu_string)
8829 {
8830 const struct mips_cpu_info *p;
8831 const char *s;
8832
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++)
8836 if (ISUPPER (*s))
8837 {
8838 warning ("the cpu name must be lower case");
8839 break;
8840 }
8841
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));
8851
8852 /* 'default' has traditionally been a no-op. Probably not very useful. */
8853 if (strcasecmp (cpu_string, "default") == 0)
8854 return 0;
8855
8856 for (p = mips_cpu_info_table; p->name != 0; p++)
8857 if (mips_matching_cpu_name_p (p->name, cpu_string))
8858 return p;
8859
8860 error ("bad value (%s) for %s", cpu_string, option);
8861 return 0;
8862 }
8863
8864
8865 /* Return the processor associated with the given ISA level, or null
8866 if the ISA isn't valid. */
8867
8868 static const struct mips_cpu_info *
8869 mips_cpu_info_from_isa (int isa)
8870 {
8871 const struct mips_cpu_info *p;
8872
8873 for (p = mips_cpu_info_table; p->name != 0; p++)
8874 if (p->isa == isa)
8875 return p;
8876
8877 return 0;
8878 }
8879 \f
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. */
8884
8885 unsigned int
8886 mips_hard_regno_nregs (int regno, enum machine_mode mode)
8887 {
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);
8892 else
8893 return ((GET_MODE_SIZE (mode) + UNITS_PER_FPREG - 1) / UNITS_PER_FPREG);
8894 }
8895
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
8900 course. */
8901
8902 static bool
8903 mips_return_in_memory (tree type, tree fndecl ATTRIBUTE_UNUSED)
8904 {
8905 if (TARGET_OLDABI)
8906 return (TYPE_MODE (type) == BLKmode);
8907 else
8908 return ((int_size_in_bytes (type) > (2 * UNITS_PER_WORD))
8909 || (int_size_in_bytes (type) == -1));
8910 }
8911
8912 static bool
8913 mips_strict_argument_naming (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED)
8914 {
8915 return !TARGET_OLDABI;
8916 }
8917 \f
8918 /* Return true if INSN is a multiply-add or multiply-subtract
8919 instruction and PREV assigns to the accumulator operand. */
8920
8921 bool
8922 mips_linked_madd_p (rtx prev, rtx insn)
8923 {
8924 rtx x;
8925
8926 x = single_set (insn);
8927 if (x == 0)
8928 return false;
8929
8930 x = SET_SRC (x);
8931
8932 if (GET_CODE (x) == PLUS
8933 && GET_CODE (XEXP (x, 0)) == MULT
8934 && reg_set_p (XEXP (x, 1), prev))
8935 return true;
8936
8937 if (GET_CODE (x) == MINUS
8938 && GET_CODE (XEXP (x, 1)) == MULT
8939 && reg_set_p (XEXP (x, 0), prev))
8940 return true;
8941
8942 return false;
8943 }
8944 \f
8945 /* Used by TUNE_MACC_CHAINS to record the last scheduled instruction
8946 that may clobber hi or lo. */
8947
8948 static rtx mips_macc_chains_last_hilo;
8949
8950 /* A TUNE_MACC_CHAINS helper function. Record that instruction INSN has
8951 been scheduled, updating mips_macc_chains_last_hilo appropriately. */
8952
8953 static void
8954 mips_macc_chains_record (rtx insn)
8955 {
8956 if (get_attr_may_clobber_hilo (insn))
8957 mips_macc_chains_last_hilo = insn;
8958 }
8959
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. */
8965
8966 static void
8967 mips_macc_chains_reorder (rtx *ready, int nready)
8968 {
8969 int i, j;
8970
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]))
8974 {
8975 for (j = nready - 1; j > i; j--)
8976 if (recog_memoized (ready[j]) >= 0
8977 && get_attr_may_clobber_hilo (ready[j]))
8978 {
8979 mips_promote_ready (ready, i, j);
8980 break;
8981 }
8982 break;
8983 }
8984 }
8985 \f
8986 /* The last instruction to be scheduled. */
8987
8988 static rtx vr4130_last_insn;
8989
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. */
8993
8994 static void
8995 vr4130_true_reg_dependence_p_1 (rtx x, rtx pat ATTRIBUTE_UNUSED, void *data)
8996 {
8997 rtx *insn_ptr = data;
8998 if (REG_P (x)
8999 && *insn_ptr != 0
9000 && reg_referenced_p (x, PATTERN (*insn_ptr)))
9001 *insn_ptr = 0;
9002 }
9003
9004 /* Return true if there is true register dependence between vr4130_last_insn
9005 and INSN. */
9006
9007 static bool
9008 vr4130_true_reg_dependence_p (rtx insn)
9009 {
9010 note_stores (PATTERN (vr4130_last_insn),
9011 vr4130_true_reg_dependence_p_1, &insn);
9012 return insn == 0;
9013 }
9014
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. */
9021
9022 static bool
9023 vr4130_swap_insns_p (rtx insn1, rtx insn2)
9024 {
9025 rtx dep;
9026
9027 /* Check for the following case:
9028
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).
9032
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)
9040 return false;
9041
9042 if (vr4130_last_insn != 0
9043 && recog_memoized (insn1) >= 0
9044 && recog_memoized (insn2) >= 0)
9045 {
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)
9052 {
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);
9057 if (dep1 != dep2)
9058 return dep1;
9059
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))
9067 return true;
9068 }
9069 }
9070 return false;
9071 }
9072
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. */
9076
9077 static void
9078 vr4130_reorder (rtx *ready, int nready)
9079 {
9080 if (vr4130_swap_insns_p (ready[nready - 1], ready[nready - 2]))
9081 mips_promote_ready (ready, nready - 2, nready - 1);
9082 }
9083 \f
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
9086 be <= HIGHER. */
9087
9088 static void
9089 mips_promote_ready (rtx *ready, int lower, int higher)
9090 {
9091 rtx new_head;
9092 int i;
9093
9094 new_head = ready[lower];
9095 for (i = lower; i < higher; i++)
9096 ready[i] = ready[i + 1];
9097 ready[i] = new_head;
9098 }
9099
9100 /* Implement TARGET_SCHED_REORDER. */
9101
9102 static int
9103 mips_sched_reorder (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
9104 rtx *ready, int *nreadyp, int cycle)
9105 {
9106 if (!reload_completed && TUNE_MACC_CHAINS)
9107 {
9108 if (cycle == 0)
9109 mips_macc_chains_last_hilo = 0;
9110 if (*nreadyp > 0)
9111 mips_macc_chains_reorder (ready, *nreadyp);
9112 }
9113 if (reload_completed && TUNE_MIPS4130 && !TARGET_VR4130_ALIGN)
9114 {
9115 if (cycle == 0)
9116 vr4130_last_insn = 0;
9117 if (*nreadyp > 1)
9118 vr4130_reorder (ready, *nreadyp);
9119 }
9120 return mips_issue_rate ();
9121 }
9122
9123 /* Implement TARGET_SCHED_VARIABLE_ISSUE. */
9124
9125 static int
9126 mips_variable_issue (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
9127 rtx insn, int more)
9128 {
9129 switch (GET_CODE (PATTERN (insn)))
9130 {
9131 case USE:
9132 case CLOBBER:
9133 /* Don't count USEs and CLOBBERs against the issue rate. */
9134 break;
9135
9136 default:
9137 more--;
9138 if (!reload_completed && TUNE_MACC_CHAINS)
9139 mips_macc_chains_record (insn);
9140 vr4130_last_insn = insn;
9141 break;
9142 }
9143 return more;
9144 }
9145 \f
9146 /* Implement TARGET_SCHED_ADJUST_COST. We assume that anti and output
9147 dependencies have no cost. */
9148
9149 static int
9150 mips_adjust_cost (rtx insn ATTRIBUTE_UNUSED, rtx link,
9151 rtx dep ATTRIBUTE_UNUSED, int cost)
9152 {
9153 if (REG_NOTE_KIND (link) != 0)
9154 return 0;
9155 return cost;
9156 }
9157
9158 /* Return the number of instructions that can be issued per cycle. */
9159
9160 static int
9161 mips_issue_rate (void)
9162 {
9163 switch (mips_tune)
9164 {
9165 case PROCESSOR_R4130:
9166 case PROCESSOR_R5400:
9167 case PROCESSOR_R5500:
9168 case PROCESSOR_R7000:
9169 case PROCESSOR_R9000:
9170 return 2;
9171
9172 case PROCESSOR_SB1:
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. */
9177 return 3;
9178
9179 default:
9180 return 1;
9181 }
9182
9183 abort ();
9184
9185 }
9186
9187 /* Implements TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD. This should
9188 be as wide as the scheduling freedom in the DFA. */
9189
9190 static int
9191 mips_multipass_dfa_lookahead (void)
9192 {
9193 /* Can schedule up to 4 of the 6 function units in any one cycle. */
9194 if (mips_tune == PROCESSOR_SB1)
9195 return 4;
9196
9197 return 0;
9198 }
9199 \f
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. */
9202
9203 rtx
9204 mips_prefetch_cookie (rtx write, rtx locality)
9205 {
9206 /* store_streamed / load_streamed. */
9207 if (INTVAL (locality) <= 0)
9208 return GEN_INT (INTVAL (write) + 4);
9209
9210 /* store / load. */
9211 if (INTVAL (locality) <= 2)
9212 return write;
9213
9214 /* store_retained / load_retained. */
9215 return GEN_INT (INTVAL (write) + 6);
9216 }
9217 \f
9218 /* MIPS builtin function support. */
9219
9220 struct builtin_description
9221 {
9222 /* Instruction code. */
9223 enum insn_code icode;
9224 /* Builtin function name. */
9225 const char *name;
9226 /* Builtin code. */
9227 enum mips_builtins code;
9228 /* Function type. */
9229 enum mips_function_type ftype;
9230 /* The target flag required for this builtin function. */
9231 int target_flags;
9232 };
9233
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[] =
9237 {
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 },
9256
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 },
9265
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 },
9278
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 },
9291
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 },
9440
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 },
9569
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,
9576 MASK_MIPS3D },
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,
9579 MASK_MIPS3D },
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,
9582 MASK_MIPS3D },
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,
9585 MASK_MIPS3D },
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,
9588 MASK_MIPS3D },
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,
9591 MASK_MIPS3D },
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,
9594 MASK_MIPS3D },
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,
9597 MASK_MIPS3D },
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,
9600 MASK_MIPS3D },
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,
9603 MASK_MIPS3D },
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,
9606 MASK_MIPS3D },
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,
9609 MASK_MIPS3D },
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,
9612 MASK_MIPS3D },
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,
9615 MASK_MIPS3D },
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,
9618 MASK_MIPS3D },
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,
9621 MASK_MIPS3D },
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,
9624 MASK_MIPS3D },
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,
9627 MASK_MIPS3D },
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,
9630 MASK_MIPS3D },
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,
9633 MASK_MIPS3D },
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,
9636 MASK_MIPS3D },
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,
9639 MASK_MIPS3D },
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,
9642 MASK_MIPS3D },
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,
9645 MASK_MIPS3D },
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,
9648 MASK_MIPS3D },
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,
9651 MASK_MIPS3D },
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,
9654 MASK_MIPS3D },
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,
9657 MASK_MIPS3D },
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,
9660 MASK_MIPS3D },
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,
9663 MASK_MIPS3D },
9664
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,
9667 MASK_MIPS3D },
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,
9670 MASK_MIPS3D },
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,
9673 MASK_MIPS3D },
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,
9676 MASK_MIPS3D },
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,
9679 MASK_MIPS3D },
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,
9682 MASK_MIPS3D },
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,
9685 MASK_MIPS3D },
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,
9688 MASK_MIPS3D },
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,
9691 MASK_MIPS3D },
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,
9694 MASK_MIPS3D },
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,
9697 MASK_MIPS3D },
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,
9700 MASK_MIPS3D },
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,
9703 MASK_MIPS3D },
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,
9706 MASK_MIPS3D },
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,
9709 MASK_MIPS3D },
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,
9712 MASK_MIPS3D },
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,
9715 MASK_MIPS3D },
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,
9718 MASK_MIPS3D },
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,
9721 MASK_MIPS3D },
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,
9724 MASK_MIPS3D },
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,
9727 MASK_MIPS3D },
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,
9730 MASK_MIPS3D },
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,
9733 MASK_MIPS3D },
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,
9736 MASK_MIPS3D },
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,
9739 MASK_MIPS3D },
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,
9742 MASK_MIPS3D },
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,
9745 MASK_MIPS3D },
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,
9748 MASK_MIPS3D },
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,
9751 MASK_MIPS3D },
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,
9754 MASK_MIPS3D },
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,
9757 MASK_MIPS3D },
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,
9760 MASK_MIPS3D },
9761
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 },
9826
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,
9877 MASK_MIPS3D },
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,
9880 MASK_MIPS3D },
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,
9883 MASK_MIPS3D },
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,
9886 MASK_MIPS3D },
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,
9889 MASK_MIPS3D },
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,
9892 MASK_MIPS3D },
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,
9895 MASK_MIPS3D },
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,
9898 MASK_MIPS3D },
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,
9901 MASK_MIPS3D },
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,
9904 MASK_MIPS3D },
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,
9907 MASK_MIPS3D },
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,
9910 MASK_MIPS3D },
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,
9913 MASK_MIPS3D },
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,
9916 MASK_MIPS3D },
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,
9919 MASK_MIPS3D },
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,
9922 MASK_MIPS3D },
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,
9973 MASK_MIPS3D },
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,
9976 MASK_MIPS3D },
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,
9979 MASK_MIPS3D },
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,
9982 MASK_MIPS3D },
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,
9985 MASK_MIPS3D },
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,
9988 MASK_MIPS3D },
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,
9991 MASK_MIPS3D },
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,
9994 MASK_MIPS3D },
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,
9997 MASK_MIPS3D },
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,
10000 MASK_MIPS3D },
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,
10003 MASK_MIPS3D },
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,
10006 MASK_MIPS3D },
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,
10009 MASK_MIPS3D },
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,
10012 MASK_MIPS3D },
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,
10015 MASK_MIPS3D },
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,
10018 MASK_MIPS3D },
10019
10020 };
10021
10022
10023 /* Expand builtin functions. This is called from TARGET_EXPAND_BUILTIN. */
10024
10025 rtx
10026 mips_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
10027 enum machine_mode mode ATTRIBUTE_UNUSED,
10028 int ignore ATTRIBUTE_UNUSED)
10029 {
10030 rtx pat;
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);
10035 tree arg0;
10036 tree arg1;
10037 tree arg2;
10038 enum machine_mode tmode;
10039 enum machine_mode mode0;
10040 enum machine_mode mode1;
10041 enum machine_mode mode2;
10042 rtx op0;
10043 rtx op1;
10044 rtx op2;
10045
10046 switch (fcode)
10047 {
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:
10062
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;
10071
10072 if (target == 0
10073 || GET_MODE (target) != tmode
10074 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
10075 target = gen_reg_rtx (tmode);
10076
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);
10081
10082 pat = GEN_FCN (icode) (target, op0, op1);
10083 if (!pat)
10084 return 0;
10085
10086 emit_insn (pat);
10087 return target;
10088
10089 /* One Operand. */
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:
10101
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;
10107
10108 if (target == 0
10109 || GET_MODE (target) != tmode
10110 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
10111 target = gen_reg_rtx (tmode);
10112
10113 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
10114 op0 = copy_to_mode_reg (mode0, op0);
10115
10116 pat = GEN_FCN (icode) (target, op0);
10117 if (!pat)
10118 return 0;
10119
10120 emit_insn (pat);
10121 return target;
10122
10123 /* Three Operands. */
10124 case MIPS_BUILTIN_ALNV_PS:
10125
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;
10137
10138 if (target == 0
10139 || GET_MODE (target) != tmode
10140 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
10141 target = gen_reg_rtx (tmode);
10142
10143 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
10144 op0 = copy_to_mode_reg (mode0, op0);
10145
10146 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
10147 op1 = copy_to_mode_reg (mode1, op1);
10148
10149 if (!(*insn_data[icode].operand[3].predicate) (op2, mode2))
10150 op2 = copy_to_mode_reg (mode2, op2);
10151
10152 pat = GEN_FCN (icode) (target, op0, op1, op2);
10153 if (!pat)
10154 return 0;
10155
10156 emit_insn (pat);
10157 return target;
10158
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,
10193 fcode, arglist);
10194
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,
10229 fcode, arglist);
10230
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,
10265 fcode, arglist);
10266
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,
10301 fcode, arglist);
10302
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,
10337 fcode, arglist);
10338
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,
10373 fcode, arglist);
10374
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);
10409
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,
10444 fcode, arglist);
10445
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,
10480 fcode, arglist);
10481
10482 default:
10483 break;
10484 }
10485
10486 return 0;
10487 }
10488
10489 /* Init builtin functions. This is called from TARGET_INIT_BUILTIN. */
10490
10491 void
10492 mips_init_builtins (void)
10493 {
10494 const struct builtin_description *d;
10495 size_t i;
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;
10505 tree sf_ftype_sf;
10506 tree df_ftype_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);
10511
10512 /* We have only builtins for -mpaired-single and -mips3d. */
10513 if (!TARGET_PAIRED_SINGLE_FLOAT)
10514 return;
10515
10516 int_ftype_sf_sf
10517 = build_function_type_list (integer_type_node,
10518 float_type_node, float_type_node,
10519 NULL_TREE);
10520
10521 int_ftype_df_df
10522 = build_function_type_list (integer_type_node,
10523 double_type_node, double_type_node,
10524 NULL_TREE);
10525
10526 v2sf_ftype_v2sf_v2sf
10527 = build_function_type_list (V2SF_type_node,
10528 V2SF_type_node, V2SF_type_node, NULL_TREE);
10529
10530 v2sf_ftype_sf_sf
10531 = build_function_type_list (V2SF_type_node,
10532 float_type_node, float_type_node,
10533 NULL_TREE);
10534
10535 sf_ftype_v2sf
10536 = build_function_type_list (float_type_node, V2SF_type_node, NULL_TREE);
10537
10538 v2sf_ftype_v2sf
10539 = build_function_type_list (V2SF_type_node, V2SF_type_node, NULL_TREE);
10540
10541 int_ftype_v2sf_v2sf
10542 = build_function_type_list (integer_type_node,
10543 V2SF_type_node, V2SF_type_node, NULL_TREE);
10544
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);
10549
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);
10554
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);
10559
10560 sf_ftype_sf
10561 = build_function_type_list (float_type_node,
10562 float_type_node, NULL_TREE);
10563
10564 df_ftype_df
10565 = build_function_type_list (double_type_node,
10566 double_type_node, NULL_TREE);
10567
10568 sf_ftype_sf_sf
10569 = build_function_type_list (float_type_node,
10570 float_type_node, float_type_node,
10571 NULL_TREE);
10572
10573 df_ftype_df_df
10574 = build_function_type_list (double_type_node,
10575 double_type_node, double_type_node,
10576 NULL_TREE);
10577
10578 for (i = 0, d = mips_bdesc; i < ARRAY_SIZE (mips_bdesc); i++, d++)
10579 {
10580 if ((d->target_flags & MASK_PAIRED_SINGLE)
10581 && !TARGET_PAIRED_SINGLE_FLOAT)
10582 continue;
10583
10584 if ((d->target_flags & MASK_MIPS3D)
10585 && !TARGET_MIPS3D)
10586 continue;
10587
10588 switch (d->ftype)
10589 {
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);
10593 break;
10594
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);
10598 break;
10599
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);
10603 break;
10604
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);
10608 break;
10609
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);
10613 break;
10614
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);
10618 break;
10619
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);
10623 break;
10624
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);
10628 break;
10629
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);
10633 break;
10634
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);
10638 break;
10639
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);
10643 break;
10644
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);
10648 break;
10649
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);
10653 break;
10654
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);
10658 break;
10659
10660 default:
10661 break;
10662 }
10663 }
10664 }
10665
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. */
10671
10672 static rtx
10673 mips_expand_ps_cond_move_builtin (enum mips_cmp_choice cmp_choice,
10674 rtx target, unsigned int fcode,
10675 tree arglist)
10676 {
10677 rtx pat;
10678 enum insn_code icode;
10679 tree arg0;
10680 tree arg1;
10681 tree arg2;
10682 tree arg3;
10683 rtx op0;
10684 rtx op1;
10685 rtx op2;
10686 rtx op3;
10687 enum machine_mode tmode;
10688 enum machine_mode mode0;
10689 enum machine_mode mode1;
10690 rtx temp_target;
10691 rtx src1;
10692 rtx src2;
10693 enum rtx_code test_code;
10694 int compare_value;
10695
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);
10704
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;
10709
10710 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
10711 op0 = copy_to_mode_reg (mode0, op0);
10712
10713 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
10714 op1 = copy_to_mode_reg (mode1, op1);
10715
10716 /* temp_target is the result of the comparison. */
10717 temp_target = gen_reg_rtx (tmode);
10718
10719 pat = GEN_FCN (icode) (temp_target, op0, op1);
10720 if (!pat)
10721 return 0;
10722
10723 emit_insn (pat);
10724
10725 icode = CODE_FOR_mips_cond_move_tf_ps;
10726 tmode = insn_data[icode].operand[0].mode;
10727
10728 if (target == 0
10729 || GET_MODE (target) != tmode
10730 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
10731 target = gen_reg_rtx (tmode);
10732
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);
10736
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);
10740
10741 /* Copy op2 to target */
10742 emit_insn (gen_rtx_SET (tmode, target, op2));
10743
10744 test_code = EQ;
10745 compare_value = 0;
10746 switch (cmp_choice)
10747 {
10748 case MIPS_CMP_MOVT:
10749 src1 = op3;
10750 src2 = target;
10751 break;
10752
10753 case MIPS_CMP_MOVF:
10754 src1 = target;
10755 src2 = op3;
10756 break;
10757
10758 default:
10759 return 0;
10760 }
10761
10762 emit_insn (gen_mips_cond_move_tf_ps (target, src1, src2, temp_target));
10763
10764 return target;
10765 }
10766
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. */
10772
10773 rtx
10774 mips_expand_4s_compare_builtin (enum mips_cmp_choice cmp_choice, rtx target,
10775 unsigned int fcode, tree arglist)
10776 {
10777 rtx pat;
10778 enum insn_code icode;
10779 tree arg0;
10780 tree arg1;
10781 tree arg2;
10782 tree arg3;
10783 rtx op0;
10784 rtx op1;
10785 rtx op2;
10786 rtx op3;
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;
10792 rtx temp_target;
10793 rtx label1;
10794 rtx label2;
10795 rtx if_then_else;
10796 enum rtx_code test_code;
10797 int compare_value;
10798
10799 if (target == 0 || GET_MODE (target) != SImode)
10800 target = gen_reg_rtx (SImode);
10801
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;
10816
10817 temp_target = gen_reg_rtx (tmode);
10818
10819 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
10820 op0 = copy_to_mode_reg (mode0, op0);
10821
10822 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
10823 op1 = copy_to_mode_reg (mode1, op1);
10824
10825 if (!(*insn_data[icode].operand[3].predicate) (op2, mode2))
10826 op2 = copy_to_mode_reg (mode2, op2);
10827
10828 if (!(*insn_data[icode].operand[4].predicate) (op3, mode3))
10829 op3 = copy_to_mode_reg (mode3, op3);
10830
10831 pat = GEN_FCN (icode) (temp_target, op0, op1, op2, op3);
10832 if (!pat)
10833 return 0;
10834
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
10838
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)
10842
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)
10847 {
10848 case MIPS_CMP_ANY:
10849 test_code = EQ;
10850 compare_value = 0;
10851 break;
10852
10853 case MIPS_CMP_ALL:
10854 test_code = NE;
10855 compare_value = 1;
10856 break;
10857
10858 default:
10859 return 0;
10860 }
10861
10862 if (cmp_choice == MIPS_CMP_ALL)
10863 emit_move_insn (target, const1_rtx);
10864 else
10865 emit_move_insn (target, const0_rtx);
10866
10867 emit_insn (pat);
10868
10869 label1 = gen_label_rtx ();
10870 label2 = gen_label_rtx ();
10871 if_then_else
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);
10876
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)));
10880
10881 emit_barrier ();
10882 emit_label (label1);
10883
10884 if (cmp_choice == MIPS_CMP_ALL)
10885 emit_move_insn (target, const0_rtx);
10886 else
10887 emit_move_insn (target, const1_rtx);
10888
10889 emit_label (label2);
10890
10891 return target;
10892 }
10893
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
10897 compare. */
10898
10899 rtx
10900 mips_expand_compare_builtin (rtx target, unsigned int fcode, tree arglist)
10901 {
10902 rtx pat;
10903 enum insn_code icode;
10904 tree arg0;
10905 tree arg1;
10906 rtx op0;
10907 rtx op1;
10908 enum machine_mode tmode;
10909 enum machine_mode mode0;
10910 enum machine_mode mode1;
10911 rtx temp_target;
10912 rtx label1;
10913 rtx label2;
10914 rtx if_then_else;
10915 enum rtx_code test_code;
10916
10917 if (target == 0 || GET_MODE (target) != SImode)
10918 target = gen_reg_rtx (SImode);
10919
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;
10928
10929 temp_target = gen_reg_rtx (tmode);
10930
10931 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
10932 op0 = copy_to_mode_reg (mode0, op0);
10933
10934 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
10935 op1 = copy_to_mode_reg (mode1, op1);
10936
10937 pat = GEN_FCN (icode) (temp_target, op0, op1);
10938 if (!pat)
10939 return 0;
10940
10941 emit_move_insn (target, const0_rtx);
10942 emit_insn (pat);
10943
10944 label1 = gen_label_rtx ();
10945 label2 = gen_label_rtx ();
10946
10947 test_code = NE;
10948 if_then_else
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);
10953
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)));
10957
10958 emit_barrier ();
10959 emit_label (label1);
10960 emit_move_insn (target, const1_rtx);
10961 emit_label (label2);
10962
10963 return target;
10964 }
10965
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. */
10971
10972 rtx
10973 mips_expand_ps_compare_builtin (enum mips_cmp_choice cmp_choice, rtx target,
10974 unsigned int fcode, tree arglist)
10975 {
10976 rtx pat;
10977 enum insn_code icode;
10978 tree arg0;
10979 tree arg1;
10980 rtx op0;
10981 rtx op1;
10982 enum machine_mode tmode;
10983 enum machine_mode mode0;
10984 enum machine_mode mode1;
10985 rtx temp_target;
10986 rtx label1;
10987 rtx label2;
10988 rtx if_then_else;
10989 enum rtx_code test_code;
10990 int compare_value;
10991
10992 if (target == 0 || GET_MODE (target) != SImode)
10993 target = gen_reg_rtx (SImode);
10994
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;
11003
11004 temp_target = gen_reg_rtx (tmode);
11005
11006 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
11007 op0 = copy_to_mode_reg (mode0, op0);
11008
11009 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
11010 op1 = copy_to_mode_reg (mode1, op1);
11011
11012 pat = GEN_FCN (icode) (temp_target, op0, op1);
11013 if (!pat)
11014 return 0;
11015
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
11021
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)
11027
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)
11032 {
11033 case MIPS_CMP_ANY:
11034 test_code = EQ;
11035 compare_value = 0;
11036 break;
11037
11038 case MIPS_CMP_UPPER:
11039 test_code = EQ;
11040 compare_value = 1;
11041 break;
11042
11043 case MIPS_CMP_LOWER:
11044 test_code = EQ;
11045 compare_value = 2;
11046 break;
11047
11048 case MIPS_CMP_ALL:
11049 test_code = NE;
11050 compare_value = 3;
11051 break;
11052
11053 default:
11054 return 0;
11055 }
11056
11057 if (cmp_choice == MIPS_CMP_ALL)
11058 emit_move_insn (target, const1_rtx);
11059 else
11060 emit_move_insn (target, const0_rtx);
11061
11062 emit_insn (pat);
11063
11064 label1 = gen_label_rtx ();
11065 label2 = gen_label_rtx ();
11066
11067 if_then_else
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);
11072
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)));
11076
11077 emit_barrier ();
11078 emit_label (label1);
11079
11080 if (cmp_choice == MIPS_CMP_ALL)
11081 emit_move_insn (target, const0_rtx);
11082 else
11083 emit_move_insn (target, const1_rtx);
11084
11085 emit_label (label2);
11086
11087 return target;
11088 }
11089 \f
11090 #include "gt-mips.h"
This page took 0.559 seconds and 5 git commands to generate.