1 /* Subroutines used for MIPS code generation.
2 Copyright (C) 1989-2018 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)
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
28 #include "coretypes.h"
38 #include "stringpool.h"
45 #include "diagnostic.h"
46 #include "insn-attr.h"
49 #include "fold-const.h"
51 #include "stor-layout.h"
57 #include "common/common-target.h"
58 #include "langhooks.h"
61 #include "sched-int.h"
63 #include "target-globals.h"
64 #include "tree-pass.h"
69 /* This file should be included last. */
70 #include "target-def.h"
72 /* True if X is an UNSPEC wrapper around a SYMBOL_REF or LABEL_REF. */
73 #define UNSPEC_ADDRESS_P(X) \
74 (GET_CODE (X) == UNSPEC \
75 && XINT (X, 1) >= UNSPEC_ADDRESS_FIRST \
76 && XINT (X, 1) < UNSPEC_ADDRESS_FIRST + NUM_SYMBOL_TYPES)
78 /* Extract the symbol or label from UNSPEC wrapper X. */
79 #define UNSPEC_ADDRESS(X) \
82 /* Extract the symbol type from UNSPEC wrapper X. */
83 #define UNSPEC_ADDRESS_TYPE(X) \
84 ((enum mips_symbol_type) (XINT (X, 1) - UNSPEC_ADDRESS_FIRST))
86 /* The maximum distance between the top of the stack frame and the
87 value $sp has when we save and restore registers.
89 The value for normal-mode code must be a SMALL_OPERAND and must
90 preserve the maximum stack alignment. We therefore use a value
91 of 0x7ff0 in this case.
93 microMIPS LWM and SWM support 12-bit offsets (from -0x800 to 0x7ff),
94 so we use a maximum of 0x7f0 for TARGET_MICROMIPS.
96 MIPS16e SAVE and RESTORE instructions can adjust the stack pointer by
97 up to 0x7f8 bytes and can usually save or restore all the registers
98 that we need to save or restore. (Note that we can only use these
99 instructions for o32, for which the stack alignment is 8 bytes.)
101 We use a maximum gap of 0x100 or 0x400 for MIPS16 code when SAVE and
102 RESTORE are not available. We can then use unextended instructions
103 to save and restore registers, and to allocate and deallocate the top
104 part of the frame. */
105 #define MIPS_MAX_FIRST_STACK_STEP \
106 (!TARGET_COMPRESSION ? 0x7ff0 \
107 : TARGET_MICROMIPS || GENERATE_MIPS16E_SAVE_RESTORE ? 0x7f8 \
108 : TARGET_64BIT ? 0x100 : 0x400)
110 /* True if INSN is a mips.md pattern or asm statement. */
111 /* ??? This test exists through the compiler, perhaps it should be
113 #define USEFUL_INSN_P(INSN) \
114 (NONDEBUG_INSN_P (INSN) \
115 && GET_CODE (PATTERN (INSN)) != USE \
116 && GET_CODE (PATTERN (INSN)) != CLOBBER)
118 /* If INSN is a delayed branch sequence, return the first instruction
119 in the sequence, otherwise return INSN itself. */
120 #define SEQ_BEGIN(INSN) \
121 (INSN_P (INSN) && GET_CODE (PATTERN (INSN)) == SEQUENCE \
122 ? as_a <rtx_insn *> (XVECEXP (PATTERN (INSN), 0, 0)) \
125 /* Likewise for the last instruction in a delayed branch sequence. */
126 #define SEQ_END(INSN) \
127 (INSN_P (INSN) && GET_CODE (PATTERN (INSN)) == SEQUENCE \
128 ? as_a <rtx_insn *> (XVECEXP (PATTERN (INSN), \
130 XVECLEN (PATTERN (INSN), 0) - 1)) \
133 /* Execute the following loop body with SUBINSN set to each instruction
134 between SEQ_BEGIN (INSN) and SEQ_END (INSN) inclusive. */
135 #define FOR_EACH_SUBINSN(SUBINSN, INSN) \
136 for ((SUBINSN) = SEQ_BEGIN (INSN); \
137 (SUBINSN) != NEXT_INSN (SEQ_END (INSN)); \
138 (SUBINSN) = NEXT_INSN (SUBINSN))
140 /* True if bit BIT is set in VALUE. */
141 #define BITSET_P(VALUE, BIT) (((VALUE) & (1 << (BIT))) != 0)
143 /* Return the opcode for a ptr_mode load of the form:
145 l[wd] DEST, OFFSET(BASE). */
146 #define MIPS_LOAD_PTR(DEST, OFFSET, BASE) \
147 (((ptr_mode == DImode ? 0x37 : 0x23) << 26) \
152 /* Return the opcode to move register SRC into register DEST. */
153 #define MIPS_MOVE(DEST, SRC) \
154 ((TARGET_64BIT ? 0x2d : 0x21) \
158 /* Return the opcode for:
161 #define MIPS_LUI(DEST, VALUE) \
162 ((0xf << 26) | ((DEST) << 16) | (VALUE))
164 /* Return the opcode to jump to register DEST. When the JR opcode is not
165 available use JALR $0, DEST. */
166 #define MIPS_JR(DEST) \
167 (TARGET_CB_ALWAYS ? ((0x1b << 27) | ((DEST) << 16)) \
168 : (((DEST) << 21) | (ISA_HAS_JR ? 0x8 : 0x9)))
170 /* Return the opcode for:
172 bal . + (1 + OFFSET) * 4. */
173 #define MIPS_BAL(OFFSET) \
174 ((0x1 << 26) | (0x11 << 16) | (OFFSET))
176 /* Return the usual opcode for a nop. */
179 /* Classifies an address.
182 A natural register + offset address. The register satisfies
183 mips_valid_base_register_p and the offset is a const_arith_operand.
186 A LO_SUM rtx. The first operand is a valid base register and
187 the second operand is a symbolic address.
190 A signed 16-bit constant address.
193 A constant symbolic address. */
194 enum mips_address_type
{
201 /* Classifies an unconditional branch of interest for the P6600. */
203 enum mips_ucbranch_type
205 /* May not even be a branch. */
211 /* Macros to create an enumeration identifier for a function prototype. */
212 #define MIPS_FTYPE_NAME1(A, B) MIPS_##A##_FTYPE_##B
213 #define MIPS_FTYPE_NAME2(A, B, C) MIPS_##A##_FTYPE_##B##_##C
214 #define MIPS_FTYPE_NAME3(A, B, C, D) MIPS_##A##_FTYPE_##B##_##C##_##D
215 #define MIPS_FTYPE_NAME4(A, B, C, D, E) MIPS_##A##_FTYPE_##B##_##C##_##D##_##E
217 /* Classifies the prototype of a built-in function. */
218 enum mips_function_type
{
219 #define DEF_MIPS_FTYPE(NARGS, LIST) MIPS_FTYPE_NAME##NARGS LIST,
220 #include "config/mips/mips-ftypes.def"
221 #undef DEF_MIPS_FTYPE
225 /* Specifies how a built-in function should be converted into rtl. */
226 enum mips_builtin_type
{
227 /* The function corresponds directly to an .md pattern. The return
228 value is mapped to operand 0 and the arguments are mapped to
229 operands 1 and above. */
232 /* The function corresponds directly to an .md pattern. There is no return
233 value and the arguments are mapped to operands 0 and above. */
234 MIPS_BUILTIN_DIRECT_NO_TARGET
,
236 /* The function corresponds to a comparison instruction followed by
237 a mips_cond_move_tf_ps pattern. The first two arguments are the
238 values to compare and the second two arguments are the vector
239 operands for the movt.ps or movf.ps instruction (in assembly order). */
243 /* The function corresponds to a V2SF comparison instruction. Operand 0
244 of this instruction is the result of the comparison, which has mode
245 CCV2 or CCV4. The function arguments are mapped to operands 1 and
246 above. The function's return value is an SImode boolean that is
247 true under the following conditions:
249 MIPS_BUILTIN_CMP_ANY: one of the registers is true
250 MIPS_BUILTIN_CMP_ALL: all of the registers are true
251 MIPS_BUILTIN_CMP_LOWER: the first register is true
252 MIPS_BUILTIN_CMP_UPPER: the second register is true. */
253 MIPS_BUILTIN_CMP_ANY
,
254 MIPS_BUILTIN_CMP_ALL
,
255 MIPS_BUILTIN_CMP_UPPER
,
256 MIPS_BUILTIN_CMP_LOWER
,
258 /* As above, but the instruction only sets a single $fcc register. */
259 MIPS_BUILTIN_CMP_SINGLE
,
261 /* The function corresponds to an MSA conditional branch instruction
262 combined with a compare instruction. */
263 MIPS_BUILTIN_MSA_TEST_BRANCH
,
265 /* For generating bposge32 branch instructions in MIPS32 DSP ASE. */
266 MIPS_BUILTIN_BPOSGE32
269 /* Invoke MACRO (COND) for each C.cond.fmt condition. */
270 #define MIPS_FP_CONDITIONS(MACRO) \
288 /* Enumerates the codes above as MIPS_FP_COND_<X>. */
289 #define DECLARE_MIPS_COND(X) MIPS_FP_COND_ ## X
290 enum mips_fp_condition
{
291 MIPS_FP_CONDITIONS (DECLARE_MIPS_COND
)
293 #undef DECLARE_MIPS_COND
295 /* Index X provides the string representation of MIPS_FP_COND_<X>. */
296 #define STRINGIFY(X) #X
297 static const char *const mips_fp_conditions
[] = {
298 MIPS_FP_CONDITIONS (STRINGIFY
)
302 /* A class used to control a comdat-style stub that we output in each
303 translation unit that needs it. */
304 class mips_one_only_stub
{
306 virtual ~mips_one_only_stub () {}
308 /* Return the name of the stub. */
309 virtual const char *get_name () = 0;
311 /* Output the body of the function to asm_out_file. */
312 virtual void output_body () = 0;
315 /* Tuning information that is automatically derived from other sources
316 (such as the scheduler). */
318 /* The architecture and tuning settings that this structure describes. */
322 /* True if this structure describes MIPS16 settings. */
325 /* True if the structure has been initialized. */
328 /* True if "MULT $0, $0" is preferable to "MTLO $0; MTHI $0"
329 when optimizing for speed. */
330 bool fast_mult_zero_zero_p
;
333 /* Information about a single argument. */
334 struct mips_arg_info
{
335 /* True if the argument is passed in a floating-point register, or
336 would have been if we hadn't run out of registers. */
339 /* The number of words passed in registers, rounded up. */
340 unsigned int reg_words
;
342 /* For EABI, the offset of the first register from GP_ARG_FIRST or
343 FP_ARG_FIRST. For other ABIs, the offset of the first register from
344 the start of the ABI's argument structure (see the CUMULATIVE_ARGS
345 comment for details).
347 The value is MAX_ARGS_IN_REGISTERS if the argument is passed entirely
349 unsigned int reg_offset
;
351 /* The number of words that must be passed on the stack, rounded up. */
352 unsigned int stack_words
;
354 /* The offset from the start of the stack overflow area of the argument's
355 first stack word. Only meaningful when STACK_WORDS is nonzero. */
356 unsigned int stack_offset
;
359 /* Information about an address described by mips_address_type.
365 REG is the base register and OFFSET is the constant offset.
368 REG and OFFSET are the operands to the LO_SUM and SYMBOL_TYPE
369 is the type of symbol it references.
372 SYMBOL_TYPE is the type of symbol that the address references. */
373 struct mips_address_info
{
374 enum mips_address_type type
;
377 enum mips_symbol_type symbol_type
;
380 /* One stage in a constant building sequence. These sequences have
384 A = A CODE[1] VALUE[1]
385 A = A CODE[2] VALUE[2]
388 where A is an accumulator, each CODE[i] is a binary rtl operation
389 and each VALUE[i] is a constant integer. CODE[0] is undefined. */
390 struct mips_integer_op
{
392 unsigned HOST_WIDE_INT value
;
395 /* The largest number of operations needed to load an integer constant.
396 The worst accepted case for 64-bit constants is LUI,ORI,SLL,ORI,SLL,ORI.
397 When the lowest bit is clear, we can try, but reject a sequence with
398 an extra SLL at the end. */
399 #define MIPS_MAX_INTEGER_OPS 7
401 /* Information about a MIPS16e SAVE or RESTORE instruction. */
402 struct mips16e_save_restore_info
{
403 /* The number of argument registers saved by a SAVE instruction.
404 0 for RESTORE instructions. */
407 /* Bit X is set if the instruction saves or restores GPR X. */
410 /* The total number of bytes to allocate. */
414 /* Costs of various operations on the different architectures. */
416 struct mips_rtx_cost_data
418 unsigned short fp_add
;
419 unsigned short fp_mult_sf
;
420 unsigned short fp_mult_df
;
421 unsigned short fp_div_sf
;
422 unsigned short fp_div_df
;
423 unsigned short int_mult_si
;
424 unsigned short int_mult_di
;
425 unsigned short int_div_si
;
426 unsigned short int_div_di
;
427 unsigned short branch_cost
;
428 unsigned short memory_latency
;
431 /* Global variables for machine-dependent things. */
433 /* The -G setting, or the configuration's default small-data limit if
434 no -G option is given. */
435 static unsigned int mips_small_data_threshold
;
437 /* The number of file directives written by mips_output_filename. */
438 int num_source_filenames
;
440 /* The name that appeared in the last .file directive written by
441 mips_output_filename, or "" if mips_output_filename hasn't
442 written anything yet. */
443 const char *current_function_file
= "";
445 /* Arrays that map GCC register numbers to debugger register numbers. */
446 int mips_dbx_regno
[FIRST_PSEUDO_REGISTER
];
447 int mips_dwarf_regno
[FIRST_PSEUDO_REGISTER
];
449 /* Information about the current function's epilogue, used only while
452 /* A list of queued REG_CFA_RESTORE notes. */
455 /* The CFA is currently defined as CFA_REG + CFA_OFFSET. */
457 HOST_WIDE_INT cfa_offset
;
459 /* The offset of the CFA from the stack pointer while restoring
461 HOST_WIDE_INT cfa_restore_sp_offset
;
464 /* The nesting depth of the PRINT_OPERAND '%(', '%<' and '%[' constructs. */
465 struct mips_asm_switch mips_noreorder
= { "reorder", 0 };
466 struct mips_asm_switch mips_nomacro
= { "macro", 0 };
467 struct mips_asm_switch mips_noat
= { "at", 0 };
469 /* True if we're writing out a branch-likely instruction rather than a
471 static bool mips_branch_likely
;
473 /* The current instruction-set architecture. */
474 enum processor mips_arch
;
475 const struct mips_cpu_info
*mips_arch_info
;
477 /* The processor that we should tune the code for. */
478 enum processor mips_tune
;
479 const struct mips_cpu_info
*mips_tune_info
;
481 /* The ISA level associated with mips_arch. */
484 /* The ISA revision level. This is 0 for MIPS I to V and N for
488 /* The architecture selected by -mipsN, or null if -mipsN wasn't used. */
489 static const struct mips_cpu_info
*mips_isa_option_info
;
491 /* Which cost information to use. */
492 static const struct mips_rtx_cost_data
*mips_cost
;
494 /* The ambient target flags, excluding MASK_MIPS16. */
495 static int mips_base_target_flags
;
497 /* The default compression mode. */
498 unsigned int mips_base_compression_flags
;
500 /* The ambient values of other global variables. */
501 static int mips_base_schedule_insns
; /* flag_schedule_insns */
502 static int mips_base_reorder_blocks_and_partition
; /* flag_reorder... */
503 static int mips_base_move_loop_invariants
; /* flag_move_loop_invariants */
504 static const char *mips_base_align_loops
; /* align_loops */
505 static const char *mips_base_align_jumps
; /* align_jumps */
506 static const char *mips_base_align_functions
; /* align_functions */
508 /* Index [M][R] is true if register R is allowed to hold a value of mode M. */
509 static bool mips_hard_regno_mode_ok_p
[MAX_MACHINE_MODE
][FIRST_PSEUDO_REGISTER
];
511 /* Index C is true if character C is a valid PRINT_OPERAND punctation
513 static bool mips_print_operand_punct
[256];
515 static GTY (()) int mips_output_filename_first_time
= 1;
517 /* mips_split_p[X] is true if symbols of type X can be split by
518 mips_split_symbol. */
519 bool mips_split_p
[NUM_SYMBOL_TYPES
];
521 /* mips_split_hi_p[X] is true if the high parts of symbols of type X
522 can be split by mips_split_symbol. */
523 bool mips_split_hi_p
[NUM_SYMBOL_TYPES
];
525 /* mips_use_pcrel_pool_p[X] is true if symbols of type X should be
526 forced into a PC-relative constant pool. */
527 bool mips_use_pcrel_pool_p
[NUM_SYMBOL_TYPES
];
529 /* mips_lo_relocs[X] is the relocation to use when a symbol of type X
530 appears in a LO_SUM. It can be null if such LO_SUMs aren't valid or
531 if they are matched by a special .md file pattern. */
532 const char *mips_lo_relocs
[NUM_SYMBOL_TYPES
];
534 /* Likewise for HIGHs. */
535 const char *mips_hi_relocs
[NUM_SYMBOL_TYPES
];
537 /* Target state for MIPS16. */
538 struct target_globals
*mips16_globals
;
540 /* Target state for MICROMIPS. */
541 struct target_globals
*micromips_globals
;
543 /* Cached value of can_issue_more. This is cached in mips_variable_issue hook
544 and returned from mips_sched_reorder2. */
545 static int cached_can_issue_more
;
547 /* The stubs for various MIPS16 support functions, if used. */
548 static mips_one_only_stub
*mips16_rdhwr_stub
;
549 static mips_one_only_stub
*mips16_get_fcsr_stub
;
550 static mips_one_only_stub
*mips16_set_fcsr_stub
;
552 /* Index R is the smallest register class that contains register R. */
553 const enum reg_class mips_regno_to_class
[FIRST_PSEUDO_REGISTER
] = {
554 LEA_REGS
, LEA_REGS
, M16_STORE_REGS
, V1_REG
,
555 M16_STORE_REGS
, M16_STORE_REGS
, M16_STORE_REGS
, M16_STORE_REGS
,
556 LEA_REGS
, LEA_REGS
, LEA_REGS
, LEA_REGS
,
557 LEA_REGS
, LEA_REGS
, LEA_REGS
, LEA_REGS
,
558 M16_REGS
, M16_STORE_REGS
, LEA_REGS
, LEA_REGS
,
559 LEA_REGS
, LEA_REGS
, LEA_REGS
, LEA_REGS
,
560 T_REG
, PIC_FN_ADDR_REG
, LEA_REGS
, LEA_REGS
,
561 LEA_REGS
, M16_SP_REGS
, LEA_REGS
, LEA_REGS
,
563 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
564 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
565 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
566 FP_REGS
, FP_REGS
, FP_REGS
, FP_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 MD0_REG
, MD1_REG
, NO_REGS
, ST_REGS
,
572 ST_REGS
, ST_REGS
, ST_REGS
, ST_REGS
,
573 ST_REGS
, ST_REGS
, ST_REGS
, NO_REGS
,
574 NO_REGS
, FRAME_REGS
, FRAME_REGS
, NO_REGS
,
575 COP0_REGS
, COP0_REGS
, COP0_REGS
, COP0_REGS
,
576 COP0_REGS
, COP0_REGS
, COP0_REGS
, COP0_REGS
,
577 COP0_REGS
, COP0_REGS
, COP0_REGS
, COP0_REGS
,
578 COP0_REGS
, COP0_REGS
, COP0_REGS
, COP0_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 COP2_REGS
, COP2_REGS
, COP2_REGS
, COP2_REGS
,
584 COP2_REGS
, COP2_REGS
, COP2_REGS
, COP2_REGS
,
585 COP2_REGS
, COP2_REGS
, COP2_REGS
, COP2_REGS
,
586 COP2_REGS
, COP2_REGS
, COP2_REGS
, COP2_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 COP3_REGS
, COP3_REGS
, COP3_REGS
, COP3_REGS
,
592 COP3_REGS
, COP3_REGS
, COP3_REGS
, COP3_REGS
,
593 COP3_REGS
, COP3_REGS
, COP3_REGS
, COP3_REGS
,
594 COP3_REGS
, COP3_REGS
, COP3_REGS
, COP3_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 DSP_ACC_REGS
, DSP_ACC_REGS
, DSP_ACC_REGS
, DSP_ACC_REGS
,
600 DSP_ACC_REGS
, DSP_ACC_REGS
, ALL_REGS
, ALL_REGS
,
601 ALL_REGS
, ALL_REGS
, ALL_REGS
, ALL_REGS
604 static tree
mips_handle_interrupt_attr (tree
*, tree
, tree
, int, bool *);
605 static tree
mips_handle_use_shadow_register_set_attr (tree
*, tree
, tree
, int,
608 /* The value of TARGET_ATTRIBUTE_TABLE. */
609 static const struct attribute_spec mips_attribute_table
[] = {
610 /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
611 affects_type_identity, handler, exclude } */
612 { "long_call", 0, 0, false, true, true, false, NULL
, NULL
},
613 { "short_call", 0, 0, false, true, true, false, NULL
, NULL
},
614 { "far", 0, 0, false, true, true, false, NULL
, NULL
},
615 { "near", 0, 0, false, true, true, false, NULL
, NULL
},
616 /* We would really like to treat "mips16" and "nomips16" as type
617 attributes, but GCC doesn't provide the hooks we need to support
618 the right conversion rules. As declaration attributes, they affect
619 code generation but don't carry other semantics. */
620 { "mips16", 0, 0, true, false, false, false, NULL
, NULL
},
621 { "nomips16", 0, 0, true, false, false, false, NULL
, NULL
},
622 { "micromips", 0, 0, true, false, false, false, NULL
, NULL
},
623 { "nomicromips", 0, 0, true, false, false, false, NULL
, NULL
},
624 { "nocompression", 0, 0, true, false, false, false, NULL
, NULL
},
625 /* Allow functions to be specified as interrupt handlers */
626 { "interrupt", 0, 1, false, true, true, false, mips_handle_interrupt_attr
,
628 { "use_shadow_register_set", 0, 1, false, true, true, false,
629 mips_handle_use_shadow_register_set_attr
, NULL
},
630 { "keep_interrupts_masked", 0, 0, false, true, true, false, NULL
, NULL
},
631 { "use_debug_exception_return", 0, 0, false, true, true, false, NULL
, NULL
},
632 { NULL
, 0, 0, false, false, false, false, NULL
, NULL
}
635 /* A table describing all the processors GCC knows about; see
636 mips-cpus.def for details. */
637 static const struct mips_cpu_info mips_cpu_info_table
[] = {
638 #define MIPS_CPU(NAME, CPU, ISA, FLAGS) \
639 { NAME, CPU, ISA, FLAGS },
640 #include "mips-cpus.def"
644 /* Default costs. If these are used for a processor we should look
645 up the actual costs. */
646 #define DEFAULT_COSTS COSTS_N_INSNS (6), /* fp_add */ \
647 COSTS_N_INSNS (7), /* fp_mult_sf */ \
648 COSTS_N_INSNS (8), /* fp_mult_df */ \
649 COSTS_N_INSNS (23), /* fp_div_sf */ \
650 COSTS_N_INSNS (36), /* fp_div_df */ \
651 COSTS_N_INSNS (10), /* int_mult_si */ \
652 COSTS_N_INSNS (10), /* int_mult_di */ \
653 COSTS_N_INSNS (69), /* int_div_si */ \
654 COSTS_N_INSNS (69), /* int_div_di */ \
655 2, /* branch_cost */ \
656 4 /* memory_latency */
658 /* Floating-point costs for processors without an FPU. Just assume that
659 all floating-point libcalls are very expensive. */
660 #define SOFT_FP_COSTS COSTS_N_INSNS (256), /* fp_add */ \
661 COSTS_N_INSNS (256), /* fp_mult_sf */ \
662 COSTS_N_INSNS (256), /* fp_mult_df */ \
663 COSTS_N_INSNS (256), /* fp_div_sf */ \
664 COSTS_N_INSNS (256) /* fp_div_df */
666 /* Costs to use when optimizing for size. */
667 static const struct mips_rtx_cost_data mips_rtx_cost_optimize_size
= {
668 COSTS_N_INSNS (1), /* fp_add */
669 COSTS_N_INSNS (1), /* fp_mult_sf */
670 COSTS_N_INSNS (1), /* fp_mult_df */
671 COSTS_N_INSNS (1), /* fp_div_sf */
672 COSTS_N_INSNS (1), /* fp_div_df */
673 COSTS_N_INSNS (1), /* int_mult_si */
674 COSTS_N_INSNS (1), /* int_mult_di */
675 COSTS_N_INSNS (1), /* int_div_si */
676 COSTS_N_INSNS (1), /* int_div_di */
678 4 /* memory_latency */
681 /* Costs to use when optimizing for speed, indexed by processor. */
682 static const struct mips_rtx_cost_data
683 mips_rtx_cost_data
[NUM_PROCESSOR_VALUES
] = {
685 COSTS_N_INSNS (2), /* fp_add */
686 COSTS_N_INSNS (4), /* fp_mult_sf */
687 COSTS_N_INSNS (5), /* fp_mult_df */
688 COSTS_N_INSNS (12), /* fp_div_sf */
689 COSTS_N_INSNS (19), /* fp_div_df */
690 COSTS_N_INSNS (12), /* int_mult_si */
691 COSTS_N_INSNS (12), /* int_mult_di */
692 COSTS_N_INSNS (35), /* int_div_si */
693 COSTS_N_INSNS (35), /* int_div_di */
695 4 /* memory_latency */
699 COSTS_N_INSNS (6), /* int_mult_si */
700 COSTS_N_INSNS (6), /* int_mult_di */
701 COSTS_N_INSNS (36), /* int_div_si */
702 COSTS_N_INSNS (36), /* int_div_di */
704 4 /* memory_latency */
708 COSTS_N_INSNS (36), /* int_mult_si */
709 COSTS_N_INSNS (36), /* int_mult_di */
710 COSTS_N_INSNS (37), /* int_div_si */
711 COSTS_N_INSNS (37), /* int_div_di */
713 4 /* memory_latency */
717 COSTS_N_INSNS (4), /* int_mult_si */
718 COSTS_N_INSNS (11), /* int_mult_di */
719 COSTS_N_INSNS (36), /* int_div_si */
720 COSTS_N_INSNS (68), /* int_div_di */
722 4 /* memory_latency */
725 COSTS_N_INSNS (4), /* fp_add */
726 COSTS_N_INSNS (4), /* fp_mult_sf */
727 COSTS_N_INSNS (5), /* fp_mult_df */
728 COSTS_N_INSNS (17), /* fp_div_sf */
729 COSTS_N_INSNS (32), /* fp_div_df */
730 COSTS_N_INSNS (4), /* int_mult_si */
731 COSTS_N_INSNS (11), /* int_mult_di */
732 COSTS_N_INSNS (36), /* int_div_si */
733 COSTS_N_INSNS (68), /* int_div_di */
735 4 /* memory_latency */
738 COSTS_N_INSNS (4), /* fp_add */
739 COSTS_N_INSNS (4), /* fp_mult_sf */
740 COSTS_N_INSNS (5), /* fp_mult_df */
741 COSTS_N_INSNS (17), /* fp_div_sf */
742 COSTS_N_INSNS (32), /* fp_div_df */
743 COSTS_N_INSNS (4), /* int_mult_si */
744 COSTS_N_INSNS (7), /* int_mult_di */
745 COSTS_N_INSNS (42), /* int_div_si */
746 COSTS_N_INSNS (72), /* int_div_di */
748 4 /* memory_latency */
752 COSTS_N_INSNS (5), /* int_mult_si */
753 COSTS_N_INSNS (5), /* int_mult_di */
754 COSTS_N_INSNS (41), /* int_div_si */
755 COSTS_N_INSNS (41), /* int_div_di */
757 4 /* memory_latency */
760 COSTS_N_INSNS (8), /* fp_add */
761 COSTS_N_INSNS (8), /* fp_mult_sf */
762 COSTS_N_INSNS (10), /* fp_mult_df */
763 COSTS_N_INSNS (34), /* fp_div_sf */
764 COSTS_N_INSNS (64), /* fp_div_df */
765 COSTS_N_INSNS (5), /* int_mult_si */
766 COSTS_N_INSNS (5), /* int_mult_di */
767 COSTS_N_INSNS (41), /* int_div_si */
768 COSTS_N_INSNS (41), /* int_div_di */
770 4 /* memory_latency */
773 COSTS_N_INSNS (4), /* fp_add */
774 COSTS_N_INSNS (4), /* fp_mult_sf */
775 COSTS_N_INSNS (5), /* fp_mult_df */
776 COSTS_N_INSNS (17), /* fp_div_sf */
777 COSTS_N_INSNS (32), /* fp_div_df */
778 COSTS_N_INSNS (5), /* int_mult_si */
779 COSTS_N_INSNS (5), /* int_mult_di */
780 COSTS_N_INSNS (41), /* int_div_si */
781 COSTS_N_INSNS (41), /* int_div_di */
783 4 /* memory_latency */
787 COSTS_N_INSNS (5), /* int_mult_si */
788 COSTS_N_INSNS (5), /* int_mult_di */
789 COSTS_N_INSNS (41), /* int_div_si */
790 COSTS_N_INSNS (41), /* int_div_di */
792 4 /* memory_latency */
795 COSTS_N_INSNS (8), /* fp_add */
796 COSTS_N_INSNS (8), /* fp_mult_sf */
797 COSTS_N_INSNS (10), /* fp_mult_df */
798 COSTS_N_INSNS (34), /* fp_div_sf */
799 COSTS_N_INSNS (64), /* fp_div_df */
800 COSTS_N_INSNS (5), /* int_mult_si */
801 COSTS_N_INSNS (5), /* int_mult_di */
802 COSTS_N_INSNS (41), /* int_div_si */
803 COSTS_N_INSNS (41), /* int_div_di */
805 4 /* memory_latency */
808 COSTS_N_INSNS (4), /* fp_add */
809 COSTS_N_INSNS (4), /* fp_mult_sf */
810 COSTS_N_INSNS (5), /* fp_mult_df */
811 COSTS_N_INSNS (17), /* fp_div_sf */
812 COSTS_N_INSNS (32), /* fp_div_df */
813 COSTS_N_INSNS (5), /* int_mult_si */
814 COSTS_N_INSNS (5), /* int_mult_di */
815 COSTS_N_INSNS (41), /* int_div_si */
816 COSTS_N_INSNS (41), /* int_div_di */
818 4 /* memory_latency */
821 COSTS_N_INSNS (6), /* fp_add */
822 COSTS_N_INSNS (6), /* fp_mult_sf */
823 COSTS_N_INSNS (7), /* fp_mult_df */
824 COSTS_N_INSNS (25), /* fp_div_sf */
825 COSTS_N_INSNS (48), /* fp_div_df */
826 COSTS_N_INSNS (5), /* int_mult_si */
827 COSTS_N_INSNS (5), /* int_mult_di */
828 COSTS_N_INSNS (41), /* int_div_si */
829 COSTS_N_INSNS (41), /* int_div_di */
831 4 /* memory_latency */
848 COSTS_N_INSNS (5), /* int_mult_si */
849 COSTS_N_INSNS (5), /* int_mult_di */
850 COSTS_N_INSNS (72), /* int_div_si */
851 COSTS_N_INSNS (72), /* int_div_di */
853 4 /* memory_latency */
858 COSTS_N_INSNS (6), /* int_mult_si */
859 COSTS_N_INSNS (6), /* int_mult_di */
860 COSTS_N_INSNS (18), /* int_div_si */
861 COSTS_N_INSNS (35), /* int_div_di */
863 4 /* memory_latency */
867 COSTS_N_INSNS (6), /* fp_add */
868 COSTS_N_INSNS (6), /* fp_mult_sf */
869 COSTS_N_INSNS (7), /* fp_mult_df */
870 COSTS_N_INSNS (25), /* fp_div_sf */
871 COSTS_N_INSNS (48), /* fp_div_df */
872 COSTS_N_INSNS (6), /* int_mult_si */
873 COSTS_N_INSNS (6), /* int_mult_di */
874 COSTS_N_INSNS (18), /* int_div_si */
875 COSTS_N_INSNS (35), /* int_div_di */
877 4 /* memory_latency */
880 COSTS_N_INSNS (2), /* fp_add */
881 COSTS_N_INSNS (4), /* fp_mult_sf */
882 COSTS_N_INSNS (5), /* fp_mult_df */
883 COSTS_N_INSNS (12), /* fp_div_sf */
884 COSTS_N_INSNS (19), /* fp_div_df */
885 COSTS_N_INSNS (2), /* int_mult_si */
886 COSTS_N_INSNS (2), /* int_mult_di */
887 COSTS_N_INSNS (35), /* int_div_si */
888 COSTS_N_INSNS (35), /* int_div_di */
890 4 /* memory_latency */
893 COSTS_N_INSNS (3), /* fp_add */
894 COSTS_N_INSNS (5), /* fp_mult_sf */
895 COSTS_N_INSNS (6), /* fp_mult_df */
896 COSTS_N_INSNS (15), /* fp_div_sf */
897 COSTS_N_INSNS (16), /* fp_div_df */
898 COSTS_N_INSNS (17), /* int_mult_si */
899 COSTS_N_INSNS (17), /* int_mult_di */
900 COSTS_N_INSNS (38), /* int_div_si */
901 COSTS_N_INSNS (38), /* int_div_di */
903 6 /* memory_latency */
906 COSTS_N_INSNS (6), /* fp_add */
907 COSTS_N_INSNS (7), /* fp_mult_sf */
908 COSTS_N_INSNS (8), /* fp_mult_df */
909 COSTS_N_INSNS (23), /* fp_div_sf */
910 COSTS_N_INSNS (36), /* fp_div_df */
911 COSTS_N_INSNS (10), /* int_mult_si */
912 COSTS_N_INSNS (10), /* int_mult_di */
913 COSTS_N_INSNS (69), /* int_div_si */
914 COSTS_N_INSNS (69), /* int_div_di */
916 6 /* memory_latency */
928 /* The only costs that appear to be updated here are
929 integer multiplication. */
931 COSTS_N_INSNS (4), /* int_mult_si */
932 COSTS_N_INSNS (6), /* int_mult_di */
933 COSTS_N_INSNS (69), /* int_div_si */
934 COSTS_N_INSNS (69), /* int_div_di */
936 4 /* memory_latency */
951 COSTS_N_INSNS (6), /* fp_add */
952 COSTS_N_INSNS (4), /* fp_mult_sf */
953 COSTS_N_INSNS (5), /* fp_mult_df */
954 COSTS_N_INSNS (23), /* fp_div_sf */
955 COSTS_N_INSNS (36), /* fp_div_df */
956 COSTS_N_INSNS (5), /* int_mult_si */
957 COSTS_N_INSNS (5), /* int_mult_di */
958 COSTS_N_INSNS (36), /* int_div_si */
959 COSTS_N_INSNS (36), /* int_div_di */
961 4 /* memory_latency */
964 COSTS_N_INSNS (6), /* fp_add */
965 COSTS_N_INSNS (5), /* fp_mult_sf */
966 COSTS_N_INSNS (6), /* fp_mult_df */
967 COSTS_N_INSNS (30), /* fp_div_sf */
968 COSTS_N_INSNS (59), /* fp_div_df */
969 COSTS_N_INSNS (3), /* int_mult_si */
970 COSTS_N_INSNS (4), /* int_mult_di */
971 COSTS_N_INSNS (42), /* int_div_si */
972 COSTS_N_INSNS (74), /* int_div_di */
974 4 /* memory_latency */
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 (5), /* int_mult_si */
983 COSTS_N_INSNS (9), /* int_mult_di */
984 COSTS_N_INSNS (42), /* int_div_si */
985 COSTS_N_INSNS (74), /* int_div_di */
987 4 /* memory_latency */
990 COSTS_N_INSNS (4), /* fp_add */
991 COSTS_N_INSNS (4), /* fp_mult_sf */
992 COSTS_N_INSNS (256), /* fp_mult_df */
993 COSTS_N_INSNS (8), /* fp_div_sf */
994 COSTS_N_INSNS (256), /* fp_div_df */
995 COSTS_N_INSNS (4), /* int_mult_si */
996 COSTS_N_INSNS (256), /* int_mult_di */
997 COSTS_N_INSNS (37), /* int_div_si */
998 COSTS_N_INSNS (256), /* int_div_di */
1000 4 /* memory_latency */
1003 /* The only costs that are changed here are
1004 integer multiplication. */
1005 COSTS_N_INSNS (6), /* fp_add */
1006 COSTS_N_INSNS (7), /* fp_mult_sf */
1007 COSTS_N_INSNS (8), /* fp_mult_df */
1008 COSTS_N_INSNS (23), /* fp_div_sf */
1009 COSTS_N_INSNS (36), /* fp_div_df */
1010 COSTS_N_INSNS (5), /* int_mult_si */
1011 COSTS_N_INSNS (9), /* int_mult_di */
1012 COSTS_N_INSNS (69), /* int_div_si */
1013 COSTS_N_INSNS (69), /* int_div_di */
1014 1, /* branch_cost */
1015 4 /* memory_latency */
1021 /* The only costs that are changed here are
1022 integer multiplication. */
1023 COSTS_N_INSNS (6), /* fp_add */
1024 COSTS_N_INSNS (7), /* fp_mult_sf */
1025 COSTS_N_INSNS (8), /* fp_mult_df */
1026 COSTS_N_INSNS (23), /* fp_div_sf */
1027 COSTS_N_INSNS (36), /* fp_div_df */
1028 COSTS_N_INSNS (3), /* int_mult_si */
1029 COSTS_N_INSNS (8), /* int_mult_di */
1030 COSTS_N_INSNS (69), /* int_div_si */
1031 COSTS_N_INSNS (69), /* int_div_di */
1032 1, /* branch_cost */
1033 4 /* memory_latency */
1036 COSTS_N_INSNS (2), /* fp_add */
1037 COSTS_N_INSNS (2), /* fp_mult_sf */
1038 COSTS_N_INSNS (2), /* fp_mult_df */
1039 COSTS_N_INSNS (12), /* fp_div_sf */
1040 COSTS_N_INSNS (19), /* fp_div_df */
1041 COSTS_N_INSNS (5), /* int_mult_si */
1042 COSTS_N_INSNS (9), /* int_mult_di */
1043 COSTS_N_INSNS (34), /* int_div_si */
1044 COSTS_N_INSNS (66), /* int_div_di */
1045 1, /* branch_cost */
1046 4 /* memory_latency */
1049 /* These costs are the same as the SB-1A below. */
1050 COSTS_N_INSNS (4), /* fp_add */
1051 COSTS_N_INSNS (4), /* fp_mult_sf */
1052 COSTS_N_INSNS (4), /* fp_mult_df */
1053 COSTS_N_INSNS (24), /* fp_div_sf */
1054 COSTS_N_INSNS (32), /* fp_div_df */
1055 COSTS_N_INSNS (3), /* int_mult_si */
1056 COSTS_N_INSNS (4), /* int_mult_di */
1057 COSTS_N_INSNS (36), /* int_div_si */
1058 COSTS_N_INSNS (68), /* int_div_di */
1059 1, /* branch_cost */
1060 4 /* memory_latency */
1063 /* These costs are the same as the SB-1 above. */
1064 COSTS_N_INSNS (4), /* fp_add */
1065 COSTS_N_INSNS (4), /* fp_mult_sf */
1066 COSTS_N_INSNS (4), /* fp_mult_df */
1067 COSTS_N_INSNS (24), /* fp_div_sf */
1068 COSTS_N_INSNS (32), /* fp_div_df */
1069 COSTS_N_INSNS (3), /* int_mult_si */
1070 COSTS_N_INSNS (4), /* int_mult_di */
1071 COSTS_N_INSNS (36), /* int_div_si */
1072 COSTS_N_INSNS (68), /* int_div_di */
1073 1, /* branch_cost */
1074 4 /* memory_latency */
1081 COSTS_N_INSNS (8), /* int_mult_si */
1082 COSTS_N_INSNS (8), /* int_mult_di */
1083 COSTS_N_INSNS (72), /* int_div_si */
1084 COSTS_N_INSNS (72), /* int_div_di */
1085 1, /* branch_cost */
1086 4 /* memory_latency */
1089 /* These costs are the same as 5KF above. */
1090 COSTS_N_INSNS (4), /* fp_add */
1091 COSTS_N_INSNS (4), /* fp_mult_sf */
1092 COSTS_N_INSNS (5), /* fp_mult_df */
1093 COSTS_N_INSNS (17), /* fp_div_sf */
1094 COSTS_N_INSNS (32), /* fp_div_df */
1095 COSTS_N_INSNS (4), /* int_mult_si */
1096 COSTS_N_INSNS (11), /* int_mult_di */
1097 COSTS_N_INSNS (36), /* int_div_si */
1098 COSTS_N_INSNS (68), /* int_div_di */
1099 1, /* branch_cost */
1100 4 /* memory_latency */
1103 COSTS_N_INSNS (4), /* fp_add */
1104 COSTS_N_INSNS (5), /* fp_mult_sf */
1105 COSTS_N_INSNS (5), /* fp_mult_df */
1106 COSTS_N_INSNS (17), /* fp_div_sf */
1107 COSTS_N_INSNS (17), /* fp_div_df */
1108 COSTS_N_INSNS (5), /* int_mult_si */
1109 COSTS_N_INSNS (5), /* int_mult_di */
1110 COSTS_N_INSNS (8), /* int_div_si */
1111 COSTS_N_INSNS (8), /* int_div_di */
1112 2, /* branch_cost */
1113 4 /* memory_latency */
1116 COSTS_N_INSNS (4), /* fp_add */
1117 COSTS_N_INSNS (4), /* fp_mult_sf */
1118 COSTS_N_INSNS (5), /* fp_mult_df */
1119 COSTS_N_INSNS (17), /* fp_div_sf */
1120 COSTS_N_INSNS (32), /* fp_div_df */
1121 COSTS_N_INSNS (5), /* int_mult_si */
1122 COSTS_N_INSNS (5), /* int_mult_di */
1123 COSTS_N_INSNS (34), /* int_div_si */
1124 COSTS_N_INSNS (68), /* int_div_di */
1125 1, /* branch_cost */
1126 4 /* memory_latency */
1129 COSTS_N_INSNS (4), /* fp_add */
1130 COSTS_N_INSNS (5), /* fp_mult_sf */
1131 COSTS_N_INSNS (5), /* fp_mult_df */
1132 COSTS_N_INSNS (32), /* 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 (36), /* int_div_si */
1137 COSTS_N_INSNS (36), /* int_div_di */
1138 2, /* branch_cost */
1139 4 /* memory_latency */
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 (17), /* fp_div_sf */
1146 COSTS_N_INSNS (17), /* fp_div_df */
1147 COSTS_N_INSNS (5), /* int_mult_si */
1148 COSTS_N_INSNS (5), /* int_mult_di */
1149 COSTS_N_INSNS (8), /* int_div_si */
1150 COSTS_N_INSNS (8), /* int_div_di */
1151 2, /* branch_cost */
1152 4 /* memory_latency */
1156 static rtx
mips_find_pic_call_symbol (rtx_insn
*, rtx
, bool);
1157 static int mips_register_move_cost (machine_mode
, reg_class_t
,
1159 static unsigned int mips_function_arg_boundary (machine_mode
, const_tree
);
1160 static rtx
mips_gen_const_int_vector_shuffle (machine_mode
, int);
1162 /* This hash table keeps track of implicit "mips16" and "nomips16" attributes
1163 for -mflip_mips16. It maps decl names onto a boolean mode setting. */
1164 static GTY (()) hash_map
<nofree_string_hash
, bool> *mflip_mips16_htab
;
1166 /* True if -mflip-mips16 should next add an attribute for the default MIPS16
1167 mode, false if it should next add an attribute for the opposite mode. */
1168 static GTY(()) bool mips16_flipper
;
1170 /* DECL is a function that needs a default "mips16" or "nomips16" attribute
1171 for -mflip-mips16. Return true if it should use "mips16" and false if
1172 it should use "nomips16". */
1175 mflip_mips16_use_mips16_p (tree decl
)
1178 bool base_is_mips16
= (mips_base_compression_flags
& MASK_MIPS16
) != 0;
1180 /* Use the opposite of the command-line setting for anonymous decls. */
1181 if (!DECL_NAME (decl
))
1182 return !base_is_mips16
;
1184 if (!mflip_mips16_htab
)
1185 mflip_mips16_htab
= hash_map
<nofree_string_hash
, bool>::create_ggc (37);
1187 name
= IDENTIFIER_POINTER (DECL_NAME (decl
));
1190 bool *slot
= &mflip_mips16_htab
->get_or_insert (name
, &existed
);
1193 mips16_flipper
= !mips16_flipper
;
1194 *slot
= mips16_flipper
? !base_is_mips16
: base_is_mips16
;
1199 /* Predicates to test for presence of "near"/"short_call" and "far"/"long_call"
1200 attributes on the given TYPE. */
1203 mips_near_type_p (const_tree type
)
1205 return (lookup_attribute ("short_call", TYPE_ATTRIBUTES (type
)) != NULL
1206 || lookup_attribute ("near", TYPE_ATTRIBUTES (type
)) != NULL
);
1210 mips_far_type_p (const_tree type
)
1212 return (lookup_attribute ("long_call", TYPE_ATTRIBUTES (type
)) != NULL
1213 || lookup_attribute ("far", TYPE_ATTRIBUTES (type
)) != NULL
);
1217 /* Check if the interrupt attribute is set for a function. */
1220 mips_interrupt_type_p (tree type
)
1222 return lookup_attribute ("interrupt", TYPE_ATTRIBUTES (type
)) != NULL
;
1225 /* Return the mask for the "interrupt" attribute. */
1227 static enum mips_int_mask
1228 mips_interrupt_mask (tree type
)
1230 tree attr
= lookup_attribute ("interrupt", TYPE_ATTRIBUTES (type
));
1234 /* For missing attributes or no arguments then return 'eic' as a safe
1237 return INT_MASK_EIC
;
1239 args
= TREE_VALUE (attr
);
1242 return INT_MASK_EIC
;
1244 cst
= TREE_VALUE (args
);
1246 if (strcmp (TREE_STRING_POINTER (cst
), "eic") == 0)
1247 return INT_MASK_EIC
;
1249 /* The validation code in mips_handle_interrupt_attr guarantees that the
1250 argument is now in the form:
1251 vector=(sw0|sw1|hw0|hw1|hw2|hw3|hw4|hw5). */
1252 str
= TREE_STRING_POINTER (cst
);
1254 gcc_assert (strlen (str
) == strlen ("vector=sw0"));
1257 return (enum mips_int_mask
) (INT_MASK_SW0
+ (str
[9] - '0'));
1259 return (enum mips_int_mask
) (INT_MASK_HW0
+ (str
[9] - '0'));
1262 /* Return the mips_shadow_set if the "use_shadow_register_set" attribute is
1263 set for a function. */
1265 static enum mips_shadow_set
1266 mips_use_shadow_register_set (tree type
)
1268 tree attr
= lookup_attribute ("use_shadow_register_set",
1269 TYPE_ATTRIBUTES (type
));
1272 /* The validation code in mips_handle_use_shadow_register_set_attr guarantees
1273 that if an argument is present then it means: Assume the shadow register
1274 set has a valid stack pointer in it. */
1276 return SHADOW_SET_NO
;
1278 args
= TREE_VALUE (attr
);
1281 return SHADOW_SET_YES
;
1283 return SHADOW_SET_INTSTACK
;
1286 /* Check if the attribute to keep interrupts masked is set for a function. */
1289 mips_keep_interrupts_masked_p (tree type
)
1291 return lookup_attribute ("keep_interrupts_masked",
1292 TYPE_ATTRIBUTES (type
)) != NULL
;
1295 /* Check if the attribute to use debug exception return is set for
1299 mips_use_debug_exception_return_p (tree type
)
1301 return lookup_attribute ("use_debug_exception_return",
1302 TYPE_ATTRIBUTES (type
)) != NULL
;
1305 /* Return the set of compression modes that are explicitly required
1306 by the attributes in ATTRIBUTES. */
1309 mips_get_compress_on_flags (tree attributes
)
1311 unsigned int flags
= 0;
1313 if (lookup_attribute ("mips16", attributes
) != NULL
)
1314 flags
|= MASK_MIPS16
;
1316 if (lookup_attribute ("micromips", attributes
) != NULL
)
1317 flags
|= MASK_MICROMIPS
;
1322 /* Return the set of compression modes that are explicitly forbidden
1323 by the attributes in ATTRIBUTES. */
1326 mips_get_compress_off_flags (tree attributes
)
1328 unsigned int flags
= 0;
1330 if (lookup_attribute ("nocompression", attributes
) != NULL
)
1331 flags
|= MASK_MIPS16
| MASK_MICROMIPS
;
1333 if (lookup_attribute ("nomips16", attributes
) != NULL
)
1334 flags
|= MASK_MIPS16
;
1336 if (lookup_attribute ("nomicromips", attributes
) != NULL
)
1337 flags
|= MASK_MICROMIPS
;
1342 /* Return the compression mode that should be used for function DECL.
1343 Return the ambient setting if DECL is null. */
1346 mips_get_compress_mode (tree decl
)
1348 unsigned int flags
, force_on
;
1350 flags
= mips_base_compression_flags
;
1353 /* Nested functions must use the same frame pointer as their
1354 parent and must therefore use the same ISA mode. */
1355 tree parent
= decl_function_context (decl
);
1358 force_on
= mips_get_compress_on_flags (DECL_ATTRIBUTES (decl
));
1361 flags
&= ~mips_get_compress_off_flags (DECL_ATTRIBUTES (decl
));
1366 /* Return the attribute name associated with MASK_MIPS16 and MASK_MICROMIPS
1370 mips_get_compress_on_name (unsigned int flags
)
1372 if (flags
== MASK_MIPS16
)
1377 /* Return the attribute name that forbids MASK_MIPS16 and MASK_MICROMIPS
1381 mips_get_compress_off_name (unsigned int flags
)
1383 if (flags
== MASK_MIPS16
)
1385 if (flags
== MASK_MICROMIPS
)
1386 return "nomicromips";
1387 return "nocompression";
1390 /* Implement TARGET_COMP_TYPE_ATTRIBUTES. */
1393 mips_comp_type_attributes (const_tree type1
, const_tree type2
)
1395 /* Disallow mixed near/far attributes. */
1396 if (mips_far_type_p (type1
) && mips_near_type_p (type2
))
1398 if (mips_near_type_p (type1
) && mips_far_type_p (type2
))
1403 /* Implement TARGET_INSERT_ATTRIBUTES. */
1406 mips_insert_attributes (tree decl
, tree
*attributes
)
1409 unsigned int compression_flags
, nocompression_flags
;
1411 /* Check for "mips16" and "nomips16" attributes. */
1412 compression_flags
= mips_get_compress_on_flags (*attributes
);
1413 nocompression_flags
= mips_get_compress_off_flags (*attributes
);
1415 if (TREE_CODE (decl
) != FUNCTION_DECL
)
1417 if (nocompression_flags
)
1418 error ("%qs attribute only applies to functions",
1419 mips_get_compress_off_name (nocompression_flags
));
1421 if (compression_flags
)
1422 error ("%qs attribute only applies to functions",
1423 mips_get_compress_on_name (nocompression_flags
));
1427 compression_flags
|= mips_get_compress_on_flags (DECL_ATTRIBUTES (decl
));
1428 nocompression_flags
|=
1429 mips_get_compress_off_flags (DECL_ATTRIBUTES (decl
));
1431 if (compression_flags
&& nocompression_flags
)
1432 error ("%qE cannot have both %qs and %qs attributes",
1433 DECL_NAME (decl
), mips_get_compress_on_name (compression_flags
),
1434 mips_get_compress_off_name (nocompression_flags
));
1436 if (compression_flags
& MASK_MIPS16
1437 && compression_flags
& MASK_MICROMIPS
)
1438 error ("%qE cannot have both %qs and %qs attributes",
1439 DECL_NAME (decl
), "mips16", "micromips");
1441 if (TARGET_FLIP_MIPS16
1442 && !DECL_ARTIFICIAL (decl
)
1443 && compression_flags
== 0
1444 && nocompression_flags
== 0)
1446 /* Implement -mflip-mips16. If DECL has neither a "nomips16" nor a
1447 "mips16" attribute, arbitrarily pick one. We must pick the same
1448 setting for duplicate declarations of a function. */
1449 name
= mflip_mips16_use_mips16_p (decl
) ? "mips16" : "nomips16";
1450 *attributes
= tree_cons (get_identifier (name
), NULL
, *attributes
);
1451 name
= "nomicromips";
1452 *attributes
= tree_cons (get_identifier (name
), NULL
, *attributes
);
1457 /* Implement TARGET_MERGE_DECL_ATTRIBUTES. */
1460 mips_merge_decl_attributes (tree olddecl
, tree newdecl
)
1464 diff
= (mips_get_compress_on_flags (DECL_ATTRIBUTES (olddecl
))
1465 ^ mips_get_compress_on_flags (DECL_ATTRIBUTES (newdecl
)));
1467 error ("%qE redeclared with conflicting %qs attributes",
1468 DECL_NAME (newdecl
), mips_get_compress_on_name (diff
));
1470 diff
= (mips_get_compress_off_flags (DECL_ATTRIBUTES (olddecl
))
1471 ^ mips_get_compress_off_flags (DECL_ATTRIBUTES (newdecl
)));
1473 error ("%qE redeclared with conflicting %qs attributes",
1474 DECL_NAME (newdecl
), mips_get_compress_off_name (diff
));
1476 return merge_attributes (DECL_ATTRIBUTES (olddecl
),
1477 DECL_ATTRIBUTES (newdecl
));
1480 /* Implement TARGET_CAN_INLINE_P. */
1483 mips_can_inline_p (tree caller
, tree callee
)
1485 if (mips_get_compress_mode (callee
) != mips_get_compress_mode (caller
))
1487 return default_target_can_inline_p (caller
, callee
);
1490 /* Handle an "interrupt" attribute with an optional argument. */
1493 mips_handle_interrupt_attr (tree
*node ATTRIBUTE_UNUSED
, tree name
, tree args
,
1494 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
1496 /* Check for an argument. */
1497 if (is_attribute_p ("interrupt", name
) && args
!= NULL
)
1501 cst
= TREE_VALUE (args
);
1502 if (TREE_CODE (cst
) != STRING_CST
)
1504 warning (OPT_Wattributes
,
1505 "%qE attribute requires a string argument",
1507 *no_add_attrs
= true;
1509 else if (strcmp (TREE_STRING_POINTER (cst
), "eic") != 0
1510 && strncmp (TREE_STRING_POINTER (cst
), "vector=", 7) != 0)
1512 warning (OPT_Wattributes
,
1513 "argument to %qE attribute is neither eic, nor "
1514 "vector=<line>", name
);
1515 *no_add_attrs
= true;
1517 else if (strncmp (TREE_STRING_POINTER (cst
), "vector=", 7) == 0)
1519 const char *arg
= TREE_STRING_POINTER (cst
) + 7;
1521 /* Acceptable names are: sw0,sw1,hw0,hw1,hw2,hw3,hw4,hw5. */
1522 if (strlen (arg
) != 3
1523 || (arg
[0] != 's' && arg
[0] != 'h')
1525 || (arg
[0] == 's' && arg
[2] != '0' && arg
[2] != '1')
1526 || (arg
[0] == 'h' && (arg
[2] < '0' || arg
[2] > '5')))
1528 warning (OPT_Wattributes
,
1529 "interrupt vector to %qE attribute is not "
1530 "vector=(sw0|sw1|hw0|hw1|hw2|hw3|hw4|hw5)",
1532 *no_add_attrs
= true;
1542 /* Handle a "use_shadow_register_set" attribute with an optional argument. */
1545 mips_handle_use_shadow_register_set_attr (tree
*node ATTRIBUTE_UNUSED
,
1546 tree name
, tree args
,
1547 int flags ATTRIBUTE_UNUSED
,
1550 /* Check for an argument. */
1551 if (is_attribute_p ("use_shadow_register_set", name
) && args
!= NULL
)
1555 cst
= TREE_VALUE (args
);
1556 if (TREE_CODE (cst
) != STRING_CST
)
1558 warning (OPT_Wattributes
,
1559 "%qE attribute requires a string argument",
1561 *no_add_attrs
= true;
1563 else if (strcmp (TREE_STRING_POINTER (cst
), "intstack") != 0)
1565 warning (OPT_Wattributes
,
1566 "argument to %qE attribute is not intstack", name
);
1567 *no_add_attrs
= true;
1576 /* If X is a PLUS of a CONST_INT, return the two terms in *BASE_PTR
1577 and *OFFSET_PTR. Return X in *BASE_PTR and 0 in *OFFSET_PTR otherwise. */
1580 mips_split_plus (rtx x
, rtx
*base_ptr
, HOST_WIDE_INT
*offset_ptr
)
1582 if (GET_CODE (x
) == PLUS
&& CONST_INT_P (XEXP (x
, 1)))
1584 *base_ptr
= XEXP (x
, 0);
1585 *offset_ptr
= INTVAL (XEXP (x
, 1));
1594 static unsigned int mips_build_integer (struct mips_integer_op
*,
1595 unsigned HOST_WIDE_INT
);
1597 /* A subroutine of mips_build_integer, with the same interface.
1598 Assume that the final action in the sequence should be a left shift. */
1601 mips_build_shift (struct mips_integer_op
*codes
, HOST_WIDE_INT value
)
1603 unsigned int i
, shift
;
1605 /* Shift VALUE right until its lowest bit is set. Shift arithmetically
1606 since signed numbers are easier to load than unsigned ones. */
1608 while ((value
& 1) == 0)
1609 value
/= 2, shift
++;
1611 i
= mips_build_integer (codes
, value
);
1612 codes
[i
].code
= ASHIFT
;
1613 codes
[i
].value
= shift
;
1617 /* As for mips_build_shift, but assume that the final action will be
1618 an IOR or PLUS operation. */
1621 mips_build_lower (struct mips_integer_op
*codes
, unsigned HOST_WIDE_INT value
)
1623 unsigned HOST_WIDE_INT high
;
1626 high
= value
& ~(unsigned HOST_WIDE_INT
) 0xffff;
1627 if (!LUI_OPERAND (high
) && (value
& 0x18000) == 0x18000)
1629 /* The constant is too complex to load with a simple LUI/ORI pair,
1630 so we want to give the recursive call as many trailing zeros as
1631 possible. In this case, we know bit 16 is set and that the
1632 low 16 bits form a negative number. If we subtract that number
1633 from VALUE, we will clear at least the lowest 17 bits, maybe more. */
1634 i
= mips_build_integer (codes
, CONST_HIGH_PART (value
));
1635 codes
[i
].code
= PLUS
;
1636 codes
[i
].value
= CONST_LOW_PART (value
);
1640 /* Either this is a simple LUI/ORI pair, or clearing the lowest 16
1641 bits gives a value with at least 17 trailing zeros. */
1642 i
= mips_build_integer (codes
, high
);
1643 codes
[i
].code
= IOR
;
1644 codes
[i
].value
= value
& 0xffff;
1649 /* Fill CODES with a sequence of rtl operations to load VALUE.
1650 Return the number of operations needed. */
1653 mips_build_integer (struct mips_integer_op
*codes
,
1654 unsigned HOST_WIDE_INT value
)
1656 if (SMALL_OPERAND (value
)
1657 || SMALL_OPERAND_UNSIGNED (value
)
1658 || LUI_OPERAND (value
))
1660 /* The value can be loaded with a single instruction. */
1661 codes
[0].code
= UNKNOWN
;
1662 codes
[0].value
= value
;
1665 else if ((value
& 1) != 0 || LUI_OPERAND (CONST_HIGH_PART (value
)))
1667 /* Either the constant is a simple LUI/ORI combination or its
1668 lowest bit is set. We don't want to shift in this case. */
1669 return mips_build_lower (codes
, value
);
1671 else if ((value
& 0xffff) == 0)
1673 /* The constant will need at least three actions. The lowest
1674 16 bits are clear, so the final action will be a shift. */
1675 return mips_build_shift (codes
, value
);
1679 /* The final action could be a shift, add or inclusive OR.
1680 Rather than use a complex condition to select the best
1681 approach, try both mips_build_shift and mips_build_lower
1682 and pick the one that gives the shortest sequence.
1683 Note that this case is only used once per constant. */
1684 struct mips_integer_op alt_codes
[MIPS_MAX_INTEGER_OPS
];
1685 unsigned int cost
, alt_cost
;
1687 cost
= mips_build_shift (codes
, value
);
1688 alt_cost
= mips_build_lower (alt_codes
, value
);
1689 if (alt_cost
< cost
)
1691 memcpy (codes
, alt_codes
, alt_cost
* sizeof (codes
[0]));
1698 /* Implement TARGET_LEGITIMATE_CONSTANT_P. */
1701 mips_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED
, rtx x
)
1703 return mips_const_insns (x
) > 0;
1706 /* Return a SYMBOL_REF for a MIPS16 function called NAME. */
1709 mips16_stub_function (const char *name
)
1713 x
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (name
));
1714 SYMBOL_REF_FLAGS (x
) |= (SYMBOL_FLAG_EXTERNAL
| SYMBOL_FLAG_FUNCTION
);
1718 /* Return a legitimate call address for STUB, given that STUB is a MIPS16
1719 support function. */
1722 mips16_stub_call_address (mips_one_only_stub
*stub
)
1724 rtx fn
= mips16_stub_function (stub
->get_name ());
1725 SYMBOL_REF_FLAGS (fn
) |= SYMBOL_FLAG_LOCAL
;
1726 if (!call_insn_operand (fn
, VOIDmode
))
1727 fn
= force_reg (Pmode
, fn
);
1731 /* A stub for moving the thread pointer into TLS_GET_TP_REGNUM. */
1733 class mips16_rdhwr_one_only_stub
: public mips_one_only_stub
1735 virtual const char *get_name ();
1736 virtual void output_body ();
1740 mips16_rdhwr_one_only_stub::get_name ()
1742 return "__mips16_rdhwr";
1746 mips16_rdhwr_one_only_stub::output_body ()
1748 fprintf (asm_out_file
,
1750 "\t.set\tmips32r2\n"
1751 "\t.set\tnoreorder\n"
1757 /* A stub for moving the FCSR into GET_FCSR_REGNUM. */
1758 class mips16_get_fcsr_one_only_stub
: public mips_one_only_stub
1760 virtual const char *get_name ();
1761 virtual void output_body ();
1765 mips16_get_fcsr_one_only_stub::get_name ()
1767 return "__mips16_get_fcsr";
1771 mips16_get_fcsr_one_only_stub::output_body ()
1773 fprintf (asm_out_file
,
1775 "\tj\t$31\n", reg_names
[GET_FCSR_REGNUM
]);
1778 /* A stub for moving SET_FCSR_REGNUM into the FCSR. */
1779 class mips16_set_fcsr_one_only_stub
: public mips_one_only_stub
1781 virtual const char *get_name ();
1782 virtual void output_body ();
1786 mips16_set_fcsr_one_only_stub::get_name ()
1788 return "__mips16_set_fcsr";
1792 mips16_set_fcsr_one_only_stub::output_body ()
1794 fprintf (asm_out_file
,
1796 "\tj\t$31\n", reg_names
[SET_FCSR_REGNUM
]);
1799 /* Return true if symbols of type TYPE require a GOT access. */
1802 mips_got_symbol_type_p (enum mips_symbol_type type
)
1806 case SYMBOL_GOT_PAGE_OFST
:
1807 case SYMBOL_GOT_DISP
:
1815 /* Return true if X is a thread-local symbol. */
1818 mips_tls_symbol_p (rtx x
)
1820 return GET_CODE (x
) == SYMBOL_REF
&& SYMBOL_REF_TLS_MODEL (x
) != 0;
1823 /* Return true if SYMBOL_REF X is associated with a global symbol
1824 (in the STB_GLOBAL sense). */
1827 mips_global_symbol_p (const_rtx x
)
1829 const_tree decl
= SYMBOL_REF_DECL (x
);
1832 return !SYMBOL_REF_LOCAL_P (x
) || SYMBOL_REF_EXTERNAL_P (x
);
1834 /* Weakref symbols are not TREE_PUBLIC, but their targets are global
1835 or weak symbols. Relocations in the object file will be against
1836 the target symbol, so it's that symbol's binding that matters here. */
1837 return DECL_P (decl
) && (TREE_PUBLIC (decl
) || DECL_WEAK (decl
));
1840 /* Return true if function X is a libgcc MIPS16 stub function. */
1843 mips16_stub_function_p (const_rtx x
)
1845 return (GET_CODE (x
) == SYMBOL_REF
1846 && strncmp (XSTR (x
, 0), "__mips16_", 9) == 0);
1849 /* Return true if function X is a locally-defined and locally-binding
1853 mips16_local_function_p (const_rtx x
)
1855 return (GET_CODE (x
) == SYMBOL_REF
1856 && SYMBOL_REF_LOCAL_P (x
)
1857 && !SYMBOL_REF_EXTERNAL_P (x
)
1858 && (mips_get_compress_mode (SYMBOL_REF_DECL (x
)) & MASK_MIPS16
));
1861 /* Return true if SYMBOL_REF X binds locally. */
1864 mips_symbol_binds_local_p (const_rtx x
)
1866 return (SYMBOL_REF_DECL (x
)
1867 ? targetm
.binds_local_p (SYMBOL_REF_DECL (x
))
1868 : SYMBOL_REF_LOCAL_P (x
));
1871 /* Return true if OP is a constant vector with the number of units in MODE,
1872 and each unit has the same bit set. */
1875 mips_const_vector_bitimm_set_p (rtx op
, machine_mode mode
)
1877 if (GET_CODE (op
) == CONST_VECTOR
&& op
!= CONST0_RTX (mode
))
1879 unsigned HOST_WIDE_INT val
= UINTVAL (CONST_VECTOR_ELT (op
, 0));
1880 int vlog2
= exact_log2 (val
& GET_MODE_MASK (GET_MODE_INNER (mode
)));
1884 gcc_assert (GET_MODE_CLASS (mode
) == MODE_VECTOR_INT
);
1885 gcc_assert (vlog2
>= 0 && vlog2
<= GET_MODE_UNIT_BITSIZE (mode
) - 1);
1886 return mips_const_vector_same_val_p (op
, mode
);
1893 /* Return true if OP is a constant vector with the number of units in MODE,
1894 and each unit has the same bit clear. */
1897 mips_const_vector_bitimm_clr_p (rtx op
, machine_mode mode
)
1899 if (GET_CODE (op
) == CONST_VECTOR
&& op
!= CONSTM1_RTX (mode
))
1901 unsigned HOST_WIDE_INT val
= ~UINTVAL (CONST_VECTOR_ELT (op
, 0));
1902 int vlog2
= exact_log2 (val
& GET_MODE_MASK (GET_MODE_INNER (mode
)));
1906 gcc_assert (GET_MODE_CLASS (mode
) == MODE_VECTOR_INT
);
1907 gcc_assert (vlog2
>= 0 && vlog2
<= GET_MODE_UNIT_BITSIZE (mode
) - 1);
1908 return mips_const_vector_same_val_p (op
, mode
);
1915 /* Return true if OP is a constant vector with the number of units in MODE,
1916 and each unit has the same value. */
1919 mips_const_vector_same_val_p (rtx op
, machine_mode mode
)
1921 int i
, nunits
= GET_MODE_NUNITS (mode
);
1924 if (GET_CODE (op
) != CONST_VECTOR
|| GET_MODE (op
) != mode
)
1927 first
= CONST_VECTOR_ELT (op
, 0);
1928 for (i
= 1; i
< nunits
; i
++)
1929 if (!rtx_equal_p (first
, CONST_VECTOR_ELT (op
, i
)))
1935 /* Return true if OP is a constant vector with the number of units in MODE,
1936 and each unit has the same value as well as replicated bytes in the value.
1940 mips_const_vector_same_bytes_p (rtx op
, machine_mode mode
)
1943 HOST_WIDE_INT val
, first_byte
;
1946 if (!mips_const_vector_same_val_p (op
, mode
))
1949 first
= CONST_VECTOR_ELT (op
, 0);
1950 bytes
= GET_MODE_UNIT_SIZE (mode
);
1951 val
= INTVAL (first
);
1952 first_byte
= val
& 0xff;
1953 for (i
= 1; i
< bytes
; i
++)
1956 if ((val
& 0xff) != first_byte
)
1963 /* Return true if OP is a constant vector with the number of units in MODE,
1964 and each unit has the same integer value in the range [LOW, HIGH]. */
1967 mips_const_vector_same_int_p (rtx op
, machine_mode mode
, HOST_WIDE_INT low
,
1970 HOST_WIDE_INT value
;
1973 if (!mips_const_vector_same_val_p (op
, mode
))
1976 elem0
= CONST_VECTOR_ELT (op
, 0);
1977 if (!CONST_INT_P (elem0
))
1980 value
= INTVAL (elem0
);
1981 return (value
>= low
&& value
<= high
);
1984 /* Return true if OP is a constant vector with repeated 4-element sets
1988 mips_const_vector_shuffle_set_p (rtx op
, machine_mode mode
)
1990 int nunits
= GET_MODE_NUNITS (mode
);
1991 int nsets
= nunits
/ 4;
1995 /* Check if we have the same 4-element sets. */
1996 for (j
= 0; j
< nsets
; j
++, set
= 4 * j
)
1997 for (i
= 0; i
< 4; i
++)
1998 if ((INTVAL (XVECEXP (op
, 0, i
))
1999 != (INTVAL (XVECEXP (op
, 0, set
+ i
)) - set
))
2000 || !IN_RANGE (INTVAL (XVECEXP (op
, 0, set
+ i
)), 0, set
+ 3))
2005 /* Return true if rtx constants of mode MODE should be put into a small
2009 mips_rtx_constant_in_small_data_p (machine_mode mode
)
2011 return (!TARGET_EMBEDDED_DATA
2012 && TARGET_LOCAL_SDATA
2013 && GET_MODE_SIZE (mode
) <= mips_small_data_threshold
);
2016 /* Return true if X should not be moved directly into register $25.
2017 We need this because many versions of GAS will treat "la $25,foo" as
2018 part of a call sequence and so allow a global "foo" to be lazily bound. */
2021 mips_dangerous_for_la25_p (rtx x
)
2023 return (!TARGET_EXPLICIT_RELOCS
2025 && GET_CODE (x
) == SYMBOL_REF
2026 && mips_global_symbol_p (x
));
2029 /* Return true if calls to X might need $25 to be valid on entry. */
2032 mips_use_pic_fn_addr_reg_p (const_rtx x
)
2034 if (!TARGET_USE_PIC_FN_ADDR_REG
)
2037 /* MIPS16 stub functions are guaranteed not to use $25. */
2038 if (mips16_stub_function_p (x
))
2041 if (GET_CODE (x
) == SYMBOL_REF
)
2043 /* If PLTs and copy relocations are available, the static linker
2044 will make sure that $25 is valid on entry to the target function. */
2045 if (TARGET_ABICALLS_PIC0
)
2048 /* Locally-defined functions use absolute accesses to set up
2049 the global pointer. */
2050 if (TARGET_ABSOLUTE_ABICALLS
2051 && mips_symbol_binds_local_p (x
)
2052 && !SYMBOL_REF_EXTERNAL_P (x
))
2059 /* Return the method that should be used to access SYMBOL_REF or
2060 LABEL_REF X in context CONTEXT. */
2062 static enum mips_symbol_type
2063 mips_classify_symbol (const_rtx x
, enum mips_symbol_context context
)
2066 return SYMBOL_GOT_DISP
;
2068 if (GET_CODE (x
) == LABEL_REF
)
2070 /* Only return SYMBOL_PC_RELATIVE if we are generating MIPS16
2071 code and if we know that the label is in the current function's
2072 text section. LABEL_REFs are used for jump tables as well as
2073 text labels, so we must check whether jump tables live in the
2075 if (TARGET_MIPS16_SHORT_JUMP_TABLES
2076 && !LABEL_REF_NONLOCAL_P (x
))
2077 return SYMBOL_PC_RELATIVE
;
2079 if (TARGET_ABICALLS
&& !TARGET_ABSOLUTE_ABICALLS
)
2080 return SYMBOL_GOT_PAGE_OFST
;
2082 return SYMBOL_ABSOLUTE
;
2085 gcc_assert (GET_CODE (x
) == SYMBOL_REF
);
2087 if (SYMBOL_REF_TLS_MODEL (x
))
2090 if (CONSTANT_POOL_ADDRESS_P (x
))
2092 if (TARGET_MIPS16_TEXT_LOADS
)
2093 return SYMBOL_PC_RELATIVE
;
2095 if (TARGET_MIPS16_PCREL_LOADS
&& context
== SYMBOL_CONTEXT_MEM
)
2096 return SYMBOL_PC_RELATIVE
;
2098 if (mips_rtx_constant_in_small_data_p (get_pool_mode (x
)))
2099 return SYMBOL_GP_RELATIVE
;
2102 /* Do not use small-data accesses for weak symbols; they may end up
2104 if (TARGET_GPOPT
&& SYMBOL_REF_SMALL_P (x
) && !SYMBOL_REF_WEAK (x
))
2105 return SYMBOL_GP_RELATIVE
;
2107 /* Don't use GOT accesses for locally-binding symbols when -mno-shared
2109 if (TARGET_ABICALLS_PIC2
2110 && !(TARGET_ABSOLUTE_ABICALLS
&& mips_symbol_binds_local_p (x
)))
2112 /* There are three cases to consider:
2114 - o32 PIC (either with or without explicit relocs)
2115 - n32/n64 PIC without explicit relocs
2116 - n32/n64 PIC with explicit relocs
2118 In the first case, both local and global accesses will use an
2119 R_MIPS_GOT16 relocation. We must correctly predict which of
2120 the two semantics (local or global) the assembler and linker
2121 will apply. The choice depends on the symbol's binding rather
2122 than its visibility.
2124 In the second case, the assembler will not use R_MIPS_GOT16
2125 relocations, but it chooses between local and global accesses
2126 in the same way as for o32 PIC.
2128 In the third case we have more freedom since both forms of
2129 access will work for any kind of symbol. However, there seems
2130 little point in doing things differently. */
2131 if (mips_global_symbol_p (x
))
2132 return SYMBOL_GOT_DISP
;
2134 return SYMBOL_GOT_PAGE_OFST
;
2137 return SYMBOL_ABSOLUTE
;
2140 /* Classify the base of symbolic expression X, given that X appears in
2143 static enum mips_symbol_type
2144 mips_classify_symbolic_expression (rtx x
, enum mips_symbol_context context
)
2148 split_const (x
, &x
, &offset
);
2149 if (UNSPEC_ADDRESS_P (x
))
2150 return UNSPEC_ADDRESS_TYPE (x
);
2152 return mips_classify_symbol (x
, context
);
2155 /* Return true if OFFSET is within the range [0, ALIGN), where ALIGN
2156 is the alignment in bytes of SYMBOL_REF X. */
2159 mips_offset_within_alignment_p (rtx x
, HOST_WIDE_INT offset
)
2161 HOST_WIDE_INT align
;
2163 align
= SYMBOL_REF_DECL (x
) ? DECL_ALIGN_UNIT (SYMBOL_REF_DECL (x
)) : 1;
2164 return IN_RANGE (offset
, 0, align
- 1);
2167 /* Return true if X is a symbolic constant that can be used in context
2168 CONTEXT. If it is, store the type of the symbol in *SYMBOL_TYPE. */
2171 mips_symbolic_constant_p (rtx x
, enum mips_symbol_context context
,
2172 enum mips_symbol_type
*symbol_type
)
2176 split_const (x
, &x
, &offset
);
2177 if (UNSPEC_ADDRESS_P (x
))
2179 *symbol_type
= UNSPEC_ADDRESS_TYPE (x
);
2180 x
= UNSPEC_ADDRESS (x
);
2182 else if (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == LABEL_REF
)
2184 *symbol_type
= mips_classify_symbol (x
, context
);
2185 if (*symbol_type
== SYMBOL_TLS
)
2191 if (offset
== const0_rtx
)
2194 /* Check whether a nonzero offset is valid for the underlying
2196 switch (*symbol_type
)
2198 case SYMBOL_ABSOLUTE
:
2199 case SYMBOL_64_HIGH
:
2202 /* If the target has 64-bit pointers and the object file only
2203 supports 32-bit symbols, the values of those symbols will be
2204 sign-extended. In this case we can't allow an arbitrary offset
2205 in case the 32-bit value X + OFFSET has a different sign from X. */
2206 if (Pmode
== DImode
&& !ABI_HAS_64BIT_SYMBOLS
)
2207 return offset_within_block_p (x
, INTVAL (offset
));
2209 /* In other cases the relocations can handle any offset. */
2212 case SYMBOL_PC_RELATIVE
:
2213 /* Allow constant pool references to be converted to LABEL+CONSTANT.
2214 In this case, we no longer have access to the underlying constant,
2215 but the original symbol-based access was known to be valid. */
2216 if (GET_CODE (x
) == LABEL_REF
)
2221 case SYMBOL_GP_RELATIVE
:
2222 /* Make sure that the offset refers to something within the
2223 same object block. This should guarantee that the final
2224 PC- or GP-relative offset is within the 16-bit limit. */
2225 return offset_within_block_p (x
, INTVAL (offset
));
2227 case SYMBOL_GOT_PAGE_OFST
:
2228 case SYMBOL_GOTOFF_PAGE
:
2229 /* If the symbol is global, the GOT entry will contain the symbol's
2230 address, and we will apply a 16-bit offset after loading it.
2231 If the symbol is local, the linker should provide enough local
2232 GOT entries for a 16-bit offset, but larger offsets may lead
2234 return SMALL_INT (offset
);
2238 /* There is no carry between the HI and LO REL relocations, so the
2239 offset is only valid if we know it won't lead to such a carry. */
2240 return mips_offset_within_alignment_p (x
, INTVAL (offset
));
2242 case SYMBOL_GOT_DISP
:
2243 case SYMBOL_GOTOFF_DISP
:
2244 case SYMBOL_GOTOFF_CALL
:
2245 case SYMBOL_GOTOFF_LOADGP
:
2248 case SYMBOL_GOTTPREL
:
2256 /* Like mips_symbol_insns, but treat extended MIPS16 instructions as a
2257 single instruction. We rely on the fact that, in the worst case,
2258 all instructions involved in a MIPS16 address calculation are usually
2262 mips_symbol_insns_1 (enum mips_symbol_type type
, machine_mode mode
)
2264 if (mips_use_pcrel_pool_p
[(int) type
])
2266 if (mode
== MAX_MACHINE_MODE
)
2267 /* LEAs will be converted into constant-pool references by
2269 type
= SYMBOL_PC_RELATIVE
;
2271 /* The constant must be loaded and then dereferenced. */
2277 case SYMBOL_ABSOLUTE
:
2278 /* When using 64-bit symbols, we need 5 preparatory instructions,
2281 lui $at,%highest(symbol)
2282 daddiu $at,$at,%higher(symbol)
2284 daddiu $at,$at,%hi(symbol)
2287 The final address is then $at + %lo(symbol). With 32-bit
2288 symbols we just need a preparatory LUI for normal mode and
2289 a preparatory LI and SLL for MIPS16. */
2290 return ABI_HAS_64BIT_SYMBOLS
? 6 : TARGET_MIPS16
? 3 : 2;
2292 case SYMBOL_GP_RELATIVE
:
2293 /* Treat GP-relative accesses as taking a single instruction on
2294 MIPS16 too; the copy of $gp can often be shared. */
2297 case SYMBOL_PC_RELATIVE
:
2298 /* PC-relative constants can be only be used with ADDIUPC,
2299 DADDIUPC, LWPC and LDPC. */
2300 if (mode
== MAX_MACHINE_MODE
2301 || GET_MODE_SIZE (mode
) == 4
2302 || GET_MODE_SIZE (mode
) == 8)
2305 /* The constant must be loaded using ADDIUPC or DADDIUPC first. */
2308 case SYMBOL_GOT_DISP
:
2309 /* The constant will have to be loaded from the GOT before it
2310 is used in an address. */
2311 if (mode
!= MAX_MACHINE_MODE
)
2316 case SYMBOL_GOT_PAGE_OFST
:
2317 /* Unless -funit-at-a-time is in effect, we can't be sure whether the
2318 local/global classification is accurate. The worst cases are:
2320 (1) For local symbols when generating o32 or o64 code. The assembler
2326 ...and the final address will be $at + %lo(symbol).
2328 (2) For global symbols when -mxgot. The assembler will use:
2330 lui $at,%got_hi(symbol)
2333 ...and the final address will be $at + %got_lo(symbol). */
2336 case SYMBOL_GOTOFF_PAGE
:
2337 case SYMBOL_GOTOFF_DISP
:
2338 case SYMBOL_GOTOFF_CALL
:
2339 case SYMBOL_GOTOFF_LOADGP
:
2340 case SYMBOL_64_HIGH
:
2346 case SYMBOL_GOTTPREL
:
2349 /* A 16-bit constant formed by a single relocation, or a 32-bit
2350 constant formed from a high 16-bit relocation and a low 16-bit
2351 relocation. Use mips_split_p to determine which. 32-bit
2352 constants need an "lui; addiu" sequence for normal mode and
2353 an "li; sll; addiu" sequence for MIPS16 mode. */
2354 return !mips_split_p
[type
] ? 1 : TARGET_MIPS16
? 3 : 2;
2357 /* We don't treat a bare TLS symbol as a constant. */
2363 /* If MODE is MAX_MACHINE_MODE, return the number of instructions needed
2364 to load symbols of type TYPE into a register. Return 0 if the given
2365 type of symbol cannot be used as an immediate operand.
2367 Otherwise, return the number of instructions needed to load or store
2368 values of mode MODE to or from addresses of type TYPE. Return 0 if
2369 the given type of symbol is not valid in addresses.
2371 In both cases, instruction counts are based off BASE_INSN_LENGTH. */
2374 mips_symbol_insns (enum mips_symbol_type type
, machine_mode mode
)
2376 /* MSA LD.* and ST.* cannot support loading symbols via an immediate
2378 if (MSA_SUPPORTED_MODE_P (mode
))
2381 return mips_symbol_insns_1 (type
, mode
) * (TARGET_MIPS16
? 2 : 1);
2384 /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
2387 mips_cannot_force_const_mem (machine_mode mode
, rtx x
)
2389 enum mips_symbol_type type
;
2392 /* There is no assembler syntax for expressing an address-sized
2394 if (GET_CODE (x
) == HIGH
)
2397 /* As an optimization, reject constants that mips_legitimize_move
2400 Suppose we have a multi-instruction sequence that loads constant C
2401 into register R. If R does not get allocated a hard register, and
2402 R is used in an operand that allows both registers and memory
2403 references, reload will consider forcing C into memory and using
2404 one of the instruction's memory alternatives. Returning false
2405 here will force it to use an input reload instead. */
2406 if (CONST_INT_P (x
) && mips_legitimate_constant_p (mode
, x
))
2409 split_const (x
, &base
, &offset
);
2410 if (mips_symbolic_constant_p (base
, SYMBOL_CONTEXT_LEA
, &type
))
2412 /* See whether we explicitly want these symbols in the pool. */
2413 if (mips_use_pcrel_pool_p
[(int) type
])
2416 /* The same optimization as for CONST_INT. */
2417 if (SMALL_INT (offset
) && mips_symbol_insns (type
, MAX_MACHINE_MODE
) > 0)
2420 /* If MIPS16 constant pools live in the text section, they should
2421 not refer to anything that might need run-time relocation. */
2422 if (TARGET_MIPS16_PCREL_LOADS
&& mips_got_symbol_type_p (type
))
2426 /* TLS symbols must be computed by mips_legitimize_move. */
2427 if (tls_referenced_p (x
))
2433 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. We can't use blocks for
2434 constants when we're using a per-function constant pool. */
2437 mips_use_blocks_for_constant_p (machine_mode mode ATTRIBUTE_UNUSED
,
2438 const_rtx x ATTRIBUTE_UNUSED
)
2440 return !TARGET_MIPS16_PCREL_LOADS
;
2443 /* Return true if register REGNO is a valid base register for mode MODE.
2444 STRICT_P is true if REG_OK_STRICT is in effect. */
2447 mips_regno_mode_ok_for_base_p (int regno
, machine_mode mode
,
2450 if (!HARD_REGISTER_NUM_P (regno
))
2454 regno
= reg_renumber
[regno
];
2457 /* These fake registers will be eliminated to either the stack or
2458 hard frame pointer, both of which are usually valid base registers.
2459 Reload deals with the cases where the eliminated form isn't valid. */
2460 if (regno
== ARG_POINTER_REGNUM
|| regno
== FRAME_POINTER_REGNUM
)
2463 /* In MIPS16 mode, the stack pointer can only address word and doubleword
2464 values, nothing smaller. */
2465 if (TARGET_MIPS16
&& regno
== STACK_POINTER_REGNUM
)
2466 return GET_MODE_SIZE (mode
) == 4 || GET_MODE_SIZE (mode
) == 8;
2468 return TARGET_MIPS16
? M16_REG_P (regno
) : GP_REG_P (regno
);
2471 /* Return true if X is a valid base register for mode MODE.
2472 STRICT_P is true if REG_OK_STRICT is in effect. */
2475 mips_valid_base_register_p (rtx x
, machine_mode mode
, bool strict_p
)
2477 if (!strict_p
&& GET_CODE (x
) == SUBREG
)
2481 && mips_regno_mode_ok_for_base_p (REGNO (x
), mode
, strict_p
));
2484 /* Return true if, for every base register BASE_REG, (plus BASE_REG X)
2485 can address a value of mode MODE. */
2488 mips_valid_offset_p (rtx x
, machine_mode mode
)
2490 /* Check that X is a signed 16-bit number. */
2491 if (!const_arith_operand (x
, Pmode
))
2494 /* We may need to split multiword moves, so make sure that every word
2496 if (GET_MODE_SIZE (mode
) > UNITS_PER_WORD
2497 && !SMALL_OPERAND (INTVAL (x
) + GET_MODE_SIZE (mode
) - UNITS_PER_WORD
))
2500 /* MSA LD.* and ST.* supports 10-bit signed offsets. */
2501 if (MSA_SUPPORTED_MODE_P (mode
)
2502 && !mips_signed_immediate_p (INTVAL (x
), 10,
2503 mips_ldst_scaled_shift (mode
)))
2509 /* Return true if a LO_SUM can address a value of mode MODE when the
2510 LO_SUM symbol has type SYMBOL_TYPE. */
2513 mips_valid_lo_sum_p (enum mips_symbol_type symbol_type
, machine_mode mode
)
2515 /* Check that symbols of type SYMBOL_TYPE can be used to access values
2517 if (mips_symbol_insns (symbol_type
, mode
) == 0)
2520 /* Check that there is a known low-part relocation. */
2521 if (mips_lo_relocs
[symbol_type
] == NULL
)
2524 /* We may need to split multiword moves, so make sure that each word
2525 can be accessed without inducing a carry. This is mainly needed
2526 for o64, which has historically only guaranteed 64-bit alignment
2527 for 128-bit types. */
2528 if (GET_MODE_SIZE (mode
) > UNITS_PER_WORD
2529 && GET_MODE_BITSIZE (mode
) > GET_MODE_ALIGNMENT (mode
))
2532 /* MSA LD.* and ST.* cannot support loading symbols via %lo($base). */
2533 if (MSA_SUPPORTED_MODE_P (mode
))
2539 /* Return true if X is a valid address for machine mode MODE. If it is,
2540 fill in INFO appropriately. STRICT_P is true if REG_OK_STRICT is in
2544 mips_classify_address (struct mips_address_info
*info
, rtx x
,
2545 machine_mode mode
, bool strict_p
)
2547 switch (GET_CODE (x
))
2551 info
->type
= ADDRESS_REG
;
2553 info
->offset
= const0_rtx
;
2554 return mips_valid_base_register_p (info
->reg
, mode
, strict_p
);
2557 info
->type
= ADDRESS_REG
;
2558 info
->reg
= XEXP (x
, 0);
2559 info
->offset
= XEXP (x
, 1);
2560 return (mips_valid_base_register_p (info
->reg
, mode
, strict_p
)
2561 && mips_valid_offset_p (info
->offset
, mode
));
2564 info
->type
= ADDRESS_LO_SUM
;
2565 info
->reg
= XEXP (x
, 0);
2566 info
->offset
= XEXP (x
, 1);
2567 /* We have to trust the creator of the LO_SUM to do something vaguely
2568 sane. Target-independent code that creates a LO_SUM should also
2569 create and verify the matching HIGH. Target-independent code that
2570 adds an offset to a LO_SUM must prove that the offset will not
2571 induce a carry. Failure to do either of these things would be
2572 a bug, and we are not required to check for it here. The MIPS
2573 backend itself should only create LO_SUMs for valid symbolic
2574 constants, with the high part being either a HIGH or a copy
2577 = mips_classify_symbolic_expression (info
->offset
, SYMBOL_CONTEXT_MEM
);
2578 return (mips_valid_base_register_p (info
->reg
, mode
, strict_p
)
2579 && mips_valid_lo_sum_p (info
->symbol_type
, mode
));
2582 /* Small-integer addresses don't occur very often, but they
2583 are legitimate if $0 is a valid base register. */
2584 info
->type
= ADDRESS_CONST_INT
;
2585 return !TARGET_MIPS16
&& SMALL_INT (x
);
2590 info
->type
= ADDRESS_SYMBOLIC
;
2591 return (mips_symbolic_constant_p (x
, SYMBOL_CONTEXT_MEM
,
2593 && mips_symbol_insns (info
->symbol_type
, mode
) > 0
2594 && !mips_split_p
[info
->symbol_type
]);
2601 /* Implement TARGET_LEGITIMATE_ADDRESS_P. */
2604 mips_legitimate_address_p (machine_mode mode
, rtx x
, bool strict_p
)
2606 struct mips_address_info addr
;
2608 return mips_classify_address (&addr
, x
, mode
, strict_p
);
2611 /* Return true if X is a legitimate $sp-based address for mode MODE. */
2614 mips_stack_address_p (rtx x
, machine_mode mode
)
2616 struct mips_address_info addr
;
2618 return (mips_classify_address (&addr
, x
, mode
, false)
2619 && addr
.type
== ADDRESS_REG
2620 && addr
.reg
== stack_pointer_rtx
);
2623 /* Return true if ADDR matches the pattern for the LWXS load scaled indexed
2624 address instruction. Note that such addresses are not considered
2625 legitimate in the TARGET_LEGITIMATE_ADDRESS_P sense, because their use
2626 is so restricted. */
2629 mips_lwxs_address_p (rtx addr
)
2632 && GET_CODE (addr
) == PLUS
2633 && REG_P (XEXP (addr
, 1)))
2635 rtx offset
= XEXP (addr
, 0);
2636 if (GET_CODE (offset
) == MULT
2637 && REG_P (XEXP (offset
, 0))
2638 && CONST_INT_P (XEXP (offset
, 1))
2639 && INTVAL (XEXP (offset
, 1)) == 4)
2645 /* Return true if ADDR matches the pattern for the L{B,H,W,D}{,U}X load
2646 indexed address instruction. Note that such addresses are
2647 not considered legitimate in the TARGET_LEGITIMATE_ADDRESS_P
2648 sense, because their use is so restricted. */
2651 mips_lx_address_p (rtx addr
, machine_mode mode
)
2653 if (GET_CODE (addr
) != PLUS
2654 || !REG_P (XEXP (addr
, 0))
2655 || !REG_P (XEXP (addr
, 1)))
2657 if (ISA_HAS_LBX
&& mode
== QImode
)
2659 if (ISA_HAS_LHX
&& mode
== HImode
)
2661 if (ISA_HAS_LWX
&& mode
== SImode
)
2663 if (ISA_HAS_LDX
&& mode
== DImode
)
2665 if (MSA_SUPPORTED_MODE_P (mode
))
2670 /* Return true if a value at OFFSET bytes from base register BASE can be
2671 accessed using an unextended MIPS16 instruction. MODE is the mode of
2674 Usually the offset in an unextended instruction is a 5-bit field.
2675 The offset is unsigned and shifted left once for LH and SH, twice
2676 for LW and SW, and so on. An exception is LWSP and SWSP, which have
2677 an 8-bit immediate field that's shifted left twice. */
2680 mips16_unextended_reference_p (machine_mode mode
, rtx base
,
2681 unsigned HOST_WIDE_INT offset
)
2683 if (mode
!= BLKmode
&& offset
% GET_MODE_SIZE (mode
) == 0)
2685 if (GET_MODE_SIZE (mode
) == 4 && base
== stack_pointer_rtx
)
2686 return offset
< 256U * GET_MODE_SIZE (mode
);
2687 return offset
< 32U * GET_MODE_SIZE (mode
);
2692 /* Return the number of instructions needed to load or store a value
2693 of mode MODE at address X, assuming that BASE_INSN_LENGTH is the
2694 length of one instruction. Return 0 if X isn't valid for MODE.
2695 Assume that multiword moves may need to be split into word moves
2696 if MIGHT_SPLIT_P, otherwise assume that a single load or store is
2700 mips_address_insns (rtx x
, machine_mode mode
, bool might_split_p
)
2702 struct mips_address_info addr
;
2704 bool msa_p
= (!might_split_p
&& MSA_SUPPORTED_MODE_P (mode
));
2706 /* BLKmode is used for single unaligned loads and stores and should
2707 not count as a multiword mode. (GET_MODE_SIZE (BLKmode) is pretty
2708 meaningless, so we have to single it out as a special case one way
2710 if (mode
!= BLKmode
&& might_split_p
)
2711 factor
= (GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
2715 if (mips_classify_address (&addr
, x
, mode
, false))
2721 /* MSA LD.* and ST.* supports 10-bit signed offsets. */
2722 if (mips_signed_immediate_p (INTVAL (addr
.offset
), 10,
2723 mips_ldst_scaled_shift (mode
)))
2729 && !mips16_unextended_reference_p (mode
, addr
.reg
,
2730 UINTVAL (addr
.offset
)))
2734 case ADDRESS_LO_SUM
:
2735 return msa_p
? 0 : TARGET_MIPS16
? factor
* 2 : factor
;
2737 case ADDRESS_CONST_INT
:
2738 return msa_p
? 0 : factor
;
2740 case ADDRESS_SYMBOLIC
:
2741 return msa_p
? 0 : factor
* mips_symbol_insns (addr
.symbol_type
, mode
);
2746 /* Return true if X fits within an unsigned field of BITS bits that is
2747 shifted left SHIFT bits before being used. */
2750 mips_unsigned_immediate_p (unsigned HOST_WIDE_INT x
, int bits
, int shift
= 0)
2752 return (x
& ((1 << shift
) - 1)) == 0 && x
< ((unsigned) 1 << (shift
+ bits
));
2755 /* Return true if X fits within a signed field of BITS bits that is
2756 shifted left SHIFT bits before being used. */
2759 mips_signed_immediate_p (unsigned HOST_WIDE_INT x
, int bits
, int shift
= 0)
2761 x
+= 1 << (bits
+ shift
- 1);
2762 return mips_unsigned_immediate_p (x
, bits
, shift
);
2765 /* Return the scale shift that applied to MSA LD/ST address offset. */
2768 mips_ldst_scaled_shift (machine_mode mode
)
2770 int shift
= exact_log2 (GET_MODE_UNIT_SIZE (mode
));
2772 if (shift
< 0 || shift
> 8)
2778 /* Return true if X is legitimate for accessing values of mode MODE,
2779 if it is based on a MIPS16 register, and if the offset satisfies
2780 OFFSET_PREDICATE. */
2783 m16_based_address_p (rtx x
, machine_mode mode
,
2784 insn_operand_predicate_fn offset_predicate
)
2786 struct mips_address_info addr
;
2788 return (mips_classify_address (&addr
, x
, mode
, false)
2789 && addr
.type
== ADDRESS_REG
2790 && M16_REG_P (REGNO (addr
.reg
))
2791 && offset_predicate (addr
.offset
, mode
));
2794 /* Return true if X is a legitimate address that conforms to the requirements
2795 for a microMIPS LWSP or SWSP insn. */
2798 lwsp_swsp_address_p (rtx x
, machine_mode mode
)
2800 struct mips_address_info addr
;
2802 return (mips_classify_address (&addr
, x
, mode
, false)
2803 && addr
.type
== ADDRESS_REG
2804 && REGNO (addr
.reg
) == STACK_POINTER_REGNUM
2805 && uw5_operand (addr
.offset
, mode
));
2808 /* Return true if X is a legitimate address with a 12-bit offset.
2809 MODE is the mode of the value being accessed. */
2812 umips_12bit_offset_address_p (rtx x
, machine_mode mode
)
2814 struct mips_address_info addr
;
2816 return (mips_classify_address (&addr
, x
, mode
, false)
2817 && addr
.type
== ADDRESS_REG
2818 && CONST_INT_P (addr
.offset
)
2819 && UMIPS_12BIT_OFFSET_P (INTVAL (addr
.offset
)));
2822 /* Return true if X is a legitimate address with a 9-bit offset.
2823 MODE is the mode of the value being accessed. */
2826 mips_9bit_offset_address_p (rtx x
, machine_mode mode
)
2828 struct mips_address_info addr
;
2830 return (mips_classify_address (&addr
, x
, mode
, false)
2831 && addr
.type
== ADDRESS_REG
2832 && CONST_INT_P (addr
.offset
)
2833 && MIPS_9BIT_OFFSET_P (INTVAL (addr
.offset
)));
2836 /* Return the number of instructions needed to load constant X,
2837 assuming that BASE_INSN_LENGTH is the length of one instruction.
2838 Return 0 if X isn't a valid constant. */
2841 mips_const_insns (rtx x
)
2843 struct mips_integer_op codes
[MIPS_MAX_INTEGER_OPS
];
2844 enum mips_symbol_type symbol_type
;
2847 switch (GET_CODE (x
))
2850 if (!mips_symbolic_constant_p (XEXP (x
, 0), SYMBOL_CONTEXT_LEA
,
2852 || !mips_split_p
[symbol_type
])
2855 /* This is simply an LUI for normal mode. It is an extended
2856 LI followed by an extended SLL for MIPS16. */
2857 return TARGET_MIPS16
? 4 : 1;
2861 /* Unsigned 8-bit constants can be loaded using an unextended
2862 LI instruction. Unsigned 16-bit constants can be loaded
2863 using an extended LI. Negative constants must be loaded
2864 using LI and then negated. */
2865 return (IN_RANGE (INTVAL (x
), 0, 255) ? 1
2866 : SMALL_OPERAND_UNSIGNED (INTVAL (x
)) ? 2
2867 : IN_RANGE (-INTVAL (x
), 0, 255) ? 2
2868 : SMALL_OPERAND_UNSIGNED (-INTVAL (x
)) ? 3
2871 return mips_build_integer (codes
, INTVAL (x
));
2875 && mips_const_vector_same_int_p (x
, GET_MODE (x
), -512, 511))
2879 /* Allow zeros for normal mode, where we can use $0. */
2880 return !TARGET_MIPS16
&& x
== CONST0_RTX (GET_MODE (x
)) ? 1 : 0;
2886 /* See if we can refer to X directly. */
2887 if (mips_symbolic_constant_p (x
, SYMBOL_CONTEXT_LEA
, &symbol_type
))
2888 return mips_symbol_insns (symbol_type
, MAX_MACHINE_MODE
);
2890 /* Otherwise try splitting the constant into a base and offset.
2891 If the offset is a 16-bit value, we can load the base address
2892 into a register and then use (D)ADDIU to add in the offset.
2893 If the offset is larger, we can load the base and offset
2894 into separate registers and add them together with (D)ADDU.
2895 However, the latter is only possible before reload; during
2896 and after reload, we must have the option of forcing the
2897 constant into the pool instead. */
2898 split_const (x
, &x
, &offset
);
2901 int n
= mips_const_insns (x
);
2904 if (SMALL_INT (offset
))
2906 else if (!targetm
.cannot_force_const_mem (GET_MODE (x
), x
))
2907 return n
+ 1 + mips_build_integer (codes
, INTVAL (offset
));
2914 return mips_symbol_insns (mips_classify_symbol (x
, SYMBOL_CONTEXT_LEA
),
2922 /* X is a doubleword constant that can be handled by splitting it into
2923 two words and loading each word separately. Return the number of
2924 instructions required to do this, assuming that BASE_INSN_LENGTH
2925 is the length of one instruction. */
2928 mips_split_const_insns (rtx x
)
2930 unsigned int low
, high
;
2932 low
= mips_const_insns (mips_subword (x
, false));
2933 high
= mips_const_insns (mips_subword (x
, true));
2934 gcc_assert (low
> 0 && high
> 0);
2938 /* Return one word of 128-bit value OP, taking into account the fixed
2939 endianness of certain registers. BYTE selects from the byte address. */
2942 mips_subword_at_byte (rtx op
, unsigned int byte
)
2946 mode
= GET_MODE (op
);
2947 if (mode
== VOIDmode
)
2950 gcc_assert (!FP_REG_RTX_P (op
));
2953 return mips_rewrite_small_data (adjust_address (op
, word_mode
, byte
));
2955 return simplify_gen_subreg (word_mode
, op
, mode
, byte
);
2958 /* Return the number of instructions needed to implement INSN,
2959 given that it loads from or stores to MEM. Assume that
2960 BASE_INSN_LENGTH is the length of one instruction. */
2963 mips_load_store_insns (rtx mem
, rtx_insn
*insn
)
2969 gcc_assert (MEM_P (mem
));
2970 mode
= GET_MODE (mem
);
2972 /* Try to prove that INSN does not need to be split. */
2973 might_split_p
= GET_MODE_SIZE (mode
) > UNITS_PER_WORD
;
2976 set
= single_set (insn
);
2977 if (set
&& !mips_split_move_insn_p (SET_DEST (set
), SET_SRC (set
), insn
))
2978 might_split_p
= false;
2981 return mips_address_insns (XEXP (mem
, 0), mode
, might_split_p
);
2984 /* Return the number of instructions needed for an integer division,
2985 assuming that BASE_INSN_LENGTH is the length of one instruction. */
2988 mips_idiv_insns (machine_mode mode
)
2993 if (TARGET_CHECK_ZERO_DIV
)
2995 if (GENERATE_DIVIDE_TRAPS
&& !MSA_SUPPORTED_MODE_P (mode
))
3001 if (TARGET_FIX_R4000
|| TARGET_FIX_R4400
)
3007 /* Emit a move from SRC to DEST. Assume that the move expanders can
3008 handle all moves if !can_create_pseudo_p (). The distinction is
3009 important because, unlike emit_move_insn, the move expanders know
3010 how to force Pmode objects into the constant pool even when the
3011 constant pool address is not itself legitimate. */
3014 mips_emit_move (rtx dest
, rtx src
)
3016 return (can_create_pseudo_p ()
3017 ? emit_move_insn (dest
, src
)
3018 : emit_move_insn_1 (dest
, src
));
3021 /* Emit a move from SRC to DEST, splitting compound moves into individual
3022 instructions. SPLIT_TYPE is the type of split to perform. */
3025 mips_emit_move_or_split (rtx dest
, rtx src
, enum mips_split_type split_type
)
3027 if (mips_split_move_p (dest
, src
, split_type
))
3028 mips_split_move (dest
, src
, split_type
);
3030 mips_emit_move (dest
, src
);
3033 /* Emit an instruction of the form (set TARGET (CODE OP0)). */
3036 mips_emit_unary (enum rtx_code code
, rtx target
, rtx op0
)
3038 emit_insn (gen_rtx_SET (target
, gen_rtx_fmt_e (code
, GET_MODE (op0
), op0
)));
3041 /* Compute (CODE OP0) and store the result in a new register of mode MODE.
3042 Return that new register. */
3045 mips_force_unary (machine_mode mode
, enum rtx_code code
, rtx op0
)
3049 reg
= gen_reg_rtx (mode
);
3050 mips_emit_unary (code
, reg
, op0
);
3054 /* Emit an instruction of the form (set TARGET (CODE OP0 OP1)). */
3057 mips_emit_binary (enum rtx_code code
, rtx target
, rtx op0
, rtx op1
)
3059 emit_insn (gen_rtx_SET (target
, gen_rtx_fmt_ee (code
, GET_MODE (target
),
3063 /* Compute (CODE OP0 OP1) and store the result in a new register
3064 of mode MODE. Return that new register. */
3067 mips_force_binary (machine_mode mode
, enum rtx_code code
, rtx op0
, rtx op1
)
3071 reg
= gen_reg_rtx (mode
);
3072 mips_emit_binary (code
, reg
, op0
, op1
);
3076 /* Copy VALUE to a register and return that register. If new pseudos
3077 are allowed, copy it into a new register, otherwise use DEST. */
3080 mips_force_temporary (rtx dest
, rtx value
)
3082 if (can_create_pseudo_p ())
3083 return force_reg (Pmode
, value
);
3086 mips_emit_move (dest
, value
);
3091 /* Emit a call sequence with call pattern PATTERN and return the call
3092 instruction itself (which is not necessarily the last instruction
3093 emitted). ORIG_ADDR is the original, unlegitimized address,
3094 ADDR is the legitimized form, and LAZY_P is true if the call
3095 address is lazily-bound. */
3098 mips_emit_call_insn (rtx pattern
, rtx orig_addr
, rtx addr
, bool lazy_p
)
3103 insn
= emit_call_insn (pattern
);
3105 if (TARGET_MIPS16
&& mips_use_pic_fn_addr_reg_p (orig_addr
))
3107 /* MIPS16 JALRs only take MIPS16 registers. If the target
3108 function requires $25 to be valid on entry, we must copy it
3109 there separately. The move instruction can be put in the
3110 call's delay slot. */
3111 reg
= gen_rtx_REG (Pmode
, PIC_FUNCTION_ADDR_REGNUM
);
3112 emit_insn_before (gen_move_insn (reg
, addr
), insn
);
3113 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), reg
);
3117 /* Lazy-binding stubs require $gp to be valid on entry. */
3118 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), pic_offset_table_rtx
);
3122 /* See the comment above load_call<mode> for details. */
3123 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
),
3124 gen_rtx_REG (Pmode
, GOT_VERSION_REGNUM
));
3125 emit_insn (gen_update_got_version ());
3129 && TARGET_EXPLICIT_RELOCS
3130 && TARGET_CALL_CLOBBERED_GP
)
3132 rtx post_call_tmp_reg
= gen_rtx_REG (word_mode
, POST_CALL_TMP_REG
);
3133 clobber_reg (&CALL_INSN_FUNCTION_USAGE (insn
), post_call_tmp_reg
);
3139 /* Wrap symbol or label BASE in an UNSPEC address of type SYMBOL_TYPE,
3140 then add CONST_INT OFFSET to the result. */
3143 mips_unspec_address_offset (rtx base
, rtx offset
,
3144 enum mips_symbol_type symbol_type
)
3146 base
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, base
),
3147 UNSPEC_ADDRESS_FIRST
+ symbol_type
);
3148 if (offset
!= const0_rtx
)
3149 base
= gen_rtx_PLUS (Pmode
, base
, offset
);
3150 return gen_rtx_CONST (Pmode
, base
);
3153 /* Return an UNSPEC address with underlying address ADDRESS and symbol
3154 type SYMBOL_TYPE. */
3157 mips_unspec_address (rtx address
, enum mips_symbol_type symbol_type
)
3161 split_const (address
, &base
, &offset
);
3162 return mips_unspec_address_offset (base
, offset
, symbol_type
);
3165 /* If OP is an UNSPEC address, return the address to which it refers,
3166 otherwise return OP itself. */
3169 mips_strip_unspec_address (rtx op
)
3173 split_const (op
, &base
, &offset
);
3174 if (UNSPEC_ADDRESS_P (base
))
3175 op
= plus_constant (Pmode
, UNSPEC_ADDRESS (base
), INTVAL (offset
));
3179 /* If mips_unspec_address (ADDR, SYMBOL_TYPE) is a 32-bit value, add the
3180 high part to BASE and return the result. Just return BASE otherwise.
3181 TEMP is as for mips_force_temporary.
3183 The returned expression can be used as the first operand to a LO_SUM. */
3186 mips_unspec_offset_high (rtx temp
, rtx base
, rtx addr
,
3187 enum mips_symbol_type symbol_type
)
3189 if (mips_split_p
[symbol_type
])
3191 addr
= gen_rtx_HIGH (Pmode
, mips_unspec_address (addr
, symbol_type
));
3192 addr
= mips_force_temporary (temp
, addr
);
3193 base
= mips_force_temporary (temp
, gen_rtx_PLUS (Pmode
, addr
, base
));
3198 /* Return an instruction that copies $gp into register REG. We want
3199 GCC to treat the register's value as constant, so that its value
3200 can be rematerialized on demand. */
3203 gen_load_const_gp (rtx reg
)
3205 return PMODE_INSN (gen_load_const_gp
, (reg
));
3208 /* Return a pseudo register that contains the value of $gp throughout
3209 the current function. Such registers are needed by MIPS16 functions,
3210 for which $gp itself is not a valid base register or addition operand. */
3213 mips16_gp_pseudo_reg (void)
3215 if (cfun
->machine
->mips16_gp_pseudo_rtx
== NULL_RTX
)
3219 cfun
->machine
->mips16_gp_pseudo_rtx
= gen_reg_rtx (Pmode
);
3221 push_topmost_sequence ();
3223 scan
= get_insns ();
3224 while (NEXT_INSN (scan
) && !INSN_P (NEXT_INSN (scan
)))
3225 scan
= NEXT_INSN (scan
);
3227 rtx set
= gen_load_const_gp (cfun
->machine
->mips16_gp_pseudo_rtx
);
3228 rtx_insn
*insn
= emit_insn_after (set
, scan
);
3229 INSN_LOCATION (insn
) = 0;
3231 pop_topmost_sequence ();
3234 return cfun
->machine
->mips16_gp_pseudo_rtx
;
3237 /* Return a base register that holds pic_offset_table_rtx.
3238 TEMP, if nonnull, is a scratch Pmode base register. */
3241 mips_pic_base_register (rtx temp
)
3244 return pic_offset_table_rtx
;
3246 if (currently_expanding_to_rtl
)
3247 return mips16_gp_pseudo_reg ();
3249 if (can_create_pseudo_p ())
3250 temp
= gen_reg_rtx (Pmode
);
3253 /* The first post-reload split exposes all references to $gp
3254 (both uses and definitions). All references must remain
3255 explicit after that point.
3257 It is safe to introduce uses of $gp at any time, so for
3258 simplicity, we do that before the split too. */
3259 mips_emit_move (temp
, pic_offset_table_rtx
);
3261 emit_insn (gen_load_const_gp (temp
));
3265 /* Return the RHS of a load_call<mode> insn. */
3268 mips_unspec_call (rtx reg
, rtx symbol
)
3272 vec
= gen_rtvec (3, reg
, symbol
, gen_rtx_REG (SImode
, GOT_VERSION_REGNUM
));
3273 return gen_rtx_UNSPEC (Pmode
, vec
, UNSPEC_LOAD_CALL
);
3276 /* If SRC is the RHS of a load_call<mode> insn, return the underlying symbol
3277 reference. Return NULL_RTX otherwise. */
3280 mips_strip_unspec_call (rtx src
)
3282 if (GET_CODE (src
) == UNSPEC
&& XINT (src
, 1) == UNSPEC_LOAD_CALL
)
3283 return mips_strip_unspec_address (XVECEXP (src
, 0, 1));
3287 /* Create and return a GOT reference of type TYPE for address ADDR.
3288 TEMP, if nonnull, is a scratch Pmode base register. */
3291 mips_got_load (rtx temp
, rtx addr
, enum mips_symbol_type type
)
3293 rtx base
, high
, lo_sum_symbol
;
3295 base
= mips_pic_base_register (temp
);
3297 /* If we used the temporary register to load $gp, we can't use
3298 it for the high part as well. */
3299 if (temp
!= NULL
&& reg_overlap_mentioned_p (base
, temp
))
3302 high
= mips_unspec_offset_high (temp
, base
, addr
, type
);
3303 lo_sum_symbol
= mips_unspec_address (addr
, type
);
3305 if (type
== SYMBOL_GOTOFF_CALL
)
3306 return mips_unspec_call (high
, lo_sum_symbol
);
3308 return PMODE_INSN (gen_unspec_got
, (high
, lo_sum_symbol
));
3311 /* If MODE is MAX_MACHINE_MODE, ADDR appears as a move operand, otherwise
3312 it appears in a MEM of that mode. Return true if ADDR is a legitimate
3313 constant in that context and can be split into high and low parts.
3314 If so, and if LOW_OUT is nonnull, emit the high part and store the
3315 low part in *LOW_OUT. Leave *LOW_OUT unchanged otherwise.
3317 TEMP is as for mips_force_temporary and is used to load the high
3318 part into a register.
3320 When MODE is MAX_MACHINE_MODE, the low part is guaranteed to be
3321 a legitimize SET_SRC for an .md pattern, otherwise the low part
3322 is guaranteed to be a legitimate address for mode MODE. */
3325 mips_split_symbol (rtx temp
, rtx addr
, machine_mode mode
, rtx
*low_out
)
3327 enum mips_symbol_context context
;
3328 enum mips_symbol_type symbol_type
;
3331 context
= (mode
== MAX_MACHINE_MODE
3332 ? SYMBOL_CONTEXT_LEA
3333 : SYMBOL_CONTEXT_MEM
);
3334 if (GET_CODE (addr
) == HIGH
&& context
== SYMBOL_CONTEXT_LEA
)
3336 addr
= XEXP (addr
, 0);
3337 if (mips_symbolic_constant_p (addr
, context
, &symbol_type
)
3338 && mips_symbol_insns (symbol_type
, mode
) > 0
3339 && mips_split_hi_p
[symbol_type
])
3342 switch (symbol_type
)
3344 case SYMBOL_GOT_PAGE_OFST
:
3345 /* The high part of a page/ofst pair is loaded from the GOT. */
3346 *low_out
= mips_got_load (temp
, addr
, SYMBOL_GOTOFF_PAGE
);
3357 if (mips_symbolic_constant_p (addr
, context
, &symbol_type
)
3358 && mips_symbol_insns (symbol_type
, mode
) > 0
3359 && mips_split_p
[symbol_type
])
3362 switch (symbol_type
)
3364 case SYMBOL_GOT_DISP
:
3365 /* SYMBOL_GOT_DISP symbols are loaded from the GOT. */
3366 *low_out
= mips_got_load (temp
, addr
, SYMBOL_GOTOFF_DISP
);
3369 case SYMBOL_GP_RELATIVE
:
3370 high
= mips_pic_base_register (temp
);
3371 *low_out
= gen_rtx_LO_SUM (Pmode
, high
, addr
);
3375 high
= gen_rtx_HIGH (Pmode
, copy_rtx (addr
));
3376 high
= mips_force_temporary (temp
, high
);
3377 *low_out
= gen_rtx_LO_SUM (Pmode
, high
, addr
);
3386 /* Return a legitimate address for REG + OFFSET. TEMP is as for
3387 mips_force_temporary; it is only needed when OFFSET is not a
3391 mips_add_offset (rtx temp
, rtx reg
, HOST_WIDE_INT offset
)
3393 if (!SMALL_OPERAND (offset
))
3399 /* Load the full offset into a register so that we can use
3400 an unextended instruction for the address itself. */
3401 high
= GEN_INT (offset
);
3406 /* Leave OFFSET as a 16-bit offset and put the excess in HIGH.
3407 The addition inside the macro CONST_HIGH_PART may cause an
3408 overflow, so we need to force a sign-extension check. */
3409 high
= gen_int_mode (CONST_HIGH_PART (offset
), Pmode
);
3410 offset
= CONST_LOW_PART (offset
);
3412 high
= mips_force_temporary (temp
, high
);
3413 reg
= mips_force_temporary (temp
, gen_rtx_PLUS (Pmode
, high
, reg
));
3415 return plus_constant (Pmode
, reg
, offset
);
3418 /* The __tls_get_attr symbol. */
3419 static GTY(()) rtx mips_tls_symbol
;
3421 /* Return an instruction sequence that calls __tls_get_addr. SYM is
3422 the TLS symbol we are referencing and TYPE is the symbol type to use
3423 (either global dynamic or local dynamic). V0 is an RTX for the
3424 return value location. */
3427 mips_call_tls_get_addr (rtx sym
, enum mips_symbol_type type
, rtx v0
)
3432 a0
= gen_rtx_REG (Pmode
, GP_ARG_FIRST
);
3434 if (!mips_tls_symbol
)
3435 mips_tls_symbol
= init_one_libfunc ("__tls_get_addr");
3437 loc
= mips_unspec_address (sym
, type
);
3441 emit_insn (gen_rtx_SET (a0
, gen_rtx_LO_SUM (Pmode
, pic_offset_table_rtx
,
3443 insn
= mips_expand_call (MIPS_CALL_NORMAL
, v0
, mips_tls_symbol
,
3444 const0_rtx
, NULL_RTX
, false);
3445 RTL_CONST_CALL_P (insn
) = 1;
3446 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), a0
);
3447 insn
= get_insns ();
3454 /* Return a pseudo register that contains the current thread pointer. */
3457 mips_expand_thread_pointer (rtx tp
)
3463 if (!mips16_rdhwr_stub
)
3464 mips16_rdhwr_stub
= new mips16_rdhwr_one_only_stub ();
3465 fn
= mips16_stub_call_address (mips16_rdhwr_stub
);
3466 emit_insn (PMODE_INSN (gen_tls_get_tp_mips16
, (tp
, fn
)));
3469 emit_insn (PMODE_INSN (gen_tls_get_tp
, (tp
)));
3476 return mips_expand_thread_pointer (gen_reg_rtx (Pmode
));
3479 /* Generate the code to access LOC, a thread-local SYMBOL_REF, and return
3480 its address. The return value will be both a valid address and a valid
3481 SET_SRC (either a REG or a LO_SUM). */
3484 mips_legitimize_tls_address (rtx loc
)
3486 rtx dest
, v0
, tp
, tmp1
, tmp2
, eqv
, offset
;
3487 enum tls_model model
;
3489 model
= SYMBOL_REF_TLS_MODEL (loc
);
3490 /* Only TARGET_ABICALLS code can have more than one module; other
3491 code must be static and should not use a GOT. All TLS models
3492 reduce to local exec in this situation. */
3493 if (!TARGET_ABICALLS
)
3494 model
= TLS_MODEL_LOCAL_EXEC
;
3498 case TLS_MODEL_GLOBAL_DYNAMIC
:
3500 v0
= gen_rtx_REG (Pmode
, GP_RETURN
);
3501 rtx_insn
*insn
= mips_call_tls_get_addr (loc
, SYMBOL_TLSGD
, v0
);
3502 dest
= gen_reg_rtx (Pmode
);
3503 emit_libcall_block (insn
, dest
, v0
, loc
);
3507 case TLS_MODEL_LOCAL_DYNAMIC
:
3509 v0
= gen_rtx_REG (Pmode
, GP_RETURN
);
3510 rtx_insn
*insn
= mips_call_tls_get_addr (loc
, SYMBOL_TLSLDM
, v0
);
3511 tmp1
= gen_reg_rtx (Pmode
);
3513 /* Attach a unique REG_EQUIV, to allow the RTL optimizers to
3514 share the LDM result with other LD model accesses. */
3515 eqv
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
),
3517 emit_libcall_block (insn
, tmp1
, v0
, eqv
);
3519 offset
= mips_unspec_address (loc
, SYMBOL_DTPREL
);
3520 if (mips_split_p
[SYMBOL_DTPREL
])
3522 tmp2
= mips_unspec_offset_high (NULL
, tmp1
, loc
, SYMBOL_DTPREL
);
3523 dest
= gen_rtx_LO_SUM (Pmode
, tmp2
, offset
);
3526 dest
= expand_binop (Pmode
, add_optab
, tmp1
, offset
,
3527 0, 0, OPTAB_DIRECT
);
3531 case TLS_MODEL_INITIAL_EXEC
:
3532 tp
= mips_get_tp ();
3533 tmp1
= gen_reg_rtx (Pmode
);
3534 tmp2
= mips_unspec_address (loc
, SYMBOL_GOTTPREL
);
3535 if (Pmode
== DImode
)
3536 emit_insn (gen_load_gotdi (tmp1
, pic_offset_table_rtx
, tmp2
));
3538 emit_insn (gen_load_gotsi (tmp1
, pic_offset_table_rtx
, tmp2
));
3539 dest
= gen_reg_rtx (Pmode
);
3540 emit_insn (gen_add3_insn (dest
, tmp1
, tp
));
3543 case TLS_MODEL_LOCAL_EXEC
:
3544 tmp1
= mips_get_tp ();
3545 offset
= mips_unspec_address (loc
, SYMBOL_TPREL
);
3546 if (mips_split_p
[SYMBOL_TPREL
])
3548 tmp2
= mips_unspec_offset_high (NULL
, tmp1
, loc
, SYMBOL_TPREL
);
3549 dest
= gen_rtx_LO_SUM (Pmode
, tmp2
, offset
);
3552 dest
= expand_binop (Pmode
, add_optab
, tmp1
, offset
,
3553 0, 0, OPTAB_DIRECT
);
3562 /* Implement "TARGET = __builtin_mips_get_fcsr ()" for MIPS16,
3566 mips16_expand_get_fcsr (rtx target
)
3568 if (!mips16_get_fcsr_stub
)
3569 mips16_get_fcsr_stub
= new mips16_get_fcsr_one_only_stub ();
3570 rtx fn
= mips16_stub_call_address (mips16_get_fcsr_stub
);
3571 emit_insn (PMODE_INSN (gen_mips_get_fcsr_mips16
, (fn
)));
3572 emit_move_insn (target
, gen_rtx_REG (SImode
, GET_FCSR_REGNUM
));
3575 /* Implement __builtin_mips_set_fcsr (TARGET) for MIPS16, using a stub. */
3578 mips16_expand_set_fcsr (rtx newval
)
3580 if (!mips16_set_fcsr_stub
)
3581 mips16_set_fcsr_stub
= new mips16_set_fcsr_one_only_stub ();
3582 rtx fn
= mips16_stub_call_address (mips16_set_fcsr_stub
);
3583 emit_move_insn (gen_rtx_REG (SImode
, SET_FCSR_REGNUM
), newval
);
3584 emit_insn (PMODE_INSN (gen_mips_set_fcsr_mips16
, (fn
)));
3587 /* If X is not a valid address for mode MODE, force it into a register. */
3590 mips_force_address (rtx x
, machine_mode mode
)
3592 if (!mips_legitimate_address_p (mode
, x
, false))
3593 x
= force_reg (Pmode
, x
);
3597 /* This function is used to implement LEGITIMIZE_ADDRESS. If X can
3598 be legitimized in a way that the generic machinery might not expect,
3599 return a new address, otherwise return NULL. MODE is the mode of
3600 the memory being accessed. */
3603 mips_legitimize_address (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
3607 HOST_WIDE_INT offset
;
3609 if (mips_tls_symbol_p (x
))
3610 return mips_legitimize_tls_address (x
);
3612 /* See if the address can split into a high part and a LO_SUM. */
3613 if (mips_split_symbol (NULL
, x
, mode
, &addr
))
3614 return mips_force_address (addr
, mode
);
3616 /* Handle BASE + OFFSET using mips_add_offset. */
3617 mips_split_plus (x
, &base
, &offset
);
3620 if (!mips_valid_base_register_p (base
, mode
, false))
3621 base
= copy_to_mode_reg (Pmode
, base
);
3622 addr
= mips_add_offset (NULL
, base
, offset
);
3623 return mips_force_address (addr
, mode
);
3629 /* Load VALUE into DEST. TEMP is as for mips_force_temporary. */
3632 mips_move_integer (rtx temp
, rtx dest
, unsigned HOST_WIDE_INT value
)
3634 struct mips_integer_op codes
[MIPS_MAX_INTEGER_OPS
];
3636 unsigned int i
, num_ops
;
3639 mode
= GET_MODE (dest
);
3640 num_ops
= mips_build_integer (codes
, value
);
3642 /* Apply each binary operation to X. Invariant: X is a legitimate
3643 source operand for a SET pattern. */
3644 x
= GEN_INT (codes
[0].value
);
3645 for (i
= 1; i
< num_ops
; i
++)
3647 if (!can_create_pseudo_p ())
3649 emit_insn (gen_rtx_SET (temp
, x
));
3653 x
= force_reg (mode
, x
);
3654 x
= gen_rtx_fmt_ee (codes
[i
].code
, mode
, x
, GEN_INT (codes
[i
].value
));
3657 emit_insn (gen_rtx_SET (dest
, x
));
3660 /* Subroutine of mips_legitimize_move. Move constant SRC into register
3661 DEST given that SRC satisfies immediate_operand but doesn't satisfy
3665 mips_legitimize_const_move (machine_mode mode
, rtx dest
, rtx src
)
3669 /* Split moves of big integers into smaller pieces. */
3670 if (splittable_const_int_operand (src
, mode
))
3672 mips_move_integer (dest
, dest
, INTVAL (src
));
3676 /* Split moves of symbolic constants into high/low pairs. */
3677 if (mips_split_symbol (dest
, src
, MAX_MACHINE_MODE
, &src
))
3679 emit_insn (gen_rtx_SET (dest
, src
));
3683 /* Generate the appropriate access sequences for TLS symbols. */
3684 if (mips_tls_symbol_p (src
))
3686 mips_emit_move (dest
, mips_legitimize_tls_address (src
));
3690 /* If we have (const (plus symbol offset)), and that expression cannot
3691 be forced into memory, load the symbol first and add in the offset.
3692 In non-MIPS16 mode, prefer to do this even if the constant _can_ be
3693 forced into memory, as it usually produces better code. */
3694 split_const (src
, &base
, &offset
);
3695 if (offset
!= const0_rtx
3696 && (targetm
.cannot_force_const_mem (mode
, src
)
3697 || (!TARGET_MIPS16
&& can_create_pseudo_p ())))
3699 base
= mips_force_temporary (dest
, base
);
3700 mips_emit_move (dest
, mips_add_offset (NULL
, base
, INTVAL (offset
)));
3704 src
= force_const_mem (mode
, src
);
3706 /* When using explicit relocs, constant pool references are sometimes
3707 not legitimate addresses. */
3708 mips_split_symbol (dest
, XEXP (src
, 0), mode
, &XEXP (src
, 0));
3709 mips_emit_move (dest
, src
);
3712 /* If (set DEST SRC) is not a valid move instruction, emit an equivalent
3713 sequence that is valid. */
3716 mips_legitimize_move (machine_mode mode
, rtx dest
, rtx src
)
3718 /* Both src and dest are non-registers; one special case is supported where
3719 the source is (const_int 0) and the store can source the zero register.
3720 MIPS16 and MSA are never able to source the zero register directly in
3721 memory operations. */
3722 if (!register_operand (dest
, mode
)
3723 && !register_operand (src
, mode
)
3724 && (TARGET_MIPS16
|| !const_0_operand (src
, mode
)
3725 || MSA_SUPPORTED_MODE_P (mode
)))
3727 mips_emit_move (dest
, force_reg (mode
, src
));
3731 /* We need to deal with constants that would be legitimate
3732 immediate_operands but aren't legitimate move_operands. */
3733 if (CONSTANT_P (src
) && !move_operand (src
, mode
))
3735 mips_legitimize_const_move (mode
, dest
, src
);
3736 set_unique_reg_note (get_last_insn (), REG_EQUAL
, copy_rtx (src
));
3742 /* Return true if value X in context CONTEXT is a small-data address
3743 that can be rewritten as a LO_SUM. */
3746 mips_rewrite_small_data_p (rtx x
, enum mips_symbol_context context
)
3748 enum mips_symbol_type symbol_type
;
3750 return (mips_lo_relocs
[SYMBOL_GP_RELATIVE
]
3751 && !mips_split_p
[SYMBOL_GP_RELATIVE
]
3752 && mips_symbolic_constant_p (x
, context
, &symbol_type
)
3753 && symbol_type
== SYMBOL_GP_RELATIVE
);
3756 /* Return true if OP refers to small data symbols directly, not through
3757 a LO_SUM. CONTEXT is the context in which X appears. */
3760 mips_small_data_pattern_1 (rtx x
, enum mips_symbol_context context
)
3762 subrtx_var_iterator::array_type array
;
3763 FOR_EACH_SUBRTX_VAR (iter
, array
, x
, ALL
)
3767 /* Ignore things like "g" constraints in asms. We make no particular
3768 guarantee about which symbolic constants are acceptable as asm operands
3769 versus which must be forced into a GPR. */
3770 if (GET_CODE (x
) == LO_SUM
|| GET_CODE (x
) == ASM_OPERANDS
)
3771 iter
.skip_subrtxes ();
3774 if (mips_small_data_pattern_1 (XEXP (x
, 0), SYMBOL_CONTEXT_MEM
))
3776 iter
.skip_subrtxes ();
3778 else if (mips_rewrite_small_data_p (x
, context
))
3784 /* Return true if OP refers to small data symbols directly, not through
3788 mips_small_data_pattern_p (rtx op
)
3790 return mips_small_data_pattern_1 (op
, SYMBOL_CONTEXT_LEA
);
3793 /* Rewrite *LOC so that it refers to small data using explicit
3794 relocations. CONTEXT is the context in which *LOC appears. */
3797 mips_rewrite_small_data_1 (rtx
*loc
, enum mips_symbol_context context
)
3799 subrtx_ptr_iterator::array_type array
;
3800 FOR_EACH_SUBRTX_PTR (iter
, array
, loc
, ALL
)
3805 mips_rewrite_small_data_1 (&XEXP (*loc
, 0), SYMBOL_CONTEXT_MEM
);
3806 iter
.skip_subrtxes ();
3808 else if (mips_rewrite_small_data_p (*loc
, context
))
3810 *loc
= gen_rtx_LO_SUM (Pmode
, pic_offset_table_rtx
, *loc
);
3811 iter
.skip_subrtxes ();
3813 else if (GET_CODE (*loc
) == LO_SUM
)
3814 iter
.skip_subrtxes ();
3818 /* Rewrite instruction pattern PATTERN so that it refers to small data
3819 using explicit relocations. */
3822 mips_rewrite_small_data (rtx pattern
)
3824 pattern
= copy_insn (pattern
);
3825 mips_rewrite_small_data_1 (&pattern
, SYMBOL_CONTEXT_LEA
);
3829 /* The cost of loading values from the constant pool. It should be
3830 larger than the cost of any constant we want to synthesize inline. */
3831 #define CONSTANT_POOL_COST COSTS_N_INSNS (TARGET_MIPS16 ? 4 : 8)
3833 /* Return the cost of X when used as an operand to the MIPS16 instruction
3834 that implements CODE. Return -1 if there is no such instruction, or if
3835 X is not a valid immediate operand for it. */
3838 mips16_constant_cost (int code
, HOST_WIDE_INT x
)
3845 /* Shifts by between 1 and 8 bits (inclusive) are unextended,
3846 other shifts are extended. The shift patterns truncate the shift
3847 count to the right size, so there are no out-of-range values. */
3848 if (IN_RANGE (x
, 1, 8))
3850 return COSTS_N_INSNS (1);
3853 if (IN_RANGE (x
, -128, 127))
3855 if (SMALL_OPERAND (x
))
3856 return COSTS_N_INSNS (1);
3860 /* Like LE, but reject the always-true case. */
3865 /* We add 1 to the immediate and use SLT. */
3869 /* We can use CMPI for an xor with an unsigned 16-bit X. */
3872 if (IN_RANGE (x
, 0, 255))
3874 if (SMALL_OPERAND_UNSIGNED (x
))
3875 return COSTS_N_INSNS (1);
3880 /* Equality comparisons with 0 are cheap. */
3890 /* Return true if there is a non-MIPS16 instruction that implements CODE
3891 and if that instruction accepts X as an immediate operand. */
3894 mips_immediate_operand_p (int code
, HOST_WIDE_INT x
)
3901 /* All shift counts are truncated to a valid constant. */
3906 /* Likewise rotates, if the target supports rotates at all. */
3912 /* These instructions take 16-bit unsigned immediates. */
3913 return SMALL_OPERAND_UNSIGNED (x
);
3918 /* These instructions take 16-bit signed immediates. */
3919 return SMALL_OPERAND (x
);
3925 /* The "immediate" forms of these instructions are really
3926 implemented as comparisons with register 0. */
3931 /* Likewise, meaning that the only valid immediate operand is 1. */
3935 /* We add 1 to the immediate and use SLT. */
3936 return SMALL_OPERAND (x
+ 1);
3939 /* Likewise SLTU, but reject the always-true case. */
3940 return SMALL_OPERAND (x
+ 1) && x
+ 1 != 0;
3944 /* The bit position and size are immediate operands. */
3945 return ISA_HAS_EXT_INS
;
3948 /* By default assume that $0 can be used for 0. */
3953 /* Return the cost of binary operation X, given that the instruction
3954 sequence for a word-sized or smaller operation has cost SINGLE_COST
3955 and that the sequence of a double-word operation has cost DOUBLE_COST.
3956 If SPEED is true, optimize for speed otherwise optimize for size. */
3959 mips_binary_cost (rtx x
, int single_cost
, int double_cost
, bool speed
)
3963 if (GET_MODE_SIZE (GET_MODE (x
)) == UNITS_PER_WORD
* 2)
3968 + set_src_cost (XEXP (x
, 0), GET_MODE (x
), speed
)
3969 + rtx_cost (XEXP (x
, 1), GET_MODE (x
), GET_CODE (x
), 1, speed
));
3972 /* Return the cost of floating-point multiplications of mode MODE. */
3975 mips_fp_mult_cost (machine_mode mode
)
3977 return mode
== DFmode
? mips_cost
->fp_mult_df
: mips_cost
->fp_mult_sf
;
3980 /* Return the cost of floating-point divisions of mode MODE. */
3983 mips_fp_div_cost (machine_mode mode
)
3985 return mode
== DFmode
? mips_cost
->fp_div_df
: mips_cost
->fp_div_sf
;
3988 /* Return the cost of sign-extending OP to mode MODE, not including the
3989 cost of OP itself. */
3992 mips_sign_extend_cost (machine_mode mode
, rtx op
)
3995 /* Extended loads are as cheap as unextended ones. */
3998 if (TARGET_64BIT
&& mode
== DImode
&& GET_MODE (op
) == SImode
)
3999 /* A sign extension from SImode to DImode in 64-bit mode is free. */
4002 if (ISA_HAS_SEB_SEH
|| GENERATE_MIPS16E
)
4003 /* We can use SEB or SEH. */
4004 return COSTS_N_INSNS (1);
4006 /* We need to use a shift left and a shift right. */
4007 return COSTS_N_INSNS (TARGET_MIPS16
? 4 : 2);
4010 /* Return the cost of zero-extending OP to mode MODE, not including the
4011 cost of OP itself. */
4014 mips_zero_extend_cost (machine_mode mode
, rtx op
)
4017 /* Extended loads are as cheap as unextended ones. */
4020 if (TARGET_64BIT
&& mode
== DImode
&& GET_MODE (op
) == SImode
)
4021 /* We need a shift left by 32 bits and a shift right by 32 bits. */
4022 return COSTS_N_INSNS (TARGET_MIPS16
? 4 : 2);
4024 if (GENERATE_MIPS16E
)
4025 /* We can use ZEB or ZEH. */
4026 return COSTS_N_INSNS (1);
4029 /* We need to load 0xff or 0xffff into a register and use AND. */
4030 return COSTS_N_INSNS (GET_MODE (op
) == QImode
? 2 : 3);
4032 /* We can use ANDI. */
4033 return COSTS_N_INSNS (1);
4036 /* Return the cost of moving between two registers of mode MODE,
4037 assuming that the move will be in pieces of at most UNITS bytes. */
4040 mips_set_reg_reg_piece_cost (machine_mode mode
, unsigned int units
)
4042 return COSTS_N_INSNS ((GET_MODE_SIZE (mode
) + units
- 1) / units
);
4045 /* Return the cost of moving between two registers of mode MODE. */
4048 mips_set_reg_reg_cost (machine_mode mode
)
4050 switch (GET_MODE_CLASS (mode
))
4053 return mips_set_reg_reg_piece_cost (mode
, GET_MODE_SIZE (CCmode
));
4056 case MODE_COMPLEX_FLOAT
:
4057 case MODE_VECTOR_FLOAT
:
4058 if (TARGET_HARD_FLOAT
)
4059 return mips_set_reg_reg_piece_cost (mode
, UNITS_PER_HWFPVALUE
);
4063 return mips_set_reg_reg_piece_cost (mode
, UNITS_PER_WORD
);
4067 /* Implement TARGET_RTX_COSTS. */
4070 mips_rtx_costs (rtx x
, machine_mode mode
, int outer_code
,
4071 int opno ATTRIBUTE_UNUSED
, int *total
, bool speed
)
4073 int code
= GET_CODE (x
);
4074 bool float_mode_p
= FLOAT_MODE_P (mode
);
4078 /* The cost of a COMPARE is hard to define for MIPS. COMPAREs don't
4079 appear in the instruction stream, and the cost of a comparison is
4080 really the cost of the branch or scc condition. At the time of
4081 writing, GCC only uses an explicit outer COMPARE code when optabs
4082 is testing whether a constant is expensive enough to force into a
4083 register. We want optabs to pass such constants through the MIPS
4084 expanders instead, so make all constants very cheap here. */
4085 if (outer_code
== COMPARE
)
4087 gcc_assert (CONSTANT_P (x
));
4095 /* Treat *clear_upper32-style ANDs as having zero cost in the
4096 second operand. The cost is entirely in the first operand.
4098 ??? This is needed because we would otherwise try to CSE
4099 the constant operand. Although that's the right thing for
4100 instructions that continue to be a register operation throughout
4101 compilation, it is disastrous for instructions that could
4102 later be converted into a memory operation. */
4104 && outer_code
== AND
4105 && UINTVAL (x
) == 0xffffffff)
4113 cost
= mips16_constant_cost (outer_code
, INTVAL (x
));
4122 /* When not optimizing for size, we care more about the cost
4123 of hot code, and hot code is often in a loop. If a constant
4124 operand needs to be forced into a register, we will often be
4125 able to hoist the constant load out of the loop, so the load
4126 should not contribute to the cost. */
4127 if (speed
|| mips_immediate_operand_p (outer_code
, INTVAL (x
)))
4139 if (force_to_mem_operand (x
, VOIDmode
))
4141 *total
= COSTS_N_INSNS (1);
4144 cost
= mips_const_insns (x
);
4147 /* If the constant is likely to be stored in a GPR, SETs of
4148 single-insn constants are as cheap as register sets; we
4149 never want to CSE them.
4151 Don't reduce the cost of storing a floating-point zero in
4152 FPRs. If we have a zero in an FPR for other reasons, we
4153 can get better cfg-cleanup and delayed-branch results by
4154 using it consistently, rather than using $0 sometimes and
4155 an FPR at other times. Also, moves between floating-point
4156 registers are sometimes cheaper than (D)MTC1 $0. */
4158 && outer_code
== SET
4159 && !(float_mode_p
&& TARGET_HARD_FLOAT
))
4161 /* When non-MIPS16 code loads a constant N>1 times, we rarely
4162 want to CSE the constant itself. It is usually better to
4163 have N copies of the last operation in the sequence and one
4164 shared copy of the other operations. (Note that this is
4165 not true for MIPS16 code, where the final operation in the
4166 sequence is often an extended instruction.)
4168 Also, if we have a CONST_INT, we don't know whether it is
4169 for a word or doubleword operation, so we cannot rely on
4170 the result of mips_build_integer. */
4171 else if (!TARGET_MIPS16
4172 && (outer_code
== SET
|| GET_MODE (x
) == VOIDmode
))
4174 *total
= COSTS_N_INSNS (cost
);
4177 /* The value will need to be fetched from the constant pool. */
4178 *total
= CONSTANT_POOL_COST
;
4182 /* If the address is legitimate, return the number of
4183 instructions it needs. */
4185 cost
= mips_address_insns (addr
, mode
, true);
4188 *total
= COSTS_N_INSNS (cost
+ 1);
4191 /* Check for a scaled indexed address. */
4192 if (mips_lwxs_address_p (addr
)
4193 || mips_lx_address_p (addr
, mode
))
4195 *total
= COSTS_N_INSNS (2);
4198 /* Otherwise use the default handling. */
4202 *total
= COSTS_N_INSNS (6);
4206 *total
= COSTS_N_INSNS (GET_MODE_SIZE (mode
) > UNITS_PER_WORD
? 2 : 1);
4210 /* Check for a *clear_upper32 pattern and treat it like a zero
4211 extension. See the pattern's comment for details. */
4214 && CONST_INT_P (XEXP (x
, 1))
4215 && UINTVAL (XEXP (x
, 1)) == 0xffffffff)
4217 *total
= (mips_zero_extend_cost (mode
, XEXP (x
, 0))
4218 + set_src_cost (XEXP (x
, 0), mode
, speed
));
4221 if (ISA_HAS_CINS
&& CONST_INT_P (XEXP (x
, 1)))
4223 rtx op
= XEXP (x
, 0);
4224 if (GET_CODE (op
) == ASHIFT
4225 && CONST_INT_P (XEXP (op
, 1))
4226 && mask_low_and_shift_p (mode
, XEXP (x
, 1), XEXP (op
, 1), 32))
4228 *total
= COSTS_N_INSNS (1);
4229 *total
+= set_src_cost (XEXP (op
, 0), mode
, speed
);
4233 /* (AND (NOT op0) (NOT op1) is a nor operation that can be done in
4234 a single instruction. */
4236 && GET_CODE (XEXP (x
, 0)) == NOT
4237 && GET_CODE (XEXP (x
, 1)) == NOT
)
4239 cost
= GET_MODE_SIZE (mode
) > UNITS_PER_WORD
? 2 : 1;
4240 *total
= (COSTS_N_INSNS (cost
)
4241 + set_src_cost (XEXP (XEXP (x
, 0), 0), mode
, speed
)
4242 + set_src_cost (XEXP (XEXP (x
, 1), 0), mode
, speed
));
4250 /* Double-word operations use two single-word operations. */
4251 *total
= mips_binary_cost (x
, COSTS_N_INSNS (1), COSTS_N_INSNS (2),
4260 if (CONSTANT_P (XEXP (x
, 1)))
4261 *total
= mips_binary_cost (x
, COSTS_N_INSNS (1), COSTS_N_INSNS (4),
4264 *total
= mips_binary_cost (x
, COSTS_N_INSNS (1), COSTS_N_INSNS (12),
4270 *total
= mips_cost
->fp_add
;
4272 *total
= COSTS_N_INSNS (4);
4276 /* Low-part immediates need an extended MIPS16 instruction. */
4277 *total
= (COSTS_N_INSNS (TARGET_MIPS16
? 2 : 1)
4278 + set_src_cost (XEXP (x
, 0), mode
, speed
));
4297 /* Branch comparisons have VOIDmode, so use the first operand's
4299 mode
= GET_MODE (XEXP (x
, 0));
4300 if (FLOAT_MODE_P (mode
))
4302 *total
= mips_cost
->fp_add
;
4305 *total
= mips_binary_cost (x
, COSTS_N_INSNS (1), COSTS_N_INSNS (4),
4310 if (float_mode_p
&& ISA_HAS_UNFUSED_MADD4
&& !HONOR_SIGNED_ZEROS (mode
))
4312 /* See if we can use NMADD or NMSUB via the *nmadd4<mode>_fastmath
4313 or *nmsub4<mode>_fastmath patterns. These patterns check for
4314 HONOR_SIGNED_ZEROS so we check here too. */
4315 rtx op0
= XEXP (x
, 0);
4316 rtx op1
= XEXP (x
, 1);
4317 if (GET_CODE (op0
) == MULT
&& GET_CODE (XEXP (op0
, 0)) == NEG
)
4319 *total
= (mips_fp_mult_cost (mode
)
4320 + set_src_cost (XEXP (XEXP (op0
, 0), 0), mode
, speed
)
4321 + set_src_cost (XEXP (op0
, 1), mode
, speed
)
4322 + set_src_cost (op1
, mode
, speed
));
4325 if (GET_CODE (op1
) == MULT
)
4327 *total
= (mips_fp_mult_cost (mode
)
4328 + set_src_cost (op0
, mode
, speed
)
4329 + set_src_cost (XEXP (op1
, 0), mode
, speed
)
4330 + set_src_cost (XEXP (op1
, 1), mode
, speed
));
4339 /* If this is part of a MADD or MSUB, treat the PLUS as
4341 if (ISA_HAS_UNFUSED_MADD4
&& GET_CODE (XEXP (x
, 0)) == MULT
)
4344 *total
= mips_cost
->fp_add
;
4348 /* If it's an add + mult (which is equivalent to shift left) and
4349 it's immediate operand satisfies const_immlsa_operand predicate. */
4350 if (((ISA_HAS_LSA
&& mode
== SImode
)
4351 || (ISA_HAS_DLSA
&& mode
== DImode
))
4352 && GET_CODE (XEXP (x
, 0)) == MULT
)
4354 rtx op2
= XEXP (XEXP (x
, 0), 1);
4355 if (const_immlsa_operand (op2
, mode
))
4357 *total
= (COSTS_N_INSNS (1)
4358 + set_src_cost (XEXP (XEXP (x
, 0), 0), mode
, speed
)
4359 + set_src_cost (XEXP (x
, 1), mode
, speed
));
4364 /* Double-word operations require three single-word operations and
4365 an SLTU. The MIPS16 version then needs to move the result of
4366 the SLTU from $24 to a MIPS16 register. */
4367 *total
= mips_binary_cost (x
, COSTS_N_INSNS (1),
4368 COSTS_N_INSNS (TARGET_MIPS16
? 5 : 4),
4373 if (float_mode_p
&& ISA_HAS_UNFUSED_MADD4
)
4375 /* See if we can use NMADD or NMSUB via the *nmadd4<mode> or
4376 *nmsub4<mode> patterns. */
4377 rtx op
= XEXP (x
, 0);
4378 if ((GET_CODE (op
) == PLUS
|| GET_CODE (op
) == MINUS
)
4379 && GET_CODE (XEXP (op
, 0)) == MULT
)
4381 *total
= (mips_fp_mult_cost (mode
)
4382 + set_src_cost (XEXP (XEXP (op
, 0), 0), mode
, speed
)
4383 + set_src_cost (XEXP (XEXP (op
, 0), 1), mode
, speed
)
4384 + set_src_cost (XEXP (op
, 1), mode
, speed
));
4390 *total
= mips_cost
->fp_add
;
4392 *total
= COSTS_N_INSNS (GET_MODE_SIZE (mode
) > UNITS_PER_WORD
? 4 : 1);
4396 *total
= mips_fp_mult_cost (mode
);
4401 *total
= mips_fp_mult_cost (mode
);
4402 else if (mode
== DImode
&& !TARGET_64BIT
)
4403 /* Synthesized from 2 mulsi3s, 1 mulsidi3 and two additions,
4404 where the mulsidi3 always includes an MFHI and an MFLO. */
4406 ? mips_cost
->int_mult_si
* 3 + 6
4407 : COSTS_N_INSNS (ISA_HAS_MUL3
? 7 : 9));
4409 *total
= COSTS_N_INSNS ((ISA_HAS_MUL3
|| ISA_HAS_R6MUL
) ? 1 : 2) + 1;
4410 else if (mode
== DImode
)
4411 *total
= mips_cost
->int_mult_di
;
4413 *total
= mips_cost
->int_mult_si
;
4417 /* Check for a reciprocal. */
4419 && ISA_HAS_FP_RECIP_RSQRT (mode
)
4420 && flag_unsafe_math_optimizations
4421 && XEXP (x
, 0) == CONST1_RTX (mode
))
4423 if (outer_code
== SQRT
|| GET_CODE (XEXP (x
, 1)) == SQRT
)
4424 /* An rsqrt<mode>a or rsqrt<mode>b pattern. Count the
4425 division as being free. */
4426 *total
= set_src_cost (XEXP (x
, 1), mode
, speed
);
4428 *total
= (mips_fp_div_cost (mode
)
4429 + set_src_cost (XEXP (x
, 1), mode
, speed
));
4438 *total
= mips_fp_div_cost (mode
);
4447 /* It is our responsibility to make division by a power of 2
4448 as cheap as 2 register additions if we want the division
4449 expanders to be used for such operations; see the setting
4450 of sdiv_pow2_cheap in optabs.c. Using (D)DIV for MIPS16
4451 should always produce shorter code than using
4452 expand_sdiv2_pow2. */
4454 && CONST_INT_P (XEXP (x
, 1))
4455 && exact_log2 (INTVAL (XEXP (x
, 1))) >= 0)
4457 *total
= COSTS_N_INSNS (2);
4458 *total
+= set_src_cost (XEXP (x
, 0), mode
, speed
);
4461 *total
= COSTS_N_INSNS (mips_idiv_insns (mode
));
4463 else if (mode
== DImode
)
4464 *total
= mips_cost
->int_div_di
;
4466 *total
= mips_cost
->int_div_si
;
4470 *total
= mips_sign_extend_cost (mode
, XEXP (x
, 0));
4474 if (outer_code
== SET
4476 && (GET_CODE (XEXP (x
, 0)) == TRUNCATE
4477 || GET_CODE (XEXP (x
, 0)) == SUBREG
)
4478 && GET_MODE (XEXP (x
, 0)) == QImode
4479 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == PLUS
)
4481 *total
= set_src_cost (XEXP (XEXP (x
, 0), 0), VOIDmode
, speed
);
4484 *total
= mips_zero_extend_cost (mode
, XEXP (x
, 0));
4487 /* Costings for highpart multiplies. Matching patterns of the form:
4489 (lshiftrt:DI (mult:DI (sign_extend:DI (...)
4490 (sign_extend:DI (...))
4494 && (GET_CODE (XEXP (x
, 0)) == ASHIFTRT
4495 || GET_CODE (XEXP (x
, 0)) == LSHIFTRT
)
4496 && CONST_INT_P (XEXP (XEXP (x
, 0), 1))
4497 && ((INTVAL (XEXP (XEXP (x
, 0), 1)) == 32
4498 && GET_MODE (XEXP (x
, 0)) == DImode
)
4500 && INTVAL (XEXP (XEXP (x
, 0), 1)) == 64
4501 && GET_MODE (XEXP (x
, 0)) == TImode
))
4502 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == MULT
4503 && ((GET_CODE (XEXP (XEXP (XEXP (x
, 0), 0), 0)) == SIGN_EXTEND
4504 && GET_CODE (XEXP (XEXP (XEXP (x
, 0), 0), 1)) == SIGN_EXTEND
)
4505 || (GET_CODE (XEXP (XEXP (XEXP (x
, 0), 0), 0)) == ZERO_EXTEND
4506 && (GET_CODE (XEXP (XEXP (XEXP (x
, 0), 0), 1))
4510 *total
= COSTS_N_INSNS (1) + 1;
4511 else if (mode
== DImode
)
4512 *total
= mips_cost
->int_mult_di
;
4514 *total
= mips_cost
->int_mult_si
;
4516 /* Sign extension is free, zero extension costs for DImode when
4517 on a 64bit core / when DMUL is present. */
4518 for (int i
= 0; i
< 2; ++i
)
4520 rtx op
= XEXP (XEXP (XEXP (x
, 0), 0), i
);
4522 && GET_CODE (op
) == ZERO_EXTEND
4523 && GET_MODE (op
) == DImode
)
4524 *total
+= rtx_cost (op
, DImode
, MULT
, i
, speed
);
4526 *total
+= rtx_cost (XEXP (op
, 0), VOIDmode
, GET_CODE (op
),
4535 case UNSIGNED_FLOAT
:
4538 case FLOAT_TRUNCATE
:
4539 *total
= mips_cost
->fp_add
;
4543 if (register_operand (SET_DEST (x
), VOIDmode
)
4544 && reg_or_0_operand (SET_SRC (x
), VOIDmode
))
4546 *total
= mips_set_reg_reg_cost (GET_MODE (SET_DEST (x
)));
4556 /* Implement TARGET_ADDRESS_COST. */
4559 mips_address_cost (rtx addr
, machine_mode mode
,
4560 addr_space_t as ATTRIBUTE_UNUSED
,
4561 bool speed ATTRIBUTE_UNUSED
)
4563 return mips_address_insns (addr
, mode
, false);
4566 /* Implement TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P. */
4569 mips_no_speculation_in_delay_slots_p ()
4571 return TARGET_CB_MAYBE
;
4574 /* Information about a single instruction in a multi-instruction
4576 struct mips_multi_member
{
4577 /* True if this is a label, false if it is code. */
4580 /* The output_asm_insn format of the instruction. */
4583 /* The operands to the instruction. */
4584 rtx operands
[MAX_RECOG_OPERANDS
];
4586 typedef struct mips_multi_member mips_multi_member
;
4588 /* The instructions that make up the current multi-insn sequence. */
4589 static vec
<mips_multi_member
> mips_multi_members
;
4591 /* How many instructions (as opposed to labels) are in the current
4592 multi-insn sequence. */
4593 static unsigned int mips_multi_num_insns
;
4595 /* Start a new multi-insn sequence. */
4598 mips_multi_start (void)
4600 mips_multi_members
.truncate (0);
4601 mips_multi_num_insns
= 0;
4604 /* Add a new, zero initialized member to the current multi-insn sequence. */
4606 static struct mips_multi_member
*
4607 mips_multi_add (void)
4609 mips_multi_member empty
;
4610 memset (&empty
, 0, sizeof (empty
));
4611 return mips_multi_members
.safe_push (empty
);
4614 /* Add a normal insn with the given asm format to the current multi-insn
4615 sequence. The other arguments are a null-terminated list of operands. */
4618 mips_multi_add_insn (const char *format
, ...)
4620 struct mips_multi_member
*member
;
4625 member
= mips_multi_add ();
4626 member
->is_label_p
= false;
4627 member
->format
= format
;
4628 va_start (ap
, format
);
4630 while ((op
= va_arg (ap
, rtx
)))
4631 member
->operands
[i
++] = op
;
4633 mips_multi_num_insns
++;
4636 /* Add the given label definition to the current multi-insn sequence.
4637 The definition should include the colon. */
4640 mips_multi_add_label (const char *label
)
4642 struct mips_multi_member
*member
;
4644 member
= mips_multi_add ();
4645 member
->is_label_p
= true;
4646 member
->format
= label
;
4649 /* Return the index of the last member of the current multi-insn sequence. */
4652 mips_multi_last_index (void)
4654 return mips_multi_members
.length () - 1;
4657 /* Add a copy of an existing instruction to the current multi-insn
4658 sequence. I is the index of the instruction that should be copied. */
4661 mips_multi_copy_insn (unsigned int i
)
4663 struct mips_multi_member
*member
;
4665 member
= mips_multi_add ();
4666 memcpy (member
, &mips_multi_members
[i
], sizeof (*member
));
4667 gcc_assert (!member
->is_label_p
);
4670 /* Change the operand of an existing instruction in the current
4671 multi-insn sequence. I is the index of the instruction,
4672 OP is the index of the operand, and X is the new value. */
4675 mips_multi_set_operand (unsigned int i
, unsigned int op
, rtx x
)
4677 mips_multi_members
[i
].operands
[op
] = x
;
4680 /* Write out the asm code for the current multi-insn sequence. */
4683 mips_multi_write (void)
4685 struct mips_multi_member
*member
;
4688 FOR_EACH_VEC_ELT (mips_multi_members
, i
, member
)
4689 if (member
->is_label_p
)
4690 fprintf (asm_out_file
, "%s\n", member
->format
);
4692 output_asm_insn (member
->format
, member
->operands
);
4695 /* Return one word of double-word value OP, taking into account the fixed
4696 endianness of certain registers. HIGH_P is true to select the high part,
4697 false to select the low part. */
4700 mips_subword (rtx op
, bool high_p
)
4702 unsigned int byte
, offset
;
4705 mode
= GET_MODE (op
);
4706 if (mode
== VOIDmode
)
4707 mode
= TARGET_64BIT
? TImode
: DImode
;
4709 if (TARGET_BIG_ENDIAN
? !high_p
: high_p
)
4710 byte
= UNITS_PER_WORD
;
4714 if (FP_REG_RTX_P (op
))
4716 /* Paired FPRs are always ordered little-endian. */
4717 offset
= (UNITS_PER_WORD
< UNITS_PER_HWFPVALUE
? high_p
: byte
!= 0);
4718 return gen_rtx_REG (word_mode
, REGNO (op
) + offset
);
4722 return mips_rewrite_small_data (adjust_address (op
, word_mode
, byte
));
4724 return simplify_gen_subreg (word_mode
, op
, mode
, byte
);
4727 /* Return true if SRC should be moved into DEST using "MULT $0, $0".
4728 SPLIT_TYPE is the condition under which moves should be split. */
4731 mips_mult_move_p (rtx dest
, rtx src
, enum mips_split_type split_type
)
4733 return ((split_type
!= SPLIT_FOR_SPEED
4734 || mips_tuning_info
.fast_mult_zero_zero_p
)
4735 && src
== const0_rtx
4737 && GET_MODE_SIZE (GET_MODE (dest
)) == 2 * UNITS_PER_WORD
4738 && (ISA_HAS_DSP_MULT
4739 ? ACC_REG_P (REGNO (dest
))
4740 : MD_REG_P (REGNO (dest
))));
4743 /* Return true if a move from SRC to DEST should be split into two.
4744 SPLIT_TYPE describes the split condition. */
4747 mips_split_move_p (rtx dest
, rtx src
, enum mips_split_type split_type
)
4749 /* Check whether the move can be done using some variant of MULT $0,$0. */
4750 if (mips_mult_move_p (dest
, src
, split_type
))
4753 /* FPR-to-FPR moves can be done in a single instruction, if they're
4755 unsigned int size
= GET_MODE_SIZE (GET_MODE (dest
));
4756 if (size
== 8 && FP_REG_RTX_P (src
) && FP_REG_RTX_P (dest
))
4759 /* Check for floating-point loads and stores. */
4760 if (size
== 8 && ISA_HAS_LDC1_SDC1
)
4762 if (FP_REG_RTX_P (dest
) && MEM_P (src
))
4764 if (FP_REG_RTX_P (src
) && MEM_P (dest
))
4768 /* Check if MSA moves need splitting. */
4769 if (MSA_SUPPORTED_MODE_P (GET_MODE (dest
)))
4770 return mips_split_128bit_move_p (dest
, src
);
4772 /* Otherwise split all multiword moves. */
4773 return size
> UNITS_PER_WORD
;
4776 /* Split a move from SRC to DEST, given that mips_split_move_p holds.
4777 SPLIT_TYPE describes the split condition. */
4780 mips_split_move (rtx dest
, rtx src
, enum mips_split_type split_type
)
4784 gcc_checking_assert (mips_split_move_p (dest
, src
, split_type
));
4785 if (MSA_SUPPORTED_MODE_P (GET_MODE (dest
)))
4786 mips_split_128bit_move (dest
, src
);
4787 else if (FP_REG_RTX_P (dest
) || FP_REG_RTX_P (src
))
4789 if (!TARGET_64BIT
&& GET_MODE (dest
) == DImode
)
4790 emit_insn (gen_move_doubleword_fprdi (dest
, src
));
4791 else if (!TARGET_64BIT
&& GET_MODE (dest
) == DFmode
)
4792 emit_insn (gen_move_doubleword_fprdf (dest
, src
));
4793 else if (!TARGET_64BIT
&& GET_MODE (dest
) == V2SFmode
)
4794 emit_insn (gen_move_doubleword_fprv2sf (dest
, src
));
4795 else if (!TARGET_64BIT
&& GET_MODE (dest
) == V2SImode
)
4796 emit_insn (gen_move_doubleword_fprv2si (dest
, src
));
4797 else if (!TARGET_64BIT
&& GET_MODE (dest
) == V4HImode
)
4798 emit_insn (gen_move_doubleword_fprv4hi (dest
, src
));
4799 else if (!TARGET_64BIT
&& GET_MODE (dest
) == V8QImode
)
4800 emit_insn (gen_move_doubleword_fprv8qi (dest
, src
));
4801 else if (TARGET_64BIT
&& GET_MODE (dest
) == TFmode
)
4802 emit_insn (gen_move_doubleword_fprtf (dest
, src
));
4806 else if (REG_P (dest
) && REGNO (dest
) == MD_REG_FIRST
)
4808 low_dest
= mips_subword (dest
, false);
4809 mips_emit_move (low_dest
, mips_subword (src
, false));
4811 emit_insn (gen_mthidi_ti (dest
, mips_subword (src
, true), low_dest
));
4813 emit_insn (gen_mthisi_di (dest
, mips_subword (src
, true), low_dest
));
4815 else if (REG_P (src
) && REGNO (src
) == MD_REG_FIRST
)
4817 mips_emit_move (mips_subword (dest
, false), mips_subword (src
, false));
4819 emit_insn (gen_mfhidi_ti (mips_subword (dest
, true), src
));
4821 emit_insn (gen_mfhisi_di (mips_subword (dest
, true), src
));
4825 /* The operation can be split into two normal moves. Decide in
4826 which order to do them. */
4827 low_dest
= mips_subword (dest
, false);
4828 if (REG_P (low_dest
)
4829 && reg_overlap_mentioned_p (low_dest
, src
))
4831 mips_emit_move (mips_subword (dest
, true), mips_subword (src
, true));
4832 mips_emit_move (low_dest
, mips_subword (src
, false));
4836 mips_emit_move (low_dest
, mips_subword (src
, false));
4837 mips_emit_move (mips_subword (dest
, true), mips_subword (src
, true));
4842 /* Return the split type for instruction INSN. */
4844 static enum mips_split_type
4845 mips_insn_split_type (rtx insn
)
4847 basic_block bb
= BLOCK_FOR_INSN (insn
);
4850 if (optimize_bb_for_speed_p (bb
))
4851 return SPLIT_FOR_SPEED
;
4853 return SPLIT_FOR_SIZE
;
4855 /* Once CFG information has been removed, we should trust the optimization
4856 decisions made by previous passes and only split where necessary. */
4857 return SPLIT_IF_NECESSARY
;
4860 /* Return true if a 128-bit move from SRC to DEST should be split. */
4863 mips_split_128bit_move_p (rtx dest
, rtx src
)
4865 /* MSA-to-MSA moves can be done in a single instruction. */
4866 if (FP_REG_RTX_P (src
) && FP_REG_RTX_P (dest
))
4869 /* Check for MSA loads and stores. */
4870 if (FP_REG_RTX_P (dest
) && MEM_P (src
))
4872 if (FP_REG_RTX_P (src
) && MEM_P (dest
))
4875 /* Check for MSA set to an immediate const vector with valid replicated
4877 if (FP_REG_RTX_P (dest
)
4878 && mips_const_vector_same_int_p (src
, GET_MODE (src
), -512, 511))
4881 /* Check for MSA load zero immediate. */
4882 if (FP_REG_RTX_P (dest
) && src
== CONST0_RTX (GET_MODE (src
)))
4888 /* Split a 128-bit move from SRC to DEST. */
4891 mips_split_128bit_move (rtx dest
, rtx src
)
4894 rtx low_dest
, low_src
, d
, s
;
4896 if (FP_REG_RTX_P (dest
))
4898 gcc_assert (!MEM_P (src
));
4900 rtx new_dest
= dest
;
4903 if (GET_MODE (dest
) != V4SImode
)
4904 new_dest
= simplify_gen_subreg (V4SImode
, dest
, GET_MODE (dest
), 0);
4908 if (GET_MODE (dest
) != V2DImode
)
4909 new_dest
= simplify_gen_subreg (V2DImode
, dest
, GET_MODE (dest
), 0);
4912 for (byte
= 0, index
= 0; byte
< GET_MODE_SIZE (TImode
);
4913 byte
+= UNITS_PER_WORD
, index
++)
4915 s
= mips_subword_at_byte (src
, byte
);
4917 emit_insn (gen_msa_insert_w (new_dest
, s
, new_dest
,
4918 GEN_INT (1 << index
)));
4920 emit_insn (gen_msa_insert_d (new_dest
, s
, new_dest
,
4921 GEN_INT (1 << index
)));
4924 else if (FP_REG_RTX_P (src
))
4926 gcc_assert (!MEM_P (dest
));
4931 if (GET_MODE (src
) != V4SImode
)
4932 new_src
= simplify_gen_subreg (V4SImode
, src
, GET_MODE (src
), 0);
4936 if (GET_MODE (src
) != V2DImode
)
4937 new_src
= simplify_gen_subreg (V2DImode
, src
, GET_MODE (src
), 0);
4940 for (byte
= 0, index
= 0; byte
< GET_MODE_SIZE (TImode
);
4941 byte
+= UNITS_PER_WORD
, index
++)
4943 d
= mips_subword_at_byte (dest
, byte
);
4945 emit_insn (gen_msa_copy_s_w (d
, new_src
, GEN_INT (index
)));
4947 emit_insn (gen_msa_copy_s_d (d
, new_src
, GEN_INT (index
)));
4952 low_dest
= mips_subword_at_byte (dest
, 0);
4953 low_src
= mips_subword_at_byte (src
, 0);
4954 gcc_assert (REG_P (low_dest
) && REG_P (low_src
));
4955 /* Make sure the source register is not written before reading. */
4956 if (REGNO (low_dest
) <= REGNO (low_src
))
4958 for (byte
= 0; byte
< GET_MODE_SIZE (TImode
);
4959 byte
+= UNITS_PER_WORD
)
4961 d
= mips_subword_at_byte (dest
, byte
);
4962 s
= mips_subword_at_byte (src
, byte
);
4963 mips_emit_move (d
, s
);
4968 for (byte
= GET_MODE_SIZE (TImode
) - UNITS_PER_WORD
; byte
>= 0;
4969 byte
-= UNITS_PER_WORD
)
4971 d
= mips_subword_at_byte (dest
, byte
);
4972 s
= mips_subword_at_byte (src
, byte
);
4973 mips_emit_move (d
, s
);
4979 /* Split a COPY_S.D with operands DEST, SRC and INDEX. GEN is a function
4980 used to generate subregs. */
4983 mips_split_msa_copy_d (rtx dest
, rtx src
, rtx index
,
4984 rtx (*gen_fn
)(rtx
, rtx
, rtx
))
4986 gcc_assert ((GET_MODE (src
) == V2DImode
&& GET_MODE (dest
) == DImode
)
4987 || (GET_MODE (src
) == V2DFmode
&& GET_MODE (dest
) == DFmode
));
4989 /* Note that low is always from the lower index, and high is always
4990 from the higher index. */
4991 rtx low
= mips_subword (dest
, false);
4992 rtx high
= mips_subword (dest
, true);
4993 rtx new_src
= simplify_gen_subreg (V4SImode
, src
, GET_MODE (src
), 0);
4995 emit_insn (gen_fn (low
, new_src
, GEN_INT (INTVAL (index
) * 2)));
4996 emit_insn (gen_fn (high
, new_src
, GEN_INT (INTVAL (index
) * 2 + 1)));
4999 /* Split a INSERT.D with operand DEST, SRC1.INDEX and SRC2. */
5002 mips_split_msa_insert_d (rtx dest
, rtx src1
, rtx index
, rtx src2
)
5005 gcc_assert (GET_MODE (dest
) == GET_MODE (src1
));
5006 gcc_assert ((GET_MODE (dest
) == V2DImode
5007 && (GET_MODE (src2
) == DImode
|| src2
== const0_rtx
))
5008 || (GET_MODE (dest
) == V2DFmode
&& GET_MODE (src2
) == DFmode
));
5010 /* Note that low is always from the lower index, and high is always
5011 from the higher index. */
5012 rtx low
= mips_subword (src2
, false);
5013 rtx high
= mips_subword (src2
, true);
5014 rtx new_dest
= simplify_gen_subreg (V4SImode
, dest
, GET_MODE (dest
), 0);
5015 rtx new_src1
= simplify_gen_subreg (V4SImode
, src1
, GET_MODE (src1
), 0);
5016 i
= exact_log2 (INTVAL (index
));
5017 gcc_assert (i
!= -1);
5019 emit_insn (gen_msa_insert_w (new_dest
, low
, new_src1
,
5020 GEN_INT (1 << (i
* 2))));
5021 emit_insn (gen_msa_insert_w (new_dest
, high
, new_dest
,
5022 GEN_INT (1 << (i
* 2 + 1))));
5028 mips_split_msa_fill_d (rtx dest
, rtx src
)
5030 gcc_assert ((GET_MODE (dest
) == V2DImode
5031 && (GET_MODE (src
) == DImode
|| src
== const0_rtx
))
5032 || (GET_MODE (dest
) == V2DFmode
&& GET_MODE (src
) == DFmode
));
5034 /* Note that low is always from the lower index, and high is always
5035 from the higher index. */
5037 if (src
== const0_rtx
)
5044 low
= mips_subword (src
, false);
5045 high
= mips_subword (src
, true);
5047 rtx new_dest
= simplify_gen_subreg (V4SImode
, dest
, GET_MODE (dest
), 0);
5048 emit_insn (gen_msa_fill_w (new_dest
, low
));
5049 emit_insn (gen_msa_insert_w (new_dest
, high
, new_dest
, GEN_INT (1 << 1)));
5050 emit_insn (gen_msa_insert_w (new_dest
, high
, new_dest
, GEN_INT (1 << 3)));
5053 /* Return true if a move from SRC to DEST in INSN should be split. */
5056 mips_split_move_insn_p (rtx dest
, rtx src
, rtx insn
)
5058 return mips_split_move_p (dest
, src
, mips_insn_split_type (insn
));
5061 /* Split a move from SRC to DEST in INSN, given that mips_split_move_insn_p
5065 mips_split_move_insn (rtx dest
, rtx src
, rtx insn
)
5067 mips_split_move (dest
, src
, mips_insn_split_type (insn
));
5070 /* Return the appropriate instructions to move SRC into DEST. Assume
5071 that SRC is operand 1 and DEST is operand 0. */
5074 mips_output_move (rtx dest
, rtx src
)
5076 enum rtx_code dest_code
= GET_CODE (dest
);
5077 enum rtx_code src_code
= GET_CODE (src
);
5078 machine_mode mode
= GET_MODE (dest
);
5079 bool dbl_p
= (GET_MODE_SIZE (mode
) == 8);
5080 bool msa_p
= MSA_SUPPORTED_MODE_P (mode
);
5081 enum mips_symbol_type symbol_type
;
5083 if (mips_split_move_p (dest
, src
, SPLIT_IF_NECESSARY
))
5087 && dest_code
== REG
&& FP_REG_P (REGNO (dest
))
5088 && src_code
== CONST_VECTOR
5089 && CONST_INT_P (CONST_VECTOR_ELT (src
, 0)))
5091 gcc_assert (mips_const_vector_same_int_p (src
, mode
, -512, 511));
5092 return "ldi.%v0\t%w0,%E1";
5095 if ((src_code
== REG
&& GP_REG_P (REGNO (src
)))
5096 || (!TARGET_MIPS16
&& src
== CONST0_RTX (mode
)))
5098 if (dest_code
== REG
)
5100 if (GP_REG_P (REGNO (dest
)))
5101 return "move\t%0,%z1";
5103 if (mips_mult_move_p (dest
, src
, SPLIT_IF_NECESSARY
))
5105 if (ISA_HAS_DSP_MULT
)
5106 return "mult\t%q0,%.,%.";
5108 return "mult\t%.,%.";
5111 /* Moves to HI are handled by special .md insns. */
5112 if (REGNO (dest
) == LO_REGNUM
)
5115 if (DSP_ACC_REG_P (REGNO (dest
)))
5117 static char retval
[] = "mt__\t%z1,%q0";
5119 retval
[2] = reg_names
[REGNO (dest
)][4];
5120 retval
[3] = reg_names
[REGNO (dest
)][5];
5124 if (FP_REG_P (REGNO (dest
)))
5128 gcc_assert (src
== CONST0_RTX (GET_MODE (src
)));
5129 return "ldi.%v0\t%w0,0";
5132 return dbl_p
? "dmtc1\t%z1,%0" : "mtc1\t%z1,%0";
5135 if (ALL_COP_REG_P (REGNO (dest
)))
5137 static char retval
[] = "dmtc_\t%z1,%0";
5139 retval
[4] = COPNUM_AS_CHAR_FROM_REGNUM (REGNO (dest
));
5140 return dbl_p
? retval
: retval
+ 1;
5143 if (dest_code
== MEM
)
5144 switch (GET_MODE_SIZE (mode
))
5146 case 1: return "sb\t%z1,%0";
5147 case 2: return "sh\t%z1,%0";
5148 case 4: return "sw\t%z1,%0";
5149 case 8: return "sd\t%z1,%0";
5150 default: gcc_unreachable ();
5153 if (dest_code
== REG
&& GP_REG_P (REGNO (dest
)))
5155 if (src_code
== REG
)
5157 /* Moves from HI are handled by special .md insns. */
5158 if (REGNO (src
) == LO_REGNUM
)
5160 /* When generating VR4120 or VR4130 code, we use MACC and
5161 DMACC instead of MFLO. This avoids both the normal
5162 MIPS III HI/LO hazards and the errata related to
5165 return dbl_p
? "dmacc\t%0,%.,%." : "macc\t%0,%.,%.";
5169 if (DSP_ACC_REG_P (REGNO (src
)))
5171 static char retval
[] = "mf__\t%0,%q1";
5173 retval
[2] = reg_names
[REGNO (src
)][4];
5174 retval
[3] = reg_names
[REGNO (src
)][5];
5178 if (FP_REG_P (REGNO (src
)))
5180 gcc_assert (!msa_p
);
5181 return dbl_p
? "dmfc1\t%0,%1" : "mfc1\t%0,%1";
5184 if (ALL_COP_REG_P (REGNO (src
)))
5186 static char retval
[] = "dmfc_\t%0,%1";
5188 retval
[4] = COPNUM_AS_CHAR_FROM_REGNUM (REGNO (src
));
5189 return dbl_p
? retval
: retval
+ 1;
5193 if (src_code
== MEM
)
5194 switch (GET_MODE_SIZE (mode
))
5196 case 1: return "lbu\t%0,%1";
5197 case 2: return "lhu\t%0,%1";
5198 case 4: return "lw\t%0,%1";
5199 case 8: return "ld\t%0,%1";
5200 default: gcc_unreachable ();
5203 if (src_code
== CONST_INT
)
5205 /* Don't use the X format for the operand itself, because that
5206 will give out-of-range numbers for 64-bit hosts and 32-bit
5209 return "li\t%0,%1\t\t\t# %X1";
5211 if (SMALL_OPERAND_UNSIGNED (INTVAL (src
)))
5214 if (SMALL_OPERAND_UNSIGNED (-INTVAL (src
)))
5218 if (src_code
== HIGH
)
5219 return TARGET_MIPS16
? "#" : "lui\t%0,%h1";
5221 if (CONST_GP_P (src
))
5222 return "move\t%0,%1";
5224 if (mips_symbolic_constant_p (src
, SYMBOL_CONTEXT_LEA
, &symbol_type
)
5225 && mips_lo_relocs
[symbol_type
] != 0)
5227 /* A signed 16-bit constant formed by applying a relocation
5228 operator to a symbolic address. */
5229 gcc_assert (!mips_split_p
[symbol_type
]);
5230 return "li\t%0,%R1";
5233 if (symbolic_operand (src
, VOIDmode
))
5235 gcc_assert (TARGET_MIPS16
5236 ? TARGET_MIPS16_TEXT_LOADS
5237 : !TARGET_EXPLICIT_RELOCS
);
5238 return dbl_p
? "dla\t%0,%1" : "la\t%0,%1";
5241 if (src_code
== REG
&& FP_REG_P (REGNO (src
)))
5243 if (dest_code
== REG
&& FP_REG_P (REGNO (dest
)))
5245 if (GET_MODE (dest
) == V2SFmode
)
5246 return "mov.ps\t%0,%1";
5248 return "move.v\t%w0,%w1";
5250 return dbl_p
? "mov.d\t%0,%1" : "mov.s\t%0,%1";
5253 if (dest_code
== MEM
)
5256 return "st.%v1\t%w1,%0";
5258 return dbl_p
? "sdc1\t%1,%0" : "swc1\t%1,%0";
5261 if (dest_code
== REG
&& FP_REG_P (REGNO (dest
)))
5263 if (src_code
== MEM
)
5266 return "ld.%v0\t%w0,%1";
5268 return dbl_p
? "ldc1\t%0,%1" : "lwc1\t%0,%1";
5271 if (dest_code
== REG
&& ALL_COP_REG_P (REGNO (dest
)) && src_code
== MEM
)
5273 static char retval
[] = "l_c_\t%0,%1";
5275 retval
[1] = (dbl_p
? 'd' : 'w');
5276 retval
[3] = COPNUM_AS_CHAR_FROM_REGNUM (REGNO (dest
));
5279 if (dest_code
== MEM
&& src_code
== REG
&& ALL_COP_REG_P (REGNO (src
)))
5281 static char retval
[] = "s_c_\t%1,%0";
5283 retval
[1] = (dbl_p
? 'd' : 'w');
5284 retval
[3] = COPNUM_AS_CHAR_FROM_REGNUM (REGNO (src
));
5290 /* Return true if CMP1 is a suitable second operand for integer ordering
5291 test CODE. See also the *sCC patterns in mips.md. */
5294 mips_int_order_operand_ok_p (enum rtx_code code
, rtx cmp1
)
5300 return reg_or_0_operand (cmp1
, VOIDmode
);
5304 return !TARGET_MIPS16
&& cmp1
== const1_rtx
;
5308 return arith_operand (cmp1
, VOIDmode
);
5311 return sle_operand (cmp1
, VOIDmode
);
5314 return sleu_operand (cmp1
, VOIDmode
);
5321 /* Return true if *CMP1 (of mode MODE) is a valid second operand for
5322 integer ordering test *CODE, or if an equivalent combination can
5323 be formed by adjusting *CODE and *CMP1. When returning true, update
5324 *CODE and *CMP1 with the chosen code and operand, otherwise leave
5328 mips_canonicalize_int_order_test (enum rtx_code
*code
, rtx
*cmp1
,
5331 HOST_WIDE_INT plus_one
;
5333 if (mips_int_order_operand_ok_p (*code
, *cmp1
))
5336 if (CONST_INT_P (*cmp1
))
5340 plus_one
= trunc_int_for_mode (UINTVAL (*cmp1
) + 1, mode
);
5341 if (INTVAL (*cmp1
) < plus_one
)
5344 *cmp1
= force_reg (mode
, GEN_INT (plus_one
));
5350 plus_one
= trunc_int_for_mode (UINTVAL (*cmp1
) + 1, mode
);
5354 *cmp1
= force_reg (mode
, GEN_INT (plus_one
));
5365 /* Compare CMP0 and CMP1 using ordering test CODE and store the result
5366 in TARGET. CMP0 and TARGET are register_operands. If INVERT_PTR
5367 is nonnull, it's OK to set TARGET to the inverse of the result and
5368 flip *INVERT_PTR instead. */
5371 mips_emit_int_order_test (enum rtx_code code
, bool *invert_ptr
,
5372 rtx target
, rtx cmp0
, rtx cmp1
)
5376 /* First see if there is a MIPS instruction that can do this operation.
5377 If not, try doing the same for the inverse operation. If that also
5378 fails, force CMP1 into a register and try again. */
5379 mode
= GET_MODE (cmp0
);
5380 if (mips_canonicalize_int_order_test (&code
, &cmp1
, mode
))
5381 mips_emit_binary (code
, target
, cmp0
, cmp1
);
5384 enum rtx_code inv_code
= reverse_condition (code
);
5385 if (!mips_canonicalize_int_order_test (&inv_code
, &cmp1
, mode
))
5387 cmp1
= force_reg (mode
, cmp1
);
5388 mips_emit_int_order_test (code
, invert_ptr
, target
, cmp0
, cmp1
);
5390 else if (invert_ptr
== 0)
5394 inv_target
= mips_force_binary (GET_MODE (target
),
5395 inv_code
, cmp0
, cmp1
);
5396 mips_emit_binary (XOR
, target
, inv_target
, const1_rtx
);
5400 *invert_ptr
= !*invert_ptr
;
5401 mips_emit_binary (inv_code
, target
, cmp0
, cmp1
);
5406 /* Return a register that is zero iff CMP0 and CMP1 are equal.
5407 The register will have the same mode as CMP0. */
5410 mips_zero_if_equal (rtx cmp0
, rtx cmp1
)
5412 if (cmp1
== const0_rtx
)
5415 if (uns_arith_operand (cmp1
, VOIDmode
))
5416 return expand_binop (GET_MODE (cmp0
), xor_optab
,
5417 cmp0
, cmp1
, 0, 0, OPTAB_DIRECT
);
5419 return expand_binop (GET_MODE (cmp0
), sub_optab
,
5420 cmp0
, cmp1
, 0, 0, OPTAB_DIRECT
);
5423 /* Convert *CODE into a code that can be used in a floating-point
5424 scc instruction (C.cond.fmt). Return true if the values of
5425 the condition code registers will be inverted, with 0 indicating
5426 that the condition holds. */
5429 mips_reversed_fp_cond (enum rtx_code
*code
)
5436 *code
= reverse_condition_maybe_unordered (*code
);
5444 /* Allocate a floating-point condition-code register of mode MODE.
5446 These condition code registers are used for certain kinds
5447 of compound operation, such as compare and branches, vconds,
5448 and built-in functions. At expand time, their use is entirely
5449 controlled by MIPS-specific code and is entirely internal
5450 to these compound operations.
5452 We could (and did in the past) expose condition-code values
5453 as pseudo registers and leave the register allocator to pick
5454 appropriate registers. The problem is that it is not practically
5455 possible for the rtl optimizers to guarantee that no spills will
5456 be needed, even when AVOID_CCMODE_COPIES is defined. We would
5457 therefore need spill and reload sequences to handle the worst case.
5459 Although such sequences do exist, they are very expensive and are
5460 not something we'd want to use. This is especially true of CCV2 and
5461 CCV4, where all the shuffling would greatly outweigh whatever benefit
5462 the vectorization itself provides.
5464 The main benefit of having more than one condition-code register
5465 is to allow the pipelining of operations, especially those involving
5466 comparisons and conditional moves. We don't really expect the
5467 registers to be live for long periods, and certainly never want
5468 them to be live across calls.
5470 Also, there should be no penalty attached to using all the available
5471 registers. They are simply bits in the same underlying FPU control
5474 We therefore expose the hardware registers from the outset and use
5475 a simple round-robin allocation scheme. */
5478 mips_allocate_fcc (machine_mode mode
)
5480 unsigned int regno
, count
;
5482 gcc_assert (TARGET_HARD_FLOAT
&& ISA_HAS_8CC
);
5486 else if (mode
== CCV2mode
)
5488 else if (mode
== CCV4mode
)
5493 cfun
->machine
->next_fcc
+= -cfun
->machine
->next_fcc
& (count
- 1);
5494 if (cfun
->machine
->next_fcc
> ST_REG_LAST
- ST_REG_FIRST
)
5495 cfun
->machine
->next_fcc
= 0;
5496 regno
= ST_REG_FIRST
+ cfun
->machine
->next_fcc
;
5497 cfun
->machine
->next_fcc
+= count
;
5498 return gen_rtx_REG (mode
, regno
);
5501 /* Convert a comparison into something that can be used in a branch or
5502 conditional move. On entry, *OP0 and *OP1 are the values being
5503 compared and *CODE is the code used to compare them.
5505 Update *CODE, *OP0 and *OP1 so that they describe the final comparison.
5506 If NEED_EQ_NE_P, then only EQ or NE comparisons against zero are possible,
5507 otherwise any standard branch condition can be used. The standard branch
5510 - EQ or NE between two registers.
5511 - any comparison between a register and zero.
5512 - if compact branches are available then any condition is valid. */
5515 mips_emit_compare (enum rtx_code
*code
, rtx
*op0
, rtx
*op1
, bool need_eq_ne_p
)
5520 if (GET_MODE_CLASS (GET_MODE (*op0
)) == MODE_INT
)
5522 if (!need_eq_ne_p
&& *op1
== const0_rtx
)
5524 else if (*code
== EQ
|| *code
== NE
)
5528 *op0
= mips_zero_if_equal (cmp_op0
, cmp_op1
);
5532 *op1
= force_reg (GET_MODE (cmp_op0
), cmp_op1
);
5534 else if (!need_eq_ne_p
&& TARGET_CB_MAYBE
)
5564 *op1
= force_reg (GET_MODE (cmp_op0
), cmp_op1
);
5574 /* The comparison needs a separate scc instruction. Store the
5575 result of the scc in *OP0 and compare it against zero. */
5576 bool invert
= false;
5577 *op0
= gen_reg_rtx (GET_MODE (cmp_op0
));
5578 mips_emit_int_order_test (*code
, &invert
, *op0
, cmp_op0
, cmp_op1
);
5579 *code
= (invert
? EQ
: NE
);
5583 else if (ALL_FIXED_POINT_MODE_P (GET_MODE (cmp_op0
)))
5585 *op0
= gen_rtx_REG (CCDSPmode
, CCDSP_CC_REGNUM
);
5586 mips_emit_binary (*code
, *op0
, cmp_op0
, cmp_op1
);
5592 enum rtx_code cmp_code
;
5594 /* Floating-point tests use a separate C.cond.fmt or CMP.cond.fmt
5595 comparison to set a register. The branch or conditional move will
5596 then compare that register against zero.
5598 Set CMP_CODE to the code of the comparison instruction and
5599 *CODE to the code that the branch or move should use. */
5603 /* All FP conditions can be implemented directly with CMP.cond.fmt
5604 or by reversing the operands. */
5606 *op0
= gen_reg_rtx (CCFmode
);
5610 /* Three FP conditions cannot be implemented by reversing the
5611 operands for C.cond.fmt, instead a reversed condition code is
5612 required and a test for false. */
5613 *code
= mips_reversed_fp_cond (&cmp_code
) ? EQ
: NE
;
5615 *op0
= mips_allocate_fcc (CCmode
);
5617 *op0
= gen_rtx_REG (CCmode
, FPSW_REGNUM
);
5621 mips_emit_binary (cmp_code
, *op0
, cmp_op0
, cmp_op1
);
5625 /* Try performing the comparison in OPERANDS[1], whose arms are OPERANDS[2]
5626 and OPERAND[3]. Store the result in OPERANDS[0].
5628 On 64-bit targets, the mode of the comparison and target will always be
5629 SImode, thus possibly narrower than that of the comparison's operands. */
5632 mips_expand_scc (rtx operands
[])
5634 rtx target
= operands
[0];
5635 enum rtx_code code
= GET_CODE (operands
[1]);
5636 rtx op0
= operands
[2];
5637 rtx op1
= operands
[3];
5639 gcc_assert (GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
);
5641 if (code
== EQ
|| code
== NE
)
5644 && reg_imm10_operand (op1
, GET_MODE (op1
)))
5645 mips_emit_binary (code
, target
, op0
, op1
);
5648 rtx zie
= mips_zero_if_equal (op0
, op1
);
5649 mips_emit_binary (code
, target
, zie
, const0_rtx
);
5653 mips_emit_int_order_test (code
, 0, target
, op0
, op1
);
5656 /* Compare OPERANDS[1] with OPERANDS[2] using comparison code
5657 CODE and jump to OPERANDS[3] if the condition holds. */
5660 mips_expand_conditional_branch (rtx
*operands
)
5662 enum rtx_code code
= GET_CODE (operands
[0]);
5663 rtx op0
= operands
[1];
5664 rtx op1
= operands
[2];
5667 mips_emit_compare (&code
, &op0
, &op1
, TARGET_MIPS16
);
5668 condition
= gen_rtx_fmt_ee (code
, VOIDmode
, op0
, op1
);
5669 emit_jump_insn (gen_condjump (condition
, operands
[3]));
5674 (set temp (COND:CCV2 CMP_OP0 CMP_OP1))
5675 (set DEST (unspec [TRUE_SRC FALSE_SRC temp] UNSPEC_MOVE_TF_PS)) */
5678 mips_expand_vcondv2sf (rtx dest
, rtx true_src
, rtx false_src
,
5679 enum rtx_code cond
, rtx cmp_op0
, rtx cmp_op1
)
5684 reversed_p
= mips_reversed_fp_cond (&cond
);
5685 cmp_result
= mips_allocate_fcc (CCV2mode
);
5686 emit_insn (gen_scc_ps (cmp_result
,
5687 gen_rtx_fmt_ee (cond
, VOIDmode
, cmp_op0
, cmp_op1
)));
5689 emit_insn (gen_mips_cond_move_tf_ps (dest
, false_src
, true_src
,
5692 emit_insn (gen_mips_cond_move_tf_ps (dest
, true_src
, false_src
,
5696 /* Perform the comparison in OPERANDS[1]. Move OPERANDS[2] into OPERANDS[0]
5697 if the condition holds, otherwise move OPERANDS[3] into OPERANDS[0]. */
5700 mips_expand_conditional_move (rtx
*operands
)
5703 enum rtx_code code
= GET_CODE (operands
[1]);
5704 rtx op0
= XEXP (operands
[1], 0);
5705 rtx op1
= XEXP (operands
[1], 1);
5707 mips_emit_compare (&code
, &op0
, &op1
, true);
5708 cond
= gen_rtx_fmt_ee (code
, GET_MODE (op0
), op0
, op1
);
5710 /* There is no direct support for general conditional GP move involving
5711 two registers using SEL. */
5713 && INTEGRAL_MODE_P (GET_MODE (operands
[2]))
5714 && register_operand (operands
[2], VOIDmode
)
5715 && register_operand (operands
[3], VOIDmode
))
5717 machine_mode mode
= GET_MODE (operands
[0]);
5718 rtx temp
= gen_reg_rtx (mode
);
5719 rtx temp2
= gen_reg_rtx (mode
);
5721 emit_insn (gen_rtx_SET (temp
,
5722 gen_rtx_IF_THEN_ELSE (mode
, cond
,
5723 operands
[2], const0_rtx
)));
5725 /* Flip the test for the second operand. */
5726 cond
= gen_rtx_fmt_ee ((code
== EQ
) ? NE
: EQ
, GET_MODE (op0
), op0
, op1
);
5728 emit_insn (gen_rtx_SET (temp2
,
5729 gen_rtx_IF_THEN_ELSE (mode
, cond
,
5730 operands
[3], const0_rtx
)));
5732 /* Merge the two results, at least one is guaranteed to be zero. */
5733 emit_insn (gen_rtx_SET (operands
[0], gen_rtx_IOR (mode
, temp
, temp2
)));
5737 if (FLOAT_MODE_P (GET_MODE (operands
[2])) && !ISA_HAS_SEL
)
5739 operands
[2] = force_reg (GET_MODE (operands
[0]), operands
[2]);
5740 operands
[3] = force_reg (GET_MODE (operands
[0]), operands
[3]);
5743 emit_insn (gen_rtx_SET (operands
[0],
5744 gen_rtx_IF_THEN_ELSE (GET_MODE (operands
[0]), cond
,
5745 operands
[2], operands
[3])));
5749 /* Perform the comparison in COMPARISON, then trap if the condition holds. */
5752 mips_expand_conditional_trap (rtx comparison
)
5758 /* MIPS conditional trap instructions don't have GT or LE flavors,
5759 so we must swap the operands and convert to LT and GE respectively. */
5760 code
= GET_CODE (comparison
);
5767 code
= swap_condition (code
);
5768 op0
= XEXP (comparison
, 1);
5769 op1
= XEXP (comparison
, 0);
5773 op0
= XEXP (comparison
, 0);
5774 op1
= XEXP (comparison
, 1);
5778 mode
= GET_MODE (XEXP (comparison
, 0));
5779 op0
= force_reg (mode
, op0
);
5780 if (!(ISA_HAS_COND_TRAPI
5781 ? arith_operand (op1
, mode
)
5782 : reg_or_0_operand (op1
, mode
)))
5783 op1
= force_reg (mode
, op1
);
5785 emit_insn (gen_rtx_TRAP_IF (VOIDmode
,
5786 gen_rtx_fmt_ee (code
, mode
, op0
, op1
),
5790 /* Initialize *CUM for a call to a function of type FNTYPE. */
5793 mips_init_cumulative_args (CUMULATIVE_ARGS
*cum
, tree fntype
)
5795 memset (cum
, 0, sizeof (*cum
));
5796 cum
->prototype
= (fntype
&& prototype_p (fntype
));
5797 cum
->gp_reg_found
= (cum
->prototype
&& stdarg_p (fntype
));
5800 /* Fill INFO with information about a single argument. CUM is the
5801 cumulative state for earlier arguments. MODE is the mode of this
5802 argument and TYPE is its type (if known). NAMED is true if this
5803 is a named (fixed) argument rather than a variable one. */
5806 mips_get_arg_info (struct mips_arg_info
*info
, const CUMULATIVE_ARGS
*cum
,
5807 machine_mode mode
, const_tree type
, bool named
)
5809 bool doubleword_aligned_p
;
5810 unsigned int num_bytes
, num_words
, max_regs
;
5812 /* Work out the size of the argument. */
5813 num_bytes
= type
? int_size_in_bytes (type
) : GET_MODE_SIZE (mode
);
5814 num_words
= (num_bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
5816 /* Decide whether it should go in a floating-point register, assuming
5817 one is free. Later code checks for availability.
5819 The checks against UNITS_PER_FPVALUE handle the soft-float and
5820 single-float cases. */
5824 /* The EABI conventions have traditionally been defined in terms
5825 of TYPE_MODE, regardless of the actual type. */
5826 info
->fpr_p
= ((GET_MODE_CLASS (mode
) == MODE_FLOAT
5827 || mode
== V2SFmode
)
5828 && GET_MODE_SIZE (mode
) <= UNITS_PER_FPVALUE
);
5833 /* Only leading floating-point scalars are passed in
5834 floating-point registers. We also handle vector floats the same
5835 say, which is OK because they are not covered by the standard ABI. */
5836 gcc_assert (TARGET_PAIRED_SINGLE_FLOAT
|| mode
!= V2SFmode
);
5837 info
->fpr_p
= (!cum
->gp_reg_found
5838 && cum
->arg_number
< 2
5840 || SCALAR_FLOAT_TYPE_P (type
)
5841 || VECTOR_FLOAT_TYPE_P (type
))
5842 && (GET_MODE_CLASS (mode
) == MODE_FLOAT
5843 || mode
== V2SFmode
)
5844 && GET_MODE_SIZE (mode
) <= UNITS_PER_FPVALUE
);
5849 /* Scalar, complex and vector floating-point types are passed in
5850 floating-point registers, as long as this is a named rather
5851 than a variable argument. */
5852 gcc_assert (TARGET_PAIRED_SINGLE_FLOAT
|| mode
!= V2SFmode
);
5853 info
->fpr_p
= (named
5854 && (type
== 0 || FLOAT_TYPE_P (type
))
5855 && (GET_MODE_CLASS (mode
) == MODE_FLOAT
5856 || GET_MODE_CLASS (mode
) == MODE_COMPLEX_FLOAT
5857 || mode
== V2SFmode
)
5858 && GET_MODE_UNIT_SIZE (mode
) <= UNITS_PER_FPVALUE
);
5860 /* ??? According to the ABI documentation, the real and imaginary
5861 parts of complex floats should be passed in individual registers.
5862 The real and imaginary parts of stack arguments are supposed
5863 to be contiguous and there should be an extra word of padding
5866 This has two problems. First, it makes it impossible to use a
5867 single "void *" va_list type, since register and stack arguments
5868 are passed differently. (At the time of writing, MIPSpro cannot
5869 handle complex float varargs correctly.) Second, it's unclear
5870 what should happen when there is only one register free.
5872 For now, we assume that named complex floats should go into FPRs
5873 if there are two FPRs free, otherwise they should be passed in the
5874 same way as a struct containing two floats. */
5876 && GET_MODE_CLASS (mode
) == MODE_COMPLEX_FLOAT
5877 && GET_MODE_UNIT_SIZE (mode
) < UNITS_PER_FPVALUE
)
5879 if (cum
->num_gprs
>= MAX_ARGS_IN_REGISTERS
- 1)
5880 info
->fpr_p
= false;
5890 /* See whether the argument has doubleword alignment. */
5891 doubleword_aligned_p
= (mips_function_arg_boundary (mode
, type
)
5894 /* Set REG_OFFSET to the register count we're interested in.
5895 The EABI allocates the floating-point registers separately,
5896 but the other ABIs allocate them like integer registers. */
5897 info
->reg_offset
= (mips_abi
== ABI_EABI
&& info
->fpr_p
5901 /* Advance to an even register if the argument is doubleword-aligned. */
5902 if (doubleword_aligned_p
)
5903 info
->reg_offset
+= info
->reg_offset
& 1;
5905 /* Work out the offset of a stack argument. */
5906 info
->stack_offset
= cum
->stack_words
;
5907 if (doubleword_aligned_p
)
5908 info
->stack_offset
+= info
->stack_offset
& 1;
5910 max_regs
= MAX_ARGS_IN_REGISTERS
- info
->reg_offset
;
5912 /* Partition the argument between registers and stack. */
5913 info
->reg_words
= MIN (num_words
, max_regs
);
5914 info
->stack_words
= num_words
- info
->reg_words
;
5917 /* INFO describes a register argument that has the normal format for the
5918 argument's mode. Return the register it uses, assuming that FPRs are
5919 available if HARD_FLOAT_P. */
5922 mips_arg_regno (const struct mips_arg_info
*info
, bool hard_float_p
)
5924 if (!info
->fpr_p
|| !hard_float_p
)
5925 return GP_ARG_FIRST
+ info
->reg_offset
;
5926 else if (mips_abi
== ABI_32
&& TARGET_DOUBLE_FLOAT
&& info
->reg_offset
> 0)
5927 /* In o32, the second argument is always passed in $f14
5928 for TARGET_DOUBLE_FLOAT, regardless of whether the
5929 first argument was a word or doubleword. */
5930 return FP_ARG_FIRST
+ 2;
5932 return FP_ARG_FIRST
+ info
->reg_offset
;
5935 /* Implement TARGET_STRICT_ARGUMENT_NAMING. */
5938 mips_strict_argument_naming (cumulative_args_t ca ATTRIBUTE_UNUSED
)
5940 return !TARGET_OLDABI
;
5943 /* Implement TARGET_FUNCTION_ARG. */
5946 mips_function_arg (cumulative_args_t cum_v
, machine_mode mode
,
5947 const_tree type
, bool named
)
5949 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
5950 struct mips_arg_info info
;
5952 /* We will be called with a mode of VOIDmode after the last argument
5953 has been seen. Whatever we return will be passed to the call expander.
5954 If we need a MIPS16 fp_code, return a REG with the code stored as
5956 if (mode
== VOIDmode
)
5958 if (TARGET_MIPS16
&& cum
->fp_code
!= 0)
5959 return gen_rtx_REG ((machine_mode
) cum
->fp_code
, 0);
5964 mips_get_arg_info (&info
, cum
, mode
, type
, named
);
5966 /* Return straight away if the whole argument is passed on the stack. */
5967 if (info
.reg_offset
== MAX_ARGS_IN_REGISTERS
)
5970 /* The n32 and n64 ABIs say that if any 64-bit chunk of the structure
5971 contains a double in its entirety, then that 64-bit chunk is passed
5972 in a floating-point register. */
5974 && TARGET_HARD_FLOAT
5977 && TREE_CODE (type
) == RECORD_TYPE
5978 && TYPE_SIZE_UNIT (type
)
5979 && tree_fits_uhwi_p (TYPE_SIZE_UNIT (type
)))
5983 /* First check to see if there is any such field. */
5984 for (field
= TYPE_FIELDS (type
); field
; field
= DECL_CHAIN (field
))
5985 if (TREE_CODE (field
) == FIELD_DECL
5986 && SCALAR_FLOAT_TYPE_P (TREE_TYPE (field
))
5987 && TYPE_PRECISION (TREE_TYPE (field
)) == BITS_PER_WORD
5988 && tree_fits_shwi_p (bit_position (field
))
5989 && int_bit_position (field
) % BITS_PER_WORD
== 0)
5994 /* Now handle the special case by returning a PARALLEL
5995 indicating where each 64-bit chunk goes. INFO.REG_WORDS
5996 chunks are passed in registers. */
5998 HOST_WIDE_INT bitpos
;
6001 /* assign_parms checks the mode of ENTRY_PARM, so we must
6002 use the actual mode here. */
6003 ret
= gen_rtx_PARALLEL (mode
, rtvec_alloc (info
.reg_words
));
6006 field
= TYPE_FIELDS (type
);
6007 for (i
= 0; i
< info
.reg_words
; i
++)
6011 for (; field
; field
= DECL_CHAIN (field
))
6012 if (TREE_CODE (field
) == FIELD_DECL
6013 && int_bit_position (field
) >= bitpos
)
6017 && int_bit_position (field
) == bitpos
6018 && SCALAR_FLOAT_TYPE_P (TREE_TYPE (field
))
6019 && TYPE_PRECISION (TREE_TYPE (field
)) == BITS_PER_WORD
)
6020 reg
= gen_rtx_REG (DFmode
, FP_ARG_FIRST
+ info
.reg_offset
+ i
);
6022 reg
= gen_rtx_REG (DImode
, GP_ARG_FIRST
+ info
.reg_offset
+ i
);
6025 = gen_rtx_EXPR_LIST (VOIDmode
, reg
,
6026 GEN_INT (bitpos
/ BITS_PER_UNIT
));
6028 bitpos
+= BITS_PER_WORD
;
6034 /* Handle the n32/n64 conventions for passing complex floating-point
6035 arguments in FPR pairs. The real part goes in the lower register
6036 and the imaginary part goes in the upper register. */
6039 && GET_MODE_CLASS (mode
) == MODE_COMPLEX_FLOAT
)
6045 inner
= GET_MODE_INNER (mode
);
6046 regno
= FP_ARG_FIRST
+ info
.reg_offset
;
6047 if (info
.reg_words
* UNITS_PER_WORD
== GET_MODE_SIZE (inner
))
6049 /* Real part in registers, imaginary part on stack. */
6050 gcc_assert (info
.stack_words
== info
.reg_words
);
6051 return gen_rtx_REG (inner
, regno
);
6055 gcc_assert (info
.stack_words
== 0);
6056 real
= gen_rtx_EXPR_LIST (VOIDmode
,
6057 gen_rtx_REG (inner
, regno
),
6059 imag
= gen_rtx_EXPR_LIST (VOIDmode
,
6061 regno
+ info
.reg_words
/ 2),
6062 GEN_INT (GET_MODE_SIZE (inner
)));
6063 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, real
, imag
));
6067 return gen_rtx_REG (mode
, mips_arg_regno (&info
, TARGET_HARD_FLOAT
));
6070 /* Implement TARGET_FUNCTION_ARG_ADVANCE. */
6073 mips_function_arg_advance (cumulative_args_t cum_v
, machine_mode mode
,
6074 const_tree type
, bool named
)
6076 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
6077 struct mips_arg_info info
;
6079 mips_get_arg_info (&info
, cum
, mode
, type
, named
);
6082 cum
->gp_reg_found
= true;
6084 /* See the comment above the CUMULATIVE_ARGS structure in mips.h for
6085 an explanation of what this code does. It assumes that we're using
6086 either the o32 or the o64 ABI, both of which pass at most 2 arguments
6088 if (cum
->arg_number
< 2 && info
.fpr_p
)
6089 cum
->fp_code
+= (mode
== SFmode
? 1 : 2) << (cum
->arg_number
* 2);
6091 /* Advance the register count. This has the effect of setting
6092 num_gprs to MAX_ARGS_IN_REGISTERS if a doubleword-aligned
6093 argument required us to skip the final GPR and pass the whole
6094 argument on the stack. */
6095 if (mips_abi
!= ABI_EABI
|| !info
.fpr_p
)
6096 cum
->num_gprs
= info
.reg_offset
+ info
.reg_words
;
6097 else if (info
.reg_words
> 0)
6098 cum
->num_fprs
+= MAX_FPRS_PER_FMT
;
6100 /* Advance the stack word count. */
6101 if (info
.stack_words
> 0)
6102 cum
->stack_words
= info
.stack_offset
+ info
.stack_words
;
6107 /* Implement TARGET_ARG_PARTIAL_BYTES. */
6110 mips_arg_partial_bytes (cumulative_args_t cum
,
6111 machine_mode mode
, tree type
, bool named
)
6113 struct mips_arg_info info
;
6115 mips_get_arg_info (&info
, get_cumulative_args (cum
), mode
, type
, named
);
6116 return info
.stack_words
> 0 ? info
.reg_words
* UNITS_PER_WORD
: 0;
6119 /* Implement TARGET_FUNCTION_ARG_BOUNDARY. Every parameter gets at
6120 least PARM_BOUNDARY bits of alignment, but will be given anything up
6121 to STACK_BOUNDARY bits if the type requires it. */
6124 mips_function_arg_boundary (machine_mode mode
, const_tree type
)
6126 unsigned int alignment
;
6128 alignment
= type
? TYPE_ALIGN (type
) : GET_MODE_ALIGNMENT (mode
);
6129 if (alignment
< PARM_BOUNDARY
)
6130 alignment
= PARM_BOUNDARY
;
6131 if (alignment
> STACK_BOUNDARY
)
6132 alignment
= STACK_BOUNDARY
;
6136 /* Implement TARGET_GET_RAW_RESULT_MODE and TARGET_GET_RAW_ARG_MODE. */
6138 static fixed_size_mode
6139 mips_get_reg_raw_mode (int regno
)
6141 if (TARGET_FLOATXX
&& FP_REG_P (regno
))
6143 return default_get_reg_raw_mode (regno
);
6146 /* Implement TARGET_FUNCTION_ARG_PADDING; return PAD_UPWARD if the first
6147 byte of the stack slot has useful data, PAD_DOWNWARD if the last byte
6150 static pad_direction
6151 mips_function_arg_padding (machine_mode mode
, const_tree type
)
6153 /* On little-endian targets, the first byte of every stack argument
6154 is passed in the first byte of the stack slot. */
6155 if (!BYTES_BIG_ENDIAN
)
6158 /* Otherwise, integral types are padded downward: the last byte of a
6159 stack argument is passed in the last byte of the stack slot. */
6161 ? (INTEGRAL_TYPE_P (type
)
6162 || POINTER_TYPE_P (type
)
6163 || FIXED_POINT_TYPE_P (type
))
6164 : (SCALAR_INT_MODE_P (mode
)
6165 || ALL_SCALAR_FIXED_POINT_MODE_P (mode
)))
6166 return PAD_DOWNWARD
;
6168 /* Big-endian o64 pads floating-point arguments downward. */
6169 if (mips_abi
== ABI_O64
)
6170 if (type
!= 0 ? FLOAT_TYPE_P (type
) : GET_MODE_CLASS (mode
) == MODE_FLOAT
)
6171 return PAD_DOWNWARD
;
6173 /* Other types are padded upward for o32, o64, n32 and n64. */
6174 if (mips_abi
!= ABI_EABI
)
6177 /* Arguments smaller than a stack slot are padded downward. */
6179 ? GET_MODE_BITSIZE (mode
) >= PARM_BOUNDARY
6180 : int_size_in_bytes (type
) >= (PARM_BOUNDARY
/ BITS_PER_UNIT
))
6183 return PAD_DOWNWARD
;
6186 /* Likewise BLOCK_REG_PADDING (MODE, TYPE, ...). Return !BYTES_BIG_ENDIAN
6187 if the least significant byte of the register has useful data. Return
6188 the opposite if the most significant byte does. */
6191 mips_pad_reg_upward (machine_mode mode
, tree type
)
6193 /* No shifting is required for floating-point arguments. */
6194 if (type
!= 0 ? FLOAT_TYPE_P (type
) : GET_MODE_CLASS (mode
) == MODE_FLOAT
)
6195 return !BYTES_BIG_ENDIAN
;
6197 /* Otherwise, apply the same padding to register arguments as we do
6198 to stack arguments. */
6199 return mips_function_arg_padding (mode
, type
) == PAD_UPWARD
;
6202 /* Return nonzero when an argument must be passed by reference. */
6205 mips_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED
,
6206 machine_mode mode
, const_tree type
,
6207 bool named ATTRIBUTE_UNUSED
)
6209 if (mips_abi
== ABI_EABI
)
6213 /* ??? How should SCmode be handled? */
6214 if (mode
== DImode
|| mode
== DFmode
6215 || mode
== DQmode
|| mode
== UDQmode
6216 || mode
== DAmode
|| mode
== UDAmode
)
6219 size
= type
? int_size_in_bytes (type
) : GET_MODE_SIZE (mode
);
6220 return size
== -1 || size
> UNITS_PER_WORD
;
6224 /* If we have a variable-sized parameter, we have no choice. */
6225 return targetm
.calls
.must_pass_in_stack (mode
, type
);
6229 /* Implement TARGET_CALLEE_COPIES. */
6232 mips_callee_copies (cumulative_args_t cum ATTRIBUTE_UNUSED
,
6233 machine_mode mode ATTRIBUTE_UNUSED
,
6234 const_tree type ATTRIBUTE_UNUSED
, bool named
)
6236 return mips_abi
== ABI_EABI
&& named
;
6239 /* See whether VALTYPE is a record whose fields should be returned in
6240 floating-point registers. If so, return the number of fields and
6241 list them in FIELDS (which should have two elements). Return 0
6244 For n32 & n64, a structure with one or two fields is returned in
6245 floating-point registers as long as every field has a floating-point
6249 mips_fpr_return_fields (const_tree valtype
, tree
*fields
)
6257 if (TREE_CODE (valtype
) != RECORD_TYPE
)
6261 for (field
= TYPE_FIELDS (valtype
); field
!= 0; field
= DECL_CHAIN (field
))
6263 if (TREE_CODE (field
) != FIELD_DECL
)
6266 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (field
)))
6272 fields
[i
++] = field
;
6277 /* Implement TARGET_RETURN_IN_MSB. For n32 & n64, we should return
6278 a value in the most significant part of $2/$3 if:
6280 - the target is big-endian;
6282 - the value has a structure or union type (we generalize this to
6283 cover aggregates from other languages too); and
6285 - the structure is not returned in floating-point registers. */
6288 mips_return_in_msb (const_tree valtype
)
6292 return (TARGET_NEWABI
6293 && TARGET_BIG_ENDIAN
6294 && AGGREGATE_TYPE_P (valtype
)
6295 && mips_fpr_return_fields (valtype
, fields
) == 0);
6298 /* Return true if the function return value MODE will get returned in a
6299 floating-point register. */
6302 mips_return_mode_in_fpr_p (machine_mode mode
)
6304 gcc_assert (TARGET_PAIRED_SINGLE_FLOAT
|| mode
!= V2SFmode
);
6305 return ((GET_MODE_CLASS (mode
) == MODE_FLOAT
6307 || GET_MODE_CLASS (mode
) == MODE_COMPLEX_FLOAT
)
6308 && GET_MODE_UNIT_SIZE (mode
) <= UNITS_PER_HWFPVALUE
);
6311 /* Return the representation of an FPR return register when the
6312 value being returned in FP_RETURN has mode VALUE_MODE and the
6313 return type itself has mode TYPE_MODE. On NewABI targets,
6314 the two modes may be different for structures like:
6316 struct __attribute__((packed)) foo { float f; }
6318 where we return the SFmode value of "f" in FP_RETURN, but where
6319 the structure itself has mode BLKmode. */
6322 mips_return_fpr_single (machine_mode type_mode
,
6323 machine_mode value_mode
)
6327 x
= gen_rtx_REG (value_mode
, FP_RETURN
);
6328 if (type_mode
!= value_mode
)
6330 x
= gen_rtx_EXPR_LIST (VOIDmode
, x
, const0_rtx
);
6331 x
= gen_rtx_PARALLEL (type_mode
, gen_rtvec (1, x
));
6336 /* Return a composite value in a pair of floating-point registers.
6337 MODE1 and OFFSET1 are the mode and byte offset for the first value,
6338 likewise MODE2 and OFFSET2 for the second. MODE is the mode of the
6341 For n32 & n64, $f0 always holds the first value and $f2 the second.
6342 Otherwise the values are packed together as closely as possible. */
6345 mips_return_fpr_pair (machine_mode mode
,
6346 machine_mode mode1
, HOST_WIDE_INT offset1
,
6347 machine_mode mode2
, HOST_WIDE_INT offset2
)
6351 inc
= (TARGET_NEWABI
|| mips_abi
== ABI_32
? 2 : MAX_FPRS_PER_FMT
);
6352 return gen_rtx_PARALLEL
6355 gen_rtx_EXPR_LIST (VOIDmode
,
6356 gen_rtx_REG (mode1
, FP_RETURN
),
6358 gen_rtx_EXPR_LIST (VOIDmode
,
6359 gen_rtx_REG (mode2
, FP_RETURN
+ inc
),
6360 GEN_INT (offset2
))));
6364 /* Implement TARGET_FUNCTION_VALUE and TARGET_LIBCALL_VALUE.
6365 For normal calls, VALTYPE is the return type and MODE is VOIDmode.
6366 For libcalls, VALTYPE is null and MODE is the mode of the return value. */
6369 mips_function_value_1 (const_tree valtype
, const_tree fn_decl_or_type
,
6378 if (fn_decl_or_type
&& DECL_P (fn_decl_or_type
))
6379 func
= fn_decl_or_type
;
6383 mode
= TYPE_MODE (valtype
);
6384 unsigned_p
= TYPE_UNSIGNED (valtype
);
6386 /* Since TARGET_PROMOTE_FUNCTION_MODE unconditionally promotes,
6387 return values, promote the mode here too. */
6388 mode
= promote_function_mode (valtype
, mode
, &unsigned_p
, func
, 1);
6390 /* Handle structures whose fields are returned in $f0/$f2. */
6391 switch (mips_fpr_return_fields (valtype
, fields
))
6394 return mips_return_fpr_single (mode
,
6395 TYPE_MODE (TREE_TYPE (fields
[0])));
6398 return mips_return_fpr_pair (mode
,
6399 TYPE_MODE (TREE_TYPE (fields
[0])),
6400 int_byte_position (fields
[0]),
6401 TYPE_MODE (TREE_TYPE (fields
[1])),
6402 int_byte_position (fields
[1]));
6405 /* If a value is passed in the most significant part of a register, see
6406 whether we have to round the mode up to a whole number of words. */
6407 if (mips_return_in_msb (valtype
))
6409 HOST_WIDE_INT size
= int_size_in_bytes (valtype
);
6410 if (size
% UNITS_PER_WORD
!= 0)
6412 size
+= UNITS_PER_WORD
- size
% UNITS_PER_WORD
;
6413 mode
= int_mode_for_size (size
* BITS_PER_UNIT
, 0).require ();
6417 /* For EABI, the class of return register depends entirely on MODE.
6418 For example, "struct { some_type x; }" and "union { some_type x; }"
6419 are returned in the same way as a bare "some_type" would be.
6420 Other ABIs only use FPRs for scalar, complex or vector types. */
6421 if (mips_abi
!= ABI_EABI
&& !FLOAT_TYPE_P (valtype
))
6422 return gen_rtx_REG (mode
, GP_RETURN
);
6427 /* Handle long doubles for n32 & n64. */
6429 return mips_return_fpr_pair (mode
,
6431 DImode
, GET_MODE_SIZE (mode
) / 2);
6433 if (mips_return_mode_in_fpr_p (mode
))
6435 if (GET_MODE_CLASS (mode
) == MODE_COMPLEX_FLOAT
)
6436 return mips_return_fpr_pair (mode
,
6437 GET_MODE_INNER (mode
), 0,
6438 GET_MODE_INNER (mode
),
6439 GET_MODE_SIZE (mode
) / 2);
6441 return gen_rtx_REG (mode
, FP_RETURN
);
6445 return gen_rtx_REG (mode
, GP_RETURN
);
6448 /* Implement TARGET_FUNCTION_VALUE. */
6451 mips_function_value (const_tree valtype
, const_tree fn_decl_or_type
,
6452 bool outgoing ATTRIBUTE_UNUSED
)
6454 return mips_function_value_1 (valtype
, fn_decl_or_type
, VOIDmode
);
6457 /* Implement TARGET_LIBCALL_VALUE. */
6460 mips_libcall_value (machine_mode mode
, const_rtx fun ATTRIBUTE_UNUSED
)
6462 return mips_function_value_1 (NULL_TREE
, NULL_TREE
, mode
);
6465 /* Implement TARGET_FUNCTION_VALUE_REGNO_P.
6467 On the MIPS, R2 R3 and F0 F2 are the only register thus used. */
6470 mips_function_value_regno_p (const unsigned int regno
)
6472 /* Most types only require one GPR or one FPR for return values but for
6473 hard-float two FPRs can be used for _Complex types (for all ABIs)
6474 and long doubles (for n64). */
6475 if (regno
== GP_RETURN
6476 || regno
== FP_RETURN
6477 || (FP_RETURN
!= GP_RETURN
6478 && regno
== FP_RETURN
+ 2))
6481 /* For o32 FP32, _Complex double will be returned in four 32-bit registers.
6482 This does not apply to o32 FPXX as floating-point function argument and
6483 return registers are described as 64-bit even though floating-point
6484 registers are primarily described as 32-bit internally.
6485 See: mips_get_reg_raw_mode. */
6486 if ((mips_abi
== ABI_32
&& TARGET_FLOAT32
)
6487 && FP_RETURN
!= GP_RETURN
6488 && (regno
== FP_RETURN
+ 1
6489 || regno
== FP_RETURN
+ 3))
6495 /* Implement TARGET_RETURN_IN_MEMORY. Under the o32 and o64 ABIs,
6496 all BLKmode objects are returned in memory. Under the n32, n64
6497 and embedded ABIs, small structures are returned in a register.
6498 Objects with varying size must still be returned in memory, of
6502 mips_return_in_memory (const_tree type
, const_tree fndecl ATTRIBUTE_UNUSED
)
6505 /* Ensure that any floating point vector types are returned via memory
6506 even if they are supported through a vector mode with some ASEs. */
6507 return (VECTOR_FLOAT_TYPE_P (type
)
6508 || TYPE_MODE (type
) == BLKmode
);
6510 return (!IN_RANGE (int_size_in_bytes (type
), 0, 2 * UNITS_PER_WORD
));
6513 /* Implement TARGET_SETUP_INCOMING_VARARGS. */
6516 mips_setup_incoming_varargs (cumulative_args_t cum
, machine_mode mode
,
6517 tree type
, int *pretend_size ATTRIBUTE_UNUSED
,
6520 CUMULATIVE_ARGS local_cum
;
6521 int gp_saved
, fp_saved
;
6523 /* The caller has advanced CUM up to, but not beyond, the last named
6524 argument. Advance a local copy of CUM past the last "real" named
6525 argument, to find out how many registers are left over. */
6526 local_cum
= *get_cumulative_args (cum
);
6527 mips_function_arg_advance (pack_cumulative_args (&local_cum
), mode
, type
,
6530 /* Found out how many registers we need to save. */
6531 gp_saved
= MAX_ARGS_IN_REGISTERS
- local_cum
.num_gprs
;
6532 fp_saved
= (EABI_FLOAT_VARARGS_P
6533 ? MAX_ARGS_IN_REGISTERS
- local_cum
.num_fprs
6542 ptr
= plus_constant (Pmode
, virtual_incoming_args_rtx
,
6543 REG_PARM_STACK_SPACE (cfun
->decl
)
6544 - gp_saved
* UNITS_PER_WORD
);
6545 mem
= gen_frame_mem (BLKmode
, ptr
);
6546 set_mem_alias_set (mem
, get_varargs_alias_set ());
6548 move_block_from_reg (local_cum
.num_gprs
+ GP_ARG_FIRST
,
6553 /* We can't use move_block_from_reg, because it will use
6558 /* Set OFF to the offset from virtual_incoming_args_rtx of
6559 the first float register. The FP save area lies below
6560 the integer one, and is aligned to UNITS_PER_FPVALUE bytes. */
6561 off
= ROUND_DOWN (-gp_saved
* UNITS_PER_WORD
, UNITS_PER_FPVALUE
);
6562 off
-= fp_saved
* UNITS_PER_FPREG
;
6564 mode
= TARGET_SINGLE_FLOAT
? SFmode
: DFmode
;
6566 for (i
= local_cum
.num_fprs
; i
< MAX_ARGS_IN_REGISTERS
;
6567 i
+= MAX_FPRS_PER_FMT
)
6571 ptr
= plus_constant (Pmode
, virtual_incoming_args_rtx
, off
);
6572 mem
= gen_frame_mem (mode
, ptr
);
6573 set_mem_alias_set (mem
, get_varargs_alias_set ());
6574 mips_emit_move (mem
, gen_rtx_REG (mode
, FP_ARG_FIRST
+ i
));
6575 off
+= UNITS_PER_HWFPVALUE
;
6579 if (REG_PARM_STACK_SPACE (cfun
->decl
) == 0)
6580 cfun
->machine
->varargs_size
= (gp_saved
* UNITS_PER_WORD
6581 + fp_saved
* UNITS_PER_FPREG
);
6584 /* Implement TARGET_BUILTIN_VA_LIST. */
6587 mips_build_builtin_va_list (void)
6589 if (EABI_FLOAT_VARARGS_P
)
6591 /* We keep 3 pointers, and two offsets.
6593 Two pointers are to the overflow area, which starts at the CFA.
6594 One of these is constant, for addressing into the GPR save area
6595 below it. The other is advanced up the stack through the
6598 The third pointer is to the bottom of the GPR save area.
6599 Since the FPR save area is just below it, we can address
6600 FPR slots off this pointer.
6602 We also keep two one-byte offsets, which are to be subtracted
6603 from the constant pointers to yield addresses in the GPR and
6604 FPR save areas. These are downcounted as float or non-float
6605 arguments are used, and when they get to zero, the argument
6606 must be obtained from the overflow region. */
6607 tree f_ovfl
, f_gtop
, f_ftop
, f_goff
, f_foff
, f_res
, record
;
6610 record
= lang_hooks
.types
.make_type (RECORD_TYPE
);
6612 f_ovfl
= build_decl (BUILTINS_LOCATION
,
6613 FIELD_DECL
, get_identifier ("__overflow_argptr"),
6615 f_gtop
= build_decl (BUILTINS_LOCATION
,
6616 FIELD_DECL
, get_identifier ("__gpr_top"),
6618 f_ftop
= build_decl (BUILTINS_LOCATION
,
6619 FIELD_DECL
, get_identifier ("__fpr_top"),
6621 f_goff
= build_decl (BUILTINS_LOCATION
,
6622 FIELD_DECL
, get_identifier ("__gpr_offset"),
6623 unsigned_char_type_node
);
6624 f_foff
= build_decl (BUILTINS_LOCATION
,
6625 FIELD_DECL
, get_identifier ("__fpr_offset"),
6626 unsigned_char_type_node
);
6627 /* Explicitly pad to the size of a pointer, so that -Wpadded won't
6628 warn on every user file. */
6629 index
= build_int_cst (NULL_TREE
, GET_MODE_SIZE (ptr_mode
) - 2 - 1);
6630 array
= build_array_type (unsigned_char_type_node
,
6631 build_index_type (index
));
6632 f_res
= build_decl (BUILTINS_LOCATION
,
6633 FIELD_DECL
, get_identifier ("__reserved"), array
);
6635 DECL_FIELD_CONTEXT (f_ovfl
) = record
;
6636 DECL_FIELD_CONTEXT (f_gtop
) = record
;
6637 DECL_FIELD_CONTEXT (f_ftop
) = record
;
6638 DECL_FIELD_CONTEXT (f_goff
) = record
;
6639 DECL_FIELD_CONTEXT (f_foff
) = record
;
6640 DECL_FIELD_CONTEXT (f_res
) = record
;
6642 TYPE_FIELDS (record
) = f_ovfl
;
6643 DECL_CHAIN (f_ovfl
) = f_gtop
;
6644 DECL_CHAIN (f_gtop
) = f_ftop
;
6645 DECL_CHAIN (f_ftop
) = f_goff
;
6646 DECL_CHAIN (f_goff
) = f_foff
;
6647 DECL_CHAIN (f_foff
) = f_res
;
6649 layout_type (record
);
6653 /* Otherwise, we use 'void *'. */
6654 return ptr_type_node
;
6657 /* Implement TARGET_EXPAND_BUILTIN_VA_START. */
6660 mips_va_start (tree valist
, rtx nextarg
)
6662 if (EABI_FLOAT_VARARGS_P
)
6664 const CUMULATIVE_ARGS
*cum
;
6665 tree f_ovfl
, f_gtop
, f_ftop
, f_goff
, f_foff
;
6666 tree ovfl
, gtop
, ftop
, goff
, foff
;
6668 int gpr_save_area_size
;
6669 int fpr_save_area_size
;
6672 cum
= &crtl
->args
.info
;
6674 = (MAX_ARGS_IN_REGISTERS
- cum
->num_gprs
) * UNITS_PER_WORD
;
6676 = (MAX_ARGS_IN_REGISTERS
- cum
->num_fprs
) * UNITS_PER_FPREG
;
6678 f_ovfl
= TYPE_FIELDS (va_list_type_node
);
6679 f_gtop
= DECL_CHAIN (f_ovfl
);
6680 f_ftop
= DECL_CHAIN (f_gtop
);
6681 f_goff
= DECL_CHAIN (f_ftop
);
6682 f_foff
= DECL_CHAIN (f_goff
);
6684 ovfl
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovfl
), valist
, f_ovfl
,
6686 gtop
= build3 (COMPONENT_REF
, TREE_TYPE (f_gtop
), valist
, f_gtop
,
6688 ftop
= build3 (COMPONENT_REF
, TREE_TYPE (f_ftop
), valist
, f_ftop
,
6690 goff
= build3 (COMPONENT_REF
, TREE_TYPE (f_goff
), valist
, f_goff
,
6692 foff
= build3 (COMPONENT_REF
, TREE_TYPE (f_foff
), valist
, f_foff
,
6695 /* Emit code to initialize OVFL, which points to the next varargs
6696 stack argument. CUM->STACK_WORDS gives the number of stack
6697 words used by named arguments. */
6698 t
= make_tree (TREE_TYPE (ovfl
), virtual_incoming_args_rtx
);
6699 if (cum
->stack_words
> 0)
6700 t
= fold_build_pointer_plus_hwi (t
, cum
->stack_words
* UNITS_PER_WORD
);
6701 t
= build2 (MODIFY_EXPR
, TREE_TYPE (ovfl
), ovfl
, t
);
6702 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6704 /* Emit code to initialize GTOP, the top of the GPR save area. */
6705 t
= make_tree (TREE_TYPE (gtop
), virtual_incoming_args_rtx
);
6706 t
= build2 (MODIFY_EXPR
, TREE_TYPE (gtop
), gtop
, t
);
6707 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6709 /* Emit code to initialize FTOP, the top of the FPR save area.
6710 This address is gpr_save_area_bytes below GTOP, rounded
6711 down to the next fp-aligned boundary. */
6712 t
= make_tree (TREE_TYPE (ftop
), virtual_incoming_args_rtx
);
6713 fpr_offset
= gpr_save_area_size
+ UNITS_PER_FPVALUE
- 1;
6714 fpr_offset
&= -UNITS_PER_FPVALUE
;
6716 t
= fold_build_pointer_plus_hwi (t
, -fpr_offset
);
6717 t
= build2 (MODIFY_EXPR
, TREE_TYPE (ftop
), ftop
, t
);
6718 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6720 /* Emit code to initialize GOFF, the offset from GTOP of the
6721 next GPR argument. */
6722 t
= build2 (MODIFY_EXPR
, TREE_TYPE (goff
), goff
,
6723 build_int_cst (TREE_TYPE (goff
), gpr_save_area_size
));
6724 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6726 /* Likewise emit code to initialize FOFF, the offset from FTOP
6727 of the next FPR argument. */
6728 t
= build2 (MODIFY_EXPR
, TREE_TYPE (foff
), foff
,
6729 build_int_cst (TREE_TYPE (foff
), fpr_save_area_size
));
6730 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6734 nextarg
= plus_constant (Pmode
, nextarg
, -cfun
->machine
->varargs_size
);
6735 std_expand_builtin_va_start (valist
, nextarg
);
6739 /* Like std_gimplify_va_arg_expr, but apply alignment to zero-sized
6743 mips_std_gimplify_va_arg_expr (tree valist
, tree type
, gimple_seq
*pre_p
,
6746 tree addr
, t
, type_size
, rounded_size
, valist_tmp
;
6747 unsigned HOST_WIDE_INT align
, boundary
;
6750 indirect
= pass_by_reference (NULL
, TYPE_MODE (type
), type
, false);
6752 type
= build_pointer_type (type
);
6754 align
= PARM_BOUNDARY
/ BITS_PER_UNIT
;
6755 boundary
= targetm
.calls
.function_arg_boundary (TYPE_MODE (type
), type
);
6757 /* When we align parameter on stack for caller, if the parameter
6758 alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
6759 aligned at MAX_SUPPORTED_STACK_ALIGNMENT. We will match callee
6760 here with caller. */
6761 if (boundary
> MAX_SUPPORTED_STACK_ALIGNMENT
)
6762 boundary
= MAX_SUPPORTED_STACK_ALIGNMENT
;
6764 boundary
/= BITS_PER_UNIT
;
6766 /* Hoist the valist value into a temporary for the moment. */
6767 valist_tmp
= get_initialized_tmp_var (valist
, pre_p
, NULL
);
6769 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
6770 requires greater alignment, we must perform dynamic alignment. */
6771 if (boundary
> align
)
6773 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
6774 fold_build_pointer_plus_hwi (valist_tmp
, boundary
- 1));
6775 gimplify_and_add (t
, pre_p
);
6777 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
6778 fold_build2 (BIT_AND_EXPR
, TREE_TYPE (valist
),
6780 build_int_cst (TREE_TYPE (valist
), -boundary
)));
6781 gimplify_and_add (t
, pre_p
);
6786 /* If the actual alignment is less than the alignment of the type,
6787 adjust the type accordingly so that we don't assume strict alignment
6788 when dereferencing the pointer. */
6789 boundary
*= BITS_PER_UNIT
;
6790 if (boundary
< TYPE_ALIGN (type
))
6792 type
= build_variant_type_copy (type
);
6793 SET_TYPE_ALIGN (type
, boundary
);
6796 /* Compute the rounded size of the type. */
6797 type_size
= size_in_bytes (type
);
6798 rounded_size
= round_up (type_size
, align
);
6800 /* Reduce rounded_size so it's sharable with the postqueue. */
6801 gimplify_expr (&rounded_size
, pre_p
, post_p
, is_gimple_val
, fb_rvalue
);
6805 if (PAD_VARARGS_DOWN
&& !integer_zerop (rounded_size
))
6807 /* Small args are padded downward. */
6808 t
= fold_build2_loc (input_location
, GT_EXPR
, sizetype
,
6809 rounded_size
, size_int (align
));
6810 t
= fold_build3 (COND_EXPR
, sizetype
, t
, size_zero_node
,
6811 size_binop (MINUS_EXPR
, rounded_size
, type_size
));
6812 addr
= fold_build_pointer_plus (addr
, t
);
6815 /* Compute new value for AP. */
6816 t
= fold_build_pointer_plus (valist_tmp
, rounded_size
);
6817 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist
, t
);
6818 gimplify_and_add (t
, pre_p
);
6820 addr
= fold_convert (build_pointer_type (type
), addr
);
6823 addr
= build_va_arg_indirect_ref (addr
);
6825 return build_va_arg_indirect_ref (addr
);
6828 /* Implement TARGET_GIMPLIFY_VA_ARG_EXPR. */
6831 mips_gimplify_va_arg_expr (tree valist
, tree type
, gimple_seq
*pre_p
,
6837 indirect_p
= pass_by_reference (NULL
, TYPE_MODE (type
), type
, 0);
6839 type
= build_pointer_type (type
);
6841 if (!EABI_FLOAT_VARARGS_P
)
6842 addr
= mips_std_gimplify_va_arg_expr (valist
, type
, pre_p
, post_p
);
6845 tree f_ovfl
, f_gtop
, f_ftop
, f_goff
, f_foff
;
6846 tree ovfl
, top
, off
, align
;
6847 HOST_WIDE_INT size
, rsize
, osize
;
6850 f_ovfl
= TYPE_FIELDS (va_list_type_node
);
6851 f_gtop
= DECL_CHAIN (f_ovfl
);
6852 f_ftop
= DECL_CHAIN (f_gtop
);
6853 f_goff
= DECL_CHAIN (f_ftop
);
6854 f_foff
= DECL_CHAIN (f_goff
);
6858 TOP be the top of the GPR or FPR save area;
6859 OFF be the offset from TOP of the next register;
6860 ADDR_RTX be the address of the argument;
6861 SIZE be the number of bytes in the argument type;
6862 RSIZE be the number of bytes used to store the argument
6863 when it's in the register save area; and
6864 OSIZE be the number of bytes used to store it when it's
6865 in the stack overflow area.
6867 The code we want is:
6869 1: off &= -rsize; // round down
6872 4: addr_rtx = top - off + (BYTES_BIG_ENDIAN ? RSIZE - SIZE : 0);
6877 9: ovfl = ((intptr_t) ovfl + osize - 1) & -osize;
6878 10: addr_rtx = ovfl + (BYTES_BIG_ENDIAN ? OSIZE - SIZE : 0);
6882 [1] and [9] can sometimes be optimized away. */
6884 ovfl
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovfl
), valist
, f_ovfl
,
6886 size
= int_size_in_bytes (type
);
6888 if (GET_MODE_CLASS (TYPE_MODE (type
)) == MODE_FLOAT
6889 && GET_MODE_SIZE (TYPE_MODE (type
)) <= UNITS_PER_FPVALUE
)
6891 top
= build3 (COMPONENT_REF
, TREE_TYPE (f_ftop
),
6892 unshare_expr (valist
), f_ftop
, NULL_TREE
);
6893 off
= build3 (COMPONENT_REF
, TREE_TYPE (f_foff
),
6894 unshare_expr (valist
), f_foff
, NULL_TREE
);
6896 /* When va_start saves FPR arguments to the stack, each slot
6897 takes up UNITS_PER_HWFPVALUE bytes, regardless of the
6898 argument's precision. */
6899 rsize
= UNITS_PER_HWFPVALUE
;
6901 /* Overflow arguments are padded to UNITS_PER_WORD bytes
6902 (= PARM_BOUNDARY bits). This can be different from RSIZE
6905 (1) On 32-bit targets when TYPE is a structure such as:
6907 struct s { float f; };
6909 Such structures are passed in paired FPRs, so RSIZE
6910 will be 8 bytes. However, the structure only takes
6911 up 4 bytes of memory, so OSIZE will only be 4.
6913 (2) In combinations such as -mgp64 -msingle-float
6914 -fshort-double. Doubles passed in registers will then take
6915 up 4 (UNITS_PER_HWFPVALUE) bytes, but those passed on the
6916 stack take up UNITS_PER_WORD bytes. */
6917 osize
= MAX (GET_MODE_SIZE (TYPE_MODE (type
)), UNITS_PER_WORD
);
6921 top
= build3 (COMPONENT_REF
, TREE_TYPE (f_gtop
),
6922 unshare_expr (valist
), f_gtop
, NULL_TREE
);
6923 off
= build3 (COMPONENT_REF
, TREE_TYPE (f_goff
),
6924 unshare_expr (valist
), f_goff
, NULL_TREE
);
6925 rsize
= ROUND_UP (size
, UNITS_PER_WORD
);
6926 if (rsize
> UNITS_PER_WORD
)
6928 /* [1] Emit code for: off &= -rsize. */
6929 t
= build2 (BIT_AND_EXPR
, TREE_TYPE (off
), unshare_expr (off
),
6930 build_int_cst (TREE_TYPE (off
), -rsize
));
6931 gimplify_assign (unshare_expr (off
), t
, pre_p
);
6936 /* [2] Emit code to branch if off == 0. */
6937 t
= build2 (NE_EXPR
, boolean_type_node
, unshare_expr (off
),
6938 build_int_cst (TREE_TYPE (off
), 0));
6939 addr
= build3 (COND_EXPR
, ptr_type_node
, t
, NULL_TREE
, NULL_TREE
);
6941 /* [5] Emit code for: off -= rsize. We do this as a form of
6942 post-decrement not available to C. */
6943 t
= fold_convert (TREE_TYPE (off
), build_int_cst (NULL_TREE
, rsize
));
6944 t
= build2 (POSTDECREMENT_EXPR
, TREE_TYPE (off
), off
, t
);
6946 /* [4] Emit code for:
6947 addr_rtx = top - off + (BYTES_BIG_ENDIAN ? RSIZE - SIZE : 0). */
6948 t
= fold_convert (sizetype
, t
);
6949 t
= fold_build1 (NEGATE_EXPR
, sizetype
, t
);
6950 t
= fold_build_pointer_plus (top
, t
);
6951 if (BYTES_BIG_ENDIAN
&& rsize
> size
)
6952 t
= fold_build_pointer_plus_hwi (t
, rsize
- size
);
6953 COND_EXPR_THEN (addr
) = t
;
6955 if (osize
> UNITS_PER_WORD
)
6957 /* [9] Emit: ovfl = ((intptr_t) ovfl + osize - 1) & -osize. */
6958 t
= fold_build_pointer_plus_hwi (unshare_expr (ovfl
), osize
- 1);
6959 u
= build_int_cst (TREE_TYPE (t
), -osize
);
6960 t
= build2 (BIT_AND_EXPR
, TREE_TYPE (t
), t
, u
);
6961 align
= build2 (MODIFY_EXPR
, TREE_TYPE (ovfl
),
6962 unshare_expr (ovfl
), t
);
6967 /* [10, 11] Emit code for:
6968 addr_rtx = ovfl + (BYTES_BIG_ENDIAN ? OSIZE - SIZE : 0)
6970 u
= fold_convert (TREE_TYPE (ovfl
), build_int_cst (NULL_TREE
, osize
));
6971 t
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (ovfl
), ovfl
, u
);
6972 if (BYTES_BIG_ENDIAN
&& osize
> size
)
6973 t
= fold_build_pointer_plus_hwi (t
, osize
- size
);
6975 /* String [9] and [10, 11] together. */
6977 t
= build2 (COMPOUND_EXPR
, TREE_TYPE (t
), align
, t
);
6978 COND_EXPR_ELSE (addr
) = t
;
6980 addr
= fold_convert (build_pointer_type (type
), addr
);
6981 addr
= build_va_arg_indirect_ref (addr
);
6985 addr
= build_va_arg_indirect_ref (addr
);
6990 /* Declare a unique, locally-binding function called NAME, then start
6994 mips_start_unique_function (const char *name
)
6998 decl
= build_decl (BUILTINS_LOCATION
, FUNCTION_DECL
,
6999 get_identifier (name
),
7000 build_function_type_list (void_type_node
, NULL_TREE
));
7001 DECL_RESULT (decl
) = build_decl (BUILTINS_LOCATION
, RESULT_DECL
,
7002 NULL_TREE
, void_type_node
);
7003 TREE_PUBLIC (decl
) = 1;
7004 TREE_STATIC (decl
) = 1;
7006 cgraph_node::create (decl
)->set_comdat_group (DECL_ASSEMBLER_NAME (decl
));
7008 targetm
.asm_out
.unique_section (decl
, 0);
7009 switch_to_section (get_named_section (decl
, NULL
, 0));
7011 targetm
.asm_out
.globalize_label (asm_out_file
, name
);
7012 fputs ("\t.hidden\t", asm_out_file
);
7013 assemble_name (asm_out_file
, name
);
7014 putc ('\n', asm_out_file
);
7017 /* Start a definition of function NAME. MIPS16_P indicates whether the
7018 function contains MIPS16 code. */
7021 mips_start_function_definition (const char *name
, bool mips16_p
)
7024 fprintf (asm_out_file
, "\t.set\tmips16\n");
7026 fprintf (asm_out_file
, "\t.set\tnomips16\n");
7028 if (TARGET_MICROMIPS
)
7029 fprintf (asm_out_file
, "\t.set\tmicromips\n");
7030 #ifdef HAVE_GAS_MICROMIPS
7032 fprintf (asm_out_file
, "\t.set\tnomicromips\n");
7035 if (!flag_inhibit_size_directive
)
7037 fputs ("\t.ent\t", asm_out_file
);
7038 assemble_name (asm_out_file
, name
);
7039 fputs ("\n", asm_out_file
);
7042 ASM_OUTPUT_TYPE_DIRECTIVE (asm_out_file
, name
, "function");
7044 /* Start the definition proper. */
7045 assemble_name (asm_out_file
, name
);
7046 fputs (":\n", asm_out_file
);
7049 /* End a function definition started by mips_start_function_definition. */
7052 mips_end_function_definition (const char *name
)
7054 if (!flag_inhibit_size_directive
)
7056 fputs ("\t.end\t", asm_out_file
);
7057 assemble_name (asm_out_file
, name
);
7058 fputs ("\n", asm_out_file
);
7062 /* If *STUB_PTR points to a stub, output a comdat-style definition for it,
7063 then free *STUB_PTR. */
7066 mips_finish_stub (mips_one_only_stub
**stub_ptr
)
7068 mips_one_only_stub
*stub
= *stub_ptr
;
7072 const char *name
= stub
->get_name ();
7073 mips_start_unique_function (name
);
7074 mips_start_function_definition (name
, false);
7075 stub
->output_body ();
7076 mips_end_function_definition (name
);
7081 /* Return true if calls to X can use R_MIPS_CALL* relocations. */
7084 mips_ok_for_lazy_binding_p (rtx x
)
7086 return (TARGET_USE_GOT
7087 && GET_CODE (x
) == SYMBOL_REF
7088 && !SYMBOL_REF_BIND_NOW_P (x
)
7089 && !mips_symbol_binds_local_p (x
));
7092 /* Load function address ADDR into register DEST. TYPE is as for
7093 mips_expand_call. Return true if we used an explicit lazy-binding
7097 mips_load_call_address (enum mips_call_type type
, rtx dest
, rtx addr
)
7099 /* If we're generating PIC, and this call is to a global function,
7100 try to allow its address to be resolved lazily. This isn't
7101 possible for sibcalls when $gp is call-saved because the value
7102 of $gp on entry to the stub would be our caller's gp, not ours. */
7103 if (TARGET_EXPLICIT_RELOCS
7104 && !(type
== MIPS_CALL_SIBCALL
&& TARGET_CALL_SAVED_GP
)
7105 && mips_ok_for_lazy_binding_p (addr
))
7107 addr
= mips_got_load (dest
, addr
, SYMBOL_GOTOFF_CALL
);
7108 emit_insn (gen_rtx_SET (dest
, addr
));
7113 mips_emit_move (dest
, addr
);
7118 /* Each locally-defined hard-float MIPS16 function has a local symbol
7119 associated with it. This hash table maps the function symbol (FUNC)
7120 to the local symbol (LOCAL). */
7121 static GTY (()) hash_map
<nofree_string_hash
, rtx
> *mips16_local_aliases
;
7123 /* FUNC is the symbol for a locally-defined hard-float MIPS16 function.
7124 Return a local alias for it, creating a new one if necessary. */
7127 mips16_local_alias (rtx func
)
7129 /* Create the hash table if this is the first call. */
7130 if (mips16_local_aliases
== NULL
)
7131 mips16_local_aliases
= hash_map
<nofree_string_hash
, rtx
>::create_ggc (37);
7133 /* Look up the function symbol, creating a new entry if need be. */
7135 const char *func_name
= XSTR (func
, 0);
7136 rtx
*slot
= &mips16_local_aliases
->get_or_insert (func_name
, &existed
);
7137 gcc_assert (slot
!= NULL
);
7143 /* Create a new SYMBOL_REF for the local symbol. The choice of
7144 __fn_local_* is based on the __fn_stub_* names that we've
7145 traditionally used for the non-MIPS16 stub. */
7146 func_name
= targetm
.strip_name_encoding (XSTR (func
, 0));
7147 const char *local_name
= ACONCAT (("__fn_local_", func_name
, NULL
));
7148 local
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (local_name
));
7149 SYMBOL_REF_FLAGS (local
) = SYMBOL_REF_FLAGS (func
) | SYMBOL_FLAG_LOCAL
;
7151 /* Create a new structure to represent the mapping. */
7157 /* A chained list of functions for which mips16_build_call_stub has already
7158 generated a stub. NAME is the name of the function and FP_RET_P is true
7159 if the function returns a value in floating-point registers. */
7160 struct mips16_stub
{
7161 struct mips16_stub
*next
;
7165 static struct mips16_stub
*mips16_stubs
;
7167 /* Return the two-character string that identifies floating-point
7168 return mode MODE in the name of a MIPS16 function stub. */
7171 mips16_call_stub_mode_suffix (machine_mode mode
)
7175 else if (mode
== DFmode
)
7177 else if (mode
== SCmode
)
7179 else if (mode
== DCmode
)
7181 else if (mode
== V2SFmode
)
7183 gcc_assert (TARGET_PAIRED_SINGLE_FLOAT
);
7190 /* Write instructions to move a 32-bit value between general register
7191 GPREG and floating-point register FPREG. DIRECTION is 't' to move
7192 from GPREG to FPREG and 'f' to move in the opposite direction. */
7195 mips_output_32bit_xfer (char direction
, unsigned int gpreg
, unsigned int fpreg
)
7197 fprintf (asm_out_file
, "\tm%cc1\t%s,%s\n", direction
,
7198 reg_names
[gpreg
], reg_names
[fpreg
]);
7201 /* Likewise for 64-bit values. */
7204 mips_output_64bit_xfer (char direction
, unsigned int gpreg
, unsigned int fpreg
)
7207 fprintf (asm_out_file
, "\tdm%cc1\t%s,%s\n", direction
,
7208 reg_names
[gpreg
], reg_names
[fpreg
]);
7209 else if (ISA_HAS_MXHC1
)
7211 fprintf (asm_out_file
, "\tm%cc1\t%s,%s\n", direction
,
7212 reg_names
[gpreg
+ TARGET_BIG_ENDIAN
], reg_names
[fpreg
]);
7213 fprintf (asm_out_file
, "\tm%chc1\t%s,%s\n", direction
,
7214 reg_names
[gpreg
+ TARGET_LITTLE_ENDIAN
], reg_names
[fpreg
]);
7216 else if (TARGET_FLOATXX
&& direction
== 't')
7218 /* Use the argument save area to move via memory. */
7219 fprintf (asm_out_file
, "\tsw\t%s,0($sp)\n", reg_names
[gpreg
]);
7220 fprintf (asm_out_file
, "\tsw\t%s,4($sp)\n", reg_names
[gpreg
+ 1]);
7221 fprintf (asm_out_file
, "\tldc1\t%s,0($sp)\n", reg_names
[fpreg
]);
7223 else if (TARGET_FLOATXX
&& direction
== 'f')
7225 /* Use the argument save area to move via memory. */
7226 fprintf (asm_out_file
, "\tsdc1\t%s,0($sp)\n", reg_names
[fpreg
]);
7227 fprintf (asm_out_file
, "\tlw\t%s,0($sp)\n", reg_names
[gpreg
]);
7228 fprintf (asm_out_file
, "\tlw\t%s,4($sp)\n", reg_names
[gpreg
+ 1]);
7232 /* Move the least-significant word. */
7233 fprintf (asm_out_file
, "\tm%cc1\t%s,%s\n", direction
,
7234 reg_names
[gpreg
+ TARGET_BIG_ENDIAN
], reg_names
[fpreg
]);
7235 /* ...then the most significant word. */
7236 fprintf (asm_out_file
, "\tm%cc1\t%s,%s\n", direction
,
7237 reg_names
[gpreg
+ TARGET_LITTLE_ENDIAN
], reg_names
[fpreg
+ 1]);
7241 /* Write out code to move floating-point arguments into or out of
7242 general registers. FP_CODE is the code describing which arguments
7243 are present (see the comment above the definition of CUMULATIVE_ARGS
7244 in mips.h). DIRECTION is as for mips_output_32bit_xfer. */
7247 mips_output_args_xfer (int fp_code
, char direction
)
7249 unsigned int gparg
, fparg
, f
;
7250 CUMULATIVE_ARGS cum
;
7252 /* This code only works for o32 and o64. */
7253 gcc_assert (TARGET_OLDABI
);
7255 mips_init_cumulative_args (&cum
, NULL
);
7257 for (f
= (unsigned int) fp_code
; f
!= 0; f
>>= 2)
7260 struct mips_arg_info info
;
7264 else if ((f
& 3) == 2)
7269 mips_get_arg_info (&info
, &cum
, mode
, NULL
, true);
7270 gparg
= mips_arg_regno (&info
, false);
7271 fparg
= mips_arg_regno (&info
, true);
7274 mips_output_32bit_xfer (direction
, gparg
, fparg
);
7276 mips_output_64bit_xfer (direction
, gparg
, fparg
);
7278 mips_function_arg_advance (pack_cumulative_args (&cum
), mode
, NULL
, true);
7282 /* Write a MIPS16 stub for the current function. This stub is used
7283 for functions which take arguments in the floating-point registers.
7284 It is normal-mode code that moves the floating-point arguments
7285 into the general registers and then jumps to the MIPS16 code. */
7288 mips16_build_function_stub (void)
7290 const char *fnname
, *alias_name
, *separator
;
7291 char *secname
, *stubname
;
7296 /* Create the name of the stub, and its unique section. */
7297 symbol
= XEXP (DECL_RTL (current_function_decl
), 0);
7298 alias
= mips16_local_alias (symbol
);
7300 fnname
= targetm
.strip_name_encoding (XSTR (symbol
, 0));
7301 alias_name
= targetm
.strip_name_encoding (XSTR (alias
, 0));
7302 secname
= ACONCAT ((".mips16.fn.", fnname
, NULL
));
7303 stubname
= ACONCAT (("__fn_stub_", fnname
, NULL
));
7305 /* Build a decl for the stub. */
7306 stubdecl
= build_decl (BUILTINS_LOCATION
,
7307 FUNCTION_DECL
, get_identifier (stubname
),
7308 build_function_type_list (void_type_node
, NULL_TREE
));
7309 set_decl_section_name (stubdecl
, secname
);
7310 DECL_RESULT (stubdecl
) = build_decl (BUILTINS_LOCATION
,
7311 RESULT_DECL
, NULL_TREE
, void_type_node
);
7313 /* Output a comment. */
7314 fprintf (asm_out_file
, "\t# Stub function for %s (",
7315 current_function_name ());
7317 for (f
= (unsigned int) crtl
->args
.info
.fp_code
; f
!= 0; f
>>= 2)
7319 fprintf (asm_out_file
, "%s%s", separator
,
7320 (f
& 3) == 1 ? "float" : "double");
7323 fprintf (asm_out_file
, ")\n");
7325 /* Start the function definition. */
7326 assemble_start_function (stubdecl
, stubname
);
7327 mips_start_function_definition (stubname
, false);
7329 /* If generating pic2 code, either set up the global pointer or
7331 if (TARGET_ABICALLS_PIC2
)
7333 if (TARGET_ABSOLUTE_ABICALLS
)
7334 fprintf (asm_out_file
, "\t.option\tpic0\n");
7337 output_asm_insn ("%(.cpload\t%^%)", NULL
);
7338 /* Emit an R_MIPS_NONE relocation to tell the linker what the
7339 target function is. Use a local GOT access when loading the
7340 symbol, to cut down on the number of unnecessary GOT entries
7341 for stubs that aren't needed. */
7342 output_asm_insn (".reloc\t0,R_MIPS_NONE,%0", &symbol
);
7347 /* Load the address of the MIPS16 function into $25. Do this first so
7348 that targets with coprocessor interlocks can use an MFC1 to fill the
7350 output_asm_insn ("la\t%^,%0", &symbol
);
7352 /* Move the arguments from floating-point registers to general registers. */
7353 mips_output_args_xfer (crtl
->args
.info
.fp_code
, 'f');
7355 /* Jump to the MIPS16 function. */
7356 output_asm_insn ("jr\t%^", NULL
);
7358 if (TARGET_ABICALLS_PIC2
&& TARGET_ABSOLUTE_ABICALLS
)
7359 fprintf (asm_out_file
, "\t.option\tpic2\n");
7361 mips_end_function_definition (stubname
);
7363 /* If the linker needs to create a dynamic symbol for the target
7364 function, it will associate the symbol with the stub (which,
7365 unlike the target function, follows the proper calling conventions).
7366 It is therefore useful to have a local alias for the target function,
7367 so that it can still be identified as MIPS16 code. As an optimization,
7368 this symbol can also be used for indirect MIPS16 references from
7369 within this file. */
7370 ASM_OUTPUT_DEF (asm_out_file
, alias_name
, fnname
);
7372 switch_to_section (function_section (current_function_decl
));
7375 /* The current function is a MIPS16 function that returns a value in an FPR.
7376 Copy the return value from its soft-float to its hard-float location.
7377 libgcc2 has special non-MIPS16 helper functions for each case. */
7380 mips16_copy_fpr_return_value (void)
7382 rtx fn
, insn
, retval
;
7384 machine_mode return_mode
;
7387 return_type
= DECL_RESULT (current_function_decl
);
7388 return_mode
= DECL_MODE (return_type
);
7390 name
= ACONCAT (("__mips16_ret_",
7391 mips16_call_stub_mode_suffix (return_mode
),
7393 fn
= mips16_stub_function (name
);
7395 /* The function takes arguments in $2 (and possibly $3), so calls
7396 to it cannot be lazily bound. */
7397 SYMBOL_REF_FLAGS (fn
) |= SYMBOL_FLAG_BIND_NOW
;
7399 /* Model the call as something that takes the GPR return value as
7400 argument and returns an "updated" value. */
7401 retval
= gen_rtx_REG (return_mode
, GP_RETURN
);
7402 insn
= mips_expand_call (MIPS_CALL_EPILOGUE
, retval
, fn
,
7403 const0_rtx
, NULL_RTX
, false);
7404 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), retval
);
7407 /* Consider building a stub for a MIPS16 call to function *FN_PTR.
7408 RETVAL is the location of the return value, or null if this is
7409 a "call" rather than a "call_value". ARGS_SIZE is the size of the
7410 arguments and FP_CODE is the code built by mips_function_arg;
7411 see the comment before the fp_code field in CUMULATIVE_ARGS for details.
7413 There are three alternatives:
7415 - If a stub was needed, emit the call and return the call insn itself.
7417 - If we can avoid using a stub by redirecting the call, set *FN_PTR
7418 to the new target and return null.
7420 - If *FN_PTR doesn't need a stub, return null and leave *FN_PTR
7423 A stub is needed for calls to functions that, in normal mode,
7424 receive arguments in FPRs or return values in FPRs. The stub
7425 copies the arguments from their soft-float positions to their
7426 hard-float positions, calls the real function, then copies the
7427 return value from its hard-float position to its soft-float
7430 We can emit a JAL to *FN_PTR even when *FN_PTR might need a stub.
7431 If *FN_PTR turns out to be to a non-MIPS16 function, the linker
7432 automatically redirects the JAL to the stub, otherwise the JAL
7433 continues to call FN directly. */
7436 mips16_build_call_stub (rtx retval
, rtx
*fn_ptr
, rtx args_size
, int fp_code
)
7440 struct mips16_stub
*l
;
7444 /* We don't need to do anything if we aren't in MIPS16 mode, or if
7445 we were invoked with the -msoft-float option. */
7446 if (!TARGET_MIPS16
|| TARGET_SOFT_FLOAT_ABI
)
7449 /* Figure out whether the value might come back in a floating-point
7451 fp_ret_p
= retval
&& mips_return_mode_in_fpr_p (GET_MODE (retval
));
7453 /* We don't need to do anything if there were no floating-point
7454 arguments and the value will not be returned in a floating-point
7456 if (fp_code
== 0 && !fp_ret_p
)
7459 /* We don't need to do anything if this is a call to a special
7460 MIPS16 support function. */
7462 if (mips16_stub_function_p (fn
))
7465 /* If we're calling a locally-defined MIPS16 function, we know that
7466 it will return values in both the "soft-float" and "hard-float"
7467 registers. There is no need to use a stub to move the latter
7469 if (fp_code
== 0 && mips16_local_function_p (fn
))
7472 /* This code will only work for o32 and o64 abis. The other ABI's
7473 require more sophisticated support. */
7474 gcc_assert (TARGET_OLDABI
);
7476 /* If we're calling via a function pointer, use one of the magic
7477 libgcc.a stubs provided for each (FP_CODE, FP_RET_P) combination.
7478 Each stub expects the function address to arrive in register $2. */
7479 if (GET_CODE (fn
) != SYMBOL_REF
7480 || !call_insn_operand (fn
, VOIDmode
))
7487 /* If this is a locally-defined and locally-binding function,
7488 avoid the stub by calling the local alias directly. */
7489 if (mips16_local_function_p (fn
))
7491 *fn_ptr
= mips16_local_alias (fn
);
7495 /* Create a SYMBOL_REF for the libgcc.a function. */
7497 sprintf (buf
, "__mips16_call_stub_%s_%d",
7498 mips16_call_stub_mode_suffix (GET_MODE (retval
)),
7501 sprintf (buf
, "__mips16_call_stub_%d", fp_code
);
7502 stub_fn
= mips16_stub_function (buf
);
7504 /* The function uses $2 as an argument, so calls to it
7505 cannot be lazily bound. */
7506 SYMBOL_REF_FLAGS (stub_fn
) |= SYMBOL_FLAG_BIND_NOW
;
7508 /* Load the target function into $2. */
7509 addr
= gen_rtx_REG (Pmode
, GP_REG_FIRST
+ 2);
7510 lazy_p
= mips_load_call_address (MIPS_CALL_NORMAL
, addr
, fn
);
7512 /* Emit the call. */
7513 insn
= mips_expand_call (MIPS_CALL_NORMAL
, retval
, stub_fn
,
7514 args_size
, NULL_RTX
, lazy_p
);
7516 /* Tell GCC that this call does indeed use the value of $2. */
7517 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), addr
);
7519 /* If we are handling a floating-point return value, we need to
7520 save $18 in the function prologue. Putting a note on the
7521 call will mean that df_regs_ever_live_p ($18) will be true if the
7522 call is not eliminated, and we can check that in the prologue
7525 CALL_INSN_FUNCTION_USAGE (insn
) =
7526 gen_rtx_EXPR_LIST (VOIDmode
,
7527 gen_rtx_CLOBBER (VOIDmode
,
7528 gen_rtx_REG (word_mode
, 18)),
7529 CALL_INSN_FUNCTION_USAGE (insn
));
7534 /* We know the function we are going to call. If we have already
7535 built a stub, we don't need to do anything further. */
7536 fnname
= targetm
.strip_name_encoding (XSTR (fn
, 0));
7537 for (l
= mips16_stubs
; l
!= NULL
; l
= l
->next
)
7538 if (strcmp (l
->name
, fnname
) == 0)
7543 const char *separator
;
7544 char *secname
, *stubname
;
7545 tree stubid
, stubdecl
;
7548 /* If the function does not return in FPRs, the special stub
7552 If the function does return in FPRs, the stub section is named
7553 .mips16.call.fp.FNNAME
7555 Build a decl for the stub. */
7556 secname
= ACONCAT ((".mips16.call.", fp_ret_p
? "fp." : "",
7558 stubname
= ACONCAT (("__call_stub_", fp_ret_p
? "fp_" : "",
7560 stubid
= get_identifier (stubname
);
7561 stubdecl
= build_decl (BUILTINS_LOCATION
,
7562 FUNCTION_DECL
, stubid
,
7563 build_function_type_list (void_type_node
,
7565 set_decl_section_name (stubdecl
, secname
);
7566 DECL_RESULT (stubdecl
) = build_decl (BUILTINS_LOCATION
,
7567 RESULT_DECL
, NULL_TREE
,
7570 /* Output a comment. */
7571 fprintf (asm_out_file
, "\t# Stub function to call %s%s (",
7573 ? (GET_MODE (retval
) == SFmode
? "float " : "double ")
7577 for (f
= (unsigned int) fp_code
; f
!= 0; f
>>= 2)
7579 fprintf (asm_out_file
, "%s%s", separator
,
7580 (f
& 3) == 1 ? "float" : "double");
7583 fprintf (asm_out_file
, ")\n");
7585 /* Start the function definition. */
7586 assemble_start_function (stubdecl
, stubname
);
7587 mips_start_function_definition (stubname
, false);
7591 fprintf (asm_out_file
, "\t.cfi_startproc\n");
7593 /* Create a fake CFA 4 bytes below the stack pointer.
7594 This works around unwinders (like libgcc's) that expect
7595 the CFA for non-signal frames to be unique. */
7596 fprintf (asm_out_file
, "\t.cfi_def_cfa 29,-4\n");
7598 /* "Save" $sp in itself so we don't use the fake CFA.
7599 This is: DW_CFA_val_expression r29, { DW_OP_reg29 }. */
7600 fprintf (asm_out_file
, "\t.cfi_escape 0x16,29,1,0x6d\n");
7602 /* Save the return address in $18. The stub's caller knows
7603 that $18 might be clobbered, even though $18 is usually
7604 a call-saved register.
7606 Do it early on in case the last move to a floating-point
7607 register can be scheduled into the delay slot of the
7608 call we are about to make. */
7609 fprintf (asm_out_file
, "\tmove\t%s,%s\n",
7610 reg_names
[GP_REG_FIRST
+ 18],
7611 reg_names
[RETURN_ADDR_REGNUM
]);
7615 /* Load the address of the MIPS16 function into $25. Do this
7616 first so that targets with coprocessor interlocks can use
7617 an MFC1 to fill the delay slot. */
7618 if (TARGET_EXPLICIT_RELOCS
)
7620 output_asm_insn ("lui\t%^,%%hi(%0)", &fn
);
7621 output_asm_insn ("addiu\t%^,%^,%%lo(%0)", &fn
);
7624 output_asm_insn ("la\t%^,%0", &fn
);
7627 /* Move the arguments from general registers to floating-point
7629 mips_output_args_xfer (fp_code
, 't');
7633 /* Now call the non-MIPS16 function. */
7634 output_asm_insn (mips_output_jump (&fn
, 0, -1, true), &fn
);
7635 fprintf (asm_out_file
, "\t.cfi_register 31,18\n");
7637 /* Move the result from floating-point registers to
7638 general registers. */
7639 switch (GET_MODE (retval
))
7642 mips_output_32bit_xfer ('f', GP_RETURN
+ TARGET_BIG_ENDIAN
,
7646 mips_output_32bit_xfer ('f', GP_RETURN
+ TARGET_LITTLE_ENDIAN
,
7647 TARGET_LITTLE_ENDIAN
7650 if (GET_MODE (retval
) == SCmode
&& TARGET_64BIT
)
7652 /* On 64-bit targets, complex floats are returned in
7653 a single GPR, such that "sd" on a suitably-aligned
7654 target would store the value correctly. */
7655 fprintf (asm_out_file
, "\tdsll\t%s,%s,32\n",
7656 reg_names
[GP_RETURN
+ TARGET_BIG_ENDIAN
],
7657 reg_names
[GP_RETURN
+ TARGET_BIG_ENDIAN
]);
7658 fprintf (asm_out_file
, "\tdsll\t%s,%s,32\n",
7659 reg_names
[GP_RETURN
+ TARGET_LITTLE_ENDIAN
],
7660 reg_names
[GP_RETURN
+ TARGET_LITTLE_ENDIAN
]);
7661 fprintf (asm_out_file
, "\tdsrl\t%s,%s,32\n",
7662 reg_names
[GP_RETURN
+ TARGET_BIG_ENDIAN
],
7663 reg_names
[GP_RETURN
+ TARGET_BIG_ENDIAN
]);
7664 fprintf (asm_out_file
, "\tor\t%s,%s,%s\n",
7665 reg_names
[GP_RETURN
],
7666 reg_names
[GP_RETURN
],
7667 reg_names
[GP_RETURN
+ 1]);
7672 mips_output_32bit_xfer ('f', GP_RETURN
, FP_REG_FIRST
);
7676 mips_output_64bit_xfer ('f', GP_RETURN
+ (8 / UNITS_PER_WORD
),
7681 gcc_assert (TARGET_PAIRED_SINGLE_FLOAT
7682 || GET_MODE (retval
) != V2SFmode
);
7683 mips_output_64bit_xfer ('f', GP_RETURN
, FP_REG_FIRST
);
7689 fprintf (asm_out_file
, "\tjr\t%s\n", reg_names
[GP_REG_FIRST
+ 18]);
7690 fprintf (asm_out_file
, "\t.cfi_endproc\n");
7694 /* Jump to the previously-loaded address. */
7695 output_asm_insn ("jr\t%^", NULL
);
7698 #ifdef ASM_DECLARE_FUNCTION_SIZE
7699 ASM_DECLARE_FUNCTION_SIZE (asm_out_file
, stubname
, stubdecl
);
7702 mips_end_function_definition (stubname
);
7704 /* Record this stub. */
7705 l
= XNEW (struct mips16_stub
);
7706 l
->name
= xstrdup (fnname
);
7707 l
->fp_ret_p
= fp_ret_p
;
7708 l
->next
= mips16_stubs
;
7712 /* If we expect a floating-point return value, but we've built a
7713 stub which does not expect one, then we're in trouble. We can't
7714 use the existing stub, because it won't handle the floating-point
7715 value. We can't build a new stub, because the linker won't know
7716 which stub to use for the various calls in this object file.
7717 Fortunately, this case is illegal, since it means that a function
7718 was declared in two different ways in a single compilation. */
7719 if (fp_ret_p
&& !l
->fp_ret_p
)
7720 error ("cannot handle inconsistent calls to %qs", fnname
);
7722 if (retval
== NULL_RTX
)
7723 pattern
= gen_call_internal_direct (fn
, args_size
);
7725 pattern
= gen_call_value_internal_direct (retval
, fn
, args_size
);
7726 insn
= mips_emit_call_insn (pattern
, fn
, fn
, false);
7728 /* If we are calling a stub which handles a floating-point return
7729 value, we need to arrange to save $18 in the prologue. We do this
7730 by marking the function call as using the register. The prologue
7731 will later see that it is used, and emit code to save it. */
7733 CALL_INSN_FUNCTION_USAGE (insn
) =
7734 gen_rtx_EXPR_LIST (VOIDmode
,
7735 gen_rtx_CLOBBER (VOIDmode
,
7736 gen_rtx_REG (word_mode
, 18)),
7737 CALL_INSN_FUNCTION_USAGE (insn
));
7742 /* Expand a call of type TYPE. RESULT is where the result will go (null
7743 for "call"s and "sibcall"s), ADDR is the address of the function,
7744 ARGS_SIZE is the size of the arguments and AUX is the value passed
7745 to us by mips_function_arg. LAZY_P is true if this call already
7746 involves a lazily-bound function address (such as when calling
7747 functions through a MIPS16 hard-float stub).
7749 Return the call itself. */
7752 mips_expand_call (enum mips_call_type type
, rtx result
, rtx addr
,
7753 rtx args_size
, rtx aux
, bool lazy_p
)
7755 rtx orig_addr
, pattern
;
7759 fp_code
= aux
== 0 ? 0 : (int) GET_MODE (aux
);
7760 insn
= mips16_build_call_stub (result
, &addr
, args_size
, fp_code
);
7763 gcc_assert (!lazy_p
&& type
== MIPS_CALL_NORMAL
);
7768 if (!call_insn_operand (addr
, VOIDmode
))
7770 if (type
== MIPS_CALL_EPILOGUE
)
7771 addr
= MIPS_EPILOGUE_TEMP (Pmode
);
7773 addr
= gen_reg_rtx (Pmode
);
7774 lazy_p
|= mips_load_call_address (type
, addr
, orig_addr
);
7779 rtx (*fn
) (rtx
, rtx
);
7781 if (type
== MIPS_CALL_SIBCALL
)
7782 fn
= gen_sibcall_internal
;
7784 fn
= gen_call_internal
;
7786 pattern
= fn (addr
, args_size
);
7788 else if (GET_CODE (result
) == PARALLEL
&& XVECLEN (result
, 0) == 2)
7790 /* Handle return values created by mips_return_fpr_pair. */
7791 rtx (*fn
) (rtx
, rtx
, rtx
, rtx
);
7794 if (type
== MIPS_CALL_SIBCALL
)
7795 fn
= gen_sibcall_value_multiple_internal
;
7797 fn
= gen_call_value_multiple_internal
;
7799 reg1
= XEXP (XVECEXP (result
, 0, 0), 0);
7800 reg2
= XEXP (XVECEXP (result
, 0, 1), 0);
7801 pattern
= fn (reg1
, addr
, args_size
, reg2
);
7805 rtx (*fn
) (rtx
, rtx
, rtx
);
7807 if (type
== MIPS_CALL_SIBCALL
)
7808 fn
= gen_sibcall_value_internal
;
7810 fn
= gen_call_value_internal
;
7812 /* Handle return values created by mips_return_fpr_single. */
7813 if (GET_CODE (result
) == PARALLEL
&& XVECLEN (result
, 0) == 1)
7814 result
= XEXP (XVECEXP (result
, 0, 0), 0);
7815 pattern
= fn (result
, addr
, args_size
);
7818 return mips_emit_call_insn (pattern
, orig_addr
, addr
, lazy_p
);
7821 /* Split call instruction INSN into a $gp-clobbering call and
7822 (where necessary) an instruction to restore $gp from its save slot.
7823 CALL_PATTERN is the pattern of the new call. */
7826 mips_split_call (rtx insn
, rtx call_pattern
)
7828 emit_call_insn (call_pattern
);
7829 if (!find_reg_note (insn
, REG_NORETURN
, 0))
7830 mips_restore_gp_from_cprestore_slot (gen_rtx_REG (Pmode
,
7831 POST_CALL_TMP_REG
));
7834 /* Return true if a call to DECL may need to use JALX. */
7837 mips_call_may_need_jalx_p (tree decl
)
7839 /* If the current translation unit would use a different mode for DECL,
7840 assume that the call needs JALX. */
7841 if (mips_get_compress_mode (decl
) != TARGET_COMPRESSION
)
7844 /* mips_get_compress_mode is always accurate for locally-binding
7845 functions in the current translation unit. */
7846 if (!DECL_EXTERNAL (decl
) && targetm
.binds_local_p (decl
))
7849 /* When -minterlink-compressed is in effect, assume that functions
7850 could use a different encoding mode unless an attribute explicitly
7851 tells us otherwise. */
7852 if (TARGET_INTERLINK_COMPRESSED
)
7854 if (!TARGET_COMPRESSION
7855 && mips_get_compress_off_flags (DECL_ATTRIBUTES (decl
)) ==0)
7857 if (TARGET_COMPRESSION
7858 && mips_get_compress_on_flags (DECL_ATTRIBUTES (decl
)) == 0)
7865 /* Implement TARGET_FUNCTION_OK_FOR_SIBCALL. */
7868 mips_function_ok_for_sibcall (tree decl
, tree exp ATTRIBUTE_UNUSED
)
7870 if (!TARGET_SIBCALLS
)
7873 /* Interrupt handlers need special epilogue code and therefore can't
7875 if (mips_interrupt_type_p (TREE_TYPE (current_function_decl
)))
7878 /* Direct Js are only possible to functions that use the same ISA encoding.
7879 There is no JX counterpoart of JALX. */
7881 && const_call_insn_operand (XEXP (DECL_RTL (decl
), 0), VOIDmode
)
7882 && mips_call_may_need_jalx_p (decl
))
7885 /* Sibling calls should not prevent lazy binding. Lazy-binding stubs
7886 require $gp to be valid on entry, so sibcalls can only use stubs
7887 if $gp is call-clobbered. */
7889 && TARGET_CALL_SAVED_GP
7890 && !TARGET_ABICALLS_PIC0
7891 && !targetm
.binds_local_p (decl
))
7898 /* Implement TARGET_USE_MOVE_BY_PIECES_INFRASTRUCTURE_P. */
7901 mips_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size
,
7903 enum by_pieces_operation op
,
7906 if (op
== STORE_BY_PIECES
)
7907 return mips_store_by_pieces_p (size
, align
);
7908 if (op
== MOVE_BY_PIECES
&& HAVE_movmemsi
)
7910 /* movmemsi is meant to generate code that is at least as good as
7911 move_by_pieces. However, movmemsi effectively uses a by-pieces
7912 implementation both for moves smaller than a word and for
7913 word-aligned moves of no more than MIPS_MAX_MOVE_BYTES_STRAIGHT
7914 bytes. We should allow the tree-level optimisers to do such
7915 moves by pieces, as it often exposes other optimization
7916 opportunities. We might as well continue to use movmemsi at
7917 the rtl level though, as it produces better code when
7918 scheduling is disabled (such as at -O). */
7919 if (currently_expanding_to_rtl
)
7921 if (align
< BITS_PER_WORD
)
7922 return size
< UNITS_PER_WORD
;
7923 return size
<= MIPS_MAX_MOVE_BYTES_STRAIGHT
;
7926 return default_use_by_pieces_infrastructure_p (size
, align
, op
, speed_p
);
7929 /* Implement a handler for STORE_BY_PIECES operations
7930 for TARGET_USE_MOVE_BY_PIECES_INFRASTRUCTURE_P. */
7933 mips_store_by_pieces_p (unsigned HOST_WIDE_INT size
, unsigned int align
)
7935 /* Storing by pieces involves moving constants into registers
7936 of size MIN (ALIGN, BITS_PER_WORD), then storing them.
7937 We need to decide whether it is cheaper to load the address of
7938 constant data into a register and use a block move instead. */
7940 /* If the data is only byte aligned, then:
7942 (a1) A block move of less than 4 bytes would involve three 3 LBs and
7943 3 SBs. We might as well use 3 single-instruction LIs and 3 SBs
7946 (a2) A block move of 4 bytes from aligned source data can use an
7947 LW/SWL/SWR sequence. This is often better than the 4 LIs and
7948 4 SBs that we would generate when storing by pieces. */
7949 if (align
<= BITS_PER_UNIT
)
7952 /* If the data is 2-byte aligned, then:
7954 (b1) A block move of less than 4 bytes would use a combination of LBs,
7955 LHs, SBs and SHs. We get better code by using single-instruction
7956 LIs, SBs and SHs instead.
7958 (b2) A block move of 4 bytes from aligned source data would again use
7959 an LW/SWL/SWR sequence. In most cases, loading the address of
7960 the source data would require at least one extra instruction.
7961 It is often more efficient to use 2 single-instruction LIs and
7964 (b3) A block move of up to 3 additional bytes would be like (b1).
7966 (b4) A block move of 8 bytes from aligned source data can use two
7967 LW/SWL/SWR sequences or a single LD/SDL/SDR sequence. Both
7968 sequences are better than the 4 LIs and 4 SHs that we'd generate
7969 when storing by pieces.
7971 The reasoning for higher alignments is similar:
7973 (c1) A block move of less than 4 bytes would be the same as (b1).
7975 (c2) A block move of 4 bytes would use an LW/SW sequence. Again,
7976 loading the address of the source data would typically require
7977 at least one extra instruction. It is generally better to use
7980 (c3) A block move of up to 3 additional bytes would be like (b1).
7982 (c4) A block move of 8 bytes can use two LW/SW sequences or a single
7983 LD/SD sequence, and in these cases we've traditionally preferred
7984 the memory copy over the more bulky constant moves. */
7988 /* Emit straight-line code to move LENGTH bytes from SRC to DEST.
7989 Assume that the areas do not overlap. */
7992 mips_block_move_straight (rtx dest
, rtx src
, HOST_WIDE_INT length
)
7994 HOST_WIDE_INT offset
, delta
;
7995 unsigned HOST_WIDE_INT bits
;
8000 /* Work out how many bits to move at a time. If both operands have
8001 half-word alignment, it is usually better to move in half words.
8002 For instance, lh/lh/sh/sh is usually better than lwl/lwr/swl/swr
8003 and lw/lw/sw/sw is usually better than ldl/ldr/sdl/sdr.
8004 Otherwise move word-sized chunks.
8006 For ISA_HAS_LWL_LWR we rely on the lwl/lwr & swl/swr load. Otherwise
8007 picking the minimum of alignment or BITS_PER_WORD gets us the
8008 desired size for bits. */
8010 if (!ISA_HAS_LWL_LWR
)
8011 bits
= MIN (BITS_PER_WORD
, MIN (MEM_ALIGN (src
), MEM_ALIGN (dest
)));
8014 if (MEM_ALIGN (src
) == BITS_PER_WORD
/ 2
8015 && MEM_ALIGN (dest
) == BITS_PER_WORD
/ 2)
8016 bits
= BITS_PER_WORD
/ 2;
8018 bits
= BITS_PER_WORD
;
8021 mode
= int_mode_for_size (bits
, 0).require ();
8022 delta
= bits
/ BITS_PER_UNIT
;
8024 /* Allocate a buffer for the temporary registers. */
8025 regs
= XALLOCAVEC (rtx
, length
/ delta
);
8027 /* Load as many BITS-sized chunks as possible. Use a normal load if
8028 the source has enough alignment, otherwise use left/right pairs. */
8029 for (offset
= 0, i
= 0; offset
+ delta
<= length
; offset
+= delta
, i
++)
8031 regs
[i
] = gen_reg_rtx (mode
);
8032 if (MEM_ALIGN (src
) >= bits
)
8033 mips_emit_move (regs
[i
], adjust_address (src
, mode
, offset
));
8036 rtx part
= adjust_address (src
, BLKmode
, offset
);
8037 set_mem_size (part
, delta
);
8038 if (!mips_expand_ext_as_unaligned_load (regs
[i
], part
, bits
, 0, 0))
8043 /* Copy the chunks to the destination. */
8044 for (offset
= 0, i
= 0; offset
+ delta
<= length
; offset
+= delta
, i
++)
8045 if (MEM_ALIGN (dest
) >= bits
)
8046 mips_emit_move (adjust_address (dest
, mode
, offset
), regs
[i
]);
8049 rtx part
= adjust_address (dest
, BLKmode
, offset
);
8050 set_mem_size (part
, delta
);
8051 if (!mips_expand_ins_as_unaligned_store (part
, regs
[i
], bits
, 0))
8055 /* Mop up any left-over bytes. */
8056 if (offset
< length
)
8058 src
= adjust_address (src
, BLKmode
, offset
);
8059 dest
= adjust_address (dest
, BLKmode
, offset
);
8060 move_by_pieces (dest
, src
, length
- offset
,
8061 MIN (MEM_ALIGN (src
), MEM_ALIGN (dest
)), 0);
8065 /* Helper function for doing a loop-based block operation on memory
8066 reference MEM. Each iteration of the loop will operate on LENGTH
8069 Create a new base register for use within the loop and point it to
8070 the start of MEM. Create a new memory reference that uses this
8071 register. Store them in *LOOP_REG and *LOOP_MEM respectively. */
8074 mips_adjust_block_mem (rtx mem
, HOST_WIDE_INT length
,
8075 rtx
*loop_reg
, rtx
*loop_mem
)
8077 *loop_reg
= copy_addr_to_reg (XEXP (mem
, 0));
8079 /* Although the new mem does not refer to a known location,
8080 it does keep up to LENGTH bytes of alignment. */
8081 *loop_mem
= change_address (mem
, BLKmode
, *loop_reg
);
8082 set_mem_align (*loop_mem
, MIN (MEM_ALIGN (mem
), length
* BITS_PER_UNIT
));
8085 /* Move LENGTH bytes from SRC to DEST using a loop that moves BYTES_PER_ITER
8086 bytes at a time. LENGTH must be at least BYTES_PER_ITER. Assume that
8087 the memory regions do not overlap. */
8090 mips_block_move_loop (rtx dest
, rtx src
, HOST_WIDE_INT length
,
8091 HOST_WIDE_INT bytes_per_iter
)
8093 rtx_code_label
*label
;
8094 rtx src_reg
, dest_reg
, final_src
, test
;
8095 HOST_WIDE_INT leftover
;
8097 leftover
= length
% bytes_per_iter
;
8100 /* Create registers and memory references for use within the loop. */
8101 mips_adjust_block_mem (src
, bytes_per_iter
, &src_reg
, &src
);
8102 mips_adjust_block_mem (dest
, bytes_per_iter
, &dest_reg
, &dest
);
8104 /* Calculate the value that SRC_REG should have after the last iteration
8106 final_src
= expand_simple_binop (Pmode
, PLUS
, src_reg
, GEN_INT (length
),
8109 /* Emit the start of the loop. */
8110 label
= gen_label_rtx ();
8113 /* Emit the loop body. */
8114 mips_block_move_straight (dest
, src
, bytes_per_iter
);
8116 /* Move on to the next block. */
8117 mips_emit_move (src_reg
, plus_constant (Pmode
, src_reg
, bytes_per_iter
));
8118 mips_emit_move (dest_reg
, plus_constant (Pmode
, dest_reg
, bytes_per_iter
));
8120 /* Emit the loop condition. */
8121 test
= gen_rtx_NE (VOIDmode
, src_reg
, final_src
);
8122 if (Pmode
== DImode
)
8123 emit_jump_insn (gen_cbranchdi4 (test
, src_reg
, final_src
, label
));
8125 emit_jump_insn (gen_cbranchsi4 (test
, src_reg
, final_src
, label
));
8127 /* Mop up any left-over bytes. */
8129 mips_block_move_straight (dest
, src
, leftover
);
8131 /* Temporary fix for PR79150. */
8132 emit_insn (gen_nop ());
8135 /* Expand a movmemsi instruction, which copies LENGTH bytes from
8136 memory reference SRC to memory reference DEST. */
8139 mips_expand_block_move (rtx dest
, rtx src
, rtx length
)
8141 if (!ISA_HAS_LWL_LWR
8142 && (MEM_ALIGN (src
) < MIPS_MIN_MOVE_MEM_ALIGN
8143 || MEM_ALIGN (dest
) < MIPS_MIN_MOVE_MEM_ALIGN
))
8146 if (CONST_INT_P (length
))
8148 if (INTVAL (length
) <= MIPS_MAX_MOVE_BYTES_STRAIGHT
)
8150 mips_block_move_straight (dest
, src
, INTVAL (length
));
8155 mips_block_move_loop (dest
, src
, INTVAL (length
),
8156 MIPS_MAX_MOVE_BYTES_PER_LOOP_ITER
);
8163 /* Expand a loop of synci insns for the address range [BEGIN, END). */
8166 mips_expand_synci_loop (rtx begin
, rtx end
)
8168 rtx inc
, cmp_result
, mask
, length
;
8169 rtx_code_label
*label
, *end_label
;
8171 /* Create end_label. */
8172 end_label
= gen_label_rtx ();
8174 /* Check if begin equals end. */
8175 cmp_result
= gen_rtx_EQ (VOIDmode
, begin
, end
);
8176 emit_jump_insn (gen_condjump (cmp_result
, end_label
));
8178 /* Load INC with the cache line size (rdhwr INC,$1). */
8179 inc
= gen_reg_rtx (Pmode
);
8180 emit_insn (PMODE_INSN (gen_rdhwr_synci_step
, (inc
)));
8182 /* Check if inc is 0. */
8183 cmp_result
= gen_rtx_EQ (VOIDmode
, inc
, const0_rtx
);
8184 emit_jump_insn (gen_condjump (cmp_result
, end_label
));
8186 /* Calculate mask. */
8187 mask
= mips_force_unary (Pmode
, NEG
, inc
);
8189 /* Mask out begin by mask. */
8190 begin
= mips_force_binary (Pmode
, AND
, begin
, mask
);
8192 /* Calculate length. */
8193 length
= mips_force_binary (Pmode
, MINUS
, end
, begin
);
8195 /* Loop back to here. */
8196 label
= gen_label_rtx ();
8199 emit_insn (gen_synci (begin
));
8201 /* Update length. */
8202 mips_emit_binary (MINUS
, length
, length
, inc
);
8205 mips_emit_binary (PLUS
, begin
, begin
, inc
);
8207 /* Check if length is greater than 0. */
8208 cmp_result
= gen_rtx_GT (VOIDmode
, length
, const0_rtx
);
8209 emit_jump_insn (gen_condjump (cmp_result
, label
));
8211 emit_label (end_label
);
8214 /* Expand a QI or HI mode atomic memory operation.
8216 GENERATOR contains a pointer to the gen_* function that generates
8217 the SI mode underlying atomic operation using masks that we
8220 RESULT is the return register for the operation. Its value is NULL
8223 MEM is the location of the atomic access.
8225 OLDVAL is the first operand for the operation.
8227 NEWVAL is the optional second operand for the operation. Its value
8228 is NULL if unused. */
8231 mips_expand_atomic_qihi (union mips_gen_fn_ptrs generator
,
8232 rtx result
, rtx mem
, rtx oldval
, rtx newval
)
8234 rtx orig_addr
, memsi_addr
, memsi
, shift
, shiftsi
, unshifted_mask
;
8235 rtx unshifted_mask_reg
, mask
, inverted_mask
, si_op
;
8239 mode
= GET_MODE (mem
);
8241 /* Compute the address of the containing SImode value. */
8242 orig_addr
= force_reg (Pmode
, XEXP (mem
, 0));
8243 memsi_addr
= mips_force_binary (Pmode
, AND
, orig_addr
,
8244 force_reg (Pmode
, GEN_INT (-4)));
8246 /* Create a memory reference for it. */
8247 memsi
= gen_rtx_MEM (SImode
, memsi_addr
);
8248 set_mem_alias_set (memsi
, ALIAS_SET_MEMORY_BARRIER
);
8249 MEM_VOLATILE_P (memsi
) = MEM_VOLATILE_P (mem
);
8251 /* Work out the byte offset of the QImode or HImode value,
8252 counting from the least significant byte. */
8253 shift
= mips_force_binary (Pmode
, AND
, orig_addr
, GEN_INT (3));
8254 if (TARGET_BIG_ENDIAN
)
8255 mips_emit_binary (XOR
, shift
, shift
, GEN_INT (mode
== QImode
? 3 : 2));
8257 /* Multiply by eight to convert the shift value from bytes to bits. */
8258 mips_emit_binary (ASHIFT
, shift
, shift
, GEN_INT (3));
8260 /* Make the final shift an SImode value, so that it can be used in
8261 SImode operations. */
8262 shiftsi
= force_reg (SImode
, gen_lowpart (SImode
, shift
));
8264 /* Set MASK to an inclusive mask of the QImode or HImode value. */
8265 unshifted_mask
= GEN_INT (GET_MODE_MASK (mode
));
8266 unshifted_mask_reg
= force_reg (SImode
, unshifted_mask
);
8267 mask
= mips_force_binary (SImode
, ASHIFT
, unshifted_mask_reg
, shiftsi
);
8269 /* Compute the equivalent exclusive mask. */
8270 inverted_mask
= gen_reg_rtx (SImode
);
8271 emit_insn (gen_rtx_SET (inverted_mask
, gen_rtx_NOT (SImode
, mask
)));
8273 /* Shift the old value into place. */
8274 if (oldval
!= const0_rtx
)
8276 oldval
= convert_modes (SImode
, mode
, oldval
, true);
8277 oldval
= force_reg (SImode
, oldval
);
8278 oldval
= mips_force_binary (SImode
, ASHIFT
, oldval
, shiftsi
);
8281 /* Do the same for the new value. */
8282 if (newval
&& newval
!= const0_rtx
)
8284 newval
= convert_modes (SImode
, mode
, newval
, true);
8285 newval
= force_reg (SImode
, newval
);
8286 newval
= mips_force_binary (SImode
, ASHIFT
, newval
, shiftsi
);
8289 /* Do the SImode atomic access. */
8291 res
= gen_reg_rtx (SImode
);
8293 si_op
= generator
.fn_6 (res
, memsi
, mask
, inverted_mask
, oldval
, newval
);
8295 si_op
= generator
.fn_5 (res
, memsi
, mask
, inverted_mask
, oldval
);
8297 si_op
= generator
.fn_4 (memsi
, mask
, inverted_mask
, oldval
);
8303 /* Shift and convert the result. */
8304 mips_emit_binary (AND
, res
, res
, mask
);
8305 mips_emit_binary (LSHIFTRT
, res
, res
, shiftsi
);
8306 mips_emit_move (result
, gen_lowpart (GET_MODE (result
), res
));
8310 /* Return true if it is possible to use left/right accesses for a
8311 bitfield of WIDTH bits starting BITPOS bits into BLKmode memory OP.
8312 When returning true, update *LEFT and *RIGHT as follows:
8314 *LEFT is a QImode reference to the first byte if big endian or
8315 the last byte if little endian. This address can be used in the
8316 left-side instructions (LWL, SWL, LDL, SDL).
8318 *RIGHT is a QImode reference to the opposite end of the field and
8319 can be used in the patterning right-side instruction. */
8322 mips_get_unaligned_mem (rtx op
, HOST_WIDE_INT width
, HOST_WIDE_INT bitpos
,
8323 rtx
*left
, rtx
*right
)
8327 /* Check that the size is valid. */
8328 if (width
!= 32 && (!TARGET_64BIT
|| width
!= 64))
8331 /* We can only access byte-aligned values. Since we are always passed
8332 a reference to the first byte of the field, it is not necessary to
8333 do anything with BITPOS after this check. */
8334 if (bitpos
% BITS_PER_UNIT
!= 0)
8337 /* Reject aligned bitfields: we want to use a normal load or store
8338 instead of a left/right pair. */
8339 if (MEM_ALIGN (op
) >= width
)
8342 /* Get references to both ends of the field. */
8343 first
= adjust_address (op
, QImode
, 0);
8344 last
= adjust_address (op
, QImode
, width
/ BITS_PER_UNIT
- 1);
8346 /* Allocate to LEFT and RIGHT according to endianness. LEFT should
8347 correspond to the MSB and RIGHT to the LSB. */
8348 if (TARGET_BIG_ENDIAN
)
8349 *left
= first
, *right
= last
;
8351 *left
= last
, *right
= first
;
8356 /* Try to use left/right loads to expand an "extv" or "extzv" pattern.
8357 DEST, SRC, WIDTH and BITPOS are the operands passed to the expander;
8358 the operation is the equivalent of:
8360 (set DEST (*_extract SRC WIDTH BITPOS))
8362 Return true on success. */
8365 mips_expand_ext_as_unaligned_load (rtx dest
, rtx src
, HOST_WIDE_INT width
,
8366 HOST_WIDE_INT bitpos
, bool unsigned_p
)
8368 rtx left
, right
, temp
;
8369 rtx dest1
= NULL_RTX
;
8371 /* If TARGET_64BIT, the destination of a 32-bit "extz" or "extzv" will
8372 be a DImode, create a new temp and emit a zero extend at the end. */
8373 if (GET_MODE (dest
) == DImode
8375 && GET_MODE_BITSIZE (SImode
) == width
)
8378 dest
= gen_reg_rtx (SImode
);
8381 if (!mips_get_unaligned_mem (src
, width
, bitpos
, &left
, &right
))
8384 temp
= gen_reg_rtx (GET_MODE (dest
));
8385 if (GET_MODE (dest
) == DImode
)
8387 emit_insn (gen_mov_ldl (temp
, src
, left
));
8388 emit_insn (gen_mov_ldr (dest
, copy_rtx (src
), right
, temp
));
8392 emit_insn (gen_mov_lwl (temp
, src
, left
));
8393 emit_insn (gen_mov_lwr (dest
, copy_rtx (src
), right
, temp
));
8396 /* If we were loading 32bits and the original register was DI then
8397 sign/zero extend into the orignal dest. */
8401 emit_insn (gen_zero_extendsidi2 (dest1
, dest
));
8403 emit_insn (gen_extendsidi2 (dest1
, dest
));
8408 /* Try to use left/right stores to expand an "ins" pattern. DEST, WIDTH,
8409 BITPOS and SRC are the operands passed to the expander; the operation
8410 is the equivalent of:
8412 (set (zero_extract DEST WIDTH BITPOS) SRC)
8414 Return true on success. */
8417 mips_expand_ins_as_unaligned_store (rtx dest
, rtx src
, HOST_WIDE_INT width
,
8418 HOST_WIDE_INT bitpos
)
8423 if (!mips_get_unaligned_mem (dest
, width
, bitpos
, &left
, &right
))
8426 mode
= int_mode_for_size (width
, 0).require ();
8427 src
= gen_lowpart (mode
, src
);
8430 emit_insn (gen_mov_sdl (dest
, src
, left
));
8431 emit_insn (gen_mov_sdr (copy_rtx (dest
), copy_rtx (src
), right
));
8435 emit_insn (gen_mov_swl (dest
, src
, left
));
8436 emit_insn (gen_mov_swr (copy_rtx (dest
), copy_rtx (src
), right
));
8441 /* Return true if X is a MEM with the same size as MODE. */
8444 mips_mem_fits_mode_p (machine_mode mode
, rtx x
)
8447 && MEM_SIZE_KNOWN_P (x
)
8448 && MEM_SIZE (x
) == GET_MODE_SIZE (mode
));
8451 /* Return true if (zero_extract OP WIDTH BITPOS) can be used as the
8452 source of an "ext" instruction or the destination of an "ins"
8453 instruction. OP must be a register operand and the following
8454 conditions must hold:
8456 0 <= BITPOS < GET_MODE_BITSIZE (GET_MODE (op))
8457 0 < WIDTH <= GET_MODE_BITSIZE (GET_MODE (op))
8458 0 < BITPOS + WIDTH <= GET_MODE_BITSIZE (GET_MODE (op))
8460 Also reject lengths equal to a word as they are better handled
8461 by the move patterns. */
8464 mips_use_ins_ext_p (rtx op
, HOST_WIDE_INT width
, HOST_WIDE_INT bitpos
)
8466 if (!ISA_HAS_EXT_INS
8467 || !register_operand (op
, VOIDmode
)
8468 || GET_MODE_BITSIZE (GET_MODE (op
)) > BITS_PER_WORD
)
8471 if (!IN_RANGE (width
, 1, GET_MODE_BITSIZE (GET_MODE (op
)) - 1))
8474 if (bitpos
< 0 || bitpos
+ width
> GET_MODE_BITSIZE (GET_MODE (op
)))
8480 /* Check if MASK and SHIFT are valid in mask-low-and-shift-left
8481 operation if MAXLEN is the maxium length of consecutive bits that
8482 can make up MASK. MODE is the mode of the operation. See
8483 mask_low_and_shift_len for the actual definition. */
8486 mask_low_and_shift_p (machine_mode mode
, rtx mask
, rtx shift
, int maxlen
)
8488 return IN_RANGE (mask_low_and_shift_len (mode
, mask
, shift
), 1, maxlen
);
8491 /* Return true iff OP1 and OP2 are valid operands together for the
8492 *and<MODE>3 and *and<MODE>3_mips16 patterns. For the cases to consider,
8493 see the table in the comment before the pattern. */
8496 and_operands_ok (machine_mode mode
, rtx op1
, rtx op2
)
8499 if (memory_operand (op1
, mode
))
8501 if (TARGET_MIPS16
) {
8502 struct mips_address_info addr
;
8503 if (!mips_classify_address (&addr
, op1
, mode
, false))
8506 return and_load_operand (op2
, mode
);
8509 return and_reg_operand (op2
, mode
);
8512 /* The canonical form of a mask-low-and-shift-left operation is
8513 (and (ashift X SHIFT) MASK) where MASK has the lower SHIFT number of bits
8514 cleared. Thus we need to shift MASK to the right before checking if it
8515 is a valid mask value. MODE is the mode of the operation. If true
8516 return the length of the mask, otherwise return -1. */
8519 mask_low_and_shift_len (machine_mode mode
, rtx mask
, rtx shift
)
8521 HOST_WIDE_INT shval
;
8523 shval
= INTVAL (shift
) & (GET_MODE_BITSIZE (mode
) - 1);
8524 return exact_log2 ((UINTVAL (mask
) >> shval
) + 1);
8527 /* Return true if -msplit-addresses is selected and should be honored.
8529 -msplit-addresses is a half-way house between explicit relocations
8530 and the traditional assembler macros. It can split absolute 32-bit
8531 symbolic constants into a high/lo_sum pair but uses macros for other
8534 Like explicit relocation support for REL targets, it relies
8535 on GNU extensions in the assembler and the linker.
8537 Although this code should work for -O0, it has traditionally
8538 been treated as an optimization. */
8541 mips_split_addresses_p (void)
8543 return (TARGET_SPLIT_ADDRESSES
8547 && !ABI_HAS_64BIT_SYMBOLS
);
8550 /* (Re-)Initialize mips_split_p, mips_lo_relocs and mips_hi_relocs. */
8553 mips_init_relocs (void)
8555 memset (mips_split_p
, '\0', sizeof (mips_split_p
));
8556 memset (mips_split_hi_p
, '\0', sizeof (mips_split_hi_p
));
8557 memset (mips_use_pcrel_pool_p
, '\0', sizeof (mips_use_pcrel_pool_p
));
8558 memset (mips_hi_relocs
, '\0', sizeof (mips_hi_relocs
));
8559 memset (mips_lo_relocs
, '\0', sizeof (mips_lo_relocs
));
8561 if (TARGET_MIPS16_PCREL_LOADS
)
8562 mips_use_pcrel_pool_p
[SYMBOL_ABSOLUTE
] = true;
8565 if (ABI_HAS_64BIT_SYMBOLS
)
8567 if (TARGET_EXPLICIT_RELOCS
)
8569 mips_split_p
[SYMBOL_64_HIGH
] = true;
8570 mips_hi_relocs
[SYMBOL_64_HIGH
] = "%highest(";
8571 mips_lo_relocs
[SYMBOL_64_HIGH
] = "%higher(";
8573 mips_split_p
[SYMBOL_64_MID
] = true;
8574 mips_hi_relocs
[SYMBOL_64_MID
] = "%higher(";
8575 mips_lo_relocs
[SYMBOL_64_MID
] = "%hi(";
8577 mips_split_p
[SYMBOL_64_LOW
] = true;
8578 mips_hi_relocs
[SYMBOL_64_LOW
] = "%hi(";
8579 mips_lo_relocs
[SYMBOL_64_LOW
] = "%lo(";
8581 mips_split_p
[SYMBOL_ABSOLUTE
] = true;
8582 mips_lo_relocs
[SYMBOL_ABSOLUTE
] = "%lo(";
8587 if (TARGET_EXPLICIT_RELOCS
8588 || mips_split_addresses_p ()
8591 mips_split_p
[SYMBOL_ABSOLUTE
] = true;
8592 mips_hi_relocs
[SYMBOL_ABSOLUTE
] = "%hi(";
8593 mips_lo_relocs
[SYMBOL_ABSOLUTE
] = "%lo(";
8600 /* The high part is provided by a pseudo copy of $gp. */
8601 mips_split_p
[SYMBOL_GP_RELATIVE
] = true;
8602 mips_lo_relocs
[SYMBOL_GP_RELATIVE
] = "%gprel(";
8604 else if (TARGET_EXPLICIT_RELOCS
)
8605 /* Small data constants are kept whole until after reload,
8606 then lowered by mips_rewrite_small_data. */
8607 mips_lo_relocs
[SYMBOL_GP_RELATIVE
] = "%gp_rel(";
8609 if (TARGET_EXPLICIT_RELOCS
)
8611 mips_split_p
[SYMBOL_GOT_PAGE_OFST
] = true;
8614 mips_lo_relocs
[SYMBOL_GOTOFF_PAGE
] = "%got_page(";
8615 mips_lo_relocs
[SYMBOL_GOT_PAGE_OFST
] = "%got_ofst(";
8619 mips_lo_relocs
[SYMBOL_GOTOFF_PAGE
] = "%got(";
8620 mips_lo_relocs
[SYMBOL_GOT_PAGE_OFST
] = "%lo(";
8623 /* Expose the use of $28 as soon as possible. */
8624 mips_split_hi_p
[SYMBOL_GOT_PAGE_OFST
] = true;
8628 /* The HIGH and LO_SUM are matched by special .md patterns. */
8629 mips_split_p
[SYMBOL_GOT_DISP
] = true;
8631 mips_split_p
[SYMBOL_GOTOFF_DISP
] = true;
8632 mips_hi_relocs
[SYMBOL_GOTOFF_DISP
] = "%got_hi(";
8633 mips_lo_relocs
[SYMBOL_GOTOFF_DISP
] = "%got_lo(";
8635 mips_split_p
[SYMBOL_GOTOFF_CALL
] = true;
8636 mips_hi_relocs
[SYMBOL_GOTOFF_CALL
] = "%call_hi(";
8637 mips_lo_relocs
[SYMBOL_GOTOFF_CALL
] = "%call_lo(";
8642 mips_lo_relocs
[SYMBOL_GOTOFF_DISP
] = "%got_disp(";
8644 mips_lo_relocs
[SYMBOL_GOTOFF_DISP
] = "%got(";
8645 mips_lo_relocs
[SYMBOL_GOTOFF_CALL
] = "%call16(";
8647 /* Expose the use of $28 as soon as possible. */
8648 mips_split_p
[SYMBOL_GOT_DISP
] = true;
8654 mips_split_p
[SYMBOL_GOTOFF_LOADGP
] = true;
8655 mips_hi_relocs
[SYMBOL_GOTOFF_LOADGP
] = "%hi(%neg(%gp_rel(";
8656 mips_lo_relocs
[SYMBOL_GOTOFF_LOADGP
] = "%lo(%neg(%gp_rel(";
8659 mips_lo_relocs
[SYMBOL_TLSGD
] = "%tlsgd(";
8660 mips_lo_relocs
[SYMBOL_TLSLDM
] = "%tlsldm(";
8662 if (TARGET_MIPS16_PCREL_LOADS
)
8664 mips_use_pcrel_pool_p
[SYMBOL_DTPREL
] = true;
8665 mips_use_pcrel_pool_p
[SYMBOL_TPREL
] = true;
8669 mips_split_p
[SYMBOL_DTPREL
] = true;
8670 mips_hi_relocs
[SYMBOL_DTPREL
] = "%dtprel_hi(";
8671 mips_lo_relocs
[SYMBOL_DTPREL
] = "%dtprel_lo(";
8673 mips_split_p
[SYMBOL_TPREL
] = true;
8674 mips_hi_relocs
[SYMBOL_TPREL
] = "%tprel_hi(";
8675 mips_lo_relocs
[SYMBOL_TPREL
] = "%tprel_lo(";
8678 mips_lo_relocs
[SYMBOL_GOTTPREL
] = "%gottprel(";
8679 mips_lo_relocs
[SYMBOL_HALF
] = "%half(";
8682 /* Print symbolic operand OP, which is part of a HIGH or LO_SUM
8683 in context CONTEXT. RELOCS is the array of relocations to use. */
8686 mips_print_operand_reloc (FILE *file
, rtx op
, enum mips_symbol_context context
,
8687 const char **relocs
)
8689 enum mips_symbol_type symbol_type
;
8692 symbol_type
= mips_classify_symbolic_expression (op
, context
);
8693 gcc_assert (relocs
[symbol_type
]);
8695 fputs (relocs
[symbol_type
], file
);
8696 output_addr_const (file
, mips_strip_unspec_address (op
));
8697 for (p
= relocs
[symbol_type
]; *p
!= 0; p
++)
8702 /* Start a new block with the given asm switch enabled. If we need
8703 to print a directive, emit PREFIX before it and SUFFIX after it. */
8706 mips_push_asm_switch_1 (struct mips_asm_switch
*asm_switch
,
8707 const char *prefix
, const char *suffix
)
8709 if (asm_switch
->nesting_level
== 0)
8710 fprintf (asm_out_file
, "%s.set\tno%s%s", prefix
, asm_switch
->name
, suffix
);
8711 asm_switch
->nesting_level
++;
8714 /* Likewise, but end a block. */
8717 mips_pop_asm_switch_1 (struct mips_asm_switch
*asm_switch
,
8718 const char *prefix
, const char *suffix
)
8720 gcc_assert (asm_switch
->nesting_level
);
8721 asm_switch
->nesting_level
--;
8722 if (asm_switch
->nesting_level
== 0)
8723 fprintf (asm_out_file
, "%s.set\t%s%s", prefix
, asm_switch
->name
, suffix
);
8726 /* Wrappers around mips_push_asm_switch_1 and mips_pop_asm_switch_1
8727 that either print a complete line or print nothing. */
8730 mips_push_asm_switch (struct mips_asm_switch
*asm_switch
)
8732 mips_push_asm_switch_1 (asm_switch
, "\t", "\n");
8736 mips_pop_asm_switch (struct mips_asm_switch
*asm_switch
)
8738 mips_pop_asm_switch_1 (asm_switch
, "\t", "\n");
8741 /* Print the text for PRINT_OPERAND punctation character CH to FILE.
8742 The punctuation characters are:
8744 '(' Start a nested ".set noreorder" block.
8745 ')' End a nested ".set noreorder" block.
8746 '[' Start a nested ".set noat" block.
8747 ']' End a nested ".set noat" block.
8748 '<' Start a nested ".set nomacro" block.
8749 '>' End a nested ".set nomacro" block.
8750 '*' Behave like %(%< if generating a delayed-branch sequence.
8751 '#' Print a nop if in a ".set noreorder" block.
8752 '/' Like '#', but do nothing within a delayed-branch sequence.
8753 '?' Print "l" if mips_branch_likely is true
8754 '~' Print a nop if mips_branch_likely is true
8755 '.' Print the name of the register with a hard-wired zero (zero or $0).
8756 '@' Print the name of the assembler temporary register (at or $1).
8757 '^' Print the name of the pic call-through register (t9 or $25).
8758 '+' Print the name of the gp register (usually gp or $28).
8759 '$' Print the name of the stack pointer register (sp or $29).
8760 ':' Print "c" to use the compact version if the delay slot is a nop.
8761 '!' Print "s" to use the short version if the delay slot contains a
8764 See also mips_init_print_operand_punct. */
8767 mips_print_operand_punctuation (FILE *file
, int ch
)
8772 mips_push_asm_switch_1 (&mips_noreorder
, "", "\n\t");
8776 mips_pop_asm_switch_1 (&mips_noreorder
, "\n\t", "");
8780 mips_push_asm_switch_1 (&mips_noat
, "", "\n\t");
8784 mips_pop_asm_switch_1 (&mips_noat
, "\n\t", "");
8788 mips_push_asm_switch_1 (&mips_nomacro
, "", "\n\t");
8792 mips_pop_asm_switch_1 (&mips_nomacro
, "\n\t", "");
8796 if (final_sequence
!= 0)
8798 mips_print_operand_punctuation (file
, '(');
8799 mips_print_operand_punctuation (file
, '<');
8804 if (mips_noreorder
.nesting_level
> 0)
8805 fputs ("\n\tnop", file
);
8809 /* Print an extra newline so that the delayed insn is separated
8810 from the following ones. This looks neater and is consistent
8811 with non-nop delayed sequences. */
8812 if (mips_noreorder
.nesting_level
> 0 && final_sequence
== 0)
8813 fputs ("\n\tnop\n", file
);
8817 if (mips_branch_likely
)
8822 if (mips_branch_likely
)
8823 fputs ("\n\tnop", file
);
8827 fputs (reg_names
[GP_REG_FIRST
+ 0], file
);
8831 fputs (reg_names
[AT_REGNUM
], file
);
8835 fputs (reg_names
[PIC_FUNCTION_ADDR_REGNUM
], file
);
8839 fputs (reg_names
[PIC_OFFSET_TABLE_REGNUM
], file
);
8843 fputs (reg_names
[STACK_POINTER_REGNUM
], file
);
8847 /* When final_sequence is 0, the delay slot will be a nop. We can
8848 use the compact version where available. The %: formatter will
8849 only be present if a compact form of the branch is available. */
8850 if (final_sequence
== 0)
8855 /* If the delay slot instruction is short, then use the
8857 if (TARGET_MICROMIPS
&& !TARGET_INTERLINK_COMPRESSED
&& mips_isa_rev
<= 5
8858 && (final_sequence
== 0
8859 || get_attr_length (final_sequence
->insn (1)) == 2))
8869 /* Initialize mips_print_operand_punct. */
8872 mips_init_print_operand_punct (void)
8876 for (p
= "()[]<>*#/?~.@^+$:!"; *p
; p
++)
8877 mips_print_operand_punct
[(unsigned char) *p
] = true;
8880 /* PRINT_OPERAND prefix LETTER refers to the integer branch instruction
8881 associated with condition CODE. Print the condition part of the
8885 mips_print_int_branch_condition (FILE *file
, enum rtx_code code
, int letter
)
8899 /* Conveniently, the MIPS names for these conditions are the same
8900 as their RTL equivalents. */
8901 fputs (GET_RTX_NAME (code
), file
);
8905 output_operand_lossage ("'%%%c' is not a valid operand prefix", letter
);
8910 /* Likewise floating-point branches. */
8913 mips_print_float_branch_condition (FILE *file
, enum rtx_code code
, int letter
)
8919 fputs ("c1eqz", file
);
8921 fputs ("c1f", file
);
8926 fputs ("c1nez", file
);
8928 fputs ("c1t", file
);
8932 output_operand_lossage ("'%%%c' is not a valid operand prefix", letter
);
8937 /* Implement TARGET_PRINT_OPERAND_PUNCT_VALID_P. */
8940 mips_print_operand_punct_valid_p (unsigned char code
)
8942 return mips_print_operand_punct
[code
];
8945 /* Implement TARGET_PRINT_OPERAND. The MIPS-specific operand codes are:
8947 'E' Print CONST_INT OP element 0 of a replicated CONST_VECTOR in decimal.
8948 'X' Print CONST_INT OP in hexadecimal format.
8949 'x' Print the low 16 bits of CONST_INT OP in hexadecimal format.
8950 'd' Print CONST_INT OP in decimal.
8951 'B' Print CONST_INT OP element 0 of a replicated CONST_VECTOR
8952 as an unsigned byte [0..255].
8953 'm' Print one less than CONST_INT OP in decimal.
8954 'y' Print exact log2 of CONST_INT OP in decimal.
8955 'h' Print the high-part relocation associated with OP, after stripping
8957 'R' Print the low-part relocation associated with OP.
8958 'C' Print the integer branch condition for comparison OP.
8959 'N' Print the inverse of the integer branch condition for comparison OP.
8960 'F' Print the FPU branch condition for comparison OP.
8961 'W' Print the inverse of the FPU branch condition for comparison OP.
8962 'w' Print a MSA register.
8963 'T' Print 'f' for (eq:CC ...), 't' for (ne:CC ...),
8964 'z' for (eq:?I ...), 'n' for (ne:?I ...).
8965 't' Like 'T', but with the EQ/NE cases reversed
8966 'Y' Print mips_fp_conditions[INTVAL (OP)]
8967 'Z' Print OP and a comma for ISA_HAS_8CC, otherwise print nothing.
8968 'q' Print a DSP accumulator register.
8969 'D' Print the second part of a double-word register or memory operand.
8970 'L' Print the low-order register in a double-word register operand.
8971 'M' Print high-order register in a double-word register operand.
8972 'z' Print $0 if OP is zero, otherwise print OP normally.
8973 'b' Print the address of a memory operand, without offset.
8974 'v' Print the insn size suffix b, h, w or d for vector modes V16QI, V8HI,
8975 V4SI, V2SI, and w, d for vector modes V4SF, V2DF respectively.
8976 'V' Print exact log2 of CONST_INT OP element 0 of a replicated
8977 CONST_VECTOR in decimal. */
8980 mips_print_operand (FILE *file
, rtx op
, int letter
)
8984 if (mips_print_operand_punct_valid_p (letter
))
8986 mips_print_operand_punctuation (file
, letter
);
8991 code
= GET_CODE (op
);
8996 if (GET_CODE (op
) == CONST_VECTOR
)
8998 gcc_assert (mips_const_vector_same_val_p (op
, GET_MODE (op
)));
8999 op
= CONST_VECTOR_ELT (op
, 0);
9000 gcc_assert (CONST_INT_P (op
));
9001 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (op
));
9004 output_operand_lossage ("invalid use of '%%%c'", letter
);
9008 if (CONST_INT_P (op
))
9009 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, INTVAL (op
));
9011 output_operand_lossage ("invalid use of '%%%c'", letter
);
9015 if (CONST_INT_P (op
))
9016 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, INTVAL (op
) & 0xffff);
9018 output_operand_lossage ("invalid use of '%%%c'", letter
);
9022 if (CONST_INT_P (op
))
9023 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (op
));
9025 output_operand_lossage ("invalid use of '%%%c'", letter
);
9029 if (GET_CODE (op
) == CONST_VECTOR
)
9031 gcc_assert (mips_const_vector_same_val_p (op
, GET_MODE (op
)));
9032 op
= CONST_VECTOR_ELT (op
, 0);
9033 gcc_assert (CONST_INT_P (op
));
9034 unsigned HOST_WIDE_INT val8
= UINTVAL (op
) & GET_MODE_MASK (QImode
);
9035 fprintf (file
, HOST_WIDE_INT_PRINT_UNSIGNED
, val8
);
9038 output_operand_lossage ("invalid use of '%%%c'", letter
);
9042 if (CONST_INT_P (op
))
9043 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (op
) - 1);
9045 output_operand_lossage ("invalid use of '%%%c'", letter
);
9049 if (CONST_INT_P (op
))
9051 int val
= exact_log2 (INTVAL (op
));
9053 fprintf (file
, "%d", val
);
9055 output_operand_lossage ("invalid use of '%%%c'", letter
);
9058 output_operand_lossage ("invalid use of '%%%c'", letter
);
9062 if (GET_CODE (op
) == CONST_VECTOR
)
9064 machine_mode mode
= GET_MODE_INNER (GET_MODE (op
));
9065 unsigned HOST_WIDE_INT val
= UINTVAL (CONST_VECTOR_ELT (op
, 0));
9066 int vlog2
= exact_log2 (val
& GET_MODE_MASK (mode
));
9068 fprintf (file
, "%d", vlog2
);
9070 output_operand_lossage ("invalid use of '%%%c'", letter
);
9073 output_operand_lossage ("invalid use of '%%%c'", letter
);
9079 mips_print_operand_reloc (file
, op
, SYMBOL_CONTEXT_LEA
, mips_hi_relocs
);
9083 mips_print_operand_reloc (file
, op
, SYMBOL_CONTEXT_LEA
, mips_lo_relocs
);
9087 mips_print_int_branch_condition (file
, code
, letter
);
9091 mips_print_int_branch_condition (file
, reverse_condition (code
), letter
);
9095 mips_print_float_branch_condition (file
, code
, letter
);
9099 mips_print_float_branch_condition (file
, reverse_condition (code
),
9106 int truth
= (code
== NE
) == (letter
== 'T');
9107 fputc ("zfnt"[truth
* 2 + ST_REG_P (REGNO (XEXP (op
, 0)))], file
);
9112 if (code
== CONST_INT
&& UINTVAL (op
) < ARRAY_SIZE (mips_fp_conditions
))
9113 fputs (mips_fp_conditions
[UINTVAL (op
)], file
);
9115 output_operand_lossage ("'%%%c' is not a valid operand prefix",
9120 if (ISA_HAS_8CC
|| ISA_HAS_CCF
)
9122 mips_print_operand (file
, op
, 0);
9128 if (code
== REG
&& MD_REG_P (REGNO (op
)))
9129 fprintf (file
, "$ac0");
9130 else if (code
== REG
&& DSP_ACC_REG_P (REGNO (op
)))
9131 fprintf (file
, "$ac%c", reg_names
[REGNO (op
)][3]);
9133 output_operand_lossage ("invalid use of '%%%c'", letter
);
9137 if (code
== REG
&& MSA_REG_P (REGNO (op
)))
9138 fprintf (file
, "$w%s", ®_names
[REGNO (op
)][2]);
9140 output_operand_lossage ("invalid use of '%%%c'", letter
);
9144 switch (GET_MODE (op
))
9147 fprintf (file
, "b");
9150 fprintf (file
, "h");
9154 fprintf (file
, "w");
9158 fprintf (file
, "d");
9161 output_operand_lossage ("invalid use of '%%%c'", letter
);
9170 unsigned int regno
= REGNO (op
);
9171 if ((letter
== 'M' && TARGET_LITTLE_ENDIAN
)
9172 || (letter
== 'L' && TARGET_BIG_ENDIAN
)
9175 else if (letter
&& letter
!= 'z' && letter
!= 'M' && letter
!= 'L')
9176 output_operand_lossage ("invalid use of '%%%c'", letter
);
9177 /* We need to print $0 .. $31 for COP0 registers. */
9178 if (COP0_REG_P (regno
))
9179 fprintf (file
, "$%s", ®_names
[regno
][4]);
9181 fprintf (file
, "%s", reg_names
[regno
]);
9187 output_address (GET_MODE (op
), plus_constant (Pmode
,
9189 else if (letter
== 'b')
9191 gcc_assert (REG_P (XEXP (op
, 0)));
9192 mips_print_operand (file
, XEXP (op
, 0), 0);
9194 else if (letter
&& letter
!= 'z')
9195 output_operand_lossage ("invalid use of '%%%c'", letter
);
9197 output_address (GET_MODE (op
), XEXP (op
, 0));
9201 if (letter
== 'z' && op
== CONST0_RTX (GET_MODE (op
)))
9202 fputs (reg_names
[GP_REG_FIRST
], file
);
9203 else if (letter
&& letter
!= 'z')
9204 output_operand_lossage ("invalid use of '%%%c'", letter
);
9205 else if (CONST_GP_P (op
))
9206 fputs (reg_names
[GLOBAL_POINTER_REGNUM
], file
);
9208 output_addr_const (file
, mips_strip_unspec_address (op
));
9214 /* Implement TARGET_PRINT_OPERAND_ADDRESS. */
9217 mips_print_operand_address (FILE *file
, machine_mode
/*mode*/, rtx x
)
9219 struct mips_address_info addr
;
9221 if (mips_classify_address (&addr
, x
, word_mode
, true))
9225 mips_print_operand (file
, addr
.offset
, 0);
9226 fprintf (file
, "(%s)", reg_names
[REGNO (addr
.reg
)]);
9229 case ADDRESS_LO_SUM
:
9230 mips_print_operand_reloc (file
, addr
.offset
, SYMBOL_CONTEXT_MEM
,
9232 fprintf (file
, "(%s)", reg_names
[REGNO (addr
.reg
)]);
9235 case ADDRESS_CONST_INT
:
9236 output_addr_const (file
, x
);
9237 fprintf (file
, "(%s)", reg_names
[GP_REG_FIRST
]);
9240 case ADDRESS_SYMBOLIC
:
9241 output_addr_const (file
, mips_strip_unspec_address (x
));
9247 /* Implement TARGET_ENCODE_SECTION_INFO. */
9250 mips_encode_section_info (tree decl
, rtx rtl
, int first
)
9252 default_encode_section_info (decl
, rtl
, first
);
9254 if (TREE_CODE (decl
) == FUNCTION_DECL
)
9256 rtx symbol
= XEXP (rtl
, 0);
9257 tree type
= TREE_TYPE (decl
);
9259 /* Encode whether the symbol is short or long. */
9260 if ((TARGET_LONG_CALLS
&& !mips_near_type_p (type
))
9261 || mips_far_type_p (type
))
9262 SYMBOL_REF_FLAGS (symbol
) |= SYMBOL_FLAG_LONG_CALL
;
9266 /* Implement TARGET_SELECT_RTX_SECTION. */
9269 mips_select_rtx_section (machine_mode mode
, rtx x
,
9270 unsigned HOST_WIDE_INT align
)
9272 /* ??? Consider using mergeable small data sections. */
9273 if (mips_rtx_constant_in_small_data_p (mode
))
9274 return get_named_section (NULL
, ".sdata", 0);
9276 return default_elf_select_rtx_section (mode
, x
, align
);
9279 /* Implement TARGET_ASM_FUNCTION_RODATA_SECTION.
9281 The complication here is that, with the combination TARGET_ABICALLS
9282 && !TARGET_ABSOLUTE_ABICALLS && !TARGET_GPWORD, jump tables will use
9283 absolute addresses, and should therefore not be included in the
9284 read-only part of a DSO. Handle such cases by selecting a normal
9285 data section instead of a read-only one. The logic apes that in
9286 default_function_rodata_section. */
9289 mips_function_rodata_section (tree decl
)
9291 if (!TARGET_ABICALLS
|| TARGET_ABSOLUTE_ABICALLS
|| TARGET_GPWORD
)
9292 return default_function_rodata_section (decl
);
9294 if (decl
&& DECL_SECTION_NAME (decl
))
9296 const char *name
= DECL_SECTION_NAME (decl
);
9297 if (DECL_COMDAT_GROUP (decl
) && strncmp (name
, ".gnu.linkonce.t.", 16) == 0)
9299 char *rname
= ASTRDUP (name
);
9301 return get_section (rname
, SECTION_LINKONCE
| SECTION_WRITE
, decl
);
9303 else if (flag_function_sections
9304 && flag_data_sections
9305 && strncmp (name
, ".text.", 6) == 0)
9307 char *rname
= ASTRDUP (name
);
9308 memcpy (rname
+ 1, "data", 4);
9309 return get_section (rname
, SECTION_WRITE
, decl
);
9312 return data_section
;
9315 /* Implement TARGET_IN_SMALL_DATA_P. */
9318 mips_in_small_data_p (const_tree decl
)
9320 unsigned HOST_WIDE_INT size
;
9322 if (TREE_CODE (decl
) == STRING_CST
|| TREE_CODE (decl
) == FUNCTION_DECL
)
9325 /* We don't yet generate small-data references for -mabicalls
9326 or VxWorks RTP code. See the related -G handling in
9327 mips_option_override. */
9328 if (TARGET_ABICALLS
|| TARGET_VXWORKS_RTP
)
9331 if (TREE_CODE (decl
) == VAR_DECL
&& DECL_SECTION_NAME (decl
) != 0)
9335 /* Reject anything that isn't in a known small-data section. */
9336 name
= DECL_SECTION_NAME (decl
);
9337 if (strcmp (name
, ".sdata") != 0 && strcmp (name
, ".sbss") != 0)
9340 /* If a symbol is defined externally, the assembler will use the
9341 usual -G rules when deciding how to implement macros. */
9342 if (mips_lo_relocs
[SYMBOL_GP_RELATIVE
] || !DECL_EXTERNAL (decl
))
9345 else if (TARGET_EMBEDDED_DATA
)
9347 /* Don't put constants into the small data section: we want them
9348 to be in ROM rather than RAM. */
9349 if (TREE_CODE (decl
) != VAR_DECL
)
9352 if (TREE_READONLY (decl
)
9353 && !TREE_SIDE_EFFECTS (decl
)
9354 && (!DECL_INITIAL (decl
) || TREE_CONSTANT (DECL_INITIAL (decl
))))
9358 /* Enforce -mlocal-sdata. */
9359 if (!TARGET_LOCAL_SDATA
&& !TREE_PUBLIC (decl
))
9362 /* Enforce -mextern-sdata. */
9363 if (!TARGET_EXTERN_SDATA
&& DECL_P (decl
))
9365 if (DECL_EXTERNAL (decl
))
9367 if (DECL_COMMON (decl
) && DECL_INITIAL (decl
) == NULL
)
9371 /* We have traditionally not treated zero-sized objects as small data,
9372 so this is now effectively part of the ABI. */
9373 size
= int_size_in_bytes (TREE_TYPE (decl
));
9374 return size
> 0 && size
<= mips_small_data_threshold
;
9377 /* Implement TARGET_USE_ANCHORS_FOR_SYMBOL_P. We don't want to use
9378 anchors for small data: the GP register acts as an anchor in that
9379 case. We also don't want to use them for PC-relative accesses,
9380 where the PC acts as an anchor. */
9383 mips_use_anchors_for_symbol_p (const_rtx symbol
)
9385 switch (mips_classify_symbol (symbol
, SYMBOL_CONTEXT_MEM
))
9387 case SYMBOL_PC_RELATIVE
:
9388 case SYMBOL_GP_RELATIVE
:
9392 return default_use_anchors_for_symbol_p (symbol
);
9396 /* The MIPS debug format wants all automatic variables and arguments
9397 to be in terms of the virtual frame pointer (stack pointer before
9398 any adjustment in the function), while the MIPS 3.0 linker wants
9399 the frame pointer to be the stack pointer after the initial
9400 adjustment. So, we do the adjustment here. The arg pointer (which
9401 is eliminated) points to the virtual frame pointer, while the frame
9402 pointer (which may be eliminated) points to the stack pointer after
9403 the initial adjustments. */
9406 mips_debugger_offset (rtx addr
, HOST_WIDE_INT offset
)
9408 rtx offset2
= const0_rtx
;
9409 rtx reg
= eliminate_constant_term (addr
, &offset2
);
9412 offset
= INTVAL (offset2
);
9414 if (reg
== stack_pointer_rtx
9415 || reg
== frame_pointer_rtx
9416 || reg
== hard_frame_pointer_rtx
)
9418 offset
-= cfun
->machine
->frame
.total_size
;
9419 if (reg
== hard_frame_pointer_rtx
)
9420 offset
+= cfun
->machine
->frame
.hard_frame_pointer_offset
;
9426 /* Implement ASM_OUTPUT_EXTERNAL. */
9429 mips_output_external (FILE *file
, tree decl
, const char *name
)
9431 default_elf_asm_output_external (file
, decl
, name
);
9433 /* We output the name if and only if TREE_SYMBOL_REFERENCED is
9434 set in order to avoid putting out names that are never really
9436 if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl
)))
9438 if (!TARGET_EXPLICIT_RELOCS
&& mips_in_small_data_p (decl
))
9440 /* When using assembler macros, emit .extern directives for
9441 all small-data externs so that the assembler knows how
9444 In most cases it would be safe (though pointless) to emit
9445 .externs for other symbols too. One exception is when an
9446 object is within the -G limit but declared by the user to
9447 be in a section other than .sbss or .sdata. */
9448 fputs ("\t.extern\t", file
);
9449 assemble_name (file
, name
);
9450 fprintf (file
, ", " HOST_WIDE_INT_PRINT_DEC
"\n",
9451 int_size_in_bytes (TREE_TYPE (decl
)));
9456 /* Implement TARGET_ASM_OUTPUT_SOURCE_FILENAME. */
9459 mips_output_filename (FILE *stream
, const char *name
)
9461 /* If we are emitting DWARF-2, let dwarf2out handle the ".file"
9463 if (write_symbols
== DWARF2_DEBUG
)
9465 else if (mips_output_filename_first_time
)
9467 mips_output_filename_first_time
= 0;
9468 num_source_filenames
+= 1;
9469 current_function_file
= name
;
9470 fprintf (stream
, "\t.file\t%d ", num_source_filenames
);
9471 output_quoted_string (stream
, name
);
9472 putc ('\n', stream
);
9474 /* If we are emitting stabs, let dbxout.c handle this (except for
9475 the mips_output_filename_first_time case). */
9476 else if (write_symbols
== DBX_DEBUG
)
9478 else if (name
!= current_function_file
9479 && strcmp (name
, current_function_file
) != 0)
9481 num_source_filenames
+= 1;
9482 current_function_file
= name
;
9483 fprintf (stream
, "\t.file\t%d ", num_source_filenames
);
9484 output_quoted_string (stream
, name
);
9485 putc ('\n', stream
);
9489 /* Implement TARGET_ASM_OUTPUT_DWARF_DTPREL. */
9491 static void ATTRIBUTE_UNUSED
9492 mips_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
9497 fputs ("\t.dtprelword\t", file
);
9501 fputs ("\t.dtpreldword\t", file
);
9507 output_addr_const (file
, x
);
9508 fputs ("+0x8000", file
);
9511 /* Implement TARGET_DWARF_REGISTER_SPAN. */
9514 mips_dwarf_register_span (rtx reg
)
9519 /* TARGET_FLOATXX is implemented as 32-bit floating-point registers but
9520 ensures that double-precision registers are treated as if they were
9521 64-bit physical registers. The code will run correctly with 32-bit or
9522 64-bit registers which means that dwarf information cannot be precise
9523 for all scenarios. We choose to state that the 64-bit values are stored
9524 in a single 64-bit 'piece'. This slightly unusual construct can then be
9525 interpreted as either a pair of registers if the registers are 32-bit or
9526 a single 64-bit register depending on hardware. */
9527 mode
= GET_MODE (reg
);
9528 if (FP_REG_P (REGNO (reg
))
9530 && GET_MODE_SIZE (mode
) > UNITS_PER_FPREG
)
9532 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (1, reg
));
9534 /* By default, GCC maps increasing register numbers to increasing
9535 memory locations, but paired FPRs are always little-endian,
9536 regardless of the prevailing endianness. */
9537 else if (FP_REG_P (REGNO (reg
))
9538 && TARGET_BIG_ENDIAN
9539 && MAX_FPRS_PER_FMT
> 1
9540 && GET_MODE_SIZE (mode
) > UNITS_PER_FPREG
)
9542 gcc_assert (GET_MODE_SIZE (mode
) == UNITS_PER_HWFPVALUE
);
9543 high
= mips_subword (reg
, true);
9544 low
= mips_subword (reg
, false);
9545 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, high
, low
));
9551 /* Implement TARGET_DWARF_FRAME_REG_MODE. */
9554 mips_dwarf_frame_reg_mode (int regno
)
9556 machine_mode mode
= default_dwarf_frame_reg_mode (regno
);
9558 if (FP_REG_P (regno
) && mips_abi
== ABI_32
&& TARGET_FLOAT64
)
9564 /* DSP ALU can bypass data with no delays for the following pairs. */
9565 enum insn_code dspalu_bypass_table
[][2] =
9567 {CODE_FOR_mips_addsc
, CODE_FOR_mips_addwc
},
9568 {CODE_FOR_mips_cmpu_eq_qb
, CODE_FOR_mips_pick_qb
},
9569 {CODE_FOR_mips_cmpu_lt_qb
, CODE_FOR_mips_pick_qb
},
9570 {CODE_FOR_mips_cmpu_le_qb
, CODE_FOR_mips_pick_qb
},
9571 {CODE_FOR_mips_cmp_eq_ph
, CODE_FOR_mips_pick_ph
},
9572 {CODE_FOR_mips_cmp_lt_ph
, CODE_FOR_mips_pick_ph
},
9573 {CODE_FOR_mips_cmp_le_ph
, CODE_FOR_mips_pick_ph
},
9574 {CODE_FOR_mips_wrdsp
, CODE_FOR_mips_insv
}
9578 mips_dspalu_bypass_p (rtx out_insn
, rtx in_insn
)
9581 int num_bypass
= ARRAY_SIZE (dspalu_bypass_table
);
9582 enum insn_code out_icode
= (enum insn_code
) INSN_CODE (out_insn
);
9583 enum insn_code in_icode
= (enum insn_code
) INSN_CODE (in_insn
);
9585 for (i
= 0; i
< num_bypass
; i
++)
9587 if (out_icode
== dspalu_bypass_table
[i
][0]
9588 && in_icode
== dspalu_bypass_table
[i
][1])
9594 /* Implement ASM_OUTPUT_ASCII. */
9597 mips_output_ascii (FILE *stream
, const char *string
, size_t len
)
9603 fprintf (stream
, "\t.ascii\t\"");
9604 for (i
= 0; i
< len
; i
++)
9608 c
= (unsigned char) string
[i
];
9611 if (c
== '\\' || c
== '\"')
9613 putc ('\\', stream
);
9621 fprintf (stream
, "\\%03o", c
);
9625 if (cur_pos
> 72 && i
+1 < len
)
9628 fprintf (stream
, "\"\n\t.ascii\t\"");
9631 fprintf (stream
, "\"\n");
9634 /* Return the pseudo-op for full SYMBOL_(D)TPREL address *ADDR.
9635 Update *ADDR with the operand that should be printed. */
9638 mips_output_tls_reloc_directive (rtx
*addr
)
9640 enum mips_symbol_type type
;
9642 type
= mips_classify_symbolic_expression (*addr
, SYMBOL_CONTEXT_LEA
);
9643 *addr
= mips_strip_unspec_address (*addr
);
9647 return Pmode
== SImode
? ".dtprelword\t%0" : ".dtpreldword\t%0";
9650 return Pmode
== SImode
? ".tprelword\t%0" : ".tpreldword\t%0";
9657 /* Emit either a label, .comm, or .lcomm directive. When using assembler
9658 macros, mark the symbol as written so that mips_asm_output_external
9659 won't emit an .extern for it. STREAM is the output file, NAME is the
9660 name of the symbol, INIT_STRING is the string that should be written
9661 before the symbol and FINAL_STRING is the string that should be
9662 written after it. FINAL_STRING is a printf format that consumes the
9663 remaining arguments. */
9666 mips_declare_object (FILE *stream
, const char *name
, const char *init_string
,
9667 const char *final_string
, ...)
9671 fputs (init_string
, stream
);
9672 assemble_name (stream
, name
);
9673 va_start (ap
, final_string
);
9674 vfprintf (stream
, final_string
, ap
);
9677 if (!TARGET_EXPLICIT_RELOCS
)
9679 tree name_tree
= get_identifier (name
);
9680 TREE_ASM_WRITTEN (name_tree
) = 1;
9684 /* Declare a common object of SIZE bytes using asm directive INIT_STRING.
9685 NAME is the name of the object and ALIGN is the required alignment
9686 in bytes. TAKES_ALIGNMENT_P is true if the directive takes a third
9687 alignment argument. */
9690 mips_declare_common_object (FILE *stream
, const char *name
,
9691 const char *init_string
,
9692 unsigned HOST_WIDE_INT size
,
9693 unsigned int align
, bool takes_alignment_p
)
9695 if (!takes_alignment_p
)
9697 size
+= (align
/ BITS_PER_UNIT
) - 1;
9698 size
-= size
% (align
/ BITS_PER_UNIT
);
9699 mips_declare_object (stream
, name
, init_string
,
9700 "," HOST_WIDE_INT_PRINT_UNSIGNED
"\n", size
);
9703 mips_declare_object (stream
, name
, init_string
,
9704 "," HOST_WIDE_INT_PRINT_UNSIGNED
",%u\n",
9705 size
, align
/ BITS_PER_UNIT
);
9708 /* Implement ASM_OUTPUT_ALIGNED_DECL_COMMON. This is usually the same as the
9709 elfos.h version, but we also need to handle -muninit-const-in-rodata. */
9712 mips_output_aligned_decl_common (FILE *stream
, tree decl
, const char *name
,
9713 unsigned HOST_WIDE_INT size
,
9716 /* If the target wants uninitialized const declarations in
9717 .rdata then don't put them in .comm. */
9718 if (TARGET_EMBEDDED_DATA
9719 && TARGET_UNINIT_CONST_IN_RODATA
9720 && TREE_CODE (decl
) == VAR_DECL
9721 && TREE_READONLY (decl
)
9722 && (DECL_INITIAL (decl
) == 0 || DECL_INITIAL (decl
) == error_mark_node
))
9724 if (TREE_PUBLIC (decl
) && DECL_NAME (decl
))
9725 targetm
.asm_out
.globalize_label (stream
, name
);
9727 switch_to_section (readonly_data_section
);
9728 ASM_OUTPUT_ALIGN (stream
, floor_log2 (align
/ BITS_PER_UNIT
));
9729 mips_declare_object (stream
, name
, "",
9730 ":\n\t.space\t" HOST_WIDE_INT_PRINT_UNSIGNED
"\n",
9734 mips_declare_common_object (stream
, name
, "\n\t.comm\t",
9738 #ifdef ASM_OUTPUT_SIZE_DIRECTIVE
9739 extern int size_directive_output
;
9741 /* Implement ASM_DECLARE_OBJECT_NAME. This is like most of the standard ELF
9742 definitions except that it uses mips_declare_object to emit the label. */
9745 mips_declare_object_name (FILE *stream
, const char *name
,
9746 tree decl ATTRIBUTE_UNUSED
)
9748 #ifdef ASM_OUTPUT_TYPE_DIRECTIVE
9749 ASM_OUTPUT_TYPE_DIRECTIVE (stream
, name
, "object");
9752 size_directive_output
= 0;
9753 if (!flag_inhibit_size_directive
&& DECL_SIZE (decl
))
9757 size_directive_output
= 1;
9758 size
= int_size_in_bytes (TREE_TYPE (decl
));
9759 ASM_OUTPUT_SIZE_DIRECTIVE (stream
, name
, size
);
9762 mips_declare_object (stream
, name
, "", ":\n");
9765 /* Implement ASM_FINISH_DECLARE_OBJECT. This is generic ELF stuff. */
9768 mips_finish_declare_object (FILE *stream
, tree decl
, int top_level
, int at_end
)
9772 name
= XSTR (XEXP (DECL_RTL (decl
), 0), 0);
9773 if (!flag_inhibit_size_directive
9774 && DECL_SIZE (decl
) != 0
9777 && DECL_INITIAL (decl
) == error_mark_node
9778 && !size_directive_output
)
9782 size_directive_output
= 1;
9783 size
= int_size_in_bytes (TREE_TYPE (decl
));
9784 ASM_OUTPUT_SIZE_DIRECTIVE (stream
, name
, size
);
9789 /* Mark text contents as code or data, mainly for the purpose of correct
9790 disassembly. Emit a local symbol and set its type appropriately for
9791 that purpose. Also emit `.insn' if marking contents as code so that
9792 the ISA mode is recorded and any padding that follows is disassembled
9793 as correct instructions. */
9796 mips_set_text_contents_type (FILE *file ATTRIBUTE_UNUSED
,
9797 const char *prefix ATTRIBUTE_UNUSED
,
9798 unsigned long num ATTRIBUTE_UNUSED
,
9799 bool function_p ATTRIBUTE_UNUSED
)
9801 #ifdef ASM_OUTPUT_TYPE_DIRECTIVE
9802 char buf
[(sizeof (num
) * 10) / 4 + 2];
9807 sprintf (buf
, "%lu", num
);
9808 symbol
= XEXP (DECL_RTL (current_function_decl
), 0);
9809 fnname
= targetm
.strip_name_encoding (XSTR (symbol
, 0));
9810 sname
= ACONCAT ((prefix
, fnname
, "_", buf
, NULL
));
9812 ASM_OUTPUT_TYPE_DIRECTIVE (file
, sname
, function_p
? "function" : "object");
9813 assemble_name (file
, sname
);
9814 fputs (":\n", file
);
9816 fputs ("\t.insn\n", file
);
9820 /* Return the FOO in the name of the ".mdebug.FOO" section associated
9821 with the current ABI. */
9824 mips_mdebug_abi_name (void)
9837 return TARGET_64BIT
? "eabi64" : "eabi32";
9843 /* Implement TARGET_ASM_FILE_START. */
9846 mips_file_start (void)
9848 default_file_start ();
9850 /* Generate a special section to describe the ABI switches used to
9851 produce the resultant binary. */
9853 /* Record the ABI itself. Modern versions of binutils encode
9854 this information in the ELF header flags, but GDB needs the
9855 information in order to correctly debug binaries produced by
9856 older binutils. See the function mips_gdbarch_init in
9858 fprintf (asm_out_file
, "\t.section .mdebug.%s\n\t.previous\n",
9859 mips_mdebug_abi_name ());
9861 /* There is no ELF header flag to distinguish long32 forms of the
9862 EABI from long64 forms. Emit a special section to help tools
9863 such as GDB. Do the same for o64, which is sometimes used with
9865 if (mips_abi
== ABI_EABI
|| mips_abi
== ABI_O64
)
9866 fprintf (asm_out_file
, "\t.section .gcc_compiled_long%d\n"
9867 "\t.previous\n", TARGET_LONG64
? 64 : 32);
9869 /* Record the NaN encoding. */
9870 if (HAVE_AS_NAN
|| mips_nan
!= MIPS_IEEE_754_DEFAULT
)
9871 fprintf (asm_out_file
, "\t.nan\t%s\n",
9872 mips_nan
== MIPS_IEEE_754_2008
? "2008" : "legacy");
9874 #ifdef HAVE_AS_DOT_MODULE
9875 /* Record the FP ABI. See below for comments. */
9876 if (TARGET_NO_FLOAT
)
9877 #ifdef HAVE_AS_GNU_ATTRIBUTE
9878 fputs ("\t.gnu_attribute 4, 0\n", asm_out_file
);
9882 else if (!TARGET_HARD_FLOAT_ABI
)
9883 fputs ("\t.module\tsoftfloat\n", asm_out_file
);
9884 else if (!TARGET_DOUBLE_FLOAT
)
9885 fputs ("\t.module\tsinglefloat\n", asm_out_file
);
9886 else if (TARGET_FLOATXX
)
9887 fputs ("\t.module\tfp=xx\n", asm_out_file
);
9888 else if (TARGET_FLOAT64
)
9889 fputs ("\t.module\tfp=64\n", asm_out_file
);
9891 fputs ("\t.module\tfp=32\n", asm_out_file
);
9893 if (TARGET_ODD_SPREG
)
9894 fputs ("\t.module\toddspreg\n", asm_out_file
);
9896 fputs ("\t.module\tnooddspreg\n", asm_out_file
);
9899 #ifdef HAVE_AS_GNU_ATTRIBUTE
9903 /* No floating-point operations, -mno-float. */
9904 if (TARGET_NO_FLOAT
)
9906 /* Soft-float code, -msoft-float. */
9907 else if (!TARGET_HARD_FLOAT_ABI
)
9909 /* Single-float code, -msingle-float. */
9910 else if (!TARGET_DOUBLE_FLOAT
)
9912 /* 64-bit FP registers on a 32-bit target, -mips32r2 -mfp64.
9914 This case used 12 callee-saved double-precision registers
9915 and is deprecated. */
9916 /* 64-bit or 32-bit FP registers on a 32-bit target, -mfpxx. */
9917 else if (TARGET_FLOATXX
)
9919 /* 64-bit FP registers on a 32-bit target, -mfp64 -modd-spreg. */
9920 else if (mips_abi
== ABI_32
&& TARGET_FLOAT64
&& TARGET_ODD_SPREG
)
9922 /* 64-bit FP registers on a 32-bit target, -mfp64 -mno-odd-spreg. */
9923 else if (mips_abi
== ABI_32
&& TARGET_FLOAT64
)
9925 /* Regular FP code, FP regs same size as GP regs, -mdouble-float. */
9929 fprintf (asm_out_file
, "\t.gnu_attribute 4, %d\n", attr
);
9933 fprintf (asm_out_file
, "\t.gnu_attribute 8, 1\n");
9938 /* If TARGET_ABICALLS, tell GAS to generate -KPIC code. */
9939 if (TARGET_ABICALLS
)
9941 fprintf (asm_out_file
, "\t.abicalls\n");
9942 if (TARGET_ABICALLS_PIC0
)
9943 fprintf (asm_out_file
, "\t.option\tpic0\n");
9946 if (flag_verbose_asm
)
9947 fprintf (asm_out_file
, "\n%s -G value = %d, Arch = %s, ISA = %d\n",
9949 mips_small_data_threshold
, mips_arch_info
->name
, mips_isa
);
9952 /* Implement TARGET_ASM_CODE_END. */
9955 mips_code_end (void)
9957 mips_finish_stub (&mips16_rdhwr_stub
);
9958 mips_finish_stub (&mips16_get_fcsr_stub
);
9959 mips_finish_stub (&mips16_set_fcsr_stub
);
9962 /* Make the last instruction frame-related and note that it performs
9963 the operation described by FRAME_PATTERN. */
9966 mips_set_frame_expr (rtx frame_pattern
)
9970 insn
= get_last_insn ();
9971 RTX_FRAME_RELATED_P (insn
) = 1;
9972 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
9977 /* Return a frame-related rtx that stores REG at MEM.
9978 REG must be a single register. */
9981 mips_frame_set (rtx mem
, rtx reg
)
9985 set
= gen_rtx_SET (mem
, reg
);
9986 RTX_FRAME_RELATED_P (set
) = 1;
9991 /* Record that the epilogue has restored call-saved register REG. */
9994 mips_add_cfa_restore (rtx reg
)
9996 mips_epilogue
.cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
9997 mips_epilogue
.cfa_restores
);
10000 /* If a MIPS16e SAVE or RESTORE instruction saves or restores register
10001 mips16e_s2_s8_regs[X], it must also save the registers in indexes
10002 X + 1 onwards. Likewise mips16e_a0_a3_regs. */
10003 static const unsigned char mips16e_s2_s8_regs
[] = {
10004 30, 23, 22, 21, 20, 19, 18
10006 static const unsigned char mips16e_a0_a3_regs
[] = {
10010 /* A list of the registers that can be saved by the MIPS16e SAVE instruction,
10011 ordered from the uppermost in memory to the lowest in memory. */
10012 static const unsigned char mips16e_save_restore_regs
[] = {
10013 31, 30, 23, 22, 21, 20, 19, 18, 17, 16, 7, 6, 5, 4
10016 /* Return the index of the lowest X in the range [0, SIZE) for which
10017 bit REGS[X] is set in MASK. Return SIZE if there is no such X. */
10019 static unsigned int
10020 mips16e_find_first_register (unsigned int mask
, const unsigned char *regs
,
10025 for (i
= 0; i
< size
; i
++)
10026 if (BITSET_P (mask
, regs
[i
]))
10032 /* *MASK_PTR is a mask of general-purpose registers and *NUM_REGS_PTR
10033 is the number of set bits. If *MASK_PTR contains REGS[X] for some X
10034 in [0, SIZE), adjust *MASK_PTR and *NUM_REGS_PTR so that the same
10035 is true for all indexes (X, SIZE). */
10038 mips16e_mask_registers (unsigned int *mask_ptr
, const unsigned char *regs
,
10039 unsigned int size
, unsigned int *num_regs_ptr
)
10043 i
= mips16e_find_first_register (*mask_ptr
, regs
, size
);
10044 for (i
++; i
< size
; i
++)
10045 if (!BITSET_P (*mask_ptr
, regs
[i
]))
10047 *num_regs_ptr
+= 1;
10048 *mask_ptr
|= 1 << regs
[i
];
10052 /* Return a simplified form of X using the register values in REG_VALUES.
10053 REG_VALUES[R] is the last value assigned to hard register R, or null
10054 if R has not been modified.
10056 This function is rather limited, but is good enough for our purposes. */
10059 mips16e_collect_propagate_value (rtx x
, rtx
*reg_values
)
10061 x
= avoid_constant_pool_reference (x
);
10065 rtx x0
= mips16e_collect_propagate_value (XEXP (x
, 0), reg_values
);
10066 return simplify_gen_unary (GET_CODE (x
), GET_MODE (x
),
10067 x0
, GET_MODE (XEXP (x
, 0)));
10070 if (ARITHMETIC_P (x
))
10072 rtx x0
= mips16e_collect_propagate_value (XEXP (x
, 0), reg_values
);
10073 rtx x1
= mips16e_collect_propagate_value (XEXP (x
, 1), reg_values
);
10074 return simplify_gen_binary (GET_CODE (x
), GET_MODE (x
), x0
, x1
);
10078 && reg_values
[REGNO (x
)]
10079 && !rtx_unstable_p (reg_values
[REGNO (x
)]))
10080 return reg_values
[REGNO (x
)];
10085 /* Return true if (set DEST SRC) stores an argument register into its
10086 caller-allocated save slot, storing the number of that argument
10087 register in *REGNO_PTR if so. REG_VALUES is as for
10088 mips16e_collect_propagate_value. */
10091 mips16e_collect_argument_save_p (rtx dest
, rtx src
, rtx
*reg_values
,
10092 unsigned int *regno_ptr
)
10094 unsigned int argno
, regno
;
10095 HOST_WIDE_INT offset
, required_offset
;
10098 /* Check that this is a word-mode store. */
10099 if (!MEM_P (dest
) || !REG_P (src
) || GET_MODE (dest
) != word_mode
)
10102 /* Check that the register being saved is an unmodified argument
10104 regno
= REGNO (src
);
10105 if (!IN_RANGE (regno
, GP_ARG_FIRST
, GP_ARG_LAST
) || reg_values
[regno
])
10107 argno
= regno
- GP_ARG_FIRST
;
10109 /* Check whether the address is an appropriate stack-pointer or
10110 frame-pointer access. */
10111 addr
= mips16e_collect_propagate_value (XEXP (dest
, 0), reg_values
);
10112 mips_split_plus (addr
, &base
, &offset
);
10113 required_offset
= cfun
->machine
->frame
.total_size
+ argno
* UNITS_PER_WORD
;
10114 if (base
== hard_frame_pointer_rtx
)
10115 required_offset
-= cfun
->machine
->frame
.hard_frame_pointer_offset
;
10116 else if (base
!= stack_pointer_rtx
)
10118 if (offset
!= required_offset
)
10121 *regno_ptr
= regno
;
10125 /* A subroutine of mips_expand_prologue, called only when generating
10126 MIPS16e SAVE instructions. Search the start of the function for any
10127 instructions that save argument registers into their caller-allocated
10128 save slots. Delete such instructions and return a value N such that
10129 saving [GP_ARG_FIRST, GP_ARG_FIRST + N) would make all the deleted
10130 instructions redundant. */
10132 static unsigned int
10133 mips16e_collect_argument_saves (void)
10135 rtx reg_values
[FIRST_PSEUDO_REGISTER
];
10136 rtx_insn
*insn
, *next
;
10137 rtx set
, dest
, src
;
10138 unsigned int nargs
, regno
;
10140 push_topmost_sequence ();
10142 memset (reg_values
, 0, sizeof (reg_values
));
10143 for (insn
= get_insns (); insn
; insn
= next
)
10145 next
= NEXT_INSN (insn
);
10146 if (NOTE_P (insn
) || DEBUG_INSN_P (insn
))
10149 if (!INSN_P (insn
))
10152 set
= PATTERN (insn
);
10153 if (GET_CODE (set
) != SET
)
10156 dest
= SET_DEST (set
);
10157 src
= SET_SRC (set
);
10158 if (mips16e_collect_argument_save_p (dest
, src
, reg_values
, ®no
))
10160 if (!BITSET_P (cfun
->machine
->frame
.mask
, regno
))
10162 delete_insn (insn
);
10163 nargs
= MAX (nargs
, (regno
- GP_ARG_FIRST
) + 1);
10166 else if (REG_P (dest
) && GET_MODE (dest
) == word_mode
)
10167 reg_values
[REGNO (dest
)]
10168 = mips16e_collect_propagate_value (src
, reg_values
);
10172 pop_topmost_sequence ();
10177 /* Return a move between register REGNO and memory location SP + OFFSET.
10178 REG_PARM_P is true if SP + OFFSET belongs to REG_PARM_STACK_SPACE.
10179 Make the move a load if RESTORE_P, otherwise make it a store. */
10182 mips16e_save_restore_reg (bool restore_p
, bool reg_parm_p
,
10183 HOST_WIDE_INT offset
, unsigned int regno
)
10187 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
, stack_pointer_rtx
,
10189 reg
= gen_rtx_REG (SImode
, regno
);
10192 mips_add_cfa_restore (reg
);
10193 return gen_rtx_SET (reg
, mem
);
10196 return gen_rtx_SET (mem
, reg
);
10197 return mips_frame_set (mem
, reg
);
10200 /* Return RTL for a MIPS16e SAVE or RESTORE instruction; RESTORE_P says which.
10201 The instruction must:
10203 - Allocate or deallocate SIZE bytes in total; SIZE is known
10206 - Save or restore as many registers in *MASK_PTR as possible.
10207 The instruction saves the first registers at the top of the
10208 allocated area, with the other registers below it.
10210 - Save NARGS argument registers above the allocated area.
10212 (NARGS is always zero if RESTORE_P.)
10214 The SAVE and RESTORE instructions cannot save and restore all general
10215 registers, so there may be some registers left over for the caller to
10216 handle. Destructively modify *MASK_PTR so that it contains the registers
10217 that still need to be saved or restored. The caller can save these
10218 registers in the memory immediately below *OFFSET_PTR, which is a
10219 byte offset from the bottom of the allocated stack area. */
10222 mips16e_build_save_restore (bool restore_p
, unsigned int *mask_ptr
,
10223 HOST_WIDE_INT
*offset_ptr
, unsigned int nargs
,
10224 HOST_WIDE_INT size
)
10227 HOST_WIDE_INT offset
, top_offset
;
10228 unsigned int i
, regno
;
10231 gcc_assert (cfun
->machine
->frame
.num_fp
== 0);
10233 /* Calculate the number of elements in the PARALLEL. We need one element
10234 for the stack adjustment, one for each argument register save, and one
10235 for each additional register move. */
10237 for (i
= 0; i
< ARRAY_SIZE (mips16e_save_restore_regs
); i
++)
10238 if (BITSET_P (*mask_ptr
, mips16e_save_restore_regs
[i
]))
10241 /* Create the final PARALLEL. */
10242 pattern
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (n
));
10245 /* Add the stack pointer adjustment. */
10246 set
= gen_rtx_SET (stack_pointer_rtx
,
10247 plus_constant (Pmode
, stack_pointer_rtx
,
10248 restore_p
? size
: -size
));
10249 RTX_FRAME_RELATED_P (set
) = 1;
10250 XVECEXP (pattern
, 0, n
++) = set
;
10252 /* Stack offsets in the PARALLEL are relative to the old stack pointer. */
10253 top_offset
= restore_p
? size
: 0;
10255 /* Save the arguments. */
10256 for (i
= 0; i
< nargs
; i
++)
10258 offset
= top_offset
+ i
* UNITS_PER_WORD
;
10259 set
= mips16e_save_restore_reg (restore_p
, true, offset
,
10261 XVECEXP (pattern
, 0, n
++) = set
;
10264 /* Then fill in the other register moves. */
10265 offset
= top_offset
;
10266 for (i
= 0; i
< ARRAY_SIZE (mips16e_save_restore_regs
); i
++)
10268 regno
= mips16e_save_restore_regs
[i
];
10269 if (BITSET_P (*mask_ptr
, regno
))
10271 offset
-= UNITS_PER_WORD
;
10272 set
= mips16e_save_restore_reg (restore_p
, false, offset
, regno
);
10273 XVECEXP (pattern
, 0, n
++) = set
;
10274 *mask_ptr
&= ~(1 << regno
);
10278 /* Tell the caller what offset it should use for the remaining registers. */
10279 *offset_ptr
= size
+ (offset
- top_offset
);
10281 gcc_assert (n
== XVECLEN (pattern
, 0));
10286 /* PATTERN is a PARALLEL whose first element adds ADJUST to the stack
10287 pointer. Return true if PATTERN matches the kind of instruction
10288 generated by mips16e_build_save_restore. If INFO is nonnull,
10289 initialize it when returning true. */
10292 mips16e_save_restore_pattern_p (rtx pattern
, HOST_WIDE_INT adjust
,
10293 struct mips16e_save_restore_info
*info
)
10295 unsigned int i
, nargs
, mask
, extra
;
10296 HOST_WIDE_INT top_offset
, save_offset
, offset
;
10297 rtx set
, reg
, mem
, base
;
10300 if (!GENERATE_MIPS16E_SAVE_RESTORE
)
10303 /* Stack offsets in the PARALLEL are relative to the old stack pointer. */
10304 top_offset
= adjust
> 0 ? adjust
: 0;
10306 /* Interpret all other members of the PARALLEL. */
10307 save_offset
= top_offset
- UNITS_PER_WORD
;
10311 for (n
= 1; n
< XVECLEN (pattern
, 0); n
++)
10313 /* Check that we have a SET. */
10314 set
= XVECEXP (pattern
, 0, n
);
10315 if (GET_CODE (set
) != SET
)
10318 /* Check that the SET is a load (if restoring) or a store
10320 mem
= adjust
> 0 ? SET_SRC (set
) : SET_DEST (set
);
10324 /* Check that the address is the sum of the stack pointer and a
10325 possibly-zero constant offset. */
10326 mips_split_plus (XEXP (mem
, 0), &base
, &offset
);
10327 if (base
!= stack_pointer_rtx
)
10330 /* Check that SET's other operand is a register. */
10331 reg
= adjust
> 0 ? SET_DEST (set
) : SET_SRC (set
);
10335 /* Check for argument saves. */
10336 if (offset
== top_offset
+ nargs
* UNITS_PER_WORD
10337 && REGNO (reg
) == GP_ARG_FIRST
+ nargs
)
10339 else if (offset
== save_offset
)
10341 while (mips16e_save_restore_regs
[i
++] != REGNO (reg
))
10342 if (i
== ARRAY_SIZE (mips16e_save_restore_regs
))
10345 mask
|= 1 << REGNO (reg
);
10346 save_offset
-= UNITS_PER_WORD
;
10352 /* Check that the restrictions on register ranges are met. */
10354 mips16e_mask_registers (&mask
, mips16e_s2_s8_regs
,
10355 ARRAY_SIZE (mips16e_s2_s8_regs
), &extra
);
10356 mips16e_mask_registers (&mask
, mips16e_a0_a3_regs
,
10357 ARRAY_SIZE (mips16e_a0_a3_regs
), &extra
);
10361 /* Make sure that the topmost argument register is not saved twice.
10362 The checks above ensure that the same is then true for the other
10363 argument registers. */
10364 if (nargs
> 0 && BITSET_P (mask
, GP_ARG_FIRST
+ nargs
- 1))
10367 /* Pass back information, if requested. */
10370 info
->nargs
= nargs
;
10372 info
->size
= (adjust
> 0 ? adjust
: -adjust
);
10378 /* Add a MIPS16e SAVE or RESTORE register-range argument to string S
10379 for the register range [MIN_REG, MAX_REG]. Return a pointer to
10380 the null terminator. */
10383 mips16e_add_register_range (char *s
, unsigned int min_reg
,
10384 unsigned int max_reg
)
10386 if (min_reg
!= max_reg
)
10387 s
+= sprintf (s
, ",%s-%s", reg_names
[min_reg
], reg_names
[max_reg
]);
10389 s
+= sprintf (s
, ",%s", reg_names
[min_reg
]);
10393 /* Return the assembly instruction for a MIPS16e SAVE or RESTORE instruction.
10394 PATTERN and ADJUST are as for mips16e_save_restore_pattern_p. */
10397 mips16e_output_save_restore (rtx pattern
, HOST_WIDE_INT adjust
)
10399 static char buffer
[300];
10401 struct mips16e_save_restore_info info
;
10402 unsigned int i
, end
;
10405 /* Parse the pattern. */
10406 if (!mips16e_save_restore_pattern_p (pattern
, adjust
, &info
))
10407 gcc_unreachable ();
10409 /* Add the mnemonic. */
10410 s
= strcpy (buffer
, adjust
> 0 ? "restore\t" : "save\t");
10413 /* Save the arguments. */
10414 if (info
.nargs
> 1)
10415 s
+= sprintf (s
, "%s-%s,", reg_names
[GP_ARG_FIRST
],
10416 reg_names
[GP_ARG_FIRST
+ info
.nargs
- 1]);
10417 else if (info
.nargs
== 1)
10418 s
+= sprintf (s
, "%s,", reg_names
[GP_ARG_FIRST
]);
10420 /* Emit the amount of stack space to allocate or deallocate. */
10421 s
+= sprintf (s
, "%d", (int) info
.size
);
10423 /* Save or restore $16. */
10424 if (BITSET_P (info
.mask
, 16))
10425 s
+= sprintf (s
, ",%s", reg_names
[GP_REG_FIRST
+ 16]);
10427 /* Save or restore $17. */
10428 if (BITSET_P (info
.mask
, 17))
10429 s
+= sprintf (s
, ",%s", reg_names
[GP_REG_FIRST
+ 17]);
10431 /* Save or restore registers in the range $s2...$s8, which
10432 mips16e_s2_s8_regs lists in decreasing order. Note that this
10433 is a software register range; the hardware registers are not
10434 numbered consecutively. */
10435 end
= ARRAY_SIZE (mips16e_s2_s8_regs
);
10436 i
= mips16e_find_first_register (info
.mask
, mips16e_s2_s8_regs
, end
);
10438 s
= mips16e_add_register_range (s
, mips16e_s2_s8_regs
[end
- 1],
10439 mips16e_s2_s8_regs
[i
]);
10441 /* Save or restore registers in the range $a0...$a3. */
10442 end
= ARRAY_SIZE (mips16e_a0_a3_regs
);
10443 i
= mips16e_find_first_register (info
.mask
, mips16e_a0_a3_regs
, end
);
10445 s
= mips16e_add_register_range (s
, mips16e_a0_a3_regs
[i
],
10446 mips16e_a0_a3_regs
[end
- 1]);
10448 /* Save or restore $31. */
10449 if (BITSET_P (info
.mask
, RETURN_ADDR_REGNUM
))
10450 s
+= sprintf (s
, ",%s", reg_names
[RETURN_ADDR_REGNUM
]);
10455 /* Return true if the current function returns its value in a floating-point
10456 register in MIPS16 mode. */
10459 mips16_cfun_returns_in_fpr_p (void)
10461 tree return_type
= DECL_RESULT (current_function_decl
);
10462 return (TARGET_MIPS16
10463 && TARGET_HARD_FLOAT_ABI
10464 && !aggregate_value_p (return_type
, current_function_decl
)
10465 && mips_return_mode_in_fpr_p (DECL_MODE (return_type
)));
10468 /* Return true if predicate PRED is true for at least one instruction.
10469 Cache the result in *CACHE, and assume that the result is true
10470 if *CACHE is already true. */
10473 mips_find_gp_ref (bool *cache
, bool (*pred
) (rtx_insn
*))
10475 rtx_insn
*insn
, *subinsn
;
10479 push_topmost_sequence ();
10480 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
10481 FOR_EACH_SUBINSN (subinsn
, insn
)
10482 if (USEFUL_INSN_P (subinsn
) && pred (subinsn
))
10487 pop_topmost_sequence ();
10492 /* Return true if INSN refers to the global pointer in an "inflexible" way.
10493 See mips_cfun_has_inflexible_gp_ref_p for details. */
10496 mips_insn_has_inflexible_gp_ref_p (rtx_insn
*insn
)
10498 /* Uses of pic_offset_table_rtx in CALL_INSN_FUNCTION_USAGE
10499 indicate that the target could be a traditional MIPS
10500 lazily-binding stub. */
10501 return find_reg_fusage (insn
, USE
, pic_offset_table_rtx
);
10504 /* Return true if the current function refers to the global pointer
10505 in a way that forces $28 to be valid. This means that we can't
10506 change the choice of global pointer, even for NewABI code.
10508 One example of this (and one which needs several checks) is that
10509 $28 must be valid when calling traditional MIPS lazy-binding stubs.
10510 (This restriction does not apply to PLTs.) */
10513 mips_cfun_has_inflexible_gp_ref_p (void)
10515 /* If the function has a nonlocal goto, $28 must hold the correct
10516 global pointer for the target function. That is, the target
10517 of the goto implicitly uses $28. */
10518 if (crtl
->has_nonlocal_goto
)
10521 if (TARGET_ABICALLS_PIC2
)
10523 /* Symbolic accesses implicitly use the global pointer unless
10524 -mexplicit-relocs is in effect. JAL macros to symbolic addresses
10525 might go to traditional MIPS lazy-binding stubs. */
10526 if (!TARGET_EXPLICIT_RELOCS
)
10529 /* FUNCTION_PROFILER includes a JAL to _mcount, which again
10530 can be lazily-bound. */
10534 /* MIPS16 functions that return in FPRs need to call an
10535 external libgcc routine. This call is only made explict
10536 during mips_expand_epilogue, and it too might be lazily bound. */
10537 if (mips16_cfun_returns_in_fpr_p ())
10541 return mips_find_gp_ref (&cfun
->machine
->has_inflexible_gp_insn_p
,
10542 mips_insn_has_inflexible_gp_ref_p
);
10545 /* Return true if INSN refers to the global pointer in a "flexible" way.
10546 See mips_cfun_has_flexible_gp_ref_p for details. */
10549 mips_insn_has_flexible_gp_ref_p (rtx_insn
*insn
)
10551 return (get_attr_got (insn
) != GOT_UNSET
10552 || mips_small_data_pattern_p (PATTERN (insn
))
10553 || reg_overlap_mentioned_p (pic_offset_table_rtx
, PATTERN (insn
)));
10556 /* Return true if the current function references the global pointer,
10557 but if those references do not inherently require the global pointer
10558 to be $28. Assume !mips_cfun_has_inflexible_gp_ref_p (). */
10561 mips_cfun_has_flexible_gp_ref_p (void)
10563 /* Reload can sometimes introduce constant pool references
10564 into a function that otherwise didn't need them. For example,
10565 suppose we have an instruction like:
10567 (set (reg:DF R1) (float:DF (reg:SI R2)))
10569 If R2 turns out to be a constant such as 1, the instruction may
10570 have a REG_EQUAL note saying that R1 == 1.0. Reload then has
10571 the option of using this constant if R2 doesn't get allocated
10574 In cases like these, reload will have added the constant to the
10575 pool but no instruction will yet refer to it. */
10576 if (TARGET_ABICALLS_PIC2
&& !reload_completed
&& crtl
->uses_const_pool
)
10579 return mips_find_gp_ref (&cfun
->machine
->has_flexible_gp_insn_p
,
10580 mips_insn_has_flexible_gp_ref_p
);
10583 /* Return the register that should be used as the global pointer
10584 within this function. Return INVALID_REGNUM if the function
10585 doesn't need a global pointer. */
10587 static unsigned int
10588 mips_global_pointer (void)
10590 unsigned int regno
;
10592 /* $gp is always available unless we're using a GOT. */
10593 if (!TARGET_USE_GOT
)
10594 return GLOBAL_POINTER_REGNUM
;
10596 /* If there are inflexible references to $gp, we must use the
10597 standard register. */
10598 if (mips_cfun_has_inflexible_gp_ref_p ())
10599 return GLOBAL_POINTER_REGNUM
;
10601 /* If there are no current references to $gp, then the only uses
10602 we can introduce later are those involved in long branches. */
10603 if (TARGET_ABSOLUTE_JUMPS
&& !mips_cfun_has_flexible_gp_ref_p ())
10604 return INVALID_REGNUM
;
10606 /* If the global pointer is call-saved, try to use a call-clobbered
10608 if (TARGET_CALL_SAVED_GP
&& crtl
->is_leaf
)
10609 for (regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
10610 if (!df_regs_ever_live_p (regno
)
10611 && call_really_used_regs
[regno
]
10612 && !fixed_regs
[regno
]
10613 && regno
!= PIC_FUNCTION_ADDR_REGNUM
)
10616 return GLOBAL_POINTER_REGNUM
;
10619 /* Return true if the current function's prologue must load the global
10620 pointer value into pic_offset_table_rtx and store the same value in
10621 the function's cprestore slot (if any).
10623 One problem we have to deal with is that, when emitting GOT-based
10624 position independent code, long-branch sequences will need to load
10625 the address of the branch target from the GOT. We don't know until
10626 the very end of compilation whether (and where) the function needs
10627 long branches, so we must ensure that _any_ branch can access the
10628 global pointer in some form. However, we do not want to pessimize
10629 the usual case in which all branches are short.
10631 We handle this as follows:
10633 (1) During reload, we set cfun->machine->global_pointer to
10634 INVALID_REGNUM if we _know_ that the current function
10635 doesn't need a global pointer. This is only valid if
10636 long branches don't need the GOT.
10638 Otherwise, we assume that we might need a global pointer
10639 and pick an appropriate register.
10641 (2) If cfun->machine->global_pointer != INVALID_REGNUM,
10642 we ensure that the global pointer is available at every
10643 block boundary bar entry and exit. We do this in one of two ways:
10645 - If the function has a cprestore slot, we ensure that this
10646 slot is valid at every branch. However, as explained in
10647 point (6) below, there is no guarantee that pic_offset_table_rtx
10648 itself is valid if new uses of the global pointer are introduced
10649 after the first post-epilogue split.
10651 We guarantee that the cprestore slot is valid by loading it
10652 into a fake register, CPRESTORE_SLOT_REGNUM. We then make
10653 this register live at every block boundary bar function entry
10654 and exit. It is then invalid to move the load (and thus the
10655 preceding store) across a block boundary.
10657 - If the function has no cprestore slot, we guarantee that
10658 pic_offset_table_rtx itself is valid at every branch.
10660 See mips_eh_uses for the handling of the register liveness.
10662 (3) During prologue and epilogue generation, we emit "ghost"
10663 placeholder instructions to manipulate the global pointer.
10665 (4) During prologue generation, we set cfun->machine->must_initialize_gp_p
10666 and cfun->machine->must_restore_gp_when_clobbered_p if we already know
10667 that the function needs a global pointer. (There is no need to set
10668 them earlier than this, and doing it as late as possible leads to
10669 fewer false positives.)
10671 (5) If cfun->machine->must_initialize_gp_p is true during a
10672 split_insns pass, we split the ghost instructions into real
10673 instructions. These split instructions can then be optimized in
10674 the usual way. Otherwise, we keep the ghost instructions intact,
10675 and optimize for the case where they aren't needed. We still
10676 have the option of splitting them later, if we need to introduce
10677 new uses of the global pointer.
10679 For example, the scheduler ignores a ghost instruction that
10680 stores $28 to the stack, but it handles the split form of
10681 the ghost instruction as an ordinary store.
10683 (6) [OldABI only.] If cfun->machine->must_restore_gp_when_clobbered_p
10684 is true during the first post-epilogue split_insns pass, we split
10685 calls and restore_gp patterns into instructions that explicitly
10686 load pic_offset_table_rtx from the cprestore slot. Otherwise,
10687 we split these patterns into instructions that _don't_ load from
10688 the cprestore slot.
10690 If cfun->machine->must_restore_gp_when_clobbered_p is true at the
10691 time of the split, then any instructions that exist at that time
10692 can make free use of pic_offset_table_rtx. However, if we want
10693 to introduce new uses of the global pointer after the split,
10694 we must explicitly load the value from the cprestore slot, since
10695 pic_offset_table_rtx itself might not be valid at a given point
10698 The idea is that we want to be able to delete redundant
10699 loads from the cprestore slot in the usual case where no
10700 long branches are needed.
10702 (7) If cfun->machine->must_initialize_gp_p is still false at the end
10703 of md_reorg, we decide whether the global pointer is needed for
10704 long branches. If so, we set cfun->machine->must_initialize_gp_p
10705 to true and split the ghost instructions into real instructions
10708 Note that the ghost instructions must have a zero length for three reasons:
10710 - Giving the length of the underlying $gp sequence might cause
10711 us to use long branches in cases where they aren't really needed.
10713 - They would perturb things like alignment calculations.
10715 - More importantly, the hazard detection in md_reorg relies on
10716 empty instructions having a zero length.
10718 If we find a long branch and split the ghost instructions at the
10719 end of md_reorg, the split could introduce more long branches.
10720 That isn't a problem though, because we still do the split before
10721 the final shorten_branches pass.
10723 This is extremely ugly, but it seems like the best compromise between
10724 correctness and efficiency. */
10727 mips_must_initialize_gp_p (void)
10729 return cfun
->machine
->must_initialize_gp_p
;
10732 /* Return true if REGNO is a register that is ordinarily call-clobbered
10733 but must nevertheless be preserved by an interrupt handler. */
10736 mips_interrupt_extra_call_saved_reg_p (unsigned int regno
)
10738 if ((ISA_HAS_HILO
|| TARGET_DSP
)
10739 && MD_REG_P (regno
))
10742 if (TARGET_DSP
&& DSP_ACC_REG_P (regno
))
10745 if (GP_REG_P (regno
)
10746 && cfun
->machine
->use_shadow_register_set
== SHADOW_SET_NO
)
10748 /* $0 is hard-wired. */
10749 if (regno
== GP_REG_FIRST
)
10752 /* The interrupt handler can treat kernel registers as
10753 scratch registers. */
10754 if (KERNEL_REG_P (regno
))
10757 /* The function will return the stack pointer to its original value
10759 if (regno
== STACK_POINTER_REGNUM
)
10762 /* Otherwise, return true for registers that aren't ordinarily
10764 return call_really_used_regs
[regno
];
10770 /* Return true if the current function should treat register REGNO
10774 mips_cfun_call_saved_reg_p (unsigned int regno
)
10776 /* If the user makes an ordinarily-call-saved register global,
10777 that register is no longer call-saved. */
10778 if (global_regs
[regno
])
10781 /* Interrupt handlers need to save extra registers. */
10782 if (cfun
->machine
->interrupt_handler_p
10783 && mips_interrupt_extra_call_saved_reg_p (regno
))
10786 /* call_insns preserve $28 unless they explicitly say otherwise,
10787 so call_really_used_regs[] treats $28 as call-saved. However,
10788 we want the ABI property rather than the default call_insn
10790 return (regno
== GLOBAL_POINTER_REGNUM
10791 ? TARGET_CALL_SAVED_GP
10792 : !call_really_used_regs
[regno
]);
10795 /* Return true if the function body might clobber register REGNO.
10796 We know that REGNO is call-saved. */
10799 mips_cfun_might_clobber_call_saved_reg_p (unsigned int regno
)
10801 /* Some functions should be treated as clobbering all call-saved
10803 if (crtl
->saves_all_registers
)
10806 /* DF handles cases where a register is explicitly referenced in
10807 the rtl. Incoming values are passed in call-clobbered registers,
10808 so we can assume that any live call-saved register is set within
10810 if (df_regs_ever_live_p (regno
))
10813 /* Check for registers that are clobbered by FUNCTION_PROFILER.
10814 These clobbers are not explicit in the rtl. */
10815 if (crtl
->profile
&& MIPS_SAVE_REG_FOR_PROFILING_P (regno
))
10818 /* If we're using a call-saved global pointer, the function's
10819 prologue will need to set it up. */
10820 if (cfun
->machine
->global_pointer
== regno
)
10823 /* The function's prologue will need to set the frame pointer if
10824 frame_pointer_needed. */
10825 if (regno
== HARD_FRAME_POINTER_REGNUM
&& frame_pointer_needed
)
10828 /* If a MIPS16 function returns a value in FPRs, its epilogue
10829 will need to call an external libgcc routine. This yet-to-be
10830 generated call_insn will clobber $31. */
10831 if (regno
== RETURN_ADDR_REGNUM
&& mips16_cfun_returns_in_fpr_p ())
10834 /* If REGNO is ordinarily call-clobbered, we must assume that any
10835 called function could modify it. */
10836 if (cfun
->machine
->interrupt_handler_p
10838 && mips_interrupt_extra_call_saved_reg_p (regno
))
10844 /* Return true if the current function must save register REGNO. */
10847 mips_save_reg_p (unsigned int regno
)
10849 if (mips_cfun_call_saved_reg_p (regno
))
10851 if (mips_cfun_might_clobber_call_saved_reg_p (regno
))
10854 /* Save both registers in an FPR pair if either one is used. This is
10855 needed for the case when MIN_FPRS_PER_FMT == 1, which allows the odd
10856 register to be used without the even register. */
10857 if (FP_REG_P (regno
)
10858 && MAX_FPRS_PER_FMT
== 2
10859 && mips_cfun_might_clobber_call_saved_reg_p (regno
+ 1))
10863 /* We need to save the incoming return address if __builtin_eh_return
10864 is being used to set a different return address. */
10865 if (regno
== RETURN_ADDR_REGNUM
&& crtl
->calls_eh_return
)
10871 /* Populate the current function's mips_frame_info structure.
10873 MIPS stack frames look like:
10875 +-------------------------------+
10877 | incoming stack arguments |
10879 +-------------------------------+
10881 | caller-allocated save area |
10882 A | for register arguments |
10884 +-------------------------------+ <-- incoming stack pointer
10886 | callee-allocated save area |
10887 B | for arguments that are |
10888 | split between registers and |
10891 +-------------------------------+ <-- arg_pointer_rtx
10893 C | callee-allocated save area |
10894 | for register varargs |
10896 +-------------------------------+ <-- frame_pointer_rtx
10897 | | + cop0_sp_offset
10898 | COP0 reg save area | + UNITS_PER_WORD
10900 +-------------------------------+ <-- frame_pointer_rtx + acc_sp_offset
10901 | | + UNITS_PER_WORD
10902 | accumulator save area |
10904 +-------------------------------+ <-- stack_pointer_rtx + fp_sp_offset
10905 | | + UNITS_PER_HWFPVALUE
10908 +-------------------------------+ <-- stack_pointer_rtx + gp_sp_offset
10909 | | + UNITS_PER_WORD
10912 +-------------------------------+ <-- frame_pointer_rtx with
10913 | | \ -fstack-protector
10914 | local variables | | var_size
10916 +-------------------------------+
10918 | $gp save area | | cprestore_size
10920 P +-------------------------------+ <-- hard_frame_pointer_rtx for
10922 | outgoing stack arguments | |
10924 +-------------------------------+ | args_size
10926 | caller-allocated save area | |
10927 | for register arguments | |
10929 +-------------------------------+ <-- stack_pointer_rtx
10930 frame_pointer_rtx without
10932 hard_frame_pointer_rtx for
10935 At least two of A, B and C will be empty.
10937 Dynamic stack allocations such as alloca insert data at point P.
10938 They decrease stack_pointer_rtx but leave frame_pointer_rtx and
10939 hard_frame_pointer_rtx unchanged. */
10942 mips_compute_frame_info (void)
10944 struct mips_frame_info
*frame
;
10945 HOST_WIDE_INT offset
, size
;
10946 unsigned int regno
, i
;
10948 /* Skip re-computing the frame info after reload completed. */
10949 if (reload_completed
)
10952 /* Set this function's interrupt properties. */
10953 if (mips_interrupt_type_p (TREE_TYPE (current_function_decl
)))
10955 if (mips_isa_rev
< 2)
10956 error ("the %<interrupt%> attribute requires a MIPS32r2 processor or greater");
10957 else if (TARGET_MIPS16
)
10958 error ("interrupt handlers cannot be MIPS16 functions");
10961 cfun
->machine
->interrupt_handler_p
= true;
10962 cfun
->machine
->int_mask
=
10963 mips_interrupt_mask (TREE_TYPE (current_function_decl
));
10964 cfun
->machine
->use_shadow_register_set
=
10965 mips_use_shadow_register_set (TREE_TYPE (current_function_decl
));
10966 cfun
->machine
->keep_interrupts_masked_p
=
10967 mips_keep_interrupts_masked_p (TREE_TYPE (current_function_decl
));
10968 cfun
->machine
->use_debug_exception_return_p
=
10969 mips_use_debug_exception_return_p (TREE_TYPE
10970 (current_function_decl
));
10974 frame
= &cfun
->machine
->frame
;
10975 memset (frame
, 0, sizeof (*frame
));
10976 size
= get_frame_size ();
10978 /* The first two blocks contain the outgoing argument area and the $gp save
10979 slot. This area isn't needed in leaf functions. We can also skip it
10980 if we know that none of the called functions will use this space.
10982 But if the target-independent frame size is nonzero, we have already
10983 committed to allocating these in TARGET_STARTING_FRAME_OFFSET for
10984 !FRAME_GROWS_DOWNWARD. */
10986 if ((size
== 0 || FRAME_GROWS_DOWNWARD
)
10987 && (crtl
->is_leaf
|| (cfun
->machine
->optimize_call_stack
&& !flag_pic
)))
10989 /* The MIPS 3.0 linker does not like functions that dynamically
10990 allocate the stack and have 0 for STACK_DYNAMIC_OFFSET, since it
10991 looks like we are trying to create a second frame pointer to the
10992 function, so allocate some stack space to make it happy. */
10993 if (cfun
->calls_alloca
)
10994 frame
->args_size
= REG_PARM_STACK_SPACE (cfun
->decl
);
10996 frame
->args_size
= 0;
10997 frame
->cprestore_size
= 0;
11001 frame
->args_size
= crtl
->outgoing_args_size
;
11002 frame
->cprestore_size
= MIPS_GP_SAVE_AREA_SIZE
;
11005 /* MIPS16 code offsets the frame pointer by the size of the outgoing
11006 arguments. This tends to increase the chances of using unextended
11007 instructions for local variables and incoming arguments. */
11009 frame
->hard_frame_pointer_offset
= frame
->args_size
;
11011 /* PR 69129 / 69012: Beware of a possible race condition. mips_global_pointer
11012 might call mips_cfun_has_inflexible_gp_ref_p which in turn can call
11013 mips_find_gp_ref which will iterate over the current insn sequence.
11014 If any of these insns use the cprestore_save_slot_operand or
11015 cprestore_load_slot_operand predicates in order to be recognised then
11016 they will call mips_cprestore_address_p which calls
11017 mips_get_cprestore_base_and_offset which expects the frame information
11018 to be filled in... In fact mips_get_cprestore_base_and_offset only
11019 needs the args_size and hard_frame_pointer_offset fields to be filled
11020 in, which is why the global_pointer field is initialised here and not
11022 cfun
->machine
->global_pointer
= mips_global_pointer ();
11024 offset
= frame
->args_size
+ frame
->cprestore_size
;
11026 /* Move above the local variables. */
11027 frame
->var_size
= MIPS_STACK_ALIGN (size
);
11028 offset
+= frame
->var_size
;
11030 /* Find out which GPRs we need to save. */
11031 for (regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
11032 if (mips_save_reg_p (regno
))
11035 frame
->mask
|= 1 << (regno
- GP_REG_FIRST
);
11038 /* If this function calls eh_return, we must also save and restore the
11039 EH data registers. */
11040 if (crtl
->calls_eh_return
)
11041 for (i
= 0; EH_RETURN_DATA_REGNO (i
) != INVALID_REGNUM
; i
++)
11044 frame
->mask
|= 1 << (EH_RETURN_DATA_REGNO (i
) - GP_REG_FIRST
);
11047 /* The MIPS16e SAVE and RESTORE instructions have two ranges of registers:
11048 $a3-$a0 and $s2-$s8. If we save one register in the range, we must
11049 save all later registers too. */
11050 if (GENERATE_MIPS16E_SAVE_RESTORE
)
11052 mips16e_mask_registers (&frame
->mask
, mips16e_s2_s8_regs
,
11053 ARRAY_SIZE (mips16e_s2_s8_regs
), &frame
->num_gp
);
11054 mips16e_mask_registers (&frame
->mask
, mips16e_a0_a3_regs
,
11055 ARRAY_SIZE (mips16e_a0_a3_regs
), &frame
->num_gp
);
11058 /* Move above the GPR save area. */
11059 if (frame
->num_gp
> 0)
11061 offset
+= MIPS_STACK_ALIGN (frame
->num_gp
* UNITS_PER_WORD
);
11062 frame
->gp_sp_offset
= offset
- UNITS_PER_WORD
;
11065 /* Find out which FPRs we need to save. This loop must iterate over
11066 the same space as its companion in mips_for_each_saved_gpr_and_fpr. */
11067 if (TARGET_HARD_FLOAT
)
11068 for (regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
+= MAX_FPRS_PER_FMT
)
11069 if (mips_save_reg_p (regno
))
11071 frame
->num_fp
+= MAX_FPRS_PER_FMT
;
11072 frame
->fmask
|= ~(~0U << MAX_FPRS_PER_FMT
) << (regno
- FP_REG_FIRST
);
11075 /* Move above the FPR save area. */
11076 if (frame
->num_fp
> 0)
11078 offset
+= MIPS_STACK_ALIGN (frame
->num_fp
* UNITS_PER_FPREG
);
11079 frame
->fp_sp_offset
= offset
- UNITS_PER_HWFPVALUE
;
11082 /* Add in space for the interrupt context information. */
11083 if (cfun
->machine
->interrupt_handler_p
)
11086 if (mips_save_reg_p (LO_REGNUM
) || mips_save_reg_p (HI_REGNUM
))
11089 frame
->acc_mask
|= (1 << 0);
11092 /* Check accumulators 1, 2, 3. */
11093 for (i
= DSP_ACC_REG_FIRST
; i
<= DSP_ACC_REG_LAST
; i
+= 2)
11094 if (mips_save_reg_p (i
) || mips_save_reg_p (i
+ 1))
11097 frame
->acc_mask
|= 1 << (((i
- DSP_ACC_REG_FIRST
) / 2) + 1);
11100 /* All interrupt context functions need space to preserve STATUS. */
11101 frame
->num_cop0_regs
++;
11103 /* We need to save EPC regardless of whether interrupts remain masked
11104 as exceptions will corrupt EPC. */
11105 frame
->num_cop0_regs
++;
11108 /* Move above the accumulator save area. */
11109 if (frame
->num_acc
> 0)
11111 /* Each accumulator needs 2 words. */
11112 offset
+= frame
->num_acc
* 2 * UNITS_PER_WORD
;
11113 frame
->acc_sp_offset
= offset
- UNITS_PER_WORD
;
11116 /* Move above the COP0 register save area. */
11117 if (frame
->num_cop0_regs
> 0)
11119 offset
+= frame
->num_cop0_regs
* UNITS_PER_WORD
;
11120 frame
->cop0_sp_offset
= offset
- UNITS_PER_WORD
;
11123 /* Determine if we can save the callee-saved registers in the frame
11124 header. Restrict this to functions where there is no other reason
11125 to allocate stack space so that we can eliminate the instructions
11126 that modify the stack pointer. */
11130 && flag_frame_header_optimization
11131 && !MAIN_NAME_P (DECL_NAME (current_function_decl
))
11132 && cfun
->machine
->varargs_size
== 0
11133 && crtl
->args
.pretend_args_size
== 0
11134 && frame
->var_size
== 0
11135 && frame
->num_acc
== 0
11136 && frame
->num_cop0_regs
== 0
11137 && frame
->num_fp
== 0
11138 && frame
->num_gp
> 0
11139 && frame
->num_gp
<= MAX_ARGS_IN_REGISTERS
11140 && !GENERATE_MIPS16E_SAVE_RESTORE
11141 && !cfun
->machine
->interrupt_handler_p
11142 && cfun
->machine
->does_not_use_frame_header
11143 && cfun
->machine
->optimize_call_stack
11144 && !cfun
->machine
->callers_may_not_allocate_frame
11145 && !mips_cfun_has_cprestore_slot_p ())
11148 frame
->gp_sp_offset
= REG_PARM_STACK_SPACE(cfun
) - UNITS_PER_WORD
;
11149 cfun
->machine
->use_frame_header_for_callee_saved_regs
= true;
11152 /* Move above the callee-allocated varargs save area. */
11153 offset
+= MIPS_STACK_ALIGN (cfun
->machine
->varargs_size
);
11154 frame
->arg_pointer_offset
= offset
;
11156 /* Move above the callee-allocated area for pretend stack arguments. */
11157 offset
+= crtl
->args
.pretend_args_size
;
11158 frame
->total_size
= offset
;
11160 /* Work out the offsets of the save areas from the top of the frame. */
11161 if (frame
->gp_sp_offset
> 0)
11162 frame
->gp_save_offset
= frame
->gp_sp_offset
- offset
;
11163 if (frame
->fp_sp_offset
> 0)
11164 frame
->fp_save_offset
= frame
->fp_sp_offset
- offset
;
11165 if (frame
->acc_sp_offset
> 0)
11166 frame
->acc_save_offset
= frame
->acc_sp_offset
- offset
;
11167 if (frame
->num_cop0_regs
> 0)
11168 frame
->cop0_save_offset
= frame
->cop0_sp_offset
- offset
;
11171 /* Return the style of GP load sequence that is being used for the
11172 current function. */
11174 enum mips_loadgp_style
11175 mips_current_loadgp_style (void)
11177 if (!TARGET_USE_GOT
|| cfun
->machine
->global_pointer
== INVALID_REGNUM
)
11178 return LOADGP_NONE
;
11180 if (TARGET_RTP_PIC
)
11183 if (TARGET_ABSOLUTE_ABICALLS
)
11184 return LOADGP_ABSOLUTE
;
11186 return TARGET_NEWABI
? LOADGP_NEWABI
: LOADGP_OLDABI
;
11189 /* Implement TARGET_FRAME_POINTER_REQUIRED. */
11192 mips_frame_pointer_required (void)
11194 /* If the function contains dynamic stack allocations, we need to
11195 use the frame pointer to access the static parts of the frame. */
11196 if (cfun
->calls_alloca
)
11199 /* In MIPS16 mode, we need a frame pointer for a large frame; otherwise,
11200 reload may be unable to compute the address of a local variable,
11201 since there is no way to add a large constant to the stack pointer
11202 without using a second temporary register. */
11205 mips_compute_frame_info ();
11206 if (!SMALL_OPERAND (cfun
->machine
->frame
.total_size
))
11213 /* Make sure that we're not trying to eliminate to the wrong hard frame
11217 mips_can_eliminate (const int from ATTRIBUTE_UNUSED
, const int to
)
11219 return (to
== HARD_FRAME_POINTER_REGNUM
|| to
== STACK_POINTER_REGNUM
);
11222 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame pointer
11223 or argument pointer. TO is either the stack pointer or hard frame
11227 mips_initial_elimination_offset (int from
, int to
)
11229 HOST_WIDE_INT offset
;
11231 mips_compute_frame_info ();
11233 /* Set OFFSET to the offset from the end-of-prologue stack pointer. */
11236 case FRAME_POINTER_REGNUM
:
11237 if (FRAME_GROWS_DOWNWARD
)
11238 offset
= (cfun
->machine
->frame
.args_size
11239 + cfun
->machine
->frame
.cprestore_size
11240 + cfun
->machine
->frame
.var_size
);
11245 case ARG_POINTER_REGNUM
:
11246 offset
= cfun
->machine
->frame
.arg_pointer_offset
;
11250 gcc_unreachable ();
11253 if (to
== HARD_FRAME_POINTER_REGNUM
)
11254 offset
-= cfun
->machine
->frame
.hard_frame_pointer_offset
;
11259 /* Implement TARGET_EXTRA_LIVE_ON_ENTRY. */
11262 mips_extra_live_on_entry (bitmap regs
)
11264 if (TARGET_USE_GOT
)
11266 /* PIC_FUNCTION_ADDR_REGNUM is live if we need it to set up
11267 the global pointer. */
11268 if (!TARGET_ABSOLUTE_ABICALLS
)
11269 bitmap_set_bit (regs
, PIC_FUNCTION_ADDR_REGNUM
);
11271 /* The prologue may set MIPS16_PIC_TEMP_REGNUM to the value of
11272 the global pointer. */
11274 bitmap_set_bit (regs
, MIPS16_PIC_TEMP_REGNUM
);
11276 /* See the comment above load_call<mode> for details. */
11277 bitmap_set_bit (regs
, GOT_VERSION_REGNUM
);
11281 /* Implement RETURN_ADDR_RTX. We do not support moving back to a
11285 mips_return_addr (int count
, rtx frame ATTRIBUTE_UNUSED
)
11290 return get_hard_reg_initial_val (Pmode
, RETURN_ADDR_REGNUM
);
11293 /* Emit code to change the current function's return address to
11294 ADDRESS. SCRATCH is available as a scratch register, if needed.
11295 ADDRESS and SCRATCH are both word-mode GPRs. */
11298 mips_set_return_address (rtx address
, rtx scratch
)
11302 gcc_assert (BITSET_P (cfun
->machine
->frame
.mask
, RETURN_ADDR_REGNUM
));
11303 slot_address
= mips_add_offset (scratch
, stack_pointer_rtx
,
11304 cfun
->machine
->frame
.gp_sp_offset
);
11305 mips_emit_move (gen_frame_mem (GET_MODE (address
), slot_address
), address
);
11308 /* Return true if the current function has a cprestore slot. */
11311 mips_cfun_has_cprestore_slot_p (void)
11313 return (cfun
->machine
->global_pointer
!= INVALID_REGNUM
11314 && cfun
->machine
->frame
.cprestore_size
> 0);
11317 /* Fill *BASE and *OFFSET such that *BASE + *OFFSET refers to the
11318 cprestore slot. LOAD_P is true if the caller wants to load from
11319 the cprestore slot; it is false if the caller wants to store to
11323 mips_get_cprestore_base_and_offset (rtx
*base
, HOST_WIDE_INT
*offset
,
11326 const struct mips_frame_info
*frame
;
11328 frame
= &cfun
->machine
->frame
;
11329 /* .cprestore always uses the stack pointer instead of the frame pointer.
11330 We have a free choice for direct stores for non-MIPS16 functions,
11331 and for MIPS16 functions whose cprestore slot is in range of the
11332 stack pointer. Using the stack pointer would sometimes give more
11333 (early) scheduling freedom, but using the frame pointer would
11334 sometimes give more (late) scheduling freedom. It's hard to
11335 predict which applies to a given function, so let's keep things
11338 Loads must always use the frame pointer in functions that call
11339 alloca, and there's little benefit to using the stack pointer
11341 if (frame_pointer_needed
&& !(TARGET_CPRESTORE_DIRECTIVE
&& !load_p
))
11343 *base
= hard_frame_pointer_rtx
;
11344 *offset
= frame
->args_size
- frame
->hard_frame_pointer_offset
;
11348 *base
= stack_pointer_rtx
;
11349 *offset
= frame
->args_size
;
11353 /* Return true if X is the load or store address of the cprestore slot;
11354 LOAD_P says which. */
11357 mips_cprestore_address_p (rtx x
, bool load_p
)
11359 rtx given_base
, required_base
;
11360 HOST_WIDE_INT given_offset
, required_offset
;
11362 mips_split_plus (x
, &given_base
, &given_offset
);
11363 mips_get_cprestore_base_and_offset (&required_base
, &required_offset
, load_p
);
11364 return given_base
== required_base
&& given_offset
== required_offset
;
11367 /* Return a MEM rtx for the cprestore slot. LOAD_P is true if we are
11368 going to load from it, false if we are going to store to it.
11369 Use TEMP as a temporary register if need be. */
11372 mips_cprestore_slot (rtx temp
, bool load_p
)
11375 HOST_WIDE_INT offset
;
11377 mips_get_cprestore_base_and_offset (&base
, &offset
, load_p
);
11378 return gen_frame_mem (Pmode
, mips_add_offset (temp
, base
, offset
));
11381 /* Emit instructions to save global pointer value GP into cprestore
11382 slot MEM. OFFSET is the offset that MEM applies to the base register.
11384 MEM may not be a legitimate address. If it isn't, TEMP is a
11385 temporary register that can be used, otherwise it is a SCRATCH. */
11388 mips_save_gp_to_cprestore_slot (rtx mem
, rtx offset
, rtx gp
, rtx temp
)
11390 if (TARGET_CPRESTORE_DIRECTIVE
)
11392 gcc_assert (gp
== pic_offset_table_rtx
);
11393 emit_insn (PMODE_INSN (gen_cprestore
, (mem
, offset
)));
11396 mips_emit_move (mips_cprestore_slot (temp
, false), gp
);
11399 /* Restore $gp from its save slot, using TEMP as a temporary base register
11400 if need be. This function is for o32 and o64 abicalls only.
11402 See mips_must_initialize_gp_p for details about how we manage the
11406 mips_restore_gp_from_cprestore_slot (rtx temp
)
11408 gcc_assert (TARGET_ABICALLS
&& TARGET_OLDABI
&& epilogue_completed
);
11410 if (!cfun
->machine
->must_restore_gp_when_clobbered_p
)
11412 emit_note (NOTE_INSN_DELETED
);
11418 mips_emit_move (temp
, mips_cprestore_slot (temp
, true));
11419 mips_emit_move (pic_offset_table_rtx
, temp
);
11422 mips_emit_move (pic_offset_table_rtx
, mips_cprestore_slot (temp
, true));
11423 if (!TARGET_EXPLICIT_RELOCS
)
11424 emit_insn (gen_blockage ());
11427 /* A function to save or store a register. The first argument is the
11428 register and the second is the stack slot. */
11429 typedef void (*mips_save_restore_fn
) (rtx
, rtx
);
11431 /* Use FN to save or restore register REGNO. MODE is the register's
11432 mode and OFFSET is the offset of its save slot from the current
11436 mips_save_restore_reg (machine_mode mode
, int regno
,
11437 HOST_WIDE_INT offset
, mips_save_restore_fn fn
)
11441 mem
= gen_frame_mem (mode
, plus_constant (Pmode
, stack_pointer_rtx
,
11443 fn (gen_rtx_REG (mode
, regno
), mem
);
11446 /* Call FN for each accumulator that is saved by the current function.
11447 SP_OFFSET is the offset of the current stack pointer from the start
11451 mips_for_each_saved_acc (HOST_WIDE_INT sp_offset
, mips_save_restore_fn fn
)
11453 HOST_WIDE_INT offset
;
11456 offset
= cfun
->machine
->frame
.acc_sp_offset
- sp_offset
;
11457 if (BITSET_P (cfun
->machine
->frame
.acc_mask
, 0))
11459 mips_save_restore_reg (word_mode
, LO_REGNUM
, offset
, fn
);
11460 offset
-= UNITS_PER_WORD
;
11461 mips_save_restore_reg (word_mode
, HI_REGNUM
, offset
, fn
);
11462 offset
-= UNITS_PER_WORD
;
11465 for (regno
= DSP_ACC_REG_FIRST
; regno
<= DSP_ACC_REG_LAST
; regno
++)
11466 if (BITSET_P (cfun
->machine
->frame
.acc_mask
,
11467 ((regno
- DSP_ACC_REG_FIRST
) / 2) + 1))
11469 mips_save_restore_reg (word_mode
, regno
, offset
, fn
);
11470 offset
-= UNITS_PER_WORD
;
11474 /* Save register REG to MEM. Make the instruction frame-related. */
11477 mips_save_reg (rtx reg
, rtx mem
)
11479 if (GET_MODE (reg
) == DFmode
11480 && (!TARGET_FLOAT64
11481 || mips_abi
== ABI_32
))
11485 mips_emit_move_or_split (mem
, reg
, SPLIT_IF_NECESSARY
);
11487 x1
= mips_frame_set (mips_subword (mem
, false),
11488 mips_subword (reg
, false));
11489 x2
= mips_frame_set (mips_subword (mem
, true),
11490 mips_subword (reg
, true));
11491 mips_set_frame_expr (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, x1
, x2
)));
11494 mips_emit_save_slot_move (mem
, reg
, MIPS_PROLOGUE_TEMP (GET_MODE (reg
)));
11497 /* Capture the register combinations that are allowed in a SWM or LWM
11498 instruction. The entries are ordered by number of registers set in
11499 the mask. We also ignore the single register encodings because a
11500 normal SW/LW is preferred. */
11502 static const unsigned int umips_swm_mask
[17] = {
11503 0xc0ff0000, 0x80ff0000, 0x40ff0000, 0x807f0000,
11504 0x00ff0000, 0x803f0000, 0x007f0000, 0x801f0000,
11505 0x003f0000, 0x800f0000, 0x001f0000, 0x80070000,
11506 0x000f0000, 0x80030000, 0x00070000, 0x80010000,
11510 static const unsigned int umips_swm_encoding
[17] = {
11511 25, 24, 9, 23, 8, 22, 7, 21, 6, 20, 5, 19, 4, 18, 3, 17, 2
11514 /* Try to use a microMIPS LWM or SWM instruction to save or restore
11515 as many GPRs in *MASK as possible. *OFFSET is the offset from the
11516 stack pointer of the topmost save slot.
11518 Remove from *MASK all registers that were handled using LWM and SWM.
11519 Update *OFFSET so that it points to the first unused save slot. */
11522 umips_build_save_restore (mips_save_restore_fn fn
,
11523 unsigned *mask
, HOST_WIDE_INT
*offset
)
11527 rtx pattern
, set
, reg
, mem
;
11528 HOST_WIDE_INT this_offset
;
11531 /* Try matching $16 to $31 (s0 to ra). */
11532 for (i
= 0; i
< ARRAY_SIZE (umips_swm_mask
); i
++)
11533 if ((*mask
& 0xffff0000) == umips_swm_mask
[i
])
11536 if (i
== ARRAY_SIZE (umips_swm_mask
))
11539 /* Get the offset of the lowest save slot. */
11540 nregs
= (umips_swm_encoding
[i
] & 0xf) + (umips_swm_encoding
[i
] >> 4);
11541 this_offset
= *offset
- UNITS_PER_WORD
* (nregs
- 1);
11543 /* LWM/SWM can only support offsets from -2048 to 2047. */
11544 if (!UMIPS_12BIT_OFFSET_P (this_offset
))
11547 /* Create the final PARALLEL. */
11548 pattern
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (nregs
));
11549 this_base
= stack_pointer_rtx
;
11551 /* For registers $16-$23 and $30. */
11552 for (j
= 0; j
< (umips_swm_encoding
[i
] & 0xf); j
++)
11554 HOST_WIDE_INT offset
= this_offset
+ j
* UNITS_PER_WORD
;
11555 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
, this_base
, offset
));
11556 unsigned int regno
= (j
!= 8) ? 16 + j
: 30;
11557 *mask
&= ~(1 << regno
);
11558 reg
= gen_rtx_REG (SImode
, regno
);
11559 if (fn
== mips_save_reg
)
11560 set
= mips_frame_set (mem
, reg
);
11563 set
= gen_rtx_SET (reg
, mem
);
11564 mips_add_cfa_restore (reg
);
11566 XVECEXP (pattern
, 0, j
) = set
;
11569 /* For register $31. */
11570 if (umips_swm_encoding
[i
] >> 4)
11572 HOST_WIDE_INT offset
= this_offset
+ j
* UNITS_PER_WORD
;
11573 *mask
&= ~(1 << 31);
11574 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
, this_base
, offset
));
11575 reg
= gen_rtx_REG (SImode
, 31);
11576 if (fn
== mips_save_reg
)
11577 set
= mips_frame_set (mem
, reg
);
11580 set
= gen_rtx_SET (reg
, mem
);
11581 mips_add_cfa_restore (reg
);
11583 XVECEXP (pattern
, 0, j
) = set
;
11586 pattern
= emit_insn (pattern
);
11587 if (fn
== mips_save_reg
)
11588 RTX_FRAME_RELATED_P (pattern
) = 1;
11590 /* Adjust the last offset. */
11591 *offset
-= UNITS_PER_WORD
* nregs
;
11596 /* Call FN for each register that is saved by the current function.
11597 SP_OFFSET is the offset of the current stack pointer from the start
11601 mips_for_each_saved_gpr_and_fpr (HOST_WIDE_INT sp_offset
,
11602 mips_save_restore_fn fn
)
11604 machine_mode fpr_mode
;
11606 const struct mips_frame_info
*frame
= &cfun
->machine
->frame
;
11607 HOST_WIDE_INT offset
;
11610 /* Save registers starting from high to low. The debuggers prefer at least
11611 the return register be stored at func+4, and also it allows us not to
11612 need a nop in the epilogue if at least one register is reloaded in
11613 addition to return address. */
11614 offset
= frame
->gp_sp_offset
- sp_offset
;
11615 mask
= frame
->mask
;
11617 if (TARGET_MICROMIPS
)
11618 umips_build_save_restore (fn
, &mask
, &offset
);
11620 for (regno
= GP_REG_LAST
; regno
>= GP_REG_FIRST
; regno
--)
11621 if (BITSET_P (mask
, regno
- GP_REG_FIRST
))
11623 /* Record the ra offset for use by mips_function_profiler. */
11624 if (regno
== RETURN_ADDR_REGNUM
)
11625 cfun
->machine
->frame
.ra_fp_offset
= offset
+ sp_offset
;
11626 mips_save_restore_reg (word_mode
, regno
, offset
, fn
);
11627 offset
-= UNITS_PER_WORD
;
11630 /* This loop must iterate over the same space as its companion in
11631 mips_compute_frame_info. */
11632 offset
= cfun
->machine
->frame
.fp_sp_offset
- sp_offset
;
11633 fpr_mode
= (TARGET_SINGLE_FLOAT
? SFmode
: DFmode
);
11634 for (regno
= FP_REG_LAST
- MAX_FPRS_PER_FMT
+ 1;
11635 regno
>= FP_REG_FIRST
;
11636 regno
-= MAX_FPRS_PER_FMT
)
11637 if (BITSET_P (cfun
->machine
->frame
.fmask
, regno
- FP_REG_FIRST
))
11639 if (!TARGET_FLOAT64
&& TARGET_DOUBLE_FLOAT
11640 && (fixed_regs
[regno
] || fixed_regs
[regno
+ 1]))
11642 if (fixed_regs
[regno
])
11643 mips_save_restore_reg (SFmode
, regno
+ 1, offset
, fn
);
11645 mips_save_restore_reg (SFmode
, regno
, offset
, fn
);
11648 mips_save_restore_reg (fpr_mode
, regno
, offset
, fn
);
11649 offset
-= GET_MODE_SIZE (fpr_mode
);
11653 /* Return true if a move between register REGNO and its save slot (MEM)
11654 can be done in a single move. LOAD_P is true if we are loading
11655 from the slot, false if we are storing to it. */
11658 mips_direct_save_slot_move_p (unsigned int regno
, rtx mem
, bool load_p
)
11660 /* There is a specific MIPS16 instruction for saving $31 to the stack. */
11661 if (TARGET_MIPS16
&& !load_p
&& regno
== RETURN_ADDR_REGNUM
)
11664 return mips_secondary_reload_class (REGNO_REG_CLASS (regno
),
11665 GET_MODE (mem
), mem
, load_p
) == NO_REGS
;
11668 /* Emit a move from SRC to DEST, given that one of them is a register
11669 save slot and that the other is a register. TEMP is a temporary
11670 GPR of the same mode that is available if need be. */
11673 mips_emit_save_slot_move (rtx dest
, rtx src
, rtx temp
)
11675 unsigned int regno
;
11680 regno
= REGNO (src
);
11685 regno
= REGNO (dest
);
11689 if (regno
== cfun
->machine
->global_pointer
&& !mips_must_initialize_gp_p ())
11691 /* We don't yet know whether we'll need this instruction or not.
11692 Postpone the decision by emitting a ghost move. This move
11693 is specifically not frame-related; only the split version is. */
11695 emit_insn (gen_move_gpdi (dest
, src
));
11697 emit_insn (gen_move_gpsi (dest
, src
));
11701 if (regno
== HI_REGNUM
)
11705 mips_emit_move (temp
, src
);
11707 emit_insn (gen_mthidi_ti (gen_rtx_REG (TImode
, MD_REG_FIRST
),
11708 temp
, gen_rtx_REG (DImode
, LO_REGNUM
)));
11710 emit_insn (gen_mthisi_di (gen_rtx_REG (DImode
, MD_REG_FIRST
),
11711 temp
, gen_rtx_REG (SImode
, LO_REGNUM
)));
11716 emit_insn (gen_mfhidi_ti (temp
,
11717 gen_rtx_REG (TImode
, MD_REG_FIRST
)));
11719 emit_insn (gen_mfhisi_di (temp
,
11720 gen_rtx_REG (DImode
, MD_REG_FIRST
)));
11721 mips_emit_move (dest
, temp
);
11724 else if (mips_direct_save_slot_move_p (regno
, mem
, mem
== src
))
11725 mips_emit_move (dest
, src
);
11728 gcc_assert (!reg_overlap_mentioned_p (dest
, temp
));
11729 mips_emit_move (temp
, src
);
11730 mips_emit_move (dest
, temp
);
11733 mips_set_frame_expr (mips_frame_set (dest
, src
));
11736 /* If we're generating n32 or n64 abicalls, and the current function
11737 does not use $28 as its global pointer, emit a cplocal directive.
11738 Use pic_offset_table_rtx as the argument to the directive. */
11741 mips_output_cplocal (void)
11743 if (!TARGET_EXPLICIT_RELOCS
11744 && mips_must_initialize_gp_p ()
11745 && cfun
->machine
->global_pointer
!= GLOBAL_POINTER_REGNUM
)
11746 output_asm_insn (".cplocal %+", 0);
11749 /* Implement TARGET_OUTPUT_FUNCTION_PROLOGUE. */
11752 mips_output_function_prologue (FILE *file
)
11754 const char *fnname
;
11756 /* In MIPS16 mode, we may need to generate a non-MIPS16 stub to handle
11757 floating-point arguments. */
11759 && TARGET_HARD_FLOAT_ABI
11760 && crtl
->args
.info
.fp_code
!= 0)
11761 mips16_build_function_stub ();
11763 /* Get the function name the same way that toplev.c does before calling
11764 assemble_start_function. This is needed so that the name used here
11765 exactly matches the name used in ASM_DECLARE_FUNCTION_NAME. */
11766 fnname
= XSTR (XEXP (DECL_RTL (current_function_decl
), 0), 0);
11767 mips_start_function_definition (fnname
, TARGET_MIPS16
);
11769 /* Output MIPS-specific frame information. */
11770 if (!flag_inhibit_size_directive
)
11772 const struct mips_frame_info
*frame
;
11774 frame
= &cfun
->machine
->frame
;
11776 /* .frame FRAMEREG, FRAMESIZE, RETREG. */
11778 "\t.frame\t%s," HOST_WIDE_INT_PRINT_DEC
",%s\t\t"
11779 "# vars= " HOST_WIDE_INT_PRINT_DEC
11781 ", args= " HOST_WIDE_INT_PRINT_DEC
11782 ", gp= " HOST_WIDE_INT_PRINT_DEC
"\n",
11783 reg_names
[frame_pointer_needed
11784 ? HARD_FRAME_POINTER_REGNUM
11785 : STACK_POINTER_REGNUM
],
11786 (frame_pointer_needed
11787 ? frame
->total_size
- frame
->hard_frame_pointer_offset
11788 : frame
->total_size
),
11789 reg_names
[RETURN_ADDR_REGNUM
],
11791 frame
->num_gp
, frame
->num_fp
,
11793 frame
->cprestore_size
);
11795 /* .mask MASK, OFFSET. */
11796 fprintf (file
, "\t.mask\t0x%08x," HOST_WIDE_INT_PRINT_DEC
"\n",
11797 frame
->mask
, frame
->gp_save_offset
);
11799 /* .fmask MASK, OFFSET. */
11800 fprintf (file
, "\t.fmask\t0x%08x," HOST_WIDE_INT_PRINT_DEC
"\n",
11801 frame
->fmask
, frame
->fp_save_offset
);
11804 /* Handle the initialization of $gp for SVR4 PIC, if applicable.
11805 Also emit the ".set noreorder; .set nomacro" sequence for functions
11807 if (mips_must_initialize_gp_p ()
11808 && mips_current_loadgp_style () == LOADGP_OLDABI
)
11812 /* This is a fixed-form sequence. The position of the
11813 first two instructions is important because of the
11814 way _gp_disp is defined. */
11815 output_asm_insn ("li\t$2,%%hi(_gp_disp)", 0);
11816 output_asm_insn ("addiu\t$3,$pc,%%lo(_gp_disp)", 0);
11817 output_asm_insn ("sll\t$2,16", 0);
11818 output_asm_insn ("addu\t$2,$3", 0);
11822 /* .cpload must be in a .set noreorder but not a
11823 .set nomacro block. */
11824 mips_push_asm_switch (&mips_noreorder
);
11825 output_asm_insn (".cpload\t%^", 0);
11826 if (!cfun
->machine
->all_noreorder_p
)
11827 mips_pop_asm_switch (&mips_noreorder
);
11829 mips_push_asm_switch (&mips_nomacro
);
11832 else if (cfun
->machine
->all_noreorder_p
)
11834 mips_push_asm_switch (&mips_noreorder
);
11835 mips_push_asm_switch (&mips_nomacro
);
11838 /* Tell the assembler which register we're using as the global
11839 pointer. This is needed for thunks, since they can use either
11840 explicit relocs or assembler macros. */
11841 mips_output_cplocal ();
11844 /* Implement TARGET_OUTPUT_FUNCTION_EPILOGUE. */
11847 mips_output_function_epilogue (FILE *)
11849 const char *fnname
;
11851 /* Reinstate the normal $gp. */
11852 SET_REGNO (pic_offset_table_rtx
, GLOBAL_POINTER_REGNUM
);
11853 mips_output_cplocal ();
11855 if (cfun
->machine
->all_noreorder_p
)
11857 mips_pop_asm_switch (&mips_nomacro
);
11858 mips_pop_asm_switch (&mips_noreorder
);
11861 /* Get the function name the same way that toplev.c does before calling
11862 assemble_start_function. This is needed so that the name used here
11863 exactly matches the name used in ASM_DECLARE_FUNCTION_NAME. */
11864 fnname
= XSTR (XEXP (DECL_RTL (current_function_decl
), 0), 0);
11865 mips_end_function_definition (fnname
);
11868 /* Emit an optimisation barrier for accesses to the current frame. */
11871 mips_frame_barrier (void)
11873 emit_clobber (gen_frame_mem (BLKmode
, stack_pointer_rtx
));
11877 /* The __gnu_local_gp symbol. */
11879 static GTY(()) rtx mips_gnu_local_gp
;
11881 /* If we're generating n32 or n64 abicalls, emit instructions
11882 to set up the global pointer. */
11885 mips_emit_loadgp (void)
11887 rtx addr
, offset
, incoming_address
, base
, index
, pic_reg
;
11889 pic_reg
= TARGET_MIPS16
? MIPS16_PIC_TEMP
: pic_offset_table_rtx
;
11890 switch (mips_current_loadgp_style ())
11892 case LOADGP_ABSOLUTE
:
11893 if (mips_gnu_local_gp
== NULL
)
11895 mips_gnu_local_gp
= gen_rtx_SYMBOL_REF (Pmode
, "__gnu_local_gp");
11896 SYMBOL_REF_FLAGS (mips_gnu_local_gp
) |= SYMBOL_FLAG_LOCAL
;
11898 emit_insn (PMODE_INSN (gen_loadgp_absolute
,
11899 (pic_reg
, mips_gnu_local_gp
)));
11902 case LOADGP_OLDABI
:
11903 /* Added by mips_output_function_prologue. */
11906 case LOADGP_NEWABI
:
11907 addr
= XEXP (DECL_RTL (current_function_decl
), 0);
11908 offset
= mips_unspec_address (addr
, SYMBOL_GOTOFF_LOADGP
);
11909 incoming_address
= gen_rtx_REG (Pmode
, PIC_FUNCTION_ADDR_REGNUM
);
11910 emit_insn (PMODE_INSN (gen_loadgp_newabi
,
11911 (pic_reg
, offset
, incoming_address
)));
11915 base
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (VXWORKS_GOTT_BASE
));
11916 index
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (VXWORKS_GOTT_INDEX
));
11917 emit_insn (PMODE_INSN (gen_loadgp_rtp
, (pic_reg
, base
, index
)));
11925 emit_insn (PMODE_INSN (gen_copygp_mips16
,
11926 (pic_offset_table_rtx
, pic_reg
)));
11928 /* Emit a blockage if there are implicit uses of the GP register.
11929 This includes profiled functions, because FUNCTION_PROFILE uses
11931 if (!TARGET_EXPLICIT_RELOCS
|| crtl
->profile
)
11932 emit_insn (gen_loadgp_blockage ());
11935 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
11937 #if PROBE_INTERVAL > 32768
11938 #error Cannot use indexed addressing mode for stack probing
11941 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
11942 inclusive. These are offsets from the current stack pointer. */
11945 mips_emit_probe_stack_range (HOST_WIDE_INT first
, HOST_WIDE_INT size
)
11948 sorry ("-fstack-check=specific not implemented for MIPS16");
11950 /* See if we have a constant small number of probes to generate. If so,
11951 that's the easy case. */
11952 if (first
+ size
<= 32768)
11956 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
11957 it exceeds SIZE. If only one probe is needed, this will not
11958 generate any code. Then probe at FIRST + SIZE. */
11959 for (i
= PROBE_INTERVAL
; i
< size
; i
+= PROBE_INTERVAL
)
11960 emit_stack_probe (plus_constant (Pmode
, stack_pointer_rtx
,
11963 emit_stack_probe (plus_constant (Pmode
, stack_pointer_rtx
,
11967 /* Otherwise, do the same as above, but in a loop. Note that we must be
11968 extra careful with variables wrapping around because we might be at
11969 the very top (or the very bottom) of the address space and we have
11970 to be able to handle this case properly; in particular, we use an
11971 equality test for the loop condition. */
11974 HOST_WIDE_INT rounded_size
;
11975 rtx r3
= MIPS_PROLOGUE_TEMP (Pmode
);
11976 rtx r12
= MIPS_PROLOGUE_TEMP2 (Pmode
);
11978 /* Sanity check for the addressing mode we're going to use. */
11979 gcc_assert (first
<= 32768);
11982 /* Step 1: round SIZE to the previous multiple of the interval. */
11984 rounded_size
= ROUND_DOWN (size
, PROBE_INTERVAL
);
11987 /* Step 2: compute initial and final value of the loop counter. */
11989 /* TEST_ADDR = SP + FIRST. */
11990 emit_insn (gen_rtx_SET (r3
, plus_constant (Pmode
, stack_pointer_rtx
,
11993 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
11994 if (rounded_size
> 32768)
11996 emit_move_insn (r12
, GEN_INT (rounded_size
));
11997 emit_insn (gen_rtx_SET (r12
, gen_rtx_MINUS (Pmode
, r3
, r12
)));
12000 emit_insn (gen_rtx_SET (r12
, plus_constant (Pmode
, r3
,
12004 /* Step 3: the loop
12008 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
12011 while (TEST_ADDR != LAST_ADDR)
12013 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
12014 until it is equal to ROUNDED_SIZE. */
12016 emit_insn (PMODE_INSN (gen_probe_stack_range
, (r3
, r3
, r12
)));
12019 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
12020 that SIZE is equal to ROUNDED_SIZE. */
12022 if (size
!= rounded_size
)
12023 emit_stack_probe (plus_constant (Pmode
, r12
, rounded_size
- size
));
12026 /* Make sure nothing is scheduled before we are done. */
12027 emit_insn (gen_blockage ());
12030 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
12031 absolute addresses. */
12034 mips_output_probe_stack_range (rtx reg1
, rtx reg2
)
12036 static int labelno
= 0;
12037 char loop_lab
[32], tmp
[64];
12040 ASM_GENERATE_INTERNAL_LABEL (loop_lab
, "LPSRL", labelno
++);
12043 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, loop_lab
);
12045 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
12047 xops
[1] = GEN_INT (-PROBE_INTERVAL
);
12048 if (TARGET_64BIT
&& TARGET_LONG64
)
12049 output_asm_insn ("daddiu\t%0,%0,%1", xops
);
12051 output_asm_insn ("addiu\t%0,%0,%1", xops
);
12053 /* Probe at TEST_ADDR, test if TEST_ADDR == LAST_ADDR and branch. */
12055 strcpy (tmp
, "%(%<bne\t%0,%1,");
12056 output_asm_insn (strcat (tmp
, &loop_lab
[1]), xops
);
12058 output_asm_insn ("sd\t$0,0(%0)%)", xops
);
12060 output_asm_insn ("sw\t$0,0(%0)%)", xops
);
12065 /* Return true if X contains a kernel register. */
12068 mips_refers_to_kernel_reg_p (const_rtx x
)
12070 subrtx_iterator::array_type array
;
12071 FOR_EACH_SUBRTX (iter
, array
, x
, NONCONST
)
12072 if (REG_P (*iter
) && KERNEL_REG_P (REGNO (*iter
)))
12077 /* Expand the "prologue" pattern. */
12080 mips_expand_prologue (void)
12082 const struct mips_frame_info
*frame
;
12083 HOST_WIDE_INT size
;
12084 unsigned int nargs
;
12086 if (cfun
->machine
->global_pointer
!= INVALID_REGNUM
)
12088 /* Check whether an insn uses pic_offset_table_rtx, either explicitly
12089 or implicitly. If so, we can commit to using a global pointer
12090 straight away, otherwise we need to defer the decision. */
12091 if (mips_cfun_has_inflexible_gp_ref_p ()
12092 || mips_cfun_has_flexible_gp_ref_p ())
12094 cfun
->machine
->must_initialize_gp_p
= true;
12095 cfun
->machine
->must_restore_gp_when_clobbered_p
= true;
12098 SET_REGNO (pic_offset_table_rtx
, cfun
->machine
->global_pointer
);
12101 frame
= &cfun
->machine
->frame
;
12102 size
= frame
->total_size
;
12104 if (flag_stack_usage_info
)
12105 current_function_static_stack_size
= size
;
12107 if (flag_stack_check
== STATIC_BUILTIN_STACK_CHECK
12108 || flag_stack_clash_protection
)
12110 if (crtl
->is_leaf
&& !cfun
->calls_alloca
)
12112 if (size
> PROBE_INTERVAL
&& size
> get_stack_check_protect ())
12113 mips_emit_probe_stack_range (get_stack_check_protect (),
12114 size
- get_stack_check_protect ());
12117 mips_emit_probe_stack_range (get_stack_check_protect (), size
);
12120 /* Save the registers. Allocate up to MIPS_MAX_FIRST_STACK_STEP
12121 bytes beforehand; this is enough to cover the register save area
12122 without going out of range. */
12123 if (((frame
->mask
| frame
->fmask
| frame
->acc_mask
) != 0)
12124 || frame
->num_cop0_regs
> 0)
12126 HOST_WIDE_INT step1
;
12128 step1
= MIN (size
, MIPS_MAX_FIRST_STACK_STEP
);
12129 if (GENERATE_MIPS16E_SAVE_RESTORE
)
12131 HOST_WIDE_INT offset
;
12132 unsigned int mask
, regno
;
12134 /* Try to merge argument stores into the save instruction. */
12135 nargs
= mips16e_collect_argument_saves ();
12137 /* Build the save instruction. */
12138 mask
= frame
->mask
;
12139 rtx insn
= mips16e_build_save_restore (false, &mask
, &offset
,
12141 RTX_FRAME_RELATED_P (emit_insn (insn
)) = 1;
12142 mips_frame_barrier ();
12145 /* Check if we need to save other registers. */
12146 for (regno
= GP_REG_FIRST
; regno
< GP_REG_LAST
; regno
++)
12147 if (BITSET_P (mask
, regno
- GP_REG_FIRST
))
12149 offset
-= UNITS_PER_WORD
;
12150 mips_save_restore_reg (word_mode
, regno
,
12151 offset
, mips_save_reg
);
12156 if (cfun
->machine
->interrupt_handler_p
)
12158 HOST_WIDE_INT offset
;
12161 /* If this interrupt is using a shadow register set, we need to
12162 get the stack pointer from the previous register set. */
12163 if (cfun
->machine
->use_shadow_register_set
== SHADOW_SET_YES
)
12164 emit_insn (PMODE_INSN (gen_mips_rdpgpr
, (stack_pointer_rtx
,
12165 stack_pointer_rtx
)));
12167 if (!cfun
->machine
->keep_interrupts_masked_p
)
12169 if (cfun
->machine
->int_mask
== INT_MASK_EIC
)
12170 /* Move from COP0 Cause to K0. */
12171 emit_insn (gen_cop0_move (gen_rtx_REG (SImode
, K0_REG_NUM
),
12172 gen_rtx_REG (SImode
, COP0_CAUSE_REG_NUM
)));
12174 /* Move from COP0 EPC to K1. */
12175 emit_insn (gen_cop0_move (gen_rtx_REG (SImode
, K1_REG_NUM
),
12176 gen_rtx_REG (SImode
,
12177 COP0_EPC_REG_NUM
)));
12179 /* Allocate the first part of the frame. */
12180 rtx insn
= gen_add3_insn (stack_pointer_rtx
, stack_pointer_rtx
,
12182 RTX_FRAME_RELATED_P (emit_insn (insn
)) = 1;
12183 mips_frame_barrier ();
12186 /* Start at the uppermost location for saving. */
12187 offset
= frame
->cop0_sp_offset
- size
;
12189 /* Push EPC into its stack slot. */
12190 mem
= gen_frame_mem (word_mode
,
12191 plus_constant (Pmode
, stack_pointer_rtx
,
12193 mips_emit_move (mem
, gen_rtx_REG (word_mode
, K1_REG_NUM
));
12194 offset
-= UNITS_PER_WORD
;
12196 /* Move from COP0 Status to K1. */
12197 emit_insn (gen_cop0_move (gen_rtx_REG (SImode
, K1_REG_NUM
),
12198 gen_rtx_REG (SImode
,
12199 COP0_STATUS_REG_NUM
)));
12201 /* Right justify the RIPL in k0. */
12202 if (!cfun
->machine
->keep_interrupts_masked_p
12203 && cfun
->machine
->int_mask
== INT_MASK_EIC
)
12204 emit_insn (gen_lshrsi3 (gen_rtx_REG (SImode
, K0_REG_NUM
),
12205 gen_rtx_REG (SImode
, K0_REG_NUM
),
12206 GEN_INT (CAUSE_IPL
)));
12208 /* Push Status into its stack slot. */
12209 mem
= gen_frame_mem (word_mode
,
12210 plus_constant (Pmode
, stack_pointer_rtx
,
12212 mips_emit_move (mem
, gen_rtx_REG (word_mode
, K1_REG_NUM
));
12213 offset
-= UNITS_PER_WORD
;
12215 /* Insert the RIPL into our copy of SR (k1) as the new IPL. */
12216 if (!cfun
->machine
->keep_interrupts_masked_p
12217 && cfun
->machine
->int_mask
== INT_MASK_EIC
)
12218 emit_insn (gen_insvsi (gen_rtx_REG (SImode
, K1_REG_NUM
),
12221 gen_rtx_REG (SImode
, K0_REG_NUM
)));
12223 /* Clear all interrupt mask bits up to and including the
12224 handler's interrupt line. */
12225 if (!cfun
->machine
->keep_interrupts_masked_p
12226 && cfun
->machine
->int_mask
!= INT_MASK_EIC
)
12227 emit_insn (gen_insvsi (gen_rtx_REG (SImode
, K1_REG_NUM
),
12228 GEN_INT (cfun
->machine
->int_mask
+ 1),
12230 gen_rtx_REG (SImode
, GP_REG_FIRST
)));
12232 if (!cfun
->machine
->keep_interrupts_masked_p
)
12233 /* Enable interrupts by clearing the KSU ERL and EXL bits.
12234 IE is already the correct value, so we don't have to do
12235 anything explicit. */
12236 emit_insn (gen_insvsi (gen_rtx_REG (SImode
, K1_REG_NUM
),
12239 gen_rtx_REG (SImode
, GP_REG_FIRST
)));
12241 /* Disable interrupts by clearing the KSU, ERL, EXL,
12243 emit_insn (gen_insvsi (gen_rtx_REG (SImode
, K1_REG_NUM
),
12246 gen_rtx_REG (SImode
, GP_REG_FIRST
)));
12248 if (TARGET_HARD_FLOAT
)
12249 /* Disable COP1 for hard-float. This will lead to an exception
12250 if floating-point code is executed in an ISR. */
12251 emit_insn (gen_insvsi (gen_rtx_REG (SImode
, K1_REG_NUM
),
12254 gen_rtx_REG (SImode
, GP_REG_FIRST
)));
12260 rtx insn
= gen_add3_insn (stack_pointer_rtx
,
12263 RTX_FRAME_RELATED_P (emit_insn (insn
)) = 1;
12264 mips_frame_barrier ();
12268 mips_for_each_saved_acc (size
, mips_save_reg
);
12269 mips_for_each_saved_gpr_and_fpr (size
, mips_save_reg
);
12273 /* Allocate the rest of the frame. */
12276 if (SMALL_OPERAND (-size
))
12277 RTX_FRAME_RELATED_P (emit_insn (gen_add3_insn (stack_pointer_rtx
,
12279 GEN_INT (-size
)))) = 1;
12282 mips_emit_move (MIPS_PROLOGUE_TEMP (Pmode
), GEN_INT (size
));
12285 /* There are no instructions to add or subtract registers
12286 from the stack pointer, so use the frame pointer as a
12287 temporary. We should always be using a frame pointer
12288 in this case anyway. */
12289 gcc_assert (frame_pointer_needed
);
12290 mips_emit_move (hard_frame_pointer_rtx
, stack_pointer_rtx
);
12291 emit_insn (gen_sub3_insn (hard_frame_pointer_rtx
,
12292 hard_frame_pointer_rtx
,
12293 MIPS_PROLOGUE_TEMP (Pmode
)));
12294 mips_emit_move (stack_pointer_rtx
, hard_frame_pointer_rtx
);
12297 emit_insn (gen_sub3_insn (stack_pointer_rtx
,
12299 MIPS_PROLOGUE_TEMP (Pmode
)));
12301 /* Describe the combined effect of the previous instructions. */
12302 mips_set_frame_expr
12303 (gen_rtx_SET (stack_pointer_rtx
,
12304 plus_constant (Pmode
, stack_pointer_rtx
, -size
)));
12306 mips_frame_barrier ();
12309 /* Set up the frame pointer, if we're using one. */
12310 if (frame_pointer_needed
)
12312 HOST_WIDE_INT offset
;
12314 offset
= frame
->hard_frame_pointer_offset
;
12317 rtx insn
= mips_emit_move (hard_frame_pointer_rtx
, stack_pointer_rtx
);
12318 RTX_FRAME_RELATED_P (insn
) = 1;
12320 else if (SMALL_OPERAND (offset
))
12322 rtx insn
= gen_add3_insn (hard_frame_pointer_rtx
,
12323 stack_pointer_rtx
, GEN_INT (offset
));
12324 RTX_FRAME_RELATED_P (emit_insn (insn
)) = 1;
12328 mips_emit_move (MIPS_PROLOGUE_TEMP (Pmode
), GEN_INT (offset
));
12329 mips_emit_move (hard_frame_pointer_rtx
, stack_pointer_rtx
);
12330 emit_insn (gen_add3_insn (hard_frame_pointer_rtx
,
12331 hard_frame_pointer_rtx
,
12332 MIPS_PROLOGUE_TEMP (Pmode
)));
12333 mips_set_frame_expr
12334 (gen_rtx_SET (hard_frame_pointer_rtx
,
12335 plus_constant (Pmode
, stack_pointer_rtx
, offset
)));
12339 mips_emit_loadgp ();
12341 /* Initialize the $gp save slot. */
12342 if (mips_cfun_has_cprestore_slot_p ())
12344 rtx base
, mem
, gp
, temp
;
12345 HOST_WIDE_INT offset
;
12347 mips_get_cprestore_base_and_offset (&base
, &offset
, false);
12348 mem
= gen_frame_mem (Pmode
, plus_constant (Pmode
, base
, offset
));
12349 gp
= TARGET_MIPS16
? MIPS16_PIC_TEMP
: pic_offset_table_rtx
;
12350 temp
= (SMALL_OPERAND (offset
)
12351 ? gen_rtx_SCRATCH (Pmode
)
12352 : MIPS_PROLOGUE_TEMP (Pmode
));
12353 emit_insn (PMODE_INSN (gen_potential_cprestore
,
12354 (mem
, GEN_INT (offset
), gp
, temp
)));
12356 mips_get_cprestore_base_and_offset (&base
, &offset
, true);
12357 mem
= gen_frame_mem (Pmode
, plus_constant (Pmode
, base
, offset
));
12358 emit_insn (PMODE_INSN (gen_use_cprestore
, (mem
)));
12361 /* We need to search back to the last use of K0 or K1. */
12362 if (cfun
->machine
->interrupt_handler_p
)
12365 for (insn
= get_last_insn (); insn
!= NULL_RTX
; insn
= PREV_INSN (insn
))
12367 && mips_refers_to_kernel_reg_p (PATTERN (insn
)))
12369 /* Emit a move from K1 to COP0 Status after insn. */
12370 gcc_assert (insn
!= NULL_RTX
);
12371 emit_insn_after (gen_cop0_move (gen_rtx_REG (SImode
, COP0_STATUS_REG_NUM
),
12372 gen_rtx_REG (SImode
, K1_REG_NUM
)),
12376 /* If we are profiling, make sure no instructions are scheduled before
12377 the call to mcount. */
12379 emit_insn (gen_blockage ());
12382 /* Attach all pending register saves to the previous instruction.
12383 Return that instruction. */
12386 mips_epilogue_emit_cfa_restores (void)
12390 insn
= get_last_insn ();
12391 if (mips_epilogue
.cfa_restores
)
12393 gcc_assert (insn
&& !REG_NOTES (insn
));
12394 RTX_FRAME_RELATED_P (insn
) = 1;
12395 REG_NOTES (insn
) = mips_epilogue
.cfa_restores
;
12396 mips_epilogue
.cfa_restores
= 0;
12401 /* Like mips_epilogue_emit_cfa_restores, but also record that the CFA is
12402 now at REG + OFFSET. */
12405 mips_epilogue_set_cfa (rtx reg
, HOST_WIDE_INT offset
)
12409 insn
= mips_epilogue_emit_cfa_restores ();
12410 if (reg
!= mips_epilogue
.cfa_reg
|| offset
!= mips_epilogue
.cfa_offset
)
12412 RTX_FRAME_RELATED_P (insn
) = 1;
12413 REG_NOTES (insn
) = alloc_reg_note (REG_CFA_DEF_CFA
,
12414 plus_constant (Pmode
, reg
, offset
),
12416 mips_epilogue
.cfa_reg
= reg
;
12417 mips_epilogue
.cfa_offset
= offset
;
12421 /* Emit instructions to restore register REG from slot MEM. Also update
12422 the cfa_restores list. */
12425 mips_restore_reg (rtx reg
, rtx mem
)
12427 /* There's no MIPS16 instruction to load $31 directly. Load into
12428 $7 instead and adjust the return insn appropriately. */
12429 if (TARGET_MIPS16
&& REGNO (reg
) == RETURN_ADDR_REGNUM
)
12430 reg
= gen_rtx_REG (GET_MODE (reg
), GP_REG_FIRST
+ 7);
12431 else if (GET_MODE (reg
) == DFmode
12432 && (!TARGET_FLOAT64
12433 || mips_abi
== ABI_32
))
12435 mips_add_cfa_restore (mips_subword (reg
, true));
12436 mips_add_cfa_restore (mips_subword (reg
, false));
12439 mips_add_cfa_restore (reg
);
12441 mips_emit_save_slot_move (reg
, mem
, MIPS_EPILOGUE_TEMP (GET_MODE (reg
)));
12442 if (REGNO (reg
) == REGNO (mips_epilogue
.cfa_reg
))
12443 /* The CFA is currently defined in terms of the register whose
12444 value we have just restored. Redefine the CFA in terms of
12445 the stack pointer. */
12446 mips_epilogue_set_cfa (stack_pointer_rtx
,
12447 mips_epilogue
.cfa_restore_sp_offset
);
12450 /* Emit code to set the stack pointer to BASE + OFFSET, given that
12451 BASE + OFFSET is NEW_FRAME_SIZE bytes below the top of the frame.
12452 BASE, if not the stack pointer, is available as a temporary. */
12455 mips_deallocate_stack (rtx base
, rtx offset
, HOST_WIDE_INT new_frame_size
)
12457 if (base
== stack_pointer_rtx
&& offset
== const0_rtx
)
12460 mips_frame_barrier ();
12461 if (offset
== const0_rtx
)
12463 emit_move_insn (stack_pointer_rtx
, base
);
12464 mips_epilogue_set_cfa (stack_pointer_rtx
, new_frame_size
);
12466 else if (TARGET_MIPS16
&& base
!= stack_pointer_rtx
)
12468 emit_insn (gen_add3_insn (base
, base
, offset
));
12469 mips_epilogue_set_cfa (base
, new_frame_size
);
12470 emit_move_insn (stack_pointer_rtx
, base
);
12474 emit_insn (gen_add3_insn (stack_pointer_rtx
, base
, offset
));
12475 mips_epilogue_set_cfa (stack_pointer_rtx
, new_frame_size
);
12479 /* Emit any instructions needed before a return. */
12482 mips_expand_before_return (void)
12484 /* When using a call-clobbered gp, we start out with unified call
12485 insns that include instructions to restore the gp. We then split
12486 these unified calls after reload. These split calls explicitly
12487 clobber gp, so there is no need to define
12488 PIC_OFFSET_TABLE_REG_CALL_CLOBBERED.
12490 For consistency, we should also insert an explicit clobber of $28
12491 before return insns, so that the post-reload optimizers know that
12492 the register is not live on exit. */
12493 if (TARGET_CALL_CLOBBERED_GP
)
12494 emit_clobber (pic_offset_table_rtx
);
12497 /* Expand an "epilogue" or "sibcall_epilogue" pattern; SIBCALL_P
12501 mips_expand_epilogue (bool sibcall_p
)
12503 const struct mips_frame_info
*frame
;
12504 HOST_WIDE_INT step1
, step2
;
12507 bool use_jraddiusp_p
= false;
12509 if (!sibcall_p
&& mips_can_use_return_insn ())
12511 emit_jump_insn (gen_return ());
12515 /* In MIPS16 mode, if the return value should go into a floating-point
12516 register, we need to call a helper routine to copy it over. */
12517 if (mips16_cfun_returns_in_fpr_p ())
12518 mips16_copy_fpr_return_value ();
12520 /* Split the frame into two. STEP1 is the amount of stack we should
12521 deallocate before restoring the registers. STEP2 is the amount we
12522 should deallocate afterwards.
12524 Start off by assuming that no registers need to be restored. */
12525 frame
= &cfun
->machine
->frame
;
12526 step1
= frame
->total_size
;
12529 /* Work out which register holds the frame address. */
12530 if (!frame_pointer_needed
)
12531 base
= stack_pointer_rtx
;
12534 base
= hard_frame_pointer_rtx
;
12535 step1
-= frame
->hard_frame_pointer_offset
;
12537 mips_epilogue
.cfa_reg
= base
;
12538 mips_epilogue
.cfa_offset
= step1
;
12539 mips_epilogue
.cfa_restores
= NULL_RTX
;
12541 /* If we need to restore registers, deallocate as much stack as
12542 possible in the second step without going out of range. */
12543 if ((frame
->mask
| frame
->fmask
| frame
->acc_mask
) != 0
12544 || frame
->num_cop0_regs
> 0)
12546 step2
= MIN (step1
, MIPS_MAX_FIRST_STACK_STEP
);
12550 /* Get an rtx for STEP1 that we can add to BASE. */
12551 adjust
= GEN_INT (step1
);
12552 if (!SMALL_OPERAND (step1
))
12554 mips_emit_move (MIPS_EPILOGUE_TEMP (Pmode
), adjust
);
12555 adjust
= MIPS_EPILOGUE_TEMP (Pmode
);
12557 mips_deallocate_stack (base
, adjust
, step2
);
12559 /* If we're using addressing macros, $gp is implicitly used by all
12560 SYMBOL_REFs. We must emit a blockage insn before restoring $gp
12562 if (TARGET_CALL_SAVED_GP
&& !TARGET_EXPLICIT_RELOCS
)
12563 emit_insn (gen_blockage ());
12565 mips_epilogue
.cfa_restore_sp_offset
= step2
;
12566 if (GENERATE_MIPS16E_SAVE_RESTORE
&& frame
->mask
!= 0)
12568 unsigned int regno
, mask
;
12569 HOST_WIDE_INT offset
;
12572 /* Generate the restore instruction. */
12573 mask
= frame
->mask
;
12574 restore
= mips16e_build_save_restore (true, &mask
, &offset
, 0, step2
);
12576 /* Restore any other registers manually. */
12577 for (regno
= GP_REG_FIRST
; regno
< GP_REG_LAST
; regno
++)
12578 if (BITSET_P (mask
, regno
- GP_REG_FIRST
))
12580 offset
-= UNITS_PER_WORD
;
12581 mips_save_restore_reg (word_mode
, regno
, offset
, mips_restore_reg
);
12584 /* Restore the remaining registers and deallocate the final bit
12586 mips_frame_barrier ();
12587 emit_insn (restore
);
12588 mips_epilogue_set_cfa (stack_pointer_rtx
, 0);
12592 /* Restore the registers. */
12593 mips_for_each_saved_acc (frame
->total_size
- step2
, mips_restore_reg
);
12594 mips_for_each_saved_gpr_and_fpr (frame
->total_size
- step2
,
12597 if (cfun
->machine
->interrupt_handler_p
)
12599 HOST_WIDE_INT offset
;
12602 offset
= frame
->cop0_sp_offset
- (frame
->total_size
- step2
);
12604 /* Restore the original EPC. */
12605 mem
= gen_frame_mem (word_mode
,
12606 plus_constant (Pmode
, stack_pointer_rtx
,
12608 mips_emit_move (gen_rtx_REG (word_mode
, K1_REG_NUM
), mem
);
12609 offset
-= UNITS_PER_WORD
;
12611 /* Move to COP0 EPC. */
12612 emit_insn (gen_cop0_move (gen_rtx_REG (SImode
, COP0_EPC_REG_NUM
),
12613 gen_rtx_REG (SImode
, K1_REG_NUM
)));
12615 /* Restore the original Status. */
12616 mem
= gen_frame_mem (word_mode
,
12617 plus_constant (Pmode
, stack_pointer_rtx
,
12619 mips_emit_move (gen_rtx_REG (word_mode
, K1_REG_NUM
), mem
);
12620 offset
-= UNITS_PER_WORD
;
12622 /* If we don't use shadow register set, we need to update SP. */
12623 if (cfun
->machine
->use_shadow_register_set
== SHADOW_SET_NO
)
12624 mips_deallocate_stack (stack_pointer_rtx
, GEN_INT (step2
), 0);
12626 /* The choice of position is somewhat arbitrary in this case. */
12627 mips_epilogue_emit_cfa_restores ();
12629 /* Move to COP0 Status. */
12630 emit_insn (gen_cop0_move (gen_rtx_REG (SImode
, COP0_STATUS_REG_NUM
),
12631 gen_rtx_REG (SImode
, K1_REG_NUM
)));
12633 else if (TARGET_MICROMIPS
12634 && !crtl
->calls_eh_return
12637 && mips_unsigned_immediate_p (step2
, 5, 2))
12638 use_jraddiusp_p
= true;
12640 /* Deallocate the final bit of the frame. */
12641 mips_deallocate_stack (stack_pointer_rtx
, GEN_INT (step2
), 0);
12644 if (cfun
->machine
->use_frame_header_for_callee_saved_regs
)
12645 mips_epilogue_emit_cfa_restores ();
12646 else if (!use_jraddiusp_p
)
12647 gcc_assert (!mips_epilogue
.cfa_restores
);
12649 /* Add in the __builtin_eh_return stack adjustment. We need to
12650 use a temporary in MIPS16 code. */
12651 if (crtl
->calls_eh_return
)
12655 mips_emit_move (MIPS_EPILOGUE_TEMP (Pmode
), stack_pointer_rtx
);
12656 emit_insn (gen_add3_insn (MIPS_EPILOGUE_TEMP (Pmode
),
12657 MIPS_EPILOGUE_TEMP (Pmode
),
12658 EH_RETURN_STACKADJ_RTX
));
12659 mips_emit_move (stack_pointer_rtx
, MIPS_EPILOGUE_TEMP (Pmode
));
12662 emit_insn (gen_add3_insn (stack_pointer_rtx
,
12664 EH_RETURN_STACKADJ_RTX
));
12669 mips_expand_before_return ();
12670 if (cfun
->machine
->interrupt_handler_p
)
12672 /* Interrupt handlers generate eret or deret. */
12673 if (cfun
->machine
->use_debug_exception_return_p
)
12674 emit_jump_insn (gen_mips_deret ());
12676 emit_jump_insn (gen_mips_eret ());
12682 /* When generating MIPS16 code, the normal
12683 mips_for_each_saved_gpr_and_fpr path will restore the return
12684 address into $7 rather than $31. */
12686 && !GENERATE_MIPS16E_SAVE_RESTORE
12687 && BITSET_P (frame
->mask
, RETURN_ADDR_REGNUM
))
12689 /* simple_returns cannot rely on values that are only available
12690 on paths through the epilogue (because return paths that do
12691 not pass through the epilogue may nevertheless reuse a
12692 simple_return that occurs at the end of the epilogue).
12693 Use a normal return here instead. */
12694 rtx reg
= gen_rtx_REG (Pmode
, GP_REG_FIRST
+ 7);
12695 pat
= gen_return_internal (reg
);
12697 else if (use_jraddiusp_p
)
12698 pat
= gen_jraddiusp (GEN_INT (step2
));
12701 rtx reg
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
12702 pat
= gen_simple_return_internal (reg
);
12704 emit_jump_insn (pat
);
12705 if (use_jraddiusp_p
)
12706 mips_epilogue_set_cfa (stack_pointer_rtx
, step2
);
12710 /* Search from the beginning to the first use of K0 or K1. */
12711 if (cfun
->machine
->interrupt_handler_p
12712 && !cfun
->machine
->keep_interrupts_masked_p
)
12714 for (insn
= get_insns (); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
12716 && mips_refers_to_kernel_reg_p (PATTERN (insn
)))
12718 gcc_assert (insn
!= NULL_RTX
);
12719 /* Insert disable interrupts before the first use of K0 or K1. */
12720 emit_insn_before (gen_mips_di (), insn
);
12721 emit_insn_before (gen_mips_ehb (), insn
);
12725 /* Return nonzero if this function is known to have a null epilogue.
12726 This allows the optimizer to omit jumps to jumps if no stack
12730 mips_can_use_return_insn (void)
12732 /* Interrupt handlers need to go through the epilogue. */
12733 if (cfun
->machine
->interrupt_handler_p
)
12736 if (!reload_completed
)
12742 /* In MIPS16 mode, a function that returns a floating-point value
12743 needs to arrange to copy the return value into the floating-point
12745 if (mips16_cfun_returns_in_fpr_p ())
12748 return (cfun
->machine
->frame
.total_size
== 0
12749 && !cfun
->machine
->use_frame_header_for_callee_saved_regs
);
12752 /* Return true if register REGNO can store a value of mode MODE.
12753 The result of this function is cached in mips_hard_regno_mode_ok. */
12756 mips_hard_regno_mode_ok_uncached (unsigned int regno
, machine_mode mode
)
12759 enum mode_class mclass
;
12761 if (mode
== CCV2mode
)
12762 return (ISA_HAS_8CC
12763 && ST_REG_P (regno
)
12764 && (regno
- ST_REG_FIRST
) % 2 == 0);
12766 if (mode
== CCV4mode
)
12767 return (ISA_HAS_8CC
12768 && ST_REG_P (regno
)
12769 && (regno
- ST_REG_FIRST
) % 4 == 0);
12771 if (mode
== CCmode
)
12772 return ISA_HAS_8CC
? ST_REG_P (regno
) : regno
== FPSW_REGNUM
;
12774 size
= GET_MODE_SIZE (mode
);
12775 mclass
= GET_MODE_CLASS (mode
);
12777 if (GP_REG_P (regno
) && mode
!= CCFmode
&& !MSA_SUPPORTED_MODE_P (mode
))
12778 return ((regno
- GP_REG_FIRST
) & 1) == 0 || size
<= UNITS_PER_WORD
;
12780 /* For MSA, allow TImode and 128-bit vector modes in all FPR. */
12781 if (FP_REG_P (regno
) && MSA_SUPPORTED_MODE_P (mode
))
12784 if (FP_REG_P (regno
)
12785 && (((regno
- FP_REG_FIRST
) % MAX_FPRS_PER_FMT
) == 0
12786 || (MIN_FPRS_PER_FMT
== 1 && size
<= UNITS_PER_FPREG
)))
12788 /* Deny use of odd-numbered registers for 32-bit data for
12789 the o32 FP64A ABI. */
12790 if (TARGET_O32_FP64A_ABI
&& size
<= 4 && (regno
& 1) != 0)
12793 /* The FPXX ABI requires double-precision values to be placed in
12794 even-numbered registers. Disallow odd-numbered registers with
12795 CCFmode because CCFmode double-precision compares will write a
12796 64-bit value to a register. */
12797 if (mode
== CCFmode
)
12798 return !(TARGET_FLOATXX
&& (regno
& 1) != 0);
12800 /* Allow 64-bit vector modes for Loongson-2E/2F. */
12801 if (TARGET_LOONGSON_VECTORS
12802 && (mode
== V2SImode
12803 || mode
== V4HImode
12804 || mode
== V8QImode
12805 || mode
== DImode
))
12808 if (mclass
== MODE_FLOAT
12809 || mclass
== MODE_COMPLEX_FLOAT
12810 || mclass
== MODE_VECTOR_FLOAT
)
12811 return size
<= UNITS_PER_FPVALUE
;
12813 /* Allow integer modes that fit into a single register. We need
12814 to put integers into FPRs when using instructions like CVT
12815 and TRUNC. There's no point allowing sizes smaller than a word,
12816 because the FPU has no appropriate load/store instructions. */
12817 if (mclass
== MODE_INT
)
12818 return size
>= MIN_UNITS_PER_WORD
&& size
<= UNITS_PER_FPREG
;
12821 /* Don't allow vector modes in accumulators. */
12822 if (ACC_REG_P (regno
)
12823 && !VECTOR_MODE_P (mode
)
12824 && (INTEGRAL_MODE_P (mode
) || ALL_FIXED_POINT_MODE_P (mode
)))
12826 if (MD_REG_P (regno
))
12828 /* After a multiplication or division, clobbering HI makes
12829 the value of LO unpredictable, and vice versa. This means
12830 that, for all interesting cases, HI and LO are effectively
12833 We model this by requiring that any value that uses HI
12835 if (size
<= UNITS_PER_WORD
* 2)
12836 return regno
== (size
<= UNITS_PER_WORD
? LO_REGNUM
: MD_REG_FIRST
);
12840 /* DSP accumulators do not have the same restrictions as
12841 HI and LO, so we can treat them as normal doubleword
12843 if (size
<= UNITS_PER_WORD
)
12846 if (size
<= UNITS_PER_WORD
* 2
12847 && ((regno
- DSP_ACC_REG_FIRST
) & 1) == 0)
12852 if (ALL_COP_REG_P (regno
))
12853 return mclass
== MODE_INT
&& size
<= UNITS_PER_WORD
;
12855 if (regno
== GOT_VERSION_REGNUM
)
12856 return mode
== SImode
;
12861 /* Implement TARGET_HARD_REGNO_MODE_OK. */
12864 mips_hard_regno_mode_ok (unsigned int regno
, machine_mode mode
)
12866 return mips_hard_regno_mode_ok_p
[mode
][regno
];
12869 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */
12872 mips_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED
,
12873 unsigned int new_reg
)
12875 /* Interrupt functions can only use registers that have already been
12876 saved by the prologue, even if they would normally be call-clobbered. */
12877 if (cfun
->machine
->interrupt_handler_p
&& !df_regs_ever_live_p (new_reg
))
12883 /* Return nonzero if register REGNO can be used as a scratch register
12887 mips_hard_regno_scratch_ok (unsigned int regno
)
12889 /* See mips_hard_regno_rename_ok. */
12890 if (cfun
->machine
->interrupt_handler_p
&& !df_regs_ever_live_p (regno
))
12896 /* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED. Odd-numbered
12897 single-precision registers are not considered callee-saved for o32
12898 FPXX as they will be clobbered when run on an FR=1 FPU. MSA vector
12899 registers with MODE > 64 bits are part clobbered too. */
12902 mips_hard_regno_call_part_clobbered (unsigned int regno
, machine_mode mode
)
12905 && hard_regno_nregs (regno
, mode
) == 1
12906 && FP_REG_P (regno
)
12907 && (regno
& 1) != 0)
12910 if (ISA_HAS_MSA
&& FP_REG_P (regno
) && GET_MODE_SIZE (mode
) > 8)
12916 /* Implement TARGET_HARD_REGNO_NREGS. */
12918 static unsigned int
12919 mips_hard_regno_nregs (unsigned int regno
, machine_mode mode
)
12921 if (ST_REG_P (regno
))
12922 /* The size of FP status registers is always 4, because they only hold
12923 CCmode values, and CCmode is always considered to be 4 bytes wide. */
12924 return (GET_MODE_SIZE (mode
) + 3) / 4;
12926 if (FP_REG_P (regno
))
12928 if (MSA_SUPPORTED_MODE_P (mode
))
12931 return (GET_MODE_SIZE (mode
) + UNITS_PER_FPREG
- 1) / UNITS_PER_FPREG
;
12934 /* All other registers are word-sized. */
12935 return (GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
12938 /* Implement CLASS_MAX_NREGS, taking the maximum of the cases
12939 in mips_hard_regno_nregs. */
12942 mips_class_max_nregs (enum reg_class rclass
, machine_mode mode
)
12948 COPY_HARD_REG_SET (left
, reg_class_contents
[(int) rclass
]);
12949 if (hard_reg_set_intersect_p (left
, reg_class_contents
[(int) ST_REGS
]))
12951 if (mips_hard_regno_mode_ok (ST_REG_FIRST
, mode
))
12952 size
= MIN (size
, 4);
12954 AND_COMPL_HARD_REG_SET (left
, reg_class_contents
[(int) ST_REGS
]);
12956 if (hard_reg_set_intersect_p (left
, reg_class_contents
[(int) FP_REGS
]))
12958 if (mips_hard_regno_mode_ok (FP_REG_FIRST
, mode
))
12960 if (MSA_SUPPORTED_MODE_P (mode
))
12961 size
= MIN (size
, UNITS_PER_MSA_REG
);
12963 size
= MIN (size
, UNITS_PER_FPREG
);
12966 AND_COMPL_HARD_REG_SET (left
, reg_class_contents
[(int) FP_REGS
]);
12968 if (!hard_reg_set_empty_p (left
))
12969 size
= MIN (size
, UNITS_PER_WORD
);
12970 return (GET_MODE_SIZE (mode
) + size
- 1) / size
;
12973 /* Implement TARGET_CAN_CHANGE_MODE_CLASS. */
12976 mips_can_change_mode_class (machine_mode from
,
12977 machine_mode to
, reg_class_t rclass
)
12979 /* Allow conversions between different Loongson integer vectors,
12980 and between those vectors and DImode. */
12981 if (GET_MODE_SIZE (from
) == 8 && GET_MODE_SIZE (to
) == 8
12982 && INTEGRAL_MODE_P (from
) && INTEGRAL_MODE_P (to
))
12985 /* Allow conversions between different MSA vector modes. */
12986 if (MSA_SUPPORTED_MODE_P (from
) && MSA_SUPPORTED_MODE_P (to
))
12989 /* Otherwise, there are several problems with changing the modes of
12990 values in floating-point registers:
12992 - When a multi-word value is stored in paired floating-point
12993 registers, the first register always holds the low word. We
12994 therefore can't allow FPRs to change between single-word and
12995 multi-word modes on big-endian targets.
12997 - GCC assumes that each word of a multiword register can be
12998 accessed individually using SUBREGs. This is not true for
12999 floating-point registers if they are bigger than a word.
13001 - Loading a 32-bit value into a 64-bit floating-point register
13002 will not sign-extend the value, despite what LOAD_EXTEND_OP
13003 says. We can't allow FPRs to change from SImode to a wider
13004 mode on 64-bit targets.
13006 - If the FPU has already interpreted a value in one format, we
13007 must not ask it to treat the value as having a different
13010 We therefore disallow all mode changes involving FPRs. */
13012 return !reg_classes_intersect_p (FP_REGS
, rclass
);
13015 /* Implement target hook small_register_classes_for_mode_p. */
13018 mips_small_register_classes_for_mode_p (machine_mode mode
13021 return TARGET_MIPS16
;
13024 /* Return true if moves in mode MODE can use the FPU's mov.fmt instruction,
13025 or use the MSA's move.v instruction. */
13028 mips_mode_ok_for_mov_fmt_p (machine_mode mode
)
13034 return TARGET_HARD_FLOAT
;
13037 return TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
;
13040 return TARGET_HARD_FLOAT
&& TARGET_PAIRED_SINGLE_FLOAT
;
13043 return MSA_SUPPORTED_MODE_P (mode
);
13047 /* Implement TARGET_MODES_TIEABLE_P. */
13050 mips_modes_tieable_p (machine_mode mode1
, machine_mode mode2
)
13052 /* FPRs allow no mode punning, so it's not worth tying modes if we'd
13053 prefer to put one of them in FPRs. */
13054 return (mode1
== mode2
13055 || (!mips_mode_ok_for_mov_fmt_p (mode1
)
13056 && !mips_mode_ok_for_mov_fmt_p (mode2
)));
13059 /* Implement TARGET_PREFERRED_RELOAD_CLASS. */
13062 mips_preferred_reload_class (rtx x
, reg_class_t rclass
)
13064 if (mips_dangerous_for_la25_p (x
) && reg_class_subset_p (LEA_REGS
, rclass
))
13067 if (reg_class_subset_p (FP_REGS
, rclass
)
13068 && mips_mode_ok_for_mov_fmt_p (GET_MODE (x
)))
13071 if (reg_class_subset_p (GR_REGS
, rclass
))
13074 if (TARGET_MIPS16
&& reg_class_subset_p (M16_REGS
, rclass
))
13080 /* RCLASS is a class involved in a REGISTER_MOVE_COST calculation.
13081 Return a "canonical" class to represent it in later calculations. */
13084 mips_canonicalize_move_class (reg_class_t rclass
)
13086 /* All moves involving accumulator registers have the same cost. */
13087 if (reg_class_subset_p (rclass
, ACC_REGS
))
13090 /* Likewise promote subclasses of general registers to the most
13091 interesting containing class. */
13092 if (TARGET_MIPS16
&& reg_class_subset_p (rclass
, M16_REGS
))
13094 else if (reg_class_subset_p (rclass
, GENERAL_REGS
))
13095 rclass
= GENERAL_REGS
;
13100 /* Return the cost of moving a value from a register of class FROM to a GPR.
13101 Return 0 for classes that are unions of other classes handled by this
13105 mips_move_to_gpr_cost (reg_class_t from
)
13111 /* A MIPS16 MOVE instruction, or a non-MIPS16 MOVE macro. */
13115 /* MFLO and MFHI. */
13125 /* This choice of value is historical. */
13133 /* Return the cost of moving a value from a GPR to a register of class TO.
13134 Return 0 for classes that are unions of other classes handled by this
13138 mips_move_from_gpr_cost (reg_class_t to
)
13144 /* A MIPS16 MOVE instruction, or a non-MIPS16 MOVE macro. */
13148 /* MTLO and MTHI. */
13158 /* This choice of value is historical. */
13166 /* Implement TARGET_REGISTER_MOVE_COST. Return 0 for classes that are the
13167 maximum of the move costs for subclasses; regclass will work out
13168 the maximum for us. */
13171 mips_register_move_cost (machine_mode mode
,
13172 reg_class_t from
, reg_class_t to
)
13177 from
= mips_canonicalize_move_class (from
);
13178 to
= mips_canonicalize_move_class (to
);
13180 /* Handle moves that can be done without using general-purpose registers. */
13181 if (from
== FP_REGS
)
13183 if (to
== FP_REGS
&& mips_mode_ok_for_mov_fmt_p (mode
))
13188 /* Handle cases in which only one class deviates from the ideal. */
13189 dregs
= TARGET_MIPS16
? M16_REGS
: GENERAL_REGS
;
13191 return mips_move_from_gpr_cost (to
);
13193 return mips_move_to_gpr_cost (from
);
13195 /* Handles cases that require a GPR temporary. */
13196 cost1
= mips_move_to_gpr_cost (from
);
13199 cost2
= mips_move_from_gpr_cost (to
);
13201 return cost1
+ cost2
;
13207 /* Implement TARGET_REGISTER_PRIORITY. */
13210 mips_register_priority (int hard_regno
)
13212 /* Treat MIPS16 registers with higher priority than other regs. */
13214 && TEST_HARD_REG_BIT (reg_class_contents
[M16_REGS
], hard_regno
))
13219 /* Implement TARGET_MEMORY_MOVE_COST. */
13222 mips_memory_move_cost (machine_mode mode
, reg_class_t rclass
, bool in
)
13224 return (mips_cost
->memory_latency
13225 + memory_move_secondary_cost (mode
, rclass
, in
));
13228 /* Implement TARGET_SECONDARY_MEMORY_NEEDED.
13230 When targeting the o32 FPXX ABI, all moves with a length of doubleword
13231 or greater must be performed by FR-mode-aware instructions.
13232 This can be achieved using MFHC1/MTHC1 when these instructions are
13233 available but otherwise moves must go via memory.
13234 For the o32 FP64A ABI, all odd-numbered moves with a length of
13235 doubleword or greater are required to use memory. Using MTC1/MFC1
13236 to access the lower-half of these registers would require a forbidden
13237 single-precision access. We require all double-word moves to use
13238 memory because adding even and odd floating-point registers classes
13239 would have a significant impact on the backend. */
13242 mips_secondary_memory_needed (machine_mode mode
, reg_class_t class1
,
13243 reg_class_t class2
)
13245 /* Ignore spilled pseudos. */
13246 if (lra_in_progress
&& (class1
== NO_REGS
|| class2
== NO_REGS
))
13249 if (((class1
== FP_REGS
) != (class2
== FP_REGS
))
13250 && ((TARGET_FLOATXX
&& !ISA_HAS_MXHC1
)
13251 || TARGET_O32_FP64A_ABI
)
13252 && GET_MODE_SIZE (mode
) >= 8)
13258 /* Return the register class required for a secondary register when
13259 copying between one of the registers in RCLASS and value X, which
13260 has mode MODE. X is the source of the move if IN_P, otherwise it
13261 is the destination. Return NO_REGS if no secondary register is
13265 mips_secondary_reload_class (enum reg_class rclass
,
13266 machine_mode mode
, rtx x
, bool)
13270 /* If X is a constant that cannot be loaded into $25, it must be loaded
13271 into some other GPR. No other register class allows a direct move. */
13272 if (mips_dangerous_for_la25_p (x
))
13273 return reg_class_subset_p (rclass
, LEA_REGS
) ? NO_REGS
: LEA_REGS
;
13275 regno
= true_regnum (x
);
13278 /* In MIPS16 mode, every move must involve a member of M16_REGS. */
13279 if (!reg_class_subset_p (rclass
, M16_REGS
) && !M16_REG_P (regno
))
13285 /* Copying from accumulator registers to anywhere other than a general
13286 register requires a temporary general register. */
13287 if (reg_class_subset_p (rclass
, ACC_REGS
))
13288 return GP_REG_P (regno
) ? NO_REGS
: GR_REGS
;
13289 if (ACC_REG_P (regno
))
13290 return reg_class_subset_p (rclass
, GR_REGS
) ? NO_REGS
: GR_REGS
;
13292 if (reg_class_subset_p (rclass
, FP_REGS
))
13296 && (GET_MODE_SIZE (mode
) == 4 || GET_MODE_SIZE (mode
) == 8)))
13297 /* In this case we can use lwc1, swc1, ldc1 or sdc1. We'll use
13298 pairs of lwc1s and swc1s if ldc1 and sdc1 are not supported. */
13301 if (MEM_P (x
) && MSA_SUPPORTED_MODE_P (mode
))
13302 /* In this case we can use MSA LD.* and ST.*. */
13305 if (GP_REG_P (regno
) || x
== CONST0_RTX (mode
))
13306 /* In this case we can use mtc1, mfc1, dmtc1 or dmfc1. */
13309 if (CONSTANT_P (x
) && !targetm
.cannot_force_const_mem (mode
, x
))
13310 /* We can force the constant to memory and use lwc1
13311 and ldc1. As above, we will use pairs of lwc1s if
13312 ldc1 is not supported. */
13315 if (FP_REG_P (regno
) && mips_mode_ok_for_mov_fmt_p (mode
))
13316 /* In this case we can use mov.fmt. */
13319 /* Otherwise, we need to reload through an integer register. */
13322 if (FP_REG_P (regno
))
13323 return reg_class_subset_p (rclass
, GR_REGS
) ? NO_REGS
: GR_REGS
;
13328 /* Implement TARGET_MODE_REP_EXTENDED. */
13331 mips_mode_rep_extended (scalar_int_mode mode
, scalar_int_mode mode_rep
)
13333 /* On 64-bit targets, SImode register values are sign-extended to DImode. */
13334 if (TARGET_64BIT
&& mode
== SImode
&& mode_rep
== DImode
)
13335 return SIGN_EXTEND
;
13340 /* Implement TARGET_VALID_POINTER_MODE. */
13343 mips_valid_pointer_mode (scalar_int_mode mode
)
13345 return mode
== SImode
|| (TARGET_64BIT
&& mode
== DImode
);
13348 /* Implement TARGET_VECTOR_MODE_SUPPORTED_P. */
13351 mips_vector_mode_supported_p (machine_mode mode
)
13356 return TARGET_PAIRED_SINGLE_FLOAT
;
13371 return TARGET_LOONGSON_VECTORS
;
13374 return MSA_SUPPORTED_MODE_P (mode
);
13378 /* Implement TARGET_SCALAR_MODE_SUPPORTED_P. */
13381 mips_scalar_mode_supported_p (scalar_mode mode
)
13383 if (ALL_FIXED_POINT_MODE_P (mode
)
13384 && GET_MODE_PRECISION (mode
) <= 2 * BITS_PER_WORD
)
13387 return default_scalar_mode_supported_p (mode
);
13390 /* Implement TARGET_VECTORIZE_PREFERRED_SIMD_MODE. */
13392 static machine_mode
13393 mips_preferred_simd_mode (scalar_mode mode
)
13395 if (TARGET_PAIRED_SINGLE_FLOAT
13425 /* Implement TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES. */
13428 mips_autovectorize_vector_sizes (vector_sizes
*sizes
)
13431 sizes
->safe_push (16);
13434 /* Implement TARGET_INIT_LIBFUNCS. */
13437 mips_init_libfuncs (void)
13439 if (TARGET_FIX_VR4120
)
13441 /* Register the special divsi3 and modsi3 functions needed to work
13442 around VR4120 division errata. */
13443 set_optab_libfunc (sdiv_optab
, SImode
, "__vr4120_divsi3");
13444 set_optab_libfunc (smod_optab
, SImode
, "__vr4120_modsi3");
13447 if (TARGET_MIPS16
&& TARGET_HARD_FLOAT_ABI
)
13449 /* Register the MIPS16 -mhard-float stubs. */
13450 set_optab_libfunc (add_optab
, SFmode
, "__mips16_addsf3");
13451 set_optab_libfunc (sub_optab
, SFmode
, "__mips16_subsf3");
13452 set_optab_libfunc (smul_optab
, SFmode
, "__mips16_mulsf3");
13453 set_optab_libfunc (sdiv_optab
, SFmode
, "__mips16_divsf3");
13455 set_optab_libfunc (eq_optab
, SFmode
, "__mips16_eqsf2");
13456 set_optab_libfunc (ne_optab
, SFmode
, "__mips16_nesf2");
13457 set_optab_libfunc (gt_optab
, SFmode
, "__mips16_gtsf2");
13458 set_optab_libfunc (ge_optab
, SFmode
, "__mips16_gesf2");
13459 set_optab_libfunc (lt_optab
, SFmode
, "__mips16_ltsf2");
13460 set_optab_libfunc (le_optab
, SFmode
, "__mips16_lesf2");
13461 set_optab_libfunc (unord_optab
, SFmode
, "__mips16_unordsf2");
13463 set_conv_libfunc (sfix_optab
, SImode
, SFmode
, "__mips16_fix_truncsfsi");
13464 set_conv_libfunc (sfloat_optab
, SFmode
, SImode
, "__mips16_floatsisf");
13465 set_conv_libfunc (ufloat_optab
, SFmode
, SImode
, "__mips16_floatunsisf");
13467 if (TARGET_DOUBLE_FLOAT
)
13469 set_optab_libfunc (add_optab
, DFmode
, "__mips16_adddf3");
13470 set_optab_libfunc (sub_optab
, DFmode
, "__mips16_subdf3");
13471 set_optab_libfunc (smul_optab
, DFmode
, "__mips16_muldf3");
13472 set_optab_libfunc (sdiv_optab
, DFmode
, "__mips16_divdf3");
13474 set_optab_libfunc (eq_optab
, DFmode
, "__mips16_eqdf2");
13475 set_optab_libfunc (ne_optab
, DFmode
, "__mips16_nedf2");
13476 set_optab_libfunc (gt_optab
, DFmode
, "__mips16_gtdf2");
13477 set_optab_libfunc (ge_optab
, DFmode
, "__mips16_gedf2");
13478 set_optab_libfunc (lt_optab
, DFmode
, "__mips16_ltdf2");
13479 set_optab_libfunc (le_optab
, DFmode
, "__mips16_ledf2");
13480 set_optab_libfunc (unord_optab
, DFmode
, "__mips16_unorddf2");
13482 set_conv_libfunc (sext_optab
, DFmode
, SFmode
,
13483 "__mips16_extendsfdf2");
13484 set_conv_libfunc (trunc_optab
, SFmode
, DFmode
,
13485 "__mips16_truncdfsf2");
13486 set_conv_libfunc (sfix_optab
, SImode
, DFmode
,
13487 "__mips16_fix_truncdfsi");
13488 set_conv_libfunc (sfloat_optab
, DFmode
, SImode
,
13489 "__mips16_floatsidf");
13490 set_conv_libfunc (ufloat_optab
, DFmode
, SImode
,
13491 "__mips16_floatunsidf");
13495 /* The MIPS16 ISA does not have an encoding for "sync", so we rely
13496 on an external non-MIPS16 routine to implement __sync_synchronize.
13497 Similarly for the rest of the ll/sc libfuncs. */
13500 synchronize_libfunc
= init_one_libfunc ("__sync_synchronize");
13501 init_sync_libfuncs (UNITS_PER_WORD
);
13505 /* Build up a multi-insn sequence that loads label TARGET into $AT. */
13508 mips_process_load_label (rtx target
)
13510 rtx base
, gp
, intop
;
13511 HOST_WIDE_INT offset
;
13513 mips_multi_start ();
13517 mips_multi_add_insn ("lw\t%@,%%got_page(%0)(%+)", target
, 0);
13518 mips_multi_add_insn ("addiu\t%@,%@,%%got_ofst(%0)", target
, 0);
13522 mips_multi_add_insn ("ld\t%@,%%got_page(%0)(%+)", target
, 0);
13523 mips_multi_add_insn ("daddiu\t%@,%@,%%got_ofst(%0)", target
, 0);
13527 gp
= pic_offset_table_rtx
;
13528 if (mips_cfun_has_cprestore_slot_p ())
13530 gp
= gen_rtx_REG (Pmode
, AT_REGNUM
);
13531 mips_get_cprestore_base_and_offset (&base
, &offset
, true);
13532 if (!SMALL_OPERAND (offset
))
13534 intop
= GEN_INT (CONST_HIGH_PART (offset
));
13535 mips_multi_add_insn ("lui\t%0,%1", gp
, intop
, 0);
13536 mips_multi_add_insn ("addu\t%0,%0,%1", gp
, base
, 0);
13539 offset
= CONST_LOW_PART (offset
);
13541 intop
= GEN_INT (offset
);
13542 if (ISA_HAS_LOAD_DELAY
)
13543 mips_multi_add_insn ("lw\t%0,%1(%2)%#", gp
, intop
, base
, 0);
13545 mips_multi_add_insn ("lw\t%0,%1(%2)", gp
, intop
, base
, 0);
13547 if (ISA_HAS_LOAD_DELAY
)
13548 mips_multi_add_insn ("lw\t%@,%%got(%0)(%1)%#", target
, gp
, 0);
13550 mips_multi_add_insn ("lw\t%@,%%got(%0)(%1)", target
, gp
, 0);
13551 mips_multi_add_insn ("addiu\t%@,%@,%%lo(%0)", target
, 0);
13556 /* Return the number of instructions needed to load a label into $AT. */
13558 static unsigned int
13559 mips_load_label_num_insns (void)
13561 if (cfun
->machine
->load_label_num_insns
== 0)
13563 mips_process_load_label (pc_rtx
);
13564 cfun
->machine
->load_label_num_insns
= mips_multi_num_insns
;
13566 return cfun
->machine
->load_label_num_insns
;
13569 /* Emit an asm sequence to start a noat block and load the address
13570 of a label into $1. */
13573 mips_output_load_label (rtx target
)
13575 mips_push_asm_switch (&mips_noat
);
13576 if (TARGET_EXPLICIT_RELOCS
)
13578 mips_process_load_label (target
);
13579 mips_multi_write ();
13583 if (Pmode
== DImode
)
13584 output_asm_insn ("dla\t%@,%0", &target
);
13586 output_asm_insn ("la\t%@,%0", &target
);
13590 /* Return the length of INSN. LENGTH is the initial length computed by
13591 attributes in the machine-description file. */
13594 mips_adjust_insn_length (rtx_insn
*insn
, int length
)
13596 /* mips.md uses MAX_PIC_BRANCH_LENGTH as a placeholder for the length
13597 of a PIC long-branch sequence. Substitute the correct value. */
13598 if (length
== MAX_PIC_BRANCH_LENGTH
13600 && INSN_CODE (insn
) >= 0
13601 && get_attr_type (insn
) == TYPE_BRANCH
)
13603 /* Add the branch-over instruction and its delay slot, if this
13604 is a conditional branch. */
13605 length
= simplejump_p (insn
) ? 0 : 8;
13607 /* Add the size of a load into $AT. */
13608 length
+= BASE_INSN_LENGTH
* mips_load_label_num_insns ();
13610 /* Add the length of an indirect jump, ignoring the delay slot. */
13611 length
+= TARGET_COMPRESSION
? 2 : 4;
13614 /* A unconditional jump has an unfilled delay slot if it is not part
13615 of a sequence. A conditional jump normally has a delay slot, but
13616 does not on MIPS16. */
13617 if (CALL_P (insn
) || (TARGET_MIPS16
? simplejump_p (insn
) : JUMP_P (insn
)))
13618 length
+= TARGET_MIPS16
? 2 : 4;
13620 /* See how many nops might be needed to avoid hardware hazards. */
13621 if (!cfun
->machine
->ignore_hazard_length_p
13623 && INSN_CODE (insn
) >= 0)
13624 switch (get_attr_hazard (insn
))
13630 case HAZARD_FORBIDDEN_SLOT
:
13631 length
+= NOP_INSN_LENGTH
;
13635 length
+= NOP_INSN_LENGTH
* 2;
13642 /* Return the asm template for a call. OPERANDS are the operands, TARGET_OPNO
13643 is the operand number of the target. SIZE_OPNO is the operand number of
13644 the argument size operand that can optionally hold the call attributes. If
13645 SIZE_OPNO is not -1 and the call is indirect, use the function symbol from
13646 the call attributes to attach a R_MIPS_JALR relocation to the call. LINK_P
13647 indicates whether the jump is a call and needs to set the link register.
13649 When generating GOT code without explicit relocation operators, all calls
13650 should use assembly macros. Otherwise, all indirect calls should use "jr"
13651 or "jalr"; we will arrange to restore $gp afterwards if necessary. Finally,
13652 we can only generate direct calls for -mabicalls by temporarily switching
13655 For microMIPS jal(r), we try to generate jal(r)s when a 16-bit
13656 instruction is in the delay slot of jal(r).
13658 Where compact branches are available, we try to use them if the delay slot
13659 has a NOP (or equivalently delay slots were not enabled for the instruction
13663 mips_output_jump (rtx
*operands
, int target_opno
, int size_opno
, bool link_p
)
13665 static char buffer
[300];
13667 bool reg_p
= REG_P (operands
[target_opno
]);
13669 const char *and_link
= link_p
? "al" : "";
13670 const char *reg
= reg_p
? "r" : "";
13671 const char *compact
= "";
13672 const char *nop
= "%/";
13673 const char *short_delay
= link_p
? "%!" : "";
13674 const char *insn_name
= TARGET_CB_NEVER
|| reg_p
? "j" : "b";
13676 /* Compact branches can only be described when the ISA has support for them
13677 as both the compact formatter '%:' and the delay slot NOP formatter '%/'
13678 work as a mutually exclusive pair. I.e. a NOP is never required if a
13679 compact form is available. */
13680 if (!final_sequence
13681 && (TARGET_CB_MAYBE
13682 || (ISA_HAS_JRC
&& !link_p
&& reg_p
)))
13688 if (TARGET_USE_GOT
&& !TARGET_EXPLICIT_RELOCS
)
13689 sprintf (s
, "%%*%s%s\t%%%d%%/", insn_name
, and_link
, target_opno
);
13692 if (!reg_p
&& TARGET_ABICALLS_PIC2
)
13693 s
+= sprintf (s
, ".option\tpic0\n\t");
13695 if (reg_p
&& mips_get_pic_call_symbol (operands
, size_opno
))
13696 s
+= sprintf (s
, "%%*.reloc\t1f,%s,%%%d\n1:\t",
13697 TARGET_MICROMIPS
? "R_MICROMIPS_JALR" : "R_MIPS_JALR",
13700 s
+= sprintf (s
, "%%*");
13702 s
+= sprintf (s
, "%s%s%s%s%s\t%%%d%s",
13703 insn_name
, and_link
, reg
, compact
, short_delay
,
13706 if (!reg_p
&& TARGET_ABICALLS_PIC2
)
13707 s
+= sprintf (s
, "\n\t.option\tpic2");
13712 /* Return the assembly code for INSN, which has the operands given by
13713 OPERANDS, and which branches to OPERANDS[0] if some condition is true.
13714 BRANCH_IF_TRUE is the asm template that should be used if OPERANDS[0]
13715 is in range of a direct branch. BRANCH_IF_FALSE is an inverted
13716 version of BRANCH_IF_TRUE. */
13719 mips_output_conditional_branch (rtx_insn
*insn
, rtx
*operands
,
13720 const char *branch_if_true
,
13721 const char *branch_if_false
)
13723 unsigned int length
;
13726 gcc_assert (LABEL_P (operands
[0]));
13728 length
= get_attr_length (insn
);
13731 /* Just a simple conditional branch. */
13732 mips_branch_likely
= (final_sequence
&& INSN_ANNULLED_BRANCH_P (insn
));
13733 return branch_if_true
;
13736 /* Generate a reversed branch around a direct jump. This fallback does
13737 not use branch-likely instructions. */
13738 mips_branch_likely
= false;
13739 rtx_code_label
*not_taken
= gen_label_rtx ();
13740 taken
= operands
[0];
13742 /* Generate the reversed branch to NOT_TAKEN. */
13743 operands
[0] = not_taken
;
13744 output_asm_insn (branch_if_false
, operands
);
13746 /* If INSN has a delay slot, we must provide delay slots for both the
13747 branch to NOT_TAKEN and the conditional jump. We must also ensure
13748 that INSN's delay slot is executed in the appropriate cases. */
13749 if (final_sequence
)
13751 /* This first delay slot will always be executed, so use INSN's
13752 delay slot if is not annulled. */
13753 if (!INSN_ANNULLED_BRANCH_P (insn
))
13755 final_scan_insn (final_sequence
->insn (1),
13756 asm_out_file
, optimize
, 1, NULL
);
13757 final_sequence
->insn (1)->set_deleted ();
13760 output_asm_insn ("nop", 0);
13761 fprintf (asm_out_file
, "\n");
13764 /* Output the unconditional branch to TAKEN. */
13765 if (TARGET_ABSOLUTE_JUMPS
&& TARGET_CB_MAYBE
)
13767 /* Add a hazard nop. */
13768 if (!final_sequence
)
13770 output_asm_insn ("nop\t\t# hazard nop", 0);
13771 fprintf (asm_out_file
, "\n");
13773 output_asm_insn (MIPS_ABSOLUTE_JUMP ("bc\t%0"), &taken
);
13775 else if (TARGET_ABSOLUTE_JUMPS
)
13776 output_asm_insn (MIPS_ABSOLUTE_JUMP ("j\t%0%/"), &taken
);
13779 mips_output_load_label (taken
);
13780 if (TARGET_CB_MAYBE
)
13781 output_asm_insn ("jrc\t%@%]", 0);
13783 output_asm_insn ("jr\t%@%]%/", 0);
13786 /* Now deal with its delay slot; see above. */
13787 if (final_sequence
)
13789 /* This delay slot will only be executed if the branch is taken.
13790 Use INSN's delay slot if is annulled. */
13791 if (INSN_ANNULLED_BRANCH_P (insn
))
13793 final_scan_insn (final_sequence
->insn (1),
13794 asm_out_file
, optimize
, 1, NULL
);
13795 final_sequence
->insn (1)->set_deleted ();
13797 else if (TARGET_CB_NEVER
)
13798 output_asm_insn ("nop", 0);
13799 fprintf (asm_out_file
, "\n");
13802 /* Output NOT_TAKEN. */
13803 targetm
.asm_out
.internal_label (asm_out_file
, "L",
13804 CODE_LABEL_NUMBER (not_taken
));
13808 /* Return the assembly code for INSN, which branches to OPERANDS[0]
13809 if some equality condition is true. The condition is given by
13810 OPERANDS[1] if !INVERTED_P, otherwise it is the inverse of
13811 OPERANDS[1]. OPERANDS[2] is the comparison's first operand;
13812 OPERANDS[3] is the second operand and may be zero or a register. */
13815 mips_output_equal_conditional_branch (rtx_insn
* insn
, rtx
*operands
,
13818 const char *branch
[2];
13819 /* For a simple BNEZ or BEQZ microMIPSr3 branch. */
13820 if (TARGET_MICROMIPS
13821 && mips_isa_rev
<= 5
13822 && operands
[3] == const0_rtx
13823 && get_attr_length (insn
) <= 8)
13825 if (mips_cb
== MIPS_CB_OPTIMAL
)
13827 branch
[!inverted_p
] = "%*b%C1z%:\t%2,%0";
13828 branch
[inverted_p
] = "%*b%N1z%:\t%2,%0";
13832 branch
[!inverted_p
] = "%*b%C1z\t%2,%0%/";
13833 branch
[inverted_p
] = "%*b%N1z\t%2,%0%/";
13836 else if (TARGET_CB_MAYBE
)
13838 if (operands
[3] == const0_rtx
)
13840 branch
[!inverted_p
] = MIPS_BRANCH_C ("b%C1z", "%2,%0");
13841 branch
[inverted_p
] = MIPS_BRANCH_C ("b%N1z", "%2,%0");
13843 else if (REGNO (operands
[2]) != REGNO (operands
[3]))
13845 branch
[!inverted_p
] = MIPS_BRANCH_C ("b%C1", "%2,%3,%0");
13846 branch
[inverted_p
] = MIPS_BRANCH_C ("b%N1", "%2,%3,%0");
13850 /* This case is degenerate. It should not happen, but does. */
13851 if (GET_CODE (operands
[1]) == NE
)
13852 inverted_p
= !inverted_p
;
13854 branch
[!inverted_p
] = MIPS_BRANCH_C ("b", "%0");
13855 branch
[inverted_p
] = "%*\t\t# branch never";
13860 branch
[!inverted_p
] = MIPS_BRANCH ("b%C1", "%2,%z3,%0");
13861 branch
[inverted_p
] = MIPS_BRANCH ("b%N1", "%2,%z3,%0");
13864 return mips_output_conditional_branch (insn
, operands
, branch
[1], branch
[0]);
13867 /* Return the assembly code for INSN, which branches to OPERANDS[0]
13868 if some ordering condition is true. The condition is given by
13869 OPERANDS[1] if !INVERTED_P, otherwise it is the inverse of
13870 OPERANDS[1]. OPERANDS[2] is the comparison's first operand;
13871 OPERANDS[3] is the second operand and may be zero or a register. */
13874 mips_output_order_conditional_branch (rtx_insn
*insn
, rtx
*operands
,
13877 const char *branch
[2];
13879 /* Make BRANCH[1] branch to OPERANDS[0] when the condition is true.
13880 Make BRANCH[0] branch on the inverse condition. */
13881 if (operands
[3] != const0_rtx
)
13883 /* Handle degenerate cases that should not, but do, occur. */
13884 if (REGNO (operands
[2]) == REGNO (operands
[3]))
13886 switch (GET_CODE (operands
[1]))
13890 inverted_p
= !inverted_p
;
13891 /* Fall through. */
13894 branch
[!inverted_p
] = MIPS_BRANCH_C ("b", "%0");
13895 branch
[inverted_p
] = "%*\t\t# branch never";
13898 gcc_unreachable ();
13903 branch
[!inverted_p
] = MIPS_BRANCH_C ("b%C1", "%2,%3,%0");
13904 branch
[inverted_p
] = MIPS_BRANCH_C ("b%N1", "%2,%3,%0");
13909 switch (GET_CODE (operands
[1]))
13911 /* These cases are equivalent to comparisons against zero. */
13913 inverted_p
= !inverted_p
;
13914 /* Fall through. */
13916 if (TARGET_CB_MAYBE
)
13918 branch
[!inverted_p
] = MIPS_BRANCH_C ("bnez", "%2,%0");
13919 branch
[inverted_p
] = MIPS_BRANCH_C ("beqz", "%2,%0");
13923 branch
[!inverted_p
] = MIPS_BRANCH ("bne", "%2,%.,%0");
13924 branch
[inverted_p
] = MIPS_BRANCH ("beq", "%2,%.,%0");
13928 /* These cases are always true or always false. */
13930 inverted_p
= !inverted_p
;
13931 /* Fall through. */
13933 if (TARGET_CB_MAYBE
)
13935 branch
[!inverted_p
] = MIPS_BRANCH_C ("b", "%0");
13936 branch
[inverted_p
] = "%*\t\t# branch never";
13940 branch
[!inverted_p
] = MIPS_BRANCH ("beq", "%.,%.,%0");
13941 branch
[inverted_p
] = MIPS_BRANCH ("bne", "%.,%.,%0");
13946 if (TARGET_CB_MAYBE
)
13948 branch
[!inverted_p
] = MIPS_BRANCH_C ("b%C1z", "%2,%0");
13949 branch
[inverted_p
] = MIPS_BRANCH_C ("b%N1z", "%2,%0");
13953 branch
[!inverted_p
] = MIPS_BRANCH ("b%C1z", "%2,%0");
13954 branch
[inverted_p
] = MIPS_BRANCH ("b%N1z", "%2,%0");
13959 return mips_output_conditional_branch (insn
, operands
, branch
[1], branch
[0]);
13962 /* Start a block of code that needs access to the LL, SC and SYNC
13966 mips_start_ll_sc_sync_block (void)
13968 if (!ISA_HAS_LL_SC
)
13970 output_asm_insn (".set\tpush", 0);
13972 output_asm_insn (".set\tmips3", 0);
13974 output_asm_insn (".set\tmips2", 0);
13978 /* End a block started by mips_start_ll_sc_sync_block. */
13981 mips_end_ll_sc_sync_block (void)
13983 if (!ISA_HAS_LL_SC
)
13984 output_asm_insn (".set\tpop", 0);
13987 /* Output and/or return the asm template for a sync instruction. */
13990 mips_output_sync (void)
13992 mips_start_ll_sc_sync_block ();
13993 output_asm_insn ("sync", 0);
13994 mips_end_ll_sc_sync_block ();
13998 /* Return the asm template associated with sync_insn1 value TYPE.
13999 IS_64BIT_P is true if we want a 64-bit rather than 32-bit operation. */
14001 static const char *
14002 mips_sync_insn1_template (enum attr_sync_insn1 type
, bool is_64bit_p
)
14006 case SYNC_INSN1_MOVE
:
14007 return "move\t%0,%z2";
14008 case SYNC_INSN1_LI
:
14009 return "li\t%0,%2";
14010 case SYNC_INSN1_ADDU
:
14011 return is_64bit_p
? "daddu\t%0,%1,%z2" : "addu\t%0,%1,%z2";
14012 case SYNC_INSN1_ADDIU
:
14013 return is_64bit_p
? "daddiu\t%0,%1,%2" : "addiu\t%0,%1,%2";
14014 case SYNC_INSN1_SUBU
:
14015 return is_64bit_p
? "dsubu\t%0,%1,%z2" : "subu\t%0,%1,%z2";
14016 case SYNC_INSN1_AND
:
14017 return "and\t%0,%1,%z2";
14018 case SYNC_INSN1_ANDI
:
14019 return "andi\t%0,%1,%2";
14020 case SYNC_INSN1_OR
:
14021 return "or\t%0,%1,%z2";
14022 case SYNC_INSN1_ORI
:
14023 return "ori\t%0,%1,%2";
14024 case SYNC_INSN1_XOR
:
14025 return "xor\t%0,%1,%z2";
14026 case SYNC_INSN1_XORI
:
14027 return "xori\t%0,%1,%2";
14029 gcc_unreachable ();
14032 /* Return the asm template associated with sync_insn2 value TYPE. */
14034 static const char *
14035 mips_sync_insn2_template (enum attr_sync_insn2 type
)
14039 case SYNC_INSN2_NOP
:
14040 gcc_unreachable ();
14041 case SYNC_INSN2_AND
:
14042 return "and\t%0,%1,%z2";
14043 case SYNC_INSN2_XOR
:
14044 return "xor\t%0,%1,%z2";
14045 case SYNC_INSN2_NOT
:
14046 return "nor\t%0,%1,%.";
14048 gcc_unreachable ();
14051 /* OPERANDS are the operands to a sync loop instruction and INDEX is
14052 the value of the one of the sync_* attributes. Return the operand
14053 referred to by the attribute, or DEFAULT_VALUE if the insn doesn't
14054 have the associated attribute. */
14057 mips_get_sync_operand (rtx
*operands
, int index
, rtx default_value
)
14060 default_value
= operands
[index
- 1];
14061 return default_value
;
14064 /* INSN is a sync loop with operands OPERANDS. Build up a multi-insn
14065 sequence for it. */
14068 mips_process_sync_loop (rtx_insn
*insn
, rtx
*operands
)
14070 rtx at
, mem
, oldval
, newval
, inclusive_mask
, exclusive_mask
;
14071 rtx required_oldval
, insn1_op2
, tmp1
, tmp2
, tmp3
, cmp
;
14072 unsigned int tmp3_insn
;
14073 enum attr_sync_insn1 insn1
;
14074 enum attr_sync_insn2 insn2
;
14077 enum memmodel model
;
14079 /* Read an operand from the sync_WHAT attribute and store it in
14080 variable WHAT. DEFAULT is the default value if no attribute
14082 #define READ_OPERAND(WHAT, DEFAULT) \
14083 WHAT = mips_get_sync_operand (operands, (int) get_attr_sync_##WHAT (insn), \
14086 /* Read the memory. */
14087 READ_OPERAND (mem
, 0);
14089 is_64bit_p
= (GET_MODE_BITSIZE (GET_MODE (mem
)) == 64);
14091 /* Read the other attributes. */
14092 at
= gen_rtx_REG (GET_MODE (mem
), AT_REGNUM
);
14093 READ_OPERAND (oldval
, at
);
14094 READ_OPERAND (cmp
, 0);
14095 READ_OPERAND (newval
, at
);
14096 READ_OPERAND (inclusive_mask
, 0);
14097 READ_OPERAND (exclusive_mask
, 0);
14098 READ_OPERAND (required_oldval
, 0);
14099 READ_OPERAND (insn1_op2
, 0);
14100 insn1
= get_attr_sync_insn1 (insn
);
14101 insn2
= get_attr_sync_insn2 (insn
);
14103 /* Don't bother setting CMP result that is never used. */
14104 if (cmp
&& find_reg_note (insn
, REG_UNUSED
, cmp
))
14107 memmodel_attr
= get_attr_sync_memmodel (insn
);
14108 switch (memmodel_attr
)
14111 model
= MEMMODEL_ACQ_REL
;
14114 model
= MEMMODEL_ACQUIRE
;
14117 model
= memmodel_from_int (INTVAL (operands
[memmodel_attr
]));
14120 mips_multi_start ();
14122 /* Output the release side of the memory barrier. */
14123 if (need_atomic_barrier_p (model
, true))
14125 if (required_oldval
== 0 && TARGET_OCTEON
)
14127 /* Octeon doesn't reorder reads, so a full barrier can be
14128 created by using SYNCW to order writes combined with the
14129 write from the following SC. When the SC successfully
14130 completes, we know that all preceding writes are also
14131 committed to the coherent memory system. It is possible
14132 for a single SYNCW to fail, but a pair of them will never
14133 fail, so we use two. */
14134 mips_multi_add_insn ("syncw", NULL
);
14135 mips_multi_add_insn ("syncw", NULL
);
14138 mips_multi_add_insn ("sync", NULL
);
14141 /* Output the branch-back label. */
14142 mips_multi_add_label ("1:");
14144 /* OLDVAL = *MEM. */
14145 mips_multi_add_insn (is_64bit_p
? "lld\t%0,%1" : "ll\t%0,%1",
14146 oldval
, mem
, NULL
);
14148 /* if ((OLDVAL & INCLUSIVE_MASK) != REQUIRED_OLDVAL) goto 2. */
14149 if (required_oldval
)
14151 if (inclusive_mask
== 0)
14155 gcc_assert (oldval
!= at
);
14156 mips_multi_add_insn ("and\t%0,%1,%2",
14157 at
, oldval
, inclusive_mask
, NULL
);
14160 if (TARGET_CB_NEVER
)
14161 mips_multi_add_insn ("bne\t%0,%z1,2f", tmp1
, required_oldval
, NULL
);
14163 /* CMP = 0 [delay slot]. */
14165 mips_multi_add_insn ("li\t%0,0", cmp
, NULL
);
14167 if (TARGET_CB_MAYBE
&& required_oldval
== const0_rtx
)
14168 mips_multi_add_insn ("bnezc\t%0,2f", tmp1
, NULL
);
14169 else if (TARGET_CB_MAYBE
)
14170 mips_multi_add_insn ("bnec\t%0,%1,2f", tmp1
, required_oldval
, NULL
);
14174 /* $TMP1 = OLDVAL & EXCLUSIVE_MASK. */
14175 if (exclusive_mask
== 0)
14179 gcc_assert (oldval
!= at
);
14180 mips_multi_add_insn ("and\t%0,%1,%z2",
14181 at
, oldval
, exclusive_mask
, NULL
);
14185 /* $TMP2 = INSN1 (OLDVAL, INSN1_OP2).
14187 We can ignore moves if $TMP4 != INSN1_OP2, since we'll still emit
14188 at least one instruction in that case. */
14189 if (insn1
== SYNC_INSN1_MOVE
14190 && (tmp1
!= const0_rtx
|| insn2
!= SYNC_INSN2_NOP
))
14194 mips_multi_add_insn (mips_sync_insn1_template (insn1
, is_64bit_p
),
14195 newval
, oldval
, insn1_op2
, NULL
);
14199 /* $TMP3 = INSN2 ($TMP2, INCLUSIVE_MASK). */
14200 if (insn2
== SYNC_INSN2_NOP
)
14204 mips_multi_add_insn (mips_sync_insn2_template (insn2
),
14205 newval
, tmp2
, inclusive_mask
, NULL
);
14208 tmp3_insn
= mips_multi_last_index ();
14210 /* $AT = $TMP1 | $TMP3. */
14211 if (tmp1
== const0_rtx
|| tmp3
== const0_rtx
)
14213 mips_multi_set_operand (tmp3_insn
, 0, at
);
14218 gcc_assert (tmp1
!= tmp3
);
14219 mips_multi_add_insn ("or\t%0,%1,%2", at
, tmp1
, tmp3
, NULL
);
14222 /* if (!commit (*MEM = $AT)) goto 1.
14224 This will sometimes be a delayed branch; see the write code below
14226 mips_multi_add_insn (is_64bit_p
? "scd\t%0,%1" : "sc\t%0,%1", at
, mem
, NULL
);
14228 /* When using branch likely (-mfix-r10000), the delay slot instruction
14229 will be annulled on false. The normal delay slot instructions
14230 calculate the overall result of the atomic operation and must not
14231 be annulled. To ensure this behavior unconditionally use a NOP
14232 in the delay slot for the branch likely case. */
14234 if (TARGET_CB_MAYBE
)
14235 mips_multi_add_insn ("beqzc\t%0,1b", at
, NULL
);
14237 mips_multi_add_insn ("beq%?\t%0,%.,1b%~", at
, NULL
);
14239 /* if (INSN1 != MOVE && INSN1 != LI) NEWVAL = $TMP3 [delay slot]. */
14240 if (insn1
!= SYNC_INSN1_MOVE
&& insn1
!= SYNC_INSN1_LI
&& tmp3
!= newval
)
14242 mips_multi_copy_insn (tmp3_insn
);
14243 mips_multi_set_operand (mips_multi_last_index (), 0, newval
);
14245 else if (!(required_oldval
&& cmp
) && !mips_branch_likely
)
14246 mips_multi_add_insn ("nop", NULL
);
14248 /* CMP = 1 -- either standalone or in a delay slot. */
14249 if (required_oldval
&& cmp
)
14250 mips_multi_add_insn ("li\t%0,1", cmp
, NULL
);
14252 /* Output the acquire side of the memory barrier. */
14253 if (TARGET_SYNC_AFTER_SC
&& need_atomic_barrier_p (model
, false))
14254 mips_multi_add_insn ("sync", NULL
);
14256 /* Output the exit label, if needed. */
14257 if (required_oldval
)
14258 mips_multi_add_label ("2:");
14260 #undef READ_OPERAND
14263 /* Output and/or return the asm template for sync loop INSN, which has
14264 the operands given by OPERANDS. */
14267 mips_output_sync_loop (rtx_insn
*insn
, rtx
*operands
)
14269 /* Use branch-likely instructions to work around the LL/SC R10000
14271 mips_branch_likely
= TARGET_FIX_R10000
;
14273 mips_process_sync_loop (insn
, operands
);
14275 mips_push_asm_switch (&mips_noreorder
);
14276 mips_push_asm_switch (&mips_nomacro
);
14277 mips_push_asm_switch (&mips_noat
);
14278 mips_start_ll_sc_sync_block ();
14280 mips_multi_write ();
14282 mips_end_ll_sc_sync_block ();
14283 mips_pop_asm_switch (&mips_noat
);
14284 mips_pop_asm_switch (&mips_nomacro
);
14285 mips_pop_asm_switch (&mips_noreorder
);
14290 /* Return the number of individual instructions in sync loop INSN,
14291 which has the operands given by OPERANDS. */
14294 mips_sync_loop_insns (rtx_insn
*insn
, rtx
*operands
)
14296 /* Use branch-likely instructions to work around the LL/SC R10000
14298 mips_branch_likely
= TARGET_FIX_R10000
;
14299 mips_process_sync_loop (insn
, operands
);
14300 return mips_multi_num_insns
;
14303 /* Return the assembly code for DIV or DDIV instruction DIVISION, which has
14304 the operands given by OPERANDS. Add in a divide-by-zero check if needed.
14306 When working around R4000 and R4400 errata, we need to make sure that
14307 the division is not immediately followed by a shift[1][2]. We also
14308 need to stop the division from being put into a branch delay slot[3].
14309 The easiest way to avoid both problems is to add a nop after the
14310 division. When a divide-by-zero check is needed, this nop can be
14311 used to fill the branch delay slot.
14313 [1] If a double-word or a variable shift executes immediately
14314 after starting an integer division, the shift may give an
14315 incorrect result. See quotations of errata #16 and #28 from
14316 "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
14317 in mips.md for details.
14319 [2] A similar bug to [1] exists for all revisions of the
14320 R4000 and the R4400 when run in an MC configuration.
14321 From "MIPS R4000MC Errata, Processor Revision 2.2 and 3.0":
14323 "19. In this following sequence:
14325 ddiv (or ddivu or div or divu)
14326 dsll32 (or dsrl32, dsra32)
14328 if an MPT stall occurs, while the divide is slipping the cpu
14329 pipeline, then the following double shift would end up with an
14332 Workaround: The compiler needs to avoid generating any
14333 sequence with divide followed by extended double shift."
14335 This erratum is also present in "MIPS R4400MC Errata, Processor
14336 Revision 1.0" and "MIPS R4400MC Errata, Processor Revision 2.0
14337 & 3.0" as errata #10 and #4, respectively.
14339 [3] From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
14340 (also valid for MIPS R4000MC processors):
14342 "52. R4000SC: This bug does not apply for the R4000PC.
14344 There are two flavors of this bug:
14346 1) If the instruction just after divide takes an RF exception
14347 (tlb-refill, tlb-invalid) and gets an instruction cache
14348 miss (both primary and secondary) and the line which is
14349 currently in secondary cache at this index had the first
14350 data word, where the bits 5..2 are set, then R4000 would
14351 get a wrong result for the div.
14356 ------------------- # end-of page. -tlb-refill
14361 ------------------- # end-of page. -tlb-invalid
14364 2) If the divide is in the taken branch delay slot, where the
14365 target takes RF exception and gets an I-cache miss for the
14366 exception vector or where I-cache miss occurs for the
14367 target address, under the above mentioned scenarios, the
14368 div would get wrong results.
14371 j r2 # to next page mapped or unmapped
14372 div r8,r9 # this bug would be there as long
14373 # as there is an ICache miss and
14374 nop # the "data pattern" is present
14377 beq r0, r0, NextPage # to Next page
14381 This bug is present for div, divu, ddiv, and ddivu
14384 Workaround: For item 1), OS could make sure that the next page
14385 after the divide instruction is also mapped. For item 2), the
14386 compiler could make sure that the divide instruction is not in
14387 the branch delay slot."
14389 These processors have PRId values of 0x00004220 and 0x00004300 for
14390 the R4000 and 0x00004400, 0x00004500 and 0x00004600 for the R4400. */
14393 mips_output_division (const char *division
, rtx
*operands
)
14398 if (TARGET_FIX_R4000
|| TARGET_FIX_R4400
)
14400 output_asm_insn (s
, operands
);
14403 if (TARGET_CHECK_ZERO_DIV
)
14407 output_asm_insn (s
, operands
);
14408 s
= "bnez\t%2,1f\n\tbreak\t7\n1:";
14410 else if (GENERATE_DIVIDE_TRAPS
)
14412 /* Avoid long replay penalty on load miss by putting the trap before
14415 output_asm_insn ("teq\t%2,%.,7", operands
);
14418 output_asm_insn (s
, operands
);
14419 s
= "teq\t%2,%.,7";
14424 if (flag_delayed_branch
)
14426 output_asm_insn ("%(bne\t%2,%.,1f", operands
);
14427 output_asm_insn (s
, operands
);
14428 s
= "break\t7%)\n1:";
14432 output_asm_insn (s
, operands
);
14433 s
= "bne\t%2,%.,1f\n\tnop\n\tbreak\t7\n1:";
14440 /* Return the assembly code for MSA DIV_{S,U}.DF or MOD_{S,U}.DF instructions,
14441 which has the operands given by OPERANDS. Add in a divide-by-zero check
14445 mips_msa_output_division (const char *division
, rtx
*operands
)
14450 if (TARGET_CHECK_ZERO_DIV
)
14452 output_asm_insn ("%(bnz.%v0\t%w2,1f", operands
);
14453 output_asm_insn (s
, operands
);
14454 s
= "break\t7%)\n1:";
14459 /* Return true if destination of IN_INSN is used as add source in
14460 OUT_INSN. Both IN_INSN and OUT_INSN are of type fmadd. Example:
14461 madd.s dst, x, y, z
14462 madd.s a, dst, b, c */
14465 mips_fmadd_bypass (rtx_insn
*out_insn
, rtx_insn
*in_insn
)
14467 int dst_reg
, src_reg
;
14469 gcc_assert (get_attr_type (in_insn
) == TYPE_FMADD
);
14470 gcc_assert (get_attr_type (out_insn
) == TYPE_FMADD
);
14472 extract_insn (in_insn
);
14473 dst_reg
= REG_P (recog_data
.operand
[0]);
14475 extract_insn (out_insn
);
14476 src_reg
= REG_P (recog_data
.operand
[1]);
14478 if (dst_reg
== src_reg
)
14484 /* Return true if IN_INSN is a multiply-add or multiply-subtract
14485 instruction and if OUT_INSN assigns to the accumulator operand. */
14488 mips_linked_madd_p (rtx_insn
*out_insn
, rtx_insn
*in_insn
)
14490 enum attr_accum_in accum_in
;
14491 int accum_in_opnum
;
14494 if (recog_memoized (in_insn
) < 0)
14497 accum_in
= get_attr_accum_in (in_insn
);
14498 if (accum_in
== ACCUM_IN_NONE
)
14501 accum_in_opnum
= accum_in
- ACCUM_IN_0
;
14503 extract_insn (in_insn
);
14504 gcc_assert (accum_in_opnum
< recog_data
.n_operands
);
14505 accum_in_op
= recog_data
.operand
[accum_in_opnum
];
14507 return reg_set_p (accum_in_op
, out_insn
);
14510 /* True if the dependency between OUT_INSN and IN_INSN is on the store
14511 data rather than the address. We need this because the cprestore
14512 pattern is type "store", but is defined using an UNSPEC_VOLATILE,
14513 which causes the default routine to abort. We just return false
14517 mips_store_data_bypass_p (rtx_insn
*out_insn
, rtx_insn
*in_insn
)
14519 if (GET_CODE (PATTERN (in_insn
)) == UNSPEC_VOLATILE
)
14522 return store_data_bypass_p (out_insn
, in_insn
);
14526 /* Variables and flags used in scheduler hooks when tuning for
14530 /* Variables to support Loongson 2E/2F round-robin [F]ALU1/2 dispatch
14533 /* If true, then next ALU1/2 instruction will go to ALU1. */
14536 /* If true, then next FALU1/2 unstruction will go to FALU1. */
14539 /* Codes to query if [f]alu{1,2}_core units are subscribed or not. */
14540 int alu1_core_unit_code
;
14541 int alu2_core_unit_code
;
14542 int falu1_core_unit_code
;
14543 int falu2_core_unit_code
;
14545 /* True if current cycle has a multi instruction.
14546 This flag is used in mips_ls2_dfa_post_advance_cycle. */
14547 bool cycle_has_multi_p
;
14549 /* Instructions to subscribe ls2_[f]alu{1,2}_turn_enabled units.
14550 These are used in mips_ls2_dfa_post_advance_cycle to initialize
14552 E.g., when alu1_turn_enabled_insn is issued it makes next ALU1/2
14553 instruction to go ALU1. */
14554 rtx_insn
*alu1_turn_enabled_insn
;
14555 rtx_insn
*alu2_turn_enabled_insn
;
14556 rtx_insn
*falu1_turn_enabled_insn
;
14557 rtx_insn
*falu2_turn_enabled_insn
;
14560 /* Implement TARGET_SCHED_ADJUST_COST. We assume that anti and output
14561 dependencies have no cost, except on the 20Kc where output-dependence
14562 is treated like input-dependence. */
14565 mips_adjust_cost (rtx_insn
*, int dep_type
, rtx_insn
*, int cost
, unsigned int)
14567 if (dep_type
!= 0 && (dep_type
!= REG_DEP_OUTPUT
|| !TUNE_20KC
))
14572 /* Return the number of instructions that can be issued per cycle. */
14575 mips_issue_rate (void)
14579 case PROCESSOR_74KC
:
14580 case PROCESSOR_74KF2_1
:
14581 case PROCESSOR_74KF1_1
:
14582 case PROCESSOR_74KF3_2
:
14583 /* The 74k is not strictly quad-issue cpu, but can be seen as one
14584 by the scheduler. It can issue 1 ALU, 1 AGEN and 2 FPU insns,
14585 but in reality only a maximum of 3 insns can be issued as
14586 floating-point loads and stores also require a slot in the
14588 case PROCESSOR_R10000
:
14589 /* All R10K Processors are quad-issue (being the first MIPS
14590 processors to support this feature). */
14593 case PROCESSOR_20KC
:
14594 case PROCESSOR_R4130
:
14595 case PROCESSOR_R5400
:
14596 case PROCESSOR_R5500
:
14597 case PROCESSOR_R5900
:
14598 case PROCESSOR_R7000
:
14599 case PROCESSOR_R9000
:
14600 case PROCESSOR_OCTEON
:
14601 case PROCESSOR_OCTEON2
:
14602 case PROCESSOR_OCTEON3
:
14603 case PROCESSOR_I6400
:
14606 case PROCESSOR_SB1
:
14607 case PROCESSOR_SB1A
:
14608 /* This is actually 4, but we get better performance if we claim 3.
14609 This is partly because of unwanted speculative code motion with the
14610 larger number, and partly because in most common cases we can't
14611 reach the theoretical max of 4. */
14614 case PROCESSOR_LOONGSON_2E
:
14615 case PROCESSOR_LOONGSON_2F
:
14616 case PROCESSOR_LOONGSON_3A
:
14617 case PROCESSOR_P5600
:
14618 case PROCESSOR_P6600
:
14621 case PROCESSOR_XLP
:
14622 return (reload_completed
? 4 : 3);
14629 /* Implement TARGET_SCHED_INIT_DFA_POST_CYCLE_INSN hook for Loongson2. */
14632 mips_ls2_init_dfa_post_cycle_insn (void)
14635 emit_insn (gen_ls2_alu1_turn_enabled_insn ());
14636 mips_ls2
.alu1_turn_enabled_insn
= get_insns ();
14640 emit_insn (gen_ls2_alu2_turn_enabled_insn ());
14641 mips_ls2
.alu2_turn_enabled_insn
= get_insns ();
14645 emit_insn (gen_ls2_falu1_turn_enabled_insn ());
14646 mips_ls2
.falu1_turn_enabled_insn
= get_insns ();
14650 emit_insn (gen_ls2_falu2_turn_enabled_insn ());
14651 mips_ls2
.falu2_turn_enabled_insn
= get_insns ();
14654 mips_ls2
.alu1_core_unit_code
= get_cpu_unit_code ("ls2_alu1_core");
14655 mips_ls2
.alu2_core_unit_code
= get_cpu_unit_code ("ls2_alu2_core");
14656 mips_ls2
.falu1_core_unit_code
= get_cpu_unit_code ("ls2_falu1_core");
14657 mips_ls2
.falu2_core_unit_code
= get_cpu_unit_code ("ls2_falu2_core");
14660 /* Implement TARGET_SCHED_INIT_DFA_POST_CYCLE_INSN hook.
14661 Init data used in mips_dfa_post_advance_cycle. */
14664 mips_init_dfa_post_cycle_insn (void)
14666 if (TUNE_LOONGSON_2EF
)
14667 mips_ls2_init_dfa_post_cycle_insn ();
14670 /* Initialize STATE when scheduling for Loongson 2E/2F.
14671 Support round-robin dispatch scheme by enabling only one of
14672 ALU1/ALU2 and one of FALU1/FALU2 units for ALU1/2 and FALU1/2 instructions
14676 mips_ls2_dfa_post_advance_cycle (state_t state
)
14678 if (cpu_unit_reservation_p (state
, mips_ls2
.alu1_core_unit_code
))
14680 /* Though there are no non-pipelined ALU1 insns,
14681 we can get an instruction of type 'multi' before reload. */
14682 gcc_assert (mips_ls2
.cycle_has_multi_p
);
14683 mips_ls2
.alu1_turn_p
= false;
14686 mips_ls2
.cycle_has_multi_p
= false;
14688 if (cpu_unit_reservation_p (state
, mips_ls2
.alu2_core_unit_code
))
14689 /* We have a non-pipelined alu instruction in the core,
14690 adjust round-robin counter. */
14691 mips_ls2
.alu1_turn_p
= true;
14693 if (mips_ls2
.alu1_turn_p
)
14695 if (state_transition (state
, mips_ls2
.alu1_turn_enabled_insn
) >= 0)
14696 gcc_unreachable ();
14700 if (state_transition (state
, mips_ls2
.alu2_turn_enabled_insn
) >= 0)
14701 gcc_unreachable ();
14704 if (cpu_unit_reservation_p (state
, mips_ls2
.falu1_core_unit_code
))
14706 /* There are no non-pipelined FALU1 insns. */
14707 gcc_unreachable ();
14708 mips_ls2
.falu1_turn_p
= false;
14711 if (cpu_unit_reservation_p (state
, mips_ls2
.falu2_core_unit_code
))
14712 /* We have a non-pipelined falu instruction in the core,
14713 adjust round-robin counter. */
14714 mips_ls2
.falu1_turn_p
= true;
14716 if (mips_ls2
.falu1_turn_p
)
14718 if (state_transition (state
, mips_ls2
.falu1_turn_enabled_insn
) >= 0)
14719 gcc_unreachable ();
14723 if (state_transition (state
, mips_ls2
.falu2_turn_enabled_insn
) >= 0)
14724 gcc_unreachable ();
14728 /* Implement TARGET_SCHED_DFA_POST_ADVANCE_CYCLE.
14729 This hook is being called at the start of each cycle. */
14732 mips_dfa_post_advance_cycle (void)
14734 if (TUNE_LOONGSON_2EF
)
14735 mips_ls2_dfa_post_advance_cycle (curr_state
);
14738 /* Implement TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD. This should
14739 be as wide as the scheduling freedom in the DFA. */
14742 mips_multipass_dfa_lookahead (void)
14744 /* Can schedule up to 4 of the 6 function units in any one cycle. */
14748 if (TUNE_LOONGSON_2EF
|| TUNE_LOONGSON_3A
)
14754 if (TUNE_P5600
|| TUNE_P6600
|| TUNE_I6400
)
14760 /* Remove the instruction at index LOWER from ready queue READY and
14761 reinsert it in front of the instruction at index HIGHER. LOWER must
14765 mips_promote_ready (rtx_insn
**ready
, int lower
, int higher
)
14767 rtx_insn
*new_head
;
14770 new_head
= ready
[lower
];
14771 for (i
= lower
; i
< higher
; i
++)
14772 ready
[i
] = ready
[i
+ 1];
14773 ready
[i
] = new_head
;
14776 /* If the priority of the instruction at POS2 in the ready queue READY
14777 is within LIMIT units of that of the instruction at POS1, swap the
14778 instructions if POS2 is not already less than POS1. */
14781 mips_maybe_swap_ready (rtx_insn
**ready
, int pos1
, int pos2
, int limit
)
14784 && INSN_PRIORITY (ready
[pos1
]) + limit
>= INSN_PRIORITY (ready
[pos2
]))
14788 temp
= ready
[pos1
];
14789 ready
[pos1
] = ready
[pos2
];
14790 ready
[pos2
] = temp
;
14794 /* Used by TUNE_MACC_CHAINS to record the last scheduled instruction
14795 that may clobber hi or lo. */
14796 static rtx_insn
*mips_macc_chains_last_hilo
;
14798 /* A TUNE_MACC_CHAINS helper function. Record that instruction INSN has
14799 been scheduled, updating mips_macc_chains_last_hilo appropriately. */
14802 mips_macc_chains_record (rtx_insn
*insn
)
14804 if (get_attr_may_clobber_hilo (insn
))
14805 mips_macc_chains_last_hilo
= insn
;
14808 /* A TUNE_MACC_CHAINS helper function. Search ready queue READY, which
14809 has NREADY elements, looking for a multiply-add or multiply-subtract
14810 instruction that is cumulative with mips_macc_chains_last_hilo.
14811 If there is one, promote it ahead of anything else that might
14812 clobber hi or lo. */
14815 mips_macc_chains_reorder (rtx_insn
**ready
, int nready
)
14819 if (mips_macc_chains_last_hilo
!= 0)
14820 for (i
= nready
- 1; i
>= 0; i
--)
14821 if (mips_linked_madd_p (mips_macc_chains_last_hilo
, ready
[i
]))
14823 for (j
= nready
- 1; j
> i
; j
--)
14824 if (recog_memoized (ready
[j
]) >= 0
14825 && get_attr_may_clobber_hilo (ready
[j
]))
14827 mips_promote_ready (ready
, i
, j
);
14834 /* The last instruction to be scheduled. */
14835 static rtx_insn
*vr4130_last_insn
;
14837 /* A note_stores callback used by vr4130_true_reg_dependence_p. DATA
14838 points to an rtx that is initially an instruction. Nullify the rtx
14839 if the instruction uses the value of register X. */
14842 vr4130_true_reg_dependence_p_1 (rtx x
, const_rtx pat ATTRIBUTE_UNUSED
,
14847 insn_ptr
= (rtx
*) data
;
14850 && reg_referenced_p (x
, PATTERN (*insn_ptr
)))
14854 /* Return true if there is true register dependence between vr4130_last_insn
14858 vr4130_true_reg_dependence_p (rtx insn
)
14860 note_stores (PATTERN (vr4130_last_insn
),
14861 vr4130_true_reg_dependence_p_1
, &insn
);
14865 /* A TUNE_MIPS4130 helper function. Given that INSN1 is at the head of
14866 the ready queue and that INSN2 is the instruction after it, return
14867 true if it is worth promoting INSN2 ahead of INSN1. Look for cases
14868 in which INSN1 and INSN2 can probably issue in parallel, but for
14869 which (INSN2, INSN1) should be less sensitive to instruction
14870 alignment than (INSN1, INSN2). See 4130.md for more details. */
14873 vr4130_swap_insns_p (rtx_insn
*insn1
, rtx_insn
*insn2
)
14875 sd_iterator_def sd_it
;
14878 /* Check for the following case:
14880 1) there is some other instruction X with an anti dependence on INSN1;
14881 2) X has a higher priority than INSN2; and
14882 3) X is an arithmetic instruction (and thus has no unit restrictions).
14884 If INSN1 is the last instruction blocking X, it would better to
14885 choose (INSN1, X) over (INSN2, INSN1). */
14886 FOR_EACH_DEP (insn1
, SD_LIST_FORW
, sd_it
, dep
)
14887 if (DEP_TYPE (dep
) == REG_DEP_ANTI
14888 && INSN_PRIORITY (DEP_CON (dep
)) > INSN_PRIORITY (insn2
)
14889 && recog_memoized (DEP_CON (dep
)) >= 0
14890 && get_attr_vr4130_class (DEP_CON (dep
)) == VR4130_CLASS_ALU
)
14893 if (vr4130_last_insn
!= 0
14894 && recog_memoized (insn1
) >= 0
14895 && recog_memoized (insn2
) >= 0)
14897 /* See whether INSN1 and INSN2 use different execution units,
14898 or if they are both ALU-type instructions. If so, they can
14899 probably execute in parallel. */
14900 enum attr_vr4130_class class1
= get_attr_vr4130_class (insn1
);
14901 enum attr_vr4130_class class2
= get_attr_vr4130_class (insn2
);
14902 if (class1
!= class2
|| class1
== VR4130_CLASS_ALU
)
14904 /* If only one of the instructions has a dependence on
14905 vr4130_last_insn, prefer to schedule the other one first. */
14906 bool dep1_p
= vr4130_true_reg_dependence_p (insn1
);
14907 bool dep2_p
= vr4130_true_reg_dependence_p (insn2
);
14908 if (dep1_p
!= dep2_p
)
14911 /* Prefer to schedule INSN2 ahead of INSN1 if vr4130_last_insn
14912 is not an ALU-type instruction and if INSN1 uses the same
14913 execution unit. (Note that if this condition holds, we already
14914 know that INSN2 uses a different execution unit.) */
14915 if (class1
!= VR4130_CLASS_ALU
14916 && recog_memoized (vr4130_last_insn
) >= 0
14917 && class1
== get_attr_vr4130_class (vr4130_last_insn
))
14924 /* A TUNE_MIPS4130 helper function. (READY, NREADY) describes a ready
14925 queue with at least two instructions. Swap the first two if
14926 vr4130_swap_insns_p says that it could be worthwhile. */
14929 vr4130_reorder (rtx_insn
**ready
, int nready
)
14931 if (vr4130_swap_insns_p (ready
[nready
- 1], ready
[nready
- 2]))
14932 mips_promote_ready (ready
, nready
- 2, nready
- 1);
14935 /* Record whether last 74k AGEN instruction was a load or store. */
14936 static enum attr_type mips_last_74k_agen_insn
= TYPE_UNKNOWN
;
14938 /* Initialize mips_last_74k_agen_insn from INSN. A null argument
14939 resets to TYPE_UNKNOWN state. */
14942 mips_74k_agen_init (rtx_insn
*insn
)
14944 if (!insn
|| CALL_P (insn
) || JUMP_P (insn
))
14945 mips_last_74k_agen_insn
= TYPE_UNKNOWN
;
14948 enum attr_type type
= get_attr_type (insn
);
14949 if (type
== TYPE_LOAD
|| type
== TYPE_STORE
)
14950 mips_last_74k_agen_insn
= type
;
14954 /* A TUNE_74K helper function. The 74K AGEN pipeline likes multiple
14955 loads to be grouped together, and multiple stores to be grouped
14956 together. Swap things around in the ready queue to make this happen. */
14959 mips_74k_agen_reorder (rtx_insn
**ready
, int nready
)
14962 int store_pos
, load_pos
;
14967 for (i
= nready
- 1; i
>= 0; i
--)
14969 rtx_insn
*insn
= ready
[i
];
14970 if (USEFUL_INSN_P (insn
))
14971 switch (get_attr_type (insn
))
14974 if (store_pos
== -1)
14979 if (load_pos
== -1)
14988 if (load_pos
== -1 || store_pos
== -1)
14991 switch (mips_last_74k_agen_insn
)
14994 /* Prefer to schedule loads since they have a higher latency. */
14996 /* Swap loads to the front of the queue. */
14997 mips_maybe_swap_ready (ready
, load_pos
, store_pos
, 4);
15000 /* Swap stores to the front of the queue. */
15001 mips_maybe_swap_ready (ready
, store_pos
, load_pos
, 4);
15008 /* Implement TARGET_SCHED_INIT. */
15011 mips_sched_init (FILE *file ATTRIBUTE_UNUSED
, int verbose ATTRIBUTE_UNUSED
,
15012 int max_ready ATTRIBUTE_UNUSED
)
15014 mips_macc_chains_last_hilo
= 0;
15015 vr4130_last_insn
= 0;
15016 mips_74k_agen_init (NULL
);
15018 /* When scheduling for Loongson2, branch instructions go to ALU1,
15019 therefore basic block is most likely to start with round-robin counter
15020 pointed to ALU2. */
15021 mips_ls2
.alu1_turn_p
= false;
15022 mips_ls2
.falu1_turn_p
= true;
15025 /* Subroutine used by TARGET_SCHED_REORDER and TARGET_SCHED_REORDER2. */
15028 mips_sched_reorder_1 (FILE *file ATTRIBUTE_UNUSED
, int verbose ATTRIBUTE_UNUSED
,
15029 rtx_insn
**ready
, int *nreadyp
, int cycle ATTRIBUTE_UNUSED
)
15031 if (!reload_completed
15032 && TUNE_MACC_CHAINS
15034 mips_macc_chains_reorder (ready
, *nreadyp
);
15036 if (reload_completed
15038 && !TARGET_VR4130_ALIGN
15040 vr4130_reorder (ready
, *nreadyp
);
15043 mips_74k_agen_reorder (ready
, *nreadyp
);
15046 /* Implement TARGET_SCHED_REORDER. */
15049 mips_sched_reorder (FILE *file ATTRIBUTE_UNUSED
, int verbose ATTRIBUTE_UNUSED
,
15050 rtx_insn
**ready
, int *nreadyp
, int cycle ATTRIBUTE_UNUSED
)
15052 mips_sched_reorder_1 (file
, verbose
, ready
, nreadyp
, cycle
);
15053 return mips_issue_rate ();
15056 /* Implement TARGET_SCHED_REORDER2. */
15059 mips_sched_reorder2 (FILE *file ATTRIBUTE_UNUSED
, int verbose ATTRIBUTE_UNUSED
,
15060 rtx_insn
**ready
, int *nreadyp
, int cycle ATTRIBUTE_UNUSED
)
15062 mips_sched_reorder_1 (file
, verbose
, ready
, nreadyp
, cycle
);
15063 return cached_can_issue_more
;
15066 /* Update round-robin counters for ALU1/2 and FALU1/2. */
15069 mips_ls2_variable_issue (rtx_insn
*insn
)
15071 if (mips_ls2
.alu1_turn_p
)
15073 if (cpu_unit_reservation_p (curr_state
, mips_ls2
.alu1_core_unit_code
))
15074 mips_ls2
.alu1_turn_p
= false;
15078 if (cpu_unit_reservation_p (curr_state
, mips_ls2
.alu2_core_unit_code
))
15079 mips_ls2
.alu1_turn_p
= true;
15082 if (mips_ls2
.falu1_turn_p
)
15084 if (cpu_unit_reservation_p (curr_state
, mips_ls2
.falu1_core_unit_code
))
15085 mips_ls2
.falu1_turn_p
= false;
15089 if (cpu_unit_reservation_p (curr_state
, mips_ls2
.falu2_core_unit_code
))
15090 mips_ls2
.falu1_turn_p
= true;
15093 if (recog_memoized (insn
) >= 0)
15094 mips_ls2
.cycle_has_multi_p
|= (get_attr_type (insn
) == TYPE_MULTI
);
15097 /* Implement TARGET_SCHED_VARIABLE_ISSUE. */
15100 mips_variable_issue (FILE *file ATTRIBUTE_UNUSED
, int verbose ATTRIBUTE_UNUSED
,
15101 rtx_insn
*insn
, int more
)
15103 /* Ignore USEs and CLOBBERs; don't count them against the issue rate. */
15104 if (USEFUL_INSN_P (insn
))
15106 if (get_attr_type (insn
) != TYPE_GHOST
)
15108 if (!reload_completed
&& TUNE_MACC_CHAINS
)
15109 mips_macc_chains_record (insn
);
15110 vr4130_last_insn
= insn
;
15112 mips_74k_agen_init (insn
);
15113 else if (TUNE_LOONGSON_2EF
)
15114 mips_ls2_variable_issue (insn
);
15117 /* Instructions of type 'multi' should all be split before
15118 the second scheduling pass. */
15119 gcc_assert (!reload_completed
15120 || recog_memoized (insn
) < 0
15121 || get_attr_type (insn
) != TYPE_MULTI
);
15123 cached_can_issue_more
= more
;
15127 /* Given that we have an rtx of the form (prefetch ... WRITE LOCALITY),
15128 return the first operand of the associated PREF or PREFX insn. */
15131 mips_prefetch_cookie (rtx write
, rtx locality
)
15133 /* store_streamed / load_streamed. */
15134 if (INTVAL (locality
) <= 0)
15135 return GEN_INT (INTVAL (write
) + 4);
15137 /* store / load. */
15138 if (INTVAL (locality
) <= 2)
15141 /* store_retained / load_retained. */
15142 return GEN_INT (INTVAL (write
) + 6);
15145 /* Flags that indicate when a built-in function is available.
15147 BUILTIN_AVAIL_NON_MIPS16
15148 The function is available on the current target if !TARGET_MIPS16.
15150 BUILTIN_AVAIL_MIPS16
15151 The function is available on the current target if TARGET_MIPS16. */
15152 #define BUILTIN_AVAIL_NON_MIPS16 1
15153 #define BUILTIN_AVAIL_MIPS16 2
15155 /* Declare an availability predicate for built-in functions that
15156 require non-MIPS16 mode and also require COND to be true.
15157 NAME is the main part of the predicate's name. */
15158 #define AVAIL_NON_MIPS16(NAME, COND) \
15159 static unsigned int \
15160 mips_builtin_avail_##NAME (void) \
15162 return (COND) ? BUILTIN_AVAIL_NON_MIPS16 : 0; \
15165 /* Declare an availability predicate for built-in functions that
15166 support both MIPS16 and non-MIPS16 code and also require COND
15167 to be true. NAME is the main part of the predicate's name. */
15168 #define AVAIL_ALL(NAME, COND) \
15169 static unsigned int \
15170 mips_builtin_avail_##NAME (void) \
15172 return (COND) ? BUILTIN_AVAIL_NON_MIPS16 | BUILTIN_AVAIL_MIPS16 : 0; \
15175 /* This structure describes a single built-in function. */
15176 struct mips_builtin_description
{
15177 /* The code of the main .md file instruction. See mips_builtin_type
15178 for more information. */
15179 enum insn_code icode
;
15181 /* The floating-point comparison code to use with ICODE, if any. */
15182 enum mips_fp_condition cond
;
15184 /* The name of the built-in function. */
15187 /* Specifies how the function should be expanded. */
15188 enum mips_builtin_type builtin_type
;
15190 /* The function's prototype. */
15191 enum mips_function_type function_type
;
15193 /* Whether the function is available. */
15194 unsigned int (*avail
) (void);
15197 AVAIL_ALL (hard_float
, TARGET_HARD_FLOAT_ABI
)
15198 AVAIL_NON_MIPS16 (paired_single
, TARGET_PAIRED_SINGLE_FLOAT
)
15199 AVAIL_NON_MIPS16 (sb1_paired_single
, TARGET_SB1
&& TARGET_PAIRED_SINGLE_FLOAT
)
15200 AVAIL_NON_MIPS16 (mips3d
, TARGET_MIPS3D
)
15201 AVAIL_NON_MIPS16 (dsp
, TARGET_DSP
)
15202 AVAIL_NON_MIPS16 (dspr2
, TARGET_DSPR2
)
15203 AVAIL_NON_MIPS16 (dsp_32
, !TARGET_64BIT
&& TARGET_DSP
)
15204 AVAIL_NON_MIPS16 (dsp_64
, TARGET_64BIT
&& TARGET_DSP
)
15205 AVAIL_NON_MIPS16 (dspr2_32
, !TARGET_64BIT
&& TARGET_DSPR2
)
15206 AVAIL_NON_MIPS16 (loongson
, TARGET_LOONGSON_VECTORS
)
15207 AVAIL_NON_MIPS16 (cache
, TARGET_CACHE_BUILTIN
)
15208 AVAIL_NON_MIPS16 (msa
, TARGET_MSA
)
15210 /* Construct a mips_builtin_description from the given arguments.
15212 INSN is the name of the associated instruction pattern, without the
15213 leading CODE_FOR_mips_.
15215 CODE is the floating-point condition code associated with the
15216 function. It can be 'f' if the field is not applicable.
15218 NAME is the name of the function itself, without the leading
15221 BUILTIN_TYPE and FUNCTION_TYPE are mips_builtin_description fields.
15223 AVAIL is the name of the availability predicate, without the leading
15224 mips_builtin_avail_. */
15225 #define MIPS_BUILTIN(INSN, COND, NAME, BUILTIN_TYPE, \
15226 FUNCTION_TYPE, AVAIL) \
15227 { CODE_FOR_mips_ ## INSN, MIPS_FP_COND_ ## COND, \
15228 "__builtin_mips_" NAME, BUILTIN_TYPE, FUNCTION_TYPE, \
15229 mips_builtin_avail_ ## AVAIL }
15231 /* Define __builtin_mips_<INSN>, which is a MIPS_BUILTIN_DIRECT function
15232 mapped to instruction CODE_FOR_mips_<INSN>, FUNCTION_TYPE and AVAIL
15233 are as for MIPS_BUILTIN. */
15234 #define DIRECT_BUILTIN(INSN, FUNCTION_TYPE, AVAIL) \
15235 MIPS_BUILTIN (INSN, f, #INSN, MIPS_BUILTIN_DIRECT, FUNCTION_TYPE, AVAIL)
15237 /* Define __builtin_mips_<INSN>_<COND>_{s,d} functions, both of which
15238 are subject to mips_builtin_avail_<AVAIL>. */
15239 #define CMP_SCALAR_BUILTINS(INSN, COND, AVAIL) \
15240 MIPS_BUILTIN (INSN ## _cond_s, COND, #INSN "_" #COND "_s", \
15241 MIPS_BUILTIN_CMP_SINGLE, MIPS_INT_FTYPE_SF_SF, AVAIL), \
15242 MIPS_BUILTIN (INSN ## _cond_d, COND, #INSN "_" #COND "_d", \
15243 MIPS_BUILTIN_CMP_SINGLE, MIPS_INT_FTYPE_DF_DF, AVAIL)
15245 /* Define __builtin_mips_{any,all,upper,lower}_<INSN>_<COND>_ps.
15246 The lower and upper forms are subject to mips_builtin_avail_<AVAIL>
15247 while the any and all forms are subject to mips_builtin_avail_mips3d. */
15248 #define CMP_PS_BUILTINS(INSN, COND, AVAIL) \
15249 MIPS_BUILTIN (INSN ## _cond_ps, COND, "any_" #INSN "_" #COND "_ps", \
15250 MIPS_BUILTIN_CMP_ANY, MIPS_INT_FTYPE_V2SF_V2SF, \
15252 MIPS_BUILTIN (INSN ## _cond_ps, COND, "all_" #INSN "_" #COND "_ps", \
15253 MIPS_BUILTIN_CMP_ALL, MIPS_INT_FTYPE_V2SF_V2SF, \
15255 MIPS_BUILTIN (INSN ## _cond_ps, COND, "lower_" #INSN "_" #COND "_ps", \
15256 MIPS_BUILTIN_CMP_LOWER, MIPS_INT_FTYPE_V2SF_V2SF, \
15258 MIPS_BUILTIN (INSN ## _cond_ps, COND, "upper_" #INSN "_" #COND "_ps", \
15259 MIPS_BUILTIN_CMP_UPPER, MIPS_INT_FTYPE_V2SF_V2SF, \
15262 /* Define __builtin_mips_{any,all}_<INSN>_<COND>_4s. The functions
15263 are subject to mips_builtin_avail_mips3d. */
15264 #define CMP_4S_BUILTINS(INSN, COND) \
15265 MIPS_BUILTIN (INSN ## _cond_4s, COND, "any_" #INSN "_" #COND "_4s", \
15266 MIPS_BUILTIN_CMP_ANY, \
15267 MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF, mips3d), \
15268 MIPS_BUILTIN (INSN ## _cond_4s, COND, "all_" #INSN "_" #COND "_4s", \
15269 MIPS_BUILTIN_CMP_ALL, \
15270 MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF, mips3d)
15272 /* Define __builtin_mips_mov{t,f}_<INSN>_<COND>_ps. The comparison
15273 instruction requires mips_builtin_avail_<AVAIL>. */
15274 #define MOVTF_BUILTINS(INSN, COND, AVAIL) \
15275 MIPS_BUILTIN (INSN ## _cond_ps, COND, "movt_" #INSN "_" #COND "_ps", \
15276 MIPS_BUILTIN_MOVT, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF, \
15278 MIPS_BUILTIN (INSN ## _cond_ps, COND, "movf_" #INSN "_" #COND "_ps", \
15279 MIPS_BUILTIN_MOVF, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF, \
15282 /* Define all the built-in functions related to C.cond.fmt condition COND. */
15283 #define CMP_BUILTINS(COND) \
15284 MOVTF_BUILTINS (c, COND, paired_single), \
15285 MOVTF_BUILTINS (cabs, COND, mips3d), \
15286 CMP_SCALAR_BUILTINS (cabs, COND, mips3d), \
15287 CMP_PS_BUILTINS (c, COND, paired_single), \
15288 CMP_PS_BUILTINS (cabs, COND, mips3d), \
15289 CMP_4S_BUILTINS (c, COND), \
15290 CMP_4S_BUILTINS (cabs, COND)
15292 /* Define __builtin_mips_<INSN>, which is a MIPS_BUILTIN_DIRECT_NO_TARGET
15293 function mapped to instruction CODE_FOR_mips_<INSN>, FUNCTION_TYPE
15294 and AVAIL are as for MIPS_BUILTIN. */
15295 #define DIRECT_NO_TARGET_BUILTIN(INSN, FUNCTION_TYPE, AVAIL) \
15296 MIPS_BUILTIN (INSN, f, #INSN, MIPS_BUILTIN_DIRECT_NO_TARGET, \
15297 FUNCTION_TYPE, AVAIL)
15299 /* Define __builtin_mips_bposge<VALUE>. <VALUE> is 32 for the MIPS32 DSP
15300 branch instruction. AVAIL is as for MIPS_BUILTIN. */
15301 #define BPOSGE_BUILTIN(VALUE, AVAIL) \
15302 MIPS_BUILTIN (bposge, f, "bposge" #VALUE, \
15303 MIPS_BUILTIN_BPOSGE ## VALUE, MIPS_SI_FTYPE_VOID, AVAIL)
15305 /* Define a Loongson MIPS_BUILTIN_DIRECT function __builtin_loongson_<FN_NAME>
15306 for instruction CODE_FOR_loongson_<INSN>. FUNCTION_TYPE is a
15307 builtin_description field. */
15308 #define LOONGSON_BUILTIN_ALIAS(INSN, FN_NAME, FUNCTION_TYPE) \
15309 { CODE_FOR_loongson_ ## INSN, MIPS_FP_COND_f, \
15310 "__builtin_loongson_" #FN_NAME, MIPS_BUILTIN_DIRECT, \
15311 FUNCTION_TYPE, mips_builtin_avail_loongson }
15313 /* Define a Loongson MIPS_BUILTIN_DIRECT function __builtin_loongson_<INSN>
15314 for instruction CODE_FOR_loongson_<INSN>. FUNCTION_TYPE is a
15315 builtin_description field. */
15316 #define LOONGSON_BUILTIN(INSN, FUNCTION_TYPE) \
15317 LOONGSON_BUILTIN_ALIAS (INSN, INSN, FUNCTION_TYPE)
15319 /* Like LOONGSON_BUILTIN, but add _<SUFFIX> to the end of the function name.
15320 We use functions of this form when the same insn can be usefully applied
15321 to more than one datatype. */
15322 #define LOONGSON_BUILTIN_SUFFIX(INSN, SUFFIX, FUNCTION_TYPE) \
15323 LOONGSON_BUILTIN_ALIAS (INSN, INSN ## _ ## SUFFIX, FUNCTION_TYPE)
15325 /* Define an MSA MIPS_BUILTIN_DIRECT function __builtin_msa_<INSN>
15326 for instruction CODE_FOR_msa_<INSN>. FUNCTION_TYPE is a builtin_description
15328 #define MSA_BUILTIN(INSN, FUNCTION_TYPE) \
15329 { CODE_FOR_msa_ ## INSN, MIPS_FP_COND_f, \
15330 "__builtin_msa_" #INSN, MIPS_BUILTIN_DIRECT, \
15331 FUNCTION_TYPE, mips_builtin_avail_msa }
15333 /* Define a remapped MSA MIPS_BUILTIN_DIRECT function __builtin_msa_<INSN>
15334 for instruction CODE_FOR_msa_<INSN2>. FUNCTION_TYPE is
15335 a builtin_description field. */
15336 #define MSA_BUILTIN_REMAP(INSN, INSN2, FUNCTION_TYPE) \
15337 { CODE_FOR_msa_ ## INSN2, MIPS_FP_COND_f, \
15338 "__builtin_msa_" #INSN, MIPS_BUILTIN_DIRECT, \
15339 FUNCTION_TYPE, mips_builtin_avail_msa }
15341 /* Define an MSA MIPS_BUILTIN_MSA_TEST_BRANCH function __builtin_msa_<INSN>
15342 for instruction CODE_FOR_msa_<INSN>. FUNCTION_TYPE is a builtin_description
15344 #define MSA_BUILTIN_TEST_BRANCH(INSN, FUNCTION_TYPE) \
15345 { CODE_FOR_msa_ ## INSN, MIPS_FP_COND_f, \
15346 "__builtin_msa_" #INSN, MIPS_BUILTIN_MSA_TEST_BRANCH, \
15347 FUNCTION_TYPE, mips_builtin_avail_msa }
15349 /* Define an MSA MIPS_BUILTIN_DIRECT_NO_TARGET function __builtin_msa_<INSN>
15350 for instruction CODE_FOR_msa_<INSN>. FUNCTION_TYPE is a builtin_description
15352 #define MSA_NO_TARGET_BUILTIN(INSN, FUNCTION_TYPE) \
15353 { CODE_FOR_msa_ ## INSN, MIPS_FP_COND_f, \
15354 "__builtin_msa_" #INSN, MIPS_BUILTIN_DIRECT_NO_TARGET, \
15355 FUNCTION_TYPE, mips_builtin_avail_msa }
15357 #define CODE_FOR_mips_sqrt_ps CODE_FOR_sqrtv2sf2
15358 #define CODE_FOR_mips_addq_ph CODE_FOR_addv2hi3
15359 #define CODE_FOR_mips_addu_qb CODE_FOR_addv4qi3
15360 #define CODE_FOR_mips_subq_ph CODE_FOR_subv2hi3
15361 #define CODE_FOR_mips_subu_qb CODE_FOR_subv4qi3
15362 #define CODE_FOR_mips_mul_ph CODE_FOR_mulv2hi3
15363 #define CODE_FOR_mips_mult CODE_FOR_mulsidi3_32bit
15364 #define CODE_FOR_mips_multu CODE_FOR_umulsidi3_32bit
15366 #define CODE_FOR_loongson_packsswh CODE_FOR_vec_pack_ssat_v2si
15367 #define CODE_FOR_loongson_packsshb CODE_FOR_vec_pack_ssat_v4hi
15368 #define CODE_FOR_loongson_packushb CODE_FOR_vec_pack_usat_v4hi
15369 #define CODE_FOR_loongson_paddw CODE_FOR_addv2si3
15370 #define CODE_FOR_loongson_paddh CODE_FOR_addv4hi3
15371 #define CODE_FOR_loongson_paddb CODE_FOR_addv8qi3
15372 #define CODE_FOR_loongson_paddsh CODE_FOR_ssaddv4hi3
15373 #define CODE_FOR_loongson_paddsb CODE_FOR_ssaddv8qi3
15374 #define CODE_FOR_loongson_paddush CODE_FOR_usaddv4hi3
15375 #define CODE_FOR_loongson_paddusb CODE_FOR_usaddv8qi3
15376 #define CODE_FOR_loongson_pmaxsh CODE_FOR_smaxv4hi3
15377 #define CODE_FOR_loongson_pmaxub CODE_FOR_umaxv8qi3
15378 #define CODE_FOR_loongson_pminsh CODE_FOR_sminv4hi3
15379 #define CODE_FOR_loongson_pminub CODE_FOR_uminv8qi3
15380 #define CODE_FOR_loongson_pmulhuh CODE_FOR_umulv4hi3_highpart
15381 #define CODE_FOR_loongson_pmulhh CODE_FOR_smulv4hi3_highpart
15382 #define CODE_FOR_loongson_pmullh CODE_FOR_mulv4hi3
15383 #define CODE_FOR_loongson_psllh CODE_FOR_ashlv4hi3
15384 #define CODE_FOR_loongson_psllw CODE_FOR_ashlv2si3
15385 #define CODE_FOR_loongson_psrlh CODE_FOR_lshrv4hi3
15386 #define CODE_FOR_loongson_psrlw CODE_FOR_lshrv2si3
15387 #define CODE_FOR_loongson_psrah CODE_FOR_ashrv4hi3
15388 #define CODE_FOR_loongson_psraw CODE_FOR_ashrv2si3
15389 #define CODE_FOR_loongson_psubw CODE_FOR_subv2si3
15390 #define CODE_FOR_loongson_psubh CODE_FOR_subv4hi3
15391 #define CODE_FOR_loongson_psubb CODE_FOR_subv8qi3
15392 #define CODE_FOR_loongson_psubsh CODE_FOR_sssubv4hi3
15393 #define CODE_FOR_loongson_psubsb CODE_FOR_sssubv8qi3
15394 #define CODE_FOR_loongson_psubush CODE_FOR_ussubv4hi3
15395 #define CODE_FOR_loongson_psubusb CODE_FOR_ussubv8qi3
15397 #define CODE_FOR_msa_adds_s_b CODE_FOR_ssaddv16qi3
15398 #define CODE_FOR_msa_adds_s_h CODE_FOR_ssaddv8hi3
15399 #define CODE_FOR_msa_adds_s_w CODE_FOR_ssaddv4si3
15400 #define CODE_FOR_msa_adds_s_d CODE_FOR_ssaddv2di3
15401 #define CODE_FOR_msa_adds_u_b CODE_FOR_usaddv16qi3
15402 #define CODE_FOR_msa_adds_u_h CODE_FOR_usaddv8hi3
15403 #define CODE_FOR_msa_adds_u_w CODE_FOR_usaddv4si3
15404 #define CODE_FOR_msa_adds_u_d CODE_FOR_usaddv2di3
15405 #define CODE_FOR_msa_addv_b CODE_FOR_addv16qi3
15406 #define CODE_FOR_msa_addv_h CODE_FOR_addv8hi3
15407 #define CODE_FOR_msa_addv_w CODE_FOR_addv4si3
15408 #define CODE_FOR_msa_addv_d CODE_FOR_addv2di3
15409 #define CODE_FOR_msa_addvi_b CODE_FOR_addv16qi3
15410 #define CODE_FOR_msa_addvi_h CODE_FOR_addv8hi3
15411 #define CODE_FOR_msa_addvi_w CODE_FOR_addv4si3
15412 #define CODE_FOR_msa_addvi_d CODE_FOR_addv2di3
15413 #define CODE_FOR_msa_and_v CODE_FOR_andv16qi3
15414 #define CODE_FOR_msa_andi_b CODE_FOR_andv16qi3
15415 #define CODE_FOR_msa_bmnz_v CODE_FOR_msa_bmnz_b
15416 #define CODE_FOR_msa_bmnzi_b CODE_FOR_msa_bmnz_b
15417 #define CODE_FOR_msa_bmz_v CODE_FOR_msa_bmz_b
15418 #define CODE_FOR_msa_bmzi_b CODE_FOR_msa_bmz_b
15419 #define CODE_FOR_msa_bnz_v CODE_FOR_msa_bnz_v_b
15420 #define CODE_FOR_msa_bz_v CODE_FOR_msa_bz_v_b
15421 #define CODE_FOR_msa_bsel_v CODE_FOR_msa_bsel_b
15422 #define CODE_FOR_msa_bseli_b CODE_FOR_msa_bsel_b
15423 #define CODE_FOR_msa_ceqi_b CODE_FOR_msa_ceq_b
15424 #define CODE_FOR_msa_ceqi_h CODE_FOR_msa_ceq_h
15425 #define CODE_FOR_msa_ceqi_w CODE_FOR_msa_ceq_w
15426 #define CODE_FOR_msa_ceqi_d CODE_FOR_msa_ceq_d
15427 #define CODE_FOR_msa_clti_s_b CODE_FOR_msa_clt_s_b
15428 #define CODE_FOR_msa_clti_s_h CODE_FOR_msa_clt_s_h
15429 #define CODE_FOR_msa_clti_s_w CODE_FOR_msa_clt_s_w
15430 #define CODE_FOR_msa_clti_s_d CODE_FOR_msa_clt_s_d
15431 #define CODE_FOR_msa_clti_u_b CODE_FOR_msa_clt_u_b
15432 #define CODE_FOR_msa_clti_u_h CODE_FOR_msa_clt_u_h
15433 #define CODE_FOR_msa_clti_u_w CODE_FOR_msa_clt_u_w
15434 #define CODE_FOR_msa_clti_u_d CODE_FOR_msa_clt_u_d
15435 #define CODE_FOR_msa_clei_s_b CODE_FOR_msa_cle_s_b
15436 #define CODE_FOR_msa_clei_s_h CODE_FOR_msa_cle_s_h
15437 #define CODE_FOR_msa_clei_s_w CODE_FOR_msa_cle_s_w
15438 #define CODE_FOR_msa_clei_s_d CODE_FOR_msa_cle_s_d
15439 #define CODE_FOR_msa_clei_u_b CODE_FOR_msa_cle_u_b
15440 #define CODE_FOR_msa_clei_u_h CODE_FOR_msa_cle_u_h
15441 #define CODE_FOR_msa_clei_u_w CODE_FOR_msa_cle_u_w
15442 #define CODE_FOR_msa_clei_u_d CODE_FOR_msa_cle_u_d
15443 #define CODE_FOR_msa_div_s_b CODE_FOR_divv16qi3
15444 #define CODE_FOR_msa_div_s_h CODE_FOR_divv8hi3
15445 #define CODE_FOR_msa_div_s_w CODE_FOR_divv4si3
15446 #define CODE_FOR_msa_div_s_d CODE_FOR_divv2di3
15447 #define CODE_FOR_msa_div_u_b CODE_FOR_udivv16qi3
15448 #define CODE_FOR_msa_div_u_h CODE_FOR_udivv8hi3
15449 #define CODE_FOR_msa_div_u_w CODE_FOR_udivv4si3
15450 #define CODE_FOR_msa_div_u_d CODE_FOR_udivv2di3
15451 #define CODE_FOR_msa_fadd_w CODE_FOR_addv4sf3
15452 #define CODE_FOR_msa_fadd_d CODE_FOR_addv2df3
15453 #define CODE_FOR_msa_fexdo_w CODE_FOR_vec_pack_trunc_v2df
15454 #define CODE_FOR_msa_ftrunc_s_w CODE_FOR_fix_truncv4sfv4si2
15455 #define CODE_FOR_msa_ftrunc_s_d CODE_FOR_fix_truncv2dfv2di2
15456 #define CODE_FOR_msa_ftrunc_u_w CODE_FOR_fixuns_truncv4sfv4si2
15457 #define CODE_FOR_msa_ftrunc_u_d CODE_FOR_fixuns_truncv2dfv2di2
15458 #define CODE_FOR_msa_ffint_s_w CODE_FOR_floatv4siv4sf2
15459 #define CODE_FOR_msa_ffint_s_d CODE_FOR_floatv2div2df2
15460 #define CODE_FOR_msa_ffint_u_w CODE_FOR_floatunsv4siv4sf2
15461 #define CODE_FOR_msa_ffint_u_d CODE_FOR_floatunsv2div2df2
15462 #define CODE_FOR_msa_fsub_w CODE_FOR_subv4sf3
15463 #define CODE_FOR_msa_fsub_d CODE_FOR_subv2df3
15464 #define CODE_FOR_msa_fmadd_w CODE_FOR_fmav4sf4
15465 #define CODE_FOR_msa_fmadd_d CODE_FOR_fmav2df4
15466 #define CODE_FOR_msa_fmsub_w CODE_FOR_fnmav4sf4
15467 #define CODE_FOR_msa_fmsub_d CODE_FOR_fnmav2df4
15468 #define CODE_FOR_msa_fmul_w CODE_FOR_mulv4sf3
15469 #define CODE_FOR_msa_fmul_d CODE_FOR_mulv2df3
15470 #define CODE_FOR_msa_fdiv_w CODE_FOR_divv4sf3
15471 #define CODE_FOR_msa_fdiv_d CODE_FOR_divv2df3
15472 #define CODE_FOR_msa_fmax_w CODE_FOR_smaxv4sf3
15473 #define CODE_FOR_msa_fmax_d CODE_FOR_smaxv2df3
15474 #define CODE_FOR_msa_fmin_w CODE_FOR_sminv4sf3
15475 #define CODE_FOR_msa_fmin_d CODE_FOR_sminv2df3
15476 #define CODE_FOR_msa_fsqrt_w CODE_FOR_sqrtv4sf2
15477 #define CODE_FOR_msa_fsqrt_d CODE_FOR_sqrtv2df2
15478 #define CODE_FOR_msa_max_s_b CODE_FOR_smaxv16qi3
15479 #define CODE_FOR_msa_max_s_h CODE_FOR_smaxv8hi3
15480 #define CODE_FOR_msa_max_s_w CODE_FOR_smaxv4si3
15481 #define CODE_FOR_msa_max_s_d CODE_FOR_smaxv2di3
15482 #define CODE_FOR_msa_maxi_s_b CODE_FOR_smaxv16qi3
15483 #define CODE_FOR_msa_maxi_s_h CODE_FOR_smaxv8hi3
15484 #define CODE_FOR_msa_maxi_s_w CODE_FOR_smaxv4si3
15485 #define CODE_FOR_msa_maxi_s_d CODE_FOR_smaxv2di3
15486 #define CODE_FOR_msa_max_u_b CODE_FOR_umaxv16qi3
15487 #define CODE_FOR_msa_max_u_h CODE_FOR_umaxv8hi3
15488 #define CODE_FOR_msa_max_u_w CODE_FOR_umaxv4si3
15489 #define CODE_FOR_msa_max_u_d CODE_FOR_umaxv2di3
15490 #define CODE_FOR_msa_maxi_u_b CODE_FOR_umaxv16qi3
15491 #define CODE_FOR_msa_maxi_u_h CODE_FOR_umaxv8hi3
15492 #define CODE_FOR_msa_maxi_u_w CODE_FOR_umaxv4si3
15493 #define CODE_FOR_msa_maxi_u_d CODE_FOR_umaxv2di3
15494 #define CODE_FOR_msa_min_s_b CODE_FOR_sminv16qi3
15495 #define CODE_FOR_msa_min_s_h CODE_FOR_sminv8hi3
15496 #define CODE_FOR_msa_min_s_w CODE_FOR_sminv4si3
15497 #define CODE_FOR_msa_min_s_d CODE_FOR_sminv2di3
15498 #define CODE_FOR_msa_mini_s_b CODE_FOR_sminv16qi3
15499 #define CODE_FOR_msa_mini_s_h CODE_FOR_sminv8hi3
15500 #define CODE_FOR_msa_mini_s_w CODE_FOR_sminv4si3
15501 #define CODE_FOR_msa_mini_s_d CODE_FOR_sminv2di3
15502 #define CODE_FOR_msa_min_u_b CODE_FOR_uminv16qi3
15503 #define CODE_FOR_msa_min_u_h CODE_FOR_uminv8hi3
15504 #define CODE_FOR_msa_min_u_w CODE_FOR_uminv4si3
15505 #define CODE_FOR_msa_min_u_d CODE_FOR_uminv2di3
15506 #define CODE_FOR_msa_mini_u_b CODE_FOR_uminv16qi3
15507 #define CODE_FOR_msa_mini_u_h CODE_FOR_uminv8hi3
15508 #define CODE_FOR_msa_mini_u_w CODE_FOR_uminv4si3
15509 #define CODE_FOR_msa_mini_u_d CODE_FOR_uminv2di3
15510 #define CODE_FOR_msa_mod_s_b CODE_FOR_modv16qi3
15511 #define CODE_FOR_msa_mod_s_h CODE_FOR_modv8hi3
15512 #define CODE_FOR_msa_mod_s_w CODE_FOR_modv4si3
15513 #define CODE_FOR_msa_mod_s_d CODE_FOR_modv2di3
15514 #define CODE_FOR_msa_mod_u_b CODE_FOR_umodv16qi3
15515 #define CODE_FOR_msa_mod_u_h CODE_FOR_umodv8hi3
15516 #define CODE_FOR_msa_mod_u_w CODE_FOR_umodv4si3
15517 #define CODE_FOR_msa_mod_u_d CODE_FOR_umodv2di3
15518 #define CODE_FOR_msa_mod_s_b CODE_FOR_modv16qi3
15519 #define CODE_FOR_msa_mod_s_h CODE_FOR_modv8hi3
15520 #define CODE_FOR_msa_mod_s_w CODE_FOR_modv4si3
15521 #define CODE_FOR_msa_mod_s_d CODE_FOR_modv2di3
15522 #define CODE_FOR_msa_mod_u_b CODE_FOR_umodv16qi3
15523 #define CODE_FOR_msa_mod_u_h CODE_FOR_umodv8hi3
15524 #define CODE_FOR_msa_mod_u_w CODE_FOR_umodv4si3
15525 #define CODE_FOR_msa_mod_u_d CODE_FOR_umodv2di3
15526 #define CODE_FOR_msa_mulv_b CODE_FOR_mulv16qi3
15527 #define CODE_FOR_msa_mulv_h CODE_FOR_mulv8hi3
15528 #define CODE_FOR_msa_mulv_w CODE_FOR_mulv4si3
15529 #define CODE_FOR_msa_mulv_d CODE_FOR_mulv2di3
15530 #define CODE_FOR_msa_nlzc_b CODE_FOR_clzv16qi2
15531 #define CODE_FOR_msa_nlzc_h CODE_FOR_clzv8hi2
15532 #define CODE_FOR_msa_nlzc_w CODE_FOR_clzv4si2
15533 #define CODE_FOR_msa_nlzc_d CODE_FOR_clzv2di2
15534 #define CODE_FOR_msa_nor_v CODE_FOR_msa_nor_b
15535 #define CODE_FOR_msa_or_v CODE_FOR_iorv16qi3
15536 #define CODE_FOR_msa_ori_b CODE_FOR_iorv16qi3
15537 #define CODE_FOR_msa_nori_b CODE_FOR_msa_nor_b
15538 #define CODE_FOR_msa_pcnt_b CODE_FOR_popcountv16qi2
15539 #define CODE_FOR_msa_pcnt_h CODE_FOR_popcountv8hi2
15540 #define CODE_FOR_msa_pcnt_w CODE_FOR_popcountv4si2
15541 #define CODE_FOR_msa_pcnt_d CODE_FOR_popcountv2di2
15542 #define CODE_FOR_msa_xor_v CODE_FOR_xorv16qi3
15543 #define CODE_FOR_msa_xori_b CODE_FOR_xorv16qi3
15544 #define CODE_FOR_msa_sll_b CODE_FOR_vashlv16qi3
15545 #define CODE_FOR_msa_sll_h CODE_FOR_vashlv8hi3
15546 #define CODE_FOR_msa_sll_w CODE_FOR_vashlv4si3
15547 #define CODE_FOR_msa_sll_d CODE_FOR_vashlv2di3
15548 #define CODE_FOR_msa_slli_b CODE_FOR_vashlv16qi3
15549 #define CODE_FOR_msa_slli_h CODE_FOR_vashlv8hi3
15550 #define CODE_FOR_msa_slli_w CODE_FOR_vashlv4si3
15551 #define CODE_FOR_msa_slli_d CODE_FOR_vashlv2di3
15552 #define CODE_FOR_msa_sra_b CODE_FOR_vashrv16qi3
15553 #define CODE_FOR_msa_sra_h CODE_FOR_vashrv8hi3
15554 #define CODE_FOR_msa_sra_w CODE_FOR_vashrv4si3
15555 #define CODE_FOR_msa_sra_d CODE_FOR_vashrv2di3
15556 #define CODE_FOR_msa_srai_b CODE_FOR_vashrv16qi3
15557 #define CODE_FOR_msa_srai_h CODE_FOR_vashrv8hi3
15558 #define CODE_FOR_msa_srai_w CODE_FOR_vashrv4si3
15559 #define CODE_FOR_msa_srai_d CODE_FOR_vashrv2di3
15560 #define CODE_FOR_msa_srl_b CODE_FOR_vlshrv16qi3
15561 #define CODE_FOR_msa_srl_h CODE_FOR_vlshrv8hi3
15562 #define CODE_FOR_msa_srl_w CODE_FOR_vlshrv4si3
15563 #define CODE_FOR_msa_srl_d CODE_FOR_vlshrv2di3
15564 #define CODE_FOR_msa_srli_b CODE_FOR_vlshrv16qi3
15565 #define CODE_FOR_msa_srli_h CODE_FOR_vlshrv8hi3
15566 #define CODE_FOR_msa_srli_w CODE_FOR_vlshrv4si3
15567 #define CODE_FOR_msa_srli_d CODE_FOR_vlshrv2di3
15568 #define CODE_FOR_msa_subv_b CODE_FOR_subv16qi3
15569 #define CODE_FOR_msa_subv_h CODE_FOR_subv8hi3
15570 #define CODE_FOR_msa_subv_w CODE_FOR_subv4si3
15571 #define CODE_FOR_msa_subv_d CODE_FOR_subv2di3
15572 #define CODE_FOR_msa_subvi_b CODE_FOR_subv16qi3
15573 #define CODE_FOR_msa_subvi_h CODE_FOR_subv8hi3
15574 #define CODE_FOR_msa_subvi_w CODE_FOR_subv4si3
15575 #define CODE_FOR_msa_subvi_d CODE_FOR_subv2di3
15577 #define CODE_FOR_msa_move_v CODE_FOR_movv16qi
15579 #define CODE_FOR_msa_vshf_b CODE_FOR_vec_permv16qi
15580 #define CODE_FOR_msa_vshf_h CODE_FOR_vec_permv8hi
15581 #define CODE_FOR_msa_vshf_w CODE_FOR_vec_permv4si
15582 #define CODE_FOR_msa_vshf_d CODE_FOR_vec_permv2di
15584 #define CODE_FOR_msa_ilvod_d CODE_FOR_msa_ilvl_d
15585 #define CODE_FOR_msa_ilvev_d CODE_FOR_msa_ilvr_d
15586 #define CODE_FOR_msa_pckod_d CODE_FOR_msa_ilvl_d
15587 #define CODE_FOR_msa_pckev_d CODE_FOR_msa_ilvr_d
15589 #define CODE_FOR_msa_ldi_b CODE_FOR_msa_ldiv16qi
15590 #define CODE_FOR_msa_ldi_h CODE_FOR_msa_ldiv8hi
15591 #define CODE_FOR_msa_ldi_w CODE_FOR_msa_ldiv4si
15592 #define CODE_FOR_msa_ldi_d CODE_FOR_msa_ldiv2di
15594 static const struct mips_builtin_description mips_builtins
[] = {
15595 #define MIPS_GET_FCSR 0
15596 DIRECT_BUILTIN (get_fcsr
, MIPS_USI_FTYPE_VOID
, hard_float
),
15597 #define MIPS_SET_FCSR 1
15598 DIRECT_NO_TARGET_BUILTIN (set_fcsr
, MIPS_VOID_FTYPE_USI
, hard_float
),
15600 DIRECT_BUILTIN (pll_ps
, MIPS_V2SF_FTYPE_V2SF_V2SF
, paired_single
),
15601 DIRECT_BUILTIN (pul_ps
, MIPS_V2SF_FTYPE_V2SF_V2SF
, paired_single
),
15602 DIRECT_BUILTIN (plu_ps
, MIPS_V2SF_FTYPE_V2SF_V2SF
, paired_single
),
15603 DIRECT_BUILTIN (puu_ps
, MIPS_V2SF_FTYPE_V2SF_V2SF
, paired_single
),
15604 DIRECT_BUILTIN (cvt_ps_s
, MIPS_V2SF_FTYPE_SF_SF
, paired_single
),
15605 DIRECT_BUILTIN (cvt_s_pl
, MIPS_SF_FTYPE_V2SF
, paired_single
),
15606 DIRECT_BUILTIN (cvt_s_pu
, MIPS_SF_FTYPE_V2SF
, paired_single
),
15607 DIRECT_BUILTIN (abs_ps
, MIPS_V2SF_FTYPE_V2SF
, paired_single
),
15609 DIRECT_BUILTIN (alnv_ps
, MIPS_V2SF_FTYPE_V2SF_V2SF_INT
, paired_single
),
15610 DIRECT_BUILTIN (addr_ps
, MIPS_V2SF_FTYPE_V2SF_V2SF
, mips3d
),
15611 DIRECT_BUILTIN (mulr_ps
, MIPS_V2SF_FTYPE_V2SF_V2SF
, mips3d
),
15612 DIRECT_BUILTIN (cvt_pw_ps
, MIPS_V2SF_FTYPE_V2SF
, mips3d
),
15613 DIRECT_BUILTIN (cvt_ps_pw
, MIPS_V2SF_FTYPE_V2SF
, mips3d
),
15615 DIRECT_BUILTIN (recip1_s
, MIPS_SF_FTYPE_SF
, mips3d
),
15616 DIRECT_BUILTIN (recip1_d
, MIPS_DF_FTYPE_DF
, mips3d
),
15617 DIRECT_BUILTIN (recip1_ps
, MIPS_V2SF_FTYPE_V2SF
, mips3d
),
15618 DIRECT_BUILTIN (recip2_s
, MIPS_SF_FTYPE_SF_SF
, mips3d
),
15619 DIRECT_BUILTIN (recip2_d
, MIPS_DF_FTYPE_DF_DF
, mips3d
),
15620 DIRECT_BUILTIN (recip2_ps
, MIPS_V2SF_FTYPE_V2SF_V2SF
, mips3d
),
15622 DIRECT_BUILTIN (rsqrt1_s
, MIPS_SF_FTYPE_SF
, mips3d
),
15623 DIRECT_BUILTIN (rsqrt1_d
, MIPS_DF_FTYPE_DF
, mips3d
),
15624 DIRECT_BUILTIN (rsqrt1_ps
, MIPS_V2SF_FTYPE_V2SF
, mips3d
),
15625 DIRECT_BUILTIN (rsqrt2_s
, MIPS_SF_FTYPE_SF_SF
, mips3d
),
15626 DIRECT_BUILTIN (rsqrt2_d
, MIPS_DF_FTYPE_DF_DF
, mips3d
),
15627 DIRECT_BUILTIN (rsqrt2_ps
, MIPS_V2SF_FTYPE_V2SF_V2SF
, mips3d
),
15629 MIPS_FP_CONDITIONS (CMP_BUILTINS
),
15631 /* Built-in functions for the SB-1 processor. */
15632 DIRECT_BUILTIN (sqrt_ps
, MIPS_V2SF_FTYPE_V2SF
, sb1_paired_single
),
15634 /* Built-in functions for the DSP ASE (32-bit and 64-bit). */
15635 DIRECT_BUILTIN (addq_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dsp
),
15636 DIRECT_BUILTIN (addq_s_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dsp
),
15637 DIRECT_BUILTIN (addq_s_w
, MIPS_SI_FTYPE_SI_SI
, dsp
),
15638 DIRECT_BUILTIN (addu_qb
, MIPS_V4QI_FTYPE_V4QI_V4QI
, dsp
),
15639 DIRECT_BUILTIN (addu_s_qb
, MIPS_V4QI_FTYPE_V4QI_V4QI
, dsp
),
15640 DIRECT_BUILTIN (subq_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dsp
),
15641 DIRECT_BUILTIN (subq_s_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dsp
),
15642 DIRECT_BUILTIN (subq_s_w
, MIPS_SI_FTYPE_SI_SI
, dsp
),
15643 DIRECT_BUILTIN (subu_qb
, MIPS_V4QI_FTYPE_V4QI_V4QI
, dsp
),
15644 DIRECT_BUILTIN (subu_s_qb
, MIPS_V4QI_FTYPE_V4QI_V4QI
, dsp
),
15645 DIRECT_BUILTIN (addsc
, MIPS_SI_FTYPE_SI_SI
, dsp
),
15646 DIRECT_BUILTIN (addwc
, MIPS_SI_FTYPE_SI_SI
, dsp
),
15647 DIRECT_BUILTIN (modsub
, MIPS_SI_FTYPE_SI_SI
, dsp
),
15648 DIRECT_BUILTIN (raddu_w_qb
, MIPS_SI_FTYPE_V4QI
, dsp
),
15649 DIRECT_BUILTIN (absq_s_ph
, MIPS_V2HI_FTYPE_V2HI
, dsp
),
15650 DIRECT_BUILTIN (absq_s_w
, MIPS_SI_FTYPE_SI
, dsp
),
15651 DIRECT_BUILTIN (precrq_qb_ph
, MIPS_V4QI_FTYPE_V2HI_V2HI
, dsp
),
15652 DIRECT_BUILTIN (precrq_ph_w
, MIPS_V2HI_FTYPE_SI_SI
, dsp
),
15653 DIRECT_BUILTIN (precrq_rs_ph_w
, MIPS_V2HI_FTYPE_SI_SI
, dsp
),
15654 DIRECT_BUILTIN (precrqu_s_qb_ph
, MIPS_V4QI_FTYPE_V2HI_V2HI
, dsp
),
15655 DIRECT_BUILTIN (preceq_w_phl
, MIPS_SI_FTYPE_V2HI
, dsp
),
15656 DIRECT_BUILTIN (preceq_w_phr
, MIPS_SI_FTYPE_V2HI
, dsp
),
15657 DIRECT_BUILTIN (precequ_ph_qbl
, MIPS_V2HI_FTYPE_V4QI
, dsp
),
15658 DIRECT_BUILTIN (precequ_ph_qbr
, MIPS_V2HI_FTYPE_V4QI
, dsp
),
15659 DIRECT_BUILTIN (precequ_ph_qbla
, MIPS_V2HI_FTYPE_V4QI
, dsp
),
15660 DIRECT_BUILTIN (precequ_ph_qbra
, MIPS_V2HI_FTYPE_V4QI
, dsp
),
15661 DIRECT_BUILTIN (preceu_ph_qbl
, MIPS_V2HI_FTYPE_V4QI
, dsp
),
15662 DIRECT_BUILTIN (preceu_ph_qbr
, MIPS_V2HI_FTYPE_V4QI
, dsp
),
15663 DIRECT_BUILTIN (preceu_ph_qbla
, MIPS_V2HI_FTYPE_V4QI
, dsp
),
15664 DIRECT_BUILTIN (preceu_ph_qbra
, MIPS_V2HI_FTYPE_V4QI
, dsp
),
15665 DIRECT_BUILTIN (shll_qb
, MIPS_V4QI_FTYPE_V4QI_SI
, dsp
),
15666 DIRECT_BUILTIN (shll_ph
, MIPS_V2HI_FTYPE_V2HI_SI
, dsp
),
15667 DIRECT_BUILTIN (shll_s_ph
, MIPS_V2HI_FTYPE_V2HI_SI
, dsp
),
15668 DIRECT_BUILTIN (shll_s_w
, MIPS_SI_FTYPE_SI_SI
, dsp
),
15669 DIRECT_BUILTIN (shrl_qb
, MIPS_V4QI_FTYPE_V4QI_SI
, dsp
),
15670 DIRECT_BUILTIN (shra_ph
, MIPS_V2HI_FTYPE_V2HI_SI
, dsp
),
15671 DIRECT_BUILTIN (shra_r_ph
, MIPS_V2HI_FTYPE_V2HI_SI
, dsp
),
15672 DIRECT_BUILTIN (shra_r_w
, MIPS_SI_FTYPE_SI_SI
, dsp
),
15673 DIRECT_BUILTIN (muleu_s_ph_qbl
, MIPS_V2HI_FTYPE_V4QI_V2HI
, dsp
),
15674 DIRECT_BUILTIN (muleu_s_ph_qbr
, MIPS_V2HI_FTYPE_V4QI_V2HI
, dsp
),
15675 DIRECT_BUILTIN (mulq_rs_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dsp
),
15676 DIRECT_BUILTIN (muleq_s_w_phl
, MIPS_SI_FTYPE_V2HI_V2HI
, dsp
),
15677 DIRECT_BUILTIN (muleq_s_w_phr
, MIPS_SI_FTYPE_V2HI_V2HI
, dsp
),
15678 DIRECT_BUILTIN (bitrev
, MIPS_SI_FTYPE_SI
, dsp
),
15679 DIRECT_BUILTIN (insv
, MIPS_SI_FTYPE_SI_SI
, dsp
),
15680 DIRECT_BUILTIN (repl_qb
, MIPS_V4QI_FTYPE_SI
, dsp
),
15681 DIRECT_BUILTIN (repl_ph
, MIPS_V2HI_FTYPE_SI
, dsp
),
15682 DIRECT_NO_TARGET_BUILTIN (cmpu_eq_qb
, MIPS_VOID_FTYPE_V4QI_V4QI
, dsp
),
15683 DIRECT_NO_TARGET_BUILTIN (cmpu_lt_qb
, MIPS_VOID_FTYPE_V4QI_V4QI
, dsp
),
15684 DIRECT_NO_TARGET_BUILTIN (cmpu_le_qb
, MIPS_VOID_FTYPE_V4QI_V4QI
, dsp
),
15685 DIRECT_BUILTIN (cmpgu_eq_qb
, MIPS_SI_FTYPE_V4QI_V4QI
, dsp
),
15686 DIRECT_BUILTIN (cmpgu_lt_qb
, MIPS_SI_FTYPE_V4QI_V4QI
, dsp
),
15687 DIRECT_BUILTIN (cmpgu_le_qb
, MIPS_SI_FTYPE_V4QI_V4QI
, dsp
),
15688 DIRECT_NO_TARGET_BUILTIN (cmp_eq_ph
, MIPS_VOID_FTYPE_V2HI_V2HI
, dsp
),
15689 DIRECT_NO_TARGET_BUILTIN (cmp_lt_ph
, MIPS_VOID_FTYPE_V2HI_V2HI
, dsp
),
15690 DIRECT_NO_TARGET_BUILTIN (cmp_le_ph
, MIPS_VOID_FTYPE_V2HI_V2HI
, dsp
),
15691 DIRECT_BUILTIN (pick_qb
, MIPS_V4QI_FTYPE_V4QI_V4QI
, dsp
),
15692 DIRECT_BUILTIN (pick_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dsp
),
15693 DIRECT_BUILTIN (packrl_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dsp
),
15694 DIRECT_NO_TARGET_BUILTIN (wrdsp
, MIPS_VOID_FTYPE_SI_SI
, dsp
),
15695 DIRECT_BUILTIN (rddsp
, MIPS_SI_FTYPE_SI
, dsp
),
15696 DIRECT_BUILTIN (lbux
, MIPS_SI_FTYPE_POINTER_SI
, dsp
),
15697 DIRECT_BUILTIN (lhx
, MIPS_SI_FTYPE_POINTER_SI
, dsp
),
15698 DIRECT_BUILTIN (lwx
, MIPS_SI_FTYPE_POINTER_SI
, dsp
),
15699 BPOSGE_BUILTIN (32, dsp
),
15701 /* The following are for the MIPS DSP ASE REV 2 (32-bit and 64-bit). */
15702 DIRECT_BUILTIN (absq_s_qb
, MIPS_V4QI_FTYPE_V4QI
, dspr2
),
15703 DIRECT_BUILTIN (addu_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dspr2
),
15704 DIRECT_BUILTIN (addu_s_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dspr2
),
15705 DIRECT_BUILTIN (adduh_qb
, MIPS_V4QI_FTYPE_V4QI_V4QI
, dspr2
),
15706 DIRECT_BUILTIN (adduh_r_qb
, MIPS_V4QI_FTYPE_V4QI_V4QI
, dspr2
),
15707 DIRECT_BUILTIN (append
, MIPS_SI_FTYPE_SI_SI_SI
, dspr2
),
15708 DIRECT_BUILTIN (balign
, MIPS_SI_FTYPE_SI_SI_SI
, dspr2
),
15709 DIRECT_BUILTIN (cmpgdu_eq_qb
, MIPS_SI_FTYPE_V4QI_V4QI
, dspr2
),
15710 DIRECT_BUILTIN (cmpgdu_lt_qb
, MIPS_SI_FTYPE_V4QI_V4QI
, dspr2
),
15711 DIRECT_BUILTIN (cmpgdu_le_qb
, MIPS_SI_FTYPE_V4QI_V4QI
, dspr2
),
15712 DIRECT_BUILTIN (mul_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dspr2
),
15713 DIRECT_BUILTIN (mul_s_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dspr2
),
15714 DIRECT_BUILTIN (mulq_rs_w
, MIPS_SI_FTYPE_SI_SI
, dspr2
),
15715 DIRECT_BUILTIN (mulq_s_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dspr2
),
15716 DIRECT_BUILTIN (mulq_s_w
, MIPS_SI_FTYPE_SI_SI
, dspr2
),
15717 DIRECT_BUILTIN (precr_qb_ph
, MIPS_V4QI_FTYPE_V2HI_V2HI
, dspr2
),
15718 DIRECT_BUILTIN (precr_sra_ph_w
, MIPS_V2HI_FTYPE_SI_SI_SI
, dspr2
),
15719 DIRECT_BUILTIN (precr_sra_r_ph_w
, MIPS_V2HI_FTYPE_SI_SI_SI
, dspr2
),
15720 DIRECT_BUILTIN (prepend
, MIPS_SI_FTYPE_SI_SI_SI
, dspr2
),
15721 DIRECT_BUILTIN (shra_qb
, MIPS_V4QI_FTYPE_V4QI_SI
, dspr2
),
15722 DIRECT_BUILTIN (shra_r_qb
, MIPS_V4QI_FTYPE_V4QI_SI
, dspr2
),
15723 DIRECT_BUILTIN (shrl_ph
, MIPS_V2HI_FTYPE_V2HI_SI
, dspr2
),
15724 DIRECT_BUILTIN (subu_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dspr2
),
15725 DIRECT_BUILTIN (subu_s_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dspr2
),
15726 DIRECT_BUILTIN (subuh_qb
, MIPS_V4QI_FTYPE_V4QI_V4QI
, dspr2
),
15727 DIRECT_BUILTIN (subuh_r_qb
, MIPS_V4QI_FTYPE_V4QI_V4QI
, dspr2
),
15728 DIRECT_BUILTIN (addqh_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dspr2
),
15729 DIRECT_BUILTIN (addqh_r_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dspr2
),
15730 DIRECT_BUILTIN (addqh_w
, MIPS_SI_FTYPE_SI_SI
, dspr2
),
15731 DIRECT_BUILTIN (addqh_r_w
, MIPS_SI_FTYPE_SI_SI
, dspr2
),
15732 DIRECT_BUILTIN (subqh_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dspr2
),
15733 DIRECT_BUILTIN (subqh_r_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dspr2
),
15734 DIRECT_BUILTIN (subqh_w
, MIPS_SI_FTYPE_SI_SI
, dspr2
),
15735 DIRECT_BUILTIN (subqh_r_w
, MIPS_SI_FTYPE_SI_SI
, dspr2
),
15737 /* Built-in functions for the DSP ASE (32-bit only). */
15738 DIRECT_BUILTIN (dpau_h_qbl
, MIPS_DI_FTYPE_DI_V4QI_V4QI
, dsp_32
),
15739 DIRECT_BUILTIN (dpau_h_qbr
, MIPS_DI_FTYPE_DI_V4QI_V4QI
, dsp_32
),
15740 DIRECT_BUILTIN (dpsu_h_qbl
, MIPS_DI_FTYPE_DI_V4QI_V4QI
, dsp_32
),
15741 DIRECT_BUILTIN (dpsu_h_qbr
, MIPS_DI_FTYPE_DI_V4QI_V4QI
, dsp_32
),
15742 DIRECT_BUILTIN (dpaq_s_w_ph
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dsp_32
),
15743 DIRECT_BUILTIN (dpsq_s_w_ph
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dsp_32
),
15744 DIRECT_BUILTIN (mulsaq_s_w_ph
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dsp_32
),
15745 DIRECT_BUILTIN (dpaq_sa_l_w
, MIPS_DI_FTYPE_DI_SI_SI
, dsp_32
),
15746 DIRECT_BUILTIN (dpsq_sa_l_w
, MIPS_DI_FTYPE_DI_SI_SI
, dsp_32
),
15747 DIRECT_BUILTIN (maq_s_w_phl
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dsp_32
),
15748 DIRECT_BUILTIN (maq_s_w_phr
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dsp_32
),
15749 DIRECT_BUILTIN (maq_sa_w_phl
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dsp_32
),
15750 DIRECT_BUILTIN (maq_sa_w_phr
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dsp_32
),
15751 DIRECT_BUILTIN (extr_w
, MIPS_SI_FTYPE_DI_SI
, dsp_32
),
15752 DIRECT_BUILTIN (extr_r_w
, MIPS_SI_FTYPE_DI_SI
, dsp_32
),
15753 DIRECT_BUILTIN (extr_rs_w
, MIPS_SI_FTYPE_DI_SI
, dsp_32
),
15754 DIRECT_BUILTIN (extr_s_h
, MIPS_SI_FTYPE_DI_SI
, dsp_32
),
15755 DIRECT_BUILTIN (extp
, MIPS_SI_FTYPE_DI_SI
, dsp_32
),
15756 DIRECT_BUILTIN (extpdp
, MIPS_SI_FTYPE_DI_SI
, dsp_32
),
15757 DIRECT_BUILTIN (shilo
, MIPS_DI_FTYPE_DI_SI
, dsp_32
),
15758 DIRECT_BUILTIN (mthlip
, MIPS_DI_FTYPE_DI_SI
, dsp_32
),
15759 DIRECT_BUILTIN (madd
, MIPS_DI_FTYPE_DI_SI_SI
, dsp_32
),
15760 DIRECT_BUILTIN (maddu
, MIPS_DI_FTYPE_DI_USI_USI
, dsp_32
),
15761 DIRECT_BUILTIN (msub
, MIPS_DI_FTYPE_DI_SI_SI
, dsp_32
),
15762 DIRECT_BUILTIN (msubu
, MIPS_DI_FTYPE_DI_USI_USI
, dsp_32
),
15763 DIRECT_BUILTIN (mult
, MIPS_DI_FTYPE_SI_SI
, dsp_32
),
15764 DIRECT_BUILTIN (multu
, MIPS_DI_FTYPE_USI_USI
, dsp_32
),
15766 /* Built-in functions for the DSP ASE (64-bit only). */
15767 DIRECT_BUILTIN (ldx
, MIPS_DI_FTYPE_POINTER_SI
, dsp_64
),
15769 /* The following are for the MIPS DSP ASE REV 2 (32-bit only). */
15770 DIRECT_BUILTIN (dpa_w_ph
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dspr2_32
),
15771 DIRECT_BUILTIN (dps_w_ph
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dspr2_32
),
15772 DIRECT_BUILTIN (mulsa_w_ph
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dspr2_32
),
15773 DIRECT_BUILTIN (dpax_w_ph
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dspr2_32
),
15774 DIRECT_BUILTIN (dpsx_w_ph
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dspr2_32
),
15775 DIRECT_BUILTIN (dpaqx_s_w_ph
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dspr2_32
),
15776 DIRECT_BUILTIN (dpaqx_sa_w_ph
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dspr2_32
),
15777 DIRECT_BUILTIN (dpsqx_s_w_ph
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dspr2_32
),
15778 DIRECT_BUILTIN (dpsqx_sa_w_ph
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dspr2_32
),
15780 /* Builtin functions for ST Microelectronics Loongson-2E/2F cores. */
15781 LOONGSON_BUILTIN (packsswh
, MIPS_V4HI_FTYPE_V2SI_V2SI
),
15782 LOONGSON_BUILTIN (packsshb
, MIPS_V8QI_FTYPE_V4HI_V4HI
),
15783 LOONGSON_BUILTIN (packushb
, MIPS_UV8QI_FTYPE_UV4HI_UV4HI
),
15784 LOONGSON_BUILTIN_SUFFIX (paddw
, u
, MIPS_UV2SI_FTYPE_UV2SI_UV2SI
),
15785 LOONGSON_BUILTIN_SUFFIX (paddh
, u
, MIPS_UV4HI_FTYPE_UV4HI_UV4HI
),
15786 LOONGSON_BUILTIN_SUFFIX (paddb
, u
, MIPS_UV8QI_FTYPE_UV8QI_UV8QI
),
15787 LOONGSON_BUILTIN_SUFFIX (paddw
, s
, MIPS_V2SI_FTYPE_V2SI_V2SI
),
15788 LOONGSON_BUILTIN_SUFFIX (paddh
, s
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
15789 LOONGSON_BUILTIN_SUFFIX (paddb
, s
, MIPS_V8QI_FTYPE_V8QI_V8QI
),
15790 LOONGSON_BUILTIN_SUFFIX (paddd
, u
, MIPS_UDI_FTYPE_UDI_UDI
),
15791 LOONGSON_BUILTIN_SUFFIX (paddd
, s
, MIPS_DI_FTYPE_DI_DI
),
15792 LOONGSON_BUILTIN (paddsh
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
15793 LOONGSON_BUILTIN (paddsb
, MIPS_V8QI_FTYPE_V8QI_V8QI
),
15794 LOONGSON_BUILTIN (paddush
, MIPS_UV4HI_FTYPE_UV4HI_UV4HI
),
15795 LOONGSON_BUILTIN (paddusb
, MIPS_UV8QI_FTYPE_UV8QI_UV8QI
),
15796 LOONGSON_BUILTIN_ALIAS (pandn_d
, pandn_ud
, MIPS_UDI_FTYPE_UDI_UDI
),
15797 LOONGSON_BUILTIN_ALIAS (pandn_w
, pandn_uw
, MIPS_UV2SI_FTYPE_UV2SI_UV2SI
),
15798 LOONGSON_BUILTIN_ALIAS (pandn_h
, pandn_uh
, MIPS_UV4HI_FTYPE_UV4HI_UV4HI
),
15799 LOONGSON_BUILTIN_ALIAS (pandn_b
, pandn_ub
, MIPS_UV8QI_FTYPE_UV8QI_UV8QI
),
15800 LOONGSON_BUILTIN_ALIAS (pandn_d
, pandn_sd
, MIPS_DI_FTYPE_DI_DI
),
15801 LOONGSON_BUILTIN_ALIAS (pandn_w
, pandn_sw
, MIPS_V2SI_FTYPE_V2SI_V2SI
),
15802 LOONGSON_BUILTIN_ALIAS (pandn_h
, pandn_sh
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
15803 LOONGSON_BUILTIN_ALIAS (pandn_b
, pandn_sb
, MIPS_V8QI_FTYPE_V8QI_V8QI
),
15804 LOONGSON_BUILTIN (pavgh
, MIPS_UV4HI_FTYPE_UV4HI_UV4HI
),
15805 LOONGSON_BUILTIN (pavgb
, MIPS_UV8QI_FTYPE_UV8QI_UV8QI
),
15806 LOONGSON_BUILTIN_SUFFIX (pcmpeqw
, u
, MIPS_UV2SI_FTYPE_UV2SI_UV2SI
),
15807 LOONGSON_BUILTIN_SUFFIX (pcmpeqh
, u
, MIPS_UV4HI_FTYPE_UV4HI_UV4HI
),
15808 LOONGSON_BUILTIN_SUFFIX (pcmpeqb
, u
, MIPS_UV8QI_FTYPE_UV8QI_UV8QI
),
15809 LOONGSON_BUILTIN_SUFFIX (pcmpeqw
, s
, MIPS_V2SI_FTYPE_V2SI_V2SI
),
15810 LOONGSON_BUILTIN_SUFFIX (pcmpeqh
, s
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
15811 LOONGSON_BUILTIN_SUFFIX (pcmpeqb
, s
, MIPS_V8QI_FTYPE_V8QI_V8QI
),
15812 LOONGSON_BUILTIN_SUFFIX (pcmpgtw
, u
, MIPS_UV2SI_FTYPE_UV2SI_UV2SI
),
15813 LOONGSON_BUILTIN_SUFFIX (pcmpgth
, u
, MIPS_UV4HI_FTYPE_UV4HI_UV4HI
),
15814 LOONGSON_BUILTIN_SUFFIX (pcmpgtb
, u
, MIPS_UV8QI_FTYPE_UV8QI_UV8QI
),
15815 LOONGSON_BUILTIN_SUFFIX (pcmpgtw
, s
, MIPS_V2SI_FTYPE_V2SI_V2SI
),
15816 LOONGSON_BUILTIN_SUFFIX (pcmpgth
, s
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
15817 LOONGSON_BUILTIN_SUFFIX (pcmpgtb
, s
, MIPS_V8QI_FTYPE_V8QI_V8QI
),
15818 LOONGSON_BUILTIN_SUFFIX (pextrh
, u
, MIPS_UV4HI_FTYPE_UV4HI_USI
),
15819 LOONGSON_BUILTIN_SUFFIX (pextrh
, s
, MIPS_V4HI_FTYPE_V4HI_USI
),
15820 LOONGSON_BUILTIN_SUFFIX (pinsrh_0
, u
, MIPS_UV4HI_FTYPE_UV4HI_UV4HI
),
15821 LOONGSON_BUILTIN_SUFFIX (pinsrh_1
, u
, MIPS_UV4HI_FTYPE_UV4HI_UV4HI
),
15822 LOONGSON_BUILTIN_SUFFIX (pinsrh_2
, u
, MIPS_UV4HI_FTYPE_UV4HI_UV4HI
),
15823 LOONGSON_BUILTIN_SUFFIX (pinsrh_3
, u
, MIPS_UV4HI_FTYPE_UV4HI_UV4HI
),
15824 LOONGSON_BUILTIN_SUFFIX (pinsrh_0
, s
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
15825 LOONGSON_BUILTIN_SUFFIX (pinsrh_1
, s
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
15826 LOONGSON_BUILTIN_SUFFIX (pinsrh_2
, s
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
15827 LOONGSON_BUILTIN_SUFFIX (pinsrh_3
, s
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
15828 LOONGSON_BUILTIN (pmaddhw
, MIPS_V2SI_FTYPE_V4HI_V4HI
),
15829 LOONGSON_BUILTIN (pmaxsh
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
15830 LOONGSON_BUILTIN (pmaxub
, MIPS_UV8QI_FTYPE_UV8QI_UV8QI
),
15831 LOONGSON_BUILTIN (pminsh
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
15832 LOONGSON_BUILTIN (pminub
, MIPS_UV8QI_FTYPE_UV8QI_UV8QI
),
15833 LOONGSON_BUILTIN_SUFFIX (pmovmskb
, u
, MIPS_UV8QI_FTYPE_UV8QI
),
15834 LOONGSON_BUILTIN_SUFFIX (pmovmskb
, s
, MIPS_V8QI_FTYPE_V8QI
),
15835 LOONGSON_BUILTIN (pmulhuh
, MIPS_UV4HI_FTYPE_UV4HI_UV4HI
),
15836 LOONGSON_BUILTIN (pmulhh
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
15837 LOONGSON_BUILTIN (pmullh
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
15838 LOONGSON_BUILTIN (pmuluw
, MIPS_UDI_FTYPE_UV2SI_UV2SI
),
15839 LOONGSON_BUILTIN (pasubub
, MIPS_UV8QI_FTYPE_UV8QI_UV8QI
),
15840 LOONGSON_BUILTIN (biadd
, MIPS_UV4HI_FTYPE_UV8QI
),
15841 LOONGSON_BUILTIN (psadbh
, MIPS_UV4HI_FTYPE_UV8QI_UV8QI
),
15842 LOONGSON_BUILTIN_SUFFIX (pshufh
, u
, MIPS_UV4HI_FTYPE_UV4HI_UQI
),
15843 LOONGSON_BUILTIN_SUFFIX (pshufh
, s
, MIPS_V4HI_FTYPE_V4HI_UQI
),
15844 LOONGSON_BUILTIN_SUFFIX (psllh
, u
, MIPS_UV4HI_FTYPE_UV4HI_UQI
),
15845 LOONGSON_BUILTIN_SUFFIX (psllh
, s
, MIPS_V4HI_FTYPE_V4HI_UQI
),
15846 LOONGSON_BUILTIN_SUFFIX (psllw
, u
, MIPS_UV2SI_FTYPE_UV2SI_UQI
),
15847 LOONGSON_BUILTIN_SUFFIX (psllw
, s
, MIPS_V2SI_FTYPE_V2SI_UQI
),
15848 LOONGSON_BUILTIN_SUFFIX (psrah
, u
, MIPS_UV4HI_FTYPE_UV4HI_UQI
),
15849 LOONGSON_BUILTIN_SUFFIX (psrah
, s
, MIPS_V4HI_FTYPE_V4HI_UQI
),
15850 LOONGSON_BUILTIN_SUFFIX (psraw
, u
, MIPS_UV2SI_FTYPE_UV2SI_UQI
),
15851 LOONGSON_BUILTIN_SUFFIX (psraw
, s
, MIPS_V2SI_FTYPE_V2SI_UQI
),
15852 LOONGSON_BUILTIN_SUFFIX (psrlh
, u
, MIPS_UV4HI_FTYPE_UV4HI_UQI
),
15853 LOONGSON_BUILTIN_SUFFIX (psrlh
, s
, MIPS_V4HI_FTYPE_V4HI_UQI
),
15854 LOONGSON_BUILTIN_SUFFIX (psrlw
, u
, MIPS_UV2SI_FTYPE_UV2SI_UQI
),
15855 LOONGSON_BUILTIN_SUFFIX (psrlw
, s
, MIPS_V2SI_FTYPE_V2SI_UQI
),
15856 LOONGSON_BUILTIN_SUFFIX (psubw
, u
, MIPS_UV2SI_FTYPE_UV2SI_UV2SI
),
15857 LOONGSON_BUILTIN_SUFFIX (psubh
, u
, MIPS_UV4HI_FTYPE_UV4HI_UV4HI
),
15858 LOONGSON_BUILTIN_SUFFIX (psubb
, u
, MIPS_UV8QI_FTYPE_UV8QI_UV8QI
),
15859 LOONGSON_BUILTIN_SUFFIX (psubw
, s
, MIPS_V2SI_FTYPE_V2SI_V2SI
),
15860 LOONGSON_BUILTIN_SUFFIX (psubh
, s
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
15861 LOONGSON_BUILTIN_SUFFIX (psubb
, s
, MIPS_V8QI_FTYPE_V8QI_V8QI
),
15862 LOONGSON_BUILTIN_SUFFIX (psubd
, u
, MIPS_UDI_FTYPE_UDI_UDI
),
15863 LOONGSON_BUILTIN_SUFFIX (psubd
, s
, MIPS_DI_FTYPE_DI_DI
),
15864 LOONGSON_BUILTIN (psubsh
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
15865 LOONGSON_BUILTIN (psubsb
, MIPS_V8QI_FTYPE_V8QI_V8QI
),
15866 LOONGSON_BUILTIN (psubush
, MIPS_UV4HI_FTYPE_UV4HI_UV4HI
),
15867 LOONGSON_BUILTIN (psubusb
, MIPS_UV8QI_FTYPE_UV8QI_UV8QI
),
15868 LOONGSON_BUILTIN_SUFFIX (punpckhbh
, u
, MIPS_UV8QI_FTYPE_UV8QI_UV8QI
),
15869 LOONGSON_BUILTIN_SUFFIX (punpckhhw
, u
, MIPS_UV4HI_FTYPE_UV4HI_UV4HI
),
15870 LOONGSON_BUILTIN_SUFFIX (punpckhwd
, u
, MIPS_UV2SI_FTYPE_UV2SI_UV2SI
),
15871 LOONGSON_BUILTIN_SUFFIX (punpckhbh
, s
, MIPS_V8QI_FTYPE_V8QI_V8QI
),
15872 LOONGSON_BUILTIN_SUFFIX (punpckhhw
, s
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
15873 LOONGSON_BUILTIN_SUFFIX (punpckhwd
, s
, MIPS_V2SI_FTYPE_V2SI_V2SI
),
15874 LOONGSON_BUILTIN_SUFFIX (punpcklbh
, u
, MIPS_UV8QI_FTYPE_UV8QI_UV8QI
),
15875 LOONGSON_BUILTIN_SUFFIX (punpcklhw
, u
, MIPS_UV4HI_FTYPE_UV4HI_UV4HI
),
15876 LOONGSON_BUILTIN_SUFFIX (punpcklwd
, u
, MIPS_UV2SI_FTYPE_UV2SI_UV2SI
),
15877 LOONGSON_BUILTIN_SUFFIX (punpcklbh
, s
, MIPS_V8QI_FTYPE_V8QI_V8QI
),
15878 LOONGSON_BUILTIN_SUFFIX (punpcklhw
, s
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
15879 LOONGSON_BUILTIN_SUFFIX (punpcklwd
, s
, MIPS_V2SI_FTYPE_V2SI_V2SI
),
15881 /* Sundry other built-in functions. */
15882 DIRECT_NO_TARGET_BUILTIN (cache
, MIPS_VOID_FTYPE_SI_CVPOINTER
, cache
),
15884 /* Built-in functions for MSA. */
15885 MSA_BUILTIN (sll_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
15886 MSA_BUILTIN (sll_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
15887 MSA_BUILTIN (sll_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
15888 MSA_BUILTIN (sll_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
15889 MSA_BUILTIN (slli_b
, MIPS_V16QI_FTYPE_V16QI_UQI
),
15890 MSA_BUILTIN (slli_h
, MIPS_V8HI_FTYPE_V8HI_UQI
),
15891 MSA_BUILTIN (slli_w
, MIPS_V4SI_FTYPE_V4SI_UQI
),
15892 MSA_BUILTIN (slli_d
, MIPS_V2DI_FTYPE_V2DI_UQI
),
15893 MSA_BUILTIN (sra_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
15894 MSA_BUILTIN (sra_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
15895 MSA_BUILTIN (sra_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
15896 MSA_BUILTIN (sra_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
15897 MSA_BUILTIN (srai_b
, MIPS_V16QI_FTYPE_V16QI_UQI
),
15898 MSA_BUILTIN (srai_h
, MIPS_V8HI_FTYPE_V8HI_UQI
),
15899 MSA_BUILTIN (srai_w
, MIPS_V4SI_FTYPE_V4SI_UQI
),
15900 MSA_BUILTIN (srai_d
, MIPS_V2DI_FTYPE_V2DI_UQI
),
15901 MSA_BUILTIN (srar_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
15902 MSA_BUILTIN (srar_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
15903 MSA_BUILTIN (srar_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
15904 MSA_BUILTIN (srar_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
15905 MSA_BUILTIN (srari_b
, MIPS_V16QI_FTYPE_V16QI_UQI
),
15906 MSA_BUILTIN (srari_h
, MIPS_V8HI_FTYPE_V8HI_UQI
),
15907 MSA_BUILTIN (srari_w
, MIPS_V4SI_FTYPE_V4SI_UQI
),
15908 MSA_BUILTIN (srari_d
, MIPS_V2DI_FTYPE_V2DI_UQI
),
15909 MSA_BUILTIN (srl_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
15910 MSA_BUILTIN (srl_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
15911 MSA_BUILTIN (srl_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
15912 MSA_BUILTIN (srl_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
15913 MSA_BUILTIN (srli_b
, MIPS_V16QI_FTYPE_V16QI_UQI
),
15914 MSA_BUILTIN (srli_h
, MIPS_V8HI_FTYPE_V8HI_UQI
),
15915 MSA_BUILTIN (srli_w
, MIPS_V4SI_FTYPE_V4SI_UQI
),
15916 MSA_BUILTIN (srli_d
, MIPS_V2DI_FTYPE_V2DI_UQI
),
15917 MSA_BUILTIN (srlr_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
15918 MSA_BUILTIN (srlr_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
15919 MSA_BUILTIN (srlr_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
15920 MSA_BUILTIN (srlr_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
15921 MSA_BUILTIN (srlri_b
, MIPS_V16QI_FTYPE_V16QI_UQI
),
15922 MSA_BUILTIN (srlri_h
, MIPS_V8HI_FTYPE_V8HI_UQI
),
15923 MSA_BUILTIN (srlri_w
, MIPS_V4SI_FTYPE_V4SI_UQI
),
15924 MSA_BUILTIN (srlri_d
, MIPS_V2DI_FTYPE_V2DI_UQI
),
15925 MSA_BUILTIN (bclr_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
15926 MSA_BUILTIN (bclr_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI
),
15927 MSA_BUILTIN (bclr_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI
),
15928 MSA_BUILTIN (bclr_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI
),
15929 MSA_BUILTIN (bclri_b
, MIPS_UV16QI_FTYPE_UV16QI_UQI
),
15930 MSA_BUILTIN (bclri_h
, MIPS_UV8HI_FTYPE_UV8HI_UQI
),
15931 MSA_BUILTIN (bclri_w
, MIPS_UV4SI_FTYPE_UV4SI_UQI
),
15932 MSA_BUILTIN (bclri_d
, MIPS_UV2DI_FTYPE_UV2DI_UQI
),
15933 MSA_BUILTIN (bset_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
15934 MSA_BUILTIN (bset_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI
),
15935 MSA_BUILTIN (bset_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI
),
15936 MSA_BUILTIN (bset_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI
),
15937 MSA_BUILTIN (bseti_b
, MIPS_UV16QI_FTYPE_UV16QI_UQI
),
15938 MSA_BUILTIN (bseti_h
, MIPS_UV8HI_FTYPE_UV8HI_UQI
),
15939 MSA_BUILTIN (bseti_w
, MIPS_UV4SI_FTYPE_UV4SI_UQI
),
15940 MSA_BUILTIN (bseti_d
, MIPS_UV2DI_FTYPE_UV2DI_UQI
),
15941 MSA_BUILTIN (bneg_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
15942 MSA_BUILTIN (bneg_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI
),
15943 MSA_BUILTIN (bneg_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI
),
15944 MSA_BUILTIN (bneg_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI
),
15945 MSA_BUILTIN (bnegi_b
, MIPS_UV16QI_FTYPE_UV16QI_UQI
),
15946 MSA_BUILTIN (bnegi_h
, MIPS_UV8HI_FTYPE_UV8HI_UQI
),
15947 MSA_BUILTIN (bnegi_w
, MIPS_UV4SI_FTYPE_UV4SI_UQI
),
15948 MSA_BUILTIN (bnegi_d
, MIPS_UV2DI_FTYPE_UV2DI_UQI
),
15949 MSA_BUILTIN (binsl_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UV16QI
),
15950 MSA_BUILTIN (binsl_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI_UV8HI
),
15951 MSA_BUILTIN (binsl_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI_UV4SI
),
15952 MSA_BUILTIN (binsl_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI_UV2DI
),
15953 MSA_BUILTIN (binsli_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UQI
),
15954 MSA_BUILTIN (binsli_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI_UQI
),
15955 MSA_BUILTIN (binsli_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI_UQI
),
15956 MSA_BUILTIN (binsli_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI_UQI
),
15957 MSA_BUILTIN (binsr_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UV16QI
),
15958 MSA_BUILTIN (binsr_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI_UV8HI
),
15959 MSA_BUILTIN (binsr_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI_UV4SI
),
15960 MSA_BUILTIN (binsr_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI_UV2DI
),
15961 MSA_BUILTIN (binsri_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UQI
),
15962 MSA_BUILTIN (binsri_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI_UQI
),
15963 MSA_BUILTIN (binsri_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI_UQI
),
15964 MSA_BUILTIN (binsri_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI_UQI
),
15965 MSA_BUILTIN (addv_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
15966 MSA_BUILTIN (addv_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
15967 MSA_BUILTIN (addv_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
15968 MSA_BUILTIN (addv_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
15969 MSA_BUILTIN (addvi_b
, MIPS_V16QI_FTYPE_V16QI_UQI
),
15970 MSA_BUILTIN (addvi_h
, MIPS_V8HI_FTYPE_V8HI_UQI
),
15971 MSA_BUILTIN (addvi_w
, MIPS_V4SI_FTYPE_V4SI_UQI
),
15972 MSA_BUILTIN (addvi_d
, MIPS_V2DI_FTYPE_V2DI_UQI
),
15973 MSA_BUILTIN (subv_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
15974 MSA_BUILTIN (subv_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
15975 MSA_BUILTIN (subv_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
15976 MSA_BUILTIN (subv_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
15977 MSA_BUILTIN (subvi_b
, MIPS_V16QI_FTYPE_V16QI_UQI
),
15978 MSA_BUILTIN (subvi_h
, MIPS_V8HI_FTYPE_V8HI_UQI
),
15979 MSA_BUILTIN (subvi_w
, MIPS_V4SI_FTYPE_V4SI_UQI
),
15980 MSA_BUILTIN (subvi_d
, MIPS_V2DI_FTYPE_V2DI_UQI
),
15981 MSA_BUILTIN (max_s_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
15982 MSA_BUILTIN (max_s_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
15983 MSA_BUILTIN (max_s_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
15984 MSA_BUILTIN (max_s_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
15985 MSA_BUILTIN (maxi_s_b
, MIPS_V16QI_FTYPE_V16QI_QI
),
15986 MSA_BUILTIN (maxi_s_h
, MIPS_V8HI_FTYPE_V8HI_QI
),
15987 MSA_BUILTIN (maxi_s_w
, MIPS_V4SI_FTYPE_V4SI_QI
),
15988 MSA_BUILTIN (maxi_s_d
, MIPS_V2DI_FTYPE_V2DI_QI
),
15989 MSA_BUILTIN (max_u_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
15990 MSA_BUILTIN (max_u_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI
),
15991 MSA_BUILTIN (max_u_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI
),
15992 MSA_BUILTIN (max_u_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI
),
15993 MSA_BUILTIN (maxi_u_b
, MIPS_UV16QI_FTYPE_UV16QI_UQI
),
15994 MSA_BUILTIN (maxi_u_h
, MIPS_UV8HI_FTYPE_UV8HI_UQI
),
15995 MSA_BUILTIN (maxi_u_w
, MIPS_UV4SI_FTYPE_UV4SI_UQI
),
15996 MSA_BUILTIN (maxi_u_d
, MIPS_UV2DI_FTYPE_UV2DI_UQI
),
15997 MSA_BUILTIN (min_s_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
15998 MSA_BUILTIN (min_s_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
15999 MSA_BUILTIN (min_s_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16000 MSA_BUILTIN (min_s_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16001 MSA_BUILTIN (mini_s_b
, MIPS_V16QI_FTYPE_V16QI_QI
),
16002 MSA_BUILTIN (mini_s_h
, MIPS_V8HI_FTYPE_V8HI_QI
),
16003 MSA_BUILTIN (mini_s_w
, MIPS_V4SI_FTYPE_V4SI_QI
),
16004 MSA_BUILTIN (mini_s_d
, MIPS_V2DI_FTYPE_V2DI_QI
),
16005 MSA_BUILTIN (min_u_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
16006 MSA_BUILTIN (min_u_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI
),
16007 MSA_BUILTIN (min_u_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI
),
16008 MSA_BUILTIN (min_u_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI
),
16009 MSA_BUILTIN (mini_u_b
, MIPS_UV16QI_FTYPE_UV16QI_UQI
),
16010 MSA_BUILTIN (mini_u_h
, MIPS_UV8HI_FTYPE_UV8HI_UQI
),
16011 MSA_BUILTIN (mini_u_w
, MIPS_UV4SI_FTYPE_UV4SI_UQI
),
16012 MSA_BUILTIN (mini_u_d
, MIPS_UV2DI_FTYPE_UV2DI_UQI
),
16013 MSA_BUILTIN (max_a_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16014 MSA_BUILTIN (max_a_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16015 MSA_BUILTIN (max_a_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16016 MSA_BUILTIN (max_a_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16017 MSA_BUILTIN (min_a_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16018 MSA_BUILTIN (min_a_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16019 MSA_BUILTIN (min_a_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16020 MSA_BUILTIN (min_a_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16021 MSA_BUILTIN (ceq_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16022 MSA_BUILTIN (ceq_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16023 MSA_BUILTIN (ceq_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16024 MSA_BUILTIN (ceq_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16025 MSA_BUILTIN (ceqi_b
, MIPS_V16QI_FTYPE_V16QI_QI
),
16026 MSA_BUILTIN (ceqi_h
, MIPS_V8HI_FTYPE_V8HI_QI
),
16027 MSA_BUILTIN (ceqi_w
, MIPS_V4SI_FTYPE_V4SI_QI
),
16028 MSA_BUILTIN (ceqi_d
, MIPS_V2DI_FTYPE_V2DI_QI
),
16029 MSA_BUILTIN (clt_s_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16030 MSA_BUILTIN (clt_s_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16031 MSA_BUILTIN (clt_s_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16032 MSA_BUILTIN (clt_s_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16033 MSA_BUILTIN (clti_s_b
, MIPS_V16QI_FTYPE_V16QI_QI
),
16034 MSA_BUILTIN (clti_s_h
, MIPS_V8HI_FTYPE_V8HI_QI
),
16035 MSA_BUILTIN (clti_s_w
, MIPS_V4SI_FTYPE_V4SI_QI
),
16036 MSA_BUILTIN (clti_s_d
, MIPS_V2DI_FTYPE_V2DI_QI
),
16037 MSA_BUILTIN (clt_u_b
, MIPS_V16QI_FTYPE_UV16QI_UV16QI
),
16038 MSA_BUILTIN (clt_u_h
, MIPS_V8HI_FTYPE_UV8HI_UV8HI
),
16039 MSA_BUILTIN (clt_u_w
, MIPS_V4SI_FTYPE_UV4SI_UV4SI
),
16040 MSA_BUILTIN (clt_u_d
, MIPS_V2DI_FTYPE_UV2DI_UV2DI
),
16041 MSA_BUILTIN (clti_u_b
, MIPS_V16QI_FTYPE_UV16QI_UQI
),
16042 MSA_BUILTIN (clti_u_h
, MIPS_V8HI_FTYPE_UV8HI_UQI
),
16043 MSA_BUILTIN (clti_u_w
, MIPS_V4SI_FTYPE_UV4SI_UQI
),
16044 MSA_BUILTIN (clti_u_d
, MIPS_V2DI_FTYPE_UV2DI_UQI
),
16045 MSA_BUILTIN (cle_s_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16046 MSA_BUILTIN (cle_s_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16047 MSA_BUILTIN (cle_s_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16048 MSA_BUILTIN (cle_s_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16049 MSA_BUILTIN (clei_s_b
, MIPS_V16QI_FTYPE_V16QI_QI
),
16050 MSA_BUILTIN (clei_s_h
, MIPS_V8HI_FTYPE_V8HI_QI
),
16051 MSA_BUILTIN (clei_s_w
, MIPS_V4SI_FTYPE_V4SI_QI
),
16052 MSA_BUILTIN (clei_s_d
, MIPS_V2DI_FTYPE_V2DI_QI
),
16053 MSA_BUILTIN (cle_u_b
, MIPS_V16QI_FTYPE_UV16QI_UV16QI
),
16054 MSA_BUILTIN (cle_u_h
, MIPS_V8HI_FTYPE_UV8HI_UV8HI
),
16055 MSA_BUILTIN (cle_u_w
, MIPS_V4SI_FTYPE_UV4SI_UV4SI
),
16056 MSA_BUILTIN (cle_u_d
, MIPS_V2DI_FTYPE_UV2DI_UV2DI
),
16057 MSA_BUILTIN (clei_u_b
, MIPS_V16QI_FTYPE_UV16QI_UQI
),
16058 MSA_BUILTIN (clei_u_h
, MIPS_V8HI_FTYPE_UV8HI_UQI
),
16059 MSA_BUILTIN (clei_u_w
, MIPS_V4SI_FTYPE_UV4SI_UQI
),
16060 MSA_BUILTIN (clei_u_d
, MIPS_V2DI_FTYPE_UV2DI_UQI
),
16061 MSA_BUILTIN (ld_b
, MIPS_V16QI_FTYPE_CVPOINTER_SI
),
16062 MSA_BUILTIN (ld_h
, MIPS_V8HI_FTYPE_CVPOINTER_SI
),
16063 MSA_BUILTIN (ld_w
, MIPS_V4SI_FTYPE_CVPOINTER_SI
),
16064 MSA_BUILTIN (ld_d
, MIPS_V2DI_FTYPE_CVPOINTER_SI
),
16065 MSA_NO_TARGET_BUILTIN (st_b
, MIPS_VOID_FTYPE_V16QI_CVPOINTER_SI
),
16066 MSA_NO_TARGET_BUILTIN (st_h
, MIPS_VOID_FTYPE_V8HI_CVPOINTER_SI
),
16067 MSA_NO_TARGET_BUILTIN (st_w
, MIPS_VOID_FTYPE_V4SI_CVPOINTER_SI
),
16068 MSA_NO_TARGET_BUILTIN (st_d
, MIPS_VOID_FTYPE_V2DI_CVPOINTER_SI
),
16069 MSA_BUILTIN (sat_s_b
, MIPS_V16QI_FTYPE_V16QI_UQI
),
16070 MSA_BUILTIN (sat_s_h
, MIPS_V8HI_FTYPE_V8HI_UQI
),
16071 MSA_BUILTIN (sat_s_w
, MIPS_V4SI_FTYPE_V4SI_UQI
),
16072 MSA_BUILTIN (sat_s_d
, MIPS_V2DI_FTYPE_V2DI_UQI
),
16073 MSA_BUILTIN (sat_u_b
, MIPS_UV16QI_FTYPE_UV16QI_UQI
),
16074 MSA_BUILTIN (sat_u_h
, MIPS_UV8HI_FTYPE_UV8HI_UQI
),
16075 MSA_BUILTIN (sat_u_w
, MIPS_UV4SI_FTYPE_UV4SI_UQI
),
16076 MSA_BUILTIN (sat_u_d
, MIPS_UV2DI_FTYPE_UV2DI_UQI
),
16077 MSA_BUILTIN (add_a_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16078 MSA_BUILTIN (add_a_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16079 MSA_BUILTIN (add_a_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16080 MSA_BUILTIN (add_a_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16081 MSA_BUILTIN (adds_a_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16082 MSA_BUILTIN (adds_a_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16083 MSA_BUILTIN (adds_a_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16084 MSA_BUILTIN (adds_a_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16085 MSA_BUILTIN (adds_s_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16086 MSA_BUILTIN (adds_s_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16087 MSA_BUILTIN (adds_s_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16088 MSA_BUILTIN (adds_s_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16089 MSA_BUILTIN (adds_u_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
16090 MSA_BUILTIN (adds_u_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI
),
16091 MSA_BUILTIN (adds_u_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI
),
16092 MSA_BUILTIN (adds_u_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI
),
16093 MSA_BUILTIN (ave_s_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16094 MSA_BUILTIN (ave_s_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16095 MSA_BUILTIN (ave_s_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16096 MSA_BUILTIN (ave_s_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16097 MSA_BUILTIN (ave_u_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
16098 MSA_BUILTIN (ave_u_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI
),
16099 MSA_BUILTIN (ave_u_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI
),
16100 MSA_BUILTIN (ave_u_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI
),
16101 MSA_BUILTIN (aver_s_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16102 MSA_BUILTIN (aver_s_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16103 MSA_BUILTIN (aver_s_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16104 MSA_BUILTIN (aver_s_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16105 MSA_BUILTIN (aver_u_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
16106 MSA_BUILTIN (aver_u_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI
),
16107 MSA_BUILTIN (aver_u_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI
),
16108 MSA_BUILTIN (aver_u_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI
),
16109 MSA_BUILTIN (subs_s_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16110 MSA_BUILTIN (subs_s_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16111 MSA_BUILTIN (subs_s_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16112 MSA_BUILTIN (subs_s_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16113 MSA_BUILTIN (subs_u_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
16114 MSA_BUILTIN (subs_u_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI
),
16115 MSA_BUILTIN (subs_u_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI
),
16116 MSA_BUILTIN (subs_u_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI
),
16117 MSA_BUILTIN (subsuu_s_b
, MIPS_V16QI_FTYPE_UV16QI_UV16QI
),
16118 MSA_BUILTIN (subsuu_s_h
, MIPS_V8HI_FTYPE_UV8HI_UV8HI
),
16119 MSA_BUILTIN (subsuu_s_w
, MIPS_V4SI_FTYPE_UV4SI_UV4SI
),
16120 MSA_BUILTIN (subsuu_s_d
, MIPS_V2DI_FTYPE_UV2DI_UV2DI
),
16121 MSA_BUILTIN (subsus_u_b
, MIPS_UV16QI_FTYPE_UV16QI_V16QI
),
16122 MSA_BUILTIN (subsus_u_h
, MIPS_UV8HI_FTYPE_UV8HI_V8HI
),
16123 MSA_BUILTIN (subsus_u_w
, MIPS_UV4SI_FTYPE_UV4SI_V4SI
),
16124 MSA_BUILTIN (subsus_u_d
, MIPS_UV2DI_FTYPE_UV2DI_V2DI
),
16125 MSA_BUILTIN (asub_s_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16126 MSA_BUILTIN (asub_s_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16127 MSA_BUILTIN (asub_s_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16128 MSA_BUILTIN (asub_s_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16129 MSA_BUILTIN (asub_u_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
16130 MSA_BUILTIN (asub_u_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI
),
16131 MSA_BUILTIN (asub_u_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI
),
16132 MSA_BUILTIN (asub_u_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI
),
16133 MSA_BUILTIN (mulv_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16134 MSA_BUILTIN (mulv_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16135 MSA_BUILTIN (mulv_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16136 MSA_BUILTIN (mulv_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16137 MSA_BUILTIN (maddv_b
, MIPS_V16QI_FTYPE_V16QI_V16QI_V16QI
),
16138 MSA_BUILTIN (maddv_h
, MIPS_V8HI_FTYPE_V8HI_V8HI_V8HI
),
16139 MSA_BUILTIN (maddv_w
, MIPS_V4SI_FTYPE_V4SI_V4SI_V4SI
),
16140 MSA_BUILTIN (maddv_d
, MIPS_V2DI_FTYPE_V2DI_V2DI_V2DI
),
16141 MSA_BUILTIN (msubv_b
, MIPS_V16QI_FTYPE_V16QI_V16QI_V16QI
),
16142 MSA_BUILTIN (msubv_h
, MIPS_V8HI_FTYPE_V8HI_V8HI_V8HI
),
16143 MSA_BUILTIN (msubv_w
, MIPS_V4SI_FTYPE_V4SI_V4SI_V4SI
),
16144 MSA_BUILTIN (msubv_d
, MIPS_V2DI_FTYPE_V2DI_V2DI_V2DI
),
16145 MSA_BUILTIN (div_s_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16146 MSA_BUILTIN (div_s_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16147 MSA_BUILTIN (div_s_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16148 MSA_BUILTIN (div_s_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16149 MSA_BUILTIN (div_u_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
16150 MSA_BUILTIN (div_u_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI
),
16151 MSA_BUILTIN (div_u_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI
),
16152 MSA_BUILTIN (div_u_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI
),
16153 MSA_BUILTIN (hadd_s_h
, MIPS_V8HI_FTYPE_V16QI_V16QI
),
16154 MSA_BUILTIN (hadd_s_w
, MIPS_V4SI_FTYPE_V8HI_V8HI
),
16155 MSA_BUILTIN (hadd_s_d
, MIPS_V2DI_FTYPE_V4SI_V4SI
),
16156 MSA_BUILTIN (hadd_u_h
, MIPS_UV8HI_FTYPE_UV16QI_UV16QI
),
16157 MSA_BUILTIN (hadd_u_w
, MIPS_UV4SI_FTYPE_UV8HI_UV8HI
),
16158 MSA_BUILTIN (hadd_u_d
, MIPS_UV2DI_FTYPE_UV4SI_UV4SI
),
16159 MSA_BUILTIN (hsub_s_h
, MIPS_V8HI_FTYPE_V16QI_V16QI
),
16160 MSA_BUILTIN (hsub_s_w
, MIPS_V4SI_FTYPE_V8HI_V8HI
),
16161 MSA_BUILTIN (hsub_s_d
, MIPS_V2DI_FTYPE_V4SI_V4SI
),
16162 MSA_BUILTIN (hsub_u_h
, MIPS_V8HI_FTYPE_UV16QI_UV16QI
),
16163 MSA_BUILTIN (hsub_u_w
, MIPS_V4SI_FTYPE_UV8HI_UV8HI
),
16164 MSA_BUILTIN (hsub_u_d
, MIPS_V2DI_FTYPE_UV4SI_UV4SI
),
16165 MSA_BUILTIN (mod_s_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16166 MSA_BUILTIN (mod_s_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16167 MSA_BUILTIN (mod_s_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16168 MSA_BUILTIN (mod_s_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16169 MSA_BUILTIN (mod_u_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
16170 MSA_BUILTIN (mod_u_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI
),
16171 MSA_BUILTIN (mod_u_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI
),
16172 MSA_BUILTIN (mod_u_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI
),
16173 MSA_BUILTIN (dotp_s_h
, MIPS_V8HI_FTYPE_V16QI_V16QI
),
16174 MSA_BUILTIN (dotp_s_w
, MIPS_V4SI_FTYPE_V8HI_V8HI
),
16175 MSA_BUILTIN (dotp_s_d
, MIPS_V2DI_FTYPE_V4SI_V4SI
),
16176 MSA_BUILTIN (dotp_u_h
, MIPS_UV8HI_FTYPE_UV16QI_UV16QI
),
16177 MSA_BUILTIN (dotp_u_w
, MIPS_UV4SI_FTYPE_UV8HI_UV8HI
),
16178 MSA_BUILTIN (dotp_u_d
, MIPS_UV2DI_FTYPE_UV4SI_UV4SI
),
16179 MSA_BUILTIN (dpadd_s_h
, MIPS_V8HI_FTYPE_V8HI_V16QI_V16QI
),
16180 MSA_BUILTIN (dpadd_s_w
, MIPS_V4SI_FTYPE_V4SI_V8HI_V8HI
),
16181 MSA_BUILTIN (dpadd_s_d
, MIPS_V2DI_FTYPE_V2DI_V4SI_V4SI
),
16182 MSA_BUILTIN (dpadd_u_h
, MIPS_UV8HI_FTYPE_UV8HI_UV16QI_UV16QI
),
16183 MSA_BUILTIN (dpadd_u_w
, MIPS_UV4SI_FTYPE_UV4SI_UV8HI_UV8HI
),
16184 MSA_BUILTIN (dpadd_u_d
, MIPS_UV2DI_FTYPE_UV2DI_UV4SI_UV4SI
),
16185 MSA_BUILTIN (dpsub_s_h
, MIPS_V8HI_FTYPE_V8HI_V16QI_V16QI
),
16186 MSA_BUILTIN (dpsub_s_w
, MIPS_V4SI_FTYPE_V4SI_V8HI_V8HI
),
16187 MSA_BUILTIN (dpsub_s_d
, MIPS_V2DI_FTYPE_V2DI_V4SI_V4SI
),
16188 MSA_BUILTIN (dpsub_u_h
, MIPS_V8HI_FTYPE_V8HI_UV16QI_UV16QI
),
16189 MSA_BUILTIN (dpsub_u_w
, MIPS_V4SI_FTYPE_V4SI_UV8HI_UV8HI
),
16190 MSA_BUILTIN (dpsub_u_d
, MIPS_V2DI_FTYPE_V2DI_UV4SI_UV4SI
),
16191 MSA_BUILTIN (sld_b
, MIPS_V16QI_FTYPE_V16QI_V16QI_SI
),
16192 MSA_BUILTIN (sld_h
, MIPS_V8HI_FTYPE_V8HI_V8HI_SI
),
16193 MSA_BUILTIN (sld_w
, MIPS_V4SI_FTYPE_V4SI_V4SI_SI
),
16194 MSA_BUILTIN (sld_d
, MIPS_V2DI_FTYPE_V2DI_V2DI_SI
),
16195 MSA_BUILTIN (sldi_b
, MIPS_V16QI_FTYPE_V16QI_V16QI_UQI
),
16196 MSA_BUILTIN (sldi_h
, MIPS_V8HI_FTYPE_V8HI_V8HI_UQI
),
16197 MSA_BUILTIN (sldi_w
, MIPS_V4SI_FTYPE_V4SI_V4SI_UQI
),
16198 MSA_BUILTIN (sldi_d
, MIPS_V2DI_FTYPE_V2DI_V2DI_UQI
),
16199 MSA_BUILTIN (splat_b
, MIPS_V16QI_FTYPE_V16QI_SI
),
16200 MSA_BUILTIN (splat_h
, MIPS_V8HI_FTYPE_V8HI_SI
),
16201 MSA_BUILTIN (splat_w
, MIPS_V4SI_FTYPE_V4SI_SI
),
16202 MSA_BUILTIN (splat_d
, MIPS_V2DI_FTYPE_V2DI_SI
),
16203 MSA_BUILTIN (splati_b
, MIPS_V16QI_FTYPE_V16QI_UQI
),
16204 MSA_BUILTIN (splati_h
, MIPS_V8HI_FTYPE_V8HI_UQI
),
16205 MSA_BUILTIN (splati_w
, MIPS_V4SI_FTYPE_V4SI_UQI
),
16206 MSA_BUILTIN (splati_d
, MIPS_V2DI_FTYPE_V2DI_UQI
),
16207 MSA_BUILTIN (pckev_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16208 MSA_BUILTIN (pckev_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16209 MSA_BUILTIN (pckev_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16210 MSA_BUILTIN (pckev_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16211 MSA_BUILTIN (pckod_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16212 MSA_BUILTIN (pckod_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16213 MSA_BUILTIN (pckod_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16214 MSA_BUILTIN (pckod_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16215 MSA_BUILTIN (ilvl_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16216 MSA_BUILTIN (ilvl_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16217 MSA_BUILTIN (ilvl_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16218 MSA_BUILTIN (ilvl_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16219 MSA_BUILTIN (ilvr_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16220 MSA_BUILTIN (ilvr_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16221 MSA_BUILTIN (ilvr_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16222 MSA_BUILTIN (ilvr_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16223 MSA_BUILTIN (ilvev_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16224 MSA_BUILTIN (ilvev_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16225 MSA_BUILTIN (ilvev_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16226 MSA_BUILTIN (ilvev_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16227 MSA_BUILTIN (ilvod_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16228 MSA_BUILTIN (ilvod_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16229 MSA_BUILTIN (ilvod_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16230 MSA_BUILTIN (ilvod_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16231 MSA_BUILTIN (vshf_b
, MIPS_V16QI_FTYPE_V16QI_V16QI_V16QI
),
16232 MSA_BUILTIN (vshf_h
, MIPS_V8HI_FTYPE_V8HI_V8HI_V8HI
),
16233 MSA_BUILTIN (vshf_w
, MIPS_V4SI_FTYPE_V4SI_V4SI_V4SI
),
16234 MSA_BUILTIN (vshf_d
, MIPS_V2DI_FTYPE_V2DI_V2DI_V2DI
),
16235 MSA_BUILTIN (and_v
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
16236 MSA_BUILTIN (andi_b
, MIPS_UV16QI_FTYPE_UV16QI_UQI
),
16237 MSA_BUILTIN (or_v
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
16238 MSA_BUILTIN (ori_b
, MIPS_UV16QI_FTYPE_UV16QI_UQI
),
16239 MSA_BUILTIN (nor_v
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
16240 MSA_BUILTIN (nori_b
, MIPS_UV16QI_FTYPE_UV16QI_UQI
),
16241 MSA_BUILTIN (xor_v
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
16242 MSA_BUILTIN (xori_b
, MIPS_UV16QI_FTYPE_UV16QI_UQI
),
16243 MSA_BUILTIN (bmnz_v
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UV16QI
),
16244 MSA_BUILTIN (bmnzi_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UQI
),
16245 MSA_BUILTIN (bmz_v
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UV16QI
),
16246 MSA_BUILTIN (bmzi_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UQI
),
16247 MSA_BUILTIN (bsel_v
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UV16QI
),
16248 MSA_BUILTIN (bseli_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UQI
),
16249 MSA_BUILTIN (shf_b
, MIPS_V16QI_FTYPE_V16QI_UQI
),
16250 MSA_BUILTIN (shf_h
, MIPS_V8HI_FTYPE_V8HI_UQI
),
16251 MSA_BUILTIN (shf_w
, MIPS_V4SI_FTYPE_V4SI_UQI
),
16252 MSA_BUILTIN_TEST_BRANCH (bnz_v
, MIPS_SI_FTYPE_UV16QI
),
16253 MSA_BUILTIN_TEST_BRANCH (bz_v
, MIPS_SI_FTYPE_UV16QI
),
16254 MSA_BUILTIN (fill_b
, MIPS_V16QI_FTYPE_SI
),
16255 MSA_BUILTIN (fill_h
, MIPS_V8HI_FTYPE_SI
),
16256 MSA_BUILTIN (fill_w
, MIPS_V4SI_FTYPE_SI
),
16257 MSA_BUILTIN (fill_d
, MIPS_V2DI_FTYPE_DI
),
16258 MSA_BUILTIN (pcnt_b
, MIPS_V16QI_FTYPE_V16QI
),
16259 MSA_BUILTIN (pcnt_h
, MIPS_V8HI_FTYPE_V8HI
),
16260 MSA_BUILTIN (pcnt_w
, MIPS_V4SI_FTYPE_V4SI
),
16261 MSA_BUILTIN (pcnt_d
, MIPS_V2DI_FTYPE_V2DI
),
16262 MSA_BUILTIN (nloc_b
, MIPS_V16QI_FTYPE_V16QI
),
16263 MSA_BUILTIN (nloc_h
, MIPS_V8HI_FTYPE_V8HI
),
16264 MSA_BUILTIN (nloc_w
, MIPS_V4SI_FTYPE_V4SI
),
16265 MSA_BUILTIN (nloc_d
, MIPS_V2DI_FTYPE_V2DI
),
16266 MSA_BUILTIN (nlzc_b
, MIPS_V16QI_FTYPE_V16QI
),
16267 MSA_BUILTIN (nlzc_h
, MIPS_V8HI_FTYPE_V8HI
),
16268 MSA_BUILTIN (nlzc_w
, MIPS_V4SI_FTYPE_V4SI
),
16269 MSA_BUILTIN (nlzc_d
, MIPS_V2DI_FTYPE_V2DI
),
16270 MSA_BUILTIN (copy_s_b
, MIPS_SI_FTYPE_V16QI_UQI
),
16271 MSA_BUILTIN (copy_s_h
, MIPS_SI_FTYPE_V8HI_UQI
),
16272 MSA_BUILTIN (copy_s_w
, MIPS_SI_FTYPE_V4SI_UQI
),
16273 MSA_BUILTIN (copy_s_d
, MIPS_DI_FTYPE_V2DI_UQI
),
16274 MSA_BUILTIN (copy_u_b
, MIPS_USI_FTYPE_V16QI_UQI
),
16275 MSA_BUILTIN (copy_u_h
, MIPS_USI_FTYPE_V8HI_UQI
),
16276 MSA_BUILTIN_REMAP (copy_u_w
, copy_s_w
, MIPS_USI_FTYPE_V4SI_UQI
),
16277 MSA_BUILTIN_REMAP (copy_u_d
, copy_s_d
, MIPS_UDI_FTYPE_V2DI_UQI
),
16278 MSA_BUILTIN (insert_b
, MIPS_V16QI_FTYPE_V16QI_UQI_SI
),
16279 MSA_BUILTIN (insert_h
, MIPS_V8HI_FTYPE_V8HI_UQI_SI
),
16280 MSA_BUILTIN (insert_w
, MIPS_V4SI_FTYPE_V4SI_UQI_SI
),
16281 MSA_BUILTIN (insert_d
, MIPS_V2DI_FTYPE_V2DI_UQI_DI
),
16282 MSA_BUILTIN (insve_b
, MIPS_V16QI_FTYPE_V16QI_UQI_V16QI
),
16283 MSA_BUILTIN (insve_h
, MIPS_V8HI_FTYPE_V8HI_UQI_V8HI
),
16284 MSA_BUILTIN (insve_w
, MIPS_V4SI_FTYPE_V4SI_UQI_V4SI
),
16285 MSA_BUILTIN (insve_d
, MIPS_V2DI_FTYPE_V2DI_UQI_V2DI
),
16286 MSA_BUILTIN_TEST_BRANCH (bnz_b
, MIPS_SI_FTYPE_UV16QI
),
16287 MSA_BUILTIN_TEST_BRANCH (bnz_h
, MIPS_SI_FTYPE_UV8HI
),
16288 MSA_BUILTIN_TEST_BRANCH (bnz_w
, MIPS_SI_FTYPE_UV4SI
),
16289 MSA_BUILTIN_TEST_BRANCH (bnz_d
, MIPS_SI_FTYPE_UV2DI
),
16290 MSA_BUILTIN_TEST_BRANCH (bz_b
, MIPS_SI_FTYPE_UV16QI
),
16291 MSA_BUILTIN_TEST_BRANCH (bz_h
, MIPS_SI_FTYPE_UV8HI
),
16292 MSA_BUILTIN_TEST_BRANCH (bz_w
, MIPS_SI_FTYPE_UV4SI
),
16293 MSA_BUILTIN_TEST_BRANCH (bz_d
, MIPS_SI_FTYPE_UV2DI
),
16294 MSA_BUILTIN (ldi_b
, MIPS_V16QI_FTYPE_HI
),
16295 MSA_BUILTIN (ldi_h
, MIPS_V8HI_FTYPE_HI
),
16296 MSA_BUILTIN (ldi_w
, MIPS_V4SI_FTYPE_HI
),
16297 MSA_BUILTIN (ldi_d
, MIPS_V2DI_FTYPE_HI
),
16298 MSA_BUILTIN (fcaf_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16299 MSA_BUILTIN (fcaf_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16300 MSA_BUILTIN (fcor_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16301 MSA_BUILTIN (fcor_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16302 MSA_BUILTIN (fcun_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16303 MSA_BUILTIN (fcun_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16304 MSA_BUILTIN (fcune_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16305 MSA_BUILTIN (fcune_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16306 MSA_BUILTIN (fcueq_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16307 MSA_BUILTIN (fcueq_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16308 MSA_BUILTIN (fceq_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16309 MSA_BUILTIN (fceq_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16310 MSA_BUILTIN (fcne_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16311 MSA_BUILTIN (fcne_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16312 MSA_BUILTIN (fclt_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16313 MSA_BUILTIN (fclt_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16314 MSA_BUILTIN (fcult_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16315 MSA_BUILTIN (fcult_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16316 MSA_BUILTIN (fcle_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16317 MSA_BUILTIN (fcle_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16318 MSA_BUILTIN (fcule_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16319 MSA_BUILTIN (fcule_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16320 MSA_BUILTIN (fsaf_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16321 MSA_BUILTIN (fsaf_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16322 MSA_BUILTIN (fsor_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16323 MSA_BUILTIN (fsor_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16324 MSA_BUILTIN (fsun_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16325 MSA_BUILTIN (fsun_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16326 MSA_BUILTIN (fsune_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16327 MSA_BUILTIN (fsune_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16328 MSA_BUILTIN (fsueq_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16329 MSA_BUILTIN (fsueq_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16330 MSA_BUILTIN (fseq_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16331 MSA_BUILTIN (fseq_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16332 MSA_BUILTIN (fsne_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16333 MSA_BUILTIN (fsne_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16334 MSA_BUILTIN (fslt_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16335 MSA_BUILTIN (fslt_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16336 MSA_BUILTIN (fsult_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16337 MSA_BUILTIN (fsult_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16338 MSA_BUILTIN (fsle_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16339 MSA_BUILTIN (fsle_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16340 MSA_BUILTIN (fsule_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16341 MSA_BUILTIN (fsule_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16342 MSA_BUILTIN (fadd_w
, MIPS_V4SF_FTYPE_V4SF_V4SF
),
16343 MSA_BUILTIN (fadd_d
, MIPS_V2DF_FTYPE_V2DF_V2DF
),
16344 MSA_BUILTIN (fsub_w
, MIPS_V4SF_FTYPE_V4SF_V4SF
),
16345 MSA_BUILTIN (fsub_d
, MIPS_V2DF_FTYPE_V2DF_V2DF
),
16346 MSA_BUILTIN (fmul_w
, MIPS_V4SF_FTYPE_V4SF_V4SF
),
16347 MSA_BUILTIN (fmul_d
, MIPS_V2DF_FTYPE_V2DF_V2DF
),
16348 MSA_BUILTIN (fdiv_w
, MIPS_V4SF_FTYPE_V4SF_V4SF
),
16349 MSA_BUILTIN (fdiv_d
, MIPS_V2DF_FTYPE_V2DF_V2DF
),
16350 MSA_BUILTIN (fmadd_w
, MIPS_V4SF_FTYPE_V4SF_V4SF_V4SF
),
16351 MSA_BUILTIN (fmadd_d
, MIPS_V2DF_FTYPE_V2DF_V2DF_V2DF
),
16352 MSA_BUILTIN (fmsub_w
, MIPS_V4SF_FTYPE_V4SF_V4SF_V4SF
),
16353 MSA_BUILTIN (fmsub_d
, MIPS_V2DF_FTYPE_V2DF_V2DF_V2DF
),
16354 MSA_BUILTIN (fexp2_w
, MIPS_V4SF_FTYPE_V4SF_V4SI
),
16355 MSA_BUILTIN (fexp2_d
, MIPS_V2DF_FTYPE_V2DF_V2DI
),
16356 MSA_BUILTIN (fexdo_h
, MIPS_V8HI_FTYPE_V4SF_V4SF
),
16357 MSA_BUILTIN (fexdo_w
, MIPS_V4SF_FTYPE_V2DF_V2DF
),
16358 MSA_BUILTIN (ftq_h
, MIPS_V8HI_FTYPE_V4SF_V4SF
),
16359 MSA_BUILTIN (ftq_w
, MIPS_V4SI_FTYPE_V2DF_V2DF
),
16360 MSA_BUILTIN (fmin_w
, MIPS_V4SF_FTYPE_V4SF_V4SF
),
16361 MSA_BUILTIN (fmin_d
, MIPS_V2DF_FTYPE_V2DF_V2DF
),
16362 MSA_BUILTIN (fmin_a_w
, MIPS_V4SF_FTYPE_V4SF_V4SF
),
16363 MSA_BUILTIN (fmin_a_d
, MIPS_V2DF_FTYPE_V2DF_V2DF
),
16364 MSA_BUILTIN (fmax_w
, MIPS_V4SF_FTYPE_V4SF_V4SF
),
16365 MSA_BUILTIN (fmax_d
, MIPS_V2DF_FTYPE_V2DF_V2DF
),
16366 MSA_BUILTIN (fmax_a_w
, MIPS_V4SF_FTYPE_V4SF_V4SF
),
16367 MSA_BUILTIN (fmax_a_d
, MIPS_V2DF_FTYPE_V2DF_V2DF
),
16368 MSA_BUILTIN (mul_q_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16369 MSA_BUILTIN (mul_q_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16370 MSA_BUILTIN (mulr_q_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16371 MSA_BUILTIN (mulr_q_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16372 MSA_BUILTIN (madd_q_h
, MIPS_V8HI_FTYPE_V8HI_V8HI_V8HI
),
16373 MSA_BUILTIN (madd_q_w
, MIPS_V4SI_FTYPE_V4SI_V4SI_V4SI
),
16374 MSA_BUILTIN (maddr_q_h
, MIPS_V8HI_FTYPE_V8HI_V8HI_V8HI
),
16375 MSA_BUILTIN (maddr_q_w
, MIPS_V4SI_FTYPE_V4SI_V4SI_V4SI
),
16376 MSA_BUILTIN (msub_q_h
, MIPS_V8HI_FTYPE_V8HI_V8HI_V8HI
),
16377 MSA_BUILTIN (msub_q_w
, MIPS_V4SI_FTYPE_V4SI_V4SI_V4SI
),
16378 MSA_BUILTIN (msubr_q_h
, MIPS_V8HI_FTYPE_V8HI_V8HI_V8HI
),
16379 MSA_BUILTIN (msubr_q_w
, MIPS_V4SI_FTYPE_V4SI_V4SI_V4SI
),
16380 MSA_BUILTIN (fclass_w
, MIPS_V4SI_FTYPE_V4SF
),
16381 MSA_BUILTIN (fclass_d
, MIPS_V2DI_FTYPE_V2DF
),
16382 MSA_BUILTIN (fsqrt_w
, MIPS_V4SF_FTYPE_V4SF
),
16383 MSA_BUILTIN (fsqrt_d
, MIPS_V2DF_FTYPE_V2DF
),
16384 MSA_BUILTIN (frcp_w
, MIPS_V4SF_FTYPE_V4SF
),
16385 MSA_BUILTIN (frcp_d
, MIPS_V2DF_FTYPE_V2DF
),
16386 MSA_BUILTIN (frint_w
, MIPS_V4SF_FTYPE_V4SF
),
16387 MSA_BUILTIN (frint_d
, MIPS_V2DF_FTYPE_V2DF
),
16388 MSA_BUILTIN (frsqrt_w
, MIPS_V4SF_FTYPE_V4SF
),
16389 MSA_BUILTIN (frsqrt_d
, MIPS_V2DF_FTYPE_V2DF
),
16390 MSA_BUILTIN (flog2_w
, MIPS_V4SF_FTYPE_V4SF
),
16391 MSA_BUILTIN (flog2_d
, MIPS_V2DF_FTYPE_V2DF
),
16392 MSA_BUILTIN (fexupl_w
, MIPS_V4SF_FTYPE_V8HI
),
16393 MSA_BUILTIN (fexupl_d
, MIPS_V2DF_FTYPE_V4SF
),
16394 MSA_BUILTIN (fexupr_w
, MIPS_V4SF_FTYPE_V8HI
),
16395 MSA_BUILTIN (fexupr_d
, MIPS_V2DF_FTYPE_V4SF
),
16396 MSA_BUILTIN (ffql_w
, MIPS_V4SF_FTYPE_V8HI
),
16397 MSA_BUILTIN (ffql_d
, MIPS_V2DF_FTYPE_V4SI
),
16398 MSA_BUILTIN (ffqr_w
, MIPS_V4SF_FTYPE_V8HI
),
16399 MSA_BUILTIN (ffqr_d
, MIPS_V2DF_FTYPE_V4SI
),
16400 MSA_BUILTIN (ftint_s_w
, MIPS_V4SI_FTYPE_V4SF
),
16401 MSA_BUILTIN (ftint_s_d
, MIPS_V2DI_FTYPE_V2DF
),
16402 MSA_BUILTIN (ftint_u_w
, MIPS_UV4SI_FTYPE_V4SF
),
16403 MSA_BUILTIN (ftint_u_d
, MIPS_UV2DI_FTYPE_V2DF
),
16404 MSA_BUILTIN (ftrunc_s_w
, MIPS_V4SI_FTYPE_V4SF
),
16405 MSA_BUILTIN (ftrunc_s_d
, MIPS_V2DI_FTYPE_V2DF
),
16406 MSA_BUILTIN (ftrunc_u_w
, MIPS_UV4SI_FTYPE_V4SF
),
16407 MSA_BUILTIN (ftrunc_u_d
, MIPS_UV2DI_FTYPE_V2DF
),
16408 MSA_BUILTIN (ffint_s_w
, MIPS_V4SF_FTYPE_V4SI
),
16409 MSA_BUILTIN (ffint_s_d
, MIPS_V2DF_FTYPE_V2DI
),
16410 MSA_BUILTIN (ffint_u_w
, MIPS_V4SF_FTYPE_UV4SI
),
16411 MSA_BUILTIN (ffint_u_d
, MIPS_V2DF_FTYPE_UV2DI
),
16412 MSA_NO_TARGET_BUILTIN (ctcmsa
, MIPS_VOID_FTYPE_UQI_SI
),
16413 MSA_BUILTIN (cfcmsa
, MIPS_SI_FTYPE_UQI
),
16414 MSA_BUILTIN (move_v
, MIPS_V16QI_FTYPE_V16QI
),
16417 /* Index I is the function declaration for mips_builtins[I], or null if the
16418 function isn't defined on this target. */
16419 static GTY(()) tree mips_builtin_decls
[ARRAY_SIZE (mips_builtins
)];
16420 /* Get the index I of the function declaration for mips_builtin_decls[I]
16421 using the instruction code or return null if not defined for the target. */
16422 static GTY(()) int mips_get_builtin_decl_index
[NUM_INSN_CODES
];
16424 /* MODE is a vector mode whose elements have type TYPE. Return the type
16425 of the vector itself. */
16428 mips_builtin_vector_type (tree type
, machine_mode mode
)
16430 static tree types
[2 * (int) MAX_MACHINE_MODE
];
16433 mode_index
= (int) mode
;
16435 if (TREE_CODE (type
) == INTEGER_TYPE
&& TYPE_UNSIGNED (type
))
16436 mode_index
+= MAX_MACHINE_MODE
;
16438 if (types
[mode_index
] == NULL_TREE
)
16439 types
[mode_index
] = build_vector_type_for_mode (type
, mode
);
16440 return types
[mode_index
];
16443 /* Return a type for 'const volatile void *'. */
16446 mips_build_cvpointer_type (void)
16450 if (cache
== NULL_TREE
)
16451 cache
= build_pointer_type (build_qualified_type
16453 TYPE_QUAL_CONST
| TYPE_QUAL_VOLATILE
));
16457 /* Source-level argument types. */
16458 #define MIPS_ATYPE_VOID void_type_node
16459 #define MIPS_ATYPE_INT integer_type_node
16460 #define MIPS_ATYPE_POINTER ptr_type_node
16461 #define MIPS_ATYPE_CVPOINTER mips_build_cvpointer_type ()
16463 /* Standard mode-based argument types. */
16464 #define MIPS_ATYPE_QI intQI_type_node
16465 #define MIPS_ATYPE_UQI unsigned_intQI_type_node
16466 #define MIPS_ATYPE_HI intHI_type_node
16467 #define MIPS_ATYPE_SI intSI_type_node
16468 #define MIPS_ATYPE_USI unsigned_intSI_type_node
16469 #define MIPS_ATYPE_DI intDI_type_node
16470 #define MIPS_ATYPE_UDI unsigned_intDI_type_node
16471 #define MIPS_ATYPE_SF float_type_node
16472 #define MIPS_ATYPE_DF double_type_node
16474 /* Vector argument types. */
16475 #define MIPS_ATYPE_V2SF mips_builtin_vector_type (float_type_node, V2SFmode)
16476 #define MIPS_ATYPE_V2HI mips_builtin_vector_type (intHI_type_node, V2HImode)
16477 #define MIPS_ATYPE_V2SI mips_builtin_vector_type (intSI_type_node, V2SImode)
16478 #define MIPS_ATYPE_V4QI mips_builtin_vector_type (intQI_type_node, V4QImode)
16479 #define MIPS_ATYPE_V4HI mips_builtin_vector_type (intHI_type_node, V4HImode)
16480 #define MIPS_ATYPE_V8QI mips_builtin_vector_type (intQI_type_node, V8QImode)
16482 #define MIPS_ATYPE_V2DI \
16483 mips_builtin_vector_type (long_long_integer_type_node, V2DImode)
16484 #define MIPS_ATYPE_V4SI mips_builtin_vector_type (intSI_type_node, V4SImode)
16485 #define MIPS_ATYPE_V8HI mips_builtin_vector_type (intHI_type_node, V8HImode)
16486 #define MIPS_ATYPE_V16QI mips_builtin_vector_type (intQI_type_node, V16QImode)
16487 #define MIPS_ATYPE_V2DF mips_builtin_vector_type (double_type_node, V2DFmode)
16488 #define MIPS_ATYPE_V4SF mips_builtin_vector_type (float_type_node, V4SFmode)
16490 #define MIPS_ATYPE_UV2DI \
16491 mips_builtin_vector_type (long_long_unsigned_type_node, V2DImode)
16492 #define MIPS_ATYPE_UV4SI \
16493 mips_builtin_vector_type (unsigned_intSI_type_node, V4SImode)
16494 #define MIPS_ATYPE_UV8HI \
16495 mips_builtin_vector_type (unsigned_intHI_type_node, V8HImode)
16496 #define MIPS_ATYPE_UV16QI \
16497 mips_builtin_vector_type (unsigned_intQI_type_node, V16QImode)
16499 #define MIPS_ATYPE_UV2SI \
16500 mips_builtin_vector_type (unsigned_intSI_type_node, V2SImode)
16501 #define MIPS_ATYPE_UV4HI \
16502 mips_builtin_vector_type (unsigned_intHI_type_node, V4HImode)
16503 #define MIPS_ATYPE_UV8QI \
16504 mips_builtin_vector_type (unsigned_intQI_type_node, V8QImode)
16506 /* MIPS_FTYPE_ATYPESN takes N MIPS_FTYPES-like type codes and lists
16507 their associated MIPS_ATYPEs. */
16508 #define MIPS_FTYPE_ATYPES1(A, B) \
16509 MIPS_ATYPE_##A, MIPS_ATYPE_##B
16511 #define MIPS_FTYPE_ATYPES2(A, B, C) \
16512 MIPS_ATYPE_##A, MIPS_ATYPE_##B, MIPS_ATYPE_##C
16514 #define MIPS_FTYPE_ATYPES3(A, B, C, D) \
16515 MIPS_ATYPE_##A, MIPS_ATYPE_##B, MIPS_ATYPE_##C, MIPS_ATYPE_##D
16517 #define MIPS_FTYPE_ATYPES4(A, B, C, D, E) \
16518 MIPS_ATYPE_##A, MIPS_ATYPE_##B, MIPS_ATYPE_##C, MIPS_ATYPE_##D, \
16521 /* Return the function type associated with function prototype TYPE. */
16524 mips_build_function_type (enum mips_function_type type
)
16526 static tree types
[(int) MIPS_MAX_FTYPE_MAX
];
16528 if (types
[(int) type
] == NULL_TREE
)
16531 #define DEF_MIPS_FTYPE(NUM, ARGS) \
16532 case MIPS_FTYPE_NAME##NUM ARGS: \
16533 types[(int) type] \
16534 = build_function_type_list (MIPS_FTYPE_ATYPES##NUM ARGS, \
16537 #include "config/mips/mips-ftypes.def"
16538 #undef DEF_MIPS_FTYPE
16540 gcc_unreachable ();
16543 return types
[(int) type
];
16546 /* Implement TARGET_INIT_BUILTINS. */
16549 mips_init_builtins (void)
16551 const struct mips_builtin_description
*d
;
16554 /* Iterate through all of the bdesc arrays, initializing all of the
16555 builtin functions. */
16556 for (i
= 0; i
< ARRAY_SIZE (mips_builtins
); i
++)
16558 d
= &mips_builtins
[i
];
16561 mips_builtin_decls
[i
]
16562 = add_builtin_function (d
->name
,
16563 mips_build_function_type (d
->function_type
),
16564 i
, BUILT_IN_MD
, NULL
, NULL
);
16565 mips_get_builtin_decl_index
[d
->icode
] = i
;
16570 /* Implement TARGET_BUILTIN_DECL. */
16573 mips_builtin_decl (unsigned int code
, bool initialize_p ATTRIBUTE_UNUSED
)
16575 if (code
>= ARRAY_SIZE (mips_builtins
))
16576 return error_mark_node
;
16577 return mips_builtin_decls
[code
];
16580 /* Implement TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION. */
16583 mips_builtin_vectorized_function (unsigned int fn
, tree type_out
, tree type_in
)
16585 machine_mode in_mode
, out_mode
;
16588 if (TREE_CODE (type_out
) != VECTOR_TYPE
16589 || TREE_CODE (type_in
) != VECTOR_TYPE
16593 out_mode
= TYPE_MODE (TREE_TYPE (type_out
));
16594 out_n
= TYPE_VECTOR_SUBPARTS (type_out
);
16595 in_mode
= TYPE_MODE (TREE_TYPE (type_in
));
16596 in_n
= TYPE_VECTOR_SUBPARTS (type_in
);
16598 /* INSN is the name of the associated instruction pattern, without
16599 the leading CODE_FOR_. */
16600 #define MIPS_GET_BUILTIN(INSN) \
16601 mips_builtin_decls[mips_get_builtin_decl_index[CODE_FOR_##INSN]]
16605 case BUILT_IN_SQRT
:
16606 if (out_mode
== DFmode
&& out_n
== 2
16607 && in_mode
== DFmode
&& in_n
== 2)
16608 return MIPS_GET_BUILTIN (msa_fsqrt_d
);
16610 case BUILT_IN_SQRTF
:
16611 if (out_mode
== SFmode
&& out_n
== 4
16612 && in_mode
== SFmode
&& in_n
== 4)
16613 return MIPS_GET_BUILTIN (msa_fsqrt_w
);
16622 /* Take argument ARGNO from EXP's argument list and convert it into
16623 an expand operand. Store the operand in *OP. */
16626 mips_prepare_builtin_arg (struct expand_operand
*op
, tree exp
,
16627 unsigned int argno
)
16632 arg
= CALL_EXPR_ARG (exp
, argno
);
16633 value
= expand_normal (arg
);
16634 create_input_operand (op
, value
, TYPE_MODE (TREE_TYPE (arg
)));
16637 /* Expand instruction ICODE as part of a built-in function sequence.
16638 Use the first NOPS elements of OPS as the instruction's operands.
16639 HAS_TARGET_P is true if operand 0 is a target; it is false if the
16640 instruction has no target.
16642 Return the target rtx if HAS_TARGET_P, otherwise return const0_rtx. */
16645 mips_expand_builtin_insn (enum insn_code icode
, unsigned int nops
,
16646 struct expand_operand
*ops
, bool has_target_p
)
16648 machine_mode imode
;
16649 int rangelo
= 0, rangehi
= 0, error_opno
= 0;
16654 /* The third operand of these instructions is in SImode, so we need to
16655 bring the corresponding builtin argument from QImode into SImode. */
16656 case CODE_FOR_loongson_pshufh
:
16657 case CODE_FOR_loongson_psllh
:
16658 case CODE_FOR_loongson_psllw
:
16659 case CODE_FOR_loongson_psrah
:
16660 case CODE_FOR_loongson_psraw
:
16661 case CODE_FOR_loongson_psrlh
:
16662 case CODE_FOR_loongson_psrlw
:
16663 gcc_assert (has_target_p
&& nops
== 3 && ops
[2].mode
== QImode
);
16664 sireg
= gen_reg_rtx (SImode
);
16665 emit_insn (gen_zero_extendqisi2 (sireg
,
16666 force_reg (QImode
, ops
[2].value
)));
16667 ops
[2].value
= sireg
;
16668 ops
[2].mode
= SImode
;
16671 case CODE_FOR_msa_addvi_b
:
16672 case CODE_FOR_msa_addvi_h
:
16673 case CODE_FOR_msa_addvi_w
:
16674 case CODE_FOR_msa_addvi_d
:
16675 case CODE_FOR_msa_clti_u_b
:
16676 case CODE_FOR_msa_clti_u_h
:
16677 case CODE_FOR_msa_clti_u_w
:
16678 case CODE_FOR_msa_clti_u_d
:
16679 case CODE_FOR_msa_clei_u_b
:
16680 case CODE_FOR_msa_clei_u_h
:
16681 case CODE_FOR_msa_clei_u_w
:
16682 case CODE_FOR_msa_clei_u_d
:
16683 case CODE_FOR_msa_maxi_u_b
:
16684 case CODE_FOR_msa_maxi_u_h
:
16685 case CODE_FOR_msa_maxi_u_w
:
16686 case CODE_FOR_msa_maxi_u_d
:
16687 case CODE_FOR_msa_mini_u_b
:
16688 case CODE_FOR_msa_mini_u_h
:
16689 case CODE_FOR_msa_mini_u_w
:
16690 case CODE_FOR_msa_mini_u_d
:
16691 case CODE_FOR_msa_subvi_b
:
16692 case CODE_FOR_msa_subvi_h
:
16693 case CODE_FOR_msa_subvi_w
:
16694 case CODE_FOR_msa_subvi_d
:
16695 gcc_assert (has_target_p
&& nops
== 3);
16696 /* We only generate a vector of constants iff the second argument
16697 is an immediate. We also validate the range of the immediate. */
16698 if (CONST_INT_P (ops
[2].value
))
16702 if (IN_RANGE (INTVAL (ops
[2].value
), rangelo
, rangehi
))
16704 ops
[2].mode
= ops
[0].mode
;
16705 ops
[2].value
= mips_gen_const_int_vector (ops
[2].mode
,
16706 INTVAL (ops
[2].value
));
16713 case CODE_FOR_msa_ceqi_b
:
16714 case CODE_FOR_msa_ceqi_h
:
16715 case CODE_FOR_msa_ceqi_w
:
16716 case CODE_FOR_msa_ceqi_d
:
16717 case CODE_FOR_msa_clti_s_b
:
16718 case CODE_FOR_msa_clti_s_h
:
16719 case CODE_FOR_msa_clti_s_w
:
16720 case CODE_FOR_msa_clti_s_d
:
16721 case CODE_FOR_msa_clei_s_b
:
16722 case CODE_FOR_msa_clei_s_h
:
16723 case CODE_FOR_msa_clei_s_w
:
16724 case CODE_FOR_msa_clei_s_d
:
16725 case CODE_FOR_msa_maxi_s_b
:
16726 case CODE_FOR_msa_maxi_s_h
:
16727 case CODE_FOR_msa_maxi_s_w
:
16728 case CODE_FOR_msa_maxi_s_d
:
16729 case CODE_FOR_msa_mini_s_b
:
16730 case CODE_FOR_msa_mini_s_h
:
16731 case CODE_FOR_msa_mini_s_w
:
16732 case CODE_FOR_msa_mini_s_d
:
16733 gcc_assert (has_target_p
&& nops
== 3);
16734 /* We only generate a vector of constants iff the second argument
16735 is an immediate. We also validate the range of the immediate. */
16736 if (CONST_INT_P (ops
[2].value
))
16740 if (IN_RANGE (INTVAL (ops
[2].value
), rangelo
, rangehi
))
16742 ops
[2].mode
= ops
[0].mode
;
16743 ops
[2].value
= mips_gen_const_int_vector (ops
[2].mode
,
16744 INTVAL (ops
[2].value
));
16751 case CODE_FOR_msa_andi_b
:
16752 case CODE_FOR_msa_ori_b
:
16753 case CODE_FOR_msa_nori_b
:
16754 case CODE_FOR_msa_xori_b
:
16755 gcc_assert (has_target_p
&& nops
== 3);
16756 if (!CONST_INT_P (ops
[2].value
))
16758 ops
[2].mode
= ops
[0].mode
;
16759 ops
[2].value
= mips_gen_const_int_vector (ops
[2].mode
,
16760 INTVAL (ops
[2].value
));
16763 case CODE_FOR_msa_bmzi_b
:
16764 case CODE_FOR_msa_bmnzi_b
:
16765 case CODE_FOR_msa_bseli_b
:
16766 gcc_assert (has_target_p
&& nops
== 4);
16767 if (!CONST_INT_P (ops
[3].value
))
16769 ops
[3].mode
= ops
[0].mode
;
16770 ops
[3].value
= mips_gen_const_int_vector (ops
[3].mode
,
16771 INTVAL (ops
[3].value
));
16774 case CODE_FOR_msa_fill_b
:
16775 case CODE_FOR_msa_fill_h
:
16776 case CODE_FOR_msa_fill_w
:
16777 case CODE_FOR_msa_fill_d
:
16778 /* Map the built-ins to vector fill operations. We need fix up the mode
16779 for the element being inserted. */
16780 gcc_assert (has_target_p
&& nops
== 2);
16781 imode
= GET_MODE_INNER (ops
[0].mode
);
16782 ops
[1].value
= lowpart_subreg (imode
, ops
[1].value
, ops
[1].mode
);
16783 ops
[1].mode
= imode
;
16786 case CODE_FOR_msa_ilvl_b
:
16787 case CODE_FOR_msa_ilvl_h
:
16788 case CODE_FOR_msa_ilvl_w
:
16789 case CODE_FOR_msa_ilvl_d
:
16790 case CODE_FOR_msa_ilvr_b
:
16791 case CODE_FOR_msa_ilvr_h
:
16792 case CODE_FOR_msa_ilvr_w
:
16793 case CODE_FOR_msa_ilvr_d
:
16794 case CODE_FOR_msa_ilvev_b
:
16795 case CODE_FOR_msa_ilvev_h
:
16796 case CODE_FOR_msa_ilvev_w
:
16797 case CODE_FOR_msa_ilvod_b
:
16798 case CODE_FOR_msa_ilvod_h
:
16799 case CODE_FOR_msa_ilvod_w
:
16800 case CODE_FOR_msa_pckev_b
:
16801 case CODE_FOR_msa_pckev_h
:
16802 case CODE_FOR_msa_pckev_w
:
16803 case CODE_FOR_msa_pckod_b
:
16804 case CODE_FOR_msa_pckod_h
:
16805 case CODE_FOR_msa_pckod_w
:
16806 /* Swap the operands 1 and 2 for interleave operations. Built-ins follow
16807 convention of ISA, which have op1 as higher component and op2 as lower
16808 component. However, the VEC_PERM op in tree and vec_concat in RTL
16809 expects first operand to be lower component, because of which this
16810 swap is needed for builtins. */
16811 gcc_assert (has_target_p
&& nops
== 3);
16812 std::swap (ops
[1], ops
[2]);
16815 case CODE_FOR_msa_slli_b
:
16816 case CODE_FOR_msa_slli_h
:
16817 case CODE_FOR_msa_slli_w
:
16818 case CODE_FOR_msa_slli_d
:
16819 case CODE_FOR_msa_srai_b
:
16820 case CODE_FOR_msa_srai_h
:
16821 case CODE_FOR_msa_srai_w
:
16822 case CODE_FOR_msa_srai_d
:
16823 case CODE_FOR_msa_srli_b
:
16824 case CODE_FOR_msa_srli_h
:
16825 case CODE_FOR_msa_srli_w
:
16826 case CODE_FOR_msa_srli_d
:
16827 gcc_assert (has_target_p
&& nops
== 3);
16828 if (CONST_INT_P (ops
[2].value
))
16831 rangehi
= GET_MODE_UNIT_BITSIZE (ops
[0].mode
) - 1;
16832 if (IN_RANGE (INTVAL (ops
[2].value
), rangelo
, rangehi
))
16834 ops
[2].mode
= ops
[0].mode
;
16835 ops
[2].value
= mips_gen_const_int_vector (ops
[2].mode
,
16836 INTVAL (ops
[2].value
));
16843 case CODE_FOR_msa_insert_b
:
16844 case CODE_FOR_msa_insert_h
:
16845 case CODE_FOR_msa_insert_w
:
16846 case CODE_FOR_msa_insert_d
:
16847 /* Map the built-ins to insert operations. We need to swap operands,
16848 fix up the mode for the element being inserted, and generate
16849 a bit mask for vec_merge. */
16850 gcc_assert (has_target_p
&& nops
== 4);
16851 std::swap (ops
[1], ops
[2]);
16852 std::swap (ops
[1], ops
[3]);
16853 imode
= GET_MODE_INNER (ops
[0].mode
);
16854 ops
[1].value
= lowpart_subreg (imode
, ops
[1].value
, ops
[1].mode
);
16855 ops
[1].mode
= imode
;
16857 rangehi
= GET_MODE_NUNITS (ops
[0].mode
) - 1;
16858 if (CONST_INT_P (ops
[3].value
)
16859 && IN_RANGE (INTVAL (ops
[3].value
), rangelo
, rangehi
))
16860 ops
[3].value
= GEN_INT (1 << INTVAL (ops
[3].value
));
16865 case CODE_FOR_msa_insve_b
:
16866 case CODE_FOR_msa_insve_h
:
16867 case CODE_FOR_msa_insve_w
:
16868 case CODE_FOR_msa_insve_d
:
16869 /* Map the built-ins to element insert operations. We need to swap
16870 operands and generate a bit mask. */
16871 gcc_assert (has_target_p
&& nops
== 4);
16872 std::swap (ops
[1], ops
[2]);
16873 std::swap (ops
[1], ops
[3]);
16875 rangehi
= GET_MODE_NUNITS (ops
[0].mode
) - 1;
16876 if (CONST_INT_P (ops
[3].value
)
16877 && IN_RANGE (INTVAL (ops
[3].value
), rangelo
, rangehi
))
16878 ops
[3].value
= GEN_INT (1 << INTVAL (ops
[3].value
));
16883 case CODE_FOR_msa_shf_b
:
16884 case CODE_FOR_msa_shf_h
:
16885 case CODE_FOR_msa_shf_w
:
16886 case CODE_FOR_msa_shf_w_f
:
16887 gcc_assert (has_target_p
&& nops
== 3);
16888 ops
[2].value
= mips_gen_const_int_vector_shuffle (ops
[0].mode
,
16889 INTVAL (ops
[2].value
));
16892 case CODE_FOR_msa_vshf_b
:
16893 case CODE_FOR_msa_vshf_h
:
16894 case CODE_FOR_msa_vshf_w
:
16895 case CODE_FOR_msa_vshf_d
:
16896 gcc_assert (has_target_p
&& nops
== 4);
16897 std::swap (ops
[1], ops
[3]);
16904 if (error_opno
!= 0)
16906 error ("argument %d to the built-in must be a constant"
16907 " in range %d to %d", error_opno
, rangelo
, rangehi
);
16908 return has_target_p
? gen_reg_rtx (ops
[0].mode
) : const0_rtx
;
16910 else if (!maybe_expand_insn (icode
, nops
, ops
))
16912 error ("invalid argument to built-in function");
16913 return has_target_p
? gen_reg_rtx (ops
[0].mode
) : const0_rtx
;
16915 return has_target_p
? ops
[0].value
: const0_rtx
;
16918 /* Expand a floating-point comparison for built-in function call EXP.
16919 The first NARGS arguments are the values to be compared. ICODE is
16920 the .md pattern that does the comparison and COND is the condition
16921 that is being tested. Return an rtx for the result. */
16924 mips_expand_builtin_compare_1 (enum insn_code icode
,
16925 enum mips_fp_condition cond
,
16926 tree exp
, int nargs
)
16928 struct expand_operand ops
[MAX_RECOG_OPERANDS
];
16932 /* The instruction should have a target operand, an operand for each
16933 argument, and an operand for COND. */
16934 gcc_assert (nargs
+ 2 == insn_data
[(int) icode
].n_generator_args
);
16936 output
= mips_allocate_fcc (insn_data
[(int) icode
].operand
[0].mode
);
16938 create_fixed_operand (&ops
[opno
++], output
);
16939 for (argno
= 0; argno
< nargs
; argno
++)
16940 mips_prepare_builtin_arg (&ops
[opno
++], exp
, argno
);
16941 create_integer_operand (&ops
[opno
++], (int) cond
);
16942 return mips_expand_builtin_insn (icode
, opno
, ops
, true);
16945 /* Expand a MIPS_BUILTIN_DIRECT or MIPS_BUILTIN_DIRECT_NO_TARGET function;
16946 HAS_TARGET_P says which. EXP is the CALL_EXPR that calls the function
16947 and ICODE is the code of the associated .md pattern. TARGET, if nonnull,
16948 suggests a good place to put the result. */
16951 mips_expand_builtin_direct (enum insn_code icode
, rtx target
, tree exp
,
16954 struct expand_operand ops
[MAX_RECOG_OPERANDS
];
16957 /* Map any target to operand 0. */
16960 create_output_operand (&ops
[opno
++], target
, TYPE_MODE (TREE_TYPE (exp
)));
16962 /* Map the arguments to the other operands. */
16963 gcc_assert (opno
+ call_expr_nargs (exp
)
16964 == insn_data
[icode
].n_generator_args
);
16965 for (argno
= 0; argno
< call_expr_nargs (exp
); argno
++)
16966 mips_prepare_builtin_arg (&ops
[opno
++], exp
, argno
);
16968 return mips_expand_builtin_insn (icode
, opno
, ops
, has_target_p
);
16971 /* Expand a __builtin_mips_movt_*_ps or __builtin_mips_movf_*_ps
16972 function; TYPE says which. EXP is the CALL_EXPR that calls the
16973 function, ICODE is the instruction that should be used to compare
16974 the first two arguments, and COND is the condition it should test.
16975 TARGET, if nonnull, suggests a good place to put the result. */
16978 mips_expand_builtin_movtf (enum mips_builtin_type type
,
16979 enum insn_code icode
, enum mips_fp_condition cond
,
16980 rtx target
, tree exp
)
16982 struct expand_operand ops
[4];
16985 cmp_result
= mips_expand_builtin_compare_1 (icode
, cond
, exp
, 2);
16986 create_output_operand (&ops
[0], target
, TYPE_MODE (TREE_TYPE (exp
)));
16987 if (type
== MIPS_BUILTIN_MOVT
)
16989 mips_prepare_builtin_arg (&ops
[2], exp
, 2);
16990 mips_prepare_builtin_arg (&ops
[1], exp
, 3);
16994 mips_prepare_builtin_arg (&ops
[1], exp
, 2);
16995 mips_prepare_builtin_arg (&ops
[2], exp
, 3);
16997 create_fixed_operand (&ops
[3], cmp_result
);
16998 return mips_expand_builtin_insn (CODE_FOR_mips_cond_move_tf_ps
,
17002 /* Expand an MSA built-in for a compare and branch instruction specified by
17003 ICODE, set a general-purpose register to 1 if the branch was taken,
17007 mips_expand_builtin_msa_test_branch (enum insn_code icode
, tree exp
)
17009 struct expand_operand ops
[3];
17011 rtx_code_label
*true_label
, *done_label
;
17014 true_label
= gen_label_rtx ();
17015 done_label
= gen_label_rtx ();
17017 create_input_operand (&ops
[0], true_label
, TYPE_MODE (TREE_TYPE (exp
)));
17018 mips_prepare_builtin_arg (&ops
[1], exp
, 0);
17019 create_fixed_operand (&ops
[2], const0_rtx
);
17021 /* Make sure that the operand 1 is a REG. */
17022 if (GET_CODE (ops
[1].value
) != REG
)
17023 ops
[1].value
= force_reg (ops
[1].mode
, ops
[1].value
);
17025 if ((cbranch
= maybe_gen_insn (icode
, 3, ops
)) == NULL_RTX
)
17026 error ("failed to expand built-in function");
17028 cmp_result
= gen_reg_rtx (SImode
);
17030 /* First assume that CMP_RESULT is false. */
17031 mips_emit_move (cmp_result
, const0_rtx
);
17033 /* Branch to TRUE_LABEL if CBRANCH is taken and DONE_LABEL otherwise. */
17034 emit_jump_insn (cbranch
);
17035 emit_jump_insn (gen_jump (done_label
));
17038 /* Set CMP_RESULT to true if the branch was taken. */
17039 emit_label (true_label
);
17040 mips_emit_move (cmp_result
, const1_rtx
);
17042 emit_label (done_label
);
17046 /* Move VALUE_IF_TRUE into TARGET if CONDITION is true; move VALUE_IF_FALSE
17047 into TARGET otherwise. Return TARGET. */
17050 mips_builtin_branch_and_move (rtx condition
, rtx target
,
17051 rtx value_if_true
, rtx value_if_false
)
17053 rtx_code_label
*true_label
, *done_label
;
17055 true_label
= gen_label_rtx ();
17056 done_label
= gen_label_rtx ();
17058 /* First assume that CONDITION is false. */
17059 mips_emit_move (target
, value_if_false
);
17061 /* Branch to TRUE_LABEL if CONDITION is true and DONE_LABEL otherwise. */
17062 emit_jump_insn (gen_condjump (condition
, true_label
));
17063 emit_jump_insn (gen_jump (done_label
));
17066 /* Fix TARGET if CONDITION is true. */
17067 emit_label (true_label
);
17068 mips_emit_move (target
, value_if_true
);
17070 emit_label (done_label
);
17074 /* Expand a comparison built-in function of type BUILTIN_TYPE. EXP is
17075 the CALL_EXPR that calls the function, ICODE is the code of the
17076 comparison instruction, and COND is the condition it should test.
17077 TARGET, if nonnull, suggests a good place to put the boolean result. */
17080 mips_expand_builtin_compare (enum mips_builtin_type builtin_type
,
17081 enum insn_code icode
, enum mips_fp_condition cond
,
17082 rtx target
, tree exp
)
17084 rtx offset
, condition
, cmp_result
;
17086 if (target
== 0 || GET_MODE (target
) != SImode
)
17087 target
= gen_reg_rtx (SImode
);
17088 cmp_result
= mips_expand_builtin_compare_1 (icode
, cond
, exp
,
17089 call_expr_nargs (exp
));
17091 /* If the comparison sets more than one register, we define the result
17092 to be 0 if all registers are false and -1 if all registers are true.
17093 The value of the complete result is indeterminate otherwise. */
17094 switch (builtin_type
)
17096 case MIPS_BUILTIN_CMP_ALL
:
17097 condition
= gen_rtx_NE (VOIDmode
, cmp_result
, constm1_rtx
);
17098 return mips_builtin_branch_and_move (condition
, target
,
17099 const0_rtx
, const1_rtx
);
17101 case MIPS_BUILTIN_CMP_UPPER
:
17102 case MIPS_BUILTIN_CMP_LOWER
:
17103 offset
= GEN_INT (builtin_type
== MIPS_BUILTIN_CMP_UPPER
);
17104 condition
= gen_single_cc (cmp_result
, offset
);
17105 return mips_builtin_branch_and_move (condition
, target
,
17106 const1_rtx
, const0_rtx
);
17109 condition
= gen_rtx_NE (VOIDmode
, cmp_result
, const0_rtx
);
17110 return mips_builtin_branch_and_move (condition
, target
,
17111 const1_rtx
, const0_rtx
);
17115 /* Expand a bposge built-in function of type BUILTIN_TYPE. TARGET,
17116 if nonnull, suggests a good place to put the boolean result. */
17119 mips_expand_builtin_bposge (enum mips_builtin_type builtin_type
, rtx target
)
17121 rtx condition
, cmp_result
;
17124 if (target
== 0 || GET_MODE (target
) != SImode
)
17125 target
= gen_reg_rtx (SImode
);
17127 cmp_result
= gen_rtx_REG (CCDSPmode
, CCDSP_PO_REGNUM
);
17129 if (builtin_type
== MIPS_BUILTIN_BPOSGE32
)
17134 condition
= gen_rtx_GE (VOIDmode
, cmp_result
, GEN_INT (cmp_value
));
17135 return mips_builtin_branch_and_move (condition
, target
,
17136 const1_rtx
, const0_rtx
);
17139 /* Implement TARGET_EXPAND_BUILTIN. */
17142 mips_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
17143 machine_mode mode
, int ignore
)
17146 unsigned int fcode
, avail
;
17147 const struct mips_builtin_description
*d
;
17149 fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
17150 fcode
= DECL_FUNCTION_CODE (fndecl
);
17151 gcc_assert (fcode
< ARRAY_SIZE (mips_builtins
));
17152 d
= &mips_builtins
[fcode
];
17153 avail
= d
->avail ();
17154 gcc_assert (avail
!= 0);
17155 if (TARGET_MIPS16
&& !(avail
& BUILTIN_AVAIL_MIPS16
))
17157 error ("built-in function %qE not supported for MIPS16",
17158 DECL_NAME (fndecl
));
17159 return ignore
? const0_rtx
: CONST0_RTX (mode
);
17161 switch (d
->builtin_type
)
17163 case MIPS_BUILTIN_DIRECT
:
17164 return mips_expand_builtin_direct (d
->icode
, target
, exp
, true);
17166 case MIPS_BUILTIN_DIRECT_NO_TARGET
:
17167 return mips_expand_builtin_direct (d
->icode
, target
, exp
, false);
17169 case MIPS_BUILTIN_MOVT
:
17170 case MIPS_BUILTIN_MOVF
:
17171 return mips_expand_builtin_movtf (d
->builtin_type
, d
->icode
,
17172 d
->cond
, target
, exp
);
17174 case MIPS_BUILTIN_CMP_ANY
:
17175 case MIPS_BUILTIN_CMP_ALL
:
17176 case MIPS_BUILTIN_CMP_UPPER
:
17177 case MIPS_BUILTIN_CMP_LOWER
:
17178 case MIPS_BUILTIN_CMP_SINGLE
:
17179 return mips_expand_builtin_compare (d
->builtin_type
, d
->icode
,
17180 d
->cond
, target
, exp
);
17182 case MIPS_BUILTIN_MSA_TEST_BRANCH
:
17183 return mips_expand_builtin_msa_test_branch (d
->icode
, exp
);
17185 case MIPS_BUILTIN_BPOSGE32
:
17186 return mips_expand_builtin_bposge (d
->builtin_type
, target
);
17188 gcc_unreachable ();
17191 /* An entry in the MIPS16 constant pool. VALUE is the pool constant,
17192 MODE is its mode, and LABEL is the CODE_LABEL associated with it. */
17193 struct mips16_constant
{
17194 struct mips16_constant
*next
;
17196 rtx_code_label
*label
;
17200 /* Information about an incomplete MIPS16 constant pool. FIRST is the
17201 first constant, HIGHEST_ADDRESS is the highest address that the first
17202 byte of the pool can have, and INSN_ADDRESS is the current instruction
17204 struct mips16_constant_pool
{
17205 struct mips16_constant
*first
;
17206 int highest_address
;
17210 /* Add constant VALUE to POOL and return its label. MODE is the
17211 value's mode (used for CONST_INTs, etc.). */
17213 static rtx_code_label
*
17214 mips16_add_constant (struct mips16_constant_pool
*pool
,
17215 rtx value
, machine_mode mode
)
17217 struct mips16_constant
**p
, *c
;
17218 bool first_of_size_p
;
17220 /* See whether the constant is already in the pool. If so, return the
17221 existing label, otherwise leave P pointing to the place where the
17222 constant should be added.
17224 Keep the pool sorted in increasing order of mode size so that we can
17225 reduce the number of alignments needed. */
17226 first_of_size_p
= true;
17227 for (p
= &pool
->first
; *p
!= 0; p
= &(*p
)->next
)
17229 if (mode
== (*p
)->mode
&& rtx_equal_p (value
, (*p
)->value
))
17230 return (*p
)->label
;
17231 if (GET_MODE_SIZE (mode
) < GET_MODE_SIZE ((*p
)->mode
))
17233 if (GET_MODE_SIZE (mode
) == GET_MODE_SIZE ((*p
)->mode
))
17234 first_of_size_p
= false;
17237 /* In the worst case, the constant needed by the earliest instruction
17238 will end up at the end of the pool. The entire pool must then be
17239 accessible from that instruction.
17241 When adding the first constant, set the pool's highest address to
17242 the address of the first out-of-range byte. Adjust this address
17243 downwards each time a new constant is added. */
17244 if (pool
->first
== 0)
17245 /* For LWPC, ADDIUPC and DADDIUPC, the base PC value is the address
17246 of the instruction with the lowest two bits clear. The base PC
17247 value for LDPC has the lowest three bits clear. Assume the worst
17248 case here; namely that the PC-relative instruction occupies the
17249 last 2 bytes in an aligned word. */
17250 pool
->highest_address
= pool
->insn_address
- (UNITS_PER_WORD
- 2) + 0x8000;
17251 pool
->highest_address
-= GET_MODE_SIZE (mode
);
17252 if (first_of_size_p
)
17253 /* Take into account the worst possible padding due to alignment. */
17254 pool
->highest_address
-= GET_MODE_SIZE (mode
) - 1;
17256 /* Create a new entry. */
17257 c
= XNEW (struct mips16_constant
);
17260 c
->label
= gen_label_rtx ();
17267 /* Output constant VALUE after instruction INSN and return the last
17268 instruction emitted. MODE is the mode of the constant. */
17271 mips16_emit_constants_1 (machine_mode mode
, rtx value
, rtx_insn
*insn
)
17273 if (SCALAR_INT_MODE_P (mode
) || ALL_SCALAR_FIXED_POINT_MODE_P (mode
))
17275 rtx size
= GEN_INT (GET_MODE_SIZE (mode
));
17276 return emit_insn_after (gen_consttable_int (value
, size
), insn
);
17279 if (SCALAR_FLOAT_MODE_P (mode
))
17280 return emit_insn_after (gen_consttable_float (value
), insn
);
17282 if (VECTOR_MODE_P (mode
))
17286 for (i
= 0; i
< CONST_VECTOR_NUNITS (value
); i
++)
17287 insn
= mips16_emit_constants_1 (GET_MODE_INNER (mode
),
17288 CONST_VECTOR_ELT (value
, i
), insn
);
17292 gcc_unreachable ();
17295 /* Dump out the constants in CONSTANTS after INSN. Record the initial
17296 label number in the `consttable' and `consttable_end' insns emitted
17297 at the beginning and the end of the constant pool respectively, so
17298 that individual pools can be uniquely marked as data for the purpose
17302 mips16_emit_constants (struct mips16_constant
*constants
, rtx_insn
*insn
)
17304 int label_num
= constants
? CODE_LABEL_NUMBER (constants
->label
) : 0;
17305 struct mips16_constant
*c
, *next
;
17310 insn
= emit_insn_after (gen_consttable (GEN_INT (label_num
)), insn
);
17311 for (c
= constants
; c
!= NULL
; c
= next
)
17313 /* If necessary, increase the alignment of PC. */
17314 if (align
< GET_MODE_SIZE (c
->mode
))
17316 int align_log
= floor_log2 (GET_MODE_SIZE (c
->mode
));
17317 insn
= emit_insn_after (gen_align (GEN_INT (align_log
)), insn
);
17319 align
= GET_MODE_SIZE (c
->mode
);
17321 insn
= emit_label_after (c
->label
, insn
);
17322 insn
= mips16_emit_constants_1 (c
->mode
, c
->value
, insn
);
17328 insn
= emit_insn_after (gen_consttable_end (GEN_INT (label_num
)), insn
);
17330 emit_barrier_after (insn
);
17333 /* Return the length of instruction INSN. */
17336 mips16_insn_length (rtx_insn
*insn
)
17338 if (JUMP_TABLE_DATA_P (insn
))
17340 rtx body
= PATTERN (insn
);
17341 if (GET_CODE (body
) == ADDR_VEC
)
17342 return GET_MODE_SIZE (GET_MODE (body
)) * XVECLEN (body
, 0);
17343 else if (GET_CODE (body
) == ADDR_DIFF_VEC
)
17344 return GET_MODE_SIZE (GET_MODE (body
)) * XVECLEN (body
, 1);
17346 gcc_unreachable ();
17348 return get_attr_length (insn
);
17351 /* If *X is a symbolic constant that refers to the constant pool, add
17352 the constant to POOL and rewrite *X to use the constant's label. */
17355 mips16_rewrite_pool_constant (struct mips16_constant_pool
*pool
, rtx
*x
)
17358 rtx_code_label
*label
;
17360 split_const (*x
, &base
, &offset
);
17361 if (GET_CODE (base
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (base
))
17363 label
= mips16_add_constant (pool
, copy_rtx (get_pool_constant (base
)),
17364 get_pool_mode (base
));
17365 base
= gen_rtx_LABEL_REF (Pmode
, label
);
17366 *x
= mips_unspec_address_offset (base
, offset
, SYMBOL_PC_RELATIVE
);
17370 /* Rewrite INSN so that constant pool references refer to the constant's
17374 mips16_rewrite_pool_refs (rtx_insn
*insn
, struct mips16_constant_pool
*pool
)
17376 subrtx_ptr_iterator::array_type array
;
17377 FOR_EACH_SUBRTX_PTR (iter
, array
, &PATTERN (insn
), ALL
)
17381 if (force_to_mem_operand (*loc
, Pmode
))
17383 rtx mem
= force_const_mem (GET_MODE (*loc
), *loc
);
17384 validate_change (insn
, loc
, mem
, false);
17389 mips16_rewrite_pool_constant (pool
, &XEXP (*loc
, 0));
17390 iter
.skip_subrtxes ();
17394 if (TARGET_MIPS16_TEXT_LOADS
)
17395 mips16_rewrite_pool_constant (pool
, loc
);
17396 if (GET_CODE (*loc
) == CONST
17397 /* Don't rewrite the __mips16_rdwr symbol. */
17398 || (GET_CODE (*loc
) == UNSPEC
17399 && XINT (*loc
, 1) == UNSPEC_TLS_GET_TP
))
17400 iter
.skip_subrtxes ();
17405 /* Return whether CFG is used in mips_reorg. */
17408 mips_cfg_in_reorg (void)
17410 return (mips_r10k_cache_barrier
!= R10K_CACHE_BARRIER_NONE
17411 || TARGET_RELAX_PIC_CALLS
);
17414 /* Build MIPS16 constant pools. Split the instructions if SPLIT_P,
17415 otherwise assume that they are already split. */
17418 mips16_lay_out_constants (bool split_p
)
17420 struct mips16_constant_pool pool
;
17421 rtx_insn
*insn
, *barrier
;
17423 if (!TARGET_MIPS16_PCREL_LOADS
)
17428 if (mips_cfg_in_reorg ())
17429 split_all_insns ();
17431 split_all_insns_noflow ();
17434 memset (&pool
, 0, sizeof (pool
));
17435 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
17437 /* Rewrite constant pool references in INSN. */
17438 if (USEFUL_INSN_P (insn
))
17439 mips16_rewrite_pool_refs (insn
, &pool
);
17441 pool
.insn_address
+= mips16_insn_length (insn
);
17443 if (pool
.first
!= NULL
)
17445 /* If there are no natural barriers between the first user of
17446 the pool and the highest acceptable address, we'll need to
17447 create a new instruction to jump around the constant pool.
17448 In the worst case, this instruction will be 4 bytes long.
17450 If it's too late to do this transformation after INSN,
17451 do it immediately before INSN. */
17452 if (barrier
== 0 && pool
.insn_address
+ 4 > pool
.highest_address
)
17454 rtx_code_label
*label
;
17457 label
= gen_label_rtx ();
17459 jump
= emit_jump_insn_before (gen_jump (label
), insn
);
17460 JUMP_LABEL (jump
) = label
;
17461 LABEL_NUSES (label
) = 1;
17462 barrier
= emit_barrier_after (jump
);
17464 emit_label_after (label
, barrier
);
17465 pool
.insn_address
+= 4;
17468 /* See whether the constant pool is now out of range of the first
17469 user. If so, output the constants after the previous barrier.
17470 Note that any instructions between BARRIER and INSN (inclusive)
17471 will use negative offsets to refer to the pool. */
17472 if (pool
.insn_address
> pool
.highest_address
)
17474 mips16_emit_constants (pool
.first
, barrier
);
17478 else if (BARRIER_P (insn
))
17482 mips16_emit_constants (pool
.first
, get_last_insn ());
17485 /* Return true if it is worth r10k_simplify_address's while replacing
17486 an address with X. We are looking for constants, and for addresses
17487 at a known offset from the incoming stack pointer. */
17490 r10k_simplified_address_p (rtx x
)
17492 if (GET_CODE (x
) == PLUS
&& CONST_INT_P (XEXP (x
, 1)))
17494 return x
== virtual_incoming_args_rtx
|| CONSTANT_P (x
);
17497 /* X is an expression that appears in INSN. Try to use the UD chains
17498 to simplify it, returning the simplified form on success and the
17499 original form otherwise. Replace the incoming value of $sp with
17500 virtual_incoming_args_rtx (which should never occur in X otherwise). */
17503 r10k_simplify_address (rtx x
, rtx_insn
*insn
)
17505 rtx newx
, op0
, op1
, set
, note
;
17506 rtx_insn
*def_insn
;
17508 struct df_link
*defs
;
17513 op0
= r10k_simplify_address (XEXP (x
, 0), insn
);
17514 if (op0
!= XEXP (x
, 0))
17515 newx
= simplify_gen_unary (GET_CODE (x
), GET_MODE (x
),
17516 op0
, GET_MODE (XEXP (x
, 0)));
17518 else if (BINARY_P (x
))
17520 op0
= r10k_simplify_address (XEXP (x
, 0), insn
);
17521 op1
= r10k_simplify_address (XEXP (x
, 1), insn
);
17522 if (op0
!= XEXP (x
, 0) || op1
!= XEXP (x
, 1))
17523 newx
= simplify_gen_binary (GET_CODE (x
), GET_MODE (x
), op0
, op1
);
17525 else if (GET_CODE (x
) == LO_SUM
)
17527 /* LO_SUMs can be offset from HIGHs, if we know they won't
17528 overflow. See mips_classify_address for the rationale behind
17530 op0
= r10k_simplify_address (XEXP (x
, 0), insn
);
17531 if (GET_CODE (op0
) == HIGH
)
17532 newx
= XEXP (x
, 1);
17534 else if (REG_P (x
))
17536 /* Uses are recorded by regno_reg_rtx, not X itself. */
17537 use
= df_find_use (insn
, regno_reg_rtx
[REGNO (x
)]);
17539 defs
= DF_REF_CHAIN (use
);
17541 /* Require a single definition. */
17542 if (defs
&& defs
->next
== NULL
)
17545 if (DF_REF_IS_ARTIFICIAL (def
))
17547 /* Replace the incoming value of $sp with
17548 virtual_incoming_args_rtx. */
17549 if (x
== stack_pointer_rtx
17550 && DF_REF_BB (def
) == ENTRY_BLOCK_PTR_FOR_FN (cfun
))
17551 newx
= virtual_incoming_args_rtx
;
17553 else if (dominated_by_p (CDI_DOMINATORS
, DF_REF_BB (use
),
17556 /* Make sure that DEF_INSN is a single set of REG. */
17557 def_insn
= DF_REF_INSN (def
);
17558 if (NONJUMP_INSN_P (def_insn
))
17560 set
= single_set (def_insn
);
17561 if (set
&& rtx_equal_p (SET_DEST (set
), x
))
17563 /* Prefer to use notes, since the def-use chains
17564 are often shorter. */
17565 note
= find_reg_equal_equiv_note (def_insn
);
17567 newx
= XEXP (note
, 0);
17569 newx
= SET_SRC (set
);
17570 newx
= r10k_simplify_address (newx
, def_insn
);
17576 if (newx
&& r10k_simplified_address_p (newx
))
17581 /* Return true if ADDRESS is known to be an uncached address
17582 on R10K systems. */
17585 r10k_uncached_address_p (unsigned HOST_WIDE_INT address
)
17587 unsigned HOST_WIDE_INT upper
;
17589 /* Check for KSEG1. */
17590 if (address
+ 0x60000000 < 0x20000000)
17593 /* Check for uncached XKPHYS addresses. */
17594 if (Pmode
== DImode
)
17596 upper
= (address
>> 40) & 0xf9ffff;
17597 if (upper
== 0x900000 || upper
== 0xb80000)
17603 /* Return true if we can prove that an access to address X in instruction
17604 INSN would be safe from R10K speculation. This X is a general
17605 expression; it might not be a legitimate address. */
17608 r10k_safe_address_p (rtx x
, rtx_insn
*insn
)
17611 HOST_WIDE_INT offset_val
;
17613 x
= r10k_simplify_address (x
, insn
);
17615 /* Check for references to the stack frame. It doesn't really matter
17616 how much of the frame has been allocated at INSN; -mr10k-cache-barrier
17617 allows us to assume that accesses to any part of the eventual frame
17618 is safe from speculation at any point in the function. */
17619 mips_split_plus (x
, &base
, &offset_val
);
17620 if (base
== virtual_incoming_args_rtx
17621 && offset_val
>= -cfun
->machine
->frame
.total_size
17622 && offset_val
< cfun
->machine
->frame
.args_size
)
17625 /* Check for uncached addresses. */
17626 if (CONST_INT_P (x
))
17627 return r10k_uncached_address_p (INTVAL (x
));
17629 /* Check for accesses to a static object. */
17630 split_const (x
, &base
, &offset
);
17631 return offset_within_block_p (base
, INTVAL (offset
));
17634 /* Return true if a MEM with MEM_EXPR EXPR and MEM_OFFSET OFFSET is
17635 an in-range access to an automatic variable, or to an object with
17636 a link-time-constant address. */
17639 r10k_safe_mem_expr_p (tree expr
, unsigned HOST_WIDE_INT offset
)
17641 poly_int64 bitoffset
, bitsize
;
17642 tree inner
, var_offset
;
17644 int unsigned_p
, reverse_p
, volatile_p
;
17646 inner
= get_inner_reference (expr
, &bitsize
, &bitoffset
, &var_offset
, &mode
,
17647 &unsigned_p
, &reverse_p
, &volatile_p
);
17648 if (!DECL_P (inner
) || !DECL_SIZE_UNIT (inner
) || var_offset
)
17651 offset
+= bitoffset
/ BITS_PER_UNIT
;
17652 return offset
< tree_to_uhwi (DECL_SIZE_UNIT (inner
));
17655 /* Return true if X contains a MEM that is not safe from R10K speculation.
17656 INSN is the instruction that contains X. */
17659 r10k_needs_protection_p_1 (rtx x
, rtx_insn
*insn
)
17661 subrtx_var_iterator::array_type array
;
17662 FOR_EACH_SUBRTX_VAR (iter
, array
, x
, NONCONST
)
17667 if ((MEM_EXPR (mem
)
17668 && MEM_OFFSET_KNOWN_P (mem
)
17669 && r10k_safe_mem_expr_p (MEM_EXPR (mem
), MEM_OFFSET (mem
)))
17670 || r10k_safe_address_p (XEXP (mem
, 0), insn
))
17671 iter
.skip_subrtxes ();
17679 /* A note_stores callback for which DATA points to an instruction pointer.
17680 If *DATA is nonnull, make it null if it X contains a MEM that is not
17681 safe from R10K speculation. */
17684 r10k_needs_protection_p_store (rtx x
, const_rtx pat ATTRIBUTE_UNUSED
,
17687 rtx_insn
**insn_ptr
;
17689 insn_ptr
= (rtx_insn
**) data
;
17690 if (*insn_ptr
&& r10k_needs_protection_p_1 (x
, *insn_ptr
))
17694 /* X is the pattern of a call instruction. Return true if the call is
17695 not to a declared function. */
17698 r10k_needs_protection_p_call (const_rtx x
)
17700 subrtx_iterator::array_type array
;
17701 FOR_EACH_SUBRTX (iter
, array
, x
, NONCONST
)
17703 const_rtx mem
= *iter
;
17706 const_rtx addr
= XEXP (mem
, 0);
17707 if (GET_CODE (addr
) == SYMBOL_REF
&& SYMBOL_REF_DECL (addr
))
17708 iter
.skip_subrtxes ();
17716 /* Return true if instruction INSN needs to be protected by an R10K
17720 r10k_needs_protection_p (rtx_insn
*insn
)
17723 return r10k_needs_protection_p_call (PATTERN (insn
));
17725 if (mips_r10k_cache_barrier
== R10K_CACHE_BARRIER_STORE
)
17727 note_stores (PATTERN (insn
), r10k_needs_protection_p_store
, &insn
);
17728 return insn
== NULL_RTX
;
17731 return r10k_needs_protection_p_1 (PATTERN (insn
), insn
);
17734 /* Return true if BB is only reached by blocks in PROTECTED_BBS and if every
17735 edge is unconditional. */
17738 r10k_protected_bb_p (basic_block bb
, sbitmap protected_bbs
)
17743 FOR_EACH_EDGE (e
, ei
, bb
->preds
)
17744 if (!single_succ_p (e
->src
)
17745 || !bitmap_bit_p (protected_bbs
, e
->src
->index
)
17746 || (e
->flags
& EDGE_COMPLEX
) != 0)
17751 /* Implement -mr10k-cache-barrier= for the current function. */
17754 r10k_insert_cache_barriers (void)
17756 int *rev_post_order
;
17759 sbitmap protected_bbs
;
17760 rtx_insn
*insn
, *end
;
17761 rtx unprotected_region
;
17765 sorry ("%qs does not support MIPS16 code", "-mr10k-cache-barrier");
17769 /* Calculate dominators. */
17770 calculate_dominance_info (CDI_DOMINATORS
);
17772 /* Bit X of PROTECTED_BBS is set if the last operation in basic block
17773 X is protected by a cache barrier. */
17774 protected_bbs
= sbitmap_alloc (last_basic_block_for_fn (cfun
));
17775 bitmap_clear (protected_bbs
);
17777 /* Iterate over the basic blocks in reverse post-order. */
17778 rev_post_order
= XNEWVEC (int, last_basic_block_for_fn (cfun
));
17779 n
= pre_and_rev_post_order_compute (NULL
, rev_post_order
, false);
17780 for (i
= 0; i
< n
; i
++)
17782 bb
= BASIC_BLOCK_FOR_FN (cfun
, rev_post_order
[i
]);
17784 /* If this block is only reached by unconditional edges, and if the
17785 source of every edge is protected, the beginning of the block is
17787 if (r10k_protected_bb_p (bb
, protected_bbs
))
17788 unprotected_region
= NULL_RTX
;
17790 unprotected_region
= pc_rtx
;
17791 end
= NEXT_INSN (BB_END (bb
));
17793 /* UNPROTECTED_REGION is:
17795 - null if we are processing a protected region,
17796 - pc_rtx if we are processing an unprotected region but have
17797 not yet found the first instruction in it
17798 - the first instruction in an unprotected region otherwise. */
17799 for (insn
= BB_HEAD (bb
); insn
!= end
; insn
= NEXT_INSN (insn
))
17801 if (unprotected_region
&& USEFUL_INSN_P (insn
))
17803 if (recog_memoized (insn
) == CODE_FOR_mips_cache
)
17804 /* This CACHE instruction protects the following code. */
17805 unprotected_region
= NULL_RTX
;
17808 /* See if INSN is the first instruction in this
17809 unprotected region. */
17810 if (unprotected_region
== pc_rtx
)
17811 unprotected_region
= insn
;
17813 /* See if INSN needs to be protected. If so,
17814 we must insert a cache barrier somewhere between
17815 PREV_INSN (UNPROTECTED_REGION) and INSN. It isn't
17816 clear which position is better performance-wise,
17817 but as a tie-breaker, we assume that it is better
17818 to allow delay slots to be back-filled where
17819 possible, and that it is better not to insert
17820 barriers in the middle of already-scheduled code.
17821 We therefore insert the barrier at the beginning
17823 if (r10k_needs_protection_p (insn
))
17825 emit_insn_before (gen_r10k_cache_barrier (),
17826 as_a
<rtx_insn
*> (unprotected_region
));
17827 unprotected_region
= NULL_RTX
;
17833 /* The called function is not required to protect the exit path.
17834 The code that follows a call is therefore unprotected. */
17835 unprotected_region
= pc_rtx
;
17838 /* Record whether the end of this block is protected. */
17839 if (unprotected_region
== NULL_RTX
)
17840 bitmap_set_bit (protected_bbs
, bb
->index
);
17842 XDELETEVEC (rev_post_order
);
17844 sbitmap_free (protected_bbs
);
17846 free_dominance_info (CDI_DOMINATORS
);
17849 /* If INSN is a call, return the underlying CALL expr. Return NULL_RTX
17850 otherwise. If INSN has two call rtx, then store the second one in
17854 mips_call_expr_from_insn (rtx_insn
*insn
, rtx
*second_call
)
17859 if (!CALL_P (insn
))
17862 x
= PATTERN (insn
);
17863 if (GET_CODE (x
) == PARALLEL
)
17865 /* Calls returning complex values have two CALL rtx. Look for the second
17866 one here, and return it via the SECOND_CALL arg. */
17867 x2
= XVECEXP (x
, 0, 1);
17868 if (GET_CODE (x2
) == SET
)
17870 if (GET_CODE (x2
) == CALL
)
17873 x
= XVECEXP (x
, 0, 0);
17875 if (GET_CODE (x
) == SET
)
17877 gcc_assert (GET_CODE (x
) == CALL
);
17882 /* REG is set in DEF. See if the definition is one of the ways we load a
17883 register with a symbol address for a mips_use_pic_fn_addr_reg_p call.
17884 If it is, return the symbol reference of the function, otherwise return
17887 If RECURSE_P is true, use mips_find_pic_call_symbol to interpret
17888 the values of source registers, otherwise treat such registers as
17889 having an unknown value. */
17892 mips_pic_call_symbol_from_set (df_ref def
, rtx reg
, bool recurse_p
)
17894 rtx_insn
*def_insn
;
17897 if (DF_REF_IS_ARTIFICIAL (def
))
17900 def_insn
= DF_REF_INSN (def
);
17901 set
= single_set (def_insn
);
17902 if (set
&& rtx_equal_p (SET_DEST (set
), reg
))
17904 rtx note
, src
, symbol
;
17906 /* First see whether the source is a plain symbol. This is used
17907 when calling symbols that are not lazily bound. */
17908 src
= SET_SRC (set
);
17909 if (GET_CODE (src
) == SYMBOL_REF
)
17912 /* Handle %call16 references. */
17913 symbol
= mips_strip_unspec_call (src
);
17916 gcc_assert (GET_CODE (symbol
) == SYMBOL_REF
);
17920 /* If we have something more complicated, look for a
17921 REG_EQUAL or REG_EQUIV note. */
17922 note
= find_reg_equal_equiv_note (def_insn
);
17923 if (note
&& GET_CODE (XEXP (note
, 0)) == SYMBOL_REF
)
17924 return XEXP (note
, 0);
17926 /* Follow at most one simple register copy. Such copies are
17927 interesting in cases like:
17931 locally_binding_fn (...);
17936 locally_binding_fn (...);
17938 locally_binding_fn (...);
17940 where the load of locally_binding_fn can legitimately be
17941 hoisted or shared. However, we do not expect to see complex
17942 chains of copies, so a full worklist solution to the problem
17943 would probably be overkill. */
17944 if (recurse_p
&& REG_P (src
))
17945 return mips_find_pic_call_symbol (def_insn
, src
, false);
17951 /* Find the definition of the use of REG in INSN. See if the definition
17952 is one of the ways we load a register with a symbol address for a
17953 mips_use_pic_fn_addr_reg_p call. If it is return the symbol reference
17954 of the function, otherwise return NULL_RTX. RECURSE_P is as for
17955 mips_pic_call_symbol_from_set. */
17958 mips_find_pic_call_symbol (rtx_insn
*insn
, rtx reg
, bool recurse_p
)
17961 struct df_link
*defs
;
17964 use
= df_find_use (insn
, regno_reg_rtx
[REGNO (reg
)]);
17967 defs
= DF_REF_CHAIN (use
);
17970 symbol
= mips_pic_call_symbol_from_set (defs
->ref
, reg
, recurse_p
);
17974 /* If we have more than one definition, they need to be identical. */
17975 for (defs
= defs
->next
; defs
; defs
= defs
->next
)
17979 other
= mips_pic_call_symbol_from_set (defs
->ref
, reg
, recurse_p
);
17980 if (!rtx_equal_p (symbol
, other
))
17987 /* Replace the args_size operand of the call expression CALL with the
17988 call-attribute UNSPEC and fill in SYMBOL as the function symbol. */
17991 mips_annotate_pic_call_expr (rtx call
, rtx symbol
)
17995 args_size
= XEXP (call
, 1);
17996 XEXP (call
, 1) = gen_rtx_UNSPEC (GET_MODE (args_size
),
17997 gen_rtvec (2, args_size
, symbol
),
18001 /* OPERANDS[ARGS_SIZE_OPNO] is the arg_size operand of a CALL expression. See
18002 if instead of the arg_size argument it contains the call attributes. If
18003 yes return true along with setting OPERANDS[ARGS_SIZE_OPNO] to the function
18004 symbol from the call attributes. Also return false if ARGS_SIZE_OPNO is
18008 mips_get_pic_call_symbol (rtx
*operands
, int args_size_opno
)
18010 rtx args_size
, symbol
;
18012 if (!TARGET_RELAX_PIC_CALLS
|| args_size_opno
== -1)
18015 args_size
= operands
[args_size_opno
];
18016 if (GET_CODE (args_size
) != UNSPEC
)
18018 gcc_assert (XINT (args_size
, 1) == UNSPEC_CALL_ATTR
);
18020 symbol
= XVECEXP (args_size
, 0, 1);
18021 gcc_assert (GET_CODE (symbol
) == SYMBOL_REF
);
18023 operands
[args_size_opno
] = symbol
;
18027 /* Use DF to annotate PIC indirect calls with the function symbol they
18031 mips_annotate_pic_calls (void)
18036 FOR_EACH_BB_FN (bb
, cfun
)
18037 FOR_BB_INSNS (bb
, insn
)
18039 rtx call
, reg
, symbol
, second_call
;
18042 call
= mips_call_expr_from_insn (insn
, &second_call
);
18045 gcc_assert (MEM_P (XEXP (call
, 0)));
18046 reg
= XEXP (XEXP (call
, 0), 0);
18050 symbol
= mips_find_pic_call_symbol (insn
, reg
, true);
18053 mips_annotate_pic_call_expr (call
, symbol
);
18055 mips_annotate_pic_call_expr (second_call
, symbol
);
18060 /* A temporary variable used by note_uses callbacks, etc. */
18061 static rtx_insn
*mips_sim_insn
;
18063 /* A structure representing the state of the processor pipeline.
18064 Used by the mips_sim_* family of functions. */
18066 /* The maximum number of instructions that can be issued in a cycle.
18067 (Caches mips_issue_rate.) */
18068 unsigned int issue_rate
;
18070 /* The current simulation time. */
18073 /* How many more instructions can be issued in the current cycle. */
18074 unsigned int insns_left
;
18076 /* LAST_SET[X].INSN is the last instruction to set register X.
18077 LAST_SET[X].TIME is the time at which that instruction was issued.
18078 INSN is null if no instruction has yet set register X. */
18082 } last_set
[FIRST_PSEUDO_REGISTER
];
18084 /* The pipeline's current DFA state. */
18088 /* Reset STATE to the initial simulation state. */
18091 mips_sim_reset (struct mips_sim
*state
)
18093 curr_state
= state
->dfa_state
;
18096 state
->insns_left
= state
->issue_rate
;
18097 memset (&state
->last_set
, 0, sizeof (state
->last_set
));
18098 state_reset (curr_state
);
18100 targetm
.sched
.init (0, false, 0);
18101 advance_state (curr_state
);
18104 /* Initialize STATE before its first use. DFA_STATE points to an
18105 allocated but uninitialized DFA state. */
18108 mips_sim_init (struct mips_sim
*state
, state_t dfa_state
)
18110 if (targetm
.sched
.init_dfa_pre_cycle_insn
)
18111 targetm
.sched
.init_dfa_pre_cycle_insn ();
18113 if (targetm
.sched
.init_dfa_post_cycle_insn
)
18114 targetm
.sched
.init_dfa_post_cycle_insn ();
18116 state
->issue_rate
= mips_issue_rate ();
18117 state
->dfa_state
= dfa_state
;
18118 mips_sim_reset (state
);
18121 /* Advance STATE by one clock cycle. */
18124 mips_sim_next_cycle (struct mips_sim
*state
)
18126 curr_state
= state
->dfa_state
;
18129 state
->insns_left
= state
->issue_rate
;
18130 advance_state (curr_state
);
18133 /* Advance simulation state STATE until instruction INSN can read
18137 mips_sim_wait_reg (struct mips_sim
*state
, rtx_insn
*insn
, rtx reg
)
18139 unsigned int regno
, end_regno
;
18141 end_regno
= END_REGNO (reg
);
18142 for (regno
= REGNO (reg
); regno
< end_regno
; regno
++)
18143 if (state
->last_set
[regno
].insn
!= 0)
18147 t
= (state
->last_set
[regno
].time
18148 + insn_latency (state
->last_set
[regno
].insn
, insn
));
18149 while (state
->time
< t
)
18150 mips_sim_next_cycle (state
);
18154 /* A note_uses callback. For each register in *X, advance simulation
18155 state DATA until mips_sim_insn can read the register's value. */
18158 mips_sim_wait_regs_1 (rtx
*x
, void *data
)
18160 subrtx_var_iterator::array_type array
;
18161 FOR_EACH_SUBRTX_VAR (iter
, array
, *x
, NONCONST
)
18163 mips_sim_wait_reg ((struct mips_sim
*) data
, mips_sim_insn
, *iter
);
18166 /* Advance simulation state STATE until all of INSN's register
18167 dependencies are satisfied. */
18170 mips_sim_wait_regs (struct mips_sim
*state
, rtx_insn
*insn
)
18172 mips_sim_insn
= insn
;
18173 note_uses (&PATTERN (insn
), mips_sim_wait_regs_1
, state
);
18176 /* Advance simulation state STATE until the units required by
18177 instruction INSN are available. */
18180 mips_sim_wait_units (struct mips_sim
*state
, rtx_insn
*insn
)
18184 tmp_state
= alloca (state_size ());
18185 while (state
->insns_left
== 0
18186 || (memcpy (tmp_state
, state
->dfa_state
, state_size ()),
18187 state_transition (tmp_state
, insn
) >= 0))
18188 mips_sim_next_cycle (state
);
18191 /* Advance simulation state STATE until INSN is ready to issue. */
18194 mips_sim_wait_insn (struct mips_sim
*state
, rtx_insn
*insn
)
18196 mips_sim_wait_regs (state
, insn
);
18197 mips_sim_wait_units (state
, insn
);
18200 /* mips_sim_insn has just set X. Update the LAST_SET array
18201 in simulation state DATA. */
18204 mips_sim_record_set (rtx x
, const_rtx pat ATTRIBUTE_UNUSED
, void *data
)
18206 struct mips_sim
*state
;
18208 state
= (struct mips_sim
*) data
;
18211 unsigned int regno
, end_regno
;
18213 end_regno
= END_REGNO (x
);
18214 for (regno
= REGNO (x
); regno
< end_regno
; regno
++)
18216 state
->last_set
[regno
].insn
= mips_sim_insn
;
18217 state
->last_set
[regno
].time
= state
->time
;
18222 /* Issue instruction INSN in scheduler state STATE. Assume that INSN
18223 can issue immediately (i.e., that mips_sim_wait_insn has already
18227 mips_sim_issue_insn (struct mips_sim
*state
, rtx_insn
*insn
)
18229 curr_state
= state
->dfa_state
;
18231 state_transition (curr_state
, insn
);
18232 state
->insns_left
= targetm
.sched
.variable_issue (0, false, insn
,
18233 state
->insns_left
);
18235 mips_sim_insn
= insn
;
18236 note_stores (PATTERN (insn
), mips_sim_record_set
, state
);
18239 /* Simulate issuing a NOP in state STATE. */
18242 mips_sim_issue_nop (struct mips_sim
*state
)
18244 if (state
->insns_left
== 0)
18245 mips_sim_next_cycle (state
);
18246 state
->insns_left
--;
18249 /* Update simulation state STATE so that it's ready to accept the instruction
18250 after INSN. INSN should be part of the main rtl chain, not a member of a
18254 mips_sim_finish_insn (struct mips_sim
*state
, rtx_insn
*insn
)
18256 /* If INSN is a jump with an implicit delay slot, simulate a nop. */
18258 mips_sim_issue_nop (state
);
18260 switch (GET_CODE (SEQ_BEGIN (insn
)))
18264 /* We can't predict the processor state after a call or label. */
18265 mips_sim_reset (state
);
18269 /* The delay slots of branch likely instructions are only executed
18270 when the branch is taken. Therefore, if the caller has simulated
18271 the delay slot instruction, STATE does not really reflect the state
18272 of the pipeline for the instruction after the delay slot. Also,
18273 branch likely instructions tend to incur a penalty when not taken,
18274 so there will probably be an extra delay between the branch and
18275 the instruction after the delay slot. */
18276 if (INSN_ANNULLED_BRANCH_P (SEQ_BEGIN (insn
)))
18277 mips_sim_reset (state
);
18285 /* Use simulator state STATE to calculate the execution time of
18286 instruction sequence SEQ. */
18288 static unsigned int
18289 mips_seq_time (struct mips_sim
*state
, rtx_insn
*seq
)
18291 mips_sim_reset (state
);
18292 for (rtx_insn
*insn
= seq
; insn
; insn
= NEXT_INSN (insn
))
18294 mips_sim_wait_insn (state
, insn
);
18295 mips_sim_issue_insn (state
, insn
);
18297 return state
->time
;
18300 /* Return the execution-time cost of mips_tuning_info.fast_mult_zero_zero_p
18301 setting SETTING, using STATE to simulate instruction sequences. */
18303 static unsigned int
18304 mips_mult_zero_zero_cost (struct mips_sim
*state
, bool setting
)
18306 mips_tuning_info
.fast_mult_zero_zero_p
= setting
;
18309 machine_mode dword_mode
= TARGET_64BIT
? TImode
: DImode
;
18310 rtx hilo
= gen_rtx_REG (dword_mode
, MD_REG_FIRST
);
18311 mips_emit_move_or_split (hilo
, const0_rtx
, SPLIT_FOR_SPEED
);
18313 /* If the target provides mulsidi3_32bit then that's the most likely
18314 consumer of the result. Test for bypasses. */
18315 if (dword_mode
== DImode
&& HAVE_maddsidi4
)
18317 rtx gpr
= gen_rtx_REG (SImode
, GP_REG_FIRST
+ 4);
18318 emit_insn (gen_maddsidi4 (hilo
, gpr
, gpr
, hilo
));
18321 unsigned int time
= mips_seq_time (state
, get_insns ());
18326 /* Check the relative speeds of "MULT $0,$0" and "MTLO $0; MTHI $0"
18327 and set up mips_tuning_info.fast_mult_zero_zero_p accordingly.
18328 Prefer MULT -- which is shorter -- in the event of a tie. */
18331 mips_set_fast_mult_zero_zero_p (struct mips_sim
*state
)
18333 if (TARGET_MIPS16
|| !ISA_HAS_HILO
)
18334 /* No MTLO or MTHI available for MIPS16. Also, when there are no HI or LO
18335 registers then there is no reason to zero them, arbitrarily choose to
18336 say that "MULT $0,$0" would be faster. */
18337 mips_tuning_info
.fast_mult_zero_zero_p
= true;
18340 unsigned int true_time
= mips_mult_zero_zero_cost (state
, true);
18341 unsigned int false_time
= mips_mult_zero_zero_cost (state
, false);
18342 mips_tuning_info
.fast_mult_zero_zero_p
= (true_time
<= false_time
);
18346 /* Set up costs based on the current architecture and tuning settings. */
18349 mips_set_tuning_info (void)
18351 if (mips_tuning_info
.initialized_p
18352 && mips_tuning_info
.arch
== mips_arch
18353 && mips_tuning_info
.tune
== mips_tune
18354 && mips_tuning_info
.mips16_p
== TARGET_MIPS16
)
18357 mips_tuning_info
.arch
= mips_arch
;
18358 mips_tuning_info
.tune
= mips_tune
;
18359 mips_tuning_info
.mips16_p
= TARGET_MIPS16
;
18360 mips_tuning_info
.initialized_p
= true;
18364 struct mips_sim state
;
18365 mips_sim_init (&state
, alloca (state_size ()));
18367 mips_set_fast_mult_zero_zero_p (&state
);
18372 /* Implement TARGET_EXPAND_TO_RTL_HOOK. */
18375 mips_expand_to_rtl_hook (void)
18377 /* We need to call this at a point where we can safely create sequences
18378 of instructions, so TARGET_OVERRIDE_OPTIONS is too early. We also
18379 need to call it at a point where the DFA infrastructure is not
18380 already in use, so we can't just call it lazily on demand.
18382 At present, mips_tuning_info is only needed during post-expand
18383 RTL passes such as split_insns, so this hook should be early enough.
18384 We may need to move the call elsewhere if mips_tuning_info starts
18385 to be used for other things (such as rtx_costs, or expanders that
18386 could be called during gimple optimization). */
18387 mips_set_tuning_info ();
18390 /* The VR4130 pipeline issues aligned pairs of instructions together,
18391 but it stalls the second instruction if it depends on the first.
18392 In order to cut down the amount of logic required, this dependence
18393 check is not based on a full instruction decode. Instead, any non-SPECIAL
18394 instruction is assumed to modify the register specified by bits 20-16
18395 (which is usually the "rt" field).
18397 In BEQ, BEQL, BNE and BNEL instructions, the rt field is actually an
18398 input, so we can end up with a false dependence between the branch
18399 and its delay slot. If this situation occurs in instruction INSN,
18400 try to avoid it by swapping rs and rt. */
18403 vr4130_avoid_branch_rt_conflict (rtx_insn
*insn
)
18405 rtx_insn
*first
, *second
;
18407 first
= SEQ_BEGIN (insn
);
18408 second
= SEQ_END (insn
);
18410 && NONJUMP_INSN_P (second
)
18411 && GET_CODE (PATTERN (first
)) == SET
18412 && GET_CODE (SET_DEST (PATTERN (first
))) == PC
18413 && GET_CODE (SET_SRC (PATTERN (first
))) == IF_THEN_ELSE
)
18415 /* Check for the right kind of condition. */
18416 rtx cond
= XEXP (SET_SRC (PATTERN (first
)), 0);
18417 if ((GET_CODE (cond
) == EQ
|| GET_CODE (cond
) == NE
)
18418 && REG_P (XEXP (cond
, 0))
18419 && REG_P (XEXP (cond
, 1))
18420 && reg_referenced_p (XEXP (cond
, 1), PATTERN (second
))
18421 && !reg_referenced_p (XEXP (cond
, 0), PATTERN (second
)))
18423 /* SECOND mentions the rt register but not the rs register. */
18424 rtx tmp
= XEXP (cond
, 0);
18425 XEXP (cond
, 0) = XEXP (cond
, 1);
18426 XEXP (cond
, 1) = tmp
;
18431 /* Implement -mvr4130-align. Go through each basic block and simulate the
18432 processor pipeline. If we find that a pair of instructions could execute
18433 in parallel, and the first of those instructions is not 8-byte aligned,
18434 insert a nop to make it aligned. */
18437 vr4130_align_insns (void)
18439 struct mips_sim state
;
18440 rtx_insn
*insn
, *subinsn
, *last
, *last2
, *next
;
18445 /* LAST is the last instruction before INSN to have a nonzero length.
18446 LAST2 is the last such instruction before LAST. */
18450 /* ALIGNED_P is true if INSN is known to be at an aligned address. */
18453 mips_sim_init (&state
, alloca (state_size ()));
18454 for (insn
= get_insns (); insn
!= 0; insn
= next
)
18456 unsigned int length
;
18458 next
= NEXT_INSN (insn
);
18460 /* See the comment above vr4130_avoid_branch_rt_conflict for details.
18461 This isn't really related to the alignment pass, but we do it on
18462 the fly to avoid a separate instruction walk. */
18463 vr4130_avoid_branch_rt_conflict (insn
);
18465 length
= get_attr_length (insn
);
18466 if (length
> 0 && USEFUL_INSN_P (insn
))
18467 FOR_EACH_SUBINSN (subinsn
, insn
)
18469 mips_sim_wait_insn (&state
, subinsn
);
18471 /* If we want this instruction to issue in parallel with the
18472 previous one, make sure that the previous instruction is
18473 aligned. There are several reasons why this isn't worthwhile
18474 when the second instruction is a call:
18476 - Calls are less likely to be performance critical,
18477 - There's a good chance that the delay slot can execute
18478 in parallel with the call.
18479 - The return address would then be unaligned.
18481 In general, if we're going to insert a nop between instructions
18482 X and Y, it's better to insert it immediately after X. That
18483 way, if the nop makes Y aligned, it will also align any labels
18484 between X and Y. */
18485 if (state
.insns_left
!= state
.issue_rate
18486 && !CALL_P (subinsn
))
18488 if (subinsn
== SEQ_BEGIN (insn
) && aligned_p
)
18490 /* SUBINSN is the first instruction in INSN and INSN is
18491 aligned. We want to align the previous instruction
18492 instead, so insert a nop between LAST2 and LAST.
18494 Note that LAST could be either a single instruction
18495 or a branch with a delay slot. In the latter case,
18496 LAST, like INSN, is already aligned, but the delay
18497 slot must have some extra delay that stops it from
18498 issuing at the same time as the branch. We therefore
18499 insert a nop before the branch in order to align its
18501 gcc_assert (last2
);
18502 emit_insn_after (gen_nop (), last2
);
18505 else if (subinsn
!= SEQ_BEGIN (insn
) && !aligned_p
)
18507 /* SUBINSN is the delay slot of INSN, but INSN is
18508 currently unaligned. Insert a nop between
18509 LAST and INSN to align it. */
18511 emit_insn_after (gen_nop (), last
);
18515 mips_sim_issue_insn (&state
, subinsn
);
18517 mips_sim_finish_insn (&state
, insn
);
18519 /* Update LAST, LAST2 and ALIGNED_P for the next instruction. */
18520 length
= get_attr_length (insn
);
18523 /* If the instruction is an asm statement or multi-instruction
18524 mips.md patern, the length is only an estimate. Insert an
18525 8 byte alignment after it so that the following instructions
18526 can be handled correctly. */
18527 if (NONJUMP_INSN_P (SEQ_BEGIN (insn
))
18528 && (recog_memoized (insn
) < 0 || length
>= 8))
18530 next
= emit_insn_after (gen_align (GEN_INT (3)), insn
);
18531 next
= NEXT_INSN (next
);
18532 mips_sim_next_cycle (&state
);
18535 else if (length
& 4)
18536 aligned_p
= !aligned_p
;
18541 /* See whether INSN is an aligned label. */
18542 if (LABEL_P (insn
) && label_to_alignment (insn
) >= 3)
18548 /* This structure records that the current function has a LO_SUM
18549 involving SYMBOL_REF or LABEL_REF BASE and that MAX_OFFSET is
18550 the largest offset applied to BASE by all such LO_SUMs. */
18551 struct mips_lo_sum_offset
{
18553 HOST_WIDE_INT offset
;
18556 /* Return a hash value for SYMBOL_REF or LABEL_REF BASE. */
18559 mips_hash_base (rtx base
)
18561 int do_not_record_p
;
18563 return hash_rtx (base
, GET_MODE (base
), &do_not_record_p
, NULL
, false);
18566 /* Hashtable helpers. */
18568 struct mips_lo_sum_offset_hasher
: free_ptr_hash
<mips_lo_sum_offset
>
18570 typedef rtx_def
*compare_type
;
18571 static inline hashval_t
hash (const mips_lo_sum_offset
*);
18572 static inline bool equal (const mips_lo_sum_offset
*, const rtx_def
*);
18575 /* Hash-table callbacks for mips_lo_sum_offsets. */
18578 mips_lo_sum_offset_hasher::hash (const mips_lo_sum_offset
*entry
)
18580 return mips_hash_base (entry
->base
);
18584 mips_lo_sum_offset_hasher::equal (const mips_lo_sum_offset
*entry
,
18585 const rtx_def
*value
)
18587 return rtx_equal_p (entry
->base
, value
);
18590 typedef hash_table
<mips_lo_sum_offset_hasher
> mips_offset_table
;
18592 /* Look up symbolic constant X in HTAB, which is a hash table of
18593 mips_lo_sum_offsets. If OPTION is NO_INSERT, return true if X can be
18594 paired with a recorded LO_SUM, otherwise record X in the table. */
18597 mips_lo_sum_offset_lookup (mips_offset_table
*htab
, rtx x
,
18598 enum insert_option option
)
18601 mips_lo_sum_offset
**slot
;
18602 struct mips_lo_sum_offset
*entry
;
18604 /* Split X into a base and offset. */
18605 split_const (x
, &base
, &offset
);
18606 if (UNSPEC_ADDRESS_P (base
))
18607 base
= UNSPEC_ADDRESS (base
);
18609 /* Look up the base in the hash table. */
18610 slot
= htab
->find_slot_with_hash (base
, mips_hash_base (base
), option
);
18614 entry
= (struct mips_lo_sum_offset
*) *slot
;
18615 if (option
== INSERT
)
18619 entry
= XNEW (struct mips_lo_sum_offset
);
18620 entry
->base
= base
;
18621 entry
->offset
= INTVAL (offset
);
18626 if (INTVAL (offset
) > entry
->offset
)
18627 entry
->offset
= INTVAL (offset
);
18630 return INTVAL (offset
) <= entry
->offset
;
18633 /* Search X for LO_SUMs and record them in HTAB. */
18636 mips_record_lo_sums (const_rtx x
, mips_offset_table
*htab
)
18638 subrtx_iterator::array_type array
;
18639 FOR_EACH_SUBRTX (iter
, array
, x
, NONCONST
)
18640 if (GET_CODE (*iter
) == LO_SUM
)
18641 mips_lo_sum_offset_lookup (htab
, XEXP (*iter
, 1), INSERT
);
18644 /* Return true if INSN is a SET of an orphaned high-part relocation.
18645 HTAB is a hash table of mips_lo_sum_offsets that describes all the
18646 LO_SUMs in the current function. */
18649 mips_orphaned_high_part_p (mips_offset_table
*htab
, rtx_insn
*insn
)
18651 enum mips_symbol_type type
;
18654 set
= single_set (insn
);
18657 /* Check for %his. */
18659 if (GET_CODE (x
) == HIGH
18660 && absolute_symbolic_operand (XEXP (x
, 0), VOIDmode
))
18661 return !mips_lo_sum_offset_lookup (htab
, XEXP (x
, 0), NO_INSERT
);
18663 /* Check for local %gots (and %got_pages, which is redundant but OK). */
18664 if (GET_CODE (x
) == UNSPEC
18665 && XINT (x
, 1) == UNSPEC_LOAD_GOT
18666 && mips_symbolic_constant_p (XVECEXP (x
, 0, 1),
18667 SYMBOL_CONTEXT_LEA
, &type
)
18668 && type
== SYMBOL_GOTOFF_PAGE
)
18669 return !mips_lo_sum_offset_lookup (htab
, XVECEXP (x
, 0, 1), NO_INSERT
);
18674 /* Subroutine of mips_avoid_hazard. We classify unconditional branches
18675 of interest for the P6600 for performance reasons. We're interested
18676 in differentiating BALC from JIC, JIALC and BC. */
18678 static enum mips_ucbranch_type
18679 mips_classify_branch_p6600 (rtx_insn
*insn
)
18681 /* We ignore sequences here as they represent a filled delay slot. */
18683 || !USEFUL_INSN_P (insn
)
18684 || GET_CODE (PATTERN (insn
)) == SEQUENCE
)
18685 return UC_UNDEFINED
;
18687 if (get_attr_jal (insn
) == JAL_INDIRECT
/* JIC and JIALC. */
18688 || get_attr_type (insn
) == TYPE_JUMP
) /* BC. */
18691 if (CALL_P (insn
) && get_attr_jal (insn
) == JAL_DIRECT
)
18694 return UC_UNDEFINED
;
18697 /* Subroutine of mips_reorg_process_insns. If there is a hazard between
18698 INSN and a previous instruction, avoid it by inserting nops after
18701 *DELAYED_REG and *HILO_DELAY describe the hazards that apply at
18702 this point. If *DELAYED_REG is non-null, INSN must wait a cycle
18703 before using the value of that register. *HILO_DELAY counts the
18704 number of instructions since the last hilo hazard (that is,
18705 the number of instructions since the last MFLO or MFHI).
18707 After inserting nops for INSN, update *DELAYED_REG and *HILO_DELAY
18708 for the next instruction.
18710 LO_REG is an rtx for the LO register, used in dependence checking. */
18713 mips_avoid_hazard (rtx_insn
*after
, rtx_insn
*insn
, int *hilo_delay
,
18714 rtx
*delayed_reg
, rtx lo_reg
, bool *fs_delay
)
18719 pattern
= PATTERN (insn
);
18721 /* Do not put the whole function in .set noreorder if it contains
18722 an asm statement. We don't know whether there will be hazards
18723 between the asm statement and the gcc-generated code. */
18724 if (GET_CODE (pattern
) == ASM_INPUT
|| asm_noperands (pattern
) >= 0)
18725 cfun
->machine
->all_noreorder_p
= false;
18727 /* Ignore zero-length instructions (barriers and the like). */
18728 ninsns
= get_attr_length (insn
) / 4;
18732 /* Work out how many nops are needed. Note that we only care about
18733 registers that are explicitly mentioned in the instruction's pattern.
18734 It doesn't matter that calls use the argument registers or that they
18735 clobber hi and lo. */
18736 if (*hilo_delay
< 2 && reg_set_p (lo_reg
, pattern
))
18737 nops
= 2 - *hilo_delay
;
18738 else if (*delayed_reg
!= 0 && reg_referenced_p (*delayed_reg
, pattern
))
18740 /* If processing a forbidden slot hazard then a NOP is required if the
18741 branch instruction was not in a sequence (as the sequence would
18742 imply it is not actually a compact branch anyway) and the current
18743 insn is not an inline asm, and can't go in a delay slot. */
18744 else if (*fs_delay
&& get_attr_can_delay (insn
) == CAN_DELAY_NO
18745 && GET_CODE (PATTERN (after
)) != SEQUENCE
18746 && GET_CODE (pattern
) != ASM_INPUT
18747 && asm_noperands (pattern
) < 0)
18749 /* The P6600's branch predictor can handle static sequences of back-to-back
18750 branches in the following cases:
18752 (1) BALC followed by any conditional compact branch
18753 (2) BALC followed by BALC
18755 Any other combinations of compact branches will incur performance
18756 penalty. Inserting a no-op only costs space as the dispatch unit will
18757 disregard the nop. */
18758 else if (TUNE_P6600
&& TARGET_CB_MAYBE
&& !optimize_size
18759 && ((mips_classify_branch_p6600 (after
) == UC_BALC
18760 && mips_classify_branch_p6600 (insn
) == UC_OTHER
)
18761 || (mips_classify_branch_p6600 (insn
) == UC_BALC
18762 && mips_classify_branch_p6600 (after
) == UC_OTHER
)))
18767 /* Insert the nops between this instruction and the previous one.
18768 Each new nop takes us further from the last hilo hazard. */
18769 *hilo_delay
+= nops
;
18771 /* Move to the next real instruction if we are inserting a NOP and this
18772 instruction is a call with debug information. The reason being that
18773 we can't separate the call from the debug info. */
18774 rtx_insn
*real_after
= after
;
18775 if (real_after
&& nops
&& CALL_P (real_after
))
18777 && (NOTE_P (NEXT_INSN (real_after
))
18778 || BARRIER_P (NEXT_INSN (real_after
))))
18779 real_after
= NEXT_INSN (real_after
);
18782 emit_insn_after (gen_hazard_nop (), real_after
);
18784 /* Set up the state for the next instruction. */
18785 *hilo_delay
+= ninsns
;
18788 if (INSN_CODE (insn
) >= 0)
18789 switch (get_attr_hazard (insn
))
18792 /* For the P6600, flag some unconditional branches as having a
18793 pseudo-forbidden slot. This will cause additional nop insertion
18794 or SEQUENCE breaking as required. This is for performance
18795 reasons not correctness. */
18799 && mips_classify_branch_p6600 (insn
) == UC_OTHER
)
18803 case HAZARD_FORBIDDEN_SLOT
:
18804 if (TARGET_CB_MAYBE
)
18813 set
= single_set (insn
);
18815 *delayed_reg
= SET_DEST (set
);
18820 /* A SEQUENCE is breakable iff the branch inside it has a compact form
18821 and the target has compact branches. */
18824 mips_breakable_sequence_p (rtx_insn
*insn
)
18826 return (insn
&& GET_CODE (PATTERN (insn
)) == SEQUENCE
18828 && get_attr_compact_form (SEQ_BEGIN (insn
)) != COMPACT_FORM_NEVER
);
18831 /* Remove a SEQUENCE and replace it with the delay slot instruction
18832 followed by the branch and return the instruction in the delay slot.
18833 Return the first of the two new instructions.
18834 Subroutine of mips_reorg_process_insns. */
18837 mips_break_sequence (rtx_insn
*insn
)
18839 rtx_insn
*before
= PREV_INSN (insn
);
18840 rtx_insn
*branch
= SEQ_BEGIN (insn
);
18841 rtx_insn
*ds
= SEQ_END (insn
);
18842 remove_insn (insn
);
18843 add_insn_after (ds
, before
, NULL
);
18844 add_insn_after (branch
, ds
, NULL
);
18848 /* Go through the instruction stream and insert nops where necessary.
18849 Also delete any high-part relocations whose partnering low parts
18850 are now all dead. See if the whole function can then be put into
18851 .set noreorder and .set nomacro. */
18854 mips_reorg_process_insns (void)
18856 rtx_insn
*insn
, *last_insn
, *subinsn
, *next_insn
;
18857 rtx lo_reg
, delayed_reg
;
18861 /* Force all instructions to be split into their final form. */
18862 split_all_insns_noflow ();
18864 /* Recalculate instruction lengths without taking nops into account. */
18865 cfun
->machine
->ignore_hazard_length_p
= true;
18866 shorten_branches (get_insns ());
18868 cfun
->machine
->all_noreorder_p
= true;
18870 /* We don't track MIPS16 PC-relative offsets closely enough to make
18871 a good job of "set .noreorder" code in MIPS16 mode. */
18873 cfun
->machine
->all_noreorder_p
= false;
18875 /* Code that doesn't use explicit relocs can't be ".set nomacro". */
18876 if (!TARGET_EXPLICIT_RELOCS
)
18877 cfun
->machine
->all_noreorder_p
= false;
18879 /* Profiled functions can't be all noreorder because the profiler
18880 support uses assembler macros. */
18882 cfun
->machine
->all_noreorder_p
= false;
18884 /* Code compiled with -mfix-vr4120, -mfix-rm7000 or -mfix-24k can't be
18885 all noreorder because we rely on the assembler to work around some
18886 errata. The R5900 too has several bugs. */
18887 if (TARGET_FIX_VR4120
18888 || TARGET_FIX_RM7000
18890 || TARGET_MIPS5900
)
18891 cfun
->machine
->all_noreorder_p
= false;
18893 /* The same is true for -mfix-vr4130 if we might generate MFLO or
18894 MFHI instructions. Note that we avoid using MFLO and MFHI if
18895 the VR4130 MACC and DMACC instructions are available instead;
18896 see the *mfhilo_{si,di}_macc patterns. */
18897 if (TARGET_FIX_VR4130
&& !ISA_HAS_MACCHI
)
18898 cfun
->machine
->all_noreorder_p
= false;
18900 mips_offset_table
htab (37);
18902 /* Make a first pass over the instructions, recording all the LO_SUMs. */
18903 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
18904 FOR_EACH_SUBINSN (subinsn
, insn
)
18905 if (USEFUL_INSN_P (subinsn
))
18907 rtx body
= PATTERN (insn
);
18908 int noperands
= asm_noperands (body
);
18909 if (noperands
>= 0)
18911 rtx
*ops
= XALLOCAVEC (rtx
, noperands
);
18912 bool *used
= XALLOCAVEC (bool, noperands
);
18913 const char *string
= decode_asm_operands (body
, ops
, NULL
, NULL
,
18915 get_referenced_operands (string
, used
, noperands
);
18916 for (int i
= 0; i
< noperands
; ++i
)
18918 mips_record_lo_sums (ops
[i
], &htab
);
18921 mips_record_lo_sums (PATTERN (subinsn
), &htab
);
18927 lo_reg
= gen_rtx_REG (SImode
, LO_REGNUM
);
18930 /* Make a second pass over the instructions. Delete orphaned
18931 high-part relocations or turn them into NOPs. Avoid hazards
18932 by inserting NOPs. */
18933 for (insn
= get_insns (); insn
!= 0; insn
= next_insn
)
18935 next_insn
= NEXT_INSN (insn
);
18936 if (USEFUL_INSN_P (insn
))
18938 if (GET_CODE (PATTERN (insn
)) == SEQUENCE
)
18940 rtx_insn
*next_active
= next_active_insn (insn
);
18941 /* Undo delay slots to avoid bubbles if the next instruction can
18942 be placed in a forbidden slot or the cost of adding an
18943 explicit NOP in a forbidden slot is OK and if the SEQUENCE is
18944 safely breakable. */
18945 if (TARGET_CB_MAYBE
18946 && mips_breakable_sequence_p (insn
)
18947 && INSN_P (SEQ_BEGIN (insn
))
18948 && INSN_P (SEQ_END (insn
))
18950 && INSN_P (next_active
)
18951 && GET_CODE (PATTERN (next_active
)) != SEQUENCE
18952 && get_attr_can_delay (next_active
) == CAN_DELAY_YES
)
18953 || !optimize_size
))
18955 /* To hide a potential pipeline bubble, if we scan backwards
18956 from the current SEQUENCE and find that there is a load
18957 of a value that is used in the CTI and there are no
18958 dependencies between the CTI and instruction in the delay
18959 slot, break the sequence so the load delay is hidden. */
18961 CLEAR_HARD_REG_SET (uses
);
18962 note_uses (&PATTERN (SEQ_BEGIN (insn
)), record_hard_reg_uses
,
18964 HARD_REG_SET delay_sets
;
18965 CLEAR_HARD_REG_SET (delay_sets
);
18966 note_stores (PATTERN (SEQ_END (insn
)), record_hard_reg_sets
,
18969 rtx_insn
*prev
= prev_active_insn (insn
);
18971 && GET_CODE (PATTERN (prev
)) == SET
18972 && MEM_P (SET_SRC (PATTERN (prev
))))
18975 CLEAR_HARD_REG_SET (sets
);
18976 note_stores (PATTERN (prev
), record_hard_reg_sets
,
18979 /* Re-order if safe. */
18980 if (!hard_reg_set_intersect_p (delay_sets
, uses
)
18981 && hard_reg_set_intersect_p (uses
, sets
))
18983 next_insn
= mips_break_sequence (insn
);
18984 /* Need to process the hazards of the newly
18985 introduced instructions. */
18990 /* If we find an orphaned high-part relocation in a delay
18991 slot then we can convert to a compact branch and get
18992 the orphaned high part deleted. */
18993 if (mips_orphaned_high_part_p (&htab
, SEQ_END (insn
)))
18995 next_insn
= mips_break_sequence (insn
);
18996 /* Need to process the hazards of the newly
18997 introduced instructions. */
19002 /* If we find an orphaned high-part relocation in a delay
19003 slot, it's easier to turn that instruction into a NOP than
19004 to delete it. The delay slot will be a NOP either way. */
19005 FOR_EACH_SUBINSN (subinsn
, insn
)
19006 if (INSN_P (subinsn
))
19008 if (mips_orphaned_high_part_p (&htab
, subinsn
))
19010 PATTERN (subinsn
) = gen_nop ();
19011 INSN_CODE (subinsn
) = CODE_FOR_nop
;
19013 mips_avoid_hazard (last_insn
, subinsn
, &hilo_delay
,
19014 &delayed_reg
, lo_reg
, &fs_delay
);
19020 /* INSN is a single instruction. Delete it if it's an
19021 orphaned high-part relocation. */
19022 if (mips_orphaned_high_part_p (&htab
, insn
))
19023 delete_insn (insn
);
19024 /* Also delete cache barriers if the last instruction
19025 was an annulled branch. INSN will not be speculatively
19027 else if (recog_memoized (insn
) == CODE_FOR_r10k_cache_barrier
19029 && JUMP_P (SEQ_BEGIN (last_insn
))
19030 && INSN_ANNULLED_BRANCH_P (SEQ_BEGIN (last_insn
)))
19031 delete_insn (insn
);
19034 mips_avoid_hazard (last_insn
, insn
, &hilo_delay
,
19035 &delayed_reg
, lo_reg
, &fs_delay
);
19036 /* When a compact branch introduces a forbidden slot hazard
19037 and the next useful instruction is a SEQUENCE of a jump
19038 and a non-nop instruction in the delay slot, remove the
19039 sequence and replace it with the delay slot instruction
19040 then the jump to clear the forbidden slot hazard.
19042 For the P6600, this optimisation solves the performance
19043 penalty associated with BALC followed by a delay slot
19044 branch. We do not set fs_delay as we do not want
19045 the full logic of a forbidden slot; the penalty exists
19046 only against branches not the full class of forbidden
19047 slot instructions. */
19049 if (fs_delay
|| (TUNE_P6600
19051 && mips_classify_branch_p6600 (insn
)
19054 /* Search onwards from the current position looking for
19055 a SEQUENCE. We are looking for pipeline hazards here
19056 and do not need to worry about labels or barriers as
19057 the optimization only undoes delay slot filling which
19058 only affects the order of the branch and its delay
19060 rtx_insn
*next
= next_active_insn (insn
);
19062 && USEFUL_INSN_P (next
)
19063 && GET_CODE (PATTERN (next
)) == SEQUENCE
19064 && mips_breakable_sequence_p (next
))
19067 next_insn
= mips_break_sequence (next
);
19068 /* Need to process the hazards of the newly
19069 introduced instructions. */
19080 /* Return true if the function has a long branch instruction. */
19083 mips_has_long_branch_p (void)
19085 rtx_insn
*insn
, *subinsn
;
19088 /* We need up-to-date instruction lengths. */
19089 shorten_branches (get_insns ());
19091 /* Look for a branch that is longer than normal. The normal length for
19092 non-MIPS16 branches is 8, because the length includes the delay slot.
19093 It is 4 for MIPS16, because MIPS16 branches are extended instructions,
19094 but they have no delay slot. */
19095 normal_length
= (TARGET_MIPS16
? 4 : 8);
19096 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
19097 FOR_EACH_SUBINSN (subinsn
, insn
)
19098 if (JUMP_P (subinsn
)
19099 && get_attr_length (subinsn
) > normal_length
19100 && (any_condjump_p (subinsn
) || any_uncondjump_p (subinsn
)))
19106 /* If we are using a GOT, but have not decided to use a global pointer yet,
19107 see whether we need one to implement long branches. Convert the ghost
19108 global-pointer instructions into real ones if so. */
19111 mips_expand_ghost_gp_insns (void)
19113 /* Quick exit if we already know that we will or won't need a
19115 if (!TARGET_USE_GOT
19116 || cfun
->machine
->global_pointer
== INVALID_REGNUM
19117 || mips_must_initialize_gp_p ())
19120 /* Run a full check for long branches. */
19121 if (!mips_has_long_branch_p ())
19124 /* We've now established that we need $gp. */
19125 cfun
->machine
->must_initialize_gp_p
= true;
19126 split_all_insns_noflow ();
19131 /* Subroutine of mips_reorg to manage passes that require DF. */
19134 mips_df_reorg (void)
19136 /* Create def-use chains. */
19137 df_set_flags (DF_EQ_NOTES
);
19138 df_chain_add_problem (DF_UD_CHAIN
);
19141 if (TARGET_RELAX_PIC_CALLS
)
19142 mips_annotate_pic_calls ();
19144 if (mips_r10k_cache_barrier
!= R10K_CACHE_BARRIER_NONE
)
19145 r10k_insert_cache_barriers ();
19147 df_finish_pass (false);
19150 /* Emit code to load LABEL_REF SRC into MIPS16 register DEST. This is
19151 called very late in mips_reorg, but the caller is required to run
19152 mips16_lay_out_constants on the result. */
19155 mips16_load_branch_target (rtx dest
, rtx src
)
19157 if (TARGET_ABICALLS
&& !TARGET_ABSOLUTE_ABICALLS
)
19161 if (mips_cfun_has_cprestore_slot_p ())
19162 mips_emit_move (dest
, mips_cprestore_slot (dest
, true));
19164 mips_emit_move (dest
, pic_offset_table_rtx
);
19165 page
= mips_unspec_address (src
, SYMBOL_GOTOFF_PAGE
);
19166 low
= mips_unspec_address (src
, SYMBOL_GOT_PAGE_OFST
);
19167 emit_insn (gen_rtx_SET (dest
,
19168 PMODE_INSN (gen_unspec_got
, (dest
, page
))));
19169 emit_insn (gen_rtx_SET (dest
, gen_rtx_LO_SUM (Pmode
, dest
, low
)));
19173 src
= mips_unspec_address (src
, SYMBOL_ABSOLUTE
);
19174 mips_emit_move (dest
, src
);
19178 /* If we're compiling a MIPS16 function, look for and split any long branches.
19179 This must be called after all other instruction modifications in
19183 mips16_split_long_branches (void)
19185 bool something_changed
;
19187 if (!TARGET_MIPS16
)
19190 /* Loop until the alignments for all targets are sufficient. */
19194 rtx_jump_insn
*jump_insn
;
19196 shorten_branches (get_insns ());
19197 something_changed
= false;
19198 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
19199 if ((jump_insn
= dyn_cast
<rtx_jump_insn
*> (insn
))
19200 && get_attr_length (jump_insn
) > 4
19201 && (any_condjump_p (jump_insn
) || any_uncondjump_p (jump_insn
)))
19203 rtx old_label
, temp
, saved_temp
;
19204 rtx_code_label
*new_label
;
19206 rtx_insn
*jump
, *jump_sequence
;
19210 /* Free up a MIPS16 register by saving it in $1. */
19211 saved_temp
= gen_rtx_REG (Pmode
, AT_REGNUM
);
19212 temp
= gen_rtx_REG (Pmode
, GP_REG_FIRST
+ 2);
19213 emit_move_insn (saved_temp
, temp
);
19215 /* Load the branch target into TEMP. */
19216 old_label
= JUMP_LABEL (jump_insn
);
19217 target
= gen_rtx_LABEL_REF (Pmode
, old_label
);
19218 mips16_load_branch_target (temp
, target
);
19220 /* Jump to the target and restore the register's
19222 jump
= emit_jump_insn (PMODE_INSN (gen_indirect_jump_and_restore
,
19223 (temp
, temp
, saved_temp
)));
19224 JUMP_LABEL (jump
) = old_label
;
19225 LABEL_NUSES (old_label
)++;
19227 /* Rewrite any symbolic references that are supposed to use
19228 a PC-relative constant pool. */
19229 mips16_lay_out_constants (false);
19231 if (simplejump_p (jump_insn
))
19232 /* We're going to replace INSN with a longer form. */
19236 /* Create a branch-around label for the original
19238 new_label
= gen_label_rtx ();
19239 emit_label (new_label
);
19242 jump_sequence
= get_insns ();
19245 emit_insn_after (jump_sequence
, jump_insn
);
19247 invert_jump (jump_insn
, new_label
, false);
19249 delete_insn (jump_insn
);
19250 something_changed
= true;
19253 while (something_changed
);
19256 /* Insert a `.insn' assembly pseudo-op after any labels followed by
19257 a MIPS16 constant pool or no insn at all. This is needed so that
19258 targets that have been optimized away are still marked as code
19259 and therefore branches that remained and point to them are known
19260 to retain the ISA mode and as such can be successfully assembled. */
19263 mips_insert_insn_pseudos (void)
19265 bool insn_pseudo_needed
= TRUE
;
19268 for (insn
= get_last_insn (); insn
!= NULL_RTX
; insn
= PREV_INSN (insn
))
19269 switch (GET_CODE (insn
))
19272 if (GET_CODE (PATTERN (insn
)) == UNSPEC_VOLATILE
19273 && XINT (PATTERN (insn
), 1) == UNSPEC_CONSTTABLE
)
19275 insn_pseudo_needed
= TRUE
;
19278 /* Fall through. */
19281 case JUMP_TABLE_DATA
:
19282 insn_pseudo_needed
= FALSE
;
19285 if (insn_pseudo_needed
)
19287 emit_insn_after (gen_insn_pseudo (), insn
);
19288 insn_pseudo_needed
= FALSE
;
19296 /* Implement TARGET_MACHINE_DEPENDENT_REORG. */
19301 /* Restore the BLOCK_FOR_INSN pointers, which are needed by DF. Also during
19302 insn splitting in mips16_lay_out_constants, DF insn info is only kept up
19303 to date if the CFG is available. */
19304 if (mips_cfg_in_reorg ())
19305 compute_bb_for_insn ();
19306 mips16_lay_out_constants (true);
19307 if (mips_cfg_in_reorg ())
19310 free_bb_for_insn ();
19314 /* We use a machine specific pass to do a second machine dependent reorg
19315 pass after delay branch scheduling. */
19317 static unsigned int
19318 mips_machine_reorg2 (void)
19320 mips_reorg_process_insns ();
19322 && TARGET_EXPLICIT_RELOCS
19324 && TARGET_VR4130_ALIGN
)
19325 vr4130_align_insns ();
19326 if (mips_expand_ghost_gp_insns ())
19327 /* The expansion could invalidate some of the VR4130 alignment
19328 optimizations, but this should be an extremely rare case anyhow. */
19329 mips_reorg_process_insns ();
19330 mips16_split_long_branches ();
19331 mips_insert_insn_pseudos ();
19337 const pass_data pass_data_mips_machine_reorg2
=
19339 RTL_PASS
, /* type */
19340 "mach2", /* name */
19341 OPTGROUP_NONE
, /* optinfo_flags */
19342 TV_MACH_DEP
, /* tv_id */
19343 0, /* properties_required */
19344 0, /* properties_provided */
19345 0, /* properties_destroyed */
19346 0, /* todo_flags_start */
19347 0, /* todo_flags_finish */
19350 class pass_mips_machine_reorg2
: public rtl_opt_pass
19353 pass_mips_machine_reorg2(gcc::context
*ctxt
)
19354 : rtl_opt_pass(pass_data_mips_machine_reorg2
, ctxt
)
19357 /* opt_pass methods: */
19358 virtual unsigned int execute (function
*) { return mips_machine_reorg2 (); }
19360 }; // class pass_mips_machine_reorg2
19362 } // anon namespace
19365 make_pass_mips_machine_reorg2 (gcc::context
*ctxt
)
19367 return new pass_mips_machine_reorg2 (ctxt
);
19371 /* Implement TARGET_ASM_OUTPUT_MI_THUNK. Generate rtl rather than asm text
19372 in order to avoid duplicating too much logic from elsewhere. */
19375 mips_output_mi_thunk (FILE *file
, tree thunk_fndecl ATTRIBUTE_UNUSED
,
19376 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
19379 rtx this_rtx
, temp1
, temp2
, fnaddr
;
19381 bool use_sibcall_p
;
19383 /* Pretend to be a post-reload pass while generating rtl. */
19384 reload_completed
= 1;
19386 /* Mark the end of the (empty) prologue. */
19387 emit_note (NOTE_INSN_PROLOGUE_END
);
19389 /* Determine if we can use a sibcall to call FUNCTION directly. */
19390 fnaddr
= XEXP (DECL_RTL (function
), 0);
19391 use_sibcall_p
= (mips_function_ok_for_sibcall (function
, NULL
)
19392 && const_call_insn_operand (fnaddr
, Pmode
));
19394 /* Determine if we need to load FNADDR from the GOT. */
19396 && (mips_got_symbol_type_p
19397 (mips_classify_symbol (fnaddr
, SYMBOL_CONTEXT_LEA
))))
19399 /* Pick a global pointer. Use a call-clobbered register if
19400 TARGET_CALL_SAVED_GP. */
19401 cfun
->machine
->global_pointer
19402 = TARGET_CALL_SAVED_GP
? 15 : GLOBAL_POINTER_REGNUM
;
19403 cfun
->machine
->must_initialize_gp_p
= true;
19404 SET_REGNO (pic_offset_table_rtx
, cfun
->machine
->global_pointer
);
19406 /* Set up the global pointer for n32 or n64 abicalls. */
19407 mips_emit_loadgp ();
19410 /* We need two temporary registers in some cases. */
19411 temp1
= gen_rtx_REG (Pmode
, 2);
19412 temp2
= gen_rtx_REG (Pmode
, 3);
19414 /* Find out which register contains the "this" pointer. */
19415 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
19416 this_rtx
= gen_rtx_REG (Pmode
, GP_ARG_FIRST
+ 1);
19418 this_rtx
= gen_rtx_REG (Pmode
, GP_ARG_FIRST
);
19420 /* Add DELTA to THIS_RTX. */
19423 rtx offset
= GEN_INT (delta
);
19424 if (!SMALL_OPERAND (delta
))
19426 mips_emit_move (temp1
, offset
);
19429 emit_insn (gen_add3_insn (this_rtx
, this_rtx
, offset
));
19432 /* If needed, add *(*THIS_RTX + VCALL_OFFSET) to THIS_RTX. */
19433 if (vcall_offset
!= 0)
19437 /* Set TEMP1 to *THIS_RTX. */
19438 mips_emit_move (temp1
, gen_rtx_MEM (Pmode
, this_rtx
));
19440 /* Set ADDR to a legitimate address for *THIS_RTX + VCALL_OFFSET. */
19441 addr
= mips_add_offset (temp2
, temp1
, vcall_offset
);
19443 /* Load the offset and add it to THIS_RTX. */
19444 mips_emit_move (temp1
, gen_rtx_MEM (Pmode
, addr
));
19445 emit_insn (gen_add3_insn (this_rtx
, this_rtx
, temp1
));
19448 /* Jump to the target function. Use a sibcall if direct jumps are
19449 allowed, otherwise load the address into a register first. */
19452 insn
= emit_call_insn (gen_sibcall_internal (fnaddr
, const0_rtx
));
19453 SIBLING_CALL_P (insn
) = 1;
19457 /* This is messy. GAS treats "la $25,foo" as part of a call
19458 sequence and may allow a global "foo" to be lazily bound.
19459 The general move patterns therefore reject this combination.
19461 In this context, lazy binding would actually be OK
19462 for TARGET_CALL_CLOBBERED_GP, but it's still wrong for
19463 TARGET_CALL_SAVED_GP; see mips_load_call_address.
19464 We must therefore load the address via a temporary
19465 register if mips_dangerous_for_la25_p.
19467 If we jump to the temporary register rather than $25,
19468 the assembler can use the move insn to fill the jump's
19471 We can use the same technique for MIPS16 code, where $25
19472 is not a valid JR register. */
19473 if (TARGET_USE_PIC_FN_ADDR_REG
19475 && !mips_dangerous_for_la25_p (fnaddr
))
19476 temp1
= gen_rtx_REG (Pmode
, PIC_FUNCTION_ADDR_REGNUM
);
19477 mips_load_call_address (MIPS_CALL_SIBCALL
, temp1
, fnaddr
);
19479 if (TARGET_USE_PIC_FN_ADDR_REG
19480 && REGNO (temp1
) != PIC_FUNCTION_ADDR_REGNUM
)
19481 mips_emit_move (gen_rtx_REG (Pmode
, PIC_FUNCTION_ADDR_REGNUM
), temp1
);
19482 emit_jump_insn (gen_indirect_jump (temp1
));
19485 /* Run just enough of rest_of_compilation. This sequence was
19486 "borrowed" from alpha.c. */
19487 insn
= get_insns ();
19488 split_all_insns_noflow ();
19489 mips16_lay_out_constants (true);
19490 shorten_branches (insn
);
19491 final_start_function (insn
, file
, 1);
19492 final (insn
, file
, 1);
19493 final_end_function ();
19495 /* Clean up the vars set above. Note that final_end_function resets
19496 the global pointer for us. */
19497 reload_completed
= 0;
19501 /* The last argument passed to mips_set_compression_mode,
19502 or negative if the function hasn't been called yet. */
19503 static unsigned int old_compression_mode
= -1;
19505 /* Set up the target-dependent global state for ISA mode COMPRESSION_MODE,
19506 which is either MASK_MIPS16 or MASK_MICROMIPS. */
19509 mips_set_compression_mode (unsigned int compression_mode
)
19512 if (compression_mode
== old_compression_mode
)
19515 /* Restore base settings of various flags. */
19516 target_flags
= mips_base_target_flags
;
19517 flag_schedule_insns
= mips_base_schedule_insns
;
19518 flag_reorder_blocks_and_partition
= mips_base_reorder_blocks_and_partition
;
19519 flag_move_loop_invariants
= mips_base_move_loop_invariants
;
19520 str_align_loops
= mips_base_align_loops
;
19521 str_align_jumps
= mips_base_align_jumps
;
19522 str_align_functions
= mips_base_align_functions
;
19523 target_flags
&= ~(MASK_MIPS16
| MASK_MICROMIPS
);
19524 target_flags
|= compression_mode
;
19526 if (compression_mode
& MASK_MIPS16
)
19528 /* Switch to MIPS16 mode. */
19529 target_flags
|= MASK_MIPS16
;
19531 /* Turn off SYNCI if it was on, MIPS16 doesn't support it. */
19532 target_flags
&= ~MASK_SYNCI
;
19534 /* Don't run the scheduler before reload, since it tends to
19535 increase register pressure. */
19536 flag_schedule_insns
= 0;
19538 /* Don't do hot/cold partitioning. mips16_lay_out_constants expects
19539 the whole function to be in a single section. */
19540 flag_reorder_blocks_and_partition
= 0;
19542 /* Don't move loop invariants, because it tends to increase
19543 register pressure. It also introduces an extra move in cases
19544 where the constant is the first operand in a two-operand binary
19545 instruction, or when it forms a register argument to a functon
19547 flag_move_loop_invariants
= 0;
19549 target_flags
|= MASK_EXPLICIT_RELOCS
;
19551 /* Experiments suggest we get the best overall section-anchor
19552 results from using the range of an unextended LW or SW. Code
19553 that makes heavy use of byte or short accesses can do better
19554 with ranges of 0...31 and 0...63 respectively, but most code is
19555 sensitive to the range of LW and SW instead. */
19556 targetm
.min_anchor_offset
= 0;
19557 targetm
.max_anchor_offset
= 127;
19559 targetm
.const_anchor
= 0;
19561 /* MIPS16 has no BAL instruction. */
19562 target_flags
&= ~MASK_RELAX_PIC_CALLS
;
19564 /* The R4000 errata don't apply to any known MIPS16 cores.
19565 It's simpler to make the R4000 fixes and MIPS16 mode
19566 mutually exclusive. */
19567 target_flags
&= ~MASK_FIX_R4000
;
19569 if (flag_pic
&& !TARGET_OLDABI
)
19570 sorry ("MIPS16 PIC for ABIs other than o32 and o64");
19573 sorry ("MIPS16 -mxgot code");
19575 if (TARGET_HARD_FLOAT_ABI
&& !TARGET_OLDABI
)
19576 sorry ("hard-float MIPS16 code for ABIs other than o32 and o64");
19579 sorry ("MSA MIPS16 code");
19583 /* Switch to microMIPS or the standard encoding. */
19585 if (TARGET_MICROMIPS
)
19586 /* Avoid branch likely. */
19587 target_flags
&= ~MASK_BRANCHLIKELY
;
19589 /* Provide default values for align_* for 64-bit targets. */
19592 if (flag_align_loops
&& !str_align_loops
)
19593 str_align_loops
= "8";
19594 if (flag_align_jumps
&& !str_align_jumps
)
19595 str_align_jumps
= "8";
19596 if (flag_align_functions
&& !str_align_functions
)
19597 str_align_functions
= "8";
19600 targetm
.min_anchor_offset
= -32768;
19601 targetm
.max_anchor_offset
= 32767;
19603 targetm
.const_anchor
= 0x8000;
19606 /* (Re)initialize MIPS target internals for new ISA. */
19607 mips_init_relocs ();
19609 if (compression_mode
& MASK_MIPS16
)
19611 if (!mips16_globals
)
19612 mips16_globals
= save_target_globals_default_opts ();
19614 restore_target_globals (mips16_globals
);
19616 else if (compression_mode
& MASK_MICROMIPS
)
19618 if (!micromips_globals
)
19619 micromips_globals
= save_target_globals_default_opts ();
19621 restore_target_globals (micromips_globals
);
19624 restore_target_globals (&default_target_globals
);
19626 old_compression_mode
= compression_mode
;
19629 /* Implement TARGET_SET_CURRENT_FUNCTION. Decide whether the current
19630 function should use the MIPS16 or microMIPS ISA and switch modes
19634 mips_set_current_function (tree fndecl
)
19636 mips_set_compression_mode (mips_get_compress_mode (fndecl
));
19639 /* Allocate a chunk of memory for per-function machine-dependent data. */
19641 static struct machine_function
*
19642 mips_init_machine_status (void)
19644 return ggc_cleared_alloc
<machine_function
> ();
19647 /* Return the processor associated with the given ISA level, or null
19648 if the ISA isn't valid. */
19650 static const struct mips_cpu_info
*
19651 mips_cpu_info_from_isa (int isa
)
19655 for (i
= 0; i
< ARRAY_SIZE (mips_cpu_info_table
); i
++)
19656 if (mips_cpu_info_table
[i
].isa
== isa
)
19657 return mips_cpu_info_table
+ i
;
19662 /* Return a mips_cpu_info entry determined by an option valued
19665 static const struct mips_cpu_info
*
19666 mips_cpu_info_from_opt (int opt
)
19670 case MIPS_ARCH_OPTION_FROM_ABI
:
19671 /* 'from-abi' selects the most compatible architecture for the
19672 given ABI: MIPS I for 32-bit ABIs and MIPS III for 64-bit
19673 ABIs. For the EABIs, we have to decide whether we're using
19674 the 32-bit or 64-bit version. */
19675 return mips_cpu_info_from_isa (ABI_NEEDS_32BIT_REGS
? 1
19676 : ABI_NEEDS_64BIT_REGS
? 3
19677 : (TARGET_64BIT
? 3 : 1));
19679 case MIPS_ARCH_OPTION_NATIVE
:
19680 gcc_unreachable ();
19683 return &mips_cpu_info_table
[opt
];
19687 /* Return a default mips_cpu_info entry, given that no -march= option
19688 was explicitly specified. */
19690 static const struct mips_cpu_info
*
19691 mips_default_arch (void)
19693 #if defined (MIPS_CPU_STRING_DEFAULT)
19695 for (i
= 0; i
< ARRAY_SIZE (mips_cpu_info_table
); i
++)
19696 if (strcmp (mips_cpu_info_table
[i
].name
, MIPS_CPU_STRING_DEFAULT
) == 0)
19697 return mips_cpu_info_table
+ i
;
19698 gcc_unreachable ();
19699 #elif defined (MIPS_ISA_DEFAULT)
19700 return mips_cpu_info_from_isa (MIPS_ISA_DEFAULT
);
19702 /* 'from-abi' makes a good default: you get whatever the ABI
19704 return mips_cpu_info_from_opt (MIPS_ARCH_OPTION_FROM_ABI
);
19708 /* Set up globals to generate code for the ISA or processor
19709 described by INFO. */
19712 mips_set_architecture (const struct mips_cpu_info
*info
)
19716 mips_arch_info
= info
;
19717 mips_arch
= info
->cpu
;
19718 mips_isa
= info
->isa
;
19722 mips_isa_rev
= (mips_isa
& 31) + 1;
19726 /* Likewise for tuning. */
19729 mips_set_tune (const struct mips_cpu_info
*info
)
19733 mips_tune_info
= info
;
19734 mips_tune
= info
->cpu
;
19738 /* Implement TARGET_OPTION_OVERRIDE. */
19741 mips_option_override (void)
19743 int i
, start
, regno
, mode
;
19745 if (global_options_set
.x_mips_isa_option
)
19746 mips_isa_option_info
= &mips_cpu_info_table
[mips_isa_option
];
19748 #ifdef SUBTARGET_OVERRIDE_OPTIONS
19749 SUBTARGET_OVERRIDE_OPTIONS
;
19752 /* MIPS16 and microMIPS cannot coexist. */
19753 if (TARGET_MICROMIPS
&& TARGET_MIPS16
)
19754 error ("unsupported combination: %s", "-mips16 -mmicromips");
19756 /* Prohibit Paired-Single and MSA combination. This is software restriction
19757 rather than architectural. */
19758 if (ISA_HAS_MSA
&& TARGET_PAIRED_SINGLE_FLOAT
)
19759 error ("unsupported combination: %s", "-mmsa -mpaired-single");
19761 /* Save the base compression state and process flags as though we
19762 were generating uncompressed code. */
19763 mips_base_compression_flags
= TARGET_COMPRESSION
;
19764 target_flags
&= ~TARGET_COMPRESSION
;
19766 /* -mno-float overrides -mhard-float and -msoft-float. */
19767 if (TARGET_NO_FLOAT
)
19769 target_flags
|= MASK_SOFT_FLOAT_ABI
;
19770 target_flags_explicit
|= MASK_SOFT_FLOAT_ABI
;
19773 if (TARGET_FLIP_MIPS16
)
19774 TARGET_INTERLINK_COMPRESSED
= 1;
19776 /* Set the small data limit. */
19777 mips_small_data_threshold
= (global_options_set
.x_g_switch_value
19779 : MIPS_DEFAULT_GVALUE
);
19781 /* The following code determines the architecture and register size.
19782 Similar code was added to GAS 2.14 (see tc-mips.c:md_after_parse_args()).
19783 The GAS and GCC code should be kept in sync as much as possible. */
19785 if (global_options_set
.x_mips_arch_option
)
19786 mips_set_architecture (mips_cpu_info_from_opt (mips_arch_option
));
19788 if (mips_isa_option_info
!= 0)
19790 if (mips_arch_info
== 0)
19791 mips_set_architecture (mips_isa_option_info
);
19792 else if (mips_arch_info
->isa
!= mips_isa_option_info
->isa
)
19793 error ("%<-%s%> conflicts with the other architecture options, "
19794 "which specify a %s processor",
19795 mips_isa_option_info
->name
,
19796 mips_cpu_info_from_isa (mips_arch_info
->isa
)->name
);
19799 if (mips_arch_info
== 0)
19800 mips_set_architecture (mips_default_arch ());
19802 if (ABI_NEEDS_64BIT_REGS
&& !ISA_HAS_64BIT_REGS
)
19803 error ("%<-march=%s%> is not compatible with the selected ABI",
19804 mips_arch_info
->name
);
19806 /* Optimize for mips_arch, unless -mtune selects a different processor. */
19807 if (global_options_set
.x_mips_tune_option
)
19808 mips_set_tune (mips_cpu_info_from_opt (mips_tune_option
));
19810 if (mips_tune_info
== 0)
19811 mips_set_tune (mips_arch_info
);
19813 if ((target_flags_explicit
& MASK_64BIT
) != 0)
19815 /* The user specified the size of the integer registers. Make sure
19816 it agrees with the ABI and ISA. */
19817 if (TARGET_64BIT
&& !ISA_HAS_64BIT_REGS
)
19818 error ("%<-mgp64%> used with a 32-bit processor");
19819 else if (!TARGET_64BIT
&& ABI_NEEDS_64BIT_REGS
)
19820 error ("%<-mgp32%> used with a 64-bit ABI");
19821 else if (TARGET_64BIT
&& ABI_NEEDS_32BIT_REGS
)
19822 error ("%<-mgp64%> used with a 32-bit ABI");
19826 /* Infer the integer register size from the ABI and processor.
19827 Restrict ourselves to 32-bit registers if that's all the
19828 processor has, or if the ABI cannot handle 64-bit registers. */
19829 if (ABI_NEEDS_32BIT_REGS
|| !ISA_HAS_64BIT_REGS
)
19830 target_flags
&= ~MASK_64BIT
;
19832 target_flags
|= MASK_64BIT
;
19835 if ((target_flags_explicit
& MASK_FLOAT64
) != 0)
19837 if (mips_isa_rev
>= 6 && !TARGET_FLOAT64
)
19838 error ("the %qs architecture does not support %<-mfp32%>",
19839 mips_arch_info
->name
);
19840 else if (TARGET_SINGLE_FLOAT
&& TARGET_FLOAT64
)
19841 error ("unsupported combination: %s", "-mfp64 -msingle-float");
19842 else if (TARGET_64BIT
&& TARGET_DOUBLE_FLOAT
&& !TARGET_FLOAT64
)
19843 error ("unsupported combination: %s", "-mgp64 -mfp32 -mdouble-float");
19844 else if (!TARGET_64BIT
&& TARGET_FLOAT64
)
19846 if (!ISA_HAS_MXHC1
)
19847 error ("%<-mgp32%> and %<-mfp64%> can only be combined if"
19848 " the target supports the mfhc1 and mthc1 instructions");
19849 else if (mips_abi
!= ABI_32
)
19850 error ("%<-mgp32%> and %<-mfp64%> can only be combined when using"
19856 /* -msingle-float selects 32-bit float registers. On r6 and later,
19857 -mdouble-float selects 64-bit float registers, since the old paired
19858 register model is not supported. In other cases the float registers
19859 should be the same size as the integer ones. */
19860 if (mips_isa_rev
>= 6 && TARGET_DOUBLE_FLOAT
&& !TARGET_FLOATXX
)
19861 target_flags
|= MASK_FLOAT64
;
19862 else if (TARGET_64BIT
&& TARGET_DOUBLE_FLOAT
)
19863 target_flags
|= MASK_FLOAT64
;
19864 else if (mips_abi
== ABI_32
&& ISA_HAS_MSA
&& !TARGET_FLOATXX
)
19865 target_flags
|= MASK_FLOAT64
;
19867 target_flags
&= ~MASK_FLOAT64
;
19870 if (mips_abi
!= ABI_32
&& TARGET_FLOATXX
)
19871 error ("%<-mfpxx%> can only be used with the o32 ABI");
19872 else if (TARGET_FLOAT64
&& TARGET_FLOATXX
)
19873 error ("unsupported combination: %s", "-mfp64 -mfpxx");
19874 else if (ISA_MIPS1
&& !TARGET_FLOAT32
)
19875 error ("%<-march=%s%> requires %<-mfp32%>", mips_arch_info
->name
);
19876 else if (TARGET_FLOATXX
&& !mips_lra_flag
)
19877 error ("%<-mfpxx%> requires %<-mlra%>");
19879 /* End of code shared with GAS. */
19881 /* The R5900 FPU only supports single precision. */
19882 if (TARGET_MIPS5900
&& TARGET_HARD_FLOAT_ABI
&& TARGET_DOUBLE_FLOAT
)
19883 error ("unsupported combination: %s",
19884 "-march=r5900 -mhard-float -mdouble-float");
19886 /* If a -mlong* option was given, check that it matches the ABI,
19887 otherwise infer the -mlong* setting from the other options. */
19888 if ((target_flags_explicit
& MASK_LONG64
) != 0)
19892 if (mips_abi
== ABI_N32
)
19893 error ("%qs is incompatible with %qs", "-mabi=n32", "-mlong64");
19894 else if (mips_abi
== ABI_32
)
19895 error ("%qs is incompatible with %qs", "-mabi=32", "-mlong64");
19896 else if (mips_abi
== ABI_O64
&& TARGET_ABICALLS
)
19897 /* We have traditionally allowed non-abicalls code to use
19898 an LP64 form of o64. However, it would take a bit more
19899 effort to support the combination of 32-bit GOT entries
19900 and 64-bit pointers, so we treat the abicalls case as
19902 error ("the combination of %qs and %qs is incompatible with %qs",
19903 "-mabi=o64", "-mabicalls", "-mlong64");
19907 if (mips_abi
== ABI_64
)
19908 error ("%qs is incompatible with %qs", "-mabi=64", "-mlong32");
19913 if ((mips_abi
== ABI_EABI
&& TARGET_64BIT
) || mips_abi
== ABI_64
)
19914 target_flags
|= MASK_LONG64
;
19916 target_flags
&= ~MASK_LONG64
;
19919 if (!TARGET_OLDABI
)
19920 flag_pcc_struct_return
= 0;
19922 /* Decide which rtx_costs structure to use. */
19924 mips_cost
= &mips_rtx_cost_optimize_size
;
19926 mips_cost
= &mips_rtx_cost_data
[mips_tune
];
19928 /* If the user hasn't specified a branch cost, use the processor's
19930 if (mips_branch_cost
== 0)
19931 mips_branch_cost
= mips_cost
->branch_cost
;
19933 /* If neither -mbranch-likely nor -mno-branch-likely was given
19934 on the command line, set MASK_BRANCHLIKELY based on the target
19935 architecture and tuning flags. Annulled delay slots are a
19936 size win, so we only consider the processor-specific tuning
19937 for !optimize_size. */
19938 if ((target_flags_explicit
& MASK_BRANCHLIKELY
) == 0)
19940 if (ISA_HAS_BRANCHLIKELY
19942 && (mips_tune_info
->tune_flags
19943 & PTF_AVOID_BRANCHLIKELY_SIZE
) == 0)
19946 && (mips_tune_info
->tune_flags
19947 & PTF_AVOID_BRANCHLIKELY_SPEED
) == 0)
19948 || (mips_tune_info
->tune_flags
19949 & PTF_AVOID_BRANCHLIKELY_ALWAYS
) == 0))
19950 target_flags
|= MASK_BRANCHLIKELY
;
19952 target_flags
&= ~MASK_BRANCHLIKELY
;
19954 else if (TARGET_BRANCHLIKELY
&& !ISA_HAS_BRANCHLIKELY
)
19955 warning (0, "the %qs architecture does not support branch-likely"
19956 " instructions", mips_arch_info
->name
);
19958 /* If the user hasn't specified -mimadd or -mno-imadd set
19959 MASK_IMADD based on the target architecture and tuning
19961 if ((target_flags_explicit
& MASK_IMADD
) == 0)
19963 if (ISA_HAS_MADD_MSUB
&&
19964 (mips_tune_info
->tune_flags
& PTF_AVOID_IMADD
) == 0)
19965 target_flags
|= MASK_IMADD
;
19967 target_flags
&= ~MASK_IMADD
;
19969 else if (TARGET_IMADD
&& !ISA_HAS_MADD_MSUB
)
19970 warning (0, "the %qs architecture does not support madd or msub"
19971 " instructions", mips_arch_info
->name
);
19973 /* If neither -modd-spreg nor -mno-odd-spreg was given on the command
19974 line, set MASK_ODD_SPREG based on the ISA and ABI. */
19975 if ((target_flags_explicit
& MASK_ODD_SPREG
) == 0)
19977 /* Disable TARGET_ODD_SPREG when using the o32 FPXX ABI. */
19978 if (!ISA_HAS_ODD_SPREG
|| TARGET_FLOATXX
)
19979 target_flags
&= ~MASK_ODD_SPREG
;
19981 target_flags
|= MASK_ODD_SPREG
;
19983 else if (TARGET_ODD_SPREG
&& !ISA_HAS_ODD_SPREG
)
19984 warning (0, "the %qs architecture does not support odd single-precision"
19985 " registers", mips_arch_info
->name
);
19987 if (!TARGET_ODD_SPREG
&& TARGET_64BIT
)
19989 error ("unsupported combination: %s", "-mgp64 -mno-odd-spreg");
19990 /* Allow compilation to continue further even though invalid output
19991 will be produced. */
19992 target_flags
|= MASK_ODD_SPREG
;
19995 if (!ISA_HAS_COMPACT_BRANCHES
&& mips_cb
== MIPS_CB_ALWAYS
)
19997 error ("unsupported combination: %qs%s %s",
19998 mips_arch_info
->name
, TARGET_MICROMIPS
? " -mmicromips" : "",
19999 "-mcompact-branches=always");
20001 else if (!ISA_HAS_DELAY_SLOTS
&& mips_cb
== MIPS_CB_NEVER
)
20003 error ("unsupported combination: %qs%s %s",
20004 mips_arch_info
->name
, TARGET_MICROMIPS
? " -mmicromips" : "",
20005 "-mcompact-branches=never");
20008 /* Require explicit relocs for MIPS R6 onwards. This enables simplification
20009 of the compact branch and jump support through the backend. */
20010 if (!TARGET_EXPLICIT_RELOCS
&& mips_isa_rev
>= 6)
20012 error ("unsupported combination: %qs %s",
20013 mips_arch_info
->name
, "-mno-explicit-relocs");
20016 /* The effect of -mabicalls isn't defined for the EABI. */
20017 if (mips_abi
== ABI_EABI
&& TARGET_ABICALLS
)
20019 error ("unsupported combination: %s", "-mabicalls -mabi=eabi");
20020 target_flags
&= ~MASK_ABICALLS
;
20023 /* PIC requires -mabicalls. */
20026 if (mips_abi
== ABI_EABI
)
20027 error ("cannot generate position-independent code for %qs",
20029 else if (!TARGET_ABICALLS
)
20030 error ("position-independent code requires %qs", "-mabicalls");
20033 if (TARGET_ABICALLS_PIC2
)
20034 /* We need to set flag_pic for executables as well as DSOs
20035 because we may reference symbols that are not defined in
20036 the final executable. (MIPS does not use things like
20037 copy relocs, for example.)
20039 There is a body of code that uses __PIC__ to distinguish
20040 between -mabicalls and -mno-abicalls code. The non-__PIC__
20041 variant is usually appropriate for TARGET_ABICALLS_PIC0, as
20042 long as any indirect jumps use $25. */
20045 /* -mvr4130-align is a "speed over size" optimization: it usually produces
20046 faster code, but at the expense of more nops. Enable it at -O3 and
20048 if (optimize
> 2 && (target_flags_explicit
& MASK_VR4130_ALIGN
) == 0)
20049 target_flags
|= MASK_VR4130_ALIGN
;
20051 /* Prefer a call to memcpy over inline code when optimizing for size,
20052 though see MOVE_RATIO in mips.h. */
20053 if (optimize_size
&& (target_flags_explicit
& MASK_MEMCPY
) == 0)
20054 target_flags
|= MASK_MEMCPY
;
20056 /* If we have a nonzero small-data limit, check that the -mgpopt
20057 setting is consistent with the other target flags. */
20058 if (mips_small_data_threshold
> 0)
20062 if (!TARGET_EXPLICIT_RELOCS
)
20063 error ("%<-mno-gpopt%> needs %<-mexplicit-relocs%>");
20065 TARGET_LOCAL_SDATA
= false;
20066 TARGET_EXTERN_SDATA
= false;
20070 if (TARGET_VXWORKS_RTP
)
20071 warning (0, "cannot use small-data accesses for %qs", "-mrtp");
20073 if (TARGET_ABICALLS
)
20074 warning (0, "cannot use small-data accesses for %qs",
20079 /* Set NaN and ABS defaults. */
20080 if (mips_nan
== MIPS_IEEE_754_DEFAULT
&& !ISA_HAS_IEEE_754_LEGACY
)
20081 mips_nan
= MIPS_IEEE_754_2008
;
20082 if (mips_abs
== MIPS_IEEE_754_DEFAULT
&& !ISA_HAS_IEEE_754_LEGACY
)
20083 mips_abs
= MIPS_IEEE_754_2008
;
20085 /* Check for IEEE 754 legacy/2008 support. */
20086 if ((mips_nan
== MIPS_IEEE_754_LEGACY
20087 || mips_abs
== MIPS_IEEE_754_LEGACY
)
20088 && !ISA_HAS_IEEE_754_LEGACY
)
20089 warning (0, "the %qs architecture does not support %<-m%s=legacy%>",
20090 mips_arch_info
->name
,
20091 mips_nan
== MIPS_IEEE_754_LEGACY
? "nan" : "abs");
20093 if ((mips_nan
== MIPS_IEEE_754_2008
20094 || mips_abs
== MIPS_IEEE_754_2008
)
20095 && !ISA_HAS_IEEE_754_2008
)
20096 warning (0, "the %qs architecture does not support %<-m%s=2008%>",
20097 mips_arch_info
->name
,
20098 mips_nan
== MIPS_IEEE_754_2008
? "nan" : "abs");
20100 /* Pre-IEEE 754-2008 MIPS hardware has a quirky almost-IEEE format
20101 for all its floating point. */
20102 if (mips_nan
!= MIPS_IEEE_754_2008
)
20104 REAL_MODE_FORMAT (SFmode
) = &mips_single_format
;
20105 REAL_MODE_FORMAT (DFmode
) = &mips_double_format
;
20106 REAL_MODE_FORMAT (TFmode
) = &mips_quad_format
;
20109 /* Make sure that the user didn't turn off paired single support when
20110 MIPS-3D support is requested. */
20112 && (target_flags_explicit
& MASK_PAIRED_SINGLE_FLOAT
)
20113 && !TARGET_PAIRED_SINGLE_FLOAT
)
20114 error ("%<-mips3d%> requires %<-mpaired-single%>");
20116 /* If TARGET_MIPS3D, enable MASK_PAIRED_SINGLE_FLOAT. */
20118 target_flags
|= MASK_PAIRED_SINGLE_FLOAT
;
20120 /* Make sure that when TARGET_PAIRED_SINGLE_FLOAT is true, TARGET_FLOAT64
20121 and TARGET_HARD_FLOAT_ABI are both true. */
20122 if (TARGET_PAIRED_SINGLE_FLOAT
&& !(TARGET_FLOAT64
&& TARGET_HARD_FLOAT_ABI
))
20124 error ("%qs must be used with %qs",
20125 TARGET_MIPS3D
? "-mips3d" : "-mpaired-single",
20126 TARGET_HARD_FLOAT_ABI
? "-mfp64" : "-mhard-float");
20127 target_flags
&= ~MASK_PAIRED_SINGLE_FLOAT
;
20131 /* Make sure that when ISA_HAS_MSA is true, TARGET_FLOAT64 and
20132 TARGET_HARD_FLOAT_ABI and both true. */
20133 if (ISA_HAS_MSA
&& !(TARGET_FLOAT64
&& TARGET_HARD_FLOAT_ABI
))
20134 error ("%<-mmsa%> must be used with %<-mfp64%> and %<-mhard-float%>");
20136 /* Make sure that -mpaired-single is only used on ISAs that support it.
20137 We must disable it otherwise since it relies on other ISA properties
20138 like ISA_HAS_8CC having their normal values. */
20139 if (TARGET_PAIRED_SINGLE_FLOAT
&& !ISA_HAS_PAIRED_SINGLE
)
20141 error ("the %qs architecture does not support paired-single"
20142 " instructions", mips_arch_info
->name
);
20143 target_flags
&= ~MASK_PAIRED_SINGLE_FLOAT
;
20147 if (mips_r10k_cache_barrier
!= R10K_CACHE_BARRIER_NONE
20148 && !TARGET_CACHE_BUILTIN
)
20150 error ("%qs requires a target that provides the %qs instruction",
20151 "-mr10k-cache-barrier", "cache");
20152 mips_r10k_cache_barrier
= R10K_CACHE_BARRIER_NONE
;
20155 /* If TARGET_DSPR2, enable TARGET_DSP. */
20159 if (TARGET_DSP
&& mips_isa_rev
>= 6)
20161 error ("the %qs architecture does not support DSP instructions",
20162 mips_arch_info
->name
);
20163 TARGET_DSP
= false;
20164 TARGET_DSPR2
= false;
20167 /* .eh_frame addresses should be the same width as a C pointer.
20168 Most MIPS ABIs support only one pointer size, so the assembler
20169 will usually know exactly how big an .eh_frame address is.
20171 Unfortunately, this is not true of the 64-bit EABI. The ABI was
20172 originally defined to use 64-bit pointers (i.e. it is LP64), and
20173 this is still the default mode. However, we also support an n32-like
20174 ILP32 mode, which is selected by -mlong32. The problem is that the
20175 assembler has traditionally not had an -mlong option, so it has
20176 traditionally not known whether we're using the ILP32 or LP64 form.
20178 As it happens, gas versions up to and including 2.19 use _32-bit_
20179 addresses for EABI64 .cfi_* directives. This is wrong for the
20180 default LP64 mode, so we can't use the directives by default.
20181 Moreover, since gas's current behavior is at odds with gcc's
20182 default behavior, it seems unwise to rely on future versions
20183 of gas behaving the same way. We therefore avoid using .cfi
20184 directives for -mlong32 as well. */
20185 if (mips_abi
== ABI_EABI
&& TARGET_64BIT
)
20186 flag_dwarf2_cfi_asm
= 0;
20188 /* .cfi_* directives generate a read-only section, so fall back on
20189 manual .eh_frame creation if we need the section to be writable. */
20190 if (TARGET_WRITABLE_EH_FRAME
)
20191 flag_dwarf2_cfi_asm
= 0;
20193 mips_init_print_operand_punct ();
20195 /* Set up array to map GCC register number to debug register number.
20196 Ignore the special purpose register numbers. */
20198 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
20200 mips_dbx_regno
[i
] = IGNORED_DWARF_REGNUM
;
20201 if (GP_REG_P (i
) || FP_REG_P (i
) || ALL_COP_REG_P (i
))
20202 mips_dwarf_regno
[i
] = i
;
20204 mips_dwarf_regno
[i
] = INVALID_REGNUM
;
20207 start
= GP_DBX_FIRST
- GP_REG_FIRST
;
20208 for (i
= GP_REG_FIRST
; i
<= GP_REG_LAST
; i
++)
20209 mips_dbx_regno
[i
] = i
+ start
;
20211 start
= FP_DBX_FIRST
- FP_REG_FIRST
;
20212 for (i
= FP_REG_FIRST
; i
<= FP_REG_LAST
; i
++)
20213 mips_dbx_regno
[i
] = i
+ start
;
20215 /* Accumulator debug registers use big-endian ordering. */
20216 mips_dbx_regno
[HI_REGNUM
] = MD_DBX_FIRST
+ 0;
20217 mips_dbx_regno
[LO_REGNUM
] = MD_DBX_FIRST
+ 1;
20218 mips_dwarf_regno
[HI_REGNUM
] = MD_REG_FIRST
+ 0;
20219 mips_dwarf_regno
[LO_REGNUM
] = MD_REG_FIRST
+ 1;
20220 for (i
= DSP_ACC_REG_FIRST
; i
<= DSP_ACC_REG_LAST
; i
+= 2)
20222 mips_dwarf_regno
[i
+ TARGET_LITTLE_ENDIAN
] = i
;
20223 mips_dwarf_regno
[i
+ TARGET_BIG_ENDIAN
] = i
+ 1;
20226 /* Set up mips_hard_regno_mode_ok. */
20227 for (mode
= 0; mode
< MAX_MACHINE_MODE
; mode
++)
20228 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
20229 mips_hard_regno_mode_ok_p
[mode
][regno
]
20230 = mips_hard_regno_mode_ok_uncached (regno
, (machine_mode
) mode
);
20232 /* Function to allocate machine-dependent function status. */
20233 init_machine_status
= &mips_init_machine_status
;
20235 /* Default to working around R4000 errata only if the processor
20236 was selected explicitly. */
20237 if ((target_flags_explicit
& MASK_FIX_R4000
) == 0
20238 && strcmp (mips_arch_info
->name
, "r4000") == 0)
20239 target_flags
|= MASK_FIX_R4000
;
20241 /* Default to working around R4400 errata only if the processor
20242 was selected explicitly. */
20243 if ((target_flags_explicit
& MASK_FIX_R4400
) == 0
20244 && strcmp (mips_arch_info
->name
, "r4400") == 0)
20245 target_flags
|= MASK_FIX_R4400
;
20247 /* Default to working around R10000 errata only if the processor
20248 was selected explicitly. */
20249 if ((target_flags_explicit
& MASK_FIX_R10000
) == 0
20250 && strcmp (mips_arch_info
->name
, "r10000") == 0)
20251 target_flags
|= MASK_FIX_R10000
;
20253 /* Make sure that branch-likely instructions available when using
20254 -mfix-r10000. The instructions are not available if either:
20256 1. -mno-branch-likely was passed.
20257 2. The selected ISA does not support branch-likely and
20258 the command line does not include -mbranch-likely. */
20259 if (TARGET_FIX_R10000
20260 && ((target_flags_explicit
& MASK_BRANCHLIKELY
) == 0
20261 ? !ISA_HAS_BRANCHLIKELY
20262 : !TARGET_BRANCHLIKELY
))
20263 sorry ("%qs requires branch-likely instructions", "-mfix-r10000");
20265 if (TARGET_SYNCI
&& !ISA_HAS_SYNCI
)
20267 warning (0, "the %qs architecture does not support the synci "
20268 "instruction", mips_arch_info
->name
);
20269 target_flags
&= ~MASK_SYNCI
;
20272 /* Only optimize PIC indirect calls if they are actually required. */
20273 if (!TARGET_USE_GOT
|| !TARGET_EXPLICIT_RELOCS
)
20274 target_flags
&= ~MASK_RELAX_PIC_CALLS
;
20276 /* Save base state of options. */
20277 mips_base_target_flags
= target_flags
;
20278 mips_base_schedule_insns
= flag_schedule_insns
;
20279 mips_base_reorder_blocks_and_partition
= flag_reorder_blocks_and_partition
;
20280 mips_base_move_loop_invariants
= flag_move_loop_invariants
;
20281 mips_base_align_loops
= str_align_loops
;
20282 mips_base_align_jumps
= str_align_jumps
;
20283 mips_base_align_functions
= str_align_functions
;
20285 /* Now select the ISA mode.
20287 Do all CPP-sensitive stuff in uncompressed mode; we'll switch modes
20288 later if required. */
20289 mips_set_compression_mode (0);
20291 /* We register a second machine specific reorg pass after delay slot
20292 filling. Registering the pass must be done at start up. It's
20293 convenient to do it here. */
20294 opt_pass
*new_pass
= make_pass_mips_machine_reorg2 (g
);
20295 struct register_pass_info insert_pass_mips_machine_reorg2
=
20297 new_pass
, /* pass */
20298 "dbr", /* reference_pass_name */
20299 1, /* ref_pass_instance_number */
20300 PASS_POS_INSERT_AFTER
/* po_op */
20302 register_pass (&insert_pass_mips_machine_reorg2
);
20304 if (TARGET_HARD_FLOAT_ABI
&& TARGET_MIPS5900
)
20305 REAL_MODE_FORMAT (SFmode
) = &spu_single_format
;
20307 mips_register_frame_header_opt ();
20310 /* Swap the register information for registers I and I + 1, which
20311 currently have the wrong endianness. Note that the registers'
20312 fixedness and call-clobberedness might have been set on the
20316 mips_swap_registers (unsigned int i
)
20321 #define SWAP_INT(X, Y) (tmpi = (X), (X) = (Y), (Y) = tmpi)
20322 #define SWAP_STRING(X, Y) (tmps = (X), (X) = (Y), (Y) = tmps)
20324 SWAP_INT (fixed_regs
[i
], fixed_regs
[i
+ 1]);
20325 SWAP_INT (call_used_regs
[i
], call_used_regs
[i
+ 1]);
20326 SWAP_INT (call_really_used_regs
[i
], call_really_used_regs
[i
+ 1]);
20327 SWAP_STRING (reg_names
[i
], reg_names
[i
+ 1]);
20333 /* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */
20336 mips_conditional_register_usage (void)
20341 /* These DSP control register fields are global. */
20342 global_regs
[CCDSP_PO_REGNUM
] = 1;
20343 global_regs
[CCDSP_SC_REGNUM
] = 1;
20346 AND_COMPL_HARD_REG_SET (accessible_reg_set
,
20347 reg_class_contents
[(int) DSP_ACC_REGS
]);
20350 AND_COMPL_HARD_REG_SET (accessible_reg_set
,
20351 reg_class_contents
[(int) MD_REGS
]);
20353 if (!TARGET_HARD_FLOAT
)
20355 AND_COMPL_HARD_REG_SET (accessible_reg_set
,
20356 reg_class_contents
[(int) FP_REGS
]);
20357 AND_COMPL_HARD_REG_SET (accessible_reg_set
,
20358 reg_class_contents
[(int) ST_REGS
]);
20360 else if (!ISA_HAS_8CC
)
20362 /* We only have a single condition-code register. We implement
20363 this by fixing all the condition-code registers and generating
20364 RTL that refers directly to ST_REG_FIRST. */
20365 AND_COMPL_HARD_REG_SET (accessible_reg_set
,
20366 reg_class_contents
[(int) ST_REGS
]);
20368 SET_HARD_REG_BIT (accessible_reg_set
, FPSW_REGNUM
);
20369 fixed_regs
[FPSW_REGNUM
] = call_used_regs
[FPSW_REGNUM
] = 1;
20373 /* In MIPS16 mode, we prohibit the unused $s registers, since they
20374 are call-saved, and saving them via a MIPS16 register would
20375 probably waste more time than just reloading the value.
20377 We permit the $t temporary registers when optimizing for speed
20378 but not when optimizing for space because using them results in
20379 code that is larger (but faster) then not using them. We do
20380 allow $24 (t8) because it is used in CMP and CMPI instructions
20381 and $25 (t9) because it is used as the function call address in
20384 fixed_regs
[18] = call_used_regs
[18] = 1;
20385 fixed_regs
[19] = call_used_regs
[19] = 1;
20386 fixed_regs
[20] = call_used_regs
[20] = 1;
20387 fixed_regs
[21] = call_used_regs
[21] = 1;
20388 fixed_regs
[22] = call_used_regs
[22] = 1;
20389 fixed_regs
[23] = call_used_regs
[23] = 1;
20390 fixed_regs
[26] = call_used_regs
[26] = 1;
20391 fixed_regs
[27] = call_used_regs
[27] = 1;
20392 fixed_regs
[30] = call_used_regs
[30] = 1;
20395 fixed_regs
[8] = call_used_regs
[8] = 1;
20396 fixed_regs
[9] = call_used_regs
[9] = 1;
20397 fixed_regs
[10] = call_used_regs
[10] = 1;
20398 fixed_regs
[11] = call_used_regs
[11] = 1;
20399 fixed_regs
[12] = call_used_regs
[12] = 1;
20400 fixed_regs
[13] = call_used_regs
[13] = 1;
20401 fixed_regs
[14] = call_used_regs
[14] = 1;
20402 fixed_regs
[15] = call_used_regs
[15] = 1;
20405 /* Do not allow HI and LO to be treated as register operands.
20406 There are no MTHI or MTLO instructions (or any real need
20407 for them) and one-way registers cannot easily be reloaded. */
20408 AND_COMPL_HARD_REG_SET (operand_reg_set
,
20409 reg_class_contents
[(int) MD_REGS
]);
20411 /* $f20-$f23 are call-clobbered for n64. */
20412 if (mips_abi
== ABI_64
)
20415 for (regno
= FP_REG_FIRST
+ 20; regno
< FP_REG_FIRST
+ 24; regno
++)
20416 call_really_used_regs
[regno
] = call_used_regs
[regno
] = 1;
20418 /* Odd registers in the range $f21-$f31 (inclusive) are call-clobbered
20419 for n32 and o32 FP64. */
20420 if (mips_abi
== ABI_N32
20421 || (mips_abi
== ABI_32
20422 && TARGET_FLOAT64
))
20425 for (regno
= FP_REG_FIRST
+ 21; regno
<= FP_REG_FIRST
+ 31; regno
+=2)
20426 call_really_used_regs
[regno
] = call_used_regs
[regno
] = 1;
20428 /* Make sure that double-register accumulator values are correctly
20429 ordered for the current endianness. */
20430 if (TARGET_LITTLE_ENDIAN
)
20432 unsigned int regno
;
20434 mips_swap_registers (MD_REG_FIRST
);
20435 for (regno
= DSP_ACC_REG_FIRST
; regno
<= DSP_ACC_REG_LAST
; regno
+= 2)
20436 mips_swap_registers (regno
);
20440 /* Implement EH_USES. */
20443 mips_eh_uses (unsigned int regno
)
20445 if (reload_completed
&& !TARGET_ABSOLUTE_JUMPS
)
20447 /* We need to force certain registers to be live in order to handle
20448 PIC long branches correctly. See mips_must_initialize_gp_p for
20450 if (mips_cfun_has_cprestore_slot_p ())
20452 if (regno
== CPRESTORE_SLOT_REGNUM
)
20457 if (cfun
->machine
->global_pointer
== regno
)
20465 /* Implement EPILOGUE_USES. */
20468 mips_epilogue_uses (unsigned int regno
)
20470 /* Say that the epilogue uses the return address register. Note that
20471 in the case of sibcalls, the values "used by the epilogue" are
20472 considered live at the start of the called function. */
20473 if (regno
== RETURN_ADDR_REGNUM
)
20476 /* If using a GOT, say that the epilogue also uses GOT_VERSION_REGNUM.
20477 See the comment above load_call<mode> for details. */
20478 if (TARGET_USE_GOT
&& (regno
) == GOT_VERSION_REGNUM
)
20481 /* An interrupt handler must preserve some registers that are
20482 ordinarily call-clobbered. */
20483 if (cfun
->machine
->interrupt_handler_p
20484 && mips_interrupt_extra_call_saved_reg_p (regno
))
20490 /* Return true if INSN needs to be wrapped in ".set noat".
20491 INSN has NOPERANDS operands, stored in OPVEC. */
20494 mips_need_noat_wrapper_p (rtx_insn
*insn
, rtx
*opvec
, int noperands
)
20496 if (recog_memoized (insn
) >= 0)
20498 subrtx_iterator::array_type array
;
20499 for (int i
= 0; i
< noperands
; i
++)
20500 FOR_EACH_SUBRTX (iter
, array
, opvec
[i
], NONCONST
)
20501 if (REG_P (*iter
) && REGNO (*iter
) == AT_REGNUM
)
20507 /* Implement FINAL_PRESCAN_INSN. Mark MIPS16 inline constant pools
20508 as data for the purpose of disassembly. For simplicity embed the
20509 pool's initial label number in the local symbol produced so that
20510 multiple pools within a single function end up marked with unique
20511 symbols. The label number is carried by the `consttable' insn
20512 emitted at the beginning of each pool. */
20515 mips_final_prescan_insn (rtx_insn
*insn
, rtx
*opvec
, int noperands
)
20518 && GET_CODE (PATTERN (insn
)) == UNSPEC_VOLATILE
20519 && XINT (PATTERN (insn
), 1) == UNSPEC_CONSTTABLE
)
20520 mips_set_text_contents_type (asm_out_file
, "__pool_",
20521 INTVAL (XVECEXP (PATTERN (insn
), 0, 0)),
20524 if (mips_need_noat_wrapper_p (insn
, opvec
, noperands
))
20525 mips_push_asm_switch (&mips_noat
);
20528 /* Implement TARGET_ASM_FINAL_POSTSCAN_INSN. Reset text marking to
20529 code after a MIPS16 inline constant pool. Like with the beginning
20530 of a pool table use the pool's initial label number to keep symbols
20531 unique. The label number is carried by the `consttable_end' insn
20532 emitted at the end of each pool. */
20535 mips_final_postscan_insn (FILE *file ATTRIBUTE_UNUSED
, rtx_insn
*insn
,
20536 rtx
*opvec
, int noperands
)
20538 if (mips_need_noat_wrapper_p (insn
, opvec
, noperands
))
20539 mips_pop_asm_switch (&mips_noat
);
20542 && GET_CODE (PATTERN (insn
)) == UNSPEC_VOLATILE
20543 && XINT (PATTERN (insn
), 1) == UNSPEC_CONSTTABLE_END
)
20544 mips_set_text_contents_type (asm_out_file
, "__pend_",
20545 INTVAL (XVECEXP (PATTERN (insn
), 0, 0)),
20549 /* Return the function that is used to expand the <u>mulsidi3 pattern.
20550 EXT_CODE is the code of the extension used. Return NULL if widening
20551 multiplication shouldn't be used. */
20554 mips_mulsidi3_gen_fn (enum rtx_code ext_code
)
20558 signed_p
= ext_code
== SIGN_EXTEND
;
20561 /* Don't use widening multiplication with MULT when we have DMUL. Even
20562 with the extension of its input operands DMUL is faster. Note that
20563 the extension is not needed for signed multiplication. In order to
20564 ensure that we always remove the redundant sign-extension in this
20565 case we still expand mulsidi3 for DMUL. */
20566 if (ISA_HAS_R6DMUL
)
20567 return signed_p
? gen_mulsidi3_64bit_r6dmul
: NULL
;
20569 return signed_p
? gen_mulsidi3_64bit_dmul
: NULL
;
20572 ? gen_mulsidi3_64bit_mips16
20573 : gen_umulsidi3_64bit_mips16
);
20574 if (TARGET_FIX_R4000
)
20576 return signed_p
? gen_mulsidi3_64bit
: gen_umulsidi3_64bit
;
20581 return (signed_p
? gen_mulsidi3_32bit_r6
: gen_umulsidi3_32bit_r6
);
20584 ? gen_mulsidi3_32bit_mips16
20585 : gen_umulsidi3_32bit_mips16
);
20586 if (TARGET_FIX_R4000
&& !ISA_HAS_DSP
)
20587 return signed_p
? gen_mulsidi3_32bit_r4000
: gen_umulsidi3_32bit_r4000
;
20588 return signed_p
? gen_mulsidi3_32bit
: gen_umulsidi3_32bit
;
20592 /* Return true if PATTERN matches the kind of instruction generated by
20593 umips_build_save_restore. SAVE_P is true for store. */
20596 umips_save_restore_pattern_p (bool save_p
, rtx pattern
)
20600 HOST_WIDE_INT first_offset
= 0;
20601 rtx first_base
= 0;
20602 unsigned int regmask
= 0;
20604 for (n
= 0; n
< XVECLEN (pattern
, 0); n
++)
20606 rtx set
, reg
, mem
, this_base
;
20607 HOST_WIDE_INT this_offset
;
20609 /* Check that we have a SET. */
20610 set
= XVECEXP (pattern
, 0, n
);
20611 if (GET_CODE (set
) != SET
)
20614 /* Check that the SET is a load (if restoring) or a store
20616 mem
= save_p
? SET_DEST (set
) : SET_SRC (set
);
20617 if (!MEM_P (mem
) || MEM_VOLATILE_P (mem
))
20620 /* Check that the address is the sum of base and a possibly-zero
20621 constant offset. Determine if the offset is in range. */
20622 mips_split_plus (XEXP (mem
, 0), &this_base
, &this_offset
);
20623 if (!REG_P (this_base
))
20628 if (!UMIPS_12BIT_OFFSET_P (this_offset
))
20630 first_base
= this_base
;
20631 first_offset
= this_offset
;
20635 /* Check that the save slots are consecutive. */
20636 if (REGNO (this_base
) != REGNO (first_base
)
20637 || this_offset
!= first_offset
+ UNITS_PER_WORD
* n
)
20641 /* Check that SET's other operand is a register. */
20642 reg
= save_p
? SET_SRC (set
) : SET_DEST (set
);
20646 regmask
|= 1 << REGNO (reg
);
20649 for (i
= 0; i
< ARRAY_SIZE (umips_swm_mask
); i
++)
20650 if (regmask
== umips_swm_mask
[i
])
20656 /* Return the assembly instruction for microMIPS LWM or SWM.
20657 SAVE_P and PATTERN are as for umips_save_restore_pattern_p. */
20660 umips_output_save_restore (bool save_p
, rtx pattern
)
20662 static char buffer
[300];
20665 HOST_WIDE_INT offset
;
20666 rtx base
, mem
, set
, last_set
, last_reg
;
20668 /* Parse the pattern. */
20669 gcc_assert (umips_save_restore_pattern_p (save_p
, pattern
));
20671 s
= strcpy (buffer
, save_p
? "swm\t" : "lwm\t");
20673 n
= XVECLEN (pattern
, 0);
20675 set
= XVECEXP (pattern
, 0, 0);
20676 mem
= save_p
? SET_DEST (set
) : SET_SRC (set
);
20677 mips_split_plus (XEXP (mem
, 0), &base
, &offset
);
20679 last_set
= XVECEXP (pattern
, 0, n
- 1);
20680 last_reg
= save_p
? SET_SRC (last_set
) : SET_DEST (last_set
);
20682 if (REGNO (last_reg
) == 31)
20685 gcc_assert (n
<= 9);
20689 s
+= sprintf (s
, "%s,", reg_names
[16]);
20691 s
+= sprintf (s
, "%s-%s,", reg_names
[16], reg_names
[15 + n
]);
20693 s
+= sprintf (s
, "%s-%s,%s,", reg_names
[16], reg_names
[23],
20696 if (REGNO (last_reg
) == 31)
20697 s
+= sprintf (s
, "%s,", reg_names
[31]);
20699 s
+= sprintf (s
, "%d(%s)", (int)offset
, reg_names
[REGNO (base
)]);
20703 /* Return true if MEM1 and MEM2 use the same base register, and the
20704 offset of MEM2 equals the offset of MEM1 plus 4. FIRST_REG is the
20705 register into (from) which the contents of MEM1 will be loaded
20706 (stored), depending on the value of LOAD_P.
20707 SWAP_P is true when the 1st and 2nd instructions are swapped. */
20710 umips_load_store_pair_p_1 (bool load_p
, bool swap_p
,
20711 rtx first_reg
, rtx mem1
, rtx mem2
)
20714 HOST_WIDE_INT offset1
, offset2
;
20716 if (!MEM_P (mem1
) || !MEM_P (mem2
))
20719 mips_split_plus (XEXP (mem1
, 0), &base1
, &offset1
);
20720 mips_split_plus (XEXP (mem2
, 0), &base2
, &offset2
);
20722 if (!REG_P (base1
) || !rtx_equal_p (base1
, base2
))
20725 /* Avoid invalid load pair instructions. */
20726 if (load_p
&& REGNO (first_reg
) == REGNO (base1
))
20729 /* We must avoid this case for anti-dependence.
20732 first_reg is $2, but the base is $3. */
20735 && REGNO (first_reg
) + 1 == REGNO (base1
))
20738 if (offset2
!= offset1
+ 4)
20741 if (!UMIPS_12BIT_OFFSET_P (offset1
))
20748 mips_load_store_bonding_p (rtx
*operands
, machine_mode mode
, bool load_p
)
20750 rtx reg1
, reg2
, mem1
, mem2
, base1
, base2
;
20751 enum reg_class rc1
, rc2
;
20752 HOST_WIDE_INT offset1
, offset2
;
20756 reg1
= operands
[0];
20757 reg2
= operands
[2];
20758 mem1
= operands
[1];
20759 mem2
= operands
[3];
20763 reg1
= operands
[1];
20764 reg2
= operands
[3];
20765 mem1
= operands
[0];
20766 mem2
= operands
[2];
20769 if (mips_address_insns (XEXP (mem1
, 0), mode
, false) == 0
20770 || mips_address_insns (XEXP (mem2
, 0), mode
, false) == 0)
20773 mips_split_plus (XEXP (mem1
, 0), &base1
, &offset1
);
20774 mips_split_plus (XEXP (mem2
, 0), &base2
, &offset2
);
20776 /* Base regs do not match. */
20777 if (!REG_P (base1
) || !rtx_equal_p (base1
, base2
))
20780 /* Either of the loads is clobbering base register. It is legitimate to bond
20781 loads if second load clobbers base register. However, hardware does not
20782 support such bonding. */
20784 && (REGNO (reg1
) == REGNO (base1
)
20785 || (REGNO (reg2
) == REGNO (base1
))))
20788 /* Loading in same registers. */
20790 && REGNO (reg1
) == REGNO (reg2
))
20793 /* The loads/stores are not of same type. */
20794 rc1
= REGNO_REG_CLASS (REGNO (reg1
));
20795 rc2
= REGNO_REG_CLASS (REGNO (reg2
));
20797 && !reg_class_subset_p (rc1
, rc2
)
20798 && !reg_class_subset_p (rc2
, rc1
))
20801 if (abs (offset1
- offset2
) != GET_MODE_SIZE (mode
))
20807 /* OPERANDS describes the operands to a pair of SETs, in the order
20808 dest1, src1, dest2, src2. Return true if the operands can be used
20809 in an LWP or SWP instruction; LOAD_P says which. */
20812 umips_load_store_pair_p (bool load_p
, rtx
*operands
)
20814 rtx reg1
, reg2
, mem1
, mem2
;
20818 reg1
= operands
[0];
20819 reg2
= operands
[2];
20820 mem1
= operands
[1];
20821 mem2
= operands
[3];
20825 reg1
= operands
[1];
20826 reg2
= operands
[3];
20827 mem1
= operands
[0];
20828 mem2
= operands
[2];
20831 if (REGNO (reg2
) == REGNO (reg1
) + 1)
20832 return umips_load_store_pair_p_1 (load_p
, false, reg1
, mem1
, mem2
);
20834 if (REGNO (reg1
) == REGNO (reg2
) + 1)
20835 return umips_load_store_pair_p_1 (load_p
, true, reg2
, mem2
, mem1
);
20840 /* Return the assembly instruction for a microMIPS LWP or SWP in which
20841 the first register is REG and the first memory slot is MEM.
20842 LOAD_P is true for LWP. */
20845 umips_output_load_store_pair_1 (bool load_p
, rtx reg
, rtx mem
)
20847 rtx ops
[] = {reg
, mem
};
20850 output_asm_insn ("lwp\t%0,%1", ops
);
20852 output_asm_insn ("swp\t%0,%1", ops
);
20855 /* Output the assembly instruction for a microMIPS LWP or SWP instruction.
20856 LOAD_P and OPERANDS are as for umips_load_store_pair_p. */
20859 umips_output_load_store_pair (bool load_p
, rtx
*operands
)
20861 rtx reg1
, reg2
, mem1
, mem2
;
20864 reg1
= operands
[0];
20865 reg2
= operands
[2];
20866 mem1
= operands
[1];
20867 mem2
= operands
[3];
20871 reg1
= operands
[1];
20872 reg2
= operands
[3];
20873 mem1
= operands
[0];
20874 mem2
= operands
[2];
20877 if (REGNO (reg2
) == REGNO (reg1
) + 1)
20879 umips_output_load_store_pair_1 (load_p
, reg1
, mem1
);
20883 gcc_assert (REGNO (reg1
) == REGNO (reg2
) + 1);
20884 umips_output_load_store_pair_1 (load_p
, reg2
, mem2
);
20887 /* Return true if REG1 and REG2 match the criteria for a movep insn. */
20890 umips_movep_target_p (rtx reg1
, rtx reg2
)
20892 int regno1
, regno2
, pair
;
20894 static const int match
[8] = {
20895 0x00000060, /* 5, 6 */
20896 0x000000a0, /* 5, 7 */
20897 0x000000c0, /* 6, 7 */
20898 0x00200010, /* 4, 21 */
20899 0x00400010, /* 4, 22 */
20900 0x00000030, /* 4, 5 */
20901 0x00000050, /* 4, 6 */
20902 0x00000090 /* 4, 7 */
20905 if (!REG_P (reg1
) || !REG_P (reg2
))
20908 regno1
= REGNO (reg1
);
20909 regno2
= REGNO (reg2
);
20911 if (!GP_REG_P (regno1
) || !GP_REG_P (regno2
))
20914 pair
= (1 << regno1
) | (1 << regno2
);
20916 for (i
= 0; i
< ARRAY_SIZE (match
); i
++)
20917 if (pair
== match
[i
])
20923 /* Return the size in bytes of the trampoline code, padded to
20924 TRAMPOLINE_ALIGNMENT bits. The static chain pointer and target
20925 function address immediately follow. */
20928 mips_trampoline_code_size (void)
20930 if (TARGET_USE_PIC_FN_ADDR_REG
)
20932 else if (ptr_mode
== DImode
)
20934 else if (ISA_HAS_LOAD_DELAY
)
20940 /* Implement TARGET_TRAMPOLINE_INIT. */
20943 mips_trampoline_init (rtx m_tramp
, tree fndecl
, rtx chain_value
)
20945 rtx addr
, end_addr
, high
, low
, opcode
, mem
;
20948 HOST_WIDE_INT end_addr_offset
, static_chain_offset
, target_function_offset
;
20950 /* Work out the offsets of the pointers from the start of the
20951 trampoline code. */
20952 end_addr_offset
= mips_trampoline_code_size ();
20953 static_chain_offset
= end_addr_offset
;
20954 target_function_offset
= static_chain_offset
+ GET_MODE_SIZE (ptr_mode
);
20956 /* Get pointers to the beginning and end of the code block. */
20957 addr
= force_reg (Pmode
, XEXP (m_tramp
, 0));
20958 end_addr
= mips_force_binary (Pmode
, PLUS
, addr
, GEN_INT (end_addr_offset
));
20960 #define OP(X) gen_int_mode (X, SImode)
20962 /* Build up the code in TRAMPOLINE. */
20964 if (TARGET_USE_PIC_FN_ADDR_REG
)
20966 /* $25 contains the address of the trampoline. Emit code of the form:
20968 l[wd] $1, target_function_offset($25)
20969 l[wd] $static_chain, static_chain_offset($25)
20972 trampoline
[i
++] = OP (MIPS_LOAD_PTR (AT_REGNUM
,
20973 target_function_offset
,
20974 PIC_FUNCTION_ADDR_REGNUM
));
20975 trampoline
[i
++] = OP (MIPS_LOAD_PTR (STATIC_CHAIN_REGNUM
,
20976 static_chain_offset
,
20977 PIC_FUNCTION_ADDR_REGNUM
));
20978 trampoline
[i
++] = OP (MIPS_JR (AT_REGNUM
));
20979 trampoline
[i
++] = OP (MIPS_MOVE (PIC_FUNCTION_ADDR_REGNUM
, AT_REGNUM
));
20981 else if (ptr_mode
== DImode
)
20983 /* It's too cumbersome to create the full 64-bit address, so let's
20989 1: l[wd] $25, target_function_offset - 12($31)
20990 l[wd] $static_chain, static_chain_offset - 12($31)
20994 where 12 is the offset of "1:" from the start of the code block. */
20995 trampoline
[i
++] = OP (MIPS_MOVE (AT_REGNUM
, RETURN_ADDR_REGNUM
));
20996 trampoline
[i
++] = OP (MIPS_BAL (1));
20997 trampoline
[i
++] = OP (MIPS_NOP
);
20998 trampoline
[i
++] = OP (MIPS_LOAD_PTR (PIC_FUNCTION_ADDR_REGNUM
,
20999 target_function_offset
- 12,
21000 RETURN_ADDR_REGNUM
));
21001 trampoline
[i
++] = OP (MIPS_LOAD_PTR (STATIC_CHAIN_REGNUM
,
21002 static_chain_offset
- 12,
21003 RETURN_ADDR_REGNUM
));
21004 trampoline
[i
++] = OP (MIPS_JR (PIC_FUNCTION_ADDR_REGNUM
));
21005 trampoline
[i
++] = OP (MIPS_MOVE (RETURN_ADDR_REGNUM
, AT_REGNUM
));
21009 /* If the target has load delays, emit:
21011 lui $1, %hi(end_addr)
21012 lw $25, %lo(end_addr + ...)($1)
21013 lw $static_chain, %lo(end_addr + ...)($1)
21019 lui $1, %hi(end_addr)
21020 lw $25, %lo(end_addr + ...)($1)
21022 lw $static_chain, %lo(end_addr + ...)($1). */
21024 /* Split END_ADDR into %hi and %lo values. Trampolines are aligned
21025 to 64 bits, so the %lo value will have the bottom 3 bits clear. */
21026 high
= expand_simple_binop (SImode
, PLUS
, end_addr
, GEN_INT (0x8000),
21027 NULL
, false, OPTAB_WIDEN
);
21028 high
= expand_simple_binop (SImode
, LSHIFTRT
, high
, GEN_INT (16),
21029 NULL
, false, OPTAB_WIDEN
);
21030 low
= convert_to_mode (SImode
, gen_lowpart (HImode
, end_addr
), true);
21032 /* Emit the LUI. */
21033 opcode
= OP (MIPS_LUI (AT_REGNUM
, 0));
21034 trampoline
[i
++] = expand_simple_binop (SImode
, IOR
, opcode
, high
,
21035 NULL
, false, OPTAB_WIDEN
);
21037 /* Emit the load of the target function. */
21038 opcode
= OP (MIPS_LOAD_PTR (PIC_FUNCTION_ADDR_REGNUM
,
21039 target_function_offset
- end_addr_offset
,
21041 trampoline
[i
++] = expand_simple_binop (SImode
, IOR
, opcode
, low
,
21042 NULL
, false, OPTAB_WIDEN
);
21044 /* Emit the JR here, if we can. */
21045 if (!ISA_HAS_LOAD_DELAY
)
21046 trampoline
[i
++] = OP (MIPS_JR (PIC_FUNCTION_ADDR_REGNUM
));
21048 /* Emit the load of the static chain register. */
21049 opcode
= OP (MIPS_LOAD_PTR (STATIC_CHAIN_REGNUM
,
21050 static_chain_offset
- end_addr_offset
,
21052 trampoline
[i
++] = expand_simple_binop (SImode
, IOR
, opcode
, low
,
21053 NULL
, false, OPTAB_WIDEN
);
21055 /* Emit the JR, if we couldn't above. */
21056 if (ISA_HAS_LOAD_DELAY
)
21058 trampoline
[i
++] = OP (MIPS_JR (PIC_FUNCTION_ADDR_REGNUM
));
21059 trampoline
[i
++] = OP (MIPS_NOP
);
21065 /* If we are using compact branches we don't have delay slots so
21066 place the instruction that was in the delay slot before the JRC
21069 if (TARGET_CB_ALWAYS
)
21072 temp
= trampoline
[i
-2];
21073 trampoline
[i
-2] = trampoline
[i
-1];
21074 trampoline
[i
-1] = temp
;
21077 /* Copy the trampoline code. Leave any padding uninitialized. */
21078 for (j
= 0; j
< i
; j
++)
21080 mem
= adjust_address (m_tramp
, SImode
, j
* GET_MODE_SIZE (SImode
));
21081 mips_emit_move (mem
, trampoline
[j
]);
21084 /* Set up the static chain pointer field. */
21085 mem
= adjust_address (m_tramp
, ptr_mode
, static_chain_offset
);
21086 mips_emit_move (mem
, chain_value
);
21088 /* Set up the target function field. */
21089 mem
= adjust_address (m_tramp
, ptr_mode
, target_function_offset
);
21090 mips_emit_move (mem
, XEXP (DECL_RTL (fndecl
), 0));
21092 /* Flush the code part of the trampoline. */
21093 emit_insn (gen_add3_insn (end_addr
, addr
, GEN_INT (TRAMPOLINE_SIZE
)));
21094 emit_insn (gen_clear_cache (addr
, end_addr
));
21097 /* Implement FUNCTION_PROFILER. */
21099 void mips_function_profiler (FILE *file
)
21102 sorry ("mips16 function profiling");
21103 if (TARGET_LONG_CALLS
)
21105 /* For TARGET_LONG_CALLS use $3 for the address of _mcount. */
21106 if (Pmode
== DImode
)
21107 fprintf (file
, "\tdla\t%s,_mcount\n", reg_names
[3]);
21109 fprintf (file
, "\tla\t%s,_mcount\n", reg_names
[3]);
21111 mips_push_asm_switch (&mips_noat
);
21112 fprintf (file
, "\tmove\t%s,%s\t\t# save current return address\n",
21113 reg_names
[AT_REGNUM
], reg_names
[RETURN_ADDR_REGNUM
]);
21114 /* _mcount treats $2 as the static chain register. */
21115 if (cfun
->static_chain_decl
!= NULL
)
21116 fprintf (file
, "\tmove\t%s,%s\n", reg_names
[2],
21117 reg_names
[STATIC_CHAIN_REGNUM
]);
21118 if (TARGET_MCOUNT_RA_ADDRESS
)
21120 /* If TARGET_MCOUNT_RA_ADDRESS load $12 with the address of the
21121 ra save location. */
21122 if (cfun
->machine
->frame
.ra_fp_offset
== 0)
21123 /* ra not saved, pass zero. */
21124 fprintf (file
, "\tmove\t%s,%s\n", reg_names
[12], reg_names
[0]);
21126 fprintf (file
, "\t%s\t%s," HOST_WIDE_INT_PRINT_DEC
"(%s)\n",
21127 Pmode
== DImode
? "dla" : "la", reg_names
[12],
21128 cfun
->machine
->frame
.ra_fp_offset
,
21129 reg_names
[STACK_POINTER_REGNUM
]);
21131 if (!TARGET_NEWABI
)
21133 "\t%s\t%s,%s,%d\t\t# _mcount pops 2 words from stack\n",
21134 TARGET_64BIT
? "dsubu" : "subu",
21135 reg_names
[STACK_POINTER_REGNUM
],
21136 reg_names
[STACK_POINTER_REGNUM
],
21137 Pmode
== DImode
? 16 : 8);
21139 if (TARGET_LONG_CALLS
)
21140 fprintf (file
, "\tjalr\t%s\n", reg_names
[3]);
21142 fprintf (file
, "\tjal\t_mcount\n");
21143 mips_pop_asm_switch (&mips_noat
);
21144 /* _mcount treats $2 as the static chain register. */
21145 if (cfun
->static_chain_decl
!= NULL
)
21146 fprintf (file
, "\tmove\t%s,%s\n", reg_names
[STATIC_CHAIN_REGNUM
],
21150 /* Implement TARGET_SHIFT_TRUNCATION_MASK. We want to keep the default
21151 behavior of TARGET_SHIFT_TRUNCATION_MASK for non-vector modes even
21152 when TARGET_LOONGSON_VECTORS is true. */
21154 static unsigned HOST_WIDE_INT
21155 mips_shift_truncation_mask (machine_mode mode
)
21157 if (TARGET_LOONGSON_VECTORS
&& VECTOR_MODE_P (mode
))
21160 return GET_MODE_BITSIZE (mode
) - 1;
21163 /* Implement TARGET_PREPARE_PCH_SAVE. */
21166 mips_prepare_pch_save (void)
21168 /* We are called in a context where the current compression vs.
21169 non-compression setting should be irrelevant. The question then is:
21170 which setting makes most sense at load time?
21172 The PCH is loaded before the first token is read. We should never have
21173 switched into a compression mode by that point, and thus should not have
21174 populated mips16_globals or micromips_globals. Nor can we load the
21175 entire contents of mips16_globals or micromips_globals from the PCH file,
21176 because they contain a combination of GGC and non-GGC data.
21178 There is therefore no point in trying save the GGC part of
21179 mips16_globals/micromips_globals to the PCH file, or to preserve a
21180 compression setting across the PCH save and load. The loading compiler
21181 would not have access to the non-GGC parts of mips16_globals or
21182 micromips_globals (either from the PCH file, or from a copy that the
21183 loading compiler generated itself) and would have to call target_reinit
21186 It therefore seems best to switch back to non-MIPS16 mode and
21187 non-microMIPS mode to save time, and to ensure that mips16_globals and
21188 micromips_globals remain null after a PCH load. */
21189 mips_set_compression_mode (0);
21190 mips16_globals
= 0;
21191 micromips_globals
= 0;
21194 /* Generate or test for an insn that supports a constant permutation. */
21196 #define MAX_VECT_LEN 16
21198 struct expand_vec_perm_d
21200 rtx target
, op0
, op1
;
21201 unsigned char perm
[MAX_VECT_LEN
];
21202 machine_mode vmode
;
21203 unsigned char nelt
;
21208 /* Construct (set target (vec_select op0 (parallel perm))) and
21209 return true if that's a valid instruction in the active ISA. */
21212 mips_expand_vselect (rtx target
, rtx op0
,
21213 const unsigned char *perm
, unsigned nelt
)
21215 rtx rperm
[MAX_VECT_LEN
], x
;
21219 for (i
= 0; i
< nelt
; ++i
)
21220 rperm
[i
] = GEN_INT (perm
[i
]);
21222 x
= gen_rtx_PARALLEL (VOIDmode
, gen_rtvec_v (nelt
, rperm
));
21223 x
= gen_rtx_VEC_SELECT (GET_MODE (target
), op0
, x
);
21224 x
= gen_rtx_SET (target
, x
);
21226 insn
= emit_insn (x
);
21227 if (recog_memoized (insn
) < 0)
21229 remove_insn (insn
);
21235 /* Similar, but generate a vec_concat from op0 and op1 as well. */
21238 mips_expand_vselect_vconcat (rtx target
, rtx op0
, rtx op1
,
21239 const unsigned char *perm
, unsigned nelt
)
21241 machine_mode v2mode
;
21244 if (!GET_MODE_2XWIDER_MODE (GET_MODE (op0
)).exists (&v2mode
))
21246 x
= gen_rtx_VEC_CONCAT (v2mode
, op0
, op1
);
21247 return mips_expand_vselect (target
, x
, perm
, nelt
);
21250 /* Recognize patterns for even-odd extraction. */
21253 mips_expand_vpc_loongson_even_odd (struct expand_vec_perm_d
*d
)
21255 unsigned i
, odd
, nelt
= d
->nelt
;
21256 rtx t0
, t1
, t2
, t3
;
21258 if (!(TARGET_HARD_FLOAT
&& TARGET_LOONGSON_VECTORS
))
21260 /* Even-odd for V2SI/V2SFmode is matched by interleave directly. */
21267 for (i
= 1; i
< nelt
; ++i
)
21268 if (d
->perm
[i
] != i
* 2 + odd
)
21274 /* We need 2*log2(N)-1 operations to achieve odd/even with interleave. */
21275 t0
= gen_reg_rtx (d
->vmode
);
21276 t1
= gen_reg_rtx (d
->vmode
);
21280 emit_insn (gen_loongson_punpckhhw (t0
, d
->op0
, d
->op1
));
21281 emit_insn (gen_loongson_punpcklhw (t1
, d
->op0
, d
->op1
));
21283 emit_insn (gen_loongson_punpckhhw (d
->target
, t1
, t0
));
21285 emit_insn (gen_loongson_punpcklhw (d
->target
, t1
, t0
));
21289 t2
= gen_reg_rtx (d
->vmode
);
21290 t3
= gen_reg_rtx (d
->vmode
);
21291 emit_insn (gen_loongson_punpckhbh (t0
, d
->op0
, d
->op1
));
21292 emit_insn (gen_loongson_punpcklbh (t1
, d
->op0
, d
->op1
));
21293 emit_insn (gen_loongson_punpckhbh (t2
, t1
, t0
));
21294 emit_insn (gen_loongson_punpcklbh (t3
, t1
, t0
));
21296 emit_insn (gen_loongson_punpckhbh (d
->target
, t3
, t2
));
21298 emit_insn (gen_loongson_punpcklbh (d
->target
, t3
, t2
));
21302 gcc_unreachable ();
21307 /* Recognize patterns for the Loongson PSHUFH instruction. */
21310 mips_expand_vpc_loongson_pshufh (struct expand_vec_perm_d
*d
)
21315 if (!(TARGET_HARD_FLOAT
&& TARGET_LOONGSON_VECTORS
))
21317 if (d
->vmode
!= V4HImode
)
21322 /* Convert the selector into the packed 8-bit form for pshufh. */
21323 /* Recall that loongson is little-endian only. No big-endian
21324 adjustment required. */
21325 for (i
= mask
= 0; i
< 4; i
++)
21326 mask
|= (d
->perm
[i
] & 3) << (i
* 2);
21327 rmask
= force_reg (SImode
, GEN_INT (mask
));
21329 if (d
->one_vector_p
)
21330 emit_insn (gen_loongson_pshufh (d
->target
, d
->op0
, rmask
));
21333 rtx t0
, t1
, x
, merge
, rmerge
[4];
21335 t0
= gen_reg_rtx (V4HImode
);
21336 t1
= gen_reg_rtx (V4HImode
);
21337 emit_insn (gen_loongson_pshufh (t1
, d
->op1
, rmask
));
21338 emit_insn (gen_loongson_pshufh (t0
, d
->op0
, rmask
));
21340 for (i
= 0; i
< 4; ++i
)
21341 rmerge
[i
] = (d
->perm
[i
] & 4 ? constm1_rtx
: const0_rtx
);
21342 merge
= gen_rtx_CONST_VECTOR (V4HImode
, gen_rtvec_v (4, rmerge
));
21343 merge
= force_reg (V4HImode
, merge
);
21345 x
= gen_rtx_AND (V4HImode
, merge
, t1
);
21346 emit_insn (gen_rtx_SET (t1
, x
));
21348 x
= gen_rtx_NOT (V4HImode
, merge
);
21349 x
= gen_rtx_AND (V4HImode
, x
, t0
);
21350 emit_insn (gen_rtx_SET (t0
, x
));
21352 x
= gen_rtx_IOR (V4HImode
, t0
, t1
);
21353 emit_insn (gen_rtx_SET (d
->target
, x
));
21359 /* Recognize broadcast patterns for the Loongson. */
21362 mips_expand_vpc_loongson_bcast (struct expand_vec_perm_d
*d
)
21367 if (!(TARGET_HARD_FLOAT
&& TARGET_LOONGSON_VECTORS
))
21369 /* Note that we've already matched V2SI via punpck and V4HI via pshufh. */
21370 if (d
->vmode
!= V8QImode
)
21372 if (!d
->one_vector_p
)
21376 for (i
= 1; i
< 8; ++i
)
21377 if (d
->perm
[i
] != elt
)
21383 /* With one interleave we put two of the desired element adjacent. */
21384 t0
= gen_reg_rtx (V8QImode
);
21386 emit_insn (gen_loongson_punpcklbh (t0
, d
->op0
, d
->op0
));
21388 emit_insn (gen_loongson_punpckhbh (t0
, d
->op0
, d
->op0
));
21390 /* Shuffle that one HImode element into all locations. */
21393 t1
= gen_reg_rtx (V4HImode
);
21394 emit_insn (gen_loongson_pshufh (t1
, gen_lowpart (V4HImode
, t0
),
21395 force_reg (SImode
, GEN_INT (elt
))));
21397 emit_move_insn (d
->target
, gen_lowpart (V8QImode
, t1
));
21401 /* Construct (set target (vec_select op0 (parallel selector))) and
21402 return true if that's a valid instruction in the active ISA. */
21405 mips_expand_msa_shuffle (struct expand_vec_perm_d
*d
)
21407 rtx x
, elts
[MAX_VECT_LEN
];
21415 for (i
= 0; i
< d
->nelt
; i
++)
21416 elts
[i
] = GEN_INT (d
->perm
[i
]);
21418 v
= gen_rtvec_v (d
->nelt
, elts
);
21419 x
= gen_rtx_PARALLEL (VOIDmode
, v
);
21421 if (!mips_const_vector_shuffle_set_p (x
, d
->vmode
))
21424 x
= gen_rtx_VEC_SELECT (d
->vmode
, d
->op0
, x
);
21425 x
= gen_rtx_SET (d
->target
, x
);
21427 insn
= emit_insn (x
);
21428 if (recog_memoized (insn
) < 0)
21430 remove_insn (insn
);
21437 mips_expand_vec_perm_const_1 (struct expand_vec_perm_d
*d
)
21439 unsigned int i
, nelt
= d
->nelt
;
21440 unsigned char perm2
[MAX_VECT_LEN
];
21442 if (d
->one_vector_p
)
21444 /* Try interleave with alternating operands. */
21445 memcpy (perm2
, d
->perm
, sizeof(perm2
));
21446 for (i
= 1; i
< nelt
; i
+= 2)
21448 if (mips_expand_vselect_vconcat (d
->target
, d
->op0
, d
->op1
, perm2
, nelt
))
21453 if (mips_expand_vselect_vconcat (d
->target
, d
->op0
, d
->op1
,
21457 /* Try again with swapped operands. */
21458 for (i
= 0; i
< nelt
; ++i
)
21459 perm2
[i
] = (d
->perm
[i
] + nelt
) & (2 * nelt
- 1);
21460 if (mips_expand_vselect_vconcat (d
->target
, d
->op1
, d
->op0
, perm2
, nelt
))
21464 if (mips_expand_vpc_loongson_even_odd (d
))
21466 if (mips_expand_vpc_loongson_pshufh (d
))
21468 if (mips_expand_vpc_loongson_bcast (d
))
21470 if (mips_expand_msa_shuffle (d
))
21475 /* Implement TARGET_VECTORIZE_VEC_PERM_CONST. */
21478 mips_vectorize_vec_perm_const (machine_mode vmode
, rtx target
, rtx op0
,
21479 rtx op1
, const vec_perm_indices
&sel
)
21481 struct expand_vec_perm_d d
;
21482 int i
, nelt
, which
;
21483 unsigned char orig_perm
[MAX_VECT_LEN
];
21491 gcc_assert (VECTOR_MODE_P (vmode
));
21492 d
.nelt
= nelt
= GET_MODE_NUNITS (vmode
);
21493 d
.testing_p
= !target
;
21495 /* This is overly conservative, but ensures we don't get an
21496 uninitialized warning on ORIG_PERM. */
21497 memset (orig_perm
, 0, MAX_VECT_LEN
);
21498 for (i
= which
= 0; i
< nelt
; ++i
)
21500 int ei
= sel
[i
] & (2 * nelt
- 1);
21501 which
|= (ei
< nelt
? 1 : 2);
21504 memcpy (d
.perm
, orig_perm
, MAX_VECT_LEN
);
21512 d
.one_vector_p
= false;
21513 if (d
.testing_p
|| !rtx_equal_p (d
.op0
, d
.op1
))
21518 for (i
= 0; i
< nelt
; ++i
)
21519 d
.perm
[i
] &= nelt
- 1;
21521 d
.one_vector_p
= true;
21526 d
.one_vector_p
= true;
21532 d
.target
= gen_raw_REG (d
.vmode
, LAST_VIRTUAL_REGISTER
+ 1);
21533 d
.op1
= d
.op0
= gen_raw_REG (d
.vmode
, LAST_VIRTUAL_REGISTER
+ 2);
21534 if (!d
.one_vector_p
)
21535 d
.op1
= gen_raw_REG (d
.vmode
, LAST_VIRTUAL_REGISTER
+ 3);
21538 ok
= mips_expand_vec_perm_const_1 (&d
);
21543 ok
= mips_expand_vec_perm_const_1 (&d
);
21545 /* If we were given a two-vector permutation which just happened to
21546 have both input vectors equal, we folded this into a one-vector
21547 permutation. There are several loongson patterns that are matched
21548 via direct vec_select+vec_concat expansion, but we do not have
21549 support in mips_expand_vec_perm_const_1 to guess the adjustment
21550 that should be made for a single operand. Just try again with
21551 the original permutation. */
21552 if (!ok
&& which
== 3)
21556 d
.one_vector_p
= false;
21557 memcpy (d
.perm
, orig_perm
, MAX_VECT_LEN
);
21558 ok
= mips_expand_vec_perm_const_1 (&d
);
21564 /* Implement TARGET_SCHED_REASSOCIATION_WIDTH. */
21567 mips_sched_reassociation_width (unsigned int opc ATTRIBUTE_UNUSED
,
21570 if (MSA_SUPPORTED_MODE_P (mode
))
21575 /* Expand an integral vector unpack operation. */
21578 mips_expand_vec_unpack (rtx operands
[2], bool unsigned_p
, bool high_p
)
21580 machine_mode imode
= GET_MODE (operands
[1]);
21581 rtx (*unpack
) (rtx
, rtx
, rtx
);
21582 rtx (*cmpFunc
) (rtx
, rtx
, rtx
);
21583 rtx tmp
, dest
, zero
;
21590 if (BYTES_BIG_ENDIAN
!= high_p
)
21591 unpack
= gen_msa_ilvl_w
;
21593 unpack
= gen_msa_ilvr_w
;
21595 cmpFunc
= gen_msa_clt_s_w
;
21599 if (BYTES_BIG_ENDIAN
!= high_p
)
21600 unpack
= gen_msa_ilvl_h
;
21602 unpack
= gen_msa_ilvr_h
;
21604 cmpFunc
= gen_msa_clt_s_h
;
21608 if (BYTES_BIG_ENDIAN
!= high_p
)
21609 unpack
= gen_msa_ilvl_b
;
21611 unpack
= gen_msa_ilvr_b
;
21613 cmpFunc
= gen_msa_clt_s_b
;
21617 gcc_unreachable ();
21623 /* Extract sign extention for each element comparing each element
21624 with immediate zero. */
21625 tmp
= gen_reg_rtx (imode
);
21626 emit_insn (cmpFunc (tmp
, operands
[1], CONST0_RTX (imode
)));
21629 tmp
= force_reg (imode
, CONST0_RTX (imode
));
21631 dest
= gen_reg_rtx (imode
);
21633 emit_insn (unpack (dest
, operands
[1], tmp
));
21634 emit_move_insn (operands
[0], gen_lowpart (GET_MODE (operands
[0]), dest
));
21642 unpack
= gen_loongson_punpckhbh
;
21644 unpack
= gen_loongson_punpcklbh
;
21645 cmpFunc
= gen_loongson_pcmpgtb
;
21649 unpack
= gen_loongson_punpckhhw
;
21651 unpack
= gen_loongson_punpcklhw
;
21652 cmpFunc
= gen_loongson_pcmpgth
;
21655 gcc_unreachable ();
21658 zero
= force_reg (imode
, CONST0_RTX (imode
));
21663 tmp
= gen_reg_rtx (imode
);
21664 emit_insn (cmpFunc (tmp
, zero
, operands
[1]));
21667 dest
= gen_reg_rtx (imode
);
21668 emit_insn (unpack (dest
, operands
[1], tmp
));
21670 emit_move_insn (operands
[0], gen_lowpart (GET_MODE (operands
[0]), dest
));
21673 /* Construct and return PARALLEL RTX with CONST_INTs for HIGH (high_p == TRUE)
21674 or LOW (high_p == FALSE) half of a vector for mode MODE. */
21677 mips_msa_vec_parallel_const_half (machine_mode mode
, bool high_p
)
21679 int nunits
= GET_MODE_NUNITS (mode
);
21680 rtvec v
= rtvec_alloc (nunits
/ 2);
21684 if (BYTES_BIG_ENDIAN
)
21685 base
= high_p
? 0 : nunits
/ 2;
21687 base
= high_p
? nunits
/ 2 : 0;
21689 for (i
= 0; i
< nunits
/ 2; i
++)
21690 RTVEC_ELT (v
, i
) = GEN_INT (base
+ i
);
21692 return gen_rtx_PARALLEL (VOIDmode
, v
);
21695 /* A subroutine of mips_expand_vec_init, match constant vector elements. */
21698 mips_constant_elt_p (rtx x
)
21700 return CONST_INT_P (x
) || GET_CODE (x
) == CONST_DOUBLE
;
21703 /* A subroutine of mips_expand_vec_init, expand via broadcast. */
21706 mips_expand_vi_broadcast (machine_mode vmode
, rtx target
, rtx elt
)
21708 struct expand_vec_perm_d d
;
21712 if (elt
!= const0_rtx
)
21713 elt
= force_reg (GET_MODE_INNER (vmode
), elt
);
21715 elt
= gen_lowpart (DImode
, elt
);
21717 t1
= gen_reg_rtx (vmode
);
21721 emit_insn (gen_loongson_vec_init1_v8qi (t1
, elt
));
21724 emit_insn (gen_loongson_vec_init1_v4hi (t1
, elt
));
21727 gcc_unreachable ();
21730 memset (&d
, 0, sizeof (d
));
21735 d
.nelt
= GET_MODE_NUNITS (vmode
);
21736 d
.one_vector_p
= true;
21738 ok
= mips_expand_vec_perm_const_1 (&d
);
21742 /* Return a const_int vector of VAL with mode MODE. */
21745 mips_gen_const_int_vector (machine_mode mode
, HOST_WIDE_INT val
)
21747 rtx c
= gen_int_mode (val
, GET_MODE_INNER (mode
));
21748 return gen_const_vec_duplicate (mode
, c
);
21751 /* Return a vector of repeated 4-element sets generated from
21752 immediate VAL in mode MODE. */
21755 mips_gen_const_int_vector_shuffle (machine_mode mode
, int val
)
21757 int nunits
= GET_MODE_NUNITS (mode
);
21758 int nsets
= nunits
/ 4;
21759 rtx elts
[MAX_VECT_LEN
];
21763 /* Generate a const_int vector replicating the same 4-element set
21764 from an immediate. */
21765 for (j
= 0; j
< nsets
; j
++, set
= 4 * j
)
21766 for (i
= 0; i
< 4; i
++)
21767 elts
[set
+ i
] = GEN_INT (set
+ ((val
>> (2 * i
)) & 0x3));
21769 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec_v (nunits
, elts
));
21772 /* A subroutine of mips_expand_vec_init, replacing all of the non-constant
21773 elements of VALS with zeros, copy the constant vector to TARGET. */
21776 mips_expand_vi_constant (machine_mode vmode
, unsigned nelt
,
21777 rtx target
, rtx vals
)
21779 rtvec vec
= shallow_copy_rtvec (XVEC (vals
, 0));
21782 for (i
= 0; i
< nelt
; ++i
)
21784 rtx elem
= RTVEC_ELT (vec
, i
);
21785 if (!mips_constant_elt_p (elem
))
21786 RTVEC_ELT (vec
, i
) = CONST0_RTX (GET_MODE (elem
));
21789 emit_move_insn (target
, gen_rtx_CONST_VECTOR (vmode
, vec
));
21793 /* A subroutine of mips_expand_vec_init, expand via pinsrh. */
21796 mips_expand_vi_loongson_one_pinsrh (rtx target
, rtx vals
, unsigned one_var
)
21798 mips_expand_vi_constant (V4HImode
, 4, target
, vals
);
21800 emit_insn (gen_vec_setv4hi (target
, target
, XVECEXP (vals
, 0, one_var
),
21801 GEN_INT (one_var
)));
21804 /* A subroutine of mips_expand_vec_init, expand anything via memory. */
21807 mips_expand_vi_general (machine_mode vmode
, machine_mode imode
,
21808 unsigned nelt
, unsigned nvar
, rtx target
, rtx vals
)
21810 rtx mem
= assign_stack_temp (vmode
, GET_MODE_SIZE (vmode
));
21811 unsigned int i
, isize
= GET_MODE_SIZE (imode
);
21814 mips_expand_vi_constant (vmode
, nelt
, mem
, vals
);
21816 for (i
= 0; i
< nelt
; ++i
)
21818 rtx x
= XVECEXP (vals
, 0, i
);
21819 if (!mips_constant_elt_p (x
))
21820 emit_move_insn (adjust_address (mem
, imode
, i
* isize
), x
);
21823 emit_move_insn (target
, mem
);
21826 /* Expand a vector initialization. */
21829 mips_expand_vector_init (rtx target
, rtx vals
)
21831 machine_mode vmode
= GET_MODE (target
);
21832 machine_mode imode
= GET_MODE_INNER (vmode
);
21833 unsigned i
, nelt
= GET_MODE_NUNITS (vmode
);
21834 unsigned nvar
= 0, one_var
= -1u;
21835 bool all_same
= true;
21838 for (i
= 0; i
< nelt
; ++i
)
21840 x
= XVECEXP (vals
, 0, i
);
21841 if (!mips_constant_elt_p (x
))
21842 nvar
++, one_var
= i
;
21843 if (i
> 0 && !rtx_equal_p (x
, XVECEXP (vals
, 0, 0)))
21851 rtx same
= XVECEXP (vals
, 0, 0);
21854 if (CONST_INT_P (same
) && nvar
== 0
21855 && mips_signed_immediate_p (INTVAL (same
), 10, 0))
21863 temp
= gen_rtx_CONST_VECTOR (vmode
, XVEC (vals
, 0));
21864 emit_move_insn (target
, temp
);
21868 gcc_unreachable ();
21871 temp
= gen_reg_rtx (imode
);
21872 if (imode
== GET_MODE (same
))
21874 else if (GET_MODE_SIZE (imode
) >= UNITS_PER_WORD
)
21875 temp2
= simplify_gen_subreg (imode
, same
, GET_MODE (same
), 0);
21877 temp2
= lowpart_subreg (imode
, same
, GET_MODE (same
));
21878 emit_move_insn (temp
, temp2
);
21886 mips_emit_move (target
, gen_rtx_VEC_DUPLICATE (vmode
, temp
));
21890 emit_insn (gen_msa_splati_w_f_scalar (target
, temp
));
21894 emit_insn (gen_msa_splati_d_f_scalar (target
, temp
));
21898 gcc_unreachable ();
21903 emit_move_insn (target
, CONST0_RTX (vmode
));
21905 for (i
= 0; i
< nelt
; ++i
)
21907 rtx temp
= gen_reg_rtx (imode
);
21908 emit_move_insn (temp
, XVECEXP (vals
, 0, i
));
21912 emit_insn (gen_vec_setv16qi (target
, temp
, GEN_INT (i
)));
21916 emit_insn (gen_vec_setv8hi (target
, temp
, GEN_INT (i
)));
21920 emit_insn (gen_vec_setv4si (target
, temp
, GEN_INT (i
)));
21924 emit_insn (gen_vec_setv2di (target
, temp
, GEN_INT (i
)));
21928 emit_insn (gen_vec_setv4sf (target
, temp
, GEN_INT (i
)));
21932 emit_insn (gen_vec_setv2df (target
, temp
, GEN_INT (i
)));
21936 gcc_unreachable ();
21943 /* Load constants from the pool, or whatever's handy. */
21946 emit_move_insn (target
, gen_rtx_CONST_VECTOR (vmode
, XVEC (vals
, 0)));
21950 /* For two-part initialization, always use CONCAT. */
21953 rtx op0
= force_reg (imode
, XVECEXP (vals
, 0, 0));
21954 rtx op1
= force_reg (imode
, XVECEXP (vals
, 0, 1));
21955 x
= gen_rtx_VEC_CONCAT (vmode
, op0
, op1
);
21956 emit_insn (gen_rtx_SET (target
, x
));
21960 /* Loongson is the only cpu with vectors with more elements. */
21961 gcc_assert (TARGET_HARD_FLOAT
&& TARGET_LOONGSON_VECTORS
);
21963 /* If all values are identical, broadcast the value. */
21966 mips_expand_vi_broadcast (vmode
, target
, XVECEXP (vals
, 0, 0));
21970 /* If we've only got one non-variable V4HImode, use PINSRH. */
21971 if (nvar
== 1 && vmode
== V4HImode
)
21973 mips_expand_vi_loongson_one_pinsrh (target
, vals
, one_var
);
21977 mips_expand_vi_general (vmode
, imode
, nelt
, nvar
, target
, vals
);
21980 /* Expand a vector reduction. */
21983 mips_expand_vec_reduc (rtx target
, rtx in
, rtx (*gen
)(rtx
, rtx
, rtx
))
21985 machine_mode vmode
= GET_MODE (in
);
21986 unsigned char perm2
[2];
21987 rtx last
, next
, fold
, x
;
21991 fold
= gen_reg_rtx (vmode
);
21995 /* Use PUL/PLU to produce { L, H } op { H, L }.
21996 By reversing the pair order, rather than a pure interleave high,
21997 we avoid erroneous exceptional conditions that we might otherwise
21998 produce from the computation of H op H. */
22001 ok
= mips_expand_vselect_vconcat (fold
, last
, last
, perm2
, 2);
22006 /* Use interleave to produce { H, L } op { H, H }. */
22007 emit_insn (gen_loongson_punpckhwd (fold
, last
, last
));
22011 /* Perform the first reduction with interleave,
22012 and subsequent reductions with shifts. */
22013 emit_insn (gen_loongson_punpckhwd_hi (fold
, last
, last
));
22015 next
= gen_reg_rtx (vmode
);
22016 emit_insn (gen (next
, last
, fold
));
22019 fold
= gen_reg_rtx (vmode
);
22020 x
= force_reg (SImode
, GEN_INT (16));
22021 emit_insn (gen_vec_shr_v4hi (fold
, last
, x
));
22025 emit_insn (gen_loongson_punpckhwd_qi (fold
, last
, last
));
22027 next
= gen_reg_rtx (vmode
);
22028 emit_insn (gen (next
, last
, fold
));
22031 fold
= gen_reg_rtx (vmode
);
22032 x
= force_reg (SImode
, GEN_INT (16));
22033 emit_insn (gen_vec_shr_v8qi (fold
, last
, x
));
22035 next
= gen_reg_rtx (vmode
);
22036 emit_insn (gen (next
, last
, fold
));
22039 fold
= gen_reg_rtx (vmode
);
22040 x
= force_reg (SImode
, GEN_INT (8));
22041 emit_insn (gen_vec_shr_v8qi (fold
, last
, x
));
22045 gcc_unreachable ();
22048 emit_insn (gen (target
, last
, fold
));
22051 /* Expand a vector minimum/maximum. */
22054 mips_expand_vec_minmax (rtx target
, rtx op0
, rtx op1
,
22055 rtx (*cmp
) (rtx
, rtx
, rtx
), bool min_p
)
22057 machine_mode vmode
= GET_MODE (target
);
22060 tc
= gen_reg_rtx (vmode
);
22061 t0
= gen_reg_rtx (vmode
);
22062 t1
= gen_reg_rtx (vmode
);
22065 emit_insn (cmp (tc
, op0
, op1
));
22067 x
= gen_rtx_AND (vmode
, tc
, (min_p
? op1
: op0
));
22068 emit_insn (gen_rtx_SET (t0
, x
));
22070 x
= gen_rtx_NOT (vmode
, tc
);
22071 x
= gen_rtx_AND (vmode
, x
, (min_p
? op0
: op1
));
22072 emit_insn (gen_rtx_SET (t1
, x
));
22074 x
= gen_rtx_IOR (vmode
, t0
, t1
);
22075 emit_insn (gen_rtx_SET (target
, x
));
22078 /* Implement HARD_REGNO_CALLER_SAVE_MODE. */
22081 mips_hard_regno_caller_save_mode (unsigned int regno
,
22082 unsigned int nregs
,
22085 /* For performance, avoid saving/restoring upper parts of a register
22086 by returning MODE as save mode when the mode is known. */
22087 if (mode
== VOIDmode
)
22088 return choose_hard_reg_mode (regno
, nregs
, false);
22093 /* Generate RTL for comparing CMP_OP0 and CMP_OP1 using condition COND and
22094 store the result -1 or 0 in DEST. */
22097 mips_expand_msa_cmp (rtx dest
, enum rtx_code cond
, rtx op0
, rtx op1
)
22099 machine_mode cmp_mode
= GET_MODE (op0
);
22101 bool negate
= false;
22112 cond
= reverse_condition (cond
);
22125 std::swap (op0
, op1
);
22126 cond
= swap_condition (cond
);
22129 gcc_unreachable ();
22131 mips_emit_binary (cond
, dest
, op0
, op1
);
22133 emit_move_insn (dest
, gen_rtx_NOT (GET_MODE (dest
), dest
));
22148 case LTGT
: cond
= NE
; break;
22149 case UNGE
: cond
= UNLE
; std::swap (op0
, op1
); break;
22150 case UNGT
: cond
= UNLT
; std::swap (op0
, op1
); break;
22151 case LE
: unspec
= UNSPEC_MSA_FSLE
; break;
22152 case LT
: unspec
= UNSPEC_MSA_FSLT
; break;
22153 case GE
: unspec
= UNSPEC_MSA_FSLE
; std::swap (op0
, op1
); break;
22154 case GT
: unspec
= UNSPEC_MSA_FSLT
; std::swap (op0
, op1
); break;
22156 gcc_unreachable ();
22159 mips_emit_binary (cond
, dest
, op0
, op1
);
22162 rtx x
= gen_rtx_UNSPEC (GET_MODE (dest
),
22163 gen_rtvec (2, op0
, op1
), unspec
);
22164 emit_insn (gen_rtx_SET (dest
, x
));
22169 gcc_unreachable ();
22174 /* Expand VEC_COND_EXPR, where:
22175 MODE is mode of the result
22176 VIMODE equivalent integer mode
22177 OPERANDS operands of VEC_COND_EXPR. */
22180 mips_expand_vec_cond_expr (machine_mode mode
, machine_mode vimode
,
22183 rtx cond
= operands
[3];
22184 rtx cmp_op0
= operands
[4];
22185 rtx cmp_op1
= operands
[5];
22186 rtx cmp_res
= gen_reg_rtx (vimode
);
22188 mips_expand_msa_cmp (cmp_res
, GET_CODE (cond
), cmp_op0
, cmp_op1
);
22190 /* We handle the following cases:
22191 1) r = a CMP b ? -1 : 0
22192 2) r = a CMP b ? -1 : v
22193 3) r = a CMP b ? v : 0
22194 4) r = a CMP b ? v1 : v2 */
22196 /* Case (1) above. We only move the results. */
22197 if (operands
[1] == CONSTM1_RTX (vimode
)
22198 && operands
[2] == CONST0_RTX (vimode
))
22199 emit_move_insn (operands
[0], cmp_res
);
22202 rtx src1
= gen_reg_rtx (vimode
);
22203 rtx src2
= gen_reg_rtx (vimode
);
22204 rtx mask
= gen_reg_rtx (vimode
);
22207 /* Move the vector result to use it as a mask. */
22208 emit_move_insn (mask
, cmp_res
);
22210 if (register_operand (operands
[1], mode
))
22212 rtx xop1
= operands
[1];
22213 if (mode
!= vimode
)
22215 xop1
= gen_reg_rtx (vimode
);
22216 emit_move_insn (xop1
, gen_rtx_SUBREG (vimode
, operands
[1], 0));
22218 emit_move_insn (src1
, xop1
);
22222 gcc_assert (operands
[1] == CONSTM1_RTX (vimode
));
22223 /* Case (2) if the below doesn't move the mask to src2. */
22224 emit_move_insn (src1
, mask
);
22227 if (register_operand (operands
[2], mode
))
22229 rtx xop2
= operands
[2];
22230 if (mode
!= vimode
)
22232 xop2
= gen_reg_rtx (vimode
);
22233 emit_move_insn (xop2
, gen_rtx_SUBREG (vimode
, operands
[2], 0));
22235 emit_move_insn (src2
, xop2
);
22239 gcc_assert (operands
[2] == CONST0_RTX (mode
));
22240 /* Case (3) if the above didn't move the mask to src1. */
22241 emit_move_insn (src2
, mask
);
22244 /* We deal with case (4) if the mask wasn't moved to either src1 or src2.
22245 In any case, we eventually do vector mask-based copy. */
22246 bsel
= gen_rtx_IOR (vimode
,
22247 gen_rtx_AND (vimode
,
22248 gen_rtx_NOT (vimode
, mask
), src2
),
22249 gen_rtx_AND (vimode
, mask
, src1
));
22250 /* The result is placed back to a register with the mask. */
22251 emit_insn (gen_rtx_SET (mask
, bsel
));
22252 emit_move_insn (operands
[0], gen_rtx_SUBREG (mode
, mask
, 0));
22256 /* Implement TARGET_CASE_VALUES_THRESHOLD. */
22259 mips_case_values_threshold (void)
22261 /* In MIPS16 mode using a larger case threshold generates smaller code. */
22262 if (TARGET_MIPS16
&& optimize_size
)
22265 return default_case_values_threshold ();
22268 /* Implement TARGET_ATOMIC_ASSIGN_EXPAND_FENV. */
22271 mips_atomic_assign_expand_fenv (tree
*hold
, tree
*clear
, tree
*update
)
22273 if (!TARGET_HARD_FLOAT_ABI
)
22275 tree exceptions_var
= create_tmp_var_raw (MIPS_ATYPE_USI
);
22276 tree fcsr_orig_var
= create_tmp_var_raw (MIPS_ATYPE_USI
);
22277 tree fcsr_mod_var
= create_tmp_var_raw (MIPS_ATYPE_USI
);
22278 tree get_fcsr
= mips_builtin_decls
[MIPS_GET_FCSR
];
22279 tree set_fcsr
= mips_builtin_decls
[MIPS_SET_FCSR
];
22280 tree get_fcsr_hold_call
= build_call_expr (get_fcsr
, 0);
22281 tree hold_assign_orig
= build2 (MODIFY_EXPR
, MIPS_ATYPE_USI
,
22282 fcsr_orig_var
, get_fcsr_hold_call
);
22283 tree hold_mod_val
= build2 (BIT_AND_EXPR
, MIPS_ATYPE_USI
, fcsr_orig_var
,
22284 build_int_cst (MIPS_ATYPE_USI
, 0xfffff003));
22285 tree hold_assign_mod
= build2 (MODIFY_EXPR
, MIPS_ATYPE_USI
,
22286 fcsr_mod_var
, hold_mod_val
);
22287 tree set_fcsr_hold_call
= build_call_expr (set_fcsr
, 1, fcsr_mod_var
);
22288 tree hold_all
= build2 (COMPOUND_EXPR
, MIPS_ATYPE_USI
,
22289 hold_assign_orig
, hold_assign_mod
);
22290 *hold
= build2 (COMPOUND_EXPR
, void_type_node
, hold_all
,
22291 set_fcsr_hold_call
);
22293 *clear
= build_call_expr (set_fcsr
, 1, fcsr_mod_var
);
22295 tree get_fcsr_update_call
= build_call_expr (get_fcsr
, 0);
22296 *update
= build2 (MODIFY_EXPR
, MIPS_ATYPE_USI
,
22297 exceptions_var
, get_fcsr_update_call
);
22298 tree set_fcsr_update_call
= build_call_expr (set_fcsr
, 1, fcsr_orig_var
);
22299 *update
= build2 (COMPOUND_EXPR
, void_type_node
, *update
,
22300 set_fcsr_update_call
);
22301 tree atomic_feraiseexcept
22302 = builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT
);
22303 tree int_exceptions_var
= fold_convert (integer_type_node
,
22305 tree atomic_feraiseexcept_call
= build_call_expr (atomic_feraiseexcept
,
22306 1, int_exceptions_var
);
22307 *update
= build2 (COMPOUND_EXPR
, void_type_node
, *update
,
22308 atomic_feraiseexcept_call
);
22311 /* Implement TARGET_SPILL_CLASS. */
22314 mips_spill_class (reg_class_t rclass ATTRIBUTE_UNUSED
,
22315 machine_mode mode ATTRIBUTE_UNUSED
)
22322 /* Implement TARGET_LRA_P. */
22327 return mips_lra_flag
;
22330 /* Implement TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS. */
22333 mips_ira_change_pseudo_allocno_class (int regno
, reg_class_t allocno_class
,
22334 reg_class_t best_class ATTRIBUTE_UNUSED
)
22336 /* LRA will allocate an FPR for an integer mode pseudo instead of spilling
22337 to memory if an FPR is present in the allocno class. It is rare that
22338 we actually need to place an integer mode value in an FPR so where
22339 possible limit the allocation to GR_REGS. This will slightly pessimize
22340 code that involves integer to/from float conversions as these will have
22341 to reload into FPRs in LRA. Such reloads are sometimes eliminated and
22342 sometimes only partially eliminated. We choose to take this penalty
22343 in order to eliminate usage of FPRs in code that does not use floating
22346 This change has a similar effect to increasing the cost of FPR->GPR
22347 register moves for integer modes so that they are higher than the cost
22348 of memory but changing the allocno class is more reliable.
22350 This is also similar to forbidding integer mode values in FPRs entirely
22351 but this would lead to an inconsistency in the integer to/from float
22352 instructions that say integer mode values must be placed in FPRs. */
22353 if (INTEGRAL_MODE_P (PSEUDO_REGNO_MODE (regno
)) && allocno_class
== ALL_REGS
)
22355 return allocno_class
;
22358 /* Implement TARGET_PROMOTE_FUNCTION_MODE */
22360 /* This function is equivalent to default_promote_function_mode_always_promote
22361 except that it returns a promoted mode even if type is NULL_TREE. This is
22362 needed by libcalls which have no type (only a mode) such as fixed conversion
22363 routines that take a signed or unsigned char/short argument and convert it
22364 to a fixed type. */
22366 static machine_mode
22367 mips_promote_function_mode (const_tree type ATTRIBUTE_UNUSED
,
22369 int *punsignedp ATTRIBUTE_UNUSED
,
22370 const_tree fntype ATTRIBUTE_UNUSED
,
22371 int for_return ATTRIBUTE_UNUSED
)
22375 if (type
!= NULL_TREE
)
22376 return promote_mode (type
, mode
, punsignedp
);
22378 unsignedp
= *punsignedp
;
22379 PROMOTE_MODE (mode
, unsignedp
, type
);
22380 *punsignedp
= unsignedp
;
22384 /* Implement TARGET_TRULY_NOOP_TRUNCATION. */
22387 mips_truly_noop_truncation (poly_uint64 outprec
, poly_uint64 inprec
)
22389 return !TARGET_64BIT
|| inprec
<= 32 || outprec
> 32;
22392 /* Implement TARGET_CONSTANT_ALIGNMENT. */
22394 static HOST_WIDE_INT
22395 mips_constant_alignment (const_tree exp
, HOST_WIDE_INT align
)
22397 if (TREE_CODE (exp
) == STRING_CST
|| TREE_CODE (exp
) == CONSTRUCTOR
)
22398 return MAX (align
, BITS_PER_WORD
);
22402 /* Implement the TARGET_ASAN_SHADOW_OFFSET hook. */
22404 static unsigned HOST_WIDE_INT
22405 mips_asan_shadow_offset (void)
22410 /* Implement TARGET_STARTING_FRAME_OFFSET. See mips_compute_frame_info
22411 for details about the frame layout. */
22413 static HOST_WIDE_INT
22414 mips_starting_frame_offset (void)
22416 if (FRAME_GROWS_DOWNWARD
)
22418 return crtl
->outgoing_args_size
+ MIPS_GP_SAVE_AREA_SIZE
;
22421 /* Initialize the GCC target structure. */
22422 #undef TARGET_ASM_ALIGNED_HI_OP
22423 #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
22424 #undef TARGET_ASM_ALIGNED_SI_OP
22425 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
22426 #undef TARGET_ASM_ALIGNED_DI_OP
22427 #define TARGET_ASM_ALIGNED_DI_OP "\t.dword\t"
22429 #undef TARGET_OPTION_OVERRIDE
22430 #define TARGET_OPTION_OVERRIDE mips_option_override
22432 #undef TARGET_LEGITIMIZE_ADDRESS
22433 #define TARGET_LEGITIMIZE_ADDRESS mips_legitimize_address
22435 #undef TARGET_ASM_FUNCTION_PROLOGUE
22436 #define TARGET_ASM_FUNCTION_PROLOGUE mips_output_function_prologue
22437 #undef TARGET_ASM_FUNCTION_EPILOGUE
22438 #define TARGET_ASM_FUNCTION_EPILOGUE mips_output_function_epilogue
22439 #undef TARGET_ASM_SELECT_RTX_SECTION
22440 #define TARGET_ASM_SELECT_RTX_SECTION mips_select_rtx_section
22441 #undef TARGET_ASM_FUNCTION_RODATA_SECTION
22442 #define TARGET_ASM_FUNCTION_RODATA_SECTION mips_function_rodata_section
22444 #undef TARGET_SCHED_INIT
22445 #define TARGET_SCHED_INIT mips_sched_init
22446 #undef TARGET_SCHED_REORDER
22447 #define TARGET_SCHED_REORDER mips_sched_reorder
22448 #undef TARGET_SCHED_REORDER2
22449 #define TARGET_SCHED_REORDER2 mips_sched_reorder2
22450 #undef TARGET_SCHED_VARIABLE_ISSUE
22451 #define TARGET_SCHED_VARIABLE_ISSUE mips_variable_issue
22452 #undef TARGET_SCHED_ADJUST_COST
22453 #define TARGET_SCHED_ADJUST_COST mips_adjust_cost
22454 #undef TARGET_SCHED_ISSUE_RATE
22455 #define TARGET_SCHED_ISSUE_RATE mips_issue_rate
22456 #undef TARGET_SCHED_INIT_DFA_POST_CYCLE_INSN
22457 #define TARGET_SCHED_INIT_DFA_POST_CYCLE_INSN mips_init_dfa_post_cycle_insn
22458 #undef TARGET_SCHED_DFA_POST_ADVANCE_CYCLE
22459 #define TARGET_SCHED_DFA_POST_ADVANCE_CYCLE mips_dfa_post_advance_cycle
22460 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
22461 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
22462 mips_multipass_dfa_lookahead
22463 #undef TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P
22464 #define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P \
22465 mips_small_register_classes_for_mode_p
22467 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
22468 #define TARGET_FUNCTION_OK_FOR_SIBCALL mips_function_ok_for_sibcall
22470 #undef TARGET_INSERT_ATTRIBUTES
22471 #define TARGET_INSERT_ATTRIBUTES mips_insert_attributes
22472 #undef TARGET_MERGE_DECL_ATTRIBUTES
22473 #define TARGET_MERGE_DECL_ATTRIBUTES mips_merge_decl_attributes
22474 #undef TARGET_CAN_INLINE_P
22475 #define TARGET_CAN_INLINE_P mips_can_inline_p
22476 #undef TARGET_SET_CURRENT_FUNCTION
22477 #define TARGET_SET_CURRENT_FUNCTION mips_set_current_function
22479 #undef TARGET_VALID_POINTER_MODE
22480 #define TARGET_VALID_POINTER_MODE mips_valid_pointer_mode
22481 #undef TARGET_REGISTER_MOVE_COST
22482 #define TARGET_REGISTER_MOVE_COST mips_register_move_cost
22483 #undef TARGET_REGISTER_PRIORITY
22484 #define TARGET_REGISTER_PRIORITY mips_register_priority
22485 #undef TARGET_MEMORY_MOVE_COST
22486 #define TARGET_MEMORY_MOVE_COST mips_memory_move_cost
22487 #undef TARGET_RTX_COSTS
22488 #define TARGET_RTX_COSTS mips_rtx_costs
22489 #undef TARGET_ADDRESS_COST
22490 #define TARGET_ADDRESS_COST mips_address_cost
22492 #undef TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P
22493 #define TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P mips_no_speculation_in_delay_slots_p
22495 #undef TARGET_IN_SMALL_DATA_P
22496 #define TARGET_IN_SMALL_DATA_P mips_in_small_data_p
22498 #undef TARGET_MACHINE_DEPENDENT_REORG
22499 #define TARGET_MACHINE_DEPENDENT_REORG mips_reorg
22501 #undef TARGET_PREFERRED_RELOAD_CLASS
22502 #define TARGET_PREFERRED_RELOAD_CLASS mips_preferred_reload_class
22504 #undef TARGET_EXPAND_TO_RTL_HOOK
22505 #define TARGET_EXPAND_TO_RTL_HOOK mips_expand_to_rtl_hook
22506 #undef TARGET_ASM_FILE_START
22507 #define TARGET_ASM_FILE_START mips_file_start
22508 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
22509 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
22510 #undef TARGET_ASM_CODE_END
22511 #define TARGET_ASM_CODE_END mips_code_end
22513 #undef TARGET_INIT_LIBFUNCS
22514 #define TARGET_INIT_LIBFUNCS mips_init_libfuncs
22516 #undef TARGET_BUILD_BUILTIN_VA_LIST
22517 #define TARGET_BUILD_BUILTIN_VA_LIST mips_build_builtin_va_list
22518 #undef TARGET_EXPAND_BUILTIN_VA_START
22519 #define TARGET_EXPAND_BUILTIN_VA_START mips_va_start
22520 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
22521 #define TARGET_GIMPLIFY_VA_ARG_EXPR mips_gimplify_va_arg_expr
22523 #undef TARGET_PROMOTE_FUNCTION_MODE
22524 #define TARGET_PROMOTE_FUNCTION_MODE mips_promote_function_mode
22525 #undef TARGET_FUNCTION_VALUE
22526 #define TARGET_FUNCTION_VALUE mips_function_value
22527 #undef TARGET_LIBCALL_VALUE
22528 #define TARGET_LIBCALL_VALUE mips_libcall_value
22529 #undef TARGET_FUNCTION_VALUE_REGNO_P
22530 #define TARGET_FUNCTION_VALUE_REGNO_P mips_function_value_regno_p
22531 #undef TARGET_RETURN_IN_MEMORY
22532 #define TARGET_RETURN_IN_MEMORY mips_return_in_memory
22533 #undef TARGET_RETURN_IN_MSB
22534 #define TARGET_RETURN_IN_MSB mips_return_in_msb
22536 #undef TARGET_ASM_OUTPUT_MI_THUNK
22537 #define TARGET_ASM_OUTPUT_MI_THUNK mips_output_mi_thunk
22538 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
22539 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
22541 #undef TARGET_PRINT_OPERAND
22542 #define TARGET_PRINT_OPERAND mips_print_operand
22543 #undef TARGET_PRINT_OPERAND_ADDRESS
22544 #define TARGET_PRINT_OPERAND_ADDRESS mips_print_operand_address
22545 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
22546 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P mips_print_operand_punct_valid_p
22548 #undef TARGET_SETUP_INCOMING_VARARGS
22549 #define TARGET_SETUP_INCOMING_VARARGS mips_setup_incoming_varargs
22550 #undef TARGET_STRICT_ARGUMENT_NAMING
22551 #define TARGET_STRICT_ARGUMENT_NAMING mips_strict_argument_naming
22552 #undef TARGET_MUST_PASS_IN_STACK
22553 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
22554 #undef TARGET_PASS_BY_REFERENCE
22555 #define TARGET_PASS_BY_REFERENCE mips_pass_by_reference
22556 #undef TARGET_CALLEE_COPIES
22557 #define TARGET_CALLEE_COPIES mips_callee_copies
22558 #undef TARGET_ARG_PARTIAL_BYTES
22559 #define TARGET_ARG_PARTIAL_BYTES mips_arg_partial_bytes
22560 #undef TARGET_FUNCTION_ARG
22561 #define TARGET_FUNCTION_ARG mips_function_arg
22562 #undef TARGET_FUNCTION_ARG_ADVANCE
22563 #define TARGET_FUNCTION_ARG_ADVANCE mips_function_arg_advance
22564 #undef TARGET_FUNCTION_ARG_PADDING
22565 #define TARGET_FUNCTION_ARG_PADDING mips_function_arg_padding
22566 #undef TARGET_FUNCTION_ARG_BOUNDARY
22567 #define TARGET_FUNCTION_ARG_BOUNDARY mips_function_arg_boundary
22568 #undef TARGET_GET_RAW_RESULT_MODE
22569 #define TARGET_GET_RAW_RESULT_MODE mips_get_reg_raw_mode
22570 #undef TARGET_GET_RAW_ARG_MODE
22571 #define TARGET_GET_RAW_ARG_MODE mips_get_reg_raw_mode
22573 #undef TARGET_MODE_REP_EXTENDED
22574 #define TARGET_MODE_REP_EXTENDED mips_mode_rep_extended
22576 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
22577 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
22578 mips_builtin_vectorized_function
22579 #undef TARGET_VECTOR_MODE_SUPPORTED_P
22580 #define TARGET_VECTOR_MODE_SUPPORTED_P mips_vector_mode_supported_p
22582 #undef TARGET_SCALAR_MODE_SUPPORTED_P
22583 #define TARGET_SCALAR_MODE_SUPPORTED_P mips_scalar_mode_supported_p
22585 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
22586 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE mips_preferred_simd_mode
22587 #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES
22588 #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES \
22589 mips_autovectorize_vector_sizes
22591 #undef TARGET_INIT_BUILTINS
22592 #define TARGET_INIT_BUILTINS mips_init_builtins
22593 #undef TARGET_BUILTIN_DECL
22594 #define TARGET_BUILTIN_DECL mips_builtin_decl
22595 #undef TARGET_EXPAND_BUILTIN
22596 #define TARGET_EXPAND_BUILTIN mips_expand_builtin
22598 #undef TARGET_HAVE_TLS
22599 #define TARGET_HAVE_TLS HAVE_AS_TLS
22601 #undef TARGET_CANNOT_FORCE_CONST_MEM
22602 #define TARGET_CANNOT_FORCE_CONST_MEM mips_cannot_force_const_mem
22604 #undef TARGET_LEGITIMATE_CONSTANT_P
22605 #define TARGET_LEGITIMATE_CONSTANT_P mips_legitimate_constant_p
22607 #undef TARGET_ENCODE_SECTION_INFO
22608 #define TARGET_ENCODE_SECTION_INFO mips_encode_section_info
22610 #undef TARGET_ATTRIBUTE_TABLE
22611 #define TARGET_ATTRIBUTE_TABLE mips_attribute_table
22612 /* All our function attributes are related to how out-of-line copies should
22613 be compiled or called. They don't in themselves prevent inlining. */
22614 #undef TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P
22615 #define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P hook_bool_const_tree_true
22617 #undef TARGET_EXTRA_LIVE_ON_ENTRY
22618 #define TARGET_EXTRA_LIVE_ON_ENTRY mips_extra_live_on_entry
22620 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
22621 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P mips_use_blocks_for_constant_p
22622 #undef TARGET_USE_ANCHORS_FOR_SYMBOL_P
22623 #define TARGET_USE_ANCHORS_FOR_SYMBOL_P mips_use_anchors_for_symbol_p
22625 #undef TARGET_COMP_TYPE_ATTRIBUTES
22626 #define TARGET_COMP_TYPE_ATTRIBUTES mips_comp_type_attributes
22628 #ifdef HAVE_AS_DTPRELWORD
22629 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
22630 #define TARGET_ASM_OUTPUT_DWARF_DTPREL mips_output_dwarf_dtprel
22632 #undef TARGET_DWARF_REGISTER_SPAN
22633 #define TARGET_DWARF_REGISTER_SPAN mips_dwarf_register_span
22634 #undef TARGET_DWARF_FRAME_REG_MODE
22635 #define TARGET_DWARF_FRAME_REG_MODE mips_dwarf_frame_reg_mode
22637 #undef TARGET_ASM_FINAL_POSTSCAN_INSN
22638 #define TARGET_ASM_FINAL_POSTSCAN_INSN mips_final_postscan_insn
22640 #undef TARGET_LEGITIMATE_ADDRESS_P
22641 #define TARGET_LEGITIMATE_ADDRESS_P mips_legitimate_address_p
22643 #undef TARGET_FRAME_POINTER_REQUIRED
22644 #define TARGET_FRAME_POINTER_REQUIRED mips_frame_pointer_required
22646 #undef TARGET_CAN_ELIMINATE
22647 #define TARGET_CAN_ELIMINATE mips_can_eliminate
22649 #undef TARGET_CONDITIONAL_REGISTER_USAGE
22650 #define TARGET_CONDITIONAL_REGISTER_USAGE mips_conditional_register_usage
22652 #undef TARGET_TRAMPOLINE_INIT
22653 #define TARGET_TRAMPOLINE_INIT mips_trampoline_init
22655 #undef TARGET_ASM_OUTPUT_SOURCE_FILENAME
22656 #define TARGET_ASM_OUTPUT_SOURCE_FILENAME mips_output_filename
22658 #undef TARGET_SHIFT_TRUNCATION_MASK
22659 #define TARGET_SHIFT_TRUNCATION_MASK mips_shift_truncation_mask
22661 #undef TARGET_PREPARE_PCH_SAVE
22662 #define TARGET_PREPARE_PCH_SAVE mips_prepare_pch_save
22664 #undef TARGET_VECTORIZE_VEC_PERM_CONST
22665 #define TARGET_VECTORIZE_VEC_PERM_CONST mips_vectorize_vec_perm_const
22667 #undef TARGET_SCHED_REASSOCIATION_WIDTH
22668 #define TARGET_SCHED_REASSOCIATION_WIDTH mips_sched_reassociation_width
22670 #undef TARGET_CASE_VALUES_THRESHOLD
22671 #define TARGET_CASE_VALUES_THRESHOLD mips_case_values_threshold
22673 #undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
22674 #define TARGET_ATOMIC_ASSIGN_EXPAND_FENV mips_atomic_assign_expand_fenv
22676 #undef TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS
22677 #define TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS true
22679 #undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
22680 #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
22681 mips_use_by_pieces_infrastructure_p
22683 #undef TARGET_SPILL_CLASS
22684 #define TARGET_SPILL_CLASS mips_spill_class
22685 #undef TARGET_LRA_P
22686 #define TARGET_LRA_P mips_lra_p
22687 #undef TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS
22688 #define TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS mips_ira_change_pseudo_allocno_class
22690 #undef TARGET_HARD_REGNO_SCRATCH_OK
22691 #define TARGET_HARD_REGNO_SCRATCH_OK mips_hard_regno_scratch_ok
22693 #undef TARGET_HARD_REGNO_NREGS
22694 #define TARGET_HARD_REGNO_NREGS mips_hard_regno_nregs
22695 #undef TARGET_HARD_REGNO_MODE_OK
22696 #define TARGET_HARD_REGNO_MODE_OK mips_hard_regno_mode_ok
22698 #undef TARGET_MODES_TIEABLE_P
22699 #define TARGET_MODES_TIEABLE_P mips_modes_tieable_p
22701 #undef TARGET_HARD_REGNO_CALL_PART_CLOBBERED
22702 #define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \
22703 mips_hard_regno_call_part_clobbered
22705 /* The architecture reserves bit 0 for MIPS16 so use bit 1 for descriptors. */
22706 #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
22707 #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 2
22709 #undef TARGET_SECONDARY_MEMORY_NEEDED
22710 #define TARGET_SECONDARY_MEMORY_NEEDED mips_secondary_memory_needed
22712 #undef TARGET_CAN_CHANGE_MODE_CLASS
22713 #define TARGET_CAN_CHANGE_MODE_CLASS mips_can_change_mode_class
22715 #undef TARGET_TRULY_NOOP_TRUNCATION
22716 #define TARGET_TRULY_NOOP_TRUNCATION mips_truly_noop_truncation
22718 #undef TARGET_CONSTANT_ALIGNMENT
22719 #define TARGET_CONSTANT_ALIGNMENT mips_constant_alignment
22721 #undef TARGET_ASAN_SHADOW_OFFSET
22722 #define TARGET_ASAN_SHADOW_OFFSET mips_asan_shadow_offset
22724 #undef TARGET_STARTING_FRAME_OFFSET
22725 #define TARGET_STARTING_FRAME_OFFSET mips_starting_frame_offset
22727 struct gcc_target targetm
= TARGET_INITIALIZER
;
22729 #include "gt-mips.h"