1 /* Subroutines used for MIPS code generation.
2 Copyright (C) 1989-2024 Free Software Foundation, Inc.
3 Contributed by A. Lichnewsky, lich@inria.inria.fr.
4 Changes by Michael Meissner, meissner@osf.org.
5 64-bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
6 Brendan Eich, brendan@microunity.com.
8 This file is part of GCC.
10 GCC is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3, or (at your option)
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"
71 /* This file should be included last. */
72 #include "target-def.h"
74 /* True if X is an UNSPEC wrapper around a SYMBOL_REF or LABEL_REF. */
75 #define UNSPEC_ADDRESS_P(X) \
76 (GET_CODE (X) == UNSPEC \
77 && XINT (X, 1) >= UNSPEC_ADDRESS_FIRST \
78 && XINT (X, 1) < UNSPEC_ADDRESS_FIRST + NUM_SYMBOL_TYPES)
80 /* Extract the symbol or label from UNSPEC wrapper X. */
81 #define UNSPEC_ADDRESS(X) \
84 /* Extract the symbol type from UNSPEC wrapper X. */
85 #define UNSPEC_ADDRESS_TYPE(X) \
86 ((enum mips_symbol_type) (XINT (X, 1) - UNSPEC_ADDRESS_FIRST))
88 /* The maximum distance between the top of the stack frame and the
89 value $sp has when we save and restore registers.
91 The value for normal-mode code must be a SMALL_OPERAND and must
92 preserve the maximum stack alignment. We therefore use a value
93 of 0x7ff0 in this case.
95 microMIPS LWM and SWM support 12-bit offsets (from -0x800 to 0x7ff),
96 so we use a maximum of 0x7f0 for TARGET_MICROMIPS.
98 MIPS16e SAVE and RESTORE instructions can adjust the stack pointer by
99 up to 0x7f8 bytes and can usually save or restore all the registers
100 that we need to save or restore. (Note that we can only use these
101 instructions for o32, for which the stack alignment is 8 bytes.)
103 We use a maximum gap of 0x100 or 0x400 for MIPS16 code when SAVE and
104 RESTORE are not available. We can then use unextended instructions
105 to save and restore registers, and to allocate and deallocate the top
106 part of the frame. */
107 #define MIPS_MAX_FIRST_STACK_STEP \
108 (!TARGET_COMPRESSION ? 0x7ff0 \
109 : TARGET_MICROMIPS || GENERATE_MIPS16E_SAVE_RESTORE ? 0x7f8 \
110 : TARGET_64BIT ? 0x100 : 0x400)
112 /* True if INSN is a mips.md pattern or asm statement. */
113 /* ??? This test exists through the compiler, perhaps it should be
115 #define USEFUL_INSN_P(INSN) \
116 (NONDEBUG_INSN_P (INSN) \
117 && GET_CODE (PATTERN (INSN)) != USE \
118 && GET_CODE (PATTERN (INSN)) != CLOBBER)
120 /* If INSN is a delayed branch sequence, return the first instruction
121 in the sequence, otherwise return INSN itself. */
122 #define SEQ_BEGIN(INSN) \
123 (INSN_P (INSN) && GET_CODE (PATTERN (INSN)) == SEQUENCE \
124 ? as_a <rtx_insn *> (XVECEXP (PATTERN (INSN), 0, 0)) \
127 /* Likewise for the last instruction in a delayed branch sequence. */
128 #define SEQ_END(INSN) \
129 (INSN_P (INSN) && GET_CODE (PATTERN (INSN)) == SEQUENCE \
130 ? as_a <rtx_insn *> (XVECEXP (PATTERN (INSN), \
132 XVECLEN (PATTERN (INSN), 0) - 1)) \
135 /* Execute the following loop body with SUBINSN set to each instruction
136 between SEQ_BEGIN (INSN) and SEQ_END (INSN) inclusive. */
137 #define FOR_EACH_SUBINSN(SUBINSN, INSN) \
138 for ((SUBINSN) = SEQ_BEGIN (INSN); \
139 (SUBINSN) != NEXT_INSN (SEQ_END (INSN)); \
140 (SUBINSN) = NEXT_INSN (SUBINSN))
142 /* True if bit BIT is set in VALUE. */
143 #define BITSET_P(VALUE, BIT) (((VALUE) & (1 << (BIT))) != 0)
145 /* Return the opcode for a ptr_mode load of the form:
147 l[wd] DEST, OFFSET(BASE). */
148 #define MIPS_LOAD_PTR(DEST, OFFSET, BASE) \
149 (((ptr_mode == DImode ? 0x37 : 0x23) << 26) \
154 /* Return the opcode to move register SRC into register DEST. */
155 #define MIPS_MOVE(DEST, SRC) \
156 ((TARGET_64BIT ? 0x2d : 0x21) \
160 /* Return the opcode for:
163 #define MIPS_LUI(DEST, VALUE) \
164 ((0xf << 26) | ((DEST) << 16) | (VALUE))
166 /* Return the opcode to jump to register DEST. When the JR opcode is not
167 available use JALR $0, DEST. */
168 #define MIPS_JR(DEST) \
169 (TARGET_CB_ALWAYS ? ((0x1b << 27) | ((DEST) << 16)) \
170 : (((DEST) << 21) | (ISA_HAS_JR ? 0x8 : 0x9)))
172 /* Return the opcode for:
174 bal . + (1 + OFFSET) * 4. */
175 #define MIPS_BAL(OFFSET) \
176 ((0x1 << 26) | (0x11 << 16) | (OFFSET))
178 /* Return the usual opcode for a nop. */
181 /* Classifies an address.
184 A natural register + offset address. The register satisfies
185 mips_valid_base_register_p and the offset is a const_arith_operand.
188 A LO_SUM rtx. The first operand is a valid base register and
189 the second operand is a symbolic address.
192 A signed 16-bit constant address.
195 A constant symbolic address. */
196 enum mips_address_type
{
203 /* Classifies an unconditional branch of interest for the P6600. */
205 enum mips_ucbranch_type
207 /* May not even be a branch. */
213 /* Macros to create an enumeration identifier for a function prototype. */
214 #define MIPS_FTYPE_NAME1(A, B) MIPS_##A##_FTYPE_##B
215 #define MIPS_FTYPE_NAME2(A, B, C) MIPS_##A##_FTYPE_##B##_##C
216 #define MIPS_FTYPE_NAME3(A, B, C, D) MIPS_##A##_FTYPE_##B##_##C##_##D
217 #define MIPS_FTYPE_NAME4(A, B, C, D, E) MIPS_##A##_FTYPE_##B##_##C##_##D##_##E
219 /* Classifies the prototype of a built-in function. */
220 enum mips_function_type
{
221 #define DEF_MIPS_FTYPE(NARGS, LIST) MIPS_FTYPE_NAME##NARGS LIST,
222 #include "config/mips/mips-ftypes.def"
223 #undef DEF_MIPS_FTYPE
227 /* Specifies how a built-in function should be converted into rtl. */
228 enum mips_builtin_type
{
229 /* The function corresponds directly to an .md pattern. The return
230 value is mapped to operand 0 and the arguments are mapped to
231 operands 1 and above. */
234 /* The function corresponds directly to an .md pattern. There is no return
235 value and the arguments are mapped to operands 0 and above. */
236 MIPS_BUILTIN_DIRECT_NO_TARGET
,
238 /* The function corresponds to a comparison instruction followed by
239 a mips_cond_move_tf_ps pattern. The first two arguments are the
240 values to compare and the second two arguments are the vector
241 operands for the movt.ps or movf.ps instruction (in assembly order). */
245 /* The function corresponds to a V2SF comparison instruction. Operand 0
246 of this instruction is the result of the comparison, which has mode
247 CCV2 or CCV4. The function arguments are mapped to operands 1 and
248 above. The function's return value is an SImode boolean that is
249 true under the following conditions:
251 MIPS_BUILTIN_CMP_ANY: one of the registers is true
252 MIPS_BUILTIN_CMP_ALL: all of the registers are true
253 MIPS_BUILTIN_CMP_LOWER: the first register is true
254 MIPS_BUILTIN_CMP_UPPER: the second register is true. */
255 MIPS_BUILTIN_CMP_ANY
,
256 MIPS_BUILTIN_CMP_ALL
,
257 MIPS_BUILTIN_CMP_UPPER
,
258 MIPS_BUILTIN_CMP_LOWER
,
260 /* As above, but the instruction only sets a single $fcc register. */
261 MIPS_BUILTIN_CMP_SINGLE
,
263 /* The function corresponds to an MSA conditional branch instruction
264 combined with a compare instruction. */
265 MIPS_BUILTIN_MSA_TEST_BRANCH
,
267 /* For generating bposge32 branch instructions in MIPS32 DSP ASE. */
268 MIPS_BUILTIN_BPOSGE32
271 /* Invoke MACRO (COND) for each C.cond.fmt condition. */
272 #define MIPS_FP_CONDITIONS(MACRO) \
290 /* Enumerates the codes above as MIPS_FP_COND_<X>. */
291 #define DECLARE_MIPS_COND(X) MIPS_FP_COND_ ## X
292 enum mips_fp_condition
{
293 MIPS_FP_CONDITIONS (DECLARE_MIPS_COND
)
295 #undef DECLARE_MIPS_COND
297 /* Index X provides the string representation of MIPS_FP_COND_<X>. */
298 #define STRINGIFY(X) #X
299 static const char *const mips_fp_conditions
[] = {
300 MIPS_FP_CONDITIONS (STRINGIFY
)
304 /* A class used to control a comdat-style stub that we output in each
305 translation unit that needs it. */
306 class mips_one_only_stub
{
308 virtual ~mips_one_only_stub () {}
310 /* Return the name of the stub. */
311 virtual const char *get_name () = 0;
313 /* Output the body of the function to asm_out_file. */
314 virtual void output_body () = 0;
317 /* Tuning information that is automatically derived from other sources
318 (such as the scheduler). */
320 /* The architecture and tuning settings that this structure describes. */
324 /* True if this structure describes MIPS16 settings. */
327 /* True if the structure has been initialized. */
330 /* True if "MULT $0, $0" is preferable to "MTLO $0; MTHI $0"
331 when optimizing for speed. */
332 bool fast_mult_zero_zero_p
;
335 /* Information about a single argument. */
336 struct mips_arg_info
{
337 /* True if the argument is passed in a floating-point register, or
338 would have been if we hadn't run out of registers. */
341 /* The number of words passed in registers, rounded up. */
342 unsigned int reg_words
;
344 /* For EABI, the offset of the first register from GP_ARG_FIRST or
345 FP_ARG_FIRST. For other ABIs, the offset of the first register from
346 the start of the ABI's argument structure (see the CUMULATIVE_ARGS
347 comment for details).
349 The value is MAX_ARGS_IN_REGISTERS if the argument is passed entirely
351 unsigned int reg_offset
;
353 /* The number of words that must be passed on the stack, rounded up. */
354 unsigned int stack_words
;
356 /* The offset from the start of the stack overflow area of the argument's
357 first stack word. Only meaningful when STACK_WORDS is nonzero. */
358 unsigned int stack_offset
;
361 /* Information about an address described by mips_address_type.
367 REG is the base register and OFFSET is the constant offset.
370 REG and OFFSET are the operands to the LO_SUM and SYMBOL_TYPE
371 is the type of symbol it references.
374 SYMBOL_TYPE is the type of symbol that the address references. */
375 struct mips_address_info
{
376 enum mips_address_type type
;
379 enum mips_symbol_type symbol_type
;
382 /* One stage in a constant building sequence. These sequences have
386 A = A CODE[1] VALUE[1]
387 A = A CODE[2] VALUE[2]
390 where A is an accumulator, each CODE[i] is a binary rtl operation
391 and each VALUE[i] is a constant integer. CODE[0] is undefined. */
392 struct mips_integer_op
{
394 unsigned HOST_WIDE_INT value
;
397 /* The largest number of operations needed to load an integer constant.
398 The worst accepted case for 64-bit constants is LUI,ORI,SLL,ORI,SLL,ORI.
399 When the lowest bit is clear, we can try, but reject a sequence with
400 an extra SLL at the end. */
401 #define MIPS_MAX_INTEGER_OPS 7
403 /* Information about a MIPS16e SAVE or RESTORE instruction. */
404 struct mips16e_save_restore_info
{
405 /* The number of argument registers saved by a SAVE instruction.
406 0 for RESTORE instructions. */
409 /* Bit X is set if the instruction saves or restores GPR X. */
412 /* The total number of bytes to allocate. */
416 /* Costs of various operations on the different architectures. */
418 struct mips_rtx_cost_data
420 unsigned short fp_add
;
421 unsigned short fp_mult_sf
;
422 unsigned short fp_mult_df
;
423 unsigned short fp_div_sf
;
424 unsigned short fp_div_df
;
425 unsigned short int_mult_si
;
426 unsigned short int_mult_di
;
427 unsigned short int_div_si
;
428 unsigned short int_div_di
;
429 unsigned short branch_cost
;
430 unsigned short memory_latency
;
433 /* Global variables for machine-dependent things. */
435 /* The -G setting, or the configuration's default small-data limit if
436 no -G option is given. */
437 static unsigned int mips_small_data_threshold
;
439 /* The number of file directives written by mips_output_filename. */
440 int num_source_filenames
;
442 /* The name that appeared in the last .file directive written by
443 mips_output_filename, or "" if mips_output_filename hasn't
444 written anything yet. */
445 const char *current_function_file
= "";
447 /* Arrays that map GCC register numbers to debugger register numbers. */
448 int mips_dwarf_regno
[FIRST_PSEUDO_REGISTER
];
450 /* Information about the current function's epilogue, used only while
453 /* A list of queued REG_CFA_RESTORE notes. */
456 /* The CFA is currently defined as CFA_REG + CFA_OFFSET. */
458 HOST_WIDE_INT cfa_offset
;
460 /* The offset of the CFA from the stack pointer while restoring
462 HOST_WIDE_INT cfa_restore_sp_offset
;
465 /* The nesting depth of the PRINT_OPERAND '%(', '%<' and '%[' constructs. */
466 struct mips_asm_switch mips_noreorder
= { "reorder", 0 };
467 struct mips_asm_switch mips_nomacro
= { "macro", 0 };
468 struct mips_asm_switch mips_noat
= { "at", 0 };
470 /* True if we're writing out a branch-likely instruction rather than a
472 static bool mips_branch_likely
;
474 /* The current instruction-set architecture. */
475 enum processor mips_arch
;
476 const struct mips_cpu_info
*mips_arch_info
;
478 /* The processor that we should tune the code for. */
479 enum processor mips_tune
;
480 const struct mips_cpu_info
*mips_tune_info
;
482 /* The ISA level associated with mips_arch. */
485 /* The ISA revision level. This is 0 for MIPS I to V and N for
489 /* The architecture selected by -mipsN, or null if -mipsN wasn't used. */
490 static const struct mips_cpu_info
*mips_isa_option_info
;
492 /* Which cost information to use. */
493 static const struct mips_rtx_cost_data
*mips_cost
;
495 /* The ambient target flags, excluding MASK_MIPS16. */
496 static int mips_base_target_flags
;
498 /* The default compression mode. */
499 unsigned int mips_base_compression_flags
;
501 /* The default code readable setting. */
502 enum mips_code_readable_setting mips_base_code_readable
;
504 /* The ambient values of other global variables. */
505 static int mips_base_schedule_insns
; /* flag_schedule_insns */
506 static int mips_base_reorder_blocks_and_partition
; /* flag_reorder... */
507 static int mips_base_move_loop_invariants
; /* flag_move_loop_invariants */
508 static const char *mips_base_align_loops
; /* align_loops */
509 static const char *mips_base_align_jumps
; /* align_jumps */
510 static const char *mips_base_align_functions
; /* align_functions */
512 /* Index [M][R] is true if register R is allowed to hold a value of mode M. */
513 static bool mips_hard_regno_mode_ok_p
[MAX_MACHINE_MODE
][FIRST_PSEUDO_REGISTER
];
515 /* Index C is true if character C is a valid PRINT_OPERAND punctation
517 static bool mips_print_operand_punct
[256];
519 static GTY (()) int mips_output_filename_first_time
= 1;
521 /* mips_split_p[X] is true if symbols of type X can be split by
522 mips_split_symbol. */
523 bool mips_split_p
[NUM_SYMBOL_TYPES
];
525 /* mips_split_hi_p[X] is true if the high parts of symbols of type X
526 can be split by mips_split_symbol. */
527 bool mips_split_hi_p
[NUM_SYMBOL_TYPES
];
529 /* mips_use_pcrel_pool_p[X] is true if symbols of type X should be
530 forced into a PC-relative constant pool. */
531 bool mips_use_pcrel_pool_p
[NUM_SYMBOL_TYPES
];
533 /* mips_lo_relocs[X] is the relocation to use when a symbol of type X
534 appears in a LO_SUM. It can be null if such LO_SUMs aren't valid or
535 if they are matched by a special .md file pattern. */
536 const char *mips_lo_relocs
[NUM_SYMBOL_TYPES
];
538 /* Likewise for HIGHs. */
539 const char *mips_hi_relocs
[NUM_SYMBOL_TYPES
];
541 /* Target state for MIPS16. */
542 struct target_globals
*mips16_globals
;
544 /* Target state for MICROMIPS. */
545 struct target_globals
*micromips_globals
;
547 /* Cached value of can_issue_more. This is cached in mips_variable_issue hook
548 and returned from mips_sched_reorder2. */
549 static int cached_can_issue_more
;
551 /* The stubs for various MIPS16 support functions, if used. */
552 static mips_one_only_stub
*mips16_rdhwr_stub
;
553 static mips_one_only_stub
*mips16_get_fcsr_stub
;
554 static mips_one_only_stub
*mips16_set_fcsr_stub
;
556 /* Index R is the smallest register class that contains register R. */
557 const enum reg_class mips_regno_to_class
[FIRST_PSEUDO_REGISTER
] = {
558 LEA_REGS
, LEA_REGS
, M16_STORE_REGS
, V1_REG
,
559 M16_STORE_REGS
, M16_STORE_REGS
, M16_STORE_REGS
, M16_STORE_REGS
,
560 LEA_REGS
, LEA_REGS
, LEA_REGS
, LEA_REGS
,
561 LEA_REGS
, LEA_REGS
, LEA_REGS
, LEA_REGS
,
562 M16_REGS
, M16_STORE_REGS
, LEA_REGS
, LEA_REGS
,
563 LEA_REGS
, LEA_REGS
, LEA_REGS
, LEA_REGS
,
564 T_REG
, PIC_FN_ADDR_REG
, LEA_REGS
, LEA_REGS
,
565 LEA_REGS
, M16_SP_REGS
, LEA_REGS
, LEA_REGS
,
567 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
568 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
569 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
570 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
571 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
572 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
573 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
574 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
575 MD0_REG
, MD1_REG
, NO_REGS
, ST_REGS
,
576 ST_REGS
, ST_REGS
, ST_REGS
, ST_REGS
,
577 ST_REGS
, ST_REGS
, ST_REGS
, NO_REGS
,
578 NO_REGS
, FRAME_REGS
, FRAME_REGS
, NO_REGS
,
579 COP0_REGS
, COP0_REGS
, COP0_REGS
, COP0_REGS
,
580 COP0_REGS
, COP0_REGS
, COP0_REGS
, COP0_REGS
,
581 COP0_REGS
, COP0_REGS
, COP0_REGS
, COP0_REGS
,
582 COP0_REGS
, COP0_REGS
, COP0_REGS
, COP0_REGS
,
583 COP0_REGS
, COP0_REGS
, COP0_REGS
, COP0_REGS
,
584 COP0_REGS
, COP0_REGS
, COP0_REGS
, COP0_REGS
,
585 COP0_REGS
, COP0_REGS
, COP0_REGS
, COP0_REGS
,
586 COP0_REGS
, COP0_REGS
, COP0_REGS
, COP0_REGS
,
587 COP2_REGS
, COP2_REGS
, COP2_REGS
, COP2_REGS
,
588 COP2_REGS
, COP2_REGS
, COP2_REGS
, COP2_REGS
,
589 COP2_REGS
, COP2_REGS
, COP2_REGS
, COP2_REGS
,
590 COP2_REGS
, COP2_REGS
, COP2_REGS
, COP2_REGS
,
591 COP2_REGS
, COP2_REGS
, COP2_REGS
, COP2_REGS
,
592 COP2_REGS
, COP2_REGS
, COP2_REGS
, COP2_REGS
,
593 COP2_REGS
, COP2_REGS
, COP2_REGS
, COP2_REGS
,
594 COP2_REGS
, COP2_REGS
, COP2_REGS
, COP2_REGS
,
595 COP3_REGS
, COP3_REGS
, COP3_REGS
, COP3_REGS
,
596 COP3_REGS
, COP3_REGS
, COP3_REGS
, COP3_REGS
,
597 COP3_REGS
, COP3_REGS
, COP3_REGS
, COP3_REGS
,
598 COP3_REGS
, COP3_REGS
, COP3_REGS
, COP3_REGS
,
599 COP3_REGS
, COP3_REGS
, COP3_REGS
, COP3_REGS
,
600 COP3_REGS
, COP3_REGS
, COP3_REGS
, COP3_REGS
,
601 COP3_REGS
, COP3_REGS
, COP3_REGS
, COP3_REGS
,
602 COP3_REGS
, COP3_REGS
, COP3_REGS
, COP3_REGS
,
603 DSP_ACC_REGS
, DSP_ACC_REGS
, DSP_ACC_REGS
, DSP_ACC_REGS
,
604 DSP_ACC_REGS
, DSP_ACC_REGS
, ALL_REGS
, ALL_REGS
,
605 ALL_REGS
, ALL_REGS
, ALL_REGS
, ALL_REGS
608 static tree
mips_handle_code_readable_attr (tree
*, tree
, tree
, int, bool *);
609 static tree
mips_handle_interrupt_attr (tree
*, tree
, tree
, int, bool *);
610 static tree
mips_handle_use_shadow_register_set_attr (tree
*, tree
, tree
, int,
613 /* The value of TARGET_ATTRIBUTE_TABLE. */
614 TARGET_GNU_ATTRIBUTES (mips_attribute_table
, {
615 /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
616 affects_type_identity, handler, exclude } */
617 { "long_call", 0, 0, false, true, true, false, NULL
, NULL
},
618 { "short_call", 0, 0, false, true, true, false, NULL
, NULL
},
619 { "far", 0, 0, false, true, true, false, NULL
, NULL
},
620 { "near", 0, 0, false, true, true, false, NULL
, NULL
},
621 /* We would really like to treat "mips16" and "nomips16" as type
622 attributes, but GCC doesn't provide the hooks we need to support
623 the right conversion rules. As declaration attributes, they affect
624 code generation but don't carry other semantics. */
625 { "mips16", 0, 0, true, false, false, false, NULL
, NULL
},
626 { "nomips16", 0, 0, true, false, false, false, NULL
, NULL
},
627 { "micromips", 0, 0, true, false, false, false, NULL
, NULL
},
628 { "nomicromips", 0, 0, true, false, false, false, NULL
, NULL
},
629 { "nocompression", 0, 0, true, false, false, false, NULL
, NULL
},
630 { "code_readable", 0, 1, true, false, false, false,
631 mips_handle_code_readable_attr
, NULL
},
632 /* Allow functions to be specified as interrupt handlers */
633 { "interrupt", 0, 1, false, true, true, false, mips_handle_interrupt_attr
,
635 { "use_shadow_register_set", 0, 1, false, true, true, false,
636 mips_handle_use_shadow_register_set_attr
, NULL
},
637 { "keep_interrupts_masked", 0, 0, false, true, true, false, NULL
, NULL
},
638 { "use_debug_exception_return", 0, 0, false, true, true, false, NULL
, NULL
},
639 { "use_hazard_barrier_return", 0, 0, true, false, false, false, NULL
, NULL
}
642 /* A table describing all the processors GCC knows about; see
643 mips-cpus.def for details. */
644 static const struct mips_cpu_info mips_cpu_info_table
[] = {
645 #define MIPS_CPU(NAME, CPU, ISA, FLAGS) \
646 { NAME, CPU, ISA, FLAGS },
647 #include "mips-cpus.def"
651 /* Default costs. If these are used for a processor we should look
652 up the actual costs. */
653 #define DEFAULT_COSTS COSTS_N_INSNS (6), /* fp_add */ \
654 COSTS_N_INSNS (7), /* fp_mult_sf */ \
655 COSTS_N_INSNS (8), /* fp_mult_df */ \
656 COSTS_N_INSNS (23), /* fp_div_sf */ \
657 COSTS_N_INSNS (36), /* fp_div_df */ \
658 COSTS_N_INSNS (10), /* int_mult_si */ \
659 COSTS_N_INSNS (10), /* int_mult_di */ \
660 COSTS_N_INSNS (69), /* int_div_si */ \
661 COSTS_N_INSNS (69), /* int_div_di */ \
662 2, /* branch_cost */ \
663 4 /* memory_latency */
665 /* Floating-point costs for processors without an FPU. Just assume that
666 all floating-point libcalls are very expensive. */
667 #define SOFT_FP_COSTS COSTS_N_INSNS (256), /* fp_add */ \
668 COSTS_N_INSNS (256), /* fp_mult_sf */ \
669 COSTS_N_INSNS (256), /* fp_mult_df */ \
670 COSTS_N_INSNS (256), /* fp_div_sf */ \
671 COSTS_N_INSNS (256) /* fp_div_df */
673 /* Costs to use when optimizing for size. */
674 static const struct mips_rtx_cost_data mips_rtx_cost_optimize_size
= {
675 COSTS_N_INSNS (1), /* fp_add */
676 COSTS_N_INSNS (1), /* fp_mult_sf */
677 COSTS_N_INSNS (1), /* fp_mult_df */
678 COSTS_N_INSNS (1), /* fp_div_sf */
679 COSTS_N_INSNS (1), /* fp_div_df */
680 COSTS_N_INSNS (1), /* int_mult_si */
681 COSTS_N_INSNS (1), /* int_mult_di */
682 COSTS_N_INSNS (1), /* int_div_si */
683 COSTS_N_INSNS (1), /* int_div_di */
685 4 /* memory_latency */
688 /* Costs to use when optimizing for speed, indexed by processor. */
689 static const struct mips_rtx_cost_data
690 mips_rtx_cost_data
[NUM_PROCESSOR_VALUES
] = {
692 COSTS_N_INSNS (2), /* fp_add */
693 COSTS_N_INSNS (4), /* fp_mult_sf */
694 COSTS_N_INSNS (5), /* fp_mult_df */
695 COSTS_N_INSNS (12), /* fp_div_sf */
696 COSTS_N_INSNS (19), /* fp_div_df */
697 COSTS_N_INSNS (12), /* int_mult_si */
698 COSTS_N_INSNS (12), /* int_mult_di */
699 COSTS_N_INSNS (35), /* int_div_si */
700 COSTS_N_INSNS (35), /* int_div_di */
702 4 /* memory_latency */
706 COSTS_N_INSNS (6), /* int_mult_si */
707 COSTS_N_INSNS (6), /* int_mult_di */
708 COSTS_N_INSNS (36), /* int_div_si */
709 COSTS_N_INSNS (36), /* int_div_di */
711 4 /* memory_latency */
715 COSTS_N_INSNS (36), /* int_mult_si */
716 COSTS_N_INSNS (36), /* int_mult_di */
717 COSTS_N_INSNS (37), /* int_div_si */
718 COSTS_N_INSNS (37), /* int_div_di */
720 4 /* memory_latency */
724 COSTS_N_INSNS (4), /* int_mult_si */
725 COSTS_N_INSNS (11), /* int_mult_di */
726 COSTS_N_INSNS (36), /* int_div_si */
727 COSTS_N_INSNS (68), /* int_div_di */
729 4 /* memory_latency */
732 COSTS_N_INSNS (4), /* fp_add */
733 COSTS_N_INSNS (4), /* fp_mult_sf */
734 COSTS_N_INSNS (5), /* fp_mult_df */
735 COSTS_N_INSNS (17), /* fp_div_sf */
736 COSTS_N_INSNS (32), /* fp_div_df */
737 COSTS_N_INSNS (4), /* int_mult_si */
738 COSTS_N_INSNS (11), /* int_mult_di */
739 COSTS_N_INSNS (36), /* int_div_si */
740 COSTS_N_INSNS (68), /* int_div_di */
742 4 /* memory_latency */
745 COSTS_N_INSNS (4), /* fp_add */
746 COSTS_N_INSNS (4), /* fp_mult_sf */
747 COSTS_N_INSNS (5), /* fp_mult_df */
748 COSTS_N_INSNS (17), /* fp_div_sf */
749 COSTS_N_INSNS (32), /* fp_div_df */
750 COSTS_N_INSNS (4), /* int_mult_si */
751 COSTS_N_INSNS (7), /* int_mult_di */
752 COSTS_N_INSNS (42), /* int_div_si */
753 COSTS_N_INSNS (72), /* int_div_di */
755 4 /* memory_latency */
759 COSTS_N_INSNS (5), /* int_mult_si */
760 COSTS_N_INSNS (5), /* int_mult_di */
761 COSTS_N_INSNS (41), /* int_div_si */
762 COSTS_N_INSNS (41), /* int_div_di */
764 4 /* memory_latency */
767 COSTS_N_INSNS (8), /* fp_add */
768 COSTS_N_INSNS (8), /* fp_mult_sf */
769 COSTS_N_INSNS (10), /* fp_mult_df */
770 COSTS_N_INSNS (34), /* fp_div_sf */
771 COSTS_N_INSNS (64), /* fp_div_df */
772 COSTS_N_INSNS (5), /* int_mult_si */
773 COSTS_N_INSNS (5), /* int_mult_di */
774 COSTS_N_INSNS (41), /* int_div_si */
775 COSTS_N_INSNS (41), /* int_div_di */
777 4 /* memory_latency */
780 COSTS_N_INSNS (4), /* fp_add */
781 COSTS_N_INSNS (4), /* fp_mult_sf */
782 COSTS_N_INSNS (5), /* fp_mult_df */
783 COSTS_N_INSNS (17), /* fp_div_sf */
784 COSTS_N_INSNS (32), /* fp_div_df */
785 COSTS_N_INSNS (5), /* int_mult_si */
786 COSTS_N_INSNS (5), /* int_mult_di */
787 COSTS_N_INSNS (41), /* int_div_si */
788 COSTS_N_INSNS (41), /* int_div_di */
790 4 /* memory_latency */
794 COSTS_N_INSNS (5), /* int_mult_si */
795 COSTS_N_INSNS (5), /* int_mult_di */
796 COSTS_N_INSNS (41), /* int_div_si */
797 COSTS_N_INSNS (41), /* int_div_di */
799 4 /* memory_latency */
802 COSTS_N_INSNS (8), /* fp_add */
803 COSTS_N_INSNS (8), /* fp_mult_sf */
804 COSTS_N_INSNS (10), /* fp_mult_df */
805 COSTS_N_INSNS (34), /* fp_div_sf */
806 COSTS_N_INSNS (64), /* fp_div_df */
807 COSTS_N_INSNS (5), /* int_mult_si */
808 COSTS_N_INSNS (5), /* int_mult_di */
809 COSTS_N_INSNS (41), /* int_div_si */
810 COSTS_N_INSNS (41), /* int_div_di */
812 4 /* memory_latency */
815 COSTS_N_INSNS (4), /* fp_add */
816 COSTS_N_INSNS (4), /* fp_mult_sf */
817 COSTS_N_INSNS (5), /* fp_mult_df */
818 COSTS_N_INSNS (17), /* fp_div_sf */
819 COSTS_N_INSNS (32), /* fp_div_df */
820 COSTS_N_INSNS (5), /* int_mult_si */
821 COSTS_N_INSNS (5), /* int_mult_di */
822 COSTS_N_INSNS (41), /* int_div_si */
823 COSTS_N_INSNS (41), /* int_div_di */
825 4 /* memory_latency */
828 COSTS_N_INSNS (6), /* fp_add */
829 COSTS_N_INSNS (6), /* fp_mult_sf */
830 COSTS_N_INSNS (7), /* fp_mult_df */
831 COSTS_N_INSNS (25), /* fp_div_sf */
832 COSTS_N_INSNS (48), /* fp_div_df */
833 COSTS_N_INSNS (5), /* int_mult_si */
834 COSTS_N_INSNS (5), /* int_mult_di */
835 COSTS_N_INSNS (41), /* int_div_si */
836 COSTS_N_INSNS (41), /* int_div_di */
838 4 /* memory_latency */
846 { /* Loongson gs464. */
849 { /* Loongson gs464e. */
852 { /* Loongson gs264e. */
861 COSTS_N_INSNS (5), /* int_mult_si */
862 COSTS_N_INSNS (5), /* int_mult_di */
863 COSTS_N_INSNS (72), /* int_div_si */
864 COSTS_N_INSNS (72), /* int_div_di */
866 4 /* memory_latency */
871 COSTS_N_INSNS (6), /* int_mult_si */
872 COSTS_N_INSNS (6), /* int_mult_di */
873 COSTS_N_INSNS (18), /* int_div_si */
874 COSTS_N_INSNS (35), /* int_div_di */
876 4 /* memory_latency */
880 COSTS_N_INSNS (6), /* fp_add */
881 COSTS_N_INSNS (6), /* fp_mult_sf */
882 COSTS_N_INSNS (7), /* fp_mult_df */
883 COSTS_N_INSNS (25), /* fp_div_sf */
884 COSTS_N_INSNS (48), /* fp_div_df */
885 COSTS_N_INSNS (6), /* int_mult_si */
886 COSTS_N_INSNS (6), /* int_mult_di */
887 COSTS_N_INSNS (18), /* int_div_si */
888 COSTS_N_INSNS (35), /* int_div_di */
890 4 /* memory_latency */
893 COSTS_N_INSNS (2), /* fp_add */
894 COSTS_N_INSNS (4), /* fp_mult_sf */
895 COSTS_N_INSNS (5), /* fp_mult_df */
896 COSTS_N_INSNS (12), /* fp_div_sf */
897 COSTS_N_INSNS (19), /* fp_div_df */
898 COSTS_N_INSNS (2), /* int_mult_si */
899 COSTS_N_INSNS (2), /* int_mult_di */
900 COSTS_N_INSNS (35), /* int_div_si */
901 COSTS_N_INSNS (35), /* int_div_di */
903 4 /* memory_latency */
906 COSTS_N_INSNS (3), /* fp_add */
907 COSTS_N_INSNS (5), /* fp_mult_sf */
908 COSTS_N_INSNS (6), /* fp_mult_df */
909 COSTS_N_INSNS (15), /* fp_div_sf */
910 COSTS_N_INSNS (16), /* fp_div_df */
911 COSTS_N_INSNS (17), /* int_mult_si */
912 COSTS_N_INSNS (17), /* int_mult_di */
913 COSTS_N_INSNS (38), /* int_div_si */
914 COSTS_N_INSNS (38), /* int_div_di */
916 6 /* memory_latency */
919 COSTS_N_INSNS (6), /* fp_add */
920 COSTS_N_INSNS (7), /* fp_mult_sf */
921 COSTS_N_INSNS (8), /* fp_mult_df */
922 COSTS_N_INSNS (23), /* fp_div_sf */
923 COSTS_N_INSNS (36), /* fp_div_df */
924 COSTS_N_INSNS (10), /* int_mult_si */
925 COSTS_N_INSNS (10), /* int_mult_di */
926 COSTS_N_INSNS (69), /* int_div_si */
927 COSTS_N_INSNS (69), /* int_div_di */
929 6 /* memory_latency */
941 /* The only costs that appear to be updated here are
942 integer multiplication. */
944 COSTS_N_INSNS (4), /* int_mult_si */
945 COSTS_N_INSNS (6), /* int_mult_di */
946 COSTS_N_INSNS (69), /* int_div_si */
947 COSTS_N_INSNS (69), /* int_div_di */
949 4 /* memory_latency */
964 COSTS_N_INSNS (6), /* fp_add */
965 COSTS_N_INSNS (4), /* fp_mult_sf */
966 COSTS_N_INSNS (5), /* fp_mult_df */
967 COSTS_N_INSNS (23), /* fp_div_sf */
968 COSTS_N_INSNS (36), /* fp_div_df */
969 COSTS_N_INSNS (5), /* int_mult_si */
970 COSTS_N_INSNS (5), /* int_mult_di */
971 COSTS_N_INSNS (36), /* int_div_si */
972 COSTS_N_INSNS (36), /* int_div_di */
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 (3), /* int_mult_si */
983 COSTS_N_INSNS (4), /* int_mult_di */
984 COSTS_N_INSNS (42), /* int_div_si */
985 COSTS_N_INSNS (74), /* int_div_di */
987 4 /* memory_latency */
990 COSTS_N_INSNS (6), /* fp_add */
991 COSTS_N_INSNS (5), /* fp_mult_sf */
992 COSTS_N_INSNS (6), /* fp_mult_df */
993 COSTS_N_INSNS (30), /* fp_div_sf */
994 COSTS_N_INSNS (59), /* fp_div_df */
995 COSTS_N_INSNS (5), /* int_mult_si */
996 COSTS_N_INSNS (9), /* int_mult_di */
997 COSTS_N_INSNS (42), /* int_div_si */
998 COSTS_N_INSNS (74), /* int_div_di */
1000 4 /* memory_latency */
1003 COSTS_N_INSNS (4), /* fp_add */
1004 COSTS_N_INSNS (4), /* fp_mult_sf */
1005 COSTS_N_INSNS (256), /* fp_mult_df */
1006 COSTS_N_INSNS (8), /* fp_div_sf */
1007 COSTS_N_INSNS (256), /* fp_div_df */
1008 COSTS_N_INSNS (4), /* int_mult_si */
1009 COSTS_N_INSNS (256), /* int_mult_di */
1010 COSTS_N_INSNS (37), /* int_div_si */
1011 COSTS_N_INSNS (256), /* int_div_di */
1012 1, /* branch_cost */
1013 4 /* memory_latency */
1016 /* The only costs that are changed here are
1017 integer multiplication. */
1018 COSTS_N_INSNS (6), /* fp_add */
1019 COSTS_N_INSNS (7), /* fp_mult_sf */
1020 COSTS_N_INSNS (8), /* fp_mult_df */
1021 COSTS_N_INSNS (23), /* fp_div_sf */
1022 COSTS_N_INSNS (36), /* fp_div_df */
1023 COSTS_N_INSNS (5), /* int_mult_si */
1024 COSTS_N_INSNS (9), /* int_mult_di */
1025 COSTS_N_INSNS (69), /* int_div_si */
1026 COSTS_N_INSNS (69), /* int_div_di */
1027 1, /* branch_cost */
1028 4 /* memory_latency */
1034 /* The only costs that are changed here are
1035 integer multiplication. */
1036 COSTS_N_INSNS (6), /* fp_add */
1037 COSTS_N_INSNS (7), /* fp_mult_sf */
1038 COSTS_N_INSNS (8), /* fp_mult_df */
1039 COSTS_N_INSNS (23), /* fp_div_sf */
1040 COSTS_N_INSNS (36), /* fp_div_df */
1041 COSTS_N_INSNS (3), /* int_mult_si */
1042 COSTS_N_INSNS (8), /* int_mult_di */
1043 COSTS_N_INSNS (69), /* int_div_si */
1044 COSTS_N_INSNS (69), /* int_div_di */
1045 1, /* branch_cost */
1046 4 /* memory_latency */
1049 COSTS_N_INSNS (2), /* fp_add */
1050 COSTS_N_INSNS (2), /* fp_mult_sf */
1051 COSTS_N_INSNS (2), /* fp_mult_df */
1052 COSTS_N_INSNS (12), /* fp_div_sf */
1053 COSTS_N_INSNS (19), /* fp_div_df */
1054 COSTS_N_INSNS (5), /* int_mult_si */
1055 COSTS_N_INSNS (9), /* int_mult_di */
1056 COSTS_N_INSNS (34), /* int_div_si */
1057 COSTS_N_INSNS (66), /* int_div_di */
1058 1, /* branch_cost */
1059 4 /* memory_latency */
1062 /* These costs are the same as the SB-1A below. */
1063 COSTS_N_INSNS (4), /* fp_add */
1064 COSTS_N_INSNS (4), /* fp_mult_sf */
1065 COSTS_N_INSNS (4), /* fp_mult_df */
1066 COSTS_N_INSNS (24), /* fp_div_sf */
1067 COSTS_N_INSNS (32), /* fp_div_df */
1068 COSTS_N_INSNS (3), /* int_mult_si */
1069 COSTS_N_INSNS (4), /* int_mult_di */
1070 COSTS_N_INSNS (36), /* int_div_si */
1071 COSTS_N_INSNS (68), /* int_div_di */
1072 1, /* branch_cost */
1073 4 /* memory_latency */
1076 /* These costs are the same as the SB-1 above. */
1077 COSTS_N_INSNS (4), /* fp_add */
1078 COSTS_N_INSNS (4), /* fp_mult_sf */
1079 COSTS_N_INSNS (4), /* fp_mult_df */
1080 COSTS_N_INSNS (24), /* fp_div_sf */
1081 COSTS_N_INSNS (32), /* fp_div_df */
1082 COSTS_N_INSNS (3), /* int_mult_si */
1083 COSTS_N_INSNS (4), /* int_mult_di */
1084 COSTS_N_INSNS (36), /* int_div_si */
1085 COSTS_N_INSNS (68), /* int_div_di */
1086 1, /* branch_cost */
1087 4 /* memory_latency */
1094 COSTS_N_INSNS (8), /* int_mult_si */
1095 COSTS_N_INSNS (8), /* int_mult_di */
1096 COSTS_N_INSNS (72), /* int_div_si */
1097 COSTS_N_INSNS (72), /* int_div_di */
1098 1, /* branch_cost */
1099 4 /* memory_latency */
1102 /* These costs are the same as 5KF above. */
1103 COSTS_N_INSNS (4), /* fp_add */
1104 COSTS_N_INSNS (4), /* fp_mult_sf */
1105 COSTS_N_INSNS (5), /* fp_mult_df */
1106 COSTS_N_INSNS (17), /* fp_div_sf */
1107 COSTS_N_INSNS (32), /* fp_div_df */
1108 COSTS_N_INSNS (4), /* int_mult_si */
1109 COSTS_N_INSNS (11), /* int_mult_di */
1110 COSTS_N_INSNS (36), /* int_div_si */
1111 COSTS_N_INSNS (68), /* int_div_di */
1112 1, /* branch_cost */
1113 4 /* memory_latency */
1116 COSTS_N_INSNS (4), /* fp_add */
1117 COSTS_N_INSNS (5), /* fp_mult_sf */
1118 COSTS_N_INSNS (5), /* fp_mult_df */
1119 COSTS_N_INSNS (17), /* fp_div_sf */
1120 COSTS_N_INSNS (17), /* fp_div_df */
1121 COSTS_N_INSNS (5), /* int_mult_si */
1122 COSTS_N_INSNS (5), /* int_mult_di */
1123 COSTS_N_INSNS (8), /* int_div_si */
1124 COSTS_N_INSNS (8), /* int_div_di */
1125 2, /* branch_cost */
1126 4 /* memory_latency */
1129 COSTS_N_INSNS (4), /* fp_add */
1130 COSTS_N_INSNS (4), /* fp_mult_sf */
1131 COSTS_N_INSNS (5), /* fp_mult_df */
1132 COSTS_N_INSNS (17), /* fp_div_sf */
1133 COSTS_N_INSNS (32), /* fp_div_df */
1134 COSTS_N_INSNS (5), /* int_mult_si */
1135 COSTS_N_INSNS (5), /* int_mult_di */
1136 COSTS_N_INSNS (34), /* int_div_si */
1137 COSTS_N_INSNS (68), /* int_div_di */
1138 1, /* branch_cost */
1139 4 /* memory_latency */
1142 COSTS_N_INSNS (4), /* fp_add */
1143 COSTS_N_INSNS (5), /* fp_mult_sf */
1144 COSTS_N_INSNS (5), /* fp_mult_df */
1145 COSTS_N_INSNS (32), /* fp_div_sf */
1146 COSTS_N_INSNS (32), /* fp_div_df */
1147 COSTS_N_INSNS (5), /* int_mult_si */
1148 COSTS_N_INSNS (5), /* int_mult_di */
1149 COSTS_N_INSNS (36), /* int_div_si */
1150 COSTS_N_INSNS (36), /* int_div_di */
1151 2, /* branch_cost */
1152 4 /* memory_latency */
1155 COSTS_N_INSNS (4), /* fp_add */
1156 COSTS_N_INSNS (5), /* fp_mult_sf */
1157 COSTS_N_INSNS (5), /* fp_mult_df */
1158 COSTS_N_INSNS (17), /* fp_div_sf */
1159 COSTS_N_INSNS (17), /* fp_div_df */
1160 COSTS_N_INSNS (5), /* int_mult_si */
1161 COSTS_N_INSNS (5), /* int_mult_di */
1162 COSTS_N_INSNS (8), /* int_div_si */
1163 COSTS_N_INSNS (8), /* int_div_di */
1164 2, /* branch_cost */
1165 4 /* memory_latency */
1169 static rtx
mips_find_pic_call_symbol (rtx_insn
*, rtx
, bool);
1170 static int mips_register_move_cost (machine_mode
, reg_class_t
,
1172 static unsigned int mips_function_arg_boundary (machine_mode
, const_tree
);
1173 static rtx
mips_gen_const_int_vector_shuffle (machine_mode
, int);
1175 /* This hash table keeps track of implicit "mips16" and "nomips16" attributes
1176 for -mflip_mips16. It maps decl names onto a boolean mode setting. */
1177 static GTY (()) hash_map
<nofree_string_hash
, bool> *mflip_mips16_htab
;
1179 /* True if -mflip-mips16 should next add an attribute for the default MIPS16
1180 mode, false if it should next add an attribute for the opposite mode. */
1181 static GTY(()) bool mips16_flipper
;
1183 /* DECL is a function that needs a default "mips16" or "nomips16" attribute
1184 for -mflip-mips16. Return true if it should use "mips16" and false if
1185 it should use "nomips16". */
1188 mflip_mips16_use_mips16_p (tree decl
)
1191 bool base_is_mips16
= (mips_base_compression_flags
& MASK_MIPS16
) != 0;
1193 /* Use the opposite of the command-line setting for anonymous decls. */
1194 if (!DECL_NAME (decl
))
1195 return !base_is_mips16
;
1197 if (!mflip_mips16_htab
)
1198 mflip_mips16_htab
= hash_map
<nofree_string_hash
, bool>::create_ggc (37);
1200 name
= IDENTIFIER_POINTER (DECL_NAME (decl
));
1203 bool *slot
= &mflip_mips16_htab
->get_or_insert (name
, &existed
);
1206 mips16_flipper
= !mips16_flipper
;
1207 *slot
= mips16_flipper
? !base_is_mips16
: base_is_mips16
;
1212 /* Predicates to test for presence of "near"/"short_call" and "far"/"long_call"
1213 attributes on the given TYPE. */
1216 mips_near_type_p (const_tree type
)
1218 return (lookup_attribute ("short_call", TYPE_ATTRIBUTES (type
)) != NULL
1219 || lookup_attribute ("near", TYPE_ATTRIBUTES (type
)) != NULL
);
1223 mips_far_type_p (const_tree type
)
1225 return (lookup_attribute ("long_call", TYPE_ATTRIBUTES (type
)) != NULL
1226 || lookup_attribute ("far", TYPE_ATTRIBUTES (type
)) != NULL
);
1230 /* Check if the interrupt attribute is set for a function. */
1233 mips_interrupt_type_p (tree type
)
1235 return lookup_attribute ("interrupt", TYPE_ATTRIBUTES (type
)) != NULL
;
1238 /* Return the mask for the "interrupt" attribute. */
1240 static enum mips_int_mask
1241 mips_interrupt_mask (tree type
)
1243 tree attr
= lookup_attribute ("interrupt", TYPE_ATTRIBUTES (type
));
1247 /* For missing attributes or no arguments then return 'eic' as a safe
1250 return INT_MASK_EIC
;
1252 args
= TREE_VALUE (attr
);
1255 return INT_MASK_EIC
;
1257 cst
= TREE_VALUE (args
);
1259 if (strcmp (TREE_STRING_POINTER (cst
), "eic") == 0)
1260 return INT_MASK_EIC
;
1262 /* The validation code in mips_handle_interrupt_attr guarantees that the
1263 argument is now in the form:
1264 vector=(sw0|sw1|hw0|hw1|hw2|hw3|hw4|hw5). */
1265 str
= TREE_STRING_POINTER (cst
);
1267 gcc_assert (strlen (str
) == strlen ("vector=sw0"));
1270 return (enum mips_int_mask
) (INT_MASK_SW0
+ (str
[9] - '0'));
1272 return (enum mips_int_mask
) (INT_MASK_HW0
+ (str
[9] - '0'));
1275 /* Return the mips_shadow_set if the "use_shadow_register_set" attribute is
1276 set for a function. */
1278 static enum mips_shadow_set
1279 mips_use_shadow_register_set (tree type
)
1281 tree attr
= lookup_attribute ("use_shadow_register_set",
1282 TYPE_ATTRIBUTES (type
));
1285 /* The validation code in mips_handle_use_shadow_register_set_attr guarantees
1286 that if an argument is present then it means: Assume the shadow register
1287 set has a valid stack pointer in it. */
1289 return SHADOW_SET_NO
;
1291 args
= TREE_VALUE (attr
);
1294 return SHADOW_SET_YES
;
1296 return SHADOW_SET_INTSTACK
;
1299 /* Check if the attribute to keep interrupts masked is set for a function. */
1302 mips_keep_interrupts_masked_p (tree type
)
1304 return lookup_attribute ("keep_interrupts_masked",
1305 TYPE_ATTRIBUTES (type
)) != NULL
;
1308 /* Check if the attribute to use debug exception return is set for
1312 mips_use_debug_exception_return_p (tree type
)
1314 return lookup_attribute ("use_debug_exception_return",
1315 TYPE_ATTRIBUTES (type
)) != NULL
;
1319 /* Verify the arguments to a code_readable attribute. */
1322 mips_handle_code_readable_attr (tree
*node ATTRIBUTE_UNUSED
, tree name
,
1323 tree args
, int flags ATTRIBUTE_UNUSED
,
1326 if (!is_attribute_p ("code_readable", name
) || args
== NULL
)
1329 if (TREE_CODE (TREE_VALUE (args
)) != STRING_CST
)
1331 warning (OPT_Wattributes
,
1332 "%qE attribute requires a string argument", name
);
1333 *no_add_attrs
= true;
1335 else if (strcmp (TREE_STRING_POINTER (TREE_VALUE (args
)), "no") != 0
1336 && strcmp (TREE_STRING_POINTER (TREE_VALUE (args
)), "pcrel") != 0
1337 && strcmp (TREE_STRING_POINTER (TREE_VALUE (args
)), "yes") != 0)
1339 warning (OPT_Wattributes
,
1340 "argument to %qE attribute is neither no, pcrel nor yes", name
);
1341 *no_add_attrs
= true;
1347 /* Determine the code_readable setting for a function if it has one. Set
1348 *valid to true if we have a properly formed argument and
1349 return the result. If there's no argument, return GCC's default.
1350 Otherwise, leave valid false and return mips_base_code_readable. In
1351 that case the result should be unused anyway. */
1353 static enum mips_code_readable_setting
1354 mips_get_code_readable_attr (tree decl
)
1359 return mips_base_code_readable
;
1361 attr
= lookup_attribute ("code_readable", DECL_ATTRIBUTES (decl
));
1365 if (TREE_VALUE (attr
) != NULL_TREE
)
1369 str
= TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr
)));
1370 if (strcmp (str
, "no") == 0)
1371 return CODE_READABLE_NO
;
1372 else if (strcmp (str
, "pcrel") == 0)
1373 return CODE_READABLE_PCREL
;
1374 else if (strcmp (str
, "yes") == 0)
1375 return CODE_READABLE_YES
;
1377 /* mips_handle_code_readable_attr will have verified the
1378 arguments are correct before adding the attribute. */
1382 /* Just like GCC's default -mcode-readable= setting, the
1383 presence of the code_readable attribute implies that a
1384 function can read data from the instruction stream by
1386 return CODE_READABLE_YES
;
1389 return mips_base_code_readable
;
1393 /* Return the set of compression modes that are explicitly required
1394 by the attributes in ATTRIBUTES. */
1397 mips_get_compress_on_flags (tree attributes
)
1399 unsigned int flags
= 0;
1401 if (lookup_attribute ("mips16", attributes
) != NULL
)
1402 flags
|= MASK_MIPS16
;
1404 if (lookup_attribute ("micromips", attributes
) != NULL
)
1405 flags
|= MASK_MICROMIPS
;
1410 /* Return the set of compression modes that are explicitly forbidden
1411 by the attributes in ATTRIBUTES. */
1414 mips_get_compress_off_flags (tree attributes
)
1416 unsigned int flags
= 0;
1418 if (lookup_attribute ("nocompression", attributes
) != NULL
)
1419 flags
|= MASK_MIPS16
| MASK_MICROMIPS
;
1421 if (lookup_attribute ("nomips16", attributes
) != NULL
)
1422 flags
|= MASK_MIPS16
;
1424 if (lookup_attribute ("nomicromips", attributes
) != NULL
)
1425 flags
|= MASK_MICROMIPS
;
1430 /* Return the compression mode that should be used for function DECL.
1431 Return the ambient setting if DECL is null. */
1434 mips_get_compress_mode (tree decl
)
1436 unsigned int flags
, force_on
;
1438 flags
= mips_base_compression_flags
;
1441 /* Nested functions must use the same frame pointer as their
1442 parent and must therefore use the same ISA mode. */
1443 tree parent
= decl_function_context (decl
);
1446 force_on
= mips_get_compress_on_flags (DECL_ATTRIBUTES (decl
));
1449 flags
&= ~mips_get_compress_off_flags (DECL_ATTRIBUTES (decl
));
1454 /* Return the attribute name associated with MASK_MIPS16 and MASK_MICROMIPS
1458 mips_get_compress_on_name (unsigned int flags
)
1460 if (flags
== MASK_MIPS16
)
1465 /* Return the attribute name that forbids MASK_MIPS16 and MASK_MICROMIPS
1469 mips_get_compress_off_name (unsigned int flags
)
1471 if (flags
== MASK_MIPS16
)
1473 if (flags
== MASK_MICROMIPS
)
1474 return "nomicromips";
1475 return "nocompression";
1478 /* Implement TARGET_COMP_TYPE_ATTRIBUTES. */
1481 mips_comp_type_attributes (const_tree type1
, const_tree type2
)
1483 /* Disallow mixed near/far attributes. */
1484 if (mips_far_type_p (type1
) && mips_near_type_p (type2
))
1486 if (mips_near_type_p (type1
) && mips_far_type_p (type2
))
1491 /* Implement TARGET_INSERT_ATTRIBUTES. */
1494 mips_insert_attributes (tree decl
, tree
*attributes
)
1497 unsigned int compression_flags
, nocompression_flags
;
1499 /* Check for "mips16" and "nomips16" attributes. */
1500 compression_flags
= mips_get_compress_on_flags (*attributes
);
1501 nocompression_flags
= mips_get_compress_off_flags (*attributes
);
1503 if (TREE_CODE (decl
) != FUNCTION_DECL
)
1505 if (nocompression_flags
)
1506 error ("%qs attribute only applies to functions",
1507 mips_get_compress_off_name (nocompression_flags
));
1509 if (compression_flags
)
1510 error ("%qs attribute only applies to functions",
1511 mips_get_compress_on_name (nocompression_flags
));
1515 compression_flags
|= mips_get_compress_on_flags (DECL_ATTRIBUTES (decl
));
1516 nocompression_flags
|=
1517 mips_get_compress_off_flags (DECL_ATTRIBUTES (decl
));
1519 if (compression_flags
&& nocompression_flags
)
1520 error ("%qE cannot have both %qs and %qs attributes",
1521 DECL_NAME (decl
), mips_get_compress_on_name (compression_flags
),
1522 mips_get_compress_off_name (nocompression_flags
));
1524 if (compression_flags
& MASK_MIPS16
1525 && compression_flags
& MASK_MICROMIPS
)
1526 error ("%qE cannot have both %qs and %qs attributes",
1527 DECL_NAME (decl
), "mips16", "micromips");
1529 if (TARGET_FLIP_MIPS16
1530 && !DECL_ARTIFICIAL (decl
)
1531 && compression_flags
== 0
1532 && nocompression_flags
== 0)
1534 /* Implement -mflip-mips16. If DECL has neither a "nomips16" nor a
1535 "mips16" attribute, arbitrarily pick one. We must pick the same
1536 setting for duplicate declarations of a function. */
1537 name
= mflip_mips16_use_mips16_p (decl
) ? "mips16" : "nomips16";
1538 *attributes
= tree_cons (get_identifier (name
), NULL
, *attributes
);
1539 name
= "nomicromips";
1540 *attributes
= tree_cons (get_identifier (name
), NULL
, *attributes
);
1545 /* Implement TARGET_MERGE_DECL_ATTRIBUTES. */
1548 mips_merge_decl_attributes (tree olddecl
, tree newdecl
)
1552 diff
= (mips_get_compress_on_flags (DECL_ATTRIBUTES (olddecl
))
1553 ^ mips_get_compress_on_flags (DECL_ATTRIBUTES (newdecl
)));
1555 error ("%qE redeclared with conflicting %qs attributes",
1556 DECL_NAME (newdecl
), mips_get_compress_on_name (diff
));
1558 diff
= (mips_get_compress_off_flags (DECL_ATTRIBUTES (olddecl
))
1559 ^ mips_get_compress_off_flags (DECL_ATTRIBUTES (newdecl
)));
1561 error ("%qE redeclared with conflicting %qs attributes",
1562 DECL_NAME (newdecl
), mips_get_compress_off_name (diff
));
1564 return merge_attributes (DECL_ATTRIBUTES (olddecl
),
1565 DECL_ATTRIBUTES (newdecl
));
1568 /* Implement TARGET_CAN_INLINE_P. */
1571 mips_can_inline_p (tree caller
, tree callee
)
1573 if (mips_get_compress_mode (callee
) != mips_get_compress_mode (caller
))
1575 return default_target_can_inline_p (caller
, callee
);
1578 /* Handle an "interrupt" attribute with an optional argument. */
1581 mips_handle_interrupt_attr (tree
*node ATTRIBUTE_UNUSED
, tree name
, tree args
,
1582 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
1584 /* Check for an argument. */
1585 if (is_attribute_p ("interrupt", name
) && args
!= NULL
)
1589 cst
= TREE_VALUE (args
);
1590 if (TREE_CODE (cst
) != STRING_CST
)
1592 warning (OPT_Wattributes
,
1593 "%qE attribute requires a string argument",
1595 *no_add_attrs
= true;
1597 else if (strcmp (TREE_STRING_POINTER (cst
), "eic") != 0
1598 && !startswith (TREE_STRING_POINTER (cst
), "vector="))
1600 warning (OPT_Wattributes
,
1601 "argument to %qE attribute is neither eic, nor "
1602 "%<vector=<line>%>", name
);
1603 *no_add_attrs
= true;
1605 else if (startswith (TREE_STRING_POINTER (cst
), "vector="))
1607 const char *arg
= TREE_STRING_POINTER (cst
) + 7;
1609 /* Acceptable names are: sw0,sw1,hw0,hw1,hw2,hw3,hw4,hw5. */
1610 if (strlen (arg
) != 3
1611 || (arg
[0] != 's' && arg
[0] != 'h')
1613 || (arg
[0] == 's' && arg
[2] != '0' && arg
[2] != '1')
1614 || (arg
[0] == 'h' && (arg
[2] < '0' || arg
[2] > '5')))
1616 warning (OPT_Wattributes
,
1617 "interrupt vector to %qE attribute is not "
1618 "%<vector=(sw0|sw1|hw0|hw1|hw2|hw3|hw4|hw5)%>",
1620 *no_add_attrs
= true;
1630 /* Handle a "use_shadow_register_set" attribute with an optional argument. */
1633 mips_handle_use_shadow_register_set_attr (tree
*node ATTRIBUTE_UNUSED
,
1634 tree name
, tree args
,
1635 int flags ATTRIBUTE_UNUSED
,
1638 /* Check for an argument. */
1639 if (is_attribute_p ("use_shadow_register_set", name
) && args
!= NULL
)
1643 cst
= TREE_VALUE (args
);
1644 if (TREE_CODE (cst
) != STRING_CST
)
1646 warning (OPT_Wattributes
,
1647 "%qE attribute requires a string argument",
1649 *no_add_attrs
= true;
1651 else if (strcmp (TREE_STRING_POINTER (cst
), "intstack") != 0)
1653 warning (OPT_Wattributes
,
1654 "argument to %qE attribute is not intstack", name
);
1655 *no_add_attrs
= true;
1664 /* If X is a PLUS of a CONST_INT, return the two terms in *BASE_PTR
1665 and *OFFSET_PTR. Return X in *BASE_PTR and 0 in *OFFSET_PTR otherwise. */
1668 mips_split_plus (rtx x
, rtx
*base_ptr
, HOST_WIDE_INT
*offset_ptr
)
1670 if (GET_CODE (x
) == PLUS
&& CONST_INT_P (XEXP (x
, 1)))
1672 *base_ptr
= XEXP (x
, 0);
1673 *offset_ptr
= INTVAL (XEXP (x
, 1));
1682 static unsigned int mips_build_integer (struct mips_integer_op
*,
1683 unsigned HOST_WIDE_INT
);
1685 /* A subroutine of mips_build_integer, with the same interface.
1686 Assume that the final action in the sequence should be a left shift. */
1689 mips_build_shift (struct mips_integer_op
*codes
, HOST_WIDE_INT value
)
1691 unsigned int i
, shift
;
1693 /* Shift VALUE right until its lowest bit is set. Shift arithmetically
1694 since signed numbers are easier to load than unsigned ones. */
1696 while ((value
& 1) == 0)
1697 value
/= 2, shift
++;
1699 i
= mips_build_integer (codes
, value
);
1700 codes
[i
].code
= ASHIFT
;
1701 codes
[i
].value
= shift
;
1705 /* As for mips_build_shift, but assume that the final action will be
1706 an IOR or PLUS operation. */
1709 mips_build_lower (struct mips_integer_op
*codes
, unsigned HOST_WIDE_INT value
)
1711 unsigned HOST_WIDE_INT high
;
1714 high
= value
& ~(unsigned HOST_WIDE_INT
) 0xffff;
1715 if (!LUI_OPERAND (high
) && (value
& 0x18000) == 0x18000)
1717 /* The constant is too complex to load with a simple LUI/ORI pair,
1718 so we want to give the recursive call as many trailing zeros as
1719 possible. In this case, we know bit 16 is set and that the
1720 low 16 bits form a negative number. If we subtract that number
1721 from VALUE, we will clear at least the lowest 17 bits, maybe more. */
1722 i
= mips_build_integer (codes
, CONST_HIGH_PART (value
));
1723 codes
[i
].code
= PLUS
;
1724 codes
[i
].value
= CONST_LOW_PART (value
);
1728 /* Either this is a simple LUI/ORI pair, or clearing the lowest 16
1729 bits gives a value with at least 17 trailing zeros. */
1730 i
= mips_build_integer (codes
, high
);
1731 codes
[i
].code
= IOR
;
1732 codes
[i
].value
= value
& 0xffff;
1737 /* Fill CODES with a sequence of rtl operations to load VALUE.
1738 Return the number of operations needed. */
1741 mips_build_integer (struct mips_integer_op
*codes
,
1742 unsigned HOST_WIDE_INT value
)
1744 if (SMALL_OPERAND (value
)
1745 || SMALL_OPERAND_UNSIGNED (value
)
1746 || LUI_OPERAND (value
))
1748 /* The value can be loaded with a single instruction. */
1749 codes
[0].code
= UNKNOWN
;
1750 codes
[0].value
= value
;
1753 else if ((value
& 1) != 0 || LUI_OPERAND (CONST_HIGH_PART (value
)))
1755 /* Either the constant is a simple LUI/ORI combination or its
1756 lowest bit is set. We don't want to shift in this case. */
1757 return mips_build_lower (codes
, value
);
1759 else if ((value
& 0xffff) == 0)
1761 /* The constant will need at least three actions. The lowest
1762 16 bits are clear, so the final action will be a shift. */
1763 return mips_build_shift (codes
, value
);
1767 /* The final action could be a shift, add or inclusive OR.
1768 Rather than use a complex condition to select the best
1769 approach, try both mips_build_shift and mips_build_lower
1770 and pick the one that gives the shortest sequence.
1771 Note that this case is only used once per constant. */
1772 struct mips_integer_op alt_codes
[MIPS_MAX_INTEGER_OPS
];
1773 unsigned int cost
, alt_cost
;
1775 cost
= mips_build_shift (codes
, value
);
1776 alt_cost
= mips_build_lower (alt_codes
, value
);
1777 if (alt_cost
< cost
)
1779 memcpy (codes
, alt_codes
, alt_cost
* sizeof (codes
[0]));
1786 /* Implement TARGET_LEGITIMATE_CONSTANT_P. */
1789 mips_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED
, rtx x
)
1791 return mips_const_insns (x
) > 0;
1794 /* Return a SYMBOL_REF for a MIPS16 function called NAME. */
1797 mips16_stub_function (const char *name
)
1801 x
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (name
));
1802 SYMBOL_REF_FLAGS (x
) |= (SYMBOL_FLAG_EXTERNAL
| SYMBOL_FLAG_FUNCTION
);
1806 /* Return a legitimate call address for STUB, given that STUB is a MIPS16
1807 support function. */
1810 mips16_stub_call_address (mips_one_only_stub
*stub
)
1812 rtx fn
= mips16_stub_function (stub
->get_name ());
1813 SYMBOL_REF_FLAGS (fn
) |= SYMBOL_FLAG_LOCAL
;
1814 if (!call_insn_operand (fn
, VOIDmode
))
1815 fn
= force_reg (Pmode
, fn
);
1819 /* A stub for moving the thread pointer into TLS_GET_TP_REGNUM. */
1821 class mips16_rdhwr_one_only_stub
: public mips_one_only_stub
1823 virtual const char *get_name ();
1824 virtual void output_body ();
1828 mips16_rdhwr_one_only_stub::get_name ()
1830 return "__mips16_rdhwr";
1834 mips16_rdhwr_one_only_stub::output_body ()
1836 fprintf (asm_out_file
,
1838 "\t.set\tmips32r2\n"
1839 "\t.set\tnoreorder\n"
1845 /* A stub for moving the FCSR into GET_FCSR_REGNUM. */
1846 class mips16_get_fcsr_one_only_stub
: public mips_one_only_stub
1848 virtual const char *get_name ();
1849 virtual void output_body ();
1853 mips16_get_fcsr_one_only_stub::get_name ()
1855 return "__mips16_get_fcsr";
1859 mips16_get_fcsr_one_only_stub::output_body ()
1861 fprintf (asm_out_file
,
1863 "\tj\t$31\n", reg_names
[GET_FCSR_REGNUM
]);
1866 /* A stub for moving SET_FCSR_REGNUM into the FCSR. */
1867 class mips16_set_fcsr_one_only_stub
: public mips_one_only_stub
1869 virtual const char *get_name ();
1870 virtual void output_body ();
1874 mips16_set_fcsr_one_only_stub::get_name ()
1876 return "__mips16_set_fcsr";
1880 mips16_set_fcsr_one_only_stub::output_body ()
1882 fprintf (asm_out_file
,
1884 "\tj\t$31\n", reg_names
[SET_FCSR_REGNUM
]);
1887 /* Return true if symbols of type TYPE require a GOT access. */
1890 mips_got_symbol_type_p (enum mips_symbol_type type
)
1894 case SYMBOL_GOT_PAGE_OFST
:
1895 case SYMBOL_GOT_DISP
:
1903 /* Return true if X is a thread-local symbol. */
1906 mips_tls_symbol_p (rtx x
)
1908 return GET_CODE (x
) == SYMBOL_REF
&& SYMBOL_REF_TLS_MODEL (x
) != 0;
1911 /* Return true if SYMBOL_REF X is associated with a global symbol
1912 (in the STB_GLOBAL sense). */
1915 mips_global_symbol_p (const_rtx x
)
1917 const_tree decl
= SYMBOL_REF_DECL (x
);
1920 return !SYMBOL_REF_LOCAL_P (x
) || SYMBOL_REF_EXTERNAL_P (x
);
1922 /* Weakref symbols are not TREE_PUBLIC, but their targets are global
1923 or weak symbols. Relocations in the object file will be against
1924 the target symbol, so it's that symbol's binding that matters here. */
1925 return DECL_P (decl
) && (TREE_PUBLIC (decl
) || DECL_WEAK (decl
));
1928 /* Return true if function X is a libgcc MIPS16 stub function. */
1931 mips16_stub_function_p (const_rtx x
)
1933 return (GET_CODE (x
) == SYMBOL_REF
1934 && startswith (XSTR (x
, 0), "__mips16_"));
1937 /* Return true if function X is a locally-defined and locally-binding
1941 mips16_local_function_p (const_rtx x
)
1943 return (GET_CODE (x
) == SYMBOL_REF
1944 && SYMBOL_REF_LOCAL_P (x
)
1945 && !SYMBOL_REF_EXTERNAL_P (x
)
1946 && (mips_get_compress_mode (SYMBOL_REF_DECL (x
)) & MASK_MIPS16
));
1949 /* Return true if SYMBOL_REF X binds locally. */
1952 mips_symbol_binds_local_p (const_rtx x
)
1954 return (SYMBOL_REF_DECL (x
)
1955 ? targetm
.binds_local_p (SYMBOL_REF_DECL (x
))
1956 : SYMBOL_REF_LOCAL_P (x
));
1959 /* Return true if OP is a constant vector with the number of units in MODE,
1960 and each unit has the same bit set. */
1963 mips_const_vector_bitimm_set_p (rtx op
, machine_mode mode
)
1965 if (GET_CODE (op
) == CONST_VECTOR
&& op
!= CONST0_RTX (mode
))
1967 unsigned HOST_WIDE_INT val
= UINTVAL (CONST_VECTOR_ELT (op
, 0));
1968 int vlog2
= exact_log2 (val
& GET_MODE_MASK (GET_MODE_INNER (mode
)));
1972 gcc_assert (GET_MODE_CLASS (mode
) == MODE_VECTOR_INT
);
1973 gcc_assert (vlog2
>= 0 && vlog2
<= GET_MODE_UNIT_BITSIZE (mode
) - 1);
1974 return mips_const_vector_same_val_p (op
, mode
);
1981 /* Return true if OP is a constant vector with the number of units in MODE,
1982 and each unit has the same bit clear. */
1985 mips_const_vector_bitimm_clr_p (rtx op
, machine_mode mode
)
1987 if (GET_CODE (op
) == CONST_VECTOR
&& op
!= CONSTM1_RTX (mode
))
1989 unsigned HOST_WIDE_INT val
= ~UINTVAL (CONST_VECTOR_ELT (op
, 0));
1990 int vlog2
= exact_log2 (val
& GET_MODE_MASK (GET_MODE_INNER (mode
)));
1994 gcc_assert (GET_MODE_CLASS (mode
) == MODE_VECTOR_INT
);
1995 gcc_assert (vlog2
>= 0 && vlog2
<= GET_MODE_UNIT_BITSIZE (mode
) - 1);
1996 return mips_const_vector_same_val_p (op
, mode
);
2003 /* Return true if OP is a constant vector with the number of units in MODE,
2004 and each unit has the same value. */
2007 mips_const_vector_same_val_p (rtx op
, machine_mode mode
)
2009 int i
, nunits
= GET_MODE_NUNITS (mode
);
2012 if (GET_CODE (op
) != CONST_VECTOR
|| GET_MODE (op
) != mode
)
2015 first
= CONST_VECTOR_ELT (op
, 0);
2016 for (i
= 1; i
< nunits
; i
++)
2017 if (!rtx_equal_p (first
, CONST_VECTOR_ELT (op
, i
)))
2023 /* Return true if OP is a constant vector with the number of units in MODE,
2024 and each unit has the same value as well as replicated bytes in the value.
2028 mips_const_vector_same_bytes_p (rtx op
, machine_mode mode
)
2031 HOST_WIDE_INT val
, first_byte
;
2034 if (!mips_const_vector_same_val_p (op
, mode
))
2037 first
= CONST_VECTOR_ELT (op
, 0);
2038 bytes
= GET_MODE_UNIT_SIZE (mode
);
2039 val
= INTVAL (first
);
2040 first_byte
= val
& 0xff;
2041 for (i
= 1; i
< bytes
; i
++)
2044 if ((val
& 0xff) != first_byte
)
2051 /* Return true if OP is a constant vector with the number of units in MODE,
2052 and each unit has the same integer value in the range [LOW, HIGH]. */
2055 mips_const_vector_same_int_p (rtx op
, machine_mode mode
, HOST_WIDE_INT low
,
2058 HOST_WIDE_INT value
;
2061 if (!mips_const_vector_same_val_p (op
, mode
))
2064 elem0
= CONST_VECTOR_ELT (op
, 0);
2065 if (!CONST_INT_P (elem0
))
2068 value
= INTVAL (elem0
);
2069 return (value
>= low
&& value
<= high
);
2072 /* Return true if OP is a constant vector with repeated 4-element sets
2076 mips_const_vector_shuffle_set_p (rtx op
, machine_mode mode
)
2078 int nunits
= GET_MODE_NUNITS (mode
);
2079 int nsets
= nunits
/ 4;
2083 /* Check if we have the same 4-element sets. */
2084 for (j
= 0; j
< nsets
; j
++, set
= 4 * j
)
2085 for (i
= 0; i
< 4; i
++)
2086 if ((INTVAL (XVECEXP (op
, 0, i
))
2087 != (INTVAL (XVECEXP (op
, 0, set
+ i
)) - set
))
2088 || !IN_RANGE (INTVAL (XVECEXP (op
, 0, set
+ i
)), 0, set
+ 3))
2093 /* Return true if rtx constants of mode MODE should be put into a small
2097 mips_rtx_constant_in_small_data_p (machine_mode mode
)
2099 return (!TARGET_EMBEDDED_DATA
2100 && TARGET_LOCAL_SDATA
2101 && GET_MODE_SIZE (mode
) <= mips_small_data_threshold
);
2104 /* Return true if X should not be moved directly into register $25.
2105 We need this because many versions of GAS will treat "la $25,foo" as
2106 part of a call sequence and so allow a global "foo" to be lazily bound. */
2109 mips_dangerous_for_la25_p (rtx x
)
2111 return (!TARGET_EXPLICIT_RELOCS
2113 && GET_CODE (x
) == SYMBOL_REF
2114 && mips_global_symbol_p (x
));
2117 /* Return true if calls to X might need $25 to be valid on entry. */
2120 mips_use_pic_fn_addr_reg_p (const_rtx x
)
2122 if (!TARGET_USE_PIC_FN_ADDR_REG
)
2125 /* MIPS16 stub functions are guaranteed not to use $25. */
2126 if (mips16_stub_function_p (x
))
2129 if (GET_CODE (x
) == SYMBOL_REF
)
2131 /* If PLTs and copy relocations are available, the static linker
2132 will make sure that $25 is valid on entry to the target function. */
2133 if (TARGET_ABICALLS_PIC0
)
2136 /* Locally-defined functions use absolute accesses to set up
2137 the global pointer. */
2138 if (TARGET_ABSOLUTE_ABICALLS
2139 && mips_symbol_binds_local_p (x
)
2140 && !SYMBOL_REF_EXTERNAL_P (x
))
2147 /* Return the method that should be used to access SYMBOL_REF or
2148 LABEL_REF X in context CONTEXT. */
2150 static enum mips_symbol_type
2151 mips_classify_symbol (const_rtx x
, enum mips_symbol_context context
)
2154 return SYMBOL_GOT_DISP
;
2156 if (GET_CODE (x
) == LABEL_REF
)
2158 /* Only return SYMBOL_PC_RELATIVE if we are generating MIPS16
2159 code and if we know that the label is in the current function's
2160 text section. LABEL_REFs are used for jump tables as well as
2161 text labels, so we must check whether jump tables live in the
2163 if (TARGET_MIPS16_SHORT_JUMP_TABLES
2164 && !LABEL_REF_NONLOCAL_P (x
))
2165 return SYMBOL_PC_RELATIVE
;
2167 if (TARGET_ABICALLS
&& !TARGET_ABSOLUTE_ABICALLS
)
2168 return SYMBOL_GOT_PAGE_OFST
;
2170 return SYMBOL_ABSOLUTE
;
2173 gcc_assert (GET_CODE (x
) == SYMBOL_REF
);
2175 if (SYMBOL_REF_TLS_MODEL (x
))
2178 if (CONSTANT_POOL_ADDRESS_P (x
))
2180 if (TARGET_MIPS16_TEXT_LOADS
)
2181 return SYMBOL_PC_RELATIVE
;
2183 if (TARGET_MIPS16_PCREL_LOADS
&& context
== SYMBOL_CONTEXT_MEM
)
2184 return SYMBOL_PC_RELATIVE
;
2186 if (mips_rtx_constant_in_small_data_p (get_pool_mode (x
)))
2187 return SYMBOL_GP_RELATIVE
;
2190 /* Do not use small-data accesses for weak symbols; they may end up
2192 if (TARGET_GPOPT
&& SYMBOL_REF_SMALL_P (x
) && !SYMBOL_REF_WEAK (x
))
2193 return SYMBOL_GP_RELATIVE
;
2195 /* Don't use GOT accesses for locally-binding symbols when -mno-shared
2197 if (TARGET_ABICALLS_PIC2
2198 && !(TARGET_ABSOLUTE_ABICALLS
&& mips_symbol_binds_local_p (x
)))
2200 /* There are three cases to consider:
2202 - o32 PIC (either with or without explicit relocs)
2203 - n32/n64 PIC without explicit relocs
2204 - n32/n64 PIC with explicit relocs
2206 In the first case, both local and global accesses will use an
2207 R_MIPS_GOT16 relocation. We must correctly predict which of
2208 the two semantics (local or global) the assembler and linker
2209 will apply. The choice depends on the symbol's binding rather
2210 than its visibility.
2212 In the second case, the assembler will not use R_MIPS_GOT16
2213 relocations, but it chooses between local and global accesses
2214 in the same way as for o32 PIC.
2216 In the third case we have more freedom since both forms of
2217 access will work for any kind of symbol. However, there seems
2218 little point in doing things differently. */
2219 if (mips_global_symbol_p (x
))
2220 return SYMBOL_GOT_DISP
;
2222 return SYMBOL_GOT_PAGE_OFST
;
2225 return SYMBOL_ABSOLUTE
;
2228 /* Classify the base of symbolic expression X, given that X appears in
2231 static enum mips_symbol_type
2232 mips_classify_symbolic_expression (rtx x
, enum mips_symbol_context context
)
2236 split_const (x
, &x
, &offset
);
2237 if (UNSPEC_ADDRESS_P (x
))
2238 return UNSPEC_ADDRESS_TYPE (x
);
2240 return mips_classify_symbol (x
, context
);
2243 /* Return true if OFFSET is within the range [0, ALIGN), where ALIGN
2244 is the alignment in bytes of SYMBOL_REF X. */
2247 mips_offset_within_alignment_p (rtx x
, HOST_WIDE_INT offset
)
2249 HOST_WIDE_INT align
;
2251 align
= SYMBOL_REF_DECL (x
) ? DECL_ALIGN_UNIT (SYMBOL_REF_DECL (x
)) : 1;
2252 return IN_RANGE (offset
, 0, align
- 1);
2255 /* Return true if X is a symbolic constant that can be used in context
2256 CONTEXT. If it is, store the type of the symbol in *SYMBOL_TYPE. */
2259 mips_symbolic_constant_p (rtx x
, enum mips_symbol_context context
,
2260 enum mips_symbol_type
*symbol_type
)
2264 split_const (x
, &x
, &offset
);
2265 if (UNSPEC_ADDRESS_P (x
))
2267 *symbol_type
= UNSPEC_ADDRESS_TYPE (x
);
2268 x
= UNSPEC_ADDRESS (x
);
2270 else if (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == LABEL_REF
)
2272 *symbol_type
= mips_classify_symbol (x
, context
);
2273 if (*symbol_type
== SYMBOL_TLS
)
2279 if (offset
== const0_rtx
)
2282 /* Check whether a nonzero offset is valid for the underlying
2284 switch (*symbol_type
)
2286 case SYMBOL_ABSOLUTE
:
2287 case SYMBOL_64_HIGH
:
2290 /* If the target has 64-bit pointers and the object file only
2291 supports 32-bit symbols, the values of those symbols will be
2292 sign-extended. In this case we can't allow an arbitrary offset
2293 in case the 32-bit value X + OFFSET has a different sign from X. */
2294 if (Pmode
== DImode
&& !ABI_HAS_64BIT_SYMBOLS
)
2295 return offset_within_block_p (x
, INTVAL (offset
));
2297 /* In other cases the relocations can handle any offset. */
2300 case SYMBOL_PC_RELATIVE
:
2301 /* Allow constant pool references to be converted to LABEL+CONSTANT.
2302 In this case, we no longer have access to the underlying constant,
2303 but the original symbol-based access was known to be valid. */
2304 if (GET_CODE (x
) == LABEL_REF
)
2309 case SYMBOL_GP_RELATIVE
:
2310 /* Make sure that the offset refers to something within the
2311 same object block. This should guarantee that the final
2312 PC- or GP-relative offset is within the 16-bit limit. */
2313 return offset_within_block_p (x
, INTVAL (offset
));
2315 case SYMBOL_GOT_PAGE_OFST
:
2316 case SYMBOL_GOTOFF_PAGE
:
2317 /* If the symbol is global, the GOT entry will contain the symbol's
2318 address, and we will apply a 16-bit offset after loading it.
2319 If the symbol is local, the linker should provide enough local
2320 GOT entries for a 16-bit offset, but larger offsets may lead
2322 return SMALL_INT (offset
);
2326 /* There is no carry between the HI and LO REL relocations, so the
2327 offset is only valid if we know it won't lead to such a carry. */
2328 return mips_offset_within_alignment_p (x
, INTVAL (offset
));
2330 case SYMBOL_GOT_DISP
:
2331 case SYMBOL_GOTOFF_DISP
:
2332 case SYMBOL_GOTOFF_CALL
:
2333 case SYMBOL_GOTOFF_LOADGP
:
2336 case SYMBOL_GOTTPREL
:
2344 /* Like mips_symbol_insns, but treat extended MIPS16 instructions as a
2345 single instruction. We rely on the fact that, in the worst case,
2346 all instructions involved in a MIPS16 address calculation are usually
2350 mips_symbol_insns_1 (enum mips_symbol_type type
, machine_mode mode
)
2352 if (mips_use_pcrel_pool_p
[(int) type
])
2354 if (mode
== MAX_MACHINE_MODE
)
2355 /* LEAs will be converted into constant-pool references by
2357 type
= SYMBOL_PC_RELATIVE
;
2359 /* The constant must be loaded and then dereferenced. */
2365 case SYMBOL_ABSOLUTE
:
2366 /* When using 64-bit symbols, we need 5 preparatory instructions,
2369 lui $at,%highest(symbol)
2370 daddiu $at,$at,%higher(symbol)
2372 daddiu $at,$at,%hi(symbol)
2375 The final address is then $at + %lo(symbol). With 32-bit
2376 symbols we just need a preparatory LUI for normal mode and
2377 a preparatory LI and SLL for MIPS16. */
2378 return ABI_HAS_64BIT_SYMBOLS
2380 : (TARGET_MIPS16
&& !ISA_HAS_MIPS16E2
) ? 3 : 2;
2382 case SYMBOL_GP_RELATIVE
:
2383 /* Treat GP-relative accesses as taking a single instruction on
2384 MIPS16 too; the copy of $gp can often be shared. */
2387 case SYMBOL_PC_RELATIVE
:
2388 /* PC-relative constants can be only be used with ADDIUPC,
2389 DADDIUPC, LWPC and LDPC. */
2390 if (mode
== MAX_MACHINE_MODE
2391 || GET_MODE_SIZE (mode
) == 4
2392 || GET_MODE_SIZE (mode
) == 8)
2395 /* The constant must be loaded using ADDIUPC or DADDIUPC first. */
2398 case SYMBOL_GOT_DISP
:
2399 /* The constant will have to be loaded from the GOT before it
2400 is used in an address. */
2401 if (mode
!= MAX_MACHINE_MODE
)
2406 case SYMBOL_GOT_PAGE_OFST
:
2407 /* Unless -funit-at-a-time is in effect, we can't be sure whether the
2408 local/global classification is accurate. The worst cases are:
2410 (1) For local symbols when generating o32 or o64 code. The assembler
2416 ...and the final address will be $at + %lo(symbol).
2418 (2) For global symbols when -mxgot. The assembler will use:
2420 lui $at,%got_hi(symbol)
2423 ...and the final address will be $at + %got_lo(symbol). */
2426 case SYMBOL_GOTOFF_PAGE
:
2427 case SYMBOL_GOTOFF_DISP
:
2428 case SYMBOL_GOTOFF_CALL
:
2429 case SYMBOL_GOTOFF_LOADGP
:
2430 case SYMBOL_64_HIGH
:
2436 case SYMBOL_GOTTPREL
:
2439 /* A 16-bit constant formed by a single relocation, or a 32-bit
2440 constant formed from a high 16-bit relocation and a low 16-bit
2441 relocation. Use mips_split_p to determine which. 32-bit
2442 constants need an "lui; addiu" sequence for normal mode and
2443 an "li; sll; addiu" sequence for MIPS16 mode. */
2444 return !mips_split_p
[type
] ? 1 : TARGET_MIPS16
? 3 : 2;
2447 /* We don't treat a bare TLS symbol as a constant. */
2453 /* If MODE is MAX_MACHINE_MODE, return the number of instructions needed
2454 to load symbols of type TYPE into a register. Return 0 if the given
2455 type of symbol cannot be used as an immediate operand.
2457 Otherwise, return the number of instructions needed to load or store
2458 values of mode MODE to or from addresses of type TYPE. Return 0 if
2459 the given type of symbol is not valid in addresses.
2461 In both cases, instruction counts are based off BASE_INSN_LENGTH. */
2464 mips_symbol_insns (enum mips_symbol_type type
, machine_mode mode
)
2466 /* MSA LD.* and ST.* cannot support loading symbols via an immediate
2468 if (mode
!= MAX_MACHINE_MODE
&& MSA_SUPPORTED_MODE_P (mode
))
2471 return mips_symbol_insns_1 (type
, mode
) * (TARGET_MIPS16
? 2 : 1);
2474 /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
2477 mips_cannot_force_const_mem (machine_mode mode
, rtx x
)
2479 enum mips_symbol_type type
;
2482 /* There is no assembler syntax for expressing an address-sized
2484 if (GET_CODE (x
) == HIGH
)
2487 /* As an optimization, reject constants that mips_legitimize_move
2490 Suppose we have a multi-instruction sequence that loads constant C
2491 into register R. If R does not get allocated a hard register, and
2492 R is used in an operand that allows both registers and memory
2493 references, reload will consider forcing C into memory and using
2494 one of the instruction's memory alternatives. Returning false
2495 here will force it to use an input reload instead. */
2496 if ((CONST_INT_P (x
) || GET_CODE (x
) == CONST_VECTOR
)
2497 && mips_legitimate_constant_p (mode
, x
))
2500 split_const (x
, &base
, &offset
);
2501 if (mips_symbolic_constant_p (base
, SYMBOL_CONTEXT_LEA
, &type
))
2503 /* See whether we explicitly want these symbols in the pool. */
2504 if (mips_use_pcrel_pool_p
[(int) type
])
2507 /* The same optimization as for CONST_INT. */
2508 if (SMALL_INT (offset
) && mips_symbol_insns (type
, MAX_MACHINE_MODE
) > 0)
2511 /* If MIPS16 constant pools live in the text section, they should
2512 not refer to anything that might need run-time relocation. */
2513 if (TARGET_MIPS16_PCREL_LOADS
&& mips_got_symbol_type_p (type
))
2517 /* TLS symbols must be computed by mips_legitimize_move. */
2518 if (tls_referenced_p (x
))
2524 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. We can't use blocks for
2525 constants when we're using a per-function constant pool. */
2528 mips_use_blocks_for_constant_p (machine_mode mode ATTRIBUTE_UNUSED
,
2529 const_rtx x ATTRIBUTE_UNUSED
)
2531 return !TARGET_MIPS16_PCREL_LOADS
;
2534 /* Return true if register REGNO is a valid base register for mode MODE.
2535 STRICT_P is true if REG_OK_STRICT is in effect. */
2538 mips_regno_mode_ok_for_base_p (int regno
, machine_mode mode
,
2541 if (!HARD_REGISTER_NUM_P (regno
))
2545 regno
= reg_renumber
[regno
];
2548 /* These fake registers will be eliminated to either the stack or
2549 hard frame pointer, both of which are usually valid base registers.
2550 Reload deals with the cases where the eliminated form isn't valid. */
2551 if (regno
== ARG_POINTER_REGNUM
|| regno
== FRAME_POINTER_REGNUM
)
2554 /* In MIPS16 mode, the stack pointer can only address word and doubleword
2555 values, nothing smaller. */
2556 if (TARGET_MIPS16
&& regno
== STACK_POINTER_REGNUM
)
2557 return GET_MODE_SIZE (mode
) == 4 || GET_MODE_SIZE (mode
) == 8;
2559 if (MIPS16_GP_LOADS
&& regno
== GLOBAL_POINTER_REGNUM
)
2560 return (UNITS_PER_WORD
> 4 ? GET_MODE_SIZE (mode
) <= 4 : true);
2562 return TARGET_MIPS16
? M16_REG_P (regno
) : GP_REG_P (regno
);
2565 /* Return true if X is a valid base register for mode MODE.
2566 STRICT_P is true if REG_OK_STRICT is in effect. */
2569 mips_valid_base_register_p (rtx x
, machine_mode mode
, bool strict_p
)
2571 if (!strict_p
&& GET_CODE (x
) == SUBREG
)
2575 && mips_regno_mode_ok_for_base_p (REGNO (x
), mode
, strict_p
));
2578 /* Return true if, for every base register BASE_REG, (plus BASE_REG X)
2579 can address a value of mode MODE. */
2582 mips_valid_offset_p (rtx x
, machine_mode mode
)
2584 /* Check that X is a signed 16-bit number. */
2585 if (!const_arith_operand (x
, Pmode
))
2588 /* We may need to split multiword moves, so make sure that every word
2590 if (GET_MODE_SIZE (mode
) > UNITS_PER_WORD
2591 && !SMALL_OPERAND (INTVAL (x
) + GET_MODE_SIZE (mode
) - UNITS_PER_WORD
))
2594 /* MSA LD.* and ST.* supports 10-bit signed offsets. */
2595 if (MSA_SUPPORTED_MODE_P (mode
)
2596 && !mips_signed_immediate_p (INTVAL (x
), 10,
2597 mips_ldst_scaled_shift (mode
)))
2603 /* Return true if a LO_SUM can address a value of mode MODE when the
2604 LO_SUM symbol has type SYMBOL_TYPE. */
2607 mips_valid_lo_sum_p (enum mips_symbol_type symbol_type
, machine_mode mode
)
2609 /* Check that symbols of type SYMBOL_TYPE can be used to access values
2611 if (mips_symbol_insns (symbol_type
, mode
) == 0)
2614 /* Check that there is a known low-part relocation. */
2615 if (mips_lo_relocs
[symbol_type
] == NULL
)
2618 /* We may need to split multiword moves, so make sure that each word
2619 can be accessed without inducing a carry. This is mainly needed
2620 for o64, which has historically only guaranteed 64-bit alignment
2621 for 128-bit types. */
2622 if (GET_MODE_SIZE (mode
) > UNITS_PER_WORD
2623 && GET_MODE_BITSIZE (mode
) > GET_MODE_ALIGNMENT (mode
))
2626 /* MSA LD.* and ST.* cannot support loading symbols via %lo($base). */
2627 if (MSA_SUPPORTED_MODE_P (mode
))
2633 /* Return true if X is a valid address for machine mode MODE. If it is,
2634 fill in INFO appropriately. STRICT_P is true if REG_OK_STRICT is in
2638 mips_classify_address (struct mips_address_info
*info
, rtx x
,
2639 machine_mode mode
, bool strict_p
)
2641 switch (GET_CODE (x
))
2645 info
->type
= ADDRESS_REG
;
2647 info
->offset
= const0_rtx
;
2648 return mips_valid_base_register_p (info
->reg
, mode
, strict_p
);
2651 info
->type
= ADDRESS_REG
;
2652 info
->reg
= XEXP (x
, 0);
2653 info
->offset
= XEXP (x
, 1);
2654 return (mips_valid_base_register_p (info
->reg
, mode
, strict_p
)
2655 && mips_valid_offset_p (info
->offset
, mode
));
2658 info
->type
= ADDRESS_LO_SUM
;
2659 info
->reg
= XEXP (x
, 0);
2660 info
->offset
= XEXP (x
, 1);
2661 /* We have to trust the creator of the LO_SUM to do something vaguely
2662 sane. Target-independent code that creates a LO_SUM should also
2663 create and verify the matching HIGH. Target-independent code that
2664 adds an offset to a LO_SUM must prove that the offset will not
2665 induce a carry. Failure to do either of these things would be
2666 a bug, and we are not required to check for it here. The MIPS
2667 backend itself should only create LO_SUMs for valid symbolic
2668 constants, with the high part being either a HIGH or a copy
2671 = mips_classify_symbolic_expression (info
->offset
, SYMBOL_CONTEXT_MEM
);
2672 return (mips_valid_base_register_p (info
->reg
, mode
, strict_p
)
2673 && mips_valid_lo_sum_p (info
->symbol_type
, mode
));
2676 /* Small-integer addresses don't occur very often, but they
2677 are legitimate if $0 is a valid base register. */
2678 info
->type
= ADDRESS_CONST_INT
;
2679 return !TARGET_MIPS16
&& SMALL_INT (x
);
2684 info
->type
= ADDRESS_SYMBOLIC
;
2685 return (mips_symbolic_constant_p (x
, SYMBOL_CONTEXT_MEM
,
2687 && mips_symbol_insns (info
->symbol_type
, mode
) > 0
2688 && !mips_split_p
[info
->symbol_type
]);
2695 /* Implement TARGET_LEGITIMATE_ADDRESS_P. */
2698 mips_legitimate_address_p (machine_mode mode
, rtx x
, bool strict_p
,
2699 code_helper
= ERROR_MARK
)
2701 struct mips_address_info addr
;
2703 return mips_classify_address (&addr
, x
, mode
, strict_p
);
2706 /* Return true if X is a legitimate $sp-based address for mode MODE. */
2709 mips_stack_address_p (rtx x
, machine_mode mode
)
2711 struct mips_address_info addr
;
2713 return (mips_classify_address (&addr
, x
, mode
, false)
2714 && addr
.type
== ADDRESS_REG
2715 && addr
.reg
== stack_pointer_rtx
);
2718 /* Return true if ADDR matches the pattern for the LWXS load scaled indexed
2719 address instruction. Note that such addresses are not considered
2720 legitimate in the TARGET_LEGITIMATE_ADDRESS_P sense, because their use
2721 is so restricted. */
2724 mips_lwxs_address_p (rtx addr
)
2727 && GET_CODE (addr
) == PLUS
2728 && REG_P (XEXP (addr
, 1)))
2730 rtx offset
= XEXP (addr
, 0);
2731 if (GET_CODE (offset
) == MULT
2732 && REG_P (XEXP (offset
, 0))
2733 && CONST_INT_P (XEXP (offset
, 1))
2734 && INTVAL (XEXP (offset
, 1)) == 4)
2740 /* Return true if ADDR matches the pattern for the L{B,H,W,D}{,U}X load
2741 indexed address instruction. Note that such addresses are
2742 not considered legitimate in the TARGET_LEGITIMATE_ADDRESS_P
2743 sense, because their use is so restricted. */
2746 mips_lx_address_p (rtx addr
, machine_mode mode
)
2748 if (GET_CODE (addr
) != PLUS
2749 || !REG_P (XEXP (addr
, 0))
2750 || !REG_P (XEXP (addr
, 1)))
2752 if (ISA_HAS_LBX
&& mode
== QImode
)
2754 if (ISA_HAS_LHX
&& mode
== HImode
)
2756 if (ISA_HAS_LWX
&& mode
== SImode
)
2758 if (ISA_HAS_LDX
&& mode
== DImode
)
2760 if (MSA_SUPPORTED_MODE_P (mode
))
2765 /* Return true if a value at OFFSET bytes from base register BASE can be
2766 accessed using an unextended MIPS16 instruction. MODE is the mode of
2769 Usually the offset in an unextended instruction is a 5-bit field.
2770 The offset is unsigned and shifted left once for LH and SH, twice
2771 for LW and SW, and so on. An exception is LWSP and SWSP, which have
2772 an 8-bit immediate field that's shifted left twice. */
2775 mips16_unextended_reference_p (machine_mode mode
, rtx base
,
2776 unsigned HOST_WIDE_INT offset
)
2778 if (mode
!= BLKmode
&& offset
% GET_MODE_SIZE (mode
) == 0
2779 && REGNO (base
) != GLOBAL_POINTER_REGNUM
)
2781 if (GET_MODE_SIZE (mode
) == 4 && base
== stack_pointer_rtx
)
2782 return offset
< 256U * GET_MODE_SIZE (mode
);
2783 return offset
< 32U * GET_MODE_SIZE (mode
);
2788 /* Return the number of instructions needed to load or store a value
2789 of mode MODE at address X, assuming that BASE_INSN_LENGTH is the
2790 length of one instruction. Return 0 if X isn't valid for MODE.
2791 Assume that multiword moves may need to be split into word moves
2792 if MIGHT_SPLIT_P, otherwise assume that a single load or store is
2796 mips_address_insns (rtx x
, machine_mode mode
, bool might_split_p
)
2798 struct mips_address_info addr
;
2800 bool msa_p
= (!might_split_p
&& MSA_SUPPORTED_MODE_P (mode
));
2802 /* BLKmode is used for single unaligned loads and stores and should
2803 not count as a multiword mode. (GET_MODE_SIZE (BLKmode) is pretty
2804 meaningless, so we have to single it out as a special case one way
2806 if (mode
!= BLKmode
&& might_split_p
)
2807 factor
= (GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
2811 if (mips_classify_address (&addr
, x
, mode
, false))
2817 /* MSA LD.* and ST.* supports 10-bit signed offsets. */
2818 if (mips_signed_immediate_p (INTVAL (addr
.offset
), 10,
2819 mips_ldst_scaled_shift (mode
)))
2825 && !mips16_unextended_reference_p (mode
, addr
.reg
,
2826 UINTVAL (addr
.offset
)))
2830 case ADDRESS_LO_SUM
:
2831 return msa_p
? 0 : TARGET_MIPS16
? factor
* 2 : factor
;
2833 case ADDRESS_CONST_INT
:
2834 return msa_p
? 0 : factor
;
2836 case ADDRESS_SYMBOLIC
:
2837 return msa_p
? 0 : factor
* mips_symbol_insns (addr
.symbol_type
, mode
);
2842 /* Return true if X fits within an unsigned field of BITS bits that is
2843 shifted left SHIFT bits before being used. */
2846 mips_unsigned_immediate_p (unsigned HOST_WIDE_INT x
, int bits
, int shift
= 0)
2848 return (x
& ((1 << shift
) - 1)) == 0 && x
< ((unsigned) 1 << (shift
+ bits
));
2851 /* Return true if X fits within a signed field of BITS bits that is
2852 shifted left SHIFT bits before being used. */
2855 mips_signed_immediate_p (unsigned HOST_WIDE_INT x
, int bits
, int shift
= 0)
2857 x
+= 1 << (bits
+ shift
- 1);
2858 return mips_unsigned_immediate_p (x
, bits
, shift
);
2861 /* Return the scale shift that applied to MSA LD/ST address offset. */
2864 mips_ldst_scaled_shift (machine_mode mode
)
2866 int shift
= exact_log2 (GET_MODE_UNIT_SIZE (mode
));
2868 if (shift
< 0 || shift
> 8)
2874 /* Return true if X is legitimate for accessing values of mode MODE,
2875 if it is based on a MIPS16 register, and if the offset satisfies
2876 OFFSET_PREDICATE. */
2879 m16_based_address_p (rtx x
, machine_mode mode
,
2880 insn_operand_predicate_fn offset_predicate
)
2882 struct mips_address_info addr
;
2884 return (mips_classify_address (&addr
, x
, mode
, false)
2885 && addr
.type
== ADDRESS_REG
2886 && M16_REG_P (REGNO (addr
.reg
))
2887 && offset_predicate (addr
.offset
, mode
));
2890 /* Return true if X is a legitimate address that conforms to the requirements
2891 for a microMIPS LWSP or SWSP insn. */
2894 lwsp_swsp_address_p (rtx x
, machine_mode mode
)
2896 struct mips_address_info addr
;
2898 return (mips_classify_address (&addr
, x
, mode
, false)
2899 && addr
.type
== ADDRESS_REG
2900 && REGNO (addr
.reg
) == STACK_POINTER_REGNUM
2901 && uw5_operand (addr
.offset
, mode
));
2904 /* Return true if X is a legitimate address with a 12-bit offset.
2905 MODE is the mode of the value being accessed. */
2908 umips_12bit_offset_address_p (rtx x
, machine_mode mode
)
2910 struct mips_address_info addr
;
2912 return (mips_classify_address (&addr
, x
, mode
, false)
2913 && addr
.type
== ADDRESS_REG
2914 && CONST_INT_P (addr
.offset
)
2915 && UMIPS_12BIT_OFFSET_P (INTVAL (addr
.offset
)));
2918 /* Return true if X is a legitimate address with a 9-bit offset.
2919 MODE is the mode of the value being accessed. */
2922 mips_9bit_offset_address_p (rtx x
, machine_mode mode
)
2924 struct mips_address_info addr
;
2926 return (mips_classify_address (&addr
, x
, mode
, false)
2927 && addr
.type
== ADDRESS_REG
2928 && CONST_INT_P (addr
.offset
)
2929 && (!TARGET_MIPS16E2
2930 || M16_REG_P (REGNO (addr
.reg
))
2931 || REGNO (addr
.reg
) >= FIRST_PSEUDO_REGISTER
)
2932 && MIPS_9BIT_OFFSET_P (INTVAL (addr
.offset
)));
2935 /* Return the number of instructions needed to load constant X,
2936 assuming that BASE_INSN_LENGTH is the length of one instruction.
2937 Return 0 if X isn't a valid constant. */
2940 mips_const_insns (rtx x
)
2942 struct mips_integer_op codes
[MIPS_MAX_INTEGER_OPS
];
2943 enum mips_symbol_type symbol_type
;
2946 switch (GET_CODE (x
))
2949 if (!mips_symbolic_constant_p (XEXP (x
, 0), SYMBOL_CONTEXT_LEA
,
2951 || !mips_split_p
[symbol_type
])
2954 /* This is simply an LUI for normal mode. It is an extended
2955 LI followed by an extended SLL for MIPS16. */
2956 return TARGET_MIPS16
? (ISA_HAS_MIPS16E2
? 2 : 4) : 1;
2960 /* Unsigned 8-bit constants can be loaded using an unextended
2961 LI instruction. Unsigned 16-bit constants can be loaded
2962 using an extended LI. Negative constants must be loaded
2963 using LI and then negated. */
2964 return (IN_RANGE (INTVAL (x
), 0, 255) ? 1
2965 : SMALL_OPERAND_UNSIGNED (INTVAL (x
)) ? 2
2966 : IN_RANGE (-INTVAL (x
), 0, 255) ? 2
2967 : SMALL_OPERAND_UNSIGNED (-INTVAL (x
)) ? 3
2969 ? (trunc_int_for_mode (INTVAL (x
), SImode
) == INTVAL (x
)
2973 return mips_build_integer (codes
, INTVAL (x
));
2976 if (MSA_SUPPORTED_MODE_P (GET_MODE (x
))
2977 && mips_const_vector_same_int_p (x
, GET_MODE (x
), -512, 511))
2981 /* Allow zeros for normal mode, where we can use $0. */
2982 return !TARGET_MIPS16
&& x
== CONST0_RTX (GET_MODE (x
)) ? 1 : 0;
2988 /* See if we can refer to X directly. */
2989 if (mips_symbolic_constant_p (x
, SYMBOL_CONTEXT_LEA
, &symbol_type
))
2990 return mips_symbol_insns (symbol_type
, MAX_MACHINE_MODE
);
2992 /* Otherwise try splitting the constant into a base and offset.
2993 If the offset is a 16-bit value, we can load the base address
2994 into a register and then use (D)ADDIU to add in the offset.
2995 If the offset is larger, we can load the base and offset
2996 into separate registers and add them together with (D)ADDU.
2997 However, the latter is only possible before reload; during
2998 and after reload, we must have the option of forcing the
2999 constant into the pool instead. */
3000 split_const (x
, &x
, &offset
);
3003 int n
= mips_const_insns (x
);
3006 if (SMALL_INT (offset
))
3008 else if (!targetm
.cannot_force_const_mem (GET_MODE (x
), x
))
3009 return n
+ 1 + mips_build_integer (codes
, INTVAL (offset
));
3016 return mips_symbol_insns (mips_classify_symbol (x
, SYMBOL_CONTEXT_LEA
),
3024 /* X is a doubleword constant that can be handled by splitting it into
3025 two words and loading each word separately. Return the number of
3026 instructions required to do this, assuming that BASE_INSN_LENGTH
3027 is the length of one instruction. */
3030 mips_split_const_insns (rtx x
)
3032 unsigned int low
, high
;
3034 low
= mips_const_insns (mips_subword (x
, false));
3035 high
= mips_const_insns (mips_subword (x
, true));
3036 gcc_assert (low
> 0 && high
> 0);
3040 /* Return one word of 128-bit value OP, taking into account the fixed
3041 endianness of certain registers. BYTE selects from the byte address. */
3044 mips_subword_at_byte (rtx op
, unsigned int byte
)
3048 mode
= GET_MODE (op
);
3049 if (mode
== VOIDmode
)
3052 gcc_assert (!FP_REG_RTX_P (op
));
3055 return mips_rewrite_small_data (adjust_address (op
, word_mode
, byte
));
3057 return simplify_gen_subreg (word_mode
, op
, mode
, byte
);
3060 /* Return the number of instructions needed to implement INSN,
3061 given that it loads from or stores to MEM. Assume that
3062 BASE_INSN_LENGTH is the length of one instruction. */
3065 mips_load_store_insns (rtx mem
, rtx_insn
*insn
)
3071 gcc_assert (MEM_P (mem
));
3072 mode
= GET_MODE (mem
);
3074 /* Try to prove that INSN does not need to be split. */
3075 might_split_p
= GET_MODE_SIZE (mode
) > UNITS_PER_WORD
;
3078 set
= single_set (insn
);
3079 if (set
&& !mips_split_move_insn_p (SET_DEST (set
), SET_SRC (set
), insn
))
3080 might_split_p
= false;
3083 return mips_address_insns (XEXP (mem
, 0), mode
, might_split_p
);
3086 /* Return the number of instructions needed for an integer division,
3087 assuming that BASE_INSN_LENGTH is the length of one instruction. */
3090 mips_idiv_insns (machine_mode mode
)
3095 if (TARGET_CHECK_ZERO_DIV
)
3097 if (GENERATE_DIVIDE_TRAPS
&& !MSA_SUPPORTED_MODE_P (mode
))
3103 if (TARGET_FIX_R4000
|| TARGET_FIX_R4400
)
3109 /* Emit a move from SRC to DEST. Assume that the move expanders can
3110 handle all moves if !can_create_pseudo_p (). The distinction is
3111 important because, unlike emit_move_insn, the move expanders know
3112 how to force Pmode objects into the constant pool even when the
3113 constant pool address is not itself legitimate. */
3116 mips_emit_move (rtx dest
, rtx src
)
3118 return (can_create_pseudo_p ()
3119 ? emit_move_insn (dest
, src
)
3120 : emit_move_insn_1 (dest
, src
));
3123 /* Emit a move from SRC to DEST, splitting compound moves into individual
3124 instructions. SPLIT_TYPE is the type of split to perform. */
3127 mips_emit_move_or_split (rtx dest
, rtx src
, enum mips_split_type split_type
)
3129 if (mips_split_move_p (dest
, src
, split_type
))
3130 mips_split_move (dest
, src
, split_type
, NULL
);
3132 mips_emit_move (dest
, src
);
3135 /* Emit an instruction of the form (set TARGET (CODE OP0)). */
3138 mips_emit_unary (enum rtx_code code
, rtx target
, rtx op0
)
3140 emit_insn (gen_rtx_SET (target
, gen_rtx_fmt_e (code
, GET_MODE (op0
), op0
)));
3143 /* Compute (CODE OP0) and store the result in a new register of mode MODE.
3144 Return that new register. */
3147 mips_force_unary (machine_mode mode
, enum rtx_code code
, rtx op0
)
3151 reg
= gen_reg_rtx (mode
);
3152 mips_emit_unary (code
, reg
, op0
);
3156 /* Emit an instruction of the form (set TARGET (CODE OP0 OP1)). */
3159 mips_emit_binary (enum rtx_code code
, rtx target
, rtx op0
, rtx op1
)
3161 emit_insn (gen_rtx_SET (target
, gen_rtx_fmt_ee (code
, GET_MODE (target
),
3165 /* Compute (CODE OP0 OP1) and store the result in a new register
3166 of mode MODE. Return that new register. */
3169 mips_force_binary (machine_mode mode
, enum rtx_code code
, rtx op0
, rtx op1
)
3173 reg
= gen_reg_rtx (mode
);
3174 mips_emit_binary (code
, reg
, op0
, op1
);
3178 /* Copy VALUE to a register and return that register. If new pseudos
3179 are allowed, copy it into a new register, otherwise use DEST. */
3182 mips_force_temporary (rtx dest
, rtx value
)
3184 if (can_create_pseudo_p ())
3185 return force_reg (Pmode
, value
);
3188 mips_emit_move (dest
, value
);
3193 /* Emit a call sequence with call pattern PATTERN and return the call
3194 instruction itself (which is not necessarily the last instruction
3195 emitted). ORIG_ADDR is the original, unlegitimized address,
3196 ADDR is the legitimized form, and LAZY_P is true if the call
3197 address is lazily-bound. */
3200 mips_emit_call_insn (rtx pattern
, rtx orig_addr
, rtx addr
, bool lazy_p
)
3205 insn
= emit_call_insn (pattern
);
3207 if (TARGET_MIPS16
&& mips_use_pic_fn_addr_reg_p (orig_addr
))
3209 /* MIPS16 JALRs only take MIPS16 registers. If the target
3210 function requires $25 to be valid on entry, we must copy it
3211 there separately. The move instruction can be put in the
3212 call's delay slot. */
3213 reg
= gen_rtx_REG (Pmode
, PIC_FUNCTION_ADDR_REGNUM
);
3214 emit_insn_before (gen_move_insn (reg
, addr
), insn
);
3215 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), reg
);
3219 /* Lazy-binding stubs require $gp to be valid on entry. */
3220 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), pic_offset_table_rtx
);
3224 /* See the comment above load_call<mode> for details. */
3225 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
),
3226 gen_rtx_REG (Pmode
, GOT_VERSION_REGNUM
));
3227 emit_insn (gen_update_got_version ());
3231 && TARGET_EXPLICIT_RELOCS
3232 && TARGET_CALL_CLOBBERED_GP
)
3234 rtx post_call_tmp_reg
= gen_rtx_REG (word_mode
, POST_CALL_TMP_REG
);
3235 clobber_reg (&CALL_INSN_FUNCTION_USAGE (insn
), post_call_tmp_reg
);
3241 /* Wrap symbol or label BASE in an UNSPEC address of type SYMBOL_TYPE,
3242 then add CONST_INT OFFSET to the result. */
3245 mips_unspec_address_offset (rtx base
, rtx offset
,
3246 enum mips_symbol_type symbol_type
)
3248 base
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, base
),
3249 UNSPEC_ADDRESS_FIRST
+ symbol_type
);
3250 if (offset
!= const0_rtx
)
3251 base
= gen_rtx_PLUS (Pmode
, base
, offset
);
3252 return gen_rtx_CONST (Pmode
, base
);
3255 /* Return an UNSPEC address with underlying address ADDRESS and symbol
3256 type SYMBOL_TYPE. */
3259 mips_unspec_address (rtx address
, enum mips_symbol_type symbol_type
)
3263 split_const (address
, &base
, &offset
);
3264 return mips_unspec_address_offset (base
, offset
, symbol_type
);
3267 /* If OP is an UNSPEC address, return the address to which it refers,
3268 otherwise return OP itself. */
3271 mips_strip_unspec_address (rtx op
)
3275 split_const (op
, &base
, &offset
);
3276 if (UNSPEC_ADDRESS_P (base
))
3277 op
= plus_constant (Pmode
, UNSPEC_ADDRESS (base
), INTVAL (offset
));
3281 /* If mips_unspec_address (ADDR, SYMBOL_TYPE) is a 32-bit value, add the
3282 high part to BASE and return the result. Just return BASE otherwise.
3283 TEMP is as for mips_force_temporary.
3285 The returned expression can be used as the first operand to a LO_SUM. */
3288 mips_unspec_offset_high (rtx temp
, rtx base
, rtx addr
,
3289 enum mips_symbol_type symbol_type
)
3291 if (mips_split_p
[symbol_type
])
3293 addr
= gen_rtx_HIGH (Pmode
, mips_unspec_address (addr
, symbol_type
));
3294 addr
= mips_force_temporary (temp
, addr
);
3295 base
= mips_force_temporary (temp
, gen_rtx_PLUS (Pmode
, addr
, base
));
3300 /* Return an instruction that copies $gp into register REG. We want
3301 GCC to treat the register's value as constant, so that its value
3302 can be rematerialized on demand. */
3305 gen_load_const_gp (rtx reg
)
3307 return PMODE_INSN (gen_load_const_gp
, (reg
));
3310 /* Return a pseudo register that contains the value of $gp throughout
3311 the current function. Such registers are needed by MIPS16 functions,
3312 for which $gp itself is not a valid base register or addition operand. */
3315 mips16_gp_pseudo_reg (void)
3317 if (cfun
->machine
->mips16_gp_pseudo_rtx
== NULL_RTX
)
3321 cfun
->machine
->mips16_gp_pseudo_rtx
= gen_reg_rtx (Pmode
);
3323 push_topmost_sequence ();
3325 scan
= get_insns ();
3326 while (NEXT_INSN (scan
) && !INSN_P (NEXT_INSN (scan
)))
3327 scan
= NEXT_INSN (scan
);
3329 rtx set
= gen_load_const_gp (cfun
->machine
->mips16_gp_pseudo_rtx
);
3330 rtx_insn
*insn
= emit_insn_after (set
, scan
);
3331 INSN_LOCATION (insn
) = 0;
3333 pop_topmost_sequence ();
3336 return cfun
->machine
->mips16_gp_pseudo_rtx
;
3339 /* Return a base register that holds pic_offset_table_rtx.
3340 TEMP, if nonnull, is a scratch Pmode base register. */
3343 mips_pic_base_register (rtx temp
)
3345 if (MIPS16_GP_LOADS
||!TARGET_MIPS16
)
3346 return pic_offset_table_rtx
;
3348 if (currently_expanding_to_rtl
)
3349 return mips16_gp_pseudo_reg ();
3351 if (can_create_pseudo_p ())
3352 temp
= gen_reg_rtx (Pmode
);
3355 /* The first post-reload split exposes all references to $gp
3356 (both uses and definitions). All references must remain
3357 explicit after that point.
3359 It is safe to introduce uses of $gp at any time, so for
3360 simplicity, we do that before the split too. */
3361 mips_emit_move (temp
, pic_offset_table_rtx
);
3363 emit_insn (gen_load_const_gp (temp
));
3367 /* Return the RHS of a load_call<mode> insn. */
3370 mips_unspec_call (rtx reg
, rtx symbol
)
3374 vec
= gen_rtvec (3, reg
, symbol
, gen_rtx_REG (SImode
, GOT_VERSION_REGNUM
));
3375 return gen_rtx_UNSPEC (Pmode
, vec
, UNSPEC_LOAD_CALL
);
3378 /* If SRC is the RHS of a load_call<mode> insn, return the underlying symbol
3379 reference. Return NULL_RTX otherwise. */
3382 mips_strip_unspec_call (rtx src
)
3384 if (GET_CODE (src
) == UNSPEC
&& XINT (src
, 1) == UNSPEC_LOAD_CALL
)
3385 return mips_strip_unspec_address (XVECEXP (src
, 0, 1));
3389 /* Create and return a GOT reference of type TYPE for address ADDR.
3390 TEMP, if nonnull, is a scratch Pmode base register. */
3393 mips_got_load (rtx temp
, rtx addr
, enum mips_symbol_type type
)
3395 rtx base
, high
, lo_sum_symbol
;
3397 base
= mips_pic_base_register (temp
);
3399 /* If we used the temporary register to load $gp, we can't use
3400 it for the high part as well. */
3401 if (temp
!= NULL
&& reg_overlap_mentioned_p (base
, temp
))
3404 high
= mips_unspec_offset_high (temp
, base
, addr
, type
);
3405 lo_sum_symbol
= mips_unspec_address (addr
, type
);
3407 if (type
== SYMBOL_GOTOFF_CALL
)
3408 return mips_unspec_call (high
, lo_sum_symbol
);
3410 return PMODE_INSN (gen_unspec_got
, (high
, lo_sum_symbol
));
3413 /* If MODE is MAX_MACHINE_MODE, ADDR appears as a move operand, otherwise
3414 it appears in a MEM of that mode. Return true if ADDR is a legitimate
3415 constant in that context and can be split into high and low parts.
3416 If so, and if LOW_OUT is nonnull, emit the high part and store the
3417 low part in *LOW_OUT. Leave *LOW_OUT unchanged otherwise.
3419 TEMP is as for mips_force_temporary and is used to load the high
3420 part into a register.
3422 When MODE is MAX_MACHINE_MODE, the low part is guaranteed to be
3423 a legitimize SET_SRC for an .md pattern, otherwise the low part
3424 is guaranteed to be a legitimate address for mode MODE. */
3427 mips_split_symbol (rtx temp
, rtx addr
, machine_mode mode
, rtx
*low_out
)
3429 enum mips_symbol_context context
;
3430 enum mips_symbol_type symbol_type
;
3433 context
= (mode
== MAX_MACHINE_MODE
3434 ? SYMBOL_CONTEXT_LEA
3435 : SYMBOL_CONTEXT_MEM
);
3436 if (GET_CODE (addr
) == HIGH
&& context
== SYMBOL_CONTEXT_LEA
)
3438 addr
= XEXP (addr
, 0);
3439 if (mips_symbolic_constant_p (addr
, context
, &symbol_type
)
3440 && mips_symbol_insns (symbol_type
, mode
) > 0
3441 && mips_split_hi_p
[symbol_type
])
3444 switch (symbol_type
)
3446 case SYMBOL_GOT_PAGE_OFST
:
3447 /* The high part of a page/ofst pair is loaded from the GOT. */
3448 *low_out
= mips_got_load (temp
, addr
, SYMBOL_GOTOFF_PAGE
);
3459 if (mips_symbolic_constant_p (addr
, context
, &symbol_type
)
3460 && mips_symbol_insns (symbol_type
, mode
) > 0
3461 && mips_split_p
[symbol_type
])
3464 switch (symbol_type
)
3466 case SYMBOL_GOT_DISP
:
3467 /* SYMBOL_GOT_DISP symbols are loaded from the GOT. */
3468 *low_out
= mips_got_load (temp
, addr
, SYMBOL_GOTOFF_DISP
);
3471 case SYMBOL_GP_RELATIVE
:
3472 high
= mips_pic_base_register (temp
);
3473 *low_out
= gen_rtx_LO_SUM (Pmode
, high
, addr
);
3477 high
= gen_rtx_HIGH (Pmode
, copy_rtx (addr
));
3478 high
= mips_force_temporary (temp
, high
);
3479 *low_out
= gen_rtx_LO_SUM (Pmode
, high
, addr
);
3488 /* Return a legitimate address for REG + OFFSET. TEMP is as for
3489 mips_force_temporary; it is only needed when OFFSET is not a
3493 mips_add_offset (rtx temp
, rtx reg
, HOST_WIDE_INT offset
)
3495 if (!SMALL_OPERAND (offset
))
3501 /* Load the full offset into a register so that we can use
3502 an unextended instruction for the address itself. */
3503 high
= GEN_INT (offset
);
3508 /* Leave OFFSET as a 16-bit offset and put the excess in HIGH.
3509 The addition inside the macro CONST_HIGH_PART may cause an
3510 overflow, so we need to force a sign-extension check. */
3511 high
= gen_int_mode (CONST_HIGH_PART (offset
), Pmode
);
3512 offset
= CONST_LOW_PART (offset
);
3514 high
= mips_force_temporary (temp
, high
);
3515 reg
= mips_force_temporary (temp
, gen_rtx_PLUS (Pmode
, high
, reg
));
3517 return plus_constant (Pmode
, reg
, offset
);
3520 /* The __tls_get_attr symbol. */
3521 static GTY(()) rtx mips_tls_symbol
;
3523 /* Return an instruction sequence that calls __tls_get_addr. SYM is
3524 the TLS symbol we are referencing and TYPE is the symbol type to use
3525 (either global dynamic or local dynamic). V0 is an RTX for the
3526 return value location. */
3529 mips_call_tls_get_addr (rtx sym
, enum mips_symbol_type type
, rtx v0
)
3534 a0
= gen_rtx_REG (Pmode
, GP_ARG_FIRST
);
3536 if (!mips_tls_symbol
)
3537 mips_tls_symbol
= init_one_libfunc ("__tls_get_addr");
3539 loc
= mips_unspec_address (sym
, type
);
3543 emit_insn (gen_rtx_SET (a0
, gen_rtx_LO_SUM (Pmode
, pic_offset_table_rtx
,
3545 insn
= mips_expand_call (MIPS_CALL_NORMAL
, v0
, mips_tls_symbol
,
3546 const0_rtx
, NULL_RTX
, false);
3547 RTL_CONST_CALL_P (insn
) = 1;
3548 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), a0
);
3549 insn
= get_insns ();
3556 /* Return a pseudo register that contains the current thread pointer. */
3559 mips_expand_thread_pointer (rtx tp
)
3565 if (!mips16_rdhwr_stub
)
3566 mips16_rdhwr_stub
= new mips16_rdhwr_one_only_stub ();
3567 fn
= mips16_stub_call_address (mips16_rdhwr_stub
);
3568 emit_insn (PMODE_INSN (gen_tls_get_tp_mips16
, (tp
, fn
)));
3571 emit_insn (PMODE_INSN (gen_tls_get_tp
, (tp
)));
3578 return mips_expand_thread_pointer (gen_reg_rtx (Pmode
));
3581 /* Generate the code to access LOC, a thread-local SYMBOL_REF, and return
3582 its address. The return value will be both a valid address and a valid
3583 SET_SRC (either a REG or a LO_SUM). */
3586 mips_legitimize_tls_address (rtx loc
)
3588 rtx dest
, v0
, tp
, tmp1
, tmp2
, eqv
, offset
;
3589 enum tls_model model
;
3591 model
= SYMBOL_REF_TLS_MODEL (loc
);
3592 /* Only TARGET_ABICALLS code can have more than one module; other
3593 code must be static and should not use a GOT. All TLS models
3594 reduce to local exec in this situation. */
3595 if (!TARGET_ABICALLS
)
3596 model
= TLS_MODEL_LOCAL_EXEC
;
3600 case TLS_MODEL_GLOBAL_DYNAMIC
:
3602 v0
= gen_rtx_REG (Pmode
, GP_RETURN
);
3603 rtx_insn
*insn
= mips_call_tls_get_addr (loc
, SYMBOL_TLSGD
, v0
);
3604 dest
= gen_reg_rtx (Pmode
);
3605 emit_libcall_block (insn
, dest
, v0
, loc
);
3609 case TLS_MODEL_LOCAL_DYNAMIC
:
3611 v0
= gen_rtx_REG (Pmode
, GP_RETURN
);
3612 rtx_insn
*insn
= mips_call_tls_get_addr (loc
, SYMBOL_TLSLDM
, v0
);
3613 tmp1
= gen_reg_rtx (Pmode
);
3615 /* Attach a unique REG_EQUIV, to allow the RTL optimizers to
3616 share the LDM result with other LD model accesses. */
3617 eqv
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
),
3619 emit_libcall_block (insn
, tmp1
, v0
, eqv
);
3621 offset
= mips_unspec_address (loc
, SYMBOL_DTPREL
);
3622 if (mips_split_p
[SYMBOL_DTPREL
])
3624 tmp2
= mips_unspec_offset_high (NULL
, tmp1
, loc
, SYMBOL_DTPREL
);
3625 dest
= gen_rtx_LO_SUM (Pmode
, tmp2
, offset
);
3628 dest
= expand_binop (Pmode
, add_optab
, tmp1
, offset
,
3629 0, 0, OPTAB_DIRECT
);
3633 case TLS_MODEL_INITIAL_EXEC
:
3634 tp
= mips_get_tp ();
3635 tmp1
= gen_reg_rtx (Pmode
);
3636 tmp2
= mips_unspec_address (loc
, SYMBOL_GOTTPREL
);
3637 if (Pmode
== DImode
)
3638 emit_insn (gen_load_gotdi (tmp1
, pic_offset_table_rtx
, tmp2
));
3640 emit_insn (gen_load_gotsi (tmp1
, pic_offset_table_rtx
, tmp2
));
3641 dest
= gen_reg_rtx (Pmode
);
3642 emit_insn (gen_add3_insn (dest
, tmp1
, tp
));
3645 case TLS_MODEL_LOCAL_EXEC
:
3646 tmp1
= mips_get_tp ();
3647 offset
= mips_unspec_address (loc
, SYMBOL_TPREL
);
3648 if (mips_split_p
[SYMBOL_TPREL
])
3650 tmp2
= mips_unspec_offset_high (NULL
, tmp1
, loc
, SYMBOL_TPREL
);
3651 dest
= gen_rtx_LO_SUM (Pmode
, tmp2
, offset
);
3654 dest
= expand_binop (Pmode
, add_optab
, tmp1
, offset
,
3655 0, 0, OPTAB_DIRECT
);
3664 /* Implement "TARGET = __builtin_mips_get_fcsr ()" for MIPS16,
3668 mips16_expand_get_fcsr (rtx target
)
3670 if (!mips16_get_fcsr_stub
)
3671 mips16_get_fcsr_stub
= new mips16_get_fcsr_one_only_stub ();
3672 rtx fn
= mips16_stub_call_address (mips16_get_fcsr_stub
);
3673 emit_insn (PMODE_INSN (gen_mips_get_fcsr_mips16
, (fn
)));
3674 emit_move_insn (target
, gen_rtx_REG (SImode
, GET_FCSR_REGNUM
));
3677 /* Implement __builtin_mips_set_fcsr (TARGET) for MIPS16, using a stub. */
3680 mips16_expand_set_fcsr (rtx newval
)
3682 if (!mips16_set_fcsr_stub
)
3683 mips16_set_fcsr_stub
= new mips16_set_fcsr_one_only_stub ();
3684 rtx fn
= mips16_stub_call_address (mips16_set_fcsr_stub
);
3685 emit_move_insn (gen_rtx_REG (SImode
, SET_FCSR_REGNUM
), newval
);
3686 emit_insn (PMODE_INSN (gen_mips_set_fcsr_mips16
, (fn
)));
3689 /* If X is not a valid address for mode MODE, force it into a register. */
3692 mips_force_address (rtx x
, machine_mode mode
)
3694 if (!mips_legitimate_address_p (mode
, x
, false))
3695 x
= force_reg (Pmode
, x
);
3699 /* This function is used to implement LEGITIMIZE_ADDRESS. If X can
3700 be legitimized in a way that the generic machinery might not expect,
3701 return a new address, otherwise return NULL. MODE is the mode of
3702 the memory being accessed. */
3705 mips_legitimize_address (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
3709 HOST_WIDE_INT offset
;
3711 if (mips_tls_symbol_p (x
))
3712 return mips_legitimize_tls_address (x
);
3714 /* See if the address can split into a high part and a LO_SUM. */
3715 if (mips_split_symbol (NULL
, x
, mode
, &addr
))
3716 return mips_force_address (addr
, mode
);
3718 /* Handle BASE + OFFSET using mips_add_offset. */
3719 mips_split_plus (x
, &base
, &offset
);
3722 if (!mips_valid_base_register_p (base
, mode
, false))
3723 base
= copy_to_mode_reg (Pmode
, base
);
3724 addr
= mips_add_offset (NULL
, base
, offset
);
3725 return mips_force_address (addr
, mode
);
3731 /* Load VALUE into DEST. TEMP is as for mips_force_temporary. */
3734 mips_move_integer (rtx temp
, rtx dest
, unsigned HOST_WIDE_INT value
)
3736 struct mips_integer_op codes
[MIPS_MAX_INTEGER_OPS
];
3738 unsigned int i
, num_ops
;
3741 mode
= GET_MODE (dest
);
3742 num_ops
= mips_build_integer (codes
, value
);
3744 /* Apply each binary operation to X. Invariant: X is a legitimate
3745 source operand for a SET pattern. */
3746 x
= GEN_INT (codes
[0].value
);
3747 for (i
= 1; i
< num_ops
; i
++)
3749 if (!can_create_pseudo_p ())
3751 emit_insn (gen_rtx_SET (temp
, x
));
3755 x
= force_reg (mode
, x
);
3756 x
= gen_rtx_fmt_ee (codes
[i
].code
, mode
, x
, GEN_INT (codes
[i
].value
));
3759 emit_insn (gen_rtx_SET (dest
, x
));
3762 /* Subroutine of mips_legitimize_move. Move constant SRC into register
3763 DEST given that SRC satisfies immediate_operand but doesn't satisfy
3767 mips_legitimize_const_move (machine_mode mode
, rtx dest
, rtx src
)
3771 /* Split moves of big integers into smaller pieces. */
3772 if (splittable_const_int_operand (src
, mode
))
3774 mips_move_integer (dest
, dest
, INTVAL (src
));
3778 /* Split moves of symbolic constants into high/low pairs. */
3779 if (mips_split_symbol (dest
, src
, MAX_MACHINE_MODE
, &src
))
3781 emit_insn (gen_rtx_SET (dest
, src
));
3785 /* Generate the appropriate access sequences for TLS symbols. */
3786 if (mips_tls_symbol_p (src
))
3788 mips_emit_move (dest
, mips_legitimize_tls_address (src
));
3792 /* If we have (const (plus symbol offset)), and that expression cannot
3793 be forced into memory, load the symbol first and add in the offset.
3794 In non-MIPS16 mode, prefer to do this even if the constant _can_ be
3795 forced into memory, as it usually produces better code. */
3796 split_const (src
, &base
, &offset
);
3797 if (offset
!= const0_rtx
3798 && (targetm
.cannot_force_const_mem (mode
, src
)
3799 || (!TARGET_MIPS16
&& can_create_pseudo_p ())))
3801 base
= mips_force_temporary (dest
, base
);
3802 mips_emit_move (dest
, mips_add_offset (NULL
, base
, INTVAL (offset
)));
3806 src
= force_const_mem (mode
, src
);
3808 /* When using explicit relocs, constant pool references are sometimes
3809 not legitimate addresses. */
3810 mips_split_symbol (dest
, XEXP (src
, 0), mode
, &XEXP (src
, 0));
3811 mips_emit_move (dest
, src
);
3814 /* If (set DEST SRC) is not a valid move instruction, emit an equivalent
3815 sequence that is valid. */
3818 mips_legitimize_move (machine_mode mode
, rtx dest
, rtx src
)
3820 /* Both src and dest are non-registers; one special case is supported where
3821 the source is (const_int 0) and the store can source the zero register.
3822 MIPS16 and MSA are never able to source the zero register directly in
3823 memory operations. */
3824 if (!register_operand (dest
, mode
)
3825 && !register_operand (src
, mode
)
3826 && (TARGET_MIPS16
|| !const_0_operand (src
, mode
)
3827 || MSA_SUPPORTED_MODE_P (mode
)))
3829 mips_emit_move (dest
, force_reg (mode
, src
));
3833 /* We need to deal with constants that would be legitimate
3834 immediate_operands but aren't legitimate move_operands. */
3835 if (CONSTANT_P (src
) && !move_operand (src
, mode
))
3837 mips_legitimize_const_move (mode
, dest
, src
);
3838 set_unique_reg_note (get_last_insn (), REG_EQUAL
, copy_rtx (src
));
3844 /* Return true if value X in context CONTEXT is a small-data address
3845 that can be rewritten as a LO_SUM. */
3848 mips_rewrite_small_data_p (rtx x
, enum mips_symbol_context context
)
3850 enum mips_symbol_type symbol_type
;
3852 return (mips_lo_relocs
[SYMBOL_GP_RELATIVE
]
3853 && !mips_split_p
[SYMBOL_GP_RELATIVE
]
3854 && mips_symbolic_constant_p (x
, context
, &symbol_type
)
3855 && symbol_type
== SYMBOL_GP_RELATIVE
);
3858 /* Return true if OP refers to small data symbols directly, not through
3859 a LO_SUM. CONTEXT is the context in which X appears. */
3862 mips_small_data_pattern_1 (rtx x
, enum mips_symbol_context context
)
3864 subrtx_var_iterator::array_type array
;
3865 FOR_EACH_SUBRTX_VAR (iter
, array
, x
, ALL
)
3869 /* Ignore things like "g" constraints in asms. We make no particular
3870 guarantee about which symbolic constants are acceptable as asm operands
3871 versus which must be forced into a GPR. */
3872 if (GET_CODE (x
) == LO_SUM
|| GET_CODE (x
) == ASM_OPERANDS
)
3873 iter
.skip_subrtxes ();
3876 if (mips_small_data_pattern_1 (XEXP (x
, 0), SYMBOL_CONTEXT_MEM
))
3878 iter
.skip_subrtxes ();
3880 else if (mips_rewrite_small_data_p (x
, context
))
3886 /* Return true if OP refers to small data symbols directly, not through
3890 mips_small_data_pattern_p (rtx op
)
3892 return mips_small_data_pattern_1 (op
, SYMBOL_CONTEXT_LEA
);
3895 /* Rewrite *LOC so that it refers to small data using explicit
3896 relocations. CONTEXT is the context in which *LOC appears. */
3899 mips_rewrite_small_data_1 (rtx
*loc
, enum mips_symbol_context context
)
3901 subrtx_ptr_iterator::array_type array
;
3902 FOR_EACH_SUBRTX_PTR (iter
, array
, loc
, ALL
)
3907 mips_rewrite_small_data_1 (&XEXP (*loc
, 0), SYMBOL_CONTEXT_MEM
);
3908 iter
.skip_subrtxes ();
3910 else if (mips_rewrite_small_data_p (*loc
, context
))
3912 *loc
= gen_rtx_LO_SUM (Pmode
, pic_offset_table_rtx
, *loc
);
3913 iter
.skip_subrtxes ();
3915 else if (GET_CODE (*loc
) == LO_SUM
)
3916 iter
.skip_subrtxes ();
3920 /* Rewrite instruction pattern PATTERN so that it refers to small data
3921 using explicit relocations. */
3924 mips_rewrite_small_data (rtx pattern
)
3926 pattern
= copy_insn (pattern
);
3927 mips_rewrite_small_data_1 (&pattern
, SYMBOL_CONTEXT_LEA
);
3931 /* The cost of loading values from the constant pool. It should be
3932 larger than the cost of any constant we want to synthesize inline. */
3933 #define CONSTANT_POOL_COST COSTS_N_INSNS (TARGET_MIPS16 ? 4 : 8)
3935 /* Return the cost of X when used as an operand to the MIPS16 instruction
3936 that implements CODE. Return -1 if there is no such instruction, or if
3937 X is not a valid immediate operand for it. */
3940 mips16_constant_cost (int code
, HOST_WIDE_INT x
)
3947 /* Shifts by between 1 and 8 bits (inclusive) are unextended,
3948 other shifts are extended. The shift patterns truncate the shift
3949 count to the right size, so there are no out-of-range values. */
3950 if (IN_RANGE (x
, 1, 8))
3952 return COSTS_N_INSNS (1);
3955 if (IN_RANGE (x
, -128, 127))
3957 if (SMALL_OPERAND (x
))
3958 return COSTS_N_INSNS (1);
3962 /* Like LE, but reject the always-true case. */
3967 /* We add 1 to the immediate and use SLT. */
3971 /* We can use CMPI for an xor with an unsigned 16-bit X. */
3974 if (IN_RANGE (x
, 0, 255))
3976 if (SMALL_OPERAND_UNSIGNED (x
))
3977 return COSTS_N_INSNS (1);
3982 /* Equality comparisons with 0 are cheap. */
3988 /* The bit position and size are immediate operands. */
3989 return ISA_HAS_EXT_INS
? COSTS_N_INSNS (1) : -1;
3996 /* Return true if there is a non-MIPS16 instruction that implements CODE
3997 and if that instruction accepts X as an immediate operand. */
4000 mips_immediate_operand_p (int code
, HOST_WIDE_INT x
)
4007 /* All shift counts are truncated to a valid constant. */
4012 /* Likewise rotates, if the target supports rotates at all. */
4018 /* These instructions take 16-bit unsigned immediates. */
4019 return SMALL_OPERAND_UNSIGNED (x
);
4024 /* These instructions take 16-bit signed immediates. */
4025 return SMALL_OPERAND (x
);
4031 /* The "immediate" forms of these instructions are really
4032 implemented as comparisons with register 0. */
4037 /* Likewise, meaning that the only valid immediate operand is 1. */
4041 /* We add 1 to the immediate and use SLT. */
4042 return SMALL_OPERAND (x
+ 1);
4045 /* Likewise SLTU, but reject the always-true case. */
4046 return SMALL_OPERAND (x
+ 1) && x
+ 1 != 0;
4050 /* The bit position and size are immediate operands. */
4051 return ISA_HAS_EXT_INS
;
4054 /* By default assume that $0 can be used for 0. */
4059 /* Return the cost of binary operation X, given that the instruction
4060 sequence for a word-sized or smaller operation has cost SINGLE_COST
4061 and that the sequence of a double-word operation has cost DOUBLE_COST.
4062 If SPEED is true, optimize for speed otherwise optimize for size. */
4065 mips_binary_cost (rtx x
, int single_cost
, int double_cost
, bool speed
)
4069 if (GET_MODE_SIZE (GET_MODE (x
)) == UNITS_PER_WORD
* 2)
4074 + set_src_cost (XEXP (x
, 0), GET_MODE (x
), speed
)
4075 + rtx_cost (XEXP (x
, 1), GET_MODE (x
), GET_CODE (x
), 1, speed
));
4078 /* Return the cost of floating-point multiplications of mode MODE. */
4081 mips_fp_mult_cost (machine_mode mode
)
4083 return mode
== DFmode
? mips_cost
->fp_mult_df
: mips_cost
->fp_mult_sf
;
4086 /* Return the cost of floating-point divisions of mode MODE. */
4089 mips_fp_div_cost (machine_mode mode
)
4091 return mode
== DFmode
? mips_cost
->fp_div_df
: mips_cost
->fp_div_sf
;
4094 /* Return the cost of sign-extending OP to mode MODE, not including the
4095 cost of OP itself. */
4098 mips_sign_extend_cost (machine_mode mode
, rtx op
)
4101 /* Extended loads are as cheap as unextended ones. */
4104 if (TARGET_64BIT
&& mode
== DImode
&& GET_MODE (op
) == SImode
)
4105 /* A sign extension from SImode to DImode in 64-bit mode is free. */
4108 if (ISA_HAS_SEB_SEH
|| GENERATE_MIPS16E
)
4109 /* We can use SEB or SEH. */
4110 return COSTS_N_INSNS (1);
4112 /* We need to use a shift left and a shift right. */
4113 return COSTS_N_INSNS (TARGET_MIPS16
? 4 : 2);
4116 /* Return the cost of zero-extending OP to mode MODE, not including the
4117 cost of OP itself. */
4120 mips_zero_extend_cost (machine_mode mode
, rtx op
)
4123 /* Extended loads are as cheap as unextended ones. */
4126 if (TARGET_64BIT
&& mode
== DImode
&& GET_MODE (op
) == SImode
)
4127 /* We need a shift left by 32 bits and a shift right by 32 bits. */
4128 return COSTS_N_INSNS (TARGET_MIPS16
? 4 : 2);
4130 if (GENERATE_MIPS16E
)
4131 /* We can use ZEB or ZEH. */
4132 return COSTS_N_INSNS (1);
4135 /* We need to load 0xff or 0xffff into a register and use AND. */
4136 return COSTS_N_INSNS (GET_MODE (op
) == QImode
? 2 : 3);
4138 /* We can use ANDI. */
4139 return COSTS_N_INSNS (1);
4142 /* Return the cost of moving between two registers of mode MODE,
4143 assuming that the move will be in pieces of at most UNITS bytes. */
4146 mips_set_reg_reg_piece_cost (machine_mode mode
, unsigned int units
)
4148 return COSTS_N_INSNS ((GET_MODE_SIZE (mode
) + units
- 1) / units
);
4151 /* Return the cost of moving between two registers of mode MODE. */
4154 mips_set_reg_reg_cost (machine_mode mode
)
4156 switch (GET_MODE_CLASS (mode
))
4159 return mips_set_reg_reg_piece_cost (mode
, GET_MODE_SIZE (CCmode
));
4162 case MODE_COMPLEX_FLOAT
:
4163 case MODE_VECTOR_FLOAT
:
4164 if (TARGET_HARD_FLOAT
)
4165 return mips_set_reg_reg_piece_cost (mode
, UNITS_PER_HWFPVALUE
);
4169 return mips_set_reg_reg_piece_cost (mode
, UNITS_PER_WORD
);
4173 /* Implement TARGET_INSN_COSTS. */
4176 mips_insn_cost (rtx_insn
*x
, bool speed
)
4182 if (recog_memoized (x
) < 0
4183 && GET_CODE (PATTERN (x
)) != ASM_INPUT
4184 && asm_noperands (PATTERN (x
)) < 0)
4187 /* FIXME: return get_attr_length? More tests may be needed. */
4191 count
= get_attr_insn_count (x
);
4192 ratio
= get_attr_perf_ratio (x
);
4193 cost
= count
* ratio
;
4198 cost
= pattern_cost (PATTERN (x
), speed
);
4199 /* If the cost is zero, then it's likely a complex insn.
4200 FIXME: Return COSTS_N_INSNS (2)? More tests are needed. */
4204 /* Implement TARGET_RTX_COSTS. */
4207 mips_rtx_costs (rtx x
, machine_mode mode
, int outer_code
,
4208 int opno ATTRIBUTE_UNUSED
, int *total
, bool speed
)
4210 int code
= GET_CODE (x
);
4211 bool float_mode_p
= FLOAT_MODE_P (mode
);
4215 /* The cost of a COMPARE is hard to define for MIPS. COMPAREs don't
4216 appear in the instruction stream, and the cost of a comparison is
4217 really the cost of the branch or scc condition. At the time of
4218 writing, GCC only uses an explicit outer COMPARE code when optabs
4219 is testing whether a constant is expensive enough to force into a
4220 register. We want optabs to pass such constants through the MIPS
4221 expanders instead, so make all constants very cheap here. */
4222 if (outer_code
== COMPARE
)
4224 gcc_assert (CONSTANT_P (x
));
4232 /* Treat *clear_upper32-style ANDs as having zero cost in the
4233 second operand. The cost is entirely in the first operand.
4235 ??? This is needed because we would otherwise try to CSE
4236 the constant operand. Although that's the right thing for
4237 instructions that continue to be a register operation throughout
4238 compilation, it is disastrous for instructions that could
4239 later be converted into a memory operation. */
4241 && outer_code
== AND
4242 && UINTVAL (x
) == 0xffffffff)
4250 cost
= mips16_constant_cost (outer_code
, INTVAL (x
));
4259 /* When not optimizing for size, we care more about the cost
4260 of hot code, and hot code is often in a loop. If a constant
4261 operand needs to be forced into a register, we will often be
4262 able to hoist the constant load out of the loop, so the load
4263 should not contribute to the cost. */
4264 if (speed
|| mips_immediate_operand_p (outer_code
, INTVAL (x
)))
4276 if (force_to_mem_operand (x
, VOIDmode
))
4278 *total
= COSTS_N_INSNS (1);
4281 cost
= mips_const_insns (x
);
4284 /* If the constant is likely to be stored in a GPR, SETs of
4285 single-insn constants are as cheap as register sets; we
4286 never want to CSE them.
4288 Don't reduce the cost of storing a floating-point zero in
4289 FPRs. If we have a zero in an FPR for other reasons, we
4290 can get better cfg-cleanup and delayed-branch results by
4291 using it consistently, rather than using $0 sometimes and
4292 an FPR at other times. Also, moves between floating-point
4293 registers are sometimes cheaper than (D)MTC1 $0. */
4295 && outer_code
== SET
4296 && !(float_mode_p
&& TARGET_HARD_FLOAT
))
4298 /* When non-MIPS16 code loads a constant N>1 times, we rarely
4299 want to CSE the constant itself. It is usually better to
4300 have N copies of the last operation in the sequence and one
4301 shared copy of the other operations. (Note that this is
4302 not true for MIPS16 code, where the final operation in the
4303 sequence is often an extended instruction.)
4305 Also, if we have a CONST_INT, we don't know whether it is
4306 for a word or doubleword operation, so we cannot rely on
4307 the result of mips_build_integer. */
4308 else if (!TARGET_MIPS16
4309 && (outer_code
== SET
|| GET_MODE (x
) == VOIDmode
))
4311 *total
= COSTS_N_INSNS (cost
);
4314 /* The value will need to be fetched from the constant pool. */
4315 *total
= CONSTANT_POOL_COST
;
4319 /* If the address is legitimate, return the number of
4320 instructions it needs. */
4322 cost
= mips_address_insns (addr
, mode
, true);
4325 *total
= COSTS_N_INSNS (cost
+ 1);
4328 /* Check for a scaled indexed address. */
4329 if (mips_lwxs_address_p (addr
)
4330 || mips_lx_address_p (addr
, mode
))
4332 *total
= COSTS_N_INSNS (2);
4335 /* Otherwise use the default handling. */
4339 *total
= COSTS_N_INSNS (6);
4343 *total
= COSTS_N_INSNS (GET_MODE_SIZE (mode
) > UNITS_PER_WORD
? 2 : 1);
4347 /* Check for a *clear_upper32 pattern and treat it like a zero
4348 extension. See the pattern's comment for details. */
4351 && CONST_INT_P (XEXP (x
, 1))
4352 && UINTVAL (XEXP (x
, 1)) == 0xffffffff)
4354 *total
= (mips_zero_extend_cost (mode
, XEXP (x
, 0))
4355 + set_src_cost (XEXP (x
, 0), mode
, speed
));
4358 if (ISA_HAS_CINS
&& CONST_INT_P (XEXP (x
, 1)))
4360 rtx op
= XEXP (x
, 0);
4361 if (GET_CODE (op
) == ASHIFT
4362 && CONST_INT_P (XEXP (op
, 1))
4363 && mask_low_and_shift_p (mode
, XEXP (x
, 1), XEXP (op
, 1), 32))
4365 *total
= COSTS_N_INSNS (1);
4366 *total
+= set_src_cost (XEXP (op
, 0), mode
, speed
);
4370 /* (AND (NOT op0) (NOT op1) is a nor operation that can be done in
4371 a single instruction. */
4373 && GET_CODE (XEXP (x
, 0)) == NOT
4374 && GET_CODE (XEXP (x
, 1)) == NOT
)
4376 cost
= GET_MODE_SIZE (mode
) > UNITS_PER_WORD
? 2 : 1;
4377 *total
= (COSTS_N_INSNS (cost
)
4378 + set_src_cost (XEXP (XEXP (x
, 0), 0), mode
, speed
)
4379 + set_src_cost (XEXP (XEXP (x
, 1), 0), mode
, speed
));
4387 /* Double-word operations use two single-word operations. */
4388 *total
= mips_binary_cost (x
, COSTS_N_INSNS (1), COSTS_N_INSNS (2),
4397 if (CONSTANT_P (XEXP (x
, 1)))
4398 *total
= mips_binary_cost (x
, COSTS_N_INSNS (1), COSTS_N_INSNS (4),
4401 *total
= mips_binary_cost (x
, COSTS_N_INSNS (1), COSTS_N_INSNS (12),
4407 *total
= mips_cost
->fp_add
;
4409 *total
= COSTS_N_INSNS (4);
4413 /* Low-part immediates need an extended MIPS16 instruction. */
4414 *total
= (COSTS_N_INSNS (TARGET_MIPS16
? 2 : 1)
4415 + set_src_cost (XEXP (x
, 0), mode
, speed
));
4434 /* Branch comparisons have VOIDmode, so use the first operand's
4436 mode
= GET_MODE (XEXP (x
, 0));
4437 if (FLOAT_MODE_P (mode
))
4439 *total
= mips_cost
->fp_add
;
4442 *total
= mips_binary_cost (x
, COSTS_N_INSNS (1), COSTS_N_INSNS (4),
4447 if (float_mode_p
&& ISA_HAS_UNFUSED_MADD4
&& !HONOR_SIGNED_ZEROS (mode
))
4449 /* See if we can use NMADD or NMSUB via the *nmadd4<mode>_fastmath
4450 or *nmsub4<mode>_fastmath patterns. These patterns check for
4451 HONOR_SIGNED_ZEROS so we check here too. */
4452 rtx op0
= XEXP (x
, 0);
4453 rtx op1
= XEXP (x
, 1);
4454 if (GET_CODE (op0
) == MULT
&& GET_CODE (XEXP (op0
, 0)) == NEG
)
4456 *total
= (mips_fp_mult_cost (mode
)
4457 + set_src_cost (XEXP (XEXP (op0
, 0), 0), mode
, speed
)
4458 + set_src_cost (XEXP (op0
, 1), mode
, speed
)
4459 + set_src_cost (op1
, mode
, speed
));
4462 if (GET_CODE (op1
) == MULT
)
4464 *total
= (mips_fp_mult_cost (mode
)
4465 + set_src_cost (op0
, mode
, speed
)
4466 + set_src_cost (XEXP (op1
, 0), mode
, speed
)
4467 + set_src_cost (XEXP (op1
, 1), mode
, speed
));
4476 /* If this is part of a MADD or MSUB, treat the PLUS as
4478 if (ISA_HAS_UNFUSED_MADD4
&& GET_CODE (XEXP (x
, 0)) == MULT
)
4481 *total
= mips_cost
->fp_add
;
4485 /* If it's an add + mult (which is equivalent to shift left) and
4486 it's immediate operand satisfies const_immlsa_operand predicate. */
4487 if (((ISA_HAS_LSA
&& mode
== SImode
)
4488 || (ISA_HAS_DLSA
&& mode
== DImode
))
4489 && GET_CODE (XEXP (x
, 0)) == MULT
)
4491 rtx op2
= XEXP (XEXP (x
, 0), 1);
4492 if (const_immlsa_operand (op2
, mode
))
4494 *total
= (COSTS_N_INSNS (1)
4495 + set_src_cost (XEXP (XEXP (x
, 0), 0), mode
, speed
)
4496 + set_src_cost (XEXP (x
, 1), mode
, speed
));
4501 /* Double-word operations require three single-word operations and
4502 an SLTU. The MIPS16 version then needs to move the result of
4503 the SLTU from $24 to a MIPS16 register. */
4504 *total
= mips_binary_cost (x
, COSTS_N_INSNS (1),
4505 COSTS_N_INSNS (TARGET_MIPS16
? 5 : 4),
4510 if (float_mode_p
&& ISA_HAS_UNFUSED_MADD4
)
4512 /* See if we can use NMADD or NMSUB via the *nmadd4<mode> or
4513 *nmsub4<mode> patterns. */
4514 rtx op
= XEXP (x
, 0);
4515 if ((GET_CODE (op
) == PLUS
|| GET_CODE (op
) == MINUS
)
4516 && GET_CODE (XEXP (op
, 0)) == MULT
)
4518 *total
= (mips_fp_mult_cost (mode
)
4519 + set_src_cost (XEXP (XEXP (op
, 0), 0), mode
, speed
)
4520 + set_src_cost (XEXP (XEXP (op
, 0), 1), mode
, speed
)
4521 + set_src_cost (XEXP (op
, 1), mode
, speed
));
4527 *total
= mips_cost
->fp_add
;
4529 *total
= COSTS_N_INSNS (GET_MODE_SIZE (mode
) > UNITS_PER_WORD
? 4 : 1);
4533 *total
= mips_fp_mult_cost (mode
);
4538 *total
= mips_fp_mult_cost (mode
);
4539 else if (mode
== DImode
&& !TARGET_64BIT
)
4540 /* Synthesized from 2 mulsi3s, 1 mulsidi3 and two additions,
4541 where the mulsidi3 always includes an MFHI and an MFLO. */
4543 ? mips_cost
->int_mult_si
* 3 + 6
4544 : COSTS_N_INSNS (ISA_HAS_MUL3
? 7 : 9));
4546 *total
= COSTS_N_INSNS ((ISA_HAS_MUL3
|| ISA_HAS_R6MUL
) ? 1 : 2) + 1;
4547 else if (mode
== DImode
)
4548 *total
= mips_cost
->int_mult_di
;
4550 *total
= mips_cost
->int_mult_si
;
4554 /* Check for a reciprocal. */
4556 && ISA_HAS_FP_RECIP_RSQRT (mode
)
4557 && flag_unsafe_math_optimizations
4558 && XEXP (x
, 0) == CONST1_RTX (mode
))
4560 if (outer_code
== SQRT
|| GET_CODE (XEXP (x
, 1)) == SQRT
)
4561 /* An rsqrt<mode>a or rsqrt<mode>b pattern. Count the
4562 division as being free. */
4563 *total
= set_src_cost (XEXP (x
, 1), mode
, speed
);
4565 *total
= (mips_fp_div_cost (mode
)
4566 + set_src_cost (XEXP (x
, 1), mode
, speed
));
4575 *total
= mips_fp_div_cost (mode
);
4584 /* It is our responsibility to make division by a power of 2
4585 as cheap as 2 register additions if we want the division
4586 expanders to be used for such operations; see the setting
4587 of sdiv_pow2_cheap in optabs.cc. Using (D)DIV for MIPS16
4588 should always produce shorter code than using
4589 expand_sdiv2_pow2. */
4591 && CONST_INT_P (XEXP (x
, 1))
4592 && exact_log2 (INTVAL (XEXP (x
, 1))) >= 0)
4594 *total
= COSTS_N_INSNS (2);
4595 *total
+= set_src_cost (XEXP (x
, 0), mode
, speed
);
4598 *total
= COSTS_N_INSNS (mips_idiv_insns (mode
));
4600 else if (mode
== DImode
)
4601 *total
= mips_cost
->int_div_di
;
4603 *total
= mips_cost
->int_div_si
;
4607 *total
= mips_sign_extend_cost (mode
, XEXP (x
, 0));
4611 if (outer_code
== SET
4613 && (GET_CODE (XEXP (x
, 0)) == TRUNCATE
4614 || GET_CODE (XEXP (x
, 0)) == SUBREG
)
4615 && GET_MODE (XEXP (x
, 0)) == QImode
4616 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == PLUS
)
4618 *total
= set_src_cost (XEXP (XEXP (x
, 0), 0), VOIDmode
, speed
);
4621 *total
= mips_zero_extend_cost (mode
, XEXP (x
, 0));
4624 /* Costings for highpart multiplies. Matching patterns of the form:
4626 (lshiftrt:DI (mult:DI (sign_extend:DI (...)
4627 (sign_extend:DI (...))
4631 && (GET_CODE (XEXP (x
, 0)) == ASHIFTRT
4632 || GET_CODE (XEXP (x
, 0)) == LSHIFTRT
)
4633 && CONST_INT_P (XEXP (XEXP (x
, 0), 1))
4634 && ((INTVAL (XEXP (XEXP (x
, 0), 1)) == 32
4635 && GET_MODE (XEXP (x
, 0)) == DImode
)
4637 && INTVAL (XEXP (XEXP (x
, 0), 1)) == 64
4638 && GET_MODE (XEXP (x
, 0)) == TImode
))
4639 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == MULT
4640 && ((GET_CODE (XEXP (XEXP (XEXP (x
, 0), 0), 0)) == SIGN_EXTEND
4641 && GET_CODE (XEXP (XEXP (XEXP (x
, 0), 0), 1)) == SIGN_EXTEND
)
4642 || (GET_CODE (XEXP (XEXP (XEXP (x
, 0), 0), 0)) == ZERO_EXTEND
4643 && (GET_CODE (XEXP (XEXP (XEXP (x
, 0), 0), 1))
4647 *total
= COSTS_N_INSNS (1) + 1;
4648 else if (mode
== DImode
)
4649 *total
= mips_cost
->int_mult_di
;
4651 *total
= mips_cost
->int_mult_si
;
4653 /* Sign extension is free, zero extension costs for DImode when
4654 on a 64bit core / when DMUL is present. */
4655 for (int i
= 0; i
< 2; ++i
)
4657 rtx op
= XEXP (XEXP (XEXP (x
, 0), 0), i
);
4659 && GET_CODE (op
) == ZERO_EXTEND
4660 && GET_MODE (op
) == DImode
)
4661 *total
+= rtx_cost (op
, DImode
, MULT
, i
, speed
);
4663 *total
+= rtx_cost (XEXP (op
, 0), VOIDmode
, GET_CODE (op
),
4672 case UNSIGNED_FLOAT
:
4675 case FLOAT_TRUNCATE
:
4676 *total
= mips_cost
->fp_add
;
4680 if (register_operand (SET_DEST (x
), VOIDmode
)
4681 && reg_or_0_operand (SET_SRC (x
), VOIDmode
))
4683 *total
= mips_set_reg_reg_cost (GET_MODE (SET_DEST (x
)));
4693 /* Implement TARGET_ADDRESS_COST. */
4696 mips_address_cost (rtx addr
, machine_mode mode
,
4697 addr_space_t as ATTRIBUTE_UNUSED
,
4698 bool speed ATTRIBUTE_UNUSED
)
4700 return mips_address_insns (addr
, mode
, false);
4703 /* Implement TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P. */
4706 mips_no_speculation_in_delay_slots_p ()
4708 return TARGET_CB_MAYBE
;
4711 /* Information about a single instruction in a multi-instruction
4713 struct mips_multi_member
{
4714 /* True if this is a label, false if it is code. */
4717 /* The output_asm_insn format of the instruction. */
4720 /* The operands to the instruction. */
4721 rtx operands
[MAX_RECOG_OPERANDS
];
4723 typedef struct mips_multi_member mips_multi_member
;
4725 /* The instructions that make up the current multi-insn sequence. */
4726 static vec
<mips_multi_member
> mips_multi_members
;
4728 /* How many instructions (as opposed to labels) are in the current
4729 multi-insn sequence. */
4730 static unsigned int mips_multi_num_insns
;
4732 /* Start a new multi-insn sequence. */
4735 mips_multi_start (void)
4737 mips_multi_members
.truncate (0);
4738 mips_multi_num_insns
= 0;
4741 /* Add a new, zero initialized member to the current multi-insn sequence. */
4743 static struct mips_multi_member
*
4744 mips_multi_add (void)
4746 mips_multi_member empty
;
4747 memset (&empty
, 0, sizeof (empty
));
4748 return mips_multi_members
.safe_push (empty
);
4751 /* Add a normal insn with the given asm format to the current multi-insn
4752 sequence. The other arguments are a null-terminated list of operands. */
4755 mips_multi_add_insn (const char *format
, ...)
4757 struct mips_multi_member
*member
;
4762 member
= mips_multi_add ();
4763 member
->is_label_p
= false;
4764 member
->format
= format
;
4765 va_start (ap
, format
);
4767 while ((op
= va_arg (ap
, rtx
)))
4768 member
->operands
[i
++] = op
;
4770 mips_multi_num_insns
++;
4773 /* Add the given label definition to the current multi-insn sequence.
4774 The definition should include the colon. */
4777 mips_multi_add_label (const char *label
)
4779 struct mips_multi_member
*member
;
4781 member
= mips_multi_add ();
4782 member
->is_label_p
= true;
4783 member
->format
= label
;
4786 /* Return the index of the last member of the current multi-insn sequence. */
4789 mips_multi_last_index (void)
4791 return mips_multi_members
.length () - 1;
4794 /* Add a copy of an existing instruction to the current multi-insn
4795 sequence. I is the index of the instruction that should be copied. */
4798 mips_multi_copy_insn (unsigned int i
)
4800 struct mips_multi_member
*member
;
4802 member
= mips_multi_add ();
4803 memcpy (member
, &mips_multi_members
[i
], sizeof (*member
));
4804 gcc_assert (!member
->is_label_p
);
4807 /* Change the operand of an existing instruction in the current
4808 multi-insn sequence. I is the index of the instruction,
4809 OP is the index of the operand, and X is the new value. */
4812 mips_multi_set_operand (unsigned int i
, unsigned int op
, rtx x
)
4814 mips_multi_members
[i
].operands
[op
] = x
;
4817 /* Write out the asm code for the current multi-insn sequence. */
4820 mips_multi_write (void)
4822 struct mips_multi_member
*member
;
4825 FOR_EACH_VEC_ELT (mips_multi_members
, i
, member
)
4826 if (member
->is_label_p
)
4827 fprintf (asm_out_file
, "%s\n", member
->format
);
4829 output_asm_insn (member
->format
, member
->operands
);
4832 /* Return one word of double-word value OP, taking into account the fixed
4833 endianness of certain registers. HIGH_P is true to select the high part,
4834 false to select the low part. */
4837 mips_subword (rtx op
, bool high_p
)
4839 unsigned int byte
, offset
;
4842 mode
= GET_MODE (op
);
4843 if (mode
== VOIDmode
)
4844 mode
= TARGET_64BIT
? TImode
: DImode
;
4846 if (TARGET_BIG_ENDIAN
? !high_p
: high_p
)
4847 byte
= UNITS_PER_WORD
;
4851 if (FP_REG_RTX_P (op
))
4853 /* Paired FPRs are always ordered little-endian. */
4854 offset
= (UNITS_PER_WORD
< UNITS_PER_HWFPVALUE
? high_p
: byte
!= 0);
4855 return gen_rtx_REG (word_mode
, REGNO (op
) + offset
);
4859 return mips_rewrite_small_data (adjust_address (op
, word_mode
, byte
));
4861 return simplify_gen_subreg (word_mode
, op
, mode
, byte
);
4864 /* Return true if SRC should be moved into DEST using "MULT $0, $0".
4865 SPLIT_TYPE is the condition under which moves should be split. */
4868 mips_mult_move_p (rtx dest
, rtx src
, enum mips_split_type split_type
)
4870 return ((split_type
!= SPLIT_FOR_SPEED
4871 || mips_tuning_info
.fast_mult_zero_zero_p
)
4872 && src
== const0_rtx
4874 && GET_MODE_SIZE (GET_MODE (dest
)) == 2 * UNITS_PER_WORD
4875 && (ISA_HAS_DSP_MULT
4876 ? ACC_REG_P (REGNO (dest
))
4877 : MD_REG_P (REGNO (dest
))));
4880 /* Return true if a move from SRC to DEST should be split into two.
4881 SPLIT_TYPE describes the split condition. */
4884 mips_split_move_p (rtx dest
, rtx src
, enum mips_split_type split_type
)
4886 /* Check whether the move can be done using some variant of MULT $0,$0. */
4887 if (mips_mult_move_p (dest
, src
, split_type
))
4890 /* FPR-to-FPR moves can be done in a single instruction, if they're
4892 unsigned int size
= GET_MODE_SIZE (GET_MODE (dest
));
4893 if (size
== 8 && FP_REG_RTX_P (src
) && FP_REG_RTX_P (dest
))
4896 /* Check for floating-point loads and stores. */
4897 if (size
== 8 && ISA_HAS_LDC1_SDC1
)
4899 if (FP_REG_RTX_P (dest
) && MEM_P (src
))
4901 if (FP_REG_RTX_P (src
) && MEM_P (dest
))
4905 /* Check if MSA moves need splitting. */
4906 if (MSA_SUPPORTED_MODE_P (GET_MODE (dest
)))
4907 return mips_split_128bit_move_p (dest
, src
);
4909 /* Otherwise split all multiword moves. */
4910 return size
> UNITS_PER_WORD
;
4913 /* Split a move from SRC to DEST, given that mips_split_move_p holds.
4914 SPLIT_TYPE describes the split condition. INSN is the insn being
4915 split, if we know it, NULL otherwise. */
4918 mips_split_move (rtx dest
, rtx src
, enum mips_split_type split_type
, rtx insn_
)
4922 gcc_checking_assert (mips_split_move_p (dest
, src
, split_type
));
4923 if (MSA_SUPPORTED_MODE_P (GET_MODE (dest
)))
4924 mips_split_128bit_move (dest
, src
);
4925 else if (FP_REG_RTX_P (dest
) || FP_REG_RTX_P (src
))
4927 if (!TARGET_64BIT
&& GET_MODE (dest
) == DImode
)
4928 emit_insn (gen_move_doubleword_fprdi (dest
, src
));
4929 else if (!TARGET_64BIT
&& GET_MODE (dest
) == DFmode
)
4930 emit_insn (gen_move_doubleword_fprdf (dest
, src
));
4931 else if (!TARGET_64BIT
&& GET_MODE (dest
) == V2SFmode
)
4932 emit_insn (gen_move_doubleword_fprv2sf (dest
, src
));
4933 else if (!TARGET_64BIT
&& GET_MODE (dest
) == V2SImode
)
4934 emit_insn (gen_move_doubleword_fprv2si (dest
, src
));
4935 else if (!TARGET_64BIT
&& GET_MODE (dest
) == V4HImode
)
4936 emit_insn (gen_move_doubleword_fprv4hi (dest
, src
));
4937 else if (!TARGET_64BIT
&& GET_MODE (dest
) == V8QImode
)
4938 emit_insn (gen_move_doubleword_fprv8qi (dest
, src
));
4939 else if (TARGET_64BIT
&& GET_MODE (dest
) == TFmode
)
4940 emit_insn (gen_move_doubleword_fprtf (dest
, src
));
4944 else if (REG_P (dest
) && REGNO (dest
) == MD_REG_FIRST
)
4946 low_dest
= mips_subword (dest
, false);
4947 mips_emit_move (low_dest
, mips_subword (src
, false));
4949 emit_insn (gen_mthidi_ti (dest
, mips_subword (src
, true), low_dest
));
4951 emit_insn (gen_mthisi_di (dest
, mips_subword (src
, true), low_dest
));
4953 else if (REG_P (src
) && REGNO (src
) == MD_REG_FIRST
)
4955 mips_emit_move (mips_subword (dest
, false), mips_subword (src
, false));
4957 emit_insn (gen_mfhidi_ti (mips_subword (dest
, true), src
));
4959 emit_insn (gen_mfhisi_di (mips_subword (dest
, true), src
));
4963 /* The operation can be split into two normal moves. Decide in
4964 which order to do them. */
4965 low_dest
= mips_subword (dest
, false);
4966 if (REG_P (low_dest
)
4967 && reg_overlap_mentioned_p (low_dest
, src
))
4969 mips_emit_move (mips_subword (dest
, true), mips_subword (src
, true));
4970 mips_emit_move (low_dest
, mips_subword (src
, false));
4974 mips_emit_move (low_dest
, mips_subword (src
, false));
4975 mips_emit_move (mips_subword (dest
, true), mips_subword (src
, true));
4979 /* This is a hack. See if the next insn uses DEST and if so, see if we
4980 can forward SRC for DEST. This is most useful if the next insn is a
4982 rtx_insn
*insn
= (rtx_insn
*)insn_
;
4983 struct mips_address_info addr
= {};
4986 rtx_insn
*next
= next_nonnote_nondebug_insn_bb (insn
);
4989 rtx set
= single_set (next
);
4990 if (set
&& SET_SRC (set
) == dest
)
4994 rtx tmp
= XEXP (src
, 0);
4995 mips_classify_address (&addr
, tmp
, GET_MODE (tmp
), true);
4996 if (addr
.reg
&& !reg_overlap_mentioned_p (dest
, addr
.reg
))
4997 validate_change (next
, &SET_SRC (set
), src
, false);
5000 validate_change (next
, &SET_SRC (set
), src
, false);
5006 /* Return the split type for instruction INSN. */
5008 static enum mips_split_type
5009 mips_insn_split_type (rtx insn
)
5011 basic_block bb
= BLOCK_FOR_INSN (insn
);
5014 if (optimize_bb_for_speed_p (bb
))
5015 return SPLIT_FOR_SPEED
;
5017 return SPLIT_FOR_SIZE
;
5019 /* Once CFG information has been removed, we should trust the optimization
5020 decisions made by previous passes and only split where necessary. */
5021 return SPLIT_IF_NECESSARY
;
5024 /* Return true if a 128-bit move from SRC to DEST should be split. */
5027 mips_split_128bit_move_p (rtx dest
, rtx src
)
5029 /* MSA-to-MSA moves can be done in a single instruction. */
5030 if (FP_REG_RTX_P (src
) && FP_REG_RTX_P (dest
))
5033 /* Check for MSA loads and stores. */
5034 if (FP_REG_RTX_P (dest
) && MEM_P (src
))
5036 if (FP_REG_RTX_P (src
) && MEM_P (dest
))
5039 /* Check for MSA set to an immediate const vector with valid replicated
5041 if (FP_REG_RTX_P (dest
)
5042 && mips_const_vector_same_int_p (src
, GET_MODE (src
), -512, 511))
5045 /* Check for MSA load zero immediate. */
5046 if (FP_REG_RTX_P (dest
) && src
== CONST0_RTX (GET_MODE (src
)))
5052 /* Split a 128-bit move from SRC to DEST. */
5055 mips_split_128bit_move (rtx dest
, rtx src
)
5058 rtx low_dest
, low_src
, d
, s
;
5060 if (FP_REG_RTX_P (dest
))
5062 gcc_assert (!MEM_P (src
));
5064 rtx new_dest
= dest
;
5067 if (GET_MODE (dest
) != V4SImode
)
5068 new_dest
= simplify_gen_subreg (V4SImode
, dest
, GET_MODE (dest
), 0);
5072 if (GET_MODE (dest
) != V2DImode
)
5073 new_dest
= simplify_gen_subreg (V2DImode
, dest
, GET_MODE (dest
), 0);
5076 for (byte
= 0, index
= 0; byte
< GET_MODE_SIZE (TImode
);
5077 byte
+= UNITS_PER_WORD
, index
++)
5079 s
= mips_subword_at_byte (src
, byte
);
5081 emit_insn (gen_msa_insert_w (new_dest
, s
, new_dest
,
5082 GEN_INT (1 << index
)));
5084 emit_insn (gen_msa_insert_d (new_dest
, s
, new_dest
,
5085 GEN_INT (1 << index
)));
5088 else if (FP_REG_RTX_P (src
))
5090 gcc_assert (!MEM_P (dest
));
5095 if (GET_MODE (src
) != V4SImode
)
5096 new_src
= simplify_gen_subreg (V4SImode
, src
, GET_MODE (src
), 0);
5100 if (GET_MODE (src
) != V2DImode
)
5101 new_src
= simplify_gen_subreg (V2DImode
, src
, GET_MODE (src
), 0);
5104 for (byte
= 0, index
= 0; byte
< GET_MODE_SIZE (TImode
);
5105 byte
+= UNITS_PER_WORD
, index
++)
5107 d
= mips_subword_at_byte (dest
, byte
);
5109 emit_insn (gen_msa_copy_s_w (d
, new_src
, GEN_INT (index
)));
5111 emit_insn (gen_msa_copy_s_d (d
, new_src
, GEN_INT (index
)));
5116 low_dest
= mips_subword_at_byte (dest
, 0);
5117 low_src
= mips_subword_at_byte (src
, 0);
5118 gcc_assert (REG_P (low_dest
) && REG_P (low_src
));
5119 /* Make sure the source register is not written before reading. */
5120 if (REGNO (low_dest
) <= REGNO (low_src
))
5122 for (byte
= 0; byte
< GET_MODE_SIZE (TImode
);
5123 byte
+= UNITS_PER_WORD
)
5125 d
= mips_subword_at_byte (dest
, byte
);
5126 s
= mips_subword_at_byte (src
, byte
);
5127 mips_emit_move (d
, s
);
5132 for (byte
= GET_MODE_SIZE (TImode
) - UNITS_PER_WORD
; byte
>= 0;
5133 byte
-= UNITS_PER_WORD
)
5135 d
= mips_subword_at_byte (dest
, byte
);
5136 s
= mips_subword_at_byte (src
, byte
);
5137 mips_emit_move (d
, s
);
5143 /* Split a COPY_S.D with operands DEST, SRC and INDEX. GEN is a function
5144 used to generate subregs. */
5147 mips_split_msa_copy_d (rtx dest
, rtx src
, rtx index
,
5148 rtx (*gen_fn
)(rtx
, rtx
, rtx
))
5150 gcc_assert ((GET_MODE (src
) == V2DImode
&& GET_MODE (dest
) == DImode
)
5151 || (GET_MODE (src
) == V2DFmode
&& GET_MODE (dest
) == DFmode
));
5153 /* Note that low is always from the lower index, and high is always
5154 from the higher index. */
5155 rtx low
= mips_subword (dest
, false);
5156 rtx high
= mips_subword (dest
, true);
5157 rtx new_src
= simplify_gen_subreg (V4SImode
, src
, GET_MODE (src
), 0);
5159 emit_insn (gen_fn (low
, new_src
, GEN_INT (INTVAL (index
) * 2)));
5160 emit_insn (gen_fn (high
, new_src
, GEN_INT (INTVAL (index
) * 2 + 1)));
5163 /* Split a INSERT.D with operand DEST, SRC1.INDEX and SRC2. */
5166 mips_split_msa_insert_d (rtx dest
, rtx src1
, rtx index
, rtx src2
)
5169 gcc_assert (GET_MODE (dest
) == GET_MODE (src1
));
5170 gcc_assert ((GET_MODE (dest
) == V2DImode
5171 && (GET_MODE (src2
) == DImode
|| src2
== const0_rtx
))
5172 || (GET_MODE (dest
) == V2DFmode
&& GET_MODE (src2
) == DFmode
));
5174 /* Note that low is always from the lower index, and high is always
5175 from the higher index. */
5176 rtx low
= mips_subword (src2
, false);
5177 rtx high
= mips_subword (src2
, true);
5178 rtx new_dest
= simplify_gen_subreg (V4SImode
, dest
, GET_MODE (dest
), 0);
5179 rtx new_src1
= simplify_gen_subreg (V4SImode
, src1
, GET_MODE (src1
), 0);
5180 i
= exact_log2 (INTVAL (index
));
5181 gcc_assert (i
!= -1);
5183 emit_insn (gen_msa_insert_w (new_dest
, low
, new_src1
,
5184 GEN_INT (1 << (i
* 2))));
5185 emit_insn (gen_msa_insert_w (new_dest
, high
, new_dest
,
5186 GEN_INT (1 << (i
* 2 + 1))));
5192 mips_split_msa_fill_d (rtx dest
, rtx src
)
5194 gcc_assert ((GET_MODE (dest
) == V2DImode
5195 && (GET_MODE (src
) == DImode
|| src
== const0_rtx
))
5196 || (GET_MODE (dest
) == V2DFmode
&& GET_MODE (src
) == DFmode
));
5198 /* Note that low is always from the lower index, and high is always
5199 from the higher index. */
5201 if (src
== const0_rtx
)
5208 low
= mips_subword (src
, false);
5209 high
= mips_subword (src
, true);
5211 rtx new_dest
= simplify_gen_subreg (V4SImode
, dest
, GET_MODE (dest
), 0);
5212 emit_insn (gen_msa_fill_w (new_dest
, low
));
5213 emit_insn (gen_msa_insert_w (new_dest
, high
, new_dest
, GEN_INT (1 << 1)));
5214 emit_insn (gen_msa_insert_w (new_dest
, high
, new_dest
, GEN_INT (1 << 3)));
5217 /* Return true if a move from SRC to DEST in INSN should be split. */
5220 mips_split_move_insn_p (rtx dest
, rtx src
, rtx insn
)
5222 return mips_split_move_p (dest
, src
, mips_insn_split_type (insn
));
5225 /* Split a move from SRC to DEST in INSN, given that mips_split_move_insn_p
5229 mips_split_move_insn (rtx dest
, rtx src
, rtx insn
)
5231 mips_split_move (dest
, src
, mips_insn_split_type (insn
), insn
);
5234 /* Return the appropriate instructions to move SRC into DEST. Assume
5235 that SRC is operand 1 and DEST is operand 0. */
5238 mips_output_move (rtx dest
, rtx src
)
5240 enum rtx_code dest_code
= GET_CODE (dest
);
5241 enum rtx_code src_code
= GET_CODE (src
);
5242 machine_mode mode
= GET_MODE (dest
);
5243 bool dbl_p
= (GET_MODE_SIZE (mode
) == 8);
5244 bool msa_p
= MSA_SUPPORTED_MODE_P (mode
);
5245 enum mips_symbol_type symbol_type
;
5247 if (mips_split_move_p (dest
, src
, SPLIT_IF_NECESSARY
))
5251 && dest_code
== REG
&& FP_REG_P (REGNO (dest
))
5252 && src_code
== CONST_VECTOR
5253 && CONST_INT_P (CONST_VECTOR_ELT (src
, 0)))
5255 gcc_assert (mips_const_vector_same_int_p (src
, mode
, -512, 511));
5256 return "ldi.%v0\t%w0,%E1";
5259 if ((src_code
== REG
&& GP_REG_P (REGNO (src
)))
5260 || (!TARGET_MIPS16
&& src
== CONST0_RTX (mode
)))
5262 if (dest_code
== REG
)
5264 if (GP_REG_P (REGNO (dest
)))
5265 return "move\t%0,%z1";
5267 if (mips_mult_move_p (dest
, src
, SPLIT_IF_NECESSARY
))
5269 if (ISA_HAS_DSP_MULT
)
5270 return "mult\t%q0,%.,%.";
5272 return "mult\t%.,%.";
5275 /* Moves to HI are handled by special .md insns. */
5276 if (REGNO (dest
) == LO_REGNUM
)
5279 if (DSP_ACC_REG_P (REGNO (dest
)))
5281 static char retval
[] = "mt__\t%z1,%q0";
5283 retval
[2] = reg_names
[REGNO (dest
)][4];
5284 retval
[3] = reg_names
[REGNO (dest
)][5];
5288 if (FP_REG_P (REGNO (dest
)))
5292 gcc_assert (src
== CONST0_RTX (GET_MODE (src
)));
5293 return "ldi.%v0\t%w0,0";
5296 return dbl_p
? "dmtc1\t%z1,%0" : "mtc1\t%z1,%0";
5299 if (ALL_COP_REG_P (REGNO (dest
)))
5301 static char retval
[] = "dmtc_\t%z1,%0";
5303 retval
[4] = COPNUM_AS_CHAR_FROM_REGNUM (REGNO (dest
));
5304 return dbl_p
? retval
: retval
+ 1;
5307 if (dest_code
== MEM
)
5308 switch (GET_MODE_SIZE (mode
))
5310 case 1: return "sb\t%z1,%0";
5311 case 2: return "sh\t%z1,%0";
5312 case 4: return "sw\t%z1,%0";
5313 case 8: return "sd\t%z1,%0";
5314 default: gcc_unreachable ();
5317 if (dest_code
== REG
&& GP_REG_P (REGNO (dest
)))
5319 if (src_code
== REG
)
5321 /* Moves from HI are handled by special .md insns. */
5322 if (REGNO (src
) == LO_REGNUM
)
5324 /* When generating VR4120 or VR4130 code, we use MACC and
5325 DMACC instead of MFLO. This avoids both the normal
5326 MIPS III HI/LO hazards and the errata related to
5329 return dbl_p
? "dmacc\t%0,%.,%." : "macc\t%0,%.,%.";
5333 if (DSP_ACC_REG_P (REGNO (src
)))
5335 static char retval
[] = "mf__\t%0,%q1";
5337 retval
[2] = reg_names
[REGNO (src
)][4];
5338 retval
[3] = reg_names
[REGNO (src
)][5];
5342 if (FP_REG_P (REGNO (src
)))
5344 gcc_assert (!msa_p
);
5345 return dbl_p
? "dmfc1\t%0,%1" : "mfc1\t%0,%1";
5348 if (ALL_COP_REG_P (REGNO (src
)))
5350 static char retval
[] = "dmfc_\t%0,%1";
5352 retval
[4] = COPNUM_AS_CHAR_FROM_REGNUM (REGNO (src
));
5353 return dbl_p
? retval
: retval
+ 1;
5357 if (src_code
== MEM
)
5358 switch (GET_MODE_SIZE (mode
))
5360 case 1: return "lbu\t%0,%1";
5361 case 2: return "lhu\t%0,%1";
5362 case 4: return "lw\t%0,%1";
5363 case 8: return "ld\t%0,%1";
5364 default: gcc_unreachable ();
5367 if (src_code
== CONST_INT
)
5369 /* Don't use the X format for the operand itself, because that
5370 will give out-of-range numbers for 64-bit hosts and 32-bit
5373 return "li\t%0,%1\t\t\t# %X1";
5375 if (ISA_HAS_MIPS16E2
5377 && !SMALL_OPERAND_UNSIGNED (INTVAL (src
)))
5378 return "lui\t%0,%%hi(%1)\t\t\t# %X1";
5380 if (SMALL_OPERAND_UNSIGNED (INTVAL (src
)))
5383 if (SMALL_OPERAND_UNSIGNED (-INTVAL (src
)))
5387 if (src_code
== HIGH
)
5388 return (TARGET_MIPS16
&& !ISA_HAS_MIPS16E2
) ? "#" : "lui\t%0,%h1";
5390 if (CONST_GP_P (src
))
5391 return "move\t%0,%1";
5393 if (mips_symbolic_constant_p (src
, SYMBOL_CONTEXT_LEA
, &symbol_type
)
5394 && mips_lo_relocs
[symbol_type
] != 0)
5396 /* A signed 16-bit constant formed by applying a relocation
5397 operator to a symbolic address. */
5398 gcc_assert (!mips_split_p
[symbol_type
]);
5399 return "li\t%0,%R1";
5402 if (symbolic_operand (src
, VOIDmode
))
5404 gcc_assert (TARGET_MIPS16
5405 ? TARGET_MIPS16_TEXT_LOADS
5406 : !TARGET_EXPLICIT_RELOCS
);
5407 return dbl_p
? "dla\t%0,%1" : "la\t%0,%1";
5410 if (src_code
== REG
&& FP_REG_P (REGNO (src
)))
5412 if (dest_code
== REG
&& FP_REG_P (REGNO (dest
)))
5414 if (GET_MODE (dest
) == V2SFmode
)
5415 return "mov.ps\t%0,%1";
5417 return "move.v\t%w0,%w1";
5419 return dbl_p
? "mov.d\t%0,%1" : "mov.s\t%0,%1";
5422 if (dest_code
== MEM
)
5425 return "st.%v1\t%w1,%0";
5427 return dbl_p
? "sdc1\t%1,%0" : "swc1\t%1,%0";
5430 if (dest_code
== REG
&& FP_REG_P (REGNO (dest
)))
5432 if (src_code
== MEM
)
5435 return "ld.%v0\t%w0,%1";
5437 return dbl_p
? "ldc1\t%0,%1" : "lwc1\t%0,%1";
5440 if (dest_code
== REG
&& ALL_COP_REG_P (REGNO (dest
)) && src_code
== MEM
)
5442 static char retval
[] = "l_c_\t%0,%1";
5444 retval
[1] = (dbl_p
? 'd' : 'w');
5445 retval
[3] = COPNUM_AS_CHAR_FROM_REGNUM (REGNO (dest
));
5448 if (dest_code
== MEM
&& src_code
== REG
&& ALL_COP_REG_P (REGNO (src
)))
5450 static char retval
[] = "s_c_\t%1,%0";
5452 retval
[1] = (dbl_p
? 'd' : 'w');
5453 retval
[3] = COPNUM_AS_CHAR_FROM_REGNUM (REGNO (src
));
5459 /* Return true if CMP1 is a suitable second operand for integer ordering
5460 test CODE. See also the *sCC patterns in mips.md. */
5463 mips_int_order_operand_ok_p (enum rtx_code code
, rtx cmp1
)
5469 return reg_or_0_operand (cmp1
, VOIDmode
);
5473 return !TARGET_MIPS16
&& cmp1
== const1_rtx
;
5477 return arith_operand (cmp1
, VOIDmode
);
5480 return sle_operand (cmp1
, VOIDmode
);
5483 return sleu_operand (cmp1
, VOIDmode
);
5490 /* Return true if *CMP1 (of mode MODE) is a valid second operand for
5491 integer ordering test *CODE, or if an equivalent combination can
5492 be formed by adjusting *CODE and *CMP1. When returning true, update
5493 *CODE and *CMP1 with the chosen code and operand, otherwise leave
5497 mips_canonicalize_int_order_test (enum rtx_code
*code
, rtx
*cmp1
,
5500 HOST_WIDE_INT plus_one
;
5502 if (mips_int_order_operand_ok_p (*code
, *cmp1
))
5505 if (CONST_INT_P (*cmp1
))
5509 plus_one
= trunc_int_for_mode (UINTVAL (*cmp1
) + 1, mode
);
5510 if (INTVAL (*cmp1
) < plus_one
)
5513 *cmp1
= force_reg (mode
, GEN_INT (plus_one
));
5519 plus_one
= trunc_int_for_mode (UINTVAL (*cmp1
) + 1, mode
);
5523 *cmp1
= force_reg (mode
, GEN_INT (plus_one
));
5534 /* Compare CMP0 and CMP1 using ordering test CODE and store the result
5535 in TARGET. CMP0 and TARGET are register_operands. If INVERT_PTR
5536 is nonnull, it's OK to set TARGET to the inverse of the result and
5537 flip *INVERT_PTR instead. */
5540 mips_emit_int_order_test (enum rtx_code code
, bool *invert_ptr
,
5541 rtx target
, rtx cmp0
, rtx cmp1
)
5545 /* First see if there is a MIPS instruction that can do this operation.
5546 If not, try doing the same for the inverse operation. If that also
5547 fails, force CMP1 into a register and try again. */
5548 mode
= GET_MODE (cmp0
);
5549 if (mips_canonicalize_int_order_test (&code
, &cmp1
, mode
))
5550 mips_emit_binary (code
, target
, cmp0
, cmp1
);
5553 enum rtx_code inv_code
= reverse_condition (code
);
5554 if (!mips_canonicalize_int_order_test (&inv_code
, &cmp1
, mode
))
5556 cmp1
= force_reg (mode
, cmp1
);
5557 mips_emit_int_order_test (code
, invert_ptr
, target
, cmp0
, cmp1
);
5559 else if (invert_ptr
== 0)
5563 inv_target
= mips_force_binary (GET_MODE (target
),
5564 inv_code
, cmp0
, cmp1
);
5565 mips_emit_binary (XOR
, target
, inv_target
, const1_rtx
);
5569 *invert_ptr
= !*invert_ptr
;
5570 mips_emit_binary (inv_code
, target
, cmp0
, cmp1
);
5575 /* Return a register that is zero iff CMP0 and CMP1 are equal.
5576 The register will have the same mode as CMP0. */
5579 mips_zero_if_equal (rtx cmp0
, rtx cmp1
)
5581 if (cmp1
== const0_rtx
)
5584 if (uns_arith_operand (cmp1
, VOIDmode
))
5585 return expand_binop (GET_MODE (cmp0
), xor_optab
,
5586 cmp0
, cmp1
, 0, 0, OPTAB_DIRECT
);
5588 return expand_binop (GET_MODE (cmp0
), sub_optab
,
5589 cmp0
, cmp1
, 0, 0, OPTAB_DIRECT
);
5592 /* Convert *CODE into a code that can be used in a floating-point
5593 scc instruction (C.cond.fmt). Return true if the values of
5594 the condition code registers will be inverted, with 0 indicating
5595 that the condition holds. */
5598 mips_reversed_fp_cond (enum rtx_code
*code
)
5605 *code
= reverse_condition_maybe_unordered (*code
);
5613 /* Allocate a floating-point condition-code register of mode MODE.
5615 These condition code registers are used for certain kinds
5616 of compound operation, such as compare and branches, vconds,
5617 and built-in functions. At expand time, their use is entirely
5618 controlled by MIPS-specific code and is entirely internal
5619 to these compound operations.
5621 We could (and did in the past) expose condition-code values
5622 as pseudo registers and leave the register allocator to pick
5623 appropriate registers. The problem is that it is not practically
5624 possible for the rtl optimizers to guarantee that no spills will
5625 be needed, even when AVOID_CCMODE_COPIES is defined. We would
5626 therefore need spill and reload sequences to handle the worst case.
5628 Although such sequences do exist, they are very expensive and are
5629 not something we'd want to use. This is especially true of CCV2 and
5630 CCV4, where all the shuffling would greatly outweigh whatever benefit
5631 the vectorization itself provides.
5633 The main benefit of having more than one condition-code register
5634 is to allow the pipelining of operations, especially those involving
5635 comparisons and conditional moves. We don't really expect the
5636 registers to be live for long periods, and certainly never want
5637 them to be live across calls.
5639 Also, there should be no penalty attached to using all the available
5640 registers. They are simply bits in the same underlying FPU control
5643 We therefore expose the hardware registers from the outset and use
5644 a simple round-robin allocation scheme. */
5647 mips_allocate_fcc (machine_mode mode
)
5649 unsigned int regno
, count
;
5651 gcc_assert (TARGET_HARD_FLOAT
&& ISA_HAS_8CC
);
5655 else if (mode
== CCV2mode
)
5657 else if (mode
== CCV4mode
)
5662 cfun
->machine
->next_fcc
+= -cfun
->machine
->next_fcc
& (count
- 1);
5663 if (cfun
->machine
->next_fcc
> ST_REG_LAST
- ST_REG_FIRST
)
5664 cfun
->machine
->next_fcc
= 0;
5665 regno
= ST_REG_FIRST
+ cfun
->machine
->next_fcc
;
5666 cfun
->machine
->next_fcc
+= count
;
5667 return gen_rtx_REG (mode
, regno
);
5670 /* Convert a comparison into something that can be used in a branch or
5671 conditional move. On entry, *OP0 and *OP1 are the values being
5672 compared and *CODE is the code used to compare them.
5674 Update *CODE, *OP0 and *OP1 so that they describe the final comparison.
5675 If NEED_EQ_NE_P, then only EQ or NE comparisons against zero are possible,
5676 otherwise any standard branch condition can be used. The standard branch
5679 - EQ or NE between two registers.
5680 - any comparison between a register and zero.
5681 - if compact branches are available then any condition is valid. */
5684 mips_emit_compare (enum rtx_code
*code
, rtx
*op0
, rtx
*op1
, bool need_eq_ne_p
)
5689 if (GET_MODE_CLASS (GET_MODE (*op0
)) == MODE_INT
)
5691 if (!need_eq_ne_p
&& *op1
== const0_rtx
)
5693 else if (*code
== EQ
|| *code
== NE
)
5697 *op0
= mips_zero_if_equal (cmp_op0
, cmp_op1
);
5701 *op1
= force_reg (GET_MODE (cmp_op0
), cmp_op1
);
5703 else if (!need_eq_ne_p
&& TARGET_CB_MAYBE
)
5733 *op1
= force_reg (GET_MODE (cmp_op0
), cmp_op1
);
5743 /* The comparison needs a separate scc instruction. Store the
5744 result of the scc in *OP0 and compare it against zero. */
5745 bool invert
= false;
5746 *op0
= gen_reg_rtx (GET_MODE (cmp_op0
));
5747 mips_emit_int_order_test (*code
, &invert
, *op0
, cmp_op0
, cmp_op1
);
5748 *code
= (invert
? EQ
: NE
);
5752 else if (ALL_FIXED_POINT_MODE_P (GET_MODE (cmp_op0
)))
5754 *op0
= gen_rtx_REG (CCDSPmode
, CCDSP_CC_REGNUM
);
5755 mips_emit_binary (*code
, *op0
, cmp_op0
, cmp_op1
);
5761 enum rtx_code cmp_code
;
5763 /* Floating-point tests use a separate C.cond.fmt or CMP.cond.fmt
5764 comparison to set a register. The branch or conditional move will
5765 then compare that register against zero.
5767 Set CMP_CODE to the code of the comparison instruction and
5768 *CODE to the code that the branch or move should use. */
5772 /* All FP conditions can be implemented directly with CMP.cond.fmt
5773 or by reversing the operands. */
5775 *op0
= gen_reg_rtx (CCFmode
);
5779 /* Three FP conditions cannot be implemented by reversing the
5780 operands for C.cond.fmt, instead a reversed condition code is
5781 required and a test for false. */
5782 *code
= mips_reversed_fp_cond (&cmp_code
) ? EQ
: NE
;
5784 *op0
= mips_allocate_fcc (CCmode
);
5786 *op0
= gen_rtx_REG (CCmode
, FPSW_REGNUM
);
5790 mips_emit_binary (cmp_code
, *op0
, cmp_op0
, cmp_op1
);
5794 /* Try performing the comparison in OPERANDS[1], whose arms are OPERANDS[2]
5795 and OPERAND[3]. Store the result in OPERANDS[0].
5797 On 64-bit targets, the mode of the comparison and target will always be
5798 SImode, thus possibly narrower than that of the comparison's operands. */
5801 mips_expand_scc (rtx operands
[])
5803 rtx target
= operands
[0];
5804 enum rtx_code code
= GET_CODE (operands
[1]);
5805 rtx op0
= operands
[2];
5806 rtx op1
= operands
[3];
5808 gcc_assert (GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
);
5810 if (code
== EQ
|| code
== NE
)
5813 && reg_imm10_operand (op1
, GET_MODE (op1
)))
5814 mips_emit_binary (code
, target
, op0
, op1
);
5817 rtx zie
= mips_zero_if_equal (op0
, op1
);
5818 mips_emit_binary (code
, target
, zie
, const0_rtx
);
5822 mips_emit_int_order_test (code
, 0, target
, op0
, op1
);
5825 /* Compare OPERANDS[1] with OPERANDS[2] using comparison code
5826 CODE and jump to OPERANDS[3] if the condition holds. */
5829 mips_expand_conditional_branch (rtx
*operands
)
5831 enum rtx_code code
= GET_CODE (operands
[0]);
5832 rtx op0
= operands
[1];
5833 rtx op1
= operands
[2];
5836 mips_emit_compare (&code
, &op0
, &op1
, TARGET_MIPS16
);
5837 condition
= gen_rtx_fmt_ee (code
, VOIDmode
, op0
, op1
);
5838 emit_jump_insn (gen_condjump (condition
, operands
[3]));
5843 (set temp (COND:CCV2 CMP_OP0 CMP_OP1))
5844 (set DEST (unspec [TRUE_SRC FALSE_SRC temp] UNSPEC_MOVE_TF_PS)) */
5847 mips_expand_vcondv2sf (rtx dest
, rtx true_src
, rtx false_src
,
5848 enum rtx_code cond
, rtx cmp_op0
, rtx cmp_op1
)
5853 reversed_p
= mips_reversed_fp_cond (&cond
);
5854 cmp_result
= mips_allocate_fcc (CCV2mode
);
5855 emit_insn (gen_scc_ps (cmp_result
,
5856 gen_rtx_fmt_ee (cond
, VOIDmode
, cmp_op0
, cmp_op1
)));
5858 emit_insn (gen_mips_cond_move_tf_ps (dest
, false_src
, true_src
,
5861 emit_insn (gen_mips_cond_move_tf_ps (dest
, true_src
, false_src
,
5865 /* Perform the comparison in OPERANDS[1]. Move OPERANDS[2] into OPERANDS[0]
5866 if the condition holds, otherwise move OPERANDS[3] into OPERANDS[0]. */
5869 mips_expand_conditional_move (rtx
*operands
)
5872 enum rtx_code code
= GET_CODE (operands
[1]);
5873 rtx op0
= XEXP (operands
[1], 0);
5874 rtx op1
= XEXP (operands
[1], 1);
5876 mips_emit_compare (&code
, &op0
, &op1
, true);
5877 cond
= gen_rtx_fmt_ee (code
, GET_MODE (op0
), op0
, op1
);
5879 /* There is no direct support for general conditional GP move involving
5880 two registers using SEL. */
5882 && INTEGRAL_MODE_P (GET_MODE (operands
[2]))
5883 && register_operand (operands
[2], VOIDmode
)
5884 && register_operand (operands
[3], VOIDmode
))
5886 machine_mode mode
= GET_MODE (operands
[0]);
5887 rtx temp
= gen_reg_rtx (mode
);
5888 rtx temp2
= gen_reg_rtx (mode
);
5890 emit_insn (gen_rtx_SET (temp
,
5891 gen_rtx_IF_THEN_ELSE (mode
, cond
,
5892 operands
[2], const0_rtx
)));
5894 /* Flip the test for the second operand. */
5895 cond
= gen_rtx_fmt_ee ((code
== EQ
) ? NE
: EQ
, GET_MODE (op0
), op0
, op1
);
5897 emit_insn (gen_rtx_SET (temp2
,
5898 gen_rtx_IF_THEN_ELSE (mode
, cond
,
5899 operands
[3], const0_rtx
)));
5901 /* Merge the two results, at least one is guaranteed to be zero. */
5902 emit_insn (gen_rtx_SET (operands
[0], gen_rtx_IOR (mode
, temp
, temp2
)));
5906 if (FLOAT_MODE_P (GET_MODE (operands
[2])) && !ISA_HAS_SEL
)
5908 operands
[2] = force_reg (GET_MODE (operands
[0]), operands
[2]);
5909 operands
[3] = force_reg (GET_MODE (operands
[0]), operands
[3]);
5912 emit_insn (gen_rtx_SET (operands
[0],
5913 gen_rtx_IF_THEN_ELSE (GET_MODE (operands
[0]), cond
,
5914 operands
[2], operands
[3])));
5918 /* Perform the comparison in COMPARISON, then trap if the condition holds. */
5921 mips_expand_conditional_trap (rtx comparison
)
5927 /* MIPS conditional trap instructions don't have GT or LE flavors,
5928 so we must swap the operands and convert to LT and GE respectively. */
5929 code
= GET_CODE (comparison
);
5936 code
= swap_condition (code
);
5937 op0
= XEXP (comparison
, 1);
5938 op1
= XEXP (comparison
, 0);
5942 op0
= XEXP (comparison
, 0);
5943 op1
= XEXP (comparison
, 1);
5947 mode
= GET_MODE (XEXP (comparison
, 0));
5948 op0
= force_reg (mode
, op0
);
5949 if (!(ISA_HAS_COND_TRAPI
5950 ? arith_operand (op1
, mode
)
5951 : reg_or_0_operand (op1
, mode
)))
5952 op1
= force_reg (mode
, op1
);
5954 emit_insn (gen_rtx_TRAP_IF (VOIDmode
,
5955 gen_rtx_fmt_ee (code
, mode
, op0
, op1
),
5959 /* Initialize *CUM for a call to a function of type FNTYPE. */
5962 mips_init_cumulative_args (CUMULATIVE_ARGS
*cum
, tree fntype
)
5964 memset (cum
, 0, sizeof (*cum
));
5965 cum
->prototype
= (fntype
&& prototype_p (fntype
));
5966 cum
->gp_reg_found
= (cum
->prototype
&& stdarg_p (fntype
));
5969 /* Fill INFO with information about a single argument. CUM is the
5970 cumulative state for earlier arguments. MODE is the mode of this
5971 argument and TYPE is its type (if known). NAMED is true if this
5972 is a named (fixed) argument rather than a variable one. */
5975 mips_get_arg_info (struct mips_arg_info
*info
, const CUMULATIVE_ARGS
*cum
,
5976 machine_mode mode
, const_tree type
, bool named
)
5978 bool doubleword_aligned_p
;
5979 unsigned int num_bytes
, num_words
, max_regs
;
5981 /* Work out the size of the argument. */
5982 num_bytes
= type
? int_size_in_bytes (type
) : GET_MODE_SIZE (mode
);
5983 num_words
= (num_bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
5985 /* Decide whether it should go in a floating-point register, assuming
5986 one is free. Later code checks for availability.
5988 The checks against UNITS_PER_FPVALUE handle the soft-float and
5989 single-float cases. */
5993 /* The EABI conventions have traditionally been defined in terms
5994 of TYPE_MODE, regardless of the actual type. */
5995 info
->fpr_p
= ((GET_MODE_CLASS (mode
) == MODE_FLOAT
5996 || mode
== V2SFmode
)
5997 && GET_MODE_SIZE (mode
) <= UNITS_PER_FPVALUE
);
6002 /* Only leading floating-point scalars are passed in
6003 floating-point registers. We also handle vector floats the same
6004 say, which is OK because they are not covered by the standard ABI. */
6005 gcc_assert (TARGET_PAIRED_SINGLE_FLOAT
|| mode
!= V2SFmode
);
6006 info
->fpr_p
= (!cum
->gp_reg_found
6007 && cum
->arg_number
< 2
6009 || SCALAR_FLOAT_TYPE_P (type
)
6010 || VECTOR_FLOAT_TYPE_P (type
))
6011 && (GET_MODE_CLASS (mode
) == MODE_FLOAT
6012 || mode
== V2SFmode
)
6013 && GET_MODE_SIZE (mode
) <= UNITS_PER_FPVALUE
);
6018 /* Scalar, complex and vector floating-point types are passed in
6019 floating-point registers, as long as this is a named rather
6020 than a variable argument. */
6021 gcc_assert (TARGET_PAIRED_SINGLE_FLOAT
|| mode
!= V2SFmode
);
6022 info
->fpr_p
= (named
6023 && (type
== 0 || FLOAT_TYPE_P (type
))
6024 && (GET_MODE_CLASS (mode
) == MODE_FLOAT
6025 || GET_MODE_CLASS (mode
) == MODE_COMPLEX_FLOAT
6026 || mode
== V2SFmode
)
6027 && GET_MODE_UNIT_SIZE (mode
) <= UNITS_PER_FPVALUE
);
6029 /* ??? According to the ABI documentation, the real and imaginary
6030 parts of complex floats should be passed in individual registers.
6031 The real and imaginary parts of stack arguments are supposed
6032 to be contiguous and there should be an extra word of padding
6035 This has two problems. First, it makes it impossible to use a
6036 single "void *" va_list type, since register and stack arguments
6037 are passed differently. (At the time of writing, MIPSpro cannot
6038 handle complex float varargs correctly.) Second, it's unclear
6039 what should happen when there is only one register free.
6041 For now, we assume that named complex floats should go into FPRs
6042 if there are two FPRs free, otherwise they should be passed in the
6043 same way as a struct containing two floats. */
6045 && GET_MODE_CLASS (mode
) == MODE_COMPLEX_FLOAT
6046 && GET_MODE_UNIT_SIZE (mode
) < UNITS_PER_FPVALUE
)
6048 if (cum
->num_gprs
>= MAX_ARGS_IN_REGISTERS
- 1)
6049 info
->fpr_p
= false;
6059 /* See whether the argument has doubleword alignment. */
6060 doubleword_aligned_p
= (mips_function_arg_boundary (mode
, type
)
6063 /* Set REG_OFFSET to the register count we're interested in.
6064 The EABI allocates the floating-point registers separately,
6065 but the other ABIs allocate them like integer registers. */
6066 info
->reg_offset
= (mips_abi
== ABI_EABI
&& info
->fpr_p
6070 /* Advance to an even register if the argument is doubleword-aligned. */
6071 if (doubleword_aligned_p
)
6072 info
->reg_offset
+= info
->reg_offset
& 1;
6074 /* Work out the offset of a stack argument. */
6075 info
->stack_offset
= cum
->stack_words
;
6076 if (doubleword_aligned_p
)
6077 info
->stack_offset
+= info
->stack_offset
& 1;
6079 max_regs
= MAX_ARGS_IN_REGISTERS
- info
->reg_offset
;
6081 /* Partition the argument between registers and stack. */
6082 info
->reg_words
= MIN (num_words
, max_regs
);
6083 info
->stack_words
= num_words
- info
->reg_words
;
6086 /* INFO describes a register argument that has the normal format for the
6087 argument's mode. Return the register it uses, assuming that FPRs are
6088 available if HARD_FLOAT_P. */
6091 mips_arg_regno (const struct mips_arg_info
*info
, bool hard_float_p
)
6093 if (!info
->fpr_p
|| !hard_float_p
)
6094 return GP_ARG_FIRST
+ info
->reg_offset
;
6095 else if (mips_abi
== ABI_32
&& TARGET_DOUBLE_FLOAT
&& info
->reg_offset
> 0)
6096 /* In o32, the second argument is always passed in $f14
6097 for TARGET_DOUBLE_FLOAT, regardless of whether the
6098 first argument was a word or doubleword. */
6099 return FP_ARG_FIRST
+ 2;
6101 return FP_ARG_FIRST
+ info
->reg_offset
;
6104 /* Implement TARGET_STRICT_ARGUMENT_NAMING. */
6107 mips_strict_argument_naming (cumulative_args_t ca ATTRIBUTE_UNUSED
)
6109 return !TARGET_OLDABI
;
6112 /* Implement TARGET_FUNCTION_ARG. */
6115 mips_function_arg (cumulative_args_t cum_v
, const function_arg_info
&arg
)
6117 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
6118 struct mips_arg_info info
;
6120 /* We will be called with an end marker after the last argument
6121 has been seen. Whatever we return will be passed to the call expander.
6122 If we need a MIPS16 fp_code, return a REG with the code stored as
6124 if (arg
.end_marker_p ())
6126 if (TARGET_MIPS16
&& cum
->fp_code
!= 0)
6127 return gen_rtx_REG ((machine_mode
) cum
->fp_code
, 0);
6132 mips_get_arg_info (&info
, cum
, arg
.mode
, arg
.type
, arg
.named
);
6134 /* Return straight away if the whole argument is passed on the stack. */
6135 if (info
.reg_offset
== MAX_ARGS_IN_REGISTERS
)
6138 /* The n32 and n64 ABIs say that if any 64-bit chunk of the structure
6139 contains a double in its entirety, then that 64-bit chunk is passed
6140 in a floating-point register. */
6142 && TARGET_HARD_FLOAT
6145 && TREE_CODE (arg
.type
) == RECORD_TYPE
6146 && TYPE_SIZE_UNIT (arg
.type
)
6147 && tree_fits_uhwi_p (TYPE_SIZE_UNIT (arg
.type
)))
6151 /* First check to see if there is any such field. */
6152 for (field
= TYPE_FIELDS (arg
.type
); field
; field
= DECL_CHAIN (field
))
6153 if (TREE_CODE (field
) == FIELD_DECL
6154 && SCALAR_FLOAT_TYPE_P (TREE_TYPE (field
))
6155 && TYPE_PRECISION (TREE_TYPE (field
)) == BITS_PER_WORD
6156 && tree_fits_shwi_p (bit_position (field
))
6157 && int_bit_position (field
) % BITS_PER_WORD
== 0)
6162 /* Now handle the special case by returning a PARALLEL
6163 indicating where each 64-bit chunk goes. INFO.REG_WORDS
6164 chunks are passed in registers. */
6166 HOST_WIDE_INT bitpos
;
6169 /* assign_parms checks the mode of ENTRY_PARM, so we must
6170 use the actual mode here. */
6171 ret
= gen_rtx_PARALLEL (arg
.mode
, rtvec_alloc (info
.reg_words
));
6174 field
= TYPE_FIELDS (arg
.type
);
6175 for (i
= 0; i
< info
.reg_words
; i
++)
6178 bool zero_width_field_abi_change
= false;
6180 for (; field
; field
= DECL_CHAIN (field
))
6182 if (TREE_CODE (field
) != FIELD_DECL
)
6185 /* Ignore zero-width fields. And, if the ignored
6186 field is not a C++ zero-width bit-field, it may be
6188 if (DECL_FIELD_CXX_ZERO_WIDTH_BIT_FIELD (field
))
6190 if (DECL_SIZE (field
)
6191 && integer_zerop (DECL_SIZE (field
)))
6193 zero_width_field_abi_change
= true;
6197 if (int_bit_position (field
) >= bitpos
)
6202 && int_bit_position (field
) == bitpos
6203 && SCALAR_FLOAT_TYPE_P (TREE_TYPE (field
))
6204 && TYPE_PRECISION (TREE_TYPE (field
)) == BITS_PER_WORD
)
6205 reg
= gen_rtx_REG (DFmode
, FP_ARG_FIRST
+ info
.reg_offset
+ i
);
6208 reg
= gen_rtx_REG (DImode
,
6209 GP_ARG_FIRST
+ info
.reg_offset
+ i
);
6210 zero_width_field_abi_change
= false;
6213 if (zero_width_field_abi_change
&& warn_psabi
)
6215 static unsigned last_reported_type_uid
;
6216 unsigned uid
= TYPE_UID (TYPE_MAIN_VARIANT (arg
.type
));
6217 if (uid
!= last_reported_type_uid
)
6219 static const char *url
6221 "gcc-12/changes.html#mips_zero_width_fields";
6222 inform (input_location
,
6223 "the ABI for passing a value containing "
6224 "zero-width fields before an adjacent "
6225 "64-bit floating-point field was changed "
6226 "in GCC %{12.1%}", url
);
6227 last_reported_type_uid
= uid
;
6232 = gen_rtx_EXPR_LIST (VOIDmode
, reg
,
6233 GEN_INT (bitpos
/ BITS_PER_UNIT
));
6235 bitpos
+= BITS_PER_WORD
;
6241 /* Handle the n32/n64 conventions for passing complex floating-point
6242 arguments in FPR pairs. The real part goes in the lower register
6243 and the imaginary part goes in the upper register. */
6246 && GET_MODE_CLASS (arg
.mode
) == MODE_COMPLEX_FLOAT
)
6252 inner
= GET_MODE_INNER (arg
.mode
);
6253 regno
= FP_ARG_FIRST
+ info
.reg_offset
;
6254 if (info
.reg_words
* UNITS_PER_WORD
== GET_MODE_SIZE (inner
))
6256 /* Real part in registers, imaginary part on stack. */
6257 gcc_assert (info
.stack_words
== info
.reg_words
);
6258 return gen_rtx_REG (inner
, regno
);
6262 gcc_assert (info
.stack_words
== 0);
6263 real
= gen_rtx_EXPR_LIST (VOIDmode
,
6264 gen_rtx_REG (inner
, regno
),
6266 imag
= gen_rtx_EXPR_LIST (VOIDmode
,
6268 regno
+ info
.reg_words
/ 2),
6269 GEN_INT (GET_MODE_SIZE (inner
)));
6270 return gen_rtx_PARALLEL (arg
.mode
, gen_rtvec (2, real
, imag
));
6274 return gen_rtx_REG (arg
.mode
, mips_arg_regno (&info
, TARGET_HARD_FLOAT
));
6277 /* Implement TARGET_FUNCTION_ARG_ADVANCE. */
6280 mips_function_arg_advance (cumulative_args_t cum_v
,
6281 const function_arg_info
&arg
)
6283 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
6284 struct mips_arg_info info
;
6286 mips_get_arg_info (&info
, cum
, arg
.mode
, arg
.type
, arg
.named
);
6289 cum
->gp_reg_found
= true;
6291 /* See the comment above the CUMULATIVE_ARGS structure in mips.h for
6292 an explanation of what this code does. It assumes that we're using
6293 either the o32 or the o64 ABI, both of which pass at most 2 arguments
6295 if (cum
->arg_number
< 2 && info
.fpr_p
)
6296 cum
->fp_code
+= (arg
.mode
== SFmode
? 1 : 2) << (cum
->arg_number
* 2);
6298 /* Advance the register count. This has the effect of setting
6299 num_gprs to MAX_ARGS_IN_REGISTERS if a doubleword-aligned
6300 argument required us to skip the final GPR and pass the whole
6301 argument on the stack. */
6302 if (mips_abi
!= ABI_EABI
|| !info
.fpr_p
)
6303 cum
->num_gprs
= info
.reg_offset
+ info
.reg_words
;
6304 else if (info
.reg_words
> 0)
6305 cum
->num_fprs
+= MAX_FPRS_PER_FMT
;
6307 /* Advance the stack word count. */
6308 if (info
.stack_words
> 0)
6309 cum
->stack_words
= info
.stack_offset
+ info
.stack_words
;
6314 /* Implement TARGET_ARG_PARTIAL_BYTES. */
6317 mips_arg_partial_bytes (cumulative_args_t cum
, const function_arg_info
&arg
)
6319 struct mips_arg_info info
;
6321 mips_get_arg_info (&info
, get_cumulative_args (cum
),
6322 arg
.mode
, arg
.type
, arg
.named
);
6323 return info
.stack_words
> 0 ? info
.reg_words
* UNITS_PER_WORD
: 0;
6326 /* Given MODE and TYPE of a function argument, return the alignment in
6328 In case of typedef, alignment of its original type is
6332 mips_function_arg_alignment (machine_mode mode
, const_tree type
)
6335 return GET_MODE_ALIGNMENT (mode
);
6337 if (is_typedef_decl (TYPE_NAME (type
)))
6338 type
= DECL_ORIGINAL_TYPE (TYPE_NAME (type
));
6340 return TYPE_ALIGN (type
);
6343 /* Implement TARGET_FUNCTION_ARG_BOUNDARY. Every parameter gets at
6344 least PARM_BOUNDARY bits of alignment, but will be given anything up
6345 to STACK_BOUNDARY bits if the type requires it. */
6348 mips_function_arg_boundary (machine_mode mode
, const_tree type
)
6350 unsigned int alignment
;
6351 alignment
= mips_function_arg_alignment (mode
, type
);
6353 if (alignment
< PARM_BOUNDARY
)
6354 alignment
= PARM_BOUNDARY
;
6355 if (alignment
> STACK_BOUNDARY
)
6356 alignment
= STACK_BOUNDARY
;
6360 /* Implement TARGET_GET_RAW_RESULT_MODE and TARGET_GET_RAW_ARG_MODE. */
6362 static fixed_size_mode
6363 mips_get_reg_raw_mode (int regno
)
6365 if (TARGET_FLOATXX
&& FP_REG_P (regno
))
6367 return default_get_reg_raw_mode (regno
);
6370 /* Implement TARGET_FUNCTION_ARG_PADDING; return PAD_UPWARD if the first
6371 byte of the stack slot has useful data, PAD_DOWNWARD if the last byte
6374 static pad_direction
6375 mips_function_arg_padding (machine_mode mode
, const_tree type
)
6377 /* On little-endian targets, the first byte of every stack argument
6378 is passed in the first byte of the stack slot. */
6379 if (!BYTES_BIG_ENDIAN
)
6382 /* Otherwise, integral types are padded downward: the last byte of a
6383 stack argument is passed in the last byte of the stack slot. */
6385 ? (INTEGRAL_TYPE_P (type
)
6386 || POINTER_TYPE_P (type
)
6387 || FIXED_POINT_TYPE_P (type
))
6388 : (SCALAR_INT_MODE_P (mode
)
6389 || ALL_SCALAR_FIXED_POINT_MODE_P (mode
)))
6390 return PAD_DOWNWARD
;
6392 /* Big-endian o64 pads floating-point arguments downward. */
6393 if (mips_abi
== ABI_O64
)
6394 if (type
!= 0 ? FLOAT_TYPE_P (type
) : GET_MODE_CLASS (mode
) == MODE_FLOAT
)
6395 return PAD_DOWNWARD
;
6397 /* Other types are padded upward for o32, o64, n32 and n64. */
6398 if (mips_abi
!= ABI_EABI
)
6401 /* Arguments smaller than a stack slot are padded downward. */
6403 ? GET_MODE_BITSIZE (mode
) >= PARM_BOUNDARY
6404 : int_size_in_bytes (type
) >= (PARM_BOUNDARY
/ BITS_PER_UNIT
))
6407 return PAD_DOWNWARD
;
6410 /* Likewise BLOCK_REG_PADDING (MODE, TYPE, ...). Return !BYTES_BIG_ENDIAN
6411 if the least significant byte of the register has useful data. Return
6412 the opposite if the most significant byte does. */
6415 mips_pad_reg_upward (machine_mode mode
, tree type
)
6417 /* No shifting is required for floating-point arguments. */
6418 if (type
!= 0 ? FLOAT_TYPE_P (type
) : GET_MODE_CLASS (mode
) == MODE_FLOAT
)
6419 return !BYTES_BIG_ENDIAN
;
6421 /* Otherwise, apply the same padding to register arguments as we do
6422 to stack arguments. */
6423 return mips_function_arg_padding (mode
, type
) == PAD_UPWARD
;
6426 /* Return nonzero when an argument must be passed by reference. */
6429 mips_pass_by_reference (cumulative_args_t
, const function_arg_info
&arg
)
6431 if (mips_abi
== ABI_EABI
)
6435 /* ??? How should SCmode be handled? */
6436 if (arg
.mode
== DImode
|| arg
.mode
== DFmode
6437 || arg
.mode
== DQmode
|| arg
.mode
== UDQmode
6438 || arg
.mode
== DAmode
|| arg
.mode
== UDAmode
)
6441 size
= arg
.type_size_in_bytes ();
6442 return size
== -1 || size
> UNITS_PER_WORD
;
6446 /* If we have a variable-sized parameter, we have no choice. */
6447 return targetm
.calls
.must_pass_in_stack (arg
);
6451 /* Implement TARGET_CALLEE_COPIES. */
6454 mips_callee_copies (cumulative_args_t
, const function_arg_info
&arg
)
6456 return mips_abi
== ABI_EABI
&& arg
.named
;
6459 /* See whether VALTYPE is a record whose fields should be returned in
6460 floating-point registers. If so, return the number of fields and
6461 list them in FIELDS (which should have two elements). Return 0
6464 For n32 & n64, a structure with one or two fields is returned in
6465 floating-point registers as long as every field has a floating-point
6468 The C++ FE used to remove zero-width bit-fields in GCC 11 and earlier.
6469 To make a proper diagnostic, this function will set
6470 HAS_CXX_ZERO_WIDTH_BF to true once a C++ zero-width bit-field shows up,
6473 We had failed to ignore C++17 empty bases in GCC 7, 8, 9, 10, and 11.
6474 This caused an ABI incompatibility between C++14 and C++17. This is
6475 fixed now and to make a proper diagnostic, this function will set
6476 HAS_CXX17_EMPTY_BASE to true once a C++17 empty base shows up, and
6479 The caller should use the value of HAS_CXX17_EMPTY_BASE and/or
6480 HAS_CXX_ZERO_WIDTH_BF to emit a proper -Wpsabi inform. */
6483 mips_fpr_return_fields (const_tree valtype
, tree
*fields
,
6484 bool *has_cxx_zero_width_bf
,
6485 bool *has_cxx17_empty_base
)
6493 if (TREE_CODE (valtype
) != RECORD_TYPE
)
6497 for (field
= TYPE_FIELDS (valtype
); field
!= 0; field
= DECL_CHAIN (field
))
6499 if (TREE_CODE (field
) != FIELD_DECL
)
6502 if (cxx17_empty_base_field_p (field
))
6504 *has_cxx17_empty_base
= true;
6508 if (DECL_FIELD_CXX_ZERO_WIDTH_BIT_FIELD (field
))
6510 *has_cxx_zero_width_bf
= true;
6514 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (field
)))
6520 fields
[i
++] = field
;
6525 /* Implement TARGET_RETURN_IN_MSB. For n32 & n64, we should return
6526 a value in the most significant part of $2/$3 if:
6528 - the target is big-endian;
6530 - the value has a structure or union type (we generalize this to
6531 cover aggregates from other languages too); and
6533 - the structure is not returned in floating-point registers. */
6536 mips_return_in_msb (const_tree valtype
)
6538 if (!TARGET_NEWABI
|| !TARGET_BIG_ENDIAN
|| !AGGREGATE_TYPE_P (valtype
))
6542 bool has_cxx_zero_width_bf
= false;
6544 /* Its value is not used. */
6545 bool has_cxx17_empty_base
= false;
6547 return (mips_fpr_return_fields (valtype
, fields
,
6548 &has_cxx_zero_width_bf
,
6549 &has_cxx17_empty_base
) == 0
6550 || has_cxx_zero_width_bf
);
6553 /* Return true if the function return value MODE will get returned in a
6554 floating-point register. */
6557 mips_return_mode_in_fpr_p (machine_mode mode
)
6559 gcc_assert (TARGET_PAIRED_SINGLE_FLOAT
|| mode
!= V2SFmode
);
6560 return ((GET_MODE_CLASS (mode
) == MODE_FLOAT
6562 || GET_MODE_CLASS (mode
) == MODE_COMPLEX_FLOAT
)
6563 && GET_MODE_UNIT_SIZE (mode
) <= UNITS_PER_HWFPVALUE
);
6566 /* Return the representation of an FPR return register when the
6567 value being returned in FP_RETURN has mode VALUE_MODE and the
6568 return type itself has mode TYPE_MODE. On NewABI targets,
6569 the two modes may be different for structures like:
6571 struct __attribute__((packed)) foo { float f; }
6573 where we return the SFmode value of "f" in FP_RETURN, but where
6574 the structure itself has mode BLKmode. */
6577 mips_return_fpr_single (machine_mode type_mode
,
6578 machine_mode value_mode
)
6582 x
= gen_rtx_REG (value_mode
, FP_RETURN
);
6583 if (type_mode
!= value_mode
)
6585 x
= gen_rtx_EXPR_LIST (VOIDmode
, x
, const0_rtx
);
6586 x
= gen_rtx_PARALLEL (type_mode
, gen_rtvec (1, x
));
6591 /* Return a composite value in a pair of floating-point registers.
6592 MODE1 and OFFSET1 are the mode and byte offset for the first value,
6593 likewise MODE2 and OFFSET2 for the second. MODE is the mode of the
6596 For n32 & n64, $f0 always holds the first value and $f2 the second.
6597 Otherwise the values are packed together as closely as possible. */
6600 mips_return_fpr_pair (machine_mode mode
,
6601 machine_mode mode1
, HOST_WIDE_INT offset1
,
6602 machine_mode mode2
, HOST_WIDE_INT offset2
)
6606 inc
= (TARGET_NEWABI
|| mips_abi
== ABI_32
? 2 : MAX_FPRS_PER_FMT
);
6607 return gen_rtx_PARALLEL
6610 gen_rtx_EXPR_LIST (VOIDmode
,
6611 gen_rtx_REG (mode1
, FP_RETURN
),
6613 gen_rtx_EXPR_LIST (VOIDmode
,
6614 gen_rtx_REG (mode2
, FP_RETURN
+ inc
),
6615 GEN_INT (offset2
))));
6619 /* Implement TARGET_FUNCTION_VALUE and TARGET_LIBCALL_VALUE.
6620 For normal calls, VALTYPE is the return type and MODE is VOIDmode.
6621 For libcalls, VALTYPE is null and MODE is the mode of the return value. */
6624 mips_function_value_1 (const_tree valtype
, const_tree fn_decl_or_type
,
6633 if (fn_decl_or_type
&& DECL_P (fn_decl_or_type
))
6634 func
= fn_decl_or_type
;
6638 mode
= TYPE_MODE (valtype
);
6639 unsigned_p
= TYPE_UNSIGNED (valtype
);
6641 /* Since TARGET_PROMOTE_FUNCTION_MODE unconditionally promotes,
6642 return values, promote the mode here too. */
6643 mode
= promote_function_mode (valtype
, mode
, &unsigned_p
, func
, 1);
6645 bool has_cxx_zero_width_bf
= false;
6646 bool has_cxx17_empty_base
= false;
6647 int use_fpr
= mips_fpr_return_fields (valtype
, fields
,
6648 &has_cxx_zero_width_bf
,
6649 &has_cxx17_empty_base
);
6651 /* If has_cxx_zero_width_bf and has_cxx17_empty_base are both
6652 true, it *happens* that there is no ABI change. So we won't
6653 inform in this case. */
6654 if (TARGET_HARD_FLOAT
6656 && has_cxx_zero_width_bf
6657 && !has_cxx17_empty_base
6660 static unsigned last_reported_type_uid
;
6661 unsigned uid
= TYPE_UID (TYPE_MAIN_VARIANT (valtype
));
6662 if (uid
!= last_reported_type_uid
)
6664 static const char *url
6666 "gcc-12/changes.html#zero_width_bitfields";
6667 inform (input_location
,
6668 "the ABI for returning a value containing "
6669 "zero-width bit-fields but otherwise an aggregate "
6670 "with only one or two floating-point fields was "
6671 "changed in GCC %{12.1%}", url
);
6672 last_reported_type_uid
= uid
;
6676 if (has_cxx_zero_width_bf
)
6679 if (TARGET_HARD_FLOAT
6682 && has_cxx17_empty_base
)
6684 static unsigned last_reported_type_uid
;
6685 unsigned uid
= TYPE_UID (TYPE_MAIN_VARIANT (valtype
));
6686 if (uid
!= last_reported_type_uid
)
6688 static const char *url
6690 "gcc-12/changes.html#mips_cxx17_empty_bases";
6691 inform (input_location
,
6692 "the ABI for returning a value with C++17 empty "
6693 "bases but otherwise an aggregate with only one or "
6694 "two floating-point fields was changed in GCC "
6696 last_reported_type_uid
= uid
;
6700 /* Handle structures whose fields are returned in $f0/$f2. */
6704 return mips_return_fpr_single (mode
,
6705 TYPE_MODE (TREE_TYPE (fields
[0])));
6708 return mips_return_fpr_pair (mode
,
6709 TYPE_MODE (TREE_TYPE (fields
[0])),
6710 int_byte_position (fields
[0]),
6711 TYPE_MODE (TREE_TYPE (fields
[1])),
6712 int_byte_position (fields
[1]));
6715 /* If a value is passed in the most significant part of a register, see
6716 whether we have to round the mode up to a whole number of words. */
6717 if (mips_return_in_msb (valtype
))
6719 HOST_WIDE_INT size
= int_size_in_bytes (valtype
);
6720 if (size
% UNITS_PER_WORD
!= 0)
6722 size
+= UNITS_PER_WORD
- size
% UNITS_PER_WORD
;
6723 mode
= int_mode_for_size (size
* BITS_PER_UNIT
, 0).require ();
6727 /* For EABI, the class of return register depends entirely on MODE.
6728 For example, "struct { some_type x; }" and "union { some_type x; }"
6729 are returned in the same way as a bare "some_type" would be.
6730 Other ABIs only use FPRs for scalar, complex or vector types. */
6731 if (mips_abi
!= ABI_EABI
&& !FLOAT_TYPE_P (valtype
))
6732 return gen_rtx_REG (mode
, GP_RETURN
);
6737 /* Handle long doubles for n32 & n64. */
6739 return mips_return_fpr_pair (mode
,
6741 DImode
, GET_MODE_SIZE (mode
) / 2);
6743 if (mips_return_mode_in_fpr_p (mode
))
6745 if (GET_MODE_CLASS (mode
) == MODE_COMPLEX_FLOAT
)
6746 return mips_return_fpr_pair (mode
,
6747 GET_MODE_INNER (mode
), 0,
6748 GET_MODE_INNER (mode
),
6749 GET_MODE_SIZE (mode
) / 2);
6751 return gen_rtx_REG (mode
, FP_RETURN
);
6755 return gen_rtx_REG (mode
, GP_RETURN
);
6758 /* Implement TARGET_FUNCTION_VALUE. */
6761 mips_function_value (const_tree valtype
, const_tree fn_decl_or_type
,
6762 bool outgoing ATTRIBUTE_UNUSED
)
6764 return mips_function_value_1 (valtype
, fn_decl_or_type
, VOIDmode
);
6767 /* Implement TARGET_LIBCALL_VALUE. */
6770 mips_libcall_value (machine_mode mode
, const_rtx fun ATTRIBUTE_UNUSED
)
6772 return mips_function_value_1 (NULL_TREE
, NULL_TREE
, mode
);
6775 /* Implement TARGET_FUNCTION_VALUE_REGNO_P.
6777 On the MIPS, R2 R3 and F0 F2 are the only register thus used. */
6780 mips_function_value_regno_p (const unsigned int regno
)
6782 /* Most types only require one GPR or one FPR for return values but for
6783 hard-float two FPRs can be used for _Complex types (for all ABIs)
6784 and long doubles (for n64). */
6785 if (regno
== GP_RETURN
6786 || regno
== FP_RETURN
6787 || (FP_RETURN
!= GP_RETURN
6788 && regno
== FP_RETURN
+ 2))
6791 /* For o32 FP32, _Complex double will be returned in four 32-bit registers.
6792 This does not apply to o32 FPXX as floating-point function argument and
6793 return registers are described as 64-bit even though floating-point
6794 registers are primarily described as 32-bit internally.
6795 See: mips_get_reg_raw_mode. */
6796 if ((mips_abi
== ABI_32
&& TARGET_FLOAT32
)
6797 && FP_RETURN
!= GP_RETURN
6798 && (regno
== FP_RETURN
+ 1
6799 || regno
== FP_RETURN
+ 3))
6805 /* Implement TARGET_RETURN_IN_MEMORY. Under the o32 and o64 ABIs,
6806 all BLKmode objects are returned in memory. Under the n32, n64
6807 and embedded ABIs, small structures are returned in a register.
6808 Objects with varying size must still be returned in memory, of
6812 mips_return_in_memory (const_tree type
, const_tree fndecl ATTRIBUTE_UNUSED
)
6815 /* Ensure that any floating point vector types are returned via memory
6816 even if they are supported through a vector mode with some ASEs. */
6817 return (VECTOR_FLOAT_TYPE_P (type
)
6818 || TYPE_MODE (type
) == BLKmode
);
6820 return (!IN_RANGE (int_size_in_bytes (type
), 0, 2 * UNITS_PER_WORD
));
6823 /* Implement TARGET_SETUP_INCOMING_VARARGS. */
6826 mips_setup_incoming_varargs (cumulative_args_t cum
,
6827 const function_arg_info
&arg
,
6828 int *pretend_size ATTRIBUTE_UNUSED
, int no_rtl
)
6830 CUMULATIVE_ARGS local_cum
;
6831 int gp_saved
, fp_saved
;
6833 /* The caller has advanced CUM up to, but not beyond, the last named
6834 argument. Advance a local copy of CUM past the last "real" named
6835 argument, to find out how many registers are left over. */
6836 local_cum
= *get_cumulative_args (cum
);
6837 if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl
)))
6838 mips_function_arg_advance (pack_cumulative_args (&local_cum
), arg
);
6840 /* Found out how many registers we need to save. */
6841 gp_saved
= MAX_ARGS_IN_REGISTERS
- local_cum
.num_gprs
;
6842 fp_saved
= (EABI_FLOAT_VARARGS_P
6843 ? MAX_ARGS_IN_REGISTERS
- local_cum
.num_fprs
6852 ptr
= plus_constant (Pmode
, virtual_incoming_args_rtx
,
6853 REG_PARM_STACK_SPACE (cfun
->decl
)
6854 - gp_saved
* UNITS_PER_WORD
);
6855 mem
= gen_frame_mem (BLKmode
, ptr
);
6856 set_mem_alias_set (mem
, get_varargs_alias_set ());
6858 move_block_from_reg (local_cum
.num_gprs
+ GP_ARG_FIRST
,
6863 /* We can't use move_block_from_reg, because it will use
6868 /* Set OFF to the offset from virtual_incoming_args_rtx of
6869 the first float register. The FP save area lies below
6870 the integer one, and is aligned to UNITS_PER_FPVALUE bytes. */
6871 off
= ROUND_DOWN (-gp_saved
* UNITS_PER_WORD
, UNITS_PER_FPVALUE
);
6872 off
-= fp_saved
* UNITS_PER_FPREG
;
6874 mode
= TARGET_SINGLE_FLOAT
? SFmode
: DFmode
;
6876 for (i
= local_cum
.num_fprs
; i
< MAX_ARGS_IN_REGISTERS
;
6877 i
+= MAX_FPRS_PER_FMT
)
6881 ptr
= plus_constant (Pmode
, virtual_incoming_args_rtx
, off
);
6882 mem
= gen_frame_mem (mode
, ptr
);
6883 set_mem_alias_set (mem
, get_varargs_alias_set ());
6884 mips_emit_move (mem
, gen_rtx_REG (mode
, FP_ARG_FIRST
+ i
));
6885 off
+= UNITS_PER_HWFPVALUE
;
6889 if (REG_PARM_STACK_SPACE (cfun
->decl
) == 0)
6890 cfun
->machine
->varargs_size
= (gp_saved
* UNITS_PER_WORD
6891 + fp_saved
* UNITS_PER_FPREG
);
6894 /* Implement TARGET_BUILTIN_VA_LIST. */
6897 mips_build_builtin_va_list (void)
6899 if (EABI_FLOAT_VARARGS_P
)
6901 /* We keep 3 pointers, and two offsets.
6903 Two pointers are to the overflow area, which starts at the CFA.
6904 One of these is constant, for addressing into the GPR save area
6905 below it. The other is advanced up the stack through the
6908 The third pointer is to the bottom of the GPR save area.
6909 Since the FPR save area is just below it, we can address
6910 FPR slots off this pointer.
6912 We also keep two one-byte offsets, which are to be subtracted
6913 from the constant pointers to yield addresses in the GPR and
6914 FPR save areas. These are downcounted as float or non-float
6915 arguments are used, and when they get to zero, the argument
6916 must be obtained from the overflow region. */
6917 tree f_ovfl
, f_gtop
, f_ftop
, f_goff
, f_foff
, f_res
, record
;
6920 record
= lang_hooks
.types
.make_type (RECORD_TYPE
);
6922 f_ovfl
= build_decl (BUILTINS_LOCATION
,
6923 FIELD_DECL
, get_identifier ("__overflow_argptr"),
6925 f_gtop
= build_decl (BUILTINS_LOCATION
,
6926 FIELD_DECL
, get_identifier ("__gpr_top"),
6928 f_ftop
= build_decl (BUILTINS_LOCATION
,
6929 FIELD_DECL
, get_identifier ("__fpr_top"),
6931 f_goff
= build_decl (BUILTINS_LOCATION
,
6932 FIELD_DECL
, get_identifier ("__gpr_offset"),
6933 unsigned_char_type_node
);
6934 f_foff
= build_decl (BUILTINS_LOCATION
,
6935 FIELD_DECL
, get_identifier ("__fpr_offset"),
6936 unsigned_char_type_node
);
6937 /* Explicitly pad to the size of a pointer, so that -Wpadded won't
6938 warn on every user file. */
6939 index
= build_int_cst (NULL_TREE
, GET_MODE_SIZE (ptr_mode
) - 2 - 1);
6940 array
= build_array_type (unsigned_char_type_node
,
6941 build_index_type (index
));
6942 f_res
= build_decl (BUILTINS_LOCATION
,
6943 FIELD_DECL
, get_identifier ("__reserved"), array
);
6945 DECL_FIELD_CONTEXT (f_ovfl
) = record
;
6946 DECL_FIELD_CONTEXT (f_gtop
) = record
;
6947 DECL_FIELD_CONTEXT (f_ftop
) = record
;
6948 DECL_FIELD_CONTEXT (f_goff
) = record
;
6949 DECL_FIELD_CONTEXT (f_foff
) = record
;
6950 DECL_FIELD_CONTEXT (f_res
) = record
;
6952 TYPE_FIELDS (record
) = f_ovfl
;
6953 DECL_CHAIN (f_ovfl
) = f_gtop
;
6954 DECL_CHAIN (f_gtop
) = f_ftop
;
6955 DECL_CHAIN (f_ftop
) = f_goff
;
6956 DECL_CHAIN (f_goff
) = f_foff
;
6957 DECL_CHAIN (f_foff
) = f_res
;
6959 layout_type (record
);
6963 /* Otherwise, we use 'void *'. */
6964 return ptr_type_node
;
6967 /* Implement TARGET_EXPAND_BUILTIN_VA_START. */
6970 mips_va_start (tree valist
, rtx nextarg
)
6972 if (EABI_FLOAT_VARARGS_P
)
6974 const CUMULATIVE_ARGS
*cum
;
6975 tree f_ovfl
, f_gtop
, f_ftop
, f_goff
, f_foff
;
6976 tree ovfl
, gtop
, ftop
, goff
, foff
;
6978 int gpr_save_area_size
;
6979 int fpr_save_area_size
;
6982 cum
= &crtl
->args
.info
;
6984 = (MAX_ARGS_IN_REGISTERS
- cum
->num_gprs
) * UNITS_PER_WORD
;
6986 = (MAX_ARGS_IN_REGISTERS
- cum
->num_fprs
) * UNITS_PER_FPREG
;
6988 f_ovfl
= TYPE_FIELDS (va_list_type_node
);
6989 f_gtop
= DECL_CHAIN (f_ovfl
);
6990 f_ftop
= DECL_CHAIN (f_gtop
);
6991 f_goff
= DECL_CHAIN (f_ftop
);
6992 f_foff
= DECL_CHAIN (f_goff
);
6994 ovfl
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovfl
), valist
, f_ovfl
,
6996 gtop
= build3 (COMPONENT_REF
, TREE_TYPE (f_gtop
), valist
, f_gtop
,
6998 ftop
= build3 (COMPONENT_REF
, TREE_TYPE (f_ftop
), valist
, f_ftop
,
7000 goff
= build3 (COMPONENT_REF
, TREE_TYPE (f_goff
), valist
, f_goff
,
7002 foff
= build3 (COMPONENT_REF
, TREE_TYPE (f_foff
), valist
, f_foff
,
7005 /* Emit code to initialize OVFL, which points to the next varargs
7006 stack argument. CUM->STACK_WORDS gives the number of stack
7007 words used by named arguments. */
7008 t
= make_tree (TREE_TYPE (ovfl
), virtual_incoming_args_rtx
);
7009 if (cum
->stack_words
> 0)
7010 t
= fold_build_pointer_plus_hwi (t
, cum
->stack_words
* UNITS_PER_WORD
);
7011 t
= build2 (MODIFY_EXPR
, TREE_TYPE (ovfl
), ovfl
, t
);
7012 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
7014 /* Emit code to initialize GTOP, the top of the GPR save area. */
7015 t
= make_tree (TREE_TYPE (gtop
), virtual_incoming_args_rtx
);
7016 t
= build2 (MODIFY_EXPR
, TREE_TYPE (gtop
), gtop
, t
);
7017 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
7019 /* Emit code to initialize FTOP, the top of the FPR save area.
7020 This address is gpr_save_area_bytes below GTOP, rounded
7021 down to the next fp-aligned boundary. */
7022 t
= make_tree (TREE_TYPE (ftop
), virtual_incoming_args_rtx
);
7023 fpr_offset
= gpr_save_area_size
+ UNITS_PER_FPVALUE
- 1;
7024 fpr_offset
&= -UNITS_PER_FPVALUE
;
7026 t
= fold_build_pointer_plus_hwi (t
, -fpr_offset
);
7027 t
= build2 (MODIFY_EXPR
, TREE_TYPE (ftop
), ftop
, t
);
7028 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
7030 /* Emit code to initialize GOFF, the offset from GTOP of the
7031 next GPR argument. */
7032 t
= build2 (MODIFY_EXPR
, TREE_TYPE (goff
), goff
,
7033 build_int_cst (TREE_TYPE (goff
), gpr_save_area_size
));
7034 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
7036 /* Likewise emit code to initialize FOFF, the offset from FTOP
7037 of the next FPR argument. */
7038 t
= build2 (MODIFY_EXPR
, TREE_TYPE (foff
), foff
,
7039 build_int_cst (TREE_TYPE (foff
), fpr_save_area_size
));
7040 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
7044 nextarg
= plus_constant (Pmode
, nextarg
, -cfun
->machine
->varargs_size
);
7045 std_expand_builtin_va_start (valist
, nextarg
);
7049 /* Like std_gimplify_va_arg_expr, but apply alignment to zero-sized
7053 mips_std_gimplify_va_arg_expr (tree valist
, tree type
, gimple_seq
*pre_p
,
7056 tree addr
, t
, type_size
, rounded_size
, valist_tmp
;
7057 unsigned HOST_WIDE_INT align
, boundary
;
7060 indirect
= pass_va_arg_by_reference (type
);
7062 type
= build_pointer_type (type
);
7064 align
= PARM_BOUNDARY
/ BITS_PER_UNIT
;
7065 boundary
= targetm
.calls
.function_arg_boundary (TYPE_MODE (type
), type
);
7067 /* When we align parameter on stack for caller, if the parameter
7068 alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
7069 aligned at MAX_SUPPORTED_STACK_ALIGNMENT. We will match callee
7070 here with caller. */
7071 if (boundary
> MAX_SUPPORTED_STACK_ALIGNMENT
)
7072 boundary
= MAX_SUPPORTED_STACK_ALIGNMENT
;
7074 boundary
/= BITS_PER_UNIT
;
7076 /* Hoist the valist value into a temporary for the moment. */
7077 valist_tmp
= get_initialized_tmp_var (valist
, pre_p
, NULL
);
7079 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
7080 requires greater alignment, we must perform dynamic alignment. */
7081 if (boundary
> align
)
7083 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
7084 fold_build_pointer_plus_hwi (valist_tmp
, boundary
- 1));
7085 gimplify_and_add (t
, pre_p
);
7087 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
7088 fold_build2 (BIT_AND_EXPR
, TREE_TYPE (valist
),
7090 build_int_cst (TREE_TYPE (valist
), -boundary
)));
7091 gimplify_and_add (t
, pre_p
);
7096 /* If the actual alignment is less than the alignment of the type,
7097 adjust the type accordingly so that we don't assume strict alignment
7098 when dereferencing the pointer. */
7099 boundary
*= BITS_PER_UNIT
;
7100 if (boundary
< TYPE_ALIGN (type
))
7102 type
= build_variant_type_copy (type
);
7103 SET_TYPE_ALIGN (type
, boundary
);
7106 /* Compute the rounded size of the type. */
7107 type_size
= size_in_bytes (type
);
7108 rounded_size
= round_up (type_size
, align
);
7110 /* Reduce rounded_size so it's sharable with the postqueue. */
7111 gimplify_expr (&rounded_size
, pre_p
, post_p
, is_gimple_val
, fb_rvalue
);
7115 if (PAD_VARARGS_DOWN
&& !integer_zerop (rounded_size
))
7117 /* Small args are padded downward. */
7118 t
= fold_build2_loc (input_location
, GT_EXPR
, sizetype
,
7119 rounded_size
, size_int (align
));
7120 t
= fold_build3 (COND_EXPR
, sizetype
, t
, size_zero_node
,
7121 size_binop (MINUS_EXPR
, rounded_size
, type_size
));
7122 addr
= fold_build_pointer_plus (addr
, t
);
7125 /* Compute new value for AP. */
7126 t
= fold_build_pointer_plus (valist_tmp
, rounded_size
);
7127 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist
, t
);
7128 gimplify_and_add (t
, pre_p
);
7130 addr
= fold_convert (build_pointer_type (type
), addr
);
7133 addr
= build_va_arg_indirect_ref (addr
);
7135 return build_va_arg_indirect_ref (addr
);
7138 /* Implement TARGET_GIMPLIFY_VA_ARG_EXPR. */
7141 mips_gimplify_va_arg_expr (tree valist
, tree type
, gimple_seq
*pre_p
,
7147 indirect_p
= pass_va_arg_by_reference (type
);
7149 type
= build_pointer_type (type
);
7151 if (!EABI_FLOAT_VARARGS_P
)
7152 addr
= mips_std_gimplify_va_arg_expr (valist
, type
, pre_p
, post_p
);
7155 tree f_ovfl
, f_gtop
, f_ftop
, f_goff
, f_foff
;
7156 tree ovfl
, top
, off
, align
;
7157 HOST_WIDE_INT size
, rsize
, osize
;
7160 f_ovfl
= TYPE_FIELDS (va_list_type_node
);
7161 f_gtop
= DECL_CHAIN (f_ovfl
);
7162 f_ftop
= DECL_CHAIN (f_gtop
);
7163 f_goff
= DECL_CHAIN (f_ftop
);
7164 f_foff
= DECL_CHAIN (f_goff
);
7168 TOP be the top of the GPR or FPR save area;
7169 OFF be the offset from TOP of the next register;
7170 ADDR_RTX be the address of the argument;
7171 SIZE be the number of bytes in the argument type;
7172 RSIZE be the number of bytes used to store the argument
7173 when it's in the register save area; and
7174 OSIZE be the number of bytes used to store it when it's
7175 in the stack overflow area.
7177 The code we want is:
7179 1: off &= -rsize; // round down
7182 4: addr_rtx = top - off + (BYTES_BIG_ENDIAN ? RSIZE - SIZE : 0);
7187 9: ovfl = ((intptr_t) ovfl + osize - 1) & -osize;
7188 10: addr_rtx = ovfl + (BYTES_BIG_ENDIAN ? OSIZE - SIZE : 0);
7192 [1] and [9] can sometimes be optimized away. */
7194 ovfl
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovfl
), valist
, f_ovfl
,
7196 size
= int_size_in_bytes (type
);
7198 if (GET_MODE_CLASS (TYPE_MODE (type
)) == MODE_FLOAT
7199 && GET_MODE_SIZE (TYPE_MODE (type
)) <= UNITS_PER_FPVALUE
)
7201 top
= build3 (COMPONENT_REF
, TREE_TYPE (f_ftop
),
7202 unshare_expr (valist
), f_ftop
, NULL_TREE
);
7203 off
= build3 (COMPONENT_REF
, TREE_TYPE (f_foff
),
7204 unshare_expr (valist
), f_foff
, NULL_TREE
);
7206 /* When va_start saves FPR arguments to the stack, each slot
7207 takes up UNITS_PER_HWFPVALUE bytes, regardless of the
7208 argument's precision. */
7209 rsize
= UNITS_PER_HWFPVALUE
;
7211 /* Overflow arguments are padded to UNITS_PER_WORD bytes
7212 (= PARM_BOUNDARY bits). This can be different from RSIZE
7215 (1) On 32-bit targets when TYPE is a structure such as:
7217 struct s { float f; };
7219 Such structures are passed in paired FPRs, so RSIZE
7220 will be 8 bytes. However, the structure only takes
7221 up 4 bytes of memory, so OSIZE will only be 4.
7223 (2) In combinations such as -mgp64 -msingle-float
7224 -fshort-double. Doubles passed in registers will then take
7225 up 4 (UNITS_PER_HWFPVALUE) bytes, but those passed on the
7226 stack take up UNITS_PER_WORD bytes. */
7227 osize
= MAX (GET_MODE_SIZE (TYPE_MODE (type
)), UNITS_PER_WORD
);
7231 top
= build3 (COMPONENT_REF
, TREE_TYPE (f_gtop
),
7232 unshare_expr (valist
), f_gtop
, NULL_TREE
);
7233 off
= build3 (COMPONENT_REF
, TREE_TYPE (f_goff
),
7234 unshare_expr (valist
), f_goff
, NULL_TREE
);
7235 rsize
= ROUND_UP (size
, UNITS_PER_WORD
);
7236 if (rsize
> UNITS_PER_WORD
)
7238 /* [1] Emit code for: off &= -rsize. */
7239 t
= build2 (BIT_AND_EXPR
, TREE_TYPE (off
), unshare_expr (off
),
7240 build_int_cst (TREE_TYPE (off
), -rsize
));
7241 gimplify_assign (unshare_expr (off
), t
, pre_p
);
7246 /* [2] Emit code to branch if off == 0. */
7247 t
= build2 (NE_EXPR
, boolean_type_node
, unshare_expr (off
),
7248 build_int_cst (TREE_TYPE (off
), 0));
7249 addr
= build3 (COND_EXPR
, ptr_type_node
, t
, NULL_TREE
, NULL_TREE
);
7251 /* [5] Emit code for: off -= rsize. We do this as a form of
7252 post-decrement not available to C. */
7253 t
= fold_convert (TREE_TYPE (off
), build_int_cst (NULL_TREE
, rsize
));
7254 t
= build2 (POSTDECREMENT_EXPR
, TREE_TYPE (off
), off
, t
);
7256 /* [4] Emit code for:
7257 addr_rtx = top - off + (BYTES_BIG_ENDIAN ? RSIZE - SIZE : 0). */
7258 t
= fold_convert (sizetype
, t
);
7259 t
= fold_build1 (NEGATE_EXPR
, sizetype
, t
);
7260 t
= fold_build_pointer_plus (top
, t
);
7261 if (BYTES_BIG_ENDIAN
&& rsize
> size
)
7262 t
= fold_build_pointer_plus_hwi (t
, rsize
- size
);
7263 COND_EXPR_THEN (addr
) = t
;
7265 if (osize
> UNITS_PER_WORD
)
7267 /* [9] Emit: ovfl = ((intptr_t) ovfl + osize - 1) & -osize. */
7268 t
= fold_build_pointer_plus_hwi (unshare_expr (ovfl
), osize
- 1);
7269 u
= build_int_cst (TREE_TYPE (t
), -osize
);
7270 t
= build2 (BIT_AND_EXPR
, TREE_TYPE (t
), t
, u
);
7271 align
= build2 (MODIFY_EXPR
, TREE_TYPE (ovfl
),
7272 unshare_expr (ovfl
), t
);
7277 /* [10, 11] Emit code for:
7278 addr_rtx = ovfl + (BYTES_BIG_ENDIAN ? OSIZE - SIZE : 0)
7280 u
= fold_convert (TREE_TYPE (ovfl
), build_int_cst (NULL_TREE
, osize
));
7281 t
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (ovfl
), ovfl
, u
);
7282 if (BYTES_BIG_ENDIAN
&& osize
> size
)
7283 t
= fold_build_pointer_plus_hwi (t
, osize
- size
);
7285 /* String [9] and [10, 11] together. */
7287 t
= build2 (COMPOUND_EXPR
, TREE_TYPE (t
), align
, t
);
7288 COND_EXPR_ELSE (addr
) = t
;
7290 addr
= fold_convert (build_pointer_type (type
), addr
);
7291 addr
= build_va_arg_indirect_ref (addr
);
7295 addr
= build_va_arg_indirect_ref (addr
);
7300 /* Declare a unique, locally-binding function called NAME, then start
7304 mips_start_unique_function (const char *name
)
7308 decl
= build_decl (BUILTINS_LOCATION
, FUNCTION_DECL
,
7309 get_identifier (name
),
7310 build_function_type_list (void_type_node
, NULL_TREE
));
7311 DECL_RESULT (decl
) = build_decl (BUILTINS_LOCATION
, RESULT_DECL
,
7312 NULL_TREE
, void_type_node
);
7313 TREE_PUBLIC (decl
) = 1;
7314 TREE_STATIC (decl
) = 1;
7316 cgraph_node::create (decl
)->set_comdat_group (DECL_ASSEMBLER_NAME (decl
));
7318 targetm
.asm_out
.unique_section (decl
, 0);
7319 switch_to_section (get_named_section (decl
, NULL
, 0));
7321 targetm
.asm_out
.globalize_label (asm_out_file
, name
);
7322 fputs ("\t.hidden\t", asm_out_file
);
7323 assemble_name (asm_out_file
, name
);
7324 putc ('\n', asm_out_file
);
7329 /* Start a definition of function NAME. MIPS16_P indicates whether the
7330 function contains MIPS16 code. */
7333 mips_start_function_definition (const char *name
, bool mips16_p
, tree decl
)
7336 fprintf (asm_out_file
, "\t.set\tmips16\n");
7338 fprintf (asm_out_file
, "\t.set\tnomips16\n");
7340 if (TARGET_MICROMIPS
)
7341 fprintf (asm_out_file
, "\t.set\tmicromips\n");
7342 #ifdef HAVE_GAS_MICROMIPS
7344 fprintf (asm_out_file
, "\t.set\tnomicromips\n");
7347 if (!flag_inhibit_size_directive
)
7349 fputs ("\t.ent\t", asm_out_file
);
7350 assemble_name (asm_out_file
, name
);
7351 fputs ("\n", asm_out_file
);
7354 ASM_OUTPUT_TYPE_DIRECTIVE (asm_out_file
, name
, "function");
7356 /* Start the definition proper. */
7357 ASM_OUTPUT_FUNCTION_LABEL (asm_out_file
, name
, decl
);
7360 /* End a function definition started by mips_start_function_definition. */
7363 mips_end_function_definition (const char *name
)
7365 if (!flag_inhibit_size_directive
)
7367 fputs ("\t.end\t", asm_out_file
);
7368 assemble_name (asm_out_file
, name
);
7369 fputs ("\n", asm_out_file
);
7373 /* If *STUB_PTR points to a stub, output a comdat-style definition for it,
7374 then free *STUB_PTR. */
7377 mips_finish_stub (mips_one_only_stub
**stub_ptr
)
7379 mips_one_only_stub
*stub
= *stub_ptr
;
7383 const char *name
= stub
->get_name ();
7384 tree decl
= mips_start_unique_function (name
);
7385 mips_start_function_definition (name
, false, decl
);
7386 stub
->output_body ();
7387 mips_end_function_definition (name
);
7392 /* Return true if calls to X can use R_MIPS_CALL* relocations. */
7395 mips_ok_for_lazy_binding_p (rtx x
)
7397 return (TARGET_USE_GOT
7398 && GET_CODE (x
) == SYMBOL_REF
7399 && !SYMBOL_REF_BIND_NOW_P (x
)
7400 && !mips_symbol_binds_local_p (x
));
7403 /* Load function address ADDR into register DEST. TYPE is as for
7404 mips_expand_call. Return true if we used an explicit lazy-binding
7408 mips_load_call_address (enum mips_call_type type
, rtx dest
, rtx addr
)
7410 /* If we're generating PIC, and this call is to a global function,
7411 try to allow its address to be resolved lazily. This isn't
7412 possible for sibcalls when $gp is call-saved because the value
7413 of $gp on entry to the stub would be our caller's gp, not ours. */
7414 if (TARGET_EXPLICIT_RELOCS
7415 && !(type
== MIPS_CALL_SIBCALL
&& TARGET_CALL_SAVED_GP
)
7416 && mips_ok_for_lazy_binding_p (addr
))
7418 addr
= mips_got_load (dest
, addr
, SYMBOL_GOTOFF_CALL
);
7419 emit_insn (gen_rtx_SET (dest
, addr
));
7424 mips_emit_move (dest
, addr
);
7429 /* Each locally-defined hard-float MIPS16 function has a local symbol
7430 associated with it. This hash table maps the function symbol (FUNC)
7431 to the local symbol (LOCAL). */
7432 static GTY (()) hash_map
<nofree_string_hash
, rtx
> *mips16_local_aliases
;
7434 /* FUNC is the symbol for a locally-defined hard-float MIPS16 function.
7435 Return a local alias for it, creating a new one if necessary. */
7438 mips16_local_alias (rtx func
)
7440 /* Create the hash table if this is the first call. */
7441 if (mips16_local_aliases
== NULL
)
7442 mips16_local_aliases
= hash_map
<nofree_string_hash
, rtx
>::create_ggc (37);
7444 /* Look up the function symbol, creating a new entry if need be. */
7446 const char *func_name
= XSTR (func
, 0);
7447 rtx
*slot
= &mips16_local_aliases
->get_or_insert (func_name
, &existed
);
7448 gcc_assert (slot
!= NULL
);
7454 /* Create a new SYMBOL_REF for the local symbol. The choice of
7455 __fn_local_* is based on the __fn_stub_* names that we've
7456 traditionally used for the non-MIPS16 stub. */
7457 func_name
= targetm
.strip_name_encoding (XSTR (func
, 0));
7458 const char *local_name
= ACONCAT (("__fn_local_", func_name
, NULL
));
7459 local
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (local_name
));
7460 SYMBOL_REF_FLAGS (local
) = SYMBOL_REF_FLAGS (func
) | SYMBOL_FLAG_LOCAL
;
7462 /* Create a new structure to represent the mapping. */
7468 /* A chained list of functions for which mips16_build_call_stub has already
7469 generated a stub. NAME is the name of the function and FP_RET_P is true
7470 if the function returns a value in floating-point registers. */
7471 struct mips16_stub
{
7472 struct mips16_stub
*next
;
7476 static struct mips16_stub
*mips16_stubs
;
7478 /* Return the two-character string that identifies floating-point
7479 return mode MODE in the name of a MIPS16 function stub. */
7482 mips16_call_stub_mode_suffix (machine_mode mode
)
7486 else if (mode
== DFmode
)
7488 else if (mode
== SCmode
)
7490 else if (mode
== DCmode
)
7492 else if (mode
== V2SFmode
)
7494 gcc_assert (TARGET_PAIRED_SINGLE_FLOAT
);
7501 /* Write instructions to move a 32-bit value between general register
7502 GPREG and floating-point register FPREG. DIRECTION is 't' to move
7503 from GPREG to FPREG and 'f' to move in the opposite direction. */
7506 mips_output_32bit_xfer (char direction
, unsigned int gpreg
, unsigned int fpreg
)
7508 fprintf (asm_out_file
, "\tm%cc1\t%s,%s\n", direction
,
7509 reg_names
[gpreg
], reg_names
[fpreg
]);
7512 /* Likewise for 64-bit values. */
7515 mips_output_64bit_xfer (char direction
, unsigned int gpreg
, unsigned int fpreg
)
7518 fprintf (asm_out_file
, "\tdm%cc1\t%s,%s\n", direction
,
7519 reg_names
[gpreg
], reg_names
[fpreg
]);
7520 else if (ISA_HAS_MXHC1
)
7522 fprintf (asm_out_file
, "\tm%cc1\t%s,%s\n", direction
,
7523 reg_names
[gpreg
+ TARGET_BIG_ENDIAN
], reg_names
[fpreg
]);
7524 fprintf (asm_out_file
, "\tm%chc1\t%s,%s\n", direction
,
7525 reg_names
[gpreg
+ TARGET_LITTLE_ENDIAN
], reg_names
[fpreg
]);
7527 else if (TARGET_FLOATXX
&& direction
== 't')
7529 /* Use the argument save area to move via memory. */
7530 fprintf (asm_out_file
, "\tsw\t%s,0($sp)\n", reg_names
[gpreg
]);
7531 fprintf (asm_out_file
, "\tsw\t%s,4($sp)\n", reg_names
[gpreg
+ 1]);
7532 fprintf (asm_out_file
, "\tldc1\t%s,0($sp)\n", reg_names
[fpreg
]);
7534 else if (TARGET_FLOATXX
&& direction
== 'f')
7536 /* Use the argument save area to move via memory. */
7537 fprintf (asm_out_file
, "\tsdc1\t%s,0($sp)\n", reg_names
[fpreg
]);
7538 fprintf (asm_out_file
, "\tlw\t%s,0($sp)\n", reg_names
[gpreg
]);
7539 fprintf (asm_out_file
, "\tlw\t%s,4($sp)\n", reg_names
[gpreg
+ 1]);
7543 /* Move the least-significant word. */
7544 fprintf (asm_out_file
, "\tm%cc1\t%s,%s\n", direction
,
7545 reg_names
[gpreg
+ TARGET_BIG_ENDIAN
], reg_names
[fpreg
]);
7546 /* ...then the most significant word. */
7547 fprintf (asm_out_file
, "\tm%cc1\t%s,%s\n", direction
,
7548 reg_names
[gpreg
+ TARGET_LITTLE_ENDIAN
], reg_names
[fpreg
+ 1]);
7552 /* Write out code to move floating-point arguments into or out of
7553 general registers. FP_CODE is the code describing which arguments
7554 are present (see the comment above the definition of CUMULATIVE_ARGS
7555 in mips.h). DIRECTION is as for mips_output_32bit_xfer. */
7558 mips_output_args_xfer (int fp_code
, char direction
)
7560 unsigned int gparg
, fparg
, f
;
7561 CUMULATIVE_ARGS cum
;
7563 /* This code only works for o32 and o64. */
7564 gcc_assert (TARGET_OLDABI
);
7566 mips_init_cumulative_args (&cum
, NULL
);
7568 for (f
= (unsigned int) fp_code
; f
!= 0; f
>>= 2)
7571 struct mips_arg_info info
;
7575 else if ((f
& 3) == 2)
7580 mips_get_arg_info (&info
, &cum
, mode
, NULL
, true);
7581 gparg
= mips_arg_regno (&info
, false);
7582 fparg
= mips_arg_regno (&info
, true);
7585 mips_output_32bit_xfer (direction
, gparg
, fparg
);
7587 mips_output_64bit_xfer (direction
, gparg
, fparg
);
7589 function_arg_info
arg (mode
, /*named=*/true);
7590 mips_function_arg_advance (pack_cumulative_args (&cum
), arg
);
7594 /* Write a MIPS16 stub for the current function. This stub is used
7595 for functions which take arguments in the floating-point registers.
7596 It is normal-mode code that moves the floating-point arguments
7597 into the general registers and then jumps to the MIPS16 code. */
7600 mips16_build_function_stub (void)
7602 const char *fnname
, *alias_name
, *separator
;
7603 char *secname
, *stubname
;
7608 /* Create the name of the stub, and its unique section. */
7609 symbol
= XEXP (DECL_RTL (current_function_decl
), 0);
7610 alias
= mips16_local_alias (symbol
);
7612 fnname
= targetm
.strip_name_encoding (XSTR (symbol
, 0));
7613 alias_name
= targetm
.strip_name_encoding (XSTR (alias
, 0));
7614 secname
= ACONCAT ((".mips16.fn.", fnname
, NULL
));
7615 stubname
= ACONCAT (("__fn_stub_", fnname
, NULL
));
7617 /* Build a decl for the stub. */
7618 stubdecl
= build_decl (BUILTINS_LOCATION
,
7619 FUNCTION_DECL
, get_identifier (stubname
),
7620 build_function_type_list (void_type_node
, NULL_TREE
));
7621 set_decl_section_name (stubdecl
, secname
);
7622 DECL_RESULT (stubdecl
) = build_decl (BUILTINS_LOCATION
,
7623 RESULT_DECL
, NULL_TREE
, void_type_node
);
7625 /* Output a comment. */
7626 fprintf (asm_out_file
, "\t# Stub function for %s (",
7627 current_function_name ());
7629 for (f
= (unsigned int) crtl
->args
.info
.fp_code
; f
!= 0; f
>>= 2)
7631 fprintf (asm_out_file
, "%s%s", separator
,
7632 (f
& 3) == 1 ? "float" : "double");
7635 fprintf (asm_out_file
, ")\n");
7637 /* Start the function definition. */
7638 assemble_start_function (stubdecl
, stubname
);
7639 mips_start_function_definition (stubname
, false, stubdecl
);
7641 /* If generating pic2 code, either set up the global pointer or
7643 if (TARGET_ABICALLS_PIC2
)
7645 if (TARGET_ABSOLUTE_ABICALLS
)
7646 fprintf (asm_out_file
, "\t.option\tpic0\n");
7649 output_asm_insn ("%(.cpload\t%^%)", NULL
);
7650 /* Emit an R_MIPS_NONE relocation to tell the linker what the
7651 target function is. Use a local GOT access when loading the
7652 symbol, to cut down on the number of unnecessary GOT entries
7653 for stubs that aren't needed. */
7654 output_asm_insn (".reloc\t0,R_MIPS_NONE,%0", &symbol
);
7659 /* Load the address of the MIPS16 function into $25. Do this first so
7660 that targets with coprocessor interlocks can use an MFC1 to fill the
7662 output_asm_insn ("la\t%^,%0", &symbol
);
7664 /* Move the arguments from floating-point registers to general registers. */
7665 mips_output_args_xfer (crtl
->args
.info
.fp_code
, 'f');
7667 /* Jump to the MIPS16 function. */
7668 output_asm_insn ("jr\t%^", NULL
);
7670 if (TARGET_ABICALLS_PIC2
&& TARGET_ABSOLUTE_ABICALLS
)
7671 fprintf (asm_out_file
, "\t.option\tpic2\n");
7673 mips_end_function_definition (stubname
);
7675 /* If the linker needs to create a dynamic symbol for the target
7676 function, it will associate the symbol with the stub (which,
7677 unlike the target function, follows the proper calling conventions).
7678 It is therefore useful to have a local alias for the target function,
7679 so that it can still be identified as MIPS16 code. As an optimization,
7680 this symbol can also be used for indirect MIPS16 references from
7681 within this file. */
7682 ASM_OUTPUT_DEF (asm_out_file
, alias_name
, fnname
);
7684 switch_to_section (function_section (current_function_decl
));
7687 /* The current function is a MIPS16 function that returns a value in an FPR.
7688 Copy the return value from its soft-float to its hard-float location.
7689 libgcc2 has special non-MIPS16 helper functions for each case. */
7692 mips16_copy_fpr_return_value (void)
7694 rtx fn
, insn
, retval
;
7696 machine_mode return_mode
;
7699 return_type
= DECL_RESULT (current_function_decl
);
7700 return_mode
= DECL_MODE (return_type
);
7702 name
= ACONCAT (("__mips16_ret_",
7703 mips16_call_stub_mode_suffix (return_mode
),
7705 fn
= mips16_stub_function (name
);
7707 /* The function takes arguments in $2 (and possibly $3), so calls
7708 to it cannot be lazily bound. */
7709 SYMBOL_REF_FLAGS (fn
) |= SYMBOL_FLAG_BIND_NOW
;
7711 /* Model the call as something that takes the GPR return value as
7712 argument and returns an "updated" value. */
7713 retval
= gen_rtx_REG (return_mode
, GP_RETURN
);
7714 insn
= mips_expand_call (MIPS_CALL_EPILOGUE
, retval
, fn
,
7715 const0_rtx
, NULL_RTX
, false);
7716 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), retval
);
7719 /* Consider building a stub for a MIPS16 call to function *FN_PTR.
7720 RETVAL is the location of the return value, or null if this is
7721 a "call" rather than a "call_value". ARGS_SIZE is the size of the
7722 arguments and FP_CODE is the code built by mips_function_arg;
7723 see the comment before the fp_code field in CUMULATIVE_ARGS for details.
7725 There are three alternatives:
7727 - If a stub was needed, emit the call and return the call insn itself.
7729 - If we can avoid using a stub by redirecting the call, set *FN_PTR
7730 to the new target and return null.
7732 - If *FN_PTR doesn't need a stub, return null and leave *FN_PTR
7735 A stub is needed for calls to functions that, in normal mode,
7736 receive arguments in FPRs or return values in FPRs. The stub
7737 copies the arguments from their soft-float positions to their
7738 hard-float positions, calls the real function, then copies the
7739 return value from its hard-float position to its soft-float
7742 We can emit a JAL to *FN_PTR even when *FN_PTR might need a stub.
7743 If *FN_PTR turns out to be to a non-MIPS16 function, the linker
7744 automatically redirects the JAL to the stub, otherwise the JAL
7745 continues to call FN directly. */
7748 mips16_build_call_stub (rtx retval
, rtx
*fn_ptr
, rtx args_size
, int fp_code
)
7752 struct mips16_stub
*l
;
7756 /* We don't need to do anything if we aren't in MIPS16 mode, or if
7757 we were invoked with the -msoft-float option. */
7758 if (!TARGET_MIPS16
|| TARGET_SOFT_FLOAT_ABI
)
7761 /* Figure out whether the value might come back in a floating-point
7763 fp_ret_p
= retval
&& mips_return_mode_in_fpr_p (GET_MODE (retval
));
7765 /* We don't need to do anything if there were no floating-point
7766 arguments and the value will not be returned in a floating-point
7768 if (fp_code
== 0 && !fp_ret_p
)
7771 /* We don't need to do anything if this is a call to a special
7772 MIPS16 support function. */
7774 if (mips16_stub_function_p (fn
))
7777 /* If we're calling a locally-defined MIPS16 function, we know that
7778 it will return values in both the "soft-float" and "hard-float"
7779 registers. There is no need to use a stub to move the latter
7781 if (fp_code
== 0 && mips16_local_function_p (fn
))
7784 /* This code will only work for o32 and o64 abis. The other ABI's
7785 require more sophisticated support. */
7786 gcc_assert (TARGET_OLDABI
);
7788 /* If we're calling via a function pointer, use one of the magic
7789 libgcc.a stubs provided for each (FP_CODE, FP_RET_P) combination.
7790 Each stub expects the function address to arrive in register $2. */
7791 if (GET_CODE (fn
) != SYMBOL_REF
7792 || !call_insn_operand (fn
, VOIDmode
))
7799 /* If this is a locally-defined and locally-binding function,
7800 avoid the stub by calling the local alias directly. */
7801 if (mips16_local_function_p (fn
))
7803 *fn_ptr
= mips16_local_alias (fn
);
7807 /* Create a SYMBOL_REF for the libgcc.a function. */
7809 sprintf (buf
, "__mips16_call_stub_%s_%d",
7810 mips16_call_stub_mode_suffix (GET_MODE (retval
)),
7813 sprintf (buf
, "__mips16_call_stub_%d", fp_code
);
7814 stub_fn
= mips16_stub_function (buf
);
7816 /* The function uses $2 as an argument, so calls to it
7817 cannot be lazily bound. */
7818 SYMBOL_REF_FLAGS (stub_fn
) |= SYMBOL_FLAG_BIND_NOW
;
7820 /* Load the target function into $2. */
7821 addr
= gen_rtx_REG (Pmode
, GP_REG_FIRST
+ 2);
7822 lazy_p
= mips_load_call_address (MIPS_CALL_NORMAL
, addr
, fn
);
7824 /* Emit the call. */
7825 insn
= mips_expand_call (MIPS_CALL_NORMAL
, retval
, stub_fn
,
7826 args_size
, NULL_RTX
, lazy_p
);
7828 /* Tell GCC that this call does indeed use the value of $2. */
7829 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), addr
);
7831 /* If we are handling a floating-point return value, we need to
7832 save $18 in the function prologue. Putting a note on the
7833 call will mean that df_regs_ever_live_p ($18) will be true if the
7834 call is not eliminated, and we can check that in the prologue
7837 CALL_INSN_FUNCTION_USAGE (insn
) =
7838 gen_rtx_EXPR_LIST (VOIDmode
,
7839 gen_rtx_CLOBBER (VOIDmode
,
7840 gen_rtx_REG (word_mode
, 18)),
7841 CALL_INSN_FUNCTION_USAGE (insn
));
7846 /* We know the function we are going to call. If we have already
7847 built a stub, we don't need to do anything further. */
7848 fnname
= targetm
.strip_name_encoding (XSTR (fn
, 0));
7849 for (l
= mips16_stubs
; l
!= NULL
; l
= l
->next
)
7850 if (strcmp (l
->name
, fnname
) == 0)
7855 const char *separator
;
7856 char *secname
, *stubname
;
7857 tree stubid
, stubdecl
;
7860 /* If the function does not return in FPRs, the special stub
7864 If the function does return in FPRs, the stub section is named
7865 .mips16.call.fp.FNNAME
7867 Build a decl for the stub. */
7868 secname
= ACONCAT ((".mips16.call.", fp_ret_p
? "fp." : "",
7870 stubname
= ACONCAT (("__call_stub_", fp_ret_p
? "fp_" : "",
7872 stubid
= get_identifier (stubname
);
7873 stubdecl
= build_decl (BUILTINS_LOCATION
,
7874 FUNCTION_DECL
, stubid
,
7875 build_function_type_list (void_type_node
,
7877 set_decl_section_name (stubdecl
, secname
);
7878 DECL_RESULT (stubdecl
) = build_decl (BUILTINS_LOCATION
,
7879 RESULT_DECL
, NULL_TREE
,
7882 /* Output a comment. */
7883 fprintf (asm_out_file
, "\t# Stub function to call %s%s (",
7885 ? (GET_MODE (retval
) == SFmode
? "float " : "double ")
7889 for (f
= (unsigned int) fp_code
; f
!= 0; f
>>= 2)
7891 fprintf (asm_out_file
, "%s%s", separator
,
7892 (f
& 3) == 1 ? "float" : "double");
7895 fprintf (asm_out_file
, ")\n");
7897 /* Start the function definition. */
7898 assemble_start_function (stubdecl
, stubname
);
7899 mips_start_function_definition (stubname
, false, stubdecl
);
7903 fprintf (asm_out_file
, "\t.cfi_startproc\n");
7905 /* Create a fake CFA 4 bytes below the stack pointer.
7906 This works around unwinders (like libgcc's) that expect
7907 the CFA for non-signal frames to be unique. */
7908 fprintf (asm_out_file
, "\t.cfi_def_cfa 29,-4\n");
7910 /* "Save" $sp in itself so we don't use the fake CFA.
7911 This is: DW_CFA_val_expression r29, { DW_OP_reg29 }. */
7912 fprintf (asm_out_file
, "\t.cfi_escape 0x16,29,1,0x6d\n");
7914 /* Save the return address in $18. The stub's caller knows
7915 that $18 might be clobbered, even though $18 is usually
7916 a call-saved register.
7918 Do it early on in case the last move to a floating-point
7919 register can be scheduled into the delay slot of the
7920 call we are about to make. */
7921 fprintf (asm_out_file
, "\tmove\t%s,%s\n",
7922 reg_names
[GP_REG_FIRST
+ 18],
7923 reg_names
[RETURN_ADDR_REGNUM
]);
7927 /* Load the address of the MIPS16 function into $25. Do this
7928 first so that targets with coprocessor interlocks can use
7929 an MFC1 to fill the delay slot. */
7930 if (TARGET_EXPLICIT_RELOCS
)
7932 output_asm_insn ("lui\t%^,%%hi(%0)", &fn
);
7933 output_asm_insn ("addiu\t%^,%^,%%lo(%0)", &fn
);
7936 output_asm_insn ("la\t%^,%0", &fn
);
7939 /* Move the arguments from general registers to floating-point
7941 mips_output_args_xfer (fp_code
, 't');
7945 /* Now call the non-MIPS16 function. */
7946 output_asm_insn (mips_output_jump (&fn
, 0, -1, true), &fn
);
7947 fprintf (asm_out_file
, "\t.cfi_register 31,18\n");
7949 /* Move the result from floating-point registers to
7950 general registers. */
7951 switch (GET_MODE (retval
))
7954 mips_output_32bit_xfer ('f', GP_RETURN
+ TARGET_BIG_ENDIAN
,
7958 mips_output_32bit_xfer ('f', GP_RETURN
+ TARGET_LITTLE_ENDIAN
,
7959 TARGET_LITTLE_ENDIAN
7962 if (GET_MODE (retval
) == SCmode
&& TARGET_64BIT
)
7964 /* On 64-bit targets, complex floats are returned in
7965 a single GPR, such that "sd" on a suitably-aligned
7966 target would store the value correctly. */
7967 fprintf (asm_out_file
, "\tdsll\t%s,%s,32\n",
7968 reg_names
[GP_RETURN
+ TARGET_BIG_ENDIAN
],
7969 reg_names
[GP_RETURN
+ TARGET_BIG_ENDIAN
]);
7970 fprintf (asm_out_file
, "\tdsll\t%s,%s,32\n",
7971 reg_names
[GP_RETURN
+ TARGET_LITTLE_ENDIAN
],
7972 reg_names
[GP_RETURN
+ TARGET_LITTLE_ENDIAN
]);
7973 fprintf (asm_out_file
, "\tdsrl\t%s,%s,32\n",
7974 reg_names
[GP_RETURN
+ TARGET_BIG_ENDIAN
],
7975 reg_names
[GP_RETURN
+ TARGET_BIG_ENDIAN
]);
7976 fprintf (asm_out_file
, "\tor\t%s,%s,%s\n",
7977 reg_names
[GP_RETURN
],
7978 reg_names
[GP_RETURN
],
7979 reg_names
[GP_RETURN
+ 1]);
7984 mips_output_32bit_xfer ('f', GP_RETURN
, FP_REG_FIRST
);
7988 mips_output_64bit_xfer ('f', GP_RETURN
+ (8 / UNITS_PER_WORD
),
7993 gcc_assert (TARGET_PAIRED_SINGLE_FLOAT
7994 || GET_MODE (retval
) != V2SFmode
);
7995 mips_output_64bit_xfer ('f', GP_RETURN
, FP_REG_FIRST
);
8001 fprintf (asm_out_file
, "\tjr\t%s\n", reg_names
[GP_REG_FIRST
+ 18]);
8002 fprintf (asm_out_file
, "\t.cfi_endproc\n");
8006 /* Jump to the previously-loaded address. */
8007 output_asm_insn ("jr\t%^", NULL
);
8010 #ifdef ASM_DECLARE_FUNCTION_SIZE
8011 ASM_DECLARE_FUNCTION_SIZE (asm_out_file
, stubname
, stubdecl
);
8014 mips_end_function_definition (stubname
);
8016 /* Record this stub. */
8017 l
= XNEW (struct mips16_stub
);
8018 l
->name
= xstrdup (fnname
);
8019 l
->fp_ret_p
= fp_ret_p
;
8020 l
->next
= mips16_stubs
;
8024 /* If we expect a floating-point return value, but we've built a
8025 stub which does not expect one, then we're in trouble. We can't
8026 use the existing stub, because it won't handle the floating-point
8027 value. We can't build a new stub, because the linker won't know
8028 which stub to use for the various calls in this object file.
8029 Fortunately, this case is illegal, since it means that a function
8030 was declared in two different ways in a single compilation. */
8031 if (fp_ret_p
&& !l
->fp_ret_p
)
8032 error ("cannot handle inconsistent calls to %qs", fnname
);
8034 if (retval
== NULL_RTX
)
8035 pattern
= gen_call_internal_direct (fn
, args_size
);
8037 pattern
= gen_call_value_internal_direct (retval
, fn
, args_size
);
8038 insn
= mips_emit_call_insn (pattern
, fn
, fn
, false);
8040 /* If we are calling a stub which handles a floating-point return
8041 value, we need to arrange to save $18 in the prologue. We do this
8042 by marking the function call as using the register. The prologue
8043 will later see that it is used, and emit code to save it. */
8045 CALL_INSN_FUNCTION_USAGE (insn
) =
8046 gen_rtx_EXPR_LIST (VOIDmode
,
8047 gen_rtx_CLOBBER (VOIDmode
,
8048 gen_rtx_REG (word_mode
, 18)),
8049 CALL_INSN_FUNCTION_USAGE (insn
));
8054 /* Expand a call of type TYPE. RESULT is where the result will go (null
8055 for "call"s and "sibcall"s), ADDR is the address of the function,
8056 ARGS_SIZE is the size of the arguments and AUX is the value passed
8057 to us by mips_function_arg. LAZY_P is true if this call already
8058 involves a lazily-bound function address (such as when calling
8059 functions through a MIPS16 hard-float stub).
8061 Return the call itself. */
8064 mips_expand_call (enum mips_call_type type
, rtx result
, rtx addr
,
8065 rtx args_size
, rtx aux
, bool lazy_p
)
8067 rtx orig_addr
, pattern
;
8071 fp_code
= aux
== 0 ? 0 : (int) GET_MODE (aux
);
8072 insn
= mips16_build_call_stub (result
, &addr
, args_size
, fp_code
);
8075 gcc_assert (!lazy_p
&& type
== MIPS_CALL_NORMAL
);
8080 if (!call_insn_operand (addr
, VOIDmode
))
8082 if (type
== MIPS_CALL_EPILOGUE
)
8083 addr
= MIPS_EPILOGUE_TEMP (Pmode
);
8085 addr
= gen_reg_rtx (Pmode
);
8086 lazy_p
|= mips_load_call_address (type
, addr
, orig_addr
);
8091 rtx (*fn
) (rtx
, rtx
);
8093 if (type
== MIPS_CALL_SIBCALL
)
8094 fn
= gen_sibcall_internal
;
8096 fn
= gen_call_internal
;
8098 pattern
= fn (addr
, args_size
);
8100 else if (GET_CODE (result
) == PARALLEL
&& XVECLEN (result
, 0) == 2)
8102 /* Handle return values created by mips_return_fpr_pair. */
8103 rtx (*fn
) (rtx
, rtx
, rtx
, rtx
);
8106 if (type
== MIPS_CALL_SIBCALL
)
8107 fn
= gen_sibcall_value_multiple_internal
;
8109 fn
= gen_call_value_multiple_internal
;
8111 reg1
= XEXP (XVECEXP (result
, 0, 0), 0);
8112 reg2
= XEXP (XVECEXP (result
, 0, 1), 0);
8113 pattern
= fn (reg1
, addr
, args_size
, reg2
);
8117 rtx (*fn
) (rtx
, rtx
, rtx
);
8119 if (type
== MIPS_CALL_SIBCALL
)
8120 fn
= gen_sibcall_value_internal
;
8122 fn
= gen_call_value_internal
;
8124 /* Handle return values created by mips_return_fpr_single. */
8125 if (GET_CODE (result
) == PARALLEL
&& XVECLEN (result
, 0) == 1)
8126 result
= XEXP (XVECEXP (result
, 0, 0), 0);
8127 pattern
= fn (result
, addr
, args_size
);
8130 return mips_emit_call_insn (pattern
, orig_addr
, addr
, lazy_p
);
8133 /* Split call instruction INSN into a $gp-clobbering call and
8134 (where necessary) an instruction to restore $gp from its save slot.
8135 CALL_PATTERN is the pattern of the new call. */
8138 mips_split_call (rtx insn
, rtx call_pattern
)
8140 emit_call_insn (call_pattern
);
8141 if (!find_reg_note (insn
, REG_NORETURN
, 0))
8142 mips_restore_gp_from_cprestore_slot (gen_rtx_REG (Pmode
,
8143 POST_CALL_TMP_REG
));
8146 /* Return true if a call to DECL may need to use JALX. */
8149 mips_call_may_need_jalx_p (tree decl
)
8151 /* If the current translation unit would use a different mode for DECL,
8152 assume that the call needs JALX. */
8153 if (mips_get_compress_mode (decl
) != TARGET_COMPRESSION
)
8156 /* mips_get_compress_mode is always accurate for locally-binding
8157 functions in the current translation unit. */
8158 if (!DECL_EXTERNAL (decl
) && targetm
.binds_local_p (decl
))
8161 /* When -minterlink-compressed is in effect, assume that functions
8162 could use a different encoding mode unless an attribute explicitly
8163 tells us otherwise. */
8164 if (TARGET_INTERLINK_COMPRESSED
)
8166 if (!TARGET_COMPRESSION
8167 && mips_get_compress_off_flags (DECL_ATTRIBUTES (decl
)) ==0)
8169 if (TARGET_COMPRESSION
8170 && mips_get_compress_on_flags (DECL_ATTRIBUTES (decl
)) == 0)
8177 /* Implement TARGET_FUNCTION_OK_FOR_SIBCALL. */
8180 mips_function_ok_for_sibcall (tree decl
, tree exp ATTRIBUTE_UNUSED
)
8182 if (!TARGET_SIBCALLS
)
8185 /* Interrupt handlers need special epilogue code and therefore can't
8187 if (mips_interrupt_type_p (TREE_TYPE (current_function_decl
)))
8190 /* Direct Js are only possible to functions that use the same ISA encoding.
8191 There is no JX counterpoart of JALX. */
8193 && const_call_insn_operand (XEXP (DECL_RTL (decl
), 0), VOIDmode
)
8194 && mips_call_may_need_jalx_p (decl
))
8197 /* Sibling calls should not prevent lazy binding. Lazy-binding stubs
8198 require $gp to be valid on entry, so sibcalls can only use stubs
8199 if $gp is call-clobbered. */
8201 && TARGET_CALL_SAVED_GP
8202 && !TARGET_ABICALLS_PIC0
8203 && !targetm
.binds_local_p (decl
))
8210 /* Implement TARGET_USE_MOVE_BY_PIECES_INFRASTRUCTURE_P. */
8213 mips_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size
,
8215 enum by_pieces_operation op
,
8218 if (op
== STORE_BY_PIECES
)
8219 return mips_store_by_pieces_p (size
, align
);
8220 if (op
== MOVE_BY_PIECES
&& HAVE_cpymemsi
)
8222 /* cpymemsi is meant to generate code that is at least as good as
8223 move_by_pieces. However, cpymemsi effectively uses a by-pieces
8224 implementation both for moves smaller than a word and for
8225 word-aligned moves of no more than MIPS_MAX_MOVE_BYTES_STRAIGHT
8226 bytes. We should allow the tree-level optimisers to do such
8227 moves by pieces, as it often exposes other optimization
8228 opportunities. We might as well continue to use cpymemsi at
8229 the rtl level though, as it produces better code when
8230 scheduling is disabled (such as at -O). */
8231 if (currently_expanding_to_rtl
)
8233 if (align
< BITS_PER_WORD
)
8234 return size
< UNITS_PER_WORD
;
8235 return size
<= MIPS_MAX_MOVE_BYTES_STRAIGHT
;
8238 return default_use_by_pieces_infrastructure_p (size
, align
, op
, speed_p
);
8241 /* Implement a handler for STORE_BY_PIECES operations
8242 for TARGET_USE_MOVE_BY_PIECES_INFRASTRUCTURE_P. */
8245 mips_store_by_pieces_p (unsigned HOST_WIDE_INT size
, unsigned int align
)
8247 /* Storing by pieces involves moving constants into registers
8248 of size MIN (ALIGN, BITS_PER_WORD), then storing them.
8249 We need to decide whether it is cheaper to load the address of
8250 constant data into a register and use a block move instead. */
8252 /* If the data is only byte aligned, then:
8254 (a1) A block move of less than 4 bytes would involve three 3 LBs and
8255 3 SBs. We might as well use 3 single-instruction LIs and 3 SBs
8258 (a2) A block move of 4 bytes from aligned source data can use an
8259 LW/SWL/SWR sequence. This is often better than the 4 LIs and
8260 4 SBs that we would generate when storing by pieces. */
8261 if (align
<= BITS_PER_UNIT
)
8264 /* If the data is 2-byte aligned, then:
8266 (b1) A block move of less than 4 bytes would use a combination of LBs,
8267 LHs, SBs and SHs. We get better code by using single-instruction
8268 LIs, SBs and SHs instead.
8270 (b2) A block move of 4 bytes from aligned source data would again use
8271 an LW/SWL/SWR sequence. In most cases, loading the address of
8272 the source data would require at least one extra instruction.
8273 It is often more efficient to use 2 single-instruction LIs and
8276 (b3) A block move of up to 3 additional bytes would be like (b1).
8278 (b4) A block move of 8 bytes from aligned source data can use two
8279 LW/SWL/SWR sequences or a single LD/SDL/SDR sequence. Both
8280 sequences are better than the 4 LIs and 4 SHs that we'd generate
8281 when storing by pieces.
8283 The reasoning for higher alignments is similar:
8285 (c1) A block move of less than 4 bytes would be the same as (b1).
8287 (c2) A block move of 4 bytes would use an LW/SW sequence. Again,
8288 loading the address of the source data would typically require
8289 at least one extra instruction. It is generally better to use
8292 (c3) A block move of up to 3 additional bytes would be like (b1).
8294 (c4) A block move of 8 bytes can use two LW/SW sequences or a single
8295 LD/SD sequence, and in these cases we've traditionally preferred
8296 the memory copy over the more bulky constant moves. */
8300 /* Emit straight-line code to move LENGTH bytes from SRC to DEST.
8301 Assume that the areas do not overlap. */
8304 mips_block_move_straight (rtx dest
, rtx src
, HOST_WIDE_INT length
)
8306 HOST_WIDE_INT offset
, delta
;
8307 unsigned HOST_WIDE_INT bits
;
8312 /* Work out how many bits to move at a time. If both operands have
8313 half-word alignment, it is usually better to move in half words.
8314 For instance, lh/lh/sh/sh is usually better than lwl/lwr/swl/swr
8315 and lw/lw/sw/sw is usually better than ldl/ldr/sdl/sdr.
8316 Otherwise move word-sized chunks.
8318 For ISA_HAS_LWL_LWR we rely on the lwl/lwr & swl/swr load. Otherwise
8319 picking the minimum of alignment or BITS_PER_WORD gets us the
8320 desired size for bits. */
8321 if (ISA_HAS_UNALIGNED_ACCESS
)
8322 bits
= BITS_PER_WORD
;
8323 else if (!ISA_HAS_LWL_LWR
)
8324 bits
= MIN (BITS_PER_WORD
, MIN (MEM_ALIGN (src
), MEM_ALIGN (dest
)));
8327 if (MEM_ALIGN (src
) == BITS_PER_WORD
/ 2
8328 && MEM_ALIGN (dest
) == BITS_PER_WORD
/ 2)
8329 bits
= BITS_PER_WORD
/ 2;
8331 bits
= BITS_PER_WORD
;
8334 mode
= int_mode_for_size (bits
, 0).require ();
8335 delta
= bits
/ BITS_PER_UNIT
;
8337 /* Allocate a buffer for the temporary registers. */
8338 regs
= XALLOCAVEC (rtx
, length
/ delta
);
8340 /* Load as many BITS-sized chunks as possible. Use a normal load if
8341 the source has enough alignment, otherwise use left/right pairs. */
8342 for (offset
= 0, i
= 0; offset
+ delta
<= length
; offset
+= delta
, i
++)
8344 regs
[i
] = gen_reg_rtx (mode
);
8345 if (ISA_HAS_UNALIGNED_ACCESS
|| MEM_ALIGN (src
) >= bits
)
8346 mips_emit_move (regs
[i
], adjust_address (src
, mode
, offset
));
8349 rtx part
= adjust_address (src
, BLKmode
, offset
);
8350 set_mem_size (part
, delta
);
8351 if (!mips_expand_ext_as_unaligned_load (regs
[i
], part
, bits
, 0, 0))
8356 /* Copy the chunks to the destination. */
8357 for (offset
= 0, i
= 0; offset
+ delta
<= length
; offset
+= delta
, i
++)
8358 if (ISA_HAS_UNALIGNED_ACCESS
|| MEM_ALIGN (dest
) >= bits
)
8359 mips_emit_move (adjust_address (dest
, mode
, offset
), regs
[i
]);
8362 rtx part
= adjust_address (dest
, BLKmode
, offset
);
8363 set_mem_size (part
, delta
);
8364 if (!mips_expand_ins_as_unaligned_store (part
, regs
[i
], bits
, 0))
8368 /* Mop up any left-over bytes. */
8369 if (offset
< length
)
8371 src
= adjust_address (src
, BLKmode
, offset
);
8372 dest
= adjust_address (dest
, BLKmode
, offset
);
8373 move_by_pieces (dest
, src
, length
- offset
,
8374 MIN (MEM_ALIGN (src
), MEM_ALIGN (dest
)), RETURN_BEGIN
);
8378 /* Helper function for doing a loop-based block operation on memory
8379 reference MEM. Each iteration of the loop will operate on LENGTH
8382 Create a new base register for use within the loop and point it to
8383 the start of MEM. Create a new memory reference that uses this
8384 register. Store them in *LOOP_REG and *LOOP_MEM respectively. */
8387 mips_adjust_block_mem (rtx mem
, HOST_WIDE_INT length
,
8388 rtx
*loop_reg
, rtx
*loop_mem
)
8390 *loop_reg
= copy_addr_to_reg (XEXP (mem
, 0));
8392 /* Although the new mem does not refer to a known location,
8393 it does keep up to LENGTH bytes of alignment. */
8394 *loop_mem
= change_address (mem
, BLKmode
, *loop_reg
);
8395 set_mem_align (*loop_mem
, MIN (MEM_ALIGN (mem
), length
* BITS_PER_UNIT
));
8398 /* Move LENGTH bytes from SRC to DEST using a loop that moves BYTES_PER_ITER
8399 bytes at a time. LENGTH must be at least BYTES_PER_ITER. Assume that
8400 the memory regions do not overlap. */
8403 mips_block_move_loop (rtx dest
, rtx src
, HOST_WIDE_INT length
,
8404 HOST_WIDE_INT bytes_per_iter
)
8406 rtx_code_label
*label
;
8407 rtx src_reg
, dest_reg
, final_src
, test
;
8408 HOST_WIDE_INT leftover
;
8410 leftover
= length
% bytes_per_iter
;
8413 /* Create registers and memory references for use within the loop. */
8414 mips_adjust_block_mem (src
, bytes_per_iter
, &src_reg
, &src
);
8415 mips_adjust_block_mem (dest
, bytes_per_iter
, &dest_reg
, &dest
);
8417 /* Calculate the value that SRC_REG should have after the last iteration
8419 final_src
= expand_simple_binop (Pmode
, PLUS
, src_reg
, GEN_INT (length
),
8422 /* Emit the start of the loop. */
8423 label
= gen_label_rtx ();
8426 /* Emit the loop body. */
8427 mips_block_move_straight (dest
, src
, bytes_per_iter
);
8429 /* Move on to the next block. */
8430 mips_emit_move (src_reg
, plus_constant (Pmode
, src_reg
, bytes_per_iter
));
8431 mips_emit_move (dest_reg
, plus_constant (Pmode
, dest_reg
, bytes_per_iter
));
8433 /* Emit the loop condition. */
8434 test
= gen_rtx_NE (VOIDmode
, src_reg
, final_src
);
8435 if (Pmode
== DImode
)
8436 emit_jump_insn (gen_cbranchdi4 (test
, src_reg
, final_src
, label
));
8438 emit_jump_insn (gen_cbranchsi4 (test
, src_reg
, final_src
, label
));
8440 /* Mop up any left-over bytes. */
8442 mips_block_move_straight (dest
, src
, leftover
);
8444 /* Temporary fix for PR79150. */
8445 emit_insn (gen_nop ());
8448 /* Expand a cpymemsi instruction, which copies LENGTH bytes from
8449 memory reference SRC to memory reference DEST. */
8452 mips_expand_block_move (rtx dest
, rtx src
, rtx length
)
8454 if (!CONST_INT_P (length
))
8457 if (mips_isa_rev
>= 6 && !ISA_HAS_UNALIGNED_ACCESS
8458 && (MEM_ALIGN (src
) < MIPS_MIN_MOVE_MEM_ALIGN
8459 || MEM_ALIGN (dest
) < MIPS_MIN_MOVE_MEM_ALIGN
))
8462 if (INTVAL (length
) <= MIPS_MAX_MOVE_BYTES_PER_LOOP_ITER
)
8464 mips_block_move_straight (dest
, src
, INTVAL (length
));
8469 mips_block_move_loop (dest
, src
, INTVAL (length
),
8470 MIPS_MAX_MOVE_BYTES_PER_LOOP_ITER
);
8477 /* Expand a loop of synci insns for the address range [BEGIN, END). */
8480 mips_expand_synci_loop (rtx begin
, rtx end
)
8482 rtx inc
, cmp_result
, mask
, length
;
8483 rtx_code_label
*label
, *end_label
;
8485 /* Create end_label. */
8486 end_label
= gen_label_rtx ();
8488 /* Check if begin equals end. */
8489 cmp_result
= gen_rtx_EQ (VOIDmode
, begin
, end
);
8490 emit_jump_insn (gen_condjump (cmp_result
, end_label
));
8492 /* Load INC with the cache line size (rdhwr INC,$1). */
8493 inc
= gen_reg_rtx (Pmode
);
8494 emit_insn (PMODE_INSN (gen_rdhwr_synci_step
, (inc
)));
8496 /* Check if inc is 0. */
8497 cmp_result
= gen_rtx_EQ (VOIDmode
, inc
, const0_rtx
);
8498 emit_jump_insn (gen_condjump (cmp_result
, end_label
));
8500 /* Calculate mask. */
8501 mask
= mips_force_unary (Pmode
, NEG
, inc
);
8503 /* Mask out begin by mask. */
8504 begin
= mips_force_binary (Pmode
, AND
, begin
, mask
);
8506 /* Calculate length. */
8507 length
= mips_force_binary (Pmode
, MINUS
, end
, begin
);
8509 /* Loop back to here. */
8510 label
= gen_label_rtx ();
8513 emit_insn (gen_synci (begin
));
8515 /* Update length. */
8516 mips_emit_binary (MINUS
, length
, length
, inc
);
8519 mips_emit_binary (PLUS
, begin
, begin
, inc
);
8521 /* Check if length is greater than 0. */
8522 cmp_result
= gen_rtx_GT (VOIDmode
, length
, const0_rtx
);
8523 emit_jump_insn (gen_condjump (cmp_result
, label
));
8525 emit_label (end_label
);
8528 /* Expand a QI or HI mode atomic memory operation.
8530 GENERATOR contains a pointer to the gen_* function that generates
8531 the SI mode underlying atomic operation using masks that we
8534 RESULT is the return register for the operation. Its value is NULL
8537 MEM is the location of the atomic access.
8539 OLDVAL is the first operand for the operation.
8541 NEWVAL is the optional second operand for the operation. Its value
8542 is NULL if unused. */
8545 mips_expand_atomic_qihi (union mips_gen_fn_ptrs generator
,
8546 rtx result
, rtx mem
, rtx oldval
, rtx newval
)
8548 rtx orig_addr
, memsi_addr
, memsi
, shift
, shiftsi
, unshifted_mask
;
8549 rtx unshifted_mask_reg
, mask
, inverted_mask
, si_op
;
8553 mode
= GET_MODE (mem
);
8555 /* Compute the address of the containing SImode value. */
8556 orig_addr
= force_reg (Pmode
, XEXP (mem
, 0));
8557 memsi_addr
= mips_force_binary (Pmode
, AND
, orig_addr
,
8558 force_reg (Pmode
, GEN_INT (-4)));
8560 /* Create a memory reference for it. */
8561 memsi
= gen_rtx_MEM (SImode
, memsi_addr
);
8562 set_mem_alias_set (memsi
, ALIAS_SET_MEMORY_BARRIER
);
8563 MEM_VOLATILE_P (memsi
) = MEM_VOLATILE_P (mem
);
8565 /* Work out the byte offset of the QImode or HImode value,
8566 counting from the least significant byte. */
8567 shift
= mips_force_binary (Pmode
, AND
, orig_addr
, GEN_INT (3));
8568 if (TARGET_BIG_ENDIAN
)
8569 mips_emit_binary (XOR
, shift
, shift
, GEN_INT (mode
== QImode
? 3 : 2));
8571 /* Multiply by eight to convert the shift value from bytes to bits. */
8572 mips_emit_binary (ASHIFT
, shift
, shift
, GEN_INT (3));
8574 /* Make the final shift an SImode value, so that it can be used in
8575 SImode operations. */
8576 shiftsi
= force_reg (SImode
, gen_lowpart (SImode
, shift
));
8578 /* Set MASK to an inclusive mask of the QImode or HImode value. */
8579 unshifted_mask
= GEN_INT (GET_MODE_MASK (mode
));
8580 unshifted_mask_reg
= force_reg (SImode
, unshifted_mask
);
8581 mask
= mips_force_binary (SImode
, ASHIFT
, unshifted_mask_reg
, shiftsi
);
8583 /* Compute the equivalent exclusive mask. */
8584 inverted_mask
= gen_reg_rtx (SImode
);
8585 emit_insn (gen_rtx_SET (inverted_mask
, gen_rtx_NOT (SImode
, mask
)));
8587 /* Shift the old value into place. */
8588 if (oldval
!= const0_rtx
)
8590 oldval
= convert_modes (SImode
, mode
, oldval
, true);
8591 oldval
= force_reg (SImode
, oldval
);
8592 oldval
= mips_force_binary (SImode
, ASHIFT
, oldval
, shiftsi
);
8595 /* Do the same for the new value. */
8596 if (newval
&& newval
!= const0_rtx
)
8598 newval
= convert_modes (SImode
, mode
, newval
, true);
8599 newval
= force_reg (SImode
, newval
);
8600 newval
= mips_force_binary (SImode
, ASHIFT
, newval
, shiftsi
);
8603 /* Do the SImode atomic access. */
8605 res
= gen_reg_rtx (SImode
);
8607 si_op
= generator
.fn_6 (res
, memsi
, mask
, inverted_mask
, oldval
, newval
);
8609 si_op
= generator
.fn_5 (res
, memsi
, mask
, inverted_mask
, oldval
);
8611 si_op
= generator
.fn_4 (memsi
, mask
, inverted_mask
, oldval
);
8617 /* Shift and convert the result. */
8618 mips_emit_binary (AND
, res
, res
, mask
);
8619 mips_emit_binary (LSHIFTRT
, res
, res
, shiftsi
);
8620 mips_emit_move (result
, gen_lowpart (GET_MODE (result
), res
));
8624 /* Return true if it is possible to use left/right accesses for a
8625 bitfield of WIDTH bits starting BITPOS bits into BLKmode memory OP.
8626 When returning true, update *LEFT and *RIGHT as follows:
8628 *LEFT is a QImode reference to the first byte if big endian or
8629 the last byte if little endian. This address can be used in the
8630 left-side instructions (LWL, SWL, LDL, SDL).
8632 *RIGHT is a QImode reference to the opposite end of the field and
8633 can be used in the patterning right-side instruction. */
8636 mips_get_unaligned_mem (rtx op
, HOST_WIDE_INT width
, HOST_WIDE_INT bitpos
,
8637 rtx
*left
, rtx
*right
)
8641 /* Check that the size is valid. */
8642 if (width
!= 32 && (!TARGET_64BIT
|| width
!= 64))
8645 /* We can only access byte-aligned values. Since we are always passed
8646 a reference to the first byte of the field, it is not necessary to
8647 do anything with BITPOS after this check. */
8648 if (bitpos
% BITS_PER_UNIT
!= 0)
8651 /* Reject aligned bitfields: we want to use a normal load or store
8652 instead of a left/right pair. */
8653 if (MEM_ALIGN (op
) >= width
)
8656 /* Get references to both ends of the field. */
8657 first
= adjust_address (op
, QImode
, 0);
8658 last
= adjust_address (op
, QImode
, width
/ BITS_PER_UNIT
- 1);
8660 /* Allocate to LEFT and RIGHT according to endianness. LEFT should
8661 correspond to the MSB and RIGHT to the LSB. */
8662 if (TARGET_BIG_ENDIAN
)
8663 *left
= first
, *right
= last
;
8665 *left
= last
, *right
= first
;
8670 /* Try to use left/right loads to expand an "extv" or "extzv" pattern.
8671 DEST, SRC, WIDTH and BITPOS are the operands passed to the expander;
8672 the operation is the equivalent of:
8674 (set DEST (*_extract SRC WIDTH BITPOS))
8676 Return true on success. */
8679 mips_expand_ext_as_unaligned_load (rtx dest
, rtx src
, HOST_WIDE_INT width
,
8680 HOST_WIDE_INT bitpos
, bool unsigned_p
)
8682 rtx left
, right
, temp
;
8683 rtx dest1
= NULL_RTX
;
8685 /* If TARGET_64BIT, the destination of a 32-bit "extz" or "extzv" will
8686 be a DImode, create a new temp and emit a zero extend at the end. */
8687 if (GET_MODE (dest
) == DImode
8688 && (REG_P (dest
) || (SUBREG_P (dest
) && !MEM_P (SUBREG_REG (dest
))))
8689 && GET_MODE_BITSIZE (SImode
) == width
)
8692 dest
= gen_reg_rtx (SImode
);
8695 if (!mips_get_unaligned_mem (src
, width
, bitpos
, &left
, &right
))
8698 temp
= gen_reg_rtx (GET_MODE (dest
));
8699 if (GET_MODE (dest
) == DImode
)
8701 emit_insn (gen_mov_ldl (temp
, src
, left
));
8702 emit_insn (gen_mov_ldr (dest
, copy_rtx (src
), right
, temp
));
8706 emit_insn (gen_mov_lwl (temp
, src
, left
));
8707 emit_insn (gen_mov_lwr (dest
, copy_rtx (src
), right
, temp
));
8710 /* If we were loading 32bits and the original register was DI then
8711 sign/zero extend into the orignal dest. */
8715 emit_insn (gen_zero_extendsidi2 (dest1
, dest
));
8717 emit_insn (gen_extendsidi2 (dest1
, dest
));
8722 /* Try to use left/right stores to expand an "ins" pattern. DEST, WIDTH,
8723 BITPOS and SRC are the operands passed to the expander; the operation
8724 is the equivalent of:
8726 (set (zero_extract DEST WIDTH BITPOS) SRC)
8728 Return true on success. */
8731 mips_expand_ins_as_unaligned_store (rtx dest
, rtx src
, HOST_WIDE_INT width
,
8732 HOST_WIDE_INT bitpos
)
8737 if (!mips_get_unaligned_mem (dest
, width
, bitpos
, &left
, &right
))
8740 mode
= int_mode_for_size (width
, 0).require ();
8742 && src
== const0_rtx
)
8743 src
= force_reg (mode
, src
);
8745 src
= gen_lowpart (mode
, src
);
8751 emit_insn (gen_mov_sdl (dest
, src
, left
));
8752 emit_insn (gen_mov_sdr (copy_rtx (dest
), copy_rtx (src
), right
));
8754 else if (TARGET_MIPS16
)
8756 emit_insn (gen_mov_swl_mips16e2 (dest
, src
, left
));
8757 emit_insn (gen_mov_swr_mips16e2 (copy_rtx (dest
), copy_rtx (src
),
8762 emit_insn (gen_mov_swl (dest
, src
, left
));
8763 emit_insn (gen_mov_swr (copy_rtx (dest
), copy_rtx (src
), right
));
8768 /* Return true if X is a MEM with the same size as MODE. */
8771 mips_mem_fits_mode_p (machine_mode mode
, rtx x
)
8774 && MEM_SIZE_KNOWN_P (x
)
8775 && MEM_SIZE (x
) == GET_MODE_SIZE (mode
));
8778 /* Return true if (zero_extract OP WIDTH BITPOS) can be used as the
8779 source of an "ext" instruction or the destination of an "ins"
8780 instruction. OP must be a register operand and the following
8781 conditions must hold:
8783 0 <= BITPOS < GET_MODE_BITSIZE (GET_MODE (op))
8784 0 < WIDTH <= GET_MODE_BITSIZE (GET_MODE (op))
8785 0 < BITPOS + WIDTH <= GET_MODE_BITSIZE (GET_MODE (op))
8787 Also reject lengths equal to a word as they are better handled
8788 by the move patterns. */
8791 mips_use_ins_ext_p (rtx op
, HOST_WIDE_INT width
, HOST_WIDE_INT bitpos
)
8793 if (!ISA_HAS_EXT_INS
8794 || !register_operand (op
, VOIDmode
)
8795 || GET_MODE_BITSIZE (GET_MODE (op
)) > BITS_PER_WORD
)
8798 if (!IN_RANGE (width
, 1, GET_MODE_BITSIZE (GET_MODE (op
)) - 1))
8801 if (bitpos
< 0 || bitpos
+ width
> GET_MODE_BITSIZE (GET_MODE (op
)))
8807 /* Check if MASK and SHIFT are valid in mask-low-and-shift-left
8808 operation if MAXLEN is the maxium length of consecutive bits that
8809 can make up MASK. MODE is the mode of the operation. See
8810 mask_low_and_shift_len for the actual definition. */
8813 mask_low_and_shift_p (machine_mode mode
, rtx mask
, rtx shift
, int maxlen
)
8815 return IN_RANGE (mask_low_and_shift_len (mode
, mask
, shift
), 1, maxlen
);
8818 /* Return true iff OP1 and OP2 are valid operands together for the
8819 *and<MODE>3 and *and<MODE>3_mips16 patterns. For the cases to consider,
8820 see the table in the comment before the pattern. */
8823 and_operands_ok (machine_mode mode
, rtx op1
, rtx op2
)
8826 if (memory_operand (op1
, mode
))
8828 if (TARGET_MIPS16
) {
8829 struct mips_address_info addr
;
8830 if (!mips_classify_address (&addr
, op1
, mode
, false))
8833 return and_load_operand (op2
, mode
);
8836 return and_reg_operand (op2
, mode
);
8839 /* The canonical form of a mask-low-and-shift-left operation is
8840 (and (ashift X SHIFT) MASK) where MASK has the lower SHIFT number of bits
8841 cleared. Thus we need to shift MASK to the right before checking if it
8842 is a valid mask value. MODE is the mode of the operation. If true
8843 return the length of the mask, otherwise return -1. */
8846 mask_low_and_shift_len (machine_mode mode
, rtx mask
, rtx shift
)
8848 HOST_WIDE_INT shval
;
8850 shval
= INTVAL (shift
) & (GET_MODE_BITSIZE (mode
) - 1);
8851 return exact_log2 ((UINTVAL (mask
) >> shval
) + 1);
8854 /* Return true if -msplit-addresses is selected and should be honored.
8856 -msplit-addresses is a half-way house between explicit relocations
8857 and the traditional assembler macros. It can split absolute 32-bit
8858 symbolic constants into a high/lo_sum pair but uses macros for other
8861 Like explicit relocation support for REL targets, it relies
8862 on GNU extensions in the assembler and the linker.
8864 Although this code should work for -O0, it has traditionally
8865 been treated as an optimization. */
8868 mips_split_addresses_p (void)
8870 return (TARGET_SPLIT_ADDRESSES
8874 && !ABI_HAS_64BIT_SYMBOLS
);
8877 /* (Re-)Initialize mips_split_p, mips_lo_relocs and mips_hi_relocs. */
8880 mips_init_relocs (void)
8882 memset (mips_split_p
, '\0', sizeof (mips_split_p
));
8883 memset (mips_split_hi_p
, '\0', sizeof (mips_split_hi_p
));
8884 memset (mips_use_pcrel_pool_p
, '\0', sizeof (mips_use_pcrel_pool_p
));
8885 memset (mips_hi_relocs
, '\0', sizeof (mips_hi_relocs
));
8886 memset (mips_lo_relocs
, '\0', sizeof (mips_lo_relocs
));
8888 if (TARGET_MIPS16_PCREL_LOADS
)
8889 mips_use_pcrel_pool_p
[SYMBOL_ABSOLUTE
] = true;
8892 if (ABI_HAS_64BIT_SYMBOLS
)
8894 if (TARGET_EXPLICIT_RELOCS
)
8896 mips_split_p
[SYMBOL_64_HIGH
] = true;
8897 mips_hi_relocs
[SYMBOL_64_HIGH
] = "%highest(";
8898 mips_lo_relocs
[SYMBOL_64_HIGH
] = "%higher(";
8900 mips_split_p
[SYMBOL_64_MID
] = true;
8901 mips_hi_relocs
[SYMBOL_64_MID
] = "%higher(";
8902 mips_lo_relocs
[SYMBOL_64_MID
] = "%hi(";
8904 mips_split_p
[SYMBOL_64_LOW
] = true;
8905 mips_hi_relocs
[SYMBOL_64_LOW
] = "%hi(";
8906 mips_lo_relocs
[SYMBOL_64_LOW
] = "%lo(";
8908 mips_split_p
[SYMBOL_ABSOLUTE
] = true;
8909 mips_lo_relocs
[SYMBOL_ABSOLUTE
] = "%lo(";
8914 if (TARGET_EXPLICIT_RELOCS
8915 || mips_split_addresses_p ()
8918 mips_split_p
[SYMBOL_ABSOLUTE
] = true;
8919 mips_hi_relocs
[SYMBOL_ABSOLUTE
] = "%hi(";
8920 mips_lo_relocs
[SYMBOL_ABSOLUTE
] = "%lo(";
8925 if (!MIPS16_GP_LOADS
&& TARGET_MIPS16
)
8927 /* The high part is provided by a pseudo copy of $gp. */
8928 mips_split_p
[SYMBOL_GP_RELATIVE
] = true;
8929 mips_lo_relocs
[SYMBOL_GP_RELATIVE
] = "%gprel(";
8931 else if (TARGET_EXPLICIT_RELOCS
)
8932 /* Small data constants are kept whole until after reload,
8933 then lowered by mips_rewrite_small_data. */
8934 mips_lo_relocs
[SYMBOL_GP_RELATIVE
] = "%gp_rel(";
8936 if (TARGET_EXPLICIT_RELOCS
)
8938 mips_split_p
[SYMBOL_GOT_PAGE_OFST
] = true;
8941 mips_lo_relocs
[SYMBOL_GOTOFF_PAGE
] = "%got_page(";
8942 mips_lo_relocs
[SYMBOL_GOT_PAGE_OFST
] = "%got_ofst(";
8946 mips_lo_relocs
[SYMBOL_GOTOFF_PAGE
] = "%got(";
8947 mips_lo_relocs
[SYMBOL_GOT_PAGE_OFST
] = "%lo(";
8950 /* Expose the use of $28 as soon as possible. */
8951 mips_split_hi_p
[SYMBOL_GOT_PAGE_OFST
] = true;
8955 /* The HIGH and LO_SUM are matched by special .md patterns. */
8956 mips_split_p
[SYMBOL_GOT_DISP
] = true;
8958 mips_split_p
[SYMBOL_GOTOFF_DISP
] = true;
8959 mips_hi_relocs
[SYMBOL_GOTOFF_DISP
] = "%got_hi(";
8960 mips_lo_relocs
[SYMBOL_GOTOFF_DISP
] = "%got_lo(";
8962 mips_split_p
[SYMBOL_GOTOFF_CALL
] = true;
8963 mips_hi_relocs
[SYMBOL_GOTOFF_CALL
] = "%call_hi(";
8964 mips_lo_relocs
[SYMBOL_GOTOFF_CALL
] = "%call_lo(";
8969 mips_lo_relocs
[SYMBOL_GOTOFF_DISP
] = "%got_disp(";
8971 mips_lo_relocs
[SYMBOL_GOTOFF_DISP
] = "%got(";
8972 mips_lo_relocs
[SYMBOL_GOTOFF_CALL
] = "%call16(";
8974 /* Expose the use of $28 as soon as possible. */
8975 mips_split_p
[SYMBOL_GOT_DISP
] = true;
8981 mips_split_p
[SYMBOL_GOTOFF_LOADGP
] = true;
8982 mips_hi_relocs
[SYMBOL_GOTOFF_LOADGP
] = "%hi(%neg(%gp_rel(";
8983 mips_lo_relocs
[SYMBOL_GOTOFF_LOADGP
] = "%lo(%neg(%gp_rel(";
8986 mips_lo_relocs
[SYMBOL_TLSGD
] = "%tlsgd(";
8987 mips_lo_relocs
[SYMBOL_TLSLDM
] = "%tlsldm(";
8989 if (TARGET_MIPS16_PCREL_LOADS
)
8991 mips_use_pcrel_pool_p
[SYMBOL_DTPREL
] = true;
8992 mips_use_pcrel_pool_p
[SYMBOL_TPREL
] = true;
8996 mips_split_p
[SYMBOL_DTPREL
] = true;
8997 mips_hi_relocs
[SYMBOL_DTPREL
] = "%dtprel_hi(";
8998 mips_lo_relocs
[SYMBOL_DTPREL
] = "%dtprel_lo(";
9000 mips_split_p
[SYMBOL_TPREL
] = true;
9001 mips_hi_relocs
[SYMBOL_TPREL
] = "%tprel_hi(";
9002 mips_lo_relocs
[SYMBOL_TPREL
] = "%tprel_lo(";
9005 mips_lo_relocs
[SYMBOL_GOTTPREL
] = "%gottprel(";
9006 mips_lo_relocs
[SYMBOL_HALF
] = "%half(";
9009 /* Print symbolic operand OP, which is part of a HIGH or LO_SUM
9010 in context CONTEXT. RELOCS is the array of relocations to use. */
9013 mips_print_operand_reloc (FILE *file
, rtx op
, enum mips_symbol_context context
,
9014 const char **relocs
)
9016 enum mips_symbol_type symbol_type
;
9019 symbol_type
= mips_classify_symbolic_expression (op
, context
);
9020 gcc_assert (relocs
[symbol_type
]);
9022 fputs (relocs
[symbol_type
], file
);
9023 output_addr_const (file
, mips_strip_unspec_address (op
));
9024 for (p
= relocs
[symbol_type
]; *p
!= 0; p
++)
9029 /* Start a new block with the given asm switch enabled. If we need
9030 to print a directive, emit PREFIX before it and SUFFIX after it. */
9033 mips_push_asm_switch_1 (struct mips_asm_switch
*asm_switch
,
9034 const char *prefix
, const char *suffix
)
9036 if (asm_switch
->nesting_level
== 0)
9037 fprintf (asm_out_file
, "%s.set\tno%s%s", prefix
, asm_switch
->name
, suffix
);
9038 asm_switch
->nesting_level
++;
9041 /* Likewise, but end a block. */
9044 mips_pop_asm_switch_1 (struct mips_asm_switch
*asm_switch
,
9045 const char *prefix
, const char *suffix
)
9047 gcc_assert (asm_switch
->nesting_level
);
9048 asm_switch
->nesting_level
--;
9049 if (asm_switch
->nesting_level
== 0)
9050 fprintf (asm_out_file
, "%s.set\t%s%s", prefix
, asm_switch
->name
, suffix
);
9053 /* Wrappers around mips_push_asm_switch_1 and mips_pop_asm_switch_1
9054 that either print a complete line or print nothing. */
9057 mips_push_asm_switch (struct mips_asm_switch
*asm_switch
)
9059 mips_push_asm_switch_1 (asm_switch
, "\t", "\n");
9063 mips_pop_asm_switch (struct mips_asm_switch
*asm_switch
)
9065 mips_pop_asm_switch_1 (asm_switch
, "\t", "\n");
9068 /* Print the text for PRINT_OPERAND punctation character CH to FILE.
9069 The punctuation characters are:
9071 '(' Start a nested ".set noreorder" block.
9072 ')' End a nested ".set noreorder" block.
9073 '[' Start a nested ".set noat" block.
9074 ']' End a nested ".set noat" block.
9075 '<' Start a nested ".set nomacro" block.
9076 '>' End a nested ".set nomacro" block.
9077 '*' Behave like %(%< if generating a delayed-branch sequence.
9078 '#' Print a nop if in a ".set noreorder" block.
9079 '/' Like '#', but do nothing within a delayed-branch sequence.
9080 '?' Print "l" if mips_branch_likely is true
9081 '~' Print a nop if mips_branch_likely is true
9082 '.' Print the name of the register with a hard-wired zero (zero or $0).
9083 '@' Print the name of the assembler temporary register (at or $1).
9084 '^' Print the name of the pic call-through register (t9 or $25).
9085 '+' Print the name of the gp register (usually gp or $28).
9086 '$' Print the name of the stack pointer register (sp or $29).
9087 ':' Print "c" to use the compact version if the delay slot is a nop.
9088 '!' Print "s" to use the short version if the delay slot contains a
9091 See also mips_init_print_operand_punct. */
9094 mips_print_operand_punctuation (FILE *file
, int ch
)
9099 mips_push_asm_switch_1 (&mips_noreorder
, "", "\n\t");
9103 mips_pop_asm_switch_1 (&mips_noreorder
, "\n\t", "");
9107 mips_push_asm_switch_1 (&mips_noat
, "", "\n\t");
9111 mips_pop_asm_switch_1 (&mips_noat
, "\n\t", "");
9115 mips_push_asm_switch_1 (&mips_nomacro
, "", "\n\t");
9119 mips_pop_asm_switch_1 (&mips_nomacro
, "\n\t", "");
9123 if (final_sequence
!= 0)
9125 mips_print_operand_punctuation (file
, '(');
9126 mips_print_operand_punctuation (file
, '<');
9131 if (mips_noreorder
.nesting_level
> 0)
9132 fputs ("\n\tnop", file
);
9136 /* Print an extra newline so that the delayed insn is separated
9137 from the following ones. This looks neater and is consistent
9138 with non-nop delayed sequences. */
9139 if (mips_noreorder
.nesting_level
> 0 && final_sequence
== 0)
9140 fputs ("\n\tnop\n", file
);
9144 if (mips_branch_likely
)
9149 if (mips_branch_likely
)
9150 fputs ("\n\tnop", file
);
9154 fputs (reg_names
[GP_REG_FIRST
+ 0], file
);
9158 fputs (reg_names
[AT_REGNUM
], file
);
9162 fputs (reg_names
[PIC_FUNCTION_ADDR_REGNUM
], file
);
9166 fputs (reg_names
[PIC_OFFSET_TABLE_REGNUM
], file
);
9170 fputs (reg_names
[STACK_POINTER_REGNUM
], file
);
9174 /* When final_sequence is 0, the delay slot will be a nop. We can
9175 use the compact version where available. The %: formatter will
9176 only be present if a compact form of the branch is available. */
9177 if (final_sequence
== 0)
9182 /* If the delay slot instruction is short, then use the
9184 if (TARGET_MICROMIPS
&& !TARGET_INTERLINK_COMPRESSED
&& mips_isa_rev
<= 5
9185 && (final_sequence
== 0
9186 || get_attr_length (final_sequence
->insn (1)) == 2))
9196 /* Initialize mips_print_operand_punct. */
9199 mips_init_print_operand_punct (void)
9203 for (p
= "()[]<>*#/?~.@^+$:!"; *p
; p
++)
9204 mips_print_operand_punct
[(unsigned char) *p
] = true;
9207 /* PRINT_OPERAND prefix LETTER refers to the integer branch instruction
9208 associated with condition CODE. Print the condition part of the
9212 mips_print_int_branch_condition (FILE *file
, enum rtx_code code
, int letter
)
9226 /* Conveniently, the MIPS names for these conditions are the same
9227 as their RTL equivalents. */
9228 fputs (GET_RTX_NAME (code
), file
);
9232 output_operand_lossage ("'%%%c' is not a valid operand prefix", letter
);
9237 /* Likewise floating-point branches. */
9240 mips_print_float_branch_condition (FILE *file
, enum rtx_code code
, int letter
)
9246 fputs ("c1eqz", file
);
9248 fputs ("c1f", file
);
9253 fputs ("c1nez", file
);
9255 fputs ("c1t", file
);
9259 output_operand_lossage ("'%%%c' is not a valid operand prefix", letter
);
9264 /* Implement TARGET_PRINT_OPERAND_PUNCT_VALID_P. */
9267 mips_print_operand_punct_valid_p (unsigned char code
)
9269 return mips_print_operand_punct
[code
];
9272 /* Implement TARGET_PRINT_OPERAND. The MIPS-specific operand codes are:
9274 'E' Print CONST_INT OP element 0 of a replicated CONST_VECTOR in decimal.
9275 'X' Print CONST_INT OP in hexadecimal format.
9276 'x' Print the low 16 bits of CONST_INT OP in hexadecimal format.
9277 'd' Print CONST_INT OP in decimal.
9278 'B' Print CONST_INT OP element 0 of a replicated CONST_VECTOR
9279 as an unsigned byte [0..255].
9280 'm' Print one less than CONST_INT OP in decimal.
9281 'y' Print exact log2 of CONST_INT OP in decimal.
9282 'h' Print the high-part relocation associated with OP, after stripping
9284 'R' Print the low-part relocation associated with OP.
9285 'C' Print the integer branch condition for comparison OP.
9286 'N' Print the inverse of the integer branch condition for comparison OP.
9287 'F' Print the FPU branch condition for comparison OP.
9288 'W' Print the inverse of the FPU branch condition for comparison OP.
9289 'w' Print a MSA register.
9290 'T' Print 'f' for (eq:CC ...), 't' for (ne:CC ...),
9291 'z' for (eq:?I ...), 'n' for (ne:?I ...).
9292 't' Like 'T', but with the EQ/NE cases reversed
9293 'Y' Print mips_fp_conditions[INTVAL (OP)]
9294 'Z' Print OP and a comma for ISA_HAS_8CC, otherwise print nothing.
9295 'q' Print a DSP accumulator register.
9296 'D' Print the second part of a double-word register or memory operand.
9297 'L' Print the low-order register in a double-word register operand.
9298 'M' Print high-order register in a double-word register operand.
9299 'z' Print $0 if OP is zero, otherwise print OP normally.
9300 'b' Print the address of a memory operand, without offset.
9301 'v' Print the insn size suffix b, h, w or d for vector modes V16QI, V8HI,
9302 V4SI, V2SI, and w, d for vector modes V4SF, V2DF respectively.
9303 'V' Print exact log2 of CONST_INT OP element 0 of a replicated
9304 CONST_VECTOR in decimal. */
9307 mips_print_operand (FILE *file
, rtx op
, int letter
)
9311 if (mips_print_operand_punct_valid_p (letter
))
9313 mips_print_operand_punctuation (file
, letter
);
9318 code
= GET_CODE (op
);
9323 if (GET_CODE (op
) == CONST_VECTOR
)
9325 gcc_assert (mips_const_vector_same_val_p (op
, GET_MODE (op
)));
9326 op
= CONST_VECTOR_ELT (op
, 0);
9327 gcc_assert (CONST_INT_P (op
));
9328 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (op
));
9331 output_operand_lossage ("invalid use of '%%%c'", letter
);
9335 if (CONST_INT_P (op
))
9336 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, INTVAL (op
));
9338 output_operand_lossage ("invalid use of '%%%c'", letter
);
9342 if (CONST_INT_P (op
))
9343 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, INTVAL (op
) & 0xffff);
9345 output_operand_lossage ("invalid use of '%%%c'", letter
);
9349 if (CONST_INT_P (op
))
9350 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (op
));
9352 output_operand_lossage ("invalid use of '%%%c'", letter
);
9356 if (GET_CODE (op
) == CONST_VECTOR
)
9358 gcc_assert (mips_const_vector_same_val_p (op
, GET_MODE (op
)));
9359 op
= CONST_VECTOR_ELT (op
, 0);
9360 gcc_assert (CONST_INT_P (op
));
9361 unsigned HOST_WIDE_INT val8
= UINTVAL (op
) & GET_MODE_MASK (QImode
);
9362 fprintf (file
, HOST_WIDE_INT_PRINT_UNSIGNED
, val8
);
9365 output_operand_lossage ("invalid use of '%%%c'", letter
);
9369 if (CONST_INT_P (op
))
9370 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (op
) - 1);
9372 output_operand_lossage ("invalid use of '%%%c'", letter
);
9376 if (CONST_INT_P (op
))
9378 int val
= exact_log2 (INTVAL (op
));
9380 fprintf (file
, "%d", val
);
9382 output_operand_lossage ("invalid use of '%%%c'", letter
);
9385 output_operand_lossage ("invalid use of '%%%c'", letter
);
9389 if (GET_CODE (op
) == CONST_VECTOR
)
9391 machine_mode mode
= GET_MODE_INNER (GET_MODE (op
));
9392 unsigned HOST_WIDE_INT val
= UINTVAL (CONST_VECTOR_ELT (op
, 0));
9393 int vlog2
= exact_log2 (val
& GET_MODE_MASK (mode
));
9395 fprintf (file
, "%d", vlog2
);
9397 output_operand_lossage ("invalid use of '%%%c'", letter
);
9400 output_operand_lossage ("invalid use of '%%%c'", letter
);
9406 mips_print_operand_reloc (file
, op
, SYMBOL_CONTEXT_LEA
, mips_hi_relocs
);
9410 mips_print_operand_reloc (file
, op
, SYMBOL_CONTEXT_LEA
, mips_lo_relocs
);
9414 mips_print_int_branch_condition (file
, code
, letter
);
9418 mips_print_int_branch_condition (file
, reverse_condition (code
), letter
);
9422 mips_print_float_branch_condition (file
, code
, letter
);
9426 mips_print_float_branch_condition (file
, reverse_condition (code
),
9433 int truth
= (code
== NE
) == (letter
== 'T');
9434 fputc ("zfnt"[truth
* 2 + ST_REG_P (REGNO (XEXP (op
, 0)))], file
);
9439 if (code
== CONST_INT
&& UINTVAL (op
) < ARRAY_SIZE (mips_fp_conditions
))
9440 fputs (mips_fp_conditions
[UINTVAL (op
)], file
);
9442 output_operand_lossage ("'%%%c' is not a valid operand prefix",
9447 if (ISA_HAS_8CC
|| ISA_HAS_CCF
)
9449 mips_print_operand (file
, op
, 0);
9455 if (code
== REG
&& MD_REG_P (REGNO (op
)))
9456 fprintf (file
, "$ac0");
9457 else if (code
== REG
&& DSP_ACC_REG_P (REGNO (op
)))
9458 fprintf (file
, "$ac%c", reg_names
[REGNO (op
)][3]);
9460 output_operand_lossage ("invalid use of '%%%c'", letter
);
9464 if (code
== REG
&& MSA_REG_P (REGNO (op
)))
9465 fprintf (file
, "$w%s", ®_names
[REGNO (op
)][2]);
9467 output_operand_lossage ("invalid use of '%%%c'", letter
);
9471 switch (GET_MODE (op
))
9474 fprintf (file
, "b");
9477 fprintf (file
, "h");
9481 fprintf (file
, "w");
9485 fprintf (file
, "d");
9488 output_operand_lossage ("invalid use of '%%%c'", letter
);
9497 unsigned int regno
= REGNO (op
);
9498 if ((letter
== 'M' && TARGET_LITTLE_ENDIAN
)
9499 || (letter
== 'L' && TARGET_BIG_ENDIAN
)
9502 else if (letter
&& letter
!= 'z' && letter
!= 'M' && letter
!= 'L')
9503 output_operand_lossage ("invalid use of '%%%c'", letter
);
9504 /* We need to print $0 .. $31 for COP0 registers. */
9505 if (COP0_REG_P (regno
))
9506 fprintf (file
, "$%s", ®_names
[regno
][4]);
9508 fprintf (file
, "%s", reg_names
[regno
]);
9514 output_address (GET_MODE (op
), plus_constant (Pmode
,
9516 else if (letter
== 'b')
9518 gcc_assert (REG_P (XEXP (op
, 0)));
9519 mips_print_operand (file
, XEXP (op
, 0), 0);
9521 else if (letter
&& letter
!= 'z')
9522 output_operand_lossage ("invalid use of '%%%c'", letter
);
9524 output_address (GET_MODE (op
), XEXP (op
, 0));
9528 if (letter
== 'z' && op
== CONST0_RTX (GET_MODE (op
)))
9529 fputs (reg_names
[GP_REG_FIRST
], file
);
9530 else if (letter
&& letter
!= 'z')
9531 output_operand_lossage ("invalid use of '%%%c'", letter
);
9532 else if (CONST_GP_P (op
))
9533 fputs (reg_names
[GLOBAL_POINTER_REGNUM
], file
);
9535 output_addr_const (file
, mips_strip_unspec_address (op
));
9541 /* Implement TARGET_PRINT_OPERAND_ADDRESS. */
9544 mips_print_operand_address (FILE *file
, machine_mode
/*mode*/, rtx x
)
9546 struct mips_address_info addr
;
9548 if (mips_classify_address (&addr
, x
, word_mode
, true))
9552 mips_print_operand (file
, addr
.offset
, 0);
9553 fprintf (file
, "(%s)", reg_names
[REGNO (addr
.reg
)]);
9556 case ADDRESS_LO_SUM
:
9557 mips_print_operand_reloc (file
, addr
.offset
, SYMBOL_CONTEXT_MEM
,
9559 fprintf (file
, "(%s)", reg_names
[REGNO (addr
.reg
)]);
9562 case ADDRESS_CONST_INT
:
9563 output_addr_const (file
, x
);
9564 fprintf (file
, "(%s)", reg_names
[GP_REG_FIRST
]);
9567 case ADDRESS_SYMBOLIC
:
9568 output_addr_const (file
, mips_strip_unspec_address (x
));
9574 /* Implement TARGET_ENCODE_SECTION_INFO. */
9577 mips_encode_section_info (tree decl
, rtx rtl
, int first
)
9579 default_encode_section_info (decl
, rtl
, first
);
9581 if (TREE_CODE (decl
) == FUNCTION_DECL
)
9583 rtx symbol
= XEXP (rtl
, 0);
9584 tree type
= TREE_TYPE (decl
);
9586 /* Encode whether the symbol is short or long. */
9587 if ((TARGET_LONG_CALLS
&& !mips_near_type_p (type
))
9588 || mips_far_type_p (type
))
9589 SYMBOL_REF_FLAGS (symbol
) |= SYMBOL_FLAG_LONG_CALL
;
9593 /* Implement TARGET_SELECT_RTX_SECTION. */
9596 mips_select_rtx_section (machine_mode mode
, rtx x
,
9597 unsigned HOST_WIDE_INT align
)
9599 /* ??? Consider using mergeable small data sections. */
9600 if (mips_rtx_constant_in_small_data_p (mode
))
9601 return get_named_section (NULL
, ".sdata", 0);
9603 return default_elf_select_rtx_section (mode
, x
, align
);
9606 /* Implement TARGET_IN_SMALL_DATA_P. */
9609 mips_in_small_data_p (const_tree decl
)
9611 unsigned HOST_WIDE_INT size
;
9613 if (TREE_CODE (decl
) == STRING_CST
|| TREE_CODE (decl
) == FUNCTION_DECL
)
9616 /* We don't yet generate small-data references for -mabicalls
9617 or VxWorks RTP code. See the related -G handling in
9618 mips_option_override. */
9619 if (TARGET_ABICALLS
|| TARGET_VXWORKS_RTP
)
9622 if (TREE_CODE (decl
) == VAR_DECL
&& DECL_SECTION_NAME (decl
) != 0)
9626 /* Reject anything that isn't in a known small-data section. */
9627 name
= DECL_SECTION_NAME (decl
);
9628 if (strcmp (name
, ".sdata") != 0 && strcmp (name
, ".sbss") != 0)
9631 /* If a symbol is defined externally, the assembler will use the
9632 usual -G rules when deciding how to implement macros. */
9633 if (mips_lo_relocs
[SYMBOL_GP_RELATIVE
] || !DECL_EXTERNAL (decl
))
9636 else if (TARGET_EMBEDDED_DATA
)
9638 /* Don't put constants into the small data section: we want them
9639 to be in ROM rather than RAM. */
9640 if (TREE_CODE (decl
) != VAR_DECL
)
9643 if (TREE_READONLY (decl
)
9644 && !TREE_SIDE_EFFECTS (decl
)
9645 && (!DECL_INITIAL (decl
) || TREE_CONSTANT (DECL_INITIAL (decl
))))
9649 /* Enforce -mlocal-sdata. */
9650 if (!TARGET_LOCAL_SDATA
&& !TREE_PUBLIC (decl
))
9653 /* Enforce -mextern-sdata. */
9654 if (!TARGET_EXTERN_SDATA
&& DECL_P (decl
))
9656 if (DECL_EXTERNAL (decl
))
9658 if (DECL_COMMON (decl
) && DECL_INITIAL (decl
) == NULL
)
9662 /* We have traditionally not treated zero-sized objects as small data,
9663 so this is now effectively part of the ABI. */
9664 size
= int_size_in_bytes (TREE_TYPE (decl
));
9665 return size
> 0 && size
<= mips_small_data_threshold
;
9668 /* Implement TARGET_USE_ANCHORS_FOR_SYMBOL_P. We don't want to use
9669 anchors for small data: the GP register acts as an anchor in that
9670 case. We also don't want to use them for PC-relative accesses,
9671 where the PC acts as an anchor. */
9674 mips_use_anchors_for_symbol_p (const_rtx symbol
)
9676 switch (mips_classify_symbol (symbol
, SYMBOL_CONTEXT_MEM
))
9678 case SYMBOL_PC_RELATIVE
:
9679 case SYMBOL_GP_RELATIVE
:
9683 return default_use_anchors_for_symbol_p (symbol
);
9687 /* The MIPS debug format wants all automatic variables and arguments
9688 to be in terms of the virtual frame pointer (stack pointer before
9689 any adjustment in the function), while the MIPS 3.0 linker wants
9690 the frame pointer to be the stack pointer after the initial
9691 adjustment. So, we do the adjustment here. The arg pointer (which
9692 is eliminated) points to the virtual frame pointer, while the frame
9693 pointer (which may be eliminated) points to the stack pointer after
9694 the initial adjustments. */
9697 mips_debugger_offset (rtx addr
, HOST_WIDE_INT offset
)
9699 rtx offset2
= const0_rtx
;
9700 rtx reg
= eliminate_constant_term (addr
, &offset2
);
9703 offset
= INTVAL (offset2
);
9705 if (reg
== stack_pointer_rtx
9706 || reg
== frame_pointer_rtx
9707 || reg
== hard_frame_pointer_rtx
)
9709 offset
-= cfun
->machine
->frame
.total_size
;
9710 if (reg
== hard_frame_pointer_rtx
)
9711 offset
+= cfun
->machine
->frame
.hard_frame_pointer_offset
;
9717 /* Implement ASM_OUTPUT_EXTERNAL. */
9720 mips_output_external (FILE *file
, tree decl
, const char *name
)
9722 default_elf_asm_output_external (file
, decl
, name
);
9724 /* We output the name if and only if TREE_SYMBOL_REFERENCED is
9725 set in order to avoid putting out names that are never really
9727 if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl
)))
9729 if (!TARGET_EXPLICIT_RELOCS
&& mips_in_small_data_p (decl
))
9731 /* When using assembler macros, emit .extern directives for
9732 all small-data externs so that the assembler knows how
9735 In most cases it would be safe (though pointless) to emit
9736 .externs for other symbols too. One exception is when an
9737 object is within the -G limit but declared by the user to
9738 be in a section other than .sbss or .sdata. */
9739 fputs ("\t.extern\t", file
);
9740 assemble_name (file
, name
);
9741 fprintf (file
, ", " HOST_WIDE_INT_PRINT_DEC
"\n",
9742 int_size_in_bytes (TREE_TYPE (decl
)));
9747 /* Implement TARGET_ASM_OUTPUT_SOURCE_FILENAME. */
9750 mips_output_filename (FILE *stream
, const char *name
)
9752 /* If we are emitting DWARF-2, let dwarf2out handle the ".file"
9754 if (dwarf_debuginfo_p ())
9756 else if (mips_output_filename_first_time
)
9758 mips_output_filename_first_time
= 0;
9759 num_source_filenames
+= 1;
9760 current_function_file
= name
;
9761 fprintf (stream
, "\t.file\t%d ", num_source_filenames
);
9762 output_quoted_string (stream
, name
);
9763 putc ('\n', stream
);
9765 else if (name
!= current_function_file
9766 && strcmp (name
, current_function_file
) != 0)
9768 num_source_filenames
+= 1;
9769 current_function_file
= name
;
9770 fprintf (stream
, "\t.file\t%d ", num_source_filenames
);
9771 output_quoted_string (stream
, name
);
9772 putc ('\n', stream
);
9776 /* Implement TARGET_ASM_OUTPUT_DWARF_DTPREL. */
9778 static void ATTRIBUTE_UNUSED
9779 mips_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
9784 fputs ("\t.dtprelword\t", file
);
9788 fputs ("\t.dtpreldword\t", file
);
9794 output_addr_const (file
, x
);
9795 fputs ("+0x8000", file
);
9798 /* Implement TARGET_DWARF_REGISTER_SPAN. */
9801 mips_dwarf_register_span (rtx reg
)
9806 /* TARGET_FLOATXX is implemented as 32-bit floating-point registers but
9807 ensures that double-precision registers are treated as if they were
9808 64-bit physical registers. The code will run correctly with 32-bit or
9809 64-bit registers which means that dwarf information cannot be precise
9810 for all scenarios. We choose to state that the 64-bit values are stored
9811 in a single 64-bit 'piece'. This slightly unusual construct can then be
9812 interpreted as either a pair of registers if the registers are 32-bit or
9813 a single 64-bit register depending on hardware. */
9814 mode
= GET_MODE (reg
);
9815 if (FP_REG_P (REGNO (reg
))
9817 && GET_MODE_SIZE (mode
) > UNITS_PER_FPREG
)
9819 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (1, reg
));
9821 /* By default, GCC maps increasing register numbers to increasing
9822 memory locations, but paired FPRs are always little-endian,
9823 regardless of the prevailing endianness. */
9824 else if (FP_REG_P (REGNO (reg
))
9825 && TARGET_BIG_ENDIAN
9826 && MAX_FPRS_PER_FMT
> 1
9827 && GET_MODE_SIZE (mode
) > UNITS_PER_FPREG
)
9829 gcc_assert (GET_MODE_SIZE (mode
) == UNITS_PER_HWFPVALUE
);
9830 high
= mips_subword (reg
, true);
9831 low
= mips_subword (reg
, false);
9832 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, high
, low
));
9838 /* Implement TARGET_DWARF_FRAME_REG_MODE. */
9841 mips_dwarf_frame_reg_mode (int regno
)
9843 machine_mode mode
= default_dwarf_frame_reg_mode (regno
);
9845 if (FP_REG_P (regno
) && mips_abi
== ABI_32
&& !TARGET_FLOAT32
)
9851 /* DSP ALU can bypass data with no delays for the following pairs. */
9852 enum insn_code dspalu_bypass_table
[][2] =
9854 {CODE_FOR_mips_addsc
, CODE_FOR_mips_addwc
},
9855 {CODE_FOR_mips_cmpu_eq_qb
, CODE_FOR_mips_pick_qb
},
9856 {CODE_FOR_mips_cmpu_lt_qb
, CODE_FOR_mips_pick_qb
},
9857 {CODE_FOR_mips_cmpu_le_qb
, CODE_FOR_mips_pick_qb
},
9858 {CODE_FOR_mips_cmp_eq_ph
, CODE_FOR_mips_pick_ph
},
9859 {CODE_FOR_mips_cmp_lt_ph
, CODE_FOR_mips_pick_ph
},
9860 {CODE_FOR_mips_cmp_le_ph
, CODE_FOR_mips_pick_ph
},
9861 {CODE_FOR_mips_wrdsp
, CODE_FOR_mips_insv
}
9865 mips_dspalu_bypass_p (rtx out_insn
, rtx in_insn
)
9868 int num_bypass
= ARRAY_SIZE (dspalu_bypass_table
);
9869 enum insn_code out_icode
= (enum insn_code
) INSN_CODE (out_insn
);
9870 enum insn_code in_icode
= (enum insn_code
) INSN_CODE (in_insn
);
9872 for (i
= 0; i
< num_bypass
; i
++)
9874 if (out_icode
== dspalu_bypass_table
[i
][0]
9875 && in_icode
== dspalu_bypass_table
[i
][1])
9881 /* Implement ASM_OUTPUT_ASCII. */
9884 mips_output_ascii (FILE *stream
, const char *string
, size_t len
)
9890 fprintf (stream
, "\t.ascii\t\"");
9891 for (i
= 0; i
< len
; i
++)
9895 c
= (unsigned char) string
[i
];
9898 if (c
== '\\' || c
== '\"')
9900 putc ('\\', stream
);
9908 fprintf (stream
, "\\%03o", c
);
9912 if (cur_pos
> 72 && i
+1 < len
)
9915 fprintf (stream
, "\"\n\t.ascii\t\"");
9918 fprintf (stream
, "\"\n");
9921 /* Return the pseudo-op for full SYMBOL_(D)TPREL address *ADDR.
9922 Update *ADDR with the operand that should be printed. */
9925 mips_output_tls_reloc_directive (rtx
*addr
)
9927 enum mips_symbol_type type
;
9929 type
= mips_classify_symbolic_expression (*addr
, SYMBOL_CONTEXT_LEA
);
9930 *addr
= mips_strip_unspec_address (*addr
);
9934 return Pmode
== SImode
? ".dtprelword\t%0" : ".dtpreldword\t%0";
9937 return Pmode
== SImode
? ".tprelword\t%0" : ".tpreldword\t%0";
9944 /* Emit either a label, .comm, or .lcomm directive. When using assembler
9945 macros, mark the symbol as written so that mips_asm_output_external
9946 won't emit an .extern for it. STREAM is the output file, NAME is the
9947 name of the symbol, INIT_STRING is the string that should be written
9948 before the symbol and FINAL_STRING is the string that should be
9949 written after it. FINAL_STRING is a printf format that consumes the
9950 remaining arguments. */
9953 mips_declare_object (FILE *stream
, const char *name
, const char *init_string
,
9954 const char *final_string
, ...)
9958 fputs (init_string
, stream
);
9959 assemble_name (stream
, name
);
9960 va_start (ap
, final_string
);
9961 vfprintf (stream
, final_string
, ap
);
9964 if (!TARGET_EXPLICIT_RELOCS
)
9966 tree name_tree
= get_identifier (name
);
9967 TREE_ASM_WRITTEN (name_tree
) = 1;
9971 /* Declare a common object of SIZE bytes using asm directive INIT_STRING.
9972 NAME is the name of the object and ALIGN is the required alignment
9973 in bytes. TAKES_ALIGNMENT_P is true if the directive takes a third
9974 alignment argument. */
9977 mips_declare_common_object (FILE *stream
, const char *name
,
9978 const char *init_string
,
9979 unsigned HOST_WIDE_INT size
,
9980 unsigned int align
, bool takes_alignment_p
)
9982 if (!takes_alignment_p
)
9984 size
+= (align
/ BITS_PER_UNIT
) - 1;
9985 size
-= size
% (align
/ BITS_PER_UNIT
);
9986 mips_declare_object (stream
, name
, init_string
,
9987 "," HOST_WIDE_INT_PRINT_UNSIGNED
"\n", size
);
9990 mips_declare_object (stream
, name
, init_string
,
9991 "," HOST_WIDE_INT_PRINT_UNSIGNED
",%u\n",
9992 size
, align
/ BITS_PER_UNIT
);
9995 /* Implement ASM_OUTPUT_ALIGNED_DECL_COMMON. This is usually the same as the
9996 elfos.h version, but we also need to handle -muninit-const-in-rodata. */
9999 mips_output_aligned_decl_common (FILE *stream
, tree decl
, const char *name
,
10000 unsigned HOST_WIDE_INT size
,
10001 unsigned int align
)
10003 /* If the target wants uninitialized const declarations in
10004 .rdata then don't put them in .comm. */
10005 if (TARGET_EMBEDDED_DATA
10006 && TARGET_UNINIT_CONST_IN_RODATA
10008 && TREE_READONLY (decl
)
10009 && (DECL_INITIAL (decl
) == 0 || DECL_INITIAL (decl
) == error_mark_node
))
10011 if (TREE_PUBLIC (decl
) && DECL_NAME (decl
))
10012 targetm
.asm_out
.globalize_label (stream
, name
);
10014 switch_to_section (readonly_data_section
);
10015 ASM_OUTPUT_ALIGN (stream
, floor_log2 (align
/ BITS_PER_UNIT
));
10016 mips_declare_object (stream
, name
, "",
10017 ":\n\t.space\t" HOST_WIDE_INT_PRINT_UNSIGNED
"\n",
10021 mips_declare_common_object (stream
, name
, "\n\t.comm\t",
10022 size
, align
, true);
10025 #ifdef ASM_OUTPUT_SIZE_DIRECTIVE
10026 extern int size_directive_output
;
10028 /* Implement ASM_DECLARE_OBJECT_NAME. This is like most of the standard ELF
10029 definitions except that it uses mips_declare_object to emit the label. */
10032 mips_declare_object_name (FILE *stream
, const char *name
,
10033 tree decl ATTRIBUTE_UNUSED
)
10035 #ifdef ASM_OUTPUT_TYPE_DIRECTIVE
10036 #ifdef USE_GNU_UNIQUE_OBJECT
10037 /* As in elfos.h. */
10038 if (USE_GNU_UNIQUE_OBJECT
&& DECL_ONE_ONLY (decl
)
10039 && (!DECL_ARTIFICIAL (decl
) || !TREE_READONLY (decl
)))
10040 ASM_OUTPUT_TYPE_DIRECTIVE (stream
, name
, "gnu_unique_object");
10043 ASM_OUTPUT_TYPE_DIRECTIVE (stream
, name
, "object");
10046 size_directive_output
= 0;
10047 if (!flag_inhibit_size_directive
&& DECL_SIZE (decl
))
10049 HOST_WIDE_INT size
;
10051 size_directive_output
= 1;
10052 size
= int_size_in_bytes (TREE_TYPE (decl
));
10053 ASM_OUTPUT_SIZE_DIRECTIVE (stream
, name
, size
);
10056 mips_declare_object (stream
, name
, "", ":\n");
10059 /* Implement ASM_FINISH_DECLARE_OBJECT. This is generic ELF stuff. */
10062 mips_finish_declare_object (FILE *stream
, tree decl
, int top_level
, int at_end
)
10066 name
= XSTR (XEXP (DECL_RTL (decl
), 0), 0);
10067 if (!flag_inhibit_size_directive
10068 && DECL_SIZE (decl
) != 0
10071 && DECL_INITIAL (decl
) == error_mark_node
10072 && !size_directive_output
)
10074 HOST_WIDE_INT size
;
10076 size_directive_output
= 1;
10077 size
= int_size_in_bytes (TREE_TYPE (decl
));
10078 ASM_OUTPUT_SIZE_DIRECTIVE (stream
, name
, size
);
10083 /* Mark text contents as code or data, mainly for the purpose of correct
10084 disassembly. Emit a local symbol and set its type appropriately for
10085 that purpose. Also emit `.insn' if marking contents as code so that
10086 the ISA mode is recorded and any padding that follows is disassembled
10087 as correct instructions. */
10090 mips_set_text_contents_type (FILE *file ATTRIBUTE_UNUSED
,
10091 const char *prefix ATTRIBUTE_UNUSED
,
10092 unsigned HOST_WIDE_INT num ATTRIBUTE_UNUSED
,
10093 bool function_p ATTRIBUTE_UNUSED
)
10095 #ifdef ASM_OUTPUT_TYPE_DIRECTIVE
10096 char buf
[(sizeof (num
) * 10) / 4 + 2];
10097 const char *fnname
;
10101 sprintf (buf
, HOST_WIDE_INT_PRINT_UNSIGNED
, num
);
10102 symbol
= XEXP (DECL_RTL (current_function_decl
), 0);
10103 fnname
= targetm
.strip_name_encoding (XSTR (symbol
, 0));
10104 sname
= ACONCAT ((prefix
, fnname
, "_", buf
, NULL
));
10106 ASM_OUTPUT_TYPE_DIRECTIVE (file
, sname
, function_p
? "function" : "object");
10107 assemble_name (file
, sname
);
10108 fputs (":\n", file
);
10110 fputs ("\t.insn\n", file
);
10114 /* Return the FOO in the name of the ".mdebug.FOO" section associated
10115 with the current ABI. */
10117 static const char *
10118 mips_mdebug_abi_name (void)
10131 return TARGET_64BIT
? "eabi64" : "eabi32";
10133 gcc_unreachable ();
10137 /* Implement TARGET_ASM_FILE_START. */
10140 mips_file_start (void)
10142 default_file_start ();
10144 /* Generate a special section to describe the ABI switches used to
10145 produce the resultant binary. */
10147 /* Record the ABI itself. Modern versions of binutils encode
10148 this information in the ELF header flags, but GDB needs the
10149 information in order to correctly debug binaries produced by
10150 older binutils. See the function mips_gdbarch_init in
10151 gdb/mips-tdep.c. */
10152 fprintf (asm_out_file
, "\t.section .mdebug.%s\n\t.previous\n",
10153 mips_mdebug_abi_name ());
10155 /* There is no ELF header flag to distinguish long32 forms of the
10156 EABI from long64 forms. Emit a special section to help tools
10157 such as GDB. Do the same for o64, which is sometimes used with
10159 if (mips_abi
== ABI_EABI
|| mips_abi
== ABI_O64
)
10160 fprintf (asm_out_file
, "\t.section .gcc_compiled_long%d\n"
10161 "\t.previous\n", TARGET_LONG64
? 64 : 32);
10163 /* Record the NaN encoding. */
10164 if (HAVE_AS_NAN
|| mips_nan
!= MIPS_IEEE_754_DEFAULT
)
10165 fprintf (asm_out_file
, "\t.nan\t%s\n",
10166 mips_nan
== MIPS_IEEE_754_2008
? "2008" : "legacy");
10168 #ifdef HAVE_AS_DOT_MODULE
10169 /* Record the FP ABI. See below for comments. */
10170 if (TARGET_NO_FLOAT
)
10171 #ifdef HAVE_AS_GNU_ATTRIBUTE
10172 fputs ("\t.gnu_attribute 4, 0\n", asm_out_file
);
10176 else if (!TARGET_HARD_FLOAT_ABI
)
10177 fputs ("\t.module\tsoftfloat\n", asm_out_file
);
10178 else if (!TARGET_DOUBLE_FLOAT
)
10179 fputs ("\t.module\tsinglefloat\n", asm_out_file
);
10180 else if (TARGET_FLOATXX
)
10181 fputs ("\t.module\tfp=xx\n", asm_out_file
);
10182 else if (TARGET_FLOAT64
)
10183 fputs ("\t.module\tfp=64\n", asm_out_file
);
10185 fputs ("\t.module\tfp=32\n", asm_out_file
);
10187 if (TARGET_ODD_SPREG
)
10188 fputs ("\t.module\toddspreg\n", asm_out_file
);
10190 fputs ("\t.module\tnooddspreg\n", asm_out_file
);
10192 fprintf (asm_out_file
, "\t.module\tarch=%s\n", mips_arch_info
->name
);
10193 /* FIXME: DSPR3 is not supported by GCC? gas does support it */
10195 fputs ("\t.module\tdspr2\n", asm_out_file
);
10196 else if (TARGET_DSP
)
10197 fputs ("\t.module\tdsp\n", asm_out_file
);
10199 fputs ("\t.module\teva\n", asm_out_file
);
10201 fputs ("\t.module\tmcu\n", asm_out_file
);
10203 fputs ("\t.module\tmdmx\n", asm_out_file
);
10205 fputs ("\t.module\tmips3d\n", asm_out_file
);
10207 fputs ("\t.module\tmt\n", asm_out_file
);
10208 if (TARGET_SMARTMIPS
)
10209 fputs ("\t.module\tsmartmips\n", asm_out_file
);
10211 fputs ("\t.module\tvirt\n", asm_out_file
);
10213 fputs ("\t.module\tmsa\n", asm_out_file
);
10215 fputs ("\t.module\txpa\n", asm_out_file
);
10216 if (TARGET_MIPS16E2
)
10217 fputs ("\t.module\tmips16e2\n", asm_out_file
);
10219 fputs ("\t.module\tcrc\n", asm_out_file
);
10221 fputs ("\t.module\tginv\n", asm_out_file
);
10222 if (TARGET_LOONGSON_MMI
)
10223 fputs ("\t.module\tloongson-mmi\n", asm_out_file
);
10224 /* FIXME: LOONGSON-CAM is not supported by GCC? gas does support it */
10225 if (TARGET_LOONGSON_EXT2
)
10226 fputs ("\t.module\tloongson-ext2\n", asm_out_file
);
10227 else if (TARGET_LOONGSON_EXT
)
10228 fputs ("\t.module\tloongson-ext\n", asm_out_file
);
10231 #ifdef HAVE_AS_GNU_ATTRIBUTE
10235 /* No floating-point operations, -mno-float. */
10236 if (TARGET_NO_FLOAT
)
10238 /* Soft-float code, -msoft-float. */
10239 else if (!TARGET_HARD_FLOAT_ABI
)
10241 /* Single-float code, -msingle-float. */
10242 else if (!TARGET_DOUBLE_FLOAT
)
10244 /* 64-bit FP registers on a 32-bit target, -mips32r2 -mfp64.
10246 This case used 12 callee-saved double-precision registers
10247 and is deprecated. */
10248 /* 64-bit or 32-bit FP registers on a 32-bit target, -mfpxx. */
10249 else if (TARGET_FLOATXX
)
10251 /* 64-bit FP registers on a 32-bit target, -mfp64 -modd-spreg. */
10252 else if (mips_abi
== ABI_32
&& TARGET_FLOAT64
&& TARGET_ODD_SPREG
)
10254 /* 64-bit FP registers on a 32-bit target, -mfp64 -mno-odd-spreg. */
10255 else if (mips_abi
== ABI_32
&& TARGET_FLOAT64
)
10257 /* Regular FP code, FP regs same size as GP regs, -mdouble-float. */
10261 fprintf (asm_out_file
, "\t.gnu_attribute 4, %d\n", attr
);
10265 fprintf (asm_out_file
, "\t.gnu_attribute 8, 1\n");
10270 /* If TARGET_ABICALLS, tell GAS to generate -KPIC code. */
10271 if (TARGET_ABICALLS
)
10273 fprintf (asm_out_file
, "\t.abicalls\n");
10274 if (TARGET_ABICALLS_PIC0
)
10275 fprintf (asm_out_file
, "\t.option\tpic0\n");
10278 if (flag_verbose_asm
)
10279 fprintf (asm_out_file
, "\n%s -G value = %d, Arch = %s, ISA = %d\n",
10281 mips_small_data_threshold
, mips_arch_info
->name
, mips_isa
);
10284 /* Implement TARGET_ASM_CODE_END. */
10287 mips_code_end (void)
10289 mips_finish_stub (&mips16_rdhwr_stub
);
10290 mips_finish_stub (&mips16_get_fcsr_stub
);
10291 mips_finish_stub (&mips16_set_fcsr_stub
);
10294 /* Make the last instruction frame-related and note that it performs
10295 the operation described by FRAME_PATTERN. */
10298 mips_set_frame_expr (rtx frame_pattern
)
10302 insn
= get_last_insn ();
10303 RTX_FRAME_RELATED_P (insn
) = 1;
10304 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
10309 /* Return a frame-related rtx that stores REG at MEM.
10310 REG must be a single register. */
10313 mips_frame_set (rtx mem
, rtx reg
)
10317 set
= gen_rtx_SET (mem
, reg
);
10318 RTX_FRAME_RELATED_P (set
) = 1;
10323 /* Record that the epilogue has restored call-saved register REG. */
10326 mips_add_cfa_restore (rtx reg
)
10328 mips_epilogue
.cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
10329 mips_epilogue
.cfa_restores
);
10332 /* If a MIPS16e SAVE or RESTORE instruction saves or restores register
10333 mips16e_s2_s8_regs[X], it must also save the registers in indexes
10334 X + 1 onwards. Likewise mips16e_a0_a3_regs. */
10335 static const unsigned char mips16e_s2_s8_regs
[] = {
10336 30, 23, 22, 21, 20, 19, 18
10338 static const unsigned char mips16e_a0_a3_regs
[] = {
10342 /* A list of the registers that can be saved by the MIPS16e SAVE instruction,
10343 ordered from the uppermost in memory to the lowest in memory. */
10344 static const unsigned char mips16e_save_restore_regs
[] = {
10345 31, 30, 23, 22, 21, 20, 19, 18, 17, 16, 7, 6, 5, 4
10348 /* Return the index of the lowest X in the range [0, SIZE) for which
10349 bit REGS[X] is set in MASK. Return SIZE if there is no such X. */
10351 static unsigned int
10352 mips16e_find_first_register (unsigned int mask
, const unsigned char *regs
,
10357 for (i
= 0; i
< size
; i
++)
10358 if (BITSET_P (mask
, regs
[i
]))
10364 /* *MASK_PTR is a mask of general-purpose registers and *NUM_REGS_PTR
10365 is the number of set bits. If *MASK_PTR contains REGS[X] for some X
10366 in [0, SIZE), adjust *MASK_PTR and *NUM_REGS_PTR so that the same
10367 is true for all indexes (X, SIZE). */
10370 mips16e_mask_registers (unsigned int *mask_ptr
, const unsigned char *regs
,
10371 unsigned int size
, unsigned int *num_regs_ptr
)
10375 i
= mips16e_find_first_register (*mask_ptr
, regs
, size
);
10376 for (i
++; i
< size
; i
++)
10377 if (!BITSET_P (*mask_ptr
, regs
[i
]))
10379 *num_regs_ptr
+= 1;
10380 *mask_ptr
|= 1 << regs
[i
];
10384 /* Return a simplified form of X using the register values in REG_VALUES.
10385 REG_VALUES[R] is the last value assigned to hard register R, or null
10386 if R has not been modified.
10388 This function is rather limited, but is good enough for our purposes. */
10391 mips16e_collect_propagate_value (rtx x
, rtx
*reg_values
)
10393 x
= avoid_constant_pool_reference (x
);
10397 rtx x0
= mips16e_collect_propagate_value (XEXP (x
, 0), reg_values
);
10398 return simplify_gen_unary (GET_CODE (x
), GET_MODE (x
),
10399 x0
, GET_MODE (XEXP (x
, 0)));
10402 if (ARITHMETIC_P (x
))
10404 rtx x0
= mips16e_collect_propagate_value (XEXP (x
, 0), reg_values
);
10405 rtx x1
= mips16e_collect_propagate_value (XEXP (x
, 1), reg_values
);
10406 return simplify_gen_binary (GET_CODE (x
), GET_MODE (x
), x0
, x1
);
10410 && reg_values
[REGNO (x
)]
10411 && !rtx_unstable_p (reg_values
[REGNO (x
)]))
10412 return reg_values
[REGNO (x
)];
10417 /* Return true if (set DEST SRC) stores an argument register into its
10418 caller-allocated save slot, storing the number of that argument
10419 register in *REGNO_PTR if so. REG_VALUES is as for
10420 mips16e_collect_propagate_value. */
10423 mips16e_collect_argument_save_p (rtx dest
, rtx src
, rtx
*reg_values
,
10424 unsigned int *regno_ptr
)
10426 unsigned int argno
, regno
;
10427 HOST_WIDE_INT offset
, required_offset
;
10430 /* Check that this is a word-mode store. */
10431 if (!MEM_P (dest
) || !REG_P (src
) || GET_MODE (dest
) != word_mode
)
10434 /* Check that the register being saved is an unmodified argument
10436 regno
= REGNO (src
);
10437 if (!IN_RANGE (regno
, GP_ARG_FIRST
, GP_ARG_LAST
) || reg_values
[regno
])
10439 argno
= regno
- GP_ARG_FIRST
;
10441 /* Check whether the address is an appropriate stack-pointer or
10442 frame-pointer access. */
10443 addr
= mips16e_collect_propagate_value (XEXP (dest
, 0), reg_values
);
10444 mips_split_plus (addr
, &base
, &offset
);
10445 required_offset
= cfun
->machine
->frame
.total_size
+ argno
* UNITS_PER_WORD
;
10446 if (base
== hard_frame_pointer_rtx
)
10447 required_offset
-= cfun
->machine
->frame
.hard_frame_pointer_offset
;
10448 else if (base
!= stack_pointer_rtx
)
10450 if (offset
!= required_offset
)
10453 *regno_ptr
= regno
;
10457 /* A subroutine of mips_expand_prologue, called only when generating
10458 MIPS16e SAVE instructions. Search the start of the function for any
10459 instructions that save argument registers into their caller-allocated
10460 save slots. Delete such instructions and return a value N such that
10461 saving [GP_ARG_FIRST, GP_ARG_FIRST + N) would make all the deleted
10462 instructions redundant. */
10464 static unsigned int
10465 mips16e_collect_argument_saves (void)
10467 rtx reg_values
[FIRST_PSEUDO_REGISTER
];
10468 rtx_insn
*insn
, *next
;
10469 rtx set
, dest
, src
;
10470 unsigned int nargs
, regno
;
10472 push_topmost_sequence ();
10474 memset (reg_values
, 0, sizeof (reg_values
));
10475 for (insn
= get_insns (); insn
; insn
= next
)
10477 next
= NEXT_INSN (insn
);
10478 if (NOTE_P (insn
) || DEBUG_INSN_P (insn
))
10481 if (!INSN_P (insn
))
10484 set
= PATTERN (insn
);
10485 if (GET_CODE (set
) != SET
)
10488 dest
= SET_DEST (set
);
10489 src
= SET_SRC (set
);
10490 if (mips16e_collect_argument_save_p (dest
, src
, reg_values
, ®no
))
10492 if (!BITSET_P (cfun
->machine
->frame
.mask
, regno
))
10494 delete_insn (insn
);
10495 nargs
= MAX (nargs
, (regno
- GP_ARG_FIRST
) + 1);
10498 else if (REG_P (dest
) && GET_MODE (dest
) == word_mode
)
10499 reg_values
[REGNO (dest
)]
10500 = mips16e_collect_propagate_value (src
, reg_values
);
10504 pop_topmost_sequence ();
10509 /* Return a move between register REGNO and memory location SP + OFFSET.
10510 REG_PARM_P is true if SP + OFFSET belongs to REG_PARM_STACK_SPACE.
10511 Make the move a load if RESTORE_P, otherwise make it a store. */
10514 mips16e_save_restore_reg (bool restore_p
, bool reg_parm_p
,
10515 HOST_WIDE_INT offset
, unsigned int regno
)
10519 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
, stack_pointer_rtx
,
10521 reg
= gen_rtx_REG (SImode
, regno
);
10524 mips_add_cfa_restore (reg
);
10525 return gen_rtx_SET (reg
, mem
);
10528 return gen_rtx_SET (mem
, reg
);
10529 return mips_frame_set (mem
, reg
);
10532 /* Return RTL for a MIPS16e SAVE or RESTORE instruction; RESTORE_P says which.
10533 The instruction must:
10535 - Allocate or deallocate SIZE bytes in total; SIZE is known
10538 - Save or restore as many registers in *MASK_PTR as possible.
10539 The instruction saves the first registers at the top of the
10540 allocated area, with the other registers below it.
10542 - Save NARGS argument registers above the allocated area.
10544 (NARGS is always zero if RESTORE_P.)
10546 The SAVE and RESTORE instructions cannot save and restore all general
10547 registers, so there may be some registers left over for the caller to
10548 handle. Destructively modify *MASK_PTR so that it contains the registers
10549 that still need to be saved or restored. The caller can save these
10550 registers in the memory immediately below *OFFSET_PTR, which is a
10551 byte offset from the bottom of the allocated stack area. */
10554 mips16e_build_save_restore (bool restore_p
, unsigned int *mask_ptr
,
10555 HOST_WIDE_INT
*offset_ptr
, unsigned int nargs
,
10556 HOST_WIDE_INT size
)
10559 HOST_WIDE_INT offset
, top_offset
;
10560 unsigned int i
, regno
;
10563 gcc_assert (cfun
->machine
->frame
.num_fp
== 0);
10565 /* Calculate the number of elements in the PARALLEL. We need one element
10566 for the stack adjustment, one for each argument register save, and one
10567 for each additional register move. */
10569 for (i
= 0; i
< ARRAY_SIZE (mips16e_save_restore_regs
); i
++)
10570 if (BITSET_P (*mask_ptr
, mips16e_save_restore_regs
[i
]))
10573 /* Create the final PARALLEL. */
10574 pattern
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (n
));
10577 /* Add the stack pointer adjustment. */
10578 set
= gen_rtx_SET (stack_pointer_rtx
,
10579 plus_constant (Pmode
, stack_pointer_rtx
,
10580 restore_p
? size
: -size
));
10581 RTX_FRAME_RELATED_P (set
) = 1;
10582 XVECEXP (pattern
, 0, n
++) = set
;
10584 /* Stack offsets in the PARALLEL are relative to the old stack pointer. */
10585 top_offset
= restore_p
? size
: 0;
10587 /* Save the arguments. */
10588 for (i
= 0; i
< nargs
; i
++)
10590 offset
= top_offset
+ i
* UNITS_PER_WORD
;
10591 set
= mips16e_save_restore_reg (restore_p
, true, offset
,
10593 XVECEXP (pattern
, 0, n
++) = set
;
10596 /* Then fill in the other register moves. */
10597 offset
= top_offset
;
10598 for (i
= 0; i
< ARRAY_SIZE (mips16e_save_restore_regs
); i
++)
10600 regno
= mips16e_save_restore_regs
[i
];
10601 if (BITSET_P (*mask_ptr
, regno
))
10603 offset
-= UNITS_PER_WORD
;
10604 set
= mips16e_save_restore_reg (restore_p
, false, offset
, regno
);
10605 XVECEXP (pattern
, 0, n
++) = set
;
10606 *mask_ptr
&= ~(1 << regno
);
10610 /* Tell the caller what offset it should use for the remaining registers. */
10611 *offset_ptr
= size
+ (offset
- top_offset
);
10613 gcc_assert (n
== XVECLEN (pattern
, 0));
10618 /* PATTERN is a PARALLEL whose first element adds ADJUST to the stack
10619 pointer. Return true if PATTERN matches the kind of instruction
10620 generated by mips16e_build_save_restore. If INFO is nonnull,
10621 initialize it when returning true. */
10624 mips16e_save_restore_pattern_p (rtx pattern
, HOST_WIDE_INT adjust
,
10625 struct mips16e_save_restore_info
*info
)
10627 unsigned int i
, nargs
, mask
, extra
;
10628 HOST_WIDE_INT top_offset
, save_offset
, offset
;
10629 rtx set
, reg
, mem
, base
;
10632 if (!GENERATE_MIPS16E_SAVE_RESTORE
)
10635 /* Stack offsets in the PARALLEL are relative to the old stack pointer. */
10636 top_offset
= adjust
> 0 ? adjust
: 0;
10638 /* Interpret all other members of the PARALLEL. */
10639 save_offset
= top_offset
- UNITS_PER_WORD
;
10643 for (n
= 1; n
< XVECLEN (pattern
, 0); n
++)
10645 /* Check that we have a SET. */
10646 set
= XVECEXP (pattern
, 0, n
);
10647 if (GET_CODE (set
) != SET
)
10650 /* Check that the SET is a load (if restoring) or a store
10652 mem
= adjust
> 0 ? SET_SRC (set
) : SET_DEST (set
);
10656 /* Check that the address is the sum of the stack pointer and a
10657 possibly-zero constant offset. */
10658 mips_split_plus (XEXP (mem
, 0), &base
, &offset
);
10659 if (base
!= stack_pointer_rtx
)
10662 /* Check that SET's other operand is a register. */
10663 reg
= adjust
> 0 ? SET_DEST (set
) : SET_SRC (set
);
10667 /* Check for argument saves. */
10668 if (offset
== top_offset
+ nargs
* UNITS_PER_WORD
10669 && REGNO (reg
) == GP_ARG_FIRST
+ nargs
)
10671 else if (offset
== save_offset
)
10673 while (mips16e_save_restore_regs
[i
++] != REGNO (reg
))
10674 if (i
== ARRAY_SIZE (mips16e_save_restore_regs
))
10677 mask
|= 1 << REGNO (reg
);
10678 save_offset
-= UNITS_PER_WORD
;
10684 /* Check that the restrictions on register ranges are met. */
10686 mips16e_mask_registers (&mask
, mips16e_s2_s8_regs
,
10687 ARRAY_SIZE (mips16e_s2_s8_regs
), &extra
);
10688 mips16e_mask_registers (&mask
, mips16e_a0_a3_regs
,
10689 ARRAY_SIZE (mips16e_a0_a3_regs
), &extra
);
10693 /* Make sure that the topmost argument register is not saved twice.
10694 The checks above ensure that the same is then true for the other
10695 argument registers. */
10696 if (nargs
> 0 && BITSET_P (mask
, GP_ARG_FIRST
+ nargs
- 1))
10699 /* Pass back information, if requested. */
10702 info
->nargs
= nargs
;
10704 info
->size
= (adjust
> 0 ? adjust
: -adjust
);
10710 /* Add a MIPS16e SAVE or RESTORE register-range argument to string S
10711 for the register range [MIN_REG, MAX_REG]. Return a pointer to
10712 the null terminator. */
10715 mips16e_add_register_range (char *s
, unsigned int min_reg
,
10716 unsigned int max_reg
)
10718 if (min_reg
!= max_reg
)
10719 s
+= sprintf (s
, ",%s-%s", reg_names
[min_reg
], reg_names
[max_reg
]);
10721 s
+= sprintf (s
, ",%s", reg_names
[min_reg
]);
10725 /* Return the assembly instruction for a MIPS16e SAVE or RESTORE instruction.
10726 PATTERN and ADJUST are as for mips16e_save_restore_pattern_p. */
10729 mips16e_output_save_restore (rtx pattern
, HOST_WIDE_INT adjust
)
10731 static char buffer
[300];
10733 struct mips16e_save_restore_info info
;
10734 unsigned int i
, end
;
10737 /* Parse the pattern. */
10738 if (!mips16e_save_restore_pattern_p (pattern
, adjust
, &info
))
10739 gcc_unreachable ();
10741 /* Add the mnemonic. */
10742 s
= strcpy (buffer
, adjust
> 0 ? "restore\t" : "save\t");
10745 /* Save the arguments. */
10746 if (info
.nargs
> 1)
10747 s
+= sprintf (s
, "%s-%s,", reg_names
[GP_ARG_FIRST
],
10748 reg_names
[GP_ARG_FIRST
+ info
.nargs
- 1]);
10749 else if (info
.nargs
== 1)
10750 s
+= sprintf (s
, "%s,", reg_names
[GP_ARG_FIRST
]);
10752 /* Emit the amount of stack space to allocate or deallocate. */
10753 s
+= sprintf (s
, "%d", (int) info
.size
);
10755 /* Save or restore $16. */
10756 if (BITSET_P (info
.mask
, 16))
10757 s
+= sprintf (s
, ",%s", reg_names
[GP_REG_FIRST
+ 16]);
10759 /* Save or restore $17. */
10760 if (BITSET_P (info
.mask
, 17))
10761 s
+= sprintf (s
, ",%s", reg_names
[GP_REG_FIRST
+ 17]);
10763 /* Save or restore registers in the range $s2...$s8, which
10764 mips16e_s2_s8_regs lists in decreasing order. Note that this
10765 is a software register range; the hardware registers are not
10766 numbered consecutively. */
10767 end
= ARRAY_SIZE (mips16e_s2_s8_regs
);
10768 i
= mips16e_find_first_register (info
.mask
, mips16e_s2_s8_regs
, end
);
10770 s
= mips16e_add_register_range (s
, mips16e_s2_s8_regs
[end
- 1],
10771 mips16e_s2_s8_regs
[i
]);
10773 /* Save or restore registers in the range $a0...$a3. */
10774 end
= ARRAY_SIZE (mips16e_a0_a3_regs
);
10775 i
= mips16e_find_first_register (info
.mask
, mips16e_a0_a3_regs
, end
);
10777 s
= mips16e_add_register_range (s
, mips16e_a0_a3_regs
[i
],
10778 mips16e_a0_a3_regs
[end
- 1]);
10780 /* Save or restore $31. */
10781 if (BITSET_P (info
.mask
, RETURN_ADDR_REGNUM
))
10782 s
+= sprintf (s
, ",%s", reg_names
[RETURN_ADDR_REGNUM
]);
10787 /* Return true if the current function returns its value in a floating-point
10788 register in MIPS16 mode. */
10791 mips16_cfun_returns_in_fpr_p (void)
10793 tree return_type
= DECL_RESULT (current_function_decl
);
10794 return (TARGET_MIPS16
10795 && TARGET_HARD_FLOAT_ABI
10796 && !aggregate_value_p (return_type
, current_function_decl
)
10797 && mips_return_mode_in_fpr_p (DECL_MODE (return_type
)));
10800 /* Return true if predicate PRED is true for at least one instruction.
10801 Cache the result in *CACHE, and assume that the result is true
10802 if *CACHE is already true. */
10805 mips_find_gp_ref (bool *cache
, bool (*pred
) (rtx_insn
*))
10807 rtx_insn
*insn
, *subinsn
;
10811 push_topmost_sequence ();
10812 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
10813 FOR_EACH_SUBINSN (subinsn
, insn
)
10814 if (USEFUL_INSN_P (subinsn
) && pred (subinsn
))
10819 pop_topmost_sequence ();
10824 /* Return true if INSN refers to the global pointer in an "inflexible" way.
10825 See mips_cfun_has_inflexible_gp_ref_p for details. */
10828 mips_insn_has_inflexible_gp_ref_p (rtx_insn
*insn
)
10830 /* Uses of pic_offset_table_rtx in CALL_INSN_FUNCTION_USAGE
10831 indicate that the target could be a traditional MIPS
10832 lazily-binding stub. */
10833 return find_reg_fusage (insn
, USE
, pic_offset_table_rtx
);
10836 /* Return true if the current function refers to the global pointer
10837 in a way that forces $28 to be valid. This means that we can't
10838 change the choice of global pointer, even for NewABI code.
10840 One example of this (and one which needs several checks) is that
10841 $28 must be valid when calling traditional MIPS lazy-binding stubs.
10842 (This restriction does not apply to PLTs.) */
10845 mips_cfun_has_inflexible_gp_ref_p (void)
10847 /* If the function has a nonlocal goto, $28 must hold the correct
10848 global pointer for the target function. That is, the target
10849 of the goto implicitly uses $28. */
10850 if (crtl
->has_nonlocal_goto
)
10853 if (TARGET_ABICALLS_PIC2
)
10855 /* Symbolic accesses implicitly use the global pointer unless
10856 -mexplicit-relocs is in effect. JAL macros to symbolic addresses
10857 might go to traditional MIPS lazy-binding stubs. */
10858 if (!TARGET_EXPLICIT_RELOCS
)
10861 /* FUNCTION_PROFILER includes a JAL to _mcount, which again
10862 can be lazily-bound. */
10866 /* MIPS16 functions that return in FPRs need to call an
10867 external libgcc routine. This call is only made explict
10868 during mips_expand_epilogue, and it too might be lazily bound. */
10869 if (mips16_cfun_returns_in_fpr_p ())
10873 return mips_find_gp_ref (&cfun
->machine
->has_inflexible_gp_insn_p
,
10874 mips_insn_has_inflexible_gp_ref_p
);
10877 /* Return true if INSN refers to the global pointer in a "flexible" way.
10878 See mips_cfun_has_flexible_gp_ref_p for details. */
10881 mips_insn_has_flexible_gp_ref_p (rtx_insn
*insn
)
10883 return (get_attr_got (insn
) != GOT_UNSET
10884 || mips_small_data_pattern_p (PATTERN (insn
))
10885 || reg_overlap_mentioned_p (pic_offset_table_rtx
, PATTERN (insn
)));
10888 /* Return true if the current function references the global pointer,
10889 but if those references do not inherently require the global pointer
10890 to be $28. Assume !mips_cfun_has_inflexible_gp_ref_p (). */
10893 mips_cfun_has_flexible_gp_ref_p (void)
10895 /* Reload can sometimes introduce constant pool references
10896 into a function that otherwise didn't need them. For example,
10897 suppose we have an instruction like:
10899 (set (reg:DF R1) (float:DF (reg:SI R2)))
10901 If R2 turns out to be a constant such as 1, the instruction may
10902 have a REG_EQUAL note saying that R1 == 1.0. Reload then has
10903 the option of using this constant if R2 doesn't get allocated
10906 In cases like these, reload will have added the constant to the
10907 pool but no instruction will yet refer to it. */
10908 if (TARGET_ABICALLS_PIC2
&& !reload_completed
&& crtl
->uses_const_pool
)
10911 return mips_find_gp_ref (&cfun
->machine
->has_flexible_gp_insn_p
,
10912 mips_insn_has_flexible_gp_ref_p
);
10915 /* Return the register that should be used as the global pointer
10916 within this function. Return INVALID_REGNUM if the function
10917 doesn't need a global pointer. */
10919 static unsigned int
10920 mips_global_pointer (void)
10922 unsigned int regno
;
10924 /* $gp is always available unless we're using a GOT. */
10925 if (!TARGET_USE_GOT
)
10926 return GLOBAL_POINTER_REGNUM
;
10928 /* If there are inflexible references to $gp, we must use the
10929 standard register. */
10930 if (mips_cfun_has_inflexible_gp_ref_p ())
10931 return GLOBAL_POINTER_REGNUM
;
10933 /* If there are no current references to $gp, then the only uses
10934 we can introduce later are those involved in long branches. */
10935 if (TARGET_ABSOLUTE_JUMPS
&& !mips_cfun_has_flexible_gp_ref_p ())
10936 return INVALID_REGNUM
;
10938 /* If the global pointer is call-saved, try to use a call-clobbered
10940 if (TARGET_CALL_SAVED_GP
&& crtl
->is_leaf
)
10941 for (regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
10942 if (!df_regs_ever_live_p (regno
)
10943 && call_used_regs
[regno
]
10944 && !fixed_regs
[regno
]
10945 && regno
!= PIC_FUNCTION_ADDR_REGNUM
)
10948 return GLOBAL_POINTER_REGNUM
;
10951 /* Return true if the current function's prologue must load the global
10952 pointer value into pic_offset_table_rtx and store the same value in
10953 the function's cprestore slot (if any).
10955 One problem we have to deal with is that, when emitting GOT-based
10956 position independent code, long-branch sequences will need to load
10957 the address of the branch target from the GOT. We don't know until
10958 the very end of compilation whether (and where) the function needs
10959 long branches, so we must ensure that _any_ branch can access the
10960 global pointer in some form. However, we do not want to pessimize
10961 the usual case in which all branches are short.
10963 We handle this as follows:
10965 (1) During reload, we set cfun->machine->global_pointer to
10966 INVALID_REGNUM if we _know_ that the current function
10967 doesn't need a global pointer. This is only valid if
10968 long branches don't need the GOT.
10970 Otherwise, we assume that we might need a global pointer
10971 and pick an appropriate register.
10973 (2) If cfun->machine->global_pointer != INVALID_REGNUM,
10974 we ensure that the global pointer is available at every
10975 block boundary bar entry and exit. We do this in one of two ways:
10977 - If the function has a cprestore slot, we ensure that this
10978 slot is valid at every branch. However, as explained in
10979 point (6) below, there is no guarantee that pic_offset_table_rtx
10980 itself is valid if new uses of the global pointer are introduced
10981 after the first post-epilogue split.
10983 We guarantee that the cprestore slot is valid by loading it
10984 into a fake register, CPRESTORE_SLOT_REGNUM. We then make
10985 this register live at every block boundary bar function entry
10986 and exit. It is then invalid to move the load (and thus the
10987 preceding store) across a block boundary.
10989 - If the function has no cprestore slot, we guarantee that
10990 pic_offset_table_rtx itself is valid at every branch.
10992 See mips_eh_uses for the handling of the register liveness.
10994 (3) During prologue and epilogue generation, we emit "ghost"
10995 placeholder instructions to manipulate the global pointer.
10997 (4) During prologue generation, we set cfun->machine->must_initialize_gp_p
10998 and cfun->machine->must_restore_gp_when_clobbered_p if we already know
10999 that the function needs a global pointer. (There is no need to set
11000 them earlier than this, and doing it as late as possible leads to
11001 fewer false positives.)
11003 (5) If cfun->machine->must_initialize_gp_p is true during a
11004 split_insns pass, we split the ghost instructions into real
11005 instructions. These split instructions can then be optimized in
11006 the usual way. Otherwise, we keep the ghost instructions intact,
11007 and optimize for the case where they aren't needed. We still
11008 have the option of splitting them later, if we need to introduce
11009 new uses of the global pointer.
11011 For example, the scheduler ignores a ghost instruction that
11012 stores $28 to the stack, but it handles the split form of
11013 the ghost instruction as an ordinary store.
11015 (6) [OldABI only.] If cfun->machine->must_restore_gp_when_clobbered_p
11016 is true during the first post-epilogue split_insns pass, we split
11017 calls and restore_gp patterns into instructions that explicitly
11018 load pic_offset_table_rtx from the cprestore slot. Otherwise,
11019 we split these patterns into instructions that _don't_ load from
11020 the cprestore slot.
11022 If cfun->machine->must_restore_gp_when_clobbered_p is true at the
11023 time of the split, then any instructions that exist at that time
11024 can make free use of pic_offset_table_rtx. However, if we want
11025 to introduce new uses of the global pointer after the split,
11026 we must explicitly load the value from the cprestore slot, since
11027 pic_offset_table_rtx itself might not be valid at a given point
11030 The idea is that we want to be able to delete redundant
11031 loads from the cprestore slot in the usual case where no
11032 long branches are needed.
11034 (7) If cfun->machine->must_initialize_gp_p is still false at the end
11035 of md_reorg, we decide whether the global pointer is needed for
11036 long branches. If so, we set cfun->machine->must_initialize_gp_p
11037 to true and split the ghost instructions into real instructions
11040 Note that the ghost instructions must have a zero length for three reasons:
11042 - Giving the length of the underlying $gp sequence might cause
11043 us to use long branches in cases where they aren't really needed.
11045 - They would perturb things like alignment calculations.
11047 - More importantly, the hazard detection in md_reorg relies on
11048 empty instructions having a zero length.
11050 If we find a long branch and split the ghost instructions at the
11051 end of md_reorg, the split could introduce more long branches.
11052 That isn't a problem though, because we still do the split before
11053 the final shorten_branches pass.
11055 This is extremely ugly, but it seems like the best compromise between
11056 correctness and efficiency. */
11059 mips_must_initialize_gp_p (void)
11061 return cfun
->machine
->must_initialize_gp_p
;
11064 /* Return true if REGNO is a register that is ordinarily call-clobbered
11065 but must nevertheless be preserved by an interrupt handler. */
11068 mips_interrupt_extra_call_saved_reg_p (unsigned int regno
)
11070 if ((ISA_HAS_HILO
|| TARGET_DSP
)
11071 && MD_REG_P (regno
))
11074 if (TARGET_DSP
&& DSP_ACC_REG_P (regno
))
11077 if (GP_REG_P (regno
)
11078 && cfun
->machine
->use_shadow_register_set
== SHADOW_SET_NO
)
11080 /* $0 is hard-wired. */
11081 if (regno
== GP_REG_FIRST
)
11084 /* The interrupt handler can treat kernel registers as
11085 scratch registers. */
11086 if (KERNEL_REG_P (regno
))
11089 /* The function will return the stack pointer to its original value
11091 if (regno
== STACK_POINTER_REGNUM
)
11094 /* Otherwise, return true for registers that aren't ordinarily
11096 return call_used_regs
[regno
];
11102 /* Return true if the current function should treat register REGNO
11106 mips_cfun_call_saved_reg_p (unsigned int regno
)
11108 /* If the user makes an ordinarily-call-saved register global,
11109 that register is no longer call-saved. */
11110 if (global_regs
[regno
])
11113 /* Interrupt handlers need to save extra registers. */
11114 if (cfun
->machine
->interrupt_handler_p
11115 && mips_interrupt_extra_call_saved_reg_p (regno
))
11118 /* call_insns preserve $28 unless they explicitly say otherwise,
11119 so call_used_regs[] treats $28 as call-saved. However,
11120 we want the ABI property rather than the default call_insn
11122 return (regno
== GLOBAL_POINTER_REGNUM
11123 ? TARGET_CALL_SAVED_GP
11124 : !call_used_regs
[regno
]);
11127 /* Return true if the function body might clobber register REGNO.
11128 We know that REGNO is call-saved. */
11131 mips_cfun_might_clobber_call_saved_reg_p (unsigned int regno
)
11133 /* Some functions should be treated as clobbering all call-saved
11135 if (crtl
->saves_all_registers
)
11138 /* DF handles cases where a register is explicitly referenced in
11139 the rtl. Incoming values are passed in call-clobbered registers,
11140 so we can assume that any live call-saved register is set within
11142 if (df_regs_ever_live_p (regno
))
11145 /* Check for registers that are clobbered by FUNCTION_PROFILER.
11146 These clobbers are not explicit in the rtl. */
11147 if (crtl
->profile
&& MIPS_SAVE_REG_FOR_PROFILING_P (regno
))
11150 /* If we're using a call-saved global pointer, the function's
11151 prologue will need to set it up. */
11152 if (cfun
->machine
->global_pointer
== regno
)
11155 /* The function's prologue will need to set the frame pointer if
11156 frame_pointer_needed. */
11157 if (regno
== HARD_FRAME_POINTER_REGNUM
&& frame_pointer_needed
)
11160 /* If a MIPS16 function returns a value in FPRs, its epilogue
11161 will need to call an external libgcc routine. This yet-to-be
11162 generated call_insn will clobber $31. */
11163 if (regno
== RETURN_ADDR_REGNUM
&& mips16_cfun_returns_in_fpr_p ())
11166 /* If REGNO is ordinarily call-clobbered, we must assume that any
11167 called function could modify it. */
11168 if (cfun
->machine
->interrupt_handler_p
11170 && mips_interrupt_extra_call_saved_reg_p (regno
))
11176 /* Return true if the current function must save register REGNO. */
11179 mips_save_reg_p (unsigned int regno
)
11181 if (mips_cfun_call_saved_reg_p (regno
))
11183 if (mips_cfun_might_clobber_call_saved_reg_p (regno
))
11186 /* Save both registers in an FPR pair if either one is used. This is
11187 needed for the case when MIN_FPRS_PER_FMT == 1, which allows the odd
11188 register to be used without the even register. */
11189 if (FP_REG_P (regno
)
11190 && MAX_FPRS_PER_FMT
== 2
11191 && mips_cfun_might_clobber_call_saved_reg_p (regno
+ 1))
11195 /* We need to save the incoming return address if __builtin_eh_return
11196 is being used to set a different return address. */
11197 if (regno
== RETURN_ADDR_REGNUM
&& crtl
->calls_eh_return
)
11203 /* Populate the current function's mips_frame_info structure.
11205 MIPS stack frames look like:
11207 +-------------------------------+
11209 | incoming stack arguments |
11211 +-------------------------------+
11213 | caller-allocated save area |
11214 A | for register arguments |
11216 +-------------------------------+ <-- incoming stack pointer
11218 | callee-allocated save area |
11219 B | for arguments that are |
11220 | split between registers and |
11223 +-------------------------------+ <-- arg_pointer_rtx
11225 C | callee-allocated save area |
11226 | for register varargs |
11228 +-------------------------------+ <-- frame_pointer_rtx
11229 | | + cop0_sp_offset
11230 | COP0 reg save area | + UNITS_PER_WORD
11232 +-------------------------------+ <-- frame_pointer_rtx + acc_sp_offset
11233 | | + UNITS_PER_WORD
11234 | accumulator save area |
11236 +-------------------------------+ <-- stack_pointer_rtx + fp_sp_offset
11237 | | + UNITS_PER_HWFPVALUE
11240 +-------------------------------+ <-- stack_pointer_rtx + gp_sp_offset
11241 | | + UNITS_PER_WORD
11244 +-------------------------------+ <-- frame_pointer_rtx with
11245 | | \ -fstack-protector
11246 | local variables | | var_size
11248 +-------------------------------+
11250 | $gp save area | | cprestore_size
11252 P +-------------------------------+ <-- hard_frame_pointer_rtx for
11254 | outgoing stack arguments | |
11256 +-------------------------------+ | args_size
11258 | caller-allocated save area | |
11259 | for register arguments | |
11261 +-------------------------------+ <-- stack_pointer_rtx
11262 frame_pointer_rtx without
11264 hard_frame_pointer_rtx for
11267 At least two of A, B and C will be empty.
11269 Dynamic stack allocations such as alloca insert data at point P.
11270 They decrease stack_pointer_rtx but leave frame_pointer_rtx and
11271 hard_frame_pointer_rtx unchanged. */
11274 mips_compute_frame_info (void)
11276 struct mips_frame_info
*frame
;
11277 HOST_WIDE_INT offset
, size
;
11278 unsigned int regno
, i
;
11280 /* Skip re-computing the frame info after reload completed. */
11281 if (reload_completed
)
11284 /* Set this function's interrupt properties. */
11285 if (mips_interrupt_type_p (TREE_TYPE (current_function_decl
)))
11287 if (mips_isa_rev
< 2)
11288 error ("the %<interrupt%> attribute requires a MIPS32r2 processor or greater");
11289 else if (TARGET_MIPS16
)
11290 error ("interrupt handlers cannot be MIPS16 functions");
11293 cfun
->machine
->interrupt_handler_p
= true;
11294 cfun
->machine
->int_mask
=
11295 mips_interrupt_mask (TREE_TYPE (current_function_decl
));
11296 cfun
->machine
->use_shadow_register_set
=
11297 mips_use_shadow_register_set (TREE_TYPE (current_function_decl
));
11298 cfun
->machine
->keep_interrupts_masked_p
=
11299 mips_keep_interrupts_masked_p (TREE_TYPE (current_function_decl
));
11300 cfun
->machine
->use_debug_exception_return_p
=
11301 mips_use_debug_exception_return_p (TREE_TYPE
11302 (current_function_decl
));
11306 frame
= &cfun
->machine
->frame
;
11307 memset (frame
, 0, sizeof (*frame
));
11308 size
= get_frame_size ();
11310 /* The first two blocks contain the outgoing argument area and the $gp save
11311 slot. This area isn't needed in leaf functions. We can also skip it
11312 if we know that none of the called functions will use this space.
11314 But if the target-independent frame size is nonzero, we have already
11315 committed to allocating these in TARGET_STARTING_FRAME_OFFSET for
11316 !FRAME_GROWS_DOWNWARD. */
11318 if ((size
== 0 || FRAME_GROWS_DOWNWARD
)
11319 && (crtl
->is_leaf
|| (cfun
->machine
->optimize_call_stack
&& !flag_pic
)))
11321 /* The MIPS 3.0 linker does not like functions that dynamically
11322 allocate the stack and have 0 for STACK_DYNAMIC_OFFSET, since it
11323 looks like we are trying to create a second frame pointer to the
11324 function, so allocate some stack space to make it happy. */
11325 if (cfun
->calls_alloca
)
11326 frame
->args_size
= REG_PARM_STACK_SPACE (cfun
->decl
);
11328 frame
->args_size
= 0;
11329 frame
->cprestore_size
= 0;
11333 frame
->args_size
= crtl
->outgoing_args_size
;
11334 frame
->cprestore_size
= MIPS_GP_SAVE_AREA_SIZE
;
11337 /* MIPS16 code offsets the frame pointer by the size of the outgoing
11338 arguments. This tends to increase the chances of using unextended
11339 instructions for local variables and incoming arguments. */
11341 frame
->hard_frame_pointer_offset
= frame
->args_size
;
11343 /* PR 69129 / 69012: Beware of a possible race condition. mips_global_pointer
11344 might call mips_cfun_has_inflexible_gp_ref_p which in turn can call
11345 mips_find_gp_ref which will iterate over the current insn sequence.
11346 If any of these insns use the cprestore_save_slot_operand or
11347 cprestore_load_slot_operand predicates in order to be recognised then
11348 they will call mips_cprestore_address_p which calls
11349 mips_get_cprestore_base_and_offset which expects the frame information
11350 to be filled in... In fact mips_get_cprestore_base_and_offset only
11351 needs the args_size and hard_frame_pointer_offset fields to be filled
11352 in, which is why the global_pointer field is initialised here and not
11354 cfun
->machine
->global_pointer
= mips_global_pointer ();
11356 offset
= frame
->args_size
+ frame
->cprestore_size
;
11358 /* Move above the local variables. */
11359 frame
->var_size
= MIPS_STACK_ALIGN (size
);
11360 offset
+= frame
->var_size
;
11362 /* Find out which GPRs we need to save. */
11363 for (regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
11364 if (mips_save_reg_p (regno
))
11367 frame
->mask
|= 1 << (regno
- GP_REG_FIRST
);
11370 /* If this function calls eh_return, we must also save and restore the
11371 EH data registers. */
11372 if (crtl
->calls_eh_return
)
11373 for (i
= 0; EH_RETURN_DATA_REGNO (i
) != INVALID_REGNUM
; i
++)
11376 frame
->mask
|= 1 << (EH_RETURN_DATA_REGNO (i
) - GP_REG_FIRST
);
11379 /* The MIPS16e SAVE and RESTORE instructions have two ranges of registers:
11380 $a3-$a0 and $s2-$s8. If we save one register in the range, we must
11381 save all later registers too. */
11382 if (GENERATE_MIPS16E_SAVE_RESTORE
)
11384 mips16e_mask_registers (&frame
->mask
, mips16e_s2_s8_regs
,
11385 ARRAY_SIZE (mips16e_s2_s8_regs
), &frame
->num_gp
);
11386 mips16e_mask_registers (&frame
->mask
, mips16e_a0_a3_regs
,
11387 ARRAY_SIZE (mips16e_a0_a3_regs
), &frame
->num_gp
);
11390 /* Move above the GPR save area. */
11391 if (frame
->num_gp
> 0)
11393 offset
+= MIPS_STACK_ALIGN (frame
->num_gp
* UNITS_PER_WORD
);
11394 frame
->gp_sp_offset
= offset
- UNITS_PER_WORD
;
11397 /* Find out which FPRs we need to save. This loop must iterate over
11398 the same space as its companion in mips_for_each_saved_gpr_and_fpr. */
11399 if (TARGET_HARD_FLOAT
)
11400 for (regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
+= MAX_FPRS_PER_FMT
)
11401 if (mips_save_reg_p (regno
))
11403 frame
->num_fp
+= MAX_FPRS_PER_FMT
;
11404 frame
->fmask
|= ~(~0U << MAX_FPRS_PER_FMT
) << (regno
- FP_REG_FIRST
);
11407 /* Move above the FPR save area. */
11408 if (frame
->num_fp
> 0)
11410 offset
+= MIPS_STACK_ALIGN (frame
->num_fp
* UNITS_PER_FPREG
);
11411 frame
->fp_sp_offset
= offset
- UNITS_PER_HWFPVALUE
;
11414 /* Add in space for the interrupt context information. */
11415 if (cfun
->machine
->interrupt_handler_p
)
11418 if (mips_save_reg_p (LO_REGNUM
) || mips_save_reg_p (HI_REGNUM
))
11421 frame
->acc_mask
|= (1 << 0);
11424 /* Check accumulators 1, 2, 3. */
11425 for (i
= DSP_ACC_REG_FIRST
; i
<= DSP_ACC_REG_LAST
; i
+= 2)
11426 if (mips_save_reg_p (i
) || mips_save_reg_p (i
+ 1))
11429 frame
->acc_mask
|= 1 << (((i
- DSP_ACC_REG_FIRST
) / 2) + 1);
11432 /* All interrupt context functions need space to preserve STATUS. */
11433 frame
->num_cop0_regs
++;
11435 /* We need to save EPC regardless of whether interrupts remain masked
11436 as exceptions will corrupt EPC. */
11437 frame
->num_cop0_regs
++;
11440 /* Move above the accumulator save area. */
11441 if (frame
->num_acc
> 0)
11443 /* Each accumulator needs 2 words. */
11444 offset
+= frame
->num_acc
* 2 * UNITS_PER_WORD
;
11445 frame
->acc_sp_offset
= offset
- UNITS_PER_WORD
;
11448 /* Move above the COP0 register save area. */
11449 if (frame
->num_cop0_regs
> 0)
11451 offset
+= frame
->num_cop0_regs
* UNITS_PER_WORD
;
11452 frame
->cop0_sp_offset
= offset
- UNITS_PER_WORD
;
11455 /* Determine if we can save the callee-saved registers in the frame
11456 header. Restrict this to functions where there is no other reason
11457 to allocate stack space so that we can eliminate the instructions
11458 that modify the stack pointer. */
11462 && flag_frame_header_optimization
11463 && !MAIN_NAME_P (DECL_NAME (current_function_decl
))
11464 && cfun
->machine
->varargs_size
== 0
11465 && crtl
->args
.pretend_args_size
== 0
11466 && frame
->var_size
== 0
11467 && frame
->num_acc
== 0
11468 && frame
->num_cop0_regs
== 0
11469 && frame
->num_fp
== 0
11470 && frame
->num_gp
> 0
11471 && frame
->num_gp
<= MAX_ARGS_IN_REGISTERS
11472 && !GENERATE_MIPS16E_SAVE_RESTORE
11473 && !cfun
->machine
->interrupt_handler_p
11474 && cfun
->machine
->does_not_use_frame_header
11475 && cfun
->machine
->optimize_call_stack
11476 && !cfun
->machine
->callers_may_not_allocate_frame
11477 && !mips_cfun_has_cprestore_slot_p ())
11480 frame
->gp_sp_offset
= REG_PARM_STACK_SPACE(cfun
) - UNITS_PER_WORD
;
11481 cfun
->machine
->use_frame_header_for_callee_saved_regs
= true;
11484 /* Move above the callee-allocated varargs save area. */
11485 offset
+= MIPS_STACK_ALIGN (cfun
->machine
->varargs_size
);
11486 frame
->arg_pointer_offset
= offset
;
11488 /* Move above the callee-allocated area for pretend stack arguments. */
11489 offset
+= crtl
->args
.pretend_args_size
;
11490 frame
->total_size
= offset
;
11492 /* Work out the offsets of the save areas from the top of the frame. */
11493 if (frame
->gp_sp_offset
> 0)
11494 frame
->gp_save_offset
= frame
->gp_sp_offset
- offset
;
11495 if (frame
->fp_sp_offset
> 0)
11496 frame
->fp_save_offset
= frame
->fp_sp_offset
- offset
;
11497 if (frame
->acc_sp_offset
> 0)
11498 frame
->acc_save_offset
= frame
->acc_sp_offset
- offset
;
11499 if (frame
->num_cop0_regs
> 0)
11500 frame
->cop0_save_offset
= frame
->cop0_sp_offset
- offset
;
11503 /* Return the style of GP load sequence that is being used for the
11504 current function. */
11506 enum mips_loadgp_style
11507 mips_current_loadgp_style (void)
11509 if (!TARGET_USE_GOT
|| cfun
->machine
->global_pointer
== INVALID_REGNUM
)
11510 return LOADGP_NONE
;
11512 if (TARGET_RTP_PIC
)
11515 if (TARGET_ABSOLUTE_ABICALLS
)
11516 return LOADGP_ABSOLUTE
;
11518 return TARGET_NEWABI
? LOADGP_NEWABI
: LOADGP_OLDABI
;
11521 /* Implement TARGET_FRAME_POINTER_REQUIRED. */
11524 mips_frame_pointer_required (void)
11526 /* If the function contains dynamic stack allocations, we need to
11527 use the frame pointer to access the static parts of the frame. */
11528 if (cfun
->calls_alloca
)
11531 /* In MIPS16 mode, we need a frame pointer for a large frame; otherwise,
11532 reload may be unable to compute the address of a local variable,
11533 since there is no way to add a large constant to the stack pointer
11534 without using a second temporary register. */
11537 mips_compute_frame_info ();
11538 if (!SMALL_OPERAND (cfun
->machine
->frame
.total_size
))
11545 /* Make sure that we're not trying to eliminate to the wrong hard frame
11549 mips_can_eliminate (const int from ATTRIBUTE_UNUSED
, const int to
)
11551 return (to
== HARD_FRAME_POINTER_REGNUM
|| to
== STACK_POINTER_REGNUM
);
11554 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame pointer
11555 or argument pointer. TO is either the stack pointer or hard frame
11559 mips_initial_elimination_offset (int from
, int to
)
11561 HOST_WIDE_INT offset
;
11563 mips_compute_frame_info ();
11565 /* Set OFFSET to the offset from the end-of-prologue stack pointer. */
11568 case FRAME_POINTER_REGNUM
:
11569 if (FRAME_GROWS_DOWNWARD
)
11570 offset
= (cfun
->machine
->frame
.args_size
11571 + cfun
->machine
->frame
.cprestore_size
11572 + cfun
->machine
->frame
.var_size
);
11577 case ARG_POINTER_REGNUM
:
11578 offset
= cfun
->machine
->frame
.arg_pointer_offset
;
11582 gcc_unreachable ();
11585 if (to
== HARD_FRAME_POINTER_REGNUM
)
11586 offset
-= cfun
->machine
->frame
.hard_frame_pointer_offset
;
11591 /* Implement TARGET_EXTRA_LIVE_ON_ENTRY. */
11594 mips_extra_live_on_entry (bitmap regs
)
11596 if (TARGET_USE_GOT
)
11598 /* PIC_FUNCTION_ADDR_REGNUM is live if we need it to set up
11599 the global pointer. */
11600 if (!TARGET_ABSOLUTE_ABICALLS
)
11601 bitmap_set_bit (regs
, PIC_FUNCTION_ADDR_REGNUM
);
11603 /* The prologue may set MIPS16_PIC_TEMP_REGNUM to the value of
11604 the global pointer. */
11606 bitmap_set_bit (regs
, MIPS16_PIC_TEMP_REGNUM
);
11608 /* See the comment above load_call<mode> for details. */
11609 bitmap_set_bit (regs
, GOT_VERSION_REGNUM
);
11613 /* Implement RETURN_ADDR_RTX. We do not support moving back to a
11617 mips_return_addr (int count
, rtx frame ATTRIBUTE_UNUSED
)
11622 return get_hard_reg_initial_val (Pmode
, RETURN_ADDR_REGNUM
);
11625 /* Emit code to change the current function's return address to
11626 ADDRESS. SCRATCH is available as a scratch register, if needed.
11627 ADDRESS and SCRATCH are both word-mode GPRs. */
11630 mips_set_return_address (rtx address
, rtx scratch
)
11634 gcc_assert (BITSET_P (cfun
->machine
->frame
.mask
, RETURN_ADDR_REGNUM
));
11635 slot_address
= mips_add_offset (scratch
, stack_pointer_rtx
,
11636 cfun
->machine
->frame
.gp_sp_offset
);
11637 mips_emit_move (gen_frame_mem (GET_MODE (address
), slot_address
), address
);
11640 /* Return true if the current function has a cprestore slot. */
11643 mips_cfun_has_cprestore_slot_p (void)
11645 return (cfun
->machine
->global_pointer
!= INVALID_REGNUM
11646 && cfun
->machine
->frame
.cprestore_size
> 0);
11649 /* Fill *BASE and *OFFSET such that *BASE + *OFFSET refers to the
11650 cprestore slot. LOAD_P is true if the caller wants to load from
11651 the cprestore slot; it is false if the caller wants to store to
11655 mips_get_cprestore_base_and_offset (rtx
*base
, HOST_WIDE_INT
*offset
,
11658 const struct mips_frame_info
*frame
;
11660 frame
= &cfun
->machine
->frame
;
11661 /* .cprestore always uses the stack pointer instead of the frame pointer.
11662 We have a free choice for direct stores for non-MIPS16 functions,
11663 and for MIPS16 functions whose cprestore slot is in range of the
11664 stack pointer. Using the stack pointer would sometimes give more
11665 (early) scheduling freedom, but using the frame pointer would
11666 sometimes give more (late) scheduling freedom. It's hard to
11667 predict which applies to a given function, so let's keep things
11670 Loads must always use the frame pointer in functions that call
11671 alloca, and there's little benefit to using the stack pointer
11673 if (frame_pointer_needed
&& !(TARGET_CPRESTORE_DIRECTIVE
&& !load_p
))
11675 *base
= hard_frame_pointer_rtx
;
11676 *offset
= frame
->args_size
- frame
->hard_frame_pointer_offset
;
11680 *base
= stack_pointer_rtx
;
11681 *offset
= frame
->args_size
;
11685 /* Return true if X is the load or store address of the cprestore slot;
11686 LOAD_P says which. */
11689 mips_cprestore_address_p (rtx x
, bool load_p
)
11691 rtx given_base
, required_base
;
11692 HOST_WIDE_INT given_offset
, required_offset
;
11694 mips_split_plus (x
, &given_base
, &given_offset
);
11695 mips_get_cprestore_base_and_offset (&required_base
, &required_offset
, load_p
);
11696 return given_base
== required_base
&& given_offset
== required_offset
;
11699 /* Return a MEM rtx for the cprestore slot. LOAD_P is true if we are
11700 going to load from it, false if we are going to store to it.
11701 Use TEMP as a temporary register if need be. */
11704 mips_cprestore_slot (rtx temp
, bool load_p
)
11707 HOST_WIDE_INT offset
;
11709 mips_get_cprestore_base_and_offset (&base
, &offset
, load_p
);
11710 return gen_frame_mem (Pmode
, mips_add_offset (temp
, base
, offset
));
11713 /* Emit instructions to save global pointer value GP into cprestore
11714 slot MEM. OFFSET is the offset that MEM applies to the base register.
11716 MEM may not be a legitimate address. If it isn't, TEMP is a
11717 temporary register that can be used, otherwise it is a SCRATCH. */
11720 mips_save_gp_to_cprestore_slot (rtx mem
, rtx offset
, rtx gp
, rtx temp
)
11722 if (TARGET_CPRESTORE_DIRECTIVE
)
11724 gcc_assert (gp
== pic_offset_table_rtx
);
11725 emit_insn (PMODE_INSN (gen_cprestore
, (mem
, offset
)));
11728 mips_emit_move (mips_cprestore_slot (temp
, false), gp
);
11731 /* Restore $gp from its save slot, using TEMP as a temporary base register
11732 if need be. This function is for o32 and o64 abicalls only.
11734 See mips_must_initialize_gp_p for details about how we manage the
11738 mips_restore_gp_from_cprestore_slot (rtx temp
)
11740 gcc_assert (TARGET_ABICALLS
&& TARGET_OLDABI
&& epilogue_completed
);
11742 if (!cfun
->machine
->must_restore_gp_when_clobbered_p
)
11744 emit_note (NOTE_INSN_DELETED
);
11750 mips_emit_move (temp
, mips_cprestore_slot (temp
, true));
11751 mips_emit_move (pic_offset_table_rtx
, temp
);
11754 mips_emit_move (pic_offset_table_rtx
, mips_cprestore_slot (temp
, true));
11755 if (!TARGET_EXPLICIT_RELOCS
)
11756 emit_insn (gen_blockage ());
11759 /* A function to save or store a register. The first argument is the
11760 register and the second is the stack slot. */
11761 typedef void (*mips_save_restore_fn
) (rtx
, rtx
);
11763 /* Use FN to save or restore register REGNO. MODE is the register's
11764 mode and OFFSET is the offset of its save slot from the current
11768 mips_save_restore_reg (machine_mode mode
, int regno
,
11769 HOST_WIDE_INT offset
, mips_save_restore_fn fn
)
11773 mem
= gen_frame_mem (mode
, plus_constant (Pmode
, stack_pointer_rtx
,
11775 fn (gen_rtx_REG (mode
, regno
), mem
);
11778 /* Call FN for each accumulator that is saved by the current function.
11779 SP_OFFSET is the offset of the current stack pointer from the start
11783 mips_for_each_saved_acc (HOST_WIDE_INT sp_offset
, mips_save_restore_fn fn
)
11785 HOST_WIDE_INT offset
;
11788 offset
= cfun
->machine
->frame
.acc_sp_offset
- sp_offset
;
11789 if (BITSET_P (cfun
->machine
->frame
.acc_mask
, 0))
11791 mips_save_restore_reg (word_mode
, LO_REGNUM
, offset
, fn
);
11792 offset
-= UNITS_PER_WORD
;
11793 mips_save_restore_reg (word_mode
, HI_REGNUM
, offset
, fn
);
11794 offset
-= UNITS_PER_WORD
;
11797 for (regno
= DSP_ACC_REG_FIRST
; regno
<= DSP_ACC_REG_LAST
; regno
++)
11798 if (BITSET_P (cfun
->machine
->frame
.acc_mask
,
11799 ((regno
- DSP_ACC_REG_FIRST
) / 2) + 1))
11801 mips_save_restore_reg (word_mode
, regno
, offset
, fn
);
11802 offset
-= UNITS_PER_WORD
;
11806 /* Save register REG to MEM. Make the instruction frame-related. */
11809 mips_save_reg (rtx reg
, rtx mem
)
11811 if (GET_MODE (reg
) == DFmode
11812 && (!TARGET_FLOAT64
11813 || mips_abi
== ABI_32
))
11817 mips_emit_move_or_split (mem
, reg
, SPLIT_IF_NECESSARY
);
11819 x1
= mips_frame_set (mips_subword (mem
, false),
11820 mips_subword (reg
, false));
11821 x2
= mips_frame_set (mips_subword (mem
, true),
11822 mips_subword (reg
, true));
11823 mips_set_frame_expr (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, x1
, x2
)));
11826 mips_emit_save_slot_move (mem
, reg
, MIPS_PROLOGUE_TEMP (GET_MODE (reg
)));
11829 /* Capture the register combinations that are allowed in a SWM or LWM
11830 instruction. The entries are ordered by number of registers set in
11831 the mask. We also ignore the single register encodings because a
11832 normal SW/LW is preferred. */
11834 static const unsigned int umips_swm_mask
[17] = {
11835 0xc0ff0000, 0x80ff0000, 0x40ff0000, 0x807f0000,
11836 0x00ff0000, 0x803f0000, 0x007f0000, 0x801f0000,
11837 0x003f0000, 0x800f0000, 0x001f0000, 0x80070000,
11838 0x000f0000, 0x80030000, 0x00070000, 0x80010000,
11842 static const unsigned int umips_swm_encoding
[17] = {
11843 25, 24, 9, 23, 8, 22, 7, 21, 6, 20, 5, 19, 4, 18, 3, 17, 2
11846 /* Try to use a microMIPS LWM or SWM instruction to save or restore
11847 as many GPRs in *MASK as possible. *OFFSET is the offset from the
11848 stack pointer of the topmost save slot.
11850 Remove from *MASK all registers that were handled using LWM and SWM.
11851 Update *OFFSET so that it points to the first unused save slot. */
11854 umips_build_save_restore (mips_save_restore_fn fn
,
11855 unsigned *mask
, HOST_WIDE_INT
*offset
)
11859 rtx pattern
, set
, reg
, mem
;
11860 HOST_WIDE_INT this_offset
;
11863 /* Try matching $16 to $31 (s0 to ra). */
11864 for (i
= 0; i
< ARRAY_SIZE (umips_swm_mask
); i
++)
11865 if ((*mask
& 0xffff0000) == umips_swm_mask
[i
])
11868 if (i
== ARRAY_SIZE (umips_swm_mask
))
11871 /* Get the offset of the lowest save slot. */
11872 nregs
= (umips_swm_encoding
[i
] & 0xf) + (umips_swm_encoding
[i
] >> 4);
11873 this_offset
= *offset
- UNITS_PER_WORD
* (nregs
- 1);
11875 /* LWM/SWM can only support offsets from -2048 to 2047. */
11876 if (!UMIPS_12BIT_OFFSET_P (this_offset
))
11879 /* Create the final PARALLEL. */
11880 pattern
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (nregs
));
11881 this_base
= stack_pointer_rtx
;
11883 /* For registers $16-$23 and $30. */
11884 for (j
= 0; j
< (umips_swm_encoding
[i
] & 0xf); j
++)
11886 HOST_WIDE_INT offset
= this_offset
+ j
* UNITS_PER_WORD
;
11887 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
, this_base
, offset
));
11888 unsigned int regno
= (j
!= 8) ? 16 + j
: 30;
11889 *mask
&= ~(1 << regno
);
11890 reg
= gen_rtx_REG (SImode
, regno
);
11891 if (fn
== mips_save_reg
)
11892 set
= mips_frame_set (mem
, reg
);
11895 set
= gen_rtx_SET (reg
, mem
);
11896 mips_add_cfa_restore (reg
);
11898 XVECEXP (pattern
, 0, j
) = set
;
11901 /* For register $31. */
11902 if (umips_swm_encoding
[i
] >> 4)
11904 HOST_WIDE_INT offset
= this_offset
+ j
* UNITS_PER_WORD
;
11905 *mask
&= ~(1 << 31);
11906 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
, this_base
, offset
));
11907 reg
= gen_rtx_REG (SImode
, 31);
11908 if (fn
== mips_save_reg
)
11909 set
= mips_frame_set (mem
, reg
);
11912 set
= gen_rtx_SET (reg
, mem
);
11913 mips_add_cfa_restore (reg
);
11915 XVECEXP (pattern
, 0, j
) = set
;
11918 pattern
= emit_insn (pattern
);
11919 if (fn
== mips_save_reg
)
11920 RTX_FRAME_RELATED_P (pattern
) = 1;
11922 /* Adjust the last offset. */
11923 *offset
-= UNITS_PER_WORD
* nregs
;
11928 /* Call FN for each register that is saved by the current function.
11929 SP_OFFSET is the offset of the current stack pointer from the start
11933 mips_for_each_saved_gpr_and_fpr (HOST_WIDE_INT sp_offset
,
11934 mips_save_restore_fn fn
)
11936 machine_mode fpr_mode
;
11938 const struct mips_frame_info
*frame
= &cfun
->machine
->frame
;
11939 HOST_WIDE_INT offset
;
11942 /* Save registers starting from high to low. The debuggers prefer at least
11943 the return register be stored at func+4, and also it allows us not to
11944 need a nop in the epilogue if at least one register is reloaded in
11945 addition to return address. */
11946 offset
= frame
->gp_sp_offset
- sp_offset
;
11947 mask
= frame
->mask
;
11949 if (TARGET_MICROMIPS
)
11950 umips_build_save_restore (fn
, &mask
, &offset
);
11952 for (regno
= GP_REG_LAST
; regno
>= GP_REG_FIRST
; regno
--)
11953 if (BITSET_P (mask
, regno
- GP_REG_FIRST
))
11955 /* Record the ra offset for use by mips_function_profiler. */
11956 if (regno
== RETURN_ADDR_REGNUM
)
11957 cfun
->machine
->frame
.ra_fp_offset
= offset
+ sp_offset
;
11958 mips_save_restore_reg (word_mode
, regno
, offset
, fn
);
11959 offset
-= UNITS_PER_WORD
;
11962 /* This loop must iterate over the same space as its companion in
11963 mips_compute_frame_info. */
11964 offset
= cfun
->machine
->frame
.fp_sp_offset
- sp_offset
;
11965 fpr_mode
= (TARGET_SINGLE_FLOAT
? SFmode
: DFmode
);
11966 for (regno
= FP_REG_LAST
- MAX_FPRS_PER_FMT
+ 1;
11967 regno
>= FP_REG_FIRST
;
11968 regno
-= MAX_FPRS_PER_FMT
)
11969 if (BITSET_P (cfun
->machine
->frame
.fmask
, regno
- FP_REG_FIRST
))
11971 if (!TARGET_FLOAT64
&& TARGET_DOUBLE_FLOAT
11972 && (fixed_regs
[regno
] || fixed_regs
[regno
+ 1]))
11974 if (fixed_regs
[regno
])
11975 mips_save_restore_reg (SFmode
, regno
+ 1, offset
, fn
);
11977 mips_save_restore_reg (SFmode
, regno
, offset
, fn
);
11980 mips_save_restore_reg (fpr_mode
, regno
, offset
, fn
);
11981 offset
-= GET_MODE_SIZE (fpr_mode
);
11985 /* Return true if a move between register REGNO and its save slot (MEM)
11986 can be done in a single move. LOAD_P is true if we are loading
11987 from the slot, false if we are storing to it. */
11990 mips_direct_save_slot_move_p (unsigned int regno
, rtx mem
, bool load_p
)
11992 /* There is a specific MIPS16 instruction for saving $31 to the stack. */
11993 if (TARGET_MIPS16
&& !load_p
&& regno
== RETURN_ADDR_REGNUM
)
11996 return mips_secondary_reload_class (REGNO_REG_CLASS (regno
),
11997 GET_MODE (mem
), mem
, load_p
) == NO_REGS
;
12000 /* Emit a move from SRC to DEST, given that one of them is a register
12001 save slot and that the other is a register. TEMP is a temporary
12002 GPR of the same mode that is available if need be. */
12005 mips_emit_save_slot_move (rtx dest
, rtx src
, rtx temp
)
12007 unsigned int regno
;
12012 regno
= REGNO (src
);
12017 regno
= REGNO (dest
);
12021 if (regno
== cfun
->machine
->global_pointer
&& !mips_must_initialize_gp_p ())
12023 /* We don't yet know whether we'll need this instruction or not.
12024 Postpone the decision by emitting a ghost move. This move
12025 is specifically not frame-related; only the split version is. */
12027 emit_insn (gen_move_gpdi (dest
, src
));
12029 emit_insn (gen_move_gpsi (dest
, src
));
12033 if (regno
== HI_REGNUM
)
12037 mips_emit_move (temp
, src
);
12039 emit_insn (gen_mthidi_ti (gen_rtx_REG (TImode
, MD_REG_FIRST
),
12040 temp
, gen_rtx_REG (DImode
, LO_REGNUM
)));
12042 emit_insn (gen_mthisi_di (gen_rtx_REG (DImode
, MD_REG_FIRST
),
12043 temp
, gen_rtx_REG (SImode
, LO_REGNUM
)));
12048 emit_insn (gen_mfhidi_ti (temp
,
12049 gen_rtx_REG (TImode
, MD_REG_FIRST
)));
12051 emit_insn (gen_mfhisi_di (temp
,
12052 gen_rtx_REG (DImode
, MD_REG_FIRST
)));
12053 mips_emit_move (dest
, temp
);
12056 else if (mips_direct_save_slot_move_p (regno
, mem
, mem
== src
))
12057 mips_emit_move (dest
, src
);
12060 gcc_assert (!reg_overlap_mentioned_p (dest
, temp
));
12061 mips_emit_move (temp
, src
);
12062 mips_emit_move (dest
, temp
);
12065 mips_set_frame_expr (mips_frame_set (dest
, src
));
12068 /* If we're generating n32 or n64 abicalls, and the current function
12069 does not use $28 as its global pointer, emit a cplocal directive.
12070 Use pic_offset_table_rtx as the argument to the directive. */
12073 mips_output_cplocal (void)
12075 if (!TARGET_EXPLICIT_RELOCS
12076 && mips_must_initialize_gp_p ()
12077 && cfun
->machine
->global_pointer
!= GLOBAL_POINTER_REGNUM
)
12078 output_asm_insn (".cplocal %+", 0);
12081 /* Implement TARGET_OUTPUT_FUNCTION_PROLOGUE. */
12084 mips_output_function_prologue (FILE *file
)
12086 const char *fnname
;
12088 /* In MIPS16 mode, we may need to generate a non-MIPS16 stub to handle
12089 floating-point arguments. */
12091 && TARGET_HARD_FLOAT_ABI
12092 && crtl
->args
.info
.fp_code
!= 0)
12093 mips16_build_function_stub ();
12095 /* Get the function name the same way that toplev.cc does before calling
12096 assemble_start_function. This is needed so that the name used here
12097 exactly matches the name used in ASM_DECLARE_FUNCTION_NAME. */
12098 fnname
= XSTR (XEXP (DECL_RTL (current_function_decl
), 0), 0);
12099 mips_start_function_definition (fnname
, TARGET_MIPS16
, current_function_decl
);
12101 /* Output MIPS-specific frame information. */
12102 if (!flag_inhibit_size_directive
)
12104 const struct mips_frame_info
*frame
;
12106 frame
= &cfun
->machine
->frame
;
12108 /* .frame FRAMEREG, FRAMESIZE, RETREG. */
12110 "\t.frame\t%s," HOST_WIDE_INT_PRINT_DEC
",%s\t\t"
12111 "# vars= " HOST_WIDE_INT_PRINT_DEC
12113 ", args= " HOST_WIDE_INT_PRINT_DEC
12114 ", gp= " HOST_WIDE_INT_PRINT_DEC
"\n",
12115 reg_names
[frame_pointer_needed
12116 ? HARD_FRAME_POINTER_REGNUM
12117 : STACK_POINTER_REGNUM
],
12118 (frame_pointer_needed
12119 ? frame
->total_size
- frame
->hard_frame_pointer_offset
12120 : frame
->total_size
),
12121 reg_names
[RETURN_ADDR_REGNUM
],
12123 frame
->num_gp
, frame
->num_fp
,
12125 frame
->cprestore_size
);
12127 /* .mask MASK, OFFSET. */
12128 fprintf (file
, "\t.mask\t0x%08x," HOST_WIDE_INT_PRINT_DEC
"\n",
12129 frame
->mask
, frame
->gp_save_offset
);
12131 /* .fmask MASK, OFFSET. */
12132 fprintf (file
, "\t.fmask\t0x%08x," HOST_WIDE_INT_PRINT_DEC
"\n",
12133 frame
->fmask
, frame
->fp_save_offset
);
12136 /* Handle the initialization of $gp for SVR4 PIC, if applicable.
12137 Also emit the ".set noreorder; .set nomacro" sequence for functions
12139 if (mips_must_initialize_gp_p ()
12140 && mips_current_loadgp_style () == LOADGP_OLDABI
)
12144 if (ISA_HAS_MIPS16E2
)
12146 /* This is a fixed-form sequence. The position of the
12147 first two instructions is important because of the
12148 way _gp_disp is defined. */
12149 output_asm_insn ("lui\t$2,%%hi(_gp_disp)", 0);
12150 output_asm_insn ("addiu\t$3,$pc,%%lo(_gp_disp)", 0);
12151 output_asm_insn ("addu\t$2,$3", 0);
12155 /* This is a fixed-form sequence. The position of the
12156 first two instructions is important because of the
12157 way _gp_disp is defined. */
12158 output_asm_insn ("li\t$2,%%hi(_gp_disp)", 0);
12159 output_asm_insn ("addiu\t$3,$pc,%%lo(_gp_disp)", 0);
12160 output_asm_insn ("sll\t$2,16", 0);
12161 output_asm_insn ("addu\t$2,$3", 0);
12166 /* .cpload must be in a .set noreorder but not a
12167 .set nomacro block. */
12168 mips_push_asm_switch (&mips_noreorder
);
12169 output_asm_insn (".cpload\t%^", 0);
12170 if (!cfun
->machine
->all_noreorder_p
)
12171 mips_pop_asm_switch (&mips_noreorder
);
12173 mips_push_asm_switch (&mips_nomacro
);
12176 else if (cfun
->machine
->all_noreorder_p
)
12178 mips_push_asm_switch (&mips_noreorder
);
12179 mips_push_asm_switch (&mips_nomacro
);
12182 /* Tell the assembler which register we're using as the global
12183 pointer. This is needed for thunks, since they can use either
12184 explicit relocs or assembler macros. */
12185 mips_output_cplocal ();
12188 /* Implement TARGET_OUTPUT_FUNCTION_EPILOGUE. */
12191 mips_output_function_epilogue (FILE *)
12193 const char *fnname
;
12195 /* Reinstate the normal $gp. */
12196 SET_REGNO (pic_offset_table_rtx
, GLOBAL_POINTER_REGNUM
);
12197 mips_output_cplocal ();
12199 if (cfun
->machine
->all_noreorder_p
)
12201 mips_pop_asm_switch (&mips_nomacro
);
12202 mips_pop_asm_switch (&mips_noreorder
);
12205 /* Get the function name the same way that toplev.cc does before calling
12206 assemble_start_function. This is needed so that the name used here
12207 exactly matches the name used in ASM_DECLARE_FUNCTION_NAME. */
12208 fnname
= XSTR (XEXP (DECL_RTL (current_function_decl
), 0), 0);
12209 mips_end_function_definition (fnname
);
12212 /* Emit an optimisation barrier for accesses to the current frame. */
12215 mips_frame_barrier (void)
12217 emit_clobber (gen_frame_mem (BLKmode
, stack_pointer_rtx
));
12221 /* The __gnu_local_gp symbol. */
12223 static GTY(()) rtx mips_gnu_local_gp
;
12225 /* If we're generating n32 or n64 abicalls, emit instructions
12226 to set up the global pointer. */
12229 mips_emit_loadgp (void)
12231 rtx addr
, offset
, incoming_address
, base
, index
, pic_reg
;
12233 pic_reg
= TARGET_MIPS16
? MIPS16_PIC_TEMP
: pic_offset_table_rtx
;
12234 switch (mips_current_loadgp_style ())
12236 case LOADGP_ABSOLUTE
:
12237 if (mips_gnu_local_gp
== NULL
)
12239 mips_gnu_local_gp
= gen_rtx_SYMBOL_REF (Pmode
, "__gnu_local_gp");
12240 SYMBOL_REF_FLAGS (mips_gnu_local_gp
) |= SYMBOL_FLAG_LOCAL
;
12242 emit_insn (PMODE_INSN (gen_loadgp_absolute
,
12243 (pic_reg
, mips_gnu_local_gp
)));
12246 case LOADGP_OLDABI
:
12247 /* Added by mips_output_function_prologue. */
12250 case LOADGP_NEWABI
:
12251 addr
= XEXP (DECL_RTL (current_function_decl
), 0);
12252 offset
= mips_unspec_address (addr
, SYMBOL_GOTOFF_LOADGP
);
12253 incoming_address
= gen_rtx_REG (Pmode
, PIC_FUNCTION_ADDR_REGNUM
);
12254 emit_insn (PMODE_INSN (gen_loadgp_newabi
,
12255 (pic_reg
, offset
, incoming_address
)));
12259 base
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (VXWORKS_GOTT_BASE
));
12260 index
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (VXWORKS_GOTT_INDEX
));
12261 emit_insn (PMODE_INSN (gen_loadgp_rtp
, (pic_reg
, base
, index
)));
12269 emit_insn (PMODE_INSN (gen_copygp_mips16
,
12270 (pic_offset_table_rtx
, pic_reg
)));
12272 /* Emit a blockage if there are implicit uses of the GP register.
12273 This includes profiled functions, because FUNCTION_PROFILE uses
12275 if (!TARGET_EXPLICIT_RELOCS
|| crtl
->profile
)
12276 emit_insn (gen_loadgp_blockage ());
12279 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
12281 #if PROBE_INTERVAL > 32768
12282 #error Cannot use indexed addressing mode for stack probing
12285 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
12286 inclusive. These are offsets from the current stack pointer. */
12289 mips_emit_probe_stack_range (HOST_WIDE_INT first
, HOST_WIDE_INT size
)
12292 sorry ("%<-fstack-check=specific%> not implemented for MIPS16");
12294 /* See if we have a constant small number of probes to generate. If so,
12295 that's the easy case. */
12296 if (first
+ size
<= 32768)
12300 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
12301 it exceeds SIZE. If only one probe is needed, this will not
12302 generate any code. Then probe at FIRST + SIZE. */
12303 for (i
= PROBE_INTERVAL
; i
< size
; i
+= PROBE_INTERVAL
)
12304 emit_stack_probe (plus_constant (Pmode
, stack_pointer_rtx
,
12307 emit_stack_probe (plus_constant (Pmode
, stack_pointer_rtx
,
12311 /* Otherwise, do the same as above, but in a loop. Note that we must be
12312 extra careful with variables wrapping around because we might be at
12313 the very top (or the very bottom) of the address space and we have
12314 to be able to handle this case properly; in particular, we use an
12315 equality test for the loop condition. */
12318 HOST_WIDE_INT rounded_size
;
12319 rtx r3
= MIPS_PROLOGUE_TEMP (Pmode
);
12320 rtx r12
= MIPS_PROLOGUE_TEMP2 (Pmode
);
12322 /* Sanity check for the addressing mode we're going to use. */
12323 gcc_assert (first
<= 32768);
12326 /* Step 1: round SIZE to the previous multiple of the interval. */
12328 rounded_size
= ROUND_DOWN (size
, PROBE_INTERVAL
);
12331 /* Step 2: compute initial and final value of the loop counter. */
12333 /* TEST_ADDR = SP + FIRST. */
12334 emit_insn (gen_rtx_SET (r3
, plus_constant (Pmode
, stack_pointer_rtx
,
12337 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
12338 if (rounded_size
> 32768)
12340 emit_move_insn (r12
, GEN_INT (rounded_size
));
12341 emit_insn (gen_rtx_SET (r12
, gen_rtx_MINUS (Pmode
, r3
, r12
)));
12344 emit_insn (gen_rtx_SET (r12
, plus_constant (Pmode
, r3
,
12348 /* Step 3: the loop
12352 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
12355 while (TEST_ADDR != LAST_ADDR)
12357 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
12358 until it is equal to ROUNDED_SIZE. */
12360 emit_insn (PMODE_INSN (gen_probe_stack_range
, (r3
, r3
, r12
)));
12363 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
12364 that SIZE is equal to ROUNDED_SIZE. */
12366 if (size
!= rounded_size
)
12367 emit_stack_probe (plus_constant (Pmode
, r12
, rounded_size
- size
));
12370 /* Make sure nothing is scheduled before we are done. */
12371 emit_insn (gen_blockage ());
12374 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
12375 absolute addresses. */
12378 mips_output_probe_stack_range (rtx reg1
, rtx reg2
)
12380 static int labelno
= 0;
12381 char loop_lab
[32], tmp
[64];
12384 ASM_GENERATE_INTERNAL_LABEL (loop_lab
, "LPSRL", labelno
++);
12387 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, loop_lab
);
12389 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
12391 xops
[1] = GEN_INT (-PROBE_INTERVAL
);
12392 if (TARGET_64BIT
&& TARGET_LONG64
)
12393 output_asm_insn ("daddiu\t%0,%0,%1", xops
);
12395 output_asm_insn ("addiu\t%0,%0,%1", xops
);
12397 /* Probe at TEST_ADDR, test if TEST_ADDR == LAST_ADDR and branch. */
12399 strcpy (tmp
, "%(%<bne\t%0,%1,");
12400 output_asm_insn (strcat (tmp
, &loop_lab
[1]), xops
);
12402 output_asm_insn ("sd\t$0,0(%0)%)", xops
);
12404 output_asm_insn ("sw\t$0,0(%0)%)", xops
);
12409 /* Return true if X contains a kernel register. */
12412 mips_refers_to_kernel_reg_p (const_rtx x
)
12414 subrtx_iterator::array_type array
;
12415 FOR_EACH_SUBRTX (iter
, array
, x
, NONCONST
)
12416 if (REG_P (*iter
) && KERNEL_REG_P (REGNO (*iter
)))
12421 /* Expand the "prologue" pattern. */
12424 mips_expand_prologue (void)
12426 const struct mips_frame_info
*frame
;
12427 HOST_WIDE_INT size
;
12428 unsigned int nargs
;
12430 if (cfun
->machine
->global_pointer
!= INVALID_REGNUM
)
12432 /* Check whether an insn uses pic_offset_table_rtx, either explicitly
12433 or implicitly. If so, we can commit to using a global pointer
12434 straight away, otherwise we need to defer the decision. */
12435 if (mips_cfun_has_inflexible_gp_ref_p ()
12436 || mips_cfun_has_flexible_gp_ref_p ())
12438 cfun
->machine
->must_initialize_gp_p
= true;
12439 cfun
->machine
->must_restore_gp_when_clobbered_p
= true;
12442 SET_REGNO (pic_offset_table_rtx
, cfun
->machine
->global_pointer
);
12445 frame
= &cfun
->machine
->frame
;
12446 size
= frame
->total_size
;
12448 if (flag_stack_usage_info
)
12449 current_function_static_stack_size
= size
;
12451 if (flag_stack_check
== STATIC_BUILTIN_STACK_CHECK
12452 || flag_stack_clash_protection
)
12454 if (crtl
->is_leaf
&& !cfun
->calls_alloca
)
12456 if (size
> PROBE_INTERVAL
&& size
> get_stack_check_protect ())
12457 mips_emit_probe_stack_range (get_stack_check_protect (),
12458 size
- get_stack_check_protect ());
12461 mips_emit_probe_stack_range (get_stack_check_protect (), size
);
12464 /* Save the registers. Allocate up to MIPS_MAX_FIRST_STACK_STEP
12465 bytes beforehand; this is enough to cover the register save area
12466 without going out of range. */
12467 if (((frame
->mask
| frame
->fmask
| frame
->acc_mask
) != 0)
12468 || frame
->num_cop0_regs
> 0)
12470 HOST_WIDE_INT step1
;
12472 step1
= MIN (size
, MIPS_MAX_FIRST_STACK_STEP
);
12473 if (GENERATE_MIPS16E_SAVE_RESTORE
)
12475 HOST_WIDE_INT offset
;
12476 unsigned int mask
, regno
;
12478 /* Try to merge argument stores into the save instruction. */
12479 nargs
= mips16e_collect_argument_saves ();
12481 /* Build the save instruction. */
12482 mask
= frame
->mask
;
12483 rtx insn
= mips16e_build_save_restore (false, &mask
, &offset
,
12485 RTX_FRAME_RELATED_P (emit_insn (insn
)) = 1;
12486 mips_frame_barrier ();
12489 /* Check if we need to save other registers. */
12490 for (regno
= GP_REG_FIRST
; regno
< GP_REG_LAST
; regno
++)
12491 if (BITSET_P (mask
, regno
- GP_REG_FIRST
))
12493 offset
-= UNITS_PER_WORD
;
12494 mips_save_restore_reg (word_mode
, regno
,
12495 offset
, mips_save_reg
);
12500 if (cfun
->machine
->interrupt_handler_p
)
12502 HOST_WIDE_INT offset
;
12505 /* If this interrupt is using a shadow register set, we need to
12506 get the stack pointer from the previous register set. */
12507 if (cfun
->machine
->use_shadow_register_set
== SHADOW_SET_YES
)
12508 emit_insn (PMODE_INSN (gen_mips_rdpgpr
, (stack_pointer_rtx
,
12509 stack_pointer_rtx
)));
12511 if (!cfun
->machine
->keep_interrupts_masked_p
)
12513 if (cfun
->machine
->int_mask
== INT_MASK_EIC
)
12514 /* Move from COP0 Cause to K0. */
12515 emit_insn (gen_cop0_move (gen_rtx_REG (SImode
, K0_REG_NUM
),
12516 gen_rtx_REG (SImode
, COP0_CAUSE_REG_NUM
)));
12518 /* Move from COP0 EPC to K1. */
12519 emit_insn (gen_cop0_move (gen_rtx_REG (SImode
, K1_REG_NUM
),
12520 gen_rtx_REG (SImode
,
12521 COP0_EPC_REG_NUM
)));
12523 /* Allocate the first part of the frame. */
12524 rtx insn
= gen_add3_insn (stack_pointer_rtx
, stack_pointer_rtx
,
12526 RTX_FRAME_RELATED_P (emit_insn (insn
)) = 1;
12527 mips_frame_barrier ();
12530 /* Start at the uppermost location for saving. */
12531 offset
= frame
->cop0_sp_offset
- size
;
12533 /* Push EPC into its stack slot. */
12534 mem
= gen_frame_mem (word_mode
,
12535 plus_constant (Pmode
, stack_pointer_rtx
,
12537 mips_emit_move (mem
, gen_rtx_REG (word_mode
, K1_REG_NUM
));
12538 offset
-= UNITS_PER_WORD
;
12540 /* Move from COP0 Status to K1. */
12541 emit_insn (gen_cop0_move (gen_rtx_REG (SImode
, K1_REG_NUM
),
12542 gen_rtx_REG (SImode
,
12543 COP0_STATUS_REG_NUM
)));
12545 /* Right justify the RIPL in k0. */
12546 if (!cfun
->machine
->keep_interrupts_masked_p
12547 && cfun
->machine
->int_mask
== INT_MASK_EIC
)
12548 emit_insn (gen_lshrsi3 (gen_rtx_REG (SImode
, K0_REG_NUM
),
12549 gen_rtx_REG (SImode
, K0_REG_NUM
),
12550 GEN_INT (CAUSE_IPL
)));
12552 /* Push Status into its stack slot. */
12553 mem
= gen_frame_mem (word_mode
,
12554 plus_constant (Pmode
, stack_pointer_rtx
,
12556 mips_emit_move (mem
, gen_rtx_REG (word_mode
, K1_REG_NUM
));
12557 offset
-= UNITS_PER_WORD
;
12559 /* Insert the RIPL into our copy of SR (k1) as the new IPL. */
12560 if (!cfun
->machine
->keep_interrupts_masked_p
12561 && cfun
->machine
->int_mask
== INT_MASK_EIC
)
12563 emit_insn (gen_insvsi (gen_rtx_REG (SImode
, K1_REG_NUM
),
12564 TARGET_MCU
? GEN_INT (7) : GEN_INT (6),
12566 gen_rtx_REG (SImode
, K0_REG_NUM
)));
12569 emit_insn (gen_lshrsi3 (gen_rtx_REG (SImode
, K0_REG_NUM
),
12570 gen_rtx_REG (SImode
, K0_REG_NUM
),
12572 emit_insn (gen_insvsi (gen_rtx_REG (SImode
, K1_REG_NUM
),
12574 GEN_INT (SR_IPL
+8),
12575 gen_rtx_REG (SImode
, K0_REG_NUM
)));
12579 /* Clear all interrupt mask bits up to and including the
12580 handler's interrupt line. */
12581 if (!cfun
->machine
->keep_interrupts_masked_p
12582 && cfun
->machine
->int_mask
!= INT_MASK_EIC
)
12583 emit_insn (gen_insvsi (gen_rtx_REG (SImode
, K1_REG_NUM
),
12584 GEN_INT (cfun
->machine
->int_mask
+ 1),
12586 gen_rtx_REG (SImode
, GP_REG_FIRST
)));
12588 if (!cfun
->machine
->keep_interrupts_masked_p
)
12589 /* Enable interrupts by clearing the KSU ERL and EXL bits.
12590 IE is already the correct value, so we don't have to do
12591 anything explicit. */
12592 emit_insn (gen_insvsi (gen_rtx_REG (SImode
, K1_REG_NUM
),
12595 gen_rtx_REG (SImode
, GP_REG_FIRST
)));
12597 /* Disable interrupts by clearing the KSU, ERL, EXL,
12599 emit_insn (gen_insvsi (gen_rtx_REG (SImode
, K1_REG_NUM
),
12602 gen_rtx_REG (SImode
, GP_REG_FIRST
)));
12604 if (TARGET_HARD_FLOAT
)
12605 /* Disable COP1 for hard-float. This will lead to an exception
12606 if floating-point code is executed in an ISR. */
12607 emit_insn (gen_insvsi (gen_rtx_REG (SImode
, K1_REG_NUM
),
12610 gen_rtx_REG (SImode
, GP_REG_FIRST
)));
12616 rtx insn
= gen_add3_insn (stack_pointer_rtx
,
12619 RTX_FRAME_RELATED_P (emit_insn (insn
)) = 1;
12620 mips_frame_barrier ();
12624 mips_for_each_saved_acc (size
, mips_save_reg
);
12625 mips_for_each_saved_gpr_and_fpr (size
, mips_save_reg
);
12629 /* Allocate the rest of the frame. */
12632 if (SMALL_OPERAND (-size
))
12633 RTX_FRAME_RELATED_P (emit_insn (gen_add3_insn (stack_pointer_rtx
,
12635 GEN_INT (-size
)))) = 1;
12638 mips_emit_move (MIPS_PROLOGUE_TEMP (Pmode
), GEN_INT (size
));
12641 /* There are no instructions to add or subtract registers
12642 from the stack pointer, so use the frame pointer as a
12643 temporary. We should always be using a frame pointer
12644 in this case anyway. */
12645 gcc_assert (frame_pointer_needed
);
12646 mips_emit_move (hard_frame_pointer_rtx
, stack_pointer_rtx
);
12647 emit_insn (gen_sub3_insn (hard_frame_pointer_rtx
,
12648 hard_frame_pointer_rtx
,
12649 MIPS_PROLOGUE_TEMP (Pmode
)));
12650 mips_emit_move (stack_pointer_rtx
, hard_frame_pointer_rtx
);
12653 emit_insn (gen_sub3_insn (stack_pointer_rtx
,
12655 MIPS_PROLOGUE_TEMP (Pmode
)));
12657 /* Describe the combined effect of the previous instructions. */
12658 mips_set_frame_expr
12659 (gen_rtx_SET (stack_pointer_rtx
,
12660 plus_constant (Pmode
, stack_pointer_rtx
, -size
)));
12662 mips_frame_barrier ();
12665 /* Set up the frame pointer, if we're using one. */
12666 if (frame_pointer_needed
)
12668 HOST_WIDE_INT offset
;
12670 offset
= frame
->hard_frame_pointer_offset
;
12673 rtx insn
= mips_emit_move (hard_frame_pointer_rtx
, stack_pointer_rtx
);
12674 RTX_FRAME_RELATED_P (insn
) = 1;
12676 else if (SMALL_OPERAND (offset
))
12678 rtx insn
= gen_add3_insn (hard_frame_pointer_rtx
,
12679 stack_pointer_rtx
, GEN_INT (offset
));
12680 RTX_FRAME_RELATED_P (emit_insn (insn
)) = 1;
12684 mips_emit_move (MIPS_PROLOGUE_TEMP (Pmode
), GEN_INT (offset
));
12685 mips_emit_move (hard_frame_pointer_rtx
, stack_pointer_rtx
);
12686 emit_insn (gen_add3_insn (hard_frame_pointer_rtx
,
12687 hard_frame_pointer_rtx
,
12688 MIPS_PROLOGUE_TEMP (Pmode
)));
12689 mips_set_frame_expr
12690 (gen_rtx_SET (hard_frame_pointer_rtx
,
12691 plus_constant (Pmode
, stack_pointer_rtx
, offset
)));
12695 mips_emit_loadgp ();
12697 /* Initialize the $gp save slot. */
12698 if (mips_cfun_has_cprestore_slot_p ())
12700 rtx base
, mem
, gp
, temp
;
12701 HOST_WIDE_INT offset
;
12703 mips_get_cprestore_base_and_offset (&base
, &offset
, false);
12704 mem
= gen_frame_mem (Pmode
, plus_constant (Pmode
, base
, offset
));
12705 gp
= TARGET_MIPS16
? MIPS16_PIC_TEMP
: pic_offset_table_rtx
;
12706 temp
= (SMALL_OPERAND (offset
)
12707 ? gen_rtx_SCRATCH (Pmode
)
12708 : MIPS_PROLOGUE_TEMP (Pmode
));
12709 emit_insn (PMODE_INSN (gen_potential_cprestore
,
12710 (mem
, GEN_INT (offset
), gp
, temp
)));
12712 mips_get_cprestore_base_and_offset (&base
, &offset
, true);
12713 mem
= gen_frame_mem (Pmode
, plus_constant (Pmode
, base
, offset
));
12714 emit_insn (PMODE_INSN (gen_use_cprestore
, (mem
)));
12717 /* We need to search back to the last use of K0 or K1. */
12718 if (cfun
->machine
->interrupt_handler_p
)
12721 for (insn
= get_last_insn (); insn
!= NULL_RTX
; insn
= PREV_INSN (insn
))
12723 && mips_refers_to_kernel_reg_p (PATTERN (insn
)))
12725 /* Emit a move from K1 to COP0 Status after insn. */
12726 gcc_assert (insn
!= NULL_RTX
);
12727 emit_insn_after (gen_cop0_move (gen_rtx_REG (SImode
, COP0_STATUS_REG_NUM
),
12728 gen_rtx_REG (SImode
, K1_REG_NUM
)),
12732 /* If we are profiling, make sure no instructions are scheduled before
12733 the call to mcount. */
12735 emit_insn (gen_blockage ());
12738 /* Attach all pending register saves to the previous instruction.
12739 Return that instruction. */
12742 mips_epilogue_emit_cfa_restores (void)
12746 insn
= get_last_insn ();
12747 if (mips_epilogue
.cfa_restores
)
12749 gcc_assert (insn
&& !REG_NOTES (insn
));
12750 RTX_FRAME_RELATED_P (insn
) = 1;
12751 REG_NOTES (insn
) = mips_epilogue
.cfa_restores
;
12752 mips_epilogue
.cfa_restores
= 0;
12757 /* Like mips_epilogue_emit_cfa_restores, but also record that the CFA is
12758 now at REG + OFFSET. */
12761 mips_epilogue_set_cfa (rtx reg
, HOST_WIDE_INT offset
)
12765 insn
= mips_epilogue_emit_cfa_restores ();
12766 if (reg
!= mips_epilogue
.cfa_reg
|| offset
!= mips_epilogue
.cfa_offset
)
12768 RTX_FRAME_RELATED_P (insn
) = 1;
12769 REG_NOTES (insn
) = alloc_reg_note (REG_CFA_DEF_CFA
,
12770 plus_constant (Pmode
, reg
, offset
),
12772 mips_epilogue
.cfa_reg
= reg
;
12773 mips_epilogue
.cfa_offset
= offset
;
12777 /* Emit instructions to restore register REG from slot MEM. Also update
12778 the cfa_restores list. */
12781 mips_restore_reg (rtx reg
, rtx mem
)
12783 /* There's no MIPS16 instruction to load $31 directly. Load into
12784 $7 instead and adjust the return insn appropriately. */
12785 if (TARGET_MIPS16
&& REGNO (reg
) == RETURN_ADDR_REGNUM
)
12786 reg
= gen_rtx_REG (GET_MODE (reg
), GP_REG_FIRST
+ 7);
12787 else if (GET_MODE (reg
) == DFmode
12788 && (!TARGET_FLOAT64
12789 || mips_abi
== ABI_32
))
12791 mips_add_cfa_restore (mips_subword (reg
, true));
12792 mips_add_cfa_restore (mips_subword (reg
, false));
12795 mips_add_cfa_restore (reg
);
12797 mips_emit_save_slot_move (reg
, mem
, MIPS_EPILOGUE_TEMP (GET_MODE (reg
)));
12798 if (REGNO (reg
) == REGNO (mips_epilogue
.cfa_reg
))
12799 /* The CFA is currently defined in terms of the register whose
12800 value we have just restored. Redefine the CFA in terms of
12801 the stack pointer. */
12802 mips_epilogue_set_cfa (stack_pointer_rtx
,
12803 mips_epilogue
.cfa_restore_sp_offset
);
12806 /* Emit code to set the stack pointer to BASE + OFFSET, given that
12807 BASE + OFFSET is NEW_FRAME_SIZE bytes below the top of the frame.
12808 BASE, if not the stack pointer, is available as a temporary. */
12811 mips_deallocate_stack (rtx base
, rtx offset
, HOST_WIDE_INT new_frame_size
)
12813 if (base
== stack_pointer_rtx
&& offset
== const0_rtx
)
12816 mips_frame_barrier ();
12817 if (offset
== const0_rtx
)
12819 emit_move_insn (stack_pointer_rtx
, base
);
12820 mips_epilogue_set_cfa (stack_pointer_rtx
, new_frame_size
);
12822 else if (TARGET_MIPS16
&& base
!= stack_pointer_rtx
)
12824 emit_insn (gen_add3_insn (base
, base
, offset
));
12825 mips_epilogue_set_cfa (base
, new_frame_size
);
12826 emit_move_insn (stack_pointer_rtx
, base
);
12830 emit_insn (gen_add3_insn (stack_pointer_rtx
, base
, offset
));
12831 mips_epilogue_set_cfa (stack_pointer_rtx
, new_frame_size
);
12835 /* Emit any instructions needed before a return. */
12838 mips_expand_before_return (void)
12840 /* When using a call-clobbered gp, we start out with unified call
12841 insns that include instructions to restore the gp. We then split
12842 these unified calls after reload. These split calls explicitly
12843 clobber gp, so there is no need to define
12844 PIC_OFFSET_TABLE_REG_CALL_CLOBBERED.
12846 For consistency, we should also insert an explicit clobber of $28
12847 before return insns, so that the post-reload optimizers know that
12848 the register is not live on exit. */
12849 if (TARGET_CALL_CLOBBERED_GP
)
12850 emit_clobber (pic_offset_table_rtx
);
12853 /* Expand an "epilogue" or "sibcall_epilogue" pattern; SIBCALL_P
12857 mips_expand_epilogue (bool sibcall_p
)
12859 const struct mips_frame_info
*frame
;
12860 HOST_WIDE_INT step1
, step2
;
12863 bool use_jraddiusp_p
= false;
12865 if (!sibcall_p
&& mips_can_use_return_insn ())
12867 emit_jump_insn (gen_return ());
12871 /* In MIPS16 mode, if the return value should go into a floating-point
12872 register, we need to call a helper routine to copy it over. */
12873 if (mips16_cfun_returns_in_fpr_p ())
12874 mips16_copy_fpr_return_value ();
12876 /* Split the frame into two. STEP1 is the amount of stack we should
12877 deallocate before restoring the registers. STEP2 is the amount we
12878 should deallocate afterwards.
12880 Start off by assuming that no registers need to be restored. */
12881 frame
= &cfun
->machine
->frame
;
12882 step1
= frame
->total_size
;
12885 /* Work out which register holds the frame address. */
12886 if (!frame_pointer_needed
)
12887 base
= stack_pointer_rtx
;
12890 base
= hard_frame_pointer_rtx
;
12891 step1
-= frame
->hard_frame_pointer_offset
;
12893 mips_epilogue
.cfa_reg
= base
;
12894 mips_epilogue
.cfa_offset
= step1
;
12895 mips_epilogue
.cfa_restores
= NULL_RTX
;
12897 /* If we need to restore registers, deallocate as much stack as
12898 possible in the second step without going out of range. */
12899 if ((frame
->mask
| frame
->fmask
| frame
->acc_mask
) != 0
12900 || frame
->num_cop0_regs
> 0)
12902 step2
= MIN (step1
, MIPS_MAX_FIRST_STACK_STEP
);
12906 /* Get an rtx for STEP1 that we can add to BASE. */
12907 adjust
= GEN_INT (step1
);
12908 if (!SMALL_OPERAND (step1
))
12910 mips_emit_move (MIPS_EPILOGUE_TEMP (Pmode
), adjust
);
12911 adjust
= MIPS_EPILOGUE_TEMP (Pmode
);
12913 mips_deallocate_stack (base
, adjust
, step2
);
12915 /* If we're using addressing macros, $gp is implicitly used by all
12916 SYMBOL_REFs. We must emit a blockage insn before restoring $gp
12918 if (TARGET_CALL_SAVED_GP
&& !TARGET_EXPLICIT_RELOCS
)
12919 emit_insn (gen_blockage ());
12921 mips_epilogue
.cfa_restore_sp_offset
= step2
;
12922 if (GENERATE_MIPS16E_SAVE_RESTORE
&& frame
->mask
!= 0)
12924 unsigned int regno
, mask
;
12925 HOST_WIDE_INT offset
;
12928 /* Generate the restore instruction. */
12929 mask
= frame
->mask
;
12930 restore
= mips16e_build_save_restore (true, &mask
, &offset
, 0, step2
);
12932 /* Restore any other registers manually. */
12933 for (regno
= GP_REG_FIRST
; regno
< GP_REG_LAST
; regno
++)
12934 if (BITSET_P (mask
, regno
- GP_REG_FIRST
))
12936 offset
-= UNITS_PER_WORD
;
12937 mips_save_restore_reg (word_mode
, regno
, offset
, mips_restore_reg
);
12940 /* Restore the remaining registers and deallocate the final bit
12942 mips_frame_barrier ();
12943 emit_insn (restore
);
12944 mips_epilogue_set_cfa (stack_pointer_rtx
, 0);
12948 /* Restore the registers. */
12949 mips_for_each_saved_acc (frame
->total_size
- step2
, mips_restore_reg
);
12950 mips_for_each_saved_gpr_and_fpr (frame
->total_size
- step2
,
12953 if (cfun
->machine
->interrupt_handler_p
)
12955 HOST_WIDE_INT offset
;
12958 offset
= frame
->cop0_sp_offset
- (frame
->total_size
- step2
);
12960 /* Restore the original EPC. */
12961 mem
= gen_frame_mem (word_mode
,
12962 plus_constant (Pmode
, stack_pointer_rtx
,
12964 mips_emit_move (gen_rtx_REG (word_mode
, K1_REG_NUM
), mem
);
12965 offset
-= UNITS_PER_WORD
;
12967 /* Move to COP0 EPC. */
12968 emit_insn (gen_cop0_move (gen_rtx_REG (SImode
, COP0_EPC_REG_NUM
),
12969 gen_rtx_REG (SImode
, K1_REG_NUM
)));
12971 /* Restore the original Status. */
12972 mem
= gen_frame_mem (word_mode
,
12973 plus_constant (Pmode
, stack_pointer_rtx
,
12975 mips_emit_move (gen_rtx_REG (word_mode
, K1_REG_NUM
), mem
);
12976 offset
-= UNITS_PER_WORD
;
12978 /* If we don't use shadow register set, we need to update SP. */
12979 if (cfun
->machine
->use_shadow_register_set
== SHADOW_SET_NO
)
12980 mips_deallocate_stack (stack_pointer_rtx
, GEN_INT (step2
), 0);
12982 /* The choice of position is somewhat arbitrary in this case. */
12983 mips_epilogue_emit_cfa_restores ();
12985 /* Move to COP0 Status. */
12986 emit_insn (gen_cop0_move (gen_rtx_REG (SImode
, COP0_STATUS_REG_NUM
),
12987 gen_rtx_REG (SImode
, K1_REG_NUM
)));
12989 else if (TARGET_MICROMIPS
12990 && !crtl
->calls_eh_return
12993 && mips_unsigned_immediate_p (step2
, 5, 2))
12994 use_jraddiusp_p
= true;
12996 /* Deallocate the final bit of the frame. */
12997 mips_deallocate_stack (stack_pointer_rtx
, GEN_INT (step2
), 0);
13000 if (cfun
->machine
->use_frame_header_for_callee_saved_regs
)
13001 mips_epilogue_emit_cfa_restores ();
13002 else if (!use_jraddiusp_p
)
13003 gcc_assert (!mips_epilogue
.cfa_restores
);
13005 /* Add in the __builtin_eh_return stack adjustment. We need to
13006 use a temporary in MIPS16 code. */
13007 if (crtl
->calls_eh_return
)
13011 mips_emit_move (MIPS_EPILOGUE_TEMP (Pmode
), stack_pointer_rtx
);
13012 emit_insn (gen_add3_insn (MIPS_EPILOGUE_TEMP (Pmode
),
13013 MIPS_EPILOGUE_TEMP (Pmode
),
13014 EH_RETURN_STACKADJ_RTX
));
13015 mips_emit_move (stack_pointer_rtx
, MIPS_EPILOGUE_TEMP (Pmode
));
13018 emit_insn (gen_add3_insn (stack_pointer_rtx
,
13020 EH_RETURN_STACKADJ_RTX
));
13025 mips_expand_before_return ();
13026 if (cfun
->machine
->interrupt_handler_p
)
13028 /* Interrupt handlers generate eret or deret. */
13029 if (cfun
->machine
->use_debug_exception_return_p
)
13030 emit_jump_insn (gen_mips_deret ());
13032 emit_jump_insn (gen_mips_eret ());
13038 /* When generating MIPS16 code, the normal
13039 mips_for_each_saved_gpr_and_fpr path will restore the return
13040 address into $7 rather than $31. */
13042 && !GENERATE_MIPS16E_SAVE_RESTORE
13043 && BITSET_P (frame
->mask
, RETURN_ADDR_REGNUM
))
13045 /* simple_returns cannot rely on values that are only available
13046 on paths through the epilogue (because return paths that do
13047 not pass through the epilogue may nevertheless reuse a
13048 simple_return that occurs at the end of the epilogue).
13049 Use a normal return here instead. */
13050 rtx reg
= gen_rtx_REG (Pmode
, GP_REG_FIRST
+ 7);
13051 pat
= gen_return_internal (reg
);
13053 else if (use_jraddiusp_p
)
13054 pat
= gen_jraddiusp (GEN_INT (step2
));
13057 rtx reg
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
13058 pat
= gen_simple_return_internal (reg
);
13060 emit_jump_insn (pat
);
13061 if (use_jraddiusp_p
)
13062 mips_epilogue_set_cfa (stack_pointer_rtx
, step2
);
13066 /* Search from the beginning to the first use of K0 or K1. */
13067 if (cfun
->machine
->interrupt_handler_p
13068 && !cfun
->machine
->keep_interrupts_masked_p
)
13070 for (insn
= get_insns (); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
13072 && mips_refers_to_kernel_reg_p (PATTERN (insn
)))
13074 gcc_assert (insn
!= NULL_RTX
);
13075 /* Insert disable interrupts before the first use of K0 or K1. */
13076 emit_insn_before (gen_mips_di (), insn
);
13077 emit_insn_before (gen_mips_ehb (), insn
);
13081 /* Return nonzero if this function is known to have a null epilogue.
13082 This allows the optimizer to omit jumps to jumps if no stack
13086 mips_can_use_return_insn (void)
13088 /* Interrupt handlers need to go through the epilogue. */
13089 if (cfun
->machine
->interrupt_handler_p
)
13092 if (!reload_completed
)
13098 /* In MIPS16 mode, a function that returns a floating-point value
13099 needs to arrange to copy the return value into the floating-point
13101 if (mips16_cfun_returns_in_fpr_p ())
13104 return (cfun
->machine
->frame
.total_size
== 0
13105 && !cfun
->machine
->use_frame_header_for_callee_saved_regs
);
13108 /* Return true if register REGNO can store a value of mode MODE.
13109 The result of this function is cached in mips_hard_regno_mode_ok. */
13112 mips_hard_regno_mode_ok_uncached (unsigned int regno
, machine_mode mode
)
13115 enum mode_class mclass
;
13117 if (mode
== CCV2mode
)
13118 return (ISA_HAS_8CC
13119 && ST_REG_P (regno
)
13120 && (regno
- ST_REG_FIRST
) % 2 == 0);
13122 if (mode
== CCV4mode
)
13123 return (ISA_HAS_8CC
13124 && ST_REG_P (regno
)
13125 && (regno
- ST_REG_FIRST
) % 4 == 0);
13127 if (mode
== CCmode
)
13128 return ISA_HAS_8CC
? ST_REG_P (regno
) : regno
== FPSW_REGNUM
;
13130 size
= GET_MODE_SIZE (mode
);
13131 mclass
= GET_MODE_CLASS (mode
);
13133 if (GP_REG_P (regno
) && mode
!= CCFmode
&& !MSA_SUPPORTED_MODE_P (mode
))
13134 return ((regno
- GP_REG_FIRST
) & 1) == 0 || size
<= UNITS_PER_WORD
;
13136 /* For MSA, allow TImode and 128-bit vector modes in all FPR. */
13137 if (FP_REG_P (regno
) && MSA_SUPPORTED_MODE_P (mode
))
13140 if (FP_REG_P (regno
)
13141 && (((regno
- FP_REG_FIRST
) % MAX_FPRS_PER_FMT
) == 0
13142 || (MIN_FPRS_PER_FMT
== 1 && size
<= UNITS_PER_FPREG
)))
13144 /* Deny use of odd-numbered registers for 32-bit data for
13145 the o32 FP64A ABI. */
13146 if (TARGET_O32_FP64A_ABI
&& size
<= 4 && (regno
& 1) != 0)
13149 /* The FPXX ABI requires double-precision values to be placed in
13150 even-numbered registers. Disallow odd-numbered registers with
13151 CCFmode because CCFmode double-precision compares will write a
13152 64-bit value to a register. */
13153 if (mode
== CCFmode
)
13154 return !(TARGET_FLOATXX
&& (regno
& 1) != 0);
13156 /* Allow 64-bit vector modes for Loongson MultiMedia extensions
13157 Instructions (MMI). */
13158 if (TARGET_LOONGSON_MMI
13159 && (mode
== V2SImode
13160 || mode
== V4HImode
13161 || mode
== V8QImode
13162 || mode
== DImode
))
13165 if (mclass
== MODE_FLOAT
13166 || mclass
== MODE_COMPLEX_FLOAT
13167 || mclass
== MODE_VECTOR_FLOAT
)
13168 return size
<= UNITS_PER_FPVALUE
;
13170 /* Allow integer modes that fit into a single register. We need
13171 to put integers into FPRs when using instructions like CVT
13172 and TRUNC. There's no point allowing sizes smaller than a word,
13173 because the FPU has no appropriate load/store instructions. */
13174 if (mclass
== MODE_INT
)
13175 return size
>= MIN_UNITS_PER_WORD
&& size
<= UNITS_PER_FPREG
;
13178 /* Don't allow vector modes in accumulators. */
13179 if (ACC_REG_P (regno
)
13180 && !VECTOR_MODE_P (mode
)
13181 && (INTEGRAL_MODE_P (mode
) || ALL_FIXED_POINT_MODE_P (mode
)))
13183 if (MD_REG_P (regno
))
13185 /* After a multiplication or division, clobbering HI makes
13186 the value of LO unpredictable, and vice versa. This means
13187 that, for all interesting cases, HI and LO are effectively
13190 We model this by requiring that any value that uses HI
13192 if (size
<= UNITS_PER_WORD
* 2)
13193 return regno
== (size
<= UNITS_PER_WORD
? LO_REGNUM
: MD_REG_FIRST
);
13197 /* DSP accumulators do not have the same restrictions as
13198 HI and LO, so we can treat them as normal doubleword
13200 if (size
<= UNITS_PER_WORD
)
13203 if (size
<= UNITS_PER_WORD
* 2
13204 && ((regno
- DSP_ACC_REG_FIRST
) & 1) == 0)
13209 if (ALL_COP_REG_P (regno
))
13210 return mclass
== MODE_INT
&& size
<= UNITS_PER_WORD
;
13212 if (regno
== GOT_VERSION_REGNUM
)
13213 return mode
== SImode
;
13218 /* Implement TARGET_HARD_REGNO_MODE_OK. */
13221 mips_hard_regno_mode_ok (unsigned int regno
, machine_mode mode
)
13223 return mips_hard_regno_mode_ok_p
[mode
][regno
];
13226 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */
13229 mips_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED
,
13230 unsigned int new_reg
)
13232 /* Interrupt functions can only use registers that have already been
13233 saved by the prologue, even if they would normally be call-clobbered. */
13234 if (cfun
->machine
->interrupt_handler_p
&& !df_regs_ever_live_p (new_reg
))
13240 /* Return nonzero if register REGNO can be used as a scratch register
13244 mips_hard_regno_scratch_ok (unsigned int regno
)
13246 /* See mips_hard_regno_rename_ok. */
13247 if (cfun
->machine
->interrupt_handler_p
&& !df_regs_ever_live_p (regno
))
13253 /* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED. Odd-numbered
13254 single-precision registers are not considered callee-saved for o32
13255 FPXX as they will be clobbered when run on an FR=1 FPU. MSA vector
13256 registers with MODE > 64 bits are part clobbered too. */
13259 mips_hard_regno_call_part_clobbered (unsigned int, unsigned int regno
,
13263 && hard_regno_nregs (regno
, mode
) == 1
13264 && FP_REG_P (regno
)
13265 && (regno
& 1) != 0)
13268 if (ISA_HAS_MSA
&& FP_REG_P (regno
) && GET_MODE_SIZE (mode
) > 8)
13274 /* Implement TARGET_HARD_REGNO_NREGS. */
13276 static unsigned int
13277 mips_hard_regno_nregs (unsigned int regno
, machine_mode mode
)
13279 if (ST_REG_P (regno
))
13280 /* The size of FP status registers is always 4, because they only hold
13281 CCmode values, and CCmode is always considered to be 4 bytes wide. */
13282 return (GET_MODE_SIZE (mode
) + 3) / 4;
13284 if (FP_REG_P (regno
))
13286 if (MSA_SUPPORTED_MODE_P (mode
))
13289 return (GET_MODE_SIZE (mode
) + UNITS_PER_FPREG
- 1) / UNITS_PER_FPREG
;
13292 /* All other registers are word-sized. */
13293 return (GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
13296 /* Implement CLASS_MAX_NREGS, taking the maximum of the cases
13297 in mips_hard_regno_nregs. */
13300 mips_class_max_nregs (enum reg_class rclass
, machine_mode mode
)
13306 left
= reg_class_contents
[rclass
];
13307 if (hard_reg_set_intersect_p (left
, reg_class_contents
[(int) ST_REGS
]))
13309 if (mips_hard_regno_mode_ok (ST_REG_FIRST
, mode
))
13310 size
= MIN (size
, 4);
13312 left
&= ~reg_class_contents
[ST_REGS
];
13314 if (hard_reg_set_intersect_p (left
, reg_class_contents
[(int) FP_REGS
]))
13316 if (mips_hard_regno_mode_ok (FP_REG_FIRST
, mode
))
13318 if (MSA_SUPPORTED_MODE_P (mode
))
13319 size
= MIN (size
, UNITS_PER_MSA_REG
);
13321 size
= MIN (size
, UNITS_PER_FPREG
);
13324 left
&= ~reg_class_contents
[FP_REGS
];
13326 if (!hard_reg_set_empty_p (left
))
13327 size
= MIN (size
, UNITS_PER_WORD
);
13328 return (GET_MODE_SIZE (mode
) + size
- 1) / size
;
13331 /* Implement TARGET_CAN_CHANGE_MODE_CLASS. */
13334 mips_can_change_mode_class (machine_mode from
,
13335 machine_mode to
, reg_class_t rclass
)
13337 /* Allow conversions between different Loongson integer vectors,
13338 and between those vectors and DImode. */
13339 if (GET_MODE_SIZE (from
) == 8 && GET_MODE_SIZE (to
) == 8
13340 && INTEGRAL_MODE_P (from
) && INTEGRAL_MODE_P (to
))
13343 /* Allow conversions between different MSA vector modes. */
13344 if (MSA_SUPPORTED_MODE_P (from
) && MSA_SUPPORTED_MODE_P (to
))
13347 /* Otherwise, there are several problems with changing the modes of
13348 values in floating-point registers:
13350 - When a multi-word value is stored in paired floating-point
13351 registers, the first register always holds the low word. We
13352 therefore can't allow FPRs to change between single-word and
13353 multi-word modes on big-endian targets.
13355 - GCC assumes that each word of a multiword register can be
13356 accessed individually using SUBREGs. This is not true for
13357 floating-point registers if they are bigger than a word.
13359 - Loading a 32-bit value into a 64-bit floating-point register
13360 will not sign-extend the value, despite what LOAD_EXTEND_OP
13361 says. We can't allow FPRs to change from SImode to a wider
13362 mode on 64-bit targets.
13364 - If the FPU has already interpreted a value in one format, we
13365 must not ask it to treat the value as having a different
13368 We therefore disallow all mode changes involving FPRs. */
13370 return !reg_classes_intersect_p (FP_REGS
, rclass
);
13373 /* Implement target hook small_register_classes_for_mode_p. */
13376 mips_small_register_classes_for_mode_p (machine_mode mode
13379 return TARGET_MIPS16
;
13382 /* Return true if moves in mode MODE can use the FPU's mov.fmt instruction,
13383 or use the MSA's move.v instruction. */
13386 mips_mode_ok_for_mov_fmt_p (machine_mode mode
)
13392 return TARGET_HARD_FLOAT
;
13395 return TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
;
13398 return TARGET_HARD_FLOAT
&& TARGET_PAIRED_SINGLE_FLOAT
;
13401 return MSA_SUPPORTED_MODE_P (mode
);
13405 /* Implement TARGET_MODES_TIEABLE_P. */
13408 mips_modes_tieable_p (machine_mode mode1
, machine_mode mode2
)
13410 /* FPRs allow no mode punning, so it's not worth tying modes if we'd
13411 prefer to put one of them in FPRs. */
13412 return (mode1
== mode2
13413 || (!mips_mode_ok_for_mov_fmt_p (mode1
)
13414 && !mips_mode_ok_for_mov_fmt_p (mode2
)));
13417 /* Implement TARGET_PREFERRED_RELOAD_CLASS. */
13420 mips_preferred_reload_class (rtx x
, reg_class_t rclass
)
13422 if (mips_dangerous_for_la25_p (x
) && reg_class_subset_p (LEA_REGS
, rclass
))
13425 if (reg_class_subset_p (FP_REGS
, rclass
)
13426 && mips_mode_ok_for_mov_fmt_p (GET_MODE (x
)))
13429 if (reg_class_subset_p (GR_REGS
, rclass
))
13432 if (TARGET_MIPS16
&& reg_class_subset_p (M16_REGS
, rclass
))
13438 /* RCLASS is a class involved in a REGISTER_MOVE_COST calculation.
13439 Return a "canonical" class to represent it in later calculations. */
13442 mips_canonicalize_move_class (reg_class_t rclass
)
13444 /* All moves involving accumulator registers have the same cost. */
13445 if (reg_class_subset_p (rclass
, ACC_REGS
))
13448 /* Likewise promote subclasses of general registers to the most
13449 interesting containing class. */
13450 if (TARGET_MIPS16
&& reg_class_subset_p (rclass
, M16_REGS
))
13452 else if (reg_class_subset_p (rclass
, GENERAL_REGS
))
13453 rclass
= GENERAL_REGS
;
13458 /* Return the cost of moving a value from a register of class FROM to a GPR.
13459 Return 0 for classes that are unions of other classes handled by this
13463 mips_move_to_gpr_cost (reg_class_t from
)
13469 /* A MIPS16 MOVE instruction, or a non-MIPS16 MOVE macro. */
13473 /* MFLO and MFHI. */
13483 /* This choice of value is historical. */
13491 /* Return the cost of moving a value from a GPR to a register of class TO.
13492 Return 0 for classes that are unions of other classes handled by this
13496 mips_move_from_gpr_cost (reg_class_t to
)
13502 /* A MIPS16 MOVE instruction, or a non-MIPS16 MOVE macro. */
13506 /* MTLO and MTHI. */
13516 /* This choice of value is historical. */
13524 /* Implement TARGET_REGISTER_MOVE_COST. Return 0 for classes that are the
13525 maximum of the move costs for subclasses; regclass will work out
13526 the maximum for us. */
13529 mips_register_move_cost (machine_mode mode
,
13530 reg_class_t from
, reg_class_t to
)
13535 from
= mips_canonicalize_move_class (from
);
13536 to
= mips_canonicalize_move_class (to
);
13538 /* Handle moves that can be done without using general-purpose registers. */
13539 if (from
== FP_REGS
)
13541 if (to
== FP_REGS
&& mips_mode_ok_for_mov_fmt_p (mode
))
13546 /* Handle cases in which only one class deviates from the ideal. */
13547 dregs
= TARGET_MIPS16
? M16_REGS
: GENERAL_REGS
;
13549 return mips_move_from_gpr_cost (to
);
13551 return mips_move_to_gpr_cost (from
);
13553 /* Handles cases that require a GPR temporary. */
13554 cost1
= mips_move_to_gpr_cost (from
);
13557 cost2
= mips_move_from_gpr_cost (to
);
13559 return cost1
+ cost2
;
13565 /* Implement TARGET_REGISTER_PRIORITY. */
13568 mips_register_priority (int hard_regno
)
13570 /* Treat MIPS16 registers with higher priority than other regs. */
13572 && TEST_HARD_REG_BIT (reg_class_contents
[M16_REGS
], hard_regno
))
13577 /* Implement TARGET_MEMORY_MOVE_COST. */
13580 mips_memory_move_cost (machine_mode mode
, reg_class_t rclass
, bool in
)
13582 return (mips_cost
->memory_latency
13583 + memory_move_secondary_cost (mode
, rclass
, in
));
13586 /* Implement TARGET_SECONDARY_MEMORY_NEEDED.
13588 When targeting the o32 FPXX ABI, all moves with a length of doubleword
13589 or greater must be performed by FR-mode-aware instructions.
13590 This can be achieved using MFHC1/MTHC1 when these instructions are
13591 available but otherwise moves must go via memory.
13592 For the o32 FP64A ABI, all odd-numbered moves with a length of
13593 doubleword or greater are required to use memory. Using MTC1/MFC1
13594 to access the lower-half of these registers would require a forbidden
13595 single-precision access. We require all double-word moves to use
13596 memory because adding even and odd floating-point registers classes
13597 would have a significant impact on the backend. */
13600 mips_secondary_memory_needed (machine_mode mode
, reg_class_t class1
,
13601 reg_class_t class2
)
13603 /* Ignore spilled pseudos. */
13604 if (lra_in_progress
&& (class1
== NO_REGS
|| class2
== NO_REGS
))
13607 if (((class1
== FP_REGS
) != (class2
== FP_REGS
))
13608 && ((TARGET_FLOATXX
&& !ISA_HAS_MXHC1
)
13609 || TARGET_O32_FP64A_ABI
)
13610 && GET_MODE_SIZE (mode
) >= 8)
13616 /* Return the register class required for a secondary register when
13617 copying between one of the registers in RCLASS and value X, which
13618 has mode MODE. X is the source of the move if IN_P, otherwise it
13619 is the destination. Return NO_REGS if no secondary register is
13623 mips_secondary_reload_class (enum reg_class rclass
,
13624 machine_mode mode
, rtx x
, bool)
13628 /* If X is a constant that cannot be loaded into $25, it must be loaded
13629 into some other GPR. No other register class allows a direct move. */
13630 if (mips_dangerous_for_la25_p (x
))
13631 return reg_class_subset_p (rclass
, LEA_REGS
) ? NO_REGS
: LEA_REGS
;
13633 regno
= true_regnum (x
);
13636 /* In MIPS16 mode, every move must involve a member of M16_REGS. */
13637 if (!reg_class_subset_p (rclass
, M16_REGS
) && !M16_REG_P (regno
))
13643 /* Copying from accumulator registers to anywhere other than a general
13644 register requires a temporary general register. */
13645 if (reg_class_subset_p (rclass
, ACC_REGS
))
13646 return GP_REG_P (regno
) ? NO_REGS
: GR_REGS
;
13647 if (ACC_REG_P (regno
))
13648 return reg_class_subset_p (rclass
, GR_REGS
) ? NO_REGS
: GR_REGS
;
13650 if (reg_class_subset_p (rclass
, FP_REGS
))
13654 && (GET_MODE_SIZE (mode
) == 4 || GET_MODE_SIZE (mode
) == 8)))
13655 /* In this case we can use lwc1, swc1, ldc1 or sdc1. We'll use
13656 pairs of lwc1s and swc1s if ldc1 and sdc1 are not supported. */
13659 if (MEM_P (x
) && MSA_SUPPORTED_MODE_P (mode
))
13660 /* In this case we can use MSA LD.* and ST.*. */
13663 if (GP_REG_P (regno
) || x
== CONST0_RTX (mode
))
13664 /* In this case we can use mtc1, mfc1, dmtc1 or dmfc1. */
13667 if (CONSTANT_P (x
) && !targetm
.cannot_force_const_mem (mode
, x
))
13668 /* We can force the constant to memory and use lwc1
13669 and ldc1. As above, we will use pairs of lwc1s if
13670 ldc1 is not supported. */
13673 if (FP_REG_P (regno
) && mips_mode_ok_for_mov_fmt_p (mode
))
13674 /* In this case we can use mov.fmt. */
13677 /* Otherwise, we need to reload through an integer register. */
13680 if (FP_REG_P (regno
))
13681 return reg_class_subset_p (rclass
, GR_REGS
) ? NO_REGS
: GR_REGS
;
13686 /* Implement TARGET_MODE_REP_EXTENDED. */
13689 mips_mode_rep_extended (scalar_int_mode mode
, scalar_int_mode mode_rep
)
13691 /* On 64-bit targets, SImode register values are sign-extended to DImode. */
13692 if (TARGET_64BIT
&& mode
== SImode
&& mode_rep
== DImode
)
13693 return SIGN_EXTEND
;
13698 /* Implement TARGET_VALID_POINTER_MODE. */
13701 mips_valid_pointer_mode (scalar_int_mode mode
)
13703 return mode
== SImode
|| (TARGET_64BIT
&& mode
== DImode
);
13706 /* Implement TARGET_VECTOR_MODE_SUPPORTED_P. */
13709 mips_vector_mode_supported_p (machine_mode mode
)
13714 return TARGET_PAIRED_SINGLE_FLOAT
;
13729 return TARGET_LOONGSON_MMI
;
13732 return MSA_SUPPORTED_MODE_P (mode
);
13736 /* Implement TARGET_SCALAR_MODE_SUPPORTED_P. */
13739 mips_scalar_mode_supported_p (scalar_mode mode
)
13741 if (ALL_FIXED_POINT_MODE_P (mode
)
13742 && GET_MODE_PRECISION (mode
) <= 2 * BITS_PER_WORD
)
13745 return default_scalar_mode_supported_p (mode
);
13748 /* Implement TARGET_VECTORIZE_PREFERRED_SIMD_MODE. */
13750 static machine_mode
13751 mips_preferred_simd_mode (scalar_mode mode
)
13753 if (TARGET_PAIRED_SINGLE_FLOAT
13783 /* Implement TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES. */
13785 static unsigned int
13786 mips_autovectorize_vector_modes (vector_modes
*modes
, bool)
13789 modes
->safe_push (V16QImode
);
13794 static GTY (()) rtx speculation_barrier_libfunc
;
13796 /* Implement TARGET_INIT_LIBFUNCS. */
13799 mips_init_libfuncs (void)
13801 if (TARGET_FIX_VR4120
)
13803 /* Register the special divsi3 and modsi3 functions needed to work
13804 around VR4120 division errata. */
13805 set_optab_libfunc (sdiv_optab
, SImode
, "__vr4120_divsi3");
13806 set_optab_libfunc (smod_optab
, SImode
, "__vr4120_modsi3");
13809 if (TARGET_MIPS16
&& TARGET_HARD_FLOAT_ABI
)
13811 /* Register the MIPS16 -mhard-float stubs. */
13812 set_optab_libfunc (add_optab
, SFmode
, "__mips16_addsf3");
13813 set_optab_libfunc (sub_optab
, SFmode
, "__mips16_subsf3");
13814 set_optab_libfunc (smul_optab
, SFmode
, "__mips16_mulsf3");
13815 set_optab_libfunc (sdiv_optab
, SFmode
, "__mips16_divsf3");
13817 set_optab_libfunc (eq_optab
, SFmode
, "__mips16_eqsf2");
13818 set_optab_libfunc (ne_optab
, SFmode
, "__mips16_nesf2");
13819 set_optab_libfunc (gt_optab
, SFmode
, "__mips16_gtsf2");
13820 set_optab_libfunc (ge_optab
, SFmode
, "__mips16_gesf2");
13821 set_optab_libfunc (lt_optab
, SFmode
, "__mips16_ltsf2");
13822 set_optab_libfunc (le_optab
, SFmode
, "__mips16_lesf2");
13823 set_optab_libfunc (unord_optab
, SFmode
, "__mips16_unordsf2");
13825 set_conv_libfunc (sfix_optab
, SImode
, SFmode
, "__mips16_fix_truncsfsi");
13826 set_conv_libfunc (sfloat_optab
, SFmode
, SImode
, "__mips16_floatsisf");
13827 set_conv_libfunc (ufloat_optab
, SFmode
, SImode
, "__mips16_floatunsisf");
13829 if (TARGET_DOUBLE_FLOAT
)
13831 set_optab_libfunc (add_optab
, DFmode
, "__mips16_adddf3");
13832 set_optab_libfunc (sub_optab
, DFmode
, "__mips16_subdf3");
13833 set_optab_libfunc (smul_optab
, DFmode
, "__mips16_muldf3");
13834 set_optab_libfunc (sdiv_optab
, DFmode
, "__mips16_divdf3");
13836 set_optab_libfunc (eq_optab
, DFmode
, "__mips16_eqdf2");
13837 set_optab_libfunc (ne_optab
, DFmode
, "__mips16_nedf2");
13838 set_optab_libfunc (gt_optab
, DFmode
, "__mips16_gtdf2");
13839 set_optab_libfunc (ge_optab
, DFmode
, "__mips16_gedf2");
13840 set_optab_libfunc (lt_optab
, DFmode
, "__mips16_ltdf2");
13841 set_optab_libfunc (le_optab
, DFmode
, "__mips16_ledf2");
13842 set_optab_libfunc (unord_optab
, DFmode
, "__mips16_unorddf2");
13844 set_conv_libfunc (sext_optab
, DFmode
, SFmode
,
13845 "__mips16_extendsfdf2");
13846 set_conv_libfunc (trunc_optab
, SFmode
, DFmode
,
13847 "__mips16_truncdfsf2");
13848 set_conv_libfunc (sfix_optab
, SImode
, DFmode
,
13849 "__mips16_fix_truncdfsi");
13850 set_conv_libfunc (sfloat_optab
, DFmode
, SImode
,
13851 "__mips16_floatsidf");
13852 set_conv_libfunc (ufloat_optab
, DFmode
, SImode
,
13853 "__mips16_floatunsidf");
13857 /* The MIPS16 ISA does not have an encoding for "sync", so we rely
13858 on an external non-MIPS16 routine to implement __sync_synchronize.
13859 Similarly for the rest of the ll/sc libfuncs. */
13862 synchronize_libfunc
= init_one_libfunc ("__sync_synchronize");
13863 init_sync_libfuncs (UNITS_PER_WORD
);
13865 speculation_barrier_libfunc
= init_one_libfunc ("__speculation_barrier");
13868 /* Build up a multi-insn sequence that loads label TARGET into $AT. */
13871 mips_process_load_label (rtx target
)
13873 rtx base
, gp
, intop
;
13874 HOST_WIDE_INT offset
;
13876 mips_multi_start ();
13880 mips_multi_add_insn ("lw\t%@,%%got_page(%0)(%+)", target
, 0);
13881 mips_multi_add_insn ("addiu\t%@,%@,%%got_ofst(%0)", target
, 0);
13885 mips_multi_add_insn ("ld\t%@,%%got_page(%0)(%+)", target
, 0);
13886 mips_multi_add_insn ("daddiu\t%@,%@,%%got_ofst(%0)", target
, 0);
13890 gp
= pic_offset_table_rtx
;
13891 if (mips_cfun_has_cprestore_slot_p ())
13893 gp
= gen_rtx_REG (Pmode
, AT_REGNUM
);
13894 mips_get_cprestore_base_and_offset (&base
, &offset
, true);
13895 if (!SMALL_OPERAND (offset
))
13897 intop
= GEN_INT (CONST_HIGH_PART (offset
));
13898 mips_multi_add_insn ("lui\t%0,%1", gp
, intop
, 0);
13899 mips_multi_add_insn ("addu\t%0,%0,%1", gp
, base
, 0);
13902 offset
= CONST_LOW_PART (offset
);
13904 intop
= GEN_INT (offset
);
13905 if (ISA_HAS_LOAD_DELAY
)
13906 mips_multi_add_insn ("lw\t%0,%1(%2)%#", gp
, intop
, base
, 0);
13908 mips_multi_add_insn ("lw\t%0,%1(%2)", gp
, intop
, base
, 0);
13910 if (ISA_HAS_LOAD_DELAY
)
13911 mips_multi_add_insn ("lw\t%@,%%got(%0)(%1)%#", target
, gp
, 0);
13913 mips_multi_add_insn ("lw\t%@,%%got(%0)(%1)", target
, gp
, 0);
13914 mips_multi_add_insn ("addiu\t%@,%@,%%lo(%0)", target
, 0);
13919 /* Return the number of instructions needed to load a label into $AT. */
13921 static unsigned int
13922 mips_load_label_num_insns (void)
13924 if (cfun
->machine
->load_label_num_insns
== 0)
13926 mips_process_load_label (pc_rtx
);
13927 cfun
->machine
->load_label_num_insns
= mips_multi_num_insns
;
13929 return cfun
->machine
->load_label_num_insns
;
13932 /* Emit an asm sequence to start a noat block and load the address
13933 of a label into $1. */
13936 mips_output_load_label (rtx target
)
13938 mips_push_asm_switch (&mips_noat
);
13939 if (TARGET_EXPLICIT_RELOCS
)
13941 mips_process_load_label (target
);
13942 mips_multi_write ();
13946 if (Pmode
== DImode
)
13947 output_asm_insn ("dla\t%@,%0", &target
);
13949 output_asm_insn ("la\t%@,%0", &target
);
13953 /* Return the length of INSN. LENGTH is the initial length computed by
13954 attributes in the machine-description file. */
13957 mips_adjust_insn_length (rtx_insn
*insn
, int length
)
13959 /* mips.md uses MAX_PIC_BRANCH_LENGTH as a placeholder for the length
13960 of a PIC long-branch sequence. Substitute the correct value. */
13961 if (length
== MAX_PIC_BRANCH_LENGTH
13963 && INSN_CODE (insn
) >= 0
13964 && get_attr_type (insn
) == TYPE_BRANCH
)
13966 /* Add the branch-over instruction and its delay slot, if this
13967 is a conditional branch. */
13968 length
= simplejump_p (insn
) ? 0 : 8;
13970 /* Add the size of a load into $AT. */
13971 length
+= BASE_INSN_LENGTH
* mips_load_label_num_insns ();
13973 /* Add the length of an indirect jump, ignoring the delay slot. */
13974 length
+= TARGET_COMPRESSION
? 2 : 4;
13977 /* A unconditional jump has an unfilled delay slot if it is not part
13978 of a sequence. A conditional jump normally has a delay slot, but
13979 does not on MIPS16. */
13980 if (CALL_P (insn
) || (TARGET_MIPS16
? simplejump_p (insn
) : JUMP_P (insn
)))
13981 length
+= TARGET_MIPS16
? 2 : 4;
13983 /* See how many nops might be needed to avoid hardware hazards. */
13984 if (!cfun
->machine
->ignore_hazard_length_p
13986 && INSN_CODE (insn
) >= 0)
13987 switch (get_attr_hazard (insn
))
13993 case HAZARD_FORBIDDEN_SLOT
:
13994 length
+= NOP_INSN_LENGTH
;
13998 length
+= NOP_INSN_LENGTH
* 2;
14005 /* Return the asm template for a call. OPERANDS are the operands, TARGET_OPNO
14006 is the operand number of the target. SIZE_OPNO is the operand number of
14007 the argument size operand that can optionally hold the call attributes. If
14008 SIZE_OPNO is not -1 and the call is indirect, use the function symbol from
14009 the call attributes to attach a R_MIPS_JALR relocation to the call. LINK_P
14010 indicates whether the jump is a call and needs to set the link register.
14012 When generating GOT code without explicit relocation operators, all calls
14013 should use assembly macros. Otherwise, all indirect calls should use "jr"
14014 or "jalr"; we will arrange to restore $gp afterwards if necessary. Finally,
14015 we can only generate direct calls for -mabicalls by temporarily switching
14018 For microMIPS jal(r), we try to generate jal(r)s when a 16-bit
14019 instruction is in the delay slot of jal(r).
14021 Where compact branches are available, we try to use them if the delay slot
14022 has a NOP (or equivalently delay slots were not enabled for the instruction
14026 mips_output_jump (rtx
*operands
, int target_opno
, int size_opno
, bool link_p
)
14028 static char buffer
[300];
14030 bool reg_p
= REG_P (operands
[target_opno
]);
14032 const char *and_link
= link_p
? "al" : "";
14033 const char *reg
= reg_p
? "r" : "";
14034 const char *compact
= "";
14035 const char *nop
= "%/";
14036 const char *short_delay
= link_p
? "%!" : "";
14037 const char *insn_name
= TARGET_CB_NEVER
|| reg_p
? "j" : "b";
14039 /* Compact branches can only be described when the ISA has support for them
14040 as both the compact formatter '%:' and the delay slot NOP formatter '%/'
14041 work as a mutually exclusive pair. I.e. a NOP is never required if a
14042 compact form is available. */
14043 if (!final_sequence
14044 && (TARGET_CB_MAYBE
14045 || (ISA_HAS_JRC
&& !link_p
&& reg_p
)))
14051 if (TARGET_USE_GOT
&& !TARGET_EXPLICIT_RELOCS
)
14052 sprintf (s
, "%%*%s%s\t%%%d%%/", insn_name
, and_link
, target_opno
);
14055 if (!reg_p
&& TARGET_ABICALLS_PIC2
)
14056 s
+= sprintf (s
, ".option\tpic0\n\t");
14058 if (reg_p
&& mips_get_pic_call_symbol (operands
, size_opno
))
14059 s
+= sprintf (s
, "%%*.reloc\t1f,%s,%%%d\n1:\t",
14060 TARGET_MICROMIPS
? "R_MICROMIPS_JALR" : "R_MIPS_JALR",
14063 s
+= sprintf (s
, "%%*");
14065 s
+= sprintf (s
, "%s%s%s%s%s\t%%%d%s",
14066 insn_name
, and_link
, reg
, compact
, short_delay
,
14069 if (!reg_p
&& TARGET_ABICALLS_PIC2
)
14070 s
+= sprintf (s
, "\n\t.option\tpic2");
14075 /* Return the assembly code for INSN, which has the operands given by
14076 OPERANDS, and which branches to OPERANDS[0] if some condition is true.
14077 BRANCH_IF_TRUE is the asm template that should be used if OPERANDS[0]
14078 is in range of a direct branch. BRANCH_IF_FALSE is an inverted
14079 version of BRANCH_IF_TRUE. */
14082 mips_output_conditional_branch (rtx_insn
*insn
, rtx
*operands
,
14083 const char *branch_if_true
,
14084 const char *branch_if_false
)
14086 unsigned int length
;
14089 gcc_assert (LABEL_P (operands
[0]));
14091 length
= get_attr_length (insn
);
14094 /* Just a simple conditional branch. */
14095 mips_branch_likely
= (final_sequence
&& INSN_ANNULLED_BRANCH_P (insn
));
14096 return branch_if_true
;
14099 /* Generate a reversed branch around a direct jump. This fallback does
14100 not use branch-likely instructions. */
14101 mips_branch_likely
= false;
14102 rtx_code_label
*not_taken
= gen_label_rtx ();
14103 taken
= operands
[0];
14105 /* Generate the reversed branch to NOT_TAKEN. */
14106 operands
[0] = not_taken
;
14107 output_asm_insn (branch_if_false
, operands
);
14109 /* If INSN has a delay slot, we must provide delay slots for both the
14110 branch to NOT_TAKEN and the conditional jump. We must also ensure
14111 that INSN's delay slot is executed in the appropriate cases. */
14112 if (final_sequence
)
14114 /* This first delay slot will always be executed, so use INSN's
14115 delay slot if is not annulled. */
14116 if (!INSN_ANNULLED_BRANCH_P (insn
))
14118 final_scan_insn (final_sequence
->insn (1),
14119 asm_out_file
, optimize
, 1, NULL
);
14120 final_sequence
->insn (1)->set_deleted ();
14123 output_asm_insn ("nop", 0);
14124 fprintf (asm_out_file
, "\n");
14127 /* Output the unconditional branch to TAKEN. */
14128 if (TARGET_ABSOLUTE_JUMPS
&& TARGET_CB_MAYBE
)
14130 /* Add a hazard nop. */
14131 if (!final_sequence
)
14133 output_asm_insn ("nop\t\t# hazard nop", 0);
14134 fprintf (asm_out_file
, "\n");
14136 output_asm_insn (MIPS_ABSOLUTE_JUMP ("bc\t%0"), &taken
);
14138 else if (TARGET_ABSOLUTE_JUMPS
)
14139 output_asm_insn (MIPS_ABSOLUTE_JUMP ("j\t%0%/"), &taken
);
14142 mips_output_load_label (taken
);
14143 if (TARGET_CB_MAYBE
)
14144 output_asm_insn ("jrc\t%@%]", 0);
14146 output_asm_insn ("jr\t%@%]%/", 0);
14149 /* Now deal with its delay slot; see above. */
14150 if (final_sequence
)
14152 /* This delay slot will only be executed if the branch is taken.
14153 Use INSN's delay slot if is annulled. */
14154 if (INSN_ANNULLED_BRANCH_P (insn
))
14156 final_scan_insn (final_sequence
->insn (1),
14157 asm_out_file
, optimize
, 1, NULL
);
14158 final_sequence
->insn (1)->set_deleted ();
14160 else if (TARGET_CB_NEVER
)
14161 output_asm_insn ("nop", 0);
14162 fprintf (asm_out_file
, "\n");
14165 /* Output NOT_TAKEN. */
14166 targetm
.asm_out
.internal_label (asm_out_file
, "L",
14167 CODE_LABEL_NUMBER (not_taken
));
14171 /* Return the assembly code for INSN, which branches to OPERANDS[0]
14172 if some equality condition is true. The condition is given by
14173 OPERANDS[1] if !INVERTED_P, otherwise it is the inverse of
14174 OPERANDS[1]. OPERANDS[2] is the comparison's first operand;
14175 OPERANDS[3] is the second operand and may be zero or a register. */
14178 mips_output_equal_conditional_branch (rtx_insn
* insn
, rtx
*operands
,
14181 const char *branch
[2];
14182 /* For a simple BNEZ or BEQZ microMIPSr3 branch. */
14183 if (TARGET_MICROMIPS
14184 && mips_isa_rev
<= 5
14185 && operands
[3] == const0_rtx
14186 && get_attr_length (insn
) <= 8)
14188 if (mips_cb
== MIPS_CB_OPTIMAL
)
14190 branch
[!inverted_p
] = "%*b%C1z%:\t%2,%0";
14191 branch
[inverted_p
] = "%*b%N1z%:\t%2,%0";
14195 branch
[!inverted_p
] = "%*b%C1z\t%2,%0%/";
14196 branch
[inverted_p
] = "%*b%N1z\t%2,%0%/";
14199 else if (TARGET_CB_MAYBE
)
14201 if (operands
[3] == const0_rtx
)
14203 branch
[!inverted_p
] = MIPS_BRANCH_C ("b%C1z", "%2,%0");
14204 branch
[inverted_p
] = MIPS_BRANCH_C ("b%N1z", "%2,%0");
14206 else if (REGNO (operands
[2]) != REGNO (operands
[3]))
14208 branch
[!inverted_p
] = MIPS_BRANCH_C ("b%C1", "%2,%3,%0");
14209 branch
[inverted_p
] = MIPS_BRANCH_C ("b%N1", "%2,%3,%0");
14213 /* This case is degenerate. It should not happen, but does. */
14214 if (GET_CODE (operands
[1]) == NE
)
14215 inverted_p
= !inverted_p
;
14217 branch
[!inverted_p
] = MIPS_BRANCH_C ("b", "%0");
14218 branch
[inverted_p
] = "%*\t\t# branch never";
14223 branch
[!inverted_p
] = MIPS_BRANCH ("b%C1", "%2,%z3,%0");
14224 branch
[inverted_p
] = MIPS_BRANCH ("b%N1", "%2,%z3,%0");
14227 return mips_output_conditional_branch (insn
, operands
, branch
[1], branch
[0]);
14230 /* Return the assembly code for INSN, which branches to OPERANDS[0]
14231 if some ordering condition is true. The condition is given by
14232 OPERANDS[1] if !INVERTED_P, otherwise it is the inverse of
14233 OPERANDS[1]. OPERANDS[2] is the comparison's first operand;
14234 OPERANDS[3] is the second operand and may be zero or a register. */
14237 mips_output_order_conditional_branch (rtx_insn
*insn
, rtx
*operands
,
14240 const char *branch
[2];
14242 /* Make BRANCH[1] branch to OPERANDS[0] when the condition is true.
14243 Make BRANCH[0] branch on the inverse condition. */
14244 if (operands
[3] != const0_rtx
)
14246 /* Handle degenerate cases that should not, but do, occur. */
14247 if (REGNO (operands
[2]) == REGNO (operands
[3]))
14249 switch (GET_CODE (operands
[1]))
14253 inverted_p
= !inverted_p
;
14254 /* Fall through. */
14257 branch
[!inverted_p
] = MIPS_BRANCH_C ("b", "%0");
14258 branch
[inverted_p
] = "%*\t\t# branch never";
14261 gcc_unreachable ();
14266 branch
[!inverted_p
] = MIPS_BRANCH_C ("b%C1", "%2,%3,%0");
14267 branch
[inverted_p
] = MIPS_BRANCH_C ("b%N1", "%2,%3,%0");
14272 switch (GET_CODE (operands
[1]))
14274 /* These cases are equivalent to comparisons against zero. */
14276 inverted_p
= !inverted_p
;
14277 /* Fall through. */
14279 if (TARGET_CB_MAYBE
)
14281 branch
[!inverted_p
] = MIPS_BRANCH_C ("bnez", "%2,%0");
14282 branch
[inverted_p
] = MIPS_BRANCH_C ("beqz", "%2,%0");
14286 branch
[!inverted_p
] = MIPS_BRANCH ("bne", "%2,%.,%0");
14287 branch
[inverted_p
] = MIPS_BRANCH ("beq", "%2,%.,%0");
14291 /* These cases are always true or always false. */
14293 inverted_p
= !inverted_p
;
14294 /* Fall through. */
14296 if (TARGET_CB_MAYBE
)
14298 branch
[!inverted_p
] = MIPS_BRANCH_C ("b", "%0");
14299 branch
[inverted_p
] = "%*\t\t# branch never";
14303 branch
[!inverted_p
] = MIPS_BRANCH ("beq", "%.,%.,%0");
14304 branch
[inverted_p
] = MIPS_BRANCH ("bne", "%.,%.,%0");
14309 if (TARGET_CB_MAYBE
)
14311 branch
[!inverted_p
] = MIPS_BRANCH_C ("b%C1z", "%2,%0");
14312 branch
[inverted_p
] = MIPS_BRANCH_C ("b%N1z", "%2,%0");
14316 branch
[!inverted_p
] = MIPS_BRANCH ("b%C1z", "%2,%0");
14317 branch
[inverted_p
] = MIPS_BRANCH ("b%N1z", "%2,%0");
14322 return mips_output_conditional_branch (insn
, operands
, branch
[1], branch
[0]);
14325 /* Start a block of code that needs access to the LL, SC and SYNC
14329 mips_start_ll_sc_sync_block (void)
14331 if (!ISA_HAS_LL_SC
)
14333 output_asm_insn (".set\tpush", 0);
14335 output_asm_insn (".set\tmips3", 0);
14337 output_asm_insn (".set\tmips2", 0);
14341 /* End a block started by mips_start_ll_sc_sync_block. */
14344 mips_end_ll_sc_sync_block (void)
14346 if (!ISA_HAS_LL_SC
)
14347 output_asm_insn (".set\tpop", 0);
14350 /* Output and/or return the asm template for a sync instruction. */
14353 mips_output_sync (void)
14355 mips_start_ll_sc_sync_block ();
14356 output_asm_insn ("sync", 0);
14357 mips_end_ll_sc_sync_block ();
14361 /* Return the asm template associated with sync_insn1 value TYPE.
14362 IS_64BIT_P is true if we want a 64-bit rather than 32-bit operation. */
14364 static const char *
14365 mips_sync_insn1_template (enum attr_sync_insn1 type
, bool is_64bit_p
)
14369 case SYNC_INSN1_MOVE
:
14370 return "move\t%0,%z2";
14371 case SYNC_INSN1_LI
:
14372 return "li\t%0,%2";
14373 case SYNC_INSN1_ADDU
:
14374 return is_64bit_p
? "daddu\t%0,%1,%z2" : "addu\t%0,%1,%z2";
14375 case SYNC_INSN1_ADDIU
:
14376 return is_64bit_p
? "daddiu\t%0,%1,%2" : "addiu\t%0,%1,%2";
14377 case SYNC_INSN1_SUBU
:
14378 return is_64bit_p
? "dsubu\t%0,%1,%z2" : "subu\t%0,%1,%z2";
14379 case SYNC_INSN1_AND
:
14380 return "and\t%0,%1,%z2";
14381 case SYNC_INSN1_ANDI
:
14382 return "andi\t%0,%1,%2";
14383 case SYNC_INSN1_OR
:
14384 return "or\t%0,%1,%z2";
14385 case SYNC_INSN1_ORI
:
14386 return "ori\t%0,%1,%2";
14387 case SYNC_INSN1_XOR
:
14388 return "xor\t%0,%1,%z2";
14389 case SYNC_INSN1_XORI
:
14390 return "xori\t%0,%1,%2";
14392 gcc_unreachable ();
14395 /* Return the asm template associated with sync_insn2 value TYPE. */
14397 static const char *
14398 mips_sync_insn2_template (enum attr_sync_insn2 type
)
14402 case SYNC_INSN2_NOP
:
14403 gcc_unreachable ();
14404 case SYNC_INSN2_AND
:
14405 return "and\t%0,%1,%z2";
14406 case SYNC_INSN2_XOR
:
14407 return "xor\t%0,%1,%z2";
14408 case SYNC_INSN2_NOT
:
14409 return "nor\t%0,%1,%.";
14411 gcc_unreachable ();
14414 /* OPERANDS are the operands to a sync loop instruction and INDEX is
14415 the value of the one of the sync_* attributes. Return the operand
14416 referred to by the attribute, or DEFAULT_VALUE if the insn doesn't
14417 have the associated attribute. */
14420 mips_get_sync_operand (rtx
*operands
, int index
, rtx default_value
)
14423 default_value
= operands
[index
- 1];
14424 return default_value
;
14427 /* INSN is a sync loop with operands OPERANDS. Build up a multi-insn
14428 sequence for it. */
14431 mips_process_sync_loop (rtx_insn
*insn
, rtx
*operands
)
14433 rtx at
, mem
, oldval
, newval
, inclusive_mask
, exclusive_mask
;
14434 rtx required_oldval
, insn1_op2
, tmp1
, tmp2
, tmp3
, cmp
;
14435 unsigned int tmp3_insn
;
14436 enum attr_sync_insn1 insn1
;
14437 enum attr_sync_insn2 insn2
;
14440 enum memmodel model
;
14442 /* Read an operand from the sync_WHAT attribute and store it in
14443 variable WHAT. DEFAULT is the default value if no attribute
14445 #define READ_OPERAND(WHAT, DEFAULT) \
14446 WHAT = mips_get_sync_operand (operands, (int) get_attr_sync_##WHAT (insn), \
14449 /* Read the memory. */
14450 READ_OPERAND (mem
, 0);
14452 is_64bit_p
= (GET_MODE_BITSIZE (GET_MODE (mem
)) == 64);
14454 /* Read the other attributes. */
14455 at
= gen_rtx_REG (GET_MODE (mem
), AT_REGNUM
);
14456 READ_OPERAND (oldval
, at
);
14457 READ_OPERAND (cmp
, 0);
14458 READ_OPERAND (newval
, at
);
14459 READ_OPERAND (inclusive_mask
, 0);
14460 READ_OPERAND (exclusive_mask
, 0);
14461 READ_OPERAND (required_oldval
, 0);
14462 READ_OPERAND (insn1_op2
, 0);
14463 insn1
= get_attr_sync_insn1 (insn
);
14464 insn2
= get_attr_sync_insn2 (insn
);
14466 /* Don't bother setting CMP result that is never used. */
14467 if (cmp
&& find_reg_note (insn
, REG_UNUSED
, cmp
))
14470 memmodel_attr
= get_attr_sync_memmodel (insn
);
14471 switch (memmodel_attr
)
14474 model
= MEMMODEL_ACQ_REL
;
14477 model
= MEMMODEL_ACQUIRE
;
14480 model
= memmodel_from_int (INTVAL (operands
[memmodel_attr
]));
14483 mips_multi_start ();
14485 /* Output the release side of the memory barrier. */
14486 if (need_atomic_barrier_p (model
, true))
14488 if (required_oldval
== 0 && TARGET_OCTEON
)
14490 /* Octeon doesn't reorder reads, so a full barrier can be
14491 created by using SYNCW to order writes combined with the
14492 write from the following SC. When the SC successfully
14493 completes, we know that all preceding writes are also
14494 committed to the coherent memory system. It is possible
14495 for a single SYNCW to fail, but a pair of them will never
14496 fail, so we use two. */
14497 mips_multi_add_insn ("syncw", NULL
);
14498 mips_multi_add_insn ("syncw", NULL
);
14501 mips_multi_add_insn ("sync", NULL
);
14504 /* Output the branch-back label. */
14505 mips_multi_add_label ("1:");
14507 /* OLDVAL = *MEM. */
14508 mips_multi_add_insn (is_64bit_p
? "lld\t%0,%1" : "ll\t%0,%1",
14509 oldval
, mem
, NULL
);
14511 /* if ((OLDVAL & INCLUSIVE_MASK) != REQUIRED_OLDVAL) goto 2. */
14512 if (required_oldval
)
14514 if (inclusive_mask
== 0)
14518 gcc_assert (oldval
!= at
);
14519 mips_multi_add_insn ("and\t%0,%1,%2",
14520 at
, oldval
, inclusive_mask
, NULL
);
14523 if (TARGET_CB_NEVER
)
14524 mips_multi_add_insn ("bne\t%0,%z1,2f", tmp1
, required_oldval
, NULL
);
14526 /* CMP = 0 [delay slot]. */
14528 mips_multi_add_insn ("li\t%0,0", cmp
, NULL
);
14530 if (TARGET_CB_MAYBE
&& required_oldval
== const0_rtx
)
14531 mips_multi_add_insn ("bnezc\t%0,2f", tmp1
, NULL
);
14532 else if (TARGET_CB_MAYBE
)
14533 mips_multi_add_insn ("bnec\t%0,%1,2f", tmp1
, required_oldval
, NULL
);
14537 /* $TMP1 = OLDVAL & EXCLUSIVE_MASK. */
14538 if (exclusive_mask
== 0)
14542 gcc_assert (oldval
!= at
);
14543 mips_multi_add_insn ("and\t%0,%1,%z2",
14544 at
, oldval
, exclusive_mask
, NULL
);
14548 /* $TMP2 = INSN1 (OLDVAL, INSN1_OP2).
14550 We can ignore moves if $TMP4 != INSN1_OP2, since we'll still emit
14551 at least one instruction in that case. */
14552 if (insn1
== SYNC_INSN1_MOVE
14553 && (tmp1
!= const0_rtx
|| insn2
!= SYNC_INSN2_NOP
))
14557 mips_multi_add_insn (mips_sync_insn1_template (insn1
, is_64bit_p
),
14558 newval
, oldval
, insn1_op2
, NULL
);
14562 /* $TMP3 = INSN2 ($TMP2, INCLUSIVE_MASK). */
14563 if (insn2
== SYNC_INSN2_NOP
)
14567 mips_multi_add_insn (mips_sync_insn2_template (insn2
),
14568 newval
, tmp2
, inclusive_mask
, NULL
);
14571 tmp3_insn
= mips_multi_last_index ();
14573 /* $AT = $TMP1 | $TMP3. */
14574 if (tmp1
== const0_rtx
|| tmp3
== const0_rtx
)
14576 mips_multi_set_operand (tmp3_insn
, 0, at
);
14581 gcc_assert (tmp1
!= tmp3
);
14582 mips_multi_add_insn ("or\t%0,%1,%2", at
, tmp1
, tmp3
, NULL
);
14585 /* if (!commit (*MEM = $AT)) goto 1.
14587 This will sometimes be a delayed branch; see the write code below
14589 mips_multi_add_insn (is_64bit_p
? "scd\t%0,%1" : "sc\t%0,%1", at
, mem
, NULL
);
14591 /* When using branch likely (-mfix-r10000), the delay slot instruction
14592 will be annulled on false. The normal delay slot instructions
14593 calculate the overall result of the atomic operation and must not
14594 be annulled. To ensure this behavior unconditionally use a NOP
14595 in the delay slot for the branch likely case. */
14597 if (TARGET_CB_MAYBE
)
14598 mips_multi_add_insn ("beqzc\t%0,1b", at
, NULL
);
14600 mips_multi_add_insn ("beq%?\t%0,%.,1b%~", at
, NULL
);
14602 /* if (INSN1 != MOVE && INSN1 != LI) NEWVAL = $TMP3 [delay slot]. */
14603 if (insn1
!= SYNC_INSN1_MOVE
&& insn1
!= SYNC_INSN1_LI
&& tmp3
!= newval
)
14605 mips_multi_copy_insn (tmp3_insn
);
14606 mips_multi_set_operand (mips_multi_last_index (), 0, newval
);
14608 else if (!(required_oldval
&& cmp
) && !mips_branch_likely
)
14609 mips_multi_add_insn ("nop", NULL
);
14611 /* CMP = 1 -- either standalone or in a delay slot. */
14612 if (required_oldval
&& cmp
)
14613 mips_multi_add_insn ("li\t%0,1", cmp
, NULL
);
14615 /* Output the acquire side of the memory barrier. */
14616 if (TARGET_SYNC_AFTER_SC
&& need_atomic_barrier_p (model
, false))
14617 mips_multi_add_insn ("sync", NULL
);
14619 /* Output the exit label, if needed. */
14620 if (required_oldval
)
14621 mips_multi_add_label ("2:");
14623 #undef READ_OPERAND
14626 /* Output and/or return the asm template for sync loop INSN, which has
14627 the operands given by OPERANDS. */
14630 mips_output_sync_loop (rtx_insn
*insn
, rtx
*operands
)
14632 /* Use branch-likely instructions to work around the LL/SC R10000
14634 mips_branch_likely
= TARGET_FIX_R10000
;
14636 mips_process_sync_loop (insn
, operands
);
14638 mips_push_asm_switch (&mips_noreorder
);
14639 mips_push_asm_switch (&mips_nomacro
);
14640 mips_push_asm_switch (&mips_noat
);
14641 mips_start_ll_sc_sync_block ();
14643 mips_multi_write ();
14645 mips_end_ll_sc_sync_block ();
14646 mips_pop_asm_switch (&mips_noat
);
14647 mips_pop_asm_switch (&mips_nomacro
);
14648 mips_pop_asm_switch (&mips_noreorder
);
14653 /* Return the number of individual instructions in sync loop INSN,
14654 which has the operands given by OPERANDS. */
14657 mips_sync_loop_insns (rtx_insn
*insn
, rtx
*operands
)
14659 /* Use branch-likely instructions to work around the LL/SC R10000
14661 mips_branch_likely
= TARGET_FIX_R10000
;
14662 mips_process_sync_loop (insn
, operands
);
14663 return mips_multi_num_insns
;
14666 /* Return the assembly code for DIV or DDIV instruction DIVISION, which has
14667 the operands given by OPERANDS. Add in a divide-by-zero check if needed.
14669 When working around R4000 and R4400 errata, we need to make sure that
14670 the division is not immediately followed by a shift[1][2]. We also
14671 need to stop the division from being put into a branch delay slot[3].
14672 The easiest way to avoid both problems is to add a nop after the
14673 division. When a divide-by-zero check is needed, this nop can be
14674 used to fill the branch delay slot.
14676 [1] If a double-word or a variable shift executes immediately
14677 after starting an integer division, the shift may give an
14678 incorrect result. See quotations of errata #16 and #28 from
14679 "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
14680 in mips.md for details.
14682 [2] A similar bug to [1] exists for all revisions of the
14683 R4000 and the R4400 when run in an MC configuration.
14684 From "MIPS R4000MC Errata, Processor Revision 2.2 and 3.0":
14686 "19. In this following sequence:
14688 ddiv (or ddivu or div or divu)
14689 dsll32 (or dsrl32, dsra32)
14691 if an MPT stall occurs, while the divide is slipping the cpu
14692 pipeline, then the following double shift would end up with an
14695 Workaround: The compiler needs to avoid generating any
14696 sequence with divide followed by extended double shift."
14698 This erratum is also present in "MIPS R4400MC Errata, Processor
14699 Revision 1.0" and "MIPS R4400MC Errata, Processor Revision 2.0
14700 & 3.0" as errata #10 and #4, respectively.
14702 [3] From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
14703 (also valid for MIPS R4000MC processors):
14705 "52. R4000SC: This bug does not apply for the R4000PC.
14707 There are two flavors of this bug:
14709 1) If the instruction just after divide takes an RF exception
14710 (tlb-refill, tlb-invalid) and gets an instruction cache
14711 miss (both primary and secondary) and the line which is
14712 currently in secondary cache at this index had the first
14713 data word, where the bits 5..2 are set, then R4000 would
14714 get a wrong result for the div.
14719 ------------------- # end-of page. -tlb-refill
14724 ------------------- # end-of page. -tlb-invalid
14727 2) If the divide is in the taken branch delay slot, where the
14728 target takes RF exception and gets an I-cache miss for the
14729 exception vector or where I-cache miss occurs for the
14730 target address, under the above mentioned scenarios, the
14731 div would get wrong results.
14734 j r2 # to next page mapped or unmapped
14735 div r8,r9 # this bug would be there as long
14736 # as there is an ICache miss and
14737 nop # the "data pattern" is present
14740 beq r0, r0, NextPage # to Next page
14744 This bug is present for div, divu, ddiv, and ddivu
14747 Workaround: For item 1), OS could make sure that the next page
14748 after the divide instruction is also mapped. For item 2), the
14749 compiler could make sure that the divide instruction is not in
14750 the branch delay slot."
14752 These processors have PRId values of 0x00004220 and 0x00004300 for
14753 the R4000 and 0x00004400, 0x00004500 and 0x00004600 for the R4400. */
14756 mips_output_division (const char *division
, rtx
*operands
)
14761 if (TARGET_FIX_R4000
|| TARGET_FIX_R4400
)
14763 output_asm_insn (s
, operands
);
14766 if (TARGET_CHECK_ZERO_DIV
)
14770 output_asm_insn (s
, operands
);
14771 s
= "bnez\t%2,1f\n\tbreak\t7\n1:";
14773 else if (GENERATE_DIVIDE_TRAPS
)
14775 /* Avoid long replay penalty on load miss by putting the trap before
14778 output_asm_insn ("teq\t%2,%.,7", operands
);
14781 output_asm_insn (s
, operands
);
14782 s
= "teq\t%2,%.,7";
14787 if (flag_delayed_branch
)
14789 output_asm_insn ("%(bne\t%2,%.,1f", operands
);
14790 output_asm_insn (s
, operands
);
14791 s
= "break\t7%)\n1:";
14795 output_asm_insn (s
, operands
);
14796 s
= "bne\t%2,%.,1f\n\tnop\n\tbreak\t7\n1:";
14803 /* Return the assembly code for MSA DIV_{S,U}.DF or MOD_{S,U}.DF instructions,
14804 which has the operands given by OPERANDS. Add in a divide-by-zero check
14808 mips_msa_output_division (const char *division
, rtx
*operands
)
14813 if (TARGET_CHECK_ZERO_DIV
)
14815 output_asm_insn ("%(bnz.%v0\t%w2,1f", operands
);
14816 output_asm_insn (s
, operands
);
14817 s
= "break\t7%)\n1:";
14822 /* Return the assembly code for MSA immediate shift instructions,
14823 which has the operands given by OPERANDS. Truncate the shift amount
14824 to make GAS happy. */
14827 mips_msa_output_shift_immediate (const char *shift
, rtx
*operands
)
14829 rtx amount
= operands
[2];
14830 machine_mode mode
= amount
->mode
;
14832 unsigned val
= UINTVAL (CONST_VECTOR_ELT (amount
, 0));
14833 val
&= GET_MODE_UNIT_BITSIZE (mode
) - 1;
14837 rtx c
= gen_int_mode (val
, GET_MODE_INNER (mode
));
14838 operands
[2] = gen_const_vec_duplicate (mode
, c
);
14843 /* Return true if destination of IN_INSN is used as add source in
14844 OUT_INSN. Both IN_INSN and OUT_INSN are of type fmadd. Example:
14845 madd.s dst, x, y, z
14846 madd.s a, dst, b, c */
14849 mips_fmadd_bypass (rtx_insn
*out_insn
, rtx_insn
*in_insn
)
14851 int dst_reg
, src_reg
;
14853 gcc_assert (get_attr_type (in_insn
) == TYPE_FMADD
);
14854 gcc_assert (get_attr_type (out_insn
) == TYPE_FMADD
);
14856 extract_insn (in_insn
);
14857 dst_reg
= REG_P (recog_data
.operand
[0]);
14859 extract_insn (out_insn
);
14860 src_reg
= REG_P (recog_data
.operand
[1]);
14862 if (dst_reg
== src_reg
)
14868 /* Return true if IN_INSN is a multiply-add or multiply-subtract
14869 instruction and if OUT_INSN assigns to the accumulator operand. */
14872 mips_linked_madd_p (rtx_insn
*out_insn
, rtx_insn
*in_insn
)
14874 enum attr_accum_in accum_in
;
14875 int accum_in_opnum
;
14878 if (recog_memoized (in_insn
) < 0)
14881 accum_in
= get_attr_accum_in (in_insn
);
14882 if (accum_in
== ACCUM_IN_NONE
)
14885 accum_in_opnum
= accum_in
- ACCUM_IN_0
;
14887 extract_insn (in_insn
);
14888 gcc_assert (accum_in_opnum
< recog_data
.n_operands
);
14889 accum_in_op
= recog_data
.operand
[accum_in_opnum
];
14891 return reg_set_p (accum_in_op
, out_insn
);
14894 /* True if the dependency between OUT_INSN and IN_INSN is on the store
14895 data rather than the address. We need this because the cprestore
14896 pattern is type "store", but is defined using an UNSPEC_VOLATILE,
14897 which causes the default routine to abort. We just return false
14901 mips_store_data_bypass_p (rtx_insn
*out_insn
, rtx_insn
*in_insn
)
14903 if (GET_CODE (PATTERN (in_insn
)) == UNSPEC_VOLATILE
)
14906 return store_data_bypass_p (out_insn
, in_insn
);
14910 /* Variables and flags used in scheduler hooks when tuning for
14914 /* Variables to support Loongson 2E/2F round-robin [F]ALU1/2 dispatch
14917 /* If true, then next ALU1/2 instruction will go to ALU1. */
14920 /* If true, then next FALU1/2 unstruction will go to FALU1. */
14923 /* Codes to query if [f]alu{1,2}_core units are subscribed or not. */
14924 int alu1_core_unit_code
;
14925 int alu2_core_unit_code
;
14926 int falu1_core_unit_code
;
14927 int falu2_core_unit_code
;
14929 /* True if current cycle has a multi instruction.
14930 This flag is used in mips_ls2_dfa_post_advance_cycle. */
14931 bool cycle_has_multi_p
;
14933 /* Instructions to subscribe ls2_[f]alu{1,2}_turn_enabled units.
14934 These are used in mips_ls2_dfa_post_advance_cycle to initialize
14936 E.g., when alu1_turn_enabled_insn is issued it makes next ALU1/2
14937 instruction to go ALU1. */
14938 rtx_insn
*alu1_turn_enabled_insn
;
14939 rtx_insn
*alu2_turn_enabled_insn
;
14940 rtx_insn
*falu1_turn_enabled_insn
;
14941 rtx_insn
*falu2_turn_enabled_insn
;
14944 /* Implement TARGET_SCHED_ADJUST_COST. We assume that anti and output
14945 dependencies have no cost, except on the 20Kc where output-dependence
14946 is treated like input-dependence. */
14949 mips_adjust_cost (rtx_insn
*, int dep_type
, rtx_insn
*, int cost
, unsigned int)
14951 if (dep_type
!= 0 && (dep_type
!= REG_DEP_OUTPUT
|| !TUNE_20KC
))
14956 /* Return the number of instructions that can be issued per cycle. */
14959 mips_issue_rate (void)
14963 case PROCESSOR_74KC
:
14964 case PROCESSOR_74KF2_1
:
14965 case PROCESSOR_74KF1_1
:
14966 case PROCESSOR_74KF3_2
:
14967 /* The 74k is not strictly quad-issue cpu, but can be seen as one
14968 by the scheduler. It can issue 1 ALU, 1 AGEN and 2 FPU insns,
14969 but in reality only a maximum of 3 insns can be issued as
14970 floating-point loads and stores also require a slot in the
14972 case PROCESSOR_R10000
:
14973 /* All R10K Processors are quad-issue (being the first MIPS
14974 processors to support this feature). */
14977 case PROCESSOR_20KC
:
14978 case PROCESSOR_R4130
:
14979 case PROCESSOR_R5400
:
14980 case PROCESSOR_R5500
:
14981 case PROCESSOR_R5900
:
14982 case PROCESSOR_R7000
:
14983 case PROCESSOR_R9000
:
14984 case PROCESSOR_OCTEON
:
14985 case PROCESSOR_OCTEON2
:
14986 case PROCESSOR_OCTEON3
:
14987 case PROCESSOR_I6400
:
14988 case PROCESSOR_GS264E
:
14991 case PROCESSOR_SB1
:
14992 case PROCESSOR_SB1A
:
14993 /* This is actually 4, but we get better performance if we claim 3.
14994 This is partly because of unwanted speculative code motion with the
14995 larger number, and partly because in most common cases we can't
14996 reach the theoretical max of 4. */
14999 case PROCESSOR_LOONGSON_2E
:
15000 case PROCESSOR_LOONGSON_2F
:
15001 case PROCESSOR_GS464
:
15002 case PROCESSOR_GS464E
:
15003 case PROCESSOR_P5600
:
15004 case PROCESSOR_P6600
:
15007 case PROCESSOR_XLP
:
15008 return (reload_completed
? 4 : 3);
15015 /* Implement TARGET_SCHED_INIT_DFA_POST_CYCLE_INSN hook for Loongson2. */
15018 mips_ls2_init_dfa_post_cycle_insn (void)
15021 emit_insn (gen_ls2_alu1_turn_enabled_insn ());
15022 mips_ls2
.alu1_turn_enabled_insn
= get_insns ();
15026 emit_insn (gen_ls2_alu2_turn_enabled_insn ());
15027 mips_ls2
.alu2_turn_enabled_insn
= get_insns ();
15031 emit_insn (gen_ls2_falu1_turn_enabled_insn ());
15032 mips_ls2
.falu1_turn_enabled_insn
= get_insns ();
15036 emit_insn (gen_ls2_falu2_turn_enabled_insn ());
15037 mips_ls2
.falu2_turn_enabled_insn
= get_insns ();
15040 mips_ls2
.alu1_core_unit_code
= get_cpu_unit_code ("ls2_alu1_core");
15041 mips_ls2
.alu2_core_unit_code
= get_cpu_unit_code ("ls2_alu2_core");
15042 mips_ls2
.falu1_core_unit_code
= get_cpu_unit_code ("ls2_falu1_core");
15043 mips_ls2
.falu2_core_unit_code
= get_cpu_unit_code ("ls2_falu2_core");
15046 /* Implement TARGET_SCHED_INIT_DFA_POST_CYCLE_INSN hook.
15047 Init data used in mips_dfa_post_advance_cycle. */
15050 mips_init_dfa_post_cycle_insn (void)
15052 if (TUNE_LOONGSON_2EF
)
15053 mips_ls2_init_dfa_post_cycle_insn ();
15056 /* Initialize STATE when scheduling for Loongson 2E/2F.
15057 Support round-robin dispatch scheme by enabling only one of
15058 ALU1/ALU2 and one of FALU1/FALU2 units for ALU1/2 and FALU1/2 instructions
15062 mips_ls2_dfa_post_advance_cycle (state_t state
)
15064 if (cpu_unit_reservation_p (state
, mips_ls2
.alu1_core_unit_code
))
15066 /* Though there are no non-pipelined ALU1 insns,
15067 we can get an instruction of type 'multi' before reload. */
15068 gcc_assert (mips_ls2
.cycle_has_multi_p
);
15069 mips_ls2
.alu1_turn_p
= false;
15072 mips_ls2
.cycle_has_multi_p
= false;
15074 if (cpu_unit_reservation_p (state
, mips_ls2
.alu2_core_unit_code
))
15075 /* We have a non-pipelined alu instruction in the core,
15076 adjust round-robin counter. */
15077 mips_ls2
.alu1_turn_p
= true;
15079 if (mips_ls2
.alu1_turn_p
)
15081 if (state_transition (state
, mips_ls2
.alu1_turn_enabled_insn
) >= 0)
15082 gcc_unreachable ();
15086 if (state_transition (state
, mips_ls2
.alu2_turn_enabled_insn
) >= 0)
15087 gcc_unreachable ();
15090 if (cpu_unit_reservation_p (state
, mips_ls2
.falu1_core_unit_code
))
15092 /* There are no non-pipelined FALU1 insns. */
15093 gcc_unreachable ();
15094 mips_ls2
.falu1_turn_p
= false;
15097 if (cpu_unit_reservation_p (state
, mips_ls2
.falu2_core_unit_code
))
15098 /* We have a non-pipelined falu instruction in the core,
15099 adjust round-robin counter. */
15100 mips_ls2
.falu1_turn_p
= true;
15102 if (mips_ls2
.falu1_turn_p
)
15104 if (state_transition (state
, mips_ls2
.falu1_turn_enabled_insn
) >= 0)
15105 gcc_unreachable ();
15109 if (state_transition (state
, mips_ls2
.falu2_turn_enabled_insn
) >= 0)
15110 gcc_unreachable ();
15114 /* Implement TARGET_SCHED_DFA_POST_ADVANCE_CYCLE.
15115 This hook is being called at the start of each cycle. */
15118 mips_dfa_post_advance_cycle (void)
15120 if (TUNE_LOONGSON_2EF
)
15121 mips_ls2_dfa_post_advance_cycle (curr_state
);
15124 /* Implement TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD. This should
15125 be as wide as the scheduling freedom in the DFA. */
15128 mips_multipass_dfa_lookahead (void)
15130 /* Can schedule up to 4 of the 6 function units in any one cycle. */
15134 if (TUNE_LOONGSON_2EF
|| TUNE_GS464
|| TUNE_GS464E
)
15137 if (TUNE_OCTEON
|| TUNE_GS264E
)
15140 if (TUNE_P5600
|| TUNE_P6600
|| TUNE_I6400
)
15146 /* Remove the instruction at index LOWER from ready queue READY and
15147 reinsert it in front of the instruction at index HIGHER. LOWER must
15151 mips_promote_ready (rtx_insn
**ready
, int lower
, int higher
)
15153 rtx_insn
*new_head
;
15156 new_head
= ready
[lower
];
15157 for (i
= lower
; i
< higher
; i
++)
15158 ready
[i
] = ready
[i
+ 1];
15159 ready
[i
] = new_head
;
15162 /* If the priority of the instruction at POS2 in the ready queue READY
15163 is within LIMIT units of that of the instruction at POS1, swap the
15164 instructions if POS2 is not already less than POS1. */
15167 mips_maybe_swap_ready (rtx_insn
**ready
, int pos1
, int pos2
, int limit
)
15170 && INSN_PRIORITY (ready
[pos1
]) + limit
>= INSN_PRIORITY (ready
[pos2
]))
15174 temp
= ready
[pos1
];
15175 ready
[pos1
] = ready
[pos2
];
15176 ready
[pos2
] = temp
;
15180 /* Used by TUNE_MACC_CHAINS to record the last scheduled instruction
15181 that may clobber hi or lo. */
15182 static rtx_insn
*mips_macc_chains_last_hilo
;
15184 /* A TUNE_MACC_CHAINS helper function. Record that instruction INSN has
15185 been scheduled, updating mips_macc_chains_last_hilo appropriately. */
15188 mips_macc_chains_record (rtx_insn
*insn
)
15190 if (get_attr_may_clobber_hilo (insn
))
15191 mips_macc_chains_last_hilo
= insn
;
15194 /* A TUNE_MACC_CHAINS helper function. Search ready queue READY, which
15195 has NREADY elements, looking for a multiply-add or multiply-subtract
15196 instruction that is cumulative with mips_macc_chains_last_hilo.
15197 If there is one, promote it ahead of anything else that might
15198 clobber hi or lo. */
15201 mips_macc_chains_reorder (rtx_insn
**ready
, int nready
)
15205 if (mips_macc_chains_last_hilo
!= 0)
15206 for (i
= nready
- 1; i
>= 0; i
--)
15207 if (mips_linked_madd_p (mips_macc_chains_last_hilo
, ready
[i
]))
15209 for (j
= nready
- 1; j
> i
; j
--)
15210 if (recog_memoized (ready
[j
]) >= 0
15211 && get_attr_may_clobber_hilo (ready
[j
]))
15213 mips_promote_ready (ready
, i
, j
);
15220 /* The last instruction to be scheduled. */
15221 static rtx_insn
*vr4130_last_insn
;
15223 /* A note_stores callback used by vr4130_true_reg_dependence_p. DATA
15224 points to an rtx that is initially an instruction. Nullify the rtx
15225 if the instruction uses the value of register X. */
15228 vr4130_true_reg_dependence_p_1 (rtx x
, const_rtx pat ATTRIBUTE_UNUSED
,
15233 insn_ptr
= (rtx
*) data
;
15236 && reg_referenced_p (x
, PATTERN (*insn_ptr
)))
15240 /* Return true if there is true register dependence between vr4130_last_insn
15244 vr4130_true_reg_dependence_p (rtx insn
)
15246 note_stores (vr4130_last_insn
, vr4130_true_reg_dependence_p_1
, &insn
);
15250 /* A TUNE_MIPS4130 helper function. Given that INSN1 is at the head of
15251 the ready queue and that INSN2 is the instruction after it, return
15252 true if it is worth promoting INSN2 ahead of INSN1. Look for cases
15253 in which INSN1 and INSN2 can probably issue in parallel, but for
15254 which (INSN2, INSN1) should be less sensitive to instruction
15255 alignment than (INSN1, INSN2). See 4130.md for more details. */
15258 vr4130_swap_insns_p (rtx_insn
*insn1
, rtx_insn
*insn2
)
15260 sd_iterator_def sd_it
;
15263 /* Check for the following case:
15265 1) there is some other instruction X with an anti dependence on INSN1;
15266 2) X has a higher priority than INSN2; and
15267 3) X is an arithmetic instruction (and thus has no unit restrictions).
15269 If INSN1 is the last instruction blocking X, it would better to
15270 choose (INSN1, X) over (INSN2, INSN1). */
15271 FOR_EACH_DEP (insn1
, SD_LIST_FORW
, sd_it
, dep
)
15272 if (DEP_TYPE (dep
) == REG_DEP_ANTI
15273 && INSN_PRIORITY (DEP_CON (dep
)) > INSN_PRIORITY (insn2
)
15274 && recog_memoized (DEP_CON (dep
)) >= 0
15275 && get_attr_vr4130_class (DEP_CON (dep
)) == VR4130_CLASS_ALU
)
15278 if (vr4130_last_insn
!= 0
15279 && recog_memoized (insn1
) >= 0
15280 && recog_memoized (insn2
) >= 0)
15282 /* See whether INSN1 and INSN2 use different execution units,
15283 or if they are both ALU-type instructions. If so, they can
15284 probably execute in parallel. */
15285 enum attr_vr4130_class class1
= get_attr_vr4130_class (insn1
);
15286 enum attr_vr4130_class class2
= get_attr_vr4130_class (insn2
);
15287 if (class1
!= class2
|| class1
== VR4130_CLASS_ALU
)
15289 /* If only one of the instructions has a dependence on
15290 vr4130_last_insn, prefer to schedule the other one first. */
15291 bool dep1_p
= vr4130_true_reg_dependence_p (insn1
);
15292 bool dep2_p
= vr4130_true_reg_dependence_p (insn2
);
15293 if (dep1_p
!= dep2_p
)
15296 /* Prefer to schedule INSN2 ahead of INSN1 if vr4130_last_insn
15297 is not an ALU-type instruction and if INSN1 uses the same
15298 execution unit. (Note that if this condition holds, we already
15299 know that INSN2 uses a different execution unit.) */
15300 if (class1
!= VR4130_CLASS_ALU
15301 && recog_memoized (vr4130_last_insn
) >= 0
15302 && class1
== get_attr_vr4130_class (vr4130_last_insn
))
15309 /* A TUNE_MIPS4130 helper function. (READY, NREADY) describes a ready
15310 queue with at least two instructions. Swap the first two if
15311 vr4130_swap_insns_p says that it could be worthwhile. */
15314 vr4130_reorder (rtx_insn
**ready
, int nready
)
15316 if (vr4130_swap_insns_p (ready
[nready
- 1], ready
[nready
- 2]))
15317 mips_promote_ready (ready
, nready
- 2, nready
- 1);
15320 /* Record whether last 74k AGEN instruction was a load or store. */
15321 static enum attr_type mips_last_74k_agen_insn
= TYPE_UNKNOWN
;
15323 /* Initialize mips_last_74k_agen_insn from INSN. A null argument
15324 resets to TYPE_UNKNOWN state. */
15327 mips_74k_agen_init (rtx_insn
*insn
)
15329 if (!insn
|| CALL_P (insn
) || JUMP_P (insn
))
15330 mips_last_74k_agen_insn
= TYPE_UNKNOWN
;
15333 enum attr_type type
= get_attr_type (insn
);
15334 if (type
== TYPE_LOAD
|| type
== TYPE_STORE
)
15335 mips_last_74k_agen_insn
= type
;
15339 /* A TUNE_74K helper function. The 74K AGEN pipeline likes multiple
15340 loads to be grouped together, and multiple stores to be grouped
15341 together. Swap things around in the ready queue to make this happen. */
15344 mips_74k_agen_reorder (rtx_insn
**ready
, int nready
)
15347 int store_pos
, load_pos
;
15352 for (i
= nready
- 1; i
>= 0; i
--)
15354 rtx_insn
*insn
= ready
[i
];
15355 if (USEFUL_INSN_P (insn
))
15356 switch (get_attr_type (insn
))
15359 if (store_pos
== -1)
15364 if (load_pos
== -1)
15373 if (load_pos
== -1 || store_pos
== -1)
15376 switch (mips_last_74k_agen_insn
)
15379 /* Prefer to schedule loads since they have a higher latency. */
15381 /* Swap loads to the front of the queue. */
15382 mips_maybe_swap_ready (ready
, load_pos
, store_pos
, 4);
15385 /* Swap stores to the front of the queue. */
15386 mips_maybe_swap_ready (ready
, store_pos
, load_pos
, 4);
15393 /* Implement TARGET_SCHED_INIT. */
15396 mips_sched_init (FILE *file ATTRIBUTE_UNUSED
, int verbose ATTRIBUTE_UNUSED
,
15397 int max_ready ATTRIBUTE_UNUSED
)
15399 mips_macc_chains_last_hilo
= 0;
15400 vr4130_last_insn
= 0;
15401 mips_74k_agen_init (NULL
);
15403 /* When scheduling for Loongson2, branch instructions go to ALU1,
15404 therefore basic block is most likely to start with round-robin counter
15405 pointed to ALU2. */
15406 mips_ls2
.alu1_turn_p
= false;
15407 mips_ls2
.falu1_turn_p
= true;
15410 /* Subroutine used by TARGET_SCHED_REORDER and TARGET_SCHED_REORDER2. */
15413 mips_sched_reorder_1 (FILE *file ATTRIBUTE_UNUSED
, int verbose ATTRIBUTE_UNUSED
,
15414 rtx_insn
**ready
, int *nreadyp
, int cycle ATTRIBUTE_UNUSED
)
15416 if (!reload_completed
15417 && TUNE_MACC_CHAINS
15419 mips_macc_chains_reorder (ready
, *nreadyp
);
15421 if (reload_completed
15423 && !TARGET_VR4130_ALIGN
15425 vr4130_reorder (ready
, *nreadyp
);
15428 mips_74k_agen_reorder (ready
, *nreadyp
);
15431 /* Implement TARGET_SCHED_REORDER. */
15434 mips_sched_reorder (FILE *file ATTRIBUTE_UNUSED
, int verbose ATTRIBUTE_UNUSED
,
15435 rtx_insn
**ready
, int *nreadyp
, int cycle ATTRIBUTE_UNUSED
)
15437 mips_sched_reorder_1 (file
, verbose
, ready
, nreadyp
, cycle
);
15438 return mips_issue_rate ();
15441 /* Implement TARGET_SCHED_REORDER2. */
15444 mips_sched_reorder2 (FILE *file ATTRIBUTE_UNUSED
, int verbose ATTRIBUTE_UNUSED
,
15445 rtx_insn
**ready
, int *nreadyp
, int cycle ATTRIBUTE_UNUSED
)
15447 mips_sched_reorder_1 (file
, verbose
, ready
, nreadyp
, cycle
);
15448 return cached_can_issue_more
;
15451 /* Update round-robin counters for ALU1/2 and FALU1/2. */
15454 mips_ls2_variable_issue (rtx_insn
*insn
)
15456 if (mips_ls2
.alu1_turn_p
)
15458 if (cpu_unit_reservation_p (curr_state
, mips_ls2
.alu1_core_unit_code
))
15459 mips_ls2
.alu1_turn_p
= false;
15463 if (cpu_unit_reservation_p (curr_state
, mips_ls2
.alu2_core_unit_code
))
15464 mips_ls2
.alu1_turn_p
= true;
15467 if (mips_ls2
.falu1_turn_p
)
15469 if (cpu_unit_reservation_p (curr_state
, mips_ls2
.falu1_core_unit_code
))
15470 mips_ls2
.falu1_turn_p
= false;
15474 if (cpu_unit_reservation_p (curr_state
, mips_ls2
.falu2_core_unit_code
))
15475 mips_ls2
.falu1_turn_p
= true;
15478 if (recog_memoized (insn
) >= 0)
15479 mips_ls2
.cycle_has_multi_p
|= (get_attr_type (insn
) == TYPE_MULTI
);
15482 /* Implement TARGET_SCHED_VARIABLE_ISSUE. */
15485 mips_variable_issue (FILE *file ATTRIBUTE_UNUSED
, int verbose ATTRIBUTE_UNUSED
,
15486 rtx_insn
*insn
, int more
)
15488 /* Ignore USEs and CLOBBERs; don't count them against the issue rate. */
15489 if (USEFUL_INSN_P (insn
))
15491 if (get_attr_type (insn
) != TYPE_GHOST
)
15493 if (!reload_completed
&& TUNE_MACC_CHAINS
)
15494 mips_macc_chains_record (insn
);
15495 vr4130_last_insn
= insn
;
15497 mips_74k_agen_init (insn
);
15498 else if (TUNE_LOONGSON_2EF
)
15499 mips_ls2_variable_issue (insn
);
15502 /* Instructions of type 'multi' should all be split before
15503 the second scheduling pass. */
15504 gcc_assert (!reload_completed
15505 || recog_memoized (insn
) < 0
15506 || get_attr_type (insn
) != TYPE_MULTI
);
15508 cached_can_issue_more
= more
;
15512 /* Given that we have an rtx of the form (prefetch ... WRITE LOCALITY),
15513 return the first operand of the associated PREF or PREFX insn. */
15516 mips_prefetch_cookie (rtx write
, rtx locality
)
15518 /* store_streamed / load_streamed. */
15519 if (INTVAL (locality
) <= 0)
15520 return GEN_INT (INTVAL (write
) + 4);
15522 /* store / load. */
15523 if (INTVAL (locality
) <= 2)
15526 /* store_retained / load_retained. */
15527 return GEN_INT (INTVAL (write
) + 6);
15530 /* Loongson EXT2 only implements pref hint=0 (prefetch for load) and hint=1
15531 (prefetch for store), other hint just scale to hint = 0 and hint = 1. */
15534 mips_loongson_ext2_prefetch_cookie (rtx write
, rtx
)
15537 if (INTVAL (write
) == 1)
15538 return GEN_INT (INTVAL (write
));
15541 if (INTVAL (write
) == 0)
15542 return GEN_INT (INTVAL (write
));
15544 gcc_unreachable ();
15548 /* Flags that indicate when a built-in function is available.
15550 BUILTIN_AVAIL_NON_MIPS16
15551 The function is available on the current target if !TARGET_MIPS16.
15553 BUILTIN_AVAIL_MIPS16
15554 The function is available on the current target if TARGET_MIPS16.
15556 BUILTIN_AVAIL_MIPS16E2
15557 The function is available on the current target if TARGET_MIPS16E2. */
15558 #define BUILTIN_AVAIL_NON_MIPS16 1
15559 #define BUILTIN_AVAIL_MIPS16 2
15560 #define BUILTIN_AVAIL_MIPS16E2 4
15562 /* Declare an availability predicate for built-in functions that
15563 require non-MIPS16 mode and also require COND to be true.
15564 NAME is the main part of the predicate's name. */
15565 #define AVAIL_NON_MIPS16(NAME, COND) \
15566 static unsigned int \
15567 mips_builtin_avail_##NAME (void) \
15569 return (COND) ? BUILTIN_AVAIL_NON_MIPS16 : 0; \
15572 /* Declare an availability predicate for built-in functions that
15573 require non-MIPS16 mode or MIPS16E2 and also require COND to be true.
15574 NAME is the main part of the predicate's name. */
15575 #define AVAIL_MIPS16E2_OR_NON_MIPS16(NAME, COND) \
15576 static unsigned int \
15577 mips_builtin_avail_##NAME (void) \
15579 return ((COND) ? BUILTIN_AVAIL_NON_MIPS16 | BUILTIN_AVAIL_MIPS16E2 \
15583 /* Declare an availability predicate for built-in functions that
15584 support both MIPS16 and non-MIPS16 code and also require COND
15585 to be true. NAME is the main part of the predicate's name. */
15586 #define AVAIL_ALL(NAME, COND) \
15587 static unsigned int \
15588 mips_builtin_avail_##NAME (void) \
15590 return (COND) ? BUILTIN_AVAIL_NON_MIPS16 | BUILTIN_AVAIL_MIPS16 : 0; \
15593 /* This structure describes a single built-in function. */
15594 struct mips_builtin_description
{
15595 /* The code of the main .md file instruction. See mips_builtin_type
15596 for more information. */
15597 enum insn_code icode
;
15599 /* The floating-point comparison code to use with ICODE, if any. */
15600 enum mips_fp_condition cond
;
15602 /* The name of the built-in function. */
15605 /* Specifies how the function should be expanded. */
15606 enum mips_builtin_type builtin_type
;
15608 /* The function's prototype. */
15609 enum mips_function_type function_type
;
15611 /* Whether the function is available. */
15612 unsigned int (*avail
) (void);
15614 /* Whether the function is pure. */
15618 AVAIL_ALL (hard_float
, TARGET_HARD_FLOAT_ABI
)
15619 AVAIL_NON_MIPS16 (paired_single
, TARGET_PAIRED_SINGLE_FLOAT
)
15620 AVAIL_NON_MIPS16 (sb1_paired_single
, TARGET_SB1
&& TARGET_PAIRED_SINGLE_FLOAT
)
15621 AVAIL_NON_MIPS16 (mips3d
, TARGET_MIPS3D
)
15622 AVAIL_NON_MIPS16 (dsp
, TARGET_DSP
)
15623 AVAIL_NON_MIPS16 (dspr2
, TARGET_DSPR2
)
15624 AVAIL_NON_MIPS16 (dsp_32
, !TARGET_64BIT
&& TARGET_DSP
)
15625 AVAIL_NON_MIPS16 (dsp_64
, TARGET_64BIT
&& TARGET_DSP
)
15626 AVAIL_NON_MIPS16 (dspr2_32
, !TARGET_64BIT
&& TARGET_DSPR2
)
15627 AVAIL_NON_MIPS16 (loongson
, TARGET_LOONGSON_MMI
)
15628 AVAIL_MIPS16E2_OR_NON_MIPS16 (cache
, TARGET_CACHE_BUILTIN
)
15629 AVAIL_NON_MIPS16 (msa
, TARGET_MSA
)
15631 /* Construct a mips_builtin_description from the given arguments.
15633 INSN is the name of the associated instruction pattern, without the
15634 leading CODE_FOR_mips_.
15636 CODE is the floating-point condition code associated with the
15637 function. It can be 'f' if the field is not applicable.
15639 NAME is the name of the function itself, without the leading
15642 BUILTIN_TYPE and FUNCTION_TYPE are mips_builtin_description fields.
15644 AVAIL is the name of the availability predicate, without the leading
15645 mips_builtin_avail_. */
15646 #define MIPS_BUILTIN(INSN, COND, NAME, BUILTIN_TYPE, \
15647 FUNCTION_TYPE, AVAIL, PURE) \
15648 { CODE_FOR_mips_ ## INSN, MIPS_FP_COND_ ## COND, \
15649 "__builtin_mips_" NAME, BUILTIN_TYPE, FUNCTION_TYPE, \
15650 mips_builtin_avail_ ## AVAIL, PURE }
15652 /* Define __builtin_mips_<INSN>, which is a MIPS_BUILTIN_DIRECT function
15653 mapped to instruction CODE_FOR_mips_<INSN>, FUNCTION_TYPE and AVAIL
15654 are as for MIPS_BUILTIN. */
15655 #define DIRECT_BUILTIN(INSN, FUNCTION_TYPE, AVAIL) \
15656 MIPS_BUILTIN (INSN, f, #INSN, MIPS_BUILTIN_DIRECT, FUNCTION_TYPE, \
15659 /* Define __builtin_mips_<INSN>, which is a MIPS_BUILTIN_DIRECT pure function
15660 mapped to instruction CODE_FOR_mips_<INSN>, FUNCTION_TYPE and AVAIL
15661 are as for MIPS_BUILTIN. */
15662 #define DIRECT_BUILTIN_PURE(INSN, FUNCTION_TYPE, AVAIL) \
15663 MIPS_BUILTIN (INSN, f, #INSN, MIPS_BUILTIN_DIRECT, FUNCTION_TYPE, \
15666 /* Define __builtin_mips_<INSN>_<COND>_{s,d} functions, both of which
15667 are subject to mips_builtin_avail_<AVAIL>. */
15668 #define CMP_SCALAR_BUILTINS(INSN, COND, AVAIL) \
15669 MIPS_BUILTIN (INSN ## _cond_s, COND, #INSN "_" #COND "_s", \
15670 MIPS_BUILTIN_CMP_SINGLE, MIPS_INT_FTYPE_SF_SF, AVAIL, \
15672 MIPS_BUILTIN (INSN ## _cond_d, COND, #INSN "_" #COND "_d", \
15673 MIPS_BUILTIN_CMP_SINGLE, MIPS_INT_FTYPE_DF_DF, AVAIL, false)
15675 /* Define __builtin_mips_{any,all,upper,lower}_<INSN>_<COND>_ps.
15676 The lower and upper forms are subject to mips_builtin_avail_<AVAIL>
15677 while the any and all forms are subject to mips_builtin_avail_mips3d. */
15678 #define CMP_PS_BUILTINS(INSN, COND, AVAIL) \
15679 MIPS_BUILTIN (INSN ## _cond_ps, COND, "any_" #INSN "_" #COND "_ps", \
15680 MIPS_BUILTIN_CMP_ANY, MIPS_INT_FTYPE_V2SF_V2SF, \
15682 MIPS_BUILTIN (INSN ## _cond_ps, COND, "all_" #INSN "_" #COND "_ps", \
15683 MIPS_BUILTIN_CMP_ALL, MIPS_INT_FTYPE_V2SF_V2SF, \
15685 MIPS_BUILTIN (INSN ## _cond_ps, COND, "lower_" #INSN "_" #COND "_ps", \
15686 MIPS_BUILTIN_CMP_LOWER, MIPS_INT_FTYPE_V2SF_V2SF, \
15688 MIPS_BUILTIN (INSN ## _cond_ps, COND, "upper_" #INSN "_" #COND "_ps", \
15689 MIPS_BUILTIN_CMP_UPPER, MIPS_INT_FTYPE_V2SF_V2SF, \
15692 /* Define __builtin_mips_{any,all}_<INSN>_<COND>_4s. The functions
15693 are subject to mips_builtin_avail_mips3d. */
15694 #define CMP_4S_BUILTINS(INSN, COND) \
15695 MIPS_BUILTIN (INSN ## _cond_4s, COND, "any_" #INSN "_" #COND "_4s", \
15696 MIPS_BUILTIN_CMP_ANY, \
15697 MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF, mips3d, false), \
15698 MIPS_BUILTIN (INSN ## _cond_4s, COND, "all_" #INSN "_" #COND "_4s", \
15699 MIPS_BUILTIN_CMP_ALL, \
15700 MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF, mips3d, false)
15702 /* Define __builtin_mips_mov{t,f}_<INSN>_<COND>_ps. The comparison
15703 instruction requires mips_builtin_avail_<AVAIL>. */
15704 #define MOVTF_BUILTINS(INSN, COND, AVAIL) \
15705 MIPS_BUILTIN (INSN ## _cond_ps, COND, "movt_" #INSN "_" #COND "_ps", \
15706 MIPS_BUILTIN_MOVT, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF, \
15708 MIPS_BUILTIN (INSN ## _cond_ps, COND, "movf_" #INSN "_" #COND "_ps", \
15709 MIPS_BUILTIN_MOVF, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF, \
15712 /* Define all the built-in functions related to C.cond.fmt condition COND. */
15713 #define CMP_BUILTINS(COND) \
15714 MOVTF_BUILTINS (c, COND, paired_single), \
15715 MOVTF_BUILTINS (cabs, COND, mips3d), \
15716 CMP_SCALAR_BUILTINS (cabs, COND, mips3d), \
15717 CMP_PS_BUILTINS (c, COND, paired_single), \
15718 CMP_PS_BUILTINS (cabs, COND, mips3d), \
15719 CMP_4S_BUILTINS (c, COND), \
15720 CMP_4S_BUILTINS (cabs, COND)
15722 /* Define __builtin_mips_<INSN>, which is a MIPS_BUILTIN_DIRECT_NO_TARGET
15723 function mapped to instruction CODE_FOR_mips_<INSN>, FUNCTION_TYPE
15724 and AVAIL are as for MIPS_BUILTIN. */
15725 #define DIRECT_NO_TARGET_BUILTIN(INSN, FUNCTION_TYPE, AVAIL) \
15726 MIPS_BUILTIN (INSN, f, #INSN, MIPS_BUILTIN_DIRECT_NO_TARGET, \
15727 FUNCTION_TYPE, AVAIL, false)
15729 /* Define __builtin_mips_bposge<VALUE>. <VALUE> is 32 for the MIPS32 DSP
15730 branch instruction. AVAIL is as for MIPS_BUILTIN. */
15731 #define BPOSGE_BUILTIN(VALUE, AVAIL) \
15732 MIPS_BUILTIN (bposge, f, "bposge" #VALUE, \
15733 MIPS_BUILTIN_BPOSGE ## VALUE, MIPS_SI_FTYPE_VOID, AVAIL, false)
15735 /* Define a Loongson MIPS_BUILTIN_DIRECT function __builtin_loongson_<FN_NAME>
15736 for instruction CODE_FOR_loongson_<INSN>. FUNCTION_TYPE is a
15737 builtin_description field. */
15738 #define LOONGSON_BUILTIN_ALIAS(INSN, FN_NAME, FUNCTION_TYPE) \
15739 { CODE_FOR_loongson_ ## INSN, MIPS_FP_COND_f, \
15740 "__builtin_loongson_" #FN_NAME, MIPS_BUILTIN_DIRECT, \
15741 FUNCTION_TYPE, mips_builtin_avail_loongson, false }
15743 /* Define a Loongson MIPS_BUILTIN_DIRECT function __builtin_loongson_<INSN>
15744 for instruction CODE_FOR_loongson_<INSN>. FUNCTION_TYPE is a
15745 builtin_description field. */
15746 #define LOONGSON_BUILTIN(INSN, FUNCTION_TYPE) \
15747 LOONGSON_BUILTIN_ALIAS (INSN, INSN, FUNCTION_TYPE)
15749 /* Like LOONGSON_BUILTIN, but add _<SUFFIX> to the end of the function name.
15750 We use functions of this form when the same insn can be usefully applied
15751 to more than one datatype. */
15752 #define LOONGSON_BUILTIN_SUFFIX(INSN, SUFFIX, FUNCTION_TYPE) \
15753 LOONGSON_BUILTIN_ALIAS (INSN, INSN ## _ ## SUFFIX, FUNCTION_TYPE)
15755 /* Define an MSA MIPS_BUILTIN_DIRECT pure function __builtin_msa_<INSN>
15756 for instruction CODE_FOR_msa_<INSN>. FUNCTION_TYPE is a builtin_description
15758 #define MSA_BUILTIN_PURE(INSN, FUNCTION_TYPE) \
15759 { CODE_FOR_msa_ ## INSN, MIPS_FP_COND_f, \
15760 "__builtin_msa_" #INSN, MIPS_BUILTIN_DIRECT, \
15761 FUNCTION_TYPE, mips_builtin_avail_msa, true }
15763 /* Define an MSA MIPS_BUILTIN_DIRECT non-pure function __builtin_msa_<INSN>
15764 for instruction CODE_FOR_msa_<INSN>. FUNCTION_TYPE is a builtin_description
15766 #define MSA_BUILTIN(INSN, FUNCTION_TYPE) \
15767 { CODE_FOR_msa_ ## INSN, MIPS_FP_COND_f, \
15768 "__builtin_msa_" #INSN, MIPS_BUILTIN_DIRECT, \
15769 FUNCTION_TYPE, mips_builtin_avail_msa, false }
15771 /* Define a remapped MSA MIPS_BUILTIN_DIRECT function __builtin_msa_<INSN>
15772 for instruction CODE_FOR_msa_<INSN2>. FUNCTION_TYPE is
15773 a builtin_description field. */
15774 #define MSA_BUILTIN_REMAP(INSN, INSN2, FUNCTION_TYPE) \
15775 { CODE_FOR_msa_ ## INSN2, MIPS_FP_COND_f, \
15776 "__builtin_msa_" #INSN, MIPS_BUILTIN_DIRECT, \
15777 FUNCTION_TYPE, mips_builtin_avail_msa, false }
15779 /* Define an MSA MIPS_BUILTIN_MSA_TEST_BRANCH function __builtin_msa_<INSN>
15780 for instruction CODE_FOR_msa_<INSN>. FUNCTION_TYPE is a builtin_description
15782 #define MSA_BUILTIN_TEST_BRANCH(INSN, FUNCTION_TYPE) \
15783 { CODE_FOR_msa_ ## INSN, MIPS_FP_COND_f, \
15784 "__builtin_msa_" #INSN, MIPS_BUILTIN_MSA_TEST_BRANCH, \
15785 FUNCTION_TYPE, mips_builtin_avail_msa, false }
15787 /* Define an MSA MIPS_BUILTIN_DIRECT_NO_TARGET function __builtin_msa_<INSN>
15788 for instruction CODE_FOR_msa_<INSN>. FUNCTION_TYPE is a builtin_description
15790 #define MSA_NO_TARGET_BUILTIN(INSN, FUNCTION_TYPE) \
15791 { CODE_FOR_msa_ ## INSN, MIPS_FP_COND_f, \
15792 "__builtin_msa_" #INSN, MIPS_BUILTIN_DIRECT_NO_TARGET, \
15793 FUNCTION_TYPE, mips_builtin_avail_msa, false }
15795 #define CODE_FOR_mips_sqrt_ps CODE_FOR_sqrtv2sf2
15796 #define CODE_FOR_mips_addq_ph CODE_FOR_addv2hi3
15797 #define CODE_FOR_mips_addu_qb CODE_FOR_addv4qi3
15798 #define CODE_FOR_mips_subq_ph CODE_FOR_subv2hi3
15799 #define CODE_FOR_mips_subu_qb CODE_FOR_subv4qi3
15800 #define CODE_FOR_mips_mul_ph CODE_FOR_mulv2hi3
15801 #define CODE_FOR_mips_mult CODE_FOR_mulsidi3_32bit
15802 #define CODE_FOR_mips_multu CODE_FOR_umulsidi3_32bit
15804 #define CODE_FOR_loongson_packsswh CODE_FOR_vec_pack_ssat_v2si
15805 #define CODE_FOR_loongson_packsshb CODE_FOR_vec_pack_ssat_v4hi
15806 #define CODE_FOR_loongson_packushb CODE_FOR_vec_pack_usat_v4hi
15807 #define CODE_FOR_loongson_paddw CODE_FOR_addv2si3
15808 #define CODE_FOR_loongson_paddh CODE_FOR_addv4hi3
15809 #define CODE_FOR_loongson_paddb CODE_FOR_addv8qi3
15810 #define CODE_FOR_loongson_paddsh CODE_FOR_ssaddv4hi3
15811 #define CODE_FOR_loongson_paddsb CODE_FOR_ssaddv8qi3
15812 #define CODE_FOR_loongson_paddush CODE_FOR_usaddv4hi3
15813 #define CODE_FOR_loongson_paddusb CODE_FOR_usaddv8qi3
15814 #define CODE_FOR_loongson_pmaxsh CODE_FOR_smaxv4hi3
15815 #define CODE_FOR_loongson_pmaxub CODE_FOR_umaxv8qi3
15816 #define CODE_FOR_loongson_pminsh CODE_FOR_sminv4hi3
15817 #define CODE_FOR_loongson_pminub CODE_FOR_uminv8qi3
15818 #define CODE_FOR_loongson_pmulhuh CODE_FOR_umulv4hi3_highpart
15819 #define CODE_FOR_loongson_pmulhh CODE_FOR_smulv4hi3_highpart
15820 #define CODE_FOR_loongson_pmullh CODE_FOR_mulv4hi3
15821 #define CODE_FOR_loongson_psllh CODE_FOR_ashlv4hi3
15822 #define CODE_FOR_loongson_psllw CODE_FOR_ashlv2si3
15823 #define CODE_FOR_loongson_psrlh CODE_FOR_lshrv4hi3
15824 #define CODE_FOR_loongson_psrlw CODE_FOR_lshrv2si3
15825 #define CODE_FOR_loongson_psrah CODE_FOR_ashrv4hi3
15826 #define CODE_FOR_loongson_psraw CODE_FOR_ashrv2si3
15827 #define CODE_FOR_loongson_psubw CODE_FOR_subv2si3
15828 #define CODE_FOR_loongson_psubh CODE_FOR_subv4hi3
15829 #define CODE_FOR_loongson_psubb CODE_FOR_subv8qi3
15830 #define CODE_FOR_loongson_psubsh CODE_FOR_sssubv4hi3
15831 #define CODE_FOR_loongson_psubsb CODE_FOR_sssubv8qi3
15832 #define CODE_FOR_loongson_psubush CODE_FOR_ussubv4hi3
15833 #define CODE_FOR_loongson_psubusb CODE_FOR_ussubv8qi3
15835 #define CODE_FOR_msa_adds_s_b CODE_FOR_ssaddv16qi3
15836 #define CODE_FOR_msa_adds_s_h CODE_FOR_ssaddv8hi3
15837 #define CODE_FOR_msa_adds_s_w CODE_FOR_ssaddv4si3
15838 #define CODE_FOR_msa_adds_s_d CODE_FOR_ssaddv2di3
15839 #define CODE_FOR_msa_adds_u_b CODE_FOR_usaddv16qi3
15840 #define CODE_FOR_msa_adds_u_h CODE_FOR_usaddv8hi3
15841 #define CODE_FOR_msa_adds_u_w CODE_FOR_usaddv4si3
15842 #define CODE_FOR_msa_adds_u_d CODE_FOR_usaddv2di3
15843 #define CODE_FOR_msa_addv_b CODE_FOR_addv16qi3
15844 #define CODE_FOR_msa_addv_h CODE_FOR_addv8hi3
15845 #define CODE_FOR_msa_addv_w CODE_FOR_addv4si3
15846 #define CODE_FOR_msa_addv_d CODE_FOR_addv2di3
15847 #define CODE_FOR_msa_addvi_b CODE_FOR_addv16qi3
15848 #define CODE_FOR_msa_addvi_h CODE_FOR_addv8hi3
15849 #define CODE_FOR_msa_addvi_w CODE_FOR_addv4si3
15850 #define CODE_FOR_msa_addvi_d CODE_FOR_addv2di3
15851 #define CODE_FOR_msa_and_v CODE_FOR_andv16qi3
15852 #define CODE_FOR_msa_andi_b CODE_FOR_andv16qi3
15853 #define CODE_FOR_msa_bmnz_v CODE_FOR_msa_bmnz_b
15854 #define CODE_FOR_msa_bmnzi_b CODE_FOR_msa_bmnz_b
15855 #define CODE_FOR_msa_bmz_v CODE_FOR_msa_bmz_b
15856 #define CODE_FOR_msa_bmzi_b CODE_FOR_msa_bmz_b
15857 #define CODE_FOR_msa_bnz_v CODE_FOR_msa_bnz_v_b
15858 #define CODE_FOR_msa_bz_v CODE_FOR_msa_bz_v_b
15859 #define CODE_FOR_msa_bsel_v CODE_FOR_msa_bsel_b
15860 #define CODE_FOR_msa_bseli_b CODE_FOR_msa_bsel_b
15861 #define CODE_FOR_msa_ceqi_b CODE_FOR_msa_ceq_b
15862 #define CODE_FOR_msa_ceqi_h CODE_FOR_msa_ceq_h
15863 #define CODE_FOR_msa_ceqi_w CODE_FOR_msa_ceq_w
15864 #define CODE_FOR_msa_ceqi_d CODE_FOR_msa_ceq_d
15865 #define CODE_FOR_msa_clti_s_b CODE_FOR_msa_clt_s_b
15866 #define CODE_FOR_msa_clti_s_h CODE_FOR_msa_clt_s_h
15867 #define CODE_FOR_msa_clti_s_w CODE_FOR_msa_clt_s_w
15868 #define CODE_FOR_msa_clti_s_d CODE_FOR_msa_clt_s_d
15869 #define CODE_FOR_msa_clti_u_b CODE_FOR_msa_clt_u_b
15870 #define CODE_FOR_msa_clti_u_h CODE_FOR_msa_clt_u_h
15871 #define CODE_FOR_msa_clti_u_w CODE_FOR_msa_clt_u_w
15872 #define CODE_FOR_msa_clti_u_d CODE_FOR_msa_clt_u_d
15873 #define CODE_FOR_msa_clei_s_b CODE_FOR_msa_cle_s_b
15874 #define CODE_FOR_msa_clei_s_h CODE_FOR_msa_cle_s_h
15875 #define CODE_FOR_msa_clei_s_w CODE_FOR_msa_cle_s_w
15876 #define CODE_FOR_msa_clei_s_d CODE_FOR_msa_cle_s_d
15877 #define CODE_FOR_msa_clei_u_b CODE_FOR_msa_cle_u_b
15878 #define CODE_FOR_msa_clei_u_h CODE_FOR_msa_cle_u_h
15879 #define CODE_FOR_msa_clei_u_w CODE_FOR_msa_cle_u_w
15880 #define CODE_FOR_msa_clei_u_d CODE_FOR_msa_cle_u_d
15881 #define CODE_FOR_msa_div_s_b CODE_FOR_divv16qi3
15882 #define CODE_FOR_msa_div_s_h CODE_FOR_divv8hi3
15883 #define CODE_FOR_msa_div_s_w CODE_FOR_divv4si3
15884 #define CODE_FOR_msa_div_s_d CODE_FOR_divv2di3
15885 #define CODE_FOR_msa_div_u_b CODE_FOR_udivv16qi3
15886 #define CODE_FOR_msa_div_u_h CODE_FOR_udivv8hi3
15887 #define CODE_FOR_msa_div_u_w CODE_FOR_udivv4si3
15888 #define CODE_FOR_msa_div_u_d CODE_FOR_udivv2di3
15889 #define CODE_FOR_msa_fadd_w CODE_FOR_addv4sf3
15890 #define CODE_FOR_msa_fadd_d CODE_FOR_addv2df3
15891 #define CODE_FOR_msa_fexdo_w CODE_FOR_vec_pack_trunc_v2df
15892 #define CODE_FOR_msa_ftrunc_s_w CODE_FOR_fix_truncv4sfv4si2
15893 #define CODE_FOR_msa_ftrunc_s_d CODE_FOR_fix_truncv2dfv2di2
15894 #define CODE_FOR_msa_ftrunc_u_w CODE_FOR_fixuns_truncv4sfv4si2
15895 #define CODE_FOR_msa_ftrunc_u_d CODE_FOR_fixuns_truncv2dfv2di2
15896 #define CODE_FOR_msa_ffint_s_w CODE_FOR_floatv4siv4sf2
15897 #define CODE_FOR_msa_ffint_s_d CODE_FOR_floatv2div2df2
15898 #define CODE_FOR_msa_ffint_u_w CODE_FOR_floatunsv4siv4sf2
15899 #define CODE_FOR_msa_ffint_u_d CODE_FOR_floatunsv2div2df2
15900 #define CODE_FOR_msa_fsub_w CODE_FOR_subv4sf3
15901 #define CODE_FOR_msa_fsub_d CODE_FOR_subv2df3
15902 #define CODE_FOR_msa_fmadd_w CODE_FOR_fmav4sf4
15903 #define CODE_FOR_msa_fmadd_d CODE_FOR_fmav2df4
15904 #define CODE_FOR_msa_fmsub_w CODE_FOR_fnmav4sf4
15905 #define CODE_FOR_msa_fmsub_d CODE_FOR_fnmav2df4
15906 #define CODE_FOR_msa_fmul_w CODE_FOR_mulv4sf3
15907 #define CODE_FOR_msa_fmul_d CODE_FOR_mulv2df3
15908 #define CODE_FOR_msa_fdiv_w CODE_FOR_divv4sf3
15909 #define CODE_FOR_msa_fdiv_d CODE_FOR_divv2df3
15910 #define CODE_FOR_msa_fmax_w CODE_FOR_smaxv4sf3
15911 #define CODE_FOR_msa_fmax_d CODE_FOR_smaxv2df3
15912 #define CODE_FOR_msa_fmin_w CODE_FOR_sminv4sf3
15913 #define CODE_FOR_msa_fmin_d CODE_FOR_sminv2df3
15914 #define CODE_FOR_msa_fsqrt_w CODE_FOR_sqrtv4sf2
15915 #define CODE_FOR_msa_fsqrt_d CODE_FOR_sqrtv2df2
15916 #define CODE_FOR_msa_max_s_b CODE_FOR_smaxv16qi3
15917 #define CODE_FOR_msa_max_s_h CODE_FOR_smaxv8hi3
15918 #define CODE_FOR_msa_max_s_w CODE_FOR_smaxv4si3
15919 #define CODE_FOR_msa_max_s_d CODE_FOR_smaxv2di3
15920 #define CODE_FOR_msa_maxi_s_b CODE_FOR_smaxv16qi3
15921 #define CODE_FOR_msa_maxi_s_h CODE_FOR_smaxv8hi3
15922 #define CODE_FOR_msa_maxi_s_w CODE_FOR_smaxv4si3
15923 #define CODE_FOR_msa_maxi_s_d CODE_FOR_smaxv2di3
15924 #define CODE_FOR_msa_max_u_b CODE_FOR_umaxv16qi3
15925 #define CODE_FOR_msa_max_u_h CODE_FOR_umaxv8hi3
15926 #define CODE_FOR_msa_max_u_w CODE_FOR_umaxv4si3
15927 #define CODE_FOR_msa_max_u_d CODE_FOR_umaxv2di3
15928 #define CODE_FOR_msa_maxi_u_b CODE_FOR_umaxv16qi3
15929 #define CODE_FOR_msa_maxi_u_h CODE_FOR_umaxv8hi3
15930 #define CODE_FOR_msa_maxi_u_w CODE_FOR_umaxv4si3
15931 #define CODE_FOR_msa_maxi_u_d CODE_FOR_umaxv2di3
15932 #define CODE_FOR_msa_min_s_b CODE_FOR_sminv16qi3
15933 #define CODE_FOR_msa_min_s_h CODE_FOR_sminv8hi3
15934 #define CODE_FOR_msa_min_s_w CODE_FOR_sminv4si3
15935 #define CODE_FOR_msa_min_s_d CODE_FOR_sminv2di3
15936 #define CODE_FOR_msa_mini_s_b CODE_FOR_sminv16qi3
15937 #define CODE_FOR_msa_mini_s_h CODE_FOR_sminv8hi3
15938 #define CODE_FOR_msa_mini_s_w CODE_FOR_sminv4si3
15939 #define CODE_FOR_msa_mini_s_d CODE_FOR_sminv2di3
15940 #define CODE_FOR_msa_min_u_b CODE_FOR_uminv16qi3
15941 #define CODE_FOR_msa_min_u_h CODE_FOR_uminv8hi3
15942 #define CODE_FOR_msa_min_u_w CODE_FOR_uminv4si3
15943 #define CODE_FOR_msa_min_u_d CODE_FOR_uminv2di3
15944 #define CODE_FOR_msa_mini_u_b CODE_FOR_uminv16qi3
15945 #define CODE_FOR_msa_mini_u_h CODE_FOR_uminv8hi3
15946 #define CODE_FOR_msa_mini_u_w CODE_FOR_uminv4si3
15947 #define CODE_FOR_msa_mini_u_d CODE_FOR_uminv2di3
15948 #define CODE_FOR_msa_mod_s_b CODE_FOR_modv16qi3
15949 #define CODE_FOR_msa_mod_s_h CODE_FOR_modv8hi3
15950 #define CODE_FOR_msa_mod_s_w CODE_FOR_modv4si3
15951 #define CODE_FOR_msa_mod_s_d CODE_FOR_modv2di3
15952 #define CODE_FOR_msa_mod_u_b CODE_FOR_umodv16qi3
15953 #define CODE_FOR_msa_mod_u_h CODE_FOR_umodv8hi3
15954 #define CODE_FOR_msa_mod_u_w CODE_FOR_umodv4si3
15955 #define CODE_FOR_msa_mod_u_d CODE_FOR_umodv2di3
15956 #define CODE_FOR_msa_mod_s_b CODE_FOR_modv16qi3
15957 #define CODE_FOR_msa_mod_s_h CODE_FOR_modv8hi3
15958 #define CODE_FOR_msa_mod_s_w CODE_FOR_modv4si3
15959 #define CODE_FOR_msa_mod_s_d CODE_FOR_modv2di3
15960 #define CODE_FOR_msa_mod_u_b CODE_FOR_umodv16qi3
15961 #define CODE_FOR_msa_mod_u_h CODE_FOR_umodv8hi3
15962 #define CODE_FOR_msa_mod_u_w CODE_FOR_umodv4si3
15963 #define CODE_FOR_msa_mod_u_d CODE_FOR_umodv2di3
15964 #define CODE_FOR_msa_mulv_b CODE_FOR_mulv16qi3
15965 #define CODE_FOR_msa_mulv_h CODE_FOR_mulv8hi3
15966 #define CODE_FOR_msa_mulv_w CODE_FOR_mulv4si3
15967 #define CODE_FOR_msa_mulv_d CODE_FOR_mulv2di3
15968 #define CODE_FOR_msa_nlzc_b CODE_FOR_clzv16qi2
15969 #define CODE_FOR_msa_nlzc_h CODE_FOR_clzv8hi2
15970 #define CODE_FOR_msa_nlzc_w CODE_FOR_clzv4si2
15971 #define CODE_FOR_msa_nlzc_d CODE_FOR_clzv2di2
15972 #define CODE_FOR_msa_nor_v CODE_FOR_msa_nor_b
15973 #define CODE_FOR_msa_or_v CODE_FOR_iorv16qi3
15974 #define CODE_FOR_msa_ori_b CODE_FOR_iorv16qi3
15975 #define CODE_FOR_msa_nori_b CODE_FOR_msa_nor_b
15976 #define CODE_FOR_msa_pcnt_b CODE_FOR_popcountv16qi2
15977 #define CODE_FOR_msa_pcnt_h CODE_FOR_popcountv8hi2
15978 #define CODE_FOR_msa_pcnt_w CODE_FOR_popcountv4si2
15979 #define CODE_FOR_msa_pcnt_d CODE_FOR_popcountv2di2
15980 #define CODE_FOR_msa_xor_v CODE_FOR_xorv16qi3
15981 #define CODE_FOR_msa_xori_b CODE_FOR_xorv16qi3
15982 #define CODE_FOR_msa_sll_b CODE_FOR_vashlv16qi3
15983 #define CODE_FOR_msa_sll_h CODE_FOR_vashlv8hi3
15984 #define CODE_FOR_msa_sll_w CODE_FOR_vashlv4si3
15985 #define CODE_FOR_msa_sll_d CODE_FOR_vashlv2di3
15986 #define CODE_FOR_msa_slli_b CODE_FOR_vashlv16qi3
15987 #define CODE_FOR_msa_slli_h CODE_FOR_vashlv8hi3
15988 #define CODE_FOR_msa_slli_w CODE_FOR_vashlv4si3
15989 #define CODE_FOR_msa_slli_d CODE_FOR_vashlv2di3
15990 #define CODE_FOR_msa_sra_b CODE_FOR_vashrv16qi3
15991 #define CODE_FOR_msa_sra_h CODE_FOR_vashrv8hi3
15992 #define CODE_FOR_msa_sra_w CODE_FOR_vashrv4si3
15993 #define CODE_FOR_msa_sra_d CODE_FOR_vashrv2di3
15994 #define CODE_FOR_msa_srai_b CODE_FOR_vashrv16qi3
15995 #define CODE_FOR_msa_srai_h CODE_FOR_vashrv8hi3
15996 #define CODE_FOR_msa_srai_w CODE_FOR_vashrv4si3
15997 #define CODE_FOR_msa_srai_d CODE_FOR_vashrv2di3
15998 #define CODE_FOR_msa_srl_b CODE_FOR_vlshrv16qi3
15999 #define CODE_FOR_msa_srl_h CODE_FOR_vlshrv8hi3
16000 #define CODE_FOR_msa_srl_w CODE_FOR_vlshrv4si3
16001 #define CODE_FOR_msa_srl_d CODE_FOR_vlshrv2di3
16002 #define CODE_FOR_msa_srli_b CODE_FOR_vlshrv16qi3
16003 #define CODE_FOR_msa_srli_h CODE_FOR_vlshrv8hi3
16004 #define CODE_FOR_msa_srli_w CODE_FOR_vlshrv4si3
16005 #define CODE_FOR_msa_srli_d CODE_FOR_vlshrv2di3
16006 #define CODE_FOR_msa_subv_b CODE_FOR_subv16qi3
16007 #define CODE_FOR_msa_subv_h CODE_FOR_subv8hi3
16008 #define CODE_FOR_msa_subv_w CODE_FOR_subv4si3
16009 #define CODE_FOR_msa_subv_d CODE_FOR_subv2di3
16010 #define CODE_FOR_msa_subvi_b CODE_FOR_subv16qi3
16011 #define CODE_FOR_msa_subvi_h CODE_FOR_subv8hi3
16012 #define CODE_FOR_msa_subvi_w CODE_FOR_subv4si3
16013 #define CODE_FOR_msa_subvi_d CODE_FOR_subv2di3
16015 #define CODE_FOR_msa_move_v CODE_FOR_movv16qi
16017 #define CODE_FOR_msa_vshf_b CODE_FOR_vec_permv16qi
16018 #define CODE_FOR_msa_vshf_h CODE_FOR_vec_permv8hi
16019 #define CODE_FOR_msa_vshf_w CODE_FOR_vec_permv4si
16020 #define CODE_FOR_msa_vshf_d CODE_FOR_vec_permv2di
16022 #define CODE_FOR_msa_ilvod_d CODE_FOR_msa_ilvl_d
16023 #define CODE_FOR_msa_ilvev_d CODE_FOR_msa_ilvr_d
16024 #define CODE_FOR_msa_pckod_d CODE_FOR_msa_ilvl_d
16025 #define CODE_FOR_msa_pckev_d CODE_FOR_msa_ilvr_d
16027 #define CODE_FOR_msa_ldi_b CODE_FOR_msa_ldiv16qi
16028 #define CODE_FOR_msa_ldi_h CODE_FOR_msa_ldiv8hi
16029 #define CODE_FOR_msa_ldi_w CODE_FOR_msa_ldiv4si
16030 #define CODE_FOR_msa_ldi_d CODE_FOR_msa_ldiv2di
16032 static const struct mips_builtin_description mips_builtins
[] = {
16033 #define MIPS_GET_FCSR 0
16034 DIRECT_BUILTIN (get_fcsr
, MIPS_USI_FTYPE_VOID
, hard_float
),
16035 #define MIPS_SET_FCSR 1
16036 DIRECT_NO_TARGET_BUILTIN (set_fcsr
, MIPS_VOID_FTYPE_USI
, hard_float
),
16038 DIRECT_BUILTIN_PURE (pll_ps
, MIPS_V2SF_FTYPE_V2SF_V2SF
, paired_single
),
16039 DIRECT_BUILTIN_PURE (pul_ps
, MIPS_V2SF_FTYPE_V2SF_V2SF
, paired_single
),
16040 DIRECT_BUILTIN_PURE (plu_ps
, MIPS_V2SF_FTYPE_V2SF_V2SF
, paired_single
),
16041 DIRECT_BUILTIN_PURE (puu_ps
, MIPS_V2SF_FTYPE_V2SF_V2SF
, paired_single
),
16042 DIRECT_BUILTIN_PURE (cvt_ps_s
, MIPS_V2SF_FTYPE_SF_SF
, paired_single
),
16043 DIRECT_BUILTIN_PURE (cvt_s_pl
, MIPS_SF_FTYPE_V2SF
, paired_single
),
16044 DIRECT_BUILTIN_PURE (cvt_s_pu
, MIPS_SF_FTYPE_V2SF
, paired_single
),
16045 DIRECT_BUILTIN_PURE (abs_ps
, MIPS_V2SF_FTYPE_V2SF
, paired_single
),
16047 DIRECT_BUILTIN_PURE (alnv_ps
, MIPS_V2SF_FTYPE_V2SF_V2SF_INT
, paired_single
),
16048 DIRECT_BUILTIN_PURE (addr_ps
, MIPS_V2SF_FTYPE_V2SF_V2SF
, mips3d
),
16049 DIRECT_BUILTIN_PURE (mulr_ps
, MIPS_V2SF_FTYPE_V2SF_V2SF
, mips3d
),
16050 DIRECT_BUILTIN_PURE (cvt_pw_ps
, MIPS_V2SF_FTYPE_V2SF
, mips3d
),
16051 DIRECT_BUILTIN_PURE (cvt_ps_pw
, MIPS_V2SF_FTYPE_V2SF
, mips3d
),
16053 DIRECT_BUILTIN_PURE (recip1_s
, MIPS_SF_FTYPE_SF
, mips3d
),
16054 DIRECT_BUILTIN_PURE (recip1_d
, MIPS_DF_FTYPE_DF
, mips3d
),
16055 DIRECT_BUILTIN_PURE (recip1_ps
, MIPS_V2SF_FTYPE_V2SF
, mips3d
),
16056 DIRECT_BUILTIN_PURE (recip2_s
, MIPS_SF_FTYPE_SF_SF
, mips3d
),
16057 DIRECT_BUILTIN_PURE (recip2_d
, MIPS_DF_FTYPE_DF_DF
, mips3d
),
16058 DIRECT_BUILTIN_PURE (recip2_ps
, MIPS_V2SF_FTYPE_V2SF_V2SF
, mips3d
),
16060 DIRECT_BUILTIN_PURE (rsqrt1_s
, MIPS_SF_FTYPE_SF
, mips3d
),
16061 DIRECT_BUILTIN_PURE (rsqrt1_d
, MIPS_DF_FTYPE_DF
, mips3d
),
16062 DIRECT_BUILTIN_PURE (rsqrt1_ps
, MIPS_V2SF_FTYPE_V2SF
, mips3d
),
16063 DIRECT_BUILTIN_PURE (rsqrt2_s
, MIPS_SF_FTYPE_SF_SF
, mips3d
),
16064 DIRECT_BUILTIN_PURE (rsqrt2_d
, MIPS_DF_FTYPE_DF_DF
, mips3d
),
16065 DIRECT_BUILTIN_PURE (rsqrt2_ps
, MIPS_V2SF_FTYPE_V2SF_V2SF
, mips3d
),
16067 MIPS_FP_CONDITIONS (CMP_BUILTINS
),
16069 /* Built-in functions for the SB-1 processor. */
16070 DIRECT_BUILTIN (sqrt_ps
, MIPS_V2SF_FTYPE_V2SF
, sb1_paired_single
),
16072 /* Built-in functions for the DSP ASE (32-bit and 64-bit). */
16073 DIRECT_BUILTIN_PURE (addq_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dsp
),
16074 DIRECT_BUILTIN_PURE (addq_s_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dsp
),
16075 DIRECT_BUILTIN_PURE (addq_s_w
, MIPS_SI_FTYPE_SI_SI
, dsp
),
16076 DIRECT_BUILTIN_PURE (addu_qb
, MIPS_V4QI_FTYPE_V4QI_V4QI
, dsp
),
16077 DIRECT_BUILTIN_PURE (addu_s_qb
, MIPS_V4QI_FTYPE_V4QI_V4QI
, dsp
),
16078 DIRECT_BUILTIN_PURE (subq_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dsp
),
16079 DIRECT_BUILTIN_PURE (subq_s_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dsp
),
16080 DIRECT_BUILTIN_PURE (subq_s_w
, MIPS_SI_FTYPE_SI_SI
, dsp
),
16081 DIRECT_BUILTIN_PURE (subu_qb
, MIPS_V4QI_FTYPE_V4QI_V4QI
, dsp
),
16082 DIRECT_BUILTIN_PURE (subu_s_qb
, MIPS_V4QI_FTYPE_V4QI_V4QI
, dsp
),
16083 DIRECT_BUILTIN_PURE (addsc
, MIPS_SI_FTYPE_SI_SI
, dsp
),
16084 DIRECT_BUILTIN_PURE (addwc
, MIPS_SI_FTYPE_SI_SI
, dsp
),
16085 DIRECT_BUILTIN_PURE (modsub
, MIPS_SI_FTYPE_SI_SI
, dsp
),
16086 DIRECT_BUILTIN_PURE (raddu_w_qb
, MIPS_SI_FTYPE_V4QI
, dsp
),
16087 DIRECT_BUILTIN_PURE (absq_s_ph
, MIPS_V2HI_FTYPE_V2HI
, dsp
),
16088 DIRECT_BUILTIN_PURE (absq_s_w
, MIPS_SI_FTYPE_SI
, dsp
),
16089 DIRECT_BUILTIN_PURE (precrq_qb_ph
, MIPS_V4QI_FTYPE_V2HI_V2HI
, dsp
),
16090 DIRECT_BUILTIN_PURE (precrq_ph_w
, MIPS_V2HI_FTYPE_SI_SI
, dsp
),
16091 DIRECT_BUILTIN_PURE (precrq_rs_ph_w
, MIPS_V2HI_FTYPE_SI_SI
, dsp
),
16092 DIRECT_BUILTIN_PURE (precrqu_s_qb_ph
, MIPS_V4QI_FTYPE_V2HI_V2HI
, dsp
),
16093 DIRECT_BUILTIN_PURE (preceq_w_phl
, MIPS_SI_FTYPE_V2HI
, dsp
),
16094 DIRECT_BUILTIN_PURE (preceq_w_phr
, MIPS_SI_FTYPE_V2HI
, dsp
),
16095 DIRECT_BUILTIN_PURE (precequ_ph_qbl
, MIPS_V2HI_FTYPE_V4QI
, dsp
),
16096 DIRECT_BUILTIN_PURE (precequ_ph_qbr
, MIPS_V2HI_FTYPE_V4QI
, dsp
),
16097 DIRECT_BUILTIN_PURE (precequ_ph_qbla
, MIPS_V2HI_FTYPE_V4QI
, dsp
),
16098 DIRECT_BUILTIN_PURE (precequ_ph_qbra
, MIPS_V2HI_FTYPE_V4QI
, dsp
),
16099 DIRECT_BUILTIN_PURE (preceu_ph_qbl
, MIPS_V2HI_FTYPE_V4QI
, dsp
),
16100 DIRECT_BUILTIN_PURE (preceu_ph_qbr
, MIPS_V2HI_FTYPE_V4QI
, dsp
),
16101 DIRECT_BUILTIN_PURE (preceu_ph_qbla
, MIPS_V2HI_FTYPE_V4QI
, dsp
),
16102 DIRECT_BUILTIN_PURE (preceu_ph_qbra
, MIPS_V2HI_FTYPE_V4QI
, dsp
),
16103 DIRECT_BUILTIN_PURE (shll_qb
, MIPS_V4QI_FTYPE_V4QI_SI
, dsp
),
16104 DIRECT_BUILTIN_PURE (shll_ph
, MIPS_V2HI_FTYPE_V2HI_SI
, dsp
),
16105 DIRECT_BUILTIN_PURE (shll_s_ph
, MIPS_V2HI_FTYPE_V2HI_SI
, dsp
),
16106 DIRECT_BUILTIN_PURE (shll_s_w
, MIPS_SI_FTYPE_SI_SI
, dsp
),
16107 DIRECT_BUILTIN_PURE (shrl_qb
, MIPS_V4QI_FTYPE_V4QI_SI
, dsp
),
16108 DIRECT_BUILTIN_PURE (shra_ph
, MIPS_V2HI_FTYPE_V2HI_SI
, dsp
),
16109 DIRECT_BUILTIN_PURE (shra_r_ph
, MIPS_V2HI_FTYPE_V2HI_SI
, dsp
),
16110 DIRECT_BUILTIN_PURE (shra_r_w
, MIPS_SI_FTYPE_SI_SI
, dsp
),
16111 DIRECT_BUILTIN_PURE (muleu_s_ph_qbl
, MIPS_V2HI_FTYPE_V4QI_V2HI
, dsp
),
16112 DIRECT_BUILTIN_PURE (muleu_s_ph_qbr
, MIPS_V2HI_FTYPE_V4QI_V2HI
, dsp
),
16113 DIRECT_BUILTIN_PURE (mulq_rs_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dsp
),
16114 DIRECT_BUILTIN_PURE (muleq_s_w_phl
, MIPS_SI_FTYPE_V2HI_V2HI
, dsp
),
16115 DIRECT_BUILTIN_PURE (muleq_s_w_phr
, MIPS_SI_FTYPE_V2HI_V2HI
, dsp
),
16116 DIRECT_BUILTIN_PURE (bitrev
, MIPS_SI_FTYPE_SI
, dsp
),
16117 DIRECT_BUILTIN_PURE (insv
, MIPS_SI_FTYPE_SI_SI
, dsp
),
16118 DIRECT_BUILTIN_PURE (repl_qb
, MIPS_V4QI_FTYPE_SI
, dsp
),
16119 DIRECT_BUILTIN_PURE (repl_ph
, MIPS_V2HI_FTYPE_SI
, dsp
),
16120 DIRECT_NO_TARGET_BUILTIN (cmpu_eq_qb
, MIPS_VOID_FTYPE_V4QI_V4QI
, dsp
),
16121 DIRECT_NO_TARGET_BUILTIN (cmpu_lt_qb
, MIPS_VOID_FTYPE_V4QI_V4QI
, dsp
),
16122 DIRECT_NO_TARGET_BUILTIN (cmpu_le_qb
, MIPS_VOID_FTYPE_V4QI_V4QI
, dsp
),
16123 DIRECT_BUILTIN_PURE (cmpgu_eq_qb
, MIPS_SI_FTYPE_V4QI_V4QI
, dsp
),
16124 DIRECT_BUILTIN_PURE (cmpgu_lt_qb
, MIPS_SI_FTYPE_V4QI_V4QI
, dsp
),
16125 DIRECT_BUILTIN_PURE (cmpgu_le_qb
, MIPS_SI_FTYPE_V4QI_V4QI
, dsp
),
16126 DIRECT_NO_TARGET_BUILTIN (cmp_eq_ph
, MIPS_VOID_FTYPE_V2HI_V2HI
, dsp
),
16127 DIRECT_NO_TARGET_BUILTIN (cmp_lt_ph
, MIPS_VOID_FTYPE_V2HI_V2HI
, dsp
),
16128 DIRECT_NO_TARGET_BUILTIN (cmp_le_ph
, MIPS_VOID_FTYPE_V2HI_V2HI
, dsp
),
16129 DIRECT_BUILTIN_PURE (pick_qb
, MIPS_V4QI_FTYPE_V4QI_V4QI
, dsp
),
16130 DIRECT_BUILTIN_PURE (pick_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dsp
),
16131 DIRECT_BUILTIN_PURE (packrl_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dsp
),
16132 DIRECT_NO_TARGET_BUILTIN (wrdsp
, MIPS_VOID_FTYPE_SI_SI
, dsp
),
16133 DIRECT_BUILTIN_PURE (rddsp
, MIPS_SI_FTYPE_SI
, dsp
),
16134 DIRECT_BUILTIN (lbux
, MIPS_SI_FTYPE_POINTER_SI
, dsp
),
16135 DIRECT_BUILTIN (lhx
, MIPS_SI_FTYPE_POINTER_SI
, dsp
),
16136 DIRECT_BUILTIN (lwx
, MIPS_SI_FTYPE_POINTER_SI
, dsp
),
16137 BPOSGE_BUILTIN (32, dsp
),
16139 /* The following are for the MIPS DSP ASE REV 2 (32-bit and 64-bit). */
16140 DIRECT_BUILTIN_PURE (absq_s_qb
, MIPS_V4QI_FTYPE_V4QI
, dspr2
),
16141 DIRECT_BUILTIN_PURE (addu_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dspr2
),
16142 DIRECT_BUILTIN_PURE (addu_s_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dspr2
),
16143 DIRECT_BUILTIN_PURE (adduh_qb
, MIPS_V4QI_FTYPE_V4QI_V4QI
, dspr2
),
16144 DIRECT_BUILTIN_PURE (adduh_r_qb
, MIPS_V4QI_FTYPE_V4QI_V4QI
, dspr2
),
16145 DIRECT_BUILTIN_PURE (append
, MIPS_SI_FTYPE_SI_SI_SI
, dspr2
),
16146 DIRECT_BUILTIN_PURE (balign
, MIPS_SI_FTYPE_SI_SI_SI
, dspr2
),
16147 DIRECT_BUILTIN_PURE (cmpgdu_eq_qb
, MIPS_SI_FTYPE_V4QI_V4QI
, dspr2
),
16148 DIRECT_BUILTIN_PURE (cmpgdu_lt_qb
, MIPS_SI_FTYPE_V4QI_V4QI
, dspr2
),
16149 DIRECT_BUILTIN_PURE (cmpgdu_le_qb
, MIPS_SI_FTYPE_V4QI_V4QI
, dspr2
),
16150 DIRECT_BUILTIN_PURE (mul_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dspr2
),
16151 DIRECT_BUILTIN_PURE (mul_s_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dspr2
),
16152 DIRECT_BUILTIN_PURE (mulq_rs_w
, MIPS_SI_FTYPE_SI_SI
, dspr2
),
16153 DIRECT_BUILTIN_PURE (mulq_s_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dspr2
),
16154 DIRECT_BUILTIN_PURE (mulq_s_w
, MIPS_SI_FTYPE_SI_SI
, dspr2
),
16155 DIRECT_BUILTIN_PURE (precr_qb_ph
, MIPS_V4QI_FTYPE_V2HI_V2HI
, dspr2
),
16156 DIRECT_BUILTIN_PURE (precr_sra_ph_w
, MIPS_V2HI_FTYPE_SI_SI_SI
, dspr2
),
16157 DIRECT_BUILTIN_PURE (precr_sra_r_ph_w
, MIPS_V2HI_FTYPE_SI_SI_SI
, dspr2
),
16158 DIRECT_BUILTIN_PURE (prepend
, MIPS_SI_FTYPE_SI_SI_SI
, dspr2
),
16159 DIRECT_BUILTIN_PURE (shra_qb
, MIPS_V4QI_FTYPE_V4QI_SI
, dspr2
),
16160 DIRECT_BUILTIN_PURE (shra_r_qb
, MIPS_V4QI_FTYPE_V4QI_SI
, dspr2
),
16161 DIRECT_BUILTIN_PURE (shrl_ph
, MIPS_V2HI_FTYPE_V2HI_SI
, dspr2
),
16162 DIRECT_BUILTIN_PURE (subu_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dspr2
),
16163 DIRECT_BUILTIN_PURE (subu_s_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dspr2
),
16164 DIRECT_BUILTIN_PURE (subuh_qb
, MIPS_V4QI_FTYPE_V4QI_V4QI
, dspr2
),
16165 DIRECT_BUILTIN_PURE (subuh_r_qb
, MIPS_V4QI_FTYPE_V4QI_V4QI
, dspr2
),
16166 DIRECT_BUILTIN_PURE (addqh_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dspr2
),
16167 DIRECT_BUILTIN_PURE (addqh_r_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dspr2
),
16168 DIRECT_BUILTIN_PURE (addqh_w
, MIPS_SI_FTYPE_SI_SI
, dspr2
),
16169 DIRECT_BUILTIN_PURE (addqh_r_w
, MIPS_SI_FTYPE_SI_SI
, dspr2
),
16170 DIRECT_BUILTIN_PURE (subqh_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dspr2
),
16171 DIRECT_BUILTIN_PURE (subqh_r_ph
, MIPS_V2HI_FTYPE_V2HI_V2HI
, dspr2
),
16172 DIRECT_BUILTIN_PURE (subqh_w
, MIPS_SI_FTYPE_SI_SI
, dspr2
),
16173 DIRECT_BUILTIN_PURE (subqh_r_w
, MIPS_SI_FTYPE_SI_SI
, dspr2
),
16175 /* Built-in functions for the DSP ASE (32-bit only). */
16176 DIRECT_BUILTIN_PURE (dpau_h_qbl
, MIPS_DI_FTYPE_DI_V4QI_V4QI
, dsp_32
),
16177 DIRECT_BUILTIN_PURE (dpau_h_qbr
, MIPS_DI_FTYPE_DI_V4QI_V4QI
, dsp_32
),
16178 DIRECT_BUILTIN_PURE (dpsu_h_qbl
, MIPS_DI_FTYPE_DI_V4QI_V4QI
, dsp_32
),
16179 DIRECT_BUILTIN_PURE (dpsu_h_qbr
, MIPS_DI_FTYPE_DI_V4QI_V4QI
, dsp_32
),
16180 DIRECT_BUILTIN_PURE (dpaq_s_w_ph
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dsp_32
),
16181 DIRECT_BUILTIN_PURE (dpsq_s_w_ph
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dsp_32
),
16182 DIRECT_BUILTIN_PURE (mulsaq_s_w_ph
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dsp_32
),
16183 DIRECT_BUILTIN_PURE (dpaq_sa_l_w
, MIPS_DI_FTYPE_DI_SI_SI
, dsp_32
),
16184 DIRECT_BUILTIN_PURE (dpsq_sa_l_w
, MIPS_DI_FTYPE_DI_SI_SI
, dsp_32
),
16185 DIRECT_BUILTIN_PURE (maq_s_w_phl
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dsp_32
),
16186 DIRECT_BUILTIN_PURE (maq_s_w_phr
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dsp_32
),
16187 DIRECT_BUILTIN_PURE (maq_sa_w_phl
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dsp_32
),
16188 DIRECT_BUILTIN_PURE (maq_sa_w_phr
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dsp_32
),
16189 DIRECT_BUILTIN_PURE (extr_w
, MIPS_SI_FTYPE_DI_SI
, dsp_32
),
16190 DIRECT_BUILTIN_PURE (extr_r_w
, MIPS_SI_FTYPE_DI_SI
, dsp_32
),
16191 DIRECT_BUILTIN_PURE (extr_rs_w
, MIPS_SI_FTYPE_DI_SI
, dsp_32
),
16192 DIRECT_BUILTIN_PURE (extr_s_h
, MIPS_SI_FTYPE_DI_SI
, dsp_32
),
16193 DIRECT_BUILTIN_PURE (extp
, MIPS_SI_FTYPE_DI_SI
, dsp_32
),
16194 DIRECT_BUILTIN_PURE (extpdp
, MIPS_SI_FTYPE_DI_SI
, dsp_32
),
16195 DIRECT_BUILTIN_PURE (shilo
, MIPS_DI_FTYPE_DI_SI
, dsp_32
),
16196 DIRECT_BUILTIN_PURE (mthlip
, MIPS_DI_FTYPE_DI_SI
, dsp_32
),
16197 DIRECT_BUILTIN_PURE (madd
, MIPS_DI_FTYPE_DI_SI_SI
, dsp_32
),
16198 DIRECT_BUILTIN_PURE (maddu
, MIPS_DI_FTYPE_DI_USI_USI
, dsp_32
),
16199 DIRECT_BUILTIN_PURE (msub
, MIPS_DI_FTYPE_DI_SI_SI
, dsp_32
),
16200 DIRECT_BUILTIN_PURE (msubu
, MIPS_DI_FTYPE_DI_USI_USI
, dsp_32
),
16201 DIRECT_BUILTIN_PURE (mult
, MIPS_DI_FTYPE_SI_SI
, dsp_32
),
16202 DIRECT_BUILTIN_PURE (multu
, MIPS_DI_FTYPE_USI_USI
, dsp_32
),
16204 /* Built-in functions for the DSP ASE (64-bit only). */
16205 DIRECT_BUILTIN (ldx
, MIPS_DI_FTYPE_POINTER_SI
, dsp_64
),
16207 /* The following are for the MIPS DSP ASE REV 2 (32-bit only). */
16208 DIRECT_BUILTIN_PURE (dpa_w_ph
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dspr2_32
),
16209 DIRECT_BUILTIN_PURE (dps_w_ph
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dspr2_32
),
16210 DIRECT_BUILTIN_PURE (mulsa_w_ph
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dspr2_32
),
16211 DIRECT_BUILTIN_PURE (dpax_w_ph
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dspr2_32
),
16212 DIRECT_BUILTIN_PURE (dpsx_w_ph
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dspr2_32
),
16213 DIRECT_BUILTIN_PURE (dpaqx_s_w_ph
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dspr2_32
),
16214 DIRECT_BUILTIN_PURE (dpaqx_sa_w_ph
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dspr2_32
),
16215 DIRECT_BUILTIN_PURE (dpsqx_s_w_ph
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dspr2_32
),
16216 DIRECT_BUILTIN_PURE (dpsqx_sa_w_ph
, MIPS_DI_FTYPE_DI_V2HI_V2HI
, dspr2_32
),
16218 /* Builtin functions for ST Microelectronics Loongson-2E/2F cores. */
16219 LOONGSON_BUILTIN (packsswh
, MIPS_V4HI_FTYPE_V2SI_V2SI
),
16220 LOONGSON_BUILTIN (packsshb
, MIPS_V8QI_FTYPE_V4HI_V4HI
),
16221 LOONGSON_BUILTIN (packushb
, MIPS_UV8QI_FTYPE_UV4HI_UV4HI
),
16222 LOONGSON_BUILTIN_SUFFIX (paddw
, u
, MIPS_UV2SI_FTYPE_UV2SI_UV2SI
),
16223 LOONGSON_BUILTIN_SUFFIX (paddh
, u
, MIPS_UV4HI_FTYPE_UV4HI_UV4HI
),
16224 LOONGSON_BUILTIN_SUFFIX (paddb
, u
, MIPS_UV8QI_FTYPE_UV8QI_UV8QI
),
16225 LOONGSON_BUILTIN_SUFFIX (paddw
, s
, MIPS_V2SI_FTYPE_V2SI_V2SI
),
16226 LOONGSON_BUILTIN_SUFFIX (paddh
, s
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
16227 LOONGSON_BUILTIN_SUFFIX (paddb
, s
, MIPS_V8QI_FTYPE_V8QI_V8QI
),
16228 LOONGSON_BUILTIN_SUFFIX (paddd
, u
, MIPS_UDI_FTYPE_UDI_UDI
),
16229 LOONGSON_BUILTIN_SUFFIX (paddd
, s
, MIPS_DI_FTYPE_DI_DI
),
16230 LOONGSON_BUILTIN (paddsh
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
16231 LOONGSON_BUILTIN (paddsb
, MIPS_V8QI_FTYPE_V8QI_V8QI
),
16232 LOONGSON_BUILTIN (paddush
, MIPS_UV4HI_FTYPE_UV4HI_UV4HI
),
16233 LOONGSON_BUILTIN (paddusb
, MIPS_UV8QI_FTYPE_UV8QI_UV8QI
),
16234 LOONGSON_BUILTIN_ALIAS (pandn_d
, pandn_ud
, MIPS_UDI_FTYPE_UDI_UDI
),
16235 LOONGSON_BUILTIN_ALIAS (pandn_w
, pandn_uw
, MIPS_UV2SI_FTYPE_UV2SI_UV2SI
),
16236 LOONGSON_BUILTIN_ALIAS (pandn_h
, pandn_uh
, MIPS_UV4HI_FTYPE_UV4HI_UV4HI
),
16237 LOONGSON_BUILTIN_ALIAS (pandn_b
, pandn_ub
, MIPS_UV8QI_FTYPE_UV8QI_UV8QI
),
16238 LOONGSON_BUILTIN_ALIAS (pandn_d
, pandn_sd
, MIPS_DI_FTYPE_DI_DI
),
16239 LOONGSON_BUILTIN_ALIAS (pandn_w
, pandn_sw
, MIPS_V2SI_FTYPE_V2SI_V2SI
),
16240 LOONGSON_BUILTIN_ALIAS (pandn_h
, pandn_sh
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
16241 LOONGSON_BUILTIN_ALIAS (pandn_b
, pandn_sb
, MIPS_V8QI_FTYPE_V8QI_V8QI
),
16242 LOONGSON_BUILTIN (pavgh
, MIPS_UV4HI_FTYPE_UV4HI_UV4HI
),
16243 LOONGSON_BUILTIN (pavgb
, MIPS_UV8QI_FTYPE_UV8QI_UV8QI
),
16244 LOONGSON_BUILTIN_SUFFIX (pcmpeqw
, u
, MIPS_UV2SI_FTYPE_UV2SI_UV2SI
),
16245 LOONGSON_BUILTIN_SUFFIX (pcmpeqh
, u
, MIPS_UV4HI_FTYPE_UV4HI_UV4HI
),
16246 LOONGSON_BUILTIN_SUFFIX (pcmpeqb
, u
, MIPS_UV8QI_FTYPE_UV8QI_UV8QI
),
16247 LOONGSON_BUILTIN_SUFFIX (pcmpeqw
, s
, MIPS_V2SI_FTYPE_V2SI_V2SI
),
16248 LOONGSON_BUILTIN_SUFFIX (pcmpeqh
, s
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
16249 LOONGSON_BUILTIN_SUFFIX (pcmpeqb
, s
, MIPS_V8QI_FTYPE_V8QI_V8QI
),
16250 LOONGSON_BUILTIN_SUFFIX (pcmpgtw
, u
, MIPS_UV2SI_FTYPE_UV2SI_UV2SI
),
16251 LOONGSON_BUILTIN_SUFFIX (pcmpgth
, u
, MIPS_UV4HI_FTYPE_UV4HI_UV4HI
),
16252 LOONGSON_BUILTIN_SUFFIX (pcmpgtb
, u
, MIPS_UV8QI_FTYPE_UV8QI_UV8QI
),
16253 LOONGSON_BUILTIN_SUFFIX (pcmpgtw
, s
, MIPS_V2SI_FTYPE_V2SI_V2SI
),
16254 LOONGSON_BUILTIN_SUFFIX (pcmpgth
, s
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
16255 LOONGSON_BUILTIN_SUFFIX (pcmpgtb
, s
, MIPS_V8QI_FTYPE_V8QI_V8QI
),
16256 LOONGSON_BUILTIN_SUFFIX (pextrh
, u
, MIPS_UV4HI_FTYPE_UV4HI_USI
),
16257 LOONGSON_BUILTIN_SUFFIX (pextrh
, s
, MIPS_V4HI_FTYPE_V4HI_USI
),
16258 LOONGSON_BUILTIN_SUFFIX (pinsrh_0
, u
, MIPS_UV4HI_FTYPE_UV4HI_UV4HI
),
16259 LOONGSON_BUILTIN_SUFFIX (pinsrh_1
, u
, MIPS_UV4HI_FTYPE_UV4HI_UV4HI
),
16260 LOONGSON_BUILTIN_SUFFIX (pinsrh_2
, u
, MIPS_UV4HI_FTYPE_UV4HI_UV4HI
),
16261 LOONGSON_BUILTIN_SUFFIX (pinsrh_3
, u
, MIPS_UV4HI_FTYPE_UV4HI_UV4HI
),
16262 LOONGSON_BUILTIN_SUFFIX (pinsrh_0
, s
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
16263 LOONGSON_BUILTIN_SUFFIX (pinsrh_1
, s
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
16264 LOONGSON_BUILTIN_SUFFIX (pinsrh_2
, s
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
16265 LOONGSON_BUILTIN_SUFFIX (pinsrh_3
, s
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
16266 LOONGSON_BUILTIN (pmaddhw
, MIPS_V2SI_FTYPE_V4HI_V4HI
),
16267 LOONGSON_BUILTIN (pmaxsh
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
16268 LOONGSON_BUILTIN (pmaxub
, MIPS_UV8QI_FTYPE_UV8QI_UV8QI
),
16269 LOONGSON_BUILTIN (pminsh
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
16270 LOONGSON_BUILTIN (pminub
, MIPS_UV8QI_FTYPE_UV8QI_UV8QI
),
16271 LOONGSON_BUILTIN_SUFFIX (pmovmskb
, u
, MIPS_UV8QI_FTYPE_UV8QI
),
16272 LOONGSON_BUILTIN_SUFFIX (pmovmskb
, s
, MIPS_V8QI_FTYPE_V8QI
),
16273 LOONGSON_BUILTIN (pmulhuh
, MIPS_UV4HI_FTYPE_UV4HI_UV4HI
),
16274 LOONGSON_BUILTIN (pmulhh
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
16275 LOONGSON_BUILTIN (pmullh
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
16276 LOONGSON_BUILTIN (pmuluw
, MIPS_UDI_FTYPE_UV2SI_UV2SI
),
16277 LOONGSON_BUILTIN (pasubub
, MIPS_UV8QI_FTYPE_UV8QI_UV8QI
),
16278 LOONGSON_BUILTIN (biadd
, MIPS_UV4HI_FTYPE_UV8QI
),
16279 LOONGSON_BUILTIN (psadbh
, MIPS_UV4HI_FTYPE_UV8QI_UV8QI
),
16280 LOONGSON_BUILTIN_SUFFIX (pshufh
, u
, MIPS_UV4HI_FTYPE_UV4HI_UQI
),
16281 LOONGSON_BUILTIN_SUFFIX (pshufh
, s
, MIPS_V4HI_FTYPE_V4HI_UQI
),
16282 LOONGSON_BUILTIN_SUFFIX (psllh
, u
, MIPS_UV4HI_FTYPE_UV4HI_UQI
),
16283 LOONGSON_BUILTIN_SUFFIX (psllh
, s
, MIPS_V4HI_FTYPE_V4HI_UQI
),
16284 LOONGSON_BUILTIN_SUFFIX (psllw
, u
, MIPS_UV2SI_FTYPE_UV2SI_UQI
),
16285 LOONGSON_BUILTIN_SUFFIX (psllw
, s
, MIPS_V2SI_FTYPE_V2SI_UQI
),
16286 LOONGSON_BUILTIN_SUFFIX (psrah
, u
, MIPS_UV4HI_FTYPE_UV4HI_UQI
),
16287 LOONGSON_BUILTIN_SUFFIX (psrah
, s
, MIPS_V4HI_FTYPE_V4HI_UQI
),
16288 LOONGSON_BUILTIN_SUFFIX (psraw
, u
, MIPS_UV2SI_FTYPE_UV2SI_UQI
),
16289 LOONGSON_BUILTIN_SUFFIX (psraw
, s
, MIPS_V2SI_FTYPE_V2SI_UQI
),
16290 LOONGSON_BUILTIN_SUFFIX (psrlh
, u
, MIPS_UV4HI_FTYPE_UV4HI_UQI
),
16291 LOONGSON_BUILTIN_SUFFIX (psrlh
, s
, MIPS_V4HI_FTYPE_V4HI_UQI
),
16292 LOONGSON_BUILTIN_SUFFIX (psrlw
, u
, MIPS_UV2SI_FTYPE_UV2SI_UQI
),
16293 LOONGSON_BUILTIN_SUFFIX (psrlw
, s
, MIPS_V2SI_FTYPE_V2SI_UQI
),
16294 LOONGSON_BUILTIN_SUFFIX (psubw
, u
, MIPS_UV2SI_FTYPE_UV2SI_UV2SI
),
16295 LOONGSON_BUILTIN_SUFFIX (psubh
, u
, MIPS_UV4HI_FTYPE_UV4HI_UV4HI
),
16296 LOONGSON_BUILTIN_SUFFIX (psubb
, u
, MIPS_UV8QI_FTYPE_UV8QI_UV8QI
),
16297 LOONGSON_BUILTIN_SUFFIX (psubw
, s
, MIPS_V2SI_FTYPE_V2SI_V2SI
),
16298 LOONGSON_BUILTIN_SUFFIX (psubh
, s
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
16299 LOONGSON_BUILTIN_SUFFIX (psubb
, s
, MIPS_V8QI_FTYPE_V8QI_V8QI
),
16300 LOONGSON_BUILTIN_SUFFIX (psubd
, u
, MIPS_UDI_FTYPE_UDI_UDI
),
16301 LOONGSON_BUILTIN_SUFFIX (psubd
, s
, MIPS_DI_FTYPE_DI_DI
),
16302 LOONGSON_BUILTIN (psubsh
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
16303 LOONGSON_BUILTIN (psubsb
, MIPS_V8QI_FTYPE_V8QI_V8QI
),
16304 LOONGSON_BUILTIN (psubush
, MIPS_UV4HI_FTYPE_UV4HI_UV4HI
),
16305 LOONGSON_BUILTIN (psubusb
, MIPS_UV8QI_FTYPE_UV8QI_UV8QI
),
16306 LOONGSON_BUILTIN_SUFFIX (punpckhbh
, u
, MIPS_UV8QI_FTYPE_UV8QI_UV8QI
),
16307 LOONGSON_BUILTIN_SUFFIX (punpckhhw
, u
, MIPS_UV4HI_FTYPE_UV4HI_UV4HI
),
16308 LOONGSON_BUILTIN_SUFFIX (punpckhwd
, u
, MIPS_UV2SI_FTYPE_UV2SI_UV2SI
),
16309 LOONGSON_BUILTIN_SUFFIX (punpckhbh
, s
, MIPS_V8QI_FTYPE_V8QI_V8QI
),
16310 LOONGSON_BUILTIN_SUFFIX (punpckhhw
, s
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
16311 LOONGSON_BUILTIN_SUFFIX (punpckhwd
, s
, MIPS_V2SI_FTYPE_V2SI_V2SI
),
16312 LOONGSON_BUILTIN_SUFFIX (punpcklbh
, u
, MIPS_UV8QI_FTYPE_UV8QI_UV8QI
),
16313 LOONGSON_BUILTIN_SUFFIX (punpcklhw
, u
, MIPS_UV4HI_FTYPE_UV4HI_UV4HI
),
16314 LOONGSON_BUILTIN_SUFFIX (punpcklwd
, u
, MIPS_UV2SI_FTYPE_UV2SI_UV2SI
),
16315 LOONGSON_BUILTIN_SUFFIX (punpcklbh
, s
, MIPS_V8QI_FTYPE_V8QI_V8QI
),
16316 LOONGSON_BUILTIN_SUFFIX (punpcklhw
, s
, MIPS_V4HI_FTYPE_V4HI_V4HI
),
16317 LOONGSON_BUILTIN_SUFFIX (punpcklwd
, s
, MIPS_V2SI_FTYPE_V2SI_V2SI
),
16319 /* Sundry other built-in functions. */
16320 DIRECT_NO_TARGET_BUILTIN (cache
, MIPS_VOID_FTYPE_SI_CVPOINTER
, cache
),
16322 /* Built-in functions for MSA. */
16323 MSA_BUILTIN_PURE (sll_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16324 MSA_BUILTIN_PURE (sll_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16325 MSA_BUILTIN_PURE (sll_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16326 MSA_BUILTIN_PURE (sll_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16327 MSA_BUILTIN_PURE (slli_b
, MIPS_V16QI_FTYPE_V16QI_UQI
),
16328 MSA_BUILTIN_PURE (slli_h
, MIPS_V8HI_FTYPE_V8HI_UQI
),
16329 MSA_BUILTIN_PURE (slli_w
, MIPS_V4SI_FTYPE_V4SI_UQI
),
16330 MSA_BUILTIN_PURE (slli_d
, MIPS_V2DI_FTYPE_V2DI_UQI
),
16331 MSA_BUILTIN_PURE (sra_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16332 MSA_BUILTIN_PURE (sra_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16333 MSA_BUILTIN_PURE (sra_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16334 MSA_BUILTIN_PURE (sra_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16335 MSA_BUILTIN_PURE (srai_b
, MIPS_V16QI_FTYPE_V16QI_UQI
),
16336 MSA_BUILTIN_PURE (srai_h
, MIPS_V8HI_FTYPE_V8HI_UQI
),
16337 MSA_BUILTIN_PURE (srai_w
, MIPS_V4SI_FTYPE_V4SI_UQI
),
16338 MSA_BUILTIN_PURE (srai_d
, MIPS_V2DI_FTYPE_V2DI_UQI
),
16339 MSA_BUILTIN_PURE (srar_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16340 MSA_BUILTIN_PURE (srar_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16341 MSA_BUILTIN_PURE (srar_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16342 MSA_BUILTIN_PURE (srar_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16343 MSA_BUILTIN_PURE (srari_b
, MIPS_V16QI_FTYPE_V16QI_UQI
),
16344 MSA_BUILTIN_PURE (srari_h
, MIPS_V8HI_FTYPE_V8HI_UQI
),
16345 MSA_BUILTIN_PURE (srari_w
, MIPS_V4SI_FTYPE_V4SI_UQI
),
16346 MSA_BUILTIN_PURE (srari_d
, MIPS_V2DI_FTYPE_V2DI_UQI
),
16347 MSA_BUILTIN_PURE (srl_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16348 MSA_BUILTIN_PURE (srl_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16349 MSA_BUILTIN_PURE (srl_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16350 MSA_BUILTIN_PURE (srl_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16351 MSA_BUILTIN_PURE (srli_b
, MIPS_V16QI_FTYPE_V16QI_UQI
),
16352 MSA_BUILTIN_PURE (srli_h
, MIPS_V8HI_FTYPE_V8HI_UQI
),
16353 MSA_BUILTIN_PURE (srli_w
, MIPS_V4SI_FTYPE_V4SI_UQI
),
16354 MSA_BUILTIN_PURE (srli_d
, MIPS_V2DI_FTYPE_V2DI_UQI
),
16355 MSA_BUILTIN_PURE (srlr_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16356 MSA_BUILTIN_PURE (srlr_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16357 MSA_BUILTIN_PURE (srlr_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16358 MSA_BUILTIN_PURE (srlr_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16359 MSA_BUILTIN_PURE (srlri_b
, MIPS_V16QI_FTYPE_V16QI_UQI
),
16360 MSA_BUILTIN_PURE (srlri_h
, MIPS_V8HI_FTYPE_V8HI_UQI
),
16361 MSA_BUILTIN_PURE (srlri_w
, MIPS_V4SI_FTYPE_V4SI_UQI
),
16362 MSA_BUILTIN_PURE (srlri_d
, MIPS_V2DI_FTYPE_V2DI_UQI
),
16363 MSA_BUILTIN_PURE (bclr_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
16364 MSA_BUILTIN_PURE (bclr_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI
),
16365 MSA_BUILTIN_PURE (bclr_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI
),
16366 MSA_BUILTIN_PURE (bclr_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI
),
16367 MSA_BUILTIN_PURE (bclri_b
, MIPS_UV16QI_FTYPE_UV16QI_UQI
),
16368 MSA_BUILTIN_PURE (bclri_h
, MIPS_UV8HI_FTYPE_UV8HI_UQI
),
16369 MSA_BUILTIN_PURE (bclri_w
, MIPS_UV4SI_FTYPE_UV4SI_UQI
),
16370 MSA_BUILTIN_PURE (bclri_d
, MIPS_UV2DI_FTYPE_UV2DI_UQI
),
16371 MSA_BUILTIN_PURE (bset_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
16372 MSA_BUILTIN_PURE (bset_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI
),
16373 MSA_BUILTIN_PURE (bset_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI
),
16374 MSA_BUILTIN_PURE (bset_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI
),
16375 MSA_BUILTIN_PURE (bseti_b
, MIPS_UV16QI_FTYPE_UV16QI_UQI
),
16376 MSA_BUILTIN_PURE (bseti_h
, MIPS_UV8HI_FTYPE_UV8HI_UQI
),
16377 MSA_BUILTIN_PURE (bseti_w
, MIPS_UV4SI_FTYPE_UV4SI_UQI
),
16378 MSA_BUILTIN_PURE (bseti_d
, MIPS_UV2DI_FTYPE_UV2DI_UQI
),
16379 MSA_BUILTIN_PURE (bneg_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
16380 MSA_BUILTIN_PURE (bneg_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI
),
16381 MSA_BUILTIN_PURE (bneg_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI
),
16382 MSA_BUILTIN_PURE (bneg_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI
),
16383 MSA_BUILTIN_PURE (bnegi_b
, MIPS_UV16QI_FTYPE_UV16QI_UQI
),
16384 MSA_BUILTIN_PURE (bnegi_h
, MIPS_UV8HI_FTYPE_UV8HI_UQI
),
16385 MSA_BUILTIN_PURE (bnegi_w
, MIPS_UV4SI_FTYPE_UV4SI_UQI
),
16386 MSA_BUILTIN_PURE (bnegi_d
, MIPS_UV2DI_FTYPE_UV2DI_UQI
),
16387 MSA_BUILTIN_PURE (binsl_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UV16QI
),
16388 MSA_BUILTIN_PURE (binsl_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI_UV8HI
),
16389 MSA_BUILTIN_PURE (binsl_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI_UV4SI
),
16390 MSA_BUILTIN_PURE (binsl_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI_UV2DI
),
16391 MSA_BUILTIN_PURE (binsli_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UQI
),
16392 MSA_BUILTIN_PURE (binsli_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI_UQI
),
16393 MSA_BUILTIN_PURE (binsli_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI_UQI
),
16394 MSA_BUILTIN_PURE (binsli_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI_UQI
),
16395 MSA_BUILTIN_PURE (binsr_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UV16QI
),
16396 MSA_BUILTIN_PURE (binsr_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI_UV8HI
),
16397 MSA_BUILTIN_PURE (binsr_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI_UV4SI
),
16398 MSA_BUILTIN_PURE (binsr_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI_UV2DI
),
16399 MSA_BUILTIN_PURE (binsri_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UQI
),
16400 MSA_BUILTIN_PURE (binsri_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI_UQI
),
16401 MSA_BUILTIN_PURE (binsri_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI_UQI
),
16402 MSA_BUILTIN_PURE (binsri_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI_UQI
),
16403 MSA_BUILTIN_PURE (addv_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16404 MSA_BUILTIN_PURE (addv_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16405 MSA_BUILTIN_PURE (addv_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16406 MSA_BUILTIN_PURE (addv_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16407 MSA_BUILTIN_PURE (addvi_b
, MIPS_V16QI_FTYPE_V16QI_UQI
),
16408 MSA_BUILTIN_PURE (addvi_h
, MIPS_V8HI_FTYPE_V8HI_UQI
),
16409 MSA_BUILTIN_PURE (addvi_w
, MIPS_V4SI_FTYPE_V4SI_UQI
),
16410 MSA_BUILTIN_PURE (addvi_d
, MIPS_V2DI_FTYPE_V2DI_UQI
),
16411 MSA_BUILTIN_PURE (subv_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16412 MSA_BUILTIN_PURE (subv_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16413 MSA_BUILTIN_PURE (subv_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16414 MSA_BUILTIN_PURE (subv_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16415 MSA_BUILTIN_PURE (subvi_b
, MIPS_V16QI_FTYPE_V16QI_UQI
),
16416 MSA_BUILTIN_PURE (subvi_h
, MIPS_V8HI_FTYPE_V8HI_UQI
),
16417 MSA_BUILTIN_PURE (subvi_w
, MIPS_V4SI_FTYPE_V4SI_UQI
),
16418 MSA_BUILTIN_PURE (subvi_d
, MIPS_V2DI_FTYPE_V2DI_UQI
),
16419 MSA_BUILTIN_PURE (max_s_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16420 MSA_BUILTIN_PURE (max_s_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16421 MSA_BUILTIN_PURE (max_s_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16422 MSA_BUILTIN_PURE (max_s_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16423 MSA_BUILTIN_PURE (maxi_s_b
, MIPS_V16QI_FTYPE_V16QI_QI
),
16424 MSA_BUILTIN_PURE (maxi_s_h
, MIPS_V8HI_FTYPE_V8HI_QI
),
16425 MSA_BUILTIN_PURE (maxi_s_w
, MIPS_V4SI_FTYPE_V4SI_QI
),
16426 MSA_BUILTIN_PURE (maxi_s_d
, MIPS_V2DI_FTYPE_V2DI_QI
),
16427 MSA_BUILTIN_PURE (max_u_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
16428 MSA_BUILTIN_PURE (max_u_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI
),
16429 MSA_BUILTIN_PURE (max_u_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI
),
16430 MSA_BUILTIN_PURE (max_u_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI
),
16431 MSA_BUILTIN_PURE (maxi_u_b
, MIPS_UV16QI_FTYPE_UV16QI_UQI
),
16432 MSA_BUILTIN_PURE (maxi_u_h
, MIPS_UV8HI_FTYPE_UV8HI_UQI
),
16433 MSA_BUILTIN_PURE (maxi_u_w
, MIPS_UV4SI_FTYPE_UV4SI_UQI
),
16434 MSA_BUILTIN_PURE (maxi_u_d
, MIPS_UV2DI_FTYPE_UV2DI_UQI
),
16435 MSA_BUILTIN_PURE (min_s_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16436 MSA_BUILTIN_PURE (min_s_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16437 MSA_BUILTIN_PURE (min_s_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16438 MSA_BUILTIN_PURE (min_s_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16439 MSA_BUILTIN_PURE (mini_s_b
, MIPS_V16QI_FTYPE_V16QI_QI
),
16440 MSA_BUILTIN_PURE (mini_s_h
, MIPS_V8HI_FTYPE_V8HI_QI
),
16441 MSA_BUILTIN_PURE (mini_s_w
, MIPS_V4SI_FTYPE_V4SI_QI
),
16442 MSA_BUILTIN_PURE (mini_s_d
, MIPS_V2DI_FTYPE_V2DI_QI
),
16443 MSA_BUILTIN_PURE (min_u_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
16444 MSA_BUILTIN_PURE (min_u_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI
),
16445 MSA_BUILTIN_PURE (min_u_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI
),
16446 MSA_BUILTIN_PURE (min_u_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI
),
16447 MSA_BUILTIN_PURE (mini_u_b
, MIPS_UV16QI_FTYPE_UV16QI_UQI
),
16448 MSA_BUILTIN_PURE (mini_u_h
, MIPS_UV8HI_FTYPE_UV8HI_UQI
),
16449 MSA_BUILTIN_PURE (mini_u_w
, MIPS_UV4SI_FTYPE_UV4SI_UQI
),
16450 MSA_BUILTIN_PURE (mini_u_d
, MIPS_UV2DI_FTYPE_UV2DI_UQI
),
16451 MSA_BUILTIN_PURE (max_a_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16452 MSA_BUILTIN_PURE (max_a_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16453 MSA_BUILTIN_PURE (max_a_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16454 MSA_BUILTIN_PURE (max_a_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16455 MSA_BUILTIN_PURE (min_a_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16456 MSA_BUILTIN_PURE (min_a_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16457 MSA_BUILTIN_PURE (min_a_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16458 MSA_BUILTIN_PURE (min_a_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16459 MSA_BUILTIN (ceq_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16460 MSA_BUILTIN (ceq_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16461 MSA_BUILTIN (ceq_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16462 MSA_BUILTIN (ceq_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16463 MSA_BUILTIN (ceqi_b
, MIPS_V16QI_FTYPE_V16QI_QI
),
16464 MSA_BUILTIN (ceqi_h
, MIPS_V8HI_FTYPE_V8HI_QI
),
16465 MSA_BUILTIN (ceqi_w
, MIPS_V4SI_FTYPE_V4SI_QI
),
16466 MSA_BUILTIN (ceqi_d
, MIPS_V2DI_FTYPE_V2DI_QI
),
16467 MSA_BUILTIN (clt_s_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16468 MSA_BUILTIN (clt_s_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16469 MSA_BUILTIN (clt_s_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16470 MSA_BUILTIN (clt_s_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16471 MSA_BUILTIN (clti_s_b
, MIPS_V16QI_FTYPE_V16QI_QI
),
16472 MSA_BUILTIN (clti_s_h
, MIPS_V8HI_FTYPE_V8HI_QI
),
16473 MSA_BUILTIN (clti_s_w
, MIPS_V4SI_FTYPE_V4SI_QI
),
16474 MSA_BUILTIN (clti_s_d
, MIPS_V2DI_FTYPE_V2DI_QI
),
16475 MSA_BUILTIN (clt_u_b
, MIPS_V16QI_FTYPE_UV16QI_UV16QI
),
16476 MSA_BUILTIN (clt_u_h
, MIPS_V8HI_FTYPE_UV8HI_UV8HI
),
16477 MSA_BUILTIN (clt_u_w
, MIPS_V4SI_FTYPE_UV4SI_UV4SI
),
16478 MSA_BUILTIN (clt_u_d
, MIPS_V2DI_FTYPE_UV2DI_UV2DI
),
16479 MSA_BUILTIN (clti_u_b
, MIPS_V16QI_FTYPE_UV16QI_UQI
),
16480 MSA_BUILTIN (clti_u_h
, MIPS_V8HI_FTYPE_UV8HI_UQI
),
16481 MSA_BUILTIN (clti_u_w
, MIPS_V4SI_FTYPE_UV4SI_UQI
),
16482 MSA_BUILTIN (clti_u_d
, MIPS_V2DI_FTYPE_UV2DI_UQI
),
16483 MSA_BUILTIN (cle_s_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16484 MSA_BUILTIN (cle_s_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16485 MSA_BUILTIN (cle_s_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16486 MSA_BUILTIN (cle_s_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16487 MSA_BUILTIN (clei_s_b
, MIPS_V16QI_FTYPE_V16QI_QI
),
16488 MSA_BUILTIN (clei_s_h
, MIPS_V8HI_FTYPE_V8HI_QI
),
16489 MSA_BUILTIN (clei_s_w
, MIPS_V4SI_FTYPE_V4SI_QI
),
16490 MSA_BUILTIN (clei_s_d
, MIPS_V2DI_FTYPE_V2DI_QI
),
16491 MSA_BUILTIN (cle_u_b
, MIPS_V16QI_FTYPE_UV16QI_UV16QI
),
16492 MSA_BUILTIN (cle_u_h
, MIPS_V8HI_FTYPE_UV8HI_UV8HI
),
16493 MSA_BUILTIN (cle_u_w
, MIPS_V4SI_FTYPE_UV4SI_UV4SI
),
16494 MSA_BUILTIN (cle_u_d
, MIPS_V2DI_FTYPE_UV2DI_UV2DI
),
16495 MSA_BUILTIN (clei_u_b
, MIPS_V16QI_FTYPE_UV16QI_UQI
),
16496 MSA_BUILTIN (clei_u_h
, MIPS_V8HI_FTYPE_UV8HI_UQI
),
16497 MSA_BUILTIN (clei_u_w
, MIPS_V4SI_FTYPE_UV4SI_UQI
),
16498 MSA_BUILTIN (clei_u_d
, MIPS_V2DI_FTYPE_UV2DI_UQI
),
16499 MSA_BUILTIN (ld_b
, MIPS_V16QI_FTYPE_CVPOINTER_SI
),
16500 MSA_BUILTIN (ld_h
, MIPS_V8HI_FTYPE_CVPOINTER_SI
),
16501 MSA_BUILTIN (ld_w
, MIPS_V4SI_FTYPE_CVPOINTER_SI
),
16502 MSA_BUILTIN (ld_d
, MIPS_V2DI_FTYPE_CVPOINTER_SI
),
16503 MSA_NO_TARGET_BUILTIN (st_b
, MIPS_VOID_FTYPE_V16QI_CVPOINTER_SI
),
16504 MSA_NO_TARGET_BUILTIN (st_h
, MIPS_VOID_FTYPE_V8HI_CVPOINTER_SI
),
16505 MSA_NO_TARGET_BUILTIN (st_w
, MIPS_VOID_FTYPE_V4SI_CVPOINTER_SI
),
16506 MSA_NO_TARGET_BUILTIN (st_d
, MIPS_VOID_FTYPE_V2DI_CVPOINTER_SI
),
16507 MSA_BUILTIN_PURE (sat_s_b
, MIPS_V16QI_FTYPE_V16QI_UQI
),
16508 MSA_BUILTIN_PURE (sat_s_h
, MIPS_V8HI_FTYPE_V8HI_UQI
),
16509 MSA_BUILTIN_PURE (sat_s_w
, MIPS_V4SI_FTYPE_V4SI_UQI
),
16510 MSA_BUILTIN_PURE (sat_s_d
, MIPS_V2DI_FTYPE_V2DI_UQI
),
16511 MSA_BUILTIN_PURE (sat_u_b
, MIPS_UV16QI_FTYPE_UV16QI_UQI
),
16512 MSA_BUILTIN_PURE (sat_u_h
, MIPS_UV8HI_FTYPE_UV8HI_UQI
),
16513 MSA_BUILTIN_PURE (sat_u_w
, MIPS_UV4SI_FTYPE_UV4SI_UQI
),
16514 MSA_BUILTIN_PURE (sat_u_d
, MIPS_UV2DI_FTYPE_UV2DI_UQI
),
16515 MSA_BUILTIN_PURE (add_a_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16516 MSA_BUILTIN_PURE (add_a_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16517 MSA_BUILTIN_PURE (add_a_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16518 MSA_BUILTIN_PURE (add_a_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16519 MSA_BUILTIN_PURE (adds_a_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16520 MSA_BUILTIN_PURE (adds_a_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16521 MSA_BUILTIN_PURE (adds_a_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16522 MSA_BUILTIN_PURE (adds_a_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16523 MSA_BUILTIN_PURE (adds_s_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16524 MSA_BUILTIN_PURE (adds_s_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16525 MSA_BUILTIN_PURE (adds_s_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16526 MSA_BUILTIN_PURE (adds_s_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16527 MSA_BUILTIN_PURE (adds_u_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
16528 MSA_BUILTIN_PURE (adds_u_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI
),
16529 MSA_BUILTIN_PURE (adds_u_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI
),
16530 MSA_BUILTIN_PURE (adds_u_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI
),
16531 MSA_BUILTIN_PURE (ave_s_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16532 MSA_BUILTIN_PURE (ave_s_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16533 MSA_BUILTIN_PURE (ave_s_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16534 MSA_BUILTIN_PURE (ave_s_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16535 MSA_BUILTIN_PURE (ave_u_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
16536 MSA_BUILTIN_PURE (ave_u_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI
),
16537 MSA_BUILTIN_PURE (ave_u_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI
),
16538 MSA_BUILTIN_PURE (ave_u_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI
),
16539 MSA_BUILTIN_PURE (aver_s_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16540 MSA_BUILTIN_PURE (aver_s_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16541 MSA_BUILTIN_PURE (aver_s_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16542 MSA_BUILTIN_PURE (aver_s_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16543 MSA_BUILTIN_PURE (aver_u_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
16544 MSA_BUILTIN_PURE (aver_u_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI
),
16545 MSA_BUILTIN_PURE (aver_u_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI
),
16546 MSA_BUILTIN_PURE (aver_u_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI
),
16547 MSA_BUILTIN_PURE (subs_s_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16548 MSA_BUILTIN_PURE (subs_s_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16549 MSA_BUILTIN_PURE (subs_s_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16550 MSA_BUILTIN_PURE (subs_s_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16551 MSA_BUILTIN_PURE (subs_u_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
16552 MSA_BUILTIN_PURE (subs_u_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI
),
16553 MSA_BUILTIN_PURE (subs_u_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI
),
16554 MSA_BUILTIN_PURE (subs_u_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI
),
16555 MSA_BUILTIN_PURE (subsuu_s_b
, MIPS_V16QI_FTYPE_UV16QI_UV16QI
),
16556 MSA_BUILTIN_PURE (subsuu_s_h
, MIPS_V8HI_FTYPE_UV8HI_UV8HI
),
16557 MSA_BUILTIN_PURE (subsuu_s_w
, MIPS_V4SI_FTYPE_UV4SI_UV4SI
),
16558 MSA_BUILTIN_PURE (subsuu_s_d
, MIPS_V2DI_FTYPE_UV2DI_UV2DI
),
16559 MSA_BUILTIN_PURE (subsus_u_b
, MIPS_UV16QI_FTYPE_UV16QI_V16QI
),
16560 MSA_BUILTIN_PURE (subsus_u_h
, MIPS_UV8HI_FTYPE_UV8HI_V8HI
),
16561 MSA_BUILTIN_PURE (subsus_u_w
, MIPS_UV4SI_FTYPE_UV4SI_V4SI
),
16562 MSA_BUILTIN_PURE (subsus_u_d
, MIPS_UV2DI_FTYPE_UV2DI_V2DI
),
16563 MSA_BUILTIN_PURE (asub_s_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16564 MSA_BUILTIN_PURE (asub_s_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16565 MSA_BUILTIN_PURE (asub_s_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16566 MSA_BUILTIN_PURE (asub_s_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16567 MSA_BUILTIN_PURE (asub_u_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
16568 MSA_BUILTIN_PURE (asub_u_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI
),
16569 MSA_BUILTIN_PURE (asub_u_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI
),
16570 MSA_BUILTIN_PURE (asub_u_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI
),
16571 MSA_BUILTIN_PURE (mulv_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16572 MSA_BUILTIN_PURE (mulv_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16573 MSA_BUILTIN_PURE (mulv_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16574 MSA_BUILTIN_PURE (mulv_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16575 MSA_BUILTIN_PURE (maddv_b
, MIPS_V16QI_FTYPE_V16QI_V16QI_V16QI
),
16576 MSA_BUILTIN_PURE (maddv_h
, MIPS_V8HI_FTYPE_V8HI_V8HI_V8HI
),
16577 MSA_BUILTIN_PURE (maddv_w
, MIPS_V4SI_FTYPE_V4SI_V4SI_V4SI
),
16578 MSA_BUILTIN_PURE (maddv_d
, MIPS_V2DI_FTYPE_V2DI_V2DI_V2DI
),
16579 MSA_BUILTIN_PURE (msubv_b
, MIPS_V16QI_FTYPE_V16QI_V16QI_V16QI
),
16580 MSA_BUILTIN_PURE (msubv_h
, MIPS_V8HI_FTYPE_V8HI_V8HI_V8HI
),
16581 MSA_BUILTIN_PURE (msubv_w
, MIPS_V4SI_FTYPE_V4SI_V4SI_V4SI
),
16582 MSA_BUILTIN_PURE (msubv_d
, MIPS_V2DI_FTYPE_V2DI_V2DI_V2DI
),
16583 MSA_BUILTIN_PURE (div_s_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16584 MSA_BUILTIN_PURE (div_s_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16585 MSA_BUILTIN_PURE (div_s_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16586 MSA_BUILTIN_PURE (div_s_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16587 MSA_BUILTIN_PURE (div_u_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
16588 MSA_BUILTIN_PURE (div_u_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI
),
16589 MSA_BUILTIN_PURE (div_u_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI
),
16590 MSA_BUILTIN_PURE (div_u_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI
),
16591 MSA_BUILTIN_PURE (hadd_s_h
, MIPS_V8HI_FTYPE_V16QI_V16QI
),
16592 MSA_BUILTIN_PURE (hadd_s_w
, MIPS_V4SI_FTYPE_V8HI_V8HI
),
16593 MSA_BUILTIN_PURE (hadd_s_d
, MIPS_V2DI_FTYPE_V4SI_V4SI
),
16594 MSA_BUILTIN_PURE (hadd_u_h
, MIPS_UV8HI_FTYPE_UV16QI_UV16QI
),
16595 MSA_BUILTIN_PURE (hadd_u_w
, MIPS_UV4SI_FTYPE_UV8HI_UV8HI
),
16596 MSA_BUILTIN_PURE (hadd_u_d
, MIPS_UV2DI_FTYPE_UV4SI_UV4SI
),
16597 MSA_BUILTIN_PURE (hsub_s_h
, MIPS_V8HI_FTYPE_V16QI_V16QI
),
16598 MSA_BUILTIN_PURE (hsub_s_w
, MIPS_V4SI_FTYPE_V8HI_V8HI
),
16599 MSA_BUILTIN_PURE (hsub_s_d
, MIPS_V2DI_FTYPE_V4SI_V4SI
),
16600 MSA_BUILTIN_PURE (hsub_u_h
, MIPS_V8HI_FTYPE_UV16QI_UV16QI
),
16601 MSA_BUILTIN_PURE (hsub_u_w
, MIPS_V4SI_FTYPE_UV8HI_UV8HI
),
16602 MSA_BUILTIN_PURE (hsub_u_d
, MIPS_V2DI_FTYPE_UV4SI_UV4SI
),
16603 MSA_BUILTIN_PURE (mod_s_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16604 MSA_BUILTIN_PURE (mod_s_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16605 MSA_BUILTIN_PURE (mod_s_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16606 MSA_BUILTIN_PURE (mod_s_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16607 MSA_BUILTIN_PURE (mod_u_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
16608 MSA_BUILTIN_PURE (mod_u_h
, MIPS_UV8HI_FTYPE_UV8HI_UV8HI
),
16609 MSA_BUILTIN_PURE (mod_u_w
, MIPS_UV4SI_FTYPE_UV4SI_UV4SI
),
16610 MSA_BUILTIN_PURE (mod_u_d
, MIPS_UV2DI_FTYPE_UV2DI_UV2DI
),
16611 MSA_BUILTIN_PURE (dotp_s_h
, MIPS_V8HI_FTYPE_V16QI_V16QI
),
16612 MSA_BUILTIN_PURE (dotp_s_w
, MIPS_V4SI_FTYPE_V8HI_V8HI
),
16613 MSA_BUILTIN_PURE (dotp_s_d
, MIPS_V2DI_FTYPE_V4SI_V4SI
),
16614 MSA_BUILTIN_PURE (dotp_u_h
, MIPS_UV8HI_FTYPE_UV16QI_UV16QI
),
16615 MSA_BUILTIN_PURE (dotp_u_w
, MIPS_UV4SI_FTYPE_UV8HI_UV8HI
),
16616 MSA_BUILTIN_PURE (dotp_u_d
, MIPS_UV2DI_FTYPE_UV4SI_UV4SI
),
16617 MSA_BUILTIN_PURE (dpadd_s_h
, MIPS_V8HI_FTYPE_V8HI_V16QI_V16QI
),
16618 MSA_BUILTIN_PURE (dpadd_s_w
, MIPS_V4SI_FTYPE_V4SI_V8HI_V8HI
),
16619 MSA_BUILTIN_PURE (dpadd_s_d
, MIPS_V2DI_FTYPE_V2DI_V4SI_V4SI
),
16620 MSA_BUILTIN_PURE (dpadd_u_h
, MIPS_UV8HI_FTYPE_UV8HI_UV16QI_UV16QI
),
16621 MSA_BUILTIN_PURE (dpadd_u_w
, MIPS_UV4SI_FTYPE_UV4SI_UV8HI_UV8HI
),
16622 MSA_BUILTIN_PURE (dpadd_u_d
, MIPS_UV2DI_FTYPE_UV2DI_UV4SI_UV4SI
),
16623 MSA_BUILTIN_PURE (dpsub_s_h
, MIPS_V8HI_FTYPE_V8HI_V16QI_V16QI
),
16624 MSA_BUILTIN_PURE (dpsub_s_w
, MIPS_V4SI_FTYPE_V4SI_V8HI_V8HI
),
16625 MSA_BUILTIN_PURE (dpsub_s_d
, MIPS_V2DI_FTYPE_V2DI_V4SI_V4SI
),
16626 MSA_BUILTIN_PURE (dpsub_u_h
, MIPS_V8HI_FTYPE_V8HI_UV16QI_UV16QI
),
16627 MSA_BUILTIN_PURE (dpsub_u_w
, MIPS_V4SI_FTYPE_V4SI_UV8HI_UV8HI
),
16628 MSA_BUILTIN_PURE (dpsub_u_d
, MIPS_V2DI_FTYPE_V2DI_UV4SI_UV4SI
),
16629 MSA_BUILTIN_PURE (sld_b
, MIPS_V16QI_FTYPE_V16QI_V16QI_SI
),
16630 MSA_BUILTIN_PURE (sld_h
, MIPS_V8HI_FTYPE_V8HI_V8HI_SI
),
16631 MSA_BUILTIN_PURE (sld_w
, MIPS_V4SI_FTYPE_V4SI_V4SI_SI
),
16632 MSA_BUILTIN_PURE (sld_d
, MIPS_V2DI_FTYPE_V2DI_V2DI_SI
),
16633 MSA_BUILTIN_PURE (sldi_b
, MIPS_V16QI_FTYPE_V16QI_V16QI_UQI
),
16634 MSA_BUILTIN_PURE (sldi_h
, MIPS_V8HI_FTYPE_V8HI_V8HI_UQI
),
16635 MSA_BUILTIN_PURE (sldi_w
, MIPS_V4SI_FTYPE_V4SI_V4SI_UQI
),
16636 MSA_BUILTIN_PURE (sldi_d
, MIPS_V2DI_FTYPE_V2DI_V2DI_UQI
),
16637 MSA_BUILTIN_PURE (splat_b
, MIPS_V16QI_FTYPE_V16QI_SI
),
16638 MSA_BUILTIN_PURE (splat_h
, MIPS_V8HI_FTYPE_V8HI_SI
),
16639 MSA_BUILTIN_PURE (splat_w
, MIPS_V4SI_FTYPE_V4SI_SI
),
16640 MSA_BUILTIN_PURE (splat_d
, MIPS_V2DI_FTYPE_V2DI_SI
),
16641 MSA_BUILTIN_PURE (splati_b
, MIPS_V16QI_FTYPE_V16QI_UQI
),
16642 MSA_BUILTIN_PURE (splati_h
, MIPS_V8HI_FTYPE_V8HI_UQI
),
16643 MSA_BUILTIN_PURE (splati_w
, MIPS_V4SI_FTYPE_V4SI_UQI
),
16644 MSA_BUILTIN_PURE (splati_d
, MIPS_V2DI_FTYPE_V2DI_UQI
),
16645 MSA_BUILTIN_PURE (pckev_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16646 MSA_BUILTIN_PURE (pckev_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16647 MSA_BUILTIN_PURE (pckev_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16648 MSA_BUILTIN_PURE (pckev_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16649 MSA_BUILTIN_PURE (pckod_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16650 MSA_BUILTIN_PURE (pckod_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16651 MSA_BUILTIN_PURE (pckod_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16652 MSA_BUILTIN_PURE (pckod_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16653 MSA_BUILTIN_PURE (ilvl_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16654 MSA_BUILTIN_PURE (ilvl_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16655 MSA_BUILTIN_PURE (ilvl_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16656 MSA_BUILTIN_PURE (ilvl_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16657 MSA_BUILTIN_PURE (ilvr_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16658 MSA_BUILTIN_PURE (ilvr_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16659 MSA_BUILTIN_PURE (ilvr_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16660 MSA_BUILTIN_PURE (ilvr_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16661 MSA_BUILTIN_PURE (ilvev_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16662 MSA_BUILTIN_PURE (ilvev_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16663 MSA_BUILTIN_PURE (ilvev_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16664 MSA_BUILTIN_PURE (ilvev_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16665 MSA_BUILTIN_PURE (ilvod_b
, MIPS_V16QI_FTYPE_V16QI_V16QI
),
16666 MSA_BUILTIN_PURE (ilvod_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16667 MSA_BUILTIN_PURE (ilvod_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16668 MSA_BUILTIN_PURE (ilvod_d
, MIPS_V2DI_FTYPE_V2DI_V2DI
),
16669 MSA_BUILTIN_PURE (vshf_b
, MIPS_V16QI_FTYPE_V16QI_V16QI_V16QI
),
16670 MSA_BUILTIN_PURE (vshf_h
, MIPS_V8HI_FTYPE_V8HI_V8HI_V8HI
),
16671 MSA_BUILTIN_PURE (vshf_w
, MIPS_V4SI_FTYPE_V4SI_V4SI_V4SI
),
16672 MSA_BUILTIN_PURE (vshf_d
, MIPS_V2DI_FTYPE_V2DI_V2DI_V2DI
),
16673 MSA_BUILTIN_PURE (and_v
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
16674 MSA_BUILTIN_PURE (andi_b
, MIPS_UV16QI_FTYPE_UV16QI_UQI
),
16675 MSA_BUILTIN_PURE (or_v
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
16676 MSA_BUILTIN_PURE (ori_b
, MIPS_UV16QI_FTYPE_UV16QI_UQI
),
16677 MSA_BUILTIN_PURE (nor_v
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
16678 MSA_BUILTIN_PURE (nori_b
, MIPS_UV16QI_FTYPE_UV16QI_UQI
),
16679 MSA_BUILTIN_PURE (xor_v
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI
),
16680 MSA_BUILTIN_PURE (xori_b
, MIPS_UV16QI_FTYPE_UV16QI_UQI
),
16681 MSA_BUILTIN_PURE (bmnz_v
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UV16QI
),
16682 MSA_BUILTIN_PURE (bmnzi_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UQI
),
16683 MSA_BUILTIN_PURE (bmz_v
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UV16QI
),
16684 MSA_BUILTIN_PURE (bmzi_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UQI
),
16685 MSA_BUILTIN_PURE (bsel_v
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UV16QI
),
16686 MSA_BUILTIN_PURE (bseli_b
, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UQI
),
16687 MSA_BUILTIN_PURE (shf_b
, MIPS_V16QI_FTYPE_V16QI_UQI
),
16688 MSA_BUILTIN_PURE (shf_h
, MIPS_V8HI_FTYPE_V8HI_UQI
),
16689 MSA_BUILTIN_PURE (shf_w
, MIPS_V4SI_FTYPE_V4SI_UQI
),
16690 MSA_BUILTIN_TEST_BRANCH (bnz_v
, MIPS_SI_FTYPE_UV16QI
),
16691 MSA_BUILTIN_TEST_BRANCH (bz_v
, MIPS_SI_FTYPE_UV16QI
),
16692 MSA_BUILTIN_PURE (fill_b
, MIPS_V16QI_FTYPE_SI
),
16693 MSA_BUILTIN_PURE (fill_h
, MIPS_V8HI_FTYPE_SI
),
16694 MSA_BUILTIN_PURE (fill_w
, MIPS_V4SI_FTYPE_SI
),
16695 MSA_BUILTIN_PURE (fill_d
, MIPS_V2DI_FTYPE_DI
),
16696 MSA_BUILTIN_PURE (pcnt_b
, MIPS_V16QI_FTYPE_V16QI
),
16697 MSA_BUILTIN_PURE (pcnt_h
, MIPS_V8HI_FTYPE_V8HI
),
16698 MSA_BUILTIN_PURE (pcnt_w
, MIPS_V4SI_FTYPE_V4SI
),
16699 MSA_BUILTIN_PURE (pcnt_d
, MIPS_V2DI_FTYPE_V2DI
),
16700 MSA_BUILTIN_PURE (nloc_b
, MIPS_V16QI_FTYPE_V16QI
),
16701 MSA_BUILTIN_PURE (nloc_h
, MIPS_V8HI_FTYPE_V8HI
),
16702 MSA_BUILTIN_PURE (nloc_w
, MIPS_V4SI_FTYPE_V4SI
),
16703 MSA_BUILTIN_PURE (nloc_d
, MIPS_V2DI_FTYPE_V2DI
),
16704 MSA_BUILTIN_PURE (nlzc_b
, MIPS_V16QI_FTYPE_V16QI
),
16705 MSA_BUILTIN_PURE (nlzc_h
, MIPS_V8HI_FTYPE_V8HI
),
16706 MSA_BUILTIN_PURE (nlzc_w
, MIPS_V4SI_FTYPE_V4SI
),
16707 MSA_BUILTIN_PURE (nlzc_d
, MIPS_V2DI_FTYPE_V2DI
),
16708 MSA_BUILTIN_PURE (copy_s_b
, MIPS_SI_FTYPE_V16QI_UQI
),
16709 MSA_BUILTIN_PURE (copy_s_h
, MIPS_SI_FTYPE_V8HI_UQI
),
16710 MSA_BUILTIN_PURE (copy_s_w
, MIPS_SI_FTYPE_V4SI_UQI
),
16711 MSA_BUILTIN_PURE (copy_s_d
, MIPS_DI_FTYPE_V2DI_UQI
),
16712 MSA_BUILTIN_PURE (copy_u_b
, MIPS_USI_FTYPE_V16QI_UQI
),
16713 MSA_BUILTIN_PURE (copy_u_h
, MIPS_USI_FTYPE_V8HI_UQI
),
16714 MSA_BUILTIN_REMAP (copy_u_w
, copy_s_w
, MIPS_USI_FTYPE_V4SI_UQI
),
16715 MSA_BUILTIN_REMAP (copy_u_d
, copy_s_d
, MIPS_UDI_FTYPE_V2DI_UQI
),
16716 MSA_BUILTIN_PURE (insert_b
, MIPS_V16QI_FTYPE_V16QI_UQI_SI
),
16717 MSA_BUILTIN_PURE (insert_h
, MIPS_V8HI_FTYPE_V8HI_UQI_SI
),
16718 MSA_BUILTIN_PURE (insert_w
, MIPS_V4SI_FTYPE_V4SI_UQI_SI
),
16719 MSA_BUILTIN_PURE (insert_d
, MIPS_V2DI_FTYPE_V2DI_UQI_DI
),
16720 MSA_BUILTIN_PURE (insve_b
, MIPS_V16QI_FTYPE_V16QI_UQI_V16QI
),
16721 MSA_BUILTIN_PURE (insve_h
, MIPS_V8HI_FTYPE_V8HI_UQI_V8HI
),
16722 MSA_BUILTIN_PURE (insve_w
, MIPS_V4SI_FTYPE_V4SI_UQI_V4SI
),
16723 MSA_BUILTIN_PURE (insve_d
, MIPS_V2DI_FTYPE_V2DI_UQI_V2DI
),
16724 MSA_BUILTIN_TEST_BRANCH (bnz_b
, MIPS_SI_FTYPE_UV16QI
),
16725 MSA_BUILTIN_TEST_BRANCH (bnz_h
, MIPS_SI_FTYPE_UV8HI
),
16726 MSA_BUILTIN_TEST_BRANCH (bnz_w
, MIPS_SI_FTYPE_UV4SI
),
16727 MSA_BUILTIN_TEST_BRANCH (bnz_d
, MIPS_SI_FTYPE_UV2DI
),
16728 MSA_BUILTIN_TEST_BRANCH (bz_b
, MIPS_SI_FTYPE_UV16QI
),
16729 MSA_BUILTIN_TEST_BRANCH (bz_h
, MIPS_SI_FTYPE_UV8HI
),
16730 MSA_BUILTIN_TEST_BRANCH (bz_w
, MIPS_SI_FTYPE_UV4SI
),
16731 MSA_BUILTIN_TEST_BRANCH (bz_d
, MIPS_SI_FTYPE_UV2DI
),
16732 MSA_BUILTIN_PURE (ldi_b
, MIPS_V16QI_FTYPE_HI
),
16733 MSA_BUILTIN_PURE (ldi_h
, MIPS_V8HI_FTYPE_HI
),
16734 MSA_BUILTIN_PURE (ldi_w
, MIPS_V4SI_FTYPE_HI
),
16735 MSA_BUILTIN_PURE (ldi_d
, MIPS_V2DI_FTYPE_HI
),
16736 MSA_BUILTIN_PURE (fcaf_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16737 MSA_BUILTIN_PURE (fcaf_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16738 MSA_BUILTIN_PURE (fcor_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16739 MSA_BUILTIN_PURE (fcor_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16740 MSA_BUILTIN_PURE (fcun_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16741 MSA_BUILTIN_PURE (fcun_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16742 MSA_BUILTIN_PURE (fcune_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16743 MSA_BUILTIN_PURE (fcune_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16744 MSA_BUILTIN_PURE (fcueq_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16745 MSA_BUILTIN_PURE (fcueq_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16746 MSA_BUILTIN_PURE (fceq_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16747 MSA_BUILTIN_PURE (fceq_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16748 MSA_BUILTIN_PURE (fcne_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16749 MSA_BUILTIN_PURE (fcne_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16750 MSA_BUILTIN_PURE (fclt_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16751 MSA_BUILTIN_PURE (fclt_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16752 MSA_BUILTIN_PURE (fcult_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16753 MSA_BUILTIN_PURE (fcult_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16754 MSA_BUILTIN_PURE (fcle_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16755 MSA_BUILTIN_PURE (fcle_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16756 MSA_BUILTIN_PURE (fcule_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16757 MSA_BUILTIN_PURE (fcule_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16758 MSA_BUILTIN_PURE (fsaf_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16759 MSA_BUILTIN_PURE (fsaf_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16760 MSA_BUILTIN_PURE (fsor_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16761 MSA_BUILTIN_PURE (fsor_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16762 MSA_BUILTIN_PURE (fsun_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16763 MSA_BUILTIN_PURE (fsun_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16764 MSA_BUILTIN_PURE (fsune_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16765 MSA_BUILTIN_PURE (fsune_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16766 MSA_BUILTIN_PURE (fsueq_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16767 MSA_BUILTIN_PURE (fsueq_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16768 MSA_BUILTIN_PURE (fseq_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16769 MSA_BUILTIN_PURE (fseq_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16770 MSA_BUILTIN_PURE (fsne_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16771 MSA_BUILTIN_PURE (fsne_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16772 MSA_BUILTIN_PURE (fslt_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16773 MSA_BUILTIN_PURE (fslt_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16774 MSA_BUILTIN_PURE (fsult_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16775 MSA_BUILTIN_PURE (fsult_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16776 MSA_BUILTIN_PURE (fsle_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16777 MSA_BUILTIN_PURE (fsle_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16778 MSA_BUILTIN_PURE (fsule_w
, MIPS_V4SI_FTYPE_V4SF_V4SF
),
16779 MSA_BUILTIN_PURE (fsule_d
, MIPS_V2DI_FTYPE_V2DF_V2DF
),
16780 MSA_BUILTIN_PURE (fadd_w
, MIPS_V4SF_FTYPE_V4SF_V4SF
),
16781 MSA_BUILTIN_PURE (fadd_d
, MIPS_V2DF_FTYPE_V2DF_V2DF
),
16782 MSA_BUILTIN_PURE (fsub_w
, MIPS_V4SF_FTYPE_V4SF_V4SF
),
16783 MSA_BUILTIN_PURE (fsub_d
, MIPS_V2DF_FTYPE_V2DF_V2DF
),
16784 MSA_BUILTIN_PURE (fmul_w
, MIPS_V4SF_FTYPE_V4SF_V4SF
),
16785 MSA_BUILTIN_PURE (fmul_d
, MIPS_V2DF_FTYPE_V2DF_V2DF
),
16786 MSA_BUILTIN_PURE (fdiv_w
, MIPS_V4SF_FTYPE_V4SF_V4SF
),
16787 MSA_BUILTIN_PURE (fdiv_d
, MIPS_V2DF_FTYPE_V2DF_V2DF
),
16788 MSA_BUILTIN_PURE (fmadd_w
, MIPS_V4SF_FTYPE_V4SF_V4SF_V4SF
),
16789 MSA_BUILTIN_PURE (fmadd_d
, MIPS_V2DF_FTYPE_V2DF_V2DF_V2DF
),
16790 MSA_BUILTIN_PURE (fmsub_w
, MIPS_V4SF_FTYPE_V4SF_V4SF_V4SF
),
16791 MSA_BUILTIN_PURE (fmsub_d
, MIPS_V2DF_FTYPE_V2DF_V2DF_V2DF
),
16792 MSA_BUILTIN_PURE (fexp2_w
, MIPS_V4SF_FTYPE_V4SF_V4SI
),
16793 MSA_BUILTIN_PURE (fexp2_d
, MIPS_V2DF_FTYPE_V2DF_V2DI
),
16794 MSA_BUILTIN_PURE (fexdo_h
, MIPS_V8HI_FTYPE_V4SF_V4SF
),
16795 MSA_BUILTIN_PURE (fexdo_w
, MIPS_V4SF_FTYPE_V2DF_V2DF
),
16796 MSA_BUILTIN_PURE (ftq_h
, MIPS_V8HI_FTYPE_V4SF_V4SF
),
16797 MSA_BUILTIN_PURE (ftq_w
, MIPS_V4SI_FTYPE_V2DF_V2DF
),
16798 MSA_BUILTIN_PURE (fmin_w
, MIPS_V4SF_FTYPE_V4SF_V4SF
),
16799 MSA_BUILTIN_PURE (fmin_d
, MIPS_V2DF_FTYPE_V2DF_V2DF
),
16800 MSA_BUILTIN_PURE (fmin_a_w
, MIPS_V4SF_FTYPE_V4SF_V4SF
),
16801 MSA_BUILTIN_PURE (fmin_a_d
, MIPS_V2DF_FTYPE_V2DF_V2DF
),
16802 MSA_BUILTIN_PURE (fmax_w
, MIPS_V4SF_FTYPE_V4SF_V4SF
),
16803 MSA_BUILTIN_PURE (fmax_d
, MIPS_V2DF_FTYPE_V2DF_V2DF
),
16804 MSA_BUILTIN_PURE (fmax_a_w
, MIPS_V4SF_FTYPE_V4SF_V4SF
),
16805 MSA_BUILTIN_PURE (fmax_a_d
, MIPS_V2DF_FTYPE_V2DF_V2DF
),
16806 MSA_BUILTIN_PURE (mul_q_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16807 MSA_BUILTIN_PURE (mul_q_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16808 MSA_BUILTIN_PURE (mulr_q_h
, MIPS_V8HI_FTYPE_V8HI_V8HI
),
16809 MSA_BUILTIN_PURE (mulr_q_w
, MIPS_V4SI_FTYPE_V4SI_V4SI
),
16810 MSA_BUILTIN_PURE (madd_q_h
, MIPS_V8HI_FTYPE_V8HI_V8HI_V8HI
),
16811 MSA_BUILTIN_PURE (madd_q_w
, MIPS_V4SI_FTYPE_V4SI_V4SI_V4SI
),
16812 MSA_BUILTIN_PURE (maddr_q_h
, MIPS_V8HI_FTYPE_V8HI_V8HI_V8HI
),
16813 MSA_BUILTIN_PURE (maddr_q_w
, MIPS_V4SI_FTYPE_V4SI_V4SI_V4SI
),
16814 MSA_BUILTIN_PURE (msub_q_h
, MIPS_V8HI_FTYPE_V8HI_V8HI_V8HI
),
16815 MSA_BUILTIN_PURE (msub_q_w
, MIPS_V4SI_FTYPE_V4SI_V4SI_V4SI
),
16816 MSA_BUILTIN_PURE (msubr_q_h
, MIPS_V8HI_FTYPE_V8HI_V8HI_V8HI
),
16817 MSA_BUILTIN_PURE (msubr_q_w
, MIPS_V4SI_FTYPE_V4SI_V4SI_V4SI
),
16818 MSA_BUILTIN_PURE (fclass_w
, MIPS_V4SI_FTYPE_V4SF
),
16819 MSA_BUILTIN_PURE (fclass_d
, MIPS_V2DI_FTYPE_V2DF
),
16820 MSA_BUILTIN_PURE (fsqrt_w
, MIPS_V4SF_FTYPE_V4SF
),
16821 MSA_BUILTIN_PURE (fsqrt_d
, MIPS_V2DF_FTYPE_V2DF
),
16822 MSA_BUILTIN_PURE (frcp_w
, MIPS_V4SF_FTYPE_V4SF
),
16823 MSA_BUILTIN_PURE (frcp_d
, MIPS_V2DF_FTYPE_V2DF
),
16824 MSA_BUILTIN_PURE (frint_w
, MIPS_V4SF_FTYPE_V4SF
),
16825 MSA_BUILTIN_PURE (frint_d
, MIPS_V2DF_FTYPE_V2DF
),
16826 MSA_BUILTIN_PURE (frsqrt_w
, MIPS_V4SF_FTYPE_V4SF
),
16827 MSA_BUILTIN_PURE (frsqrt_d
, MIPS_V2DF_FTYPE_V2DF
),
16828 MSA_BUILTIN_PURE (flog2_w
, MIPS_V4SF_FTYPE_V4SF
),
16829 MSA_BUILTIN_PURE (flog2_d
, MIPS_V2DF_FTYPE_V2DF
),
16830 MSA_BUILTIN_PURE (fexupl_w
, MIPS_V4SF_FTYPE_V8HI
),
16831 MSA_BUILTIN_PURE (fexupl_d
, MIPS_V2DF_FTYPE_V4SF
),
16832 MSA_BUILTIN_PURE (fexupr_w
, MIPS_V4SF_FTYPE_V8HI
),
16833 MSA_BUILTIN_PURE (fexupr_d
, MIPS_V2DF_FTYPE_V4SF
),
16834 MSA_BUILTIN_PURE (ffql_w
, MIPS_V4SF_FTYPE_V8HI
),
16835 MSA_BUILTIN_PURE (ffql_d
, MIPS_V2DF_FTYPE_V4SI
),
16836 MSA_BUILTIN_PURE (ffqr_w
, MIPS_V4SF_FTYPE_V8HI
),
16837 MSA_BUILTIN_PURE (ffqr_d
, MIPS_V2DF_FTYPE_V4SI
),
16838 MSA_BUILTIN_PURE (ftint_s_w
, MIPS_V4SI_FTYPE_V4SF
),
16839 MSA_BUILTIN_PURE (ftint_s_d
, MIPS_V2DI_FTYPE_V2DF
),
16840 MSA_BUILTIN_PURE (ftint_u_w
, MIPS_UV4SI_FTYPE_V4SF
),
16841 MSA_BUILTIN_PURE (ftint_u_d
, MIPS_UV2DI_FTYPE_V2DF
),
16842 MSA_BUILTIN_PURE (ftrunc_s_w
, MIPS_V4SI_FTYPE_V4SF
),
16843 MSA_BUILTIN_PURE (ftrunc_s_d
, MIPS_V2DI_FTYPE_V2DF
),
16844 MSA_BUILTIN_PURE (ftrunc_u_w
, MIPS_UV4SI_FTYPE_V4SF
),
16845 MSA_BUILTIN_PURE (ftrunc_u_d
, MIPS_UV2DI_FTYPE_V2DF
),
16846 MSA_BUILTIN_PURE (ffint_s_w
, MIPS_V4SF_FTYPE_V4SI
),
16847 MSA_BUILTIN_PURE (ffint_s_d
, MIPS_V2DF_FTYPE_V2DI
),
16848 MSA_BUILTIN_PURE (ffint_u_w
, MIPS_V4SF_FTYPE_UV4SI
),
16849 MSA_BUILTIN_PURE (ffint_u_d
, MIPS_V2DF_FTYPE_UV2DI
),
16850 MSA_NO_TARGET_BUILTIN (ctcmsa
, MIPS_VOID_FTYPE_UQI_SI
),
16851 MSA_BUILTIN_PURE (cfcmsa
, MIPS_SI_FTYPE_UQI
),
16852 MSA_BUILTIN_PURE (move_v
, MIPS_V16QI_FTYPE_V16QI
),
16855 /* Index I is the function declaration for mips_builtins[I], or null if the
16856 function isn't defined on this target. */
16857 static GTY(()) tree mips_builtin_decls
[ARRAY_SIZE (mips_builtins
)];
16858 /* Get the index I of the function declaration for mips_builtin_decls[I]
16859 using the instruction code or return null if not defined for the target. */
16860 static GTY(()) int mips_get_builtin_decl_index
[NUM_INSN_CODES
];
16862 /* MODE is a vector mode whose elements have type TYPE. Return the type
16863 of the vector itself. */
16866 mips_builtin_vector_type (tree type
, machine_mode mode
)
16868 static tree types
[2 * (int) MAX_MACHINE_MODE
];
16871 mode_index
= (int) mode
;
16873 if (TREE_CODE (type
) == INTEGER_TYPE
&& TYPE_UNSIGNED (type
))
16874 mode_index
+= MAX_MACHINE_MODE
;
16876 if (types
[mode_index
] == NULL_TREE
)
16877 types
[mode_index
] = build_vector_type_for_mode (type
, mode
);
16878 return types
[mode_index
];
16881 /* Return a type for 'const volatile void *'. */
16884 mips_build_cvpointer_type (void)
16888 if (cache
== NULL_TREE
)
16889 cache
= build_pointer_type (build_qualified_type
16891 TYPE_QUAL_CONST
| TYPE_QUAL_VOLATILE
));
16895 /* Source-level argument types. */
16896 #define MIPS_ATYPE_VOID void_type_node
16897 #define MIPS_ATYPE_INT integer_type_node
16898 #define MIPS_ATYPE_POINTER ptr_type_node
16899 #define MIPS_ATYPE_CVPOINTER mips_build_cvpointer_type ()
16901 /* Standard mode-based argument types. */
16902 #define MIPS_ATYPE_QI intQI_type_node
16903 #define MIPS_ATYPE_UQI unsigned_intQI_type_node
16904 #define MIPS_ATYPE_HI intHI_type_node
16905 #define MIPS_ATYPE_SI intSI_type_node
16906 #define MIPS_ATYPE_USI unsigned_intSI_type_node
16907 #define MIPS_ATYPE_DI intDI_type_node
16908 #define MIPS_ATYPE_UDI unsigned_intDI_type_node
16909 #define MIPS_ATYPE_SF float_type_node
16910 #define MIPS_ATYPE_DF double_type_node
16912 /* Vector argument types. */
16913 #define MIPS_ATYPE_V2SF mips_builtin_vector_type (float_type_node, V2SFmode)
16914 #define MIPS_ATYPE_V2HI mips_builtin_vector_type (intHI_type_node, V2HImode)
16915 #define MIPS_ATYPE_V2SI mips_builtin_vector_type (intSI_type_node, V2SImode)
16916 #define MIPS_ATYPE_V4QI mips_builtin_vector_type (intQI_type_node, V4QImode)
16917 #define MIPS_ATYPE_V4HI mips_builtin_vector_type (intHI_type_node, V4HImode)
16918 #define MIPS_ATYPE_V8QI mips_builtin_vector_type (intQI_type_node, V8QImode)
16920 #define MIPS_ATYPE_V2DI \
16921 mips_builtin_vector_type (long_long_integer_type_node, V2DImode)
16922 #define MIPS_ATYPE_V4SI mips_builtin_vector_type (intSI_type_node, V4SImode)
16923 #define MIPS_ATYPE_V8HI mips_builtin_vector_type (intHI_type_node, V8HImode)
16924 #define MIPS_ATYPE_V16QI mips_builtin_vector_type (intQI_type_node, V16QImode)
16925 #define MIPS_ATYPE_V2DF mips_builtin_vector_type (double_type_node, V2DFmode)
16926 #define MIPS_ATYPE_V4SF mips_builtin_vector_type (float_type_node, V4SFmode)
16928 #define MIPS_ATYPE_UV2DI \
16929 mips_builtin_vector_type (long_long_unsigned_type_node, V2DImode)
16930 #define MIPS_ATYPE_UV4SI \
16931 mips_builtin_vector_type (unsigned_intSI_type_node, V4SImode)
16932 #define MIPS_ATYPE_UV8HI \
16933 mips_builtin_vector_type (unsigned_intHI_type_node, V8HImode)
16934 #define MIPS_ATYPE_UV16QI \
16935 mips_builtin_vector_type (unsigned_intQI_type_node, V16QImode)
16937 #define MIPS_ATYPE_UV2SI \
16938 mips_builtin_vector_type (unsigned_intSI_type_node, V2SImode)
16939 #define MIPS_ATYPE_UV4HI \
16940 mips_builtin_vector_type (unsigned_intHI_type_node, V4HImode)
16941 #define MIPS_ATYPE_UV8QI \
16942 mips_builtin_vector_type (unsigned_intQI_type_node, V8QImode)
16944 /* MIPS_FTYPE_ATYPESN takes N MIPS_FTYPES-like type codes and lists
16945 their associated MIPS_ATYPEs. */
16946 #define MIPS_FTYPE_ATYPES1(A, B) \
16947 MIPS_ATYPE_##A, MIPS_ATYPE_##B
16949 #define MIPS_FTYPE_ATYPES2(A, B, C) \
16950 MIPS_ATYPE_##A, MIPS_ATYPE_##B, MIPS_ATYPE_##C
16952 #define MIPS_FTYPE_ATYPES3(A, B, C, D) \
16953 MIPS_ATYPE_##A, MIPS_ATYPE_##B, MIPS_ATYPE_##C, MIPS_ATYPE_##D
16955 #define MIPS_FTYPE_ATYPES4(A, B, C, D, E) \
16956 MIPS_ATYPE_##A, MIPS_ATYPE_##B, MIPS_ATYPE_##C, MIPS_ATYPE_##D, \
16959 /* Return the function type associated with function prototype TYPE. */
16962 mips_build_function_type (enum mips_function_type type
)
16964 static tree types
[(int) MIPS_MAX_FTYPE_MAX
];
16966 if (types
[(int) type
] == NULL_TREE
)
16969 #define DEF_MIPS_FTYPE(NUM, ARGS) \
16970 case MIPS_FTYPE_NAME##NUM ARGS: \
16971 types[(int) type] \
16972 = build_function_type_list (MIPS_FTYPE_ATYPES##NUM ARGS, \
16975 #include "config/mips/mips-ftypes.def"
16976 #undef DEF_MIPS_FTYPE
16978 gcc_unreachable ();
16981 return types
[(int) type
];
16984 /* Implement TARGET_INIT_BUILTINS. */
16987 mips_init_builtins (void)
16989 const struct mips_builtin_description
*d
;
16992 /* Iterate through all of the bdesc arrays, initializing all of the
16993 builtin functions. */
16994 for (i
= 0; i
< ARRAY_SIZE (mips_builtins
); i
++)
16996 d
= &mips_builtins
[i
];
16999 mips_builtin_decls
[i
]
17000 = add_builtin_function (d
->name
,
17001 mips_build_function_type (d
->function_type
),
17002 i
, BUILT_IN_MD
, NULL
, NULL
);
17003 if (mips_builtin_decls
[i
] && d
->is_pure
)
17004 DECL_PURE_P (mips_builtin_decls
[i
]) = 1;
17005 mips_get_builtin_decl_index
[d
->icode
] = i
;
17010 /* Implement TARGET_BUILTIN_DECL. */
17013 mips_builtin_decl (unsigned int code
, bool initialize_p ATTRIBUTE_UNUSED
)
17015 if (code
>= ARRAY_SIZE (mips_builtins
))
17016 return error_mark_node
;
17017 return mips_builtin_decls
[code
];
17020 /* Implement TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION. */
17023 mips_builtin_vectorized_function (unsigned int fn
, tree type_out
, tree type_in
)
17025 machine_mode in_mode
, out_mode
;
17028 if (TREE_CODE (type_out
) != VECTOR_TYPE
17029 || TREE_CODE (type_in
) != VECTOR_TYPE
17033 out_mode
= TYPE_MODE (TREE_TYPE (type_out
));
17034 out_n
= TYPE_VECTOR_SUBPARTS (type_out
);
17035 in_mode
= TYPE_MODE (TREE_TYPE (type_in
));
17036 in_n
= TYPE_VECTOR_SUBPARTS (type_in
);
17038 /* INSN is the name of the associated instruction pattern, without
17039 the leading CODE_FOR_. */
17040 #define MIPS_GET_BUILTIN(INSN) \
17041 mips_builtin_decls[mips_get_builtin_decl_index[CODE_FOR_##INSN]]
17045 case BUILT_IN_SQRT
:
17046 if (out_mode
== DFmode
&& out_n
== 2
17047 && in_mode
== DFmode
&& in_n
== 2)
17048 return MIPS_GET_BUILTIN (msa_fsqrt_d
);
17050 case BUILT_IN_SQRTF
:
17051 if (out_mode
== SFmode
&& out_n
== 4
17052 && in_mode
== SFmode
&& in_n
== 4)
17053 return MIPS_GET_BUILTIN (msa_fsqrt_w
);
17062 /* Take argument ARGNO from EXP's argument list and convert it into
17063 an expand operand. Store the operand in *OP. */
17066 mips_prepare_builtin_arg (struct expand_operand
*op
, tree exp
,
17067 unsigned int argno
)
17072 arg
= CALL_EXPR_ARG (exp
, argno
);
17073 value
= expand_normal (arg
);
17074 create_input_operand (op
, value
, TYPE_MODE (TREE_TYPE (arg
)));
17077 /* Expand instruction ICODE as part of a built-in function sequence.
17078 Use the first NOPS elements of OPS as the instruction's operands.
17079 HAS_TARGET_P is true if operand 0 is a target; it is false if the
17080 instruction has no target.
17082 Return the target rtx if HAS_TARGET_P, otherwise return const0_rtx. */
17085 mips_expand_builtin_insn (enum insn_code icode
, unsigned int nops
,
17086 struct expand_operand
*ops
, bool has_target_p
)
17088 machine_mode imode
;
17089 int rangelo
= 0, rangehi
= 0, error_opno
= 0;
17094 /* The third operand of these instructions is in SImode, so we need to
17095 bring the corresponding builtin argument from QImode into SImode. */
17096 case CODE_FOR_loongson_pshufh
:
17097 case CODE_FOR_loongson_psllh
:
17098 case CODE_FOR_loongson_psllw
:
17099 case CODE_FOR_loongson_psrah
:
17100 case CODE_FOR_loongson_psraw
:
17101 case CODE_FOR_loongson_psrlh
:
17102 case CODE_FOR_loongson_psrlw
:
17103 gcc_assert (has_target_p
&& nops
== 3 && ops
[2].mode
== QImode
);
17104 sireg
= gen_reg_rtx (SImode
);
17105 emit_insn (gen_zero_extendqisi2 (sireg
,
17106 force_reg (QImode
, ops
[2].value
)));
17107 ops
[2].value
= sireg
;
17108 ops
[2].mode
= SImode
;
17111 case CODE_FOR_msa_addvi_b
:
17112 case CODE_FOR_msa_addvi_h
:
17113 case CODE_FOR_msa_addvi_w
:
17114 case CODE_FOR_msa_addvi_d
:
17115 case CODE_FOR_msa_clti_u_b
:
17116 case CODE_FOR_msa_clti_u_h
:
17117 case CODE_FOR_msa_clti_u_w
:
17118 case CODE_FOR_msa_clti_u_d
:
17119 case CODE_FOR_msa_clei_u_b
:
17120 case CODE_FOR_msa_clei_u_h
:
17121 case CODE_FOR_msa_clei_u_w
:
17122 case CODE_FOR_msa_clei_u_d
:
17123 case CODE_FOR_msa_maxi_u_b
:
17124 case CODE_FOR_msa_maxi_u_h
:
17125 case CODE_FOR_msa_maxi_u_w
:
17126 case CODE_FOR_msa_maxi_u_d
:
17127 case CODE_FOR_msa_mini_u_b
:
17128 case CODE_FOR_msa_mini_u_h
:
17129 case CODE_FOR_msa_mini_u_w
:
17130 case CODE_FOR_msa_mini_u_d
:
17131 case CODE_FOR_msa_subvi_b
:
17132 case CODE_FOR_msa_subvi_h
:
17133 case CODE_FOR_msa_subvi_w
:
17134 case CODE_FOR_msa_subvi_d
:
17135 gcc_assert (has_target_p
&& nops
== 3);
17136 /* We only generate a vector of constants iff the second argument
17137 is an immediate. We also validate the range of the immediate. */
17138 if (CONST_INT_P (ops
[2].value
))
17142 if (IN_RANGE (INTVAL (ops
[2].value
), rangelo
, rangehi
))
17144 ops
[2].mode
= ops
[0].mode
;
17145 ops
[2].value
= mips_gen_const_int_vector (ops
[2].mode
,
17146 INTVAL (ops
[2].value
));
17153 case CODE_FOR_msa_ceqi_b
:
17154 case CODE_FOR_msa_ceqi_h
:
17155 case CODE_FOR_msa_ceqi_w
:
17156 case CODE_FOR_msa_ceqi_d
:
17157 case CODE_FOR_msa_clti_s_b
:
17158 case CODE_FOR_msa_clti_s_h
:
17159 case CODE_FOR_msa_clti_s_w
:
17160 case CODE_FOR_msa_clti_s_d
:
17161 case CODE_FOR_msa_clei_s_b
:
17162 case CODE_FOR_msa_clei_s_h
:
17163 case CODE_FOR_msa_clei_s_w
:
17164 case CODE_FOR_msa_clei_s_d
:
17165 case CODE_FOR_msa_maxi_s_b
:
17166 case CODE_FOR_msa_maxi_s_h
:
17167 case CODE_FOR_msa_maxi_s_w
:
17168 case CODE_FOR_msa_maxi_s_d
:
17169 case CODE_FOR_msa_mini_s_b
:
17170 case CODE_FOR_msa_mini_s_h
:
17171 case CODE_FOR_msa_mini_s_w
:
17172 case CODE_FOR_msa_mini_s_d
:
17173 gcc_assert (has_target_p
&& nops
== 3);
17174 /* We only generate a vector of constants iff the second argument
17175 is an immediate. We also validate the range of the immediate. */
17176 if (CONST_INT_P (ops
[2].value
))
17180 if (IN_RANGE (INTVAL (ops
[2].value
), rangelo
, rangehi
))
17182 ops
[2].mode
= ops
[0].mode
;
17183 ops
[2].value
= mips_gen_const_int_vector (ops
[2].mode
,
17184 INTVAL (ops
[2].value
));
17191 case CODE_FOR_msa_andi_b
:
17192 case CODE_FOR_msa_ori_b
:
17193 case CODE_FOR_msa_nori_b
:
17194 case CODE_FOR_msa_xori_b
:
17195 gcc_assert (has_target_p
&& nops
== 3);
17196 if (!CONST_INT_P (ops
[2].value
))
17198 ops
[2].mode
= ops
[0].mode
;
17199 ops
[2].value
= mips_gen_const_int_vector (ops
[2].mode
,
17200 INTVAL (ops
[2].value
));
17203 case CODE_FOR_msa_bmzi_b
:
17204 case CODE_FOR_msa_bmnzi_b
:
17205 case CODE_FOR_msa_bseli_b
:
17206 gcc_assert (has_target_p
&& nops
== 4);
17207 if (!CONST_INT_P (ops
[3].value
))
17209 ops
[3].mode
= ops
[0].mode
;
17210 ops
[3].value
= mips_gen_const_int_vector (ops
[3].mode
,
17211 INTVAL (ops
[3].value
));
17214 case CODE_FOR_msa_fill_b
:
17215 case CODE_FOR_msa_fill_h
:
17216 case CODE_FOR_msa_fill_w
:
17217 case CODE_FOR_msa_fill_d
:
17218 /* Map the built-ins to vector fill operations. We need fix up the mode
17219 for the element being inserted. */
17220 gcc_assert (has_target_p
&& nops
== 2);
17221 imode
= GET_MODE_INNER (ops
[0].mode
);
17222 ops
[1].value
= lowpart_subreg (imode
, ops
[1].value
, ops
[1].mode
);
17223 ops
[1].mode
= imode
;
17226 case CODE_FOR_msa_ilvl_b
:
17227 case CODE_FOR_msa_ilvl_h
:
17228 case CODE_FOR_msa_ilvl_w
:
17229 case CODE_FOR_msa_ilvl_d
:
17230 case CODE_FOR_msa_ilvr_b
:
17231 case CODE_FOR_msa_ilvr_h
:
17232 case CODE_FOR_msa_ilvr_w
:
17233 case CODE_FOR_msa_ilvr_d
:
17234 case CODE_FOR_msa_ilvev_b
:
17235 case CODE_FOR_msa_ilvev_h
:
17236 case CODE_FOR_msa_ilvev_w
:
17237 case CODE_FOR_msa_ilvod_b
:
17238 case CODE_FOR_msa_ilvod_h
:
17239 case CODE_FOR_msa_ilvod_w
:
17240 case CODE_FOR_msa_pckev_b
:
17241 case CODE_FOR_msa_pckev_h
:
17242 case CODE_FOR_msa_pckev_w
:
17243 case CODE_FOR_msa_pckod_b
:
17244 case CODE_FOR_msa_pckod_h
:
17245 case CODE_FOR_msa_pckod_w
:
17246 /* Swap the operands 1 and 2 for interleave operations. Built-ins follow
17247 convention of ISA, which have op1 as higher component and op2 as lower
17248 component. However, the VEC_PERM op in tree and vec_concat in RTL
17249 expects first operand to be lower component, because of which this
17250 swap is needed for builtins. */
17251 gcc_assert (has_target_p
&& nops
== 3);
17252 std::swap (ops
[1], ops
[2]);
17255 case CODE_FOR_msa_maddv_b
:
17256 case CODE_FOR_msa_maddv_h
:
17257 case CODE_FOR_msa_maddv_w
:
17258 case CODE_FOR_msa_maddv_d
:
17259 case CODE_FOR_msa_fmadd_w
:
17260 case CODE_FOR_msa_fmadd_d
:
17261 case CODE_FOR_msa_fmsub_w
:
17262 case CODE_FOR_msa_fmsub_d
:
17263 /* fma(a, b, c) results into (a * b + c), however builtin_msa_fmadd expects
17264 it to be (a + b * c). Swap the 1st and 3rd operands. */
17265 std::swap (ops
[1], ops
[3]);
17268 case CODE_FOR_msa_slli_b
:
17269 case CODE_FOR_msa_slli_h
:
17270 case CODE_FOR_msa_slli_w
:
17271 case CODE_FOR_msa_slli_d
:
17272 case CODE_FOR_msa_srai_b
:
17273 case CODE_FOR_msa_srai_h
:
17274 case CODE_FOR_msa_srai_w
:
17275 case CODE_FOR_msa_srai_d
:
17276 case CODE_FOR_msa_srli_b
:
17277 case CODE_FOR_msa_srli_h
:
17278 case CODE_FOR_msa_srli_w
:
17279 case CODE_FOR_msa_srli_d
:
17280 gcc_assert (has_target_p
&& nops
== 3);
17281 if (CONST_INT_P (ops
[2].value
))
17284 rangehi
= GET_MODE_UNIT_BITSIZE (ops
[0].mode
) - 1;
17285 if (IN_RANGE (INTVAL (ops
[2].value
), rangelo
, rangehi
))
17287 ops
[2].mode
= ops
[0].mode
;
17288 ops
[2].value
= mips_gen_const_int_vector (ops
[2].mode
,
17289 INTVAL (ops
[2].value
));
17296 case CODE_FOR_msa_insert_b
:
17297 case CODE_FOR_msa_insert_h
:
17298 case CODE_FOR_msa_insert_w
:
17299 case CODE_FOR_msa_insert_d
:
17300 /* Map the built-ins to insert operations. We need to swap operands,
17301 fix up the mode for the element being inserted, and generate
17302 a bit mask for vec_merge. */
17303 gcc_assert (has_target_p
&& nops
== 4);
17304 std::swap (ops
[1], ops
[2]);
17305 std::swap (ops
[1], ops
[3]);
17306 imode
= GET_MODE_INNER (ops
[0].mode
);
17307 ops
[1].value
= lowpart_subreg (imode
, ops
[1].value
, ops
[1].mode
);
17308 ops
[1].mode
= imode
;
17310 rangehi
= GET_MODE_NUNITS (ops
[0].mode
) - 1;
17311 if (CONST_INT_P (ops
[3].value
)
17312 && IN_RANGE (INTVAL (ops
[3].value
), rangelo
, rangehi
))
17313 ops
[3].value
= GEN_INT (1 << INTVAL (ops
[3].value
));
17318 case CODE_FOR_msa_insve_b
:
17319 case CODE_FOR_msa_insve_h
:
17320 case CODE_FOR_msa_insve_w
:
17321 case CODE_FOR_msa_insve_d
:
17322 /* Map the built-ins to element insert operations. We need to swap
17323 operands and generate a bit mask. */
17324 gcc_assert (has_target_p
&& nops
== 4);
17325 std::swap (ops
[1], ops
[2]);
17326 std::swap (ops
[1], ops
[3]);
17328 rangehi
= GET_MODE_NUNITS (ops
[0].mode
) - 1;
17329 if (CONST_INT_P (ops
[3].value
)
17330 && IN_RANGE (INTVAL (ops
[3].value
), rangelo
, rangehi
))
17331 ops
[3].value
= GEN_INT (1 << INTVAL (ops
[3].value
));
17336 case CODE_FOR_msa_shf_b
:
17337 case CODE_FOR_msa_shf_h
:
17338 case CODE_FOR_msa_shf_w
:
17339 case CODE_FOR_msa_shf_w_f
:
17340 gcc_assert (has_target_p
&& nops
== 3);
17341 ops
[2].value
= mips_gen_const_int_vector_shuffle (ops
[0].mode
,
17342 INTVAL (ops
[2].value
));
17345 case CODE_FOR_msa_vshf_b
:
17346 case CODE_FOR_msa_vshf_h
:
17347 case CODE_FOR_msa_vshf_w
:
17348 case CODE_FOR_msa_vshf_d
:
17349 gcc_assert (has_target_p
&& nops
== 4);
17350 std::swap (ops
[1], ops
[3]);
17353 case CODE_FOR_msa_dpadd_s_w
:
17354 case CODE_FOR_msa_dpadd_s_h
:
17355 case CODE_FOR_msa_dpadd_s_d
:
17356 case CODE_FOR_msa_dpadd_u_w
:
17357 case CODE_FOR_msa_dpadd_u_h
:
17358 case CODE_FOR_msa_dpadd_u_d
:
17359 case CODE_FOR_msa_dpsub_s_w
:
17360 case CODE_FOR_msa_dpsub_s_h
:
17361 case CODE_FOR_msa_dpsub_s_d
:
17362 case CODE_FOR_msa_dpsub_u_w
:
17363 case CODE_FOR_msa_dpsub_u_h
:
17364 case CODE_FOR_msa_dpsub_u_d
:
17365 /* Force the operands which correspond to the same in-out register
17366 to have the same pseudo assigned to them. If the input operand
17367 is not REG, create one for it. */
17368 if (!REG_P (ops
[1].value
))
17369 ops
[1].value
= copy_to_mode_reg (ops
[1].mode
, ops
[1].value
);
17370 create_output_operand (&ops
[0], ops
[1].value
, ops
[1].mode
);
17377 if (error_opno
!= 0)
17379 error ("argument %d to the built-in must be a constant"
17380 " in range %d to %d", error_opno
, rangelo
, rangehi
);
17381 return has_target_p
? gen_reg_rtx (ops
[0].mode
) : const0_rtx
;
17383 else if (!maybe_expand_insn (icode
, nops
, ops
))
17385 error ("invalid argument to built-in function");
17386 return has_target_p
? gen_reg_rtx (ops
[0].mode
) : const0_rtx
;
17388 return has_target_p
? ops
[0].value
: const0_rtx
;
17391 /* Expand a floating-point comparison for built-in function call EXP.
17392 The first NARGS arguments are the values to be compared. ICODE is
17393 the .md pattern that does the comparison and COND is the condition
17394 that is being tested. Return an rtx for the result. */
17397 mips_expand_builtin_compare_1 (enum insn_code icode
,
17398 enum mips_fp_condition cond
,
17399 tree exp
, int nargs
)
17401 struct expand_operand ops
[MAX_RECOG_OPERANDS
];
17405 /* The instruction should have a target operand, an operand for each
17406 argument, and an operand for COND. */
17407 gcc_assert (nargs
+ 2 == insn_data
[(int) icode
].n_generator_args
);
17409 output
= mips_allocate_fcc (insn_data
[(int) icode
].operand
[0].mode
);
17411 create_fixed_operand (&ops
[opno
++], output
);
17412 for (argno
= 0; argno
< nargs
; argno
++)
17413 mips_prepare_builtin_arg (&ops
[opno
++], exp
, argno
);
17414 create_integer_operand (&ops
[opno
++], (int) cond
);
17415 return mips_expand_builtin_insn (icode
, opno
, ops
, true);
17418 /* Expand a MIPS_BUILTIN_DIRECT or MIPS_BUILTIN_DIRECT_NO_TARGET function;
17419 HAS_TARGET_P says which. EXP is the CALL_EXPR that calls the function
17420 and ICODE is the code of the associated .md pattern. TARGET, if nonnull,
17421 suggests a good place to put the result. */
17424 mips_expand_builtin_direct (enum insn_code icode
, rtx target
, tree exp
,
17427 struct expand_operand ops
[MAX_RECOG_OPERANDS
];
17430 /* Map any target to operand 0. */
17433 create_output_operand (&ops
[opno
++], target
, TYPE_MODE (TREE_TYPE (exp
)));
17435 /* Map the arguments to the other operands. */
17436 gcc_assert (opno
+ call_expr_nargs (exp
)
17437 == insn_data
[icode
].n_generator_args
);
17438 for (argno
= 0; argno
< call_expr_nargs (exp
); argno
++)
17439 mips_prepare_builtin_arg (&ops
[opno
++], exp
, argno
);
17441 return mips_expand_builtin_insn (icode
, opno
, ops
, has_target_p
);
17444 /* Expand a __builtin_mips_movt_*_ps or __builtin_mips_movf_*_ps
17445 function; TYPE says which. EXP is the CALL_EXPR that calls the
17446 function, ICODE is the instruction that should be used to compare
17447 the first two arguments, and COND is the condition it should test.
17448 TARGET, if nonnull, suggests a good place to put the result. */
17451 mips_expand_builtin_movtf (enum mips_builtin_type type
,
17452 enum insn_code icode
, enum mips_fp_condition cond
,
17453 rtx target
, tree exp
)
17455 struct expand_operand ops
[4];
17458 cmp_result
= mips_expand_builtin_compare_1 (icode
, cond
, exp
, 2);
17459 create_output_operand (&ops
[0], target
, TYPE_MODE (TREE_TYPE (exp
)));
17460 if (type
== MIPS_BUILTIN_MOVT
)
17462 mips_prepare_builtin_arg (&ops
[2], exp
, 2);
17463 mips_prepare_builtin_arg (&ops
[1], exp
, 3);
17467 mips_prepare_builtin_arg (&ops
[1], exp
, 2);
17468 mips_prepare_builtin_arg (&ops
[2], exp
, 3);
17470 create_fixed_operand (&ops
[3], cmp_result
);
17471 return mips_expand_builtin_insn (CODE_FOR_mips_cond_move_tf_ps
,
17475 /* Expand an MSA built-in for a compare and branch instruction specified by
17476 ICODE, set a general-purpose register to 1 if the branch was taken,
17480 mips_expand_builtin_msa_test_branch (enum insn_code icode
, tree exp
)
17482 struct expand_operand ops
[3];
17484 rtx_code_label
*true_label
, *done_label
;
17487 true_label
= gen_label_rtx ();
17488 done_label
= gen_label_rtx ();
17490 create_input_operand (&ops
[0], true_label
, TYPE_MODE (TREE_TYPE (exp
)));
17491 mips_prepare_builtin_arg (&ops
[1], exp
, 0);
17492 create_fixed_operand (&ops
[2], const0_rtx
);
17494 /* Make sure that the operand 1 is a REG. */
17495 if (GET_CODE (ops
[1].value
) != REG
)
17496 ops
[1].value
= force_reg (ops
[1].mode
, ops
[1].value
);
17498 if ((cbranch
= maybe_gen_insn (icode
, 3, ops
)) == NULL_RTX
)
17499 error ("failed to expand built-in function");
17501 cmp_result
= gen_reg_rtx (SImode
);
17503 /* First assume that CMP_RESULT is false. */
17504 mips_emit_move (cmp_result
, const0_rtx
);
17506 /* Branch to TRUE_LABEL if CBRANCH is taken and DONE_LABEL otherwise. */
17507 emit_jump_insn (cbranch
);
17508 emit_jump_insn (gen_jump (done_label
));
17511 /* Set CMP_RESULT to true if the branch was taken. */
17512 emit_label (true_label
);
17513 mips_emit_move (cmp_result
, const1_rtx
);
17515 emit_label (done_label
);
17519 /* Move VALUE_IF_TRUE into TARGET if CONDITION is true; move VALUE_IF_FALSE
17520 into TARGET otherwise. Return TARGET. */
17523 mips_builtin_branch_and_move (rtx condition
, rtx target
,
17524 rtx value_if_true
, rtx value_if_false
)
17526 rtx_code_label
*true_label
, *done_label
;
17528 true_label
= gen_label_rtx ();
17529 done_label
= gen_label_rtx ();
17531 /* First assume that CONDITION is false. */
17532 mips_emit_move (target
, value_if_false
);
17534 /* Branch to TRUE_LABEL if CONDITION is true and DONE_LABEL otherwise. */
17535 emit_jump_insn (gen_condjump (condition
, true_label
));
17536 emit_jump_insn (gen_jump (done_label
));
17539 /* Fix TARGET if CONDITION is true. */
17540 emit_label (true_label
);
17541 mips_emit_move (target
, value_if_true
);
17543 emit_label (done_label
);
17547 /* Expand a comparison built-in function of type BUILTIN_TYPE. EXP is
17548 the CALL_EXPR that calls the function, ICODE is the code of the
17549 comparison instruction, and COND is the condition it should test.
17550 TARGET, if nonnull, suggests a good place to put the boolean result. */
17553 mips_expand_builtin_compare (enum mips_builtin_type builtin_type
,
17554 enum insn_code icode
, enum mips_fp_condition cond
,
17555 rtx target
, tree exp
)
17557 rtx offset
, condition
, cmp_result
;
17559 if (target
== 0 || GET_MODE (target
) != SImode
)
17560 target
= gen_reg_rtx (SImode
);
17561 cmp_result
= mips_expand_builtin_compare_1 (icode
, cond
, exp
,
17562 call_expr_nargs (exp
));
17564 /* If the comparison sets more than one register, we define the result
17565 to be 0 if all registers are false and -1 if all registers are true.
17566 The value of the complete result is indeterminate otherwise. */
17567 switch (builtin_type
)
17569 case MIPS_BUILTIN_CMP_ALL
:
17570 condition
= gen_rtx_NE (VOIDmode
, cmp_result
, constm1_rtx
);
17571 return mips_builtin_branch_and_move (condition
, target
,
17572 const0_rtx
, const1_rtx
);
17574 case MIPS_BUILTIN_CMP_UPPER
:
17575 case MIPS_BUILTIN_CMP_LOWER
:
17576 offset
= GEN_INT (builtin_type
== MIPS_BUILTIN_CMP_UPPER
);
17577 condition
= gen_single_cc (cmp_result
, offset
);
17578 return mips_builtin_branch_and_move (condition
, target
,
17579 const1_rtx
, const0_rtx
);
17582 condition
= gen_rtx_NE (VOIDmode
, cmp_result
, const0_rtx
);
17583 return mips_builtin_branch_and_move (condition
, target
,
17584 const1_rtx
, const0_rtx
);
17588 /* Expand a bposge built-in function of type BUILTIN_TYPE. TARGET,
17589 if nonnull, suggests a good place to put the boolean result. */
17592 mips_expand_builtin_bposge (enum mips_builtin_type builtin_type
, rtx target
)
17594 rtx condition
, cmp_result
;
17597 if (target
== 0 || GET_MODE (target
) != SImode
)
17598 target
= gen_reg_rtx (SImode
);
17600 cmp_result
= gen_rtx_REG (CCDSPmode
, CCDSP_PO_REGNUM
);
17602 if (builtin_type
== MIPS_BUILTIN_BPOSGE32
)
17607 condition
= gen_rtx_GE (VOIDmode
, cmp_result
, GEN_INT (cmp_value
));
17608 return mips_builtin_branch_and_move (condition
, target
,
17609 const1_rtx
, const0_rtx
);
17612 /* Implement TARGET_EXPAND_BUILTIN. */
17615 mips_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
17616 machine_mode mode
, int ignore
)
17619 unsigned int fcode
, avail
;
17620 const struct mips_builtin_description
*d
;
17622 fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
17623 fcode
= DECL_MD_FUNCTION_CODE (fndecl
);
17624 gcc_assert (fcode
< ARRAY_SIZE (mips_builtins
));
17625 d
= &mips_builtins
[fcode
];
17626 avail
= d
->avail ();
17627 gcc_assert (avail
!= 0);
17628 if (TARGET_MIPS16
&& !(avail
& BUILTIN_AVAIL_MIPS16
)
17629 && (!TARGET_MIPS16E2
|| !(avail
& BUILTIN_AVAIL_MIPS16E2
)))
17631 error ("built-in function %qE not supported for MIPS16",
17632 DECL_NAME (fndecl
));
17633 return ignore
? const0_rtx
: CONST0_RTX (mode
);
17635 switch (d
->builtin_type
)
17637 case MIPS_BUILTIN_DIRECT
:
17638 return mips_expand_builtin_direct (d
->icode
, target
, exp
, true);
17640 case MIPS_BUILTIN_DIRECT_NO_TARGET
:
17641 return mips_expand_builtin_direct (d
->icode
, target
, exp
, false);
17643 case MIPS_BUILTIN_MOVT
:
17644 case MIPS_BUILTIN_MOVF
:
17645 return mips_expand_builtin_movtf (d
->builtin_type
, d
->icode
,
17646 d
->cond
, target
, exp
);
17648 case MIPS_BUILTIN_CMP_ANY
:
17649 case MIPS_BUILTIN_CMP_ALL
:
17650 case MIPS_BUILTIN_CMP_UPPER
:
17651 case MIPS_BUILTIN_CMP_LOWER
:
17652 case MIPS_BUILTIN_CMP_SINGLE
:
17653 return mips_expand_builtin_compare (d
->builtin_type
, d
->icode
,
17654 d
->cond
, target
, exp
);
17656 case MIPS_BUILTIN_MSA_TEST_BRANCH
:
17657 return mips_expand_builtin_msa_test_branch (d
->icode
, exp
);
17659 case MIPS_BUILTIN_BPOSGE32
:
17660 return mips_expand_builtin_bposge (d
->builtin_type
, target
);
17662 gcc_unreachable ();
17665 /* An entry in the MIPS16 constant pool. VALUE is the pool constant,
17666 MODE is its mode, and LABEL is the CODE_LABEL associated with it. */
17667 struct mips16_constant
{
17668 struct mips16_constant
*next
;
17670 rtx_code_label
*label
;
17674 /* Information about an incomplete MIPS16 constant pool. FIRST is the
17675 first constant, HIGHEST_ADDRESS is the highest address that the first
17676 byte of the pool can have, and INSN_ADDRESS is the current instruction
17678 struct mips16_constant_pool
{
17679 struct mips16_constant
*first
;
17680 int highest_address
;
17684 /* Add constant VALUE to POOL and return its label. MODE is the
17685 value's mode (used for CONST_INTs, etc.). */
17687 static rtx_code_label
*
17688 mips16_add_constant (struct mips16_constant_pool
*pool
,
17689 rtx value
, machine_mode mode
)
17691 struct mips16_constant
**p
, *c
;
17692 bool first_of_size_p
;
17694 /* See whether the constant is already in the pool. If so, return the
17695 existing label, otherwise leave P pointing to the place where the
17696 constant should be added.
17698 Keep the pool sorted in increasing order of mode size so that we can
17699 reduce the number of alignments needed. */
17700 first_of_size_p
= true;
17701 for (p
= &pool
->first
; *p
!= 0; p
= &(*p
)->next
)
17703 if (mode
== (*p
)->mode
&& rtx_equal_p (value
, (*p
)->value
))
17704 return (*p
)->label
;
17705 if (GET_MODE_SIZE (mode
) < GET_MODE_SIZE ((*p
)->mode
))
17707 if (GET_MODE_SIZE (mode
) == GET_MODE_SIZE ((*p
)->mode
))
17708 first_of_size_p
= false;
17711 /* In the worst case, the constant needed by the earliest instruction
17712 will end up at the end of the pool. The entire pool must then be
17713 accessible from that instruction.
17715 When adding the first constant, set the pool's highest address to
17716 the address of the first out-of-range byte. Adjust this address
17717 downwards each time a new constant is added. */
17718 if (pool
->first
== 0)
17719 /* For LWPC, ADDIUPC and DADDIUPC, the base PC value is the address
17720 of the instruction with the lowest two bits clear. The base PC
17721 value for LDPC has the lowest three bits clear. Assume the worst
17722 case here; namely that the PC-relative instruction occupies the
17723 last 2 bytes in an aligned word. */
17724 pool
->highest_address
= pool
->insn_address
- (UNITS_PER_WORD
- 2) + 0x8000;
17725 pool
->highest_address
-= GET_MODE_SIZE (mode
);
17726 if (first_of_size_p
)
17727 /* Take into account the worst possible padding due to alignment. */
17728 pool
->highest_address
-= GET_MODE_SIZE (mode
) - 1;
17730 /* Create a new entry. */
17731 c
= XNEW (struct mips16_constant
);
17734 c
->label
= gen_label_rtx ();
17741 /* Output constant VALUE after instruction INSN and return the last
17742 instruction emitted. MODE is the mode of the constant. */
17745 mips16_emit_constants_1 (machine_mode mode
, rtx value
, rtx_insn
*insn
)
17747 if (SCALAR_INT_MODE_P (mode
) || ALL_SCALAR_FIXED_POINT_MODE_P (mode
))
17749 rtx size
= GEN_INT (GET_MODE_SIZE (mode
));
17750 return emit_insn_after (gen_consttable_int (value
, size
), insn
);
17753 if (SCALAR_FLOAT_MODE_P (mode
))
17754 return emit_insn_after (gen_consttable_float (value
), insn
);
17756 if (VECTOR_MODE_P (mode
))
17760 for (i
= 0; i
< CONST_VECTOR_NUNITS (value
); i
++)
17761 insn
= mips16_emit_constants_1 (GET_MODE_INNER (mode
),
17762 CONST_VECTOR_ELT (value
, i
), insn
);
17766 gcc_unreachable ();
17769 /* Dump out the constants in CONSTANTS after INSN. Record the initial
17770 label number in the `consttable' and `consttable_end' insns emitted
17771 at the beginning and the end of the constant pool respectively, so
17772 that individual pools can be uniquely marked as data for the purpose
17776 mips16_emit_constants (struct mips16_constant
*constants
, rtx_insn
*insn
)
17778 int label_num
= constants
? CODE_LABEL_NUMBER (constants
->label
) : 0;
17779 struct mips16_constant
*c
, *next
;
17784 insn
= emit_insn_after (gen_consttable (GEN_INT (label_num
)), insn
);
17785 for (c
= constants
; c
!= NULL
; c
= next
)
17787 /* If necessary, increase the alignment of PC. */
17788 if (align
< GET_MODE_SIZE (c
->mode
))
17790 int align_log
= floor_log2 (GET_MODE_SIZE (c
->mode
));
17791 insn
= emit_insn_after (gen_align (GEN_INT (align_log
)), insn
);
17793 align
= GET_MODE_SIZE (c
->mode
);
17795 insn
= emit_label_after (c
->label
, insn
);
17796 insn
= mips16_emit_constants_1 (c
->mode
, c
->value
, insn
);
17802 insn
= emit_insn_after (gen_consttable_end (GEN_INT (label_num
)), insn
);
17804 emit_barrier_after (insn
);
17807 /* Return the length of instruction INSN. */
17810 mips16_insn_length (rtx_insn
*insn
)
17812 if (JUMP_TABLE_DATA_P (insn
))
17814 rtx body
= PATTERN (insn
);
17815 if (GET_CODE (body
) == ADDR_VEC
)
17816 return GET_MODE_SIZE (GET_MODE (body
)) * XVECLEN (body
, 0);
17817 else if (GET_CODE (body
) == ADDR_DIFF_VEC
)
17818 return GET_MODE_SIZE (GET_MODE (body
)) * XVECLEN (body
, 1);
17820 gcc_unreachable ();
17822 return get_attr_length (insn
);
17825 /* If *X is a symbolic constant that refers to the constant pool, add
17826 the constant to POOL and rewrite *X to use the constant's label. */
17829 mips16_rewrite_pool_constant (struct mips16_constant_pool
*pool
, rtx
*x
)
17832 rtx_code_label
*label
;
17834 split_const (*x
, &base
, &offset
);
17835 if (GET_CODE (base
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (base
))
17837 label
= mips16_add_constant (pool
, copy_rtx (get_pool_constant (base
)),
17838 get_pool_mode (base
));
17839 base
= gen_rtx_LABEL_REF (Pmode
, label
);
17840 *x
= mips_unspec_address_offset (base
, offset
, SYMBOL_PC_RELATIVE
);
17844 /* Rewrite INSN so that constant pool references refer to the constant's
17848 mips16_rewrite_pool_refs (rtx_insn
*insn
, struct mips16_constant_pool
*pool
)
17850 subrtx_ptr_iterator::array_type array
;
17851 FOR_EACH_SUBRTX_PTR (iter
, array
, &PATTERN (insn
), ALL
)
17855 if (force_to_mem_operand (*loc
, Pmode
))
17857 rtx mem
= force_const_mem (GET_MODE (*loc
), *loc
);
17858 validate_change (insn
, loc
, mem
, false);
17863 mips16_rewrite_pool_constant (pool
, &XEXP (*loc
, 0));
17864 iter
.skip_subrtxes ();
17868 if (TARGET_MIPS16_TEXT_LOADS
)
17869 mips16_rewrite_pool_constant (pool
, loc
);
17870 if (GET_CODE (*loc
) == CONST
17871 /* Don't rewrite the __mips16_rdwr symbol. */
17872 || (GET_CODE (*loc
) == UNSPEC
17873 && XINT (*loc
, 1) == UNSPEC_TLS_GET_TP
))
17874 iter
.skip_subrtxes ();
17879 /* Return whether CFG is used in mips_reorg. */
17882 mips_cfg_in_reorg (void)
17884 return (mips_r10k_cache_barrier
!= R10K_CACHE_BARRIER_NONE
17885 || TARGET_RELAX_PIC_CALLS
);
17888 /* Build MIPS16 constant pools. Split the instructions if SPLIT_P,
17889 otherwise assume that they are already split. */
17892 mips16_lay_out_constants (bool split_p
)
17894 struct mips16_constant_pool pool
;
17895 rtx_insn
*insn
, *barrier
;
17897 if (!TARGET_MIPS16_PCREL_LOADS
)
17902 if (mips_cfg_in_reorg ())
17903 split_all_insns ();
17905 split_all_insns_noflow ();
17908 memset (&pool
, 0, sizeof (pool
));
17909 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
17911 /* Rewrite constant pool references in INSN. */
17912 if (USEFUL_INSN_P (insn
))
17913 mips16_rewrite_pool_refs (insn
, &pool
);
17915 pool
.insn_address
+= mips16_insn_length (insn
);
17917 if (pool
.first
!= NULL
)
17919 /* If there are no natural barriers between the first user of
17920 the pool and the highest acceptable address, we'll need to
17921 create a new instruction to jump around the constant pool.
17922 In the worst case, this instruction will be 4 bytes long.
17924 If it's too late to do this transformation after INSN,
17925 do it immediately before INSN. */
17926 if (barrier
== 0 && pool
.insn_address
+ 4 > pool
.highest_address
)
17928 rtx_code_label
*label
;
17931 label
= gen_label_rtx ();
17933 jump
= emit_jump_insn_before (gen_jump (label
), insn
);
17934 JUMP_LABEL (jump
) = label
;
17935 LABEL_NUSES (label
) = 1;
17936 barrier
= emit_barrier_after (jump
);
17938 emit_label_after (label
, barrier
);
17939 pool
.insn_address
+= 4;
17942 /* See whether the constant pool is now out of range of the first
17943 user. If so, output the constants after the previous barrier.
17944 Note that any instructions between BARRIER and INSN (inclusive)
17945 will use negative offsets to refer to the pool. */
17946 if (pool
.insn_address
> pool
.highest_address
)
17948 mips16_emit_constants (pool
.first
, barrier
);
17952 else if (BARRIER_P (insn
))
17956 mips16_emit_constants (pool
.first
, get_last_insn ());
17959 /* Return true if it is worth r10k_simplify_address's while replacing
17960 an address with X. We are looking for constants, and for addresses
17961 at a known offset from the incoming stack pointer. */
17964 r10k_simplified_address_p (rtx x
)
17966 if (GET_CODE (x
) == PLUS
&& CONST_INT_P (XEXP (x
, 1)))
17968 return x
== virtual_incoming_args_rtx
|| CONSTANT_P (x
);
17971 /* X is an expression that appears in INSN. Try to use the UD chains
17972 to simplify it, returning the simplified form on success and the
17973 original form otherwise. Replace the incoming value of $sp with
17974 virtual_incoming_args_rtx (which should never occur in X otherwise). */
17977 r10k_simplify_address (rtx x
, rtx_insn
*insn
)
17979 rtx newx
, op0
, op1
, set
, note
;
17980 rtx_insn
*def_insn
;
17982 struct df_link
*defs
;
17987 op0
= r10k_simplify_address (XEXP (x
, 0), insn
);
17988 if (op0
!= XEXP (x
, 0))
17989 newx
= simplify_gen_unary (GET_CODE (x
), GET_MODE (x
),
17990 op0
, GET_MODE (XEXP (x
, 0)));
17992 else if (BINARY_P (x
))
17994 op0
= r10k_simplify_address (XEXP (x
, 0), insn
);
17995 op1
= r10k_simplify_address (XEXP (x
, 1), insn
);
17996 if (op0
!= XEXP (x
, 0) || op1
!= XEXP (x
, 1))
17997 newx
= simplify_gen_binary (GET_CODE (x
), GET_MODE (x
), op0
, op1
);
17999 else if (GET_CODE (x
) == LO_SUM
)
18001 /* LO_SUMs can be offset from HIGHs, if we know they won't
18002 overflow. See mips_classify_address for the rationale behind
18004 op0
= r10k_simplify_address (XEXP (x
, 0), insn
);
18005 if (GET_CODE (op0
) == HIGH
)
18006 newx
= XEXP (x
, 1);
18008 else if (REG_P (x
))
18010 /* Uses are recorded by regno_reg_rtx, not X itself. */
18011 use
= df_find_use (insn
, regno_reg_rtx
[REGNO (x
)]);
18013 defs
= DF_REF_CHAIN (use
);
18015 /* Require a single definition. */
18016 if (defs
&& defs
->next
== NULL
)
18019 if (DF_REF_IS_ARTIFICIAL (def
))
18021 /* Replace the incoming value of $sp with
18022 virtual_incoming_args_rtx. */
18023 if (x
== stack_pointer_rtx
18024 && DF_REF_BB (def
) == ENTRY_BLOCK_PTR_FOR_FN (cfun
))
18025 newx
= virtual_incoming_args_rtx
;
18027 else if (dominated_by_p (CDI_DOMINATORS
, DF_REF_BB (use
),
18030 /* Make sure that DEF_INSN is a single set of REG. */
18031 def_insn
= DF_REF_INSN (def
);
18032 if (NONJUMP_INSN_P (def_insn
))
18034 set
= single_set (def_insn
);
18035 if (set
&& rtx_equal_p (SET_DEST (set
), x
))
18037 /* Prefer to use notes, since the def-use chains
18038 are often shorter. */
18039 note
= find_reg_equal_equiv_note (def_insn
);
18041 newx
= XEXP (note
, 0);
18043 newx
= SET_SRC (set
);
18044 newx
= r10k_simplify_address (newx
, def_insn
);
18050 if (newx
&& r10k_simplified_address_p (newx
))
18055 /* Return true if ADDRESS is known to be an uncached address
18056 on R10K systems. */
18059 r10k_uncached_address_p (unsigned HOST_WIDE_INT address
)
18061 unsigned HOST_WIDE_INT upper
;
18063 /* Check for KSEG1. */
18064 if (address
+ 0x60000000 < 0x20000000)
18067 /* Check for uncached XKPHYS addresses. */
18068 if (Pmode
== DImode
)
18070 upper
= (address
>> 40) & 0xf9ffff;
18071 if (upper
== 0x900000 || upper
== 0xb80000)
18077 /* Return true if we can prove that an access to address X in instruction
18078 INSN would be safe from R10K speculation. This X is a general
18079 expression; it might not be a legitimate address. */
18082 r10k_safe_address_p (rtx x
, rtx_insn
*insn
)
18085 HOST_WIDE_INT offset_val
;
18087 x
= r10k_simplify_address (x
, insn
);
18089 /* Check for references to the stack frame. It doesn't really matter
18090 how much of the frame has been allocated at INSN; -mr10k-cache-barrier
18091 allows us to assume that accesses to any part of the eventual frame
18092 is safe from speculation at any point in the function. */
18093 mips_split_plus (x
, &base
, &offset_val
);
18094 if (base
== virtual_incoming_args_rtx
18095 && offset_val
>= -cfun
->machine
->frame
.total_size
18096 && offset_val
< cfun
->machine
->frame
.args_size
)
18099 /* Check for uncached addresses. */
18100 if (CONST_INT_P (x
))
18101 return r10k_uncached_address_p (INTVAL (x
));
18103 /* Check for accesses to a static object. */
18104 split_const (x
, &base
, &offset
);
18105 return offset_within_block_p (base
, INTVAL (offset
));
18108 /* Return true if a MEM with MEM_EXPR EXPR and MEM_OFFSET OFFSET is
18109 an in-range access to an automatic variable, or to an object with
18110 a link-time-constant address. */
18113 r10k_safe_mem_expr_p (tree expr
, unsigned HOST_WIDE_INT offset
)
18115 poly_int64 bitoffset
, bitsize
;
18116 tree inner
, var_offset
;
18118 int unsigned_p
, reverse_p
, volatile_p
;
18120 inner
= get_inner_reference (expr
, &bitsize
, &bitoffset
, &var_offset
, &mode
,
18121 &unsigned_p
, &reverse_p
, &volatile_p
);
18122 if (!DECL_P (inner
) || !DECL_SIZE_UNIT (inner
) || var_offset
)
18125 offset
+= bitoffset
/ BITS_PER_UNIT
;
18126 return offset
< tree_to_uhwi (DECL_SIZE_UNIT (inner
));
18129 /* Return true if X contains a MEM that is not safe from R10K speculation.
18130 INSN is the instruction that contains X. */
18133 r10k_needs_protection_p_1 (rtx x
, rtx_insn
*insn
)
18135 subrtx_var_iterator::array_type array
;
18136 FOR_EACH_SUBRTX_VAR (iter
, array
, x
, NONCONST
)
18141 if ((MEM_EXPR (mem
)
18142 && MEM_OFFSET_KNOWN_P (mem
)
18143 && r10k_safe_mem_expr_p (MEM_EXPR (mem
), MEM_OFFSET (mem
)))
18144 || r10k_safe_address_p (XEXP (mem
, 0), insn
))
18145 iter
.skip_subrtxes ();
18153 /* A note_stores callback for which DATA points to an instruction pointer.
18154 If *DATA is nonnull, make it null if it X contains a MEM that is not
18155 safe from R10K speculation. */
18158 r10k_needs_protection_p_store (rtx x
, const_rtx pat ATTRIBUTE_UNUSED
,
18161 rtx_insn
**insn_ptr
;
18163 insn_ptr
= (rtx_insn
**) data
;
18164 if (*insn_ptr
&& r10k_needs_protection_p_1 (x
, *insn_ptr
))
18168 /* X is the pattern of a call instruction. Return true if the call is
18169 not to a declared function. */
18172 r10k_needs_protection_p_call (const_rtx x
)
18174 subrtx_iterator::array_type array
;
18175 FOR_EACH_SUBRTX (iter
, array
, x
, NONCONST
)
18177 const_rtx mem
= *iter
;
18180 const_rtx addr
= XEXP (mem
, 0);
18181 if (GET_CODE (addr
) == SYMBOL_REF
&& SYMBOL_REF_DECL (addr
))
18182 iter
.skip_subrtxes ();
18190 /* Return true if instruction INSN needs to be protected by an R10K
18194 r10k_needs_protection_p (rtx_insn
*insn
)
18197 return r10k_needs_protection_p_call (PATTERN (insn
));
18199 if (mips_r10k_cache_barrier
== R10K_CACHE_BARRIER_STORE
)
18201 note_stores (insn
, r10k_needs_protection_p_store
, &insn
);
18202 return insn
== NULL_RTX
;
18205 return r10k_needs_protection_p_1 (PATTERN (insn
), insn
);
18208 /* Return true if BB is only reached by blocks in PROTECTED_BBS and if every
18209 edge is unconditional. */
18212 r10k_protected_bb_p (basic_block bb
, sbitmap protected_bbs
)
18217 FOR_EACH_EDGE (e
, ei
, bb
->preds
)
18218 if (!single_succ_p (e
->src
)
18219 || !bitmap_bit_p (protected_bbs
, e
->src
->index
)
18220 || (e
->flags
& EDGE_COMPLEX
) != 0)
18225 /* Implement -mr10k-cache-barrier= for the current function. */
18228 r10k_insert_cache_barriers (void)
18230 int *rev_post_order
;
18233 sbitmap protected_bbs
;
18234 rtx_insn
*insn
, *end
;
18235 rtx unprotected_region
;
18239 sorry ("%qs does not support MIPS16 code", "-mr10k-cache-barrier");
18243 /* Calculate dominators. */
18244 calculate_dominance_info (CDI_DOMINATORS
);
18246 /* Bit X of PROTECTED_BBS is set if the last operation in basic block
18247 X is protected by a cache barrier. */
18248 protected_bbs
= sbitmap_alloc (last_basic_block_for_fn (cfun
));
18249 bitmap_clear (protected_bbs
);
18251 /* Iterate over the basic blocks in reverse post-order. */
18252 rev_post_order
= XNEWVEC (int, last_basic_block_for_fn (cfun
));
18253 n
= pre_and_rev_post_order_compute (NULL
, rev_post_order
, false);
18254 for (i
= 0; i
< n
; i
++)
18256 bb
= BASIC_BLOCK_FOR_FN (cfun
, rev_post_order
[i
]);
18258 /* If this block is only reached by unconditional edges, and if the
18259 source of every edge is protected, the beginning of the block is
18261 if (r10k_protected_bb_p (bb
, protected_bbs
))
18262 unprotected_region
= NULL_RTX
;
18264 unprotected_region
= pc_rtx
;
18265 end
= NEXT_INSN (BB_END (bb
));
18267 /* UNPROTECTED_REGION is:
18269 - null if we are processing a protected region,
18270 - pc_rtx if we are processing an unprotected region but have
18271 not yet found the first instruction in it
18272 - the first instruction in an unprotected region otherwise. */
18273 for (insn
= BB_HEAD (bb
); insn
!= end
; insn
= NEXT_INSN (insn
))
18275 if (unprotected_region
&& USEFUL_INSN_P (insn
))
18277 if (recog_memoized (insn
) == CODE_FOR_mips_cache
)
18278 /* This CACHE instruction protects the following code. */
18279 unprotected_region
= NULL_RTX
;
18282 /* See if INSN is the first instruction in this
18283 unprotected region. */
18284 if (unprotected_region
== pc_rtx
)
18285 unprotected_region
= insn
;
18287 /* See if INSN needs to be protected. If so,
18288 we must insert a cache barrier somewhere between
18289 PREV_INSN (UNPROTECTED_REGION) and INSN. It isn't
18290 clear which position is better performance-wise,
18291 but as a tie-breaker, we assume that it is better
18292 to allow delay slots to be back-filled where
18293 possible, and that it is better not to insert
18294 barriers in the middle of already-scheduled code.
18295 We therefore insert the barrier at the beginning
18297 if (r10k_needs_protection_p (insn
))
18299 emit_insn_before (gen_r10k_cache_barrier (),
18300 as_a
<rtx_insn
*> (unprotected_region
));
18301 unprotected_region
= NULL_RTX
;
18307 /* The called function is not required to protect the exit path.
18308 The code that follows a call is therefore unprotected. */
18309 unprotected_region
= pc_rtx
;
18312 /* Record whether the end of this block is protected. */
18313 if (unprotected_region
== NULL_RTX
)
18314 bitmap_set_bit (protected_bbs
, bb
->index
);
18316 XDELETEVEC (rev_post_order
);
18318 sbitmap_free (protected_bbs
);
18320 free_dominance_info (CDI_DOMINATORS
);
18323 /* If INSN is a call, return the underlying CALL expr. Return NULL_RTX
18324 otherwise. If INSN has two call rtx, then store the second one in
18328 mips_call_expr_from_insn (rtx_insn
*insn
, rtx
*second_call
)
18333 if (!CALL_P (insn
))
18336 x
= PATTERN (insn
);
18337 if (GET_CODE (x
) == PARALLEL
)
18339 /* Calls returning complex values have two CALL rtx. Look for the second
18340 one here, and return it via the SECOND_CALL arg. */
18341 x2
= XVECEXP (x
, 0, 1);
18342 if (GET_CODE (x2
) == SET
)
18344 if (GET_CODE (x2
) == CALL
)
18347 x
= XVECEXP (x
, 0, 0);
18349 if (GET_CODE (x
) == SET
)
18351 gcc_assert (GET_CODE (x
) == CALL
);
18356 /* REG is set in DEF. See if the definition is one of the ways we load a
18357 register with a symbol address for a mips_use_pic_fn_addr_reg_p call.
18358 If it is, return the symbol reference of the function, otherwise return
18361 If RECURSE_P is true, use mips_find_pic_call_symbol to interpret
18362 the values of source registers, otherwise treat such registers as
18363 having an unknown value. */
18366 mips_pic_call_symbol_from_set (df_ref def
, rtx reg
, bool recurse_p
)
18368 rtx_insn
*def_insn
;
18371 if (DF_REF_IS_ARTIFICIAL (def
))
18374 def_insn
= DF_REF_INSN (def
);
18375 set
= single_set (def_insn
);
18376 if (set
&& rtx_equal_p (SET_DEST (set
), reg
))
18378 rtx note
, src
, symbol
;
18380 /* First see whether the source is a plain symbol. This is used
18381 when calling symbols that are not lazily bound. */
18382 src
= SET_SRC (set
);
18383 if (GET_CODE (src
) == SYMBOL_REF
)
18386 /* Handle %call16 references. */
18387 symbol
= mips_strip_unspec_call (src
);
18390 gcc_assert (GET_CODE (symbol
) == SYMBOL_REF
);
18394 /* If we have something more complicated, look for a
18395 REG_EQUAL or REG_EQUIV note. */
18396 note
= find_reg_equal_equiv_note (def_insn
);
18397 if (note
&& GET_CODE (XEXP (note
, 0)) == SYMBOL_REF
)
18398 return XEXP (note
, 0);
18400 /* Follow at most one simple register copy. Such copies are
18401 interesting in cases like:
18405 locally_binding_fn (...);
18410 locally_binding_fn (...);
18412 locally_binding_fn (...);
18414 where the load of locally_binding_fn can legitimately be
18415 hoisted or shared. However, we do not expect to see complex
18416 chains of copies, so a full worklist solution to the problem
18417 would probably be overkill. */
18418 if (recurse_p
&& REG_P (src
))
18419 return mips_find_pic_call_symbol (def_insn
, src
, false);
18425 /* Find the definition of the use of REG in INSN. See if the definition
18426 is one of the ways we load a register with a symbol address for a
18427 mips_use_pic_fn_addr_reg_p call. If it is return the symbol reference
18428 of the function, otherwise return NULL_RTX. RECURSE_P is as for
18429 mips_pic_call_symbol_from_set. */
18432 mips_find_pic_call_symbol (rtx_insn
*insn
, rtx reg
, bool recurse_p
)
18435 struct df_link
*defs
;
18438 use
= df_find_use (insn
, regno_reg_rtx
[REGNO (reg
)]);
18441 defs
= DF_REF_CHAIN (use
);
18444 symbol
= mips_pic_call_symbol_from_set (defs
->ref
, reg
, recurse_p
);
18448 /* If we have more than one definition, they need to be identical. */
18449 for (defs
= defs
->next
; defs
; defs
= defs
->next
)
18453 other
= mips_pic_call_symbol_from_set (defs
->ref
, reg
, recurse_p
);
18454 if (!rtx_equal_p (symbol
, other
))
18461 /* Replace the args_size operand of the call expression CALL with the
18462 call-attribute UNSPEC and fill in SYMBOL as the function symbol. */
18465 mips_annotate_pic_call_expr (rtx call
, rtx symbol
)
18469 args_size
= XEXP (call
, 1);
18470 XEXP (call
, 1) = gen_rtx_UNSPEC (GET_MODE (args_size
),
18471 gen_rtvec (2, args_size
, symbol
),
18475 /* OPERANDS[ARGS_SIZE_OPNO] is the arg_size operand of a CALL expression. See
18476 if instead of the arg_size argument it contains the call attributes. If
18477 yes return true along with setting OPERANDS[ARGS_SIZE_OPNO] to the function
18478 symbol from the call attributes. Also return false if ARGS_SIZE_OPNO is
18482 mips_get_pic_call_symbol (rtx
*operands
, int args_size_opno
)
18484 rtx args_size
, symbol
;
18486 if (!TARGET_RELAX_PIC_CALLS
|| args_size_opno
== -1)
18489 args_size
= operands
[args_size_opno
];
18490 if (GET_CODE (args_size
) != UNSPEC
)
18492 gcc_assert (XINT (args_size
, 1) == UNSPEC_CALL_ATTR
);
18494 symbol
= XVECEXP (args_size
, 0, 1);
18495 gcc_assert (GET_CODE (symbol
) == SYMBOL_REF
);
18497 operands
[args_size_opno
] = symbol
;
18501 /* Use DF to annotate PIC indirect calls with the function symbol they
18505 mips_annotate_pic_calls (void)
18510 FOR_EACH_BB_FN (bb
, cfun
)
18511 FOR_BB_INSNS (bb
, insn
)
18513 rtx call
, reg
, symbol
, second_call
;
18516 call
= mips_call_expr_from_insn (insn
, &second_call
);
18519 gcc_assert (MEM_P (XEXP (call
, 0)));
18520 reg
= XEXP (XEXP (call
, 0), 0);
18524 symbol
= mips_find_pic_call_symbol (insn
, reg
, true);
18527 mips_annotate_pic_call_expr (call
, symbol
);
18529 mips_annotate_pic_call_expr (second_call
, symbol
);
18534 /* A temporary variable used by note_uses callbacks, etc. */
18535 static rtx_insn
*mips_sim_insn
;
18537 /* A structure representing the state of the processor pipeline.
18538 Used by the mips_sim_* family of functions. */
18540 /* The maximum number of instructions that can be issued in a cycle.
18541 (Caches mips_issue_rate.) */
18542 unsigned int issue_rate
;
18544 /* The current simulation time. */
18547 /* How many more instructions can be issued in the current cycle. */
18548 unsigned int insns_left
;
18550 /* LAST_SET[X].INSN is the last instruction to set register X.
18551 LAST_SET[X].TIME is the time at which that instruction was issued.
18552 INSN is null if no instruction has yet set register X. */
18556 } last_set
[FIRST_PSEUDO_REGISTER
];
18558 /* The pipeline's current DFA state. */
18562 /* Reset STATE to the initial simulation state. */
18565 mips_sim_reset (struct mips_sim
*state
)
18567 curr_state
= state
->dfa_state
;
18570 state
->insns_left
= state
->issue_rate
;
18571 memset (&state
->last_set
, 0, sizeof (state
->last_set
));
18572 state_reset (curr_state
);
18574 targetm
.sched
.init (0, false, 0);
18575 advance_state (curr_state
);
18578 /* Initialize STATE before its first use. DFA_STATE points to an
18579 allocated but uninitialized DFA state. */
18582 mips_sim_init (struct mips_sim
*state
, state_t dfa_state
)
18584 if (targetm
.sched
.init_dfa_pre_cycle_insn
)
18585 targetm
.sched
.init_dfa_pre_cycle_insn ();
18587 if (targetm
.sched
.init_dfa_post_cycle_insn
)
18588 targetm
.sched
.init_dfa_post_cycle_insn ();
18590 state
->issue_rate
= mips_issue_rate ();
18591 state
->dfa_state
= dfa_state
;
18592 mips_sim_reset (state
);
18595 /* Advance STATE by one clock cycle. */
18598 mips_sim_next_cycle (struct mips_sim
*state
)
18600 curr_state
= state
->dfa_state
;
18603 state
->insns_left
= state
->issue_rate
;
18604 advance_state (curr_state
);
18607 /* Advance simulation state STATE until instruction INSN can read
18611 mips_sim_wait_reg (struct mips_sim
*state
, rtx_insn
*insn
, rtx reg
)
18613 unsigned int regno
, end_regno
;
18615 end_regno
= END_REGNO (reg
);
18616 for (regno
= REGNO (reg
); regno
< end_regno
; regno
++)
18617 if (state
->last_set
[regno
].insn
!= 0)
18621 t
= (state
->last_set
[regno
].time
18622 + insn_latency (state
->last_set
[regno
].insn
, insn
));
18623 while (state
->time
< t
)
18624 mips_sim_next_cycle (state
);
18628 /* A note_uses callback. For each register in *X, advance simulation
18629 state DATA until mips_sim_insn can read the register's value. */
18632 mips_sim_wait_regs_1 (rtx
*x
, void *data
)
18634 subrtx_var_iterator::array_type array
;
18635 FOR_EACH_SUBRTX_VAR (iter
, array
, *x
, NONCONST
)
18637 mips_sim_wait_reg ((struct mips_sim
*) data
, mips_sim_insn
, *iter
);
18640 /* Advance simulation state STATE until all of INSN's register
18641 dependencies are satisfied. */
18644 mips_sim_wait_regs (struct mips_sim
*state
, rtx_insn
*insn
)
18646 mips_sim_insn
= insn
;
18647 note_uses (&PATTERN (insn
), mips_sim_wait_regs_1
, state
);
18650 /* Advance simulation state STATE until the units required by
18651 instruction INSN are available. */
18654 mips_sim_wait_units (struct mips_sim
*state
, rtx_insn
*insn
)
18658 tmp_state
= alloca (state_size ());
18659 while (state
->insns_left
== 0
18660 || (memcpy (tmp_state
, state
->dfa_state
, state_size ()),
18661 state_transition (tmp_state
, insn
) >= 0))
18662 mips_sim_next_cycle (state
);
18665 /* Advance simulation state STATE until INSN is ready to issue. */
18668 mips_sim_wait_insn (struct mips_sim
*state
, rtx_insn
*insn
)
18670 mips_sim_wait_regs (state
, insn
);
18671 mips_sim_wait_units (state
, insn
);
18674 /* mips_sim_insn has just set X. Update the LAST_SET array
18675 in simulation state DATA. */
18678 mips_sim_record_set (rtx x
, const_rtx pat ATTRIBUTE_UNUSED
, void *data
)
18680 struct mips_sim
*state
;
18682 state
= (struct mips_sim
*) data
;
18685 unsigned int regno
, end_regno
;
18687 end_regno
= END_REGNO (x
);
18688 for (regno
= REGNO (x
); regno
< end_regno
; regno
++)
18690 state
->last_set
[regno
].insn
= mips_sim_insn
;
18691 state
->last_set
[regno
].time
= state
->time
;
18696 /* Issue instruction INSN in scheduler state STATE. Assume that INSN
18697 can issue immediately (i.e., that mips_sim_wait_insn has already
18701 mips_sim_issue_insn (struct mips_sim
*state
, rtx_insn
*insn
)
18703 curr_state
= state
->dfa_state
;
18705 state_transition (curr_state
, insn
);
18706 state
->insns_left
= targetm
.sched
.variable_issue (0, false, insn
,
18707 state
->insns_left
);
18709 mips_sim_insn
= insn
;
18710 note_stores (insn
, mips_sim_record_set
, state
);
18713 /* Simulate issuing a NOP in state STATE. */
18716 mips_sim_issue_nop (struct mips_sim
*state
)
18718 if (state
->insns_left
== 0)
18719 mips_sim_next_cycle (state
);
18720 state
->insns_left
--;
18723 /* Update simulation state STATE so that it's ready to accept the instruction
18724 after INSN. INSN should be part of the main rtl chain, not a member of a
18728 mips_sim_finish_insn (struct mips_sim
*state
, rtx_insn
*insn
)
18730 /* If INSN is a jump with an implicit delay slot, simulate a nop. */
18732 mips_sim_issue_nop (state
);
18734 switch (GET_CODE (SEQ_BEGIN (insn
)))
18738 /* We can't predict the processor state after a call or label. */
18739 mips_sim_reset (state
);
18743 /* The delay slots of branch likely instructions are only executed
18744 when the branch is taken. Therefore, if the caller has simulated
18745 the delay slot instruction, STATE does not really reflect the state
18746 of the pipeline for the instruction after the delay slot. Also,
18747 branch likely instructions tend to incur a penalty when not taken,
18748 so there will probably be an extra delay between the branch and
18749 the instruction after the delay slot. */
18750 if (INSN_ANNULLED_BRANCH_P (SEQ_BEGIN (insn
)))
18751 mips_sim_reset (state
);
18759 /* Use simulator state STATE to calculate the execution time of
18760 instruction sequence SEQ. */
18762 static unsigned int
18763 mips_seq_time (struct mips_sim
*state
, rtx_insn
*seq
)
18765 mips_sim_reset (state
);
18766 for (rtx_insn
*insn
= seq
; insn
; insn
= NEXT_INSN (insn
))
18768 mips_sim_wait_insn (state
, insn
);
18769 mips_sim_issue_insn (state
, insn
);
18771 return state
->time
;
18774 /* Return the execution-time cost of mips_tuning_info.fast_mult_zero_zero_p
18775 setting SETTING, using STATE to simulate instruction sequences. */
18777 static unsigned int
18778 mips_mult_zero_zero_cost (struct mips_sim
*state
, bool setting
)
18780 mips_tuning_info
.fast_mult_zero_zero_p
= setting
;
18783 machine_mode dword_mode
= TARGET_64BIT
? TImode
: DImode
;
18784 rtx hilo
= gen_rtx_REG (dword_mode
, MD_REG_FIRST
);
18785 mips_emit_move_or_split (hilo
, const0_rtx
, SPLIT_FOR_SPEED
);
18787 /* If the target provides mulsidi3_32bit then that's the most likely
18788 consumer of the result. Test for bypasses. */
18789 if (dword_mode
== DImode
&& HAVE_maddsidi4
)
18791 rtx gpr
= gen_rtx_REG (SImode
, GP_REG_FIRST
+ 4);
18792 emit_insn (gen_maddsidi4 (hilo
, gpr
, gpr
, hilo
));
18795 unsigned int time
= mips_seq_time (state
, get_insns ());
18800 /* Check the relative speeds of "MULT $0,$0" and "MTLO $0; MTHI $0"
18801 and set up mips_tuning_info.fast_mult_zero_zero_p accordingly.
18802 Prefer MULT -- which is shorter -- in the event of a tie. */
18805 mips_set_fast_mult_zero_zero_p (struct mips_sim
*state
)
18807 if (TARGET_MIPS16
|| !ISA_HAS_HILO
)
18808 /* No MTLO or MTHI available for MIPS16. Also, when there are no HI or LO
18809 registers then there is no reason to zero them, arbitrarily choose to
18810 say that "MULT $0,$0" would be faster. */
18811 mips_tuning_info
.fast_mult_zero_zero_p
= true;
18814 unsigned int true_time
= mips_mult_zero_zero_cost (state
, true);
18815 unsigned int false_time
= mips_mult_zero_zero_cost (state
, false);
18816 mips_tuning_info
.fast_mult_zero_zero_p
= (true_time
<= false_time
);
18820 /* Set up costs based on the current architecture and tuning settings. */
18823 mips_set_tuning_info (void)
18825 if (mips_tuning_info
.initialized_p
18826 && mips_tuning_info
.arch
== mips_arch
18827 && mips_tuning_info
.tune
== mips_tune
18828 && mips_tuning_info
.mips16_p
== TARGET_MIPS16
)
18831 mips_tuning_info
.arch
= mips_arch
;
18832 mips_tuning_info
.tune
= mips_tune
;
18833 mips_tuning_info
.mips16_p
= TARGET_MIPS16
;
18834 mips_tuning_info
.initialized_p
= true;
18838 struct mips_sim state
;
18839 mips_sim_init (&state
, alloca (state_size ()));
18841 mips_set_fast_mult_zero_zero_p (&state
);
18846 /* Implement TARGET_EXPAND_TO_RTL_HOOK. */
18849 mips_expand_to_rtl_hook (void)
18851 /* We need to call this at a point where we can safely create sequences
18852 of instructions, so TARGET_OVERRIDE_OPTIONS is too early. We also
18853 need to call it at a point where the DFA infrastructure is not
18854 already in use, so we can't just call it lazily on demand.
18856 At present, mips_tuning_info is only needed during post-expand
18857 RTL passes such as split_insns, so this hook should be early enough.
18858 We may need to move the call elsewhere if mips_tuning_info starts
18859 to be used for other things (such as rtx_costs, or expanders that
18860 could be called during gimple optimization). */
18861 mips_set_tuning_info ();
18864 /* The VR4130 pipeline issues aligned pairs of instructions together,
18865 but it stalls the second instruction if it depends on the first.
18866 In order to cut down the amount of logic required, this dependence
18867 check is not based on a full instruction decode. Instead, any non-SPECIAL
18868 instruction is assumed to modify the register specified by bits 20-16
18869 (which is usually the "rt" field).
18871 In BEQ, BEQL, BNE and BNEL instructions, the rt field is actually an
18872 input, so we can end up with a false dependence between the branch
18873 and its delay slot. If this situation occurs in instruction INSN,
18874 try to avoid it by swapping rs and rt. */
18877 vr4130_avoid_branch_rt_conflict (rtx_insn
*insn
)
18879 rtx_insn
*first
, *second
;
18881 first
= SEQ_BEGIN (insn
);
18882 second
= SEQ_END (insn
);
18884 && NONJUMP_INSN_P (second
)
18885 && GET_CODE (PATTERN (first
)) == SET
18886 && GET_CODE (SET_DEST (PATTERN (first
))) == PC
18887 && GET_CODE (SET_SRC (PATTERN (first
))) == IF_THEN_ELSE
)
18889 /* Check for the right kind of condition. */
18890 rtx cond
= XEXP (SET_SRC (PATTERN (first
)), 0);
18891 if ((GET_CODE (cond
) == EQ
|| GET_CODE (cond
) == NE
)
18892 && REG_P (XEXP (cond
, 0))
18893 && REG_P (XEXP (cond
, 1))
18894 && reg_referenced_p (XEXP (cond
, 1), PATTERN (second
))
18895 && !reg_referenced_p (XEXP (cond
, 0), PATTERN (second
)))
18897 /* SECOND mentions the rt register but not the rs register. */
18898 rtx tmp
= XEXP (cond
, 0);
18899 XEXP (cond
, 0) = XEXP (cond
, 1);
18900 XEXP (cond
, 1) = tmp
;
18905 /* Implement -mvr4130-align. Go through each basic block and simulate the
18906 processor pipeline. If we find that a pair of instructions could execute
18907 in parallel, and the first of those instructions is not 8-byte aligned,
18908 insert a nop to make it aligned. */
18911 vr4130_align_insns (void)
18913 struct mips_sim state
;
18914 rtx_insn
*insn
, *subinsn
, *last
, *last2
, *next
;
18919 /* LAST is the last instruction before INSN to have a nonzero length.
18920 LAST2 is the last such instruction before LAST. */
18924 /* ALIGNED_P is true if INSN is known to be at an aligned address. */
18927 mips_sim_init (&state
, alloca (state_size ()));
18928 for (insn
= get_insns (); insn
!= 0; insn
= next
)
18930 unsigned int length
;
18932 next
= NEXT_INSN (insn
);
18934 /* See the comment above vr4130_avoid_branch_rt_conflict for details.
18935 This isn't really related to the alignment pass, but we do it on
18936 the fly to avoid a separate instruction walk. */
18937 vr4130_avoid_branch_rt_conflict (insn
);
18939 length
= get_attr_length (insn
);
18940 if (length
> 0 && USEFUL_INSN_P (insn
))
18941 FOR_EACH_SUBINSN (subinsn
, insn
)
18943 mips_sim_wait_insn (&state
, subinsn
);
18945 /* If we want this instruction to issue in parallel with the
18946 previous one, make sure that the previous instruction is
18947 aligned. There are several reasons why this isn't worthwhile
18948 when the second instruction is a call:
18950 - Calls are less likely to be performance critical,
18951 - There's a good chance that the delay slot can execute
18952 in parallel with the call.
18953 - The return address would then be unaligned.
18955 In general, if we're going to insert a nop between instructions
18956 X and Y, it's better to insert it immediately after X. That
18957 way, if the nop makes Y aligned, it will also align any labels
18958 between X and Y. */
18959 if (state
.insns_left
!= state
.issue_rate
18960 && !CALL_P (subinsn
))
18962 if (subinsn
== SEQ_BEGIN (insn
) && aligned_p
)
18964 /* SUBINSN is the first instruction in INSN and INSN is
18965 aligned. We want to align the previous instruction
18966 instead, so insert a nop between LAST2 and LAST.
18968 Note that LAST could be either a single instruction
18969 or a branch with a delay slot. In the latter case,
18970 LAST, like INSN, is already aligned, but the delay
18971 slot must have some extra delay that stops it from
18972 issuing at the same time as the branch. We therefore
18973 insert a nop before the branch in order to align its
18975 gcc_assert (last2
);
18976 emit_insn_after (gen_nop (), last2
);
18979 else if (subinsn
!= SEQ_BEGIN (insn
) && !aligned_p
)
18981 /* SUBINSN is the delay slot of INSN, but INSN is
18982 currently unaligned. Insert a nop between
18983 LAST and INSN to align it. */
18985 emit_insn_after (gen_nop (), last
);
18989 mips_sim_issue_insn (&state
, subinsn
);
18991 mips_sim_finish_insn (&state
, insn
);
18993 /* Update LAST, LAST2 and ALIGNED_P for the next instruction. */
18994 length
= get_attr_length (insn
);
18997 /* If the instruction is an asm statement or multi-instruction
18998 mips.md pattern, the length is only an estimate. Insert an
18999 8 byte alignment after it so that the following instructions
19000 can be handled correctly. */
19001 if (NONJUMP_INSN_P (SEQ_BEGIN (insn
))
19002 && (recog_memoized (insn
) < 0 || length
>= 8))
19004 next
= emit_insn_after (gen_align (GEN_INT (3)), insn
);
19005 next
= NEXT_INSN (next
);
19006 mips_sim_next_cycle (&state
);
19009 else if (length
& 4)
19010 aligned_p
= !aligned_p
;
19015 /* See whether INSN is an aligned label. */
19016 if (LABEL_P (insn
) && label_to_alignment (insn
).levels
[0].log
>= 3)
19022 /* This structure records that the current function has a LO_SUM
19023 involving SYMBOL_REF or LABEL_REF BASE and that MAX_OFFSET is
19024 the largest offset applied to BASE by all such LO_SUMs. */
19025 struct mips_lo_sum_offset
{
19027 HOST_WIDE_INT offset
;
19030 /* Return a hash value for SYMBOL_REF or LABEL_REF BASE. */
19033 mips_hash_base (rtx base
)
19035 int do_not_record_p
;
19037 return hash_rtx (base
, GET_MODE (base
), &do_not_record_p
, NULL
, false);
19040 /* Hashtable helpers. */
19042 struct mips_lo_sum_offset_hasher
: free_ptr_hash
<mips_lo_sum_offset
>
19044 typedef rtx_def
*compare_type
;
19045 static inline hashval_t
hash (const mips_lo_sum_offset
*);
19046 static inline bool equal (const mips_lo_sum_offset
*, const rtx_def
*);
19049 /* Hash-table callbacks for mips_lo_sum_offsets. */
19052 mips_lo_sum_offset_hasher::hash (const mips_lo_sum_offset
*entry
)
19054 return mips_hash_base (entry
->base
);
19058 mips_lo_sum_offset_hasher::equal (const mips_lo_sum_offset
*entry
,
19059 const rtx_def
*value
)
19061 return rtx_equal_p (entry
->base
, value
);
19064 typedef hash_table
<mips_lo_sum_offset_hasher
> mips_offset_table
;
19066 /* Look up symbolic constant X in HTAB, which is a hash table of
19067 mips_lo_sum_offsets. If OPTION is NO_INSERT, return true if X can be
19068 paired with a recorded LO_SUM, otherwise record X in the table. */
19071 mips_lo_sum_offset_lookup (mips_offset_table
*htab
, rtx x
,
19072 enum insert_option option
)
19075 mips_lo_sum_offset
**slot
;
19076 struct mips_lo_sum_offset
*entry
;
19078 /* Split X into a base and offset. */
19079 split_const (x
, &base
, &offset
);
19080 if (UNSPEC_ADDRESS_P (base
))
19081 base
= UNSPEC_ADDRESS (base
);
19083 /* Look up the base in the hash table. */
19084 slot
= htab
->find_slot_with_hash (base
, mips_hash_base (base
), option
);
19088 entry
= (struct mips_lo_sum_offset
*) *slot
;
19089 if (option
== INSERT
)
19093 entry
= XNEW (struct mips_lo_sum_offset
);
19094 entry
->base
= base
;
19095 entry
->offset
= INTVAL (offset
);
19100 if (INTVAL (offset
) > entry
->offset
)
19101 entry
->offset
= INTVAL (offset
);
19104 return INTVAL (offset
) <= entry
->offset
;
19107 /* Search X for LO_SUMs and record them in HTAB. */
19110 mips_record_lo_sums (const_rtx x
, mips_offset_table
*htab
)
19112 subrtx_iterator::array_type array
;
19113 FOR_EACH_SUBRTX (iter
, array
, x
, NONCONST
)
19114 if (GET_CODE (*iter
) == LO_SUM
)
19115 mips_lo_sum_offset_lookup (htab
, XEXP (*iter
, 1), INSERT
);
19118 /* Return true if INSN is a SET of an orphaned high-part relocation.
19119 HTAB is a hash table of mips_lo_sum_offsets that describes all the
19120 LO_SUMs in the current function. */
19123 mips_orphaned_high_part_p (mips_offset_table
*htab
, rtx_insn
*insn
)
19125 enum mips_symbol_type type
;
19128 set
= single_set (insn
);
19131 /* Check for %his. */
19133 if (GET_CODE (x
) == HIGH
19134 && absolute_symbolic_operand (XEXP (x
, 0), VOIDmode
))
19135 return !mips_lo_sum_offset_lookup (htab
, XEXP (x
, 0), NO_INSERT
);
19137 /* Check for local %gots (and %got_pages, which is redundant but OK). */
19138 if (GET_CODE (x
) == UNSPEC
19139 && XINT (x
, 1) == UNSPEC_LOAD_GOT
19140 && mips_symbolic_constant_p (XVECEXP (x
, 0, 1),
19141 SYMBOL_CONTEXT_LEA
, &type
)
19142 && type
== SYMBOL_GOTOFF_PAGE
)
19143 return !mips_lo_sum_offset_lookup (htab
, XVECEXP (x
, 0, 1), NO_INSERT
);
19148 /* Subroutine of mips_avoid_hazard. We classify unconditional branches
19149 of interest for the P6600 for performance reasons. We're interested
19150 in differentiating BALC from JIC, JIALC and BC. */
19152 static enum mips_ucbranch_type
19153 mips_classify_branch_p6600 (rtx_insn
*insn
)
19155 /* We ignore sequences here as they represent a filled delay slot. */
19157 || !USEFUL_INSN_P (insn
)
19158 || GET_CODE (PATTERN (insn
)) == SEQUENCE
)
19159 return UC_UNDEFINED
;
19161 if (get_attr_jal (insn
) == JAL_INDIRECT
/* JIC and JIALC. */
19162 || get_attr_type (insn
) == TYPE_JUMP
) /* BC. */
19165 if (CALL_P (insn
) && get_attr_jal (insn
) == JAL_DIRECT
)
19168 return UC_UNDEFINED
;
19171 /* Subroutine of mips_reorg_process_insns. If there is a hazard between
19172 INSN and a previous instruction, avoid it by inserting nops after
19175 *DELAYED_REG and *HILO_DELAY describe the hazards that apply at
19176 this point. If *DELAYED_REG is non-null, INSN must wait a cycle
19177 before using the value of that register. *HILO_DELAY counts the
19178 number of instructions since the last hilo hazard (that is,
19179 the number of instructions since the last MFLO or MFHI).
19181 After inserting nops for INSN, update *DELAYED_REG and *HILO_DELAY
19182 for the next instruction.
19184 LO_REG is an rtx for the LO register, used in dependence checking. */
19187 mips_avoid_hazard (rtx_insn
*after
, rtx_insn
*insn
, int *hilo_delay
,
19188 rtx
*delayed_reg
, rtx lo_reg
, bool *fs_delay
)
19193 pattern
= PATTERN (insn
);
19195 /* Do not put the whole function in .set noreorder if it contains
19196 an asm statement. We don't know whether there will be hazards
19197 between the asm statement and the gcc-generated code. */
19198 if (GET_CODE (pattern
) == ASM_INPUT
|| asm_noperands (pattern
) >= 0)
19199 cfun
->machine
->all_noreorder_p
= false;
19201 /* Ignore zero-length instructions (barriers and the like). */
19202 ninsns
= get_attr_length (insn
) / 4;
19206 /* Work out how many nops are needed. Note that we only care about
19207 registers that are explicitly mentioned in the instruction's pattern.
19208 It doesn't matter that calls use the argument registers or that they
19209 clobber hi and lo. */
19210 if (*hilo_delay
< 2 && reg_set_p (lo_reg
, pattern
))
19211 nops
= 2 - *hilo_delay
;
19212 else if (*delayed_reg
!= 0 && reg_referenced_p (*delayed_reg
, pattern
))
19214 /* If processing a forbidden slot hazard then a NOP is required if the
19215 branch instruction was not in a sequence (as the sequence would
19216 imply it is not actually a compact branch anyway) and the current
19217 insn is not an inline asm, and can't go in a delay slot. */
19218 else if (*fs_delay
&& get_attr_can_delay (insn
) == CAN_DELAY_NO
19219 && GET_CODE (PATTERN (after
)) != SEQUENCE
19220 && GET_CODE (pattern
) != ASM_INPUT
19221 && asm_noperands (pattern
) < 0)
19223 /* The P6600's branch predictor can handle static sequences of back-to-back
19224 branches in the following cases:
19226 (1) BALC followed by any conditional compact branch
19227 (2) BALC followed by BALC
19229 Any other combinations of compact branches will incur performance
19230 penalty. Inserting a no-op only costs space as the dispatch unit will
19231 disregard the nop. */
19232 else if (TUNE_P6600
&& TARGET_CB_MAYBE
&& !optimize_size
19233 && ((mips_classify_branch_p6600 (after
) == UC_BALC
19234 && mips_classify_branch_p6600 (insn
) == UC_OTHER
)
19235 || (mips_classify_branch_p6600 (insn
) == UC_BALC
19236 && mips_classify_branch_p6600 (after
) == UC_OTHER
)))
19241 /* Insert the nops between this instruction and the previous one.
19242 Each new nop takes us further from the last hilo hazard. */
19243 *hilo_delay
+= nops
;
19245 /* Move to the next real instruction if we are inserting a NOP and this
19246 instruction is a call with debug information. The reason being that
19247 we can't separate the call from the debug info. */
19248 rtx_insn
*real_after
= after
;
19249 if (real_after
&& nops
&& CALL_P (real_after
))
19251 && (NOTE_P (NEXT_INSN (real_after
))
19252 || BARRIER_P (NEXT_INSN (real_after
))))
19253 real_after
= NEXT_INSN (real_after
);
19256 emit_insn_after (gen_hazard_nop (), real_after
);
19258 /* Set up the state for the next instruction. */
19259 *hilo_delay
+= ninsns
;
19262 if (INSN_CODE (insn
) >= 0)
19263 switch (get_attr_hazard (insn
))
19266 /* For the P6600, flag some unconditional branches as having a
19267 pseudo-forbidden slot. This will cause additional nop insertion
19268 or SEQUENCE breaking as required. This is for performance
19269 reasons not correctness. */
19273 && mips_classify_branch_p6600 (insn
) == UC_OTHER
)
19277 case HAZARD_FORBIDDEN_SLOT
:
19278 if (TARGET_CB_MAYBE
)
19287 set
= single_set (insn
);
19289 *delayed_reg
= SET_DEST (set
);
19294 /* Emit a speculation barrier.
19295 JR.HB is needed, so we put speculation_barrier_libfunc in libgcc. */
19297 mips_emit_speculation_barrier_function ()
19299 emit_library_call (speculation_barrier_libfunc
, LCT_NORMAL
, VOIDmode
);
19302 /* A SEQUENCE is breakable iff the branch inside it has a compact form
19303 and the target has compact branches. */
19306 mips_breakable_sequence_p (rtx_insn
*insn
)
19308 return (insn
&& GET_CODE (PATTERN (insn
)) == SEQUENCE
19310 && get_attr_compact_form (SEQ_BEGIN (insn
)) != COMPACT_FORM_NEVER
);
19313 /* Remove a SEQUENCE and replace it with the delay slot instruction
19314 followed by the branch and return the instruction in the delay slot.
19315 Return the first of the two new instructions.
19316 Subroutine of mips_reorg_process_insns. */
19319 mips_break_sequence (rtx_insn
*insn
)
19321 rtx_insn
*before
= PREV_INSN (insn
);
19322 rtx_insn
*branch
= SEQ_BEGIN (insn
);
19323 rtx_insn
*ds
= SEQ_END (insn
);
19324 remove_insn (insn
);
19325 add_insn_after (ds
, before
, NULL
);
19326 add_insn_after (branch
, ds
, NULL
);
19330 /* Go through the instruction stream and insert nops where necessary.
19331 Also delete any high-part relocations whose partnering low parts
19332 are now all dead. See if the whole function can then be put into
19333 .set noreorder and .set nomacro. */
19336 mips_reorg_process_insns (void)
19338 rtx_insn
*insn
, *last_insn
, *subinsn
, *next_insn
;
19339 rtx lo_reg
, delayed_reg
;
19343 /* Force all instructions to be split into their final form. */
19344 split_all_insns_noflow ();
19346 /* Recalculate instruction lengths without taking nops into account. */
19347 cfun
->machine
->ignore_hazard_length_p
= true;
19348 shorten_branches (get_insns ());
19350 cfun
->machine
->all_noreorder_p
= true;
19352 /* We don't track MIPS16 PC-relative offsets closely enough to make
19353 a good job of "set .noreorder" code in MIPS16 mode. */
19355 cfun
->machine
->all_noreorder_p
= false;
19357 /* Code that doesn't use explicit relocs can't be ".set nomacro". */
19358 if (!TARGET_EXPLICIT_RELOCS
)
19359 cfun
->machine
->all_noreorder_p
= false;
19361 /* Profiled functions can't be all noreorder because the profiler
19362 support uses assembler macros. */
19364 cfun
->machine
->all_noreorder_p
= false;
19366 /* Code compiled with -mfix-vr4120, -mfix-r5900, -mfix-rm7000 or
19367 -mfix-24k can't be all noreorder because we rely on the assembler
19368 to work around some errata. The R5900 target has several bugs. */
19369 if (TARGET_FIX_VR4120
19370 || TARGET_FIX_RM7000
19372 || TARGET_FIX_R5900
)
19373 cfun
->machine
->all_noreorder_p
= false;
19375 /* The same is true for -mfix-vr4130 if we might generate MFLO or
19376 MFHI instructions. Note that we avoid using MFLO and MFHI if
19377 the VR4130 MACC and DMACC instructions are available instead;
19378 see the *mfhilo_{si,di}_macc patterns. */
19379 if (TARGET_FIX_VR4130
&& !ISA_HAS_MACCHI
)
19380 cfun
->machine
->all_noreorder_p
= false;
19382 mips_offset_table
htab (37);
19384 /* Make a first pass over the instructions, recording all the LO_SUMs. */
19385 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
19386 FOR_EACH_SUBINSN (subinsn
, insn
)
19387 if (USEFUL_INSN_P (subinsn
))
19389 rtx body
= PATTERN (insn
);
19390 int noperands
= asm_noperands (body
);
19391 if (noperands
>= 0)
19393 rtx
*ops
= XALLOCAVEC (rtx
, noperands
);
19394 bool *used
= XALLOCAVEC (bool, noperands
);
19395 const char *string
= decode_asm_operands (body
, ops
, NULL
, NULL
,
19397 get_referenced_operands (string
, used
, noperands
);
19398 for (int i
= 0; i
< noperands
; ++i
)
19400 mips_record_lo_sums (ops
[i
], &htab
);
19403 mips_record_lo_sums (PATTERN (subinsn
), &htab
);
19409 lo_reg
= gen_rtx_REG (SImode
, LO_REGNUM
);
19412 /* Make a second pass over the instructions. Delete orphaned
19413 high-part relocations or turn them into NOPs. Avoid hazards
19414 by inserting NOPs. */
19415 for (insn
= get_insns (); insn
!= 0; insn
= next_insn
)
19417 next_insn
= NEXT_INSN (insn
);
19418 if (USEFUL_INSN_P (insn
))
19420 if (GET_CODE (PATTERN (insn
)) == SEQUENCE
)
19422 rtx_insn
*next_active
= next_active_insn (insn
);
19423 /* Undo delay slots to avoid bubbles if the next instruction can
19424 be placed in a forbidden slot or the cost of adding an
19425 explicit NOP in a forbidden slot is OK and if the SEQUENCE is
19426 safely breakable. */
19427 if (TARGET_CB_MAYBE
19428 && mips_breakable_sequence_p (insn
)
19429 && INSN_P (SEQ_BEGIN (insn
))
19430 && INSN_P (SEQ_END (insn
))
19432 && INSN_P (next_active
)
19433 && GET_CODE (PATTERN (next_active
)) != SEQUENCE
19434 && get_attr_can_delay (next_active
) == CAN_DELAY_YES
)
19435 || !optimize_size
))
19437 /* To hide a potential pipeline bubble, if we scan backwards
19438 from the current SEQUENCE and find that there is a load
19439 of a value that is used in the CTI and there are no
19440 dependencies between the CTI and instruction in the delay
19441 slot, break the sequence so the load delay is hidden. */
19443 CLEAR_HARD_REG_SET (uses
);
19444 note_uses (&PATTERN (SEQ_BEGIN (insn
)), record_hard_reg_uses
,
19446 HARD_REG_SET delay_sets
;
19447 CLEAR_HARD_REG_SET (delay_sets
);
19448 note_stores (SEQ_END (insn
), record_hard_reg_sets
,
19451 rtx_insn
*prev
= prev_active_insn (insn
);
19453 && GET_CODE (PATTERN (prev
)) == SET
19454 && MEM_P (SET_SRC (PATTERN (prev
))))
19457 CLEAR_HARD_REG_SET (sets
);
19458 note_stores (prev
, record_hard_reg_sets
, &sets
);
19460 /* Re-order if safe. */
19461 if (!hard_reg_set_intersect_p (delay_sets
, uses
)
19462 && hard_reg_set_intersect_p (uses
, sets
))
19464 next_insn
= mips_break_sequence (insn
);
19465 /* Need to process the hazards of the newly
19466 introduced instructions. */
19471 /* If we find an orphaned high-part relocation in a delay
19472 slot then we can convert to a compact branch and get
19473 the orphaned high part deleted. */
19474 if (mips_orphaned_high_part_p (&htab
, SEQ_END (insn
)))
19476 next_insn
= mips_break_sequence (insn
);
19477 /* Need to process the hazards of the newly
19478 introduced instructions. */
19483 /* If we find an orphaned high-part relocation in a delay
19484 slot, it's easier to turn that instruction into a NOP than
19485 to delete it. The delay slot will be a NOP either way. */
19486 FOR_EACH_SUBINSN (subinsn
, insn
)
19487 if (INSN_P (subinsn
))
19489 if (mips_orphaned_high_part_p (&htab
, subinsn
))
19491 PATTERN (subinsn
) = gen_nop ();
19492 INSN_CODE (subinsn
) = CODE_FOR_nop
;
19494 mips_avoid_hazard (last_insn
, subinsn
, &hilo_delay
,
19495 &delayed_reg
, lo_reg
, &fs_delay
);
19501 /* INSN is a single instruction. Delete it if it's an
19502 orphaned high-part relocation. */
19503 if (mips_orphaned_high_part_p (&htab
, insn
))
19504 delete_insn (insn
);
19505 /* Also delete cache barriers if the last instruction
19506 was an annulled branch. INSN will not be speculatively
19508 else if (recog_memoized (insn
) == CODE_FOR_r10k_cache_barrier
19510 && JUMP_P (SEQ_BEGIN (last_insn
))
19511 && INSN_ANNULLED_BRANCH_P (SEQ_BEGIN (last_insn
)))
19512 delete_insn (insn
);
19515 mips_avoid_hazard (last_insn
, insn
, &hilo_delay
,
19516 &delayed_reg
, lo_reg
, &fs_delay
);
19517 /* When a compact branch introduces a forbidden slot hazard
19518 and the next useful instruction is a SEQUENCE of a jump
19519 and a non-nop instruction in the delay slot, remove the
19520 sequence and replace it with the delay slot instruction
19521 then the jump to clear the forbidden slot hazard.
19523 For the P6600, this optimisation solves the performance
19524 penalty associated with BALC followed by a delay slot
19525 branch. We do not set fs_delay as we do not want
19526 the full logic of a forbidden slot; the penalty exists
19527 only against branches not the full class of forbidden
19528 slot instructions. */
19530 if (fs_delay
|| (TUNE_P6600
19532 && mips_classify_branch_p6600 (insn
)
19535 /* Search onwards from the current position looking for
19536 a SEQUENCE. We are looking for pipeline hazards here
19537 and do not need to worry about labels or barriers as
19538 the optimization only undoes delay slot filling which
19539 only affects the order of the branch and its delay
19541 rtx_insn
*next
= next_active_insn (insn
);
19543 && USEFUL_INSN_P (next
)
19544 && GET_CODE (PATTERN (next
)) == SEQUENCE
19545 && mips_breakable_sequence_p (next
))
19548 next_insn
= mips_break_sequence (next
);
19549 /* Need to process the hazards of the newly
19550 introduced instructions. */
19561 /* Return true if the function has a long branch instruction. */
19564 mips_has_long_branch_p (void)
19566 rtx_insn
*insn
, *subinsn
;
19569 /* We need up-to-date instruction lengths. */
19570 shorten_branches (get_insns ());
19572 /* Look for a branch that is longer than normal. The normal length for
19573 non-MIPS16 branches is 8, because the length includes the delay slot.
19574 It is 4 for MIPS16, because MIPS16 branches are extended instructions,
19575 but they have no delay slot. */
19576 normal_length
= (TARGET_MIPS16
? 4 : 8);
19577 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
19578 FOR_EACH_SUBINSN (subinsn
, insn
)
19579 if (JUMP_P (subinsn
)
19580 && get_attr_length (subinsn
) > normal_length
19581 && (any_condjump_p (subinsn
) || any_uncondjump_p (subinsn
)))
19587 /* If we are using a GOT, but have not decided to use a global pointer yet,
19588 see whether we need one to implement long branches. Convert the ghost
19589 global-pointer instructions into real ones if so. */
19592 mips_expand_ghost_gp_insns (void)
19594 /* Quick exit if we already know that we will or won't need a
19596 if (!TARGET_USE_GOT
19597 || cfun
->machine
->global_pointer
== INVALID_REGNUM
19598 || mips_must_initialize_gp_p ())
19601 /* Run a full check for long branches. */
19602 if (!mips_has_long_branch_p ())
19605 /* We've now established that we need $gp. */
19606 cfun
->machine
->must_initialize_gp_p
= true;
19607 split_all_insns_noflow ();
19612 /* Subroutine of mips_reorg to manage passes that require DF. */
19615 mips_df_reorg (void)
19617 /* Create def-use chains. */
19618 df_set_flags (DF_EQ_NOTES
);
19619 df_chain_add_problem (DF_UD_CHAIN
);
19622 if (TARGET_RELAX_PIC_CALLS
)
19623 mips_annotate_pic_calls ();
19625 if (mips_r10k_cache_barrier
!= R10K_CACHE_BARRIER_NONE
)
19626 r10k_insert_cache_barriers ();
19628 df_finish_pass (false);
19631 /* Emit code to load LABEL_REF SRC into MIPS16 register DEST. This is
19632 called very late in mips_reorg, but the caller is required to run
19633 mips16_lay_out_constants on the result. */
19636 mips16_load_branch_target (rtx dest
, rtx src
)
19638 if (TARGET_ABICALLS
&& !TARGET_ABSOLUTE_ABICALLS
)
19642 if (mips_cfun_has_cprestore_slot_p ())
19643 mips_emit_move (dest
, mips_cprestore_slot (dest
, true));
19645 mips_emit_move (dest
, pic_offset_table_rtx
);
19646 page
= mips_unspec_address (src
, SYMBOL_GOTOFF_PAGE
);
19647 low
= mips_unspec_address (src
, SYMBOL_GOT_PAGE_OFST
);
19648 emit_insn (gen_rtx_SET (dest
,
19649 PMODE_INSN (gen_unspec_got
, (dest
, page
))));
19650 emit_insn (gen_rtx_SET (dest
, gen_rtx_LO_SUM (Pmode
, dest
, low
)));
19654 src
= mips_unspec_address (src
, SYMBOL_ABSOLUTE
);
19655 mips_emit_move (dest
, src
);
19659 /* If we're compiling a MIPS16 function, look for and split any long branches.
19660 This must be called after all other instruction modifications in
19664 mips16_split_long_branches (void)
19666 bool something_changed
;
19668 if (!TARGET_MIPS16
)
19671 /* Loop until the alignments for all targets are sufficient. */
19675 rtx_jump_insn
*jump_insn
;
19677 shorten_branches (get_insns ());
19678 something_changed
= false;
19679 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
19680 if ((jump_insn
= dyn_cast
<rtx_jump_insn
*> (insn
))
19681 && get_attr_length (jump_insn
) > 4
19682 && (any_condjump_p (jump_insn
) || any_uncondjump_p (jump_insn
)))
19684 rtx old_label
, temp
, saved_temp
;
19685 rtx_code_label
*new_label
;
19687 rtx_insn
*jump
, *jump_sequence
;
19691 /* Free up a MIPS16 register by saving it in $1. */
19692 saved_temp
= gen_rtx_REG (Pmode
, AT_REGNUM
);
19693 temp
= gen_rtx_REG (Pmode
, GP_REG_FIRST
+ 2);
19694 emit_move_insn (saved_temp
, temp
);
19696 /* Load the branch target into TEMP. */
19697 old_label
= JUMP_LABEL (jump_insn
);
19698 target
= gen_rtx_LABEL_REF (Pmode
, old_label
);
19699 mips16_load_branch_target (temp
, target
);
19701 /* Jump to the target and restore the register's
19703 jump
= emit_jump_insn (PMODE_INSN (gen_indirect_jump_and_restore
,
19704 (temp
, temp
, saved_temp
)));
19705 JUMP_LABEL (jump
) = old_label
;
19706 LABEL_NUSES (old_label
)++;
19708 /* Rewrite any symbolic references that are supposed to use
19709 a PC-relative constant pool. */
19710 mips16_lay_out_constants (false);
19712 if (simplejump_p (jump_insn
))
19713 /* We're going to replace INSN with a longer form. */
19717 /* Create a branch-around label for the original
19719 new_label
= gen_label_rtx ();
19720 emit_label (new_label
);
19723 jump_sequence
= get_insns ();
19726 emit_insn_after (jump_sequence
, jump_insn
);
19728 invert_jump (jump_insn
, new_label
, false);
19730 delete_insn (jump_insn
);
19731 something_changed
= true;
19734 while (something_changed
);
19737 /* Insert a `.insn' assembly pseudo-op after any labels followed by
19738 a MIPS16 constant pool or no insn at all. This is needed so that
19739 targets that have been optimized away are still marked as code
19740 and therefore branches that remained and point to them are known
19741 to retain the ISA mode and as such can be successfully assembled. */
19744 mips_insert_insn_pseudos (void)
19746 bool insn_pseudo_needed
= TRUE
;
19749 for (insn
= get_last_insn (); insn
!= NULL_RTX
; insn
= PREV_INSN (insn
))
19750 switch (GET_CODE (insn
))
19753 if (GET_CODE (PATTERN (insn
)) == UNSPEC_VOLATILE
19754 && XINT (PATTERN (insn
), 1) == UNSPEC_CONSTTABLE
)
19756 insn_pseudo_needed
= TRUE
;
19759 /* Fall through. */
19762 case JUMP_TABLE_DATA
:
19763 insn_pseudo_needed
= FALSE
;
19766 if (insn_pseudo_needed
)
19768 emit_insn_after (gen_insn_pseudo (), insn
);
19769 insn_pseudo_needed
= FALSE
;
19777 /* Implement TARGET_MACHINE_DEPENDENT_REORG. */
19782 /* Restore the BLOCK_FOR_INSN pointers, which are needed by DF. Also during
19783 insn splitting in mips16_lay_out_constants, DF insn info is only kept up
19784 to date if the CFG is available. */
19785 if (mips_cfg_in_reorg ())
19786 compute_bb_for_insn ();
19787 mips16_lay_out_constants (true);
19788 if (mips_cfg_in_reorg ())
19791 free_bb_for_insn ();
19795 /* We use a machine specific pass to do a second machine dependent reorg
19796 pass after delay branch scheduling. */
19798 static unsigned int
19799 mips_machine_reorg2 (void)
19801 mips_reorg_process_insns ();
19803 && TARGET_EXPLICIT_RELOCS
19805 && TARGET_VR4130_ALIGN
)
19806 vr4130_align_insns ();
19807 if (mips_expand_ghost_gp_insns ())
19808 /* The expansion could invalidate some of the VR4130 alignment
19809 optimizations, but this should be an extremely rare case anyhow. */
19810 mips_reorg_process_insns ();
19811 mips16_split_long_branches ();
19812 mips_insert_insn_pseudos ();
19818 const pass_data pass_data_mips_machine_reorg2
=
19820 RTL_PASS
, /* type */
19821 "mach2", /* name */
19822 OPTGROUP_NONE
, /* optinfo_flags */
19823 TV_MACH_DEP
, /* tv_id */
19824 0, /* properties_required */
19825 0, /* properties_provided */
19826 0, /* properties_destroyed */
19827 0, /* todo_flags_start */
19828 0, /* todo_flags_finish */
19831 class pass_mips_machine_reorg2
: public rtl_opt_pass
19834 pass_mips_machine_reorg2(gcc::context
*ctxt
)
19835 : rtl_opt_pass(pass_data_mips_machine_reorg2
, ctxt
)
19838 /* opt_pass methods: */
19839 virtual unsigned int execute (function
*) { return mips_machine_reorg2 (); }
19841 }; // class pass_mips_machine_reorg2
19843 } // anon namespace
19846 make_pass_mips_machine_reorg2 (gcc::context
*ctxt
)
19848 return new pass_mips_machine_reorg2 (ctxt
);
19852 /* Implement TARGET_ASM_OUTPUT_MI_THUNK. Generate rtl rather than asm text
19853 in order to avoid duplicating too much logic from elsewhere. */
19856 mips_output_mi_thunk (FILE *file
, tree thunk_fndecl ATTRIBUTE_UNUSED
,
19857 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
19860 const char *fnname
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl
));
19861 rtx this_rtx
, temp1
, temp2
, fnaddr
;
19863 bool use_sibcall_p
;
19865 /* Pretend to be a post-reload pass while generating rtl. */
19866 reload_completed
= 1;
19868 /* Mark the end of the (empty) prologue. */
19869 emit_note (NOTE_INSN_PROLOGUE_END
);
19871 /* Determine if we can use a sibcall to call FUNCTION directly. */
19872 fnaddr
= XEXP (DECL_RTL (function
), 0);
19873 use_sibcall_p
= (mips_function_ok_for_sibcall (function
, NULL
)
19874 && const_call_insn_operand (fnaddr
, Pmode
));
19876 /* Determine if we need to load FNADDR from the GOT. */
19878 && (mips_got_symbol_type_p
19879 (mips_classify_symbol (fnaddr
, SYMBOL_CONTEXT_LEA
))))
19881 /* Pick a global pointer. Use a call-clobbered register if
19882 TARGET_CALL_SAVED_GP. */
19883 cfun
->machine
->global_pointer
19884 = TARGET_CALL_SAVED_GP
? 15 : GLOBAL_POINTER_REGNUM
;
19885 cfun
->machine
->must_initialize_gp_p
= true;
19886 SET_REGNO (pic_offset_table_rtx
, cfun
->machine
->global_pointer
);
19888 /* Set up the global pointer for n32 or n64 abicalls. */
19889 mips_emit_loadgp ();
19892 /* We need two temporary registers in some cases. */
19893 temp1
= gen_rtx_REG (Pmode
, 2);
19894 temp2
= gen_rtx_REG (Pmode
, 3);
19896 /* Find out which register contains the "this" pointer. */
19897 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
19898 this_rtx
= gen_rtx_REG (Pmode
, GP_ARG_FIRST
+ 1);
19900 this_rtx
= gen_rtx_REG (Pmode
, GP_ARG_FIRST
);
19902 /* Add DELTA to THIS_RTX. */
19905 rtx offset
= GEN_INT (delta
);
19906 if (!SMALL_OPERAND (delta
))
19908 mips_emit_move (temp1
, offset
);
19911 emit_insn (gen_add3_insn (this_rtx
, this_rtx
, offset
));
19914 /* If needed, add *(*THIS_RTX + VCALL_OFFSET) to THIS_RTX. */
19915 if (vcall_offset
!= 0)
19919 /* Set TEMP1 to *THIS_RTX. */
19920 mips_emit_move (temp1
, gen_rtx_MEM (Pmode
, this_rtx
));
19922 /* Set ADDR to a legitimate address for *THIS_RTX + VCALL_OFFSET. */
19923 addr
= mips_add_offset (temp2
, temp1
, vcall_offset
);
19925 /* Load the offset and add it to THIS_RTX. */
19926 mips_emit_move (temp1
, gen_rtx_MEM (Pmode
, addr
));
19927 emit_insn (gen_add3_insn (this_rtx
, this_rtx
, temp1
));
19930 /* Jump to the target function. Use a sibcall if direct jumps are
19931 allowed, otherwise load the address into a register first. */
19934 insn
= emit_call_insn (gen_sibcall_internal (fnaddr
, const0_rtx
));
19935 SIBLING_CALL_P (insn
) = 1;
19939 /* This is messy. GAS treats "la $25,foo" as part of a call
19940 sequence and may allow a global "foo" to be lazily bound.
19941 The general move patterns therefore reject this combination.
19943 In this context, lazy binding would actually be OK
19944 for TARGET_CALL_CLOBBERED_GP, but it's still wrong for
19945 TARGET_CALL_SAVED_GP; see mips_load_call_address.
19946 We must therefore load the address via a temporary
19947 register if mips_dangerous_for_la25_p.
19949 If we jump to the temporary register rather than $25,
19950 the assembler can use the move insn to fill the jump's
19953 We can use the same technique for MIPS16 code, where $25
19954 is not a valid JR register. */
19955 if (TARGET_USE_PIC_FN_ADDR_REG
19957 && !mips_dangerous_for_la25_p (fnaddr
))
19958 temp1
= gen_rtx_REG (Pmode
, PIC_FUNCTION_ADDR_REGNUM
);
19959 mips_load_call_address (MIPS_CALL_SIBCALL
, temp1
, fnaddr
);
19961 if (TARGET_USE_PIC_FN_ADDR_REG
19962 && REGNO (temp1
) != PIC_FUNCTION_ADDR_REGNUM
)
19963 mips_emit_move (gen_rtx_REG (Pmode
, PIC_FUNCTION_ADDR_REGNUM
), temp1
);
19964 emit_jump_insn (gen_indirect_jump (temp1
));
19967 /* Run just enough of rest_of_compilation. This sequence was
19968 "borrowed" from alpha.cc. */
19969 insn
= get_insns ();
19970 split_all_insns_noflow ();
19971 mips16_lay_out_constants (true);
19972 shorten_branches (insn
);
19973 assemble_start_function (thunk_fndecl
, fnname
);
19974 final_start_function (insn
, file
, 1);
19975 final (insn
, file
, 1);
19976 final_end_function ();
19977 assemble_end_function (thunk_fndecl
, fnname
);
19979 /* Clean up the vars set above. Note that final_end_function resets
19980 the global pointer for us. */
19981 reload_completed
= 0;
19985 /* The last argument passed to mips_set_compression_mode,
19986 or negative if the function hasn't been called yet. */
19987 static unsigned int old_compression_mode
= -1;
19989 /* Set up the target-dependent global state for ISA mode COMPRESSION_MODE,
19990 which is either MASK_MIPS16 or MASK_MICROMIPS. */
19993 mips_set_compression_mode (unsigned int compression_mode
)
19996 if (compression_mode
== old_compression_mode
)
19999 /* Restore base settings of various flags. */
20000 target_flags
= mips_base_target_flags
;
20001 flag_schedule_insns
= mips_base_schedule_insns
;
20002 flag_reorder_blocks_and_partition
= mips_base_reorder_blocks_and_partition
;
20003 flag_move_loop_invariants
= mips_base_move_loop_invariants
;
20004 str_align_loops
= mips_base_align_loops
;
20005 str_align_jumps
= mips_base_align_jumps
;
20006 str_align_functions
= mips_base_align_functions
;
20007 target_flags
&= ~(MASK_MIPS16
| MASK_MICROMIPS
);
20008 target_flags
|= compression_mode
;
20010 if (compression_mode
& MASK_MIPS16
)
20012 /* Switch to MIPS16 mode. */
20013 target_flags
|= MASK_MIPS16
;
20015 /* Turn off SYNCI if it was on, MIPS16 doesn't support it. */
20016 target_flags
&= ~MASK_SYNCI
;
20018 /* Don't run the scheduler before reload, since it tends to
20019 increase register pressure. */
20020 flag_schedule_insns
= 0;
20022 /* Don't do hot/cold partitioning. mips16_lay_out_constants expects
20023 the whole function to be in a single section. */
20024 flag_reorder_blocks_and_partition
= 0;
20026 /* Don't move loop invariants, because it tends to increase
20027 register pressure. It also introduces an extra move in cases
20028 where the constant is the first operand in a two-operand binary
20029 instruction, or when it forms a register argument to a functon
20031 flag_move_loop_invariants
= 0;
20033 target_flags
|= MASK_EXPLICIT_RELOCS
;
20035 /* Experiments suggest we get the best overall section-anchor
20036 results from using the range of an unextended LW or SW. Code
20037 that makes heavy use of byte or short accesses can do better
20038 with ranges of 0...31 and 0...63 respectively, but most code is
20039 sensitive to the range of LW and SW instead. */
20040 targetm
.min_anchor_offset
= 0;
20041 targetm
.max_anchor_offset
= 127;
20043 targetm
.const_anchor
= 0;
20045 /* MIPS16 has no BAL instruction. */
20046 target_flags
&= ~MASK_RELAX_PIC_CALLS
;
20048 /* The R4000 errata don't apply to any known MIPS16 cores.
20049 It's simpler to make the R4000 fixes and MIPS16 mode
20050 mutually exclusive. */
20051 target_flags
&= ~MASK_FIX_R4000
;
20053 if (flag_pic
&& !TARGET_OLDABI
)
20054 sorry ("MIPS16 PIC for ABIs other than o32 and o64");
20057 sorry ("MIPS16 %<-mxgot%> code");
20059 if (TARGET_HARD_FLOAT_ABI
&& !TARGET_OLDABI
)
20060 sorry ("%<hard-float%> MIPS16 code for ABIs other than o32 and o64");
20063 sorry ("MSA MIPS16 code");
20067 /* Switch to microMIPS or the standard encoding. */
20069 if (TARGET_MICROMIPS
)
20070 /* Avoid branch likely. */
20071 target_flags
&= ~MASK_BRANCHLIKELY
;
20073 /* Provide default values for align_* for 64-bit targets. */
20076 if (flag_align_loops
&& !str_align_loops
)
20077 str_align_loops
= "8";
20078 if (flag_align_jumps
&& !str_align_jumps
)
20079 str_align_jumps
= "8";
20080 if (flag_align_functions
&& !str_align_functions
)
20081 str_align_functions
= "8";
20084 targetm
.min_anchor_offset
= -32768;
20085 targetm
.max_anchor_offset
= 32767;
20087 targetm
.const_anchor
= 0x8000;
20090 /* (Re)initialize MIPS target internals for new ISA. */
20091 mips_init_relocs ();
20093 if (compression_mode
& MASK_MIPS16
)
20095 if (!mips16_globals
)
20096 mips16_globals
= save_target_globals_default_opts ();
20098 restore_target_globals (mips16_globals
);
20100 else if (compression_mode
& MASK_MICROMIPS
)
20102 if (!micromips_globals
)
20103 micromips_globals
= save_target_globals_default_opts ();
20105 restore_target_globals (micromips_globals
);
20108 restore_target_globals (&default_target_globals
);
20110 old_compression_mode
= compression_mode
;
20113 /* Implement TARGET_SET_CURRENT_FUNCTION. Decide whether the current
20114 function should use the MIPS16 or microMIPS ISA and switch modes
20115 accordingly. Also set the current code_readable mode. */
20118 mips_set_current_function (tree fndecl
)
20120 enum mips_code_readable_setting old_code_readable
= mips_code_readable
;
20122 mips_set_compression_mode (mips_get_compress_mode (fndecl
));
20124 mips_code_readable
= mips_get_code_readable_attr (fndecl
);
20126 /* Since the mips_code_readable setting has potentially changed, the
20127 relocation tables must be reinitialized. Otherwise GCC will not
20128 split symbols for functions that are code_readable ("no") when others
20129 are code_readable ("yes") and ICE later on in places such as
20130 mips_emit_move. Ditto for similar paired cases. It must be restored
20131 to its previous state as well. */
20132 if (old_code_readable
!= mips_code_readable
)
20133 mips_init_relocs ();
20136 /* Allocate a chunk of memory for per-function machine-dependent data. */
20138 static struct machine_function
*
20139 mips_init_machine_status (void)
20141 return ggc_cleared_alloc
<machine_function
> ();
20144 /* Return the processor associated with the given ISA level, or null
20145 if the ISA isn't valid. */
20147 static const struct mips_cpu_info
*
20148 mips_cpu_info_from_isa (int isa
)
20152 for (i
= 0; i
< ARRAY_SIZE (mips_cpu_info_table
); i
++)
20153 if (mips_cpu_info_table
[i
].isa
== isa
)
20154 return mips_cpu_info_table
+ i
;
20159 /* Return a mips_cpu_info entry determined by an option valued
20162 static const struct mips_cpu_info
*
20163 mips_cpu_info_from_opt (int opt
)
20167 case MIPS_ARCH_OPTION_FROM_ABI
:
20168 /* 'from-abi' selects the most compatible architecture for the
20169 given ABI: MIPS I for 32-bit ABIs and MIPS III for 64-bit
20170 ABIs. For the EABIs, we have to decide whether we're using
20171 the 32-bit or 64-bit version. */
20172 return mips_cpu_info_from_isa (ABI_NEEDS_32BIT_REGS
? 1
20173 : ABI_NEEDS_64BIT_REGS
? 3
20174 : (TARGET_64BIT
? 3 : 1));
20176 case MIPS_ARCH_OPTION_NATIVE
:
20177 gcc_unreachable ();
20180 return &mips_cpu_info_table
[opt
];
20184 /* Return a default mips_cpu_info entry, given that no -march= option
20185 was explicitly specified. */
20187 static const struct mips_cpu_info
*
20188 mips_default_arch (void)
20190 #if defined (MIPS_CPU_STRING_DEFAULT)
20192 for (i
= 0; i
< ARRAY_SIZE (mips_cpu_info_table
); i
++)
20193 if (strcmp (mips_cpu_info_table
[i
].name
, MIPS_CPU_STRING_DEFAULT
) == 0)
20194 return mips_cpu_info_table
+ i
;
20195 gcc_unreachable ();
20196 #elif defined (MIPS_ISA_DEFAULT)
20197 return mips_cpu_info_from_isa (MIPS_ISA_DEFAULT
);
20199 /* 'from-abi' makes a good default: you get whatever the ABI
20201 return mips_cpu_info_from_opt (MIPS_ARCH_OPTION_FROM_ABI
);
20205 /* Set up globals to generate code for the ISA or processor
20206 described by INFO. */
20209 mips_set_architecture (const struct mips_cpu_info
*info
)
20213 mips_arch_info
= info
;
20214 mips_arch
= info
->cpu
;
20215 mips_isa
= info
->isa
;
20216 if (mips_isa
< MIPS_ISA_MIPS32
)
20219 /* we can do this is due to the
20220 * enum of MIPS32rN is from 32 to 37
20221 * enum of MIPS64rN is from 64 to 69 */
20222 mips_isa_rev
= (mips_isa
& 31) + 1;
20226 /* Likewise for tuning. */
20229 mips_set_tune (const struct mips_cpu_info
*info
)
20233 mips_tune_info
= info
;
20234 mips_tune
= info
->cpu
;
20238 /* Implement TARGET_OPTION_OVERRIDE. */
20241 mips_option_override (void)
20243 int i
, regno
, mode
;
20245 if (OPTION_SET_P (mips_isa_option
))
20246 mips_isa_option_info
= &mips_cpu_info_table
[mips_isa_option
];
20248 #ifdef SUBTARGET_OVERRIDE_OPTIONS
20249 SUBTARGET_OVERRIDE_OPTIONS
;
20252 /* MIPS16 and microMIPS cannot coexist. */
20253 if (TARGET_MICROMIPS
&& TARGET_MIPS16
)
20254 error ("unsupported combination: %s", "-mips16 -mmicromips");
20256 /* Prohibit Paired-Single and MSA combination. This is software restriction
20257 rather than architectural. */
20258 if (ISA_HAS_MSA
&& TARGET_PAIRED_SINGLE_FLOAT
)
20259 error ("unsupported combination: %s", "-mmsa -mpaired-single");
20261 /* Save the base compression state and process flags as though we
20262 were generating uncompressed code. */
20263 mips_base_compression_flags
= TARGET_COMPRESSION
;
20264 target_flags
&= ~TARGET_COMPRESSION
;
20265 mips_base_code_readable
= mips_code_readable
;
20267 /* -mno-float overrides -mhard-float and -msoft-float. */
20268 if (TARGET_NO_FLOAT
)
20270 target_flags
|= MASK_SOFT_FLOAT_ABI
;
20271 target_flags_explicit
|= MASK_SOFT_FLOAT_ABI
;
20274 if (TARGET_FLIP_MIPS16
)
20275 TARGET_INTERLINK_COMPRESSED
= 1;
20277 /* Set the small data limit. */
20278 mips_small_data_threshold
= (OPTION_SET_P (g_switch_value
)
20280 : MIPS_DEFAULT_GVALUE
);
20282 /* The following code determines the architecture and register size.
20283 Similar code was added to GAS 2.14 (see tc-mips.c:md_after_parse_args()).
20284 The GAS and GCC code should be kept in sync as much as possible. */
20286 if (OPTION_SET_P (mips_arch_option
))
20287 mips_set_architecture (mips_cpu_info_from_opt (mips_arch_option
));
20289 if (mips_isa_option_info
!= 0)
20291 if (mips_arch_info
== 0)
20292 mips_set_architecture (mips_isa_option_info
);
20293 else if (mips_arch_info
->isa
!= mips_isa_option_info
->isa
)
20294 error ("%<-%s%> conflicts with the other architecture options, "
20295 "which specify a %s processor",
20296 mips_isa_option_info
->name
,
20297 mips_cpu_info_from_isa (mips_arch_info
->isa
)->name
);
20300 if (mips_arch_info
== 0)
20301 mips_set_architecture (mips_default_arch ());
20303 if (ABI_NEEDS_64BIT_REGS
&& !ISA_HAS_64BIT_REGS
)
20304 error ("%<-march=%s%> is not compatible with the selected ABI",
20305 mips_arch_info
->name
);
20307 /* Optimize for mips_arch, unless -mtune selects a different processor. */
20308 if (OPTION_SET_P (mips_tune_option
))
20309 mips_set_tune (mips_cpu_info_from_opt (mips_tune_option
));
20311 if (mips_tune_info
== 0)
20312 mips_set_tune (mips_arch_info
);
20314 if ((target_flags_explicit
& MASK_64BIT
) != 0)
20316 /* The user specified the size of the integer registers. Make sure
20317 it agrees with the ABI and ISA. */
20318 if (TARGET_64BIT
&& !ISA_HAS_64BIT_REGS
)
20319 error ("%<-mgp64%> used with a 32-bit processor");
20320 else if (!TARGET_64BIT
&& ABI_NEEDS_64BIT_REGS
)
20321 error ("%<-mgp32%> used with a 64-bit ABI");
20322 else if (TARGET_64BIT
&& ABI_NEEDS_32BIT_REGS
)
20323 error ("%<-mgp64%> used with a 32-bit ABI");
20327 /* Infer the integer register size from the ABI and processor.
20328 Restrict ourselves to 32-bit registers if that's all the
20329 processor has, or if the ABI cannot handle 64-bit registers. */
20330 if (ABI_NEEDS_32BIT_REGS
|| !ISA_HAS_64BIT_REGS
)
20331 target_flags
&= ~MASK_64BIT
;
20333 target_flags
|= MASK_64BIT
;
20336 /* -fsanitize=address needs to turn on -fasynchronous-unwind-tables in
20337 order for tracebacks to be complete but not if any
20338 -fasynchronous-unwind-table were already specified. */
20339 if (flag_sanitize
& SANITIZE_USER_ADDRESS
20340 && !global_options_set
.x_flag_asynchronous_unwind_tables
)
20341 flag_asynchronous_unwind_tables
= 1;
20343 if ((target_flags_explicit
& MASK_FLOAT64
) != 0)
20345 if (mips_isa_rev
>= 6 && !TARGET_FLOAT64
)
20346 error ("the %qs architecture does not support %<-mfp32%>",
20347 mips_arch_info
->name
);
20348 else if (TARGET_SINGLE_FLOAT
&& TARGET_FLOAT64
)
20349 error ("unsupported combination: %s", "-mfp64 -msingle-float");
20350 else if (TARGET_64BIT
&& TARGET_DOUBLE_FLOAT
&& !TARGET_FLOAT64
)
20351 error ("unsupported combination: %s", "-mgp64 -mfp32 -mdouble-float");
20352 else if (!TARGET_64BIT
&& TARGET_FLOAT64
)
20354 if (!ISA_HAS_MXHC1
)
20355 error ("%<-mgp32%> and %<-mfp64%> can only be combined if"
20356 " the target supports the mfhc1 and mthc1 instructions");
20357 else if (mips_abi
!= ABI_32
)
20358 error ("%<-mgp32%> and %<-mfp64%> can only be combined when using"
20364 /* -msingle-float selects 32-bit float registers. On r6 and later,
20365 -mdouble-float selects 64-bit float registers, since the old paired
20366 register model is not supported. In other cases the float registers
20367 should be the same size as the integer ones. */
20368 if (mips_isa_rev
>= 6 && TARGET_DOUBLE_FLOAT
&& !TARGET_FLOATXX
)
20369 target_flags
|= MASK_FLOAT64
;
20370 else if (TARGET_64BIT
&& TARGET_DOUBLE_FLOAT
)
20371 target_flags
|= MASK_FLOAT64
;
20372 else if (mips_abi
== ABI_32
&& ISA_HAS_MSA
&& !TARGET_FLOATXX
)
20373 target_flags
|= MASK_FLOAT64
;
20375 target_flags
&= ~MASK_FLOAT64
;
20378 if (mips_abi
!= ABI_32
&& TARGET_FLOATXX
)
20379 error ("%<-mfpxx%> can only be used with the o32 ABI");
20380 else if (TARGET_FLOAT64
&& TARGET_FLOATXX
)
20381 error ("unsupported combination: %s", "-mfp64 -mfpxx");
20382 else if (ISA_MIPS1
&& !TARGET_FLOAT32
)
20383 error ("%<-march=%s%> requires %<-mfp32%>", mips_arch_info
->name
);
20384 else if (TARGET_FLOATXX
&& !mips_lra_flag
)
20385 error ("%<-mfpxx%> requires %<-mlra%>");
20387 /* End of code shared with GAS. */
20389 /* The R5900 FPU only supports single precision. */
20390 if (TARGET_MIPS5900
&& TARGET_HARD_FLOAT_ABI
&& TARGET_DOUBLE_FLOAT
)
20391 error ("unsupported combination: %s",
20392 "-march=r5900 -mhard-float -mdouble-float");
20394 /* If a -mlong* option was given, check that it matches the ABI,
20395 otherwise infer the -mlong* setting from the other options. */
20396 if ((target_flags_explicit
& MASK_LONG64
) != 0)
20400 if (mips_abi
== ABI_N32
)
20401 error ("%qs is incompatible with %qs", "-mabi=n32", "-mlong64");
20402 else if (mips_abi
== ABI_32
)
20403 error ("%qs is incompatible with %qs", "-mabi=32", "-mlong64");
20404 else if (mips_abi
== ABI_O64
&& TARGET_ABICALLS
)
20405 /* We have traditionally allowed non-abicalls code to use
20406 an LP64 form of o64. However, it would take a bit more
20407 effort to support the combination of 32-bit GOT entries
20408 and 64-bit pointers, so we treat the abicalls case as
20410 error ("the combination of %qs and %qs is incompatible with %qs",
20411 "-mabi=o64", "-mabicalls", "-mlong64");
20415 if (mips_abi
== ABI_64
)
20416 error ("%qs is incompatible with %qs", "-mabi=64", "-mlong32");
20421 if ((mips_abi
== ABI_EABI
&& TARGET_64BIT
) || mips_abi
== ABI_64
)
20422 target_flags
|= MASK_LONG64
;
20424 target_flags
&= ~MASK_LONG64
;
20427 if (!TARGET_OLDABI
)
20428 flag_pcc_struct_return
= 0;
20430 /* Decide which rtx_costs structure to use. */
20432 mips_cost
= &mips_rtx_cost_optimize_size
;
20434 mips_cost
= &mips_rtx_cost_data
[mips_tune
];
20436 /* If the user hasn't specified a branch cost, use the processor's
20438 if (mips_branch_cost
== 0)
20439 mips_branch_cost
= mips_cost
->branch_cost
;
20441 /* If neither -mbranch-likely nor -mno-branch-likely was given
20442 on the command line, set MASK_BRANCHLIKELY based on the target
20443 architecture and tuning flags. Annulled delay slots are a
20444 size win, so we only consider the processor-specific tuning
20445 for !optimize_size. */
20446 if ((target_flags_explicit
& MASK_BRANCHLIKELY
) == 0)
20448 if (ISA_HAS_BRANCHLIKELY
20450 && (mips_tune_info
->tune_flags
20451 & PTF_AVOID_BRANCHLIKELY_SIZE
) == 0)
20454 && (mips_tune_info
->tune_flags
20455 & PTF_AVOID_BRANCHLIKELY_SPEED
) == 0)
20456 || (mips_tune_info
->tune_flags
20457 & PTF_AVOID_BRANCHLIKELY_ALWAYS
) == 0))
20458 target_flags
|= MASK_BRANCHLIKELY
;
20460 target_flags
&= ~MASK_BRANCHLIKELY
;
20462 else if (TARGET_BRANCHLIKELY
&& !ISA_HAS_BRANCHLIKELY
)
20463 warning (0, "the %qs architecture does not support branch-likely"
20464 " instructions", mips_arch_info
->name
);
20466 /* If the user hasn't specified -mimadd or -mno-imadd set
20467 MASK_IMADD based on the target architecture and tuning
20469 if ((target_flags_explicit
& MASK_IMADD
) == 0)
20471 if (ISA_HAS_MADD_MSUB
&&
20472 (mips_tune_info
->tune_flags
& PTF_AVOID_IMADD
) == 0)
20473 target_flags
|= MASK_IMADD
;
20475 target_flags
&= ~MASK_IMADD
;
20477 else if (TARGET_IMADD
&& !ISA_HAS_MADD_MSUB
)
20478 warning (0, "the %qs architecture does not support madd or msub"
20479 " instructions", mips_arch_info
->name
);
20481 /* If neither -modd-spreg nor -mno-odd-spreg was given on the command
20482 line, set MASK_ODD_SPREG based on the ISA and ABI. */
20483 if ((target_flags_explicit
& MASK_ODD_SPREG
) == 0)
20485 /* Disable TARGET_ODD_SPREG when using the o32 FPXX ABI. */
20486 if (!ISA_HAS_ODD_SPREG
|| TARGET_FLOATXX
)
20487 target_flags
&= ~MASK_ODD_SPREG
;
20489 target_flags
|= MASK_ODD_SPREG
;
20491 else if (TARGET_ODD_SPREG
&& !ISA_HAS_ODD_SPREG
)
20492 warning (0, "the %qs architecture does not support odd single-precision"
20493 " registers", mips_arch_info
->name
);
20495 if (!TARGET_ODD_SPREG
&& TARGET_64BIT
)
20497 error ("unsupported combination: %s", "-mgp64 -mno-odd-spreg");
20498 /* Allow compilation to continue further even though invalid output
20499 will be produced. */
20500 target_flags
|= MASK_ODD_SPREG
;
20503 if (!ISA_HAS_DELAY_SLOTS
&& mips_cb
== MIPS_CB_NEVER
)
20505 error ("unsupported combination: %qs%s %s",
20506 mips_arch_info
->name
, TARGET_MICROMIPS
? " -mmicromips" : "",
20507 "-mcompact-branches=never");
20510 /* Require explicit relocs for MIPS R6 onwards. This enables simplification
20511 of the compact branch and jump support through the backend. */
20512 if (!TARGET_EXPLICIT_RELOCS
&& mips_isa_rev
>= 6)
20514 error ("unsupported combination: %qs %s",
20515 mips_arch_info
->name
, "-mno-explicit-relocs");
20518 /* The effect of -mabicalls isn't defined for the EABI. */
20519 if (mips_abi
== ABI_EABI
&& TARGET_ABICALLS
)
20521 error ("unsupported combination: %s", "-mabicalls -mabi=eabi");
20522 target_flags
&= ~MASK_ABICALLS
;
20525 /* PIC requires -mabicalls. */
20528 if (mips_abi
== ABI_EABI
)
20529 error ("cannot generate position-independent code for %qs",
20531 else if (!TARGET_ABICALLS
)
20532 error ("position-independent code requires %qs", "-mabicalls");
20535 if (TARGET_ABICALLS_PIC2
)
20536 /* We need to set flag_pic for executables as well as DSOs
20537 because we may reference symbols that are not defined in
20538 the final executable. (MIPS does not use things like
20539 copy relocs, for example.)
20541 There is a body of code that uses __PIC__ to distinguish
20542 between -mabicalls and -mno-abicalls code. The non-__PIC__
20543 variant is usually appropriate for TARGET_ABICALLS_PIC0, as
20544 long as any indirect jumps use $25. */
20547 /* -mvr4130-align is a "speed over size" optimization: it usually produces
20548 faster code, but at the expense of more nops. Enable it at -O3 and
20550 if (optimize
> 2 && (target_flags_explicit
& MASK_VR4130_ALIGN
) == 0)
20551 target_flags
|= MASK_VR4130_ALIGN
;
20553 /* Prefer a call to memcpy over inline code when optimizing for size,
20554 though see MOVE_RATIO in mips.h. */
20555 if (optimize_size
&& (target_flags_explicit
& MASK_MEMCPY
) == 0)
20556 target_flags
|= MASK_MEMCPY
;
20558 /* If we have a nonzero small-data limit, check that the -mgpopt
20559 setting is consistent with the other target flags. */
20560 if (mips_small_data_threshold
> 0)
20564 if (!TARGET_EXPLICIT_RELOCS
)
20565 error ("%<-mno-gpopt%> needs %<-mexplicit-relocs%>");
20567 TARGET_LOCAL_SDATA
= false;
20568 TARGET_EXTERN_SDATA
= false;
20572 if (TARGET_VXWORKS_RTP
)
20573 warning (0, "cannot use small-data accesses for %qs", "-mrtp");
20575 if (TARGET_ABICALLS
)
20576 warning (0, "cannot use small-data accesses for %qs",
20581 /* Set NaN and ABS defaults. */
20582 if (mips_nan
== MIPS_IEEE_754_DEFAULT
&& !ISA_HAS_IEEE_754_LEGACY
)
20583 mips_nan
= MIPS_IEEE_754_2008
;
20584 if (mips_abs
== MIPS_IEEE_754_DEFAULT
&& mips_nan
== MIPS_IEEE_754_2008
)
20585 mips_abs
= MIPS_IEEE_754_2008
;
20586 if (mips_abs
== MIPS_IEEE_754_DEFAULT
&& !ISA_HAS_IEEE_754_LEGACY
)
20587 mips_abs
= MIPS_IEEE_754_2008
;
20589 /* Check for IEEE 754 legacy/2008 support. */
20590 if ((mips_nan
== MIPS_IEEE_754_LEGACY
20591 || mips_abs
== MIPS_IEEE_754_LEGACY
)
20592 && !ISA_HAS_IEEE_754_LEGACY
)
20593 warning (0, "the %qs architecture does not support %<-m%s=legacy%>",
20594 mips_arch_info
->name
,
20595 mips_nan
== MIPS_IEEE_754_LEGACY
? "nan" : "abs");
20597 if ((mips_nan
== MIPS_IEEE_754_2008
20598 || mips_abs
== MIPS_IEEE_754_2008
)
20599 && !ISA_HAS_IEEE_754_2008
)
20600 warning (0, "the %qs architecture does not support %<-m%s=2008%>",
20601 mips_arch_info
->name
,
20602 mips_nan
== MIPS_IEEE_754_2008
? "nan" : "abs");
20604 /* Pre-IEEE 754-2008 MIPS hardware has a quirky almost-IEEE format
20605 for all its floating point. */
20606 if (mips_nan
!= MIPS_IEEE_754_2008
)
20608 REAL_MODE_FORMAT (SFmode
) = &mips_single_format
;
20609 REAL_MODE_FORMAT (DFmode
) = &mips_double_format
;
20610 REAL_MODE_FORMAT (TFmode
) = &mips_quad_format
;
20613 /* Make sure that the user didn't turn off paired single support when
20614 MIPS-3D support is requested. */
20616 && (target_flags_explicit
& MASK_PAIRED_SINGLE_FLOAT
)
20617 && !TARGET_PAIRED_SINGLE_FLOAT
)
20618 error ("%<-mips3d%> requires %<-mpaired-single%>");
20620 /* If TARGET_MIPS3D, enable MASK_PAIRED_SINGLE_FLOAT. */
20622 target_flags
|= MASK_PAIRED_SINGLE_FLOAT
;
20624 /* Make sure that when TARGET_PAIRED_SINGLE_FLOAT is true, TARGET_FLOAT64
20625 and TARGET_HARD_FLOAT_ABI are both true. */
20626 if (TARGET_PAIRED_SINGLE_FLOAT
&& !(TARGET_FLOAT64
&& TARGET_HARD_FLOAT_ABI
))
20628 error ("%qs must be used with %qs",
20629 TARGET_MIPS3D
? "-mips3d" : "-mpaired-single",
20630 TARGET_HARD_FLOAT_ABI
? "-mfp64" : "-mhard-float");
20631 target_flags
&= ~MASK_PAIRED_SINGLE_FLOAT
;
20635 /* Make sure that when ISA_HAS_MSA is true, TARGET_FLOAT64 and
20636 TARGET_HARD_FLOAT_ABI and both true. */
20637 if (ISA_HAS_MSA
&& !(TARGET_FLOAT64
&& TARGET_HARD_FLOAT_ABI
))
20638 error ("%<-mmsa%> must be used with %<-mfp64%> and %<-mhard-float%>");
20640 /* Make sure that -mpaired-single is only used on ISAs that support it.
20641 We must disable it otherwise since it relies on other ISA properties
20642 like ISA_HAS_8CC having their normal values. */
20643 if (TARGET_PAIRED_SINGLE_FLOAT
&& !ISA_HAS_PAIRED_SINGLE
)
20645 error ("the %qs architecture does not support paired-single"
20646 " instructions", mips_arch_info
->name
);
20647 target_flags
&= ~MASK_PAIRED_SINGLE_FLOAT
;
20651 if (mips_r10k_cache_barrier
!= R10K_CACHE_BARRIER_NONE
20652 && !TARGET_CACHE_BUILTIN
)
20654 error ("%qs requires a target that provides the %qs instruction",
20655 "-mr10k-cache-barrier", "cache");
20656 mips_r10k_cache_barrier
= R10K_CACHE_BARRIER_NONE
;
20659 /* If TARGET_DSPR2, enable TARGET_DSP. */
20663 if (TARGET_DSP
&& mips_isa_rev
>= 6)
20665 error ("the %qs architecture does not support DSP instructions",
20666 mips_arch_info
->name
);
20667 TARGET_DSP
= false;
20668 TARGET_DSPR2
= false;
20671 /* Make sure that when TARGET_LOONGSON_MMI is true, TARGET_HARD_FLOAT_ABI
20672 is true. In o32 pairs of floating-point registers provide 64-bit
20674 if (TARGET_LOONGSON_MMI
&& !TARGET_HARD_FLOAT_ABI
)
20675 error ("%<-mloongson-mmi%> must be used with %<-mhard-float%>");
20677 /* If TARGET_LOONGSON_EXT2, enable TARGET_LOONGSON_EXT. */
20678 if (TARGET_LOONGSON_EXT2
)
20680 /* Make sure that when TARGET_LOONGSON_EXT2 is true, TARGET_LOONGSON_EXT
20681 is true. If a user explicitly says -mloongson-ext2 -mno-loongson-ext
20682 then that is an error. */
20683 if (!TARGET_LOONGSON_EXT
20684 && (target_flags_explicit
& MASK_LOONGSON_EXT
) != 0)
20685 error ("%<-mloongson-ext2%> must be used with %<-mloongson-ext%>");
20686 target_flags
|= MASK_LOONGSON_EXT
;
20689 /* .eh_frame addresses should be the same width as a C pointer.
20690 Most MIPS ABIs support only one pointer size, so the assembler
20691 will usually know exactly how big an .eh_frame address is.
20693 Unfortunately, this is not true of the 64-bit EABI. The ABI was
20694 originally defined to use 64-bit pointers (i.e. it is LP64), and
20695 this is still the default mode. However, we also support an n32-like
20696 ILP32 mode, which is selected by -mlong32. The problem is that the
20697 assembler has traditionally not had an -mlong option, so it has
20698 traditionally not known whether we're using the ILP32 or LP64 form.
20700 As it happens, gas versions up to and including 2.19 use _32-bit_
20701 addresses for EABI64 .cfi_* directives. This is wrong for the
20702 default LP64 mode, so we can't use the directives by default.
20703 Moreover, since gas's current behavior is at odds with gcc's
20704 default behavior, it seems unwise to rely on future versions
20705 of gas behaving the same way. We therefore avoid using .cfi
20706 directives for -mlong32 as well. */
20707 if (mips_abi
== ABI_EABI
&& TARGET_64BIT
)
20708 flag_dwarf2_cfi_asm
= 0;
20710 /* .cfi_* directives generate a read-only section, so fall back on
20711 manual .eh_frame creation if we need the section to be writable. */
20712 if (TARGET_WRITABLE_EH_FRAME
)
20713 flag_dwarf2_cfi_asm
= 0;
20715 mips_init_print_operand_punct ();
20717 /* Set up array to map GCC register number to debug register number.
20718 Ignore the special purpose register numbers. */
20720 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
20722 if (GP_REG_P (i
) || FP_REG_P (i
) || ALL_COP_REG_P (i
))
20723 mips_dwarf_regno
[i
] = i
;
20725 mips_dwarf_regno
[i
] = INVALID_REGNUM
;
20728 /* Accumulator debug registers use big-endian ordering. */
20729 mips_dwarf_regno
[HI_REGNUM
] = MD_REG_FIRST
+ 0;
20730 mips_dwarf_regno
[LO_REGNUM
] = MD_REG_FIRST
+ 1;
20731 for (i
= DSP_ACC_REG_FIRST
; i
<= DSP_ACC_REG_LAST
; i
+= 2)
20733 mips_dwarf_regno
[i
+ TARGET_LITTLE_ENDIAN
] = i
;
20734 mips_dwarf_regno
[i
+ TARGET_BIG_ENDIAN
] = i
+ 1;
20737 /* Set up mips_hard_regno_mode_ok. */
20738 for (mode
= 0; mode
< MAX_MACHINE_MODE
; mode
++)
20739 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
20740 mips_hard_regno_mode_ok_p
[mode
][regno
]
20741 = mips_hard_regno_mode_ok_uncached (regno
, (machine_mode
) mode
);
20743 /* Function to allocate machine-dependent function status. */
20744 init_machine_status
= &mips_init_machine_status
;
20746 /* Default to working around R4000 errata only if the processor
20747 was selected explicitly. */
20748 if ((target_flags_explicit
& MASK_FIX_R4000
) == 0
20749 && strcmp (mips_arch_info
->name
, "r4000") == 0)
20750 target_flags
|= MASK_FIX_R4000
;
20752 /* Default to working around R4400 errata only if the processor
20753 was selected explicitly. */
20754 if ((target_flags_explicit
& MASK_FIX_R4400
) == 0
20755 && strcmp (mips_arch_info
->name
, "r4400") == 0)
20756 target_flags
|= MASK_FIX_R4400
;
20758 /* Default to working around R5900 errata only if the processor
20759 was selected explicitly. */
20760 if ((target_flags_explicit
& MASK_FIX_R5900
) == 0
20761 && strcmp (mips_arch_info
->name
, "r5900") == 0)
20762 target_flags
|= MASK_FIX_R5900
;
20764 /* Default to working around R10000 errata only if the processor
20765 was selected explicitly. */
20766 if ((target_flags_explicit
& MASK_FIX_R10000
) == 0
20767 && strcmp (mips_arch_info
->name
, "r10000") == 0)
20768 target_flags
|= MASK_FIX_R10000
;
20770 /* Make sure that branch-likely instructions available when using
20771 -mfix-r10000. The instructions are not available if either:
20773 1. -mno-branch-likely was passed.
20774 2. The selected ISA does not support branch-likely and
20775 the command line does not include -mbranch-likely. */
20776 if (TARGET_FIX_R10000
20777 && ((target_flags_explicit
& MASK_BRANCHLIKELY
) == 0
20778 ? !ISA_HAS_BRANCHLIKELY
20779 : !TARGET_BRANCHLIKELY
))
20780 sorry ("%qs requires branch-likely instructions", "-mfix-r10000");
20782 if (TARGET_SYNCI
&& !ISA_HAS_SYNCI
)
20784 warning (0, "the %qs architecture does not support the synci "
20785 "instruction", mips_arch_info
->name
);
20786 target_flags
&= ~MASK_SYNCI
;
20789 /* Only optimize PIC indirect calls if they are actually required. */
20790 if (!TARGET_USE_GOT
|| !TARGET_EXPLICIT_RELOCS
)
20791 target_flags
&= ~MASK_RELAX_PIC_CALLS
;
20793 /* Save base state of options. */
20794 mips_base_target_flags
= target_flags
;
20795 mips_base_schedule_insns
= flag_schedule_insns
;
20796 mips_base_reorder_blocks_and_partition
= flag_reorder_blocks_and_partition
;
20797 mips_base_move_loop_invariants
= flag_move_loop_invariants
;
20798 mips_base_align_loops
= str_align_loops
;
20799 mips_base_align_jumps
= str_align_jumps
;
20800 mips_base_align_functions
= str_align_functions
;
20802 /* Now select the ISA mode.
20804 Do all CPP-sensitive stuff in uncompressed mode; we'll switch modes
20805 later if required. */
20806 mips_set_compression_mode (0);
20808 /* We register a second machine specific reorg pass after delay slot
20809 filling. Registering the pass must be done at start up. It's
20810 convenient to do it here. */
20811 opt_pass
*new_pass
= make_pass_mips_machine_reorg2 (g
);
20812 struct register_pass_info insert_pass_mips_machine_reorg2
=
20814 new_pass
, /* pass */
20815 "dbr", /* reference_pass_name */
20816 1, /* ref_pass_instance_number */
20817 PASS_POS_INSERT_AFTER
/* po_op */
20819 register_pass (&insert_pass_mips_machine_reorg2
);
20821 if (TARGET_HARD_FLOAT_ABI
&& TARGET_MIPS5900
)
20822 REAL_MODE_FORMAT (SFmode
) = &spu_single_format
;
20824 mips_register_frame_header_opt ();
20827 /* Swap the register information for registers I and I + 1, which
20828 currently have the wrong endianness. Note that the registers'
20829 fixedness and call-clobberedness might have been set on the
20833 mips_swap_registers (unsigned int i
)
20838 #define SWAP_INT(X, Y) (tmpi = (X), (X) = (Y), (Y) = tmpi)
20839 #define SWAP_STRING(X, Y) (tmps = (X), (X) = (Y), (Y) = tmps)
20841 SWAP_INT (fixed_regs
[i
], fixed_regs
[i
+ 1]);
20842 SWAP_INT (call_used_regs
[i
], call_used_regs
[i
+ 1]);
20843 SWAP_STRING (reg_names
[i
], reg_names
[i
+ 1]);
20849 /* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */
20852 mips_conditional_register_usage (void)
20857 /* These DSP control register fields are global. */
20858 global_regs
[CCDSP_PO_REGNUM
] = 1;
20859 global_regs
[CCDSP_SC_REGNUM
] = 1;
20862 accessible_reg_set
&= ~reg_class_contents
[DSP_ACC_REGS
];
20865 accessible_reg_set
&= ~reg_class_contents
[MD_REGS
];
20867 if (!TARGET_HARD_FLOAT
)
20868 accessible_reg_set
&= ~(reg_class_contents
[FP_REGS
]
20869 | reg_class_contents
[ST_REGS
]);
20870 else if (!ISA_HAS_8CC
)
20872 /* We only have a single condition-code register. We implement
20873 this by fixing all the condition-code registers and generating
20874 RTL that refers directly to ST_REG_FIRST. */
20875 accessible_reg_set
&= ~reg_class_contents
[ST_REGS
];
20877 SET_HARD_REG_BIT (accessible_reg_set
, FPSW_REGNUM
);
20878 fixed_regs
[FPSW_REGNUM
] = 1;
20882 /* In MIPS16 mode, we prohibit the unused $s registers, since they
20883 are call-saved, and saving them via a MIPS16 register would
20884 probably waste more time than just reloading the value.
20886 We permit the $t temporary registers when optimizing for speed
20887 but not when optimizing for space because using them results in
20888 code that is larger (but faster) then not using them. We do
20889 allow $24 (t8) because it is used in CMP and CMPI instructions
20890 and $25 (t9) because it is used as the function call address in
20893 fixed_regs
[18] = 1;
20894 fixed_regs
[19] = 1;
20895 fixed_regs
[20] = 1;
20896 fixed_regs
[21] = 1;
20897 fixed_regs
[22] = 1;
20898 fixed_regs
[23] = 1;
20899 fixed_regs
[26] = 1;
20900 fixed_regs
[27] = 1;
20901 fixed_regs
[30] = 1;
20906 fixed_regs
[10] = 1;
20907 fixed_regs
[11] = 1;
20908 fixed_regs
[12] = 1;
20909 fixed_regs
[13] = 1;
20910 fixed_regs
[14] = 1;
20911 fixed_regs
[15] = 1;
20914 /* Do not allow HI and LO to be treated as register operands.
20915 There are no MTHI or MTLO instructions (or any real need
20916 for them) and one-way registers cannot easily be reloaded. */
20917 operand_reg_set
&= ~reg_class_contents
[MD_REGS
];
20919 /* $f20-$f23 are call-clobbered for n64. */
20920 if (mips_abi
== ABI_64
)
20923 for (regno
= FP_REG_FIRST
+ 20; regno
< FP_REG_FIRST
+ 24; regno
++)
20924 call_used_regs
[regno
] = 1;
20926 /* Odd registers in the range $f21-$f31 (inclusive) are call-clobbered
20927 for n32 and o32 FP64. */
20928 if (mips_abi
== ABI_N32
20929 || (mips_abi
== ABI_32
20930 && TARGET_FLOAT64
))
20933 for (regno
= FP_REG_FIRST
+ 21; regno
<= FP_REG_FIRST
+ 31; regno
+=2)
20934 call_used_regs
[regno
] = 1;
20936 /* Make sure that double-register accumulator values are correctly
20937 ordered for the current endianness. */
20938 if (TARGET_LITTLE_ENDIAN
)
20940 unsigned int regno
;
20942 mips_swap_registers (MD_REG_FIRST
);
20943 for (regno
= DSP_ACC_REG_FIRST
; regno
<= DSP_ACC_REG_LAST
; regno
+= 2)
20944 mips_swap_registers (regno
);
20948 /* Implement EH_USES. */
20951 mips_eh_uses (unsigned int regno
)
20953 if (reload_completed
&& !TARGET_ABSOLUTE_JUMPS
)
20955 /* We need to force certain registers to be live in order to handle
20956 PIC long branches correctly. See mips_must_initialize_gp_p for
20958 if (mips_cfun_has_cprestore_slot_p ())
20960 if (regno
== CPRESTORE_SLOT_REGNUM
)
20965 if (cfun
->machine
->global_pointer
== regno
)
20973 /* Implement EPILOGUE_USES. */
20976 mips_epilogue_uses (unsigned int regno
)
20978 /* Say that the epilogue uses the return address register. Note that
20979 in the case of sibcalls, the values "used by the epilogue" are
20980 considered live at the start of the called function. */
20981 if (regno
== RETURN_ADDR_REGNUM
)
20984 /* If using a GOT, say that the epilogue also uses GOT_VERSION_REGNUM.
20985 See the comment above load_call<mode> for details. */
20986 if (TARGET_USE_GOT
&& (regno
) == GOT_VERSION_REGNUM
)
20989 /* An interrupt handler must preserve some registers that are
20990 ordinarily call-clobbered. */
20991 if (cfun
->machine
->interrupt_handler_p
20992 && mips_interrupt_extra_call_saved_reg_p (regno
))
20998 /* Return true if INSN needs to be wrapped in ".set noat".
20999 INSN has NOPERANDS operands, stored in OPVEC. */
21002 mips_need_noat_wrapper_p (rtx_insn
*insn
, rtx
*opvec
, int noperands
)
21004 if (recog_memoized (insn
) >= 0)
21006 subrtx_iterator::array_type array
;
21007 for (int i
= 0; i
< noperands
; i
++)
21008 FOR_EACH_SUBRTX (iter
, array
, opvec
[i
], NONCONST
)
21009 if (REG_P (*iter
) && REGNO (*iter
) == AT_REGNUM
)
21015 /* Implement FINAL_PRESCAN_INSN. Mark MIPS16 inline constant pools
21016 as data for the purpose of disassembly. For simplicity embed the
21017 pool's initial label number in the local symbol produced so that
21018 multiple pools within a single function end up marked with unique
21019 symbols. The label number is carried by the `consttable' insn
21020 emitted at the beginning of each pool. */
21023 mips_final_prescan_insn (rtx_insn
*insn
, rtx
*opvec
, int noperands
)
21026 && GET_CODE (PATTERN (insn
)) == UNSPEC_VOLATILE
21027 && XINT (PATTERN (insn
), 1) == UNSPEC_CONSTTABLE
)
21028 mips_set_text_contents_type (asm_out_file
, "__pool_",
21029 INTVAL (XVECEXP (PATTERN (insn
), 0, 0)),
21032 if (mips_need_noat_wrapper_p (insn
, opvec
, noperands
))
21033 mips_push_asm_switch (&mips_noat
);
21036 /* Implement TARGET_ASM_FINAL_POSTSCAN_INSN. Reset text marking to
21037 code after a MIPS16 inline constant pool. Like with the beginning
21038 of a pool table use the pool's initial label number to keep symbols
21039 unique. The label number is carried by the `consttable_end' insn
21040 emitted at the end of each pool. */
21043 mips_final_postscan_insn (FILE *file ATTRIBUTE_UNUSED
, rtx_insn
*insn
,
21044 rtx
*opvec
, int noperands
)
21046 if (mips_need_noat_wrapper_p (insn
, opvec
, noperands
))
21047 mips_pop_asm_switch (&mips_noat
);
21050 && GET_CODE (PATTERN (insn
)) == UNSPEC_VOLATILE
21051 && XINT (PATTERN (insn
), 1) == UNSPEC_CONSTTABLE_END
)
21053 rtx_insn
*next_insn
= next_real_nondebug_insn (insn
);
21054 bool code_p
= (next_insn
!= NULL
21055 && INSN_P (next_insn
)
21056 && (GET_CODE (PATTERN (next_insn
)) != UNSPEC_VOLATILE
21057 || XINT (PATTERN (next_insn
), 1) != UNSPEC_CONSTTABLE
));
21059 /* Switch content type depending on whether there is code beyond
21060 the constant pool. */
21061 mips_set_text_contents_type (asm_out_file
, "__pend_",
21062 INTVAL (XVECEXP (PATTERN (insn
), 0, 0)),
21067 /* Return the function that is used to expand the <u>mulsidi3 pattern.
21068 EXT_CODE is the code of the extension used. Return NULL if widening
21069 multiplication shouldn't be used. */
21072 mips_mulsidi3_gen_fn (enum rtx_code ext_code
)
21076 signed_p
= ext_code
== SIGN_EXTEND
;
21079 /* Don't use widening multiplication with MULT when we have DMUL. Even
21080 with the extension of its input operands DMUL is faster. Note that
21081 the extension is not needed for signed multiplication. In order to
21082 ensure that we always remove the redundant sign-extension in this
21083 case we still expand mulsidi3 for DMUL. */
21084 if (ISA_HAS_R6DMUL
)
21085 return signed_p
? gen_mulsidi3_64bit_r6dmul
: NULL
;
21087 return signed_p
? gen_mulsidi3_64bit_dmul
: NULL
;
21090 ? gen_mulsidi3_64bit_mips16
21091 : gen_umulsidi3_64bit_mips16
);
21092 if (TARGET_FIX_R4000
)
21094 return signed_p
? gen_mulsidi3_64bit
: gen_umulsidi3_64bit
;
21099 return (signed_p
? gen_mulsidi3_32bit_r6
: gen_umulsidi3_32bit_r6
);
21102 ? gen_mulsidi3_32bit_mips16
21103 : gen_umulsidi3_32bit_mips16
);
21104 if (TARGET_FIX_R4000
&& !ISA_HAS_DSP
)
21105 return signed_p
? gen_mulsidi3_32bit_r4000
: gen_umulsidi3_32bit_r4000
;
21106 return signed_p
? gen_mulsidi3_32bit
: gen_umulsidi3_32bit
;
21110 /* Return true if PATTERN matches the kind of instruction generated by
21111 umips_build_save_restore. SAVE_P is true for store. */
21114 umips_save_restore_pattern_p (bool save_p
, rtx pattern
)
21118 HOST_WIDE_INT first_offset
= 0;
21119 rtx first_base
= 0;
21120 unsigned int regmask
= 0;
21122 for (n
= 0; n
< XVECLEN (pattern
, 0); n
++)
21124 rtx set
, reg
, mem
, this_base
;
21125 HOST_WIDE_INT this_offset
;
21127 /* Check that we have a SET. */
21128 set
= XVECEXP (pattern
, 0, n
);
21129 if (GET_CODE (set
) != SET
)
21132 /* Check that the SET is a load (if restoring) or a store
21134 mem
= save_p
? SET_DEST (set
) : SET_SRC (set
);
21135 if (!MEM_P (mem
) || MEM_VOLATILE_P (mem
))
21138 /* Check that the address is the sum of base and a possibly-zero
21139 constant offset. Determine if the offset is in range. */
21140 mips_split_plus (XEXP (mem
, 0), &this_base
, &this_offset
);
21141 if (!REG_P (this_base
))
21146 if (!UMIPS_12BIT_OFFSET_P (this_offset
))
21148 first_base
= this_base
;
21149 first_offset
= this_offset
;
21153 /* Check that the save slots are consecutive. */
21154 if (REGNO (this_base
) != REGNO (first_base
)
21155 || this_offset
!= first_offset
+ UNITS_PER_WORD
* n
)
21159 /* Check that SET's other operand is a register. */
21160 reg
= save_p
? SET_SRC (set
) : SET_DEST (set
);
21164 regmask
|= 1 << REGNO (reg
);
21167 for (i
= 0; i
< ARRAY_SIZE (umips_swm_mask
); i
++)
21168 if (regmask
== umips_swm_mask
[i
])
21174 /* Return the assembly instruction for microMIPS LWM or SWM.
21175 SAVE_P and PATTERN are as for umips_save_restore_pattern_p. */
21178 umips_output_save_restore (bool save_p
, rtx pattern
)
21180 static char buffer
[300];
21183 HOST_WIDE_INT offset
;
21184 rtx base
, mem
, set
, last_set
, last_reg
;
21186 /* Parse the pattern. */
21187 gcc_assert (umips_save_restore_pattern_p (save_p
, pattern
));
21189 s
= strcpy (buffer
, save_p
? "swm\t" : "lwm\t");
21191 n
= XVECLEN (pattern
, 0);
21193 set
= XVECEXP (pattern
, 0, 0);
21194 mem
= save_p
? SET_DEST (set
) : SET_SRC (set
);
21195 mips_split_plus (XEXP (mem
, 0), &base
, &offset
);
21197 last_set
= XVECEXP (pattern
, 0, n
- 1);
21198 last_reg
= save_p
? SET_SRC (last_set
) : SET_DEST (last_set
);
21200 if (REGNO (last_reg
) == 31)
21203 gcc_assert (n
<= 9);
21207 s
+= sprintf (s
, "%s,", reg_names
[16]);
21209 s
+= sprintf (s
, "%s-%s,", reg_names
[16], reg_names
[15 + n
]);
21211 s
+= sprintf (s
, "%s-%s,%s,", reg_names
[16], reg_names
[23],
21214 if (REGNO (last_reg
) == 31)
21215 s
+= sprintf (s
, "%s,", reg_names
[31]);
21217 s
+= sprintf (s
, "%d(%s)", (int)offset
, reg_names
[REGNO (base
)]);
21221 /* Return true if MEM1 and MEM2 use the same base register, and the
21222 offset of MEM2 equals the offset of MEM1 plus 4. FIRST_REG is the
21223 register into (from) which the contents of MEM1 will be loaded
21224 (stored), depending on the value of LOAD_P.
21225 SWAP_P is true when the 1st and 2nd instructions are swapped. */
21228 umips_load_store_pair_p_1 (bool load_p
, bool swap_p
,
21229 rtx first_reg
, rtx mem1
, rtx mem2
)
21232 HOST_WIDE_INT offset1
, offset2
;
21234 if (!MEM_P (mem1
) || !MEM_P (mem2
))
21237 mips_split_plus (XEXP (mem1
, 0), &base1
, &offset1
);
21238 mips_split_plus (XEXP (mem2
, 0), &base2
, &offset2
);
21240 if (!REG_P (base1
) || !rtx_equal_p (base1
, base2
))
21243 /* Avoid invalid load pair instructions. */
21244 if (load_p
&& REGNO (first_reg
) == REGNO (base1
))
21247 /* We must avoid this case for anti-dependence.
21250 first_reg is $2, but the base is $3. */
21253 && REGNO (first_reg
) + 1 == REGNO (base1
))
21256 if (offset2
!= offset1
+ 4)
21259 if (!UMIPS_12BIT_OFFSET_P (offset1
))
21266 mips_load_store_bonding_p (rtx
*operands
, machine_mode mode
, bool load_p
)
21268 rtx reg1
, reg2
, mem1
, mem2
, base1
, base2
;
21269 enum reg_class rc1
, rc2
;
21270 HOST_WIDE_INT offset1
, offset2
;
21274 reg1
= operands
[0];
21275 reg2
= operands
[2];
21276 mem1
= operands
[1];
21277 mem2
= operands
[3];
21281 reg1
= operands
[1];
21282 reg2
= operands
[3];
21283 mem1
= operands
[0];
21284 mem2
= operands
[2];
21287 if (mips_address_insns (XEXP (mem1
, 0), mode
, false) == 0
21288 || mips_address_insns (XEXP (mem2
, 0), mode
, false) == 0)
21291 mips_split_plus (XEXP (mem1
, 0), &base1
, &offset1
);
21292 mips_split_plus (XEXP (mem2
, 0), &base2
, &offset2
);
21294 /* Base regs do not match. */
21295 if (!REG_P (base1
) || !rtx_equal_p (base1
, base2
))
21298 /* Either of the loads is clobbering base register. It is legitimate to bond
21299 loads if second load clobbers base register. However, hardware does not
21300 support such bonding. */
21302 && (REGNO (reg1
) == REGNO (base1
)
21303 || (REGNO (reg2
) == REGNO (base1
))))
21306 /* Loading in same registers. */
21308 && REGNO (reg1
) == REGNO (reg2
))
21311 /* The loads/stores are not of same type. */
21312 rc1
= REGNO_REG_CLASS (REGNO (reg1
));
21313 rc2
= REGNO_REG_CLASS (REGNO (reg2
));
21315 && !reg_class_subset_p (rc1
, rc2
)
21316 && !reg_class_subset_p (rc2
, rc1
))
21319 if (abs (offset1
- offset2
) != GET_MODE_SIZE (mode
))
21325 /* OPERANDS describes the operands to a pair of SETs, in the order
21326 dest1, src1, dest2, src2. Return true if the operands can be used
21327 in an LWP or SWP instruction; LOAD_P says which. */
21330 umips_load_store_pair_p (bool load_p
, rtx
*operands
)
21332 rtx reg1
, reg2
, mem1
, mem2
;
21336 reg1
= operands
[0];
21337 reg2
= operands
[2];
21338 mem1
= operands
[1];
21339 mem2
= operands
[3];
21343 reg1
= operands
[1];
21344 reg2
= operands
[3];
21345 mem1
= operands
[0];
21346 mem2
= operands
[2];
21349 if (REGNO (reg2
) == REGNO (reg1
) + 1)
21350 return umips_load_store_pair_p_1 (load_p
, false, reg1
, mem1
, mem2
);
21352 if (REGNO (reg1
) == REGNO (reg2
) + 1)
21353 return umips_load_store_pair_p_1 (load_p
, true, reg2
, mem2
, mem1
);
21358 /* Return the assembly instruction for a microMIPS LWP or SWP in which
21359 the first register is REG and the first memory slot is MEM.
21360 LOAD_P is true for LWP. */
21363 umips_output_load_store_pair_1 (bool load_p
, rtx reg
, rtx mem
)
21365 rtx ops
[] = {reg
, mem
};
21368 output_asm_insn ("lwp\t%0,%1", ops
);
21370 output_asm_insn ("swp\t%0,%1", ops
);
21373 /* Output the assembly instruction for a microMIPS LWP or SWP instruction.
21374 LOAD_P and OPERANDS are as for umips_load_store_pair_p. */
21377 umips_output_load_store_pair (bool load_p
, rtx
*operands
)
21379 rtx reg1
, reg2
, mem1
, mem2
;
21382 reg1
= operands
[0];
21383 reg2
= operands
[2];
21384 mem1
= operands
[1];
21385 mem2
= operands
[3];
21389 reg1
= operands
[1];
21390 reg2
= operands
[3];
21391 mem1
= operands
[0];
21392 mem2
= operands
[2];
21395 if (REGNO (reg2
) == REGNO (reg1
) + 1)
21397 umips_output_load_store_pair_1 (load_p
, reg1
, mem1
);
21401 gcc_assert (REGNO (reg1
) == REGNO (reg2
) + 1);
21402 umips_output_load_store_pair_1 (load_p
, reg2
, mem2
);
21405 /* Return true if REG1 and REG2 match the criteria for a movep insn. */
21408 umips_movep_target_p (rtx reg1
, rtx reg2
)
21410 int regno1
, regno2
, pair
;
21412 static const int match
[8] = {
21413 0x00000060, /* 5, 6 */
21414 0x000000a0, /* 5, 7 */
21415 0x000000c0, /* 6, 7 */
21416 0x00200010, /* 4, 21 */
21417 0x00400010, /* 4, 22 */
21418 0x00000030, /* 4, 5 */
21419 0x00000050, /* 4, 6 */
21420 0x00000090 /* 4, 7 */
21423 if (!REG_P (reg1
) || !REG_P (reg2
))
21426 regno1
= REGNO (reg1
);
21427 regno2
= REGNO (reg2
);
21429 if (!GP_REG_P (regno1
) || !GP_REG_P (regno2
))
21432 pair
= (1 << regno1
) | (1 << regno2
);
21434 for (i
= 0; i
< ARRAY_SIZE (match
); i
++)
21435 if (pair
== match
[i
])
21441 /* Return the size in bytes of the trampoline code, padded to
21442 TRAMPOLINE_ALIGNMENT bits. The static chain pointer and target
21443 function address immediately follow. */
21446 mips_trampoline_code_size (void)
21448 if (TARGET_USE_PIC_FN_ADDR_REG
)
21450 else if (ptr_mode
== DImode
)
21452 else if (ISA_HAS_LOAD_DELAY
)
21458 /* Implement TARGET_TRAMPOLINE_INIT. */
21461 mips_trampoline_init (rtx m_tramp
, tree fndecl
, rtx chain_value
)
21463 rtx addr
, end_addr
, high
, low
, opcode
, mem
;
21466 HOST_WIDE_INT end_addr_offset
, static_chain_offset
, target_function_offset
;
21468 /* Work out the offsets of the pointers from the start of the
21469 trampoline code. */
21470 end_addr_offset
= mips_trampoline_code_size ();
21471 static_chain_offset
= end_addr_offset
;
21472 target_function_offset
= static_chain_offset
+ GET_MODE_SIZE (ptr_mode
);
21474 /* Get pointers to the beginning and end of the code block. */
21475 addr
= force_reg (Pmode
, XEXP (m_tramp
, 0));
21476 end_addr
= mips_force_binary (Pmode
, PLUS
, addr
, GEN_INT (end_addr_offset
));
21478 #define OP(X) gen_int_mode (X, SImode)
21480 /* Build up the code in TRAMPOLINE. */
21482 if (TARGET_USE_PIC_FN_ADDR_REG
)
21484 /* $25 contains the address of the trampoline. Emit code of the form:
21486 l[wd] $1, target_function_offset($25)
21487 l[wd] $static_chain, static_chain_offset($25)
21490 trampoline
[i
++] = OP (MIPS_LOAD_PTR (AT_REGNUM
,
21491 target_function_offset
,
21492 PIC_FUNCTION_ADDR_REGNUM
));
21493 trampoline
[i
++] = OP (MIPS_LOAD_PTR (STATIC_CHAIN_REGNUM
,
21494 static_chain_offset
,
21495 PIC_FUNCTION_ADDR_REGNUM
));
21496 trampoline
[i
++] = OP (MIPS_JR (AT_REGNUM
));
21497 trampoline
[i
++] = OP (MIPS_MOVE (PIC_FUNCTION_ADDR_REGNUM
, AT_REGNUM
));
21499 else if (ptr_mode
== DImode
)
21501 /* It's too cumbersome to create the full 64-bit address, so let's
21507 1: l[wd] $25, target_function_offset - 12($31)
21508 l[wd] $static_chain, static_chain_offset - 12($31)
21512 where 12 is the offset of "1:" from the start of the code block. */
21513 trampoline
[i
++] = OP (MIPS_MOVE (AT_REGNUM
, RETURN_ADDR_REGNUM
));
21514 trampoline
[i
++] = OP (MIPS_BAL (1));
21515 trampoline
[i
++] = OP (MIPS_NOP
);
21516 trampoline
[i
++] = OP (MIPS_LOAD_PTR (PIC_FUNCTION_ADDR_REGNUM
,
21517 target_function_offset
- 12,
21518 RETURN_ADDR_REGNUM
));
21519 trampoline
[i
++] = OP (MIPS_LOAD_PTR (STATIC_CHAIN_REGNUM
,
21520 static_chain_offset
- 12,
21521 RETURN_ADDR_REGNUM
));
21522 trampoline
[i
++] = OP (MIPS_JR (PIC_FUNCTION_ADDR_REGNUM
));
21523 trampoline
[i
++] = OP (MIPS_MOVE (RETURN_ADDR_REGNUM
, AT_REGNUM
));
21527 /* If the target has load delays, emit:
21529 lui $1, %hi(end_addr)
21530 lw $25, %lo(end_addr + ...)($1)
21531 lw $static_chain, %lo(end_addr + ...)($1)
21537 lui $1, %hi(end_addr)
21538 lw $25, %lo(end_addr + ...)($1)
21540 lw $static_chain, %lo(end_addr + ...)($1). */
21542 /* Split END_ADDR into %hi and %lo values. Trampolines are aligned
21543 to 64 bits, so the %lo value will have the bottom 3 bits clear. */
21544 high
= expand_simple_binop (SImode
, PLUS
, end_addr
, GEN_INT (0x8000),
21545 NULL
, false, OPTAB_WIDEN
);
21546 high
= expand_simple_binop (SImode
, LSHIFTRT
, high
, GEN_INT (16),
21547 NULL
, false, OPTAB_WIDEN
);
21548 low
= convert_to_mode (SImode
, gen_lowpart (HImode
, end_addr
), true);
21550 /* Emit the LUI. */
21551 opcode
= OP (MIPS_LUI (AT_REGNUM
, 0));
21552 trampoline
[i
++] = expand_simple_binop (SImode
, IOR
, opcode
, high
,
21553 NULL
, false, OPTAB_WIDEN
);
21555 /* Emit the load of the target function. */
21556 opcode
= OP (MIPS_LOAD_PTR (PIC_FUNCTION_ADDR_REGNUM
,
21557 target_function_offset
- end_addr_offset
,
21559 trampoline
[i
++] = expand_simple_binop (SImode
, IOR
, opcode
, low
,
21560 NULL
, false, OPTAB_WIDEN
);
21562 /* Emit the JR here, if we can. */
21563 if (!ISA_HAS_LOAD_DELAY
)
21564 trampoline
[i
++] = OP (MIPS_JR (PIC_FUNCTION_ADDR_REGNUM
));
21566 /* Emit the load of the static chain register. */
21567 opcode
= OP (MIPS_LOAD_PTR (STATIC_CHAIN_REGNUM
,
21568 static_chain_offset
- end_addr_offset
,
21570 trampoline
[i
++] = expand_simple_binop (SImode
, IOR
, opcode
, low
,
21571 NULL
, false, OPTAB_WIDEN
);
21573 /* Emit the JR, if we couldn't above. */
21574 if (ISA_HAS_LOAD_DELAY
)
21576 trampoline
[i
++] = OP (MIPS_JR (PIC_FUNCTION_ADDR_REGNUM
));
21577 trampoline
[i
++] = OP (MIPS_NOP
);
21583 /* If we are using compact branches we don't have delay slots so
21584 place the instruction that was in the delay slot before the JRC
21587 if (TARGET_CB_ALWAYS
)
21590 temp
= trampoline
[i
-2];
21591 trampoline
[i
-2] = trampoline
[i
-1];
21592 trampoline
[i
-1] = temp
;
21595 /* Copy the trampoline code. Leave any padding uninitialized. */
21596 for (j
= 0; j
< i
; j
++)
21598 mem
= adjust_address (m_tramp
, SImode
, j
* GET_MODE_SIZE (SImode
));
21599 mips_emit_move (mem
, trampoline
[j
]);
21602 /* Set up the static chain pointer field. */
21603 mem
= adjust_address (m_tramp
, ptr_mode
, static_chain_offset
);
21604 mips_emit_move (mem
, chain_value
);
21606 /* Set up the target function field. */
21607 mem
= adjust_address (m_tramp
, ptr_mode
, target_function_offset
);
21608 mips_emit_move (mem
, XEXP (DECL_RTL (fndecl
), 0));
21610 /* Flush the code part of the trampoline. */
21611 emit_insn (gen_add3_insn (end_addr
, addr
, GEN_INT (TRAMPOLINE_SIZE
)));
21612 emit_insn (gen_clear_cache (addr
, end_addr
));
21615 /* Implement FUNCTION_PROFILER. */
21617 void mips_function_profiler (FILE *file
)
21620 sorry ("mips16 function profiling");
21621 if (TARGET_LONG_CALLS
)
21623 /* For TARGET_LONG_CALLS use $3 for the address of _mcount. */
21624 if (Pmode
== DImode
)
21625 fprintf (file
, "\tdla\t%s,_mcount\n", reg_names
[3]);
21627 fprintf (file
, "\tla\t%s,_mcount\n", reg_names
[3]);
21629 mips_push_asm_switch (&mips_noat
);
21630 fprintf (file
, "\tmove\t%s,%s\t\t# save current return address\n",
21631 reg_names
[AT_REGNUM
], reg_names
[RETURN_ADDR_REGNUM
]);
21632 /* _mcount treats $2 as the static chain register. */
21633 if (cfun
->static_chain_decl
!= NULL
)
21634 fprintf (file
, "\tmove\t%s,%s\n", reg_names
[2],
21635 reg_names
[STATIC_CHAIN_REGNUM
]);
21636 if (TARGET_MCOUNT_RA_ADDRESS
)
21638 /* If TARGET_MCOUNT_RA_ADDRESS load $12 with the address of the
21639 ra save location. */
21640 if (cfun
->machine
->frame
.ra_fp_offset
== 0)
21641 /* ra not saved, pass zero. */
21642 fprintf (file
, "\tmove\t%s,%s\n", reg_names
[12], reg_names
[0]);
21644 fprintf (file
, "\t%s\t%s," HOST_WIDE_INT_PRINT_DEC
"(%s)\n",
21645 Pmode
== DImode
? "dla" : "la", reg_names
[12],
21646 cfun
->machine
->frame
.ra_fp_offset
,
21647 reg_names
[STACK_POINTER_REGNUM
]);
21649 if (!TARGET_NEWABI
)
21651 "\t%s\t%s,%s,%d\t\t# _mcount pops 2 words from stack\n",
21652 TARGET_64BIT
? "dsubu" : "subu",
21653 reg_names
[STACK_POINTER_REGNUM
],
21654 reg_names
[STACK_POINTER_REGNUM
],
21655 Pmode
== DImode
? 16 : 8);
21657 if (TARGET_LONG_CALLS
)
21658 fprintf (file
, "\tjalr\t%s\n", reg_names
[3]);
21660 fprintf (file
, "\tjal\t_mcount\n");
21661 mips_pop_asm_switch (&mips_noat
);
21662 /* _mcount treats $2 as the static chain register. */
21663 if (cfun
->static_chain_decl
!= NULL
)
21664 fprintf (file
, "\tmove\t%s,%s\n", reg_names
[STATIC_CHAIN_REGNUM
],
21668 /* Implement TARGET_SHIFT_TRUNCATION_MASK. We want to keep the default
21669 behavior of TARGET_SHIFT_TRUNCATION_MASK for non-vector modes even
21670 when TARGET_LOONGSON_MMI is true. */
21672 static unsigned HOST_WIDE_INT
21673 mips_shift_truncation_mask (machine_mode mode
)
21675 if (TARGET_LOONGSON_MMI
&& VECTOR_MODE_P (mode
))
21678 return GET_MODE_BITSIZE (mode
) - 1;
21681 /* Implement TARGET_PREPARE_PCH_SAVE. */
21684 mips_prepare_pch_save (void)
21686 /* We are called in a context where the current compression vs.
21687 non-compression setting should be irrelevant. The question then is:
21688 which setting makes most sense at load time?
21690 The PCH is loaded before the first token is read. We should never have
21691 switched into a compression mode by that point, and thus should not have
21692 populated mips16_globals or micromips_globals. Nor can we load the
21693 entire contents of mips16_globals or micromips_globals from the PCH file,
21694 because they contain a combination of GGC and non-GGC data.
21696 There is therefore no point in trying save the GGC part of
21697 mips16_globals/micromips_globals to the PCH file, or to preserve a
21698 compression setting across the PCH save and load. The loading compiler
21699 would not have access to the non-GGC parts of mips16_globals or
21700 micromips_globals (either from the PCH file, or from a copy that the
21701 loading compiler generated itself) and would have to call target_reinit
21704 It therefore seems best to switch back to non-MIPS16 mode and
21705 non-microMIPS mode to save time, and to ensure that mips16_globals and
21706 micromips_globals remain null after a PCH load. */
21707 mips_set_compression_mode (0);
21708 mips16_globals
= 0;
21709 micromips_globals
= 0;
21712 /* Generate or test for an insn that supports a constant permutation. */
21714 #define MAX_VECT_LEN 16
21716 struct expand_vec_perm_d
21718 rtx target
, op0
, op1
;
21719 unsigned char perm
[MAX_VECT_LEN
];
21720 machine_mode vmode
;
21721 unsigned char nelt
;
21726 /* Construct (set target (vec_select op0 (parallel perm))) and
21727 return true if that's a valid instruction in the active ISA. */
21730 mips_expand_vselect (rtx target
, rtx op0
,
21731 const unsigned char *perm
, unsigned nelt
)
21733 rtx rperm
[MAX_VECT_LEN
], x
;
21737 for (i
= 0; i
< nelt
; ++i
)
21738 rperm
[i
] = GEN_INT (perm
[i
]);
21740 x
= gen_rtx_PARALLEL (VOIDmode
, gen_rtvec_v (nelt
, rperm
));
21741 x
= gen_rtx_VEC_SELECT (GET_MODE (target
), op0
, x
);
21742 x
= gen_rtx_SET (target
, x
);
21744 insn
= emit_insn (x
);
21745 if (recog_memoized (insn
) < 0)
21747 remove_insn (insn
);
21753 /* Similar, but generate a vec_concat from op0 and op1 as well. */
21756 mips_expand_vselect_vconcat (rtx target
, rtx op0
, rtx op1
,
21757 const unsigned char *perm
, unsigned nelt
)
21759 machine_mode v2mode
;
21762 if (!GET_MODE_2XWIDER_MODE (GET_MODE (op0
)).exists (&v2mode
))
21764 x
= gen_rtx_VEC_CONCAT (v2mode
, op0
, op1
);
21765 return mips_expand_vselect (target
, x
, perm
, nelt
);
21768 /* Recognize patterns for even-odd extraction. */
21771 mips_expand_vpc_loongson_even_odd (struct expand_vec_perm_d
*d
)
21773 unsigned i
, odd
, nelt
= d
->nelt
;
21774 rtx t0
, t1
, t2
, t3
;
21776 if (!(TARGET_HARD_FLOAT
&& TARGET_LOONGSON_MMI
))
21778 /* Even-odd for V2SI/V2SFmode is matched by interleave directly. */
21785 for (i
= 1; i
< nelt
; ++i
)
21786 if (d
->perm
[i
] != i
* 2 + odd
)
21792 /* We need 2*log2(N)-1 operations to achieve odd/even with interleave. */
21793 t0
= gen_reg_rtx (d
->vmode
);
21794 t1
= gen_reg_rtx (d
->vmode
);
21798 emit_insn (gen_loongson_punpckhhw (t0
, d
->op0
, d
->op1
));
21799 emit_insn (gen_loongson_punpcklhw (t1
, d
->op0
, d
->op1
));
21801 emit_insn (gen_loongson_punpckhhw (d
->target
, t1
, t0
));
21803 emit_insn (gen_loongson_punpcklhw (d
->target
, t1
, t0
));
21807 t2
= gen_reg_rtx (d
->vmode
);
21808 t3
= gen_reg_rtx (d
->vmode
);
21809 emit_insn (gen_loongson_punpckhbh (t0
, d
->op0
, d
->op1
));
21810 emit_insn (gen_loongson_punpcklbh (t1
, d
->op0
, d
->op1
));
21811 emit_insn (gen_loongson_punpckhbh (t2
, t1
, t0
));
21812 emit_insn (gen_loongson_punpcklbh (t3
, t1
, t0
));
21814 emit_insn (gen_loongson_punpckhbh (d
->target
, t3
, t2
));
21816 emit_insn (gen_loongson_punpcklbh (d
->target
, t3
, t2
));
21820 gcc_unreachable ();
21825 /* Recognize patterns for the Loongson PSHUFH instruction. */
21828 mips_expand_vpc_loongson_pshufh (struct expand_vec_perm_d
*d
)
21833 if (!(TARGET_HARD_FLOAT
&& TARGET_LOONGSON_MMI
))
21835 if (d
->vmode
!= V4HImode
)
21840 /* Convert the selector into the packed 8-bit form for pshufh. */
21841 /* Recall that loongson is little-endian only. No big-endian
21842 adjustment required. */
21843 for (i
= mask
= 0; i
< 4; i
++)
21844 mask
|= (d
->perm
[i
] & 3) << (i
* 2);
21845 rmask
= force_reg (SImode
, GEN_INT (mask
));
21847 if (d
->one_vector_p
)
21848 emit_insn (gen_loongson_pshufh (d
->target
, d
->op0
, rmask
));
21851 rtx t0
, t1
, x
, merge
, rmerge
[4];
21853 t0
= gen_reg_rtx (V4HImode
);
21854 t1
= gen_reg_rtx (V4HImode
);
21855 emit_insn (gen_loongson_pshufh (t1
, d
->op1
, rmask
));
21856 emit_insn (gen_loongson_pshufh (t0
, d
->op0
, rmask
));
21858 for (i
= 0; i
< 4; ++i
)
21859 rmerge
[i
] = (d
->perm
[i
] & 4 ? constm1_rtx
: const0_rtx
);
21860 merge
= gen_rtx_CONST_VECTOR (V4HImode
, gen_rtvec_v (4, rmerge
));
21861 merge
= force_reg (V4HImode
, merge
);
21863 x
= gen_rtx_AND (V4HImode
, merge
, t1
);
21864 emit_insn (gen_rtx_SET (t1
, x
));
21866 x
= gen_rtx_NOT (V4HImode
, merge
);
21867 x
= gen_rtx_AND (V4HImode
, x
, t0
);
21868 emit_insn (gen_rtx_SET (t0
, x
));
21870 x
= gen_rtx_IOR (V4HImode
, t0
, t1
);
21871 emit_insn (gen_rtx_SET (d
->target
, x
));
21877 /* Recognize broadcast patterns for the Loongson. */
21880 mips_expand_vpc_loongson_bcast (struct expand_vec_perm_d
*d
)
21885 if (!(TARGET_HARD_FLOAT
&& TARGET_LOONGSON_MMI
))
21887 /* Note that we've already matched V2SI via punpck and V4HI via pshufh. */
21888 if (d
->vmode
!= V8QImode
)
21890 if (!d
->one_vector_p
)
21894 for (i
= 1; i
< 8; ++i
)
21895 if (d
->perm
[i
] != elt
)
21901 /* With one interleave we put two of the desired element adjacent. */
21902 t0
= gen_reg_rtx (V8QImode
);
21904 emit_insn (gen_loongson_punpcklbh (t0
, d
->op0
, d
->op0
));
21906 emit_insn (gen_loongson_punpckhbh (t0
, d
->op0
, d
->op0
));
21908 /* Shuffle that one HImode element into all locations. */
21911 t1
= gen_reg_rtx (V4HImode
);
21912 emit_insn (gen_loongson_pshufh (t1
, gen_lowpart (V4HImode
, t0
),
21913 force_reg (SImode
, GEN_INT (elt
))));
21915 emit_move_insn (d
->target
, gen_lowpart (V8QImode
, t1
));
21919 /* Construct (set target (vec_select op0 (parallel selector))) and
21920 return true if that's a valid instruction in the active ISA. */
21923 mips_expand_msa_shuffle (struct expand_vec_perm_d
*d
)
21925 rtx x
, elts
[MAX_VECT_LEN
];
21933 for (i
= 0; i
< d
->nelt
; i
++)
21934 elts
[i
] = GEN_INT (d
->perm
[i
]);
21936 v
= gen_rtvec_v (d
->nelt
, elts
);
21937 x
= gen_rtx_PARALLEL (VOIDmode
, v
);
21939 if (!mips_const_vector_shuffle_set_p (x
, d
->vmode
))
21942 x
= gen_rtx_VEC_SELECT (d
->vmode
, d
->op0
, x
);
21943 x
= gen_rtx_SET (d
->target
, x
);
21945 insn
= emit_insn (x
);
21946 if (recog_memoized (insn
) < 0)
21948 remove_insn (insn
);
21955 mips_expand_vec_perm_const_1 (struct expand_vec_perm_d
*d
)
21957 unsigned int i
, nelt
= d
->nelt
;
21958 unsigned char perm2
[MAX_VECT_LEN
];
21960 if (d
->one_vector_p
)
21962 /* Try interleave with alternating operands. */
21963 memcpy (perm2
, d
->perm
, sizeof(perm2
));
21964 for (i
= 1; i
< nelt
; i
+= 2)
21966 if (mips_expand_vselect_vconcat (d
->target
, d
->op0
, d
->op1
, perm2
, nelt
))
21971 if (mips_expand_vselect_vconcat (d
->target
, d
->op0
, d
->op1
,
21975 /* Try again with swapped operands. */
21976 for (i
= 0; i
< nelt
; ++i
)
21977 perm2
[i
] = (d
->perm
[i
] + nelt
) & (2 * nelt
- 1);
21978 if (mips_expand_vselect_vconcat (d
->target
, d
->op1
, d
->op0
, perm2
, nelt
))
21982 if (mips_expand_vpc_loongson_even_odd (d
))
21984 if (mips_expand_vpc_loongson_pshufh (d
))
21986 if (mips_expand_vpc_loongson_bcast (d
))
21988 if (mips_expand_msa_shuffle (d
))
21993 /* Implement TARGET_VECTORIZE_VEC_PERM_CONST. */
21996 mips_vectorize_vec_perm_const (machine_mode vmode
, machine_mode op_mode
,
21997 rtx target
, rtx op0
, rtx op1
,
21998 const vec_perm_indices
&sel
)
22000 if (vmode
!= op_mode
)
22003 struct expand_vec_perm_d d
;
22004 int i
, nelt
, which
;
22005 unsigned char orig_perm
[MAX_VECT_LEN
];
22011 rtx nop0
= force_reg (vmode
, op0
);
22017 op1
= force_reg (vmode
, op1
);
22022 gcc_assert (VECTOR_MODE_P (vmode
));
22023 d
.nelt
= nelt
= GET_MODE_NUNITS (vmode
);
22024 d
.testing_p
= !target
;
22026 /* This is overly conservative, but ensures we don't get an
22027 uninitialized warning on ORIG_PERM. */
22028 memset (orig_perm
, 0, MAX_VECT_LEN
);
22029 for (i
= which
= 0; i
< nelt
; ++i
)
22031 int ei
= sel
[i
] & (2 * nelt
- 1);
22032 which
|= (ei
< nelt
? 1 : 2);
22035 memcpy (d
.perm
, orig_perm
, MAX_VECT_LEN
);
22043 d
.one_vector_p
= false;
22044 if (d
.testing_p
|| !rtx_equal_p (d
.op0
, d
.op1
))
22049 for (i
= 0; i
< nelt
; ++i
)
22050 d
.perm
[i
] &= nelt
- 1;
22052 d
.one_vector_p
= true;
22057 d
.one_vector_p
= true;
22063 d
.target
= gen_raw_REG (d
.vmode
, LAST_VIRTUAL_REGISTER
+ 1);
22064 d
.op1
= d
.op0
= gen_raw_REG (d
.vmode
, LAST_VIRTUAL_REGISTER
+ 2);
22065 if (!d
.one_vector_p
)
22066 d
.op1
= gen_raw_REG (d
.vmode
, LAST_VIRTUAL_REGISTER
+ 3);
22069 ok
= mips_expand_vec_perm_const_1 (&d
);
22074 ok
= mips_expand_vec_perm_const_1 (&d
);
22076 /* If we were given a two-vector permutation which just happened to
22077 have both input vectors equal, we folded this into a one-vector
22078 permutation. There are several loongson patterns that are matched
22079 via direct vec_select+vec_concat expansion, but we do not have
22080 support in mips_expand_vec_perm_const_1 to guess the adjustment
22081 that should be made for a single operand. Just try again with
22082 the original permutation. */
22083 if (!ok
&& which
== 3)
22087 d
.one_vector_p
= false;
22088 memcpy (d
.perm
, orig_perm
, MAX_VECT_LEN
);
22089 ok
= mips_expand_vec_perm_const_1 (&d
);
22095 /* Implement TARGET_SCHED_REASSOCIATION_WIDTH. */
22098 mips_sched_reassociation_width (unsigned int opc ATTRIBUTE_UNUSED
,
22101 if (MSA_SUPPORTED_MODE_P (mode
))
22106 /* Expand an integral vector unpack operation. */
22109 mips_expand_vec_unpack (rtx operands
[2], bool unsigned_p
, bool high_p
)
22111 machine_mode imode
= GET_MODE (operands
[1]);
22112 rtx (*unpack
) (rtx
, rtx
, rtx
);
22113 rtx (*cmpFunc
) (rtx
, rtx
, rtx
);
22114 rtx tmp
, dest
, zero
;
22116 if (MSA_SUPPORTED_MODE_P (imode
))
22121 if (BYTES_BIG_ENDIAN
!= high_p
)
22122 unpack
= gen_msa_ilvl_w
;
22124 unpack
= gen_msa_ilvr_w
;
22126 cmpFunc
= gen_msa_clt_s_w
;
22130 if (BYTES_BIG_ENDIAN
!= high_p
)
22131 unpack
= gen_msa_ilvl_h
;
22133 unpack
= gen_msa_ilvr_h
;
22135 cmpFunc
= gen_msa_clt_s_h
;
22139 if (BYTES_BIG_ENDIAN
!= high_p
)
22140 unpack
= gen_msa_ilvl_b
;
22142 unpack
= gen_msa_ilvr_b
;
22144 cmpFunc
= gen_msa_clt_s_b
;
22148 gcc_unreachable ();
22154 /* Extract sign extention for each element comparing each element
22155 with immediate zero. */
22156 tmp
= gen_reg_rtx (imode
);
22157 emit_insn (cmpFunc (tmp
, operands
[1], CONST0_RTX (imode
)));
22160 tmp
= force_reg (imode
, CONST0_RTX (imode
));
22162 dest
= gen_reg_rtx (imode
);
22164 emit_insn (unpack (dest
, operands
[1], tmp
));
22165 emit_move_insn (operands
[0], gen_lowpart (GET_MODE (operands
[0]), dest
));
22173 unpack
= gen_loongson_punpckhbh
;
22175 unpack
= gen_loongson_punpcklbh
;
22176 cmpFunc
= gen_loongson_pcmpgtb
;
22180 unpack
= gen_loongson_punpckhhw
;
22182 unpack
= gen_loongson_punpcklhw
;
22183 cmpFunc
= gen_loongson_pcmpgth
;
22186 gcc_unreachable ();
22189 zero
= force_reg (imode
, CONST0_RTX (imode
));
22194 tmp
= gen_reg_rtx (imode
);
22195 emit_insn (cmpFunc (tmp
, zero
, operands
[1]));
22198 dest
= gen_reg_rtx (imode
);
22199 emit_insn (unpack (dest
, operands
[1], tmp
));
22201 emit_move_insn (operands
[0], gen_lowpart (GET_MODE (operands
[0]), dest
));
22204 /* Construct and return PARALLEL RTX with CONST_INTs for HIGH (high_p == TRUE)
22205 or LOW (high_p == FALSE) half of a vector for mode MODE. */
22208 mips_msa_vec_parallel_const_half (machine_mode mode
, bool high_p
)
22210 int nunits
= GET_MODE_NUNITS (mode
);
22211 rtvec v
= rtvec_alloc (nunits
/ 2);
22215 if (BYTES_BIG_ENDIAN
)
22216 base
= high_p
? 0 : nunits
/ 2;
22218 base
= high_p
? nunits
/ 2 : 0;
22220 for (i
= 0; i
< nunits
/ 2; i
++)
22221 RTVEC_ELT (v
, i
) = GEN_INT (base
+ i
);
22223 return gen_rtx_PARALLEL (VOIDmode
, v
);
22226 /* A subroutine of mips_expand_vec_init, match constant vector elements. */
22229 mips_constant_elt_p (rtx x
)
22231 return CONST_INT_P (x
) || GET_CODE (x
) == CONST_DOUBLE
;
22234 /* A subroutine of mips_expand_vec_init, expand via broadcast. */
22237 mips_expand_vi_broadcast (machine_mode vmode
, rtx target
, rtx elt
)
22239 struct expand_vec_perm_d d
;
22243 if (elt
!= const0_rtx
)
22244 elt
= force_reg (GET_MODE_INNER (vmode
), elt
);
22246 elt
= gen_lowpart (DImode
, elt
);
22248 t1
= gen_reg_rtx (vmode
);
22252 emit_insn (gen_loongson_vec_init1_v8qi (t1
, elt
));
22255 emit_insn (gen_loongson_vec_init1_v4hi (t1
, elt
));
22258 gcc_unreachable ();
22261 memset (&d
, 0, sizeof (d
));
22266 d
.nelt
= GET_MODE_NUNITS (vmode
);
22267 d
.one_vector_p
= true;
22269 ok
= mips_expand_vec_perm_const_1 (&d
);
22273 /* Return a const_int vector of VAL with mode MODE. */
22276 mips_gen_const_int_vector (machine_mode mode
, HOST_WIDE_INT val
)
22278 rtx c
= gen_int_mode (val
, GET_MODE_INNER (mode
));
22279 return gen_const_vec_duplicate (mode
, c
);
22282 /* Return a vector of repeated 4-element sets generated from
22283 immediate VAL in mode MODE. */
22286 mips_gen_const_int_vector_shuffle (machine_mode mode
, int val
)
22288 int nunits
= GET_MODE_NUNITS (mode
);
22289 int nsets
= nunits
/ 4;
22290 rtx elts
[MAX_VECT_LEN
];
22294 /* Generate a const_int vector replicating the same 4-element set
22295 from an immediate. */
22296 for (j
= 0; j
< nsets
; j
++, set
= 4 * j
)
22297 for (i
= 0; i
< 4; i
++)
22298 elts
[set
+ i
] = GEN_INT (set
+ ((val
>> (2 * i
)) & 0x3));
22300 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec_v (nunits
, elts
));
22303 /* A subroutine of mips_expand_vec_init, replacing all of the non-constant
22304 elements of VALS with zeros, copy the constant vector to TARGET. */
22307 mips_expand_vi_constant (machine_mode vmode
, unsigned nelt
,
22308 rtx target
, rtx vals
)
22310 rtvec vec
= shallow_copy_rtvec (XVEC (vals
, 0));
22313 for (i
= 0; i
< nelt
; ++i
)
22315 rtx elem
= RTVEC_ELT (vec
, i
);
22316 if (!mips_constant_elt_p (elem
))
22317 RTVEC_ELT (vec
, i
) = CONST0_RTX (GET_MODE (elem
));
22320 emit_move_insn (target
, gen_rtx_CONST_VECTOR (vmode
, vec
));
22324 /* A subroutine of mips_expand_vec_init, expand via pinsrh. */
22327 mips_expand_vi_loongson_one_pinsrh (rtx target
, rtx vals
, unsigned one_var
)
22329 mips_expand_vi_constant (V4HImode
, 4, target
, vals
);
22331 emit_insn (gen_vec_setv4hi (target
, target
, XVECEXP (vals
, 0, one_var
),
22332 GEN_INT (one_var
)));
22335 /* A subroutine of mips_expand_vec_init, expand anything via memory. */
22338 mips_expand_vi_general (machine_mode vmode
, machine_mode imode
,
22339 unsigned nelt
, unsigned nvar
, rtx target
, rtx vals
)
22341 rtx mem
= assign_stack_temp (vmode
, GET_MODE_SIZE (vmode
));
22342 unsigned int i
, isize
= GET_MODE_SIZE (imode
);
22345 mips_expand_vi_constant (vmode
, nelt
, mem
, vals
);
22347 for (i
= 0; i
< nelt
; ++i
)
22349 rtx x
= XVECEXP (vals
, 0, i
);
22350 if (!mips_constant_elt_p (x
))
22351 emit_move_insn (adjust_address (mem
, imode
, i
* isize
), x
);
22354 emit_move_insn (target
, mem
);
22357 /* Expand a vector initialization. */
22360 mips_expand_vector_init (rtx target
, rtx vals
)
22362 machine_mode vmode
= GET_MODE (target
);
22363 machine_mode imode
= GET_MODE_INNER (vmode
);
22364 unsigned i
, nelt
= GET_MODE_NUNITS (vmode
);
22365 unsigned nvar
= 0, one_var
= -1u;
22366 bool all_same
= true;
22369 for (i
= 0; i
< nelt
; ++i
)
22371 x
= XVECEXP (vals
, 0, i
);
22372 if (!mips_constant_elt_p (x
))
22373 nvar
++, one_var
= i
;
22374 if (i
> 0 && !rtx_equal_p (x
, XVECEXP (vals
, 0, 0)))
22378 if (MSA_SUPPORTED_MODE_P (vmode
))
22382 rtx same
= XVECEXP (vals
, 0, 0);
22385 if (CONST_INT_P (same
) && nvar
== 0
22386 && mips_signed_immediate_p (INTVAL (same
), 10, 0))
22394 temp
= gen_rtx_CONST_VECTOR (vmode
, XVEC (vals
, 0));
22395 emit_move_insn (target
, temp
);
22399 gcc_unreachable ();
22402 temp
= gen_reg_rtx (imode
);
22403 if (imode
== GET_MODE (same
))
22405 else if (GET_MODE_SIZE (imode
) >= UNITS_PER_WORD
)
22406 temp2
= simplify_gen_subreg (imode
, same
, GET_MODE (same
), 0);
22408 temp2
= lowpart_subreg (imode
, same
, GET_MODE (same
));
22409 emit_move_insn (temp
, temp2
);
22417 mips_emit_move (target
, gen_rtx_VEC_DUPLICATE (vmode
, temp
));
22421 emit_insn (gen_msa_splati_w_f_scalar (target
, temp
));
22425 emit_insn (gen_msa_splati_d_f_scalar (target
, temp
));
22429 gcc_unreachable ();
22434 emit_move_insn (target
, CONST0_RTX (vmode
));
22436 for (i
= 0; i
< nelt
; ++i
)
22438 rtx temp
= gen_reg_rtx (imode
);
22439 emit_move_insn (temp
, XVECEXP (vals
, 0, i
));
22443 emit_insn (gen_vec_setv16qi (target
, temp
, GEN_INT (i
)));
22447 emit_insn (gen_vec_setv8hi (target
, temp
, GEN_INT (i
)));
22451 emit_insn (gen_vec_setv4si (target
, temp
, GEN_INT (i
)));
22455 emit_insn (gen_vec_setv2di (target
, temp
, GEN_INT (i
)));
22459 emit_insn (gen_vec_setv4sf (target
, temp
, GEN_INT (i
)));
22463 emit_insn (gen_vec_setv2df (target
, temp
, GEN_INT (i
)));
22467 gcc_unreachable ();
22474 /* Load constants from the pool, or whatever's handy. */
22477 emit_move_insn (target
, gen_rtx_CONST_VECTOR (vmode
, XVEC (vals
, 0)));
22481 /* For two-part initialization, always use CONCAT. */
22484 rtx op0
= force_reg (imode
, XVECEXP (vals
, 0, 0));
22485 rtx op1
= force_reg (imode
, XVECEXP (vals
, 0, 1));
22486 x
= gen_rtx_VEC_CONCAT (vmode
, op0
, op1
);
22487 emit_insn (gen_rtx_SET (target
, x
));
22491 /* Loongson is the only cpu with vectors with more elements. */
22492 gcc_assert (TARGET_HARD_FLOAT
&& TARGET_LOONGSON_MMI
);
22494 /* If all values are identical, broadcast the value. */
22497 mips_expand_vi_broadcast (vmode
, target
, XVECEXP (vals
, 0, 0));
22501 /* If we've only got one non-variable V4HImode, use PINSRH. */
22502 if (nvar
== 1 && vmode
== V4HImode
)
22504 mips_expand_vi_loongson_one_pinsrh (target
, vals
, one_var
);
22508 mips_expand_vi_general (vmode
, imode
, nelt
, nvar
, target
, vals
);
22511 /* Expand a vector reduction. */
22514 mips_expand_vec_reduc (rtx target
, rtx in
, rtx (*gen
)(rtx
, rtx
, rtx
))
22516 machine_mode vmode
= GET_MODE (in
);
22517 unsigned char perm2
[2];
22518 rtx last
, next
, fold
, x
;
22522 fold
= gen_reg_rtx (vmode
);
22526 /* Use PUL/PLU to produce { L, H } op { H, L }.
22527 By reversing the pair order, rather than a pure interleave high,
22528 we avoid erroneous exceptional conditions that we might otherwise
22529 produce from the computation of H op H. */
22532 ok
= mips_expand_vselect_vconcat (fold
, last
, last
, perm2
, 2);
22537 /* Use interleave to produce { H, L } op { H, H }. */
22538 emit_insn (gen_loongson_punpckhwd (fold
, last
, last
));
22542 /* Perform the first reduction with interleave,
22543 and subsequent reductions with shifts. */
22544 emit_insn (gen_loongson_punpckhwd_hi (fold
, last
, last
));
22546 next
= gen_reg_rtx (vmode
);
22547 emit_insn (gen (next
, last
, fold
));
22550 fold
= gen_reg_rtx (vmode
);
22551 x
= force_reg (SImode
, GEN_INT (16));
22552 emit_insn (gen_vec_shr_v4hi (fold
, last
, x
));
22556 emit_insn (gen_loongson_punpckhwd_qi (fold
, last
, last
));
22558 next
= gen_reg_rtx (vmode
);
22559 emit_insn (gen (next
, last
, fold
));
22562 fold
= gen_reg_rtx (vmode
);
22563 x
= force_reg (SImode
, GEN_INT (16));
22564 emit_insn (gen_vec_shr_v8qi (fold
, last
, x
));
22566 next
= gen_reg_rtx (vmode
);
22567 emit_insn (gen (next
, last
, fold
));
22570 fold
= gen_reg_rtx (vmode
);
22571 x
= force_reg (SImode
, GEN_INT (8));
22572 emit_insn (gen_vec_shr_v8qi (fold
, last
, x
));
22576 gcc_unreachable ();
22579 emit_insn (gen (target
, last
, fold
));
22582 /* Expand a vector minimum/maximum. */
22585 mips_expand_vec_minmax (rtx target
, rtx op0
, rtx op1
,
22586 rtx (*cmp
) (rtx
, rtx
, rtx
), bool min_p
)
22588 machine_mode vmode
= GET_MODE (target
);
22591 tc
= gen_reg_rtx (vmode
);
22592 t0
= gen_reg_rtx (vmode
);
22593 t1
= gen_reg_rtx (vmode
);
22596 emit_insn (cmp (tc
, op0
, op1
));
22598 x
= gen_rtx_AND (vmode
, tc
, (min_p
? op1
: op0
));
22599 emit_insn (gen_rtx_SET (t0
, x
));
22601 x
= gen_rtx_NOT (vmode
, tc
);
22602 x
= gen_rtx_AND (vmode
, x
, (min_p
? op0
: op1
));
22603 emit_insn (gen_rtx_SET (t1
, x
));
22605 x
= gen_rtx_IOR (vmode
, t0
, t1
);
22606 emit_insn (gen_rtx_SET (target
, x
));
22609 /* Implement HARD_REGNO_CALLER_SAVE_MODE. */
22612 mips_hard_regno_caller_save_mode (unsigned int regno
,
22613 unsigned int nregs
,
22616 /* For performance, avoid saving/restoring upper parts of a register
22617 by returning MODE as save mode when the mode is known. */
22618 if (mode
== VOIDmode
)
22619 return choose_hard_reg_mode (regno
, nregs
, NULL
);
22624 /* Generate RTL for comparing CMP_OP0 and CMP_OP1 using condition COND and
22625 store the result -1 or 0 in DEST. */
22628 mips_expand_msa_cmp (rtx dest
, enum rtx_code cond
, rtx op0
, rtx op1
)
22630 machine_mode cmp_mode
= GET_MODE (op0
);
22632 bool negate
= false;
22643 cond
= reverse_condition (cond
);
22656 std::swap (op0
, op1
);
22657 cond
= swap_condition (cond
);
22660 gcc_unreachable ();
22662 mips_emit_binary (cond
, dest
, op0
, op1
);
22664 emit_move_insn (dest
, gen_rtx_NOT (GET_MODE (dest
), dest
));
22679 case LTGT
: cond
= NE
; break;
22680 case UNGE
: cond
= UNLE
; std::swap (op0
, op1
); break;
22681 case UNGT
: cond
= UNLT
; std::swap (op0
, op1
); break;
22682 case LE
: unspec
= UNSPEC_MSA_FSLE
; break;
22683 case LT
: unspec
= UNSPEC_MSA_FSLT
; break;
22684 case GE
: unspec
= UNSPEC_MSA_FSLE
; std::swap (op0
, op1
); break;
22685 case GT
: unspec
= UNSPEC_MSA_FSLT
; std::swap (op0
, op1
); break;
22687 gcc_unreachable ();
22690 mips_emit_binary (cond
, dest
, op0
, op1
);
22693 rtx x
= gen_rtx_UNSPEC (GET_MODE (dest
),
22694 gen_rtvec (2, op0
, op1
), unspec
);
22695 emit_insn (gen_rtx_SET (dest
, x
));
22700 gcc_unreachable ();
22706 mips_expand_vec_cmp_expr (rtx
*operands
)
22708 rtx cond
= operands
[1];
22709 rtx op0
= operands
[2];
22710 rtx op1
= operands
[3];
22711 rtx res
= operands
[0];
22713 mips_expand_msa_cmp (res
, GET_CODE (cond
), op0
, op1
);
22716 /* Expand VEC_COND_EXPR, where:
22717 MODE is mode of the result
22718 VIMODE equivalent integer mode
22719 OPERANDS operands of VEC_COND_EXPR. */
22722 mips_expand_vec_cond_expr (machine_mode mode
, machine_mode vimode
,
22725 rtx cond
= operands
[3];
22726 rtx cmp_op0
= operands
[4];
22727 rtx cmp_op1
= operands
[5];
22728 rtx cmp_res
= gen_reg_rtx (vimode
);
22730 mips_expand_msa_cmp (cmp_res
, GET_CODE (cond
), cmp_op0
, cmp_op1
);
22732 /* We handle the following cases:
22733 1) r = a CMP b ? -1 : 0
22734 2) r = a CMP b ? -1 : v
22735 3) r = a CMP b ? v : 0
22736 4) r = a CMP b ? v1 : v2 */
22738 /* Case (1) above. We only move the results. */
22739 if (operands
[1] == CONSTM1_RTX (vimode
)
22740 && operands
[2] == CONST0_RTX (vimode
))
22741 emit_move_insn (operands
[0], cmp_res
);
22744 rtx src1
= gen_reg_rtx (vimode
);
22745 rtx src2
= gen_reg_rtx (vimode
);
22746 rtx mask
= gen_reg_rtx (vimode
);
22749 /* Move the vector result to use it as a mask. */
22750 emit_move_insn (mask
, cmp_res
);
22752 if (register_operand (operands
[1], mode
))
22754 rtx xop1
= operands
[1];
22755 if (mode
!= vimode
)
22757 xop1
= gen_reg_rtx (vimode
);
22758 emit_move_insn (xop1
, gen_lowpart (vimode
, operands
[1]));
22760 emit_move_insn (src1
, xop1
);
22764 gcc_assert (operands
[1] == CONSTM1_RTX (vimode
));
22765 /* Case (2) if the below doesn't move the mask to src2. */
22766 emit_move_insn (src1
, mask
);
22769 if (register_operand (operands
[2], mode
))
22771 rtx xop2
= operands
[2];
22772 if (mode
!= vimode
)
22774 xop2
= gen_reg_rtx (vimode
);
22775 emit_move_insn (xop2
, gen_lowpart (vimode
, operands
[2]));
22777 emit_move_insn (src2
, xop2
);
22781 gcc_assert (operands
[2] == CONST0_RTX (mode
));
22782 /* Case (3) if the above didn't move the mask to src1. */
22783 emit_move_insn (src2
, mask
);
22786 /* We deal with case (4) if the mask wasn't moved to either src1 or src2.
22787 In any case, we eventually do vector mask-based copy. */
22788 bsel
= gen_rtx_IOR (vimode
,
22789 gen_rtx_AND (vimode
,
22790 gen_rtx_NOT (vimode
, mask
), src2
),
22791 gen_rtx_AND (vimode
, mask
, src1
));
22792 /* The result is placed back to a register with the mask. */
22793 emit_insn (gen_rtx_SET (mask
, bsel
));
22794 emit_move_insn (operands
[0], gen_rtx_SUBREG (mode
, mask
, 0));
22798 /* Implement TARGET_CASE_VALUES_THRESHOLD. */
22801 mips_case_values_threshold (void)
22803 /* In MIPS16 mode using a larger case threshold generates smaller code. */
22804 if (TARGET_MIPS16
&& optimize_size
)
22807 return default_case_values_threshold ();
22810 /* Implement TARGET_ATOMIC_ASSIGN_EXPAND_FENV. */
22813 mips_atomic_assign_expand_fenv (tree
*hold
, tree
*clear
, tree
*update
)
22815 if (!TARGET_HARD_FLOAT_ABI
)
22817 tree exceptions_var
= create_tmp_var_raw (MIPS_ATYPE_USI
);
22818 tree fcsr_orig_var
= create_tmp_var_raw (MIPS_ATYPE_USI
);
22819 tree fcsr_mod_var
= create_tmp_var_raw (MIPS_ATYPE_USI
);
22820 tree get_fcsr
= mips_builtin_decls
[MIPS_GET_FCSR
];
22821 tree set_fcsr
= mips_builtin_decls
[MIPS_SET_FCSR
];
22822 tree get_fcsr_hold_call
= build_call_expr (get_fcsr
, 0);
22823 tree hold_assign_orig
= build4 (TARGET_EXPR
, MIPS_ATYPE_USI
,
22824 fcsr_orig_var
, get_fcsr_hold_call
, NULL
, NULL
);
22825 tree hold_mod_val
= build2 (BIT_AND_EXPR
, MIPS_ATYPE_USI
, fcsr_orig_var
,
22826 build_int_cst (MIPS_ATYPE_USI
, 0xfffff003));
22827 tree hold_assign_mod
= build4 (TARGET_EXPR
, MIPS_ATYPE_USI
,
22828 fcsr_mod_var
, hold_mod_val
, NULL
, NULL
);
22829 tree set_fcsr_hold_call
= build_call_expr (set_fcsr
, 1, fcsr_mod_var
);
22830 tree hold_all
= build2 (COMPOUND_EXPR
, MIPS_ATYPE_USI
,
22831 hold_assign_orig
, hold_assign_mod
);
22832 *hold
= build2 (COMPOUND_EXPR
, void_type_node
, hold_all
,
22833 set_fcsr_hold_call
);
22835 *clear
= build_call_expr (set_fcsr
, 1, fcsr_mod_var
);
22837 tree get_fcsr_update_call
= build_call_expr (get_fcsr
, 0);
22838 *update
= build4 (TARGET_EXPR
, MIPS_ATYPE_USI
,
22839 exceptions_var
, get_fcsr_update_call
, NULL
, NULL
);
22840 tree set_fcsr_update_call
= build_call_expr (set_fcsr
, 1, fcsr_orig_var
);
22841 *update
= build2 (COMPOUND_EXPR
, void_type_node
, *update
,
22842 set_fcsr_update_call
);
22843 tree atomic_feraiseexcept
22844 = builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT
);
22845 tree int_exceptions_var
= fold_convert (integer_type_node
,
22847 tree atomic_feraiseexcept_call
= build_call_expr (atomic_feraiseexcept
,
22848 1, int_exceptions_var
);
22849 *update
= build2 (COMPOUND_EXPR
, void_type_node
, *update
,
22850 atomic_feraiseexcept_call
);
22853 /* Implement TARGET_SPILL_CLASS. */
22856 mips_spill_class (reg_class_t rclass ATTRIBUTE_UNUSED
,
22857 machine_mode mode ATTRIBUTE_UNUSED
)
22864 /* Implement TARGET_LRA_P. */
22869 return mips_lra_flag
;
22872 /* Implement TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS. */
22875 mips_ira_change_pseudo_allocno_class (int regno
, reg_class_t allocno_class
,
22876 reg_class_t best_class ATTRIBUTE_UNUSED
)
22878 /* LRA will allocate an FPR for an integer mode pseudo instead of spilling
22879 to memory if an FPR is present in the allocno class. It is rare that
22880 we actually need to place an integer mode value in an FPR so where
22881 possible limit the allocation to GR_REGS. This will slightly pessimize
22882 code that involves integer to/from float conversions as these will have
22883 to reload into FPRs in LRA. Such reloads are sometimes eliminated and
22884 sometimes only partially eliminated. We choose to take this penalty
22885 in order to eliminate usage of FPRs in code that does not use floating
22888 This change has a similar effect to increasing the cost of FPR->GPR
22889 register moves for integer modes so that they are higher than the cost
22890 of memory but changing the allocno class is more reliable.
22892 This is also similar to forbidding integer mode values in FPRs entirely
22893 but this would lead to an inconsistency in the integer to/from float
22894 instructions that say integer mode values must be placed in FPRs. */
22895 if (INTEGRAL_MODE_P (PSEUDO_REGNO_MODE (regno
)) && allocno_class
== ALL_REGS
)
22897 return allocno_class
;
22900 /* Implement TARGET_PROMOTE_FUNCTION_MODE */
22902 /* This function is equivalent to default_promote_function_mode_always_promote
22903 except that it returns a promoted mode even if type is NULL_TREE. This is
22904 needed by libcalls which have no type (only a mode) such as fixed conversion
22905 routines that take a signed or unsigned char/short argument and convert it
22906 to a fixed type. */
22908 static machine_mode
22909 mips_promote_function_mode (const_tree type ATTRIBUTE_UNUSED
,
22911 int *punsignedp ATTRIBUTE_UNUSED
,
22912 const_tree fntype ATTRIBUTE_UNUSED
,
22913 int for_return ATTRIBUTE_UNUSED
)
22917 if (type
!= NULL_TREE
)
22918 return promote_mode (type
, mode
, punsignedp
);
22920 unsignedp
= *punsignedp
;
22921 PROMOTE_MODE (mode
, unsignedp
, type
);
22922 *punsignedp
= unsignedp
;
22926 /* Implement TARGET_TRULY_NOOP_TRUNCATION. */
22929 mips_truly_noop_truncation (poly_uint64 outprec
, poly_uint64 inprec
)
22931 return !TARGET_64BIT
|| inprec
<= 32 || outprec
> 32;
22934 /* Implement TARGET_CONSTANT_ALIGNMENT. */
22936 static HOST_WIDE_INT
22937 mips_constant_alignment (const_tree exp
, HOST_WIDE_INT align
)
22939 if (TREE_CODE (exp
) == STRING_CST
|| TREE_CODE (exp
) == CONSTRUCTOR
)
22940 return MAX (align
, BITS_PER_WORD
);
22944 /* Implement the TARGET_ASAN_SHADOW_OFFSET hook. */
22946 static unsigned HOST_WIDE_INT
22947 mips_asan_shadow_offset (void)
22949 if (mips_abi
== ABI_N32
)
22950 return (HOST_WIDE_INT_1
<< 29);
22951 if (POINTER_SIZE
== 64)
22952 return (HOST_WIDE_INT_1
<< 37);
22954 return HOST_WIDE_INT_C (0x0aaa0000);
22957 /* Implement TARGET_STARTING_FRAME_OFFSET. See mips_compute_frame_info
22958 for details about the frame layout. */
22960 static HOST_WIDE_INT
22961 mips_starting_frame_offset (void)
22963 if (FRAME_GROWS_DOWNWARD
)
22965 return crtl
->outgoing_args_size
+ MIPS_GP_SAVE_AREA_SIZE
;
22969 mips_asm_file_end (void)
22971 if (NEED_INDICATE_EXEC_STACK
)
22972 file_end_indicate_exec_stack ();
22976 mips_bit_clear_info (enum machine_mode mode
, unsigned HOST_WIDE_INT m
,
22977 int *start_pos
, int *size
)
22979 unsigned int shift
= 0;
22980 unsigned int change_count
= 0;
22981 unsigned int prev_val
= 1;
22982 unsigned int curr_val
= 0;
22983 unsigned int end_pos
= GET_MODE_SIZE (mode
) * BITS_PER_UNIT
;
22985 for (shift
= 0 ; shift
< (GET_MODE_SIZE (mode
) * BITS_PER_UNIT
) ; shift
++)
22987 curr_val
= (unsigned int)((m
& (unsigned int)(1 << shift
)) >> shift
);
22988 if (curr_val
!= prev_val
)
22991 switch (change_count
)
22994 *start_pos
= shift
;
23000 gcc_unreachable ();
23003 prev_val
= curr_val
;
23005 *size
= (end_pos
- *start_pos
);
23009 mips_bit_clear_p (enum machine_mode mode
, unsigned HOST_WIDE_INT m
)
23011 unsigned int shift
= 0;
23012 unsigned int change_count
= 0;
23013 unsigned int prev_val
= 1;
23014 unsigned int curr_val
= 0;
23016 if (mode
!= SImode
&& mode
!= VOIDmode
)
23019 if (!ISA_HAS_EXT_INS
)
23022 for (shift
= 0 ; shift
< (UNITS_PER_WORD
* BITS_PER_UNIT
) ; shift
++)
23024 curr_val
= (unsigned int)((m
& (unsigned int)(1 << shift
)) >> shift
);
23025 if (curr_val
!= prev_val
)
23027 prev_val
= curr_val
;
23030 if (change_count
== 2)
23036 /* Initialize the GCC target structure. */
23037 #undef TARGET_ASM_ALIGNED_HI_OP
23038 #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
23039 #undef TARGET_ASM_ALIGNED_SI_OP
23040 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
23041 #undef TARGET_ASM_ALIGNED_DI_OP
23042 #define TARGET_ASM_ALIGNED_DI_OP "\t.dword\t"
23044 #undef TARGET_OPTION_OVERRIDE
23045 #define TARGET_OPTION_OVERRIDE mips_option_override
23047 #undef TARGET_LEGITIMIZE_ADDRESS
23048 #define TARGET_LEGITIMIZE_ADDRESS mips_legitimize_address
23050 #undef TARGET_ASM_FUNCTION_PROLOGUE
23051 #define TARGET_ASM_FUNCTION_PROLOGUE mips_output_function_prologue
23052 #undef TARGET_ASM_FUNCTION_EPILOGUE
23053 #define TARGET_ASM_FUNCTION_EPILOGUE mips_output_function_epilogue
23054 #undef TARGET_ASM_SELECT_RTX_SECTION
23055 #define TARGET_ASM_SELECT_RTX_SECTION mips_select_rtx_section
23057 #undef TARGET_SCHED_INIT
23058 #define TARGET_SCHED_INIT mips_sched_init
23059 #undef TARGET_SCHED_REORDER
23060 #define TARGET_SCHED_REORDER mips_sched_reorder
23061 #undef TARGET_SCHED_REORDER2
23062 #define TARGET_SCHED_REORDER2 mips_sched_reorder2
23063 #undef TARGET_SCHED_VARIABLE_ISSUE
23064 #define TARGET_SCHED_VARIABLE_ISSUE mips_variable_issue
23065 #undef TARGET_SCHED_ADJUST_COST
23066 #define TARGET_SCHED_ADJUST_COST mips_adjust_cost
23067 #undef TARGET_SCHED_ISSUE_RATE
23068 #define TARGET_SCHED_ISSUE_RATE mips_issue_rate
23069 #undef TARGET_SCHED_INIT_DFA_POST_CYCLE_INSN
23070 #define TARGET_SCHED_INIT_DFA_POST_CYCLE_INSN mips_init_dfa_post_cycle_insn
23071 #undef TARGET_SCHED_DFA_POST_ADVANCE_CYCLE
23072 #define TARGET_SCHED_DFA_POST_ADVANCE_CYCLE mips_dfa_post_advance_cycle
23073 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
23074 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
23075 mips_multipass_dfa_lookahead
23076 #undef TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P
23077 #define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P \
23078 mips_small_register_classes_for_mode_p
23080 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
23081 #define TARGET_FUNCTION_OK_FOR_SIBCALL mips_function_ok_for_sibcall
23083 #undef TARGET_INSERT_ATTRIBUTES
23084 #define TARGET_INSERT_ATTRIBUTES mips_insert_attributes
23085 #undef TARGET_MERGE_DECL_ATTRIBUTES
23086 #define TARGET_MERGE_DECL_ATTRIBUTES mips_merge_decl_attributes
23087 #undef TARGET_CAN_INLINE_P
23088 #define TARGET_CAN_INLINE_P mips_can_inline_p
23089 #undef TARGET_SET_CURRENT_FUNCTION
23090 #define TARGET_SET_CURRENT_FUNCTION mips_set_current_function
23092 #undef TARGET_VALID_POINTER_MODE
23093 #define TARGET_VALID_POINTER_MODE mips_valid_pointer_mode
23094 #undef TARGET_REGISTER_MOVE_COST
23095 #define TARGET_REGISTER_MOVE_COST mips_register_move_cost
23096 #undef TARGET_REGISTER_PRIORITY
23097 #define TARGET_REGISTER_PRIORITY mips_register_priority
23098 #undef TARGET_MEMORY_MOVE_COST
23099 #define TARGET_MEMORY_MOVE_COST mips_memory_move_cost
23100 #undef TARGET_RTX_COSTS
23101 #define TARGET_RTX_COSTS mips_rtx_costs
23102 #undef TARGET_ADDRESS_COST
23103 #define TARGET_ADDRESS_COST mips_address_cost
23104 #undef TARGET_INSN_COST
23105 #define TARGET_INSN_COST mips_insn_cost
23107 #undef TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P
23108 #define TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P mips_no_speculation_in_delay_slots_p
23110 #undef TARGET_IN_SMALL_DATA_P
23111 #define TARGET_IN_SMALL_DATA_P mips_in_small_data_p
23113 #undef TARGET_MACHINE_DEPENDENT_REORG
23114 #define TARGET_MACHINE_DEPENDENT_REORG mips_reorg
23116 #undef TARGET_PREFERRED_RELOAD_CLASS
23117 #define TARGET_PREFERRED_RELOAD_CLASS mips_preferred_reload_class
23119 #undef TARGET_EXPAND_TO_RTL_HOOK
23120 #define TARGET_EXPAND_TO_RTL_HOOK mips_expand_to_rtl_hook
23121 #undef TARGET_ASM_FILE_START
23122 #define TARGET_ASM_FILE_START mips_file_start
23123 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
23124 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
23125 #undef TARGET_ASM_CODE_END
23126 #define TARGET_ASM_CODE_END mips_code_end
23128 #undef TARGET_INIT_LIBFUNCS
23129 #define TARGET_INIT_LIBFUNCS mips_init_libfuncs
23131 #undef TARGET_BUILD_BUILTIN_VA_LIST
23132 #define TARGET_BUILD_BUILTIN_VA_LIST mips_build_builtin_va_list
23133 #undef TARGET_EXPAND_BUILTIN_VA_START
23134 #define TARGET_EXPAND_BUILTIN_VA_START mips_va_start
23135 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
23136 #define TARGET_GIMPLIFY_VA_ARG_EXPR mips_gimplify_va_arg_expr
23138 #undef TARGET_PROMOTE_FUNCTION_MODE
23139 #define TARGET_PROMOTE_FUNCTION_MODE mips_promote_function_mode
23140 #undef TARGET_FUNCTION_VALUE
23141 #define TARGET_FUNCTION_VALUE mips_function_value
23142 #undef TARGET_LIBCALL_VALUE
23143 #define TARGET_LIBCALL_VALUE mips_libcall_value
23144 #undef TARGET_FUNCTION_VALUE_REGNO_P
23145 #define TARGET_FUNCTION_VALUE_REGNO_P mips_function_value_regno_p
23146 #undef TARGET_RETURN_IN_MEMORY
23147 #define TARGET_RETURN_IN_MEMORY mips_return_in_memory
23148 #undef TARGET_RETURN_IN_MSB
23149 #define TARGET_RETURN_IN_MSB mips_return_in_msb
23151 #undef TARGET_ASM_OUTPUT_MI_THUNK
23152 #define TARGET_ASM_OUTPUT_MI_THUNK mips_output_mi_thunk
23153 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
23154 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
23156 #undef TARGET_PRINT_OPERAND
23157 #define TARGET_PRINT_OPERAND mips_print_operand
23158 #undef TARGET_PRINT_OPERAND_ADDRESS
23159 #define TARGET_PRINT_OPERAND_ADDRESS mips_print_operand_address
23160 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
23161 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P mips_print_operand_punct_valid_p
23163 #undef TARGET_SETUP_INCOMING_VARARGS
23164 #define TARGET_SETUP_INCOMING_VARARGS mips_setup_incoming_varargs
23165 #undef TARGET_STRICT_ARGUMENT_NAMING
23166 #define TARGET_STRICT_ARGUMENT_NAMING mips_strict_argument_naming
23167 #undef TARGET_MUST_PASS_IN_STACK
23168 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
23169 #undef TARGET_PASS_BY_REFERENCE
23170 #define TARGET_PASS_BY_REFERENCE mips_pass_by_reference
23171 #undef TARGET_CALLEE_COPIES
23172 #define TARGET_CALLEE_COPIES mips_callee_copies
23173 #undef TARGET_ARG_PARTIAL_BYTES
23174 #define TARGET_ARG_PARTIAL_BYTES mips_arg_partial_bytes
23175 #undef TARGET_FUNCTION_ARG
23176 #define TARGET_FUNCTION_ARG mips_function_arg
23177 #undef TARGET_FUNCTION_ARG_ADVANCE
23178 #define TARGET_FUNCTION_ARG_ADVANCE mips_function_arg_advance
23179 #undef TARGET_FUNCTION_ARG_PADDING
23180 #define TARGET_FUNCTION_ARG_PADDING mips_function_arg_padding
23181 #undef TARGET_FUNCTION_ARG_BOUNDARY
23182 #define TARGET_FUNCTION_ARG_BOUNDARY mips_function_arg_boundary
23183 #undef TARGET_GET_RAW_RESULT_MODE
23184 #define TARGET_GET_RAW_RESULT_MODE mips_get_reg_raw_mode
23185 #undef TARGET_GET_RAW_ARG_MODE
23186 #define TARGET_GET_RAW_ARG_MODE mips_get_reg_raw_mode
23188 #undef TARGET_MODE_REP_EXTENDED
23189 #define TARGET_MODE_REP_EXTENDED mips_mode_rep_extended
23191 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
23192 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
23193 mips_builtin_vectorized_function
23194 #undef TARGET_VECTOR_MODE_SUPPORTED_P
23195 #define TARGET_VECTOR_MODE_SUPPORTED_P mips_vector_mode_supported_p
23197 #undef TARGET_SCALAR_MODE_SUPPORTED_P
23198 #define TARGET_SCALAR_MODE_SUPPORTED_P mips_scalar_mode_supported_p
23200 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
23201 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE mips_preferred_simd_mode
23202 #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES
23203 #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES \
23204 mips_autovectorize_vector_modes
23206 #undef TARGET_INIT_BUILTINS
23207 #define TARGET_INIT_BUILTINS mips_init_builtins
23208 #undef TARGET_BUILTIN_DECL
23209 #define TARGET_BUILTIN_DECL mips_builtin_decl
23210 #undef TARGET_EXPAND_BUILTIN
23211 #define TARGET_EXPAND_BUILTIN mips_expand_builtin
23213 #undef TARGET_HAVE_TLS
23214 #define TARGET_HAVE_TLS HAVE_AS_TLS
23216 #undef TARGET_CANNOT_FORCE_CONST_MEM
23217 #define TARGET_CANNOT_FORCE_CONST_MEM mips_cannot_force_const_mem
23219 #undef TARGET_LEGITIMATE_CONSTANT_P
23220 #define TARGET_LEGITIMATE_CONSTANT_P mips_legitimate_constant_p
23222 #undef TARGET_ENCODE_SECTION_INFO
23223 #define TARGET_ENCODE_SECTION_INFO mips_encode_section_info
23225 #undef TARGET_ATTRIBUTE_TABLE
23226 #define TARGET_ATTRIBUTE_TABLE mips_attribute_table
23227 /* All our function attributes are related to how out-of-line copies should
23228 be compiled or called. They don't in themselves prevent inlining. */
23229 #undef TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P
23230 #define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P hook_bool_const_tree_true
23232 #undef TARGET_EXTRA_LIVE_ON_ENTRY
23233 #define TARGET_EXTRA_LIVE_ON_ENTRY mips_extra_live_on_entry
23235 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
23236 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P mips_use_blocks_for_constant_p
23237 #undef TARGET_USE_ANCHORS_FOR_SYMBOL_P
23238 #define TARGET_USE_ANCHORS_FOR_SYMBOL_P mips_use_anchors_for_symbol_p
23240 #undef TARGET_COMP_TYPE_ATTRIBUTES
23241 #define TARGET_COMP_TYPE_ATTRIBUTES mips_comp_type_attributes
23243 #ifdef HAVE_AS_DTPRELWORD
23244 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
23245 #define TARGET_ASM_OUTPUT_DWARF_DTPREL mips_output_dwarf_dtprel
23247 #undef TARGET_DWARF_REGISTER_SPAN
23248 #define TARGET_DWARF_REGISTER_SPAN mips_dwarf_register_span
23249 #undef TARGET_DWARF_FRAME_REG_MODE
23250 #define TARGET_DWARF_FRAME_REG_MODE mips_dwarf_frame_reg_mode
23252 #undef TARGET_ASM_FINAL_POSTSCAN_INSN
23253 #define TARGET_ASM_FINAL_POSTSCAN_INSN mips_final_postscan_insn
23255 #undef TARGET_LEGITIMATE_ADDRESS_P
23256 #define TARGET_LEGITIMATE_ADDRESS_P mips_legitimate_address_p
23258 #undef TARGET_FRAME_POINTER_REQUIRED
23259 #define TARGET_FRAME_POINTER_REQUIRED mips_frame_pointer_required
23261 #undef TARGET_CAN_ELIMINATE
23262 #define TARGET_CAN_ELIMINATE mips_can_eliminate
23264 #undef TARGET_CONDITIONAL_REGISTER_USAGE
23265 #define TARGET_CONDITIONAL_REGISTER_USAGE mips_conditional_register_usage
23267 #undef TARGET_TRAMPOLINE_INIT
23268 #define TARGET_TRAMPOLINE_INIT mips_trampoline_init
23270 #undef TARGET_ASM_OUTPUT_SOURCE_FILENAME
23271 #define TARGET_ASM_OUTPUT_SOURCE_FILENAME mips_output_filename
23273 #undef TARGET_SHIFT_TRUNCATION_MASK
23274 #define TARGET_SHIFT_TRUNCATION_MASK mips_shift_truncation_mask
23276 #undef TARGET_PREPARE_PCH_SAVE
23277 #define TARGET_PREPARE_PCH_SAVE mips_prepare_pch_save
23279 #undef TARGET_VECTORIZE_VEC_PERM_CONST
23280 #define TARGET_VECTORIZE_VEC_PERM_CONST mips_vectorize_vec_perm_const
23282 #undef TARGET_SCHED_REASSOCIATION_WIDTH
23283 #define TARGET_SCHED_REASSOCIATION_WIDTH mips_sched_reassociation_width
23285 #undef TARGET_CASE_VALUES_THRESHOLD
23286 #define TARGET_CASE_VALUES_THRESHOLD mips_case_values_threshold
23288 #undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
23289 #define TARGET_ATOMIC_ASSIGN_EXPAND_FENV mips_atomic_assign_expand_fenv
23291 #undef TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS
23292 #define TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS true
23294 #undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
23295 #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
23296 mips_use_by_pieces_infrastructure_p
23298 #undef TARGET_SPILL_CLASS
23299 #define TARGET_SPILL_CLASS mips_spill_class
23300 #undef TARGET_LRA_P
23301 #define TARGET_LRA_P mips_lra_p
23302 #undef TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS
23303 #define TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS mips_ira_change_pseudo_allocno_class
23305 #undef TARGET_HARD_REGNO_SCRATCH_OK
23306 #define TARGET_HARD_REGNO_SCRATCH_OK mips_hard_regno_scratch_ok
23308 #undef TARGET_HARD_REGNO_NREGS
23309 #define TARGET_HARD_REGNO_NREGS mips_hard_regno_nregs
23310 #undef TARGET_HARD_REGNO_MODE_OK
23311 #define TARGET_HARD_REGNO_MODE_OK mips_hard_regno_mode_ok
23313 #undef TARGET_MODES_TIEABLE_P
23314 #define TARGET_MODES_TIEABLE_P mips_modes_tieable_p
23316 #undef TARGET_HARD_REGNO_CALL_PART_CLOBBERED
23317 #define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \
23318 mips_hard_regno_call_part_clobbered
23320 /* The architecture reserves bit 0 for MIPS16 so use bit 1 for descriptors. */
23321 #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
23322 #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 2
23324 #undef TARGET_SECONDARY_MEMORY_NEEDED
23325 #define TARGET_SECONDARY_MEMORY_NEEDED mips_secondary_memory_needed
23327 #undef TARGET_CAN_CHANGE_MODE_CLASS
23328 #define TARGET_CAN_CHANGE_MODE_CLASS mips_can_change_mode_class
23330 #undef TARGET_TRULY_NOOP_TRUNCATION
23331 #define TARGET_TRULY_NOOP_TRUNCATION mips_truly_noop_truncation
23333 #undef TARGET_CONSTANT_ALIGNMENT
23334 #define TARGET_CONSTANT_ALIGNMENT mips_constant_alignment
23336 #undef TARGET_ASAN_SHADOW_OFFSET
23337 #define TARGET_ASAN_SHADOW_OFFSET mips_asan_shadow_offset
23339 #undef TARGET_STARTING_FRAME_OFFSET
23340 #define TARGET_STARTING_FRAME_OFFSET mips_starting_frame_offset
23342 #undef TARGET_ASM_FILE_END
23343 #define TARGET_ASM_FILE_END mips_asm_file_end
23346 struct gcc_target targetm
= TARGET_INITIALIZER
;
23348 #include "gt-mips.h"