1 /* Subroutines used for code generation for RISC-V.
2 Copyright (C) 2011-2023 Free Software Foundation, Inc.
3 Contributed by Andrew Waterman (andrew@sifive.com).
4 Based on MIPS target for GNU compiler.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 #define IN_TARGET_CODE 1
24 #define INCLUDE_STRING
27 #include "coretypes.h"
33 #include "insn-config.h"
34 #include "insn-attr.h"
39 #include "stringpool.h"
42 #include "stor-layout.h"
50 #include "basic-block.h"
55 #include "function-abi.h"
56 #include "diagnostic.h"
59 #include "tree-pass.h"
61 #include "tm-constrs.h"
67 #include "sel-sched.h"
68 #include "fold-const.h"
69 #include "gimple-iterator.h"
70 #include "gimple-expr.h"
71 #include "tree-vectorizer.h"
73 /* This file should be included last. */
74 #include "target-def.h"
76 /* True if X is an UNSPEC wrapper around a SYMBOL_REF or LABEL_REF. */
77 #define UNSPEC_ADDRESS_P(X) \
78 (GET_CODE (X) == UNSPEC \
79 && XINT (X, 1) >= UNSPEC_ADDRESS_FIRST \
80 && XINT (X, 1) < UNSPEC_ADDRESS_FIRST + NUM_SYMBOL_TYPES)
82 /* Extract the symbol or label from UNSPEC wrapper X. */
83 #define UNSPEC_ADDRESS(X) \
86 /* Extract the symbol type from UNSPEC wrapper X. */
87 #define UNSPEC_ADDRESS_TYPE(X) \
88 ((enum riscv_symbol_type) (XINT (X, 1) - UNSPEC_ADDRESS_FIRST))
90 /* True if bit BIT is set in VALUE. */
91 #define BITSET_P(VALUE, BIT) (((VALUE) & (1ULL << (BIT))) != 0)
93 /* Classifies an address.
96 A natural register + offset address. The register satisfies
97 riscv_valid_base_register_p and the offset is a const_arith_operand.
100 A LO_SUM rtx. The first operand is a valid base register and
101 the second operand is a symbolic address.
104 A signed 16-bit constant address.
107 A constant symbolic address. */
108 enum riscv_address_type
{
115 /* Information about a function's frame layout. */
116 struct GTY(()) riscv_frame_info
{
117 /* The size of the frame in bytes. */
118 poly_int64 total_size
;
120 /* Bit X is set if the function saves or restores GPR X. */
123 /* Likewise FPR X. */
126 /* How much the GPR save/restore routines adjust sp (or 0 if unused). */
127 unsigned save_libcall_adjustment
;
129 /* Offsets of fixed-point and floating-point save areas from frame bottom */
130 poly_int64 gp_sp_offset
;
131 poly_int64 fp_sp_offset
;
133 /* Offset of virtual frame pointer from stack pointer/frame bottom */
134 poly_int64 frame_pointer_offset
;
136 /* Offset of hard frame pointer from stack pointer/frame bottom */
137 poly_int64 hard_frame_pointer_offset
;
139 /* The offset of arg_pointer_rtx from the bottom of the frame. */
140 poly_int64 arg_pointer_offset
;
142 /* Reset this struct, clean all field to zero. */
146 enum riscv_privilege_levels
{
147 UNKNOWN_MODE
, USER_MODE
, SUPERVISOR_MODE
, MACHINE_MODE
150 struct GTY(()) machine_function
{
151 /* The number of extra stack bytes taken up by register varargs.
152 This area is allocated by the callee at the very top of the frame. */
155 /* True if current function is a naked function. */
158 /* True if current function is an interrupt function. */
159 bool interrupt_handler_p
;
160 /* For an interrupt handler, indicates the privilege level. */
161 enum riscv_privilege_levels interrupt_mode
;
163 /* True if attributes on current function have been checked. */
164 bool attributes_checked_p
;
166 /* The current frame information, calculated by riscv_compute_frame_info. */
167 struct riscv_frame_info frame
;
169 /* The components already handled by separate shrink-wrapping, which should
170 not be considered by the prologue and epilogue. */
171 bool reg_is_wrapped_separately
[FIRST_PSEUDO_REGISTER
];
175 /* Information about a single argument. */
176 struct riscv_arg_info
{
177 /* True if the argument is at least partially passed on the stack. */
180 /* The number of integer registers allocated to this argument. */
181 unsigned int num_gprs
;
183 /* The offset of the first register used, provided num_gprs is nonzero.
184 If passed entirely on the stack, the value is MAX_ARGS_IN_REGISTERS. */
185 unsigned int gpr_offset
;
187 /* The number of floating-point registers allocated to this argument. */
188 unsigned int num_fprs
;
190 /* The offset of the first register used, provided num_fprs is nonzero. */
191 unsigned int fpr_offset
;
194 /* Information about an address described by riscv_address_type.
200 REG is the base register and OFFSET is the constant offset.
203 REG and OFFSET are the operands to the LO_SUM and SYMBOL_TYPE
204 is the type of symbol it references.
207 SYMBOL_TYPE is the type of symbol that the address references. */
208 struct riscv_address_info
{
209 enum riscv_address_type type
;
212 enum riscv_symbol_type symbol_type
;
215 /* One stage in a constant building sequence. These sequences have
219 A = A CODE[1] VALUE[1]
220 A = A CODE[2] VALUE[2]
223 where A is an accumulator, each CODE[i] is a binary rtl operation
224 and each VALUE[i] is a constant integer. CODE[0] is undefined. */
225 struct riscv_integer_op
{
227 unsigned HOST_WIDE_INT value
;
230 /* The largest number of operations needed to load an integer constant.
231 The worst case is LUI, ADDI, SLLI, ADDI, SLLI, ADDI, SLLI, ADDI. */
232 #define RISCV_MAX_INTEGER_OPS 8
234 /* Costs of various operations on the different architectures. */
236 struct riscv_tune_param
238 unsigned short fp_add
[2];
239 unsigned short fp_mul
[2];
240 unsigned short fp_div
[2];
241 unsigned short int_mul
[2];
242 unsigned short int_div
[2];
243 unsigned short issue_rate
;
244 unsigned short branch_cost
;
245 unsigned short memory_cost
;
246 unsigned short fmv_cost
;
247 bool slow_unaligned_access
;
248 bool use_divmod_expansion
;
251 /* Information about one micro-arch we know about. */
252 struct riscv_tune_info
{
253 /* This micro-arch canonical name. */
256 /* Which automaton to use for tuning. */
257 enum riscv_microarchitecture_type microarchitecture
;
259 /* Tuning parameters for this micro-arch. */
260 const struct riscv_tune_param
*tune_param
;
263 /* Global variables for machine-dependent things. */
265 /* Whether unaligned accesses execute very slowly. */
266 bool riscv_slow_unaligned_access_p
;
268 /* Stack alignment to assume/maintain. */
269 unsigned riscv_stack_boundary
;
271 /* If non-zero, this is an offset to be added to SP to redefine the CFA
272 when restoring the FP register from the stack. Only valid when generating
274 static int epilogue_cfa_sp_offset
;
276 /* Which tuning parameters to use. */
277 static const struct riscv_tune_param
*tune_param
;
279 /* Which automaton to use for tuning. */
280 enum riscv_microarchitecture_type riscv_microarchitecture
;
282 /* The number of chunks in a single vector register. */
283 poly_uint16 riscv_vector_chunks
;
285 /* The number of bytes in a vector chunk. */
286 unsigned riscv_bytes_per_vector_chunk
;
288 /* Index R is the smallest register class that contains register R. */
289 const enum reg_class riscv_regno_to_class
[FIRST_PSEUDO_REGISTER
] = {
290 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
291 GR_REGS
, GR_REGS
, SIBCALL_REGS
, SIBCALL_REGS
,
292 JALR_REGS
, JALR_REGS
, SIBCALL_REGS
, SIBCALL_REGS
,
293 SIBCALL_REGS
, SIBCALL_REGS
, SIBCALL_REGS
, SIBCALL_REGS
,
294 SIBCALL_REGS
, SIBCALL_REGS
, JALR_REGS
, JALR_REGS
,
295 JALR_REGS
, JALR_REGS
, JALR_REGS
, JALR_REGS
,
296 JALR_REGS
, JALR_REGS
, JALR_REGS
, JALR_REGS
,
297 SIBCALL_REGS
, SIBCALL_REGS
, SIBCALL_REGS
, SIBCALL_REGS
,
298 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
299 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
300 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
301 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
302 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
303 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
304 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
305 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
306 FRAME_REGS
, FRAME_REGS
, NO_REGS
, NO_REGS
,
307 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
308 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
309 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
310 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
311 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
312 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
313 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
314 VM_REGS
, VD_REGS
, VD_REGS
, VD_REGS
,
315 VD_REGS
, VD_REGS
, VD_REGS
, VD_REGS
,
316 VD_REGS
, VD_REGS
, VD_REGS
, VD_REGS
,
317 VD_REGS
, VD_REGS
, VD_REGS
, VD_REGS
,
318 VD_REGS
, VD_REGS
, VD_REGS
, VD_REGS
,
319 VD_REGS
, VD_REGS
, VD_REGS
, VD_REGS
,
320 VD_REGS
, VD_REGS
, VD_REGS
, VD_REGS
,
321 VD_REGS
, VD_REGS
, VD_REGS
, VD_REGS
,
324 /* Costs to use when optimizing for rocket. */
325 static const struct riscv_tune_param rocket_tune_info
= {
326 {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_add */
327 {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_mul */
328 {COSTS_N_INSNS (20), COSTS_N_INSNS (20)}, /* fp_div */
329 {COSTS_N_INSNS (4), COSTS_N_INSNS (4)}, /* int_mul */
330 {COSTS_N_INSNS (6), COSTS_N_INSNS (6)}, /* int_div */
335 true, /* slow_unaligned_access */
336 false, /* use_divmod_expansion */
339 /* Costs to use when optimizing for Sifive 7 Series. */
340 static const struct riscv_tune_param sifive_7_tune_info
= {
341 {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_add */
342 {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_mul */
343 {COSTS_N_INSNS (20), COSTS_N_INSNS (20)}, /* fp_div */
344 {COSTS_N_INSNS (4), COSTS_N_INSNS (4)}, /* int_mul */
345 {COSTS_N_INSNS (6), COSTS_N_INSNS (6)}, /* int_div */
350 true, /* slow_unaligned_access */
351 false, /* use_divmod_expansion */
354 /* Costs to use when optimizing for T-HEAD c906. */
355 static const struct riscv_tune_param thead_c906_tune_info
= {
356 {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_add */
357 {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_mul */
358 {COSTS_N_INSNS (20), COSTS_N_INSNS (20)}, /* fp_div */
359 {COSTS_N_INSNS (4), COSTS_N_INSNS (4)}, /* int_mul */
360 {COSTS_N_INSNS (6), COSTS_N_INSNS (6)}, /* int_div */
365 false, /* slow_unaligned_access */
366 false /* use_divmod_expansion */
369 /* Costs to use when optimizing for size. */
370 static const struct riscv_tune_param optimize_size_tune_info
= {
371 {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* fp_add */
372 {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* fp_mul */
373 {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* fp_div */
374 {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* int_mul */
375 {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* int_div */
380 false, /* slow_unaligned_access */
381 false, /* use_divmod_expansion */
384 static tree
riscv_handle_fndecl_attribute (tree
*, tree
, tree
, int, bool *);
385 static tree
riscv_handle_type_attribute (tree
*, tree
, tree
, int, bool *);
387 /* Defining target-specific uses of __attribute__. */
388 static const struct attribute_spec riscv_attribute_table
[] =
390 /* Syntax: { name, min_len, max_len, decl_required, type_required,
391 function_type_required, affects_type_identity, handler,
394 /* The attribute telling no prologue/epilogue. */
395 { "naked", 0, 0, true, false, false, false,
396 riscv_handle_fndecl_attribute
, NULL
},
397 /* This attribute generates prologue/epilogue for interrupt handlers. */
398 { "interrupt", 0, 1, false, true, true, false,
399 riscv_handle_type_attribute
, NULL
},
401 /* The following two are used for the built-in properties of the Vector type
402 and are not used externally */
403 {"RVV sizeless type", 4, 4, false, true, false, true, NULL
, NULL
},
404 {"RVV type", 0, 0, false, true, false, true, NULL
, NULL
},
406 /* The last attribute spec is set to be NULL. */
407 { NULL
, 0, 0, false, false, false, false, NULL
, NULL
}
410 /* Order for the CLOBBERs/USEs of gpr_save. */
411 static const unsigned gpr_save_reg_order
[] = {
412 INVALID_REGNUM
, T0_REGNUM
, T1_REGNUM
, RETURN_ADDR_REGNUM
,
413 S0_REGNUM
, S1_REGNUM
, S2_REGNUM
, S3_REGNUM
, S4_REGNUM
,
414 S5_REGNUM
, S6_REGNUM
, S7_REGNUM
, S8_REGNUM
, S9_REGNUM
,
415 S10_REGNUM
, S11_REGNUM
418 /* A table describing all the processors GCC knows about. */
419 static const struct riscv_tune_info riscv_tune_info_table
[] = {
420 #define RISCV_TUNE(TUNE_NAME, PIPELINE_MODEL, TUNE_INFO) \
421 { TUNE_NAME, PIPELINE_MODEL, & TUNE_INFO},
422 #include "riscv-cores.def"
425 void riscv_frame_info::reset(void)
430 save_libcall_adjustment
= 0;
435 frame_pointer_offset
= 0;
437 hard_frame_pointer_offset
= 0;
439 arg_pointer_offset
= 0;
442 /* Implement TARGET_MIN_ARITHMETIC_PRECISION. */
445 riscv_min_arithmetic_precision (void)
450 /* Return the riscv_tune_info entry for the given name string. */
452 static const struct riscv_tune_info
*
453 riscv_parse_tune (const char *tune_string
)
455 const riscv_cpu_info
*cpu
= riscv_find_cpu (tune_string
);
458 tune_string
= cpu
->tune
;
460 for (unsigned i
= 0; i
< ARRAY_SIZE (riscv_tune_info_table
); i
++)
461 if (strcmp (riscv_tune_info_table
[i
].name
, tune_string
) == 0)
462 return riscv_tune_info_table
+ i
;
464 error ("unknown cpu %qs for %<-mtune%>", tune_string
);
465 return riscv_tune_info_table
;
468 /* Helper function for riscv_build_integer; arguments are as for
469 riscv_build_integer. */
472 riscv_build_integer_1 (struct riscv_integer_op codes
[RISCV_MAX_INTEGER_OPS
],
473 HOST_WIDE_INT value
, machine_mode mode
)
475 HOST_WIDE_INT low_part
= CONST_LOW_PART (value
);
476 int cost
= RISCV_MAX_INTEGER_OPS
+ 1, alt_cost
;
477 struct riscv_integer_op alt_codes
[RISCV_MAX_INTEGER_OPS
];
479 if (SMALL_OPERAND (value
) || LUI_OPERAND (value
))
481 /* Simply ADDI or LUI. */
482 codes
[0].code
= UNKNOWN
;
483 codes
[0].value
= value
;
486 if (TARGET_ZBS
&& SINGLE_BIT_MASK_OPERAND (value
))
489 codes
[0].code
= UNKNOWN
;
490 codes
[0].value
= value
;
492 /* RISC-V sign-extends all 32bit values that live in a 32bit
493 register. To avoid paradoxes, we thus need to use the
494 sign-extended (negative) representation (-1 << 31) for the
495 value, if we want to build (1 << 31) in SImode. This will
496 then expand to an LUI instruction. */
497 if (TARGET_64BIT
&& mode
== SImode
&& value
== (HOST_WIDE_INT_1U
<< 31))
498 codes
[0].value
= (HOST_WIDE_INT_M1U
<< 31);
503 /* End with ADDI. When constructing HImode constants, do not generate any
504 intermediate value that is not itself a valid HImode constant. The
505 XORI case below will handle those remaining HImode constants. */
508 || value
- low_part
<= ((1 << (GET_MODE_BITSIZE (HImode
) - 1)) - 1)))
510 HOST_WIDE_INT upper_part
= value
- low_part
;
511 if (mode
!= VOIDmode
)
512 upper_part
= trunc_int_for_mode (value
- low_part
, mode
);
514 alt_cost
= 1 + riscv_build_integer_1 (alt_codes
, upper_part
, mode
);
517 alt_codes
[alt_cost
-1].code
= PLUS
;
518 alt_codes
[alt_cost
-1].value
= low_part
;
519 memcpy (codes
, alt_codes
, sizeof (alt_codes
));
525 if (cost
> 2 && (low_part
< 0 || mode
== HImode
))
527 alt_cost
= 1 + riscv_build_integer_1 (alt_codes
, value
^ low_part
, mode
);
530 alt_codes
[alt_cost
-1].code
= XOR
;
531 alt_codes
[alt_cost
-1].value
= low_part
;
532 memcpy (codes
, alt_codes
, sizeof (alt_codes
));
537 /* Eliminate trailing zeros and end with SLLI. */
538 if (cost
> 2 && (value
& 1) == 0)
540 int shift
= ctz_hwi (value
);
541 unsigned HOST_WIDE_INT x
= value
;
542 x
= sext_hwi (x
>> shift
, HOST_BITS_PER_WIDE_INT
- shift
);
544 /* Don't eliminate the lower 12 bits if LUI might apply. */
545 if (shift
> IMM_BITS
&& !SMALL_OPERAND (x
) && LUI_OPERAND (x
<< IMM_BITS
))
546 shift
-= IMM_BITS
, x
<<= IMM_BITS
;
548 alt_cost
= 1 + riscv_build_integer_1 (alt_codes
, x
, mode
);
551 alt_codes
[alt_cost
-1].code
= ASHIFT
;
552 alt_codes
[alt_cost
-1].value
= shift
;
553 memcpy (codes
, alt_codes
, sizeof (alt_codes
));
558 if (cost
> 2 && TARGET_64BIT
&& TARGET_ZBB
)
560 int leading_ones
= clz_hwi (~value
);
561 int trailing_ones
= ctz_hwi (~value
);
563 /* If all bits are one except a few that are zero, and the zero bits
564 are within a range of 11 bits, and at least one of the upper 32-bits
565 is a zero, then we can generate a constant by loading a small
566 negative constant and rotating. */
567 if (leading_ones
< 32
568 && ((64 - leading_ones
- trailing_ones
) < 12))
570 codes
[0].code
= UNKNOWN
;
571 /* The sign-bit might be zero, so just rotate to be safe. */
572 codes
[0].value
= (((unsigned HOST_WIDE_INT
) value
>> trailing_ones
)
573 | (value
<< (64 - trailing_ones
)));
574 codes
[1].code
= ROTATERT
;
575 codes
[1].value
= 64 - trailing_ones
;
578 /* Handle the case where the 11 bit range of zero bits wraps around. */
581 int upper_trailing_ones
= ctz_hwi (~value
>> 32);
582 int lower_leading_ones
= clz_hwi (~value
<< 32);
584 if (upper_trailing_ones
< 32 && lower_leading_ones
< 32
585 && ((64 - upper_trailing_ones
- lower_leading_ones
) < 12))
587 codes
[0].code
= UNKNOWN
;
588 /* The sign-bit might be zero, so just rotate to be safe. */
589 codes
[0].value
= ((value
<< (32 - upper_trailing_ones
))
590 | ((unsigned HOST_WIDE_INT
) value
591 >> (32 + upper_trailing_ones
)));
592 codes
[1].code
= ROTATERT
;
593 codes
[1].value
= 32 - upper_trailing_ones
;
599 gcc_assert (cost
<= RISCV_MAX_INTEGER_OPS
);
603 /* Fill CODES with a sequence of rtl operations to load VALUE.
604 Return the number of operations needed. */
607 riscv_build_integer (struct riscv_integer_op
*codes
, HOST_WIDE_INT value
,
610 int cost
= riscv_build_integer_1 (codes
, value
, mode
);
612 /* Eliminate leading zeros and end with SRLI. */
613 if (value
> 0 && cost
> 2)
615 struct riscv_integer_op alt_codes
[RISCV_MAX_INTEGER_OPS
];
616 int alt_cost
, shift
= clz_hwi (value
);
617 HOST_WIDE_INT shifted_val
;
619 /* Try filling trailing bits with 1s. */
620 shifted_val
= (value
<< shift
) | ((((HOST_WIDE_INT
) 1) << shift
) - 1);
621 alt_cost
= 1 + riscv_build_integer_1 (alt_codes
, shifted_val
, mode
);
624 alt_codes
[alt_cost
-1].code
= LSHIFTRT
;
625 alt_codes
[alt_cost
-1].value
= shift
;
626 memcpy (codes
, alt_codes
, sizeof (alt_codes
));
630 /* Try filling trailing bits with 0s. */
631 shifted_val
= value
<< shift
;
632 alt_cost
= 1 + riscv_build_integer_1 (alt_codes
, shifted_val
, mode
);
635 alt_codes
[alt_cost
-1].code
= LSHIFTRT
;
636 alt_codes
[alt_cost
-1].value
= shift
;
637 memcpy (codes
, alt_codes
, sizeof (alt_codes
));
643 && (value
> INT32_MAX
|| value
< INT32_MIN
))
645 unsigned HOST_WIDE_INT loval
= sext_hwi (value
, 32);
646 unsigned HOST_WIDE_INT hival
= sext_hwi ((value
- loval
) >> 32, 32);
647 struct riscv_integer_op alt_codes
[RISCV_MAX_INTEGER_OPS
];
648 struct riscv_integer_op hicode
[RISCV_MAX_INTEGER_OPS
];
649 int hi_cost
, lo_cost
;
651 hi_cost
= riscv_build_integer_1 (hicode
, hival
, mode
);
654 lo_cost
= riscv_build_integer_1 (alt_codes
, loval
, mode
);
655 if (lo_cost
+ hi_cost
< cost
)
657 memcpy (codes
, alt_codes
,
658 lo_cost
* sizeof (struct riscv_integer_op
));
659 memcpy (codes
+ lo_cost
, hicode
,
660 hi_cost
* sizeof (struct riscv_integer_op
));
661 cost
= lo_cost
+ hi_cost
;
669 /* Return the cost of constructing VAL in the event that a scratch
670 register is available. */
673 riscv_split_integer_cost (HOST_WIDE_INT val
)
676 unsigned HOST_WIDE_INT loval
= sext_hwi (val
, 32);
677 unsigned HOST_WIDE_INT hival
= sext_hwi ((val
- loval
) >> 32, 32);
678 struct riscv_integer_op codes
[RISCV_MAX_INTEGER_OPS
];
680 cost
= 2 + riscv_build_integer (codes
, loval
, VOIDmode
);
682 cost
+= riscv_build_integer (codes
, hival
, VOIDmode
);
687 /* Return the cost of constructing the integer constant VAL. */
690 riscv_integer_cost (HOST_WIDE_INT val
)
692 struct riscv_integer_op codes
[RISCV_MAX_INTEGER_OPS
];
693 return MIN (riscv_build_integer (codes
, val
, VOIDmode
),
694 riscv_split_integer_cost (val
));
697 /* Try to split a 64b integer into 32b parts, then reassemble. */
700 riscv_split_integer (HOST_WIDE_INT val
, machine_mode mode
)
702 unsigned HOST_WIDE_INT loval
= sext_hwi (val
, 32);
703 unsigned HOST_WIDE_INT hival
= sext_hwi ((val
- loval
) >> 32, 32);
704 rtx hi
= gen_reg_rtx (mode
), lo
= gen_reg_rtx (mode
);
706 riscv_move_integer (lo
, lo
, loval
, mode
);
709 hi
= gen_rtx_ASHIFT (mode
, lo
, GEN_INT (32));
712 riscv_move_integer (hi
, hi
, hival
, mode
);
713 hi
= gen_rtx_ASHIFT (mode
, hi
, GEN_INT (32));
716 hi
= force_reg (mode
, hi
);
717 return gen_rtx_PLUS (mode
, hi
, lo
);
720 /* Return true if X is a thread-local symbol. */
723 riscv_tls_symbol_p (const_rtx x
)
725 return SYMBOL_REF_P (x
) && SYMBOL_REF_TLS_MODEL (x
) != 0;
728 /* Return true if symbol X binds locally. */
731 riscv_symbol_binds_local_p (const_rtx x
)
733 if (SYMBOL_REF_P (x
))
734 return (SYMBOL_REF_DECL (x
)
735 ? targetm
.binds_local_p (SYMBOL_REF_DECL (x
))
736 : SYMBOL_REF_LOCAL_P (x
));
741 /* Return the method that should be used to access SYMBOL_REF or
744 static enum riscv_symbol_type
745 riscv_classify_symbol (const_rtx x
)
747 if (riscv_tls_symbol_p (x
))
750 if (GET_CODE (x
) == SYMBOL_REF
&& flag_pic
&& !riscv_symbol_binds_local_p (x
))
751 return SYMBOL_GOT_DISP
;
753 return riscv_cmodel
== CM_MEDLOW
? SYMBOL_ABSOLUTE
: SYMBOL_PCREL
;
756 /* Classify the base of symbolic expression X. */
758 enum riscv_symbol_type
759 riscv_classify_symbolic_expression (rtx x
)
763 split_const (x
, &x
, &offset
);
764 if (UNSPEC_ADDRESS_P (x
))
765 return UNSPEC_ADDRESS_TYPE (x
);
767 return riscv_classify_symbol (x
);
770 /* Return true if X is a symbolic constant. If it is, store the type of
771 the symbol in *SYMBOL_TYPE. */
774 riscv_symbolic_constant_p (rtx x
, enum riscv_symbol_type
*symbol_type
)
778 split_const (x
, &x
, &offset
);
779 if (UNSPEC_ADDRESS_P (x
))
781 *symbol_type
= UNSPEC_ADDRESS_TYPE (x
);
782 x
= UNSPEC_ADDRESS (x
);
784 else if (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == LABEL_REF
)
785 *symbol_type
= riscv_classify_symbol (x
);
789 if (offset
== const0_rtx
)
792 /* Nonzero offsets are only valid for references that don't use the GOT. */
793 switch (*symbol_type
)
795 case SYMBOL_ABSOLUTE
:
798 /* GAS rejects offsets outside the range [-2^31, 2^31-1]. */
799 return sext_hwi (INTVAL (offset
), 32) == INTVAL (offset
);
806 /* Returns the number of instructions necessary to reference a symbol. */
808 static int riscv_symbol_insns (enum riscv_symbol_type type
)
812 case SYMBOL_TLS
: return 0; /* Depends on the TLS model. */
813 case SYMBOL_ABSOLUTE
: return 2; /* LUI + the reference. */
814 case SYMBOL_PCREL
: return 2; /* AUIPC + the reference. */
815 case SYMBOL_TLS_LE
: return 3; /* LUI + ADD TP + the reference. */
816 case SYMBOL_GOT_DISP
: return 3; /* AUIPC + LD GOT + the reference. */
817 default: gcc_unreachable ();
821 /* Implement TARGET_LEGITIMATE_CONSTANT_P. */
824 riscv_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED
, rtx x
)
826 return riscv_const_insns (x
) > 0;
829 /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
832 riscv_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED
, rtx x
)
834 enum riscv_symbol_type type
;
837 /* There's no way to calculate VL-based values using relocations. */
838 subrtx_iterator::array_type array
;
839 FOR_EACH_SUBRTX (iter
, array
, x
, ALL
)
840 if (GET_CODE (*iter
) == CONST_POLY_INT
)
843 /* There is no assembler syntax for expressing an address-sized
845 if (GET_CODE (x
) == HIGH
)
848 split_const (x
, &base
, &offset
);
849 if (riscv_symbolic_constant_p (base
, &type
))
851 /* As an optimization, don't spill symbolic constants that are as
852 cheap to rematerialize as to access in the constant pool. */
853 if (SMALL_OPERAND (INTVAL (offset
)) && riscv_symbol_insns (type
) > 0)
856 /* As an optimization, avoid needlessly generate dynamic relocations. */
861 /* TLS symbols must be computed by riscv_legitimize_move. */
862 if (tls_referenced_p (x
))
868 /* Return true if register REGNO is a valid base register for mode MODE.
869 STRICT_P is true if REG_OK_STRICT is in effect. */
872 riscv_regno_mode_ok_for_base_p (int regno
,
873 machine_mode mode ATTRIBUTE_UNUSED
,
876 if (!HARD_REGISTER_NUM_P (regno
))
880 regno
= reg_renumber
[regno
];
883 /* These fake registers will be eliminated to either the stack or
884 hard frame pointer, both of which are usually valid base registers.
885 Reload deals with the cases where the eliminated form isn't valid. */
886 if (regno
== ARG_POINTER_REGNUM
|| regno
== FRAME_POINTER_REGNUM
)
889 return GP_REG_P (regno
);
892 /* Return true if X is a valid base register for mode MODE.
893 STRICT_P is true if REG_OK_STRICT is in effect. */
896 riscv_valid_base_register_p (rtx x
, machine_mode mode
, bool strict_p
)
898 if (!strict_p
&& GET_CODE (x
) == SUBREG
)
902 && riscv_regno_mode_ok_for_base_p (REGNO (x
), mode
, strict_p
));
905 /* Return true if, for every base register BASE_REG, (plus BASE_REG X)
906 can address a value of mode MODE. */
909 riscv_valid_offset_p (rtx x
, machine_mode mode
)
911 /* Check that X is a signed 12-bit number. */
912 if (!const_arith_operand (x
, Pmode
))
915 /* We may need to split multiword moves, so make sure that every word
917 if (GET_MODE_SIZE (mode
).to_constant () > UNITS_PER_WORD
918 && !SMALL_OPERAND (INTVAL (x
) + GET_MODE_SIZE (mode
).to_constant () - UNITS_PER_WORD
))
924 /* Should a symbol of type SYMBOL_TYPE should be split in two? */
927 riscv_split_symbol_type (enum riscv_symbol_type symbol_type
)
929 if (symbol_type
== SYMBOL_TLS_LE
)
932 if (!TARGET_EXPLICIT_RELOCS
)
935 return symbol_type
== SYMBOL_ABSOLUTE
|| symbol_type
== SYMBOL_PCREL
;
938 /* Return true if a LO_SUM can address a value of mode MODE when the
939 LO_SUM symbol has type SYM_TYPE. X is the LO_SUM second operand, which
940 is used when the mode is BLKmode. */
943 riscv_valid_lo_sum_p (enum riscv_symbol_type sym_type
, machine_mode mode
,
948 /* Check that symbols of type SYMBOL_TYPE can be used to access values
950 if (riscv_symbol_insns (sym_type
) == 0)
953 /* Check that there is a known low-part relocation. */
954 if (!riscv_split_symbol_type (sym_type
))
957 /* We can't tell size or alignment when we have BLKmode, so try extracing a
958 decl from the symbol if possible. */
963 /* Extract the symbol from the LO_SUM operand, if any. */
964 split_const (x
, &x
, &offset
);
966 /* Might be a CODE_LABEL. We can compute align but not size for that,
967 so don't bother trying to handle it. */
968 if (!SYMBOL_REF_P (x
))
971 /* Use worst case assumptions if we don't have a SYMBOL_REF_DECL. */
972 align
= (SYMBOL_REF_DECL (x
)
973 ? DECL_ALIGN (SYMBOL_REF_DECL (x
))
975 size
= (SYMBOL_REF_DECL (x
) && DECL_SIZE (SYMBOL_REF_DECL (x
))
976 ? tree_to_uhwi (DECL_SIZE (SYMBOL_REF_DECL (x
)))
981 align
= GET_MODE_ALIGNMENT (mode
);
982 size
= GET_MODE_BITSIZE (mode
).to_constant ();
985 /* We may need to split multiword moves, so make sure that each word
986 can be accessed without inducing a carry. */
987 if (size
> BITS_PER_WORD
988 && (!TARGET_STRICT_ALIGN
|| size
> align
))
994 /* Return true if mode is the RVV enabled mode.
995 For example: 'VNx1DI' mode is disabled if MIN_VLEN == 32.
996 'VNx1SI' mode is enabled if MIN_VLEN == 32. */
999 riscv_v_ext_vector_mode_p (machine_mode mode
)
1001 #define ENTRY(MODE, REQUIREMENT, ...) \
1006 #include "riscv-vector-switch.def"
1014 /* Return true if mode is the RVV enabled tuple mode. */
1017 riscv_v_ext_tuple_mode_p (machine_mode mode
)
1019 #define TUPLE_ENTRY(MODE, REQUIREMENT, ...) \
1024 #include "riscv-vector-switch.def"
1032 /* Return true if it is either RVV vector mode or RVV tuple mode. */
1035 riscv_v_ext_mode_p (machine_mode mode
)
1037 return riscv_v_ext_vector_mode_p (mode
) || riscv_v_ext_tuple_mode_p (mode
);
1040 /* Call from ADJUST_NUNITS in riscv-modes.def. Return the correct
1041 NUNITS size for corresponding machine_mode. */
1044 riscv_v_adjust_nunits (machine_mode mode
, int scale
)
1046 if (riscv_v_ext_mode_p (mode
))
1047 return riscv_vector_chunks
* scale
;
1051 /* Call from ADJUST_BYTESIZE in riscv-modes.def. Return the correct
1052 BYTE size for corresponding machine_mode. */
1055 riscv_v_adjust_bytesize (machine_mode mode
, int scale
)
1057 if (riscv_v_ext_vector_mode_p (mode
))
1059 poly_uint16 mode_size
= GET_MODE_SIZE (mode
);
1061 if (maybe_eq (mode_size
, (uint16_t)-1))
1062 mode_size
= riscv_vector_chunks
* scale
;
1064 if (known_gt (mode_size
, BYTES_PER_RISCV_VECTOR
))
1065 mode_size
= BYTES_PER_RISCV_VECTOR
;
1073 /* Call from ADJUST_PRECISION in riscv-modes.def. Return the correct
1074 PRECISION size for corresponding machine_mode. */
1077 riscv_v_adjust_precision (machine_mode mode
, int scale
)
1079 if (riscv_v_ext_vector_mode_p (mode
))
1080 return riscv_vector_chunks
* scale
;
1085 /* Return true if X is a valid address for machine mode MODE. If it is,
1086 fill in INFO appropriately. STRICT_P is true if REG_OK_STRICT is in
1090 riscv_classify_address (struct riscv_address_info
*info
, rtx x
,
1091 machine_mode mode
, bool strict_p
)
1093 switch (GET_CODE (x
))
1097 info
->type
= ADDRESS_REG
;
1099 info
->offset
= const0_rtx
;
1100 return riscv_valid_base_register_p (info
->reg
, mode
, strict_p
);
1103 /* RVV load/store disallow any offset. */
1104 if (riscv_v_ext_mode_p (mode
))
1107 info
->type
= ADDRESS_REG
;
1108 info
->reg
= XEXP (x
, 0);
1109 info
->offset
= XEXP (x
, 1);
1110 return (riscv_valid_base_register_p (info
->reg
, mode
, strict_p
)
1111 && riscv_valid_offset_p (info
->offset
, mode
));
1114 /* RVV load/store disallow LO_SUM. */
1115 if (riscv_v_ext_mode_p (mode
))
1118 info
->type
= ADDRESS_LO_SUM
;
1119 info
->reg
= XEXP (x
, 0);
1120 info
->offset
= XEXP (x
, 1);
1121 /* We have to trust the creator of the LO_SUM to do something vaguely
1122 sane. Target-independent code that creates a LO_SUM should also
1123 create and verify the matching HIGH. Target-independent code that
1124 adds an offset to a LO_SUM must prove that the offset will not
1125 induce a carry. Failure to do either of these things would be
1126 a bug, and we are not required to check for it here. The RISC-V
1127 backend itself should only create LO_SUMs for valid symbolic
1128 constants, with the high part being either a HIGH or a copy
1131 = riscv_classify_symbolic_expression (info
->offset
);
1132 return (riscv_valid_base_register_p (info
->reg
, mode
, strict_p
)
1133 && riscv_valid_lo_sum_p (info
->symbol_type
, mode
, info
->offset
));
1136 /* We only allow the const0_rtx for the RVV load/store. For example:
1137 +----------------------------------------------------------+
1139 | vsetvli zero,a1,e32,m1,ta,ma |
1140 | vle32.v v24,0(a5) <- propagate the const 0 to a5 here. |
1141 | vs1r.v v24,0(a0) |
1142 +----------------------------------------------------------+
1143 It can be folded to:
1144 +----------------------------------------------------------+
1145 | vsetvli zero,a1,e32,m1,ta,ma |
1146 | vle32.v v24,0(zero) |
1147 | vs1r.v v24,0(a0) |
1148 +----------------------------------------------------------+
1149 This behavior will benefit the underlying RVV auto vectorization. */
1150 if (riscv_v_ext_mode_p (mode
))
1151 return x
== const0_rtx
;
1153 /* Small-integer addresses don't occur very often, but they
1154 are legitimate if x0 is a valid base register. */
1155 info
->type
= ADDRESS_CONST_INT
;
1156 return SMALL_OPERAND (INTVAL (x
));
1163 /* Implement TARGET_LEGITIMATE_ADDRESS_P. */
1166 riscv_legitimate_address_p (machine_mode mode
, rtx x
, bool strict_p
)
1168 struct riscv_address_info addr
;
1170 return riscv_classify_address (&addr
, x
, mode
, strict_p
);
1173 /* Return true if hard reg REGNO can be used in compressed instructions. */
1176 riscv_compressed_reg_p (int regno
)
1178 /* x8-x15/f8-f15 are compressible registers. */
1179 return (TARGET_RVC
&& (IN_RANGE (regno
, GP_REG_FIRST
+ 8, GP_REG_FIRST
+ 15)
1180 || IN_RANGE (regno
, FP_REG_FIRST
+ 8, FP_REG_FIRST
+ 15)));
1183 /* Return true if x is an unsigned 5-bit immediate scaled by 4. */
1186 riscv_compressed_lw_offset_p (rtx x
)
1188 return (CONST_INT_P (x
)
1189 && (INTVAL (x
) & 3) == 0
1190 && IN_RANGE (INTVAL (x
), 0, CSW_MAX_OFFSET
));
1193 /* Return true if load/store from/to address x can be compressed. */
1196 riscv_compressed_lw_address_p (rtx x
)
1198 struct riscv_address_info addr
;
1199 bool result
= riscv_classify_address (&addr
, x
, GET_MODE (x
),
1202 /* Return false if address is not compressed_reg + small_offset. */
1204 || addr
.type
!= ADDRESS_REG
1205 /* Before reload, assume all registers are OK. */
1206 || (reload_completed
1207 && !riscv_compressed_reg_p (REGNO (addr
.reg
))
1208 && addr
.reg
!= stack_pointer_rtx
)
1209 || !riscv_compressed_lw_offset_p (addr
.offset
))
1215 /* Return the number of instructions needed to load or store a value
1216 of mode MODE at address X. Return 0 if X isn't valid for MODE.
1217 Assume that multiword moves may need to be split into word moves
1218 if MIGHT_SPLIT_P, otherwise assume that a single load or store is
1222 riscv_address_insns (rtx x
, machine_mode mode
, bool might_split_p
)
1224 struct riscv_address_info addr
= {};
1227 if (!riscv_classify_address (&addr
, x
, mode
, false))
1229 /* This could be a pattern from the pic.md file. In which case we want
1230 this address to always have a cost of 3 to make it as expensive as the
1231 most expensive symbol. This prevents constant propagation from
1232 preferring symbols over register plus offset. */
1236 /* BLKmode is used for single unaligned loads and stores and should
1237 not count as a multiword mode. */
1238 if (!riscv_v_ext_vector_mode_p (mode
) && mode
!= BLKmode
&& might_split_p
)
1239 n
+= (GET_MODE_SIZE (mode
).to_constant () + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
1241 if (addr
.type
== ADDRESS_LO_SUM
)
1242 n
+= riscv_symbol_insns (addr
.symbol_type
) - 1;
1247 /* Return the number of instructions needed to load constant X.
1248 Return 0 if X isn't a valid constant. */
1251 riscv_const_insns (rtx x
)
1253 enum riscv_symbol_type symbol_type
;
1256 switch (GET_CODE (x
))
1259 if (!riscv_symbolic_constant_p (XEXP (x
, 0), &symbol_type
)
1260 || !riscv_split_symbol_type (symbol_type
))
1263 /* This is simply an LUI. */
1268 int cost
= riscv_integer_cost (INTVAL (x
));
1269 /* Force complicated constants to memory. */
1270 return cost
< 4 ? cost
: 0;
1274 /* We can use x0 to load floating-point zero. */
1275 return x
== CONST0_RTX (GET_MODE (x
)) ? 1 : 0;
1278 /* TODO: This is not accurate, we will need to
1279 adapt the COST of CONST_VECTOR in the future
1280 for the following cases:
1282 - 1. const duplicate vector with element value
1283 in range of [-16, 15].
1284 - 2. const duplicate vector with element value
1285 out range of [-16, 15].
1286 - 3. const series vector.
1288 if (riscv_v_ext_vector_mode_p (GET_MODE (x
)))
1290 /* const series vector. */
1292 if (const_vec_series_p (x
, &base
, &step
))
1294 /* This is not accurate, we will need to adapt the COST
1295 * accurately according to BASE && STEP. */
1300 if (const_vec_duplicate_p (x
, &elt
))
1302 /* Constants from -16 to 15 can be loaded with vmv.v.i.
1303 The Wc0, Wc1 constraints are already covered by the
1304 vi constraint so we do not need to check them here
1306 if (satisfies_constraint_vi (x
))
1309 /* A const duplicate vector can always be broadcast from
1310 a general-purpose register. This means we need as many
1311 insns as it takes to load the constant into the GPR
1313 return 1 + riscv_const_insns (elt
);
1317 /* TODO: We may support more const vector in the future. */
1318 return x
== CONST0_RTX (GET_MODE (x
)) ? 1 : 0;
1322 /* See if we can refer to X directly. */
1323 if (riscv_symbolic_constant_p (x
, &symbol_type
))
1324 return riscv_symbol_insns (symbol_type
);
1326 /* Otherwise try splitting the constant into a base and offset. */
1327 split_const (x
, &x
, &offset
);
1330 int n
= riscv_const_insns (x
);
1332 return n
+ riscv_integer_cost (INTVAL (offset
));
1338 return riscv_symbol_insns (riscv_classify_symbol (x
));
1340 /* TODO: In RVV, we get CONST_POLY_INT by using csrr VLENB
1341 instruction and several scalar shift or mult instructions,
1342 it is so far unknown. We set it to 4 temporarily. */
1343 case CONST_POLY_INT
:
1351 /* X is a doubleword constant that can be handled by splitting it into
1352 two words and loading each word separately. Return the number of
1353 instructions required to do this. */
1356 riscv_split_const_insns (rtx x
)
1358 unsigned int low
, high
;
1360 low
= riscv_const_insns (riscv_subword (x
, false));
1361 high
= riscv_const_insns (riscv_subword (x
, true));
1362 gcc_assert (low
> 0 && high
> 0);
1366 /* Return the number of instructions needed to implement INSN,
1367 given that it loads from or stores to MEM. */
1370 riscv_load_store_insns (rtx mem
, rtx_insn
*insn
)
1376 gcc_assert (MEM_P (mem
));
1377 mode
= GET_MODE (mem
);
1379 /* Try to prove that INSN does not need to be split. */
1380 might_split_p
= true;
1381 if (GET_MODE_BITSIZE (mode
).to_constant () <= 32)
1382 might_split_p
= false;
1383 else if (GET_MODE_BITSIZE (mode
).to_constant () == 64)
1385 set
= single_set (insn
);
1386 if (set
&& !riscv_split_64bit_move_p (SET_DEST (set
), SET_SRC (set
)))
1387 might_split_p
= false;
1390 return riscv_address_insns (XEXP (mem
, 0), mode
, might_split_p
);
1393 /* Emit a move from SRC to DEST. Assume that the move expanders can
1394 handle all moves if !can_create_pseudo_p (). The distinction is
1395 important because, unlike emit_move_insn, the move expanders know
1396 how to force Pmode objects into the constant pool even when the
1397 constant pool address is not itself legitimate. */
1400 riscv_emit_move (rtx dest
, rtx src
)
1402 return (can_create_pseudo_p ()
1403 ? emit_move_insn (dest
, src
)
1404 : emit_move_insn_1 (dest
, src
));
1407 /* Emit an instruction of the form (set TARGET SRC). */
1410 riscv_emit_set (rtx target
, rtx src
)
1412 emit_insn (gen_rtx_SET (target
, src
));
1416 /* Emit an instruction of the form (set DEST (CODE X Y)). */
1419 riscv_emit_binary (enum rtx_code code
, rtx dest
, rtx x
, rtx y
)
1421 return riscv_emit_set (dest
, gen_rtx_fmt_ee (code
, GET_MODE (dest
), x
, y
));
1424 /* Compute (CODE X Y) and store the result in a new register
1425 of mode MODE. Return that new register. */
1428 riscv_force_binary (machine_mode mode
, enum rtx_code code
, rtx x
, rtx y
)
1430 return riscv_emit_binary (code
, gen_reg_rtx (mode
), x
, y
);
1434 riscv_swap_instruction (rtx inst
)
1436 gcc_assert (GET_MODE (inst
) == SImode
);
1437 if (BYTES_BIG_ENDIAN
)
1438 inst
= expand_unop (SImode
, bswap_optab
, inst
, gen_reg_rtx (SImode
), 1);
1442 /* Copy VALUE to a register and return that register. If new pseudos
1443 are allowed, copy it into a new register, otherwise use DEST. */
1446 riscv_force_temporary (rtx dest
, rtx value
)
1448 if (can_create_pseudo_p ())
1449 return force_reg (Pmode
, value
);
1452 riscv_emit_move (dest
, value
);
1457 /* Wrap symbol or label BASE in an UNSPEC address of type SYMBOL_TYPE,
1458 then add CONST_INT OFFSET to the result. */
1461 riscv_unspec_address_offset (rtx base
, rtx offset
,
1462 enum riscv_symbol_type symbol_type
)
1464 base
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, base
),
1465 UNSPEC_ADDRESS_FIRST
+ symbol_type
);
1466 if (offset
!= const0_rtx
)
1467 base
= gen_rtx_PLUS (Pmode
, base
, offset
);
1468 return gen_rtx_CONST (Pmode
, base
);
1471 /* Return an UNSPEC address with underlying address ADDRESS and symbol
1472 type SYMBOL_TYPE. */
1475 riscv_unspec_address (rtx address
, enum riscv_symbol_type symbol_type
)
1479 split_const (address
, &base
, &offset
);
1480 return riscv_unspec_address_offset (base
, offset
, symbol_type
);
1483 /* If OP is an UNSPEC address, return the address to which it refers,
1484 otherwise return OP itself. */
1487 riscv_strip_unspec_address (rtx op
)
1491 split_const (op
, &base
, &offset
);
1492 if (UNSPEC_ADDRESS_P (base
))
1493 op
= plus_constant (Pmode
, UNSPEC_ADDRESS (base
), INTVAL (offset
));
1497 /* If riscv_unspec_address (ADDR, SYMBOL_TYPE) is a 32-bit value, add the
1498 high part to BASE and return the result. Just return BASE otherwise.
1499 TEMP is as for riscv_force_temporary.
1501 The returned expression can be used as the first operand to a LO_SUM. */
1504 riscv_unspec_offset_high (rtx temp
, rtx addr
, enum riscv_symbol_type symbol_type
)
1506 addr
= gen_rtx_HIGH (Pmode
, riscv_unspec_address (addr
, symbol_type
));
1507 return riscv_force_temporary (temp
, addr
);
1510 /* Load an entry from the GOT for a TLS GD access. */
1512 static rtx
riscv_got_load_tls_gd (rtx dest
, rtx sym
)
1514 if (Pmode
== DImode
)
1515 return gen_got_load_tls_gddi (dest
, sym
);
1517 return gen_got_load_tls_gdsi (dest
, sym
);
1520 /* Load an entry from the GOT for a TLS IE access. */
1522 static rtx
riscv_got_load_tls_ie (rtx dest
, rtx sym
)
1524 if (Pmode
== DImode
)
1525 return gen_got_load_tls_iedi (dest
, sym
);
1527 return gen_got_load_tls_iesi (dest
, sym
);
1530 /* Add in the thread pointer for a TLS LE access. */
1532 static rtx
riscv_tls_add_tp_le (rtx dest
, rtx base
, rtx sym
)
1534 rtx tp
= gen_rtx_REG (Pmode
, THREAD_POINTER_REGNUM
);
1535 if (Pmode
== DImode
)
1536 return gen_tls_add_tp_ledi (dest
, base
, tp
, sym
);
1538 return gen_tls_add_tp_lesi (dest
, base
, tp
, sym
);
1541 /* If MODE is MAX_MACHINE_MODE, ADDR appears as a move operand, otherwise
1542 it appears in a MEM of that mode. Return true if ADDR is a legitimate
1543 constant in that context and can be split into high and low parts.
1544 If so, and if LOW_OUT is nonnull, emit the high part and store the
1545 low part in *LOW_OUT. Leave *LOW_OUT unchanged otherwise.
1547 TEMP is as for riscv_force_temporary and is used to load the high
1548 part into a register.
1550 When MODE is MAX_MACHINE_MODE, the low part is guaranteed to be
1551 a legitimize SET_SRC for an .md pattern, otherwise the low part
1552 is guaranteed to be a legitimate address for mode MODE. */
1555 riscv_split_symbol (rtx temp
, rtx addr
, machine_mode mode
, rtx
*low_out
)
1557 enum riscv_symbol_type symbol_type
;
1559 if ((GET_CODE (addr
) == HIGH
&& mode
== MAX_MACHINE_MODE
)
1560 || !riscv_symbolic_constant_p (addr
, &symbol_type
)
1561 || riscv_symbol_insns (symbol_type
) == 0
1562 || !riscv_split_symbol_type (symbol_type
))
1566 switch (symbol_type
)
1568 case SYMBOL_ABSOLUTE
:
1570 rtx high
= gen_rtx_HIGH (Pmode
, copy_rtx (addr
));
1571 high
= riscv_force_temporary (temp
, high
);
1572 *low_out
= gen_rtx_LO_SUM (Pmode
, high
, addr
);
1578 static unsigned seqno
;
1582 ssize_t bytes
= snprintf (buf
, sizeof (buf
), ".LA%u", seqno
);
1583 gcc_assert ((size_t) bytes
< sizeof (buf
));
1585 label
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
1586 SYMBOL_REF_FLAGS (label
) |= SYMBOL_FLAG_LOCAL
;
1587 /* ??? Ugly hack to make weak symbols work. May need to change the
1588 RTL for the auipc and/or low patterns to get a better fix for
1590 if (! nonzero_address_p (addr
))
1591 SYMBOL_REF_WEAK (label
) = 1;
1594 temp
= gen_reg_rtx (Pmode
);
1596 if (Pmode
== DImode
)
1597 emit_insn (gen_auipcdi (temp
, copy_rtx (addr
), GEN_INT (seqno
)));
1599 emit_insn (gen_auipcsi (temp
, copy_rtx (addr
), GEN_INT (seqno
)));
1601 *low_out
= gen_rtx_LO_SUM (Pmode
, temp
, label
);
1614 /* Return a legitimate address for REG + OFFSET. TEMP is as for
1615 riscv_force_temporary; it is only needed when OFFSET is not a
1619 riscv_add_offset (rtx temp
, rtx reg
, HOST_WIDE_INT offset
)
1621 if (!SMALL_OPERAND (offset
))
1625 /* Leave OFFSET as a 16-bit offset and put the excess in HIGH.
1626 The addition inside the macro CONST_HIGH_PART may cause an
1627 overflow, so we need to force a sign-extension check. */
1628 high
= gen_int_mode (CONST_HIGH_PART (offset
), Pmode
);
1629 offset
= CONST_LOW_PART (offset
);
1630 high
= riscv_force_temporary (temp
, high
);
1631 reg
= riscv_force_temporary (temp
, gen_rtx_PLUS (Pmode
, high
, reg
));
1633 return plus_constant (Pmode
, reg
, offset
);
1636 /* The __tls_get_attr symbol. */
1637 static GTY(()) rtx riscv_tls_symbol
;
1639 /* Return an instruction sequence that calls __tls_get_addr. SYM is
1640 the TLS symbol we are referencing and TYPE is the symbol type to use
1641 (either global dynamic or local dynamic). RESULT is an RTX for the
1642 return value location. */
1645 riscv_call_tls_get_addr (rtx sym
, rtx result
)
1647 rtx a0
= gen_rtx_REG (Pmode
, GP_ARG_FIRST
), func
;
1650 if (!riscv_tls_symbol
)
1651 riscv_tls_symbol
= init_one_libfunc ("__tls_get_addr");
1652 func
= gen_rtx_MEM (FUNCTION_MODE
, riscv_tls_symbol
);
1656 emit_insn (riscv_got_load_tls_gd (a0
, sym
));
1657 insn
= emit_call_insn (gen_call_value (result
, func
, const0_rtx
, NULL
));
1658 RTL_CONST_CALL_P (insn
) = 1;
1659 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), a0
);
1660 insn
= get_insns ();
1667 /* Generate the code to access LOC, a thread-local SYMBOL_REF, and return
1668 its address. The return value will be both a valid address and a valid
1669 SET_SRC (either a REG or a LO_SUM). */
1672 riscv_legitimize_tls_address (rtx loc
)
1675 enum tls_model model
= SYMBOL_REF_TLS_MODEL (loc
);
1678 /* TLS copy relocs are now deprecated and should not be used. */
1679 /* Since we support TLS copy relocs, non-PIC TLS accesses may all use LE. */
1681 model
= TLS_MODEL_LOCAL_EXEC
;
1686 case TLS_MODEL_LOCAL_DYNAMIC
:
1687 /* Rely on section anchors for the optimization that LDM TLS
1688 provides. The anchor's address is loaded with GD TLS. */
1689 case TLS_MODEL_GLOBAL_DYNAMIC
:
1690 tmp
= gen_rtx_REG (Pmode
, GP_RETURN
);
1691 dest
= gen_reg_rtx (Pmode
);
1692 emit_libcall_block (riscv_call_tls_get_addr (loc
, tmp
), dest
, tmp
, loc
);
1695 case TLS_MODEL_INITIAL_EXEC
:
1696 /* la.tls.ie; tp-relative add */
1697 tp
= gen_rtx_REG (Pmode
, THREAD_POINTER_REGNUM
);
1698 tmp
= gen_reg_rtx (Pmode
);
1699 emit_insn (riscv_got_load_tls_ie (tmp
, loc
));
1700 dest
= gen_reg_rtx (Pmode
);
1701 emit_insn (gen_add3_insn (dest
, tmp
, tp
));
1704 case TLS_MODEL_LOCAL_EXEC
:
1705 tmp
= riscv_unspec_offset_high (NULL
, loc
, SYMBOL_TLS_LE
);
1706 dest
= gen_reg_rtx (Pmode
);
1707 emit_insn (riscv_tls_add_tp_le (dest
, tmp
, loc
));
1708 dest
= gen_rtx_LO_SUM (Pmode
, dest
,
1709 riscv_unspec_address (loc
, SYMBOL_TLS_LE
));
1718 /* If X is not a valid address for mode MODE, force it into a register. */
1721 riscv_force_address (rtx x
, machine_mode mode
)
1723 if (!riscv_legitimate_address_p (mode
, x
, false))
1724 x
= force_reg (Pmode
, x
);
1728 /* Modify base + offset so that offset fits within a compressed load/store insn
1729 and the excess is added to base. */
1732 riscv_shorten_lw_offset (rtx base
, HOST_WIDE_INT offset
)
1735 /* Leave OFFSET as an unsigned 5-bit offset scaled by 4 and put the excess
1737 high
= GEN_INT (offset
& ~CSW_MAX_OFFSET
);
1738 offset
&= CSW_MAX_OFFSET
;
1739 if (!SMALL_OPERAND (INTVAL (high
)))
1740 high
= force_reg (Pmode
, high
);
1741 base
= force_reg (Pmode
, gen_rtx_PLUS (Pmode
, high
, base
));
1742 addr
= plus_constant (Pmode
, base
, offset
);
1746 /* This function is used to implement LEGITIMIZE_ADDRESS. If X can
1747 be legitimized in a way that the generic machinery might not expect,
1748 return a new address, otherwise return NULL. MODE is the mode of
1749 the memory being accessed. */
1752 riscv_legitimize_address (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
1757 if (riscv_tls_symbol_p (x
))
1758 return riscv_legitimize_tls_address (x
);
1760 /* See if the address can split into a high part and a LO_SUM. */
1761 if (riscv_split_symbol (NULL
, x
, mode
, &addr
))
1762 return riscv_force_address (addr
, mode
);
1764 /* Handle BASE + OFFSET. */
1765 if (GET_CODE (x
) == PLUS
&& CONST_INT_P (XEXP (x
, 1))
1766 && INTVAL (XEXP (x
, 1)) != 0)
1768 rtx base
= XEXP (x
, 0);
1769 HOST_WIDE_INT offset
= INTVAL (XEXP (x
, 1));
1771 if (!riscv_valid_base_register_p (base
, mode
, false))
1772 base
= copy_to_mode_reg (Pmode
, base
);
1773 if (optimize_function_for_size_p (cfun
)
1774 && (strcmp (current_pass
->name
, "shorten_memrefs") == 0)
1776 /* Convert BASE + LARGE_OFFSET into NEW_BASE + SMALL_OFFSET to allow
1777 possible compressed load/store. */
1778 addr
= riscv_shorten_lw_offset (base
, offset
);
1780 addr
= riscv_add_offset (NULL
, base
, offset
);
1781 return riscv_force_address (addr
, mode
);
1787 /* Load VALUE into DEST. TEMP is as for riscv_force_temporary. ORIG_MODE
1788 is the original src mode before promotion. */
1791 riscv_move_integer (rtx temp
, rtx dest
, HOST_WIDE_INT value
,
1792 machine_mode orig_mode
)
1794 struct riscv_integer_op codes
[RISCV_MAX_INTEGER_OPS
];
1799 mode
= GET_MODE (dest
);
1800 /* We use the original mode for the riscv_build_integer call, because HImode
1801 values are given special treatment. */
1802 num_ops
= riscv_build_integer (codes
, value
, orig_mode
);
1804 if (can_create_pseudo_p () && num_ops
> 2 /* not a simple constant */
1805 && num_ops
>= riscv_split_integer_cost (value
))
1806 x
= riscv_split_integer (value
, mode
);
1809 codes
[0].value
= trunc_int_for_mode (codes
[0].value
, mode
);
1810 /* Apply each binary operation to X. */
1811 x
= GEN_INT (codes
[0].value
);
1813 for (i
= 1; i
< num_ops
; i
++)
1815 if (!can_create_pseudo_p ())
1816 x
= riscv_emit_set (temp
, x
);
1818 x
= force_reg (mode
, x
);
1819 codes
[i
].value
= trunc_int_for_mode (codes
[i
].value
, mode
);
1820 x
= gen_rtx_fmt_ee (codes
[i
].code
, mode
, x
, GEN_INT (codes
[i
].value
));
1824 riscv_emit_set (dest
, x
);
1827 /* Subroutine of riscv_legitimize_move. Move constant SRC into register
1828 DEST given that SRC satisfies immediate_operand but doesn't satisfy
1832 riscv_legitimize_const_move (machine_mode mode
, rtx dest
, rtx src
)
1836 /* Split moves of big integers into smaller pieces. */
1837 if (splittable_const_int_operand (src
, mode
))
1839 riscv_move_integer (dest
, dest
, INTVAL (src
), mode
);
1843 /* Split moves of symbolic constants into high/low pairs. */
1844 if (riscv_split_symbol (dest
, src
, MAX_MACHINE_MODE
, &src
))
1846 riscv_emit_set (dest
, src
);
1850 /* Generate the appropriate access sequences for TLS symbols. */
1851 if (riscv_tls_symbol_p (src
))
1853 riscv_emit_move (dest
, riscv_legitimize_tls_address (src
));
1857 /* If we have (const (plus symbol offset)), and that expression cannot
1858 be forced into memory, load the symbol first and add in the offset. Also
1859 prefer to do this even if the constant _can_ be forced into memory, as it
1860 usually produces better code. */
1861 split_const (src
, &base
, &offset
);
1862 if (offset
!= const0_rtx
1863 && (targetm
.cannot_force_const_mem (mode
, src
) || can_create_pseudo_p ()))
1865 base
= riscv_force_temporary (dest
, base
);
1866 riscv_emit_move (dest
, riscv_add_offset (NULL
, base
, INTVAL (offset
)));
1870 src
= force_const_mem (mode
, src
);
1872 /* When using explicit relocs, constant pool references are sometimes
1873 not legitimate addresses. */
1874 riscv_split_symbol (dest
, XEXP (src
, 0), mode
, &XEXP (src
, 0));
1875 riscv_emit_move (dest
, src
);
1878 /* Report when we try to do something that requires vector when vector is
1879 disabled. This is an error of last resort and isn't very high-quality. It
1880 usually involves attempts to measure the vector length in some way. */
1883 riscv_report_v_required (void)
1885 static bool reported_p
= false;
1887 /* Avoid reporting a slew of messages for a single oversight. */
1891 error ("this operation requires the RVV ISA extension");
1892 inform (input_location
, "you can enable RVV using the command-line"
1893 " option %<-march%>, or by using the %<target%>"
1894 " attribute or pragma");
1898 /* Helper function to operation for rtx_code CODE. */
1900 riscv_expand_op (enum rtx_code code
, machine_mode mode
, rtx op0
, rtx op1
,
1903 if (can_create_pseudo_p ())
1906 if (GET_RTX_CLASS (code
) == RTX_UNARY
)
1907 result
= expand_simple_unop (mode
, code
, op1
, NULL_RTX
, false);
1909 result
= expand_simple_binop (mode
, code
, op1
, op2
, NULL_RTX
, false,
1911 riscv_emit_move (op0
, result
);
1916 /* The following implementation is for prologue and epilogue.
1917 Because prologue and epilogue can not use pseudo register.
1918 We can't using expand_simple_binop or expand_simple_unop. */
1919 if (GET_RTX_CLASS (code
) == RTX_UNARY
)
1920 pat
= gen_rtx_fmt_e (code
, mode
, op1
);
1922 pat
= gen_rtx_fmt_ee (code
, mode
, op1
, op2
);
1923 emit_insn (gen_rtx_SET (op0
, pat
));
1927 /* Expand mult operation with constant integer, multiplicand also used as a
1928 * temporary register. */
1931 riscv_expand_mult_with_const_int (machine_mode mode
, rtx dest
, rtx multiplicand
,
1934 if (multiplier
== 0)
1936 riscv_emit_move (dest
, GEN_INT (0));
1940 bool neg_p
= multiplier
< 0;
1941 int multiplier_abs
= abs (multiplier
);
1943 if (multiplier_abs
== 1)
1946 riscv_expand_op (NEG
, mode
, dest
, multiplicand
, NULL_RTX
);
1948 riscv_emit_move (dest
, multiplicand
);
1952 if (pow2p_hwi (multiplier_abs
))
1955 multiplicand = [BYTES_PER_RISCV_VECTOR].
1956 1. const_poly_int:P [BYTES_PER_RISCV_VECTOR * 8].
1960 2. const_poly_int:P [-BYTES_PER_RISCV_VECTOR * 8].
1966 riscv_expand_op (ASHIFT
, mode
, dest
, multiplicand
,
1967 gen_int_mode (exact_log2 (multiplier_abs
), QImode
));
1969 riscv_expand_op (NEG
, mode
, dest
, dest
, NULL_RTX
);
1971 else if (pow2p_hwi (multiplier_abs
+ 1))
1974 multiplicand = [BYTES_PER_RISCV_VECTOR].
1975 1. const_poly_int:P [BYTES_PER_RISCV_VECTOR * 7].
1980 2. const_poly_int:P [-BYTES_PER_RISCV_VECTOR * 7].
1984 sub a5, a4, a5 + neg a5, a5 => sub a5, a5, a4
1986 riscv_expand_op (ASHIFT
, mode
, dest
, multiplicand
,
1987 gen_int_mode (exact_log2 (multiplier_abs
+ 1),
1990 riscv_expand_op (MINUS
, mode
, dest
, multiplicand
, dest
);
1992 riscv_expand_op (MINUS
, mode
, dest
, dest
, multiplicand
);
1994 else if (pow2p_hwi (multiplier
- 1))
1997 multiplicand = [BYTES_PER_RISCV_VECTOR].
1998 1. const_poly_int:P [BYTES_PER_RISCV_VECTOR * 9].
2003 2. const_poly_int:P [-BYTES_PER_RISCV_VECTOR * 9].
2010 riscv_expand_op (ASHIFT
, mode
, dest
, multiplicand
,
2011 gen_int_mode (exact_log2 (multiplier_abs
- 1),
2013 riscv_expand_op (PLUS
, mode
, dest
, dest
, multiplicand
);
2015 riscv_expand_op (NEG
, mode
, dest
, dest
, NULL_RTX
);
2019 /* We use multiplication for remaining cases. */
2022 && "M-extension must be enabled to calculate the poly_int "
2024 riscv_emit_move (dest
, gen_int_mode (multiplier
, mode
));
2025 riscv_expand_op (MULT
, mode
, dest
, dest
, multiplicand
);
2030 /* Analyze src and emit const_poly_int mov sequence. */
2033 riscv_legitimize_poly_move (machine_mode mode
, rtx dest
, rtx tmp
, rtx src
)
2035 poly_int64 value
= rtx_to_poly_int64 (src
);
2036 int offset
= value
.coeffs
[0];
2037 int factor
= value
.coeffs
[1];
2038 int vlenb
= BYTES_PER_RISCV_VECTOR
.coeffs
[1];
2040 /* Calculate (const_poly_int:MODE [m, n]) using scalar instructions.
2041 For any (const_poly_int:MODE [m, n]), the calculation formula is as
2044 When minimum VLEN = 32, poly of VLENB = (4, 4).
2045 base = vlenb(4, 4) or vlenb/2(2, 2) or vlenb/4(1, 1).
2046 When minimum VLEN > 32, poly of VLENB = (8, 8).
2047 base = vlenb(8, 8) or vlenb/2(4, 4) or vlenb/4(2, 2) or vlenb/8(1, 1).
2048 magn = (n, n) / base.
2049 (m, n) = base * magn + constant.
2050 This calculation doesn't need div operation. */
2052 emit_move_insn (tmp
, gen_int_mode (BYTES_PER_RISCV_VECTOR
, mode
));
2054 if (BYTES_PER_RISCV_VECTOR
.is_constant ())
2056 gcc_assert (value
.is_constant ());
2057 riscv_emit_move (dest
, GEN_INT (value
.to_constant ()));
2060 else if ((factor
% vlenb
) == 0)
2062 else if ((factor
% (vlenb
/ 2)) == 0)
2064 else if ((factor
% (vlenb
/ 4)) == 0)
2066 else if ((factor
% (vlenb
/ 8)) == 0)
2068 else if ((factor
% (vlenb
/ 16)) == 0)
2073 if (div_factor
!= 1)
2074 riscv_expand_op (LSHIFTRT
, mode
, tmp
, tmp
,
2075 gen_int_mode (exact_log2 (div_factor
), QImode
));
2077 riscv_expand_mult_with_const_int (mode
, dest
, tmp
,
2078 factor
/ (vlenb
/ div_factor
));
2079 HOST_WIDE_INT constant
= offset
- factor
;
2083 else if (SMALL_OPERAND (constant
))
2084 riscv_expand_op (PLUS
, mode
, dest
, dest
, gen_int_mode (constant
, mode
));
2087 /* Handle the constant value is not a 12-bit value. */
2090 /* Leave OFFSET as a 16-bit offset and put the excess in HIGH.
2091 The addition inside the macro CONST_HIGH_PART may cause an
2092 overflow, so we need to force a sign-extension check. */
2093 high
= gen_int_mode (CONST_HIGH_PART (constant
), mode
);
2094 constant
= CONST_LOW_PART (constant
);
2095 riscv_emit_move (tmp
, high
);
2096 riscv_expand_op (PLUS
, mode
, dest
, tmp
, dest
);
2097 riscv_expand_op (PLUS
, mode
, dest
, dest
, gen_int_mode (constant
, mode
));
2101 /* Adjust scalable frame of vector for prologue && epilogue. */
2104 riscv_v_adjust_scalable_frame (rtx target
, poly_int64 offset
, bool epilogue
)
2106 rtx tmp
= RISCV_PROLOGUE_TEMP (Pmode
);
2107 rtx adjust_size
= RISCV_PROLOGUE_TEMP2 (Pmode
);
2108 rtx insn
, dwarf
, adjust_frame_rtx
;
2110 riscv_legitimize_poly_move (Pmode
, adjust_size
, tmp
,
2111 gen_int_mode (offset
, Pmode
));
2114 insn
= gen_add3_insn (target
, target
, adjust_size
);
2116 insn
= gen_sub3_insn (target
, target
, adjust_size
);
2118 insn
= emit_insn (insn
);
2120 RTX_FRAME_RELATED_P (insn
) = 1;
2123 = gen_rtx_SET (target
,
2124 plus_constant (Pmode
, target
, epilogue
? offset
: -offset
));
2126 dwarf
= alloc_reg_note (REG_FRAME_RELATED_EXPR
, copy_rtx (adjust_frame_rtx
),
2129 REG_NOTES (insn
) = dwarf
;
2132 /* If (set DEST SRC) is not a valid move instruction, emit an equivalent
2133 sequence that is valid. */
2136 riscv_legitimize_move (machine_mode mode
, rtx dest
, rtx src
)
2138 if (CONST_POLY_INT_P (src
))
2142 (insn 183 182 184 6 (set (mem:QI (plus:DI (reg/f:DI 156)
2143 (const_int 96 [0x60])) [0 S1 A8])
2144 (const_poly_int:QI [8, 8]))
2145 "../../../../riscv-gcc/libgcc/unwind-dw2.c":1579:3 -1 (nil))
2149 emit_move_insn (dest
, force_reg (mode
, src
));
2152 poly_int64 value
= rtx_to_poly_int64 (src
);
2153 if (!value
.is_constant () && !TARGET_VECTOR
)
2155 riscv_report_v_required ();
2159 if (satisfies_constraint_vp (src
))
2162 if (GET_MODE_SIZE (mode
).to_constant () < GET_MODE_SIZE (Pmode
))
2164 /* In RV32 system, handle (const_poly_int:QI [m, n])
2165 (const_poly_int:HI [m, n]).
2166 In RV64 system, handle (const_poly_int:QI [m, n])
2167 (const_poly_int:HI [m, n])
2168 (const_poly_int:SI [m, n]). */
2169 rtx tmp
= gen_reg_rtx (Pmode
);
2170 riscv_legitimize_poly_move (Pmode
, gen_lowpart (Pmode
, dest
), tmp
,
2175 /* In RV32 system, handle (const_poly_int:SI [m, n])
2176 (const_poly_int:DI [m, n]).
2177 In RV64 system, handle (const_poly_int:DI [m, n]).
2178 FIXME: Maybe we could gen SImode in RV32 and then sign-extend to DImode,
2179 the offset should not exceed 4GiB in general. */
2180 rtx tmp
= gen_reg_rtx (mode
);
2181 riscv_legitimize_poly_move (mode
, dest
, tmp
, src
);
2186 (set (reg:QI target) (mem:QI (address)))
2188 (set (reg:DI temp) (zero_extend:DI (mem:QI (address))))
2189 (set (reg:QI target) (subreg:QI (reg:DI temp) 0))
2190 with auto-sign/zero extend. */
2191 if (GET_MODE_CLASS (mode
) == MODE_INT
2192 && GET_MODE_SIZE (mode
).to_constant () < UNITS_PER_WORD
2193 && can_create_pseudo_p ()
2199 temp_reg
= gen_reg_rtx (word_mode
);
2200 zero_extend_p
= (LOAD_EXTEND_OP (mode
) == ZERO_EXTEND
);
2201 emit_insn (gen_extend_insn (temp_reg
, src
, word_mode
, mode
,
2203 riscv_emit_move (dest
, gen_lowpart (mode
, temp_reg
));
2207 if (!register_operand (dest
, mode
) && !reg_or_0_operand (src
, mode
))
2211 if (GET_CODE (src
) == CONST_INT
)
2213 /* Apply the equivalent of PROMOTE_MODE here for constants to
2215 machine_mode promoted_mode
= mode
;
2216 if (GET_MODE_CLASS (mode
) == MODE_INT
2217 && GET_MODE_SIZE (mode
).to_constant () < UNITS_PER_WORD
)
2218 promoted_mode
= word_mode
;
2220 if (splittable_const_int_operand (src
, mode
))
2222 reg
= gen_reg_rtx (promoted_mode
);
2223 riscv_move_integer (reg
, reg
, INTVAL (src
), mode
);
2226 reg
= force_reg (promoted_mode
, src
);
2228 if (promoted_mode
!= mode
)
2229 reg
= gen_lowpart (mode
, reg
);
2232 reg
= force_reg (mode
, src
);
2233 riscv_emit_move (dest
, reg
);
2237 /* We need to deal with constants that would be legitimate
2238 immediate_operands but aren't legitimate move_operands. */
2239 if (CONSTANT_P (src
) && !move_operand (src
, mode
))
2241 riscv_legitimize_const_move (mode
, dest
, src
);
2242 set_unique_reg_note (get_last_insn (), REG_EQUAL
, copy_rtx (src
));
2246 /* RISC-V GCC may generate non-legitimate address due to we provide some
2247 pattern for optimize access PIC local symbol and it's make GCC generate
2248 unrecognizable instruction during optmizing. */
2250 if (MEM_P (dest
) && !riscv_legitimate_address_p (mode
, XEXP (dest
, 0),
2253 XEXP (dest
, 0) = riscv_force_address (XEXP (dest
, 0), mode
);
2256 if (MEM_P (src
) && !riscv_legitimate_address_p (mode
, XEXP (src
, 0),
2259 XEXP (src
, 0) = riscv_force_address (XEXP (src
, 0), mode
);
2265 /* Return true if there is an instruction that implements CODE and accepts
2266 X as an immediate operand. */
2269 riscv_immediate_operand_p (int code
, HOST_WIDE_INT x
)
2276 /* All shift counts are truncated to a valid constant. */
2285 /* These instructions take 12-bit signed immediates. */
2286 return SMALL_OPERAND (x
);
2289 /* We add 1 to the immediate and use SLT. */
2290 return SMALL_OPERAND (x
+ 1);
2293 /* Likewise SLTU, but reject the always-true case. */
2294 return SMALL_OPERAND (x
+ 1) && x
+ 1 != 0;
2298 /* We can emulate an immediate of 1 by using GT/GTU against x0. */
2302 /* By default assume that x0 can be used for 0. */
2307 /* Return the cost of binary operation X, given that the instruction
2308 sequence for a word-sized or smaller operation takes SIGNLE_INSNS
2309 instructions and that the sequence of a double-word operation takes
2310 DOUBLE_INSNS instructions. */
2313 riscv_binary_cost (rtx x
, int single_insns
, int double_insns
)
2315 if (!riscv_v_ext_mode_p (GET_MODE (x
))
2316 && GET_MODE_SIZE (GET_MODE (x
)).to_constant () == UNITS_PER_WORD
* 2)
2317 return COSTS_N_INSNS (double_insns
);
2318 return COSTS_N_INSNS (single_insns
);
2321 /* Return the cost of sign- or zero-extending OP. */
2324 riscv_extend_cost (rtx op
, bool unsigned_p
)
2329 if (unsigned_p
&& GET_MODE (op
) == QImode
)
2330 /* We can use ANDI. */
2331 return COSTS_N_INSNS (1);
2333 /* ZBA provide zext.w. */
2334 if (TARGET_ZBA
&& TARGET_64BIT
&& unsigned_p
&& GET_MODE (op
) == SImode
)
2335 return COSTS_N_INSNS (1);
2337 /* ZBB provide zext.h, sext.b and sext.h. */
2340 if (!unsigned_p
&& GET_MODE (op
) == QImode
)
2341 return COSTS_N_INSNS (1);
2343 if (GET_MODE (op
) == HImode
)
2344 return COSTS_N_INSNS (1);
2347 if (!unsigned_p
&& GET_MODE (op
) == SImode
)
2348 /* We can use SEXT.W. */
2349 return COSTS_N_INSNS (1);
2351 /* We need to use a shift left and a shift right. */
2352 return COSTS_N_INSNS (2);
2355 /* Implement TARGET_RTX_COSTS. */
2357 #define SINGLE_SHIFT_COST 1
2360 riscv_rtx_costs (rtx x
, machine_mode mode
, int outer_code
, int opno ATTRIBUTE_UNUSED
,
2361 int *total
, bool speed
)
2363 /* TODO: We set RVV instruction cost as 1 by default.
2364 Cost Model need to be well analyzed and supported in the future. */
2365 if (riscv_v_ext_mode_p (mode
))
2367 *total
= COSTS_N_INSNS (1);
2371 bool float_mode_p
= FLOAT_MODE_P (mode
);
2374 switch (GET_CODE (x
))
2377 if (riscv_immediate_operand_p (outer_code
, INTVAL (x
)))
2387 /* With TARGET_SUPPORTS_WIDE_INT const int can't be in CONST_DOUBLE
2388 rtl object. Weird recheck due to switch-case fall through above. */
2389 if (GET_CODE (x
) == CONST_DOUBLE
)
2390 gcc_assert (GET_MODE (x
) != VOIDmode
);
2394 if ((cost
= riscv_const_insns (x
)) > 0)
2396 /* If the constant is likely to be stored in a GPR, SETs of
2397 single-insn constants are as cheap as register sets; we
2398 never want to CSE them. */
2399 if (cost
== 1 && outer_code
== SET
)
2401 /* When we load a constant more than once, it usually is better
2402 to duplicate the last operation in the sequence than to CSE
2403 the constant itself. */
2404 else if (outer_code
== SET
|| GET_MODE (x
) == VOIDmode
)
2405 *total
= COSTS_N_INSNS (1);
2407 else /* The instruction will be fetched from the constant pool. */
2408 *total
= COSTS_N_INSNS (riscv_symbol_insns (SYMBOL_ABSOLUTE
));
2412 /* If the address is legitimate, return the number of
2413 instructions it needs. */
2414 if ((cost
= riscv_address_insns (XEXP (x
, 0), mode
, true)) > 0)
2416 /* When optimizing for size, make uncompressible 32-bit addresses
2417 more expensive so that compressible 32-bit addresses are
2419 if (TARGET_RVC
&& !speed
&& riscv_mshorten_memrefs
&& mode
== SImode
2420 && !riscv_compressed_lw_address_p (XEXP (x
, 0)))
2423 *total
= COSTS_N_INSNS (cost
+ tune_param
->memory_cost
);
2426 /* Otherwise use the default handling. */
2430 if ((TARGET_SFB_ALU
|| TARGET_XTHEADCONDMOV
)
2431 && reg_or_0_operand (XEXP (x
, 1), mode
)
2432 && sfb_alu_operand (XEXP (x
, 2), mode
)
2433 && comparison_operator (XEXP (x
, 0), VOIDmode
))
2435 /* For predicated conditional-move operations we assume the cost
2436 of a single instruction even though there are actually two. */
2437 *total
= COSTS_N_INSNS (1);
2440 else if (LABEL_REF_P (XEXP (x
, 1)) && XEXP (x
, 2) == pc_rtx
)
2442 if (equality_operator (XEXP (x
, 0), mode
)
2443 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == ZERO_EXTRACT
)
2445 *total
= COSTS_N_INSNS (SINGLE_SHIFT_COST
+ 1);
2448 if (order_operator (XEXP (x
, 0), mode
))
2450 *total
= COSTS_N_INSNS (1);
2457 *total
= COSTS_N_INSNS (GET_MODE_SIZE (mode
).to_constant () > UNITS_PER_WORD
? 2 : 1);
2461 /* slli.uw pattern for zba. */
2462 if (TARGET_ZBA
&& TARGET_64BIT
&& mode
== DImode
2463 && GET_CODE (XEXP (x
, 0)) == ASHIFT
)
2465 rtx and_rhs
= XEXP (x
, 1);
2466 rtx ashift_lhs
= XEXP (XEXP (x
, 0), 0);
2467 rtx ashift_rhs
= XEXP (XEXP (x
, 0), 1);
2468 if (REG_P (ashift_lhs
)
2469 && CONST_INT_P (ashift_rhs
)
2470 && CONST_INT_P (and_rhs
)
2471 && ((INTVAL (and_rhs
) >> INTVAL (ashift_rhs
)) == 0xffffffff))
2472 *total
= COSTS_N_INSNS (1);
2475 /* bclri pattern for zbs. */
2477 && not_single_bit_mask_operand (XEXP (x
, 1), VOIDmode
))
2479 *total
= COSTS_N_INSNS (1);
2482 /* bclr pattern for zbs. */
2484 && REG_P (XEXP (x
, 1))
2485 && GET_CODE (XEXP (x
, 0)) == ROTATE
2486 && CONST_INT_P (XEXP ((XEXP (x
, 0)), 0))
2487 && INTVAL (XEXP ((XEXP (x
, 0)), 0)) == -2)
2489 *total
= COSTS_N_INSNS (1);
2496 /* orn, andn and xorn pattern for zbb. */
2498 && GET_CODE (XEXP (x
, 0)) == NOT
)
2500 *total
= riscv_binary_cost (x
, 1, 2);
2504 /* bset[i] and binv[i] pattern for zbs. */
2505 if ((GET_CODE (x
) == IOR
|| GET_CODE (x
) == XOR
)
2507 && ((GET_CODE (XEXP (x
, 0)) == ASHIFT
2508 && CONST_INT_P (XEXP (XEXP (x
, 0), 0)))
2509 || single_bit_mask_operand (XEXP (x
, 1), VOIDmode
)))
2511 *total
= COSTS_N_INSNS (1);
2515 /* Double-word operations use two single-word operations. */
2516 *total
= riscv_binary_cost (x
, 1, 2);
2520 /* This is an SImode shift. */
2521 if (outer_code
== SET
2522 && CONST_INT_P (XEXP (x
, 1))
2523 && CONST_INT_P (XEXP (x
, 2))
2524 && (INTVAL (XEXP (x
, 2)) > 0)
2525 && (INTVAL (XEXP (x
, 1)) + INTVAL (XEXP (x
, 2)) == 32))
2527 *total
= COSTS_N_INSNS (SINGLE_SHIFT_COST
);
2530 /* bit extraction pattern (zbs:bext, xtheadbs:tst). */
2531 if ((TARGET_ZBS
|| TARGET_XTHEADBS
) && outer_code
== SET
2532 && GET_CODE (XEXP (x
, 1)) == CONST_INT
2533 && INTVAL (XEXP (x
, 1)) == 1)
2535 *total
= COSTS_N_INSNS (SINGLE_SHIFT_COST
);
2540 if (TARGET_XTHEADBB
&& outer_code
== SET
2541 && CONST_INT_P (XEXP (x
, 1))
2542 && CONST_INT_P (XEXP (x
, 2)))
2544 *total
= COSTS_N_INSNS (SINGLE_SHIFT_COST
);
2550 /* bset pattern for zbs. */
2552 && CONST_INT_P (XEXP (x
, 0))
2553 && INTVAL (XEXP (x
, 0)) == 1)
2555 *total
= COSTS_N_INSNS (1);
2561 *total
= riscv_binary_cost (x
, SINGLE_SHIFT_COST
,
2562 CONSTANT_P (XEXP (x
, 1)) ? 4 : 9);
2566 *total
= COSTS_N_INSNS (float_mode_p
? 1 : 3);
2570 *total
= set_src_cost (XEXP (x
, 0), mode
, speed
);
2574 /* This is an SImode shift. */
2575 if (outer_code
== SET
&& GET_MODE (x
) == DImode
2576 && GET_MODE (XEXP (x
, 0)) == SImode
)
2578 *total
= COSTS_N_INSNS (SINGLE_SHIFT_COST
);
2591 /* Branch comparisons have VOIDmode, so use the first operand's
2593 mode
= GET_MODE (XEXP (x
, 0));
2595 *total
= tune_param
->fp_add
[mode
== DFmode
];
2597 *total
= riscv_binary_cost (x
, 1, 3);
2602 /* (FEQ(A, A) & FEQ(B, B)) compared against 0. */
2603 mode
= GET_MODE (XEXP (x
, 0));
2604 *total
= tune_param
->fp_add
[mode
== DFmode
] + COSTS_N_INSNS (2);
2608 /* (FEQ(A, A) & FEQ(B, B)) compared against FEQ(A, B). */
2609 mode
= GET_MODE (XEXP (x
, 0));
2610 *total
= tune_param
->fp_add
[mode
== DFmode
] + COSTS_N_INSNS (3);
2614 /* (FLT(A, A) || FGT(B, B)). */
2615 mode
= GET_MODE (XEXP (x
, 0));
2616 *total
= tune_param
->fp_add
[mode
== DFmode
] + COSTS_N_INSNS (2);
2623 /* FLT or FLE, but guarded by an FFLAGS read and write. */
2624 mode
= GET_MODE (XEXP (x
, 0));
2625 *total
= tune_param
->fp_add
[mode
== DFmode
] + COSTS_N_INSNS (4);
2630 *total
= tune_param
->fp_add
[mode
== DFmode
];
2632 *total
= riscv_binary_cost (x
, 1, 4);
2636 /* add.uw pattern for zba. */
2638 && (TARGET_64BIT
&& (mode
== DImode
))
2639 && GET_CODE (XEXP (x
, 0)) == ZERO_EXTEND
2640 && REG_P (XEXP (XEXP (x
, 0), 0))
2641 && GET_MODE (XEXP (XEXP (x
, 0), 0)) == SImode
)
2643 *total
= COSTS_N_INSNS (1);
2646 /* shNadd pattern for zba. */
2648 && ((!TARGET_64BIT
&& (mode
== SImode
)) ||
2649 (TARGET_64BIT
&& (mode
== DImode
)))
2650 && (GET_CODE (XEXP (x
, 0)) == ASHIFT
)
2651 && REG_P (XEXP (XEXP (x
, 0), 0))
2652 && CONST_INT_P (XEXP (XEXP (x
, 0), 1))
2653 && IN_RANGE (INTVAL (XEXP (XEXP (x
, 0), 1)), 1, 3))
2655 *total
= COSTS_N_INSNS (1);
2658 /* Before strength-reduction, the shNadd can be expressed as the addition
2659 of a multiplication with a power-of-two. If this case is not handled,
2660 the strength-reduction in expmed.c will calculate an inflated cost. */
2662 && mode
== word_mode
2663 && GET_CODE (XEXP (x
, 0)) == MULT
2664 && REG_P (XEXP (XEXP (x
, 0), 0))
2665 && CONST_INT_P (XEXP (XEXP (x
, 0), 1))
2666 && pow2p_hwi (INTVAL (XEXP (XEXP (x
, 0), 1)))
2667 && IN_RANGE (exact_log2 (INTVAL (XEXP (XEXP (x
, 0), 1))), 1, 3))
2669 *total
= COSTS_N_INSNS (1);
2672 /* shNadd.uw pattern for zba.
2673 [(set (match_operand:DI 0 "register_operand" "=r")
2675 (and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r")
2676 (match_operand:QI 2 "immediate_operand" "I"))
2677 (match_operand 3 "immediate_operand" ""))
2678 (match_operand:DI 4 "register_operand" "r")))]
2679 "TARGET_64BIT && TARGET_ZBA
2680 && (INTVAL (operands[2]) >= 1) && (INTVAL (operands[2]) <= 3)
2681 && (INTVAL (operands[3]) >> INTVAL (operands[2])) == 0xffffffff"
2684 && (TARGET_64BIT
&& (mode
== DImode
))
2685 && (GET_CODE (XEXP (x
, 0)) == AND
)
2686 && (REG_P (XEXP (x
, 1))))
2689 rtx and_lhs
= XEXP (XEXP (x
, 0), 0);
2690 rtx and_rhs
= XEXP (XEXP (x
, 0), 1);
2691 if (GET_CODE (and_lhs
) != ASHIFT
)
2693 if (!CONST_INT_P (and_rhs
))
2696 rtx ashift_rhs
= XEXP (and_lhs
, 1);
2698 if (!CONST_INT_P (ashift_rhs
)
2699 || !IN_RANGE (INTVAL (ashift_rhs
), 1, 3))
2702 if (CONST_INT_P (and_rhs
)
2703 && ((INTVAL (and_rhs
) >> INTVAL (ashift_rhs
)) == 0xffffffff))
2705 *total
= COSTS_N_INSNS (1);
2712 *total
= tune_param
->fp_add
[mode
== DFmode
];
2714 *total
= riscv_binary_cost (x
, 1, 4);
2719 rtx op
= XEXP (x
, 0);
2720 if (GET_CODE (op
) == FMA
&& !HONOR_SIGNED_ZEROS (mode
))
2722 *total
= (tune_param
->fp_mul
[mode
== DFmode
]
2723 + set_src_cost (XEXP (op
, 0), mode
, speed
)
2724 + set_src_cost (XEXP (op
, 1), mode
, speed
)
2725 + set_src_cost (XEXP (op
, 2), mode
, speed
));
2731 *total
= tune_param
->fp_add
[mode
== DFmode
];
2733 *total
= COSTS_N_INSNS (GET_MODE_SIZE (mode
).to_constant () > UNITS_PER_WORD
? 4 : 1);
2738 *total
= tune_param
->fp_mul
[mode
== DFmode
];
2739 else if (!TARGET_MUL
)
2740 /* Estimate the cost of a library call. */
2741 *total
= COSTS_N_INSNS (speed
? 32 : 6);
2742 else if (GET_MODE_SIZE (mode
).to_constant () > UNITS_PER_WORD
)
2743 *total
= 3 * tune_param
->int_mul
[0] + COSTS_N_INSNS (2);
2745 *total
= COSTS_N_INSNS (1);
2747 *total
= tune_param
->int_mul
[mode
== DImode
];
2755 *total
= tune_param
->fp_div
[mode
== DFmode
];
2763 /* Estimate the cost of a library call. */
2764 *total
= COSTS_N_INSNS (speed
? 32 : 6);
2766 *total
= tune_param
->int_div
[mode
== DImode
];
2768 *total
= COSTS_N_INSNS (1);
2772 /* This is an SImode shift. */
2773 if (GET_CODE (XEXP (x
, 0)) == LSHIFTRT
)
2775 *total
= COSTS_N_INSNS (SINGLE_SHIFT_COST
);
2780 *total
= riscv_extend_cost (XEXP (x
, 0), GET_CODE (x
) == ZERO_EXTEND
);
2786 /* RISC-V only defines rev8 for XLEN, so we will need an extra
2787 shift-right instruction for smaller modes. */
2788 *total
= COSTS_N_INSNS (mode
== word_mode
? 1 : 2);
2794 case UNSIGNED_FLOAT
:
2797 case FLOAT_TRUNCATE
:
2798 *total
= tune_param
->fp_add
[mode
== DFmode
];
2802 *total
= (tune_param
->fp_mul
[mode
== DFmode
]
2803 + set_src_cost (XEXP (x
, 0), mode
, speed
)
2804 + set_src_cost (XEXP (x
, 1), mode
, speed
)
2805 + set_src_cost (XEXP (x
, 2), mode
, speed
));
2809 if (XINT (x
, 1) == UNSPEC_AUIPC
)
2811 /* Make AUIPC cheap to avoid spilling its result to the stack. */
2822 /* Implement TARGET_ADDRESS_COST. */
2825 riscv_address_cost (rtx addr
, machine_mode mode
,
2826 addr_space_t as ATTRIBUTE_UNUSED
,
2827 bool speed ATTRIBUTE_UNUSED
)
2829 /* When optimizing for size, make uncompressible 32-bit addresses more
2830 * expensive so that compressible 32-bit addresses are preferred. */
2831 if (TARGET_RVC
&& !speed
&& riscv_mshorten_memrefs
&& mode
== SImode
2832 && !riscv_compressed_lw_address_p (addr
))
2833 return riscv_address_insns (addr
, mode
, false) + 1;
2834 return riscv_address_insns (addr
, mode
, false);
2837 /* Return one word of double-word value OP. HIGH_P is true to select the
2838 high part or false to select the low part. */
2841 riscv_subword (rtx op
, bool high_p
)
2843 unsigned int byte
= (high_p
!= BYTES_BIG_ENDIAN
) ? UNITS_PER_WORD
: 0;
2844 machine_mode mode
= GET_MODE (op
);
2846 if (mode
== VOIDmode
)
2847 mode
= TARGET_64BIT
? TImode
: DImode
;
2850 return adjust_address (op
, word_mode
, byte
);
2853 gcc_assert (!FP_REG_RTX_P (op
));
2855 return simplify_gen_subreg (word_mode
, op
, mode
, byte
);
2858 /* Return true if a 64-bit move from SRC to DEST should be split into two. */
2861 riscv_split_64bit_move_p (rtx dest
, rtx src
)
2866 /* Allow FPR <-> FPR and FPR <-> MEM moves, and permit the special case
2867 of zeroing an FPR with FCVT.D.W. */
2868 if (TARGET_DOUBLE_FLOAT
2869 && ((FP_REG_RTX_P (src
) && FP_REG_RTX_P (dest
))
2870 || (FP_REG_RTX_P (dest
) && MEM_P (src
))
2871 || (FP_REG_RTX_P (src
) && MEM_P (dest
))
2872 || (FP_REG_RTX_P (dest
) && src
== CONST0_RTX (GET_MODE (src
)))))
2878 /* Split a doubleword move from SRC to DEST. On 32-bit targets,
2879 this function handles 64-bit moves for which riscv_split_64bit_move_p
2880 holds. For 64-bit targets, this function handles 128-bit moves. */
2883 riscv_split_doubleword_move (rtx dest
, rtx src
)
2885 /* XTheadFmv has instructions for accessing the upper bits of a double. */
2886 if (!TARGET_64BIT
&& TARGET_XTHEADFMV
)
2888 if (FP_REG_RTX_P (dest
))
2890 rtx low_src
= riscv_subword (src
, false);
2891 rtx high_src
= riscv_subword (src
, true);
2892 emit_insn (gen_th_fmv_hw_w_x (dest
, high_src
, low_src
));
2895 if (FP_REG_RTX_P (src
))
2897 rtx low_dest
= riscv_subword (dest
, false);
2898 rtx high_dest
= riscv_subword (dest
, true);
2899 emit_insn (gen_th_fmv_x_w (low_dest
, src
));
2900 emit_insn (gen_th_fmv_x_hw (high_dest
, src
));
2905 /* The operation can be split into two normal moves. Decide in
2906 which order to do them. */
2907 rtx low_dest
= riscv_subword (dest
, false);
2908 if (REG_P (low_dest
) && reg_overlap_mentioned_p (low_dest
, src
))
2910 riscv_emit_move (riscv_subword (dest
, true), riscv_subword (src
, true));
2911 riscv_emit_move (low_dest
, riscv_subword (src
, false));
2915 riscv_emit_move (low_dest
, riscv_subword (src
, false));
2916 riscv_emit_move (riscv_subword (dest
, true), riscv_subword (src
, true));
2920 /* Return the appropriate instructions to move SRC into DEST. Assume
2921 that SRC is operand 1 and DEST is operand 0. */
2924 riscv_output_move (rtx dest
, rtx src
)
2926 enum rtx_code dest_code
, src_code
;
2931 dest_code
= GET_CODE (dest
);
2932 src_code
= GET_CODE (src
);
2933 mode
= GET_MODE (dest
);
2934 dbl_p
= (GET_MODE_SIZE (mode
).to_constant () == 8);
2935 width
= GET_MODE_SIZE (mode
).to_constant ();
2937 if (dbl_p
&& riscv_split_64bit_move_p (dest
, src
))
2940 if (dest_code
== REG
&& GP_REG_P (REGNO (dest
)))
2942 if (src_code
== REG
&& FP_REG_P (REGNO (src
)))
2947 return "fmv.x.h\t%0,%1";
2948 /* Using fmv.x.s + sign-extend to emulate fmv.x.h. */
2949 return "fmv.x.s\t%0,%1;slli\t%0,%0,16;srai\t%0,%0,16";
2951 return "fmv.x.s\t%0,%1";
2953 return "fmv.x.d\t%0,%1";
2956 if (src_code
== MEM
)
2959 case 1: return "lbu\t%0,%1";
2960 case 2: return "lhu\t%0,%1";
2961 case 4: return "lw\t%0,%1";
2962 case 8: return "ld\t%0,%1";
2965 if (src_code
== CONST_INT
)
2967 if (SMALL_OPERAND (INTVAL (src
)) || LUI_OPERAND (INTVAL (src
)))
2971 && SINGLE_BIT_MASK_OPERAND (INTVAL (src
)))
2972 return "bseti\t%0,zero,%S1";
2974 /* Should never reach here. */
2978 if (src_code
== HIGH
)
2979 return "lui\t%0,%h1";
2981 if (symbolic_operand (src
, VOIDmode
))
2982 switch (riscv_classify_symbolic_expression (src
))
2984 case SYMBOL_GOT_DISP
: return "la\t%0,%1";
2985 case SYMBOL_ABSOLUTE
: return "lla\t%0,%1";
2986 case SYMBOL_PCREL
: return "lla\t%0,%1";
2987 default: gcc_unreachable ();
2990 if ((src_code
== REG
&& GP_REG_P (REGNO (src
)))
2991 || (src
== CONST0_RTX (mode
)))
2993 if (dest_code
== REG
)
2995 if (GP_REG_P (REGNO (dest
)))
2996 return "mv\t%0,%z1";
2998 if (FP_REG_P (REGNO (dest
)))
3003 return "fmv.h.x\t%0,%z1";
3004 /* High 16 bits should be all-1, otherwise HW will treated
3005 as a n-bit canonical NaN, but isn't matter for softfloat. */
3006 return "fmv.s.x\t%0,%1";
3008 return "fmv.s.x\t%0,%z1";
3011 return "fmv.d.x\t%0,%z1";
3012 /* in RV32, we can emulate fmv.d.x %0, x0 using fcvt.d.w */
3013 gcc_assert (src
== CONST0_RTX (mode
));
3014 return "fcvt.d.w\t%0,x0";
3017 if (dest_code
== MEM
)
3020 case 1: return "sb\t%z1,%0";
3021 case 2: return "sh\t%z1,%0";
3022 case 4: return "sw\t%z1,%0";
3023 case 8: return "sd\t%z1,%0";
3026 if (src_code
== REG
&& FP_REG_P (REGNO (src
)))
3028 if (dest_code
== REG
&& FP_REG_P (REGNO (dest
)))
3033 return "fmv.h\t%0,%1";
3034 return "fmv.s\t%0,%1";
3036 return "fmv.s\t%0,%1";
3038 return "fmv.d\t%0,%1";
3041 if (dest_code
== MEM
)
3045 return "fsh\t%1,%0";
3047 return "fsw\t%1,%0";
3049 return "fsd\t%1,%0";
3052 if (dest_code
== REG
&& FP_REG_P (REGNO (dest
)))
3054 if (src_code
== MEM
)
3058 return "flh\t%0,%1";
3060 return "flw\t%0,%1";
3062 return "fld\t%0,%1";
3065 if (dest_code
== REG
&& GP_REG_P (REGNO (dest
)) && src_code
== CONST_POLY_INT
)
3067 /* We only want a single full vector register VLEN read after reload. */
3068 gcc_assert (known_eq (rtx_to_poly_int64 (src
), BYTES_PER_RISCV_VECTOR
));
3069 return "csrr\t%0,vlenb";
3075 riscv_output_return ()
3077 if (cfun
->machine
->naked_p
)
3084 /* Return true if CMP1 is a suitable second operand for integer ordering
3085 test CODE. See also the *sCC patterns in riscv.md. */
3088 riscv_int_order_operand_ok_p (enum rtx_code code
, rtx cmp1
)
3094 return reg_or_0_operand (cmp1
, VOIDmode
);
3098 return cmp1
== const1_rtx
;
3102 return arith_operand (cmp1
, VOIDmode
);
3105 return sle_operand (cmp1
, VOIDmode
);
3108 return sleu_operand (cmp1
, VOIDmode
);
3115 /* Return true if *CMP1 (of mode MODE) is a valid second operand for
3116 integer ordering test *CODE, or if an equivalent combination can
3117 be formed by adjusting *CODE and *CMP1. When returning true, update
3118 *CODE and *CMP1 with the chosen code and operand, otherwise leave
3122 riscv_canonicalize_int_order_test (enum rtx_code
*code
, rtx
*cmp1
,
3125 HOST_WIDE_INT plus_one
;
3127 if (riscv_int_order_operand_ok_p (*code
, *cmp1
))
3130 if (CONST_INT_P (*cmp1
))
3134 plus_one
= trunc_int_for_mode (UINTVAL (*cmp1
) + 1, mode
);
3135 if (INTVAL (*cmp1
) < plus_one
)
3138 *cmp1
= force_reg (mode
, GEN_INT (plus_one
));
3144 plus_one
= trunc_int_for_mode (UINTVAL (*cmp1
) + 1, mode
);
3148 *cmp1
= force_reg (mode
, GEN_INT (plus_one
));
3159 /* Compare CMP0 and CMP1 using ordering test CODE and store the result
3160 in TARGET. CMP0 and TARGET are register_operands. If INVERT_PTR
3161 is nonnull, it's OK to set TARGET to the inverse of the result and
3162 flip *INVERT_PTR instead. */
3165 riscv_emit_int_order_test (enum rtx_code code
, bool *invert_ptr
,
3166 rtx target
, rtx cmp0
, rtx cmp1
)
3170 /* First see if there is a RISCV instruction that can do this operation.
3171 If not, try doing the same for the inverse operation. If that also
3172 fails, force CMP1 into a register and try again. */
3173 mode
= GET_MODE (cmp0
);
3174 if (riscv_canonicalize_int_order_test (&code
, &cmp1
, mode
))
3175 riscv_emit_binary (code
, target
, cmp0
, cmp1
);
3178 enum rtx_code inv_code
= reverse_condition (code
);
3179 if (!riscv_canonicalize_int_order_test (&inv_code
, &cmp1
, mode
))
3181 cmp1
= force_reg (mode
, cmp1
);
3182 riscv_emit_int_order_test (code
, invert_ptr
, target
, cmp0
, cmp1
);
3184 else if (invert_ptr
== 0)
3186 rtx inv_target
= riscv_force_binary (word_mode
,
3187 inv_code
, cmp0
, cmp1
);
3188 riscv_emit_binary (EQ
, target
, inv_target
, const0_rtx
);
3192 *invert_ptr
= !*invert_ptr
;
3193 riscv_emit_binary (inv_code
, target
, cmp0
, cmp1
);
3198 /* Return a register that is zero iff CMP0 and CMP1 are equal.
3199 The register will have the same mode as CMP0. */
3202 riscv_zero_if_equal (rtx cmp0
, rtx cmp1
)
3204 if (cmp1
== const0_rtx
)
3207 return expand_binop (GET_MODE (cmp0
), sub_optab
,
3208 cmp0
, cmp1
, 0, 0, OPTAB_DIRECT
);
3211 /* Sign- or zero-extend OP0 and OP1 for integer comparisons. */
3214 riscv_extend_comparands (rtx_code code
, rtx
*op0
, rtx
*op1
)
3216 /* Comparisons consider all XLEN bits, so extend sub-XLEN values. */
3217 if (GET_MODE_SIZE (word_mode
) > GET_MODE_SIZE (GET_MODE (*op0
)).to_constant ())
3219 /* It is more profitable to zero-extend QImode values. But not if the
3220 first operand has already been sign-extended, and the second one is
3221 is a constant or has already been sign-extended also. */
3222 if (unsigned_condition (code
) == code
3223 && (GET_MODE (*op0
) == QImode
3224 && ! (GET_CODE (*op0
) == SUBREG
3225 && SUBREG_PROMOTED_VAR_P (*op0
)
3226 && SUBREG_PROMOTED_SIGNED_P (*op0
)
3227 && (CONST_INT_P (*op1
)
3228 || (GET_CODE (*op1
) == SUBREG
3229 && SUBREG_PROMOTED_VAR_P (*op1
)
3230 && SUBREG_PROMOTED_SIGNED_P (*op1
))))))
3232 *op0
= gen_rtx_ZERO_EXTEND (word_mode
, *op0
);
3233 if (CONST_INT_P (*op1
))
3234 *op1
= GEN_INT ((uint8_t) INTVAL (*op1
));
3236 *op1
= gen_rtx_ZERO_EXTEND (word_mode
, *op1
);
3240 *op0
= gen_rtx_SIGN_EXTEND (word_mode
, *op0
);
3241 if (*op1
!= const0_rtx
)
3242 *op1
= gen_rtx_SIGN_EXTEND (word_mode
, *op1
);
3247 /* Convert a comparison into something that can be used in a branch or
3248 conditional move. On entry, *OP0 and *OP1 are the values being
3249 compared and *CODE is the code used to compare them.
3251 Update *CODE, *OP0 and *OP1 so that they describe the final comparison.
3252 If NEED_EQ_NE_P, then only EQ or NE comparisons against zero are
3256 riscv_emit_int_compare (enum rtx_code
*code
, rtx
*op0
, rtx
*op1
,
3257 bool need_eq_ne_p
= false)
3263 if (*code
== EQ
|| *code
== NE
)
3265 *op0
= riscv_zero_if_equal (cmp_op0
, cmp_op1
);
3271 if (splittable_const_int_operand (*op1
, VOIDmode
))
3273 HOST_WIDE_INT rhs
= INTVAL (*op1
);
3275 if (*code
== EQ
|| *code
== NE
)
3277 /* Convert e.g. OP0 == 2048 into OP0 - 2048 == 0. */
3278 if (SMALL_OPERAND (-rhs
))
3280 *op0
= riscv_force_binary (GET_MODE (*op0
), PLUS
, *op0
,
3287 static const enum rtx_code mag_comparisons
[][2] = {
3288 {LEU
, LTU
}, {GTU
, GEU
}, {LE
, LT
}, {GT
, GE
}
3291 /* Convert e.g. (OP0 <= 0xFFF) into (OP0 < 0x1000). */
3292 for (size_t i
= 0; i
< ARRAY_SIZE (mag_comparisons
); i
++)
3294 HOST_WIDE_INT new_rhs
;
3295 bool increment
= *code
== mag_comparisons
[i
][0];
3296 bool decrement
= *code
== mag_comparisons
[i
][1];
3297 if (!increment
&& !decrement
)
3300 new_rhs
= rhs
+ (increment
? 1 : -1);
3301 new_rhs
= trunc_int_for_mode (new_rhs
, GET_MODE (*op0
));
3302 if (riscv_integer_cost (new_rhs
) < riscv_integer_cost (rhs
)
3303 && (rhs
< 0) == (new_rhs
< 0))
3305 *op1
= GEN_INT (new_rhs
);
3306 *code
= mag_comparisons
[i
][increment
];
3313 riscv_extend_comparands (*code
, op0
, op1
);
3315 *op0
= force_reg (word_mode
, *op0
);
3316 if (*op1
!= const0_rtx
)
3317 *op1
= force_reg (word_mode
, *op1
);
3320 /* Like riscv_emit_int_compare, but for floating-point comparisons. */
3323 riscv_emit_float_compare (enum rtx_code
*code
, rtx
*op0
, rtx
*op1
)
3325 rtx tmp0
, tmp1
, cmp_op0
= *op0
, cmp_op1
= *op1
;
3326 enum rtx_code fp_code
= *code
;
3336 /* a == a && b == b */
3337 tmp0
= riscv_force_binary (word_mode
, EQ
, cmp_op0
, cmp_op0
);
3338 tmp1
= riscv_force_binary (word_mode
, EQ
, cmp_op1
, cmp_op1
);
3339 *op0
= riscv_force_binary (word_mode
, AND
, tmp0
, tmp1
);
3344 /* ordered(a, b) > (a == b) */
3346 tmp0
= riscv_force_binary (word_mode
, EQ
, cmp_op0
, cmp_op0
);
3347 tmp1
= riscv_force_binary (word_mode
, EQ
, cmp_op1
, cmp_op1
);
3348 *op0
= riscv_force_binary (word_mode
, AND
, tmp0
, tmp1
);
3349 *op1
= riscv_force_binary (word_mode
, EQ
, cmp_op0
, cmp_op1
);
3352 #define UNORDERED_COMPARISON(CODE, CMP) \
3355 *op0 = gen_reg_rtx (word_mode); \
3356 if (GET_MODE (cmp_op0) == SFmode && TARGET_64BIT) \
3357 emit_insn (gen_f##CMP##_quietsfdi4 (*op0, cmp_op0, cmp_op1)); \
3358 else if (GET_MODE (cmp_op0) == SFmode) \
3359 emit_insn (gen_f##CMP##_quietsfsi4 (*op0, cmp_op0, cmp_op1)); \
3360 else if (GET_MODE (cmp_op0) == DFmode && TARGET_64BIT) \
3361 emit_insn (gen_f##CMP##_quietdfdi4 (*op0, cmp_op0, cmp_op1)); \
3362 else if (GET_MODE (cmp_op0) == DFmode) \
3363 emit_insn (gen_f##CMP##_quietdfsi4 (*op0, cmp_op0, cmp_op1)); \
3364 else if (GET_MODE (cmp_op0) == HFmode && TARGET_64BIT) \
3365 emit_insn (gen_f##CMP##_quiethfdi4 (*op0, cmp_op0, cmp_op1)); \
3366 else if (GET_MODE (cmp_op0) == HFmode) \
3367 emit_insn (gen_f##CMP##_quiethfsi4 (*op0, cmp_op0, cmp_op1)); \
3369 gcc_unreachable (); \
3370 *op1 = const0_rtx; \
3374 std::swap (cmp_op0
, cmp_op1
);
3377 UNORDERED_COMPARISON(UNGT
, le
)
3380 std::swap (cmp_op0
, cmp_op1
);
3383 UNORDERED_COMPARISON(UNGE
, lt
)
3384 #undef UNORDERED_COMPARISON
3396 /* We have instructions for these cases. */
3397 *op0
= riscv_force_binary (word_mode
, fp_code
, cmp_op0
, cmp_op1
);
3402 /* (a < b) | (a > b) */
3403 tmp0
= riscv_force_binary (word_mode
, LT
, cmp_op0
, cmp_op1
);
3404 tmp1
= riscv_force_binary (word_mode
, GT
, cmp_op0
, cmp_op1
);
3405 *op0
= riscv_force_binary (word_mode
, IOR
, tmp0
, tmp1
);
3414 /* CODE-compare OP0 and OP1. Store the result in TARGET. */
3417 riscv_expand_int_scc (rtx target
, enum rtx_code code
, rtx op0
, rtx op1
)
3419 riscv_extend_comparands (code
, &op0
, &op1
);
3420 op0
= force_reg (word_mode
, op0
);
3422 if (code
== EQ
|| code
== NE
)
3424 rtx zie
= riscv_zero_if_equal (op0
, op1
);
3425 riscv_emit_binary (code
, target
, zie
, const0_rtx
);
3428 riscv_emit_int_order_test (code
, 0, target
, op0
, op1
);
3431 /* Like riscv_expand_int_scc, but for floating-point comparisons. */
3434 riscv_expand_float_scc (rtx target
, enum rtx_code code
, rtx op0
, rtx op1
)
3436 riscv_emit_float_compare (&code
, &op0
, &op1
);
3438 rtx cmp
= riscv_force_binary (word_mode
, code
, op0
, op1
);
3439 riscv_emit_set (target
, lowpart_subreg (SImode
, cmp
, word_mode
));
3442 /* Jump to LABEL if (CODE OP0 OP1) holds. */
3445 riscv_expand_conditional_branch (rtx label
, rtx_code code
, rtx op0
, rtx op1
)
3447 if (FLOAT_MODE_P (GET_MODE (op1
)))
3448 riscv_emit_float_compare (&code
, &op0
, &op1
);
3450 riscv_emit_int_compare (&code
, &op0
, &op1
);
3452 rtx condition
= gen_rtx_fmt_ee (code
, VOIDmode
, op0
, op1
);
3453 emit_jump_insn (gen_condjump (condition
, label
));
3456 /* Emit a cond move: If OP holds, move CONS to DEST; else move ALT to DEST.
3457 Return 0 if expansion failed. */
3460 riscv_expand_conditional_move (rtx dest
, rtx op
, rtx cons
, rtx alt
)
3462 machine_mode mode
= GET_MODE (dest
);
3463 rtx_code code
= GET_CODE (op
);
3464 rtx op0
= XEXP (op
, 0);
3465 rtx op1
= XEXP (op
, 1);
3466 bool need_eq_ne_p
= false;
3468 if (TARGET_XTHEADCONDMOV
3469 && GET_MODE_CLASS (mode
) == MODE_INT
3470 && reg_or_0_operand (cons
, mode
)
3471 && reg_or_0_operand (alt
, mode
)
3472 && (GET_MODE (op
) == mode
|| GET_MODE (op
) == E_VOIDmode
)
3473 && GET_MODE (op0
) == mode
3474 && GET_MODE (op1
) == mode
3475 && (code
== EQ
|| code
== NE
))
3476 need_eq_ne_p
= true;
3479 || (TARGET_SFB_ALU
&& GET_MODE (op0
) == word_mode
))
3481 riscv_emit_int_compare (&code
, &op0
, &op1
, need_eq_ne_p
);
3482 rtx cond
= gen_rtx_fmt_ee (code
, GET_MODE (op0
), op0
, op1
);
3484 /* The expander allows (const_int 0) for CONS for the benefit of
3485 TARGET_XTHEADCONDMOV, but that case isn't supported for
3486 TARGET_SFB_ALU. So force that operand into a register if
3488 cons
= force_reg (GET_MODE (dest
), cons
);
3489 emit_insn (gen_rtx_SET (dest
, gen_rtx_IF_THEN_ELSE (GET_MODE (dest
),
3497 /* Implement TARGET_FUNCTION_ARG_BOUNDARY. Every parameter gets at
3498 least PARM_BOUNDARY bits of alignment, but will be given anything up
3499 to PREFERRED_STACK_BOUNDARY bits if the type requires it. */
3502 riscv_function_arg_boundary (machine_mode mode
, const_tree type
)
3504 unsigned int alignment
;
3506 /* Use natural alignment if the type is not aggregate data. */
3507 if (type
&& !AGGREGATE_TYPE_P (type
))
3508 alignment
= TYPE_ALIGN (TYPE_MAIN_VARIANT (type
));
3510 alignment
= type
? TYPE_ALIGN (type
) : GET_MODE_ALIGNMENT (mode
);
3512 return MIN (PREFERRED_STACK_BOUNDARY
, MAX (PARM_BOUNDARY
, alignment
));
3515 /* If MODE represents an argument that can be passed or returned in
3516 floating-point registers, return the number of registers, else 0. */
3519 riscv_pass_mode_in_fpr_p (machine_mode mode
)
3521 if (GET_MODE_UNIT_SIZE (mode
) <= UNITS_PER_FP_ARG
)
3523 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
)
3526 if (GET_MODE_CLASS (mode
) == MODE_COMPLEX_FLOAT
)
3535 HOST_WIDE_INT offset
;
3536 } riscv_aggregate_field
;
3538 /* Identify subfields of aggregates that are candidates for passing in
3539 floating-point registers. */
3542 riscv_flatten_aggregate_field (const_tree type
,
3543 riscv_aggregate_field fields
[2],
3544 int n
, HOST_WIDE_INT offset
,
3545 bool ignore_zero_width_bit_field_p
)
3547 switch (TREE_CODE (type
))
3550 /* Can't handle incomplete types nor sizes that are not fixed. */
3551 if (!COMPLETE_TYPE_P (type
)
3552 || TREE_CODE (TYPE_SIZE (type
)) != INTEGER_CST
3553 || !tree_fits_uhwi_p (TYPE_SIZE (type
)))
3556 for (tree f
= TYPE_FIELDS (type
); f
; f
= DECL_CHAIN (f
))
3557 if (TREE_CODE (f
) == FIELD_DECL
)
3559 if (!TYPE_P (TREE_TYPE (f
)))
3562 /* The C++ front end strips zero-length bit-fields from structs.
3563 So we need to ignore them in the C front end to make C code
3564 compatible with C++ code. */
3565 if (ignore_zero_width_bit_field_p
3566 && DECL_BIT_FIELD (f
)
3567 && (DECL_SIZE (f
) == NULL_TREE
3568 || integer_zerop (DECL_SIZE (f
))))
3572 HOST_WIDE_INT pos
= offset
+ int_byte_position (f
);
3573 n
= riscv_flatten_aggregate_field (TREE_TYPE (f
),
3575 ignore_zero_width_bit_field_p
);
3584 HOST_WIDE_INT n_elts
;
3585 riscv_aggregate_field subfields
[2];
3586 tree index
= TYPE_DOMAIN (type
);
3587 tree elt_size
= TYPE_SIZE_UNIT (TREE_TYPE (type
));
3588 int n_subfields
= riscv_flatten_aggregate_field (TREE_TYPE (type
),
3589 subfields
, 0, offset
,
3590 ignore_zero_width_bit_field_p
);
3592 /* Can't handle incomplete types nor sizes that are not fixed. */
3593 if (n_subfields
<= 0
3594 || !COMPLETE_TYPE_P (type
)
3595 || TREE_CODE (TYPE_SIZE (type
)) != INTEGER_CST
3597 || !TYPE_MAX_VALUE (index
)
3598 || !tree_fits_uhwi_p (TYPE_MAX_VALUE (index
))
3599 || !TYPE_MIN_VALUE (index
)
3600 || !tree_fits_uhwi_p (TYPE_MIN_VALUE (index
))
3601 || !tree_fits_uhwi_p (elt_size
))
3604 n_elts
= 1 + tree_to_uhwi (TYPE_MAX_VALUE (index
))
3605 - tree_to_uhwi (TYPE_MIN_VALUE (index
));
3606 gcc_assert (n_elts
>= 0);
3608 for (HOST_WIDE_INT i
= 0; i
< n_elts
; i
++)
3609 for (int j
= 0; j
< n_subfields
; j
++)
3614 fields
[n
] = subfields
[j
];
3615 fields
[n
++].offset
+= i
* tree_to_uhwi (elt_size
);
3623 /* Complex type need consume 2 field, so n must be 0. */
3627 HOST_WIDE_INT elt_size
= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (type
))).to_constant ();
3629 if (elt_size
<= UNITS_PER_FP_ARG
)
3631 fields
[0].type
= TREE_TYPE (type
);
3632 fields
[0].offset
= offset
;
3633 fields
[1].type
= TREE_TYPE (type
);
3634 fields
[1].offset
= offset
+ elt_size
;
3644 && ((SCALAR_FLOAT_TYPE_P (type
)
3645 && GET_MODE_SIZE (TYPE_MODE (type
)).to_constant () <= UNITS_PER_FP_ARG
)
3646 || (INTEGRAL_TYPE_P (type
)
3647 && GET_MODE_SIZE (TYPE_MODE (type
)).to_constant () <= UNITS_PER_WORD
)))
3649 fields
[n
].type
= type
;
3650 fields
[n
].offset
= offset
;
3658 /* Identify candidate aggregates for passing in floating-point registers.
3659 Candidates have at most two fields after flattening. */
3662 riscv_flatten_aggregate_argument (const_tree type
,
3663 riscv_aggregate_field fields
[2],
3664 bool ignore_zero_width_bit_field_p
)
3666 if (!type
|| TREE_CODE (type
) != RECORD_TYPE
)
3669 return riscv_flatten_aggregate_field (type
, fields
, 0, 0,
3670 ignore_zero_width_bit_field_p
);
3673 /* See whether TYPE is a record whose fields should be returned in one or
3674 two floating-point registers. If so, populate FIELDS accordingly. */
3677 riscv_pass_aggregate_in_fpr_pair_p (const_tree type
,
3678 riscv_aggregate_field fields
[2])
3680 static int warned
= 0;
3682 /* This is the old ABI, which differs for C++ and C. */
3683 int n_old
= riscv_flatten_aggregate_argument (type
, fields
, false);
3684 for (int i
= 0; i
< n_old
; i
++)
3685 if (!SCALAR_FLOAT_TYPE_P (fields
[i
].type
))
3691 /* This is the new ABI, which is the same for C++ and C. */
3692 int n_new
= riscv_flatten_aggregate_argument (type
, fields
, true);
3693 for (int i
= 0; i
< n_new
; i
++)
3694 if (!SCALAR_FLOAT_TYPE_P (fields
[i
].type
))
3700 if ((n_old
!= n_new
) && (warned
== 0))
3702 warning (OPT_Wpsabi
, "ABI for flattened struct with zero-length "
3703 "bit-fields changed in GCC 10");
3707 return n_new
> 0 ? n_new
: 0;
3710 /* See whether TYPE is a record whose fields should be returned in one or
3711 floating-point register and one integer register. If so, populate
3712 FIELDS accordingly. */
3715 riscv_pass_aggregate_in_fpr_and_gpr_p (const_tree type
,
3716 riscv_aggregate_field fields
[2])
3718 static int warned
= 0;
3720 /* This is the old ABI, which differs for C++ and C. */
3721 unsigned num_int_old
= 0, num_float_old
= 0;
3722 int n_old
= riscv_flatten_aggregate_argument (type
, fields
, false);
3723 for (int i
= 0; i
< n_old
; i
++)
3725 num_float_old
+= SCALAR_FLOAT_TYPE_P (fields
[i
].type
);
3726 num_int_old
+= INTEGRAL_TYPE_P (fields
[i
].type
);
3729 /* This is the new ABI, which is the same for C++ and C. */
3730 unsigned num_int_new
= 0, num_float_new
= 0;
3731 int n_new
= riscv_flatten_aggregate_argument (type
, fields
, true);
3732 for (int i
= 0; i
< n_new
; i
++)
3734 num_float_new
+= SCALAR_FLOAT_TYPE_P (fields
[i
].type
);
3735 num_int_new
+= INTEGRAL_TYPE_P (fields
[i
].type
);
3738 if (((num_int_old
== 1 && num_float_old
== 1
3739 && (num_int_old
!= num_int_new
|| num_float_old
!= num_float_new
))
3740 || (num_int_new
== 1 && num_float_new
== 1
3741 && (num_int_old
!= num_int_new
|| num_float_old
!= num_float_new
)))
3744 warning (OPT_Wpsabi
, "ABI for flattened struct with zero-length "
3745 "bit-fields changed in GCC 10");
3749 return num_int_new
== 1 && num_float_new
== 1;
3752 /* Return the representation of an argument passed or returned in an FPR
3753 when the value has mode VALUE_MODE and the type has TYPE_MODE. The
3754 two modes may be different for structures like:
3756 struct __attribute__((packed)) foo { float f; }
3758 where the SFmode value "f" is passed in REGNO but the struct itself
3759 has mode BLKmode. */
3762 riscv_pass_fpr_single (machine_mode type_mode
, unsigned regno
,
3763 machine_mode value_mode
,
3764 HOST_WIDE_INT offset
)
3766 rtx x
= gen_rtx_REG (value_mode
, regno
);
3768 if (type_mode
!= value_mode
)
3770 x
= gen_rtx_EXPR_LIST (VOIDmode
, x
, GEN_INT (offset
));
3771 x
= gen_rtx_PARALLEL (type_mode
, gen_rtvec (1, x
));
3776 /* Pass or return a composite value in the FPR pair REGNO and REGNO + 1.
3777 MODE is the mode of the composite. MODE1 and OFFSET1 are the mode and
3778 byte offset for the first value, likewise MODE2 and OFFSET2 for the
3782 riscv_pass_fpr_pair (machine_mode mode
, unsigned regno1
,
3783 machine_mode mode1
, HOST_WIDE_INT offset1
,
3784 unsigned regno2
, machine_mode mode2
,
3785 HOST_WIDE_INT offset2
)
3787 return gen_rtx_PARALLEL
3790 gen_rtx_EXPR_LIST (VOIDmode
,
3791 gen_rtx_REG (mode1
, regno1
),
3793 gen_rtx_EXPR_LIST (VOIDmode
,
3794 gen_rtx_REG (mode2
, regno2
),
3795 GEN_INT (offset2
))));
3798 /* Fill INFO with information about a single argument, and return an
3799 RTL pattern to pass or return the argument. CUM is the cumulative
3800 state for earlier arguments. MODE is the mode of this argument and
3801 TYPE is its type (if known). NAMED is true if this is a named
3802 (fixed) argument rather than a variable one. RETURN_P is true if
3803 returning the argument, or false if passing the argument. */
3806 riscv_get_arg_info (struct riscv_arg_info
*info
, const CUMULATIVE_ARGS
*cum
,
3807 machine_mode mode
, const_tree type
, bool named
,
3810 unsigned num_bytes
, num_words
;
3811 unsigned fpr_base
= return_p
? FP_RETURN
: FP_ARG_FIRST
;
3812 unsigned gpr_base
= return_p
? GP_RETURN
: GP_ARG_FIRST
;
3813 unsigned alignment
= riscv_function_arg_boundary (mode
, type
);
3815 memset (info
, 0, sizeof (*info
));
3816 info
->gpr_offset
= cum
->num_gprs
;
3817 info
->fpr_offset
= cum
->num_fprs
;
3819 /* TODO: Currently, it will cause an ICE for --param
3820 riscv-autovec-preference=fixed-vlmax. So, we just return NULL_RTX here
3821 let GCC generate loads/stores. Ideally, we should either warn the user not
3822 to use an RVV vector type as function argument or support the calling
3823 convention directly. */
3824 if (riscv_v_ext_mode_p (mode
))
3828 riscv_aggregate_field fields
[2];
3829 unsigned fregno
= fpr_base
+ info
->fpr_offset
;
3830 unsigned gregno
= gpr_base
+ info
->gpr_offset
;
3832 /* Pass one- or two-element floating-point aggregates in FPRs. */
3833 if ((info
->num_fprs
= riscv_pass_aggregate_in_fpr_pair_p (type
, fields
))
3834 && info
->fpr_offset
+ info
->num_fprs
<= MAX_ARGS_IN_REGISTERS
)
3835 switch (info
->num_fprs
)
3838 return riscv_pass_fpr_single (mode
, fregno
,
3839 TYPE_MODE (fields
[0].type
),
3843 return riscv_pass_fpr_pair (mode
, fregno
,
3844 TYPE_MODE (fields
[0].type
),
3847 TYPE_MODE (fields
[1].type
),
3854 /* Pass real and complex floating-point numbers in FPRs. */
3855 if ((info
->num_fprs
= riscv_pass_mode_in_fpr_p (mode
))
3856 && info
->fpr_offset
+ info
->num_fprs
<= MAX_ARGS_IN_REGISTERS
)
3857 switch (GET_MODE_CLASS (mode
))
3860 return gen_rtx_REG (mode
, fregno
);
3862 case MODE_COMPLEX_FLOAT
:
3863 return riscv_pass_fpr_pair (mode
, fregno
, GET_MODE_INNER (mode
), 0,
3864 fregno
+ 1, GET_MODE_INNER (mode
),
3865 GET_MODE_UNIT_SIZE (mode
));
3871 /* Pass structs with one float and one integer in an FPR and a GPR. */
3872 if (riscv_pass_aggregate_in_fpr_and_gpr_p (type
, fields
)
3873 && info
->gpr_offset
< MAX_ARGS_IN_REGISTERS
3874 && info
->fpr_offset
< MAX_ARGS_IN_REGISTERS
)
3879 if (!SCALAR_FLOAT_TYPE_P (fields
[0].type
))
3880 std::swap (fregno
, gregno
);
3882 return riscv_pass_fpr_pair (mode
, fregno
, TYPE_MODE (fields
[0].type
),
3884 gregno
, TYPE_MODE (fields
[1].type
),
3889 /* Work out the size of the argument. */
3890 num_bytes
= type
? int_size_in_bytes (type
) : GET_MODE_SIZE (mode
).to_constant ();
3891 num_words
= (num_bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
3893 /* Doubleword-aligned varargs start on an even register boundary. */
3894 if (!named
&& num_bytes
!= 0 && alignment
> BITS_PER_WORD
)
3895 info
->gpr_offset
+= info
->gpr_offset
& 1;
3897 /* Partition the argument between registers and stack. */
3899 info
->num_gprs
= MIN (num_words
, MAX_ARGS_IN_REGISTERS
- info
->gpr_offset
);
3900 info
->stack_p
= (num_words
- info
->num_gprs
) != 0;
3902 if (info
->num_gprs
|| return_p
)
3903 return gen_rtx_REG (mode
, gpr_base
+ info
->gpr_offset
);
3908 /* Implement TARGET_FUNCTION_ARG. */
3911 riscv_function_arg (cumulative_args_t cum_v
, const function_arg_info
&arg
)
3913 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
3914 struct riscv_arg_info info
;
3916 if (arg
.end_marker_p ())
3919 return riscv_get_arg_info (&info
, cum
, arg
.mode
, arg
.type
, arg
.named
, false);
3922 /* Implement TARGET_FUNCTION_ARG_ADVANCE. */
3925 riscv_function_arg_advance (cumulative_args_t cum_v
,
3926 const function_arg_info
&arg
)
3928 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
3929 struct riscv_arg_info info
;
3931 riscv_get_arg_info (&info
, cum
, arg
.mode
, arg
.type
, arg
.named
, false);
3933 /* Advance the register count. This has the effect of setting
3934 num_gprs to MAX_ARGS_IN_REGISTERS if a doubleword-aligned
3935 argument required us to skip the final GPR and pass the whole
3936 argument on the stack. */
3937 cum
->num_fprs
= info
.fpr_offset
+ info
.num_fprs
;
3938 cum
->num_gprs
= info
.gpr_offset
+ info
.num_gprs
;
3941 /* Implement TARGET_ARG_PARTIAL_BYTES. */
3944 riscv_arg_partial_bytes (cumulative_args_t cum
,
3945 const function_arg_info
&generic_arg
)
3947 struct riscv_arg_info arg
;
3949 riscv_get_arg_info (&arg
, get_cumulative_args (cum
), generic_arg
.mode
,
3950 generic_arg
.type
, generic_arg
.named
, false);
3951 return arg
.stack_p
? arg
.num_gprs
* UNITS_PER_WORD
: 0;
3954 /* Implement FUNCTION_VALUE and LIBCALL_VALUE. For normal calls,
3955 VALTYPE is the return type and MODE is VOIDmode. For libcalls,
3956 VALTYPE is null and MODE is the mode of the return value. */
3959 riscv_function_value (const_tree type
, const_tree func
, machine_mode mode
)
3961 struct riscv_arg_info info
;
3962 CUMULATIVE_ARGS args
;
3966 int unsigned_p
= TYPE_UNSIGNED (type
);
3968 mode
= TYPE_MODE (type
);
3970 /* Since TARGET_PROMOTE_FUNCTION_MODE unconditionally promotes,
3971 return values, promote the mode here too. */
3972 mode
= promote_function_mode (type
, mode
, &unsigned_p
, func
, 1);
3975 memset (&args
, 0, sizeof args
);
3976 return riscv_get_arg_info (&info
, &args
, mode
, type
, true, true);
3979 /* Implement TARGET_PASS_BY_REFERENCE. */
3982 riscv_pass_by_reference (cumulative_args_t cum_v
, const function_arg_info
&arg
)
3984 HOST_WIDE_INT size
= arg
.type_size_in_bytes ().to_constant ();;
3985 struct riscv_arg_info info
;
3986 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
3988 /* ??? std_gimplify_va_arg_expr passes NULL for cum. Fortunately, we
3989 never pass variadic arguments in floating-point registers, so we can
3990 avoid the call to riscv_get_arg_info in this case. */
3993 /* Don't pass by reference if we can use a floating-point register. */
3994 riscv_get_arg_info (&info
, cum
, arg
.mode
, arg
.type
, arg
.named
, false);
3999 /* Pass by reference if the data do not fit in two integer registers. */
4000 return !IN_RANGE (size
, 0, 2 * UNITS_PER_WORD
);
4003 /* Implement TARGET_RETURN_IN_MEMORY. */
4006 riscv_return_in_memory (const_tree type
, const_tree fndecl ATTRIBUTE_UNUSED
)
4008 CUMULATIVE_ARGS args
;
4009 cumulative_args_t cum
= pack_cumulative_args (&args
);
4011 /* The rules for returning in memory are the same as for passing the
4012 first named argument by reference. */
4013 memset (&args
, 0, sizeof args
);
4014 function_arg_info
arg (const_cast<tree
> (type
), /*named=*/true);
4015 return riscv_pass_by_reference (cum
, arg
);
4018 /* Implement TARGET_SETUP_INCOMING_VARARGS. */
4021 riscv_setup_incoming_varargs (cumulative_args_t cum
,
4022 const function_arg_info
&arg
,
4023 int *pretend_size ATTRIBUTE_UNUSED
, int no_rtl
)
4025 CUMULATIVE_ARGS local_cum
;
4028 /* The caller has advanced CUM up to, but not beyond, the last named
4029 argument. Advance a local copy of CUM past the last "real" named
4030 argument, to find out how many registers are left over. */
4031 local_cum
= *get_cumulative_args (cum
);
4032 if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl
)))
4033 riscv_function_arg_advance (pack_cumulative_args (&local_cum
), arg
);
4035 /* Found out how many registers we need to save. */
4036 gp_saved
= MAX_ARGS_IN_REGISTERS
- local_cum
.num_gprs
;
4038 if (!no_rtl
&& gp_saved
> 0)
4040 rtx ptr
= plus_constant (Pmode
, virtual_incoming_args_rtx
,
4041 REG_PARM_STACK_SPACE (cfun
->decl
)
4042 - gp_saved
* UNITS_PER_WORD
);
4043 rtx mem
= gen_frame_mem (BLKmode
, ptr
);
4044 set_mem_alias_set (mem
, get_varargs_alias_set ());
4046 move_block_from_reg (local_cum
.num_gprs
+ GP_ARG_FIRST
,
4049 if (REG_PARM_STACK_SPACE (cfun
->decl
) == 0)
4050 cfun
->machine
->varargs_size
= gp_saved
* UNITS_PER_WORD
;
4053 /* Handle an attribute requiring a FUNCTION_DECL;
4054 arguments as in struct attribute_spec.handler. */
4056 riscv_handle_fndecl_attribute (tree
*node
, tree name
,
4057 tree args ATTRIBUTE_UNUSED
,
4058 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
4060 if (TREE_CODE (*node
) != FUNCTION_DECL
)
4062 warning (OPT_Wattributes
, "%qE attribute only applies to functions",
4064 *no_add_attrs
= true;
4070 /* Verify type based attributes. NODE is the what the attribute is being
4071 applied to. NAME is the attribute name. ARGS are the attribute args.
4072 FLAGS gives info about the context. NO_ADD_ATTRS should be set to true if
4073 the attribute should be ignored. */
4076 riscv_handle_type_attribute (tree
*node ATTRIBUTE_UNUSED
, tree name
, tree args
,
4077 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
4079 /* Check for an argument. */
4080 if (is_attribute_p ("interrupt", name
))
4084 tree cst
= TREE_VALUE (args
);
4087 if (TREE_CODE (cst
) != STRING_CST
)
4089 warning (OPT_Wattributes
,
4090 "%qE attribute requires a string argument",
4092 *no_add_attrs
= true;
4096 string
= TREE_STRING_POINTER (cst
);
4097 if (strcmp (string
, "user") && strcmp (string
, "supervisor")
4098 && strcmp (string
, "machine"))
4100 warning (OPT_Wattributes
,
4101 "argument to %qE attribute is not %<\"user\"%>, %<\"supervisor\"%>, "
4102 "or %<\"machine\"%>", name
);
4103 *no_add_attrs
= true;
4111 /* Return true if function TYPE is an interrupt function. */
4113 riscv_interrupt_type_p (tree type
)
4115 return lookup_attribute ("interrupt", TYPE_ATTRIBUTES (type
)) != NULL
;
4118 /* Return true if FUNC is a naked function. */
4120 riscv_naked_function_p (tree func
)
4122 tree func_decl
= func
;
4123 if (func
== NULL_TREE
)
4124 func_decl
= current_function_decl
;
4125 return NULL_TREE
!= lookup_attribute ("naked", DECL_ATTRIBUTES (func_decl
));
4128 /* Implement TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS. */
4130 riscv_allocate_stack_slots_for_args ()
4132 /* Naked functions should not allocate stack slots for arguments. */
4133 return !riscv_naked_function_p (current_function_decl
);
4136 /* Implement TARGET_WARN_FUNC_RETURN. */
4138 riscv_warn_func_return (tree decl
)
4140 /* Naked functions are implemented entirely in assembly, including the
4141 return sequence, so suppress warnings about this. */
4142 return !riscv_naked_function_p (decl
);
4145 /* Implement TARGET_EXPAND_BUILTIN_VA_START. */
4148 riscv_va_start (tree valist
, rtx nextarg
)
4150 nextarg
= plus_constant (Pmode
, nextarg
, -cfun
->machine
->varargs_size
);
4151 std_expand_builtin_va_start (valist
, nextarg
);
4154 /* Make ADDR suitable for use as a call or sibcall target. */
4157 riscv_legitimize_call_address (rtx addr
)
4159 if (!call_insn_operand (addr
, VOIDmode
))
4161 rtx reg
= RISCV_CALL_ADDRESS_TEMP (Pmode
);
4162 riscv_emit_move (reg
, addr
);
4168 /* Emit straight-line code to move LENGTH bytes from SRC to DEST.
4169 Assume that the areas do not overlap. */
4172 riscv_block_move_straight (rtx dest
, rtx src
, unsigned HOST_WIDE_INT length
)
4174 unsigned HOST_WIDE_INT offset
, delta
;
4175 unsigned HOST_WIDE_INT bits
;
4177 enum machine_mode mode
;
4180 bits
= MAX (BITS_PER_UNIT
,
4181 MIN (BITS_PER_WORD
, MIN (MEM_ALIGN (src
), MEM_ALIGN (dest
))));
4183 mode
= mode_for_size (bits
, MODE_INT
, 0).require ();
4184 delta
= bits
/ BITS_PER_UNIT
;
4186 /* Allocate a buffer for the temporary registers. */
4187 regs
= XALLOCAVEC (rtx
, length
/ delta
);
4189 /* Load as many BITS-sized chunks as possible. Use a normal load if
4190 the source has enough alignment, otherwise use left/right pairs. */
4191 for (offset
= 0, i
= 0; offset
+ delta
<= length
; offset
+= delta
, i
++)
4193 regs
[i
] = gen_reg_rtx (mode
);
4194 riscv_emit_move (regs
[i
], adjust_address (src
, mode
, offset
));
4197 /* Copy the chunks to the destination. */
4198 for (offset
= 0, i
= 0; offset
+ delta
<= length
; offset
+= delta
, i
++)
4199 riscv_emit_move (adjust_address (dest
, mode
, offset
), regs
[i
]);
4201 /* Mop up any left-over bytes. */
4202 if (offset
< length
)
4204 src
= adjust_address (src
, BLKmode
, offset
);
4205 dest
= adjust_address (dest
, BLKmode
, offset
);
4206 move_by_pieces (dest
, src
, length
- offset
,
4207 MIN (MEM_ALIGN (src
), MEM_ALIGN (dest
)), RETURN_BEGIN
);
4211 /* Helper function for doing a loop-based block operation on memory
4212 reference MEM. Each iteration of the loop will operate on LENGTH
4215 Create a new base register for use within the loop and point it to
4216 the start of MEM. Create a new memory reference that uses this
4217 register. Store them in *LOOP_REG and *LOOP_MEM respectively. */
4220 riscv_adjust_block_mem (rtx mem
, unsigned HOST_WIDE_INT length
,
4221 rtx
*loop_reg
, rtx
*loop_mem
)
4223 *loop_reg
= copy_addr_to_reg (XEXP (mem
, 0));
4225 /* Although the new mem does not refer to a known location,
4226 it does keep up to LENGTH bytes of alignment. */
4227 *loop_mem
= change_address (mem
, BLKmode
, *loop_reg
);
4228 set_mem_align (*loop_mem
, MIN (MEM_ALIGN (mem
), length
* BITS_PER_UNIT
));
4231 /* Move LENGTH bytes from SRC to DEST using a loop that moves BYTES_PER_ITER
4232 bytes at a time. LENGTH must be at least BYTES_PER_ITER. Assume that
4233 the memory regions do not overlap. */
4236 riscv_block_move_loop (rtx dest
, rtx src
, unsigned HOST_WIDE_INT length
,
4237 unsigned HOST_WIDE_INT bytes_per_iter
)
4239 rtx label
, src_reg
, dest_reg
, final_src
, test
;
4240 unsigned HOST_WIDE_INT leftover
;
4242 leftover
= length
% bytes_per_iter
;
4245 /* Create registers and memory references for use within the loop. */
4246 riscv_adjust_block_mem (src
, bytes_per_iter
, &src_reg
, &src
);
4247 riscv_adjust_block_mem (dest
, bytes_per_iter
, &dest_reg
, &dest
);
4249 /* Calculate the value that SRC_REG should have after the last iteration
4251 final_src
= expand_simple_binop (Pmode
, PLUS
, src_reg
, GEN_INT (length
),
4254 /* Emit the start of the loop. */
4255 label
= gen_label_rtx ();
4258 /* Emit the loop body. */
4259 riscv_block_move_straight (dest
, src
, bytes_per_iter
);
4261 /* Move on to the next block. */
4262 riscv_emit_move (src_reg
, plus_constant (Pmode
, src_reg
, bytes_per_iter
));
4263 riscv_emit_move (dest_reg
, plus_constant (Pmode
, dest_reg
, bytes_per_iter
));
4265 /* Emit the loop condition. */
4266 test
= gen_rtx_NE (VOIDmode
, src_reg
, final_src
);
4267 emit_jump_insn (gen_cbranch4 (Pmode
, test
, src_reg
, final_src
, label
));
4269 /* Mop up any left-over bytes. */
4271 riscv_block_move_straight (dest
, src
, leftover
);
4273 emit_insn(gen_nop ());
4276 /* Expand a cpymemsi instruction, which copies LENGTH bytes from
4277 memory reference SRC to memory reference DEST. */
4280 riscv_expand_block_move (rtx dest
, rtx src
, rtx length
)
4282 if (CONST_INT_P (length
))
4284 unsigned HOST_WIDE_INT hwi_length
= UINTVAL (length
);
4285 unsigned HOST_WIDE_INT factor
, align
;
4287 align
= MIN (MIN (MEM_ALIGN (src
), MEM_ALIGN (dest
)), BITS_PER_WORD
);
4288 factor
= BITS_PER_WORD
/ align
;
4290 if (optimize_function_for_size_p (cfun
)
4291 && hwi_length
* factor
* UNITS_PER_WORD
> MOVE_RATIO (false))
4294 if (hwi_length
<= (RISCV_MAX_MOVE_BYTES_STRAIGHT
/ factor
))
4296 riscv_block_move_straight (dest
, src
, INTVAL (length
));
4299 else if (optimize
&& align
>= BITS_PER_WORD
)
4301 unsigned min_iter_words
4302 = RISCV_MAX_MOVE_BYTES_PER_LOOP_ITER
/ UNITS_PER_WORD
;
4303 unsigned iter_words
= min_iter_words
;
4304 unsigned HOST_WIDE_INT bytes
= hwi_length
;
4305 unsigned HOST_WIDE_INT words
= bytes
/ UNITS_PER_WORD
;
4307 /* Lengthen the loop body if it shortens the tail. */
4308 for (unsigned i
= min_iter_words
; i
< min_iter_words
* 2 - 1; i
++)
4310 unsigned cur_cost
= iter_words
+ words
% iter_words
;
4311 unsigned new_cost
= i
+ words
% i
;
4312 if (new_cost
<= cur_cost
)
4316 riscv_block_move_loop (dest
, src
, bytes
, iter_words
* UNITS_PER_WORD
);
4323 /* Print symbolic operand OP, which is part of a HIGH or LO_SUM
4324 in context CONTEXT. HI_RELOC indicates a high-part reloc. */
4327 riscv_print_operand_reloc (FILE *file
, rtx op
, bool hi_reloc
)
4331 switch (riscv_classify_symbolic_expression (op
))
4333 case SYMBOL_ABSOLUTE
:
4334 reloc
= hi_reloc
? "%hi" : "%lo";
4338 reloc
= hi_reloc
? "%pcrel_hi" : "%pcrel_lo";
4342 reloc
= hi_reloc
? "%tprel_hi" : "%tprel_lo";
4346 output_operand_lossage ("invalid use of '%%%c'", hi_reloc
? 'h' : 'R');
4350 fprintf (file
, "%s(", reloc
);
4351 output_addr_const (file
, riscv_strip_unspec_address (op
));
4355 /* Return the memory model that encapuslates both given models. */
4358 riscv_union_memmodels (enum memmodel model1
, enum memmodel model2
)
4360 model1
= memmodel_base (model1
);
4361 model2
= memmodel_base (model2
);
4363 enum memmodel weaker
= model1
<= model2
? model1
: model2
;
4364 enum memmodel stronger
= model1
> model2
? model1
: model2
;
4368 case MEMMODEL_SEQ_CST
:
4369 case MEMMODEL_ACQ_REL
:
4371 case MEMMODEL_RELEASE
:
4372 if (weaker
== MEMMODEL_ACQUIRE
|| weaker
== MEMMODEL_CONSUME
)
4373 return MEMMODEL_ACQ_REL
;
4376 case MEMMODEL_ACQUIRE
:
4377 case MEMMODEL_CONSUME
:
4378 case MEMMODEL_RELAXED
:
4385 /* Return true if the .AQ suffix should be added to an AMO to implement the
4386 acquire portion of memory model MODEL. */
4389 riscv_memmodel_needs_amo_acquire (enum memmodel model
)
4393 case MEMMODEL_ACQ_REL
:
4394 case MEMMODEL_SEQ_CST
:
4395 case MEMMODEL_ACQUIRE
:
4396 case MEMMODEL_CONSUME
:
4399 case MEMMODEL_RELEASE
:
4400 case MEMMODEL_RELAXED
:
4408 /* Return true if the .RL suffix should be added to an AMO to implement the
4409 release portion of memory model MODEL. */
4412 riscv_memmodel_needs_amo_release (enum memmodel model
)
4416 case MEMMODEL_ACQ_REL
:
4417 case MEMMODEL_SEQ_CST
:
4418 case MEMMODEL_RELEASE
:
4421 case MEMMODEL_ACQUIRE
:
4422 case MEMMODEL_CONSUME
:
4423 case MEMMODEL_RELAXED
:
4431 /* Implement TARGET_PRINT_OPERAND. The RISCV-specific operand codes are:
4433 'h' Print the high-part relocation associated with OP, after stripping
4435 'R' Print the low-part relocation associated with OP.
4436 'C' Print the integer branch condition for comparison OP.
4437 'A' Print the atomic operation suffix for memory model OP.
4438 'I' Print the LR suffix for memory model OP.
4439 'J' Print the SC suffix for memory model OP.
4440 'z' Print x0 if OP is zero, otherwise print OP normally.
4441 'i' Print i if the operand is not a register.
4442 'S' Print shift-index of single-bit mask OP.
4443 'T' Print shift-index of inverted single-bit mask OP.
4444 '~' Print w if TARGET_64BIT is true; otherwise not print anything.
4446 Note please keep this list and the list in riscv.md in sync. */
4449 riscv_print_operand (FILE *file
, rtx op
, int letter
)
4451 /* `~` does not take an operand so op will be null
4452 Check for before accessing op.
4460 machine_mode mode
= GET_MODE (op
);
4461 enum rtx_code code
= GET_CODE (op
);
4466 /* Print 'OP' variant for RVV instructions.
4467 1. If the operand is VECTOR REG, we print 'v'(vnsrl.wv).
4468 2. If the operand is CONST_INT/CONST_VECTOR, we print 'i'(vnsrl.wi).
4469 3. If the operand is SCALAR REG, we print 'x'(vnsrl.wx). */
4470 if (riscv_v_ext_vector_mode_p (mode
))
4473 asm_fprintf (file
, "v");
4474 else if (CONST_VECTOR_P (op
))
4475 asm_fprintf (file
, "i");
4477 output_operand_lossage ("invalid vector operand");
4481 if (CONST_INT_P (op
))
4482 asm_fprintf (file
, "i");
4484 asm_fprintf (file
, "x");
4492 asm_fprintf (file
, "%s", reg_names
[REGNO (op
)]);
4495 if (!const_vec_duplicate_p (op
, &elt
))
4496 output_operand_lossage ("invalid vector constant");
4497 else if (satisfies_constraint_Wc0 (op
))
4498 asm_fprintf (file
, "0");
4499 else if (satisfies_constraint_vi (op
)
4500 || satisfies_constraint_vj (op
))
4501 asm_fprintf (file
, "%wd", INTVAL (elt
));
4503 output_operand_lossage ("invalid vector constant");
4509 if (!const_vec_duplicate_p (op
, &elt
))
4510 output_operand_lossage ("invalid vector constant");
4511 else if (satisfies_constraint_vj (op
))
4512 asm_fprintf (file
, "%wd", -INTVAL (elt
));
4514 output_operand_lossage ("invalid vector constant");
4518 if (riscv_v_ext_vector_mode_p (mode
))
4520 /* Calculate lmul according to mode and print the value. */
4521 poly_int64 size
= GET_MODE_SIZE (mode
);
4523 if (known_lt (size
, BYTES_PER_RISCV_VECTOR
))
4526 lmul
= exact_div (size
, BYTES_PER_RISCV_VECTOR
).to_constant ();
4527 asm_fprintf (file
, "%d", lmul
);
4529 else if (code
== CONST_INT
)
4531 /* If it is a const_int value, it denotes the VLMUL field enum. */
4532 unsigned int vlmul
= UINTVAL (op
);
4535 case riscv_vector::LMUL_1
:
4536 asm_fprintf (file
, "%s", "m1");
4538 case riscv_vector::LMUL_2
:
4539 asm_fprintf (file
, "%s", "m2");
4541 case riscv_vector::LMUL_4
:
4542 asm_fprintf (file
, "%s", "m4");
4544 case riscv_vector::LMUL_8
:
4545 asm_fprintf (file
, "%s", "m8");
4547 case riscv_vector::LMUL_F8
:
4548 asm_fprintf (file
, "%s", "mf8");
4550 case riscv_vector::LMUL_F4
:
4551 asm_fprintf (file
, "%s", "mf4");
4553 case riscv_vector::LMUL_F2
:
4554 asm_fprintf (file
, "%s", "mf2");
4561 output_operand_lossage ("invalid vector constant");
4565 if (GET_MODE_CLASS (mode
) == MODE_VECTOR_BOOL
)
4567 /* Print for RVV mask operand.
4568 If op is reg, print ",v0.t".
4569 Otherwise, don't print anything. */
4571 fprintf (file
, ",%s.t", reg_names
[REGNO (op
)]);
4573 else if (code
== CONST_INT
)
4575 /* Tail && Mask policy. */
4576 bool agnostic_p
= UINTVAL (op
) & 0x1;
4577 asm_fprintf (file
, "%s", agnostic_p
? "a" : "u");
4580 output_operand_lossage ("invalid vector constant");
4586 riscv_print_operand_reloc (file
, op
, true);
4590 riscv_print_operand_reloc (file
, op
, false);
4594 /* The RTL names match the instruction names. */
4595 fputs (GET_RTX_NAME (code
), file
);
4599 const enum memmodel model
= memmodel_base (INTVAL (op
));
4600 if (riscv_memmodel_needs_amo_acquire (model
)
4601 && riscv_memmodel_needs_amo_release (model
))
4602 fputs (".aqrl", file
);
4603 else if (riscv_memmodel_needs_amo_acquire (model
))
4604 fputs (".aq", file
);
4605 else if (riscv_memmodel_needs_amo_release (model
))
4606 fputs (".rl", file
);
4611 const enum memmodel model
= memmodel_base (INTVAL (op
));
4612 if (model
== MEMMODEL_SEQ_CST
)
4613 fputs (".aqrl", file
);
4614 else if (riscv_memmodel_needs_amo_acquire (model
))
4615 fputs (".aq", file
);
4620 const enum memmodel model
= memmodel_base (INTVAL (op
));
4621 if (riscv_memmodel_needs_amo_release (model
))
4622 fputs (".rl", file
);
4632 fputs (GET_RTX_NAME (code
), file
);
4637 rtx newop
= GEN_INT (ctz_hwi (INTVAL (op
)));
4638 output_addr_const (file
, newop
);
4643 rtx newop
= GEN_INT (ctz_hwi (~INTVAL (op
)));
4644 output_addr_const (file
, newop
);
4651 if (letter
&& letter
!= 'z')
4652 output_operand_lossage ("invalid use of '%%%c'", letter
);
4653 fprintf (file
, "%s", reg_names
[REGNO (op
)]);
4657 if (letter
&& letter
!= 'z')
4658 output_operand_lossage ("invalid use of '%%%c'", letter
);
4660 output_address (mode
, XEXP (op
, 0));
4664 if (letter
== 'z' && op
== CONST0_RTX (GET_MODE (op
)))
4665 fputs (reg_names
[GP_REG_FIRST
], file
);
4666 else if (letter
&& letter
!= 'z')
4667 output_operand_lossage ("invalid use of '%%%c'", letter
);
4669 output_addr_const (file
, riscv_strip_unspec_address (op
));
4675 /* Implement TARGET_PRINT_OPERAND_PUNCT_VALID_P */
4677 riscv_print_operand_punct_valid_p (unsigned char code
)
4679 return (code
== '~');
4682 /* Implement TARGET_PRINT_OPERAND_ADDRESS. */
4685 riscv_print_operand_address (FILE *file
, machine_mode mode ATTRIBUTE_UNUSED
, rtx x
)
4687 struct riscv_address_info addr
;
4689 if (riscv_classify_address (&addr
, x
, word_mode
, true))
4693 riscv_print_operand (file
, addr
.offset
, 0);
4694 fprintf (file
, "(%s)", reg_names
[REGNO (addr
.reg
)]);
4697 case ADDRESS_LO_SUM
:
4698 riscv_print_operand_reloc (file
, addr
.offset
, false);
4699 fprintf (file
, "(%s)", reg_names
[REGNO (addr
.reg
)]);
4702 case ADDRESS_CONST_INT
:
4703 output_addr_const (file
, x
);
4704 fprintf (file
, "(%s)", reg_names
[GP_REG_FIRST
]);
4707 case ADDRESS_SYMBOLIC
:
4708 output_addr_const (file
, riscv_strip_unspec_address (x
));
4715 riscv_size_ok_for_small_data_p (int size
)
4717 return g_switch_value
&& IN_RANGE (size
, 1, g_switch_value
);
4720 /* Return true if EXP should be placed in the small data section. */
4723 riscv_in_small_data_p (const_tree x
)
4725 if (TREE_CODE (x
) == STRING_CST
|| TREE_CODE (x
) == FUNCTION_DECL
)
4728 if (VAR_P (x
) && DECL_SECTION_NAME (x
))
4730 const char *sec
= DECL_SECTION_NAME (x
);
4731 return strcmp (sec
, ".sdata") == 0 || strcmp (sec
, ".sbss") == 0;
4734 return riscv_size_ok_for_small_data_p (int_size_in_bytes (TREE_TYPE (x
)));
4737 /* Switch to the appropriate section for output of DECL. */
4740 riscv_select_section (tree decl
, int reloc
,
4741 unsigned HOST_WIDE_INT align
)
4743 switch (categorize_decl_for_section (decl
, reloc
))
4745 case SECCAT_SRODATA
:
4746 return get_named_section (decl
, ".srodata", reloc
);
4749 return default_elf_select_section (decl
, reloc
, align
);
4753 /* Switch to the appropriate section for output of DECL. */
4756 riscv_unique_section (tree decl
, int reloc
)
4758 const char *prefix
= NULL
;
4759 bool one_only
= DECL_ONE_ONLY (decl
) && !HAVE_COMDAT_GROUP
;
4761 switch (categorize_decl_for_section (decl
, reloc
))
4763 case SECCAT_SRODATA
:
4764 prefix
= one_only
? ".sr" : ".srodata";
4772 const char *name
, *linkonce
;
4775 name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
));
4776 name
= targetm
.strip_name_encoding (name
);
4778 /* If we're using one_only, then there needs to be a .gnu.linkonce
4779 prefix to the section name. */
4780 linkonce
= one_only
? ".gnu.linkonce" : "";
4782 string
= ACONCAT ((linkonce
, prefix
, ".", name
, NULL
));
4784 set_decl_section_name (decl
, string
);
4787 default_unique_section (decl
, reloc
);
4790 /* Return a section for X, handling small data. */
4793 riscv_elf_select_rtx_section (machine_mode mode
, rtx x
,
4794 unsigned HOST_WIDE_INT align
)
4796 section
*s
= default_elf_select_rtx_section (mode
, x
, align
);
4798 if (riscv_size_ok_for_small_data_p (GET_MODE_SIZE (mode
).to_constant ()))
4800 if (startswith (s
->named
.name
, ".rodata.cst"))
4802 /* Rename .rodata.cst* to .srodata.cst*. */
4803 char *name
= (char *) alloca (strlen (s
->named
.name
) + 2);
4804 sprintf (name
, ".s%s", s
->named
.name
+ 1);
4805 return get_section (name
, s
->named
.common
.flags
, NULL
);
4808 if (s
== data_section
)
4809 return sdata_section
;
4815 /* Make the last instruction frame-related and note that it performs
4816 the operation described by FRAME_PATTERN. */
4819 riscv_set_frame_expr (rtx frame_pattern
)
4823 insn
= get_last_insn ();
4824 RTX_FRAME_RELATED_P (insn
) = 1;
4825 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
4830 /* Return a frame-related rtx that stores REG at MEM.
4831 REG must be a single register. */
4834 riscv_frame_set (rtx mem
, rtx reg
)
4836 rtx set
= gen_rtx_SET (mem
, reg
);
4837 RTX_FRAME_RELATED_P (set
) = 1;
4841 /* Return true if the current function must save register REGNO. */
4844 riscv_save_reg_p (unsigned int regno
)
4846 bool call_saved
= !global_regs
[regno
] && !call_used_or_fixed_reg_p (regno
);
4847 bool might_clobber
= crtl
->saves_all_registers
4848 || df_regs_ever_live_p (regno
);
4850 if (call_saved
&& might_clobber
)
4853 if (regno
== HARD_FRAME_POINTER_REGNUM
&& frame_pointer_needed
)
4856 if (regno
== RETURN_ADDR_REGNUM
&& crtl
->calls_eh_return
)
4859 /* If this is an interrupt handler, then must save extra registers. */
4860 if (cfun
->machine
->interrupt_handler_p
)
4862 /* zero register is always zero. */
4863 if (regno
== GP_REG_FIRST
)
4866 /* The function will return the stack pointer to its original value. */
4867 if (regno
== STACK_POINTER_REGNUM
)
4870 /* By convention, we assume that gp and tp are safe. */
4871 if (regno
== GP_REGNUM
|| regno
== THREAD_POINTER_REGNUM
)
4874 /* We must save every register used in this function. If this is not a
4875 leaf function, then we must save all temporary registers. */
4876 if (df_regs_ever_live_p (regno
)
4877 || (!crtl
->is_leaf
&& call_used_or_fixed_reg_p (regno
)))
4884 /* Return TRUE if a libcall to save/restore GPRs should be
4885 avoided. FALSE otherwise. */
4887 riscv_avoid_save_libcall (void)
4889 if (!TARGET_SAVE_RESTORE
4890 || crtl
->calls_eh_return
4891 || frame_pointer_needed
4892 || cfun
->machine
->interrupt_handler_p
4893 || cfun
->machine
->varargs_size
!= 0
4894 || crtl
->args
.pretend_args_size
!= 0)
4900 /* Determine whether to call GPR save/restore routines. */
4902 riscv_use_save_libcall (const struct riscv_frame_info
*frame
)
4904 if (riscv_avoid_save_libcall ())
4907 return frame
->save_libcall_adjustment
!= 0;
4910 /* Determine which GPR save/restore routine to call. */
4913 riscv_save_libcall_count (unsigned mask
)
4915 for (unsigned n
= GP_REG_LAST
; n
> GP_REG_FIRST
; n
--)
4916 if (BITSET_P (mask
, n
))
4917 return CALLEE_SAVED_REG_NUMBER (n
) + 1;
4921 /* Populate the current function's riscv_frame_info structure.
4923 RISC-V stack frames grown downward. High addresses are at the top.
4925 +-------------------------------+
4927 | incoming stack arguments |
4929 +-------------------------------+ <-- incoming stack pointer
4931 | callee-allocated save area |
4932 | for arguments that are |
4933 | split between registers and |
4936 +-------------------------------+ <-- arg_pointer_rtx
4938 | callee-allocated save area |
4939 | for register varargs |
4941 +-------------------------------+ <-- hard_frame_pointer_rtx;
4942 | | stack_pointer_rtx + gp_sp_offset
4943 | GPR save area | + UNITS_PER_WORD
4945 +-------------------------------+ <-- stack_pointer_rtx + fp_sp_offset
4946 | | + UNITS_PER_HWVALUE
4949 +-------------------------------+ <-- frame_pointer_rtx (virtual)
4953 P +-------------------------------+
4955 | outgoing stack arguments |
4957 +-------------------------------+ <-- stack_pointer_rtx
4959 Dynamic stack allocations such as alloca insert data at point P.
4960 They decrease stack_pointer_rtx but leave frame_pointer_rtx and
4961 hard_frame_pointer_rtx unchanged. */
4963 static HOST_WIDE_INT
riscv_first_stack_step (struct riscv_frame_info
*frame
, poly_int64 remaining_size
);
4965 /* Handle stack align for poly_int. */
4967 riscv_stack_align (poly_int64 value
)
4969 return aligned_upper_bound (value
, PREFERRED_STACK_BOUNDARY
/ 8);
4972 static HOST_WIDE_INT
4973 riscv_stack_align (HOST_WIDE_INT value
)
4975 return RISCV_STACK_ALIGN (value
);
4979 riscv_compute_frame_info (void)
4981 struct riscv_frame_info
*frame
;
4983 bool interrupt_save_prologue_temp
= false;
4984 unsigned int regno
, i
, num_x_saved
= 0, num_f_saved
= 0, x_save_size
= 0;
4986 frame
= &cfun
->machine
->frame
;
4988 /* In an interrupt function, if we have a large frame, then we need to
4989 save/restore t0. We check for this before clearing the frame struct. */
4990 if (cfun
->machine
->interrupt_handler_p
)
4992 HOST_WIDE_INT step1
= riscv_first_stack_step (frame
, frame
->total_size
);
4993 if (! POLY_SMALL_OPERAND_P ((frame
->total_size
- step1
)))
4994 interrupt_save_prologue_temp
= true;
4999 if (!cfun
->machine
->naked_p
)
5001 /* Find out which GPRs we need to save. */
5002 for (regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
5003 if (riscv_save_reg_p (regno
)
5004 || (interrupt_save_prologue_temp
5005 && (regno
== RISCV_PROLOGUE_TEMP_REGNUM
)))
5006 frame
->mask
|= 1 << (regno
- GP_REG_FIRST
), num_x_saved
++;
5008 /* If this function calls eh_return, we must also save and restore the
5009 EH data registers. */
5010 if (crtl
->calls_eh_return
)
5011 for (i
= 0; (regno
= EH_RETURN_DATA_REGNO (i
)) != INVALID_REGNUM
; i
++)
5012 frame
->mask
|= 1 << (regno
- GP_REG_FIRST
), num_x_saved
++;
5014 /* Find out which FPRs we need to save. This loop must iterate over
5015 the same space as its companion in riscv_for_each_saved_reg. */
5016 if (TARGET_HARD_FLOAT
)
5017 for (regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
++)
5018 if (riscv_save_reg_p (regno
))
5019 frame
->fmask
|= 1 << (regno
- FP_REG_FIRST
), num_f_saved
++;
5024 x_save_size
= riscv_stack_align (num_x_saved
* UNITS_PER_WORD
);
5025 unsigned num_save_restore
= 1 + riscv_save_libcall_count (frame
->mask
);
5027 /* Only use save/restore routines if they don't alter the stack size. */
5028 if (riscv_stack_align (num_save_restore
* UNITS_PER_WORD
) == x_save_size
5029 && !riscv_avoid_save_libcall ())
5031 /* Libcall saves/restores 3 registers at once, so we need to
5032 allocate 12 bytes for callee-saved register. */
5034 x_save_size
= 3 * UNITS_PER_WORD
;
5036 frame
->save_libcall_adjustment
= x_save_size
;
5040 /* At the bottom of the frame are any outgoing stack arguments. */
5041 offset
= riscv_stack_align (crtl
->outgoing_args_size
);
5042 /* Next are local stack variables. */
5043 offset
+= riscv_stack_align (get_frame_size ());
5044 /* The virtual frame pointer points above the local variables. */
5045 frame
->frame_pointer_offset
= offset
;
5046 /* Next are the callee-saved FPRs. */
5048 offset
+= riscv_stack_align (num_f_saved
* UNITS_PER_FP_REG
);
5049 frame
->fp_sp_offset
= offset
- UNITS_PER_FP_REG
;
5050 /* Next are the callee-saved GPRs. */
5052 offset
+= x_save_size
;
5053 frame
->gp_sp_offset
= offset
- UNITS_PER_WORD
;
5054 /* The hard frame pointer points above the callee-saved GPRs. */
5055 frame
->hard_frame_pointer_offset
= offset
;
5056 /* Above the hard frame pointer is the callee-allocated varags save area. */
5057 offset
+= riscv_stack_align (cfun
->machine
->varargs_size
);
5058 /* Next is the callee-allocated area for pretend stack arguments. */
5059 offset
+= riscv_stack_align (crtl
->args
.pretend_args_size
);
5060 /* Arg pointer must be below pretend args, but must be above alignment
5062 frame
->arg_pointer_offset
= offset
- crtl
->args
.pretend_args_size
;
5063 frame
->total_size
= offset
;
5065 /* Next points the incoming stack pointer and any incoming arguments. */
5068 /* Make sure that we're not trying to eliminate to the wrong hard frame
5072 riscv_can_eliminate (const int from ATTRIBUTE_UNUSED
, const int to
)
5074 return (to
== HARD_FRAME_POINTER_REGNUM
|| to
== STACK_POINTER_REGNUM
);
5077 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame pointer
5078 or argument pointer. TO is either the stack pointer or hard frame
5082 riscv_initial_elimination_offset (int from
, int to
)
5084 poly_int64 src
, dest
;
5086 riscv_compute_frame_info ();
5088 if (to
== HARD_FRAME_POINTER_REGNUM
)
5089 dest
= cfun
->machine
->frame
.hard_frame_pointer_offset
;
5090 else if (to
== STACK_POINTER_REGNUM
)
5091 dest
= 0; /* The stack pointer is the base of all offsets, hence 0. */
5095 if (from
== FRAME_POINTER_REGNUM
)
5096 src
= cfun
->machine
->frame
.frame_pointer_offset
;
5097 else if (from
== ARG_POINTER_REGNUM
)
5098 src
= cfun
->machine
->frame
.arg_pointer_offset
;
5105 /* Implement RETURN_ADDR_RTX. We do not support moving back to a
5109 riscv_return_addr (int count
, rtx frame ATTRIBUTE_UNUSED
)
5114 return get_hard_reg_initial_val (Pmode
, RETURN_ADDR_REGNUM
);
5117 /* Emit code to change the current function's return address to
5118 ADDRESS. SCRATCH is available as a scratch register, if needed.
5119 ADDRESS and SCRATCH are both word-mode GPRs. */
5122 riscv_set_return_address (rtx address
, rtx scratch
)
5126 gcc_assert (BITSET_P (cfun
->machine
->frame
.mask
, RETURN_ADDR_REGNUM
));
5127 slot_address
= riscv_add_offset (scratch
, stack_pointer_rtx
,
5128 cfun
->machine
->frame
.gp_sp_offset
.to_constant());
5129 riscv_emit_move (gen_frame_mem (GET_MODE (address
), slot_address
), address
);
5132 /* Save register REG to MEM. Make the instruction frame-related. */
5135 riscv_save_reg (rtx reg
, rtx mem
)
5137 riscv_emit_move (mem
, reg
);
5138 riscv_set_frame_expr (riscv_frame_set (mem
, reg
));
5141 /* Restore register REG from MEM. */
5144 riscv_restore_reg (rtx reg
, rtx mem
)
5146 rtx insn
= riscv_emit_move (reg
, mem
);
5147 rtx dwarf
= NULL_RTX
;
5148 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
5150 if (epilogue_cfa_sp_offset
&& REGNO (reg
) == HARD_FRAME_POINTER_REGNUM
)
5152 rtx cfa_adjust_rtx
= gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
5153 GEN_INT (epilogue_cfa_sp_offset
));
5154 dwarf
= alloc_reg_note (REG_CFA_DEF_CFA
, cfa_adjust_rtx
, dwarf
);
5157 REG_NOTES (insn
) = dwarf
;
5158 RTX_FRAME_RELATED_P (insn
) = 1;
5161 /* A function to save or store a register. The first argument is the
5162 register and the second is the stack slot. */
5163 typedef void (*riscv_save_restore_fn
) (rtx
, rtx
);
5165 /* Use FN to save or restore register REGNO. MODE is the register's
5166 mode and OFFSET is the offset of its save slot from the current
5170 riscv_save_restore_reg (machine_mode mode
, int regno
,
5171 HOST_WIDE_INT offset
, riscv_save_restore_fn fn
)
5175 mem
= gen_frame_mem (mode
, plus_constant (Pmode
, stack_pointer_rtx
, offset
));
5176 fn (gen_rtx_REG (mode
, regno
), mem
);
5179 /* Return the next register up from REGNO up to LIMIT for the callee
5180 to save or restore. OFFSET will be adjusted accordingly.
5181 If INC is set, then REGNO will be incremented first.
5182 Returns INVALID_REGNUM if there is no such next register. */
5185 riscv_next_saved_reg (unsigned int regno
, unsigned int limit
,
5186 HOST_WIDE_INT
*offset
, bool inc
= true)
5191 while (regno
<= limit
)
5193 if (BITSET_P (cfun
->machine
->frame
.mask
, regno
- GP_REG_FIRST
))
5195 *offset
= *offset
- UNITS_PER_WORD
;
5201 return INVALID_REGNUM
;
5204 /* Return TRUE if provided REGNO is eh return data register. */
5207 riscv_is_eh_return_data_register (unsigned int regno
)
5209 unsigned int i
, regnum
;
5211 if (!crtl
->calls_eh_return
)
5214 for (i
= 0; (regnum
= EH_RETURN_DATA_REGNO (i
)) != INVALID_REGNUM
; i
++)
5215 if (regno
== regnum
)
5223 /* Call FN for each register that is saved by the current function.
5224 SP_OFFSET is the offset of the current stack pointer from the start
5228 riscv_for_each_saved_reg (poly_int64 sp_offset
, riscv_save_restore_fn fn
,
5229 bool epilogue
, bool maybe_eh_return
)
5231 HOST_WIDE_INT offset
;
5233 unsigned int start
= GP_REG_FIRST
;
5234 unsigned int limit
= GP_REG_LAST
;
5236 /* Save the link register and s-registers. */
5237 offset
= (cfun
->machine
->frame
.gp_sp_offset
- sp_offset
).to_constant ()
5239 for (regno
= riscv_next_saved_reg (start
, limit
, &offset
, false);
5240 regno
!= INVALID_REGNUM
;
5241 regno
= riscv_next_saved_reg (regno
, limit
, &offset
))
5243 if (cfun
->machine
->reg_is_wrapped_separately
[regno
])
5246 /* If this is a normal return in a function that calls the eh_return
5247 builtin, then do not restore the eh return data registers as that
5248 would clobber the return value. But we do still need to save them
5249 in the prologue, and restore them for an exception return, so we
5250 need special handling here. */
5251 if (epilogue
&& !maybe_eh_return
5252 && riscv_is_eh_return_data_register (regno
))
5255 if (TARGET_XTHEADMEMPAIR
)
5257 /* Get the next reg/offset pair. */
5258 HOST_WIDE_INT offset2
= offset
;
5259 unsigned int regno2
= riscv_next_saved_reg (regno
, limit
, &offset2
);
5261 /* Validate everything before emitting a mempair instruction. */
5262 if (regno2
!= INVALID_REGNUM
5263 && !cfun
->machine
->reg_is_wrapped_separately
[regno2
]
5264 && !(epilogue
&& !maybe_eh_return
5265 && riscv_is_eh_return_data_register (regno2
)))
5267 bool load_p
= (fn
== riscv_restore_reg
);
5269 th_mempair_prepare_save_restore_operands (operands
,
5274 /* If the operands fit into a mempair insn, then emit one. */
5275 if (th_mempair_operands_p (operands
, load_p
, word_mode
))
5277 th_mempair_save_restore_regs (operands
, load_p
, word_mode
);
5285 riscv_save_restore_reg (word_mode
, regno
, offset
, fn
);
5288 /* This loop must iterate over the same space as its companion in
5289 riscv_compute_frame_info. */
5290 offset
= (cfun
->machine
->frame
.fp_sp_offset
- sp_offset
).to_constant ();
5291 for (unsigned int regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
++)
5292 if (BITSET_P (cfun
->machine
->frame
.fmask
, regno
- FP_REG_FIRST
))
5294 bool handle_reg
= !cfun
->machine
->reg_is_wrapped_separately
[regno
];
5295 machine_mode mode
= TARGET_DOUBLE_FLOAT
? DFmode
: SFmode
;
5298 riscv_save_restore_reg (mode
, regno
, offset
, fn
);
5299 offset
-= GET_MODE_SIZE (mode
).to_constant ();
5303 /* For stack frames that can't be allocated with a single ADDI instruction,
5304 compute the best value to initially allocate. It must at a minimum
5305 allocate enough space to spill the callee-saved registers. If TARGET_RVC,
5306 try to pick a value that will allow compression of the register saves
5307 without adding extra instructions. */
5309 static HOST_WIDE_INT
5310 riscv_first_stack_step (struct riscv_frame_info
*frame
, poly_int64 remaining_size
)
5312 HOST_WIDE_INT remaining_const_size
;
5313 if (!remaining_size
.is_constant ())
5314 remaining_const_size
5315 = riscv_stack_align (remaining_size
.coeffs
[0])
5316 - riscv_stack_align (remaining_size
.coeffs
[1]);
5318 remaining_const_size
= remaining_size
.to_constant ();
5320 if (SMALL_OPERAND (remaining_const_size
))
5321 return remaining_const_size
;
5323 poly_int64 callee_saved_first_step
=
5324 remaining_size
- frame
->frame_pointer_offset
;
5325 gcc_assert(callee_saved_first_step
.is_constant ());
5326 HOST_WIDE_INT min_first_step
=
5327 riscv_stack_align (callee_saved_first_step
.to_constant ());
5328 HOST_WIDE_INT max_first_step
= IMM_REACH
/ 2 - PREFERRED_STACK_BOUNDARY
/ 8;
5329 HOST_WIDE_INT min_second_step
= remaining_const_size
- max_first_step
;
5330 gcc_assert (min_first_step
<= max_first_step
);
5332 /* As an optimization, use the least-significant bits of the total frame
5333 size, so that the second adjustment step is just LUI + ADD. */
5334 if (!SMALL_OPERAND (min_second_step
)
5335 && remaining_const_size
% IMM_REACH
<= max_first_step
5336 && remaining_const_size
% IMM_REACH
>= min_first_step
)
5337 return remaining_const_size
% IMM_REACH
;
5341 /* If we need two subtracts, and one is small enough to allow compressed
5342 loads and stores, then put that one first. */
5343 if (IN_RANGE (min_second_step
, 0,
5344 (TARGET_64BIT
? SDSP_REACH
: SWSP_REACH
)))
5345 return MAX (min_second_step
, min_first_step
);
5347 /* If we need LUI + ADDI + ADD for the second adjustment step, then start
5348 with the minimum first step, so that we can get compressed loads and
5350 else if (!SMALL_OPERAND (min_second_step
))
5351 return min_first_step
;
5354 return max_first_step
;
5358 riscv_adjust_libcall_cfi_prologue ()
5360 rtx dwarf
= NULL_RTX
;
5361 rtx adjust_sp_rtx
, reg
, mem
, insn
;
5362 int saved_size
= cfun
->machine
->frame
.save_libcall_adjustment
;
5365 for (int regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
5366 if (BITSET_P (cfun
->machine
->frame
.mask
, regno
- GP_REG_FIRST
))
5368 /* The save order is ra, s0, s1, s2 to s11. */
5369 if (regno
== RETURN_ADDR_REGNUM
)
5370 offset
= saved_size
- UNITS_PER_WORD
;
5371 else if (regno
== S0_REGNUM
)
5372 offset
= saved_size
- UNITS_PER_WORD
* 2;
5373 else if (regno
== S1_REGNUM
)
5374 offset
= saved_size
- UNITS_PER_WORD
* 3;
5376 offset
= saved_size
- ((regno
- S2_REGNUM
+ 4) * UNITS_PER_WORD
);
5378 reg
= gen_rtx_REG (Pmode
, regno
);
5379 mem
= gen_frame_mem (Pmode
, plus_constant (Pmode
,
5383 insn
= gen_rtx_SET (mem
, reg
);
5384 dwarf
= alloc_reg_note (REG_CFA_OFFSET
, insn
, dwarf
);
5387 /* Debug info for adjust sp. */
5389 gen_rtx_SET (stack_pointer_rtx
,
5390 gen_rtx_PLUS (GET_MODE(stack_pointer_rtx
), stack_pointer_rtx
, GEN_INT (-saved_size
)));
5391 dwarf
= alloc_reg_note (REG_CFA_ADJUST_CFA
, adjust_sp_rtx
,
5397 riscv_emit_stack_tie (void)
5399 if (Pmode
== SImode
)
5400 emit_insn (gen_stack_tiesi (stack_pointer_rtx
, hard_frame_pointer_rtx
));
5402 emit_insn (gen_stack_tiedi (stack_pointer_rtx
, hard_frame_pointer_rtx
));
5405 /* Expand the "prologue" pattern. */
5408 riscv_expand_prologue (void)
5410 struct riscv_frame_info
*frame
= &cfun
->machine
->frame
;
5411 poly_int64 remaining_size
= frame
->total_size
;
5412 unsigned mask
= frame
->mask
;
5415 if (flag_stack_usage_info
)
5416 current_function_static_stack_size
= constant_lower_bound (remaining_size
);
5418 if (cfun
->machine
->naked_p
)
5421 /* When optimizing for size, call a subroutine to save the registers. */
5422 if (riscv_use_save_libcall (frame
))
5424 rtx dwarf
= NULL_RTX
;
5425 dwarf
= riscv_adjust_libcall_cfi_prologue ();
5427 remaining_size
-= frame
->save_libcall_adjustment
;
5428 insn
= emit_insn (riscv_gen_gpr_save_insn (frame
));
5429 frame
->mask
= 0; /* Temporarily fib that we need not save GPRs. */
5431 RTX_FRAME_RELATED_P (insn
) = 1;
5432 REG_NOTES (insn
) = dwarf
;
5435 /* Save the registers. */
5436 if ((frame
->mask
| frame
->fmask
) != 0)
5438 HOST_WIDE_INT step1
= riscv_first_stack_step (frame
, remaining_size
);
5440 insn
= gen_add3_insn (stack_pointer_rtx
,
5443 RTX_FRAME_RELATED_P (emit_insn (insn
)) = 1;
5444 remaining_size
-= step1
;
5445 riscv_for_each_saved_reg (remaining_size
, riscv_save_reg
, false, false);
5448 frame
->mask
= mask
; /* Undo the above fib. */
5450 /* Set up the frame pointer, if we're using one. */
5451 if (frame_pointer_needed
)
5453 insn
= gen_add3_insn (hard_frame_pointer_rtx
, stack_pointer_rtx
,
5454 GEN_INT ((frame
->hard_frame_pointer_offset
- remaining_size
).to_constant ()));
5455 RTX_FRAME_RELATED_P (emit_insn (insn
)) = 1;
5457 riscv_emit_stack_tie ();
5460 /* Allocate the rest of the frame. */
5461 if (known_gt (remaining_size
, 0))
5463 /* Two step adjustment:
5464 1.scalable frame. 2.constant frame. */
5465 poly_int64
scalable_frame (0, 0);
5466 if (!remaining_size
.is_constant ())
5468 /* First for scalable frame. */
5469 poly_int64 scalable_frame
= remaining_size
;
5470 scalable_frame
.coeffs
[0] = remaining_size
.coeffs
[1];
5471 riscv_v_adjust_scalable_frame (stack_pointer_rtx
, scalable_frame
, false);
5472 remaining_size
-= scalable_frame
;
5475 /* Second step for constant frame. */
5476 HOST_WIDE_INT constant_frame
= remaining_size
.to_constant ();
5477 if (constant_frame
== 0)
5480 if (SMALL_OPERAND (-constant_frame
))
5482 insn
= gen_add3_insn (stack_pointer_rtx
, stack_pointer_rtx
,
5483 GEN_INT (-constant_frame
));
5484 RTX_FRAME_RELATED_P (emit_insn (insn
)) = 1;
5488 riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode
), GEN_INT (-constant_frame
));
5489 emit_insn (gen_add3_insn (stack_pointer_rtx
,
5491 RISCV_PROLOGUE_TEMP (Pmode
)));
5493 /* Describe the effect of the previous instructions. */
5494 insn
= plus_constant (Pmode
, stack_pointer_rtx
, -constant_frame
);
5495 insn
= gen_rtx_SET (stack_pointer_rtx
, insn
);
5496 riscv_set_frame_expr (insn
);
5502 riscv_adjust_libcall_cfi_epilogue ()
5504 rtx dwarf
= NULL_RTX
;
5505 rtx adjust_sp_rtx
, reg
;
5506 int saved_size
= cfun
->machine
->frame
.save_libcall_adjustment
;
5508 /* Debug info for adjust sp. */
5510 gen_rtx_SET (stack_pointer_rtx
,
5511 gen_rtx_PLUS (GET_MODE(stack_pointer_rtx
), stack_pointer_rtx
, GEN_INT (saved_size
)));
5512 dwarf
= alloc_reg_note (REG_CFA_ADJUST_CFA
, adjust_sp_rtx
,
5515 for (int regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
5516 if (BITSET_P (cfun
->machine
->frame
.mask
, regno
- GP_REG_FIRST
))
5518 reg
= gen_rtx_REG (Pmode
, regno
);
5519 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
5525 /* Expand an "epilogue", "sibcall_epilogue", or "eh_return_internal" pattern;
5526 style says which. */
5529 riscv_expand_epilogue (int style
)
5531 /* Split the frame into 3 steps. STEP1 is the amount of stack we should
5532 deallocate before restoring the registers. STEP2 is the amount we
5533 should deallocate afterwards including the callee saved regs. STEP3
5534 is the amount deallocated by save-restore libcall.
5536 Start off by assuming that no registers need to be restored. */
5537 struct riscv_frame_info
*frame
= &cfun
->machine
->frame
;
5538 unsigned mask
= frame
->mask
;
5539 HOST_WIDE_INT step2
= 0;
5540 bool use_restore_libcall
= ((style
== NORMAL_RETURN
)
5541 && riscv_use_save_libcall (frame
));
5542 unsigned libcall_size
= (use_restore_libcall
5543 ? frame
->save_libcall_adjustment
: 0);
5544 rtx ra
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
5547 /* We need to add memory barrier to prevent read from deallocated stack. */
5548 bool need_barrier_p
= known_ne (get_frame_size ()
5549 + cfun
->machine
->frame
.arg_pointer_offset
, 0);
5551 if (cfun
->machine
->naked_p
)
5553 gcc_assert (style
== NORMAL_RETURN
);
5555 emit_jump_insn (gen_return ());
5560 if ((style
== NORMAL_RETURN
) && riscv_can_use_return_insn ())
5562 emit_jump_insn (gen_return ());
5566 /* Reset the epilogue cfa info before starting to emit the epilogue. */
5567 epilogue_cfa_sp_offset
= 0;
5569 /* Move past any dynamic stack allocations. */
5570 if (cfun
->calls_alloca
)
5572 /* Emit a barrier to prevent loads from a deallocated stack. */
5573 riscv_emit_stack_tie ();
5574 need_barrier_p
= false;
5576 poly_int64 adjust_offset
= -frame
->hard_frame_pointer_offset
;
5577 rtx adjust
= NULL_RTX
;
5579 if (!adjust_offset
.is_constant ())
5581 rtx tmp1
= RISCV_PROLOGUE_TEMP (Pmode
);
5582 rtx tmp2
= RISCV_PROLOGUE_TEMP2 (Pmode
);
5583 riscv_legitimize_poly_move (Pmode
, tmp1
, tmp2
,
5584 gen_int_mode (adjust_offset
, Pmode
));
5589 if (!SMALL_OPERAND (adjust_offset
.to_constant ()))
5591 riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode
),
5592 GEN_INT (adjust_offset
.to_constant ()));
5593 adjust
= RISCV_PROLOGUE_TEMP (Pmode
);
5596 adjust
= GEN_INT (adjust_offset
.to_constant ());
5600 gen_add3_insn (stack_pointer_rtx
, hard_frame_pointer_rtx
,
5603 rtx dwarf
= NULL_RTX
;
5604 rtx cfa_adjust_value
= gen_rtx_PLUS (
5605 Pmode
, hard_frame_pointer_rtx
,
5606 gen_int_mode (-frame
->hard_frame_pointer_offset
, Pmode
));
5607 rtx cfa_adjust_rtx
= gen_rtx_SET (stack_pointer_rtx
, cfa_adjust_value
);
5608 dwarf
= alloc_reg_note (REG_CFA_ADJUST_CFA
, cfa_adjust_rtx
, dwarf
);
5609 RTX_FRAME_RELATED_P (insn
) = 1;
5611 REG_NOTES (insn
) = dwarf
;
5614 if (use_restore_libcall
)
5615 frame
->mask
= 0; /* Temporarily fib for GPRs. */
5617 /* If we need to restore registers, deallocate as much stack as
5618 possible in the second step without going out of range. */
5619 if ((frame
->mask
| frame
->fmask
) != 0)
5620 step2
= riscv_first_stack_step (frame
, frame
->total_size
- libcall_size
);
5622 if (use_restore_libcall
)
5623 frame
->mask
= mask
; /* Undo the above fib. */
5625 poly_int64 step1
= frame
->total_size
- step2
- libcall_size
;
5627 /* Set TARGET to BASE + STEP1. */
5628 if (known_gt (step1
, 0))
5630 /* Emit a barrier to prevent loads from a deallocated stack. */
5631 riscv_emit_stack_tie ();
5632 need_barrier_p
= false;
5634 /* Restore the scalable frame which is assigned in prologue. */
5635 if (!step1
.is_constant ())
5637 poly_int64 scalable_frame
= step1
;
5638 scalable_frame
.coeffs
[0] = step1
.coeffs
[1];
5639 riscv_v_adjust_scalable_frame (stack_pointer_rtx
, scalable_frame
,
5641 step1
-= scalable_frame
;
5644 /* Get an rtx for STEP1 that we can add to BASE.
5645 Skip if adjust equal to zero. */
5646 if (step1
.to_constant () != 0)
5648 rtx adjust
= GEN_INT (step1
.to_constant ());
5649 if (!SMALL_OPERAND (step1
.to_constant ()))
5651 riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode
), adjust
);
5652 adjust
= RISCV_PROLOGUE_TEMP (Pmode
);
5655 insn
= emit_insn (gen_add3_insn (stack_pointer_rtx
,
5658 rtx dwarf
= NULL_RTX
;
5659 rtx cfa_adjust_rtx
= gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
5660 GEN_INT (step2
+ libcall_size
));
5662 dwarf
= alloc_reg_note (REG_CFA_DEF_CFA
, cfa_adjust_rtx
, dwarf
);
5663 RTX_FRAME_RELATED_P (insn
) = 1;
5665 REG_NOTES (insn
) = dwarf
;
5668 else if (frame_pointer_needed
)
5670 /* Tell riscv_restore_reg to emit dwarf to redefine CFA when restoring
5672 epilogue_cfa_sp_offset
= step2
;
5675 if (use_restore_libcall
)
5676 frame
->mask
= 0; /* Temporarily fib that we need not save GPRs. */
5678 /* Restore the registers. */
5679 riscv_for_each_saved_reg (frame
->total_size
- step2
- libcall_size
,
5681 true, style
== EXCEPTION_RETURN
);
5683 if (use_restore_libcall
)
5684 frame
->mask
= mask
; /* Undo the above fib. */
5687 riscv_emit_stack_tie ();
5689 /* Deallocate the final bit of the frame. */
5692 insn
= emit_insn (gen_add3_insn (stack_pointer_rtx
, stack_pointer_rtx
,
5695 rtx dwarf
= NULL_RTX
;
5696 rtx cfa_adjust_rtx
= gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
5697 GEN_INT (libcall_size
));
5698 dwarf
= alloc_reg_note (REG_CFA_DEF_CFA
, cfa_adjust_rtx
, dwarf
);
5699 RTX_FRAME_RELATED_P (insn
) = 1;
5701 REG_NOTES (insn
) = dwarf
;
5704 if (use_restore_libcall
)
5706 rtx dwarf
= riscv_adjust_libcall_cfi_epilogue ();
5707 insn
= emit_insn (gen_gpr_restore (GEN_INT (riscv_save_libcall_count (mask
))));
5708 RTX_FRAME_RELATED_P (insn
) = 1;
5709 REG_NOTES (insn
) = dwarf
;
5711 emit_jump_insn (gen_gpr_restore_return (ra
));
5715 /* Add in the __builtin_eh_return stack adjustment. */
5716 if ((style
== EXCEPTION_RETURN
) && crtl
->calls_eh_return
)
5717 emit_insn (gen_add3_insn (stack_pointer_rtx
, stack_pointer_rtx
,
5718 EH_RETURN_STACKADJ_RTX
));
5720 /* Return from interrupt. */
5721 if (cfun
->machine
->interrupt_handler_p
)
5723 enum riscv_privilege_levels mode
= cfun
->machine
->interrupt_mode
;
5725 gcc_assert (mode
!= UNKNOWN_MODE
);
5727 if (mode
== MACHINE_MODE
)
5728 emit_jump_insn (gen_riscv_mret ());
5729 else if (mode
== SUPERVISOR_MODE
)
5730 emit_jump_insn (gen_riscv_sret ());
5732 emit_jump_insn (gen_riscv_uret ());
5734 else if (style
!= SIBCALL_RETURN
)
5735 emit_jump_insn (gen_simple_return_internal (ra
));
5738 /* Implement EPILOGUE_USES. */
5741 riscv_epilogue_uses (unsigned int regno
)
5743 if (regno
== RETURN_ADDR_REGNUM
)
5746 if (epilogue_completed
&& cfun
->machine
->interrupt_handler_p
)
5748 /* An interrupt function restores temp regs, so we must indicate that
5749 they are live at function end. */
5750 if (df_regs_ever_live_p (regno
)
5751 || (!crtl
->is_leaf
&& call_used_or_fixed_reg_p (regno
)))
5758 /* Implement TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS. */
5761 riscv_get_separate_components (void)
5763 HOST_WIDE_INT offset
;
5764 sbitmap components
= sbitmap_alloc (FIRST_PSEUDO_REGISTER
);
5765 bitmap_clear (components
);
5767 if (riscv_use_save_libcall (&cfun
->machine
->frame
)
5768 || cfun
->machine
->interrupt_handler_p
5769 || !cfun
->machine
->frame
.gp_sp_offset
.is_constant ())
5772 offset
= cfun
->machine
->frame
.gp_sp_offset
.to_constant ();
5773 for (unsigned int regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
5774 if (BITSET_P (cfun
->machine
->frame
.mask
, regno
- GP_REG_FIRST
))
5776 /* We can only wrap registers that have small operand offsets.
5777 For large offsets a pseudo register might be needed which
5778 cannot be created during the shrink wrapping pass. */
5779 if (SMALL_OPERAND (offset
))
5780 bitmap_set_bit (components
, regno
);
5782 offset
-= UNITS_PER_WORD
;
5785 offset
= cfun
->machine
->frame
.fp_sp_offset
.to_constant ();
5786 for (unsigned int regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
++)
5787 if (BITSET_P (cfun
->machine
->frame
.fmask
, regno
- FP_REG_FIRST
))
5789 machine_mode mode
= TARGET_DOUBLE_FLOAT
? DFmode
: SFmode
;
5791 /* We can only wrap registers that have small operand offsets.
5792 For large offsets a pseudo register might be needed which
5793 cannot be created during the shrink wrapping pass. */
5794 if (SMALL_OPERAND (offset
))
5795 bitmap_set_bit (components
, regno
);
5797 offset
-= GET_MODE_SIZE (mode
).to_constant ();
5800 /* Don't mess with the hard frame pointer. */
5801 if (frame_pointer_needed
)
5802 bitmap_clear_bit (components
, HARD_FRAME_POINTER_REGNUM
);
5804 bitmap_clear_bit (components
, RETURN_ADDR_REGNUM
);
5809 /* Implement TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB. */
5812 riscv_components_for_bb (basic_block bb
)
5814 bitmap in
= DF_LIVE_IN (bb
);
5815 bitmap gen
= &DF_LIVE_BB_INFO (bb
)->gen
;
5816 bitmap kill
= &DF_LIVE_BB_INFO (bb
)->kill
;
5818 sbitmap components
= sbitmap_alloc (FIRST_PSEUDO_REGISTER
);
5819 bitmap_clear (components
);
5821 function_abi_aggregator callee_abis
;
5823 FOR_BB_INSNS (bb
, insn
)
5825 callee_abis
.note_callee_abi (insn_callee_abi (insn
));
5826 HARD_REG_SET extra_caller_saves
= callee_abis
.caller_save_regs (*crtl
->abi
);
5828 /* GPRs are used in a bb if they are in the IN, GEN, or KILL sets. */
5829 for (unsigned int regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
5830 if (!fixed_regs
[regno
]
5831 && !crtl
->abi
->clobbers_full_reg_p (regno
)
5832 && (TEST_HARD_REG_BIT (extra_caller_saves
, regno
)
5833 || bitmap_bit_p (in
, regno
)
5834 || bitmap_bit_p (gen
, regno
)
5835 || bitmap_bit_p (kill
, regno
)))
5836 bitmap_set_bit (components
, regno
);
5838 for (unsigned int regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
++)
5839 if (!fixed_regs
[regno
]
5840 && !crtl
->abi
->clobbers_full_reg_p (regno
)
5841 && (TEST_HARD_REG_BIT (extra_caller_saves
, regno
)
5842 || bitmap_bit_p (in
, regno
)
5843 || bitmap_bit_p (gen
, regno
)
5844 || bitmap_bit_p (kill
, regno
)))
5845 bitmap_set_bit (components
, regno
);
5850 /* Implement TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS. */
5853 riscv_disqualify_components (sbitmap
, edge
, sbitmap
, bool)
5855 /* Nothing to do for riscv. */
5859 riscv_process_components (sbitmap components
, bool prologue_p
)
5861 HOST_WIDE_INT offset
;
5862 riscv_save_restore_fn fn
= prologue_p
? riscv_save_reg
: riscv_restore_reg
;
5864 offset
= cfun
->machine
->frame
.gp_sp_offset
.to_constant ();
5865 for (unsigned int regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
5866 if (BITSET_P (cfun
->machine
->frame
.mask
, regno
- GP_REG_FIRST
))
5868 if (bitmap_bit_p (components
, regno
))
5869 riscv_save_restore_reg (word_mode
, regno
, offset
, fn
);
5871 offset
-= UNITS_PER_WORD
;
5874 offset
= cfun
->machine
->frame
.fp_sp_offset
.to_constant ();
5875 for (unsigned int regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
++)
5876 if (BITSET_P (cfun
->machine
->frame
.fmask
, regno
- FP_REG_FIRST
))
5878 machine_mode mode
= TARGET_DOUBLE_FLOAT
? DFmode
: SFmode
;
5880 if (bitmap_bit_p (components
, regno
))
5881 riscv_save_restore_reg (mode
, regno
, offset
, fn
);
5883 offset
-= GET_MODE_SIZE (mode
).to_constant ();
5887 /* Implement TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS. */
5890 riscv_emit_prologue_components (sbitmap components
)
5892 riscv_process_components (components
, true);
5895 /* Implement TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS. */
5898 riscv_emit_epilogue_components (sbitmap components
)
5900 riscv_process_components (components
, false);
5904 riscv_set_handled_components (sbitmap components
)
5906 for (unsigned int regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
5907 if (bitmap_bit_p (components
, regno
))
5908 cfun
->machine
->reg_is_wrapped_separately
[regno
] = true;
5910 for (unsigned int regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
++)
5911 if (bitmap_bit_p (components
, regno
))
5912 cfun
->machine
->reg_is_wrapped_separately
[regno
] = true;
5915 /* Return nonzero if this function is known to have a null epilogue.
5916 This allows the optimizer to omit jumps to jumps if no stack
5920 riscv_can_use_return_insn (void)
5922 return (reload_completed
&& known_eq (cfun
->machine
->frame
.total_size
, 0)
5923 && ! cfun
->machine
->interrupt_handler_p
);
5926 /* Given that there exists at least one variable that is set (produced)
5927 by OUT_INSN and read (consumed) by IN_INSN, return true iff
5928 IN_INSN represents one or more memory store operations and none of
5929 the variables set by OUT_INSN is used by IN_INSN as the address of a
5930 store operation. If either IN_INSN or OUT_INSN does not represent
5931 a "single" RTL SET expression (as loosely defined by the
5932 implementation of the single_set function) or a PARALLEL with only
5933 SETs, CLOBBERs, and USEs inside, this function returns false.
5935 Borrowed from rs6000, riscv_store_data_bypass_p checks for certain
5936 conditions that result in assertion failures in the generic
5937 store_data_bypass_p function and returns FALSE in such cases.
5939 This is required to make -msave-restore work with the sifive-7
5940 pipeline description. */
5943 riscv_store_data_bypass_p (rtx_insn
*out_insn
, rtx_insn
*in_insn
)
5945 rtx out_set
, in_set
;
5946 rtx out_pat
, in_pat
;
5947 rtx out_exp
, in_exp
;
5950 in_set
= single_set (in_insn
);
5953 if (MEM_P (SET_DEST (in_set
)))
5955 out_set
= single_set (out_insn
);
5958 out_pat
= PATTERN (out_insn
);
5959 if (GET_CODE (out_pat
) == PARALLEL
)
5961 for (i
= 0; i
< XVECLEN (out_pat
, 0); i
++)
5963 out_exp
= XVECEXP (out_pat
, 0, i
);
5964 if ((GET_CODE (out_exp
) == CLOBBER
)
5965 || (GET_CODE (out_exp
) == USE
))
5967 else if (GET_CODE (out_exp
) != SET
)
5976 in_pat
= PATTERN (in_insn
);
5977 if (GET_CODE (in_pat
) != PARALLEL
)
5980 for (i
= 0; i
< XVECLEN (in_pat
, 0); i
++)
5982 in_exp
= XVECEXP (in_pat
, 0, i
);
5983 if ((GET_CODE (in_exp
) == CLOBBER
) || (GET_CODE (in_exp
) == USE
))
5985 else if (GET_CODE (in_exp
) != SET
)
5988 if (MEM_P (SET_DEST (in_exp
)))
5990 out_set
= single_set (out_insn
);
5993 out_pat
= PATTERN (out_insn
);
5994 if (GET_CODE (out_pat
) != PARALLEL
)
5996 for (j
= 0; j
< XVECLEN (out_pat
, 0); j
++)
5998 out_exp
= XVECEXP (out_pat
, 0, j
);
5999 if ((GET_CODE (out_exp
) == CLOBBER
)
6000 || (GET_CODE (out_exp
) == USE
))
6002 else if (GET_CODE (out_exp
) != SET
)
6010 return store_data_bypass_p (out_insn
, in_insn
);
6013 /* Implement TARGET_SECONDARY_MEMORY_NEEDED.
6015 When floating-point registers are wider than integer ones, moves between
6016 them must go through memory. */
6019 riscv_secondary_memory_needed (machine_mode mode
, reg_class_t class1
,
6022 return (!riscv_v_ext_mode_p (mode
)
6023 && GET_MODE_SIZE (mode
).to_constant () > UNITS_PER_WORD
6024 && (class1
== FP_REGS
) != (class2
== FP_REGS
)
6025 && !TARGET_XTHEADFMV
);
6028 /* Implement TARGET_REGISTER_MOVE_COST. */
6031 riscv_register_move_cost (machine_mode mode
,
6032 reg_class_t from
, reg_class_t to
)
6034 if ((from
== FP_REGS
&& to
== GR_REGS
) ||
6035 (from
== GR_REGS
&& to
== FP_REGS
))
6036 return tune_param
->fmv_cost
;
6038 return riscv_secondary_memory_needed (mode
, from
, to
) ? 8 : 2;
6041 /* Implement TARGET_HARD_REGNO_NREGS. */
6044 riscv_hard_regno_nregs (unsigned int regno
, machine_mode mode
)
6046 if (riscv_v_ext_vector_mode_p (mode
))
6048 /* Handle fractional LMUL, it only occupy part of vector register but
6049 still need one vector register to hold. */
6050 if (maybe_lt (GET_MODE_SIZE (mode
), UNITS_PER_V_REG
))
6053 return exact_div (GET_MODE_SIZE (mode
), UNITS_PER_V_REG
).to_constant ();
6056 /* For tuple modes, the number of register = NF * LMUL. */
6057 if (riscv_v_ext_tuple_mode_p (mode
))
6059 unsigned int nf
= riscv_vector::get_nf (mode
);
6060 machine_mode subpart_mode
= riscv_vector::get_subpart_mode (mode
);
6061 poly_int64 size
= GET_MODE_SIZE (subpart_mode
);
6062 gcc_assert (known_eq (size
* nf
, GET_MODE_SIZE (mode
)));
6063 if (maybe_lt (size
, UNITS_PER_V_REG
))
6067 unsigned int lmul
= exact_div (size
, UNITS_PER_V_REG
).to_constant ();
6072 /* mode for VL or VTYPE are just a marker, not holding value,
6073 so it always consume one register. */
6074 if (VTYPE_REG_P (regno
) || VL_REG_P (regno
) || VXRM_REG_P (regno
)
6075 || FRM_REG_P (regno
))
6078 /* Assume every valid non-vector mode fits in one vector register. */
6079 if (V_REG_P (regno
))
6082 if (FP_REG_P (regno
))
6083 return (GET_MODE_SIZE (mode
).to_constant () + UNITS_PER_FP_REG
- 1) / UNITS_PER_FP_REG
;
6085 /* All other registers are word-sized. */
6086 return (GET_MODE_SIZE (mode
).to_constant () + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
6089 /* Implement TARGET_HARD_REGNO_MODE_OK. */
6092 riscv_hard_regno_mode_ok (unsigned int regno
, machine_mode mode
)
6094 unsigned int nregs
= riscv_hard_regno_nregs (regno
, mode
);
6096 if (GP_REG_P (regno
))
6098 if (riscv_v_ext_mode_p (mode
))
6101 if (!GP_REG_P (regno
+ nregs
- 1))
6104 else if (FP_REG_P (regno
))
6106 if (riscv_v_ext_mode_p (mode
))
6109 if (!FP_REG_P (regno
+ nregs
- 1))
6112 if (GET_MODE_CLASS (mode
) != MODE_FLOAT
6113 && GET_MODE_CLASS (mode
) != MODE_COMPLEX_FLOAT
)
6116 /* Only use callee-saved registers if a potential callee is guaranteed
6117 to spill the requisite width. */
6118 if (GET_MODE_UNIT_SIZE (mode
) > UNITS_PER_FP_REG
6119 || (!call_used_or_fixed_reg_p (regno
)
6120 && GET_MODE_UNIT_SIZE (mode
) > UNITS_PER_FP_ARG
))
6123 else if (V_REG_P (regno
))
6125 if (!riscv_v_ext_mode_p (mode
))
6128 if (!V_REG_P (regno
+ nregs
- 1))
6131 /* 3.3.2. LMUL = 2,4,8, register numbers should be multiple of 2,4,8.
6132 but for mask vector register, register numbers can be any number. */
6134 machine_mode rvv_mode
= mode
;
6135 if (riscv_v_ext_tuple_mode_p (rvv_mode
))
6136 rvv_mode
= riscv_vector::get_subpart_mode (rvv_mode
);
6137 poly_int64 size
= GET_MODE_SIZE (rvv_mode
);
6138 if (known_gt (size
, UNITS_PER_V_REG
))
6139 lmul
= exact_div (size
, UNITS_PER_V_REG
).to_constant ();
6141 return ((regno
% lmul
) == 0);
6143 else if (VTYPE_REG_P (regno
) || VL_REG_P (regno
) || VXRM_REG_P (regno
)
6144 || FRM_REG_P (regno
))
6149 /* Require same callee-savedness for all registers. */
6150 for (unsigned i
= 1; i
< nregs
; i
++)
6151 if (call_used_or_fixed_reg_p (regno
)
6152 != call_used_or_fixed_reg_p (regno
+ i
))
6155 /* Only use even registers in RV32 ZDINX */
6156 if (!TARGET_64BIT
&& TARGET_ZDINX
){
6157 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
&&
6158 GET_MODE_UNIT_SIZE (mode
) == GET_MODE_SIZE (DFmode
))
6159 return !(regno
& 1);
6165 /* Implement TARGET_MODES_TIEABLE_P.
6167 Don't allow floating-point modes to be tied, since type punning of
6168 single-precision and double-precision is implementation defined. */
6171 riscv_modes_tieable_p (machine_mode mode1
, machine_mode mode2
)
6173 return (mode1
== mode2
6174 || !(GET_MODE_CLASS (mode1
) == MODE_FLOAT
6175 && GET_MODE_CLASS (mode2
) == MODE_FLOAT
));
6178 /* Implement CLASS_MAX_NREGS. */
6180 static unsigned char
6181 riscv_class_max_nregs (reg_class_t rclass
, machine_mode mode
)
6183 if (reg_class_subset_p (rclass
, FP_REGS
))
6184 return riscv_hard_regno_nregs (FP_REG_FIRST
, mode
);
6186 if (reg_class_subset_p (rclass
, GR_REGS
))
6187 return riscv_hard_regno_nregs (GP_REG_FIRST
, mode
);
6189 if (reg_class_subset_p (rclass
, V_REGS
))
6190 return riscv_hard_regno_nregs (V_REG_FIRST
, mode
);
6195 /* Implement TARGET_MEMORY_MOVE_COST. */
6198 riscv_memory_move_cost (machine_mode mode
, reg_class_t rclass
, bool in
)
6200 return (tune_param
->memory_cost
6201 + memory_move_secondary_cost (mode
, rclass
, in
));
6204 /* Return the number of instructions that can be issued per cycle. */
6207 riscv_issue_rate (void)
6209 return tune_param
->issue_rate
;
6212 /* Auxiliary function to emit RISC-V ELF attribute. */
6214 riscv_emit_attribute ()
6216 fprintf (asm_out_file
, "\t.attribute arch, \"%s\"\n",
6217 riscv_arch_str ().c_str ());
6219 fprintf (asm_out_file
, "\t.attribute unaligned_access, %d\n",
6220 TARGET_STRICT_ALIGN
? 0 : 1);
6222 fprintf (asm_out_file
, "\t.attribute stack_align, %d\n",
6223 riscv_stack_boundary
/ 8);
6226 /* Implement TARGET_ASM_FILE_START. */
6229 riscv_file_start (void)
6231 default_file_start ();
6233 /* Instruct GAS to generate position-[in]dependent code. */
6234 fprintf (asm_out_file
, "\t.option %spic\n", (flag_pic
? "" : "no"));
6236 /* If the user specifies "-mno-relax" on the command line then disable linker
6237 relaxation in the assembler. */
6239 fprintf (asm_out_file
, "\t.option norelax\n");
6241 /* If the user specifies "-mcsr-check" on the command line then enable csr
6242 check in the assembler. */
6243 if (riscv_mcsr_check
)
6244 fprintf (asm_out_file
, "\t.option csr-check\n");
6246 if (riscv_emit_attribute_p
)
6247 riscv_emit_attribute ();
6250 /* Implement TARGET_ASM_OUTPUT_MI_THUNK. Generate rtl rather than asm text
6251 in order to avoid duplicating too much logic from elsewhere. */
6254 riscv_output_mi_thunk (FILE *file
, tree thunk_fndecl ATTRIBUTE_UNUSED
,
6255 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
6258 const char *fnname
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl
));
6259 rtx this_rtx
, temp1
, temp2
, fnaddr
;
6262 /* Pretend to be a post-reload pass while generating rtl. */
6263 reload_completed
= 1;
6265 /* Mark the end of the (empty) prologue. */
6266 emit_note (NOTE_INSN_PROLOGUE_END
);
6268 /* Determine if we can use a sibcall to call FUNCTION directly. */
6269 fnaddr
= gen_rtx_MEM (FUNCTION_MODE
, XEXP (DECL_RTL (function
), 0));
6271 /* We need two temporary registers in some cases. */
6272 temp1
= gen_rtx_REG (Pmode
, RISCV_PROLOGUE_TEMP_REGNUM
);
6273 temp2
= gen_rtx_REG (Pmode
, STATIC_CHAIN_REGNUM
);
6275 /* Find out which register contains the "this" pointer. */
6276 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
6277 this_rtx
= gen_rtx_REG (Pmode
, GP_ARG_FIRST
+ 1);
6279 this_rtx
= gen_rtx_REG (Pmode
, GP_ARG_FIRST
);
6281 /* Add DELTA to THIS_RTX. */
6284 rtx offset
= GEN_INT (delta
);
6285 if (!SMALL_OPERAND (delta
))
6287 riscv_emit_move (temp1
, offset
);
6290 emit_insn (gen_add3_insn (this_rtx
, this_rtx
, offset
));
6293 /* If needed, add *(*THIS_RTX + VCALL_OFFSET) to THIS_RTX. */
6294 if (vcall_offset
!= 0)
6298 /* Set TEMP1 to *THIS_RTX. */
6299 riscv_emit_move (temp1
, gen_rtx_MEM (Pmode
, this_rtx
));
6301 /* Set ADDR to a legitimate address for *THIS_RTX + VCALL_OFFSET. */
6302 addr
= riscv_add_offset (temp2
, temp1
, vcall_offset
);
6304 /* Load the offset and add it to THIS_RTX. */
6305 riscv_emit_move (temp1
, gen_rtx_MEM (Pmode
, addr
));
6306 emit_insn (gen_add3_insn (this_rtx
, this_rtx
, temp1
));
6309 /* Jump to the target function. */
6310 insn
= emit_call_insn (gen_sibcall (fnaddr
, const0_rtx
, NULL
, const0_rtx
));
6311 SIBLING_CALL_P (insn
) = 1;
6313 /* Run just enough of rest_of_compilation. This sequence was
6314 "borrowed" from alpha.cc. */
6315 insn
= get_insns ();
6316 split_all_insns_noflow ();
6317 shorten_branches (insn
);
6318 assemble_start_function (thunk_fndecl
, fnname
);
6319 final_start_function (insn
, file
, 1);
6320 final (insn
, file
, 1);
6321 final_end_function ();
6322 assemble_end_function (thunk_fndecl
, fnname
);
6324 /* Clean up the vars set above. Note that final_end_function resets
6325 the global pointer for us. */
6326 reload_completed
= 0;
6329 /* Allocate a chunk of memory for per-function machine-dependent data. */
6331 static struct machine_function
*
6332 riscv_init_machine_status (void)
6334 return ggc_cleared_alloc
<machine_function
> ();
6337 /* Return the VLEN value associated with -march.
6338 TODO: So far we only support length-agnostic value. */
6340 riscv_convert_vector_bits (void)
6342 if (TARGET_MIN_VLEN
>= 128)
6344 /* We have Full 'V' extension for application processors. It's specified
6345 by -march=rv64gcv/rv32gcv, The 'V' extension depends upon the Zvl128b
6346 and Zve64d extensions. Thus the number of bytes in a vector is 16 + 16
6347 * x1 which is riscv_vector_chunks * 16 = poly_int (16, 16). */
6348 riscv_bytes_per_vector_chunk
= 16;
6350 else if (TARGET_MIN_VLEN
> 32)
6352 /* When targetting minimum VLEN > 32, we should use 64-bit chunk size.
6353 Otherwise we can not include SEW = 64bits.
6354 Runtime invariant: The single indeterminate represent the
6355 number of 64-bit chunks in a vector beyond minimum length of 64 bits.
6356 Thus the number of bytes in a vector is 8 + 8 * x1 which is
6357 riscv_vector_chunks * 8 = poly_int (8, 8). */
6358 riscv_bytes_per_vector_chunk
= 8;
6362 /* When targetting minimum VLEN = 32, we should use 32-bit
6363 chunk size. Runtime invariant: The single indeterminate represent the
6364 number of 32-bit chunks in a vector beyond minimum length of 32 bits.
6365 Thus the number of bytes in a vector is 4 + 4 * x1 which is
6366 riscv_vector_chunks * 4 = poly_int (4, 4). */
6367 riscv_bytes_per_vector_chunk
= 4;
6370 /* Set riscv_vector_chunks as poly (1, 1) run-time constant if TARGET_VECTOR
6371 is enabled. Set riscv_vector_chunks as 1 compile-time constant if
6372 TARGET_VECTOR is disabled. riscv_vector_chunks is used in "riscv-modes.def"
6373 to set RVV mode size. The RVV machine modes size are run-time constant if
6374 TARGET_VECTOR is enabled. The RVV machine modes size remains default
6375 compile-time constant if TARGET_VECTOR is disabled. */
6378 if (riscv_autovec_preference
== RVV_FIXED_VLMAX
)
6379 return (int) TARGET_MIN_VLEN
/ (riscv_bytes_per_vector_chunk
* 8);
6381 return poly_uint16 (1, 1);
6387 /* Implement TARGET_OPTION_OVERRIDE. */
6390 riscv_option_override (void)
6392 const struct riscv_tune_info
*cpu
;
6394 #ifdef SUBTARGET_OVERRIDE_OPTIONS
6395 SUBTARGET_OVERRIDE_OPTIONS
;
6398 flag_pcc_struct_return
= 0;
6403 /* The presence of the M extension implies that division instructions
6404 are present, so include them unless explicitly disabled. */
6405 if (TARGET_MUL
&& (target_flags_explicit
& MASK_DIV
) == 0)
6406 target_flags
|= MASK_DIV
;
6407 else if (!TARGET_MUL
&& TARGET_DIV
)
6408 error ("%<-mdiv%> requires %<-march%> to subsume the %<M%> extension");
6410 /* Likewise floating-point division and square root. */
6411 if ((TARGET_HARD_FLOAT
|| TARGET_ZFINX
) && (target_flags_explicit
& MASK_FDIV
) == 0)
6412 target_flags
|= MASK_FDIV
;
6414 /* Handle -mtune, use -mcpu if -mtune is not given, and use default -mtune
6415 if both -mtune and -mcpu are not given. */
6416 cpu
= riscv_parse_tune (riscv_tune_string
? riscv_tune_string
:
6417 (riscv_cpu_string
? riscv_cpu_string
:
6418 RISCV_TUNE_STRING_DEFAULT
));
6419 riscv_microarchitecture
= cpu
->microarchitecture
;
6420 tune_param
= optimize_size
? &optimize_size_tune_info
: cpu
->tune_param
;
6422 /* Use -mtune's setting for slow_unaligned_access, even when optimizing
6423 for size. For architectures that trap and emulate unaligned accesses,
6424 the performance cost is too great, even for -Os. Similarly, if
6425 -m[no-]strict-align is left unspecified, heed -mtune's advice. */
6426 riscv_slow_unaligned_access_p
= (cpu
->tune_param
->slow_unaligned_access
6427 || TARGET_STRICT_ALIGN
);
6428 if ((target_flags_explicit
& MASK_STRICT_ALIGN
) == 0
6429 && cpu
->tune_param
->slow_unaligned_access
)
6430 target_flags
|= MASK_STRICT_ALIGN
;
6432 /* If the user hasn't specified a branch cost, use the processor's
6434 if (riscv_branch_cost
== 0)
6435 riscv_branch_cost
= tune_param
->branch_cost
;
6437 /* Function to allocate machine-dependent function status. */
6438 init_machine_status
= &riscv_init_machine_status
;
6441 riscv_cmodel
= CM_PIC
;
6443 /* We get better code with explicit relocs for CM_MEDLOW, but
6444 worse code for the others (for now). Pick the best default. */
6445 if ((target_flags_explicit
& MASK_EXPLICIT_RELOCS
) == 0)
6446 if (riscv_cmodel
== CM_MEDLOW
)
6447 target_flags
|= MASK_EXPLICIT_RELOCS
;
6449 /* Require that the ISA supports the requested floating-point ABI. */
6450 if (UNITS_PER_FP_ARG
> (TARGET_HARD_FLOAT
? UNITS_PER_FP_REG
: 0))
6451 error ("requested ABI requires %<-march%> to subsume the %qc extension",
6452 UNITS_PER_FP_ARG
> 8 ? 'Q' : (UNITS_PER_FP_ARG
> 4 ? 'D' : 'F'));
6454 if (TARGET_RVE
&& riscv_abi
!= ABI_ILP32E
)
6455 error ("rv32e requires ilp32e ABI");
6457 // Zfinx require abi ilp32,ilp32e or lp64.
6458 if (TARGET_ZFINX
&& riscv_abi
!= ABI_ILP32
6459 && riscv_abi
!= ABI_LP64
&& riscv_abi
!= ABI_ILP32E
)
6460 error ("z*inx requires ABI ilp32, ilp32e or lp64");
6462 /* We do not yet support ILP32 on RV64. */
6463 if (BITS_PER_WORD
!= POINTER_SIZE
)
6464 error ("ABI requires %<-march=rv%d%>", POINTER_SIZE
);
6466 /* Validate -mpreferred-stack-boundary= value. */
6467 riscv_stack_boundary
= ABI_STACK_BOUNDARY
;
6468 if (riscv_preferred_stack_boundary_arg
)
6470 int min
= ctz_hwi (STACK_BOUNDARY
/ 8);
6473 if (!IN_RANGE (riscv_preferred_stack_boundary_arg
, min
, max
))
6474 error ("%<-mpreferred-stack-boundary=%d%> must be between %d and %d",
6475 riscv_preferred_stack_boundary_arg
, min
, max
);
6477 riscv_stack_boundary
= 8 << riscv_preferred_stack_boundary_arg
;
6480 if (riscv_emit_attribute_p
< 0)
6481 #ifdef HAVE_AS_RISCV_ATTRIBUTE
6482 riscv_emit_attribute_p
= TARGET_RISCV_ATTRIBUTE
;
6484 riscv_emit_attribute_p
= 0;
6486 if (riscv_emit_attribute_p
)
6487 error ("%<-mriscv-attribute%> RISC-V ELF attribute requires GNU as 2.32"
6488 " [%<-mriscv-attribute%>]");
6491 if (riscv_stack_protector_guard
== SSP_GLOBAL
6492 && OPTION_SET_P (riscv_stack_protector_guard_offset_str
))
6494 error ("incompatible options %<-mstack-protector-guard=global%> and "
6495 "%<-mstack-protector-guard-offset=%s%>",
6496 riscv_stack_protector_guard_offset_str
);
6499 if (riscv_stack_protector_guard
== SSP_TLS
6500 && !(OPTION_SET_P (riscv_stack_protector_guard_offset_str
)
6501 && OPTION_SET_P (riscv_stack_protector_guard_reg_str
)))
6503 error ("both %<-mstack-protector-guard-offset%> and "
6504 "%<-mstack-protector-guard-reg%> must be used "
6505 "with %<-mstack-protector-guard=sysreg%>");
6508 if (OPTION_SET_P (riscv_stack_protector_guard_reg_str
))
6510 const char *str
= riscv_stack_protector_guard_reg_str
;
6511 int reg
= decode_reg_name (str
);
6513 if (!IN_RANGE (reg
, GP_REG_FIRST
+ 1, GP_REG_LAST
))
6514 error ("%qs is not a valid base register in %qs", str
,
6515 "-mstack-protector-guard-reg=");
6517 riscv_stack_protector_guard_reg
= reg
;
6520 if (OPTION_SET_P (riscv_stack_protector_guard_offset_str
))
6523 const char *str
= riscv_stack_protector_guard_offset_str
;
6525 long offs
= strtol (riscv_stack_protector_guard_offset_str
, &end
, 0);
6527 if (!*str
|| *end
|| errno
)
6528 error ("%qs is not a valid number in %qs", str
,
6529 "-mstack-protector-guard-offset=");
6531 if (!SMALL_OPERAND (offs
))
6532 error ("%qs is not a valid offset in %qs", str
,
6533 "-mstack-protector-guard-offset=");
6535 riscv_stack_protector_guard_offset
= offs
;
6538 /* Convert -march to a chunks count. */
6539 riscv_vector_chunks
= riscv_convert_vector_bits ();
6542 /* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */
6545 riscv_conditional_register_usage (void)
6547 /* We have only x0~x15 on RV32E. */
6550 for (int r
= 16; r
<= 31; r
++)
6554 if (riscv_abi
== ABI_ILP32E
)
6556 for (int r
= 16; r
<= 31; r
++)
6557 call_used_regs
[r
] = 1;
6560 if (!TARGET_HARD_FLOAT
)
6562 for (int regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
++)
6563 fixed_regs
[regno
] = call_used_regs
[regno
] = 1;
6566 /* In the soft-float ABI, there are no callee-saved FP registers. */
6567 if (UNITS_PER_FP_ARG
== 0)
6569 for (int regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
++)
6570 call_used_regs
[regno
] = 1;
6575 for (int regno
= V_REG_FIRST
; regno
<= V_REG_LAST
; regno
++)
6576 fixed_regs
[regno
] = call_used_regs
[regno
] = 1;
6578 fixed_regs
[VTYPE_REGNUM
] = call_used_regs
[VTYPE_REGNUM
] = 1;
6579 fixed_regs
[VL_REGNUM
] = call_used_regs
[VL_REGNUM
] = 1;
6580 fixed_regs
[VXRM_REGNUM
] = call_used_regs
[VXRM_REGNUM
] = 1;
6581 fixed_regs
[FRM_REGNUM
] = call_used_regs
[FRM_REGNUM
] = 1;
6585 /* Return a register priority for hard reg REGNO. */
6588 riscv_register_priority (int regno
)
6590 /* Favor compressed registers to improve the odds of RVC instruction
6592 if (riscv_compressed_reg_p (regno
))
6598 /* Implement TARGET_TRAMPOLINE_INIT. */
6601 riscv_trampoline_init (rtx m_tramp
, tree fndecl
, rtx chain_value
)
6603 rtx addr
, end_addr
, mem
;
6604 uint32_t trampoline
[4];
6606 HOST_WIDE_INT static_chain_offset
, target_function_offset
;
6608 /* Work out the offsets of the pointers from the start of the
6610 gcc_assert (ARRAY_SIZE (trampoline
) * 4 == TRAMPOLINE_CODE_SIZE
);
6612 /* Get pointers to the beginning and end of the code block. */
6613 addr
= force_reg (Pmode
, XEXP (m_tramp
, 0));
6614 end_addr
= riscv_force_binary (Pmode
, PLUS
, addr
,
6615 GEN_INT (TRAMPOLINE_CODE_SIZE
));
6618 if (Pmode
== SImode
)
6620 chain_value
= force_reg (Pmode
, chain_value
);
6622 rtx target_function
= force_reg (Pmode
, XEXP (DECL_RTL (fndecl
), 0));
6623 /* lui t2, hi(chain)
6625 addi t2, t2, lo(chain)
6628 unsigned HOST_WIDE_INT lui_hi_chain_code
, lui_hi_func_code
;
6629 unsigned HOST_WIDE_INT lo_chain_code
, lo_func_code
;
6631 rtx uimm_mask
= force_reg (SImode
, gen_int_mode (-IMM_REACH
, SImode
));
6634 rtx imm12_mask
= gen_reg_rtx (SImode
);
6635 emit_insn (gen_one_cmplsi2 (imm12_mask
, uimm_mask
));
6637 rtx fixup_value
= force_reg (SImode
, gen_int_mode (IMM_REACH
/2, SImode
));
6639 /* Gen lui t2, hi(chain). */
6640 rtx hi_chain
= riscv_force_binary (SImode
, PLUS
, chain_value
,
6642 hi_chain
= riscv_force_binary (SImode
, AND
, hi_chain
,
6644 lui_hi_chain_code
= OPCODE_LUI
| (STATIC_CHAIN_REGNUM
<< SHIFT_RD
);
6645 rtx lui_hi_chain
= riscv_force_binary (SImode
, IOR
, hi_chain
,
6646 gen_int_mode (lui_hi_chain_code
, SImode
));
6648 mem
= adjust_address (m_tramp
, SImode
, 0);
6649 riscv_emit_move (mem
, riscv_swap_instruction (lui_hi_chain
));
6651 /* Gen lui t0, hi(func). */
6652 rtx hi_func
= riscv_force_binary (SImode
, PLUS
, target_function
,
6654 hi_func
= riscv_force_binary (SImode
, AND
, hi_func
,
6656 lui_hi_func_code
= OPCODE_LUI
| (RISCV_PROLOGUE_TEMP_REGNUM
<< SHIFT_RD
);
6657 rtx lui_hi_func
= riscv_force_binary (SImode
, IOR
, hi_func
,
6658 gen_int_mode (lui_hi_func_code
, SImode
));
6660 mem
= adjust_address (m_tramp
, SImode
, 1 * GET_MODE_SIZE (SImode
));
6661 riscv_emit_move (mem
, riscv_swap_instruction (lui_hi_func
));
6663 /* Gen addi t2, t2, lo(chain). */
6664 rtx lo_chain
= riscv_force_binary (SImode
, AND
, chain_value
,
6666 lo_chain
= riscv_force_binary (SImode
, ASHIFT
, lo_chain
, GEN_INT (20));
6668 lo_chain_code
= OPCODE_ADDI
6669 | (STATIC_CHAIN_REGNUM
<< SHIFT_RD
)
6670 | (STATIC_CHAIN_REGNUM
<< SHIFT_RS1
);
6672 rtx addi_lo_chain
= riscv_force_binary (SImode
, IOR
, lo_chain
,
6673 force_reg (SImode
, GEN_INT (lo_chain_code
)));
6675 mem
= adjust_address (m_tramp
, SImode
, 2 * GET_MODE_SIZE (SImode
));
6676 riscv_emit_move (mem
, riscv_swap_instruction (addi_lo_chain
));
6678 /* Gen jr t0, lo(func). */
6679 rtx lo_func
= riscv_force_binary (SImode
, AND
, target_function
,
6681 lo_func
= riscv_force_binary (SImode
, ASHIFT
, lo_func
, GEN_INT (20));
6683 lo_func_code
= OPCODE_JALR
| (RISCV_PROLOGUE_TEMP_REGNUM
<< SHIFT_RS1
);
6685 rtx jr_lo_func
= riscv_force_binary (SImode
, IOR
, lo_func
,
6686 force_reg (SImode
, GEN_INT (lo_func_code
)));
6688 mem
= adjust_address (m_tramp
, SImode
, 3 * GET_MODE_SIZE (SImode
));
6689 riscv_emit_move (mem
, riscv_swap_instruction (jr_lo_func
));
6693 static_chain_offset
= TRAMPOLINE_CODE_SIZE
;
6694 target_function_offset
= static_chain_offset
+ GET_MODE_SIZE (ptr_mode
);
6697 l[wd] t0, target_function_offset(t2)
6698 l[wd] t2, static_chain_offset(t2)
6701 trampoline
[0] = OPCODE_AUIPC
| (STATIC_CHAIN_REGNUM
<< SHIFT_RD
);
6702 trampoline
[1] = (Pmode
== DImode
? OPCODE_LD
: OPCODE_LW
)
6703 | (RISCV_PROLOGUE_TEMP_REGNUM
<< SHIFT_RD
)
6704 | (STATIC_CHAIN_REGNUM
<< SHIFT_RS1
)
6705 | (target_function_offset
<< SHIFT_IMM
);
6706 trampoline
[2] = (Pmode
== DImode
? OPCODE_LD
: OPCODE_LW
)
6707 | (STATIC_CHAIN_REGNUM
<< SHIFT_RD
)
6708 | (STATIC_CHAIN_REGNUM
<< SHIFT_RS1
)
6709 | (static_chain_offset
<< SHIFT_IMM
);
6710 trampoline
[3] = OPCODE_JALR
| (RISCV_PROLOGUE_TEMP_REGNUM
<< SHIFT_RS1
);
6712 /* Copy the trampoline code. */
6713 for (i
= 0; i
< ARRAY_SIZE (trampoline
); i
++)
6715 if (BYTES_BIG_ENDIAN
)
6716 trampoline
[i
] = __builtin_bswap32(trampoline
[i
]);
6717 mem
= adjust_address (m_tramp
, SImode
, i
* GET_MODE_SIZE (SImode
));
6718 riscv_emit_move (mem
, gen_int_mode (trampoline
[i
], SImode
));
6721 /* Set up the static chain pointer field. */
6722 mem
= adjust_address (m_tramp
, ptr_mode
, static_chain_offset
);
6723 riscv_emit_move (mem
, chain_value
);
6725 /* Set up the target function field. */
6726 mem
= adjust_address (m_tramp
, ptr_mode
, target_function_offset
);
6727 riscv_emit_move (mem
, XEXP (DECL_RTL (fndecl
), 0));
6730 /* Flush the code part of the trampoline. */
6731 emit_insn (gen_add3_insn (end_addr
, addr
, GEN_INT (TRAMPOLINE_SIZE
)));
6732 emit_insn (gen_clear_cache (addr
, end_addr
));
6735 /* Implement TARGET_FUNCTION_OK_FOR_SIBCALL. */
6738 riscv_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED
,
6739 tree exp ATTRIBUTE_UNUSED
)
6741 /* Don't use sibcalls when use save-restore routine. */
6742 if (TARGET_SAVE_RESTORE
)
6745 /* Don't use sibcall for naked functions. */
6746 if (cfun
->machine
->naked_p
)
6749 /* Don't use sibcall for interrupt functions. */
6750 if (cfun
->machine
->interrupt_handler_p
)
6756 /* Get the interrupt type, return UNKNOWN_MODE if it's not
6757 interrupt function. */
6758 static enum riscv_privilege_levels
6759 riscv_get_interrupt_type (tree decl
)
6761 gcc_assert (decl
!= NULL_TREE
);
6763 if ((TREE_CODE(decl
) != FUNCTION_DECL
)
6764 || (!riscv_interrupt_type_p (TREE_TYPE (decl
))))
6765 return UNKNOWN_MODE
;
6768 = TREE_VALUE (lookup_attribute ("interrupt",
6769 TYPE_ATTRIBUTES (TREE_TYPE (decl
))));
6771 if (attr_args
&& TREE_CODE (TREE_VALUE (attr_args
)) != VOID_TYPE
)
6773 const char *string
= TREE_STRING_POINTER (TREE_VALUE (attr_args
));
6775 if (!strcmp (string
, "user"))
6777 else if (!strcmp (string
, "supervisor"))
6778 return SUPERVISOR_MODE
;
6779 else /* Must be "machine". */
6780 return MACHINE_MODE
;
6783 /* Interrupt attributes are machine mode by default. */
6784 return MACHINE_MODE
;
6787 /* Implement `TARGET_SET_CURRENT_FUNCTION'. */
6788 /* Sanity cheching for above function attributes. */
6790 riscv_set_current_function (tree decl
)
6792 if (decl
== NULL_TREE
6793 || current_function_decl
== NULL_TREE
6794 || current_function_decl
== error_mark_node
6796 || cfun
->machine
->attributes_checked_p
)
6799 cfun
->machine
->naked_p
= riscv_naked_function_p (decl
);
6800 cfun
->machine
->interrupt_handler_p
6801 = riscv_interrupt_type_p (TREE_TYPE (decl
));
6803 if (cfun
->machine
->naked_p
&& cfun
->machine
->interrupt_handler_p
)
6804 error ("function attributes %qs and %qs are mutually exclusive",
6805 "interrupt", "naked");
6807 if (cfun
->machine
->interrupt_handler_p
)
6809 tree ret
= TREE_TYPE (TREE_TYPE (decl
));
6810 tree args
= TYPE_ARG_TYPES (TREE_TYPE (decl
));
6812 if (TREE_CODE (ret
) != VOID_TYPE
)
6813 error ("%qs function cannot return a value", "interrupt");
6815 if (args
&& TREE_CODE (TREE_VALUE (args
)) != VOID_TYPE
)
6816 error ("%qs function cannot have arguments", "interrupt");
6818 cfun
->machine
->interrupt_mode
= riscv_get_interrupt_type (decl
);
6820 gcc_assert (cfun
->machine
->interrupt_mode
!= UNKNOWN_MODE
);
6823 /* Don't print the above diagnostics more than once. */
6824 cfun
->machine
->attributes_checked_p
= 1;
6827 /* Implement TARGET_MERGE_DECL_ATTRIBUTES. */
6829 riscv_merge_decl_attributes (tree olddecl
, tree newdecl
)
6831 tree combined_attrs
;
6833 enum riscv_privilege_levels old_interrupt_type
6834 = riscv_get_interrupt_type (olddecl
);
6835 enum riscv_privilege_levels new_interrupt_type
6836 = riscv_get_interrupt_type (newdecl
);
6838 /* Check old and new has same interrupt type. */
6839 if ((old_interrupt_type
!= UNKNOWN_MODE
)
6840 && (new_interrupt_type
!= UNKNOWN_MODE
)
6841 && (old_interrupt_type
!= new_interrupt_type
))
6842 error ("%qs function cannot have different interrupt type", "interrupt");
6844 /* Create combined attributes. */
6845 combined_attrs
= merge_attributes (DECL_ATTRIBUTES (olddecl
),
6846 DECL_ATTRIBUTES (newdecl
));
6848 return combined_attrs
;
6851 /* Implement TARGET_CANNOT_COPY_INSN_P. */
6854 riscv_cannot_copy_insn_p (rtx_insn
*insn
)
6856 return recog_memoized (insn
) >= 0 && get_attr_cannot_copy (insn
);
6859 /* Implement TARGET_SLOW_UNALIGNED_ACCESS. */
6862 riscv_slow_unaligned_access (machine_mode
, unsigned int)
6864 return riscv_slow_unaligned_access_p
;
6867 /* Implement TARGET_CAN_CHANGE_MODE_CLASS. */
6870 riscv_can_change_mode_class (machine_mode
, machine_mode
, reg_class_t rclass
)
6872 return !reg_classes_intersect_p (FP_REGS
, rclass
);
6876 /* Implement TARGET_CONSTANT_ALIGNMENT. */
6878 static HOST_WIDE_INT
6879 riscv_constant_alignment (const_tree exp
, HOST_WIDE_INT align
)
6881 if ((TREE_CODE (exp
) == STRING_CST
|| TREE_CODE (exp
) == CONSTRUCTOR
)
6882 && (riscv_align_data_type
== riscv_align_data_type_xlen
))
6883 return MAX (align
, BITS_PER_WORD
);
6887 /* Implement TARGET_PROMOTE_FUNCTION_MODE. */
6889 /* This function is equivalent to default_promote_function_mode_always_promote
6890 except that it returns a promoted mode even if type is NULL_TREE. This is
6891 needed by libcalls which have no type (only a mode) such as fixed conversion
6892 routines that take a signed or unsigned char/short/int argument and convert
6893 it to a fixed type. */
6896 riscv_promote_function_mode (const_tree type ATTRIBUTE_UNUSED
,
6898 int *punsignedp ATTRIBUTE_UNUSED
,
6899 const_tree fntype ATTRIBUTE_UNUSED
,
6900 int for_return ATTRIBUTE_UNUSED
)
6904 if (type
!= NULL_TREE
)
6905 return promote_mode (type
, mode
, punsignedp
);
6907 unsignedp
= *punsignedp
;
6908 PROMOTE_MODE (as_a
<scalar_mode
> (mode
), unsignedp
, type
);
6909 *punsignedp
= unsignedp
;
6913 /* Implement TARGET_MACHINE_DEPENDENT_REORG. */
6918 /* Do nothing unless we have -msave-restore */
6919 if (TARGET_SAVE_RESTORE
)
6920 riscv_remove_unneeded_save_restore_calls ();
6923 /* Return nonzero if register FROM_REGNO can be renamed to register
6927 riscv_hard_regno_rename_ok (unsigned from_regno ATTRIBUTE_UNUSED
,
6930 /* Interrupt functions can only use registers that have already been
6931 saved by the prologue, even if they would normally be
6933 return !cfun
->machine
->interrupt_handler_p
|| df_regs_ever_live_p (to_regno
);
6936 /* Implement TARGET_NEW_ADDRESS_PROFITABLE_P. */
6939 riscv_new_address_profitable_p (rtx memref
, rtx_insn
*insn
, rtx new_addr
)
6941 /* Prefer old address if it is less expensive. */
6942 addr_space_t as
= MEM_ADDR_SPACE (memref
);
6943 bool speed
= optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn
));
6944 int old_cost
= address_cost (XEXP (memref
, 0), GET_MODE (memref
), as
, speed
);
6945 int new_cost
= address_cost (new_addr
, GET_MODE (memref
), as
, speed
);
6946 return new_cost
<= old_cost
;
6949 /* Helper function for generating gpr_save pattern. */
6952 riscv_gen_gpr_save_insn (struct riscv_frame_info
*frame
)
6954 unsigned count
= riscv_save_libcall_count (frame
->mask
);
6955 /* 1 for unspec 2 for clobber t0/t1 and 1 for ra. */
6956 unsigned veclen
= 1 + 2 + 1 + count
;
6957 rtvec vec
= rtvec_alloc (veclen
);
6959 gcc_assert (veclen
<= ARRAY_SIZE (gpr_save_reg_order
));
6961 RTVEC_ELT (vec
, 0) =
6962 gen_rtx_UNSPEC_VOLATILE (VOIDmode
,
6963 gen_rtvec (1, GEN_INT (count
)), UNSPECV_GPR_SAVE
);
6965 for (unsigned i
= 1; i
< veclen
; ++i
)
6967 unsigned regno
= gpr_save_reg_order
[i
];
6968 rtx reg
= gen_rtx_REG (Pmode
, regno
);
6971 /* t0 and t1 are CLOBBERs, others are USEs. */
6973 elt
= gen_rtx_CLOBBER (Pmode
, reg
);
6975 elt
= gen_rtx_USE (Pmode
, reg
);
6977 RTVEC_ELT (vec
, i
) = elt
;
6980 /* Largest number of caller-save register must set in mask if we are
6981 not using __riscv_save_0. */
6982 gcc_assert ((count
== 0) ||
6983 BITSET_P (frame
->mask
, gpr_save_reg_order
[veclen
- 1]));
6985 return gen_rtx_PARALLEL (VOIDmode
, vec
);
6988 /* Return true if it's valid gpr_save pattern. */
6991 riscv_gpr_save_operation_p (rtx op
)
6993 unsigned len
= XVECLEN (op
, 0);
6995 if (len
> ARRAY_SIZE (gpr_save_reg_order
))
6998 for (unsigned i
= 0; i
< len
; i
++)
7000 rtx elt
= XVECEXP (op
, 0, i
);
7003 /* First element in parallel is unspec. */
7004 if (GET_CODE (elt
) != UNSPEC_VOLATILE
7005 || GET_CODE (XVECEXP (elt
, 0, 0)) != CONST_INT
7006 || XINT (elt
, 1) != UNSPECV_GPR_SAVE
)
7011 /* Two CLOBBER and USEs, must check the order. */
7012 unsigned expect_code
= i
< 3 ? CLOBBER
: USE
;
7013 if (GET_CODE (elt
) != expect_code
7014 || !REG_P (XEXP (elt
, 1))
7015 || (REGNO (XEXP (elt
, 1)) != gpr_save_reg_order
[i
]))
7023 /* Implement TARGET_ASAN_SHADOW_OFFSET. */
7025 static unsigned HOST_WIDE_INT
7026 riscv_asan_shadow_offset (void)
7028 /* We only have libsanitizer support for RV64 at present.
7030 This number must match ASAN_SHADOW_OFFSET_CONST in the file
7031 libsanitizer/asan/asan_mapping.h. */
7032 return TARGET_64BIT
? HOST_WIDE_INT_UC (0xd55550000) : 0;
7035 /* Implement TARGET_MANGLE_TYPE. */
7038 riscv_mangle_type (const_tree type
)
7040 /* Half-precision float, _Float16 is "DF16_". */
7041 if (SCALAR_FLOAT_TYPE_P (type
) && TYPE_PRECISION (type
) == 16)
7044 /* Mangle all vector type for vector extension. */
7045 /* The mangle name follows the rule of RVV LLVM
7046 that is "u" + length of (abi_name) + abi_name. */
7047 if (TYPE_NAME (type
) != NULL
)
7049 const char *res
= riscv_vector::mangle_builtin_type (type
);
7054 /* Use the default mangling. */
7058 /* Implement TARGET_SCALAR_MODE_SUPPORTED_P. */
7061 riscv_scalar_mode_supported_p (scalar_mode mode
)
7066 return default_scalar_mode_supported_p (mode
);
7069 /* Implement TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P - return TRUE
7070 if MODE is HFmode, and punt to the generic implementation otherwise. */
7073 riscv_libgcc_floating_mode_supported_p (scalar_float_mode mode
)
7078 return default_libgcc_floating_mode_supported_p (mode
);
7081 /* Set the value of FLT_EVAL_METHOD.
7082 ISO/IEC TS 18661-3 defines two values that we'd like to make use of:
7084 0: evaluate all operations and constants, whose semantic type has at
7085 most the range and precision of type float, to the range and
7086 precision of float; evaluate all other operations and constants to
7087 the range and precision of the semantic type;
7089 N, where _FloatN is a supported interchange floating type
7090 evaluate all operations and constants, whose semantic type has at
7091 most the range and precision of _FloatN type, to the range and
7092 precision of the _FloatN type; evaluate all other operations and
7093 constants to the range and precision of the semantic type;
7095 If we have the zfh/zhinx extensions then we support _Float16 in native
7096 precision, so we should set this to 16. */
7097 static enum flt_eval_method
7098 riscv_excess_precision (enum excess_precision_type type
)
7102 case EXCESS_PRECISION_TYPE_FAST
:
7103 case EXCESS_PRECISION_TYPE_STANDARD
:
7104 return ((TARGET_ZFH
|| TARGET_ZHINX
)
7105 ? FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16
7106 : FLT_EVAL_METHOD_PROMOTE_TO_FLOAT
);
7107 case EXCESS_PRECISION_TYPE_IMPLICIT
:
7108 case EXCESS_PRECISION_TYPE_FLOAT16
:
7109 return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16
;
7113 return FLT_EVAL_METHOD_UNPREDICTABLE
;
7116 /* Implement TARGET_FLOATN_MODE. */
7117 static opt_scalar_float_mode
7118 riscv_floatn_mode (int n
, bool extended
)
7120 if (!extended
&& n
== 16)
7123 return default_floatn_mode (n
, extended
);
7127 riscv_init_libfuncs (void)
7129 /* Half-precision float operations. The compiler handles all operations
7130 with NULL libfuncs by converting to SFmode. */
7133 set_optab_libfunc (add_optab
, HFmode
, NULL
);
7134 set_optab_libfunc (sdiv_optab
, HFmode
, NULL
);
7135 set_optab_libfunc (smul_optab
, HFmode
, NULL
);
7136 set_optab_libfunc (neg_optab
, HFmode
, NULL
);
7137 set_optab_libfunc (sub_optab
, HFmode
, NULL
);
7140 set_optab_libfunc (eq_optab
, HFmode
, NULL
);
7141 set_optab_libfunc (ne_optab
, HFmode
, NULL
);
7142 set_optab_libfunc (lt_optab
, HFmode
, NULL
);
7143 set_optab_libfunc (le_optab
, HFmode
, NULL
);
7144 set_optab_libfunc (ge_optab
, HFmode
, NULL
);
7145 set_optab_libfunc (gt_optab
, HFmode
, NULL
);
7146 set_optab_libfunc (unord_optab
, HFmode
, NULL
);
7153 riscv_option_override ();
7154 init_adjust_machine_modes ();
7155 init_derived_machine_modes ();
7162 #undef TARGET_RUN_TARGET_SELFTESTS
7163 #define TARGET_RUN_TARGET_SELFTESTS selftest::riscv_run_selftests
7164 #endif /* #if CHECKING_P */
7166 /* Implement TARGET_VECTOR_MODE_SUPPORTED_P. */
7169 riscv_vector_mode_supported_p (machine_mode mode
)
7172 return riscv_v_ext_mode_p (mode
);
7177 /* Implement TARGET_VERIFY_TYPE_CONTEXT. */
7180 riscv_verify_type_context (location_t loc
, type_context_kind context
,
7181 const_tree type
, bool silent_p
)
7183 return riscv_vector::verify_type_context (loc
, context
, type
, silent_p
);
7186 /* Implement TARGET_VECTOR_ALIGNMENT. */
7188 static HOST_WIDE_INT
7189 riscv_vector_alignment (const_tree type
)
7191 /* ??? Checking the mode isn't ideal, but VECTOR_BOOLEAN_TYPE_P can
7192 be set for non-predicate vectors of booleans. Modes are the most
7193 direct way we have of identifying real RVV predicate types. */
7194 /* FIXME: RVV didn't mention the alignment of bool, we uses
7196 if (GET_MODE_CLASS (TYPE_MODE (type
)) == MODE_VECTOR_BOOL
)
7200 = constant_lower_bound (wi::to_poly_widest (TYPE_SIZE (type
)));
7201 return wi::umin (min_size
, 128).to_uhwi ();
7204 /* Implement REGMODE_NATURAL_SIZE. */
7207 riscv_regmode_natural_size (machine_mode mode
)
7209 /* The natural size for RVV data modes is one RVV data vector,
7210 and similarly for predicates. We can't independently modify
7211 anything smaller than that. */
7212 /* ??? For now, only do this for variable-width RVV registers.
7213 Doing it for constant-sized registers breaks lower-subreg.c. */
7214 if (!riscv_vector_chunks
.is_constant () && riscv_v_ext_mode_p (mode
))
7216 if (riscv_v_ext_tuple_mode_p (mode
))
7219 = GET_MODE_SIZE (riscv_vector::get_subpart_mode (mode
));
7220 if (known_lt (size
, BYTES_PER_RISCV_VECTOR
))
7223 return BYTES_PER_RISCV_VECTOR
;
7225 return UNITS_PER_WORD
;
7228 /* Implement the TARGET_DWARF_POLY_INDETERMINATE_VALUE hook. */
7231 riscv_dwarf_poly_indeterminate_value (unsigned int i
, unsigned int *factor
,
7234 /* Polynomial invariant 1 == (VLENB / riscv_bytes_per_vector_chunk) - 1.
7235 1. TARGET_MIN_VLEN == 32, polynomial invariant 1 == (VLENB / 4) - 1.
7236 2. TARGET_MIN_VLEN > 32, polynomial invariant 1 == (VLENB / 8) - 1.
7238 gcc_assert (i
== 1);
7239 *factor
= riscv_bytes_per_vector_chunk
;
7241 return RISCV_DWARF_VLENB
;
7244 /* Implement TARGET_ESTIMATED_POLY_VALUE.
7245 Look into the tuning structure for an estimate.
7246 KIND specifies the type of requested estimate: min, max or likely.
7247 For cores with a known RVV width all three estimates are the same.
7248 For generic RVV tuning we want to distinguish the maximum estimate from
7249 the minimum and likely ones.
7250 The likely estimate is the same as the minimum in that case to give a
7251 conservative behavior of auto-vectorizing with RVV when it is a win
7252 even for 128-bit RVV.
7253 When RVV width information is available VAL.coeffs[1] is multiplied by
7254 the number of VQ chunks over the initial Advanced SIMD 128 bits. */
7256 static HOST_WIDE_INT
7257 riscv_estimated_poly_value (poly_int64 val
,
7258 poly_value_estimate_kind kind
= POLY_VALUE_LIKELY
)
7260 unsigned int width_source
= BITS_PER_RISCV_VECTOR
.is_constant ()
7261 ? (unsigned int) BITS_PER_RISCV_VECTOR
.to_constant ()
7262 : (unsigned int) RVV_SCALABLE
;
7264 /* If there is no core-specific information then the minimum and likely
7265 values are based on 128-bit vectors and the maximum is based on
7266 the architectural maximum of 65536 bits. */
7267 if (width_source
== RVV_SCALABLE
)
7270 case POLY_VALUE_MIN
:
7271 case POLY_VALUE_LIKELY
:
7272 return val
.coeffs
[0];
7274 case POLY_VALUE_MAX
:
7275 return val
.coeffs
[0] + val
.coeffs
[1] * 15;
7278 /* Allow BITS_PER_RISCV_VECTOR to be a bitmask of different VL, treating the
7279 lowest as likely. This could be made more general if future -mtune
7280 options need it to be. */
7281 if (kind
== POLY_VALUE_MAX
)
7282 width_source
= 1 << floor_log2 (width_source
);
7284 width_source
= least_bit_hwi (width_source
);
7286 /* If the core provides width information, use that. */
7287 HOST_WIDE_INT over_128
= width_source
- 128;
7288 return val
.coeffs
[0] + val
.coeffs
[1] * over_128
/ 128;
7291 /* Return true if the vector misalignment factor is supported by the
7294 riscv_support_vector_misalignment (machine_mode mode
,
7295 const_tree type ATTRIBUTE_UNUSED
,
7297 bool is_packed ATTRIBUTE_UNUSED
)
7299 /* TODO: For RVV scalable vector auto-vectorization, we should allow
7300 movmisalign<mode> pattern to handle misalign data movement to unblock
7301 possible auto-vectorization.
7303 RVV VLS auto-vectorization or SIMD auto-vectorization can be supported here
7305 return default_builtin_support_vector_misalignment (mode
, type
, misalignment
,
7309 /* Implement TARGET_VECTORIZE_GET_MASK_MODE. */
7311 static opt_machine_mode
7312 riscv_get_mask_mode (machine_mode mode
)
7314 machine_mode mask_mode
= VOIDmode
;
7315 if (TARGET_VECTOR
&& riscv_vector::get_mask_mode (mode
).exists (&mask_mode
))
7318 return default_get_mask_mode (mode
);
7321 /* Implement TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE. Assume for now that
7322 it isn't worth branching around empty masked ops (including masked
7326 riscv_empty_mask_is_expensive (unsigned)
7331 /* Return true if a shift-amount matches the trailing cleared bits on
7335 riscv_shamt_matches_mask_p (int shamt
, HOST_WIDE_INT mask
)
7337 return shamt
== ctz_hwi (mask
);
7341 vector_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs
)
7343 HARD_REG_SET zeroed_hardregs
;
7344 CLEAR_HARD_REG_SET (zeroed_hardregs
);
7346 /* Find a register to hold vl. */
7347 unsigned vl_regno
= INVALID_REGNUM
;
7348 /* Skip the first GPR, otherwise the existing vl is kept due to the same
7349 between vl and avl. */
7350 for (unsigned regno
= GP_REG_FIRST
+ 1; regno
<= GP_REG_LAST
; regno
++)
7352 if (TEST_HARD_REG_BIT (need_zeroed_hardregs
, regno
))
7359 if (vl_regno
> GP_REG_LAST
)
7360 sorry ("cannot allocate vl register for %qs on this target",
7361 "-fzero-call-used-regs");
7363 /* Vector configurations need not be saved and restored here. The
7364 -fzero-call-used-regs=* option will zero all vector registers and
7365 return. So there's no vector operations between them. */
7367 bool emitted_vlmax_vsetvl
= false;
7368 rtx vl
= gen_rtx_REG (Pmode
, vl_regno
); /* vl is VLMAX. */
7369 for (unsigned regno
= V_REG_FIRST
; regno
<= V_REG_LAST
; ++regno
)
7371 if (TEST_HARD_REG_BIT (need_zeroed_hardregs
, regno
))
7373 rtx target
= regno_reg_rtx
[regno
];
7374 machine_mode mode
= GET_MODE (target
);
7376 if (!emitted_vlmax_vsetvl
)
7378 riscv_vector::emit_hard_vlmax_vsetvl (mode
, vl
);
7379 emitted_vlmax_vsetvl
= true;
7382 rtx ops
[] = {target
, CONST0_RTX (mode
)};
7383 riscv_vector::emit_vlmax_insn (code_for_pred_mov (mode
),
7384 riscv_vector::RVV_UNOP
, ops
, vl
);
7386 SET_HARD_REG_BIT (zeroed_hardregs
, regno
);
7390 return zeroed_hardregs
;
7393 /* Generate a sequence of instructions that zero registers specified by
7394 NEED_ZEROED_HARDREGS. Return the ZEROED_HARDREGS that are actually
7397 riscv_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs
)
7399 HARD_REG_SET zeroed_hardregs
;
7400 CLEAR_HARD_REG_SET (zeroed_hardregs
);
7403 zeroed_hardregs
|= vector_zero_call_used_regs (need_zeroed_hardregs
);
7405 return zeroed_hardregs
| default_zero_call_used_regs (need_zeroed_hardregs
7406 & ~zeroed_hardregs
);
7409 /* Implement target hook TARGET_ARRAY_MODE. */
7411 static opt_machine_mode
7412 riscv_array_mode (machine_mode mode
, unsigned HOST_WIDE_INT nelems
)
7416 && riscv_vector::get_tuple_mode (mode
, nelems
).exists (&vmode
))
7419 return opt_machine_mode ();
7422 /* Given memory reference MEM, expand code to compute the aligned
7423 memory address, shift and mask values and store them into
7424 *ALIGNED_MEM, *SHIFT, *MASK and *NOT_MASK. */
7427 riscv_subword_address (rtx mem
, rtx
*aligned_mem
, rtx
*shift
, rtx
*mask
,
7430 /* Align the memory address to a word. */
7431 rtx addr
= force_reg (Pmode
, XEXP (mem
, 0));
7433 rtx addr_mask
= gen_int_mode (-4, Pmode
);
7435 rtx aligned_addr
= gen_reg_rtx (Pmode
);
7436 emit_move_insn (aligned_addr
, gen_rtx_AND (Pmode
, addr
, addr_mask
));
7438 *aligned_mem
= change_address (mem
, SImode
, aligned_addr
);
7440 /* Calculate the shift amount. */
7441 emit_move_insn (*shift
, gen_rtx_AND (SImode
, gen_lowpart (SImode
, addr
),
7442 gen_int_mode (3, SImode
)));
7443 emit_move_insn (*shift
, gen_rtx_ASHIFT (SImode
, *shift
,
7444 gen_int_mode (3, SImode
)));
7446 /* Calculate the mask. */
7447 int unshifted_mask
= GET_MODE_MASK (GET_MODE (mem
));
7449 emit_move_insn (*mask
, gen_int_mode (unshifted_mask
, SImode
));
7451 emit_move_insn (*mask
, gen_rtx_ASHIFT (SImode
, *mask
,
7452 gen_lowpart (QImode
, *shift
)));
7454 emit_move_insn (*not_mask
, gen_rtx_NOT (SImode
, *mask
));
7457 /* Leftshift a subword within an SImode register. */
7460 riscv_lshift_subword (machine_mode mode
, rtx value
, rtx shift
,
7463 rtx value_reg
= gen_reg_rtx (SImode
);
7464 emit_move_insn (value_reg
, simplify_gen_subreg (SImode
, value
,
7467 emit_move_insn (*shifted_value
, gen_rtx_ASHIFT (SImode
, value_reg
,
7468 gen_lowpart (QImode
, shift
)));
7471 /* Return TRUE if we should use the divmod expander, FALSE otherwise. This
7472 allows the behavior to be tuned for specific implementations as well as
7473 when optimizing for size. */
7476 riscv_use_divmod_expander (void)
7478 return tune_param
->use_divmod_expansion
;
7481 /* Implement TARGET_VECTORIZE_PREFERRED_SIMD_MODE. */
7484 riscv_preferred_simd_mode (scalar_mode mode
)
7487 return riscv_vector::preferred_simd_mode (mode
);
7492 /* Implement target hook TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT. */
7495 riscv_vectorize_preferred_vector_alignment (const_tree type
)
7497 if (riscv_v_ext_vector_mode_p (TYPE_MODE (type
)))
7498 return TYPE_ALIGN (TREE_TYPE (type
));
7499 return TYPE_ALIGN (type
);
7502 /* Implement Mode switching. */
7505 riscv_emit_mode_set (int entity
, int mode
, int prev_mode
,
7506 HARD_REG_SET regs_live ATTRIBUTE_UNUSED
)
7511 if (mode
!= VXRM_MODE_NONE
&& mode
!= prev_mode
)
7512 emit_insn (gen_vxrmsi (gen_int_mode (mode
, SImode
)));
7519 /* Return mode that entity must be switched into
7520 prior to the execution of insn. */
7523 riscv_mode_needed (int entity
, rtx_insn
*insn
)
7528 return recog_memoized (insn
) >= 0 ? get_attr_vxrm_mode (insn
)
7535 /* Return true if the VXRM/FRM status of the INSN is unknown. */
7537 global_state_unknown_p (rtx_insn
*insn
, unsigned int regno
)
7539 struct df_insn_info
*insn_info
= DF_INSN_INFO_GET (insn
);
7542 /* Return true if there is a definition of VXRM. */
7543 for (ref
= DF_INSN_INFO_DEFS (insn_info
); ref
; ref
= DF_REF_NEXT_LOC (ref
))
7544 if (DF_REF_REGNO (ref
) == regno
)
7547 /* A CALL function may contain an instruction that modifies the VXRM,
7548 return true in this situation. */
7552 /* Return true for all assembly since users may hardcode a assembly
7553 like this: asm volatile ("csrwi vxrm, 0"). */
7554 extract_insn (insn
);
7555 if (recog_data
.is_asm
)
7560 /* Return the mode that an insn results in. */
7563 riscv_mode_after (int entity
, int mode
, rtx_insn
*insn
)
7568 if (global_state_unknown_p (insn
, VXRM_REGNUM
))
7569 return VXRM_MODE_NONE
;
7570 else if (recog_memoized (insn
) >= 0)
7571 return reg_mentioned_p (gen_rtx_REG (SImode
, VXRM_REGNUM
),
7573 ? get_attr_vxrm_mode (insn
)
7582 /* Return a mode that ENTITY is assumed to be
7583 switched to at function entry. */
7586 riscv_mode_entry (int entity
)
7591 return VXRM_MODE_NONE
;
7597 /* Return a mode that ENTITY is assumed to be
7598 switched to at function exit. */
7601 riscv_mode_exit (int entity
)
7606 return VXRM_MODE_NONE
;
7613 riscv_mode_priority (int, int n
)
7618 /* Implement TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES. */
7620 riscv_autovectorize_vector_modes (vector_modes
*modes
, bool all
)
7623 return riscv_vector::autovectorize_vector_modes (modes
, all
);
7625 return default_autovectorize_vector_modes (modes
, all
);
7628 /* Implement TARGET_VECTORIZE_RELATED_MODE. */
7630 riscv_vectorize_related_mode (machine_mode vector_mode
, scalar_mode element_mode
,
7634 return riscv_vector::vectorize_related_mode (vector_mode
, element_mode
,
7636 return default_vectorize_related_mode (vector_mode
, element_mode
, nunits
);
7639 /* Implement TARGET_VECTORIZE_VEC_PERM_CONST. */
7642 riscv_vectorize_vec_perm_const (machine_mode vmode
, machine_mode op_mode
,
7643 rtx target
, rtx op0
, rtx op1
,
7644 const vec_perm_indices
&sel
)
7646 if (TARGET_VECTOR
&& riscv_v_ext_vector_mode_p (vmode
))
7647 return riscv_vector::expand_vec_perm_const (vmode
, op_mode
, target
, op0
,
7653 /* Initialize the GCC target structure. */
7654 #undef TARGET_ASM_ALIGNED_HI_OP
7655 #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
7656 #undef TARGET_ASM_ALIGNED_SI_OP
7657 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
7658 #undef TARGET_ASM_ALIGNED_DI_OP
7659 #define TARGET_ASM_ALIGNED_DI_OP "\t.dword\t"
7661 #undef TARGET_OPTION_OVERRIDE
7662 #define TARGET_OPTION_OVERRIDE riscv_option_override
7664 #undef TARGET_LEGITIMIZE_ADDRESS
7665 #define TARGET_LEGITIMIZE_ADDRESS riscv_legitimize_address
7667 #undef TARGET_SCHED_ISSUE_RATE
7668 #define TARGET_SCHED_ISSUE_RATE riscv_issue_rate
7670 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
7671 #define TARGET_FUNCTION_OK_FOR_SIBCALL riscv_function_ok_for_sibcall
7673 #undef TARGET_SET_CURRENT_FUNCTION
7674 #define TARGET_SET_CURRENT_FUNCTION riscv_set_current_function
7676 #undef TARGET_REGISTER_MOVE_COST
7677 #define TARGET_REGISTER_MOVE_COST riscv_register_move_cost
7678 #undef TARGET_MEMORY_MOVE_COST
7679 #define TARGET_MEMORY_MOVE_COST riscv_memory_move_cost
7680 #undef TARGET_RTX_COSTS
7681 #define TARGET_RTX_COSTS riscv_rtx_costs
7682 #undef TARGET_ADDRESS_COST
7683 #define TARGET_ADDRESS_COST riscv_address_cost
7685 #undef TARGET_ASM_FILE_START
7686 #define TARGET_ASM_FILE_START riscv_file_start
7687 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
7688 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
7690 #undef TARGET_EXPAND_BUILTIN_VA_START
7691 #define TARGET_EXPAND_BUILTIN_VA_START riscv_va_start
7693 #undef TARGET_PROMOTE_FUNCTION_MODE
7694 #define TARGET_PROMOTE_FUNCTION_MODE riscv_promote_function_mode
7696 #undef TARGET_RETURN_IN_MEMORY
7697 #define TARGET_RETURN_IN_MEMORY riscv_return_in_memory
7699 #undef TARGET_ASM_OUTPUT_MI_THUNK
7700 #define TARGET_ASM_OUTPUT_MI_THUNK riscv_output_mi_thunk
7701 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
7702 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
7704 #undef TARGET_PRINT_OPERAND
7705 #define TARGET_PRINT_OPERAND riscv_print_operand
7706 #undef TARGET_PRINT_OPERAND_ADDRESS
7707 #define TARGET_PRINT_OPERAND_ADDRESS riscv_print_operand_address
7708 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
7709 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P riscv_print_operand_punct_valid_p
7711 #undef TARGET_SETUP_INCOMING_VARARGS
7712 #define TARGET_SETUP_INCOMING_VARARGS riscv_setup_incoming_varargs
7713 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
7714 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS riscv_allocate_stack_slots_for_args
7715 #undef TARGET_STRICT_ARGUMENT_NAMING
7716 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
7717 #undef TARGET_MUST_PASS_IN_STACK
7718 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
7719 #undef TARGET_PASS_BY_REFERENCE
7720 #define TARGET_PASS_BY_REFERENCE riscv_pass_by_reference
7721 #undef TARGET_ARG_PARTIAL_BYTES
7722 #define TARGET_ARG_PARTIAL_BYTES riscv_arg_partial_bytes
7723 #undef TARGET_FUNCTION_ARG
7724 #define TARGET_FUNCTION_ARG riscv_function_arg
7725 #undef TARGET_FUNCTION_ARG_ADVANCE
7726 #define TARGET_FUNCTION_ARG_ADVANCE riscv_function_arg_advance
7727 #undef TARGET_FUNCTION_ARG_BOUNDARY
7728 #define TARGET_FUNCTION_ARG_BOUNDARY riscv_function_arg_boundary
7730 #undef TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS
7731 #define TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS \
7732 riscv_get_separate_components
7734 #undef TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB
7735 #define TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB \
7736 riscv_components_for_bb
7738 #undef TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS
7739 #define TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS \
7740 riscv_disqualify_components
7742 #undef TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS
7743 #define TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS \
7744 riscv_emit_prologue_components
7746 #undef TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS
7747 #define TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS \
7748 riscv_emit_epilogue_components
7750 #undef TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS
7751 #define TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS \
7752 riscv_set_handled_components
7754 /* The generic ELF target does not always have TLS support. */
7756 #undef TARGET_HAVE_TLS
7757 #define TARGET_HAVE_TLS true
7760 #undef TARGET_CANNOT_FORCE_CONST_MEM
7761 #define TARGET_CANNOT_FORCE_CONST_MEM riscv_cannot_force_const_mem
7763 #undef TARGET_LEGITIMATE_CONSTANT_P
7764 #define TARGET_LEGITIMATE_CONSTANT_P riscv_legitimate_constant_p
7766 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
7767 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P hook_bool_mode_const_rtx_true
7769 #undef TARGET_LEGITIMATE_ADDRESS_P
7770 #define TARGET_LEGITIMATE_ADDRESS_P riscv_legitimate_address_p
7772 #undef TARGET_CAN_ELIMINATE
7773 #define TARGET_CAN_ELIMINATE riscv_can_eliminate
7775 #undef TARGET_CONDITIONAL_REGISTER_USAGE
7776 #define TARGET_CONDITIONAL_REGISTER_USAGE riscv_conditional_register_usage
7778 #undef TARGET_CLASS_MAX_NREGS
7779 #define TARGET_CLASS_MAX_NREGS riscv_class_max_nregs
7781 #undef TARGET_TRAMPOLINE_INIT
7782 #define TARGET_TRAMPOLINE_INIT riscv_trampoline_init
7784 #undef TARGET_IN_SMALL_DATA_P
7785 #define TARGET_IN_SMALL_DATA_P riscv_in_small_data_p
7787 #undef TARGET_HAVE_SRODATA_SECTION
7788 #define TARGET_HAVE_SRODATA_SECTION true
7790 #undef TARGET_ASM_SELECT_SECTION
7791 #define TARGET_ASM_SELECT_SECTION riscv_select_section
7793 #undef TARGET_ASM_UNIQUE_SECTION
7794 #define TARGET_ASM_UNIQUE_SECTION riscv_unique_section
7796 #undef TARGET_ASM_SELECT_RTX_SECTION
7797 #define TARGET_ASM_SELECT_RTX_SECTION riscv_elf_select_rtx_section
7799 #undef TARGET_MIN_ANCHOR_OFFSET
7800 #define TARGET_MIN_ANCHOR_OFFSET (-IMM_REACH/2)
7802 #undef TARGET_MAX_ANCHOR_OFFSET
7803 #define TARGET_MAX_ANCHOR_OFFSET (IMM_REACH/2-1)
7805 #undef TARGET_REGISTER_PRIORITY
7806 #define TARGET_REGISTER_PRIORITY riscv_register_priority
7808 #undef TARGET_CANNOT_COPY_INSN_P
7809 #define TARGET_CANNOT_COPY_INSN_P riscv_cannot_copy_insn_p
7811 #undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
7812 #define TARGET_ATOMIC_ASSIGN_EXPAND_FENV riscv_atomic_assign_expand_fenv
7814 #undef TARGET_INIT_BUILTINS
7815 #define TARGET_INIT_BUILTINS riscv_init_builtins
7817 #undef TARGET_BUILTIN_DECL
7818 #define TARGET_BUILTIN_DECL riscv_builtin_decl
7820 #undef TARGET_GIMPLE_FOLD_BUILTIN
7821 #define TARGET_GIMPLE_FOLD_BUILTIN riscv_gimple_fold_builtin
7823 #undef TARGET_EXPAND_BUILTIN
7824 #define TARGET_EXPAND_BUILTIN riscv_expand_builtin
7826 #undef TARGET_HARD_REGNO_NREGS
7827 #define TARGET_HARD_REGNO_NREGS riscv_hard_regno_nregs
7828 #undef TARGET_HARD_REGNO_MODE_OK
7829 #define TARGET_HARD_REGNO_MODE_OK riscv_hard_regno_mode_ok
7831 #undef TARGET_MODES_TIEABLE_P
7832 #define TARGET_MODES_TIEABLE_P riscv_modes_tieable_p
7834 #undef TARGET_SLOW_UNALIGNED_ACCESS
7835 #define TARGET_SLOW_UNALIGNED_ACCESS riscv_slow_unaligned_access
7837 #undef TARGET_SECONDARY_MEMORY_NEEDED
7838 #define TARGET_SECONDARY_MEMORY_NEEDED riscv_secondary_memory_needed
7840 #undef TARGET_CAN_CHANGE_MODE_CLASS
7841 #define TARGET_CAN_CHANGE_MODE_CLASS riscv_can_change_mode_class
7843 #undef TARGET_CONSTANT_ALIGNMENT
7844 #define TARGET_CONSTANT_ALIGNMENT riscv_constant_alignment
7846 #undef TARGET_MERGE_DECL_ATTRIBUTES
7847 #define TARGET_MERGE_DECL_ATTRIBUTES riscv_merge_decl_attributes
7849 #undef TARGET_ATTRIBUTE_TABLE
7850 #define TARGET_ATTRIBUTE_TABLE riscv_attribute_table
7852 #undef TARGET_WARN_FUNC_RETURN
7853 #define TARGET_WARN_FUNC_RETURN riscv_warn_func_return
7855 /* The low bit is ignored by jump instructions so is safe to use. */
7856 #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
7857 #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 1
7859 #undef TARGET_MACHINE_DEPENDENT_REORG
7860 #define TARGET_MACHINE_DEPENDENT_REORG riscv_reorg
7862 #undef TARGET_NEW_ADDRESS_PROFITABLE_P
7863 #define TARGET_NEW_ADDRESS_PROFITABLE_P riscv_new_address_profitable_p
7865 #undef TARGET_MANGLE_TYPE
7866 #define TARGET_MANGLE_TYPE riscv_mangle_type
7868 #undef TARGET_SCALAR_MODE_SUPPORTED_P
7869 #define TARGET_SCALAR_MODE_SUPPORTED_P riscv_scalar_mode_supported_p
7871 #undef TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P
7872 #define TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P \
7873 riscv_libgcc_floating_mode_supported_p
7875 #undef TARGET_INIT_LIBFUNCS
7876 #define TARGET_INIT_LIBFUNCS riscv_init_libfuncs
7878 #undef TARGET_C_EXCESS_PRECISION
7879 #define TARGET_C_EXCESS_PRECISION riscv_excess_precision
7881 #undef TARGET_FLOATN_MODE
7882 #define TARGET_FLOATN_MODE riscv_floatn_mode
7884 #undef TARGET_ASAN_SHADOW_OFFSET
7885 #define TARGET_ASAN_SHADOW_OFFSET riscv_asan_shadow_offset
7887 #ifdef TARGET_BIG_ENDIAN_DEFAULT
7888 #undef TARGET_DEFAULT_TARGET_FLAGS
7889 #define TARGET_DEFAULT_TARGET_FLAGS (MASK_BIG_ENDIAN)
7892 #undef TARGET_VECTOR_MODE_SUPPORTED_P
7893 #define TARGET_VECTOR_MODE_SUPPORTED_P riscv_vector_mode_supported_p
7895 #undef TARGET_VERIFY_TYPE_CONTEXT
7896 #define TARGET_VERIFY_TYPE_CONTEXT riscv_verify_type_context
7898 #undef TARGET_ESTIMATED_POLY_VALUE
7899 #define TARGET_ESTIMATED_POLY_VALUE riscv_estimated_poly_value
7901 #undef TARGET_VECTORIZE_GET_MASK_MODE
7902 #define TARGET_VECTORIZE_GET_MASK_MODE riscv_get_mask_mode
7904 #undef TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE
7905 #define TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE riscv_empty_mask_is_expensive
7907 #undef TARGET_VECTOR_ALIGNMENT
7908 #define TARGET_VECTOR_ALIGNMENT riscv_vector_alignment
7910 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
7911 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT riscv_support_vector_misalignment
7913 #undef TARGET_DWARF_POLY_INDETERMINATE_VALUE
7914 #define TARGET_DWARF_POLY_INDETERMINATE_VALUE riscv_dwarf_poly_indeterminate_value
7916 #undef TARGET_ZERO_CALL_USED_REGS
7917 #define TARGET_ZERO_CALL_USED_REGS riscv_zero_call_used_regs
7919 #undef TARGET_ARRAY_MODE
7920 #define TARGET_ARRAY_MODE riscv_array_mode
7922 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
7923 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE riscv_preferred_simd_mode
7925 #undef TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT
7926 #define TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT \
7927 riscv_vectorize_preferred_vector_alignment
7929 /* Mode switching hooks. */
7931 #undef TARGET_MODE_EMIT
7932 #define TARGET_MODE_EMIT riscv_emit_mode_set
7933 #undef TARGET_MODE_NEEDED
7934 #define TARGET_MODE_NEEDED riscv_mode_needed
7935 #undef TARGET_MODE_AFTER
7936 #define TARGET_MODE_AFTER riscv_mode_after
7937 #undef TARGET_MODE_ENTRY
7938 #define TARGET_MODE_ENTRY riscv_mode_entry
7939 #undef TARGET_MODE_EXIT
7940 #define TARGET_MODE_EXIT riscv_mode_exit
7941 #undef TARGET_MODE_PRIORITY
7942 #define TARGET_MODE_PRIORITY riscv_mode_priority
7944 #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES
7945 #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES \
7946 riscv_autovectorize_vector_modes
7948 #undef TARGET_VECTORIZE_RELATED_MODE
7949 #define TARGET_VECTORIZE_RELATED_MODE riscv_vectorize_related_mode
7951 #undef TARGET_VECTORIZE_VEC_PERM_CONST
7952 #define TARGET_VECTORIZE_VEC_PERM_CONST riscv_vectorize_vec_perm_const
7954 struct gcc_target targetm
= TARGET_INITIALIZER
;
7956 #include "gt-riscv.h"