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 "shrink-wrap.h"
68 #include "sel-sched.h"
69 #include "sched-int.h"
70 #include "fold-const.h"
71 #include "gimple-iterator.h"
72 #include "gimple-expr.h"
73 #include "tree-vectorizer.h"
77 /* This file should be included last. */
78 #include "target-def.h"
79 #include "riscv-vector-costs.h"
81 /* True if X is an UNSPEC wrapper around a SYMBOL_REF or LABEL_REF. */
82 #define UNSPEC_ADDRESS_P(X) \
83 (GET_CODE (X) == UNSPEC \
84 && XINT (X, 1) >= UNSPEC_ADDRESS_FIRST \
85 && XINT (X, 1) < UNSPEC_ADDRESS_FIRST + NUM_SYMBOL_TYPES)
87 /* Extract the symbol or label from UNSPEC wrapper X. */
88 #define UNSPEC_ADDRESS(X) \
91 /* Extract the symbol type from UNSPEC wrapper X. */
92 #define UNSPEC_ADDRESS_TYPE(X) \
93 ((enum riscv_symbol_type) (XINT (X, 1) - UNSPEC_ADDRESS_FIRST))
95 /* True if bit BIT is set in VALUE. */
96 #define BITSET_P(VALUE, BIT) (((VALUE) & (1ULL << (BIT))) != 0)
98 /* Extract the backup dynamic frm rtl. */
99 #define DYNAMIC_FRM_RTL(c) ((c)->machine->mode_sw_info.dynamic_frm)
101 /* True the mode switching has static frm, or false. */
102 #define STATIC_FRM_P(c) ((c)->machine->mode_sw_info.static_frm_p)
104 /* Information about a function's frame layout. */
105 struct GTY(()) riscv_frame_info
{
106 /* The size of the frame in bytes. */
107 poly_int64 total_size
;
109 /* Bit X is set if the function saves or restores GPR X. */
112 /* Likewise FPR X. */
115 /* Likewise for vector registers. */
118 /* How much the GPR save/restore routines adjust sp (or 0 if unused). */
119 unsigned save_libcall_adjustment
;
121 /* the minimum number of bytes, in multiples of 16-byte address increments,
122 required to cover the registers in a multi push & pop. */
123 unsigned multi_push_adj_base
;
125 /* the number of additional 16-byte address increments allocated for the stack
126 frame in a multi push & pop. */
127 unsigned multi_push_adj_addi
;
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 /* Top and bottom offsets of vector save areas from frame bottom. */
134 poly_int64 v_sp_offset_top
;
135 poly_int64 v_sp_offset_bottom
;
137 /* Offset of virtual frame pointer from stack pointer/frame bottom */
138 poly_int64 frame_pointer_offset
;
140 /* Offset of hard frame pointer from stack pointer/frame bottom */
141 poly_int64 hard_frame_pointer_offset
;
143 /* The offset of arg_pointer_rtx from the bottom of the frame. */
144 poly_int64 arg_pointer_offset
;
146 /* Reset this struct, clean all field to zero. */
150 enum riscv_privilege_levels
{
151 UNKNOWN_MODE
, USER_MODE
, SUPERVISOR_MODE
, MACHINE_MODE
154 struct GTY(()) mode_switching_info
{
155 /* The RTL variable which stores the dynamic FRM value. We always use this
156 RTX to restore dynamic FRM rounding mode in mode switching. */
159 /* The boolean variables indicates there is at least one static rounding
160 mode instruction in the function or not. */
163 mode_switching_info ()
165 dynamic_frm
= NULL_RTX
;
166 static_frm_p
= false;
170 struct GTY(()) machine_function
{
171 /* The number of extra stack bytes taken up by register varargs.
172 This area is allocated by the callee at the very top of the frame. */
175 /* True if current function is a naked function. */
178 /* True if current function is an interrupt function. */
179 bool interrupt_handler_p
;
180 /* For an interrupt handler, indicates the privilege level. */
181 enum riscv_privilege_levels interrupt_mode
;
183 /* True if attributes on current function have been checked. */
184 bool attributes_checked_p
;
186 /* True if RA must be saved because of a far jump. */
189 /* The current frame information, calculated by riscv_compute_frame_info. */
190 struct riscv_frame_info frame
;
192 /* The components already handled by separate shrink-wrapping, which should
193 not be considered by the prologue and epilogue. */
194 bool reg_is_wrapped_separately
[FIRST_PSEUDO_REGISTER
];
196 /* The mode swithching information for the FRM rounding modes. */
197 struct mode_switching_info mode_sw_info
;
200 /* Information about a single argument. */
201 struct riscv_arg_info
{
202 /* True if the argument is at least partially passed on the stack. */
205 /* The number of integer registers allocated to this argument. */
206 unsigned int num_gprs
;
208 /* The offset of the first register used, provided num_gprs is nonzero.
209 If passed entirely on the stack, the value is MAX_ARGS_IN_REGISTERS. */
210 unsigned int gpr_offset
;
212 /* The number of floating-point registers allocated to this argument. */
213 unsigned int num_fprs
;
215 /* The offset of the first register used, provided num_fprs is nonzero. */
216 unsigned int fpr_offset
;
218 /* The number of vector registers allocated to this argument. */
219 unsigned int num_vrs
;
221 /* The offset of the first register used, provided num_vrs is nonzero. */
222 unsigned int vr_offset
;
224 /* The number of mask registers allocated to this argument. */
225 unsigned int num_mrs
;
227 /* The offset of the first register used, provided num_mrs is nonzero. */
228 unsigned int mr_offset
;
231 /* One stage in a constant building sequence. These sequences have
235 A = A CODE[1] VALUE[1]
236 A = A CODE[2] VALUE[2]
239 where A is an accumulator, each CODE[i] is a binary rtl operation
240 and each VALUE[i] is a constant integer. CODE[0] is undefined. */
241 struct riscv_integer_op
{
243 unsigned HOST_WIDE_INT value
;
246 /* The largest number of operations needed to load an integer constant.
247 The worst case is LUI, ADDI, SLLI, ADDI, SLLI, ADDI, SLLI, ADDI. */
248 #define RISCV_MAX_INTEGER_OPS 8
250 /* Costs of various operations on the different architectures. */
252 struct riscv_tune_param
254 unsigned short fp_add
[2];
255 unsigned short fp_mul
[2];
256 unsigned short fp_div
[2];
257 unsigned short int_mul
[2];
258 unsigned short int_div
[2];
259 unsigned short issue_rate
;
260 unsigned short branch_cost
;
261 unsigned short memory_cost
;
262 unsigned short fmv_cost
;
263 bool slow_unaligned_access
;
264 bool use_divmod_expansion
;
267 /* Information about one micro-arch we know about. */
268 struct riscv_tune_info
{
269 /* This micro-arch canonical name. */
272 /* Which automaton to use for tuning. */
273 enum riscv_microarchitecture_type microarchitecture
;
275 /* Tuning parameters for this micro-arch. */
276 const struct riscv_tune_param
*tune_param
;
279 /* Global variables for machine-dependent things. */
281 /* Whether unaligned accesses execute very slowly. */
282 bool riscv_slow_unaligned_access_p
;
284 /* Whether user explicitly passed -mstrict-align. */
285 bool riscv_user_wants_strict_align
;
287 /* Stack alignment to assume/maintain. */
288 unsigned riscv_stack_boundary
;
290 /* If non-zero, this is an offset to be added to SP to redefine the CFA
291 when restoring the FP register from the stack. Only valid when generating
293 static poly_int64 epilogue_cfa_sp_offset
;
295 /* Which tuning parameters to use. */
296 static const struct riscv_tune_param
*tune_param
;
298 /* Which automaton to use for tuning. */
299 enum riscv_microarchitecture_type riscv_microarchitecture
;
301 /* The number of chunks in a single vector register. */
302 poly_uint16 riscv_vector_chunks
;
304 /* The number of bytes in a vector chunk. */
305 unsigned riscv_bytes_per_vector_chunk
;
307 /* Index R is the smallest register class that contains register R. */
308 const enum reg_class riscv_regno_to_class
[FIRST_PSEUDO_REGISTER
] = {
309 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
310 GR_REGS
, GR_REGS
, SIBCALL_REGS
, SIBCALL_REGS
,
311 JALR_REGS
, JALR_REGS
, SIBCALL_REGS
, SIBCALL_REGS
,
312 SIBCALL_REGS
, SIBCALL_REGS
, SIBCALL_REGS
, SIBCALL_REGS
,
313 SIBCALL_REGS
, SIBCALL_REGS
, JALR_REGS
, JALR_REGS
,
314 JALR_REGS
, JALR_REGS
, JALR_REGS
, JALR_REGS
,
315 JALR_REGS
, JALR_REGS
, JALR_REGS
, JALR_REGS
,
316 SIBCALL_REGS
, SIBCALL_REGS
, SIBCALL_REGS
, SIBCALL_REGS
,
317 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
318 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
319 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
320 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
321 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
322 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
323 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
324 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
325 FRAME_REGS
, FRAME_REGS
, NO_REGS
, NO_REGS
,
326 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
327 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
328 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
329 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
330 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
331 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
332 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
333 VM_REGS
, VD_REGS
, VD_REGS
, VD_REGS
,
334 VD_REGS
, VD_REGS
, VD_REGS
, VD_REGS
,
335 VD_REGS
, VD_REGS
, VD_REGS
, VD_REGS
,
336 VD_REGS
, VD_REGS
, VD_REGS
, VD_REGS
,
337 VD_REGS
, VD_REGS
, VD_REGS
, VD_REGS
,
338 VD_REGS
, VD_REGS
, VD_REGS
, VD_REGS
,
339 VD_REGS
, VD_REGS
, VD_REGS
, VD_REGS
,
340 VD_REGS
, VD_REGS
, VD_REGS
, VD_REGS
,
343 /* Costs to use when optimizing for rocket. */
344 static const struct riscv_tune_param rocket_tune_info
= {
345 {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_add */
346 {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_mul */
347 {COSTS_N_INSNS (20), COSTS_N_INSNS (20)}, /* fp_div */
348 {COSTS_N_INSNS (4), COSTS_N_INSNS (4)}, /* int_mul */
349 {COSTS_N_INSNS (33), COSTS_N_INSNS (65)}, /* int_div */
354 true, /* slow_unaligned_access */
355 false, /* use_divmod_expansion */
358 /* Costs to use when optimizing for Sifive 7 Series. */
359 static const struct riscv_tune_param sifive_7_tune_info
= {
360 {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_add */
361 {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_mul */
362 {COSTS_N_INSNS (20), COSTS_N_INSNS (20)}, /* fp_div */
363 {COSTS_N_INSNS (4), COSTS_N_INSNS (4)}, /* int_mul */
364 {COSTS_N_INSNS (33), COSTS_N_INSNS (65)}, /* int_div */
369 true, /* slow_unaligned_access */
370 false, /* use_divmod_expansion */
373 /* Costs to use when optimizing for T-HEAD c906. */
374 static const struct riscv_tune_param thead_c906_tune_info
= {
375 {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_add */
376 {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_mul */
377 {COSTS_N_INSNS (20), COSTS_N_INSNS (20)}, /* fp_div */
378 {COSTS_N_INSNS (4), COSTS_N_INSNS (4)}, /* int_mul */
379 {COSTS_N_INSNS (18), COSTS_N_INSNS (34)}, /* int_div */
384 false, /* slow_unaligned_access */
385 false /* use_divmod_expansion */
388 /* Costs to use when optimizing for a generic ooo profile. */
389 static const struct riscv_tune_param generic_ooo_tune_info
= {
390 {COSTS_N_INSNS (2), COSTS_N_INSNS (2)}, /* fp_add */
391 {COSTS_N_INSNS (5), COSTS_N_INSNS (6)}, /* fp_mul */
392 {COSTS_N_INSNS (7), COSTS_N_INSNS (8)}, /* fp_div */
393 {COSTS_N_INSNS (2), COSTS_N_INSNS (2)}, /* int_mul */
394 {COSTS_N_INSNS (6), COSTS_N_INSNS (6)}, /* int_div */
399 false, /* slow_unaligned_access */
400 false, /* use_divmod_expansion */
403 /* Costs to use when optimizing for size. */
404 static const struct riscv_tune_param optimize_size_tune_info
= {
405 {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* fp_add */
406 {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* fp_mul */
407 {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* fp_div */
408 {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* int_mul */
409 {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* int_div */
414 false, /* slow_unaligned_access */
415 false, /* use_divmod_expansion */
418 static bool riscv_avoid_shrink_wrapping_separate ();
419 static tree
riscv_handle_fndecl_attribute (tree
*, tree
, tree
, int, bool *);
420 static tree
riscv_handle_type_attribute (tree
*, tree
, tree
, int, bool *);
421 static void riscv_legitimize_poly_move (machine_mode
, rtx
, rtx
, rtx
);
423 /* Defining target-specific uses of __attribute__. */
424 static const struct attribute_spec riscv_attribute_table
[] =
426 /* Syntax: { name, min_len, max_len, decl_required, type_required,
427 function_type_required, affects_type_identity, handler,
430 /* The attribute telling no prologue/epilogue. */
431 { "naked", 0, 0, true, false, false, false,
432 riscv_handle_fndecl_attribute
, NULL
},
433 /* This attribute generates prologue/epilogue for interrupt handlers. */
434 { "interrupt", 0, 1, false, true, true, false,
435 riscv_handle_type_attribute
, NULL
},
437 /* The following two are used for the built-in properties of the Vector type
438 and are not used externally */
439 {"RVV sizeless type", 4, 4, false, true, false, true, NULL
, NULL
},
440 {"RVV type", 0, 0, false, true, false, true, NULL
, NULL
},
442 /* The last attribute spec is set to be NULL. */
443 { NULL
, 0, 0, false, false, false, false, NULL
, NULL
}
446 /* Order for the CLOBBERs/USEs of gpr_save. */
447 static const unsigned gpr_save_reg_order
[] = {
448 INVALID_REGNUM
, T0_REGNUM
, T1_REGNUM
, RETURN_ADDR_REGNUM
,
449 S0_REGNUM
, S1_REGNUM
, S2_REGNUM
, S3_REGNUM
, S4_REGNUM
,
450 S5_REGNUM
, S6_REGNUM
, S7_REGNUM
, S8_REGNUM
, S9_REGNUM
,
451 S10_REGNUM
, S11_REGNUM
454 /* A table describing all the processors GCC knows about. */
455 static const struct riscv_tune_info riscv_tune_info_table
[] = {
456 #define RISCV_TUNE(TUNE_NAME, PIPELINE_MODEL, TUNE_INFO) \
457 { TUNE_NAME, PIPELINE_MODEL, & TUNE_INFO},
458 #include "riscv-cores.def"
461 /* Global variable to distinguish whether we should save and restore s0/fp for
463 static bool riscv_save_frame_pointer
;
474 typedef insn_code (*code_for_push_pop_t
) (machine_mode
);
476 void riscv_frame_info::reset(void)
482 save_libcall_adjustment
= 0;
487 v_sp_offset_bottom
= 0;
489 frame_pointer_offset
= 0;
491 hard_frame_pointer_offset
= 0;
493 arg_pointer_offset
= 0;
496 /* Implement TARGET_MIN_ARITHMETIC_PRECISION. */
499 riscv_min_arithmetic_precision (void)
504 /* Return the riscv_tune_info entry for the given name string. */
506 static const struct riscv_tune_info
*
507 riscv_parse_tune (const char *tune_string
)
509 const riscv_cpu_info
*cpu
= riscv_find_cpu (tune_string
);
512 tune_string
= cpu
->tune
;
514 for (unsigned i
= 0; i
< ARRAY_SIZE (riscv_tune_info_table
); i
++)
515 if (strcmp (riscv_tune_info_table
[i
].name
, tune_string
) == 0)
516 return riscv_tune_info_table
+ i
;
518 error ("unknown cpu %qs for %<-mtune%>", tune_string
);
519 return riscv_tune_info_table
;
522 /* Helper function for riscv_build_integer; arguments are as for
523 riscv_build_integer. */
526 riscv_build_integer_1 (struct riscv_integer_op codes
[RISCV_MAX_INTEGER_OPS
],
527 HOST_WIDE_INT value
, machine_mode mode
)
529 HOST_WIDE_INT low_part
= CONST_LOW_PART (value
);
530 int cost
= RISCV_MAX_INTEGER_OPS
+ 1, alt_cost
;
531 struct riscv_integer_op alt_codes
[RISCV_MAX_INTEGER_OPS
];
533 if (SMALL_OPERAND (value
) || LUI_OPERAND (value
))
535 /* Simply ADDI or LUI. */
536 codes
[0].code
= UNKNOWN
;
537 codes
[0].value
= value
;
540 if (TARGET_ZBS
&& SINGLE_BIT_MASK_OPERAND (value
))
543 codes
[0].code
= UNKNOWN
;
544 codes
[0].value
= value
;
546 /* RISC-V sign-extends all 32bit values that live in a 32bit
547 register. To avoid paradoxes, we thus need to use the
548 sign-extended (negative) representation (-1 << 31) for the
549 value, if we want to build (1 << 31) in SImode. This will
550 then expand to an LUI instruction. */
551 if (TARGET_64BIT
&& mode
== SImode
&& value
== (HOST_WIDE_INT_1U
<< 31))
552 codes
[0].value
= (HOST_WIDE_INT_M1U
<< 31);
557 /* End with ADDI. When constructing HImode constants, do not generate any
558 intermediate value that is not itself a valid HImode constant. The
559 XORI case below will handle those remaining HImode constants. */
562 || value
- low_part
<= ((1 << (GET_MODE_BITSIZE (HImode
) - 1)) - 1)))
564 HOST_WIDE_INT upper_part
= value
- low_part
;
565 if (mode
!= VOIDmode
)
566 upper_part
= trunc_int_for_mode (value
- low_part
, mode
);
568 alt_cost
= 1 + riscv_build_integer_1 (alt_codes
, upper_part
, mode
);
571 alt_codes
[alt_cost
-1].code
= PLUS
;
572 alt_codes
[alt_cost
-1].value
= low_part
;
573 memcpy (codes
, alt_codes
, sizeof (alt_codes
));
579 if (cost
> 2 && (low_part
< 0 || mode
== HImode
))
581 alt_cost
= 1 + riscv_build_integer_1 (alt_codes
, value
^ low_part
, mode
);
584 alt_codes
[alt_cost
-1].code
= XOR
;
585 alt_codes
[alt_cost
-1].value
= low_part
;
586 memcpy (codes
, alt_codes
, sizeof (alt_codes
));
591 /* Eliminate trailing zeros and end with SLLI. */
592 if (cost
> 2 && (value
& 1) == 0)
594 int shift
= ctz_hwi (value
);
595 unsigned HOST_WIDE_INT x
= value
;
596 x
= sext_hwi (x
>> shift
, HOST_BITS_PER_WIDE_INT
- shift
);
598 /* Don't eliminate the lower 12 bits if LUI might apply. */
599 if (shift
> IMM_BITS
&& !SMALL_OPERAND (x
) && LUI_OPERAND (x
<< IMM_BITS
))
600 shift
-= IMM_BITS
, x
<<= IMM_BITS
;
602 alt_cost
= 1 + riscv_build_integer_1 (alt_codes
, x
, mode
);
605 alt_codes
[alt_cost
-1].code
= ASHIFT
;
606 alt_codes
[alt_cost
-1].value
= shift
;
607 memcpy (codes
, alt_codes
, sizeof (alt_codes
));
612 if (cost
> 2 && TARGET_64BIT
&& (TARGET_ZBB
|| TARGET_XTHEADBB
))
614 int leading_ones
= clz_hwi (~value
);
615 int trailing_ones
= ctz_hwi (~value
);
617 /* If all bits are one except a few that are zero, and the zero bits
618 are within a range of 11 bits, then we can synthesize a constant
619 by loading a small negative constant and rotating. */
620 if (leading_ones
< 64
621 && ((64 - leading_ones
- trailing_ones
) < 12))
623 codes
[0].code
= UNKNOWN
;
624 /* The sign-bit might be zero, so just rotate to be safe. */
625 codes
[0].value
= (((unsigned HOST_WIDE_INT
) value
>> trailing_ones
)
626 | (value
<< (64 - trailing_ones
)));
627 codes
[1].code
= ROTATERT
;
628 codes
[1].value
= 64 - trailing_ones
;
631 /* Handle the case where the 11 bit range of zero bits wraps around. */
634 int upper_trailing_ones
= ctz_hwi (~value
>> 32);
635 int lower_leading_ones
= clz_hwi (~value
<< 32);
637 if (upper_trailing_ones
< 32 && lower_leading_ones
< 32
638 && ((64 - upper_trailing_ones
- lower_leading_ones
) < 12))
640 codes
[0].code
= UNKNOWN
;
641 /* The sign-bit might be zero, so just rotate to be safe. */
642 codes
[0].value
= ((value
<< (32 - upper_trailing_ones
))
643 | ((unsigned HOST_WIDE_INT
) value
644 >> (32 + upper_trailing_ones
)));
645 codes
[1].code
= ROTATERT
;
646 codes
[1].value
= 32 - upper_trailing_ones
;
652 gcc_assert (cost
<= RISCV_MAX_INTEGER_OPS
);
656 /* Fill CODES with a sequence of rtl operations to load VALUE.
657 Return the number of operations needed. */
660 riscv_build_integer (struct riscv_integer_op
*codes
, HOST_WIDE_INT value
,
663 int cost
= riscv_build_integer_1 (codes
, value
, mode
);
665 /* Eliminate leading zeros and end with SRLI. */
666 if (value
> 0 && cost
> 2)
668 struct riscv_integer_op alt_codes
[RISCV_MAX_INTEGER_OPS
];
669 int alt_cost
, shift
= clz_hwi (value
);
670 HOST_WIDE_INT shifted_val
;
672 /* Try filling trailing bits with 1s. */
673 shifted_val
= (value
<< shift
) | ((((HOST_WIDE_INT
) 1) << shift
) - 1);
674 alt_cost
= 1 + riscv_build_integer_1 (alt_codes
, shifted_val
, mode
);
677 alt_codes
[alt_cost
-1].code
= LSHIFTRT
;
678 alt_codes
[alt_cost
-1].value
= shift
;
679 memcpy (codes
, alt_codes
, sizeof (alt_codes
));
683 /* Try filling trailing bits with 0s. */
684 shifted_val
= value
<< shift
;
685 alt_cost
= 1 + riscv_build_integer_1 (alt_codes
, shifted_val
, mode
);
688 alt_codes
[alt_cost
-1].code
= LSHIFTRT
;
689 alt_codes
[alt_cost
-1].value
= shift
;
690 memcpy (codes
, alt_codes
, sizeof (alt_codes
));
696 && (value
> INT32_MAX
|| value
< INT32_MIN
))
698 unsigned HOST_WIDE_INT loval
= sext_hwi (value
, 32);
699 unsigned HOST_WIDE_INT hival
= sext_hwi ((value
- loval
) >> 32, 32);
700 struct riscv_integer_op alt_codes
[RISCV_MAX_INTEGER_OPS
];
701 struct riscv_integer_op hicode
[RISCV_MAX_INTEGER_OPS
];
702 int hi_cost
, lo_cost
;
704 hi_cost
= riscv_build_integer_1 (hicode
, hival
, mode
);
707 lo_cost
= riscv_build_integer_1 (alt_codes
, loval
, mode
);
708 if (lo_cost
+ hi_cost
< cost
)
710 memcpy (codes
, alt_codes
,
711 lo_cost
* sizeof (struct riscv_integer_op
));
712 memcpy (codes
+ lo_cost
, hicode
,
713 hi_cost
* sizeof (struct riscv_integer_op
));
714 cost
= lo_cost
+ hi_cost
;
722 /* Return the cost of constructing VAL in the event that a scratch
723 register is available. */
726 riscv_split_integer_cost (HOST_WIDE_INT val
)
729 unsigned HOST_WIDE_INT loval
= sext_hwi (val
, 32);
730 unsigned HOST_WIDE_INT hival
= sext_hwi ((val
- loval
) >> 32, 32);
731 struct riscv_integer_op codes
[RISCV_MAX_INTEGER_OPS
];
733 cost
= 2 + riscv_build_integer (codes
, loval
, VOIDmode
);
735 cost
+= riscv_build_integer (codes
, hival
, VOIDmode
);
740 /* Return the cost of constructing the integer constant VAL. */
743 riscv_integer_cost (HOST_WIDE_INT val
)
745 struct riscv_integer_op codes
[RISCV_MAX_INTEGER_OPS
];
746 return MIN (riscv_build_integer (codes
, val
, VOIDmode
),
747 riscv_split_integer_cost (val
));
750 /* Try to split a 64b integer into 32b parts, then reassemble. */
753 riscv_split_integer (HOST_WIDE_INT val
, machine_mode mode
)
755 unsigned HOST_WIDE_INT loval
= sext_hwi (val
, 32);
756 unsigned HOST_WIDE_INT hival
= sext_hwi ((val
- loval
) >> 32, 32);
757 rtx hi
= gen_reg_rtx (mode
), lo
= gen_reg_rtx (mode
);
759 riscv_move_integer (lo
, lo
, loval
, mode
);
762 hi
= gen_rtx_ASHIFT (mode
, lo
, GEN_INT (32));
765 riscv_move_integer (hi
, hi
, hival
, mode
);
766 hi
= gen_rtx_ASHIFT (mode
, hi
, GEN_INT (32));
769 hi
= force_reg (mode
, hi
);
770 return gen_rtx_PLUS (mode
, hi
, lo
);
773 /* Return true if X is a thread-local symbol. */
776 riscv_tls_symbol_p (const_rtx x
)
778 return SYMBOL_REF_P (x
) && SYMBOL_REF_TLS_MODEL (x
) != 0;
781 /* Return true if symbol X binds locally. */
784 riscv_symbol_binds_local_p (const_rtx x
)
786 if (SYMBOL_REF_P (x
))
787 return (SYMBOL_REF_DECL (x
)
788 ? targetm
.binds_local_p (SYMBOL_REF_DECL (x
))
789 : SYMBOL_REF_LOCAL_P (x
));
794 /* Return the method that should be used to access SYMBOL_REF or
797 static enum riscv_symbol_type
798 riscv_classify_symbol (const_rtx x
)
800 if (riscv_tls_symbol_p (x
))
803 if (GET_CODE (x
) == SYMBOL_REF
&& flag_pic
&& !riscv_symbol_binds_local_p (x
))
804 return SYMBOL_GOT_DISP
;
806 return riscv_cmodel
== CM_MEDLOW
? SYMBOL_ABSOLUTE
: SYMBOL_PCREL
;
809 /* Classify the base of symbolic expression X. */
811 enum riscv_symbol_type
812 riscv_classify_symbolic_expression (rtx x
)
816 split_const (x
, &x
, &offset
);
817 if (UNSPEC_ADDRESS_P (x
))
818 return UNSPEC_ADDRESS_TYPE (x
);
820 return riscv_classify_symbol (x
);
823 /* Return true if X is a symbolic constant. If it is, store the type of
824 the symbol in *SYMBOL_TYPE. */
827 riscv_symbolic_constant_p (rtx x
, enum riscv_symbol_type
*symbol_type
)
831 split_const (x
, &x
, &offset
);
832 if (UNSPEC_ADDRESS_P (x
))
834 *symbol_type
= UNSPEC_ADDRESS_TYPE (x
);
835 x
= UNSPEC_ADDRESS (x
);
837 else if (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == LABEL_REF
)
838 *symbol_type
= riscv_classify_symbol (x
);
842 if (offset
== const0_rtx
)
845 /* Nonzero offsets are only valid for references that don't use the GOT. */
846 switch (*symbol_type
)
848 case SYMBOL_ABSOLUTE
:
851 /* GAS rejects offsets outside the range [-2^31, 2^31-1]. */
852 return sext_hwi (INTVAL (offset
), 32) == INTVAL (offset
);
859 /* Returns the number of instructions necessary to reference a symbol. */
861 static int riscv_symbol_insns (enum riscv_symbol_type type
)
865 case SYMBOL_TLS
: return 0; /* Depends on the TLS model. */
866 case SYMBOL_ABSOLUTE
: return 2; /* LUI + the reference. */
867 case SYMBOL_PCREL
: return 2; /* AUIPC + the reference. */
868 case SYMBOL_TLS_LE
: return 3; /* LUI + ADD TP + the reference. */
869 case SYMBOL_GOT_DISP
: return 3; /* AUIPC + LD GOT + the reference. */
870 default: gcc_unreachable ();
874 /* Immediate values loaded by the FLI.S instruction in Chapter 25 of the latest RISC-V ISA
875 Manual draft. For details, please see:
876 https://github.com/riscv/riscv-isa-manual/releases/tag/isa-449cd0c */
878 static unsigned HOST_WIDE_INT fli_value_hf
[32] =
880 0xbcp
8, 0x4p
8, 0x1p
8, 0x2p
8, 0x1cp
8, 0x20p
8, 0x2cp
8, 0x30p
8,
881 0x34p
8, 0x35p
8, 0x36p
8, 0x37p
8, 0x38p
8, 0x39p
8, 0x3ap
8, 0x3bp
8,
882 0x3cp
8, 0x3dp
8, 0x3ep
8, 0x3fp
8, 0x40p
8, 0x41p
8, 0x42p
8, 0x44p
8,
883 0x48p
8, 0x4cp
8, 0x58p
8, 0x5cp
8, 0x78p
8,
884 /* Only used for filling, ensuring that 29 and 30 of HF are the same. */
889 static unsigned HOST_WIDE_INT fli_value_sf
[32] =
891 0xbf8p
20, 0x008p
20, 0x378p
20, 0x380p
20, 0x3b8p
20, 0x3c0p
20, 0x3d8p
20, 0x3e0p
20,
892 0x3e8p
20, 0x3eap
20, 0x3ecp
20, 0x3eep
20, 0x3f0p
20, 0x3f2p
20, 0x3f4p
20, 0x3f6p
20,
893 0x3f8p
20, 0x3fap
20, 0x3fcp
20, 0x3fep
20, 0x400p
20, 0x402p
20, 0x404p
20, 0x408p
20,
894 0x410p
20, 0x418p
20, 0x430p
20, 0x438p
20, 0x470p
20, 0x478p
20, 0x7f8p
20, 0x7fcp
20
897 static unsigned HOST_WIDE_INT fli_value_df
[32] =
899 0xbff0p
48, 0x10p
48, 0x3ef0p
48, 0x3f00p
48,
900 0x3f70p
48, 0x3f80p
48, 0x3fb0p
48, 0x3fc0p
48,
901 0x3fd0p
48, 0x3fd4p
48, 0x3fd8p
48, 0x3fdcp
48,
902 0x3fe0p
48, 0x3fe4p
48, 0x3fe8p
48, 0x3fecp
48,
903 0x3ff0p
48, 0x3ff4p
48, 0x3ff8p
48, 0x3ffcp
48,
904 0x4000p
48, 0x4004p
48, 0x4008p
48, 0x4010p
48,
905 0x4020p
48, 0x4030p
48, 0x4060p
48, 0x4070p
48,
906 0x40e0p
48, 0x40f0p
48, 0x7ff0p
48, 0x7ff8p
48
909 /* Display floating-point values at the assembly level, which is consistent
910 with the zfa extension of llvm:
911 https://reviews.llvm.org/D145645. */
913 const char *fli_value_print
[32] =
915 "-1.0", "min", "1.52587890625e-05", "3.0517578125e-05", "0.00390625", "0.0078125", "0.0625", "0.125",
916 "0.25", "0.3125", "0.375", "0.4375", "0.5", "0.625", "0.75", "0.875",
917 "1.0", "1.25", "1.5", "1.75", "2.0", "2.5", "3.0", "4.0",
918 "8.0", "16.0", "128.0", "256.0", "32768.0", "65536.0", "inf", "nan"
921 /* Return index of the FLI instruction table if rtx X is an immediate constant that can
922 be moved using a single FLI instruction in zfa extension. Return -1 if not found. */
925 riscv_float_const_rtx_index_for_fli (rtx x
)
927 unsigned HOST_WIDE_INT
*fli_value_array
;
929 machine_mode mode
= GET_MODE (x
);
932 || !CONST_DOUBLE_P(x
)
934 || (mode
== HFmode
&& !(TARGET_ZFH
|| TARGET_ZVFH
))
935 || (mode
== SFmode
&& !TARGET_HARD_FLOAT
)
936 || (mode
== DFmode
&& !TARGET_DOUBLE_FLOAT
))
939 if (!SCALAR_FLOAT_MODE_P (mode
)
940 || GET_MODE_BITSIZE (mode
).to_constant () > HOST_BITS_PER_WIDE_INT
941 /* Only support up to DF mode. */
942 || GET_MODE_BITSIZE (mode
).to_constant () > GET_MODE_BITSIZE (DFmode
))
945 unsigned HOST_WIDE_INT ival
= 0;
949 CONST_DOUBLE_REAL_VALUE (x
),
950 REAL_MODE_FORMAT (mode
));
954 int order
= BYTES_BIG_ENDIAN
? 1 : 0;
955 ival
= zext_hwi (res
[order
], 32);
956 ival
|= (zext_hwi (res
[1 - order
], 32) << 32);
958 /* When the lower 32 bits are not all 0, it is impossible to be in the table. */
959 if (ival
& (unsigned HOST_WIDE_INT
)0xffffffff)
963 ival
= zext_hwi (res
[0], 32);
968 fli_value_array
= fli_value_hf
;
971 fli_value_array
= fli_value_sf
;
974 fli_value_array
= fli_value_df
;
980 if (fli_value_array
[0] == ival
)
983 if (fli_value_array
[1] == ival
)
986 /* Perform a binary search to find target index. */
995 if (fli_value_array
[m
] == ival
)
997 else if (fli_value_array
[m
] < ival
)
1006 /* Implement TARGET_LEGITIMATE_CONSTANT_P. */
1009 riscv_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED
, rtx x
)
1011 return riscv_const_insns (x
) > 0;
1014 /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
1017 riscv_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED
, rtx x
)
1019 enum riscv_symbol_type type
;
1022 /* There's no way to calculate VL-based values using relocations. */
1023 subrtx_iterator::array_type array
;
1024 FOR_EACH_SUBRTX (iter
, array
, x
, ALL
)
1025 if (GET_CODE (*iter
) == CONST_POLY_INT
)
1028 /* There is no assembler syntax for expressing an address-sized
1030 if (GET_CODE (x
) == HIGH
)
1033 if (satisfies_constraint_zfli (x
))
1036 split_const (x
, &base
, &offset
);
1037 if (riscv_symbolic_constant_p (base
, &type
))
1039 /* As an optimization, don't spill symbolic constants that are as
1040 cheap to rematerialize as to access in the constant pool. */
1041 if (SMALL_OPERAND (INTVAL (offset
)) && riscv_symbol_insns (type
) > 0)
1044 /* As an optimization, avoid needlessly generate dynamic relocations. */
1049 /* TLS symbols must be computed by riscv_legitimize_move. */
1050 if (tls_referenced_p (x
))
1056 /* Return true if register REGNO is a valid base register for mode MODE.
1057 STRICT_P is true if REG_OK_STRICT is in effect. */
1060 riscv_regno_mode_ok_for_base_p (int regno
,
1061 machine_mode mode ATTRIBUTE_UNUSED
,
1064 if (!HARD_REGISTER_NUM_P (regno
))
1068 regno
= reg_renumber
[regno
];
1071 /* These fake registers will be eliminated to either the stack or
1072 hard frame pointer, both of which are usually valid base registers.
1073 Reload deals with the cases where the eliminated form isn't valid. */
1074 if (regno
== ARG_POINTER_REGNUM
|| regno
== FRAME_POINTER_REGNUM
)
1077 return GP_REG_P (regno
);
1080 /* Get valid index register class.
1081 The RISC-V base instructions don't support index registers,
1082 but extensions might support that. */
1085 riscv_index_reg_class ()
1087 if (TARGET_XTHEADMEMIDX
)
1093 /* Return true if register REGNO is a valid index register.
1094 The RISC-V base instructions don't support index registers,
1095 but extensions might support that. */
1098 riscv_regno_ok_for_index_p (int regno
)
1100 if (TARGET_XTHEADMEMIDX
)
1101 return riscv_regno_mode_ok_for_base_p (regno
, VOIDmode
, 1);
1106 /* Return true if X is a valid base register for mode MODE.
1107 STRICT_P is true if REG_OK_STRICT is in effect. */
1110 riscv_valid_base_register_p (rtx x
, machine_mode mode
, bool strict_p
)
1112 if (!strict_p
&& GET_CODE (x
) == SUBREG
)
1116 && riscv_regno_mode_ok_for_base_p (REGNO (x
), mode
, strict_p
));
1119 /* Return true if, for every base register BASE_REG, (plus BASE_REG X)
1120 can address a value of mode MODE. */
1123 riscv_valid_offset_p (rtx x
, machine_mode mode
)
1125 /* Check that X is a signed 12-bit number. */
1126 if (!const_arith_operand (x
, Pmode
))
1129 /* We may need to split multiword moves, so make sure that every word
1131 if (GET_MODE_SIZE (mode
).to_constant () > UNITS_PER_WORD
1132 && !SMALL_OPERAND (INTVAL (x
) + GET_MODE_SIZE (mode
).to_constant () - UNITS_PER_WORD
))
1138 /* Should a symbol of type SYMBOL_TYPE should be split in two? */
1141 riscv_split_symbol_type (enum riscv_symbol_type symbol_type
)
1143 if (symbol_type
== SYMBOL_TLS_LE
)
1146 if (!TARGET_EXPLICIT_RELOCS
)
1149 return symbol_type
== SYMBOL_ABSOLUTE
|| symbol_type
== SYMBOL_PCREL
;
1152 /* Return true if a LO_SUM can address a value of mode MODE when the
1153 LO_SUM symbol has type SYM_TYPE. X is the LO_SUM second operand, which
1154 is used when the mode is BLKmode. */
1157 riscv_valid_lo_sum_p (enum riscv_symbol_type sym_type
, machine_mode mode
,
1162 /* Check that symbols of type SYMBOL_TYPE can be used to access values
1164 if (riscv_symbol_insns (sym_type
) == 0)
1167 /* Check that there is a known low-part relocation. */
1168 if (!riscv_split_symbol_type (sym_type
))
1171 /* We can't tell size or alignment when we have BLKmode, so try extracing a
1172 decl from the symbol if possible. */
1173 if (mode
== BLKmode
)
1177 /* Extract the symbol from the LO_SUM operand, if any. */
1178 split_const (x
, &x
, &offset
);
1180 /* Might be a CODE_LABEL. We can compute align but not size for that,
1181 so don't bother trying to handle it. */
1182 if (!SYMBOL_REF_P (x
))
1185 /* Use worst case assumptions if we don't have a SYMBOL_REF_DECL. */
1186 align
= (SYMBOL_REF_DECL (x
)
1187 ? DECL_ALIGN (SYMBOL_REF_DECL (x
))
1189 size
= (SYMBOL_REF_DECL (x
) && DECL_SIZE (SYMBOL_REF_DECL (x
))
1190 ? tree_to_uhwi (DECL_SIZE (SYMBOL_REF_DECL (x
)))
1195 align
= GET_MODE_ALIGNMENT (mode
);
1196 size
= GET_MODE_BITSIZE (mode
).to_constant ();
1199 /* We may need to split multiword moves, so make sure that each word
1200 can be accessed without inducing a carry. */
1201 if (size
> BITS_PER_WORD
1202 && (!TARGET_STRICT_ALIGN
|| size
> align
))
1208 /* Return true if mode is the RVV enabled mode.
1209 For example: 'RVVMF2SI' mode is disabled,
1210 wheras 'RVVM1SI' mode is enabled if MIN_VLEN == 32. */
1213 riscv_v_ext_vector_mode_p (machine_mode mode
)
1215 #define ENTRY(MODE, REQUIREMENT, ...) \
1220 #include "riscv-vector-switch.def"
1228 /* Return true if mode is the RVV enabled tuple mode. */
1231 riscv_v_ext_tuple_mode_p (machine_mode mode
)
1233 #define TUPLE_ENTRY(MODE, REQUIREMENT, ...) \
1238 #include "riscv-vector-switch.def"
1246 /* Return true if mode is the RVV enabled vls mode. */
1249 riscv_v_ext_vls_mode_p (machine_mode mode
)
1251 #define VLS_ENTRY(MODE, REQUIREMENT) \
1256 #include "riscv-vector-switch.def"
1264 /* Return true if it is either RVV vector mode or RVV tuple mode. */
1267 riscv_v_ext_mode_p (machine_mode mode
)
1269 return riscv_v_ext_vector_mode_p (mode
) || riscv_v_ext_tuple_mode_p (mode
)
1270 || riscv_v_ext_vls_mode_p (mode
);
1273 /* Call from ADJUST_NUNITS in riscv-modes.def. Return the correct
1274 NUNITS size for corresponding machine_mode. */
1277 riscv_v_adjust_nunits (machine_mode mode
, int scale
)
1279 gcc_assert (GET_MODE_CLASS (mode
) == MODE_VECTOR_BOOL
);
1280 if (riscv_v_ext_mode_p (mode
))
1282 if (TARGET_MIN_VLEN
== 32)
1284 return riscv_vector_chunks
* scale
;
1289 /* Call from ADJUST_NUNITS in riscv-modes.def. Return the correct
1290 NUNITS size for corresponding machine_mode. */
1293 riscv_v_adjust_nunits (machine_mode mode
, bool fractional_p
, int lmul
, int nf
)
1295 if (riscv_v_ext_mode_p (mode
))
1297 scalar_mode smode
= GET_MODE_INNER (mode
);
1298 int size
= GET_MODE_SIZE (smode
);
1299 int nunits_per_chunk
= riscv_bytes_per_vector_chunk
/ size
;
1301 return nunits_per_chunk
/ lmul
* riscv_vector_chunks
* nf
;
1303 return nunits_per_chunk
* lmul
* riscv_vector_chunks
* nf
;
1305 /* Set the disabled RVV modes size as 1 by default. */
1309 /* Call from ADJUST_BYTESIZE in riscv-modes.def. Return the correct
1310 BYTE size for corresponding machine_mode. */
1313 riscv_v_adjust_bytesize (machine_mode mode
, int scale
)
1315 if (riscv_v_ext_vector_mode_p (mode
))
1317 poly_int64 nunits
= GET_MODE_NUNITS (mode
);
1318 poly_int64 mode_size
= GET_MODE_SIZE (mode
);
1320 if (maybe_eq (mode_size
, (uint16_t) -1))
1321 mode_size
= riscv_vector_chunks
* scale
;
1323 if (nunits
.coeffs
[0] > 8)
1324 return exact_div (nunits
, 8);
1325 else if (nunits
.is_constant ())
1328 return poly_int64 (1, 1);
1334 /* Call from ADJUST_PRECISION in riscv-modes.def. Return the correct
1335 PRECISION size for corresponding machine_mode. */
1338 riscv_v_adjust_precision (machine_mode mode
, int scale
)
1340 return riscv_v_adjust_nunits (mode
, scale
);
1343 /* Return true if X is a valid address for machine mode MODE. If it is,
1344 fill in INFO appropriately. STRICT_P is true if REG_OK_STRICT is in
1348 riscv_classify_address (struct riscv_address_info
*info
, rtx x
,
1349 machine_mode mode
, bool strict_p
)
1351 if (th_classify_address (info
, x
, mode
, strict_p
))
1354 switch (GET_CODE (x
))
1358 info
->type
= ADDRESS_REG
;
1360 info
->offset
= const0_rtx
;
1361 return riscv_valid_base_register_p (info
->reg
, mode
, strict_p
);
1364 /* RVV load/store disallow any offset. */
1365 if (riscv_v_ext_mode_p (mode
))
1368 info
->type
= ADDRESS_REG
;
1369 info
->reg
= XEXP (x
, 0);
1370 info
->offset
= XEXP (x
, 1);
1371 return (riscv_valid_base_register_p (info
->reg
, mode
, strict_p
)
1372 && riscv_valid_offset_p (info
->offset
, mode
));
1375 /* RVV load/store disallow LO_SUM. */
1376 if (riscv_v_ext_mode_p (mode
))
1379 info
->type
= ADDRESS_LO_SUM
;
1380 info
->reg
= XEXP (x
, 0);
1381 info
->offset
= XEXP (x
, 1);
1382 /* We have to trust the creator of the LO_SUM to do something vaguely
1383 sane. Target-independent code that creates a LO_SUM should also
1384 create and verify the matching HIGH. Target-independent code that
1385 adds an offset to a LO_SUM must prove that the offset will not
1386 induce a carry. Failure to do either of these things would be
1387 a bug, and we are not required to check for it here. The RISC-V
1388 backend itself should only create LO_SUMs for valid symbolic
1389 constants, with the high part being either a HIGH or a copy
1392 = riscv_classify_symbolic_expression (info
->offset
);
1393 return (riscv_valid_base_register_p (info
->reg
, mode
, strict_p
)
1394 && riscv_valid_lo_sum_p (info
->symbol_type
, mode
, info
->offset
));
1397 /* We only allow the const0_rtx for the RVV load/store. For example:
1398 +----------------------------------------------------------+
1400 | vsetvli zero,a1,e32,m1,ta,ma |
1401 | vle32.v v24,0(a5) <- propagate the const 0 to a5 here. |
1402 | vs1r.v v24,0(a0) |
1403 +----------------------------------------------------------+
1404 It can be folded to:
1405 +----------------------------------------------------------+
1406 | vsetvli zero,a1,e32,m1,ta,ma |
1407 | vle32.v v24,0(zero) |
1408 | vs1r.v v24,0(a0) |
1409 +----------------------------------------------------------+
1410 This behavior will benefit the underlying RVV auto vectorization. */
1411 if (riscv_v_ext_mode_p (mode
))
1412 return x
== const0_rtx
;
1414 /* Small-integer addresses don't occur very often, but they
1415 are legitimate if x0 is a valid base register. */
1416 info
->type
= ADDRESS_CONST_INT
;
1417 return SMALL_OPERAND (INTVAL (x
));
1424 /* Implement TARGET_LEGITIMATE_ADDRESS_P. */
1427 riscv_legitimate_address_p (machine_mode mode
, rtx x
, bool strict_p
,
1428 code_helper
= ERROR_MARK
)
1430 struct riscv_address_info addr
;
1432 return riscv_classify_address (&addr
, x
, mode
, strict_p
);
1435 /* Return true if hard reg REGNO can be used in compressed instructions. */
1438 riscv_compressed_reg_p (int regno
)
1440 /* x8-x15/f8-f15 are compressible registers. */
1441 return ((TARGET_RVC
|| TARGET_ZCA
)
1442 && (IN_RANGE (regno
, GP_REG_FIRST
+ 8, GP_REG_FIRST
+ 15)
1443 || IN_RANGE (regno
, FP_REG_FIRST
+ 8, FP_REG_FIRST
+ 15)));
1446 /* Return true if x is an unsigned 5-bit immediate scaled by 4. */
1449 riscv_compressed_lw_offset_p (rtx x
)
1451 return (CONST_INT_P (x
)
1452 && (INTVAL (x
) & 3) == 0
1453 && IN_RANGE (INTVAL (x
), 0, CSW_MAX_OFFSET
));
1456 /* Return true if load/store from/to address x can be compressed. */
1459 riscv_compressed_lw_address_p (rtx x
)
1461 struct riscv_address_info addr
;
1462 bool result
= riscv_classify_address (&addr
, x
, GET_MODE (x
),
1465 /* Return false if address is not compressed_reg + small_offset. */
1467 || addr
.type
!= ADDRESS_REG
1468 /* Before reload, assume all registers are OK. */
1469 || (reload_completed
1470 && !riscv_compressed_reg_p (REGNO (addr
.reg
))
1471 && addr
.reg
!= stack_pointer_rtx
)
1472 || !riscv_compressed_lw_offset_p (addr
.offset
))
1478 /* Return the number of instructions needed to load or store a value
1479 of mode MODE at address X. Return 0 if X isn't valid for MODE.
1480 Assume that multiword moves may need to be split into word moves
1481 if MIGHT_SPLIT_P, otherwise assume that a single load or store is
1485 riscv_address_insns (rtx x
, machine_mode mode
, bool might_split_p
)
1487 struct riscv_address_info addr
= {};
1490 if (!riscv_classify_address (&addr
, x
, mode
, false))
1492 /* This could be a pattern from the pic.md file. In which case we want
1493 this address to always have a cost of 3 to make it as expensive as the
1494 most expensive symbol. This prevents constant propagation from
1495 preferring symbols over register plus offset. */
1499 /* BLKmode is used for single unaligned loads and stores and should
1500 not count as a multiword mode. */
1501 if (!riscv_v_ext_vector_mode_p (mode
) && mode
!= BLKmode
&& might_split_p
)
1502 n
+= (GET_MODE_SIZE (mode
).to_constant () + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
1504 if (addr
.type
== ADDRESS_LO_SUM
)
1505 n
+= riscv_symbol_insns (addr
.symbol_type
) - 1;
1510 /* Return the number of instructions needed to load constant X.
1511 Return 0 if X isn't a valid constant. */
1514 riscv_const_insns (rtx x
)
1516 enum riscv_symbol_type symbol_type
;
1519 switch (GET_CODE (x
))
1522 if (!riscv_symbolic_constant_p (XEXP (x
, 0), &symbol_type
)
1523 || !riscv_split_symbol_type (symbol_type
))
1526 /* This is simply an LUI. */
1531 int cost
= riscv_integer_cost (INTVAL (x
));
1532 /* Force complicated constants to memory. */
1533 return cost
< 4 ? cost
: 0;
1537 /* See if we can use FMV directly. */
1538 if (satisfies_constraint_zfli (x
))
1541 /* We can use x0 to load floating-point zero. */
1542 return x
== CONST0_RTX (GET_MODE (x
)) ? 1 : 0;
1545 /* TODO: This is not accurate, we will need to
1546 adapt the COST of CONST_VECTOR in the future
1547 for the following cases:
1549 - 1. const duplicate vector with element value
1550 in range of [-16, 15].
1551 - 2. const duplicate vector with element value
1552 out range of [-16, 15].
1553 - 3. const series vector.
1555 if (riscv_v_ext_mode_p (GET_MODE (x
)))
1557 /* const series vector. */
1559 if (const_vec_series_p (x
, &base
, &step
))
1561 /* This is not accurate, we will need to adapt the COST
1562 * accurately according to BASE && STEP. */
1567 if (const_vec_duplicate_p (x
, &elt
))
1569 /* Constants from -16 to 15 can be loaded with vmv.v.i.
1570 The Wc0, Wc1 constraints are already covered by the
1571 vi constraint so we do not need to check them here
1573 if (satisfies_constraint_vi (x
))
1576 /* Any int/FP constants can always be broadcast from a
1577 scalar register. Loading of a floating-point
1578 constant incurs a literal-pool access. Allow this in
1579 order to increase vectorization possibilities. */
1580 int n
= riscv_const_insns (elt
);
1581 if (CONST_DOUBLE_P (elt
))
1582 return 1 + 4; /* vfmv.v.f + memory access. */
1585 /* We need as many insns as it takes to load the constant
1586 into a GPR and one vmv.v.x. */
1590 return 1 + 4; /*vmv.v.x + memory access. */
1595 /* TODO: We may support more const vector in the future. */
1596 return x
== CONST0_RTX (GET_MODE (x
)) ? 1 : 0;
1600 /* See if we can refer to X directly. */
1601 if (riscv_symbolic_constant_p (x
, &symbol_type
))
1602 return riscv_symbol_insns (symbol_type
);
1604 /* Otherwise try splitting the constant into a base and offset. */
1605 split_const (x
, &x
, &offset
);
1608 int n
= riscv_const_insns (x
);
1610 return n
+ riscv_integer_cost (INTVAL (offset
));
1616 return riscv_symbol_insns (riscv_classify_symbol (x
));
1618 /* TODO: In RVV, we get CONST_POLY_INT by using csrr VLENB
1619 instruction and several scalar shift or mult instructions,
1620 it is so far unknown. We set it to 4 temporarily. */
1621 case CONST_POLY_INT
:
1629 /* X is a doubleword constant that can be handled by splitting it into
1630 two words and loading each word separately. Return the number of
1631 instructions required to do this. */
1634 riscv_split_const_insns (rtx x
)
1636 unsigned int low
, high
;
1638 low
= riscv_const_insns (riscv_subword (x
, false));
1639 high
= riscv_const_insns (riscv_subword (x
, true));
1640 gcc_assert (low
> 0 && high
> 0);
1644 /* Return the number of instructions needed to implement INSN,
1645 given that it loads from or stores to MEM. */
1648 riscv_load_store_insns (rtx mem
, rtx_insn
*insn
)
1654 gcc_assert (MEM_P (mem
));
1655 mode
= GET_MODE (mem
);
1657 /* Try to prove that INSN does not need to be split. */
1658 might_split_p
= true;
1659 if (GET_MODE_BITSIZE (mode
).to_constant () <= 32)
1660 might_split_p
= false;
1661 else if (GET_MODE_BITSIZE (mode
).to_constant () == 64)
1663 set
= single_set (insn
);
1664 if (set
&& !riscv_split_64bit_move_p (SET_DEST (set
), SET_SRC (set
)))
1665 might_split_p
= false;
1668 return riscv_address_insns (XEXP (mem
, 0), mode
, might_split_p
);
1671 /* Emit a move from SRC to DEST. Assume that the move expanders can
1672 handle all moves if !can_create_pseudo_p (). The distinction is
1673 important because, unlike emit_move_insn, the move expanders know
1674 how to force Pmode objects into the constant pool even when the
1675 constant pool address is not itself legitimate. */
1678 riscv_emit_move (rtx dest
, rtx src
)
1680 return (can_create_pseudo_p ()
1681 ? emit_move_insn (dest
, src
)
1682 : emit_move_insn_1 (dest
, src
));
1685 /* Emit an instruction of the form (set TARGET SRC). */
1688 riscv_emit_set (rtx target
, rtx src
)
1690 emit_insn (gen_rtx_SET (target
, src
));
1694 /* Emit an instruction of the form (set DEST (CODE X Y)). */
1697 riscv_emit_binary (enum rtx_code code
, rtx dest
, rtx x
, rtx y
)
1699 return riscv_emit_set (dest
, gen_rtx_fmt_ee (code
, GET_MODE (dest
), x
, y
));
1702 /* Compute (CODE X Y) and store the result in a new register
1703 of mode MODE. Return that new register. */
1706 riscv_force_binary (machine_mode mode
, enum rtx_code code
, rtx x
, rtx y
)
1708 return riscv_emit_binary (code
, gen_reg_rtx (mode
), x
, y
);
1712 riscv_swap_instruction (rtx inst
)
1714 gcc_assert (GET_MODE (inst
) == SImode
);
1715 if (BYTES_BIG_ENDIAN
)
1716 inst
= expand_unop (SImode
, bswap_optab
, inst
, gen_reg_rtx (SImode
), 1);
1720 /* Copy VALUE to a register and return that register. If new pseudos
1721 are allowed, copy it into a new register, otherwise use DEST. */
1724 riscv_force_temporary (rtx dest
, rtx value
)
1726 if (can_create_pseudo_p ())
1727 return force_reg (Pmode
, value
);
1730 riscv_emit_move (dest
, value
);
1735 /* Wrap symbol or label BASE in an UNSPEC address of type SYMBOL_TYPE,
1736 then add CONST_INT OFFSET to the result. */
1739 riscv_unspec_address_offset (rtx base
, rtx offset
,
1740 enum riscv_symbol_type symbol_type
)
1742 base
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, base
),
1743 UNSPEC_ADDRESS_FIRST
+ symbol_type
);
1744 if (offset
!= const0_rtx
)
1745 base
= gen_rtx_PLUS (Pmode
, base
, offset
);
1746 return gen_rtx_CONST (Pmode
, base
);
1749 /* Return an UNSPEC address with underlying address ADDRESS and symbol
1750 type SYMBOL_TYPE. */
1753 riscv_unspec_address (rtx address
, enum riscv_symbol_type symbol_type
)
1757 split_const (address
, &base
, &offset
);
1758 return riscv_unspec_address_offset (base
, offset
, symbol_type
);
1761 /* If OP is an UNSPEC address, return the address to which it refers,
1762 otherwise return OP itself. */
1765 riscv_strip_unspec_address (rtx op
)
1769 split_const (op
, &base
, &offset
);
1770 if (UNSPEC_ADDRESS_P (base
))
1771 op
= plus_constant (Pmode
, UNSPEC_ADDRESS (base
), INTVAL (offset
));
1775 /* If riscv_unspec_address (ADDR, SYMBOL_TYPE) is a 32-bit value, add the
1776 high part to BASE and return the result. Just return BASE otherwise.
1777 TEMP is as for riscv_force_temporary.
1779 The returned expression can be used as the first operand to a LO_SUM. */
1782 riscv_unspec_offset_high (rtx temp
, rtx addr
, enum riscv_symbol_type symbol_type
)
1784 addr
= gen_rtx_HIGH (Pmode
, riscv_unspec_address (addr
, symbol_type
));
1785 return riscv_force_temporary (temp
, addr
);
1788 /* Load an entry from the GOT for a TLS GD access. */
1790 static rtx
riscv_got_load_tls_gd (rtx dest
, rtx sym
)
1792 if (Pmode
== DImode
)
1793 return gen_got_load_tls_gddi (dest
, sym
);
1795 return gen_got_load_tls_gdsi (dest
, sym
);
1798 /* Load an entry from the GOT for a TLS IE access. */
1800 static rtx
riscv_got_load_tls_ie (rtx dest
, rtx sym
)
1802 if (Pmode
== DImode
)
1803 return gen_got_load_tls_iedi (dest
, sym
);
1805 return gen_got_load_tls_iesi (dest
, sym
);
1808 /* Add in the thread pointer for a TLS LE access. */
1810 static rtx
riscv_tls_add_tp_le (rtx dest
, rtx base
, rtx sym
)
1812 rtx tp
= gen_rtx_REG (Pmode
, THREAD_POINTER_REGNUM
);
1813 if (Pmode
== DImode
)
1814 return gen_tls_add_tp_ledi (dest
, base
, tp
, sym
);
1816 return gen_tls_add_tp_lesi (dest
, base
, tp
, sym
);
1819 /* If MODE is MAX_MACHINE_MODE, ADDR appears as a move operand, otherwise
1820 it appears in a MEM of that mode. Return true if ADDR is a legitimate
1821 constant in that context and can be split into high and low parts.
1822 If so, and if LOW_OUT is nonnull, emit the high part and store the
1823 low part in *LOW_OUT. Leave *LOW_OUT unchanged otherwise.
1825 TEMP is as for riscv_force_temporary and is used to load the high
1826 part into a register.
1828 When MODE is MAX_MACHINE_MODE, the low part is guaranteed to be
1829 a legitimize SET_SRC for an .md pattern, otherwise the low part
1830 is guaranteed to be a legitimate address for mode MODE. */
1833 riscv_split_symbol (rtx temp
, rtx addr
, machine_mode mode
, rtx
*low_out
)
1835 enum riscv_symbol_type symbol_type
;
1837 if ((GET_CODE (addr
) == HIGH
&& mode
== MAX_MACHINE_MODE
)
1838 || !riscv_symbolic_constant_p (addr
, &symbol_type
)
1839 || riscv_symbol_insns (symbol_type
) == 0
1840 || !riscv_split_symbol_type (symbol_type
))
1844 switch (symbol_type
)
1846 case SYMBOL_ABSOLUTE
:
1848 rtx high
= gen_rtx_HIGH (Pmode
, copy_rtx (addr
));
1849 high
= riscv_force_temporary (temp
, high
);
1850 *low_out
= gen_rtx_LO_SUM (Pmode
, high
, addr
);
1856 static unsigned seqno
;
1860 ssize_t bytes
= snprintf (buf
, sizeof (buf
), ".LA%u", seqno
);
1861 gcc_assert ((size_t) bytes
< sizeof (buf
));
1863 label
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
1864 SYMBOL_REF_FLAGS (label
) |= SYMBOL_FLAG_LOCAL
;
1865 /* ??? Ugly hack to make weak symbols work. May need to change the
1866 RTL for the auipc and/or low patterns to get a better fix for
1868 if (! nonzero_address_p (addr
))
1869 SYMBOL_REF_WEAK (label
) = 1;
1872 temp
= gen_reg_rtx (Pmode
);
1874 if (Pmode
== DImode
)
1875 emit_insn (gen_auipcdi (temp
, copy_rtx (addr
), GEN_INT (seqno
)));
1877 emit_insn (gen_auipcsi (temp
, copy_rtx (addr
), GEN_INT (seqno
)));
1879 *low_out
= gen_rtx_LO_SUM (Pmode
, temp
, label
);
1892 /* Return a legitimate address for REG + OFFSET. TEMP is as for
1893 riscv_force_temporary; it is only needed when OFFSET is not a
1897 riscv_add_offset (rtx temp
, rtx reg
, HOST_WIDE_INT offset
)
1899 if (!SMALL_OPERAND (offset
))
1903 /* Leave OFFSET as a 16-bit offset and put the excess in HIGH.
1904 The addition inside the macro CONST_HIGH_PART may cause an
1905 overflow, so we need to force a sign-extension check. */
1906 high
= gen_int_mode (CONST_HIGH_PART (offset
), Pmode
);
1907 offset
= CONST_LOW_PART (offset
);
1908 high
= riscv_force_temporary (temp
, high
);
1909 reg
= riscv_force_temporary (temp
, gen_rtx_PLUS (Pmode
, high
, reg
));
1911 return plus_constant (Pmode
, reg
, offset
);
1914 /* The __tls_get_attr symbol. */
1915 static GTY(()) rtx riscv_tls_symbol
;
1917 /* Return an instruction sequence that calls __tls_get_addr. SYM is
1918 the TLS symbol we are referencing and TYPE is the symbol type to use
1919 (either global dynamic or local dynamic). RESULT is an RTX for the
1920 return value location. */
1923 riscv_call_tls_get_addr (rtx sym
, rtx result
)
1925 rtx a0
= gen_rtx_REG (Pmode
, GP_ARG_FIRST
), func
;
1928 if (!riscv_tls_symbol
)
1929 riscv_tls_symbol
= init_one_libfunc ("__tls_get_addr");
1930 func
= gen_rtx_MEM (FUNCTION_MODE
, riscv_tls_symbol
);
1934 emit_insn (riscv_got_load_tls_gd (a0
, sym
));
1935 insn
= emit_call_insn (gen_call_value (result
, func
, const0_rtx
,
1936 gen_int_mode (RISCV_CC_BASE
, SImode
)));
1937 RTL_CONST_CALL_P (insn
) = 1;
1938 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), a0
);
1939 insn
= get_insns ();
1946 /* Generate the code to access LOC, a thread-local SYMBOL_REF, and return
1947 its address. The return value will be both a valid address and a valid
1948 SET_SRC (either a REG or a LO_SUM). */
1951 riscv_legitimize_tls_address (rtx loc
)
1954 enum tls_model model
= SYMBOL_REF_TLS_MODEL (loc
);
1957 /* TLS copy relocs are now deprecated and should not be used. */
1958 /* Since we support TLS copy relocs, non-PIC TLS accesses may all use LE. */
1960 model
= TLS_MODEL_LOCAL_EXEC
;
1965 case TLS_MODEL_LOCAL_DYNAMIC
:
1966 /* Rely on section anchors for the optimization that LDM TLS
1967 provides. The anchor's address is loaded with GD TLS. */
1968 case TLS_MODEL_GLOBAL_DYNAMIC
:
1969 tmp
= gen_rtx_REG (Pmode
, GP_RETURN
);
1970 dest
= gen_reg_rtx (Pmode
);
1971 emit_libcall_block (riscv_call_tls_get_addr (loc
, tmp
), dest
, tmp
, loc
);
1974 case TLS_MODEL_INITIAL_EXEC
:
1975 /* la.tls.ie; tp-relative add */
1976 tp
= gen_rtx_REG (Pmode
, THREAD_POINTER_REGNUM
);
1977 tmp
= gen_reg_rtx (Pmode
);
1978 emit_insn (riscv_got_load_tls_ie (tmp
, loc
));
1979 dest
= gen_reg_rtx (Pmode
);
1980 emit_insn (gen_add3_insn (dest
, tmp
, tp
));
1983 case TLS_MODEL_LOCAL_EXEC
:
1984 tmp
= riscv_unspec_offset_high (NULL
, loc
, SYMBOL_TLS_LE
);
1985 dest
= gen_reg_rtx (Pmode
);
1986 emit_insn (riscv_tls_add_tp_le (dest
, tmp
, loc
));
1987 dest
= gen_rtx_LO_SUM (Pmode
, dest
,
1988 riscv_unspec_address (loc
, SYMBOL_TLS_LE
));
1997 /* If X is not a valid address for mode MODE, force it into a register. */
2000 riscv_force_address (rtx x
, machine_mode mode
)
2002 if (!riscv_legitimate_address_p (mode
, x
, false))
2003 x
= force_reg (Pmode
, x
);
2007 /* Modify base + offset so that offset fits within a compressed load/store insn
2008 and the excess is added to base. */
2011 riscv_shorten_lw_offset (rtx base
, HOST_WIDE_INT offset
)
2014 /* Leave OFFSET as an unsigned 5-bit offset scaled by 4 and put the excess
2016 high
= GEN_INT (offset
& ~CSW_MAX_OFFSET
);
2017 offset
&= CSW_MAX_OFFSET
;
2018 if (!SMALL_OPERAND (INTVAL (high
)))
2019 high
= force_reg (Pmode
, high
);
2020 base
= force_reg (Pmode
, gen_rtx_PLUS (Pmode
, high
, base
));
2021 addr
= plus_constant (Pmode
, base
, offset
);
2025 /* Helper for riscv_legitimize_address. Given X, return true if it
2026 is a left shift by 1, 2 or 3 positions or a multiply by 2, 4 or 8.
2028 This respectively represent canonical shift-add rtxs or scaled
2029 memory addresses. */
2031 mem_shadd_or_shadd_rtx_p (rtx x
)
2033 return ((GET_CODE (x
) == ASHIFT
2034 || GET_CODE (x
) == MULT
)
2035 && CONST_INT_P (XEXP (x
, 1))
2036 && ((GET_CODE (x
) == ASHIFT
&& IN_RANGE (INTVAL (XEXP (x
, 1)), 1, 3))
2037 || (GET_CODE (x
) == MULT
2038 && IN_RANGE (exact_log2 (INTVAL (XEXP (x
, 1))), 1, 3))));
2041 /* This function is used to implement LEGITIMIZE_ADDRESS. If X can
2042 be legitimized in a way that the generic machinery might not expect,
2043 return a new address, otherwise return NULL. MODE is the mode of
2044 the memory being accessed. */
2047 riscv_legitimize_address (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
2052 if (riscv_tls_symbol_p (x
))
2053 return riscv_legitimize_tls_address (x
);
2055 /* See if the address can split into a high part and a LO_SUM. */
2056 if (riscv_split_symbol (NULL
, x
, mode
, &addr
))
2057 return riscv_force_address (addr
, mode
);
2059 /* Handle BASE + OFFSET. */
2060 if (GET_CODE (x
) == PLUS
&& CONST_INT_P (XEXP (x
, 1))
2061 && INTVAL (XEXP (x
, 1)) != 0)
2063 rtx base
= XEXP (x
, 0);
2064 HOST_WIDE_INT offset
= INTVAL (XEXP (x
, 1));
2066 /* Handle (plus (plus (mult (a) (mem_shadd_constant)) (fp)) (C)) case. */
2067 if (GET_CODE (base
) == PLUS
&& mem_shadd_or_shadd_rtx_p (XEXP (base
, 0))
2068 && SMALL_OPERAND (offset
))
2070 rtx index
= XEXP (base
, 0);
2071 rtx fp
= XEXP (base
, 1);
2072 if (REG_P (fp
) && REGNO (fp
) == VIRTUAL_STACK_VARS_REGNUM
)
2075 /* If we were given a MULT, we must fix the constant
2076 as we're going to create the ASHIFT form. */
2077 int shift_val
= INTVAL (XEXP (index
, 1));
2078 if (GET_CODE (index
) == MULT
)
2079 shift_val
= exact_log2 (shift_val
);
2081 rtx reg1
= gen_reg_rtx (Pmode
);
2082 rtx reg2
= gen_reg_rtx (Pmode
);
2083 rtx reg3
= gen_reg_rtx (Pmode
);
2084 riscv_emit_binary (PLUS
, reg1
, fp
, GEN_INT (offset
));
2085 riscv_emit_binary (ASHIFT
, reg2
, XEXP (index
, 0), GEN_INT (shift_val
));
2086 riscv_emit_binary (PLUS
, reg3
, reg2
, reg1
);
2092 if (!riscv_valid_base_register_p (base
, mode
, false))
2093 base
= copy_to_mode_reg (Pmode
, base
);
2094 if (optimize_function_for_size_p (cfun
)
2095 && (strcmp (current_pass
->name
, "shorten_memrefs") == 0)
2097 /* Convert BASE + LARGE_OFFSET into NEW_BASE + SMALL_OFFSET to allow
2098 possible compressed load/store. */
2099 addr
= riscv_shorten_lw_offset (base
, offset
);
2101 addr
= riscv_add_offset (NULL
, base
, offset
);
2102 return riscv_force_address (addr
, mode
);
2108 /* Load VALUE into DEST. TEMP is as for riscv_force_temporary. ORIG_MODE
2109 is the original src mode before promotion. */
2112 riscv_move_integer (rtx temp
, rtx dest
, HOST_WIDE_INT value
,
2113 machine_mode orig_mode
)
2115 struct riscv_integer_op codes
[RISCV_MAX_INTEGER_OPS
];
2120 mode
= GET_MODE (dest
);
2121 /* We use the original mode for the riscv_build_integer call, because HImode
2122 values are given special treatment. */
2123 num_ops
= riscv_build_integer (codes
, value
, orig_mode
);
2125 if (can_create_pseudo_p () && num_ops
> 2 /* not a simple constant */
2126 && num_ops
>= riscv_split_integer_cost (value
))
2127 x
= riscv_split_integer (value
, mode
);
2130 codes
[0].value
= trunc_int_for_mode (codes
[0].value
, mode
);
2131 /* Apply each binary operation to X. */
2132 x
= GEN_INT (codes
[0].value
);
2134 for (i
= 1; i
< num_ops
; i
++)
2136 if (!can_create_pseudo_p ())
2137 x
= riscv_emit_set (temp
, x
);
2139 x
= force_reg (mode
, x
);
2140 codes
[i
].value
= trunc_int_for_mode (codes
[i
].value
, mode
);
2141 x
= gen_rtx_fmt_ee (codes
[i
].code
, mode
, x
, GEN_INT (codes
[i
].value
));
2145 riscv_emit_set (dest
, x
);
2148 /* Subroutine of riscv_legitimize_move. Move constant SRC into register
2149 DEST given that SRC satisfies immediate_operand but doesn't satisfy
2153 riscv_legitimize_const_move (machine_mode mode
, rtx dest
, rtx src
)
2157 /* Split moves of big integers into smaller pieces. */
2158 if (splittable_const_int_operand (src
, mode
))
2160 riscv_move_integer (dest
, dest
, INTVAL (src
), mode
);
2164 if (satisfies_constraint_zfli (src
))
2166 riscv_emit_set (dest
, src
);
2170 /* Split moves of symbolic constants into high/low pairs. */
2171 if (riscv_split_symbol (dest
, src
, MAX_MACHINE_MODE
, &src
))
2173 riscv_emit_set (dest
, src
);
2177 /* Generate the appropriate access sequences for TLS symbols. */
2178 if (riscv_tls_symbol_p (src
))
2180 riscv_emit_move (dest
, riscv_legitimize_tls_address (src
));
2184 /* If we have (const (plus symbol offset)), and that expression cannot
2185 be forced into memory, load the symbol first and add in the offset. Also
2186 prefer to do this even if the constant _can_ be forced into memory, as it
2187 usually produces better code. */
2188 split_const (src
, &base
, &offset
);
2189 if (offset
!= const0_rtx
2190 && (targetm
.cannot_force_const_mem (mode
, src
) || can_create_pseudo_p ()))
2192 base
= riscv_force_temporary (dest
, base
);
2193 riscv_emit_move (dest
, riscv_add_offset (NULL
, base
, INTVAL (offset
)));
2197 /* Handle below format.
2200 (symbol_ref:DI ("ic") [flags 0x2] <var_decl 0x7fe57740be10 ic>) <- op_0
2201 (const_poly_int:DI [16, 16]) // <- op_1
2204 if (GET_CODE (src
) == CONST
&& GET_CODE (XEXP (src
, 0)) == PLUS
2205 && CONST_POLY_INT_P (XEXP (XEXP (src
, 0), 1)))
2207 rtx dest_tmp
= gen_reg_rtx (mode
);
2208 rtx tmp
= gen_reg_rtx (mode
);
2210 riscv_emit_move (dest
, XEXP (XEXP (src
, 0), 0));
2211 riscv_legitimize_poly_move (mode
, dest_tmp
, tmp
, XEXP (XEXP (src
, 0), 1));
2213 emit_insn (gen_rtx_SET (dest
, gen_rtx_PLUS (mode
, dest
, dest_tmp
)));
2217 src
= force_const_mem (mode
, src
);
2219 /* When using explicit relocs, constant pool references are sometimes
2220 not legitimate addresses. */
2221 riscv_split_symbol (dest
, XEXP (src
, 0), mode
, &XEXP (src
, 0));
2222 riscv_emit_move (dest
, src
);
2225 /* Report when we try to do something that requires vector when vector is
2226 disabled. This is an error of last resort and isn't very high-quality. It
2227 usually involves attempts to measure the vector length in some way. */
2230 riscv_report_v_required (void)
2232 static bool reported_p
= false;
2234 /* Avoid reporting a slew of messages for a single oversight. */
2238 error ("this operation requires the RVV ISA extension");
2239 inform (input_location
, "you can enable RVV using the command-line"
2240 " option %<-march%>, or by using the %<target%>"
2241 " attribute or pragma");
2245 /* Helper function to operation for rtx_code CODE. */
2247 riscv_expand_op (enum rtx_code code
, machine_mode mode
, rtx op0
, rtx op1
,
2250 if (can_create_pseudo_p ())
2253 if (GET_RTX_CLASS (code
) == RTX_UNARY
)
2254 result
= expand_simple_unop (mode
, code
, op1
, NULL_RTX
, false);
2256 result
= expand_simple_binop (mode
, code
, op1
, op2
, NULL_RTX
, false,
2258 riscv_emit_move (op0
, result
);
2263 /* The following implementation is for prologue and epilogue.
2264 Because prologue and epilogue can not use pseudo register.
2265 We can't using expand_simple_binop or expand_simple_unop. */
2266 if (GET_RTX_CLASS (code
) == RTX_UNARY
)
2267 pat
= gen_rtx_fmt_e (code
, mode
, op1
);
2269 pat
= gen_rtx_fmt_ee (code
, mode
, op1
, op2
);
2270 emit_insn (gen_rtx_SET (op0
, pat
));
2274 /* Expand mult operation with constant integer, multiplicand also used as a
2275 * temporary register. */
2278 riscv_expand_mult_with_const_int (machine_mode mode
, rtx dest
, rtx multiplicand
,
2281 if (multiplier
== 0)
2283 riscv_emit_move (dest
, GEN_INT (0));
2287 bool neg_p
= multiplier
< 0;
2288 int multiplier_abs
= abs (multiplier
);
2290 if (multiplier_abs
== 1)
2293 riscv_expand_op (NEG
, mode
, dest
, multiplicand
, NULL_RTX
);
2295 riscv_emit_move (dest
, multiplicand
);
2299 if (pow2p_hwi (multiplier_abs
))
2302 multiplicand = [BYTES_PER_RISCV_VECTOR].
2303 1. const_poly_int:P [BYTES_PER_RISCV_VECTOR * 8].
2307 2. const_poly_int:P [-BYTES_PER_RISCV_VECTOR * 8].
2313 riscv_expand_op (ASHIFT
, mode
, dest
, multiplicand
,
2314 gen_int_mode (exact_log2 (multiplier_abs
), QImode
));
2316 riscv_expand_op (NEG
, mode
, dest
, dest
, NULL_RTX
);
2318 else if (pow2p_hwi (multiplier_abs
+ 1))
2321 multiplicand = [BYTES_PER_RISCV_VECTOR].
2322 1. const_poly_int:P [BYTES_PER_RISCV_VECTOR * 7].
2327 2. const_poly_int:P [-BYTES_PER_RISCV_VECTOR * 7].
2331 sub a5, a4, a5 + neg a5, a5 => sub a5, a5, a4
2333 riscv_expand_op (ASHIFT
, mode
, dest
, multiplicand
,
2334 gen_int_mode (exact_log2 (multiplier_abs
+ 1),
2337 riscv_expand_op (MINUS
, mode
, dest
, multiplicand
, dest
);
2339 riscv_expand_op (MINUS
, mode
, dest
, dest
, multiplicand
);
2341 else if (pow2p_hwi (multiplier
- 1))
2344 multiplicand = [BYTES_PER_RISCV_VECTOR].
2345 1. const_poly_int:P [BYTES_PER_RISCV_VECTOR * 9].
2350 2. const_poly_int:P [-BYTES_PER_RISCV_VECTOR * 9].
2357 riscv_expand_op (ASHIFT
, mode
, dest
, multiplicand
,
2358 gen_int_mode (exact_log2 (multiplier_abs
- 1),
2360 riscv_expand_op (PLUS
, mode
, dest
, dest
, multiplicand
);
2362 riscv_expand_op (NEG
, mode
, dest
, dest
, NULL_RTX
);
2366 /* We use multiplication for remaining cases. */
2369 && "M-extension must be enabled to calculate the poly_int "
2371 riscv_emit_move (dest
, gen_int_mode (multiplier
, mode
));
2372 riscv_expand_op (MULT
, mode
, dest
, dest
, multiplicand
);
2377 /* Analyze src and emit const_poly_int mov sequence. */
2380 riscv_legitimize_poly_move (machine_mode mode
, rtx dest
, rtx tmp
, rtx src
)
2382 poly_int64 value
= rtx_to_poly_int64 (src
);
2383 int offset
= value
.coeffs
[0];
2384 int factor
= value
.coeffs
[1];
2385 int vlenb
= BYTES_PER_RISCV_VECTOR
.coeffs
[1];
2387 /* Calculate (const_poly_int:MODE [m, n]) using scalar instructions.
2388 For any (const_poly_int:MODE [m, n]), the calculation formula is as
2391 When minimum VLEN = 32, poly of VLENB = (4, 4).
2392 base = vlenb(4, 4) or vlenb/2(2, 2) or vlenb/4(1, 1).
2393 When minimum VLEN > 32, poly of VLENB = (8, 8).
2394 base = vlenb(8, 8) or vlenb/2(4, 4) or vlenb/4(2, 2) or vlenb/8(1, 1).
2395 magn = (n, n) / base.
2396 (m, n) = base * magn + constant.
2397 This calculation doesn't need div operation. */
2399 if (known_le (GET_MODE_SIZE (mode
), GET_MODE_SIZE (Pmode
)))
2400 emit_move_insn (tmp
, gen_int_mode (BYTES_PER_RISCV_VECTOR
, mode
));
2403 emit_move_insn (gen_highpart (Pmode
, tmp
), CONST0_RTX (Pmode
));
2404 emit_move_insn (gen_lowpart (Pmode
, tmp
),
2405 gen_int_mode (BYTES_PER_RISCV_VECTOR
, Pmode
));
2408 if (BYTES_PER_RISCV_VECTOR
.is_constant ())
2410 gcc_assert (value
.is_constant ());
2411 riscv_emit_move (dest
, GEN_INT (value
.to_constant ()));
2416 int max_power
= exact_log2 (MAX_POLY_VARIANT
);
2417 for (int i
= 0; i
<= max_power
; i
++)
2419 int possible_div_factor
= 1 << i
;
2420 if (factor
% (vlenb
/ possible_div_factor
) == 0)
2422 div_factor
= possible_div_factor
;
2426 gcc_assert (div_factor
!= 0);
2429 if (div_factor
!= 1)
2430 riscv_expand_op (LSHIFTRT
, mode
, tmp
, tmp
,
2431 gen_int_mode (exact_log2 (div_factor
), QImode
));
2433 riscv_expand_mult_with_const_int (mode
, dest
, tmp
,
2434 factor
/ (vlenb
/ div_factor
));
2435 HOST_WIDE_INT constant
= offset
- factor
;
2439 else if (SMALL_OPERAND (constant
))
2440 riscv_expand_op (PLUS
, mode
, dest
, dest
, gen_int_mode (constant
, mode
));
2443 /* Handle the constant value is not a 12-bit value. */
2446 /* Leave OFFSET as a 16-bit offset and put the excess in HIGH.
2447 The addition inside the macro CONST_HIGH_PART may cause an
2448 overflow, so we need to force a sign-extension check. */
2449 high
= gen_int_mode (CONST_HIGH_PART (constant
), mode
);
2450 constant
= CONST_LOW_PART (constant
);
2451 riscv_emit_move (tmp
, high
);
2452 riscv_expand_op (PLUS
, mode
, dest
, tmp
, dest
);
2453 riscv_expand_op (PLUS
, mode
, dest
, dest
, gen_int_mode (constant
, mode
));
2457 /* Adjust scalable frame of vector for prologue && epilogue. */
2460 riscv_v_adjust_scalable_frame (rtx target
, poly_int64 offset
, bool epilogue
)
2462 rtx tmp
= RISCV_PROLOGUE_TEMP (Pmode
);
2463 rtx adjust_size
= RISCV_PROLOGUE_TEMP2 (Pmode
);
2464 rtx insn
, dwarf
, adjust_frame_rtx
;
2466 riscv_legitimize_poly_move (Pmode
, adjust_size
, tmp
,
2467 gen_int_mode (offset
, Pmode
));
2470 insn
= gen_add3_insn (target
, target
, adjust_size
);
2472 insn
= gen_sub3_insn (target
, target
, adjust_size
);
2474 insn
= emit_insn (insn
);
2476 RTX_FRAME_RELATED_P (insn
) = 1;
2479 = gen_rtx_SET (target
,
2480 plus_constant (Pmode
, target
, epilogue
? offset
: -offset
));
2482 dwarf
= alloc_reg_note (REG_FRAME_RELATED_EXPR
, copy_rtx (adjust_frame_rtx
),
2485 REG_NOTES (insn
) = dwarf
;
2488 /* If (set DEST SRC) is not a valid move instruction, emit an equivalent
2489 sequence that is valid. */
2492 riscv_legitimize_move (machine_mode mode
, rtx dest
, rtx src
)
2494 if (CONST_POLY_INT_P (src
))
2498 (insn 183 182 184 6 (set (mem:QI (plus:DI (reg/f:DI 156)
2499 (const_int 96 [0x60])) [0 S1 A8])
2500 (const_poly_int:QI [8, 8]))
2501 "../../../../riscv-gcc/libgcc/unwind-dw2.c":1579:3 -1 (nil))
2505 emit_move_insn (dest
, force_reg (mode
, src
));
2508 poly_int64 value
= rtx_to_poly_int64 (src
);
2509 if (!value
.is_constant () && !TARGET_VECTOR
)
2511 riscv_report_v_required ();
2515 if (satisfies_constraint_vp (src
) && GET_MODE (src
) == Pmode
)
2518 if (GET_MODE_SIZE (mode
).to_constant () < GET_MODE_SIZE (Pmode
))
2520 /* In RV32 system, handle (const_poly_int:QI [m, n])
2521 (const_poly_int:HI [m, n]).
2522 In RV64 system, handle (const_poly_int:QI [m, n])
2523 (const_poly_int:HI [m, n])
2524 (const_poly_int:SI [m, n]). */
2525 rtx tmp
= gen_reg_rtx (Pmode
);
2526 riscv_legitimize_poly_move (Pmode
, gen_lowpart (Pmode
, dest
), tmp
,
2531 /* In RV32 system, handle (const_poly_int:SI [m, n])
2532 (const_poly_int:DI [m, n]).
2533 In RV64 system, handle (const_poly_int:DI [m, n]).
2534 FIXME: Maybe we could gen SImode in RV32 and then sign-extend to DImode,
2535 the offset should not exceed 4GiB in general. */
2536 rtx tmp
= gen_reg_rtx (mode
);
2537 riscv_legitimize_poly_move (mode
, dest
, tmp
, src
);
2542 (set (reg:DI target) (subreg:DI (reg:V8QI reg) 0))
2543 Expand this data movement instead of simply forbid it since
2544 we can improve the code generation for this following scenario
2545 by RVV auto-vectorization:
2546 (set (reg:V8QI 149) (vec_duplicate:V8QI (reg:QI))
2547 (set (reg:DI target) (subreg:DI (reg:V8QI reg) 0))
2548 Since RVV mode and scalar mode are in different REG_CLASS,
2549 we need to explicitly move data from V_REGS to GR_REGS by scalar move. */
2550 if (SUBREG_P (src
) && riscv_v_ext_mode_p (GET_MODE (SUBREG_REG (src
))))
2552 machine_mode vmode
= GET_MODE (SUBREG_REG (src
));
2553 unsigned int mode_size
= GET_MODE_SIZE (mode
).to_constant ();
2554 unsigned int vmode_size
= GET_MODE_SIZE (vmode
).to_constant ();
2555 /* We should be able to handle both partial and paradoxical subreg. */
2556 unsigned int nunits
= vmode_size
> mode_size
? vmode_size
/ mode_size
: 1;
2557 scalar_mode smode
= as_a
<scalar_mode
> (mode
);
2558 unsigned int index
= SUBREG_BYTE (src
).to_constant () / mode_size
;
2559 unsigned int num
= smode
== DImode
&& !TARGET_VECTOR_ELEN_64
? 2 : 1;
2563 /* If we want to extract 64bit value but ELEN < 64,
2564 we use RVV vector mode with EEW = 32 to extract
2565 the highpart and lowpart. */
2567 nunits
= nunits
* 2;
2569 vmode
= riscv_vector::get_vector_mode (smode
, nunits
).require ();
2570 enum insn_code icode
2571 = convert_optab_handler (vec_extract_optab
, vmode
, smode
);
2572 gcc_assert (icode
!= CODE_FOR_nothing
);
2573 rtx v
= gen_lowpart (vmode
, SUBREG_REG (src
));
2575 for (unsigned int i
= 0; i
< num
; i
++)
2577 class expand_operand ops
[3];
2582 result
= gen_lowpart (smode
, dest
);
2584 result
= gen_reg_rtx (smode
);
2585 create_output_operand (&ops
[0], result
, smode
);
2587 create_input_operand (&ops
[1], v
, vmode
);
2588 create_integer_operand (&ops
[2], index
+ i
);
2589 expand_insn (icode
, 3, ops
);
2590 if (ops
[0].value
!= result
)
2591 emit_move_insn (result
, ops
[0].value
);
2596 = expand_binop (Pmode
, ashl_optab
, gen_lowpart (Pmode
, result
),
2597 gen_int_mode (32, Pmode
), NULL_RTX
, 0,
2599 rtx tmp2
= expand_binop (Pmode
, ior_optab
, tmp
, dest
, NULL_RTX
, 0,
2601 emit_move_insn (dest
, tmp2
);
2607 (set (reg:QI target) (mem:QI (address)))
2609 (set (reg:DI temp) (zero_extend:DI (mem:QI (address))))
2610 (set (reg:QI target) (subreg:QI (reg:DI temp) 0))
2611 with auto-sign/zero extend. */
2612 if (GET_MODE_CLASS (mode
) == MODE_INT
2613 && GET_MODE_SIZE (mode
).to_constant () < UNITS_PER_WORD
2614 && can_create_pseudo_p ()
2620 temp_reg
= gen_reg_rtx (word_mode
);
2621 zero_extend_p
= (LOAD_EXTEND_OP (mode
) == ZERO_EXTEND
);
2622 emit_insn (gen_extend_insn (temp_reg
, src
, word_mode
, mode
,
2624 riscv_emit_move (dest
, gen_lowpart (mode
, temp_reg
));
2628 if (!register_operand (dest
, mode
) && !reg_or_0_operand (src
, mode
))
2632 if (GET_CODE (src
) == CONST_INT
)
2634 /* Apply the equivalent of PROMOTE_MODE here for constants to
2636 machine_mode promoted_mode
= mode
;
2637 if (GET_MODE_CLASS (mode
) == MODE_INT
2638 && GET_MODE_SIZE (mode
).to_constant () < UNITS_PER_WORD
)
2639 promoted_mode
= word_mode
;
2641 if (splittable_const_int_operand (src
, mode
))
2643 reg
= gen_reg_rtx (promoted_mode
);
2644 riscv_move_integer (reg
, reg
, INTVAL (src
), mode
);
2647 reg
= force_reg (promoted_mode
, src
);
2649 if (promoted_mode
!= mode
)
2650 reg
= gen_lowpart (mode
, reg
);
2653 reg
= force_reg (mode
, src
);
2654 riscv_emit_move (dest
, reg
);
2658 /* We need to deal with constants that would be legitimate
2659 immediate_operands but aren't legitimate move_operands. */
2660 if (CONSTANT_P (src
) && !move_operand (src
, mode
))
2662 riscv_legitimize_const_move (mode
, dest
, src
);
2663 set_unique_reg_note (get_last_insn (), REG_EQUAL
, copy_rtx (src
));
2667 /* RISC-V GCC may generate non-legitimate address due to we provide some
2668 pattern for optimize access PIC local symbol and it's make GCC generate
2669 unrecognizable instruction during optmizing. */
2671 if (MEM_P (dest
) && !riscv_legitimate_address_p (mode
, XEXP (dest
, 0),
2674 XEXP (dest
, 0) = riscv_force_address (XEXP (dest
, 0), mode
);
2677 if (MEM_P (src
) && !riscv_legitimate_address_p (mode
, XEXP (src
, 0),
2680 XEXP (src
, 0) = riscv_force_address (XEXP (src
, 0), mode
);
2686 /* Return true if there is an instruction that implements CODE and accepts
2687 X as an immediate operand. */
2690 riscv_immediate_operand_p (int code
, HOST_WIDE_INT x
)
2697 /* All shift counts are truncated to a valid constant. */
2706 /* These instructions take 12-bit signed immediates. */
2707 return SMALL_OPERAND (x
);
2710 /* We add 1 to the immediate and use SLT. */
2711 return SMALL_OPERAND (x
+ 1);
2714 /* Likewise SLTU, but reject the always-true case. */
2715 return SMALL_OPERAND (x
+ 1) && x
+ 1 != 0;
2719 /* We can emulate an immediate of 1 by using GT/GTU against x0. */
2723 /* By default assume that x0 can be used for 0. */
2728 /* Return the cost of binary operation X, given that the instruction
2729 sequence for a word-sized or smaller operation takes SIGNLE_INSNS
2730 instructions and that the sequence of a double-word operation takes
2731 DOUBLE_INSNS instructions. */
2734 riscv_binary_cost (rtx x
, int single_insns
, int double_insns
)
2736 if (!riscv_v_ext_mode_p (GET_MODE (x
))
2737 && GET_MODE_SIZE (GET_MODE (x
)).to_constant () == UNITS_PER_WORD
* 2)
2738 return COSTS_N_INSNS (double_insns
);
2739 return COSTS_N_INSNS (single_insns
);
2742 /* Return the cost of sign- or zero-extending OP. */
2745 riscv_extend_cost (rtx op
, bool unsigned_p
)
2750 if (unsigned_p
&& GET_MODE (op
) == QImode
)
2751 /* We can use ANDI. */
2752 return COSTS_N_INSNS (1);
2754 /* ZBA provide zext.w. */
2755 if (TARGET_ZBA
&& TARGET_64BIT
&& unsigned_p
&& GET_MODE (op
) == SImode
)
2756 return COSTS_N_INSNS (1);
2758 /* ZBB provide zext.h, sext.b and sext.h. */
2761 if (!unsigned_p
&& GET_MODE (op
) == QImode
)
2762 return COSTS_N_INSNS (1);
2764 if (GET_MODE (op
) == HImode
)
2765 return COSTS_N_INSNS (1);
2768 if (!unsigned_p
&& GET_MODE (op
) == SImode
)
2769 /* We can use SEXT.W. */
2770 return COSTS_N_INSNS (1);
2772 /* We need to use a shift left and a shift right. */
2773 return COSTS_N_INSNS (2);
2776 /* Implement TARGET_RTX_COSTS. */
2778 #define SINGLE_SHIFT_COST 1
2781 riscv_rtx_costs (rtx x
, machine_mode mode
, int outer_code
, int opno ATTRIBUTE_UNUSED
,
2782 int *total
, bool speed
)
2784 /* TODO: We set RVV instruction cost as 1 by default.
2785 Cost Model need to be well analyzed and supported in the future. */
2786 if (riscv_v_ext_mode_p (mode
))
2788 *total
= COSTS_N_INSNS (1);
2792 bool float_mode_p
= FLOAT_MODE_P (mode
);
2795 switch (GET_CODE (x
))
2798 /* If we are called for an INSN that's a simple set of a register,
2799 then cost based on the SET_SRC alone. */
2800 if (outer_code
== INSN
&& REG_P (SET_DEST (x
)))
2802 riscv_rtx_costs (SET_SRC (x
), mode
, outer_code
, opno
, total
, speed
);
2806 /* Otherwise return FALSE indicating we should recurse into both the
2807 SET_DEST and SET_SRC combining the cost of both. */
2811 /* trivial constants checked using OUTER_CODE in case they are
2812 encodable in insn itself w/o need for additional insn(s). */
2813 if (riscv_immediate_operand_p (outer_code
, INTVAL (x
)))
2823 /* With TARGET_SUPPORTS_WIDE_INT const int can't be in CONST_DOUBLE
2824 rtl object. Weird recheck due to switch-case fall through above. */
2825 if (GET_CODE (x
) == CONST_DOUBLE
)
2826 gcc_assert (GET_MODE (x
) != VOIDmode
);
2830 /* Non trivial CONST_INT Fall through: check if need multiple insns. */
2831 if ((cost
= riscv_const_insns (x
)) > 0)
2833 /* 1. Hoist will GCSE constants only if TOTAL returned is non-zero.
2834 2. For constants loaded more than once, the approach so far has
2835 been to duplicate the operation than to CSE the constant.
2836 3. TODO: make cost more accurate specially if riscv_const_insns
2838 if (outer_code
== SET
|| GET_MODE (x
) == VOIDmode
)
2839 *total
= COSTS_N_INSNS (1);
2841 else /* The instruction will be fetched from the constant pool. */
2842 *total
= COSTS_N_INSNS (riscv_symbol_insns (SYMBOL_ABSOLUTE
));
2846 /* If the address is legitimate, return the number of
2847 instructions it needs. */
2848 if ((cost
= riscv_address_insns (XEXP (x
, 0), mode
, true)) > 0)
2850 /* When optimizing for size, make uncompressible 32-bit addresses
2851 more expensive so that compressible 32-bit addresses are
2853 if ((TARGET_RVC
|| TARGET_ZCA
)
2854 && !speed
&& riscv_mshorten_memrefs
&& mode
== SImode
2855 && !riscv_compressed_lw_address_p (XEXP (x
, 0)))
2858 *total
= COSTS_N_INSNS (cost
+ tune_param
->memory_cost
);
2861 /* Otherwise use the default handling. */
2865 if ((TARGET_SFB_ALU
|| TARGET_XTHEADCONDMOV
)
2866 && reg_or_0_operand (XEXP (x
, 1), mode
)
2867 && sfb_alu_operand (XEXP (x
, 2), mode
)
2868 && comparison_operator (XEXP (x
, 0), VOIDmode
))
2870 /* For predicated conditional-move operations we assume the cost
2871 of a single instruction even though there are actually two. */
2872 *total
= COSTS_N_INSNS (1);
2875 else if (TARGET_ZICOND_LIKE
2876 && outer_code
== SET
2877 && ((GET_CODE (XEXP (x
, 1)) == REG
2878 && XEXP (x
, 2) == CONST0_RTX (GET_MODE (XEXP (x
, 1))))
2879 || (GET_CODE (XEXP (x
, 2)) == REG
2880 && XEXP (x
, 1) == CONST0_RTX (GET_MODE (XEXP (x
, 2))))
2881 || (GET_CODE (XEXP (x
, 1)) == REG
2882 && rtx_equal_p (XEXP (x
, 1), XEXP (XEXP (x
, 0), 0)))
2883 || (GET_CODE (XEXP (x
, 1)) == REG
2884 && rtx_equal_p (XEXP (x
, 2), XEXP (XEXP (x
, 0), 0)))))
2886 *total
= COSTS_N_INSNS (1);
2889 else if (LABEL_REF_P (XEXP (x
, 1)) && XEXP (x
, 2) == pc_rtx
)
2891 if (equality_operator (XEXP (x
, 0), mode
)
2892 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == ZERO_EXTRACT
)
2894 *total
= COSTS_N_INSNS (SINGLE_SHIFT_COST
+ 1);
2897 if (order_operator (XEXP (x
, 0), mode
))
2899 *total
= COSTS_N_INSNS (1);
2906 *total
= COSTS_N_INSNS (GET_MODE_SIZE (mode
).to_constant () > UNITS_PER_WORD
? 2 : 1);
2910 /* slli.uw pattern for zba. */
2911 if (TARGET_ZBA
&& TARGET_64BIT
&& mode
== DImode
2912 && GET_CODE (XEXP (x
, 0)) == ASHIFT
)
2914 rtx and_rhs
= XEXP (x
, 1);
2915 rtx ashift_lhs
= XEXP (XEXP (x
, 0), 0);
2916 rtx ashift_rhs
= XEXP (XEXP (x
, 0), 1);
2917 if (REG_P (ashift_lhs
)
2918 && CONST_INT_P (ashift_rhs
)
2919 && CONST_INT_P (and_rhs
)
2920 && ((INTVAL (and_rhs
) >> INTVAL (ashift_rhs
)) == 0xffffffff))
2921 *total
= COSTS_N_INSNS (1);
2924 /* bclri pattern for zbs. */
2926 && not_single_bit_mask_operand (XEXP (x
, 1), VOIDmode
))
2928 *total
= COSTS_N_INSNS (1);
2931 /* bclr pattern for zbs. */
2933 && REG_P (XEXP (x
, 1))
2934 && GET_CODE (XEXP (x
, 0)) == ROTATE
2935 && CONST_INT_P (XEXP ((XEXP (x
, 0)), 0))
2936 && INTVAL (XEXP ((XEXP (x
, 0)), 0)) == -2)
2938 *total
= COSTS_N_INSNS (1);
2945 /* orn, andn and xorn pattern for zbb. */
2947 && GET_CODE (XEXP (x
, 0)) == NOT
)
2949 *total
= riscv_binary_cost (x
, 1, 2);
2953 /* bset[i] and binv[i] pattern for zbs. */
2954 if ((GET_CODE (x
) == IOR
|| GET_CODE (x
) == XOR
)
2956 && ((GET_CODE (XEXP (x
, 0)) == ASHIFT
2957 && CONST_INT_P (XEXP (XEXP (x
, 0), 0)))
2958 || single_bit_mask_operand (XEXP (x
, 1), VOIDmode
)))
2960 *total
= COSTS_N_INSNS (1);
2964 /* Double-word operations use two single-word operations. */
2965 *total
= riscv_binary_cost (x
, 1, 2);
2969 /* This is an SImode shift. */
2970 if (outer_code
== SET
2971 && CONST_INT_P (XEXP (x
, 1))
2972 && CONST_INT_P (XEXP (x
, 2))
2973 && (INTVAL (XEXP (x
, 2)) > 0)
2974 && (INTVAL (XEXP (x
, 1)) + INTVAL (XEXP (x
, 2)) == 32))
2976 *total
= COSTS_N_INSNS (SINGLE_SHIFT_COST
);
2979 /* bit extraction pattern (zbs:bext, xtheadbs:tst). */
2980 if ((TARGET_ZBS
|| TARGET_XTHEADBS
) && outer_code
== SET
2981 && GET_CODE (XEXP (x
, 1)) == CONST_INT
2982 && INTVAL (XEXP (x
, 1)) == 1)
2984 *total
= COSTS_N_INSNS (SINGLE_SHIFT_COST
);
2989 if (TARGET_XTHEADBB
&& outer_code
== SET
2990 && CONST_INT_P (XEXP (x
, 1))
2991 && CONST_INT_P (XEXP (x
, 2)))
2993 *total
= COSTS_N_INSNS (SINGLE_SHIFT_COST
);
2999 /* bset pattern for zbs. */
3001 && CONST_INT_P (XEXP (x
, 0))
3002 && INTVAL (XEXP (x
, 0)) == 1)
3004 *total
= COSTS_N_INSNS (1);
3010 *total
= riscv_binary_cost (x
, SINGLE_SHIFT_COST
,
3011 CONSTANT_P (XEXP (x
, 1)) ? 4 : 9);
3015 *total
= COSTS_N_INSNS (float_mode_p
? 1 : 3);
3019 *total
= set_src_cost (XEXP (x
, 0), mode
, speed
);
3023 /* This is an SImode shift. */
3024 if (outer_code
== SET
&& GET_MODE (x
) == DImode
3025 && GET_MODE (XEXP (x
, 0)) == SImode
)
3027 *total
= COSTS_N_INSNS (SINGLE_SHIFT_COST
);
3040 /* Branch comparisons have VOIDmode, so use the first operand's
3042 mode
= GET_MODE (XEXP (x
, 0));
3044 *total
= tune_param
->fp_add
[mode
== DFmode
];
3046 *total
= riscv_binary_cost (x
, 1, 3);
3051 /* (FEQ(A, A) & FEQ(B, B)) compared against 0. */
3052 mode
= GET_MODE (XEXP (x
, 0));
3053 *total
= tune_param
->fp_add
[mode
== DFmode
] + COSTS_N_INSNS (2);
3057 /* (FEQ(A, A) & FEQ(B, B)) compared against FEQ(A, B). */
3058 mode
= GET_MODE (XEXP (x
, 0));
3059 *total
= tune_param
->fp_add
[mode
== DFmode
] + COSTS_N_INSNS (3);
3063 /* (FLT(A, A) || FGT(B, B)). */
3064 mode
= GET_MODE (XEXP (x
, 0));
3065 *total
= tune_param
->fp_add
[mode
== DFmode
] + COSTS_N_INSNS (2);
3072 /* FLT or FLE, but guarded by an FFLAGS read and write. */
3073 mode
= GET_MODE (XEXP (x
, 0));
3074 *total
= tune_param
->fp_add
[mode
== DFmode
] + COSTS_N_INSNS (4);
3079 *total
= tune_param
->fp_add
[mode
== DFmode
];
3081 *total
= riscv_binary_cost (x
, 1, 4);
3085 /* add.uw pattern for zba. */
3087 && (TARGET_64BIT
&& (mode
== DImode
))
3088 && GET_CODE (XEXP (x
, 0)) == ZERO_EXTEND
3089 && REG_P (XEXP (XEXP (x
, 0), 0))
3090 && GET_MODE (XEXP (XEXP (x
, 0), 0)) == SImode
)
3092 *total
= COSTS_N_INSNS (1);
3095 /* shNadd pattern for zba. */
3097 && ((!TARGET_64BIT
&& (mode
== SImode
)) ||
3098 (TARGET_64BIT
&& (mode
== DImode
)))
3099 && (GET_CODE (XEXP (x
, 0)) == ASHIFT
)
3100 && REG_P (XEXP (XEXP (x
, 0), 0))
3101 && CONST_INT_P (XEXP (XEXP (x
, 0), 1))
3102 && IN_RANGE (INTVAL (XEXP (XEXP (x
, 0), 1)), 1, 3))
3104 *total
= COSTS_N_INSNS (1);
3107 /* Before strength-reduction, the shNadd can be expressed as the addition
3108 of a multiplication with a power-of-two. If this case is not handled,
3109 the strength-reduction in expmed.c will calculate an inflated cost. */
3111 && mode
== word_mode
3112 && GET_CODE (XEXP (x
, 0)) == MULT
3113 && REG_P (XEXP (XEXP (x
, 0), 0))
3114 && CONST_INT_P (XEXP (XEXP (x
, 0), 1))
3115 && pow2p_hwi (INTVAL (XEXP (XEXP (x
, 0), 1)))
3116 && IN_RANGE (exact_log2 (INTVAL (XEXP (XEXP (x
, 0), 1))), 1, 3))
3118 *total
= COSTS_N_INSNS (1);
3121 /* shNadd.uw pattern for zba.
3122 [(set (match_operand:DI 0 "register_operand" "=r")
3124 (and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r")
3125 (match_operand:QI 2 "immediate_operand" "I"))
3126 (match_operand 3 "immediate_operand" ""))
3127 (match_operand:DI 4 "register_operand" "r")))]
3128 "TARGET_64BIT && TARGET_ZBA
3129 && (INTVAL (operands[2]) >= 1) && (INTVAL (operands[2]) <= 3)
3130 && (INTVAL (operands[3]) >> INTVAL (operands[2])) == 0xffffffff"
3133 && (TARGET_64BIT
&& (mode
== DImode
))
3134 && (GET_CODE (XEXP (x
, 0)) == AND
)
3135 && (REG_P (XEXP (x
, 1))))
3138 rtx and_lhs
= XEXP (XEXP (x
, 0), 0);
3139 rtx and_rhs
= XEXP (XEXP (x
, 0), 1);
3140 if (GET_CODE (and_lhs
) != ASHIFT
)
3142 if (!CONST_INT_P (and_rhs
))
3145 rtx ashift_rhs
= XEXP (and_lhs
, 1);
3147 if (!CONST_INT_P (ashift_rhs
)
3148 || !IN_RANGE (INTVAL (ashift_rhs
), 1, 3))
3151 if (CONST_INT_P (and_rhs
)
3152 && ((INTVAL (and_rhs
) >> INTVAL (ashift_rhs
)) == 0xffffffff))
3154 *total
= COSTS_N_INSNS (1);
3161 *total
= tune_param
->fp_add
[mode
== DFmode
];
3163 *total
= riscv_binary_cost (x
, 1, 4);
3168 rtx op
= XEXP (x
, 0);
3169 if (GET_CODE (op
) == FMA
&& !HONOR_SIGNED_ZEROS (mode
))
3171 *total
= (tune_param
->fp_mul
[mode
== DFmode
]
3172 + set_src_cost (XEXP (op
, 0), mode
, speed
)
3173 + set_src_cost (XEXP (op
, 1), mode
, speed
)
3174 + set_src_cost (XEXP (op
, 2), mode
, speed
));
3180 *total
= tune_param
->fp_add
[mode
== DFmode
];
3182 *total
= COSTS_N_INSNS (GET_MODE_SIZE (mode
).to_constant () > UNITS_PER_WORD
? 4 : 1);
3187 *total
= tune_param
->fp_mul
[mode
== DFmode
];
3188 else if (!TARGET_MUL
)
3189 /* Estimate the cost of a library call. */
3190 *total
= COSTS_N_INSNS (speed
? 32 : 6);
3191 else if (GET_MODE_SIZE (mode
).to_constant () > UNITS_PER_WORD
)
3192 *total
= 3 * tune_param
->int_mul
[0] + COSTS_N_INSNS (2);
3194 *total
= COSTS_N_INSNS (1);
3196 *total
= tune_param
->int_mul
[mode
== DImode
];
3204 *total
= tune_param
->fp_div
[mode
== DFmode
];
3212 /* Estimate the cost of a library call. */
3213 *total
= COSTS_N_INSNS (speed
? 32 : 6);
3215 *total
= tune_param
->int_div
[mode
== DImode
];
3217 *total
= COSTS_N_INSNS (1);
3221 /* This is an SImode shift. */
3222 if (GET_CODE (XEXP (x
, 0)) == LSHIFTRT
)
3224 *total
= COSTS_N_INSNS (SINGLE_SHIFT_COST
);
3229 *total
= riscv_extend_cost (XEXP (x
, 0), GET_CODE (x
) == ZERO_EXTEND
);
3235 /* RISC-V only defines rev8 for XLEN, so we will need an extra
3236 shift-right instruction for smaller modes. */
3237 *total
= COSTS_N_INSNS (mode
== word_mode
? 1 : 2);
3243 case UNSIGNED_FLOAT
:
3246 case FLOAT_TRUNCATE
:
3247 *total
= tune_param
->fp_add
[mode
== DFmode
];
3251 *total
= (tune_param
->fp_mul
[mode
== DFmode
]
3252 + set_src_cost (XEXP (x
, 0), mode
, speed
)
3253 + set_src_cost (XEXP (x
, 1), mode
, speed
)
3254 + set_src_cost (XEXP (x
, 2), mode
, speed
));
3258 if (XINT (x
, 1) == UNSPEC_AUIPC
)
3260 /* Make AUIPC cheap to avoid spilling its result to the stack. */
3271 /* Implement TARGET_ADDRESS_COST. */
3274 riscv_address_cost (rtx addr
, machine_mode mode
,
3275 addr_space_t as ATTRIBUTE_UNUSED
,
3276 bool speed ATTRIBUTE_UNUSED
)
3278 /* When optimizing for size, make uncompressible 32-bit addresses more
3279 * expensive so that compressible 32-bit addresses are preferred. */
3280 if ((TARGET_RVC
|| TARGET_ZCA
)
3281 && !speed
&& riscv_mshorten_memrefs
&& mode
== SImode
3282 && !riscv_compressed_lw_address_p (addr
))
3283 return riscv_address_insns (addr
, mode
, false) + 1;
3284 return riscv_address_insns (addr
, mode
, false);
3287 /* Return one word of double-word value OP. HIGH_P is true to select the
3288 high part or false to select the low part. */
3291 riscv_subword (rtx op
, bool high_p
)
3293 unsigned int byte
= (high_p
!= BYTES_BIG_ENDIAN
) ? UNITS_PER_WORD
: 0;
3294 machine_mode mode
= GET_MODE (op
);
3296 if (mode
== VOIDmode
)
3297 mode
= TARGET_64BIT
? TImode
: DImode
;
3300 return adjust_address (op
, word_mode
, byte
);
3303 gcc_assert (!FP_REG_RTX_P (op
));
3305 return simplify_gen_subreg (word_mode
, op
, mode
, byte
);
3308 /* Return true if a 64-bit move from SRC to DEST should be split into two. */
3311 riscv_split_64bit_move_p (rtx dest
, rtx src
)
3316 /* There is no need to split if the FLI instruction in the `Zfa` extension can be used. */
3317 if (satisfies_constraint_zfli (src
))
3320 /* Allow FPR <-> FPR and FPR <-> MEM moves, and permit the special case
3321 of zeroing an FPR with FCVT.D.W. */
3322 if (TARGET_DOUBLE_FLOAT
3323 && ((FP_REG_RTX_P (src
) && FP_REG_RTX_P (dest
))
3324 || (FP_REG_RTX_P (dest
) && MEM_P (src
))
3325 || (FP_REG_RTX_P (src
) && MEM_P (dest
))
3326 || (FP_REG_RTX_P (dest
) && src
== CONST0_RTX (GET_MODE (src
)))))
3332 /* Split a doubleword move from SRC to DEST. On 32-bit targets,
3333 this function handles 64-bit moves for which riscv_split_64bit_move_p
3334 holds. For 64-bit targets, this function handles 128-bit moves. */
3337 riscv_split_doubleword_move (rtx dest
, rtx src
)
3339 /* ZFA or XTheadFmv has instructions for accessing the upper bits of a double. */
3340 if (!TARGET_64BIT
&& (TARGET_ZFA
|| TARGET_XTHEADFMV
))
3342 if (FP_REG_RTX_P (dest
))
3344 rtx low_src
= riscv_subword (src
, false);
3345 rtx high_src
= riscv_subword (src
, true);
3348 emit_insn (gen_movdfsisi3_rv32 (dest
, high_src
, low_src
));
3350 emit_insn (gen_th_fmv_hw_w_x (dest
, high_src
, low_src
));
3353 if (FP_REG_RTX_P (src
))
3355 rtx low_dest
= riscv_subword (dest
, false);
3356 rtx high_dest
= riscv_subword (dest
, true);
3360 emit_insn (gen_movsidf2_low_rv32 (low_dest
, src
));
3361 emit_insn (gen_movsidf2_high_rv32 (high_dest
, src
));
3366 emit_insn (gen_th_fmv_x_w (low_dest
, src
));
3367 emit_insn (gen_th_fmv_x_hw (high_dest
, src
));
3373 /* The operation can be split into two normal moves. Decide in
3374 which order to do them. */
3375 rtx low_dest
= riscv_subword (dest
, false);
3376 if (REG_P (low_dest
) && reg_overlap_mentioned_p (low_dest
, src
))
3378 riscv_emit_move (riscv_subword (dest
, true), riscv_subword (src
, true));
3379 riscv_emit_move (low_dest
, riscv_subword (src
, false));
3383 riscv_emit_move (low_dest
, riscv_subword (src
, false));
3384 riscv_emit_move (riscv_subword (dest
, true), riscv_subword (src
, true));
3388 /* Return the appropriate instructions to move SRC into DEST. Assume
3389 that SRC is operand 1 and DEST is operand 0. */
3392 riscv_output_move (rtx dest
, rtx src
)
3394 enum rtx_code dest_code
, src_code
;
3400 if ((insn
= th_output_move (dest
, src
)))
3403 dest_code
= GET_CODE (dest
);
3404 src_code
= GET_CODE (src
);
3405 mode
= GET_MODE (dest
);
3406 dbl_p
= (GET_MODE_SIZE (mode
).to_constant () == 8);
3407 width
= GET_MODE_SIZE (mode
).to_constant ();
3409 if (dbl_p
&& riscv_split_64bit_move_p (dest
, src
))
3412 if (dest_code
== REG
&& GP_REG_P (REGNO (dest
)))
3414 if (src_code
== REG
&& FP_REG_P (REGNO (src
)))
3419 return "fmv.x.h\t%0,%1";
3420 /* Using fmv.x.s + sign-extend to emulate fmv.x.h. */
3421 return "fmv.x.s\t%0,%1;slli\t%0,%0,16;srai\t%0,%0,16";
3423 return "fmv.x.s\t%0,%1";
3425 return "fmv.x.d\t%0,%1";
3428 if (src_code
== MEM
)
3431 case 1: return "lbu\t%0,%1";
3432 case 2: return "lhu\t%0,%1";
3433 case 4: return "lw\t%0,%1";
3434 case 8: return "ld\t%0,%1";
3437 if (src_code
== CONST_INT
)
3439 if (SMALL_OPERAND (INTVAL (src
)) || LUI_OPERAND (INTVAL (src
)))
3443 && SINGLE_BIT_MASK_OPERAND (INTVAL (src
)))
3444 return "bseti\t%0,zero,%S1";
3446 /* Should never reach here. */
3450 if (src_code
== HIGH
)
3451 return "lui\t%0,%h1";
3453 if (symbolic_operand (src
, VOIDmode
))
3454 switch (riscv_classify_symbolic_expression (src
))
3456 case SYMBOL_GOT_DISP
: return "la\t%0,%1";
3457 case SYMBOL_ABSOLUTE
: return "lla\t%0,%1";
3458 case SYMBOL_PCREL
: return "lla\t%0,%1";
3459 default: gcc_unreachable ();
3462 if ((src_code
== REG
&& GP_REG_P (REGNO (src
)))
3463 || (src
== CONST0_RTX (mode
)))
3465 if (dest_code
== REG
)
3467 if (GP_REG_P (REGNO (dest
)))
3468 return "mv\t%0,%z1";
3470 if (FP_REG_P (REGNO (dest
)))
3475 return "fmv.h.x\t%0,%z1";
3476 /* High 16 bits should be all-1, otherwise HW will treated
3477 as a n-bit canonical NaN, but isn't matter for softfloat. */
3478 return "fmv.s.x\t%0,%1";
3480 return "fmv.s.x\t%0,%z1";
3483 return "fmv.d.x\t%0,%z1";
3484 /* in RV32, we can emulate fmv.d.x %0, x0 using fcvt.d.w */
3485 gcc_assert (src
== CONST0_RTX (mode
));
3486 return "fcvt.d.w\t%0,x0";
3489 if (dest_code
== MEM
)
3492 case 1: return "sb\t%z1,%0";
3493 case 2: return "sh\t%z1,%0";
3494 case 4: return "sw\t%z1,%0";
3495 case 8: return "sd\t%z1,%0";
3498 if (src_code
== REG
&& FP_REG_P (REGNO (src
)))
3500 if (dest_code
== REG
&& FP_REG_P (REGNO (dest
)))
3505 return "fmv.h\t%0,%1";
3506 return "fmv.s\t%0,%1";
3508 return "fmv.s\t%0,%1";
3510 return "fmv.d\t%0,%1";
3513 if (dest_code
== MEM
)
3517 return "fsh\t%1,%0";
3519 return "fsw\t%1,%0";
3521 return "fsd\t%1,%0";
3524 if (dest_code
== REG
&& FP_REG_P (REGNO (dest
)))
3526 if (src_code
== MEM
)
3530 return "flh\t%0,%1";
3532 return "flw\t%0,%1";
3534 return "fld\t%0,%1";
3537 if (src_code
== CONST_DOUBLE
&& satisfies_constraint_zfli (src
))
3541 return "fli.h\t%0,%1";
3543 return "fli.s\t%0,%1";
3545 return "fli.d\t%0,%1";
3548 if (dest_code
== REG
&& GP_REG_P (REGNO (dest
)) && src_code
== CONST_POLY_INT
)
3550 /* We only want a single full vector register VLEN read after reload. */
3551 gcc_assert (known_eq (rtx_to_poly_int64 (src
), BYTES_PER_RISCV_VECTOR
));
3552 return "csrr\t%0,vlenb";
3558 riscv_output_return ()
3560 if (cfun
->machine
->naked_p
)
3567 /* Return true if CMP1 is a suitable second operand for integer ordering
3568 test CODE. See also the *sCC patterns in riscv.md. */
3571 riscv_int_order_operand_ok_p (enum rtx_code code
, rtx cmp1
)
3577 return reg_or_0_operand (cmp1
, VOIDmode
);
3581 return cmp1
== const1_rtx
;
3585 return arith_operand (cmp1
, VOIDmode
);
3588 return sle_operand (cmp1
, VOIDmode
);
3591 return sleu_operand (cmp1
, VOIDmode
);
3598 /* Return true if *CMP1 (of mode MODE) is a valid second operand for
3599 integer ordering test *CODE, or if an equivalent combination can
3600 be formed by adjusting *CODE and *CMP1. When returning true, update
3601 *CODE and *CMP1 with the chosen code and operand, otherwise leave
3605 riscv_canonicalize_int_order_test (enum rtx_code
*code
, rtx
*cmp1
,
3608 HOST_WIDE_INT plus_one
;
3610 if (riscv_int_order_operand_ok_p (*code
, *cmp1
))
3613 if (CONST_INT_P (*cmp1
))
3617 plus_one
= trunc_int_for_mode (UINTVAL (*cmp1
) + 1, mode
);
3618 if (INTVAL (*cmp1
) < plus_one
)
3621 *cmp1
= force_reg (mode
, GEN_INT (plus_one
));
3627 plus_one
= trunc_int_for_mode (UINTVAL (*cmp1
) + 1, mode
);
3631 *cmp1
= force_reg (mode
, GEN_INT (plus_one
));
3642 /* Compare CMP0 and CMP1 using ordering test CODE and store the result
3643 in TARGET. CMP0 and TARGET are register_operands. If INVERT_PTR
3644 is nonnull, it's OK to set TARGET to the inverse of the result and
3645 flip *INVERT_PTR instead. */
3648 riscv_emit_int_order_test (enum rtx_code code
, bool *invert_ptr
,
3649 rtx target
, rtx cmp0
, rtx cmp1
)
3653 /* First see if there is a RISCV instruction that can do this operation.
3654 If not, try doing the same for the inverse operation. If that also
3655 fails, force CMP1 into a register and try again. */
3656 mode
= GET_MODE (cmp0
);
3657 if (riscv_canonicalize_int_order_test (&code
, &cmp1
, mode
))
3658 riscv_emit_binary (code
, target
, cmp0
, cmp1
);
3661 enum rtx_code inv_code
= reverse_condition (code
);
3662 if (!riscv_canonicalize_int_order_test (&inv_code
, &cmp1
, mode
))
3664 cmp1
= force_reg (mode
, cmp1
);
3665 riscv_emit_int_order_test (code
, invert_ptr
, target
, cmp0
, cmp1
);
3667 else if (invert_ptr
== 0)
3669 rtx inv_target
= riscv_force_binary (word_mode
,
3670 inv_code
, cmp0
, cmp1
);
3671 riscv_emit_binary (EQ
, target
, inv_target
, const0_rtx
);
3675 *invert_ptr
= !*invert_ptr
;
3676 riscv_emit_binary (inv_code
, target
, cmp0
, cmp1
);
3681 /* Return a register that is zero iff CMP0 and CMP1 are equal.
3682 The register will have the same mode as CMP0. */
3685 riscv_zero_if_equal (rtx cmp0
, rtx cmp1
)
3687 if (cmp1
== const0_rtx
)
3690 return expand_binop (GET_MODE (cmp0
), sub_optab
,
3691 cmp0
, cmp1
, 0, 0, OPTAB_DIRECT
);
3694 /* Sign- or zero-extend OP0 and OP1 for integer comparisons. */
3697 riscv_extend_comparands (rtx_code code
, rtx
*op0
, rtx
*op1
)
3699 /* Comparisons consider all XLEN bits, so extend sub-XLEN values. */
3700 if (GET_MODE_SIZE (word_mode
) > GET_MODE_SIZE (GET_MODE (*op0
)).to_constant ())
3702 /* It is more profitable to zero-extend QImode values. But not if the
3703 first operand has already been sign-extended, and the second one is
3704 is a constant or has already been sign-extended also. */
3705 if (unsigned_condition (code
) == code
3706 && (GET_MODE (*op0
) == QImode
3707 && ! (GET_CODE (*op0
) == SUBREG
3708 && SUBREG_PROMOTED_VAR_P (*op0
)
3709 && SUBREG_PROMOTED_SIGNED_P (*op0
)
3710 && (CONST_INT_P (*op1
)
3711 || (GET_CODE (*op1
) == SUBREG
3712 && SUBREG_PROMOTED_VAR_P (*op1
)
3713 && SUBREG_PROMOTED_SIGNED_P (*op1
))))))
3715 *op0
= gen_rtx_ZERO_EXTEND (word_mode
, *op0
);
3716 if (CONST_INT_P (*op1
))
3717 *op1
= GEN_INT ((uint8_t) INTVAL (*op1
));
3719 *op1
= gen_rtx_ZERO_EXTEND (word_mode
, *op1
);
3723 *op0
= gen_rtx_SIGN_EXTEND (word_mode
, *op0
);
3724 if (*op1
!= const0_rtx
)
3725 *op1
= gen_rtx_SIGN_EXTEND (word_mode
, *op1
);
3730 /* Convert a comparison into something that can be used in a branch or
3731 conditional move. On entry, *OP0 and *OP1 are the values being
3732 compared and *CODE is the code used to compare them.
3734 Update *CODE, *OP0 and *OP1 so that they describe the final comparison.
3735 If NEED_EQ_NE_P, then only EQ or NE comparisons against zero are
3739 riscv_emit_int_compare (enum rtx_code
*code
, rtx
*op0
, rtx
*op1
,
3740 bool need_eq_ne_p
= false)
3746 if (*code
== EQ
|| *code
== NE
)
3748 *op0
= riscv_zero_if_equal (cmp_op0
, cmp_op1
);
3754 if (splittable_const_int_operand (*op1
, VOIDmode
))
3756 HOST_WIDE_INT rhs
= INTVAL (*op1
);
3758 if (*code
== EQ
|| *code
== NE
)
3760 /* Convert e.g. OP0 == 2048 into OP0 - 2048 == 0. */
3761 if (SMALL_OPERAND (-rhs
))
3763 *op0
= riscv_force_binary (GET_MODE (*op0
), PLUS
, *op0
,
3770 static const enum rtx_code mag_comparisons
[][2] = {
3771 {LEU
, LTU
}, {GTU
, GEU
}, {LE
, LT
}, {GT
, GE
}
3774 /* Convert e.g. (OP0 <= 0xFFF) into (OP0 < 0x1000). */
3775 for (size_t i
= 0; i
< ARRAY_SIZE (mag_comparisons
); i
++)
3777 HOST_WIDE_INT new_rhs
;
3778 bool increment
= *code
== mag_comparisons
[i
][0];
3779 bool decrement
= *code
== mag_comparisons
[i
][1];
3780 if (!increment
&& !decrement
)
3783 new_rhs
= rhs
+ (increment
? 1 : -1);
3784 new_rhs
= trunc_int_for_mode (new_rhs
, GET_MODE (*op0
));
3785 if (riscv_integer_cost (new_rhs
) < riscv_integer_cost (rhs
)
3786 && (rhs
< 0) == (new_rhs
< 0))
3788 *op1
= GEN_INT (new_rhs
);
3789 *code
= mag_comparisons
[i
][increment
];
3796 riscv_extend_comparands (*code
, op0
, op1
);
3798 *op0
= force_reg (word_mode
, *op0
);
3799 if (*op1
!= const0_rtx
)
3800 *op1
= force_reg (word_mode
, *op1
);
3803 /* Like riscv_emit_int_compare, but for floating-point comparisons. */
3806 riscv_emit_float_compare (enum rtx_code
*code
, rtx
*op0
, rtx
*op1
)
3808 rtx tmp0
, tmp1
, cmp_op0
= *op0
, cmp_op1
= *op1
;
3809 enum rtx_code fp_code
= *code
;
3819 /* a == a && b == b */
3820 tmp0
= riscv_force_binary (word_mode
, EQ
, cmp_op0
, cmp_op0
);
3821 tmp1
= riscv_force_binary (word_mode
, EQ
, cmp_op1
, cmp_op1
);
3822 *op0
= riscv_force_binary (word_mode
, AND
, tmp0
, tmp1
);
3827 /* ordered(a, b) > (a == b) */
3829 tmp0
= riscv_force_binary (word_mode
, EQ
, cmp_op0
, cmp_op0
);
3830 tmp1
= riscv_force_binary (word_mode
, EQ
, cmp_op1
, cmp_op1
);
3831 *op0
= riscv_force_binary (word_mode
, AND
, tmp0
, tmp1
);
3832 *op1
= riscv_force_binary (word_mode
, EQ
, cmp_op0
, cmp_op1
);
3835 #define UNORDERED_COMPARISON(CODE, CMP) \
3838 *op0 = gen_reg_rtx (word_mode); \
3839 if (GET_MODE (cmp_op0) == SFmode && TARGET_64BIT) \
3840 emit_insn (gen_f##CMP##_quietsfdi4 (*op0, cmp_op0, cmp_op1)); \
3841 else if (GET_MODE (cmp_op0) == SFmode) \
3842 emit_insn (gen_f##CMP##_quietsfsi4 (*op0, cmp_op0, cmp_op1)); \
3843 else if (GET_MODE (cmp_op0) == DFmode && TARGET_64BIT) \
3844 emit_insn (gen_f##CMP##_quietdfdi4 (*op0, cmp_op0, cmp_op1)); \
3845 else if (GET_MODE (cmp_op0) == DFmode) \
3846 emit_insn (gen_f##CMP##_quietdfsi4 (*op0, cmp_op0, cmp_op1)); \
3847 else if (GET_MODE (cmp_op0) == HFmode && TARGET_64BIT) \
3848 emit_insn (gen_f##CMP##_quiethfdi4 (*op0, cmp_op0, cmp_op1)); \
3849 else if (GET_MODE (cmp_op0) == HFmode) \
3850 emit_insn (gen_f##CMP##_quiethfsi4 (*op0, cmp_op0, cmp_op1)); \
3852 gcc_unreachable (); \
3853 *op1 = const0_rtx; \
3857 std::swap (cmp_op0
, cmp_op1
);
3860 UNORDERED_COMPARISON(UNGT
, le
)
3863 std::swap (cmp_op0
, cmp_op1
);
3866 UNORDERED_COMPARISON(UNGE
, lt
)
3867 #undef UNORDERED_COMPARISON
3879 /* We have instructions for these cases. */
3880 *op0
= riscv_force_binary (word_mode
, fp_code
, cmp_op0
, cmp_op1
);
3885 /* (a < b) | (a > b) */
3886 tmp0
= riscv_force_binary (word_mode
, LT
, cmp_op0
, cmp_op1
);
3887 tmp1
= riscv_force_binary (word_mode
, GT
, cmp_op0
, cmp_op1
);
3888 *op0
= riscv_force_binary (word_mode
, IOR
, tmp0
, tmp1
);
3897 /* CODE-compare OP0 and OP1. Store the result in TARGET. */
3900 riscv_expand_int_scc (rtx target
, enum rtx_code code
, rtx op0
, rtx op1
, bool *invert_ptr
)
3902 riscv_extend_comparands (code
, &op0
, &op1
);
3903 op0
= force_reg (word_mode
, op0
);
3905 if (code
== EQ
|| code
== NE
)
3907 rtx zie
= riscv_zero_if_equal (op0
, op1
);
3908 riscv_emit_binary (code
, target
, zie
, const0_rtx
);
3911 riscv_emit_int_order_test (code
, invert_ptr
, target
, op0
, op1
);
3914 /* Like riscv_expand_int_scc, but for floating-point comparisons. */
3917 riscv_expand_float_scc (rtx target
, enum rtx_code code
, rtx op0
, rtx op1
)
3919 riscv_emit_float_compare (&code
, &op0
, &op1
);
3921 rtx cmp
= riscv_force_binary (word_mode
, code
, op0
, op1
);
3922 riscv_emit_set (target
, lowpart_subreg (SImode
, cmp
, word_mode
));
3925 /* Jump to LABEL if (CODE OP0 OP1) holds. */
3928 riscv_expand_conditional_branch (rtx label
, rtx_code code
, rtx op0
, rtx op1
)
3930 if (FLOAT_MODE_P (GET_MODE (op1
)))
3931 riscv_emit_float_compare (&code
, &op0
, &op1
);
3933 riscv_emit_int_compare (&code
, &op0
, &op1
);
3935 rtx condition
= gen_rtx_fmt_ee (code
, VOIDmode
, op0
, op1
);
3936 emit_jump_insn (gen_condjump (condition
, label
));
3939 /* Emit a cond move: If OP holds, move CONS to DEST; else move ALT to DEST.
3940 Return 0 if expansion failed. */
3943 riscv_expand_conditional_move (rtx dest
, rtx op
, rtx cons
, rtx alt
)
3945 machine_mode mode
= GET_MODE (dest
);
3946 rtx_code code
= GET_CODE (op
);
3947 rtx op0
= XEXP (op
, 0);
3948 rtx op1
= XEXP (op
, 1);
3949 bool need_eq_ne_p
= false;
3951 if (TARGET_XTHEADCONDMOV
3952 && GET_MODE_CLASS (mode
) == MODE_INT
3953 && reg_or_0_operand (cons
, mode
)
3954 && reg_or_0_operand (alt
, mode
)
3955 && (GET_MODE (op
) == mode
|| GET_MODE (op
) == E_VOIDmode
)
3956 && GET_MODE (op0
) == mode
3957 && GET_MODE (op1
) == mode
3958 && (code
== EQ
|| code
== NE
))
3959 need_eq_ne_p
= true;
3962 || (TARGET_SFB_ALU
&& GET_MODE (op0
) == word_mode
))
3964 riscv_emit_int_compare (&code
, &op0
, &op1
, need_eq_ne_p
);
3965 rtx cond
= gen_rtx_fmt_ee (code
, GET_MODE (op0
), op0
, op1
);
3967 /* The expander is a bit loose in its specification of the true
3968 arm of the conditional move. That allows us to support more
3969 cases for extensions which are more general than SFB. But
3970 does mean we need to force CONS into a register at this point. */
3971 cons
= force_reg (GET_MODE (dest
), cons
);
3972 emit_insn (gen_rtx_SET (dest
, gen_rtx_IF_THEN_ELSE (GET_MODE (dest
),
3976 else if (TARGET_ZICOND_LIKE
3977 && GET_MODE_CLASS (mode
) == MODE_INT
)
3979 /* The comparison must be comparing WORD_MODE objects. We must
3980 enforce that so that we don't strip away a sign_extension
3981 thinking it is unnecessary. We might consider using
3982 riscv_extend_operands if they are not already properly extended. */
3983 if ((GET_MODE (op0
) != word_mode
&& GET_MODE (op0
) != VOIDmode
)
3984 || (GET_MODE (op1
) != word_mode
&& GET_MODE (op1
) != VOIDmode
))
3987 /* Canonicalize the comparison. It must be an equality comparison
3988 against 0. If it isn't, then emit an SCC instruction so that
3989 we can then use an equality comparison against zero. */
3990 if (!equality_operator (op
, VOIDmode
) || op1
!= CONST0_RTX (mode
))
3992 enum rtx_code new_code
= NE
;
3993 bool *invert_ptr
= 0;
3994 bool invert
= false;
3996 if (code
== LE
|| code
== GE
)
3997 invert_ptr
= &invert
;
3999 /* Emit an scc like instruction into a temporary
4000 so that we can use an EQ/NE comparison. */
4001 rtx tmp
= gen_reg_rtx (word_mode
);
4003 /* We can support both FP and integer conditional moves. */
4004 if (INTEGRAL_MODE_P (GET_MODE (XEXP (op
, 0))))
4005 riscv_expand_int_scc (tmp
, code
, op0
, op1
, invert_ptr
);
4006 else if (FLOAT_MODE_P (GET_MODE (XEXP (op
, 0)))
4007 && fp_scc_comparison (op
, GET_MODE (op
)))
4008 riscv_expand_float_scc (tmp
, code
, op0
, op1
);
4012 /* If riscv_expand_int_scc inverts the condition, then it will
4013 flip the value of INVERT. We need to know where so that
4014 we can adjust it for our needs. */
4018 op
= gen_rtx_fmt_ee (new_code
, mode
, tmp
, const0_rtx
);
4020 /* We've generated a new comparison. Update the local variables. */
4021 code
= GET_CODE (op
);
4026 /* 0, reg or 0, imm */
4027 if (cons
== CONST0_RTX (mode
)
4029 || (CONST_INT_P (alt
) && alt
!= CONST0_RTX (mode
))))
4031 riscv_emit_int_compare (&code
, &op0
, &op1
, true);
4032 rtx cond
= gen_rtx_fmt_ee (code
, GET_MODE (op0
), op0
, op1
);
4033 alt
= force_reg (mode
, alt
);
4034 emit_insn (gen_rtx_SET (dest
,
4035 gen_rtx_IF_THEN_ELSE (mode
, cond
,
4040 else if (CONST_INT_P (cons
) && cons
!= CONST0_RTX (mode
)
4041 && CONST_INT_P (alt
) && alt
!= CONST0_RTX (mode
))
4043 riscv_emit_int_compare (&code
, &op0
, &op1
, true);
4044 rtx cond
= gen_rtx_fmt_ee (code
, GET_MODE (op0
), op0
, op1
);
4045 HOST_WIDE_INT t
= INTVAL (alt
) - INTVAL (cons
);
4046 alt
= force_reg (mode
, gen_int_mode (t
, mode
));
4047 emit_insn (gen_rtx_SET (dest
,
4048 gen_rtx_IF_THEN_ELSE (mode
, cond
,
4051 /* CONS might not fit into a signed 12 bit immediate suitable
4052 for an addi instruction. If that's the case, force it
4054 if (!SMALL_OPERAND (INTVAL (cons
)))
4055 cons
= force_reg (mode
, cons
);
4056 riscv_emit_binary (PLUS
, dest
, dest
, cons
);
4060 else if (CONST_INT_P (cons
) && cons
!= CONST0_RTX (mode
) && REG_P (alt
))
4062 /* Optimize for register value of 0. */
4063 if (code
== NE
&& rtx_equal_p (op0
, alt
) && op1
== CONST0_RTX (mode
))
4065 rtx cond
= gen_rtx_fmt_ee (code
, GET_MODE (op0
), op0
, op1
);
4066 cons
= force_reg (mode
, cons
);
4067 emit_insn (gen_rtx_SET (dest
,
4068 gen_rtx_IF_THEN_ELSE (mode
, cond
,
4073 riscv_emit_int_compare (&code
, &op0
, &op1
, true);
4074 rtx cond
= gen_rtx_fmt_ee (code
, GET_MODE (op0
), op0
, op1
);
4076 rtx temp1
= gen_reg_rtx (mode
);
4077 rtx temp2
= gen_int_mode (-1 * INTVAL (cons
), mode
);
4079 /* TEMP2 and/or CONS might not fit into a signed 12 bit immediate
4080 suitable for an addi instruction. If that's the case, force it
4082 if (!SMALL_OPERAND (INTVAL (temp2
)))
4083 temp2
= force_reg (mode
, temp2
);
4084 if (!SMALL_OPERAND (INTVAL (cons
)))
4085 cons
= force_reg (mode
, cons
);
4087 riscv_emit_binary (PLUS
, temp1
, alt
, temp2
);
4088 emit_insn (gen_rtx_SET (dest
,
4089 gen_rtx_IF_THEN_ELSE (mode
, cond
,
4092 riscv_emit_binary (PLUS
, dest
, dest
, cons
);
4095 /* reg, 0 or imm, 0 */
4096 else if ((REG_P (cons
)
4097 || (CONST_INT_P (cons
) && cons
!= CONST0_RTX (mode
)))
4098 && alt
== CONST0_RTX (mode
))
4100 riscv_emit_int_compare (&code
, &op0
, &op1
, true);
4101 rtx cond
= gen_rtx_fmt_ee (code
, GET_MODE (op0
), op0
, op1
);
4102 cons
= force_reg (mode
, cons
);
4103 emit_insn (gen_rtx_SET (dest
, gen_rtx_IF_THEN_ELSE (mode
, cond
,
4108 else if (REG_P (cons
) && CONST_INT_P (alt
) && alt
!= CONST0_RTX (mode
))
4110 /* Optimize for register value of 0. */
4111 if (code
== EQ
&& rtx_equal_p (op0
, cons
) && op1
== CONST0_RTX (mode
))
4113 rtx cond
= gen_rtx_fmt_ee (code
, GET_MODE (op0
), op0
, op1
);
4114 alt
= force_reg (mode
, alt
);
4115 emit_insn (gen_rtx_SET (dest
,
4116 gen_rtx_IF_THEN_ELSE (mode
, cond
,
4121 riscv_emit_int_compare (&code
, &op0
, &op1
, true);
4122 rtx cond
= gen_rtx_fmt_ee (code
, GET_MODE (op0
), op0
, op1
);
4124 rtx temp1
= gen_reg_rtx (mode
);
4125 rtx temp2
= gen_int_mode (-1 * INTVAL (alt
), mode
);
4127 /* TEMP2 and/or ALT might not fit into a signed 12 bit immediate
4128 suitable for an addi instruction. If that's the case, force it
4130 if (!SMALL_OPERAND (INTVAL (temp2
)))
4131 temp2
= force_reg (mode
, temp2
);
4132 if (!SMALL_OPERAND (INTVAL (alt
)))
4133 alt
= force_reg (mode
, alt
);
4135 riscv_emit_binary (PLUS
, temp1
, cons
, temp2
);
4136 emit_insn (gen_rtx_SET (dest
,
4137 gen_rtx_IF_THEN_ELSE (mode
, cond
,
4139 CONST0_RTX (mode
))));
4140 riscv_emit_binary (PLUS
, dest
, dest
, alt
);
4144 else if (REG_P (cons
) && REG_P (alt
))
4146 if ((code
== EQ
&& rtx_equal_p (cons
, op0
))
4147 || (code
== NE
&& rtx_equal_p (alt
, op0
)))
4149 rtx cond
= gen_rtx_fmt_ee (code
, GET_MODE (op0
), op0
, op1
);
4150 if (!rtx_equal_p (cons
, op0
))
4151 std::swap (alt
, cons
);
4152 alt
= force_reg (mode
, alt
);
4153 emit_insn (gen_rtx_SET (dest
,
4154 gen_rtx_IF_THEN_ELSE (mode
, cond
,
4159 rtx reg1
= gen_reg_rtx (mode
);
4160 rtx reg2
= gen_reg_rtx (mode
);
4161 riscv_emit_int_compare (&code
, &op0
, &op1
, true);
4162 rtx cond1
= gen_rtx_fmt_ee (code
, GET_MODE (op0
), op0
, op1
);
4163 rtx cond2
= gen_rtx_fmt_ee (code
== NE
? EQ
: NE
,
4164 GET_MODE (op0
), op0
, op1
);
4165 emit_insn (gen_rtx_SET (reg2
,
4166 gen_rtx_IF_THEN_ELSE (mode
, cond2
,
4169 emit_insn (gen_rtx_SET (reg1
,
4170 gen_rtx_IF_THEN_ELSE (mode
, cond1
,
4173 riscv_emit_binary (IOR
, dest
, reg1
, reg2
);
4181 /* Implement TARGET_FUNCTION_ARG_BOUNDARY. Every parameter gets at
4182 least PARM_BOUNDARY bits of alignment, but will be given anything up
4183 to PREFERRED_STACK_BOUNDARY bits if the type requires it. */
4186 riscv_function_arg_boundary (machine_mode mode
, const_tree type
)
4188 unsigned int alignment
;
4190 /* Use natural alignment if the type is not aggregate data. */
4191 if (type
&& !AGGREGATE_TYPE_P (type
))
4192 alignment
= TYPE_ALIGN (TYPE_MAIN_VARIANT (type
));
4194 alignment
= type
? TYPE_ALIGN (type
) : GET_MODE_ALIGNMENT (mode
);
4196 return MIN (PREFERRED_STACK_BOUNDARY
, MAX (PARM_BOUNDARY
, alignment
));
4199 /* If MODE represents an argument that can be passed or returned in
4200 floating-point registers, return the number of registers, else 0. */
4203 riscv_pass_mode_in_fpr_p (machine_mode mode
)
4205 if (GET_MODE_UNIT_SIZE (mode
) <= UNITS_PER_FP_ARG
)
4207 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
)
4210 if (GET_MODE_CLASS (mode
) == MODE_COMPLEX_FLOAT
)
4219 HOST_WIDE_INT offset
;
4220 } riscv_aggregate_field
;
4222 /* Identify subfields of aggregates that are candidates for passing in
4223 floating-point registers. */
4226 riscv_flatten_aggregate_field (const_tree type
,
4227 riscv_aggregate_field fields
[2],
4228 int n
, HOST_WIDE_INT offset
,
4229 bool ignore_zero_width_bit_field_p
)
4231 switch (TREE_CODE (type
))
4234 /* Can't handle incomplete types nor sizes that are not fixed. */
4235 if (!COMPLETE_TYPE_P (type
)
4236 || TREE_CODE (TYPE_SIZE (type
)) != INTEGER_CST
4237 || !tree_fits_uhwi_p (TYPE_SIZE (type
)))
4240 for (tree f
= TYPE_FIELDS (type
); f
; f
= DECL_CHAIN (f
))
4241 if (TREE_CODE (f
) == FIELD_DECL
)
4243 if (!TYPE_P (TREE_TYPE (f
)))
4246 /* The C++ front end strips zero-length bit-fields from structs.
4247 So we need to ignore them in the C front end to make C code
4248 compatible with C++ code. */
4249 if (ignore_zero_width_bit_field_p
4250 && DECL_BIT_FIELD (f
)
4251 && (DECL_SIZE (f
) == NULL_TREE
4252 || integer_zerop (DECL_SIZE (f
))))
4256 HOST_WIDE_INT pos
= offset
+ int_byte_position (f
);
4257 n
= riscv_flatten_aggregate_field (TREE_TYPE (f
),
4259 ignore_zero_width_bit_field_p
);
4268 HOST_WIDE_INT n_elts
;
4269 riscv_aggregate_field subfields
[2];
4270 tree index
= TYPE_DOMAIN (type
);
4271 tree elt_size
= TYPE_SIZE_UNIT (TREE_TYPE (type
));
4272 int n_subfields
= riscv_flatten_aggregate_field (TREE_TYPE (type
),
4273 subfields
, 0, offset
,
4274 ignore_zero_width_bit_field_p
);
4276 /* Can't handle incomplete types nor sizes that are not fixed. */
4277 if (n_subfields
<= 0
4278 || !COMPLETE_TYPE_P (type
)
4279 || TREE_CODE (TYPE_SIZE (type
)) != INTEGER_CST
4281 || !TYPE_MAX_VALUE (index
)
4282 || !tree_fits_uhwi_p (TYPE_MAX_VALUE (index
))
4283 || !TYPE_MIN_VALUE (index
)
4284 || !tree_fits_uhwi_p (TYPE_MIN_VALUE (index
))
4285 || !tree_fits_uhwi_p (elt_size
))
4288 n_elts
= 1 + tree_to_uhwi (TYPE_MAX_VALUE (index
))
4289 - tree_to_uhwi (TYPE_MIN_VALUE (index
));
4290 gcc_assert (n_elts
>= 0);
4292 for (HOST_WIDE_INT i
= 0; i
< n_elts
; i
++)
4293 for (int j
= 0; j
< n_subfields
; j
++)
4298 fields
[n
] = subfields
[j
];
4299 fields
[n
++].offset
+= i
* tree_to_uhwi (elt_size
);
4307 /* Complex type need consume 2 field, so n must be 0. */
4311 HOST_WIDE_INT elt_size
= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (type
))).to_constant ();
4313 if (elt_size
<= UNITS_PER_FP_ARG
)
4315 fields
[0].type
= TREE_TYPE (type
);
4316 fields
[0].offset
= offset
;
4317 fields
[1].type
= TREE_TYPE (type
);
4318 fields
[1].offset
= offset
+ elt_size
;
4328 && ((SCALAR_FLOAT_TYPE_P (type
)
4329 && GET_MODE_SIZE (TYPE_MODE (type
)).to_constant () <= UNITS_PER_FP_ARG
)
4330 || (INTEGRAL_TYPE_P (type
)
4331 && GET_MODE_SIZE (TYPE_MODE (type
)).to_constant () <= UNITS_PER_WORD
)))
4333 fields
[n
].type
= type
;
4334 fields
[n
].offset
= offset
;
4342 /* Identify candidate aggregates for passing in floating-point registers.
4343 Candidates have at most two fields after flattening. */
4346 riscv_flatten_aggregate_argument (const_tree type
,
4347 riscv_aggregate_field fields
[2],
4348 bool ignore_zero_width_bit_field_p
)
4350 if (!type
|| TREE_CODE (type
) != RECORD_TYPE
)
4353 return riscv_flatten_aggregate_field (type
, fields
, 0, 0,
4354 ignore_zero_width_bit_field_p
);
4357 /* See whether TYPE is a record whose fields should be returned in one or
4358 two floating-point registers. If so, populate FIELDS accordingly. */
4361 riscv_pass_aggregate_in_fpr_pair_p (const_tree type
,
4362 riscv_aggregate_field fields
[2])
4364 static int warned
= 0;
4366 /* This is the old ABI, which differs for C++ and C. */
4367 int n_old
= riscv_flatten_aggregate_argument (type
, fields
, false);
4368 for (int i
= 0; i
< n_old
; i
++)
4369 if (!SCALAR_FLOAT_TYPE_P (fields
[i
].type
))
4375 /* This is the new ABI, which is the same for C++ and C. */
4376 int n_new
= riscv_flatten_aggregate_argument (type
, fields
, true);
4377 for (int i
= 0; i
< n_new
; i
++)
4378 if (!SCALAR_FLOAT_TYPE_P (fields
[i
].type
))
4384 if ((n_old
!= n_new
) && (warned
== 0))
4386 warning (OPT_Wpsabi
, "ABI for flattened struct with zero-length "
4387 "bit-fields changed in GCC 10");
4391 return n_new
> 0 ? n_new
: 0;
4394 /* See whether TYPE is a record whose fields should be returned in one or
4395 floating-point register and one integer register. If so, populate
4396 FIELDS accordingly. */
4399 riscv_pass_aggregate_in_fpr_and_gpr_p (const_tree type
,
4400 riscv_aggregate_field fields
[2])
4402 static int warned
= 0;
4404 /* This is the old ABI, which differs for C++ and C. */
4405 unsigned num_int_old
= 0, num_float_old
= 0;
4406 int n_old
= riscv_flatten_aggregate_argument (type
, fields
, false);
4407 for (int i
= 0; i
< n_old
; i
++)
4409 num_float_old
+= SCALAR_FLOAT_TYPE_P (fields
[i
].type
);
4410 num_int_old
+= INTEGRAL_TYPE_P (fields
[i
].type
);
4413 /* This is the new ABI, which is the same for C++ and C. */
4414 unsigned num_int_new
= 0, num_float_new
= 0;
4415 int n_new
= riscv_flatten_aggregate_argument (type
, fields
, true);
4416 for (int i
= 0; i
< n_new
; i
++)
4418 num_float_new
+= SCALAR_FLOAT_TYPE_P (fields
[i
].type
);
4419 num_int_new
+= INTEGRAL_TYPE_P (fields
[i
].type
);
4422 if (((num_int_old
== 1 && num_float_old
== 1
4423 && (num_int_old
!= num_int_new
|| num_float_old
!= num_float_new
))
4424 || (num_int_new
== 1 && num_float_new
== 1
4425 && (num_int_old
!= num_int_new
|| num_float_old
!= num_float_new
)))
4428 warning (OPT_Wpsabi
, "ABI for flattened struct with zero-length "
4429 "bit-fields changed in GCC 10");
4433 return num_int_new
== 1 && num_float_new
== 1;
4436 /* Return the representation of an argument passed or returned in an FPR
4437 when the value has mode VALUE_MODE and the type has TYPE_MODE. The
4438 two modes may be different for structures like:
4440 struct __attribute__((packed)) foo { float f; }
4442 where the SFmode value "f" is passed in REGNO but the struct itself
4443 has mode BLKmode. */
4446 riscv_pass_fpr_single (machine_mode type_mode
, unsigned regno
,
4447 machine_mode value_mode
,
4448 HOST_WIDE_INT offset
)
4450 rtx x
= gen_rtx_REG (value_mode
, regno
);
4452 if (type_mode
!= value_mode
)
4454 x
= gen_rtx_EXPR_LIST (VOIDmode
, x
, GEN_INT (offset
));
4455 x
= gen_rtx_PARALLEL (type_mode
, gen_rtvec (1, x
));
4460 /* Pass or return a composite value in the FPR pair REGNO and REGNO + 1.
4461 MODE is the mode of the composite. MODE1 and OFFSET1 are the mode and
4462 byte offset for the first value, likewise MODE2 and OFFSET2 for the
4466 riscv_pass_fpr_pair (machine_mode mode
, unsigned regno1
,
4467 machine_mode mode1
, HOST_WIDE_INT offset1
,
4468 unsigned regno2
, machine_mode mode2
,
4469 HOST_WIDE_INT offset2
)
4471 return gen_rtx_PARALLEL
4474 gen_rtx_EXPR_LIST (VOIDmode
,
4475 gen_rtx_REG (mode1
, regno1
),
4477 gen_rtx_EXPR_LIST (VOIDmode
,
4478 gen_rtx_REG (mode2
, regno2
),
4479 GEN_INT (offset2
))));
4482 /* Return true if a vector type is included in the type TYPE. */
4485 riscv_arg_has_vector (const_tree type
)
4487 if (riscv_v_ext_mode_p (TYPE_MODE (type
)))
4490 if (!COMPLETE_TYPE_P (type
))
4493 switch (TREE_CODE (type
))
4496 /* If it is a record, it is further determined whether its fields have
4498 for (tree f
= TYPE_FIELDS (type
); f
; f
= DECL_CHAIN (f
))
4499 if (TREE_CODE (f
) == FIELD_DECL
)
4501 tree field_type
= TREE_TYPE (f
);
4502 if (!TYPE_P (field_type
))
4505 if (riscv_arg_has_vector (field_type
))
4510 return riscv_arg_has_vector (TREE_TYPE (type
));
4518 /* Pass the type to check whether it's a vector type or contains vector type.
4519 Only check the value type and no checking for vector pointer type. */
4522 riscv_pass_in_vector_p (const_tree type
)
4524 static int warned
= 0;
4526 if (type
&& riscv_vector::lookup_vector_type_attribute (type
) && !warned
)
4528 warning (OPT_Wpsabi
,
4529 "ABI for the vector type is currently in experimental stage and "
4530 "may changes in the upcoming version of GCC.");
4535 /* Initialize a variable CUM of type CUMULATIVE_ARGS
4536 for a call to a function whose data type is FNTYPE.
4537 For a library call, FNTYPE is 0. */
4540 riscv_init_cumulative_args (CUMULATIVE_ARGS
*cum
,
4541 tree fntype ATTRIBUTE_UNUSED
,
4542 rtx libname ATTRIBUTE_UNUSED
,
4544 int caller ATTRIBUTE_UNUSED
)
4546 memset (cum
, 0, sizeof (*cum
));
4549 cum
->variant_cc
= (riscv_cc
) fntype_abi (fntype
).id ();
4551 cum
->variant_cc
= RISCV_CC_BASE
;
4555 const tree_function_decl
&fn
4556 = FUNCTION_DECL_CHECK (fndecl
)->function_decl
;
4558 if (fn
.built_in_class
== NOT_BUILT_IN
)
4559 cum
->rvv_psabi_warning
= 1;
4563 /* Return true if TYPE is a vector type that can be passed in vector registers.
4567 riscv_vector_type_p (const_tree type
)
4569 /* Currently, only builtin scalabler vector type is allowed, in the future,
4570 more vector types may be allowed, such as GNU vector type, etc. */
4571 return riscv_vector::builtin_type_p (type
);
4575 riscv_hard_regno_nregs (unsigned int regno
, machine_mode mode
);
4577 /* Subroutine of riscv_get_arg_info. */
4580 riscv_get_vector_arg (struct riscv_arg_info
*info
, const CUMULATIVE_ARGS
*cum
,
4581 machine_mode mode
, bool return_p
)
4583 gcc_assert (riscv_v_ext_mode_p (mode
));
4585 info
->mr_offset
= cum
->num_mrs
;
4586 if (GET_MODE_CLASS (mode
) == MODE_VECTOR_BOOL
)
4588 /* For scalable mask return value. */
4590 return gen_rtx_REG (mode
, V_REG_FIRST
);
4592 /* For the first scalable mask argument. */
4593 if (info
->mr_offset
< MAX_ARGS_IN_MASK_REGISTERS
)
4596 return gen_rtx_REG (mode
, V_REG_FIRST
);
4600 /* Rest scalable mask arguments are treated as scalable data
4605 /* The number and alignment of vector registers need for this scalable vector
4606 argument. When the mode size is less than a full vector, we use 1 vector
4607 register to pass. Just call TARGET_HARD_REGNO_NREGS for the number
4609 int nregs
= riscv_hard_regno_nregs (V_ARG_FIRST
, mode
);
4610 int LMUL
= riscv_v_ext_tuple_mode_p (mode
)
4611 ? nregs
/ riscv_vector::get_nf (mode
)
4613 int arg_reg_start
= V_ARG_FIRST
- V_REG_FIRST
;
4614 int arg_reg_end
= V_ARG_LAST
- V_REG_FIRST
;
4615 int aligned_reg_start
= ROUND_UP (arg_reg_start
, LMUL
);
4617 /* For scalable data and scalable tuple return value. */
4619 return gen_rtx_REG (mode
, aligned_reg_start
+ V_REG_FIRST
);
4621 /* Iterate through the USED_VRS array to find vector register groups that have
4622 not been allocated and the first register is aligned with LMUL. */
4623 for (int i
= aligned_reg_start
; i
+ nregs
- 1 <= arg_reg_end
; i
+= LMUL
)
4625 /* The index in USED_VRS array. */
4626 int idx
= i
- arg_reg_start
;
4627 /* Find the first register unused. */
4628 if (!cum
->used_vrs
[idx
])
4630 bool find_set
= true;
4631 /* Ensure there are NREGS continuous unused registers. */
4632 for (int j
= 1; j
< nregs
; j
++)
4633 if (cum
->used_vrs
[idx
+ j
])
4636 /* Update I to the last aligned register which
4637 cannot be used and the next iteration will add
4639 i
+= (j
/ LMUL
) * LMUL
;
4645 info
->num_vrs
= nregs
;
4646 info
->vr_offset
= idx
;
4647 return gen_rtx_REG (mode
, i
+ V_REG_FIRST
);
4655 /* Fill INFO with information about a single argument, and return an RTL
4656 pattern to pass or return the argument. Return NULL_RTX if argument cannot
4657 pass or return in registers, then the argument may be passed by reference or
4658 through the stack or . CUM is the cumulative state for earlier arguments.
4659 MODE is the mode of this argument and TYPE is its type (if known). NAMED is
4660 true if this is a named (fixed) argument rather than a variable one. RETURN_P
4661 is true if returning the argument, or false if passing the argument. */
4664 riscv_get_arg_info (struct riscv_arg_info
*info
, const CUMULATIVE_ARGS
*cum
,
4665 machine_mode mode
, const_tree type
, bool named
,
4668 unsigned num_bytes
, num_words
;
4669 unsigned fpr_base
= return_p
? FP_RETURN
: FP_ARG_FIRST
;
4670 unsigned gpr_base
= return_p
? GP_RETURN
: GP_ARG_FIRST
;
4671 unsigned alignment
= riscv_function_arg_boundary (mode
, type
);
4673 memset (info
, 0, sizeof (*info
));
4674 info
->gpr_offset
= cum
->num_gprs
;
4675 info
->fpr_offset
= cum
->num_fprs
;
4677 if (cum
->rvv_psabi_warning
)
4679 /* Only check existing of vector type. */
4680 riscv_pass_in_vector_p (type
);
4683 /* When disable vector_abi or scalable vector argument is anonymous, this
4684 argument is passed by reference. */
4685 if (riscv_v_ext_mode_p (mode
) && (!riscv_vector_abi
|| !named
))
4690 riscv_aggregate_field fields
[2];
4691 unsigned fregno
= fpr_base
+ info
->fpr_offset
;
4692 unsigned gregno
= gpr_base
+ info
->gpr_offset
;
4694 /* Pass one- or two-element floating-point aggregates in FPRs. */
4695 if ((info
->num_fprs
= riscv_pass_aggregate_in_fpr_pair_p (type
, fields
))
4696 && info
->fpr_offset
+ info
->num_fprs
<= MAX_ARGS_IN_REGISTERS
)
4697 switch (info
->num_fprs
)
4700 return riscv_pass_fpr_single (mode
, fregno
,
4701 TYPE_MODE (fields
[0].type
),
4705 return riscv_pass_fpr_pair (mode
, fregno
,
4706 TYPE_MODE (fields
[0].type
),
4709 TYPE_MODE (fields
[1].type
),
4716 /* Pass real and complex floating-point numbers in FPRs. */
4717 if ((info
->num_fprs
= riscv_pass_mode_in_fpr_p (mode
))
4718 && info
->fpr_offset
+ info
->num_fprs
<= MAX_ARGS_IN_REGISTERS
)
4719 switch (GET_MODE_CLASS (mode
))
4722 return gen_rtx_REG (mode
, fregno
);
4724 case MODE_COMPLEX_FLOAT
:
4725 return riscv_pass_fpr_pair (mode
, fregno
, GET_MODE_INNER (mode
), 0,
4726 fregno
+ 1, GET_MODE_INNER (mode
),
4727 GET_MODE_UNIT_SIZE (mode
));
4733 /* Pass structs with one float and one integer in an FPR and a GPR. */
4734 if (riscv_pass_aggregate_in_fpr_and_gpr_p (type
, fields
)
4735 && info
->gpr_offset
< MAX_ARGS_IN_REGISTERS
4736 && info
->fpr_offset
< MAX_ARGS_IN_REGISTERS
)
4741 if (!SCALAR_FLOAT_TYPE_P (fields
[0].type
))
4742 std::swap (fregno
, gregno
);
4744 return riscv_pass_fpr_pair (mode
, fregno
, TYPE_MODE (fields
[0].type
),
4746 gregno
, TYPE_MODE (fields
[1].type
),
4750 /* For scalable vector argument. */
4751 if (riscv_vector_type_p (type
) && riscv_v_ext_mode_p (mode
))
4752 return riscv_get_vector_arg (info
, cum
, mode
, return_p
);
4755 /* Work out the size of the argument. */
4756 num_bytes
= type
? int_size_in_bytes (type
) : GET_MODE_SIZE (mode
).to_constant ();
4757 num_words
= (num_bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
4759 /* Doubleword-aligned varargs start on an even register boundary. */
4760 if (!named
&& num_bytes
!= 0 && alignment
> BITS_PER_WORD
)
4761 info
->gpr_offset
+= info
->gpr_offset
& 1;
4763 /* Partition the argument between registers and stack. */
4765 info
->num_gprs
= MIN (num_words
, MAX_ARGS_IN_REGISTERS
- info
->gpr_offset
);
4766 info
->stack_p
= (num_words
- info
->num_gprs
) != 0;
4768 if (info
->num_gprs
|| return_p
)
4769 return gen_rtx_REG (mode
, gpr_base
+ info
->gpr_offset
);
4774 /* Implement TARGET_FUNCTION_ARG. */
4777 riscv_function_arg (cumulative_args_t cum_v
, const function_arg_info
&arg
)
4779 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
4780 struct riscv_arg_info info
;
4782 if (arg
.end_marker_p ())
4783 /* Return the calling convention that used by the current function. */
4784 return gen_int_mode (cum
->variant_cc
, SImode
);
4786 return riscv_get_arg_info (&info
, cum
, arg
.mode
, arg
.type
, arg
.named
, false);
4789 /* Implement TARGET_FUNCTION_ARG_ADVANCE. */
4792 riscv_function_arg_advance (cumulative_args_t cum_v
,
4793 const function_arg_info
&arg
)
4795 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
4796 struct riscv_arg_info info
;
4798 riscv_get_arg_info (&info
, cum
, arg
.mode
, arg
.type
, arg
.named
, false);
4800 /* Set the corresponding register in USED_VRS to used status. */
4801 for (unsigned int i
= 0; i
< info
.num_vrs
; i
++)
4803 gcc_assert (!cum
->used_vrs
[info
.vr_offset
+ i
]);
4804 cum
->used_vrs
[info
.vr_offset
+ i
] = true;
4807 if ((info
.num_vrs
> 0 || info
.num_mrs
> 0) && cum
->variant_cc
!= RISCV_CC_V
)
4809 error ("RVV type %qT cannot be passed to an unprototyped function",
4811 /* Avoid repeating the message */
4812 cum
->variant_cc
= RISCV_CC_V
;
4815 /* Advance the register count. This has the effect of setting
4816 num_gprs to MAX_ARGS_IN_REGISTERS if a doubleword-aligned
4817 argument required us to skip the final GPR and pass the whole
4818 argument on the stack. */
4819 cum
->num_fprs
= info
.fpr_offset
+ info
.num_fprs
;
4820 cum
->num_gprs
= info
.gpr_offset
+ info
.num_gprs
;
4821 cum
->num_mrs
= info
.mr_offset
+ info
.num_mrs
;
4824 /* Implement TARGET_ARG_PARTIAL_BYTES. */
4827 riscv_arg_partial_bytes (cumulative_args_t cum
,
4828 const function_arg_info
&generic_arg
)
4830 struct riscv_arg_info arg
;
4832 riscv_get_arg_info (&arg
, get_cumulative_args (cum
), generic_arg
.mode
,
4833 generic_arg
.type
, generic_arg
.named
, false);
4834 return arg
.stack_p
? arg
.num_gprs
* UNITS_PER_WORD
: 0;
4837 /* Implement FUNCTION_VALUE and LIBCALL_VALUE. For normal calls,
4838 VALTYPE is the return type and MODE is VOIDmode. For libcalls,
4839 VALTYPE is null and MODE is the mode of the return value. */
4842 riscv_function_value (const_tree type
, const_tree func
, machine_mode mode
)
4844 struct riscv_arg_info info
;
4845 CUMULATIVE_ARGS args
;
4849 int unsigned_p
= TYPE_UNSIGNED (type
);
4851 mode
= TYPE_MODE (type
);
4853 /* Since TARGET_PROMOTE_FUNCTION_MODE unconditionally promotes,
4854 return values, promote the mode here too. */
4855 mode
= promote_function_mode (type
, mode
, &unsigned_p
, func
, 1);
4858 memset (&args
, 0, sizeof args
);
4860 const_tree arg_type
= type
;
4861 if (func
&& DECL_RESULT (func
))
4863 const tree_function_decl
&fn
= FUNCTION_DECL_CHECK (func
)->function_decl
;
4864 if (fn
.built_in_class
== NOT_BUILT_IN
)
4865 args
.rvv_psabi_warning
= 1;
4867 arg_type
= TREE_TYPE (DECL_RESULT (func
));
4870 return riscv_get_arg_info (&info
, &args
, mode
, arg_type
, true, true);
4873 /* Implement TARGET_PASS_BY_REFERENCE. */
4876 riscv_pass_by_reference (cumulative_args_t cum_v
, const function_arg_info
&arg
)
4878 HOST_WIDE_INT size
= arg
.type_size_in_bytes ().to_constant ();;
4879 struct riscv_arg_info info
;
4880 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
4882 /* ??? std_gimplify_va_arg_expr passes NULL for cum. Fortunately, we
4883 never pass variadic arguments in floating-point and vector registers,
4884 so we can avoid the call to riscv_get_arg_info in this case. */
4887 /* Don't pass by reference if we can use a floating-point register. */
4888 riscv_get_arg_info (&info
, cum
, arg
.mode
, arg
.type
, arg
.named
, false);
4892 /* Don't pass by reference if we can use vector register groups. */
4893 if (info
.num_vrs
> 0 || info
.num_mrs
> 0)
4897 /* When vector abi disabled(without --param=riscv-vector-abi option) or
4898 scalable vector argument is anonymous or cannot be passed through vector
4899 registers, this argument is passed by reference. */
4900 if (riscv_v_ext_mode_p (arg
.mode
))
4903 /* Pass by reference if the data do not fit in two integer registers. */
4904 return !IN_RANGE (size
, 0, 2 * UNITS_PER_WORD
);
4907 /* Implement TARGET_RETURN_IN_MEMORY. */
4910 riscv_return_in_memory (const_tree type
, const_tree fndecl ATTRIBUTE_UNUSED
)
4912 CUMULATIVE_ARGS args
;
4913 cumulative_args_t cum
= pack_cumulative_args (&args
);
4915 /* The rules for returning in memory are the same as for passing the
4916 first named argument by reference. */
4917 memset (&args
, 0, sizeof args
);
4918 function_arg_info
arg (const_cast<tree
> (type
), /*named=*/true);
4919 return riscv_pass_by_reference (cum
, arg
);
4922 /* Implement TARGET_SETUP_INCOMING_VARARGS. */
4925 riscv_setup_incoming_varargs (cumulative_args_t cum
,
4926 const function_arg_info
&arg
,
4927 int *pretend_size ATTRIBUTE_UNUSED
, int no_rtl
)
4929 CUMULATIVE_ARGS local_cum
;
4932 /* The caller has advanced CUM up to, but not beyond, the last named
4933 argument. Advance a local copy of CUM past the last "real" named
4934 argument, to find out how many registers are left over. */
4935 local_cum
= *get_cumulative_args (cum
);
4936 if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl
)))
4937 riscv_function_arg_advance (pack_cumulative_args (&local_cum
), arg
);
4939 /* Found out how many registers we need to save. */
4940 gp_saved
= MAX_ARGS_IN_REGISTERS
- local_cum
.num_gprs
;
4942 if (!no_rtl
&& gp_saved
> 0)
4944 rtx ptr
= plus_constant (Pmode
, virtual_incoming_args_rtx
,
4945 REG_PARM_STACK_SPACE (cfun
->decl
)
4946 - gp_saved
* UNITS_PER_WORD
);
4947 rtx mem
= gen_frame_mem (BLKmode
, ptr
);
4948 set_mem_alias_set (mem
, get_varargs_alias_set ());
4950 move_block_from_reg (local_cum
.num_gprs
+ GP_ARG_FIRST
,
4953 if (REG_PARM_STACK_SPACE (cfun
->decl
) == 0)
4954 cfun
->machine
->varargs_size
= gp_saved
* UNITS_PER_WORD
;
4957 /* Return the descriptor of the Standard Vector Calling Convention Variant. */
4959 static const predefined_function_abi
&
4962 predefined_function_abi
&v_abi
= function_abis
[RISCV_CC_V
];
4963 if (!v_abi
.initialized_p ())
4965 HARD_REG_SET full_reg_clobbers
4966 = default_function_abi
.full_reg_clobbers ();
4967 /* Callee-saved vector registers: v1-v7, v24-v31. */
4968 for (int regno
= V_REG_FIRST
+ 1; regno
<= V_REG_FIRST
+ 7; regno
+= 1)
4969 CLEAR_HARD_REG_BIT (full_reg_clobbers
, regno
);
4970 for (int regno
= V_REG_FIRST
+ 24; regno
<= V_REG_FIRST
+ 31; regno
+= 1)
4971 CLEAR_HARD_REG_BIT (full_reg_clobbers
, regno
);
4972 v_abi
.initialize (RISCV_CC_V
, full_reg_clobbers
);
4977 /* Return true if a function with type FNTYPE returns its value in
4978 RISC-V V registers. */
4981 riscv_return_value_is_vector_type_p (const_tree fntype
)
4983 tree return_type
= TREE_TYPE (fntype
);
4985 return riscv_vector_type_p (return_type
);
4988 /* Return true if a function with type FNTYPE takes arguments in
4989 RISC-V V registers. */
4992 riscv_arguments_is_vector_type_p (const_tree fntype
)
4994 for (tree chain
= TYPE_ARG_TYPES (fntype
); chain
&& chain
!= void_list_node
;
4995 chain
= TREE_CHAIN (chain
))
4997 tree arg_type
= TREE_VALUE (chain
);
4998 if (riscv_vector_type_p (arg_type
))
5005 /* Implement TARGET_FNTYPE_ABI. */
5007 static const predefined_function_abi
&
5008 riscv_fntype_abi (const_tree fntype
)
5010 /* Implementing an experimental vector calling convention, the proposal
5011 can be viewed at the bellow link:
5012 https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/389
5014 You can enable this feature via the `--param=riscv-vector-abi` compiler
5016 if (riscv_vector_abi
5017 && (riscv_return_value_is_vector_type_p (fntype
)
5018 || riscv_arguments_is_vector_type_p (fntype
)))
5019 return riscv_v_abi ();
5021 return default_function_abi
;
5024 /* Return riscv calling convention of call_insn. */
5026 get_riscv_cc (const rtx use
)
5028 gcc_assert (GET_CODE (use
) == USE
);
5029 rtx unspec
= XEXP (use
, 0);
5030 gcc_assert (GET_CODE (unspec
) == UNSPEC
5031 && XINT (unspec
, 1) == UNSPEC_CALLEE_CC
);
5032 riscv_cc cc
= (riscv_cc
) INTVAL (XVECEXP (unspec
, 0, 0));
5033 gcc_assert (cc
< RISCV_CC_UNKNOWN
);
5037 /* Implement TARGET_INSN_CALLEE_ABI. */
5039 const predefined_function_abi
&
5040 riscv_insn_callee_abi (const rtx_insn
*insn
)
5042 rtx pat
= PATTERN (insn
);
5043 gcc_assert (GET_CODE (pat
) == PARALLEL
);
5044 riscv_cc cc
= get_riscv_cc (XVECEXP (pat
, 0, 1));
5045 return function_abis
[cc
];
5048 /* Handle an attribute requiring a FUNCTION_DECL;
5049 arguments as in struct attribute_spec.handler. */
5051 riscv_handle_fndecl_attribute (tree
*node
, tree name
,
5052 tree args ATTRIBUTE_UNUSED
,
5053 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
5055 if (TREE_CODE (*node
) != FUNCTION_DECL
)
5057 warning (OPT_Wattributes
, "%qE attribute only applies to functions",
5059 *no_add_attrs
= true;
5065 /* Verify type based attributes. NODE is the what the attribute is being
5066 applied to. NAME is the attribute name. ARGS are the attribute args.
5067 FLAGS gives info about the context. NO_ADD_ATTRS should be set to true if
5068 the attribute should be ignored. */
5071 riscv_handle_type_attribute (tree
*node ATTRIBUTE_UNUSED
, tree name
, tree args
,
5072 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
5074 /* Check for an argument. */
5075 if (is_attribute_p ("interrupt", name
))
5079 tree cst
= TREE_VALUE (args
);
5082 if (TREE_CODE (cst
) != STRING_CST
)
5084 warning (OPT_Wattributes
,
5085 "%qE attribute requires a string argument",
5087 *no_add_attrs
= true;
5091 string
= TREE_STRING_POINTER (cst
);
5092 if (strcmp (string
, "user") && strcmp (string
, "supervisor")
5093 && strcmp (string
, "machine"))
5095 warning (OPT_Wattributes
,
5096 "argument to %qE attribute is not %<\"user\"%>, %<\"supervisor\"%>, "
5097 "or %<\"machine\"%>", name
);
5098 *no_add_attrs
= true;
5106 /* Return true if function TYPE is an interrupt function. */
5108 riscv_interrupt_type_p (tree type
)
5110 return lookup_attribute ("interrupt", TYPE_ATTRIBUTES (type
)) != NULL
;
5113 /* Return true if FUNC is a naked function. */
5115 riscv_naked_function_p (tree func
)
5117 tree func_decl
= func
;
5118 if (func
== NULL_TREE
)
5119 func_decl
= current_function_decl
;
5120 return NULL_TREE
!= lookup_attribute ("naked", DECL_ATTRIBUTES (func_decl
));
5123 /* Implement TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS. */
5125 riscv_allocate_stack_slots_for_args ()
5127 /* Naked functions should not allocate stack slots for arguments. */
5128 return !riscv_naked_function_p (current_function_decl
);
5131 /* Implement TARGET_WARN_FUNC_RETURN. */
5133 riscv_warn_func_return (tree decl
)
5135 /* Naked functions are implemented entirely in assembly, including the
5136 return sequence, so suppress warnings about this. */
5137 return !riscv_naked_function_p (decl
);
5140 /* Implement TARGET_EXPAND_BUILTIN_VA_START. */
5143 riscv_va_start (tree valist
, rtx nextarg
)
5145 nextarg
= plus_constant (Pmode
, nextarg
, -cfun
->machine
->varargs_size
);
5146 std_expand_builtin_va_start (valist
, nextarg
);
5149 /* Make ADDR suitable for use as a call or sibcall target. */
5152 riscv_legitimize_call_address (rtx addr
)
5154 if (!call_insn_operand (addr
, VOIDmode
))
5156 rtx reg
= RISCV_CALL_ADDRESS_TEMP (Pmode
);
5157 riscv_emit_move (reg
, addr
);
5163 /* Print symbolic operand OP, which is part of a HIGH or LO_SUM
5164 in context CONTEXT. HI_RELOC indicates a high-part reloc. */
5167 riscv_print_operand_reloc (FILE *file
, rtx op
, bool hi_reloc
)
5171 switch (riscv_classify_symbolic_expression (op
))
5173 case SYMBOL_ABSOLUTE
:
5174 reloc
= hi_reloc
? "%hi" : "%lo";
5178 reloc
= hi_reloc
? "%pcrel_hi" : "%pcrel_lo";
5182 reloc
= hi_reloc
? "%tprel_hi" : "%tprel_lo";
5186 output_operand_lossage ("invalid use of '%%%c'", hi_reloc
? 'h' : 'R');
5190 fprintf (file
, "%s(", reloc
);
5191 output_addr_const (file
, riscv_strip_unspec_address (op
));
5195 /* Return the memory model that encapuslates both given models. */
5198 riscv_union_memmodels (enum memmodel model1
, enum memmodel model2
)
5200 model1
= memmodel_base (model1
);
5201 model2
= memmodel_base (model2
);
5203 enum memmodel weaker
= model1
<= model2
? model1
: model2
;
5204 enum memmodel stronger
= model1
> model2
? model1
: model2
;
5208 case MEMMODEL_SEQ_CST
:
5209 case MEMMODEL_ACQ_REL
:
5211 case MEMMODEL_RELEASE
:
5212 if (weaker
== MEMMODEL_ACQUIRE
|| weaker
== MEMMODEL_CONSUME
)
5213 return MEMMODEL_ACQ_REL
;
5216 case MEMMODEL_ACQUIRE
:
5217 case MEMMODEL_CONSUME
:
5218 case MEMMODEL_RELAXED
:
5225 /* Return true if the .AQ suffix should be added to an AMO to implement the
5226 acquire portion of memory model MODEL. */
5229 riscv_memmodel_needs_amo_acquire (enum memmodel model
)
5231 /* ZTSO amo mappings require no annotations. */
5237 case MEMMODEL_ACQ_REL
:
5238 case MEMMODEL_SEQ_CST
:
5239 case MEMMODEL_ACQUIRE
:
5240 case MEMMODEL_CONSUME
:
5243 case MEMMODEL_RELEASE
:
5244 case MEMMODEL_RELAXED
:
5252 /* Return true if the .RL suffix should be added to an AMO to implement the
5253 release portion of memory model MODEL. */
5256 riscv_memmodel_needs_amo_release (enum memmodel model
)
5258 /* ZTSO amo mappings require no annotations. */
5264 case MEMMODEL_ACQ_REL
:
5265 case MEMMODEL_SEQ_CST
:
5266 case MEMMODEL_RELEASE
:
5269 case MEMMODEL_ACQUIRE
:
5270 case MEMMODEL_CONSUME
:
5271 case MEMMODEL_RELAXED
:
5279 /* Get REGNO alignment of vector mode.
5280 The alignment = LMUL when the LMUL >= 1.
5281 Otherwise, alignment = 1. */
5283 riscv_get_v_regno_alignment (machine_mode mode
)
5285 /* 3.3.2. LMUL = 2,4,8, register numbers should be multiple of 2,4,8.
5286 but for mask vector register, register numbers can be any number. */
5288 machine_mode rvv_mode
= mode
;
5289 if (riscv_v_ext_vls_mode_p (rvv_mode
))
5291 int size
= GET_MODE_BITSIZE (rvv_mode
).to_constant ();
5292 if (size
< TARGET_MIN_VLEN
)
5295 return size
/ TARGET_MIN_VLEN
;
5297 if (riscv_v_ext_tuple_mode_p (rvv_mode
))
5298 rvv_mode
= riscv_vector::get_subpart_mode (rvv_mode
);
5299 poly_int64 size
= GET_MODE_SIZE (rvv_mode
);
5300 if (known_gt (size
, UNITS_PER_V_REG
))
5301 lmul
= exact_div (size
, UNITS_PER_V_REG
).to_constant ();
5305 /* Implement TARGET_PRINT_OPERAND. The RISCV-specific operand codes are:
5307 'h' Print the high-part relocation associated with OP, after stripping
5309 'R' Print the low-part relocation associated with OP.
5310 'C' Print the integer branch condition for comparison OP.
5311 'N' Print the inverse of the integer branch condition for comparison OP.
5312 'A' Print the atomic operation suffix for memory model OP.
5313 'I' Print the LR suffix for memory model OP.
5314 'J' Print the SC suffix for memory model OP.
5315 'z' Print x0 if OP is zero, otherwise print OP normally.
5316 'i' Print i if the operand is not a register.
5317 'S' Print shift-index of single-bit mask OP.
5318 'T' Print shift-index of inverted single-bit mask OP.
5319 '~' Print w if TARGET_64BIT is true; otherwise not print anything.
5321 Note please keep this list and the list in riscv.md in sync. */
5324 riscv_print_operand (FILE *file
, rtx op
, int letter
)
5326 /* `~` does not take an operand so op will be null
5327 Check for before accessing op.
5335 machine_mode mode
= GET_MODE (op
);
5336 enum rtx_code code
= GET_CODE (op
);
5341 /* Print 'OP' variant for RVV instructions.
5342 1. If the operand is VECTOR REG, we print 'v'(vnsrl.wv).
5343 2. If the operand is CONST_INT/CONST_VECTOR, we print 'i'(vnsrl.wi).
5344 3. If the operand is SCALAR REG, we print 'x'(vnsrl.wx). */
5345 if (riscv_v_ext_mode_p (mode
))
5348 asm_fprintf (file
, "v");
5349 else if (CONST_VECTOR_P (op
))
5350 asm_fprintf (file
, "i");
5352 output_operand_lossage ("invalid vector operand");
5356 if (CONST_INT_P (op
))
5357 asm_fprintf (file
, "i");
5359 asm_fprintf (file
, "x");
5367 asm_fprintf (file
, "%s", reg_names
[REGNO (op
)]);
5370 if (!const_vec_duplicate_p (op
, &elt
))
5371 output_operand_lossage ("invalid vector constant");
5372 else if (satisfies_constraint_Wc0 (op
))
5373 asm_fprintf (file
, "0");
5374 else if (satisfies_constraint_vi (op
)
5375 || satisfies_constraint_vj (op
)
5376 || satisfies_constraint_vk (op
))
5377 asm_fprintf (file
, "%wd", INTVAL (elt
));
5379 output_operand_lossage ("invalid vector constant");
5385 if (!const_vec_duplicate_p (op
, &elt
))
5386 output_operand_lossage ("invalid vector constant");
5387 else if (satisfies_constraint_vj (op
))
5388 asm_fprintf (file
, "%wd", -INTVAL (elt
));
5390 output_operand_lossage ("invalid vector constant");
5394 if (riscv_v_ext_mode_p (mode
))
5396 /* Calculate lmul according to mode and print the value. */
5397 int lmul
= riscv_get_v_regno_alignment (mode
);
5398 asm_fprintf (file
, "%d", lmul
);
5400 else if (code
== CONST_INT
)
5402 /* If it is a const_int value, it denotes the VLMUL field enum. */
5403 unsigned int vlmul
= UINTVAL (op
);
5406 case riscv_vector::LMUL_1
:
5407 asm_fprintf (file
, "%s", "m1");
5409 case riscv_vector::LMUL_2
:
5410 asm_fprintf (file
, "%s", "m2");
5412 case riscv_vector::LMUL_4
:
5413 asm_fprintf (file
, "%s", "m4");
5415 case riscv_vector::LMUL_8
:
5416 asm_fprintf (file
, "%s", "m8");
5418 case riscv_vector::LMUL_F8
:
5419 asm_fprintf (file
, "%s", "mf8");
5421 case riscv_vector::LMUL_F4
:
5422 asm_fprintf (file
, "%s", "mf4");
5424 case riscv_vector::LMUL_F2
:
5425 asm_fprintf (file
, "%s", "mf2");
5432 output_operand_lossage ("invalid vector constant");
5436 if (GET_MODE_CLASS (mode
) == MODE_VECTOR_BOOL
)
5438 /* Print for RVV mask operand.
5439 If op is reg, print ",v0.t".
5440 Otherwise, don't print anything. */
5442 fprintf (file
, ",%s.t", reg_names
[REGNO (op
)]);
5444 else if (code
== CONST_INT
)
5446 /* Tail && Mask policy. */
5447 asm_fprintf (file
, "%s", IS_AGNOSTIC (UINTVAL (op
)) ? "a" : "u");
5450 output_operand_lossage ("invalid vector constant");
5456 riscv_print_operand_reloc (file
, op
, true);
5460 riscv_print_operand_reloc (file
, op
, false);
5464 /* The RTL names match the instruction names. */
5465 fputs (GET_RTX_NAME (code
), file
);
5469 /* The RTL names match the instruction names. */
5470 fputs (GET_RTX_NAME (reverse_condition (code
)), file
);
5474 const enum memmodel model
= memmodel_base (INTVAL (op
));
5475 if (riscv_memmodel_needs_amo_acquire (model
)
5476 && riscv_memmodel_needs_amo_release (model
))
5477 fputs (".aqrl", file
);
5478 else if (riscv_memmodel_needs_amo_acquire (model
))
5479 fputs (".aq", file
);
5480 else if (riscv_memmodel_needs_amo_release (model
))
5481 fputs (".rl", file
);
5486 const enum memmodel model
= memmodel_base (INTVAL (op
));
5487 if (TARGET_ZTSO
&& model
!= MEMMODEL_SEQ_CST
)
5488 /* LR ops only have an annotation for SEQ_CST in the Ztso mapping. */
5490 else if (model
== MEMMODEL_SEQ_CST
)
5491 fputs (".aqrl", file
);
5492 else if (riscv_memmodel_needs_amo_acquire (model
))
5493 fputs (".aq", file
);
5498 const enum memmodel model
= memmodel_base (INTVAL (op
));
5499 if (TARGET_ZTSO
&& model
== MEMMODEL_SEQ_CST
)
5500 /* SC ops only have an annotation for SEQ_CST in the Ztso mapping. */
5501 fputs (".rl", file
);
5502 else if (TARGET_ZTSO
)
5504 else if (riscv_memmodel_needs_amo_release (model
))
5505 fputs (".rl", file
);
5515 fputs (GET_RTX_NAME (code
), file
);
5520 rtx newop
= GEN_INT (ctz_hwi (INTVAL (op
)));
5521 output_addr_const (file
, newop
);
5526 rtx newop
= GEN_INT (ctz_hwi (~INTVAL (op
)));
5527 output_addr_const (file
, newop
);
5532 int ival
= INTVAL (op
) + 1;
5533 rtx newop
= GEN_INT (ctz_hwi (ival
) + 1);
5534 output_addr_const (file
, newop
);
5541 if (letter
&& letter
!= 'z')
5542 output_operand_lossage ("invalid use of '%%%c'", letter
);
5543 fprintf (file
, "%s", reg_names
[REGNO (op
)]);
5547 if (letter
&& letter
!= 'z')
5548 output_operand_lossage ("invalid use of '%%%c'", letter
);
5550 output_address (mode
, XEXP (op
, 0));
5555 if (letter
== 'z' && op
== CONST0_RTX (GET_MODE (op
)))
5557 fputs (reg_names
[GP_REG_FIRST
], file
);
5561 int fli_index
= riscv_float_const_rtx_index_for_fli (op
);
5562 if (fli_index
== -1 || fli_index
> 31)
5564 output_operand_lossage ("invalid use of '%%%c'", letter
);
5567 asm_fprintf (file
, "%s", fli_value_print
[fli_index
]);
5572 if (letter
== 'z' && op
== CONST0_RTX (GET_MODE (op
)))
5573 fputs (reg_names
[GP_REG_FIRST
], file
);
5574 else if (letter
&& letter
!= 'z')
5575 output_operand_lossage ("invalid use of '%%%c'", letter
);
5577 output_addr_const (file
, riscv_strip_unspec_address (op
));
5583 /* Implement TARGET_PRINT_OPERAND_PUNCT_VALID_P */
5585 riscv_print_operand_punct_valid_p (unsigned char code
)
5587 return (code
== '~');
5590 /* Implement TARGET_PRINT_OPERAND_ADDRESS. */
5593 riscv_print_operand_address (FILE *file
, machine_mode mode ATTRIBUTE_UNUSED
, rtx x
)
5595 struct riscv_address_info addr
;
5597 if (th_print_operand_address (file
, mode
, x
))
5600 if (riscv_classify_address (&addr
, x
, word_mode
, true))
5604 output_addr_const (file
, riscv_strip_unspec_address (addr
.offset
));
5605 fprintf (file
, "(%s)", reg_names
[REGNO (addr
.reg
)]);
5608 case ADDRESS_LO_SUM
:
5609 riscv_print_operand_reloc (file
, addr
.offset
, false);
5610 fprintf (file
, "(%s)", reg_names
[REGNO (addr
.reg
)]);
5613 case ADDRESS_CONST_INT
:
5614 output_addr_const (file
, x
);
5615 fprintf (file
, "(%s)", reg_names
[GP_REG_FIRST
]);
5618 case ADDRESS_SYMBOLIC
:
5619 output_addr_const (file
, riscv_strip_unspec_address (x
));
5630 riscv_size_ok_for_small_data_p (int size
)
5632 return g_switch_value
&& IN_RANGE (size
, 1, g_switch_value
);
5635 /* Return true if EXP should be placed in the small data section. */
5638 riscv_in_small_data_p (const_tree x
)
5640 if (TREE_CODE (x
) == STRING_CST
|| TREE_CODE (x
) == FUNCTION_DECL
)
5643 if (VAR_P (x
) && DECL_SECTION_NAME (x
))
5645 const char *sec
= DECL_SECTION_NAME (x
);
5646 return strcmp (sec
, ".sdata") == 0 || strcmp (sec
, ".sbss") == 0;
5649 return riscv_size_ok_for_small_data_p (int_size_in_bytes (TREE_TYPE (x
)));
5652 /* Switch to the appropriate section for output of DECL. */
5655 riscv_select_section (tree decl
, int reloc
,
5656 unsigned HOST_WIDE_INT align
)
5658 switch (categorize_decl_for_section (decl
, reloc
))
5660 case SECCAT_SRODATA
:
5661 return get_named_section (decl
, ".srodata", reloc
);
5664 return default_elf_select_section (decl
, reloc
, align
);
5668 /* Switch to the appropriate section for output of DECL. */
5671 riscv_unique_section (tree decl
, int reloc
)
5673 const char *prefix
= NULL
;
5674 bool one_only
= DECL_ONE_ONLY (decl
) && !HAVE_COMDAT_GROUP
;
5676 switch (categorize_decl_for_section (decl
, reloc
))
5678 case SECCAT_SRODATA
:
5679 prefix
= one_only
? ".sr" : ".srodata";
5687 const char *name
, *linkonce
;
5690 name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
));
5691 name
= targetm
.strip_name_encoding (name
);
5693 /* If we're using one_only, then there needs to be a .gnu.linkonce
5694 prefix to the section name. */
5695 linkonce
= one_only
? ".gnu.linkonce" : "";
5697 string
= ACONCAT ((linkonce
, prefix
, ".", name
, NULL
));
5699 set_decl_section_name (decl
, string
);
5702 default_unique_section (decl
, reloc
);
5705 /* Return a section for X, handling small data. */
5708 riscv_elf_select_rtx_section (machine_mode mode
, rtx x
,
5709 unsigned HOST_WIDE_INT align
)
5711 section
*s
= default_elf_select_rtx_section (mode
, x
, align
);
5713 if (riscv_size_ok_for_small_data_p (GET_MODE_SIZE (mode
).to_constant ()))
5715 if (startswith (s
->named
.name
, ".rodata.cst"))
5717 /* Rename .rodata.cst* to .srodata.cst*. */
5718 char *name
= (char *) alloca (strlen (s
->named
.name
) + 2);
5719 sprintf (name
, ".s%s", s
->named
.name
+ 1);
5720 return get_section (name
, s
->named
.common
.flags
, NULL
);
5723 if (s
== data_section
)
5724 return sdata_section
;
5730 /* Make the last instruction frame-related and note that it performs
5731 the operation described by FRAME_PATTERN. */
5734 riscv_set_frame_expr (rtx frame_pattern
)
5738 insn
= get_last_insn ();
5739 RTX_FRAME_RELATED_P (insn
) = 1;
5740 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
5745 /* Return a frame-related rtx that stores REG at MEM.
5746 REG must be a single register. */
5749 riscv_frame_set (rtx mem
, rtx reg
)
5751 rtx set
= gen_rtx_SET (mem
, reg
);
5752 RTX_FRAME_RELATED_P (set
) = 1;
5756 /* Returns true if the current function might contain a far jump. */
5759 riscv_far_jump_used_p ()
5761 size_t func_size
= 0;
5763 if (cfun
->machine
->far_jump_used
)
5766 /* We can't change far_jump_used during or after reload, as there is
5767 no chance to change stack frame layout. So we must rely on the
5768 conservative heuristic below having done the right thing. */
5769 if (reload_in_progress
|| reload_completed
)
5772 /* Estimate the function length. */
5773 for (rtx_insn
*insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5774 func_size
+= get_attr_length (insn
);
5776 /* Conservatively determine whether some jump might exceed 1 MiB
5778 if (func_size
* 2 >= 0x100000)
5779 cfun
->machine
->far_jump_used
= true;
5781 return cfun
->machine
->far_jump_used
;
5784 /* Return true, if the current function must save the incoming return
5788 riscv_save_return_addr_reg_p (void)
5790 /* The $ra register is call-clobbered: if this is not a leaf function,
5795 /* We need to save the incoming return address if __builtin_eh_return
5796 is being used to set a different return address. */
5797 if (crtl
->calls_eh_return
)
5800 /* Far jumps/branches use $ra as a temporary to set up the target jump
5801 location (clobbering the incoming return address). */
5802 if (riscv_far_jump_used_p ())
5805 /* Need not to use ra for leaf when frame pointer is turned off by
5806 option whatever the omit-leaf-frame's value. */
5807 if (frame_pointer_needed
&& crtl
->is_leaf
5808 && !TARGET_OMIT_LEAF_FRAME_POINTER
)
5814 /* Return true if the current function must save register REGNO. */
5817 riscv_save_reg_p (unsigned int regno
)
5819 bool call_saved
= !global_regs
[regno
] && !call_used_or_fixed_reg_p (regno
);
5820 bool might_clobber
= crtl
->saves_all_registers
5821 || df_regs_ever_live_p (regno
);
5823 if (call_saved
&& might_clobber
)
5826 /* Save callee-saved V registers. */
5827 if (V_REG_P (regno
) && !crtl
->abi
->clobbers_full_reg_p (regno
)
5831 if (regno
== HARD_FRAME_POINTER_REGNUM
&& frame_pointer_needed
)
5834 if (regno
== RETURN_ADDR_REGNUM
&& riscv_save_return_addr_reg_p ())
5837 /* If this is an interrupt handler, then must save extra registers. */
5838 if (cfun
->machine
->interrupt_handler_p
)
5840 /* zero register is always zero. */
5841 if (regno
== GP_REG_FIRST
)
5844 /* The function will return the stack pointer to its original value. */
5845 if (regno
== STACK_POINTER_REGNUM
)
5848 /* By convention, we assume that gp and tp are safe. */
5849 if (regno
== GP_REGNUM
|| regno
== THREAD_POINTER_REGNUM
)
5852 /* We must save every register used in this function. If this is not a
5853 leaf function, then we must save all temporary registers. */
5854 if (df_regs_ever_live_p (regno
)
5855 || (!crtl
->is_leaf
&& call_used_or_fixed_reg_p (regno
)))
5862 /* Return TRUE if Zcmp push and pop insns should be
5863 avoided. FALSE otherwise.
5864 Only use multi push & pop if all GPRs masked can be covered,
5865 and stack access is SP based,
5866 and GPRs are at top of the stack frame,
5867 and no conflicts in stack allocation with other features */
5869 riscv_avoid_multi_push (const struct riscv_frame_info
*frame
)
5871 if (!TARGET_ZCMP
|| crtl
->calls_eh_return
|| frame_pointer_needed
5872 || cfun
->machine
->interrupt_handler_p
|| cfun
->machine
->varargs_size
!= 0
5873 || crtl
->args
.pretend_args_size
!= 0
5874 || (use_shrink_wrapping_separate ()
5875 && !riscv_avoid_shrink_wrapping_separate ())
5876 || (frame
->mask
& ~MULTI_PUSH_GPR_MASK
))
5882 /* Determine whether to use multi push insn. */
5884 riscv_use_multi_push (const struct riscv_frame_info
*frame
)
5886 if (riscv_avoid_multi_push (frame
))
5889 return (frame
->multi_push_adj_base
!= 0);
5892 /* Return TRUE if a libcall to save/restore GPRs should be
5893 avoided. FALSE otherwise. */
5895 riscv_avoid_save_libcall (void)
5897 if (!TARGET_SAVE_RESTORE
5898 || crtl
->calls_eh_return
5899 || frame_pointer_needed
5900 || cfun
->machine
->interrupt_handler_p
5901 || cfun
->machine
->varargs_size
!= 0
5902 || crtl
->args
.pretend_args_size
!= 0)
5908 /* Determine whether to call GPR save/restore routines. */
5910 riscv_use_save_libcall (const struct riscv_frame_info
*frame
)
5912 if (riscv_avoid_save_libcall ())
5915 return frame
->save_libcall_adjustment
!= 0;
5918 /* Determine which GPR save/restore routine to call. */
5921 riscv_save_libcall_count (unsigned mask
)
5923 for (unsigned n
= GP_REG_LAST
; n
> GP_REG_FIRST
; n
--)
5924 if (BITSET_P (mask
, n
))
5925 return CALLEE_SAVED_REG_NUMBER (n
) + 1;
5929 /* calculate number of s regs in multi push and pop.
5930 Note that {s0-s10} is not valid in Zcmp, use {s0-s11} instead. */
5932 riscv_multi_push_sregs_count (unsigned mask
)
5934 unsigned num
= riscv_save_libcall_count (mask
);
5935 return (num
== ZCMP_INVALID_S0S10_SREGS_COUNTS
) ? ZCMP_S0S11_SREGS_COUNTS
5939 /* calculate number of regs(ra, s0-sx) in multi push and pop. */
5941 riscv_multi_push_regs_count (unsigned mask
)
5944 return riscv_multi_push_sregs_count (mask
) + 1;
5947 /* Handle 16 bytes align for poly_int. */
5949 riscv_16bytes_align (poly_int64 value
)
5951 return aligned_upper_bound (value
, 16);
5954 static HOST_WIDE_INT
5955 riscv_16bytes_align (HOST_WIDE_INT value
)
5957 return ROUND_UP (value
, 16);
5960 /* Handle stack align for poly_int. */
5962 riscv_stack_align (poly_int64 value
)
5964 return aligned_upper_bound (value
, PREFERRED_STACK_BOUNDARY
/ 8);
5967 static HOST_WIDE_INT
5968 riscv_stack_align (HOST_WIDE_INT value
)
5970 return RISCV_STACK_ALIGN (value
);
5973 /* Populate the current function's riscv_frame_info structure.
5975 RISC-V stack frames grown downward. High addresses are at the top.
5977 +-------------------------------+
5979 | incoming stack arguments |
5981 +-------------------------------+ <-- incoming stack pointer
5983 | callee-allocated save area |
5984 | for arguments that are |
5985 | split between registers and |
5988 +-------------------------------+ <-- arg_pointer_rtx
5990 | callee-allocated save area |
5991 | for register varargs |
5993 +-------------------------------+ <-- hard_frame_pointer_rtx;
5994 | | stack_pointer_rtx + gp_sp_offset
5995 | GPR save area | + UNITS_PER_WORD
5997 +-------------------------------+ <-- stack_pointer_rtx + fp_sp_offset
5998 | | + UNITS_PER_FP_REG
6001 +-------------------------------+ <-- stack_pointer_rtx
6002 | | + v_sp_offset_top
6003 | Vector Registers save area |
6005 | ----------------------------- | <-- stack_pointer_rtx
6006 | padding | + v_sp_offset_bottom
6007 +-------------------------------+ <-- frame_pointer_rtx (virtual)
6011 P +-------------------------------+
6013 | outgoing stack arguments |
6015 +-------------------------------+ <-- stack_pointer_rtx
6017 Dynamic stack allocations such as alloca insert data at point P.
6018 They decrease stack_pointer_rtx but leave frame_pointer_rtx and
6019 hard_frame_pointer_rtx unchanged. */
6021 static HOST_WIDE_INT
riscv_first_stack_step (struct riscv_frame_info
*frame
, poly_int64 remaining_size
);
6024 riscv_compute_frame_info (void)
6026 struct riscv_frame_info
*frame
;
6028 bool interrupt_save_prologue_temp
= false;
6029 unsigned int regno
, i
, num_x_saved
= 0, num_f_saved
= 0, x_save_size
= 0;
6030 unsigned int num_v_saved
= 0;
6032 frame
= &cfun
->machine
->frame
;
6034 /* In an interrupt function, there are two cases in which t0 needs to be used:
6035 1, If we have a large frame, then we need to save/restore t0. We check for
6036 this before clearing the frame struct.
6037 2, Need to save and restore some CSRs in the frame. */
6038 if (cfun
->machine
->interrupt_handler_p
)
6040 HOST_WIDE_INT step1
= riscv_first_stack_step (frame
, frame
->total_size
);
6041 if (! POLY_SMALL_OPERAND_P ((frame
->total_size
- step1
))
6042 || (TARGET_HARD_FLOAT
|| TARGET_ZFINX
))
6043 interrupt_save_prologue_temp
= true;
6048 if (!cfun
->machine
->naked_p
)
6050 /* Find out which GPRs we need to save. */
6051 for (regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
6052 if (riscv_save_reg_p (regno
)
6053 || (interrupt_save_prologue_temp
6054 && (regno
== RISCV_PROLOGUE_TEMP_REGNUM
)))
6055 frame
->mask
|= 1 << (regno
- GP_REG_FIRST
), num_x_saved
++;
6057 /* If this function calls eh_return, we must also save and restore the
6058 EH data registers. */
6059 if (crtl
->calls_eh_return
)
6060 for (i
= 0; (regno
= EH_RETURN_DATA_REGNO (i
)) != INVALID_REGNUM
; i
++)
6061 frame
->mask
|= 1 << (regno
- GP_REG_FIRST
), num_x_saved
++;
6063 /* Find out which FPRs we need to save. This loop must iterate over
6064 the same space as its companion in riscv_for_each_saved_reg. */
6065 if (TARGET_HARD_FLOAT
)
6066 for (regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
++)
6067 if (riscv_save_reg_p (regno
))
6068 frame
->fmask
|= 1 << (regno
- FP_REG_FIRST
), num_f_saved
++;
6070 /* Find out which V registers we need to save. */
6072 for (regno
= V_REG_FIRST
; regno
<= V_REG_LAST
; regno
++)
6073 if (riscv_save_reg_p (regno
))
6075 frame
->vmask
|= 1 << (regno
- V_REG_FIRST
);
6082 x_save_size
= riscv_stack_align (num_x_saved
* UNITS_PER_WORD
);
6085 unsigned num_save_restore
= 1 + riscv_save_libcall_count (frame
->mask
);
6086 /* Only use save/restore routines if they don't alter the stack size. */
6087 if (riscv_stack_align (num_save_restore
* UNITS_PER_WORD
) == x_save_size
6088 && !riscv_avoid_save_libcall ())
6090 /* Libcall saves/restores 3 registers at once, so we need to
6091 allocate 12 bytes for callee-saved register. */
6093 x_save_size
= 3 * UNITS_PER_WORD
;
6095 frame
->save_libcall_adjustment
= x_save_size
;
6098 if (!riscv_avoid_multi_push (frame
))
6100 /* num(ra, s0-sx) */
6101 unsigned num_multi_push
= riscv_multi_push_regs_count (frame
->mask
);
6102 x_save_size
= riscv_stack_align (num_multi_push
* UNITS_PER_WORD
);
6103 frame
->multi_push_adj_base
= riscv_16bytes_align (x_save_size
);
6107 /* In an interrupt function, we need extra space for the initial saves of CSRs. */
6108 if (cfun
->machine
->interrupt_handler_p
6109 && ((TARGET_HARD_FLOAT
&& frame
->fmask
)
6111 /* Except for RISCV_PROLOGUE_TEMP_REGNUM. */
6112 && (frame
->mask
& ~(1 << RISCV_PROLOGUE_TEMP_REGNUM
)))))
6113 /* Save and restore FCSR. */
6114 /* TODO: When P or V extensions support interrupts, some of their CSRs
6115 may also need to be saved and restored. */
6116 x_save_size
+= riscv_stack_align (1 * UNITS_PER_WORD
);
6118 /* At the bottom of the frame are any outgoing stack arguments. */
6119 offset
= riscv_stack_align (crtl
->outgoing_args_size
);
6120 /* Next are local stack variables. */
6121 offset
+= riscv_stack_align (get_frame_size ());
6122 /* The virtual frame pointer points above the local variables. */
6123 frame
->frame_pointer_offset
= offset
;
6124 /* Next are the callee-saved VRs. */
6126 offset
+= riscv_stack_align (num_v_saved
* UNITS_PER_V_REG
);
6127 frame
->v_sp_offset_top
= offset
;
6128 frame
->v_sp_offset_bottom
6129 = frame
->v_sp_offset_top
- num_v_saved
* UNITS_PER_V_REG
;
6130 /* Next are the callee-saved FPRs. */
6132 offset
+= riscv_stack_align (num_f_saved
* UNITS_PER_FP_REG
);
6133 frame
->fp_sp_offset
= offset
- UNITS_PER_FP_REG
;
6134 /* Next are the callee-saved GPRs. */
6137 offset
+= x_save_size
;
6138 /* align to 16 bytes and add paddings to GPR part to honor
6139 both stack alignment and zcmp pus/pop size alignment. */
6140 if (riscv_use_multi_push (frame
)
6141 && known_lt (offset
, frame
->multi_push_adj_base
6142 + ZCMP_SP_INC_STEP
* ZCMP_MAX_SPIMM
))
6143 offset
= riscv_16bytes_align (offset
);
6145 frame
->gp_sp_offset
= offset
- UNITS_PER_WORD
;
6146 /* The hard frame pointer points above the callee-saved GPRs. */
6147 frame
->hard_frame_pointer_offset
= offset
;
6148 /* Above the hard frame pointer is the callee-allocated varags save area. */
6149 offset
+= riscv_stack_align (cfun
->machine
->varargs_size
);
6150 /* Next is the callee-allocated area for pretend stack arguments. */
6151 offset
+= riscv_stack_align (crtl
->args
.pretend_args_size
);
6152 /* Arg pointer must be below pretend args, but must be above alignment
6154 frame
->arg_pointer_offset
= offset
- crtl
->args
.pretend_args_size
;
6155 frame
->total_size
= offset
;
6157 /* Next points the incoming stack pointer and any incoming arguments. */
6160 /* Make sure that we're not trying to eliminate to the wrong hard frame
6164 riscv_can_eliminate (const int from ATTRIBUTE_UNUSED
, const int to
)
6166 return (to
== HARD_FRAME_POINTER_REGNUM
|| to
== STACK_POINTER_REGNUM
);
6169 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame pointer
6170 or argument pointer. TO is either the stack pointer or hard frame
6174 riscv_initial_elimination_offset (int from
, int to
)
6176 poly_int64 src
, dest
;
6178 riscv_compute_frame_info ();
6180 if (to
== HARD_FRAME_POINTER_REGNUM
)
6181 dest
= cfun
->machine
->frame
.hard_frame_pointer_offset
;
6182 else if (to
== STACK_POINTER_REGNUM
)
6183 dest
= 0; /* The stack pointer is the base of all offsets, hence 0. */
6187 if (from
== FRAME_POINTER_REGNUM
)
6188 src
= cfun
->machine
->frame
.frame_pointer_offset
;
6189 else if (from
== ARG_POINTER_REGNUM
)
6190 src
= cfun
->machine
->frame
.arg_pointer_offset
;
6197 /* Implement RETURN_ADDR_RTX. We do not support moving back to a
6201 riscv_return_addr (int count
, rtx frame ATTRIBUTE_UNUSED
)
6206 return get_hard_reg_initial_val (Pmode
, RETURN_ADDR_REGNUM
);
6209 /* Emit code to change the current function's return address to
6210 ADDRESS. SCRATCH is available as a scratch register, if needed.
6211 ADDRESS and SCRATCH are both word-mode GPRs. */
6214 riscv_set_return_address (rtx address
, rtx scratch
)
6218 gcc_assert (BITSET_P (cfun
->machine
->frame
.mask
, RETURN_ADDR_REGNUM
));
6219 slot_address
= riscv_add_offset (scratch
, stack_pointer_rtx
,
6220 cfun
->machine
->frame
.gp_sp_offset
.to_constant());
6221 riscv_emit_move (gen_frame_mem (GET_MODE (address
), slot_address
), address
);
6224 /* Save register REG to MEM. Make the instruction frame-related. */
6227 riscv_save_reg (rtx reg
, rtx mem
)
6229 riscv_emit_move (mem
, reg
);
6230 riscv_set_frame_expr (riscv_frame_set (mem
, reg
));
6233 /* Restore register REG from MEM. */
6236 riscv_restore_reg (rtx reg
, rtx mem
)
6238 rtx insn
= riscv_emit_move (reg
, mem
);
6239 rtx dwarf
= NULL_RTX
;
6240 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
6242 if (known_gt (epilogue_cfa_sp_offset
, 0)
6243 && REGNO (reg
) == HARD_FRAME_POINTER_REGNUM
)
6246 = gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
6247 gen_int_mode (epilogue_cfa_sp_offset
, Pmode
));
6248 dwarf
= alloc_reg_note (REG_CFA_DEF_CFA
, cfa_adjust_rtx
, dwarf
);
6251 REG_NOTES (insn
) = dwarf
;
6252 RTX_FRAME_RELATED_P (insn
) = 1;
6255 /* A function to save or store a register. The first argument is the
6256 register and the second is the stack slot. */
6257 typedef void (*riscv_save_restore_fn
) (rtx
, rtx
);
6259 /* Use FN to save or restore register REGNO. MODE is the register's
6260 mode and OFFSET is the offset of its save slot from the current
6264 riscv_save_restore_reg (machine_mode mode
, int regno
,
6265 HOST_WIDE_INT offset
, riscv_save_restore_fn fn
)
6269 mem
= gen_frame_mem (mode
, plus_constant (Pmode
, stack_pointer_rtx
, offset
));
6270 fn (gen_rtx_REG (mode
, regno
), mem
);
6273 /* Return the next register up from REGNO up to LIMIT for the callee
6274 to save or restore. OFFSET will be adjusted accordingly.
6275 If INC is set, then REGNO will be incremented first.
6276 Returns INVALID_REGNUM if there is no such next register. */
6279 riscv_next_saved_reg (unsigned int regno
, unsigned int limit
,
6280 HOST_WIDE_INT
*offset
, bool inc
= true)
6285 while (regno
<= limit
)
6287 if (BITSET_P (cfun
->machine
->frame
.mask
, regno
- GP_REG_FIRST
))
6289 *offset
= *offset
- UNITS_PER_WORD
;
6295 return INVALID_REGNUM
;
6298 /* Return TRUE if provided REGNO is eh return data register. */
6301 riscv_is_eh_return_data_register (unsigned int regno
)
6303 unsigned int i
, regnum
;
6305 if (!crtl
->calls_eh_return
)
6308 for (i
= 0; (regnum
= EH_RETURN_DATA_REGNO (i
)) != INVALID_REGNUM
; i
++)
6309 if (regno
== regnum
)
6317 /* Call FN for each register that is saved by the current function.
6318 SP_OFFSET is the offset of the current stack pointer from the start
6322 riscv_for_each_saved_reg (poly_int64 sp_offset
, riscv_save_restore_fn fn
,
6323 bool epilogue
, bool maybe_eh_return
)
6325 HOST_WIDE_INT offset
, first_fp_offset
;
6326 unsigned int regno
, num_masked_fp
= 0;
6327 unsigned int start
= GP_REG_FIRST
;
6328 unsigned int limit
= GP_REG_LAST
;
6330 /* Save the link register and s-registers. */
6331 offset
= (cfun
->machine
->frame
.gp_sp_offset
- sp_offset
).to_constant ()
6333 for (regno
= riscv_next_saved_reg (start
, limit
, &offset
, false);
6334 regno
!= INVALID_REGNUM
;
6335 regno
= riscv_next_saved_reg (regno
, limit
, &offset
))
6337 if (cfun
->machine
->reg_is_wrapped_separately
[regno
])
6340 /* If this is a normal return in a function that calls the eh_return
6341 builtin, then do not restore the eh return data registers as that
6342 would clobber the return value. But we do still need to save them
6343 in the prologue, and restore them for an exception return, so we
6344 need special handling here. */
6345 if (epilogue
&& !maybe_eh_return
6346 && riscv_is_eh_return_data_register (regno
))
6349 if (TARGET_XTHEADMEMPAIR
)
6351 /* Get the next reg/offset pair. */
6352 HOST_WIDE_INT offset2
= offset
;
6353 unsigned int regno2
= riscv_next_saved_reg (regno
, limit
, &offset2
);
6355 /* Validate everything before emitting a mempair instruction. */
6356 if (regno2
!= INVALID_REGNUM
6357 && !cfun
->machine
->reg_is_wrapped_separately
[regno2
]
6358 && !(epilogue
&& !maybe_eh_return
6359 && riscv_is_eh_return_data_register (regno2
)))
6361 bool load_p
= (fn
== riscv_restore_reg
);
6363 th_mempair_prepare_save_restore_operands (operands
,
6368 /* If the operands fit into a mempair insn, then emit one. */
6369 if (th_mempair_operands_p (operands
, load_p
, word_mode
))
6371 th_mempair_save_restore_regs (operands
, load_p
, word_mode
);
6379 /* In an interrupt function, save and restore some necessary CSRs in the stack
6380 to avoid changes in CSRs. */
6381 if (regno
== RISCV_PROLOGUE_TEMP_REGNUM
6382 && cfun
->machine
->interrupt_handler_p
6383 && ((TARGET_HARD_FLOAT
&& cfun
->machine
->frame
.fmask
)
6385 && (cfun
->machine
->frame
.mask
& ~(1 << RISCV_PROLOGUE_TEMP_REGNUM
)))))
6387 unsigned int fcsr_size
= GET_MODE_SIZE (SImode
);
6390 riscv_save_restore_reg (word_mode
, regno
, offset
, fn
);
6391 offset
-= fcsr_size
;
6392 emit_insn (gen_riscv_frcsr (RISCV_PROLOGUE_TEMP (SImode
)));
6393 riscv_save_restore_reg (SImode
, RISCV_PROLOGUE_TEMP_REGNUM
,
6394 offset
, riscv_save_reg
);
6398 riscv_save_restore_reg (SImode
, RISCV_PROLOGUE_TEMP_REGNUM
,
6399 offset
- fcsr_size
, riscv_restore_reg
);
6400 emit_insn (gen_riscv_fscsr (RISCV_PROLOGUE_TEMP (SImode
)));
6401 riscv_save_restore_reg (word_mode
, regno
, offset
, fn
);
6402 offset
-= fcsr_size
;
6407 riscv_save_restore_reg (word_mode
, regno
, offset
, fn
);
6410 /* This loop must iterate over the same space as its companion in
6411 riscv_compute_frame_info. */
6413 = (cfun
->machine
->frame
.fp_sp_offset
- sp_offset
).to_constant ();
6414 for (unsigned int regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
++)
6415 if (BITSET_P (cfun
->machine
->frame
.fmask
, regno
- FP_REG_FIRST
))
6417 bool handle_reg
= !cfun
->machine
->reg_is_wrapped_separately
[regno
];
6418 machine_mode mode
= TARGET_DOUBLE_FLOAT
? DFmode
: SFmode
;
6419 unsigned int slot
= (riscv_use_multi_push (&cfun
->machine
->frame
))
6420 ? CALLEE_SAVED_FREG_NUMBER (regno
)
6422 offset
= first_fp_offset
- slot
* GET_MODE_SIZE (mode
).to_constant ();
6424 riscv_save_restore_reg (mode
, regno
, offset
, fn
);
6429 /* Call FN for each V register that is saved by the current function. */
6432 riscv_for_each_saved_v_reg (poly_int64
&remaining_size
,
6433 riscv_save_restore_fn fn
, bool prologue
)
6435 rtx vlen
= NULL_RTX
;
6436 if (cfun
->machine
->frame
.vmask
!= 0)
6438 if (UNITS_PER_V_REG
.is_constant ()
6439 && SMALL_OPERAND (UNITS_PER_V_REG
.to_constant ()))
6440 vlen
= GEN_INT (UNITS_PER_V_REG
.to_constant ());
6443 vlen
= RISCV_PROLOGUE_TEMP (Pmode
);
6445 = emit_move_insn (vlen
, gen_int_mode (UNITS_PER_V_REG
, Pmode
));
6446 RTX_FRAME_RELATED_P (insn
) = 1;
6450 /* Select the mode where LMUL is 1 and SEW is largest. */
6451 machine_mode m1_mode
= TARGET_VECTOR_ELEN_64
? RVVM1DImode
: RVVM1SImode
;
6455 /* This loop must iterate over the same space as its companion in
6456 riscv_compute_frame_info. */
6457 for (unsigned int regno
= V_REG_FIRST
; regno
<= V_REG_LAST
; regno
++)
6458 if (BITSET_P (cfun
->machine
->frame
.vmask
, regno
- V_REG_FIRST
))
6460 bool handle_reg
= !cfun
->machine
->reg_is_wrapped_separately
[regno
];
6463 rtx insn
= NULL_RTX
;
6464 if (CONST_INT_P (vlen
))
6466 gcc_assert (SMALL_OPERAND (-INTVAL (vlen
)));
6467 insn
= emit_insn (gen_add3_insn (stack_pointer_rtx
,
6469 GEN_INT (-INTVAL (vlen
))));
6473 gen_sub3_insn (stack_pointer_rtx
, stack_pointer_rtx
, vlen
));
6474 gcc_assert (insn
!= NULL_RTX
);
6475 RTX_FRAME_RELATED_P (insn
) = 1;
6476 riscv_save_restore_reg (m1_mode
, regno
, 0, fn
);
6477 remaining_size
-= UNITS_PER_V_REG
;
6483 /* This loop must iterate over the same space as its companion in
6484 riscv_compute_frame_info. */
6485 for (unsigned int regno
= V_REG_LAST
; regno
>= V_REG_FIRST
; regno
--)
6486 if (BITSET_P (cfun
->machine
->frame
.vmask
, regno
- V_REG_FIRST
))
6488 bool handle_reg
= !cfun
->machine
->reg_is_wrapped_separately
[regno
];
6491 riscv_save_restore_reg (m1_mode
, regno
, 0, fn
);
6492 rtx insn
= emit_insn (
6493 gen_add3_insn (stack_pointer_rtx
, stack_pointer_rtx
, vlen
));
6494 gcc_assert (insn
!= NULL_RTX
);
6495 RTX_FRAME_RELATED_P (insn
) = 1;
6496 remaining_size
-= UNITS_PER_V_REG
;
6502 /* For stack frames that can't be allocated with a single ADDI instruction,
6503 compute the best value to initially allocate. It must at a minimum
6504 allocate enough space to spill the callee-saved registers. If TARGET_RVC,
6505 try to pick a value that will allow compression of the register saves
6506 without adding extra instructions. */
6508 static HOST_WIDE_INT
6509 riscv_first_stack_step (struct riscv_frame_info
*frame
, poly_int64 remaining_size
)
6511 HOST_WIDE_INT remaining_const_size
;
6512 if (!remaining_size
.is_constant ())
6513 remaining_const_size
6514 = riscv_stack_align (remaining_size
.coeffs
[0])
6515 - riscv_stack_align (remaining_size
.coeffs
[1]);
6517 remaining_const_size
= remaining_size
.to_constant ();
6519 /* First step must be set to the top of vector registers save area if any
6520 vector registers need be preversed. */
6521 if (frame
->vmask
!= 0)
6522 return (remaining_size
- frame
->v_sp_offset_top
).to_constant ();
6524 if (SMALL_OPERAND (remaining_const_size
))
6525 return remaining_const_size
;
6527 poly_int64 callee_saved_first_step
=
6528 remaining_size
- frame
->frame_pointer_offset
;
6529 gcc_assert(callee_saved_first_step
.is_constant ());
6530 HOST_WIDE_INT min_first_step
=
6531 riscv_stack_align (callee_saved_first_step
.to_constant ());
6532 HOST_WIDE_INT max_first_step
= IMM_REACH
/ 2 - PREFERRED_STACK_BOUNDARY
/ 8;
6533 HOST_WIDE_INT min_second_step
= remaining_const_size
- max_first_step
;
6534 gcc_assert (min_first_step
<= max_first_step
);
6536 /* As an optimization, use the least-significant bits of the total frame
6537 size, so that the second adjustment step is just LUI + ADD. */
6538 if (!SMALL_OPERAND (min_second_step
)
6539 && remaining_const_size
% IMM_REACH
<= max_first_step
6540 && remaining_const_size
% IMM_REACH
>= min_first_step
)
6541 return remaining_const_size
% IMM_REACH
;
6543 if (TARGET_RVC
|| TARGET_ZCA
)
6545 /* If we need two subtracts, and one is small enough to allow compressed
6546 loads and stores, then put that one first. */
6547 if (IN_RANGE (min_second_step
, 0,
6548 (TARGET_64BIT
? SDSP_REACH
: SWSP_REACH
)))
6549 return MAX (min_second_step
, min_first_step
);
6551 /* If we need LUI + ADDI + ADD for the second adjustment step, then start
6552 with the minimum first step, so that we can get compressed loads and
6554 else if (!SMALL_OPERAND (min_second_step
))
6555 return min_first_step
;
6558 return max_first_step
;
6562 riscv_adjust_libcall_cfi_prologue ()
6564 rtx dwarf
= NULL_RTX
;
6565 rtx adjust_sp_rtx
, reg
, mem
, insn
;
6566 int saved_size
= cfun
->machine
->frame
.save_libcall_adjustment
;
6569 for (int regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
6570 if (BITSET_P (cfun
->machine
->frame
.mask
, regno
- GP_REG_FIRST
))
6572 /* The save order is ra, s0, s1, s2 to s11. */
6573 if (regno
== RETURN_ADDR_REGNUM
)
6574 offset
= saved_size
- UNITS_PER_WORD
;
6575 else if (regno
== S0_REGNUM
)
6576 offset
= saved_size
- UNITS_PER_WORD
* 2;
6577 else if (regno
== S1_REGNUM
)
6578 offset
= saved_size
- UNITS_PER_WORD
* 3;
6580 offset
= saved_size
- ((regno
- S2_REGNUM
+ 4) * UNITS_PER_WORD
);
6582 reg
= gen_rtx_REG (Pmode
, regno
);
6583 mem
= gen_frame_mem (Pmode
, plus_constant (Pmode
,
6587 insn
= gen_rtx_SET (mem
, reg
);
6588 dwarf
= alloc_reg_note (REG_CFA_OFFSET
, insn
, dwarf
);
6591 /* Debug info for adjust sp. */
6593 gen_rtx_SET (stack_pointer_rtx
,
6594 gen_rtx_PLUS (GET_MODE(stack_pointer_rtx
), stack_pointer_rtx
, GEN_INT (-saved_size
)));
6595 dwarf
= alloc_reg_note (REG_CFA_ADJUST_CFA
, adjust_sp_rtx
,
6601 riscv_adjust_multi_push_cfi_prologue (int saved_size
)
6603 rtx dwarf
= NULL_RTX
;
6604 rtx adjust_sp_rtx
, reg
, mem
, insn
;
6605 unsigned int mask
= cfun
->machine
->frame
.mask
;
6609 if (mask
& S10_MASK
)
6612 for (int regno
= GP_REG_LAST
; regno
>= GP_REG_FIRST
; regno
--)
6613 if (BITSET_P (mask
& MULTI_PUSH_GPR_MASK
, regno
- GP_REG_FIRST
))
6615 /* The save order is s11-s0, ra
6616 from high to low addr. */
6617 offset
= saved_size
- UNITS_PER_WORD
* (++saved_cnt
);
6619 reg
= gen_rtx_REG (Pmode
, regno
);
6620 mem
= gen_frame_mem (Pmode
,
6621 plus_constant (Pmode
, stack_pointer_rtx
, offset
));
6623 insn
= gen_rtx_SET (mem
, reg
);
6624 dwarf
= alloc_reg_note (REG_CFA_OFFSET
, insn
, dwarf
);
6627 /* Debug info for adjust sp. */
6629 = gen_rtx_SET (stack_pointer_rtx
,
6630 plus_constant (Pmode
, stack_pointer_rtx
, -saved_size
));
6631 dwarf
= alloc_reg_note (REG_CFA_ADJUST_CFA
, adjust_sp_rtx
, dwarf
);
6636 riscv_emit_stack_tie (void)
6638 if (Pmode
== SImode
)
6639 emit_insn (gen_stack_tiesi (stack_pointer_rtx
, hard_frame_pointer_rtx
));
6641 emit_insn (gen_stack_tiedi (stack_pointer_rtx
, hard_frame_pointer_rtx
));
6644 /*zcmp multi push and pop code_for_push_pop function ptr array */
6645 static const code_for_push_pop_t code_for_push_pop
[ZCMP_MAX_GRP_SLOTS
][ZCMP_OP_NUM
]
6646 = {{code_for_gpr_multi_push_up_to_ra
, code_for_gpr_multi_pop_up_to_ra
,
6647 code_for_gpr_multi_popret_up_to_ra
, code_for_gpr_multi_popretz_up_to_ra
},
6648 {code_for_gpr_multi_push_up_to_s0
, code_for_gpr_multi_pop_up_to_s0
,
6649 code_for_gpr_multi_popret_up_to_s0
, code_for_gpr_multi_popretz_up_to_s0
},
6650 {code_for_gpr_multi_push_up_to_s1
, code_for_gpr_multi_pop_up_to_s1
,
6651 code_for_gpr_multi_popret_up_to_s1
, code_for_gpr_multi_popretz_up_to_s1
},
6652 {code_for_gpr_multi_push_up_to_s2
, code_for_gpr_multi_pop_up_to_s2
,
6653 code_for_gpr_multi_popret_up_to_s2
, code_for_gpr_multi_popretz_up_to_s2
},
6654 {code_for_gpr_multi_push_up_to_s3
, code_for_gpr_multi_pop_up_to_s3
,
6655 code_for_gpr_multi_popret_up_to_s3
, code_for_gpr_multi_popretz_up_to_s3
},
6656 {code_for_gpr_multi_push_up_to_s4
, code_for_gpr_multi_pop_up_to_s4
,
6657 code_for_gpr_multi_popret_up_to_s4
, code_for_gpr_multi_popretz_up_to_s4
},
6658 {code_for_gpr_multi_push_up_to_s5
, code_for_gpr_multi_pop_up_to_s5
,
6659 code_for_gpr_multi_popret_up_to_s5
, code_for_gpr_multi_popretz_up_to_s5
},
6660 {code_for_gpr_multi_push_up_to_s6
, code_for_gpr_multi_pop_up_to_s6
,
6661 code_for_gpr_multi_popret_up_to_s6
, code_for_gpr_multi_popretz_up_to_s6
},
6662 {code_for_gpr_multi_push_up_to_s7
, code_for_gpr_multi_pop_up_to_s7
,
6663 code_for_gpr_multi_popret_up_to_s7
, code_for_gpr_multi_popretz_up_to_s7
},
6664 {code_for_gpr_multi_push_up_to_s8
, code_for_gpr_multi_pop_up_to_s8
,
6665 code_for_gpr_multi_popret_up_to_s8
, code_for_gpr_multi_popretz_up_to_s8
},
6666 {code_for_gpr_multi_push_up_to_s9
, code_for_gpr_multi_pop_up_to_s9
,
6667 code_for_gpr_multi_popret_up_to_s9
, code_for_gpr_multi_popretz_up_to_s9
},
6668 {nullptr, nullptr, nullptr, nullptr},
6669 {code_for_gpr_multi_push_up_to_s11
, code_for_gpr_multi_pop_up_to_s11
,
6670 code_for_gpr_multi_popret_up_to_s11
,
6671 code_for_gpr_multi_popretz_up_to_s11
}};
6674 riscv_gen_multi_push_pop_insn (riscv_zcmp_op_t op
, HOST_WIDE_INT adj_size
,
6675 unsigned int regs_num
)
6677 gcc_assert (op
< ZCMP_OP_NUM
);
6678 gcc_assert (regs_num
<= ZCMP_MAX_GRP_SLOTS
6679 && regs_num
!= ZCMP_INVALID_S0S10_SREGS_COUNTS
+ 1); /* 1 for ra*/
6680 rtx stack_adj
= GEN_INT (adj_size
);
6681 return GEN_FCN (code_for_push_pop
[regs_num
- 1][op
](Pmode
)) (stack_adj
);
6685 get_multi_push_fpr_mask (unsigned max_fprs_push
)
6687 unsigned mask_fprs_push
= 0, num_f_pushed
= 0;
6688 for (unsigned regno
= FP_REG_FIRST
;
6689 regno
<= FP_REG_LAST
&& num_f_pushed
< max_fprs_push
; regno
++)
6690 if (riscv_save_reg_p (regno
))
6691 mask_fprs_push
|= 1 << (regno
- FP_REG_FIRST
), num_f_pushed
++;
6692 return mask_fprs_push
;
6695 /* Expand the "prologue" pattern. */
6698 riscv_expand_prologue (void)
6700 struct riscv_frame_info
*frame
= &cfun
->machine
->frame
;
6701 poly_int64 remaining_size
= frame
->total_size
;
6702 unsigned mask
= frame
->mask
;
6703 unsigned fmask
= frame
->fmask
;
6704 int spimm
, multi_push_additional
, stack_adj
;
6705 rtx insn
, dwarf
= NULL_RTX
;
6707 if (flag_stack_usage_info
)
6708 current_function_static_stack_size
= constant_lower_bound (remaining_size
);
6710 if (cfun
->machine
->naked_p
)
6713 /* prefer muti-push to save-restore libcall. */
6714 if (riscv_use_multi_push (frame
))
6716 remaining_size
-= frame
->multi_push_adj_base
;
6717 /* If there are vector registers that need to be saved, then it can only
6718 be reduced to the frame->v_sp_offset_top position at most, since the
6719 vector registers will need to be saved one by one by decreasing the SP
6721 poly_int64 remaining_size_above_varea
6723 ? remaining_size
- frame
->v_sp_offset_top
6726 if (known_gt (remaining_size_above_varea
, 2 * ZCMP_SP_INC_STEP
))
6728 else if (known_gt (remaining_size_above_varea
, ZCMP_SP_INC_STEP
))
6730 else if (known_gt (remaining_size_above_varea
, 0))
6734 multi_push_additional
= spimm
* ZCMP_SP_INC_STEP
;
6735 frame
->multi_push_adj_addi
= multi_push_additional
;
6736 remaining_size
-= multi_push_additional
;
6738 /* emit multi push insn & dwarf along with it. */
6739 stack_adj
= frame
->multi_push_adj_base
+ multi_push_additional
;
6740 insn
= emit_insn (riscv_gen_multi_push_pop_insn (
6741 PUSH_IDX
, -stack_adj
, riscv_multi_push_regs_count (frame
->mask
)));
6742 dwarf
= riscv_adjust_multi_push_cfi_prologue (stack_adj
);
6743 RTX_FRAME_RELATED_P (insn
) = 1;
6744 REG_NOTES (insn
) = dwarf
;
6746 /* Temporarily fib that we need not save GPRs. */
6749 /* push FPRs into the addtional reserved space by cm.push. */
6752 unsigned mask_fprs_push
6753 = get_multi_push_fpr_mask (multi_push_additional
/ UNITS_PER_WORD
);
6754 frame
->fmask
&= mask_fprs_push
;
6755 riscv_for_each_saved_reg (remaining_size
, riscv_save_reg
, false,
6757 frame
->fmask
= fmask
& ~mask_fprs_push
; /* mask for the rest FPRs. */
6760 /* When optimizing for size, call a subroutine to save the registers. */
6761 else if (riscv_use_save_libcall (frame
))
6763 rtx dwarf
= NULL_RTX
;
6764 dwarf
= riscv_adjust_libcall_cfi_prologue ();
6766 remaining_size
-= frame
->save_libcall_adjustment
;
6767 insn
= emit_insn (riscv_gen_gpr_save_insn (frame
));
6768 frame
->mask
= 0; /* Temporarily fib that we need not save GPRs. */
6770 RTX_FRAME_RELATED_P (insn
) = 1;
6771 REG_NOTES (insn
) = dwarf
;
6774 /* Save the GP, FP registers. */
6775 if ((frame
->mask
| frame
->fmask
) != 0)
6777 if (known_gt (remaining_size
, frame
->frame_pointer_offset
))
6779 HOST_WIDE_INT step1
= riscv_first_stack_step (frame
, remaining_size
);
6780 remaining_size
-= step1
;
6781 insn
= gen_add3_insn (stack_pointer_rtx
, stack_pointer_rtx
,
6783 RTX_FRAME_RELATED_P (emit_insn (insn
)) = 1;
6785 riscv_for_each_saved_reg (remaining_size
, riscv_save_reg
, false, false);
6788 /* Undo the above fib. */
6790 frame
->fmask
= fmask
;
6792 /* Set up the frame pointer, if we're using one. */
6793 if (frame_pointer_needed
)
6795 insn
= gen_add3_insn (hard_frame_pointer_rtx
, stack_pointer_rtx
,
6796 GEN_INT ((frame
->hard_frame_pointer_offset
- remaining_size
).to_constant ()));
6797 RTX_FRAME_RELATED_P (emit_insn (insn
)) = 1;
6799 riscv_emit_stack_tie ();
6802 /* Save the V registers. */
6803 if (frame
->vmask
!= 0)
6804 riscv_for_each_saved_v_reg (remaining_size
, riscv_save_reg
, true);
6806 /* Allocate the rest of the frame. */
6807 if (known_gt (remaining_size
, 0))
6809 /* Two step adjustment:
6810 1.scalable frame. 2.constant frame. */
6811 poly_int64
scalable_frame (0, 0);
6812 if (!remaining_size
.is_constant ())
6814 /* First for scalable frame. */
6815 poly_int64 scalable_frame
= remaining_size
;
6816 scalable_frame
.coeffs
[0] = remaining_size
.coeffs
[1];
6817 riscv_v_adjust_scalable_frame (stack_pointer_rtx
, scalable_frame
, false);
6818 remaining_size
-= scalable_frame
;
6821 /* Second step for constant frame. */
6822 HOST_WIDE_INT constant_frame
= remaining_size
.to_constant ();
6823 if (constant_frame
== 0)
6826 if (SMALL_OPERAND (-constant_frame
))
6828 insn
= gen_add3_insn (stack_pointer_rtx
, stack_pointer_rtx
,
6829 GEN_INT (-constant_frame
));
6830 RTX_FRAME_RELATED_P (emit_insn (insn
)) = 1;
6834 riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode
), GEN_INT (-constant_frame
));
6835 emit_insn (gen_add3_insn (stack_pointer_rtx
,
6837 RISCV_PROLOGUE_TEMP (Pmode
)));
6839 /* Describe the effect of the previous instructions. */
6840 insn
= plus_constant (Pmode
, stack_pointer_rtx
, -constant_frame
);
6841 insn
= gen_rtx_SET (stack_pointer_rtx
, insn
);
6842 riscv_set_frame_expr (insn
);
6848 riscv_adjust_multi_pop_cfi_epilogue (int saved_size
)
6850 rtx dwarf
= NULL_RTX
;
6851 rtx adjust_sp_rtx
, reg
;
6852 unsigned int mask
= cfun
->machine
->frame
.mask
;
6854 if (mask
& S10_MASK
)
6857 /* Debug info for adjust sp. */
6859 = gen_rtx_SET (stack_pointer_rtx
,
6860 plus_constant (Pmode
, stack_pointer_rtx
, saved_size
));
6861 dwarf
= alloc_reg_note (REG_CFA_ADJUST_CFA
, adjust_sp_rtx
, dwarf
);
6863 for (int regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
6864 if (BITSET_P (mask
, regno
- GP_REG_FIRST
))
6866 reg
= gen_rtx_REG (Pmode
, regno
);
6867 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
6874 riscv_adjust_libcall_cfi_epilogue ()
6876 rtx dwarf
= NULL_RTX
;
6877 rtx adjust_sp_rtx
, reg
;
6878 int saved_size
= cfun
->machine
->frame
.save_libcall_adjustment
;
6880 /* Debug info for adjust sp. */
6882 gen_rtx_SET (stack_pointer_rtx
,
6883 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
, GEN_INT (saved_size
)));
6884 dwarf
= alloc_reg_note (REG_CFA_ADJUST_CFA
, adjust_sp_rtx
,
6887 for (int regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
6888 if (BITSET_P (cfun
->machine
->frame
.mask
, regno
- GP_REG_FIRST
))
6890 reg
= gen_rtx_REG (Pmode
, regno
);
6891 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
6897 /* return true if popretz pattern can be matched.
6898 set (reg 10 a0) (const_int 0)
6900 NOTE_INSN_EPILOGUE_BEG */
6902 riscv_zcmp_can_use_popretz (void)
6904 rtx_insn
*insn
= NULL
, *use
= NULL
, *clear
= NULL
;
6906 /* sequence stack for NOTE_INSN_EPILOGUE_BEG*/
6907 struct sequence_stack
*outer_seq
= get_current_sequence ()->next
;
6910 insn
= outer_seq
->first
;
6911 if (!insn
|| !NOTE_P (insn
) || NOTE_KIND (insn
) != NOTE_INSN_EPILOGUE_BEG
)
6914 /* sequence stack for the insn before NOTE_INSN_EPILOGUE_BEG*/
6915 outer_seq
= outer_seq
->next
;
6917 insn
= outer_seq
->last
;
6920 while (insn
&& NOTE_P (insn
))
6922 insn
= PREV_INSN (insn
);
6926 /* match use (reg 10 a0) */
6927 if (use
== NULL
|| !INSN_P (use
) || GET_CODE (PATTERN (use
)) != USE
6928 || !REG_P (XEXP (PATTERN (use
), 0))
6929 || REGNO (XEXP (PATTERN (use
), 0)) != A0_REGNUM
)
6932 /* match set (reg 10 a0) (const_int 0 [0]) */
6933 clear
= PREV_INSN (use
);
6934 if (clear
!= NULL
&& INSN_P (clear
) && GET_CODE (PATTERN (clear
)) == SET
6935 && REG_P (SET_DEST (PATTERN (clear
)))
6936 && REGNO (SET_DEST (PATTERN (clear
))) == A0_REGNUM
6937 && SET_SRC (PATTERN (clear
)) == const0_rtx
)
6944 riscv_gen_multi_pop_insn (bool use_multi_pop_normal
, unsigned mask
,
6945 unsigned multipop_size
)
6948 unsigned regs_count
= riscv_multi_push_regs_count (mask
);
6950 if (!use_multi_pop_normal
)
6952 riscv_gen_multi_push_pop_insn (POP_IDX
, multipop_size
, regs_count
));
6953 else if (rtx_insn
*clear_a0_insn
= riscv_zcmp_can_use_popretz ())
6955 delete_insn (NEXT_INSN (clear_a0_insn
));
6956 delete_insn (clear_a0_insn
);
6957 insn
= emit_jump_insn (
6958 riscv_gen_multi_push_pop_insn (POPRETZ_IDX
, multipop_size
, regs_count
));
6961 insn
= emit_jump_insn (
6962 riscv_gen_multi_push_pop_insn (POPRET_IDX
, multipop_size
, regs_count
));
6964 rtx dwarf
= riscv_adjust_multi_pop_cfi_epilogue (multipop_size
);
6965 RTX_FRAME_RELATED_P (insn
) = 1;
6966 REG_NOTES (insn
) = dwarf
;
6969 /* Expand an "epilogue", "sibcall_epilogue", or "eh_return_internal" pattern;
6970 style says which. */
6973 riscv_expand_epilogue (int style
)
6975 /* Split the frame into 3 steps. STEP1 is the amount of stack we should
6976 deallocate before restoring the registers. STEP2 is the amount we
6977 should deallocate afterwards including the callee saved regs. STEP3
6978 is the amount deallocated by save-restore libcall.
6980 Start off by assuming that no registers need to be restored. */
6981 struct riscv_frame_info
*frame
= &cfun
->machine
->frame
;
6982 unsigned mask
= frame
->mask
;
6983 unsigned fmask
= frame
->fmask
;
6984 unsigned mask_fprs_push
= 0;
6985 poly_int64 step2
= 0;
6986 bool use_multi_pop_normal
6987 = ((style
== NORMAL_RETURN
) && riscv_use_multi_push (frame
));
6988 bool use_multi_pop_sibcall
6989 = ((style
== SIBCALL_RETURN
) && riscv_use_multi_push (frame
));
6990 bool use_multi_pop
= use_multi_pop_normal
|| use_multi_pop_sibcall
;
6992 bool use_restore_libcall
6994 && ((style
== NORMAL_RETURN
) && riscv_use_save_libcall (frame
));
6995 unsigned libcall_size
= use_restore_libcall
&& !use_multi_pop
6996 ? frame
->save_libcall_adjustment
6998 unsigned multipop_size
6999 = use_multi_pop
? frame
->multi_push_adj_base
+ frame
->multi_push_adj_addi
7001 rtx ra
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
7004 /* We need to add memory barrier to prevent read from deallocated stack. */
7005 bool need_barrier_p
= known_ne (get_frame_size ()
7006 + cfun
->machine
->frame
.arg_pointer_offset
, 0);
7008 if (cfun
->machine
->naked_p
)
7010 gcc_assert (style
== NORMAL_RETURN
);
7012 emit_jump_insn (gen_return ());
7017 if ((style
== NORMAL_RETURN
) && riscv_can_use_return_insn ())
7019 emit_jump_insn (gen_return ());
7023 /* Reset the epilogue cfa info before starting to emit the epilogue. */
7024 epilogue_cfa_sp_offset
= 0;
7026 /* Move past any dynamic stack allocations. */
7027 if (cfun
->calls_alloca
)
7029 /* Emit a barrier to prevent loads from a deallocated stack. */
7030 riscv_emit_stack_tie ();
7031 need_barrier_p
= false;
7033 poly_int64 adjust_offset
= -frame
->hard_frame_pointer_offset
;
7034 rtx adjust
= NULL_RTX
;
7036 if (!adjust_offset
.is_constant ())
7038 rtx tmp1
= RISCV_PROLOGUE_TEMP (Pmode
);
7039 rtx tmp2
= RISCV_PROLOGUE_TEMP2 (Pmode
);
7040 riscv_legitimize_poly_move (Pmode
, tmp1
, tmp2
,
7041 gen_int_mode (adjust_offset
, Pmode
));
7046 if (!SMALL_OPERAND (adjust_offset
.to_constant ()))
7048 riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode
),
7049 GEN_INT (adjust_offset
.to_constant ()));
7050 adjust
= RISCV_PROLOGUE_TEMP (Pmode
);
7053 adjust
= GEN_INT (adjust_offset
.to_constant ());
7057 gen_add3_insn (stack_pointer_rtx
, hard_frame_pointer_rtx
,
7060 rtx dwarf
= NULL_RTX
;
7061 rtx cfa_adjust_value
= gen_rtx_PLUS (
7062 Pmode
, hard_frame_pointer_rtx
,
7063 gen_int_mode (-frame
->hard_frame_pointer_offset
, Pmode
));
7064 rtx cfa_adjust_rtx
= gen_rtx_SET (stack_pointer_rtx
, cfa_adjust_value
);
7065 dwarf
= alloc_reg_note (REG_CFA_ADJUST_CFA
, cfa_adjust_rtx
, dwarf
);
7066 RTX_FRAME_RELATED_P (insn
) = 1;
7068 REG_NOTES (insn
) = dwarf
;
7071 if (use_restore_libcall
|| use_multi_pop
)
7072 frame
->mask
= 0; /* Temporarily fib that we need not restore GPRs. */
7074 /* If we need to restore registers, deallocate as much stack as
7075 possible in the second step without going out of range. */
7079 && known_gt (frame
->total_size
- multipop_size
,
7080 frame
->frame_pointer_offset
))
7082 = riscv_first_stack_step (frame
, frame
->total_size
- multipop_size
);
7084 else if ((frame
->mask
| frame
->fmask
) != 0)
7085 step2
= riscv_first_stack_step (frame
, frame
->total_size
- libcall_size
);
7087 if (use_restore_libcall
|| use_multi_pop
)
7088 frame
->mask
= mask
; /* Undo the above fib. */
7091 /* STEP1 must be set to the bottom of vector registers save area if any
7092 vector registers need be preversed. */
7093 if (frame
->vmask
!= 0)
7095 step1
= frame
->v_sp_offset_bottom
;
7096 step2
= frame
->total_size
- step1
- libcall_size
- multipop_size
;
7099 step1
= frame
->total_size
- step2
- libcall_size
- multipop_size
;
7101 /* Set TARGET to BASE + STEP1. */
7102 if (known_gt (step1
, 0))
7104 /* Emit a barrier to prevent loads from a deallocated stack. */
7105 riscv_emit_stack_tie ();
7106 need_barrier_p
= false;
7108 /* Restore the scalable frame which is assigned in prologue. */
7109 if (!step1
.is_constant ())
7111 poly_int64 scalable_frame
= step1
;
7112 scalable_frame
.coeffs
[0] = step1
.coeffs
[1];
7113 riscv_v_adjust_scalable_frame (stack_pointer_rtx
, scalable_frame
,
7115 step1
-= scalable_frame
;
7118 /* Get an rtx for STEP1 that we can add to BASE.
7119 Skip if adjust equal to zero. */
7120 if (step1
.to_constant () != 0)
7122 rtx adjust
= GEN_INT (step1
.to_constant ());
7123 if (!SMALL_OPERAND (step1
.to_constant ()))
7125 riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode
), adjust
);
7126 adjust
= RISCV_PROLOGUE_TEMP (Pmode
);
7129 insn
= emit_insn (gen_add3_insn (stack_pointer_rtx
,
7132 rtx dwarf
= NULL_RTX
;
7134 = gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
7135 gen_int_mode (step2
+ libcall_size
+ multipop_size
,
7138 dwarf
= alloc_reg_note (REG_CFA_DEF_CFA
, cfa_adjust_rtx
, dwarf
);
7139 RTX_FRAME_RELATED_P (insn
) = 1;
7141 REG_NOTES (insn
) = dwarf
;
7144 else if (frame_pointer_needed
)
7146 /* Tell riscv_restore_reg to emit dwarf to redefine CFA when restoring
7148 epilogue_cfa_sp_offset
= step2
;
7153 frame
->mask
= 0; /* Temporarily fib that we need not restore GPRs. */
7156 mask_fprs_push
= get_multi_push_fpr_mask (frame
->multi_push_adj_addi
7158 frame
->fmask
&= ~mask_fprs_push
; /* FPRs not saved by cm.push */
7161 else if (use_restore_libcall
)
7162 frame
->mask
= 0; /* Temporarily fib that we need not restore GPRs. */
7164 /* Restore the registers. */
7165 riscv_for_each_saved_v_reg (step2
, riscv_restore_reg
, false);
7166 riscv_for_each_saved_reg (frame
->total_size
- step2
- libcall_size
7168 riscv_restore_reg
, true, style
== EXCEPTION_RETURN
);
7170 if (use_restore_libcall
)
7171 frame
->mask
= mask
; /* Undo the above fib. */
7174 riscv_emit_stack_tie ();
7176 /* Deallocate the final bit of the frame. */
7177 if (step2
.to_constant () > 0)
7179 insn
= emit_insn (gen_add3_insn (stack_pointer_rtx
, stack_pointer_rtx
,
7180 GEN_INT (step2
.to_constant ())));
7182 rtx dwarf
= NULL_RTX
;
7184 = gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
7185 GEN_INT (libcall_size
+ multipop_size
));
7186 dwarf
= alloc_reg_note (REG_CFA_DEF_CFA
, cfa_adjust_rtx
, dwarf
);
7187 RTX_FRAME_RELATED_P (insn
) = 1;
7189 REG_NOTES (insn
) = dwarf
;
7194 /* restore FPRs pushed by cm.push. */
7195 frame
->fmask
= fmask
& mask_fprs_push
;
7197 riscv_for_each_saved_reg (frame
->total_size
- libcall_size
7199 riscv_restore_reg
, true,
7200 style
== EXCEPTION_RETURN
);
7201 /* Undo the above fib. */
7203 frame
->fmask
= fmask
;
7204 riscv_gen_multi_pop_insn (use_multi_pop_normal
, frame
->mask
,
7206 if (use_multi_pop_normal
)
7209 else if (use_restore_libcall
)
7211 rtx dwarf
= riscv_adjust_libcall_cfi_epilogue ();
7212 insn
= emit_insn (gen_gpr_restore (GEN_INT (riscv_save_libcall_count (mask
))));
7213 RTX_FRAME_RELATED_P (insn
) = 1;
7214 REG_NOTES (insn
) = dwarf
;
7216 emit_jump_insn (gen_gpr_restore_return (ra
));
7220 /* Add in the __builtin_eh_return stack adjustment. */
7221 if ((style
== EXCEPTION_RETURN
) && crtl
->calls_eh_return
)
7222 emit_insn (gen_add3_insn (stack_pointer_rtx
, stack_pointer_rtx
,
7223 EH_RETURN_STACKADJ_RTX
));
7225 /* Return from interrupt. */
7226 if (cfun
->machine
->interrupt_handler_p
)
7228 enum riscv_privilege_levels mode
= cfun
->machine
->interrupt_mode
;
7230 gcc_assert (mode
!= UNKNOWN_MODE
);
7232 if (mode
== MACHINE_MODE
)
7233 emit_jump_insn (gen_riscv_mret ());
7234 else if (mode
== SUPERVISOR_MODE
)
7235 emit_jump_insn (gen_riscv_sret ());
7237 emit_jump_insn (gen_riscv_uret ());
7239 else if (style
!= SIBCALL_RETURN
)
7240 emit_jump_insn (gen_simple_return_internal (ra
));
7243 /* Implement EPILOGUE_USES. */
7246 riscv_epilogue_uses (unsigned int regno
)
7248 if (regno
== RETURN_ADDR_REGNUM
)
7251 if (epilogue_completed
&& cfun
->machine
->interrupt_handler_p
)
7253 /* An interrupt function restores temp regs, so we must indicate that
7254 they are live at function end. */
7255 if (df_regs_ever_live_p (regno
)
7256 || (!crtl
->is_leaf
&& call_used_or_fixed_reg_p (regno
)))
7264 riscv_avoid_shrink_wrapping_separate ()
7266 if (riscv_use_save_libcall (&cfun
->machine
->frame
)
7267 || cfun
->machine
->interrupt_handler_p
7268 || !cfun
->machine
->frame
.gp_sp_offset
.is_constant ())
7274 /* Implement TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS. */
7277 riscv_get_separate_components (void)
7279 HOST_WIDE_INT offset
;
7280 sbitmap components
= sbitmap_alloc (FIRST_PSEUDO_REGISTER
);
7281 bitmap_clear (components
);
7283 if (riscv_avoid_shrink_wrapping_separate ())
7286 offset
= cfun
->machine
->frame
.gp_sp_offset
.to_constant ();
7287 for (unsigned int regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
7288 if (BITSET_P (cfun
->machine
->frame
.mask
, regno
- GP_REG_FIRST
))
7290 /* We can only wrap registers that have small operand offsets.
7291 For large offsets a pseudo register might be needed which
7292 cannot be created during the shrink wrapping pass. */
7293 if (SMALL_OPERAND (offset
))
7294 bitmap_set_bit (components
, regno
);
7296 offset
-= UNITS_PER_WORD
;
7299 offset
= cfun
->machine
->frame
.fp_sp_offset
.to_constant ();
7300 for (unsigned int regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
++)
7301 if (BITSET_P (cfun
->machine
->frame
.fmask
, regno
- FP_REG_FIRST
))
7303 machine_mode mode
= TARGET_DOUBLE_FLOAT
? DFmode
: SFmode
;
7305 /* We can only wrap registers that have small operand offsets.
7306 For large offsets a pseudo register might be needed which
7307 cannot be created during the shrink wrapping pass. */
7308 if (SMALL_OPERAND (offset
))
7309 bitmap_set_bit (components
, regno
);
7311 offset
-= GET_MODE_SIZE (mode
).to_constant ();
7314 /* Don't mess with the hard frame pointer. */
7315 if (frame_pointer_needed
)
7316 bitmap_clear_bit (components
, HARD_FRAME_POINTER_REGNUM
);
7318 bitmap_clear_bit (components
, RETURN_ADDR_REGNUM
);
7323 /* Implement TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB. */
7326 riscv_components_for_bb (basic_block bb
)
7328 bitmap in
= DF_LIVE_IN (bb
);
7329 bitmap gen
= &DF_LIVE_BB_INFO (bb
)->gen
;
7330 bitmap kill
= &DF_LIVE_BB_INFO (bb
)->kill
;
7332 sbitmap components
= sbitmap_alloc (FIRST_PSEUDO_REGISTER
);
7333 bitmap_clear (components
);
7335 function_abi_aggregator callee_abis
;
7337 FOR_BB_INSNS (bb
, insn
)
7339 callee_abis
.note_callee_abi (insn_callee_abi (insn
));
7340 HARD_REG_SET extra_caller_saves
= callee_abis
.caller_save_regs (*crtl
->abi
);
7342 /* GPRs are used in a bb if they are in the IN, GEN, or KILL sets. */
7343 for (unsigned int regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
7344 if (!fixed_regs
[regno
]
7345 && !crtl
->abi
->clobbers_full_reg_p (regno
)
7346 && (TEST_HARD_REG_BIT (extra_caller_saves
, regno
)
7347 || bitmap_bit_p (in
, regno
)
7348 || bitmap_bit_p (gen
, regno
)
7349 || bitmap_bit_p (kill
, regno
)))
7350 bitmap_set_bit (components
, regno
);
7352 for (unsigned int regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
++)
7353 if (!fixed_regs
[regno
]
7354 && !crtl
->abi
->clobbers_full_reg_p (regno
)
7355 && (TEST_HARD_REG_BIT (extra_caller_saves
, regno
)
7356 || bitmap_bit_p (in
, regno
)
7357 || bitmap_bit_p (gen
, regno
)
7358 || bitmap_bit_p (kill
, regno
)))
7359 bitmap_set_bit (components
, regno
);
7364 /* Implement TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS. */
7367 riscv_disqualify_components (sbitmap
, edge
, sbitmap
, bool)
7369 /* Nothing to do for riscv. */
7373 riscv_process_components (sbitmap components
, bool prologue_p
)
7375 HOST_WIDE_INT offset
;
7376 riscv_save_restore_fn fn
= prologue_p
? riscv_save_reg
: riscv_restore_reg
;
7378 offset
= cfun
->machine
->frame
.gp_sp_offset
.to_constant ();
7379 for (unsigned int regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
7380 if (BITSET_P (cfun
->machine
->frame
.mask
, regno
- GP_REG_FIRST
))
7382 if (bitmap_bit_p (components
, regno
))
7383 riscv_save_restore_reg (word_mode
, regno
, offset
, fn
);
7385 offset
-= UNITS_PER_WORD
;
7388 offset
= cfun
->machine
->frame
.fp_sp_offset
.to_constant ();
7389 for (unsigned int regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
++)
7390 if (BITSET_P (cfun
->machine
->frame
.fmask
, regno
- FP_REG_FIRST
))
7392 machine_mode mode
= TARGET_DOUBLE_FLOAT
? DFmode
: SFmode
;
7394 if (bitmap_bit_p (components
, regno
))
7395 riscv_save_restore_reg (mode
, regno
, offset
, fn
);
7397 offset
-= GET_MODE_SIZE (mode
).to_constant ();
7401 /* Implement TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS. */
7404 riscv_emit_prologue_components (sbitmap components
)
7406 riscv_process_components (components
, true);
7409 /* Implement TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS. */
7412 riscv_emit_epilogue_components (sbitmap components
)
7414 riscv_process_components (components
, false);
7418 riscv_set_handled_components (sbitmap components
)
7420 for (unsigned int regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
7421 if (bitmap_bit_p (components
, regno
))
7422 cfun
->machine
->reg_is_wrapped_separately
[regno
] = true;
7424 for (unsigned int regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
++)
7425 if (bitmap_bit_p (components
, regno
))
7426 cfun
->machine
->reg_is_wrapped_separately
[regno
] = true;
7429 /* Return nonzero if this function is known to have a null epilogue.
7430 This allows the optimizer to omit jumps to jumps if no stack
7434 riscv_can_use_return_insn (void)
7436 return (reload_completed
&& known_eq (cfun
->machine
->frame
.total_size
, 0)
7437 && ! cfun
->machine
->interrupt_handler_p
);
7440 /* Given that there exists at least one variable that is set (produced)
7441 by OUT_INSN and read (consumed) by IN_INSN, return true iff
7442 IN_INSN represents one or more memory store operations and none of
7443 the variables set by OUT_INSN is used by IN_INSN as the address of a
7444 store operation. If either IN_INSN or OUT_INSN does not represent
7445 a "single" RTL SET expression (as loosely defined by the
7446 implementation of the single_set function) or a PARALLEL with only
7447 SETs, CLOBBERs, and USEs inside, this function returns false.
7449 Borrowed from rs6000, riscv_store_data_bypass_p checks for certain
7450 conditions that result in assertion failures in the generic
7451 store_data_bypass_p function and returns FALSE in such cases.
7453 This is required to make -msave-restore work with the sifive-7
7454 pipeline description. */
7457 riscv_store_data_bypass_p (rtx_insn
*out_insn
, rtx_insn
*in_insn
)
7459 rtx out_set
, in_set
;
7460 rtx out_pat
, in_pat
;
7461 rtx out_exp
, in_exp
;
7464 in_set
= single_set (in_insn
);
7467 if (MEM_P (SET_DEST (in_set
)))
7469 out_set
= single_set (out_insn
);
7472 out_pat
= PATTERN (out_insn
);
7473 if (GET_CODE (out_pat
) == PARALLEL
)
7475 for (i
= 0; i
< XVECLEN (out_pat
, 0); i
++)
7477 out_exp
= XVECEXP (out_pat
, 0, i
);
7478 if ((GET_CODE (out_exp
) == CLOBBER
)
7479 || (GET_CODE (out_exp
) == USE
))
7481 else if (GET_CODE (out_exp
) != SET
)
7490 in_pat
= PATTERN (in_insn
);
7491 if (GET_CODE (in_pat
) != PARALLEL
)
7494 for (i
= 0; i
< XVECLEN (in_pat
, 0); i
++)
7496 in_exp
= XVECEXP (in_pat
, 0, i
);
7497 if ((GET_CODE (in_exp
) == CLOBBER
) || (GET_CODE (in_exp
) == USE
))
7499 else if (GET_CODE (in_exp
) != SET
)
7502 if (MEM_P (SET_DEST (in_exp
)))
7504 out_set
= single_set (out_insn
);
7507 out_pat
= PATTERN (out_insn
);
7508 if (GET_CODE (out_pat
) != PARALLEL
)
7510 for (j
= 0; j
< XVECLEN (out_pat
, 0); j
++)
7512 out_exp
= XVECEXP (out_pat
, 0, j
);
7513 if ((GET_CODE (out_exp
) == CLOBBER
)
7514 || (GET_CODE (out_exp
) == USE
))
7516 else if (GET_CODE (out_exp
) != SET
)
7524 return store_data_bypass_p (out_insn
, in_insn
);
7527 /* Implement TARGET_SECONDARY_MEMORY_NEEDED.
7529 When floating-point registers are wider than integer ones, moves between
7530 them must go through memory. */
7533 riscv_secondary_memory_needed (machine_mode mode
, reg_class_t class1
,
7536 return (!riscv_v_ext_mode_p (mode
)
7537 && GET_MODE_SIZE (mode
).to_constant () > UNITS_PER_WORD
7538 && (class1
== FP_REGS
) != (class2
== FP_REGS
)
7539 && !TARGET_XTHEADFMV
7543 /* Implement TARGET_REGISTER_MOVE_COST. */
7546 riscv_register_move_cost (machine_mode mode
,
7547 reg_class_t from
, reg_class_t to
)
7549 if ((from
== FP_REGS
&& to
== GR_REGS
) ||
7550 (from
== GR_REGS
&& to
== FP_REGS
))
7551 return tune_param
->fmv_cost
;
7553 return riscv_secondary_memory_needed (mode
, from
, to
) ? 8 : 2;
7556 /* Implement TARGET_HARD_REGNO_NREGS. */
7559 riscv_hard_regno_nregs (unsigned int regno
, machine_mode mode
)
7561 if (riscv_v_ext_vector_mode_p (mode
))
7563 /* Handle fractional LMUL, it only occupy part of vector register but
7564 still need one vector register to hold. */
7565 if (maybe_lt (GET_MODE_SIZE (mode
), UNITS_PER_V_REG
))
7568 return exact_div (GET_MODE_SIZE (mode
), UNITS_PER_V_REG
).to_constant ();
7571 /* For tuple modes, the number of register = NF * LMUL. */
7572 if (riscv_v_ext_tuple_mode_p (mode
))
7574 unsigned int nf
= riscv_vector::get_nf (mode
);
7575 machine_mode subpart_mode
= riscv_vector::get_subpart_mode (mode
);
7576 poly_int64 size
= GET_MODE_SIZE (subpart_mode
);
7577 gcc_assert (known_eq (size
* nf
, GET_MODE_SIZE (mode
)));
7578 if (maybe_lt (size
, UNITS_PER_V_REG
))
7582 unsigned int lmul
= exact_div (size
, UNITS_PER_V_REG
).to_constant ();
7587 /* For VLS modes, we allocate registers according to TARGET_MIN_VLEN. */
7588 if (riscv_v_ext_vls_mode_p (mode
))
7590 int size
= GET_MODE_BITSIZE (mode
).to_constant ();
7591 if (size
< TARGET_MIN_VLEN
)
7594 return size
/ TARGET_MIN_VLEN
;
7597 /* mode for VL or VTYPE are just a marker, not holding value,
7598 so it always consume one register. */
7599 if (VTYPE_REG_P (regno
) || VL_REG_P (regno
) || VXRM_REG_P (regno
)
7600 || FRM_REG_P (regno
))
7603 /* Assume every valid non-vector mode fits in one vector register. */
7604 if (V_REG_P (regno
))
7607 if (FP_REG_P (regno
))
7608 return (GET_MODE_SIZE (mode
).to_constant () + UNITS_PER_FP_REG
- 1) / UNITS_PER_FP_REG
;
7610 /* All other registers are word-sized. */
7611 return (GET_MODE_SIZE (mode
).to_constant () + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
7614 /* Implement TARGET_HARD_REGNO_MODE_OK. */
7617 riscv_hard_regno_mode_ok (unsigned int regno
, machine_mode mode
)
7619 unsigned int nregs
= riscv_hard_regno_nregs (regno
, mode
);
7621 if (GP_REG_P (regno
))
7623 if (riscv_v_ext_mode_p (mode
))
7626 if (!GP_REG_P (regno
+ nregs
- 1))
7629 else if (FP_REG_P (regno
))
7631 if (riscv_v_ext_mode_p (mode
))
7634 if (!FP_REG_P (regno
+ nregs
- 1))
7637 if (GET_MODE_CLASS (mode
) != MODE_FLOAT
7638 && GET_MODE_CLASS (mode
) != MODE_COMPLEX_FLOAT
)
7641 /* Only use callee-saved registers if a potential callee is guaranteed
7642 to spill the requisite width. */
7643 if (GET_MODE_UNIT_SIZE (mode
) > UNITS_PER_FP_REG
7644 || (!call_used_or_fixed_reg_p (regno
)
7645 && GET_MODE_UNIT_SIZE (mode
) > UNITS_PER_FP_ARG
))
7648 else if (V_REG_P (regno
))
7650 if (!riscv_v_ext_mode_p (mode
))
7653 if (!V_REG_P (regno
+ nregs
- 1))
7656 int regno_alignment
= riscv_get_v_regno_alignment (mode
);
7657 if (regno_alignment
!= 1)
7658 return ((regno
% regno_alignment
) == 0);
7660 else if (VTYPE_REG_P (regno
) || VL_REG_P (regno
) || VXRM_REG_P (regno
)
7661 || FRM_REG_P (regno
))
7666 /* Require same callee-savedness for all registers. */
7667 for (unsigned i
= 1; i
< nregs
; i
++)
7668 if (call_used_or_fixed_reg_p (regno
)
7669 != call_used_or_fixed_reg_p (regno
+ i
))
7672 /* Only use even registers in RV32 ZDINX */
7673 if (!TARGET_64BIT
&& TARGET_ZDINX
){
7674 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
&&
7675 GET_MODE_UNIT_SIZE (mode
) == GET_MODE_SIZE (DFmode
))
7676 return !(regno
& 1);
7682 /* Implement TARGET_MODES_TIEABLE_P.
7684 Don't allow floating-point modes to be tied, since type punning of
7685 single-precision and double-precision is implementation defined. */
7688 riscv_modes_tieable_p (machine_mode mode1
, machine_mode mode2
)
7690 /* We don't allow different REG_CLASS modes tieable since it
7691 will cause ICE in register allocation (RA).
7692 E.g. V2SI and DI are not tieable. */
7693 if (riscv_v_ext_mode_p (mode1
) != riscv_v_ext_mode_p (mode2
))
7695 return (mode1
== mode2
7696 || !(GET_MODE_CLASS (mode1
) == MODE_FLOAT
7697 && GET_MODE_CLASS (mode2
) == MODE_FLOAT
));
7700 /* Implement CLASS_MAX_NREGS. */
7702 static unsigned char
7703 riscv_class_max_nregs (reg_class_t rclass
, machine_mode mode
)
7705 if (reg_class_subset_p (rclass
, FP_REGS
))
7706 return riscv_hard_regno_nregs (FP_REG_FIRST
, mode
);
7708 if (reg_class_subset_p (rclass
, GR_REGS
))
7709 return riscv_hard_regno_nregs (GP_REG_FIRST
, mode
);
7711 if (reg_class_subset_p (rclass
, V_REGS
))
7712 return riscv_hard_regno_nregs (V_REG_FIRST
, mode
);
7717 /* Implement TARGET_MEMORY_MOVE_COST. */
7720 riscv_memory_move_cost (machine_mode mode
, reg_class_t rclass
, bool in
)
7722 return (tune_param
->memory_cost
7723 + memory_move_secondary_cost (mode
, rclass
, in
));
7726 /* Return the number of instructions that can be issued per cycle. */
7729 riscv_issue_rate (void)
7731 return tune_param
->issue_rate
;
7734 /* Implement TARGET_SCHED_VARIABLE_ISSUE. */
7736 riscv_sched_variable_issue (FILE *, int, rtx_insn
*insn
, int more
)
7738 if (DEBUG_INSN_P (insn
))
7741 rtx_code code
= GET_CODE (PATTERN (insn
));
7742 if (code
== USE
|| code
== CLOBBER
)
7745 /* GHOST insns are used for blockage and similar cases which
7746 effectively end a cycle. */
7747 if (get_attr_type (insn
) == TYPE_GHOST
)
7750 /* If we ever encounter an insn with an unknown type, trip
7751 an assert so we can find and fix this problem. */
7752 gcc_assert (get_attr_type (insn
) != TYPE_UNKNOWN
);
7757 /* Adjust the cost/latency of instructions for scheduling.
7758 For now this is just used to change the latency of vector instructions
7759 according to their LMUL. We assume that an insn with LMUL == 8 requires
7760 eight times more execution cycles than the same insn with LMUL == 1.
7761 As this may cause very high latencies which lead to scheduling artifacts
7762 we currently only perform the adjustment when -madjust-lmul-cost is given.
7765 riscv_sched_adjust_cost (rtx_insn
*, int, rtx_insn
*insn
, int cost
,
7768 /* Only do adjustments for the generic out-of-order scheduling model. */
7769 if (!TARGET_VECTOR
|| riscv_microarchitecture
!= generic_ooo
)
7772 if (recog_memoized (insn
) < 0)
7775 enum attr_type type
= get_attr_type (insn
);
7777 if (type
== TYPE_VFREDO
|| type
== TYPE_VFWREDO
)
7779 /* TODO: For ordered reductions scale the base cost relative to the
7784 /* Don't do any LMUL-based latency adjustment unless explicitly asked to. */
7785 if (!TARGET_ADJUST_LMUL_COST
)
7788 /* vsetvl has a vlmul attribute but its latency does not depend on it. */
7789 if (type
== TYPE_VSETVL
|| type
== TYPE_VSETVL_PRE
)
7792 enum riscv_vector::vlmul_type lmul
=
7793 (riscv_vector::vlmul_type
)get_attr_vlmul (insn
);
7798 case riscv_vector::LMUL_2
:
7801 case riscv_vector::LMUL_4
:
7804 case riscv_vector::LMUL_8
:
7807 case riscv_vector::LMUL_F2
:
7810 case riscv_vector::LMUL_F4
:
7813 case riscv_vector::LMUL_F8
:
7820 /* If the latency was nonzero, keep it that way. */
7821 int new_cost
= MAX (cost
> 0 ? 1 : 0, cost
* factor
);
7826 /* Auxiliary function to emit RISC-V ELF attribute. */
7828 riscv_emit_attribute ()
7830 fprintf (asm_out_file
, "\t.attribute arch, \"%s\"\n",
7831 riscv_arch_str ().c_str ());
7833 fprintf (asm_out_file
, "\t.attribute unaligned_access, %d\n",
7834 TARGET_STRICT_ALIGN
? 0 : 1);
7836 fprintf (asm_out_file
, "\t.attribute stack_align, %d\n",
7837 riscv_stack_boundary
/ 8);
7840 /* Output .variant_cc for function symbol which follows vector calling
7844 riscv_asm_output_variant_cc (FILE *stream
, const tree decl
, const char *name
)
7846 if (TREE_CODE (decl
) == FUNCTION_DECL
)
7848 riscv_cc cc
= (riscv_cc
) fndecl_abi (decl
).id ();
7849 if (cc
== RISCV_CC_V
)
7851 fprintf (stream
, "\t.variant_cc\t");
7852 assemble_name (stream
, name
);
7853 fprintf (stream
, "\n");
7858 /* Implement ASM_DECLARE_FUNCTION_NAME. */
7861 riscv_declare_function_name (FILE *stream
, const char *name
, tree fndecl
)
7863 riscv_asm_output_variant_cc (stream
, fndecl
, name
);
7864 ASM_OUTPUT_TYPE_DIRECTIVE (stream
, name
, "function");
7865 ASM_OUTPUT_LABEL (stream
, name
);
7868 /* Implement ASM_OUTPUT_DEF_FROM_DECLS. */
7871 riscv_asm_output_alias (FILE *stream
, const tree decl
, const tree target
)
7873 const char *name
= XSTR (XEXP (DECL_RTL (decl
), 0), 0);
7874 const char *value
= IDENTIFIER_POINTER (target
);
7875 riscv_asm_output_variant_cc (stream
, decl
, name
);
7876 ASM_OUTPUT_DEF (stream
, name
, value
);
7879 /* Implement ASM_OUTPUT_EXTERNAL. */
7882 riscv_asm_output_external (FILE *stream
, tree decl
, const char *name
)
7884 default_elf_asm_output_external (stream
, decl
, name
);
7885 riscv_asm_output_variant_cc (stream
, decl
, name
);
7888 /* Implement TARGET_ASM_FILE_START. */
7891 riscv_file_start (void)
7893 default_file_start ();
7895 /* Instruct GAS to generate position-[in]dependent code. */
7896 fprintf (asm_out_file
, "\t.option %spic\n", (flag_pic
? "" : "no"));
7898 /* If the user specifies "-mno-relax" on the command line then disable linker
7899 relaxation in the assembler. */
7901 fprintf (asm_out_file
, "\t.option norelax\n");
7903 /* If the user specifies "-mcsr-check" on the command line then enable csr
7904 check in the assembler. */
7905 if (riscv_mcsr_check
)
7906 fprintf (asm_out_file
, "\t.option csr-check\n");
7908 if (riscv_emit_attribute_p
)
7909 riscv_emit_attribute ();
7912 /* Implement TARGET_ASM_OUTPUT_MI_THUNK. Generate rtl rather than asm text
7913 in order to avoid duplicating too much logic from elsewhere. */
7916 riscv_output_mi_thunk (FILE *file
, tree thunk_fndecl ATTRIBUTE_UNUSED
,
7917 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
7920 const char *fnname
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl
));
7921 rtx this_rtx
, temp1
, temp2
, fnaddr
;
7924 /* Pretend to be a post-reload pass while generating rtl. */
7925 reload_completed
= 1;
7927 /* Mark the end of the (empty) prologue. */
7928 emit_note (NOTE_INSN_PROLOGUE_END
);
7930 /* Determine if we can use a sibcall to call FUNCTION directly. */
7931 fnaddr
= gen_rtx_MEM (FUNCTION_MODE
, XEXP (DECL_RTL (function
), 0));
7933 /* We need two temporary registers in some cases. */
7934 temp1
= gen_rtx_REG (Pmode
, RISCV_PROLOGUE_TEMP_REGNUM
);
7935 temp2
= gen_rtx_REG (Pmode
, STATIC_CHAIN_REGNUM
);
7937 /* Find out which register contains the "this" pointer. */
7938 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
7939 this_rtx
= gen_rtx_REG (Pmode
, GP_ARG_FIRST
+ 1);
7941 this_rtx
= gen_rtx_REG (Pmode
, GP_ARG_FIRST
);
7943 /* Add DELTA to THIS_RTX. */
7946 rtx offset
= GEN_INT (delta
);
7947 if (!SMALL_OPERAND (delta
))
7949 riscv_emit_move (temp1
, offset
);
7952 emit_insn (gen_add3_insn (this_rtx
, this_rtx
, offset
));
7955 /* If needed, add *(*THIS_RTX + VCALL_OFFSET) to THIS_RTX. */
7956 if (vcall_offset
!= 0)
7960 /* Set TEMP1 to *THIS_RTX. */
7961 riscv_emit_move (temp1
, gen_rtx_MEM (Pmode
, this_rtx
));
7963 /* Set ADDR to a legitimate address for *THIS_RTX + VCALL_OFFSET. */
7964 addr
= riscv_add_offset (temp2
, temp1
, vcall_offset
);
7966 /* Load the offset and add it to THIS_RTX. */
7967 riscv_emit_move (temp1
, gen_rtx_MEM (Pmode
, addr
));
7968 emit_insn (gen_add3_insn (this_rtx
, this_rtx
, temp1
));
7971 /* Jump to the target function. */
7972 rtx callee_cc
= gen_int_mode (fndecl_abi (function
).id (), SImode
);
7973 insn
= emit_call_insn (gen_sibcall (fnaddr
, const0_rtx
, callee_cc
));
7974 SIBLING_CALL_P (insn
) = 1;
7976 /* Run just enough of rest_of_compilation. This sequence was
7977 "borrowed" from alpha.cc. */
7978 insn
= get_insns ();
7979 split_all_insns_noflow ();
7980 shorten_branches (insn
);
7981 assemble_start_function (thunk_fndecl
, fnname
);
7982 final_start_function (insn
, file
, 1);
7983 final (insn
, file
, 1);
7984 final_end_function ();
7985 assemble_end_function (thunk_fndecl
, fnname
);
7987 /* Clean up the vars set above. Note that final_end_function resets
7988 the global pointer for us. */
7989 reload_completed
= 0;
7992 /* Allocate a chunk of memory for per-function machine-dependent data. */
7994 static struct machine_function
*
7995 riscv_init_machine_status (void)
7997 return ggc_cleared_alloc
<machine_function
> ();
8000 /* Return the VLEN value associated with -march.
8001 TODO: So far we only support length-agnostic value. */
8003 riscv_convert_vector_bits (struct gcc_options
*opts
)
8006 int min_vlen
= TARGET_MIN_VLEN_OPTS (opts
);
8009 /* When targetting minimum VLEN > 32, we should use 64-bit chunk size.
8010 Otherwise we can not include SEW = 64bits.
8011 Runtime invariant: The single indeterminate represent the
8012 number of 64-bit chunks in a vector beyond minimum length of 64 bits.
8013 Thus the number of bytes in a vector is 8 + 8 * x1 which is
8014 riscv_vector_chunks * 8 = poly_int (8, 8). */
8015 riscv_bytes_per_vector_chunk
= 8;
8016 /* Adjust BYTES_PER_RISCV_VECTOR according to TARGET_MIN_VLEN:
8017 - TARGET_MIN_VLEN = 64bit: [8,8]
8018 - TARGET_MIN_VLEN = 128bit: [16,16]
8019 - TARGET_MIN_VLEN = 256bit: [32,32]
8020 - TARGET_MIN_VLEN = 512bit: [64,64]
8021 - TARGET_MIN_VLEN = 1024bit: [128,128]
8022 - TARGET_MIN_VLEN = 2048bit: [256,256]
8023 - TARGET_MIN_VLEN = 4096bit: [512,512]
8024 FIXME: We currently DON'T support TARGET_MIN_VLEN > 4096bit. */
8025 chunk_num
= min_vlen
/ 64;
8029 /* When targetting minimum VLEN = 32, we should use 32-bit
8030 chunk size. Runtime invariant: The single indeterminate represent the
8031 number of 32-bit chunks in a vector beyond minimum length of 32 bits.
8032 Thus the number of bytes in a vector is 4 + 4 * x1 which is
8033 riscv_vector_chunks * 4 = poly_int (4, 4). */
8034 riscv_bytes_per_vector_chunk
= 4;
8038 /* Set riscv_vector_chunks as poly (1, 1) run-time constant if TARGET_VECTOR
8039 is enabled. Set riscv_vector_chunks as 1 compile-time constant if
8040 TARGET_VECTOR is disabled. riscv_vector_chunks is used in "riscv-modes.def"
8041 to set RVV mode size. The RVV machine modes size are run-time constant if
8042 TARGET_VECTOR is enabled. The RVV machine modes size remains default
8043 compile-time constant if TARGET_VECTOR is disabled. */
8044 if (TARGET_VECTOR_OPTS_P (opts
))
8046 if (opts
->x_riscv_autovec_preference
== RVV_FIXED_VLMAX
)
8047 return (int) min_vlen
/ (riscv_bytes_per_vector_chunk
* 8);
8049 return poly_uint16 (chunk_num
, chunk_num
);
8055 /* 'Unpack' up the internal tuning structs and update the options
8056 in OPTS. The caller must have set up selected_tune and selected_arch
8057 as all the other target-specific codegen decisions are
8058 derived from them. */
8060 riscv_override_options_internal (struct gcc_options
*opts
)
8062 const struct riscv_tune_info
*cpu
;
8064 /* The presence of the M extension implies that division instructions
8065 are present, so include them unless explicitly disabled. */
8066 if (TARGET_MUL_OPTS_P (opts
) && (target_flags_explicit
& MASK_DIV
) == 0)
8067 opts
->x_target_flags
|= MASK_DIV
;
8068 else if (!TARGET_MUL_OPTS_P (opts
) && TARGET_DIV_OPTS_P (opts
))
8069 error ("%<-mdiv%> requires %<-march%> to subsume the %<M%> extension");
8071 /* Likewise floating-point division and square root. */
8072 if ((TARGET_HARD_FLOAT
|| TARGET_ZFINX
) && (target_flags_explicit
& MASK_FDIV
) == 0)
8073 opts
->x_target_flags
|= MASK_FDIV
;
8075 /* Handle -mtune, use -mcpu if -mtune is not given, and use default -mtune
8076 if both -mtune and -mcpu are not given. */
8077 cpu
= riscv_parse_tune (opts
->x_riscv_tune_string
? opts
->x_riscv_tune_string
:
8078 (opts
->x_riscv_cpu_string
? opts
->x_riscv_cpu_string
:
8079 RISCV_TUNE_STRING_DEFAULT
));
8080 riscv_microarchitecture
= cpu
->microarchitecture
;
8081 tune_param
= opts
->x_optimize_size
? &optimize_size_tune_info
: cpu
->tune_param
;
8083 /* Use -mtune's setting for slow_unaligned_access, even when optimizing
8084 for size. For architectures that trap and emulate unaligned accesses,
8085 the performance cost is too great, even for -Os. Similarly, if
8086 -m[no-]strict-align is left unspecified, heed -mtune's advice. */
8087 riscv_slow_unaligned_access_p
= (cpu
->tune_param
->slow_unaligned_access
8088 || TARGET_STRICT_ALIGN
);
8090 /* Make a note if user explicity passed -mstrict-align for later
8091 builtin macro generation. Can't use target_flags_explicitly since
8092 it is set even for -mno-strict-align. */
8093 riscv_user_wants_strict_align
= TARGET_STRICT_ALIGN
;
8095 if ((target_flags_explicit
& MASK_STRICT_ALIGN
) == 0
8096 && cpu
->tune_param
->slow_unaligned_access
)
8097 opts
->x_target_flags
|= MASK_STRICT_ALIGN
;
8099 /* If the user hasn't specified a branch cost, use the processor's
8101 if (opts
->x_riscv_branch_cost
== 0)
8102 opts
->x_riscv_branch_cost
= tune_param
->branch_cost
;
8104 /* FIXME: We don't allow TARGET_MIN_VLEN > 4096 since the datatypes of
8105 both GET_MODE_SIZE and GET_MODE_BITSIZE are poly_uint16.
8107 We can only allow TARGET_MIN_VLEN * 8 (LMUL) < 65535. */
8108 if (TARGET_MIN_VLEN_OPTS (opts
) > 4096)
8109 sorry ("Current RISC-V GCC cannot support VLEN greater than 4096bit for "
8112 /* Convert -march to a chunks count. */
8113 riscv_vector_chunks
= riscv_convert_vector_bits (opts
);
8116 /* Implement TARGET_OPTION_OVERRIDE. */
8119 riscv_option_override (void)
8121 #ifdef SUBTARGET_OVERRIDE_OPTIONS
8122 SUBTARGET_OVERRIDE_OPTIONS
;
8125 flag_pcc_struct_return
= 0;
8131 riscv_cmodel
= CM_PIC
;
8133 /* We need to save the fp with ra for non-leaf functions with no fp and ra
8134 for leaf functions while no-omit-frame-pointer with
8135 omit-leaf-frame-pointer. The x_flag_omit_frame_pointer has the first
8136 priority to determine whether the frame pointer is needed. If we do not
8137 override it, the fp and ra will be stored for leaf functions, which is not
8139 riscv_save_frame_pointer
= false;
8140 if (TARGET_OMIT_LEAF_FRAME_POINTER_P (global_options
.x_target_flags
))
8142 if (!global_options
.x_flag_omit_frame_pointer
)
8143 riscv_save_frame_pointer
= true;
8145 global_options
.x_flag_omit_frame_pointer
= 1;
8148 /* We get better code with explicit relocs for CM_MEDLOW, but
8149 worse code for the others (for now). Pick the best default. */
8150 if ((target_flags_explicit
& MASK_EXPLICIT_RELOCS
) == 0)
8151 if (riscv_cmodel
== CM_MEDLOW
)
8152 target_flags
|= MASK_EXPLICIT_RELOCS
;
8154 /* Require that the ISA supports the requested floating-point ABI. */
8155 if (UNITS_PER_FP_ARG
> (TARGET_HARD_FLOAT
? UNITS_PER_FP_REG
: 0))
8156 error ("requested ABI requires %<-march%> to subsume the %qc extension",
8157 UNITS_PER_FP_ARG
> 8 ? 'Q' : (UNITS_PER_FP_ARG
> 4 ? 'D' : 'F'));
8159 if (TARGET_RVE
&& riscv_abi
!= ABI_ILP32E
)
8160 error ("rv32e requires ilp32e ABI");
8162 // Zfinx require abi ilp32,ilp32e or lp64.
8163 if (TARGET_ZFINX
&& riscv_abi
!= ABI_ILP32
8164 && riscv_abi
!= ABI_LP64
&& riscv_abi
!= ABI_ILP32E
)
8165 error ("z*inx requires ABI ilp32, ilp32e or lp64");
8167 /* We do not yet support ILP32 on RV64. */
8168 if (BITS_PER_WORD
!= POINTER_SIZE
)
8169 error ("ABI requires %<-march=rv%d%>", POINTER_SIZE
);
8171 /* Validate -mpreferred-stack-boundary= value. */
8172 riscv_stack_boundary
= ABI_STACK_BOUNDARY
;
8173 if (riscv_preferred_stack_boundary_arg
)
8175 int min
= ctz_hwi (STACK_BOUNDARY
/ 8);
8178 if (!IN_RANGE (riscv_preferred_stack_boundary_arg
, min
, max
))
8179 error ("%<-mpreferred-stack-boundary=%d%> must be between %d and %d",
8180 riscv_preferred_stack_boundary_arg
, min
, max
);
8182 riscv_stack_boundary
= 8 << riscv_preferred_stack_boundary_arg
;
8185 if (riscv_emit_attribute_p
< 0)
8186 #ifdef HAVE_AS_RISCV_ATTRIBUTE
8187 riscv_emit_attribute_p
= TARGET_RISCV_ATTRIBUTE
;
8189 riscv_emit_attribute_p
= 0;
8191 if (riscv_emit_attribute_p
)
8192 error ("%<-mriscv-attribute%> RISC-V ELF attribute requires GNU as 2.32"
8193 " [%<-mriscv-attribute%>]");
8196 if (riscv_stack_protector_guard
== SSP_GLOBAL
8197 && OPTION_SET_P (riscv_stack_protector_guard_offset_str
))
8199 error ("incompatible options %<-mstack-protector-guard=global%> and "
8200 "%<-mstack-protector-guard-offset=%s%>",
8201 riscv_stack_protector_guard_offset_str
);
8204 if (riscv_stack_protector_guard
== SSP_TLS
8205 && !(OPTION_SET_P (riscv_stack_protector_guard_offset_str
)
8206 && OPTION_SET_P (riscv_stack_protector_guard_reg_str
)))
8208 error ("both %<-mstack-protector-guard-offset%> and "
8209 "%<-mstack-protector-guard-reg%> must be used "
8210 "with %<-mstack-protector-guard=sysreg%>");
8213 if (OPTION_SET_P (riscv_stack_protector_guard_reg_str
))
8215 const char *str
= riscv_stack_protector_guard_reg_str
;
8216 int reg
= decode_reg_name (str
);
8218 if (!IN_RANGE (reg
, GP_REG_FIRST
+ 1, GP_REG_LAST
))
8219 error ("%qs is not a valid base register in %qs", str
,
8220 "-mstack-protector-guard-reg=");
8222 riscv_stack_protector_guard_reg
= reg
;
8225 if (OPTION_SET_P (riscv_stack_protector_guard_offset_str
))
8228 const char *str
= riscv_stack_protector_guard_offset_str
;
8230 long offs
= strtol (riscv_stack_protector_guard_offset_str
, &end
, 0);
8232 if (!*str
|| *end
|| errno
)
8233 error ("%qs is not a valid number in %qs", str
,
8234 "-mstack-protector-guard-offset=");
8236 if (!SMALL_OPERAND (offs
))
8237 error ("%qs is not a valid offset in %qs", str
,
8238 "-mstack-protector-guard-offset=");
8240 riscv_stack_protector_guard_offset
= offs
;
8243 SET_OPTION_IF_UNSET (&global_options
, &global_options_set
,
8244 param_sched_pressure_algorithm
,
8245 SCHED_PRESSURE_MODEL
);
8247 /* Function to allocate machine-dependent function status. */
8248 init_machine_status
= &riscv_init_machine_status
;
8250 riscv_override_options_internal (&global_options
);
8253 /* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */
8256 riscv_conditional_register_usage (void)
8258 /* We have only x0~x15 on RV32E. */
8261 for (int r
= 16; r
<= 31; r
++)
8265 if (riscv_abi
== ABI_ILP32E
)
8267 for (int r
= 16; r
<= 31; r
++)
8268 call_used_regs
[r
] = 1;
8271 if (!TARGET_HARD_FLOAT
)
8273 for (int regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
++)
8274 fixed_regs
[regno
] = call_used_regs
[regno
] = 1;
8277 /* In the soft-float ABI, there are no callee-saved FP registers. */
8278 if (UNITS_PER_FP_ARG
== 0)
8280 for (int regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
++)
8281 call_used_regs
[regno
] = 1;
8286 for (int regno
= V_REG_FIRST
; regno
<= V_REG_LAST
; regno
++)
8287 fixed_regs
[regno
] = call_used_regs
[regno
] = 1;
8289 fixed_regs
[VTYPE_REGNUM
] = call_used_regs
[VTYPE_REGNUM
] = 1;
8290 fixed_regs
[VL_REGNUM
] = call_used_regs
[VL_REGNUM
] = 1;
8291 fixed_regs
[VXRM_REGNUM
] = call_used_regs
[VXRM_REGNUM
] = 1;
8292 fixed_regs
[FRM_REGNUM
] = call_used_regs
[FRM_REGNUM
] = 1;
8296 /* Return a register priority for hard reg REGNO. */
8299 riscv_register_priority (int regno
)
8301 /* Favor compressed registers to improve the odds of RVC instruction
8303 if (riscv_compressed_reg_p (regno
))
8309 /* Implement TARGET_TRAMPOLINE_INIT. */
8312 riscv_trampoline_init (rtx m_tramp
, tree fndecl
, rtx chain_value
)
8314 rtx addr
, end_addr
, mem
;
8315 uint32_t trampoline
[4];
8317 HOST_WIDE_INT static_chain_offset
, target_function_offset
;
8319 /* Work out the offsets of the pointers from the start of the
8321 gcc_assert (ARRAY_SIZE (trampoline
) * 4 == TRAMPOLINE_CODE_SIZE
);
8323 /* Get pointers to the beginning and end of the code block. */
8324 addr
= force_reg (Pmode
, XEXP (m_tramp
, 0));
8325 end_addr
= riscv_force_binary (Pmode
, PLUS
, addr
,
8326 GEN_INT (TRAMPOLINE_CODE_SIZE
));
8329 if (Pmode
== SImode
)
8331 chain_value
= force_reg (Pmode
, chain_value
);
8333 rtx target_function
= force_reg (Pmode
, XEXP (DECL_RTL (fndecl
), 0));
8334 /* lui t2, hi(chain)
8336 addi t2, t2, lo(chain)
8339 unsigned HOST_WIDE_INT lui_hi_chain_code
, lui_hi_func_code
;
8340 unsigned HOST_WIDE_INT lo_chain_code
, lo_func_code
;
8342 rtx uimm_mask
= force_reg (SImode
, gen_int_mode (-IMM_REACH
, SImode
));
8345 rtx imm12_mask
= gen_reg_rtx (SImode
);
8346 emit_insn (gen_one_cmplsi2 (imm12_mask
, uimm_mask
));
8348 rtx fixup_value
= force_reg (SImode
, gen_int_mode (IMM_REACH
/2, SImode
));
8350 /* Gen lui t2, hi(chain). */
8351 rtx hi_chain
= riscv_force_binary (SImode
, PLUS
, chain_value
,
8353 hi_chain
= riscv_force_binary (SImode
, AND
, hi_chain
,
8355 lui_hi_chain_code
= OPCODE_LUI
| (STATIC_CHAIN_REGNUM
<< SHIFT_RD
);
8356 rtx lui_hi_chain
= riscv_force_binary (SImode
, IOR
, hi_chain
,
8357 gen_int_mode (lui_hi_chain_code
, SImode
));
8359 mem
= adjust_address (m_tramp
, SImode
, 0);
8360 riscv_emit_move (mem
, riscv_swap_instruction (lui_hi_chain
));
8362 /* Gen lui t0, hi(func). */
8363 rtx hi_func
= riscv_force_binary (SImode
, PLUS
, target_function
,
8365 hi_func
= riscv_force_binary (SImode
, AND
, hi_func
,
8367 lui_hi_func_code
= OPCODE_LUI
| (RISCV_PROLOGUE_TEMP_REGNUM
<< SHIFT_RD
);
8368 rtx lui_hi_func
= riscv_force_binary (SImode
, IOR
, hi_func
,
8369 gen_int_mode (lui_hi_func_code
, SImode
));
8371 mem
= adjust_address (m_tramp
, SImode
, 1 * GET_MODE_SIZE (SImode
));
8372 riscv_emit_move (mem
, riscv_swap_instruction (lui_hi_func
));
8374 /* Gen addi t2, t2, lo(chain). */
8375 rtx lo_chain
= riscv_force_binary (SImode
, AND
, chain_value
,
8377 lo_chain
= riscv_force_binary (SImode
, ASHIFT
, lo_chain
, GEN_INT (20));
8379 lo_chain_code
= OPCODE_ADDI
8380 | (STATIC_CHAIN_REGNUM
<< SHIFT_RD
)
8381 | (STATIC_CHAIN_REGNUM
<< SHIFT_RS1
);
8383 rtx addi_lo_chain
= riscv_force_binary (SImode
, IOR
, lo_chain
,
8384 force_reg (SImode
, GEN_INT (lo_chain_code
)));
8386 mem
= adjust_address (m_tramp
, SImode
, 2 * GET_MODE_SIZE (SImode
));
8387 riscv_emit_move (mem
, riscv_swap_instruction (addi_lo_chain
));
8389 /* Gen jr t0, lo(func). */
8390 rtx lo_func
= riscv_force_binary (SImode
, AND
, target_function
,
8392 lo_func
= riscv_force_binary (SImode
, ASHIFT
, lo_func
, GEN_INT (20));
8394 lo_func_code
= OPCODE_JALR
| (RISCV_PROLOGUE_TEMP_REGNUM
<< SHIFT_RS1
);
8396 rtx jr_lo_func
= riscv_force_binary (SImode
, IOR
, lo_func
,
8397 force_reg (SImode
, GEN_INT (lo_func_code
)));
8399 mem
= adjust_address (m_tramp
, SImode
, 3 * GET_MODE_SIZE (SImode
));
8400 riscv_emit_move (mem
, riscv_swap_instruction (jr_lo_func
));
8404 static_chain_offset
= TRAMPOLINE_CODE_SIZE
;
8405 target_function_offset
= static_chain_offset
+ GET_MODE_SIZE (ptr_mode
);
8408 l[wd] t0, target_function_offset(t2)
8409 l[wd] t2, static_chain_offset(t2)
8412 trampoline
[0] = OPCODE_AUIPC
| (STATIC_CHAIN_REGNUM
<< SHIFT_RD
);
8413 trampoline
[1] = (Pmode
== DImode
? OPCODE_LD
: OPCODE_LW
)
8414 | (RISCV_PROLOGUE_TEMP_REGNUM
<< SHIFT_RD
)
8415 | (STATIC_CHAIN_REGNUM
<< SHIFT_RS1
)
8416 | (target_function_offset
<< SHIFT_IMM
);
8417 trampoline
[2] = (Pmode
== DImode
? OPCODE_LD
: OPCODE_LW
)
8418 | (STATIC_CHAIN_REGNUM
<< SHIFT_RD
)
8419 | (STATIC_CHAIN_REGNUM
<< SHIFT_RS1
)
8420 | (static_chain_offset
<< SHIFT_IMM
);
8421 trampoline
[3] = OPCODE_JALR
| (RISCV_PROLOGUE_TEMP_REGNUM
<< SHIFT_RS1
);
8423 /* Copy the trampoline code. */
8424 for (i
= 0; i
< ARRAY_SIZE (trampoline
); i
++)
8426 if (BYTES_BIG_ENDIAN
)
8427 trampoline
[i
] = __builtin_bswap32(trampoline
[i
]);
8428 mem
= adjust_address (m_tramp
, SImode
, i
* GET_MODE_SIZE (SImode
));
8429 riscv_emit_move (mem
, gen_int_mode (trampoline
[i
], SImode
));
8432 /* Set up the static chain pointer field. */
8433 mem
= adjust_address (m_tramp
, ptr_mode
, static_chain_offset
);
8434 riscv_emit_move (mem
, chain_value
);
8436 /* Set up the target function field. */
8437 mem
= adjust_address (m_tramp
, ptr_mode
, target_function_offset
);
8438 riscv_emit_move (mem
, XEXP (DECL_RTL (fndecl
), 0));
8441 /* Flush the code part of the trampoline. */
8442 emit_insn (gen_add3_insn (end_addr
, addr
, GEN_INT (TRAMPOLINE_SIZE
)));
8443 emit_insn (gen_clear_cache (addr
, end_addr
));
8446 /* Implement TARGET_FUNCTION_OK_FOR_SIBCALL. */
8449 riscv_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED
,
8450 tree exp ATTRIBUTE_UNUSED
)
8452 /* Don't use sibcalls when use save-restore routine. */
8453 if (TARGET_SAVE_RESTORE
)
8456 /* Don't use sibcall for naked functions. */
8457 if (cfun
->machine
->naked_p
)
8460 /* Don't use sibcall for interrupt functions. */
8461 if (cfun
->machine
->interrupt_handler_p
)
8467 /* Get the interrupt type, return UNKNOWN_MODE if it's not
8468 interrupt function. */
8469 static enum riscv_privilege_levels
8470 riscv_get_interrupt_type (tree decl
)
8472 gcc_assert (decl
!= NULL_TREE
);
8474 if ((TREE_CODE(decl
) != FUNCTION_DECL
)
8475 || (!riscv_interrupt_type_p (TREE_TYPE (decl
))))
8476 return UNKNOWN_MODE
;
8479 = TREE_VALUE (lookup_attribute ("interrupt",
8480 TYPE_ATTRIBUTES (TREE_TYPE (decl
))));
8482 if (attr_args
&& TREE_CODE (TREE_VALUE (attr_args
)) != VOID_TYPE
)
8484 const char *string
= TREE_STRING_POINTER (TREE_VALUE (attr_args
));
8486 if (!strcmp (string
, "user"))
8488 else if (!strcmp (string
, "supervisor"))
8489 return SUPERVISOR_MODE
;
8490 else /* Must be "machine". */
8491 return MACHINE_MODE
;
8494 /* Interrupt attributes are machine mode by default. */
8495 return MACHINE_MODE
;
8498 /* Implement `TARGET_SET_CURRENT_FUNCTION'. */
8499 /* Sanity cheching for above function attributes. */
8501 riscv_set_current_function (tree decl
)
8503 if (decl
== NULL_TREE
8504 || current_function_decl
== NULL_TREE
8505 || current_function_decl
== error_mark_node
8507 || cfun
->machine
->attributes_checked_p
)
8510 cfun
->machine
->naked_p
= riscv_naked_function_p (decl
);
8511 cfun
->machine
->interrupt_handler_p
8512 = riscv_interrupt_type_p (TREE_TYPE (decl
));
8514 if (cfun
->machine
->naked_p
&& cfun
->machine
->interrupt_handler_p
)
8515 error ("function attributes %qs and %qs are mutually exclusive",
8516 "interrupt", "naked");
8518 if (cfun
->machine
->interrupt_handler_p
)
8520 tree ret
= TREE_TYPE (TREE_TYPE (decl
));
8521 tree args
= TYPE_ARG_TYPES (TREE_TYPE (decl
));
8523 if (TREE_CODE (ret
) != VOID_TYPE
)
8524 error ("%qs function cannot return a value", "interrupt");
8526 if (args
&& TREE_CODE (TREE_VALUE (args
)) != VOID_TYPE
)
8527 error ("%qs function cannot have arguments", "interrupt");
8529 cfun
->machine
->interrupt_mode
= riscv_get_interrupt_type (decl
);
8531 gcc_assert (cfun
->machine
->interrupt_mode
!= UNKNOWN_MODE
);
8534 /* Don't print the above diagnostics more than once. */
8535 cfun
->machine
->attributes_checked_p
= 1;
8538 /* Implement TARGET_MERGE_DECL_ATTRIBUTES. */
8540 riscv_merge_decl_attributes (tree olddecl
, tree newdecl
)
8542 tree combined_attrs
;
8544 enum riscv_privilege_levels old_interrupt_type
8545 = riscv_get_interrupt_type (olddecl
);
8546 enum riscv_privilege_levels new_interrupt_type
8547 = riscv_get_interrupt_type (newdecl
);
8549 /* Check old and new has same interrupt type. */
8550 if ((old_interrupt_type
!= UNKNOWN_MODE
)
8551 && (new_interrupt_type
!= UNKNOWN_MODE
)
8552 && (old_interrupt_type
!= new_interrupt_type
))
8553 error ("%qs function cannot have different interrupt type", "interrupt");
8555 /* Create combined attributes. */
8556 combined_attrs
= merge_attributes (DECL_ATTRIBUTES (olddecl
),
8557 DECL_ATTRIBUTES (newdecl
));
8559 return combined_attrs
;
8562 /* Implement TARGET_CANNOT_COPY_INSN_P. */
8565 riscv_cannot_copy_insn_p (rtx_insn
*insn
)
8567 return recog_memoized (insn
) >= 0 && get_attr_cannot_copy (insn
);
8570 /* Implement TARGET_SLOW_UNALIGNED_ACCESS. */
8573 riscv_slow_unaligned_access (machine_mode
, unsigned int)
8575 return riscv_slow_unaligned_access_p
;
8578 /* Implement TARGET_CAN_CHANGE_MODE_CLASS. */
8581 riscv_can_change_mode_class (machine_mode from
, machine_mode to
,
8584 /* We have RVV VLS modes and VLA modes sharing same REG_CLASS.
8585 In 'cprop_hardreg' stage, we will try to do hard reg copy propagation
8586 between wider mode (FROM) and narrow mode (TO).
8588 E.g. We should not allow copy propagation
8589 - RVVMF8BI (precision = [16, 16]) -> V32BI (precision = [32, 0])
8590 since we can't order their size which will cause ICE in regcprop.
8592 TODO: Even though they are have different size, they always change
8593 the whole register. We may enhance such case in regcprop to optimize
8594 it in the future. */
8595 if (reg_classes_intersect_p (V_REGS
, rclass
)
8596 && !ordered_p (GET_MODE_PRECISION (from
), GET_MODE_PRECISION (to
)))
8598 return !reg_classes_intersect_p (FP_REGS
, rclass
);
8601 /* Implement TARGET_CONSTANT_ALIGNMENT. */
8603 static HOST_WIDE_INT
8604 riscv_constant_alignment (const_tree exp
, HOST_WIDE_INT align
)
8606 if ((TREE_CODE (exp
) == STRING_CST
|| TREE_CODE (exp
) == CONSTRUCTOR
)
8607 && (riscv_align_data_type
== riscv_align_data_type_xlen
))
8608 return MAX (align
, BITS_PER_WORD
);
8612 /* Implement TARGET_PROMOTE_FUNCTION_MODE. */
8614 /* This function is equivalent to default_promote_function_mode_always_promote
8615 except that it returns a promoted mode even if type is NULL_TREE. This is
8616 needed by libcalls which have no type (only a mode) such as fixed conversion
8617 routines that take a signed or unsigned char/short/int argument and convert
8618 it to a fixed type. */
8621 riscv_promote_function_mode (const_tree type ATTRIBUTE_UNUSED
,
8623 int *punsignedp ATTRIBUTE_UNUSED
,
8624 const_tree fntype ATTRIBUTE_UNUSED
,
8625 int for_return ATTRIBUTE_UNUSED
)
8629 if (type
!= NULL_TREE
)
8630 return promote_mode (type
, mode
, punsignedp
);
8632 unsignedp
= *punsignedp
;
8633 PROMOTE_MODE (as_a
<scalar_mode
> (mode
), unsignedp
, type
);
8634 *punsignedp
= unsignedp
;
8638 /* Implement TARGET_MACHINE_DEPENDENT_REORG. */
8643 /* Do nothing unless we have -msave-restore */
8644 if (TARGET_SAVE_RESTORE
)
8645 riscv_remove_unneeded_save_restore_calls ();
8648 /* Return nonzero if register FROM_REGNO can be renamed to register
8652 riscv_hard_regno_rename_ok (unsigned from_regno ATTRIBUTE_UNUSED
,
8655 /* Interrupt functions can only use registers that have already been
8656 saved by the prologue, even if they would normally be
8658 return !cfun
->machine
->interrupt_handler_p
|| df_regs_ever_live_p (to_regno
);
8661 /* Implement TARGET_NEW_ADDRESS_PROFITABLE_P. */
8664 riscv_new_address_profitable_p (rtx memref
, rtx_insn
*insn
, rtx new_addr
)
8666 /* Prefer old address if it is less expensive. */
8667 addr_space_t as
= MEM_ADDR_SPACE (memref
);
8668 bool speed
= optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn
));
8669 int old_cost
= address_cost (XEXP (memref
, 0), GET_MODE (memref
), as
, speed
);
8670 int new_cost
= address_cost (new_addr
, GET_MODE (memref
), as
, speed
);
8671 return new_cost
<= old_cost
;
8674 /* Helper function for generating gpr_save pattern. */
8677 riscv_gen_gpr_save_insn (struct riscv_frame_info
*frame
)
8679 unsigned count
= riscv_save_libcall_count (frame
->mask
);
8680 /* 1 for unspec 2 for clobber t0/t1 and 1 for ra. */
8681 unsigned veclen
= 1 + 2 + 1 + count
;
8682 rtvec vec
= rtvec_alloc (veclen
);
8684 gcc_assert (veclen
<= ARRAY_SIZE (gpr_save_reg_order
));
8686 RTVEC_ELT (vec
, 0) =
8687 gen_rtx_UNSPEC_VOLATILE (VOIDmode
,
8688 gen_rtvec (1, GEN_INT (count
)), UNSPECV_GPR_SAVE
);
8690 for (unsigned i
= 1; i
< veclen
; ++i
)
8692 unsigned regno
= gpr_save_reg_order
[i
];
8693 rtx reg
= gen_rtx_REG (Pmode
, regno
);
8696 /* t0 and t1 are CLOBBERs, others are USEs. */
8698 elt
= gen_rtx_CLOBBER (Pmode
, reg
);
8700 elt
= gen_rtx_USE (Pmode
, reg
);
8702 RTVEC_ELT (vec
, i
) = elt
;
8705 /* Largest number of caller-save register must set in mask if we are
8706 not using __riscv_save_0. */
8707 gcc_assert ((count
== 0) ||
8708 BITSET_P (frame
->mask
, gpr_save_reg_order
[veclen
- 1]));
8710 return gen_rtx_PARALLEL (VOIDmode
, vec
);
8713 static HOST_WIDE_INT
8714 zcmp_base_adj (int regs_num
)
8716 return riscv_16bytes_align ((regs_num
) *GET_MODE_SIZE (word_mode
));
8719 static HOST_WIDE_INT
8720 zcmp_additional_adj (HOST_WIDE_INT total
, int regs_num
)
8722 return total
- zcmp_base_adj (regs_num
);
8726 riscv_zcmp_valid_stack_adj_bytes_p (HOST_WIDE_INT total
, int regs_num
)
8728 HOST_WIDE_INT additioanl_bytes
= zcmp_additional_adj (total
, regs_num
);
8729 return additioanl_bytes
== 0 || additioanl_bytes
== 1 * ZCMP_SP_INC_STEP
8730 || additioanl_bytes
== 2 * ZCMP_SP_INC_STEP
8731 || additioanl_bytes
== ZCMP_MAX_SPIMM
* ZCMP_SP_INC_STEP
;
8734 /* Return true if it's valid gpr_save pattern. */
8737 riscv_gpr_save_operation_p (rtx op
)
8739 unsigned len
= XVECLEN (op
, 0);
8741 if (len
> ARRAY_SIZE (gpr_save_reg_order
))
8744 for (unsigned i
= 0; i
< len
; i
++)
8746 rtx elt
= XVECEXP (op
, 0, i
);
8749 /* First element in parallel is unspec. */
8750 if (GET_CODE (elt
) != UNSPEC_VOLATILE
8751 || GET_CODE (XVECEXP (elt
, 0, 0)) != CONST_INT
8752 || XINT (elt
, 1) != UNSPECV_GPR_SAVE
)
8757 /* Two CLOBBER and USEs, must check the order. */
8758 unsigned expect_code
= i
< 3 ? CLOBBER
: USE
;
8759 if (GET_CODE (elt
) != expect_code
8760 || !REG_P (XEXP (elt
, 1))
8761 || (REGNO (XEXP (elt
, 1)) != gpr_save_reg_order
[i
]))
8769 /* Implement TARGET_ASAN_SHADOW_OFFSET. */
8771 static unsigned HOST_WIDE_INT
8772 riscv_asan_shadow_offset (void)
8774 /* We only have libsanitizer support for RV64 at present.
8776 This number must match ASAN_SHADOW_OFFSET_CONST in the file
8777 libsanitizer/asan/asan_mapping.h. */
8778 return TARGET_64BIT
? HOST_WIDE_INT_UC (0xd55550000) : 0;
8781 /* Implement TARGET_MANGLE_TYPE. */
8784 riscv_mangle_type (const_tree type
)
8786 /* Half-precision float, _Float16 is "DF16_". */
8787 if (SCALAR_FLOAT_TYPE_P (type
) && TYPE_PRECISION (type
) == 16)
8790 /* Mangle all vector type for vector extension. */
8791 /* The mangle name follows the rule of RVV LLVM
8792 that is "u" + length of (abi_name) + abi_name. */
8793 if (TYPE_NAME (type
) != NULL
)
8795 const char *res
= riscv_vector::mangle_builtin_type (type
);
8800 /* Use the default mangling. */
8804 /* Implement TARGET_SCALAR_MODE_SUPPORTED_P. */
8807 riscv_scalar_mode_supported_p (scalar_mode mode
)
8812 return default_scalar_mode_supported_p (mode
);
8815 /* Implement TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P - return TRUE
8816 if MODE is HFmode, and punt to the generic implementation otherwise. */
8819 riscv_libgcc_floating_mode_supported_p (scalar_float_mode mode
)
8824 return default_libgcc_floating_mode_supported_p (mode
);
8827 /* Set the value of FLT_EVAL_METHOD.
8828 ISO/IEC TS 18661-3 defines two values that we'd like to make use of:
8830 0: evaluate all operations and constants, whose semantic type has at
8831 most the range and precision of type float, to the range and
8832 precision of float; evaluate all other operations and constants to
8833 the range and precision of the semantic type;
8835 N, where _FloatN is a supported interchange floating type
8836 evaluate all operations and constants, whose semantic type has at
8837 most the range and precision of _FloatN type, to the range and
8838 precision of the _FloatN type; evaluate all other operations and
8839 constants to the range and precision of the semantic type;
8841 If we have the zfh/zhinx/zvfh extensions then we support _Float16
8842 in native precision, so we should set this to 16. */
8843 static enum flt_eval_method
8844 riscv_excess_precision (enum excess_precision_type type
)
8848 case EXCESS_PRECISION_TYPE_FAST
:
8849 case EXCESS_PRECISION_TYPE_STANDARD
:
8850 return ((TARGET_ZFH
|| TARGET_ZHINX
|| TARGET_ZVFH
)
8851 ? FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16
8852 : FLT_EVAL_METHOD_PROMOTE_TO_FLOAT
);
8853 case EXCESS_PRECISION_TYPE_IMPLICIT
:
8854 case EXCESS_PRECISION_TYPE_FLOAT16
:
8855 return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16
;
8859 return FLT_EVAL_METHOD_UNPREDICTABLE
;
8862 /* Implement TARGET_FLOATN_MODE. */
8863 static opt_scalar_float_mode
8864 riscv_floatn_mode (int n
, bool extended
)
8866 if (!extended
&& n
== 16)
8869 return default_floatn_mode (n
, extended
);
8873 riscv_init_libfuncs (void)
8875 /* Half-precision float operations. The compiler handles all operations
8876 with NULL libfuncs by converting to SFmode. */
8879 set_optab_libfunc (add_optab
, HFmode
, NULL
);
8880 set_optab_libfunc (sdiv_optab
, HFmode
, NULL
);
8881 set_optab_libfunc (smul_optab
, HFmode
, NULL
);
8882 set_optab_libfunc (neg_optab
, HFmode
, NULL
);
8883 set_optab_libfunc (sub_optab
, HFmode
, NULL
);
8886 set_optab_libfunc (eq_optab
, HFmode
, NULL
);
8887 set_optab_libfunc (ne_optab
, HFmode
, NULL
);
8888 set_optab_libfunc (lt_optab
, HFmode
, NULL
);
8889 set_optab_libfunc (le_optab
, HFmode
, NULL
);
8890 set_optab_libfunc (ge_optab
, HFmode
, NULL
);
8891 set_optab_libfunc (gt_optab
, HFmode
, NULL
);
8892 set_optab_libfunc (unord_optab
, HFmode
, NULL
);
8899 riscv_option_override ();
8900 init_adjust_machine_modes ();
8901 init_derived_machine_modes ();
8908 #undef TARGET_RUN_TARGET_SELFTESTS
8909 #define TARGET_RUN_TARGET_SELFTESTS selftest::riscv_run_selftests
8910 #endif /* #if CHECKING_P */
8912 /* Implement TARGET_VECTOR_MODE_SUPPORTED_P. */
8915 riscv_vector_mode_supported_p (machine_mode mode
)
8918 return riscv_v_ext_mode_p (mode
);
8923 /* Implement TARGET_VERIFY_TYPE_CONTEXT. */
8926 riscv_verify_type_context (location_t loc
, type_context_kind context
,
8927 const_tree type
, bool silent_p
)
8929 return riscv_vector::verify_type_context (loc
, context
, type
, silent_p
);
8932 /* Implement TARGET_VECTOR_ALIGNMENT. */
8934 static HOST_WIDE_INT
8935 riscv_vector_alignment (const_tree type
)
8937 /* ??? Checking the mode isn't ideal, but VECTOR_BOOLEAN_TYPE_P can
8938 be set for non-predicate vectors of booleans. Modes are the most
8939 direct way we have of identifying real RVV predicate types. */
8940 /* FIXME: RVV didn't mention the alignment of bool, we uses
8942 if (GET_MODE_CLASS (TYPE_MODE (type
)) == MODE_VECTOR_BOOL
)
8946 = constant_lower_bound (wi::to_poly_widest (TYPE_SIZE (type
)));
8947 return wi::umin (min_size
, 128).to_uhwi ();
8950 /* Implement REGMODE_NATURAL_SIZE. */
8953 riscv_regmode_natural_size (machine_mode mode
)
8955 /* The natural size for RVV data modes is one RVV data vector,
8956 and similarly for predicates. We can't independently modify
8957 anything smaller than that. */
8958 /* ??? For now, only do this for variable-width RVV registers.
8959 Doing it for constant-sized registers breaks lower-subreg.c. */
8961 if (riscv_v_ext_mode_p (mode
))
8963 if (riscv_v_ext_tuple_mode_p (mode
))
8966 = GET_MODE_SIZE (riscv_vector::get_subpart_mode (mode
));
8967 if (known_lt (size
, BYTES_PER_RISCV_VECTOR
))
8970 else if (riscv_v_ext_vector_mode_p (mode
))
8972 /* RVV mask modes always consume a single register. */
8973 if (GET_MODE_CLASS (mode
) == MODE_VECTOR_BOOL
)
8974 return BYTES_PER_RISCV_VECTOR
;
8976 if (!GET_MODE_SIZE (mode
).is_constant ())
8977 return BYTES_PER_RISCV_VECTOR
;
8979 return UNITS_PER_WORD
;
8982 /* Implement the TARGET_DWARF_POLY_INDETERMINATE_VALUE hook. */
8985 riscv_dwarf_poly_indeterminate_value (unsigned int i
, unsigned int *factor
,
8988 /* Polynomial invariant 1 == (VLENB / riscv_bytes_per_vector_chunk) - 1.
8989 1. TARGET_MIN_VLEN == 32, polynomial invariant 1 == (VLENB / 4) - 1.
8990 2. TARGET_MIN_VLEN > 32, polynomial invariant 1 == (VLENB / 8) - 1.
8992 gcc_assert (i
== 1);
8993 *factor
= riscv_bytes_per_vector_chunk
;
8995 return RISCV_DWARF_VLENB
;
8998 /* Implement TARGET_ESTIMATED_POLY_VALUE.
8999 Look into the tuning structure for an estimate.
9000 KIND specifies the type of requested estimate: min, max or likely.
9001 For cores with a known RVV width all three estimates are the same.
9002 For generic RVV tuning we want to distinguish the maximum estimate from
9003 the minimum and likely ones.
9004 The likely estimate is the same as the minimum in that case to give a
9005 conservative behavior of auto-vectorizing with RVV when it is a win
9006 even for 128-bit RVV.
9007 When RVV width information is available VAL.coeffs[1] is multiplied by
9008 the number of VQ chunks over the initial Advanced SIMD 128 bits. */
9010 static HOST_WIDE_INT
9011 riscv_estimated_poly_value (poly_int64 val
,
9012 poly_value_estimate_kind kind
= POLY_VALUE_LIKELY
)
9014 unsigned int width_source
= BITS_PER_RISCV_VECTOR
.is_constant ()
9015 ? (unsigned int) BITS_PER_RISCV_VECTOR
.to_constant ()
9016 : (unsigned int) RVV_SCALABLE
;
9018 /* If there is no core-specific information then the minimum and likely
9019 values are based on 128-bit vectors and the maximum is based on
9020 the architectural maximum of 65536 bits. */
9021 if (width_source
== RVV_SCALABLE
)
9024 case POLY_VALUE_MIN
:
9025 case POLY_VALUE_LIKELY
:
9026 return val
.coeffs
[0];
9028 case POLY_VALUE_MAX
:
9029 return val
.coeffs
[0] + val
.coeffs
[1] * 15;
9032 /* Allow BITS_PER_RISCV_VECTOR to be a bitmask of different VL, treating the
9033 lowest as likely. This could be made more general if future -mtune
9034 options need it to be. */
9035 if (kind
== POLY_VALUE_MAX
)
9036 width_source
= 1 << floor_log2 (width_source
);
9038 width_source
= least_bit_hwi (width_source
);
9040 /* If the core provides width information, use that. */
9041 HOST_WIDE_INT over_128
= width_source
- 128;
9042 return val
.coeffs
[0] + val
.coeffs
[1] * over_128
/ 128;
9045 /* Return true if the vector misalignment factor is supported by the
9048 riscv_support_vector_misalignment (machine_mode mode
,
9049 const_tree type ATTRIBUTE_UNUSED
,
9051 bool is_packed ATTRIBUTE_UNUSED
)
9053 /* Depend on movmisalign pattern. */
9054 return default_builtin_support_vector_misalignment (mode
, type
, misalignment
,
9058 /* Implement TARGET_VECTORIZE_GET_MASK_MODE. */
9060 static opt_machine_mode
9061 riscv_get_mask_mode (machine_mode mode
)
9063 if (TARGET_VECTOR
&& riscv_v_ext_mode_p (mode
))
9064 return riscv_vector::get_mask_mode (mode
);
9066 return default_get_mask_mode (mode
);
9069 /* Implement TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE. Assume for now that
9070 it isn't worth branching around empty masked ops (including masked
9074 riscv_empty_mask_is_expensive (unsigned)
9079 /* Return true if a shift-amount matches the trailing cleared bits on
9083 riscv_shamt_matches_mask_p (int shamt
, HOST_WIDE_INT mask
)
9085 return shamt
== ctz_hwi (mask
);
9089 vector_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs
)
9091 HARD_REG_SET zeroed_hardregs
;
9092 CLEAR_HARD_REG_SET (zeroed_hardregs
);
9094 /* Find a register to hold vl. */
9095 unsigned vl_regno
= INVALID_REGNUM
;
9096 /* Skip the first GPR, otherwise the existing vl is kept due to the same
9097 between vl and avl. */
9098 for (unsigned regno
= GP_REG_FIRST
+ 1; regno
<= GP_REG_LAST
; regno
++)
9100 if (TEST_HARD_REG_BIT (need_zeroed_hardregs
, regno
))
9107 if (vl_regno
> GP_REG_LAST
)
9108 sorry ("cannot allocate vl register for %qs on this target",
9109 "-fzero-call-used-regs");
9111 /* Vector configurations need not be saved and restored here. The
9112 -fzero-call-used-regs=* option will zero all vector registers and
9113 return. So there's no vector operations between them. */
9115 bool emitted_vlmax_vsetvl
= false;
9116 rtx vl
= gen_rtx_REG (Pmode
, vl_regno
); /* vl is VLMAX. */
9117 for (unsigned regno
= V_REG_FIRST
; regno
<= V_REG_LAST
; ++regno
)
9119 if (TEST_HARD_REG_BIT (need_zeroed_hardregs
, regno
))
9121 rtx target
= regno_reg_rtx
[regno
];
9122 machine_mode mode
= GET_MODE (target
);
9124 if (!emitted_vlmax_vsetvl
)
9126 riscv_vector::emit_hard_vlmax_vsetvl (mode
, vl
);
9127 emitted_vlmax_vsetvl
= true;
9130 rtx ops
[] = {target
, CONST0_RTX (mode
)};
9131 riscv_vector::emit_vlmax_insn_lra (code_for_pred_mov (mode
),
9132 riscv_vector::UNARY_OP
, ops
, vl
);
9134 SET_HARD_REG_BIT (zeroed_hardregs
, regno
);
9138 return zeroed_hardregs
;
9141 /* Generate a sequence of instructions that zero registers specified by
9142 NEED_ZEROED_HARDREGS. Return the ZEROED_HARDREGS that are actually
9145 riscv_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs
)
9147 HARD_REG_SET zeroed_hardregs
;
9148 CLEAR_HARD_REG_SET (zeroed_hardregs
);
9151 zeroed_hardregs
|= vector_zero_call_used_regs (need_zeroed_hardregs
);
9153 return zeroed_hardregs
| default_zero_call_used_regs (need_zeroed_hardregs
9154 & ~zeroed_hardregs
);
9157 /* Implement target hook TARGET_ARRAY_MODE. */
9159 static opt_machine_mode
9160 riscv_array_mode (machine_mode mode
, unsigned HOST_WIDE_INT nelems
)
9164 && riscv_vector::get_tuple_mode (mode
, nelems
).exists (&vmode
))
9167 return opt_machine_mode ();
9170 /* Given memory reference MEM, expand code to compute the aligned
9171 memory address, shift and mask values and store them into
9172 *ALIGNED_MEM, *SHIFT, *MASK and *NOT_MASK. */
9175 riscv_subword_address (rtx mem
, rtx
*aligned_mem
, rtx
*shift
, rtx
*mask
,
9178 /* Align the memory address to a word. */
9179 rtx addr
= force_reg (Pmode
, XEXP (mem
, 0));
9181 rtx addr_mask
= gen_int_mode (-4, Pmode
);
9183 rtx aligned_addr
= gen_reg_rtx (Pmode
);
9184 emit_move_insn (aligned_addr
, gen_rtx_AND (Pmode
, addr
, addr_mask
));
9186 *aligned_mem
= change_address (mem
, SImode
, aligned_addr
);
9188 /* Calculate the shift amount. */
9189 emit_move_insn (*shift
, gen_rtx_AND (SImode
, gen_lowpart (SImode
, addr
),
9190 gen_int_mode (3, SImode
)));
9191 emit_move_insn (*shift
, gen_rtx_ASHIFT (SImode
, *shift
,
9192 gen_int_mode (3, SImode
)));
9194 /* Calculate the mask. */
9195 int unshifted_mask
= GET_MODE_MASK (GET_MODE (mem
));
9197 emit_move_insn (*mask
, gen_int_mode (unshifted_mask
, SImode
));
9199 emit_move_insn (*mask
, gen_rtx_ASHIFT (SImode
, *mask
,
9200 gen_lowpart (QImode
, *shift
)));
9202 emit_move_insn (*not_mask
, gen_rtx_NOT (SImode
, *mask
));
9205 /* Leftshift a subword within an SImode register. */
9208 riscv_lshift_subword (machine_mode mode
, rtx value
, rtx shift
,
9211 rtx value_reg
= gen_reg_rtx (SImode
);
9212 emit_move_insn (value_reg
, simplify_gen_subreg (SImode
, value
,
9215 emit_move_insn (*shifted_value
, gen_rtx_ASHIFT (SImode
, value_reg
,
9216 gen_lowpart (QImode
, shift
)));
9219 /* Return TRUE if we should use the divmod expander, FALSE otherwise. This
9220 allows the behavior to be tuned for specific implementations as well as
9221 when optimizing for size. */
9224 riscv_use_divmod_expander (void)
9226 return tune_param
->use_divmod_expansion
;
9229 /* Implement TARGET_VECTORIZE_PREFERRED_SIMD_MODE. */
9232 riscv_preferred_simd_mode (scalar_mode mode
)
9235 return riscv_vector::preferred_simd_mode (mode
);
9240 /* Implement target hook TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT. */
9243 riscv_vectorize_preferred_vector_alignment (const_tree type
)
9245 if (riscv_v_ext_mode_p (TYPE_MODE (type
)))
9246 return TYPE_ALIGN (TREE_TYPE (type
));
9247 return TYPE_ALIGN (type
);
9250 /* Return true if it is static FRM rounding mode. */
9253 riscv_static_frm_mode_p (int mode
)
9257 case riscv_vector::FRM_RDN
:
9258 case riscv_vector::FRM_RUP
:
9259 case riscv_vector::FRM_RTZ
:
9260 case riscv_vector::FRM_RMM
:
9261 case riscv_vector::FRM_RNE
:
9270 /* Implement the floating-point Mode Switching. */
9273 riscv_emit_frm_mode_set (int mode
, int prev_mode
)
9275 rtx backup_reg
= DYNAMIC_FRM_RTL (cfun
);
9277 if (prev_mode
== riscv_vector::FRM_DYN_CALL
)
9278 emit_insn (gen_frrmsi (backup_reg
)); /* Backup frm when DYN_CALL. */
9280 if (mode
!= prev_mode
)
9282 rtx frm
= gen_int_mode (mode
, SImode
);
9284 if (mode
== riscv_vector::FRM_DYN_CALL
9285 && prev_mode
!= riscv_vector::FRM_DYN
&& STATIC_FRM_P (cfun
))
9286 /* No need to emit when prev mode is DYN already. */
9287 emit_insn (gen_fsrmsi_restore_volatile (backup_reg
));
9288 else if (mode
== riscv_vector::FRM_DYN_EXIT
&& STATIC_FRM_P (cfun
)
9289 && prev_mode
!= riscv_vector::FRM_DYN
9290 && prev_mode
!= riscv_vector::FRM_DYN_CALL
)
9291 /* No need to emit when prev mode is DYN or DYN_CALL already. */
9292 emit_insn (gen_fsrmsi_restore_volatile (backup_reg
));
9293 else if (mode
== riscv_vector::FRM_DYN
9294 && prev_mode
!= riscv_vector::FRM_DYN_CALL
)
9295 /* Restore frm value from backup when switch to DYN mode. */
9296 emit_insn (gen_fsrmsi_restore (backup_reg
));
9297 else if (riscv_static_frm_mode_p (mode
))
9298 /* Set frm value when switch to static mode. */
9299 emit_insn (gen_fsrmsi_restore (frm
));
9303 /* Implement Mode switching. */
9306 riscv_emit_mode_set (int entity
, int mode
, int prev_mode
,
9307 HARD_REG_SET regs_live ATTRIBUTE_UNUSED
)
9312 if (mode
!= VXRM_MODE_NONE
&& mode
!= prev_mode
)
9313 emit_insn (gen_vxrmsi (gen_int_mode (mode
, SImode
)));
9316 riscv_emit_frm_mode_set (mode
, prev_mode
);
9323 /* Adjust the FRM_NONE insn after a call to FRM_DYN for the
9327 riscv_frm_adjust_mode_after_call (rtx_insn
*cur_insn
, int mode
)
9329 rtx_insn
*insn
= prev_nonnote_nondebug_insn_bb (cur_insn
);
9331 if (insn
&& CALL_P (insn
))
9332 return riscv_vector::FRM_DYN
;
9337 /* Insert the backup frm insn to the end of the bb if and only if the call
9338 is the last insn of this bb. */
9341 riscv_frm_emit_after_bb_end (rtx_insn
*cur_insn
)
9344 edge_iterator eg_iterator
;
9345 basic_block bb
= BLOCK_FOR_INSN (cur_insn
);
9347 FOR_EACH_EDGE (eg
, eg_iterator
, bb
->succs
)
9350 emit_insn (gen_frrmsi (DYNAMIC_FRM_RTL (cfun
)));
9351 rtx_insn
*backup_insn
= get_insns ();
9354 if (eg
->flags
& EDGE_ABNORMAL
)
9355 insert_insn_end_basic_block (backup_insn
, bb
);
9357 insert_insn_on_edge (backup_insn
, eg
);
9360 commit_edge_insertions ();
9363 /* Return mode that frm must be switched into
9364 prior to the execution of insn. */
9367 riscv_frm_mode_needed (rtx_insn
*cur_insn
, int code
)
9369 if (!DYNAMIC_FRM_RTL(cfun
))
9371 /* The dynamic frm will be initialized only onece during cfun. */
9372 DYNAMIC_FRM_RTL (cfun
) = gen_reg_rtx (SImode
);
9373 emit_insn_at_entry (gen_frrmsi (DYNAMIC_FRM_RTL (cfun
)));
9376 if (CALL_P (cur_insn
))
9378 rtx_insn
*insn
= next_nonnote_nondebug_insn_bb (cur_insn
);
9381 riscv_frm_emit_after_bb_end (cur_insn
);
9383 return riscv_vector::FRM_DYN_CALL
;
9386 int mode
= code
>= 0 ? get_attr_frm_mode (cur_insn
) : riscv_vector::FRM_NONE
;
9388 if (mode
== riscv_vector::FRM_NONE
)
9389 /* After meet a call, we need to backup the frm because it may be
9390 updated during the call. Here, for each insn, we will check if
9391 the previous insn is a call or not. When previous insn is call,
9392 there will be 2 cases for the emit mode set.
9394 1. Current insn is not MODE_NONE, then the mode switch framework
9395 will do the mode switch from MODE_CALL to MODE_NONE natively.
9396 2. Current insn is MODE_NONE, we need to adjust the MODE_NONE to
9397 the MODE_DYN, and leave the mode switch itself to perform
9400 mode
= riscv_frm_adjust_mode_after_call (cur_insn
, mode
);
9405 /* Return mode that entity must be switched into
9406 prior to the execution of insn. */
9409 riscv_mode_needed (int entity
, rtx_insn
*insn
)
9411 int code
= recog_memoized (insn
);
9416 return code
>= 0 ? get_attr_vxrm_mode (insn
) : VXRM_MODE_NONE
;
9418 return riscv_frm_mode_needed (insn
, code
);
9424 /* Return TRUE that an insn is asm. */
9427 asm_insn_p (rtx_insn
*insn
)
9429 extract_insn (insn
);
9431 return recog_data
.is_asm
;
9434 /* Return TRUE that an insn is unknown for VXRM. */
9437 vxrm_unknown_p (rtx_insn
*insn
)
9439 /* Return true if there is a definition of VXRM. */
9440 if (reg_set_p (gen_rtx_REG (SImode
, VXRM_REGNUM
), insn
))
9443 /* A CALL function may contain an instruction that modifies the VXRM,
9444 return true in this situation. */
9448 /* Return true for all assembly since users may hardcode a assembly
9449 like this: asm volatile ("csrwi vxrm, 0"). */
9450 if (asm_insn_p (insn
))
9456 /* Return TRUE that an insn is unknown dynamic for FRM. */
9459 frm_unknown_dynamic_p (rtx_insn
*insn
)
9461 /* Return true if there is a definition of FRM. */
9462 if (reg_set_p (gen_rtx_REG (SImode
, FRM_REGNUM
), insn
))
9468 /* Return the mode that an insn results in for VXRM. */
9471 riscv_vxrm_mode_after (rtx_insn
*insn
, int mode
)
9473 if (vxrm_unknown_p (insn
))
9474 return VXRM_MODE_NONE
;
9476 if (recog_memoized (insn
) < 0)
9479 if (reg_mentioned_p (gen_rtx_REG (SImode
, VXRM_REGNUM
), PATTERN (insn
)))
9480 return get_attr_vxrm_mode (insn
);
9485 /* Return the mode that an insn results in for FRM. */
9488 riscv_frm_mode_after (rtx_insn
*insn
, int mode
)
9490 STATIC_FRM_P (cfun
) = STATIC_FRM_P (cfun
) || riscv_static_frm_mode_p (mode
);
9495 if (frm_unknown_dynamic_p (insn
))
9496 return riscv_vector::FRM_DYN
;
9498 if (recog_memoized (insn
) < 0)
9501 if (reg_mentioned_p (gen_rtx_REG (SImode
, FRM_REGNUM
), PATTERN (insn
)))
9502 return get_attr_frm_mode (insn
);
9507 /* Return the mode that an insn results in. */
9510 riscv_mode_after (int entity
, int mode
, rtx_insn
*insn
)
9515 return riscv_vxrm_mode_after (insn
, mode
);
9517 return riscv_frm_mode_after (insn
, mode
);
9523 /* Return a mode that ENTITY is assumed to be
9524 switched to at function entry. */
9527 riscv_mode_entry (int entity
)
9532 return VXRM_MODE_NONE
;
9535 /* According to RVV 1.0 spec, all vector floating-point operations use
9536 the dynamic rounding mode in the frm register. Likewise in other
9538 return riscv_vector::FRM_DYN
;
9545 /* Return a mode that ENTITY is assumed to be
9546 switched to at function exit. */
9549 riscv_mode_exit (int entity
)
9554 return VXRM_MODE_NONE
;
9556 return riscv_vector::FRM_DYN_EXIT
;
9563 riscv_mode_priority (int, int n
)
9568 /* Implement TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES. */
9570 riscv_autovectorize_vector_modes (vector_modes
*modes
, bool all
)
9573 return riscv_vector::autovectorize_vector_modes (modes
, all
);
9575 return default_autovectorize_vector_modes (modes
, all
);
9578 /* Implement TARGET_VECTORIZE_RELATED_MODE. */
9580 riscv_vectorize_related_mode (machine_mode vector_mode
, scalar_mode element_mode
,
9584 return riscv_vector::vectorize_related_mode (vector_mode
, element_mode
,
9586 return default_vectorize_related_mode (vector_mode
, element_mode
, nunits
);
9589 /* Implement TARGET_VECTORIZE_VEC_PERM_CONST. */
9592 riscv_vectorize_vec_perm_const (machine_mode vmode
, machine_mode op_mode
,
9593 rtx target
, rtx op0
, rtx op1
,
9594 const vec_perm_indices
&sel
)
9596 if (TARGET_VECTOR
&& riscv_v_ext_mode_p (vmode
))
9597 return riscv_vector::expand_vec_perm_const (vmode
, op_mode
, target
, op0
,
9604 riscv_frame_pointer_required (void)
9606 return riscv_save_frame_pointer
&& !crtl
->is_leaf
;
9609 /* Implement targetm.vectorize.create_costs. */
9611 static vector_costs
*
9612 riscv_vectorize_create_costs (vec_info
*vinfo
, bool costing_for_scalar
)
9615 return new riscv_vector::costs (vinfo
, costing_for_scalar
);
9616 /* Default vector costs. */
9617 return new vector_costs (vinfo
, costing_for_scalar
);
9620 /* Implement TARGET_PREFERRED_ELSE_VALUE. */
9623 riscv_preferred_else_value (unsigned ifn
, tree vectype
, unsigned int nops
,
9626 if (riscv_v_ext_mode_p (TYPE_MODE (vectype
)))
9627 return get_or_create_ssa_default_def (cfun
, create_tmp_var (vectype
));
9629 return default_preferred_else_value (ifn
, vectype
, nops
, ops
);
9632 /* Initialize the GCC target structure. */
9633 #undef TARGET_ASM_ALIGNED_HI_OP
9634 #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
9635 #undef TARGET_ASM_ALIGNED_SI_OP
9636 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
9637 #undef TARGET_ASM_ALIGNED_DI_OP
9638 #define TARGET_ASM_ALIGNED_DI_OP "\t.dword\t"
9640 #undef TARGET_OPTION_OVERRIDE
9641 #define TARGET_OPTION_OVERRIDE riscv_option_override
9643 #undef TARGET_LEGITIMIZE_ADDRESS
9644 #define TARGET_LEGITIMIZE_ADDRESS riscv_legitimize_address
9646 #undef TARGET_SCHED_ISSUE_RATE
9647 #define TARGET_SCHED_ISSUE_RATE riscv_issue_rate
9649 #undef TARGET_SCHED_VARIABLE_ISSUE
9650 #define TARGET_SCHED_VARIABLE_ISSUE riscv_sched_variable_issue
9652 #undef TARGET_SCHED_ADJUST_COST
9653 #define TARGET_SCHED_ADJUST_COST riscv_sched_adjust_cost
9655 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
9656 #define TARGET_FUNCTION_OK_FOR_SIBCALL riscv_function_ok_for_sibcall
9658 #undef TARGET_SET_CURRENT_FUNCTION
9659 #define TARGET_SET_CURRENT_FUNCTION riscv_set_current_function
9661 #undef TARGET_REGISTER_MOVE_COST
9662 #define TARGET_REGISTER_MOVE_COST riscv_register_move_cost
9663 #undef TARGET_MEMORY_MOVE_COST
9664 #define TARGET_MEMORY_MOVE_COST riscv_memory_move_cost
9665 #undef TARGET_RTX_COSTS
9666 #define TARGET_RTX_COSTS riscv_rtx_costs
9667 #undef TARGET_ADDRESS_COST
9668 #define TARGET_ADDRESS_COST riscv_address_cost
9670 #undef TARGET_ASM_FILE_START
9671 #define TARGET_ASM_FILE_START riscv_file_start
9672 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
9673 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
9674 #undef TARGET_ASM_FILE_END
9675 #define TARGET_ASM_FILE_END file_end_indicate_exec_stack
9677 #undef TARGET_EXPAND_BUILTIN_VA_START
9678 #define TARGET_EXPAND_BUILTIN_VA_START riscv_va_start
9680 #undef TARGET_PROMOTE_FUNCTION_MODE
9681 #define TARGET_PROMOTE_FUNCTION_MODE riscv_promote_function_mode
9683 #undef TARGET_RETURN_IN_MEMORY
9684 #define TARGET_RETURN_IN_MEMORY riscv_return_in_memory
9686 #undef TARGET_ASM_OUTPUT_MI_THUNK
9687 #define TARGET_ASM_OUTPUT_MI_THUNK riscv_output_mi_thunk
9688 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
9689 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
9691 #undef TARGET_PRINT_OPERAND
9692 #define TARGET_PRINT_OPERAND riscv_print_operand
9693 #undef TARGET_PRINT_OPERAND_ADDRESS
9694 #define TARGET_PRINT_OPERAND_ADDRESS riscv_print_operand_address
9695 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
9696 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P riscv_print_operand_punct_valid_p
9698 #undef TARGET_SETUP_INCOMING_VARARGS
9699 #define TARGET_SETUP_INCOMING_VARARGS riscv_setup_incoming_varargs
9700 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
9701 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS riscv_allocate_stack_slots_for_args
9702 #undef TARGET_STRICT_ARGUMENT_NAMING
9703 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
9704 #undef TARGET_MUST_PASS_IN_STACK
9705 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
9706 #undef TARGET_PASS_BY_REFERENCE
9707 #define TARGET_PASS_BY_REFERENCE riscv_pass_by_reference
9708 #undef TARGET_ARG_PARTIAL_BYTES
9709 #define TARGET_ARG_PARTIAL_BYTES riscv_arg_partial_bytes
9710 #undef TARGET_FUNCTION_ARG
9711 #define TARGET_FUNCTION_ARG riscv_function_arg
9712 #undef TARGET_FUNCTION_ARG_ADVANCE
9713 #define TARGET_FUNCTION_ARG_ADVANCE riscv_function_arg_advance
9714 #undef TARGET_FUNCTION_ARG_BOUNDARY
9715 #define TARGET_FUNCTION_ARG_BOUNDARY riscv_function_arg_boundary
9716 #undef TARGET_FNTYPE_ABI
9717 #define TARGET_FNTYPE_ABI riscv_fntype_abi
9718 #undef TARGET_INSN_CALLEE_ABI
9719 #define TARGET_INSN_CALLEE_ABI riscv_insn_callee_abi
9721 #undef TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS
9722 #define TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS \
9723 riscv_get_separate_components
9725 #undef TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB
9726 #define TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB \
9727 riscv_components_for_bb
9729 #undef TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS
9730 #define TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS \
9731 riscv_disqualify_components
9733 #undef TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS
9734 #define TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS \
9735 riscv_emit_prologue_components
9737 #undef TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS
9738 #define TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS \
9739 riscv_emit_epilogue_components
9741 #undef TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS
9742 #define TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS \
9743 riscv_set_handled_components
9745 /* The generic ELF target does not always have TLS support. */
9747 #undef TARGET_HAVE_TLS
9748 #define TARGET_HAVE_TLS true
9751 #undef TARGET_CANNOT_FORCE_CONST_MEM
9752 #define TARGET_CANNOT_FORCE_CONST_MEM riscv_cannot_force_const_mem
9754 #undef TARGET_LEGITIMATE_CONSTANT_P
9755 #define TARGET_LEGITIMATE_CONSTANT_P riscv_legitimate_constant_p
9757 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
9758 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P hook_bool_mode_const_rtx_true
9760 #undef TARGET_LEGITIMATE_ADDRESS_P
9761 #define TARGET_LEGITIMATE_ADDRESS_P riscv_legitimate_address_p
9763 #undef TARGET_CAN_ELIMINATE
9764 #define TARGET_CAN_ELIMINATE riscv_can_eliminate
9766 #undef TARGET_CONDITIONAL_REGISTER_USAGE
9767 #define TARGET_CONDITIONAL_REGISTER_USAGE riscv_conditional_register_usage
9769 #undef TARGET_CLASS_MAX_NREGS
9770 #define TARGET_CLASS_MAX_NREGS riscv_class_max_nregs
9772 #undef TARGET_TRAMPOLINE_INIT
9773 #define TARGET_TRAMPOLINE_INIT riscv_trampoline_init
9775 #undef TARGET_IN_SMALL_DATA_P
9776 #define TARGET_IN_SMALL_DATA_P riscv_in_small_data_p
9778 #undef TARGET_HAVE_SRODATA_SECTION
9779 #define TARGET_HAVE_SRODATA_SECTION true
9781 #undef TARGET_ASM_SELECT_SECTION
9782 #define TARGET_ASM_SELECT_SECTION riscv_select_section
9784 #undef TARGET_ASM_UNIQUE_SECTION
9785 #define TARGET_ASM_UNIQUE_SECTION riscv_unique_section
9787 #undef TARGET_ASM_SELECT_RTX_SECTION
9788 #define TARGET_ASM_SELECT_RTX_SECTION riscv_elf_select_rtx_section
9790 #undef TARGET_MIN_ANCHOR_OFFSET
9791 #define TARGET_MIN_ANCHOR_OFFSET (-IMM_REACH/2)
9793 #undef TARGET_MAX_ANCHOR_OFFSET
9794 #define TARGET_MAX_ANCHOR_OFFSET (IMM_REACH/2-1)
9796 #undef TARGET_REGISTER_PRIORITY
9797 #define TARGET_REGISTER_PRIORITY riscv_register_priority
9799 #undef TARGET_CANNOT_COPY_INSN_P
9800 #define TARGET_CANNOT_COPY_INSN_P riscv_cannot_copy_insn_p
9802 #undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
9803 #define TARGET_ATOMIC_ASSIGN_EXPAND_FENV riscv_atomic_assign_expand_fenv
9805 #undef TARGET_INIT_BUILTINS
9806 #define TARGET_INIT_BUILTINS riscv_init_builtins
9808 #undef TARGET_BUILTIN_DECL
9809 #define TARGET_BUILTIN_DECL riscv_builtin_decl
9811 #undef TARGET_GIMPLE_FOLD_BUILTIN
9812 #define TARGET_GIMPLE_FOLD_BUILTIN riscv_gimple_fold_builtin
9814 #undef TARGET_EXPAND_BUILTIN
9815 #define TARGET_EXPAND_BUILTIN riscv_expand_builtin
9817 #undef TARGET_HARD_REGNO_NREGS
9818 #define TARGET_HARD_REGNO_NREGS riscv_hard_regno_nregs
9819 #undef TARGET_HARD_REGNO_MODE_OK
9820 #define TARGET_HARD_REGNO_MODE_OK riscv_hard_regno_mode_ok
9822 #undef TARGET_MODES_TIEABLE_P
9823 #define TARGET_MODES_TIEABLE_P riscv_modes_tieable_p
9825 #undef TARGET_SLOW_UNALIGNED_ACCESS
9826 #define TARGET_SLOW_UNALIGNED_ACCESS riscv_slow_unaligned_access
9828 #undef TARGET_SECONDARY_MEMORY_NEEDED
9829 #define TARGET_SECONDARY_MEMORY_NEEDED riscv_secondary_memory_needed
9831 #undef TARGET_CAN_CHANGE_MODE_CLASS
9832 #define TARGET_CAN_CHANGE_MODE_CLASS riscv_can_change_mode_class
9834 #undef TARGET_CONSTANT_ALIGNMENT
9835 #define TARGET_CONSTANT_ALIGNMENT riscv_constant_alignment
9837 #undef TARGET_MERGE_DECL_ATTRIBUTES
9838 #define TARGET_MERGE_DECL_ATTRIBUTES riscv_merge_decl_attributes
9840 #undef TARGET_ATTRIBUTE_TABLE
9841 #define TARGET_ATTRIBUTE_TABLE riscv_attribute_table
9843 #undef TARGET_WARN_FUNC_RETURN
9844 #define TARGET_WARN_FUNC_RETURN riscv_warn_func_return
9846 /* The low bit is ignored by jump instructions so is safe to use. */
9847 #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
9848 #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 1
9850 #undef TARGET_MACHINE_DEPENDENT_REORG
9851 #define TARGET_MACHINE_DEPENDENT_REORG riscv_reorg
9853 #undef TARGET_NEW_ADDRESS_PROFITABLE_P
9854 #define TARGET_NEW_ADDRESS_PROFITABLE_P riscv_new_address_profitable_p
9856 #undef TARGET_MANGLE_TYPE
9857 #define TARGET_MANGLE_TYPE riscv_mangle_type
9859 #undef TARGET_SCALAR_MODE_SUPPORTED_P
9860 #define TARGET_SCALAR_MODE_SUPPORTED_P riscv_scalar_mode_supported_p
9862 #undef TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P
9863 #define TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P \
9864 riscv_libgcc_floating_mode_supported_p
9866 #undef TARGET_INIT_LIBFUNCS
9867 #define TARGET_INIT_LIBFUNCS riscv_init_libfuncs
9869 #undef TARGET_C_EXCESS_PRECISION
9870 #define TARGET_C_EXCESS_PRECISION riscv_excess_precision
9872 #undef TARGET_FLOATN_MODE
9873 #define TARGET_FLOATN_MODE riscv_floatn_mode
9875 #undef TARGET_ASAN_SHADOW_OFFSET
9876 #define TARGET_ASAN_SHADOW_OFFSET riscv_asan_shadow_offset
9878 #ifdef TARGET_BIG_ENDIAN_DEFAULT
9879 #undef TARGET_DEFAULT_TARGET_FLAGS
9880 #define TARGET_DEFAULT_TARGET_FLAGS (MASK_BIG_ENDIAN)
9883 #undef TARGET_VECTOR_MODE_SUPPORTED_P
9884 #define TARGET_VECTOR_MODE_SUPPORTED_P riscv_vector_mode_supported_p
9886 #undef TARGET_VERIFY_TYPE_CONTEXT
9887 #define TARGET_VERIFY_TYPE_CONTEXT riscv_verify_type_context
9889 #undef TARGET_ESTIMATED_POLY_VALUE
9890 #define TARGET_ESTIMATED_POLY_VALUE riscv_estimated_poly_value
9892 #undef TARGET_VECTORIZE_GET_MASK_MODE
9893 #define TARGET_VECTORIZE_GET_MASK_MODE riscv_get_mask_mode
9895 #undef TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE
9896 #define TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE riscv_empty_mask_is_expensive
9898 #undef TARGET_VECTOR_ALIGNMENT
9899 #define TARGET_VECTOR_ALIGNMENT riscv_vector_alignment
9901 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
9902 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT riscv_support_vector_misalignment
9904 #undef TARGET_DWARF_POLY_INDETERMINATE_VALUE
9905 #define TARGET_DWARF_POLY_INDETERMINATE_VALUE riscv_dwarf_poly_indeterminate_value
9907 #undef TARGET_ZERO_CALL_USED_REGS
9908 #define TARGET_ZERO_CALL_USED_REGS riscv_zero_call_used_regs
9910 #undef TARGET_ARRAY_MODE
9911 #define TARGET_ARRAY_MODE riscv_array_mode
9913 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
9914 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE riscv_preferred_simd_mode
9916 #undef TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT
9917 #define TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT \
9918 riscv_vectorize_preferred_vector_alignment
9920 /* Mode switching hooks. */
9922 #undef TARGET_MODE_EMIT
9923 #define TARGET_MODE_EMIT riscv_emit_mode_set
9924 #undef TARGET_MODE_NEEDED
9925 #define TARGET_MODE_NEEDED riscv_mode_needed
9926 #undef TARGET_MODE_AFTER
9927 #define TARGET_MODE_AFTER riscv_mode_after
9928 #undef TARGET_MODE_ENTRY
9929 #define TARGET_MODE_ENTRY riscv_mode_entry
9930 #undef TARGET_MODE_EXIT
9931 #define TARGET_MODE_EXIT riscv_mode_exit
9932 #undef TARGET_MODE_PRIORITY
9933 #define TARGET_MODE_PRIORITY riscv_mode_priority
9935 #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES
9936 #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES \
9937 riscv_autovectorize_vector_modes
9939 #undef TARGET_VECTORIZE_RELATED_MODE
9940 #define TARGET_VECTORIZE_RELATED_MODE riscv_vectorize_related_mode
9942 #undef TARGET_VECTORIZE_VEC_PERM_CONST
9943 #define TARGET_VECTORIZE_VEC_PERM_CONST riscv_vectorize_vec_perm_const
9945 #undef TARGET_FRAME_POINTER_REQUIRED
9946 #define TARGET_FRAME_POINTER_REQUIRED riscv_frame_pointer_required
9948 #undef TARGET_VECTORIZE_CREATE_COSTS
9949 #define TARGET_VECTORIZE_CREATE_COSTS riscv_vectorize_create_costs
9951 #undef TARGET_PREFERRED_ELSE_VALUE
9952 #define TARGET_PREFERRED_ELSE_VALUE riscv_preferred_else_value
9954 struct gcc_target targetm
= TARGET_INITIALIZER
;
9956 #include "gt-riscv.h"