Implement ASM_DECLARE_FUNCTION_NAME using ASM_OUTPUT_FUNCTION_LABEL
[official-gcc.git] / gcc / config / mips / mips.cc
blob60b336e43d0fc09c272b5171a440b2c5968e560b
1 /* Subroutines used for MIPS code generation.
2 Copyright (C) 1989-2024 Free Software Foundation, Inc.
3 Contributed by A. Lichnewsky, lich@inria.inria.fr.
4 Changes by Michael Meissner, meissner@osf.org.
5 64-bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
6 Brendan Eich, brendan@microunity.com.
8 This file is part of GCC.
10 GCC is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3, or (at your option)
13 any later version.
15 GCC is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3. If not see
22 <http://www.gnu.org/licenses/>. */
24 #define IN_TARGET_CODE 1
26 #include "config.h"
27 #include "system.h"
28 #include "coretypes.h"
29 #include "backend.h"
30 #include "target.h"
31 #include "rtl.h"
32 #include "tree.h"
33 #include "memmodel.h"
34 #include "gimple.h"
35 #include "cfghooks.h"
36 #include "df.h"
37 #include "tm_p.h"
38 #include "stringpool.h"
39 #include "attribs.h"
40 #include "optabs.h"
41 #include "regs.h"
42 #include "emit-rtl.h"
43 #include "recog.h"
44 #include "cgraph.h"
45 #include "diagnostic.h"
46 #include "insn-attr.h"
47 #include "output.h"
48 #include "alias.h"
49 #include "fold-const.h"
50 #include "varasm.h"
51 #include "stor-layout.h"
52 #include "calls.h"
53 #include "explow.h"
54 #include "expr.h"
55 #include "libfuncs.h"
56 #include "reload.h"
57 #include "common/common-target.h"
58 #include "langhooks.h"
59 #include "cfgrtl.h"
60 #include "cfganal.h"
61 #include "sched-int.h"
62 #include "gimplify.h"
63 #include "target-globals.h"
64 #include "tree-pass.h"
65 #include "context.h"
66 #include "builtins.h"
67 #include "rtl-iter.h"
68 #include "flags.h"
69 #include "opts.h"
71 /* This file should be included last. */
72 #include "target-def.h"
74 /* True if X is an UNSPEC wrapper around a SYMBOL_REF or LABEL_REF. */
75 #define UNSPEC_ADDRESS_P(X) \
76 (GET_CODE (X) == UNSPEC \
77 && XINT (X, 1) >= UNSPEC_ADDRESS_FIRST \
78 && XINT (X, 1) < UNSPEC_ADDRESS_FIRST + NUM_SYMBOL_TYPES)
80 /* Extract the symbol or label from UNSPEC wrapper X. */
81 #define UNSPEC_ADDRESS(X) \
82 XVECEXP (X, 0, 0)
84 /* Extract the symbol type from UNSPEC wrapper X. */
85 #define UNSPEC_ADDRESS_TYPE(X) \
86 ((enum mips_symbol_type) (XINT (X, 1) - UNSPEC_ADDRESS_FIRST))
88 /* The maximum distance between the top of the stack frame and the
89 value $sp has when we save and restore registers.
91 The value for normal-mode code must be a SMALL_OPERAND and must
92 preserve the maximum stack alignment. We therefore use a value
93 of 0x7ff0 in this case.
95 microMIPS LWM and SWM support 12-bit offsets (from -0x800 to 0x7ff),
96 so we use a maximum of 0x7f0 for TARGET_MICROMIPS.
98 MIPS16e SAVE and RESTORE instructions can adjust the stack pointer by
99 up to 0x7f8 bytes and can usually save or restore all the registers
100 that we need to save or restore. (Note that we can only use these
101 instructions for o32, for which the stack alignment is 8 bytes.)
103 We use a maximum gap of 0x100 or 0x400 for MIPS16 code when SAVE and
104 RESTORE are not available. We can then use unextended instructions
105 to save and restore registers, and to allocate and deallocate the top
106 part of the frame. */
107 #define MIPS_MAX_FIRST_STACK_STEP \
108 (!TARGET_COMPRESSION ? 0x7ff0 \
109 : TARGET_MICROMIPS || GENERATE_MIPS16E_SAVE_RESTORE ? 0x7f8 \
110 : TARGET_64BIT ? 0x100 : 0x400)
112 /* True if INSN is a mips.md pattern or asm statement. */
113 /* ??? This test exists through the compiler, perhaps it should be
114 moved to rtl.h. */
115 #define USEFUL_INSN_P(INSN) \
116 (NONDEBUG_INSN_P (INSN) \
117 && GET_CODE (PATTERN (INSN)) != USE \
118 && GET_CODE (PATTERN (INSN)) != CLOBBER)
120 /* If INSN is a delayed branch sequence, return the first instruction
121 in the sequence, otherwise return INSN itself. */
122 #define SEQ_BEGIN(INSN) \
123 (INSN_P (INSN) && GET_CODE (PATTERN (INSN)) == SEQUENCE \
124 ? as_a <rtx_insn *> (XVECEXP (PATTERN (INSN), 0, 0)) \
125 : (INSN))
127 /* Likewise for the last instruction in a delayed branch sequence. */
128 #define SEQ_END(INSN) \
129 (INSN_P (INSN) && GET_CODE (PATTERN (INSN)) == SEQUENCE \
130 ? as_a <rtx_insn *> (XVECEXP (PATTERN (INSN), \
131 0, \
132 XVECLEN (PATTERN (INSN), 0) - 1)) \
133 : (INSN))
135 /* Execute the following loop body with SUBINSN set to each instruction
136 between SEQ_BEGIN (INSN) and SEQ_END (INSN) inclusive. */
137 #define FOR_EACH_SUBINSN(SUBINSN, INSN) \
138 for ((SUBINSN) = SEQ_BEGIN (INSN); \
139 (SUBINSN) != NEXT_INSN (SEQ_END (INSN)); \
140 (SUBINSN) = NEXT_INSN (SUBINSN))
142 /* True if bit BIT is set in VALUE. */
143 #define BITSET_P(VALUE, BIT) (((VALUE) & (1 << (BIT))) != 0)
145 /* Return the opcode for a ptr_mode load of the form:
147 l[wd] DEST, OFFSET(BASE). */
148 #define MIPS_LOAD_PTR(DEST, OFFSET, BASE) \
149 (((ptr_mode == DImode ? 0x37 : 0x23) << 26) \
150 | ((BASE) << 21) \
151 | ((DEST) << 16) \
152 | (OFFSET))
154 /* Return the opcode to move register SRC into register DEST. */
155 #define MIPS_MOVE(DEST, SRC) \
156 ((TARGET_64BIT ? 0x2d : 0x21) \
157 | ((DEST) << 11) \
158 | ((SRC) << 21))
160 /* Return the opcode for:
162 lui DEST, VALUE. */
163 #define MIPS_LUI(DEST, VALUE) \
164 ((0xf << 26) | ((DEST) << 16) | (VALUE))
166 /* Return the opcode to jump to register DEST. When the JR opcode is not
167 available use JALR $0, DEST. */
168 #define MIPS_JR(DEST) \
169 (TARGET_CB_ALWAYS ? ((0x1b << 27) | ((DEST) << 16)) \
170 : (((DEST) << 21) | (ISA_HAS_JR ? 0x8 : 0x9)))
172 /* Return the opcode for:
174 bal . + (1 + OFFSET) * 4. */
175 #define MIPS_BAL(OFFSET) \
176 ((0x1 << 26) | (0x11 << 16) | (OFFSET))
178 /* Return the usual opcode for a nop. */
179 #define MIPS_NOP 0
181 /* Classifies an address.
183 ADDRESS_REG
184 A natural register + offset address. The register satisfies
185 mips_valid_base_register_p and the offset is a const_arith_operand.
187 ADDRESS_LO_SUM
188 A LO_SUM rtx. The first operand is a valid base register and
189 the second operand is a symbolic address.
191 ADDRESS_CONST_INT
192 A signed 16-bit constant address.
194 ADDRESS_SYMBOLIC:
195 A constant symbolic address. */
196 enum mips_address_type {
197 ADDRESS_REG,
198 ADDRESS_LO_SUM,
199 ADDRESS_CONST_INT,
200 ADDRESS_SYMBOLIC
203 /* Classifies an unconditional branch of interest for the P6600. */
205 enum mips_ucbranch_type
207 /* May not even be a branch. */
208 UC_UNDEFINED,
209 UC_BALC,
210 UC_OTHER
213 /* Macros to create an enumeration identifier for a function prototype. */
214 #define MIPS_FTYPE_NAME1(A, B) MIPS_##A##_FTYPE_##B
215 #define MIPS_FTYPE_NAME2(A, B, C) MIPS_##A##_FTYPE_##B##_##C
216 #define MIPS_FTYPE_NAME3(A, B, C, D) MIPS_##A##_FTYPE_##B##_##C##_##D
217 #define MIPS_FTYPE_NAME4(A, B, C, D, E) MIPS_##A##_FTYPE_##B##_##C##_##D##_##E
219 /* Classifies the prototype of a built-in function. */
220 enum mips_function_type {
221 #define DEF_MIPS_FTYPE(NARGS, LIST) MIPS_FTYPE_NAME##NARGS LIST,
222 #include "config/mips/mips-ftypes.def"
223 #undef DEF_MIPS_FTYPE
224 MIPS_MAX_FTYPE_MAX
227 /* Specifies how a built-in function should be converted into rtl. */
228 enum mips_builtin_type {
229 /* The function corresponds directly to an .md pattern. The return
230 value is mapped to operand 0 and the arguments are mapped to
231 operands 1 and above. */
232 MIPS_BUILTIN_DIRECT,
234 /* The function corresponds directly to an .md pattern. There is no return
235 value and the arguments are mapped to operands 0 and above. */
236 MIPS_BUILTIN_DIRECT_NO_TARGET,
238 /* The function corresponds to a comparison instruction followed by
239 a mips_cond_move_tf_ps pattern. The first two arguments are the
240 values to compare and the second two arguments are the vector
241 operands for the movt.ps or movf.ps instruction (in assembly order). */
242 MIPS_BUILTIN_MOVF,
243 MIPS_BUILTIN_MOVT,
245 /* The function corresponds to a V2SF comparison instruction. Operand 0
246 of this instruction is the result of the comparison, which has mode
247 CCV2 or CCV4. The function arguments are mapped to operands 1 and
248 above. The function's return value is an SImode boolean that is
249 true under the following conditions:
251 MIPS_BUILTIN_CMP_ANY: one of the registers is true
252 MIPS_BUILTIN_CMP_ALL: all of the registers are true
253 MIPS_BUILTIN_CMP_LOWER: the first register is true
254 MIPS_BUILTIN_CMP_UPPER: the second register is true. */
255 MIPS_BUILTIN_CMP_ANY,
256 MIPS_BUILTIN_CMP_ALL,
257 MIPS_BUILTIN_CMP_UPPER,
258 MIPS_BUILTIN_CMP_LOWER,
260 /* As above, but the instruction only sets a single $fcc register. */
261 MIPS_BUILTIN_CMP_SINGLE,
263 /* The function corresponds to an MSA conditional branch instruction
264 combined with a compare instruction. */
265 MIPS_BUILTIN_MSA_TEST_BRANCH,
267 /* For generating bposge32 branch instructions in MIPS32 DSP ASE. */
268 MIPS_BUILTIN_BPOSGE32
271 /* Invoke MACRO (COND) for each C.cond.fmt condition. */
272 #define MIPS_FP_CONDITIONS(MACRO) \
273 MACRO (f), \
274 MACRO (un), \
275 MACRO (eq), \
276 MACRO (ueq), \
277 MACRO (olt), \
278 MACRO (ult), \
279 MACRO (ole), \
280 MACRO (ule), \
281 MACRO (sf), \
282 MACRO (ngle), \
283 MACRO (seq), \
284 MACRO (ngl), \
285 MACRO (lt), \
286 MACRO (nge), \
287 MACRO (le), \
288 MACRO (ngt)
290 /* Enumerates the codes above as MIPS_FP_COND_<X>. */
291 #define DECLARE_MIPS_COND(X) MIPS_FP_COND_ ## X
292 enum mips_fp_condition {
293 MIPS_FP_CONDITIONS (DECLARE_MIPS_COND)
295 #undef DECLARE_MIPS_COND
297 /* Index X provides the string representation of MIPS_FP_COND_<X>. */
298 #define STRINGIFY(X) #X
299 static const char *const mips_fp_conditions[] = {
300 MIPS_FP_CONDITIONS (STRINGIFY)
302 #undef STRINGIFY
304 /* A class used to control a comdat-style stub that we output in each
305 translation unit that needs it. */
306 class mips_one_only_stub {
307 public:
308 virtual ~mips_one_only_stub () {}
310 /* Return the name of the stub. */
311 virtual const char *get_name () = 0;
313 /* Output the body of the function to asm_out_file. */
314 virtual void output_body () = 0;
317 /* Tuning information that is automatically derived from other sources
318 (such as the scheduler). */
319 static struct {
320 /* The architecture and tuning settings that this structure describes. */
321 enum processor arch;
322 enum processor tune;
324 /* True if this structure describes MIPS16 settings. */
325 bool mips16_p;
327 /* True if the structure has been initialized. */
328 bool initialized_p;
330 /* True if "MULT $0, $0" is preferable to "MTLO $0; MTHI $0"
331 when optimizing for speed. */
332 bool fast_mult_zero_zero_p;
333 } mips_tuning_info;
335 /* Information about a single argument. */
336 struct mips_arg_info {
337 /* True if the argument is passed in a floating-point register, or
338 would have been if we hadn't run out of registers. */
339 bool fpr_p;
341 /* The number of words passed in registers, rounded up. */
342 unsigned int reg_words;
344 /* For EABI, the offset of the first register from GP_ARG_FIRST or
345 FP_ARG_FIRST. For other ABIs, the offset of the first register from
346 the start of the ABI's argument structure (see the CUMULATIVE_ARGS
347 comment for details).
349 The value is MAX_ARGS_IN_REGISTERS if the argument is passed entirely
350 on the stack. */
351 unsigned int reg_offset;
353 /* The number of words that must be passed on the stack, rounded up. */
354 unsigned int stack_words;
356 /* The offset from the start of the stack overflow area of the argument's
357 first stack word. Only meaningful when STACK_WORDS is nonzero. */
358 unsigned int stack_offset;
361 /* Information about an address described by mips_address_type.
363 ADDRESS_CONST_INT
364 No fields are used.
366 ADDRESS_REG
367 REG is the base register and OFFSET is the constant offset.
369 ADDRESS_LO_SUM
370 REG and OFFSET are the operands to the LO_SUM and SYMBOL_TYPE
371 is the type of symbol it references.
373 ADDRESS_SYMBOLIC
374 SYMBOL_TYPE is the type of symbol that the address references. */
375 struct mips_address_info {
376 enum mips_address_type type;
377 rtx reg;
378 rtx offset;
379 enum mips_symbol_type symbol_type;
382 /* One stage in a constant building sequence. These sequences have
383 the form:
385 A = VALUE[0]
386 A = A CODE[1] VALUE[1]
387 A = A CODE[2] VALUE[2]
390 where A is an accumulator, each CODE[i] is a binary rtl operation
391 and each VALUE[i] is a constant integer. CODE[0] is undefined. */
392 struct mips_integer_op {
393 enum rtx_code code;
394 unsigned HOST_WIDE_INT value;
397 /* The largest number of operations needed to load an integer constant.
398 The worst accepted case for 64-bit constants is LUI,ORI,SLL,ORI,SLL,ORI.
399 When the lowest bit is clear, we can try, but reject a sequence with
400 an extra SLL at the end. */
401 #define MIPS_MAX_INTEGER_OPS 7
403 /* Information about a MIPS16e SAVE or RESTORE instruction. */
404 struct mips16e_save_restore_info {
405 /* The number of argument registers saved by a SAVE instruction.
406 0 for RESTORE instructions. */
407 unsigned int nargs;
409 /* Bit X is set if the instruction saves or restores GPR X. */
410 unsigned int mask;
412 /* The total number of bytes to allocate. */
413 HOST_WIDE_INT size;
416 /* Costs of various operations on the different architectures. */
418 struct mips_rtx_cost_data
420 unsigned short fp_add;
421 unsigned short fp_mult_sf;
422 unsigned short fp_mult_df;
423 unsigned short fp_div_sf;
424 unsigned short fp_div_df;
425 unsigned short int_mult_si;
426 unsigned short int_mult_di;
427 unsigned short int_div_si;
428 unsigned short int_div_di;
429 unsigned short branch_cost;
430 unsigned short memory_latency;
433 /* Global variables for machine-dependent things. */
435 /* The -G setting, or the configuration's default small-data limit if
436 no -G option is given. */
437 static unsigned int mips_small_data_threshold;
439 /* The number of file directives written by mips_output_filename. */
440 int num_source_filenames;
442 /* The name that appeared in the last .file directive written by
443 mips_output_filename, or "" if mips_output_filename hasn't
444 written anything yet. */
445 const char *current_function_file = "";
447 /* Arrays that map GCC register numbers to debugger register numbers. */
448 int mips_dwarf_regno[FIRST_PSEUDO_REGISTER];
450 /* Information about the current function's epilogue, used only while
451 expanding it. */
452 static struct {
453 /* A list of queued REG_CFA_RESTORE notes. */
454 rtx cfa_restores;
456 /* The CFA is currently defined as CFA_REG + CFA_OFFSET. */
457 rtx cfa_reg;
458 HOST_WIDE_INT cfa_offset;
460 /* The offset of the CFA from the stack pointer while restoring
461 registers. */
462 HOST_WIDE_INT cfa_restore_sp_offset;
463 } mips_epilogue;
465 /* The nesting depth of the PRINT_OPERAND '%(', '%<' and '%[' constructs. */
466 struct mips_asm_switch mips_noreorder = { "reorder", 0 };
467 struct mips_asm_switch mips_nomacro = { "macro", 0 };
468 struct mips_asm_switch mips_noat = { "at", 0 };
470 /* True if we're writing out a branch-likely instruction rather than a
471 normal branch. */
472 static bool mips_branch_likely;
474 /* The current instruction-set architecture. */
475 enum processor mips_arch;
476 const struct mips_cpu_info *mips_arch_info;
478 /* The processor that we should tune the code for. */
479 enum processor mips_tune;
480 const struct mips_cpu_info *mips_tune_info;
482 /* The ISA level associated with mips_arch. */
483 int mips_isa;
485 /* The ISA revision level. This is 0 for MIPS I to V and N for
486 MIPS{32,64}rN. */
487 int mips_isa_rev;
489 /* The architecture selected by -mipsN, or null if -mipsN wasn't used. */
490 static const struct mips_cpu_info *mips_isa_option_info;
492 /* Which cost information to use. */
493 static const struct mips_rtx_cost_data *mips_cost;
495 /* The ambient target flags, excluding MASK_MIPS16. */
496 static int mips_base_target_flags;
498 /* The default compression mode. */
499 unsigned int mips_base_compression_flags;
501 /* The default code readable setting. */
502 enum mips_code_readable_setting mips_base_code_readable;
504 /* The ambient values of other global variables. */
505 static int mips_base_schedule_insns; /* flag_schedule_insns */
506 static int mips_base_reorder_blocks_and_partition; /* flag_reorder... */
507 static int mips_base_move_loop_invariants; /* flag_move_loop_invariants */
508 static const char *mips_base_align_loops; /* align_loops */
509 static const char *mips_base_align_jumps; /* align_jumps */
510 static const char *mips_base_align_functions; /* align_functions */
512 /* Index [M][R] is true if register R is allowed to hold a value of mode M. */
513 static bool mips_hard_regno_mode_ok_p[MAX_MACHINE_MODE][FIRST_PSEUDO_REGISTER];
515 /* Index C is true if character C is a valid PRINT_OPERAND punctation
516 character. */
517 static bool mips_print_operand_punct[256];
519 static GTY (()) int mips_output_filename_first_time = 1;
521 /* mips_split_p[X] is true if symbols of type X can be split by
522 mips_split_symbol. */
523 bool mips_split_p[NUM_SYMBOL_TYPES];
525 /* mips_split_hi_p[X] is true if the high parts of symbols of type X
526 can be split by mips_split_symbol. */
527 bool mips_split_hi_p[NUM_SYMBOL_TYPES];
529 /* mips_use_pcrel_pool_p[X] is true if symbols of type X should be
530 forced into a PC-relative constant pool. */
531 bool mips_use_pcrel_pool_p[NUM_SYMBOL_TYPES];
533 /* mips_lo_relocs[X] is the relocation to use when a symbol of type X
534 appears in a LO_SUM. It can be null if such LO_SUMs aren't valid or
535 if they are matched by a special .md file pattern. */
536 const char *mips_lo_relocs[NUM_SYMBOL_TYPES];
538 /* Likewise for HIGHs. */
539 const char *mips_hi_relocs[NUM_SYMBOL_TYPES];
541 /* Target state for MIPS16. */
542 struct target_globals *mips16_globals;
544 /* Target state for MICROMIPS. */
545 struct target_globals *micromips_globals;
547 /* Cached value of can_issue_more. This is cached in mips_variable_issue hook
548 and returned from mips_sched_reorder2. */
549 static int cached_can_issue_more;
551 /* The stubs for various MIPS16 support functions, if used. */
552 static mips_one_only_stub *mips16_rdhwr_stub;
553 static mips_one_only_stub *mips16_get_fcsr_stub;
554 static mips_one_only_stub *mips16_set_fcsr_stub;
556 /* Index R is the smallest register class that contains register R. */
557 const enum reg_class mips_regno_to_class[FIRST_PSEUDO_REGISTER] = {
558 LEA_REGS, LEA_REGS, M16_STORE_REGS, V1_REG,
559 M16_STORE_REGS, M16_STORE_REGS, M16_STORE_REGS, M16_STORE_REGS,
560 LEA_REGS, LEA_REGS, LEA_REGS, LEA_REGS,
561 LEA_REGS, LEA_REGS, LEA_REGS, LEA_REGS,
562 M16_REGS, M16_STORE_REGS, LEA_REGS, LEA_REGS,
563 LEA_REGS, LEA_REGS, LEA_REGS, LEA_REGS,
564 T_REG, PIC_FN_ADDR_REG, LEA_REGS, LEA_REGS,
565 LEA_REGS, M16_SP_REGS, LEA_REGS, LEA_REGS,
567 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
568 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
569 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
570 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
571 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
572 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
573 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
574 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
575 MD0_REG, MD1_REG, NO_REGS, ST_REGS,
576 ST_REGS, ST_REGS, ST_REGS, ST_REGS,
577 ST_REGS, ST_REGS, ST_REGS, NO_REGS,
578 NO_REGS, FRAME_REGS, FRAME_REGS, NO_REGS,
579 COP0_REGS, COP0_REGS, COP0_REGS, COP0_REGS,
580 COP0_REGS, COP0_REGS, COP0_REGS, COP0_REGS,
581 COP0_REGS, COP0_REGS, COP0_REGS, COP0_REGS,
582 COP0_REGS, COP0_REGS, COP0_REGS, COP0_REGS,
583 COP0_REGS, COP0_REGS, COP0_REGS, COP0_REGS,
584 COP0_REGS, COP0_REGS, COP0_REGS, COP0_REGS,
585 COP0_REGS, COP0_REGS, COP0_REGS, COP0_REGS,
586 COP0_REGS, COP0_REGS, COP0_REGS, COP0_REGS,
587 COP2_REGS, COP2_REGS, COP2_REGS, COP2_REGS,
588 COP2_REGS, COP2_REGS, COP2_REGS, COP2_REGS,
589 COP2_REGS, COP2_REGS, COP2_REGS, COP2_REGS,
590 COP2_REGS, COP2_REGS, COP2_REGS, COP2_REGS,
591 COP2_REGS, COP2_REGS, COP2_REGS, COP2_REGS,
592 COP2_REGS, COP2_REGS, COP2_REGS, COP2_REGS,
593 COP2_REGS, COP2_REGS, COP2_REGS, COP2_REGS,
594 COP2_REGS, COP2_REGS, COP2_REGS, COP2_REGS,
595 COP3_REGS, COP3_REGS, COP3_REGS, COP3_REGS,
596 COP3_REGS, COP3_REGS, COP3_REGS, COP3_REGS,
597 COP3_REGS, COP3_REGS, COP3_REGS, COP3_REGS,
598 COP3_REGS, COP3_REGS, COP3_REGS, COP3_REGS,
599 COP3_REGS, COP3_REGS, COP3_REGS, COP3_REGS,
600 COP3_REGS, COP3_REGS, COP3_REGS, COP3_REGS,
601 COP3_REGS, COP3_REGS, COP3_REGS, COP3_REGS,
602 COP3_REGS, COP3_REGS, COP3_REGS, COP3_REGS,
603 DSP_ACC_REGS, DSP_ACC_REGS, DSP_ACC_REGS, DSP_ACC_REGS,
604 DSP_ACC_REGS, DSP_ACC_REGS, ALL_REGS, ALL_REGS,
605 ALL_REGS, ALL_REGS, ALL_REGS, ALL_REGS
608 static tree mips_handle_code_readable_attr (tree *, tree, tree, int, bool *);
609 static tree mips_handle_interrupt_attr (tree *, tree, tree, int, bool *);
610 static tree mips_handle_use_shadow_register_set_attr (tree *, tree, tree, int,
611 bool *);
613 /* The value of TARGET_ATTRIBUTE_TABLE. */
614 TARGET_GNU_ATTRIBUTES (mips_attribute_table, {
615 /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
616 affects_type_identity, handler, exclude } */
617 { "long_call", 0, 0, false, true, true, false, NULL, NULL },
618 { "short_call", 0, 0, false, true, true, false, NULL, NULL },
619 { "far", 0, 0, false, true, true, false, NULL, NULL },
620 { "near", 0, 0, false, true, true, false, NULL, NULL },
621 /* We would really like to treat "mips16" and "nomips16" as type
622 attributes, but GCC doesn't provide the hooks we need to support
623 the right conversion rules. As declaration attributes, they affect
624 code generation but don't carry other semantics. */
625 { "mips16", 0, 0, true, false, false, false, NULL, NULL },
626 { "nomips16", 0, 0, true, false, false, false, NULL, NULL },
627 { "micromips", 0, 0, true, false, false, false, NULL, NULL },
628 { "nomicromips", 0, 0, true, false, false, false, NULL, NULL },
629 { "nocompression", 0, 0, true, false, false, false, NULL, NULL },
630 { "code_readable", 0, 1, true, false, false, false,
631 mips_handle_code_readable_attr, NULL },
632 /* Allow functions to be specified as interrupt handlers */
633 { "interrupt", 0, 1, false, true, true, false, mips_handle_interrupt_attr,
634 NULL },
635 { "use_shadow_register_set", 0, 1, false, true, true, false,
636 mips_handle_use_shadow_register_set_attr, NULL },
637 { "keep_interrupts_masked", 0, 0, false, true, true, false, NULL, NULL },
638 { "use_debug_exception_return", 0, 0, false, true, true, false, NULL, NULL },
639 { "use_hazard_barrier_return", 0, 0, true, false, false, false, NULL, NULL }
642 /* A table describing all the processors GCC knows about; see
643 mips-cpus.def for details. */
644 static const struct mips_cpu_info mips_cpu_info_table[] = {
645 #define MIPS_CPU(NAME, CPU, ISA, FLAGS) \
646 { NAME, CPU, ISA, FLAGS },
647 #include "mips-cpus.def"
648 #undef MIPS_CPU
651 /* Default costs. If these are used for a processor we should look
652 up the actual costs. */
653 #define DEFAULT_COSTS COSTS_N_INSNS (6), /* fp_add */ \
654 COSTS_N_INSNS (7), /* fp_mult_sf */ \
655 COSTS_N_INSNS (8), /* fp_mult_df */ \
656 COSTS_N_INSNS (23), /* fp_div_sf */ \
657 COSTS_N_INSNS (36), /* fp_div_df */ \
658 COSTS_N_INSNS (10), /* int_mult_si */ \
659 COSTS_N_INSNS (10), /* int_mult_di */ \
660 COSTS_N_INSNS (69), /* int_div_si */ \
661 COSTS_N_INSNS (69), /* int_div_di */ \
662 2, /* branch_cost */ \
663 4 /* memory_latency */
665 /* Floating-point costs for processors without an FPU. Just assume that
666 all floating-point libcalls are very expensive. */
667 #define SOFT_FP_COSTS COSTS_N_INSNS (256), /* fp_add */ \
668 COSTS_N_INSNS (256), /* fp_mult_sf */ \
669 COSTS_N_INSNS (256), /* fp_mult_df */ \
670 COSTS_N_INSNS (256), /* fp_div_sf */ \
671 COSTS_N_INSNS (256) /* fp_div_df */
673 /* Costs to use when optimizing for size. */
674 static const struct mips_rtx_cost_data mips_rtx_cost_optimize_size = {
675 COSTS_N_INSNS (1), /* fp_add */
676 COSTS_N_INSNS (1), /* fp_mult_sf */
677 COSTS_N_INSNS (1), /* fp_mult_df */
678 COSTS_N_INSNS (1), /* fp_div_sf */
679 COSTS_N_INSNS (1), /* fp_div_df */
680 COSTS_N_INSNS (1), /* int_mult_si */
681 COSTS_N_INSNS (1), /* int_mult_di */
682 COSTS_N_INSNS (1), /* int_div_si */
683 COSTS_N_INSNS (1), /* int_div_di */
684 2, /* branch_cost */
685 4 /* memory_latency */
688 /* Costs to use when optimizing for speed, indexed by processor. */
689 static const struct mips_rtx_cost_data
690 mips_rtx_cost_data[NUM_PROCESSOR_VALUES] = {
691 { /* R3000 */
692 COSTS_N_INSNS (2), /* fp_add */
693 COSTS_N_INSNS (4), /* fp_mult_sf */
694 COSTS_N_INSNS (5), /* fp_mult_df */
695 COSTS_N_INSNS (12), /* fp_div_sf */
696 COSTS_N_INSNS (19), /* fp_div_df */
697 COSTS_N_INSNS (12), /* int_mult_si */
698 COSTS_N_INSNS (12), /* int_mult_di */
699 COSTS_N_INSNS (35), /* int_div_si */
700 COSTS_N_INSNS (35), /* int_div_di */
701 1, /* branch_cost */
702 4 /* memory_latency */
704 { /* 4KC */
705 SOFT_FP_COSTS,
706 COSTS_N_INSNS (6), /* int_mult_si */
707 COSTS_N_INSNS (6), /* int_mult_di */
708 COSTS_N_INSNS (36), /* int_div_si */
709 COSTS_N_INSNS (36), /* int_div_di */
710 1, /* branch_cost */
711 4 /* memory_latency */
713 { /* 4KP */
714 SOFT_FP_COSTS,
715 COSTS_N_INSNS (36), /* int_mult_si */
716 COSTS_N_INSNS (36), /* int_mult_di */
717 COSTS_N_INSNS (37), /* int_div_si */
718 COSTS_N_INSNS (37), /* int_div_di */
719 1, /* branch_cost */
720 4 /* memory_latency */
722 { /* 5KC */
723 SOFT_FP_COSTS,
724 COSTS_N_INSNS (4), /* int_mult_si */
725 COSTS_N_INSNS (11), /* int_mult_di */
726 COSTS_N_INSNS (36), /* int_div_si */
727 COSTS_N_INSNS (68), /* int_div_di */
728 1, /* branch_cost */
729 4 /* memory_latency */
731 { /* 5KF */
732 COSTS_N_INSNS (4), /* fp_add */
733 COSTS_N_INSNS (4), /* fp_mult_sf */
734 COSTS_N_INSNS (5), /* fp_mult_df */
735 COSTS_N_INSNS (17), /* fp_div_sf */
736 COSTS_N_INSNS (32), /* fp_div_df */
737 COSTS_N_INSNS (4), /* int_mult_si */
738 COSTS_N_INSNS (11), /* int_mult_di */
739 COSTS_N_INSNS (36), /* int_div_si */
740 COSTS_N_INSNS (68), /* int_div_di */
741 1, /* branch_cost */
742 4 /* memory_latency */
744 { /* 20KC */
745 COSTS_N_INSNS (4), /* fp_add */
746 COSTS_N_INSNS (4), /* fp_mult_sf */
747 COSTS_N_INSNS (5), /* fp_mult_df */
748 COSTS_N_INSNS (17), /* fp_div_sf */
749 COSTS_N_INSNS (32), /* fp_div_df */
750 COSTS_N_INSNS (4), /* int_mult_si */
751 COSTS_N_INSNS (7), /* int_mult_di */
752 COSTS_N_INSNS (42), /* int_div_si */
753 COSTS_N_INSNS (72), /* int_div_di */
754 1, /* branch_cost */
755 4 /* memory_latency */
757 { /* 24KC */
758 SOFT_FP_COSTS,
759 COSTS_N_INSNS (5), /* int_mult_si */
760 COSTS_N_INSNS (5), /* int_mult_di */
761 COSTS_N_INSNS (41), /* int_div_si */
762 COSTS_N_INSNS (41), /* int_div_di */
763 1, /* branch_cost */
764 4 /* memory_latency */
766 { /* 24KF2_1 */
767 COSTS_N_INSNS (8), /* fp_add */
768 COSTS_N_INSNS (8), /* fp_mult_sf */
769 COSTS_N_INSNS (10), /* fp_mult_df */
770 COSTS_N_INSNS (34), /* fp_div_sf */
771 COSTS_N_INSNS (64), /* fp_div_df */
772 COSTS_N_INSNS (5), /* int_mult_si */
773 COSTS_N_INSNS (5), /* int_mult_di */
774 COSTS_N_INSNS (41), /* int_div_si */
775 COSTS_N_INSNS (41), /* int_div_di */
776 1, /* branch_cost */
777 4 /* memory_latency */
779 { /* 24KF1_1 */
780 COSTS_N_INSNS (4), /* fp_add */
781 COSTS_N_INSNS (4), /* fp_mult_sf */
782 COSTS_N_INSNS (5), /* fp_mult_df */
783 COSTS_N_INSNS (17), /* fp_div_sf */
784 COSTS_N_INSNS (32), /* fp_div_df */
785 COSTS_N_INSNS (5), /* int_mult_si */
786 COSTS_N_INSNS (5), /* int_mult_di */
787 COSTS_N_INSNS (41), /* int_div_si */
788 COSTS_N_INSNS (41), /* int_div_di */
789 1, /* branch_cost */
790 4 /* memory_latency */
792 { /* 74KC */
793 SOFT_FP_COSTS,
794 COSTS_N_INSNS (5), /* int_mult_si */
795 COSTS_N_INSNS (5), /* int_mult_di */
796 COSTS_N_INSNS (41), /* int_div_si */
797 COSTS_N_INSNS (41), /* int_div_di */
798 1, /* branch_cost */
799 4 /* memory_latency */
801 { /* 74KF2_1 */
802 COSTS_N_INSNS (8), /* fp_add */
803 COSTS_N_INSNS (8), /* fp_mult_sf */
804 COSTS_N_INSNS (10), /* fp_mult_df */
805 COSTS_N_INSNS (34), /* fp_div_sf */
806 COSTS_N_INSNS (64), /* fp_div_df */
807 COSTS_N_INSNS (5), /* int_mult_si */
808 COSTS_N_INSNS (5), /* int_mult_di */
809 COSTS_N_INSNS (41), /* int_div_si */
810 COSTS_N_INSNS (41), /* int_div_di */
811 1, /* branch_cost */
812 4 /* memory_latency */
814 { /* 74KF1_1 */
815 COSTS_N_INSNS (4), /* fp_add */
816 COSTS_N_INSNS (4), /* fp_mult_sf */
817 COSTS_N_INSNS (5), /* fp_mult_df */
818 COSTS_N_INSNS (17), /* fp_div_sf */
819 COSTS_N_INSNS (32), /* fp_div_df */
820 COSTS_N_INSNS (5), /* int_mult_si */
821 COSTS_N_INSNS (5), /* int_mult_di */
822 COSTS_N_INSNS (41), /* int_div_si */
823 COSTS_N_INSNS (41), /* int_div_di */
824 1, /* branch_cost */
825 4 /* memory_latency */
827 { /* 74KF3_2 */
828 COSTS_N_INSNS (6), /* fp_add */
829 COSTS_N_INSNS (6), /* fp_mult_sf */
830 COSTS_N_INSNS (7), /* fp_mult_df */
831 COSTS_N_INSNS (25), /* fp_div_sf */
832 COSTS_N_INSNS (48), /* fp_div_df */
833 COSTS_N_INSNS (5), /* int_mult_si */
834 COSTS_N_INSNS (5), /* int_mult_di */
835 COSTS_N_INSNS (41), /* int_div_si */
836 COSTS_N_INSNS (41), /* int_div_di */
837 1, /* branch_cost */
838 4 /* memory_latency */
840 { /* Loongson-2E */
841 DEFAULT_COSTS
843 { /* Loongson-2F */
844 DEFAULT_COSTS
846 { /* Loongson gs464. */
847 DEFAULT_COSTS
849 { /* Loongson gs464e. */
850 DEFAULT_COSTS
852 { /* Loongson gs264e. */
853 DEFAULT_COSTS
855 { /* M4k */
856 DEFAULT_COSTS
858 /* Octeon */
860 SOFT_FP_COSTS,
861 COSTS_N_INSNS (5), /* int_mult_si */
862 COSTS_N_INSNS (5), /* int_mult_di */
863 COSTS_N_INSNS (72), /* int_div_si */
864 COSTS_N_INSNS (72), /* int_div_di */
865 1, /* branch_cost */
866 4 /* memory_latency */
868 /* Octeon II */
870 SOFT_FP_COSTS,
871 COSTS_N_INSNS (6), /* int_mult_si */
872 COSTS_N_INSNS (6), /* int_mult_di */
873 COSTS_N_INSNS (18), /* int_div_si */
874 COSTS_N_INSNS (35), /* int_div_di */
875 4, /* branch_cost */
876 4 /* memory_latency */
878 /* Octeon III */
880 COSTS_N_INSNS (6), /* fp_add */
881 COSTS_N_INSNS (6), /* fp_mult_sf */
882 COSTS_N_INSNS (7), /* fp_mult_df */
883 COSTS_N_INSNS (25), /* fp_div_sf */
884 COSTS_N_INSNS (48), /* fp_div_df */
885 COSTS_N_INSNS (6), /* int_mult_si */
886 COSTS_N_INSNS (6), /* int_mult_di */
887 COSTS_N_INSNS (18), /* int_div_si */
888 COSTS_N_INSNS (35), /* int_div_di */
889 4, /* branch_cost */
890 4 /* memory_latency */
892 { /* R3900 */
893 COSTS_N_INSNS (2), /* fp_add */
894 COSTS_N_INSNS (4), /* fp_mult_sf */
895 COSTS_N_INSNS (5), /* fp_mult_df */
896 COSTS_N_INSNS (12), /* fp_div_sf */
897 COSTS_N_INSNS (19), /* fp_div_df */
898 COSTS_N_INSNS (2), /* int_mult_si */
899 COSTS_N_INSNS (2), /* int_mult_di */
900 COSTS_N_INSNS (35), /* int_div_si */
901 COSTS_N_INSNS (35), /* int_div_di */
902 1, /* branch_cost */
903 4 /* memory_latency */
905 { /* R6000 */
906 COSTS_N_INSNS (3), /* fp_add */
907 COSTS_N_INSNS (5), /* fp_mult_sf */
908 COSTS_N_INSNS (6), /* fp_mult_df */
909 COSTS_N_INSNS (15), /* fp_div_sf */
910 COSTS_N_INSNS (16), /* fp_div_df */
911 COSTS_N_INSNS (17), /* int_mult_si */
912 COSTS_N_INSNS (17), /* int_mult_di */
913 COSTS_N_INSNS (38), /* int_div_si */
914 COSTS_N_INSNS (38), /* int_div_di */
915 2, /* branch_cost */
916 6 /* memory_latency */
918 { /* R4000 */
919 COSTS_N_INSNS (6), /* fp_add */
920 COSTS_N_INSNS (7), /* fp_mult_sf */
921 COSTS_N_INSNS (8), /* fp_mult_df */
922 COSTS_N_INSNS (23), /* fp_div_sf */
923 COSTS_N_INSNS (36), /* fp_div_df */
924 COSTS_N_INSNS (10), /* int_mult_si */
925 COSTS_N_INSNS (10), /* int_mult_di */
926 COSTS_N_INSNS (69), /* int_div_si */
927 COSTS_N_INSNS (69), /* int_div_di */
928 2, /* branch_cost */
929 6 /* memory_latency */
931 { /* R4100 */
932 DEFAULT_COSTS
934 { /* R4111 */
935 DEFAULT_COSTS
937 { /* R4120 */
938 DEFAULT_COSTS
940 { /* R4130 */
941 /* The only costs that appear to be updated here are
942 integer multiplication. */
943 SOFT_FP_COSTS,
944 COSTS_N_INSNS (4), /* int_mult_si */
945 COSTS_N_INSNS (6), /* int_mult_di */
946 COSTS_N_INSNS (69), /* int_div_si */
947 COSTS_N_INSNS (69), /* int_div_di */
948 1, /* branch_cost */
949 4 /* memory_latency */
951 { /* R4300 */
952 DEFAULT_COSTS
954 { /* R4600 */
955 DEFAULT_COSTS
957 { /* R4650 */
958 DEFAULT_COSTS
960 { /* R4700 */
961 DEFAULT_COSTS
963 { /* R5000 */
964 COSTS_N_INSNS (6), /* fp_add */
965 COSTS_N_INSNS (4), /* fp_mult_sf */
966 COSTS_N_INSNS (5), /* fp_mult_df */
967 COSTS_N_INSNS (23), /* fp_div_sf */
968 COSTS_N_INSNS (36), /* fp_div_df */
969 COSTS_N_INSNS (5), /* int_mult_si */
970 COSTS_N_INSNS (5), /* int_mult_di */
971 COSTS_N_INSNS (36), /* int_div_si */
972 COSTS_N_INSNS (36), /* int_div_di */
973 1, /* branch_cost */
974 4 /* memory_latency */
976 { /* R5400 */
977 COSTS_N_INSNS (6), /* fp_add */
978 COSTS_N_INSNS (5), /* fp_mult_sf */
979 COSTS_N_INSNS (6), /* fp_mult_df */
980 COSTS_N_INSNS (30), /* fp_div_sf */
981 COSTS_N_INSNS (59), /* fp_div_df */
982 COSTS_N_INSNS (3), /* int_mult_si */
983 COSTS_N_INSNS (4), /* int_mult_di */
984 COSTS_N_INSNS (42), /* int_div_si */
985 COSTS_N_INSNS (74), /* int_div_di */
986 1, /* branch_cost */
987 4 /* memory_latency */
989 { /* R5500 */
990 COSTS_N_INSNS (6), /* fp_add */
991 COSTS_N_INSNS (5), /* fp_mult_sf */
992 COSTS_N_INSNS (6), /* fp_mult_df */
993 COSTS_N_INSNS (30), /* fp_div_sf */
994 COSTS_N_INSNS (59), /* fp_div_df */
995 COSTS_N_INSNS (5), /* int_mult_si */
996 COSTS_N_INSNS (9), /* int_mult_di */
997 COSTS_N_INSNS (42), /* int_div_si */
998 COSTS_N_INSNS (74), /* int_div_di */
999 1, /* branch_cost */
1000 4 /* memory_latency */
1002 { /* R5900 */
1003 COSTS_N_INSNS (4), /* fp_add */
1004 COSTS_N_INSNS (4), /* fp_mult_sf */
1005 COSTS_N_INSNS (256), /* fp_mult_df */
1006 COSTS_N_INSNS (8), /* fp_div_sf */
1007 COSTS_N_INSNS (256), /* fp_div_df */
1008 COSTS_N_INSNS (4), /* int_mult_si */
1009 COSTS_N_INSNS (256), /* int_mult_di */
1010 COSTS_N_INSNS (37), /* int_div_si */
1011 COSTS_N_INSNS (256), /* int_div_di */
1012 1, /* branch_cost */
1013 4 /* memory_latency */
1015 { /* R7000 */
1016 /* The only costs that are changed here are
1017 integer multiplication. */
1018 COSTS_N_INSNS (6), /* fp_add */
1019 COSTS_N_INSNS (7), /* fp_mult_sf */
1020 COSTS_N_INSNS (8), /* fp_mult_df */
1021 COSTS_N_INSNS (23), /* fp_div_sf */
1022 COSTS_N_INSNS (36), /* fp_div_df */
1023 COSTS_N_INSNS (5), /* int_mult_si */
1024 COSTS_N_INSNS (9), /* int_mult_di */
1025 COSTS_N_INSNS (69), /* int_div_si */
1026 COSTS_N_INSNS (69), /* int_div_di */
1027 1, /* branch_cost */
1028 4 /* memory_latency */
1030 { /* R8000 */
1031 DEFAULT_COSTS
1033 { /* R9000 */
1034 /* The only costs that are changed here are
1035 integer multiplication. */
1036 COSTS_N_INSNS (6), /* fp_add */
1037 COSTS_N_INSNS (7), /* fp_mult_sf */
1038 COSTS_N_INSNS (8), /* fp_mult_df */
1039 COSTS_N_INSNS (23), /* fp_div_sf */
1040 COSTS_N_INSNS (36), /* fp_div_df */
1041 COSTS_N_INSNS (3), /* int_mult_si */
1042 COSTS_N_INSNS (8), /* int_mult_di */
1043 COSTS_N_INSNS (69), /* int_div_si */
1044 COSTS_N_INSNS (69), /* int_div_di */
1045 1, /* branch_cost */
1046 4 /* memory_latency */
1048 { /* R1x000 */
1049 COSTS_N_INSNS (2), /* fp_add */
1050 COSTS_N_INSNS (2), /* fp_mult_sf */
1051 COSTS_N_INSNS (2), /* fp_mult_df */
1052 COSTS_N_INSNS (12), /* fp_div_sf */
1053 COSTS_N_INSNS (19), /* fp_div_df */
1054 COSTS_N_INSNS (5), /* int_mult_si */
1055 COSTS_N_INSNS (9), /* int_mult_di */
1056 COSTS_N_INSNS (34), /* int_div_si */
1057 COSTS_N_INSNS (66), /* int_div_di */
1058 1, /* branch_cost */
1059 4 /* memory_latency */
1061 { /* SB1 */
1062 /* These costs are the same as the SB-1A below. */
1063 COSTS_N_INSNS (4), /* fp_add */
1064 COSTS_N_INSNS (4), /* fp_mult_sf */
1065 COSTS_N_INSNS (4), /* fp_mult_df */
1066 COSTS_N_INSNS (24), /* fp_div_sf */
1067 COSTS_N_INSNS (32), /* fp_div_df */
1068 COSTS_N_INSNS (3), /* int_mult_si */
1069 COSTS_N_INSNS (4), /* int_mult_di */
1070 COSTS_N_INSNS (36), /* int_div_si */
1071 COSTS_N_INSNS (68), /* int_div_di */
1072 1, /* branch_cost */
1073 4 /* memory_latency */
1075 { /* SB1-A */
1076 /* These costs are the same as the SB-1 above. */
1077 COSTS_N_INSNS (4), /* fp_add */
1078 COSTS_N_INSNS (4), /* fp_mult_sf */
1079 COSTS_N_INSNS (4), /* fp_mult_df */
1080 COSTS_N_INSNS (24), /* fp_div_sf */
1081 COSTS_N_INSNS (32), /* fp_div_df */
1082 COSTS_N_INSNS (3), /* int_mult_si */
1083 COSTS_N_INSNS (4), /* int_mult_di */
1084 COSTS_N_INSNS (36), /* int_div_si */
1085 COSTS_N_INSNS (68), /* int_div_di */
1086 1, /* branch_cost */
1087 4 /* memory_latency */
1089 { /* SR71000 */
1090 DEFAULT_COSTS
1092 { /* XLR */
1093 SOFT_FP_COSTS,
1094 COSTS_N_INSNS (8), /* int_mult_si */
1095 COSTS_N_INSNS (8), /* int_mult_di */
1096 COSTS_N_INSNS (72), /* int_div_si */
1097 COSTS_N_INSNS (72), /* int_div_di */
1098 1, /* branch_cost */
1099 4 /* memory_latency */
1101 { /* XLP */
1102 /* These costs are the same as 5KF above. */
1103 COSTS_N_INSNS (4), /* fp_add */
1104 COSTS_N_INSNS (4), /* fp_mult_sf */
1105 COSTS_N_INSNS (5), /* fp_mult_df */
1106 COSTS_N_INSNS (17), /* fp_div_sf */
1107 COSTS_N_INSNS (32), /* fp_div_df */
1108 COSTS_N_INSNS (4), /* int_mult_si */
1109 COSTS_N_INSNS (11), /* int_mult_di */
1110 COSTS_N_INSNS (36), /* int_div_si */
1111 COSTS_N_INSNS (68), /* int_div_di */
1112 1, /* branch_cost */
1113 4 /* memory_latency */
1115 { /* P5600 */
1116 COSTS_N_INSNS (4), /* fp_add */
1117 COSTS_N_INSNS (5), /* fp_mult_sf */
1118 COSTS_N_INSNS (5), /* fp_mult_df */
1119 COSTS_N_INSNS (17), /* fp_div_sf */
1120 COSTS_N_INSNS (17), /* fp_div_df */
1121 COSTS_N_INSNS (5), /* int_mult_si */
1122 COSTS_N_INSNS (5), /* int_mult_di */
1123 COSTS_N_INSNS (8), /* int_div_si */
1124 COSTS_N_INSNS (8), /* int_div_di */
1125 2, /* branch_cost */
1126 4 /* memory_latency */
1128 { /* M5100 */
1129 COSTS_N_INSNS (4), /* fp_add */
1130 COSTS_N_INSNS (4), /* fp_mult_sf */
1131 COSTS_N_INSNS (5), /* fp_mult_df */
1132 COSTS_N_INSNS (17), /* fp_div_sf */
1133 COSTS_N_INSNS (32), /* fp_div_df */
1134 COSTS_N_INSNS (5), /* int_mult_si */
1135 COSTS_N_INSNS (5), /* int_mult_di */
1136 COSTS_N_INSNS (34), /* int_div_si */
1137 COSTS_N_INSNS (68), /* int_div_di */
1138 1, /* branch_cost */
1139 4 /* memory_latency */
1141 { /* I6400 */
1142 COSTS_N_INSNS (4), /* fp_add */
1143 COSTS_N_INSNS (5), /* fp_mult_sf */
1144 COSTS_N_INSNS (5), /* fp_mult_df */
1145 COSTS_N_INSNS (32), /* fp_div_sf */
1146 COSTS_N_INSNS (32), /* fp_div_df */
1147 COSTS_N_INSNS (5), /* int_mult_si */
1148 COSTS_N_INSNS (5), /* int_mult_di */
1149 COSTS_N_INSNS (36), /* int_div_si */
1150 COSTS_N_INSNS (36), /* int_div_di */
1151 2, /* branch_cost */
1152 4 /* memory_latency */
1154 { /* P6600 */
1155 COSTS_N_INSNS (4), /* fp_add */
1156 COSTS_N_INSNS (5), /* fp_mult_sf */
1157 COSTS_N_INSNS (5), /* fp_mult_df */
1158 COSTS_N_INSNS (17), /* fp_div_sf */
1159 COSTS_N_INSNS (17), /* fp_div_df */
1160 COSTS_N_INSNS (5), /* int_mult_si */
1161 COSTS_N_INSNS (5), /* int_mult_di */
1162 COSTS_N_INSNS (8), /* int_div_si */
1163 COSTS_N_INSNS (8), /* int_div_di */
1164 2, /* branch_cost */
1165 4 /* memory_latency */
1169 static rtx mips_find_pic_call_symbol (rtx_insn *, rtx, bool);
1170 static int mips_register_move_cost (machine_mode, reg_class_t,
1171 reg_class_t);
1172 static unsigned int mips_function_arg_boundary (machine_mode, const_tree);
1173 static rtx mips_gen_const_int_vector_shuffle (machine_mode, int);
1175 /* This hash table keeps track of implicit "mips16" and "nomips16" attributes
1176 for -mflip_mips16. It maps decl names onto a boolean mode setting. */
1177 static GTY (()) hash_map<nofree_string_hash, bool> *mflip_mips16_htab;
1179 /* True if -mflip-mips16 should next add an attribute for the default MIPS16
1180 mode, false if it should next add an attribute for the opposite mode. */
1181 static GTY(()) bool mips16_flipper;
1183 /* DECL is a function that needs a default "mips16" or "nomips16" attribute
1184 for -mflip-mips16. Return true if it should use "mips16" and false if
1185 it should use "nomips16". */
1187 static bool
1188 mflip_mips16_use_mips16_p (tree decl)
1190 const char *name;
1191 bool base_is_mips16 = (mips_base_compression_flags & MASK_MIPS16) != 0;
1193 /* Use the opposite of the command-line setting for anonymous decls. */
1194 if (!DECL_NAME (decl))
1195 return !base_is_mips16;
1197 if (!mflip_mips16_htab)
1198 mflip_mips16_htab = hash_map<nofree_string_hash, bool>::create_ggc (37);
1200 name = IDENTIFIER_POINTER (DECL_NAME (decl));
1202 bool existed;
1203 bool *slot = &mflip_mips16_htab->get_or_insert (name, &existed);
1204 if (!existed)
1206 mips16_flipper = !mips16_flipper;
1207 *slot = mips16_flipper ? !base_is_mips16 : base_is_mips16;
1209 return *slot;
1212 /* Predicates to test for presence of "near"/"short_call" and "far"/"long_call"
1213 attributes on the given TYPE. */
1215 static bool
1216 mips_near_type_p (const_tree type)
1218 return (lookup_attribute ("short_call", TYPE_ATTRIBUTES (type)) != NULL
1219 || lookup_attribute ("near", TYPE_ATTRIBUTES (type)) != NULL);
1222 static bool
1223 mips_far_type_p (const_tree type)
1225 return (lookup_attribute ("long_call", TYPE_ATTRIBUTES (type)) != NULL
1226 || lookup_attribute ("far", TYPE_ATTRIBUTES (type)) != NULL);
1230 /* Check if the interrupt attribute is set for a function. */
1232 static bool
1233 mips_interrupt_type_p (tree type)
1235 return lookup_attribute ("interrupt", TYPE_ATTRIBUTES (type)) != NULL;
1238 /* Return the mask for the "interrupt" attribute. */
1240 static enum mips_int_mask
1241 mips_interrupt_mask (tree type)
1243 tree attr = lookup_attribute ("interrupt", TYPE_ATTRIBUTES (type));
1244 tree args, cst;
1245 const char *str;
1247 /* For missing attributes or no arguments then return 'eic' as a safe
1248 fallback. */
1249 if (attr == NULL)
1250 return INT_MASK_EIC;
1252 args = TREE_VALUE (attr);
1254 if (args == NULL)
1255 return INT_MASK_EIC;
1257 cst = TREE_VALUE (args);
1259 if (strcmp (TREE_STRING_POINTER (cst), "eic") == 0)
1260 return INT_MASK_EIC;
1262 /* The validation code in mips_handle_interrupt_attr guarantees that the
1263 argument is now in the form:
1264 vector=(sw0|sw1|hw0|hw1|hw2|hw3|hw4|hw5). */
1265 str = TREE_STRING_POINTER (cst);
1267 gcc_assert (strlen (str) == strlen ("vector=sw0"));
1269 if (str[7] == 's')
1270 return (enum mips_int_mask) (INT_MASK_SW0 + (str[9] - '0'));
1272 return (enum mips_int_mask) (INT_MASK_HW0 + (str[9] - '0'));
1275 /* Return the mips_shadow_set if the "use_shadow_register_set" attribute is
1276 set for a function. */
1278 static enum mips_shadow_set
1279 mips_use_shadow_register_set (tree type)
1281 tree attr = lookup_attribute ("use_shadow_register_set",
1282 TYPE_ATTRIBUTES (type));
1283 tree args;
1285 /* The validation code in mips_handle_use_shadow_register_set_attr guarantees
1286 that if an argument is present then it means: Assume the shadow register
1287 set has a valid stack pointer in it. */
1288 if (attr == NULL)
1289 return SHADOW_SET_NO;
1291 args = TREE_VALUE (attr);
1293 if (args == NULL)
1294 return SHADOW_SET_YES;
1296 return SHADOW_SET_INTSTACK;
1299 /* Check if the attribute to keep interrupts masked is set for a function. */
1301 static bool
1302 mips_keep_interrupts_masked_p (tree type)
1304 return lookup_attribute ("keep_interrupts_masked",
1305 TYPE_ATTRIBUTES (type)) != NULL;
1308 /* Check if the attribute to use debug exception return is set for
1309 a function. */
1311 static bool
1312 mips_use_debug_exception_return_p (tree type)
1314 return lookup_attribute ("use_debug_exception_return",
1315 TYPE_ATTRIBUTES (type)) != NULL;
1319 /* Verify the arguments to a code_readable attribute. */
1321 static tree
1322 mips_handle_code_readable_attr (tree *node ATTRIBUTE_UNUSED, tree name,
1323 tree args, int flags ATTRIBUTE_UNUSED,
1324 bool *no_add_attrs)
1326 if (!is_attribute_p ("code_readable", name) || args == NULL)
1327 return NULL_TREE;
1329 if (TREE_CODE (TREE_VALUE (args)) != STRING_CST)
1331 warning (OPT_Wattributes,
1332 "%qE attribute requires a string argument", name);
1333 *no_add_attrs = true;
1335 else if (strcmp (TREE_STRING_POINTER (TREE_VALUE (args)), "no") != 0
1336 && strcmp (TREE_STRING_POINTER (TREE_VALUE (args)), "pcrel") != 0
1337 && strcmp (TREE_STRING_POINTER (TREE_VALUE (args)), "yes") != 0)
1339 warning (OPT_Wattributes,
1340 "argument to %qE attribute is neither no, pcrel nor yes", name);
1341 *no_add_attrs = true;
1344 return NULL_TREE;
1347 /* Determine the code_readable setting for a function if it has one. Set
1348 *valid to true if we have a properly formed argument and
1349 return the result. If there's no argument, return GCC's default.
1350 Otherwise, leave valid false and return mips_base_code_readable. In
1351 that case the result should be unused anyway. */
1353 static enum mips_code_readable_setting
1354 mips_get_code_readable_attr (tree decl)
1356 tree attr;
1358 if (decl == NULL)
1359 return mips_base_code_readable;
1361 attr = lookup_attribute ("code_readable", DECL_ATTRIBUTES (decl));
1363 if (attr != NULL)
1365 if (TREE_VALUE (attr) != NULL_TREE)
1367 const char * str;
1369 str = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)));
1370 if (strcmp (str, "no") == 0)
1371 return CODE_READABLE_NO;
1372 else if (strcmp (str, "pcrel") == 0)
1373 return CODE_READABLE_PCREL;
1374 else if (strcmp (str, "yes") == 0)
1375 return CODE_READABLE_YES;
1377 /* mips_handle_code_readable_attr will have verified the
1378 arguments are correct before adding the attribute. */
1379 gcc_unreachable ();
1382 /* Just like GCC's default -mcode-readable= setting, the
1383 presence of the code_readable attribute implies that a
1384 function can read data from the instruction stream by
1385 default. */
1386 return CODE_READABLE_YES;
1389 return mips_base_code_readable;
1393 /* Return the set of compression modes that are explicitly required
1394 by the attributes in ATTRIBUTES. */
1396 static unsigned int
1397 mips_get_compress_on_flags (tree attributes)
1399 unsigned int flags = 0;
1401 if (lookup_attribute ("mips16", attributes) != NULL)
1402 flags |= MASK_MIPS16;
1404 if (lookup_attribute ("micromips", attributes) != NULL)
1405 flags |= MASK_MICROMIPS;
1407 return flags;
1410 /* Return the set of compression modes that are explicitly forbidden
1411 by the attributes in ATTRIBUTES. */
1413 static unsigned int
1414 mips_get_compress_off_flags (tree attributes)
1416 unsigned int flags = 0;
1418 if (lookup_attribute ("nocompression", attributes) != NULL)
1419 flags |= MASK_MIPS16 | MASK_MICROMIPS;
1421 if (lookup_attribute ("nomips16", attributes) != NULL)
1422 flags |= MASK_MIPS16;
1424 if (lookup_attribute ("nomicromips", attributes) != NULL)
1425 flags |= MASK_MICROMIPS;
1427 return flags;
1430 /* Return the compression mode that should be used for function DECL.
1431 Return the ambient setting if DECL is null. */
1433 static unsigned int
1434 mips_get_compress_mode (tree decl)
1436 unsigned int flags, force_on;
1438 flags = mips_base_compression_flags;
1439 if (decl)
1441 /* Nested functions must use the same frame pointer as their
1442 parent and must therefore use the same ISA mode. */
1443 tree parent = decl_function_context (decl);
1444 if (parent)
1445 decl = parent;
1446 force_on = mips_get_compress_on_flags (DECL_ATTRIBUTES (decl));
1447 if (force_on)
1448 return force_on;
1449 flags &= ~mips_get_compress_off_flags (DECL_ATTRIBUTES (decl));
1451 return flags;
1454 /* Return the attribute name associated with MASK_MIPS16 and MASK_MICROMIPS
1455 flags FLAGS. */
1457 static const char *
1458 mips_get_compress_on_name (unsigned int flags)
1460 if (flags == MASK_MIPS16)
1461 return "mips16";
1462 return "micromips";
1465 /* Return the attribute name that forbids MASK_MIPS16 and MASK_MICROMIPS
1466 flags FLAGS. */
1468 static const char *
1469 mips_get_compress_off_name (unsigned int flags)
1471 if (flags == MASK_MIPS16)
1472 return "nomips16";
1473 if (flags == MASK_MICROMIPS)
1474 return "nomicromips";
1475 return "nocompression";
1478 /* Implement TARGET_COMP_TYPE_ATTRIBUTES. */
1480 static int
1481 mips_comp_type_attributes (const_tree type1, const_tree type2)
1483 /* Disallow mixed near/far attributes. */
1484 if (mips_far_type_p (type1) && mips_near_type_p (type2))
1485 return 0;
1486 if (mips_near_type_p (type1) && mips_far_type_p (type2))
1487 return 0;
1488 return 1;
1491 /* Implement TARGET_INSERT_ATTRIBUTES. */
1493 static void
1494 mips_insert_attributes (tree decl, tree *attributes)
1496 const char *name;
1497 unsigned int compression_flags, nocompression_flags;
1499 /* Check for "mips16" and "nomips16" attributes. */
1500 compression_flags = mips_get_compress_on_flags (*attributes);
1501 nocompression_flags = mips_get_compress_off_flags (*attributes);
1503 if (TREE_CODE (decl) != FUNCTION_DECL)
1505 if (nocompression_flags)
1506 error ("%qs attribute only applies to functions",
1507 mips_get_compress_off_name (nocompression_flags));
1509 if (compression_flags)
1510 error ("%qs attribute only applies to functions",
1511 mips_get_compress_on_name (nocompression_flags));
1513 else
1515 compression_flags |= mips_get_compress_on_flags (DECL_ATTRIBUTES (decl));
1516 nocompression_flags |=
1517 mips_get_compress_off_flags (DECL_ATTRIBUTES (decl));
1519 if (compression_flags && nocompression_flags)
1520 error ("%qE cannot have both %qs and %qs attributes",
1521 DECL_NAME (decl), mips_get_compress_on_name (compression_flags),
1522 mips_get_compress_off_name (nocompression_flags));
1524 if (compression_flags & MASK_MIPS16
1525 && compression_flags & MASK_MICROMIPS)
1526 error ("%qE cannot have both %qs and %qs attributes",
1527 DECL_NAME (decl), "mips16", "micromips");
1529 if (TARGET_FLIP_MIPS16
1530 && !DECL_ARTIFICIAL (decl)
1531 && compression_flags == 0
1532 && nocompression_flags == 0)
1534 /* Implement -mflip-mips16. If DECL has neither a "nomips16" nor a
1535 "mips16" attribute, arbitrarily pick one. We must pick the same
1536 setting for duplicate declarations of a function. */
1537 name = mflip_mips16_use_mips16_p (decl) ? "mips16" : "nomips16";
1538 *attributes = tree_cons (get_identifier (name), NULL, *attributes);
1539 name = "nomicromips";
1540 *attributes = tree_cons (get_identifier (name), NULL, *attributes);
1545 /* Implement TARGET_MERGE_DECL_ATTRIBUTES. */
1547 static tree
1548 mips_merge_decl_attributes (tree olddecl, tree newdecl)
1550 unsigned int diff;
1552 diff = (mips_get_compress_on_flags (DECL_ATTRIBUTES (olddecl))
1553 ^ mips_get_compress_on_flags (DECL_ATTRIBUTES (newdecl)));
1554 if (diff)
1555 error ("%qE redeclared with conflicting %qs attributes",
1556 DECL_NAME (newdecl), mips_get_compress_on_name (diff));
1558 diff = (mips_get_compress_off_flags (DECL_ATTRIBUTES (olddecl))
1559 ^ mips_get_compress_off_flags (DECL_ATTRIBUTES (newdecl)));
1560 if (diff)
1561 error ("%qE redeclared with conflicting %qs attributes",
1562 DECL_NAME (newdecl), mips_get_compress_off_name (diff));
1564 return merge_attributes (DECL_ATTRIBUTES (olddecl),
1565 DECL_ATTRIBUTES (newdecl));
1568 /* Implement TARGET_CAN_INLINE_P. */
1570 static bool
1571 mips_can_inline_p (tree caller, tree callee)
1573 if (mips_get_compress_mode (callee) != mips_get_compress_mode (caller))
1574 return false;
1575 return default_target_can_inline_p (caller, callee);
1578 /* Handle an "interrupt" attribute with an optional argument. */
1580 static tree
1581 mips_handle_interrupt_attr (tree *node ATTRIBUTE_UNUSED, tree name, tree args,
1582 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
1584 /* Check for an argument. */
1585 if (is_attribute_p ("interrupt", name) && args != NULL)
1587 tree cst;
1589 cst = TREE_VALUE (args);
1590 if (TREE_CODE (cst) != STRING_CST)
1592 warning (OPT_Wattributes,
1593 "%qE attribute requires a string argument",
1594 name);
1595 *no_add_attrs = true;
1597 else if (strcmp (TREE_STRING_POINTER (cst), "eic") != 0
1598 && !startswith (TREE_STRING_POINTER (cst), "vector="))
1600 warning (OPT_Wattributes,
1601 "argument to %qE attribute is neither eic, nor "
1602 "%<vector=<line>%>", name);
1603 *no_add_attrs = true;
1605 else if (startswith (TREE_STRING_POINTER (cst), "vector="))
1607 const char *arg = TREE_STRING_POINTER (cst) + 7;
1609 /* Acceptable names are: sw0,sw1,hw0,hw1,hw2,hw3,hw4,hw5. */
1610 if (strlen (arg) != 3
1611 || (arg[0] != 's' && arg[0] != 'h')
1612 || arg[1] != 'w'
1613 || (arg[0] == 's' && arg[2] != '0' && arg[2] != '1')
1614 || (arg[0] == 'h' && (arg[2] < '0' || arg[2] > '5')))
1616 warning (OPT_Wattributes,
1617 "interrupt vector to %qE attribute is not "
1618 "%<vector=(sw0|sw1|hw0|hw1|hw2|hw3|hw4|hw5)%>",
1619 name);
1620 *no_add_attrs = true;
1624 return NULL_TREE;
1627 return NULL_TREE;
1630 /* Handle a "use_shadow_register_set" attribute with an optional argument. */
1632 static tree
1633 mips_handle_use_shadow_register_set_attr (tree *node ATTRIBUTE_UNUSED,
1634 tree name, tree args,
1635 int flags ATTRIBUTE_UNUSED,
1636 bool *no_add_attrs)
1638 /* Check for an argument. */
1639 if (is_attribute_p ("use_shadow_register_set", name) && args != NULL)
1641 tree cst;
1643 cst = TREE_VALUE (args);
1644 if (TREE_CODE (cst) != STRING_CST)
1646 warning (OPT_Wattributes,
1647 "%qE attribute requires a string argument",
1648 name);
1649 *no_add_attrs = true;
1651 else if (strcmp (TREE_STRING_POINTER (cst), "intstack") != 0)
1653 warning (OPT_Wattributes,
1654 "argument to %qE attribute is not intstack", name);
1655 *no_add_attrs = true;
1658 return NULL_TREE;
1661 return NULL_TREE;
1664 /* If X is a PLUS of a CONST_INT, return the two terms in *BASE_PTR
1665 and *OFFSET_PTR. Return X in *BASE_PTR and 0 in *OFFSET_PTR otherwise. */
1667 static void
1668 mips_split_plus (rtx x, rtx *base_ptr, HOST_WIDE_INT *offset_ptr)
1670 if (GET_CODE (x) == PLUS && CONST_INT_P (XEXP (x, 1)))
1672 *base_ptr = XEXP (x, 0);
1673 *offset_ptr = INTVAL (XEXP (x, 1));
1675 else
1677 *base_ptr = x;
1678 *offset_ptr = 0;
1682 static unsigned int mips_build_integer (struct mips_integer_op *,
1683 unsigned HOST_WIDE_INT);
1685 /* A subroutine of mips_build_integer, with the same interface.
1686 Assume that the final action in the sequence should be a left shift. */
1688 static unsigned int
1689 mips_build_shift (struct mips_integer_op *codes, HOST_WIDE_INT value)
1691 unsigned int i, shift;
1693 /* Shift VALUE right until its lowest bit is set. Shift arithmetically
1694 since signed numbers are easier to load than unsigned ones. */
1695 shift = 0;
1696 while ((value & 1) == 0)
1697 value /= 2, shift++;
1699 i = mips_build_integer (codes, value);
1700 codes[i].code = ASHIFT;
1701 codes[i].value = shift;
1702 return i + 1;
1705 /* As for mips_build_shift, but assume that the final action will be
1706 an IOR or PLUS operation. */
1708 static unsigned int
1709 mips_build_lower (struct mips_integer_op *codes, unsigned HOST_WIDE_INT value)
1711 unsigned HOST_WIDE_INT high;
1712 unsigned int i;
1714 high = value & ~(unsigned HOST_WIDE_INT) 0xffff;
1715 if (!LUI_OPERAND (high) && (value & 0x18000) == 0x18000)
1717 /* The constant is too complex to load with a simple LUI/ORI pair,
1718 so we want to give the recursive call as many trailing zeros as
1719 possible. In this case, we know bit 16 is set and that the
1720 low 16 bits form a negative number. If we subtract that number
1721 from VALUE, we will clear at least the lowest 17 bits, maybe more. */
1722 i = mips_build_integer (codes, CONST_HIGH_PART (value));
1723 codes[i].code = PLUS;
1724 codes[i].value = CONST_LOW_PART (value);
1726 else
1728 /* Either this is a simple LUI/ORI pair, or clearing the lowest 16
1729 bits gives a value with at least 17 trailing zeros. */
1730 i = mips_build_integer (codes, high);
1731 codes[i].code = IOR;
1732 codes[i].value = value & 0xffff;
1734 return i + 1;
1737 /* Fill CODES with a sequence of rtl operations to load VALUE.
1738 Return the number of operations needed. */
1740 static unsigned int
1741 mips_build_integer (struct mips_integer_op *codes,
1742 unsigned HOST_WIDE_INT value)
1744 if (SMALL_OPERAND (value)
1745 || SMALL_OPERAND_UNSIGNED (value)
1746 || LUI_OPERAND (value))
1748 /* The value can be loaded with a single instruction. */
1749 codes[0].code = UNKNOWN;
1750 codes[0].value = value;
1751 return 1;
1753 else if ((value & 1) != 0 || LUI_OPERAND (CONST_HIGH_PART (value)))
1755 /* Either the constant is a simple LUI/ORI combination or its
1756 lowest bit is set. We don't want to shift in this case. */
1757 return mips_build_lower (codes, value);
1759 else if ((value & 0xffff) == 0)
1761 /* The constant will need at least three actions. The lowest
1762 16 bits are clear, so the final action will be a shift. */
1763 return mips_build_shift (codes, value);
1765 else
1767 /* The final action could be a shift, add or inclusive OR.
1768 Rather than use a complex condition to select the best
1769 approach, try both mips_build_shift and mips_build_lower
1770 and pick the one that gives the shortest sequence.
1771 Note that this case is only used once per constant. */
1772 struct mips_integer_op alt_codes[MIPS_MAX_INTEGER_OPS];
1773 unsigned int cost, alt_cost;
1775 cost = mips_build_shift (codes, value);
1776 alt_cost = mips_build_lower (alt_codes, value);
1777 if (alt_cost < cost)
1779 memcpy (codes, alt_codes, alt_cost * sizeof (codes[0]));
1780 cost = alt_cost;
1782 return cost;
1786 /* Implement TARGET_LEGITIMATE_CONSTANT_P. */
1788 static bool
1789 mips_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
1791 return mips_const_insns (x) > 0;
1794 /* Return a SYMBOL_REF for a MIPS16 function called NAME. */
1796 static rtx
1797 mips16_stub_function (const char *name)
1799 rtx x;
1801 x = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
1802 SYMBOL_REF_FLAGS (x) |= (SYMBOL_FLAG_EXTERNAL | SYMBOL_FLAG_FUNCTION);
1803 return x;
1806 /* Return a legitimate call address for STUB, given that STUB is a MIPS16
1807 support function. */
1809 static rtx
1810 mips16_stub_call_address (mips_one_only_stub *stub)
1812 rtx fn = mips16_stub_function (stub->get_name ());
1813 SYMBOL_REF_FLAGS (fn) |= SYMBOL_FLAG_LOCAL;
1814 if (!call_insn_operand (fn, VOIDmode))
1815 fn = force_reg (Pmode, fn);
1816 return fn;
1819 /* A stub for moving the thread pointer into TLS_GET_TP_REGNUM. */
1821 class mips16_rdhwr_one_only_stub : public mips_one_only_stub
1823 virtual const char *get_name ();
1824 virtual void output_body ();
1827 const char *
1828 mips16_rdhwr_one_only_stub::get_name ()
1830 return "__mips16_rdhwr";
1833 void
1834 mips16_rdhwr_one_only_stub::output_body ()
1836 fprintf (asm_out_file,
1837 "\t.set\tpush\n"
1838 "\t.set\tmips32r2\n"
1839 "\t.set\tnoreorder\n"
1840 "\trdhwr\t$3,$29\n"
1841 "\t.set\tpop\n"
1842 "\tj\t$31\n");
1845 /* A stub for moving the FCSR into GET_FCSR_REGNUM. */
1846 class mips16_get_fcsr_one_only_stub : public mips_one_only_stub
1848 virtual const char *get_name ();
1849 virtual void output_body ();
1852 const char *
1853 mips16_get_fcsr_one_only_stub::get_name ()
1855 return "__mips16_get_fcsr";
1858 void
1859 mips16_get_fcsr_one_only_stub::output_body ()
1861 fprintf (asm_out_file,
1862 "\tcfc1\t%s,$31\n"
1863 "\tj\t$31\n", reg_names[GET_FCSR_REGNUM]);
1866 /* A stub for moving SET_FCSR_REGNUM into the FCSR. */
1867 class mips16_set_fcsr_one_only_stub : public mips_one_only_stub
1869 virtual const char *get_name ();
1870 virtual void output_body ();
1873 const char *
1874 mips16_set_fcsr_one_only_stub::get_name ()
1876 return "__mips16_set_fcsr";
1879 void
1880 mips16_set_fcsr_one_only_stub::output_body ()
1882 fprintf (asm_out_file,
1883 "\tctc1\t%s,$31\n"
1884 "\tj\t$31\n", reg_names[SET_FCSR_REGNUM]);
1887 /* Return true if symbols of type TYPE require a GOT access. */
1889 static bool
1890 mips_got_symbol_type_p (enum mips_symbol_type type)
1892 switch (type)
1894 case SYMBOL_GOT_PAGE_OFST:
1895 case SYMBOL_GOT_DISP:
1896 return true;
1898 default:
1899 return false;
1903 /* Return true if X is a thread-local symbol. */
1905 static bool
1906 mips_tls_symbol_p (rtx x)
1908 return GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x) != 0;
1911 /* Return true if SYMBOL_REF X is associated with a global symbol
1912 (in the STB_GLOBAL sense). */
1914 static bool
1915 mips_global_symbol_p (const_rtx x)
1917 const_tree decl = SYMBOL_REF_DECL (x);
1919 if (!decl)
1920 return !SYMBOL_REF_LOCAL_P (x) || SYMBOL_REF_EXTERNAL_P (x);
1922 /* Weakref symbols are not TREE_PUBLIC, but their targets are global
1923 or weak symbols. Relocations in the object file will be against
1924 the target symbol, so it's that symbol's binding that matters here. */
1925 return DECL_P (decl) && (TREE_PUBLIC (decl) || DECL_WEAK (decl));
1928 /* Return true if function X is a libgcc MIPS16 stub function. */
1930 static bool
1931 mips16_stub_function_p (const_rtx x)
1933 return (GET_CODE (x) == SYMBOL_REF
1934 && startswith (XSTR (x, 0), "__mips16_"));
1937 /* Return true if function X is a locally-defined and locally-binding
1938 MIPS16 function. */
1940 static bool
1941 mips16_local_function_p (const_rtx x)
1943 return (GET_CODE (x) == SYMBOL_REF
1944 && SYMBOL_REF_LOCAL_P (x)
1945 && !SYMBOL_REF_EXTERNAL_P (x)
1946 && (mips_get_compress_mode (SYMBOL_REF_DECL (x)) & MASK_MIPS16));
1949 /* Return true if SYMBOL_REF X binds locally. */
1951 static bool
1952 mips_symbol_binds_local_p (const_rtx x)
1954 return (SYMBOL_REF_DECL (x)
1955 ? targetm.binds_local_p (SYMBOL_REF_DECL (x))
1956 : SYMBOL_REF_LOCAL_P (x));
1959 /* Return true if OP is a constant vector with the number of units in MODE,
1960 and each unit has the same bit set. */
1962 bool
1963 mips_const_vector_bitimm_set_p (rtx op, machine_mode mode)
1965 if (GET_CODE (op) == CONST_VECTOR && op != CONST0_RTX (mode))
1967 unsigned HOST_WIDE_INT val = UINTVAL (CONST_VECTOR_ELT (op, 0));
1968 int vlog2 = exact_log2 (val & GET_MODE_MASK (GET_MODE_INNER (mode)));
1970 if (vlog2 != -1)
1972 gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
1973 gcc_assert (vlog2 >= 0 && vlog2 <= GET_MODE_UNIT_BITSIZE (mode) - 1);
1974 return mips_const_vector_same_val_p (op, mode);
1978 return false;
1981 /* Return true if OP is a constant vector with the number of units in MODE,
1982 and each unit has the same bit clear. */
1984 bool
1985 mips_const_vector_bitimm_clr_p (rtx op, machine_mode mode)
1987 if (GET_CODE (op) == CONST_VECTOR && op != CONSTM1_RTX (mode))
1989 unsigned HOST_WIDE_INT val = ~UINTVAL (CONST_VECTOR_ELT (op, 0));
1990 int vlog2 = exact_log2 (val & GET_MODE_MASK (GET_MODE_INNER (mode)));
1992 if (vlog2 != -1)
1994 gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
1995 gcc_assert (vlog2 >= 0 && vlog2 <= GET_MODE_UNIT_BITSIZE (mode) - 1);
1996 return mips_const_vector_same_val_p (op, mode);
2000 return false;
2003 /* Return true if OP is a constant vector with the number of units in MODE,
2004 and each unit has the same value. */
2006 bool
2007 mips_const_vector_same_val_p (rtx op, machine_mode mode)
2009 int i, nunits = GET_MODE_NUNITS (mode);
2010 rtx first;
2012 if (GET_CODE (op) != CONST_VECTOR || GET_MODE (op) != mode)
2013 return false;
2015 first = CONST_VECTOR_ELT (op, 0);
2016 for (i = 1; i < nunits; i++)
2017 if (!rtx_equal_p (first, CONST_VECTOR_ELT (op, i)))
2018 return false;
2020 return true;
2023 /* Return true if OP is a constant vector with the number of units in MODE,
2024 and each unit has the same value as well as replicated bytes in the value.
2027 bool
2028 mips_const_vector_same_bytes_p (rtx op, machine_mode mode)
2030 int i, bytes;
2031 HOST_WIDE_INT val, first_byte;
2032 rtx first;
2034 if (!mips_const_vector_same_val_p (op, mode))
2035 return false;
2037 first = CONST_VECTOR_ELT (op, 0);
2038 bytes = GET_MODE_UNIT_SIZE (mode);
2039 val = INTVAL (first);
2040 first_byte = val & 0xff;
2041 for (i = 1; i < bytes; i++)
2043 val >>= 8;
2044 if ((val & 0xff) != first_byte)
2045 return false;
2048 return true;
2051 /* Return true if OP is a constant vector with the number of units in MODE,
2052 and each unit has the same integer value in the range [LOW, HIGH]. */
2054 bool
2055 mips_const_vector_same_int_p (rtx op, machine_mode mode, HOST_WIDE_INT low,
2056 HOST_WIDE_INT high)
2058 HOST_WIDE_INT value;
2059 rtx elem0;
2061 if (!mips_const_vector_same_val_p (op, mode))
2062 return false;
2064 elem0 = CONST_VECTOR_ELT (op, 0);
2065 if (!CONST_INT_P (elem0))
2066 return false;
2068 value = INTVAL (elem0);
2069 return (value >= low && value <= high);
2072 /* Return true if OP is a constant vector with repeated 4-element sets
2073 in mode MODE. */
2075 bool
2076 mips_const_vector_shuffle_set_p (rtx op, machine_mode mode)
2078 int nunits = GET_MODE_NUNITS (mode);
2079 int nsets = nunits / 4;
2080 int set = 0;
2081 int i, j;
2083 /* Check if we have the same 4-element sets. */
2084 for (j = 0; j < nsets; j++, set = 4 * j)
2085 for (i = 0; i < 4; i++)
2086 if ((INTVAL (XVECEXP (op, 0, i))
2087 != (INTVAL (XVECEXP (op, 0, set + i)) - set))
2088 || !IN_RANGE (INTVAL (XVECEXP (op, 0, set + i)), 0, set + 3))
2089 return false;
2090 return true;
2093 /* Return true if rtx constants of mode MODE should be put into a small
2094 data section. */
2096 static bool
2097 mips_rtx_constant_in_small_data_p (machine_mode mode)
2099 return (!TARGET_EMBEDDED_DATA
2100 && TARGET_LOCAL_SDATA
2101 && GET_MODE_SIZE (mode) <= mips_small_data_threshold);
2104 /* Return true if X should not be moved directly into register $25.
2105 We need this because many versions of GAS will treat "la $25,foo" as
2106 part of a call sequence and so allow a global "foo" to be lazily bound. */
2108 bool
2109 mips_dangerous_for_la25_p (rtx x)
2111 return (!TARGET_EXPLICIT_RELOCS
2112 && TARGET_USE_GOT
2113 && GET_CODE (x) == SYMBOL_REF
2114 && mips_global_symbol_p (x));
2117 /* Return true if calls to X might need $25 to be valid on entry. */
2119 bool
2120 mips_use_pic_fn_addr_reg_p (const_rtx x)
2122 if (!TARGET_USE_PIC_FN_ADDR_REG)
2123 return false;
2125 /* MIPS16 stub functions are guaranteed not to use $25. */
2126 if (mips16_stub_function_p (x))
2127 return false;
2129 if (GET_CODE (x) == SYMBOL_REF)
2131 /* If PLTs and copy relocations are available, the static linker
2132 will make sure that $25 is valid on entry to the target function. */
2133 if (TARGET_ABICALLS_PIC0)
2134 return false;
2136 /* Locally-defined functions use absolute accesses to set up
2137 the global pointer. */
2138 if (TARGET_ABSOLUTE_ABICALLS
2139 && mips_symbol_binds_local_p (x)
2140 && !SYMBOL_REF_EXTERNAL_P (x))
2141 return false;
2144 return true;
2147 /* Return the method that should be used to access SYMBOL_REF or
2148 LABEL_REF X in context CONTEXT. */
2150 static enum mips_symbol_type
2151 mips_classify_symbol (const_rtx x, enum mips_symbol_context context)
2153 if (TARGET_RTP_PIC)
2154 return SYMBOL_GOT_DISP;
2156 if (GET_CODE (x) == LABEL_REF)
2158 /* Only return SYMBOL_PC_RELATIVE if we are generating MIPS16
2159 code and if we know that the label is in the current function's
2160 text section. LABEL_REFs are used for jump tables as well as
2161 text labels, so we must check whether jump tables live in the
2162 text section. */
2163 if (TARGET_MIPS16_SHORT_JUMP_TABLES
2164 && !LABEL_REF_NONLOCAL_P (x))
2165 return SYMBOL_PC_RELATIVE;
2167 if (TARGET_ABICALLS && !TARGET_ABSOLUTE_ABICALLS)
2168 return SYMBOL_GOT_PAGE_OFST;
2170 return SYMBOL_ABSOLUTE;
2173 gcc_assert (GET_CODE (x) == SYMBOL_REF);
2175 if (SYMBOL_REF_TLS_MODEL (x))
2176 return SYMBOL_TLS;
2178 if (CONSTANT_POOL_ADDRESS_P (x))
2180 if (TARGET_MIPS16_TEXT_LOADS)
2181 return SYMBOL_PC_RELATIVE;
2183 if (TARGET_MIPS16_PCREL_LOADS && context == SYMBOL_CONTEXT_MEM)
2184 return SYMBOL_PC_RELATIVE;
2186 if (mips_rtx_constant_in_small_data_p (get_pool_mode (x)))
2187 return SYMBOL_GP_RELATIVE;
2190 /* Do not use small-data accesses for weak symbols; they may end up
2191 being zero. */
2192 if (TARGET_GPOPT && SYMBOL_REF_SMALL_P (x) && !SYMBOL_REF_WEAK (x))
2193 return SYMBOL_GP_RELATIVE;
2195 /* Don't use GOT accesses for locally-binding symbols when -mno-shared
2196 is in effect. */
2197 if (TARGET_ABICALLS_PIC2
2198 && !(TARGET_ABSOLUTE_ABICALLS && mips_symbol_binds_local_p (x)))
2200 /* There are three cases to consider:
2202 - o32 PIC (either with or without explicit relocs)
2203 - n32/n64 PIC without explicit relocs
2204 - n32/n64 PIC with explicit relocs
2206 In the first case, both local and global accesses will use an
2207 R_MIPS_GOT16 relocation. We must correctly predict which of
2208 the two semantics (local or global) the assembler and linker
2209 will apply. The choice depends on the symbol's binding rather
2210 than its visibility.
2212 In the second case, the assembler will not use R_MIPS_GOT16
2213 relocations, but it chooses between local and global accesses
2214 in the same way as for o32 PIC.
2216 In the third case we have more freedom since both forms of
2217 access will work for any kind of symbol. However, there seems
2218 little point in doing things differently. */
2219 if (mips_global_symbol_p (x))
2220 return SYMBOL_GOT_DISP;
2222 return SYMBOL_GOT_PAGE_OFST;
2225 return SYMBOL_ABSOLUTE;
2228 /* Classify the base of symbolic expression X, given that X appears in
2229 context CONTEXT. */
2231 static enum mips_symbol_type
2232 mips_classify_symbolic_expression (rtx x, enum mips_symbol_context context)
2234 rtx offset;
2236 split_const (x, &x, &offset);
2237 if (UNSPEC_ADDRESS_P (x))
2238 return UNSPEC_ADDRESS_TYPE (x);
2240 return mips_classify_symbol (x, context);
2243 /* Return true if OFFSET is within the range [0, ALIGN), where ALIGN
2244 is the alignment in bytes of SYMBOL_REF X. */
2246 static bool
2247 mips_offset_within_alignment_p (rtx x, HOST_WIDE_INT offset)
2249 HOST_WIDE_INT align;
2251 align = SYMBOL_REF_DECL (x) ? DECL_ALIGN_UNIT (SYMBOL_REF_DECL (x)) : 1;
2252 return IN_RANGE (offset, 0, align - 1);
2255 /* Return true if X is a symbolic constant that can be used in context
2256 CONTEXT. If it is, store the type of the symbol in *SYMBOL_TYPE. */
2258 bool
2259 mips_symbolic_constant_p (rtx x, enum mips_symbol_context context,
2260 enum mips_symbol_type *symbol_type)
2262 rtx offset;
2264 split_const (x, &x, &offset);
2265 if (UNSPEC_ADDRESS_P (x))
2267 *symbol_type = UNSPEC_ADDRESS_TYPE (x);
2268 x = UNSPEC_ADDRESS (x);
2270 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF)
2272 *symbol_type = mips_classify_symbol (x, context);
2273 if (*symbol_type == SYMBOL_TLS)
2274 return false;
2276 else
2277 return false;
2279 if (offset == const0_rtx)
2280 return true;
2282 /* Check whether a nonzero offset is valid for the underlying
2283 relocations. */
2284 switch (*symbol_type)
2286 case SYMBOL_ABSOLUTE:
2287 case SYMBOL_64_HIGH:
2288 case SYMBOL_64_MID:
2289 case SYMBOL_64_LOW:
2290 /* If the target has 64-bit pointers and the object file only
2291 supports 32-bit symbols, the values of those symbols will be
2292 sign-extended. In this case we can't allow an arbitrary offset
2293 in case the 32-bit value X + OFFSET has a different sign from X. */
2294 if (Pmode == DImode && !ABI_HAS_64BIT_SYMBOLS)
2295 return offset_within_block_p (x, INTVAL (offset));
2297 /* In other cases the relocations can handle any offset. */
2298 return true;
2300 case SYMBOL_PC_RELATIVE:
2301 /* Allow constant pool references to be converted to LABEL+CONSTANT.
2302 In this case, we no longer have access to the underlying constant,
2303 but the original symbol-based access was known to be valid. */
2304 if (GET_CODE (x) == LABEL_REF)
2305 return true;
2307 /* Fall through. */
2309 case SYMBOL_GP_RELATIVE:
2310 /* Make sure that the offset refers to something within the
2311 same object block. This should guarantee that the final
2312 PC- or GP-relative offset is within the 16-bit limit. */
2313 return offset_within_block_p (x, INTVAL (offset));
2315 case SYMBOL_GOT_PAGE_OFST:
2316 case SYMBOL_GOTOFF_PAGE:
2317 /* If the symbol is global, the GOT entry will contain the symbol's
2318 address, and we will apply a 16-bit offset after loading it.
2319 If the symbol is local, the linker should provide enough local
2320 GOT entries for a 16-bit offset, but larger offsets may lead
2321 to GOT overflow. */
2322 return SMALL_INT (offset);
2324 case SYMBOL_TPREL:
2325 case SYMBOL_DTPREL:
2326 /* There is no carry between the HI and LO REL relocations, so the
2327 offset is only valid if we know it won't lead to such a carry. */
2328 return mips_offset_within_alignment_p (x, INTVAL (offset));
2330 case SYMBOL_GOT_DISP:
2331 case SYMBOL_GOTOFF_DISP:
2332 case SYMBOL_GOTOFF_CALL:
2333 case SYMBOL_GOTOFF_LOADGP:
2334 case SYMBOL_TLSGD:
2335 case SYMBOL_TLSLDM:
2336 case SYMBOL_GOTTPREL:
2337 case SYMBOL_TLS:
2338 case SYMBOL_HALF:
2339 return false;
2341 gcc_unreachable ();
2344 /* Like mips_symbol_insns, but treat extended MIPS16 instructions as a
2345 single instruction. We rely on the fact that, in the worst case,
2346 all instructions involved in a MIPS16 address calculation are usually
2347 extended ones. */
2349 static int
2350 mips_symbol_insns_1 (enum mips_symbol_type type, machine_mode mode)
2352 if (mips_use_pcrel_pool_p[(int) type])
2354 if (mode == MAX_MACHINE_MODE)
2355 /* LEAs will be converted into constant-pool references by
2356 mips_reorg. */
2357 type = SYMBOL_PC_RELATIVE;
2358 else
2359 /* The constant must be loaded and then dereferenced. */
2360 return 0;
2363 switch (type)
2365 case SYMBOL_ABSOLUTE:
2366 /* When using 64-bit symbols, we need 5 preparatory instructions,
2367 such as:
2369 lui $at,%highest(symbol)
2370 daddiu $at,$at,%higher(symbol)
2371 dsll $at,$at,16
2372 daddiu $at,$at,%hi(symbol)
2373 dsll $at,$at,16
2375 The final address is then $at + %lo(symbol). With 32-bit
2376 symbols we just need a preparatory LUI for normal mode and
2377 a preparatory LI and SLL for MIPS16. */
2378 return ABI_HAS_64BIT_SYMBOLS
2380 : (TARGET_MIPS16 && !ISA_HAS_MIPS16E2) ? 3 : 2;
2382 case SYMBOL_GP_RELATIVE:
2383 /* Treat GP-relative accesses as taking a single instruction on
2384 MIPS16 too; the copy of $gp can often be shared. */
2385 return 1;
2387 case SYMBOL_PC_RELATIVE:
2388 /* PC-relative constants can be only be used with ADDIUPC,
2389 DADDIUPC, LWPC and LDPC. */
2390 if (mode == MAX_MACHINE_MODE
2391 || GET_MODE_SIZE (mode) == 4
2392 || GET_MODE_SIZE (mode) == 8)
2393 return 1;
2395 /* The constant must be loaded using ADDIUPC or DADDIUPC first. */
2396 return 0;
2398 case SYMBOL_GOT_DISP:
2399 /* The constant will have to be loaded from the GOT before it
2400 is used in an address. */
2401 if (mode != MAX_MACHINE_MODE)
2402 return 0;
2404 /* Fall through. */
2406 case SYMBOL_GOT_PAGE_OFST:
2407 /* Unless -funit-at-a-time is in effect, we can't be sure whether the
2408 local/global classification is accurate. The worst cases are:
2410 (1) For local symbols when generating o32 or o64 code. The assembler
2411 will use:
2413 lw $at,%got(symbol)
2416 ...and the final address will be $at + %lo(symbol).
2418 (2) For global symbols when -mxgot. The assembler will use:
2420 lui $at,%got_hi(symbol)
2421 (d)addu $at,$at,$gp
2423 ...and the final address will be $at + %got_lo(symbol). */
2424 return 3;
2426 case SYMBOL_GOTOFF_PAGE:
2427 case SYMBOL_GOTOFF_DISP:
2428 case SYMBOL_GOTOFF_CALL:
2429 case SYMBOL_GOTOFF_LOADGP:
2430 case SYMBOL_64_HIGH:
2431 case SYMBOL_64_MID:
2432 case SYMBOL_64_LOW:
2433 case SYMBOL_TLSGD:
2434 case SYMBOL_TLSLDM:
2435 case SYMBOL_DTPREL:
2436 case SYMBOL_GOTTPREL:
2437 case SYMBOL_TPREL:
2438 case SYMBOL_HALF:
2439 /* A 16-bit constant formed by a single relocation, or a 32-bit
2440 constant formed from a high 16-bit relocation and a low 16-bit
2441 relocation. Use mips_split_p to determine which. 32-bit
2442 constants need an "lui; addiu" sequence for normal mode and
2443 an "li; sll; addiu" sequence for MIPS16 mode. */
2444 return !mips_split_p[type] ? 1 : TARGET_MIPS16 ? 3 : 2;
2446 case SYMBOL_TLS:
2447 /* We don't treat a bare TLS symbol as a constant. */
2448 return 0;
2450 gcc_unreachable ();
2453 /* If MODE is MAX_MACHINE_MODE, return the number of instructions needed
2454 to load symbols of type TYPE into a register. Return 0 if the given
2455 type of symbol cannot be used as an immediate operand.
2457 Otherwise, return the number of instructions needed to load or store
2458 values of mode MODE to or from addresses of type TYPE. Return 0 if
2459 the given type of symbol is not valid in addresses.
2461 In both cases, instruction counts are based off BASE_INSN_LENGTH. */
2463 static int
2464 mips_symbol_insns (enum mips_symbol_type type, machine_mode mode)
2466 /* MSA LD.* and ST.* cannot support loading symbols via an immediate
2467 operand. */
2468 if (mode != MAX_MACHINE_MODE && MSA_SUPPORTED_MODE_P (mode))
2469 return 0;
2471 return mips_symbol_insns_1 (type, mode) * (TARGET_MIPS16 ? 2 : 1);
2474 /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
2476 static bool
2477 mips_cannot_force_const_mem (machine_mode mode, rtx x)
2479 enum mips_symbol_type type;
2480 rtx base, offset;
2482 /* There is no assembler syntax for expressing an address-sized
2483 high part. */
2484 if (GET_CODE (x) == HIGH)
2485 return true;
2487 /* As an optimization, reject constants that mips_legitimize_move
2488 can expand inline.
2490 Suppose we have a multi-instruction sequence that loads constant C
2491 into register R. If R does not get allocated a hard register, and
2492 R is used in an operand that allows both registers and memory
2493 references, reload will consider forcing C into memory and using
2494 one of the instruction's memory alternatives. Returning false
2495 here will force it to use an input reload instead. */
2496 if ((CONST_INT_P (x) || GET_CODE (x) == CONST_VECTOR)
2497 && mips_legitimate_constant_p (mode, x))
2498 return true;
2500 split_const (x, &base, &offset);
2501 if (mips_symbolic_constant_p (base, SYMBOL_CONTEXT_LEA, &type))
2503 /* See whether we explicitly want these symbols in the pool. */
2504 if (mips_use_pcrel_pool_p[(int) type])
2505 return false;
2507 /* The same optimization as for CONST_INT. */
2508 if (SMALL_INT (offset) && mips_symbol_insns (type, MAX_MACHINE_MODE) > 0)
2509 return true;
2511 /* If MIPS16 constant pools live in the text section, they should
2512 not refer to anything that might need run-time relocation. */
2513 if (TARGET_MIPS16_PCREL_LOADS && mips_got_symbol_type_p (type))
2514 return true;
2517 /* TLS symbols must be computed by mips_legitimize_move. */
2518 if (tls_referenced_p (x))
2519 return true;
2521 return false;
2524 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. We can't use blocks for
2525 constants when we're using a per-function constant pool. */
2527 static bool
2528 mips_use_blocks_for_constant_p (machine_mode mode ATTRIBUTE_UNUSED,
2529 const_rtx x ATTRIBUTE_UNUSED)
2531 return !TARGET_MIPS16_PCREL_LOADS;
2534 /* Return true if register REGNO is a valid base register for mode MODE.
2535 STRICT_P is true if REG_OK_STRICT is in effect. */
2538 mips_regno_mode_ok_for_base_p (int regno, machine_mode mode,
2539 bool strict_p)
2541 if (!HARD_REGISTER_NUM_P (regno))
2543 if (!strict_p)
2544 return true;
2545 regno = reg_renumber[regno];
2548 /* These fake registers will be eliminated to either the stack or
2549 hard frame pointer, both of which are usually valid base registers.
2550 Reload deals with the cases where the eliminated form isn't valid. */
2551 if (regno == ARG_POINTER_REGNUM || regno == FRAME_POINTER_REGNUM)
2552 return true;
2554 /* In MIPS16 mode, the stack pointer can only address word and doubleword
2555 values, nothing smaller. */
2556 if (TARGET_MIPS16 && regno == STACK_POINTER_REGNUM)
2557 return GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8;
2559 if (MIPS16_GP_LOADS && regno == GLOBAL_POINTER_REGNUM)
2560 return (UNITS_PER_WORD > 4 ? GET_MODE_SIZE (mode) <= 4 : true);
2562 return TARGET_MIPS16 ? M16_REG_P (regno) : GP_REG_P (regno);
2565 /* Return true if X is a valid base register for mode MODE.
2566 STRICT_P is true if REG_OK_STRICT is in effect. */
2568 static bool
2569 mips_valid_base_register_p (rtx x, machine_mode mode, bool strict_p)
2571 if (!strict_p && GET_CODE (x) == SUBREG)
2572 x = SUBREG_REG (x);
2574 return (REG_P (x)
2575 && mips_regno_mode_ok_for_base_p (REGNO (x), mode, strict_p));
2578 /* Return true if, for every base register BASE_REG, (plus BASE_REG X)
2579 can address a value of mode MODE. */
2581 static bool
2582 mips_valid_offset_p (rtx x, machine_mode mode)
2584 /* Check that X is a signed 16-bit number. */
2585 if (!const_arith_operand (x, Pmode))
2586 return false;
2588 /* We may need to split multiword moves, so make sure that every word
2589 is accessible. */
2590 if (GET_MODE_SIZE (mode) > UNITS_PER_WORD
2591 && !SMALL_OPERAND (INTVAL (x) + GET_MODE_SIZE (mode) - UNITS_PER_WORD))
2592 return false;
2594 /* MSA LD.* and ST.* supports 10-bit signed offsets. */
2595 if (MSA_SUPPORTED_MODE_P (mode)
2596 && !mips_signed_immediate_p (INTVAL (x), 10,
2597 mips_ldst_scaled_shift (mode)))
2598 return false;
2600 return true;
2603 /* Return true if a LO_SUM can address a value of mode MODE when the
2604 LO_SUM symbol has type SYMBOL_TYPE. */
2606 static bool
2607 mips_valid_lo_sum_p (enum mips_symbol_type symbol_type, machine_mode mode)
2609 /* Check that symbols of type SYMBOL_TYPE can be used to access values
2610 of mode MODE. */
2611 if (mips_symbol_insns (symbol_type, mode) == 0)
2612 return false;
2614 /* Check that there is a known low-part relocation. */
2615 if (mips_lo_relocs[symbol_type] == NULL)
2616 return false;
2618 /* We may need to split multiword moves, so make sure that each word
2619 can be accessed without inducing a carry. This is mainly needed
2620 for o64, which has historically only guaranteed 64-bit alignment
2621 for 128-bit types. */
2622 if (GET_MODE_SIZE (mode) > UNITS_PER_WORD
2623 && GET_MODE_BITSIZE (mode) > GET_MODE_ALIGNMENT (mode))
2624 return false;
2626 /* MSA LD.* and ST.* cannot support loading symbols via %lo($base). */
2627 if (MSA_SUPPORTED_MODE_P (mode))
2628 return false;
2630 return true;
2633 /* Return true if X is a valid address for machine mode MODE. If it is,
2634 fill in INFO appropriately. STRICT_P is true if REG_OK_STRICT is in
2635 effect. */
2637 static bool
2638 mips_classify_address (struct mips_address_info *info, rtx x,
2639 machine_mode mode, bool strict_p)
2641 switch (GET_CODE (x))
2643 case REG:
2644 case SUBREG:
2645 info->type = ADDRESS_REG;
2646 info->reg = x;
2647 info->offset = const0_rtx;
2648 return mips_valid_base_register_p (info->reg, mode, strict_p);
2650 case PLUS:
2651 info->type = ADDRESS_REG;
2652 info->reg = XEXP (x, 0);
2653 info->offset = XEXP (x, 1);
2654 return (mips_valid_base_register_p (info->reg, mode, strict_p)
2655 && mips_valid_offset_p (info->offset, mode));
2657 case LO_SUM:
2658 info->type = ADDRESS_LO_SUM;
2659 info->reg = XEXP (x, 0);
2660 info->offset = XEXP (x, 1);
2661 /* We have to trust the creator of the LO_SUM to do something vaguely
2662 sane. Target-independent code that creates a LO_SUM should also
2663 create and verify the matching HIGH. Target-independent code that
2664 adds an offset to a LO_SUM must prove that the offset will not
2665 induce a carry. Failure to do either of these things would be
2666 a bug, and we are not required to check for it here. The MIPS
2667 backend itself should only create LO_SUMs for valid symbolic
2668 constants, with the high part being either a HIGH or a copy
2669 of _gp. */
2670 info->symbol_type
2671 = mips_classify_symbolic_expression (info->offset, SYMBOL_CONTEXT_MEM);
2672 return (mips_valid_base_register_p (info->reg, mode, strict_p)
2673 && mips_valid_lo_sum_p (info->symbol_type, mode));
2675 case CONST_INT:
2676 /* Small-integer addresses don't occur very often, but they
2677 are legitimate if $0 is a valid base register. */
2678 info->type = ADDRESS_CONST_INT;
2679 return !TARGET_MIPS16 && SMALL_INT (x);
2681 case CONST:
2682 case LABEL_REF:
2683 case SYMBOL_REF:
2684 info->type = ADDRESS_SYMBOLIC;
2685 return (mips_symbolic_constant_p (x, SYMBOL_CONTEXT_MEM,
2686 &info->symbol_type)
2687 && mips_symbol_insns (info->symbol_type, mode) > 0
2688 && !mips_split_p[info->symbol_type]);
2690 default:
2691 return false;
2695 /* Implement TARGET_LEGITIMATE_ADDRESS_P. */
2697 static bool
2698 mips_legitimate_address_p (machine_mode mode, rtx x, bool strict_p,
2699 code_helper = ERROR_MARK)
2701 struct mips_address_info addr;
2703 return mips_classify_address (&addr, x, mode, strict_p);
2706 /* Return true if X is a legitimate $sp-based address for mode MODE. */
2708 bool
2709 mips_stack_address_p (rtx x, machine_mode mode)
2711 struct mips_address_info addr;
2713 return (mips_classify_address (&addr, x, mode, false)
2714 && addr.type == ADDRESS_REG
2715 && addr.reg == stack_pointer_rtx);
2718 /* Return true if ADDR matches the pattern for the LWXS load scaled indexed
2719 address instruction. Note that such addresses are not considered
2720 legitimate in the TARGET_LEGITIMATE_ADDRESS_P sense, because their use
2721 is so restricted. */
2723 static bool
2724 mips_lwxs_address_p (rtx addr)
2726 if (ISA_HAS_LWXS
2727 && GET_CODE (addr) == PLUS
2728 && REG_P (XEXP (addr, 1)))
2730 rtx offset = XEXP (addr, 0);
2731 if (GET_CODE (offset) == MULT
2732 && REG_P (XEXP (offset, 0))
2733 && CONST_INT_P (XEXP (offset, 1))
2734 && INTVAL (XEXP (offset, 1)) == 4)
2735 return true;
2737 return false;
2740 /* Return true if ADDR matches the pattern for the L{B,H,W,D}{,U}X load
2741 indexed address instruction. Note that such addresses are
2742 not considered legitimate in the TARGET_LEGITIMATE_ADDRESS_P
2743 sense, because their use is so restricted. */
2745 static bool
2746 mips_lx_address_p (rtx addr, machine_mode mode)
2748 if (GET_CODE (addr) != PLUS
2749 || !REG_P (XEXP (addr, 0))
2750 || !REG_P (XEXP (addr, 1)))
2751 return false;
2752 if (ISA_HAS_LBX && mode == QImode)
2753 return true;
2754 if (ISA_HAS_LHX && mode == HImode)
2755 return true;
2756 if (ISA_HAS_LWX && mode == SImode)
2757 return true;
2758 if (ISA_HAS_LDX && mode == DImode)
2759 return true;
2760 if (MSA_SUPPORTED_MODE_P (mode))
2761 return true;
2762 return false;
2765 /* Return true if a value at OFFSET bytes from base register BASE can be
2766 accessed using an unextended MIPS16 instruction. MODE is the mode of
2767 the value.
2769 Usually the offset in an unextended instruction is a 5-bit field.
2770 The offset is unsigned and shifted left once for LH and SH, twice
2771 for LW and SW, and so on. An exception is LWSP and SWSP, which have
2772 an 8-bit immediate field that's shifted left twice. */
2774 static bool
2775 mips16_unextended_reference_p (machine_mode mode, rtx base,
2776 unsigned HOST_WIDE_INT offset)
2778 if (mode != BLKmode && offset % GET_MODE_SIZE (mode) == 0
2779 && REGNO (base) != GLOBAL_POINTER_REGNUM)
2781 if (GET_MODE_SIZE (mode) == 4 && base == stack_pointer_rtx)
2782 return offset < 256U * GET_MODE_SIZE (mode);
2783 return offset < 32U * GET_MODE_SIZE (mode);
2785 return false;
2788 /* Return the number of instructions needed to load or store a value
2789 of mode MODE at address X, assuming that BASE_INSN_LENGTH is the
2790 length of one instruction. Return 0 if X isn't valid for MODE.
2791 Assume that multiword moves may need to be split into word moves
2792 if MIGHT_SPLIT_P, otherwise assume that a single load or store is
2793 enough. */
2796 mips_address_insns (rtx x, machine_mode mode, bool might_split_p)
2798 struct mips_address_info addr;
2799 int factor;
2800 bool msa_p = (!might_split_p && MSA_SUPPORTED_MODE_P (mode));
2802 /* BLKmode is used for single unaligned loads and stores and should
2803 not count as a multiword mode. (GET_MODE_SIZE (BLKmode) is pretty
2804 meaningless, so we have to single it out as a special case one way
2805 or the other.) */
2806 if (mode != BLKmode && might_split_p)
2807 factor = (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
2808 else
2809 factor = 1;
2811 if (mips_classify_address (&addr, x, mode, false))
2812 switch (addr.type)
2814 case ADDRESS_REG:
2815 if (msa_p)
2817 /* MSA LD.* and ST.* supports 10-bit signed offsets. */
2818 if (mips_signed_immediate_p (INTVAL (addr.offset), 10,
2819 mips_ldst_scaled_shift (mode)))
2820 return 1;
2821 else
2822 return 0;
2824 if (TARGET_MIPS16
2825 && !mips16_unextended_reference_p (mode, addr.reg,
2826 UINTVAL (addr.offset)))
2827 return factor * 2;
2828 return factor;
2830 case ADDRESS_LO_SUM:
2831 return msa_p ? 0 : TARGET_MIPS16 ? factor * 2 : factor;
2833 case ADDRESS_CONST_INT:
2834 return msa_p ? 0 : factor;
2836 case ADDRESS_SYMBOLIC:
2837 return msa_p ? 0 : factor * mips_symbol_insns (addr.symbol_type, mode);
2839 return 0;
2842 /* Return true if X fits within an unsigned field of BITS bits that is
2843 shifted left SHIFT bits before being used. */
2845 bool
2846 mips_unsigned_immediate_p (unsigned HOST_WIDE_INT x, int bits, int shift = 0)
2848 return (x & ((1 << shift) - 1)) == 0 && x < ((unsigned) 1 << (shift + bits));
2851 /* Return true if X fits within a signed field of BITS bits that is
2852 shifted left SHIFT bits before being used. */
2854 bool
2855 mips_signed_immediate_p (unsigned HOST_WIDE_INT x, int bits, int shift = 0)
2857 x += 1 << (bits + shift - 1);
2858 return mips_unsigned_immediate_p (x, bits, shift);
2861 /* Return the scale shift that applied to MSA LD/ST address offset. */
2864 mips_ldst_scaled_shift (machine_mode mode)
2866 int shift = exact_log2 (GET_MODE_UNIT_SIZE (mode));
2868 if (shift < 0 || shift > 8)
2869 gcc_unreachable ();
2871 return shift;
2874 /* Return true if X is legitimate for accessing values of mode MODE,
2875 if it is based on a MIPS16 register, and if the offset satisfies
2876 OFFSET_PREDICATE. */
2878 bool
2879 m16_based_address_p (rtx x, machine_mode mode,
2880 insn_operand_predicate_fn offset_predicate)
2882 struct mips_address_info addr;
2884 return (mips_classify_address (&addr, x, mode, false)
2885 && addr.type == ADDRESS_REG
2886 && M16_REG_P (REGNO (addr.reg))
2887 && offset_predicate (addr.offset, mode));
2890 /* Return true if X is a legitimate address that conforms to the requirements
2891 for a microMIPS LWSP or SWSP insn. */
2893 bool
2894 lwsp_swsp_address_p (rtx x, machine_mode mode)
2896 struct mips_address_info addr;
2898 return (mips_classify_address (&addr, x, mode, false)
2899 && addr.type == ADDRESS_REG
2900 && REGNO (addr.reg) == STACK_POINTER_REGNUM
2901 && uw5_operand (addr.offset, mode));
2904 /* Return true if X is a legitimate address with a 12-bit offset.
2905 MODE is the mode of the value being accessed. */
2907 bool
2908 umips_12bit_offset_address_p (rtx x, machine_mode mode)
2910 struct mips_address_info addr;
2912 return (mips_classify_address (&addr, x, mode, false)
2913 && addr.type == ADDRESS_REG
2914 && CONST_INT_P (addr.offset)
2915 && UMIPS_12BIT_OFFSET_P (INTVAL (addr.offset)));
2918 /* Return true if X is a legitimate address with a 9-bit offset.
2919 MODE is the mode of the value being accessed. */
2921 bool
2922 mips_9bit_offset_address_p (rtx x, machine_mode mode)
2924 struct mips_address_info addr;
2926 return (mips_classify_address (&addr, x, mode, false)
2927 && addr.type == ADDRESS_REG
2928 && CONST_INT_P (addr.offset)
2929 && (!TARGET_MIPS16E2
2930 || M16_REG_P (REGNO (addr.reg))
2931 || REGNO (addr.reg) >= FIRST_PSEUDO_REGISTER)
2932 && MIPS_9BIT_OFFSET_P (INTVAL (addr.offset)));
2935 /* Return the number of instructions needed to load constant X,
2936 assuming that BASE_INSN_LENGTH is the length of one instruction.
2937 Return 0 if X isn't a valid constant. */
2940 mips_const_insns (rtx x)
2942 struct mips_integer_op codes[MIPS_MAX_INTEGER_OPS];
2943 enum mips_symbol_type symbol_type;
2944 rtx offset;
2946 switch (GET_CODE (x))
2948 case HIGH:
2949 if (!mips_symbolic_constant_p (XEXP (x, 0), SYMBOL_CONTEXT_LEA,
2950 &symbol_type)
2951 || !mips_split_p[symbol_type])
2952 return 0;
2954 /* This is simply an LUI for normal mode. It is an extended
2955 LI followed by an extended SLL for MIPS16. */
2956 return TARGET_MIPS16 ? (ISA_HAS_MIPS16E2 ? 2 : 4) : 1;
2958 case CONST_INT:
2959 if (TARGET_MIPS16)
2960 /* Unsigned 8-bit constants can be loaded using an unextended
2961 LI instruction. Unsigned 16-bit constants can be loaded
2962 using an extended LI. Negative constants must be loaded
2963 using LI and then negated. */
2964 return (IN_RANGE (INTVAL (x), 0, 255) ? 1
2965 : SMALL_OPERAND_UNSIGNED (INTVAL (x)) ? 2
2966 : IN_RANGE (-INTVAL (x), 0, 255) ? 2
2967 : SMALL_OPERAND_UNSIGNED (-INTVAL (x)) ? 3
2968 : ISA_HAS_MIPS16E2
2969 ? (trunc_int_for_mode (INTVAL (x), SImode) == INTVAL (x)
2970 ? 4 : 8)
2971 : 0);
2973 return mips_build_integer (codes, INTVAL (x));
2975 case CONST_VECTOR:
2976 if (MSA_SUPPORTED_MODE_P (GET_MODE (x))
2977 && mips_const_vector_same_int_p (x, GET_MODE (x), -512, 511))
2978 return 1;
2979 /* Fall through. */
2980 case CONST_DOUBLE:
2981 /* Allow zeros for normal mode, where we can use $0. */
2982 return !TARGET_MIPS16 && x == CONST0_RTX (GET_MODE (x)) ? 1 : 0;
2984 case CONST:
2985 if (CONST_GP_P (x))
2986 return 1;
2988 /* See if we can refer to X directly. */
2989 if (mips_symbolic_constant_p (x, SYMBOL_CONTEXT_LEA, &symbol_type))
2990 return mips_symbol_insns (symbol_type, MAX_MACHINE_MODE);
2992 /* Otherwise try splitting the constant into a base and offset.
2993 If the offset is a 16-bit value, we can load the base address
2994 into a register and then use (D)ADDIU to add in the offset.
2995 If the offset is larger, we can load the base and offset
2996 into separate registers and add them together with (D)ADDU.
2997 However, the latter is only possible before reload; during
2998 and after reload, we must have the option of forcing the
2999 constant into the pool instead. */
3000 split_const (x, &x, &offset);
3001 if (offset != 0)
3003 int n = mips_const_insns (x);
3004 if (n != 0)
3006 if (SMALL_INT (offset))
3007 return n + 1;
3008 else if (!targetm.cannot_force_const_mem (GET_MODE (x), x))
3009 return n + 1 + mips_build_integer (codes, INTVAL (offset));
3012 return 0;
3014 case SYMBOL_REF:
3015 case LABEL_REF:
3016 return mips_symbol_insns (mips_classify_symbol (x, SYMBOL_CONTEXT_LEA),
3017 MAX_MACHINE_MODE);
3019 default:
3020 return 0;
3024 /* X is a doubleword constant that can be handled by splitting it into
3025 two words and loading each word separately. Return the number of
3026 instructions required to do this, assuming that BASE_INSN_LENGTH
3027 is the length of one instruction. */
3030 mips_split_const_insns (rtx x)
3032 unsigned int low, high;
3034 low = mips_const_insns (mips_subword (x, false));
3035 high = mips_const_insns (mips_subword (x, true));
3036 gcc_assert (low > 0 && high > 0);
3037 return low + high;
3040 /* Return one word of 128-bit value OP, taking into account the fixed
3041 endianness of certain registers. BYTE selects from the byte address. */
3044 mips_subword_at_byte (rtx op, unsigned int byte)
3046 machine_mode mode;
3048 mode = GET_MODE (op);
3049 if (mode == VOIDmode)
3050 mode = TImode;
3052 gcc_assert (!FP_REG_RTX_P (op));
3054 if (MEM_P (op))
3055 return mips_rewrite_small_data (adjust_address (op, word_mode, byte));
3057 return simplify_gen_subreg (word_mode, op, mode, byte);
3060 /* Return the number of instructions needed to implement INSN,
3061 given that it loads from or stores to MEM. Assume that
3062 BASE_INSN_LENGTH is the length of one instruction. */
3065 mips_load_store_insns (rtx mem, rtx_insn *insn)
3067 machine_mode mode;
3068 bool might_split_p;
3069 rtx set;
3071 gcc_assert (MEM_P (mem));
3072 mode = GET_MODE (mem);
3074 /* Try to prove that INSN does not need to be split. */
3075 might_split_p = GET_MODE_SIZE (mode) > UNITS_PER_WORD;
3076 if (might_split_p)
3078 set = single_set (insn);
3079 if (set && !mips_split_move_insn_p (SET_DEST (set), SET_SRC (set), insn))
3080 might_split_p = false;
3083 return mips_address_insns (XEXP (mem, 0), mode, might_split_p);
3086 /* Return the number of instructions needed for an integer division,
3087 assuming that BASE_INSN_LENGTH is the length of one instruction. */
3090 mips_idiv_insns (machine_mode mode)
3092 int count;
3094 count = 1;
3095 if (TARGET_CHECK_ZERO_DIV)
3097 if (GENERATE_DIVIDE_TRAPS && !MSA_SUPPORTED_MODE_P (mode))
3098 count++;
3099 else
3100 count += 2;
3103 if (TARGET_FIX_R4000 || TARGET_FIX_R4400)
3104 count++;
3105 return count;
3109 /* Emit a move from SRC to DEST. Assume that the move expanders can
3110 handle all moves if !can_create_pseudo_p (). The distinction is
3111 important because, unlike emit_move_insn, the move expanders know
3112 how to force Pmode objects into the constant pool even when the
3113 constant pool address is not itself legitimate. */
3115 rtx_insn *
3116 mips_emit_move (rtx dest, rtx src)
3118 return (can_create_pseudo_p ()
3119 ? emit_move_insn (dest, src)
3120 : emit_move_insn_1 (dest, src));
3123 /* Emit a move from SRC to DEST, splitting compound moves into individual
3124 instructions. SPLIT_TYPE is the type of split to perform. */
3126 static void
3127 mips_emit_move_or_split (rtx dest, rtx src, enum mips_split_type split_type)
3129 if (mips_split_move_p (dest, src, split_type))
3130 mips_split_move (dest, src, split_type, NULL);
3131 else
3132 mips_emit_move (dest, src);
3135 /* Emit an instruction of the form (set TARGET (CODE OP0)). */
3137 static void
3138 mips_emit_unary (enum rtx_code code, rtx target, rtx op0)
3140 emit_insn (gen_rtx_SET (target, gen_rtx_fmt_e (code, GET_MODE (op0), op0)));
3143 /* Compute (CODE OP0) and store the result in a new register of mode MODE.
3144 Return that new register. */
3146 static rtx
3147 mips_force_unary (machine_mode mode, enum rtx_code code, rtx op0)
3149 rtx reg;
3151 reg = gen_reg_rtx (mode);
3152 mips_emit_unary (code, reg, op0);
3153 return reg;
3156 /* Emit an instruction of the form (set TARGET (CODE OP0 OP1)). */
3158 void
3159 mips_emit_binary (enum rtx_code code, rtx target, rtx op0, rtx op1)
3161 emit_insn (gen_rtx_SET (target, gen_rtx_fmt_ee (code, GET_MODE (target),
3162 op0, op1)));
3165 /* Compute (CODE OP0 OP1) and store the result in a new register
3166 of mode MODE. Return that new register. */
3168 static rtx
3169 mips_force_binary (machine_mode mode, enum rtx_code code, rtx op0, rtx op1)
3171 rtx reg;
3173 reg = gen_reg_rtx (mode);
3174 mips_emit_binary (code, reg, op0, op1);
3175 return reg;
3178 /* Copy VALUE to a register and return that register. If new pseudos
3179 are allowed, copy it into a new register, otherwise use DEST. */
3181 static rtx
3182 mips_force_temporary (rtx dest, rtx value)
3184 if (can_create_pseudo_p ())
3185 return force_reg (Pmode, value);
3186 else
3188 mips_emit_move (dest, value);
3189 return dest;
3193 /* Emit a call sequence with call pattern PATTERN and return the call
3194 instruction itself (which is not necessarily the last instruction
3195 emitted). ORIG_ADDR is the original, unlegitimized address,
3196 ADDR is the legitimized form, and LAZY_P is true if the call
3197 address is lazily-bound. */
3199 static rtx_insn *
3200 mips_emit_call_insn (rtx pattern, rtx orig_addr, rtx addr, bool lazy_p)
3202 rtx_insn *insn;
3203 rtx reg;
3205 insn = emit_call_insn (pattern);
3207 if (TARGET_MIPS16 && mips_use_pic_fn_addr_reg_p (orig_addr))
3209 /* MIPS16 JALRs only take MIPS16 registers. If the target
3210 function requires $25 to be valid on entry, we must copy it
3211 there separately. The move instruction can be put in the
3212 call's delay slot. */
3213 reg = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
3214 emit_insn_before (gen_move_insn (reg, addr), insn);
3215 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
3218 if (lazy_p)
3219 /* Lazy-binding stubs require $gp to be valid on entry. */
3220 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
3222 if (TARGET_USE_GOT)
3224 /* See the comment above load_call<mode> for details. */
3225 use_reg (&CALL_INSN_FUNCTION_USAGE (insn),
3226 gen_rtx_REG (Pmode, GOT_VERSION_REGNUM));
3227 emit_insn (gen_update_got_version ());
3230 if (TARGET_MIPS16
3231 && TARGET_EXPLICIT_RELOCS
3232 && TARGET_CALL_CLOBBERED_GP)
3234 rtx post_call_tmp_reg = gen_rtx_REG (word_mode, POST_CALL_TMP_REG);
3235 clobber_reg (&CALL_INSN_FUNCTION_USAGE (insn), post_call_tmp_reg);
3238 return insn;
3241 /* Wrap symbol or label BASE in an UNSPEC address of type SYMBOL_TYPE,
3242 then add CONST_INT OFFSET to the result. */
3244 static rtx
3245 mips_unspec_address_offset (rtx base, rtx offset,
3246 enum mips_symbol_type symbol_type)
3248 base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base),
3249 UNSPEC_ADDRESS_FIRST + symbol_type);
3250 if (offset != const0_rtx)
3251 base = gen_rtx_PLUS (Pmode, base, offset);
3252 return gen_rtx_CONST (Pmode, base);
3255 /* Return an UNSPEC address with underlying address ADDRESS and symbol
3256 type SYMBOL_TYPE. */
3259 mips_unspec_address (rtx address, enum mips_symbol_type symbol_type)
3261 rtx base, offset;
3263 split_const (address, &base, &offset);
3264 return mips_unspec_address_offset (base, offset, symbol_type);
3267 /* If OP is an UNSPEC address, return the address to which it refers,
3268 otherwise return OP itself. */
3271 mips_strip_unspec_address (rtx op)
3273 rtx base, offset;
3275 split_const (op, &base, &offset);
3276 if (UNSPEC_ADDRESS_P (base))
3277 op = plus_constant (Pmode, UNSPEC_ADDRESS (base), INTVAL (offset));
3278 return op;
3281 /* If mips_unspec_address (ADDR, SYMBOL_TYPE) is a 32-bit value, add the
3282 high part to BASE and return the result. Just return BASE otherwise.
3283 TEMP is as for mips_force_temporary.
3285 The returned expression can be used as the first operand to a LO_SUM. */
3287 static rtx
3288 mips_unspec_offset_high (rtx temp, rtx base, rtx addr,
3289 enum mips_symbol_type symbol_type)
3291 if (mips_split_p[symbol_type])
3293 addr = gen_rtx_HIGH (Pmode, mips_unspec_address (addr, symbol_type));
3294 addr = mips_force_temporary (temp, addr);
3295 base = mips_force_temporary (temp, gen_rtx_PLUS (Pmode, addr, base));
3297 return base;
3300 /* Return an instruction that copies $gp into register REG. We want
3301 GCC to treat the register's value as constant, so that its value
3302 can be rematerialized on demand. */
3304 static rtx
3305 gen_load_const_gp (rtx reg)
3307 return PMODE_INSN (gen_load_const_gp, (reg));
3310 /* Return a pseudo register that contains the value of $gp throughout
3311 the current function. Such registers are needed by MIPS16 functions,
3312 for which $gp itself is not a valid base register or addition operand. */
3314 static rtx
3315 mips16_gp_pseudo_reg (void)
3317 if (cfun->machine->mips16_gp_pseudo_rtx == NULL_RTX)
3319 rtx_insn *scan;
3321 cfun->machine->mips16_gp_pseudo_rtx = gen_reg_rtx (Pmode);
3323 push_topmost_sequence ();
3325 scan = get_insns ();
3326 while (NEXT_INSN (scan) && !INSN_P (NEXT_INSN (scan)))
3327 scan = NEXT_INSN (scan);
3329 rtx set = gen_load_const_gp (cfun->machine->mips16_gp_pseudo_rtx);
3330 rtx_insn *insn = emit_insn_after (set, scan);
3331 INSN_LOCATION (insn) = 0;
3333 pop_topmost_sequence ();
3336 return cfun->machine->mips16_gp_pseudo_rtx;
3339 /* Return a base register that holds pic_offset_table_rtx.
3340 TEMP, if nonnull, is a scratch Pmode base register. */
3343 mips_pic_base_register (rtx temp)
3345 if (MIPS16_GP_LOADS ||!TARGET_MIPS16)
3346 return pic_offset_table_rtx;
3348 if (currently_expanding_to_rtl)
3349 return mips16_gp_pseudo_reg ();
3351 if (can_create_pseudo_p ())
3352 temp = gen_reg_rtx (Pmode);
3354 if (TARGET_USE_GOT)
3355 /* The first post-reload split exposes all references to $gp
3356 (both uses and definitions). All references must remain
3357 explicit after that point.
3359 It is safe to introduce uses of $gp at any time, so for
3360 simplicity, we do that before the split too. */
3361 mips_emit_move (temp, pic_offset_table_rtx);
3362 else
3363 emit_insn (gen_load_const_gp (temp));
3364 return temp;
3367 /* Return the RHS of a load_call<mode> insn. */
3369 static rtx
3370 mips_unspec_call (rtx reg, rtx symbol)
3372 rtvec vec;
3374 vec = gen_rtvec (3, reg, symbol, gen_rtx_REG (SImode, GOT_VERSION_REGNUM));
3375 return gen_rtx_UNSPEC (Pmode, vec, UNSPEC_LOAD_CALL);
3378 /* If SRC is the RHS of a load_call<mode> insn, return the underlying symbol
3379 reference. Return NULL_RTX otherwise. */
3381 static rtx
3382 mips_strip_unspec_call (rtx src)
3384 if (GET_CODE (src) == UNSPEC && XINT (src, 1) == UNSPEC_LOAD_CALL)
3385 return mips_strip_unspec_address (XVECEXP (src, 0, 1));
3386 return NULL_RTX;
3389 /* Create and return a GOT reference of type TYPE for address ADDR.
3390 TEMP, if nonnull, is a scratch Pmode base register. */
3393 mips_got_load (rtx temp, rtx addr, enum mips_symbol_type type)
3395 rtx base, high, lo_sum_symbol;
3397 base = mips_pic_base_register (temp);
3399 /* If we used the temporary register to load $gp, we can't use
3400 it for the high part as well. */
3401 if (temp != NULL && reg_overlap_mentioned_p (base, temp))
3402 temp = NULL;
3404 high = mips_unspec_offset_high (temp, base, addr, type);
3405 lo_sum_symbol = mips_unspec_address (addr, type);
3407 if (type == SYMBOL_GOTOFF_CALL)
3408 return mips_unspec_call (high, lo_sum_symbol);
3409 else
3410 return PMODE_INSN (gen_unspec_got, (high, lo_sum_symbol));
3413 /* If MODE is MAX_MACHINE_MODE, ADDR appears as a move operand, otherwise
3414 it appears in a MEM of that mode. Return true if ADDR is a legitimate
3415 constant in that context and can be split into high and low parts.
3416 If so, and if LOW_OUT is nonnull, emit the high part and store the
3417 low part in *LOW_OUT. Leave *LOW_OUT unchanged otherwise.
3419 TEMP is as for mips_force_temporary and is used to load the high
3420 part into a register.
3422 When MODE is MAX_MACHINE_MODE, the low part is guaranteed to be
3423 a legitimize SET_SRC for an .md pattern, otherwise the low part
3424 is guaranteed to be a legitimate address for mode MODE. */
3426 bool
3427 mips_split_symbol (rtx temp, rtx addr, machine_mode mode, rtx *low_out)
3429 enum mips_symbol_context context;
3430 enum mips_symbol_type symbol_type;
3431 rtx high;
3433 context = (mode == MAX_MACHINE_MODE
3434 ? SYMBOL_CONTEXT_LEA
3435 : SYMBOL_CONTEXT_MEM);
3436 if (GET_CODE (addr) == HIGH && context == SYMBOL_CONTEXT_LEA)
3438 addr = XEXP (addr, 0);
3439 if (mips_symbolic_constant_p (addr, context, &symbol_type)
3440 && mips_symbol_insns (symbol_type, mode) > 0
3441 && mips_split_hi_p[symbol_type])
3443 if (low_out)
3444 switch (symbol_type)
3446 case SYMBOL_GOT_PAGE_OFST:
3447 /* The high part of a page/ofst pair is loaded from the GOT. */
3448 *low_out = mips_got_load (temp, addr, SYMBOL_GOTOFF_PAGE);
3449 break;
3451 default:
3452 gcc_unreachable ();
3454 return true;
3457 else
3459 if (mips_symbolic_constant_p (addr, context, &symbol_type)
3460 && mips_symbol_insns (symbol_type, mode) > 0
3461 && mips_split_p[symbol_type])
3463 if (low_out)
3464 switch (symbol_type)
3466 case SYMBOL_GOT_DISP:
3467 /* SYMBOL_GOT_DISP symbols are loaded from the GOT. */
3468 *low_out = mips_got_load (temp, addr, SYMBOL_GOTOFF_DISP);
3469 break;
3471 case SYMBOL_GP_RELATIVE:
3472 high = mips_pic_base_register (temp);
3473 *low_out = gen_rtx_LO_SUM (Pmode, high, addr);
3474 break;
3476 default:
3477 high = gen_rtx_HIGH (Pmode, copy_rtx (addr));
3478 high = mips_force_temporary (temp, high);
3479 *low_out = gen_rtx_LO_SUM (Pmode, high, addr);
3480 break;
3482 return true;
3485 return false;
3488 /* Return a legitimate address for REG + OFFSET. TEMP is as for
3489 mips_force_temporary; it is only needed when OFFSET is not a
3490 SMALL_OPERAND. */
3492 static rtx
3493 mips_add_offset (rtx temp, rtx reg, HOST_WIDE_INT offset)
3495 if (!SMALL_OPERAND (offset))
3497 rtx high;
3499 if (TARGET_MIPS16)
3501 /* Load the full offset into a register so that we can use
3502 an unextended instruction for the address itself. */
3503 high = GEN_INT (offset);
3504 offset = 0;
3506 else
3508 /* Leave OFFSET as a 16-bit offset and put the excess in HIGH.
3509 The addition inside the macro CONST_HIGH_PART may cause an
3510 overflow, so we need to force a sign-extension check. */
3511 high = gen_int_mode (CONST_HIGH_PART (offset), Pmode);
3512 offset = CONST_LOW_PART (offset);
3514 high = mips_force_temporary (temp, high);
3515 reg = mips_force_temporary (temp, gen_rtx_PLUS (Pmode, high, reg));
3517 return plus_constant (Pmode, reg, offset);
3520 /* The __tls_get_attr symbol. */
3521 static GTY(()) rtx mips_tls_symbol;
3523 /* Return an instruction sequence that calls __tls_get_addr. SYM is
3524 the TLS symbol we are referencing and TYPE is the symbol type to use
3525 (either global dynamic or local dynamic). V0 is an RTX for the
3526 return value location. */
3528 static rtx_insn *
3529 mips_call_tls_get_addr (rtx sym, enum mips_symbol_type type, rtx v0)
3531 rtx loc, a0;
3532 rtx_insn *insn;
3534 a0 = gen_rtx_REG (Pmode, GP_ARG_FIRST);
3536 if (!mips_tls_symbol)
3537 mips_tls_symbol = init_one_libfunc ("__tls_get_addr");
3539 loc = mips_unspec_address (sym, type);
3541 start_sequence ();
3543 emit_insn (gen_rtx_SET (a0, gen_rtx_LO_SUM (Pmode, pic_offset_table_rtx,
3544 loc)));
3545 insn = mips_expand_call (MIPS_CALL_NORMAL, v0, mips_tls_symbol,
3546 const0_rtx, NULL_RTX, false);
3547 RTL_CONST_CALL_P (insn) = 1;
3548 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), a0);
3549 insn = get_insns ();
3551 end_sequence ();
3553 return insn;
3556 /* Return a pseudo register that contains the current thread pointer. */
3559 mips_expand_thread_pointer (rtx tp)
3561 rtx fn;
3563 if (TARGET_MIPS16)
3565 if (!mips16_rdhwr_stub)
3566 mips16_rdhwr_stub = new mips16_rdhwr_one_only_stub ();
3567 fn = mips16_stub_call_address (mips16_rdhwr_stub);
3568 emit_insn (PMODE_INSN (gen_tls_get_tp_mips16, (tp, fn)));
3570 else
3571 emit_insn (PMODE_INSN (gen_tls_get_tp, (tp)));
3572 return tp;
3575 static rtx
3576 mips_get_tp (void)
3578 return mips_expand_thread_pointer (gen_reg_rtx (Pmode));
3581 /* Generate the code to access LOC, a thread-local SYMBOL_REF, and return
3582 its address. The return value will be both a valid address and a valid
3583 SET_SRC (either a REG or a LO_SUM). */
3585 static rtx
3586 mips_legitimize_tls_address (rtx loc)
3588 rtx dest, v0, tp, tmp1, tmp2, eqv, offset;
3589 enum tls_model model;
3591 model = SYMBOL_REF_TLS_MODEL (loc);
3592 /* Only TARGET_ABICALLS code can have more than one module; other
3593 code must be static and should not use a GOT. All TLS models
3594 reduce to local exec in this situation. */
3595 if (!TARGET_ABICALLS)
3596 model = TLS_MODEL_LOCAL_EXEC;
3598 switch (model)
3600 case TLS_MODEL_GLOBAL_DYNAMIC:
3602 v0 = gen_rtx_REG (Pmode, GP_RETURN);
3603 rtx_insn *insn = mips_call_tls_get_addr (loc, SYMBOL_TLSGD, v0);
3604 dest = gen_reg_rtx (Pmode);
3605 emit_libcall_block (insn, dest, v0, loc);
3606 break;
3609 case TLS_MODEL_LOCAL_DYNAMIC:
3611 v0 = gen_rtx_REG (Pmode, GP_RETURN);
3612 rtx_insn *insn = mips_call_tls_get_addr (loc, SYMBOL_TLSLDM, v0);
3613 tmp1 = gen_reg_rtx (Pmode);
3615 /* Attach a unique REG_EQUIV, to allow the RTL optimizers to
3616 share the LDM result with other LD model accesses. */
3617 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
3618 UNSPEC_TLS_LDM);
3619 emit_libcall_block (insn, tmp1, v0, eqv);
3621 offset = mips_unspec_address (loc, SYMBOL_DTPREL);
3622 if (mips_split_p[SYMBOL_DTPREL])
3624 tmp2 = mips_unspec_offset_high (NULL, tmp1, loc, SYMBOL_DTPREL);
3625 dest = gen_rtx_LO_SUM (Pmode, tmp2, offset);
3627 else
3628 dest = expand_binop (Pmode, add_optab, tmp1, offset,
3629 0, 0, OPTAB_DIRECT);
3630 break;
3633 case TLS_MODEL_INITIAL_EXEC:
3634 tp = mips_get_tp ();
3635 tmp1 = gen_reg_rtx (Pmode);
3636 tmp2 = mips_unspec_address (loc, SYMBOL_GOTTPREL);
3637 if (Pmode == DImode)
3638 emit_insn (gen_load_gotdi (tmp1, pic_offset_table_rtx, tmp2));
3639 else
3640 emit_insn (gen_load_gotsi (tmp1, pic_offset_table_rtx, tmp2));
3641 dest = gen_reg_rtx (Pmode);
3642 emit_insn (gen_add3_insn (dest, tmp1, tp));
3643 break;
3645 case TLS_MODEL_LOCAL_EXEC:
3646 tmp1 = mips_get_tp ();
3647 offset = mips_unspec_address (loc, SYMBOL_TPREL);
3648 if (mips_split_p[SYMBOL_TPREL])
3650 tmp2 = mips_unspec_offset_high (NULL, tmp1, loc, SYMBOL_TPREL);
3651 dest = gen_rtx_LO_SUM (Pmode, tmp2, offset);
3653 else
3654 dest = expand_binop (Pmode, add_optab, tmp1, offset,
3655 0, 0, OPTAB_DIRECT);
3656 break;
3658 default:
3659 gcc_unreachable ();
3661 return dest;
3664 /* Implement "TARGET = __builtin_mips_get_fcsr ()" for MIPS16,
3665 using a stub. */
3667 void
3668 mips16_expand_get_fcsr (rtx target)
3670 if (!mips16_get_fcsr_stub)
3671 mips16_get_fcsr_stub = new mips16_get_fcsr_one_only_stub ();
3672 rtx fn = mips16_stub_call_address (mips16_get_fcsr_stub);
3673 emit_insn (PMODE_INSN (gen_mips_get_fcsr_mips16, (fn)));
3674 emit_move_insn (target, gen_rtx_REG (SImode, GET_FCSR_REGNUM));
3677 /* Implement __builtin_mips_set_fcsr (TARGET) for MIPS16, using a stub. */
3679 void
3680 mips16_expand_set_fcsr (rtx newval)
3682 if (!mips16_set_fcsr_stub)
3683 mips16_set_fcsr_stub = new mips16_set_fcsr_one_only_stub ();
3684 rtx fn = mips16_stub_call_address (mips16_set_fcsr_stub);
3685 emit_move_insn (gen_rtx_REG (SImode, SET_FCSR_REGNUM), newval);
3686 emit_insn (PMODE_INSN (gen_mips_set_fcsr_mips16, (fn)));
3689 /* If X is not a valid address for mode MODE, force it into a register. */
3691 static rtx
3692 mips_force_address (rtx x, machine_mode mode)
3694 if (!mips_legitimate_address_p (mode, x, false))
3695 x = force_reg (Pmode, x);
3696 return x;
3699 /* This function is used to implement LEGITIMIZE_ADDRESS. If X can
3700 be legitimized in a way that the generic machinery might not expect,
3701 return a new address, otherwise return NULL. MODE is the mode of
3702 the memory being accessed. */
3704 static rtx
3705 mips_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
3706 machine_mode mode)
3708 rtx base, addr;
3709 HOST_WIDE_INT offset;
3711 if (mips_tls_symbol_p (x))
3712 return mips_legitimize_tls_address (x);
3714 /* See if the address can split into a high part and a LO_SUM. */
3715 if (mips_split_symbol (NULL, x, mode, &addr))
3716 return mips_force_address (addr, mode);
3718 /* Handle BASE + OFFSET using mips_add_offset. */
3719 mips_split_plus (x, &base, &offset);
3720 if (offset != 0)
3722 if (!mips_valid_base_register_p (base, mode, false))
3723 base = copy_to_mode_reg (Pmode, base);
3724 addr = mips_add_offset (NULL, base, offset);
3725 return mips_force_address (addr, mode);
3728 return x;
3731 /* Load VALUE into DEST. TEMP is as for mips_force_temporary. */
3733 void
3734 mips_move_integer (rtx temp, rtx dest, unsigned HOST_WIDE_INT value)
3736 struct mips_integer_op codes[MIPS_MAX_INTEGER_OPS];
3737 machine_mode mode;
3738 unsigned int i, num_ops;
3739 rtx x;
3741 mode = GET_MODE (dest);
3742 num_ops = mips_build_integer (codes, value);
3744 /* Apply each binary operation to X. Invariant: X is a legitimate
3745 source operand for a SET pattern. */
3746 x = GEN_INT (codes[0].value);
3747 for (i = 1; i < num_ops; i++)
3749 if (!can_create_pseudo_p ())
3751 emit_insn (gen_rtx_SET (temp, x));
3752 x = temp;
3754 else
3755 x = force_reg (mode, x);
3756 x = gen_rtx_fmt_ee (codes[i].code, mode, x, GEN_INT (codes[i].value));
3759 emit_insn (gen_rtx_SET (dest, x));
3762 /* Subroutine of mips_legitimize_move. Move constant SRC into register
3763 DEST given that SRC satisfies immediate_operand but doesn't satisfy
3764 move_operand. */
3766 static void
3767 mips_legitimize_const_move (machine_mode mode, rtx dest, rtx src)
3769 rtx base, offset;
3771 /* Split moves of big integers into smaller pieces. */
3772 if (splittable_const_int_operand (src, mode))
3774 mips_move_integer (dest, dest, INTVAL (src));
3775 return;
3778 /* Split moves of symbolic constants into high/low pairs. */
3779 if (mips_split_symbol (dest, src, MAX_MACHINE_MODE, &src))
3781 emit_insn (gen_rtx_SET (dest, src));
3782 return;
3785 /* Generate the appropriate access sequences for TLS symbols. */
3786 if (mips_tls_symbol_p (src))
3788 mips_emit_move (dest, mips_legitimize_tls_address (src));
3789 return;
3792 /* If we have (const (plus symbol offset)), and that expression cannot
3793 be forced into memory, load the symbol first and add in the offset.
3794 In non-MIPS16 mode, prefer to do this even if the constant _can_ be
3795 forced into memory, as it usually produces better code. */
3796 split_const (src, &base, &offset);
3797 if (offset != const0_rtx
3798 && (targetm.cannot_force_const_mem (mode, src)
3799 || (!TARGET_MIPS16 && can_create_pseudo_p ())))
3801 base = mips_force_temporary (dest, base);
3802 mips_emit_move (dest, mips_add_offset (NULL, base, INTVAL (offset)));
3803 return;
3806 src = force_const_mem (mode, src);
3808 /* When using explicit relocs, constant pool references are sometimes
3809 not legitimate addresses. */
3810 mips_split_symbol (dest, XEXP (src, 0), mode, &XEXP (src, 0));
3811 mips_emit_move (dest, src);
3814 /* If (set DEST SRC) is not a valid move instruction, emit an equivalent
3815 sequence that is valid. */
3817 bool
3818 mips_legitimize_move (machine_mode mode, rtx dest, rtx src)
3820 /* Both src and dest are non-registers; one special case is supported where
3821 the source is (const_int 0) and the store can source the zero register.
3822 MIPS16 and MSA are never able to source the zero register directly in
3823 memory operations. */
3824 if (!register_operand (dest, mode)
3825 && !register_operand (src, mode)
3826 && (TARGET_MIPS16 || !const_0_operand (src, mode)
3827 || MSA_SUPPORTED_MODE_P (mode)))
3829 mips_emit_move (dest, force_reg (mode, src));
3830 return true;
3833 /* We need to deal with constants that would be legitimate
3834 immediate_operands but aren't legitimate move_operands. */
3835 if (CONSTANT_P (src) && !move_operand (src, mode))
3837 mips_legitimize_const_move (mode, dest, src);
3838 set_unique_reg_note (get_last_insn (), REG_EQUAL, copy_rtx (src));
3839 return true;
3841 return false;
3844 /* Return true if value X in context CONTEXT is a small-data address
3845 that can be rewritten as a LO_SUM. */
3847 static bool
3848 mips_rewrite_small_data_p (rtx x, enum mips_symbol_context context)
3850 enum mips_symbol_type symbol_type;
3852 return (mips_lo_relocs[SYMBOL_GP_RELATIVE]
3853 && !mips_split_p[SYMBOL_GP_RELATIVE]
3854 && mips_symbolic_constant_p (x, context, &symbol_type)
3855 && symbol_type == SYMBOL_GP_RELATIVE);
3858 /* Return true if OP refers to small data symbols directly, not through
3859 a LO_SUM. CONTEXT is the context in which X appears. */
3861 static int
3862 mips_small_data_pattern_1 (rtx x, enum mips_symbol_context context)
3864 subrtx_var_iterator::array_type array;
3865 FOR_EACH_SUBRTX_VAR (iter, array, x, ALL)
3867 rtx x = *iter;
3869 /* Ignore things like "g" constraints in asms. We make no particular
3870 guarantee about which symbolic constants are acceptable as asm operands
3871 versus which must be forced into a GPR. */
3872 if (GET_CODE (x) == LO_SUM || GET_CODE (x) == ASM_OPERANDS)
3873 iter.skip_subrtxes ();
3874 else if (MEM_P (x))
3876 if (mips_small_data_pattern_1 (XEXP (x, 0), SYMBOL_CONTEXT_MEM))
3877 return true;
3878 iter.skip_subrtxes ();
3880 else if (mips_rewrite_small_data_p (x, context))
3881 return true;
3883 return false;
3886 /* Return true if OP refers to small data symbols directly, not through
3887 a LO_SUM. */
3889 bool
3890 mips_small_data_pattern_p (rtx op)
3892 return mips_small_data_pattern_1 (op, SYMBOL_CONTEXT_LEA);
3895 /* Rewrite *LOC so that it refers to small data using explicit
3896 relocations. CONTEXT is the context in which *LOC appears. */
3898 static void
3899 mips_rewrite_small_data_1 (rtx *loc, enum mips_symbol_context context)
3901 subrtx_ptr_iterator::array_type array;
3902 FOR_EACH_SUBRTX_PTR (iter, array, loc, ALL)
3904 rtx *loc = *iter;
3905 if (MEM_P (*loc))
3907 mips_rewrite_small_data_1 (&XEXP (*loc, 0), SYMBOL_CONTEXT_MEM);
3908 iter.skip_subrtxes ();
3910 else if (mips_rewrite_small_data_p (*loc, context))
3912 *loc = gen_rtx_LO_SUM (Pmode, pic_offset_table_rtx, *loc);
3913 iter.skip_subrtxes ();
3915 else if (GET_CODE (*loc) == LO_SUM)
3916 iter.skip_subrtxes ();
3920 /* Rewrite instruction pattern PATTERN so that it refers to small data
3921 using explicit relocations. */
3924 mips_rewrite_small_data (rtx pattern)
3926 pattern = copy_insn (pattern);
3927 mips_rewrite_small_data_1 (&pattern, SYMBOL_CONTEXT_LEA);
3928 return pattern;
3931 /* The cost of loading values from the constant pool. It should be
3932 larger than the cost of any constant we want to synthesize inline. */
3933 #define CONSTANT_POOL_COST COSTS_N_INSNS (TARGET_MIPS16 ? 4 : 8)
3935 /* Return the cost of X when used as an operand to the MIPS16 instruction
3936 that implements CODE. Return -1 if there is no such instruction, or if
3937 X is not a valid immediate operand for it. */
3939 static int
3940 mips16_constant_cost (int code, HOST_WIDE_INT x)
3942 switch (code)
3944 case ASHIFT:
3945 case ASHIFTRT:
3946 case LSHIFTRT:
3947 /* Shifts by between 1 and 8 bits (inclusive) are unextended,
3948 other shifts are extended. The shift patterns truncate the shift
3949 count to the right size, so there are no out-of-range values. */
3950 if (IN_RANGE (x, 1, 8))
3951 return 0;
3952 return COSTS_N_INSNS (1);
3954 case PLUS:
3955 if (IN_RANGE (x, -128, 127))
3956 return 0;
3957 if (SMALL_OPERAND (x))
3958 return COSTS_N_INSNS (1);
3959 return -1;
3961 case LEU:
3962 /* Like LE, but reject the always-true case. */
3963 if (x == -1)
3964 return -1;
3965 /* FALLTHRU */
3966 case LE:
3967 /* We add 1 to the immediate and use SLT. */
3968 x += 1;
3969 /* FALLTHRU */
3970 case XOR:
3971 /* We can use CMPI for an xor with an unsigned 16-bit X. */
3972 case LT:
3973 case LTU:
3974 if (IN_RANGE (x, 0, 255))
3975 return 0;
3976 if (SMALL_OPERAND_UNSIGNED (x))
3977 return COSTS_N_INSNS (1);
3978 return -1;
3980 case EQ:
3981 case NE:
3982 /* Equality comparisons with 0 are cheap. */
3983 if (x == 0)
3984 return 0;
3985 return -1;
3987 case ZERO_EXTRACT:
3988 /* The bit position and size are immediate operands. */
3989 return ISA_HAS_EXT_INS ? COSTS_N_INSNS (1) : -1;
3991 default:
3992 return -1;
3996 /* Return true if there is a non-MIPS16 instruction that implements CODE
3997 and if that instruction accepts X as an immediate operand. */
3999 static int
4000 mips_immediate_operand_p (int code, HOST_WIDE_INT x)
4002 switch (code)
4004 case ASHIFT:
4005 case ASHIFTRT:
4006 case LSHIFTRT:
4007 /* All shift counts are truncated to a valid constant. */
4008 return true;
4010 case ROTATE:
4011 case ROTATERT:
4012 /* Likewise rotates, if the target supports rotates at all. */
4013 return ISA_HAS_ROR;
4015 case AND:
4016 case IOR:
4017 case XOR:
4018 /* These instructions take 16-bit unsigned immediates. */
4019 return SMALL_OPERAND_UNSIGNED (x);
4021 case PLUS:
4022 case LT:
4023 case LTU:
4024 /* These instructions take 16-bit signed immediates. */
4025 return SMALL_OPERAND (x);
4027 case EQ:
4028 case NE:
4029 case GT:
4030 case GTU:
4031 /* The "immediate" forms of these instructions are really
4032 implemented as comparisons with register 0. */
4033 return x == 0;
4035 case GE:
4036 case GEU:
4037 /* Likewise, meaning that the only valid immediate operand is 1. */
4038 return x == 1;
4040 case LE:
4041 /* We add 1 to the immediate and use SLT. */
4042 return SMALL_OPERAND (x + 1);
4044 case LEU:
4045 /* Likewise SLTU, but reject the always-true case. */
4046 return SMALL_OPERAND (x + 1) && x + 1 != 0;
4048 case SIGN_EXTRACT:
4049 case ZERO_EXTRACT:
4050 /* The bit position and size are immediate operands. */
4051 return ISA_HAS_EXT_INS;
4053 default:
4054 /* By default assume that $0 can be used for 0. */
4055 return x == 0;
4059 /* Return the cost of binary operation X, given that the instruction
4060 sequence for a word-sized or smaller operation has cost SINGLE_COST
4061 and that the sequence of a double-word operation has cost DOUBLE_COST.
4062 If SPEED is true, optimize for speed otherwise optimize for size. */
4064 static int
4065 mips_binary_cost (rtx x, int single_cost, int double_cost, bool speed)
4067 int cost;
4069 if (GET_MODE_SIZE (GET_MODE (x)) == UNITS_PER_WORD * 2)
4070 cost = double_cost;
4071 else
4072 cost = single_cost;
4073 return (cost
4074 + set_src_cost (XEXP (x, 0), GET_MODE (x), speed)
4075 + rtx_cost (XEXP (x, 1), GET_MODE (x), GET_CODE (x), 1, speed));
4078 /* Return the cost of floating-point multiplications of mode MODE. */
4080 static int
4081 mips_fp_mult_cost (machine_mode mode)
4083 return mode == DFmode ? mips_cost->fp_mult_df : mips_cost->fp_mult_sf;
4086 /* Return the cost of floating-point divisions of mode MODE. */
4088 static int
4089 mips_fp_div_cost (machine_mode mode)
4091 return mode == DFmode ? mips_cost->fp_div_df : mips_cost->fp_div_sf;
4094 /* Return the cost of sign-extending OP to mode MODE, not including the
4095 cost of OP itself. */
4097 static int
4098 mips_sign_extend_cost (machine_mode mode, rtx op)
4100 if (MEM_P (op))
4101 /* Extended loads are as cheap as unextended ones. */
4102 return 0;
4104 if (TARGET_64BIT && mode == DImode && GET_MODE (op) == SImode)
4105 /* A sign extension from SImode to DImode in 64-bit mode is free. */
4106 return 0;
4108 if (ISA_HAS_SEB_SEH || GENERATE_MIPS16E)
4109 /* We can use SEB or SEH. */
4110 return COSTS_N_INSNS (1);
4112 /* We need to use a shift left and a shift right. */
4113 return COSTS_N_INSNS (TARGET_MIPS16 ? 4 : 2);
4116 /* Return the cost of zero-extending OP to mode MODE, not including the
4117 cost of OP itself. */
4119 static int
4120 mips_zero_extend_cost (machine_mode mode, rtx op)
4122 if (MEM_P (op))
4123 /* Extended loads are as cheap as unextended ones. */
4124 return 0;
4126 if (TARGET_64BIT && mode == DImode && GET_MODE (op) == SImode)
4127 /* We need a shift left by 32 bits and a shift right by 32 bits. */
4128 return COSTS_N_INSNS (TARGET_MIPS16 ? 4 : 2);
4130 if (GENERATE_MIPS16E)
4131 /* We can use ZEB or ZEH. */
4132 return COSTS_N_INSNS (1);
4134 if (TARGET_MIPS16)
4135 /* We need to load 0xff or 0xffff into a register and use AND. */
4136 return COSTS_N_INSNS (GET_MODE (op) == QImode ? 2 : 3);
4138 /* We can use ANDI. */
4139 return COSTS_N_INSNS (1);
4142 /* Return the cost of moving between two registers of mode MODE,
4143 assuming that the move will be in pieces of at most UNITS bytes. */
4145 static int
4146 mips_set_reg_reg_piece_cost (machine_mode mode, unsigned int units)
4148 return COSTS_N_INSNS ((GET_MODE_SIZE (mode) + units - 1) / units);
4151 /* Return the cost of moving between two registers of mode MODE. */
4153 static int
4154 mips_set_reg_reg_cost (machine_mode mode)
4156 switch (GET_MODE_CLASS (mode))
4158 case MODE_CC:
4159 return mips_set_reg_reg_piece_cost (mode, GET_MODE_SIZE (CCmode));
4161 case MODE_FLOAT:
4162 case MODE_COMPLEX_FLOAT:
4163 case MODE_VECTOR_FLOAT:
4164 if (TARGET_HARD_FLOAT)
4165 return mips_set_reg_reg_piece_cost (mode, UNITS_PER_HWFPVALUE);
4166 /* Fall through */
4168 default:
4169 return mips_set_reg_reg_piece_cost (mode, UNITS_PER_WORD);
4173 /* Implement TARGET_INSN_COSTS. */
4175 static int
4176 mips_insn_cost (rtx_insn *x, bool speed)
4178 int cost;
4179 int count;
4180 int ratio;
4182 if (recog_memoized (x) < 0
4183 && GET_CODE (PATTERN (x)) != ASM_INPUT
4184 && asm_noperands (PATTERN (x)) < 0)
4185 goto pattern_cost;
4187 /* FIXME: return get_attr_length? More tests may be needed. */
4188 if (!speed)
4189 goto pattern_cost;
4191 count = get_attr_insn_count (x);
4192 ratio = get_attr_perf_ratio (x);
4193 cost = count * ratio;
4194 if (cost > 0)
4195 return cost;
4197 pattern_cost:
4198 cost = pattern_cost (PATTERN (x), speed);
4199 /* If the cost is zero, then it's likely a complex insn.
4200 FIXME: Return COSTS_N_INSNS (2)? More tests are needed. */
4201 return cost;
4204 /* Implement TARGET_RTX_COSTS. */
4206 static bool
4207 mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
4208 int opno ATTRIBUTE_UNUSED, int *total, bool speed)
4210 int code = GET_CODE (x);
4211 bool float_mode_p = FLOAT_MODE_P (mode);
4212 int cost;
4213 rtx addr;
4215 /* The cost of a COMPARE is hard to define for MIPS. COMPAREs don't
4216 appear in the instruction stream, and the cost of a comparison is
4217 really the cost of the branch or scc condition. At the time of
4218 writing, GCC only uses an explicit outer COMPARE code when optabs
4219 is testing whether a constant is expensive enough to force into a
4220 register. We want optabs to pass such constants through the MIPS
4221 expanders instead, so make all constants very cheap here. */
4222 if (outer_code == COMPARE)
4224 gcc_assert (CONSTANT_P (x));
4225 *total = 0;
4226 return true;
4229 switch (code)
4231 case CONST_INT:
4232 /* Treat *clear_upper32-style ANDs as having zero cost in the
4233 second operand. The cost is entirely in the first operand.
4235 ??? This is needed because we would otherwise try to CSE
4236 the constant operand. Although that's the right thing for
4237 instructions that continue to be a register operation throughout
4238 compilation, it is disastrous for instructions that could
4239 later be converted into a memory operation. */
4240 if (TARGET_64BIT
4241 && outer_code == AND
4242 && UINTVAL (x) == 0xffffffff)
4244 *total = 0;
4245 return true;
4248 if (TARGET_MIPS16)
4250 cost = mips16_constant_cost (outer_code, INTVAL (x));
4251 if (cost >= 0)
4253 *total = cost;
4254 return true;
4257 else
4259 /* When not optimizing for size, we care more about the cost
4260 of hot code, and hot code is often in a loop. If a constant
4261 operand needs to be forced into a register, we will often be
4262 able to hoist the constant load out of the loop, so the load
4263 should not contribute to the cost. */
4264 if (speed || mips_immediate_operand_p (outer_code, INTVAL (x)))
4266 *total = 0;
4267 return true;
4270 /* Fall through. */
4272 case CONST:
4273 case SYMBOL_REF:
4274 case LABEL_REF:
4275 case CONST_DOUBLE:
4276 if (force_to_mem_operand (x, VOIDmode))
4278 *total = COSTS_N_INSNS (1);
4279 return true;
4281 cost = mips_const_insns (x);
4282 if (cost > 0)
4284 /* If the constant is likely to be stored in a GPR, SETs of
4285 single-insn constants are as cheap as register sets; we
4286 never want to CSE them.
4288 Don't reduce the cost of storing a floating-point zero in
4289 FPRs. If we have a zero in an FPR for other reasons, we
4290 can get better cfg-cleanup and delayed-branch results by
4291 using it consistently, rather than using $0 sometimes and
4292 an FPR at other times. Also, moves between floating-point
4293 registers are sometimes cheaper than (D)MTC1 $0. */
4294 if (cost == 1
4295 && outer_code == SET
4296 && !(float_mode_p && TARGET_HARD_FLOAT))
4297 cost = 0;
4298 /* When non-MIPS16 code loads a constant N>1 times, we rarely
4299 want to CSE the constant itself. It is usually better to
4300 have N copies of the last operation in the sequence and one
4301 shared copy of the other operations. (Note that this is
4302 not true for MIPS16 code, where the final operation in the
4303 sequence is often an extended instruction.)
4305 Also, if we have a CONST_INT, we don't know whether it is
4306 for a word or doubleword operation, so we cannot rely on
4307 the result of mips_build_integer. */
4308 else if (!TARGET_MIPS16
4309 && (outer_code == SET || GET_MODE (x) == VOIDmode))
4310 cost = 1;
4311 *total = COSTS_N_INSNS (cost);
4312 return true;
4314 /* The value will need to be fetched from the constant pool. */
4315 *total = CONSTANT_POOL_COST;
4316 return true;
4318 case MEM:
4319 /* If the address is legitimate, return the number of
4320 instructions it needs. */
4321 addr = XEXP (x, 0);
4322 cost = mips_address_insns (addr, mode, true);
4323 if (cost > 0)
4325 *total = COSTS_N_INSNS (cost + 1);
4326 return true;
4328 /* Check for a scaled indexed address. */
4329 if (mips_lwxs_address_p (addr)
4330 || mips_lx_address_p (addr, mode))
4332 *total = COSTS_N_INSNS (2);
4333 return true;
4335 /* Otherwise use the default handling. */
4336 return false;
4338 case FFS:
4339 *total = COSTS_N_INSNS (6);
4340 return false;
4342 case NOT:
4343 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) > UNITS_PER_WORD ? 2 : 1);
4344 return false;
4346 case AND:
4347 /* Check for a *clear_upper32 pattern and treat it like a zero
4348 extension. See the pattern's comment for details. */
4349 if (TARGET_64BIT
4350 && mode == DImode
4351 && CONST_INT_P (XEXP (x, 1))
4352 && UINTVAL (XEXP (x, 1)) == 0xffffffff)
4354 *total = (mips_zero_extend_cost (mode, XEXP (x, 0))
4355 + set_src_cost (XEXP (x, 0), mode, speed));
4356 return true;
4358 if (ISA_HAS_CINS && CONST_INT_P (XEXP (x, 1)))
4360 rtx op = XEXP (x, 0);
4361 if (GET_CODE (op) == ASHIFT
4362 && CONST_INT_P (XEXP (op, 1))
4363 && mask_low_and_shift_p (mode, XEXP (x, 1), XEXP (op, 1), 32))
4365 *total = COSTS_N_INSNS (1);
4366 *total += set_src_cost (XEXP (op, 0), mode, speed);
4367 return true;
4370 /* (AND (NOT op0) (NOT op1) is a nor operation that can be done in
4371 a single instruction. */
4372 if (!TARGET_MIPS16
4373 && GET_CODE (XEXP (x, 0)) == NOT
4374 && GET_CODE (XEXP (x, 1)) == NOT)
4376 cost = GET_MODE_SIZE (mode) > UNITS_PER_WORD ? 2 : 1;
4377 *total = (COSTS_N_INSNS (cost)
4378 + set_src_cost (XEXP (XEXP (x, 0), 0), mode, speed)
4379 + set_src_cost (XEXP (XEXP (x, 1), 0), mode, speed));
4380 return true;
4383 /* Fall through. */
4385 case IOR:
4386 case XOR:
4387 /* Double-word operations use two single-word operations. */
4388 *total = mips_binary_cost (x, COSTS_N_INSNS (1), COSTS_N_INSNS (2),
4389 speed);
4390 return true;
4392 case ASHIFT:
4393 case ASHIFTRT:
4394 case LSHIFTRT:
4395 case ROTATE:
4396 case ROTATERT:
4397 if (CONSTANT_P (XEXP (x, 1)))
4398 *total = mips_binary_cost (x, COSTS_N_INSNS (1), COSTS_N_INSNS (4),
4399 speed);
4400 else
4401 *total = mips_binary_cost (x, COSTS_N_INSNS (1), COSTS_N_INSNS (12),
4402 speed);
4403 return true;
4405 case ABS:
4406 if (float_mode_p)
4407 *total = mips_cost->fp_add;
4408 else
4409 *total = COSTS_N_INSNS (4);
4410 return false;
4412 case LO_SUM:
4413 /* Low-part immediates need an extended MIPS16 instruction. */
4414 *total = (COSTS_N_INSNS (TARGET_MIPS16 ? 2 : 1)
4415 + set_src_cost (XEXP (x, 0), mode, speed));
4416 return true;
4418 case LT:
4419 case LTU:
4420 case LE:
4421 case LEU:
4422 case GT:
4423 case GTU:
4424 case GE:
4425 case GEU:
4426 case EQ:
4427 case NE:
4428 case UNORDERED:
4429 case LTGT:
4430 case UNGE:
4431 case UNGT:
4432 case UNLE:
4433 case UNLT:
4434 /* Branch comparisons have VOIDmode, so use the first operand's
4435 mode instead. */
4436 mode = GET_MODE (XEXP (x, 0));
4437 if (FLOAT_MODE_P (mode))
4439 *total = mips_cost->fp_add;
4440 return false;
4442 *total = mips_binary_cost (x, COSTS_N_INSNS (1), COSTS_N_INSNS (4),
4443 speed);
4444 return true;
4446 case MINUS:
4447 if (float_mode_p && ISA_HAS_UNFUSED_MADD4 && !HONOR_SIGNED_ZEROS (mode))
4449 /* See if we can use NMADD or NMSUB via the *nmadd4<mode>_fastmath
4450 or *nmsub4<mode>_fastmath patterns. These patterns check for
4451 HONOR_SIGNED_ZEROS so we check here too. */
4452 rtx op0 = XEXP (x, 0);
4453 rtx op1 = XEXP (x, 1);
4454 if (GET_CODE (op0) == MULT && GET_CODE (XEXP (op0, 0)) == NEG)
4456 *total = (mips_fp_mult_cost (mode)
4457 + set_src_cost (XEXP (XEXP (op0, 0), 0), mode, speed)
4458 + set_src_cost (XEXP (op0, 1), mode, speed)
4459 + set_src_cost (op1, mode, speed));
4460 return true;
4462 if (GET_CODE (op1) == MULT)
4464 *total = (mips_fp_mult_cost (mode)
4465 + set_src_cost (op0, mode, speed)
4466 + set_src_cost (XEXP (op1, 0), mode, speed)
4467 + set_src_cost (XEXP (op1, 1), mode, speed));
4468 return true;
4471 /* Fall through. */
4473 case PLUS:
4474 if (float_mode_p)
4476 /* If this is part of a MADD or MSUB, treat the PLUS as
4477 being free. */
4478 if (ISA_HAS_UNFUSED_MADD4 && GET_CODE (XEXP (x, 0)) == MULT)
4479 *total = 0;
4480 else
4481 *total = mips_cost->fp_add;
4482 return false;
4485 /* If it's an add + mult (which is equivalent to shift left) and
4486 it's immediate operand satisfies const_immlsa_operand predicate. */
4487 if (((ISA_HAS_LSA && mode == SImode)
4488 || (ISA_HAS_DLSA && mode == DImode))
4489 && GET_CODE (XEXP (x, 0)) == MULT)
4491 rtx op2 = XEXP (XEXP (x, 0), 1);
4492 if (const_immlsa_operand (op2, mode))
4494 *total = (COSTS_N_INSNS (1)
4495 + set_src_cost (XEXP (XEXP (x, 0), 0), mode, speed)
4496 + set_src_cost (XEXP (x, 1), mode, speed));
4497 return true;
4501 /* Double-word operations require three single-word operations and
4502 an SLTU. The MIPS16 version then needs to move the result of
4503 the SLTU from $24 to a MIPS16 register. */
4504 *total = mips_binary_cost (x, COSTS_N_INSNS (1),
4505 COSTS_N_INSNS (TARGET_MIPS16 ? 5 : 4),
4506 speed);
4507 return true;
4509 case NEG:
4510 if (float_mode_p && ISA_HAS_UNFUSED_MADD4)
4512 /* See if we can use NMADD or NMSUB via the *nmadd4<mode> or
4513 *nmsub4<mode> patterns. */
4514 rtx op = XEXP (x, 0);
4515 if ((GET_CODE (op) == PLUS || GET_CODE (op) == MINUS)
4516 && GET_CODE (XEXP (op, 0)) == MULT)
4518 *total = (mips_fp_mult_cost (mode)
4519 + set_src_cost (XEXP (XEXP (op, 0), 0), mode, speed)
4520 + set_src_cost (XEXP (XEXP (op, 0), 1), mode, speed)
4521 + set_src_cost (XEXP (op, 1), mode, speed));
4522 return true;
4526 if (float_mode_p)
4527 *total = mips_cost->fp_add;
4528 else
4529 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) > UNITS_PER_WORD ? 4 : 1);
4530 return false;
4532 case FMA:
4533 *total = mips_fp_mult_cost (mode);
4534 return false;
4536 case MULT:
4537 if (float_mode_p)
4538 *total = mips_fp_mult_cost (mode);
4539 else if (mode == DImode && !TARGET_64BIT)
4540 /* Synthesized from 2 mulsi3s, 1 mulsidi3 and two additions,
4541 where the mulsidi3 always includes an MFHI and an MFLO. */
4542 *total = (speed
4543 ? mips_cost->int_mult_si * 3 + 6
4544 : COSTS_N_INSNS (ISA_HAS_MUL3 ? 7 : 9));
4545 else if (!speed)
4546 *total = COSTS_N_INSNS ((ISA_HAS_MUL3 || ISA_HAS_R6MUL) ? 1 : 2) + 1;
4547 else if (mode == DImode)
4548 *total = mips_cost->int_mult_di;
4549 else
4550 *total = mips_cost->int_mult_si;
4551 return false;
4553 case DIV:
4554 /* Check for a reciprocal. */
4555 if (float_mode_p
4556 && ISA_HAS_FP_RECIP_RSQRT (mode)
4557 && flag_unsafe_math_optimizations
4558 && XEXP (x, 0) == CONST1_RTX (mode))
4560 if (outer_code == SQRT || GET_CODE (XEXP (x, 1)) == SQRT)
4561 /* An rsqrt<mode>a or rsqrt<mode>b pattern. Count the
4562 division as being free. */
4563 *total = set_src_cost (XEXP (x, 1), mode, speed);
4564 else
4565 *total = (mips_fp_div_cost (mode)
4566 + set_src_cost (XEXP (x, 1), mode, speed));
4567 return true;
4569 /* Fall through. */
4571 case SQRT:
4572 case MOD:
4573 if (float_mode_p)
4575 *total = mips_fp_div_cost (mode);
4576 return false;
4578 /* Fall through. */
4580 case UDIV:
4581 case UMOD:
4582 if (!speed)
4584 /* It is our responsibility to make division by a power of 2
4585 as cheap as 2 register additions if we want the division
4586 expanders to be used for such operations; see the setting
4587 of sdiv_pow2_cheap in optabs.cc. Using (D)DIV for MIPS16
4588 should always produce shorter code than using
4589 expand_sdiv2_pow2. */
4590 if (TARGET_MIPS16
4591 && CONST_INT_P (XEXP (x, 1))
4592 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
4594 *total = COSTS_N_INSNS (2);
4595 *total += set_src_cost (XEXP (x, 0), mode, speed);
4596 return true;
4598 *total = COSTS_N_INSNS (mips_idiv_insns (mode));
4600 else if (mode == DImode)
4601 *total = mips_cost->int_div_di;
4602 else
4603 *total = mips_cost->int_div_si;
4604 return false;
4606 case SIGN_EXTEND:
4607 *total = mips_sign_extend_cost (mode, XEXP (x, 0));
4608 return false;
4610 case ZERO_EXTEND:
4611 if (outer_code == SET
4612 && ISA_HAS_BADDU
4613 && (GET_CODE (XEXP (x, 0)) == TRUNCATE
4614 || GET_CODE (XEXP (x, 0)) == SUBREG)
4615 && GET_MODE (XEXP (x, 0)) == QImode
4616 && GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS)
4618 *total = set_src_cost (XEXP (XEXP (x, 0), 0), VOIDmode, speed);
4619 return true;
4621 *total = mips_zero_extend_cost (mode, XEXP (x, 0));
4622 return false;
4623 case TRUNCATE:
4624 /* Costings for highpart multiplies. Matching patterns of the form:
4626 (lshiftrt:DI (mult:DI (sign_extend:DI (...)
4627 (sign_extend:DI (...))
4628 (const_int 32)
4630 if (ISA_HAS_R6MUL
4631 && (GET_CODE (XEXP (x, 0)) == ASHIFTRT
4632 || GET_CODE (XEXP (x, 0)) == LSHIFTRT)
4633 && CONST_INT_P (XEXP (XEXP (x, 0), 1))
4634 && ((INTVAL (XEXP (XEXP (x, 0), 1)) == 32
4635 && GET_MODE (XEXP (x, 0)) == DImode)
4636 || (ISA_HAS_R6DMUL
4637 && INTVAL (XEXP (XEXP (x, 0), 1)) == 64
4638 && GET_MODE (XEXP (x, 0)) == TImode))
4639 && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
4640 && ((GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == SIGN_EXTEND
4641 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == SIGN_EXTEND)
4642 || (GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == ZERO_EXTEND
4643 && (GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1))
4644 == ZERO_EXTEND))))
4646 if (!speed)
4647 *total = COSTS_N_INSNS (1) + 1;
4648 else if (mode == DImode)
4649 *total = mips_cost->int_mult_di;
4650 else
4651 *total = mips_cost->int_mult_si;
4653 /* Sign extension is free, zero extension costs for DImode when
4654 on a 64bit core / when DMUL is present. */
4655 for (int i = 0; i < 2; ++i)
4657 rtx op = XEXP (XEXP (XEXP (x, 0), 0), i);
4658 if (ISA_HAS_R6DMUL
4659 && GET_CODE (op) == ZERO_EXTEND
4660 && GET_MODE (op) == DImode)
4661 *total += rtx_cost (op, DImode, MULT, i, speed);
4662 else
4663 *total += rtx_cost (XEXP (op, 0), VOIDmode, GET_CODE (op),
4664 0, speed);
4667 return true;
4669 return false;
4671 case FLOAT:
4672 case UNSIGNED_FLOAT:
4673 case FIX:
4674 case FLOAT_EXTEND:
4675 case FLOAT_TRUNCATE:
4676 *total = mips_cost->fp_add;
4677 return false;
4679 case SET:
4680 if (register_operand (SET_DEST (x), VOIDmode)
4681 && reg_or_0_operand (SET_SRC (x), VOIDmode))
4683 *total = mips_set_reg_reg_cost (GET_MODE (SET_DEST (x)));
4684 return true;
4686 return false;
4688 default:
4689 return false;
4693 /* Implement TARGET_ADDRESS_COST. */
4695 static int
4696 mips_address_cost (rtx addr, machine_mode mode,
4697 addr_space_t as ATTRIBUTE_UNUSED,
4698 bool speed ATTRIBUTE_UNUSED)
4700 return mips_address_insns (addr, mode, false);
4703 /* Implement TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P. */
4705 static bool
4706 mips_no_speculation_in_delay_slots_p ()
4708 return TARGET_CB_MAYBE;
4711 /* Information about a single instruction in a multi-instruction
4712 asm sequence. */
4713 struct mips_multi_member {
4714 /* True if this is a label, false if it is code. */
4715 bool is_label_p;
4717 /* The output_asm_insn format of the instruction. */
4718 const char *format;
4720 /* The operands to the instruction. */
4721 rtx operands[MAX_RECOG_OPERANDS];
4723 typedef struct mips_multi_member mips_multi_member;
4725 /* The instructions that make up the current multi-insn sequence. */
4726 static vec<mips_multi_member> mips_multi_members;
4728 /* How many instructions (as opposed to labels) are in the current
4729 multi-insn sequence. */
4730 static unsigned int mips_multi_num_insns;
4732 /* Start a new multi-insn sequence. */
4734 static void
4735 mips_multi_start (void)
4737 mips_multi_members.truncate (0);
4738 mips_multi_num_insns = 0;
4741 /* Add a new, zero initialized member to the current multi-insn sequence. */
4743 static struct mips_multi_member *
4744 mips_multi_add (void)
4746 mips_multi_member empty;
4747 memset (&empty, 0, sizeof (empty));
4748 return mips_multi_members.safe_push (empty);
4751 /* Add a normal insn with the given asm format to the current multi-insn
4752 sequence. The other arguments are a null-terminated list of operands. */
4754 static void
4755 mips_multi_add_insn (const char *format, ...)
4757 struct mips_multi_member *member;
4758 va_list ap;
4759 unsigned int i;
4760 rtx op;
4762 member = mips_multi_add ();
4763 member->is_label_p = false;
4764 member->format = format;
4765 va_start (ap, format);
4766 i = 0;
4767 while ((op = va_arg (ap, rtx)))
4768 member->operands[i++] = op;
4769 va_end (ap);
4770 mips_multi_num_insns++;
4773 /* Add the given label definition to the current multi-insn sequence.
4774 The definition should include the colon. */
4776 static void
4777 mips_multi_add_label (const char *label)
4779 struct mips_multi_member *member;
4781 member = mips_multi_add ();
4782 member->is_label_p = true;
4783 member->format = label;
4786 /* Return the index of the last member of the current multi-insn sequence. */
4788 static unsigned int
4789 mips_multi_last_index (void)
4791 return mips_multi_members.length () - 1;
4794 /* Add a copy of an existing instruction to the current multi-insn
4795 sequence. I is the index of the instruction that should be copied. */
4797 static void
4798 mips_multi_copy_insn (unsigned int i)
4800 struct mips_multi_member *member;
4802 member = mips_multi_add ();
4803 memcpy (member, &mips_multi_members[i], sizeof (*member));
4804 gcc_assert (!member->is_label_p);
4807 /* Change the operand of an existing instruction in the current
4808 multi-insn sequence. I is the index of the instruction,
4809 OP is the index of the operand, and X is the new value. */
4811 static void
4812 mips_multi_set_operand (unsigned int i, unsigned int op, rtx x)
4814 mips_multi_members[i].operands[op] = x;
4817 /* Write out the asm code for the current multi-insn sequence. */
4819 static void
4820 mips_multi_write (void)
4822 struct mips_multi_member *member;
4823 unsigned int i;
4825 FOR_EACH_VEC_ELT (mips_multi_members, i, member)
4826 if (member->is_label_p)
4827 fprintf (asm_out_file, "%s\n", member->format);
4828 else
4829 output_asm_insn (member->format, member->operands);
4832 /* Return one word of double-word value OP, taking into account the fixed
4833 endianness of certain registers. HIGH_P is true to select the high part,
4834 false to select the low part. */
4837 mips_subword (rtx op, bool high_p)
4839 unsigned int byte, offset;
4840 machine_mode mode;
4842 mode = GET_MODE (op);
4843 if (mode == VOIDmode)
4844 mode = TARGET_64BIT ? TImode : DImode;
4846 if (TARGET_BIG_ENDIAN ? !high_p : high_p)
4847 byte = UNITS_PER_WORD;
4848 else
4849 byte = 0;
4851 if (FP_REG_RTX_P (op))
4853 /* Paired FPRs are always ordered little-endian. */
4854 offset = (UNITS_PER_WORD < UNITS_PER_HWFPVALUE ? high_p : byte != 0);
4855 return gen_rtx_REG (word_mode, REGNO (op) + offset);
4858 if (MEM_P (op))
4859 return mips_rewrite_small_data (adjust_address (op, word_mode, byte));
4861 return simplify_gen_subreg (word_mode, op, mode, byte);
4864 /* Return true if SRC should be moved into DEST using "MULT $0, $0".
4865 SPLIT_TYPE is the condition under which moves should be split. */
4867 static bool
4868 mips_mult_move_p (rtx dest, rtx src, enum mips_split_type split_type)
4870 return ((split_type != SPLIT_FOR_SPEED
4871 || mips_tuning_info.fast_mult_zero_zero_p)
4872 && src == const0_rtx
4873 && REG_P (dest)
4874 && GET_MODE_SIZE (GET_MODE (dest)) == 2 * UNITS_PER_WORD
4875 && (ISA_HAS_DSP_MULT
4876 ? ACC_REG_P (REGNO (dest))
4877 : MD_REG_P (REGNO (dest))));
4880 /* Return true if a move from SRC to DEST should be split into two.
4881 SPLIT_TYPE describes the split condition. */
4883 bool
4884 mips_split_move_p (rtx dest, rtx src, enum mips_split_type split_type)
4886 /* Check whether the move can be done using some variant of MULT $0,$0. */
4887 if (mips_mult_move_p (dest, src, split_type))
4888 return false;
4890 /* FPR-to-FPR moves can be done in a single instruction, if they're
4891 allowed at all. */
4892 unsigned int size = GET_MODE_SIZE (GET_MODE (dest));
4893 if (size == 8 && FP_REG_RTX_P (src) && FP_REG_RTX_P (dest))
4894 return false;
4896 /* Check for floating-point loads and stores. */
4897 if (size == 8 && ISA_HAS_LDC1_SDC1)
4899 if (FP_REG_RTX_P (dest) && MEM_P (src))
4900 return false;
4901 if (FP_REG_RTX_P (src) && MEM_P (dest))
4902 return false;
4905 /* Check if MSA moves need splitting. */
4906 if (MSA_SUPPORTED_MODE_P (GET_MODE (dest)))
4907 return mips_split_128bit_move_p (dest, src);
4909 /* Otherwise split all multiword moves. */
4910 return size > UNITS_PER_WORD;
4913 /* Split a move from SRC to DEST, given that mips_split_move_p holds.
4914 SPLIT_TYPE describes the split condition. INSN is the insn being
4915 split, if we know it, NULL otherwise. */
4917 void
4918 mips_split_move (rtx dest, rtx src, enum mips_split_type split_type, rtx insn_)
4920 rtx low_dest;
4922 gcc_checking_assert (mips_split_move_p (dest, src, split_type));
4923 if (MSA_SUPPORTED_MODE_P (GET_MODE (dest)))
4924 mips_split_128bit_move (dest, src);
4925 else if (FP_REG_RTX_P (dest) || FP_REG_RTX_P (src))
4927 if (!TARGET_64BIT && GET_MODE (dest) == DImode)
4928 emit_insn (gen_move_doubleword_fprdi (dest, src));
4929 else if (!TARGET_64BIT && GET_MODE (dest) == DFmode)
4930 emit_insn (gen_move_doubleword_fprdf (dest, src));
4931 else if (!TARGET_64BIT && GET_MODE (dest) == V2SFmode)
4932 emit_insn (gen_move_doubleword_fprv2sf (dest, src));
4933 else if (!TARGET_64BIT && GET_MODE (dest) == V2SImode)
4934 emit_insn (gen_move_doubleword_fprv2si (dest, src));
4935 else if (!TARGET_64BIT && GET_MODE (dest) == V4HImode)
4936 emit_insn (gen_move_doubleword_fprv4hi (dest, src));
4937 else if (!TARGET_64BIT && GET_MODE (dest) == V8QImode)
4938 emit_insn (gen_move_doubleword_fprv8qi (dest, src));
4939 else if (TARGET_64BIT && GET_MODE (dest) == TFmode)
4940 emit_insn (gen_move_doubleword_fprtf (dest, src));
4941 else
4942 gcc_unreachable ();
4944 else if (REG_P (dest) && REGNO (dest) == MD_REG_FIRST)
4946 low_dest = mips_subword (dest, false);
4947 mips_emit_move (low_dest, mips_subword (src, false));
4948 if (TARGET_64BIT)
4949 emit_insn (gen_mthidi_ti (dest, mips_subword (src, true), low_dest));
4950 else
4951 emit_insn (gen_mthisi_di (dest, mips_subword (src, true), low_dest));
4953 else if (REG_P (src) && REGNO (src) == MD_REG_FIRST)
4955 mips_emit_move (mips_subword (dest, false), mips_subword (src, false));
4956 if (TARGET_64BIT)
4957 emit_insn (gen_mfhidi_ti (mips_subword (dest, true), src));
4958 else
4959 emit_insn (gen_mfhisi_di (mips_subword (dest, true), src));
4961 else
4963 /* The operation can be split into two normal moves. Decide in
4964 which order to do them. */
4965 low_dest = mips_subword (dest, false);
4966 if (REG_P (low_dest)
4967 && reg_overlap_mentioned_p (low_dest, src))
4969 mips_emit_move (mips_subword (dest, true), mips_subword (src, true));
4970 mips_emit_move (low_dest, mips_subword (src, false));
4972 else
4974 mips_emit_move (low_dest, mips_subword (src, false));
4975 mips_emit_move (mips_subword (dest, true), mips_subword (src, true));
4979 /* This is a hack. See if the next insn uses DEST and if so, see if we
4980 can forward SRC for DEST. This is most useful if the next insn is a
4981 simple store. */
4982 rtx_insn *insn = (rtx_insn *)insn_;
4983 struct mips_address_info addr = {};
4984 if (insn)
4986 rtx_insn *next = next_nonnote_nondebug_insn_bb (insn);
4987 if (next)
4989 rtx set = single_set (next);
4990 if (set && SET_SRC (set) == dest)
4992 if (MEM_P (src))
4994 rtx tmp = XEXP (src, 0);
4995 mips_classify_address (&addr, tmp, GET_MODE (tmp), true);
4996 if (addr.reg && !reg_overlap_mentioned_p (dest, addr.reg))
4997 validate_change (next, &SET_SRC (set), src, false);
4999 else
5000 validate_change (next, &SET_SRC (set), src, false);
5006 /* Return the split type for instruction INSN. */
5008 static enum mips_split_type
5009 mips_insn_split_type (rtx insn)
5011 basic_block bb = BLOCK_FOR_INSN (insn);
5012 if (bb)
5014 if (optimize_bb_for_speed_p (bb))
5015 return SPLIT_FOR_SPEED;
5016 else
5017 return SPLIT_FOR_SIZE;
5019 /* Once CFG information has been removed, we should trust the optimization
5020 decisions made by previous passes and only split where necessary. */
5021 return SPLIT_IF_NECESSARY;
5024 /* Return true if a 128-bit move from SRC to DEST should be split. */
5026 bool
5027 mips_split_128bit_move_p (rtx dest, rtx src)
5029 /* MSA-to-MSA moves can be done in a single instruction. */
5030 if (FP_REG_RTX_P (src) && FP_REG_RTX_P (dest))
5031 return false;
5033 /* Check for MSA loads and stores. */
5034 if (FP_REG_RTX_P (dest) && MEM_P (src))
5035 return false;
5036 if (FP_REG_RTX_P (src) && MEM_P (dest))
5037 return false;
5039 /* Check for MSA set to an immediate const vector with valid replicated
5040 element. */
5041 if (FP_REG_RTX_P (dest)
5042 && mips_const_vector_same_int_p (src, GET_MODE (src), -512, 511))
5043 return false;
5045 /* Check for MSA load zero immediate. */
5046 if (FP_REG_RTX_P (dest) && src == CONST0_RTX (GET_MODE (src)))
5047 return false;
5049 return true;
5052 /* Split a 128-bit move from SRC to DEST. */
5054 void
5055 mips_split_128bit_move (rtx dest, rtx src)
5057 int byte, index;
5058 rtx low_dest, low_src, d, s;
5060 if (FP_REG_RTX_P (dest))
5062 gcc_assert (!MEM_P (src));
5064 rtx new_dest = dest;
5065 if (!TARGET_64BIT)
5067 if (GET_MODE (dest) != V4SImode)
5068 new_dest = simplify_gen_subreg (V4SImode, dest, GET_MODE (dest), 0);
5070 else
5072 if (GET_MODE (dest) != V2DImode)
5073 new_dest = simplify_gen_subreg (V2DImode, dest, GET_MODE (dest), 0);
5076 for (byte = 0, index = 0; byte < GET_MODE_SIZE (TImode);
5077 byte += UNITS_PER_WORD, index++)
5079 s = mips_subword_at_byte (src, byte);
5080 if (!TARGET_64BIT)
5081 emit_insn (gen_msa_insert_w (new_dest, s, new_dest,
5082 GEN_INT (1 << index)));
5083 else
5084 emit_insn (gen_msa_insert_d (new_dest, s, new_dest,
5085 GEN_INT (1 << index)));
5088 else if (FP_REG_RTX_P (src))
5090 gcc_assert (!MEM_P (dest));
5092 rtx new_src = src;
5093 if (!TARGET_64BIT)
5095 if (GET_MODE (src) != V4SImode)
5096 new_src = simplify_gen_subreg (V4SImode, src, GET_MODE (src), 0);
5098 else
5100 if (GET_MODE (src) != V2DImode)
5101 new_src = simplify_gen_subreg (V2DImode, src, GET_MODE (src), 0);
5104 for (byte = 0, index = 0; byte < GET_MODE_SIZE (TImode);
5105 byte += UNITS_PER_WORD, index++)
5107 d = mips_subword_at_byte (dest, byte);
5108 if (!TARGET_64BIT)
5109 emit_insn (gen_msa_copy_s_w (d, new_src, GEN_INT (index)));
5110 else
5111 emit_insn (gen_msa_copy_s_d (d, new_src, GEN_INT (index)));
5114 else
5116 low_dest = mips_subword_at_byte (dest, 0);
5117 low_src = mips_subword_at_byte (src, 0);
5118 gcc_assert (REG_P (low_dest) && REG_P (low_src));
5119 /* Make sure the source register is not written before reading. */
5120 if (REGNO (low_dest) <= REGNO (low_src))
5122 for (byte = 0; byte < GET_MODE_SIZE (TImode);
5123 byte += UNITS_PER_WORD)
5125 d = mips_subword_at_byte (dest, byte);
5126 s = mips_subword_at_byte (src, byte);
5127 mips_emit_move (d, s);
5130 else
5132 for (byte = GET_MODE_SIZE (TImode) - UNITS_PER_WORD; byte >= 0;
5133 byte -= UNITS_PER_WORD)
5135 d = mips_subword_at_byte (dest, byte);
5136 s = mips_subword_at_byte (src, byte);
5137 mips_emit_move (d, s);
5143 /* Split a COPY_S.D with operands DEST, SRC and INDEX. GEN is a function
5144 used to generate subregs. */
5146 void
5147 mips_split_msa_copy_d (rtx dest, rtx src, rtx index,
5148 rtx (*gen_fn)(rtx, rtx, rtx))
5150 gcc_assert ((GET_MODE (src) == V2DImode && GET_MODE (dest) == DImode)
5151 || (GET_MODE (src) == V2DFmode && GET_MODE (dest) == DFmode));
5153 /* Note that low is always from the lower index, and high is always
5154 from the higher index. */
5155 rtx low = mips_subword (dest, false);
5156 rtx high = mips_subword (dest, true);
5157 rtx new_src = simplify_gen_subreg (V4SImode, src, GET_MODE (src), 0);
5159 emit_insn (gen_fn (low, new_src, GEN_INT (INTVAL (index) * 2)));
5160 emit_insn (gen_fn (high, new_src, GEN_INT (INTVAL (index) * 2 + 1)));
5163 /* Split a INSERT.D with operand DEST, SRC1.INDEX and SRC2. */
5165 void
5166 mips_split_msa_insert_d (rtx dest, rtx src1, rtx index, rtx src2)
5168 int i;
5169 gcc_assert (GET_MODE (dest) == GET_MODE (src1));
5170 gcc_assert ((GET_MODE (dest) == V2DImode
5171 && (GET_MODE (src2) == DImode || src2 == const0_rtx))
5172 || (GET_MODE (dest) == V2DFmode && GET_MODE (src2) == DFmode));
5174 /* Note that low is always from the lower index, and high is always
5175 from the higher index. */
5176 rtx low = mips_subword (src2, false);
5177 rtx high = mips_subword (src2, true);
5178 rtx new_dest = simplify_gen_subreg (V4SImode, dest, GET_MODE (dest), 0);
5179 rtx new_src1 = simplify_gen_subreg (V4SImode, src1, GET_MODE (src1), 0);
5180 i = exact_log2 (INTVAL (index));
5181 gcc_assert (i != -1);
5183 emit_insn (gen_msa_insert_w (new_dest, low, new_src1,
5184 GEN_INT (1 << (i * 2))));
5185 emit_insn (gen_msa_insert_w (new_dest, high, new_dest,
5186 GEN_INT (1 << (i * 2 + 1))));
5189 /* Split FILL.D. */
5191 void
5192 mips_split_msa_fill_d (rtx dest, rtx src)
5194 gcc_assert ((GET_MODE (dest) == V2DImode
5195 && (GET_MODE (src) == DImode || src == const0_rtx))
5196 || (GET_MODE (dest) == V2DFmode && GET_MODE (src) == DFmode));
5198 /* Note that low is always from the lower index, and high is always
5199 from the higher index. */
5200 rtx low, high;
5201 if (src == const0_rtx)
5203 low = src;
5204 high = src;
5206 else
5208 low = mips_subword (src, false);
5209 high = mips_subword (src, true);
5211 rtx new_dest = simplify_gen_subreg (V4SImode, dest, GET_MODE (dest), 0);
5212 emit_insn (gen_msa_fill_w (new_dest, low));
5213 emit_insn (gen_msa_insert_w (new_dest, high, new_dest, GEN_INT (1 << 1)));
5214 emit_insn (gen_msa_insert_w (new_dest, high, new_dest, GEN_INT (1 << 3)));
5217 /* Return true if a move from SRC to DEST in INSN should be split. */
5219 bool
5220 mips_split_move_insn_p (rtx dest, rtx src, rtx insn)
5222 return mips_split_move_p (dest, src, mips_insn_split_type (insn));
5225 /* Split a move from SRC to DEST in INSN, given that mips_split_move_insn_p
5226 holds. */
5228 void
5229 mips_split_move_insn (rtx dest, rtx src, rtx insn)
5231 mips_split_move (dest, src, mips_insn_split_type (insn), insn);
5234 /* Return the appropriate instructions to move SRC into DEST. Assume
5235 that SRC is operand 1 and DEST is operand 0. */
5237 const char *
5238 mips_output_move (rtx dest, rtx src)
5240 enum rtx_code dest_code = GET_CODE (dest);
5241 enum rtx_code src_code = GET_CODE (src);
5242 machine_mode mode = GET_MODE (dest);
5243 bool dbl_p = (GET_MODE_SIZE (mode) == 8);
5244 bool msa_p = MSA_SUPPORTED_MODE_P (mode);
5245 enum mips_symbol_type symbol_type;
5247 if (mips_split_move_p (dest, src, SPLIT_IF_NECESSARY))
5248 return "#";
5250 if (msa_p
5251 && dest_code == REG && FP_REG_P (REGNO (dest))
5252 && src_code == CONST_VECTOR
5253 && CONST_INT_P (CONST_VECTOR_ELT (src, 0)))
5255 gcc_assert (mips_const_vector_same_int_p (src, mode, -512, 511));
5256 return "ldi.%v0\t%w0,%E1";
5259 if ((src_code == REG && GP_REG_P (REGNO (src)))
5260 || (!TARGET_MIPS16 && src == CONST0_RTX (mode)))
5262 if (dest_code == REG)
5264 if (GP_REG_P (REGNO (dest)))
5265 return "move\t%0,%z1";
5267 if (mips_mult_move_p (dest, src, SPLIT_IF_NECESSARY))
5269 if (ISA_HAS_DSP_MULT)
5270 return "mult\t%q0,%.,%.";
5271 else
5272 return "mult\t%.,%.";
5275 /* Moves to HI are handled by special .md insns. */
5276 if (REGNO (dest) == LO_REGNUM)
5277 return "mtlo\t%z1";
5279 if (DSP_ACC_REG_P (REGNO (dest)))
5281 static char retval[] = "mt__\t%z1,%q0";
5283 retval[2] = reg_names[REGNO (dest)][4];
5284 retval[3] = reg_names[REGNO (dest)][5];
5285 return retval;
5288 if (FP_REG_P (REGNO (dest)))
5290 if (msa_p)
5292 gcc_assert (src == CONST0_RTX (GET_MODE (src)));
5293 return "ldi.%v0\t%w0,0";
5296 return dbl_p ? "dmtc1\t%z1,%0" : "mtc1\t%z1,%0";
5299 if (ALL_COP_REG_P (REGNO (dest)))
5301 static char retval[] = "dmtc_\t%z1,%0";
5303 retval[4] = COPNUM_AS_CHAR_FROM_REGNUM (REGNO (dest));
5304 return dbl_p ? retval : retval + 1;
5307 if (dest_code == MEM)
5308 switch (GET_MODE_SIZE (mode))
5310 case 1: return "sb\t%z1,%0";
5311 case 2: return "sh\t%z1,%0";
5312 case 4: return "sw\t%z1,%0";
5313 case 8: return "sd\t%z1,%0";
5314 default: gcc_unreachable ();
5317 if (dest_code == REG && GP_REG_P (REGNO (dest)))
5319 if (src_code == REG)
5321 /* Moves from HI are handled by special .md insns. */
5322 if (REGNO (src) == LO_REGNUM)
5324 /* When generating VR4120 or VR4130 code, we use MACC and
5325 DMACC instead of MFLO. This avoids both the normal
5326 MIPS III HI/LO hazards and the errata related to
5327 -mfix-vr4130. */
5328 if (ISA_HAS_MACCHI)
5329 return dbl_p ? "dmacc\t%0,%.,%." : "macc\t%0,%.,%.";
5330 return "mflo\t%0";
5333 if (DSP_ACC_REG_P (REGNO (src)))
5335 static char retval[] = "mf__\t%0,%q1";
5337 retval[2] = reg_names[REGNO (src)][4];
5338 retval[3] = reg_names[REGNO (src)][5];
5339 return retval;
5342 if (FP_REG_P (REGNO (src)))
5344 gcc_assert (!msa_p);
5345 return dbl_p ? "dmfc1\t%0,%1" : "mfc1\t%0,%1";
5348 if (ALL_COP_REG_P (REGNO (src)))
5350 static char retval[] = "dmfc_\t%0,%1";
5352 retval[4] = COPNUM_AS_CHAR_FROM_REGNUM (REGNO (src));
5353 return dbl_p ? retval : retval + 1;
5357 if (src_code == MEM)
5358 switch (GET_MODE_SIZE (mode))
5360 case 1: return "lbu\t%0,%1";
5361 case 2: return "lhu\t%0,%1";
5362 case 4: return "lw\t%0,%1";
5363 case 8: return "ld\t%0,%1";
5364 default: gcc_unreachable ();
5367 if (src_code == CONST_INT)
5369 /* Don't use the X format for the operand itself, because that
5370 will give out-of-range numbers for 64-bit hosts and 32-bit
5371 targets. */
5372 if (!TARGET_MIPS16)
5373 return "li\t%0,%1\t\t\t# %X1";
5375 if (ISA_HAS_MIPS16E2
5376 && LUI_INT (src)
5377 && !SMALL_OPERAND_UNSIGNED (INTVAL (src)))
5378 return "lui\t%0,%%hi(%1)\t\t\t# %X1";
5380 if (SMALL_OPERAND_UNSIGNED (INTVAL (src)))
5381 return "li\t%0,%1";
5383 if (SMALL_OPERAND_UNSIGNED (-INTVAL (src)))
5384 return "#";
5387 if (src_code == HIGH)
5388 return (TARGET_MIPS16 && !ISA_HAS_MIPS16E2) ? "#" : "lui\t%0,%h1";
5390 if (CONST_GP_P (src))
5391 return "move\t%0,%1";
5393 if (mips_symbolic_constant_p (src, SYMBOL_CONTEXT_LEA, &symbol_type)
5394 && mips_lo_relocs[symbol_type] != 0)
5396 /* A signed 16-bit constant formed by applying a relocation
5397 operator to a symbolic address. */
5398 gcc_assert (!mips_split_p[symbol_type]);
5399 return "li\t%0,%R1";
5402 if (symbolic_operand (src, VOIDmode))
5404 gcc_assert (TARGET_MIPS16
5405 ? TARGET_MIPS16_TEXT_LOADS
5406 : !TARGET_EXPLICIT_RELOCS);
5407 return dbl_p ? "dla\t%0,%1" : "la\t%0,%1";
5410 if (src_code == REG && FP_REG_P (REGNO (src)))
5412 if (dest_code == REG && FP_REG_P (REGNO (dest)))
5414 if (GET_MODE (dest) == V2SFmode)
5415 return "mov.ps\t%0,%1";
5416 else if (msa_p)
5417 return "move.v\t%w0,%w1";
5418 else
5419 return dbl_p ? "mov.d\t%0,%1" : "mov.s\t%0,%1";
5422 if (dest_code == MEM)
5424 if (msa_p)
5425 return "st.%v1\t%w1,%0";
5427 return dbl_p ? "sdc1\t%1,%0" : "swc1\t%1,%0";
5430 if (dest_code == REG && FP_REG_P (REGNO (dest)))
5432 if (src_code == MEM)
5434 if (msa_p)
5435 return "ld.%v0\t%w0,%1";
5437 return dbl_p ? "ldc1\t%0,%1" : "lwc1\t%0,%1";
5440 if (dest_code == REG && ALL_COP_REG_P (REGNO (dest)) && src_code == MEM)
5442 static char retval[] = "l_c_\t%0,%1";
5444 retval[1] = (dbl_p ? 'd' : 'w');
5445 retval[3] = COPNUM_AS_CHAR_FROM_REGNUM (REGNO (dest));
5446 return retval;
5448 if (dest_code == MEM && src_code == REG && ALL_COP_REG_P (REGNO (src)))
5450 static char retval[] = "s_c_\t%1,%0";
5452 retval[1] = (dbl_p ? 'd' : 'w');
5453 retval[3] = COPNUM_AS_CHAR_FROM_REGNUM (REGNO (src));
5454 return retval;
5456 gcc_unreachable ();
5459 /* Return true if CMP1 is a suitable second operand for integer ordering
5460 test CODE. See also the *sCC patterns in mips.md. */
5462 static bool
5463 mips_int_order_operand_ok_p (enum rtx_code code, rtx cmp1)
5465 switch (code)
5467 case GT:
5468 case GTU:
5469 return reg_or_0_operand (cmp1, VOIDmode);
5471 case GE:
5472 case GEU:
5473 return !TARGET_MIPS16 && cmp1 == const1_rtx;
5475 case LT:
5476 case LTU:
5477 return arith_operand (cmp1, VOIDmode);
5479 case LE:
5480 return sle_operand (cmp1, VOIDmode);
5482 case LEU:
5483 return sleu_operand (cmp1, VOIDmode);
5485 default:
5486 gcc_unreachable ();
5490 /* Return true if *CMP1 (of mode MODE) is a valid second operand for
5491 integer ordering test *CODE, or if an equivalent combination can
5492 be formed by adjusting *CODE and *CMP1. When returning true, update
5493 *CODE and *CMP1 with the chosen code and operand, otherwise leave
5494 them alone. */
5496 static bool
5497 mips_canonicalize_int_order_test (enum rtx_code *code, rtx *cmp1,
5498 machine_mode mode)
5500 HOST_WIDE_INT plus_one;
5502 if (mips_int_order_operand_ok_p (*code, *cmp1))
5503 return true;
5505 if (CONST_INT_P (*cmp1))
5506 switch (*code)
5508 case LE:
5509 plus_one = trunc_int_for_mode (UINTVAL (*cmp1) + 1, mode);
5510 if (INTVAL (*cmp1) < plus_one)
5512 *code = LT;
5513 *cmp1 = force_reg (mode, GEN_INT (plus_one));
5514 return true;
5516 break;
5518 case LEU:
5519 plus_one = trunc_int_for_mode (UINTVAL (*cmp1) + 1, mode);
5520 if (plus_one != 0)
5522 *code = LTU;
5523 *cmp1 = force_reg (mode, GEN_INT (plus_one));
5524 return true;
5526 break;
5528 default:
5529 break;
5531 return false;
5534 /* Compare CMP0 and CMP1 using ordering test CODE and store the result
5535 in TARGET. CMP0 and TARGET are register_operands. If INVERT_PTR
5536 is nonnull, it's OK to set TARGET to the inverse of the result and
5537 flip *INVERT_PTR instead. */
5539 static void
5540 mips_emit_int_order_test (enum rtx_code code, bool *invert_ptr,
5541 rtx target, rtx cmp0, rtx cmp1)
5543 machine_mode mode;
5545 /* First see if there is a MIPS instruction that can do this operation.
5546 If not, try doing the same for the inverse operation. If that also
5547 fails, force CMP1 into a register and try again. */
5548 mode = GET_MODE (cmp0);
5549 if (mips_canonicalize_int_order_test (&code, &cmp1, mode))
5550 mips_emit_binary (code, target, cmp0, cmp1);
5551 else
5553 enum rtx_code inv_code = reverse_condition (code);
5554 if (!mips_canonicalize_int_order_test (&inv_code, &cmp1, mode))
5556 cmp1 = force_reg (mode, cmp1);
5557 mips_emit_int_order_test (code, invert_ptr, target, cmp0, cmp1);
5559 else if (invert_ptr == 0)
5561 rtx inv_target;
5563 inv_target = mips_force_binary (GET_MODE (target),
5564 inv_code, cmp0, cmp1);
5565 mips_emit_binary (XOR, target, inv_target, const1_rtx);
5567 else
5569 *invert_ptr = !*invert_ptr;
5570 mips_emit_binary (inv_code, target, cmp0, cmp1);
5575 /* Return a register that is zero iff CMP0 and CMP1 are equal.
5576 The register will have the same mode as CMP0. */
5578 static rtx
5579 mips_zero_if_equal (rtx cmp0, rtx cmp1)
5581 if (cmp1 == const0_rtx)
5582 return cmp0;
5584 if (uns_arith_operand (cmp1, VOIDmode))
5585 return expand_binop (GET_MODE (cmp0), xor_optab,
5586 cmp0, cmp1, 0, 0, OPTAB_DIRECT);
5588 return expand_binop (GET_MODE (cmp0), sub_optab,
5589 cmp0, cmp1, 0, 0, OPTAB_DIRECT);
5592 /* Convert *CODE into a code that can be used in a floating-point
5593 scc instruction (C.cond.fmt). Return true if the values of
5594 the condition code registers will be inverted, with 0 indicating
5595 that the condition holds. */
5597 static bool
5598 mips_reversed_fp_cond (enum rtx_code *code)
5600 switch (*code)
5602 case NE:
5603 case LTGT:
5604 case ORDERED:
5605 *code = reverse_condition_maybe_unordered (*code);
5606 return true;
5608 default:
5609 return false;
5613 /* Allocate a floating-point condition-code register of mode MODE.
5615 These condition code registers are used for certain kinds
5616 of compound operation, such as compare and branches, vconds,
5617 and built-in functions. At expand time, their use is entirely
5618 controlled by MIPS-specific code and is entirely internal
5619 to these compound operations.
5621 We could (and did in the past) expose condition-code values
5622 as pseudo registers and leave the register allocator to pick
5623 appropriate registers. The problem is that it is not practically
5624 possible for the rtl optimizers to guarantee that no spills will
5625 be needed, even when AVOID_CCMODE_COPIES is defined. We would
5626 therefore need spill and reload sequences to handle the worst case.
5628 Although such sequences do exist, they are very expensive and are
5629 not something we'd want to use. This is especially true of CCV2 and
5630 CCV4, where all the shuffling would greatly outweigh whatever benefit
5631 the vectorization itself provides.
5633 The main benefit of having more than one condition-code register
5634 is to allow the pipelining of operations, especially those involving
5635 comparisons and conditional moves. We don't really expect the
5636 registers to be live for long periods, and certainly never want
5637 them to be live across calls.
5639 Also, there should be no penalty attached to using all the available
5640 registers. They are simply bits in the same underlying FPU control
5641 register.
5643 We therefore expose the hardware registers from the outset and use
5644 a simple round-robin allocation scheme. */
5646 static rtx
5647 mips_allocate_fcc (machine_mode mode)
5649 unsigned int regno, count;
5651 gcc_assert (TARGET_HARD_FLOAT && ISA_HAS_8CC);
5653 if (mode == CCmode)
5654 count = 1;
5655 else if (mode == CCV2mode)
5656 count = 2;
5657 else if (mode == CCV4mode)
5658 count = 4;
5659 else
5660 gcc_unreachable ();
5662 cfun->machine->next_fcc += -cfun->machine->next_fcc & (count - 1);
5663 if (cfun->machine->next_fcc > ST_REG_LAST - ST_REG_FIRST)
5664 cfun->machine->next_fcc = 0;
5665 regno = ST_REG_FIRST + cfun->machine->next_fcc;
5666 cfun->machine->next_fcc += count;
5667 return gen_rtx_REG (mode, regno);
5670 /* Convert a comparison into something that can be used in a branch or
5671 conditional move. On entry, *OP0 and *OP1 are the values being
5672 compared and *CODE is the code used to compare them.
5674 Update *CODE, *OP0 and *OP1 so that they describe the final comparison.
5675 If NEED_EQ_NE_P, then only EQ or NE comparisons against zero are possible,
5676 otherwise any standard branch condition can be used. The standard branch
5677 conditions are:
5679 - EQ or NE between two registers.
5680 - any comparison between a register and zero.
5681 - if compact branches are available then any condition is valid. */
5683 static void
5684 mips_emit_compare (enum rtx_code *code, rtx *op0, rtx *op1, bool need_eq_ne_p)
5686 rtx cmp_op0 = *op0;
5687 rtx cmp_op1 = *op1;
5689 if (GET_MODE_CLASS (GET_MODE (*op0)) == MODE_INT)
5691 if (!need_eq_ne_p && *op1 == const0_rtx)
5693 else if (*code == EQ || *code == NE)
5695 if (need_eq_ne_p)
5697 *op0 = mips_zero_if_equal (cmp_op0, cmp_op1);
5698 *op1 = const0_rtx;
5700 else
5701 *op1 = force_reg (GET_MODE (cmp_op0), cmp_op1);
5703 else if (!need_eq_ne_p && TARGET_CB_MAYBE)
5705 bool swap = false;
5706 switch (*code)
5708 case LE:
5709 swap = true;
5710 *code = GE;
5711 break;
5712 case GT:
5713 swap = true;
5714 *code = LT;
5715 break;
5716 case LEU:
5717 swap = true;
5718 *code = GEU;
5719 break;
5720 case GTU:
5721 swap = true;
5722 *code = LTU;
5723 break;
5724 case GE:
5725 case LT:
5726 case GEU:
5727 case LTU:
5728 /* Do nothing. */
5729 break;
5730 default:
5731 gcc_unreachable ();
5733 *op1 = force_reg (GET_MODE (cmp_op0), cmp_op1);
5734 if (swap)
5736 rtx tmp = *op1;
5737 *op1 = *op0;
5738 *op0 = tmp;
5741 else
5743 /* The comparison needs a separate scc instruction. Store the
5744 result of the scc in *OP0 and compare it against zero. */
5745 bool invert = false;
5746 *op0 = gen_reg_rtx (GET_MODE (cmp_op0));
5747 mips_emit_int_order_test (*code, &invert, *op0, cmp_op0, cmp_op1);
5748 *code = (invert ? EQ : NE);
5749 *op1 = const0_rtx;
5752 else if (ALL_FIXED_POINT_MODE_P (GET_MODE (cmp_op0)))
5754 *op0 = gen_rtx_REG (CCDSPmode, CCDSP_CC_REGNUM);
5755 mips_emit_binary (*code, *op0, cmp_op0, cmp_op1);
5756 *code = NE;
5757 *op1 = const0_rtx;
5759 else
5761 enum rtx_code cmp_code;
5763 /* Floating-point tests use a separate C.cond.fmt or CMP.cond.fmt
5764 comparison to set a register. The branch or conditional move will
5765 then compare that register against zero.
5767 Set CMP_CODE to the code of the comparison instruction and
5768 *CODE to the code that the branch or move should use. */
5769 cmp_code = *code;
5770 if (ISA_HAS_CCF)
5772 /* All FP conditions can be implemented directly with CMP.cond.fmt
5773 or by reversing the operands. */
5774 *code = NE;
5775 *op0 = gen_reg_rtx (CCFmode);
5777 else
5779 /* Three FP conditions cannot be implemented by reversing the
5780 operands for C.cond.fmt, instead a reversed condition code is
5781 required and a test for false. */
5782 *code = mips_reversed_fp_cond (&cmp_code) ? EQ : NE;
5783 if (ISA_HAS_8CC)
5784 *op0 = mips_allocate_fcc (CCmode);
5785 else
5786 *op0 = gen_rtx_REG (CCmode, FPSW_REGNUM);
5789 *op1 = const0_rtx;
5790 mips_emit_binary (cmp_code, *op0, cmp_op0, cmp_op1);
5794 /* Try performing the comparison in OPERANDS[1], whose arms are OPERANDS[2]
5795 and OPERAND[3]. Store the result in OPERANDS[0].
5797 On 64-bit targets, the mode of the comparison and target will always be
5798 SImode, thus possibly narrower than that of the comparison's operands. */
5800 void
5801 mips_expand_scc (rtx operands[])
5803 rtx target = operands[0];
5804 enum rtx_code code = GET_CODE (operands[1]);
5805 rtx op0 = operands[2];
5806 rtx op1 = operands[3];
5808 gcc_assert (GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT);
5810 if (code == EQ || code == NE)
5812 if (ISA_HAS_SEQ_SNE
5813 && reg_imm10_operand (op1, GET_MODE (op1)))
5814 mips_emit_binary (code, target, op0, op1);
5815 else
5817 rtx zie = mips_zero_if_equal (op0, op1);
5818 mips_emit_binary (code, target, zie, const0_rtx);
5821 else
5822 mips_emit_int_order_test (code, 0, target, op0, op1);
5825 /* Compare OPERANDS[1] with OPERANDS[2] using comparison code
5826 CODE and jump to OPERANDS[3] if the condition holds. */
5828 void
5829 mips_expand_conditional_branch (rtx *operands)
5831 enum rtx_code code = GET_CODE (operands[0]);
5832 rtx op0 = operands[1];
5833 rtx op1 = operands[2];
5834 rtx condition;
5836 mips_emit_compare (&code, &op0, &op1, TARGET_MIPS16);
5837 condition = gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
5838 emit_jump_insn (gen_condjump (condition, operands[3]));
5841 /* Implement:
5843 (set temp (COND:CCV2 CMP_OP0 CMP_OP1))
5844 (set DEST (unspec [TRUE_SRC FALSE_SRC temp] UNSPEC_MOVE_TF_PS)) */
5846 void
5847 mips_expand_vcondv2sf (rtx dest, rtx true_src, rtx false_src,
5848 enum rtx_code cond, rtx cmp_op0, rtx cmp_op1)
5850 rtx cmp_result;
5851 bool reversed_p;
5853 reversed_p = mips_reversed_fp_cond (&cond);
5854 cmp_result = mips_allocate_fcc (CCV2mode);
5855 emit_insn (gen_scc_ps (cmp_result,
5856 gen_rtx_fmt_ee (cond, VOIDmode, cmp_op0, cmp_op1)));
5857 if (reversed_p)
5858 emit_insn (gen_mips_cond_move_tf_ps (dest, false_src, true_src,
5859 cmp_result));
5860 else
5861 emit_insn (gen_mips_cond_move_tf_ps (dest, true_src, false_src,
5862 cmp_result));
5865 /* Perform the comparison in OPERANDS[1]. Move OPERANDS[2] into OPERANDS[0]
5866 if the condition holds, otherwise move OPERANDS[3] into OPERANDS[0]. */
5868 void
5869 mips_expand_conditional_move (rtx *operands)
5871 rtx cond;
5872 enum rtx_code code = GET_CODE (operands[1]);
5873 rtx op0 = XEXP (operands[1], 0);
5874 rtx op1 = XEXP (operands[1], 1);
5876 mips_emit_compare (&code, &op0, &op1, true);
5877 cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
5879 /* There is no direct support for general conditional GP move involving
5880 two registers using SEL. */
5881 if (ISA_HAS_SEL
5882 && INTEGRAL_MODE_P (GET_MODE (operands[2]))
5883 && register_operand (operands[2], VOIDmode)
5884 && register_operand (operands[3], VOIDmode))
5886 machine_mode mode = GET_MODE (operands[0]);
5887 rtx temp = gen_reg_rtx (mode);
5888 rtx temp2 = gen_reg_rtx (mode);
5890 emit_insn (gen_rtx_SET (temp,
5891 gen_rtx_IF_THEN_ELSE (mode, cond,
5892 operands[2], const0_rtx)));
5894 /* Flip the test for the second operand. */
5895 cond = gen_rtx_fmt_ee ((code == EQ) ? NE : EQ, GET_MODE (op0), op0, op1);
5897 emit_insn (gen_rtx_SET (temp2,
5898 gen_rtx_IF_THEN_ELSE (mode, cond,
5899 operands[3], const0_rtx)));
5901 /* Merge the two results, at least one is guaranteed to be zero. */
5902 emit_insn (gen_rtx_SET (operands[0], gen_rtx_IOR (mode, temp, temp2)));
5904 else
5906 if (FLOAT_MODE_P (GET_MODE (operands[2])) && !ISA_HAS_SEL)
5908 operands[2] = force_reg (GET_MODE (operands[0]), operands[2]);
5909 operands[3] = force_reg (GET_MODE (operands[0]), operands[3]);
5912 emit_insn (gen_rtx_SET (operands[0],
5913 gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]), cond,
5914 operands[2], operands[3])));
5918 /* Perform the comparison in COMPARISON, then trap if the condition holds. */
5920 void
5921 mips_expand_conditional_trap (rtx comparison)
5923 rtx op0, op1;
5924 machine_mode mode;
5925 enum rtx_code code;
5927 /* MIPS conditional trap instructions don't have GT or LE flavors,
5928 so we must swap the operands and convert to LT and GE respectively. */
5929 code = GET_CODE (comparison);
5930 switch (code)
5932 case GT:
5933 case LE:
5934 case GTU:
5935 case LEU:
5936 code = swap_condition (code);
5937 op0 = XEXP (comparison, 1);
5938 op1 = XEXP (comparison, 0);
5939 break;
5941 default:
5942 op0 = XEXP (comparison, 0);
5943 op1 = XEXP (comparison, 1);
5944 break;
5947 mode = GET_MODE (XEXP (comparison, 0));
5948 op0 = force_reg (mode, op0);
5949 if (!(ISA_HAS_COND_TRAPI
5950 ? arith_operand (op1, mode)
5951 : reg_or_0_operand (op1, mode)))
5952 op1 = force_reg (mode, op1);
5954 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
5955 gen_rtx_fmt_ee (code, mode, op0, op1),
5956 const0_rtx));
5959 /* Initialize *CUM for a call to a function of type FNTYPE. */
5961 void
5962 mips_init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype)
5964 memset (cum, 0, sizeof (*cum));
5965 cum->prototype = (fntype && prototype_p (fntype));
5966 cum->gp_reg_found = (cum->prototype && stdarg_p (fntype));
5969 /* Fill INFO with information about a single argument. CUM is the
5970 cumulative state for earlier arguments. MODE is the mode of this
5971 argument and TYPE is its type (if known). NAMED is true if this
5972 is a named (fixed) argument rather than a variable one. */
5974 static void
5975 mips_get_arg_info (struct mips_arg_info *info, const CUMULATIVE_ARGS *cum,
5976 machine_mode mode, const_tree type, bool named)
5978 bool doubleword_aligned_p;
5979 unsigned int num_bytes, num_words, max_regs;
5981 /* Work out the size of the argument. */
5982 num_bytes = type ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
5983 num_words = (num_bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
5985 /* Decide whether it should go in a floating-point register, assuming
5986 one is free. Later code checks for availability.
5988 The checks against UNITS_PER_FPVALUE handle the soft-float and
5989 single-float cases. */
5990 switch (mips_abi)
5992 case ABI_EABI:
5993 /* The EABI conventions have traditionally been defined in terms
5994 of TYPE_MODE, regardless of the actual type. */
5995 info->fpr_p = ((GET_MODE_CLASS (mode) == MODE_FLOAT
5996 || mode == V2SFmode)
5997 && GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE);
5998 break;
6000 case ABI_32:
6001 case ABI_O64:
6002 /* Only leading floating-point scalars are passed in
6003 floating-point registers. We also handle vector floats the same
6004 say, which is OK because they are not covered by the standard ABI. */
6005 gcc_assert (TARGET_PAIRED_SINGLE_FLOAT || mode != V2SFmode);
6006 info->fpr_p = (!cum->gp_reg_found
6007 && cum->arg_number < 2
6008 && (type == 0
6009 || SCALAR_FLOAT_TYPE_P (type)
6010 || VECTOR_FLOAT_TYPE_P (type))
6011 && (GET_MODE_CLASS (mode) == MODE_FLOAT
6012 || mode == V2SFmode)
6013 && GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE);
6014 break;
6016 case ABI_N32:
6017 case ABI_64:
6018 /* Scalar, complex and vector floating-point types are passed in
6019 floating-point registers, as long as this is a named rather
6020 than a variable argument. */
6021 gcc_assert (TARGET_PAIRED_SINGLE_FLOAT || mode != V2SFmode);
6022 info->fpr_p = (named
6023 && (type == 0 || FLOAT_TYPE_P (type))
6024 && (GET_MODE_CLASS (mode) == MODE_FLOAT
6025 || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
6026 || mode == V2SFmode)
6027 && GET_MODE_UNIT_SIZE (mode) <= UNITS_PER_FPVALUE);
6029 /* ??? According to the ABI documentation, the real and imaginary
6030 parts of complex floats should be passed in individual registers.
6031 The real and imaginary parts of stack arguments are supposed
6032 to be contiguous and there should be an extra word of padding
6033 at the end.
6035 This has two problems. First, it makes it impossible to use a
6036 single "void *" va_list type, since register and stack arguments
6037 are passed differently. (At the time of writing, MIPSpro cannot
6038 handle complex float varargs correctly.) Second, it's unclear
6039 what should happen when there is only one register free.
6041 For now, we assume that named complex floats should go into FPRs
6042 if there are two FPRs free, otherwise they should be passed in the
6043 same way as a struct containing two floats. */
6044 if (info->fpr_p
6045 && GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
6046 && GET_MODE_UNIT_SIZE (mode) < UNITS_PER_FPVALUE)
6048 if (cum->num_gprs >= MAX_ARGS_IN_REGISTERS - 1)
6049 info->fpr_p = false;
6050 else
6051 num_words = 2;
6053 break;
6055 default:
6056 gcc_unreachable ();
6059 /* See whether the argument has doubleword alignment. */
6060 doubleword_aligned_p = (mips_function_arg_boundary (mode, type)
6061 > BITS_PER_WORD);
6063 /* Set REG_OFFSET to the register count we're interested in.
6064 The EABI allocates the floating-point registers separately,
6065 but the other ABIs allocate them like integer registers. */
6066 info->reg_offset = (mips_abi == ABI_EABI && info->fpr_p
6067 ? cum->num_fprs
6068 : cum->num_gprs);
6070 /* Advance to an even register if the argument is doubleword-aligned. */
6071 if (doubleword_aligned_p)
6072 info->reg_offset += info->reg_offset & 1;
6074 /* Work out the offset of a stack argument. */
6075 info->stack_offset = cum->stack_words;
6076 if (doubleword_aligned_p)
6077 info->stack_offset += info->stack_offset & 1;
6079 max_regs = MAX_ARGS_IN_REGISTERS - info->reg_offset;
6081 /* Partition the argument between registers and stack. */
6082 info->reg_words = MIN (num_words, max_regs);
6083 info->stack_words = num_words - info->reg_words;
6086 /* INFO describes a register argument that has the normal format for the
6087 argument's mode. Return the register it uses, assuming that FPRs are
6088 available if HARD_FLOAT_P. */
6090 static unsigned int
6091 mips_arg_regno (const struct mips_arg_info *info, bool hard_float_p)
6093 if (!info->fpr_p || !hard_float_p)
6094 return GP_ARG_FIRST + info->reg_offset;
6095 else if (mips_abi == ABI_32 && TARGET_DOUBLE_FLOAT && info->reg_offset > 0)
6096 /* In o32, the second argument is always passed in $f14
6097 for TARGET_DOUBLE_FLOAT, regardless of whether the
6098 first argument was a word or doubleword. */
6099 return FP_ARG_FIRST + 2;
6100 else
6101 return FP_ARG_FIRST + info->reg_offset;
6104 /* Implement TARGET_STRICT_ARGUMENT_NAMING. */
6106 static bool
6107 mips_strict_argument_naming (cumulative_args_t ca ATTRIBUTE_UNUSED)
6109 return !TARGET_OLDABI;
6112 /* Implement TARGET_FUNCTION_ARG. */
6114 static rtx
6115 mips_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
6117 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
6118 struct mips_arg_info info;
6120 /* We will be called with an end marker after the last argument
6121 has been seen. Whatever we return will be passed to the call expander.
6122 If we need a MIPS16 fp_code, return a REG with the code stored as
6123 the mode. */
6124 if (arg.end_marker_p ())
6126 if (TARGET_MIPS16 && cum->fp_code != 0)
6127 return gen_rtx_REG ((machine_mode) cum->fp_code, 0);
6128 else
6129 return NULL;
6132 mips_get_arg_info (&info, cum, arg.mode, arg.type, arg.named);
6134 /* Return straight away if the whole argument is passed on the stack. */
6135 if (info.reg_offset == MAX_ARGS_IN_REGISTERS)
6136 return NULL;
6138 /* The n32 and n64 ABIs say that if any 64-bit chunk of the structure
6139 contains a double in its entirety, then that 64-bit chunk is passed
6140 in a floating-point register. */
6141 if (TARGET_NEWABI
6142 && TARGET_HARD_FLOAT
6143 && arg.named
6144 && arg.type != 0
6145 && TREE_CODE (arg.type) == RECORD_TYPE
6146 && TYPE_SIZE_UNIT (arg.type)
6147 && tree_fits_uhwi_p (TYPE_SIZE_UNIT (arg.type)))
6149 tree field;
6151 /* First check to see if there is any such field. */
6152 for (field = TYPE_FIELDS (arg.type); field; field = DECL_CHAIN (field))
6153 if (TREE_CODE (field) == FIELD_DECL
6154 && SCALAR_FLOAT_TYPE_P (TREE_TYPE (field))
6155 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD
6156 && tree_fits_shwi_p (bit_position (field))
6157 && int_bit_position (field) % BITS_PER_WORD == 0)
6158 break;
6160 if (field != 0)
6162 /* Now handle the special case by returning a PARALLEL
6163 indicating where each 64-bit chunk goes. INFO.REG_WORDS
6164 chunks are passed in registers. */
6165 unsigned int i;
6166 HOST_WIDE_INT bitpos;
6167 rtx ret;
6169 /* assign_parms checks the mode of ENTRY_PARM, so we must
6170 use the actual mode here. */
6171 ret = gen_rtx_PARALLEL (arg.mode, rtvec_alloc (info.reg_words));
6173 bitpos = 0;
6174 field = TYPE_FIELDS (arg.type);
6175 for (i = 0; i < info.reg_words; i++)
6177 rtx reg;
6178 bool zero_width_field_abi_change = false;
6180 for (; field; field = DECL_CHAIN (field))
6182 if (TREE_CODE (field) != FIELD_DECL)
6183 continue;
6185 /* Ignore zero-width fields. And, if the ignored
6186 field is not a C++ zero-width bit-field, it may be
6187 an ABI change. */
6188 if (DECL_FIELD_CXX_ZERO_WIDTH_BIT_FIELD (field))
6189 continue;
6190 if (DECL_SIZE (field)
6191 && integer_zerop (DECL_SIZE (field)))
6193 zero_width_field_abi_change = true;
6194 continue;
6197 if (int_bit_position (field) >= bitpos)
6198 break;
6201 if (field
6202 && int_bit_position (field) == bitpos
6203 && SCALAR_FLOAT_TYPE_P (TREE_TYPE (field))
6204 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD)
6205 reg = gen_rtx_REG (DFmode, FP_ARG_FIRST + info.reg_offset + i);
6206 else
6208 reg = gen_rtx_REG (DImode,
6209 GP_ARG_FIRST + info.reg_offset + i);
6210 zero_width_field_abi_change = false;
6213 if (zero_width_field_abi_change && warn_psabi)
6215 static unsigned last_reported_type_uid;
6216 unsigned uid = TYPE_UID (TYPE_MAIN_VARIANT (arg.type));
6217 if (uid != last_reported_type_uid)
6219 static const char *url
6220 = CHANGES_ROOT_URL
6221 "gcc-12/changes.html#mips_zero_width_fields";
6222 inform (input_location,
6223 "the ABI for passing a value containing "
6224 "zero-width fields before an adjacent "
6225 "64-bit floating-point field was changed "
6226 "in GCC %{12.1%}", url);
6227 last_reported_type_uid = uid;
6231 XVECEXP (ret, 0, i)
6232 = gen_rtx_EXPR_LIST (VOIDmode, reg,
6233 GEN_INT (bitpos / BITS_PER_UNIT));
6235 bitpos += BITS_PER_WORD;
6237 return ret;
6241 /* Handle the n32/n64 conventions for passing complex floating-point
6242 arguments in FPR pairs. The real part goes in the lower register
6243 and the imaginary part goes in the upper register. */
6244 if (TARGET_NEWABI
6245 && info.fpr_p
6246 && GET_MODE_CLASS (arg.mode) == MODE_COMPLEX_FLOAT)
6248 rtx real, imag;
6249 machine_mode inner;
6250 unsigned int regno;
6252 inner = GET_MODE_INNER (arg.mode);
6253 regno = FP_ARG_FIRST + info.reg_offset;
6254 if (info.reg_words * UNITS_PER_WORD == GET_MODE_SIZE (inner))
6256 /* Real part in registers, imaginary part on stack. */
6257 gcc_assert (info.stack_words == info.reg_words);
6258 return gen_rtx_REG (inner, regno);
6260 else
6262 gcc_assert (info.stack_words == 0);
6263 real = gen_rtx_EXPR_LIST (VOIDmode,
6264 gen_rtx_REG (inner, regno),
6265 const0_rtx);
6266 imag = gen_rtx_EXPR_LIST (VOIDmode,
6267 gen_rtx_REG (inner,
6268 regno + info.reg_words / 2),
6269 GEN_INT (GET_MODE_SIZE (inner)));
6270 return gen_rtx_PARALLEL (arg.mode, gen_rtvec (2, real, imag));
6274 return gen_rtx_REG (arg.mode, mips_arg_regno (&info, TARGET_HARD_FLOAT));
6277 /* Implement TARGET_FUNCTION_ARG_ADVANCE. */
6279 static void
6280 mips_function_arg_advance (cumulative_args_t cum_v,
6281 const function_arg_info &arg)
6283 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
6284 struct mips_arg_info info;
6286 mips_get_arg_info (&info, cum, arg.mode, arg.type, arg.named);
6288 if (!info.fpr_p)
6289 cum->gp_reg_found = true;
6291 /* See the comment above the CUMULATIVE_ARGS structure in mips.h for
6292 an explanation of what this code does. It assumes that we're using
6293 either the o32 or the o64 ABI, both of which pass at most 2 arguments
6294 in FPRs. */
6295 if (cum->arg_number < 2 && info.fpr_p)
6296 cum->fp_code += (arg.mode == SFmode ? 1 : 2) << (cum->arg_number * 2);
6298 /* Advance the register count. This has the effect of setting
6299 num_gprs to MAX_ARGS_IN_REGISTERS if a doubleword-aligned
6300 argument required us to skip the final GPR and pass the whole
6301 argument on the stack. */
6302 if (mips_abi != ABI_EABI || !info.fpr_p)
6303 cum->num_gprs = info.reg_offset + info.reg_words;
6304 else if (info.reg_words > 0)
6305 cum->num_fprs += MAX_FPRS_PER_FMT;
6307 /* Advance the stack word count. */
6308 if (info.stack_words > 0)
6309 cum->stack_words = info.stack_offset + info.stack_words;
6311 cum->arg_number++;
6314 /* Implement TARGET_ARG_PARTIAL_BYTES. */
6316 static int
6317 mips_arg_partial_bytes (cumulative_args_t cum, const function_arg_info &arg)
6319 struct mips_arg_info info;
6321 mips_get_arg_info (&info, get_cumulative_args (cum),
6322 arg.mode, arg.type, arg.named);
6323 return info.stack_words > 0 ? info.reg_words * UNITS_PER_WORD : 0;
6326 /* Given MODE and TYPE of a function argument, return the alignment in
6327 bits.
6328 In case of typedef, alignment of its original type is
6329 used. */
6331 static unsigned int
6332 mips_function_arg_alignment (machine_mode mode, const_tree type)
6334 if (!type)
6335 return GET_MODE_ALIGNMENT (mode);
6337 if (is_typedef_decl (TYPE_NAME (type)))
6338 type = DECL_ORIGINAL_TYPE (TYPE_NAME (type));
6340 return TYPE_ALIGN (type);
6343 /* Implement TARGET_FUNCTION_ARG_BOUNDARY. Every parameter gets at
6344 least PARM_BOUNDARY bits of alignment, but will be given anything up
6345 to STACK_BOUNDARY bits if the type requires it. */
6347 static unsigned int
6348 mips_function_arg_boundary (machine_mode mode, const_tree type)
6350 unsigned int alignment;
6351 alignment = mips_function_arg_alignment (mode, type);
6353 if (alignment < PARM_BOUNDARY)
6354 alignment = PARM_BOUNDARY;
6355 if (alignment > STACK_BOUNDARY)
6356 alignment = STACK_BOUNDARY;
6357 return alignment;
6360 /* Implement TARGET_GET_RAW_RESULT_MODE and TARGET_GET_RAW_ARG_MODE. */
6362 static fixed_size_mode
6363 mips_get_reg_raw_mode (int regno)
6365 if (TARGET_FLOATXX && FP_REG_P (regno))
6366 return DFmode;
6367 return default_get_reg_raw_mode (regno);
6370 /* Implement TARGET_FUNCTION_ARG_PADDING; return PAD_UPWARD if the first
6371 byte of the stack slot has useful data, PAD_DOWNWARD if the last byte
6372 does. */
6374 static pad_direction
6375 mips_function_arg_padding (machine_mode mode, const_tree type)
6377 /* On little-endian targets, the first byte of every stack argument
6378 is passed in the first byte of the stack slot. */
6379 if (!BYTES_BIG_ENDIAN)
6380 return PAD_UPWARD;
6382 /* Otherwise, integral types are padded downward: the last byte of a
6383 stack argument is passed in the last byte of the stack slot. */
6384 if (type != 0
6385 ? (INTEGRAL_TYPE_P (type)
6386 || POINTER_TYPE_P (type)
6387 || FIXED_POINT_TYPE_P (type))
6388 : (SCALAR_INT_MODE_P (mode)
6389 || ALL_SCALAR_FIXED_POINT_MODE_P (mode)))
6390 return PAD_DOWNWARD;
6392 /* Big-endian o64 pads floating-point arguments downward. */
6393 if (mips_abi == ABI_O64)
6394 if (type != 0 ? FLOAT_TYPE_P (type) : GET_MODE_CLASS (mode) == MODE_FLOAT)
6395 return PAD_DOWNWARD;
6397 /* Other types are padded upward for o32, o64, n32 and n64. */
6398 if (mips_abi != ABI_EABI)
6399 return PAD_UPWARD;
6401 /* Arguments smaller than a stack slot are padded downward. */
6402 if (mode != BLKmode
6403 ? GET_MODE_BITSIZE (mode) >= PARM_BOUNDARY
6404 : int_size_in_bytes (type) >= (PARM_BOUNDARY / BITS_PER_UNIT))
6405 return PAD_UPWARD;
6407 return PAD_DOWNWARD;
6410 /* Likewise BLOCK_REG_PADDING (MODE, TYPE, ...). Return !BYTES_BIG_ENDIAN
6411 if the least significant byte of the register has useful data. Return
6412 the opposite if the most significant byte does. */
6414 bool
6415 mips_pad_reg_upward (machine_mode mode, tree type)
6417 /* No shifting is required for floating-point arguments. */
6418 if (type != 0 ? FLOAT_TYPE_P (type) : GET_MODE_CLASS (mode) == MODE_FLOAT)
6419 return !BYTES_BIG_ENDIAN;
6421 /* Otherwise, apply the same padding to register arguments as we do
6422 to stack arguments. */
6423 return mips_function_arg_padding (mode, type) == PAD_UPWARD;
6426 /* Return nonzero when an argument must be passed by reference. */
6428 static bool
6429 mips_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
6431 if (mips_abi == ABI_EABI)
6433 int size;
6435 /* ??? How should SCmode be handled? */
6436 if (arg.mode == DImode || arg.mode == DFmode
6437 || arg.mode == DQmode || arg.mode == UDQmode
6438 || arg.mode == DAmode || arg.mode == UDAmode)
6439 return 0;
6441 size = arg.type_size_in_bytes ();
6442 return size == -1 || size > UNITS_PER_WORD;
6444 else
6446 /* If we have a variable-sized parameter, we have no choice. */
6447 return targetm.calls.must_pass_in_stack (arg);
6451 /* Implement TARGET_CALLEE_COPIES. */
6453 static bool
6454 mips_callee_copies (cumulative_args_t, const function_arg_info &arg)
6456 return mips_abi == ABI_EABI && arg.named;
6459 /* See whether VALTYPE is a record whose fields should be returned in
6460 floating-point registers. If so, return the number of fields and
6461 list them in FIELDS (which should have two elements). Return 0
6462 otherwise.
6464 For n32 & n64, a structure with one or two fields is returned in
6465 floating-point registers as long as every field has a floating-point
6466 type.
6468 The C++ FE used to remove zero-width bit-fields in GCC 11 and earlier.
6469 To make a proper diagnostic, this function will set
6470 HAS_CXX_ZERO_WIDTH_BF to true once a C++ zero-width bit-field shows up,
6471 and then ignore it.
6473 We had failed to ignore C++17 empty bases in GCC 7, 8, 9, 10, and 11.
6474 This caused an ABI incompatibility between C++14 and C++17. This is
6475 fixed now and to make a proper diagnostic, this function will set
6476 HAS_CXX17_EMPTY_BASE to true once a C++17 empty base shows up, and
6477 then ignore it.
6479 The caller should use the value of HAS_CXX17_EMPTY_BASE and/or
6480 HAS_CXX_ZERO_WIDTH_BF to emit a proper -Wpsabi inform. */
6482 static int
6483 mips_fpr_return_fields (const_tree valtype, tree *fields,
6484 bool *has_cxx_zero_width_bf,
6485 bool *has_cxx17_empty_base)
6487 tree field;
6488 int i;
6490 if (!TARGET_NEWABI)
6491 return 0;
6493 if (TREE_CODE (valtype) != RECORD_TYPE)
6494 return 0;
6496 i = 0;
6497 for (field = TYPE_FIELDS (valtype); field != 0; field = DECL_CHAIN (field))
6499 if (TREE_CODE (field) != FIELD_DECL)
6500 continue;
6502 if (cxx17_empty_base_field_p (field))
6504 *has_cxx17_empty_base = true;
6505 continue;
6508 if (DECL_FIELD_CXX_ZERO_WIDTH_BIT_FIELD (field))
6510 *has_cxx_zero_width_bf = true;
6511 continue;
6514 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (field)))
6515 return 0;
6517 if (i == 2)
6518 return 0;
6520 fields[i++] = field;
6522 return i;
6525 /* Implement TARGET_RETURN_IN_MSB. For n32 & n64, we should return
6526 a value in the most significant part of $2/$3 if:
6528 - the target is big-endian;
6530 - the value has a structure or union type (we generalize this to
6531 cover aggregates from other languages too); and
6533 - the structure is not returned in floating-point registers. */
6535 static bool
6536 mips_return_in_msb (const_tree valtype)
6538 if (!TARGET_NEWABI || !TARGET_BIG_ENDIAN || !AGGREGATE_TYPE_P (valtype))
6539 return false;
6541 tree fields[2];
6542 bool has_cxx_zero_width_bf = false;
6544 /* Its value is not used. */
6545 bool has_cxx17_empty_base = false;
6547 return (mips_fpr_return_fields (valtype, fields,
6548 &has_cxx_zero_width_bf,
6549 &has_cxx17_empty_base) == 0
6550 || has_cxx_zero_width_bf);
6553 /* Return true if the function return value MODE will get returned in a
6554 floating-point register. */
6556 static bool
6557 mips_return_mode_in_fpr_p (machine_mode mode)
6559 gcc_assert (TARGET_PAIRED_SINGLE_FLOAT || mode != V2SFmode);
6560 return ((GET_MODE_CLASS (mode) == MODE_FLOAT
6561 || mode == V2SFmode
6562 || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
6563 && GET_MODE_UNIT_SIZE (mode) <= UNITS_PER_HWFPVALUE);
6566 /* Return the representation of an FPR return register when the
6567 value being returned in FP_RETURN has mode VALUE_MODE and the
6568 return type itself has mode TYPE_MODE. On NewABI targets,
6569 the two modes may be different for structures like:
6571 struct __attribute__((packed)) foo { float f; }
6573 where we return the SFmode value of "f" in FP_RETURN, but where
6574 the structure itself has mode BLKmode. */
6576 static rtx
6577 mips_return_fpr_single (machine_mode type_mode,
6578 machine_mode value_mode)
6580 rtx x;
6582 x = gen_rtx_REG (value_mode, FP_RETURN);
6583 if (type_mode != value_mode)
6585 x = gen_rtx_EXPR_LIST (VOIDmode, x, const0_rtx);
6586 x = gen_rtx_PARALLEL (type_mode, gen_rtvec (1, x));
6588 return x;
6591 /* Return a composite value in a pair of floating-point registers.
6592 MODE1 and OFFSET1 are the mode and byte offset for the first value,
6593 likewise MODE2 and OFFSET2 for the second. MODE is the mode of the
6594 complete value.
6596 For n32 & n64, $f0 always holds the first value and $f2 the second.
6597 Otherwise the values are packed together as closely as possible. */
6599 static rtx
6600 mips_return_fpr_pair (machine_mode mode,
6601 machine_mode mode1, HOST_WIDE_INT offset1,
6602 machine_mode mode2, HOST_WIDE_INT offset2)
6604 int inc;
6606 inc = (TARGET_NEWABI || mips_abi == ABI_32 ? 2 : MAX_FPRS_PER_FMT);
6607 return gen_rtx_PARALLEL
6608 (mode,
6609 gen_rtvec (2,
6610 gen_rtx_EXPR_LIST (VOIDmode,
6611 gen_rtx_REG (mode1, FP_RETURN),
6612 GEN_INT (offset1)),
6613 gen_rtx_EXPR_LIST (VOIDmode,
6614 gen_rtx_REG (mode2, FP_RETURN + inc),
6615 GEN_INT (offset2))));
6619 /* Implement TARGET_FUNCTION_VALUE and TARGET_LIBCALL_VALUE.
6620 For normal calls, VALTYPE is the return type and MODE is VOIDmode.
6621 For libcalls, VALTYPE is null and MODE is the mode of the return value. */
6623 static rtx
6624 mips_function_value_1 (const_tree valtype, const_tree fn_decl_or_type,
6625 machine_mode mode)
6627 if (valtype)
6629 tree fields[2];
6630 int unsigned_p;
6631 const_tree func;
6633 if (fn_decl_or_type && DECL_P (fn_decl_or_type))
6634 func = fn_decl_or_type;
6635 else
6636 func = NULL;
6638 mode = TYPE_MODE (valtype);
6639 unsigned_p = TYPE_UNSIGNED (valtype);
6641 /* Since TARGET_PROMOTE_FUNCTION_MODE unconditionally promotes,
6642 return values, promote the mode here too. */
6643 mode = promote_function_mode (valtype, mode, &unsigned_p, func, 1);
6645 bool has_cxx_zero_width_bf = false;
6646 bool has_cxx17_empty_base = false;
6647 int use_fpr = mips_fpr_return_fields (valtype, fields,
6648 &has_cxx_zero_width_bf,
6649 &has_cxx17_empty_base);
6651 /* If has_cxx_zero_width_bf and has_cxx17_empty_base are both
6652 true, it *happens* that there is no ABI change. So we won't
6653 inform in this case. */
6654 if (TARGET_HARD_FLOAT
6655 && warn_psabi
6656 && has_cxx_zero_width_bf
6657 && !has_cxx17_empty_base
6658 && use_fpr != 0)
6660 static unsigned last_reported_type_uid;
6661 unsigned uid = TYPE_UID (TYPE_MAIN_VARIANT (valtype));
6662 if (uid != last_reported_type_uid)
6664 static const char *url
6665 = CHANGES_ROOT_URL
6666 "gcc-12/changes.html#zero_width_bitfields";
6667 inform (input_location,
6668 "the ABI for returning a value containing "
6669 "zero-width bit-fields but otherwise an aggregate "
6670 "with only one or two floating-point fields was "
6671 "changed in GCC %{12.1%}", url);
6672 last_reported_type_uid = uid;
6676 if (has_cxx_zero_width_bf)
6677 use_fpr = 0;
6679 if (TARGET_HARD_FLOAT
6680 && warn_psabi
6681 && use_fpr != 0
6682 && has_cxx17_empty_base)
6684 static unsigned last_reported_type_uid;
6685 unsigned uid = TYPE_UID (TYPE_MAIN_VARIANT (valtype));
6686 if (uid != last_reported_type_uid)
6688 static const char *url
6689 = CHANGES_ROOT_URL
6690 "gcc-12/changes.html#mips_cxx17_empty_bases";
6691 inform (input_location,
6692 "the ABI for returning a value with C++17 empty "
6693 "bases but otherwise an aggregate with only one or "
6694 "two floating-point fields was changed in GCC "
6695 "%{12.1%}", url);
6696 last_reported_type_uid = uid;
6700 /* Handle structures whose fields are returned in $f0/$f2. */
6701 switch (use_fpr)
6703 case 1:
6704 return mips_return_fpr_single (mode,
6705 TYPE_MODE (TREE_TYPE (fields[0])));
6707 case 2:
6708 return mips_return_fpr_pair (mode,
6709 TYPE_MODE (TREE_TYPE (fields[0])),
6710 int_byte_position (fields[0]),
6711 TYPE_MODE (TREE_TYPE (fields[1])),
6712 int_byte_position (fields[1]));
6715 /* If a value is passed in the most significant part of a register, see
6716 whether we have to round the mode up to a whole number of words. */
6717 if (mips_return_in_msb (valtype))
6719 HOST_WIDE_INT size = int_size_in_bytes (valtype);
6720 if (size % UNITS_PER_WORD != 0)
6722 size += UNITS_PER_WORD - size % UNITS_PER_WORD;
6723 mode = int_mode_for_size (size * BITS_PER_UNIT, 0).require ();
6727 /* For EABI, the class of return register depends entirely on MODE.
6728 For example, "struct { some_type x; }" and "union { some_type x; }"
6729 are returned in the same way as a bare "some_type" would be.
6730 Other ABIs only use FPRs for scalar, complex or vector types. */
6731 if (mips_abi != ABI_EABI && !FLOAT_TYPE_P (valtype))
6732 return gen_rtx_REG (mode, GP_RETURN);
6735 if (!TARGET_MIPS16)
6737 /* Handle long doubles for n32 & n64. */
6738 if (mode == TFmode)
6739 return mips_return_fpr_pair (mode,
6740 DImode, 0,
6741 DImode, GET_MODE_SIZE (mode) / 2);
6743 if (mips_return_mode_in_fpr_p (mode))
6745 if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
6746 return mips_return_fpr_pair (mode,
6747 GET_MODE_INNER (mode), 0,
6748 GET_MODE_INNER (mode),
6749 GET_MODE_SIZE (mode) / 2);
6750 else
6751 return gen_rtx_REG (mode, FP_RETURN);
6755 return gen_rtx_REG (mode, GP_RETURN);
6758 /* Implement TARGET_FUNCTION_VALUE. */
6760 static rtx
6761 mips_function_value (const_tree valtype, const_tree fn_decl_or_type,
6762 bool outgoing ATTRIBUTE_UNUSED)
6764 return mips_function_value_1 (valtype, fn_decl_or_type, VOIDmode);
6767 /* Implement TARGET_LIBCALL_VALUE. */
6769 static rtx
6770 mips_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
6772 return mips_function_value_1 (NULL_TREE, NULL_TREE, mode);
6775 /* Implement TARGET_FUNCTION_VALUE_REGNO_P.
6777 On the MIPS, R2 R3 and F0 F2 are the only register thus used. */
6779 static bool
6780 mips_function_value_regno_p (const unsigned int regno)
6782 /* Most types only require one GPR or one FPR for return values but for
6783 hard-float two FPRs can be used for _Complex types (for all ABIs)
6784 and long doubles (for n64). */
6785 if (regno == GP_RETURN
6786 || regno == FP_RETURN
6787 || (FP_RETURN != GP_RETURN
6788 && regno == FP_RETURN + 2))
6789 return true;
6791 /* For o32 FP32, _Complex double will be returned in four 32-bit registers.
6792 This does not apply to o32 FPXX as floating-point function argument and
6793 return registers are described as 64-bit even though floating-point
6794 registers are primarily described as 32-bit internally.
6795 See: mips_get_reg_raw_mode. */
6796 if ((mips_abi == ABI_32 && TARGET_FLOAT32)
6797 && FP_RETURN != GP_RETURN
6798 && (regno == FP_RETURN + 1
6799 || regno == FP_RETURN + 3))
6800 return true;
6802 return false;
6805 /* Implement TARGET_RETURN_IN_MEMORY. Under the o32 and o64 ABIs,
6806 all BLKmode objects are returned in memory. Under the n32, n64
6807 and embedded ABIs, small structures are returned in a register.
6808 Objects with varying size must still be returned in memory, of
6809 course. */
6811 static bool
6812 mips_return_in_memory (const_tree type, const_tree fndecl ATTRIBUTE_UNUSED)
6814 if (TARGET_OLDABI)
6815 /* Ensure that any floating point vector types are returned via memory
6816 even if they are supported through a vector mode with some ASEs. */
6817 return (VECTOR_FLOAT_TYPE_P (type)
6818 || TYPE_MODE (type) == BLKmode);
6820 return (!IN_RANGE (int_size_in_bytes (type), 0, 2 * UNITS_PER_WORD));
6823 /* Implement TARGET_SETUP_INCOMING_VARARGS. */
6825 static void
6826 mips_setup_incoming_varargs (cumulative_args_t cum,
6827 const function_arg_info &arg,
6828 int *pretend_size ATTRIBUTE_UNUSED, int no_rtl)
6830 CUMULATIVE_ARGS local_cum;
6831 int gp_saved, fp_saved;
6833 /* The caller has advanced CUM up to, but not beyond, the last named
6834 argument. Advance a local copy of CUM past the last "real" named
6835 argument, to find out how many registers are left over. */
6836 local_cum = *get_cumulative_args (cum);
6837 if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl)))
6838 mips_function_arg_advance (pack_cumulative_args (&local_cum), arg);
6840 /* Found out how many registers we need to save. */
6841 gp_saved = MAX_ARGS_IN_REGISTERS - local_cum.num_gprs;
6842 fp_saved = (EABI_FLOAT_VARARGS_P
6843 ? MAX_ARGS_IN_REGISTERS - local_cum.num_fprs
6844 : 0);
6846 if (!no_rtl)
6848 if (gp_saved > 0)
6850 rtx ptr, mem;
6852 ptr = plus_constant (Pmode, virtual_incoming_args_rtx,
6853 REG_PARM_STACK_SPACE (cfun->decl)
6854 - gp_saved * UNITS_PER_WORD);
6855 mem = gen_frame_mem (BLKmode, ptr);
6856 set_mem_alias_set (mem, get_varargs_alias_set ());
6858 move_block_from_reg (local_cum.num_gprs + GP_ARG_FIRST,
6859 mem, gp_saved);
6861 if (fp_saved > 0)
6863 /* We can't use move_block_from_reg, because it will use
6864 the wrong mode. */
6865 machine_mode mode;
6866 int off, i;
6868 /* Set OFF to the offset from virtual_incoming_args_rtx of
6869 the first float register. The FP save area lies below
6870 the integer one, and is aligned to UNITS_PER_FPVALUE bytes. */
6871 off = ROUND_DOWN (-gp_saved * UNITS_PER_WORD, UNITS_PER_FPVALUE);
6872 off -= fp_saved * UNITS_PER_FPREG;
6874 mode = TARGET_SINGLE_FLOAT ? SFmode : DFmode;
6876 for (i = local_cum.num_fprs; i < MAX_ARGS_IN_REGISTERS;
6877 i += MAX_FPRS_PER_FMT)
6879 rtx ptr, mem;
6881 ptr = plus_constant (Pmode, virtual_incoming_args_rtx, off);
6882 mem = gen_frame_mem (mode, ptr);
6883 set_mem_alias_set (mem, get_varargs_alias_set ());
6884 mips_emit_move (mem, gen_rtx_REG (mode, FP_ARG_FIRST + i));
6885 off += UNITS_PER_HWFPVALUE;
6889 if (REG_PARM_STACK_SPACE (cfun->decl) == 0)
6890 cfun->machine->varargs_size = (gp_saved * UNITS_PER_WORD
6891 + fp_saved * UNITS_PER_FPREG);
6894 /* Implement TARGET_BUILTIN_VA_LIST. */
6896 static tree
6897 mips_build_builtin_va_list (void)
6899 if (EABI_FLOAT_VARARGS_P)
6901 /* We keep 3 pointers, and two offsets.
6903 Two pointers are to the overflow area, which starts at the CFA.
6904 One of these is constant, for addressing into the GPR save area
6905 below it. The other is advanced up the stack through the
6906 overflow region.
6908 The third pointer is to the bottom of the GPR save area.
6909 Since the FPR save area is just below it, we can address
6910 FPR slots off this pointer.
6912 We also keep two one-byte offsets, which are to be subtracted
6913 from the constant pointers to yield addresses in the GPR and
6914 FPR save areas. These are downcounted as float or non-float
6915 arguments are used, and when they get to zero, the argument
6916 must be obtained from the overflow region. */
6917 tree f_ovfl, f_gtop, f_ftop, f_goff, f_foff, f_res, record;
6918 tree array, index;
6920 record = lang_hooks.types.make_type (RECORD_TYPE);
6922 f_ovfl = build_decl (BUILTINS_LOCATION,
6923 FIELD_DECL, get_identifier ("__overflow_argptr"),
6924 ptr_type_node);
6925 f_gtop = build_decl (BUILTINS_LOCATION,
6926 FIELD_DECL, get_identifier ("__gpr_top"),
6927 ptr_type_node);
6928 f_ftop = build_decl (BUILTINS_LOCATION,
6929 FIELD_DECL, get_identifier ("__fpr_top"),
6930 ptr_type_node);
6931 f_goff = build_decl (BUILTINS_LOCATION,
6932 FIELD_DECL, get_identifier ("__gpr_offset"),
6933 unsigned_char_type_node);
6934 f_foff = build_decl (BUILTINS_LOCATION,
6935 FIELD_DECL, get_identifier ("__fpr_offset"),
6936 unsigned_char_type_node);
6937 /* Explicitly pad to the size of a pointer, so that -Wpadded won't
6938 warn on every user file. */
6939 index = build_int_cst (NULL_TREE, GET_MODE_SIZE (ptr_mode) - 2 - 1);
6940 array = build_array_type (unsigned_char_type_node,
6941 build_index_type (index));
6942 f_res = build_decl (BUILTINS_LOCATION,
6943 FIELD_DECL, get_identifier ("__reserved"), array);
6945 DECL_FIELD_CONTEXT (f_ovfl) = record;
6946 DECL_FIELD_CONTEXT (f_gtop) = record;
6947 DECL_FIELD_CONTEXT (f_ftop) = record;
6948 DECL_FIELD_CONTEXT (f_goff) = record;
6949 DECL_FIELD_CONTEXT (f_foff) = record;
6950 DECL_FIELD_CONTEXT (f_res) = record;
6952 TYPE_FIELDS (record) = f_ovfl;
6953 DECL_CHAIN (f_ovfl) = f_gtop;
6954 DECL_CHAIN (f_gtop) = f_ftop;
6955 DECL_CHAIN (f_ftop) = f_goff;
6956 DECL_CHAIN (f_goff) = f_foff;
6957 DECL_CHAIN (f_foff) = f_res;
6959 layout_type (record);
6960 return record;
6962 else
6963 /* Otherwise, we use 'void *'. */
6964 return ptr_type_node;
6967 /* Implement TARGET_EXPAND_BUILTIN_VA_START. */
6969 static void
6970 mips_va_start (tree valist, rtx nextarg)
6972 if (EABI_FLOAT_VARARGS_P)
6974 const CUMULATIVE_ARGS *cum;
6975 tree f_ovfl, f_gtop, f_ftop, f_goff, f_foff;
6976 tree ovfl, gtop, ftop, goff, foff;
6977 tree t;
6978 int gpr_save_area_size;
6979 int fpr_save_area_size;
6980 int fpr_offset;
6982 cum = &crtl->args.info;
6983 gpr_save_area_size
6984 = (MAX_ARGS_IN_REGISTERS - cum->num_gprs) * UNITS_PER_WORD;
6985 fpr_save_area_size
6986 = (MAX_ARGS_IN_REGISTERS - cum->num_fprs) * UNITS_PER_FPREG;
6988 f_ovfl = TYPE_FIELDS (va_list_type_node);
6989 f_gtop = DECL_CHAIN (f_ovfl);
6990 f_ftop = DECL_CHAIN (f_gtop);
6991 f_goff = DECL_CHAIN (f_ftop);
6992 f_foff = DECL_CHAIN (f_goff);
6994 ovfl = build3 (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl,
6995 NULL_TREE);
6996 gtop = build3 (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop,
6997 NULL_TREE);
6998 ftop = build3 (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop,
6999 NULL_TREE);
7000 goff = build3 (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff,
7001 NULL_TREE);
7002 foff = build3 (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff,
7003 NULL_TREE);
7005 /* Emit code to initialize OVFL, which points to the next varargs
7006 stack argument. CUM->STACK_WORDS gives the number of stack
7007 words used by named arguments. */
7008 t = make_tree (TREE_TYPE (ovfl), virtual_incoming_args_rtx);
7009 if (cum->stack_words > 0)
7010 t = fold_build_pointer_plus_hwi (t, cum->stack_words * UNITS_PER_WORD);
7011 t = build2 (MODIFY_EXPR, TREE_TYPE (ovfl), ovfl, t);
7012 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
7014 /* Emit code to initialize GTOP, the top of the GPR save area. */
7015 t = make_tree (TREE_TYPE (gtop), virtual_incoming_args_rtx);
7016 t = build2 (MODIFY_EXPR, TREE_TYPE (gtop), gtop, t);
7017 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
7019 /* Emit code to initialize FTOP, the top of the FPR save area.
7020 This address is gpr_save_area_bytes below GTOP, rounded
7021 down to the next fp-aligned boundary. */
7022 t = make_tree (TREE_TYPE (ftop), virtual_incoming_args_rtx);
7023 fpr_offset = gpr_save_area_size + UNITS_PER_FPVALUE - 1;
7024 fpr_offset &= -UNITS_PER_FPVALUE;
7025 if (fpr_offset)
7026 t = fold_build_pointer_plus_hwi (t, -fpr_offset);
7027 t = build2 (MODIFY_EXPR, TREE_TYPE (ftop), ftop, t);
7028 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
7030 /* Emit code to initialize GOFF, the offset from GTOP of the
7031 next GPR argument. */
7032 t = build2 (MODIFY_EXPR, TREE_TYPE (goff), goff,
7033 build_int_cst (TREE_TYPE (goff), gpr_save_area_size));
7034 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
7036 /* Likewise emit code to initialize FOFF, the offset from FTOP
7037 of the next FPR argument. */
7038 t = build2 (MODIFY_EXPR, TREE_TYPE (foff), foff,
7039 build_int_cst (TREE_TYPE (foff), fpr_save_area_size));
7040 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
7042 else
7044 nextarg = plus_constant (Pmode, nextarg, -cfun->machine->varargs_size);
7045 std_expand_builtin_va_start (valist, nextarg);
7049 /* Like std_gimplify_va_arg_expr, but apply alignment to zero-sized
7050 types as well. */
7052 static tree
7053 mips_std_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
7054 gimple_seq *post_p)
7056 tree addr, t, type_size, rounded_size, valist_tmp;
7057 unsigned HOST_WIDE_INT align, boundary;
7058 bool indirect;
7060 indirect = pass_va_arg_by_reference (type);
7061 if (indirect)
7062 type = build_pointer_type (type);
7064 align = PARM_BOUNDARY / BITS_PER_UNIT;
7065 boundary = targetm.calls.function_arg_boundary (TYPE_MODE (type), type);
7067 /* When we align parameter on stack for caller, if the parameter
7068 alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
7069 aligned at MAX_SUPPORTED_STACK_ALIGNMENT. We will match callee
7070 here with caller. */
7071 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
7072 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
7074 boundary /= BITS_PER_UNIT;
7076 /* Hoist the valist value into a temporary for the moment. */
7077 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
7079 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
7080 requires greater alignment, we must perform dynamic alignment. */
7081 if (boundary > align)
7083 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
7084 fold_build_pointer_plus_hwi (valist_tmp, boundary - 1));
7085 gimplify_and_add (t, pre_p);
7087 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
7088 fold_build2 (BIT_AND_EXPR, TREE_TYPE (valist),
7089 valist_tmp,
7090 build_int_cst (TREE_TYPE (valist), -boundary)));
7091 gimplify_and_add (t, pre_p);
7093 else
7094 boundary = align;
7096 /* If the actual alignment is less than the alignment of the type,
7097 adjust the type accordingly so that we don't assume strict alignment
7098 when dereferencing the pointer. */
7099 boundary *= BITS_PER_UNIT;
7100 if (boundary < TYPE_ALIGN (type))
7102 type = build_variant_type_copy (type);
7103 SET_TYPE_ALIGN (type, boundary);
7106 /* Compute the rounded size of the type. */
7107 type_size = size_in_bytes (type);
7108 rounded_size = round_up (type_size, align);
7110 /* Reduce rounded_size so it's sharable with the postqueue. */
7111 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
7113 /* Get AP. */
7114 addr = valist_tmp;
7115 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
7117 /* Small args are padded downward. */
7118 t = fold_build2_loc (input_location, GT_EXPR, sizetype,
7119 rounded_size, size_int (align));
7120 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
7121 size_binop (MINUS_EXPR, rounded_size, type_size));
7122 addr = fold_build_pointer_plus (addr, t);
7125 /* Compute new value for AP. */
7126 t = fold_build_pointer_plus (valist_tmp, rounded_size);
7127 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
7128 gimplify_and_add (t, pre_p);
7130 addr = fold_convert (build_pointer_type (type), addr);
7132 if (indirect)
7133 addr = build_va_arg_indirect_ref (addr);
7135 return build_va_arg_indirect_ref (addr);
7138 /* Implement TARGET_GIMPLIFY_VA_ARG_EXPR. */
7140 static tree
7141 mips_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
7142 gimple_seq *post_p)
7144 tree addr;
7145 bool indirect_p;
7147 indirect_p = pass_va_arg_by_reference (type);
7148 if (indirect_p)
7149 type = build_pointer_type (type);
7151 if (!EABI_FLOAT_VARARGS_P)
7152 addr = mips_std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
7153 else
7155 tree f_ovfl, f_gtop, f_ftop, f_goff, f_foff;
7156 tree ovfl, top, off, align;
7157 HOST_WIDE_INT size, rsize, osize;
7158 tree t, u;
7160 f_ovfl = TYPE_FIELDS (va_list_type_node);
7161 f_gtop = DECL_CHAIN (f_ovfl);
7162 f_ftop = DECL_CHAIN (f_gtop);
7163 f_goff = DECL_CHAIN (f_ftop);
7164 f_foff = DECL_CHAIN (f_goff);
7166 /* Let:
7168 TOP be the top of the GPR or FPR save area;
7169 OFF be the offset from TOP of the next register;
7170 ADDR_RTX be the address of the argument;
7171 SIZE be the number of bytes in the argument type;
7172 RSIZE be the number of bytes used to store the argument
7173 when it's in the register save area; and
7174 OSIZE be the number of bytes used to store it when it's
7175 in the stack overflow area.
7177 The code we want is:
7179 1: off &= -rsize; // round down
7180 2: if (off != 0)
7181 3: {
7182 4: addr_rtx = top - off + (BYTES_BIG_ENDIAN ? RSIZE - SIZE : 0);
7183 5: off -= rsize;
7184 6: }
7185 7: else
7186 8: {
7187 9: ovfl = ((intptr_t) ovfl + osize - 1) & -osize;
7188 10: addr_rtx = ovfl + (BYTES_BIG_ENDIAN ? OSIZE - SIZE : 0);
7189 11: ovfl += osize;
7190 14: }
7192 [1] and [9] can sometimes be optimized away. */
7194 ovfl = build3 (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl,
7195 NULL_TREE);
7196 size = int_size_in_bytes (type);
7198 if (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT
7199 && GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_FPVALUE)
7201 top = build3 (COMPONENT_REF, TREE_TYPE (f_ftop),
7202 unshare_expr (valist), f_ftop, NULL_TREE);
7203 off = build3 (COMPONENT_REF, TREE_TYPE (f_foff),
7204 unshare_expr (valist), f_foff, NULL_TREE);
7206 /* When va_start saves FPR arguments to the stack, each slot
7207 takes up UNITS_PER_HWFPVALUE bytes, regardless of the
7208 argument's precision. */
7209 rsize = UNITS_PER_HWFPVALUE;
7211 /* Overflow arguments are padded to UNITS_PER_WORD bytes
7212 (= PARM_BOUNDARY bits). This can be different from RSIZE
7213 in two cases:
7215 (1) On 32-bit targets when TYPE is a structure such as:
7217 struct s { float f; };
7219 Such structures are passed in paired FPRs, so RSIZE
7220 will be 8 bytes. However, the structure only takes
7221 up 4 bytes of memory, so OSIZE will only be 4.
7223 (2) In combinations such as -mgp64 -msingle-float
7224 -fshort-double. Doubles passed in registers will then take
7225 up 4 (UNITS_PER_HWFPVALUE) bytes, but those passed on the
7226 stack take up UNITS_PER_WORD bytes. */
7227 osize = MAX (GET_MODE_SIZE (TYPE_MODE (type)), UNITS_PER_WORD);
7229 else
7231 top = build3 (COMPONENT_REF, TREE_TYPE (f_gtop),
7232 unshare_expr (valist), f_gtop, NULL_TREE);
7233 off = build3 (COMPONENT_REF, TREE_TYPE (f_goff),
7234 unshare_expr (valist), f_goff, NULL_TREE);
7235 rsize = ROUND_UP (size, UNITS_PER_WORD);
7236 if (rsize > UNITS_PER_WORD)
7238 /* [1] Emit code for: off &= -rsize. */
7239 t = build2 (BIT_AND_EXPR, TREE_TYPE (off), unshare_expr (off),
7240 build_int_cst (TREE_TYPE (off), -rsize));
7241 gimplify_assign (unshare_expr (off), t, pre_p);
7243 osize = rsize;
7246 /* [2] Emit code to branch if off == 0. */
7247 t = build2 (NE_EXPR, boolean_type_node, unshare_expr (off),
7248 build_int_cst (TREE_TYPE (off), 0));
7249 addr = build3 (COND_EXPR, ptr_type_node, t, NULL_TREE, NULL_TREE);
7251 /* [5] Emit code for: off -= rsize. We do this as a form of
7252 post-decrement not available to C. */
7253 t = fold_convert (TREE_TYPE (off), build_int_cst (NULL_TREE, rsize));
7254 t = build2 (POSTDECREMENT_EXPR, TREE_TYPE (off), off, t);
7256 /* [4] Emit code for:
7257 addr_rtx = top - off + (BYTES_BIG_ENDIAN ? RSIZE - SIZE : 0). */
7258 t = fold_convert (sizetype, t);
7259 t = fold_build1 (NEGATE_EXPR, sizetype, t);
7260 t = fold_build_pointer_plus (top, t);
7261 if (BYTES_BIG_ENDIAN && rsize > size)
7262 t = fold_build_pointer_plus_hwi (t, rsize - size);
7263 COND_EXPR_THEN (addr) = t;
7265 if (osize > UNITS_PER_WORD)
7267 /* [9] Emit: ovfl = ((intptr_t) ovfl + osize - 1) & -osize. */
7268 t = fold_build_pointer_plus_hwi (unshare_expr (ovfl), osize - 1);
7269 u = build_int_cst (TREE_TYPE (t), -osize);
7270 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t, u);
7271 align = build2 (MODIFY_EXPR, TREE_TYPE (ovfl),
7272 unshare_expr (ovfl), t);
7274 else
7275 align = NULL;
7277 /* [10, 11] Emit code for:
7278 addr_rtx = ovfl + (BYTES_BIG_ENDIAN ? OSIZE - SIZE : 0)
7279 ovfl += osize. */
7280 u = fold_convert (TREE_TYPE (ovfl), build_int_cst (NULL_TREE, osize));
7281 t = build2 (POSTINCREMENT_EXPR, TREE_TYPE (ovfl), ovfl, u);
7282 if (BYTES_BIG_ENDIAN && osize > size)
7283 t = fold_build_pointer_plus_hwi (t, osize - size);
7285 /* String [9] and [10, 11] together. */
7286 if (align)
7287 t = build2 (COMPOUND_EXPR, TREE_TYPE (t), align, t);
7288 COND_EXPR_ELSE (addr) = t;
7290 addr = fold_convert (build_pointer_type (type), addr);
7291 addr = build_va_arg_indirect_ref (addr);
7294 if (indirect_p)
7295 addr = build_va_arg_indirect_ref (addr);
7297 return addr;
7300 /* Declare a unique, locally-binding function called NAME, then start
7301 its definition. */
7303 static tree
7304 mips_start_unique_function (const char *name)
7306 tree decl;
7308 decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
7309 get_identifier (name),
7310 build_function_type_list (void_type_node, NULL_TREE));
7311 DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL,
7312 NULL_TREE, void_type_node);
7313 TREE_PUBLIC (decl) = 1;
7314 TREE_STATIC (decl) = 1;
7316 cgraph_node::create (decl)->set_comdat_group (DECL_ASSEMBLER_NAME (decl));
7318 targetm.asm_out.unique_section (decl, 0);
7319 switch_to_section (get_named_section (decl, NULL, 0));
7321 targetm.asm_out.globalize_label (asm_out_file, name);
7322 fputs ("\t.hidden\t", asm_out_file);
7323 assemble_name (asm_out_file, name);
7324 putc ('\n', asm_out_file);
7326 return decl;
7329 /* Start a definition of function NAME. MIPS16_P indicates whether the
7330 function contains MIPS16 code. */
7332 static void
7333 mips_start_function_definition (const char *name, bool mips16_p, tree decl)
7335 if (mips16_p)
7336 fprintf (asm_out_file, "\t.set\tmips16\n");
7337 else
7338 fprintf (asm_out_file, "\t.set\tnomips16\n");
7340 if (TARGET_MICROMIPS)
7341 fprintf (asm_out_file, "\t.set\tmicromips\n");
7342 #ifdef HAVE_GAS_MICROMIPS
7343 else
7344 fprintf (asm_out_file, "\t.set\tnomicromips\n");
7345 #endif
7347 if (!flag_inhibit_size_directive)
7349 fputs ("\t.ent\t", asm_out_file);
7350 assemble_name (asm_out_file, name);
7351 fputs ("\n", asm_out_file);
7354 ASM_OUTPUT_TYPE_DIRECTIVE (asm_out_file, name, "function");
7356 /* Start the definition proper. */
7357 ASM_OUTPUT_FUNCTION_LABEL (asm_out_file, name, decl);
7360 /* End a function definition started by mips_start_function_definition. */
7362 static void
7363 mips_end_function_definition (const char *name)
7365 if (!flag_inhibit_size_directive)
7367 fputs ("\t.end\t", asm_out_file);
7368 assemble_name (asm_out_file, name);
7369 fputs ("\n", asm_out_file);
7373 /* If *STUB_PTR points to a stub, output a comdat-style definition for it,
7374 then free *STUB_PTR. */
7376 static void
7377 mips_finish_stub (mips_one_only_stub **stub_ptr)
7379 mips_one_only_stub *stub = *stub_ptr;
7380 if (!stub)
7381 return;
7383 const char *name = stub->get_name ();
7384 tree decl = mips_start_unique_function (name);
7385 mips_start_function_definition (name, false, decl);
7386 stub->output_body ();
7387 mips_end_function_definition (name);
7388 delete stub;
7389 *stub_ptr = 0;
7392 /* Return true if calls to X can use R_MIPS_CALL* relocations. */
7394 static bool
7395 mips_ok_for_lazy_binding_p (rtx x)
7397 return (TARGET_USE_GOT
7398 && GET_CODE (x) == SYMBOL_REF
7399 && !SYMBOL_REF_BIND_NOW_P (x)
7400 && !mips_symbol_binds_local_p (x));
7403 /* Load function address ADDR into register DEST. TYPE is as for
7404 mips_expand_call. Return true if we used an explicit lazy-binding
7405 sequence. */
7407 static bool
7408 mips_load_call_address (enum mips_call_type type, rtx dest, rtx addr)
7410 /* If we're generating PIC, and this call is to a global function,
7411 try to allow its address to be resolved lazily. This isn't
7412 possible for sibcalls when $gp is call-saved because the value
7413 of $gp on entry to the stub would be our caller's gp, not ours. */
7414 if (TARGET_EXPLICIT_RELOCS
7415 && !(type == MIPS_CALL_SIBCALL && TARGET_CALL_SAVED_GP)
7416 && mips_ok_for_lazy_binding_p (addr))
7418 addr = mips_got_load (dest, addr, SYMBOL_GOTOFF_CALL);
7419 emit_insn (gen_rtx_SET (dest, addr));
7420 return true;
7422 else
7424 mips_emit_move (dest, addr);
7425 return false;
7429 /* Each locally-defined hard-float MIPS16 function has a local symbol
7430 associated with it. This hash table maps the function symbol (FUNC)
7431 to the local symbol (LOCAL). */
7432 static GTY (()) hash_map<nofree_string_hash, rtx> *mips16_local_aliases;
7434 /* FUNC is the symbol for a locally-defined hard-float MIPS16 function.
7435 Return a local alias for it, creating a new one if necessary. */
7437 static rtx
7438 mips16_local_alias (rtx func)
7440 /* Create the hash table if this is the first call. */
7441 if (mips16_local_aliases == NULL)
7442 mips16_local_aliases = hash_map<nofree_string_hash, rtx>::create_ggc (37);
7444 /* Look up the function symbol, creating a new entry if need be. */
7445 bool existed;
7446 const char *func_name = XSTR (func, 0);
7447 rtx *slot = &mips16_local_aliases->get_or_insert (func_name, &existed);
7448 gcc_assert (slot != NULL);
7450 if (!existed)
7452 rtx local;
7454 /* Create a new SYMBOL_REF for the local symbol. The choice of
7455 __fn_local_* is based on the __fn_stub_* names that we've
7456 traditionally used for the non-MIPS16 stub. */
7457 func_name = targetm.strip_name_encoding (XSTR (func, 0));
7458 const char *local_name = ACONCAT (("__fn_local_", func_name, NULL));
7459 local = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (local_name));
7460 SYMBOL_REF_FLAGS (local) = SYMBOL_REF_FLAGS (func) | SYMBOL_FLAG_LOCAL;
7462 /* Create a new structure to represent the mapping. */
7463 *slot = local;
7465 return *slot;
7468 /* A chained list of functions for which mips16_build_call_stub has already
7469 generated a stub. NAME is the name of the function and FP_RET_P is true
7470 if the function returns a value in floating-point registers. */
7471 struct mips16_stub {
7472 struct mips16_stub *next;
7473 char *name;
7474 bool fp_ret_p;
7476 static struct mips16_stub *mips16_stubs;
7478 /* Return the two-character string that identifies floating-point
7479 return mode MODE in the name of a MIPS16 function stub. */
7481 static const char *
7482 mips16_call_stub_mode_suffix (machine_mode mode)
7484 if (mode == SFmode)
7485 return "sf";
7486 else if (mode == DFmode)
7487 return "df";
7488 else if (mode == SCmode)
7489 return "sc";
7490 else if (mode == DCmode)
7491 return "dc";
7492 else if (mode == V2SFmode)
7494 gcc_assert (TARGET_PAIRED_SINGLE_FLOAT);
7495 return "df";
7497 else
7498 gcc_unreachable ();
7501 /* Write instructions to move a 32-bit value between general register
7502 GPREG and floating-point register FPREG. DIRECTION is 't' to move
7503 from GPREG to FPREG and 'f' to move in the opposite direction. */
7505 static void
7506 mips_output_32bit_xfer (char direction, unsigned int gpreg, unsigned int fpreg)
7508 fprintf (asm_out_file, "\tm%cc1\t%s,%s\n", direction,
7509 reg_names[gpreg], reg_names[fpreg]);
7512 /* Likewise for 64-bit values. */
7514 static void
7515 mips_output_64bit_xfer (char direction, unsigned int gpreg, unsigned int fpreg)
7517 if (TARGET_64BIT)
7518 fprintf (asm_out_file, "\tdm%cc1\t%s,%s\n", direction,
7519 reg_names[gpreg], reg_names[fpreg]);
7520 else if (ISA_HAS_MXHC1)
7522 fprintf (asm_out_file, "\tm%cc1\t%s,%s\n", direction,
7523 reg_names[gpreg + TARGET_BIG_ENDIAN], reg_names[fpreg]);
7524 fprintf (asm_out_file, "\tm%chc1\t%s,%s\n", direction,
7525 reg_names[gpreg + TARGET_LITTLE_ENDIAN], reg_names[fpreg]);
7527 else if (TARGET_FLOATXX && direction == 't')
7529 /* Use the argument save area to move via memory. */
7530 fprintf (asm_out_file, "\tsw\t%s,0($sp)\n", reg_names[gpreg]);
7531 fprintf (asm_out_file, "\tsw\t%s,4($sp)\n", reg_names[gpreg + 1]);
7532 fprintf (asm_out_file, "\tldc1\t%s,0($sp)\n", reg_names[fpreg]);
7534 else if (TARGET_FLOATXX && direction == 'f')
7536 /* Use the argument save area to move via memory. */
7537 fprintf (asm_out_file, "\tsdc1\t%s,0($sp)\n", reg_names[fpreg]);
7538 fprintf (asm_out_file, "\tlw\t%s,0($sp)\n", reg_names[gpreg]);
7539 fprintf (asm_out_file, "\tlw\t%s,4($sp)\n", reg_names[gpreg + 1]);
7541 else
7543 /* Move the least-significant word. */
7544 fprintf (asm_out_file, "\tm%cc1\t%s,%s\n", direction,
7545 reg_names[gpreg + TARGET_BIG_ENDIAN], reg_names[fpreg]);
7546 /* ...then the most significant word. */
7547 fprintf (asm_out_file, "\tm%cc1\t%s,%s\n", direction,
7548 reg_names[gpreg + TARGET_LITTLE_ENDIAN], reg_names[fpreg + 1]);
7552 /* Write out code to move floating-point arguments into or out of
7553 general registers. FP_CODE is the code describing which arguments
7554 are present (see the comment above the definition of CUMULATIVE_ARGS
7555 in mips.h). DIRECTION is as for mips_output_32bit_xfer. */
7557 static void
7558 mips_output_args_xfer (int fp_code, char direction)
7560 unsigned int gparg, fparg, f;
7561 CUMULATIVE_ARGS cum;
7563 /* This code only works for o32 and o64. */
7564 gcc_assert (TARGET_OLDABI);
7566 mips_init_cumulative_args (&cum, NULL);
7568 for (f = (unsigned int) fp_code; f != 0; f >>= 2)
7570 machine_mode mode;
7571 struct mips_arg_info info;
7573 if ((f & 3) == 1)
7574 mode = SFmode;
7575 else if ((f & 3) == 2)
7576 mode = DFmode;
7577 else
7578 gcc_unreachable ();
7580 mips_get_arg_info (&info, &cum, mode, NULL, true);
7581 gparg = mips_arg_regno (&info, false);
7582 fparg = mips_arg_regno (&info, true);
7584 if (mode == SFmode)
7585 mips_output_32bit_xfer (direction, gparg, fparg);
7586 else
7587 mips_output_64bit_xfer (direction, gparg, fparg);
7589 function_arg_info arg (mode, /*named=*/true);
7590 mips_function_arg_advance (pack_cumulative_args (&cum), arg);
7594 /* Write a MIPS16 stub for the current function. This stub is used
7595 for functions which take arguments in the floating-point registers.
7596 It is normal-mode code that moves the floating-point arguments
7597 into the general registers and then jumps to the MIPS16 code. */
7599 static void
7600 mips16_build_function_stub (void)
7602 const char *fnname, *alias_name, *separator;
7603 char *secname, *stubname;
7604 tree stubdecl;
7605 unsigned int f;
7606 rtx symbol, alias;
7608 /* Create the name of the stub, and its unique section. */
7609 symbol = XEXP (DECL_RTL (current_function_decl), 0);
7610 alias = mips16_local_alias (symbol);
7612 fnname = targetm.strip_name_encoding (XSTR (symbol, 0));
7613 alias_name = targetm.strip_name_encoding (XSTR (alias, 0));
7614 secname = ACONCAT ((".mips16.fn.", fnname, NULL));
7615 stubname = ACONCAT (("__fn_stub_", fnname, NULL));
7617 /* Build a decl for the stub. */
7618 stubdecl = build_decl (BUILTINS_LOCATION,
7619 FUNCTION_DECL, get_identifier (stubname),
7620 build_function_type_list (void_type_node, NULL_TREE));
7621 set_decl_section_name (stubdecl, secname);
7622 DECL_RESULT (stubdecl) = build_decl (BUILTINS_LOCATION,
7623 RESULT_DECL, NULL_TREE, void_type_node);
7625 /* Output a comment. */
7626 fprintf (asm_out_file, "\t# Stub function for %s (",
7627 current_function_name ());
7628 separator = "";
7629 for (f = (unsigned int) crtl->args.info.fp_code; f != 0; f >>= 2)
7631 fprintf (asm_out_file, "%s%s", separator,
7632 (f & 3) == 1 ? "float" : "double");
7633 separator = ", ";
7635 fprintf (asm_out_file, ")\n");
7637 /* Start the function definition. */
7638 assemble_start_function (stubdecl, stubname);
7639 mips_start_function_definition (stubname, false, stubdecl);
7641 /* If generating pic2 code, either set up the global pointer or
7642 switch to pic0. */
7643 if (TARGET_ABICALLS_PIC2)
7645 if (TARGET_ABSOLUTE_ABICALLS)
7646 fprintf (asm_out_file, "\t.option\tpic0\n");
7647 else
7649 output_asm_insn ("%(.cpload\t%^%)", NULL);
7650 /* Emit an R_MIPS_NONE relocation to tell the linker what the
7651 target function is. Use a local GOT access when loading the
7652 symbol, to cut down on the number of unnecessary GOT entries
7653 for stubs that aren't needed. */
7654 output_asm_insn (".reloc\t0,R_MIPS_NONE,%0", &symbol);
7655 symbol = alias;
7659 /* Load the address of the MIPS16 function into $25. Do this first so
7660 that targets with coprocessor interlocks can use an MFC1 to fill the
7661 delay slot. */
7662 output_asm_insn ("la\t%^,%0", &symbol);
7664 /* Move the arguments from floating-point registers to general registers. */
7665 mips_output_args_xfer (crtl->args.info.fp_code, 'f');
7667 /* Jump to the MIPS16 function. */
7668 output_asm_insn ("jr\t%^", NULL);
7670 if (TARGET_ABICALLS_PIC2 && TARGET_ABSOLUTE_ABICALLS)
7671 fprintf (asm_out_file, "\t.option\tpic2\n");
7673 mips_end_function_definition (stubname);
7675 /* If the linker needs to create a dynamic symbol for the target
7676 function, it will associate the symbol with the stub (which,
7677 unlike the target function, follows the proper calling conventions).
7678 It is therefore useful to have a local alias for the target function,
7679 so that it can still be identified as MIPS16 code. As an optimization,
7680 this symbol can also be used for indirect MIPS16 references from
7681 within this file. */
7682 ASM_OUTPUT_DEF (asm_out_file, alias_name, fnname);
7684 switch_to_section (function_section (current_function_decl));
7687 /* The current function is a MIPS16 function that returns a value in an FPR.
7688 Copy the return value from its soft-float to its hard-float location.
7689 libgcc2 has special non-MIPS16 helper functions for each case. */
7691 static void
7692 mips16_copy_fpr_return_value (void)
7694 rtx fn, insn, retval;
7695 tree return_type;
7696 machine_mode return_mode;
7697 const char *name;
7699 return_type = DECL_RESULT (current_function_decl);
7700 return_mode = DECL_MODE (return_type);
7702 name = ACONCAT (("__mips16_ret_",
7703 mips16_call_stub_mode_suffix (return_mode),
7704 NULL));
7705 fn = mips16_stub_function (name);
7707 /* The function takes arguments in $2 (and possibly $3), so calls
7708 to it cannot be lazily bound. */
7709 SYMBOL_REF_FLAGS (fn) |= SYMBOL_FLAG_BIND_NOW;
7711 /* Model the call as something that takes the GPR return value as
7712 argument and returns an "updated" value. */
7713 retval = gen_rtx_REG (return_mode, GP_RETURN);
7714 insn = mips_expand_call (MIPS_CALL_EPILOGUE, retval, fn,
7715 const0_rtx, NULL_RTX, false);
7716 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), retval);
7719 /* Consider building a stub for a MIPS16 call to function *FN_PTR.
7720 RETVAL is the location of the return value, or null if this is
7721 a "call" rather than a "call_value". ARGS_SIZE is the size of the
7722 arguments and FP_CODE is the code built by mips_function_arg;
7723 see the comment before the fp_code field in CUMULATIVE_ARGS for details.
7725 There are three alternatives:
7727 - If a stub was needed, emit the call and return the call insn itself.
7729 - If we can avoid using a stub by redirecting the call, set *FN_PTR
7730 to the new target and return null.
7732 - If *FN_PTR doesn't need a stub, return null and leave *FN_PTR
7733 unmodified.
7735 A stub is needed for calls to functions that, in normal mode,
7736 receive arguments in FPRs or return values in FPRs. The stub
7737 copies the arguments from their soft-float positions to their
7738 hard-float positions, calls the real function, then copies the
7739 return value from its hard-float position to its soft-float
7740 position.
7742 We can emit a JAL to *FN_PTR even when *FN_PTR might need a stub.
7743 If *FN_PTR turns out to be to a non-MIPS16 function, the linker
7744 automatically redirects the JAL to the stub, otherwise the JAL
7745 continues to call FN directly. */
7747 static rtx_insn *
7748 mips16_build_call_stub (rtx retval, rtx *fn_ptr, rtx args_size, int fp_code)
7750 const char *fnname;
7751 bool fp_ret_p;
7752 struct mips16_stub *l;
7753 rtx_insn *insn;
7754 rtx pattern, fn;
7756 /* We don't need to do anything if we aren't in MIPS16 mode, or if
7757 we were invoked with the -msoft-float option. */
7758 if (!TARGET_MIPS16 || TARGET_SOFT_FLOAT_ABI)
7759 return NULL;
7761 /* Figure out whether the value might come back in a floating-point
7762 register. */
7763 fp_ret_p = retval && mips_return_mode_in_fpr_p (GET_MODE (retval));
7765 /* We don't need to do anything if there were no floating-point
7766 arguments and the value will not be returned in a floating-point
7767 register. */
7768 if (fp_code == 0 && !fp_ret_p)
7769 return NULL;
7771 /* We don't need to do anything if this is a call to a special
7772 MIPS16 support function. */
7773 fn = *fn_ptr;
7774 if (mips16_stub_function_p (fn))
7775 return NULL;
7777 /* If we're calling a locally-defined MIPS16 function, we know that
7778 it will return values in both the "soft-float" and "hard-float"
7779 registers. There is no need to use a stub to move the latter
7780 to the former. */
7781 if (fp_code == 0 && mips16_local_function_p (fn))
7782 return NULL;
7784 /* This code will only work for o32 and o64 abis. The other ABI's
7785 require more sophisticated support. */
7786 gcc_assert (TARGET_OLDABI);
7788 /* If we're calling via a function pointer, use one of the magic
7789 libgcc.a stubs provided for each (FP_CODE, FP_RET_P) combination.
7790 Each stub expects the function address to arrive in register $2. */
7791 if (GET_CODE (fn) != SYMBOL_REF
7792 || !call_insn_operand (fn, VOIDmode))
7794 char buf[32];
7795 rtx stub_fn, addr;
7796 rtx_insn *insn;
7797 bool lazy_p;
7799 /* If this is a locally-defined and locally-binding function,
7800 avoid the stub by calling the local alias directly. */
7801 if (mips16_local_function_p (fn))
7803 *fn_ptr = mips16_local_alias (fn);
7804 return NULL;
7807 /* Create a SYMBOL_REF for the libgcc.a function. */
7808 if (fp_ret_p)
7809 sprintf (buf, "__mips16_call_stub_%s_%d",
7810 mips16_call_stub_mode_suffix (GET_MODE (retval)),
7811 fp_code);
7812 else
7813 sprintf (buf, "__mips16_call_stub_%d", fp_code);
7814 stub_fn = mips16_stub_function (buf);
7816 /* The function uses $2 as an argument, so calls to it
7817 cannot be lazily bound. */
7818 SYMBOL_REF_FLAGS (stub_fn) |= SYMBOL_FLAG_BIND_NOW;
7820 /* Load the target function into $2. */
7821 addr = gen_rtx_REG (Pmode, GP_REG_FIRST + 2);
7822 lazy_p = mips_load_call_address (MIPS_CALL_NORMAL, addr, fn);
7824 /* Emit the call. */
7825 insn = mips_expand_call (MIPS_CALL_NORMAL, retval, stub_fn,
7826 args_size, NULL_RTX, lazy_p);
7828 /* Tell GCC that this call does indeed use the value of $2. */
7829 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), addr);
7831 /* If we are handling a floating-point return value, we need to
7832 save $18 in the function prologue. Putting a note on the
7833 call will mean that df_regs_ever_live_p ($18) will be true if the
7834 call is not eliminated, and we can check that in the prologue
7835 code. */
7836 if (fp_ret_p)
7837 CALL_INSN_FUNCTION_USAGE (insn) =
7838 gen_rtx_EXPR_LIST (VOIDmode,
7839 gen_rtx_CLOBBER (VOIDmode,
7840 gen_rtx_REG (word_mode, 18)),
7841 CALL_INSN_FUNCTION_USAGE (insn));
7843 return insn;
7846 /* We know the function we are going to call. If we have already
7847 built a stub, we don't need to do anything further. */
7848 fnname = targetm.strip_name_encoding (XSTR (fn, 0));
7849 for (l = mips16_stubs; l != NULL; l = l->next)
7850 if (strcmp (l->name, fnname) == 0)
7851 break;
7853 if (l == NULL)
7855 const char *separator;
7856 char *secname, *stubname;
7857 tree stubid, stubdecl;
7858 unsigned int f;
7860 /* If the function does not return in FPRs, the special stub
7861 section is named
7862 .mips16.call.FNNAME
7864 If the function does return in FPRs, the stub section is named
7865 .mips16.call.fp.FNNAME
7867 Build a decl for the stub. */
7868 secname = ACONCAT ((".mips16.call.", fp_ret_p ? "fp." : "",
7869 fnname, NULL));
7870 stubname = ACONCAT (("__call_stub_", fp_ret_p ? "fp_" : "",
7871 fnname, NULL));
7872 stubid = get_identifier (stubname);
7873 stubdecl = build_decl (BUILTINS_LOCATION,
7874 FUNCTION_DECL, stubid,
7875 build_function_type_list (void_type_node,
7876 NULL_TREE));
7877 set_decl_section_name (stubdecl, secname);
7878 DECL_RESULT (stubdecl) = build_decl (BUILTINS_LOCATION,
7879 RESULT_DECL, NULL_TREE,
7880 void_type_node);
7882 /* Output a comment. */
7883 fprintf (asm_out_file, "\t# Stub function to call %s%s (",
7884 (fp_ret_p
7885 ? (GET_MODE (retval) == SFmode ? "float " : "double ")
7886 : ""),
7887 fnname);
7888 separator = "";
7889 for (f = (unsigned int) fp_code; f != 0; f >>= 2)
7891 fprintf (asm_out_file, "%s%s", separator,
7892 (f & 3) == 1 ? "float" : "double");
7893 separator = ", ";
7895 fprintf (asm_out_file, ")\n");
7897 /* Start the function definition. */
7898 assemble_start_function (stubdecl, stubname);
7899 mips_start_function_definition (stubname, false, stubdecl);
7901 if (fp_ret_p)
7903 fprintf (asm_out_file, "\t.cfi_startproc\n");
7905 /* Create a fake CFA 4 bytes below the stack pointer.
7906 This works around unwinders (like libgcc's) that expect
7907 the CFA for non-signal frames to be unique. */
7908 fprintf (asm_out_file, "\t.cfi_def_cfa 29,-4\n");
7910 /* "Save" $sp in itself so we don't use the fake CFA.
7911 This is: DW_CFA_val_expression r29, { DW_OP_reg29 }. */
7912 fprintf (asm_out_file, "\t.cfi_escape 0x16,29,1,0x6d\n");
7914 /* Save the return address in $18. The stub's caller knows
7915 that $18 might be clobbered, even though $18 is usually
7916 a call-saved register.
7918 Do it early on in case the last move to a floating-point
7919 register can be scheduled into the delay slot of the
7920 call we are about to make. */
7921 fprintf (asm_out_file, "\tmove\t%s,%s\n",
7922 reg_names[GP_REG_FIRST + 18],
7923 reg_names[RETURN_ADDR_REGNUM]);
7925 else
7927 /* Load the address of the MIPS16 function into $25. Do this
7928 first so that targets with coprocessor interlocks can use
7929 an MFC1 to fill the delay slot. */
7930 if (TARGET_EXPLICIT_RELOCS)
7932 output_asm_insn ("lui\t%^,%%hi(%0)", &fn);
7933 output_asm_insn ("addiu\t%^,%^,%%lo(%0)", &fn);
7935 else
7936 output_asm_insn ("la\t%^,%0", &fn);
7939 /* Move the arguments from general registers to floating-point
7940 registers. */
7941 mips_output_args_xfer (fp_code, 't');
7943 if (fp_ret_p)
7945 /* Now call the non-MIPS16 function. */
7946 output_asm_insn (mips_output_jump (&fn, 0, -1, true), &fn);
7947 fprintf (asm_out_file, "\t.cfi_register 31,18\n");
7949 /* Move the result from floating-point registers to
7950 general registers. */
7951 switch (GET_MODE (retval))
7953 case E_SCmode:
7954 mips_output_32bit_xfer ('f', GP_RETURN + TARGET_BIG_ENDIAN,
7955 TARGET_BIG_ENDIAN
7956 ? FP_REG_FIRST + 2
7957 : FP_REG_FIRST);
7958 mips_output_32bit_xfer ('f', GP_RETURN + TARGET_LITTLE_ENDIAN,
7959 TARGET_LITTLE_ENDIAN
7960 ? FP_REG_FIRST + 2
7961 : FP_REG_FIRST);
7962 if (GET_MODE (retval) == SCmode && TARGET_64BIT)
7964 /* On 64-bit targets, complex floats are returned in
7965 a single GPR, such that "sd" on a suitably-aligned
7966 target would store the value correctly. */
7967 fprintf (asm_out_file, "\tdsll\t%s,%s,32\n",
7968 reg_names[GP_RETURN + TARGET_BIG_ENDIAN],
7969 reg_names[GP_RETURN + TARGET_BIG_ENDIAN]);
7970 fprintf (asm_out_file, "\tdsll\t%s,%s,32\n",
7971 reg_names[GP_RETURN + TARGET_LITTLE_ENDIAN],
7972 reg_names[GP_RETURN + TARGET_LITTLE_ENDIAN]);
7973 fprintf (asm_out_file, "\tdsrl\t%s,%s,32\n",
7974 reg_names[GP_RETURN + TARGET_BIG_ENDIAN],
7975 reg_names[GP_RETURN + TARGET_BIG_ENDIAN]);
7976 fprintf (asm_out_file, "\tor\t%s,%s,%s\n",
7977 reg_names[GP_RETURN],
7978 reg_names[GP_RETURN],
7979 reg_names[GP_RETURN + 1]);
7981 break;
7983 case E_SFmode:
7984 mips_output_32bit_xfer ('f', GP_RETURN, FP_REG_FIRST);
7985 break;
7987 case E_DCmode:
7988 mips_output_64bit_xfer ('f', GP_RETURN + (8 / UNITS_PER_WORD),
7989 FP_REG_FIRST + 2);
7990 /* FALLTHRU */
7991 case E_DFmode:
7992 case E_V2SFmode:
7993 gcc_assert (TARGET_PAIRED_SINGLE_FLOAT
7994 || GET_MODE (retval) != V2SFmode);
7995 mips_output_64bit_xfer ('f', GP_RETURN, FP_REG_FIRST);
7996 break;
7998 default:
7999 gcc_unreachable ();
8001 fprintf (asm_out_file, "\tjr\t%s\n", reg_names[GP_REG_FIRST + 18]);
8002 fprintf (asm_out_file, "\t.cfi_endproc\n");
8004 else
8006 /* Jump to the previously-loaded address. */
8007 output_asm_insn ("jr\t%^", NULL);
8010 #ifdef ASM_DECLARE_FUNCTION_SIZE
8011 ASM_DECLARE_FUNCTION_SIZE (asm_out_file, stubname, stubdecl);
8012 #endif
8014 mips_end_function_definition (stubname);
8016 /* Record this stub. */
8017 l = XNEW (struct mips16_stub);
8018 l->name = xstrdup (fnname);
8019 l->fp_ret_p = fp_ret_p;
8020 l->next = mips16_stubs;
8021 mips16_stubs = l;
8024 /* If we expect a floating-point return value, but we've built a
8025 stub which does not expect one, then we're in trouble. We can't
8026 use the existing stub, because it won't handle the floating-point
8027 value. We can't build a new stub, because the linker won't know
8028 which stub to use for the various calls in this object file.
8029 Fortunately, this case is illegal, since it means that a function
8030 was declared in two different ways in a single compilation. */
8031 if (fp_ret_p && !l->fp_ret_p)
8032 error ("cannot handle inconsistent calls to %qs", fnname);
8034 if (retval == NULL_RTX)
8035 pattern = gen_call_internal_direct (fn, args_size);
8036 else
8037 pattern = gen_call_value_internal_direct (retval, fn, args_size);
8038 insn = mips_emit_call_insn (pattern, fn, fn, false);
8040 /* If we are calling a stub which handles a floating-point return
8041 value, we need to arrange to save $18 in the prologue. We do this
8042 by marking the function call as using the register. The prologue
8043 will later see that it is used, and emit code to save it. */
8044 if (fp_ret_p)
8045 CALL_INSN_FUNCTION_USAGE (insn) =
8046 gen_rtx_EXPR_LIST (VOIDmode,
8047 gen_rtx_CLOBBER (VOIDmode,
8048 gen_rtx_REG (word_mode, 18)),
8049 CALL_INSN_FUNCTION_USAGE (insn));
8051 return insn;
8054 /* Expand a call of type TYPE. RESULT is where the result will go (null
8055 for "call"s and "sibcall"s), ADDR is the address of the function,
8056 ARGS_SIZE is the size of the arguments and AUX is the value passed
8057 to us by mips_function_arg. LAZY_P is true if this call already
8058 involves a lazily-bound function address (such as when calling
8059 functions through a MIPS16 hard-float stub).
8061 Return the call itself. */
8063 rtx_insn *
8064 mips_expand_call (enum mips_call_type type, rtx result, rtx addr,
8065 rtx args_size, rtx aux, bool lazy_p)
8067 rtx orig_addr, pattern;
8068 rtx_insn *insn;
8069 int fp_code;
8071 fp_code = aux == 0 ? 0 : (int) GET_MODE (aux);
8072 insn = mips16_build_call_stub (result, &addr, args_size, fp_code);
8073 if (insn)
8075 gcc_assert (!lazy_p && type == MIPS_CALL_NORMAL);
8076 return insn;
8079 orig_addr = addr;
8080 if (!call_insn_operand (addr, VOIDmode))
8082 if (type == MIPS_CALL_EPILOGUE)
8083 addr = MIPS_EPILOGUE_TEMP (Pmode);
8084 else
8085 addr = gen_reg_rtx (Pmode);
8086 lazy_p |= mips_load_call_address (type, addr, orig_addr);
8089 if (result == 0)
8091 rtx (*fn) (rtx, rtx);
8093 if (type == MIPS_CALL_SIBCALL)
8094 fn = gen_sibcall_internal;
8095 else
8096 fn = gen_call_internal;
8098 pattern = fn (addr, args_size);
8100 else if (GET_CODE (result) == PARALLEL && XVECLEN (result, 0) == 2)
8102 /* Handle return values created by mips_return_fpr_pair. */
8103 rtx (*fn) (rtx, rtx, rtx, rtx);
8104 rtx reg1, reg2;
8106 if (type == MIPS_CALL_SIBCALL)
8107 fn = gen_sibcall_value_multiple_internal;
8108 else
8109 fn = gen_call_value_multiple_internal;
8111 reg1 = XEXP (XVECEXP (result, 0, 0), 0);
8112 reg2 = XEXP (XVECEXP (result, 0, 1), 0);
8113 pattern = fn (reg1, addr, args_size, reg2);
8115 else
8117 rtx (*fn) (rtx, rtx, rtx);
8119 if (type == MIPS_CALL_SIBCALL)
8120 fn = gen_sibcall_value_internal;
8121 else
8122 fn = gen_call_value_internal;
8124 /* Handle return values created by mips_return_fpr_single. */
8125 if (GET_CODE (result) == PARALLEL && XVECLEN (result, 0) == 1)
8126 result = XEXP (XVECEXP (result, 0, 0), 0);
8127 pattern = fn (result, addr, args_size);
8130 return mips_emit_call_insn (pattern, orig_addr, addr, lazy_p);
8133 /* Split call instruction INSN into a $gp-clobbering call and
8134 (where necessary) an instruction to restore $gp from its save slot.
8135 CALL_PATTERN is the pattern of the new call. */
8137 void
8138 mips_split_call (rtx insn, rtx call_pattern)
8140 emit_call_insn (call_pattern);
8141 if (!find_reg_note (insn, REG_NORETURN, 0))
8142 mips_restore_gp_from_cprestore_slot (gen_rtx_REG (Pmode,
8143 POST_CALL_TMP_REG));
8146 /* Return true if a call to DECL may need to use JALX. */
8148 static bool
8149 mips_call_may_need_jalx_p (tree decl)
8151 /* If the current translation unit would use a different mode for DECL,
8152 assume that the call needs JALX. */
8153 if (mips_get_compress_mode (decl) != TARGET_COMPRESSION)
8154 return true;
8156 /* mips_get_compress_mode is always accurate for locally-binding
8157 functions in the current translation unit. */
8158 if (!DECL_EXTERNAL (decl) && targetm.binds_local_p (decl))
8159 return false;
8161 /* When -minterlink-compressed is in effect, assume that functions
8162 could use a different encoding mode unless an attribute explicitly
8163 tells us otherwise. */
8164 if (TARGET_INTERLINK_COMPRESSED)
8166 if (!TARGET_COMPRESSION
8167 && mips_get_compress_off_flags (DECL_ATTRIBUTES (decl)) ==0)
8168 return true;
8169 if (TARGET_COMPRESSION
8170 && mips_get_compress_on_flags (DECL_ATTRIBUTES (decl)) == 0)
8171 return true;
8174 return false;
8177 /* Implement TARGET_FUNCTION_OK_FOR_SIBCALL. */
8179 static bool
8180 mips_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
8182 if (!TARGET_SIBCALLS)
8183 return false;
8185 /* Interrupt handlers need special epilogue code and therefore can't
8186 use sibcalls. */
8187 if (mips_interrupt_type_p (TREE_TYPE (current_function_decl)))
8188 return false;
8190 /* Direct Js are only possible to functions that use the same ISA encoding.
8191 There is no JX counterpoart of JALX. */
8192 if (decl
8193 && const_call_insn_operand (XEXP (DECL_RTL (decl), 0), VOIDmode)
8194 && mips_call_may_need_jalx_p (decl))
8195 return false;
8197 /* Sibling calls should not prevent lazy binding. Lazy-binding stubs
8198 require $gp to be valid on entry, so sibcalls can only use stubs
8199 if $gp is call-clobbered. */
8200 if (decl
8201 && TARGET_CALL_SAVED_GP
8202 && !TARGET_ABICALLS_PIC0
8203 && !targetm.binds_local_p (decl))
8204 return false;
8206 /* Otherwise OK. */
8207 return true;
8210 /* Implement TARGET_USE_MOVE_BY_PIECES_INFRASTRUCTURE_P. */
8212 bool
8213 mips_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
8214 unsigned int align,
8215 enum by_pieces_operation op,
8216 bool speed_p)
8218 if (op == STORE_BY_PIECES)
8219 return mips_store_by_pieces_p (size, align);
8220 if (op == MOVE_BY_PIECES && HAVE_cpymemsi)
8222 /* cpymemsi is meant to generate code that is at least as good as
8223 move_by_pieces. However, cpymemsi effectively uses a by-pieces
8224 implementation both for moves smaller than a word and for
8225 word-aligned moves of no more than MIPS_MAX_MOVE_BYTES_STRAIGHT
8226 bytes. We should allow the tree-level optimisers to do such
8227 moves by pieces, as it often exposes other optimization
8228 opportunities. We might as well continue to use cpymemsi at
8229 the rtl level though, as it produces better code when
8230 scheduling is disabled (such as at -O). */
8231 if (currently_expanding_to_rtl)
8232 return false;
8233 if (align < BITS_PER_WORD)
8234 return size < UNITS_PER_WORD;
8235 return size <= MIPS_MAX_MOVE_BYTES_STRAIGHT;
8238 return default_use_by_pieces_infrastructure_p (size, align, op, speed_p);
8241 /* Implement a handler for STORE_BY_PIECES operations
8242 for TARGET_USE_MOVE_BY_PIECES_INFRASTRUCTURE_P. */
8244 bool
8245 mips_store_by_pieces_p (unsigned HOST_WIDE_INT size, unsigned int align)
8247 /* Storing by pieces involves moving constants into registers
8248 of size MIN (ALIGN, BITS_PER_WORD), then storing them.
8249 We need to decide whether it is cheaper to load the address of
8250 constant data into a register and use a block move instead. */
8252 /* If the data is only byte aligned, then:
8254 (a1) A block move of less than 4 bytes would involve three 3 LBs and
8255 3 SBs. We might as well use 3 single-instruction LIs and 3 SBs
8256 instead.
8258 (a2) A block move of 4 bytes from aligned source data can use an
8259 LW/SWL/SWR sequence. This is often better than the 4 LIs and
8260 4 SBs that we would generate when storing by pieces. */
8261 if (align <= BITS_PER_UNIT)
8262 return size < 4;
8264 /* If the data is 2-byte aligned, then:
8266 (b1) A block move of less than 4 bytes would use a combination of LBs,
8267 LHs, SBs and SHs. We get better code by using single-instruction
8268 LIs, SBs and SHs instead.
8270 (b2) A block move of 4 bytes from aligned source data would again use
8271 an LW/SWL/SWR sequence. In most cases, loading the address of
8272 the source data would require at least one extra instruction.
8273 It is often more efficient to use 2 single-instruction LIs and
8274 2 SHs instead.
8276 (b3) A block move of up to 3 additional bytes would be like (b1).
8278 (b4) A block move of 8 bytes from aligned source data can use two
8279 LW/SWL/SWR sequences or a single LD/SDL/SDR sequence. Both
8280 sequences are better than the 4 LIs and 4 SHs that we'd generate
8281 when storing by pieces.
8283 The reasoning for higher alignments is similar:
8285 (c1) A block move of less than 4 bytes would be the same as (b1).
8287 (c2) A block move of 4 bytes would use an LW/SW sequence. Again,
8288 loading the address of the source data would typically require
8289 at least one extra instruction. It is generally better to use
8290 LUI/ORI/SW instead.
8292 (c3) A block move of up to 3 additional bytes would be like (b1).
8294 (c4) A block move of 8 bytes can use two LW/SW sequences or a single
8295 LD/SD sequence, and in these cases we've traditionally preferred
8296 the memory copy over the more bulky constant moves. */
8297 return size < 8;
8300 /* Emit straight-line code to move LENGTH bytes from SRC to DEST.
8301 Assume that the areas do not overlap. */
8303 static void
8304 mips_block_move_straight (rtx dest, rtx src, HOST_WIDE_INT length)
8306 HOST_WIDE_INT offset, delta;
8307 unsigned HOST_WIDE_INT bits;
8308 int i;
8309 machine_mode mode;
8310 rtx *regs;
8312 /* Work out how many bits to move at a time. If both operands have
8313 half-word alignment, it is usually better to move in half words.
8314 For instance, lh/lh/sh/sh is usually better than lwl/lwr/swl/swr
8315 and lw/lw/sw/sw is usually better than ldl/ldr/sdl/sdr.
8316 Otherwise move word-sized chunks.
8318 For ISA_HAS_LWL_LWR we rely on the lwl/lwr & swl/swr load. Otherwise
8319 picking the minimum of alignment or BITS_PER_WORD gets us the
8320 desired size for bits. */
8321 if (ISA_HAS_UNALIGNED_ACCESS)
8322 bits = BITS_PER_WORD;
8323 else if (!ISA_HAS_LWL_LWR)
8324 bits = MIN (BITS_PER_WORD, MIN (MEM_ALIGN (src), MEM_ALIGN (dest)));
8325 else
8327 if (MEM_ALIGN (src) == BITS_PER_WORD / 2
8328 && MEM_ALIGN (dest) == BITS_PER_WORD / 2)
8329 bits = BITS_PER_WORD / 2;
8330 else
8331 bits = BITS_PER_WORD;
8334 mode = int_mode_for_size (bits, 0).require ();
8335 delta = bits / BITS_PER_UNIT;
8337 /* Allocate a buffer for the temporary registers. */
8338 regs = XALLOCAVEC (rtx, length / delta);
8340 /* Load as many BITS-sized chunks as possible. Use a normal load if
8341 the source has enough alignment, otherwise use left/right pairs. */
8342 for (offset = 0, i = 0; offset + delta <= length; offset += delta, i++)
8344 regs[i] = gen_reg_rtx (mode);
8345 if (ISA_HAS_UNALIGNED_ACCESS || MEM_ALIGN (src) >= bits)
8346 mips_emit_move (regs[i], adjust_address (src, mode, offset));
8347 else
8349 rtx part = adjust_address (src, BLKmode, offset);
8350 set_mem_size (part, delta);
8351 if (!mips_expand_ext_as_unaligned_load (regs[i], part, bits, 0, 0))
8352 gcc_unreachable ();
8356 /* Copy the chunks to the destination. */
8357 for (offset = 0, i = 0; offset + delta <= length; offset += delta, i++)
8358 if (ISA_HAS_UNALIGNED_ACCESS || MEM_ALIGN (dest) >= bits)
8359 mips_emit_move (adjust_address (dest, mode, offset), regs[i]);
8360 else
8362 rtx part = adjust_address (dest, BLKmode, offset);
8363 set_mem_size (part, delta);
8364 if (!mips_expand_ins_as_unaligned_store (part, regs[i], bits, 0))
8365 gcc_unreachable ();
8368 /* Mop up any left-over bytes. */
8369 if (offset < length)
8371 src = adjust_address (src, BLKmode, offset);
8372 dest = adjust_address (dest, BLKmode, offset);
8373 move_by_pieces (dest, src, length - offset,
8374 MIN (MEM_ALIGN (src), MEM_ALIGN (dest)), RETURN_BEGIN);
8378 /* Helper function for doing a loop-based block operation on memory
8379 reference MEM. Each iteration of the loop will operate on LENGTH
8380 bytes of MEM.
8382 Create a new base register for use within the loop and point it to
8383 the start of MEM. Create a new memory reference that uses this
8384 register. Store them in *LOOP_REG and *LOOP_MEM respectively. */
8386 static void
8387 mips_adjust_block_mem (rtx mem, HOST_WIDE_INT length,
8388 rtx *loop_reg, rtx *loop_mem)
8390 *loop_reg = copy_addr_to_reg (XEXP (mem, 0));
8392 /* Although the new mem does not refer to a known location,
8393 it does keep up to LENGTH bytes of alignment. */
8394 *loop_mem = change_address (mem, BLKmode, *loop_reg);
8395 set_mem_align (*loop_mem, MIN (MEM_ALIGN (mem), length * BITS_PER_UNIT));
8398 /* Move LENGTH bytes from SRC to DEST using a loop that moves BYTES_PER_ITER
8399 bytes at a time. LENGTH must be at least BYTES_PER_ITER. Assume that
8400 the memory regions do not overlap. */
8402 static void
8403 mips_block_move_loop (rtx dest, rtx src, HOST_WIDE_INT length,
8404 HOST_WIDE_INT bytes_per_iter)
8406 rtx_code_label *label;
8407 rtx src_reg, dest_reg, final_src, test;
8408 HOST_WIDE_INT leftover;
8410 leftover = length % bytes_per_iter;
8411 length -= leftover;
8413 /* Create registers and memory references for use within the loop. */
8414 mips_adjust_block_mem (src, bytes_per_iter, &src_reg, &src);
8415 mips_adjust_block_mem (dest, bytes_per_iter, &dest_reg, &dest);
8417 /* Calculate the value that SRC_REG should have after the last iteration
8418 of the loop. */
8419 final_src = expand_simple_binop (Pmode, PLUS, src_reg, GEN_INT (length),
8420 0, 0, OPTAB_WIDEN);
8422 /* Emit the start of the loop. */
8423 label = gen_label_rtx ();
8424 emit_label (label);
8426 /* Emit the loop body. */
8427 mips_block_move_straight (dest, src, bytes_per_iter);
8429 /* Move on to the next block. */
8430 mips_emit_move (src_reg, plus_constant (Pmode, src_reg, bytes_per_iter));
8431 mips_emit_move (dest_reg, plus_constant (Pmode, dest_reg, bytes_per_iter));
8433 /* Emit the loop condition. */
8434 test = gen_rtx_NE (VOIDmode, src_reg, final_src);
8435 if (Pmode == DImode)
8436 emit_jump_insn (gen_cbranchdi4 (test, src_reg, final_src, label));
8437 else
8438 emit_jump_insn (gen_cbranchsi4 (test, src_reg, final_src, label));
8440 /* Mop up any left-over bytes. */
8441 if (leftover)
8442 mips_block_move_straight (dest, src, leftover);
8443 else
8444 /* Temporary fix for PR79150. */
8445 emit_insn (gen_nop ());
8448 /* Expand a cpymemsi instruction, which copies LENGTH bytes from
8449 memory reference SRC to memory reference DEST. */
8451 bool
8452 mips_expand_block_move (rtx dest, rtx src, rtx length)
8454 if (!CONST_INT_P (length))
8455 return false;
8457 if (mips_isa_rev >= 6 && !ISA_HAS_UNALIGNED_ACCESS
8458 && (MEM_ALIGN (src) < MIPS_MIN_MOVE_MEM_ALIGN
8459 || MEM_ALIGN (dest) < MIPS_MIN_MOVE_MEM_ALIGN))
8460 return false;
8462 if (INTVAL (length) <= MIPS_MAX_MOVE_BYTES_PER_LOOP_ITER)
8464 mips_block_move_straight (dest, src, INTVAL (length));
8465 return true;
8467 else if (optimize)
8469 mips_block_move_loop (dest, src, INTVAL (length),
8470 MIPS_MAX_MOVE_BYTES_PER_LOOP_ITER);
8471 return true;
8474 return false;
8477 /* Expand a loop of synci insns for the address range [BEGIN, END). */
8479 void
8480 mips_expand_synci_loop (rtx begin, rtx end)
8482 rtx inc, cmp_result, mask, length;
8483 rtx_code_label *label, *end_label;
8485 /* Create end_label. */
8486 end_label = gen_label_rtx ();
8488 /* Check if begin equals end. */
8489 cmp_result = gen_rtx_EQ (VOIDmode, begin, end);
8490 emit_jump_insn (gen_condjump (cmp_result, end_label));
8492 /* Load INC with the cache line size (rdhwr INC,$1). */
8493 inc = gen_reg_rtx (Pmode);
8494 emit_insn (PMODE_INSN (gen_rdhwr_synci_step, (inc)));
8496 /* Check if inc is 0. */
8497 cmp_result = gen_rtx_EQ (VOIDmode, inc, const0_rtx);
8498 emit_jump_insn (gen_condjump (cmp_result, end_label));
8500 /* Calculate mask. */
8501 mask = mips_force_unary (Pmode, NEG, inc);
8503 /* Mask out begin by mask. */
8504 begin = mips_force_binary (Pmode, AND, begin, mask);
8506 /* Calculate length. */
8507 length = mips_force_binary (Pmode, MINUS, end, begin);
8509 /* Loop back to here. */
8510 label = gen_label_rtx ();
8511 emit_label (label);
8513 emit_insn (gen_synci (begin));
8515 /* Update length. */
8516 mips_emit_binary (MINUS, length, length, inc);
8518 /* Update begin. */
8519 mips_emit_binary (PLUS, begin, begin, inc);
8521 /* Check if length is greater than 0. */
8522 cmp_result = gen_rtx_GT (VOIDmode, length, const0_rtx);
8523 emit_jump_insn (gen_condjump (cmp_result, label));
8525 emit_label (end_label);
8528 /* Expand a QI or HI mode atomic memory operation.
8530 GENERATOR contains a pointer to the gen_* function that generates
8531 the SI mode underlying atomic operation using masks that we
8532 calculate.
8534 RESULT is the return register for the operation. Its value is NULL
8535 if unused.
8537 MEM is the location of the atomic access.
8539 OLDVAL is the first operand for the operation.
8541 NEWVAL is the optional second operand for the operation. Its value
8542 is NULL if unused. */
8544 void
8545 mips_expand_atomic_qihi (union mips_gen_fn_ptrs generator,
8546 rtx result, rtx mem, rtx oldval, rtx newval)
8548 rtx orig_addr, memsi_addr, memsi, shift, shiftsi, unshifted_mask;
8549 rtx unshifted_mask_reg, mask, inverted_mask, si_op;
8550 rtx res = NULL;
8551 machine_mode mode;
8553 mode = GET_MODE (mem);
8555 /* Compute the address of the containing SImode value. */
8556 orig_addr = force_reg (Pmode, XEXP (mem, 0));
8557 memsi_addr = mips_force_binary (Pmode, AND, orig_addr,
8558 force_reg (Pmode, GEN_INT (-4)));
8560 /* Create a memory reference for it. */
8561 memsi = gen_rtx_MEM (SImode, memsi_addr);
8562 set_mem_alias_set (memsi, ALIAS_SET_MEMORY_BARRIER);
8563 MEM_VOLATILE_P (memsi) = MEM_VOLATILE_P (mem);
8565 /* Work out the byte offset of the QImode or HImode value,
8566 counting from the least significant byte. */
8567 shift = mips_force_binary (Pmode, AND, orig_addr, GEN_INT (3));
8568 if (TARGET_BIG_ENDIAN)
8569 mips_emit_binary (XOR, shift, shift, GEN_INT (mode == QImode ? 3 : 2));
8571 /* Multiply by eight to convert the shift value from bytes to bits. */
8572 mips_emit_binary (ASHIFT, shift, shift, GEN_INT (3));
8574 /* Make the final shift an SImode value, so that it can be used in
8575 SImode operations. */
8576 shiftsi = force_reg (SImode, gen_lowpart (SImode, shift));
8578 /* Set MASK to an inclusive mask of the QImode or HImode value. */
8579 unshifted_mask = GEN_INT (GET_MODE_MASK (mode));
8580 unshifted_mask_reg = force_reg (SImode, unshifted_mask);
8581 mask = mips_force_binary (SImode, ASHIFT, unshifted_mask_reg, shiftsi);
8583 /* Compute the equivalent exclusive mask. */
8584 inverted_mask = gen_reg_rtx (SImode);
8585 emit_insn (gen_rtx_SET (inverted_mask, gen_rtx_NOT (SImode, mask)));
8587 /* Shift the old value into place. */
8588 if (oldval != const0_rtx)
8590 oldval = convert_modes (SImode, mode, oldval, true);
8591 oldval = force_reg (SImode, oldval);
8592 oldval = mips_force_binary (SImode, ASHIFT, oldval, shiftsi);
8595 /* Do the same for the new value. */
8596 if (newval && newval != const0_rtx)
8598 newval = convert_modes (SImode, mode, newval, true);
8599 newval = force_reg (SImode, newval);
8600 newval = mips_force_binary (SImode, ASHIFT, newval, shiftsi);
8603 /* Do the SImode atomic access. */
8604 if (result)
8605 res = gen_reg_rtx (SImode);
8606 if (newval)
8607 si_op = generator.fn_6 (res, memsi, mask, inverted_mask, oldval, newval);
8608 else if (result)
8609 si_op = generator.fn_5 (res, memsi, mask, inverted_mask, oldval);
8610 else
8611 si_op = generator.fn_4 (memsi, mask, inverted_mask, oldval);
8613 emit_insn (si_op);
8615 if (result)
8617 /* Shift and convert the result. */
8618 mips_emit_binary (AND, res, res, mask);
8619 mips_emit_binary (LSHIFTRT, res, res, shiftsi);
8620 mips_emit_move (result, gen_lowpart (GET_MODE (result), res));
8624 /* Return true if it is possible to use left/right accesses for a
8625 bitfield of WIDTH bits starting BITPOS bits into BLKmode memory OP.
8626 When returning true, update *LEFT and *RIGHT as follows:
8628 *LEFT is a QImode reference to the first byte if big endian or
8629 the last byte if little endian. This address can be used in the
8630 left-side instructions (LWL, SWL, LDL, SDL).
8632 *RIGHT is a QImode reference to the opposite end of the field and
8633 can be used in the patterning right-side instruction. */
8635 static bool
8636 mips_get_unaligned_mem (rtx op, HOST_WIDE_INT width, HOST_WIDE_INT bitpos,
8637 rtx *left, rtx *right)
8639 rtx first, last;
8641 /* Check that the size is valid. */
8642 if (width != 32 && (!TARGET_64BIT || width != 64))
8643 return false;
8645 /* We can only access byte-aligned values. Since we are always passed
8646 a reference to the first byte of the field, it is not necessary to
8647 do anything with BITPOS after this check. */
8648 if (bitpos % BITS_PER_UNIT != 0)
8649 return false;
8651 /* Reject aligned bitfields: we want to use a normal load or store
8652 instead of a left/right pair. */
8653 if (MEM_ALIGN (op) >= width)
8654 return false;
8656 /* Get references to both ends of the field. */
8657 first = adjust_address (op, QImode, 0);
8658 last = adjust_address (op, QImode, width / BITS_PER_UNIT - 1);
8660 /* Allocate to LEFT and RIGHT according to endianness. LEFT should
8661 correspond to the MSB and RIGHT to the LSB. */
8662 if (TARGET_BIG_ENDIAN)
8663 *left = first, *right = last;
8664 else
8665 *left = last, *right = first;
8667 return true;
8670 /* Try to use left/right loads to expand an "extv" or "extzv" pattern.
8671 DEST, SRC, WIDTH and BITPOS are the operands passed to the expander;
8672 the operation is the equivalent of:
8674 (set DEST (*_extract SRC WIDTH BITPOS))
8676 Return true on success. */
8678 bool
8679 mips_expand_ext_as_unaligned_load (rtx dest, rtx src, HOST_WIDE_INT width,
8680 HOST_WIDE_INT bitpos, bool unsigned_p)
8682 rtx left, right, temp;
8683 rtx dest1 = NULL_RTX;
8685 /* If TARGET_64BIT, the destination of a 32-bit "extz" or "extzv" will
8686 be a DImode, create a new temp and emit a zero extend at the end. */
8687 if (GET_MODE (dest) == DImode
8688 && (REG_P (dest) || (SUBREG_P (dest) && !MEM_P (SUBREG_REG (dest))))
8689 && GET_MODE_BITSIZE (SImode) == width)
8691 dest1 = dest;
8692 dest = gen_reg_rtx (SImode);
8695 if (!mips_get_unaligned_mem (src, width, bitpos, &left, &right))
8696 return false;
8698 temp = gen_reg_rtx (GET_MODE (dest));
8699 if (GET_MODE (dest) == DImode)
8701 emit_insn (gen_mov_ldl (temp, src, left));
8702 emit_insn (gen_mov_ldr (dest, copy_rtx (src), right, temp));
8704 else
8706 emit_insn (gen_mov_lwl (temp, src, left));
8707 emit_insn (gen_mov_lwr (dest, copy_rtx (src), right, temp));
8710 /* If we were loading 32bits and the original register was DI then
8711 sign/zero extend into the orignal dest. */
8712 if (dest1)
8714 if (unsigned_p)
8715 emit_insn (gen_zero_extendsidi2 (dest1, dest));
8716 else
8717 emit_insn (gen_extendsidi2 (dest1, dest));
8719 return true;
8722 /* Try to use left/right stores to expand an "ins" pattern. DEST, WIDTH,
8723 BITPOS and SRC are the operands passed to the expander; the operation
8724 is the equivalent of:
8726 (set (zero_extract DEST WIDTH BITPOS) SRC)
8728 Return true on success. */
8730 bool
8731 mips_expand_ins_as_unaligned_store (rtx dest, rtx src, HOST_WIDE_INT width,
8732 HOST_WIDE_INT bitpos)
8734 rtx left, right;
8735 machine_mode mode;
8737 if (!mips_get_unaligned_mem (dest, width, bitpos, &left, &right))
8738 return false;
8740 mode = int_mode_for_size (width, 0).require ();
8741 if (TARGET_MIPS16
8742 && src == const0_rtx)
8743 src = force_reg (mode, src);
8744 else
8745 src = gen_lowpart (mode, src);
8747 if (mode == DImode)
8749 if (TARGET_MIPS16)
8750 gcc_unreachable ();
8751 emit_insn (gen_mov_sdl (dest, src, left));
8752 emit_insn (gen_mov_sdr (copy_rtx (dest), copy_rtx (src), right));
8754 else if (TARGET_MIPS16)
8756 emit_insn (gen_mov_swl_mips16e2 (dest, src, left));
8757 emit_insn (gen_mov_swr_mips16e2 (copy_rtx (dest), copy_rtx (src),
8758 right));
8760 else
8762 emit_insn (gen_mov_swl (dest, src, left));
8763 emit_insn (gen_mov_swr (copy_rtx (dest), copy_rtx (src), right));
8765 return true;
8768 /* Return true if X is a MEM with the same size as MODE. */
8770 bool
8771 mips_mem_fits_mode_p (machine_mode mode, rtx x)
8773 return (MEM_P (x)
8774 && MEM_SIZE_KNOWN_P (x)
8775 && MEM_SIZE (x) == GET_MODE_SIZE (mode));
8778 /* Return true if (zero_extract OP WIDTH BITPOS) can be used as the
8779 source of an "ext" instruction or the destination of an "ins"
8780 instruction. OP must be a register operand and the following
8781 conditions must hold:
8783 0 <= BITPOS < GET_MODE_BITSIZE (GET_MODE (op))
8784 0 < WIDTH <= GET_MODE_BITSIZE (GET_MODE (op))
8785 0 < BITPOS + WIDTH <= GET_MODE_BITSIZE (GET_MODE (op))
8787 Also reject lengths equal to a word as they are better handled
8788 by the move patterns. */
8790 bool
8791 mips_use_ins_ext_p (rtx op, HOST_WIDE_INT width, HOST_WIDE_INT bitpos)
8793 if (!ISA_HAS_EXT_INS
8794 || !register_operand (op, VOIDmode)
8795 || GET_MODE_BITSIZE (GET_MODE (op)) > BITS_PER_WORD)
8796 return false;
8798 if (!IN_RANGE (width, 1, GET_MODE_BITSIZE (GET_MODE (op)) - 1))
8799 return false;
8801 if (bitpos < 0 || bitpos + width > GET_MODE_BITSIZE (GET_MODE (op)))
8802 return false;
8804 return true;
8807 /* Check if MASK and SHIFT are valid in mask-low-and-shift-left
8808 operation if MAXLEN is the maxium length of consecutive bits that
8809 can make up MASK. MODE is the mode of the operation. See
8810 mask_low_and_shift_len for the actual definition. */
8812 bool
8813 mask_low_and_shift_p (machine_mode mode, rtx mask, rtx shift, int maxlen)
8815 return IN_RANGE (mask_low_and_shift_len (mode, mask, shift), 1, maxlen);
8818 /* Return true iff OP1 and OP2 are valid operands together for the
8819 *and<MODE>3 and *and<MODE>3_mips16 patterns. For the cases to consider,
8820 see the table in the comment before the pattern. */
8822 bool
8823 and_operands_ok (machine_mode mode, rtx op1, rtx op2)
8826 if (memory_operand (op1, mode))
8828 if (TARGET_MIPS16) {
8829 struct mips_address_info addr;
8830 if (!mips_classify_address (&addr, op1, mode, false))
8831 return false;
8833 return and_load_operand (op2, mode);
8835 else
8836 return and_reg_operand (op2, mode);
8839 /* The canonical form of a mask-low-and-shift-left operation is
8840 (and (ashift X SHIFT) MASK) where MASK has the lower SHIFT number of bits
8841 cleared. Thus we need to shift MASK to the right before checking if it
8842 is a valid mask value. MODE is the mode of the operation. If true
8843 return the length of the mask, otherwise return -1. */
8846 mask_low_and_shift_len (machine_mode mode, rtx mask, rtx shift)
8848 HOST_WIDE_INT shval;
8850 shval = INTVAL (shift) & (GET_MODE_BITSIZE (mode) - 1);
8851 return exact_log2 ((UINTVAL (mask) >> shval) + 1);
8854 /* Return true if -msplit-addresses is selected and should be honored.
8856 -msplit-addresses is a half-way house between explicit relocations
8857 and the traditional assembler macros. It can split absolute 32-bit
8858 symbolic constants into a high/lo_sum pair but uses macros for other
8859 sorts of access.
8861 Like explicit relocation support for REL targets, it relies
8862 on GNU extensions in the assembler and the linker.
8864 Although this code should work for -O0, it has traditionally
8865 been treated as an optimization. */
8867 static bool
8868 mips_split_addresses_p (void)
8870 return (TARGET_SPLIT_ADDRESSES
8871 && optimize
8872 && !TARGET_MIPS16
8873 && !flag_pic
8874 && !ABI_HAS_64BIT_SYMBOLS);
8877 /* (Re-)Initialize mips_split_p, mips_lo_relocs and mips_hi_relocs. */
8879 static void
8880 mips_init_relocs (void)
8882 memset (mips_split_p, '\0', sizeof (mips_split_p));
8883 memset (mips_split_hi_p, '\0', sizeof (mips_split_hi_p));
8884 memset (mips_use_pcrel_pool_p, '\0', sizeof (mips_use_pcrel_pool_p));
8885 memset (mips_hi_relocs, '\0', sizeof (mips_hi_relocs));
8886 memset (mips_lo_relocs, '\0', sizeof (mips_lo_relocs));
8888 if (TARGET_MIPS16_PCREL_LOADS)
8889 mips_use_pcrel_pool_p[SYMBOL_ABSOLUTE] = true;
8890 else
8892 if (ABI_HAS_64BIT_SYMBOLS)
8894 if (TARGET_EXPLICIT_RELOCS)
8896 mips_split_p[SYMBOL_64_HIGH] = true;
8897 mips_hi_relocs[SYMBOL_64_HIGH] = "%highest(";
8898 mips_lo_relocs[SYMBOL_64_HIGH] = "%higher(";
8900 mips_split_p[SYMBOL_64_MID] = true;
8901 mips_hi_relocs[SYMBOL_64_MID] = "%higher(";
8902 mips_lo_relocs[SYMBOL_64_MID] = "%hi(";
8904 mips_split_p[SYMBOL_64_LOW] = true;
8905 mips_hi_relocs[SYMBOL_64_LOW] = "%hi(";
8906 mips_lo_relocs[SYMBOL_64_LOW] = "%lo(";
8908 mips_split_p[SYMBOL_ABSOLUTE] = true;
8909 mips_lo_relocs[SYMBOL_ABSOLUTE] = "%lo(";
8912 else
8914 if (TARGET_EXPLICIT_RELOCS
8915 || mips_split_addresses_p ()
8916 || TARGET_MIPS16)
8918 mips_split_p[SYMBOL_ABSOLUTE] = true;
8919 mips_hi_relocs[SYMBOL_ABSOLUTE] = "%hi(";
8920 mips_lo_relocs[SYMBOL_ABSOLUTE] = "%lo(";
8925 if (!MIPS16_GP_LOADS && TARGET_MIPS16)
8927 /* The high part is provided by a pseudo copy of $gp. */
8928 mips_split_p[SYMBOL_GP_RELATIVE] = true;
8929 mips_lo_relocs[SYMBOL_GP_RELATIVE] = "%gprel(";
8931 else if (TARGET_EXPLICIT_RELOCS)
8932 /* Small data constants are kept whole until after reload,
8933 then lowered by mips_rewrite_small_data. */
8934 mips_lo_relocs[SYMBOL_GP_RELATIVE] = "%gp_rel(";
8936 if (TARGET_EXPLICIT_RELOCS)
8938 mips_split_p[SYMBOL_GOT_PAGE_OFST] = true;
8939 if (TARGET_NEWABI)
8941 mips_lo_relocs[SYMBOL_GOTOFF_PAGE] = "%got_page(";
8942 mips_lo_relocs[SYMBOL_GOT_PAGE_OFST] = "%got_ofst(";
8944 else
8946 mips_lo_relocs[SYMBOL_GOTOFF_PAGE] = "%got(";
8947 mips_lo_relocs[SYMBOL_GOT_PAGE_OFST] = "%lo(";
8949 if (TARGET_MIPS16)
8950 /* Expose the use of $28 as soon as possible. */
8951 mips_split_hi_p[SYMBOL_GOT_PAGE_OFST] = true;
8953 if (TARGET_XGOT)
8955 /* The HIGH and LO_SUM are matched by special .md patterns. */
8956 mips_split_p[SYMBOL_GOT_DISP] = true;
8958 mips_split_p[SYMBOL_GOTOFF_DISP] = true;
8959 mips_hi_relocs[SYMBOL_GOTOFF_DISP] = "%got_hi(";
8960 mips_lo_relocs[SYMBOL_GOTOFF_DISP] = "%got_lo(";
8962 mips_split_p[SYMBOL_GOTOFF_CALL] = true;
8963 mips_hi_relocs[SYMBOL_GOTOFF_CALL] = "%call_hi(";
8964 mips_lo_relocs[SYMBOL_GOTOFF_CALL] = "%call_lo(";
8966 else
8968 if (TARGET_NEWABI)
8969 mips_lo_relocs[SYMBOL_GOTOFF_DISP] = "%got_disp(";
8970 else
8971 mips_lo_relocs[SYMBOL_GOTOFF_DISP] = "%got(";
8972 mips_lo_relocs[SYMBOL_GOTOFF_CALL] = "%call16(";
8973 if (TARGET_MIPS16)
8974 /* Expose the use of $28 as soon as possible. */
8975 mips_split_p[SYMBOL_GOT_DISP] = true;
8979 if (TARGET_NEWABI)
8981 mips_split_p[SYMBOL_GOTOFF_LOADGP] = true;
8982 mips_hi_relocs[SYMBOL_GOTOFF_LOADGP] = "%hi(%neg(%gp_rel(";
8983 mips_lo_relocs[SYMBOL_GOTOFF_LOADGP] = "%lo(%neg(%gp_rel(";
8986 mips_lo_relocs[SYMBOL_TLSGD] = "%tlsgd(";
8987 mips_lo_relocs[SYMBOL_TLSLDM] = "%tlsldm(";
8989 if (TARGET_MIPS16_PCREL_LOADS)
8991 mips_use_pcrel_pool_p[SYMBOL_DTPREL] = true;
8992 mips_use_pcrel_pool_p[SYMBOL_TPREL] = true;
8994 else
8996 mips_split_p[SYMBOL_DTPREL] = true;
8997 mips_hi_relocs[SYMBOL_DTPREL] = "%dtprel_hi(";
8998 mips_lo_relocs[SYMBOL_DTPREL] = "%dtprel_lo(";
9000 mips_split_p[SYMBOL_TPREL] = true;
9001 mips_hi_relocs[SYMBOL_TPREL] = "%tprel_hi(";
9002 mips_lo_relocs[SYMBOL_TPREL] = "%tprel_lo(";
9005 mips_lo_relocs[SYMBOL_GOTTPREL] = "%gottprel(";
9006 mips_lo_relocs[SYMBOL_HALF] = "%half(";
9009 /* Print symbolic operand OP, which is part of a HIGH or LO_SUM
9010 in context CONTEXT. RELOCS is the array of relocations to use. */
9012 static void
9013 mips_print_operand_reloc (FILE *file, rtx op, enum mips_symbol_context context,
9014 const char **relocs)
9016 enum mips_symbol_type symbol_type;
9017 const char *p;
9019 symbol_type = mips_classify_symbolic_expression (op, context);
9020 gcc_assert (relocs[symbol_type]);
9022 fputs (relocs[symbol_type], file);
9023 output_addr_const (file, mips_strip_unspec_address (op));
9024 for (p = relocs[symbol_type]; *p != 0; p++)
9025 if (*p == '(')
9026 fputc (')', file);
9029 /* Start a new block with the given asm switch enabled. If we need
9030 to print a directive, emit PREFIX before it and SUFFIX after it. */
9032 static void
9033 mips_push_asm_switch_1 (struct mips_asm_switch *asm_switch,
9034 const char *prefix, const char *suffix)
9036 if (asm_switch->nesting_level == 0)
9037 fprintf (asm_out_file, "%s.set\tno%s%s", prefix, asm_switch->name, suffix);
9038 asm_switch->nesting_level++;
9041 /* Likewise, but end a block. */
9043 static void
9044 mips_pop_asm_switch_1 (struct mips_asm_switch *asm_switch,
9045 const char *prefix, const char *suffix)
9047 gcc_assert (asm_switch->nesting_level);
9048 asm_switch->nesting_level--;
9049 if (asm_switch->nesting_level == 0)
9050 fprintf (asm_out_file, "%s.set\t%s%s", prefix, asm_switch->name, suffix);
9053 /* Wrappers around mips_push_asm_switch_1 and mips_pop_asm_switch_1
9054 that either print a complete line or print nothing. */
9056 void
9057 mips_push_asm_switch (struct mips_asm_switch *asm_switch)
9059 mips_push_asm_switch_1 (asm_switch, "\t", "\n");
9062 void
9063 mips_pop_asm_switch (struct mips_asm_switch *asm_switch)
9065 mips_pop_asm_switch_1 (asm_switch, "\t", "\n");
9068 /* Print the text for PRINT_OPERAND punctation character CH to FILE.
9069 The punctuation characters are:
9071 '(' Start a nested ".set noreorder" block.
9072 ')' End a nested ".set noreorder" block.
9073 '[' Start a nested ".set noat" block.
9074 ']' End a nested ".set noat" block.
9075 '<' Start a nested ".set nomacro" block.
9076 '>' End a nested ".set nomacro" block.
9077 '*' Behave like %(%< if generating a delayed-branch sequence.
9078 '#' Print a nop if in a ".set noreorder" block.
9079 '/' Like '#', but do nothing within a delayed-branch sequence.
9080 '?' Print "l" if mips_branch_likely is true
9081 '~' Print a nop if mips_branch_likely is true
9082 '.' Print the name of the register with a hard-wired zero (zero or $0).
9083 '@' Print the name of the assembler temporary register (at or $1).
9084 '^' Print the name of the pic call-through register (t9 or $25).
9085 '+' Print the name of the gp register (usually gp or $28).
9086 '$' Print the name of the stack pointer register (sp or $29).
9087 ':' Print "c" to use the compact version if the delay slot is a nop.
9088 '!' Print "s" to use the short version if the delay slot contains a
9089 16-bit instruction.
9091 See also mips_init_print_operand_punct. */
9093 static void
9094 mips_print_operand_punctuation (FILE *file, int ch)
9096 switch (ch)
9098 case '(':
9099 mips_push_asm_switch_1 (&mips_noreorder, "", "\n\t");
9100 break;
9102 case ')':
9103 mips_pop_asm_switch_1 (&mips_noreorder, "\n\t", "");
9104 break;
9106 case '[':
9107 mips_push_asm_switch_1 (&mips_noat, "", "\n\t");
9108 break;
9110 case ']':
9111 mips_pop_asm_switch_1 (&mips_noat, "\n\t", "");
9112 break;
9114 case '<':
9115 mips_push_asm_switch_1 (&mips_nomacro, "", "\n\t");
9116 break;
9118 case '>':
9119 mips_pop_asm_switch_1 (&mips_nomacro, "\n\t", "");
9120 break;
9122 case '*':
9123 if (final_sequence != 0)
9125 mips_print_operand_punctuation (file, '(');
9126 mips_print_operand_punctuation (file, '<');
9128 break;
9130 case '#':
9131 if (mips_noreorder.nesting_level > 0)
9132 fputs ("\n\tnop", file);
9133 break;
9135 case '/':
9136 /* Print an extra newline so that the delayed insn is separated
9137 from the following ones. This looks neater and is consistent
9138 with non-nop delayed sequences. */
9139 if (mips_noreorder.nesting_level > 0 && final_sequence == 0)
9140 fputs ("\n\tnop\n", file);
9141 break;
9143 case '?':
9144 if (mips_branch_likely)
9145 putc ('l', file);
9146 break;
9148 case '~':
9149 if (mips_branch_likely)
9150 fputs ("\n\tnop", file);
9151 break;
9153 case '.':
9154 fputs (reg_names[GP_REG_FIRST + 0], file);
9155 break;
9157 case '@':
9158 fputs (reg_names[AT_REGNUM], file);
9159 break;
9161 case '^':
9162 fputs (reg_names[PIC_FUNCTION_ADDR_REGNUM], file);
9163 break;
9165 case '+':
9166 fputs (reg_names[PIC_OFFSET_TABLE_REGNUM], file);
9167 break;
9169 case '$':
9170 fputs (reg_names[STACK_POINTER_REGNUM], file);
9171 break;
9173 case ':':
9174 /* When final_sequence is 0, the delay slot will be a nop. We can
9175 use the compact version where available. The %: formatter will
9176 only be present if a compact form of the branch is available. */
9177 if (final_sequence == 0)
9178 putc ('c', file);
9179 break;
9181 case '!':
9182 /* If the delay slot instruction is short, then use the
9183 compact version. */
9184 if (TARGET_MICROMIPS && !TARGET_INTERLINK_COMPRESSED && mips_isa_rev <= 5
9185 && (final_sequence == 0
9186 || get_attr_length (final_sequence->insn (1)) == 2))
9187 putc ('s', file);
9188 break;
9190 default:
9191 gcc_unreachable ();
9192 break;
9196 /* Initialize mips_print_operand_punct. */
9198 static void
9199 mips_init_print_operand_punct (void)
9201 const char *p;
9203 for (p = "()[]<>*#/?~.@^+$:!"; *p; p++)
9204 mips_print_operand_punct[(unsigned char) *p] = true;
9207 /* PRINT_OPERAND prefix LETTER refers to the integer branch instruction
9208 associated with condition CODE. Print the condition part of the
9209 opcode to FILE. */
9211 static void
9212 mips_print_int_branch_condition (FILE *file, enum rtx_code code, int letter)
9214 switch (code)
9216 case EQ:
9217 case NE:
9218 case GT:
9219 case GE:
9220 case LT:
9221 case LE:
9222 case GTU:
9223 case GEU:
9224 case LTU:
9225 case LEU:
9226 /* Conveniently, the MIPS names for these conditions are the same
9227 as their RTL equivalents. */
9228 fputs (GET_RTX_NAME (code), file);
9229 break;
9231 default:
9232 output_operand_lossage ("'%%%c' is not a valid operand prefix", letter);
9233 break;
9237 /* Likewise floating-point branches. */
9239 static void
9240 mips_print_float_branch_condition (FILE *file, enum rtx_code code, int letter)
9242 switch (code)
9244 case EQ:
9245 if (ISA_HAS_CCF)
9246 fputs ("c1eqz", file);
9247 else
9248 fputs ("c1f", file);
9249 break;
9251 case NE:
9252 if (ISA_HAS_CCF)
9253 fputs ("c1nez", file);
9254 else
9255 fputs ("c1t", file);
9256 break;
9258 default:
9259 output_operand_lossage ("'%%%c' is not a valid operand prefix", letter);
9260 break;
9264 /* Implement TARGET_PRINT_OPERAND_PUNCT_VALID_P. */
9266 static bool
9267 mips_print_operand_punct_valid_p (unsigned char code)
9269 return mips_print_operand_punct[code];
9272 /* Implement TARGET_PRINT_OPERAND. The MIPS-specific operand codes are:
9274 'E' Print CONST_INT OP element 0 of a replicated CONST_VECTOR in decimal.
9275 'X' Print CONST_INT OP in hexadecimal format.
9276 'x' Print the low 16 bits of CONST_INT OP in hexadecimal format.
9277 'd' Print CONST_INT OP in decimal.
9278 'B' Print CONST_INT OP element 0 of a replicated CONST_VECTOR
9279 as an unsigned byte [0..255].
9280 'm' Print one less than CONST_INT OP in decimal.
9281 'y' Print exact log2 of CONST_INT OP in decimal.
9282 'h' Print the high-part relocation associated with OP, after stripping
9283 any outermost HIGH.
9284 'R' Print the low-part relocation associated with OP.
9285 'C' Print the integer branch condition for comparison OP.
9286 'N' Print the inverse of the integer branch condition for comparison OP.
9287 'F' Print the FPU branch condition for comparison OP.
9288 'W' Print the inverse of the FPU branch condition for comparison OP.
9289 'w' Print a MSA register.
9290 'T' Print 'f' for (eq:CC ...), 't' for (ne:CC ...),
9291 'z' for (eq:?I ...), 'n' for (ne:?I ...).
9292 't' Like 'T', but with the EQ/NE cases reversed
9293 'Y' Print mips_fp_conditions[INTVAL (OP)]
9294 'Z' Print OP and a comma for ISA_HAS_8CC, otherwise print nothing.
9295 'q' Print a DSP accumulator register.
9296 'D' Print the second part of a double-word register or memory operand.
9297 'L' Print the low-order register in a double-word register operand.
9298 'M' Print high-order register in a double-word register operand.
9299 'z' Print $0 if OP is zero, otherwise print OP normally.
9300 'b' Print the address of a memory operand, without offset.
9301 'v' Print the insn size suffix b, h, w or d for vector modes V16QI, V8HI,
9302 V4SI, V2SI, and w, d for vector modes V4SF, V2DF respectively.
9303 'V' Print exact log2 of CONST_INT OP element 0 of a replicated
9304 CONST_VECTOR in decimal. */
9306 static void
9307 mips_print_operand (FILE *file, rtx op, int letter)
9309 enum rtx_code code;
9311 if (mips_print_operand_punct_valid_p (letter))
9313 mips_print_operand_punctuation (file, letter);
9314 return;
9317 gcc_assert (op);
9318 code = GET_CODE (op);
9320 switch (letter)
9322 case 'E':
9323 if (GET_CODE (op) == CONST_VECTOR)
9325 gcc_assert (mips_const_vector_same_val_p (op, GET_MODE (op)));
9326 op = CONST_VECTOR_ELT (op, 0);
9327 gcc_assert (CONST_INT_P (op));
9328 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (op));
9330 else
9331 output_operand_lossage ("invalid use of '%%%c'", letter);
9332 break;
9334 case 'X':
9335 if (CONST_INT_P (op))
9336 fprintf (file, HOST_WIDE_INT_PRINT_HEX, INTVAL (op));
9337 else
9338 output_operand_lossage ("invalid use of '%%%c'", letter);
9339 break;
9341 case 'x':
9342 if (CONST_INT_P (op))
9343 fprintf (file, HOST_WIDE_INT_PRINT_HEX, INTVAL (op) & 0xffff);
9344 else
9345 output_operand_lossage ("invalid use of '%%%c'", letter);
9346 break;
9348 case 'd':
9349 if (CONST_INT_P (op))
9350 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (op));
9351 else
9352 output_operand_lossage ("invalid use of '%%%c'", letter);
9353 break;
9355 case 'B':
9356 if (GET_CODE (op) == CONST_VECTOR)
9358 gcc_assert (mips_const_vector_same_val_p (op, GET_MODE (op)));
9359 op = CONST_VECTOR_ELT (op, 0);
9360 gcc_assert (CONST_INT_P (op));
9361 unsigned HOST_WIDE_INT val8 = UINTVAL (op) & GET_MODE_MASK (QImode);
9362 fprintf (file, HOST_WIDE_INT_PRINT_UNSIGNED, val8);
9364 else
9365 output_operand_lossage ("invalid use of '%%%c'", letter);
9366 break;
9368 case 'm':
9369 if (CONST_INT_P (op))
9370 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (op) - 1);
9371 else
9372 output_operand_lossage ("invalid use of '%%%c'", letter);
9373 break;
9375 case 'y':
9376 if (CONST_INT_P (op))
9378 int val = exact_log2 (INTVAL (op));
9379 if (val != -1)
9380 fprintf (file, "%d", val);
9381 else
9382 output_operand_lossage ("invalid use of '%%%c'", letter);
9384 else
9385 output_operand_lossage ("invalid use of '%%%c'", letter);
9386 break;
9388 case 'V':
9389 if (GET_CODE (op) == CONST_VECTOR)
9391 machine_mode mode = GET_MODE_INNER (GET_MODE (op));
9392 unsigned HOST_WIDE_INT val = UINTVAL (CONST_VECTOR_ELT (op, 0));
9393 int vlog2 = exact_log2 (val & GET_MODE_MASK (mode));
9394 if (vlog2 != -1)
9395 fprintf (file, "%d", vlog2);
9396 else
9397 output_operand_lossage ("invalid use of '%%%c'", letter);
9399 else
9400 output_operand_lossage ("invalid use of '%%%c'", letter);
9401 break;
9403 case 'h':
9404 if (code == HIGH)
9405 op = XEXP (op, 0);
9406 mips_print_operand_reloc (file, op, SYMBOL_CONTEXT_LEA, mips_hi_relocs);
9407 break;
9409 case 'R':
9410 mips_print_operand_reloc (file, op, SYMBOL_CONTEXT_LEA, mips_lo_relocs);
9411 break;
9413 case 'C':
9414 mips_print_int_branch_condition (file, code, letter);
9415 break;
9417 case 'N':
9418 mips_print_int_branch_condition (file, reverse_condition (code), letter);
9419 break;
9421 case 'F':
9422 mips_print_float_branch_condition (file, code, letter);
9423 break;
9425 case 'W':
9426 mips_print_float_branch_condition (file, reverse_condition (code),
9427 letter);
9428 break;
9430 case 'T':
9431 case 't':
9433 int truth = (code == NE) == (letter == 'T');
9434 fputc ("zfnt"[truth * 2 + ST_REG_P (REGNO (XEXP (op, 0)))], file);
9436 break;
9438 case 'Y':
9439 if (code == CONST_INT && UINTVAL (op) < ARRAY_SIZE (mips_fp_conditions))
9440 fputs (mips_fp_conditions[UINTVAL (op)], file);
9441 else
9442 output_operand_lossage ("'%%%c' is not a valid operand prefix",
9443 letter);
9444 break;
9446 case 'Z':
9447 if (ISA_HAS_8CC || ISA_HAS_CCF)
9449 mips_print_operand (file, op, 0);
9450 fputc (',', file);
9452 break;
9454 case 'q':
9455 if (code == REG && MD_REG_P (REGNO (op)))
9456 fprintf (file, "$ac0");
9457 else if (code == REG && DSP_ACC_REG_P (REGNO (op)))
9458 fprintf (file, "$ac%c", reg_names[REGNO (op)][3]);
9459 else
9460 output_operand_lossage ("invalid use of '%%%c'", letter);
9461 break;
9463 case 'w':
9464 if (code == REG && MSA_REG_P (REGNO (op)))
9465 fprintf (file, "$w%s", &reg_names[REGNO (op)][2]);
9466 else
9467 output_operand_lossage ("invalid use of '%%%c'", letter);
9468 break;
9470 case 'v':
9471 switch (GET_MODE (op))
9473 case E_V16QImode:
9474 fprintf (file, "b");
9475 break;
9476 case E_V8HImode:
9477 fprintf (file, "h");
9478 break;
9479 case E_V4SImode:
9480 case E_V4SFmode:
9481 fprintf (file, "w");
9482 break;
9483 case E_V2DImode:
9484 case E_V2DFmode:
9485 fprintf (file, "d");
9486 break;
9487 default:
9488 output_operand_lossage ("invalid use of '%%%c'", letter);
9490 break;
9492 default:
9493 switch (code)
9495 case REG:
9497 unsigned int regno = REGNO (op);
9498 if ((letter == 'M' && TARGET_LITTLE_ENDIAN)
9499 || (letter == 'L' && TARGET_BIG_ENDIAN)
9500 || letter == 'D')
9501 regno++;
9502 else if (letter && letter != 'z' && letter != 'M' && letter != 'L')
9503 output_operand_lossage ("invalid use of '%%%c'", letter);
9504 /* We need to print $0 .. $31 for COP0 registers. */
9505 if (COP0_REG_P (regno))
9506 fprintf (file, "$%s", &reg_names[regno][4]);
9507 else
9508 fprintf (file, "%s", reg_names[regno]);
9510 break;
9512 case MEM:
9513 if (letter == 'D')
9514 output_address (GET_MODE (op), plus_constant (Pmode,
9515 XEXP (op, 0), 4));
9516 else if (letter == 'b')
9518 gcc_assert (REG_P (XEXP (op, 0)));
9519 mips_print_operand (file, XEXP (op, 0), 0);
9521 else if (letter && letter != 'z')
9522 output_operand_lossage ("invalid use of '%%%c'", letter);
9523 else
9524 output_address (GET_MODE (op), XEXP (op, 0));
9525 break;
9527 default:
9528 if (letter == 'z' && op == CONST0_RTX (GET_MODE (op)))
9529 fputs (reg_names[GP_REG_FIRST], file);
9530 else if (letter && letter != 'z')
9531 output_operand_lossage ("invalid use of '%%%c'", letter);
9532 else if (CONST_GP_P (op))
9533 fputs (reg_names[GLOBAL_POINTER_REGNUM], file);
9534 else
9535 output_addr_const (file, mips_strip_unspec_address (op));
9536 break;
9541 /* Implement TARGET_PRINT_OPERAND_ADDRESS. */
9543 static void
9544 mips_print_operand_address (FILE *file, machine_mode /*mode*/, rtx x)
9546 struct mips_address_info addr;
9548 if (mips_classify_address (&addr, x, word_mode, true))
9549 switch (addr.type)
9551 case ADDRESS_REG:
9552 mips_print_operand (file, addr.offset, 0);
9553 fprintf (file, "(%s)", reg_names[REGNO (addr.reg)]);
9554 return;
9556 case ADDRESS_LO_SUM:
9557 mips_print_operand_reloc (file, addr.offset, SYMBOL_CONTEXT_MEM,
9558 mips_lo_relocs);
9559 fprintf (file, "(%s)", reg_names[REGNO (addr.reg)]);
9560 return;
9562 case ADDRESS_CONST_INT:
9563 output_addr_const (file, x);
9564 fprintf (file, "(%s)", reg_names[GP_REG_FIRST]);
9565 return;
9567 case ADDRESS_SYMBOLIC:
9568 output_addr_const (file, mips_strip_unspec_address (x));
9569 return;
9571 gcc_unreachable ();
9574 /* Implement TARGET_ENCODE_SECTION_INFO. */
9576 static void
9577 mips_encode_section_info (tree decl, rtx rtl, int first)
9579 default_encode_section_info (decl, rtl, first);
9581 if (TREE_CODE (decl) == FUNCTION_DECL)
9583 rtx symbol = XEXP (rtl, 0);
9584 tree type = TREE_TYPE (decl);
9586 /* Encode whether the symbol is short or long. */
9587 if ((TARGET_LONG_CALLS && !mips_near_type_p (type))
9588 || mips_far_type_p (type))
9589 SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_LONG_CALL;
9593 /* Implement TARGET_SELECT_RTX_SECTION. */
9595 static section *
9596 mips_select_rtx_section (machine_mode mode, rtx x,
9597 unsigned HOST_WIDE_INT align)
9599 /* ??? Consider using mergeable small data sections. */
9600 if (mips_rtx_constant_in_small_data_p (mode))
9601 return get_named_section (NULL, ".sdata", 0);
9603 return default_elf_select_rtx_section (mode, x, align);
9606 /* Implement TARGET_IN_SMALL_DATA_P. */
9608 static bool
9609 mips_in_small_data_p (const_tree decl)
9611 unsigned HOST_WIDE_INT size;
9613 if (TREE_CODE (decl) == STRING_CST || TREE_CODE (decl) == FUNCTION_DECL)
9614 return false;
9616 /* We don't yet generate small-data references for -mabicalls
9617 or VxWorks RTP code. See the related -G handling in
9618 mips_option_override. */
9619 if (TARGET_ABICALLS || TARGET_VXWORKS_RTP)
9620 return false;
9622 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl) != 0)
9624 const char *name;
9626 /* Reject anything that isn't in a known small-data section. */
9627 name = DECL_SECTION_NAME (decl);
9628 if (strcmp (name, ".sdata") != 0 && strcmp (name, ".sbss") != 0)
9629 return false;
9631 /* If a symbol is defined externally, the assembler will use the
9632 usual -G rules when deciding how to implement macros. */
9633 if (mips_lo_relocs[SYMBOL_GP_RELATIVE] || !DECL_EXTERNAL (decl))
9634 return true;
9636 else if (TARGET_EMBEDDED_DATA)
9638 /* Don't put constants into the small data section: we want them
9639 to be in ROM rather than RAM. */
9640 if (TREE_CODE (decl) != VAR_DECL)
9641 return false;
9643 if (TREE_READONLY (decl)
9644 && !TREE_SIDE_EFFECTS (decl)
9645 && (!DECL_INITIAL (decl) || TREE_CONSTANT (DECL_INITIAL (decl))))
9646 return false;
9649 /* Enforce -mlocal-sdata. */
9650 if (!TARGET_LOCAL_SDATA && !TREE_PUBLIC (decl))
9651 return false;
9653 /* Enforce -mextern-sdata. */
9654 if (!TARGET_EXTERN_SDATA && DECL_P (decl))
9656 if (DECL_EXTERNAL (decl))
9657 return false;
9658 if (DECL_COMMON (decl) && DECL_INITIAL (decl) == NULL)
9659 return false;
9662 /* We have traditionally not treated zero-sized objects as small data,
9663 so this is now effectively part of the ABI. */
9664 size = int_size_in_bytes (TREE_TYPE (decl));
9665 return size > 0 && size <= mips_small_data_threshold;
9668 /* Implement TARGET_USE_ANCHORS_FOR_SYMBOL_P. We don't want to use
9669 anchors for small data: the GP register acts as an anchor in that
9670 case. We also don't want to use them for PC-relative accesses,
9671 where the PC acts as an anchor. */
9673 static bool
9674 mips_use_anchors_for_symbol_p (const_rtx symbol)
9676 switch (mips_classify_symbol (symbol, SYMBOL_CONTEXT_MEM))
9678 case SYMBOL_PC_RELATIVE:
9679 case SYMBOL_GP_RELATIVE:
9680 return false;
9682 default:
9683 return default_use_anchors_for_symbol_p (symbol);
9687 /* The MIPS debug format wants all automatic variables and arguments
9688 to be in terms of the virtual frame pointer (stack pointer before
9689 any adjustment in the function), while the MIPS 3.0 linker wants
9690 the frame pointer to be the stack pointer after the initial
9691 adjustment. So, we do the adjustment here. The arg pointer (which
9692 is eliminated) points to the virtual frame pointer, while the frame
9693 pointer (which may be eliminated) points to the stack pointer after
9694 the initial adjustments. */
9696 HOST_WIDE_INT
9697 mips_debugger_offset (rtx addr, HOST_WIDE_INT offset)
9699 rtx offset2 = const0_rtx;
9700 rtx reg = eliminate_constant_term (addr, &offset2);
9702 if (offset == 0)
9703 offset = INTVAL (offset2);
9705 if (reg == stack_pointer_rtx
9706 || reg == frame_pointer_rtx
9707 || reg == hard_frame_pointer_rtx)
9709 offset -= cfun->machine->frame.total_size;
9710 if (reg == hard_frame_pointer_rtx)
9711 offset += cfun->machine->frame.hard_frame_pointer_offset;
9714 return offset;
9717 /* Implement ASM_OUTPUT_EXTERNAL. */
9719 void
9720 mips_output_external (FILE *file, tree decl, const char *name)
9722 default_elf_asm_output_external (file, decl, name);
9724 /* We output the name if and only if TREE_SYMBOL_REFERENCED is
9725 set in order to avoid putting out names that are never really
9726 used. */
9727 if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
9729 if (!TARGET_EXPLICIT_RELOCS && mips_in_small_data_p (decl))
9731 /* When using assembler macros, emit .extern directives for
9732 all small-data externs so that the assembler knows how
9733 big they are.
9735 In most cases it would be safe (though pointless) to emit
9736 .externs for other symbols too. One exception is when an
9737 object is within the -G limit but declared by the user to
9738 be in a section other than .sbss or .sdata. */
9739 fputs ("\t.extern\t", file);
9740 assemble_name (file, name);
9741 fprintf (file, ", " HOST_WIDE_INT_PRINT_DEC "\n",
9742 int_size_in_bytes (TREE_TYPE (decl)));
9747 /* Implement TARGET_ASM_OUTPUT_SOURCE_FILENAME. */
9749 static void
9750 mips_output_filename (FILE *stream, const char *name)
9752 /* If we are emitting DWARF-2, let dwarf2out handle the ".file"
9753 directives. */
9754 if (dwarf_debuginfo_p ())
9755 return;
9756 else if (mips_output_filename_first_time)
9758 mips_output_filename_first_time = 0;
9759 num_source_filenames += 1;
9760 current_function_file = name;
9761 fprintf (stream, "\t.file\t%d ", num_source_filenames);
9762 output_quoted_string (stream, name);
9763 putc ('\n', stream);
9765 else if (name != current_function_file
9766 && strcmp (name, current_function_file) != 0)
9768 num_source_filenames += 1;
9769 current_function_file = name;
9770 fprintf (stream, "\t.file\t%d ", num_source_filenames);
9771 output_quoted_string (stream, name);
9772 putc ('\n', stream);
9776 /* Implement TARGET_ASM_OUTPUT_DWARF_DTPREL. */
9778 static void ATTRIBUTE_UNUSED
9779 mips_output_dwarf_dtprel (FILE *file, int size, rtx x)
9781 switch (size)
9783 case 4:
9784 fputs ("\t.dtprelword\t", file);
9785 break;
9787 case 8:
9788 fputs ("\t.dtpreldword\t", file);
9789 break;
9791 default:
9792 gcc_unreachable ();
9794 output_addr_const (file, x);
9795 fputs ("+0x8000", file);
9798 /* Implement TARGET_DWARF_REGISTER_SPAN. */
9800 static rtx
9801 mips_dwarf_register_span (rtx reg)
9803 rtx high, low;
9804 machine_mode mode;
9806 /* TARGET_FLOATXX is implemented as 32-bit floating-point registers but
9807 ensures that double-precision registers are treated as if they were
9808 64-bit physical registers. The code will run correctly with 32-bit or
9809 64-bit registers which means that dwarf information cannot be precise
9810 for all scenarios. We choose to state that the 64-bit values are stored
9811 in a single 64-bit 'piece'. This slightly unusual construct can then be
9812 interpreted as either a pair of registers if the registers are 32-bit or
9813 a single 64-bit register depending on hardware. */
9814 mode = GET_MODE (reg);
9815 if (FP_REG_P (REGNO (reg))
9816 && TARGET_FLOATXX
9817 && GET_MODE_SIZE (mode) > UNITS_PER_FPREG)
9819 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, reg));
9821 /* By default, GCC maps increasing register numbers to increasing
9822 memory locations, but paired FPRs are always little-endian,
9823 regardless of the prevailing endianness. */
9824 else if (FP_REG_P (REGNO (reg))
9825 && TARGET_BIG_ENDIAN
9826 && MAX_FPRS_PER_FMT > 1
9827 && GET_MODE_SIZE (mode) > UNITS_PER_FPREG)
9829 gcc_assert (GET_MODE_SIZE (mode) == UNITS_PER_HWFPVALUE);
9830 high = mips_subword (reg, true);
9831 low = mips_subword (reg, false);
9832 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, high, low));
9835 return NULL_RTX;
9838 /* Implement TARGET_DWARF_FRAME_REG_MODE. */
9840 static machine_mode
9841 mips_dwarf_frame_reg_mode (int regno)
9843 machine_mode mode = default_dwarf_frame_reg_mode (regno);
9845 if (FP_REG_P (regno) && mips_abi == ABI_32 && !TARGET_FLOAT32)
9846 mode = SImode;
9848 return mode;
9851 /* DSP ALU can bypass data with no delays for the following pairs. */
9852 enum insn_code dspalu_bypass_table[][2] =
9854 {CODE_FOR_mips_addsc, CODE_FOR_mips_addwc},
9855 {CODE_FOR_mips_cmpu_eq_qb, CODE_FOR_mips_pick_qb},
9856 {CODE_FOR_mips_cmpu_lt_qb, CODE_FOR_mips_pick_qb},
9857 {CODE_FOR_mips_cmpu_le_qb, CODE_FOR_mips_pick_qb},
9858 {CODE_FOR_mips_cmp_eq_ph, CODE_FOR_mips_pick_ph},
9859 {CODE_FOR_mips_cmp_lt_ph, CODE_FOR_mips_pick_ph},
9860 {CODE_FOR_mips_cmp_le_ph, CODE_FOR_mips_pick_ph},
9861 {CODE_FOR_mips_wrdsp, CODE_FOR_mips_insv}
9865 mips_dspalu_bypass_p (rtx out_insn, rtx in_insn)
9867 int i;
9868 int num_bypass = ARRAY_SIZE (dspalu_bypass_table);
9869 enum insn_code out_icode = (enum insn_code) INSN_CODE (out_insn);
9870 enum insn_code in_icode = (enum insn_code) INSN_CODE (in_insn);
9872 for (i = 0; i < num_bypass; i++)
9874 if (out_icode == dspalu_bypass_table[i][0]
9875 && in_icode == dspalu_bypass_table[i][1])
9876 return true;
9879 return false;
9881 /* Implement ASM_OUTPUT_ASCII. */
9883 void
9884 mips_output_ascii (FILE *stream, const char *string, size_t len)
9886 size_t i;
9887 int cur_pos;
9889 cur_pos = 17;
9890 fprintf (stream, "\t.ascii\t\"");
9891 for (i = 0; i < len; i++)
9893 int c;
9895 c = (unsigned char) string[i];
9896 if (ISPRINT (c))
9898 if (c == '\\' || c == '\"')
9900 putc ('\\', stream);
9901 cur_pos++;
9903 putc (c, stream);
9904 cur_pos++;
9906 else
9908 fprintf (stream, "\\%03o", c);
9909 cur_pos += 4;
9912 if (cur_pos > 72 && i+1 < len)
9914 cur_pos = 17;
9915 fprintf (stream, "\"\n\t.ascii\t\"");
9918 fprintf (stream, "\"\n");
9921 /* Return the pseudo-op for full SYMBOL_(D)TPREL address *ADDR.
9922 Update *ADDR with the operand that should be printed. */
9924 const char *
9925 mips_output_tls_reloc_directive (rtx *addr)
9927 enum mips_symbol_type type;
9929 type = mips_classify_symbolic_expression (*addr, SYMBOL_CONTEXT_LEA);
9930 *addr = mips_strip_unspec_address (*addr);
9931 switch (type)
9933 case SYMBOL_DTPREL:
9934 return Pmode == SImode ? ".dtprelword\t%0" : ".dtpreldword\t%0";
9936 case SYMBOL_TPREL:
9937 return Pmode == SImode ? ".tprelword\t%0" : ".tpreldword\t%0";
9939 default:
9940 gcc_unreachable ();
9944 /* Emit either a label, .comm, or .lcomm directive. When using assembler
9945 macros, mark the symbol as written so that mips_asm_output_external
9946 won't emit an .extern for it. STREAM is the output file, NAME is the
9947 name of the symbol, INIT_STRING is the string that should be written
9948 before the symbol and FINAL_STRING is the string that should be
9949 written after it. FINAL_STRING is a printf format that consumes the
9950 remaining arguments. */
9952 void
9953 mips_declare_object (FILE *stream, const char *name, const char *init_string,
9954 const char *final_string, ...)
9956 va_list ap;
9958 fputs (init_string, stream);
9959 assemble_name (stream, name);
9960 va_start (ap, final_string);
9961 vfprintf (stream, final_string, ap);
9962 va_end (ap);
9964 if (!TARGET_EXPLICIT_RELOCS)
9966 tree name_tree = get_identifier (name);
9967 TREE_ASM_WRITTEN (name_tree) = 1;
9971 /* Declare a common object of SIZE bytes using asm directive INIT_STRING.
9972 NAME is the name of the object and ALIGN is the required alignment
9973 in bytes. TAKES_ALIGNMENT_P is true if the directive takes a third
9974 alignment argument. */
9976 void
9977 mips_declare_common_object (FILE *stream, const char *name,
9978 const char *init_string,
9979 unsigned HOST_WIDE_INT size,
9980 unsigned int align, bool takes_alignment_p)
9982 if (!takes_alignment_p)
9984 size += (align / BITS_PER_UNIT) - 1;
9985 size -= size % (align / BITS_PER_UNIT);
9986 mips_declare_object (stream, name, init_string,
9987 "," HOST_WIDE_INT_PRINT_UNSIGNED "\n", size);
9989 else
9990 mips_declare_object (stream, name, init_string,
9991 "," HOST_WIDE_INT_PRINT_UNSIGNED ",%u\n",
9992 size, align / BITS_PER_UNIT);
9995 /* Implement ASM_OUTPUT_ALIGNED_DECL_COMMON. This is usually the same as the
9996 elfos.h version, but we also need to handle -muninit-const-in-rodata. */
9998 void
9999 mips_output_aligned_decl_common (FILE *stream, tree decl, const char *name,
10000 unsigned HOST_WIDE_INT size,
10001 unsigned int align)
10003 /* If the target wants uninitialized const declarations in
10004 .rdata then don't put them in .comm. */
10005 if (TARGET_EMBEDDED_DATA
10006 && TARGET_UNINIT_CONST_IN_RODATA
10007 && VAR_P (decl)
10008 && TREE_READONLY (decl)
10009 && (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node))
10011 if (TREE_PUBLIC (decl) && DECL_NAME (decl))
10012 targetm.asm_out.globalize_label (stream, name);
10014 switch_to_section (readonly_data_section);
10015 ASM_OUTPUT_ALIGN (stream, floor_log2 (align / BITS_PER_UNIT));
10016 mips_declare_object (stream, name, "",
10017 ":\n\t.space\t" HOST_WIDE_INT_PRINT_UNSIGNED "\n",
10018 size);
10020 else
10021 mips_declare_common_object (stream, name, "\n\t.comm\t",
10022 size, align, true);
10025 #ifdef ASM_OUTPUT_SIZE_DIRECTIVE
10026 extern int size_directive_output;
10028 /* Implement ASM_DECLARE_OBJECT_NAME. This is like most of the standard ELF
10029 definitions except that it uses mips_declare_object to emit the label. */
10031 void
10032 mips_declare_object_name (FILE *stream, const char *name,
10033 tree decl ATTRIBUTE_UNUSED)
10035 #ifdef ASM_OUTPUT_TYPE_DIRECTIVE
10036 #ifdef USE_GNU_UNIQUE_OBJECT
10037 /* As in elfos.h. */
10038 if (USE_GNU_UNIQUE_OBJECT && DECL_ONE_ONLY (decl)
10039 && (!DECL_ARTIFICIAL (decl) || !TREE_READONLY (decl)))
10040 ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "gnu_unique_object");
10041 else
10042 #endif
10043 ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "object");
10044 #endif
10046 size_directive_output = 0;
10047 if (!flag_inhibit_size_directive && DECL_SIZE (decl))
10049 HOST_WIDE_INT size;
10051 size_directive_output = 1;
10052 size = int_size_in_bytes (TREE_TYPE (decl));
10053 ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
10056 mips_declare_object (stream, name, "", ":\n");
10059 /* Implement ASM_FINISH_DECLARE_OBJECT. This is generic ELF stuff. */
10061 void
10062 mips_finish_declare_object (FILE *stream, tree decl, int top_level, int at_end)
10064 const char *name;
10066 name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
10067 if (!flag_inhibit_size_directive
10068 && DECL_SIZE (decl) != 0
10069 && !at_end
10070 && top_level
10071 && DECL_INITIAL (decl) == error_mark_node
10072 && !size_directive_output)
10074 HOST_WIDE_INT size;
10076 size_directive_output = 1;
10077 size = int_size_in_bytes (TREE_TYPE (decl));
10078 ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
10081 #endif
10083 /* Mark text contents as code or data, mainly for the purpose of correct
10084 disassembly. Emit a local symbol and set its type appropriately for
10085 that purpose. Also emit `.insn' if marking contents as code so that
10086 the ISA mode is recorded and any padding that follows is disassembled
10087 as correct instructions. */
10089 void
10090 mips_set_text_contents_type (FILE *file ATTRIBUTE_UNUSED,
10091 const char *prefix ATTRIBUTE_UNUSED,
10092 unsigned HOST_WIDE_INT num ATTRIBUTE_UNUSED,
10093 bool function_p ATTRIBUTE_UNUSED)
10095 #ifdef ASM_OUTPUT_TYPE_DIRECTIVE
10096 char buf[(sizeof (num) * 10) / 4 + 2];
10097 const char *fnname;
10098 char *sname;
10099 rtx symbol;
10101 sprintf (buf, HOST_WIDE_INT_PRINT_UNSIGNED, num);
10102 symbol = XEXP (DECL_RTL (current_function_decl), 0);
10103 fnname = targetm.strip_name_encoding (XSTR (symbol, 0));
10104 sname = ACONCAT ((prefix, fnname, "_", buf, NULL));
10106 ASM_OUTPUT_TYPE_DIRECTIVE (file, sname, function_p ? "function" : "object");
10107 assemble_name (file, sname);
10108 fputs (":\n", file);
10109 if (function_p)
10110 fputs ("\t.insn\n", file);
10111 #endif
10114 /* Return the FOO in the name of the ".mdebug.FOO" section associated
10115 with the current ABI. */
10117 static const char *
10118 mips_mdebug_abi_name (void)
10120 switch (mips_abi)
10122 case ABI_32:
10123 return "abi32";
10124 case ABI_O64:
10125 return "abiO64";
10126 case ABI_N32:
10127 return "abiN32";
10128 case ABI_64:
10129 return "abi64";
10130 case ABI_EABI:
10131 return TARGET_64BIT ? "eabi64" : "eabi32";
10132 default:
10133 gcc_unreachable ();
10137 /* Implement TARGET_ASM_FILE_START. */
10139 static void
10140 mips_file_start (void)
10142 default_file_start ();
10144 /* Generate a special section to describe the ABI switches used to
10145 produce the resultant binary. */
10147 /* Record the ABI itself. Modern versions of binutils encode
10148 this information in the ELF header flags, but GDB needs the
10149 information in order to correctly debug binaries produced by
10150 older binutils. See the function mips_gdbarch_init in
10151 gdb/mips-tdep.c. */
10152 fprintf (asm_out_file, "\t.section .mdebug.%s\n\t.previous\n",
10153 mips_mdebug_abi_name ());
10155 /* There is no ELF header flag to distinguish long32 forms of the
10156 EABI from long64 forms. Emit a special section to help tools
10157 such as GDB. Do the same for o64, which is sometimes used with
10158 -mlong64. */
10159 if (mips_abi == ABI_EABI || mips_abi == ABI_O64)
10160 fprintf (asm_out_file, "\t.section .gcc_compiled_long%d\n"
10161 "\t.previous\n", TARGET_LONG64 ? 64 : 32);
10163 /* Record the NaN encoding. */
10164 if (HAVE_AS_NAN || mips_nan != MIPS_IEEE_754_DEFAULT)
10165 fprintf (asm_out_file, "\t.nan\t%s\n",
10166 mips_nan == MIPS_IEEE_754_2008 ? "2008" : "legacy");
10168 #ifdef HAVE_AS_DOT_MODULE
10169 /* Record the FP ABI. See below for comments. */
10170 if (TARGET_NO_FLOAT)
10171 #ifdef HAVE_AS_GNU_ATTRIBUTE
10172 fputs ("\t.gnu_attribute 4, 0\n", asm_out_file);
10173 #else
10175 #endif
10176 else if (!TARGET_HARD_FLOAT_ABI)
10177 fputs ("\t.module\tsoftfloat\n", asm_out_file);
10178 else if (!TARGET_DOUBLE_FLOAT)
10179 fputs ("\t.module\tsinglefloat\n", asm_out_file);
10180 else if (TARGET_FLOATXX)
10181 fputs ("\t.module\tfp=xx\n", asm_out_file);
10182 else if (TARGET_FLOAT64)
10183 fputs ("\t.module\tfp=64\n", asm_out_file);
10184 else
10185 fputs ("\t.module\tfp=32\n", asm_out_file);
10187 if (TARGET_ODD_SPREG)
10188 fputs ("\t.module\toddspreg\n", asm_out_file);
10189 else
10190 fputs ("\t.module\tnooddspreg\n", asm_out_file);
10192 fprintf (asm_out_file, "\t.module\tarch=%s\n", mips_arch_info->name);
10193 /* FIXME: DSPR3 is not supported by GCC? gas does support it */
10194 if (TARGET_DSPR2)
10195 fputs ("\t.module\tdspr2\n", asm_out_file);
10196 else if (TARGET_DSP)
10197 fputs ("\t.module\tdsp\n", asm_out_file);
10198 if (TARGET_EVA)
10199 fputs ("\t.module\teva\n", asm_out_file);
10200 if (TARGET_MCU)
10201 fputs ("\t.module\tmcu\n", asm_out_file);
10202 if (TARGET_MDMX)
10203 fputs ("\t.module\tmdmx\n", asm_out_file);
10204 if (TARGET_MIPS3D)
10205 fputs ("\t.module\tmips3d\n", asm_out_file);
10206 if (TARGET_MT)
10207 fputs ("\t.module\tmt\n", asm_out_file);
10208 if (TARGET_SMARTMIPS)
10209 fputs ("\t.module\tsmartmips\n", asm_out_file);
10210 if (TARGET_VIRT)
10211 fputs ("\t.module\tvirt\n", asm_out_file);
10212 if (TARGET_MSA)
10213 fputs ("\t.module\tmsa\n", asm_out_file);
10214 if (TARGET_XPA)
10215 fputs ("\t.module\txpa\n", asm_out_file);
10216 if (TARGET_MIPS16E2)
10217 fputs ("\t.module\tmips16e2\n", asm_out_file);
10218 if (TARGET_CRC)
10219 fputs ("\t.module\tcrc\n", asm_out_file);
10220 if (TARGET_GINV)
10221 fputs ("\t.module\tginv\n", asm_out_file);
10222 if (TARGET_LOONGSON_MMI)
10223 fputs ("\t.module\tloongson-mmi\n", asm_out_file);
10224 /* FIXME: LOONGSON-CAM is not supported by GCC? gas does support it */
10225 if (TARGET_LOONGSON_EXT2)
10226 fputs ("\t.module\tloongson-ext2\n", asm_out_file);
10227 else if (TARGET_LOONGSON_EXT)
10228 fputs ("\t.module\tloongson-ext\n", asm_out_file);
10230 #else
10231 #ifdef HAVE_AS_GNU_ATTRIBUTE
10233 int attr;
10235 /* No floating-point operations, -mno-float. */
10236 if (TARGET_NO_FLOAT)
10237 attr = 0;
10238 /* Soft-float code, -msoft-float. */
10239 else if (!TARGET_HARD_FLOAT_ABI)
10240 attr = 3;
10241 /* Single-float code, -msingle-float. */
10242 else if (!TARGET_DOUBLE_FLOAT)
10243 attr = 2;
10244 /* 64-bit FP registers on a 32-bit target, -mips32r2 -mfp64.
10245 Reserved attr=4.
10246 This case used 12 callee-saved double-precision registers
10247 and is deprecated. */
10248 /* 64-bit or 32-bit FP registers on a 32-bit target, -mfpxx. */
10249 else if (TARGET_FLOATXX)
10250 attr = 5;
10251 /* 64-bit FP registers on a 32-bit target, -mfp64 -modd-spreg. */
10252 else if (mips_abi == ABI_32 && TARGET_FLOAT64 && TARGET_ODD_SPREG)
10253 attr = 6;
10254 /* 64-bit FP registers on a 32-bit target, -mfp64 -mno-odd-spreg. */
10255 else if (mips_abi == ABI_32 && TARGET_FLOAT64)
10256 attr = 7;
10257 /* Regular FP code, FP regs same size as GP regs, -mdouble-float. */
10258 else
10259 attr = 1;
10261 fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n", attr);
10263 /* 128-bit MSA. */
10264 if (ISA_HAS_MSA)
10265 fprintf (asm_out_file, "\t.gnu_attribute 8, 1\n");
10267 #endif
10268 #endif
10270 /* If TARGET_ABICALLS, tell GAS to generate -KPIC code. */
10271 if (TARGET_ABICALLS)
10273 fprintf (asm_out_file, "\t.abicalls\n");
10274 if (TARGET_ABICALLS_PIC0)
10275 fprintf (asm_out_file, "\t.option\tpic0\n");
10278 if (flag_verbose_asm)
10279 fprintf (asm_out_file, "\n%s -G value = %d, Arch = %s, ISA = %d\n",
10280 ASM_COMMENT_START,
10281 mips_small_data_threshold, mips_arch_info->name, mips_isa);
10284 /* Implement TARGET_ASM_CODE_END. */
10286 static void
10287 mips_code_end (void)
10289 mips_finish_stub (&mips16_rdhwr_stub);
10290 mips_finish_stub (&mips16_get_fcsr_stub);
10291 mips_finish_stub (&mips16_set_fcsr_stub);
10294 /* Make the last instruction frame-related and note that it performs
10295 the operation described by FRAME_PATTERN. */
10297 static void
10298 mips_set_frame_expr (rtx frame_pattern)
10300 rtx_insn *insn;
10302 insn = get_last_insn ();
10303 RTX_FRAME_RELATED_P (insn) = 1;
10304 REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
10305 frame_pattern,
10306 REG_NOTES (insn));
10309 /* Return a frame-related rtx that stores REG at MEM.
10310 REG must be a single register. */
10312 static rtx
10313 mips_frame_set (rtx mem, rtx reg)
10315 rtx set;
10317 set = gen_rtx_SET (mem, reg);
10318 RTX_FRAME_RELATED_P (set) = 1;
10320 return set;
10323 /* Record that the epilogue has restored call-saved register REG. */
10325 static void
10326 mips_add_cfa_restore (rtx reg)
10328 mips_epilogue.cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
10329 mips_epilogue.cfa_restores);
10332 /* If a MIPS16e SAVE or RESTORE instruction saves or restores register
10333 mips16e_s2_s8_regs[X], it must also save the registers in indexes
10334 X + 1 onwards. Likewise mips16e_a0_a3_regs. */
10335 static const unsigned char mips16e_s2_s8_regs[] = {
10336 30, 23, 22, 21, 20, 19, 18
10338 static const unsigned char mips16e_a0_a3_regs[] = {
10339 4, 5, 6, 7
10342 /* A list of the registers that can be saved by the MIPS16e SAVE instruction,
10343 ordered from the uppermost in memory to the lowest in memory. */
10344 static const unsigned char mips16e_save_restore_regs[] = {
10345 31, 30, 23, 22, 21, 20, 19, 18, 17, 16, 7, 6, 5, 4
10348 /* Return the index of the lowest X in the range [0, SIZE) for which
10349 bit REGS[X] is set in MASK. Return SIZE if there is no such X. */
10351 static unsigned int
10352 mips16e_find_first_register (unsigned int mask, const unsigned char *regs,
10353 unsigned int size)
10355 unsigned int i;
10357 for (i = 0; i < size; i++)
10358 if (BITSET_P (mask, regs[i]))
10359 break;
10361 return i;
10364 /* *MASK_PTR is a mask of general-purpose registers and *NUM_REGS_PTR
10365 is the number of set bits. If *MASK_PTR contains REGS[X] for some X
10366 in [0, SIZE), adjust *MASK_PTR and *NUM_REGS_PTR so that the same
10367 is true for all indexes (X, SIZE). */
10369 static void
10370 mips16e_mask_registers (unsigned int *mask_ptr, const unsigned char *regs,
10371 unsigned int size, unsigned int *num_regs_ptr)
10373 unsigned int i;
10375 i = mips16e_find_first_register (*mask_ptr, regs, size);
10376 for (i++; i < size; i++)
10377 if (!BITSET_P (*mask_ptr, regs[i]))
10379 *num_regs_ptr += 1;
10380 *mask_ptr |= 1 << regs[i];
10384 /* Return a simplified form of X using the register values in REG_VALUES.
10385 REG_VALUES[R] is the last value assigned to hard register R, or null
10386 if R has not been modified.
10388 This function is rather limited, but is good enough for our purposes. */
10390 static rtx
10391 mips16e_collect_propagate_value (rtx x, rtx *reg_values)
10393 x = avoid_constant_pool_reference (x);
10395 if (UNARY_P (x))
10397 rtx x0 = mips16e_collect_propagate_value (XEXP (x, 0), reg_values);
10398 return simplify_gen_unary (GET_CODE (x), GET_MODE (x),
10399 x0, GET_MODE (XEXP (x, 0)));
10402 if (ARITHMETIC_P (x))
10404 rtx x0 = mips16e_collect_propagate_value (XEXP (x, 0), reg_values);
10405 rtx x1 = mips16e_collect_propagate_value (XEXP (x, 1), reg_values);
10406 return simplify_gen_binary (GET_CODE (x), GET_MODE (x), x0, x1);
10409 if (REG_P (x)
10410 && reg_values[REGNO (x)]
10411 && !rtx_unstable_p (reg_values[REGNO (x)]))
10412 return reg_values[REGNO (x)];
10414 return x;
10417 /* Return true if (set DEST SRC) stores an argument register into its
10418 caller-allocated save slot, storing the number of that argument
10419 register in *REGNO_PTR if so. REG_VALUES is as for
10420 mips16e_collect_propagate_value. */
10422 static bool
10423 mips16e_collect_argument_save_p (rtx dest, rtx src, rtx *reg_values,
10424 unsigned int *regno_ptr)
10426 unsigned int argno, regno;
10427 HOST_WIDE_INT offset, required_offset;
10428 rtx addr, base;
10430 /* Check that this is a word-mode store. */
10431 if (!MEM_P (dest) || !REG_P (src) || GET_MODE (dest) != word_mode)
10432 return false;
10434 /* Check that the register being saved is an unmodified argument
10435 register. */
10436 regno = REGNO (src);
10437 if (!IN_RANGE (regno, GP_ARG_FIRST, GP_ARG_LAST) || reg_values[regno])
10438 return false;
10439 argno = regno - GP_ARG_FIRST;
10441 /* Check whether the address is an appropriate stack-pointer or
10442 frame-pointer access. */
10443 addr = mips16e_collect_propagate_value (XEXP (dest, 0), reg_values);
10444 mips_split_plus (addr, &base, &offset);
10445 required_offset = cfun->machine->frame.total_size + argno * UNITS_PER_WORD;
10446 if (base == hard_frame_pointer_rtx)
10447 required_offset -= cfun->machine->frame.hard_frame_pointer_offset;
10448 else if (base != stack_pointer_rtx)
10449 return false;
10450 if (offset != required_offset)
10451 return false;
10453 *regno_ptr = regno;
10454 return true;
10457 /* A subroutine of mips_expand_prologue, called only when generating
10458 MIPS16e SAVE instructions. Search the start of the function for any
10459 instructions that save argument registers into their caller-allocated
10460 save slots. Delete such instructions and return a value N such that
10461 saving [GP_ARG_FIRST, GP_ARG_FIRST + N) would make all the deleted
10462 instructions redundant. */
10464 static unsigned int
10465 mips16e_collect_argument_saves (void)
10467 rtx reg_values[FIRST_PSEUDO_REGISTER];
10468 rtx_insn *insn, *next;
10469 rtx set, dest, src;
10470 unsigned int nargs, regno;
10472 push_topmost_sequence ();
10473 nargs = 0;
10474 memset (reg_values, 0, sizeof (reg_values));
10475 for (insn = get_insns (); insn; insn = next)
10477 next = NEXT_INSN (insn);
10478 if (NOTE_P (insn) || DEBUG_INSN_P (insn))
10479 continue;
10481 if (!INSN_P (insn))
10482 break;
10484 set = PATTERN (insn);
10485 if (GET_CODE (set) != SET)
10486 break;
10488 dest = SET_DEST (set);
10489 src = SET_SRC (set);
10490 if (mips16e_collect_argument_save_p (dest, src, reg_values, &regno))
10492 if (!BITSET_P (cfun->machine->frame.mask, regno))
10494 delete_insn (insn);
10495 nargs = MAX (nargs, (regno - GP_ARG_FIRST) + 1);
10498 else if (REG_P (dest) && GET_MODE (dest) == word_mode)
10499 reg_values[REGNO (dest)]
10500 = mips16e_collect_propagate_value (src, reg_values);
10501 else
10502 break;
10504 pop_topmost_sequence ();
10506 return nargs;
10509 /* Return a move between register REGNO and memory location SP + OFFSET.
10510 REG_PARM_P is true if SP + OFFSET belongs to REG_PARM_STACK_SPACE.
10511 Make the move a load if RESTORE_P, otherwise make it a store. */
10513 static rtx
10514 mips16e_save_restore_reg (bool restore_p, bool reg_parm_p,
10515 HOST_WIDE_INT offset, unsigned int regno)
10517 rtx reg, mem;
10519 mem = gen_frame_mem (SImode, plus_constant (Pmode, stack_pointer_rtx,
10520 offset));
10521 reg = gen_rtx_REG (SImode, regno);
10522 if (restore_p)
10524 mips_add_cfa_restore (reg);
10525 return gen_rtx_SET (reg, mem);
10527 if (reg_parm_p)
10528 return gen_rtx_SET (mem, reg);
10529 return mips_frame_set (mem, reg);
10532 /* Return RTL for a MIPS16e SAVE or RESTORE instruction; RESTORE_P says which.
10533 The instruction must:
10535 - Allocate or deallocate SIZE bytes in total; SIZE is known
10536 to be nonzero.
10538 - Save or restore as many registers in *MASK_PTR as possible.
10539 The instruction saves the first registers at the top of the
10540 allocated area, with the other registers below it.
10542 - Save NARGS argument registers above the allocated area.
10544 (NARGS is always zero if RESTORE_P.)
10546 The SAVE and RESTORE instructions cannot save and restore all general
10547 registers, so there may be some registers left over for the caller to
10548 handle. Destructively modify *MASK_PTR so that it contains the registers
10549 that still need to be saved or restored. The caller can save these
10550 registers in the memory immediately below *OFFSET_PTR, which is a
10551 byte offset from the bottom of the allocated stack area. */
10553 static rtx
10554 mips16e_build_save_restore (bool restore_p, unsigned int *mask_ptr,
10555 HOST_WIDE_INT *offset_ptr, unsigned int nargs,
10556 HOST_WIDE_INT size)
10558 rtx pattern, set;
10559 HOST_WIDE_INT offset, top_offset;
10560 unsigned int i, regno;
10561 int n;
10563 gcc_assert (cfun->machine->frame.num_fp == 0);
10565 /* Calculate the number of elements in the PARALLEL. We need one element
10566 for the stack adjustment, one for each argument register save, and one
10567 for each additional register move. */
10568 n = 1 + nargs;
10569 for (i = 0; i < ARRAY_SIZE (mips16e_save_restore_regs); i++)
10570 if (BITSET_P (*mask_ptr, mips16e_save_restore_regs[i]))
10571 n++;
10573 /* Create the final PARALLEL. */
10574 pattern = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (n));
10575 n = 0;
10577 /* Add the stack pointer adjustment. */
10578 set = gen_rtx_SET (stack_pointer_rtx,
10579 plus_constant (Pmode, stack_pointer_rtx,
10580 restore_p ? size : -size));
10581 RTX_FRAME_RELATED_P (set) = 1;
10582 XVECEXP (pattern, 0, n++) = set;
10584 /* Stack offsets in the PARALLEL are relative to the old stack pointer. */
10585 top_offset = restore_p ? size : 0;
10587 /* Save the arguments. */
10588 for (i = 0; i < nargs; i++)
10590 offset = top_offset + i * UNITS_PER_WORD;
10591 set = mips16e_save_restore_reg (restore_p, true, offset,
10592 GP_ARG_FIRST + i);
10593 XVECEXP (pattern, 0, n++) = set;
10596 /* Then fill in the other register moves. */
10597 offset = top_offset;
10598 for (i = 0; i < ARRAY_SIZE (mips16e_save_restore_regs); i++)
10600 regno = mips16e_save_restore_regs[i];
10601 if (BITSET_P (*mask_ptr, regno))
10603 offset -= UNITS_PER_WORD;
10604 set = mips16e_save_restore_reg (restore_p, false, offset, regno);
10605 XVECEXP (pattern, 0, n++) = set;
10606 *mask_ptr &= ~(1 << regno);
10610 /* Tell the caller what offset it should use for the remaining registers. */
10611 *offset_ptr = size + (offset - top_offset);
10613 gcc_assert (n == XVECLEN (pattern, 0));
10615 return pattern;
10618 /* PATTERN is a PARALLEL whose first element adds ADJUST to the stack
10619 pointer. Return true if PATTERN matches the kind of instruction
10620 generated by mips16e_build_save_restore. If INFO is nonnull,
10621 initialize it when returning true. */
10623 bool
10624 mips16e_save_restore_pattern_p (rtx pattern, HOST_WIDE_INT adjust,
10625 struct mips16e_save_restore_info *info)
10627 unsigned int i, nargs, mask, extra;
10628 HOST_WIDE_INT top_offset, save_offset, offset;
10629 rtx set, reg, mem, base;
10630 int n;
10632 if (!GENERATE_MIPS16E_SAVE_RESTORE)
10633 return false;
10635 /* Stack offsets in the PARALLEL are relative to the old stack pointer. */
10636 top_offset = adjust > 0 ? adjust : 0;
10638 /* Interpret all other members of the PARALLEL. */
10639 save_offset = top_offset - UNITS_PER_WORD;
10640 mask = 0;
10641 nargs = 0;
10642 i = 0;
10643 for (n = 1; n < XVECLEN (pattern, 0); n++)
10645 /* Check that we have a SET. */
10646 set = XVECEXP (pattern, 0, n);
10647 if (GET_CODE (set) != SET)
10648 return false;
10650 /* Check that the SET is a load (if restoring) or a store
10651 (if saving). */
10652 mem = adjust > 0 ? SET_SRC (set) : SET_DEST (set);
10653 if (!MEM_P (mem))
10654 return false;
10656 /* Check that the address is the sum of the stack pointer and a
10657 possibly-zero constant offset. */
10658 mips_split_plus (XEXP (mem, 0), &base, &offset);
10659 if (base != stack_pointer_rtx)
10660 return false;
10662 /* Check that SET's other operand is a register. */
10663 reg = adjust > 0 ? SET_DEST (set) : SET_SRC (set);
10664 if (!REG_P (reg))
10665 return false;
10667 /* Check for argument saves. */
10668 if (offset == top_offset + nargs * UNITS_PER_WORD
10669 && REGNO (reg) == GP_ARG_FIRST + nargs)
10670 nargs++;
10671 else if (offset == save_offset)
10673 while (mips16e_save_restore_regs[i++] != REGNO (reg))
10674 if (i == ARRAY_SIZE (mips16e_save_restore_regs))
10675 return false;
10677 mask |= 1 << REGNO (reg);
10678 save_offset -= UNITS_PER_WORD;
10680 else
10681 return false;
10684 /* Check that the restrictions on register ranges are met. */
10685 extra = 0;
10686 mips16e_mask_registers (&mask, mips16e_s2_s8_regs,
10687 ARRAY_SIZE (mips16e_s2_s8_regs), &extra);
10688 mips16e_mask_registers (&mask, mips16e_a0_a3_regs,
10689 ARRAY_SIZE (mips16e_a0_a3_regs), &extra);
10690 if (extra != 0)
10691 return false;
10693 /* Make sure that the topmost argument register is not saved twice.
10694 The checks above ensure that the same is then true for the other
10695 argument registers. */
10696 if (nargs > 0 && BITSET_P (mask, GP_ARG_FIRST + nargs - 1))
10697 return false;
10699 /* Pass back information, if requested. */
10700 if (info)
10702 info->nargs = nargs;
10703 info->mask = mask;
10704 info->size = (adjust > 0 ? adjust : -adjust);
10707 return true;
10710 /* Add a MIPS16e SAVE or RESTORE register-range argument to string S
10711 for the register range [MIN_REG, MAX_REG]. Return a pointer to
10712 the null terminator. */
10714 static char *
10715 mips16e_add_register_range (char *s, unsigned int min_reg,
10716 unsigned int max_reg)
10718 if (min_reg != max_reg)
10719 s += sprintf (s, ",%s-%s", reg_names[min_reg], reg_names[max_reg]);
10720 else
10721 s += sprintf (s, ",%s", reg_names[min_reg]);
10722 return s;
10725 /* Return the assembly instruction for a MIPS16e SAVE or RESTORE instruction.
10726 PATTERN and ADJUST are as for mips16e_save_restore_pattern_p. */
10728 const char *
10729 mips16e_output_save_restore (rtx pattern, HOST_WIDE_INT adjust)
10731 static char buffer[300];
10733 struct mips16e_save_restore_info info;
10734 unsigned int i, end;
10735 char *s;
10737 /* Parse the pattern. */
10738 if (!mips16e_save_restore_pattern_p (pattern, adjust, &info))
10739 gcc_unreachable ();
10741 /* Add the mnemonic. */
10742 s = strcpy (buffer, adjust > 0 ? "restore\t" : "save\t");
10743 s += strlen (s);
10745 /* Save the arguments. */
10746 if (info.nargs > 1)
10747 s += sprintf (s, "%s-%s,", reg_names[GP_ARG_FIRST],
10748 reg_names[GP_ARG_FIRST + info.nargs - 1]);
10749 else if (info.nargs == 1)
10750 s += sprintf (s, "%s,", reg_names[GP_ARG_FIRST]);
10752 /* Emit the amount of stack space to allocate or deallocate. */
10753 s += sprintf (s, "%d", (int) info.size);
10755 /* Save or restore $16. */
10756 if (BITSET_P (info.mask, 16))
10757 s += sprintf (s, ",%s", reg_names[GP_REG_FIRST + 16]);
10759 /* Save or restore $17. */
10760 if (BITSET_P (info.mask, 17))
10761 s += sprintf (s, ",%s", reg_names[GP_REG_FIRST + 17]);
10763 /* Save or restore registers in the range $s2...$s8, which
10764 mips16e_s2_s8_regs lists in decreasing order. Note that this
10765 is a software register range; the hardware registers are not
10766 numbered consecutively. */
10767 end = ARRAY_SIZE (mips16e_s2_s8_regs);
10768 i = mips16e_find_first_register (info.mask, mips16e_s2_s8_regs, end);
10769 if (i < end)
10770 s = mips16e_add_register_range (s, mips16e_s2_s8_regs[end - 1],
10771 mips16e_s2_s8_regs[i]);
10773 /* Save or restore registers in the range $a0...$a3. */
10774 end = ARRAY_SIZE (mips16e_a0_a3_regs);
10775 i = mips16e_find_first_register (info.mask, mips16e_a0_a3_regs, end);
10776 if (i < end)
10777 s = mips16e_add_register_range (s, mips16e_a0_a3_regs[i],
10778 mips16e_a0_a3_regs[end - 1]);
10780 /* Save or restore $31. */
10781 if (BITSET_P (info.mask, RETURN_ADDR_REGNUM))
10782 s += sprintf (s, ",%s", reg_names[RETURN_ADDR_REGNUM]);
10784 return buffer;
10787 /* Return true if the current function returns its value in a floating-point
10788 register in MIPS16 mode. */
10790 static bool
10791 mips16_cfun_returns_in_fpr_p (void)
10793 tree return_type = DECL_RESULT (current_function_decl);
10794 return (TARGET_MIPS16
10795 && TARGET_HARD_FLOAT_ABI
10796 && !aggregate_value_p (return_type, current_function_decl)
10797 && mips_return_mode_in_fpr_p (DECL_MODE (return_type)));
10800 /* Return true if predicate PRED is true for at least one instruction.
10801 Cache the result in *CACHE, and assume that the result is true
10802 if *CACHE is already true. */
10804 static bool
10805 mips_find_gp_ref (bool *cache, bool (*pred) (rtx_insn *))
10807 rtx_insn *insn, *subinsn;
10809 if (!*cache)
10811 push_topmost_sequence ();
10812 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
10813 FOR_EACH_SUBINSN (subinsn, insn)
10814 if (USEFUL_INSN_P (subinsn) && pred (subinsn))
10816 *cache = true;
10817 break;
10819 pop_topmost_sequence ();
10821 return *cache;
10824 /* Return true if INSN refers to the global pointer in an "inflexible" way.
10825 See mips_cfun_has_inflexible_gp_ref_p for details. */
10827 static bool
10828 mips_insn_has_inflexible_gp_ref_p (rtx_insn *insn)
10830 /* Uses of pic_offset_table_rtx in CALL_INSN_FUNCTION_USAGE
10831 indicate that the target could be a traditional MIPS
10832 lazily-binding stub. */
10833 return find_reg_fusage (insn, USE, pic_offset_table_rtx);
10836 /* Return true if the current function refers to the global pointer
10837 in a way that forces $28 to be valid. This means that we can't
10838 change the choice of global pointer, even for NewABI code.
10840 One example of this (and one which needs several checks) is that
10841 $28 must be valid when calling traditional MIPS lazy-binding stubs.
10842 (This restriction does not apply to PLTs.) */
10844 static bool
10845 mips_cfun_has_inflexible_gp_ref_p (void)
10847 /* If the function has a nonlocal goto, $28 must hold the correct
10848 global pointer for the target function. That is, the target
10849 of the goto implicitly uses $28. */
10850 if (crtl->has_nonlocal_goto)
10851 return true;
10853 if (TARGET_ABICALLS_PIC2)
10855 /* Symbolic accesses implicitly use the global pointer unless
10856 -mexplicit-relocs is in effect. JAL macros to symbolic addresses
10857 might go to traditional MIPS lazy-binding stubs. */
10858 if (!TARGET_EXPLICIT_RELOCS)
10859 return true;
10861 /* FUNCTION_PROFILER includes a JAL to _mcount, which again
10862 can be lazily-bound. */
10863 if (crtl->profile)
10864 return true;
10866 /* MIPS16 functions that return in FPRs need to call an
10867 external libgcc routine. This call is only made explict
10868 during mips_expand_epilogue, and it too might be lazily bound. */
10869 if (mips16_cfun_returns_in_fpr_p ())
10870 return true;
10873 return mips_find_gp_ref (&cfun->machine->has_inflexible_gp_insn_p,
10874 mips_insn_has_inflexible_gp_ref_p);
10877 /* Return true if INSN refers to the global pointer in a "flexible" way.
10878 See mips_cfun_has_flexible_gp_ref_p for details. */
10880 static bool
10881 mips_insn_has_flexible_gp_ref_p (rtx_insn *insn)
10883 return (get_attr_got (insn) != GOT_UNSET
10884 || mips_small_data_pattern_p (PATTERN (insn))
10885 || reg_overlap_mentioned_p (pic_offset_table_rtx, PATTERN (insn)));
10888 /* Return true if the current function references the global pointer,
10889 but if those references do not inherently require the global pointer
10890 to be $28. Assume !mips_cfun_has_inflexible_gp_ref_p (). */
10892 static bool
10893 mips_cfun_has_flexible_gp_ref_p (void)
10895 /* Reload can sometimes introduce constant pool references
10896 into a function that otherwise didn't need them. For example,
10897 suppose we have an instruction like:
10899 (set (reg:DF R1) (float:DF (reg:SI R2)))
10901 If R2 turns out to be a constant such as 1, the instruction may
10902 have a REG_EQUAL note saying that R1 == 1.0. Reload then has
10903 the option of using this constant if R2 doesn't get allocated
10904 to a register.
10906 In cases like these, reload will have added the constant to the
10907 pool but no instruction will yet refer to it. */
10908 if (TARGET_ABICALLS_PIC2 && !reload_completed && crtl->uses_const_pool)
10909 return true;
10911 return mips_find_gp_ref (&cfun->machine->has_flexible_gp_insn_p,
10912 mips_insn_has_flexible_gp_ref_p);
10915 /* Return the register that should be used as the global pointer
10916 within this function. Return INVALID_REGNUM if the function
10917 doesn't need a global pointer. */
10919 static unsigned int
10920 mips_global_pointer (void)
10922 unsigned int regno;
10924 /* $gp is always available unless we're using a GOT. */
10925 if (!TARGET_USE_GOT)
10926 return GLOBAL_POINTER_REGNUM;
10928 /* If there are inflexible references to $gp, we must use the
10929 standard register. */
10930 if (mips_cfun_has_inflexible_gp_ref_p ())
10931 return GLOBAL_POINTER_REGNUM;
10933 /* If there are no current references to $gp, then the only uses
10934 we can introduce later are those involved in long branches. */
10935 if (TARGET_ABSOLUTE_JUMPS && !mips_cfun_has_flexible_gp_ref_p ())
10936 return INVALID_REGNUM;
10938 /* If the global pointer is call-saved, try to use a call-clobbered
10939 alternative. */
10940 if (TARGET_CALL_SAVED_GP && crtl->is_leaf)
10941 for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
10942 if (!df_regs_ever_live_p (regno)
10943 && call_used_regs[regno]
10944 && !fixed_regs[regno]
10945 && regno != PIC_FUNCTION_ADDR_REGNUM)
10946 return regno;
10948 return GLOBAL_POINTER_REGNUM;
10951 /* Return true if the current function's prologue must load the global
10952 pointer value into pic_offset_table_rtx and store the same value in
10953 the function's cprestore slot (if any).
10955 One problem we have to deal with is that, when emitting GOT-based
10956 position independent code, long-branch sequences will need to load
10957 the address of the branch target from the GOT. We don't know until
10958 the very end of compilation whether (and where) the function needs
10959 long branches, so we must ensure that _any_ branch can access the
10960 global pointer in some form. However, we do not want to pessimize
10961 the usual case in which all branches are short.
10963 We handle this as follows:
10965 (1) During reload, we set cfun->machine->global_pointer to
10966 INVALID_REGNUM if we _know_ that the current function
10967 doesn't need a global pointer. This is only valid if
10968 long branches don't need the GOT.
10970 Otherwise, we assume that we might need a global pointer
10971 and pick an appropriate register.
10973 (2) If cfun->machine->global_pointer != INVALID_REGNUM,
10974 we ensure that the global pointer is available at every
10975 block boundary bar entry and exit. We do this in one of two ways:
10977 - If the function has a cprestore slot, we ensure that this
10978 slot is valid at every branch. However, as explained in
10979 point (6) below, there is no guarantee that pic_offset_table_rtx
10980 itself is valid if new uses of the global pointer are introduced
10981 after the first post-epilogue split.
10983 We guarantee that the cprestore slot is valid by loading it
10984 into a fake register, CPRESTORE_SLOT_REGNUM. We then make
10985 this register live at every block boundary bar function entry
10986 and exit. It is then invalid to move the load (and thus the
10987 preceding store) across a block boundary.
10989 - If the function has no cprestore slot, we guarantee that
10990 pic_offset_table_rtx itself is valid at every branch.
10992 See mips_eh_uses for the handling of the register liveness.
10994 (3) During prologue and epilogue generation, we emit "ghost"
10995 placeholder instructions to manipulate the global pointer.
10997 (4) During prologue generation, we set cfun->machine->must_initialize_gp_p
10998 and cfun->machine->must_restore_gp_when_clobbered_p if we already know
10999 that the function needs a global pointer. (There is no need to set
11000 them earlier than this, and doing it as late as possible leads to
11001 fewer false positives.)
11003 (5) If cfun->machine->must_initialize_gp_p is true during a
11004 split_insns pass, we split the ghost instructions into real
11005 instructions. These split instructions can then be optimized in
11006 the usual way. Otherwise, we keep the ghost instructions intact,
11007 and optimize for the case where they aren't needed. We still
11008 have the option of splitting them later, if we need to introduce
11009 new uses of the global pointer.
11011 For example, the scheduler ignores a ghost instruction that
11012 stores $28 to the stack, but it handles the split form of
11013 the ghost instruction as an ordinary store.
11015 (6) [OldABI only.] If cfun->machine->must_restore_gp_when_clobbered_p
11016 is true during the first post-epilogue split_insns pass, we split
11017 calls and restore_gp patterns into instructions that explicitly
11018 load pic_offset_table_rtx from the cprestore slot. Otherwise,
11019 we split these patterns into instructions that _don't_ load from
11020 the cprestore slot.
11022 If cfun->machine->must_restore_gp_when_clobbered_p is true at the
11023 time of the split, then any instructions that exist at that time
11024 can make free use of pic_offset_table_rtx. However, if we want
11025 to introduce new uses of the global pointer after the split,
11026 we must explicitly load the value from the cprestore slot, since
11027 pic_offset_table_rtx itself might not be valid at a given point
11028 in the function.
11030 The idea is that we want to be able to delete redundant
11031 loads from the cprestore slot in the usual case where no
11032 long branches are needed.
11034 (7) If cfun->machine->must_initialize_gp_p is still false at the end
11035 of md_reorg, we decide whether the global pointer is needed for
11036 long branches. If so, we set cfun->machine->must_initialize_gp_p
11037 to true and split the ghost instructions into real instructions
11038 at that stage.
11040 Note that the ghost instructions must have a zero length for three reasons:
11042 - Giving the length of the underlying $gp sequence might cause
11043 us to use long branches in cases where they aren't really needed.
11045 - They would perturb things like alignment calculations.
11047 - More importantly, the hazard detection in md_reorg relies on
11048 empty instructions having a zero length.
11050 If we find a long branch and split the ghost instructions at the
11051 end of md_reorg, the split could introduce more long branches.
11052 That isn't a problem though, because we still do the split before
11053 the final shorten_branches pass.
11055 This is extremely ugly, but it seems like the best compromise between
11056 correctness and efficiency. */
11058 bool
11059 mips_must_initialize_gp_p (void)
11061 return cfun->machine->must_initialize_gp_p;
11064 /* Return true if REGNO is a register that is ordinarily call-clobbered
11065 but must nevertheless be preserved by an interrupt handler. */
11067 static bool
11068 mips_interrupt_extra_call_saved_reg_p (unsigned int regno)
11070 if ((ISA_HAS_HILO || TARGET_DSP)
11071 && MD_REG_P (regno))
11072 return true;
11074 if (TARGET_DSP && DSP_ACC_REG_P (regno))
11075 return true;
11077 if (GP_REG_P (regno)
11078 && cfun->machine->use_shadow_register_set == SHADOW_SET_NO)
11080 /* $0 is hard-wired. */
11081 if (regno == GP_REG_FIRST)
11082 return false;
11084 /* The interrupt handler can treat kernel registers as
11085 scratch registers. */
11086 if (KERNEL_REG_P (regno))
11087 return false;
11089 /* The function will return the stack pointer to its original value
11090 anyway. */
11091 if (regno == STACK_POINTER_REGNUM)
11092 return false;
11094 /* Otherwise, return true for registers that aren't ordinarily
11095 call-clobbered. */
11096 return call_used_regs[regno];
11099 return false;
11102 /* Return true if the current function should treat register REGNO
11103 as call-saved. */
11105 static bool
11106 mips_cfun_call_saved_reg_p (unsigned int regno)
11108 /* If the user makes an ordinarily-call-saved register global,
11109 that register is no longer call-saved. */
11110 if (global_regs[regno])
11111 return false;
11113 /* Interrupt handlers need to save extra registers. */
11114 if (cfun->machine->interrupt_handler_p
11115 && mips_interrupt_extra_call_saved_reg_p (regno))
11116 return true;
11118 /* call_insns preserve $28 unless they explicitly say otherwise,
11119 so call_used_regs[] treats $28 as call-saved. However,
11120 we want the ABI property rather than the default call_insn
11121 property here. */
11122 return (regno == GLOBAL_POINTER_REGNUM
11123 ? TARGET_CALL_SAVED_GP
11124 : !call_used_regs[regno]);
11127 /* Return true if the function body might clobber register REGNO.
11128 We know that REGNO is call-saved. */
11130 static bool
11131 mips_cfun_might_clobber_call_saved_reg_p (unsigned int regno)
11133 /* Some functions should be treated as clobbering all call-saved
11134 registers. */
11135 if (crtl->saves_all_registers)
11136 return true;
11138 /* DF handles cases where a register is explicitly referenced in
11139 the rtl. Incoming values are passed in call-clobbered registers,
11140 so we can assume that any live call-saved register is set within
11141 the function. */
11142 if (df_regs_ever_live_p (regno))
11143 return true;
11145 /* Check for registers that are clobbered by FUNCTION_PROFILER.
11146 These clobbers are not explicit in the rtl. */
11147 if (crtl->profile && MIPS_SAVE_REG_FOR_PROFILING_P (regno))
11148 return true;
11150 /* If we're using a call-saved global pointer, the function's
11151 prologue will need to set it up. */
11152 if (cfun->machine->global_pointer == regno)
11153 return true;
11155 /* The function's prologue will need to set the frame pointer if
11156 frame_pointer_needed. */
11157 if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
11158 return true;
11160 /* If a MIPS16 function returns a value in FPRs, its epilogue
11161 will need to call an external libgcc routine. This yet-to-be
11162 generated call_insn will clobber $31. */
11163 if (regno == RETURN_ADDR_REGNUM && mips16_cfun_returns_in_fpr_p ())
11164 return true;
11166 /* If REGNO is ordinarily call-clobbered, we must assume that any
11167 called function could modify it. */
11168 if (cfun->machine->interrupt_handler_p
11169 && !crtl->is_leaf
11170 && mips_interrupt_extra_call_saved_reg_p (regno))
11171 return true;
11173 return false;
11176 /* Return true if the current function must save register REGNO. */
11178 static bool
11179 mips_save_reg_p (unsigned int regno)
11181 if (mips_cfun_call_saved_reg_p (regno))
11183 if (mips_cfun_might_clobber_call_saved_reg_p (regno))
11184 return true;
11186 /* Save both registers in an FPR pair if either one is used. This is
11187 needed for the case when MIN_FPRS_PER_FMT == 1, which allows the odd
11188 register to be used without the even register. */
11189 if (FP_REG_P (regno)
11190 && MAX_FPRS_PER_FMT == 2
11191 && mips_cfun_might_clobber_call_saved_reg_p (regno + 1))
11192 return true;
11195 /* We need to save the incoming return address if __builtin_eh_return
11196 is being used to set a different return address. */
11197 if (regno == RETURN_ADDR_REGNUM && crtl->calls_eh_return)
11198 return true;
11200 return false;
11203 /* Populate the current function's mips_frame_info structure.
11205 MIPS stack frames look like:
11207 +-------------------------------+
11209 | incoming stack arguments |
11211 +-------------------------------+
11213 | caller-allocated save area |
11214 A | for register arguments |
11216 +-------------------------------+ <-- incoming stack pointer
11218 | callee-allocated save area |
11219 B | for arguments that are |
11220 | split between registers and |
11221 | the stack |
11223 +-------------------------------+ <-- arg_pointer_rtx
11225 C | callee-allocated save area |
11226 | for register varargs |
11228 +-------------------------------+ <-- frame_pointer_rtx
11229 | | + cop0_sp_offset
11230 | COP0 reg save area | + UNITS_PER_WORD
11232 +-------------------------------+ <-- frame_pointer_rtx + acc_sp_offset
11233 | | + UNITS_PER_WORD
11234 | accumulator save area |
11236 +-------------------------------+ <-- stack_pointer_rtx + fp_sp_offset
11237 | | + UNITS_PER_HWFPVALUE
11238 | FPR save area |
11240 +-------------------------------+ <-- stack_pointer_rtx + gp_sp_offset
11241 | | + UNITS_PER_WORD
11242 | GPR save area |
11244 +-------------------------------+ <-- frame_pointer_rtx with
11245 | | \ -fstack-protector
11246 | local variables | | var_size
11247 | | /
11248 +-------------------------------+
11249 | | \
11250 | $gp save area | | cprestore_size
11251 | | /
11252 P +-------------------------------+ <-- hard_frame_pointer_rtx for
11253 | | \ MIPS16 code
11254 | outgoing stack arguments | |
11255 | | |
11256 +-------------------------------+ | args_size
11257 | | |
11258 | caller-allocated save area | |
11259 | for register arguments | |
11260 | | /
11261 +-------------------------------+ <-- stack_pointer_rtx
11262 frame_pointer_rtx without
11263 -fstack-protector
11264 hard_frame_pointer_rtx for
11265 non-MIPS16 code.
11267 At least two of A, B and C will be empty.
11269 Dynamic stack allocations such as alloca insert data at point P.
11270 They decrease stack_pointer_rtx but leave frame_pointer_rtx and
11271 hard_frame_pointer_rtx unchanged. */
11273 static void
11274 mips_compute_frame_info (void)
11276 struct mips_frame_info *frame;
11277 HOST_WIDE_INT offset, size;
11278 unsigned int regno, i;
11280 /* Skip re-computing the frame info after reload completed. */
11281 if (reload_completed)
11282 return;
11284 /* Set this function's interrupt properties. */
11285 if (mips_interrupt_type_p (TREE_TYPE (current_function_decl)))
11287 if (mips_isa_rev < 2)
11288 error ("the %<interrupt%> attribute requires a MIPS32r2 processor or greater");
11289 else if (TARGET_MIPS16)
11290 error ("interrupt handlers cannot be MIPS16 functions");
11291 else
11293 cfun->machine->interrupt_handler_p = true;
11294 cfun->machine->int_mask =
11295 mips_interrupt_mask (TREE_TYPE (current_function_decl));
11296 cfun->machine->use_shadow_register_set =
11297 mips_use_shadow_register_set (TREE_TYPE (current_function_decl));
11298 cfun->machine->keep_interrupts_masked_p =
11299 mips_keep_interrupts_masked_p (TREE_TYPE (current_function_decl));
11300 cfun->machine->use_debug_exception_return_p =
11301 mips_use_debug_exception_return_p (TREE_TYPE
11302 (current_function_decl));
11306 frame = &cfun->machine->frame;
11307 memset (frame, 0, sizeof (*frame));
11308 size = get_frame_size ();
11310 /* The first two blocks contain the outgoing argument area and the $gp save
11311 slot. This area isn't needed in leaf functions. We can also skip it
11312 if we know that none of the called functions will use this space.
11314 But if the target-independent frame size is nonzero, we have already
11315 committed to allocating these in TARGET_STARTING_FRAME_OFFSET for
11316 !FRAME_GROWS_DOWNWARD. */
11318 if ((size == 0 || FRAME_GROWS_DOWNWARD)
11319 && (crtl->is_leaf || (cfun->machine->optimize_call_stack && !flag_pic)))
11321 /* The MIPS 3.0 linker does not like functions that dynamically
11322 allocate the stack and have 0 for STACK_DYNAMIC_OFFSET, since it
11323 looks like we are trying to create a second frame pointer to the
11324 function, so allocate some stack space to make it happy. */
11325 if (cfun->calls_alloca)
11326 frame->args_size = REG_PARM_STACK_SPACE (cfun->decl);
11327 else
11328 frame->args_size = 0;
11329 frame->cprestore_size = 0;
11331 else
11333 frame->args_size = crtl->outgoing_args_size;
11334 frame->cprestore_size = MIPS_GP_SAVE_AREA_SIZE;
11337 /* MIPS16 code offsets the frame pointer by the size of the outgoing
11338 arguments. This tends to increase the chances of using unextended
11339 instructions for local variables and incoming arguments. */
11340 if (TARGET_MIPS16)
11341 frame->hard_frame_pointer_offset = frame->args_size;
11343 /* PR 69129 / 69012: Beware of a possible race condition. mips_global_pointer
11344 might call mips_cfun_has_inflexible_gp_ref_p which in turn can call
11345 mips_find_gp_ref which will iterate over the current insn sequence.
11346 If any of these insns use the cprestore_save_slot_operand or
11347 cprestore_load_slot_operand predicates in order to be recognised then
11348 they will call mips_cprestore_address_p which calls
11349 mips_get_cprestore_base_and_offset which expects the frame information
11350 to be filled in... In fact mips_get_cprestore_base_and_offset only
11351 needs the args_size and hard_frame_pointer_offset fields to be filled
11352 in, which is why the global_pointer field is initialised here and not
11353 earlier. */
11354 cfun->machine->global_pointer = mips_global_pointer ();
11356 offset = frame->args_size + frame->cprestore_size;
11358 /* Move above the local variables. */
11359 frame->var_size = MIPS_STACK_ALIGN (size);
11360 offset += frame->var_size;
11362 /* Find out which GPRs we need to save. */
11363 for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
11364 if (mips_save_reg_p (regno))
11366 frame->num_gp++;
11367 frame->mask |= 1 << (regno - GP_REG_FIRST);
11370 /* If this function calls eh_return, we must also save and restore the
11371 EH data registers. */
11372 if (crtl->calls_eh_return)
11373 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; i++)
11375 frame->num_gp++;
11376 frame->mask |= 1 << (EH_RETURN_DATA_REGNO (i) - GP_REG_FIRST);
11379 /* The MIPS16e SAVE and RESTORE instructions have two ranges of registers:
11380 $a3-$a0 and $s2-$s8. If we save one register in the range, we must
11381 save all later registers too. */
11382 if (GENERATE_MIPS16E_SAVE_RESTORE)
11384 mips16e_mask_registers (&frame->mask, mips16e_s2_s8_regs,
11385 ARRAY_SIZE (mips16e_s2_s8_regs), &frame->num_gp);
11386 mips16e_mask_registers (&frame->mask, mips16e_a0_a3_regs,
11387 ARRAY_SIZE (mips16e_a0_a3_regs), &frame->num_gp);
11390 /* Move above the GPR save area. */
11391 if (frame->num_gp > 0)
11393 offset += MIPS_STACK_ALIGN (frame->num_gp * UNITS_PER_WORD);
11394 frame->gp_sp_offset = offset - UNITS_PER_WORD;
11397 /* Find out which FPRs we need to save. This loop must iterate over
11398 the same space as its companion in mips_for_each_saved_gpr_and_fpr. */
11399 if (TARGET_HARD_FLOAT)
11400 for (regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno += MAX_FPRS_PER_FMT)
11401 if (mips_save_reg_p (regno))
11403 frame->num_fp += MAX_FPRS_PER_FMT;
11404 frame->fmask |= ~(~0U << MAX_FPRS_PER_FMT) << (regno - FP_REG_FIRST);
11407 /* Move above the FPR save area. */
11408 if (frame->num_fp > 0)
11410 offset += MIPS_STACK_ALIGN (frame->num_fp * UNITS_PER_FPREG);
11411 frame->fp_sp_offset = offset - UNITS_PER_HWFPVALUE;
11414 /* Add in space for the interrupt context information. */
11415 if (cfun->machine->interrupt_handler_p)
11417 /* Check HI/LO. */
11418 if (mips_save_reg_p (LO_REGNUM) || mips_save_reg_p (HI_REGNUM))
11420 frame->num_acc++;
11421 frame->acc_mask |= (1 << 0);
11424 /* Check accumulators 1, 2, 3. */
11425 for (i = DSP_ACC_REG_FIRST; i <= DSP_ACC_REG_LAST; i += 2)
11426 if (mips_save_reg_p (i) || mips_save_reg_p (i + 1))
11428 frame->num_acc++;
11429 frame->acc_mask |= 1 << (((i - DSP_ACC_REG_FIRST) / 2) + 1);
11432 /* All interrupt context functions need space to preserve STATUS. */
11433 frame->num_cop0_regs++;
11435 /* We need to save EPC regardless of whether interrupts remain masked
11436 as exceptions will corrupt EPC. */
11437 frame->num_cop0_regs++;
11440 /* Move above the accumulator save area. */
11441 if (frame->num_acc > 0)
11443 /* Each accumulator needs 2 words. */
11444 offset += frame->num_acc * 2 * UNITS_PER_WORD;
11445 frame->acc_sp_offset = offset - UNITS_PER_WORD;
11448 /* Move above the COP0 register save area. */
11449 if (frame->num_cop0_regs > 0)
11451 offset += frame->num_cop0_regs * UNITS_PER_WORD;
11452 frame->cop0_sp_offset = offset - UNITS_PER_WORD;
11455 /* Determine if we can save the callee-saved registers in the frame
11456 header. Restrict this to functions where there is no other reason
11457 to allocate stack space so that we can eliminate the instructions
11458 that modify the stack pointer. */
11460 if (TARGET_OLDABI
11461 && optimize > 0
11462 && flag_frame_header_optimization
11463 && !MAIN_NAME_P (DECL_NAME (current_function_decl))
11464 && cfun->machine->varargs_size == 0
11465 && crtl->args.pretend_args_size == 0
11466 && frame->var_size == 0
11467 && frame->num_acc == 0
11468 && frame->num_cop0_regs == 0
11469 && frame->num_fp == 0
11470 && frame->num_gp > 0
11471 && frame->num_gp <= MAX_ARGS_IN_REGISTERS
11472 && !GENERATE_MIPS16E_SAVE_RESTORE
11473 && !cfun->machine->interrupt_handler_p
11474 && cfun->machine->does_not_use_frame_header
11475 && cfun->machine->optimize_call_stack
11476 && !cfun->machine->callers_may_not_allocate_frame
11477 && !mips_cfun_has_cprestore_slot_p ())
11479 offset = 0;
11480 frame->gp_sp_offset = REG_PARM_STACK_SPACE(cfun) - UNITS_PER_WORD;
11481 cfun->machine->use_frame_header_for_callee_saved_regs = true;
11484 /* Move above the callee-allocated varargs save area. */
11485 offset += MIPS_STACK_ALIGN (cfun->machine->varargs_size);
11486 frame->arg_pointer_offset = offset;
11488 /* Move above the callee-allocated area for pretend stack arguments. */
11489 offset += crtl->args.pretend_args_size;
11490 frame->total_size = offset;
11492 /* Work out the offsets of the save areas from the top of the frame. */
11493 if (frame->gp_sp_offset > 0)
11494 frame->gp_save_offset = frame->gp_sp_offset - offset;
11495 if (frame->fp_sp_offset > 0)
11496 frame->fp_save_offset = frame->fp_sp_offset - offset;
11497 if (frame->acc_sp_offset > 0)
11498 frame->acc_save_offset = frame->acc_sp_offset - offset;
11499 if (frame->num_cop0_regs > 0)
11500 frame->cop0_save_offset = frame->cop0_sp_offset - offset;
11503 /* Return the style of GP load sequence that is being used for the
11504 current function. */
11506 enum mips_loadgp_style
11507 mips_current_loadgp_style (void)
11509 if (!TARGET_USE_GOT || cfun->machine->global_pointer == INVALID_REGNUM)
11510 return LOADGP_NONE;
11512 if (TARGET_RTP_PIC)
11513 return LOADGP_RTP;
11515 if (TARGET_ABSOLUTE_ABICALLS)
11516 return LOADGP_ABSOLUTE;
11518 return TARGET_NEWABI ? LOADGP_NEWABI : LOADGP_OLDABI;
11521 /* Implement TARGET_FRAME_POINTER_REQUIRED. */
11523 static bool
11524 mips_frame_pointer_required (void)
11526 /* If the function contains dynamic stack allocations, we need to
11527 use the frame pointer to access the static parts of the frame. */
11528 if (cfun->calls_alloca)
11529 return true;
11531 /* In MIPS16 mode, we need a frame pointer for a large frame; otherwise,
11532 reload may be unable to compute the address of a local variable,
11533 since there is no way to add a large constant to the stack pointer
11534 without using a second temporary register. */
11535 if (TARGET_MIPS16)
11537 mips_compute_frame_info ();
11538 if (!SMALL_OPERAND (cfun->machine->frame.total_size))
11539 return true;
11542 return false;
11545 /* Make sure that we're not trying to eliminate to the wrong hard frame
11546 pointer. */
11548 static bool
11549 mips_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
11551 return (to == HARD_FRAME_POINTER_REGNUM || to == STACK_POINTER_REGNUM);
11554 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame pointer
11555 or argument pointer. TO is either the stack pointer or hard frame
11556 pointer. */
11558 HOST_WIDE_INT
11559 mips_initial_elimination_offset (int from, int to)
11561 HOST_WIDE_INT offset;
11563 mips_compute_frame_info ();
11565 /* Set OFFSET to the offset from the end-of-prologue stack pointer. */
11566 switch (from)
11568 case FRAME_POINTER_REGNUM:
11569 if (FRAME_GROWS_DOWNWARD)
11570 offset = (cfun->machine->frame.args_size
11571 + cfun->machine->frame.cprestore_size
11572 + cfun->machine->frame.var_size);
11573 else
11574 offset = 0;
11575 break;
11577 case ARG_POINTER_REGNUM:
11578 offset = cfun->machine->frame.arg_pointer_offset;
11579 break;
11581 default:
11582 gcc_unreachable ();
11585 if (to == HARD_FRAME_POINTER_REGNUM)
11586 offset -= cfun->machine->frame.hard_frame_pointer_offset;
11588 return offset;
11591 /* Implement TARGET_EXTRA_LIVE_ON_ENTRY. */
11593 static void
11594 mips_extra_live_on_entry (bitmap regs)
11596 if (TARGET_USE_GOT)
11598 /* PIC_FUNCTION_ADDR_REGNUM is live if we need it to set up
11599 the global pointer. */
11600 if (!TARGET_ABSOLUTE_ABICALLS)
11601 bitmap_set_bit (regs, PIC_FUNCTION_ADDR_REGNUM);
11603 /* The prologue may set MIPS16_PIC_TEMP_REGNUM to the value of
11604 the global pointer. */
11605 if (TARGET_MIPS16)
11606 bitmap_set_bit (regs, MIPS16_PIC_TEMP_REGNUM);
11608 /* See the comment above load_call<mode> for details. */
11609 bitmap_set_bit (regs, GOT_VERSION_REGNUM);
11613 /* Implement RETURN_ADDR_RTX. We do not support moving back to a
11614 previous frame. */
11617 mips_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
11619 if (count != 0)
11620 return const0_rtx;
11622 return get_hard_reg_initial_val (Pmode, RETURN_ADDR_REGNUM);
11625 /* Emit code to change the current function's return address to
11626 ADDRESS. SCRATCH is available as a scratch register, if needed.
11627 ADDRESS and SCRATCH are both word-mode GPRs. */
11629 void
11630 mips_set_return_address (rtx address, rtx scratch)
11632 rtx slot_address;
11634 gcc_assert (BITSET_P (cfun->machine->frame.mask, RETURN_ADDR_REGNUM));
11635 slot_address = mips_add_offset (scratch, stack_pointer_rtx,
11636 cfun->machine->frame.gp_sp_offset);
11637 mips_emit_move (gen_frame_mem (GET_MODE (address), slot_address), address);
11640 /* Return true if the current function has a cprestore slot. */
11642 bool
11643 mips_cfun_has_cprestore_slot_p (void)
11645 return (cfun->machine->global_pointer != INVALID_REGNUM
11646 && cfun->machine->frame.cprestore_size > 0);
11649 /* Fill *BASE and *OFFSET such that *BASE + *OFFSET refers to the
11650 cprestore slot. LOAD_P is true if the caller wants to load from
11651 the cprestore slot; it is false if the caller wants to store to
11652 the slot. */
11654 static void
11655 mips_get_cprestore_base_and_offset (rtx *base, HOST_WIDE_INT *offset,
11656 bool load_p)
11658 const struct mips_frame_info *frame;
11660 frame = &cfun->machine->frame;
11661 /* .cprestore always uses the stack pointer instead of the frame pointer.
11662 We have a free choice for direct stores for non-MIPS16 functions,
11663 and for MIPS16 functions whose cprestore slot is in range of the
11664 stack pointer. Using the stack pointer would sometimes give more
11665 (early) scheduling freedom, but using the frame pointer would
11666 sometimes give more (late) scheduling freedom. It's hard to
11667 predict which applies to a given function, so let's keep things
11668 simple.
11670 Loads must always use the frame pointer in functions that call
11671 alloca, and there's little benefit to using the stack pointer
11672 otherwise. */
11673 if (frame_pointer_needed && !(TARGET_CPRESTORE_DIRECTIVE && !load_p))
11675 *base = hard_frame_pointer_rtx;
11676 *offset = frame->args_size - frame->hard_frame_pointer_offset;
11678 else
11680 *base = stack_pointer_rtx;
11681 *offset = frame->args_size;
11685 /* Return true if X is the load or store address of the cprestore slot;
11686 LOAD_P says which. */
11688 bool
11689 mips_cprestore_address_p (rtx x, bool load_p)
11691 rtx given_base, required_base;
11692 HOST_WIDE_INT given_offset, required_offset;
11694 mips_split_plus (x, &given_base, &given_offset);
11695 mips_get_cprestore_base_and_offset (&required_base, &required_offset, load_p);
11696 return given_base == required_base && given_offset == required_offset;
11699 /* Return a MEM rtx for the cprestore slot. LOAD_P is true if we are
11700 going to load from it, false if we are going to store to it.
11701 Use TEMP as a temporary register if need be. */
11703 static rtx
11704 mips_cprestore_slot (rtx temp, bool load_p)
11706 rtx base;
11707 HOST_WIDE_INT offset;
11709 mips_get_cprestore_base_and_offset (&base, &offset, load_p);
11710 return gen_frame_mem (Pmode, mips_add_offset (temp, base, offset));
11713 /* Emit instructions to save global pointer value GP into cprestore
11714 slot MEM. OFFSET is the offset that MEM applies to the base register.
11716 MEM may not be a legitimate address. If it isn't, TEMP is a
11717 temporary register that can be used, otherwise it is a SCRATCH. */
11719 void
11720 mips_save_gp_to_cprestore_slot (rtx mem, rtx offset, rtx gp, rtx temp)
11722 if (TARGET_CPRESTORE_DIRECTIVE)
11724 gcc_assert (gp == pic_offset_table_rtx);
11725 emit_insn (PMODE_INSN (gen_cprestore, (mem, offset)));
11727 else
11728 mips_emit_move (mips_cprestore_slot (temp, false), gp);
11731 /* Restore $gp from its save slot, using TEMP as a temporary base register
11732 if need be. This function is for o32 and o64 abicalls only.
11734 See mips_must_initialize_gp_p for details about how we manage the
11735 global pointer. */
11737 void
11738 mips_restore_gp_from_cprestore_slot (rtx temp)
11740 gcc_assert (TARGET_ABICALLS && TARGET_OLDABI && epilogue_completed);
11742 if (!cfun->machine->must_restore_gp_when_clobbered_p)
11744 emit_note (NOTE_INSN_DELETED);
11745 return;
11748 if (TARGET_MIPS16)
11750 mips_emit_move (temp, mips_cprestore_slot (temp, true));
11751 mips_emit_move (pic_offset_table_rtx, temp);
11753 else
11754 mips_emit_move (pic_offset_table_rtx, mips_cprestore_slot (temp, true));
11755 if (!TARGET_EXPLICIT_RELOCS)
11756 emit_insn (gen_blockage ());
11759 /* A function to save or store a register. The first argument is the
11760 register and the second is the stack slot. */
11761 typedef void (*mips_save_restore_fn) (rtx, rtx);
11763 /* Use FN to save or restore register REGNO. MODE is the register's
11764 mode and OFFSET is the offset of its save slot from the current
11765 stack pointer. */
11767 static void
11768 mips_save_restore_reg (machine_mode mode, int regno,
11769 HOST_WIDE_INT offset, mips_save_restore_fn fn)
11771 rtx mem;
11773 mem = gen_frame_mem (mode, plus_constant (Pmode, stack_pointer_rtx,
11774 offset));
11775 fn (gen_rtx_REG (mode, regno), mem);
11778 /* Call FN for each accumulator that is saved by the current function.
11779 SP_OFFSET is the offset of the current stack pointer from the start
11780 of the frame. */
11782 static void
11783 mips_for_each_saved_acc (HOST_WIDE_INT sp_offset, mips_save_restore_fn fn)
11785 HOST_WIDE_INT offset;
11786 int regno;
11788 offset = cfun->machine->frame.acc_sp_offset - sp_offset;
11789 if (BITSET_P (cfun->machine->frame.acc_mask, 0))
11791 mips_save_restore_reg (word_mode, LO_REGNUM, offset, fn);
11792 offset -= UNITS_PER_WORD;
11793 mips_save_restore_reg (word_mode, HI_REGNUM, offset, fn);
11794 offset -= UNITS_PER_WORD;
11797 for (regno = DSP_ACC_REG_FIRST; regno <= DSP_ACC_REG_LAST; regno++)
11798 if (BITSET_P (cfun->machine->frame.acc_mask,
11799 ((regno - DSP_ACC_REG_FIRST) / 2) + 1))
11801 mips_save_restore_reg (word_mode, regno, offset, fn);
11802 offset -= UNITS_PER_WORD;
11806 /* Save register REG to MEM. Make the instruction frame-related. */
11808 static void
11809 mips_save_reg (rtx reg, rtx mem)
11811 if (GET_MODE (reg) == DFmode
11812 && (!TARGET_FLOAT64
11813 || mips_abi == ABI_32))
11815 rtx x1, x2;
11817 mips_emit_move_or_split (mem, reg, SPLIT_IF_NECESSARY);
11819 x1 = mips_frame_set (mips_subword (mem, false),
11820 mips_subword (reg, false));
11821 x2 = mips_frame_set (mips_subword (mem, true),
11822 mips_subword (reg, true));
11823 mips_set_frame_expr (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, x1, x2)));
11825 else
11826 mips_emit_save_slot_move (mem, reg, MIPS_PROLOGUE_TEMP (GET_MODE (reg)));
11829 /* Capture the register combinations that are allowed in a SWM or LWM
11830 instruction. The entries are ordered by number of registers set in
11831 the mask. We also ignore the single register encodings because a
11832 normal SW/LW is preferred. */
11834 static const unsigned int umips_swm_mask[17] = {
11835 0xc0ff0000, 0x80ff0000, 0x40ff0000, 0x807f0000,
11836 0x00ff0000, 0x803f0000, 0x007f0000, 0x801f0000,
11837 0x003f0000, 0x800f0000, 0x001f0000, 0x80070000,
11838 0x000f0000, 0x80030000, 0x00070000, 0x80010000,
11839 0x00030000
11842 static const unsigned int umips_swm_encoding[17] = {
11843 25, 24, 9, 23, 8, 22, 7, 21, 6, 20, 5, 19, 4, 18, 3, 17, 2
11846 /* Try to use a microMIPS LWM or SWM instruction to save or restore
11847 as many GPRs in *MASK as possible. *OFFSET is the offset from the
11848 stack pointer of the topmost save slot.
11850 Remove from *MASK all registers that were handled using LWM and SWM.
11851 Update *OFFSET so that it points to the first unused save slot. */
11853 static bool
11854 umips_build_save_restore (mips_save_restore_fn fn,
11855 unsigned *mask, HOST_WIDE_INT *offset)
11857 int nregs;
11858 unsigned int i, j;
11859 rtx pattern, set, reg, mem;
11860 HOST_WIDE_INT this_offset;
11861 rtx this_base;
11863 /* Try matching $16 to $31 (s0 to ra). */
11864 for (i = 0; i < ARRAY_SIZE (umips_swm_mask); i++)
11865 if ((*mask & 0xffff0000) == umips_swm_mask[i])
11866 break;
11868 if (i == ARRAY_SIZE (umips_swm_mask))
11869 return false;
11871 /* Get the offset of the lowest save slot. */
11872 nregs = (umips_swm_encoding[i] & 0xf) + (umips_swm_encoding[i] >> 4);
11873 this_offset = *offset - UNITS_PER_WORD * (nregs - 1);
11875 /* LWM/SWM can only support offsets from -2048 to 2047. */
11876 if (!UMIPS_12BIT_OFFSET_P (this_offset))
11877 return false;
11879 /* Create the final PARALLEL. */
11880 pattern = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nregs));
11881 this_base = stack_pointer_rtx;
11883 /* For registers $16-$23 and $30. */
11884 for (j = 0; j < (umips_swm_encoding[i] & 0xf); j++)
11886 HOST_WIDE_INT offset = this_offset + j * UNITS_PER_WORD;
11887 mem = gen_frame_mem (SImode, plus_constant (Pmode, this_base, offset));
11888 unsigned int regno = (j != 8) ? 16 + j : 30;
11889 *mask &= ~(1 << regno);
11890 reg = gen_rtx_REG (SImode, regno);
11891 if (fn == mips_save_reg)
11892 set = mips_frame_set (mem, reg);
11893 else
11895 set = gen_rtx_SET (reg, mem);
11896 mips_add_cfa_restore (reg);
11898 XVECEXP (pattern, 0, j) = set;
11901 /* For register $31. */
11902 if (umips_swm_encoding[i] >> 4)
11904 HOST_WIDE_INT offset = this_offset + j * UNITS_PER_WORD;
11905 *mask &= ~(1 << 31);
11906 mem = gen_frame_mem (SImode, plus_constant (Pmode, this_base, offset));
11907 reg = gen_rtx_REG (SImode, 31);
11908 if (fn == mips_save_reg)
11909 set = mips_frame_set (mem, reg);
11910 else
11912 set = gen_rtx_SET (reg, mem);
11913 mips_add_cfa_restore (reg);
11915 XVECEXP (pattern, 0, j) = set;
11918 pattern = emit_insn (pattern);
11919 if (fn == mips_save_reg)
11920 RTX_FRAME_RELATED_P (pattern) = 1;
11922 /* Adjust the last offset. */
11923 *offset -= UNITS_PER_WORD * nregs;
11925 return true;
11928 /* Call FN for each register that is saved by the current function.
11929 SP_OFFSET is the offset of the current stack pointer from the start
11930 of the frame. */
11932 static void
11933 mips_for_each_saved_gpr_and_fpr (HOST_WIDE_INT sp_offset,
11934 mips_save_restore_fn fn)
11936 machine_mode fpr_mode;
11937 int regno;
11938 const struct mips_frame_info *frame = &cfun->machine->frame;
11939 HOST_WIDE_INT offset;
11940 unsigned int mask;
11942 /* Save registers starting from high to low. The debuggers prefer at least
11943 the return register be stored at func+4, and also it allows us not to
11944 need a nop in the epilogue if at least one register is reloaded in
11945 addition to return address. */
11946 offset = frame->gp_sp_offset - sp_offset;
11947 mask = frame->mask;
11949 if (TARGET_MICROMIPS)
11950 umips_build_save_restore (fn, &mask, &offset);
11952 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
11953 if (BITSET_P (mask, regno - GP_REG_FIRST))
11955 /* Record the ra offset for use by mips_function_profiler. */
11956 if (regno == RETURN_ADDR_REGNUM)
11957 cfun->machine->frame.ra_fp_offset = offset + sp_offset;
11958 mips_save_restore_reg (word_mode, regno, offset, fn);
11959 offset -= UNITS_PER_WORD;
11962 /* This loop must iterate over the same space as its companion in
11963 mips_compute_frame_info. */
11964 offset = cfun->machine->frame.fp_sp_offset - sp_offset;
11965 fpr_mode = (TARGET_SINGLE_FLOAT ? SFmode : DFmode);
11966 for (regno = FP_REG_LAST - MAX_FPRS_PER_FMT + 1;
11967 regno >= FP_REG_FIRST;
11968 regno -= MAX_FPRS_PER_FMT)
11969 if (BITSET_P (cfun->machine->frame.fmask, regno - FP_REG_FIRST))
11971 if (!TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT
11972 && (fixed_regs[regno] || fixed_regs[regno + 1]))
11974 if (fixed_regs[regno])
11975 mips_save_restore_reg (SFmode, regno + 1, offset, fn);
11976 else
11977 mips_save_restore_reg (SFmode, regno, offset, fn);
11979 else
11980 mips_save_restore_reg (fpr_mode, regno, offset, fn);
11981 offset -= GET_MODE_SIZE (fpr_mode);
11985 /* Return true if a move between register REGNO and its save slot (MEM)
11986 can be done in a single move. LOAD_P is true if we are loading
11987 from the slot, false if we are storing to it. */
11989 static bool
11990 mips_direct_save_slot_move_p (unsigned int regno, rtx mem, bool load_p)
11992 /* There is a specific MIPS16 instruction for saving $31 to the stack. */
11993 if (TARGET_MIPS16 && !load_p && regno == RETURN_ADDR_REGNUM)
11994 return false;
11996 return mips_secondary_reload_class (REGNO_REG_CLASS (regno),
11997 GET_MODE (mem), mem, load_p) == NO_REGS;
12000 /* Emit a move from SRC to DEST, given that one of them is a register
12001 save slot and that the other is a register. TEMP is a temporary
12002 GPR of the same mode that is available if need be. */
12004 void
12005 mips_emit_save_slot_move (rtx dest, rtx src, rtx temp)
12007 unsigned int regno;
12008 rtx mem;
12010 if (REG_P (src))
12012 regno = REGNO (src);
12013 mem = dest;
12015 else
12017 regno = REGNO (dest);
12018 mem = src;
12021 if (regno == cfun->machine->global_pointer && !mips_must_initialize_gp_p ())
12023 /* We don't yet know whether we'll need this instruction or not.
12024 Postpone the decision by emitting a ghost move. This move
12025 is specifically not frame-related; only the split version is. */
12026 if (TARGET_64BIT)
12027 emit_insn (gen_move_gpdi (dest, src));
12028 else
12029 emit_insn (gen_move_gpsi (dest, src));
12030 return;
12033 if (regno == HI_REGNUM)
12035 if (REG_P (dest))
12037 mips_emit_move (temp, src);
12038 if (TARGET_64BIT)
12039 emit_insn (gen_mthidi_ti (gen_rtx_REG (TImode, MD_REG_FIRST),
12040 temp, gen_rtx_REG (DImode, LO_REGNUM)));
12041 else
12042 emit_insn (gen_mthisi_di (gen_rtx_REG (DImode, MD_REG_FIRST),
12043 temp, gen_rtx_REG (SImode, LO_REGNUM)));
12045 else
12047 if (TARGET_64BIT)
12048 emit_insn (gen_mfhidi_ti (temp,
12049 gen_rtx_REG (TImode, MD_REG_FIRST)));
12050 else
12051 emit_insn (gen_mfhisi_di (temp,
12052 gen_rtx_REG (DImode, MD_REG_FIRST)));
12053 mips_emit_move (dest, temp);
12056 else if (mips_direct_save_slot_move_p (regno, mem, mem == src))
12057 mips_emit_move (dest, src);
12058 else
12060 gcc_assert (!reg_overlap_mentioned_p (dest, temp));
12061 mips_emit_move (temp, src);
12062 mips_emit_move (dest, temp);
12064 if (MEM_P (dest))
12065 mips_set_frame_expr (mips_frame_set (dest, src));
12068 /* If we're generating n32 or n64 abicalls, and the current function
12069 does not use $28 as its global pointer, emit a cplocal directive.
12070 Use pic_offset_table_rtx as the argument to the directive. */
12072 static void
12073 mips_output_cplocal (void)
12075 if (!TARGET_EXPLICIT_RELOCS
12076 && mips_must_initialize_gp_p ()
12077 && cfun->machine->global_pointer != GLOBAL_POINTER_REGNUM)
12078 output_asm_insn (".cplocal %+", 0);
12081 /* Implement TARGET_OUTPUT_FUNCTION_PROLOGUE. */
12083 static void
12084 mips_output_function_prologue (FILE *file)
12086 const char *fnname;
12088 /* In MIPS16 mode, we may need to generate a non-MIPS16 stub to handle
12089 floating-point arguments. */
12090 if (TARGET_MIPS16
12091 && TARGET_HARD_FLOAT_ABI
12092 && crtl->args.info.fp_code != 0)
12093 mips16_build_function_stub ();
12095 /* Get the function name the same way that toplev.cc does before calling
12096 assemble_start_function. This is needed so that the name used here
12097 exactly matches the name used in ASM_DECLARE_FUNCTION_NAME. */
12098 fnname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
12099 mips_start_function_definition (fnname, TARGET_MIPS16, current_function_decl);
12101 /* Output MIPS-specific frame information. */
12102 if (!flag_inhibit_size_directive)
12104 const struct mips_frame_info *frame;
12106 frame = &cfun->machine->frame;
12108 /* .frame FRAMEREG, FRAMESIZE, RETREG. */
12109 fprintf (file,
12110 "\t.frame\t%s," HOST_WIDE_INT_PRINT_DEC ",%s\t\t"
12111 "# vars= " HOST_WIDE_INT_PRINT_DEC
12112 ", regs= %d/%d"
12113 ", args= " HOST_WIDE_INT_PRINT_DEC
12114 ", gp= " HOST_WIDE_INT_PRINT_DEC "\n",
12115 reg_names[frame_pointer_needed
12116 ? HARD_FRAME_POINTER_REGNUM
12117 : STACK_POINTER_REGNUM],
12118 (frame_pointer_needed
12119 ? frame->total_size - frame->hard_frame_pointer_offset
12120 : frame->total_size),
12121 reg_names[RETURN_ADDR_REGNUM],
12122 frame->var_size,
12123 frame->num_gp, frame->num_fp,
12124 frame->args_size,
12125 frame->cprestore_size);
12127 /* .mask MASK, OFFSET. */
12128 fprintf (file, "\t.mask\t0x%08x," HOST_WIDE_INT_PRINT_DEC "\n",
12129 frame->mask, frame->gp_save_offset);
12131 /* .fmask MASK, OFFSET. */
12132 fprintf (file, "\t.fmask\t0x%08x," HOST_WIDE_INT_PRINT_DEC "\n",
12133 frame->fmask, frame->fp_save_offset);
12136 /* Handle the initialization of $gp for SVR4 PIC, if applicable.
12137 Also emit the ".set noreorder; .set nomacro" sequence for functions
12138 that need it. */
12139 if (mips_must_initialize_gp_p ()
12140 && mips_current_loadgp_style () == LOADGP_OLDABI)
12142 if (TARGET_MIPS16)
12144 if (ISA_HAS_MIPS16E2)
12146 /* This is a fixed-form sequence. The position of the
12147 first two instructions is important because of the
12148 way _gp_disp is defined. */
12149 output_asm_insn ("lui\t$2,%%hi(_gp_disp)", 0);
12150 output_asm_insn ("addiu\t$3,$pc,%%lo(_gp_disp)", 0);
12151 output_asm_insn ("addu\t$2,$3", 0);
12153 else
12155 /* This is a fixed-form sequence. The position of the
12156 first two instructions is important because of the
12157 way _gp_disp is defined. */
12158 output_asm_insn ("li\t$2,%%hi(_gp_disp)", 0);
12159 output_asm_insn ("addiu\t$3,$pc,%%lo(_gp_disp)", 0);
12160 output_asm_insn ("sll\t$2,16", 0);
12161 output_asm_insn ("addu\t$2,$3", 0);
12164 else
12166 /* .cpload must be in a .set noreorder but not a
12167 .set nomacro block. */
12168 mips_push_asm_switch (&mips_noreorder);
12169 output_asm_insn (".cpload\t%^", 0);
12170 if (!cfun->machine->all_noreorder_p)
12171 mips_pop_asm_switch (&mips_noreorder);
12172 else
12173 mips_push_asm_switch (&mips_nomacro);
12176 else if (cfun->machine->all_noreorder_p)
12178 mips_push_asm_switch (&mips_noreorder);
12179 mips_push_asm_switch (&mips_nomacro);
12182 /* Tell the assembler which register we're using as the global
12183 pointer. This is needed for thunks, since they can use either
12184 explicit relocs or assembler macros. */
12185 mips_output_cplocal ();
12188 /* Implement TARGET_OUTPUT_FUNCTION_EPILOGUE. */
12190 static void
12191 mips_output_function_epilogue (FILE *)
12193 const char *fnname;
12195 /* Reinstate the normal $gp. */
12196 SET_REGNO (pic_offset_table_rtx, GLOBAL_POINTER_REGNUM);
12197 mips_output_cplocal ();
12199 if (cfun->machine->all_noreorder_p)
12201 mips_pop_asm_switch (&mips_nomacro);
12202 mips_pop_asm_switch (&mips_noreorder);
12205 /* Get the function name the same way that toplev.cc does before calling
12206 assemble_start_function. This is needed so that the name used here
12207 exactly matches the name used in ASM_DECLARE_FUNCTION_NAME. */
12208 fnname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
12209 mips_end_function_definition (fnname);
12212 /* Emit an optimisation barrier for accesses to the current frame. */
12214 static void
12215 mips_frame_barrier (void)
12217 emit_clobber (gen_frame_mem (BLKmode, stack_pointer_rtx));
12221 /* The __gnu_local_gp symbol. */
12223 static GTY(()) rtx mips_gnu_local_gp;
12225 /* If we're generating n32 or n64 abicalls, emit instructions
12226 to set up the global pointer. */
12228 static void
12229 mips_emit_loadgp (void)
12231 rtx addr, offset, incoming_address, base, index, pic_reg;
12233 pic_reg = TARGET_MIPS16 ? MIPS16_PIC_TEMP : pic_offset_table_rtx;
12234 switch (mips_current_loadgp_style ())
12236 case LOADGP_ABSOLUTE:
12237 if (mips_gnu_local_gp == NULL)
12239 mips_gnu_local_gp = gen_rtx_SYMBOL_REF (Pmode, "__gnu_local_gp");
12240 SYMBOL_REF_FLAGS (mips_gnu_local_gp) |= SYMBOL_FLAG_LOCAL;
12242 emit_insn (PMODE_INSN (gen_loadgp_absolute,
12243 (pic_reg, mips_gnu_local_gp)));
12244 break;
12246 case LOADGP_OLDABI:
12247 /* Added by mips_output_function_prologue. */
12248 break;
12250 case LOADGP_NEWABI:
12251 addr = XEXP (DECL_RTL (current_function_decl), 0);
12252 offset = mips_unspec_address (addr, SYMBOL_GOTOFF_LOADGP);
12253 incoming_address = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
12254 emit_insn (PMODE_INSN (gen_loadgp_newabi,
12255 (pic_reg, offset, incoming_address)));
12256 break;
12258 case LOADGP_RTP:
12259 base = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (VXWORKS_GOTT_BASE));
12260 index = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (VXWORKS_GOTT_INDEX));
12261 emit_insn (PMODE_INSN (gen_loadgp_rtp, (pic_reg, base, index)));
12262 break;
12264 default:
12265 return;
12268 if (TARGET_MIPS16)
12269 emit_insn (PMODE_INSN (gen_copygp_mips16,
12270 (pic_offset_table_rtx, pic_reg)));
12272 /* Emit a blockage if there are implicit uses of the GP register.
12273 This includes profiled functions, because FUNCTION_PROFILE uses
12274 a jal macro. */
12275 if (!TARGET_EXPLICIT_RELOCS || crtl->profile)
12276 emit_insn (gen_loadgp_blockage ());
12279 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
12281 #if PROBE_INTERVAL > 32768
12282 #error Cannot use indexed addressing mode for stack probing
12283 #endif
12285 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
12286 inclusive. These are offsets from the current stack pointer. */
12288 static void
12289 mips_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size)
12291 if (TARGET_MIPS16)
12292 sorry ("%<-fstack-check=specific%> not implemented for MIPS16");
12294 /* See if we have a constant small number of probes to generate. If so,
12295 that's the easy case. */
12296 if (first + size <= 32768)
12298 HOST_WIDE_INT i;
12300 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
12301 it exceeds SIZE. If only one probe is needed, this will not
12302 generate any code. Then probe at FIRST + SIZE. */
12303 for (i = PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
12304 emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx,
12305 -(first + i)));
12307 emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx,
12308 -(first + size)));
12311 /* Otherwise, do the same as above, but in a loop. Note that we must be
12312 extra careful with variables wrapping around because we might be at
12313 the very top (or the very bottom) of the address space and we have
12314 to be able to handle this case properly; in particular, we use an
12315 equality test for the loop condition. */
12316 else
12318 HOST_WIDE_INT rounded_size;
12319 rtx r3 = MIPS_PROLOGUE_TEMP (Pmode);
12320 rtx r12 = MIPS_PROLOGUE_TEMP2 (Pmode);
12322 /* Sanity check for the addressing mode we're going to use. */
12323 gcc_assert (first <= 32768);
12326 /* Step 1: round SIZE to the previous multiple of the interval. */
12328 rounded_size = ROUND_DOWN (size, PROBE_INTERVAL);
12331 /* Step 2: compute initial and final value of the loop counter. */
12333 /* TEST_ADDR = SP + FIRST. */
12334 emit_insn (gen_rtx_SET (r3, plus_constant (Pmode, stack_pointer_rtx,
12335 -first)));
12337 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
12338 if (rounded_size > 32768)
12340 emit_move_insn (r12, GEN_INT (rounded_size));
12341 emit_insn (gen_rtx_SET (r12, gen_rtx_MINUS (Pmode, r3, r12)));
12343 else
12344 emit_insn (gen_rtx_SET (r12, plus_constant (Pmode, r3,
12345 -rounded_size)));
12348 /* Step 3: the loop
12352 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
12353 probe at TEST_ADDR
12355 while (TEST_ADDR != LAST_ADDR)
12357 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
12358 until it is equal to ROUNDED_SIZE. */
12360 emit_insn (PMODE_INSN (gen_probe_stack_range, (r3, r3, r12)));
12363 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
12364 that SIZE is equal to ROUNDED_SIZE. */
12366 if (size != rounded_size)
12367 emit_stack_probe (plus_constant (Pmode, r12, rounded_size - size));
12370 /* Make sure nothing is scheduled before we are done. */
12371 emit_insn (gen_blockage ());
12374 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
12375 absolute addresses. */
12377 const char *
12378 mips_output_probe_stack_range (rtx reg1, rtx reg2)
12380 static int labelno = 0;
12381 char loop_lab[32], tmp[64];
12382 rtx xops[2];
12384 ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno++);
12386 /* Loop. */
12387 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
12389 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
12390 xops[0] = reg1;
12391 xops[1] = GEN_INT (-PROBE_INTERVAL);
12392 if (TARGET_64BIT && TARGET_LONG64)
12393 output_asm_insn ("daddiu\t%0,%0,%1", xops);
12394 else
12395 output_asm_insn ("addiu\t%0,%0,%1", xops);
12397 /* Probe at TEST_ADDR, test if TEST_ADDR == LAST_ADDR and branch. */
12398 xops[1] = reg2;
12399 strcpy (tmp, "%(%<bne\t%0,%1,");
12400 output_asm_insn (strcat (tmp, &loop_lab[1]), xops);
12401 if (TARGET_64BIT)
12402 output_asm_insn ("sd\t$0,0(%0)%)", xops);
12403 else
12404 output_asm_insn ("sw\t$0,0(%0)%)", xops);
12406 return "";
12409 /* Return true if X contains a kernel register. */
12411 static bool
12412 mips_refers_to_kernel_reg_p (const_rtx x)
12414 subrtx_iterator::array_type array;
12415 FOR_EACH_SUBRTX (iter, array, x, NONCONST)
12416 if (REG_P (*iter) && KERNEL_REG_P (REGNO (*iter)))
12417 return true;
12418 return false;
12421 /* Expand the "prologue" pattern. */
12423 void
12424 mips_expand_prologue (void)
12426 const struct mips_frame_info *frame;
12427 HOST_WIDE_INT size;
12428 unsigned int nargs;
12430 if (cfun->machine->global_pointer != INVALID_REGNUM)
12432 /* Check whether an insn uses pic_offset_table_rtx, either explicitly
12433 or implicitly. If so, we can commit to using a global pointer
12434 straight away, otherwise we need to defer the decision. */
12435 if (mips_cfun_has_inflexible_gp_ref_p ()
12436 || mips_cfun_has_flexible_gp_ref_p ())
12438 cfun->machine->must_initialize_gp_p = true;
12439 cfun->machine->must_restore_gp_when_clobbered_p = true;
12442 SET_REGNO (pic_offset_table_rtx, cfun->machine->global_pointer);
12445 frame = &cfun->machine->frame;
12446 size = frame->total_size;
12448 if (flag_stack_usage_info)
12449 current_function_static_stack_size = size;
12451 if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK
12452 || flag_stack_clash_protection)
12454 if (crtl->is_leaf && !cfun->calls_alloca)
12456 if (size > PROBE_INTERVAL && size > get_stack_check_protect ())
12457 mips_emit_probe_stack_range (get_stack_check_protect (),
12458 size - get_stack_check_protect ());
12460 else if (size > 0)
12461 mips_emit_probe_stack_range (get_stack_check_protect (), size);
12464 /* Save the registers. Allocate up to MIPS_MAX_FIRST_STACK_STEP
12465 bytes beforehand; this is enough to cover the register save area
12466 without going out of range. */
12467 if (((frame->mask | frame->fmask | frame->acc_mask) != 0)
12468 || frame->num_cop0_regs > 0)
12470 HOST_WIDE_INT step1;
12472 step1 = MIN (size, MIPS_MAX_FIRST_STACK_STEP);
12473 if (GENERATE_MIPS16E_SAVE_RESTORE)
12475 HOST_WIDE_INT offset;
12476 unsigned int mask, regno;
12478 /* Try to merge argument stores into the save instruction. */
12479 nargs = mips16e_collect_argument_saves ();
12481 /* Build the save instruction. */
12482 mask = frame->mask;
12483 rtx insn = mips16e_build_save_restore (false, &mask, &offset,
12484 nargs, step1);
12485 RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
12486 mips_frame_barrier ();
12487 size -= step1;
12489 /* Check if we need to save other registers. */
12490 for (regno = GP_REG_FIRST; regno < GP_REG_LAST; regno++)
12491 if (BITSET_P (mask, regno - GP_REG_FIRST))
12493 offset -= UNITS_PER_WORD;
12494 mips_save_restore_reg (word_mode, regno,
12495 offset, mips_save_reg);
12498 else
12500 if (cfun->machine->interrupt_handler_p)
12502 HOST_WIDE_INT offset;
12503 rtx mem;
12505 /* If this interrupt is using a shadow register set, we need to
12506 get the stack pointer from the previous register set. */
12507 if (cfun->machine->use_shadow_register_set == SHADOW_SET_YES)
12508 emit_insn (PMODE_INSN (gen_mips_rdpgpr, (stack_pointer_rtx,
12509 stack_pointer_rtx)));
12511 if (!cfun->machine->keep_interrupts_masked_p)
12513 if (cfun->machine->int_mask == INT_MASK_EIC)
12514 /* Move from COP0 Cause to K0. */
12515 emit_insn (gen_cop0_move (gen_rtx_REG (SImode, K0_REG_NUM),
12516 gen_rtx_REG (SImode, COP0_CAUSE_REG_NUM)));
12518 /* Move from COP0 EPC to K1. */
12519 emit_insn (gen_cop0_move (gen_rtx_REG (SImode, K1_REG_NUM),
12520 gen_rtx_REG (SImode,
12521 COP0_EPC_REG_NUM)));
12523 /* Allocate the first part of the frame. */
12524 rtx insn = gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
12525 GEN_INT (-step1));
12526 RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
12527 mips_frame_barrier ();
12528 size -= step1;
12530 /* Start at the uppermost location for saving. */
12531 offset = frame->cop0_sp_offset - size;
12533 /* Push EPC into its stack slot. */
12534 mem = gen_frame_mem (word_mode,
12535 plus_constant (Pmode, stack_pointer_rtx,
12536 offset));
12537 mips_emit_move (mem, gen_rtx_REG (word_mode, K1_REG_NUM));
12538 offset -= UNITS_PER_WORD;
12540 /* Move from COP0 Status to K1. */
12541 emit_insn (gen_cop0_move (gen_rtx_REG (SImode, K1_REG_NUM),
12542 gen_rtx_REG (SImode,
12543 COP0_STATUS_REG_NUM)));
12545 /* Right justify the RIPL in k0. */
12546 if (!cfun->machine->keep_interrupts_masked_p
12547 && cfun->machine->int_mask == INT_MASK_EIC)
12548 emit_insn (gen_lshrsi3 (gen_rtx_REG (SImode, K0_REG_NUM),
12549 gen_rtx_REG (SImode, K0_REG_NUM),
12550 GEN_INT (CAUSE_IPL)));
12552 /* Push Status into its stack slot. */
12553 mem = gen_frame_mem (word_mode,
12554 plus_constant (Pmode, stack_pointer_rtx,
12555 offset));
12556 mips_emit_move (mem, gen_rtx_REG (word_mode, K1_REG_NUM));
12557 offset -= UNITS_PER_WORD;
12559 /* Insert the RIPL into our copy of SR (k1) as the new IPL. */
12560 if (!cfun->machine->keep_interrupts_masked_p
12561 && cfun->machine->int_mask == INT_MASK_EIC)
12563 emit_insn (gen_insvsi (gen_rtx_REG (SImode, K1_REG_NUM),
12564 TARGET_MCU ? GEN_INT (7) : GEN_INT (6),
12565 GEN_INT (SR_IPL),
12566 gen_rtx_REG (SImode, K0_REG_NUM)));
12567 if (TARGET_MCU)
12569 emit_insn (gen_lshrsi3 (gen_rtx_REG (SImode, K0_REG_NUM),
12570 gen_rtx_REG (SImode, K0_REG_NUM),
12571 GEN_INT (7)));
12572 emit_insn (gen_insvsi (gen_rtx_REG (SImode, K1_REG_NUM),
12573 GEN_INT (1),
12574 GEN_INT (SR_IPL+8),
12575 gen_rtx_REG (SImode, K0_REG_NUM)));
12579 /* Clear all interrupt mask bits up to and including the
12580 handler's interrupt line. */
12581 if (!cfun->machine->keep_interrupts_masked_p
12582 && cfun->machine->int_mask != INT_MASK_EIC)
12583 emit_insn (gen_insvsi (gen_rtx_REG (SImode, K1_REG_NUM),
12584 GEN_INT (cfun->machine->int_mask + 1),
12585 GEN_INT (SR_IM0),
12586 gen_rtx_REG (SImode, GP_REG_FIRST)));
12588 if (!cfun->machine->keep_interrupts_masked_p)
12589 /* Enable interrupts by clearing the KSU ERL and EXL bits.
12590 IE is already the correct value, so we don't have to do
12591 anything explicit. */
12592 emit_insn (gen_insvsi (gen_rtx_REG (SImode, K1_REG_NUM),
12593 GEN_INT (4),
12594 GEN_INT (SR_EXL),
12595 gen_rtx_REG (SImode, GP_REG_FIRST)));
12596 else
12597 /* Disable interrupts by clearing the KSU, ERL, EXL,
12598 and IE bits. */
12599 emit_insn (gen_insvsi (gen_rtx_REG (SImode, K1_REG_NUM),
12600 GEN_INT (5),
12601 GEN_INT (SR_IE),
12602 gen_rtx_REG (SImode, GP_REG_FIRST)));
12604 if (TARGET_HARD_FLOAT)
12605 /* Disable COP1 for hard-float. This will lead to an exception
12606 if floating-point code is executed in an ISR. */
12607 emit_insn (gen_insvsi (gen_rtx_REG (SImode, K1_REG_NUM),
12608 GEN_INT (1),
12609 GEN_INT (SR_COP1),
12610 gen_rtx_REG (SImode, GP_REG_FIRST)));
12612 else
12614 if (step1 != 0)
12616 rtx insn = gen_add3_insn (stack_pointer_rtx,
12617 stack_pointer_rtx,
12618 GEN_INT (-step1));
12619 RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
12620 mips_frame_barrier ();
12621 size -= step1;
12624 mips_for_each_saved_acc (size, mips_save_reg);
12625 mips_for_each_saved_gpr_and_fpr (size, mips_save_reg);
12629 /* Allocate the rest of the frame. */
12630 if (size > 0)
12632 if (SMALL_OPERAND (-size))
12633 RTX_FRAME_RELATED_P (emit_insn (gen_add3_insn (stack_pointer_rtx,
12634 stack_pointer_rtx,
12635 GEN_INT (-size)))) = 1;
12636 else
12638 mips_emit_move (MIPS_PROLOGUE_TEMP (Pmode), GEN_INT (size));
12639 if (TARGET_MIPS16)
12641 /* There are no instructions to add or subtract registers
12642 from the stack pointer, so use the frame pointer as a
12643 temporary. We should always be using a frame pointer
12644 in this case anyway. */
12645 gcc_assert (frame_pointer_needed);
12646 mips_emit_move (hard_frame_pointer_rtx, stack_pointer_rtx);
12647 emit_insn (gen_sub3_insn (hard_frame_pointer_rtx,
12648 hard_frame_pointer_rtx,
12649 MIPS_PROLOGUE_TEMP (Pmode)));
12650 mips_emit_move (stack_pointer_rtx, hard_frame_pointer_rtx);
12652 else
12653 emit_insn (gen_sub3_insn (stack_pointer_rtx,
12654 stack_pointer_rtx,
12655 MIPS_PROLOGUE_TEMP (Pmode)));
12657 /* Describe the combined effect of the previous instructions. */
12658 mips_set_frame_expr
12659 (gen_rtx_SET (stack_pointer_rtx,
12660 plus_constant (Pmode, stack_pointer_rtx, -size)));
12662 mips_frame_barrier ();
12665 /* Set up the frame pointer, if we're using one. */
12666 if (frame_pointer_needed)
12668 HOST_WIDE_INT offset;
12670 offset = frame->hard_frame_pointer_offset;
12671 if (offset == 0)
12673 rtx insn = mips_emit_move (hard_frame_pointer_rtx, stack_pointer_rtx);
12674 RTX_FRAME_RELATED_P (insn) = 1;
12676 else if (SMALL_OPERAND (offset))
12678 rtx insn = gen_add3_insn (hard_frame_pointer_rtx,
12679 stack_pointer_rtx, GEN_INT (offset));
12680 RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
12682 else
12684 mips_emit_move (MIPS_PROLOGUE_TEMP (Pmode), GEN_INT (offset));
12685 mips_emit_move (hard_frame_pointer_rtx, stack_pointer_rtx);
12686 emit_insn (gen_add3_insn (hard_frame_pointer_rtx,
12687 hard_frame_pointer_rtx,
12688 MIPS_PROLOGUE_TEMP (Pmode)));
12689 mips_set_frame_expr
12690 (gen_rtx_SET (hard_frame_pointer_rtx,
12691 plus_constant (Pmode, stack_pointer_rtx, offset)));
12695 mips_emit_loadgp ();
12697 /* Initialize the $gp save slot. */
12698 if (mips_cfun_has_cprestore_slot_p ())
12700 rtx base, mem, gp, temp;
12701 HOST_WIDE_INT offset;
12703 mips_get_cprestore_base_and_offset (&base, &offset, false);
12704 mem = gen_frame_mem (Pmode, plus_constant (Pmode, base, offset));
12705 gp = TARGET_MIPS16 ? MIPS16_PIC_TEMP : pic_offset_table_rtx;
12706 temp = (SMALL_OPERAND (offset)
12707 ? gen_rtx_SCRATCH (Pmode)
12708 : MIPS_PROLOGUE_TEMP (Pmode));
12709 emit_insn (PMODE_INSN (gen_potential_cprestore,
12710 (mem, GEN_INT (offset), gp, temp)));
12712 mips_get_cprestore_base_and_offset (&base, &offset, true);
12713 mem = gen_frame_mem (Pmode, plus_constant (Pmode, base, offset));
12714 emit_insn (PMODE_INSN (gen_use_cprestore, (mem)));
12717 /* We need to search back to the last use of K0 or K1. */
12718 if (cfun->machine->interrupt_handler_p)
12720 rtx_insn *insn;
12721 for (insn = get_last_insn (); insn != NULL_RTX; insn = PREV_INSN (insn))
12722 if (INSN_P (insn)
12723 && mips_refers_to_kernel_reg_p (PATTERN (insn)))
12724 break;
12725 /* Emit a move from K1 to COP0 Status after insn. */
12726 gcc_assert (insn != NULL_RTX);
12727 emit_insn_after (gen_cop0_move (gen_rtx_REG (SImode, COP0_STATUS_REG_NUM),
12728 gen_rtx_REG (SImode, K1_REG_NUM)),
12729 insn);
12732 /* If we are profiling, make sure no instructions are scheduled before
12733 the call to mcount. */
12734 if (crtl->profile)
12735 emit_insn (gen_blockage ());
12738 /* Attach all pending register saves to the previous instruction.
12739 Return that instruction. */
12741 static rtx_insn *
12742 mips_epilogue_emit_cfa_restores (void)
12744 rtx_insn *insn;
12746 insn = get_last_insn ();
12747 if (mips_epilogue.cfa_restores)
12749 gcc_assert (insn && !REG_NOTES (insn));
12750 RTX_FRAME_RELATED_P (insn) = 1;
12751 REG_NOTES (insn) = mips_epilogue.cfa_restores;
12752 mips_epilogue.cfa_restores = 0;
12754 return insn;
12757 /* Like mips_epilogue_emit_cfa_restores, but also record that the CFA is
12758 now at REG + OFFSET. */
12760 static void
12761 mips_epilogue_set_cfa (rtx reg, HOST_WIDE_INT offset)
12763 rtx_insn *insn;
12765 insn = mips_epilogue_emit_cfa_restores ();
12766 if (reg != mips_epilogue.cfa_reg || offset != mips_epilogue.cfa_offset)
12768 RTX_FRAME_RELATED_P (insn) = 1;
12769 REG_NOTES (insn) = alloc_reg_note (REG_CFA_DEF_CFA,
12770 plus_constant (Pmode, reg, offset),
12771 REG_NOTES (insn));
12772 mips_epilogue.cfa_reg = reg;
12773 mips_epilogue.cfa_offset = offset;
12777 /* Emit instructions to restore register REG from slot MEM. Also update
12778 the cfa_restores list. */
12780 static void
12781 mips_restore_reg (rtx reg, rtx mem)
12783 /* There's no MIPS16 instruction to load $31 directly. Load into
12784 $7 instead and adjust the return insn appropriately. */
12785 if (TARGET_MIPS16 && REGNO (reg) == RETURN_ADDR_REGNUM)
12786 reg = gen_rtx_REG (GET_MODE (reg), GP_REG_FIRST + 7);
12787 else if (GET_MODE (reg) == DFmode
12788 && (!TARGET_FLOAT64
12789 || mips_abi == ABI_32))
12791 mips_add_cfa_restore (mips_subword (reg, true));
12792 mips_add_cfa_restore (mips_subword (reg, false));
12794 else
12795 mips_add_cfa_restore (reg);
12797 mips_emit_save_slot_move (reg, mem, MIPS_EPILOGUE_TEMP (GET_MODE (reg)));
12798 if (REGNO (reg) == REGNO (mips_epilogue.cfa_reg))
12799 /* The CFA is currently defined in terms of the register whose
12800 value we have just restored. Redefine the CFA in terms of
12801 the stack pointer. */
12802 mips_epilogue_set_cfa (stack_pointer_rtx,
12803 mips_epilogue.cfa_restore_sp_offset);
12806 /* Emit code to set the stack pointer to BASE + OFFSET, given that
12807 BASE + OFFSET is NEW_FRAME_SIZE bytes below the top of the frame.
12808 BASE, if not the stack pointer, is available as a temporary. */
12810 static void
12811 mips_deallocate_stack (rtx base, rtx offset, HOST_WIDE_INT new_frame_size)
12813 if (base == stack_pointer_rtx && offset == const0_rtx)
12814 return;
12816 mips_frame_barrier ();
12817 if (offset == const0_rtx)
12819 emit_move_insn (stack_pointer_rtx, base);
12820 mips_epilogue_set_cfa (stack_pointer_rtx, new_frame_size);
12822 else if (TARGET_MIPS16 && base != stack_pointer_rtx)
12824 emit_insn (gen_add3_insn (base, base, offset));
12825 mips_epilogue_set_cfa (base, new_frame_size);
12826 emit_move_insn (stack_pointer_rtx, base);
12828 else
12830 emit_insn (gen_add3_insn (stack_pointer_rtx, base, offset));
12831 mips_epilogue_set_cfa (stack_pointer_rtx, new_frame_size);
12835 /* Emit any instructions needed before a return. */
12837 void
12838 mips_expand_before_return (void)
12840 /* When using a call-clobbered gp, we start out with unified call
12841 insns that include instructions to restore the gp. We then split
12842 these unified calls after reload. These split calls explicitly
12843 clobber gp, so there is no need to define
12844 PIC_OFFSET_TABLE_REG_CALL_CLOBBERED.
12846 For consistency, we should also insert an explicit clobber of $28
12847 before return insns, so that the post-reload optimizers know that
12848 the register is not live on exit. */
12849 if (TARGET_CALL_CLOBBERED_GP)
12850 emit_clobber (pic_offset_table_rtx);
12853 /* Expand an "epilogue" or "sibcall_epilogue" pattern; SIBCALL_P
12854 says which. */
12856 void
12857 mips_expand_epilogue (bool sibcall_p)
12859 const struct mips_frame_info *frame;
12860 HOST_WIDE_INT step1, step2;
12861 rtx base, adjust;
12862 rtx_insn *insn;
12863 bool use_jraddiusp_p = false;
12865 if (!sibcall_p && mips_can_use_return_insn ())
12867 emit_jump_insn (gen_return ());
12868 return;
12871 /* In MIPS16 mode, if the return value should go into a floating-point
12872 register, we need to call a helper routine to copy it over. */
12873 if (mips16_cfun_returns_in_fpr_p ())
12874 mips16_copy_fpr_return_value ();
12876 /* Split the frame into two. STEP1 is the amount of stack we should
12877 deallocate before restoring the registers. STEP2 is the amount we
12878 should deallocate afterwards.
12880 Start off by assuming that no registers need to be restored. */
12881 frame = &cfun->machine->frame;
12882 step1 = frame->total_size;
12883 step2 = 0;
12885 /* Work out which register holds the frame address. */
12886 if (!frame_pointer_needed)
12887 base = stack_pointer_rtx;
12888 else
12890 base = hard_frame_pointer_rtx;
12891 step1 -= frame->hard_frame_pointer_offset;
12893 mips_epilogue.cfa_reg = base;
12894 mips_epilogue.cfa_offset = step1;
12895 mips_epilogue.cfa_restores = NULL_RTX;
12897 /* If we need to restore registers, deallocate as much stack as
12898 possible in the second step without going out of range. */
12899 if ((frame->mask | frame->fmask | frame->acc_mask) != 0
12900 || frame->num_cop0_regs > 0)
12902 step2 = MIN (step1, MIPS_MAX_FIRST_STACK_STEP);
12903 step1 -= step2;
12906 /* Get an rtx for STEP1 that we can add to BASE. */
12907 adjust = GEN_INT (step1);
12908 if (!SMALL_OPERAND (step1))
12910 mips_emit_move (MIPS_EPILOGUE_TEMP (Pmode), adjust);
12911 adjust = MIPS_EPILOGUE_TEMP (Pmode);
12913 mips_deallocate_stack (base, adjust, step2);
12915 /* If we're using addressing macros, $gp is implicitly used by all
12916 SYMBOL_REFs. We must emit a blockage insn before restoring $gp
12917 from the stack. */
12918 if (TARGET_CALL_SAVED_GP && !TARGET_EXPLICIT_RELOCS)
12919 emit_insn (gen_blockage ());
12921 mips_epilogue.cfa_restore_sp_offset = step2;
12922 if (GENERATE_MIPS16E_SAVE_RESTORE && frame->mask != 0)
12924 unsigned int regno, mask;
12925 HOST_WIDE_INT offset;
12926 rtx restore;
12928 /* Generate the restore instruction. */
12929 mask = frame->mask;
12930 restore = mips16e_build_save_restore (true, &mask, &offset, 0, step2);
12932 /* Restore any other registers manually. */
12933 for (regno = GP_REG_FIRST; regno < GP_REG_LAST; regno++)
12934 if (BITSET_P (mask, regno - GP_REG_FIRST))
12936 offset -= UNITS_PER_WORD;
12937 mips_save_restore_reg (word_mode, regno, offset, mips_restore_reg);
12940 /* Restore the remaining registers and deallocate the final bit
12941 of the frame. */
12942 mips_frame_barrier ();
12943 emit_insn (restore);
12944 mips_epilogue_set_cfa (stack_pointer_rtx, 0);
12946 else
12948 /* Restore the registers. */
12949 mips_for_each_saved_acc (frame->total_size - step2, mips_restore_reg);
12950 mips_for_each_saved_gpr_and_fpr (frame->total_size - step2,
12951 mips_restore_reg);
12953 if (cfun->machine->interrupt_handler_p)
12955 HOST_WIDE_INT offset;
12956 rtx mem;
12958 offset = frame->cop0_sp_offset - (frame->total_size - step2);
12960 /* Restore the original EPC. */
12961 mem = gen_frame_mem (word_mode,
12962 plus_constant (Pmode, stack_pointer_rtx,
12963 offset));
12964 mips_emit_move (gen_rtx_REG (word_mode, K1_REG_NUM), mem);
12965 offset -= UNITS_PER_WORD;
12967 /* Move to COP0 EPC. */
12968 emit_insn (gen_cop0_move (gen_rtx_REG (SImode, COP0_EPC_REG_NUM),
12969 gen_rtx_REG (SImode, K1_REG_NUM)));
12971 /* Restore the original Status. */
12972 mem = gen_frame_mem (word_mode,
12973 plus_constant (Pmode, stack_pointer_rtx,
12974 offset));
12975 mips_emit_move (gen_rtx_REG (word_mode, K1_REG_NUM), mem);
12976 offset -= UNITS_PER_WORD;
12978 /* If we don't use shadow register set, we need to update SP. */
12979 if (cfun->machine->use_shadow_register_set == SHADOW_SET_NO)
12980 mips_deallocate_stack (stack_pointer_rtx, GEN_INT (step2), 0);
12981 else
12982 /* The choice of position is somewhat arbitrary in this case. */
12983 mips_epilogue_emit_cfa_restores ();
12985 /* Move to COP0 Status. */
12986 emit_insn (gen_cop0_move (gen_rtx_REG (SImode, COP0_STATUS_REG_NUM),
12987 gen_rtx_REG (SImode, K1_REG_NUM)));
12989 else if (TARGET_MICROMIPS
12990 && !crtl->calls_eh_return
12991 && !sibcall_p
12992 && step2 > 0
12993 && mips_unsigned_immediate_p (step2, 5, 2))
12994 use_jraddiusp_p = true;
12995 else
12996 /* Deallocate the final bit of the frame. */
12997 mips_deallocate_stack (stack_pointer_rtx, GEN_INT (step2), 0);
13000 if (cfun->machine->use_frame_header_for_callee_saved_regs)
13001 mips_epilogue_emit_cfa_restores ();
13002 else if (!use_jraddiusp_p)
13003 gcc_assert (!mips_epilogue.cfa_restores);
13005 /* Add in the __builtin_eh_return stack adjustment. We need to
13006 use a temporary in MIPS16 code. */
13007 if (crtl->calls_eh_return)
13009 if (TARGET_MIPS16)
13011 mips_emit_move (MIPS_EPILOGUE_TEMP (Pmode), stack_pointer_rtx);
13012 emit_insn (gen_add3_insn (MIPS_EPILOGUE_TEMP (Pmode),
13013 MIPS_EPILOGUE_TEMP (Pmode),
13014 EH_RETURN_STACKADJ_RTX));
13015 mips_emit_move (stack_pointer_rtx, MIPS_EPILOGUE_TEMP (Pmode));
13017 else
13018 emit_insn (gen_add3_insn (stack_pointer_rtx,
13019 stack_pointer_rtx,
13020 EH_RETURN_STACKADJ_RTX));
13023 if (!sibcall_p)
13025 mips_expand_before_return ();
13026 if (cfun->machine->interrupt_handler_p)
13028 /* Interrupt handlers generate eret or deret. */
13029 if (cfun->machine->use_debug_exception_return_p)
13030 emit_jump_insn (gen_mips_deret ());
13031 else
13032 emit_jump_insn (gen_mips_eret ());
13034 else
13036 rtx pat;
13038 /* When generating MIPS16 code, the normal
13039 mips_for_each_saved_gpr_and_fpr path will restore the return
13040 address into $7 rather than $31. */
13041 if (TARGET_MIPS16
13042 && !GENERATE_MIPS16E_SAVE_RESTORE
13043 && BITSET_P (frame->mask, RETURN_ADDR_REGNUM))
13045 /* simple_returns cannot rely on values that are only available
13046 on paths through the epilogue (because return paths that do
13047 not pass through the epilogue may nevertheless reuse a
13048 simple_return that occurs at the end of the epilogue).
13049 Use a normal return here instead. */
13050 rtx reg = gen_rtx_REG (Pmode, GP_REG_FIRST + 7);
13051 pat = gen_return_internal (reg);
13053 else if (use_jraddiusp_p)
13054 pat = gen_jraddiusp (GEN_INT (step2));
13055 else
13057 rtx reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
13058 pat = gen_simple_return_internal (reg);
13060 emit_jump_insn (pat);
13061 if (use_jraddiusp_p)
13062 mips_epilogue_set_cfa (stack_pointer_rtx, step2);
13066 /* Search from the beginning to the first use of K0 or K1. */
13067 if (cfun->machine->interrupt_handler_p
13068 && !cfun->machine->keep_interrupts_masked_p)
13070 for (insn = get_insns (); insn != NULL_RTX; insn = NEXT_INSN (insn))
13071 if (INSN_P (insn)
13072 && mips_refers_to_kernel_reg_p (PATTERN (insn)))
13073 break;
13074 gcc_assert (insn != NULL_RTX);
13075 /* Insert disable interrupts before the first use of K0 or K1. */
13076 emit_insn_before (gen_mips_di (), insn);
13077 emit_insn_before (gen_mips_ehb (), insn);
13081 /* Return nonzero if this function is known to have a null epilogue.
13082 This allows the optimizer to omit jumps to jumps if no stack
13083 was created. */
13085 bool
13086 mips_can_use_return_insn (void)
13088 /* Interrupt handlers need to go through the epilogue. */
13089 if (cfun->machine->interrupt_handler_p)
13090 return false;
13092 if (!reload_completed)
13093 return false;
13095 if (crtl->profile)
13096 return false;
13098 /* In MIPS16 mode, a function that returns a floating-point value
13099 needs to arrange to copy the return value into the floating-point
13100 registers. */
13101 if (mips16_cfun_returns_in_fpr_p ())
13102 return false;
13104 return (cfun->machine->frame.total_size == 0
13105 && !cfun->machine->use_frame_header_for_callee_saved_regs);
13108 /* Return true if register REGNO can store a value of mode MODE.
13109 The result of this function is cached in mips_hard_regno_mode_ok. */
13111 static bool
13112 mips_hard_regno_mode_ok_uncached (unsigned int regno, machine_mode mode)
13114 unsigned int size;
13115 enum mode_class mclass;
13117 if (mode == CCV2mode)
13118 return (ISA_HAS_8CC
13119 && ST_REG_P (regno)
13120 && (regno - ST_REG_FIRST) % 2 == 0);
13122 if (mode == CCV4mode)
13123 return (ISA_HAS_8CC
13124 && ST_REG_P (regno)
13125 && (regno - ST_REG_FIRST) % 4 == 0);
13127 if (mode == CCmode)
13128 return ISA_HAS_8CC ? ST_REG_P (regno) : regno == FPSW_REGNUM;
13130 size = GET_MODE_SIZE (mode);
13131 mclass = GET_MODE_CLASS (mode);
13133 if (GP_REG_P (regno) && mode != CCFmode && !MSA_SUPPORTED_MODE_P (mode))
13134 return ((regno - GP_REG_FIRST) & 1) == 0 || size <= UNITS_PER_WORD;
13136 /* For MSA, allow TImode and 128-bit vector modes in all FPR. */
13137 if (FP_REG_P (regno) && MSA_SUPPORTED_MODE_P (mode))
13138 return true;
13140 if (FP_REG_P (regno)
13141 && (((regno - FP_REG_FIRST) % MAX_FPRS_PER_FMT) == 0
13142 || (MIN_FPRS_PER_FMT == 1 && size <= UNITS_PER_FPREG)))
13144 /* Deny use of odd-numbered registers for 32-bit data for
13145 the o32 FP64A ABI. */
13146 if (TARGET_O32_FP64A_ABI && size <= 4 && (regno & 1) != 0)
13147 return false;
13149 /* The FPXX ABI requires double-precision values to be placed in
13150 even-numbered registers. Disallow odd-numbered registers with
13151 CCFmode because CCFmode double-precision compares will write a
13152 64-bit value to a register. */
13153 if (mode == CCFmode)
13154 return !(TARGET_FLOATXX && (regno & 1) != 0);
13156 /* Allow 64-bit vector modes for Loongson MultiMedia extensions
13157 Instructions (MMI). */
13158 if (TARGET_LOONGSON_MMI
13159 && (mode == V2SImode
13160 || mode == V4HImode
13161 || mode == V8QImode
13162 || mode == DImode))
13163 return true;
13165 if (mclass == MODE_FLOAT
13166 || mclass == MODE_COMPLEX_FLOAT
13167 || mclass == MODE_VECTOR_FLOAT)
13168 return size <= UNITS_PER_FPVALUE;
13170 /* Allow integer modes that fit into a single register. We need
13171 to put integers into FPRs when using instructions like CVT
13172 and TRUNC. There's no point allowing sizes smaller than a word,
13173 because the FPU has no appropriate load/store instructions. */
13174 if (mclass == MODE_INT)
13175 return size >= MIN_UNITS_PER_WORD && size <= UNITS_PER_FPREG;
13178 /* Don't allow vector modes in accumulators. */
13179 if (ACC_REG_P (regno)
13180 && !VECTOR_MODE_P (mode)
13181 && (INTEGRAL_MODE_P (mode) || ALL_FIXED_POINT_MODE_P (mode)))
13183 if (MD_REG_P (regno))
13185 /* After a multiplication or division, clobbering HI makes
13186 the value of LO unpredictable, and vice versa. This means
13187 that, for all interesting cases, HI and LO are effectively
13188 a single register.
13190 We model this by requiring that any value that uses HI
13191 also uses LO. */
13192 if (size <= UNITS_PER_WORD * 2)
13193 return regno == (size <= UNITS_PER_WORD ? LO_REGNUM : MD_REG_FIRST);
13195 else
13197 /* DSP accumulators do not have the same restrictions as
13198 HI and LO, so we can treat them as normal doubleword
13199 registers. */
13200 if (size <= UNITS_PER_WORD)
13201 return true;
13203 if (size <= UNITS_PER_WORD * 2
13204 && ((regno - DSP_ACC_REG_FIRST) & 1) == 0)
13205 return true;
13209 if (ALL_COP_REG_P (regno))
13210 return mclass == MODE_INT && size <= UNITS_PER_WORD;
13212 if (regno == GOT_VERSION_REGNUM)
13213 return mode == SImode;
13215 return false;
13218 /* Implement TARGET_HARD_REGNO_MODE_OK. */
13220 static bool
13221 mips_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
13223 return mips_hard_regno_mode_ok_p[mode][regno];
13226 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */
13228 bool
13229 mips_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED,
13230 unsigned int new_reg)
13232 /* Interrupt functions can only use registers that have already been
13233 saved by the prologue, even if they would normally be call-clobbered. */
13234 if (cfun->machine->interrupt_handler_p && !df_regs_ever_live_p (new_reg))
13235 return false;
13237 return true;
13240 /* Return nonzero if register REGNO can be used as a scratch register
13241 in peephole2. */
13243 bool
13244 mips_hard_regno_scratch_ok (unsigned int regno)
13246 /* See mips_hard_regno_rename_ok. */
13247 if (cfun->machine->interrupt_handler_p && !df_regs_ever_live_p (regno))
13248 return false;
13250 return true;
13253 /* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED. Odd-numbered
13254 single-precision registers are not considered callee-saved for o32
13255 FPXX as they will be clobbered when run on an FR=1 FPU. MSA vector
13256 registers with MODE > 64 bits are part clobbered too. */
13258 static bool
13259 mips_hard_regno_call_part_clobbered (unsigned int, unsigned int regno,
13260 machine_mode mode)
13262 if (TARGET_FLOATXX
13263 && hard_regno_nregs (regno, mode) == 1
13264 && FP_REG_P (regno)
13265 && (regno & 1) != 0)
13266 return true;
13268 if (ISA_HAS_MSA && FP_REG_P (regno) && GET_MODE_SIZE (mode) > 8)
13269 return true;
13271 return false;
13274 /* Implement TARGET_HARD_REGNO_NREGS. */
13276 static unsigned int
13277 mips_hard_regno_nregs (unsigned int regno, machine_mode mode)
13279 if (ST_REG_P (regno))
13280 /* The size of FP status registers is always 4, because they only hold
13281 CCmode values, and CCmode is always considered to be 4 bytes wide. */
13282 return (GET_MODE_SIZE (mode) + 3) / 4;
13284 if (FP_REG_P (regno))
13286 if (MSA_SUPPORTED_MODE_P (mode))
13287 return 1;
13289 return (GET_MODE_SIZE (mode) + UNITS_PER_FPREG - 1) / UNITS_PER_FPREG;
13292 /* All other registers are word-sized. */
13293 return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
13296 /* Implement CLASS_MAX_NREGS, taking the maximum of the cases
13297 in mips_hard_regno_nregs. */
13300 mips_class_max_nregs (enum reg_class rclass, machine_mode mode)
13302 int size;
13303 HARD_REG_SET left;
13305 size = 0x8000;
13306 left = reg_class_contents[rclass];
13307 if (hard_reg_set_intersect_p (left, reg_class_contents[(int) ST_REGS]))
13309 if (mips_hard_regno_mode_ok (ST_REG_FIRST, mode))
13310 size = MIN (size, 4);
13312 left &= ~reg_class_contents[ST_REGS];
13314 if (hard_reg_set_intersect_p (left, reg_class_contents[(int) FP_REGS]))
13316 if (mips_hard_regno_mode_ok (FP_REG_FIRST, mode))
13318 if (MSA_SUPPORTED_MODE_P (mode))
13319 size = MIN (size, UNITS_PER_MSA_REG);
13320 else
13321 size = MIN (size, UNITS_PER_FPREG);
13324 left &= ~reg_class_contents[FP_REGS];
13326 if (!hard_reg_set_empty_p (left))
13327 size = MIN (size, UNITS_PER_WORD);
13328 return (GET_MODE_SIZE (mode) + size - 1) / size;
13331 /* Implement TARGET_CAN_CHANGE_MODE_CLASS. */
13333 static bool
13334 mips_can_change_mode_class (machine_mode from,
13335 machine_mode to, reg_class_t rclass)
13337 /* Allow conversions between different Loongson integer vectors,
13338 and between those vectors and DImode. */
13339 if (GET_MODE_SIZE (from) == 8 && GET_MODE_SIZE (to) == 8
13340 && INTEGRAL_MODE_P (from) && INTEGRAL_MODE_P (to))
13341 return true;
13343 /* Allow conversions between different MSA vector modes. */
13344 if (MSA_SUPPORTED_MODE_P (from) && MSA_SUPPORTED_MODE_P (to))
13345 return true;
13347 /* Otherwise, there are several problems with changing the modes of
13348 values in floating-point registers:
13350 - When a multi-word value is stored in paired floating-point
13351 registers, the first register always holds the low word. We
13352 therefore can't allow FPRs to change between single-word and
13353 multi-word modes on big-endian targets.
13355 - GCC assumes that each word of a multiword register can be
13356 accessed individually using SUBREGs. This is not true for
13357 floating-point registers if they are bigger than a word.
13359 - Loading a 32-bit value into a 64-bit floating-point register
13360 will not sign-extend the value, despite what LOAD_EXTEND_OP
13361 says. We can't allow FPRs to change from SImode to a wider
13362 mode on 64-bit targets.
13364 - If the FPU has already interpreted a value in one format, we
13365 must not ask it to treat the value as having a different
13366 format.
13368 We therefore disallow all mode changes involving FPRs. */
13370 return !reg_classes_intersect_p (FP_REGS, rclass);
13373 /* Implement target hook small_register_classes_for_mode_p. */
13375 static bool
13376 mips_small_register_classes_for_mode_p (machine_mode mode
13377 ATTRIBUTE_UNUSED)
13379 return TARGET_MIPS16;
13382 /* Return true if moves in mode MODE can use the FPU's mov.fmt instruction,
13383 or use the MSA's move.v instruction. */
13385 static bool
13386 mips_mode_ok_for_mov_fmt_p (machine_mode mode)
13388 switch (mode)
13390 case E_CCFmode:
13391 case E_SFmode:
13392 return TARGET_HARD_FLOAT;
13394 case E_DFmode:
13395 return TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT;
13397 case E_V2SFmode:
13398 return TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT;
13400 default:
13401 return MSA_SUPPORTED_MODE_P (mode);
13405 /* Implement TARGET_MODES_TIEABLE_P. */
13407 static bool
13408 mips_modes_tieable_p (machine_mode mode1, machine_mode mode2)
13410 /* FPRs allow no mode punning, so it's not worth tying modes if we'd
13411 prefer to put one of them in FPRs. */
13412 return (mode1 == mode2
13413 || (!mips_mode_ok_for_mov_fmt_p (mode1)
13414 && !mips_mode_ok_for_mov_fmt_p (mode2)));
13417 /* Implement TARGET_PREFERRED_RELOAD_CLASS. */
13419 static reg_class_t
13420 mips_preferred_reload_class (rtx x, reg_class_t rclass)
13422 if (mips_dangerous_for_la25_p (x) && reg_class_subset_p (LEA_REGS, rclass))
13423 return LEA_REGS;
13425 if (reg_class_subset_p (FP_REGS, rclass)
13426 && mips_mode_ok_for_mov_fmt_p (GET_MODE (x)))
13427 return FP_REGS;
13429 if (reg_class_subset_p (GR_REGS, rclass))
13430 rclass = GR_REGS;
13432 if (TARGET_MIPS16 && reg_class_subset_p (M16_REGS, rclass))
13433 rclass = M16_REGS;
13435 return rclass;
13438 /* RCLASS is a class involved in a REGISTER_MOVE_COST calculation.
13439 Return a "canonical" class to represent it in later calculations. */
13441 static reg_class_t
13442 mips_canonicalize_move_class (reg_class_t rclass)
13444 /* All moves involving accumulator registers have the same cost. */
13445 if (reg_class_subset_p (rclass, ACC_REGS))
13446 rclass = ACC_REGS;
13448 /* Likewise promote subclasses of general registers to the most
13449 interesting containing class. */
13450 if (TARGET_MIPS16 && reg_class_subset_p (rclass, M16_REGS))
13451 rclass = M16_REGS;
13452 else if (reg_class_subset_p (rclass, GENERAL_REGS))
13453 rclass = GENERAL_REGS;
13455 return rclass;
13458 /* Return the cost of moving a value from a register of class FROM to a GPR.
13459 Return 0 for classes that are unions of other classes handled by this
13460 function. */
13462 static int
13463 mips_move_to_gpr_cost (reg_class_t from)
13465 switch (from)
13467 case M16_REGS:
13468 case GENERAL_REGS:
13469 /* A MIPS16 MOVE instruction, or a non-MIPS16 MOVE macro. */
13470 return 2;
13472 case ACC_REGS:
13473 /* MFLO and MFHI. */
13474 return 6;
13476 case FP_REGS:
13477 /* MFC1, etc. */
13478 return 4;
13480 case COP0_REGS:
13481 case COP2_REGS:
13482 case COP3_REGS:
13483 /* This choice of value is historical. */
13484 return 5;
13486 default:
13487 return 0;
13491 /* Return the cost of moving a value from a GPR to a register of class TO.
13492 Return 0 for classes that are unions of other classes handled by this
13493 function. */
13495 static int
13496 mips_move_from_gpr_cost (reg_class_t to)
13498 switch (to)
13500 case M16_REGS:
13501 case GENERAL_REGS:
13502 /* A MIPS16 MOVE instruction, or a non-MIPS16 MOVE macro. */
13503 return 2;
13505 case ACC_REGS:
13506 /* MTLO and MTHI. */
13507 return 6;
13509 case FP_REGS:
13510 /* MTC1, etc. */
13511 return 4;
13513 case COP0_REGS:
13514 case COP2_REGS:
13515 case COP3_REGS:
13516 /* This choice of value is historical. */
13517 return 5;
13519 default:
13520 return 0;
13524 /* Implement TARGET_REGISTER_MOVE_COST. Return 0 for classes that are the
13525 maximum of the move costs for subclasses; regclass will work out
13526 the maximum for us. */
13528 static int
13529 mips_register_move_cost (machine_mode mode,
13530 reg_class_t from, reg_class_t to)
13532 reg_class_t dregs;
13533 int cost1, cost2;
13535 from = mips_canonicalize_move_class (from);
13536 to = mips_canonicalize_move_class (to);
13538 /* Handle moves that can be done without using general-purpose registers. */
13539 if (from == FP_REGS)
13541 if (to == FP_REGS && mips_mode_ok_for_mov_fmt_p (mode))
13542 /* MOV.FMT. */
13543 return 4;
13546 /* Handle cases in which only one class deviates from the ideal. */
13547 dregs = TARGET_MIPS16 ? M16_REGS : GENERAL_REGS;
13548 if (from == dregs)
13549 return mips_move_from_gpr_cost (to);
13550 if (to == dregs)
13551 return mips_move_to_gpr_cost (from);
13553 /* Handles cases that require a GPR temporary. */
13554 cost1 = mips_move_to_gpr_cost (from);
13555 if (cost1 != 0)
13557 cost2 = mips_move_from_gpr_cost (to);
13558 if (cost2 != 0)
13559 return cost1 + cost2;
13562 return 0;
13565 /* Implement TARGET_REGISTER_PRIORITY. */
13567 static int
13568 mips_register_priority (int hard_regno)
13570 /* Treat MIPS16 registers with higher priority than other regs. */
13571 if (TARGET_MIPS16
13572 && TEST_HARD_REG_BIT (reg_class_contents[M16_REGS], hard_regno))
13573 return 1;
13574 return 0;
13577 /* Implement TARGET_MEMORY_MOVE_COST. */
13579 static int
13580 mips_memory_move_cost (machine_mode mode, reg_class_t rclass, bool in)
13582 return (mips_cost->memory_latency
13583 + memory_move_secondary_cost (mode, rclass, in));
13586 /* Implement TARGET_SECONDARY_MEMORY_NEEDED.
13588 When targeting the o32 FPXX ABI, all moves with a length of doubleword
13589 or greater must be performed by FR-mode-aware instructions.
13590 This can be achieved using MFHC1/MTHC1 when these instructions are
13591 available but otherwise moves must go via memory.
13592 For the o32 FP64A ABI, all odd-numbered moves with a length of
13593 doubleword or greater are required to use memory. Using MTC1/MFC1
13594 to access the lower-half of these registers would require a forbidden
13595 single-precision access. We require all double-word moves to use
13596 memory because adding even and odd floating-point registers classes
13597 would have a significant impact on the backend. */
13599 static bool
13600 mips_secondary_memory_needed (machine_mode mode, reg_class_t class1,
13601 reg_class_t class2)
13603 /* Ignore spilled pseudos. */
13604 if (lra_in_progress && (class1 == NO_REGS || class2 == NO_REGS))
13605 return false;
13607 if (((class1 == FP_REGS) != (class2 == FP_REGS))
13608 && ((TARGET_FLOATXX && !ISA_HAS_MXHC1)
13609 || TARGET_O32_FP64A_ABI)
13610 && GET_MODE_SIZE (mode) >= 8)
13611 return true;
13613 return false;
13616 /* Return the register class required for a secondary register when
13617 copying between one of the registers in RCLASS and value X, which
13618 has mode MODE. X is the source of the move if IN_P, otherwise it
13619 is the destination. Return NO_REGS if no secondary register is
13620 needed. */
13622 enum reg_class
13623 mips_secondary_reload_class (enum reg_class rclass,
13624 machine_mode mode, rtx x, bool)
13626 int regno;
13628 /* If X is a constant that cannot be loaded into $25, it must be loaded
13629 into some other GPR. No other register class allows a direct move. */
13630 if (mips_dangerous_for_la25_p (x))
13631 return reg_class_subset_p (rclass, LEA_REGS) ? NO_REGS : LEA_REGS;
13633 regno = true_regnum (x);
13634 if (TARGET_MIPS16)
13636 /* In MIPS16 mode, every move must involve a member of M16_REGS. */
13637 if (!reg_class_subset_p (rclass, M16_REGS) && !M16_REG_P (regno))
13638 return M16_REGS;
13640 return NO_REGS;
13643 /* Copying from accumulator registers to anywhere other than a general
13644 register requires a temporary general register. */
13645 if (reg_class_subset_p (rclass, ACC_REGS))
13646 return GP_REG_P (regno) ? NO_REGS : GR_REGS;
13647 if (ACC_REG_P (regno))
13648 return reg_class_subset_p (rclass, GR_REGS) ? NO_REGS : GR_REGS;
13650 if (reg_class_subset_p (rclass, FP_REGS))
13652 if (regno < 0
13653 || (MEM_P (x)
13654 && (GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8)))
13655 /* In this case we can use lwc1, swc1, ldc1 or sdc1. We'll use
13656 pairs of lwc1s and swc1s if ldc1 and sdc1 are not supported. */
13657 return NO_REGS;
13659 if (MEM_P (x) && MSA_SUPPORTED_MODE_P (mode))
13660 /* In this case we can use MSA LD.* and ST.*. */
13661 return NO_REGS;
13663 if (GP_REG_P (regno) || x == CONST0_RTX (mode))
13664 /* In this case we can use mtc1, mfc1, dmtc1 or dmfc1. */
13665 return NO_REGS;
13667 if (CONSTANT_P (x) && !targetm.cannot_force_const_mem (mode, x))
13668 /* We can force the constant to memory and use lwc1
13669 and ldc1. As above, we will use pairs of lwc1s if
13670 ldc1 is not supported. */
13671 return NO_REGS;
13673 if (FP_REG_P (regno) && mips_mode_ok_for_mov_fmt_p (mode))
13674 /* In this case we can use mov.fmt. */
13675 return NO_REGS;
13677 /* Otherwise, we need to reload through an integer register. */
13678 return GR_REGS;
13680 if (FP_REG_P (regno))
13681 return reg_class_subset_p (rclass, GR_REGS) ? NO_REGS : GR_REGS;
13683 return NO_REGS;
13686 /* Implement TARGET_MODE_REP_EXTENDED. */
13688 static int
13689 mips_mode_rep_extended (scalar_int_mode mode, scalar_int_mode mode_rep)
13691 /* On 64-bit targets, SImode register values are sign-extended to DImode. */
13692 if (TARGET_64BIT && mode == SImode && mode_rep == DImode)
13693 return SIGN_EXTEND;
13695 return UNKNOWN;
13698 /* Implement TARGET_VALID_POINTER_MODE. */
13700 static bool
13701 mips_valid_pointer_mode (scalar_int_mode mode)
13703 return mode == SImode || (TARGET_64BIT && mode == DImode);
13706 /* Implement TARGET_VECTOR_MODE_SUPPORTED_P. */
13708 static bool
13709 mips_vector_mode_supported_p (machine_mode mode)
13711 switch (mode)
13713 case E_V2SFmode:
13714 return TARGET_PAIRED_SINGLE_FLOAT;
13716 case E_V2HImode:
13717 case E_V4QImode:
13718 case E_V2HQmode:
13719 case E_V2UHQmode:
13720 case E_V2HAmode:
13721 case E_V2UHAmode:
13722 case E_V4QQmode:
13723 case E_V4UQQmode:
13724 return TARGET_DSP;
13726 case E_V2SImode:
13727 case E_V4HImode:
13728 case E_V8QImode:
13729 return TARGET_LOONGSON_MMI;
13731 default:
13732 return MSA_SUPPORTED_MODE_P (mode);
13736 /* Implement TARGET_SCALAR_MODE_SUPPORTED_P. */
13738 static bool
13739 mips_scalar_mode_supported_p (scalar_mode mode)
13741 if (ALL_FIXED_POINT_MODE_P (mode)
13742 && GET_MODE_PRECISION (mode) <= 2 * BITS_PER_WORD)
13743 return true;
13745 return default_scalar_mode_supported_p (mode);
13748 /* Implement TARGET_VECTORIZE_PREFERRED_SIMD_MODE. */
13750 static machine_mode
13751 mips_preferred_simd_mode (scalar_mode mode)
13753 if (TARGET_PAIRED_SINGLE_FLOAT
13754 && mode == SFmode)
13755 return V2SFmode;
13757 if (!ISA_HAS_MSA)
13758 return word_mode;
13760 switch (mode)
13762 case E_QImode:
13763 return V16QImode;
13764 case E_HImode:
13765 return V8HImode;
13766 case E_SImode:
13767 return V4SImode;
13768 case E_DImode:
13769 return V2DImode;
13771 case E_SFmode:
13772 return V4SFmode;
13774 case E_DFmode:
13775 return V2DFmode;
13777 default:
13778 break;
13780 return word_mode;
13783 /* Implement TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES. */
13785 static unsigned int
13786 mips_autovectorize_vector_modes (vector_modes *modes, bool)
13788 if (ISA_HAS_MSA)
13789 modes->safe_push (V16QImode);
13790 return 0;
13794 static GTY (()) rtx speculation_barrier_libfunc;
13796 /* Implement TARGET_INIT_LIBFUNCS. */
13798 static void
13799 mips_init_libfuncs (void)
13801 if (TARGET_FIX_VR4120)
13803 /* Register the special divsi3 and modsi3 functions needed to work
13804 around VR4120 division errata. */
13805 set_optab_libfunc (sdiv_optab, SImode, "__vr4120_divsi3");
13806 set_optab_libfunc (smod_optab, SImode, "__vr4120_modsi3");
13809 if (TARGET_MIPS16 && TARGET_HARD_FLOAT_ABI)
13811 /* Register the MIPS16 -mhard-float stubs. */
13812 set_optab_libfunc (add_optab, SFmode, "__mips16_addsf3");
13813 set_optab_libfunc (sub_optab, SFmode, "__mips16_subsf3");
13814 set_optab_libfunc (smul_optab, SFmode, "__mips16_mulsf3");
13815 set_optab_libfunc (sdiv_optab, SFmode, "__mips16_divsf3");
13817 set_optab_libfunc (eq_optab, SFmode, "__mips16_eqsf2");
13818 set_optab_libfunc (ne_optab, SFmode, "__mips16_nesf2");
13819 set_optab_libfunc (gt_optab, SFmode, "__mips16_gtsf2");
13820 set_optab_libfunc (ge_optab, SFmode, "__mips16_gesf2");
13821 set_optab_libfunc (lt_optab, SFmode, "__mips16_ltsf2");
13822 set_optab_libfunc (le_optab, SFmode, "__mips16_lesf2");
13823 set_optab_libfunc (unord_optab, SFmode, "__mips16_unordsf2");
13825 set_conv_libfunc (sfix_optab, SImode, SFmode, "__mips16_fix_truncsfsi");
13826 set_conv_libfunc (sfloat_optab, SFmode, SImode, "__mips16_floatsisf");
13827 set_conv_libfunc (ufloat_optab, SFmode, SImode, "__mips16_floatunsisf");
13829 if (TARGET_DOUBLE_FLOAT)
13831 set_optab_libfunc (add_optab, DFmode, "__mips16_adddf3");
13832 set_optab_libfunc (sub_optab, DFmode, "__mips16_subdf3");
13833 set_optab_libfunc (smul_optab, DFmode, "__mips16_muldf3");
13834 set_optab_libfunc (sdiv_optab, DFmode, "__mips16_divdf3");
13836 set_optab_libfunc (eq_optab, DFmode, "__mips16_eqdf2");
13837 set_optab_libfunc (ne_optab, DFmode, "__mips16_nedf2");
13838 set_optab_libfunc (gt_optab, DFmode, "__mips16_gtdf2");
13839 set_optab_libfunc (ge_optab, DFmode, "__mips16_gedf2");
13840 set_optab_libfunc (lt_optab, DFmode, "__mips16_ltdf2");
13841 set_optab_libfunc (le_optab, DFmode, "__mips16_ledf2");
13842 set_optab_libfunc (unord_optab, DFmode, "__mips16_unorddf2");
13844 set_conv_libfunc (sext_optab, DFmode, SFmode,
13845 "__mips16_extendsfdf2");
13846 set_conv_libfunc (trunc_optab, SFmode, DFmode,
13847 "__mips16_truncdfsf2");
13848 set_conv_libfunc (sfix_optab, SImode, DFmode,
13849 "__mips16_fix_truncdfsi");
13850 set_conv_libfunc (sfloat_optab, DFmode, SImode,
13851 "__mips16_floatsidf");
13852 set_conv_libfunc (ufloat_optab, DFmode, SImode,
13853 "__mips16_floatunsidf");
13857 /* The MIPS16 ISA does not have an encoding for "sync", so we rely
13858 on an external non-MIPS16 routine to implement __sync_synchronize.
13859 Similarly for the rest of the ll/sc libfuncs. */
13860 if (TARGET_MIPS16)
13862 synchronize_libfunc = init_one_libfunc ("__sync_synchronize");
13863 init_sync_libfuncs (UNITS_PER_WORD);
13865 speculation_barrier_libfunc = init_one_libfunc ("__speculation_barrier");
13868 /* Build up a multi-insn sequence that loads label TARGET into $AT. */
13870 static void
13871 mips_process_load_label (rtx target)
13873 rtx base, gp, intop;
13874 HOST_WIDE_INT offset;
13876 mips_multi_start ();
13877 switch (mips_abi)
13879 case ABI_N32:
13880 mips_multi_add_insn ("lw\t%@,%%got_page(%0)(%+)", target, 0);
13881 mips_multi_add_insn ("addiu\t%@,%@,%%got_ofst(%0)", target, 0);
13882 break;
13884 case ABI_64:
13885 mips_multi_add_insn ("ld\t%@,%%got_page(%0)(%+)", target, 0);
13886 mips_multi_add_insn ("daddiu\t%@,%@,%%got_ofst(%0)", target, 0);
13887 break;
13889 default:
13890 gp = pic_offset_table_rtx;
13891 if (mips_cfun_has_cprestore_slot_p ())
13893 gp = gen_rtx_REG (Pmode, AT_REGNUM);
13894 mips_get_cprestore_base_and_offset (&base, &offset, true);
13895 if (!SMALL_OPERAND (offset))
13897 intop = GEN_INT (CONST_HIGH_PART (offset));
13898 mips_multi_add_insn ("lui\t%0,%1", gp, intop, 0);
13899 mips_multi_add_insn ("addu\t%0,%0,%1", gp, base, 0);
13901 base = gp;
13902 offset = CONST_LOW_PART (offset);
13904 intop = GEN_INT (offset);
13905 if (ISA_HAS_LOAD_DELAY)
13906 mips_multi_add_insn ("lw\t%0,%1(%2)%#", gp, intop, base, 0);
13907 else
13908 mips_multi_add_insn ("lw\t%0,%1(%2)", gp, intop, base, 0);
13910 if (ISA_HAS_LOAD_DELAY)
13911 mips_multi_add_insn ("lw\t%@,%%got(%0)(%1)%#", target, gp, 0);
13912 else
13913 mips_multi_add_insn ("lw\t%@,%%got(%0)(%1)", target, gp, 0);
13914 mips_multi_add_insn ("addiu\t%@,%@,%%lo(%0)", target, 0);
13915 break;
13919 /* Return the number of instructions needed to load a label into $AT. */
13921 static unsigned int
13922 mips_load_label_num_insns (void)
13924 if (cfun->machine->load_label_num_insns == 0)
13926 mips_process_load_label (pc_rtx);
13927 cfun->machine->load_label_num_insns = mips_multi_num_insns;
13929 return cfun->machine->load_label_num_insns;
13932 /* Emit an asm sequence to start a noat block and load the address
13933 of a label into $1. */
13935 void
13936 mips_output_load_label (rtx target)
13938 mips_push_asm_switch (&mips_noat);
13939 if (TARGET_EXPLICIT_RELOCS)
13941 mips_process_load_label (target);
13942 mips_multi_write ();
13944 else
13946 if (Pmode == DImode)
13947 output_asm_insn ("dla\t%@,%0", &target);
13948 else
13949 output_asm_insn ("la\t%@,%0", &target);
13953 /* Return the length of INSN. LENGTH is the initial length computed by
13954 attributes in the machine-description file. */
13957 mips_adjust_insn_length (rtx_insn *insn, int length)
13959 /* mips.md uses MAX_PIC_BRANCH_LENGTH as a placeholder for the length
13960 of a PIC long-branch sequence. Substitute the correct value. */
13961 if (length == MAX_PIC_BRANCH_LENGTH
13962 && JUMP_P (insn)
13963 && INSN_CODE (insn) >= 0
13964 && get_attr_type (insn) == TYPE_BRANCH)
13966 /* Add the branch-over instruction and its delay slot, if this
13967 is a conditional branch. */
13968 length = simplejump_p (insn) ? 0 : 8;
13970 /* Add the size of a load into $AT. */
13971 length += BASE_INSN_LENGTH * mips_load_label_num_insns ();
13973 /* Add the length of an indirect jump, ignoring the delay slot. */
13974 length += TARGET_COMPRESSION ? 2 : 4;
13977 /* A unconditional jump has an unfilled delay slot if it is not part
13978 of a sequence. A conditional jump normally has a delay slot, but
13979 does not on MIPS16. */
13980 if (CALL_P (insn) || (TARGET_MIPS16 ? simplejump_p (insn) : JUMP_P (insn)))
13981 length += TARGET_MIPS16 ? 2 : 4;
13983 /* See how many nops might be needed to avoid hardware hazards. */
13984 if (!cfun->machine->ignore_hazard_length_p
13985 && INSN_P (insn)
13986 && INSN_CODE (insn) >= 0)
13987 switch (get_attr_hazard (insn))
13989 case HAZARD_NONE:
13990 break;
13992 case HAZARD_DELAY:
13993 case HAZARD_FORBIDDEN_SLOT:
13994 length += NOP_INSN_LENGTH;
13995 break;
13997 case HAZARD_HILO:
13998 length += NOP_INSN_LENGTH * 2;
13999 break;
14002 return length;
14005 /* Return the asm template for a call. OPERANDS are the operands, TARGET_OPNO
14006 is the operand number of the target. SIZE_OPNO is the operand number of
14007 the argument size operand that can optionally hold the call attributes. If
14008 SIZE_OPNO is not -1 and the call is indirect, use the function symbol from
14009 the call attributes to attach a R_MIPS_JALR relocation to the call. LINK_P
14010 indicates whether the jump is a call and needs to set the link register.
14012 When generating GOT code without explicit relocation operators, all calls
14013 should use assembly macros. Otherwise, all indirect calls should use "jr"
14014 or "jalr"; we will arrange to restore $gp afterwards if necessary. Finally,
14015 we can only generate direct calls for -mabicalls by temporarily switching
14016 to non-PIC mode.
14018 For microMIPS jal(r), we try to generate jal(r)s when a 16-bit
14019 instruction is in the delay slot of jal(r).
14021 Where compact branches are available, we try to use them if the delay slot
14022 has a NOP (or equivalently delay slots were not enabled for the instruction
14023 anyway). */
14025 const char *
14026 mips_output_jump (rtx *operands, int target_opno, int size_opno, bool link_p)
14028 static char buffer[300];
14029 char *s = buffer;
14030 bool reg_p = REG_P (operands[target_opno]);
14032 const char *and_link = link_p ? "al" : "";
14033 const char *reg = reg_p ? "r" : "";
14034 const char *compact = "";
14035 const char *nop = "%/";
14036 const char *short_delay = link_p ? "%!" : "";
14037 const char *insn_name = TARGET_CB_NEVER || reg_p ? "j" : "b";
14039 /* Compact branches can only be described when the ISA has support for them
14040 as both the compact formatter '%:' and the delay slot NOP formatter '%/'
14041 work as a mutually exclusive pair. I.e. a NOP is never required if a
14042 compact form is available. */
14043 if (!final_sequence
14044 && (TARGET_CB_MAYBE
14045 || (ISA_HAS_JRC && !link_p && reg_p)))
14047 compact = "c";
14048 nop = "";
14051 if (TARGET_USE_GOT && !TARGET_EXPLICIT_RELOCS)
14052 sprintf (s, "%%*%s%s\t%%%d%%/", insn_name, and_link, target_opno);
14053 else
14055 if (!reg_p && TARGET_ABICALLS_PIC2)
14056 s += sprintf (s, ".option\tpic0\n\t");
14058 if (reg_p && mips_get_pic_call_symbol (operands, size_opno))
14059 s += sprintf (s, "%%*.reloc\t1f,%s,%%%d\n1:\t",
14060 TARGET_MICROMIPS ? "R_MICROMIPS_JALR" : "R_MIPS_JALR",
14061 size_opno);
14062 else
14063 s += sprintf (s, "%%*");
14065 s += sprintf (s, "%s%s%s%s%s\t%%%d%s",
14066 insn_name, and_link, reg, compact, short_delay,
14067 target_opno, nop);
14069 if (!reg_p && TARGET_ABICALLS_PIC2)
14070 s += sprintf (s, "\n\t.option\tpic2");
14072 return buffer;
14075 /* Return the assembly code for INSN, which has the operands given by
14076 OPERANDS, and which branches to OPERANDS[0] if some condition is true.
14077 BRANCH_IF_TRUE is the asm template that should be used if OPERANDS[0]
14078 is in range of a direct branch. BRANCH_IF_FALSE is an inverted
14079 version of BRANCH_IF_TRUE. */
14081 const char *
14082 mips_output_conditional_branch (rtx_insn *insn, rtx *operands,
14083 const char *branch_if_true,
14084 const char *branch_if_false)
14086 unsigned int length;
14087 rtx taken;
14089 gcc_assert (LABEL_P (operands[0]));
14091 length = get_attr_length (insn);
14092 if (length <= 8)
14094 /* Just a simple conditional branch. */
14095 mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
14096 return branch_if_true;
14099 /* Generate a reversed branch around a direct jump. This fallback does
14100 not use branch-likely instructions. */
14101 mips_branch_likely = false;
14102 rtx_code_label *not_taken = gen_label_rtx ();
14103 taken = operands[0];
14105 /* Generate the reversed branch to NOT_TAKEN. */
14106 operands[0] = not_taken;
14107 output_asm_insn (branch_if_false, operands);
14109 /* If INSN has a delay slot, we must provide delay slots for both the
14110 branch to NOT_TAKEN and the conditional jump. We must also ensure
14111 that INSN's delay slot is executed in the appropriate cases. */
14112 if (final_sequence)
14114 /* This first delay slot will always be executed, so use INSN's
14115 delay slot if is not annulled. */
14116 if (!INSN_ANNULLED_BRANCH_P (insn))
14118 final_scan_insn (final_sequence->insn (1),
14119 asm_out_file, optimize, 1, NULL);
14120 final_sequence->insn (1)->set_deleted ();
14122 else
14123 output_asm_insn ("nop", 0);
14124 fprintf (asm_out_file, "\n");
14127 /* Output the unconditional branch to TAKEN. */
14128 if (TARGET_ABSOLUTE_JUMPS && TARGET_CB_MAYBE)
14130 /* Add a hazard nop. */
14131 if (!final_sequence)
14133 output_asm_insn ("nop\t\t# hazard nop", 0);
14134 fprintf (asm_out_file, "\n");
14136 output_asm_insn (MIPS_ABSOLUTE_JUMP ("bc\t%0"), &taken);
14138 else if (TARGET_ABSOLUTE_JUMPS)
14139 output_asm_insn (MIPS_ABSOLUTE_JUMP ("j\t%0%/"), &taken);
14140 else
14142 mips_output_load_label (taken);
14143 if (TARGET_CB_MAYBE)
14144 output_asm_insn ("jrc\t%@%]", 0);
14145 else
14146 output_asm_insn ("jr\t%@%]%/", 0);
14149 /* Now deal with its delay slot; see above. */
14150 if (final_sequence)
14152 /* This delay slot will only be executed if the branch is taken.
14153 Use INSN's delay slot if is annulled. */
14154 if (INSN_ANNULLED_BRANCH_P (insn))
14156 final_scan_insn (final_sequence->insn (1),
14157 asm_out_file, optimize, 1, NULL);
14158 final_sequence->insn (1)->set_deleted ();
14160 else if (TARGET_CB_NEVER)
14161 output_asm_insn ("nop", 0);
14162 fprintf (asm_out_file, "\n");
14165 /* Output NOT_TAKEN. */
14166 targetm.asm_out.internal_label (asm_out_file, "L",
14167 CODE_LABEL_NUMBER (not_taken));
14168 return "";
14171 /* Return the assembly code for INSN, which branches to OPERANDS[0]
14172 if some equality condition is true. The condition is given by
14173 OPERANDS[1] if !INVERTED_P, otherwise it is the inverse of
14174 OPERANDS[1]. OPERANDS[2] is the comparison's first operand;
14175 OPERANDS[3] is the second operand and may be zero or a register. */
14177 const char *
14178 mips_output_equal_conditional_branch (rtx_insn* insn, rtx *operands,
14179 bool inverted_p)
14181 const char *branch[2];
14182 /* For a simple BNEZ or BEQZ microMIPSr3 branch. */
14183 if (TARGET_MICROMIPS
14184 && mips_isa_rev <= 5
14185 && operands[3] == const0_rtx
14186 && get_attr_length (insn) <= 8)
14188 if (mips_cb == MIPS_CB_OPTIMAL)
14190 branch[!inverted_p] = "%*b%C1z%:\t%2,%0";
14191 branch[inverted_p] = "%*b%N1z%:\t%2,%0";
14193 else
14195 branch[!inverted_p] = "%*b%C1z\t%2,%0%/";
14196 branch[inverted_p] = "%*b%N1z\t%2,%0%/";
14199 else if (TARGET_CB_MAYBE)
14201 if (operands[3] == const0_rtx)
14203 branch[!inverted_p] = MIPS_BRANCH_C ("b%C1z", "%2,%0");
14204 branch[inverted_p] = MIPS_BRANCH_C ("b%N1z", "%2,%0");
14206 else if (REGNO (operands[2]) != REGNO (operands[3]))
14208 branch[!inverted_p] = MIPS_BRANCH_C ("b%C1", "%2,%3,%0");
14209 branch[inverted_p] = MIPS_BRANCH_C ("b%N1", "%2,%3,%0");
14211 else
14213 /* This case is degenerate. It should not happen, but does. */
14214 if (GET_CODE (operands[1]) == NE)
14215 inverted_p = !inverted_p;
14217 branch[!inverted_p] = MIPS_BRANCH_C ("b", "%0");
14218 branch[inverted_p] = "%*\t\t# branch never";
14221 else
14223 branch[!inverted_p] = MIPS_BRANCH ("b%C1", "%2,%z3,%0");
14224 branch[inverted_p] = MIPS_BRANCH ("b%N1", "%2,%z3,%0");
14227 return mips_output_conditional_branch (insn, operands, branch[1], branch[0]);
14230 /* Return the assembly code for INSN, which branches to OPERANDS[0]
14231 if some ordering condition is true. The condition is given by
14232 OPERANDS[1] if !INVERTED_P, otherwise it is the inverse of
14233 OPERANDS[1]. OPERANDS[2] is the comparison's first operand;
14234 OPERANDS[3] is the second operand and may be zero or a register. */
14236 const char *
14237 mips_output_order_conditional_branch (rtx_insn *insn, rtx *operands,
14238 bool inverted_p)
14240 const char *branch[2];
14242 /* Make BRANCH[1] branch to OPERANDS[0] when the condition is true.
14243 Make BRANCH[0] branch on the inverse condition. */
14244 if (operands[3] != const0_rtx)
14246 /* Handle degenerate cases that should not, but do, occur. */
14247 if (REGNO (operands[2]) == REGNO (operands[3]))
14249 switch (GET_CODE (operands[1]))
14251 case LT:
14252 case LTU:
14253 inverted_p = !inverted_p;
14254 /* Fall through. */
14255 case GE:
14256 case GEU:
14257 branch[!inverted_p] = MIPS_BRANCH_C ("b", "%0");
14258 branch[inverted_p] = "%*\t\t# branch never";
14259 break;
14260 default:
14261 gcc_unreachable ();
14264 else
14266 branch[!inverted_p] = MIPS_BRANCH_C ("b%C1", "%2,%3,%0");
14267 branch[inverted_p] = MIPS_BRANCH_C ("b%N1", "%2,%3,%0");
14270 else
14272 switch (GET_CODE (operands[1]))
14274 /* These cases are equivalent to comparisons against zero. */
14275 case LEU:
14276 inverted_p = !inverted_p;
14277 /* Fall through. */
14278 case GTU:
14279 if (TARGET_CB_MAYBE)
14281 branch[!inverted_p] = MIPS_BRANCH_C ("bnez", "%2,%0");
14282 branch[inverted_p] = MIPS_BRANCH_C ("beqz", "%2,%0");
14284 else
14286 branch[!inverted_p] = MIPS_BRANCH ("bne", "%2,%.,%0");
14287 branch[inverted_p] = MIPS_BRANCH ("beq", "%2,%.,%0");
14289 break;
14291 /* These cases are always true or always false. */
14292 case LTU:
14293 inverted_p = !inverted_p;
14294 /* Fall through. */
14295 case GEU:
14296 if (TARGET_CB_MAYBE)
14298 branch[!inverted_p] = MIPS_BRANCH_C ("b", "%0");
14299 branch[inverted_p] = "%*\t\t# branch never";
14301 else
14303 branch[!inverted_p] = MIPS_BRANCH ("beq", "%.,%.,%0");
14304 branch[inverted_p] = MIPS_BRANCH ("bne", "%.,%.,%0");
14306 break;
14308 default:
14309 if (TARGET_CB_MAYBE)
14311 branch[!inverted_p] = MIPS_BRANCH_C ("b%C1z", "%2,%0");
14312 branch[inverted_p] = MIPS_BRANCH_C ("b%N1z", "%2,%0");
14314 else
14316 branch[!inverted_p] = MIPS_BRANCH ("b%C1z", "%2,%0");
14317 branch[inverted_p] = MIPS_BRANCH ("b%N1z", "%2,%0");
14319 break;
14322 return mips_output_conditional_branch (insn, operands, branch[1], branch[0]);
14325 /* Start a block of code that needs access to the LL, SC and SYNC
14326 instructions. */
14328 static void
14329 mips_start_ll_sc_sync_block (void)
14331 if (!ISA_HAS_LL_SC)
14333 output_asm_insn (".set\tpush", 0);
14334 if (TARGET_64BIT)
14335 output_asm_insn (".set\tmips3", 0);
14336 else
14337 output_asm_insn (".set\tmips2", 0);
14341 /* End a block started by mips_start_ll_sc_sync_block. */
14343 static void
14344 mips_end_ll_sc_sync_block (void)
14346 if (!ISA_HAS_LL_SC)
14347 output_asm_insn (".set\tpop", 0);
14350 /* Output and/or return the asm template for a sync instruction. */
14352 const char *
14353 mips_output_sync (void)
14355 mips_start_ll_sc_sync_block ();
14356 output_asm_insn ("sync", 0);
14357 mips_end_ll_sc_sync_block ();
14358 return "";
14361 /* Return the asm template associated with sync_insn1 value TYPE.
14362 IS_64BIT_P is true if we want a 64-bit rather than 32-bit operation. */
14364 static const char *
14365 mips_sync_insn1_template (enum attr_sync_insn1 type, bool is_64bit_p)
14367 switch (type)
14369 case SYNC_INSN1_MOVE:
14370 return "move\t%0,%z2";
14371 case SYNC_INSN1_LI:
14372 return "li\t%0,%2";
14373 case SYNC_INSN1_ADDU:
14374 return is_64bit_p ? "daddu\t%0,%1,%z2" : "addu\t%0,%1,%z2";
14375 case SYNC_INSN1_ADDIU:
14376 return is_64bit_p ? "daddiu\t%0,%1,%2" : "addiu\t%0,%1,%2";
14377 case SYNC_INSN1_SUBU:
14378 return is_64bit_p ? "dsubu\t%0,%1,%z2" : "subu\t%0,%1,%z2";
14379 case SYNC_INSN1_AND:
14380 return "and\t%0,%1,%z2";
14381 case SYNC_INSN1_ANDI:
14382 return "andi\t%0,%1,%2";
14383 case SYNC_INSN1_OR:
14384 return "or\t%0,%1,%z2";
14385 case SYNC_INSN1_ORI:
14386 return "ori\t%0,%1,%2";
14387 case SYNC_INSN1_XOR:
14388 return "xor\t%0,%1,%z2";
14389 case SYNC_INSN1_XORI:
14390 return "xori\t%0,%1,%2";
14392 gcc_unreachable ();
14395 /* Return the asm template associated with sync_insn2 value TYPE. */
14397 static const char *
14398 mips_sync_insn2_template (enum attr_sync_insn2 type)
14400 switch (type)
14402 case SYNC_INSN2_NOP:
14403 gcc_unreachable ();
14404 case SYNC_INSN2_AND:
14405 return "and\t%0,%1,%z2";
14406 case SYNC_INSN2_XOR:
14407 return "xor\t%0,%1,%z2";
14408 case SYNC_INSN2_NOT:
14409 return "nor\t%0,%1,%.";
14411 gcc_unreachable ();
14414 /* OPERANDS are the operands to a sync loop instruction and INDEX is
14415 the value of the one of the sync_* attributes. Return the operand
14416 referred to by the attribute, or DEFAULT_VALUE if the insn doesn't
14417 have the associated attribute. */
14419 static rtx
14420 mips_get_sync_operand (rtx *operands, int index, rtx default_value)
14422 if (index > 0)
14423 default_value = operands[index - 1];
14424 return default_value;
14427 /* INSN is a sync loop with operands OPERANDS. Build up a multi-insn
14428 sequence for it. */
14430 static void
14431 mips_process_sync_loop (rtx_insn *insn, rtx *operands)
14433 rtx at, mem, oldval, newval, inclusive_mask, exclusive_mask;
14434 rtx required_oldval, insn1_op2, tmp1, tmp2, tmp3, cmp;
14435 unsigned int tmp3_insn;
14436 enum attr_sync_insn1 insn1;
14437 enum attr_sync_insn2 insn2;
14438 bool is_64bit_p;
14439 int memmodel_attr;
14440 enum memmodel model;
14442 /* Read an operand from the sync_WHAT attribute and store it in
14443 variable WHAT. DEFAULT is the default value if no attribute
14444 is specified. */
14445 #define READ_OPERAND(WHAT, DEFAULT) \
14446 WHAT = mips_get_sync_operand (operands, (int) get_attr_sync_##WHAT (insn), \
14447 DEFAULT)
14449 /* Read the memory. */
14450 READ_OPERAND (mem, 0);
14451 gcc_assert (mem);
14452 is_64bit_p = (GET_MODE_BITSIZE (GET_MODE (mem)) == 64);
14454 /* Read the other attributes. */
14455 at = gen_rtx_REG (GET_MODE (mem), AT_REGNUM);
14456 READ_OPERAND (oldval, at);
14457 READ_OPERAND (cmp, 0);
14458 READ_OPERAND (newval, at);
14459 READ_OPERAND (inclusive_mask, 0);
14460 READ_OPERAND (exclusive_mask, 0);
14461 READ_OPERAND (required_oldval, 0);
14462 READ_OPERAND (insn1_op2, 0);
14463 insn1 = get_attr_sync_insn1 (insn);
14464 insn2 = get_attr_sync_insn2 (insn);
14466 /* Don't bother setting CMP result that is never used. */
14467 if (cmp && find_reg_note (insn, REG_UNUSED, cmp))
14468 cmp = 0;
14470 memmodel_attr = get_attr_sync_memmodel (insn);
14471 switch (memmodel_attr)
14473 case 10:
14474 model = MEMMODEL_ACQ_REL;
14475 break;
14476 case 11:
14477 model = MEMMODEL_ACQUIRE;
14478 break;
14479 default:
14480 model = memmodel_from_int (INTVAL (operands[memmodel_attr]));
14483 mips_multi_start ();
14485 /* Output the release side of the memory barrier. */
14486 if (need_atomic_barrier_p (model, true))
14488 if (required_oldval == 0 && TARGET_OCTEON)
14490 /* Octeon doesn't reorder reads, so a full barrier can be
14491 created by using SYNCW to order writes combined with the
14492 write from the following SC. When the SC successfully
14493 completes, we know that all preceding writes are also
14494 committed to the coherent memory system. It is possible
14495 for a single SYNCW to fail, but a pair of them will never
14496 fail, so we use two. */
14497 mips_multi_add_insn ("syncw", NULL);
14498 mips_multi_add_insn ("syncw", NULL);
14500 else
14501 mips_multi_add_insn ("sync", NULL);
14504 /* Output the branch-back label. */
14505 mips_multi_add_label ("1:");
14507 /* OLDVAL = *MEM. */
14508 mips_multi_add_insn (is_64bit_p ? "lld\t%0,%1" : "ll\t%0,%1",
14509 oldval, mem, NULL);
14511 /* if ((OLDVAL & INCLUSIVE_MASK) != REQUIRED_OLDVAL) goto 2. */
14512 if (required_oldval)
14514 if (inclusive_mask == 0)
14515 tmp1 = oldval;
14516 else
14518 gcc_assert (oldval != at);
14519 mips_multi_add_insn ("and\t%0,%1,%2",
14520 at, oldval, inclusive_mask, NULL);
14521 tmp1 = at;
14523 if (TARGET_CB_NEVER)
14524 mips_multi_add_insn ("bne\t%0,%z1,2f", tmp1, required_oldval, NULL);
14526 /* CMP = 0 [delay slot]. */
14527 if (cmp)
14528 mips_multi_add_insn ("li\t%0,0", cmp, NULL);
14530 if (TARGET_CB_MAYBE && required_oldval == const0_rtx)
14531 mips_multi_add_insn ("bnezc\t%0,2f", tmp1, NULL);
14532 else if (TARGET_CB_MAYBE)
14533 mips_multi_add_insn ("bnec\t%0,%1,2f", tmp1, required_oldval, NULL);
14537 /* $TMP1 = OLDVAL & EXCLUSIVE_MASK. */
14538 if (exclusive_mask == 0)
14539 tmp1 = const0_rtx;
14540 else
14542 gcc_assert (oldval != at);
14543 mips_multi_add_insn ("and\t%0,%1,%z2",
14544 at, oldval, exclusive_mask, NULL);
14545 tmp1 = at;
14548 /* $TMP2 = INSN1 (OLDVAL, INSN1_OP2).
14550 We can ignore moves if $TMP4 != INSN1_OP2, since we'll still emit
14551 at least one instruction in that case. */
14552 if (insn1 == SYNC_INSN1_MOVE
14553 && (tmp1 != const0_rtx || insn2 != SYNC_INSN2_NOP))
14554 tmp2 = insn1_op2;
14555 else
14557 mips_multi_add_insn (mips_sync_insn1_template (insn1, is_64bit_p),
14558 newval, oldval, insn1_op2, NULL);
14559 tmp2 = newval;
14562 /* $TMP3 = INSN2 ($TMP2, INCLUSIVE_MASK). */
14563 if (insn2 == SYNC_INSN2_NOP)
14564 tmp3 = tmp2;
14565 else
14567 mips_multi_add_insn (mips_sync_insn2_template (insn2),
14568 newval, tmp2, inclusive_mask, NULL);
14569 tmp3 = newval;
14571 tmp3_insn = mips_multi_last_index ();
14573 /* $AT = $TMP1 | $TMP3. */
14574 if (tmp1 == const0_rtx || tmp3 == const0_rtx)
14576 mips_multi_set_operand (tmp3_insn, 0, at);
14577 tmp3 = at;
14579 else
14581 gcc_assert (tmp1 != tmp3);
14582 mips_multi_add_insn ("or\t%0,%1,%2", at, tmp1, tmp3, NULL);
14585 /* if (!commit (*MEM = $AT)) goto 1.
14587 This will sometimes be a delayed branch; see the write code below
14588 for details. */
14589 mips_multi_add_insn (is_64bit_p ? "scd\t%0,%1" : "sc\t%0,%1", at, mem, NULL);
14591 /* When using branch likely (-mfix-r10000), the delay slot instruction
14592 will be annulled on false. The normal delay slot instructions
14593 calculate the overall result of the atomic operation and must not
14594 be annulled. To ensure this behavior unconditionally use a NOP
14595 in the delay slot for the branch likely case. */
14597 if (TARGET_CB_MAYBE)
14598 mips_multi_add_insn ("beqzc\t%0,1b", at, NULL);
14599 else
14600 mips_multi_add_insn ("beq%?\t%0,%.,1b%~", at, NULL);
14602 /* if (INSN1 != MOVE && INSN1 != LI) NEWVAL = $TMP3 [delay slot]. */
14603 if (insn1 != SYNC_INSN1_MOVE && insn1 != SYNC_INSN1_LI && tmp3 != newval)
14605 mips_multi_copy_insn (tmp3_insn);
14606 mips_multi_set_operand (mips_multi_last_index (), 0, newval);
14608 else if (!(required_oldval && cmp) && !mips_branch_likely)
14609 mips_multi_add_insn ("nop", NULL);
14611 /* CMP = 1 -- either standalone or in a delay slot. */
14612 if (required_oldval && cmp)
14613 mips_multi_add_insn ("li\t%0,1", cmp, NULL);
14615 /* Output the acquire side of the memory barrier. */
14616 if (TARGET_SYNC_AFTER_SC && need_atomic_barrier_p (model, false))
14617 mips_multi_add_insn ("sync", NULL);
14619 /* Output the exit label, if needed. */
14620 if (required_oldval)
14621 mips_multi_add_label ("2:");
14623 #undef READ_OPERAND
14626 /* Output and/or return the asm template for sync loop INSN, which has
14627 the operands given by OPERANDS. */
14629 const char *
14630 mips_output_sync_loop (rtx_insn *insn, rtx *operands)
14632 /* Use branch-likely instructions to work around the LL/SC R10000
14633 errata. */
14634 mips_branch_likely = TARGET_FIX_R10000;
14636 mips_process_sync_loop (insn, operands);
14638 mips_push_asm_switch (&mips_noreorder);
14639 mips_push_asm_switch (&mips_nomacro);
14640 mips_push_asm_switch (&mips_noat);
14641 mips_start_ll_sc_sync_block ();
14643 mips_multi_write ();
14645 mips_end_ll_sc_sync_block ();
14646 mips_pop_asm_switch (&mips_noat);
14647 mips_pop_asm_switch (&mips_nomacro);
14648 mips_pop_asm_switch (&mips_noreorder);
14650 return "";
14653 /* Return the number of individual instructions in sync loop INSN,
14654 which has the operands given by OPERANDS. */
14656 unsigned int
14657 mips_sync_loop_insns (rtx_insn *insn, rtx *operands)
14659 /* Use branch-likely instructions to work around the LL/SC R10000
14660 errata. */
14661 mips_branch_likely = TARGET_FIX_R10000;
14662 mips_process_sync_loop (insn, operands);
14663 return mips_multi_num_insns;
14666 /* Return the assembly code for DIV or DDIV instruction DIVISION, which has
14667 the operands given by OPERANDS. Add in a divide-by-zero check if needed.
14669 When working around R4000 and R4400 errata, we need to make sure that
14670 the division is not immediately followed by a shift[1][2]. We also
14671 need to stop the division from being put into a branch delay slot[3].
14672 The easiest way to avoid both problems is to add a nop after the
14673 division. When a divide-by-zero check is needed, this nop can be
14674 used to fill the branch delay slot.
14676 [1] If a double-word or a variable shift executes immediately
14677 after starting an integer division, the shift may give an
14678 incorrect result. See quotations of errata #16 and #28 from
14679 "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
14680 in mips.md for details.
14682 [2] A similar bug to [1] exists for all revisions of the
14683 R4000 and the R4400 when run in an MC configuration.
14684 From "MIPS R4000MC Errata, Processor Revision 2.2 and 3.0":
14686 "19. In this following sequence:
14688 ddiv (or ddivu or div or divu)
14689 dsll32 (or dsrl32, dsra32)
14691 if an MPT stall occurs, while the divide is slipping the cpu
14692 pipeline, then the following double shift would end up with an
14693 incorrect result.
14695 Workaround: The compiler needs to avoid generating any
14696 sequence with divide followed by extended double shift."
14698 This erratum is also present in "MIPS R4400MC Errata, Processor
14699 Revision 1.0" and "MIPS R4400MC Errata, Processor Revision 2.0
14700 & 3.0" as errata #10 and #4, respectively.
14702 [3] From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
14703 (also valid for MIPS R4000MC processors):
14705 "52. R4000SC: This bug does not apply for the R4000PC.
14707 There are two flavors of this bug:
14709 1) If the instruction just after divide takes an RF exception
14710 (tlb-refill, tlb-invalid) and gets an instruction cache
14711 miss (both primary and secondary) and the line which is
14712 currently in secondary cache at this index had the first
14713 data word, where the bits 5..2 are set, then R4000 would
14714 get a wrong result for the div.
14718 div r8, r9
14719 ------------------- # end-of page. -tlb-refill
14723 div r8, r9
14724 ------------------- # end-of page. -tlb-invalid
14727 2) If the divide is in the taken branch delay slot, where the
14728 target takes RF exception and gets an I-cache miss for the
14729 exception vector or where I-cache miss occurs for the
14730 target address, under the above mentioned scenarios, the
14731 div would get wrong results.
14734 j r2 # to next page mapped or unmapped
14735 div r8,r9 # this bug would be there as long
14736 # as there is an ICache miss and
14737 nop # the "data pattern" is present
14740 beq r0, r0, NextPage # to Next page
14741 div r8,r9
14744 This bug is present for div, divu, ddiv, and ddivu
14745 instructions.
14747 Workaround: For item 1), OS could make sure that the next page
14748 after the divide instruction is also mapped. For item 2), the
14749 compiler could make sure that the divide instruction is not in
14750 the branch delay slot."
14752 These processors have PRId values of 0x00004220 and 0x00004300 for
14753 the R4000 and 0x00004400, 0x00004500 and 0x00004600 for the R4400. */
14755 const char *
14756 mips_output_division (const char *division, rtx *operands)
14758 const char *s;
14760 s = division;
14761 if (TARGET_FIX_R4000 || TARGET_FIX_R4400)
14763 output_asm_insn (s, operands);
14764 s = "nop";
14766 if (TARGET_CHECK_ZERO_DIV)
14768 if (TARGET_MIPS16)
14770 output_asm_insn (s, operands);
14771 s = "bnez\t%2,1f\n\tbreak\t7\n1:";
14773 else if (GENERATE_DIVIDE_TRAPS)
14775 /* Avoid long replay penalty on load miss by putting the trap before
14776 the divide. */
14777 if (TUNE_74K)
14778 output_asm_insn ("teq\t%2,%.,7", operands);
14779 else
14781 output_asm_insn (s, operands);
14782 s = "teq\t%2,%.,7";
14785 else
14787 if (flag_delayed_branch)
14789 output_asm_insn ("%(bne\t%2,%.,1f", operands);
14790 output_asm_insn (s, operands);
14791 s = "break\t7%)\n1:";
14793 else
14795 output_asm_insn (s, operands);
14796 s = "bne\t%2,%.,1f\n\tnop\n\tbreak\t7\n1:";
14800 return s;
14803 /* Return the assembly code for MSA DIV_{S,U}.DF or MOD_{S,U}.DF instructions,
14804 which has the operands given by OPERANDS. Add in a divide-by-zero check
14805 if needed. */
14807 const char *
14808 mips_msa_output_division (const char *division, rtx *operands)
14810 const char *s;
14812 s = division;
14813 if (TARGET_CHECK_ZERO_DIV)
14815 output_asm_insn ("%(bnz.%v0\t%w2,1f", operands);
14816 output_asm_insn (s, operands);
14817 s = "break\t7%)\n1:";
14819 return s;
14822 /* Return the assembly code for MSA immediate shift instructions,
14823 which has the operands given by OPERANDS. Truncate the shift amount
14824 to make GAS happy. */
14826 const char *
14827 mips_msa_output_shift_immediate (const char *shift, rtx *operands)
14829 rtx amount = operands[2];
14830 machine_mode mode = amount->mode;
14832 unsigned val = UINTVAL (CONST_VECTOR_ELT (amount, 0));
14833 val &= GET_MODE_UNIT_BITSIZE (mode) - 1;
14834 if (!val)
14835 return "";
14837 rtx c = gen_int_mode (val, GET_MODE_INNER (mode));
14838 operands[2] = gen_const_vec_duplicate (mode, c);
14840 return shift;
14843 /* Return true if destination of IN_INSN is used as add source in
14844 OUT_INSN. Both IN_INSN and OUT_INSN are of type fmadd. Example:
14845 madd.s dst, x, y, z
14846 madd.s a, dst, b, c */
14848 bool
14849 mips_fmadd_bypass (rtx_insn *out_insn, rtx_insn *in_insn)
14851 int dst_reg, src_reg;
14853 gcc_assert (get_attr_type (in_insn) == TYPE_FMADD);
14854 gcc_assert (get_attr_type (out_insn) == TYPE_FMADD);
14856 extract_insn (in_insn);
14857 dst_reg = REG_P (recog_data.operand[0]);
14859 extract_insn (out_insn);
14860 src_reg = REG_P (recog_data.operand[1]);
14862 if (dst_reg == src_reg)
14863 return true;
14865 return false;
14868 /* Return true if IN_INSN is a multiply-add or multiply-subtract
14869 instruction and if OUT_INSN assigns to the accumulator operand. */
14871 bool
14872 mips_linked_madd_p (rtx_insn *out_insn, rtx_insn *in_insn)
14874 enum attr_accum_in accum_in;
14875 int accum_in_opnum;
14876 rtx accum_in_op;
14878 if (recog_memoized (in_insn) < 0)
14879 return false;
14881 accum_in = get_attr_accum_in (in_insn);
14882 if (accum_in == ACCUM_IN_NONE)
14883 return false;
14885 accum_in_opnum = accum_in - ACCUM_IN_0;
14887 extract_insn (in_insn);
14888 gcc_assert (accum_in_opnum < recog_data.n_operands);
14889 accum_in_op = recog_data.operand[accum_in_opnum];
14891 return reg_set_p (accum_in_op, out_insn);
14894 /* True if the dependency between OUT_INSN and IN_INSN is on the store
14895 data rather than the address. We need this because the cprestore
14896 pattern is type "store", but is defined using an UNSPEC_VOLATILE,
14897 which causes the default routine to abort. We just return false
14898 for that case. */
14900 bool
14901 mips_store_data_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn)
14903 if (GET_CODE (PATTERN (in_insn)) == UNSPEC_VOLATILE)
14904 return false;
14906 return store_data_bypass_p (out_insn, in_insn);
14910 /* Variables and flags used in scheduler hooks when tuning for
14911 Loongson 2E/2F. */
14912 static struct
14914 /* Variables to support Loongson 2E/2F round-robin [F]ALU1/2 dispatch
14915 strategy. */
14917 /* If true, then next ALU1/2 instruction will go to ALU1. */
14918 bool alu1_turn_p;
14920 /* If true, then next FALU1/2 unstruction will go to FALU1. */
14921 bool falu1_turn_p;
14923 /* Codes to query if [f]alu{1,2}_core units are subscribed or not. */
14924 int alu1_core_unit_code;
14925 int alu2_core_unit_code;
14926 int falu1_core_unit_code;
14927 int falu2_core_unit_code;
14929 /* True if current cycle has a multi instruction.
14930 This flag is used in mips_ls2_dfa_post_advance_cycle. */
14931 bool cycle_has_multi_p;
14933 /* Instructions to subscribe ls2_[f]alu{1,2}_turn_enabled units.
14934 These are used in mips_ls2_dfa_post_advance_cycle to initialize
14935 DFA state.
14936 E.g., when alu1_turn_enabled_insn is issued it makes next ALU1/2
14937 instruction to go ALU1. */
14938 rtx_insn *alu1_turn_enabled_insn;
14939 rtx_insn *alu2_turn_enabled_insn;
14940 rtx_insn *falu1_turn_enabled_insn;
14941 rtx_insn *falu2_turn_enabled_insn;
14942 } mips_ls2;
14944 /* Implement TARGET_SCHED_ADJUST_COST. We assume that anti and output
14945 dependencies have no cost, except on the 20Kc where output-dependence
14946 is treated like input-dependence. */
14948 static int
14949 mips_adjust_cost (rtx_insn *, int dep_type, rtx_insn *, int cost, unsigned int)
14951 if (dep_type != 0 && (dep_type != REG_DEP_OUTPUT || !TUNE_20KC))
14952 return 0;
14953 return cost;
14956 /* Return the number of instructions that can be issued per cycle. */
14958 static int
14959 mips_issue_rate (void)
14961 switch (mips_tune)
14963 case PROCESSOR_74KC:
14964 case PROCESSOR_74KF2_1:
14965 case PROCESSOR_74KF1_1:
14966 case PROCESSOR_74KF3_2:
14967 /* The 74k is not strictly quad-issue cpu, but can be seen as one
14968 by the scheduler. It can issue 1 ALU, 1 AGEN and 2 FPU insns,
14969 but in reality only a maximum of 3 insns can be issued as
14970 floating-point loads and stores also require a slot in the
14971 AGEN pipe. */
14972 case PROCESSOR_R10000:
14973 /* All R10K Processors are quad-issue (being the first MIPS
14974 processors to support this feature). */
14975 return 4;
14977 case PROCESSOR_20KC:
14978 case PROCESSOR_R4130:
14979 case PROCESSOR_R5400:
14980 case PROCESSOR_R5500:
14981 case PROCESSOR_R5900:
14982 case PROCESSOR_R7000:
14983 case PROCESSOR_R9000:
14984 case PROCESSOR_OCTEON:
14985 case PROCESSOR_OCTEON2:
14986 case PROCESSOR_OCTEON3:
14987 case PROCESSOR_I6400:
14988 case PROCESSOR_GS264E:
14989 return 2;
14991 case PROCESSOR_SB1:
14992 case PROCESSOR_SB1A:
14993 /* This is actually 4, but we get better performance if we claim 3.
14994 This is partly because of unwanted speculative code motion with the
14995 larger number, and partly because in most common cases we can't
14996 reach the theoretical max of 4. */
14997 return 3;
14999 case PROCESSOR_LOONGSON_2E:
15000 case PROCESSOR_LOONGSON_2F:
15001 case PROCESSOR_GS464:
15002 case PROCESSOR_GS464E:
15003 case PROCESSOR_P5600:
15004 case PROCESSOR_P6600:
15005 return 4;
15007 case PROCESSOR_XLP:
15008 return (reload_completed ? 4 : 3);
15010 default:
15011 return 1;
15015 /* Implement TARGET_SCHED_INIT_DFA_POST_CYCLE_INSN hook for Loongson2. */
15017 static void
15018 mips_ls2_init_dfa_post_cycle_insn (void)
15020 start_sequence ();
15021 emit_insn (gen_ls2_alu1_turn_enabled_insn ());
15022 mips_ls2.alu1_turn_enabled_insn = get_insns ();
15023 end_sequence ();
15025 start_sequence ();
15026 emit_insn (gen_ls2_alu2_turn_enabled_insn ());
15027 mips_ls2.alu2_turn_enabled_insn = get_insns ();
15028 end_sequence ();
15030 start_sequence ();
15031 emit_insn (gen_ls2_falu1_turn_enabled_insn ());
15032 mips_ls2.falu1_turn_enabled_insn = get_insns ();
15033 end_sequence ();
15035 start_sequence ();
15036 emit_insn (gen_ls2_falu2_turn_enabled_insn ());
15037 mips_ls2.falu2_turn_enabled_insn = get_insns ();
15038 end_sequence ();
15040 mips_ls2.alu1_core_unit_code = get_cpu_unit_code ("ls2_alu1_core");
15041 mips_ls2.alu2_core_unit_code = get_cpu_unit_code ("ls2_alu2_core");
15042 mips_ls2.falu1_core_unit_code = get_cpu_unit_code ("ls2_falu1_core");
15043 mips_ls2.falu2_core_unit_code = get_cpu_unit_code ("ls2_falu2_core");
15046 /* Implement TARGET_SCHED_INIT_DFA_POST_CYCLE_INSN hook.
15047 Init data used in mips_dfa_post_advance_cycle. */
15049 static void
15050 mips_init_dfa_post_cycle_insn (void)
15052 if (TUNE_LOONGSON_2EF)
15053 mips_ls2_init_dfa_post_cycle_insn ();
15056 /* Initialize STATE when scheduling for Loongson 2E/2F.
15057 Support round-robin dispatch scheme by enabling only one of
15058 ALU1/ALU2 and one of FALU1/FALU2 units for ALU1/2 and FALU1/2 instructions
15059 respectively. */
15061 static void
15062 mips_ls2_dfa_post_advance_cycle (state_t state)
15064 if (cpu_unit_reservation_p (state, mips_ls2.alu1_core_unit_code))
15066 /* Though there are no non-pipelined ALU1 insns,
15067 we can get an instruction of type 'multi' before reload. */
15068 gcc_assert (mips_ls2.cycle_has_multi_p);
15069 mips_ls2.alu1_turn_p = false;
15072 mips_ls2.cycle_has_multi_p = false;
15074 if (cpu_unit_reservation_p (state, mips_ls2.alu2_core_unit_code))
15075 /* We have a non-pipelined alu instruction in the core,
15076 adjust round-robin counter. */
15077 mips_ls2.alu1_turn_p = true;
15079 if (mips_ls2.alu1_turn_p)
15081 if (state_transition (state, mips_ls2.alu1_turn_enabled_insn) >= 0)
15082 gcc_unreachable ();
15084 else
15086 if (state_transition (state, mips_ls2.alu2_turn_enabled_insn) >= 0)
15087 gcc_unreachable ();
15090 if (cpu_unit_reservation_p (state, mips_ls2.falu1_core_unit_code))
15092 /* There are no non-pipelined FALU1 insns. */
15093 gcc_unreachable ();
15094 mips_ls2.falu1_turn_p = false;
15097 if (cpu_unit_reservation_p (state, mips_ls2.falu2_core_unit_code))
15098 /* We have a non-pipelined falu instruction in the core,
15099 adjust round-robin counter. */
15100 mips_ls2.falu1_turn_p = true;
15102 if (mips_ls2.falu1_turn_p)
15104 if (state_transition (state, mips_ls2.falu1_turn_enabled_insn) >= 0)
15105 gcc_unreachable ();
15107 else
15109 if (state_transition (state, mips_ls2.falu2_turn_enabled_insn) >= 0)
15110 gcc_unreachable ();
15114 /* Implement TARGET_SCHED_DFA_POST_ADVANCE_CYCLE.
15115 This hook is being called at the start of each cycle. */
15117 static void
15118 mips_dfa_post_advance_cycle (void)
15120 if (TUNE_LOONGSON_2EF)
15121 mips_ls2_dfa_post_advance_cycle (curr_state);
15124 /* Implement TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD. This should
15125 be as wide as the scheduling freedom in the DFA. */
15127 static int
15128 mips_multipass_dfa_lookahead (void)
15130 /* Can schedule up to 4 of the 6 function units in any one cycle. */
15131 if (TUNE_SB1)
15132 return 4;
15134 if (TUNE_LOONGSON_2EF || TUNE_GS464 || TUNE_GS464E)
15135 return 4;
15137 if (TUNE_OCTEON || TUNE_GS264E)
15138 return 2;
15140 if (TUNE_P5600 || TUNE_P6600 || TUNE_I6400)
15141 return 4;
15143 return 0;
15146 /* Remove the instruction at index LOWER from ready queue READY and
15147 reinsert it in front of the instruction at index HIGHER. LOWER must
15148 be <= HIGHER. */
15150 static void
15151 mips_promote_ready (rtx_insn **ready, int lower, int higher)
15153 rtx_insn *new_head;
15154 int i;
15156 new_head = ready[lower];
15157 for (i = lower; i < higher; i++)
15158 ready[i] = ready[i + 1];
15159 ready[i] = new_head;
15162 /* If the priority of the instruction at POS2 in the ready queue READY
15163 is within LIMIT units of that of the instruction at POS1, swap the
15164 instructions if POS2 is not already less than POS1. */
15166 static void
15167 mips_maybe_swap_ready (rtx_insn **ready, int pos1, int pos2, int limit)
15169 if (pos1 < pos2
15170 && INSN_PRIORITY (ready[pos1]) + limit >= INSN_PRIORITY (ready[pos2]))
15172 rtx_insn *temp;
15174 temp = ready[pos1];
15175 ready[pos1] = ready[pos2];
15176 ready[pos2] = temp;
15180 /* Used by TUNE_MACC_CHAINS to record the last scheduled instruction
15181 that may clobber hi or lo. */
15182 static rtx_insn *mips_macc_chains_last_hilo;
15184 /* A TUNE_MACC_CHAINS helper function. Record that instruction INSN has
15185 been scheduled, updating mips_macc_chains_last_hilo appropriately. */
15187 static void
15188 mips_macc_chains_record (rtx_insn *insn)
15190 if (get_attr_may_clobber_hilo (insn))
15191 mips_macc_chains_last_hilo = insn;
15194 /* A TUNE_MACC_CHAINS helper function. Search ready queue READY, which
15195 has NREADY elements, looking for a multiply-add or multiply-subtract
15196 instruction that is cumulative with mips_macc_chains_last_hilo.
15197 If there is one, promote it ahead of anything else that might
15198 clobber hi or lo. */
15200 static void
15201 mips_macc_chains_reorder (rtx_insn **ready, int nready)
15203 int i, j;
15205 if (mips_macc_chains_last_hilo != 0)
15206 for (i = nready - 1; i >= 0; i--)
15207 if (mips_linked_madd_p (mips_macc_chains_last_hilo, ready[i]))
15209 for (j = nready - 1; j > i; j--)
15210 if (recog_memoized (ready[j]) >= 0
15211 && get_attr_may_clobber_hilo (ready[j]))
15213 mips_promote_ready (ready, i, j);
15214 break;
15216 break;
15220 /* The last instruction to be scheduled. */
15221 static rtx_insn *vr4130_last_insn;
15223 /* A note_stores callback used by vr4130_true_reg_dependence_p. DATA
15224 points to an rtx that is initially an instruction. Nullify the rtx
15225 if the instruction uses the value of register X. */
15227 static void
15228 vr4130_true_reg_dependence_p_1 (rtx x, const_rtx pat ATTRIBUTE_UNUSED,
15229 void *data)
15231 rtx *insn_ptr;
15233 insn_ptr = (rtx *) data;
15234 if (REG_P (x)
15235 && *insn_ptr != 0
15236 && reg_referenced_p (x, PATTERN (*insn_ptr)))
15237 *insn_ptr = 0;
15240 /* Return true if there is true register dependence between vr4130_last_insn
15241 and INSN. */
15243 static bool
15244 vr4130_true_reg_dependence_p (rtx insn)
15246 note_stores (vr4130_last_insn, vr4130_true_reg_dependence_p_1, &insn);
15247 return insn == 0;
15250 /* A TUNE_MIPS4130 helper function. Given that INSN1 is at the head of
15251 the ready queue and that INSN2 is the instruction after it, return
15252 true if it is worth promoting INSN2 ahead of INSN1. Look for cases
15253 in which INSN1 and INSN2 can probably issue in parallel, but for
15254 which (INSN2, INSN1) should be less sensitive to instruction
15255 alignment than (INSN1, INSN2). See 4130.md for more details. */
15257 static bool
15258 vr4130_swap_insns_p (rtx_insn *insn1, rtx_insn *insn2)
15260 sd_iterator_def sd_it;
15261 dep_t dep;
15263 /* Check for the following case:
15265 1) there is some other instruction X with an anti dependence on INSN1;
15266 2) X has a higher priority than INSN2; and
15267 3) X is an arithmetic instruction (and thus has no unit restrictions).
15269 If INSN1 is the last instruction blocking X, it would better to
15270 choose (INSN1, X) over (INSN2, INSN1). */
15271 FOR_EACH_DEP (insn1, SD_LIST_FORW, sd_it, dep)
15272 if (DEP_TYPE (dep) == REG_DEP_ANTI
15273 && INSN_PRIORITY (DEP_CON (dep)) > INSN_PRIORITY (insn2)
15274 && recog_memoized (DEP_CON (dep)) >= 0
15275 && get_attr_vr4130_class (DEP_CON (dep)) == VR4130_CLASS_ALU)
15276 return false;
15278 if (vr4130_last_insn != 0
15279 && recog_memoized (insn1) >= 0
15280 && recog_memoized (insn2) >= 0)
15282 /* See whether INSN1 and INSN2 use different execution units,
15283 or if they are both ALU-type instructions. If so, they can
15284 probably execute in parallel. */
15285 enum attr_vr4130_class class1 = get_attr_vr4130_class (insn1);
15286 enum attr_vr4130_class class2 = get_attr_vr4130_class (insn2);
15287 if (class1 != class2 || class1 == VR4130_CLASS_ALU)
15289 /* If only one of the instructions has a dependence on
15290 vr4130_last_insn, prefer to schedule the other one first. */
15291 bool dep1_p = vr4130_true_reg_dependence_p (insn1);
15292 bool dep2_p = vr4130_true_reg_dependence_p (insn2);
15293 if (dep1_p != dep2_p)
15294 return dep1_p;
15296 /* Prefer to schedule INSN2 ahead of INSN1 if vr4130_last_insn
15297 is not an ALU-type instruction and if INSN1 uses the same
15298 execution unit. (Note that if this condition holds, we already
15299 know that INSN2 uses a different execution unit.) */
15300 if (class1 != VR4130_CLASS_ALU
15301 && recog_memoized (vr4130_last_insn) >= 0
15302 && class1 == get_attr_vr4130_class (vr4130_last_insn))
15303 return true;
15306 return false;
15309 /* A TUNE_MIPS4130 helper function. (READY, NREADY) describes a ready
15310 queue with at least two instructions. Swap the first two if
15311 vr4130_swap_insns_p says that it could be worthwhile. */
15313 static void
15314 vr4130_reorder (rtx_insn **ready, int nready)
15316 if (vr4130_swap_insns_p (ready[nready - 1], ready[nready - 2]))
15317 mips_promote_ready (ready, nready - 2, nready - 1);
15320 /* Record whether last 74k AGEN instruction was a load or store. */
15321 static enum attr_type mips_last_74k_agen_insn = TYPE_UNKNOWN;
15323 /* Initialize mips_last_74k_agen_insn from INSN. A null argument
15324 resets to TYPE_UNKNOWN state. */
15326 static void
15327 mips_74k_agen_init (rtx_insn *insn)
15329 if (!insn || CALL_P (insn) || JUMP_P (insn))
15330 mips_last_74k_agen_insn = TYPE_UNKNOWN;
15331 else
15333 enum attr_type type = get_attr_type (insn);
15334 if (type == TYPE_LOAD || type == TYPE_STORE)
15335 mips_last_74k_agen_insn = type;
15339 /* A TUNE_74K helper function. The 74K AGEN pipeline likes multiple
15340 loads to be grouped together, and multiple stores to be grouped
15341 together. Swap things around in the ready queue to make this happen. */
15343 static void
15344 mips_74k_agen_reorder (rtx_insn **ready, int nready)
15346 int i;
15347 int store_pos, load_pos;
15349 store_pos = -1;
15350 load_pos = -1;
15352 for (i = nready - 1; i >= 0; i--)
15354 rtx_insn *insn = ready[i];
15355 if (USEFUL_INSN_P (insn))
15356 switch (get_attr_type (insn))
15358 case TYPE_STORE:
15359 if (store_pos == -1)
15360 store_pos = i;
15361 break;
15363 case TYPE_LOAD:
15364 if (load_pos == -1)
15365 load_pos = i;
15366 break;
15368 default:
15369 break;
15373 if (load_pos == -1 || store_pos == -1)
15374 return;
15376 switch (mips_last_74k_agen_insn)
15378 case TYPE_UNKNOWN:
15379 /* Prefer to schedule loads since they have a higher latency. */
15380 case TYPE_LOAD:
15381 /* Swap loads to the front of the queue. */
15382 mips_maybe_swap_ready (ready, load_pos, store_pos, 4);
15383 break;
15384 case TYPE_STORE:
15385 /* Swap stores to the front of the queue. */
15386 mips_maybe_swap_ready (ready, store_pos, load_pos, 4);
15387 break;
15388 default:
15389 break;
15393 /* Implement TARGET_SCHED_INIT. */
15395 static void
15396 mips_sched_init (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
15397 int max_ready ATTRIBUTE_UNUSED)
15399 mips_macc_chains_last_hilo = 0;
15400 vr4130_last_insn = 0;
15401 mips_74k_agen_init (NULL);
15403 /* When scheduling for Loongson2, branch instructions go to ALU1,
15404 therefore basic block is most likely to start with round-robin counter
15405 pointed to ALU2. */
15406 mips_ls2.alu1_turn_p = false;
15407 mips_ls2.falu1_turn_p = true;
15410 /* Subroutine used by TARGET_SCHED_REORDER and TARGET_SCHED_REORDER2. */
15412 static void
15413 mips_sched_reorder_1 (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
15414 rtx_insn **ready, int *nreadyp, int cycle ATTRIBUTE_UNUSED)
15416 if (!reload_completed
15417 && TUNE_MACC_CHAINS
15418 && *nreadyp > 0)
15419 mips_macc_chains_reorder (ready, *nreadyp);
15421 if (reload_completed
15422 && TUNE_MIPS4130
15423 && !TARGET_VR4130_ALIGN
15424 && *nreadyp > 1)
15425 vr4130_reorder (ready, *nreadyp);
15427 if (TUNE_74K)
15428 mips_74k_agen_reorder (ready, *nreadyp);
15431 /* Implement TARGET_SCHED_REORDER. */
15433 static int
15434 mips_sched_reorder (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
15435 rtx_insn **ready, int *nreadyp, int cycle ATTRIBUTE_UNUSED)
15437 mips_sched_reorder_1 (file, verbose, ready, nreadyp, cycle);
15438 return mips_issue_rate ();
15441 /* Implement TARGET_SCHED_REORDER2. */
15443 static int
15444 mips_sched_reorder2 (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
15445 rtx_insn **ready, int *nreadyp, int cycle ATTRIBUTE_UNUSED)
15447 mips_sched_reorder_1 (file, verbose, ready, nreadyp, cycle);
15448 return cached_can_issue_more;
15451 /* Update round-robin counters for ALU1/2 and FALU1/2. */
15453 static void
15454 mips_ls2_variable_issue (rtx_insn *insn)
15456 if (mips_ls2.alu1_turn_p)
15458 if (cpu_unit_reservation_p (curr_state, mips_ls2.alu1_core_unit_code))
15459 mips_ls2.alu1_turn_p = false;
15461 else
15463 if (cpu_unit_reservation_p (curr_state, mips_ls2.alu2_core_unit_code))
15464 mips_ls2.alu1_turn_p = true;
15467 if (mips_ls2.falu1_turn_p)
15469 if (cpu_unit_reservation_p (curr_state, mips_ls2.falu1_core_unit_code))
15470 mips_ls2.falu1_turn_p = false;
15472 else
15474 if (cpu_unit_reservation_p (curr_state, mips_ls2.falu2_core_unit_code))
15475 mips_ls2.falu1_turn_p = true;
15478 if (recog_memoized (insn) >= 0)
15479 mips_ls2.cycle_has_multi_p |= (get_attr_type (insn) == TYPE_MULTI);
15482 /* Implement TARGET_SCHED_VARIABLE_ISSUE. */
15484 static int
15485 mips_variable_issue (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
15486 rtx_insn *insn, int more)
15488 /* Ignore USEs and CLOBBERs; don't count them against the issue rate. */
15489 if (USEFUL_INSN_P (insn))
15491 if (get_attr_type (insn) != TYPE_GHOST)
15492 more--;
15493 if (!reload_completed && TUNE_MACC_CHAINS)
15494 mips_macc_chains_record (insn);
15495 vr4130_last_insn = insn;
15496 if (TUNE_74K)
15497 mips_74k_agen_init (insn);
15498 else if (TUNE_LOONGSON_2EF)
15499 mips_ls2_variable_issue (insn);
15502 /* Instructions of type 'multi' should all be split before
15503 the second scheduling pass. */
15504 gcc_assert (!reload_completed
15505 || recog_memoized (insn) < 0
15506 || get_attr_type (insn) != TYPE_MULTI);
15508 cached_can_issue_more = more;
15509 return more;
15512 /* Given that we have an rtx of the form (prefetch ... WRITE LOCALITY),
15513 return the first operand of the associated PREF or PREFX insn. */
15516 mips_prefetch_cookie (rtx write, rtx locality)
15518 /* store_streamed / load_streamed. */
15519 if (INTVAL (locality) <= 0)
15520 return GEN_INT (INTVAL (write) + 4);
15522 /* store / load. */
15523 if (INTVAL (locality) <= 2)
15524 return write;
15526 /* store_retained / load_retained. */
15527 return GEN_INT (INTVAL (write) + 6);
15530 /* Loongson EXT2 only implements pref hint=0 (prefetch for load) and hint=1
15531 (prefetch for store), other hint just scale to hint = 0 and hint = 1. */
15534 mips_loongson_ext2_prefetch_cookie (rtx write, rtx)
15536 /* store. */
15537 if (INTVAL (write) == 1)
15538 return GEN_INT (INTVAL (write));
15540 /* load. */
15541 if (INTVAL (write) == 0)
15542 return GEN_INT (INTVAL (write));
15544 gcc_unreachable ();
15548 /* Flags that indicate when a built-in function is available.
15550 BUILTIN_AVAIL_NON_MIPS16
15551 The function is available on the current target if !TARGET_MIPS16.
15553 BUILTIN_AVAIL_MIPS16
15554 The function is available on the current target if TARGET_MIPS16.
15556 BUILTIN_AVAIL_MIPS16E2
15557 The function is available on the current target if TARGET_MIPS16E2. */
15558 #define BUILTIN_AVAIL_NON_MIPS16 1
15559 #define BUILTIN_AVAIL_MIPS16 2
15560 #define BUILTIN_AVAIL_MIPS16E2 4
15562 /* Declare an availability predicate for built-in functions that
15563 require non-MIPS16 mode and also require COND to be true.
15564 NAME is the main part of the predicate's name. */
15565 #define AVAIL_NON_MIPS16(NAME, COND) \
15566 static unsigned int \
15567 mips_builtin_avail_##NAME (void) \
15569 return (COND) ? BUILTIN_AVAIL_NON_MIPS16 : 0; \
15572 /* Declare an availability predicate for built-in functions that
15573 require non-MIPS16 mode or MIPS16E2 and also require COND to be true.
15574 NAME is the main part of the predicate's name. */
15575 #define AVAIL_MIPS16E2_OR_NON_MIPS16(NAME, COND) \
15576 static unsigned int \
15577 mips_builtin_avail_##NAME (void) \
15579 return ((COND) ? BUILTIN_AVAIL_NON_MIPS16 | BUILTIN_AVAIL_MIPS16E2 \
15580 : 0); \
15583 /* Declare an availability predicate for built-in functions that
15584 support both MIPS16 and non-MIPS16 code and also require COND
15585 to be true. NAME is the main part of the predicate's name. */
15586 #define AVAIL_ALL(NAME, COND) \
15587 static unsigned int \
15588 mips_builtin_avail_##NAME (void) \
15590 return (COND) ? BUILTIN_AVAIL_NON_MIPS16 | BUILTIN_AVAIL_MIPS16 : 0; \
15593 /* This structure describes a single built-in function. */
15594 struct mips_builtin_description {
15595 /* The code of the main .md file instruction. See mips_builtin_type
15596 for more information. */
15597 enum insn_code icode;
15599 /* The floating-point comparison code to use with ICODE, if any. */
15600 enum mips_fp_condition cond;
15602 /* The name of the built-in function. */
15603 const char *name;
15605 /* Specifies how the function should be expanded. */
15606 enum mips_builtin_type builtin_type;
15608 /* The function's prototype. */
15609 enum mips_function_type function_type;
15611 /* Whether the function is available. */
15612 unsigned int (*avail) (void);
15614 /* Whether the function is pure. */
15615 bool is_pure;
15618 AVAIL_ALL (hard_float, TARGET_HARD_FLOAT_ABI)
15619 AVAIL_NON_MIPS16 (paired_single, TARGET_PAIRED_SINGLE_FLOAT)
15620 AVAIL_NON_MIPS16 (sb1_paired_single, TARGET_SB1 && TARGET_PAIRED_SINGLE_FLOAT)
15621 AVAIL_NON_MIPS16 (mips3d, TARGET_MIPS3D)
15622 AVAIL_NON_MIPS16 (dsp, TARGET_DSP)
15623 AVAIL_NON_MIPS16 (dspr2, TARGET_DSPR2)
15624 AVAIL_NON_MIPS16 (dsp_32, !TARGET_64BIT && TARGET_DSP)
15625 AVAIL_NON_MIPS16 (dsp_64, TARGET_64BIT && TARGET_DSP)
15626 AVAIL_NON_MIPS16 (dspr2_32, !TARGET_64BIT && TARGET_DSPR2)
15627 AVAIL_NON_MIPS16 (loongson, TARGET_LOONGSON_MMI)
15628 AVAIL_MIPS16E2_OR_NON_MIPS16 (cache, TARGET_CACHE_BUILTIN)
15629 AVAIL_NON_MIPS16 (msa, TARGET_MSA)
15631 /* Construct a mips_builtin_description from the given arguments.
15633 INSN is the name of the associated instruction pattern, without the
15634 leading CODE_FOR_mips_.
15636 CODE is the floating-point condition code associated with the
15637 function. It can be 'f' if the field is not applicable.
15639 NAME is the name of the function itself, without the leading
15640 "__builtin_mips_".
15642 BUILTIN_TYPE and FUNCTION_TYPE are mips_builtin_description fields.
15644 AVAIL is the name of the availability predicate, without the leading
15645 mips_builtin_avail_. */
15646 #define MIPS_BUILTIN(INSN, COND, NAME, BUILTIN_TYPE, \
15647 FUNCTION_TYPE, AVAIL, PURE) \
15648 { CODE_FOR_mips_ ## INSN, MIPS_FP_COND_ ## COND, \
15649 "__builtin_mips_" NAME, BUILTIN_TYPE, FUNCTION_TYPE, \
15650 mips_builtin_avail_ ## AVAIL, PURE }
15652 /* Define __builtin_mips_<INSN>, which is a MIPS_BUILTIN_DIRECT function
15653 mapped to instruction CODE_FOR_mips_<INSN>, FUNCTION_TYPE and AVAIL
15654 are as for MIPS_BUILTIN. */
15655 #define DIRECT_BUILTIN(INSN, FUNCTION_TYPE, AVAIL) \
15656 MIPS_BUILTIN (INSN, f, #INSN, MIPS_BUILTIN_DIRECT, FUNCTION_TYPE, \
15657 AVAIL, false)
15659 /* Define __builtin_mips_<INSN>, which is a MIPS_BUILTIN_DIRECT pure function
15660 mapped to instruction CODE_FOR_mips_<INSN>, FUNCTION_TYPE and AVAIL
15661 are as for MIPS_BUILTIN. */
15662 #define DIRECT_BUILTIN_PURE(INSN, FUNCTION_TYPE, AVAIL) \
15663 MIPS_BUILTIN (INSN, f, #INSN, MIPS_BUILTIN_DIRECT, FUNCTION_TYPE, \
15664 AVAIL, true)
15666 /* Define __builtin_mips_<INSN>_<COND>_{s,d} functions, both of which
15667 are subject to mips_builtin_avail_<AVAIL>. */
15668 #define CMP_SCALAR_BUILTINS(INSN, COND, AVAIL) \
15669 MIPS_BUILTIN (INSN ## _cond_s, COND, #INSN "_" #COND "_s", \
15670 MIPS_BUILTIN_CMP_SINGLE, MIPS_INT_FTYPE_SF_SF, AVAIL, \
15671 false), \
15672 MIPS_BUILTIN (INSN ## _cond_d, COND, #INSN "_" #COND "_d", \
15673 MIPS_BUILTIN_CMP_SINGLE, MIPS_INT_FTYPE_DF_DF, AVAIL, false)
15675 /* Define __builtin_mips_{any,all,upper,lower}_<INSN>_<COND>_ps.
15676 The lower and upper forms are subject to mips_builtin_avail_<AVAIL>
15677 while the any and all forms are subject to mips_builtin_avail_mips3d. */
15678 #define CMP_PS_BUILTINS(INSN, COND, AVAIL) \
15679 MIPS_BUILTIN (INSN ## _cond_ps, COND, "any_" #INSN "_" #COND "_ps", \
15680 MIPS_BUILTIN_CMP_ANY, MIPS_INT_FTYPE_V2SF_V2SF, \
15681 mips3d, false), \
15682 MIPS_BUILTIN (INSN ## _cond_ps, COND, "all_" #INSN "_" #COND "_ps", \
15683 MIPS_BUILTIN_CMP_ALL, MIPS_INT_FTYPE_V2SF_V2SF, \
15684 mips3d, false), \
15685 MIPS_BUILTIN (INSN ## _cond_ps, COND, "lower_" #INSN "_" #COND "_ps", \
15686 MIPS_BUILTIN_CMP_LOWER, MIPS_INT_FTYPE_V2SF_V2SF, \
15687 AVAIL, false), \
15688 MIPS_BUILTIN (INSN ## _cond_ps, COND, "upper_" #INSN "_" #COND "_ps", \
15689 MIPS_BUILTIN_CMP_UPPER, MIPS_INT_FTYPE_V2SF_V2SF, \
15690 AVAIL, false)
15692 /* Define __builtin_mips_{any,all}_<INSN>_<COND>_4s. The functions
15693 are subject to mips_builtin_avail_mips3d. */
15694 #define CMP_4S_BUILTINS(INSN, COND) \
15695 MIPS_BUILTIN (INSN ## _cond_4s, COND, "any_" #INSN "_" #COND "_4s", \
15696 MIPS_BUILTIN_CMP_ANY, \
15697 MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF, mips3d, false), \
15698 MIPS_BUILTIN (INSN ## _cond_4s, COND, "all_" #INSN "_" #COND "_4s", \
15699 MIPS_BUILTIN_CMP_ALL, \
15700 MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF, mips3d, false)
15702 /* Define __builtin_mips_mov{t,f}_<INSN>_<COND>_ps. The comparison
15703 instruction requires mips_builtin_avail_<AVAIL>. */
15704 #define MOVTF_BUILTINS(INSN, COND, AVAIL) \
15705 MIPS_BUILTIN (INSN ## _cond_ps, COND, "movt_" #INSN "_" #COND "_ps", \
15706 MIPS_BUILTIN_MOVT, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF, \
15707 AVAIL, false), \
15708 MIPS_BUILTIN (INSN ## _cond_ps, COND, "movf_" #INSN "_" #COND "_ps", \
15709 MIPS_BUILTIN_MOVF, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF, \
15710 AVAIL, false)
15712 /* Define all the built-in functions related to C.cond.fmt condition COND. */
15713 #define CMP_BUILTINS(COND) \
15714 MOVTF_BUILTINS (c, COND, paired_single), \
15715 MOVTF_BUILTINS (cabs, COND, mips3d), \
15716 CMP_SCALAR_BUILTINS (cabs, COND, mips3d), \
15717 CMP_PS_BUILTINS (c, COND, paired_single), \
15718 CMP_PS_BUILTINS (cabs, COND, mips3d), \
15719 CMP_4S_BUILTINS (c, COND), \
15720 CMP_4S_BUILTINS (cabs, COND)
15722 /* Define __builtin_mips_<INSN>, which is a MIPS_BUILTIN_DIRECT_NO_TARGET
15723 function mapped to instruction CODE_FOR_mips_<INSN>, FUNCTION_TYPE
15724 and AVAIL are as for MIPS_BUILTIN. */
15725 #define DIRECT_NO_TARGET_BUILTIN(INSN, FUNCTION_TYPE, AVAIL) \
15726 MIPS_BUILTIN (INSN, f, #INSN, MIPS_BUILTIN_DIRECT_NO_TARGET, \
15727 FUNCTION_TYPE, AVAIL, false)
15729 /* Define __builtin_mips_bposge<VALUE>. <VALUE> is 32 for the MIPS32 DSP
15730 branch instruction. AVAIL is as for MIPS_BUILTIN. */
15731 #define BPOSGE_BUILTIN(VALUE, AVAIL) \
15732 MIPS_BUILTIN (bposge, f, "bposge" #VALUE, \
15733 MIPS_BUILTIN_BPOSGE ## VALUE, MIPS_SI_FTYPE_VOID, AVAIL, false)
15735 /* Define a Loongson MIPS_BUILTIN_DIRECT function __builtin_loongson_<FN_NAME>
15736 for instruction CODE_FOR_loongson_<INSN>. FUNCTION_TYPE is a
15737 builtin_description field. */
15738 #define LOONGSON_BUILTIN_ALIAS(INSN, FN_NAME, FUNCTION_TYPE) \
15739 { CODE_FOR_loongson_ ## INSN, MIPS_FP_COND_f, \
15740 "__builtin_loongson_" #FN_NAME, MIPS_BUILTIN_DIRECT, \
15741 FUNCTION_TYPE, mips_builtin_avail_loongson, false }
15743 /* Define a Loongson MIPS_BUILTIN_DIRECT function __builtin_loongson_<INSN>
15744 for instruction CODE_FOR_loongson_<INSN>. FUNCTION_TYPE is a
15745 builtin_description field. */
15746 #define LOONGSON_BUILTIN(INSN, FUNCTION_TYPE) \
15747 LOONGSON_BUILTIN_ALIAS (INSN, INSN, FUNCTION_TYPE)
15749 /* Like LOONGSON_BUILTIN, but add _<SUFFIX> to the end of the function name.
15750 We use functions of this form when the same insn can be usefully applied
15751 to more than one datatype. */
15752 #define LOONGSON_BUILTIN_SUFFIX(INSN, SUFFIX, FUNCTION_TYPE) \
15753 LOONGSON_BUILTIN_ALIAS (INSN, INSN ## _ ## SUFFIX, FUNCTION_TYPE)
15755 /* Define an MSA MIPS_BUILTIN_DIRECT pure function __builtin_msa_<INSN>
15756 for instruction CODE_FOR_msa_<INSN>. FUNCTION_TYPE is a builtin_description
15757 field. */
15758 #define MSA_BUILTIN_PURE(INSN, FUNCTION_TYPE) \
15759 { CODE_FOR_msa_ ## INSN, MIPS_FP_COND_f, \
15760 "__builtin_msa_" #INSN, MIPS_BUILTIN_DIRECT, \
15761 FUNCTION_TYPE, mips_builtin_avail_msa, true }
15763 /* Define an MSA MIPS_BUILTIN_DIRECT non-pure function __builtin_msa_<INSN>
15764 for instruction CODE_FOR_msa_<INSN>. FUNCTION_TYPE is a builtin_description
15765 field. */
15766 #define MSA_BUILTIN(INSN, FUNCTION_TYPE) \
15767 { CODE_FOR_msa_ ## INSN, MIPS_FP_COND_f, \
15768 "__builtin_msa_" #INSN, MIPS_BUILTIN_DIRECT, \
15769 FUNCTION_TYPE, mips_builtin_avail_msa, false }
15771 /* Define a remapped MSA MIPS_BUILTIN_DIRECT function __builtin_msa_<INSN>
15772 for instruction CODE_FOR_msa_<INSN2>. FUNCTION_TYPE is
15773 a builtin_description field. */
15774 #define MSA_BUILTIN_REMAP(INSN, INSN2, FUNCTION_TYPE) \
15775 { CODE_FOR_msa_ ## INSN2, MIPS_FP_COND_f, \
15776 "__builtin_msa_" #INSN, MIPS_BUILTIN_DIRECT, \
15777 FUNCTION_TYPE, mips_builtin_avail_msa, false }
15779 /* Define an MSA MIPS_BUILTIN_MSA_TEST_BRANCH function __builtin_msa_<INSN>
15780 for instruction CODE_FOR_msa_<INSN>. FUNCTION_TYPE is a builtin_description
15781 field. */
15782 #define MSA_BUILTIN_TEST_BRANCH(INSN, FUNCTION_TYPE) \
15783 { CODE_FOR_msa_ ## INSN, MIPS_FP_COND_f, \
15784 "__builtin_msa_" #INSN, MIPS_BUILTIN_MSA_TEST_BRANCH, \
15785 FUNCTION_TYPE, mips_builtin_avail_msa, false }
15787 /* Define an MSA MIPS_BUILTIN_DIRECT_NO_TARGET function __builtin_msa_<INSN>
15788 for instruction CODE_FOR_msa_<INSN>. FUNCTION_TYPE is a builtin_description
15789 field. */
15790 #define MSA_NO_TARGET_BUILTIN(INSN, FUNCTION_TYPE) \
15791 { CODE_FOR_msa_ ## INSN, MIPS_FP_COND_f, \
15792 "__builtin_msa_" #INSN, MIPS_BUILTIN_DIRECT_NO_TARGET, \
15793 FUNCTION_TYPE, mips_builtin_avail_msa, false }
15795 #define CODE_FOR_mips_sqrt_ps CODE_FOR_sqrtv2sf2
15796 #define CODE_FOR_mips_addq_ph CODE_FOR_addv2hi3
15797 #define CODE_FOR_mips_addu_qb CODE_FOR_addv4qi3
15798 #define CODE_FOR_mips_subq_ph CODE_FOR_subv2hi3
15799 #define CODE_FOR_mips_subu_qb CODE_FOR_subv4qi3
15800 #define CODE_FOR_mips_mul_ph CODE_FOR_mulv2hi3
15801 #define CODE_FOR_mips_mult CODE_FOR_mulsidi3_32bit
15802 #define CODE_FOR_mips_multu CODE_FOR_umulsidi3_32bit
15804 #define CODE_FOR_loongson_packsswh CODE_FOR_vec_pack_ssat_v2si
15805 #define CODE_FOR_loongson_packsshb CODE_FOR_vec_pack_ssat_v4hi
15806 #define CODE_FOR_loongson_packushb CODE_FOR_vec_pack_usat_v4hi
15807 #define CODE_FOR_loongson_paddw CODE_FOR_addv2si3
15808 #define CODE_FOR_loongson_paddh CODE_FOR_addv4hi3
15809 #define CODE_FOR_loongson_paddb CODE_FOR_addv8qi3
15810 #define CODE_FOR_loongson_paddsh CODE_FOR_ssaddv4hi3
15811 #define CODE_FOR_loongson_paddsb CODE_FOR_ssaddv8qi3
15812 #define CODE_FOR_loongson_paddush CODE_FOR_usaddv4hi3
15813 #define CODE_FOR_loongson_paddusb CODE_FOR_usaddv8qi3
15814 #define CODE_FOR_loongson_pmaxsh CODE_FOR_smaxv4hi3
15815 #define CODE_FOR_loongson_pmaxub CODE_FOR_umaxv8qi3
15816 #define CODE_FOR_loongson_pminsh CODE_FOR_sminv4hi3
15817 #define CODE_FOR_loongson_pminub CODE_FOR_uminv8qi3
15818 #define CODE_FOR_loongson_pmulhuh CODE_FOR_umulv4hi3_highpart
15819 #define CODE_FOR_loongson_pmulhh CODE_FOR_smulv4hi3_highpart
15820 #define CODE_FOR_loongson_pmullh CODE_FOR_mulv4hi3
15821 #define CODE_FOR_loongson_psllh CODE_FOR_ashlv4hi3
15822 #define CODE_FOR_loongson_psllw CODE_FOR_ashlv2si3
15823 #define CODE_FOR_loongson_psrlh CODE_FOR_lshrv4hi3
15824 #define CODE_FOR_loongson_psrlw CODE_FOR_lshrv2si3
15825 #define CODE_FOR_loongson_psrah CODE_FOR_ashrv4hi3
15826 #define CODE_FOR_loongson_psraw CODE_FOR_ashrv2si3
15827 #define CODE_FOR_loongson_psubw CODE_FOR_subv2si3
15828 #define CODE_FOR_loongson_psubh CODE_FOR_subv4hi3
15829 #define CODE_FOR_loongson_psubb CODE_FOR_subv8qi3
15830 #define CODE_FOR_loongson_psubsh CODE_FOR_sssubv4hi3
15831 #define CODE_FOR_loongson_psubsb CODE_FOR_sssubv8qi3
15832 #define CODE_FOR_loongson_psubush CODE_FOR_ussubv4hi3
15833 #define CODE_FOR_loongson_psubusb CODE_FOR_ussubv8qi3
15835 #define CODE_FOR_msa_adds_s_b CODE_FOR_ssaddv16qi3
15836 #define CODE_FOR_msa_adds_s_h CODE_FOR_ssaddv8hi3
15837 #define CODE_FOR_msa_adds_s_w CODE_FOR_ssaddv4si3
15838 #define CODE_FOR_msa_adds_s_d CODE_FOR_ssaddv2di3
15839 #define CODE_FOR_msa_adds_u_b CODE_FOR_usaddv16qi3
15840 #define CODE_FOR_msa_adds_u_h CODE_FOR_usaddv8hi3
15841 #define CODE_FOR_msa_adds_u_w CODE_FOR_usaddv4si3
15842 #define CODE_FOR_msa_adds_u_d CODE_FOR_usaddv2di3
15843 #define CODE_FOR_msa_addv_b CODE_FOR_addv16qi3
15844 #define CODE_FOR_msa_addv_h CODE_FOR_addv8hi3
15845 #define CODE_FOR_msa_addv_w CODE_FOR_addv4si3
15846 #define CODE_FOR_msa_addv_d CODE_FOR_addv2di3
15847 #define CODE_FOR_msa_addvi_b CODE_FOR_addv16qi3
15848 #define CODE_FOR_msa_addvi_h CODE_FOR_addv8hi3
15849 #define CODE_FOR_msa_addvi_w CODE_FOR_addv4si3
15850 #define CODE_FOR_msa_addvi_d CODE_FOR_addv2di3
15851 #define CODE_FOR_msa_and_v CODE_FOR_andv16qi3
15852 #define CODE_FOR_msa_andi_b CODE_FOR_andv16qi3
15853 #define CODE_FOR_msa_bmnz_v CODE_FOR_msa_bmnz_b
15854 #define CODE_FOR_msa_bmnzi_b CODE_FOR_msa_bmnz_b
15855 #define CODE_FOR_msa_bmz_v CODE_FOR_msa_bmz_b
15856 #define CODE_FOR_msa_bmzi_b CODE_FOR_msa_bmz_b
15857 #define CODE_FOR_msa_bnz_v CODE_FOR_msa_bnz_v_b
15858 #define CODE_FOR_msa_bz_v CODE_FOR_msa_bz_v_b
15859 #define CODE_FOR_msa_bsel_v CODE_FOR_msa_bsel_b
15860 #define CODE_FOR_msa_bseli_b CODE_FOR_msa_bsel_b
15861 #define CODE_FOR_msa_ceqi_b CODE_FOR_msa_ceq_b
15862 #define CODE_FOR_msa_ceqi_h CODE_FOR_msa_ceq_h
15863 #define CODE_FOR_msa_ceqi_w CODE_FOR_msa_ceq_w
15864 #define CODE_FOR_msa_ceqi_d CODE_FOR_msa_ceq_d
15865 #define CODE_FOR_msa_clti_s_b CODE_FOR_msa_clt_s_b
15866 #define CODE_FOR_msa_clti_s_h CODE_FOR_msa_clt_s_h
15867 #define CODE_FOR_msa_clti_s_w CODE_FOR_msa_clt_s_w
15868 #define CODE_FOR_msa_clti_s_d CODE_FOR_msa_clt_s_d
15869 #define CODE_FOR_msa_clti_u_b CODE_FOR_msa_clt_u_b
15870 #define CODE_FOR_msa_clti_u_h CODE_FOR_msa_clt_u_h
15871 #define CODE_FOR_msa_clti_u_w CODE_FOR_msa_clt_u_w
15872 #define CODE_FOR_msa_clti_u_d CODE_FOR_msa_clt_u_d
15873 #define CODE_FOR_msa_clei_s_b CODE_FOR_msa_cle_s_b
15874 #define CODE_FOR_msa_clei_s_h CODE_FOR_msa_cle_s_h
15875 #define CODE_FOR_msa_clei_s_w CODE_FOR_msa_cle_s_w
15876 #define CODE_FOR_msa_clei_s_d CODE_FOR_msa_cle_s_d
15877 #define CODE_FOR_msa_clei_u_b CODE_FOR_msa_cle_u_b
15878 #define CODE_FOR_msa_clei_u_h CODE_FOR_msa_cle_u_h
15879 #define CODE_FOR_msa_clei_u_w CODE_FOR_msa_cle_u_w
15880 #define CODE_FOR_msa_clei_u_d CODE_FOR_msa_cle_u_d
15881 #define CODE_FOR_msa_div_s_b CODE_FOR_divv16qi3
15882 #define CODE_FOR_msa_div_s_h CODE_FOR_divv8hi3
15883 #define CODE_FOR_msa_div_s_w CODE_FOR_divv4si3
15884 #define CODE_FOR_msa_div_s_d CODE_FOR_divv2di3
15885 #define CODE_FOR_msa_div_u_b CODE_FOR_udivv16qi3
15886 #define CODE_FOR_msa_div_u_h CODE_FOR_udivv8hi3
15887 #define CODE_FOR_msa_div_u_w CODE_FOR_udivv4si3
15888 #define CODE_FOR_msa_div_u_d CODE_FOR_udivv2di3
15889 #define CODE_FOR_msa_fadd_w CODE_FOR_addv4sf3
15890 #define CODE_FOR_msa_fadd_d CODE_FOR_addv2df3
15891 #define CODE_FOR_msa_fexdo_w CODE_FOR_vec_pack_trunc_v2df
15892 #define CODE_FOR_msa_ftrunc_s_w CODE_FOR_fix_truncv4sfv4si2
15893 #define CODE_FOR_msa_ftrunc_s_d CODE_FOR_fix_truncv2dfv2di2
15894 #define CODE_FOR_msa_ftrunc_u_w CODE_FOR_fixuns_truncv4sfv4si2
15895 #define CODE_FOR_msa_ftrunc_u_d CODE_FOR_fixuns_truncv2dfv2di2
15896 #define CODE_FOR_msa_ffint_s_w CODE_FOR_floatv4siv4sf2
15897 #define CODE_FOR_msa_ffint_s_d CODE_FOR_floatv2div2df2
15898 #define CODE_FOR_msa_ffint_u_w CODE_FOR_floatunsv4siv4sf2
15899 #define CODE_FOR_msa_ffint_u_d CODE_FOR_floatunsv2div2df2
15900 #define CODE_FOR_msa_fsub_w CODE_FOR_subv4sf3
15901 #define CODE_FOR_msa_fsub_d CODE_FOR_subv2df3
15902 #define CODE_FOR_msa_fmadd_w CODE_FOR_fmav4sf4
15903 #define CODE_FOR_msa_fmadd_d CODE_FOR_fmav2df4
15904 #define CODE_FOR_msa_fmsub_w CODE_FOR_fnmav4sf4
15905 #define CODE_FOR_msa_fmsub_d CODE_FOR_fnmav2df4
15906 #define CODE_FOR_msa_fmul_w CODE_FOR_mulv4sf3
15907 #define CODE_FOR_msa_fmul_d CODE_FOR_mulv2df3
15908 #define CODE_FOR_msa_fdiv_w CODE_FOR_divv4sf3
15909 #define CODE_FOR_msa_fdiv_d CODE_FOR_divv2df3
15910 #define CODE_FOR_msa_fmax_w CODE_FOR_smaxv4sf3
15911 #define CODE_FOR_msa_fmax_d CODE_FOR_smaxv2df3
15912 #define CODE_FOR_msa_fmin_w CODE_FOR_sminv4sf3
15913 #define CODE_FOR_msa_fmin_d CODE_FOR_sminv2df3
15914 #define CODE_FOR_msa_fsqrt_w CODE_FOR_sqrtv4sf2
15915 #define CODE_FOR_msa_fsqrt_d CODE_FOR_sqrtv2df2
15916 #define CODE_FOR_msa_max_s_b CODE_FOR_smaxv16qi3
15917 #define CODE_FOR_msa_max_s_h CODE_FOR_smaxv8hi3
15918 #define CODE_FOR_msa_max_s_w CODE_FOR_smaxv4si3
15919 #define CODE_FOR_msa_max_s_d CODE_FOR_smaxv2di3
15920 #define CODE_FOR_msa_maxi_s_b CODE_FOR_smaxv16qi3
15921 #define CODE_FOR_msa_maxi_s_h CODE_FOR_smaxv8hi3
15922 #define CODE_FOR_msa_maxi_s_w CODE_FOR_smaxv4si3
15923 #define CODE_FOR_msa_maxi_s_d CODE_FOR_smaxv2di3
15924 #define CODE_FOR_msa_max_u_b CODE_FOR_umaxv16qi3
15925 #define CODE_FOR_msa_max_u_h CODE_FOR_umaxv8hi3
15926 #define CODE_FOR_msa_max_u_w CODE_FOR_umaxv4si3
15927 #define CODE_FOR_msa_max_u_d CODE_FOR_umaxv2di3
15928 #define CODE_FOR_msa_maxi_u_b CODE_FOR_umaxv16qi3
15929 #define CODE_FOR_msa_maxi_u_h CODE_FOR_umaxv8hi3
15930 #define CODE_FOR_msa_maxi_u_w CODE_FOR_umaxv4si3
15931 #define CODE_FOR_msa_maxi_u_d CODE_FOR_umaxv2di3
15932 #define CODE_FOR_msa_min_s_b CODE_FOR_sminv16qi3
15933 #define CODE_FOR_msa_min_s_h CODE_FOR_sminv8hi3
15934 #define CODE_FOR_msa_min_s_w CODE_FOR_sminv4si3
15935 #define CODE_FOR_msa_min_s_d CODE_FOR_sminv2di3
15936 #define CODE_FOR_msa_mini_s_b CODE_FOR_sminv16qi3
15937 #define CODE_FOR_msa_mini_s_h CODE_FOR_sminv8hi3
15938 #define CODE_FOR_msa_mini_s_w CODE_FOR_sminv4si3
15939 #define CODE_FOR_msa_mini_s_d CODE_FOR_sminv2di3
15940 #define CODE_FOR_msa_min_u_b CODE_FOR_uminv16qi3
15941 #define CODE_FOR_msa_min_u_h CODE_FOR_uminv8hi3
15942 #define CODE_FOR_msa_min_u_w CODE_FOR_uminv4si3
15943 #define CODE_FOR_msa_min_u_d CODE_FOR_uminv2di3
15944 #define CODE_FOR_msa_mini_u_b CODE_FOR_uminv16qi3
15945 #define CODE_FOR_msa_mini_u_h CODE_FOR_uminv8hi3
15946 #define CODE_FOR_msa_mini_u_w CODE_FOR_uminv4si3
15947 #define CODE_FOR_msa_mini_u_d CODE_FOR_uminv2di3
15948 #define CODE_FOR_msa_mod_s_b CODE_FOR_modv16qi3
15949 #define CODE_FOR_msa_mod_s_h CODE_FOR_modv8hi3
15950 #define CODE_FOR_msa_mod_s_w CODE_FOR_modv4si3
15951 #define CODE_FOR_msa_mod_s_d CODE_FOR_modv2di3
15952 #define CODE_FOR_msa_mod_u_b CODE_FOR_umodv16qi3
15953 #define CODE_FOR_msa_mod_u_h CODE_FOR_umodv8hi3
15954 #define CODE_FOR_msa_mod_u_w CODE_FOR_umodv4si3
15955 #define CODE_FOR_msa_mod_u_d CODE_FOR_umodv2di3
15956 #define CODE_FOR_msa_mod_s_b CODE_FOR_modv16qi3
15957 #define CODE_FOR_msa_mod_s_h CODE_FOR_modv8hi3
15958 #define CODE_FOR_msa_mod_s_w CODE_FOR_modv4si3
15959 #define CODE_FOR_msa_mod_s_d CODE_FOR_modv2di3
15960 #define CODE_FOR_msa_mod_u_b CODE_FOR_umodv16qi3
15961 #define CODE_FOR_msa_mod_u_h CODE_FOR_umodv8hi3
15962 #define CODE_FOR_msa_mod_u_w CODE_FOR_umodv4si3
15963 #define CODE_FOR_msa_mod_u_d CODE_FOR_umodv2di3
15964 #define CODE_FOR_msa_mulv_b CODE_FOR_mulv16qi3
15965 #define CODE_FOR_msa_mulv_h CODE_FOR_mulv8hi3
15966 #define CODE_FOR_msa_mulv_w CODE_FOR_mulv4si3
15967 #define CODE_FOR_msa_mulv_d CODE_FOR_mulv2di3
15968 #define CODE_FOR_msa_nlzc_b CODE_FOR_clzv16qi2
15969 #define CODE_FOR_msa_nlzc_h CODE_FOR_clzv8hi2
15970 #define CODE_FOR_msa_nlzc_w CODE_FOR_clzv4si2
15971 #define CODE_FOR_msa_nlzc_d CODE_FOR_clzv2di2
15972 #define CODE_FOR_msa_nor_v CODE_FOR_msa_nor_b
15973 #define CODE_FOR_msa_or_v CODE_FOR_iorv16qi3
15974 #define CODE_FOR_msa_ori_b CODE_FOR_iorv16qi3
15975 #define CODE_FOR_msa_nori_b CODE_FOR_msa_nor_b
15976 #define CODE_FOR_msa_pcnt_b CODE_FOR_popcountv16qi2
15977 #define CODE_FOR_msa_pcnt_h CODE_FOR_popcountv8hi2
15978 #define CODE_FOR_msa_pcnt_w CODE_FOR_popcountv4si2
15979 #define CODE_FOR_msa_pcnt_d CODE_FOR_popcountv2di2
15980 #define CODE_FOR_msa_xor_v CODE_FOR_xorv16qi3
15981 #define CODE_FOR_msa_xori_b CODE_FOR_xorv16qi3
15982 #define CODE_FOR_msa_sll_b CODE_FOR_vashlv16qi3
15983 #define CODE_FOR_msa_sll_h CODE_FOR_vashlv8hi3
15984 #define CODE_FOR_msa_sll_w CODE_FOR_vashlv4si3
15985 #define CODE_FOR_msa_sll_d CODE_FOR_vashlv2di3
15986 #define CODE_FOR_msa_slli_b CODE_FOR_vashlv16qi3
15987 #define CODE_FOR_msa_slli_h CODE_FOR_vashlv8hi3
15988 #define CODE_FOR_msa_slli_w CODE_FOR_vashlv4si3
15989 #define CODE_FOR_msa_slli_d CODE_FOR_vashlv2di3
15990 #define CODE_FOR_msa_sra_b CODE_FOR_vashrv16qi3
15991 #define CODE_FOR_msa_sra_h CODE_FOR_vashrv8hi3
15992 #define CODE_FOR_msa_sra_w CODE_FOR_vashrv4si3
15993 #define CODE_FOR_msa_sra_d CODE_FOR_vashrv2di3
15994 #define CODE_FOR_msa_srai_b CODE_FOR_vashrv16qi3
15995 #define CODE_FOR_msa_srai_h CODE_FOR_vashrv8hi3
15996 #define CODE_FOR_msa_srai_w CODE_FOR_vashrv4si3
15997 #define CODE_FOR_msa_srai_d CODE_FOR_vashrv2di3
15998 #define CODE_FOR_msa_srl_b CODE_FOR_vlshrv16qi3
15999 #define CODE_FOR_msa_srl_h CODE_FOR_vlshrv8hi3
16000 #define CODE_FOR_msa_srl_w CODE_FOR_vlshrv4si3
16001 #define CODE_FOR_msa_srl_d CODE_FOR_vlshrv2di3
16002 #define CODE_FOR_msa_srli_b CODE_FOR_vlshrv16qi3
16003 #define CODE_FOR_msa_srli_h CODE_FOR_vlshrv8hi3
16004 #define CODE_FOR_msa_srli_w CODE_FOR_vlshrv4si3
16005 #define CODE_FOR_msa_srli_d CODE_FOR_vlshrv2di3
16006 #define CODE_FOR_msa_subv_b CODE_FOR_subv16qi3
16007 #define CODE_FOR_msa_subv_h CODE_FOR_subv8hi3
16008 #define CODE_FOR_msa_subv_w CODE_FOR_subv4si3
16009 #define CODE_FOR_msa_subv_d CODE_FOR_subv2di3
16010 #define CODE_FOR_msa_subvi_b CODE_FOR_subv16qi3
16011 #define CODE_FOR_msa_subvi_h CODE_FOR_subv8hi3
16012 #define CODE_FOR_msa_subvi_w CODE_FOR_subv4si3
16013 #define CODE_FOR_msa_subvi_d CODE_FOR_subv2di3
16015 #define CODE_FOR_msa_move_v CODE_FOR_movv16qi
16017 #define CODE_FOR_msa_vshf_b CODE_FOR_vec_permv16qi
16018 #define CODE_FOR_msa_vshf_h CODE_FOR_vec_permv8hi
16019 #define CODE_FOR_msa_vshf_w CODE_FOR_vec_permv4si
16020 #define CODE_FOR_msa_vshf_d CODE_FOR_vec_permv2di
16022 #define CODE_FOR_msa_ilvod_d CODE_FOR_msa_ilvl_d
16023 #define CODE_FOR_msa_ilvev_d CODE_FOR_msa_ilvr_d
16024 #define CODE_FOR_msa_pckod_d CODE_FOR_msa_ilvl_d
16025 #define CODE_FOR_msa_pckev_d CODE_FOR_msa_ilvr_d
16027 #define CODE_FOR_msa_ldi_b CODE_FOR_msa_ldiv16qi
16028 #define CODE_FOR_msa_ldi_h CODE_FOR_msa_ldiv8hi
16029 #define CODE_FOR_msa_ldi_w CODE_FOR_msa_ldiv4si
16030 #define CODE_FOR_msa_ldi_d CODE_FOR_msa_ldiv2di
16032 static const struct mips_builtin_description mips_builtins[] = {
16033 #define MIPS_GET_FCSR 0
16034 DIRECT_BUILTIN (get_fcsr, MIPS_USI_FTYPE_VOID, hard_float),
16035 #define MIPS_SET_FCSR 1
16036 DIRECT_NO_TARGET_BUILTIN (set_fcsr, MIPS_VOID_FTYPE_USI, hard_float),
16038 DIRECT_BUILTIN_PURE (pll_ps, MIPS_V2SF_FTYPE_V2SF_V2SF, paired_single),
16039 DIRECT_BUILTIN_PURE (pul_ps, MIPS_V2SF_FTYPE_V2SF_V2SF, paired_single),
16040 DIRECT_BUILTIN_PURE (plu_ps, MIPS_V2SF_FTYPE_V2SF_V2SF, paired_single),
16041 DIRECT_BUILTIN_PURE (puu_ps, MIPS_V2SF_FTYPE_V2SF_V2SF, paired_single),
16042 DIRECT_BUILTIN_PURE (cvt_ps_s, MIPS_V2SF_FTYPE_SF_SF, paired_single),
16043 DIRECT_BUILTIN_PURE (cvt_s_pl, MIPS_SF_FTYPE_V2SF, paired_single),
16044 DIRECT_BUILTIN_PURE (cvt_s_pu, MIPS_SF_FTYPE_V2SF, paired_single),
16045 DIRECT_BUILTIN_PURE (abs_ps, MIPS_V2SF_FTYPE_V2SF, paired_single),
16047 DIRECT_BUILTIN_PURE (alnv_ps, MIPS_V2SF_FTYPE_V2SF_V2SF_INT, paired_single),
16048 DIRECT_BUILTIN_PURE (addr_ps, MIPS_V2SF_FTYPE_V2SF_V2SF, mips3d),
16049 DIRECT_BUILTIN_PURE (mulr_ps, MIPS_V2SF_FTYPE_V2SF_V2SF, mips3d),
16050 DIRECT_BUILTIN_PURE (cvt_pw_ps, MIPS_V2SF_FTYPE_V2SF, mips3d),
16051 DIRECT_BUILTIN_PURE (cvt_ps_pw, MIPS_V2SF_FTYPE_V2SF, mips3d),
16053 DIRECT_BUILTIN_PURE (recip1_s, MIPS_SF_FTYPE_SF, mips3d),
16054 DIRECT_BUILTIN_PURE (recip1_d, MIPS_DF_FTYPE_DF, mips3d),
16055 DIRECT_BUILTIN_PURE (recip1_ps, MIPS_V2SF_FTYPE_V2SF, mips3d),
16056 DIRECT_BUILTIN_PURE (recip2_s, MIPS_SF_FTYPE_SF_SF, mips3d),
16057 DIRECT_BUILTIN_PURE (recip2_d, MIPS_DF_FTYPE_DF_DF, mips3d),
16058 DIRECT_BUILTIN_PURE (recip2_ps, MIPS_V2SF_FTYPE_V2SF_V2SF, mips3d),
16060 DIRECT_BUILTIN_PURE (rsqrt1_s, MIPS_SF_FTYPE_SF, mips3d),
16061 DIRECT_BUILTIN_PURE (rsqrt1_d, MIPS_DF_FTYPE_DF, mips3d),
16062 DIRECT_BUILTIN_PURE (rsqrt1_ps, MIPS_V2SF_FTYPE_V2SF, mips3d),
16063 DIRECT_BUILTIN_PURE (rsqrt2_s, MIPS_SF_FTYPE_SF_SF, mips3d),
16064 DIRECT_BUILTIN_PURE (rsqrt2_d, MIPS_DF_FTYPE_DF_DF, mips3d),
16065 DIRECT_BUILTIN_PURE (rsqrt2_ps, MIPS_V2SF_FTYPE_V2SF_V2SF, mips3d),
16067 MIPS_FP_CONDITIONS (CMP_BUILTINS),
16069 /* Built-in functions for the SB-1 processor. */
16070 DIRECT_BUILTIN (sqrt_ps, MIPS_V2SF_FTYPE_V2SF, sb1_paired_single),
16072 /* Built-in functions for the DSP ASE (32-bit and 64-bit). */
16073 DIRECT_BUILTIN_PURE (addq_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, dsp),
16074 DIRECT_BUILTIN_PURE (addq_s_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, dsp),
16075 DIRECT_BUILTIN_PURE (addq_s_w, MIPS_SI_FTYPE_SI_SI, dsp),
16076 DIRECT_BUILTIN_PURE (addu_qb, MIPS_V4QI_FTYPE_V4QI_V4QI, dsp),
16077 DIRECT_BUILTIN_PURE (addu_s_qb, MIPS_V4QI_FTYPE_V4QI_V4QI, dsp),
16078 DIRECT_BUILTIN_PURE (subq_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, dsp),
16079 DIRECT_BUILTIN_PURE (subq_s_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, dsp),
16080 DIRECT_BUILTIN_PURE (subq_s_w, MIPS_SI_FTYPE_SI_SI, dsp),
16081 DIRECT_BUILTIN_PURE (subu_qb, MIPS_V4QI_FTYPE_V4QI_V4QI, dsp),
16082 DIRECT_BUILTIN_PURE (subu_s_qb, MIPS_V4QI_FTYPE_V4QI_V4QI, dsp),
16083 DIRECT_BUILTIN_PURE (addsc, MIPS_SI_FTYPE_SI_SI, dsp),
16084 DIRECT_BUILTIN_PURE (addwc, MIPS_SI_FTYPE_SI_SI, dsp),
16085 DIRECT_BUILTIN_PURE (modsub, MIPS_SI_FTYPE_SI_SI, dsp),
16086 DIRECT_BUILTIN_PURE (raddu_w_qb, MIPS_SI_FTYPE_V4QI, dsp),
16087 DIRECT_BUILTIN_PURE (absq_s_ph, MIPS_V2HI_FTYPE_V2HI, dsp),
16088 DIRECT_BUILTIN_PURE (absq_s_w, MIPS_SI_FTYPE_SI, dsp),
16089 DIRECT_BUILTIN_PURE (precrq_qb_ph, MIPS_V4QI_FTYPE_V2HI_V2HI, dsp),
16090 DIRECT_BUILTIN_PURE (precrq_ph_w, MIPS_V2HI_FTYPE_SI_SI, dsp),
16091 DIRECT_BUILTIN_PURE (precrq_rs_ph_w, MIPS_V2HI_FTYPE_SI_SI, dsp),
16092 DIRECT_BUILTIN_PURE (precrqu_s_qb_ph, MIPS_V4QI_FTYPE_V2HI_V2HI, dsp),
16093 DIRECT_BUILTIN_PURE (preceq_w_phl, MIPS_SI_FTYPE_V2HI, dsp),
16094 DIRECT_BUILTIN_PURE (preceq_w_phr, MIPS_SI_FTYPE_V2HI, dsp),
16095 DIRECT_BUILTIN_PURE (precequ_ph_qbl, MIPS_V2HI_FTYPE_V4QI, dsp),
16096 DIRECT_BUILTIN_PURE (precequ_ph_qbr, MIPS_V2HI_FTYPE_V4QI, dsp),
16097 DIRECT_BUILTIN_PURE (precequ_ph_qbla, MIPS_V2HI_FTYPE_V4QI, dsp),
16098 DIRECT_BUILTIN_PURE (precequ_ph_qbra, MIPS_V2HI_FTYPE_V4QI, dsp),
16099 DIRECT_BUILTIN_PURE (preceu_ph_qbl, MIPS_V2HI_FTYPE_V4QI, dsp),
16100 DIRECT_BUILTIN_PURE (preceu_ph_qbr, MIPS_V2HI_FTYPE_V4QI, dsp),
16101 DIRECT_BUILTIN_PURE (preceu_ph_qbla, MIPS_V2HI_FTYPE_V4QI, dsp),
16102 DIRECT_BUILTIN_PURE (preceu_ph_qbra, MIPS_V2HI_FTYPE_V4QI, dsp),
16103 DIRECT_BUILTIN_PURE (shll_qb, MIPS_V4QI_FTYPE_V4QI_SI, dsp),
16104 DIRECT_BUILTIN_PURE (shll_ph, MIPS_V2HI_FTYPE_V2HI_SI, dsp),
16105 DIRECT_BUILTIN_PURE (shll_s_ph, MIPS_V2HI_FTYPE_V2HI_SI, dsp),
16106 DIRECT_BUILTIN_PURE (shll_s_w, MIPS_SI_FTYPE_SI_SI, dsp),
16107 DIRECT_BUILTIN_PURE (shrl_qb, MIPS_V4QI_FTYPE_V4QI_SI, dsp),
16108 DIRECT_BUILTIN_PURE (shra_ph, MIPS_V2HI_FTYPE_V2HI_SI, dsp),
16109 DIRECT_BUILTIN_PURE (shra_r_ph, MIPS_V2HI_FTYPE_V2HI_SI, dsp),
16110 DIRECT_BUILTIN_PURE (shra_r_w, MIPS_SI_FTYPE_SI_SI, dsp),
16111 DIRECT_BUILTIN_PURE (muleu_s_ph_qbl, MIPS_V2HI_FTYPE_V4QI_V2HI, dsp),
16112 DIRECT_BUILTIN_PURE (muleu_s_ph_qbr, MIPS_V2HI_FTYPE_V4QI_V2HI, dsp),
16113 DIRECT_BUILTIN_PURE (mulq_rs_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, dsp),
16114 DIRECT_BUILTIN_PURE (muleq_s_w_phl, MIPS_SI_FTYPE_V2HI_V2HI, dsp),
16115 DIRECT_BUILTIN_PURE (muleq_s_w_phr, MIPS_SI_FTYPE_V2HI_V2HI, dsp),
16116 DIRECT_BUILTIN_PURE (bitrev, MIPS_SI_FTYPE_SI, dsp),
16117 DIRECT_BUILTIN_PURE (insv, MIPS_SI_FTYPE_SI_SI, dsp),
16118 DIRECT_BUILTIN_PURE (repl_qb, MIPS_V4QI_FTYPE_SI, dsp),
16119 DIRECT_BUILTIN_PURE (repl_ph, MIPS_V2HI_FTYPE_SI, dsp),
16120 DIRECT_NO_TARGET_BUILTIN (cmpu_eq_qb, MIPS_VOID_FTYPE_V4QI_V4QI, dsp),
16121 DIRECT_NO_TARGET_BUILTIN (cmpu_lt_qb, MIPS_VOID_FTYPE_V4QI_V4QI, dsp),
16122 DIRECT_NO_TARGET_BUILTIN (cmpu_le_qb, MIPS_VOID_FTYPE_V4QI_V4QI, dsp),
16123 DIRECT_BUILTIN_PURE (cmpgu_eq_qb, MIPS_SI_FTYPE_V4QI_V4QI, dsp),
16124 DIRECT_BUILTIN_PURE (cmpgu_lt_qb, MIPS_SI_FTYPE_V4QI_V4QI, dsp),
16125 DIRECT_BUILTIN_PURE (cmpgu_le_qb, MIPS_SI_FTYPE_V4QI_V4QI, dsp),
16126 DIRECT_NO_TARGET_BUILTIN (cmp_eq_ph, MIPS_VOID_FTYPE_V2HI_V2HI, dsp),
16127 DIRECT_NO_TARGET_BUILTIN (cmp_lt_ph, MIPS_VOID_FTYPE_V2HI_V2HI, dsp),
16128 DIRECT_NO_TARGET_BUILTIN (cmp_le_ph, MIPS_VOID_FTYPE_V2HI_V2HI, dsp),
16129 DIRECT_BUILTIN_PURE (pick_qb, MIPS_V4QI_FTYPE_V4QI_V4QI, dsp),
16130 DIRECT_BUILTIN_PURE (pick_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, dsp),
16131 DIRECT_BUILTIN_PURE (packrl_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, dsp),
16132 DIRECT_NO_TARGET_BUILTIN (wrdsp, MIPS_VOID_FTYPE_SI_SI, dsp),
16133 DIRECT_BUILTIN_PURE (rddsp, MIPS_SI_FTYPE_SI, dsp),
16134 DIRECT_BUILTIN (lbux, MIPS_SI_FTYPE_POINTER_SI, dsp),
16135 DIRECT_BUILTIN (lhx, MIPS_SI_FTYPE_POINTER_SI, dsp),
16136 DIRECT_BUILTIN (lwx, MIPS_SI_FTYPE_POINTER_SI, dsp),
16137 BPOSGE_BUILTIN (32, dsp),
16139 /* The following are for the MIPS DSP ASE REV 2 (32-bit and 64-bit). */
16140 DIRECT_BUILTIN_PURE (absq_s_qb, MIPS_V4QI_FTYPE_V4QI, dspr2),
16141 DIRECT_BUILTIN_PURE (addu_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, dspr2),
16142 DIRECT_BUILTIN_PURE (addu_s_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, dspr2),
16143 DIRECT_BUILTIN_PURE (adduh_qb, MIPS_V4QI_FTYPE_V4QI_V4QI, dspr2),
16144 DIRECT_BUILTIN_PURE (adduh_r_qb, MIPS_V4QI_FTYPE_V4QI_V4QI, dspr2),
16145 DIRECT_BUILTIN_PURE (append, MIPS_SI_FTYPE_SI_SI_SI, dspr2),
16146 DIRECT_BUILTIN_PURE (balign, MIPS_SI_FTYPE_SI_SI_SI, dspr2),
16147 DIRECT_BUILTIN_PURE (cmpgdu_eq_qb, MIPS_SI_FTYPE_V4QI_V4QI, dspr2),
16148 DIRECT_BUILTIN_PURE (cmpgdu_lt_qb, MIPS_SI_FTYPE_V4QI_V4QI, dspr2),
16149 DIRECT_BUILTIN_PURE (cmpgdu_le_qb, MIPS_SI_FTYPE_V4QI_V4QI, dspr2),
16150 DIRECT_BUILTIN_PURE (mul_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, dspr2),
16151 DIRECT_BUILTIN_PURE (mul_s_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, dspr2),
16152 DIRECT_BUILTIN_PURE (mulq_rs_w, MIPS_SI_FTYPE_SI_SI, dspr2),
16153 DIRECT_BUILTIN_PURE (mulq_s_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, dspr2),
16154 DIRECT_BUILTIN_PURE (mulq_s_w, MIPS_SI_FTYPE_SI_SI, dspr2),
16155 DIRECT_BUILTIN_PURE (precr_qb_ph, MIPS_V4QI_FTYPE_V2HI_V2HI, dspr2),
16156 DIRECT_BUILTIN_PURE (precr_sra_ph_w, MIPS_V2HI_FTYPE_SI_SI_SI, dspr2),
16157 DIRECT_BUILTIN_PURE (precr_sra_r_ph_w, MIPS_V2HI_FTYPE_SI_SI_SI, dspr2),
16158 DIRECT_BUILTIN_PURE (prepend, MIPS_SI_FTYPE_SI_SI_SI, dspr2),
16159 DIRECT_BUILTIN_PURE (shra_qb, MIPS_V4QI_FTYPE_V4QI_SI, dspr2),
16160 DIRECT_BUILTIN_PURE (shra_r_qb, MIPS_V4QI_FTYPE_V4QI_SI, dspr2),
16161 DIRECT_BUILTIN_PURE (shrl_ph, MIPS_V2HI_FTYPE_V2HI_SI, dspr2),
16162 DIRECT_BUILTIN_PURE (subu_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, dspr2),
16163 DIRECT_BUILTIN_PURE (subu_s_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, dspr2),
16164 DIRECT_BUILTIN_PURE (subuh_qb, MIPS_V4QI_FTYPE_V4QI_V4QI, dspr2),
16165 DIRECT_BUILTIN_PURE (subuh_r_qb, MIPS_V4QI_FTYPE_V4QI_V4QI, dspr2),
16166 DIRECT_BUILTIN_PURE (addqh_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, dspr2),
16167 DIRECT_BUILTIN_PURE (addqh_r_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, dspr2),
16168 DIRECT_BUILTIN_PURE (addqh_w, MIPS_SI_FTYPE_SI_SI, dspr2),
16169 DIRECT_BUILTIN_PURE (addqh_r_w, MIPS_SI_FTYPE_SI_SI, dspr2),
16170 DIRECT_BUILTIN_PURE (subqh_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, dspr2),
16171 DIRECT_BUILTIN_PURE (subqh_r_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, dspr2),
16172 DIRECT_BUILTIN_PURE (subqh_w, MIPS_SI_FTYPE_SI_SI, dspr2),
16173 DIRECT_BUILTIN_PURE (subqh_r_w, MIPS_SI_FTYPE_SI_SI, dspr2),
16175 /* Built-in functions for the DSP ASE (32-bit only). */
16176 DIRECT_BUILTIN_PURE (dpau_h_qbl, MIPS_DI_FTYPE_DI_V4QI_V4QI, dsp_32),
16177 DIRECT_BUILTIN_PURE (dpau_h_qbr, MIPS_DI_FTYPE_DI_V4QI_V4QI, dsp_32),
16178 DIRECT_BUILTIN_PURE (dpsu_h_qbl, MIPS_DI_FTYPE_DI_V4QI_V4QI, dsp_32),
16179 DIRECT_BUILTIN_PURE (dpsu_h_qbr, MIPS_DI_FTYPE_DI_V4QI_V4QI, dsp_32),
16180 DIRECT_BUILTIN_PURE (dpaq_s_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, dsp_32),
16181 DIRECT_BUILTIN_PURE (dpsq_s_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, dsp_32),
16182 DIRECT_BUILTIN_PURE (mulsaq_s_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, dsp_32),
16183 DIRECT_BUILTIN_PURE (dpaq_sa_l_w, MIPS_DI_FTYPE_DI_SI_SI, dsp_32),
16184 DIRECT_BUILTIN_PURE (dpsq_sa_l_w, MIPS_DI_FTYPE_DI_SI_SI, dsp_32),
16185 DIRECT_BUILTIN_PURE (maq_s_w_phl, MIPS_DI_FTYPE_DI_V2HI_V2HI, dsp_32),
16186 DIRECT_BUILTIN_PURE (maq_s_w_phr, MIPS_DI_FTYPE_DI_V2HI_V2HI, dsp_32),
16187 DIRECT_BUILTIN_PURE (maq_sa_w_phl, MIPS_DI_FTYPE_DI_V2HI_V2HI, dsp_32),
16188 DIRECT_BUILTIN_PURE (maq_sa_w_phr, MIPS_DI_FTYPE_DI_V2HI_V2HI, dsp_32),
16189 DIRECT_BUILTIN_PURE (extr_w, MIPS_SI_FTYPE_DI_SI, dsp_32),
16190 DIRECT_BUILTIN_PURE (extr_r_w, MIPS_SI_FTYPE_DI_SI, dsp_32),
16191 DIRECT_BUILTIN_PURE (extr_rs_w, MIPS_SI_FTYPE_DI_SI, dsp_32),
16192 DIRECT_BUILTIN_PURE (extr_s_h, MIPS_SI_FTYPE_DI_SI, dsp_32),
16193 DIRECT_BUILTIN_PURE (extp, MIPS_SI_FTYPE_DI_SI, dsp_32),
16194 DIRECT_BUILTIN_PURE (extpdp, MIPS_SI_FTYPE_DI_SI, dsp_32),
16195 DIRECT_BUILTIN_PURE (shilo, MIPS_DI_FTYPE_DI_SI, dsp_32),
16196 DIRECT_BUILTIN_PURE (mthlip, MIPS_DI_FTYPE_DI_SI, dsp_32),
16197 DIRECT_BUILTIN_PURE (madd, MIPS_DI_FTYPE_DI_SI_SI, dsp_32),
16198 DIRECT_BUILTIN_PURE (maddu, MIPS_DI_FTYPE_DI_USI_USI, dsp_32),
16199 DIRECT_BUILTIN_PURE (msub, MIPS_DI_FTYPE_DI_SI_SI, dsp_32),
16200 DIRECT_BUILTIN_PURE (msubu, MIPS_DI_FTYPE_DI_USI_USI, dsp_32),
16201 DIRECT_BUILTIN_PURE (mult, MIPS_DI_FTYPE_SI_SI, dsp_32),
16202 DIRECT_BUILTIN_PURE (multu, MIPS_DI_FTYPE_USI_USI, dsp_32),
16204 /* Built-in functions for the DSP ASE (64-bit only). */
16205 DIRECT_BUILTIN (ldx, MIPS_DI_FTYPE_POINTER_SI, dsp_64),
16207 /* The following are for the MIPS DSP ASE REV 2 (32-bit only). */
16208 DIRECT_BUILTIN_PURE (dpa_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, dspr2_32),
16209 DIRECT_BUILTIN_PURE (dps_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, dspr2_32),
16210 DIRECT_BUILTIN_PURE (mulsa_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, dspr2_32),
16211 DIRECT_BUILTIN_PURE (dpax_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, dspr2_32),
16212 DIRECT_BUILTIN_PURE (dpsx_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, dspr2_32),
16213 DIRECT_BUILTIN_PURE (dpaqx_s_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, dspr2_32),
16214 DIRECT_BUILTIN_PURE (dpaqx_sa_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, dspr2_32),
16215 DIRECT_BUILTIN_PURE (dpsqx_s_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, dspr2_32),
16216 DIRECT_BUILTIN_PURE (dpsqx_sa_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, dspr2_32),
16218 /* Builtin functions for ST Microelectronics Loongson-2E/2F cores. */
16219 LOONGSON_BUILTIN (packsswh, MIPS_V4HI_FTYPE_V2SI_V2SI),
16220 LOONGSON_BUILTIN (packsshb, MIPS_V8QI_FTYPE_V4HI_V4HI),
16221 LOONGSON_BUILTIN (packushb, MIPS_UV8QI_FTYPE_UV4HI_UV4HI),
16222 LOONGSON_BUILTIN_SUFFIX (paddw, u, MIPS_UV2SI_FTYPE_UV2SI_UV2SI),
16223 LOONGSON_BUILTIN_SUFFIX (paddh, u, MIPS_UV4HI_FTYPE_UV4HI_UV4HI),
16224 LOONGSON_BUILTIN_SUFFIX (paddb, u, MIPS_UV8QI_FTYPE_UV8QI_UV8QI),
16225 LOONGSON_BUILTIN_SUFFIX (paddw, s, MIPS_V2SI_FTYPE_V2SI_V2SI),
16226 LOONGSON_BUILTIN_SUFFIX (paddh, s, MIPS_V4HI_FTYPE_V4HI_V4HI),
16227 LOONGSON_BUILTIN_SUFFIX (paddb, s, MIPS_V8QI_FTYPE_V8QI_V8QI),
16228 LOONGSON_BUILTIN_SUFFIX (paddd, u, MIPS_UDI_FTYPE_UDI_UDI),
16229 LOONGSON_BUILTIN_SUFFIX (paddd, s, MIPS_DI_FTYPE_DI_DI),
16230 LOONGSON_BUILTIN (paddsh, MIPS_V4HI_FTYPE_V4HI_V4HI),
16231 LOONGSON_BUILTIN (paddsb, MIPS_V8QI_FTYPE_V8QI_V8QI),
16232 LOONGSON_BUILTIN (paddush, MIPS_UV4HI_FTYPE_UV4HI_UV4HI),
16233 LOONGSON_BUILTIN (paddusb, MIPS_UV8QI_FTYPE_UV8QI_UV8QI),
16234 LOONGSON_BUILTIN_ALIAS (pandn_d, pandn_ud, MIPS_UDI_FTYPE_UDI_UDI),
16235 LOONGSON_BUILTIN_ALIAS (pandn_w, pandn_uw, MIPS_UV2SI_FTYPE_UV2SI_UV2SI),
16236 LOONGSON_BUILTIN_ALIAS (pandn_h, pandn_uh, MIPS_UV4HI_FTYPE_UV4HI_UV4HI),
16237 LOONGSON_BUILTIN_ALIAS (pandn_b, pandn_ub, MIPS_UV8QI_FTYPE_UV8QI_UV8QI),
16238 LOONGSON_BUILTIN_ALIAS (pandn_d, pandn_sd, MIPS_DI_FTYPE_DI_DI),
16239 LOONGSON_BUILTIN_ALIAS (pandn_w, pandn_sw, MIPS_V2SI_FTYPE_V2SI_V2SI),
16240 LOONGSON_BUILTIN_ALIAS (pandn_h, pandn_sh, MIPS_V4HI_FTYPE_V4HI_V4HI),
16241 LOONGSON_BUILTIN_ALIAS (pandn_b, pandn_sb, MIPS_V8QI_FTYPE_V8QI_V8QI),
16242 LOONGSON_BUILTIN (pavgh, MIPS_UV4HI_FTYPE_UV4HI_UV4HI),
16243 LOONGSON_BUILTIN (pavgb, MIPS_UV8QI_FTYPE_UV8QI_UV8QI),
16244 LOONGSON_BUILTIN_SUFFIX (pcmpeqw, u, MIPS_UV2SI_FTYPE_UV2SI_UV2SI),
16245 LOONGSON_BUILTIN_SUFFIX (pcmpeqh, u, MIPS_UV4HI_FTYPE_UV4HI_UV4HI),
16246 LOONGSON_BUILTIN_SUFFIX (pcmpeqb, u, MIPS_UV8QI_FTYPE_UV8QI_UV8QI),
16247 LOONGSON_BUILTIN_SUFFIX (pcmpeqw, s, MIPS_V2SI_FTYPE_V2SI_V2SI),
16248 LOONGSON_BUILTIN_SUFFIX (pcmpeqh, s, MIPS_V4HI_FTYPE_V4HI_V4HI),
16249 LOONGSON_BUILTIN_SUFFIX (pcmpeqb, s, MIPS_V8QI_FTYPE_V8QI_V8QI),
16250 LOONGSON_BUILTIN_SUFFIX (pcmpgtw, u, MIPS_UV2SI_FTYPE_UV2SI_UV2SI),
16251 LOONGSON_BUILTIN_SUFFIX (pcmpgth, u, MIPS_UV4HI_FTYPE_UV4HI_UV4HI),
16252 LOONGSON_BUILTIN_SUFFIX (pcmpgtb, u, MIPS_UV8QI_FTYPE_UV8QI_UV8QI),
16253 LOONGSON_BUILTIN_SUFFIX (pcmpgtw, s, MIPS_V2SI_FTYPE_V2SI_V2SI),
16254 LOONGSON_BUILTIN_SUFFIX (pcmpgth, s, MIPS_V4HI_FTYPE_V4HI_V4HI),
16255 LOONGSON_BUILTIN_SUFFIX (pcmpgtb, s, MIPS_V8QI_FTYPE_V8QI_V8QI),
16256 LOONGSON_BUILTIN_SUFFIX (pextrh, u, MIPS_UV4HI_FTYPE_UV4HI_USI),
16257 LOONGSON_BUILTIN_SUFFIX (pextrh, s, MIPS_V4HI_FTYPE_V4HI_USI),
16258 LOONGSON_BUILTIN_SUFFIX (pinsrh_0, u, MIPS_UV4HI_FTYPE_UV4HI_UV4HI),
16259 LOONGSON_BUILTIN_SUFFIX (pinsrh_1, u, MIPS_UV4HI_FTYPE_UV4HI_UV4HI),
16260 LOONGSON_BUILTIN_SUFFIX (pinsrh_2, u, MIPS_UV4HI_FTYPE_UV4HI_UV4HI),
16261 LOONGSON_BUILTIN_SUFFIX (pinsrh_3, u, MIPS_UV4HI_FTYPE_UV4HI_UV4HI),
16262 LOONGSON_BUILTIN_SUFFIX (pinsrh_0, s, MIPS_V4HI_FTYPE_V4HI_V4HI),
16263 LOONGSON_BUILTIN_SUFFIX (pinsrh_1, s, MIPS_V4HI_FTYPE_V4HI_V4HI),
16264 LOONGSON_BUILTIN_SUFFIX (pinsrh_2, s, MIPS_V4HI_FTYPE_V4HI_V4HI),
16265 LOONGSON_BUILTIN_SUFFIX (pinsrh_3, s, MIPS_V4HI_FTYPE_V4HI_V4HI),
16266 LOONGSON_BUILTIN (pmaddhw, MIPS_V2SI_FTYPE_V4HI_V4HI),
16267 LOONGSON_BUILTIN (pmaxsh, MIPS_V4HI_FTYPE_V4HI_V4HI),
16268 LOONGSON_BUILTIN (pmaxub, MIPS_UV8QI_FTYPE_UV8QI_UV8QI),
16269 LOONGSON_BUILTIN (pminsh, MIPS_V4HI_FTYPE_V4HI_V4HI),
16270 LOONGSON_BUILTIN (pminub, MIPS_UV8QI_FTYPE_UV8QI_UV8QI),
16271 LOONGSON_BUILTIN_SUFFIX (pmovmskb, u, MIPS_UV8QI_FTYPE_UV8QI),
16272 LOONGSON_BUILTIN_SUFFIX (pmovmskb, s, MIPS_V8QI_FTYPE_V8QI),
16273 LOONGSON_BUILTIN (pmulhuh, MIPS_UV4HI_FTYPE_UV4HI_UV4HI),
16274 LOONGSON_BUILTIN (pmulhh, MIPS_V4HI_FTYPE_V4HI_V4HI),
16275 LOONGSON_BUILTIN (pmullh, MIPS_V4HI_FTYPE_V4HI_V4HI),
16276 LOONGSON_BUILTIN (pmuluw, MIPS_UDI_FTYPE_UV2SI_UV2SI),
16277 LOONGSON_BUILTIN (pasubub, MIPS_UV8QI_FTYPE_UV8QI_UV8QI),
16278 LOONGSON_BUILTIN (biadd, MIPS_UV4HI_FTYPE_UV8QI),
16279 LOONGSON_BUILTIN (psadbh, MIPS_UV4HI_FTYPE_UV8QI_UV8QI),
16280 LOONGSON_BUILTIN_SUFFIX (pshufh, u, MIPS_UV4HI_FTYPE_UV4HI_UQI),
16281 LOONGSON_BUILTIN_SUFFIX (pshufh, s, MIPS_V4HI_FTYPE_V4HI_UQI),
16282 LOONGSON_BUILTIN_SUFFIX (psllh, u, MIPS_UV4HI_FTYPE_UV4HI_UQI),
16283 LOONGSON_BUILTIN_SUFFIX (psllh, s, MIPS_V4HI_FTYPE_V4HI_UQI),
16284 LOONGSON_BUILTIN_SUFFIX (psllw, u, MIPS_UV2SI_FTYPE_UV2SI_UQI),
16285 LOONGSON_BUILTIN_SUFFIX (psllw, s, MIPS_V2SI_FTYPE_V2SI_UQI),
16286 LOONGSON_BUILTIN_SUFFIX (psrah, u, MIPS_UV4HI_FTYPE_UV4HI_UQI),
16287 LOONGSON_BUILTIN_SUFFIX (psrah, s, MIPS_V4HI_FTYPE_V4HI_UQI),
16288 LOONGSON_BUILTIN_SUFFIX (psraw, u, MIPS_UV2SI_FTYPE_UV2SI_UQI),
16289 LOONGSON_BUILTIN_SUFFIX (psraw, s, MIPS_V2SI_FTYPE_V2SI_UQI),
16290 LOONGSON_BUILTIN_SUFFIX (psrlh, u, MIPS_UV4HI_FTYPE_UV4HI_UQI),
16291 LOONGSON_BUILTIN_SUFFIX (psrlh, s, MIPS_V4HI_FTYPE_V4HI_UQI),
16292 LOONGSON_BUILTIN_SUFFIX (psrlw, u, MIPS_UV2SI_FTYPE_UV2SI_UQI),
16293 LOONGSON_BUILTIN_SUFFIX (psrlw, s, MIPS_V2SI_FTYPE_V2SI_UQI),
16294 LOONGSON_BUILTIN_SUFFIX (psubw, u, MIPS_UV2SI_FTYPE_UV2SI_UV2SI),
16295 LOONGSON_BUILTIN_SUFFIX (psubh, u, MIPS_UV4HI_FTYPE_UV4HI_UV4HI),
16296 LOONGSON_BUILTIN_SUFFIX (psubb, u, MIPS_UV8QI_FTYPE_UV8QI_UV8QI),
16297 LOONGSON_BUILTIN_SUFFIX (psubw, s, MIPS_V2SI_FTYPE_V2SI_V2SI),
16298 LOONGSON_BUILTIN_SUFFIX (psubh, s, MIPS_V4HI_FTYPE_V4HI_V4HI),
16299 LOONGSON_BUILTIN_SUFFIX (psubb, s, MIPS_V8QI_FTYPE_V8QI_V8QI),
16300 LOONGSON_BUILTIN_SUFFIX (psubd, u, MIPS_UDI_FTYPE_UDI_UDI),
16301 LOONGSON_BUILTIN_SUFFIX (psubd, s, MIPS_DI_FTYPE_DI_DI),
16302 LOONGSON_BUILTIN (psubsh, MIPS_V4HI_FTYPE_V4HI_V4HI),
16303 LOONGSON_BUILTIN (psubsb, MIPS_V8QI_FTYPE_V8QI_V8QI),
16304 LOONGSON_BUILTIN (psubush, MIPS_UV4HI_FTYPE_UV4HI_UV4HI),
16305 LOONGSON_BUILTIN (psubusb, MIPS_UV8QI_FTYPE_UV8QI_UV8QI),
16306 LOONGSON_BUILTIN_SUFFIX (punpckhbh, u, MIPS_UV8QI_FTYPE_UV8QI_UV8QI),
16307 LOONGSON_BUILTIN_SUFFIX (punpckhhw, u, MIPS_UV4HI_FTYPE_UV4HI_UV4HI),
16308 LOONGSON_BUILTIN_SUFFIX (punpckhwd, u, MIPS_UV2SI_FTYPE_UV2SI_UV2SI),
16309 LOONGSON_BUILTIN_SUFFIX (punpckhbh, s, MIPS_V8QI_FTYPE_V8QI_V8QI),
16310 LOONGSON_BUILTIN_SUFFIX (punpckhhw, s, MIPS_V4HI_FTYPE_V4HI_V4HI),
16311 LOONGSON_BUILTIN_SUFFIX (punpckhwd, s, MIPS_V2SI_FTYPE_V2SI_V2SI),
16312 LOONGSON_BUILTIN_SUFFIX (punpcklbh, u, MIPS_UV8QI_FTYPE_UV8QI_UV8QI),
16313 LOONGSON_BUILTIN_SUFFIX (punpcklhw, u, MIPS_UV4HI_FTYPE_UV4HI_UV4HI),
16314 LOONGSON_BUILTIN_SUFFIX (punpcklwd, u, MIPS_UV2SI_FTYPE_UV2SI_UV2SI),
16315 LOONGSON_BUILTIN_SUFFIX (punpcklbh, s, MIPS_V8QI_FTYPE_V8QI_V8QI),
16316 LOONGSON_BUILTIN_SUFFIX (punpcklhw, s, MIPS_V4HI_FTYPE_V4HI_V4HI),
16317 LOONGSON_BUILTIN_SUFFIX (punpcklwd, s, MIPS_V2SI_FTYPE_V2SI_V2SI),
16319 /* Sundry other built-in functions. */
16320 DIRECT_NO_TARGET_BUILTIN (cache, MIPS_VOID_FTYPE_SI_CVPOINTER, cache),
16322 /* Built-in functions for MSA. */
16323 MSA_BUILTIN_PURE (sll_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
16324 MSA_BUILTIN_PURE (sll_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16325 MSA_BUILTIN_PURE (sll_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16326 MSA_BUILTIN_PURE (sll_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
16327 MSA_BUILTIN_PURE (slli_b, MIPS_V16QI_FTYPE_V16QI_UQI),
16328 MSA_BUILTIN_PURE (slli_h, MIPS_V8HI_FTYPE_V8HI_UQI),
16329 MSA_BUILTIN_PURE (slli_w, MIPS_V4SI_FTYPE_V4SI_UQI),
16330 MSA_BUILTIN_PURE (slli_d, MIPS_V2DI_FTYPE_V2DI_UQI),
16331 MSA_BUILTIN_PURE (sra_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
16332 MSA_BUILTIN_PURE (sra_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16333 MSA_BUILTIN_PURE (sra_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16334 MSA_BUILTIN_PURE (sra_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
16335 MSA_BUILTIN_PURE (srai_b, MIPS_V16QI_FTYPE_V16QI_UQI),
16336 MSA_BUILTIN_PURE (srai_h, MIPS_V8HI_FTYPE_V8HI_UQI),
16337 MSA_BUILTIN_PURE (srai_w, MIPS_V4SI_FTYPE_V4SI_UQI),
16338 MSA_BUILTIN_PURE (srai_d, MIPS_V2DI_FTYPE_V2DI_UQI),
16339 MSA_BUILTIN_PURE (srar_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
16340 MSA_BUILTIN_PURE (srar_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16341 MSA_BUILTIN_PURE (srar_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16342 MSA_BUILTIN_PURE (srar_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
16343 MSA_BUILTIN_PURE (srari_b, MIPS_V16QI_FTYPE_V16QI_UQI),
16344 MSA_BUILTIN_PURE (srari_h, MIPS_V8HI_FTYPE_V8HI_UQI),
16345 MSA_BUILTIN_PURE (srari_w, MIPS_V4SI_FTYPE_V4SI_UQI),
16346 MSA_BUILTIN_PURE (srari_d, MIPS_V2DI_FTYPE_V2DI_UQI),
16347 MSA_BUILTIN_PURE (srl_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
16348 MSA_BUILTIN_PURE (srl_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16349 MSA_BUILTIN_PURE (srl_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16350 MSA_BUILTIN_PURE (srl_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
16351 MSA_BUILTIN_PURE (srli_b, MIPS_V16QI_FTYPE_V16QI_UQI),
16352 MSA_BUILTIN_PURE (srli_h, MIPS_V8HI_FTYPE_V8HI_UQI),
16353 MSA_BUILTIN_PURE (srli_w, MIPS_V4SI_FTYPE_V4SI_UQI),
16354 MSA_BUILTIN_PURE (srli_d, MIPS_V2DI_FTYPE_V2DI_UQI),
16355 MSA_BUILTIN_PURE (srlr_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
16356 MSA_BUILTIN_PURE (srlr_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16357 MSA_BUILTIN_PURE (srlr_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16358 MSA_BUILTIN_PURE (srlr_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
16359 MSA_BUILTIN_PURE (srlri_b, MIPS_V16QI_FTYPE_V16QI_UQI),
16360 MSA_BUILTIN_PURE (srlri_h, MIPS_V8HI_FTYPE_V8HI_UQI),
16361 MSA_BUILTIN_PURE (srlri_w, MIPS_V4SI_FTYPE_V4SI_UQI),
16362 MSA_BUILTIN_PURE (srlri_d, MIPS_V2DI_FTYPE_V2DI_UQI),
16363 MSA_BUILTIN_PURE (bclr_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
16364 MSA_BUILTIN_PURE (bclr_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI),
16365 MSA_BUILTIN_PURE (bclr_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI),
16366 MSA_BUILTIN_PURE (bclr_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI),
16367 MSA_BUILTIN_PURE (bclri_b, MIPS_UV16QI_FTYPE_UV16QI_UQI),
16368 MSA_BUILTIN_PURE (bclri_h, MIPS_UV8HI_FTYPE_UV8HI_UQI),
16369 MSA_BUILTIN_PURE (bclri_w, MIPS_UV4SI_FTYPE_UV4SI_UQI),
16370 MSA_BUILTIN_PURE (bclri_d, MIPS_UV2DI_FTYPE_UV2DI_UQI),
16371 MSA_BUILTIN_PURE (bset_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
16372 MSA_BUILTIN_PURE (bset_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI),
16373 MSA_BUILTIN_PURE (bset_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI),
16374 MSA_BUILTIN_PURE (bset_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI),
16375 MSA_BUILTIN_PURE (bseti_b, MIPS_UV16QI_FTYPE_UV16QI_UQI),
16376 MSA_BUILTIN_PURE (bseti_h, MIPS_UV8HI_FTYPE_UV8HI_UQI),
16377 MSA_BUILTIN_PURE (bseti_w, MIPS_UV4SI_FTYPE_UV4SI_UQI),
16378 MSA_BUILTIN_PURE (bseti_d, MIPS_UV2DI_FTYPE_UV2DI_UQI),
16379 MSA_BUILTIN_PURE (bneg_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
16380 MSA_BUILTIN_PURE (bneg_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI),
16381 MSA_BUILTIN_PURE (bneg_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI),
16382 MSA_BUILTIN_PURE (bneg_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI),
16383 MSA_BUILTIN_PURE (bnegi_b, MIPS_UV16QI_FTYPE_UV16QI_UQI),
16384 MSA_BUILTIN_PURE (bnegi_h, MIPS_UV8HI_FTYPE_UV8HI_UQI),
16385 MSA_BUILTIN_PURE (bnegi_w, MIPS_UV4SI_FTYPE_UV4SI_UQI),
16386 MSA_BUILTIN_PURE (bnegi_d, MIPS_UV2DI_FTYPE_UV2DI_UQI),
16387 MSA_BUILTIN_PURE (binsl_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UV16QI),
16388 MSA_BUILTIN_PURE (binsl_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI_UV8HI),
16389 MSA_BUILTIN_PURE (binsl_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI_UV4SI),
16390 MSA_BUILTIN_PURE (binsl_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI_UV2DI),
16391 MSA_BUILTIN_PURE (binsli_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UQI),
16392 MSA_BUILTIN_PURE (binsli_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI_UQI),
16393 MSA_BUILTIN_PURE (binsli_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI_UQI),
16394 MSA_BUILTIN_PURE (binsli_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI_UQI),
16395 MSA_BUILTIN_PURE (binsr_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UV16QI),
16396 MSA_BUILTIN_PURE (binsr_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI_UV8HI),
16397 MSA_BUILTIN_PURE (binsr_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI_UV4SI),
16398 MSA_BUILTIN_PURE (binsr_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI_UV2DI),
16399 MSA_BUILTIN_PURE (binsri_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UQI),
16400 MSA_BUILTIN_PURE (binsri_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI_UQI),
16401 MSA_BUILTIN_PURE (binsri_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI_UQI),
16402 MSA_BUILTIN_PURE (binsri_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI_UQI),
16403 MSA_BUILTIN_PURE (addv_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
16404 MSA_BUILTIN_PURE (addv_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16405 MSA_BUILTIN_PURE (addv_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16406 MSA_BUILTIN_PURE (addv_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
16407 MSA_BUILTIN_PURE (addvi_b, MIPS_V16QI_FTYPE_V16QI_UQI),
16408 MSA_BUILTIN_PURE (addvi_h, MIPS_V8HI_FTYPE_V8HI_UQI),
16409 MSA_BUILTIN_PURE (addvi_w, MIPS_V4SI_FTYPE_V4SI_UQI),
16410 MSA_BUILTIN_PURE (addvi_d, MIPS_V2DI_FTYPE_V2DI_UQI),
16411 MSA_BUILTIN_PURE (subv_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
16412 MSA_BUILTIN_PURE (subv_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16413 MSA_BUILTIN_PURE (subv_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16414 MSA_BUILTIN_PURE (subv_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
16415 MSA_BUILTIN_PURE (subvi_b, MIPS_V16QI_FTYPE_V16QI_UQI),
16416 MSA_BUILTIN_PURE (subvi_h, MIPS_V8HI_FTYPE_V8HI_UQI),
16417 MSA_BUILTIN_PURE (subvi_w, MIPS_V4SI_FTYPE_V4SI_UQI),
16418 MSA_BUILTIN_PURE (subvi_d, MIPS_V2DI_FTYPE_V2DI_UQI),
16419 MSA_BUILTIN_PURE (max_s_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
16420 MSA_BUILTIN_PURE (max_s_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16421 MSA_BUILTIN_PURE (max_s_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16422 MSA_BUILTIN_PURE (max_s_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
16423 MSA_BUILTIN_PURE (maxi_s_b, MIPS_V16QI_FTYPE_V16QI_QI),
16424 MSA_BUILTIN_PURE (maxi_s_h, MIPS_V8HI_FTYPE_V8HI_QI),
16425 MSA_BUILTIN_PURE (maxi_s_w, MIPS_V4SI_FTYPE_V4SI_QI),
16426 MSA_BUILTIN_PURE (maxi_s_d, MIPS_V2DI_FTYPE_V2DI_QI),
16427 MSA_BUILTIN_PURE (max_u_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
16428 MSA_BUILTIN_PURE (max_u_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI),
16429 MSA_BUILTIN_PURE (max_u_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI),
16430 MSA_BUILTIN_PURE (max_u_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI),
16431 MSA_BUILTIN_PURE (maxi_u_b, MIPS_UV16QI_FTYPE_UV16QI_UQI),
16432 MSA_BUILTIN_PURE (maxi_u_h, MIPS_UV8HI_FTYPE_UV8HI_UQI),
16433 MSA_BUILTIN_PURE (maxi_u_w, MIPS_UV4SI_FTYPE_UV4SI_UQI),
16434 MSA_BUILTIN_PURE (maxi_u_d, MIPS_UV2DI_FTYPE_UV2DI_UQI),
16435 MSA_BUILTIN_PURE (min_s_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
16436 MSA_BUILTIN_PURE (min_s_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16437 MSA_BUILTIN_PURE (min_s_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16438 MSA_BUILTIN_PURE (min_s_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
16439 MSA_BUILTIN_PURE (mini_s_b, MIPS_V16QI_FTYPE_V16QI_QI),
16440 MSA_BUILTIN_PURE (mini_s_h, MIPS_V8HI_FTYPE_V8HI_QI),
16441 MSA_BUILTIN_PURE (mini_s_w, MIPS_V4SI_FTYPE_V4SI_QI),
16442 MSA_BUILTIN_PURE (mini_s_d, MIPS_V2DI_FTYPE_V2DI_QI),
16443 MSA_BUILTIN_PURE (min_u_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
16444 MSA_BUILTIN_PURE (min_u_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI),
16445 MSA_BUILTIN_PURE (min_u_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI),
16446 MSA_BUILTIN_PURE (min_u_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI),
16447 MSA_BUILTIN_PURE (mini_u_b, MIPS_UV16QI_FTYPE_UV16QI_UQI),
16448 MSA_BUILTIN_PURE (mini_u_h, MIPS_UV8HI_FTYPE_UV8HI_UQI),
16449 MSA_BUILTIN_PURE (mini_u_w, MIPS_UV4SI_FTYPE_UV4SI_UQI),
16450 MSA_BUILTIN_PURE (mini_u_d, MIPS_UV2DI_FTYPE_UV2DI_UQI),
16451 MSA_BUILTIN_PURE (max_a_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
16452 MSA_BUILTIN_PURE (max_a_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16453 MSA_BUILTIN_PURE (max_a_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16454 MSA_BUILTIN_PURE (max_a_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
16455 MSA_BUILTIN_PURE (min_a_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
16456 MSA_BUILTIN_PURE (min_a_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16457 MSA_BUILTIN_PURE (min_a_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16458 MSA_BUILTIN_PURE (min_a_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
16459 MSA_BUILTIN (ceq_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
16460 MSA_BUILTIN (ceq_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16461 MSA_BUILTIN (ceq_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16462 MSA_BUILTIN (ceq_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
16463 MSA_BUILTIN (ceqi_b, MIPS_V16QI_FTYPE_V16QI_QI),
16464 MSA_BUILTIN (ceqi_h, MIPS_V8HI_FTYPE_V8HI_QI),
16465 MSA_BUILTIN (ceqi_w, MIPS_V4SI_FTYPE_V4SI_QI),
16466 MSA_BUILTIN (ceqi_d, MIPS_V2DI_FTYPE_V2DI_QI),
16467 MSA_BUILTIN (clt_s_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
16468 MSA_BUILTIN (clt_s_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16469 MSA_BUILTIN (clt_s_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16470 MSA_BUILTIN (clt_s_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
16471 MSA_BUILTIN (clti_s_b, MIPS_V16QI_FTYPE_V16QI_QI),
16472 MSA_BUILTIN (clti_s_h, MIPS_V8HI_FTYPE_V8HI_QI),
16473 MSA_BUILTIN (clti_s_w, MIPS_V4SI_FTYPE_V4SI_QI),
16474 MSA_BUILTIN (clti_s_d, MIPS_V2DI_FTYPE_V2DI_QI),
16475 MSA_BUILTIN (clt_u_b, MIPS_V16QI_FTYPE_UV16QI_UV16QI),
16476 MSA_BUILTIN (clt_u_h, MIPS_V8HI_FTYPE_UV8HI_UV8HI),
16477 MSA_BUILTIN (clt_u_w, MIPS_V4SI_FTYPE_UV4SI_UV4SI),
16478 MSA_BUILTIN (clt_u_d, MIPS_V2DI_FTYPE_UV2DI_UV2DI),
16479 MSA_BUILTIN (clti_u_b, MIPS_V16QI_FTYPE_UV16QI_UQI),
16480 MSA_BUILTIN (clti_u_h, MIPS_V8HI_FTYPE_UV8HI_UQI),
16481 MSA_BUILTIN (clti_u_w, MIPS_V4SI_FTYPE_UV4SI_UQI),
16482 MSA_BUILTIN (clti_u_d, MIPS_V2DI_FTYPE_UV2DI_UQI),
16483 MSA_BUILTIN (cle_s_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
16484 MSA_BUILTIN (cle_s_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16485 MSA_BUILTIN (cle_s_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16486 MSA_BUILTIN (cle_s_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
16487 MSA_BUILTIN (clei_s_b, MIPS_V16QI_FTYPE_V16QI_QI),
16488 MSA_BUILTIN (clei_s_h, MIPS_V8HI_FTYPE_V8HI_QI),
16489 MSA_BUILTIN (clei_s_w, MIPS_V4SI_FTYPE_V4SI_QI),
16490 MSA_BUILTIN (clei_s_d, MIPS_V2DI_FTYPE_V2DI_QI),
16491 MSA_BUILTIN (cle_u_b, MIPS_V16QI_FTYPE_UV16QI_UV16QI),
16492 MSA_BUILTIN (cle_u_h, MIPS_V8HI_FTYPE_UV8HI_UV8HI),
16493 MSA_BUILTIN (cle_u_w, MIPS_V4SI_FTYPE_UV4SI_UV4SI),
16494 MSA_BUILTIN (cle_u_d, MIPS_V2DI_FTYPE_UV2DI_UV2DI),
16495 MSA_BUILTIN (clei_u_b, MIPS_V16QI_FTYPE_UV16QI_UQI),
16496 MSA_BUILTIN (clei_u_h, MIPS_V8HI_FTYPE_UV8HI_UQI),
16497 MSA_BUILTIN (clei_u_w, MIPS_V4SI_FTYPE_UV4SI_UQI),
16498 MSA_BUILTIN (clei_u_d, MIPS_V2DI_FTYPE_UV2DI_UQI),
16499 MSA_BUILTIN (ld_b, MIPS_V16QI_FTYPE_CVPOINTER_SI),
16500 MSA_BUILTIN (ld_h, MIPS_V8HI_FTYPE_CVPOINTER_SI),
16501 MSA_BUILTIN (ld_w, MIPS_V4SI_FTYPE_CVPOINTER_SI),
16502 MSA_BUILTIN (ld_d, MIPS_V2DI_FTYPE_CVPOINTER_SI),
16503 MSA_NO_TARGET_BUILTIN (st_b, MIPS_VOID_FTYPE_V16QI_CVPOINTER_SI),
16504 MSA_NO_TARGET_BUILTIN (st_h, MIPS_VOID_FTYPE_V8HI_CVPOINTER_SI),
16505 MSA_NO_TARGET_BUILTIN (st_w, MIPS_VOID_FTYPE_V4SI_CVPOINTER_SI),
16506 MSA_NO_TARGET_BUILTIN (st_d, MIPS_VOID_FTYPE_V2DI_CVPOINTER_SI),
16507 MSA_BUILTIN_PURE (sat_s_b, MIPS_V16QI_FTYPE_V16QI_UQI),
16508 MSA_BUILTIN_PURE (sat_s_h, MIPS_V8HI_FTYPE_V8HI_UQI),
16509 MSA_BUILTIN_PURE (sat_s_w, MIPS_V4SI_FTYPE_V4SI_UQI),
16510 MSA_BUILTIN_PURE (sat_s_d, MIPS_V2DI_FTYPE_V2DI_UQI),
16511 MSA_BUILTIN_PURE (sat_u_b, MIPS_UV16QI_FTYPE_UV16QI_UQI),
16512 MSA_BUILTIN_PURE (sat_u_h, MIPS_UV8HI_FTYPE_UV8HI_UQI),
16513 MSA_BUILTIN_PURE (sat_u_w, MIPS_UV4SI_FTYPE_UV4SI_UQI),
16514 MSA_BUILTIN_PURE (sat_u_d, MIPS_UV2DI_FTYPE_UV2DI_UQI),
16515 MSA_BUILTIN_PURE (add_a_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
16516 MSA_BUILTIN_PURE (add_a_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16517 MSA_BUILTIN_PURE (add_a_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16518 MSA_BUILTIN_PURE (add_a_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
16519 MSA_BUILTIN_PURE (adds_a_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
16520 MSA_BUILTIN_PURE (adds_a_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16521 MSA_BUILTIN_PURE (adds_a_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16522 MSA_BUILTIN_PURE (adds_a_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
16523 MSA_BUILTIN_PURE (adds_s_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
16524 MSA_BUILTIN_PURE (adds_s_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16525 MSA_BUILTIN_PURE (adds_s_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16526 MSA_BUILTIN_PURE (adds_s_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
16527 MSA_BUILTIN_PURE (adds_u_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
16528 MSA_BUILTIN_PURE (adds_u_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI),
16529 MSA_BUILTIN_PURE (adds_u_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI),
16530 MSA_BUILTIN_PURE (adds_u_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI),
16531 MSA_BUILTIN_PURE (ave_s_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
16532 MSA_BUILTIN_PURE (ave_s_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16533 MSA_BUILTIN_PURE (ave_s_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16534 MSA_BUILTIN_PURE (ave_s_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
16535 MSA_BUILTIN_PURE (ave_u_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
16536 MSA_BUILTIN_PURE (ave_u_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI),
16537 MSA_BUILTIN_PURE (ave_u_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI),
16538 MSA_BUILTIN_PURE (ave_u_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI),
16539 MSA_BUILTIN_PURE (aver_s_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
16540 MSA_BUILTIN_PURE (aver_s_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16541 MSA_BUILTIN_PURE (aver_s_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16542 MSA_BUILTIN_PURE (aver_s_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
16543 MSA_BUILTIN_PURE (aver_u_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
16544 MSA_BUILTIN_PURE (aver_u_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI),
16545 MSA_BUILTIN_PURE (aver_u_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI),
16546 MSA_BUILTIN_PURE (aver_u_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI),
16547 MSA_BUILTIN_PURE (subs_s_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
16548 MSA_BUILTIN_PURE (subs_s_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16549 MSA_BUILTIN_PURE (subs_s_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16550 MSA_BUILTIN_PURE (subs_s_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
16551 MSA_BUILTIN_PURE (subs_u_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
16552 MSA_BUILTIN_PURE (subs_u_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI),
16553 MSA_BUILTIN_PURE (subs_u_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI),
16554 MSA_BUILTIN_PURE (subs_u_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI),
16555 MSA_BUILTIN_PURE (subsuu_s_b, MIPS_V16QI_FTYPE_UV16QI_UV16QI),
16556 MSA_BUILTIN_PURE (subsuu_s_h, MIPS_V8HI_FTYPE_UV8HI_UV8HI),
16557 MSA_BUILTIN_PURE (subsuu_s_w, MIPS_V4SI_FTYPE_UV4SI_UV4SI),
16558 MSA_BUILTIN_PURE (subsuu_s_d, MIPS_V2DI_FTYPE_UV2DI_UV2DI),
16559 MSA_BUILTIN_PURE (subsus_u_b, MIPS_UV16QI_FTYPE_UV16QI_V16QI),
16560 MSA_BUILTIN_PURE (subsus_u_h, MIPS_UV8HI_FTYPE_UV8HI_V8HI),
16561 MSA_BUILTIN_PURE (subsus_u_w, MIPS_UV4SI_FTYPE_UV4SI_V4SI),
16562 MSA_BUILTIN_PURE (subsus_u_d, MIPS_UV2DI_FTYPE_UV2DI_V2DI),
16563 MSA_BUILTIN_PURE (asub_s_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
16564 MSA_BUILTIN_PURE (asub_s_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16565 MSA_BUILTIN_PURE (asub_s_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16566 MSA_BUILTIN_PURE (asub_s_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
16567 MSA_BUILTIN_PURE (asub_u_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
16568 MSA_BUILTIN_PURE (asub_u_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI),
16569 MSA_BUILTIN_PURE (asub_u_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI),
16570 MSA_BUILTIN_PURE (asub_u_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI),
16571 MSA_BUILTIN_PURE (mulv_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
16572 MSA_BUILTIN_PURE (mulv_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16573 MSA_BUILTIN_PURE (mulv_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16574 MSA_BUILTIN_PURE (mulv_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
16575 MSA_BUILTIN_PURE (maddv_b, MIPS_V16QI_FTYPE_V16QI_V16QI_V16QI),
16576 MSA_BUILTIN_PURE (maddv_h, MIPS_V8HI_FTYPE_V8HI_V8HI_V8HI),
16577 MSA_BUILTIN_PURE (maddv_w, MIPS_V4SI_FTYPE_V4SI_V4SI_V4SI),
16578 MSA_BUILTIN_PURE (maddv_d, MIPS_V2DI_FTYPE_V2DI_V2DI_V2DI),
16579 MSA_BUILTIN_PURE (msubv_b, MIPS_V16QI_FTYPE_V16QI_V16QI_V16QI),
16580 MSA_BUILTIN_PURE (msubv_h, MIPS_V8HI_FTYPE_V8HI_V8HI_V8HI),
16581 MSA_BUILTIN_PURE (msubv_w, MIPS_V4SI_FTYPE_V4SI_V4SI_V4SI),
16582 MSA_BUILTIN_PURE (msubv_d, MIPS_V2DI_FTYPE_V2DI_V2DI_V2DI),
16583 MSA_BUILTIN_PURE (div_s_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
16584 MSA_BUILTIN_PURE (div_s_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16585 MSA_BUILTIN_PURE (div_s_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16586 MSA_BUILTIN_PURE (div_s_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
16587 MSA_BUILTIN_PURE (div_u_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
16588 MSA_BUILTIN_PURE (div_u_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI),
16589 MSA_BUILTIN_PURE (div_u_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI),
16590 MSA_BUILTIN_PURE (div_u_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI),
16591 MSA_BUILTIN_PURE (hadd_s_h, MIPS_V8HI_FTYPE_V16QI_V16QI),
16592 MSA_BUILTIN_PURE (hadd_s_w, MIPS_V4SI_FTYPE_V8HI_V8HI),
16593 MSA_BUILTIN_PURE (hadd_s_d, MIPS_V2DI_FTYPE_V4SI_V4SI),
16594 MSA_BUILTIN_PURE (hadd_u_h, MIPS_UV8HI_FTYPE_UV16QI_UV16QI),
16595 MSA_BUILTIN_PURE (hadd_u_w, MIPS_UV4SI_FTYPE_UV8HI_UV8HI),
16596 MSA_BUILTIN_PURE (hadd_u_d, MIPS_UV2DI_FTYPE_UV4SI_UV4SI),
16597 MSA_BUILTIN_PURE (hsub_s_h, MIPS_V8HI_FTYPE_V16QI_V16QI),
16598 MSA_BUILTIN_PURE (hsub_s_w, MIPS_V4SI_FTYPE_V8HI_V8HI),
16599 MSA_BUILTIN_PURE (hsub_s_d, MIPS_V2DI_FTYPE_V4SI_V4SI),
16600 MSA_BUILTIN_PURE (hsub_u_h, MIPS_V8HI_FTYPE_UV16QI_UV16QI),
16601 MSA_BUILTIN_PURE (hsub_u_w, MIPS_V4SI_FTYPE_UV8HI_UV8HI),
16602 MSA_BUILTIN_PURE (hsub_u_d, MIPS_V2DI_FTYPE_UV4SI_UV4SI),
16603 MSA_BUILTIN_PURE (mod_s_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
16604 MSA_BUILTIN_PURE (mod_s_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16605 MSA_BUILTIN_PURE (mod_s_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16606 MSA_BUILTIN_PURE (mod_s_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
16607 MSA_BUILTIN_PURE (mod_u_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
16608 MSA_BUILTIN_PURE (mod_u_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI),
16609 MSA_BUILTIN_PURE (mod_u_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI),
16610 MSA_BUILTIN_PURE (mod_u_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI),
16611 MSA_BUILTIN_PURE (dotp_s_h, MIPS_V8HI_FTYPE_V16QI_V16QI),
16612 MSA_BUILTIN_PURE (dotp_s_w, MIPS_V4SI_FTYPE_V8HI_V8HI),
16613 MSA_BUILTIN_PURE (dotp_s_d, MIPS_V2DI_FTYPE_V4SI_V4SI),
16614 MSA_BUILTIN_PURE (dotp_u_h, MIPS_UV8HI_FTYPE_UV16QI_UV16QI),
16615 MSA_BUILTIN_PURE (dotp_u_w, MIPS_UV4SI_FTYPE_UV8HI_UV8HI),
16616 MSA_BUILTIN_PURE (dotp_u_d, MIPS_UV2DI_FTYPE_UV4SI_UV4SI),
16617 MSA_BUILTIN_PURE (dpadd_s_h, MIPS_V8HI_FTYPE_V8HI_V16QI_V16QI),
16618 MSA_BUILTIN_PURE (dpadd_s_w, MIPS_V4SI_FTYPE_V4SI_V8HI_V8HI),
16619 MSA_BUILTIN_PURE (dpadd_s_d, MIPS_V2DI_FTYPE_V2DI_V4SI_V4SI),
16620 MSA_BUILTIN_PURE (dpadd_u_h, MIPS_UV8HI_FTYPE_UV8HI_UV16QI_UV16QI),
16621 MSA_BUILTIN_PURE (dpadd_u_w, MIPS_UV4SI_FTYPE_UV4SI_UV8HI_UV8HI),
16622 MSA_BUILTIN_PURE (dpadd_u_d, MIPS_UV2DI_FTYPE_UV2DI_UV4SI_UV4SI),
16623 MSA_BUILTIN_PURE (dpsub_s_h, MIPS_V8HI_FTYPE_V8HI_V16QI_V16QI),
16624 MSA_BUILTIN_PURE (dpsub_s_w, MIPS_V4SI_FTYPE_V4SI_V8HI_V8HI),
16625 MSA_BUILTIN_PURE (dpsub_s_d, MIPS_V2DI_FTYPE_V2DI_V4SI_V4SI),
16626 MSA_BUILTIN_PURE (dpsub_u_h, MIPS_V8HI_FTYPE_V8HI_UV16QI_UV16QI),
16627 MSA_BUILTIN_PURE (dpsub_u_w, MIPS_V4SI_FTYPE_V4SI_UV8HI_UV8HI),
16628 MSA_BUILTIN_PURE (dpsub_u_d, MIPS_V2DI_FTYPE_V2DI_UV4SI_UV4SI),
16629 MSA_BUILTIN_PURE (sld_b, MIPS_V16QI_FTYPE_V16QI_V16QI_SI),
16630 MSA_BUILTIN_PURE (sld_h, MIPS_V8HI_FTYPE_V8HI_V8HI_SI),
16631 MSA_BUILTIN_PURE (sld_w, MIPS_V4SI_FTYPE_V4SI_V4SI_SI),
16632 MSA_BUILTIN_PURE (sld_d, MIPS_V2DI_FTYPE_V2DI_V2DI_SI),
16633 MSA_BUILTIN_PURE (sldi_b, MIPS_V16QI_FTYPE_V16QI_V16QI_UQI),
16634 MSA_BUILTIN_PURE (sldi_h, MIPS_V8HI_FTYPE_V8HI_V8HI_UQI),
16635 MSA_BUILTIN_PURE (sldi_w, MIPS_V4SI_FTYPE_V4SI_V4SI_UQI),
16636 MSA_BUILTIN_PURE (sldi_d, MIPS_V2DI_FTYPE_V2DI_V2DI_UQI),
16637 MSA_BUILTIN_PURE (splat_b, MIPS_V16QI_FTYPE_V16QI_SI),
16638 MSA_BUILTIN_PURE (splat_h, MIPS_V8HI_FTYPE_V8HI_SI),
16639 MSA_BUILTIN_PURE (splat_w, MIPS_V4SI_FTYPE_V4SI_SI),
16640 MSA_BUILTIN_PURE (splat_d, MIPS_V2DI_FTYPE_V2DI_SI),
16641 MSA_BUILTIN_PURE (splati_b, MIPS_V16QI_FTYPE_V16QI_UQI),
16642 MSA_BUILTIN_PURE (splati_h, MIPS_V8HI_FTYPE_V8HI_UQI),
16643 MSA_BUILTIN_PURE (splati_w, MIPS_V4SI_FTYPE_V4SI_UQI),
16644 MSA_BUILTIN_PURE (splati_d, MIPS_V2DI_FTYPE_V2DI_UQI),
16645 MSA_BUILTIN_PURE (pckev_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
16646 MSA_BUILTIN_PURE (pckev_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16647 MSA_BUILTIN_PURE (pckev_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16648 MSA_BUILTIN_PURE (pckev_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
16649 MSA_BUILTIN_PURE (pckod_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
16650 MSA_BUILTIN_PURE (pckod_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16651 MSA_BUILTIN_PURE (pckod_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16652 MSA_BUILTIN_PURE (pckod_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
16653 MSA_BUILTIN_PURE (ilvl_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
16654 MSA_BUILTIN_PURE (ilvl_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16655 MSA_BUILTIN_PURE (ilvl_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16656 MSA_BUILTIN_PURE (ilvl_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
16657 MSA_BUILTIN_PURE (ilvr_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
16658 MSA_BUILTIN_PURE (ilvr_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16659 MSA_BUILTIN_PURE (ilvr_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16660 MSA_BUILTIN_PURE (ilvr_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
16661 MSA_BUILTIN_PURE (ilvev_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
16662 MSA_BUILTIN_PURE (ilvev_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16663 MSA_BUILTIN_PURE (ilvev_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16664 MSA_BUILTIN_PURE (ilvev_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
16665 MSA_BUILTIN_PURE (ilvod_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
16666 MSA_BUILTIN_PURE (ilvod_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16667 MSA_BUILTIN_PURE (ilvod_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16668 MSA_BUILTIN_PURE (ilvod_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
16669 MSA_BUILTIN_PURE (vshf_b, MIPS_V16QI_FTYPE_V16QI_V16QI_V16QI),
16670 MSA_BUILTIN_PURE (vshf_h, MIPS_V8HI_FTYPE_V8HI_V8HI_V8HI),
16671 MSA_BUILTIN_PURE (vshf_w, MIPS_V4SI_FTYPE_V4SI_V4SI_V4SI),
16672 MSA_BUILTIN_PURE (vshf_d, MIPS_V2DI_FTYPE_V2DI_V2DI_V2DI),
16673 MSA_BUILTIN_PURE (and_v, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
16674 MSA_BUILTIN_PURE (andi_b, MIPS_UV16QI_FTYPE_UV16QI_UQI),
16675 MSA_BUILTIN_PURE (or_v, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
16676 MSA_BUILTIN_PURE (ori_b, MIPS_UV16QI_FTYPE_UV16QI_UQI),
16677 MSA_BUILTIN_PURE (nor_v, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
16678 MSA_BUILTIN_PURE (nori_b, MIPS_UV16QI_FTYPE_UV16QI_UQI),
16679 MSA_BUILTIN_PURE (xor_v, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
16680 MSA_BUILTIN_PURE (xori_b, MIPS_UV16QI_FTYPE_UV16QI_UQI),
16681 MSA_BUILTIN_PURE (bmnz_v, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UV16QI),
16682 MSA_BUILTIN_PURE (bmnzi_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UQI),
16683 MSA_BUILTIN_PURE (bmz_v, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UV16QI),
16684 MSA_BUILTIN_PURE (bmzi_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UQI),
16685 MSA_BUILTIN_PURE (bsel_v, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UV16QI),
16686 MSA_BUILTIN_PURE (bseli_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UQI),
16687 MSA_BUILTIN_PURE (shf_b, MIPS_V16QI_FTYPE_V16QI_UQI),
16688 MSA_BUILTIN_PURE (shf_h, MIPS_V8HI_FTYPE_V8HI_UQI),
16689 MSA_BUILTIN_PURE (shf_w, MIPS_V4SI_FTYPE_V4SI_UQI),
16690 MSA_BUILTIN_TEST_BRANCH (bnz_v, MIPS_SI_FTYPE_UV16QI),
16691 MSA_BUILTIN_TEST_BRANCH (bz_v, MIPS_SI_FTYPE_UV16QI),
16692 MSA_BUILTIN_PURE (fill_b, MIPS_V16QI_FTYPE_SI),
16693 MSA_BUILTIN_PURE (fill_h, MIPS_V8HI_FTYPE_SI),
16694 MSA_BUILTIN_PURE (fill_w, MIPS_V4SI_FTYPE_SI),
16695 MSA_BUILTIN_PURE (fill_d, MIPS_V2DI_FTYPE_DI),
16696 MSA_BUILTIN_PURE (pcnt_b, MIPS_V16QI_FTYPE_V16QI),
16697 MSA_BUILTIN_PURE (pcnt_h, MIPS_V8HI_FTYPE_V8HI),
16698 MSA_BUILTIN_PURE (pcnt_w, MIPS_V4SI_FTYPE_V4SI),
16699 MSA_BUILTIN_PURE (pcnt_d, MIPS_V2DI_FTYPE_V2DI),
16700 MSA_BUILTIN_PURE (nloc_b, MIPS_V16QI_FTYPE_V16QI),
16701 MSA_BUILTIN_PURE (nloc_h, MIPS_V8HI_FTYPE_V8HI),
16702 MSA_BUILTIN_PURE (nloc_w, MIPS_V4SI_FTYPE_V4SI),
16703 MSA_BUILTIN_PURE (nloc_d, MIPS_V2DI_FTYPE_V2DI),
16704 MSA_BUILTIN_PURE (nlzc_b, MIPS_V16QI_FTYPE_V16QI),
16705 MSA_BUILTIN_PURE (nlzc_h, MIPS_V8HI_FTYPE_V8HI),
16706 MSA_BUILTIN_PURE (nlzc_w, MIPS_V4SI_FTYPE_V4SI),
16707 MSA_BUILTIN_PURE (nlzc_d, MIPS_V2DI_FTYPE_V2DI),
16708 MSA_BUILTIN_PURE (copy_s_b, MIPS_SI_FTYPE_V16QI_UQI),
16709 MSA_BUILTIN_PURE (copy_s_h, MIPS_SI_FTYPE_V8HI_UQI),
16710 MSA_BUILTIN_PURE (copy_s_w, MIPS_SI_FTYPE_V4SI_UQI),
16711 MSA_BUILTIN_PURE (copy_s_d, MIPS_DI_FTYPE_V2DI_UQI),
16712 MSA_BUILTIN_PURE (copy_u_b, MIPS_USI_FTYPE_V16QI_UQI),
16713 MSA_BUILTIN_PURE (copy_u_h, MIPS_USI_FTYPE_V8HI_UQI),
16714 MSA_BUILTIN_REMAP (copy_u_w, copy_s_w, MIPS_USI_FTYPE_V4SI_UQI),
16715 MSA_BUILTIN_REMAP (copy_u_d, copy_s_d, MIPS_UDI_FTYPE_V2DI_UQI),
16716 MSA_BUILTIN_PURE (insert_b, MIPS_V16QI_FTYPE_V16QI_UQI_SI),
16717 MSA_BUILTIN_PURE (insert_h, MIPS_V8HI_FTYPE_V8HI_UQI_SI),
16718 MSA_BUILTIN_PURE (insert_w, MIPS_V4SI_FTYPE_V4SI_UQI_SI),
16719 MSA_BUILTIN_PURE (insert_d, MIPS_V2DI_FTYPE_V2DI_UQI_DI),
16720 MSA_BUILTIN_PURE (insve_b, MIPS_V16QI_FTYPE_V16QI_UQI_V16QI),
16721 MSA_BUILTIN_PURE (insve_h, MIPS_V8HI_FTYPE_V8HI_UQI_V8HI),
16722 MSA_BUILTIN_PURE (insve_w, MIPS_V4SI_FTYPE_V4SI_UQI_V4SI),
16723 MSA_BUILTIN_PURE (insve_d, MIPS_V2DI_FTYPE_V2DI_UQI_V2DI),
16724 MSA_BUILTIN_TEST_BRANCH (bnz_b, MIPS_SI_FTYPE_UV16QI),
16725 MSA_BUILTIN_TEST_BRANCH (bnz_h, MIPS_SI_FTYPE_UV8HI),
16726 MSA_BUILTIN_TEST_BRANCH (bnz_w, MIPS_SI_FTYPE_UV4SI),
16727 MSA_BUILTIN_TEST_BRANCH (bnz_d, MIPS_SI_FTYPE_UV2DI),
16728 MSA_BUILTIN_TEST_BRANCH (bz_b, MIPS_SI_FTYPE_UV16QI),
16729 MSA_BUILTIN_TEST_BRANCH (bz_h, MIPS_SI_FTYPE_UV8HI),
16730 MSA_BUILTIN_TEST_BRANCH (bz_w, MIPS_SI_FTYPE_UV4SI),
16731 MSA_BUILTIN_TEST_BRANCH (bz_d, MIPS_SI_FTYPE_UV2DI),
16732 MSA_BUILTIN_PURE (ldi_b, MIPS_V16QI_FTYPE_HI),
16733 MSA_BUILTIN_PURE (ldi_h, MIPS_V8HI_FTYPE_HI),
16734 MSA_BUILTIN_PURE (ldi_w, MIPS_V4SI_FTYPE_HI),
16735 MSA_BUILTIN_PURE (ldi_d, MIPS_V2DI_FTYPE_HI),
16736 MSA_BUILTIN_PURE (fcaf_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
16737 MSA_BUILTIN_PURE (fcaf_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
16738 MSA_BUILTIN_PURE (fcor_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
16739 MSA_BUILTIN_PURE (fcor_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
16740 MSA_BUILTIN_PURE (fcun_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
16741 MSA_BUILTIN_PURE (fcun_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
16742 MSA_BUILTIN_PURE (fcune_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
16743 MSA_BUILTIN_PURE (fcune_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
16744 MSA_BUILTIN_PURE (fcueq_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
16745 MSA_BUILTIN_PURE (fcueq_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
16746 MSA_BUILTIN_PURE (fceq_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
16747 MSA_BUILTIN_PURE (fceq_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
16748 MSA_BUILTIN_PURE (fcne_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
16749 MSA_BUILTIN_PURE (fcne_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
16750 MSA_BUILTIN_PURE (fclt_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
16751 MSA_BUILTIN_PURE (fclt_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
16752 MSA_BUILTIN_PURE (fcult_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
16753 MSA_BUILTIN_PURE (fcult_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
16754 MSA_BUILTIN_PURE (fcle_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
16755 MSA_BUILTIN_PURE (fcle_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
16756 MSA_BUILTIN_PURE (fcule_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
16757 MSA_BUILTIN_PURE (fcule_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
16758 MSA_BUILTIN_PURE (fsaf_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
16759 MSA_BUILTIN_PURE (fsaf_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
16760 MSA_BUILTIN_PURE (fsor_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
16761 MSA_BUILTIN_PURE (fsor_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
16762 MSA_BUILTIN_PURE (fsun_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
16763 MSA_BUILTIN_PURE (fsun_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
16764 MSA_BUILTIN_PURE (fsune_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
16765 MSA_BUILTIN_PURE (fsune_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
16766 MSA_BUILTIN_PURE (fsueq_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
16767 MSA_BUILTIN_PURE (fsueq_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
16768 MSA_BUILTIN_PURE (fseq_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
16769 MSA_BUILTIN_PURE (fseq_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
16770 MSA_BUILTIN_PURE (fsne_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
16771 MSA_BUILTIN_PURE (fsne_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
16772 MSA_BUILTIN_PURE (fslt_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
16773 MSA_BUILTIN_PURE (fslt_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
16774 MSA_BUILTIN_PURE (fsult_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
16775 MSA_BUILTIN_PURE (fsult_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
16776 MSA_BUILTIN_PURE (fsle_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
16777 MSA_BUILTIN_PURE (fsle_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
16778 MSA_BUILTIN_PURE (fsule_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
16779 MSA_BUILTIN_PURE (fsule_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
16780 MSA_BUILTIN_PURE (fadd_w, MIPS_V4SF_FTYPE_V4SF_V4SF),
16781 MSA_BUILTIN_PURE (fadd_d, MIPS_V2DF_FTYPE_V2DF_V2DF),
16782 MSA_BUILTIN_PURE (fsub_w, MIPS_V4SF_FTYPE_V4SF_V4SF),
16783 MSA_BUILTIN_PURE (fsub_d, MIPS_V2DF_FTYPE_V2DF_V2DF),
16784 MSA_BUILTIN_PURE (fmul_w, MIPS_V4SF_FTYPE_V4SF_V4SF),
16785 MSA_BUILTIN_PURE (fmul_d, MIPS_V2DF_FTYPE_V2DF_V2DF),
16786 MSA_BUILTIN_PURE (fdiv_w, MIPS_V4SF_FTYPE_V4SF_V4SF),
16787 MSA_BUILTIN_PURE (fdiv_d, MIPS_V2DF_FTYPE_V2DF_V2DF),
16788 MSA_BUILTIN_PURE (fmadd_w, MIPS_V4SF_FTYPE_V4SF_V4SF_V4SF),
16789 MSA_BUILTIN_PURE (fmadd_d, MIPS_V2DF_FTYPE_V2DF_V2DF_V2DF),
16790 MSA_BUILTIN_PURE (fmsub_w, MIPS_V4SF_FTYPE_V4SF_V4SF_V4SF),
16791 MSA_BUILTIN_PURE (fmsub_d, MIPS_V2DF_FTYPE_V2DF_V2DF_V2DF),
16792 MSA_BUILTIN_PURE (fexp2_w, MIPS_V4SF_FTYPE_V4SF_V4SI),
16793 MSA_BUILTIN_PURE (fexp2_d, MIPS_V2DF_FTYPE_V2DF_V2DI),
16794 MSA_BUILTIN_PURE (fexdo_h, MIPS_V8HI_FTYPE_V4SF_V4SF),
16795 MSA_BUILTIN_PURE (fexdo_w, MIPS_V4SF_FTYPE_V2DF_V2DF),
16796 MSA_BUILTIN_PURE (ftq_h, MIPS_V8HI_FTYPE_V4SF_V4SF),
16797 MSA_BUILTIN_PURE (ftq_w, MIPS_V4SI_FTYPE_V2DF_V2DF),
16798 MSA_BUILTIN_PURE (fmin_w, MIPS_V4SF_FTYPE_V4SF_V4SF),
16799 MSA_BUILTIN_PURE (fmin_d, MIPS_V2DF_FTYPE_V2DF_V2DF),
16800 MSA_BUILTIN_PURE (fmin_a_w, MIPS_V4SF_FTYPE_V4SF_V4SF),
16801 MSA_BUILTIN_PURE (fmin_a_d, MIPS_V2DF_FTYPE_V2DF_V2DF),
16802 MSA_BUILTIN_PURE (fmax_w, MIPS_V4SF_FTYPE_V4SF_V4SF),
16803 MSA_BUILTIN_PURE (fmax_d, MIPS_V2DF_FTYPE_V2DF_V2DF),
16804 MSA_BUILTIN_PURE (fmax_a_w, MIPS_V4SF_FTYPE_V4SF_V4SF),
16805 MSA_BUILTIN_PURE (fmax_a_d, MIPS_V2DF_FTYPE_V2DF_V2DF),
16806 MSA_BUILTIN_PURE (mul_q_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16807 MSA_BUILTIN_PURE (mul_q_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16808 MSA_BUILTIN_PURE (mulr_q_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
16809 MSA_BUILTIN_PURE (mulr_q_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
16810 MSA_BUILTIN_PURE (madd_q_h, MIPS_V8HI_FTYPE_V8HI_V8HI_V8HI),
16811 MSA_BUILTIN_PURE (madd_q_w, MIPS_V4SI_FTYPE_V4SI_V4SI_V4SI),
16812 MSA_BUILTIN_PURE (maddr_q_h, MIPS_V8HI_FTYPE_V8HI_V8HI_V8HI),
16813 MSA_BUILTIN_PURE (maddr_q_w, MIPS_V4SI_FTYPE_V4SI_V4SI_V4SI),
16814 MSA_BUILTIN_PURE (msub_q_h, MIPS_V8HI_FTYPE_V8HI_V8HI_V8HI),
16815 MSA_BUILTIN_PURE (msub_q_w, MIPS_V4SI_FTYPE_V4SI_V4SI_V4SI),
16816 MSA_BUILTIN_PURE (msubr_q_h, MIPS_V8HI_FTYPE_V8HI_V8HI_V8HI),
16817 MSA_BUILTIN_PURE (msubr_q_w, MIPS_V4SI_FTYPE_V4SI_V4SI_V4SI),
16818 MSA_BUILTIN_PURE (fclass_w, MIPS_V4SI_FTYPE_V4SF),
16819 MSA_BUILTIN_PURE (fclass_d, MIPS_V2DI_FTYPE_V2DF),
16820 MSA_BUILTIN_PURE (fsqrt_w, MIPS_V4SF_FTYPE_V4SF),
16821 MSA_BUILTIN_PURE (fsqrt_d, MIPS_V2DF_FTYPE_V2DF),
16822 MSA_BUILTIN_PURE (frcp_w, MIPS_V4SF_FTYPE_V4SF),
16823 MSA_BUILTIN_PURE (frcp_d, MIPS_V2DF_FTYPE_V2DF),
16824 MSA_BUILTIN_PURE (frint_w, MIPS_V4SF_FTYPE_V4SF),
16825 MSA_BUILTIN_PURE (frint_d, MIPS_V2DF_FTYPE_V2DF),
16826 MSA_BUILTIN_PURE (frsqrt_w, MIPS_V4SF_FTYPE_V4SF),
16827 MSA_BUILTIN_PURE (frsqrt_d, MIPS_V2DF_FTYPE_V2DF),
16828 MSA_BUILTIN_PURE (flog2_w, MIPS_V4SF_FTYPE_V4SF),
16829 MSA_BUILTIN_PURE (flog2_d, MIPS_V2DF_FTYPE_V2DF),
16830 MSA_BUILTIN_PURE (fexupl_w, MIPS_V4SF_FTYPE_V8HI),
16831 MSA_BUILTIN_PURE (fexupl_d, MIPS_V2DF_FTYPE_V4SF),
16832 MSA_BUILTIN_PURE (fexupr_w, MIPS_V4SF_FTYPE_V8HI),
16833 MSA_BUILTIN_PURE (fexupr_d, MIPS_V2DF_FTYPE_V4SF),
16834 MSA_BUILTIN_PURE (ffql_w, MIPS_V4SF_FTYPE_V8HI),
16835 MSA_BUILTIN_PURE (ffql_d, MIPS_V2DF_FTYPE_V4SI),
16836 MSA_BUILTIN_PURE (ffqr_w, MIPS_V4SF_FTYPE_V8HI),
16837 MSA_BUILTIN_PURE (ffqr_d, MIPS_V2DF_FTYPE_V4SI),
16838 MSA_BUILTIN_PURE (ftint_s_w, MIPS_V4SI_FTYPE_V4SF),
16839 MSA_BUILTIN_PURE (ftint_s_d, MIPS_V2DI_FTYPE_V2DF),
16840 MSA_BUILTIN_PURE (ftint_u_w, MIPS_UV4SI_FTYPE_V4SF),
16841 MSA_BUILTIN_PURE (ftint_u_d, MIPS_UV2DI_FTYPE_V2DF),
16842 MSA_BUILTIN_PURE (ftrunc_s_w, MIPS_V4SI_FTYPE_V4SF),
16843 MSA_BUILTIN_PURE (ftrunc_s_d, MIPS_V2DI_FTYPE_V2DF),
16844 MSA_BUILTIN_PURE (ftrunc_u_w, MIPS_UV4SI_FTYPE_V4SF),
16845 MSA_BUILTIN_PURE (ftrunc_u_d, MIPS_UV2DI_FTYPE_V2DF),
16846 MSA_BUILTIN_PURE (ffint_s_w, MIPS_V4SF_FTYPE_V4SI),
16847 MSA_BUILTIN_PURE (ffint_s_d, MIPS_V2DF_FTYPE_V2DI),
16848 MSA_BUILTIN_PURE (ffint_u_w, MIPS_V4SF_FTYPE_UV4SI),
16849 MSA_BUILTIN_PURE (ffint_u_d, MIPS_V2DF_FTYPE_UV2DI),
16850 MSA_NO_TARGET_BUILTIN (ctcmsa, MIPS_VOID_FTYPE_UQI_SI),
16851 MSA_BUILTIN_PURE (cfcmsa, MIPS_SI_FTYPE_UQI),
16852 MSA_BUILTIN_PURE (move_v, MIPS_V16QI_FTYPE_V16QI),
16855 /* Index I is the function declaration for mips_builtins[I], or null if the
16856 function isn't defined on this target. */
16857 static GTY(()) tree mips_builtin_decls[ARRAY_SIZE (mips_builtins)];
16858 /* Get the index I of the function declaration for mips_builtin_decls[I]
16859 using the instruction code or return null if not defined for the target. */
16860 static GTY(()) int mips_get_builtin_decl_index[NUM_INSN_CODES];
16862 /* MODE is a vector mode whose elements have type TYPE. Return the type
16863 of the vector itself. */
16865 static tree
16866 mips_builtin_vector_type (tree type, machine_mode mode)
16868 static tree types[2 * (int) MAX_MACHINE_MODE];
16869 int mode_index;
16871 mode_index = (int) mode;
16873 if (TREE_CODE (type) == INTEGER_TYPE && TYPE_UNSIGNED (type))
16874 mode_index += MAX_MACHINE_MODE;
16876 if (types[mode_index] == NULL_TREE)
16877 types[mode_index] = build_vector_type_for_mode (type, mode);
16878 return types[mode_index];
16881 /* Return a type for 'const volatile void *'. */
16883 static tree
16884 mips_build_cvpointer_type (void)
16886 static tree cache;
16888 if (cache == NULL_TREE)
16889 cache = build_pointer_type (build_qualified_type
16890 (void_type_node,
16891 TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE));
16892 return cache;
16895 /* Source-level argument types. */
16896 #define MIPS_ATYPE_VOID void_type_node
16897 #define MIPS_ATYPE_INT integer_type_node
16898 #define MIPS_ATYPE_POINTER ptr_type_node
16899 #define MIPS_ATYPE_CVPOINTER mips_build_cvpointer_type ()
16901 /* Standard mode-based argument types. */
16902 #define MIPS_ATYPE_QI intQI_type_node
16903 #define MIPS_ATYPE_UQI unsigned_intQI_type_node
16904 #define MIPS_ATYPE_HI intHI_type_node
16905 #define MIPS_ATYPE_SI intSI_type_node
16906 #define MIPS_ATYPE_USI unsigned_intSI_type_node
16907 #define MIPS_ATYPE_DI intDI_type_node
16908 #define MIPS_ATYPE_UDI unsigned_intDI_type_node
16909 #define MIPS_ATYPE_SF float_type_node
16910 #define MIPS_ATYPE_DF double_type_node
16912 /* Vector argument types. */
16913 #define MIPS_ATYPE_V2SF mips_builtin_vector_type (float_type_node, V2SFmode)
16914 #define MIPS_ATYPE_V2HI mips_builtin_vector_type (intHI_type_node, V2HImode)
16915 #define MIPS_ATYPE_V2SI mips_builtin_vector_type (intSI_type_node, V2SImode)
16916 #define MIPS_ATYPE_V4QI mips_builtin_vector_type (intQI_type_node, V4QImode)
16917 #define MIPS_ATYPE_V4HI mips_builtin_vector_type (intHI_type_node, V4HImode)
16918 #define MIPS_ATYPE_V8QI mips_builtin_vector_type (intQI_type_node, V8QImode)
16920 #define MIPS_ATYPE_V2DI \
16921 mips_builtin_vector_type (long_long_integer_type_node, V2DImode)
16922 #define MIPS_ATYPE_V4SI mips_builtin_vector_type (intSI_type_node, V4SImode)
16923 #define MIPS_ATYPE_V8HI mips_builtin_vector_type (intHI_type_node, V8HImode)
16924 #define MIPS_ATYPE_V16QI mips_builtin_vector_type (intQI_type_node, V16QImode)
16925 #define MIPS_ATYPE_V2DF mips_builtin_vector_type (double_type_node, V2DFmode)
16926 #define MIPS_ATYPE_V4SF mips_builtin_vector_type (float_type_node, V4SFmode)
16928 #define MIPS_ATYPE_UV2DI \
16929 mips_builtin_vector_type (long_long_unsigned_type_node, V2DImode)
16930 #define MIPS_ATYPE_UV4SI \
16931 mips_builtin_vector_type (unsigned_intSI_type_node, V4SImode)
16932 #define MIPS_ATYPE_UV8HI \
16933 mips_builtin_vector_type (unsigned_intHI_type_node, V8HImode)
16934 #define MIPS_ATYPE_UV16QI \
16935 mips_builtin_vector_type (unsigned_intQI_type_node, V16QImode)
16937 #define MIPS_ATYPE_UV2SI \
16938 mips_builtin_vector_type (unsigned_intSI_type_node, V2SImode)
16939 #define MIPS_ATYPE_UV4HI \
16940 mips_builtin_vector_type (unsigned_intHI_type_node, V4HImode)
16941 #define MIPS_ATYPE_UV8QI \
16942 mips_builtin_vector_type (unsigned_intQI_type_node, V8QImode)
16944 /* MIPS_FTYPE_ATYPESN takes N MIPS_FTYPES-like type codes and lists
16945 their associated MIPS_ATYPEs. */
16946 #define MIPS_FTYPE_ATYPES1(A, B) \
16947 MIPS_ATYPE_##A, MIPS_ATYPE_##B
16949 #define MIPS_FTYPE_ATYPES2(A, B, C) \
16950 MIPS_ATYPE_##A, MIPS_ATYPE_##B, MIPS_ATYPE_##C
16952 #define MIPS_FTYPE_ATYPES3(A, B, C, D) \
16953 MIPS_ATYPE_##A, MIPS_ATYPE_##B, MIPS_ATYPE_##C, MIPS_ATYPE_##D
16955 #define MIPS_FTYPE_ATYPES4(A, B, C, D, E) \
16956 MIPS_ATYPE_##A, MIPS_ATYPE_##B, MIPS_ATYPE_##C, MIPS_ATYPE_##D, \
16957 MIPS_ATYPE_##E
16959 /* Return the function type associated with function prototype TYPE. */
16961 static tree
16962 mips_build_function_type (enum mips_function_type type)
16964 static tree types[(int) MIPS_MAX_FTYPE_MAX];
16966 if (types[(int) type] == NULL_TREE)
16967 switch (type)
16969 #define DEF_MIPS_FTYPE(NUM, ARGS) \
16970 case MIPS_FTYPE_NAME##NUM ARGS: \
16971 types[(int) type] \
16972 = build_function_type_list (MIPS_FTYPE_ATYPES##NUM ARGS, \
16973 NULL_TREE); \
16974 break;
16975 #include "config/mips/mips-ftypes.def"
16976 #undef DEF_MIPS_FTYPE
16977 default:
16978 gcc_unreachable ();
16981 return types[(int) type];
16984 /* Implement TARGET_INIT_BUILTINS. */
16986 static void
16987 mips_init_builtins (void)
16989 const struct mips_builtin_description *d;
16990 unsigned int i;
16992 /* Iterate through all of the bdesc arrays, initializing all of the
16993 builtin functions. */
16994 for (i = 0; i < ARRAY_SIZE (mips_builtins); i++)
16996 d = &mips_builtins[i];
16997 if (d->avail ())
16999 mips_builtin_decls[i]
17000 = add_builtin_function (d->name,
17001 mips_build_function_type (d->function_type),
17002 i, BUILT_IN_MD, NULL, NULL);
17003 if (mips_builtin_decls[i] && d->is_pure)
17004 DECL_PURE_P (mips_builtin_decls[i]) = 1;
17005 mips_get_builtin_decl_index[d->icode] = i;
17010 /* Implement TARGET_BUILTIN_DECL. */
17012 static tree
17013 mips_builtin_decl (unsigned int code, bool initialize_p ATTRIBUTE_UNUSED)
17015 if (code >= ARRAY_SIZE (mips_builtins))
17016 return error_mark_node;
17017 return mips_builtin_decls[code];
17020 /* Implement TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION. */
17022 static tree
17023 mips_builtin_vectorized_function (unsigned int fn, tree type_out, tree type_in)
17025 machine_mode in_mode, out_mode;
17026 int in_n, out_n;
17028 if (TREE_CODE (type_out) != VECTOR_TYPE
17029 || TREE_CODE (type_in) != VECTOR_TYPE
17030 || !ISA_HAS_MSA)
17031 return NULL_TREE;
17033 out_mode = TYPE_MODE (TREE_TYPE (type_out));
17034 out_n = TYPE_VECTOR_SUBPARTS (type_out);
17035 in_mode = TYPE_MODE (TREE_TYPE (type_in));
17036 in_n = TYPE_VECTOR_SUBPARTS (type_in);
17038 /* INSN is the name of the associated instruction pattern, without
17039 the leading CODE_FOR_. */
17040 #define MIPS_GET_BUILTIN(INSN) \
17041 mips_builtin_decls[mips_get_builtin_decl_index[CODE_FOR_##INSN]]
17043 switch (fn)
17045 case BUILT_IN_SQRT:
17046 if (out_mode == DFmode && out_n == 2
17047 && in_mode == DFmode && in_n == 2)
17048 return MIPS_GET_BUILTIN (msa_fsqrt_d);
17049 break;
17050 case BUILT_IN_SQRTF:
17051 if (out_mode == SFmode && out_n == 4
17052 && in_mode == SFmode && in_n == 4)
17053 return MIPS_GET_BUILTIN (msa_fsqrt_w);
17054 break;
17055 default:
17056 break;
17059 return NULL_TREE;
17062 /* Take argument ARGNO from EXP's argument list and convert it into
17063 an expand operand. Store the operand in *OP. */
17065 static void
17066 mips_prepare_builtin_arg (struct expand_operand *op, tree exp,
17067 unsigned int argno)
17069 tree arg;
17070 rtx value;
17072 arg = CALL_EXPR_ARG (exp, argno);
17073 value = expand_normal (arg);
17074 create_input_operand (op, value, TYPE_MODE (TREE_TYPE (arg)));
17077 /* Expand instruction ICODE as part of a built-in function sequence.
17078 Use the first NOPS elements of OPS as the instruction's operands.
17079 HAS_TARGET_P is true if operand 0 is a target; it is false if the
17080 instruction has no target.
17082 Return the target rtx if HAS_TARGET_P, otherwise return const0_rtx. */
17084 static rtx
17085 mips_expand_builtin_insn (enum insn_code icode, unsigned int nops,
17086 struct expand_operand *ops, bool has_target_p)
17088 machine_mode imode;
17089 int rangelo = 0, rangehi = 0, error_opno = 0;
17090 rtx sireg;
17092 switch (icode)
17094 /* The third operand of these instructions is in SImode, so we need to
17095 bring the corresponding builtin argument from QImode into SImode. */
17096 case CODE_FOR_loongson_pshufh:
17097 case CODE_FOR_loongson_psllh:
17098 case CODE_FOR_loongson_psllw:
17099 case CODE_FOR_loongson_psrah:
17100 case CODE_FOR_loongson_psraw:
17101 case CODE_FOR_loongson_psrlh:
17102 case CODE_FOR_loongson_psrlw:
17103 gcc_assert (has_target_p && nops == 3 && ops[2].mode == QImode);
17104 sireg = gen_reg_rtx (SImode);
17105 emit_insn (gen_zero_extendqisi2 (sireg,
17106 force_reg (QImode, ops[2].value)));
17107 ops[2].value = sireg;
17108 ops[2].mode = SImode;
17109 break;
17111 case CODE_FOR_msa_addvi_b:
17112 case CODE_FOR_msa_addvi_h:
17113 case CODE_FOR_msa_addvi_w:
17114 case CODE_FOR_msa_addvi_d:
17115 case CODE_FOR_msa_clti_u_b:
17116 case CODE_FOR_msa_clti_u_h:
17117 case CODE_FOR_msa_clti_u_w:
17118 case CODE_FOR_msa_clti_u_d:
17119 case CODE_FOR_msa_clei_u_b:
17120 case CODE_FOR_msa_clei_u_h:
17121 case CODE_FOR_msa_clei_u_w:
17122 case CODE_FOR_msa_clei_u_d:
17123 case CODE_FOR_msa_maxi_u_b:
17124 case CODE_FOR_msa_maxi_u_h:
17125 case CODE_FOR_msa_maxi_u_w:
17126 case CODE_FOR_msa_maxi_u_d:
17127 case CODE_FOR_msa_mini_u_b:
17128 case CODE_FOR_msa_mini_u_h:
17129 case CODE_FOR_msa_mini_u_w:
17130 case CODE_FOR_msa_mini_u_d:
17131 case CODE_FOR_msa_subvi_b:
17132 case CODE_FOR_msa_subvi_h:
17133 case CODE_FOR_msa_subvi_w:
17134 case CODE_FOR_msa_subvi_d:
17135 gcc_assert (has_target_p && nops == 3);
17136 /* We only generate a vector of constants iff the second argument
17137 is an immediate. We also validate the range of the immediate. */
17138 if (CONST_INT_P (ops[2].value))
17140 rangelo = 0;
17141 rangehi = 31;
17142 if (IN_RANGE (INTVAL (ops[2].value), rangelo, rangehi))
17144 ops[2].mode = ops[0].mode;
17145 ops[2].value = mips_gen_const_int_vector (ops[2].mode,
17146 INTVAL (ops[2].value));
17148 else
17149 error_opno = 2;
17151 break;
17153 case CODE_FOR_msa_ceqi_b:
17154 case CODE_FOR_msa_ceqi_h:
17155 case CODE_FOR_msa_ceqi_w:
17156 case CODE_FOR_msa_ceqi_d:
17157 case CODE_FOR_msa_clti_s_b:
17158 case CODE_FOR_msa_clti_s_h:
17159 case CODE_FOR_msa_clti_s_w:
17160 case CODE_FOR_msa_clti_s_d:
17161 case CODE_FOR_msa_clei_s_b:
17162 case CODE_FOR_msa_clei_s_h:
17163 case CODE_FOR_msa_clei_s_w:
17164 case CODE_FOR_msa_clei_s_d:
17165 case CODE_FOR_msa_maxi_s_b:
17166 case CODE_FOR_msa_maxi_s_h:
17167 case CODE_FOR_msa_maxi_s_w:
17168 case CODE_FOR_msa_maxi_s_d:
17169 case CODE_FOR_msa_mini_s_b:
17170 case CODE_FOR_msa_mini_s_h:
17171 case CODE_FOR_msa_mini_s_w:
17172 case CODE_FOR_msa_mini_s_d:
17173 gcc_assert (has_target_p && nops == 3);
17174 /* We only generate a vector of constants iff the second argument
17175 is an immediate. We also validate the range of the immediate. */
17176 if (CONST_INT_P (ops[2].value))
17178 rangelo = -16;
17179 rangehi = 15;
17180 if (IN_RANGE (INTVAL (ops[2].value), rangelo, rangehi))
17182 ops[2].mode = ops[0].mode;
17183 ops[2].value = mips_gen_const_int_vector (ops[2].mode,
17184 INTVAL (ops[2].value));
17186 else
17187 error_opno = 2;
17189 break;
17191 case CODE_FOR_msa_andi_b:
17192 case CODE_FOR_msa_ori_b:
17193 case CODE_FOR_msa_nori_b:
17194 case CODE_FOR_msa_xori_b:
17195 gcc_assert (has_target_p && nops == 3);
17196 if (!CONST_INT_P (ops[2].value))
17197 break;
17198 ops[2].mode = ops[0].mode;
17199 ops[2].value = mips_gen_const_int_vector (ops[2].mode,
17200 INTVAL (ops[2].value));
17201 break;
17203 case CODE_FOR_msa_bmzi_b:
17204 case CODE_FOR_msa_bmnzi_b:
17205 case CODE_FOR_msa_bseli_b:
17206 gcc_assert (has_target_p && nops == 4);
17207 if (!CONST_INT_P (ops[3].value))
17208 break;
17209 ops[3].mode = ops[0].mode;
17210 ops[3].value = mips_gen_const_int_vector (ops[3].mode,
17211 INTVAL (ops[3].value));
17212 break;
17214 case CODE_FOR_msa_fill_b:
17215 case CODE_FOR_msa_fill_h:
17216 case CODE_FOR_msa_fill_w:
17217 case CODE_FOR_msa_fill_d:
17218 /* Map the built-ins to vector fill operations. We need fix up the mode
17219 for the element being inserted. */
17220 gcc_assert (has_target_p && nops == 2);
17221 imode = GET_MODE_INNER (ops[0].mode);
17222 ops[1].value = lowpart_subreg (imode, ops[1].value, ops[1].mode);
17223 ops[1].mode = imode;
17224 break;
17226 case CODE_FOR_msa_ilvl_b:
17227 case CODE_FOR_msa_ilvl_h:
17228 case CODE_FOR_msa_ilvl_w:
17229 case CODE_FOR_msa_ilvl_d:
17230 case CODE_FOR_msa_ilvr_b:
17231 case CODE_FOR_msa_ilvr_h:
17232 case CODE_FOR_msa_ilvr_w:
17233 case CODE_FOR_msa_ilvr_d:
17234 case CODE_FOR_msa_ilvev_b:
17235 case CODE_FOR_msa_ilvev_h:
17236 case CODE_FOR_msa_ilvev_w:
17237 case CODE_FOR_msa_ilvod_b:
17238 case CODE_FOR_msa_ilvod_h:
17239 case CODE_FOR_msa_ilvod_w:
17240 case CODE_FOR_msa_pckev_b:
17241 case CODE_FOR_msa_pckev_h:
17242 case CODE_FOR_msa_pckev_w:
17243 case CODE_FOR_msa_pckod_b:
17244 case CODE_FOR_msa_pckod_h:
17245 case CODE_FOR_msa_pckod_w:
17246 /* Swap the operands 1 and 2 for interleave operations. Built-ins follow
17247 convention of ISA, which have op1 as higher component and op2 as lower
17248 component. However, the VEC_PERM op in tree and vec_concat in RTL
17249 expects first operand to be lower component, because of which this
17250 swap is needed for builtins. */
17251 gcc_assert (has_target_p && nops == 3);
17252 std::swap (ops[1], ops[2]);
17253 break;
17255 case CODE_FOR_msa_maddv_b:
17256 case CODE_FOR_msa_maddv_h:
17257 case CODE_FOR_msa_maddv_w:
17258 case CODE_FOR_msa_maddv_d:
17259 case CODE_FOR_msa_fmadd_w:
17260 case CODE_FOR_msa_fmadd_d:
17261 case CODE_FOR_msa_fmsub_w:
17262 case CODE_FOR_msa_fmsub_d:
17263 /* fma(a, b, c) results into (a * b + c), however builtin_msa_fmadd expects
17264 it to be (a + b * c). Swap the 1st and 3rd operands. */
17265 std::swap (ops[1], ops[3]);
17266 break;
17268 case CODE_FOR_msa_slli_b:
17269 case CODE_FOR_msa_slli_h:
17270 case CODE_FOR_msa_slli_w:
17271 case CODE_FOR_msa_slli_d:
17272 case CODE_FOR_msa_srai_b:
17273 case CODE_FOR_msa_srai_h:
17274 case CODE_FOR_msa_srai_w:
17275 case CODE_FOR_msa_srai_d:
17276 case CODE_FOR_msa_srli_b:
17277 case CODE_FOR_msa_srli_h:
17278 case CODE_FOR_msa_srli_w:
17279 case CODE_FOR_msa_srli_d:
17280 gcc_assert (has_target_p && nops == 3);
17281 if (CONST_INT_P (ops[2].value))
17283 rangelo = 0;
17284 rangehi = GET_MODE_UNIT_BITSIZE (ops[0].mode) - 1;
17285 if (IN_RANGE (INTVAL (ops[2].value), rangelo, rangehi))
17287 ops[2].mode = ops[0].mode;
17288 ops[2].value = mips_gen_const_int_vector (ops[2].mode,
17289 INTVAL (ops[2].value));
17291 else
17292 error_opno = 2;
17294 break;
17296 case CODE_FOR_msa_insert_b:
17297 case CODE_FOR_msa_insert_h:
17298 case CODE_FOR_msa_insert_w:
17299 case CODE_FOR_msa_insert_d:
17300 /* Map the built-ins to insert operations. We need to swap operands,
17301 fix up the mode for the element being inserted, and generate
17302 a bit mask for vec_merge. */
17303 gcc_assert (has_target_p && nops == 4);
17304 std::swap (ops[1], ops[2]);
17305 std::swap (ops[1], ops[3]);
17306 imode = GET_MODE_INNER (ops[0].mode);
17307 ops[1].value = lowpart_subreg (imode, ops[1].value, ops[1].mode);
17308 ops[1].mode = imode;
17309 rangelo = 0;
17310 rangehi = GET_MODE_NUNITS (ops[0].mode) - 1;
17311 if (CONST_INT_P (ops[3].value)
17312 && IN_RANGE (INTVAL (ops[3].value), rangelo, rangehi))
17313 ops[3].value = GEN_INT (1 << INTVAL (ops[3].value));
17314 else
17315 error_opno = 2;
17316 break;
17318 case CODE_FOR_msa_insve_b:
17319 case CODE_FOR_msa_insve_h:
17320 case CODE_FOR_msa_insve_w:
17321 case CODE_FOR_msa_insve_d:
17322 /* Map the built-ins to element insert operations. We need to swap
17323 operands and generate a bit mask. */
17324 gcc_assert (has_target_p && nops == 4);
17325 std::swap (ops[1], ops[2]);
17326 std::swap (ops[1], ops[3]);
17327 rangelo = 0;
17328 rangehi = GET_MODE_NUNITS (ops[0].mode) - 1;
17329 if (CONST_INT_P (ops[3].value)
17330 && IN_RANGE (INTVAL (ops[3].value), rangelo, rangehi))
17331 ops[3].value = GEN_INT (1 << INTVAL (ops[3].value));
17332 else
17333 error_opno = 2;
17334 break;
17336 case CODE_FOR_msa_shf_b:
17337 case CODE_FOR_msa_shf_h:
17338 case CODE_FOR_msa_shf_w:
17339 case CODE_FOR_msa_shf_w_f:
17340 gcc_assert (has_target_p && nops == 3);
17341 ops[2].value = mips_gen_const_int_vector_shuffle (ops[0].mode,
17342 INTVAL (ops[2].value));
17343 break;
17345 case CODE_FOR_msa_vshf_b:
17346 case CODE_FOR_msa_vshf_h:
17347 case CODE_FOR_msa_vshf_w:
17348 case CODE_FOR_msa_vshf_d:
17349 gcc_assert (has_target_p && nops == 4);
17350 std::swap (ops[1], ops[3]);
17351 break;
17353 case CODE_FOR_msa_dpadd_s_w:
17354 case CODE_FOR_msa_dpadd_s_h:
17355 case CODE_FOR_msa_dpadd_s_d:
17356 case CODE_FOR_msa_dpadd_u_w:
17357 case CODE_FOR_msa_dpadd_u_h:
17358 case CODE_FOR_msa_dpadd_u_d:
17359 case CODE_FOR_msa_dpsub_s_w:
17360 case CODE_FOR_msa_dpsub_s_h:
17361 case CODE_FOR_msa_dpsub_s_d:
17362 case CODE_FOR_msa_dpsub_u_w:
17363 case CODE_FOR_msa_dpsub_u_h:
17364 case CODE_FOR_msa_dpsub_u_d:
17365 /* Force the operands which correspond to the same in-out register
17366 to have the same pseudo assigned to them. If the input operand
17367 is not REG, create one for it. */
17368 if (!REG_P (ops[1].value))
17369 ops[1].value = copy_to_mode_reg (ops[1].mode, ops[1].value);
17370 create_output_operand (&ops[0], ops[1].value, ops[1].mode);
17371 break;
17373 default:
17374 break;
17377 if (error_opno != 0)
17379 error ("argument %d to the built-in must be a constant"
17380 " in range %d to %d", error_opno, rangelo, rangehi);
17381 return has_target_p ? gen_reg_rtx (ops[0].mode) : const0_rtx;
17383 else if (!maybe_expand_insn (icode, nops, ops))
17385 error ("invalid argument to built-in function");
17386 return has_target_p ? gen_reg_rtx (ops[0].mode) : const0_rtx;
17388 return has_target_p ? ops[0].value : const0_rtx;
17391 /* Expand a floating-point comparison for built-in function call EXP.
17392 The first NARGS arguments are the values to be compared. ICODE is
17393 the .md pattern that does the comparison and COND is the condition
17394 that is being tested. Return an rtx for the result. */
17396 static rtx
17397 mips_expand_builtin_compare_1 (enum insn_code icode,
17398 enum mips_fp_condition cond,
17399 tree exp, int nargs)
17401 struct expand_operand ops[MAX_RECOG_OPERANDS];
17402 rtx output;
17403 int opno, argno;
17405 /* The instruction should have a target operand, an operand for each
17406 argument, and an operand for COND. */
17407 gcc_assert (nargs + 2 == insn_data[(int) icode].n_generator_args);
17409 output = mips_allocate_fcc (insn_data[(int) icode].operand[0].mode);
17410 opno = 0;
17411 create_fixed_operand (&ops[opno++], output);
17412 for (argno = 0; argno < nargs; argno++)
17413 mips_prepare_builtin_arg (&ops[opno++], exp, argno);
17414 create_integer_operand (&ops[opno++], (int) cond);
17415 return mips_expand_builtin_insn (icode, opno, ops, true);
17418 /* Expand a MIPS_BUILTIN_DIRECT or MIPS_BUILTIN_DIRECT_NO_TARGET function;
17419 HAS_TARGET_P says which. EXP is the CALL_EXPR that calls the function
17420 and ICODE is the code of the associated .md pattern. TARGET, if nonnull,
17421 suggests a good place to put the result. */
17423 static rtx
17424 mips_expand_builtin_direct (enum insn_code icode, rtx target, tree exp,
17425 bool has_target_p)
17427 struct expand_operand ops[MAX_RECOG_OPERANDS];
17428 int opno, argno;
17430 /* Map any target to operand 0. */
17431 opno = 0;
17432 if (has_target_p)
17433 create_output_operand (&ops[opno++], target, TYPE_MODE (TREE_TYPE (exp)));
17435 /* Map the arguments to the other operands. */
17436 gcc_assert (opno + call_expr_nargs (exp)
17437 == insn_data[icode].n_generator_args);
17438 for (argno = 0; argno < call_expr_nargs (exp); argno++)
17439 mips_prepare_builtin_arg (&ops[opno++], exp, argno);
17441 return mips_expand_builtin_insn (icode, opno, ops, has_target_p);
17444 /* Expand a __builtin_mips_movt_*_ps or __builtin_mips_movf_*_ps
17445 function; TYPE says which. EXP is the CALL_EXPR that calls the
17446 function, ICODE is the instruction that should be used to compare
17447 the first two arguments, and COND is the condition it should test.
17448 TARGET, if nonnull, suggests a good place to put the result. */
17450 static rtx
17451 mips_expand_builtin_movtf (enum mips_builtin_type type,
17452 enum insn_code icode, enum mips_fp_condition cond,
17453 rtx target, tree exp)
17455 struct expand_operand ops[4];
17456 rtx cmp_result;
17458 cmp_result = mips_expand_builtin_compare_1 (icode, cond, exp, 2);
17459 create_output_operand (&ops[0], target, TYPE_MODE (TREE_TYPE (exp)));
17460 if (type == MIPS_BUILTIN_MOVT)
17462 mips_prepare_builtin_arg (&ops[2], exp, 2);
17463 mips_prepare_builtin_arg (&ops[1], exp, 3);
17465 else
17467 mips_prepare_builtin_arg (&ops[1], exp, 2);
17468 mips_prepare_builtin_arg (&ops[2], exp, 3);
17470 create_fixed_operand (&ops[3], cmp_result);
17471 return mips_expand_builtin_insn (CODE_FOR_mips_cond_move_tf_ps,
17472 4, ops, true);
17475 /* Expand an MSA built-in for a compare and branch instruction specified by
17476 ICODE, set a general-purpose register to 1 if the branch was taken,
17477 0 otherwise. */
17479 static rtx
17480 mips_expand_builtin_msa_test_branch (enum insn_code icode, tree exp)
17482 struct expand_operand ops[3];
17483 rtx_insn *cbranch;
17484 rtx_code_label *true_label, *done_label;
17485 rtx cmp_result;
17487 true_label = gen_label_rtx ();
17488 done_label = gen_label_rtx ();
17490 create_input_operand (&ops[0], true_label, TYPE_MODE (TREE_TYPE (exp)));
17491 mips_prepare_builtin_arg (&ops[1], exp, 0);
17492 create_fixed_operand (&ops[2], const0_rtx);
17494 /* Make sure that the operand 1 is a REG. */
17495 if (GET_CODE (ops[1].value) != REG)
17496 ops[1].value = force_reg (ops[1].mode, ops[1].value);
17498 if ((cbranch = maybe_gen_insn (icode, 3, ops)) == NULL_RTX)
17499 error ("failed to expand built-in function");
17501 cmp_result = gen_reg_rtx (SImode);
17503 /* First assume that CMP_RESULT is false. */
17504 mips_emit_move (cmp_result, const0_rtx);
17506 /* Branch to TRUE_LABEL if CBRANCH is taken and DONE_LABEL otherwise. */
17507 emit_jump_insn (cbranch);
17508 emit_jump_insn (gen_jump (done_label));
17509 emit_barrier ();
17511 /* Set CMP_RESULT to true if the branch was taken. */
17512 emit_label (true_label);
17513 mips_emit_move (cmp_result, const1_rtx);
17515 emit_label (done_label);
17516 return cmp_result;
17519 /* Move VALUE_IF_TRUE into TARGET if CONDITION is true; move VALUE_IF_FALSE
17520 into TARGET otherwise. Return TARGET. */
17522 static rtx
17523 mips_builtin_branch_and_move (rtx condition, rtx target,
17524 rtx value_if_true, rtx value_if_false)
17526 rtx_code_label *true_label, *done_label;
17528 true_label = gen_label_rtx ();
17529 done_label = gen_label_rtx ();
17531 /* First assume that CONDITION is false. */
17532 mips_emit_move (target, value_if_false);
17534 /* Branch to TRUE_LABEL if CONDITION is true and DONE_LABEL otherwise. */
17535 emit_jump_insn (gen_condjump (condition, true_label));
17536 emit_jump_insn (gen_jump (done_label));
17537 emit_barrier ();
17539 /* Fix TARGET if CONDITION is true. */
17540 emit_label (true_label);
17541 mips_emit_move (target, value_if_true);
17543 emit_label (done_label);
17544 return target;
17547 /* Expand a comparison built-in function of type BUILTIN_TYPE. EXP is
17548 the CALL_EXPR that calls the function, ICODE is the code of the
17549 comparison instruction, and COND is the condition it should test.
17550 TARGET, if nonnull, suggests a good place to put the boolean result. */
17552 static rtx
17553 mips_expand_builtin_compare (enum mips_builtin_type builtin_type,
17554 enum insn_code icode, enum mips_fp_condition cond,
17555 rtx target, tree exp)
17557 rtx offset, condition, cmp_result;
17559 if (target == 0 || GET_MODE (target) != SImode)
17560 target = gen_reg_rtx (SImode);
17561 cmp_result = mips_expand_builtin_compare_1 (icode, cond, exp,
17562 call_expr_nargs (exp));
17564 /* If the comparison sets more than one register, we define the result
17565 to be 0 if all registers are false and -1 if all registers are true.
17566 The value of the complete result is indeterminate otherwise. */
17567 switch (builtin_type)
17569 case MIPS_BUILTIN_CMP_ALL:
17570 condition = gen_rtx_NE (VOIDmode, cmp_result, constm1_rtx);
17571 return mips_builtin_branch_and_move (condition, target,
17572 const0_rtx, const1_rtx);
17574 case MIPS_BUILTIN_CMP_UPPER:
17575 case MIPS_BUILTIN_CMP_LOWER:
17576 offset = GEN_INT (builtin_type == MIPS_BUILTIN_CMP_UPPER);
17577 condition = gen_single_cc (cmp_result, offset);
17578 return mips_builtin_branch_and_move (condition, target,
17579 const1_rtx, const0_rtx);
17581 default:
17582 condition = gen_rtx_NE (VOIDmode, cmp_result, const0_rtx);
17583 return mips_builtin_branch_and_move (condition, target,
17584 const1_rtx, const0_rtx);
17588 /* Expand a bposge built-in function of type BUILTIN_TYPE. TARGET,
17589 if nonnull, suggests a good place to put the boolean result. */
17591 static rtx
17592 mips_expand_builtin_bposge (enum mips_builtin_type builtin_type, rtx target)
17594 rtx condition, cmp_result;
17595 int cmp_value;
17597 if (target == 0 || GET_MODE (target) != SImode)
17598 target = gen_reg_rtx (SImode);
17600 cmp_result = gen_rtx_REG (CCDSPmode, CCDSP_PO_REGNUM);
17602 if (builtin_type == MIPS_BUILTIN_BPOSGE32)
17603 cmp_value = 32;
17604 else
17605 gcc_assert (0);
17607 condition = gen_rtx_GE (VOIDmode, cmp_result, GEN_INT (cmp_value));
17608 return mips_builtin_branch_and_move (condition, target,
17609 const1_rtx, const0_rtx);
17612 /* Implement TARGET_EXPAND_BUILTIN. */
17614 static rtx
17615 mips_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
17616 machine_mode mode, int ignore)
17618 tree fndecl;
17619 unsigned int fcode, avail;
17620 const struct mips_builtin_description *d;
17622 fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
17623 fcode = DECL_MD_FUNCTION_CODE (fndecl);
17624 gcc_assert (fcode < ARRAY_SIZE (mips_builtins));
17625 d = &mips_builtins[fcode];
17626 avail = d->avail ();
17627 gcc_assert (avail != 0);
17628 if (TARGET_MIPS16 && !(avail & BUILTIN_AVAIL_MIPS16)
17629 && (!TARGET_MIPS16E2 || !(avail & BUILTIN_AVAIL_MIPS16E2)))
17631 error ("built-in function %qE not supported for MIPS16",
17632 DECL_NAME (fndecl));
17633 return ignore ? const0_rtx : CONST0_RTX (mode);
17635 switch (d->builtin_type)
17637 case MIPS_BUILTIN_DIRECT:
17638 return mips_expand_builtin_direct (d->icode, target, exp, true);
17640 case MIPS_BUILTIN_DIRECT_NO_TARGET:
17641 return mips_expand_builtin_direct (d->icode, target, exp, false);
17643 case MIPS_BUILTIN_MOVT:
17644 case MIPS_BUILTIN_MOVF:
17645 return mips_expand_builtin_movtf (d->builtin_type, d->icode,
17646 d->cond, target, exp);
17648 case MIPS_BUILTIN_CMP_ANY:
17649 case MIPS_BUILTIN_CMP_ALL:
17650 case MIPS_BUILTIN_CMP_UPPER:
17651 case MIPS_BUILTIN_CMP_LOWER:
17652 case MIPS_BUILTIN_CMP_SINGLE:
17653 return mips_expand_builtin_compare (d->builtin_type, d->icode,
17654 d->cond, target, exp);
17656 case MIPS_BUILTIN_MSA_TEST_BRANCH:
17657 return mips_expand_builtin_msa_test_branch (d->icode, exp);
17659 case MIPS_BUILTIN_BPOSGE32:
17660 return mips_expand_builtin_bposge (d->builtin_type, target);
17662 gcc_unreachable ();
17665 /* An entry in the MIPS16 constant pool. VALUE is the pool constant,
17666 MODE is its mode, and LABEL is the CODE_LABEL associated with it. */
17667 struct mips16_constant {
17668 struct mips16_constant *next;
17669 rtx value;
17670 rtx_code_label *label;
17671 machine_mode mode;
17674 /* Information about an incomplete MIPS16 constant pool. FIRST is the
17675 first constant, HIGHEST_ADDRESS is the highest address that the first
17676 byte of the pool can have, and INSN_ADDRESS is the current instruction
17677 address. */
17678 struct mips16_constant_pool {
17679 struct mips16_constant *first;
17680 int highest_address;
17681 int insn_address;
17684 /* Add constant VALUE to POOL and return its label. MODE is the
17685 value's mode (used for CONST_INTs, etc.). */
17687 static rtx_code_label *
17688 mips16_add_constant (struct mips16_constant_pool *pool,
17689 rtx value, machine_mode mode)
17691 struct mips16_constant **p, *c;
17692 bool first_of_size_p;
17694 /* See whether the constant is already in the pool. If so, return the
17695 existing label, otherwise leave P pointing to the place where the
17696 constant should be added.
17698 Keep the pool sorted in increasing order of mode size so that we can
17699 reduce the number of alignments needed. */
17700 first_of_size_p = true;
17701 for (p = &pool->first; *p != 0; p = &(*p)->next)
17703 if (mode == (*p)->mode && rtx_equal_p (value, (*p)->value))
17704 return (*p)->label;
17705 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE ((*p)->mode))
17706 break;
17707 if (GET_MODE_SIZE (mode) == GET_MODE_SIZE ((*p)->mode))
17708 first_of_size_p = false;
17711 /* In the worst case, the constant needed by the earliest instruction
17712 will end up at the end of the pool. The entire pool must then be
17713 accessible from that instruction.
17715 When adding the first constant, set the pool's highest address to
17716 the address of the first out-of-range byte. Adjust this address
17717 downwards each time a new constant is added. */
17718 if (pool->first == 0)
17719 /* For LWPC, ADDIUPC and DADDIUPC, the base PC value is the address
17720 of the instruction with the lowest two bits clear. The base PC
17721 value for LDPC has the lowest three bits clear. Assume the worst
17722 case here; namely that the PC-relative instruction occupies the
17723 last 2 bytes in an aligned word. */
17724 pool->highest_address = pool->insn_address - (UNITS_PER_WORD - 2) + 0x8000;
17725 pool->highest_address -= GET_MODE_SIZE (mode);
17726 if (first_of_size_p)
17727 /* Take into account the worst possible padding due to alignment. */
17728 pool->highest_address -= GET_MODE_SIZE (mode) - 1;
17730 /* Create a new entry. */
17731 c = XNEW (struct mips16_constant);
17732 c->value = value;
17733 c->mode = mode;
17734 c->label = gen_label_rtx ();
17735 c->next = *p;
17736 *p = c;
17738 return c->label;
17741 /* Output constant VALUE after instruction INSN and return the last
17742 instruction emitted. MODE is the mode of the constant. */
17744 static rtx_insn *
17745 mips16_emit_constants_1 (machine_mode mode, rtx value, rtx_insn *insn)
17747 if (SCALAR_INT_MODE_P (mode) || ALL_SCALAR_FIXED_POINT_MODE_P (mode))
17749 rtx size = GEN_INT (GET_MODE_SIZE (mode));
17750 return emit_insn_after (gen_consttable_int (value, size), insn);
17753 if (SCALAR_FLOAT_MODE_P (mode))
17754 return emit_insn_after (gen_consttable_float (value), insn);
17756 if (VECTOR_MODE_P (mode))
17758 int i;
17760 for (i = 0; i < CONST_VECTOR_NUNITS (value); i++)
17761 insn = mips16_emit_constants_1 (GET_MODE_INNER (mode),
17762 CONST_VECTOR_ELT (value, i), insn);
17763 return insn;
17766 gcc_unreachable ();
17769 /* Dump out the constants in CONSTANTS after INSN. Record the initial
17770 label number in the `consttable' and `consttable_end' insns emitted
17771 at the beginning and the end of the constant pool respectively, so
17772 that individual pools can be uniquely marked as data for the purpose
17773 of disassembly. */
17775 static void
17776 mips16_emit_constants (struct mips16_constant *constants, rtx_insn *insn)
17778 int label_num = constants ? CODE_LABEL_NUMBER (constants->label) : 0;
17779 struct mips16_constant *c, *next;
17780 int align;
17782 align = 0;
17783 if (constants)
17784 insn = emit_insn_after (gen_consttable (GEN_INT (label_num)), insn);
17785 for (c = constants; c != NULL; c = next)
17787 /* If necessary, increase the alignment of PC. */
17788 if (align < GET_MODE_SIZE (c->mode))
17790 int align_log = floor_log2 (GET_MODE_SIZE (c->mode));
17791 insn = emit_insn_after (gen_align (GEN_INT (align_log)), insn);
17793 align = GET_MODE_SIZE (c->mode);
17795 insn = emit_label_after (c->label, insn);
17796 insn = mips16_emit_constants_1 (c->mode, c->value, insn);
17798 next = c->next;
17799 free (c);
17801 if (constants)
17802 insn = emit_insn_after (gen_consttable_end (GEN_INT (label_num)), insn);
17804 emit_barrier_after (insn);
17807 /* Return the length of instruction INSN. */
17809 static int
17810 mips16_insn_length (rtx_insn *insn)
17812 if (JUMP_TABLE_DATA_P (insn))
17814 rtx body = PATTERN (insn);
17815 if (GET_CODE (body) == ADDR_VEC)
17816 return GET_MODE_SIZE (GET_MODE (body)) * XVECLEN (body, 0);
17817 else if (GET_CODE (body) == ADDR_DIFF_VEC)
17818 return GET_MODE_SIZE (GET_MODE (body)) * XVECLEN (body, 1);
17819 else
17820 gcc_unreachable ();
17822 return get_attr_length (insn);
17825 /* If *X is a symbolic constant that refers to the constant pool, add
17826 the constant to POOL and rewrite *X to use the constant's label. */
17828 static void
17829 mips16_rewrite_pool_constant (struct mips16_constant_pool *pool, rtx *x)
17831 rtx base, offset;
17832 rtx_code_label *label;
17834 split_const (*x, &base, &offset);
17835 if (GET_CODE (base) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (base))
17837 label = mips16_add_constant (pool, copy_rtx (get_pool_constant (base)),
17838 get_pool_mode (base));
17839 base = gen_rtx_LABEL_REF (Pmode, label);
17840 *x = mips_unspec_address_offset (base, offset, SYMBOL_PC_RELATIVE);
17844 /* Rewrite INSN so that constant pool references refer to the constant's
17845 label instead. */
17847 static void
17848 mips16_rewrite_pool_refs (rtx_insn *insn, struct mips16_constant_pool *pool)
17850 subrtx_ptr_iterator::array_type array;
17851 FOR_EACH_SUBRTX_PTR (iter, array, &PATTERN (insn), ALL)
17853 rtx *loc = *iter;
17855 if (force_to_mem_operand (*loc, Pmode))
17857 rtx mem = force_const_mem (GET_MODE (*loc), *loc);
17858 validate_change (insn, loc, mem, false);
17861 if (MEM_P (*loc))
17863 mips16_rewrite_pool_constant (pool, &XEXP (*loc, 0));
17864 iter.skip_subrtxes ();
17866 else
17868 if (TARGET_MIPS16_TEXT_LOADS)
17869 mips16_rewrite_pool_constant (pool, loc);
17870 if (GET_CODE (*loc) == CONST
17871 /* Don't rewrite the __mips16_rdwr symbol. */
17872 || (GET_CODE (*loc) == UNSPEC
17873 && XINT (*loc, 1) == UNSPEC_TLS_GET_TP))
17874 iter.skip_subrtxes ();
17879 /* Return whether CFG is used in mips_reorg. */
17881 static bool
17882 mips_cfg_in_reorg (void)
17884 return (mips_r10k_cache_barrier != R10K_CACHE_BARRIER_NONE
17885 || TARGET_RELAX_PIC_CALLS);
17888 /* Build MIPS16 constant pools. Split the instructions if SPLIT_P,
17889 otherwise assume that they are already split. */
17891 static void
17892 mips16_lay_out_constants (bool split_p)
17894 struct mips16_constant_pool pool;
17895 rtx_insn *insn, *barrier;
17897 if (!TARGET_MIPS16_PCREL_LOADS)
17898 return;
17900 if (split_p)
17902 if (mips_cfg_in_reorg ())
17903 split_all_insns ();
17904 else
17905 split_all_insns_noflow ();
17907 barrier = 0;
17908 memset (&pool, 0, sizeof (pool));
17909 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
17911 /* Rewrite constant pool references in INSN. */
17912 if (USEFUL_INSN_P (insn))
17913 mips16_rewrite_pool_refs (insn, &pool);
17915 pool.insn_address += mips16_insn_length (insn);
17917 if (pool.first != NULL)
17919 /* If there are no natural barriers between the first user of
17920 the pool and the highest acceptable address, we'll need to
17921 create a new instruction to jump around the constant pool.
17922 In the worst case, this instruction will be 4 bytes long.
17924 If it's too late to do this transformation after INSN,
17925 do it immediately before INSN. */
17926 if (barrier == 0 && pool.insn_address + 4 > pool.highest_address)
17928 rtx_code_label *label;
17929 rtx_insn *jump;
17931 label = gen_label_rtx ();
17933 jump = emit_jump_insn_before (gen_jump (label), insn);
17934 JUMP_LABEL (jump) = label;
17935 LABEL_NUSES (label) = 1;
17936 barrier = emit_barrier_after (jump);
17938 emit_label_after (label, barrier);
17939 pool.insn_address += 4;
17942 /* See whether the constant pool is now out of range of the first
17943 user. If so, output the constants after the previous barrier.
17944 Note that any instructions between BARRIER and INSN (inclusive)
17945 will use negative offsets to refer to the pool. */
17946 if (pool.insn_address > pool.highest_address)
17948 mips16_emit_constants (pool.first, barrier);
17949 pool.first = NULL;
17950 barrier = 0;
17952 else if (BARRIER_P (insn))
17953 barrier = insn;
17956 mips16_emit_constants (pool.first, get_last_insn ());
17959 /* Return true if it is worth r10k_simplify_address's while replacing
17960 an address with X. We are looking for constants, and for addresses
17961 at a known offset from the incoming stack pointer. */
17963 static bool
17964 r10k_simplified_address_p (rtx x)
17966 if (GET_CODE (x) == PLUS && CONST_INT_P (XEXP (x, 1)))
17967 x = XEXP (x, 0);
17968 return x == virtual_incoming_args_rtx || CONSTANT_P (x);
17971 /* X is an expression that appears in INSN. Try to use the UD chains
17972 to simplify it, returning the simplified form on success and the
17973 original form otherwise. Replace the incoming value of $sp with
17974 virtual_incoming_args_rtx (which should never occur in X otherwise). */
17976 static rtx
17977 r10k_simplify_address (rtx x, rtx_insn *insn)
17979 rtx newx, op0, op1, set, note;
17980 rtx_insn *def_insn;
17981 df_ref use, def;
17982 struct df_link *defs;
17984 newx = NULL_RTX;
17985 if (UNARY_P (x))
17987 op0 = r10k_simplify_address (XEXP (x, 0), insn);
17988 if (op0 != XEXP (x, 0))
17989 newx = simplify_gen_unary (GET_CODE (x), GET_MODE (x),
17990 op0, GET_MODE (XEXP (x, 0)));
17992 else if (BINARY_P (x))
17994 op0 = r10k_simplify_address (XEXP (x, 0), insn);
17995 op1 = r10k_simplify_address (XEXP (x, 1), insn);
17996 if (op0 != XEXP (x, 0) || op1 != XEXP (x, 1))
17997 newx = simplify_gen_binary (GET_CODE (x), GET_MODE (x), op0, op1);
17999 else if (GET_CODE (x) == LO_SUM)
18001 /* LO_SUMs can be offset from HIGHs, if we know they won't
18002 overflow. See mips_classify_address for the rationale behind
18003 the lax check. */
18004 op0 = r10k_simplify_address (XEXP (x, 0), insn);
18005 if (GET_CODE (op0) == HIGH)
18006 newx = XEXP (x, 1);
18008 else if (REG_P (x))
18010 /* Uses are recorded by regno_reg_rtx, not X itself. */
18011 use = df_find_use (insn, regno_reg_rtx[REGNO (x)]);
18012 gcc_assert (use);
18013 defs = DF_REF_CHAIN (use);
18015 /* Require a single definition. */
18016 if (defs && defs->next == NULL)
18018 def = defs->ref;
18019 if (DF_REF_IS_ARTIFICIAL (def))
18021 /* Replace the incoming value of $sp with
18022 virtual_incoming_args_rtx. */
18023 if (x == stack_pointer_rtx
18024 && DF_REF_BB (def) == ENTRY_BLOCK_PTR_FOR_FN (cfun))
18025 newx = virtual_incoming_args_rtx;
18027 else if (dominated_by_p (CDI_DOMINATORS, DF_REF_BB (use),
18028 DF_REF_BB (def)))
18030 /* Make sure that DEF_INSN is a single set of REG. */
18031 def_insn = DF_REF_INSN (def);
18032 if (NONJUMP_INSN_P (def_insn))
18034 set = single_set (def_insn);
18035 if (set && rtx_equal_p (SET_DEST (set), x))
18037 /* Prefer to use notes, since the def-use chains
18038 are often shorter. */
18039 note = find_reg_equal_equiv_note (def_insn);
18040 if (note)
18041 newx = XEXP (note, 0);
18042 else
18043 newx = SET_SRC (set);
18044 newx = r10k_simplify_address (newx, def_insn);
18050 if (newx && r10k_simplified_address_p (newx))
18051 return newx;
18052 return x;
18055 /* Return true if ADDRESS is known to be an uncached address
18056 on R10K systems. */
18058 static bool
18059 r10k_uncached_address_p (unsigned HOST_WIDE_INT address)
18061 unsigned HOST_WIDE_INT upper;
18063 /* Check for KSEG1. */
18064 if (address + 0x60000000 < 0x20000000)
18065 return true;
18067 /* Check for uncached XKPHYS addresses. */
18068 if (Pmode == DImode)
18070 upper = (address >> 40) & 0xf9ffff;
18071 if (upper == 0x900000 || upper == 0xb80000)
18072 return true;
18074 return false;
18077 /* Return true if we can prove that an access to address X in instruction
18078 INSN would be safe from R10K speculation. This X is a general
18079 expression; it might not be a legitimate address. */
18081 static bool
18082 r10k_safe_address_p (rtx x, rtx_insn *insn)
18084 rtx base, offset;
18085 HOST_WIDE_INT offset_val;
18087 x = r10k_simplify_address (x, insn);
18089 /* Check for references to the stack frame. It doesn't really matter
18090 how much of the frame has been allocated at INSN; -mr10k-cache-barrier
18091 allows us to assume that accesses to any part of the eventual frame
18092 is safe from speculation at any point in the function. */
18093 mips_split_plus (x, &base, &offset_val);
18094 if (base == virtual_incoming_args_rtx
18095 && offset_val >= -cfun->machine->frame.total_size
18096 && offset_val < cfun->machine->frame.args_size)
18097 return true;
18099 /* Check for uncached addresses. */
18100 if (CONST_INT_P (x))
18101 return r10k_uncached_address_p (INTVAL (x));
18103 /* Check for accesses to a static object. */
18104 split_const (x, &base, &offset);
18105 return offset_within_block_p (base, INTVAL (offset));
18108 /* Return true if a MEM with MEM_EXPR EXPR and MEM_OFFSET OFFSET is
18109 an in-range access to an automatic variable, or to an object with
18110 a link-time-constant address. */
18112 static bool
18113 r10k_safe_mem_expr_p (tree expr, unsigned HOST_WIDE_INT offset)
18115 poly_int64 bitoffset, bitsize;
18116 tree inner, var_offset;
18117 machine_mode mode;
18118 int unsigned_p, reverse_p, volatile_p;
18120 inner = get_inner_reference (expr, &bitsize, &bitoffset, &var_offset, &mode,
18121 &unsigned_p, &reverse_p, &volatile_p);
18122 if (!DECL_P (inner) || !DECL_SIZE_UNIT (inner) || var_offset)
18123 return false;
18125 offset += bitoffset / BITS_PER_UNIT;
18126 return offset < tree_to_uhwi (DECL_SIZE_UNIT (inner));
18129 /* Return true if X contains a MEM that is not safe from R10K speculation.
18130 INSN is the instruction that contains X. */
18132 static bool
18133 r10k_needs_protection_p_1 (rtx x, rtx_insn *insn)
18135 subrtx_var_iterator::array_type array;
18136 FOR_EACH_SUBRTX_VAR (iter, array, x, NONCONST)
18138 rtx mem = *iter;
18139 if (MEM_P (mem))
18141 if ((MEM_EXPR (mem)
18142 && MEM_OFFSET_KNOWN_P (mem)
18143 && r10k_safe_mem_expr_p (MEM_EXPR (mem), MEM_OFFSET (mem)))
18144 || r10k_safe_address_p (XEXP (mem, 0), insn))
18145 iter.skip_subrtxes ();
18146 else
18147 return true;
18150 return false;
18153 /* A note_stores callback for which DATA points to an instruction pointer.
18154 If *DATA is nonnull, make it null if it X contains a MEM that is not
18155 safe from R10K speculation. */
18157 static void
18158 r10k_needs_protection_p_store (rtx x, const_rtx pat ATTRIBUTE_UNUSED,
18159 void *data)
18161 rtx_insn **insn_ptr;
18163 insn_ptr = (rtx_insn **) data;
18164 if (*insn_ptr && r10k_needs_protection_p_1 (x, *insn_ptr))
18165 *insn_ptr = NULL;
18168 /* X is the pattern of a call instruction. Return true if the call is
18169 not to a declared function. */
18171 static bool
18172 r10k_needs_protection_p_call (const_rtx x)
18174 subrtx_iterator::array_type array;
18175 FOR_EACH_SUBRTX (iter, array, x, NONCONST)
18177 const_rtx mem = *iter;
18178 if (MEM_P (mem))
18180 const_rtx addr = XEXP (mem, 0);
18181 if (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_DECL (addr))
18182 iter.skip_subrtxes ();
18183 else
18184 return true;
18187 return false;
18190 /* Return true if instruction INSN needs to be protected by an R10K
18191 cache barrier. */
18193 static bool
18194 r10k_needs_protection_p (rtx_insn *insn)
18196 if (CALL_P (insn))
18197 return r10k_needs_protection_p_call (PATTERN (insn));
18199 if (mips_r10k_cache_barrier == R10K_CACHE_BARRIER_STORE)
18201 note_stores (insn, r10k_needs_protection_p_store, &insn);
18202 return insn == NULL_RTX;
18205 return r10k_needs_protection_p_1 (PATTERN (insn), insn);
18208 /* Return true if BB is only reached by blocks in PROTECTED_BBS and if every
18209 edge is unconditional. */
18211 static bool
18212 r10k_protected_bb_p (basic_block bb, sbitmap protected_bbs)
18214 edge_iterator ei;
18215 edge e;
18217 FOR_EACH_EDGE (e, ei, bb->preds)
18218 if (!single_succ_p (e->src)
18219 || !bitmap_bit_p (protected_bbs, e->src->index)
18220 || (e->flags & EDGE_COMPLEX) != 0)
18221 return false;
18222 return true;
18225 /* Implement -mr10k-cache-barrier= for the current function. */
18227 static void
18228 r10k_insert_cache_barriers (void)
18230 int *rev_post_order;
18231 unsigned int i, n;
18232 basic_block bb;
18233 sbitmap protected_bbs;
18234 rtx_insn *insn, *end;
18235 rtx unprotected_region;
18237 if (TARGET_MIPS16)
18239 sorry ("%qs does not support MIPS16 code", "-mr10k-cache-barrier");
18240 return;
18243 /* Calculate dominators. */
18244 calculate_dominance_info (CDI_DOMINATORS);
18246 /* Bit X of PROTECTED_BBS is set if the last operation in basic block
18247 X is protected by a cache barrier. */
18248 protected_bbs = sbitmap_alloc (last_basic_block_for_fn (cfun));
18249 bitmap_clear (protected_bbs);
18251 /* Iterate over the basic blocks in reverse post-order. */
18252 rev_post_order = XNEWVEC (int, last_basic_block_for_fn (cfun));
18253 n = pre_and_rev_post_order_compute (NULL, rev_post_order, false);
18254 for (i = 0; i < n; i++)
18256 bb = BASIC_BLOCK_FOR_FN (cfun, rev_post_order[i]);
18258 /* If this block is only reached by unconditional edges, and if the
18259 source of every edge is protected, the beginning of the block is
18260 also protected. */
18261 if (r10k_protected_bb_p (bb, protected_bbs))
18262 unprotected_region = NULL_RTX;
18263 else
18264 unprotected_region = pc_rtx;
18265 end = NEXT_INSN (BB_END (bb));
18267 /* UNPROTECTED_REGION is:
18269 - null if we are processing a protected region,
18270 - pc_rtx if we are processing an unprotected region but have
18271 not yet found the first instruction in it
18272 - the first instruction in an unprotected region otherwise. */
18273 for (insn = BB_HEAD (bb); insn != end; insn = NEXT_INSN (insn))
18275 if (unprotected_region && USEFUL_INSN_P (insn))
18277 if (recog_memoized (insn) == CODE_FOR_mips_cache)
18278 /* This CACHE instruction protects the following code. */
18279 unprotected_region = NULL_RTX;
18280 else
18282 /* See if INSN is the first instruction in this
18283 unprotected region. */
18284 if (unprotected_region == pc_rtx)
18285 unprotected_region = insn;
18287 /* See if INSN needs to be protected. If so,
18288 we must insert a cache barrier somewhere between
18289 PREV_INSN (UNPROTECTED_REGION) and INSN. It isn't
18290 clear which position is better performance-wise,
18291 but as a tie-breaker, we assume that it is better
18292 to allow delay slots to be back-filled where
18293 possible, and that it is better not to insert
18294 barriers in the middle of already-scheduled code.
18295 We therefore insert the barrier at the beginning
18296 of the region. */
18297 if (r10k_needs_protection_p (insn))
18299 emit_insn_before (gen_r10k_cache_barrier (),
18300 as_a <rtx_insn *> (unprotected_region));
18301 unprotected_region = NULL_RTX;
18306 if (CALL_P (insn))
18307 /* The called function is not required to protect the exit path.
18308 The code that follows a call is therefore unprotected. */
18309 unprotected_region = pc_rtx;
18312 /* Record whether the end of this block is protected. */
18313 if (unprotected_region == NULL_RTX)
18314 bitmap_set_bit (protected_bbs, bb->index);
18316 XDELETEVEC (rev_post_order);
18318 sbitmap_free (protected_bbs);
18320 free_dominance_info (CDI_DOMINATORS);
18323 /* If INSN is a call, return the underlying CALL expr. Return NULL_RTX
18324 otherwise. If INSN has two call rtx, then store the second one in
18325 SECOND_CALL. */
18327 static rtx
18328 mips_call_expr_from_insn (rtx_insn *insn, rtx *second_call)
18330 rtx x;
18331 rtx x2;
18333 if (!CALL_P (insn))
18334 return NULL_RTX;
18336 x = PATTERN (insn);
18337 if (GET_CODE (x) == PARALLEL)
18339 /* Calls returning complex values have two CALL rtx. Look for the second
18340 one here, and return it via the SECOND_CALL arg. */
18341 x2 = XVECEXP (x, 0, 1);
18342 if (GET_CODE (x2) == SET)
18343 x2 = XEXP (x2, 1);
18344 if (GET_CODE (x2) == CALL)
18345 *second_call = x2;
18347 x = XVECEXP (x, 0, 0);
18349 if (GET_CODE (x) == SET)
18350 x = XEXP (x, 1);
18351 gcc_assert (GET_CODE (x) == CALL);
18353 return x;
18356 /* REG is set in DEF. See if the definition is one of the ways we load a
18357 register with a symbol address for a mips_use_pic_fn_addr_reg_p call.
18358 If it is, return the symbol reference of the function, otherwise return
18359 NULL_RTX.
18361 If RECURSE_P is true, use mips_find_pic_call_symbol to interpret
18362 the values of source registers, otherwise treat such registers as
18363 having an unknown value. */
18365 static rtx
18366 mips_pic_call_symbol_from_set (df_ref def, rtx reg, bool recurse_p)
18368 rtx_insn *def_insn;
18369 rtx set;
18371 if (DF_REF_IS_ARTIFICIAL (def))
18372 return NULL_RTX;
18374 def_insn = DF_REF_INSN (def);
18375 set = single_set (def_insn);
18376 if (set && rtx_equal_p (SET_DEST (set), reg))
18378 rtx note, src, symbol;
18380 /* First see whether the source is a plain symbol. This is used
18381 when calling symbols that are not lazily bound. */
18382 src = SET_SRC (set);
18383 if (GET_CODE (src) == SYMBOL_REF)
18384 return src;
18386 /* Handle %call16 references. */
18387 symbol = mips_strip_unspec_call (src);
18388 if (symbol)
18390 gcc_assert (GET_CODE (symbol) == SYMBOL_REF);
18391 return symbol;
18394 /* If we have something more complicated, look for a
18395 REG_EQUAL or REG_EQUIV note. */
18396 note = find_reg_equal_equiv_note (def_insn);
18397 if (note && GET_CODE (XEXP (note, 0)) == SYMBOL_REF)
18398 return XEXP (note, 0);
18400 /* Follow at most one simple register copy. Such copies are
18401 interesting in cases like:
18403 for (...)
18405 locally_binding_fn (...);
18408 and:
18410 locally_binding_fn (...);
18412 locally_binding_fn (...);
18414 where the load of locally_binding_fn can legitimately be
18415 hoisted or shared. However, we do not expect to see complex
18416 chains of copies, so a full worklist solution to the problem
18417 would probably be overkill. */
18418 if (recurse_p && REG_P (src))
18419 return mips_find_pic_call_symbol (def_insn, src, false);
18422 return NULL_RTX;
18425 /* Find the definition of the use of REG in INSN. See if the definition
18426 is one of the ways we load a register with a symbol address for a
18427 mips_use_pic_fn_addr_reg_p call. If it is return the symbol reference
18428 of the function, otherwise return NULL_RTX. RECURSE_P is as for
18429 mips_pic_call_symbol_from_set. */
18431 static rtx
18432 mips_find_pic_call_symbol (rtx_insn *insn, rtx reg, bool recurse_p)
18434 df_ref use;
18435 struct df_link *defs;
18436 rtx symbol;
18438 use = df_find_use (insn, regno_reg_rtx[REGNO (reg)]);
18439 if (!use)
18440 return NULL_RTX;
18441 defs = DF_REF_CHAIN (use);
18442 if (!defs)
18443 return NULL_RTX;
18444 symbol = mips_pic_call_symbol_from_set (defs->ref, reg, recurse_p);
18445 if (!symbol)
18446 return NULL_RTX;
18448 /* If we have more than one definition, they need to be identical. */
18449 for (defs = defs->next; defs; defs = defs->next)
18451 rtx other;
18453 other = mips_pic_call_symbol_from_set (defs->ref, reg, recurse_p);
18454 if (!rtx_equal_p (symbol, other))
18455 return NULL_RTX;
18458 return symbol;
18461 /* Replace the args_size operand of the call expression CALL with the
18462 call-attribute UNSPEC and fill in SYMBOL as the function symbol. */
18464 static void
18465 mips_annotate_pic_call_expr (rtx call, rtx symbol)
18467 rtx args_size;
18469 args_size = XEXP (call, 1);
18470 XEXP (call, 1) = gen_rtx_UNSPEC (GET_MODE (args_size),
18471 gen_rtvec (2, args_size, symbol),
18472 UNSPEC_CALL_ATTR);
18475 /* OPERANDS[ARGS_SIZE_OPNO] is the arg_size operand of a CALL expression. See
18476 if instead of the arg_size argument it contains the call attributes. If
18477 yes return true along with setting OPERANDS[ARGS_SIZE_OPNO] to the function
18478 symbol from the call attributes. Also return false if ARGS_SIZE_OPNO is
18479 -1. */
18481 bool
18482 mips_get_pic_call_symbol (rtx *operands, int args_size_opno)
18484 rtx args_size, symbol;
18486 if (!TARGET_RELAX_PIC_CALLS || args_size_opno == -1)
18487 return false;
18489 args_size = operands[args_size_opno];
18490 if (GET_CODE (args_size) != UNSPEC)
18491 return false;
18492 gcc_assert (XINT (args_size, 1) == UNSPEC_CALL_ATTR);
18494 symbol = XVECEXP (args_size, 0, 1);
18495 gcc_assert (GET_CODE (symbol) == SYMBOL_REF);
18497 operands[args_size_opno] = symbol;
18498 return true;
18501 /* Use DF to annotate PIC indirect calls with the function symbol they
18502 dispatch to. */
18504 static void
18505 mips_annotate_pic_calls (void)
18507 basic_block bb;
18508 rtx_insn *insn;
18510 FOR_EACH_BB_FN (bb, cfun)
18511 FOR_BB_INSNS (bb, insn)
18513 rtx call, reg, symbol, second_call;
18515 second_call = 0;
18516 call = mips_call_expr_from_insn (insn, &second_call);
18517 if (!call)
18518 continue;
18519 gcc_assert (MEM_P (XEXP (call, 0)));
18520 reg = XEXP (XEXP (call, 0), 0);
18521 if (!REG_P (reg))
18522 continue;
18524 symbol = mips_find_pic_call_symbol (insn, reg, true);
18525 if (symbol)
18527 mips_annotate_pic_call_expr (call, symbol);
18528 if (second_call)
18529 mips_annotate_pic_call_expr (second_call, symbol);
18534 /* A temporary variable used by note_uses callbacks, etc. */
18535 static rtx_insn *mips_sim_insn;
18537 /* A structure representing the state of the processor pipeline.
18538 Used by the mips_sim_* family of functions. */
18539 struct mips_sim {
18540 /* The maximum number of instructions that can be issued in a cycle.
18541 (Caches mips_issue_rate.) */
18542 unsigned int issue_rate;
18544 /* The current simulation time. */
18545 unsigned int time;
18547 /* How many more instructions can be issued in the current cycle. */
18548 unsigned int insns_left;
18550 /* LAST_SET[X].INSN is the last instruction to set register X.
18551 LAST_SET[X].TIME is the time at which that instruction was issued.
18552 INSN is null if no instruction has yet set register X. */
18553 struct {
18554 rtx_insn *insn;
18555 unsigned int time;
18556 } last_set[FIRST_PSEUDO_REGISTER];
18558 /* The pipeline's current DFA state. */
18559 state_t dfa_state;
18562 /* Reset STATE to the initial simulation state. */
18564 static void
18565 mips_sim_reset (struct mips_sim *state)
18567 curr_state = state->dfa_state;
18569 state->time = 0;
18570 state->insns_left = state->issue_rate;
18571 memset (&state->last_set, 0, sizeof (state->last_set));
18572 state_reset (curr_state);
18574 targetm.sched.init (0, false, 0);
18575 advance_state (curr_state);
18578 /* Initialize STATE before its first use. DFA_STATE points to an
18579 allocated but uninitialized DFA state. */
18581 static void
18582 mips_sim_init (struct mips_sim *state, state_t dfa_state)
18584 if (targetm.sched.init_dfa_pre_cycle_insn)
18585 targetm.sched.init_dfa_pre_cycle_insn ();
18587 if (targetm.sched.init_dfa_post_cycle_insn)
18588 targetm.sched.init_dfa_post_cycle_insn ();
18590 state->issue_rate = mips_issue_rate ();
18591 state->dfa_state = dfa_state;
18592 mips_sim_reset (state);
18595 /* Advance STATE by one clock cycle. */
18597 static void
18598 mips_sim_next_cycle (struct mips_sim *state)
18600 curr_state = state->dfa_state;
18602 state->time++;
18603 state->insns_left = state->issue_rate;
18604 advance_state (curr_state);
18607 /* Advance simulation state STATE until instruction INSN can read
18608 register REG. */
18610 static void
18611 mips_sim_wait_reg (struct mips_sim *state, rtx_insn *insn, rtx reg)
18613 unsigned int regno, end_regno;
18615 end_regno = END_REGNO (reg);
18616 for (regno = REGNO (reg); regno < end_regno; regno++)
18617 if (state->last_set[regno].insn != 0)
18619 unsigned int t;
18621 t = (state->last_set[regno].time
18622 + insn_latency (state->last_set[regno].insn, insn));
18623 while (state->time < t)
18624 mips_sim_next_cycle (state);
18628 /* A note_uses callback. For each register in *X, advance simulation
18629 state DATA until mips_sim_insn can read the register's value. */
18631 static void
18632 mips_sim_wait_regs_1 (rtx *x, void *data)
18634 subrtx_var_iterator::array_type array;
18635 FOR_EACH_SUBRTX_VAR (iter, array, *x, NONCONST)
18636 if (REG_P (*iter))
18637 mips_sim_wait_reg ((struct mips_sim *) data, mips_sim_insn, *iter);
18640 /* Advance simulation state STATE until all of INSN's register
18641 dependencies are satisfied. */
18643 static void
18644 mips_sim_wait_regs (struct mips_sim *state, rtx_insn *insn)
18646 mips_sim_insn = insn;
18647 note_uses (&PATTERN (insn), mips_sim_wait_regs_1, state);
18650 /* Advance simulation state STATE until the units required by
18651 instruction INSN are available. */
18653 static void
18654 mips_sim_wait_units (struct mips_sim *state, rtx_insn *insn)
18656 state_t tmp_state;
18658 tmp_state = alloca (state_size ());
18659 while (state->insns_left == 0
18660 || (memcpy (tmp_state, state->dfa_state, state_size ()),
18661 state_transition (tmp_state, insn) >= 0))
18662 mips_sim_next_cycle (state);
18665 /* Advance simulation state STATE until INSN is ready to issue. */
18667 static void
18668 mips_sim_wait_insn (struct mips_sim *state, rtx_insn *insn)
18670 mips_sim_wait_regs (state, insn);
18671 mips_sim_wait_units (state, insn);
18674 /* mips_sim_insn has just set X. Update the LAST_SET array
18675 in simulation state DATA. */
18677 static void
18678 mips_sim_record_set (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data)
18680 struct mips_sim *state;
18682 state = (struct mips_sim *) data;
18683 if (REG_P (x))
18685 unsigned int regno, end_regno;
18687 end_regno = END_REGNO (x);
18688 for (regno = REGNO (x); regno < end_regno; regno++)
18690 state->last_set[regno].insn = mips_sim_insn;
18691 state->last_set[regno].time = state->time;
18696 /* Issue instruction INSN in scheduler state STATE. Assume that INSN
18697 can issue immediately (i.e., that mips_sim_wait_insn has already
18698 been called). */
18700 static void
18701 mips_sim_issue_insn (struct mips_sim *state, rtx_insn *insn)
18703 curr_state = state->dfa_state;
18705 state_transition (curr_state, insn);
18706 state->insns_left = targetm.sched.variable_issue (0, false, insn,
18707 state->insns_left);
18709 mips_sim_insn = insn;
18710 note_stores (insn, mips_sim_record_set, state);
18713 /* Simulate issuing a NOP in state STATE. */
18715 static void
18716 mips_sim_issue_nop (struct mips_sim *state)
18718 if (state->insns_left == 0)
18719 mips_sim_next_cycle (state);
18720 state->insns_left--;
18723 /* Update simulation state STATE so that it's ready to accept the instruction
18724 after INSN. INSN should be part of the main rtl chain, not a member of a
18725 SEQUENCE. */
18727 static void
18728 mips_sim_finish_insn (struct mips_sim *state, rtx_insn *insn)
18730 /* If INSN is a jump with an implicit delay slot, simulate a nop. */
18731 if (JUMP_P (insn))
18732 mips_sim_issue_nop (state);
18734 switch (GET_CODE (SEQ_BEGIN (insn)))
18736 case CODE_LABEL:
18737 case CALL_INSN:
18738 /* We can't predict the processor state after a call or label. */
18739 mips_sim_reset (state);
18740 break;
18742 case JUMP_INSN:
18743 /* The delay slots of branch likely instructions are only executed
18744 when the branch is taken. Therefore, if the caller has simulated
18745 the delay slot instruction, STATE does not really reflect the state
18746 of the pipeline for the instruction after the delay slot. Also,
18747 branch likely instructions tend to incur a penalty when not taken,
18748 so there will probably be an extra delay between the branch and
18749 the instruction after the delay slot. */
18750 if (INSN_ANNULLED_BRANCH_P (SEQ_BEGIN (insn)))
18751 mips_sim_reset (state);
18752 break;
18754 default:
18755 break;
18759 /* Use simulator state STATE to calculate the execution time of
18760 instruction sequence SEQ. */
18762 static unsigned int
18763 mips_seq_time (struct mips_sim *state, rtx_insn *seq)
18765 mips_sim_reset (state);
18766 for (rtx_insn *insn = seq; insn; insn = NEXT_INSN (insn))
18768 mips_sim_wait_insn (state, insn);
18769 mips_sim_issue_insn (state, insn);
18771 return state->time;
18774 /* Return the execution-time cost of mips_tuning_info.fast_mult_zero_zero_p
18775 setting SETTING, using STATE to simulate instruction sequences. */
18777 static unsigned int
18778 mips_mult_zero_zero_cost (struct mips_sim *state, bool setting)
18780 mips_tuning_info.fast_mult_zero_zero_p = setting;
18781 start_sequence ();
18783 machine_mode dword_mode = TARGET_64BIT ? TImode : DImode;
18784 rtx hilo = gen_rtx_REG (dword_mode, MD_REG_FIRST);
18785 mips_emit_move_or_split (hilo, const0_rtx, SPLIT_FOR_SPEED);
18787 /* If the target provides mulsidi3_32bit then that's the most likely
18788 consumer of the result. Test for bypasses. */
18789 if (dword_mode == DImode && HAVE_maddsidi4)
18791 rtx gpr = gen_rtx_REG (SImode, GP_REG_FIRST + 4);
18792 emit_insn (gen_maddsidi4 (hilo, gpr, gpr, hilo));
18795 unsigned int time = mips_seq_time (state, get_insns ());
18796 end_sequence ();
18797 return time;
18800 /* Check the relative speeds of "MULT $0,$0" and "MTLO $0; MTHI $0"
18801 and set up mips_tuning_info.fast_mult_zero_zero_p accordingly.
18802 Prefer MULT -- which is shorter -- in the event of a tie. */
18804 static void
18805 mips_set_fast_mult_zero_zero_p (struct mips_sim *state)
18807 if (TARGET_MIPS16 || !ISA_HAS_HILO)
18808 /* No MTLO or MTHI available for MIPS16. Also, when there are no HI or LO
18809 registers then there is no reason to zero them, arbitrarily choose to
18810 say that "MULT $0,$0" would be faster. */
18811 mips_tuning_info.fast_mult_zero_zero_p = true;
18812 else
18814 unsigned int true_time = mips_mult_zero_zero_cost (state, true);
18815 unsigned int false_time = mips_mult_zero_zero_cost (state, false);
18816 mips_tuning_info.fast_mult_zero_zero_p = (true_time <= false_time);
18820 /* Set up costs based on the current architecture and tuning settings. */
18822 static void
18823 mips_set_tuning_info (void)
18825 if (mips_tuning_info.initialized_p
18826 && mips_tuning_info.arch == mips_arch
18827 && mips_tuning_info.tune == mips_tune
18828 && mips_tuning_info.mips16_p == TARGET_MIPS16)
18829 return;
18831 mips_tuning_info.arch = mips_arch;
18832 mips_tuning_info.tune = mips_tune;
18833 mips_tuning_info.mips16_p = TARGET_MIPS16;
18834 mips_tuning_info.initialized_p = true;
18836 dfa_start ();
18838 struct mips_sim state;
18839 mips_sim_init (&state, alloca (state_size ()));
18841 mips_set_fast_mult_zero_zero_p (&state);
18843 dfa_finish ();
18846 /* Implement TARGET_EXPAND_TO_RTL_HOOK. */
18848 static void
18849 mips_expand_to_rtl_hook (void)
18851 /* We need to call this at a point where we can safely create sequences
18852 of instructions, so TARGET_OVERRIDE_OPTIONS is too early. We also
18853 need to call it at a point where the DFA infrastructure is not
18854 already in use, so we can't just call it lazily on demand.
18856 At present, mips_tuning_info is only needed during post-expand
18857 RTL passes such as split_insns, so this hook should be early enough.
18858 We may need to move the call elsewhere if mips_tuning_info starts
18859 to be used for other things (such as rtx_costs, or expanders that
18860 could be called during gimple optimization). */
18861 mips_set_tuning_info ();
18864 /* The VR4130 pipeline issues aligned pairs of instructions together,
18865 but it stalls the second instruction if it depends on the first.
18866 In order to cut down the amount of logic required, this dependence
18867 check is not based on a full instruction decode. Instead, any non-SPECIAL
18868 instruction is assumed to modify the register specified by bits 20-16
18869 (which is usually the "rt" field).
18871 In BEQ, BEQL, BNE and BNEL instructions, the rt field is actually an
18872 input, so we can end up with a false dependence between the branch
18873 and its delay slot. If this situation occurs in instruction INSN,
18874 try to avoid it by swapping rs and rt. */
18876 static void
18877 vr4130_avoid_branch_rt_conflict (rtx_insn *insn)
18879 rtx_insn *first, *second;
18881 first = SEQ_BEGIN (insn);
18882 second = SEQ_END (insn);
18883 if (JUMP_P (first)
18884 && NONJUMP_INSN_P (second)
18885 && GET_CODE (PATTERN (first)) == SET
18886 && GET_CODE (SET_DEST (PATTERN (first))) == PC
18887 && GET_CODE (SET_SRC (PATTERN (first))) == IF_THEN_ELSE)
18889 /* Check for the right kind of condition. */
18890 rtx cond = XEXP (SET_SRC (PATTERN (first)), 0);
18891 if ((GET_CODE (cond) == EQ || GET_CODE (cond) == NE)
18892 && REG_P (XEXP (cond, 0))
18893 && REG_P (XEXP (cond, 1))
18894 && reg_referenced_p (XEXP (cond, 1), PATTERN (second))
18895 && !reg_referenced_p (XEXP (cond, 0), PATTERN (second)))
18897 /* SECOND mentions the rt register but not the rs register. */
18898 rtx tmp = XEXP (cond, 0);
18899 XEXP (cond, 0) = XEXP (cond, 1);
18900 XEXP (cond, 1) = tmp;
18905 /* Implement -mvr4130-align. Go through each basic block and simulate the
18906 processor pipeline. If we find that a pair of instructions could execute
18907 in parallel, and the first of those instructions is not 8-byte aligned,
18908 insert a nop to make it aligned. */
18910 static void
18911 vr4130_align_insns (void)
18913 struct mips_sim state;
18914 rtx_insn *insn, *subinsn, *last, *last2, *next;
18915 bool aligned_p;
18917 dfa_start ();
18919 /* LAST is the last instruction before INSN to have a nonzero length.
18920 LAST2 is the last such instruction before LAST. */
18921 last = 0;
18922 last2 = 0;
18924 /* ALIGNED_P is true if INSN is known to be at an aligned address. */
18925 aligned_p = true;
18927 mips_sim_init (&state, alloca (state_size ()));
18928 for (insn = get_insns (); insn != 0; insn = next)
18930 unsigned int length;
18932 next = NEXT_INSN (insn);
18934 /* See the comment above vr4130_avoid_branch_rt_conflict for details.
18935 This isn't really related to the alignment pass, but we do it on
18936 the fly to avoid a separate instruction walk. */
18937 vr4130_avoid_branch_rt_conflict (insn);
18939 length = get_attr_length (insn);
18940 if (length > 0 && USEFUL_INSN_P (insn))
18941 FOR_EACH_SUBINSN (subinsn, insn)
18943 mips_sim_wait_insn (&state, subinsn);
18945 /* If we want this instruction to issue in parallel with the
18946 previous one, make sure that the previous instruction is
18947 aligned. There are several reasons why this isn't worthwhile
18948 when the second instruction is a call:
18950 - Calls are less likely to be performance critical,
18951 - There's a good chance that the delay slot can execute
18952 in parallel with the call.
18953 - The return address would then be unaligned.
18955 In general, if we're going to insert a nop between instructions
18956 X and Y, it's better to insert it immediately after X. That
18957 way, if the nop makes Y aligned, it will also align any labels
18958 between X and Y. */
18959 if (state.insns_left != state.issue_rate
18960 && !CALL_P (subinsn))
18962 if (subinsn == SEQ_BEGIN (insn) && aligned_p)
18964 /* SUBINSN is the first instruction in INSN and INSN is
18965 aligned. We want to align the previous instruction
18966 instead, so insert a nop between LAST2 and LAST.
18968 Note that LAST could be either a single instruction
18969 or a branch with a delay slot. In the latter case,
18970 LAST, like INSN, is already aligned, but the delay
18971 slot must have some extra delay that stops it from
18972 issuing at the same time as the branch. We therefore
18973 insert a nop before the branch in order to align its
18974 delay slot. */
18975 gcc_assert (last2);
18976 emit_insn_after (gen_nop (), last2);
18977 aligned_p = false;
18979 else if (subinsn != SEQ_BEGIN (insn) && !aligned_p)
18981 /* SUBINSN is the delay slot of INSN, but INSN is
18982 currently unaligned. Insert a nop between
18983 LAST and INSN to align it. */
18984 gcc_assert (last);
18985 emit_insn_after (gen_nop (), last);
18986 aligned_p = true;
18989 mips_sim_issue_insn (&state, subinsn);
18991 mips_sim_finish_insn (&state, insn);
18993 /* Update LAST, LAST2 and ALIGNED_P for the next instruction. */
18994 length = get_attr_length (insn);
18995 if (length > 0)
18997 /* If the instruction is an asm statement or multi-instruction
18998 mips.md pattern, the length is only an estimate. Insert an
18999 8 byte alignment after it so that the following instructions
19000 can be handled correctly. */
19001 if (NONJUMP_INSN_P (SEQ_BEGIN (insn))
19002 && (recog_memoized (insn) < 0 || length >= 8))
19004 next = emit_insn_after (gen_align (GEN_INT (3)), insn);
19005 next = NEXT_INSN (next);
19006 mips_sim_next_cycle (&state);
19007 aligned_p = true;
19009 else if (length & 4)
19010 aligned_p = !aligned_p;
19011 last2 = last;
19012 last = insn;
19015 /* See whether INSN is an aligned label. */
19016 if (LABEL_P (insn) && label_to_alignment (insn).levels[0].log >= 3)
19017 aligned_p = true;
19019 dfa_finish ();
19022 /* This structure records that the current function has a LO_SUM
19023 involving SYMBOL_REF or LABEL_REF BASE and that MAX_OFFSET is
19024 the largest offset applied to BASE by all such LO_SUMs. */
19025 struct mips_lo_sum_offset {
19026 rtx base;
19027 HOST_WIDE_INT offset;
19030 /* Return a hash value for SYMBOL_REF or LABEL_REF BASE. */
19032 static hashval_t
19033 mips_hash_base (rtx base)
19035 int do_not_record_p;
19037 return hash_rtx (base, GET_MODE (base), &do_not_record_p, NULL, false);
19040 /* Hashtable helpers. */
19042 struct mips_lo_sum_offset_hasher : free_ptr_hash <mips_lo_sum_offset>
19044 typedef rtx_def *compare_type;
19045 static inline hashval_t hash (const mips_lo_sum_offset *);
19046 static inline bool equal (const mips_lo_sum_offset *, const rtx_def *);
19049 /* Hash-table callbacks for mips_lo_sum_offsets. */
19051 inline hashval_t
19052 mips_lo_sum_offset_hasher::hash (const mips_lo_sum_offset *entry)
19054 return mips_hash_base (entry->base);
19057 inline bool
19058 mips_lo_sum_offset_hasher::equal (const mips_lo_sum_offset *entry,
19059 const rtx_def *value)
19061 return rtx_equal_p (entry->base, value);
19064 typedef hash_table<mips_lo_sum_offset_hasher> mips_offset_table;
19066 /* Look up symbolic constant X in HTAB, which is a hash table of
19067 mips_lo_sum_offsets. If OPTION is NO_INSERT, return true if X can be
19068 paired with a recorded LO_SUM, otherwise record X in the table. */
19070 static bool
19071 mips_lo_sum_offset_lookup (mips_offset_table *htab, rtx x,
19072 enum insert_option option)
19074 rtx base, offset;
19075 mips_lo_sum_offset **slot;
19076 struct mips_lo_sum_offset *entry;
19078 /* Split X into a base and offset. */
19079 split_const (x, &base, &offset);
19080 if (UNSPEC_ADDRESS_P (base))
19081 base = UNSPEC_ADDRESS (base);
19083 /* Look up the base in the hash table. */
19084 slot = htab->find_slot_with_hash (base, mips_hash_base (base), option);
19085 if (slot == NULL)
19086 return false;
19088 entry = (struct mips_lo_sum_offset *) *slot;
19089 if (option == INSERT)
19091 if (entry == NULL)
19093 entry = XNEW (struct mips_lo_sum_offset);
19094 entry->base = base;
19095 entry->offset = INTVAL (offset);
19096 *slot = entry;
19098 else
19100 if (INTVAL (offset) > entry->offset)
19101 entry->offset = INTVAL (offset);
19104 return INTVAL (offset) <= entry->offset;
19107 /* Search X for LO_SUMs and record them in HTAB. */
19109 static void
19110 mips_record_lo_sums (const_rtx x, mips_offset_table *htab)
19112 subrtx_iterator::array_type array;
19113 FOR_EACH_SUBRTX (iter, array, x, NONCONST)
19114 if (GET_CODE (*iter) == LO_SUM)
19115 mips_lo_sum_offset_lookup (htab, XEXP (*iter, 1), INSERT);
19118 /* Return true if INSN is a SET of an orphaned high-part relocation.
19119 HTAB is a hash table of mips_lo_sum_offsets that describes all the
19120 LO_SUMs in the current function. */
19122 static bool
19123 mips_orphaned_high_part_p (mips_offset_table *htab, rtx_insn *insn)
19125 enum mips_symbol_type type;
19126 rtx x, set;
19128 set = single_set (insn);
19129 if (set)
19131 /* Check for %his. */
19132 x = SET_SRC (set);
19133 if (GET_CODE (x) == HIGH
19134 && absolute_symbolic_operand (XEXP (x, 0), VOIDmode))
19135 return !mips_lo_sum_offset_lookup (htab, XEXP (x, 0), NO_INSERT);
19137 /* Check for local %gots (and %got_pages, which is redundant but OK). */
19138 if (GET_CODE (x) == UNSPEC
19139 && XINT (x, 1) == UNSPEC_LOAD_GOT
19140 && mips_symbolic_constant_p (XVECEXP (x, 0, 1),
19141 SYMBOL_CONTEXT_LEA, &type)
19142 && type == SYMBOL_GOTOFF_PAGE)
19143 return !mips_lo_sum_offset_lookup (htab, XVECEXP (x, 0, 1), NO_INSERT);
19145 return false;
19148 /* Subroutine of mips_avoid_hazard. We classify unconditional branches
19149 of interest for the P6600 for performance reasons. We're interested
19150 in differentiating BALC from JIC, JIALC and BC. */
19152 static enum mips_ucbranch_type
19153 mips_classify_branch_p6600 (rtx_insn *insn)
19155 /* We ignore sequences here as they represent a filled delay slot. */
19156 if (!insn
19157 || !USEFUL_INSN_P (insn)
19158 || GET_CODE (PATTERN (insn)) == SEQUENCE)
19159 return UC_UNDEFINED;
19161 if (get_attr_jal (insn) == JAL_INDIRECT /* JIC and JIALC. */
19162 || get_attr_type (insn) == TYPE_JUMP) /* BC. */
19163 return UC_OTHER;
19165 if (CALL_P (insn) && get_attr_jal (insn) == JAL_DIRECT)
19166 return UC_BALC;
19168 return UC_UNDEFINED;
19171 /* Subroutine of mips_reorg_process_insns. If there is a hazard between
19172 INSN and a previous instruction, avoid it by inserting nops after
19173 instruction AFTER.
19175 *DELAYED_REG and *HILO_DELAY describe the hazards that apply at
19176 this point. If *DELAYED_REG is non-null, INSN must wait a cycle
19177 before using the value of that register. *HILO_DELAY counts the
19178 number of instructions since the last hilo hazard (that is,
19179 the number of instructions since the last MFLO or MFHI).
19181 After inserting nops for INSN, update *DELAYED_REG and *HILO_DELAY
19182 for the next instruction.
19184 LO_REG is an rtx for the LO register, used in dependence checking. */
19186 static void
19187 mips_avoid_hazard (rtx_insn *after, rtx_insn *insn, int *hilo_delay,
19188 rtx *delayed_reg, rtx lo_reg, bool *fs_delay)
19190 rtx pattern, set;
19191 int nops, ninsns;
19193 pattern = PATTERN (insn);
19195 /* Do not put the whole function in .set noreorder if it contains
19196 an asm statement. We don't know whether there will be hazards
19197 between the asm statement and the gcc-generated code. */
19198 if (GET_CODE (pattern) == ASM_INPUT || asm_noperands (pattern) >= 0)
19199 cfun->machine->all_noreorder_p = false;
19201 /* Ignore zero-length instructions (barriers and the like). */
19202 ninsns = get_attr_length (insn) / 4;
19203 if (ninsns == 0)
19204 return;
19206 /* Work out how many nops are needed. Note that we only care about
19207 registers that are explicitly mentioned in the instruction's pattern.
19208 It doesn't matter that calls use the argument registers or that they
19209 clobber hi and lo. */
19210 if (*hilo_delay < 2 && reg_set_p (lo_reg, pattern))
19211 nops = 2 - *hilo_delay;
19212 else if (*delayed_reg != 0 && reg_referenced_p (*delayed_reg, pattern))
19213 nops = 1;
19214 /* If processing a forbidden slot hazard then a NOP is required if the
19215 branch instruction was not in a sequence (as the sequence would
19216 imply it is not actually a compact branch anyway) and the current
19217 insn is not an inline asm, and can't go in a delay slot. */
19218 else if (*fs_delay && get_attr_can_delay (insn) == CAN_DELAY_NO
19219 && GET_CODE (PATTERN (after)) != SEQUENCE
19220 && GET_CODE (pattern) != ASM_INPUT
19221 && asm_noperands (pattern) < 0)
19222 nops = 1;
19223 /* The P6600's branch predictor can handle static sequences of back-to-back
19224 branches in the following cases:
19226 (1) BALC followed by any conditional compact branch
19227 (2) BALC followed by BALC
19229 Any other combinations of compact branches will incur performance
19230 penalty. Inserting a no-op only costs space as the dispatch unit will
19231 disregard the nop. */
19232 else if (TUNE_P6600 && TARGET_CB_MAYBE && !optimize_size
19233 && ((mips_classify_branch_p6600 (after) == UC_BALC
19234 && mips_classify_branch_p6600 (insn) == UC_OTHER)
19235 || (mips_classify_branch_p6600 (insn) == UC_BALC
19236 && mips_classify_branch_p6600 (after) == UC_OTHER)))
19237 nops = 1;
19238 else
19239 nops = 0;
19241 /* Insert the nops between this instruction and the previous one.
19242 Each new nop takes us further from the last hilo hazard. */
19243 *hilo_delay += nops;
19245 /* Move to the next real instruction if we are inserting a NOP and this
19246 instruction is a call with debug information. The reason being that
19247 we can't separate the call from the debug info. */
19248 rtx_insn *real_after = after;
19249 if (real_after && nops && CALL_P (real_after))
19250 while (real_after
19251 && (NOTE_P (NEXT_INSN (real_after))
19252 || BARRIER_P (NEXT_INSN (real_after))))
19253 real_after = NEXT_INSN (real_after);
19255 while (nops-- > 0)
19256 emit_insn_after (gen_hazard_nop (), real_after);
19258 /* Set up the state for the next instruction. */
19259 *hilo_delay += ninsns;
19260 *delayed_reg = 0;
19261 *fs_delay = false;
19262 if (INSN_CODE (insn) >= 0)
19263 switch (get_attr_hazard (insn))
19265 case HAZARD_NONE:
19266 /* For the P6600, flag some unconditional branches as having a
19267 pseudo-forbidden slot. This will cause additional nop insertion
19268 or SEQUENCE breaking as required. This is for performance
19269 reasons not correctness. */
19270 if (TUNE_P6600
19271 && !optimize_size
19272 && TARGET_CB_MAYBE
19273 && mips_classify_branch_p6600 (insn) == UC_OTHER)
19274 *fs_delay = true;
19275 break;
19277 case HAZARD_FORBIDDEN_SLOT:
19278 if (TARGET_CB_MAYBE)
19279 *fs_delay = true;
19280 break;
19282 case HAZARD_HILO:
19283 *hilo_delay = 0;
19284 break;
19286 case HAZARD_DELAY:
19287 set = single_set (insn);
19288 gcc_assert (set);
19289 *delayed_reg = SET_DEST (set);
19290 break;
19294 /* Emit a speculation barrier.
19295 JR.HB is needed, so we put speculation_barrier_libfunc in libgcc. */
19296 void
19297 mips_emit_speculation_barrier_function ()
19299 emit_library_call (speculation_barrier_libfunc, LCT_NORMAL, VOIDmode);
19302 /* A SEQUENCE is breakable iff the branch inside it has a compact form
19303 and the target has compact branches. */
19305 static bool
19306 mips_breakable_sequence_p (rtx_insn *insn)
19308 return (insn && GET_CODE (PATTERN (insn)) == SEQUENCE
19309 && TARGET_CB_MAYBE
19310 && get_attr_compact_form (SEQ_BEGIN (insn)) != COMPACT_FORM_NEVER);
19313 /* Remove a SEQUENCE and replace it with the delay slot instruction
19314 followed by the branch and return the instruction in the delay slot.
19315 Return the first of the two new instructions.
19316 Subroutine of mips_reorg_process_insns. */
19318 static rtx_insn *
19319 mips_break_sequence (rtx_insn *insn)
19321 rtx_insn *before = PREV_INSN (insn);
19322 rtx_insn *branch = SEQ_BEGIN (insn);
19323 rtx_insn *ds = SEQ_END (insn);
19324 remove_insn (insn);
19325 add_insn_after (ds, before, NULL);
19326 add_insn_after (branch, ds, NULL);
19327 return ds;
19330 /* Go through the instruction stream and insert nops where necessary.
19331 Also delete any high-part relocations whose partnering low parts
19332 are now all dead. See if the whole function can then be put into
19333 .set noreorder and .set nomacro. */
19335 static void
19336 mips_reorg_process_insns (void)
19338 rtx_insn *insn, *last_insn, *subinsn, *next_insn;
19339 rtx lo_reg, delayed_reg;
19340 int hilo_delay;
19341 bool fs_delay;
19343 /* Force all instructions to be split into their final form. */
19344 split_all_insns_noflow ();
19346 /* Recalculate instruction lengths without taking nops into account. */
19347 cfun->machine->ignore_hazard_length_p = true;
19348 shorten_branches (get_insns ());
19350 cfun->machine->all_noreorder_p = true;
19352 /* We don't track MIPS16 PC-relative offsets closely enough to make
19353 a good job of "set .noreorder" code in MIPS16 mode. */
19354 if (TARGET_MIPS16)
19355 cfun->machine->all_noreorder_p = false;
19357 /* Code that doesn't use explicit relocs can't be ".set nomacro". */
19358 if (!TARGET_EXPLICIT_RELOCS)
19359 cfun->machine->all_noreorder_p = false;
19361 /* Profiled functions can't be all noreorder because the profiler
19362 support uses assembler macros. */
19363 if (crtl->profile)
19364 cfun->machine->all_noreorder_p = false;
19366 /* Code compiled with -mfix-vr4120, -mfix-r5900, -mfix-rm7000 or
19367 -mfix-24k can't be all noreorder because we rely on the assembler
19368 to work around some errata. The R5900 target has several bugs. */
19369 if (TARGET_FIX_VR4120
19370 || TARGET_FIX_RM7000
19371 || TARGET_FIX_24K
19372 || TARGET_FIX_R5900)
19373 cfun->machine->all_noreorder_p = false;
19375 /* The same is true for -mfix-vr4130 if we might generate MFLO or
19376 MFHI instructions. Note that we avoid using MFLO and MFHI if
19377 the VR4130 MACC and DMACC instructions are available instead;
19378 see the *mfhilo_{si,di}_macc patterns. */
19379 if (TARGET_FIX_VR4130 && !ISA_HAS_MACCHI)
19380 cfun->machine->all_noreorder_p = false;
19382 mips_offset_table htab (37);
19384 /* Make a first pass over the instructions, recording all the LO_SUMs. */
19385 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
19386 FOR_EACH_SUBINSN (subinsn, insn)
19387 if (USEFUL_INSN_P (subinsn))
19389 rtx body = PATTERN (insn);
19390 int noperands = asm_noperands (body);
19391 if (noperands >= 0)
19393 rtx *ops = XALLOCAVEC (rtx, noperands);
19394 bool *used = XALLOCAVEC (bool, noperands);
19395 const char *string = decode_asm_operands (body, ops, NULL, NULL,
19396 NULL, NULL);
19397 get_referenced_operands (string, used, noperands);
19398 for (int i = 0; i < noperands; ++i)
19399 if (used[i])
19400 mips_record_lo_sums (ops[i], &htab);
19402 else
19403 mips_record_lo_sums (PATTERN (subinsn), &htab);
19406 last_insn = 0;
19407 hilo_delay = 2;
19408 delayed_reg = 0;
19409 lo_reg = gen_rtx_REG (SImode, LO_REGNUM);
19410 fs_delay = false;
19412 /* Make a second pass over the instructions. Delete orphaned
19413 high-part relocations or turn them into NOPs. Avoid hazards
19414 by inserting NOPs. */
19415 for (insn = get_insns (); insn != 0; insn = next_insn)
19417 next_insn = NEXT_INSN (insn);
19418 if (USEFUL_INSN_P (insn))
19420 if (GET_CODE (PATTERN (insn)) == SEQUENCE)
19422 rtx_insn *next_active = next_active_insn (insn);
19423 /* Undo delay slots to avoid bubbles if the next instruction can
19424 be placed in a forbidden slot or the cost of adding an
19425 explicit NOP in a forbidden slot is OK and if the SEQUENCE is
19426 safely breakable. */
19427 if (TARGET_CB_MAYBE
19428 && mips_breakable_sequence_p (insn)
19429 && INSN_P (SEQ_BEGIN (insn))
19430 && INSN_P (SEQ_END (insn))
19431 && ((next_active
19432 && INSN_P (next_active)
19433 && GET_CODE (PATTERN (next_active)) != SEQUENCE
19434 && get_attr_can_delay (next_active) == CAN_DELAY_YES)
19435 || !optimize_size))
19437 /* To hide a potential pipeline bubble, if we scan backwards
19438 from the current SEQUENCE and find that there is a load
19439 of a value that is used in the CTI and there are no
19440 dependencies between the CTI and instruction in the delay
19441 slot, break the sequence so the load delay is hidden. */
19442 HARD_REG_SET uses;
19443 CLEAR_HARD_REG_SET (uses);
19444 note_uses (&PATTERN (SEQ_BEGIN (insn)), record_hard_reg_uses,
19445 &uses);
19446 HARD_REG_SET delay_sets;
19447 CLEAR_HARD_REG_SET (delay_sets);
19448 note_stores (SEQ_END (insn), record_hard_reg_sets,
19449 &delay_sets);
19451 rtx_insn *prev = prev_active_insn (insn);
19452 if (prev
19453 && GET_CODE (PATTERN (prev)) == SET
19454 && MEM_P (SET_SRC (PATTERN (prev))))
19456 HARD_REG_SET sets;
19457 CLEAR_HARD_REG_SET (sets);
19458 note_stores (prev, record_hard_reg_sets, &sets);
19460 /* Re-order if safe. */
19461 if (!hard_reg_set_intersect_p (delay_sets, uses)
19462 && hard_reg_set_intersect_p (uses, sets))
19464 next_insn = mips_break_sequence (insn);
19465 /* Need to process the hazards of the newly
19466 introduced instructions. */
19467 continue;
19471 /* If we find an orphaned high-part relocation in a delay
19472 slot then we can convert to a compact branch and get
19473 the orphaned high part deleted. */
19474 if (mips_orphaned_high_part_p (&htab, SEQ_END (insn)))
19476 next_insn = mips_break_sequence (insn);
19477 /* Need to process the hazards of the newly
19478 introduced instructions. */
19479 continue;
19483 /* If we find an orphaned high-part relocation in a delay
19484 slot, it's easier to turn that instruction into a NOP than
19485 to delete it. The delay slot will be a NOP either way. */
19486 FOR_EACH_SUBINSN (subinsn, insn)
19487 if (INSN_P (subinsn))
19489 if (mips_orphaned_high_part_p (&htab, subinsn))
19491 PATTERN (subinsn) = gen_nop ();
19492 INSN_CODE (subinsn) = CODE_FOR_nop;
19494 mips_avoid_hazard (last_insn, subinsn, &hilo_delay,
19495 &delayed_reg, lo_reg, &fs_delay);
19497 last_insn = insn;
19499 else
19501 /* INSN is a single instruction. Delete it if it's an
19502 orphaned high-part relocation. */
19503 if (mips_orphaned_high_part_p (&htab, insn))
19504 delete_insn (insn);
19505 /* Also delete cache barriers if the last instruction
19506 was an annulled branch. INSN will not be speculatively
19507 executed. */
19508 else if (recog_memoized (insn) == CODE_FOR_r10k_cache_barrier
19509 && last_insn
19510 && JUMP_P (SEQ_BEGIN (last_insn))
19511 && INSN_ANNULLED_BRANCH_P (SEQ_BEGIN (last_insn)))
19512 delete_insn (insn);
19513 else
19515 mips_avoid_hazard (last_insn, insn, &hilo_delay,
19516 &delayed_reg, lo_reg, &fs_delay);
19517 /* When a compact branch introduces a forbidden slot hazard
19518 and the next useful instruction is a SEQUENCE of a jump
19519 and a non-nop instruction in the delay slot, remove the
19520 sequence and replace it with the delay slot instruction
19521 then the jump to clear the forbidden slot hazard.
19523 For the P6600, this optimisation solves the performance
19524 penalty associated with BALC followed by a delay slot
19525 branch. We do not set fs_delay as we do not want
19526 the full logic of a forbidden slot; the penalty exists
19527 only against branches not the full class of forbidden
19528 slot instructions. */
19530 if (fs_delay || (TUNE_P6600
19531 && TARGET_CB_MAYBE
19532 && mips_classify_branch_p6600 (insn)
19533 == UC_BALC))
19535 /* Search onwards from the current position looking for
19536 a SEQUENCE. We are looking for pipeline hazards here
19537 and do not need to worry about labels or barriers as
19538 the optimization only undoes delay slot filling which
19539 only affects the order of the branch and its delay
19540 slot. */
19541 rtx_insn *next = next_active_insn (insn);
19542 if (next
19543 && USEFUL_INSN_P (next)
19544 && GET_CODE (PATTERN (next)) == SEQUENCE
19545 && mips_breakable_sequence_p (next))
19547 last_insn = insn;
19548 next_insn = mips_break_sequence (next);
19549 /* Need to process the hazards of the newly
19550 introduced instructions. */
19551 continue;
19554 last_insn = insn;
19561 /* Return true if the function has a long branch instruction. */
19563 static bool
19564 mips_has_long_branch_p (void)
19566 rtx_insn *insn, *subinsn;
19567 int normal_length;
19569 /* We need up-to-date instruction lengths. */
19570 shorten_branches (get_insns ());
19572 /* Look for a branch that is longer than normal. The normal length for
19573 non-MIPS16 branches is 8, because the length includes the delay slot.
19574 It is 4 for MIPS16, because MIPS16 branches are extended instructions,
19575 but they have no delay slot. */
19576 normal_length = (TARGET_MIPS16 ? 4 : 8);
19577 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
19578 FOR_EACH_SUBINSN (subinsn, insn)
19579 if (JUMP_P (subinsn)
19580 && get_attr_length (subinsn) > normal_length
19581 && (any_condjump_p (subinsn) || any_uncondjump_p (subinsn)))
19582 return true;
19584 return false;
19587 /* If we are using a GOT, but have not decided to use a global pointer yet,
19588 see whether we need one to implement long branches. Convert the ghost
19589 global-pointer instructions into real ones if so. */
19591 static bool
19592 mips_expand_ghost_gp_insns (void)
19594 /* Quick exit if we already know that we will or won't need a
19595 global pointer. */
19596 if (!TARGET_USE_GOT
19597 || cfun->machine->global_pointer == INVALID_REGNUM
19598 || mips_must_initialize_gp_p ())
19599 return false;
19601 /* Run a full check for long branches. */
19602 if (!mips_has_long_branch_p ())
19603 return false;
19605 /* We've now established that we need $gp. */
19606 cfun->machine->must_initialize_gp_p = true;
19607 split_all_insns_noflow ();
19609 return true;
19612 /* Subroutine of mips_reorg to manage passes that require DF. */
19614 static void
19615 mips_df_reorg (void)
19617 /* Create def-use chains. */
19618 df_set_flags (DF_EQ_NOTES);
19619 df_chain_add_problem (DF_UD_CHAIN);
19620 df_analyze ();
19622 if (TARGET_RELAX_PIC_CALLS)
19623 mips_annotate_pic_calls ();
19625 if (mips_r10k_cache_barrier != R10K_CACHE_BARRIER_NONE)
19626 r10k_insert_cache_barriers ();
19628 df_finish_pass (false);
19631 /* Emit code to load LABEL_REF SRC into MIPS16 register DEST. This is
19632 called very late in mips_reorg, but the caller is required to run
19633 mips16_lay_out_constants on the result. */
19635 static void
19636 mips16_load_branch_target (rtx dest, rtx src)
19638 if (TARGET_ABICALLS && !TARGET_ABSOLUTE_ABICALLS)
19640 rtx page, low;
19642 if (mips_cfun_has_cprestore_slot_p ())
19643 mips_emit_move (dest, mips_cprestore_slot (dest, true));
19644 else
19645 mips_emit_move (dest, pic_offset_table_rtx);
19646 page = mips_unspec_address (src, SYMBOL_GOTOFF_PAGE);
19647 low = mips_unspec_address (src, SYMBOL_GOT_PAGE_OFST);
19648 emit_insn (gen_rtx_SET (dest,
19649 PMODE_INSN (gen_unspec_got, (dest, page))));
19650 emit_insn (gen_rtx_SET (dest, gen_rtx_LO_SUM (Pmode, dest, low)));
19652 else
19654 src = mips_unspec_address (src, SYMBOL_ABSOLUTE);
19655 mips_emit_move (dest, src);
19659 /* If we're compiling a MIPS16 function, look for and split any long branches.
19660 This must be called after all other instruction modifications in
19661 mips_reorg. */
19663 static void
19664 mips16_split_long_branches (void)
19666 bool something_changed;
19668 if (!TARGET_MIPS16)
19669 return;
19671 /* Loop until the alignments for all targets are sufficient. */
19674 rtx_insn *insn;
19675 rtx_jump_insn *jump_insn;
19677 shorten_branches (get_insns ());
19678 something_changed = false;
19679 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
19680 if ((jump_insn = dyn_cast <rtx_jump_insn *> (insn))
19681 && get_attr_length (jump_insn) > 4
19682 && (any_condjump_p (jump_insn) || any_uncondjump_p (jump_insn)))
19684 rtx old_label, temp, saved_temp;
19685 rtx_code_label *new_label;
19686 rtx target;
19687 rtx_insn *jump, *jump_sequence;
19689 start_sequence ();
19691 /* Free up a MIPS16 register by saving it in $1. */
19692 saved_temp = gen_rtx_REG (Pmode, AT_REGNUM);
19693 temp = gen_rtx_REG (Pmode, GP_REG_FIRST + 2);
19694 emit_move_insn (saved_temp, temp);
19696 /* Load the branch target into TEMP. */
19697 old_label = JUMP_LABEL (jump_insn);
19698 target = gen_rtx_LABEL_REF (Pmode, old_label);
19699 mips16_load_branch_target (temp, target);
19701 /* Jump to the target and restore the register's
19702 original value. */
19703 jump = emit_jump_insn (PMODE_INSN (gen_indirect_jump_and_restore,
19704 (temp, temp, saved_temp)));
19705 JUMP_LABEL (jump) = old_label;
19706 LABEL_NUSES (old_label)++;
19708 /* Rewrite any symbolic references that are supposed to use
19709 a PC-relative constant pool. */
19710 mips16_lay_out_constants (false);
19712 if (simplejump_p (jump_insn))
19713 /* We're going to replace INSN with a longer form. */
19714 new_label = NULL;
19715 else
19717 /* Create a branch-around label for the original
19718 instruction. */
19719 new_label = gen_label_rtx ();
19720 emit_label (new_label);
19723 jump_sequence = get_insns ();
19724 end_sequence ();
19726 emit_insn_after (jump_sequence, jump_insn);
19727 if (new_label)
19728 invert_jump (jump_insn, new_label, false);
19729 else
19730 delete_insn (jump_insn);
19731 something_changed = true;
19734 while (something_changed);
19737 /* Insert a `.insn' assembly pseudo-op after any labels followed by
19738 a MIPS16 constant pool or no insn at all. This is needed so that
19739 targets that have been optimized away are still marked as code
19740 and therefore branches that remained and point to them are known
19741 to retain the ISA mode and as such can be successfully assembled. */
19743 static void
19744 mips_insert_insn_pseudos (void)
19746 bool insn_pseudo_needed = TRUE;
19747 rtx_insn *insn;
19749 for (insn = get_last_insn (); insn != NULL_RTX; insn = PREV_INSN (insn))
19750 switch (GET_CODE (insn))
19752 case INSN:
19753 if (GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
19754 && XINT (PATTERN (insn), 1) == UNSPEC_CONSTTABLE)
19756 insn_pseudo_needed = TRUE;
19757 break;
19759 /* Fall through. */
19760 case JUMP_INSN:
19761 case CALL_INSN:
19762 case JUMP_TABLE_DATA:
19763 insn_pseudo_needed = FALSE;
19764 break;
19765 case CODE_LABEL:
19766 if (insn_pseudo_needed)
19768 emit_insn_after (gen_insn_pseudo (), insn);
19769 insn_pseudo_needed = FALSE;
19771 break;
19772 default:
19773 break;
19777 /* Implement TARGET_MACHINE_DEPENDENT_REORG. */
19779 static void
19780 mips_reorg (void)
19782 /* Restore the BLOCK_FOR_INSN pointers, which are needed by DF. Also during
19783 insn splitting in mips16_lay_out_constants, DF insn info is only kept up
19784 to date if the CFG is available. */
19785 if (mips_cfg_in_reorg ())
19786 compute_bb_for_insn ();
19787 mips16_lay_out_constants (true);
19788 if (mips_cfg_in_reorg ())
19790 mips_df_reorg ();
19791 free_bb_for_insn ();
19795 /* We use a machine specific pass to do a second machine dependent reorg
19796 pass after delay branch scheduling. */
19798 static unsigned int
19799 mips_machine_reorg2 (void)
19801 mips_reorg_process_insns ();
19802 if (!TARGET_MIPS16
19803 && TARGET_EXPLICIT_RELOCS
19804 && TUNE_MIPS4130
19805 && TARGET_VR4130_ALIGN)
19806 vr4130_align_insns ();
19807 if (mips_expand_ghost_gp_insns ())
19808 /* The expansion could invalidate some of the VR4130 alignment
19809 optimizations, but this should be an extremely rare case anyhow. */
19810 mips_reorg_process_insns ();
19811 mips16_split_long_branches ();
19812 mips_insert_insn_pseudos ();
19813 return 0;
19816 namespace {
19818 const pass_data pass_data_mips_machine_reorg2 =
19820 RTL_PASS, /* type */
19821 "mach2", /* name */
19822 OPTGROUP_NONE, /* optinfo_flags */
19823 TV_MACH_DEP, /* tv_id */
19824 0, /* properties_required */
19825 0, /* properties_provided */
19826 0, /* properties_destroyed */
19827 0, /* todo_flags_start */
19828 0, /* todo_flags_finish */
19831 class pass_mips_machine_reorg2 : public rtl_opt_pass
19833 public:
19834 pass_mips_machine_reorg2(gcc::context *ctxt)
19835 : rtl_opt_pass(pass_data_mips_machine_reorg2, ctxt)
19838 /* opt_pass methods: */
19839 virtual unsigned int execute (function *) { return mips_machine_reorg2 (); }
19841 }; // class pass_mips_machine_reorg2
19843 } // anon namespace
19845 rtl_opt_pass *
19846 make_pass_mips_machine_reorg2 (gcc::context *ctxt)
19848 return new pass_mips_machine_reorg2 (ctxt);
19852 /* Implement TARGET_ASM_OUTPUT_MI_THUNK. Generate rtl rather than asm text
19853 in order to avoid duplicating too much logic from elsewhere. */
19855 static void
19856 mips_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
19857 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
19858 tree function)
19860 const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
19861 rtx this_rtx, temp1, temp2, fnaddr;
19862 rtx_insn *insn;
19863 bool use_sibcall_p;
19865 /* Pretend to be a post-reload pass while generating rtl. */
19866 reload_completed = 1;
19868 /* Mark the end of the (empty) prologue. */
19869 emit_note (NOTE_INSN_PROLOGUE_END);
19871 /* Determine if we can use a sibcall to call FUNCTION directly. */
19872 fnaddr = XEXP (DECL_RTL (function), 0);
19873 use_sibcall_p = (mips_function_ok_for_sibcall (function, NULL)
19874 && const_call_insn_operand (fnaddr, Pmode));
19876 /* Determine if we need to load FNADDR from the GOT. */
19877 if (!use_sibcall_p
19878 && (mips_got_symbol_type_p
19879 (mips_classify_symbol (fnaddr, SYMBOL_CONTEXT_LEA))))
19881 /* Pick a global pointer. Use a call-clobbered register if
19882 TARGET_CALL_SAVED_GP. */
19883 cfun->machine->global_pointer
19884 = TARGET_CALL_SAVED_GP ? 15 : GLOBAL_POINTER_REGNUM;
19885 cfun->machine->must_initialize_gp_p = true;
19886 SET_REGNO (pic_offset_table_rtx, cfun->machine->global_pointer);
19888 /* Set up the global pointer for n32 or n64 abicalls. */
19889 mips_emit_loadgp ();
19892 /* We need two temporary registers in some cases. */
19893 temp1 = gen_rtx_REG (Pmode, 2);
19894 temp2 = gen_rtx_REG (Pmode, 3);
19896 /* Find out which register contains the "this" pointer. */
19897 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
19898 this_rtx = gen_rtx_REG (Pmode, GP_ARG_FIRST + 1);
19899 else
19900 this_rtx = gen_rtx_REG (Pmode, GP_ARG_FIRST);
19902 /* Add DELTA to THIS_RTX. */
19903 if (delta != 0)
19905 rtx offset = GEN_INT (delta);
19906 if (!SMALL_OPERAND (delta))
19908 mips_emit_move (temp1, offset);
19909 offset = temp1;
19911 emit_insn (gen_add3_insn (this_rtx, this_rtx, offset));
19914 /* If needed, add *(*THIS_RTX + VCALL_OFFSET) to THIS_RTX. */
19915 if (vcall_offset != 0)
19917 rtx addr;
19919 /* Set TEMP1 to *THIS_RTX. */
19920 mips_emit_move (temp1, gen_rtx_MEM (Pmode, this_rtx));
19922 /* Set ADDR to a legitimate address for *THIS_RTX + VCALL_OFFSET. */
19923 addr = mips_add_offset (temp2, temp1, vcall_offset);
19925 /* Load the offset and add it to THIS_RTX. */
19926 mips_emit_move (temp1, gen_rtx_MEM (Pmode, addr));
19927 emit_insn (gen_add3_insn (this_rtx, this_rtx, temp1));
19930 /* Jump to the target function. Use a sibcall if direct jumps are
19931 allowed, otherwise load the address into a register first. */
19932 if (use_sibcall_p)
19934 insn = emit_call_insn (gen_sibcall_internal (fnaddr, const0_rtx));
19935 SIBLING_CALL_P (insn) = 1;
19937 else
19939 /* This is messy. GAS treats "la $25,foo" as part of a call
19940 sequence and may allow a global "foo" to be lazily bound.
19941 The general move patterns therefore reject this combination.
19943 In this context, lazy binding would actually be OK
19944 for TARGET_CALL_CLOBBERED_GP, but it's still wrong for
19945 TARGET_CALL_SAVED_GP; see mips_load_call_address.
19946 We must therefore load the address via a temporary
19947 register if mips_dangerous_for_la25_p.
19949 If we jump to the temporary register rather than $25,
19950 the assembler can use the move insn to fill the jump's
19951 delay slot.
19953 We can use the same technique for MIPS16 code, where $25
19954 is not a valid JR register. */
19955 if (TARGET_USE_PIC_FN_ADDR_REG
19956 && !TARGET_MIPS16
19957 && !mips_dangerous_for_la25_p (fnaddr))
19958 temp1 = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
19959 mips_load_call_address (MIPS_CALL_SIBCALL, temp1, fnaddr);
19961 if (TARGET_USE_PIC_FN_ADDR_REG
19962 && REGNO (temp1) != PIC_FUNCTION_ADDR_REGNUM)
19963 mips_emit_move (gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM), temp1);
19964 emit_jump_insn (gen_indirect_jump (temp1));
19967 /* Run just enough of rest_of_compilation. This sequence was
19968 "borrowed" from alpha.cc. */
19969 insn = get_insns ();
19970 split_all_insns_noflow ();
19971 mips16_lay_out_constants (true);
19972 shorten_branches (insn);
19973 assemble_start_function (thunk_fndecl, fnname);
19974 final_start_function (insn, file, 1);
19975 final (insn, file, 1);
19976 final_end_function ();
19977 assemble_end_function (thunk_fndecl, fnname);
19979 /* Clean up the vars set above. Note that final_end_function resets
19980 the global pointer for us. */
19981 reload_completed = 0;
19985 /* The last argument passed to mips_set_compression_mode,
19986 or negative if the function hasn't been called yet. */
19987 static unsigned int old_compression_mode = -1;
19989 /* Set up the target-dependent global state for ISA mode COMPRESSION_MODE,
19990 which is either MASK_MIPS16 or MASK_MICROMIPS. */
19992 static void
19993 mips_set_compression_mode (unsigned int compression_mode)
19996 if (compression_mode == old_compression_mode)
19997 return;
19999 /* Restore base settings of various flags. */
20000 target_flags = mips_base_target_flags;
20001 flag_schedule_insns = mips_base_schedule_insns;
20002 flag_reorder_blocks_and_partition = mips_base_reorder_blocks_and_partition;
20003 flag_move_loop_invariants = mips_base_move_loop_invariants;
20004 str_align_loops = mips_base_align_loops;
20005 str_align_jumps = mips_base_align_jumps;
20006 str_align_functions = mips_base_align_functions;
20007 target_flags &= ~(MASK_MIPS16 | MASK_MICROMIPS);
20008 target_flags |= compression_mode;
20010 if (compression_mode & MASK_MIPS16)
20012 /* Switch to MIPS16 mode. */
20013 target_flags |= MASK_MIPS16;
20015 /* Turn off SYNCI if it was on, MIPS16 doesn't support it. */
20016 target_flags &= ~MASK_SYNCI;
20018 /* Don't run the scheduler before reload, since it tends to
20019 increase register pressure. */
20020 flag_schedule_insns = 0;
20022 /* Don't do hot/cold partitioning. mips16_lay_out_constants expects
20023 the whole function to be in a single section. */
20024 flag_reorder_blocks_and_partition = 0;
20026 /* Don't move loop invariants, because it tends to increase
20027 register pressure. It also introduces an extra move in cases
20028 where the constant is the first operand in a two-operand binary
20029 instruction, or when it forms a register argument to a functon
20030 call. */
20031 flag_move_loop_invariants = 0;
20033 target_flags |= MASK_EXPLICIT_RELOCS;
20035 /* Experiments suggest we get the best overall section-anchor
20036 results from using the range of an unextended LW or SW. Code
20037 that makes heavy use of byte or short accesses can do better
20038 with ranges of 0...31 and 0...63 respectively, but most code is
20039 sensitive to the range of LW and SW instead. */
20040 targetm.min_anchor_offset = 0;
20041 targetm.max_anchor_offset = 127;
20043 targetm.const_anchor = 0;
20045 /* MIPS16 has no BAL instruction. */
20046 target_flags &= ~MASK_RELAX_PIC_CALLS;
20048 /* The R4000 errata don't apply to any known MIPS16 cores.
20049 It's simpler to make the R4000 fixes and MIPS16 mode
20050 mutually exclusive. */
20051 target_flags &= ~MASK_FIX_R4000;
20053 if (flag_pic && !TARGET_OLDABI)
20054 sorry ("MIPS16 PIC for ABIs other than o32 and o64");
20056 if (TARGET_XGOT)
20057 sorry ("MIPS16 %<-mxgot%> code");
20059 if (TARGET_HARD_FLOAT_ABI && !TARGET_OLDABI)
20060 sorry ("%<hard-float%> MIPS16 code for ABIs other than o32 and o64");
20062 if (TARGET_MSA)
20063 sorry ("MSA MIPS16 code");
20065 else
20067 /* Switch to microMIPS or the standard encoding. */
20069 if (TARGET_MICROMIPS)
20070 /* Avoid branch likely. */
20071 target_flags &= ~MASK_BRANCHLIKELY;
20073 /* Provide default values for align_* for 64-bit targets. */
20074 if (TARGET_64BIT)
20076 if (flag_align_loops && !str_align_loops)
20077 str_align_loops = "8";
20078 if (flag_align_jumps && !str_align_jumps)
20079 str_align_jumps = "8";
20080 if (flag_align_functions && !str_align_functions)
20081 str_align_functions = "8";
20084 targetm.min_anchor_offset = -32768;
20085 targetm.max_anchor_offset = 32767;
20087 targetm.const_anchor = 0x8000;
20090 /* (Re)initialize MIPS target internals for new ISA. */
20091 mips_init_relocs ();
20093 if (compression_mode & MASK_MIPS16)
20095 if (!mips16_globals)
20096 mips16_globals = save_target_globals_default_opts ();
20097 else
20098 restore_target_globals (mips16_globals);
20100 else if (compression_mode & MASK_MICROMIPS)
20102 if (!micromips_globals)
20103 micromips_globals = save_target_globals_default_opts ();
20104 else
20105 restore_target_globals (micromips_globals);
20107 else
20108 restore_target_globals (&default_target_globals);
20110 old_compression_mode = compression_mode;
20113 /* Implement TARGET_SET_CURRENT_FUNCTION. Decide whether the current
20114 function should use the MIPS16 or microMIPS ISA and switch modes
20115 accordingly. Also set the current code_readable mode. */
20117 static void
20118 mips_set_current_function (tree fndecl)
20120 enum mips_code_readable_setting old_code_readable = mips_code_readable;
20122 mips_set_compression_mode (mips_get_compress_mode (fndecl));
20124 mips_code_readable = mips_get_code_readable_attr (fndecl);
20126 /* Since the mips_code_readable setting has potentially changed, the
20127 relocation tables must be reinitialized. Otherwise GCC will not
20128 split symbols for functions that are code_readable ("no") when others
20129 are code_readable ("yes") and ICE later on in places such as
20130 mips_emit_move. Ditto for similar paired cases. It must be restored
20131 to its previous state as well. */
20132 if (old_code_readable != mips_code_readable)
20133 mips_init_relocs ();
20136 /* Allocate a chunk of memory for per-function machine-dependent data. */
20138 static struct machine_function *
20139 mips_init_machine_status (void)
20141 return ggc_cleared_alloc<machine_function> ();
20144 /* Return the processor associated with the given ISA level, or null
20145 if the ISA isn't valid. */
20147 static const struct mips_cpu_info *
20148 mips_cpu_info_from_isa (int isa)
20150 unsigned int i;
20152 for (i = 0; i < ARRAY_SIZE (mips_cpu_info_table); i++)
20153 if (mips_cpu_info_table[i].isa == isa)
20154 return mips_cpu_info_table + i;
20156 return NULL;
20159 /* Return a mips_cpu_info entry determined by an option valued
20160 OPT. */
20162 static const struct mips_cpu_info *
20163 mips_cpu_info_from_opt (int opt)
20165 switch (opt)
20167 case MIPS_ARCH_OPTION_FROM_ABI:
20168 /* 'from-abi' selects the most compatible architecture for the
20169 given ABI: MIPS I for 32-bit ABIs and MIPS III for 64-bit
20170 ABIs. For the EABIs, we have to decide whether we're using
20171 the 32-bit or 64-bit version. */
20172 return mips_cpu_info_from_isa (ABI_NEEDS_32BIT_REGS ? 1
20173 : ABI_NEEDS_64BIT_REGS ? 3
20174 : (TARGET_64BIT ? 3 : 1));
20176 case MIPS_ARCH_OPTION_NATIVE:
20177 gcc_unreachable ();
20179 default:
20180 return &mips_cpu_info_table[opt];
20184 /* Return a default mips_cpu_info entry, given that no -march= option
20185 was explicitly specified. */
20187 static const struct mips_cpu_info *
20188 mips_default_arch (void)
20190 #if defined (MIPS_CPU_STRING_DEFAULT)
20191 unsigned int i;
20192 for (i = 0; i < ARRAY_SIZE (mips_cpu_info_table); i++)
20193 if (strcmp (mips_cpu_info_table[i].name, MIPS_CPU_STRING_DEFAULT) == 0)
20194 return mips_cpu_info_table + i;
20195 gcc_unreachable ();
20196 #elif defined (MIPS_ISA_DEFAULT)
20197 return mips_cpu_info_from_isa (MIPS_ISA_DEFAULT);
20198 #else
20199 /* 'from-abi' makes a good default: you get whatever the ABI
20200 requires. */
20201 return mips_cpu_info_from_opt (MIPS_ARCH_OPTION_FROM_ABI);
20202 #endif
20205 /* Set up globals to generate code for the ISA or processor
20206 described by INFO. */
20208 static void
20209 mips_set_architecture (const struct mips_cpu_info *info)
20211 if (info != 0)
20213 mips_arch_info = info;
20214 mips_arch = info->cpu;
20215 mips_isa = info->isa;
20216 if (mips_isa < MIPS_ISA_MIPS32)
20217 mips_isa_rev = 0;
20218 else
20219 /* we can do this is due to the
20220 * enum of MIPS32rN is from 32 to 37
20221 * enum of MIPS64rN is from 64 to 69 */
20222 mips_isa_rev = (mips_isa & 31) + 1;
20226 /* Likewise for tuning. */
20228 static void
20229 mips_set_tune (const struct mips_cpu_info *info)
20231 if (info != 0)
20233 mips_tune_info = info;
20234 mips_tune = info->cpu;
20238 /* Implement TARGET_OPTION_OVERRIDE. */
20240 static void
20241 mips_option_override (void)
20243 int i, regno, mode;
20245 if (OPTION_SET_P (mips_isa_option))
20246 mips_isa_option_info = &mips_cpu_info_table[mips_isa_option];
20248 #ifdef SUBTARGET_OVERRIDE_OPTIONS
20249 SUBTARGET_OVERRIDE_OPTIONS;
20250 #endif
20252 /* MIPS16 and microMIPS cannot coexist. */
20253 if (TARGET_MICROMIPS && TARGET_MIPS16)
20254 error ("unsupported combination: %s", "-mips16 -mmicromips");
20256 /* Prohibit Paired-Single and MSA combination. This is software restriction
20257 rather than architectural. */
20258 if (ISA_HAS_MSA && TARGET_PAIRED_SINGLE_FLOAT)
20259 error ("unsupported combination: %s", "-mmsa -mpaired-single");
20261 /* Save the base compression state and process flags as though we
20262 were generating uncompressed code. */
20263 mips_base_compression_flags = TARGET_COMPRESSION;
20264 target_flags &= ~TARGET_COMPRESSION;
20265 mips_base_code_readable = mips_code_readable;
20267 /* -mno-float overrides -mhard-float and -msoft-float. */
20268 if (TARGET_NO_FLOAT)
20270 target_flags |= MASK_SOFT_FLOAT_ABI;
20271 target_flags_explicit |= MASK_SOFT_FLOAT_ABI;
20274 if (TARGET_FLIP_MIPS16)
20275 TARGET_INTERLINK_COMPRESSED = 1;
20277 /* Set the small data limit. */
20278 mips_small_data_threshold = (OPTION_SET_P (g_switch_value)
20279 ? g_switch_value
20280 : MIPS_DEFAULT_GVALUE);
20282 /* The following code determines the architecture and register size.
20283 Similar code was added to GAS 2.14 (see tc-mips.c:md_after_parse_args()).
20284 The GAS and GCC code should be kept in sync as much as possible. */
20286 if (OPTION_SET_P (mips_arch_option))
20287 mips_set_architecture (mips_cpu_info_from_opt (mips_arch_option));
20289 if (mips_isa_option_info != 0)
20291 if (mips_arch_info == 0)
20292 mips_set_architecture (mips_isa_option_info);
20293 else if (mips_arch_info->isa != mips_isa_option_info->isa)
20294 error ("%<-%s%> conflicts with the other architecture options, "
20295 "which specify a %s processor",
20296 mips_isa_option_info->name,
20297 mips_cpu_info_from_isa (mips_arch_info->isa)->name);
20300 if (mips_arch_info == 0)
20301 mips_set_architecture (mips_default_arch ());
20303 if (ABI_NEEDS_64BIT_REGS && !ISA_HAS_64BIT_REGS)
20304 error ("%<-march=%s%> is not compatible with the selected ABI",
20305 mips_arch_info->name);
20307 /* Optimize for mips_arch, unless -mtune selects a different processor. */
20308 if (OPTION_SET_P (mips_tune_option))
20309 mips_set_tune (mips_cpu_info_from_opt (mips_tune_option));
20311 if (mips_tune_info == 0)
20312 mips_set_tune (mips_arch_info);
20314 if ((target_flags_explicit & MASK_64BIT) != 0)
20316 /* The user specified the size of the integer registers. Make sure
20317 it agrees with the ABI and ISA. */
20318 if (TARGET_64BIT && !ISA_HAS_64BIT_REGS)
20319 error ("%<-mgp64%> used with a 32-bit processor");
20320 else if (!TARGET_64BIT && ABI_NEEDS_64BIT_REGS)
20321 error ("%<-mgp32%> used with a 64-bit ABI");
20322 else if (TARGET_64BIT && ABI_NEEDS_32BIT_REGS)
20323 error ("%<-mgp64%> used with a 32-bit ABI");
20325 else
20327 /* Infer the integer register size from the ABI and processor.
20328 Restrict ourselves to 32-bit registers if that's all the
20329 processor has, or if the ABI cannot handle 64-bit registers. */
20330 if (ABI_NEEDS_32BIT_REGS || !ISA_HAS_64BIT_REGS)
20331 target_flags &= ~MASK_64BIT;
20332 else
20333 target_flags |= MASK_64BIT;
20336 /* -fsanitize=address needs to turn on -fasynchronous-unwind-tables in
20337 order for tracebacks to be complete but not if any
20338 -fasynchronous-unwind-table were already specified. */
20339 if (flag_sanitize & SANITIZE_USER_ADDRESS
20340 && !global_options_set.x_flag_asynchronous_unwind_tables)
20341 flag_asynchronous_unwind_tables = 1;
20343 if ((target_flags_explicit & MASK_FLOAT64) != 0)
20345 if (mips_isa_rev >= 6 && !TARGET_FLOAT64)
20346 error ("the %qs architecture does not support %<-mfp32%>",
20347 mips_arch_info->name);
20348 else if (TARGET_SINGLE_FLOAT && TARGET_FLOAT64)
20349 error ("unsupported combination: %s", "-mfp64 -msingle-float");
20350 else if (TARGET_64BIT && TARGET_DOUBLE_FLOAT && !TARGET_FLOAT64)
20351 error ("unsupported combination: %s", "-mgp64 -mfp32 -mdouble-float");
20352 else if (!TARGET_64BIT && TARGET_FLOAT64)
20354 if (!ISA_HAS_MXHC1)
20355 error ("%<-mgp32%> and %<-mfp64%> can only be combined if"
20356 " the target supports the mfhc1 and mthc1 instructions");
20357 else if (mips_abi != ABI_32)
20358 error ("%<-mgp32%> and %<-mfp64%> can only be combined when using"
20359 " the o32 ABI");
20362 else
20364 /* -msingle-float selects 32-bit float registers. On r6 and later,
20365 -mdouble-float selects 64-bit float registers, since the old paired
20366 register model is not supported. In other cases the float registers
20367 should be the same size as the integer ones. */
20368 if (mips_isa_rev >= 6 && TARGET_DOUBLE_FLOAT && !TARGET_FLOATXX)
20369 target_flags |= MASK_FLOAT64;
20370 else if (TARGET_64BIT && TARGET_DOUBLE_FLOAT)
20371 target_flags |= MASK_FLOAT64;
20372 else if (mips_abi == ABI_32 && ISA_HAS_MSA && !TARGET_FLOATXX)
20373 target_flags |= MASK_FLOAT64;
20374 else
20375 target_flags &= ~MASK_FLOAT64;
20378 if (mips_abi != ABI_32 && TARGET_FLOATXX)
20379 error ("%<-mfpxx%> can only be used with the o32 ABI");
20380 else if (TARGET_FLOAT64 && TARGET_FLOATXX)
20381 error ("unsupported combination: %s", "-mfp64 -mfpxx");
20382 else if (ISA_MIPS1 && !TARGET_FLOAT32)
20383 error ("%<-march=%s%> requires %<-mfp32%>", mips_arch_info->name);
20384 else if (TARGET_FLOATXX && !mips_lra_flag)
20385 error ("%<-mfpxx%> requires %<-mlra%>");
20387 /* End of code shared with GAS. */
20389 /* The R5900 FPU only supports single precision. */
20390 if (TARGET_MIPS5900 && TARGET_HARD_FLOAT_ABI && TARGET_DOUBLE_FLOAT)
20391 error ("unsupported combination: %s",
20392 "-march=r5900 -mhard-float -mdouble-float");
20394 /* If a -mlong* option was given, check that it matches the ABI,
20395 otherwise infer the -mlong* setting from the other options. */
20396 if ((target_flags_explicit & MASK_LONG64) != 0)
20398 if (TARGET_LONG64)
20400 if (mips_abi == ABI_N32)
20401 error ("%qs is incompatible with %qs", "-mabi=n32", "-mlong64");
20402 else if (mips_abi == ABI_32)
20403 error ("%qs is incompatible with %qs", "-mabi=32", "-mlong64");
20404 else if (mips_abi == ABI_O64 && TARGET_ABICALLS)
20405 /* We have traditionally allowed non-abicalls code to use
20406 an LP64 form of o64. However, it would take a bit more
20407 effort to support the combination of 32-bit GOT entries
20408 and 64-bit pointers, so we treat the abicalls case as
20409 an error. */
20410 error ("the combination of %qs and %qs is incompatible with %qs",
20411 "-mabi=o64", "-mabicalls", "-mlong64");
20413 else
20415 if (mips_abi == ABI_64)
20416 error ("%qs is incompatible with %qs", "-mabi=64", "-mlong32");
20419 else
20421 if ((mips_abi == ABI_EABI && TARGET_64BIT) || mips_abi == ABI_64)
20422 target_flags |= MASK_LONG64;
20423 else
20424 target_flags &= ~MASK_LONG64;
20427 if (!TARGET_OLDABI)
20428 flag_pcc_struct_return = 0;
20430 /* Decide which rtx_costs structure to use. */
20431 if (optimize_size)
20432 mips_cost = &mips_rtx_cost_optimize_size;
20433 else
20434 mips_cost = &mips_rtx_cost_data[mips_tune];
20436 /* If the user hasn't specified a branch cost, use the processor's
20437 default. */
20438 if (mips_branch_cost == 0)
20439 mips_branch_cost = mips_cost->branch_cost;
20441 /* If neither -mbranch-likely nor -mno-branch-likely was given
20442 on the command line, set MASK_BRANCHLIKELY based on the target
20443 architecture and tuning flags. Annulled delay slots are a
20444 size win, so we only consider the processor-specific tuning
20445 for !optimize_size. */
20446 if ((target_flags_explicit & MASK_BRANCHLIKELY) == 0)
20448 if (ISA_HAS_BRANCHLIKELY
20449 && ((optimize_size
20450 && (mips_tune_info->tune_flags
20451 & PTF_AVOID_BRANCHLIKELY_SIZE) == 0)
20452 || (!optimize_size
20453 && optimize > 0
20454 && (mips_tune_info->tune_flags
20455 & PTF_AVOID_BRANCHLIKELY_SPEED) == 0)
20456 || (mips_tune_info->tune_flags
20457 & PTF_AVOID_BRANCHLIKELY_ALWAYS) == 0))
20458 target_flags |= MASK_BRANCHLIKELY;
20459 else
20460 target_flags &= ~MASK_BRANCHLIKELY;
20462 else if (TARGET_BRANCHLIKELY && !ISA_HAS_BRANCHLIKELY)
20463 warning (0, "the %qs architecture does not support branch-likely"
20464 " instructions", mips_arch_info->name);
20466 /* If the user hasn't specified -mimadd or -mno-imadd set
20467 MASK_IMADD based on the target architecture and tuning
20468 flags. */
20469 if ((target_flags_explicit & MASK_IMADD) == 0)
20471 if (ISA_HAS_MADD_MSUB &&
20472 (mips_tune_info->tune_flags & PTF_AVOID_IMADD) == 0)
20473 target_flags |= MASK_IMADD;
20474 else
20475 target_flags &= ~MASK_IMADD;
20477 else if (TARGET_IMADD && !ISA_HAS_MADD_MSUB)
20478 warning (0, "the %qs architecture does not support madd or msub"
20479 " instructions", mips_arch_info->name);
20481 /* If neither -modd-spreg nor -mno-odd-spreg was given on the command
20482 line, set MASK_ODD_SPREG based on the ISA and ABI. */
20483 if ((target_flags_explicit & MASK_ODD_SPREG) == 0)
20485 /* Disable TARGET_ODD_SPREG when using the o32 FPXX ABI. */
20486 if (!ISA_HAS_ODD_SPREG || TARGET_FLOATXX)
20487 target_flags &= ~MASK_ODD_SPREG;
20488 else
20489 target_flags |= MASK_ODD_SPREG;
20491 else if (TARGET_ODD_SPREG && !ISA_HAS_ODD_SPREG)
20492 warning (0, "the %qs architecture does not support odd single-precision"
20493 " registers", mips_arch_info->name);
20495 if (!TARGET_ODD_SPREG && TARGET_64BIT)
20497 error ("unsupported combination: %s", "-mgp64 -mno-odd-spreg");
20498 /* Allow compilation to continue further even though invalid output
20499 will be produced. */
20500 target_flags |= MASK_ODD_SPREG;
20503 if (!ISA_HAS_DELAY_SLOTS && mips_cb == MIPS_CB_NEVER)
20505 error ("unsupported combination: %qs%s %s",
20506 mips_arch_info->name, TARGET_MICROMIPS ? " -mmicromips" : "",
20507 "-mcompact-branches=never");
20510 /* Require explicit relocs for MIPS R6 onwards. This enables simplification
20511 of the compact branch and jump support through the backend. */
20512 if (!TARGET_EXPLICIT_RELOCS && mips_isa_rev >= 6)
20514 error ("unsupported combination: %qs %s",
20515 mips_arch_info->name, "-mno-explicit-relocs");
20518 /* The effect of -mabicalls isn't defined for the EABI. */
20519 if (mips_abi == ABI_EABI && TARGET_ABICALLS)
20521 error ("unsupported combination: %s", "-mabicalls -mabi=eabi");
20522 target_flags &= ~MASK_ABICALLS;
20525 /* PIC requires -mabicalls. */
20526 if (flag_pic)
20528 if (mips_abi == ABI_EABI)
20529 error ("cannot generate position-independent code for %qs",
20530 "-mabi=eabi");
20531 else if (!TARGET_ABICALLS)
20532 error ("position-independent code requires %qs", "-mabicalls");
20535 if (TARGET_ABICALLS_PIC2)
20536 /* We need to set flag_pic for executables as well as DSOs
20537 because we may reference symbols that are not defined in
20538 the final executable. (MIPS does not use things like
20539 copy relocs, for example.)
20541 There is a body of code that uses __PIC__ to distinguish
20542 between -mabicalls and -mno-abicalls code. The non-__PIC__
20543 variant is usually appropriate for TARGET_ABICALLS_PIC0, as
20544 long as any indirect jumps use $25. */
20545 flag_pic = 1;
20547 /* -mvr4130-align is a "speed over size" optimization: it usually produces
20548 faster code, but at the expense of more nops. Enable it at -O3 and
20549 above. */
20550 if (optimize > 2 && (target_flags_explicit & MASK_VR4130_ALIGN) == 0)
20551 target_flags |= MASK_VR4130_ALIGN;
20553 /* Prefer a call to memcpy over inline code when optimizing for size,
20554 though see MOVE_RATIO in mips.h. */
20555 if (optimize_size && (target_flags_explicit & MASK_MEMCPY) == 0)
20556 target_flags |= MASK_MEMCPY;
20558 /* If we have a nonzero small-data limit, check that the -mgpopt
20559 setting is consistent with the other target flags. */
20560 if (mips_small_data_threshold > 0)
20562 if (!TARGET_GPOPT)
20564 if (!TARGET_EXPLICIT_RELOCS)
20565 error ("%<-mno-gpopt%> needs %<-mexplicit-relocs%>");
20567 TARGET_LOCAL_SDATA = false;
20568 TARGET_EXTERN_SDATA = false;
20570 else
20572 if (TARGET_VXWORKS_RTP)
20573 warning (0, "cannot use small-data accesses for %qs", "-mrtp");
20575 if (TARGET_ABICALLS)
20576 warning (0, "cannot use small-data accesses for %qs",
20577 "-mabicalls");
20581 /* Set NaN and ABS defaults. */
20582 if (mips_nan == MIPS_IEEE_754_DEFAULT && !ISA_HAS_IEEE_754_LEGACY)
20583 mips_nan = MIPS_IEEE_754_2008;
20584 if (mips_abs == MIPS_IEEE_754_DEFAULT && mips_nan == MIPS_IEEE_754_2008)
20585 mips_abs = MIPS_IEEE_754_2008;
20586 if (mips_abs == MIPS_IEEE_754_DEFAULT && !ISA_HAS_IEEE_754_LEGACY)
20587 mips_abs = MIPS_IEEE_754_2008;
20589 /* Check for IEEE 754 legacy/2008 support. */
20590 if ((mips_nan == MIPS_IEEE_754_LEGACY
20591 || mips_abs == MIPS_IEEE_754_LEGACY)
20592 && !ISA_HAS_IEEE_754_LEGACY)
20593 warning (0, "the %qs architecture does not support %<-m%s=legacy%>",
20594 mips_arch_info->name,
20595 mips_nan == MIPS_IEEE_754_LEGACY ? "nan" : "abs");
20597 if ((mips_nan == MIPS_IEEE_754_2008
20598 || mips_abs == MIPS_IEEE_754_2008)
20599 && !ISA_HAS_IEEE_754_2008)
20600 warning (0, "the %qs architecture does not support %<-m%s=2008%>",
20601 mips_arch_info->name,
20602 mips_nan == MIPS_IEEE_754_2008 ? "nan" : "abs");
20604 /* Pre-IEEE 754-2008 MIPS hardware has a quirky almost-IEEE format
20605 for all its floating point. */
20606 if (mips_nan != MIPS_IEEE_754_2008)
20608 REAL_MODE_FORMAT (SFmode) = &mips_single_format;
20609 REAL_MODE_FORMAT (DFmode) = &mips_double_format;
20610 REAL_MODE_FORMAT (TFmode) = &mips_quad_format;
20613 /* Make sure that the user didn't turn off paired single support when
20614 MIPS-3D support is requested. */
20615 if (TARGET_MIPS3D
20616 && (target_flags_explicit & MASK_PAIRED_SINGLE_FLOAT)
20617 && !TARGET_PAIRED_SINGLE_FLOAT)
20618 error ("%<-mips3d%> requires %<-mpaired-single%>");
20620 /* If TARGET_MIPS3D, enable MASK_PAIRED_SINGLE_FLOAT. */
20621 if (TARGET_MIPS3D)
20622 target_flags |= MASK_PAIRED_SINGLE_FLOAT;
20624 /* Make sure that when TARGET_PAIRED_SINGLE_FLOAT is true, TARGET_FLOAT64
20625 and TARGET_HARD_FLOAT_ABI are both true. */
20626 if (TARGET_PAIRED_SINGLE_FLOAT && !(TARGET_FLOAT64 && TARGET_HARD_FLOAT_ABI))
20628 error ("%qs must be used with %qs",
20629 TARGET_MIPS3D ? "-mips3d" : "-mpaired-single",
20630 TARGET_HARD_FLOAT_ABI ? "-mfp64" : "-mhard-float");
20631 target_flags &= ~MASK_PAIRED_SINGLE_FLOAT;
20632 TARGET_MIPS3D = 0;
20635 /* Make sure that when ISA_HAS_MSA is true, TARGET_FLOAT64 and
20636 TARGET_HARD_FLOAT_ABI and both true. */
20637 if (ISA_HAS_MSA && !(TARGET_FLOAT64 && TARGET_HARD_FLOAT_ABI))
20638 error ("%<-mmsa%> must be used with %<-mfp64%> and %<-mhard-float%>");
20640 /* Make sure that -mpaired-single is only used on ISAs that support it.
20641 We must disable it otherwise since it relies on other ISA properties
20642 like ISA_HAS_8CC having their normal values. */
20643 if (TARGET_PAIRED_SINGLE_FLOAT && !ISA_HAS_PAIRED_SINGLE)
20645 error ("the %qs architecture does not support paired-single"
20646 " instructions", mips_arch_info->name);
20647 target_flags &= ~MASK_PAIRED_SINGLE_FLOAT;
20648 TARGET_MIPS3D = 0;
20651 if (mips_r10k_cache_barrier != R10K_CACHE_BARRIER_NONE
20652 && !TARGET_CACHE_BUILTIN)
20654 error ("%qs requires a target that provides the %qs instruction",
20655 "-mr10k-cache-barrier", "cache");
20656 mips_r10k_cache_barrier = R10K_CACHE_BARRIER_NONE;
20659 /* If TARGET_DSPR2, enable TARGET_DSP. */
20660 if (TARGET_DSPR2)
20661 TARGET_DSP = true;
20663 if (TARGET_DSP && mips_isa_rev >= 6)
20665 error ("the %qs architecture does not support DSP instructions",
20666 mips_arch_info->name);
20667 TARGET_DSP = false;
20668 TARGET_DSPR2 = false;
20671 /* Make sure that when TARGET_LOONGSON_MMI is true, TARGET_HARD_FLOAT_ABI
20672 is true. In o32 pairs of floating-point registers provide 64-bit
20673 values. */
20674 if (TARGET_LOONGSON_MMI && !TARGET_HARD_FLOAT_ABI)
20675 error ("%<-mloongson-mmi%> must be used with %<-mhard-float%>");
20677 /* If TARGET_LOONGSON_EXT2, enable TARGET_LOONGSON_EXT. */
20678 if (TARGET_LOONGSON_EXT2)
20680 /* Make sure that when TARGET_LOONGSON_EXT2 is true, TARGET_LOONGSON_EXT
20681 is true. If a user explicitly says -mloongson-ext2 -mno-loongson-ext
20682 then that is an error. */
20683 if (!TARGET_LOONGSON_EXT
20684 && (target_flags_explicit & MASK_LOONGSON_EXT) != 0)
20685 error ("%<-mloongson-ext2%> must be used with %<-mloongson-ext%>");
20686 target_flags |= MASK_LOONGSON_EXT;
20689 /* .eh_frame addresses should be the same width as a C pointer.
20690 Most MIPS ABIs support only one pointer size, so the assembler
20691 will usually know exactly how big an .eh_frame address is.
20693 Unfortunately, this is not true of the 64-bit EABI. The ABI was
20694 originally defined to use 64-bit pointers (i.e. it is LP64), and
20695 this is still the default mode. However, we also support an n32-like
20696 ILP32 mode, which is selected by -mlong32. The problem is that the
20697 assembler has traditionally not had an -mlong option, so it has
20698 traditionally not known whether we're using the ILP32 or LP64 form.
20700 As it happens, gas versions up to and including 2.19 use _32-bit_
20701 addresses for EABI64 .cfi_* directives. This is wrong for the
20702 default LP64 mode, so we can't use the directives by default.
20703 Moreover, since gas's current behavior is at odds with gcc's
20704 default behavior, it seems unwise to rely on future versions
20705 of gas behaving the same way. We therefore avoid using .cfi
20706 directives for -mlong32 as well. */
20707 if (mips_abi == ABI_EABI && TARGET_64BIT)
20708 flag_dwarf2_cfi_asm = 0;
20710 /* .cfi_* directives generate a read-only section, so fall back on
20711 manual .eh_frame creation if we need the section to be writable. */
20712 if (TARGET_WRITABLE_EH_FRAME)
20713 flag_dwarf2_cfi_asm = 0;
20715 mips_init_print_operand_punct ();
20717 /* Set up array to map GCC register number to debug register number.
20718 Ignore the special purpose register numbers. */
20720 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
20722 if (GP_REG_P (i) || FP_REG_P (i) || ALL_COP_REG_P (i))
20723 mips_dwarf_regno[i] = i;
20724 else
20725 mips_dwarf_regno[i] = INVALID_REGNUM;
20728 /* Accumulator debug registers use big-endian ordering. */
20729 mips_dwarf_regno[HI_REGNUM] = MD_REG_FIRST + 0;
20730 mips_dwarf_regno[LO_REGNUM] = MD_REG_FIRST + 1;
20731 for (i = DSP_ACC_REG_FIRST; i <= DSP_ACC_REG_LAST; i += 2)
20733 mips_dwarf_regno[i + TARGET_LITTLE_ENDIAN] = i;
20734 mips_dwarf_regno[i + TARGET_BIG_ENDIAN] = i + 1;
20737 /* Set up mips_hard_regno_mode_ok. */
20738 for (mode = 0; mode < MAX_MACHINE_MODE; mode++)
20739 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
20740 mips_hard_regno_mode_ok_p[mode][regno]
20741 = mips_hard_regno_mode_ok_uncached (regno, (machine_mode) mode);
20743 /* Function to allocate machine-dependent function status. */
20744 init_machine_status = &mips_init_machine_status;
20746 /* Default to working around R4000 errata only if the processor
20747 was selected explicitly. */
20748 if ((target_flags_explicit & MASK_FIX_R4000) == 0
20749 && strcmp (mips_arch_info->name, "r4000") == 0)
20750 target_flags |= MASK_FIX_R4000;
20752 /* Default to working around R4400 errata only if the processor
20753 was selected explicitly. */
20754 if ((target_flags_explicit & MASK_FIX_R4400) == 0
20755 && strcmp (mips_arch_info->name, "r4400") == 0)
20756 target_flags |= MASK_FIX_R4400;
20758 /* Default to working around R5900 errata only if the processor
20759 was selected explicitly. */
20760 if ((target_flags_explicit & MASK_FIX_R5900) == 0
20761 && strcmp (mips_arch_info->name, "r5900") == 0)
20762 target_flags |= MASK_FIX_R5900;
20764 /* Default to working around R10000 errata only if the processor
20765 was selected explicitly. */
20766 if ((target_flags_explicit & MASK_FIX_R10000) == 0
20767 && strcmp (mips_arch_info->name, "r10000") == 0)
20768 target_flags |= MASK_FIX_R10000;
20770 /* Make sure that branch-likely instructions available when using
20771 -mfix-r10000. The instructions are not available if either:
20773 1. -mno-branch-likely was passed.
20774 2. The selected ISA does not support branch-likely and
20775 the command line does not include -mbranch-likely. */
20776 if (TARGET_FIX_R10000
20777 && ((target_flags_explicit & MASK_BRANCHLIKELY) == 0
20778 ? !ISA_HAS_BRANCHLIKELY
20779 : !TARGET_BRANCHLIKELY))
20780 sorry ("%qs requires branch-likely instructions", "-mfix-r10000");
20782 if (TARGET_SYNCI && !ISA_HAS_SYNCI)
20784 warning (0, "the %qs architecture does not support the synci "
20785 "instruction", mips_arch_info->name);
20786 target_flags &= ~MASK_SYNCI;
20789 /* Only optimize PIC indirect calls if they are actually required. */
20790 if (!TARGET_USE_GOT || !TARGET_EXPLICIT_RELOCS)
20791 target_flags &= ~MASK_RELAX_PIC_CALLS;
20793 /* Save base state of options. */
20794 mips_base_target_flags = target_flags;
20795 mips_base_schedule_insns = flag_schedule_insns;
20796 mips_base_reorder_blocks_and_partition = flag_reorder_blocks_and_partition;
20797 mips_base_move_loop_invariants = flag_move_loop_invariants;
20798 mips_base_align_loops = str_align_loops;
20799 mips_base_align_jumps = str_align_jumps;
20800 mips_base_align_functions = str_align_functions;
20802 /* Now select the ISA mode.
20804 Do all CPP-sensitive stuff in uncompressed mode; we'll switch modes
20805 later if required. */
20806 mips_set_compression_mode (0);
20808 /* We register a second machine specific reorg pass after delay slot
20809 filling. Registering the pass must be done at start up. It's
20810 convenient to do it here. */
20811 opt_pass *new_pass = make_pass_mips_machine_reorg2 (g);
20812 struct register_pass_info insert_pass_mips_machine_reorg2 =
20814 new_pass, /* pass */
20815 "dbr", /* reference_pass_name */
20816 1, /* ref_pass_instance_number */
20817 PASS_POS_INSERT_AFTER /* po_op */
20819 register_pass (&insert_pass_mips_machine_reorg2);
20821 if (TARGET_HARD_FLOAT_ABI && TARGET_MIPS5900)
20822 REAL_MODE_FORMAT (SFmode) = &spu_single_format;
20824 mips_register_frame_header_opt ();
20827 /* Swap the register information for registers I and I + 1, which
20828 currently have the wrong endianness. Note that the registers'
20829 fixedness and call-clobberedness might have been set on the
20830 command line. */
20832 static void
20833 mips_swap_registers (unsigned int i)
20835 int tmpi;
20836 const char *tmps;
20838 #define SWAP_INT(X, Y) (tmpi = (X), (X) = (Y), (Y) = tmpi)
20839 #define SWAP_STRING(X, Y) (tmps = (X), (X) = (Y), (Y) = tmps)
20841 SWAP_INT (fixed_regs[i], fixed_regs[i + 1]);
20842 SWAP_INT (call_used_regs[i], call_used_regs[i + 1]);
20843 SWAP_STRING (reg_names[i], reg_names[i + 1]);
20845 #undef SWAP_STRING
20846 #undef SWAP_INT
20849 /* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */
20851 static void
20852 mips_conditional_register_usage (void)
20855 if (ISA_HAS_DSP)
20857 /* These DSP control register fields are global. */
20858 global_regs[CCDSP_PO_REGNUM] = 1;
20859 global_regs[CCDSP_SC_REGNUM] = 1;
20861 else
20862 accessible_reg_set &= ~reg_class_contents[DSP_ACC_REGS];
20864 if (!ISA_HAS_HILO)
20865 accessible_reg_set &= ~reg_class_contents[MD_REGS];
20867 if (!TARGET_HARD_FLOAT)
20868 accessible_reg_set &= ~(reg_class_contents[FP_REGS]
20869 | reg_class_contents[ST_REGS]);
20870 else if (!ISA_HAS_8CC)
20872 /* We only have a single condition-code register. We implement
20873 this by fixing all the condition-code registers and generating
20874 RTL that refers directly to ST_REG_FIRST. */
20875 accessible_reg_set &= ~reg_class_contents[ST_REGS];
20876 if (!ISA_HAS_CCF)
20877 SET_HARD_REG_BIT (accessible_reg_set, FPSW_REGNUM);
20878 fixed_regs[FPSW_REGNUM] = 1;
20880 if (TARGET_MIPS16)
20882 /* In MIPS16 mode, we prohibit the unused $s registers, since they
20883 are call-saved, and saving them via a MIPS16 register would
20884 probably waste more time than just reloading the value.
20886 We permit the $t temporary registers when optimizing for speed
20887 but not when optimizing for space because using them results in
20888 code that is larger (but faster) then not using them. We do
20889 allow $24 (t8) because it is used in CMP and CMPI instructions
20890 and $25 (t9) because it is used as the function call address in
20891 SVR4 PIC code. */
20893 fixed_regs[18] = 1;
20894 fixed_regs[19] = 1;
20895 fixed_regs[20] = 1;
20896 fixed_regs[21] = 1;
20897 fixed_regs[22] = 1;
20898 fixed_regs[23] = 1;
20899 fixed_regs[26] = 1;
20900 fixed_regs[27] = 1;
20901 fixed_regs[30] = 1;
20902 if (optimize_size)
20904 fixed_regs[8] = 1;
20905 fixed_regs[9] = 1;
20906 fixed_regs[10] = 1;
20907 fixed_regs[11] = 1;
20908 fixed_regs[12] = 1;
20909 fixed_regs[13] = 1;
20910 fixed_regs[14] = 1;
20911 fixed_regs[15] = 1;
20914 /* Do not allow HI and LO to be treated as register operands.
20915 There are no MTHI or MTLO instructions (or any real need
20916 for them) and one-way registers cannot easily be reloaded. */
20917 operand_reg_set &= ~reg_class_contents[MD_REGS];
20919 /* $f20-$f23 are call-clobbered for n64. */
20920 if (mips_abi == ABI_64)
20922 int regno;
20923 for (regno = FP_REG_FIRST + 20; regno < FP_REG_FIRST + 24; regno++)
20924 call_used_regs[regno] = 1;
20926 /* Odd registers in the range $f21-$f31 (inclusive) are call-clobbered
20927 for n32 and o32 FP64. */
20928 if (mips_abi == ABI_N32
20929 || (mips_abi == ABI_32
20930 && TARGET_FLOAT64))
20932 int regno;
20933 for (regno = FP_REG_FIRST + 21; regno <= FP_REG_FIRST + 31; regno+=2)
20934 call_used_regs[regno] = 1;
20936 /* Make sure that double-register accumulator values are correctly
20937 ordered for the current endianness. */
20938 if (TARGET_LITTLE_ENDIAN)
20940 unsigned int regno;
20942 mips_swap_registers (MD_REG_FIRST);
20943 for (regno = DSP_ACC_REG_FIRST; regno <= DSP_ACC_REG_LAST; regno += 2)
20944 mips_swap_registers (regno);
20948 /* Implement EH_USES. */
20950 bool
20951 mips_eh_uses (unsigned int regno)
20953 if (reload_completed && !TARGET_ABSOLUTE_JUMPS)
20955 /* We need to force certain registers to be live in order to handle
20956 PIC long branches correctly. See mips_must_initialize_gp_p for
20957 details. */
20958 if (mips_cfun_has_cprestore_slot_p ())
20960 if (regno == CPRESTORE_SLOT_REGNUM)
20961 return true;
20963 else
20965 if (cfun->machine->global_pointer == regno)
20966 return true;
20970 return false;
20973 /* Implement EPILOGUE_USES. */
20975 bool
20976 mips_epilogue_uses (unsigned int regno)
20978 /* Say that the epilogue uses the return address register. Note that
20979 in the case of sibcalls, the values "used by the epilogue" are
20980 considered live at the start of the called function. */
20981 if (regno == RETURN_ADDR_REGNUM)
20982 return true;
20984 /* If using a GOT, say that the epilogue also uses GOT_VERSION_REGNUM.
20985 See the comment above load_call<mode> for details. */
20986 if (TARGET_USE_GOT && (regno) == GOT_VERSION_REGNUM)
20987 return true;
20989 /* An interrupt handler must preserve some registers that are
20990 ordinarily call-clobbered. */
20991 if (cfun->machine->interrupt_handler_p
20992 && mips_interrupt_extra_call_saved_reg_p (regno))
20993 return true;
20995 return false;
20998 /* Return true if INSN needs to be wrapped in ".set noat".
20999 INSN has NOPERANDS operands, stored in OPVEC. */
21001 static bool
21002 mips_need_noat_wrapper_p (rtx_insn *insn, rtx *opvec, int noperands)
21004 if (recog_memoized (insn) >= 0)
21006 subrtx_iterator::array_type array;
21007 for (int i = 0; i < noperands; i++)
21008 FOR_EACH_SUBRTX (iter, array, opvec[i], NONCONST)
21009 if (REG_P (*iter) && REGNO (*iter) == AT_REGNUM)
21010 return true;
21012 return false;
21015 /* Implement FINAL_PRESCAN_INSN. Mark MIPS16 inline constant pools
21016 as data for the purpose of disassembly. For simplicity embed the
21017 pool's initial label number in the local symbol produced so that
21018 multiple pools within a single function end up marked with unique
21019 symbols. The label number is carried by the `consttable' insn
21020 emitted at the beginning of each pool. */
21022 void
21023 mips_final_prescan_insn (rtx_insn *insn, rtx *opvec, int noperands)
21025 if (INSN_P (insn)
21026 && GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
21027 && XINT (PATTERN (insn), 1) == UNSPEC_CONSTTABLE)
21028 mips_set_text_contents_type (asm_out_file, "__pool_",
21029 INTVAL (XVECEXP (PATTERN (insn), 0, 0)),
21030 FALSE);
21032 if (mips_need_noat_wrapper_p (insn, opvec, noperands))
21033 mips_push_asm_switch (&mips_noat);
21036 /* Implement TARGET_ASM_FINAL_POSTSCAN_INSN. Reset text marking to
21037 code after a MIPS16 inline constant pool. Like with the beginning
21038 of a pool table use the pool's initial label number to keep symbols
21039 unique. The label number is carried by the `consttable_end' insn
21040 emitted at the end of each pool. */
21042 static void
21043 mips_final_postscan_insn (FILE *file ATTRIBUTE_UNUSED, rtx_insn *insn,
21044 rtx *opvec, int noperands)
21046 if (mips_need_noat_wrapper_p (insn, opvec, noperands))
21047 mips_pop_asm_switch (&mips_noat);
21049 if (INSN_P (insn)
21050 && GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
21051 && XINT (PATTERN (insn), 1) == UNSPEC_CONSTTABLE_END)
21053 rtx_insn *next_insn = next_real_nondebug_insn (insn);
21054 bool code_p = (next_insn != NULL
21055 && INSN_P (next_insn)
21056 && (GET_CODE (PATTERN (next_insn)) != UNSPEC_VOLATILE
21057 || XINT (PATTERN (next_insn), 1) != UNSPEC_CONSTTABLE));
21059 /* Switch content type depending on whether there is code beyond
21060 the constant pool. */
21061 mips_set_text_contents_type (asm_out_file, "__pend_",
21062 INTVAL (XVECEXP (PATTERN (insn), 0, 0)),
21063 code_p);
21067 /* Return the function that is used to expand the <u>mulsidi3 pattern.
21068 EXT_CODE is the code of the extension used. Return NULL if widening
21069 multiplication shouldn't be used. */
21071 mulsidi3_gen_fn
21072 mips_mulsidi3_gen_fn (enum rtx_code ext_code)
21074 bool signed_p;
21076 signed_p = ext_code == SIGN_EXTEND;
21077 if (TARGET_64BIT)
21079 /* Don't use widening multiplication with MULT when we have DMUL. Even
21080 with the extension of its input operands DMUL is faster. Note that
21081 the extension is not needed for signed multiplication. In order to
21082 ensure that we always remove the redundant sign-extension in this
21083 case we still expand mulsidi3 for DMUL. */
21084 if (ISA_HAS_R6DMUL)
21085 return signed_p ? gen_mulsidi3_64bit_r6dmul : NULL;
21086 if (ISA_HAS_DMUL3)
21087 return signed_p ? gen_mulsidi3_64bit_dmul : NULL;
21088 if (TARGET_MIPS16)
21089 return (signed_p
21090 ? gen_mulsidi3_64bit_mips16
21091 : gen_umulsidi3_64bit_mips16);
21092 if (TARGET_FIX_R4000)
21093 return NULL;
21094 return signed_p ? gen_mulsidi3_64bit : gen_umulsidi3_64bit;
21096 else
21098 if (ISA_HAS_R6MUL)
21099 return (signed_p ? gen_mulsidi3_32bit_r6 : gen_umulsidi3_32bit_r6);
21100 if (TARGET_MIPS16)
21101 return (signed_p
21102 ? gen_mulsidi3_32bit_mips16
21103 : gen_umulsidi3_32bit_mips16);
21104 if (TARGET_FIX_R4000 && !ISA_HAS_DSP)
21105 return signed_p ? gen_mulsidi3_32bit_r4000 : gen_umulsidi3_32bit_r4000;
21106 return signed_p ? gen_mulsidi3_32bit : gen_umulsidi3_32bit;
21110 /* Return true if PATTERN matches the kind of instruction generated by
21111 umips_build_save_restore. SAVE_P is true for store. */
21113 bool
21114 umips_save_restore_pattern_p (bool save_p, rtx pattern)
21116 int n;
21117 unsigned int i;
21118 HOST_WIDE_INT first_offset = 0;
21119 rtx first_base = 0;
21120 unsigned int regmask = 0;
21122 for (n = 0; n < XVECLEN (pattern, 0); n++)
21124 rtx set, reg, mem, this_base;
21125 HOST_WIDE_INT this_offset;
21127 /* Check that we have a SET. */
21128 set = XVECEXP (pattern, 0, n);
21129 if (GET_CODE (set) != SET)
21130 return false;
21132 /* Check that the SET is a load (if restoring) or a store
21133 (if saving). */
21134 mem = save_p ? SET_DEST (set) : SET_SRC (set);
21135 if (!MEM_P (mem) || MEM_VOLATILE_P (mem))
21136 return false;
21138 /* Check that the address is the sum of base and a possibly-zero
21139 constant offset. Determine if the offset is in range. */
21140 mips_split_plus (XEXP (mem, 0), &this_base, &this_offset);
21141 if (!REG_P (this_base))
21142 return false;
21144 if (n == 0)
21146 if (!UMIPS_12BIT_OFFSET_P (this_offset))
21147 return false;
21148 first_base = this_base;
21149 first_offset = this_offset;
21151 else
21153 /* Check that the save slots are consecutive. */
21154 if (REGNO (this_base) != REGNO (first_base)
21155 || this_offset != first_offset + UNITS_PER_WORD * n)
21156 return false;
21159 /* Check that SET's other operand is a register. */
21160 reg = save_p ? SET_SRC (set) : SET_DEST (set);
21161 if (!REG_P (reg))
21162 return false;
21164 regmask |= 1 << REGNO (reg);
21167 for (i = 0; i < ARRAY_SIZE (umips_swm_mask); i++)
21168 if (regmask == umips_swm_mask[i])
21169 return true;
21171 return false;
21174 /* Return the assembly instruction for microMIPS LWM or SWM.
21175 SAVE_P and PATTERN are as for umips_save_restore_pattern_p. */
21177 const char *
21178 umips_output_save_restore (bool save_p, rtx pattern)
21180 static char buffer[300];
21181 char *s;
21182 int n;
21183 HOST_WIDE_INT offset;
21184 rtx base, mem, set, last_set, last_reg;
21186 /* Parse the pattern. */
21187 gcc_assert (umips_save_restore_pattern_p (save_p, pattern));
21189 s = strcpy (buffer, save_p ? "swm\t" : "lwm\t");
21190 s += strlen (s);
21191 n = XVECLEN (pattern, 0);
21193 set = XVECEXP (pattern, 0, 0);
21194 mem = save_p ? SET_DEST (set) : SET_SRC (set);
21195 mips_split_plus (XEXP (mem, 0), &base, &offset);
21197 last_set = XVECEXP (pattern, 0, n - 1);
21198 last_reg = save_p ? SET_SRC (last_set) : SET_DEST (last_set);
21200 if (REGNO (last_reg) == 31)
21201 n--;
21203 gcc_assert (n <= 9);
21204 if (n == 0)
21206 else if (n == 1)
21207 s += sprintf (s, "%s,", reg_names[16]);
21208 else if (n < 9)
21209 s += sprintf (s, "%s-%s,", reg_names[16], reg_names[15 + n]);
21210 else if (n == 9)
21211 s += sprintf (s, "%s-%s,%s,", reg_names[16], reg_names[23],
21212 reg_names[30]);
21214 if (REGNO (last_reg) == 31)
21215 s += sprintf (s, "%s,", reg_names[31]);
21217 s += sprintf (s, "%d(%s)", (int)offset, reg_names[REGNO (base)]);
21218 return buffer;
21221 /* Return true if MEM1 and MEM2 use the same base register, and the
21222 offset of MEM2 equals the offset of MEM1 plus 4. FIRST_REG is the
21223 register into (from) which the contents of MEM1 will be loaded
21224 (stored), depending on the value of LOAD_P.
21225 SWAP_P is true when the 1st and 2nd instructions are swapped. */
21227 static bool
21228 umips_load_store_pair_p_1 (bool load_p, bool swap_p,
21229 rtx first_reg, rtx mem1, rtx mem2)
21231 rtx base1, base2;
21232 HOST_WIDE_INT offset1, offset2;
21234 if (!MEM_P (mem1) || !MEM_P (mem2))
21235 return false;
21237 mips_split_plus (XEXP (mem1, 0), &base1, &offset1);
21238 mips_split_plus (XEXP (mem2, 0), &base2, &offset2);
21240 if (!REG_P (base1) || !rtx_equal_p (base1, base2))
21241 return false;
21243 /* Avoid invalid load pair instructions. */
21244 if (load_p && REGNO (first_reg) == REGNO (base1))
21245 return false;
21247 /* We must avoid this case for anti-dependence.
21248 Ex: lw $3, 4($3)
21249 lw $2, 0($3)
21250 first_reg is $2, but the base is $3. */
21251 if (load_p
21252 && swap_p
21253 && REGNO (first_reg) + 1 == REGNO (base1))
21254 return false;
21256 if (offset2 != offset1 + 4)
21257 return false;
21259 if (!UMIPS_12BIT_OFFSET_P (offset1))
21260 return false;
21262 return true;
21265 bool
21266 mips_load_store_bonding_p (rtx *operands, machine_mode mode, bool load_p)
21268 rtx reg1, reg2, mem1, mem2, base1, base2;
21269 enum reg_class rc1, rc2;
21270 HOST_WIDE_INT offset1, offset2;
21272 if (load_p)
21274 reg1 = operands[0];
21275 reg2 = operands[2];
21276 mem1 = operands[1];
21277 mem2 = operands[3];
21279 else
21281 reg1 = operands[1];
21282 reg2 = operands[3];
21283 mem1 = operands[0];
21284 mem2 = operands[2];
21287 if (mips_address_insns (XEXP (mem1, 0), mode, false) == 0
21288 || mips_address_insns (XEXP (mem2, 0), mode, false) == 0)
21289 return false;
21291 mips_split_plus (XEXP (mem1, 0), &base1, &offset1);
21292 mips_split_plus (XEXP (mem2, 0), &base2, &offset2);
21294 /* Base regs do not match. */
21295 if (!REG_P (base1) || !rtx_equal_p (base1, base2))
21296 return false;
21298 /* Either of the loads is clobbering base register. It is legitimate to bond
21299 loads if second load clobbers base register. However, hardware does not
21300 support such bonding. */
21301 if (load_p
21302 && (REGNO (reg1) == REGNO (base1)
21303 || (REGNO (reg2) == REGNO (base1))))
21304 return false;
21306 /* Loading in same registers. */
21307 if (load_p
21308 && REGNO (reg1) == REGNO (reg2))
21309 return false;
21311 /* The loads/stores are not of same type. */
21312 rc1 = REGNO_REG_CLASS (REGNO (reg1));
21313 rc2 = REGNO_REG_CLASS (REGNO (reg2));
21314 if (rc1 != rc2
21315 && !reg_class_subset_p (rc1, rc2)
21316 && !reg_class_subset_p (rc2, rc1))
21317 return false;
21319 if (abs (offset1 - offset2) != GET_MODE_SIZE (mode))
21320 return false;
21322 return true;
21325 /* OPERANDS describes the operands to a pair of SETs, in the order
21326 dest1, src1, dest2, src2. Return true if the operands can be used
21327 in an LWP or SWP instruction; LOAD_P says which. */
21329 bool
21330 umips_load_store_pair_p (bool load_p, rtx *operands)
21332 rtx reg1, reg2, mem1, mem2;
21334 if (load_p)
21336 reg1 = operands[0];
21337 reg2 = operands[2];
21338 mem1 = operands[1];
21339 mem2 = operands[3];
21341 else
21343 reg1 = operands[1];
21344 reg2 = operands[3];
21345 mem1 = operands[0];
21346 mem2 = operands[2];
21349 if (REGNO (reg2) == REGNO (reg1) + 1)
21350 return umips_load_store_pair_p_1 (load_p, false, reg1, mem1, mem2);
21352 if (REGNO (reg1) == REGNO (reg2) + 1)
21353 return umips_load_store_pair_p_1 (load_p, true, reg2, mem2, mem1);
21355 return false;
21358 /* Return the assembly instruction for a microMIPS LWP or SWP in which
21359 the first register is REG and the first memory slot is MEM.
21360 LOAD_P is true for LWP. */
21362 static void
21363 umips_output_load_store_pair_1 (bool load_p, rtx reg, rtx mem)
21365 rtx ops[] = {reg, mem};
21367 if (load_p)
21368 output_asm_insn ("lwp\t%0,%1", ops);
21369 else
21370 output_asm_insn ("swp\t%0,%1", ops);
21373 /* Output the assembly instruction for a microMIPS LWP or SWP instruction.
21374 LOAD_P and OPERANDS are as for umips_load_store_pair_p. */
21376 void
21377 umips_output_load_store_pair (bool load_p, rtx *operands)
21379 rtx reg1, reg2, mem1, mem2;
21380 if (load_p)
21382 reg1 = operands[0];
21383 reg2 = operands[2];
21384 mem1 = operands[1];
21385 mem2 = operands[3];
21387 else
21389 reg1 = operands[1];
21390 reg2 = operands[3];
21391 mem1 = operands[0];
21392 mem2 = operands[2];
21395 if (REGNO (reg2) == REGNO (reg1) + 1)
21397 umips_output_load_store_pair_1 (load_p, reg1, mem1);
21398 return;
21401 gcc_assert (REGNO (reg1) == REGNO (reg2) + 1);
21402 umips_output_load_store_pair_1 (load_p, reg2, mem2);
21405 /* Return true if REG1 and REG2 match the criteria for a movep insn. */
21407 bool
21408 umips_movep_target_p (rtx reg1, rtx reg2)
21410 int regno1, regno2, pair;
21411 unsigned int i;
21412 static const int match[8] = {
21413 0x00000060, /* 5, 6 */
21414 0x000000a0, /* 5, 7 */
21415 0x000000c0, /* 6, 7 */
21416 0x00200010, /* 4, 21 */
21417 0x00400010, /* 4, 22 */
21418 0x00000030, /* 4, 5 */
21419 0x00000050, /* 4, 6 */
21420 0x00000090 /* 4, 7 */
21423 if (!REG_P (reg1) || !REG_P (reg2))
21424 return false;
21426 regno1 = REGNO (reg1);
21427 regno2 = REGNO (reg2);
21429 if (!GP_REG_P (regno1) || !GP_REG_P (regno2))
21430 return false;
21432 pair = (1 << regno1) | (1 << regno2);
21434 for (i = 0; i < ARRAY_SIZE (match); i++)
21435 if (pair == match[i])
21436 return true;
21438 return false;
21441 /* Return the size in bytes of the trampoline code, padded to
21442 TRAMPOLINE_ALIGNMENT bits. The static chain pointer and target
21443 function address immediately follow. */
21446 mips_trampoline_code_size (void)
21448 if (TARGET_USE_PIC_FN_ADDR_REG)
21449 return 4 * 4;
21450 else if (ptr_mode == DImode)
21451 return 8 * 4;
21452 else if (ISA_HAS_LOAD_DELAY)
21453 return 6 * 4;
21454 else
21455 return 4 * 4;
21458 /* Implement TARGET_TRAMPOLINE_INIT. */
21460 static void
21461 mips_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
21463 rtx addr, end_addr, high, low, opcode, mem;
21464 rtx trampoline[8];
21465 unsigned int i, j;
21466 HOST_WIDE_INT end_addr_offset, static_chain_offset, target_function_offset;
21468 /* Work out the offsets of the pointers from the start of the
21469 trampoline code. */
21470 end_addr_offset = mips_trampoline_code_size ();
21471 static_chain_offset = end_addr_offset;
21472 target_function_offset = static_chain_offset + GET_MODE_SIZE (ptr_mode);
21474 /* Get pointers to the beginning and end of the code block. */
21475 addr = force_reg (Pmode, XEXP (m_tramp, 0));
21476 end_addr = mips_force_binary (Pmode, PLUS, addr, GEN_INT (end_addr_offset));
21478 #define OP(X) gen_int_mode (X, SImode)
21480 /* Build up the code in TRAMPOLINE. */
21481 i = 0;
21482 if (TARGET_USE_PIC_FN_ADDR_REG)
21484 /* $25 contains the address of the trampoline. Emit code of the form:
21486 l[wd] $1, target_function_offset($25)
21487 l[wd] $static_chain, static_chain_offset($25)
21488 jr $1
21489 move $25,$1. */
21490 trampoline[i++] = OP (MIPS_LOAD_PTR (AT_REGNUM,
21491 target_function_offset,
21492 PIC_FUNCTION_ADDR_REGNUM));
21493 trampoline[i++] = OP (MIPS_LOAD_PTR (STATIC_CHAIN_REGNUM,
21494 static_chain_offset,
21495 PIC_FUNCTION_ADDR_REGNUM));
21496 trampoline[i++] = OP (MIPS_JR (AT_REGNUM));
21497 trampoline[i++] = OP (MIPS_MOVE (PIC_FUNCTION_ADDR_REGNUM, AT_REGNUM));
21499 else if (ptr_mode == DImode)
21501 /* It's too cumbersome to create the full 64-bit address, so let's
21502 instead use:
21504 move $1, $31
21505 bal 1f
21507 1: l[wd] $25, target_function_offset - 12($31)
21508 l[wd] $static_chain, static_chain_offset - 12($31)
21509 jr $25
21510 move $31, $1
21512 where 12 is the offset of "1:" from the start of the code block. */
21513 trampoline[i++] = OP (MIPS_MOVE (AT_REGNUM, RETURN_ADDR_REGNUM));
21514 trampoline[i++] = OP (MIPS_BAL (1));
21515 trampoline[i++] = OP (MIPS_NOP);
21516 trampoline[i++] = OP (MIPS_LOAD_PTR (PIC_FUNCTION_ADDR_REGNUM,
21517 target_function_offset - 12,
21518 RETURN_ADDR_REGNUM));
21519 trampoline[i++] = OP (MIPS_LOAD_PTR (STATIC_CHAIN_REGNUM,
21520 static_chain_offset - 12,
21521 RETURN_ADDR_REGNUM));
21522 trampoline[i++] = OP (MIPS_JR (PIC_FUNCTION_ADDR_REGNUM));
21523 trampoline[i++] = OP (MIPS_MOVE (RETURN_ADDR_REGNUM, AT_REGNUM));
21525 else
21527 /* If the target has load delays, emit:
21529 lui $1, %hi(end_addr)
21530 lw $25, %lo(end_addr + ...)($1)
21531 lw $static_chain, %lo(end_addr + ...)($1)
21532 jr $25
21535 Otherwise emit:
21537 lui $1, %hi(end_addr)
21538 lw $25, %lo(end_addr + ...)($1)
21539 jr $25
21540 lw $static_chain, %lo(end_addr + ...)($1). */
21542 /* Split END_ADDR into %hi and %lo values. Trampolines are aligned
21543 to 64 bits, so the %lo value will have the bottom 3 bits clear. */
21544 high = expand_simple_binop (SImode, PLUS, end_addr, GEN_INT (0x8000),
21545 NULL, false, OPTAB_WIDEN);
21546 high = expand_simple_binop (SImode, LSHIFTRT, high, GEN_INT (16),
21547 NULL, false, OPTAB_WIDEN);
21548 low = convert_to_mode (SImode, gen_lowpart (HImode, end_addr), true);
21550 /* Emit the LUI. */
21551 opcode = OP (MIPS_LUI (AT_REGNUM, 0));
21552 trampoline[i++] = expand_simple_binop (SImode, IOR, opcode, high,
21553 NULL, false, OPTAB_WIDEN);
21555 /* Emit the load of the target function. */
21556 opcode = OP (MIPS_LOAD_PTR (PIC_FUNCTION_ADDR_REGNUM,
21557 target_function_offset - end_addr_offset,
21558 AT_REGNUM));
21559 trampoline[i++] = expand_simple_binop (SImode, IOR, opcode, low,
21560 NULL, false, OPTAB_WIDEN);
21562 /* Emit the JR here, if we can. */
21563 if (!ISA_HAS_LOAD_DELAY)
21564 trampoline[i++] = OP (MIPS_JR (PIC_FUNCTION_ADDR_REGNUM));
21566 /* Emit the load of the static chain register. */
21567 opcode = OP (MIPS_LOAD_PTR (STATIC_CHAIN_REGNUM,
21568 static_chain_offset - end_addr_offset,
21569 AT_REGNUM));
21570 trampoline[i++] = expand_simple_binop (SImode, IOR, opcode, low,
21571 NULL, false, OPTAB_WIDEN);
21573 /* Emit the JR, if we couldn't above. */
21574 if (ISA_HAS_LOAD_DELAY)
21576 trampoline[i++] = OP (MIPS_JR (PIC_FUNCTION_ADDR_REGNUM));
21577 trampoline[i++] = OP (MIPS_NOP);
21581 #undef OP
21583 /* If we are using compact branches we don't have delay slots so
21584 place the instruction that was in the delay slot before the JRC
21585 instruction. */
21587 if (TARGET_CB_ALWAYS)
21589 rtx temp;
21590 temp = trampoline[i-2];
21591 trampoline[i-2] = trampoline[i-1];
21592 trampoline[i-1] = temp;
21595 /* Copy the trampoline code. Leave any padding uninitialized. */
21596 for (j = 0; j < i; j++)
21598 mem = adjust_address (m_tramp, SImode, j * GET_MODE_SIZE (SImode));
21599 mips_emit_move (mem, trampoline[j]);
21602 /* Set up the static chain pointer field. */
21603 mem = adjust_address (m_tramp, ptr_mode, static_chain_offset);
21604 mips_emit_move (mem, chain_value);
21606 /* Set up the target function field. */
21607 mem = adjust_address (m_tramp, ptr_mode, target_function_offset);
21608 mips_emit_move (mem, XEXP (DECL_RTL (fndecl), 0));
21610 /* Flush the code part of the trampoline. */
21611 emit_insn (gen_add3_insn (end_addr, addr, GEN_INT (TRAMPOLINE_SIZE)));
21612 emit_insn (gen_clear_cache (addr, end_addr));
21615 /* Implement FUNCTION_PROFILER. */
21617 void mips_function_profiler (FILE *file)
21619 if (TARGET_MIPS16)
21620 sorry ("mips16 function profiling");
21621 if (TARGET_LONG_CALLS)
21623 /* For TARGET_LONG_CALLS use $3 for the address of _mcount. */
21624 if (Pmode == DImode)
21625 fprintf (file, "\tdla\t%s,_mcount\n", reg_names[3]);
21626 else
21627 fprintf (file, "\tla\t%s,_mcount\n", reg_names[3]);
21629 mips_push_asm_switch (&mips_noat);
21630 fprintf (file, "\tmove\t%s,%s\t\t# save current return address\n",
21631 reg_names[AT_REGNUM], reg_names[RETURN_ADDR_REGNUM]);
21632 /* _mcount treats $2 as the static chain register. */
21633 if (cfun->static_chain_decl != NULL)
21634 fprintf (file, "\tmove\t%s,%s\n", reg_names[2],
21635 reg_names[STATIC_CHAIN_REGNUM]);
21636 if (TARGET_MCOUNT_RA_ADDRESS)
21638 /* If TARGET_MCOUNT_RA_ADDRESS load $12 with the address of the
21639 ra save location. */
21640 if (cfun->machine->frame.ra_fp_offset == 0)
21641 /* ra not saved, pass zero. */
21642 fprintf (file, "\tmove\t%s,%s\n", reg_names[12], reg_names[0]);
21643 else
21644 fprintf (file, "\t%s\t%s," HOST_WIDE_INT_PRINT_DEC "(%s)\n",
21645 Pmode == DImode ? "dla" : "la", reg_names[12],
21646 cfun->machine->frame.ra_fp_offset,
21647 reg_names[STACK_POINTER_REGNUM]);
21649 if (!TARGET_NEWABI)
21650 fprintf (file,
21651 "\t%s\t%s,%s,%d\t\t# _mcount pops 2 words from stack\n",
21652 TARGET_64BIT ? "dsubu" : "subu",
21653 reg_names[STACK_POINTER_REGNUM],
21654 reg_names[STACK_POINTER_REGNUM],
21655 Pmode == DImode ? 16 : 8);
21657 if (TARGET_LONG_CALLS)
21658 fprintf (file, "\tjalr\t%s\n", reg_names[3]);
21659 else
21660 fprintf (file, "\tjal\t_mcount\n");
21661 mips_pop_asm_switch (&mips_noat);
21662 /* _mcount treats $2 as the static chain register. */
21663 if (cfun->static_chain_decl != NULL)
21664 fprintf (file, "\tmove\t%s,%s\n", reg_names[STATIC_CHAIN_REGNUM],
21665 reg_names[2]);
21668 /* Implement TARGET_SHIFT_TRUNCATION_MASK. We want to keep the default
21669 behavior of TARGET_SHIFT_TRUNCATION_MASK for non-vector modes even
21670 when TARGET_LOONGSON_MMI is true. */
21672 static unsigned HOST_WIDE_INT
21673 mips_shift_truncation_mask (machine_mode mode)
21675 if (TARGET_LOONGSON_MMI && VECTOR_MODE_P (mode))
21676 return 0;
21678 return GET_MODE_BITSIZE (mode) - 1;
21681 /* Implement TARGET_PREPARE_PCH_SAVE. */
21683 static void
21684 mips_prepare_pch_save (void)
21686 /* We are called in a context where the current compression vs.
21687 non-compression setting should be irrelevant. The question then is:
21688 which setting makes most sense at load time?
21690 The PCH is loaded before the first token is read. We should never have
21691 switched into a compression mode by that point, and thus should not have
21692 populated mips16_globals or micromips_globals. Nor can we load the
21693 entire contents of mips16_globals or micromips_globals from the PCH file,
21694 because they contain a combination of GGC and non-GGC data.
21696 There is therefore no point in trying save the GGC part of
21697 mips16_globals/micromips_globals to the PCH file, or to preserve a
21698 compression setting across the PCH save and load. The loading compiler
21699 would not have access to the non-GGC parts of mips16_globals or
21700 micromips_globals (either from the PCH file, or from a copy that the
21701 loading compiler generated itself) and would have to call target_reinit
21702 anyway.
21704 It therefore seems best to switch back to non-MIPS16 mode and
21705 non-microMIPS mode to save time, and to ensure that mips16_globals and
21706 micromips_globals remain null after a PCH load. */
21707 mips_set_compression_mode (0);
21708 mips16_globals = 0;
21709 micromips_globals = 0;
21712 /* Generate or test for an insn that supports a constant permutation. */
21714 #define MAX_VECT_LEN 16
21716 struct expand_vec_perm_d
21718 rtx target, op0, op1;
21719 unsigned char perm[MAX_VECT_LEN];
21720 machine_mode vmode;
21721 unsigned char nelt;
21722 bool one_vector_p;
21723 bool testing_p;
21726 /* Construct (set target (vec_select op0 (parallel perm))) and
21727 return true if that's a valid instruction in the active ISA. */
21729 static bool
21730 mips_expand_vselect (rtx target, rtx op0,
21731 const unsigned char *perm, unsigned nelt)
21733 rtx rperm[MAX_VECT_LEN], x;
21734 rtx_insn *insn;
21735 unsigned i;
21737 for (i = 0; i < nelt; ++i)
21738 rperm[i] = GEN_INT (perm[i]);
21740 x = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelt, rperm));
21741 x = gen_rtx_VEC_SELECT (GET_MODE (target), op0, x);
21742 x = gen_rtx_SET (target, x);
21744 insn = emit_insn (x);
21745 if (recog_memoized (insn) < 0)
21747 remove_insn (insn);
21748 return false;
21750 return true;
21753 /* Similar, but generate a vec_concat from op0 and op1 as well. */
21755 static bool
21756 mips_expand_vselect_vconcat (rtx target, rtx op0, rtx op1,
21757 const unsigned char *perm, unsigned nelt)
21759 machine_mode v2mode;
21760 rtx x;
21762 if (!GET_MODE_2XWIDER_MODE (GET_MODE (op0)).exists (&v2mode))
21763 return false;
21764 x = gen_rtx_VEC_CONCAT (v2mode, op0, op1);
21765 return mips_expand_vselect (target, x, perm, nelt);
21768 /* Recognize patterns for even-odd extraction. */
21770 static bool
21771 mips_expand_vpc_loongson_even_odd (struct expand_vec_perm_d *d)
21773 unsigned i, odd, nelt = d->nelt;
21774 rtx t0, t1, t2, t3;
21776 if (!(TARGET_HARD_FLOAT && TARGET_LOONGSON_MMI))
21777 return false;
21778 /* Even-odd for V2SI/V2SFmode is matched by interleave directly. */
21779 if (nelt < 4)
21780 return false;
21782 odd = d->perm[0];
21783 if (odd > 1)
21784 return false;
21785 for (i = 1; i < nelt; ++i)
21786 if (d->perm[i] != i * 2 + odd)
21787 return false;
21789 if (d->testing_p)
21790 return true;
21792 /* We need 2*log2(N)-1 operations to achieve odd/even with interleave. */
21793 t0 = gen_reg_rtx (d->vmode);
21794 t1 = gen_reg_rtx (d->vmode);
21795 switch (d->vmode)
21797 case E_V4HImode:
21798 emit_insn (gen_loongson_punpckhhw (t0, d->op0, d->op1));
21799 emit_insn (gen_loongson_punpcklhw (t1, d->op0, d->op1));
21800 if (odd)
21801 emit_insn (gen_loongson_punpckhhw (d->target, t1, t0));
21802 else
21803 emit_insn (gen_loongson_punpcklhw (d->target, t1, t0));
21804 break;
21806 case E_V8QImode:
21807 t2 = gen_reg_rtx (d->vmode);
21808 t3 = gen_reg_rtx (d->vmode);
21809 emit_insn (gen_loongson_punpckhbh (t0, d->op0, d->op1));
21810 emit_insn (gen_loongson_punpcklbh (t1, d->op0, d->op1));
21811 emit_insn (gen_loongson_punpckhbh (t2, t1, t0));
21812 emit_insn (gen_loongson_punpcklbh (t3, t1, t0));
21813 if (odd)
21814 emit_insn (gen_loongson_punpckhbh (d->target, t3, t2));
21815 else
21816 emit_insn (gen_loongson_punpcklbh (d->target, t3, t2));
21817 break;
21819 default:
21820 gcc_unreachable ();
21822 return true;
21825 /* Recognize patterns for the Loongson PSHUFH instruction. */
21827 static bool
21828 mips_expand_vpc_loongson_pshufh (struct expand_vec_perm_d *d)
21830 unsigned i, mask;
21831 rtx rmask;
21833 if (!(TARGET_HARD_FLOAT && TARGET_LOONGSON_MMI))
21834 return false;
21835 if (d->vmode != V4HImode)
21836 return false;
21837 if (d->testing_p)
21838 return true;
21840 /* Convert the selector into the packed 8-bit form for pshufh. */
21841 /* Recall that loongson is little-endian only. No big-endian
21842 adjustment required. */
21843 for (i = mask = 0; i < 4; i++)
21844 mask |= (d->perm[i] & 3) << (i * 2);
21845 rmask = force_reg (SImode, GEN_INT (mask));
21847 if (d->one_vector_p)
21848 emit_insn (gen_loongson_pshufh (d->target, d->op0, rmask));
21849 else
21851 rtx t0, t1, x, merge, rmerge[4];
21853 t0 = gen_reg_rtx (V4HImode);
21854 t1 = gen_reg_rtx (V4HImode);
21855 emit_insn (gen_loongson_pshufh (t1, d->op1, rmask));
21856 emit_insn (gen_loongson_pshufh (t0, d->op0, rmask));
21858 for (i = 0; i < 4; ++i)
21859 rmerge[i] = (d->perm[i] & 4 ? constm1_rtx : const0_rtx);
21860 merge = gen_rtx_CONST_VECTOR (V4HImode, gen_rtvec_v (4, rmerge));
21861 merge = force_reg (V4HImode, merge);
21863 x = gen_rtx_AND (V4HImode, merge, t1);
21864 emit_insn (gen_rtx_SET (t1, x));
21866 x = gen_rtx_NOT (V4HImode, merge);
21867 x = gen_rtx_AND (V4HImode, x, t0);
21868 emit_insn (gen_rtx_SET (t0, x));
21870 x = gen_rtx_IOR (V4HImode, t0, t1);
21871 emit_insn (gen_rtx_SET (d->target, x));
21874 return true;
21877 /* Recognize broadcast patterns for the Loongson. */
21879 static bool
21880 mips_expand_vpc_loongson_bcast (struct expand_vec_perm_d *d)
21882 unsigned i, elt;
21883 rtx t0, t1;
21885 if (!(TARGET_HARD_FLOAT && TARGET_LOONGSON_MMI))
21886 return false;
21887 /* Note that we've already matched V2SI via punpck and V4HI via pshufh. */
21888 if (d->vmode != V8QImode)
21889 return false;
21890 if (!d->one_vector_p)
21891 return false;
21893 elt = d->perm[0];
21894 for (i = 1; i < 8; ++i)
21895 if (d->perm[i] != elt)
21896 return false;
21898 if (d->testing_p)
21899 return true;
21901 /* With one interleave we put two of the desired element adjacent. */
21902 t0 = gen_reg_rtx (V8QImode);
21903 if (elt < 4)
21904 emit_insn (gen_loongson_punpcklbh (t0, d->op0, d->op0));
21905 else
21906 emit_insn (gen_loongson_punpckhbh (t0, d->op0, d->op0));
21908 /* Shuffle that one HImode element into all locations. */
21909 elt &= 3;
21910 elt *= 0x55;
21911 t1 = gen_reg_rtx (V4HImode);
21912 emit_insn (gen_loongson_pshufh (t1, gen_lowpart (V4HImode, t0),
21913 force_reg (SImode, GEN_INT (elt))));
21915 emit_move_insn (d->target, gen_lowpart (V8QImode, t1));
21916 return true;
21919 /* Construct (set target (vec_select op0 (parallel selector))) and
21920 return true if that's a valid instruction in the active ISA. */
21922 static bool
21923 mips_expand_msa_shuffle (struct expand_vec_perm_d *d)
21925 rtx x, elts[MAX_VECT_LEN];
21926 rtvec v;
21927 rtx_insn *insn;
21928 unsigned i;
21930 if (!ISA_HAS_MSA)
21931 return false;
21933 for (i = 0; i < d->nelt; i++)
21934 elts[i] = GEN_INT (d->perm[i]);
21936 v = gen_rtvec_v (d->nelt, elts);
21937 x = gen_rtx_PARALLEL (VOIDmode, v);
21939 if (!mips_const_vector_shuffle_set_p (x, d->vmode))
21940 return false;
21942 x = gen_rtx_VEC_SELECT (d->vmode, d->op0, x);
21943 x = gen_rtx_SET (d->target, x);
21945 insn = emit_insn (x);
21946 if (recog_memoized (insn) < 0)
21948 remove_insn (insn);
21949 return false;
21951 return true;
21954 static bool
21955 mips_expand_vec_perm_const_1 (struct expand_vec_perm_d *d)
21957 unsigned int i, nelt = d->nelt;
21958 unsigned char perm2[MAX_VECT_LEN];
21960 if (d->one_vector_p)
21962 /* Try interleave with alternating operands. */
21963 memcpy (perm2, d->perm, sizeof(perm2));
21964 for (i = 1; i < nelt; i += 2)
21965 perm2[i] += nelt;
21966 if (mips_expand_vselect_vconcat (d->target, d->op0, d->op1, perm2, nelt))
21967 return true;
21969 else
21971 if (mips_expand_vselect_vconcat (d->target, d->op0, d->op1,
21972 d->perm, nelt))
21973 return true;
21975 /* Try again with swapped operands. */
21976 for (i = 0; i < nelt; ++i)
21977 perm2[i] = (d->perm[i] + nelt) & (2 * nelt - 1);
21978 if (mips_expand_vselect_vconcat (d->target, d->op1, d->op0, perm2, nelt))
21979 return true;
21982 if (mips_expand_vpc_loongson_even_odd (d))
21983 return true;
21984 if (mips_expand_vpc_loongson_pshufh (d))
21985 return true;
21986 if (mips_expand_vpc_loongson_bcast (d))
21987 return true;
21988 if (mips_expand_msa_shuffle (d))
21989 return true;
21990 return false;
21993 /* Implement TARGET_VECTORIZE_VEC_PERM_CONST. */
21995 static bool
21996 mips_vectorize_vec_perm_const (machine_mode vmode, machine_mode op_mode,
21997 rtx target, rtx op0, rtx op1,
21998 const vec_perm_indices &sel)
22000 if (vmode != op_mode)
22001 return false;
22003 struct expand_vec_perm_d d;
22004 int i, nelt, which;
22005 unsigned char orig_perm[MAX_VECT_LEN];
22006 bool ok;
22008 d.target = target;
22009 if (op0)
22011 rtx nop0 = force_reg (vmode, op0);
22012 if (op0 == op1)
22013 op1 = nop0;
22014 op0 = nop0;
22016 if (op1)
22017 op1 = force_reg (vmode, op1);
22018 d.op0 = op0;
22019 d.op1 = op1;
22021 d.vmode = vmode;
22022 gcc_assert (VECTOR_MODE_P (vmode));
22023 d.nelt = nelt = GET_MODE_NUNITS (vmode);
22024 d.testing_p = !target;
22026 /* This is overly conservative, but ensures we don't get an
22027 uninitialized warning on ORIG_PERM. */
22028 memset (orig_perm, 0, MAX_VECT_LEN);
22029 for (i = which = 0; i < nelt; ++i)
22031 int ei = sel[i] & (2 * nelt - 1);
22032 which |= (ei < nelt ? 1 : 2);
22033 orig_perm[i] = ei;
22035 memcpy (d.perm, orig_perm, MAX_VECT_LEN);
22037 switch (which)
22039 default:
22040 gcc_unreachable();
22042 case 3:
22043 d.one_vector_p = false;
22044 if (d.testing_p || !rtx_equal_p (d.op0, d.op1))
22045 break;
22046 /* FALLTHRU */
22048 case 2:
22049 for (i = 0; i < nelt; ++i)
22050 d.perm[i] &= nelt - 1;
22051 d.op0 = d.op1;
22052 d.one_vector_p = true;
22053 break;
22055 case 1:
22056 d.op1 = d.op0;
22057 d.one_vector_p = true;
22058 break;
22061 if (d.testing_p)
22063 d.target = gen_raw_REG (d.vmode, LAST_VIRTUAL_REGISTER + 1);
22064 d.op1 = d.op0 = gen_raw_REG (d.vmode, LAST_VIRTUAL_REGISTER + 2);
22065 if (!d.one_vector_p)
22066 d.op1 = gen_raw_REG (d.vmode, LAST_VIRTUAL_REGISTER + 3);
22068 start_sequence ();
22069 ok = mips_expand_vec_perm_const_1 (&d);
22070 end_sequence ();
22071 return ok;
22074 ok = mips_expand_vec_perm_const_1 (&d);
22076 /* If we were given a two-vector permutation which just happened to
22077 have both input vectors equal, we folded this into a one-vector
22078 permutation. There are several loongson patterns that are matched
22079 via direct vec_select+vec_concat expansion, but we do not have
22080 support in mips_expand_vec_perm_const_1 to guess the adjustment
22081 that should be made for a single operand. Just try again with
22082 the original permutation. */
22083 if (!ok && which == 3)
22085 d.op0 = op0;
22086 d.op1 = op1;
22087 d.one_vector_p = false;
22088 memcpy (d.perm, orig_perm, MAX_VECT_LEN);
22089 ok = mips_expand_vec_perm_const_1 (&d);
22092 return ok;
22095 /* Implement TARGET_SCHED_REASSOCIATION_WIDTH. */
22097 static int
22098 mips_sched_reassociation_width (unsigned int opc ATTRIBUTE_UNUSED,
22099 machine_mode mode)
22101 if (MSA_SUPPORTED_MODE_P (mode))
22102 return 2;
22103 return 1;
22106 /* Expand an integral vector unpack operation. */
22108 void
22109 mips_expand_vec_unpack (rtx operands[2], bool unsigned_p, bool high_p)
22111 machine_mode imode = GET_MODE (operands[1]);
22112 rtx (*unpack) (rtx, rtx, rtx);
22113 rtx (*cmpFunc) (rtx, rtx, rtx);
22114 rtx tmp, dest, zero;
22116 if (MSA_SUPPORTED_MODE_P (imode))
22118 switch (imode)
22120 case E_V4SImode:
22121 if (BYTES_BIG_ENDIAN != high_p)
22122 unpack = gen_msa_ilvl_w;
22123 else
22124 unpack = gen_msa_ilvr_w;
22126 cmpFunc = gen_msa_clt_s_w;
22127 break;
22129 case E_V8HImode:
22130 if (BYTES_BIG_ENDIAN != high_p)
22131 unpack = gen_msa_ilvl_h;
22132 else
22133 unpack = gen_msa_ilvr_h;
22135 cmpFunc = gen_msa_clt_s_h;
22136 break;
22138 case E_V16QImode:
22139 if (BYTES_BIG_ENDIAN != high_p)
22140 unpack = gen_msa_ilvl_b;
22141 else
22142 unpack = gen_msa_ilvr_b;
22144 cmpFunc = gen_msa_clt_s_b;
22145 break;
22147 default:
22148 gcc_unreachable ();
22149 break;
22152 if (!unsigned_p)
22154 /* Extract sign extention for each element comparing each element
22155 with immediate zero. */
22156 tmp = gen_reg_rtx (imode);
22157 emit_insn (cmpFunc (tmp, operands[1], CONST0_RTX (imode)));
22159 else
22160 tmp = force_reg (imode, CONST0_RTX (imode));
22162 dest = gen_reg_rtx (imode);
22164 emit_insn (unpack (dest, operands[1], tmp));
22165 emit_move_insn (operands[0], gen_lowpart (GET_MODE (operands[0]), dest));
22166 return;
22169 switch (imode)
22171 case E_V8QImode:
22172 if (high_p)
22173 unpack = gen_loongson_punpckhbh;
22174 else
22175 unpack = gen_loongson_punpcklbh;
22176 cmpFunc = gen_loongson_pcmpgtb;
22177 break;
22178 case E_V4HImode:
22179 if (high_p)
22180 unpack = gen_loongson_punpckhhw;
22181 else
22182 unpack = gen_loongson_punpcklhw;
22183 cmpFunc = gen_loongson_pcmpgth;
22184 break;
22185 default:
22186 gcc_unreachable ();
22189 zero = force_reg (imode, CONST0_RTX (imode));
22190 if (unsigned_p)
22191 tmp = zero;
22192 else
22194 tmp = gen_reg_rtx (imode);
22195 emit_insn (cmpFunc (tmp, zero, operands[1]));
22198 dest = gen_reg_rtx (imode);
22199 emit_insn (unpack (dest, operands[1], tmp));
22201 emit_move_insn (operands[0], gen_lowpart (GET_MODE (operands[0]), dest));
22204 /* Construct and return PARALLEL RTX with CONST_INTs for HIGH (high_p == TRUE)
22205 or LOW (high_p == FALSE) half of a vector for mode MODE. */
22208 mips_msa_vec_parallel_const_half (machine_mode mode, bool high_p)
22210 int nunits = GET_MODE_NUNITS (mode);
22211 rtvec v = rtvec_alloc (nunits / 2);
22212 int base;
22213 int i;
22215 if (BYTES_BIG_ENDIAN)
22216 base = high_p ? 0 : nunits / 2;
22217 else
22218 base = high_p ? nunits / 2 : 0;
22220 for (i = 0; i < nunits / 2; i++)
22221 RTVEC_ELT (v, i) = GEN_INT (base + i);
22223 return gen_rtx_PARALLEL (VOIDmode, v);
22226 /* A subroutine of mips_expand_vec_init, match constant vector elements. */
22228 static inline bool
22229 mips_constant_elt_p (rtx x)
22231 return CONST_INT_P (x) || GET_CODE (x) == CONST_DOUBLE;
22234 /* A subroutine of mips_expand_vec_init, expand via broadcast. */
22236 static void
22237 mips_expand_vi_broadcast (machine_mode vmode, rtx target, rtx elt)
22239 struct expand_vec_perm_d d;
22240 rtx t1;
22241 bool ok;
22243 if (elt != const0_rtx)
22244 elt = force_reg (GET_MODE_INNER (vmode), elt);
22245 if (REG_P (elt))
22246 elt = gen_lowpart (DImode, elt);
22248 t1 = gen_reg_rtx (vmode);
22249 switch (vmode)
22251 case E_V8QImode:
22252 emit_insn (gen_loongson_vec_init1_v8qi (t1, elt));
22253 break;
22254 case E_V4HImode:
22255 emit_insn (gen_loongson_vec_init1_v4hi (t1, elt));
22256 break;
22257 default:
22258 gcc_unreachable ();
22261 memset (&d, 0, sizeof (d));
22262 d.target = target;
22263 d.op0 = t1;
22264 d.op1 = t1;
22265 d.vmode = vmode;
22266 d.nelt = GET_MODE_NUNITS (vmode);
22267 d.one_vector_p = true;
22269 ok = mips_expand_vec_perm_const_1 (&d);
22270 gcc_assert (ok);
22273 /* Return a const_int vector of VAL with mode MODE. */
22276 mips_gen_const_int_vector (machine_mode mode, HOST_WIDE_INT val)
22278 rtx c = gen_int_mode (val, GET_MODE_INNER (mode));
22279 return gen_const_vec_duplicate (mode, c);
22282 /* Return a vector of repeated 4-element sets generated from
22283 immediate VAL in mode MODE. */
22285 static rtx
22286 mips_gen_const_int_vector_shuffle (machine_mode mode, int val)
22288 int nunits = GET_MODE_NUNITS (mode);
22289 int nsets = nunits / 4;
22290 rtx elts[MAX_VECT_LEN];
22291 int set = 0;
22292 int i, j;
22294 /* Generate a const_int vector replicating the same 4-element set
22295 from an immediate. */
22296 for (j = 0; j < nsets; j++, set = 4 * j)
22297 for (i = 0; i < 4; i++)
22298 elts[set + i] = GEN_INT (set + ((val >> (2 * i)) & 0x3));
22300 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nunits, elts));
22303 /* A subroutine of mips_expand_vec_init, replacing all of the non-constant
22304 elements of VALS with zeros, copy the constant vector to TARGET. */
22306 static void
22307 mips_expand_vi_constant (machine_mode vmode, unsigned nelt,
22308 rtx target, rtx vals)
22310 rtvec vec = shallow_copy_rtvec (XVEC (vals, 0));
22311 unsigned i;
22313 for (i = 0; i < nelt; ++i)
22315 rtx elem = RTVEC_ELT (vec, i);
22316 if (!mips_constant_elt_p (elem))
22317 RTVEC_ELT (vec, i) = CONST0_RTX (GET_MODE (elem));
22320 emit_move_insn (target, gen_rtx_CONST_VECTOR (vmode, vec));
22324 /* A subroutine of mips_expand_vec_init, expand via pinsrh. */
22326 static void
22327 mips_expand_vi_loongson_one_pinsrh (rtx target, rtx vals, unsigned one_var)
22329 mips_expand_vi_constant (V4HImode, 4, target, vals);
22331 emit_insn (gen_vec_setv4hi (target, target, XVECEXP (vals, 0, one_var),
22332 GEN_INT (one_var)));
22335 /* A subroutine of mips_expand_vec_init, expand anything via memory. */
22337 static void
22338 mips_expand_vi_general (machine_mode vmode, machine_mode imode,
22339 unsigned nelt, unsigned nvar, rtx target, rtx vals)
22341 rtx mem = assign_stack_temp (vmode, GET_MODE_SIZE (vmode));
22342 unsigned int i, isize = GET_MODE_SIZE (imode);
22344 if (nvar < nelt)
22345 mips_expand_vi_constant (vmode, nelt, mem, vals);
22347 for (i = 0; i < nelt; ++i)
22349 rtx x = XVECEXP (vals, 0, i);
22350 if (!mips_constant_elt_p (x))
22351 emit_move_insn (adjust_address (mem, imode, i * isize), x);
22354 emit_move_insn (target, mem);
22357 /* Expand a vector initialization. */
22359 void
22360 mips_expand_vector_init (rtx target, rtx vals)
22362 machine_mode vmode = GET_MODE (target);
22363 machine_mode imode = GET_MODE_INNER (vmode);
22364 unsigned i, nelt = GET_MODE_NUNITS (vmode);
22365 unsigned nvar = 0, one_var = -1u;
22366 bool all_same = true;
22367 rtx x;
22369 for (i = 0; i < nelt; ++i)
22371 x = XVECEXP (vals, 0, i);
22372 if (!mips_constant_elt_p (x))
22373 nvar++, one_var = i;
22374 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
22375 all_same = false;
22378 if (MSA_SUPPORTED_MODE_P (vmode))
22380 if (all_same)
22382 rtx same = XVECEXP (vals, 0, 0);
22383 rtx temp, temp2;
22385 if (CONST_INT_P (same) && nvar == 0
22386 && mips_signed_immediate_p (INTVAL (same), 10, 0))
22388 switch (vmode)
22390 case E_V16QImode:
22391 case E_V8HImode:
22392 case E_V4SImode:
22393 case E_V2DImode:
22394 temp = gen_rtx_CONST_VECTOR (vmode, XVEC (vals, 0));
22395 emit_move_insn (target, temp);
22396 return;
22398 default:
22399 gcc_unreachable ();
22402 temp = gen_reg_rtx (imode);
22403 if (imode == GET_MODE (same))
22404 temp2 = same;
22405 else if (GET_MODE_SIZE (imode) >= UNITS_PER_WORD)
22406 temp2 = simplify_gen_subreg (imode, same, GET_MODE (same), 0);
22407 else
22408 temp2 = lowpart_subreg (imode, same, GET_MODE (same));
22409 emit_move_insn (temp, temp2);
22411 switch (vmode)
22413 case E_V16QImode:
22414 case E_V8HImode:
22415 case E_V4SImode:
22416 case E_V2DImode:
22417 mips_emit_move (target, gen_rtx_VEC_DUPLICATE (vmode, temp));
22418 break;
22420 case E_V4SFmode:
22421 emit_insn (gen_msa_splati_w_f_scalar (target, temp));
22422 break;
22424 case E_V2DFmode:
22425 emit_insn (gen_msa_splati_d_f_scalar (target, temp));
22426 break;
22428 default:
22429 gcc_unreachable ();
22432 else
22434 emit_move_insn (target, CONST0_RTX (vmode));
22436 for (i = 0; i < nelt; ++i)
22438 rtx temp = gen_reg_rtx (imode);
22439 emit_move_insn (temp, XVECEXP (vals, 0, i));
22440 switch (vmode)
22442 case E_V16QImode:
22443 emit_insn (gen_vec_setv16qi (target, temp, GEN_INT (i)));
22444 break;
22446 case E_V8HImode:
22447 emit_insn (gen_vec_setv8hi (target, temp, GEN_INT (i)));
22448 break;
22450 case E_V4SImode:
22451 emit_insn (gen_vec_setv4si (target, temp, GEN_INT (i)));
22452 break;
22454 case E_V2DImode:
22455 emit_insn (gen_vec_setv2di (target, temp, GEN_INT (i)));
22456 break;
22458 case E_V4SFmode:
22459 emit_insn (gen_vec_setv4sf (target, temp, GEN_INT (i)));
22460 break;
22462 case E_V2DFmode:
22463 emit_insn (gen_vec_setv2df (target, temp, GEN_INT (i)));
22464 break;
22466 default:
22467 gcc_unreachable ();
22471 return;
22474 /* Load constants from the pool, or whatever's handy. */
22475 if (nvar == 0)
22477 emit_move_insn (target, gen_rtx_CONST_VECTOR (vmode, XVEC (vals, 0)));
22478 return;
22481 /* For two-part initialization, always use CONCAT. */
22482 if (nelt == 2)
22484 rtx op0 = force_reg (imode, XVECEXP (vals, 0, 0));
22485 rtx op1 = force_reg (imode, XVECEXP (vals, 0, 1));
22486 x = gen_rtx_VEC_CONCAT (vmode, op0, op1);
22487 emit_insn (gen_rtx_SET (target, x));
22488 return;
22491 /* Loongson is the only cpu with vectors with more elements. */
22492 gcc_assert (TARGET_HARD_FLOAT && TARGET_LOONGSON_MMI);
22494 /* If all values are identical, broadcast the value. */
22495 if (all_same)
22497 mips_expand_vi_broadcast (vmode, target, XVECEXP (vals, 0, 0));
22498 return;
22501 /* If we've only got one non-variable V4HImode, use PINSRH. */
22502 if (nvar == 1 && vmode == V4HImode)
22504 mips_expand_vi_loongson_one_pinsrh (target, vals, one_var);
22505 return;
22508 mips_expand_vi_general (vmode, imode, nelt, nvar, target, vals);
22511 /* Expand a vector reduction. */
22513 void
22514 mips_expand_vec_reduc (rtx target, rtx in, rtx (*gen)(rtx, rtx, rtx))
22516 machine_mode vmode = GET_MODE (in);
22517 unsigned char perm2[2];
22518 rtx last, next, fold, x;
22519 bool ok;
22521 last = in;
22522 fold = gen_reg_rtx (vmode);
22523 switch (vmode)
22525 case E_V2SFmode:
22526 /* Use PUL/PLU to produce { L, H } op { H, L }.
22527 By reversing the pair order, rather than a pure interleave high,
22528 we avoid erroneous exceptional conditions that we might otherwise
22529 produce from the computation of H op H. */
22530 perm2[0] = 1;
22531 perm2[1] = 2;
22532 ok = mips_expand_vselect_vconcat (fold, last, last, perm2, 2);
22533 gcc_assert (ok);
22534 break;
22536 case E_V2SImode:
22537 /* Use interleave to produce { H, L } op { H, H }. */
22538 emit_insn (gen_loongson_punpckhwd (fold, last, last));
22539 break;
22541 case E_V4HImode:
22542 /* Perform the first reduction with interleave,
22543 and subsequent reductions with shifts. */
22544 emit_insn (gen_loongson_punpckhwd_hi (fold, last, last));
22546 next = gen_reg_rtx (vmode);
22547 emit_insn (gen (next, last, fold));
22548 last = next;
22550 fold = gen_reg_rtx (vmode);
22551 x = force_reg (SImode, GEN_INT (16));
22552 emit_insn (gen_vec_shr_v4hi (fold, last, x));
22553 break;
22555 case E_V8QImode:
22556 emit_insn (gen_loongson_punpckhwd_qi (fold, last, last));
22558 next = gen_reg_rtx (vmode);
22559 emit_insn (gen (next, last, fold));
22560 last = next;
22562 fold = gen_reg_rtx (vmode);
22563 x = force_reg (SImode, GEN_INT (16));
22564 emit_insn (gen_vec_shr_v8qi (fold, last, x));
22566 next = gen_reg_rtx (vmode);
22567 emit_insn (gen (next, last, fold));
22568 last = next;
22570 fold = gen_reg_rtx (vmode);
22571 x = force_reg (SImode, GEN_INT (8));
22572 emit_insn (gen_vec_shr_v8qi (fold, last, x));
22573 break;
22575 default:
22576 gcc_unreachable ();
22579 emit_insn (gen (target, last, fold));
22582 /* Expand a vector minimum/maximum. */
22584 void
22585 mips_expand_vec_minmax (rtx target, rtx op0, rtx op1,
22586 rtx (*cmp) (rtx, rtx, rtx), bool min_p)
22588 machine_mode vmode = GET_MODE (target);
22589 rtx tc, t0, t1, x;
22591 tc = gen_reg_rtx (vmode);
22592 t0 = gen_reg_rtx (vmode);
22593 t1 = gen_reg_rtx (vmode);
22595 /* op0 > op1 */
22596 emit_insn (cmp (tc, op0, op1));
22598 x = gen_rtx_AND (vmode, tc, (min_p ? op1 : op0));
22599 emit_insn (gen_rtx_SET (t0, x));
22601 x = gen_rtx_NOT (vmode, tc);
22602 x = gen_rtx_AND (vmode, x, (min_p ? op0 : op1));
22603 emit_insn (gen_rtx_SET (t1, x));
22605 x = gen_rtx_IOR (vmode, t0, t1);
22606 emit_insn (gen_rtx_SET (target, x));
22609 /* Implement HARD_REGNO_CALLER_SAVE_MODE. */
22611 machine_mode
22612 mips_hard_regno_caller_save_mode (unsigned int regno,
22613 unsigned int nregs,
22614 machine_mode mode)
22616 /* For performance, avoid saving/restoring upper parts of a register
22617 by returning MODE as save mode when the mode is known. */
22618 if (mode == VOIDmode)
22619 return choose_hard_reg_mode (regno, nregs, NULL);
22620 else
22621 return mode;
22624 /* Generate RTL for comparing CMP_OP0 and CMP_OP1 using condition COND and
22625 store the result -1 or 0 in DEST. */
22627 static void
22628 mips_expand_msa_cmp (rtx dest, enum rtx_code cond, rtx op0, rtx op1)
22630 machine_mode cmp_mode = GET_MODE (op0);
22631 int unspec = -1;
22632 bool negate = false;
22634 switch (cmp_mode)
22636 case E_V16QImode:
22637 case E_V8HImode:
22638 case E_V4SImode:
22639 case E_V2DImode:
22640 switch (cond)
22642 case NE:
22643 cond = reverse_condition (cond);
22644 negate = true;
22645 break;
22646 case EQ:
22647 case LT:
22648 case LE:
22649 case LTU:
22650 case LEU:
22651 break;
22652 case GE:
22653 case GT:
22654 case GEU:
22655 case GTU:
22656 std::swap (op0, op1);
22657 cond = swap_condition (cond);
22658 break;
22659 default:
22660 gcc_unreachable ();
22662 mips_emit_binary (cond, dest, op0, op1);
22663 if (negate)
22664 emit_move_insn (dest, gen_rtx_NOT (GET_MODE (dest), dest));
22665 break;
22667 case E_V4SFmode:
22668 case E_V2DFmode:
22669 switch (cond)
22671 case UNORDERED:
22672 case ORDERED:
22673 case EQ:
22674 case NE:
22675 case UNEQ:
22676 case UNLE:
22677 case UNLT:
22678 break;
22679 case LTGT: cond = NE; break;
22680 case UNGE: cond = UNLE; std::swap (op0, op1); break;
22681 case UNGT: cond = UNLT; std::swap (op0, op1); break;
22682 case LE: unspec = UNSPEC_MSA_FSLE; break;
22683 case LT: unspec = UNSPEC_MSA_FSLT; break;
22684 case GE: unspec = UNSPEC_MSA_FSLE; std::swap (op0, op1); break;
22685 case GT: unspec = UNSPEC_MSA_FSLT; std::swap (op0, op1); break;
22686 default:
22687 gcc_unreachable ();
22689 if (unspec < 0)
22690 mips_emit_binary (cond, dest, op0, op1);
22691 else
22693 rtx x = gen_rtx_UNSPEC (GET_MODE (dest),
22694 gen_rtvec (2, op0, op1), unspec);
22695 emit_insn (gen_rtx_SET (dest, x));
22697 break;
22699 default:
22700 gcc_unreachable ();
22701 break;
22705 void
22706 mips_expand_vec_cmp_expr (rtx *operands)
22708 rtx cond = operands[1];
22709 rtx op0 = operands[2];
22710 rtx op1 = operands[3];
22711 rtx res = operands[0];
22713 mips_expand_msa_cmp (res, GET_CODE (cond), op0, op1);
22716 /* Expand VEC_COND_EXPR, where:
22717 MODE is mode of the result
22718 VIMODE equivalent integer mode
22719 OPERANDS operands of VEC_COND_EXPR. */
22721 void
22722 mips_expand_vec_cond_expr (machine_mode mode, machine_mode vimode,
22723 rtx *operands)
22725 rtx cond = operands[3];
22726 rtx cmp_op0 = operands[4];
22727 rtx cmp_op1 = operands[5];
22728 rtx cmp_res = gen_reg_rtx (vimode);
22730 mips_expand_msa_cmp (cmp_res, GET_CODE (cond), cmp_op0, cmp_op1);
22732 /* We handle the following cases:
22733 1) r = a CMP b ? -1 : 0
22734 2) r = a CMP b ? -1 : v
22735 3) r = a CMP b ? v : 0
22736 4) r = a CMP b ? v1 : v2 */
22738 /* Case (1) above. We only move the results. */
22739 if (operands[1] == CONSTM1_RTX (vimode)
22740 && operands[2] == CONST0_RTX (vimode))
22741 emit_move_insn (operands[0], cmp_res);
22742 else
22744 rtx src1 = gen_reg_rtx (vimode);
22745 rtx src2 = gen_reg_rtx (vimode);
22746 rtx mask = gen_reg_rtx (vimode);
22747 rtx bsel;
22749 /* Move the vector result to use it as a mask. */
22750 emit_move_insn (mask, cmp_res);
22752 if (register_operand (operands[1], mode))
22754 rtx xop1 = operands[1];
22755 if (mode != vimode)
22757 xop1 = gen_reg_rtx (vimode);
22758 emit_move_insn (xop1, gen_lowpart (vimode, operands[1]));
22760 emit_move_insn (src1, xop1);
22762 else
22764 gcc_assert (operands[1] == CONSTM1_RTX (vimode));
22765 /* Case (2) if the below doesn't move the mask to src2. */
22766 emit_move_insn (src1, mask);
22769 if (register_operand (operands[2], mode))
22771 rtx xop2 = operands[2];
22772 if (mode != vimode)
22774 xop2 = gen_reg_rtx (vimode);
22775 emit_move_insn (xop2, gen_lowpart (vimode, operands[2]));
22777 emit_move_insn (src2, xop2);
22779 else
22781 gcc_assert (operands[2] == CONST0_RTX (mode));
22782 /* Case (3) if the above didn't move the mask to src1. */
22783 emit_move_insn (src2, mask);
22786 /* We deal with case (4) if the mask wasn't moved to either src1 or src2.
22787 In any case, we eventually do vector mask-based copy. */
22788 bsel = gen_rtx_IOR (vimode,
22789 gen_rtx_AND (vimode,
22790 gen_rtx_NOT (vimode, mask), src2),
22791 gen_rtx_AND (vimode, mask, src1));
22792 /* The result is placed back to a register with the mask. */
22793 emit_insn (gen_rtx_SET (mask, bsel));
22794 emit_move_insn (operands[0], gen_rtx_SUBREG (mode, mask, 0));
22798 /* Implement TARGET_CASE_VALUES_THRESHOLD. */
22800 unsigned int
22801 mips_case_values_threshold (void)
22803 /* In MIPS16 mode using a larger case threshold generates smaller code. */
22804 if (TARGET_MIPS16 && optimize_size)
22805 return 10;
22806 else
22807 return default_case_values_threshold ();
22810 /* Implement TARGET_ATOMIC_ASSIGN_EXPAND_FENV. */
22812 static void
22813 mips_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
22815 if (!TARGET_HARD_FLOAT_ABI)
22816 return;
22817 tree exceptions_var = create_tmp_var_raw (MIPS_ATYPE_USI);
22818 tree fcsr_orig_var = create_tmp_var_raw (MIPS_ATYPE_USI);
22819 tree fcsr_mod_var = create_tmp_var_raw (MIPS_ATYPE_USI);
22820 tree get_fcsr = mips_builtin_decls[MIPS_GET_FCSR];
22821 tree set_fcsr = mips_builtin_decls[MIPS_SET_FCSR];
22822 tree get_fcsr_hold_call = build_call_expr (get_fcsr, 0);
22823 tree hold_assign_orig = build4 (TARGET_EXPR, MIPS_ATYPE_USI,
22824 fcsr_orig_var, get_fcsr_hold_call, NULL, NULL);
22825 tree hold_mod_val = build2 (BIT_AND_EXPR, MIPS_ATYPE_USI, fcsr_orig_var,
22826 build_int_cst (MIPS_ATYPE_USI, 0xfffff003));
22827 tree hold_assign_mod = build4 (TARGET_EXPR, MIPS_ATYPE_USI,
22828 fcsr_mod_var, hold_mod_val, NULL, NULL);
22829 tree set_fcsr_hold_call = build_call_expr (set_fcsr, 1, fcsr_mod_var);
22830 tree hold_all = build2 (COMPOUND_EXPR, MIPS_ATYPE_USI,
22831 hold_assign_orig, hold_assign_mod);
22832 *hold = build2 (COMPOUND_EXPR, void_type_node, hold_all,
22833 set_fcsr_hold_call);
22835 *clear = build_call_expr (set_fcsr, 1, fcsr_mod_var);
22837 tree get_fcsr_update_call = build_call_expr (get_fcsr, 0);
22838 *update = build4 (TARGET_EXPR, MIPS_ATYPE_USI,
22839 exceptions_var, get_fcsr_update_call, NULL, NULL);
22840 tree set_fcsr_update_call = build_call_expr (set_fcsr, 1, fcsr_orig_var);
22841 *update = build2 (COMPOUND_EXPR, void_type_node, *update,
22842 set_fcsr_update_call);
22843 tree atomic_feraiseexcept
22844 = builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT);
22845 tree int_exceptions_var = fold_convert (integer_type_node,
22846 exceptions_var);
22847 tree atomic_feraiseexcept_call = build_call_expr (atomic_feraiseexcept,
22848 1, int_exceptions_var);
22849 *update = build2 (COMPOUND_EXPR, void_type_node, *update,
22850 atomic_feraiseexcept_call);
22853 /* Implement TARGET_SPILL_CLASS. */
22855 static reg_class_t
22856 mips_spill_class (reg_class_t rclass ATTRIBUTE_UNUSED,
22857 machine_mode mode ATTRIBUTE_UNUSED)
22859 if (TARGET_MIPS16)
22860 return SPILL_REGS;
22861 return NO_REGS;
22864 /* Implement TARGET_LRA_P. */
22866 static bool
22867 mips_lra_p (void)
22869 return mips_lra_flag;
22872 /* Implement TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS. */
22874 static reg_class_t
22875 mips_ira_change_pseudo_allocno_class (int regno, reg_class_t allocno_class,
22876 reg_class_t best_class ATTRIBUTE_UNUSED)
22878 /* LRA will allocate an FPR for an integer mode pseudo instead of spilling
22879 to memory if an FPR is present in the allocno class. It is rare that
22880 we actually need to place an integer mode value in an FPR so where
22881 possible limit the allocation to GR_REGS. This will slightly pessimize
22882 code that involves integer to/from float conversions as these will have
22883 to reload into FPRs in LRA. Such reloads are sometimes eliminated and
22884 sometimes only partially eliminated. We choose to take this penalty
22885 in order to eliminate usage of FPRs in code that does not use floating
22886 point data.
22888 This change has a similar effect to increasing the cost of FPR->GPR
22889 register moves for integer modes so that they are higher than the cost
22890 of memory but changing the allocno class is more reliable.
22892 This is also similar to forbidding integer mode values in FPRs entirely
22893 but this would lead to an inconsistency in the integer to/from float
22894 instructions that say integer mode values must be placed in FPRs. */
22895 if (INTEGRAL_MODE_P (PSEUDO_REGNO_MODE (regno)) && allocno_class == ALL_REGS)
22896 return GR_REGS;
22897 return allocno_class;
22900 /* Implement TARGET_PROMOTE_FUNCTION_MODE */
22902 /* This function is equivalent to default_promote_function_mode_always_promote
22903 except that it returns a promoted mode even if type is NULL_TREE. This is
22904 needed by libcalls which have no type (only a mode) such as fixed conversion
22905 routines that take a signed or unsigned char/short argument and convert it
22906 to a fixed type. */
22908 static machine_mode
22909 mips_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
22910 machine_mode mode,
22911 int *punsignedp ATTRIBUTE_UNUSED,
22912 const_tree fntype ATTRIBUTE_UNUSED,
22913 int for_return ATTRIBUTE_UNUSED)
22915 int unsignedp;
22917 if (type != NULL_TREE)
22918 return promote_mode (type, mode, punsignedp);
22920 unsignedp = *punsignedp;
22921 PROMOTE_MODE (mode, unsignedp, type);
22922 *punsignedp = unsignedp;
22923 return mode;
22926 /* Implement TARGET_TRULY_NOOP_TRUNCATION. */
22928 static bool
22929 mips_truly_noop_truncation (poly_uint64 outprec, poly_uint64 inprec)
22931 return !TARGET_64BIT || inprec <= 32 || outprec > 32;
22934 /* Implement TARGET_CONSTANT_ALIGNMENT. */
22936 static HOST_WIDE_INT
22937 mips_constant_alignment (const_tree exp, HOST_WIDE_INT align)
22939 if (TREE_CODE (exp) == STRING_CST || TREE_CODE (exp) == CONSTRUCTOR)
22940 return MAX (align, BITS_PER_WORD);
22941 return align;
22944 /* Implement the TARGET_ASAN_SHADOW_OFFSET hook. */
22946 static unsigned HOST_WIDE_INT
22947 mips_asan_shadow_offset (void)
22949 if (mips_abi == ABI_N32)
22950 return (HOST_WIDE_INT_1 << 29);
22951 if (POINTER_SIZE == 64)
22952 return (HOST_WIDE_INT_1 << 37);
22953 else
22954 return HOST_WIDE_INT_C (0x0aaa0000);
22957 /* Implement TARGET_STARTING_FRAME_OFFSET. See mips_compute_frame_info
22958 for details about the frame layout. */
22960 static HOST_WIDE_INT
22961 mips_starting_frame_offset (void)
22963 if (FRAME_GROWS_DOWNWARD)
22964 return 0;
22965 return crtl->outgoing_args_size + MIPS_GP_SAVE_AREA_SIZE;
22968 static void
22969 mips_asm_file_end (void)
22971 if (NEED_INDICATE_EXEC_STACK)
22972 file_end_indicate_exec_stack ();
22975 void
22976 mips_bit_clear_info (enum machine_mode mode, unsigned HOST_WIDE_INT m,
22977 int *start_pos, int *size)
22979 unsigned int shift = 0;
22980 unsigned int change_count = 0;
22981 unsigned int prev_val = 1;
22982 unsigned int curr_val = 0;
22983 unsigned int end_pos = GET_MODE_SIZE (mode) * BITS_PER_UNIT;
22985 for (shift = 0 ; shift < (GET_MODE_SIZE (mode) * BITS_PER_UNIT) ; shift++)
22987 curr_val = (unsigned int)((m & (unsigned int)(1 << shift)) >> shift);
22988 if (curr_val != prev_val)
22990 change_count++;
22991 switch (change_count)
22993 case 1:
22994 *start_pos = shift;
22995 break;
22996 case 2:
22997 end_pos = shift;
22998 break;
22999 default:
23000 gcc_unreachable ();
23003 prev_val = curr_val;
23005 *size = (end_pos - *start_pos);
23008 bool
23009 mips_bit_clear_p (enum machine_mode mode, unsigned HOST_WIDE_INT m)
23011 unsigned int shift = 0;
23012 unsigned int change_count = 0;
23013 unsigned int prev_val = 1;
23014 unsigned int curr_val = 0;
23016 if (mode != SImode && mode != VOIDmode)
23017 return false;
23019 if (!ISA_HAS_EXT_INS)
23020 return false;
23022 for (shift = 0 ; shift < (UNITS_PER_WORD * BITS_PER_UNIT) ; shift++)
23024 curr_val = (unsigned int)((m & (unsigned int)(1 << shift)) >> shift);
23025 if (curr_val != prev_val)
23026 change_count++;
23027 prev_val = curr_val;
23030 if (change_count == 2)
23031 return true;
23033 return false;
23036 /* Initialize the GCC target structure. */
23037 #undef TARGET_ASM_ALIGNED_HI_OP
23038 #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
23039 #undef TARGET_ASM_ALIGNED_SI_OP
23040 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
23041 #undef TARGET_ASM_ALIGNED_DI_OP
23042 #define TARGET_ASM_ALIGNED_DI_OP "\t.dword\t"
23044 #undef TARGET_OPTION_OVERRIDE
23045 #define TARGET_OPTION_OVERRIDE mips_option_override
23047 #undef TARGET_LEGITIMIZE_ADDRESS
23048 #define TARGET_LEGITIMIZE_ADDRESS mips_legitimize_address
23050 #undef TARGET_ASM_FUNCTION_PROLOGUE
23051 #define TARGET_ASM_FUNCTION_PROLOGUE mips_output_function_prologue
23052 #undef TARGET_ASM_FUNCTION_EPILOGUE
23053 #define TARGET_ASM_FUNCTION_EPILOGUE mips_output_function_epilogue
23054 #undef TARGET_ASM_SELECT_RTX_SECTION
23055 #define TARGET_ASM_SELECT_RTX_SECTION mips_select_rtx_section
23057 #undef TARGET_SCHED_INIT
23058 #define TARGET_SCHED_INIT mips_sched_init
23059 #undef TARGET_SCHED_REORDER
23060 #define TARGET_SCHED_REORDER mips_sched_reorder
23061 #undef TARGET_SCHED_REORDER2
23062 #define TARGET_SCHED_REORDER2 mips_sched_reorder2
23063 #undef TARGET_SCHED_VARIABLE_ISSUE
23064 #define TARGET_SCHED_VARIABLE_ISSUE mips_variable_issue
23065 #undef TARGET_SCHED_ADJUST_COST
23066 #define TARGET_SCHED_ADJUST_COST mips_adjust_cost
23067 #undef TARGET_SCHED_ISSUE_RATE
23068 #define TARGET_SCHED_ISSUE_RATE mips_issue_rate
23069 #undef TARGET_SCHED_INIT_DFA_POST_CYCLE_INSN
23070 #define TARGET_SCHED_INIT_DFA_POST_CYCLE_INSN mips_init_dfa_post_cycle_insn
23071 #undef TARGET_SCHED_DFA_POST_ADVANCE_CYCLE
23072 #define TARGET_SCHED_DFA_POST_ADVANCE_CYCLE mips_dfa_post_advance_cycle
23073 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
23074 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
23075 mips_multipass_dfa_lookahead
23076 #undef TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P
23077 #define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P \
23078 mips_small_register_classes_for_mode_p
23080 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
23081 #define TARGET_FUNCTION_OK_FOR_SIBCALL mips_function_ok_for_sibcall
23083 #undef TARGET_INSERT_ATTRIBUTES
23084 #define TARGET_INSERT_ATTRIBUTES mips_insert_attributes
23085 #undef TARGET_MERGE_DECL_ATTRIBUTES
23086 #define TARGET_MERGE_DECL_ATTRIBUTES mips_merge_decl_attributes
23087 #undef TARGET_CAN_INLINE_P
23088 #define TARGET_CAN_INLINE_P mips_can_inline_p
23089 #undef TARGET_SET_CURRENT_FUNCTION
23090 #define TARGET_SET_CURRENT_FUNCTION mips_set_current_function
23092 #undef TARGET_VALID_POINTER_MODE
23093 #define TARGET_VALID_POINTER_MODE mips_valid_pointer_mode
23094 #undef TARGET_REGISTER_MOVE_COST
23095 #define TARGET_REGISTER_MOVE_COST mips_register_move_cost
23096 #undef TARGET_REGISTER_PRIORITY
23097 #define TARGET_REGISTER_PRIORITY mips_register_priority
23098 #undef TARGET_MEMORY_MOVE_COST
23099 #define TARGET_MEMORY_MOVE_COST mips_memory_move_cost
23100 #undef TARGET_RTX_COSTS
23101 #define TARGET_RTX_COSTS mips_rtx_costs
23102 #undef TARGET_ADDRESS_COST
23103 #define TARGET_ADDRESS_COST mips_address_cost
23104 #undef TARGET_INSN_COST
23105 #define TARGET_INSN_COST mips_insn_cost
23107 #undef TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P
23108 #define TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P mips_no_speculation_in_delay_slots_p
23110 #undef TARGET_IN_SMALL_DATA_P
23111 #define TARGET_IN_SMALL_DATA_P mips_in_small_data_p
23113 #undef TARGET_MACHINE_DEPENDENT_REORG
23114 #define TARGET_MACHINE_DEPENDENT_REORG mips_reorg
23116 #undef TARGET_PREFERRED_RELOAD_CLASS
23117 #define TARGET_PREFERRED_RELOAD_CLASS mips_preferred_reload_class
23119 #undef TARGET_EXPAND_TO_RTL_HOOK
23120 #define TARGET_EXPAND_TO_RTL_HOOK mips_expand_to_rtl_hook
23121 #undef TARGET_ASM_FILE_START
23122 #define TARGET_ASM_FILE_START mips_file_start
23123 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
23124 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
23125 #undef TARGET_ASM_CODE_END
23126 #define TARGET_ASM_CODE_END mips_code_end
23128 #undef TARGET_INIT_LIBFUNCS
23129 #define TARGET_INIT_LIBFUNCS mips_init_libfuncs
23131 #undef TARGET_BUILD_BUILTIN_VA_LIST
23132 #define TARGET_BUILD_BUILTIN_VA_LIST mips_build_builtin_va_list
23133 #undef TARGET_EXPAND_BUILTIN_VA_START
23134 #define TARGET_EXPAND_BUILTIN_VA_START mips_va_start
23135 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
23136 #define TARGET_GIMPLIFY_VA_ARG_EXPR mips_gimplify_va_arg_expr
23138 #undef TARGET_PROMOTE_FUNCTION_MODE
23139 #define TARGET_PROMOTE_FUNCTION_MODE mips_promote_function_mode
23140 #undef TARGET_FUNCTION_VALUE
23141 #define TARGET_FUNCTION_VALUE mips_function_value
23142 #undef TARGET_LIBCALL_VALUE
23143 #define TARGET_LIBCALL_VALUE mips_libcall_value
23144 #undef TARGET_FUNCTION_VALUE_REGNO_P
23145 #define TARGET_FUNCTION_VALUE_REGNO_P mips_function_value_regno_p
23146 #undef TARGET_RETURN_IN_MEMORY
23147 #define TARGET_RETURN_IN_MEMORY mips_return_in_memory
23148 #undef TARGET_RETURN_IN_MSB
23149 #define TARGET_RETURN_IN_MSB mips_return_in_msb
23151 #undef TARGET_ASM_OUTPUT_MI_THUNK
23152 #define TARGET_ASM_OUTPUT_MI_THUNK mips_output_mi_thunk
23153 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
23154 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
23156 #undef TARGET_PRINT_OPERAND
23157 #define TARGET_PRINT_OPERAND mips_print_operand
23158 #undef TARGET_PRINT_OPERAND_ADDRESS
23159 #define TARGET_PRINT_OPERAND_ADDRESS mips_print_operand_address
23160 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
23161 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P mips_print_operand_punct_valid_p
23163 #undef TARGET_SETUP_INCOMING_VARARGS
23164 #define TARGET_SETUP_INCOMING_VARARGS mips_setup_incoming_varargs
23165 #undef TARGET_STRICT_ARGUMENT_NAMING
23166 #define TARGET_STRICT_ARGUMENT_NAMING mips_strict_argument_naming
23167 #undef TARGET_MUST_PASS_IN_STACK
23168 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
23169 #undef TARGET_PASS_BY_REFERENCE
23170 #define TARGET_PASS_BY_REFERENCE mips_pass_by_reference
23171 #undef TARGET_CALLEE_COPIES
23172 #define TARGET_CALLEE_COPIES mips_callee_copies
23173 #undef TARGET_ARG_PARTIAL_BYTES
23174 #define TARGET_ARG_PARTIAL_BYTES mips_arg_partial_bytes
23175 #undef TARGET_FUNCTION_ARG
23176 #define TARGET_FUNCTION_ARG mips_function_arg
23177 #undef TARGET_FUNCTION_ARG_ADVANCE
23178 #define TARGET_FUNCTION_ARG_ADVANCE mips_function_arg_advance
23179 #undef TARGET_FUNCTION_ARG_PADDING
23180 #define TARGET_FUNCTION_ARG_PADDING mips_function_arg_padding
23181 #undef TARGET_FUNCTION_ARG_BOUNDARY
23182 #define TARGET_FUNCTION_ARG_BOUNDARY mips_function_arg_boundary
23183 #undef TARGET_GET_RAW_RESULT_MODE
23184 #define TARGET_GET_RAW_RESULT_MODE mips_get_reg_raw_mode
23185 #undef TARGET_GET_RAW_ARG_MODE
23186 #define TARGET_GET_RAW_ARG_MODE mips_get_reg_raw_mode
23188 #undef TARGET_MODE_REP_EXTENDED
23189 #define TARGET_MODE_REP_EXTENDED mips_mode_rep_extended
23191 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
23192 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
23193 mips_builtin_vectorized_function
23194 #undef TARGET_VECTOR_MODE_SUPPORTED_P
23195 #define TARGET_VECTOR_MODE_SUPPORTED_P mips_vector_mode_supported_p
23197 #undef TARGET_SCALAR_MODE_SUPPORTED_P
23198 #define TARGET_SCALAR_MODE_SUPPORTED_P mips_scalar_mode_supported_p
23200 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
23201 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE mips_preferred_simd_mode
23202 #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES
23203 #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES \
23204 mips_autovectorize_vector_modes
23206 #undef TARGET_INIT_BUILTINS
23207 #define TARGET_INIT_BUILTINS mips_init_builtins
23208 #undef TARGET_BUILTIN_DECL
23209 #define TARGET_BUILTIN_DECL mips_builtin_decl
23210 #undef TARGET_EXPAND_BUILTIN
23211 #define TARGET_EXPAND_BUILTIN mips_expand_builtin
23213 #undef TARGET_HAVE_TLS
23214 #define TARGET_HAVE_TLS HAVE_AS_TLS
23216 #undef TARGET_CANNOT_FORCE_CONST_MEM
23217 #define TARGET_CANNOT_FORCE_CONST_MEM mips_cannot_force_const_mem
23219 #undef TARGET_LEGITIMATE_CONSTANT_P
23220 #define TARGET_LEGITIMATE_CONSTANT_P mips_legitimate_constant_p
23222 #undef TARGET_ENCODE_SECTION_INFO
23223 #define TARGET_ENCODE_SECTION_INFO mips_encode_section_info
23225 #undef TARGET_ATTRIBUTE_TABLE
23226 #define TARGET_ATTRIBUTE_TABLE mips_attribute_table
23227 /* All our function attributes are related to how out-of-line copies should
23228 be compiled or called. They don't in themselves prevent inlining. */
23229 #undef TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P
23230 #define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P hook_bool_const_tree_true
23232 #undef TARGET_EXTRA_LIVE_ON_ENTRY
23233 #define TARGET_EXTRA_LIVE_ON_ENTRY mips_extra_live_on_entry
23235 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
23236 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P mips_use_blocks_for_constant_p
23237 #undef TARGET_USE_ANCHORS_FOR_SYMBOL_P
23238 #define TARGET_USE_ANCHORS_FOR_SYMBOL_P mips_use_anchors_for_symbol_p
23240 #undef TARGET_COMP_TYPE_ATTRIBUTES
23241 #define TARGET_COMP_TYPE_ATTRIBUTES mips_comp_type_attributes
23243 #ifdef HAVE_AS_DTPRELWORD
23244 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
23245 #define TARGET_ASM_OUTPUT_DWARF_DTPREL mips_output_dwarf_dtprel
23246 #endif
23247 #undef TARGET_DWARF_REGISTER_SPAN
23248 #define TARGET_DWARF_REGISTER_SPAN mips_dwarf_register_span
23249 #undef TARGET_DWARF_FRAME_REG_MODE
23250 #define TARGET_DWARF_FRAME_REG_MODE mips_dwarf_frame_reg_mode
23252 #undef TARGET_ASM_FINAL_POSTSCAN_INSN
23253 #define TARGET_ASM_FINAL_POSTSCAN_INSN mips_final_postscan_insn
23255 #undef TARGET_LEGITIMATE_ADDRESS_P
23256 #define TARGET_LEGITIMATE_ADDRESS_P mips_legitimate_address_p
23258 #undef TARGET_FRAME_POINTER_REQUIRED
23259 #define TARGET_FRAME_POINTER_REQUIRED mips_frame_pointer_required
23261 #undef TARGET_CAN_ELIMINATE
23262 #define TARGET_CAN_ELIMINATE mips_can_eliminate
23264 #undef TARGET_CONDITIONAL_REGISTER_USAGE
23265 #define TARGET_CONDITIONAL_REGISTER_USAGE mips_conditional_register_usage
23267 #undef TARGET_TRAMPOLINE_INIT
23268 #define TARGET_TRAMPOLINE_INIT mips_trampoline_init
23270 #undef TARGET_ASM_OUTPUT_SOURCE_FILENAME
23271 #define TARGET_ASM_OUTPUT_SOURCE_FILENAME mips_output_filename
23273 #undef TARGET_SHIFT_TRUNCATION_MASK
23274 #define TARGET_SHIFT_TRUNCATION_MASK mips_shift_truncation_mask
23276 #undef TARGET_PREPARE_PCH_SAVE
23277 #define TARGET_PREPARE_PCH_SAVE mips_prepare_pch_save
23279 #undef TARGET_VECTORIZE_VEC_PERM_CONST
23280 #define TARGET_VECTORIZE_VEC_PERM_CONST mips_vectorize_vec_perm_const
23282 #undef TARGET_SCHED_REASSOCIATION_WIDTH
23283 #define TARGET_SCHED_REASSOCIATION_WIDTH mips_sched_reassociation_width
23285 #undef TARGET_CASE_VALUES_THRESHOLD
23286 #define TARGET_CASE_VALUES_THRESHOLD mips_case_values_threshold
23288 #undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
23289 #define TARGET_ATOMIC_ASSIGN_EXPAND_FENV mips_atomic_assign_expand_fenv
23291 #undef TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS
23292 #define TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS true
23294 #undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
23295 #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
23296 mips_use_by_pieces_infrastructure_p
23298 #undef TARGET_SPILL_CLASS
23299 #define TARGET_SPILL_CLASS mips_spill_class
23300 #undef TARGET_LRA_P
23301 #define TARGET_LRA_P mips_lra_p
23302 #undef TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS
23303 #define TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS mips_ira_change_pseudo_allocno_class
23305 #undef TARGET_HARD_REGNO_SCRATCH_OK
23306 #define TARGET_HARD_REGNO_SCRATCH_OK mips_hard_regno_scratch_ok
23308 #undef TARGET_HARD_REGNO_NREGS
23309 #define TARGET_HARD_REGNO_NREGS mips_hard_regno_nregs
23310 #undef TARGET_HARD_REGNO_MODE_OK
23311 #define TARGET_HARD_REGNO_MODE_OK mips_hard_regno_mode_ok
23313 #undef TARGET_MODES_TIEABLE_P
23314 #define TARGET_MODES_TIEABLE_P mips_modes_tieable_p
23316 #undef TARGET_HARD_REGNO_CALL_PART_CLOBBERED
23317 #define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \
23318 mips_hard_regno_call_part_clobbered
23320 /* The architecture reserves bit 0 for MIPS16 so use bit 1 for descriptors. */
23321 #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
23322 #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 2
23324 #undef TARGET_SECONDARY_MEMORY_NEEDED
23325 #define TARGET_SECONDARY_MEMORY_NEEDED mips_secondary_memory_needed
23327 #undef TARGET_CAN_CHANGE_MODE_CLASS
23328 #define TARGET_CAN_CHANGE_MODE_CLASS mips_can_change_mode_class
23330 #undef TARGET_TRULY_NOOP_TRUNCATION
23331 #define TARGET_TRULY_NOOP_TRUNCATION mips_truly_noop_truncation
23333 #undef TARGET_CONSTANT_ALIGNMENT
23334 #define TARGET_CONSTANT_ALIGNMENT mips_constant_alignment
23336 #undef TARGET_ASAN_SHADOW_OFFSET
23337 #define TARGET_ASAN_SHADOW_OFFSET mips_asan_shadow_offset
23339 #undef TARGET_STARTING_FRAME_OFFSET
23340 #define TARGET_STARTING_FRAME_OFFSET mips_starting_frame_offset
23342 #undef TARGET_ASM_FILE_END
23343 #define TARGET_ASM_FILE_END mips_asm_file_end
23346 struct gcc_target targetm = TARGET_INITIALIZER;
23348 #include "gt-mips.h"