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"
76 #include "target-globals.h"
78 /* This file should be included last. */
79 #include "target-def.h"
80 #include "riscv-vector-costs.h"
81 #include "riscv-subset.h"
83 /* True if X is an UNSPEC wrapper around a SYMBOL_REF or LABEL_REF. */
84 #define UNSPEC_ADDRESS_P(X) \
85 (GET_CODE (X) == UNSPEC \
86 && XINT (X, 1) >= UNSPEC_ADDRESS_FIRST \
87 && XINT (X, 1) < UNSPEC_ADDRESS_FIRST + NUM_SYMBOL_TYPES)
89 /* Extract the symbol or label from UNSPEC wrapper X. */
90 #define UNSPEC_ADDRESS(X) \
93 /* Extract the symbol type from UNSPEC wrapper X. */
94 #define UNSPEC_ADDRESS_TYPE(X) \
95 ((enum riscv_symbol_type) (XINT (X, 1) - UNSPEC_ADDRESS_FIRST))
97 /* True if bit BIT is set in VALUE. */
98 #define BITSET_P(VALUE, BIT) (((VALUE) & (1ULL << (BIT))) != 0)
100 /* Extract the backup dynamic frm rtl. */
101 #define DYNAMIC_FRM_RTL(c) ((c)->machine->mode_sw_info.dynamic_frm)
103 /* True the mode switching has static frm, or false. */
104 #define STATIC_FRM_P(c) ((c)->machine->mode_sw_info.static_frm_p)
106 /* Information about a function's frame layout. */
107 struct GTY(()) riscv_frame_info
{
108 /* The size of the frame in bytes. */
109 poly_int64 total_size
;
111 /* Bit X is set if the function saves or restores GPR X. */
114 /* Likewise FPR X. */
117 /* Likewise for vector registers. */
120 /* How much the GPR save/restore routines adjust sp (or 0 if unused). */
121 unsigned save_libcall_adjustment
;
123 /* the minimum number of bytes, in multiples of 16-byte address increments,
124 required to cover the registers in a multi push & pop. */
125 unsigned multi_push_adj_base
;
127 /* the number of additional 16-byte address increments allocated for the stack
128 frame in a multi push & pop. */
129 unsigned multi_push_adj_addi
;
131 /* Offsets of fixed-point and floating-point save areas from frame bottom */
132 poly_int64 gp_sp_offset
;
133 poly_int64 fp_sp_offset
;
135 /* Top and bottom offsets of vector save areas from frame bottom. */
136 poly_int64 v_sp_offset_top
;
137 poly_int64 v_sp_offset_bottom
;
139 /* Offset of virtual frame pointer from stack pointer/frame bottom */
140 poly_int64 frame_pointer_offset
;
142 /* Offset of hard frame pointer from stack pointer/frame bottom */
143 poly_int64 hard_frame_pointer_offset
;
145 /* The offset of arg_pointer_rtx from the bottom of the frame. */
146 poly_int64 arg_pointer_offset
;
148 /* Reset this struct, clean all field to zero. */
152 enum riscv_privilege_levels
{
153 UNKNOWN_MODE
, USER_MODE
, SUPERVISOR_MODE
, MACHINE_MODE
156 struct GTY(()) mode_switching_info
{
157 /* The RTL variable which stores the dynamic FRM value. We always use this
158 RTX to restore dynamic FRM rounding mode in mode switching. */
161 /* The boolean variables indicates there is at least one static rounding
162 mode instruction in the function or not. */
165 mode_switching_info ()
167 dynamic_frm
= NULL_RTX
;
168 static_frm_p
= false;
172 struct GTY(()) machine_function
{
173 /* The number of extra stack bytes taken up by register varargs.
174 This area is allocated by the callee at the very top of the frame. */
177 /* True if current function is a naked function. */
180 /* True if current function is an interrupt function. */
181 bool interrupt_handler_p
;
182 /* For an interrupt handler, indicates the privilege level. */
183 enum riscv_privilege_levels interrupt_mode
;
185 /* True if attributes on current function have been checked. */
186 bool attributes_checked_p
;
188 /* True if RA must be saved because of a far jump. */
191 /* The current frame information, calculated by riscv_compute_frame_info. */
192 struct riscv_frame_info frame
;
194 /* The components already handled by separate shrink-wrapping, which should
195 not be considered by the prologue and epilogue. */
196 bool reg_is_wrapped_separately
[FIRST_PSEUDO_REGISTER
];
198 /* The mode swithching information for the FRM rounding modes. */
199 struct mode_switching_info mode_sw_info
;
202 /* Information about a single argument. */
203 struct riscv_arg_info
{
204 /* True if the argument is at least partially passed on the stack. */
207 /* The number of integer registers allocated to this argument. */
208 unsigned int num_gprs
;
210 /* The offset of the first register used, provided num_gprs is nonzero.
211 If passed entirely on the stack, the value is MAX_ARGS_IN_REGISTERS. */
212 unsigned int gpr_offset
;
214 /* The number of floating-point registers allocated to this argument. */
215 unsigned int num_fprs
;
217 /* The offset of the first register used, provided num_fprs is nonzero. */
218 unsigned int fpr_offset
;
220 /* The number of vector registers allocated to this argument. */
221 unsigned int num_vrs
;
223 /* The offset of the first register used, provided num_vrs is nonzero. */
224 unsigned int vr_offset
;
226 /* The number of mask registers allocated to this argument. */
227 unsigned int num_mrs
;
229 /* The offset of the first register used, provided num_mrs is nonzero. */
230 unsigned int mr_offset
;
233 /* One stage in a constant building sequence. These sequences have
237 A = A CODE[1] VALUE[1]
238 A = A CODE[2] VALUE[2]
241 where A is an accumulator, each CODE[i] is a binary rtl operation
242 and each VALUE[i] is a constant integer. CODE[0] is undefined. */
243 struct riscv_integer_op
{
245 unsigned HOST_WIDE_INT value
;
248 /* The largest number of operations needed to load an integer constant.
249 The worst case is LUI, ADDI, SLLI, ADDI, SLLI, ADDI, SLLI, ADDI. */
250 #define RISCV_MAX_INTEGER_OPS 8
252 enum riscv_fusion_pairs
254 RISCV_FUSE_NOTHING
= 0,
255 RISCV_FUSE_ZEXTW
= (1 << 0),
256 RISCV_FUSE_ZEXTH
= (1 << 1),
257 RISCV_FUSE_ZEXTWS
= (1 << 2),
258 RISCV_FUSE_LDINDEXED
= (1 << 3),
259 RISCV_FUSE_LUI_ADDI
= (1 << 4),
260 RISCV_FUSE_AUIPC_ADDI
= (1 << 5),
261 RISCV_FUSE_LUI_LD
= (1 << 6),
262 RISCV_FUSE_AUIPC_LD
= (1 << 7),
263 RISCV_FUSE_LDPREINCREMENT
= (1 << 8),
264 RISCV_FUSE_ALIGNED_STD
= (1 << 9),
267 /* Costs of various operations on the different architectures. */
269 struct riscv_tune_param
271 unsigned short fp_add
[2];
272 unsigned short fp_mul
[2];
273 unsigned short fp_div
[2];
274 unsigned short int_mul
[2];
275 unsigned short int_div
[2];
276 unsigned short issue_rate
;
277 unsigned short branch_cost
;
278 unsigned short memory_cost
;
279 unsigned short fmv_cost
;
280 bool slow_unaligned_access
;
281 bool use_divmod_expansion
;
282 unsigned int fusible_ops
;
286 /* Global variables for machine-dependent things. */
288 /* Whether unaligned accesses execute very slowly. */
289 bool riscv_slow_unaligned_access_p
;
291 /* Whether user explicitly passed -mstrict-align. */
292 bool riscv_user_wants_strict_align
;
294 /* Stack alignment to assume/maintain. */
295 unsigned riscv_stack_boundary
;
297 /* If non-zero, this is an offset to be added to SP to redefine the CFA
298 when restoring the FP register from the stack. Only valid when generating
300 static poly_int64 epilogue_cfa_sp_offset
;
302 /* Which tuning parameters to use. */
303 static const struct riscv_tune_param
*tune_param
;
305 /* Which automaton to use for tuning. */
306 enum riscv_microarchitecture_type riscv_microarchitecture
;
308 /* The number of chunks in a single vector register. */
309 poly_uint16 riscv_vector_chunks
;
311 /* The number of bytes in a vector chunk. */
312 unsigned riscv_bytes_per_vector_chunk
;
314 /* Index R is the smallest register class that contains register R. */
315 const enum reg_class riscv_regno_to_class
[FIRST_PSEUDO_REGISTER
] = {
316 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
317 GR_REGS
, GR_REGS
, SIBCALL_REGS
, SIBCALL_REGS
,
318 JALR_REGS
, JALR_REGS
, SIBCALL_REGS
, SIBCALL_REGS
,
319 SIBCALL_REGS
, SIBCALL_REGS
, SIBCALL_REGS
, SIBCALL_REGS
,
320 SIBCALL_REGS
, SIBCALL_REGS
, JALR_REGS
, JALR_REGS
,
321 JALR_REGS
, JALR_REGS
, JALR_REGS
, JALR_REGS
,
322 JALR_REGS
, JALR_REGS
, JALR_REGS
, JALR_REGS
,
323 SIBCALL_REGS
, SIBCALL_REGS
, SIBCALL_REGS
, SIBCALL_REGS
,
324 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
325 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
326 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
327 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
328 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
329 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
330 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
331 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
332 FRAME_REGS
, FRAME_REGS
, NO_REGS
, NO_REGS
,
333 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
334 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
335 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
336 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
337 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
338 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
339 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
340 VM_REGS
, VD_REGS
, VD_REGS
, VD_REGS
,
341 VD_REGS
, VD_REGS
, VD_REGS
, VD_REGS
,
342 VD_REGS
, VD_REGS
, VD_REGS
, VD_REGS
,
343 VD_REGS
, VD_REGS
, VD_REGS
, VD_REGS
,
344 VD_REGS
, VD_REGS
, VD_REGS
, VD_REGS
,
345 VD_REGS
, VD_REGS
, VD_REGS
, VD_REGS
,
346 VD_REGS
, VD_REGS
, VD_REGS
, VD_REGS
,
347 VD_REGS
, VD_REGS
, VD_REGS
, VD_REGS
,
350 /* Costs to use when optimizing for rocket. */
351 static const struct riscv_tune_param rocket_tune_info
= {
352 {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_add */
353 {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_mul */
354 {COSTS_N_INSNS (20), COSTS_N_INSNS (20)}, /* fp_div */
355 {COSTS_N_INSNS (4), COSTS_N_INSNS (4)}, /* int_mul */
356 {COSTS_N_INSNS (33), COSTS_N_INSNS (65)}, /* int_div */
361 true, /* slow_unaligned_access */
362 false, /* use_divmod_expansion */
363 RISCV_FUSE_NOTHING
, /* fusible_ops */
366 /* Costs to use when optimizing for Sifive 7 Series. */
367 static const struct riscv_tune_param sifive_7_tune_info
= {
368 {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_add */
369 {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_mul */
370 {COSTS_N_INSNS (20), COSTS_N_INSNS (20)}, /* fp_div */
371 {COSTS_N_INSNS (4), COSTS_N_INSNS (4)}, /* int_mul */
372 {COSTS_N_INSNS (33), COSTS_N_INSNS (65)}, /* int_div */
377 true, /* slow_unaligned_access */
378 false, /* use_divmod_expansion */
379 RISCV_FUSE_NOTHING
, /* fusible_ops */
382 /* Costs to use when optimizing for T-HEAD c906. */
383 static const struct riscv_tune_param thead_c906_tune_info
= {
384 {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_add */
385 {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_mul */
386 {COSTS_N_INSNS (20), COSTS_N_INSNS (20)}, /* fp_div */
387 {COSTS_N_INSNS (4), COSTS_N_INSNS (4)}, /* int_mul */
388 {COSTS_N_INSNS (18), COSTS_N_INSNS (34)}, /* int_div */
393 false, /* slow_unaligned_access */
394 false, /* use_divmod_expansion */
395 RISCV_FUSE_NOTHING
, /* fusible_ops */
398 /* Costs to use when optimizing for a generic ooo profile. */
399 static const struct riscv_tune_param generic_ooo_tune_info
= {
400 {COSTS_N_INSNS (2), COSTS_N_INSNS (2)}, /* fp_add */
401 {COSTS_N_INSNS (5), COSTS_N_INSNS (6)}, /* fp_mul */
402 {COSTS_N_INSNS (7), COSTS_N_INSNS (8)}, /* fp_div */
403 {COSTS_N_INSNS (2), COSTS_N_INSNS (2)}, /* int_mul */
404 {COSTS_N_INSNS (6), COSTS_N_INSNS (6)}, /* int_div */
409 false, /* slow_unaligned_access */
410 false, /* use_divmod_expansion */
411 RISCV_FUSE_NOTHING
, /* fusible_ops */
414 /* Costs to use when optimizing for size. */
415 static const struct riscv_tune_param optimize_size_tune_info
= {
416 {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* fp_add */
417 {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* fp_mul */
418 {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* fp_div */
419 {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* int_mul */
420 {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* int_div */
425 false, /* slow_unaligned_access */
426 false, /* use_divmod_expansion */
427 RISCV_FUSE_NOTHING
, /* fusible_ops */
430 static bool riscv_avoid_shrink_wrapping_separate ();
431 static tree
riscv_handle_fndecl_attribute (tree
*, tree
, tree
, int, bool *);
432 static tree
riscv_handle_type_attribute (tree
*, tree
, tree
, int, bool *);
433 static void riscv_legitimize_poly_move (machine_mode
, rtx
, rtx
, rtx
);
435 /* Defining target-specific uses of __attribute__. */
436 static const struct attribute_spec riscv_attribute_table
[] =
438 /* Syntax: { name, min_len, max_len, decl_required, type_required,
439 function_type_required, affects_type_identity, handler,
442 /* The attribute telling no prologue/epilogue. */
443 { "naked", 0, 0, true, false, false, false,
444 riscv_handle_fndecl_attribute
, NULL
},
445 /* This attribute generates prologue/epilogue for interrupt handlers. */
446 { "interrupt", 0, 1, false, true, true, false,
447 riscv_handle_type_attribute
, NULL
},
449 /* The following two are used for the built-in properties of the Vector type
450 and are not used externally */
451 {"RVV sizeless type", 4, 4, false, true, false, true, NULL
, NULL
},
452 {"RVV type", 0, 0, false, true, false, true, NULL
, NULL
},
454 /* The last attribute spec is set to be NULL. */
455 { NULL
, 0, 0, false, false, false, false, NULL
, NULL
}
458 /* Order for the CLOBBERs/USEs of gpr_save. */
459 static const unsigned gpr_save_reg_order
[] = {
460 INVALID_REGNUM
, T0_REGNUM
, T1_REGNUM
, RETURN_ADDR_REGNUM
,
461 S0_REGNUM
, S1_REGNUM
, S2_REGNUM
, S3_REGNUM
, S4_REGNUM
,
462 S5_REGNUM
, S6_REGNUM
, S7_REGNUM
, S8_REGNUM
, S9_REGNUM
,
463 S10_REGNUM
, S11_REGNUM
466 /* A table describing all the processors GCC knows about. */
467 static const struct riscv_tune_info riscv_tune_info_table
[] = {
468 #define RISCV_TUNE(TUNE_NAME, PIPELINE_MODEL, TUNE_INFO) \
469 { TUNE_NAME, PIPELINE_MODEL, & TUNE_INFO},
470 #include "riscv-cores.def"
473 /* Global variable to distinguish whether we should save and restore s0/fp for
475 static bool riscv_save_frame_pointer
;
486 typedef insn_code (*code_for_push_pop_t
) (machine_mode
);
488 void riscv_frame_info::reset(void)
494 save_libcall_adjustment
= 0;
499 v_sp_offset_bottom
= 0;
501 frame_pointer_offset
= 0;
503 hard_frame_pointer_offset
= 0;
505 arg_pointer_offset
= 0;
508 /* Implement TARGET_MIN_ARITHMETIC_PRECISION. */
511 riscv_min_arithmetic_precision (void)
518 get_tune_str (const T
*opts
)
520 const char *tune_string
= RISCV_TUNE_STRING_DEFAULT
;
521 if (opts
->x_riscv_tune_string
)
522 tune_string
= opts
->x_riscv_tune_string
;
523 else if (opts
->x_riscv_cpu_string
)
524 tune_string
= opts
->x_riscv_cpu_string
;
528 /* Return the riscv_tune_info entry for the given name string, return nullptr
529 if NULL_P is true, otherwise return an placeholder and report error. */
531 const struct riscv_tune_info
*
532 riscv_parse_tune (const char *tune_string
, bool null_p
)
534 const riscv_cpu_info
*cpu
= riscv_find_cpu (tune_string
);
537 tune_string
= cpu
->tune
;
539 for (unsigned i
= 0; i
< ARRAY_SIZE (riscv_tune_info_table
); i
++)
540 if (strcmp (riscv_tune_info_table
[i
].name
, tune_string
) == 0)
541 return riscv_tune_info_table
+ i
;
546 error ("unknown cpu %qs for %<-mtune%>", tune_string
);
547 return riscv_tune_info_table
;
550 /* Helper function for riscv_build_integer; arguments are as for
551 riscv_build_integer. */
554 riscv_build_integer_1 (struct riscv_integer_op codes
[RISCV_MAX_INTEGER_OPS
],
555 HOST_WIDE_INT value
, machine_mode mode
)
557 HOST_WIDE_INT low_part
= CONST_LOW_PART (value
);
558 int cost
= RISCV_MAX_INTEGER_OPS
+ 1, alt_cost
;
559 struct riscv_integer_op alt_codes
[RISCV_MAX_INTEGER_OPS
];
561 if (SMALL_OPERAND (value
) || LUI_OPERAND (value
))
563 /* Simply ADDI or LUI. */
564 codes
[0].code
= UNKNOWN
;
565 codes
[0].value
= value
;
568 if (TARGET_ZBS
&& SINGLE_BIT_MASK_OPERAND (value
))
571 codes
[0].code
= UNKNOWN
;
572 codes
[0].value
= value
;
574 /* RISC-V sign-extends all 32bit values that live in a 32bit
575 register. To avoid paradoxes, we thus need to use the
576 sign-extended (negative) representation (-1 << 31) for the
577 value, if we want to build (1 << 31) in SImode. This will
578 then expand to an LUI instruction. */
579 if (TARGET_64BIT
&& mode
== SImode
&& value
== (HOST_WIDE_INT_1U
<< 31))
580 codes
[0].value
= (HOST_WIDE_INT_M1U
<< 31);
585 /* End with ADDI. When constructing HImode constants, do not generate any
586 intermediate value that is not itself a valid HImode constant. The
587 XORI case below will handle those remaining HImode constants. */
590 || value
- low_part
<= ((1 << (GET_MODE_BITSIZE (HImode
) - 1)) - 1)))
592 HOST_WIDE_INT upper_part
= value
- low_part
;
593 if (mode
!= VOIDmode
)
594 upper_part
= trunc_int_for_mode (value
- low_part
, mode
);
596 alt_cost
= 1 + riscv_build_integer_1 (alt_codes
, upper_part
, mode
);
599 alt_codes
[alt_cost
-1].code
= PLUS
;
600 alt_codes
[alt_cost
-1].value
= low_part
;
601 memcpy (codes
, alt_codes
, sizeof (alt_codes
));
607 if (cost
> 2 && (low_part
< 0 || mode
== HImode
))
609 alt_cost
= 1 + riscv_build_integer_1 (alt_codes
, value
^ low_part
, mode
);
612 alt_codes
[alt_cost
-1].code
= XOR
;
613 alt_codes
[alt_cost
-1].value
= low_part
;
614 memcpy (codes
, alt_codes
, sizeof (alt_codes
));
619 /* Eliminate trailing zeros and end with SLLI. */
620 if (cost
> 2 && (value
& 1) == 0)
622 int shift
= ctz_hwi (value
);
623 unsigned HOST_WIDE_INT x
= value
;
624 x
= sext_hwi (x
>> shift
, HOST_BITS_PER_WIDE_INT
- shift
);
626 /* Don't eliminate the lower 12 bits if LUI might apply. */
627 if (shift
> IMM_BITS
&& !SMALL_OPERAND (x
) && LUI_OPERAND (x
<< IMM_BITS
))
628 shift
-= IMM_BITS
, x
<<= IMM_BITS
;
630 alt_cost
= 1 + riscv_build_integer_1 (alt_codes
, x
, mode
);
633 alt_codes
[alt_cost
-1].code
= ASHIFT
;
634 alt_codes
[alt_cost
-1].value
= shift
;
635 memcpy (codes
, alt_codes
, sizeof (alt_codes
));
640 if (cost
> 2 && TARGET_64BIT
&& (TARGET_ZBB
|| TARGET_XTHEADBB
))
642 int leading_ones
= clz_hwi (~value
);
643 int trailing_ones
= ctz_hwi (~value
);
645 /* If all bits are one except a few that are zero, and the zero bits
646 are within a range of 11 bits, then we can synthesize a constant
647 by loading a small negative constant and rotating. */
648 if (leading_ones
< 64
649 && ((64 - leading_ones
- trailing_ones
) < 12))
651 codes
[0].code
= UNKNOWN
;
652 /* The sign-bit might be zero, so just rotate to be safe. */
653 codes
[0].value
= (((unsigned HOST_WIDE_INT
) value
>> trailing_ones
)
654 | (value
<< (64 - trailing_ones
)));
655 codes
[1].code
= ROTATERT
;
656 codes
[1].value
= 64 - trailing_ones
;
659 /* Handle the case where the 11 bit range of zero bits wraps around. */
662 int upper_trailing_ones
= ctz_hwi (~value
>> 32);
663 int lower_leading_ones
= clz_hwi (~value
<< 32);
665 if (upper_trailing_ones
< 32 && lower_leading_ones
< 32
666 && ((64 - upper_trailing_ones
- lower_leading_ones
) < 12))
668 codes
[0].code
= UNKNOWN
;
669 /* The sign-bit might be zero, so just rotate to be safe. */
670 codes
[0].value
= ((value
<< (32 - upper_trailing_ones
))
671 | ((unsigned HOST_WIDE_INT
) value
672 >> (32 + upper_trailing_ones
)));
673 codes
[1].code
= ROTATERT
;
674 codes
[1].value
= 32 - upper_trailing_ones
;
680 gcc_assert (cost
<= RISCV_MAX_INTEGER_OPS
);
684 /* Fill CODES with a sequence of rtl operations to load VALUE.
685 Return the number of operations needed. */
688 riscv_build_integer (struct riscv_integer_op
*codes
, HOST_WIDE_INT value
,
691 int cost
= riscv_build_integer_1 (codes
, value
, mode
);
693 /* Eliminate leading zeros and end with SRLI. */
694 if (value
> 0 && cost
> 2)
696 struct riscv_integer_op alt_codes
[RISCV_MAX_INTEGER_OPS
];
697 int alt_cost
, shift
= clz_hwi (value
);
698 HOST_WIDE_INT shifted_val
;
700 /* Try filling trailing bits with 1s. */
701 shifted_val
= (value
<< shift
) | ((((HOST_WIDE_INT
) 1) << shift
) - 1);
702 alt_cost
= 1 + riscv_build_integer_1 (alt_codes
, shifted_val
, mode
);
705 alt_codes
[alt_cost
-1].code
= LSHIFTRT
;
706 alt_codes
[alt_cost
-1].value
= shift
;
707 memcpy (codes
, alt_codes
, sizeof (alt_codes
));
711 /* Try filling trailing bits with 0s. */
712 shifted_val
= value
<< shift
;
713 alt_cost
= 1 + riscv_build_integer_1 (alt_codes
, shifted_val
, mode
);
716 alt_codes
[alt_cost
-1].code
= LSHIFTRT
;
717 alt_codes
[alt_cost
-1].value
= shift
;
718 memcpy (codes
, alt_codes
, sizeof (alt_codes
));
724 && (value
> INT32_MAX
|| value
< INT32_MIN
))
726 unsigned HOST_WIDE_INT loval
= sext_hwi (value
, 32);
727 unsigned HOST_WIDE_INT hival
= sext_hwi ((value
- loval
) >> 32, 32);
728 struct riscv_integer_op alt_codes
[RISCV_MAX_INTEGER_OPS
];
729 struct riscv_integer_op hicode
[RISCV_MAX_INTEGER_OPS
];
730 int hi_cost
, lo_cost
;
732 hi_cost
= riscv_build_integer_1 (hicode
, hival
, mode
);
735 lo_cost
= riscv_build_integer_1 (alt_codes
, loval
, mode
);
736 if (lo_cost
+ hi_cost
< cost
)
738 memcpy (codes
, alt_codes
,
739 lo_cost
* sizeof (struct riscv_integer_op
));
740 memcpy (codes
+ lo_cost
, hicode
,
741 hi_cost
* sizeof (struct riscv_integer_op
));
742 cost
= lo_cost
+ hi_cost
;
750 /* Return the cost of constructing VAL in the event that a scratch
751 register is available. */
754 riscv_split_integer_cost (HOST_WIDE_INT val
)
757 unsigned HOST_WIDE_INT loval
= sext_hwi (val
, 32);
758 unsigned HOST_WIDE_INT hival
= sext_hwi ((val
- loval
) >> 32, 32);
759 struct riscv_integer_op codes
[RISCV_MAX_INTEGER_OPS
];
761 cost
= 2 + riscv_build_integer (codes
, loval
, VOIDmode
);
763 cost
+= riscv_build_integer (codes
, hival
, VOIDmode
);
768 /* Return the cost of constructing the integer constant VAL. */
771 riscv_integer_cost (HOST_WIDE_INT val
)
773 struct riscv_integer_op codes
[RISCV_MAX_INTEGER_OPS
];
774 return MIN (riscv_build_integer (codes
, val
, VOIDmode
),
775 riscv_split_integer_cost (val
));
778 /* Try to split a 64b integer into 32b parts, then reassemble. */
781 riscv_split_integer (HOST_WIDE_INT val
, machine_mode mode
)
783 unsigned HOST_WIDE_INT loval
= sext_hwi (val
, 32);
784 unsigned HOST_WIDE_INT hival
= sext_hwi ((val
- loval
) >> 32, 32);
785 rtx hi
= gen_reg_rtx (mode
), lo
= gen_reg_rtx (mode
);
787 riscv_move_integer (lo
, lo
, loval
, mode
);
790 hi
= gen_rtx_ASHIFT (mode
, lo
, GEN_INT (32));
793 riscv_move_integer (hi
, hi
, hival
, mode
);
794 hi
= gen_rtx_ASHIFT (mode
, hi
, GEN_INT (32));
797 hi
= force_reg (mode
, hi
);
798 return gen_rtx_PLUS (mode
, hi
, lo
);
801 /* Return true if X is a thread-local symbol. */
804 riscv_tls_symbol_p (const_rtx x
)
806 return SYMBOL_REF_P (x
) && SYMBOL_REF_TLS_MODEL (x
) != 0;
809 /* Return true if symbol X binds locally. */
812 riscv_symbol_binds_local_p (const_rtx x
)
814 if (SYMBOL_REF_P (x
))
815 return (SYMBOL_REF_DECL (x
)
816 ? targetm
.binds_local_p (SYMBOL_REF_DECL (x
))
817 : SYMBOL_REF_LOCAL_P (x
));
822 /* Return the method that should be used to access SYMBOL_REF or
825 static enum riscv_symbol_type
826 riscv_classify_symbol (const_rtx x
)
828 if (riscv_tls_symbol_p (x
))
831 if (GET_CODE (x
) == SYMBOL_REF
&& flag_pic
&& !riscv_symbol_binds_local_p (x
))
832 return SYMBOL_GOT_DISP
;
834 return riscv_cmodel
== CM_MEDLOW
? SYMBOL_ABSOLUTE
: SYMBOL_PCREL
;
837 /* Classify the base of symbolic expression X. */
839 enum riscv_symbol_type
840 riscv_classify_symbolic_expression (rtx x
)
844 split_const (x
, &x
, &offset
);
845 if (UNSPEC_ADDRESS_P (x
))
846 return UNSPEC_ADDRESS_TYPE (x
);
848 return riscv_classify_symbol (x
);
851 /* Return true if X is a symbolic constant. If it is, store the type of
852 the symbol in *SYMBOL_TYPE. */
855 riscv_symbolic_constant_p (rtx x
, enum riscv_symbol_type
*symbol_type
)
859 split_const (x
, &x
, &offset
);
860 if (UNSPEC_ADDRESS_P (x
))
862 *symbol_type
= UNSPEC_ADDRESS_TYPE (x
);
863 x
= UNSPEC_ADDRESS (x
);
865 else if (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == LABEL_REF
)
866 *symbol_type
= riscv_classify_symbol (x
);
870 if (offset
== const0_rtx
)
873 /* Nonzero offsets are only valid for references that don't use the GOT. */
874 switch (*symbol_type
)
876 case SYMBOL_ABSOLUTE
:
879 /* GAS rejects offsets outside the range [-2^31, 2^31-1]. */
880 return sext_hwi (INTVAL (offset
), 32) == INTVAL (offset
);
887 /* Returns the number of instructions necessary to reference a symbol. */
889 static int riscv_symbol_insns (enum riscv_symbol_type type
)
893 case SYMBOL_TLS
: return 0; /* Depends on the TLS model. */
894 case SYMBOL_ABSOLUTE
: return 2; /* LUI + the reference. */
895 case SYMBOL_PCREL
: return 2; /* AUIPC + the reference. */
896 case SYMBOL_TLS_LE
: return 3; /* LUI + ADD TP + the reference. */
897 case SYMBOL_GOT_DISP
: return 3; /* AUIPC + LD GOT + the reference. */
898 default: gcc_unreachable ();
902 /* Immediate values loaded by the FLI.S instruction in Chapter 25 of the latest RISC-V ISA
903 Manual draft. For details, please see:
904 https://github.com/riscv/riscv-isa-manual/releases/tag/isa-449cd0c */
906 static unsigned HOST_WIDE_INT fli_value_hf
[32] =
908 0xbcp
8, 0x4p
8, 0x1p
8, 0x2p
8, 0x1cp
8, 0x20p
8, 0x2cp
8, 0x30p
8,
909 0x34p
8, 0x35p
8, 0x36p
8, 0x37p
8, 0x38p
8, 0x39p
8, 0x3ap
8, 0x3bp
8,
910 0x3cp
8, 0x3dp
8, 0x3ep
8, 0x3fp
8, 0x40p
8, 0x41p
8, 0x42p
8, 0x44p
8,
911 0x48p
8, 0x4cp
8, 0x58p
8, 0x5cp
8, 0x78p
8,
912 /* Only used for filling, ensuring that 29 and 30 of HF are the same. */
917 static unsigned HOST_WIDE_INT fli_value_sf
[32] =
919 0xbf8p
20, 0x008p
20, 0x378p
20, 0x380p
20, 0x3b8p
20, 0x3c0p
20, 0x3d8p
20, 0x3e0p
20,
920 0x3e8p
20, 0x3eap
20, 0x3ecp
20, 0x3eep
20, 0x3f0p
20, 0x3f2p
20, 0x3f4p
20, 0x3f6p
20,
921 0x3f8p
20, 0x3fap
20, 0x3fcp
20, 0x3fep
20, 0x400p
20, 0x402p
20, 0x404p
20, 0x408p
20,
922 0x410p
20, 0x418p
20, 0x430p
20, 0x438p
20, 0x470p
20, 0x478p
20, 0x7f8p
20, 0x7fcp
20
925 static unsigned HOST_WIDE_INT fli_value_df
[32] =
927 0xbff0p
48, 0x10p
48, 0x3ef0p
48, 0x3f00p
48,
928 0x3f70p
48, 0x3f80p
48, 0x3fb0p
48, 0x3fc0p
48,
929 0x3fd0p
48, 0x3fd4p
48, 0x3fd8p
48, 0x3fdcp
48,
930 0x3fe0p
48, 0x3fe4p
48, 0x3fe8p
48, 0x3fecp
48,
931 0x3ff0p
48, 0x3ff4p
48, 0x3ff8p
48, 0x3ffcp
48,
932 0x4000p
48, 0x4004p
48, 0x4008p
48, 0x4010p
48,
933 0x4020p
48, 0x4030p
48, 0x4060p
48, 0x4070p
48,
934 0x40e0p
48, 0x40f0p
48, 0x7ff0p
48, 0x7ff8p
48
937 /* Display floating-point values at the assembly level, which is consistent
938 with the zfa extension of llvm:
939 https://reviews.llvm.org/D145645. */
941 const char *fli_value_print
[32] =
943 "-1.0", "min", "1.52587890625e-05", "3.0517578125e-05", "0.00390625", "0.0078125", "0.0625", "0.125",
944 "0.25", "0.3125", "0.375", "0.4375", "0.5", "0.625", "0.75", "0.875",
945 "1.0", "1.25", "1.5", "1.75", "2.0", "2.5", "3.0", "4.0",
946 "8.0", "16.0", "128.0", "256.0", "32768.0", "65536.0", "inf", "nan"
949 /* Return index of the FLI instruction table if rtx X is an immediate constant that can
950 be moved using a single FLI instruction in zfa extension. Return -1 if not found. */
953 riscv_float_const_rtx_index_for_fli (rtx x
)
955 unsigned HOST_WIDE_INT
*fli_value_array
;
957 machine_mode mode
= GET_MODE (x
);
960 || !CONST_DOUBLE_P(x
)
962 || (mode
== HFmode
&& !(TARGET_ZFH
|| TARGET_ZVFH
))
963 || (mode
== SFmode
&& !TARGET_HARD_FLOAT
)
964 || (mode
== DFmode
&& !TARGET_DOUBLE_FLOAT
))
967 if (!SCALAR_FLOAT_MODE_P (mode
)
968 || GET_MODE_BITSIZE (mode
).to_constant () > HOST_BITS_PER_WIDE_INT
969 /* Only support up to DF mode. */
970 || GET_MODE_BITSIZE (mode
).to_constant () > GET_MODE_BITSIZE (DFmode
))
973 unsigned HOST_WIDE_INT ival
= 0;
977 CONST_DOUBLE_REAL_VALUE (x
),
978 REAL_MODE_FORMAT (mode
));
982 int order
= BYTES_BIG_ENDIAN
? 1 : 0;
983 ival
= zext_hwi (res
[order
], 32);
984 ival
|= (zext_hwi (res
[1 - order
], 32) << 32);
986 /* When the lower 32 bits are not all 0, it is impossible to be in the table. */
987 if (ival
& (unsigned HOST_WIDE_INT
)0xffffffff)
991 ival
= zext_hwi (res
[0], 32);
996 fli_value_array
= fli_value_hf
;
999 fli_value_array
= fli_value_sf
;
1002 fli_value_array
= fli_value_df
;
1008 if (fli_value_array
[0] == ival
)
1011 if (fli_value_array
[1] == ival
)
1014 /* Perform a binary search to find target index. */
1023 if (fli_value_array
[m
] == ival
)
1025 else if (fli_value_array
[m
] < ival
)
1034 /* Implement TARGET_LEGITIMATE_CONSTANT_P. */
1037 riscv_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED
, rtx x
)
1039 return riscv_const_insns (x
) > 0;
1042 /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
1045 riscv_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED
, rtx x
)
1047 enum riscv_symbol_type type
;
1050 /* There's no way to calculate VL-based values using relocations. */
1051 subrtx_iterator::array_type array
;
1052 FOR_EACH_SUBRTX (iter
, array
, x
, ALL
)
1053 if (GET_CODE (*iter
) == CONST_POLY_INT
)
1056 /* There is no assembler syntax for expressing an address-sized
1058 if (GET_CODE (x
) == HIGH
)
1061 if (satisfies_constraint_zfli (x
))
1064 split_const (x
, &base
, &offset
);
1065 if (riscv_symbolic_constant_p (base
, &type
))
1067 /* As an optimization, don't spill symbolic constants that are as
1068 cheap to rematerialize as to access in the constant pool. */
1069 if (SMALL_OPERAND (INTVAL (offset
)) && riscv_symbol_insns (type
) > 0)
1072 /* As an optimization, avoid needlessly generate dynamic relocations. */
1077 /* TLS symbols must be computed by riscv_legitimize_move. */
1078 if (tls_referenced_p (x
))
1084 /* Return true if register REGNO is a valid base register for mode MODE.
1085 STRICT_P is true if REG_OK_STRICT is in effect. */
1088 riscv_regno_mode_ok_for_base_p (int regno
,
1089 machine_mode mode ATTRIBUTE_UNUSED
,
1092 if (!HARD_REGISTER_NUM_P (regno
))
1096 regno
= reg_renumber
[regno
];
1099 /* These fake registers will be eliminated to either the stack or
1100 hard frame pointer, both of which are usually valid base registers.
1101 Reload deals with the cases where the eliminated form isn't valid. */
1102 if (regno
== ARG_POINTER_REGNUM
|| regno
== FRAME_POINTER_REGNUM
)
1105 return GP_REG_P (regno
);
1108 /* Get valid index register class.
1109 The RISC-V base instructions don't support index registers,
1110 but extensions might support that. */
1113 riscv_index_reg_class ()
1115 if (TARGET_XTHEADMEMIDX
|| TARGET_XTHEADFMEMIDX
)
1121 /* Return true if register REGNO is a valid index register.
1122 The RISC-V base instructions don't support index registers,
1123 but extensions might support that. */
1126 riscv_regno_ok_for_index_p (int regno
)
1128 if (TARGET_XTHEADMEMIDX
|| TARGET_XTHEADFMEMIDX
)
1129 return riscv_regno_mode_ok_for_base_p (regno
, VOIDmode
, 1);
1134 /* Return true if X is a valid base register for mode MODE.
1135 STRICT_P is true if REG_OK_STRICT is in effect. */
1138 riscv_valid_base_register_p (rtx x
, machine_mode mode
, bool strict_p
)
1140 if (!strict_p
&& GET_CODE (x
) == SUBREG
)
1144 && riscv_regno_mode_ok_for_base_p (REGNO (x
), mode
, strict_p
));
1147 /* Return true if, for every base register BASE_REG, (plus BASE_REG X)
1148 can address a value of mode MODE. */
1151 riscv_valid_offset_p (rtx x
, machine_mode mode
)
1153 /* Check that X is a signed 12-bit number. */
1154 if (!const_arith_operand (x
, Pmode
))
1157 /* We may need to split multiword moves, so make sure that every word
1159 if (GET_MODE_SIZE (mode
).to_constant () > UNITS_PER_WORD
1160 && !SMALL_OPERAND (INTVAL (x
) + GET_MODE_SIZE (mode
).to_constant () - UNITS_PER_WORD
))
1166 /* Should a symbol of type SYMBOL_TYPE should be split in two? */
1169 riscv_split_symbol_type (enum riscv_symbol_type symbol_type
)
1171 if (symbol_type
== SYMBOL_TLS_LE
)
1174 if (!TARGET_EXPLICIT_RELOCS
)
1177 return symbol_type
== SYMBOL_ABSOLUTE
|| symbol_type
== SYMBOL_PCREL
;
1180 /* Return true if a LO_SUM can address a value of mode MODE when the
1181 LO_SUM symbol has type SYM_TYPE. X is the LO_SUM second operand, which
1182 is used when the mode is BLKmode. */
1185 riscv_valid_lo_sum_p (enum riscv_symbol_type sym_type
, machine_mode mode
,
1190 /* Check that symbols of type SYMBOL_TYPE can be used to access values
1192 if (riscv_symbol_insns (sym_type
) == 0)
1195 /* Check that there is a known low-part relocation. */
1196 if (!riscv_split_symbol_type (sym_type
))
1199 /* We can't tell size or alignment when we have BLKmode, so try extracing a
1200 decl from the symbol if possible. */
1201 if (mode
== BLKmode
)
1205 /* Extract the symbol from the LO_SUM operand, if any. */
1206 split_const (x
, &x
, &offset
);
1208 /* Might be a CODE_LABEL. We can compute align but not size for that,
1209 so don't bother trying to handle it. */
1210 if (!SYMBOL_REF_P (x
))
1213 /* Use worst case assumptions if we don't have a SYMBOL_REF_DECL. */
1214 align
= (SYMBOL_REF_DECL (x
)
1215 ? DECL_ALIGN (SYMBOL_REF_DECL (x
))
1217 size
= (SYMBOL_REF_DECL (x
) && DECL_SIZE (SYMBOL_REF_DECL (x
))
1218 ? tree_to_uhwi (DECL_SIZE (SYMBOL_REF_DECL (x
)))
1223 align
= GET_MODE_ALIGNMENT (mode
);
1224 size
= GET_MODE_BITSIZE (mode
).to_constant ();
1227 /* We may need to split multiword moves, so make sure that each word
1228 can be accessed without inducing a carry. */
1229 if (size
> BITS_PER_WORD
1230 && (!TARGET_STRICT_ALIGN
|| size
> align
))
1236 /* Return true if mode is the RVV enabled mode.
1237 For example: 'RVVMF2SI' mode is disabled,
1238 wheras 'RVVM1SI' mode is enabled if MIN_VLEN == 32. */
1241 riscv_v_ext_vector_mode_p (machine_mode mode
)
1243 #define ENTRY(MODE, REQUIREMENT, ...) \
1248 #include "riscv-vector-switch.def"
1256 /* Return true if mode is the RVV enabled tuple mode. */
1259 riscv_v_ext_tuple_mode_p (machine_mode mode
)
1261 #define TUPLE_ENTRY(MODE, REQUIREMENT, ...) \
1266 #include "riscv-vector-switch.def"
1274 /* Return true if mode is the RVV enabled vls mode. */
1277 riscv_v_ext_vls_mode_p (machine_mode mode
)
1279 #define VLS_ENTRY(MODE, REQUIREMENT) \
1284 #include "riscv-vector-switch.def"
1292 /* Return true if it is either RVV vector mode or RVV tuple mode. */
1295 riscv_v_ext_mode_p (machine_mode mode
)
1297 return riscv_v_ext_vector_mode_p (mode
) || riscv_v_ext_tuple_mode_p (mode
)
1298 || riscv_v_ext_vls_mode_p (mode
);
1301 /* Call from ADJUST_NUNITS in riscv-modes.def. Return the correct
1302 NUNITS size for corresponding machine_mode. */
1305 riscv_v_adjust_nunits (machine_mode mode
, int scale
)
1307 gcc_assert (GET_MODE_CLASS (mode
) == MODE_VECTOR_BOOL
);
1308 if (riscv_v_ext_mode_p (mode
))
1310 if (TARGET_MIN_VLEN
== 32)
1312 return riscv_vector_chunks
* scale
;
1317 /* Call from ADJUST_NUNITS in riscv-modes.def. Return the correct
1318 NUNITS size for corresponding machine_mode. */
1321 riscv_v_adjust_nunits (machine_mode mode
, bool fractional_p
, int lmul
, int nf
)
1323 if (riscv_v_ext_mode_p (mode
))
1325 scalar_mode smode
= GET_MODE_INNER (mode
);
1326 int size
= GET_MODE_SIZE (smode
);
1327 int nunits_per_chunk
= riscv_bytes_per_vector_chunk
/ size
;
1329 return nunits_per_chunk
/ lmul
* riscv_vector_chunks
* nf
;
1331 return nunits_per_chunk
* lmul
* riscv_vector_chunks
* nf
;
1333 /* Set the disabled RVV modes size as 1 by default. */
1337 /* Call from ADJUST_BYTESIZE in riscv-modes.def. Return the correct
1338 BYTE size for corresponding machine_mode. */
1341 riscv_v_adjust_bytesize (machine_mode mode
, int scale
)
1343 if (riscv_v_ext_vector_mode_p (mode
))
1345 poly_int64 nunits
= GET_MODE_NUNITS (mode
);
1346 poly_int64 mode_size
= GET_MODE_SIZE (mode
);
1348 if (maybe_eq (mode_size
, (uint16_t) -1))
1349 mode_size
= riscv_vector_chunks
* scale
;
1351 if (nunits
.coeffs
[0] > 8)
1352 return exact_div (nunits
, 8);
1353 else if (nunits
.is_constant ())
1356 return poly_int64 (1, 1);
1362 /* Call from ADJUST_PRECISION in riscv-modes.def. Return the correct
1363 PRECISION size for corresponding machine_mode. */
1366 riscv_v_adjust_precision (machine_mode mode
, int scale
)
1368 return riscv_v_adjust_nunits (mode
, scale
);
1371 /* Return true if X is a valid address for machine mode MODE. If it is,
1372 fill in INFO appropriately. STRICT_P is true if REG_OK_STRICT is in
1376 riscv_classify_address (struct riscv_address_info
*info
, rtx x
,
1377 machine_mode mode
, bool strict_p
)
1379 if (th_classify_address (info
, x
, mode
, strict_p
))
1382 switch (GET_CODE (x
))
1386 info
->type
= ADDRESS_REG
;
1388 info
->offset
= const0_rtx
;
1389 return riscv_valid_base_register_p (info
->reg
, mode
, strict_p
);
1392 /* RVV load/store disallow any offset. */
1393 if (riscv_v_ext_mode_p (mode
))
1396 info
->type
= ADDRESS_REG
;
1397 info
->reg
= XEXP (x
, 0);
1398 info
->offset
= XEXP (x
, 1);
1399 return (riscv_valid_base_register_p (info
->reg
, mode
, strict_p
)
1400 && riscv_valid_offset_p (info
->offset
, mode
));
1403 /* RVV load/store disallow LO_SUM. */
1404 if (riscv_v_ext_mode_p (mode
))
1407 info
->type
= ADDRESS_LO_SUM
;
1408 info
->reg
= XEXP (x
, 0);
1409 info
->offset
= XEXP (x
, 1);
1410 /* We have to trust the creator of the LO_SUM to do something vaguely
1411 sane. Target-independent code that creates a LO_SUM should also
1412 create and verify the matching HIGH. Target-independent code that
1413 adds an offset to a LO_SUM must prove that the offset will not
1414 induce a carry. Failure to do either of these things would be
1415 a bug, and we are not required to check for it here. The RISC-V
1416 backend itself should only create LO_SUMs for valid symbolic
1417 constants, with the high part being either a HIGH or a copy
1420 = riscv_classify_symbolic_expression (info
->offset
);
1421 return (riscv_valid_base_register_p (info
->reg
, mode
, strict_p
)
1422 && riscv_valid_lo_sum_p (info
->symbol_type
, mode
, info
->offset
));
1425 /* We only allow the const0_rtx for the RVV load/store. For example:
1426 +----------------------------------------------------------+
1428 | vsetvli zero,a1,e32,m1,ta,ma |
1429 | vle32.v v24,0(a5) <- propagate the const 0 to a5 here. |
1430 | vs1r.v v24,0(a0) |
1431 +----------------------------------------------------------+
1432 It can be folded to:
1433 +----------------------------------------------------------+
1434 | vsetvli zero,a1,e32,m1,ta,ma |
1435 | vle32.v v24,0(zero) |
1436 | vs1r.v v24,0(a0) |
1437 +----------------------------------------------------------+
1438 This behavior will benefit the underlying RVV auto vectorization. */
1439 if (riscv_v_ext_mode_p (mode
))
1440 return x
== const0_rtx
;
1442 /* Small-integer addresses don't occur very often, but they
1443 are legitimate if x0 is a valid base register. */
1444 info
->type
= ADDRESS_CONST_INT
;
1445 return SMALL_OPERAND (INTVAL (x
));
1452 /* Implement TARGET_LEGITIMATE_ADDRESS_P. */
1455 riscv_legitimate_address_p (machine_mode mode
, rtx x
, bool strict_p
,
1456 code_helper
= ERROR_MARK
)
1458 /* Disallow RVV modes base address.
1459 E.g. (mem:SI (subreg:DI (reg:V1DI 155) 0). */
1460 if (SUBREG_P (x
) && riscv_v_ext_mode_p (GET_MODE (SUBREG_REG (x
))))
1462 struct riscv_address_info addr
;
1464 return riscv_classify_address (&addr
, x
, mode
, strict_p
);
1467 /* Return true if hard reg REGNO can be used in compressed instructions. */
1470 riscv_compressed_reg_p (int regno
)
1472 /* x8-x15/f8-f15 are compressible registers. */
1473 return ((TARGET_RVC
|| TARGET_ZCA
)
1474 && (IN_RANGE (regno
, GP_REG_FIRST
+ 8, GP_REG_FIRST
+ 15)
1475 || IN_RANGE (regno
, FP_REG_FIRST
+ 8, FP_REG_FIRST
+ 15)));
1478 /* Return true if x is an unsigned 5-bit immediate scaled by 4. */
1481 riscv_compressed_lw_offset_p (rtx x
)
1483 return (CONST_INT_P (x
)
1484 && (INTVAL (x
) & 3) == 0
1485 && IN_RANGE (INTVAL (x
), 0, CSW_MAX_OFFSET
));
1488 /* Return true if load/store from/to address x can be compressed. */
1491 riscv_compressed_lw_address_p (rtx x
)
1493 struct riscv_address_info addr
;
1494 bool result
= riscv_classify_address (&addr
, x
, GET_MODE (x
),
1497 /* Return false if address is not compressed_reg + small_offset. */
1499 || addr
.type
!= ADDRESS_REG
1500 /* Before reload, assume all registers are OK. */
1501 || (reload_completed
1502 && !riscv_compressed_reg_p (REGNO (addr
.reg
))
1503 && addr
.reg
!= stack_pointer_rtx
)
1504 || !riscv_compressed_lw_offset_p (addr
.offset
))
1510 /* Return the number of instructions needed to load or store a value
1511 of mode MODE at address X. Return 0 if X isn't valid for MODE.
1512 Assume that multiword moves may need to be split into word moves
1513 if MIGHT_SPLIT_P, otherwise assume that a single load or store is
1517 riscv_address_insns (rtx x
, machine_mode mode
, bool might_split_p
)
1519 struct riscv_address_info addr
= {};
1522 if (!riscv_classify_address (&addr
, x
, mode
, false))
1524 /* This could be a pattern from the pic.md file. In which case we want
1525 this address to always have a cost of 3 to make it as expensive as the
1526 most expensive symbol. This prevents constant propagation from
1527 preferring symbols over register plus offset. */
1531 /* BLKmode is used for single unaligned loads and stores and should
1532 not count as a multiword mode. */
1533 if (!riscv_v_ext_vector_mode_p (mode
) && mode
!= BLKmode
&& might_split_p
)
1534 n
+= (GET_MODE_SIZE (mode
).to_constant () + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
1536 if (addr
.type
== ADDRESS_LO_SUM
)
1537 n
+= riscv_symbol_insns (addr
.symbol_type
) - 1;
1542 /* Return the number of instructions needed to load constant X.
1543 Return 0 if X isn't a valid constant. */
1546 riscv_const_insns (rtx x
)
1548 enum riscv_symbol_type symbol_type
;
1551 switch (GET_CODE (x
))
1554 if (!riscv_symbolic_constant_p (XEXP (x
, 0), &symbol_type
)
1555 || !riscv_split_symbol_type (symbol_type
))
1558 /* This is simply an LUI. */
1563 int cost
= riscv_integer_cost (INTVAL (x
));
1564 /* Force complicated constants to memory. */
1565 return cost
< 4 ? cost
: 0;
1569 /* See if we can use FMV directly. */
1570 if (satisfies_constraint_zfli (x
))
1573 /* We can use x0 to load floating-point zero. */
1574 return x
== CONST0_RTX (GET_MODE (x
)) ? 1 : 0;
1577 /* TODO: This is not accurate, we will need to
1578 adapt the COST of CONST_VECTOR in the future
1579 for the following cases:
1581 - 1. const duplicate vector with element value
1582 in range of [-16, 15].
1583 - 2. const duplicate vector with element value
1584 out range of [-16, 15].
1585 - 3. const series vector.
1587 if (riscv_v_ext_mode_p (GET_MODE (x
)))
1589 /* const series vector. */
1591 if (const_vec_series_p (x
, &base
, &step
))
1593 /* This is not accurate, we will need to adapt the COST
1594 * accurately according to BASE && STEP. */
1599 if (const_vec_duplicate_p (x
, &elt
))
1601 /* We don't allow CONST_VECTOR for DI vector on RV32
1602 system since the ELT constant value can not held
1603 within a single register to disable reload a DI
1604 register vec_duplicate into vmv.v.x. */
1605 scalar_mode smode
= GET_MODE_INNER (GET_MODE (x
));
1606 if (maybe_gt (GET_MODE_SIZE (smode
), UNITS_PER_WORD
)
1607 && !immediate_operand (elt
, Pmode
))
1609 /* Constants from -16 to 15 can be loaded with vmv.v.i.
1610 The Wc0, Wc1 constraints are already covered by the
1611 vi constraint so we do not need to check them here
1613 if (satisfies_constraint_vi (x
))
1616 /* Any int/FP constants can always be broadcast from a
1617 scalar register. Loading of a floating-point
1618 constant incurs a literal-pool access. Allow this in
1619 order to increase vectorization possibilities. */
1620 int n
= riscv_const_insns (elt
);
1621 if (CONST_DOUBLE_P (elt
))
1622 return 1 + 4; /* vfmv.v.f + memory access. */
1625 /* We need as many insns as it takes to load the constant
1626 into a GPR and one vmv.v.x. */
1630 return 1 + 4; /*vmv.v.x + memory access. */
1635 /* TODO: We may support more const vector in the future. */
1636 return x
== CONST0_RTX (GET_MODE (x
)) ? 1 : 0;
1640 /* See if we can refer to X directly. */
1641 if (riscv_symbolic_constant_p (x
, &symbol_type
))
1642 return riscv_symbol_insns (symbol_type
);
1644 /* Otherwise try splitting the constant into a base and offset. */
1645 split_const (x
, &x
, &offset
);
1648 int n
= riscv_const_insns (x
);
1650 return n
+ riscv_integer_cost (INTVAL (offset
));
1656 return riscv_symbol_insns (riscv_classify_symbol (x
));
1658 /* TODO: In RVV, we get CONST_POLY_INT by using csrr VLENB
1659 instruction and several scalar shift or mult instructions,
1660 it is so far unknown. We set it to 4 temporarily. */
1661 case CONST_POLY_INT
:
1669 /* X is a doubleword constant that can be handled by splitting it into
1670 two words and loading each word separately. Return the number of
1671 instructions required to do this. */
1674 riscv_split_const_insns (rtx x
)
1676 unsigned int low
, high
;
1678 low
= riscv_const_insns (riscv_subword (x
, false));
1679 high
= riscv_const_insns (riscv_subword (x
, true));
1680 gcc_assert (low
> 0 && high
> 0);
1684 /* Return the number of instructions needed to implement INSN,
1685 given that it loads from or stores to MEM. */
1688 riscv_load_store_insns (rtx mem
, rtx_insn
*insn
)
1694 gcc_assert (MEM_P (mem
));
1695 mode
= GET_MODE (mem
);
1697 /* Try to prove that INSN does not need to be split. */
1698 might_split_p
= true;
1699 if (GET_MODE_BITSIZE (mode
).to_constant () <= 32)
1700 might_split_p
= false;
1701 else if (GET_MODE_BITSIZE (mode
).to_constant () == 64)
1703 set
= single_set (insn
);
1704 if (set
&& !riscv_split_64bit_move_p (SET_DEST (set
), SET_SRC (set
)))
1705 might_split_p
= false;
1708 return riscv_address_insns (XEXP (mem
, 0), mode
, might_split_p
);
1711 /* Emit a move from SRC to DEST. Assume that the move expanders can
1712 handle all moves if !can_create_pseudo_p (). The distinction is
1713 important because, unlike emit_move_insn, the move expanders know
1714 how to force Pmode objects into the constant pool even when the
1715 constant pool address is not itself legitimate. */
1718 riscv_emit_move (rtx dest
, rtx src
)
1720 return (can_create_pseudo_p ()
1721 ? emit_move_insn (dest
, src
)
1722 : emit_move_insn_1 (dest
, src
));
1725 /* Emit an instruction of the form (set TARGET SRC). */
1728 riscv_emit_set (rtx target
, rtx src
)
1730 emit_insn (gen_rtx_SET (target
, src
));
1734 /* Emit an instruction of the form (set DEST (CODE X Y)). */
1737 riscv_emit_binary (enum rtx_code code
, rtx dest
, rtx x
, rtx y
)
1739 return riscv_emit_set (dest
, gen_rtx_fmt_ee (code
, GET_MODE (dest
), x
, y
));
1742 /* Compute (CODE X Y) and store the result in a new register
1743 of mode MODE. Return that new register. */
1746 riscv_force_binary (machine_mode mode
, enum rtx_code code
, rtx x
, rtx y
)
1748 return riscv_emit_binary (code
, gen_reg_rtx (mode
), x
, y
);
1752 riscv_swap_instruction (rtx inst
)
1754 gcc_assert (GET_MODE (inst
) == SImode
);
1755 if (BYTES_BIG_ENDIAN
)
1756 inst
= expand_unop (SImode
, bswap_optab
, inst
, gen_reg_rtx (SImode
), 1);
1760 /* Copy VALUE to a register and return that register. If new pseudos
1761 are allowed, copy it into a new register, otherwise use DEST. */
1764 riscv_force_temporary (rtx dest
, rtx value
)
1766 if (can_create_pseudo_p ())
1767 return force_reg (Pmode
, value
);
1770 riscv_emit_move (dest
, value
);
1775 /* Wrap symbol or label BASE in an UNSPEC address of type SYMBOL_TYPE,
1776 then add CONST_INT OFFSET to the result. */
1779 riscv_unspec_address_offset (rtx base
, rtx offset
,
1780 enum riscv_symbol_type symbol_type
)
1782 base
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, base
),
1783 UNSPEC_ADDRESS_FIRST
+ symbol_type
);
1784 if (offset
!= const0_rtx
)
1785 base
= gen_rtx_PLUS (Pmode
, base
, offset
);
1786 return gen_rtx_CONST (Pmode
, base
);
1789 /* Return an UNSPEC address with underlying address ADDRESS and symbol
1790 type SYMBOL_TYPE. */
1793 riscv_unspec_address (rtx address
, enum riscv_symbol_type symbol_type
)
1797 split_const (address
, &base
, &offset
);
1798 return riscv_unspec_address_offset (base
, offset
, symbol_type
);
1801 /* If OP is an UNSPEC address, return the address to which it refers,
1802 otherwise return OP itself. */
1805 riscv_strip_unspec_address (rtx op
)
1809 split_const (op
, &base
, &offset
);
1810 if (UNSPEC_ADDRESS_P (base
))
1811 op
= plus_constant (Pmode
, UNSPEC_ADDRESS (base
), INTVAL (offset
));
1815 /* If riscv_unspec_address (ADDR, SYMBOL_TYPE) is a 32-bit value, add the
1816 high part to BASE and return the result. Just return BASE otherwise.
1817 TEMP is as for riscv_force_temporary.
1819 The returned expression can be used as the first operand to a LO_SUM. */
1822 riscv_unspec_offset_high (rtx temp
, rtx addr
, enum riscv_symbol_type symbol_type
)
1824 addr
= gen_rtx_HIGH (Pmode
, riscv_unspec_address (addr
, symbol_type
));
1825 return riscv_force_temporary (temp
, addr
);
1828 /* Load an entry from the GOT for a TLS GD access. */
1830 static rtx
riscv_got_load_tls_gd (rtx dest
, rtx sym
)
1832 if (Pmode
== DImode
)
1833 return gen_got_load_tls_gddi (dest
, sym
);
1835 return gen_got_load_tls_gdsi (dest
, sym
);
1838 /* Load an entry from the GOT for a TLS IE access. */
1840 static rtx
riscv_got_load_tls_ie (rtx dest
, rtx sym
)
1842 if (Pmode
== DImode
)
1843 return gen_got_load_tls_iedi (dest
, sym
);
1845 return gen_got_load_tls_iesi (dest
, sym
);
1848 /* Add in the thread pointer for a TLS LE access. */
1850 static rtx
riscv_tls_add_tp_le (rtx dest
, rtx base
, rtx sym
)
1852 rtx tp
= gen_rtx_REG (Pmode
, THREAD_POINTER_REGNUM
);
1853 if (Pmode
== DImode
)
1854 return gen_tls_add_tp_ledi (dest
, base
, tp
, sym
);
1856 return gen_tls_add_tp_lesi (dest
, base
, tp
, sym
);
1859 /* If MODE is MAX_MACHINE_MODE, ADDR appears as a move operand, otherwise
1860 it appears in a MEM of that mode. Return true if ADDR is a legitimate
1861 constant in that context and can be split into high and low parts.
1862 If so, and if LOW_OUT is nonnull, emit the high part and store the
1863 low part in *LOW_OUT. Leave *LOW_OUT unchanged otherwise.
1865 TEMP is as for riscv_force_temporary and is used to load the high
1866 part into a register.
1868 When MODE is MAX_MACHINE_MODE, the low part is guaranteed to be
1869 a legitimize SET_SRC for an .md pattern, otherwise the low part
1870 is guaranteed to be a legitimate address for mode MODE. */
1873 riscv_split_symbol (rtx temp
, rtx addr
, machine_mode mode
, rtx
*low_out
)
1875 enum riscv_symbol_type symbol_type
;
1877 if ((GET_CODE (addr
) == HIGH
&& mode
== MAX_MACHINE_MODE
)
1878 || !riscv_symbolic_constant_p (addr
, &symbol_type
)
1879 || riscv_symbol_insns (symbol_type
) == 0
1880 || !riscv_split_symbol_type (symbol_type
))
1884 switch (symbol_type
)
1886 case SYMBOL_ABSOLUTE
:
1888 rtx high
= gen_rtx_HIGH (Pmode
, copy_rtx (addr
));
1889 high
= riscv_force_temporary (temp
, high
);
1890 *low_out
= gen_rtx_LO_SUM (Pmode
, high
, addr
);
1896 static unsigned seqno
;
1900 ssize_t bytes
= snprintf (buf
, sizeof (buf
), ".LA%u", seqno
);
1901 gcc_assert ((size_t) bytes
< sizeof (buf
));
1903 label
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
1904 SYMBOL_REF_FLAGS (label
) |= SYMBOL_FLAG_LOCAL
;
1905 /* ??? Ugly hack to make weak symbols work. May need to change the
1906 RTL for the auipc and/or low patterns to get a better fix for
1908 if (! nonzero_address_p (addr
))
1909 SYMBOL_REF_WEAK (label
) = 1;
1912 temp
= gen_reg_rtx (Pmode
);
1914 if (Pmode
== DImode
)
1915 emit_insn (gen_auipcdi (temp
, copy_rtx (addr
), GEN_INT (seqno
)));
1917 emit_insn (gen_auipcsi (temp
, copy_rtx (addr
), GEN_INT (seqno
)));
1919 *low_out
= gen_rtx_LO_SUM (Pmode
, temp
, label
);
1932 /* Return a legitimate address for REG + OFFSET. TEMP is as for
1933 riscv_force_temporary; it is only needed when OFFSET is not a
1937 riscv_add_offset (rtx temp
, rtx reg
, HOST_WIDE_INT offset
)
1939 if (!SMALL_OPERAND (offset
))
1943 /* Leave OFFSET as a 16-bit offset and put the excess in HIGH.
1944 The addition inside the macro CONST_HIGH_PART may cause an
1945 overflow, so we need to force a sign-extension check. */
1946 high
= gen_int_mode (CONST_HIGH_PART (offset
), Pmode
);
1947 offset
= CONST_LOW_PART (offset
);
1948 high
= riscv_force_temporary (temp
, high
);
1949 reg
= riscv_force_temporary (temp
, gen_rtx_PLUS (Pmode
, high
, reg
));
1951 return plus_constant (Pmode
, reg
, offset
);
1954 /* The __tls_get_attr symbol. */
1955 static GTY(()) rtx riscv_tls_symbol
;
1957 /* Return an instruction sequence that calls __tls_get_addr. SYM is
1958 the TLS symbol we are referencing and TYPE is the symbol type to use
1959 (either global dynamic or local dynamic). RESULT is an RTX for the
1960 return value location. */
1963 riscv_call_tls_get_addr (rtx sym
, rtx result
)
1965 rtx a0
= gen_rtx_REG (Pmode
, GP_ARG_FIRST
), func
;
1968 if (!riscv_tls_symbol
)
1969 riscv_tls_symbol
= init_one_libfunc ("__tls_get_addr");
1970 func
= gen_rtx_MEM (FUNCTION_MODE
, riscv_tls_symbol
);
1974 emit_insn (riscv_got_load_tls_gd (a0
, sym
));
1975 insn
= emit_call_insn (gen_call_value (result
, func
, const0_rtx
,
1976 gen_int_mode (RISCV_CC_BASE
, SImode
)));
1977 RTL_CONST_CALL_P (insn
) = 1;
1978 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), a0
);
1979 insn
= get_insns ();
1986 /* Generate the code to access LOC, a thread-local SYMBOL_REF, and return
1987 its address. The return value will be both a valid address and a valid
1988 SET_SRC (either a REG or a LO_SUM). */
1991 riscv_legitimize_tls_address (rtx loc
)
1994 enum tls_model model
= SYMBOL_REF_TLS_MODEL (loc
);
1997 /* TLS copy relocs are now deprecated and should not be used. */
1998 /* Since we support TLS copy relocs, non-PIC TLS accesses may all use LE. */
2000 model
= TLS_MODEL_LOCAL_EXEC
;
2005 case TLS_MODEL_LOCAL_DYNAMIC
:
2006 /* Rely on section anchors for the optimization that LDM TLS
2007 provides. The anchor's address is loaded with GD TLS. */
2008 case TLS_MODEL_GLOBAL_DYNAMIC
:
2009 tmp
= gen_rtx_REG (Pmode
, GP_RETURN
);
2010 dest
= gen_reg_rtx (Pmode
);
2011 emit_libcall_block (riscv_call_tls_get_addr (loc
, tmp
), dest
, tmp
, loc
);
2014 case TLS_MODEL_INITIAL_EXEC
:
2015 /* la.tls.ie; tp-relative add */
2016 tp
= gen_rtx_REG (Pmode
, THREAD_POINTER_REGNUM
);
2017 tmp
= gen_reg_rtx (Pmode
);
2018 emit_insn (riscv_got_load_tls_ie (tmp
, loc
));
2019 dest
= gen_reg_rtx (Pmode
);
2020 emit_insn (gen_add3_insn (dest
, tmp
, tp
));
2023 case TLS_MODEL_LOCAL_EXEC
:
2024 tmp
= riscv_unspec_offset_high (NULL
, loc
, SYMBOL_TLS_LE
);
2025 dest
= gen_reg_rtx (Pmode
);
2026 emit_insn (riscv_tls_add_tp_le (dest
, tmp
, loc
));
2027 dest
= gen_rtx_LO_SUM (Pmode
, dest
,
2028 riscv_unspec_address (loc
, SYMBOL_TLS_LE
));
2037 /* If X is not a valid address for mode MODE, force it into a register. */
2040 riscv_force_address (rtx x
, machine_mode mode
)
2042 if (!riscv_legitimate_address_p (mode
, x
, false))
2043 x
= force_reg (Pmode
, x
);
2047 /* Modify base + offset so that offset fits within a compressed load/store insn
2048 and the excess is added to base. */
2051 riscv_shorten_lw_offset (rtx base
, HOST_WIDE_INT offset
)
2054 /* Leave OFFSET as an unsigned 5-bit offset scaled by 4 and put the excess
2056 high
= GEN_INT (offset
& ~CSW_MAX_OFFSET
);
2057 offset
&= CSW_MAX_OFFSET
;
2058 if (!SMALL_OPERAND (INTVAL (high
)))
2059 high
= force_reg (Pmode
, high
);
2060 base
= force_reg (Pmode
, gen_rtx_PLUS (Pmode
, high
, base
));
2061 addr
= plus_constant (Pmode
, base
, offset
);
2065 /* Helper for riscv_legitimize_address. Given X, return true if it
2066 is a left shift by 1, 2 or 3 positions or a multiply by 2, 4 or 8.
2068 This respectively represent canonical shift-add rtxs or scaled
2069 memory addresses. */
2071 mem_shadd_or_shadd_rtx_p (rtx x
)
2073 return ((GET_CODE (x
) == ASHIFT
2074 || GET_CODE (x
) == MULT
)
2075 && CONST_INT_P (XEXP (x
, 1))
2076 && ((GET_CODE (x
) == ASHIFT
&& IN_RANGE (INTVAL (XEXP (x
, 1)), 1, 3))
2077 || (GET_CODE (x
) == MULT
2078 && IN_RANGE (exact_log2 (INTVAL (XEXP (x
, 1))), 1, 3))));
2081 /* This function is used to implement LEGITIMIZE_ADDRESS. If X can
2082 be legitimized in a way that the generic machinery might not expect,
2083 return a new address, otherwise return NULL. MODE is the mode of
2084 the memory being accessed. */
2087 riscv_legitimize_address (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
2092 if (riscv_tls_symbol_p (x
))
2093 return riscv_legitimize_tls_address (x
);
2095 /* See if the address can split into a high part and a LO_SUM. */
2096 if (riscv_split_symbol (NULL
, x
, mode
, &addr
))
2097 return riscv_force_address (addr
, mode
);
2099 /* Handle BASE + OFFSET. */
2100 if (GET_CODE (x
) == PLUS
&& CONST_INT_P (XEXP (x
, 1))
2101 && INTVAL (XEXP (x
, 1)) != 0)
2103 rtx base
= XEXP (x
, 0);
2104 HOST_WIDE_INT offset
= INTVAL (XEXP (x
, 1));
2106 /* Handle (plus (plus (mult (a) (mem_shadd_constant)) (fp)) (C)) case. */
2107 if (GET_CODE (base
) == PLUS
&& mem_shadd_or_shadd_rtx_p (XEXP (base
, 0))
2108 && SMALL_OPERAND (offset
))
2110 rtx index
= XEXP (base
, 0);
2111 rtx fp
= XEXP (base
, 1);
2112 if (REG_P (fp
) && REGNO (fp
) == VIRTUAL_STACK_VARS_REGNUM
)
2115 /* If we were given a MULT, we must fix the constant
2116 as we're going to create the ASHIFT form. */
2117 int shift_val
= INTVAL (XEXP (index
, 1));
2118 if (GET_CODE (index
) == MULT
)
2119 shift_val
= exact_log2 (shift_val
);
2121 rtx reg1
= gen_reg_rtx (Pmode
);
2122 rtx reg2
= gen_reg_rtx (Pmode
);
2123 rtx reg3
= gen_reg_rtx (Pmode
);
2124 riscv_emit_binary (PLUS
, reg1
, fp
, GEN_INT (offset
));
2125 riscv_emit_binary (ASHIFT
, reg2
, XEXP (index
, 0), GEN_INT (shift_val
));
2126 riscv_emit_binary (PLUS
, reg3
, reg2
, reg1
);
2132 if (!riscv_valid_base_register_p (base
, mode
, false))
2133 base
= copy_to_mode_reg (Pmode
, base
);
2134 if (optimize_function_for_size_p (cfun
)
2135 && (strcmp (current_pass
->name
, "shorten_memrefs") == 0)
2137 /* Convert BASE + LARGE_OFFSET into NEW_BASE + SMALL_OFFSET to allow
2138 possible compressed load/store. */
2139 addr
= riscv_shorten_lw_offset (base
, offset
);
2141 addr
= riscv_add_offset (NULL
, base
, offset
);
2142 return riscv_force_address (addr
, mode
);
2148 /* Load VALUE into DEST. TEMP is as for riscv_force_temporary. ORIG_MODE
2149 is the original src mode before promotion. */
2152 riscv_move_integer (rtx temp
, rtx dest
, HOST_WIDE_INT value
,
2153 machine_mode orig_mode
)
2155 struct riscv_integer_op codes
[RISCV_MAX_INTEGER_OPS
];
2160 mode
= GET_MODE (dest
);
2161 /* We use the original mode for the riscv_build_integer call, because HImode
2162 values are given special treatment. */
2163 num_ops
= riscv_build_integer (codes
, value
, orig_mode
);
2165 if (can_create_pseudo_p () && num_ops
> 2 /* not a simple constant */
2166 && num_ops
>= riscv_split_integer_cost (value
))
2167 x
= riscv_split_integer (value
, mode
);
2170 codes
[0].value
= trunc_int_for_mode (codes
[0].value
, mode
);
2171 /* Apply each binary operation to X. */
2172 x
= GEN_INT (codes
[0].value
);
2174 for (i
= 1; i
< num_ops
; i
++)
2176 if (!can_create_pseudo_p ())
2177 x
= riscv_emit_set (temp
, x
);
2179 x
= force_reg (mode
, x
);
2180 codes
[i
].value
= trunc_int_for_mode (codes
[i
].value
, mode
);
2181 x
= gen_rtx_fmt_ee (codes
[i
].code
, mode
, x
, GEN_INT (codes
[i
].value
));
2185 riscv_emit_set (dest
, x
);
2188 /* Subroutine of riscv_legitimize_move. Move constant SRC into register
2189 DEST given that SRC satisfies immediate_operand but doesn't satisfy
2193 riscv_legitimize_const_move (machine_mode mode
, rtx dest
, rtx src
)
2197 /* Split moves of big integers into smaller pieces. */
2198 if (splittable_const_int_operand (src
, mode
))
2200 riscv_move_integer (dest
, dest
, INTVAL (src
), mode
);
2204 if (satisfies_constraint_zfli (src
))
2206 riscv_emit_set (dest
, src
);
2210 /* Split moves of symbolic constants into high/low pairs. */
2211 if (riscv_split_symbol (dest
, src
, MAX_MACHINE_MODE
, &src
))
2213 riscv_emit_set (dest
, src
);
2217 /* Generate the appropriate access sequences for TLS symbols. */
2218 if (riscv_tls_symbol_p (src
))
2220 riscv_emit_move (dest
, riscv_legitimize_tls_address (src
));
2224 /* If we have (const (plus symbol offset)), and that expression cannot
2225 be forced into memory, load the symbol first and add in the offset. Also
2226 prefer to do this even if the constant _can_ be forced into memory, as it
2227 usually produces better code. */
2228 split_const (src
, &base
, &offset
);
2229 if (offset
!= const0_rtx
2230 && (targetm
.cannot_force_const_mem (mode
, src
) || can_create_pseudo_p ()))
2232 base
= riscv_force_temporary (dest
, base
);
2233 riscv_emit_move (dest
, riscv_add_offset (NULL
, base
, INTVAL (offset
)));
2237 /* Handle below format.
2240 (symbol_ref:DI ("ic") [flags 0x2] <var_decl 0x7fe57740be10 ic>) <- op_0
2241 (const_poly_int:DI [16, 16]) // <- op_1
2244 if (GET_CODE (src
) == CONST
&& GET_CODE (XEXP (src
, 0)) == PLUS
2245 && CONST_POLY_INT_P (XEXP (XEXP (src
, 0), 1)))
2247 rtx dest_tmp
= gen_reg_rtx (mode
);
2248 rtx tmp
= gen_reg_rtx (mode
);
2250 riscv_emit_move (dest
, XEXP (XEXP (src
, 0), 0));
2251 riscv_legitimize_poly_move (mode
, dest_tmp
, tmp
, XEXP (XEXP (src
, 0), 1));
2253 emit_insn (gen_rtx_SET (dest
, gen_rtx_PLUS (mode
, dest
, dest_tmp
)));
2257 src
= force_const_mem (mode
, src
);
2259 /* When using explicit relocs, constant pool references are sometimes
2260 not legitimate addresses. */
2261 riscv_split_symbol (dest
, XEXP (src
, 0), mode
, &XEXP (src
, 0));
2262 riscv_emit_move (dest
, src
);
2265 /* Report when we try to do something that requires vector when vector is
2266 disabled. This is an error of last resort and isn't very high-quality. It
2267 usually involves attempts to measure the vector length in some way. */
2270 riscv_report_v_required (void)
2272 static bool reported_p
= false;
2274 /* Avoid reporting a slew of messages for a single oversight. */
2278 error ("this operation requires the RVV ISA extension");
2279 inform (input_location
, "you can enable RVV using the command-line"
2280 " option %<-march%>, or by using the %<target%>"
2281 " attribute or pragma");
2285 /* Helper function to operation for rtx_code CODE. */
2287 riscv_expand_op (enum rtx_code code
, machine_mode mode
, rtx op0
, rtx op1
,
2290 if (can_create_pseudo_p ())
2293 if (GET_RTX_CLASS (code
) == RTX_UNARY
)
2294 result
= expand_simple_unop (mode
, code
, op1
, NULL_RTX
, false);
2296 result
= expand_simple_binop (mode
, code
, op1
, op2
, NULL_RTX
, false,
2298 riscv_emit_move (op0
, result
);
2303 /* The following implementation is for prologue and epilogue.
2304 Because prologue and epilogue can not use pseudo register.
2305 We can't using expand_simple_binop or expand_simple_unop. */
2306 if (GET_RTX_CLASS (code
) == RTX_UNARY
)
2307 pat
= gen_rtx_fmt_e (code
, mode
, op1
);
2309 pat
= gen_rtx_fmt_ee (code
, mode
, op1
, op2
);
2310 emit_insn (gen_rtx_SET (op0
, pat
));
2314 /* Expand mult operation with constant integer, multiplicand also used as a
2315 * temporary register. */
2318 riscv_expand_mult_with_const_int (machine_mode mode
, rtx dest
, rtx multiplicand
,
2321 if (multiplier
== 0)
2323 riscv_emit_move (dest
, GEN_INT (0));
2327 bool neg_p
= multiplier
< 0;
2328 int multiplier_abs
= abs (multiplier
);
2330 if (multiplier_abs
== 1)
2333 riscv_expand_op (NEG
, mode
, dest
, multiplicand
, NULL_RTX
);
2335 riscv_emit_move (dest
, multiplicand
);
2339 if (pow2p_hwi (multiplier_abs
))
2342 multiplicand = [BYTES_PER_RISCV_VECTOR].
2343 1. const_poly_int:P [BYTES_PER_RISCV_VECTOR * 8].
2347 2. const_poly_int:P [-BYTES_PER_RISCV_VECTOR * 8].
2353 riscv_expand_op (ASHIFT
, mode
, dest
, multiplicand
,
2354 gen_int_mode (exact_log2 (multiplier_abs
), QImode
));
2356 riscv_expand_op (NEG
, mode
, dest
, dest
, NULL_RTX
);
2358 else if (pow2p_hwi (multiplier_abs
+ 1))
2361 multiplicand = [BYTES_PER_RISCV_VECTOR].
2362 1. const_poly_int:P [BYTES_PER_RISCV_VECTOR * 7].
2367 2. const_poly_int:P [-BYTES_PER_RISCV_VECTOR * 7].
2371 sub a5, a4, a5 + neg a5, a5 => sub a5, a5, a4
2373 riscv_expand_op (ASHIFT
, mode
, dest
, multiplicand
,
2374 gen_int_mode (exact_log2 (multiplier_abs
+ 1),
2377 riscv_expand_op (MINUS
, mode
, dest
, multiplicand
, dest
);
2379 riscv_expand_op (MINUS
, mode
, dest
, dest
, multiplicand
);
2381 else if (pow2p_hwi (multiplier
- 1))
2384 multiplicand = [BYTES_PER_RISCV_VECTOR].
2385 1. const_poly_int:P [BYTES_PER_RISCV_VECTOR * 9].
2390 2. const_poly_int:P [-BYTES_PER_RISCV_VECTOR * 9].
2397 riscv_expand_op (ASHIFT
, mode
, dest
, multiplicand
,
2398 gen_int_mode (exact_log2 (multiplier_abs
- 1),
2400 riscv_expand_op (PLUS
, mode
, dest
, dest
, multiplicand
);
2402 riscv_expand_op (NEG
, mode
, dest
, dest
, NULL_RTX
);
2406 /* We use multiplication for remaining cases. */
2409 && "M-extension must be enabled to calculate the poly_int "
2411 riscv_emit_move (dest
, gen_int_mode (multiplier
, mode
));
2412 riscv_expand_op (MULT
, mode
, dest
, dest
, multiplicand
);
2417 /* Analyze src and emit const_poly_int mov sequence. */
2420 riscv_legitimize_poly_move (machine_mode mode
, rtx dest
, rtx tmp
, rtx src
)
2422 poly_int64 value
= rtx_to_poly_int64 (src
);
2423 int offset
= value
.coeffs
[0];
2424 int factor
= value
.coeffs
[1];
2425 int vlenb
= BYTES_PER_RISCV_VECTOR
.coeffs
[1];
2427 /* Calculate (const_poly_int:MODE [m, n]) using scalar instructions.
2428 For any (const_poly_int:MODE [m, n]), the calculation formula is as
2431 When minimum VLEN = 32, poly of VLENB = (4, 4).
2432 base = vlenb(4, 4) or vlenb/2(2, 2) or vlenb/4(1, 1).
2433 When minimum VLEN > 32, poly of VLENB = (8, 8).
2434 base = vlenb(8, 8) or vlenb/2(4, 4) or vlenb/4(2, 2) or vlenb/8(1, 1).
2435 magn = (n, n) / base.
2436 (m, n) = base * magn + constant.
2437 This calculation doesn't need div operation. */
2439 if (known_le (GET_MODE_SIZE (mode
), GET_MODE_SIZE (Pmode
)))
2440 emit_move_insn (tmp
, gen_int_mode (BYTES_PER_RISCV_VECTOR
, mode
));
2443 emit_move_insn (gen_highpart (Pmode
, tmp
), CONST0_RTX (Pmode
));
2444 emit_move_insn (gen_lowpart (Pmode
, tmp
),
2445 gen_int_mode (BYTES_PER_RISCV_VECTOR
, Pmode
));
2448 if (BYTES_PER_RISCV_VECTOR
.is_constant ())
2450 gcc_assert (value
.is_constant ());
2451 riscv_emit_move (dest
, GEN_INT (value
.to_constant ()));
2456 int max_power
= exact_log2 (MAX_POLY_VARIANT
);
2457 for (int i
= 0; i
<= max_power
; i
++)
2459 int possible_div_factor
= 1 << i
;
2460 if (factor
% (vlenb
/ possible_div_factor
) == 0)
2462 div_factor
= possible_div_factor
;
2466 gcc_assert (div_factor
!= 0);
2469 if (div_factor
!= 1)
2470 riscv_expand_op (LSHIFTRT
, mode
, tmp
, tmp
,
2471 gen_int_mode (exact_log2 (div_factor
), QImode
));
2473 riscv_expand_mult_with_const_int (mode
, dest
, tmp
,
2474 factor
/ (vlenb
/ div_factor
));
2475 HOST_WIDE_INT constant
= offset
- factor
;
2479 else if (SMALL_OPERAND (constant
))
2480 riscv_expand_op (PLUS
, mode
, dest
, dest
, gen_int_mode (constant
, mode
));
2483 /* Handle the constant value is not a 12-bit value. */
2486 /* Leave OFFSET as a 16-bit offset and put the excess in HIGH.
2487 The addition inside the macro CONST_HIGH_PART may cause an
2488 overflow, so we need to force a sign-extension check. */
2489 high
= gen_int_mode (CONST_HIGH_PART (constant
), mode
);
2490 constant
= CONST_LOW_PART (constant
);
2491 riscv_emit_move (tmp
, high
);
2492 riscv_expand_op (PLUS
, mode
, dest
, tmp
, dest
);
2493 riscv_expand_op (PLUS
, mode
, dest
, dest
, gen_int_mode (constant
, mode
));
2497 /* Adjust scalable frame of vector for prologue && epilogue. */
2500 riscv_v_adjust_scalable_frame (rtx target
, poly_int64 offset
, bool epilogue
)
2502 rtx tmp
= RISCV_PROLOGUE_TEMP (Pmode
);
2503 rtx adjust_size
= RISCV_PROLOGUE_TEMP2 (Pmode
);
2504 rtx insn
, dwarf
, adjust_frame_rtx
;
2506 riscv_legitimize_poly_move (Pmode
, adjust_size
, tmp
,
2507 gen_int_mode (offset
, Pmode
));
2510 insn
= gen_add3_insn (target
, target
, adjust_size
);
2512 insn
= gen_sub3_insn (target
, target
, adjust_size
);
2514 insn
= emit_insn (insn
);
2516 RTX_FRAME_RELATED_P (insn
) = 1;
2519 = gen_rtx_SET (target
,
2520 plus_constant (Pmode
, target
, epilogue
? offset
: -offset
));
2522 dwarf
= alloc_reg_note (REG_FRAME_RELATED_EXPR
, copy_rtx (adjust_frame_rtx
),
2525 REG_NOTES (insn
) = dwarf
;
2528 /* If (set DEST SRC) is not a valid move instruction, emit an equivalent
2529 sequence that is valid. */
2532 riscv_legitimize_move (machine_mode mode
, rtx dest
, rtx src
)
2534 if (CONST_POLY_INT_P (src
))
2538 (insn 183 182 184 6 (set (mem:QI (plus:DI (reg/f:DI 156)
2539 (const_int 96 [0x60])) [0 S1 A8])
2540 (const_poly_int:QI [8, 8]))
2541 "../../../../riscv-gcc/libgcc/unwind-dw2.c":1579:3 -1 (nil))
2545 emit_move_insn (dest
, force_reg (mode
, src
));
2548 poly_int64 value
= rtx_to_poly_int64 (src
);
2549 if (!value
.is_constant () && !TARGET_VECTOR
)
2551 riscv_report_v_required ();
2555 if (satisfies_constraint_vp (src
) && GET_MODE (src
) == Pmode
)
2558 if (GET_MODE_SIZE (mode
).to_constant () < GET_MODE_SIZE (Pmode
))
2560 /* In RV32 system, handle (const_poly_int:QI [m, n])
2561 (const_poly_int:HI [m, n]).
2562 In RV64 system, handle (const_poly_int:QI [m, n])
2563 (const_poly_int:HI [m, n])
2564 (const_poly_int:SI [m, n]). */
2565 rtx tmp
= gen_reg_rtx (Pmode
);
2566 riscv_legitimize_poly_move (Pmode
, gen_lowpart (Pmode
, dest
), tmp
,
2571 /* In RV32 system, handle (const_poly_int:SI [m, n])
2572 (const_poly_int:DI [m, n]).
2573 In RV64 system, handle (const_poly_int:DI [m, n]).
2574 FIXME: Maybe we could gen SImode in RV32 and then sign-extend to DImode,
2575 the offset should not exceed 4GiB in general. */
2576 rtx tmp
= gen_reg_rtx (mode
);
2577 riscv_legitimize_poly_move (mode
, dest
, tmp
, src
);
2582 (set (reg:DI target) (subreg:DI (reg:V8QI reg) 0))
2583 Expand this data movement instead of simply forbid it since
2584 we can improve the code generation for this following scenario
2585 by RVV auto-vectorization:
2586 (set (reg:V8QI 149) (vec_duplicate:V8QI (reg:QI))
2587 (set (reg:DI target) (subreg:DI (reg:V8QI reg) 0))
2588 Since RVV mode and scalar mode are in different REG_CLASS,
2589 we need to explicitly move data from V_REGS to GR_REGS by scalar move. */
2590 if (SUBREG_P (src
) && riscv_v_ext_mode_p (GET_MODE (SUBREG_REG (src
))))
2592 machine_mode vmode
= GET_MODE (SUBREG_REG (src
));
2593 unsigned int mode_size
= GET_MODE_SIZE (mode
).to_constant ();
2594 unsigned int vmode_size
= GET_MODE_SIZE (vmode
).to_constant ();
2595 /* We should be able to handle both partial and paradoxical subreg. */
2596 unsigned int nunits
= vmode_size
> mode_size
? vmode_size
/ mode_size
: 1;
2597 scalar_mode smode
= as_a
<scalar_mode
> (mode
);
2598 unsigned int index
= SUBREG_BYTE (src
).to_constant () / mode_size
;
2599 unsigned int num
= smode
== DImode
&& !TARGET_VECTOR_ELEN_64
? 2 : 1;
2603 /* If we want to extract 64bit value but ELEN < 64,
2604 we use RVV vector mode with EEW = 32 to extract
2605 the highpart and lowpart. */
2607 nunits
= nunits
* 2;
2609 vmode
= riscv_vector::get_vector_mode (smode
, nunits
).require ();
2610 enum insn_code icode
2611 = convert_optab_handler (vec_extract_optab
, vmode
, smode
);
2612 gcc_assert (icode
!= CODE_FOR_nothing
);
2613 rtx v
= gen_lowpart (vmode
, SUBREG_REG (src
));
2615 for (unsigned int i
= 0; i
< num
; i
++)
2617 class expand_operand ops
[3];
2622 result
= gen_lowpart (smode
, dest
);
2624 result
= gen_reg_rtx (smode
);
2625 create_output_operand (&ops
[0], result
, smode
);
2627 create_input_operand (&ops
[1], v
, vmode
);
2628 create_integer_operand (&ops
[2], index
+ i
);
2629 expand_insn (icode
, 3, ops
);
2630 if (ops
[0].value
!= result
)
2631 emit_move_insn (result
, ops
[0].value
);
2636 = expand_binop (Pmode
, ashl_optab
, gen_lowpart (Pmode
, result
),
2637 gen_int_mode (32, Pmode
), NULL_RTX
, 0,
2639 rtx tmp2
= expand_binop (Pmode
, ior_optab
, tmp
, dest
, NULL_RTX
, 0,
2641 emit_move_insn (dest
, tmp2
);
2647 (set (reg:QI target) (mem:QI (address)))
2649 (set (reg:DI temp) (zero_extend:DI (mem:QI (address))))
2650 (set (reg:QI target) (subreg:QI (reg:DI temp) 0))
2651 with auto-sign/zero extend. */
2652 if (GET_MODE_CLASS (mode
) == MODE_INT
2653 && GET_MODE_SIZE (mode
).to_constant () < UNITS_PER_WORD
2654 && can_create_pseudo_p ()
2660 temp_reg
= gen_reg_rtx (word_mode
);
2661 zero_extend_p
= (LOAD_EXTEND_OP (mode
) == ZERO_EXTEND
);
2662 emit_insn (gen_extend_insn (temp_reg
, src
, word_mode
, mode
,
2664 riscv_emit_move (dest
, gen_lowpart (mode
, temp_reg
));
2668 if (!register_operand (dest
, mode
) && !reg_or_0_operand (src
, mode
))
2672 if (GET_CODE (src
) == CONST_INT
)
2674 /* Apply the equivalent of PROMOTE_MODE here for constants to
2676 machine_mode promoted_mode
= mode
;
2677 if (GET_MODE_CLASS (mode
) == MODE_INT
2678 && GET_MODE_SIZE (mode
).to_constant () < UNITS_PER_WORD
)
2679 promoted_mode
= word_mode
;
2681 if (splittable_const_int_operand (src
, mode
))
2683 reg
= gen_reg_rtx (promoted_mode
);
2684 riscv_move_integer (reg
, reg
, INTVAL (src
), mode
);
2687 reg
= force_reg (promoted_mode
, src
);
2689 if (promoted_mode
!= mode
)
2690 reg
= gen_lowpart (mode
, reg
);
2693 reg
= force_reg (mode
, src
);
2694 riscv_emit_move (dest
, reg
);
2698 /* We need to deal with constants that would be legitimate
2699 immediate_operands but aren't legitimate move_operands. */
2700 if (CONSTANT_P (src
) && !move_operand (src
, mode
))
2702 riscv_legitimize_const_move (mode
, dest
, src
);
2703 set_unique_reg_note (get_last_insn (), REG_EQUAL
, copy_rtx (src
));
2707 /* RISC-V GCC may generate non-legitimate address due to we provide some
2708 pattern for optimize access PIC local symbol and it's make GCC generate
2709 unrecognizable instruction during optmizing. */
2711 if (MEM_P (dest
) && !riscv_legitimate_address_p (mode
, XEXP (dest
, 0),
2714 XEXP (dest
, 0) = riscv_force_address (XEXP (dest
, 0), mode
);
2717 if (MEM_P (src
) && !riscv_legitimate_address_p (mode
, XEXP (src
, 0),
2720 XEXP (src
, 0) = riscv_force_address (XEXP (src
, 0), mode
);
2726 /* Return true if there is an instruction that implements CODE and accepts
2727 X as an immediate operand. */
2730 riscv_immediate_operand_p (int code
, HOST_WIDE_INT x
)
2737 /* All shift counts are truncated to a valid constant. */
2746 /* These instructions take 12-bit signed immediates. */
2747 return SMALL_OPERAND (x
);
2750 /* We add 1 to the immediate and use SLT. */
2751 return SMALL_OPERAND (x
+ 1);
2754 /* Likewise SLTU, but reject the always-true case. */
2755 return SMALL_OPERAND (x
+ 1) && x
+ 1 != 0;
2759 /* We can emulate an immediate of 1 by using GT/GTU against x0. */
2763 /* By default assume that x0 can be used for 0. */
2768 /* Return the cost of binary operation X, given that the instruction
2769 sequence for a word-sized or smaller operation takes SIGNLE_INSNS
2770 instructions and that the sequence of a double-word operation takes
2771 DOUBLE_INSNS instructions. */
2774 riscv_binary_cost (rtx x
, int single_insns
, int double_insns
)
2776 if (!riscv_v_ext_mode_p (GET_MODE (x
))
2777 && GET_MODE_SIZE (GET_MODE (x
)).to_constant () == UNITS_PER_WORD
* 2)
2778 return COSTS_N_INSNS (double_insns
);
2779 return COSTS_N_INSNS (single_insns
);
2782 /* Return the cost of sign- or zero-extending OP. */
2785 riscv_extend_cost (rtx op
, bool unsigned_p
)
2790 if (unsigned_p
&& GET_MODE (op
) == QImode
)
2791 /* We can use ANDI. */
2792 return COSTS_N_INSNS (1);
2794 /* ZBA provide zext.w. */
2795 if (TARGET_ZBA
&& TARGET_64BIT
&& unsigned_p
&& GET_MODE (op
) == SImode
)
2796 return COSTS_N_INSNS (1);
2798 /* ZBB provide zext.h, sext.b and sext.h. */
2801 if (!unsigned_p
&& GET_MODE (op
) == QImode
)
2802 return COSTS_N_INSNS (1);
2804 if (GET_MODE (op
) == HImode
)
2805 return COSTS_N_INSNS (1);
2808 if (!unsigned_p
&& GET_MODE (op
) == SImode
)
2809 /* We can use SEXT.W. */
2810 return COSTS_N_INSNS (1);
2812 /* We need to use a shift left and a shift right. */
2813 return COSTS_N_INSNS (2);
2816 /* Implement TARGET_RTX_COSTS. */
2818 #define SINGLE_SHIFT_COST 1
2821 riscv_rtx_costs (rtx x
, machine_mode mode
, int outer_code
, int opno ATTRIBUTE_UNUSED
,
2822 int *total
, bool speed
)
2824 /* TODO: We set RVV instruction cost as 1 by default.
2825 Cost Model need to be well analyzed and supported in the future. */
2826 if (riscv_v_ext_mode_p (mode
))
2828 *total
= COSTS_N_INSNS (1);
2832 bool float_mode_p
= FLOAT_MODE_P (mode
);
2835 switch (GET_CODE (x
))
2838 /* If we are called for an INSN that's a simple set of a register,
2839 then cost based on the SET_SRC alone. */
2840 if (outer_code
== INSN
&& REG_P (SET_DEST (x
)))
2842 riscv_rtx_costs (SET_SRC (x
), mode
, outer_code
, opno
, total
, speed
);
2846 /* Otherwise return FALSE indicating we should recurse into both the
2847 SET_DEST and SET_SRC combining the cost of both. */
2851 /* trivial constants checked using OUTER_CODE in case they are
2852 encodable in insn itself w/o need for additional insn(s). */
2853 if (riscv_immediate_operand_p (outer_code
, INTVAL (x
)))
2863 /* With TARGET_SUPPORTS_WIDE_INT const int can't be in CONST_DOUBLE
2864 rtl object. Weird recheck due to switch-case fall through above. */
2865 if (GET_CODE (x
) == CONST_DOUBLE
)
2866 gcc_assert (GET_MODE (x
) != VOIDmode
);
2870 /* Non trivial CONST_INT Fall through: check if need multiple insns. */
2871 if ((cost
= riscv_const_insns (x
)) > 0)
2873 /* 1. Hoist will GCSE constants only if TOTAL returned is non-zero.
2874 2. For constants loaded more than once, the approach so far has
2875 been to duplicate the operation than to CSE the constant.
2876 3. TODO: make cost more accurate specially if riscv_const_insns
2878 if (outer_code
== SET
|| GET_MODE (x
) == VOIDmode
)
2879 *total
= COSTS_N_INSNS (1);
2881 else /* The instruction will be fetched from the constant pool. */
2882 *total
= COSTS_N_INSNS (riscv_symbol_insns (SYMBOL_ABSOLUTE
));
2886 /* If the address is legitimate, return the number of
2887 instructions it needs. */
2888 if ((cost
= riscv_address_insns (XEXP (x
, 0), mode
, true)) > 0)
2890 /* When optimizing for size, make uncompressible 32-bit addresses
2891 more expensive so that compressible 32-bit addresses are
2893 if ((TARGET_RVC
|| TARGET_ZCA
)
2894 && !speed
&& riscv_mshorten_memrefs
&& mode
== SImode
2895 && !riscv_compressed_lw_address_p (XEXP (x
, 0)))
2898 *total
= COSTS_N_INSNS (cost
+ tune_param
->memory_cost
);
2901 /* Otherwise use the default handling. */
2905 if ((TARGET_SFB_ALU
|| TARGET_XTHEADCONDMOV
)
2906 && reg_or_0_operand (XEXP (x
, 1), mode
)
2907 && sfb_alu_operand (XEXP (x
, 2), mode
)
2908 && comparison_operator (XEXP (x
, 0), VOIDmode
))
2910 /* For predicated conditional-move operations we assume the cost
2911 of a single instruction even though there are actually two. */
2912 *total
= COSTS_N_INSNS (1);
2915 else if (TARGET_ZICOND_LIKE
2916 && outer_code
== SET
2917 && ((GET_CODE (XEXP (x
, 1)) == REG
2918 && XEXP (x
, 2) == CONST0_RTX (GET_MODE (XEXP (x
, 1))))
2919 || (GET_CODE (XEXP (x
, 2)) == REG
2920 && XEXP (x
, 1) == CONST0_RTX (GET_MODE (XEXP (x
, 2))))
2921 || (GET_CODE (XEXP (x
, 1)) == REG
2922 && rtx_equal_p (XEXP (x
, 1), XEXP (XEXP (x
, 0), 0)))
2923 || (GET_CODE (XEXP (x
, 1)) == REG
2924 && rtx_equal_p (XEXP (x
, 2), XEXP (XEXP (x
, 0), 0)))))
2926 *total
= COSTS_N_INSNS (1);
2929 else if (LABEL_REF_P (XEXP (x
, 1)) && XEXP (x
, 2) == pc_rtx
)
2931 if (equality_operator (XEXP (x
, 0), mode
)
2932 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == ZERO_EXTRACT
)
2934 *total
= COSTS_N_INSNS (SINGLE_SHIFT_COST
+ 1);
2937 if (order_operator (XEXP (x
, 0), mode
))
2939 *total
= COSTS_N_INSNS (1);
2946 *total
= COSTS_N_INSNS (GET_MODE_SIZE (mode
).to_constant () > UNITS_PER_WORD
? 2 : 1);
2950 /* slli.uw pattern for zba. */
2951 if (TARGET_ZBA
&& TARGET_64BIT
&& mode
== DImode
2952 && GET_CODE (XEXP (x
, 0)) == ASHIFT
)
2954 rtx and_rhs
= XEXP (x
, 1);
2955 rtx ashift_lhs
= XEXP (XEXP (x
, 0), 0);
2956 rtx ashift_rhs
= XEXP (XEXP (x
, 0), 1);
2957 if (REG_P (ashift_lhs
)
2958 && CONST_INT_P (ashift_rhs
)
2959 && CONST_INT_P (and_rhs
)
2960 && ((INTVAL (and_rhs
) >> INTVAL (ashift_rhs
)) == 0xffffffff))
2961 *total
= COSTS_N_INSNS (1);
2964 /* bclri pattern for zbs. */
2966 && not_single_bit_mask_operand (XEXP (x
, 1), VOIDmode
))
2968 *total
= COSTS_N_INSNS (1);
2971 /* bclr pattern for zbs. */
2973 && REG_P (XEXP (x
, 1))
2974 && GET_CODE (XEXP (x
, 0)) == ROTATE
2975 && CONST_INT_P (XEXP ((XEXP (x
, 0)), 0))
2976 && INTVAL (XEXP ((XEXP (x
, 0)), 0)) == -2)
2978 *total
= COSTS_N_INSNS (1);
2985 /* orn, andn and xorn pattern for zbb. */
2987 && GET_CODE (XEXP (x
, 0)) == NOT
)
2989 *total
= riscv_binary_cost (x
, 1, 2);
2993 /* bset[i] and binv[i] pattern for zbs. */
2994 if ((GET_CODE (x
) == IOR
|| GET_CODE (x
) == XOR
)
2996 && ((GET_CODE (XEXP (x
, 0)) == ASHIFT
2997 && CONST_INT_P (XEXP (XEXP (x
, 0), 0)))
2998 || single_bit_mask_operand (XEXP (x
, 1), VOIDmode
)))
3000 *total
= COSTS_N_INSNS (1);
3004 /* Double-word operations use two single-word operations. */
3005 *total
= riscv_binary_cost (x
, 1, 2);
3009 /* This is an SImode shift. */
3010 if (outer_code
== SET
3011 && CONST_INT_P (XEXP (x
, 1))
3012 && CONST_INT_P (XEXP (x
, 2))
3013 && (INTVAL (XEXP (x
, 2)) > 0)
3014 && (INTVAL (XEXP (x
, 1)) + INTVAL (XEXP (x
, 2)) == 32))
3016 *total
= COSTS_N_INSNS (SINGLE_SHIFT_COST
);
3019 /* bit extraction pattern (zbs:bext, xtheadbs:tst). */
3020 if ((TARGET_ZBS
|| TARGET_XTHEADBS
) && outer_code
== SET
3021 && GET_CODE (XEXP (x
, 1)) == CONST_INT
3022 && INTVAL (XEXP (x
, 1)) == 1)
3024 *total
= COSTS_N_INSNS (SINGLE_SHIFT_COST
);
3029 if (TARGET_XTHEADBB
&& outer_code
== SET
3030 && CONST_INT_P (XEXP (x
, 1))
3031 && CONST_INT_P (XEXP (x
, 2)))
3033 *total
= COSTS_N_INSNS (SINGLE_SHIFT_COST
);
3039 /* bset pattern for zbs. */
3041 && CONST_INT_P (XEXP (x
, 0))
3042 && INTVAL (XEXP (x
, 0)) == 1)
3044 *total
= COSTS_N_INSNS (1);
3050 *total
= riscv_binary_cost (x
, SINGLE_SHIFT_COST
,
3051 CONSTANT_P (XEXP (x
, 1)) ? 4 : 9);
3055 *total
= COSTS_N_INSNS (float_mode_p
? 1 : 3);
3059 *total
= set_src_cost (XEXP (x
, 0), mode
, speed
);
3063 /* This is an SImode shift. */
3064 if (outer_code
== SET
&& GET_MODE (x
) == DImode
3065 && GET_MODE (XEXP (x
, 0)) == SImode
)
3067 *total
= COSTS_N_INSNS (SINGLE_SHIFT_COST
);
3080 /* Branch comparisons have VOIDmode, so use the first operand's
3082 mode
= GET_MODE (XEXP (x
, 0));
3084 *total
= tune_param
->fp_add
[mode
== DFmode
];
3086 *total
= riscv_binary_cost (x
, 1, 3);
3091 /* (FEQ(A, A) & FEQ(B, B)) compared against 0. */
3092 mode
= GET_MODE (XEXP (x
, 0));
3093 *total
= tune_param
->fp_add
[mode
== DFmode
] + COSTS_N_INSNS (2);
3097 /* (FEQ(A, A) & FEQ(B, B)) compared against FEQ(A, B). */
3098 mode
= GET_MODE (XEXP (x
, 0));
3099 *total
= tune_param
->fp_add
[mode
== DFmode
] + COSTS_N_INSNS (3);
3103 /* (FLT(A, A) || FGT(B, B)). */
3104 mode
= GET_MODE (XEXP (x
, 0));
3105 *total
= tune_param
->fp_add
[mode
== DFmode
] + COSTS_N_INSNS (2);
3112 /* FLT or FLE, but guarded by an FFLAGS read and write. */
3113 mode
= GET_MODE (XEXP (x
, 0));
3114 *total
= tune_param
->fp_add
[mode
== DFmode
] + COSTS_N_INSNS (4);
3119 *total
= tune_param
->fp_add
[mode
== DFmode
];
3121 *total
= riscv_binary_cost (x
, 1, 4);
3125 /* add.uw pattern for zba. */
3127 && (TARGET_64BIT
&& (mode
== DImode
))
3128 && GET_CODE (XEXP (x
, 0)) == ZERO_EXTEND
3129 && REG_P (XEXP (XEXP (x
, 0), 0))
3130 && GET_MODE (XEXP (XEXP (x
, 0), 0)) == SImode
)
3132 *total
= COSTS_N_INSNS (1);
3135 /* shNadd pattern for zba. */
3137 && ((!TARGET_64BIT
&& (mode
== SImode
)) ||
3138 (TARGET_64BIT
&& (mode
== DImode
)))
3139 && (GET_CODE (XEXP (x
, 0)) == ASHIFT
)
3140 && REG_P (XEXP (XEXP (x
, 0), 0))
3141 && CONST_INT_P (XEXP (XEXP (x
, 0), 1))
3142 && IN_RANGE (INTVAL (XEXP (XEXP (x
, 0), 1)), 1, 3))
3144 *total
= COSTS_N_INSNS (1);
3147 /* Before strength-reduction, the shNadd can be expressed as the addition
3148 of a multiplication with a power-of-two. If this case is not handled,
3149 the strength-reduction in expmed.c will calculate an inflated cost. */
3151 && mode
== word_mode
3152 && GET_CODE (XEXP (x
, 0)) == MULT
3153 && REG_P (XEXP (XEXP (x
, 0), 0))
3154 && CONST_INT_P (XEXP (XEXP (x
, 0), 1))
3155 && pow2p_hwi (INTVAL (XEXP (XEXP (x
, 0), 1)))
3156 && IN_RANGE (exact_log2 (INTVAL (XEXP (XEXP (x
, 0), 1))), 1, 3))
3158 *total
= COSTS_N_INSNS (1);
3161 /* shNadd.uw pattern for zba.
3162 [(set (match_operand:DI 0 "register_operand" "=r")
3164 (and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r")
3165 (match_operand:QI 2 "immediate_operand" "I"))
3166 (match_operand 3 "immediate_operand" ""))
3167 (match_operand:DI 4 "register_operand" "r")))]
3168 "TARGET_64BIT && TARGET_ZBA
3169 && (INTVAL (operands[2]) >= 1) && (INTVAL (operands[2]) <= 3)
3170 && (INTVAL (operands[3]) >> INTVAL (operands[2])) == 0xffffffff"
3173 && (TARGET_64BIT
&& (mode
== DImode
))
3174 && (GET_CODE (XEXP (x
, 0)) == AND
)
3175 && (REG_P (XEXP (x
, 1))))
3178 rtx and_lhs
= XEXP (XEXP (x
, 0), 0);
3179 rtx and_rhs
= XEXP (XEXP (x
, 0), 1);
3180 if (GET_CODE (and_lhs
) != ASHIFT
)
3182 if (!CONST_INT_P (and_rhs
))
3185 rtx ashift_rhs
= XEXP (and_lhs
, 1);
3187 if (!CONST_INT_P (ashift_rhs
)
3188 || !IN_RANGE (INTVAL (ashift_rhs
), 1, 3))
3191 if (CONST_INT_P (and_rhs
)
3192 && ((INTVAL (and_rhs
) >> INTVAL (ashift_rhs
)) == 0xffffffff))
3194 *total
= COSTS_N_INSNS (1);
3201 *total
= tune_param
->fp_add
[mode
== DFmode
];
3203 *total
= riscv_binary_cost (x
, 1, 4);
3208 rtx op
= XEXP (x
, 0);
3209 if (GET_CODE (op
) == FMA
&& !HONOR_SIGNED_ZEROS (mode
))
3211 *total
= (tune_param
->fp_mul
[mode
== DFmode
]
3212 + set_src_cost (XEXP (op
, 0), mode
, speed
)
3213 + set_src_cost (XEXP (op
, 1), mode
, speed
)
3214 + set_src_cost (XEXP (op
, 2), mode
, speed
));
3220 *total
= tune_param
->fp_add
[mode
== DFmode
];
3222 *total
= COSTS_N_INSNS (GET_MODE_SIZE (mode
).to_constant () > UNITS_PER_WORD
? 4 : 1);
3227 *total
= tune_param
->fp_mul
[mode
== DFmode
];
3228 else if (!TARGET_MUL
)
3229 /* Estimate the cost of a library call. */
3230 *total
= COSTS_N_INSNS (speed
? 32 : 6);
3231 else if (GET_MODE_SIZE (mode
).to_constant () > UNITS_PER_WORD
)
3232 *total
= 3 * tune_param
->int_mul
[0] + COSTS_N_INSNS (2);
3234 *total
= COSTS_N_INSNS (1);
3236 *total
= tune_param
->int_mul
[mode
== DImode
];
3244 *total
= tune_param
->fp_div
[mode
== DFmode
];
3252 /* Estimate the cost of a library call. */
3253 *total
= COSTS_N_INSNS (speed
? 32 : 6);
3255 *total
= tune_param
->int_div
[mode
== DImode
];
3257 *total
= COSTS_N_INSNS (1);
3261 /* This is an SImode shift. */
3262 if (GET_CODE (XEXP (x
, 0)) == LSHIFTRT
)
3264 *total
= COSTS_N_INSNS (SINGLE_SHIFT_COST
);
3269 *total
= riscv_extend_cost (XEXP (x
, 0), GET_CODE (x
) == ZERO_EXTEND
);
3275 /* RISC-V only defines rev8 for XLEN, so we will need an extra
3276 shift-right instruction for smaller modes. */
3277 *total
= COSTS_N_INSNS (mode
== word_mode
? 1 : 2);
3283 case UNSIGNED_FLOAT
:
3286 case FLOAT_TRUNCATE
:
3287 *total
= tune_param
->fp_add
[mode
== DFmode
];
3291 *total
= (tune_param
->fp_mul
[mode
== DFmode
]
3292 + set_src_cost (XEXP (x
, 0), mode
, speed
)
3293 + set_src_cost (XEXP (x
, 1), mode
, speed
)
3294 + set_src_cost (XEXP (x
, 2), mode
, speed
));
3298 if (XINT (x
, 1) == UNSPEC_AUIPC
)
3300 /* Make AUIPC cheap to avoid spilling its result to the stack. */
3311 /* Implement TARGET_ADDRESS_COST. */
3314 riscv_address_cost (rtx addr
, machine_mode mode
,
3315 addr_space_t as ATTRIBUTE_UNUSED
,
3316 bool speed ATTRIBUTE_UNUSED
)
3318 /* When optimizing for size, make uncompressible 32-bit addresses more
3319 * expensive so that compressible 32-bit addresses are preferred. */
3320 if ((TARGET_RVC
|| TARGET_ZCA
)
3321 && !speed
&& riscv_mshorten_memrefs
&& mode
== SImode
3322 && !riscv_compressed_lw_address_p (addr
))
3323 return riscv_address_insns (addr
, mode
, false) + 1;
3324 return riscv_address_insns (addr
, mode
, false);
3327 /* Return one word of double-word value OP. HIGH_P is true to select the
3328 high part or false to select the low part. */
3331 riscv_subword (rtx op
, bool high_p
)
3333 unsigned int byte
= (high_p
!= BYTES_BIG_ENDIAN
) ? UNITS_PER_WORD
: 0;
3334 machine_mode mode
= GET_MODE (op
);
3336 if (mode
== VOIDmode
)
3337 mode
= TARGET_64BIT
? TImode
: DImode
;
3340 return adjust_address (op
, word_mode
, byte
);
3343 gcc_assert (!FP_REG_RTX_P (op
));
3345 return simplify_gen_subreg (word_mode
, op
, mode
, byte
);
3348 /* Return true if a 64-bit move from SRC to DEST should be split into two. */
3351 riscv_split_64bit_move_p (rtx dest
, rtx src
)
3356 /* There is no need to split if the FLI instruction in the `Zfa` extension can be used. */
3357 if (satisfies_constraint_zfli (src
))
3360 /* Allow FPR <-> FPR and FPR <-> MEM moves, and permit the special case
3361 of zeroing an FPR with FCVT.D.W. */
3362 if (TARGET_DOUBLE_FLOAT
3363 && ((FP_REG_RTX_P (src
) && FP_REG_RTX_P (dest
))
3364 || (FP_REG_RTX_P (dest
) && MEM_P (src
))
3365 || (FP_REG_RTX_P (src
) && MEM_P (dest
))
3366 || (FP_REG_RTX_P (dest
) && src
== CONST0_RTX (GET_MODE (src
)))))
3372 /* Split a doubleword move from SRC to DEST. On 32-bit targets,
3373 this function handles 64-bit moves for which riscv_split_64bit_move_p
3374 holds. For 64-bit targets, this function handles 128-bit moves. */
3377 riscv_split_doubleword_move (rtx dest
, rtx src
)
3379 /* ZFA or XTheadFmv has instructions for accessing the upper bits of a double. */
3380 if (!TARGET_64BIT
&& (TARGET_ZFA
|| TARGET_XTHEADFMV
))
3382 if (FP_REG_RTX_P (dest
))
3384 rtx low_src
= riscv_subword (src
, false);
3385 rtx high_src
= riscv_subword (src
, true);
3388 emit_insn (gen_movdfsisi3_rv32 (dest
, high_src
, low_src
));
3390 emit_insn (gen_th_fmv_hw_w_x (dest
, high_src
, low_src
));
3393 if (FP_REG_RTX_P (src
))
3395 rtx low_dest
= riscv_subword (dest
, false);
3396 rtx high_dest
= riscv_subword (dest
, true);
3400 emit_insn (gen_movsidf2_low_rv32 (low_dest
, src
));
3401 emit_insn (gen_movsidf2_high_rv32 (high_dest
, src
));
3406 emit_insn (gen_th_fmv_x_w (low_dest
, src
));
3407 emit_insn (gen_th_fmv_x_hw (high_dest
, src
));
3413 /* The operation can be split into two normal moves. Decide in
3414 which order to do them. */
3415 rtx low_dest
= riscv_subword (dest
, false);
3416 if (REG_P (low_dest
) && reg_overlap_mentioned_p (low_dest
, src
))
3418 riscv_emit_move (riscv_subword (dest
, true), riscv_subword (src
, true));
3419 riscv_emit_move (low_dest
, riscv_subword (src
, false));
3423 riscv_emit_move (low_dest
, riscv_subword (src
, false));
3424 riscv_emit_move (riscv_subword (dest
, true), riscv_subword (src
, true));
3428 /* Return the appropriate instructions to move SRC into DEST. Assume
3429 that SRC is operand 1 and DEST is operand 0. */
3432 riscv_output_move (rtx dest
, rtx src
)
3434 enum rtx_code dest_code
, src_code
;
3440 if ((insn
= th_output_move (dest
, src
)))
3443 dest_code
= GET_CODE (dest
);
3444 src_code
= GET_CODE (src
);
3445 mode
= GET_MODE (dest
);
3446 dbl_p
= (GET_MODE_SIZE (mode
).to_constant () == 8);
3447 width
= GET_MODE_SIZE (mode
).to_constant ();
3449 if (dbl_p
&& riscv_split_64bit_move_p (dest
, src
))
3452 if (dest_code
== REG
&& GP_REG_P (REGNO (dest
)))
3454 if (src_code
== REG
&& FP_REG_P (REGNO (src
)))
3459 return "fmv.x.h\t%0,%1";
3460 /* Using fmv.x.s + sign-extend to emulate fmv.x.h. */
3461 return "fmv.x.s\t%0,%1;slli\t%0,%0,16;srai\t%0,%0,16";
3463 return "fmv.x.s\t%0,%1";
3465 return "fmv.x.d\t%0,%1";
3468 if (src_code
== MEM
)
3471 case 1: return "lbu\t%0,%1";
3472 case 2: return "lhu\t%0,%1";
3473 case 4: return "lw\t%0,%1";
3474 case 8: return "ld\t%0,%1";
3477 if (src_code
== CONST_INT
)
3479 if (SMALL_OPERAND (INTVAL (src
)) || LUI_OPERAND (INTVAL (src
)))
3483 && SINGLE_BIT_MASK_OPERAND (INTVAL (src
)))
3484 return "bseti\t%0,zero,%S1";
3486 /* Should never reach here. */
3490 if (src_code
== HIGH
)
3491 return "lui\t%0,%h1";
3493 if (symbolic_operand (src
, VOIDmode
))
3494 switch (riscv_classify_symbolic_expression (src
))
3496 case SYMBOL_GOT_DISP
: return "la\t%0,%1";
3497 case SYMBOL_ABSOLUTE
: return "lla\t%0,%1";
3498 case SYMBOL_PCREL
: return "lla\t%0,%1";
3499 default: gcc_unreachable ();
3502 if ((src_code
== REG
&& GP_REG_P (REGNO (src
)))
3503 || (src
== CONST0_RTX (mode
)))
3505 if (dest_code
== REG
)
3507 if (GP_REG_P (REGNO (dest
)))
3508 return "mv\t%0,%z1";
3510 if (FP_REG_P (REGNO (dest
)))
3515 return "fmv.h.x\t%0,%z1";
3516 /* High 16 bits should be all-1, otherwise HW will treated
3517 as a n-bit canonical NaN, but isn't matter for softfloat. */
3518 return "fmv.s.x\t%0,%1";
3520 return "fmv.s.x\t%0,%z1";
3523 return "fmv.d.x\t%0,%z1";
3524 /* in RV32, we can emulate fmv.d.x %0, x0 using fcvt.d.w */
3525 gcc_assert (src
== CONST0_RTX (mode
));
3526 return "fcvt.d.w\t%0,x0";
3529 if (dest_code
== MEM
)
3532 case 1: return "sb\t%z1,%0";
3533 case 2: return "sh\t%z1,%0";
3534 case 4: return "sw\t%z1,%0";
3535 case 8: return "sd\t%z1,%0";
3538 if (src_code
== REG
&& FP_REG_P (REGNO (src
)))
3540 if (dest_code
== REG
&& FP_REG_P (REGNO (dest
)))
3545 return "fmv.h\t%0,%1";
3546 return "fmv.s\t%0,%1";
3548 return "fmv.s\t%0,%1";
3550 return "fmv.d\t%0,%1";
3553 if (dest_code
== MEM
)
3557 return "fsh\t%1,%0";
3559 return "fsw\t%1,%0";
3561 return "fsd\t%1,%0";
3564 if (dest_code
== REG
&& FP_REG_P (REGNO (dest
)))
3566 if (src_code
== MEM
)
3570 return "flh\t%0,%1";
3572 return "flw\t%0,%1";
3574 return "fld\t%0,%1";
3577 if (src_code
== CONST_DOUBLE
&& satisfies_constraint_zfli (src
))
3581 return "fli.h\t%0,%1";
3583 return "fli.s\t%0,%1";
3585 return "fli.d\t%0,%1";
3588 if (dest_code
== REG
&& GP_REG_P (REGNO (dest
)) && src_code
== CONST_POLY_INT
)
3590 /* We only want a single full vector register VLEN read after reload. */
3591 gcc_assert (known_eq (rtx_to_poly_int64 (src
), BYTES_PER_RISCV_VECTOR
));
3592 return "csrr\t%0,vlenb";
3598 riscv_output_return ()
3600 if (cfun
->machine
->naked_p
)
3607 /* Return true if CMP1 is a suitable second operand for integer ordering
3608 test CODE. See also the *sCC patterns in riscv.md. */
3611 riscv_int_order_operand_ok_p (enum rtx_code code
, rtx cmp1
)
3617 return reg_or_0_operand (cmp1
, VOIDmode
);
3621 return cmp1
== const1_rtx
;
3625 return arith_operand (cmp1
, VOIDmode
);
3628 return sle_operand (cmp1
, VOIDmode
);
3631 return sleu_operand (cmp1
, VOIDmode
);
3638 /* Return true if *CMP1 (of mode MODE) is a valid second operand for
3639 integer ordering test *CODE, or if an equivalent combination can
3640 be formed by adjusting *CODE and *CMP1. When returning true, update
3641 *CODE and *CMP1 with the chosen code and operand, otherwise leave
3645 riscv_canonicalize_int_order_test (enum rtx_code
*code
, rtx
*cmp1
,
3648 HOST_WIDE_INT plus_one
;
3650 if (riscv_int_order_operand_ok_p (*code
, *cmp1
))
3653 if (CONST_INT_P (*cmp1
))
3657 plus_one
= trunc_int_for_mode (UINTVAL (*cmp1
) + 1, mode
);
3658 if (INTVAL (*cmp1
) < plus_one
)
3661 *cmp1
= force_reg (mode
, GEN_INT (plus_one
));
3667 plus_one
= trunc_int_for_mode (UINTVAL (*cmp1
) + 1, mode
);
3671 *cmp1
= force_reg (mode
, GEN_INT (plus_one
));
3682 /* Compare CMP0 and CMP1 using ordering test CODE and store the result
3683 in TARGET. CMP0 and TARGET are register_operands. If INVERT_PTR
3684 is nonnull, it's OK to set TARGET to the inverse of the result and
3685 flip *INVERT_PTR instead. */
3688 riscv_emit_int_order_test (enum rtx_code code
, bool *invert_ptr
,
3689 rtx target
, rtx cmp0
, rtx cmp1
)
3693 /* First see if there is a RISCV instruction that can do this operation.
3694 If not, try doing the same for the inverse operation. If that also
3695 fails, force CMP1 into a register and try again. */
3696 mode
= GET_MODE (cmp0
);
3697 if (riscv_canonicalize_int_order_test (&code
, &cmp1
, mode
))
3698 riscv_emit_binary (code
, target
, cmp0
, cmp1
);
3701 enum rtx_code inv_code
= reverse_condition (code
);
3702 if (!riscv_canonicalize_int_order_test (&inv_code
, &cmp1
, mode
))
3704 cmp1
= force_reg (mode
, cmp1
);
3705 riscv_emit_int_order_test (code
, invert_ptr
, target
, cmp0
, cmp1
);
3707 else if (invert_ptr
== 0)
3709 rtx inv_target
= riscv_force_binary (word_mode
,
3710 inv_code
, cmp0
, cmp1
);
3711 riscv_emit_binary (EQ
, target
, inv_target
, const0_rtx
);
3715 *invert_ptr
= !*invert_ptr
;
3716 riscv_emit_binary (inv_code
, target
, cmp0
, cmp1
);
3721 /* Return a register that is zero iff CMP0 and CMP1 are equal.
3722 The register will have the same mode as CMP0. */
3725 riscv_zero_if_equal (rtx cmp0
, rtx cmp1
)
3727 if (cmp1
== const0_rtx
)
3730 return expand_binop (GET_MODE (cmp0
), sub_optab
,
3731 cmp0
, cmp1
, 0, 0, OPTAB_DIRECT
);
3734 /* Helper function for riscv_extend_comparands to Sign-extend the OP.
3735 However if the OP is SI subreg promoted with an inner DI, such as
3736 (subreg/s/v:SI (reg/v:DI) 0)
3737 just peel off the SUBREG to get DI, avoiding extraneous extension. */
3740 riscv_sign_extend_if_not_subreg_prom (rtx
*op
)
3742 if (GET_CODE (*op
) == SUBREG
3743 && SUBREG_PROMOTED_VAR_P (*op
)
3744 && SUBREG_PROMOTED_SIGNED_P (*op
)
3745 && (GET_MODE_SIZE (GET_MODE (XEXP (*op
, 0))).to_constant ()
3746 == GET_MODE_SIZE (word_mode
)))
3747 *op
= XEXP (*op
, 0);
3749 *op
= gen_rtx_SIGN_EXTEND (word_mode
, *op
);
3752 /* Sign- or zero-extend OP0 and OP1 for integer comparisons. */
3755 riscv_extend_comparands (rtx_code code
, rtx
*op0
, rtx
*op1
)
3757 /* Comparisons consider all XLEN bits, so extend sub-XLEN values. */
3758 if (GET_MODE_SIZE (word_mode
) > GET_MODE_SIZE (GET_MODE (*op0
)).to_constant ())
3760 /* It is more profitable to zero-extend QImode values. But not if the
3761 first operand has already been sign-extended, and the second one is
3762 is a constant or has already been sign-extended also. */
3763 if (unsigned_condition (code
) == code
3764 && (GET_MODE (*op0
) == QImode
3765 && ! (GET_CODE (*op0
) == SUBREG
3766 && SUBREG_PROMOTED_VAR_P (*op0
)
3767 && SUBREG_PROMOTED_SIGNED_P (*op0
)
3768 && (CONST_INT_P (*op1
)
3769 || (GET_CODE (*op1
) == SUBREG
3770 && SUBREG_PROMOTED_VAR_P (*op1
)
3771 && SUBREG_PROMOTED_SIGNED_P (*op1
))))))
3773 *op0
= gen_rtx_ZERO_EXTEND (word_mode
, *op0
);
3774 if (CONST_INT_P (*op1
))
3775 *op1
= GEN_INT ((uint8_t) INTVAL (*op1
));
3777 *op1
= gen_rtx_ZERO_EXTEND (word_mode
, *op1
);
3781 riscv_sign_extend_if_not_subreg_prom (op0
);
3783 if (*op1
!= const0_rtx
)
3784 riscv_sign_extend_if_not_subreg_prom (op1
);
3789 /* Convert a comparison into something that can be used in a branch or
3790 conditional move. On entry, *OP0 and *OP1 are the values being
3791 compared and *CODE is the code used to compare them.
3793 Update *CODE, *OP0 and *OP1 so that they describe the final comparison.
3794 If NEED_EQ_NE_P, then only EQ or NE comparisons against zero are
3798 riscv_emit_int_compare (enum rtx_code
*code
, rtx
*op0
, rtx
*op1
,
3799 bool need_eq_ne_p
= false)
3805 if (*code
== EQ
|| *code
== NE
)
3807 *op0
= riscv_zero_if_equal (cmp_op0
, cmp_op1
);
3813 if (splittable_const_int_operand (*op1
, VOIDmode
))
3815 HOST_WIDE_INT rhs
= INTVAL (*op1
);
3817 if (*code
== EQ
|| *code
== NE
)
3819 /* Convert e.g. OP0 == 2048 into OP0 - 2048 == 0. */
3820 if (SMALL_OPERAND (-rhs
))
3822 *op0
= riscv_force_binary (GET_MODE (*op0
), PLUS
, *op0
,
3829 static const enum rtx_code mag_comparisons
[][2] = {
3830 {LEU
, LTU
}, {GTU
, GEU
}, {LE
, LT
}, {GT
, GE
}
3833 /* Convert e.g. (OP0 <= 0xFFF) into (OP0 < 0x1000). */
3834 for (size_t i
= 0; i
< ARRAY_SIZE (mag_comparisons
); i
++)
3836 HOST_WIDE_INT new_rhs
;
3837 bool increment
= *code
== mag_comparisons
[i
][0];
3838 bool decrement
= *code
== mag_comparisons
[i
][1];
3839 if (!increment
&& !decrement
)
3842 new_rhs
= rhs
+ (increment
? 1 : -1);
3843 new_rhs
= trunc_int_for_mode (new_rhs
, GET_MODE (*op0
));
3844 if (riscv_integer_cost (new_rhs
) < riscv_integer_cost (rhs
)
3845 && (rhs
< 0) == (new_rhs
< 0))
3847 *op1
= GEN_INT (new_rhs
);
3848 *code
= mag_comparisons
[i
][increment
];
3855 riscv_extend_comparands (*code
, op0
, op1
);
3857 *op0
= force_reg (word_mode
, *op0
);
3858 if (*op1
!= const0_rtx
)
3859 *op1
= force_reg (word_mode
, *op1
);
3862 /* Like riscv_emit_int_compare, but for floating-point comparisons. */
3865 riscv_emit_float_compare (enum rtx_code
*code
, rtx
*op0
, rtx
*op1
)
3867 rtx tmp0
, tmp1
, cmp_op0
= *op0
, cmp_op1
= *op1
;
3868 enum rtx_code fp_code
= *code
;
3878 /* a == a && b == b */
3879 tmp0
= riscv_force_binary (word_mode
, EQ
, cmp_op0
, cmp_op0
);
3880 tmp1
= riscv_force_binary (word_mode
, EQ
, cmp_op1
, cmp_op1
);
3881 *op0
= riscv_force_binary (word_mode
, AND
, tmp0
, tmp1
);
3886 /* ordered(a, b) > (a == b) */
3888 tmp0
= riscv_force_binary (word_mode
, EQ
, cmp_op0
, cmp_op0
);
3889 tmp1
= riscv_force_binary (word_mode
, EQ
, cmp_op1
, cmp_op1
);
3890 *op0
= riscv_force_binary (word_mode
, AND
, tmp0
, tmp1
);
3891 *op1
= riscv_force_binary (word_mode
, EQ
, cmp_op0
, cmp_op1
);
3894 #define UNORDERED_COMPARISON(CODE, CMP) \
3897 *op0 = gen_reg_rtx (word_mode); \
3898 if (GET_MODE (cmp_op0) == SFmode && TARGET_64BIT) \
3899 emit_insn (gen_f##CMP##_quietsfdi4 (*op0, cmp_op0, cmp_op1)); \
3900 else if (GET_MODE (cmp_op0) == SFmode) \
3901 emit_insn (gen_f##CMP##_quietsfsi4 (*op0, cmp_op0, cmp_op1)); \
3902 else if (GET_MODE (cmp_op0) == DFmode && TARGET_64BIT) \
3903 emit_insn (gen_f##CMP##_quietdfdi4 (*op0, cmp_op0, cmp_op1)); \
3904 else if (GET_MODE (cmp_op0) == DFmode) \
3905 emit_insn (gen_f##CMP##_quietdfsi4 (*op0, cmp_op0, cmp_op1)); \
3906 else if (GET_MODE (cmp_op0) == HFmode && TARGET_64BIT) \
3907 emit_insn (gen_f##CMP##_quiethfdi4 (*op0, cmp_op0, cmp_op1)); \
3908 else if (GET_MODE (cmp_op0) == HFmode) \
3909 emit_insn (gen_f##CMP##_quiethfsi4 (*op0, cmp_op0, cmp_op1)); \
3911 gcc_unreachable (); \
3912 *op1 = const0_rtx; \
3916 std::swap (cmp_op0
, cmp_op1
);
3919 UNORDERED_COMPARISON(UNGT
, le
)
3922 std::swap (cmp_op0
, cmp_op1
);
3925 UNORDERED_COMPARISON(UNGE
, lt
)
3926 #undef UNORDERED_COMPARISON
3938 /* We have instructions for these cases. */
3939 *op0
= riscv_force_binary (word_mode
, fp_code
, cmp_op0
, cmp_op1
);
3944 /* (a < b) | (a > b) */
3945 tmp0
= riscv_force_binary (word_mode
, LT
, cmp_op0
, cmp_op1
);
3946 tmp1
= riscv_force_binary (word_mode
, GT
, cmp_op0
, cmp_op1
);
3947 *op0
= riscv_force_binary (word_mode
, IOR
, tmp0
, tmp1
);
3956 /* CODE-compare OP0 and OP1. Store the result in TARGET. */
3959 riscv_expand_int_scc (rtx target
, enum rtx_code code
, rtx op0
, rtx op1
, bool *invert_ptr
)
3961 riscv_extend_comparands (code
, &op0
, &op1
);
3962 op0
= force_reg (word_mode
, op0
);
3964 if (code
== EQ
|| code
== NE
)
3966 rtx zie
= riscv_zero_if_equal (op0
, op1
);
3967 riscv_emit_binary (code
, target
, zie
, const0_rtx
);
3970 riscv_emit_int_order_test (code
, invert_ptr
, target
, op0
, op1
);
3973 /* Like riscv_expand_int_scc, but for floating-point comparisons. */
3976 riscv_expand_float_scc (rtx target
, enum rtx_code code
, rtx op0
, rtx op1
)
3978 riscv_emit_float_compare (&code
, &op0
, &op1
);
3980 rtx cmp
= riscv_force_binary (word_mode
, code
, op0
, op1
);
3981 riscv_emit_set (target
, lowpart_subreg (SImode
, cmp
, word_mode
));
3984 /* Jump to LABEL if (CODE OP0 OP1) holds. */
3987 riscv_expand_conditional_branch (rtx label
, rtx_code code
, rtx op0
, rtx op1
)
3989 if (FLOAT_MODE_P (GET_MODE (op1
)))
3990 riscv_emit_float_compare (&code
, &op0
, &op1
);
3992 riscv_emit_int_compare (&code
, &op0
, &op1
);
3994 rtx condition
= gen_rtx_fmt_ee (code
, VOIDmode
, op0
, op1
);
3995 emit_jump_insn (gen_condjump (condition
, label
));
3998 /* Emit a cond move: If OP holds, move CONS to DEST; else move ALT to DEST.
3999 Return 0 if expansion failed. */
4002 riscv_expand_conditional_move (rtx dest
, rtx op
, rtx cons
, rtx alt
)
4004 machine_mode mode
= GET_MODE (dest
);
4005 rtx_code code
= GET_CODE (op
);
4006 rtx op0
= XEXP (op
, 0);
4007 rtx op1
= XEXP (op
, 1);
4008 bool need_eq_ne_p
= false;
4010 if (TARGET_XTHEADCONDMOV
4011 && GET_MODE_CLASS (mode
) == MODE_INT
4012 && reg_or_0_operand (cons
, mode
)
4013 && reg_or_0_operand (alt
, mode
)
4014 && (GET_MODE (op
) == mode
|| GET_MODE (op
) == E_VOIDmode
)
4015 && GET_MODE (op0
) == mode
4016 && GET_MODE (op1
) == mode
4017 && (code
== EQ
|| code
== NE
))
4018 need_eq_ne_p
= true;
4021 || (TARGET_SFB_ALU
&& GET_MODE (op0
) == word_mode
))
4023 riscv_emit_int_compare (&code
, &op0
, &op1
, need_eq_ne_p
);
4024 rtx cond
= gen_rtx_fmt_ee (code
, GET_MODE (op0
), op0
, op1
);
4026 /* The expander is a bit loose in its specification of the true
4027 arm of the conditional move. That allows us to support more
4028 cases for extensions which are more general than SFB. But
4029 does mean we need to force CONS into a register at this point. */
4030 cons
= force_reg (GET_MODE (dest
), cons
);
4031 emit_insn (gen_rtx_SET (dest
, gen_rtx_IF_THEN_ELSE (GET_MODE (dest
),
4035 else if (TARGET_ZICOND_LIKE
4036 && GET_MODE_CLASS (mode
) == MODE_INT
)
4038 /* The comparison must be comparing WORD_MODE objects. We must
4039 enforce that so that we don't strip away a sign_extension
4040 thinking it is unnecessary. We might consider using
4041 riscv_extend_operands if they are not already properly extended. */
4042 if ((GET_MODE (op0
) != word_mode
&& GET_MODE (op0
) != VOIDmode
)
4043 || (GET_MODE (op1
) != word_mode
&& GET_MODE (op1
) != VOIDmode
))
4046 /* Canonicalize the comparison. It must be an equality comparison
4047 against 0. If it isn't, then emit an SCC instruction so that
4048 we can then use an equality comparison against zero. */
4049 if (!equality_operator (op
, VOIDmode
) || op1
!= CONST0_RTX (mode
))
4051 enum rtx_code new_code
= NE
;
4052 bool *invert_ptr
= 0;
4053 bool invert
= false;
4055 if (code
== LE
|| code
== GE
)
4056 invert_ptr
= &invert
;
4058 /* Emit an scc like instruction into a temporary
4059 so that we can use an EQ/NE comparison. */
4060 rtx tmp
= gen_reg_rtx (word_mode
);
4062 /* We can support both FP and integer conditional moves. */
4063 if (INTEGRAL_MODE_P (GET_MODE (XEXP (op
, 0))))
4064 riscv_expand_int_scc (tmp
, code
, op0
, op1
, invert_ptr
);
4065 else if (FLOAT_MODE_P (GET_MODE (XEXP (op
, 0)))
4066 && fp_scc_comparison (op
, GET_MODE (op
)))
4067 riscv_expand_float_scc (tmp
, code
, op0
, op1
);
4071 /* If riscv_expand_int_scc inverts the condition, then it will
4072 flip the value of INVERT. We need to know where so that
4073 we can adjust it for our needs. */
4077 op
= gen_rtx_fmt_ee (new_code
, mode
, tmp
, const0_rtx
);
4079 /* We've generated a new comparison. Update the local variables. */
4080 code
= GET_CODE (op
);
4085 /* 0, reg or 0, imm */
4086 if (cons
== CONST0_RTX (mode
)
4088 || (CONST_INT_P (alt
) && alt
!= CONST0_RTX (mode
))))
4090 riscv_emit_int_compare (&code
, &op0
, &op1
, true);
4091 rtx cond
= gen_rtx_fmt_ee (code
, GET_MODE (op0
), op0
, op1
);
4092 alt
= force_reg (mode
, alt
);
4093 emit_insn (gen_rtx_SET (dest
,
4094 gen_rtx_IF_THEN_ELSE (mode
, cond
,
4099 else if (CONST_INT_P (cons
) && cons
!= CONST0_RTX (mode
)
4100 && CONST_INT_P (alt
) && alt
!= CONST0_RTX (mode
))
4102 riscv_emit_int_compare (&code
, &op0
, &op1
, true);
4103 rtx cond
= gen_rtx_fmt_ee (code
, GET_MODE (op0
), op0
, op1
);
4104 HOST_WIDE_INT t
= INTVAL (alt
) - INTVAL (cons
);
4105 alt
= force_reg (mode
, gen_int_mode (t
, mode
));
4106 emit_insn (gen_rtx_SET (dest
,
4107 gen_rtx_IF_THEN_ELSE (mode
, cond
,
4110 /* CONS might not fit into a signed 12 bit immediate suitable
4111 for an addi instruction. If that's the case, force it
4113 if (!SMALL_OPERAND (INTVAL (cons
)))
4114 cons
= force_reg (mode
, cons
);
4115 riscv_emit_binary (PLUS
, dest
, dest
, cons
);
4119 else if (CONST_INT_P (cons
) && cons
!= CONST0_RTX (mode
) && REG_P (alt
))
4121 /* Optimize for register value of 0. */
4122 if (code
== NE
&& rtx_equal_p (op0
, alt
) && op1
== CONST0_RTX (mode
))
4124 rtx cond
= gen_rtx_fmt_ee (code
, GET_MODE (op0
), op0
, op1
);
4125 cons
= force_reg (mode
, cons
);
4126 emit_insn (gen_rtx_SET (dest
,
4127 gen_rtx_IF_THEN_ELSE (mode
, cond
,
4132 riscv_emit_int_compare (&code
, &op0
, &op1
, true);
4133 rtx cond
= gen_rtx_fmt_ee (code
, GET_MODE (op0
), op0
, op1
);
4135 rtx temp1
= gen_reg_rtx (mode
);
4136 rtx temp2
= gen_int_mode (-1 * INTVAL (cons
), mode
);
4138 /* TEMP2 and/or CONS might not fit into a signed 12 bit immediate
4139 suitable for an addi instruction. If that's the case, force it
4141 if (!SMALL_OPERAND (INTVAL (temp2
)))
4142 temp2
= force_reg (mode
, temp2
);
4143 if (!SMALL_OPERAND (INTVAL (cons
)))
4144 cons
= force_reg (mode
, cons
);
4146 riscv_emit_binary (PLUS
, temp1
, alt
, temp2
);
4147 emit_insn (gen_rtx_SET (dest
,
4148 gen_rtx_IF_THEN_ELSE (mode
, cond
,
4151 riscv_emit_binary (PLUS
, dest
, dest
, cons
);
4154 /* reg, 0 or imm, 0 */
4155 else if ((REG_P (cons
)
4156 || (CONST_INT_P (cons
) && cons
!= CONST0_RTX (mode
)))
4157 && alt
== CONST0_RTX (mode
))
4159 riscv_emit_int_compare (&code
, &op0
, &op1
, true);
4160 rtx cond
= gen_rtx_fmt_ee (code
, GET_MODE (op0
), op0
, op1
);
4161 cons
= force_reg (mode
, cons
);
4162 emit_insn (gen_rtx_SET (dest
, gen_rtx_IF_THEN_ELSE (mode
, cond
,
4167 else if (REG_P (cons
) && CONST_INT_P (alt
) && alt
!= CONST0_RTX (mode
))
4169 /* Optimize for register value of 0. */
4170 if (code
== EQ
&& rtx_equal_p (op0
, cons
) && op1
== CONST0_RTX (mode
))
4172 rtx cond
= gen_rtx_fmt_ee (code
, GET_MODE (op0
), op0
, op1
);
4173 alt
= force_reg (mode
, alt
);
4174 emit_insn (gen_rtx_SET (dest
,
4175 gen_rtx_IF_THEN_ELSE (mode
, cond
,
4180 riscv_emit_int_compare (&code
, &op0
, &op1
, true);
4181 rtx cond
= gen_rtx_fmt_ee (code
, GET_MODE (op0
), op0
, op1
);
4183 rtx temp1
= gen_reg_rtx (mode
);
4184 rtx temp2
= gen_int_mode (-1 * INTVAL (alt
), mode
);
4186 /* TEMP2 and/or ALT might not fit into a signed 12 bit immediate
4187 suitable for an addi instruction. If that's the case, force it
4189 if (!SMALL_OPERAND (INTVAL (temp2
)))
4190 temp2
= force_reg (mode
, temp2
);
4191 if (!SMALL_OPERAND (INTVAL (alt
)))
4192 alt
= force_reg (mode
, alt
);
4194 riscv_emit_binary (PLUS
, temp1
, cons
, temp2
);
4195 emit_insn (gen_rtx_SET (dest
,
4196 gen_rtx_IF_THEN_ELSE (mode
, cond
,
4198 CONST0_RTX (mode
))));
4199 riscv_emit_binary (PLUS
, dest
, dest
, alt
);
4203 else if (REG_P (cons
) && REG_P (alt
))
4205 if ((code
== EQ
&& rtx_equal_p (cons
, op0
))
4206 || (code
== NE
&& rtx_equal_p (alt
, op0
)))
4208 rtx cond
= gen_rtx_fmt_ee (code
, GET_MODE (op0
), op0
, op1
);
4209 if (!rtx_equal_p (cons
, op0
))
4210 std::swap (alt
, cons
);
4211 alt
= force_reg (mode
, alt
);
4212 emit_insn (gen_rtx_SET (dest
,
4213 gen_rtx_IF_THEN_ELSE (mode
, cond
,
4218 rtx reg1
= gen_reg_rtx (mode
);
4219 rtx reg2
= gen_reg_rtx (mode
);
4220 riscv_emit_int_compare (&code
, &op0
, &op1
, true);
4221 rtx cond1
= gen_rtx_fmt_ee (code
, GET_MODE (op0
), op0
, op1
);
4222 rtx cond2
= gen_rtx_fmt_ee (code
== NE
? EQ
: NE
,
4223 GET_MODE (op0
), op0
, op1
);
4224 emit_insn (gen_rtx_SET (reg2
,
4225 gen_rtx_IF_THEN_ELSE (mode
, cond2
,
4228 emit_insn (gen_rtx_SET (reg1
,
4229 gen_rtx_IF_THEN_ELSE (mode
, cond1
,
4232 riscv_emit_binary (IOR
, dest
, reg1
, reg2
);
4240 /* Implement TARGET_FUNCTION_ARG_BOUNDARY. Every parameter gets at
4241 least PARM_BOUNDARY bits of alignment, but will be given anything up
4242 to PREFERRED_STACK_BOUNDARY bits if the type requires it. */
4245 riscv_function_arg_boundary (machine_mode mode
, const_tree type
)
4247 unsigned int alignment
;
4249 /* Use natural alignment if the type is not aggregate data. */
4250 if (type
&& !AGGREGATE_TYPE_P (type
))
4251 alignment
= TYPE_ALIGN (TYPE_MAIN_VARIANT (type
));
4253 alignment
= type
? TYPE_ALIGN (type
) : GET_MODE_ALIGNMENT (mode
);
4255 return MIN (PREFERRED_STACK_BOUNDARY
, MAX (PARM_BOUNDARY
, alignment
));
4258 /* If MODE represents an argument that can be passed or returned in
4259 floating-point registers, return the number of registers, else 0. */
4262 riscv_pass_mode_in_fpr_p (machine_mode mode
)
4264 if (GET_MODE_UNIT_SIZE (mode
) <= UNITS_PER_FP_ARG
)
4266 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
)
4269 if (GET_MODE_CLASS (mode
) == MODE_COMPLEX_FLOAT
)
4278 HOST_WIDE_INT offset
;
4279 } riscv_aggregate_field
;
4281 /* Identify subfields of aggregates that are candidates for passing in
4282 floating-point registers. */
4285 riscv_flatten_aggregate_field (const_tree type
,
4286 riscv_aggregate_field fields
[2],
4287 int n
, HOST_WIDE_INT offset
,
4288 bool ignore_zero_width_bit_field_p
)
4290 switch (TREE_CODE (type
))
4293 /* Can't handle incomplete types nor sizes that are not fixed. */
4294 if (!COMPLETE_TYPE_P (type
)
4295 || TREE_CODE (TYPE_SIZE (type
)) != INTEGER_CST
4296 || !tree_fits_uhwi_p (TYPE_SIZE (type
)))
4299 for (tree f
= TYPE_FIELDS (type
); f
; f
= DECL_CHAIN (f
))
4300 if (TREE_CODE (f
) == FIELD_DECL
)
4302 if (!TYPE_P (TREE_TYPE (f
)))
4305 /* The C++ front end strips zero-length bit-fields from structs.
4306 So we need to ignore them in the C front end to make C code
4307 compatible with C++ code. */
4308 if (ignore_zero_width_bit_field_p
4309 && DECL_BIT_FIELD (f
)
4310 && (DECL_SIZE (f
) == NULL_TREE
4311 || integer_zerop (DECL_SIZE (f
))))
4315 HOST_WIDE_INT pos
= offset
+ int_byte_position (f
);
4316 n
= riscv_flatten_aggregate_field (TREE_TYPE (f
),
4318 ignore_zero_width_bit_field_p
);
4327 HOST_WIDE_INT n_elts
;
4328 riscv_aggregate_field subfields
[2];
4329 tree index
= TYPE_DOMAIN (type
);
4330 tree elt_size
= TYPE_SIZE_UNIT (TREE_TYPE (type
));
4331 int n_subfields
= riscv_flatten_aggregate_field (TREE_TYPE (type
),
4332 subfields
, 0, offset
,
4333 ignore_zero_width_bit_field_p
);
4335 /* Can't handle incomplete types nor sizes that are not fixed. */
4336 if (n_subfields
<= 0
4337 || !COMPLETE_TYPE_P (type
)
4338 || TREE_CODE (TYPE_SIZE (type
)) != INTEGER_CST
4340 || !TYPE_MAX_VALUE (index
)
4341 || !tree_fits_uhwi_p (TYPE_MAX_VALUE (index
))
4342 || !TYPE_MIN_VALUE (index
)
4343 || !tree_fits_uhwi_p (TYPE_MIN_VALUE (index
))
4344 || !tree_fits_uhwi_p (elt_size
))
4347 n_elts
= 1 + tree_to_uhwi (TYPE_MAX_VALUE (index
))
4348 - tree_to_uhwi (TYPE_MIN_VALUE (index
));
4349 gcc_assert (n_elts
>= 0);
4351 for (HOST_WIDE_INT i
= 0; i
< n_elts
; i
++)
4352 for (int j
= 0; j
< n_subfields
; j
++)
4357 fields
[n
] = subfields
[j
];
4358 fields
[n
++].offset
+= i
* tree_to_uhwi (elt_size
);
4366 /* Complex type need consume 2 field, so n must be 0. */
4370 HOST_WIDE_INT elt_size
= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (type
))).to_constant ();
4372 if (elt_size
<= UNITS_PER_FP_ARG
)
4374 fields
[0].type
= TREE_TYPE (type
);
4375 fields
[0].offset
= offset
;
4376 fields
[1].type
= TREE_TYPE (type
);
4377 fields
[1].offset
= offset
+ elt_size
;
4387 && ((SCALAR_FLOAT_TYPE_P (type
)
4388 && GET_MODE_SIZE (TYPE_MODE (type
)).to_constant () <= UNITS_PER_FP_ARG
)
4389 || (INTEGRAL_TYPE_P (type
)
4390 && GET_MODE_SIZE (TYPE_MODE (type
)).to_constant () <= UNITS_PER_WORD
)))
4392 fields
[n
].type
= type
;
4393 fields
[n
].offset
= offset
;
4401 /* Identify candidate aggregates for passing in floating-point registers.
4402 Candidates have at most two fields after flattening. */
4405 riscv_flatten_aggregate_argument (const_tree type
,
4406 riscv_aggregate_field fields
[2],
4407 bool ignore_zero_width_bit_field_p
)
4409 if (!type
|| TREE_CODE (type
) != RECORD_TYPE
)
4412 return riscv_flatten_aggregate_field (type
, fields
, 0, 0,
4413 ignore_zero_width_bit_field_p
);
4416 /* See whether TYPE is a record whose fields should be returned in one or
4417 two floating-point registers. If so, populate FIELDS accordingly. */
4420 riscv_pass_aggregate_in_fpr_pair_p (const_tree type
,
4421 riscv_aggregate_field fields
[2])
4423 static int warned
= 0;
4425 /* This is the old ABI, which differs for C++ and C. */
4426 int n_old
= riscv_flatten_aggregate_argument (type
, fields
, false);
4427 for (int i
= 0; i
< n_old
; i
++)
4428 if (!SCALAR_FLOAT_TYPE_P (fields
[i
].type
))
4434 /* This is the new ABI, which is the same for C++ and C. */
4435 int n_new
= riscv_flatten_aggregate_argument (type
, fields
, true);
4436 for (int i
= 0; i
< n_new
; i
++)
4437 if (!SCALAR_FLOAT_TYPE_P (fields
[i
].type
))
4443 if ((n_old
!= n_new
) && (warned
== 0))
4445 warning (OPT_Wpsabi
, "ABI for flattened struct with zero-length "
4446 "bit-fields changed in GCC 10");
4450 return n_new
> 0 ? n_new
: 0;
4453 /* See whether TYPE is a record whose fields should be returned in one or
4454 floating-point register and one integer register. If so, populate
4455 FIELDS accordingly. */
4458 riscv_pass_aggregate_in_fpr_and_gpr_p (const_tree type
,
4459 riscv_aggregate_field fields
[2])
4461 static int warned
= 0;
4463 /* This is the old ABI, which differs for C++ and C. */
4464 unsigned num_int_old
= 0, num_float_old
= 0;
4465 int n_old
= riscv_flatten_aggregate_argument (type
, fields
, false);
4466 for (int i
= 0; i
< n_old
; i
++)
4468 num_float_old
+= SCALAR_FLOAT_TYPE_P (fields
[i
].type
);
4469 num_int_old
+= INTEGRAL_TYPE_P (fields
[i
].type
);
4472 /* This is the new ABI, which is the same for C++ and C. */
4473 unsigned num_int_new
= 0, num_float_new
= 0;
4474 int n_new
= riscv_flatten_aggregate_argument (type
, fields
, true);
4475 for (int i
= 0; i
< n_new
; i
++)
4477 num_float_new
+= SCALAR_FLOAT_TYPE_P (fields
[i
].type
);
4478 num_int_new
+= INTEGRAL_TYPE_P (fields
[i
].type
);
4481 if (((num_int_old
== 1 && num_float_old
== 1
4482 && (num_int_old
!= num_int_new
|| num_float_old
!= num_float_new
))
4483 || (num_int_new
== 1 && num_float_new
== 1
4484 && (num_int_old
!= num_int_new
|| num_float_old
!= num_float_new
)))
4487 warning (OPT_Wpsabi
, "ABI for flattened struct with zero-length "
4488 "bit-fields changed in GCC 10");
4492 return num_int_new
== 1 && num_float_new
== 1;
4495 /* Return the representation of an argument passed or returned in an FPR
4496 when the value has mode VALUE_MODE and the type has TYPE_MODE. The
4497 two modes may be different for structures like:
4499 struct __attribute__((packed)) foo { float f; }
4501 where the SFmode value "f" is passed in REGNO but the struct itself
4502 has mode BLKmode. */
4505 riscv_pass_fpr_single (machine_mode type_mode
, unsigned regno
,
4506 machine_mode value_mode
,
4507 HOST_WIDE_INT offset
)
4509 rtx x
= gen_rtx_REG (value_mode
, regno
);
4511 if (type_mode
!= value_mode
)
4513 x
= gen_rtx_EXPR_LIST (VOIDmode
, x
, GEN_INT (offset
));
4514 x
= gen_rtx_PARALLEL (type_mode
, gen_rtvec (1, x
));
4519 /* Pass or return a composite value in the FPR pair REGNO and REGNO + 1.
4520 MODE is the mode of the composite. MODE1 and OFFSET1 are the mode and
4521 byte offset for the first value, likewise MODE2 and OFFSET2 for the
4525 riscv_pass_fpr_pair (machine_mode mode
, unsigned regno1
,
4526 machine_mode mode1
, HOST_WIDE_INT offset1
,
4527 unsigned regno2
, machine_mode mode2
,
4528 HOST_WIDE_INT offset2
)
4530 return gen_rtx_PARALLEL
4533 gen_rtx_EXPR_LIST (VOIDmode
,
4534 gen_rtx_REG (mode1
, regno1
),
4536 gen_rtx_EXPR_LIST (VOIDmode
,
4537 gen_rtx_REG (mode2
, regno2
),
4538 GEN_INT (offset2
))));
4541 /* Return true if a vector type is included in the type TYPE. */
4544 riscv_arg_has_vector (const_tree type
)
4546 if (riscv_v_ext_mode_p (TYPE_MODE (type
)))
4549 if (!COMPLETE_TYPE_P (type
))
4552 switch (TREE_CODE (type
))
4555 /* If it is a record, it is further determined whether its fields have
4557 for (tree f
= TYPE_FIELDS (type
); f
; f
= DECL_CHAIN (f
))
4558 if (TREE_CODE (f
) == FIELD_DECL
)
4560 tree field_type
= TREE_TYPE (f
);
4561 if (!TYPE_P (field_type
))
4564 if (riscv_arg_has_vector (field_type
))
4569 return riscv_arg_has_vector (TREE_TYPE (type
));
4577 /* Pass the type to check whether it's a vector type or contains vector type.
4578 Only check the value type and no checking for vector pointer type. */
4581 riscv_pass_in_vector_p (const_tree type
)
4583 static int warned
= 0;
4585 if (type
&& riscv_vector::lookup_vector_type_attribute (type
) && !warned
)
4587 warning (OPT_Wpsabi
,
4588 "ABI for the vector type is currently in experimental stage and "
4589 "may changes in the upcoming version of GCC.");
4594 /* Initialize a variable CUM of type CUMULATIVE_ARGS
4595 for a call to a function whose data type is FNTYPE.
4596 For a library call, FNTYPE is 0. */
4599 riscv_init_cumulative_args (CUMULATIVE_ARGS
*cum
,
4600 tree fntype ATTRIBUTE_UNUSED
,
4601 rtx libname ATTRIBUTE_UNUSED
,
4603 int caller ATTRIBUTE_UNUSED
)
4605 memset (cum
, 0, sizeof (*cum
));
4608 cum
->variant_cc
= (riscv_cc
) fntype_abi (fntype
).id ();
4610 cum
->variant_cc
= RISCV_CC_BASE
;
4614 const tree_function_decl
&fn
4615 = FUNCTION_DECL_CHECK (fndecl
)->function_decl
;
4617 if (fn
.built_in_class
== NOT_BUILT_IN
)
4618 cum
->rvv_psabi_warning
= 1;
4622 /* Return true if TYPE is a vector type that can be passed in vector registers.
4626 riscv_vector_type_p (const_tree type
)
4628 /* Currently, only builtin scalabler vector type is allowed, in the future,
4629 more vector types may be allowed, such as GNU vector type, etc. */
4630 return riscv_vector::builtin_type_p (type
);
4634 riscv_hard_regno_nregs (unsigned int regno
, machine_mode mode
);
4636 /* Subroutine of riscv_get_arg_info. */
4639 riscv_get_vector_arg (struct riscv_arg_info
*info
, const CUMULATIVE_ARGS
*cum
,
4640 machine_mode mode
, bool return_p
)
4642 gcc_assert (riscv_v_ext_mode_p (mode
));
4644 info
->mr_offset
= cum
->num_mrs
;
4645 if (GET_MODE_CLASS (mode
) == MODE_VECTOR_BOOL
)
4647 /* For scalable mask return value. */
4649 return gen_rtx_REG (mode
, V_REG_FIRST
);
4651 /* For the first scalable mask argument. */
4652 if (info
->mr_offset
< MAX_ARGS_IN_MASK_REGISTERS
)
4655 return gen_rtx_REG (mode
, V_REG_FIRST
);
4659 /* Rest scalable mask arguments are treated as scalable data
4664 /* The number and alignment of vector registers need for this scalable vector
4665 argument. When the mode size is less than a full vector, we use 1 vector
4666 register to pass. Just call TARGET_HARD_REGNO_NREGS for the number
4668 int nregs
= riscv_hard_regno_nregs (V_ARG_FIRST
, mode
);
4669 int LMUL
= riscv_v_ext_tuple_mode_p (mode
)
4670 ? nregs
/ riscv_vector::get_nf (mode
)
4672 int arg_reg_start
= V_ARG_FIRST
- V_REG_FIRST
;
4673 int arg_reg_end
= V_ARG_LAST
- V_REG_FIRST
;
4674 int aligned_reg_start
= ROUND_UP (arg_reg_start
, LMUL
);
4676 /* For scalable data and scalable tuple return value. */
4678 return gen_rtx_REG (mode
, aligned_reg_start
+ V_REG_FIRST
);
4680 /* Iterate through the USED_VRS array to find vector register groups that have
4681 not been allocated and the first register is aligned with LMUL. */
4682 for (int i
= aligned_reg_start
; i
+ nregs
- 1 <= arg_reg_end
; i
+= LMUL
)
4684 /* The index in USED_VRS array. */
4685 int idx
= i
- arg_reg_start
;
4686 /* Find the first register unused. */
4687 if (!cum
->used_vrs
[idx
])
4689 bool find_set
= true;
4690 /* Ensure there are NREGS continuous unused registers. */
4691 for (int j
= 1; j
< nregs
; j
++)
4692 if (cum
->used_vrs
[idx
+ j
])
4695 /* Update I to the last aligned register which
4696 cannot be used and the next iteration will add
4698 i
+= (j
/ LMUL
) * LMUL
;
4704 info
->num_vrs
= nregs
;
4705 info
->vr_offset
= idx
;
4706 return gen_rtx_REG (mode
, i
+ V_REG_FIRST
);
4714 /* Fill INFO with information about a single argument, and return an RTL
4715 pattern to pass or return the argument. Return NULL_RTX if argument cannot
4716 pass or return in registers, then the argument may be passed by reference or
4717 through the stack or . CUM is the cumulative state for earlier arguments.
4718 MODE is the mode of this argument and TYPE is its type (if known). NAMED is
4719 true if this is a named (fixed) argument rather than a variable one. RETURN_P
4720 is true if returning the argument, or false if passing the argument. */
4723 riscv_get_arg_info (struct riscv_arg_info
*info
, const CUMULATIVE_ARGS
*cum
,
4724 machine_mode mode
, const_tree type
, bool named
,
4727 unsigned num_bytes
, num_words
;
4728 unsigned fpr_base
= return_p
? FP_RETURN
: FP_ARG_FIRST
;
4729 unsigned gpr_base
= return_p
? GP_RETURN
: GP_ARG_FIRST
;
4730 unsigned alignment
= riscv_function_arg_boundary (mode
, type
);
4732 memset (info
, 0, sizeof (*info
));
4733 info
->gpr_offset
= cum
->num_gprs
;
4734 info
->fpr_offset
= cum
->num_fprs
;
4736 if (cum
->rvv_psabi_warning
)
4738 /* Only check existing of vector type. */
4739 riscv_pass_in_vector_p (type
);
4742 /* When disable vector_abi or scalable vector argument is anonymous, this
4743 argument is passed by reference. */
4744 if (riscv_v_ext_mode_p (mode
) && (!riscv_vector_abi
|| !named
))
4749 riscv_aggregate_field fields
[2];
4750 unsigned fregno
= fpr_base
+ info
->fpr_offset
;
4751 unsigned gregno
= gpr_base
+ info
->gpr_offset
;
4753 /* Pass one- or two-element floating-point aggregates in FPRs. */
4754 if ((info
->num_fprs
= riscv_pass_aggregate_in_fpr_pair_p (type
, fields
))
4755 && info
->fpr_offset
+ info
->num_fprs
<= MAX_ARGS_IN_REGISTERS
)
4756 switch (info
->num_fprs
)
4759 return riscv_pass_fpr_single (mode
, fregno
,
4760 TYPE_MODE (fields
[0].type
),
4764 return riscv_pass_fpr_pair (mode
, fregno
,
4765 TYPE_MODE (fields
[0].type
),
4768 TYPE_MODE (fields
[1].type
),
4775 /* Pass real and complex floating-point numbers in FPRs. */
4776 if ((info
->num_fprs
= riscv_pass_mode_in_fpr_p (mode
))
4777 && info
->fpr_offset
+ info
->num_fprs
<= MAX_ARGS_IN_REGISTERS
)
4778 switch (GET_MODE_CLASS (mode
))
4781 return gen_rtx_REG (mode
, fregno
);
4783 case MODE_COMPLEX_FLOAT
:
4784 return riscv_pass_fpr_pair (mode
, fregno
, GET_MODE_INNER (mode
), 0,
4785 fregno
+ 1, GET_MODE_INNER (mode
),
4786 GET_MODE_UNIT_SIZE (mode
));
4792 /* Pass structs with one float and one integer in an FPR and a GPR. */
4793 if (riscv_pass_aggregate_in_fpr_and_gpr_p (type
, fields
)
4794 && info
->gpr_offset
< MAX_ARGS_IN_REGISTERS
4795 && info
->fpr_offset
< MAX_ARGS_IN_REGISTERS
)
4800 if (!SCALAR_FLOAT_TYPE_P (fields
[0].type
))
4801 std::swap (fregno
, gregno
);
4803 return riscv_pass_fpr_pair (mode
, fregno
, TYPE_MODE (fields
[0].type
),
4805 gregno
, TYPE_MODE (fields
[1].type
),
4809 /* For scalable vector argument. */
4810 if (riscv_vector_type_p (type
) && riscv_v_ext_mode_p (mode
))
4811 return riscv_get_vector_arg (info
, cum
, mode
, return_p
);
4814 /* Work out the size of the argument. */
4815 num_bytes
= type
? int_size_in_bytes (type
) : GET_MODE_SIZE (mode
).to_constant ();
4816 num_words
= (num_bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
4818 /* Doubleword-aligned varargs start on an even register boundary. */
4819 if (!named
&& num_bytes
!= 0 && alignment
> BITS_PER_WORD
)
4820 info
->gpr_offset
+= info
->gpr_offset
& 1;
4822 /* Partition the argument between registers and stack. */
4824 info
->num_gprs
= MIN (num_words
, MAX_ARGS_IN_REGISTERS
- info
->gpr_offset
);
4825 info
->stack_p
= (num_words
- info
->num_gprs
) != 0;
4827 if (info
->num_gprs
|| return_p
)
4828 return gen_rtx_REG (mode
, gpr_base
+ info
->gpr_offset
);
4833 /* Implement TARGET_FUNCTION_ARG. */
4836 riscv_function_arg (cumulative_args_t cum_v
, const function_arg_info
&arg
)
4838 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
4839 struct riscv_arg_info info
;
4841 if (arg
.end_marker_p ())
4842 /* Return the calling convention that used by the current function. */
4843 return gen_int_mode (cum
->variant_cc
, SImode
);
4845 return riscv_get_arg_info (&info
, cum
, arg
.mode
, arg
.type
, arg
.named
, false);
4848 /* Implement TARGET_FUNCTION_ARG_ADVANCE. */
4851 riscv_function_arg_advance (cumulative_args_t cum_v
,
4852 const function_arg_info
&arg
)
4854 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
4855 struct riscv_arg_info info
;
4857 riscv_get_arg_info (&info
, cum
, arg
.mode
, arg
.type
, arg
.named
, false);
4859 /* Set the corresponding register in USED_VRS to used status. */
4860 for (unsigned int i
= 0; i
< info
.num_vrs
; i
++)
4862 gcc_assert (!cum
->used_vrs
[info
.vr_offset
+ i
]);
4863 cum
->used_vrs
[info
.vr_offset
+ i
] = true;
4866 if ((info
.num_vrs
> 0 || info
.num_mrs
> 0) && cum
->variant_cc
!= RISCV_CC_V
)
4868 error ("RVV type %qT cannot be passed to an unprototyped function",
4870 /* Avoid repeating the message */
4871 cum
->variant_cc
= RISCV_CC_V
;
4874 /* Advance the register count. This has the effect of setting
4875 num_gprs to MAX_ARGS_IN_REGISTERS if a doubleword-aligned
4876 argument required us to skip the final GPR and pass the whole
4877 argument on the stack. */
4878 cum
->num_fprs
= info
.fpr_offset
+ info
.num_fprs
;
4879 cum
->num_gprs
= info
.gpr_offset
+ info
.num_gprs
;
4880 cum
->num_mrs
= info
.mr_offset
+ info
.num_mrs
;
4883 /* Implement TARGET_ARG_PARTIAL_BYTES. */
4886 riscv_arg_partial_bytes (cumulative_args_t cum
,
4887 const function_arg_info
&generic_arg
)
4889 struct riscv_arg_info arg
;
4891 riscv_get_arg_info (&arg
, get_cumulative_args (cum
), generic_arg
.mode
,
4892 generic_arg
.type
, generic_arg
.named
, false);
4893 return arg
.stack_p
? arg
.num_gprs
* UNITS_PER_WORD
: 0;
4896 /* Implement FUNCTION_VALUE and LIBCALL_VALUE. For normal calls,
4897 VALTYPE is the return type and MODE is VOIDmode. For libcalls,
4898 VALTYPE is null and MODE is the mode of the return value. */
4901 riscv_function_value (const_tree type
, const_tree func
, machine_mode mode
)
4903 struct riscv_arg_info info
;
4904 CUMULATIVE_ARGS args
;
4908 int unsigned_p
= TYPE_UNSIGNED (type
);
4910 mode
= TYPE_MODE (type
);
4912 /* Since TARGET_PROMOTE_FUNCTION_MODE unconditionally promotes,
4913 return values, promote the mode here too. */
4914 mode
= promote_function_mode (type
, mode
, &unsigned_p
, func
, 1);
4917 memset (&args
, 0, sizeof args
);
4919 const_tree arg_type
= type
;
4920 if (func
&& DECL_RESULT (func
))
4922 const tree_function_decl
&fn
= FUNCTION_DECL_CHECK (func
)->function_decl
;
4923 if (fn
.built_in_class
== NOT_BUILT_IN
)
4924 args
.rvv_psabi_warning
= 1;
4926 arg_type
= TREE_TYPE (DECL_RESULT (func
));
4929 return riscv_get_arg_info (&info
, &args
, mode
, arg_type
, true, true);
4932 /* Implement TARGET_PASS_BY_REFERENCE. */
4935 riscv_pass_by_reference (cumulative_args_t cum_v
, const function_arg_info
&arg
)
4937 HOST_WIDE_INT size
= arg
.type_size_in_bytes ().to_constant ();;
4938 struct riscv_arg_info info
;
4939 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
4941 /* ??? std_gimplify_va_arg_expr passes NULL for cum. Fortunately, we
4942 never pass variadic arguments in floating-point and vector registers,
4943 so we can avoid the call to riscv_get_arg_info in this case. */
4946 /* Don't pass by reference if we can use a floating-point register. */
4947 riscv_get_arg_info (&info
, cum
, arg
.mode
, arg
.type
, arg
.named
, false);
4951 /* Don't pass by reference if we can use vector register groups. */
4952 if (info
.num_vrs
> 0 || info
.num_mrs
> 0)
4956 /* When vector abi disabled(without --param=riscv-vector-abi option) or
4957 scalable vector argument is anonymous or cannot be passed through vector
4958 registers, this argument is passed by reference. */
4959 if (riscv_v_ext_mode_p (arg
.mode
))
4962 /* Pass by reference if the data do not fit in two integer registers. */
4963 return !IN_RANGE (size
, 0, 2 * UNITS_PER_WORD
);
4966 /* Implement TARGET_RETURN_IN_MEMORY. */
4969 riscv_return_in_memory (const_tree type
, const_tree fndecl ATTRIBUTE_UNUSED
)
4971 CUMULATIVE_ARGS args
;
4972 cumulative_args_t cum
= pack_cumulative_args (&args
);
4974 /* The rules for returning in memory are the same as for passing the
4975 first named argument by reference. */
4976 memset (&args
, 0, sizeof args
);
4977 function_arg_info
arg (const_cast<tree
> (type
), /*named=*/true);
4978 return riscv_pass_by_reference (cum
, arg
);
4981 /* Implement TARGET_SETUP_INCOMING_VARARGS. */
4984 riscv_setup_incoming_varargs (cumulative_args_t cum
,
4985 const function_arg_info
&arg
,
4986 int *pretend_size ATTRIBUTE_UNUSED
, int no_rtl
)
4988 CUMULATIVE_ARGS local_cum
;
4991 /* The caller has advanced CUM up to, but not beyond, the last named
4992 argument. Advance a local copy of CUM past the last "real" named
4993 argument, to find out how many registers are left over. */
4994 local_cum
= *get_cumulative_args (cum
);
4995 if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl
)))
4996 riscv_function_arg_advance (pack_cumulative_args (&local_cum
), arg
);
4998 /* Found out how many registers we need to save. */
4999 gp_saved
= MAX_ARGS_IN_REGISTERS
- local_cum
.num_gprs
;
5001 if (!no_rtl
&& gp_saved
> 0)
5003 rtx ptr
= plus_constant (Pmode
, virtual_incoming_args_rtx
,
5004 REG_PARM_STACK_SPACE (cfun
->decl
)
5005 - gp_saved
* UNITS_PER_WORD
);
5006 rtx mem
= gen_frame_mem (BLKmode
, ptr
);
5007 set_mem_alias_set (mem
, get_varargs_alias_set ());
5009 move_block_from_reg (local_cum
.num_gprs
+ GP_ARG_FIRST
,
5012 if (REG_PARM_STACK_SPACE (cfun
->decl
) == 0)
5013 cfun
->machine
->varargs_size
= gp_saved
* UNITS_PER_WORD
;
5016 /* Return the descriptor of the Standard Vector Calling Convention Variant. */
5018 static const predefined_function_abi
&
5021 predefined_function_abi
&v_abi
= function_abis
[RISCV_CC_V
];
5022 if (!v_abi
.initialized_p ())
5024 HARD_REG_SET full_reg_clobbers
5025 = default_function_abi
.full_reg_clobbers ();
5026 /* Callee-saved vector registers: v1-v7, v24-v31. */
5027 for (int regno
= V_REG_FIRST
+ 1; regno
<= V_REG_FIRST
+ 7; regno
+= 1)
5028 CLEAR_HARD_REG_BIT (full_reg_clobbers
, regno
);
5029 for (int regno
= V_REG_FIRST
+ 24; regno
<= V_REG_FIRST
+ 31; regno
+= 1)
5030 CLEAR_HARD_REG_BIT (full_reg_clobbers
, regno
);
5031 v_abi
.initialize (RISCV_CC_V
, full_reg_clobbers
);
5036 /* Return true if a function with type FNTYPE returns its value in
5037 RISC-V V registers. */
5040 riscv_return_value_is_vector_type_p (const_tree fntype
)
5042 tree return_type
= TREE_TYPE (fntype
);
5044 return riscv_vector_type_p (return_type
);
5047 /* Return true if a function with type FNTYPE takes arguments in
5048 RISC-V V registers. */
5051 riscv_arguments_is_vector_type_p (const_tree fntype
)
5053 for (tree chain
= TYPE_ARG_TYPES (fntype
); chain
&& chain
!= void_list_node
;
5054 chain
= TREE_CHAIN (chain
))
5056 tree arg_type
= TREE_VALUE (chain
);
5057 if (riscv_vector_type_p (arg_type
))
5064 /* Implement TARGET_FNTYPE_ABI. */
5066 static const predefined_function_abi
&
5067 riscv_fntype_abi (const_tree fntype
)
5069 /* Implementing an experimental vector calling convention, the proposal
5070 can be viewed at the bellow link:
5071 https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/389
5073 You can enable this feature via the `--param=riscv-vector-abi` compiler
5075 if (riscv_vector_abi
5076 && (riscv_return_value_is_vector_type_p (fntype
)
5077 || riscv_arguments_is_vector_type_p (fntype
)))
5078 return riscv_v_abi ();
5080 return default_function_abi
;
5083 /* Return riscv calling convention of call_insn. */
5085 get_riscv_cc (const rtx use
)
5087 gcc_assert (GET_CODE (use
) == USE
);
5088 rtx unspec
= XEXP (use
, 0);
5089 gcc_assert (GET_CODE (unspec
) == UNSPEC
5090 && XINT (unspec
, 1) == UNSPEC_CALLEE_CC
);
5091 riscv_cc cc
= (riscv_cc
) INTVAL (XVECEXP (unspec
, 0, 0));
5092 gcc_assert (cc
< RISCV_CC_UNKNOWN
);
5096 /* Implement TARGET_INSN_CALLEE_ABI. */
5098 const predefined_function_abi
&
5099 riscv_insn_callee_abi (const rtx_insn
*insn
)
5101 rtx pat
= PATTERN (insn
);
5102 gcc_assert (GET_CODE (pat
) == PARALLEL
);
5103 riscv_cc cc
= get_riscv_cc (XVECEXP (pat
, 0, 1));
5104 return function_abis
[cc
];
5107 /* Handle an attribute requiring a FUNCTION_DECL;
5108 arguments as in struct attribute_spec.handler. */
5110 riscv_handle_fndecl_attribute (tree
*node
, tree name
,
5111 tree args ATTRIBUTE_UNUSED
,
5112 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
5114 if (TREE_CODE (*node
) != FUNCTION_DECL
)
5116 warning (OPT_Wattributes
, "%qE attribute only applies to functions",
5118 *no_add_attrs
= true;
5124 /* Verify type based attributes. NODE is the what the attribute is being
5125 applied to. NAME is the attribute name. ARGS are the attribute args.
5126 FLAGS gives info about the context. NO_ADD_ATTRS should be set to true if
5127 the attribute should be ignored. */
5130 riscv_handle_type_attribute (tree
*node ATTRIBUTE_UNUSED
, tree name
, tree args
,
5131 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
5133 /* Check for an argument. */
5134 if (is_attribute_p ("interrupt", name
))
5138 tree cst
= TREE_VALUE (args
);
5141 if (TREE_CODE (cst
) != STRING_CST
)
5143 warning (OPT_Wattributes
,
5144 "%qE attribute requires a string argument",
5146 *no_add_attrs
= true;
5150 string
= TREE_STRING_POINTER (cst
);
5151 if (strcmp (string
, "user") && strcmp (string
, "supervisor")
5152 && strcmp (string
, "machine"))
5154 warning (OPT_Wattributes
,
5155 "argument to %qE attribute is not %<\"user\"%>, %<\"supervisor\"%>, "
5156 "or %<\"machine\"%>", name
);
5157 *no_add_attrs
= true;
5165 /* Return true if function TYPE is an interrupt function. */
5167 riscv_interrupt_type_p (tree type
)
5169 return lookup_attribute ("interrupt", TYPE_ATTRIBUTES (type
)) != NULL
;
5172 /* Return true if FUNC is a naked function. */
5174 riscv_naked_function_p (tree func
)
5176 tree func_decl
= func
;
5177 if (func
== NULL_TREE
)
5178 func_decl
= current_function_decl
;
5179 return NULL_TREE
!= lookup_attribute ("naked", DECL_ATTRIBUTES (func_decl
));
5182 /* Implement TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS. */
5184 riscv_allocate_stack_slots_for_args ()
5186 /* Naked functions should not allocate stack slots for arguments. */
5187 return !riscv_naked_function_p (current_function_decl
);
5190 /* Implement TARGET_WARN_FUNC_RETURN. */
5192 riscv_warn_func_return (tree decl
)
5194 /* Naked functions are implemented entirely in assembly, including the
5195 return sequence, so suppress warnings about this. */
5196 return !riscv_naked_function_p (decl
);
5199 /* Implement TARGET_EXPAND_BUILTIN_VA_START. */
5202 riscv_va_start (tree valist
, rtx nextarg
)
5204 nextarg
= plus_constant (Pmode
, nextarg
, -cfun
->machine
->varargs_size
);
5205 std_expand_builtin_va_start (valist
, nextarg
);
5208 /* Make ADDR suitable for use as a call or sibcall target. */
5211 riscv_legitimize_call_address (rtx addr
)
5213 if (!call_insn_operand (addr
, VOIDmode
))
5215 rtx reg
= RISCV_CALL_ADDRESS_TEMP (Pmode
);
5216 riscv_emit_move (reg
, addr
);
5222 /* Print symbolic operand OP, which is part of a HIGH or LO_SUM
5223 in context CONTEXT. HI_RELOC indicates a high-part reloc. */
5226 riscv_print_operand_reloc (FILE *file
, rtx op
, bool hi_reloc
)
5230 switch (riscv_classify_symbolic_expression (op
))
5232 case SYMBOL_ABSOLUTE
:
5233 reloc
= hi_reloc
? "%hi" : "%lo";
5237 reloc
= hi_reloc
? "%pcrel_hi" : "%pcrel_lo";
5241 reloc
= hi_reloc
? "%tprel_hi" : "%tprel_lo";
5245 output_operand_lossage ("invalid use of '%%%c'", hi_reloc
? 'h' : 'R');
5249 fprintf (file
, "%s(", reloc
);
5250 output_addr_const (file
, riscv_strip_unspec_address (op
));
5254 /* Return the memory model that encapuslates both given models. */
5257 riscv_union_memmodels (enum memmodel model1
, enum memmodel model2
)
5259 model1
= memmodel_base (model1
);
5260 model2
= memmodel_base (model2
);
5262 enum memmodel weaker
= model1
<= model2
? model1
: model2
;
5263 enum memmodel stronger
= model1
> model2
? model1
: model2
;
5267 case MEMMODEL_SEQ_CST
:
5268 case MEMMODEL_ACQ_REL
:
5270 case MEMMODEL_RELEASE
:
5271 if (weaker
== MEMMODEL_ACQUIRE
|| weaker
== MEMMODEL_CONSUME
)
5272 return MEMMODEL_ACQ_REL
;
5275 case MEMMODEL_ACQUIRE
:
5276 case MEMMODEL_CONSUME
:
5277 case MEMMODEL_RELAXED
:
5284 /* Return true if the .AQ suffix should be added to an AMO to implement the
5285 acquire portion of memory model MODEL. */
5288 riscv_memmodel_needs_amo_acquire (enum memmodel model
)
5290 /* ZTSO amo mappings require no annotations. */
5296 case MEMMODEL_ACQ_REL
:
5297 case MEMMODEL_SEQ_CST
:
5298 case MEMMODEL_ACQUIRE
:
5299 case MEMMODEL_CONSUME
:
5302 case MEMMODEL_RELEASE
:
5303 case MEMMODEL_RELAXED
:
5311 /* Return true if the .RL suffix should be added to an AMO to implement the
5312 release portion of memory model MODEL. */
5315 riscv_memmodel_needs_amo_release (enum memmodel model
)
5317 /* ZTSO amo mappings require no annotations. */
5323 case MEMMODEL_ACQ_REL
:
5324 case MEMMODEL_SEQ_CST
:
5325 case MEMMODEL_RELEASE
:
5328 case MEMMODEL_ACQUIRE
:
5329 case MEMMODEL_CONSUME
:
5330 case MEMMODEL_RELAXED
:
5338 /* Get REGNO alignment of vector mode.
5339 The alignment = LMUL when the LMUL >= 1.
5340 Otherwise, alignment = 1. */
5342 riscv_get_v_regno_alignment (machine_mode mode
)
5344 /* 3.3.2. LMUL = 2,4,8, register numbers should be multiple of 2,4,8.
5345 but for mask vector register, register numbers can be any number. */
5347 machine_mode rvv_mode
= mode
;
5348 if (riscv_v_ext_vls_mode_p (rvv_mode
))
5350 int size
= GET_MODE_BITSIZE (rvv_mode
).to_constant ();
5351 if (size
< TARGET_MIN_VLEN
)
5354 return size
/ TARGET_MIN_VLEN
;
5356 if (riscv_v_ext_tuple_mode_p (rvv_mode
))
5357 rvv_mode
= riscv_vector::get_subpart_mode (rvv_mode
);
5358 poly_int64 size
= GET_MODE_SIZE (rvv_mode
);
5359 if (known_gt (size
, UNITS_PER_V_REG
))
5360 lmul
= exact_div (size
, UNITS_PER_V_REG
).to_constant ();
5364 /* Implement TARGET_PRINT_OPERAND. The RISCV-specific operand codes are:
5366 'h' Print the high-part relocation associated with OP, after stripping
5368 'R' Print the low-part relocation associated with OP.
5369 'C' Print the integer branch condition for comparison OP.
5370 'N' Print the inverse of the integer branch condition for comparison OP.
5371 'A' Print the atomic operation suffix for memory model OP.
5372 'I' Print the LR suffix for memory model OP.
5373 'J' Print the SC suffix for memory model OP.
5374 'z' Print x0 if OP is zero, otherwise print OP normally.
5375 'i' Print i if the operand is not a register.
5376 'S' Print shift-index of single-bit mask OP.
5377 'T' Print shift-index of inverted single-bit mask OP.
5378 '~' Print w if TARGET_64BIT is true; otherwise not print anything.
5380 Note please keep this list and the list in riscv.md in sync. */
5383 riscv_print_operand (FILE *file
, rtx op
, int letter
)
5385 /* `~` does not take an operand so op will be null
5386 Check for before accessing op.
5394 machine_mode mode
= GET_MODE (op
);
5395 enum rtx_code code
= GET_CODE (op
);
5400 /* Print 'OP' variant for RVV instructions.
5401 1. If the operand is VECTOR REG, we print 'v'(vnsrl.wv).
5402 2. If the operand is CONST_INT/CONST_VECTOR, we print 'i'(vnsrl.wi).
5403 3. If the operand is SCALAR REG, we print 'x'(vnsrl.wx). */
5404 if (riscv_v_ext_mode_p (mode
))
5407 asm_fprintf (file
, "v");
5408 else if (CONST_VECTOR_P (op
))
5409 asm_fprintf (file
, "i");
5411 output_operand_lossage ("invalid vector operand");
5415 if (CONST_INT_P (op
))
5416 asm_fprintf (file
, "i");
5418 asm_fprintf (file
, "x");
5426 asm_fprintf (file
, "%s", reg_names
[REGNO (op
)]);
5429 if (!const_vec_duplicate_p (op
, &elt
))
5430 output_operand_lossage ("invalid vector constant");
5431 else if (satisfies_constraint_Wc0 (op
))
5432 asm_fprintf (file
, "0");
5433 else if (satisfies_constraint_vi (op
)
5434 || satisfies_constraint_vj (op
)
5435 || satisfies_constraint_vk (op
))
5436 asm_fprintf (file
, "%wd", INTVAL (elt
));
5438 output_operand_lossage ("invalid vector constant");
5444 if (!const_vec_duplicate_p (op
, &elt
))
5445 output_operand_lossage ("invalid vector constant");
5446 else if (satisfies_constraint_vj (op
))
5447 asm_fprintf (file
, "%wd", -INTVAL (elt
));
5449 output_operand_lossage ("invalid vector constant");
5453 if (riscv_v_ext_mode_p (mode
))
5455 /* Calculate lmul according to mode and print the value. */
5456 int lmul
= riscv_get_v_regno_alignment (mode
);
5457 asm_fprintf (file
, "%d", lmul
);
5459 else if (code
== CONST_INT
)
5461 /* If it is a const_int value, it denotes the VLMUL field enum. */
5462 unsigned int vlmul
= UINTVAL (op
);
5465 case riscv_vector::LMUL_1
:
5466 asm_fprintf (file
, "%s", "m1");
5468 case riscv_vector::LMUL_2
:
5469 asm_fprintf (file
, "%s", "m2");
5471 case riscv_vector::LMUL_4
:
5472 asm_fprintf (file
, "%s", "m4");
5474 case riscv_vector::LMUL_8
:
5475 asm_fprintf (file
, "%s", "m8");
5477 case riscv_vector::LMUL_F8
:
5478 asm_fprintf (file
, "%s", "mf8");
5480 case riscv_vector::LMUL_F4
:
5481 asm_fprintf (file
, "%s", "mf4");
5483 case riscv_vector::LMUL_F2
:
5484 asm_fprintf (file
, "%s", "mf2");
5491 output_operand_lossage ("invalid vector constant");
5495 if (GET_MODE_CLASS (mode
) == MODE_VECTOR_BOOL
)
5497 /* Print for RVV mask operand.
5498 If op is reg, print ",v0.t".
5499 Otherwise, don't print anything. */
5501 fprintf (file
, ",%s.t", reg_names
[REGNO (op
)]);
5503 else if (code
== CONST_INT
)
5505 /* Tail && Mask policy. */
5506 asm_fprintf (file
, "%s", IS_AGNOSTIC (UINTVAL (op
)) ? "a" : "u");
5509 output_operand_lossage ("invalid vector constant");
5515 riscv_print_operand_reloc (file
, op
, true);
5519 riscv_print_operand_reloc (file
, op
, false);
5523 /* The RTL names match the instruction names. */
5524 fputs (GET_RTX_NAME (code
), file
);
5528 /* The RTL names match the instruction names. */
5529 fputs (GET_RTX_NAME (reverse_condition (code
)), file
);
5533 const enum memmodel model
= memmodel_base (INTVAL (op
));
5534 if (riscv_memmodel_needs_amo_acquire (model
)
5535 && riscv_memmodel_needs_amo_release (model
))
5536 fputs (".aqrl", file
);
5537 else if (riscv_memmodel_needs_amo_acquire (model
))
5538 fputs (".aq", file
);
5539 else if (riscv_memmodel_needs_amo_release (model
))
5540 fputs (".rl", file
);
5545 const enum memmodel model
= memmodel_base (INTVAL (op
));
5546 if (TARGET_ZTSO
&& model
!= MEMMODEL_SEQ_CST
)
5547 /* LR ops only have an annotation for SEQ_CST in the Ztso mapping. */
5549 else if (model
== MEMMODEL_SEQ_CST
)
5550 fputs (".aqrl", file
);
5551 else if (riscv_memmodel_needs_amo_acquire (model
))
5552 fputs (".aq", file
);
5557 const enum memmodel model
= memmodel_base (INTVAL (op
));
5558 if (TARGET_ZTSO
&& model
== MEMMODEL_SEQ_CST
)
5559 /* SC ops only have an annotation for SEQ_CST in the Ztso mapping. */
5560 fputs (".rl", file
);
5561 else if (TARGET_ZTSO
)
5563 else if (riscv_memmodel_needs_amo_release (model
))
5564 fputs (".rl", file
);
5574 fputs (GET_RTX_NAME (code
), file
);
5579 rtx newop
= GEN_INT (ctz_hwi (INTVAL (op
)));
5580 output_addr_const (file
, newop
);
5585 rtx newop
= GEN_INT (ctz_hwi (~INTVAL (op
)));
5586 output_addr_const (file
, newop
);
5591 int ival
= INTVAL (op
) + 1;
5592 rtx newop
= GEN_INT (ctz_hwi (ival
) + 1);
5593 output_addr_const (file
, newop
);
5600 if (letter
&& letter
!= 'z')
5601 output_operand_lossage ("invalid use of '%%%c'", letter
);
5602 fprintf (file
, "%s", reg_names
[REGNO (op
)]);
5606 if (letter
&& letter
!= 'z')
5607 output_operand_lossage ("invalid use of '%%%c'", letter
);
5609 output_address (mode
, XEXP (op
, 0));
5614 if (letter
== 'z' && op
== CONST0_RTX (GET_MODE (op
)))
5616 fputs (reg_names
[GP_REG_FIRST
], file
);
5620 int fli_index
= riscv_float_const_rtx_index_for_fli (op
);
5621 if (fli_index
== -1 || fli_index
> 31)
5623 output_operand_lossage ("invalid use of '%%%c'", letter
);
5626 asm_fprintf (file
, "%s", fli_value_print
[fli_index
]);
5631 if (letter
== 'z' && op
== CONST0_RTX (GET_MODE (op
)))
5632 fputs (reg_names
[GP_REG_FIRST
], file
);
5633 else if (letter
&& letter
!= 'z')
5634 output_operand_lossage ("invalid use of '%%%c'", letter
);
5636 output_addr_const (file
, riscv_strip_unspec_address (op
));
5642 /* Implement TARGET_PRINT_OPERAND_PUNCT_VALID_P */
5644 riscv_print_operand_punct_valid_p (unsigned char code
)
5646 return (code
== '~');
5649 /* Implement TARGET_PRINT_OPERAND_ADDRESS. */
5652 riscv_print_operand_address (FILE *file
, machine_mode mode ATTRIBUTE_UNUSED
, rtx x
)
5654 struct riscv_address_info addr
;
5656 if (th_print_operand_address (file
, mode
, x
))
5659 if (riscv_classify_address (&addr
, x
, word_mode
, true))
5663 output_addr_const (file
, riscv_strip_unspec_address (addr
.offset
));
5664 fprintf (file
, "(%s)", reg_names
[REGNO (addr
.reg
)]);
5667 case ADDRESS_LO_SUM
:
5668 riscv_print_operand_reloc (file
, addr
.offset
, false);
5669 fprintf (file
, "(%s)", reg_names
[REGNO (addr
.reg
)]);
5672 case ADDRESS_CONST_INT
:
5673 output_addr_const (file
, x
);
5674 fprintf (file
, "(%s)", reg_names
[GP_REG_FIRST
]);
5677 case ADDRESS_SYMBOLIC
:
5678 output_addr_const (file
, riscv_strip_unspec_address (x
));
5689 riscv_size_ok_for_small_data_p (int size
)
5691 return g_switch_value
&& IN_RANGE (size
, 1, g_switch_value
);
5694 /* Return true if EXP should be placed in the small data section. */
5697 riscv_in_small_data_p (const_tree x
)
5699 if (TREE_CODE (x
) == STRING_CST
|| TREE_CODE (x
) == FUNCTION_DECL
)
5702 if (VAR_P (x
) && DECL_SECTION_NAME (x
))
5704 const char *sec
= DECL_SECTION_NAME (x
);
5705 return strcmp (sec
, ".sdata") == 0 || strcmp (sec
, ".sbss") == 0;
5708 return riscv_size_ok_for_small_data_p (int_size_in_bytes (TREE_TYPE (x
)));
5711 /* Switch to the appropriate section for output of DECL. */
5714 riscv_select_section (tree decl
, int reloc
,
5715 unsigned HOST_WIDE_INT align
)
5717 switch (categorize_decl_for_section (decl
, reloc
))
5719 case SECCAT_SRODATA
:
5720 return get_named_section (decl
, ".srodata", reloc
);
5723 return default_elf_select_section (decl
, reloc
, align
);
5727 /* Switch to the appropriate section for output of DECL. */
5730 riscv_unique_section (tree decl
, int reloc
)
5732 const char *prefix
= NULL
;
5733 bool one_only
= DECL_ONE_ONLY (decl
) && !HAVE_COMDAT_GROUP
;
5735 switch (categorize_decl_for_section (decl
, reloc
))
5737 case SECCAT_SRODATA
:
5738 prefix
= one_only
? ".sr" : ".srodata";
5746 const char *name
, *linkonce
;
5749 name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
));
5750 name
= targetm
.strip_name_encoding (name
);
5752 /* If we're using one_only, then there needs to be a .gnu.linkonce
5753 prefix to the section name. */
5754 linkonce
= one_only
? ".gnu.linkonce" : "";
5756 string
= ACONCAT ((linkonce
, prefix
, ".", name
, NULL
));
5758 set_decl_section_name (decl
, string
);
5761 default_unique_section (decl
, reloc
);
5764 /* Return a section for X, handling small data. */
5767 riscv_elf_select_rtx_section (machine_mode mode
, rtx x
,
5768 unsigned HOST_WIDE_INT align
)
5770 section
*s
= default_elf_select_rtx_section (mode
, x
, align
);
5772 if (riscv_size_ok_for_small_data_p (GET_MODE_SIZE (mode
).to_constant ()))
5774 if (startswith (s
->named
.name
, ".rodata.cst"))
5776 /* Rename .rodata.cst* to .srodata.cst*. */
5777 char *name
= (char *) alloca (strlen (s
->named
.name
) + 2);
5778 sprintf (name
, ".s%s", s
->named
.name
+ 1);
5779 return get_section (name
, s
->named
.common
.flags
, NULL
);
5782 if (s
== data_section
)
5783 return sdata_section
;
5789 /* Make the last instruction frame-related and note that it performs
5790 the operation described by FRAME_PATTERN. */
5793 riscv_set_frame_expr (rtx frame_pattern
)
5797 insn
= get_last_insn ();
5798 RTX_FRAME_RELATED_P (insn
) = 1;
5799 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
5804 /* Return a frame-related rtx that stores REG at MEM.
5805 REG must be a single register. */
5808 riscv_frame_set (rtx mem
, rtx reg
)
5810 rtx set
= gen_rtx_SET (mem
, reg
);
5811 RTX_FRAME_RELATED_P (set
) = 1;
5815 /* Returns true if the current function might contain a far jump. */
5818 riscv_far_jump_used_p ()
5820 size_t func_size
= 0;
5822 if (cfun
->machine
->far_jump_used
)
5825 /* We can't change far_jump_used during or after reload, as there is
5826 no chance to change stack frame layout. So we must rely on the
5827 conservative heuristic below having done the right thing. */
5828 if (reload_in_progress
|| reload_completed
)
5831 /* Estimate the function length. */
5832 for (rtx_insn
*insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5833 func_size
+= get_attr_length (insn
);
5835 /* Conservatively determine whether some jump might exceed 1 MiB
5837 if (func_size
* 2 >= 0x100000)
5838 cfun
->machine
->far_jump_used
= true;
5840 return cfun
->machine
->far_jump_used
;
5843 /* Return true, if the current function must save the incoming return
5847 riscv_save_return_addr_reg_p (void)
5849 /* The $ra register is call-clobbered: if this is not a leaf function,
5854 /* We need to save the incoming return address if __builtin_eh_return
5855 is being used to set a different return address. */
5856 if (crtl
->calls_eh_return
)
5859 /* Far jumps/branches use $ra as a temporary to set up the target jump
5860 location (clobbering the incoming return address). */
5861 if (riscv_far_jump_used_p ())
5864 /* We need to save it if anyone has used that. */
5865 if (df_regs_ever_live_p (RETURN_ADDR_REGNUM
))
5868 /* Need not to use ra for leaf when frame pointer is turned off by
5869 option whatever the omit-leaf-frame's value. */
5870 if (frame_pointer_needed
&& crtl
->is_leaf
5871 && !TARGET_OMIT_LEAF_FRAME_POINTER
)
5877 /* Return true if the current function must save register REGNO. */
5880 riscv_save_reg_p (unsigned int regno
)
5882 bool call_saved
= !global_regs
[regno
] && !call_used_or_fixed_reg_p (regno
);
5883 bool might_clobber
= crtl
->saves_all_registers
5884 || df_regs_ever_live_p (regno
);
5886 if (call_saved
&& might_clobber
)
5889 /* Save callee-saved V registers. */
5890 if (V_REG_P (regno
) && !crtl
->abi
->clobbers_full_reg_p (regno
)
5894 if (regno
== HARD_FRAME_POINTER_REGNUM
&& frame_pointer_needed
)
5897 if (regno
== RETURN_ADDR_REGNUM
&& riscv_save_return_addr_reg_p ())
5900 /* If this is an interrupt handler, then must save extra registers. */
5901 if (cfun
->machine
->interrupt_handler_p
)
5903 /* zero register is always zero. */
5904 if (regno
== GP_REG_FIRST
)
5907 /* The function will return the stack pointer to its original value. */
5908 if (regno
== STACK_POINTER_REGNUM
)
5911 /* By convention, we assume that gp and tp are safe. */
5912 if (regno
== GP_REGNUM
|| regno
== THREAD_POINTER_REGNUM
)
5915 /* We must save every register used in this function. If this is not a
5916 leaf function, then we must save all temporary registers. */
5917 if (df_regs_ever_live_p (regno
)
5918 || (!crtl
->is_leaf
&& call_used_or_fixed_reg_p (regno
)))
5925 /* Return TRUE if Zcmp push and pop insns should be
5926 avoided. FALSE otherwise.
5927 Only use multi push & pop if all GPRs masked can be covered,
5928 and stack access is SP based,
5929 and GPRs are at top of the stack frame,
5930 and no conflicts in stack allocation with other features */
5932 riscv_avoid_multi_push (const struct riscv_frame_info
*frame
)
5934 if (!TARGET_ZCMP
|| crtl
->calls_eh_return
|| frame_pointer_needed
5935 || cfun
->machine
->interrupt_handler_p
|| cfun
->machine
->varargs_size
!= 0
5936 || crtl
->args
.pretend_args_size
!= 0
5937 || (use_shrink_wrapping_separate ()
5938 && !riscv_avoid_shrink_wrapping_separate ())
5939 || (frame
->mask
& ~MULTI_PUSH_GPR_MASK
))
5945 /* Determine whether to use multi push insn. */
5947 riscv_use_multi_push (const struct riscv_frame_info
*frame
)
5949 if (riscv_avoid_multi_push (frame
))
5952 return (frame
->multi_push_adj_base
!= 0);
5955 /* Return TRUE if a libcall to save/restore GPRs should be
5956 avoided. FALSE otherwise. */
5958 riscv_avoid_save_libcall (void)
5960 if (!TARGET_SAVE_RESTORE
5961 || crtl
->calls_eh_return
5962 || frame_pointer_needed
5963 || cfun
->machine
->interrupt_handler_p
5964 || cfun
->machine
->varargs_size
!= 0
5965 || crtl
->args
.pretend_args_size
!= 0)
5971 /* Determine whether to call GPR save/restore routines. */
5973 riscv_use_save_libcall (const struct riscv_frame_info
*frame
)
5975 if (riscv_avoid_save_libcall ())
5978 return frame
->save_libcall_adjustment
!= 0;
5981 /* Determine which GPR save/restore routine to call. */
5984 riscv_save_libcall_count (unsigned mask
)
5986 for (unsigned n
= GP_REG_LAST
; n
> GP_REG_FIRST
; n
--)
5987 if (BITSET_P (mask
, n
))
5988 return CALLEE_SAVED_REG_NUMBER (n
) + 1;
5992 /* calculate number of s regs in multi push and pop.
5993 Note that {s0-s10} is not valid in Zcmp, use {s0-s11} instead. */
5995 riscv_multi_push_sregs_count (unsigned mask
)
5997 unsigned num
= riscv_save_libcall_count (mask
);
5998 return (num
== ZCMP_INVALID_S0S10_SREGS_COUNTS
) ? ZCMP_S0S11_SREGS_COUNTS
6002 /* calculate number of regs(ra, s0-sx) in multi push and pop. */
6004 riscv_multi_push_regs_count (unsigned mask
)
6007 return riscv_multi_push_sregs_count (mask
) + 1;
6010 /* Handle 16 bytes align for poly_int. */
6012 riscv_16bytes_align (poly_int64 value
)
6014 return aligned_upper_bound (value
, 16);
6017 static HOST_WIDE_INT
6018 riscv_16bytes_align (HOST_WIDE_INT value
)
6020 return ROUND_UP (value
, 16);
6023 /* Handle stack align for poly_int. */
6025 riscv_stack_align (poly_int64 value
)
6027 return aligned_upper_bound (value
, PREFERRED_STACK_BOUNDARY
/ 8);
6030 static HOST_WIDE_INT
6031 riscv_stack_align (HOST_WIDE_INT value
)
6033 return RISCV_STACK_ALIGN (value
);
6036 /* Populate the current function's riscv_frame_info structure.
6038 RISC-V stack frames grown downward. High addresses are at the top.
6040 +-------------------------------+
6042 | incoming stack arguments |
6044 +-------------------------------+ <-- incoming stack pointer
6046 | callee-allocated save area |
6047 | for arguments that are |
6048 | split between registers and |
6051 +-------------------------------+ <-- arg_pointer_rtx
6053 | callee-allocated save area |
6054 | for register varargs |
6056 +-------------------------------+ <-- hard_frame_pointer_rtx;
6057 | | stack_pointer_rtx + gp_sp_offset
6058 | GPR save area | + UNITS_PER_WORD
6060 +-------------------------------+ <-- stack_pointer_rtx + fp_sp_offset
6061 | | + UNITS_PER_FP_REG
6064 +-------------------------------+ <-- stack_pointer_rtx
6065 | | + v_sp_offset_top
6066 | Vector Registers save area |
6068 | ----------------------------- | <-- stack_pointer_rtx
6069 | padding | + v_sp_offset_bottom
6070 +-------------------------------+ <-- frame_pointer_rtx (virtual)
6074 P +-------------------------------+
6076 | outgoing stack arguments |
6078 +-------------------------------+ <-- stack_pointer_rtx
6080 Dynamic stack allocations such as alloca insert data at point P.
6081 They decrease stack_pointer_rtx but leave frame_pointer_rtx and
6082 hard_frame_pointer_rtx unchanged. */
6084 static HOST_WIDE_INT
riscv_first_stack_step (struct riscv_frame_info
*frame
, poly_int64 remaining_size
);
6087 riscv_compute_frame_info (void)
6089 struct riscv_frame_info
*frame
;
6091 bool interrupt_save_prologue_temp
= false;
6092 unsigned int regno
, i
, num_x_saved
= 0, num_f_saved
= 0, x_save_size
= 0;
6093 unsigned int num_v_saved
= 0;
6095 frame
= &cfun
->machine
->frame
;
6097 /* In an interrupt function, there are two cases in which t0 needs to be used:
6098 1, If we have a large frame, then we need to save/restore t0. We check for
6099 this before clearing the frame struct.
6100 2, Need to save and restore some CSRs in the frame. */
6101 if (cfun
->machine
->interrupt_handler_p
)
6103 HOST_WIDE_INT step1
= riscv_first_stack_step (frame
, frame
->total_size
);
6104 if (! POLY_SMALL_OPERAND_P ((frame
->total_size
- step1
))
6105 || (TARGET_HARD_FLOAT
|| TARGET_ZFINX
))
6106 interrupt_save_prologue_temp
= true;
6111 if (!cfun
->machine
->naked_p
)
6113 /* Find out which GPRs we need to save. */
6114 for (regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
6115 if (riscv_save_reg_p (regno
)
6116 || (interrupt_save_prologue_temp
6117 && (regno
== RISCV_PROLOGUE_TEMP_REGNUM
)))
6118 frame
->mask
|= 1 << (regno
- GP_REG_FIRST
), num_x_saved
++;
6120 /* If this function calls eh_return, we must also save and restore the
6121 EH data registers. */
6122 if (crtl
->calls_eh_return
)
6123 for (i
= 0; (regno
= EH_RETURN_DATA_REGNO (i
)) != INVALID_REGNUM
; i
++)
6124 frame
->mask
|= 1 << (regno
- GP_REG_FIRST
), num_x_saved
++;
6126 /* Find out which FPRs we need to save. This loop must iterate over
6127 the same space as its companion in riscv_for_each_saved_reg. */
6128 if (TARGET_HARD_FLOAT
)
6129 for (regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
++)
6130 if (riscv_save_reg_p (regno
))
6131 frame
->fmask
|= 1 << (regno
- FP_REG_FIRST
), num_f_saved
++;
6133 /* Find out which V registers we need to save. */
6135 for (regno
= V_REG_FIRST
; regno
<= V_REG_LAST
; regno
++)
6136 if (riscv_save_reg_p (regno
))
6138 frame
->vmask
|= 1 << (regno
- V_REG_FIRST
);
6145 x_save_size
= riscv_stack_align (num_x_saved
* UNITS_PER_WORD
);
6148 unsigned num_save_restore
= 1 + riscv_save_libcall_count (frame
->mask
);
6149 /* Only use save/restore routines if they don't alter the stack size. */
6150 if (riscv_stack_align (num_save_restore
* UNITS_PER_WORD
) == x_save_size
6151 && !riscv_avoid_save_libcall ())
6153 /* Libcall saves/restores 3 registers at once, so we need to
6154 allocate 12 bytes for callee-saved register. */
6156 x_save_size
= 3 * UNITS_PER_WORD
;
6158 frame
->save_libcall_adjustment
= x_save_size
;
6161 if (!riscv_avoid_multi_push (frame
))
6163 /* num(ra, s0-sx) */
6164 unsigned num_multi_push
= riscv_multi_push_regs_count (frame
->mask
);
6165 x_save_size
= riscv_stack_align (num_multi_push
* UNITS_PER_WORD
);
6166 frame
->multi_push_adj_base
= riscv_16bytes_align (x_save_size
);
6170 /* In an interrupt function, we need extra space for the initial saves of CSRs. */
6171 if (cfun
->machine
->interrupt_handler_p
6172 && ((TARGET_HARD_FLOAT
&& frame
->fmask
)
6174 /* Except for RISCV_PROLOGUE_TEMP_REGNUM. */
6175 && (frame
->mask
& ~(1 << RISCV_PROLOGUE_TEMP_REGNUM
)))))
6176 /* Save and restore FCSR. */
6177 /* TODO: When P or V extensions support interrupts, some of their CSRs
6178 may also need to be saved and restored. */
6179 x_save_size
+= riscv_stack_align (1 * UNITS_PER_WORD
);
6181 /* At the bottom of the frame are any outgoing stack arguments. */
6182 offset
= riscv_stack_align (crtl
->outgoing_args_size
);
6183 /* Next are local stack variables. */
6184 offset
+= riscv_stack_align (get_frame_size ());
6185 /* The virtual frame pointer points above the local variables. */
6186 frame
->frame_pointer_offset
= offset
;
6187 /* Next are the callee-saved VRs. */
6189 offset
+= riscv_stack_align (num_v_saved
* UNITS_PER_V_REG
);
6190 frame
->v_sp_offset_top
= offset
;
6191 frame
->v_sp_offset_bottom
6192 = frame
->v_sp_offset_top
- num_v_saved
* UNITS_PER_V_REG
;
6193 /* Next are the callee-saved FPRs. */
6195 offset
+= riscv_stack_align (num_f_saved
* UNITS_PER_FP_REG
);
6196 frame
->fp_sp_offset
= offset
- UNITS_PER_FP_REG
;
6197 /* Next are the callee-saved GPRs. */
6200 offset
+= x_save_size
;
6201 /* align to 16 bytes and add paddings to GPR part to honor
6202 both stack alignment and zcmp pus/pop size alignment. */
6203 if (riscv_use_multi_push (frame
)
6204 && known_lt (offset
, frame
->multi_push_adj_base
6205 + ZCMP_SP_INC_STEP
* ZCMP_MAX_SPIMM
))
6206 offset
= riscv_16bytes_align (offset
);
6208 frame
->gp_sp_offset
= offset
- UNITS_PER_WORD
;
6209 /* The hard frame pointer points above the callee-saved GPRs. */
6210 frame
->hard_frame_pointer_offset
= offset
;
6211 /* Above the hard frame pointer is the callee-allocated varags save area. */
6212 offset
+= riscv_stack_align (cfun
->machine
->varargs_size
);
6213 /* Next is the callee-allocated area for pretend stack arguments. */
6214 offset
+= riscv_stack_align (crtl
->args
.pretend_args_size
);
6215 /* Arg pointer must be below pretend args, but must be above alignment
6217 frame
->arg_pointer_offset
= offset
- crtl
->args
.pretend_args_size
;
6218 frame
->total_size
= offset
;
6220 /* Next points the incoming stack pointer and any incoming arguments. */
6223 /* Make sure that we're not trying to eliminate to the wrong hard frame
6227 riscv_can_eliminate (const int from ATTRIBUTE_UNUSED
, const int to
)
6229 return (to
== HARD_FRAME_POINTER_REGNUM
|| to
== STACK_POINTER_REGNUM
);
6232 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame pointer
6233 or argument pointer. TO is either the stack pointer or hard frame
6237 riscv_initial_elimination_offset (int from
, int to
)
6239 poly_int64 src
, dest
;
6241 riscv_compute_frame_info ();
6243 if (to
== HARD_FRAME_POINTER_REGNUM
)
6244 dest
= cfun
->machine
->frame
.hard_frame_pointer_offset
;
6245 else if (to
== STACK_POINTER_REGNUM
)
6246 dest
= 0; /* The stack pointer is the base of all offsets, hence 0. */
6250 if (from
== FRAME_POINTER_REGNUM
)
6251 src
= cfun
->machine
->frame
.frame_pointer_offset
;
6252 else if (from
== ARG_POINTER_REGNUM
)
6253 src
= cfun
->machine
->frame
.arg_pointer_offset
;
6260 /* Implement RETURN_ADDR_RTX. We do not support moving back to a
6264 riscv_return_addr (int count
, rtx frame ATTRIBUTE_UNUSED
)
6269 return get_hard_reg_initial_val (Pmode
, RETURN_ADDR_REGNUM
);
6272 /* Emit code to change the current function's return address to
6273 ADDRESS. SCRATCH is available as a scratch register, if needed.
6274 ADDRESS and SCRATCH are both word-mode GPRs. */
6277 riscv_set_return_address (rtx address
, rtx scratch
)
6281 gcc_assert (BITSET_P (cfun
->machine
->frame
.mask
, RETURN_ADDR_REGNUM
));
6282 slot_address
= riscv_add_offset (scratch
, stack_pointer_rtx
,
6283 cfun
->machine
->frame
.gp_sp_offset
.to_constant());
6284 riscv_emit_move (gen_frame_mem (GET_MODE (address
), slot_address
), address
);
6287 /* Save register REG to MEM. Make the instruction frame-related. */
6290 riscv_save_reg (rtx reg
, rtx mem
)
6292 riscv_emit_move (mem
, reg
);
6293 riscv_set_frame_expr (riscv_frame_set (mem
, reg
));
6296 /* Restore register REG from MEM. */
6299 riscv_restore_reg (rtx reg
, rtx mem
)
6301 rtx insn
= riscv_emit_move (reg
, mem
);
6302 rtx dwarf
= NULL_RTX
;
6303 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
6305 if (known_gt (epilogue_cfa_sp_offset
, 0)
6306 && REGNO (reg
) == HARD_FRAME_POINTER_REGNUM
)
6309 = gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
6310 gen_int_mode (epilogue_cfa_sp_offset
, Pmode
));
6311 dwarf
= alloc_reg_note (REG_CFA_DEF_CFA
, cfa_adjust_rtx
, dwarf
);
6314 REG_NOTES (insn
) = dwarf
;
6315 RTX_FRAME_RELATED_P (insn
) = 1;
6318 /* A function to save or store a register. The first argument is the
6319 register and the second is the stack slot. */
6320 typedef void (*riscv_save_restore_fn
) (rtx
, rtx
);
6322 /* Use FN to save or restore register REGNO. MODE is the register's
6323 mode and OFFSET is the offset of its save slot from the current
6327 riscv_save_restore_reg (machine_mode mode
, int regno
,
6328 HOST_WIDE_INT offset
, riscv_save_restore_fn fn
)
6332 mem
= gen_frame_mem (mode
, plus_constant (Pmode
, stack_pointer_rtx
, offset
));
6333 fn (gen_rtx_REG (mode
, regno
), mem
);
6336 /* Return the next register up from REGNO up to LIMIT for the callee
6337 to save or restore. OFFSET will be adjusted accordingly.
6338 If INC is set, then REGNO will be incremented first.
6339 Returns INVALID_REGNUM if there is no such next register. */
6342 riscv_next_saved_reg (unsigned int regno
, unsigned int limit
,
6343 HOST_WIDE_INT
*offset
, bool inc
= true)
6348 while (regno
<= limit
)
6350 if (BITSET_P (cfun
->machine
->frame
.mask
, regno
- GP_REG_FIRST
))
6352 *offset
= *offset
- UNITS_PER_WORD
;
6358 return INVALID_REGNUM
;
6361 /* Return TRUE if provided REGNO is eh return data register. */
6364 riscv_is_eh_return_data_register (unsigned int regno
)
6366 unsigned int i
, regnum
;
6368 if (!crtl
->calls_eh_return
)
6371 for (i
= 0; (regnum
= EH_RETURN_DATA_REGNO (i
)) != INVALID_REGNUM
; i
++)
6372 if (regno
== regnum
)
6380 /* Call FN for each register that is saved by the current function.
6381 SP_OFFSET is the offset of the current stack pointer from the start
6385 riscv_for_each_saved_reg (poly_int64 sp_offset
, riscv_save_restore_fn fn
,
6386 bool epilogue
, bool maybe_eh_return
)
6388 HOST_WIDE_INT offset
, first_fp_offset
;
6389 unsigned int regno
, num_masked_fp
= 0;
6390 unsigned int start
= GP_REG_FIRST
;
6391 unsigned int limit
= GP_REG_LAST
;
6393 /* Save the link register and s-registers. */
6394 offset
= (cfun
->machine
->frame
.gp_sp_offset
- sp_offset
).to_constant ()
6396 for (regno
= riscv_next_saved_reg (start
, limit
, &offset
, false);
6397 regno
!= INVALID_REGNUM
;
6398 regno
= riscv_next_saved_reg (regno
, limit
, &offset
))
6400 if (cfun
->machine
->reg_is_wrapped_separately
[regno
])
6403 /* If this is a normal return in a function that calls the eh_return
6404 builtin, then do not restore the eh return data registers as that
6405 would clobber the return value. But we do still need to save them
6406 in the prologue, and restore them for an exception return, so we
6407 need special handling here. */
6408 if (epilogue
&& !maybe_eh_return
6409 && riscv_is_eh_return_data_register (regno
))
6412 /* In an interrupt function, save and restore some necessary CSRs in the stack
6413 to avoid changes in CSRs. */
6414 if (regno
== RISCV_PROLOGUE_TEMP_REGNUM
6415 && cfun
->machine
->interrupt_handler_p
6416 && ((TARGET_HARD_FLOAT
&& cfun
->machine
->frame
.fmask
)
6418 && (cfun
->machine
->frame
.mask
& ~(1 << RISCV_PROLOGUE_TEMP_REGNUM
)))))
6420 unsigned int fcsr_size
= GET_MODE_SIZE (SImode
);
6423 riscv_save_restore_reg (word_mode
, regno
, offset
, fn
);
6424 offset
-= fcsr_size
;
6425 emit_insn (gen_riscv_frcsr (RISCV_PROLOGUE_TEMP (SImode
)));
6426 riscv_save_restore_reg (SImode
, RISCV_PROLOGUE_TEMP_REGNUM
,
6427 offset
, riscv_save_reg
);
6431 riscv_save_restore_reg (SImode
, RISCV_PROLOGUE_TEMP_REGNUM
,
6432 offset
- fcsr_size
, riscv_restore_reg
);
6433 emit_insn (gen_riscv_fscsr (RISCV_PROLOGUE_TEMP (SImode
)));
6434 riscv_save_restore_reg (word_mode
, regno
, offset
, fn
);
6435 offset
-= fcsr_size
;
6440 if (TARGET_XTHEADMEMPAIR
)
6442 /* Get the next reg/offset pair. */
6443 HOST_WIDE_INT offset2
= offset
;
6444 unsigned int regno2
= riscv_next_saved_reg (regno
, limit
, &offset2
);
6446 /* Validate everything before emitting a mempair instruction. */
6447 if (regno2
!= INVALID_REGNUM
6448 && !cfun
->machine
->reg_is_wrapped_separately
[regno2
]
6449 && !(epilogue
&& !maybe_eh_return
6450 && riscv_is_eh_return_data_register (regno2
)))
6452 bool load_p
= (fn
== riscv_restore_reg
);
6454 th_mempair_prepare_save_restore_operands (operands
,
6459 /* If the operands fit into a mempair insn, then emit one. */
6460 if (th_mempair_operands_p (operands
, load_p
, word_mode
))
6462 th_mempair_save_restore_regs (operands
, load_p
, word_mode
);
6470 riscv_save_restore_reg (word_mode
, regno
, offset
, fn
);
6473 /* This loop must iterate over the same space as its companion in
6474 riscv_compute_frame_info. */
6476 = (cfun
->machine
->frame
.fp_sp_offset
- sp_offset
).to_constant ();
6477 for (unsigned int regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
++)
6478 if (BITSET_P (cfun
->machine
->frame
.fmask
, regno
- FP_REG_FIRST
))
6480 bool handle_reg
= !cfun
->machine
->reg_is_wrapped_separately
[regno
];
6481 machine_mode mode
= TARGET_DOUBLE_FLOAT
? DFmode
: SFmode
;
6482 unsigned int slot
= (riscv_use_multi_push (&cfun
->machine
->frame
))
6483 ? CALLEE_SAVED_FREG_NUMBER (regno
)
6485 offset
= first_fp_offset
- slot
* GET_MODE_SIZE (mode
).to_constant ();
6487 riscv_save_restore_reg (mode
, regno
, offset
, fn
);
6492 /* Call FN for each V register that is saved by the current function. */
6495 riscv_for_each_saved_v_reg (poly_int64
&remaining_size
,
6496 riscv_save_restore_fn fn
, bool prologue
)
6498 rtx vlen
= NULL_RTX
;
6499 if (cfun
->machine
->frame
.vmask
!= 0)
6501 if (UNITS_PER_V_REG
.is_constant ()
6502 && SMALL_OPERAND (UNITS_PER_V_REG
.to_constant ()))
6503 vlen
= GEN_INT (UNITS_PER_V_REG
.to_constant ());
6506 vlen
= RISCV_PROLOGUE_TEMP (Pmode
);
6508 = emit_move_insn (vlen
, gen_int_mode (UNITS_PER_V_REG
, Pmode
));
6509 RTX_FRAME_RELATED_P (insn
) = 1;
6513 /* Select the mode where LMUL is 1 and SEW is largest. */
6514 machine_mode m1_mode
= TARGET_VECTOR_ELEN_64
? RVVM1DImode
: RVVM1SImode
;
6518 /* This loop must iterate over the same space as its companion in
6519 riscv_compute_frame_info. */
6520 for (unsigned int regno
= V_REG_FIRST
; regno
<= V_REG_LAST
; regno
++)
6521 if (BITSET_P (cfun
->machine
->frame
.vmask
, regno
- V_REG_FIRST
))
6523 bool handle_reg
= !cfun
->machine
->reg_is_wrapped_separately
[regno
];
6526 rtx insn
= NULL_RTX
;
6527 if (CONST_INT_P (vlen
))
6529 gcc_assert (SMALL_OPERAND (-INTVAL (vlen
)));
6530 insn
= emit_insn (gen_add3_insn (stack_pointer_rtx
,
6532 GEN_INT (-INTVAL (vlen
))));
6536 gen_sub3_insn (stack_pointer_rtx
, stack_pointer_rtx
, vlen
));
6537 gcc_assert (insn
!= NULL_RTX
);
6538 RTX_FRAME_RELATED_P (insn
) = 1;
6539 riscv_save_restore_reg (m1_mode
, regno
, 0, fn
);
6540 remaining_size
-= UNITS_PER_V_REG
;
6546 /* This loop must iterate over the same space as its companion in
6547 riscv_compute_frame_info. */
6548 for (unsigned int regno
= V_REG_LAST
; regno
>= V_REG_FIRST
; regno
--)
6549 if (BITSET_P (cfun
->machine
->frame
.vmask
, regno
- V_REG_FIRST
))
6551 bool handle_reg
= !cfun
->machine
->reg_is_wrapped_separately
[regno
];
6554 riscv_save_restore_reg (m1_mode
, regno
, 0, fn
);
6555 rtx insn
= emit_insn (
6556 gen_add3_insn (stack_pointer_rtx
, stack_pointer_rtx
, vlen
));
6557 gcc_assert (insn
!= NULL_RTX
);
6558 RTX_FRAME_RELATED_P (insn
) = 1;
6559 remaining_size
-= UNITS_PER_V_REG
;
6565 /* For stack frames that can't be allocated with a single ADDI instruction,
6566 compute the best value to initially allocate. It must at a minimum
6567 allocate enough space to spill the callee-saved registers. If TARGET_RVC,
6568 try to pick a value that will allow compression of the register saves
6569 without adding extra instructions. */
6571 static HOST_WIDE_INT
6572 riscv_first_stack_step (struct riscv_frame_info
*frame
, poly_int64 remaining_size
)
6574 HOST_WIDE_INT remaining_const_size
;
6575 if (!remaining_size
.is_constant ())
6576 remaining_const_size
6577 = riscv_stack_align (remaining_size
.coeffs
[0])
6578 - riscv_stack_align (remaining_size
.coeffs
[1]);
6580 remaining_const_size
= remaining_size
.to_constant ();
6582 /* First step must be set to the top of vector registers save area if any
6583 vector registers need be preversed. */
6584 if (frame
->vmask
!= 0)
6585 return (remaining_size
- frame
->v_sp_offset_top
).to_constant ();
6587 if (SMALL_OPERAND (remaining_const_size
))
6588 return remaining_const_size
;
6590 poly_int64 callee_saved_first_step
=
6591 remaining_size
- frame
->frame_pointer_offset
;
6592 gcc_assert(callee_saved_first_step
.is_constant ());
6593 HOST_WIDE_INT min_first_step
=
6594 riscv_stack_align (callee_saved_first_step
.to_constant ());
6595 HOST_WIDE_INT max_first_step
= IMM_REACH
/ 2 - PREFERRED_STACK_BOUNDARY
/ 8;
6596 HOST_WIDE_INT min_second_step
= remaining_const_size
- max_first_step
;
6597 gcc_assert (min_first_step
<= max_first_step
);
6599 /* As an optimization, use the least-significant bits of the total frame
6600 size, so that the second adjustment step is just LUI + ADD. */
6601 if (!SMALL_OPERAND (min_second_step
)
6602 && remaining_const_size
% IMM_REACH
<= max_first_step
6603 && remaining_const_size
% IMM_REACH
>= min_first_step
)
6604 return remaining_const_size
% IMM_REACH
;
6606 if (TARGET_RVC
|| TARGET_ZCA
)
6608 /* If we need two subtracts, and one is small enough to allow compressed
6609 loads and stores, then put that one first. */
6610 if (IN_RANGE (min_second_step
, 0,
6611 (TARGET_64BIT
? SDSP_REACH
: SWSP_REACH
)))
6612 return MAX (min_second_step
, min_first_step
);
6614 /* If we need LUI + ADDI + ADD for the second adjustment step, then start
6615 with the minimum first step, so that we can get compressed loads and
6617 else if (!SMALL_OPERAND (min_second_step
))
6618 return min_first_step
;
6621 return max_first_step
;
6625 riscv_adjust_libcall_cfi_prologue ()
6627 rtx dwarf
= NULL_RTX
;
6628 rtx adjust_sp_rtx
, reg
, mem
, insn
;
6629 int saved_size
= cfun
->machine
->frame
.save_libcall_adjustment
;
6632 for (int regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
6633 if (BITSET_P (cfun
->machine
->frame
.mask
, regno
- GP_REG_FIRST
))
6635 /* The save order is ra, s0, s1, s2 to s11. */
6636 if (regno
== RETURN_ADDR_REGNUM
)
6637 offset
= saved_size
- UNITS_PER_WORD
;
6638 else if (regno
== S0_REGNUM
)
6639 offset
= saved_size
- UNITS_PER_WORD
* 2;
6640 else if (regno
== S1_REGNUM
)
6641 offset
= saved_size
- UNITS_PER_WORD
* 3;
6643 offset
= saved_size
- ((regno
- S2_REGNUM
+ 4) * UNITS_PER_WORD
);
6645 reg
= gen_rtx_REG (Pmode
, regno
);
6646 mem
= gen_frame_mem (Pmode
, plus_constant (Pmode
,
6650 insn
= gen_rtx_SET (mem
, reg
);
6651 dwarf
= alloc_reg_note (REG_CFA_OFFSET
, insn
, dwarf
);
6654 /* Debug info for adjust sp. */
6656 gen_rtx_SET (stack_pointer_rtx
,
6657 gen_rtx_PLUS (GET_MODE(stack_pointer_rtx
), stack_pointer_rtx
, GEN_INT (-saved_size
)));
6658 dwarf
= alloc_reg_note (REG_CFA_ADJUST_CFA
, adjust_sp_rtx
,
6664 riscv_adjust_multi_push_cfi_prologue (int saved_size
)
6666 rtx dwarf
= NULL_RTX
;
6667 rtx adjust_sp_rtx
, reg
, mem
, insn
;
6668 unsigned int mask
= cfun
->machine
->frame
.mask
;
6672 if (mask
& S10_MASK
)
6675 for (int regno
= GP_REG_LAST
; regno
>= GP_REG_FIRST
; regno
--)
6676 if (BITSET_P (mask
& MULTI_PUSH_GPR_MASK
, regno
- GP_REG_FIRST
))
6678 /* The save order is s11-s0, ra
6679 from high to low addr. */
6680 offset
= saved_size
- UNITS_PER_WORD
* (++saved_cnt
);
6682 reg
= gen_rtx_REG (Pmode
, regno
);
6683 mem
= gen_frame_mem (Pmode
,
6684 plus_constant (Pmode
, stack_pointer_rtx
, offset
));
6686 insn
= gen_rtx_SET (mem
, reg
);
6687 dwarf
= alloc_reg_note (REG_CFA_OFFSET
, insn
, dwarf
);
6690 /* Debug info for adjust sp. */
6692 = gen_rtx_SET (stack_pointer_rtx
,
6693 plus_constant (Pmode
, stack_pointer_rtx
, -saved_size
));
6694 dwarf
= alloc_reg_note (REG_CFA_ADJUST_CFA
, adjust_sp_rtx
, dwarf
);
6699 riscv_emit_stack_tie (void)
6701 if (Pmode
== SImode
)
6702 emit_insn (gen_stack_tiesi (stack_pointer_rtx
, hard_frame_pointer_rtx
));
6704 emit_insn (gen_stack_tiedi (stack_pointer_rtx
, hard_frame_pointer_rtx
));
6707 /*zcmp multi push and pop code_for_push_pop function ptr array */
6708 static const code_for_push_pop_t code_for_push_pop
[ZCMP_MAX_GRP_SLOTS
][ZCMP_OP_NUM
]
6709 = {{code_for_gpr_multi_push_up_to_ra
, code_for_gpr_multi_pop_up_to_ra
,
6710 code_for_gpr_multi_popret_up_to_ra
, code_for_gpr_multi_popretz_up_to_ra
},
6711 {code_for_gpr_multi_push_up_to_s0
, code_for_gpr_multi_pop_up_to_s0
,
6712 code_for_gpr_multi_popret_up_to_s0
, code_for_gpr_multi_popretz_up_to_s0
},
6713 {code_for_gpr_multi_push_up_to_s1
, code_for_gpr_multi_pop_up_to_s1
,
6714 code_for_gpr_multi_popret_up_to_s1
, code_for_gpr_multi_popretz_up_to_s1
},
6715 {code_for_gpr_multi_push_up_to_s2
, code_for_gpr_multi_pop_up_to_s2
,
6716 code_for_gpr_multi_popret_up_to_s2
, code_for_gpr_multi_popretz_up_to_s2
},
6717 {code_for_gpr_multi_push_up_to_s3
, code_for_gpr_multi_pop_up_to_s3
,
6718 code_for_gpr_multi_popret_up_to_s3
, code_for_gpr_multi_popretz_up_to_s3
},
6719 {code_for_gpr_multi_push_up_to_s4
, code_for_gpr_multi_pop_up_to_s4
,
6720 code_for_gpr_multi_popret_up_to_s4
, code_for_gpr_multi_popretz_up_to_s4
},
6721 {code_for_gpr_multi_push_up_to_s5
, code_for_gpr_multi_pop_up_to_s5
,
6722 code_for_gpr_multi_popret_up_to_s5
, code_for_gpr_multi_popretz_up_to_s5
},
6723 {code_for_gpr_multi_push_up_to_s6
, code_for_gpr_multi_pop_up_to_s6
,
6724 code_for_gpr_multi_popret_up_to_s6
, code_for_gpr_multi_popretz_up_to_s6
},
6725 {code_for_gpr_multi_push_up_to_s7
, code_for_gpr_multi_pop_up_to_s7
,
6726 code_for_gpr_multi_popret_up_to_s7
, code_for_gpr_multi_popretz_up_to_s7
},
6727 {code_for_gpr_multi_push_up_to_s8
, code_for_gpr_multi_pop_up_to_s8
,
6728 code_for_gpr_multi_popret_up_to_s8
, code_for_gpr_multi_popretz_up_to_s8
},
6729 {code_for_gpr_multi_push_up_to_s9
, code_for_gpr_multi_pop_up_to_s9
,
6730 code_for_gpr_multi_popret_up_to_s9
, code_for_gpr_multi_popretz_up_to_s9
},
6731 {nullptr, nullptr, nullptr, nullptr},
6732 {code_for_gpr_multi_push_up_to_s11
, code_for_gpr_multi_pop_up_to_s11
,
6733 code_for_gpr_multi_popret_up_to_s11
,
6734 code_for_gpr_multi_popretz_up_to_s11
}};
6737 riscv_gen_multi_push_pop_insn (riscv_zcmp_op_t op
, HOST_WIDE_INT adj_size
,
6738 unsigned int regs_num
)
6740 gcc_assert (op
< ZCMP_OP_NUM
);
6741 gcc_assert (regs_num
<= ZCMP_MAX_GRP_SLOTS
6742 && regs_num
!= ZCMP_INVALID_S0S10_SREGS_COUNTS
+ 1); /* 1 for ra*/
6743 rtx stack_adj
= GEN_INT (adj_size
);
6744 return GEN_FCN (code_for_push_pop
[regs_num
- 1][op
](Pmode
)) (stack_adj
);
6748 get_multi_push_fpr_mask (unsigned max_fprs_push
)
6750 unsigned mask_fprs_push
= 0, num_f_pushed
= 0;
6751 for (unsigned regno
= FP_REG_FIRST
;
6752 regno
<= FP_REG_LAST
&& num_f_pushed
< max_fprs_push
; regno
++)
6753 if (riscv_save_reg_p (regno
))
6754 mask_fprs_push
|= 1 << (regno
- FP_REG_FIRST
), num_f_pushed
++;
6755 return mask_fprs_push
;
6758 /* Expand the "prologue" pattern. */
6761 riscv_expand_prologue (void)
6763 struct riscv_frame_info
*frame
= &cfun
->machine
->frame
;
6764 poly_int64 remaining_size
= frame
->total_size
;
6765 unsigned mask
= frame
->mask
;
6766 unsigned fmask
= frame
->fmask
;
6767 int spimm
, multi_push_additional
, stack_adj
;
6768 rtx insn
, dwarf
= NULL_RTX
;
6770 if (flag_stack_usage_info
)
6771 current_function_static_stack_size
= constant_lower_bound (remaining_size
);
6773 if (cfun
->machine
->naked_p
)
6776 /* prefer muti-push to save-restore libcall. */
6777 if (riscv_use_multi_push (frame
))
6779 remaining_size
-= frame
->multi_push_adj_base
;
6780 /* If there are vector registers that need to be saved, then it can only
6781 be reduced to the frame->v_sp_offset_top position at most, since the
6782 vector registers will need to be saved one by one by decreasing the SP
6784 poly_int64 remaining_size_above_varea
6786 ? remaining_size
- frame
->v_sp_offset_top
6789 if (known_gt (remaining_size_above_varea
, 2 * ZCMP_SP_INC_STEP
))
6791 else if (known_gt (remaining_size_above_varea
, ZCMP_SP_INC_STEP
))
6793 else if (known_gt (remaining_size_above_varea
, 0))
6797 multi_push_additional
= spimm
* ZCMP_SP_INC_STEP
;
6798 frame
->multi_push_adj_addi
= multi_push_additional
;
6799 remaining_size
-= multi_push_additional
;
6801 /* emit multi push insn & dwarf along with it. */
6802 stack_adj
= frame
->multi_push_adj_base
+ multi_push_additional
;
6803 insn
= emit_insn (riscv_gen_multi_push_pop_insn (
6804 PUSH_IDX
, -stack_adj
, riscv_multi_push_regs_count (frame
->mask
)));
6805 dwarf
= riscv_adjust_multi_push_cfi_prologue (stack_adj
);
6806 RTX_FRAME_RELATED_P (insn
) = 1;
6807 REG_NOTES (insn
) = dwarf
;
6809 /* Temporarily fib that we need not save GPRs. */
6812 /* push FPRs into the addtional reserved space by cm.push. */
6815 unsigned mask_fprs_push
6816 = get_multi_push_fpr_mask (multi_push_additional
/ UNITS_PER_WORD
);
6817 frame
->fmask
&= mask_fprs_push
;
6818 riscv_for_each_saved_reg (remaining_size
, riscv_save_reg
, false,
6820 frame
->fmask
= fmask
& ~mask_fprs_push
; /* mask for the rest FPRs. */
6823 /* When optimizing for size, call a subroutine to save the registers. */
6824 else if (riscv_use_save_libcall (frame
))
6826 rtx dwarf
= NULL_RTX
;
6827 dwarf
= riscv_adjust_libcall_cfi_prologue ();
6829 remaining_size
-= frame
->save_libcall_adjustment
;
6830 insn
= emit_insn (riscv_gen_gpr_save_insn (frame
));
6831 frame
->mask
= 0; /* Temporarily fib that we need not save GPRs. */
6833 RTX_FRAME_RELATED_P (insn
) = 1;
6834 REG_NOTES (insn
) = dwarf
;
6837 /* Save the GP, FP registers. */
6838 if ((frame
->mask
| frame
->fmask
) != 0)
6840 if (known_gt (remaining_size
, frame
->frame_pointer_offset
))
6842 HOST_WIDE_INT step1
= riscv_first_stack_step (frame
, remaining_size
);
6843 remaining_size
-= step1
;
6844 insn
= gen_add3_insn (stack_pointer_rtx
, stack_pointer_rtx
,
6846 RTX_FRAME_RELATED_P (emit_insn (insn
)) = 1;
6848 riscv_for_each_saved_reg (remaining_size
, riscv_save_reg
, false, false);
6851 /* Undo the above fib. */
6853 frame
->fmask
= fmask
;
6855 /* Set up the frame pointer, if we're using one. */
6856 if (frame_pointer_needed
)
6858 insn
= gen_add3_insn (hard_frame_pointer_rtx
, stack_pointer_rtx
,
6859 GEN_INT ((frame
->hard_frame_pointer_offset
- remaining_size
).to_constant ()));
6860 RTX_FRAME_RELATED_P (emit_insn (insn
)) = 1;
6862 riscv_emit_stack_tie ();
6865 /* Save the V registers. */
6866 if (frame
->vmask
!= 0)
6867 riscv_for_each_saved_v_reg (remaining_size
, riscv_save_reg
, true);
6869 /* Allocate the rest of the frame. */
6870 if (known_gt (remaining_size
, 0))
6872 /* Two step adjustment:
6873 1.scalable frame. 2.constant frame. */
6874 poly_int64
scalable_frame (0, 0);
6875 if (!remaining_size
.is_constant ())
6877 /* First for scalable frame. */
6878 poly_int64 scalable_frame
= remaining_size
;
6879 scalable_frame
.coeffs
[0] = remaining_size
.coeffs
[1];
6880 riscv_v_adjust_scalable_frame (stack_pointer_rtx
, scalable_frame
, false);
6881 remaining_size
-= scalable_frame
;
6884 /* Second step for constant frame. */
6885 HOST_WIDE_INT constant_frame
= remaining_size
.to_constant ();
6886 if (constant_frame
== 0)
6889 if (SMALL_OPERAND (-constant_frame
))
6891 insn
= gen_add3_insn (stack_pointer_rtx
, stack_pointer_rtx
,
6892 GEN_INT (-constant_frame
));
6893 RTX_FRAME_RELATED_P (emit_insn (insn
)) = 1;
6897 riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode
), GEN_INT (-constant_frame
));
6898 emit_insn (gen_add3_insn (stack_pointer_rtx
,
6900 RISCV_PROLOGUE_TEMP (Pmode
)));
6902 /* Describe the effect of the previous instructions. */
6903 insn
= plus_constant (Pmode
, stack_pointer_rtx
, -constant_frame
);
6904 insn
= gen_rtx_SET (stack_pointer_rtx
, insn
);
6905 riscv_set_frame_expr (insn
);
6911 riscv_adjust_multi_pop_cfi_epilogue (int saved_size
)
6913 rtx dwarf
= NULL_RTX
;
6914 rtx adjust_sp_rtx
, reg
;
6915 unsigned int mask
= cfun
->machine
->frame
.mask
;
6917 if (mask
& S10_MASK
)
6920 /* Debug info for adjust sp. */
6922 = gen_rtx_SET (stack_pointer_rtx
,
6923 plus_constant (Pmode
, stack_pointer_rtx
, saved_size
));
6924 dwarf
= alloc_reg_note (REG_CFA_ADJUST_CFA
, adjust_sp_rtx
, dwarf
);
6926 for (int regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
6927 if (BITSET_P (mask
, regno
- GP_REG_FIRST
))
6929 reg
= gen_rtx_REG (Pmode
, regno
);
6930 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
6937 riscv_adjust_libcall_cfi_epilogue ()
6939 rtx dwarf
= NULL_RTX
;
6940 rtx adjust_sp_rtx
, reg
;
6941 int saved_size
= cfun
->machine
->frame
.save_libcall_adjustment
;
6943 /* Debug info for adjust sp. */
6945 gen_rtx_SET (stack_pointer_rtx
,
6946 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
, GEN_INT (saved_size
)));
6947 dwarf
= alloc_reg_note (REG_CFA_ADJUST_CFA
, adjust_sp_rtx
,
6950 for (int regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
6951 if (BITSET_P (cfun
->machine
->frame
.mask
, regno
- GP_REG_FIRST
))
6953 reg
= gen_rtx_REG (Pmode
, regno
);
6954 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
6960 /* return true if popretz pattern can be matched.
6961 set (reg 10 a0) (const_int 0)
6963 NOTE_INSN_EPILOGUE_BEG */
6965 riscv_zcmp_can_use_popretz (void)
6967 rtx_insn
*insn
= NULL
, *use
= NULL
, *clear
= NULL
;
6969 /* sequence stack for NOTE_INSN_EPILOGUE_BEG*/
6970 struct sequence_stack
*outer_seq
= get_current_sequence ()->next
;
6973 insn
= outer_seq
->first
;
6974 if (!insn
|| !NOTE_P (insn
) || NOTE_KIND (insn
) != NOTE_INSN_EPILOGUE_BEG
)
6977 /* sequence stack for the insn before NOTE_INSN_EPILOGUE_BEG*/
6978 outer_seq
= outer_seq
->next
;
6980 insn
= outer_seq
->last
;
6983 while (insn
&& NOTE_P (insn
))
6985 insn
= PREV_INSN (insn
);
6989 /* match use (reg 10 a0) */
6990 if (use
== NULL
|| !INSN_P (use
) || GET_CODE (PATTERN (use
)) != USE
6991 || !REG_P (XEXP (PATTERN (use
), 0))
6992 || REGNO (XEXP (PATTERN (use
), 0)) != A0_REGNUM
)
6995 /* match set (reg 10 a0) (const_int 0 [0]) */
6996 clear
= PREV_INSN (use
);
6997 if (clear
!= NULL
&& INSN_P (clear
) && GET_CODE (PATTERN (clear
)) == SET
6998 && REG_P (SET_DEST (PATTERN (clear
)))
6999 && REGNO (SET_DEST (PATTERN (clear
))) == A0_REGNUM
7000 && SET_SRC (PATTERN (clear
)) == const0_rtx
)
7007 riscv_gen_multi_pop_insn (bool use_multi_pop_normal
, unsigned mask
,
7008 unsigned multipop_size
)
7011 unsigned regs_count
= riscv_multi_push_regs_count (mask
);
7013 if (!use_multi_pop_normal
)
7015 riscv_gen_multi_push_pop_insn (POP_IDX
, multipop_size
, regs_count
));
7016 else if (rtx_insn
*clear_a0_insn
= riscv_zcmp_can_use_popretz ())
7018 delete_insn (NEXT_INSN (clear_a0_insn
));
7019 delete_insn (clear_a0_insn
);
7020 insn
= emit_jump_insn (
7021 riscv_gen_multi_push_pop_insn (POPRETZ_IDX
, multipop_size
, regs_count
));
7024 insn
= emit_jump_insn (
7025 riscv_gen_multi_push_pop_insn (POPRET_IDX
, multipop_size
, regs_count
));
7027 rtx dwarf
= riscv_adjust_multi_pop_cfi_epilogue (multipop_size
);
7028 RTX_FRAME_RELATED_P (insn
) = 1;
7029 REG_NOTES (insn
) = dwarf
;
7032 /* Expand an "epilogue", "sibcall_epilogue", or "eh_return_internal" pattern;
7033 style says which. */
7036 riscv_expand_epilogue (int style
)
7038 /* Split the frame into 3 steps. STEP1 is the amount of stack we should
7039 deallocate before restoring the registers. STEP2 is the amount we
7040 should deallocate afterwards including the callee saved regs. STEP3
7041 is the amount deallocated by save-restore libcall.
7043 Start off by assuming that no registers need to be restored. */
7044 struct riscv_frame_info
*frame
= &cfun
->machine
->frame
;
7045 unsigned mask
= frame
->mask
;
7046 unsigned fmask
= frame
->fmask
;
7047 unsigned mask_fprs_push
= 0;
7048 poly_int64 step2
= 0;
7049 bool use_multi_pop_normal
7050 = ((style
== NORMAL_RETURN
) && riscv_use_multi_push (frame
));
7051 bool use_multi_pop_sibcall
7052 = ((style
== SIBCALL_RETURN
) && riscv_use_multi_push (frame
));
7053 bool use_multi_pop
= use_multi_pop_normal
|| use_multi_pop_sibcall
;
7055 bool use_restore_libcall
7057 && ((style
== NORMAL_RETURN
) && riscv_use_save_libcall (frame
));
7058 unsigned libcall_size
= use_restore_libcall
&& !use_multi_pop
7059 ? frame
->save_libcall_adjustment
7061 unsigned multipop_size
7062 = use_multi_pop
? frame
->multi_push_adj_base
+ frame
->multi_push_adj_addi
7064 rtx ra
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
7067 /* We need to add memory barrier to prevent read from deallocated stack. */
7068 bool need_barrier_p
= known_ne (get_frame_size ()
7069 + cfun
->machine
->frame
.arg_pointer_offset
, 0);
7071 if (cfun
->machine
->naked_p
)
7073 gcc_assert (style
== NORMAL_RETURN
);
7075 emit_jump_insn (gen_return ());
7080 if ((style
== NORMAL_RETURN
) && riscv_can_use_return_insn ())
7082 emit_jump_insn (gen_return ());
7086 /* Reset the epilogue cfa info before starting to emit the epilogue. */
7087 epilogue_cfa_sp_offset
= 0;
7089 /* Move past any dynamic stack allocations. */
7090 if (cfun
->calls_alloca
)
7092 /* Emit a barrier to prevent loads from a deallocated stack. */
7093 riscv_emit_stack_tie ();
7094 need_barrier_p
= false;
7096 poly_int64 adjust_offset
= -frame
->hard_frame_pointer_offset
;
7097 rtx adjust
= NULL_RTX
;
7099 if (!adjust_offset
.is_constant ())
7101 rtx tmp1
= RISCV_PROLOGUE_TEMP (Pmode
);
7102 rtx tmp2
= RISCV_PROLOGUE_TEMP2 (Pmode
);
7103 riscv_legitimize_poly_move (Pmode
, tmp1
, tmp2
,
7104 gen_int_mode (adjust_offset
, Pmode
));
7109 if (!SMALL_OPERAND (adjust_offset
.to_constant ()))
7111 riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode
),
7112 GEN_INT (adjust_offset
.to_constant ()));
7113 adjust
= RISCV_PROLOGUE_TEMP (Pmode
);
7116 adjust
= GEN_INT (adjust_offset
.to_constant ());
7120 gen_add3_insn (stack_pointer_rtx
, hard_frame_pointer_rtx
,
7123 rtx dwarf
= NULL_RTX
;
7124 rtx cfa_adjust_value
= gen_rtx_PLUS (
7125 Pmode
, hard_frame_pointer_rtx
,
7126 gen_int_mode (-frame
->hard_frame_pointer_offset
, Pmode
));
7127 rtx cfa_adjust_rtx
= gen_rtx_SET (stack_pointer_rtx
, cfa_adjust_value
);
7128 dwarf
= alloc_reg_note (REG_CFA_ADJUST_CFA
, cfa_adjust_rtx
, dwarf
);
7129 RTX_FRAME_RELATED_P (insn
) = 1;
7131 REG_NOTES (insn
) = dwarf
;
7134 if (use_restore_libcall
|| use_multi_pop
)
7135 frame
->mask
= 0; /* Temporarily fib that we need not restore GPRs. */
7137 /* If we need to restore registers, deallocate as much stack as
7138 possible in the second step without going out of range. */
7142 && known_gt (frame
->total_size
- multipop_size
,
7143 frame
->frame_pointer_offset
))
7145 = riscv_first_stack_step (frame
, frame
->total_size
- multipop_size
);
7147 else if ((frame
->mask
| frame
->fmask
) != 0)
7148 step2
= riscv_first_stack_step (frame
, frame
->total_size
- libcall_size
);
7150 if (use_restore_libcall
|| use_multi_pop
)
7151 frame
->mask
= mask
; /* Undo the above fib. */
7154 /* STEP1 must be set to the bottom of vector registers save area if any
7155 vector registers need be preversed. */
7156 if (frame
->vmask
!= 0)
7158 step1
= frame
->v_sp_offset_bottom
;
7159 step2
= frame
->total_size
- step1
- libcall_size
- multipop_size
;
7162 step1
= frame
->total_size
- step2
- libcall_size
- multipop_size
;
7164 /* Set TARGET to BASE + STEP1. */
7165 if (known_gt (step1
, 0))
7167 /* Emit a barrier to prevent loads from a deallocated stack. */
7168 riscv_emit_stack_tie ();
7169 need_barrier_p
= false;
7171 /* Restore the scalable frame which is assigned in prologue. */
7172 if (!step1
.is_constant ())
7174 poly_int64 scalable_frame
= step1
;
7175 scalable_frame
.coeffs
[0] = step1
.coeffs
[1];
7176 riscv_v_adjust_scalable_frame (stack_pointer_rtx
, scalable_frame
,
7178 step1
-= scalable_frame
;
7181 /* Get an rtx for STEP1 that we can add to BASE.
7182 Skip if adjust equal to zero. */
7183 if (step1
.to_constant () != 0)
7185 rtx adjust
= GEN_INT (step1
.to_constant ());
7186 if (!SMALL_OPERAND (step1
.to_constant ()))
7188 riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode
), adjust
);
7189 adjust
= RISCV_PROLOGUE_TEMP (Pmode
);
7192 insn
= emit_insn (gen_add3_insn (stack_pointer_rtx
,
7195 rtx dwarf
= NULL_RTX
;
7197 = gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
7198 gen_int_mode (step2
+ libcall_size
+ multipop_size
,
7201 dwarf
= alloc_reg_note (REG_CFA_DEF_CFA
, cfa_adjust_rtx
, dwarf
);
7202 RTX_FRAME_RELATED_P (insn
) = 1;
7204 REG_NOTES (insn
) = dwarf
;
7207 else if (frame_pointer_needed
)
7209 /* Tell riscv_restore_reg to emit dwarf to redefine CFA when restoring
7211 epilogue_cfa_sp_offset
= step2
;
7216 frame
->mask
= 0; /* Temporarily fib that we need not restore GPRs. */
7219 mask_fprs_push
= get_multi_push_fpr_mask (frame
->multi_push_adj_addi
7221 frame
->fmask
&= ~mask_fprs_push
; /* FPRs not saved by cm.push */
7224 else if (use_restore_libcall
)
7225 frame
->mask
= 0; /* Temporarily fib that we need not restore GPRs. */
7227 /* Restore the registers. */
7228 riscv_for_each_saved_v_reg (step2
, riscv_restore_reg
, false);
7229 riscv_for_each_saved_reg (frame
->total_size
- step2
- libcall_size
7231 riscv_restore_reg
, true, style
== EXCEPTION_RETURN
);
7233 if (use_restore_libcall
)
7234 frame
->mask
= mask
; /* Undo the above fib. */
7237 riscv_emit_stack_tie ();
7239 /* Deallocate the final bit of the frame. */
7240 if (step2
.to_constant () > 0)
7242 insn
= emit_insn (gen_add3_insn (stack_pointer_rtx
, stack_pointer_rtx
,
7243 GEN_INT (step2
.to_constant ())));
7245 rtx dwarf
= NULL_RTX
;
7247 = gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
7248 GEN_INT (libcall_size
+ multipop_size
));
7249 dwarf
= alloc_reg_note (REG_CFA_DEF_CFA
, cfa_adjust_rtx
, dwarf
);
7250 RTX_FRAME_RELATED_P (insn
) = 1;
7252 REG_NOTES (insn
) = dwarf
;
7257 /* restore FPRs pushed by cm.push. */
7258 frame
->fmask
= fmask
& mask_fprs_push
;
7260 riscv_for_each_saved_reg (frame
->total_size
- libcall_size
7262 riscv_restore_reg
, true,
7263 style
== EXCEPTION_RETURN
);
7264 /* Undo the above fib. */
7266 frame
->fmask
= fmask
;
7267 riscv_gen_multi_pop_insn (use_multi_pop_normal
, frame
->mask
,
7269 if (use_multi_pop_normal
)
7272 else if (use_restore_libcall
)
7274 rtx dwarf
= riscv_adjust_libcall_cfi_epilogue ();
7275 insn
= emit_insn (gen_gpr_restore (GEN_INT (riscv_save_libcall_count (mask
))));
7276 RTX_FRAME_RELATED_P (insn
) = 1;
7277 REG_NOTES (insn
) = dwarf
;
7279 emit_jump_insn (gen_gpr_restore_return (ra
));
7283 /* Add in the __builtin_eh_return stack adjustment. */
7284 if ((style
== EXCEPTION_RETURN
) && crtl
->calls_eh_return
)
7285 emit_insn (gen_add3_insn (stack_pointer_rtx
, stack_pointer_rtx
,
7286 EH_RETURN_STACKADJ_RTX
));
7288 /* Return from interrupt. */
7289 if (cfun
->machine
->interrupt_handler_p
)
7291 enum riscv_privilege_levels mode
= cfun
->machine
->interrupt_mode
;
7293 gcc_assert (mode
!= UNKNOWN_MODE
);
7295 if (mode
== MACHINE_MODE
)
7296 emit_jump_insn (gen_riscv_mret ());
7297 else if (mode
== SUPERVISOR_MODE
)
7298 emit_jump_insn (gen_riscv_sret ());
7300 emit_jump_insn (gen_riscv_uret ());
7302 else if (style
!= SIBCALL_RETURN
)
7303 emit_jump_insn (gen_simple_return_internal (ra
));
7306 /* Implement EPILOGUE_USES. */
7309 riscv_epilogue_uses (unsigned int regno
)
7311 if (regno
== RETURN_ADDR_REGNUM
)
7314 if (epilogue_completed
&& cfun
->machine
->interrupt_handler_p
)
7316 /* An interrupt function restores temp regs, so we must indicate that
7317 they are live at function end. */
7318 if (df_regs_ever_live_p (regno
)
7319 || (!crtl
->is_leaf
&& call_used_or_fixed_reg_p (regno
)))
7327 riscv_avoid_shrink_wrapping_separate ()
7329 if (riscv_use_save_libcall (&cfun
->machine
->frame
)
7330 || cfun
->machine
->interrupt_handler_p
7331 || !cfun
->machine
->frame
.gp_sp_offset
.is_constant ())
7337 /* Implement TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS. */
7340 riscv_get_separate_components (void)
7342 HOST_WIDE_INT offset
;
7343 sbitmap components
= sbitmap_alloc (FIRST_PSEUDO_REGISTER
);
7344 bitmap_clear (components
);
7346 if (riscv_avoid_shrink_wrapping_separate ())
7349 offset
= cfun
->machine
->frame
.gp_sp_offset
.to_constant ();
7350 for (unsigned int regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
7351 if (BITSET_P (cfun
->machine
->frame
.mask
, regno
- GP_REG_FIRST
))
7353 /* We can only wrap registers that have small operand offsets.
7354 For large offsets a pseudo register might be needed which
7355 cannot be created during the shrink wrapping pass. */
7356 if (SMALL_OPERAND (offset
))
7357 bitmap_set_bit (components
, regno
);
7359 offset
-= UNITS_PER_WORD
;
7362 offset
= cfun
->machine
->frame
.fp_sp_offset
.to_constant ();
7363 for (unsigned int regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
++)
7364 if (BITSET_P (cfun
->machine
->frame
.fmask
, regno
- FP_REG_FIRST
))
7366 machine_mode mode
= TARGET_DOUBLE_FLOAT
? DFmode
: SFmode
;
7368 /* We can only wrap registers that have small operand offsets.
7369 For large offsets a pseudo register might be needed which
7370 cannot be created during the shrink wrapping pass. */
7371 if (SMALL_OPERAND (offset
))
7372 bitmap_set_bit (components
, regno
);
7374 offset
-= GET_MODE_SIZE (mode
).to_constant ();
7377 /* Don't mess with the hard frame pointer. */
7378 if (frame_pointer_needed
)
7379 bitmap_clear_bit (components
, HARD_FRAME_POINTER_REGNUM
);
7381 bitmap_clear_bit (components
, RETURN_ADDR_REGNUM
);
7386 /* Implement TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB. */
7389 riscv_components_for_bb (basic_block bb
)
7391 bitmap in
= DF_LIVE_IN (bb
);
7392 bitmap gen
= &DF_LIVE_BB_INFO (bb
)->gen
;
7393 bitmap kill
= &DF_LIVE_BB_INFO (bb
)->kill
;
7395 sbitmap components
= sbitmap_alloc (FIRST_PSEUDO_REGISTER
);
7396 bitmap_clear (components
);
7398 function_abi_aggregator callee_abis
;
7400 FOR_BB_INSNS (bb
, insn
)
7402 callee_abis
.note_callee_abi (insn_callee_abi (insn
));
7403 HARD_REG_SET extra_caller_saves
= callee_abis
.caller_save_regs (*crtl
->abi
);
7405 /* GPRs are used in a bb if they are in the IN, GEN, or KILL sets. */
7406 for (unsigned int regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
7407 if (!fixed_regs
[regno
]
7408 && !crtl
->abi
->clobbers_full_reg_p (regno
)
7409 && (TEST_HARD_REG_BIT (extra_caller_saves
, regno
)
7410 || bitmap_bit_p (in
, regno
)
7411 || bitmap_bit_p (gen
, regno
)
7412 || bitmap_bit_p (kill
, regno
)))
7413 bitmap_set_bit (components
, regno
);
7415 for (unsigned int regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
++)
7416 if (!fixed_regs
[regno
]
7417 && !crtl
->abi
->clobbers_full_reg_p (regno
)
7418 && (TEST_HARD_REG_BIT (extra_caller_saves
, regno
)
7419 || bitmap_bit_p (in
, regno
)
7420 || bitmap_bit_p (gen
, regno
)
7421 || bitmap_bit_p (kill
, regno
)))
7422 bitmap_set_bit (components
, regno
);
7427 /* Implement TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS. */
7430 riscv_disqualify_components (sbitmap
, edge
, sbitmap
, bool)
7432 /* Nothing to do for riscv. */
7436 riscv_process_components (sbitmap components
, bool prologue_p
)
7438 HOST_WIDE_INT offset
;
7439 riscv_save_restore_fn fn
= prologue_p
? riscv_save_reg
: riscv_restore_reg
;
7441 offset
= cfun
->machine
->frame
.gp_sp_offset
.to_constant ();
7442 for (unsigned int regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
7443 if (BITSET_P (cfun
->machine
->frame
.mask
, regno
- GP_REG_FIRST
))
7445 if (bitmap_bit_p (components
, regno
))
7446 riscv_save_restore_reg (word_mode
, regno
, offset
, fn
);
7448 offset
-= UNITS_PER_WORD
;
7451 offset
= cfun
->machine
->frame
.fp_sp_offset
.to_constant ();
7452 for (unsigned int regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
++)
7453 if (BITSET_P (cfun
->machine
->frame
.fmask
, regno
- FP_REG_FIRST
))
7455 machine_mode mode
= TARGET_DOUBLE_FLOAT
? DFmode
: SFmode
;
7457 if (bitmap_bit_p (components
, regno
))
7458 riscv_save_restore_reg (mode
, regno
, offset
, fn
);
7460 offset
-= GET_MODE_SIZE (mode
).to_constant ();
7464 /* Implement TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS. */
7467 riscv_emit_prologue_components (sbitmap components
)
7469 riscv_process_components (components
, true);
7472 /* Implement TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS. */
7475 riscv_emit_epilogue_components (sbitmap components
)
7477 riscv_process_components (components
, false);
7481 riscv_set_handled_components (sbitmap components
)
7483 for (unsigned int regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
7484 if (bitmap_bit_p (components
, regno
))
7485 cfun
->machine
->reg_is_wrapped_separately
[regno
] = true;
7487 for (unsigned int regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
++)
7488 if (bitmap_bit_p (components
, regno
))
7489 cfun
->machine
->reg_is_wrapped_separately
[regno
] = true;
7492 /* Return nonzero if this function is known to have a null epilogue.
7493 This allows the optimizer to omit jumps to jumps if no stack
7497 riscv_can_use_return_insn (void)
7499 return (reload_completed
&& known_eq (cfun
->machine
->frame
.total_size
, 0)
7500 && ! cfun
->machine
->interrupt_handler_p
);
7503 /* Given that there exists at least one variable that is set (produced)
7504 by OUT_INSN and read (consumed) by IN_INSN, return true iff
7505 IN_INSN represents one or more memory store operations and none of
7506 the variables set by OUT_INSN is used by IN_INSN as the address of a
7507 store operation. If either IN_INSN or OUT_INSN does not represent
7508 a "single" RTL SET expression (as loosely defined by the
7509 implementation of the single_set function) or a PARALLEL with only
7510 SETs, CLOBBERs, and USEs inside, this function returns false.
7512 Borrowed from rs6000, riscv_store_data_bypass_p checks for certain
7513 conditions that result in assertion failures in the generic
7514 store_data_bypass_p function and returns FALSE in such cases.
7516 This is required to make -msave-restore work with the sifive-7
7517 pipeline description. */
7520 riscv_store_data_bypass_p (rtx_insn
*out_insn
, rtx_insn
*in_insn
)
7522 rtx out_set
, in_set
;
7523 rtx out_pat
, in_pat
;
7524 rtx out_exp
, in_exp
;
7527 in_set
= single_set (in_insn
);
7530 if (MEM_P (SET_DEST (in_set
)))
7532 out_set
= single_set (out_insn
);
7535 out_pat
= PATTERN (out_insn
);
7536 if (GET_CODE (out_pat
) == PARALLEL
)
7538 for (i
= 0; i
< XVECLEN (out_pat
, 0); i
++)
7540 out_exp
= XVECEXP (out_pat
, 0, i
);
7541 if ((GET_CODE (out_exp
) == CLOBBER
)
7542 || (GET_CODE (out_exp
) == USE
))
7544 else if (GET_CODE (out_exp
) != SET
)
7553 in_pat
= PATTERN (in_insn
);
7554 if (GET_CODE (in_pat
) != PARALLEL
)
7557 for (i
= 0; i
< XVECLEN (in_pat
, 0); i
++)
7559 in_exp
= XVECEXP (in_pat
, 0, i
);
7560 if ((GET_CODE (in_exp
) == CLOBBER
) || (GET_CODE (in_exp
) == USE
))
7562 else if (GET_CODE (in_exp
) != SET
)
7565 if (MEM_P (SET_DEST (in_exp
)))
7567 out_set
= single_set (out_insn
);
7570 out_pat
= PATTERN (out_insn
);
7571 if (GET_CODE (out_pat
) != PARALLEL
)
7573 for (j
= 0; j
< XVECLEN (out_pat
, 0); j
++)
7575 out_exp
= XVECEXP (out_pat
, 0, j
);
7576 if ((GET_CODE (out_exp
) == CLOBBER
)
7577 || (GET_CODE (out_exp
) == USE
))
7579 else if (GET_CODE (out_exp
) != SET
)
7587 return store_data_bypass_p (out_insn
, in_insn
);
7590 /* Implement TARGET_SECONDARY_MEMORY_NEEDED.
7592 When floating-point registers are wider than integer ones, moves between
7593 them must go through memory. */
7596 riscv_secondary_memory_needed (machine_mode mode
, reg_class_t class1
,
7599 return (!riscv_v_ext_mode_p (mode
)
7600 && GET_MODE_SIZE (mode
).to_constant () > UNITS_PER_WORD
7601 && (class1
== FP_REGS
) != (class2
== FP_REGS
)
7602 && !TARGET_XTHEADFMV
7606 /* Implement TARGET_REGISTER_MOVE_COST. */
7609 riscv_register_move_cost (machine_mode mode
,
7610 reg_class_t from
, reg_class_t to
)
7612 if ((from
== FP_REGS
&& to
== GR_REGS
) ||
7613 (from
== GR_REGS
&& to
== FP_REGS
))
7614 return tune_param
->fmv_cost
;
7616 return riscv_secondary_memory_needed (mode
, from
, to
) ? 8 : 2;
7619 /* Implement TARGET_HARD_REGNO_NREGS. */
7622 riscv_hard_regno_nregs (unsigned int regno
, machine_mode mode
)
7624 if (riscv_v_ext_vector_mode_p (mode
))
7626 /* Handle fractional LMUL, it only occupy part of vector register but
7627 still need one vector register to hold. */
7628 if (maybe_lt (GET_MODE_SIZE (mode
), UNITS_PER_V_REG
))
7631 return exact_div (GET_MODE_SIZE (mode
), UNITS_PER_V_REG
).to_constant ();
7634 /* For tuple modes, the number of register = NF * LMUL. */
7635 if (riscv_v_ext_tuple_mode_p (mode
))
7637 unsigned int nf
= riscv_vector::get_nf (mode
);
7638 machine_mode subpart_mode
= riscv_vector::get_subpart_mode (mode
);
7639 poly_int64 size
= GET_MODE_SIZE (subpart_mode
);
7640 gcc_assert (known_eq (size
* nf
, GET_MODE_SIZE (mode
)));
7641 if (maybe_lt (size
, UNITS_PER_V_REG
))
7645 unsigned int lmul
= exact_div (size
, UNITS_PER_V_REG
).to_constant ();
7650 /* For VLS modes, we allocate registers according to TARGET_MIN_VLEN. */
7651 if (riscv_v_ext_vls_mode_p (mode
))
7653 int size
= GET_MODE_BITSIZE (mode
).to_constant ();
7654 if (size
< TARGET_MIN_VLEN
)
7657 return size
/ TARGET_MIN_VLEN
;
7660 /* mode for VL or VTYPE are just a marker, not holding value,
7661 so it always consume one register. */
7662 if (VTYPE_REG_P (regno
) || VL_REG_P (regno
) || VXRM_REG_P (regno
)
7663 || FRM_REG_P (regno
))
7666 /* Assume every valid non-vector mode fits in one vector register. */
7667 if (V_REG_P (regno
))
7670 if (FP_REG_P (regno
))
7671 return (GET_MODE_SIZE (mode
).to_constant () + UNITS_PER_FP_REG
- 1) / UNITS_PER_FP_REG
;
7673 /* All other registers are word-sized. */
7674 return (GET_MODE_SIZE (mode
).to_constant () + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
7677 /* Implement TARGET_HARD_REGNO_MODE_OK. */
7680 riscv_hard_regno_mode_ok (unsigned int regno
, machine_mode mode
)
7682 unsigned int nregs
= riscv_hard_regno_nregs (regno
, mode
);
7684 if (GP_REG_P (regno
))
7686 if (riscv_v_ext_mode_p (mode
))
7689 if (!GP_REG_P (regno
+ nregs
- 1))
7692 else if (FP_REG_P (regno
))
7694 if (riscv_v_ext_mode_p (mode
))
7697 if (!FP_REG_P (regno
+ nregs
- 1))
7700 if (GET_MODE_CLASS (mode
) != MODE_FLOAT
7701 && GET_MODE_CLASS (mode
) != MODE_COMPLEX_FLOAT
)
7704 /* Only use callee-saved registers if a potential callee is guaranteed
7705 to spill the requisite width. */
7706 if (GET_MODE_UNIT_SIZE (mode
) > UNITS_PER_FP_REG
7707 || (!call_used_or_fixed_reg_p (regno
)
7708 && GET_MODE_UNIT_SIZE (mode
) > UNITS_PER_FP_ARG
))
7711 else if (V_REG_P (regno
))
7713 if (!riscv_v_ext_mode_p (mode
))
7716 if (!V_REG_P (regno
+ nregs
- 1))
7719 int regno_alignment
= riscv_get_v_regno_alignment (mode
);
7720 if (regno_alignment
!= 1)
7721 return ((regno
% regno_alignment
) == 0);
7723 else if (VTYPE_REG_P (regno
) || VL_REG_P (regno
) || VXRM_REG_P (regno
)
7724 || FRM_REG_P (regno
))
7729 /* Require same callee-savedness for all registers. */
7730 for (unsigned i
= 1; i
< nregs
; i
++)
7731 if (call_used_or_fixed_reg_p (regno
)
7732 != call_used_or_fixed_reg_p (regno
+ i
))
7735 /* Only use even registers in RV32 ZDINX */
7736 if (!TARGET_64BIT
&& TARGET_ZDINX
){
7737 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
&&
7738 GET_MODE_UNIT_SIZE (mode
) == GET_MODE_SIZE (DFmode
))
7739 return !(regno
& 1);
7745 /* Implement TARGET_MODES_TIEABLE_P.
7747 Don't allow floating-point modes to be tied, since type punning of
7748 single-precision and double-precision is implementation defined. */
7751 riscv_modes_tieable_p (machine_mode mode1
, machine_mode mode2
)
7753 /* We don't allow different REG_CLASS modes tieable since it
7754 will cause ICE in register allocation (RA).
7755 E.g. V2SI and DI are not tieable. */
7756 if (riscv_v_ext_mode_p (mode1
) != riscv_v_ext_mode_p (mode2
))
7758 return (mode1
== mode2
7759 || !(GET_MODE_CLASS (mode1
) == MODE_FLOAT
7760 && GET_MODE_CLASS (mode2
) == MODE_FLOAT
));
7763 /* Implement CLASS_MAX_NREGS. */
7765 static unsigned char
7766 riscv_class_max_nregs (reg_class_t rclass
, machine_mode mode
)
7768 if (reg_class_subset_p (rclass
, FP_REGS
))
7769 return riscv_hard_regno_nregs (FP_REG_FIRST
, mode
);
7771 if (reg_class_subset_p (rclass
, GR_REGS
))
7772 return riscv_hard_regno_nregs (GP_REG_FIRST
, mode
);
7774 if (reg_class_subset_p (rclass
, V_REGS
))
7775 return riscv_hard_regno_nregs (V_REG_FIRST
, mode
);
7780 /* Implement TARGET_MEMORY_MOVE_COST. */
7783 riscv_memory_move_cost (machine_mode mode
, reg_class_t rclass
, bool in
)
7785 return (tune_param
->memory_cost
7786 + memory_move_secondary_cost (mode
, rclass
, in
));
7789 /* Return the number of instructions that can be issued per cycle. */
7792 riscv_issue_rate (void)
7794 return tune_param
->issue_rate
;
7797 /* Implement TARGET_SCHED_VARIABLE_ISSUE. */
7799 riscv_sched_variable_issue (FILE *, int, rtx_insn
*insn
, int more
)
7801 if (DEBUG_INSN_P (insn
))
7804 rtx_code code
= GET_CODE (PATTERN (insn
));
7805 if (code
== USE
|| code
== CLOBBER
)
7808 /* GHOST insns are used for blockage and similar cases which
7809 effectively end a cycle. */
7810 if (get_attr_type (insn
) == TYPE_GHOST
)
7813 /* If we ever encounter an insn with an unknown type, trip
7814 an assert so we can find and fix this problem. */
7815 gcc_assert (get_attr_type (insn
) != TYPE_UNKNOWN
);
7817 /* If we ever encounter an insn without an insn reservation, trip
7818 an assert so we can find and fix this problem. */
7820 gcc_assert (insn_has_dfa_reservation_p (insn
));
7826 /* Implement TARGET_SCHED_MACRO_FUSION_P. Return true if target supports
7827 instruction fusion of some sort. */
7830 riscv_macro_fusion_p (void)
7832 return tune_param
->fusible_ops
!= RISCV_FUSE_NOTHING
;
7835 /* Return true iff the instruction fusion described by OP is enabled. */
7838 riscv_fusion_enabled_p(enum riscv_fusion_pairs op
)
7840 return tune_param
->fusible_ops
& op
;
7843 /* Implement TARGET_SCHED_MACRO_FUSION_PAIR_P. Return true if PREV and CURR
7844 should be kept together during scheduling. */
7847 riscv_macro_fusion_pair_p (rtx_insn
*prev
, rtx_insn
*curr
)
7849 rtx prev_set
= single_set (prev
);
7850 rtx curr_set
= single_set (curr
);
7851 /* prev and curr are simple SET insns i.e. no flag setting or branching. */
7852 bool simple_sets_p
= prev_set
&& curr_set
&& !any_condjump_p (curr
);
7854 if (!riscv_macro_fusion_p ())
7857 if (simple_sets_p
&& (riscv_fusion_enabled_p (RISCV_FUSE_ZEXTW
) ||
7858 riscv_fusion_enabled_p (RISCV_FUSE_ZEXTH
)))
7860 /* We are trying to match the following:
7861 prev (slli) == (set (reg:DI rD)
7862 (ashift:DI (reg:DI rS) (const_int 32)))
7863 curr (slri) == (set (reg:DI rD)
7864 (lshiftrt:DI (reg:DI rD) (const_int <shift>)))
7865 with <shift> being either 32 for FUSE_ZEXTW, or
7866 `less than 32 for FUSE_ZEXTWS. */
7868 if (GET_CODE (SET_SRC (prev_set
)) == ASHIFT
7869 && GET_CODE (SET_SRC (curr_set
)) == LSHIFTRT
7870 && REG_P (SET_DEST (prev_set
))
7871 && REG_P (SET_DEST (curr_set
))
7872 && REGNO (SET_DEST (prev_set
)) == REGNO (SET_DEST (curr_set
))
7873 && REGNO (XEXP (SET_SRC (curr_set
), 0)) == REGNO(SET_DEST (curr_set
))
7874 && CONST_INT_P (XEXP (SET_SRC (prev_set
), 1))
7875 && CONST_INT_P (XEXP (SET_SRC (curr_set
), 1))
7876 && INTVAL (XEXP (SET_SRC (prev_set
), 1)) == 32
7877 && (( INTVAL (XEXP (SET_SRC (curr_set
), 1)) == 32
7878 && riscv_fusion_enabled_p(RISCV_FUSE_ZEXTW
) )
7879 || ( INTVAL (XEXP (SET_SRC (curr_set
), 1)) < 32
7880 && riscv_fusion_enabled_p(RISCV_FUSE_ZEXTWS
))))
7884 if (simple_sets_p
&& riscv_fusion_enabled_p (RISCV_FUSE_ZEXTH
))
7886 /* We are trying to match the following:
7887 prev (slli) == (set (reg:DI rD)
7888 (ashift:DI (reg:DI rS) (const_int 48)))
7889 curr (slri) == (set (reg:DI rD)
7890 (lshiftrt:DI (reg:DI rD) (const_int 48))) */
7892 if (GET_CODE (SET_SRC (prev_set
)) == ASHIFT
7893 && GET_CODE (SET_SRC (curr_set
)) == LSHIFTRT
7894 && REG_P (SET_DEST (prev_set
))
7895 && REG_P (SET_DEST (curr_set
))
7896 && REGNO (SET_DEST (prev_set
)) == REGNO (SET_DEST (curr_set
))
7897 && REGNO (XEXP (SET_SRC (curr_set
), 0)) == REGNO(SET_DEST (curr_set
))
7898 && CONST_INT_P (XEXP (SET_SRC (prev_set
), 1))
7899 && CONST_INT_P (XEXP (SET_SRC (curr_set
), 1))
7900 && INTVAL (XEXP (SET_SRC (prev_set
), 1)) == 48
7901 && INTVAL (XEXP (SET_SRC (curr_set
), 1)) == 48)
7905 if (simple_sets_p
&& riscv_fusion_enabled_p (RISCV_FUSE_LDINDEXED
))
7907 /* We are trying to match the following:
7908 prev (add) == (set (reg:DI rD)
7909 (plus:DI (reg:DI rS1) (reg:DI rS2))
7910 curr (ld) == (set (reg:DI rD)
7911 (mem:DI (reg:DI rD))) */
7913 if (MEM_P (SET_SRC (curr_set
))
7914 && REG_P (XEXP (SET_SRC (curr_set
), 0))
7915 && REGNO (XEXP (SET_SRC (curr_set
), 0)) == REGNO (SET_DEST (prev_set
))
7916 && GET_CODE (SET_SRC (prev_set
)) == PLUS
7917 && REG_P (XEXP (SET_SRC (prev_set
), 0))
7918 && REG_P (XEXP (SET_SRC (prev_set
), 1)))
7921 /* We are trying to match the following:
7922 prev (add) == (set (reg:DI rD)
7923 (plus:DI (reg:DI rS1) (reg:DI rS2)))
7924 curr (lw) == (set (any_extend:DI (mem:SUBX (reg:DI rD)))) */
7926 if ((GET_CODE (SET_SRC (curr_set
)) == SIGN_EXTEND
7927 || (GET_CODE (SET_SRC (curr_set
)) == ZERO_EXTEND
))
7928 && MEM_P (XEXP (SET_SRC (curr_set
), 0))
7929 && REG_P (XEXP (XEXP (SET_SRC (curr_set
), 0), 0))
7930 && REGNO (XEXP (XEXP (SET_SRC (curr_set
), 0), 0)) == REGNO (SET_DEST (prev_set
))
7931 && GET_CODE (SET_SRC (prev_set
)) == PLUS
7932 && REG_P (XEXP (SET_SRC (prev_set
), 0))
7933 && REG_P (XEXP (SET_SRC (prev_set
), 1)))
7937 if (simple_sets_p
&& riscv_fusion_enabled_p (RISCV_FUSE_LDPREINCREMENT
))
7939 /* We are trying to match the following:
7940 prev (add) == (set (reg:DI rS)
7941 (plus:DI (reg:DI rS) (const_int))
7942 curr (ld) == (set (reg:DI rD)
7943 (mem:DI (reg:DI rS))) */
7945 if (MEM_P (SET_SRC (curr_set
))
7946 && REG_P (XEXP (SET_SRC (curr_set
), 0))
7947 && REGNO (XEXP (SET_SRC (curr_set
), 0)) == REGNO (SET_DEST (prev_set
))
7948 && GET_CODE (SET_SRC (prev_set
)) == PLUS
7949 && REG_P (XEXP (SET_SRC (prev_set
), 0))
7950 && CONST_INT_P (XEXP (SET_SRC (prev_set
), 1)))
7954 if (simple_sets_p
&& riscv_fusion_enabled_p (RISCV_FUSE_LUI_ADDI
))
7956 /* We are trying to match the following:
7957 prev (lui) == (set (reg:DI rD) (const_int UPPER_IMM_20))
7958 curr (addi) == (set (reg:DI rD)
7959 (plus:DI (reg:DI rD) (const_int IMM12))) */
7961 if ((GET_CODE (SET_SRC (curr_set
)) == LO_SUM
7962 || (GET_CODE (SET_SRC (curr_set
)) == PLUS
7963 && CONST_INT_P (XEXP (SET_SRC (curr_set
), 1))
7964 && SMALL_OPERAND (INTVAL (XEXP (SET_SRC (curr_set
), 1)))))
7965 && (GET_CODE (SET_SRC (prev_set
)) == HIGH
7966 || (CONST_INT_P (SET_SRC (prev_set
))
7967 && LUI_OPERAND (INTVAL (SET_SRC (prev_set
))))))
7971 if (simple_sets_p
&& riscv_fusion_enabled_p (RISCV_FUSE_AUIPC_ADDI
))
7973 /* We are trying to match the following:
7974 prev (auipc) == (set (reg:DI rD) (unspec:DI [...] UNSPEC_AUIPC))
7975 curr (addi) == (set (reg:DI rD)
7976 (plus:DI (reg:DI rD) (const_int IMM12)))
7978 prev (auipc) == (set (reg:DI rD) (unspec:DI [...] UNSPEC_AUIPC))
7979 curr (addi) == (set (reg:DI rD)
7980 (lo_sum:DI (reg:DI rD) (const_int IMM12))) */
7982 if (GET_CODE (SET_SRC (prev_set
)) == UNSPEC
7983 && XINT (prev_set
, 1) == UNSPEC_AUIPC
7984 && (GET_CODE (SET_SRC (curr_set
)) == LO_SUM
7985 || (GET_CODE (SET_SRC (curr_set
)) == PLUS
7986 && SMALL_OPERAND (INTVAL (XEXP (SET_SRC (curr_set
), 1))))))
7991 if (simple_sets_p
&& riscv_fusion_enabled_p (RISCV_FUSE_LUI_LD
))
7993 /* We are trying to match the following:
7994 prev (lui) == (set (reg:DI rD) (const_int UPPER_IMM_20))
7995 curr (ld) == (set (reg:DI rD)
7996 (mem:DI (plus:DI (reg:DI rD) (const_int IMM12)))) */
7998 if (CONST_INT_P (SET_SRC (prev_set
))
7999 && LUI_OPERAND (INTVAL (SET_SRC (prev_set
)))
8000 && MEM_P (SET_SRC (curr_set
))
8001 && GET_CODE (XEXP (SET_SRC (curr_set
), 0)) == PLUS
)
8004 if (GET_CODE (SET_SRC (prev_set
)) == HIGH
8005 && MEM_P (SET_SRC (curr_set
))
8006 && GET_CODE (XEXP (SET_SRC (curr_set
), 0)) == LO_SUM
8007 && REGNO (SET_DEST (prev_set
)) == REGNO (XEXP (XEXP (SET_SRC (curr_set
), 0), 0)))
8010 if (GET_CODE (SET_SRC (prev_set
)) == HIGH
8011 && (GET_CODE (SET_SRC (curr_set
)) == SIGN_EXTEND
8012 || GET_CODE (SET_SRC (curr_set
)) == ZERO_EXTEND
)
8013 && MEM_P (XEXP (SET_SRC (curr_set
), 0))
8014 && (GET_CODE (XEXP (XEXP (SET_SRC (curr_set
), 0), 0)) == LO_SUM
8015 && REGNO (SET_DEST (prev_set
)) == REGNO (XEXP (XEXP (XEXP (SET_SRC (curr_set
), 0), 0), 0))))
8019 if (simple_sets_p
&& riscv_fusion_enabled_p (RISCV_FUSE_AUIPC_LD
))
8021 /* We are trying to match the following:
8022 prev (auipc) == (set (reg:DI rD) (unspec:DI [...] UNSPEC_AUIPC))
8023 curr (ld) == (set (reg:DI rD)
8024 (mem:DI (plus:DI (reg:DI rD) (const_int IMM12)))) */
8026 if (GET_CODE (SET_SRC (prev_set
)) == UNSPEC
8027 && XINT (prev_set
, 1) == UNSPEC_AUIPC
8028 && MEM_P (SET_SRC (curr_set
))
8029 && GET_CODE (XEXP (SET_SRC (curr_set
), 0)) == PLUS
)
8033 if (simple_sets_p
&& riscv_fusion_enabled_p (RISCV_FUSE_ALIGNED_STD
))
8035 /* We are trying to match the following:
8036 prev (sd) == (set (mem (plus (reg sp|fp) (const_int)))
8038 curr (sd) == (set (mem (plus (reg sp|fp) (const_int)))
8041 if (MEM_P (SET_DEST (prev_set
))
8042 && MEM_P (SET_DEST (curr_set
))
8043 /* We can probably relax this condition. The documentation is a bit
8044 unclear about sub-word cases. So we just model DImode for now. */
8045 && GET_MODE (SET_DEST (curr_set
)) == DImode
8046 && GET_MODE (SET_DEST (prev_set
)) == DImode
)
8048 rtx base_prev
, base_curr
, offset_prev
, offset_curr
;
8050 extract_base_offset_in_addr (SET_DEST (prev_set
), &base_prev
, &offset_prev
);
8051 extract_base_offset_in_addr (SET_DEST (curr_set
), &base_curr
, &offset_curr
);
8053 /* The two stores must be contained within opposite halves of the same
8054 16 byte aligned block of memory. We know that the stack pointer and
8055 the frame pointer have suitable alignment. So we just need to check
8056 the offsets of the two stores for suitable alignment.
8058 Originally the thought was to check MEM_ALIGN, but that was reporting
8059 incorrect alignments, even for SP/FP accesses, so we gave up on that
8061 if (base_prev
!= NULL_RTX
8062 && base_curr
!= NULL_RTX
8063 && REG_P (base_prev
)
8064 && REG_P (base_curr
)
8065 && REGNO (base_prev
) == REGNO (base_curr
)
8066 && (REGNO (base_prev
) == STACK_POINTER_REGNUM
8067 || REGNO (base_prev
) == HARD_FRAME_POINTER_REGNUM
)
8068 && ((INTVAL (offset_prev
) == INTVAL (offset_curr
) + 8
8069 && (INTVAL (offset_prev
) % 16) == 0)
8070 || ((INTVAL (offset_curr
) == INTVAL (offset_prev
) + 8)
8071 && (INTVAL (offset_curr
) % 16) == 0)))
8079 /* Adjust the cost/latency of instructions for scheduling.
8080 For now this is just used to change the latency of vector instructions
8081 according to their LMUL. We assume that an insn with LMUL == 8 requires
8082 eight times more execution cycles than the same insn with LMUL == 1.
8083 As this may cause very high latencies which lead to scheduling artifacts
8084 we currently only perform the adjustment when -madjust-lmul-cost is given.
8087 riscv_sched_adjust_cost (rtx_insn
*, int, rtx_insn
*insn
, int cost
,
8090 /* Only do adjustments for the generic out-of-order scheduling model. */
8091 if (!TARGET_VECTOR
|| riscv_microarchitecture
!= generic_ooo
)
8094 if (recog_memoized (insn
) < 0)
8097 enum attr_type type
= get_attr_type (insn
);
8099 if (type
== TYPE_VFREDO
|| type
== TYPE_VFWREDO
)
8101 /* TODO: For ordered reductions scale the base cost relative to the
8106 /* Don't do any LMUL-based latency adjustment unless explicitly asked to. */
8107 if (!TARGET_ADJUST_LMUL_COST
)
8110 /* vsetvl has a vlmul attribute but its latency does not depend on it. */
8111 if (type
== TYPE_VSETVL
|| type
== TYPE_VSETVL_PRE
)
8114 enum riscv_vector::vlmul_type lmul
=
8115 (riscv_vector::vlmul_type
)get_attr_vlmul (insn
);
8120 case riscv_vector::LMUL_2
:
8123 case riscv_vector::LMUL_4
:
8126 case riscv_vector::LMUL_8
:
8129 case riscv_vector::LMUL_F2
:
8132 case riscv_vector::LMUL_F4
:
8135 case riscv_vector::LMUL_F8
:
8142 /* If the latency was nonzero, keep it that way. */
8143 int new_cost
= MAX (cost
> 0 ? 1 : 0, cost
* factor
);
8148 /* Auxiliary function to emit RISC-V ELF attribute. */
8150 riscv_emit_attribute ()
8152 fprintf (asm_out_file
, "\t.attribute arch, \"%s\"\n",
8153 riscv_arch_str ().c_str ());
8155 fprintf (asm_out_file
, "\t.attribute unaligned_access, %d\n",
8156 TARGET_STRICT_ALIGN
? 0 : 1);
8158 fprintf (asm_out_file
, "\t.attribute stack_align, %d\n",
8159 riscv_stack_boundary
/ 8);
8162 /* Output .variant_cc for function symbol which follows vector calling
8166 riscv_asm_output_variant_cc (FILE *stream
, const tree decl
, const char *name
)
8168 if (TREE_CODE (decl
) == FUNCTION_DECL
)
8170 riscv_cc cc
= (riscv_cc
) fndecl_abi (decl
).id ();
8171 if (cc
== RISCV_CC_V
)
8173 fprintf (stream
, "\t.variant_cc\t");
8174 assemble_name (stream
, name
);
8175 fprintf (stream
, "\n");
8180 /* Implement ASM_DECLARE_FUNCTION_NAME. */
8183 riscv_declare_function_name (FILE *stream
, const char *name
, tree fndecl
)
8185 riscv_asm_output_variant_cc (stream
, fndecl
, name
);
8186 ASM_OUTPUT_TYPE_DIRECTIVE (stream
, name
, "function");
8187 ASM_OUTPUT_LABEL (stream
, name
);
8188 if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl
))
8190 fprintf (stream
, "\t.option push\n");
8191 std::string isa
= riscv_current_subset_list ()->to_string (true);
8192 fprintf (stream
, "\t.option arch, %s\n", isa
.c_str ());
8194 struct cl_target_option
*local_cl_target
=
8195 TREE_TARGET_OPTION (DECL_FUNCTION_SPECIFIC_TARGET (fndecl
));
8196 struct cl_target_option
*global_cl_target
=
8197 TREE_TARGET_OPTION (target_option_default_node
);
8198 const char *local_tune_str
= get_tune_str (local_cl_target
);
8199 const char *global_tune_str
= get_tune_str (global_cl_target
);
8200 if (strcmp (local_tune_str
, global_tune_str
) != 0)
8201 fprintf (stream
, "\t# tune = %s\n", local_tune_str
);
8206 riscv_declare_function_size (FILE *stream
, const char *name
, tree fndecl
)
8208 if (!flag_inhibit_size_directive
)
8209 ASM_OUTPUT_MEASURED_SIZE (stream
, name
);
8211 if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl
))
8213 fprintf (stream
, "\t.option pop\n");
8217 /* Implement ASM_OUTPUT_DEF_FROM_DECLS. */
8220 riscv_asm_output_alias (FILE *stream
, const tree decl
, const tree target
)
8222 const char *name
= XSTR (XEXP (DECL_RTL (decl
), 0), 0);
8223 const char *value
= IDENTIFIER_POINTER (target
);
8224 riscv_asm_output_variant_cc (stream
, decl
, name
);
8225 ASM_OUTPUT_DEF (stream
, name
, value
);
8228 /* Implement ASM_OUTPUT_EXTERNAL. */
8231 riscv_asm_output_external (FILE *stream
, tree decl
, const char *name
)
8233 default_elf_asm_output_external (stream
, decl
, name
);
8234 riscv_asm_output_variant_cc (stream
, decl
, name
);
8237 /* Implement TARGET_ASM_FILE_START. */
8240 riscv_file_start (void)
8242 default_file_start ();
8244 /* Instruct GAS to generate position-[in]dependent code. */
8245 fprintf (asm_out_file
, "\t.option %spic\n", (flag_pic
? "" : "no"));
8247 /* If the user specifies "-mno-relax" on the command line then disable linker
8248 relaxation in the assembler. */
8250 fprintf (asm_out_file
, "\t.option norelax\n");
8252 /* If the user specifies "-mcsr-check" on the command line then enable csr
8253 check in the assembler. */
8254 if (riscv_mcsr_check
)
8255 fprintf (asm_out_file
, "\t.option csr-check\n");
8257 if (riscv_emit_attribute_p
)
8258 riscv_emit_attribute ();
8261 /* Implement TARGET_ASM_OUTPUT_MI_THUNK. Generate rtl rather than asm text
8262 in order to avoid duplicating too much logic from elsewhere. */
8265 riscv_output_mi_thunk (FILE *file
, tree thunk_fndecl ATTRIBUTE_UNUSED
,
8266 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
8269 const char *fnname
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl
));
8270 rtx this_rtx
, temp1
, temp2
, fnaddr
;
8273 /* Pretend to be a post-reload pass while generating rtl. */
8274 reload_completed
= 1;
8276 /* Mark the end of the (empty) prologue. */
8277 emit_note (NOTE_INSN_PROLOGUE_END
);
8279 /* Determine if we can use a sibcall to call FUNCTION directly. */
8280 fnaddr
= gen_rtx_MEM (FUNCTION_MODE
, XEXP (DECL_RTL (function
), 0));
8282 /* We need two temporary registers in some cases. */
8283 temp1
= gen_rtx_REG (Pmode
, RISCV_PROLOGUE_TEMP_REGNUM
);
8284 temp2
= gen_rtx_REG (Pmode
, STATIC_CHAIN_REGNUM
);
8286 /* Find out which register contains the "this" pointer. */
8287 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
8288 this_rtx
= gen_rtx_REG (Pmode
, GP_ARG_FIRST
+ 1);
8290 this_rtx
= gen_rtx_REG (Pmode
, GP_ARG_FIRST
);
8292 /* Add DELTA to THIS_RTX. */
8295 rtx offset
= GEN_INT (delta
);
8296 if (!SMALL_OPERAND (delta
))
8298 riscv_emit_move (temp1
, offset
);
8301 emit_insn (gen_add3_insn (this_rtx
, this_rtx
, offset
));
8304 /* If needed, add *(*THIS_RTX + VCALL_OFFSET) to THIS_RTX. */
8305 if (vcall_offset
!= 0)
8309 /* Set TEMP1 to *THIS_RTX. */
8310 riscv_emit_move (temp1
, gen_rtx_MEM (Pmode
, this_rtx
));
8312 /* Set ADDR to a legitimate address for *THIS_RTX + VCALL_OFFSET. */
8313 addr
= riscv_add_offset (temp2
, temp1
, vcall_offset
);
8315 /* Load the offset and add it to THIS_RTX. */
8316 riscv_emit_move (temp1
, gen_rtx_MEM (Pmode
, addr
));
8317 emit_insn (gen_add3_insn (this_rtx
, this_rtx
, temp1
));
8320 /* Jump to the target function. */
8321 rtx callee_cc
= gen_int_mode (fndecl_abi (function
).id (), SImode
);
8322 insn
= emit_call_insn (gen_sibcall (fnaddr
, const0_rtx
, callee_cc
));
8323 SIBLING_CALL_P (insn
) = 1;
8325 /* Run just enough of rest_of_compilation. This sequence was
8326 "borrowed" from alpha.cc. */
8327 insn
= get_insns ();
8328 split_all_insns_noflow ();
8329 shorten_branches (insn
);
8330 assemble_start_function (thunk_fndecl
, fnname
);
8331 final_start_function (insn
, file
, 1);
8332 final (insn
, file
, 1);
8333 final_end_function ();
8334 assemble_end_function (thunk_fndecl
, fnname
);
8336 /* Clean up the vars set above. Note that final_end_function resets
8337 the global pointer for us. */
8338 reload_completed
= 0;
8341 /* Allocate a chunk of memory for per-function machine-dependent data. */
8343 static struct machine_function
*
8344 riscv_init_machine_status (void)
8346 return ggc_cleared_alloc
<machine_function
> ();
8349 /* Return the VLEN value associated with -march.
8350 TODO: So far we only support length-agnostic value. */
8352 riscv_convert_vector_bits (struct gcc_options
*opts
)
8355 int min_vlen
= TARGET_MIN_VLEN_OPTS (opts
);
8358 /* When targetting minimum VLEN > 32, we should use 64-bit chunk size.
8359 Otherwise we can not include SEW = 64bits.
8360 Runtime invariant: The single indeterminate represent the
8361 number of 64-bit chunks in a vector beyond minimum length of 64 bits.
8362 Thus the number of bytes in a vector is 8 + 8 * x1 which is
8363 riscv_vector_chunks * 8 = poly_int (8, 8). */
8364 riscv_bytes_per_vector_chunk
= 8;
8365 /* Adjust BYTES_PER_RISCV_VECTOR according to TARGET_MIN_VLEN:
8366 - TARGET_MIN_VLEN = 64bit: [8,8]
8367 - TARGET_MIN_VLEN = 128bit: [16,16]
8368 - TARGET_MIN_VLEN = 256bit: [32,32]
8369 - TARGET_MIN_VLEN = 512bit: [64,64]
8370 - TARGET_MIN_VLEN = 1024bit: [128,128]
8371 - TARGET_MIN_VLEN = 2048bit: [256,256]
8372 - TARGET_MIN_VLEN = 4096bit: [512,512]
8373 FIXME: We currently DON'T support TARGET_MIN_VLEN > 4096bit. */
8374 chunk_num
= min_vlen
/ 64;
8378 /* When targetting minimum VLEN = 32, we should use 32-bit
8379 chunk size. Runtime invariant: The single indeterminate represent the
8380 number of 32-bit chunks in a vector beyond minimum length of 32 bits.
8381 Thus the number of bytes in a vector is 4 + 4 * x1 which is
8382 riscv_vector_chunks * 4 = poly_int (4, 4). */
8383 riscv_bytes_per_vector_chunk
= 4;
8387 /* Set riscv_vector_chunks as poly (1, 1) run-time constant if TARGET_VECTOR
8388 is enabled. Set riscv_vector_chunks as 1 compile-time constant if
8389 TARGET_VECTOR is disabled. riscv_vector_chunks is used in "riscv-modes.def"
8390 to set RVV mode size. The RVV machine modes size are run-time constant if
8391 TARGET_VECTOR is enabled. The RVV machine modes size remains default
8392 compile-time constant if TARGET_VECTOR is disabled. */
8393 if (TARGET_VECTOR_OPTS_P (opts
))
8395 if (opts
->x_riscv_autovec_preference
== RVV_FIXED_VLMAX
)
8396 return (int) min_vlen
/ (riscv_bytes_per_vector_chunk
* 8);
8398 return poly_uint16 (chunk_num
, chunk_num
);
8404 /* 'Unpack' up the internal tuning structs and update the options
8405 in OPTS. The caller must have set up selected_tune and selected_arch
8406 as all the other target-specific codegen decisions are
8407 derived from them. */
8409 riscv_override_options_internal (struct gcc_options
*opts
)
8411 const struct riscv_tune_info
*cpu
;
8413 /* The presence of the M extension implies that division instructions
8414 are present, so include them unless explicitly disabled. */
8415 if (TARGET_MUL_OPTS_P (opts
) && (target_flags_explicit
& MASK_DIV
) == 0)
8416 opts
->x_target_flags
|= MASK_DIV
;
8417 else if (!TARGET_MUL_OPTS_P (opts
) && TARGET_DIV_OPTS_P (opts
))
8418 error ("%<-mdiv%> requires %<-march%> to subsume the %<M%> extension");
8420 /* Likewise floating-point division and square root. */
8421 if ((TARGET_HARD_FLOAT_OPTS_P (opts
) || TARGET_ZFINX_OPTS_P (opts
))
8422 && ((target_flags_explicit
& MASK_FDIV
) == 0))
8423 opts
->x_target_flags
|= MASK_FDIV
;
8425 /* Handle -mtune, use -mcpu if -mtune is not given, and use default -mtune
8426 if both -mtune and -mcpu are not given. */
8427 const char *tune_string
= get_tune_str (opts
);
8428 cpu
= riscv_parse_tune (tune_string
, false);
8429 riscv_microarchitecture
= cpu
->microarchitecture
;
8430 tune_param
= opts
->x_optimize_size
8431 ? &optimize_size_tune_info
8434 /* Use -mtune's setting for slow_unaligned_access, even when optimizing
8435 for size. For architectures that trap and emulate unaligned accesses,
8436 the performance cost is too great, even for -Os. Similarly, if
8437 -m[no-]strict-align is left unspecified, heed -mtune's advice. */
8438 riscv_slow_unaligned_access_p
= (cpu
->tune_param
->slow_unaligned_access
8439 || TARGET_STRICT_ALIGN
);
8441 /* Make a note if user explicity passed -mstrict-align for later
8442 builtin macro generation. Can't use target_flags_explicitly since
8443 it is set even for -mno-strict-align. */
8444 riscv_user_wants_strict_align
= TARGET_STRICT_ALIGN_OPTS_P (opts
);
8446 if ((target_flags_explicit
& MASK_STRICT_ALIGN
) == 0
8447 && cpu
->tune_param
->slow_unaligned_access
)
8448 opts
->x_target_flags
|= MASK_STRICT_ALIGN
;
8450 /* If the user hasn't specified a branch cost, use the processor's
8452 if (opts
->x_riscv_branch_cost
== 0)
8453 opts
->x_riscv_branch_cost
= tune_param
->branch_cost
;
8455 /* FIXME: We don't allow TARGET_MIN_VLEN > 4096 since the datatypes of
8456 both GET_MODE_SIZE and GET_MODE_BITSIZE are poly_uint16.
8458 We can only allow TARGET_MIN_VLEN * 8 (LMUL) < 65535. */
8459 if (TARGET_MIN_VLEN_OPTS (opts
) > 4096)
8460 sorry ("Current RISC-V GCC cannot support VLEN greater than 4096bit for "
8463 /* Convert -march to a chunks count. */
8464 riscv_vector_chunks
= riscv_convert_vector_bits (opts
);
8467 /* Implement TARGET_OPTION_OVERRIDE. */
8470 riscv_option_override (void)
8472 #ifdef SUBTARGET_OVERRIDE_OPTIONS
8473 SUBTARGET_OVERRIDE_OPTIONS
;
8476 flag_pcc_struct_return
= 0;
8482 riscv_cmodel
= CM_PIC
;
8484 /* We need to save the fp with ra for non-leaf functions with no fp and ra
8485 for leaf functions while no-omit-frame-pointer with
8486 omit-leaf-frame-pointer. The x_flag_omit_frame_pointer has the first
8487 priority to determine whether the frame pointer is needed. If we do not
8488 override it, the fp and ra will be stored for leaf functions, which is not
8490 riscv_save_frame_pointer
= false;
8491 if (TARGET_OMIT_LEAF_FRAME_POINTER_P (global_options
.x_target_flags
))
8493 if (!global_options
.x_flag_omit_frame_pointer
)
8494 riscv_save_frame_pointer
= true;
8496 global_options
.x_flag_omit_frame_pointer
= 1;
8499 /* We get better code with explicit relocs for CM_MEDLOW, but
8500 worse code for the others (for now). Pick the best default. */
8501 if ((target_flags_explicit
& MASK_EXPLICIT_RELOCS
) == 0)
8502 if (riscv_cmodel
== CM_MEDLOW
)
8503 target_flags
|= MASK_EXPLICIT_RELOCS
;
8505 /* Require that the ISA supports the requested floating-point ABI. */
8506 if (UNITS_PER_FP_ARG
> (TARGET_HARD_FLOAT
? UNITS_PER_FP_REG
: 0))
8507 error ("requested ABI requires %<-march%> to subsume the %qc extension",
8508 UNITS_PER_FP_ARG
> 8 ? 'Q' : (UNITS_PER_FP_ARG
> 4 ? 'D' : 'F'));
8510 if (TARGET_RVE
&& riscv_abi
!= ABI_ILP32E
)
8511 error ("rv32e requires ilp32e ABI");
8513 // Zfinx require abi ilp32,ilp32e or lp64.
8514 if (TARGET_ZFINX
&& riscv_abi
!= ABI_ILP32
8515 && riscv_abi
!= ABI_LP64
&& riscv_abi
!= ABI_ILP32E
)
8516 error ("z*inx requires ABI ilp32, ilp32e or lp64");
8518 /* We do not yet support ILP32 on RV64. */
8519 if (BITS_PER_WORD
!= POINTER_SIZE
)
8520 error ("ABI requires %<-march=rv%d%>", POINTER_SIZE
);
8522 /* Validate -mpreferred-stack-boundary= value. */
8523 riscv_stack_boundary
= ABI_STACK_BOUNDARY
;
8524 if (riscv_preferred_stack_boundary_arg
)
8526 int min
= ctz_hwi (STACK_BOUNDARY
/ 8);
8529 if (!IN_RANGE (riscv_preferred_stack_boundary_arg
, min
, max
))
8530 error ("%<-mpreferred-stack-boundary=%d%> must be between %d and %d",
8531 riscv_preferred_stack_boundary_arg
, min
, max
);
8533 riscv_stack_boundary
= 8 << riscv_preferred_stack_boundary_arg
;
8536 if (riscv_emit_attribute_p
< 0)
8537 #ifdef HAVE_AS_RISCV_ATTRIBUTE
8538 riscv_emit_attribute_p
= TARGET_RISCV_ATTRIBUTE
;
8540 riscv_emit_attribute_p
= 0;
8542 if (riscv_emit_attribute_p
)
8543 error ("%<-mriscv-attribute%> RISC-V ELF attribute requires GNU as 2.32"
8544 " [%<-mriscv-attribute%>]");
8547 if (riscv_stack_protector_guard
== SSP_GLOBAL
8548 && OPTION_SET_P (riscv_stack_protector_guard_offset_str
))
8550 error ("incompatible options %<-mstack-protector-guard=global%> and "
8551 "%<-mstack-protector-guard-offset=%s%>",
8552 riscv_stack_protector_guard_offset_str
);
8555 if (riscv_stack_protector_guard
== SSP_TLS
8556 && !(OPTION_SET_P (riscv_stack_protector_guard_offset_str
)
8557 && OPTION_SET_P (riscv_stack_protector_guard_reg_str
)))
8559 error ("both %<-mstack-protector-guard-offset%> and "
8560 "%<-mstack-protector-guard-reg%> must be used "
8561 "with %<-mstack-protector-guard=sysreg%>");
8564 if (OPTION_SET_P (riscv_stack_protector_guard_reg_str
))
8566 const char *str
= riscv_stack_protector_guard_reg_str
;
8567 int reg
= decode_reg_name (str
);
8569 if (!IN_RANGE (reg
, GP_REG_FIRST
+ 1, GP_REG_LAST
))
8570 error ("%qs is not a valid base register in %qs", str
,
8571 "-mstack-protector-guard-reg=");
8573 riscv_stack_protector_guard_reg
= reg
;
8576 if (OPTION_SET_P (riscv_stack_protector_guard_offset_str
))
8579 const char *str
= riscv_stack_protector_guard_offset_str
;
8581 long offs
= strtol (riscv_stack_protector_guard_offset_str
, &end
, 0);
8583 if (!*str
|| *end
|| errno
)
8584 error ("%qs is not a valid number in %qs", str
,
8585 "-mstack-protector-guard-offset=");
8587 if (!SMALL_OPERAND (offs
))
8588 error ("%qs is not a valid offset in %qs", str
,
8589 "-mstack-protector-guard-offset=");
8591 riscv_stack_protector_guard_offset
= offs
;
8594 SET_OPTION_IF_UNSET (&global_options
, &global_options_set
,
8595 param_sched_pressure_algorithm
,
8596 SCHED_PRESSURE_MODEL
);
8598 /* Function to allocate machine-dependent function status. */
8599 init_machine_status
= &riscv_init_machine_status
;
8601 riscv_override_options_internal (&global_options
);
8603 /* Save these options as the default ones in case we push and pop them later
8604 while processing functions with potential target attributes. */
8605 target_option_default_node
= target_option_current_node
8606 = build_target_option_node (&global_options
, &global_options_set
);
8609 /* Restore or save the TREE_TARGET_GLOBALS from or to NEW_TREE.
8610 Used by riscv_set_current_function to
8611 make sure optab availability predicates are recomputed when necessary. */
8614 riscv_save_restore_target_globals (tree new_tree
)
8616 if (TREE_TARGET_GLOBALS (new_tree
))
8617 restore_target_globals (TREE_TARGET_GLOBALS (new_tree
));
8618 else if (new_tree
== target_option_default_node
)
8619 restore_target_globals (&default_target_globals
);
8621 TREE_TARGET_GLOBALS (new_tree
) = save_target_globals_default_opts ();
8624 /* Implements TARGET_OPTION_RESTORE. Restore the backend codegen decisions
8625 using the information saved in PTR. */
8628 riscv_option_restore (struct gcc_options
*opts
,
8629 struct gcc_options
* /* opts_set */,
8630 struct cl_target_option
* /* ptr */)
8632 riscv_override_options_internal (opts
);
8635 static GTY (()) tree riscv_previous_fndecl
;
8637 /* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */
8640 riscv_conditional_register_usage (void)
8642 /* We have only x0~x15 on RV32E. */
8645 for (int r
= 16; r
<= 31; r
++)
8649 if (riscv_abi
== ABI_ILP32E
)
8651 for (int r
= 16; r
<= 31; r
++)
8652 call_used_regs
[r
] = 1;
8655 if (!TARGET_HARD_FLOAT
)
8657 for (int regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
++)
8658 fixed_regs
[regno
] = call_used_regs
[regno
] = 1;
8661 /* In the soft-float ABI, there are no callee-saved FP registers. */
8662 if (UNITS_PER_FP_ARG
== 0)
8664 for (int regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
++)
8665 call_used_regs
[regno
] = 1;
8670 for (int regno
= V_REG_FIRST
; regno
<= V_REG_LAST
; regno
++)
8671 fixed_regs
[regno
] = call_used_regs
[regno
] = 1;
8673 fixed_regs
[VTYPE_REGNUM
] = call_used_regs
[VTYPE_REGNUM
] = 1;
8674 fixed_regs
[VL_REGNUM
] = call_used_regs
[VL_REGNUM
] = 1;
8675 fixed_regs
[VXRM_REGNUM
] = call_used_regs
[VXRM_REGNUM
] = 1;
8676 fixed_regs
[FRM_REGNUM
] = call_used_regs
[FRM_REGNUM
] = 1;
8680 /* Return a register priority for hard reg REGNO. */
8683 riscv_register_priority (int regno
)
8685 /* Favor compressed registers to improve the odds of RVC instruction
8687 if (riscv_compressed_reg_p (regno
))
8693 /* Implement TARGET_TRAMPOLINE_INIT. */
8696 riscv_trampoline_init (rtx m_tramp
, tree fndecl
, rtx chain_value
)
8698 rtx addr
, end_addr
, mem
;
8699 uint32_t trampoline
[4];
8701 HOST_WIDE_INT static_chain_offset
, target_function_offset
;
8703 /* Work out the offsets of the pointers from the start of the
8705 gcc_assert (ARRAY_SIZE (trampoline
) * 4 == TRAMPOLINE_CODE_SIZE
);
8707 /* Get pointers to the beginning and end of the code block. */
8708 addr
= force_reg (Pmode
, XEXP (m_tramp
, 0));
8709 end_addr
= riscv_force_binary (Pmode
, PLUS
, addr
,
8710 GEN_INT (TRAMPOLINE_CODE_SIZE
));
8713 if (Pmode
== SImode
)
8715 chain_value
= force_reg (Pmode
, chain_value
);
8717 rtx target_function
= force_reg (Pmode
, XEXP (DECL_RTL (fndecl
), 0));
8718 /* lui t2, hi(chain)
8720 addi t2, t2, lo(chain)
8723 unsigned HOST_WIDE_INT lui_hi_chain_code
, lui_hi_func_code
;
8724 unsigned HOST_WIDE_INT lo_chain_code
, lo_func_code
;
8726 rtx uimm_mask
= force_reg (SImode
, gen_int_mode (-IMM_REACH
, SImode
));
8729 rtx imm12_mask
= gen_reg_rtx (SImode
);
8730 emit_insn (gen_one_cmplsi2 (imm12_mask
, uimm_mask
));
8732 rtx fixup_value
= force_reg (SImode
, gen_int_mode (IMM_REACH
/2, SImode
));
8734 /* Gen lui t2, hi(chain). */
8735 rtx hi_chain
= riscv_force_binary (SImode
, PLUS
, chain_value
,
8737 hi_chain
= riscv_force_binary (SImode
, AND
, hi_chain
,
8739 lui_hi_chain_code
= OPCODE_LUI
| (STATIC_CHAIN_REGNUM
<< SHIFT_RD
);
8740 rtx lui_hi_chain
= riscv_force_binary (SImode
, IOR
, hi_chain
,
8741 gen_int_mode (lui_hi_chain_code
, SImode
));
8743 mem
= adjust_address (m_tramp
, SImode
, 0);
8744 riscv_emit_move (mem
, riscv_swap_instruction (lui_hi_chain
));
8746 /* Gen lui t0, hi(func). */
8747 rtx hi_func
= riscv_force_binary (SImode
, PLUS
, target_function
,
8749 hi_func
= riscv_force_binary (SImode
, AND
, hi_func
,
8751 lui_hi_func_code
= OPCODE_LUI
| (RISCV_PROLOGUE_TEMP_REGNUM
<< SHIFT_RD
);
8752 rtx lui_hi_func
= riscv_force_binary (SImode
, IOR
, hi_func
,
8753 gen_int_mode (lui_hi_func_code
, SImode
));
8755 mem
= adjust_address (m_tramp
, SImode
, 1 * GET_MODE_SIZE (SImode
));
8756 riscv_emit_move (mem
, riscv_swap_instruction (lui_hi_func
));
8758 /* Gen addi t2, t2, lo(chain). */
8759 rtx lo_chain
= riscv_force_binary (SImode
, AND
, chain_value
,
8761 lo_chain
= riscv_force_binary (SImode
, ASHIFT
, lo_chain
, GEN_INT (20));
8763 lo_chain_code
= OPCODE_ADDI
8764 | (STATIC_CHAIN_REGNUM
<< SHIFT_RD
)
8765 | (STATIC_CHAIN_REGNUM
<< SHIFT_RS1
);
8767 rtx addi_lo_chain
= riscv_force_binary (SImode
, IOR
, lo_chain
,
8768 force_reg (SImode
, GEN_INT (lo_chain_code
)));
8770 mem
= adjust_address (m_tramp
, SImode
, 2 * GET_MODE_SIZE (SImode
));
8771 riscv_emit_move (mem
, riscv_swap_instruction (addi_lo_chain
));
8773 /* Gen jr t0, lo(func). */
8774 rtx lo_func
= riscv_force_binary (SImode
, AND
, target_function
,
8776 lo_func
= riscv_force_binary (SImode
, ASHIFT
, lo_func
, GEN_INT (20));
8778 lo_func_code
= OPCODE_JALR
| (RISCV_PROLOGUE_TEMP_REGNUM
<< SHIFT_RS1
);
8780 rtx jr_lo_func
= riscv_force_binary (SImode
, IOR
, lo_func
,
8781 force_reg (SImode
, GEN_INT (lo_func_code
)));
8783 mem
= adjust_address (m_tramp
, SImode
, 3 * GET_MODE_SIZE (SImode
));
8784 riscv_emit_move (mem
, riscv_swap_instruction (jr_lo_func
));
8788 static_chain_offset
= TRAMPOLINE_CODE_SIZE
;
8789 target_function_offset
= static_chain_offset
+ GET_MODE_SIZE (ptr_mode
);
8792 l[wd] t0, target_function_offset(t2)
8793 l[wd] t2, static_chain_offset(t2)
8796 trampoline
[0] = OPCODE_AUIPC
| (STATIC_CHAIN_REGNUM
<< SHIFT_RD
);
8797 trampoline
[1] = (Pmode
== DImode
? OPCODE_LD
: OPCODE_LW
)
8798 | (RISCV_PROLOGUE_TEMP_REGNUM
<< SHIFT_RD
)
8799 | (STATIC_CHAIN_REGNUM
<< SHIFT_RS1
)
8800 | (target_function_offset
<< SHIFT_IMM
);
8801 trampoline
[2] = (Pmode
== DImode
? OPCODE_LD
: OPCODE_LW
)
8802 | (STATIC_CHAIN_REGNUM
<< SHIFT_RD
)
8803 | (STATIC_CHAIN_REGNUM
<< SHIFT_RS1
)
8804 | (static_chain_offset
<< SHIFT_IMM
);
8805 trampoline
[3] = OPCODE_JALR
| (RISCV_PROLOGUE_TEMP_REGNUM
<< SHIFT_RS1
);
8807 /* Copy the trampoline code. */
8808 for (i
= 0; i
< ARRAY_SIZE (trampoline
); i
++)
8810 if (BYTES_BIG_ENDIAN
)
8811 trampoline
[i
] = __builtin_bswap32(trampoline
[i
]);
8812 mem
= adjust_address (m_tramp
, SImode
, i
* GET_MODE_SIZE (SImode
));
8813 riscv_emit_move (mem
, gen_int_mode (trampoline
[i
], SImode
));
8816 /* Set up the static chain pointer field. */
8817 mem
= adjust_address (m_tramp
, ptr_mode
, static_chain_offset
);
8818 riscv_emit_move (mem
, chain_value
);
8820 /* Set up the target function field. */
8821 mem
= adjust_address (m_tramp
, ptr_mode
, target_function_offset
);
8822 riscv_emit_move (mem
, XEXP (DECL_RTL (fndecl
), 0));
8825 /* Flush the code part of the trampoline. */
8826 emit_insn (gen_add3_insn (end_addr
, addr
, GEN_INT (TRAMPOLINE_SIZE
)));
8827 emit_insn (gen_clear_cache (addr
, end_addr
));
8830 /* Implement TARGET_FUNCTION_OK_FOR_SIBCALL. */
8833 riscv_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED
,
8834 tree exp ATTRIBUTE_UNUSED
)
8836 /* Don't use sibcalls when use save-restore routine. */
8837 if (TARGET_SAVE_RESTORE
)
8840 /* Don't use sibcall for naked functions. */
8841 if (cfun
->machine
->naked_p
)
8844 /* Don't use sibcall for interrupt functions. */
8845 if (cfun
->machine
->interrupt_handler_p
)
8851 /* Get the interrupt type, return UNKNOWN_MODE if it's not
8852 interrupt function. */
8853 static enum riscv_privilege_levels
8854 riscv_get_interrupt_type (tree decl
)
8856 gcc_assert (decl
!= NULL_TREE
);
8858 if ((TREE_CODE(decl
) != FUNCTION_DECL
)
8859 || (!riscv_interrupt_type_p (TREE_TYPE (decl
))))
8860 return UNKNOWN_MODE
;
8863 = TREE_VALUE (lookup_attribute ("interrupt",
8864 TYPE_ATTRIBUTES (TREE_TYPE (decl
))));
8866 if (attr_args
&& TREE_CODE (TREE_VALUE (attr_args
)) != VOID_TYPE
)
8868 const char *string
= TREE_STRING_POINTER (TREE_VALUE (attr_args
));
8870 if (!strcmp (string
, "user"))
8872 else if (!strcmp (string
, "supervisor"))
8873 return SUPERVISOR_MODE
;
8874 else /* Must be "machine". */
8875 return MACHINE_MODE
;
8878 /* Interrupt attributes are machine mode by default. */
8879 return MACHINE_MODE
;
8882 /* Implement `TARGET_SET_CURRENT_FUNCTION'. Unpack the codegen decisions
8883 like tuning and ISA features from the DECL_FUNCTION_SPECIFIC_TARGET
8884 of the function, if such exists. This function may be called multiple
8885 times on a single function so use aarch64_previous_fndecl to avoid
8886 setting up identical state. */
8888 /* Sanity cheching for above function attributes. */
8890 riscv_set_current_function (tree decl
)
8892 if (decl
== NULL_TREE
8893 || current_function_decl
== NULL_TREE
8894 || current_function_decl
== error_mark_node
8898 if (!cfun
->machine
->attributes_checked_p
)
8900 cfun
->machine
->naked_p
= riscv_naked_function_p (decl
);
8901 cfun
->machine
->interrupt_handler_p
8902 = riscv_interrupt_type_p (TREE_TYPE (decl
));
8904 if (cfun
->machine
->naked_p
&& cfun
->machine
->interrupt_handler_p
)
8905 error ("function attributes %qs and %qs are mutually exclusive",
8906 "interrupt", "naked");
8908 if (cfun
->machine
->interrupt_handler_p
)
8910 tree ret
= TREE_TYPE (TREE_TYPE (decl
));
8911 tree args
= TYPE_ARG_TYPES (TREE_TYPE (decl
));
8913 if (TREE_CODE (ret
) != VOID_TYPE
)
8914 error ("%qs function cannot return a value", "interrupt");
8916 if (args
&& TREE_CODE (TREE_VALUE (args
)) != VOID_TYPE
)
8917 error ("%qs function cannot have arguments", "interrupt");
8919 cfun
->machine
->interrupt_mode
= riscv_get_interrupt_type (decl
);
8921 gcc_assert (cfun
->machine
->interrupt_mode
!= UNKNOWN_MODE
);
8924 /* Don't print the above diagnostics more than once. */
8925 cfun
->machine
->attributes_checked_p
= 1;
8928 if (!decl
|| decl
== riscv_previous_fndecl
)
8931 tree old_tree
= (riscv_previous_fndecl
8932 ? DECL_FUNCTION_SPECIFIC_TARGET (riscv_previous_fndecl
)
8935 tree new_tree
= DECL_FUNCTION_SPECIFIC_TARGET (decl
);
8937 /* If current function has no attributes but the previous one did,
8938 use the default node. */
8939 if (!new_tree
&& old_tree
)
8940 new_tree
= target_option_default_node
;
8942 /* If nothing to do, return. #pragma GCC reset or #pragma GCC pop to
8943 the default have been handled by aarch64_save_restore_target_globals from
8944 aarch64_pragma_target_parse. */
8945 if (old_tree
== new_tree
)
8948 riscv_previous_fndecl
= decl
;
8950 /* First set the target options. */
8951 cl_target_option_restore (&global_options
, &global_options_set
,
8952 TREE_TARGET_OPTION (new_tree
));
8954 riscv_save_restore_target_globals (new_tree
);
8957 /* Implement TARGET_MERGE_DECL_ATTRIBUTES. */
8959 riscv_merge_decl_attributes (tree olddecl
, tree newdecl
)
8961 tree combined_attrs
;
8963 enum riscv_privilege_levels old_interrupt_type
8964 = riscv_get_interrupt_type (olddecl
);
8965 enum riscv_privilege_levels new_interrupt_type
8966 = riscv_get_interrupt_type (newdecl
);
8968 /* Check old and new has same interrupt type. */
8969 if ((old_interrupt_type
!= UNKNOWN_MODE
)
8970 && (new_interrupt_type
!= UNKNOWN_MODE
)
8971 && (old_interrupt_type
!= new_interrupt_type
))
8972 error ("%qs function cannot have different interrupt type", "interrupt");
8974 /* Create combined attributes. */
8975 combined_attrs
= merge_attributes (DECL_ATTRIBUTES (olddecl
),
8976 DECL_ATTRIBUTES (newdecl
));
8978 return combined_attrs
;
8981 /* Implement TARGET_CANNOT_COPY_INSN_P. */
8984 riscv_cannot_copy_insn_p (rtx_insn
*insn
)
8986 return recog_memoized (insn
) >= 0 && get_attr_cannot_copy (insn
);
8989 /* Implement TARGET_SLOW_UNALIGNED_ACCESS. */
8992 riscv_slow_unaligned_access (machine_mode
, unsigned int)
8994 return riscv_slow_unaligned_access_p
;
8997 /* Implement TARGET_CAN_CHANGE_MODE_CLASS. */
9000 riscv_can_change_mode_class (machine_mode from
, machine_mode to
,
9003 /* We have RVV VLS modes and VLA modes sharing same REG_CLASS.
9004 In 'cprop_hardreg' stage, we will try to do hard reg copy propagation
9005 between wider mode (FROM) and narrow mode (TO).
9007 E.g. We should not allow copy propagation
9008 - RVVMF8BI (precision = [16, 16]) -> V32BI (precision = [32, 0])
9009 since we can't order their size which will cause ICE in regcprop.
9011 TODO: Even though they are have different size, they always change
9012 the whole register. We may enhance such case in regcprop to optimize
9013 it in the future. */
9014 if (reg_classes_intersect_p (V_REGS
, rclass
)
9015 && !ordered_p (GET_MODE_PRECISION (from
), GET_MODE_PRECISION (to
)))
9017 return !reg_classes_intersect_p (FP_REGS
, rclass
);
9020 /* Implement TARGET_CONSTANT_ALIGNMENT. */
9022 static HOST_WIDE_INT
9023 riscv_constant_alignment (const_tree exp
, HOST_WIDE_INT align
)
9025 if ((TREE_CODE (exp
) == STRING_CST
|| TREE_CODE (exp
) == CONSTRUCTOR
)
9026 && (riscv_align_data_type
== riscv_align_data_type_xlen
))
9027 return MAX (align
, BITS_PER_WORD
);
9031 /* Implement TARGET_PROMOTE_FUNCTION_MODE. */
9033 /* This function is equivalent to default_promote_function_mode_always_promote
9034 except that it returns a promoted mode even if type is NULL_TREE. This is
9035 needed by libcalls which have no type (only a mode) such as fixed conversion
9036 routines that take a signed or unsigned char/short/int argument and convert
9037 it to a fixed type. */
9040 riscv_promote_function_mode (const_tree type ATTRIBUTE_UNUSED
,
9042 int *punsignedp ATTRIBUTE_UNUSED
,
9043 const_tree fntype ATTRIBUTE_UNUSED
,
9044 int for_return ATTRIBUTE_UNUSED
)
9048 if (type
!= NULL_TREE
)
9049 return promote_mode (type
, mode
, punsignedp
);
9051 unsignedp
= *punsignedp
;
9052 scalar_mode smode
= as_a
<scalar_mode
> (mode
);
9053 PROMOTE_MODE (smode
, unsignedp
, type
);
9054 *punsignedp
= unsignedp
;
9058 /* Implement TARGET_MACHINE_DEPENDENT_REORG. */
9063 /* Do nothing unless we have -msave-restore */
9064 if (TARGET_SAVE_RESTORE
)
9065 riscv_remove_unneeded_save_restore_calls ();
9068 /* Return nonzero if register FROM_REGNO can be renamed to register
9072 riscv_hard_regno_rename_ok (unsigned from_regno ATTRIBUTE_UNUSED
,
9075 /* Interrupt functions can only use registers that have already been
9076 saved by the prologue, even if they would normally be
9078 return !cfun
->machine
->interrupt_handler_p
|| df_regs_ever_live_p (to_regno
);
9081 /* Implement TARGET_NEW_ADDRESS_PROFITABLE_P. */
9084 riscv_new_address_profitable_p (rtx memref
, rtx_insn
*insn
, rtx new_addr
)
9086 /* Prefer old address if it is less expensive. */
9087 addr_space_t as
= MEM_ADDR_SPACE (memref
);
9088 bool speed
= optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn
));
9089 int old_cost
= address_cost (XEXP (memref
, 0), GET_MODE (memref
), as
, speed
);
9090 int new_cost
= address_cost (new_addr
, GET_MODE (memref
), as
, speed
);
9091 return new_cost
<= old_cost
;
9094 /* Helper function for generating gpr_save pattern. */
9097 riscv_gen_gpr_save_insn (struct riscv_frame_info
*frame
)
9099 unsigned count
= riscv_save_libcall_count (frame
->mask
);
9100 /* 1 for unspec 2 for clobber t0/t1 and 1 for ra. */
9101 unsigned veclen
= 1 + 2 + 1 + count
;
9102 rtvec vec
= rtvec_alloc (veclen
);
9104 gcc_assert (veclen
<= ARRAY_SIZE (gpr_save_reg_order
));
9106 RTVEC_ELT (vec
, 0) =
9107 gen_rtx_UNSPEC_VOLATILE (VOIDmode
,
9108 gen_rtvec (1, GEN_INT (count
)), UNSPECV_GPR_SAVE
);
9110 for (unsigned i
= 1; i
< veclen
; ++i
)
9112 unsigned regno
= gpr_save_reg_order
[i
];
9113 rtx reg
= gen_rtx_REG (Pmode
, regno
);
9116 /* t0 and t1 are CLOBBERs, others are USEs. */
9118 elt
= gen_rtx_CLOBBER (Pmode
, reg
);
9120 elt
= gen_rtx_USE (Pmode
, reg
);
9122 RTVEC_ELT (vec
, i
) = elt
;
9125 /* Largest number of caller-save register must set in mask if we are
9126 not using __riscv_save_0. */
9127 gcc_assert ((count
== 0) ||
9128 BITSET_P (frame
->mask
, gpr_save_reg_order
[veclen
- 1]));
9130 return gen_rtx_PARALLEL (VOIDmode
, vec
);
9133 static HOST_WIDE_INT
9134 zcmp_base_adj (int regs_num
)
9136 return riscv_16bytes_align ((regs_num
) *GET_MODE_SIZE (word_mode
));
9139 static HOST_WIDE_INT
9140 zcmp_additional_adj (HOST_WIDE_INT total
, int regs_num
)
9142 return total
- zcmp_base_adj (regs_num
);
9146 riscv_zcmp_valid_stack_adj_bytes_p (HOST_WIDE_INT total
, int regs_num
)
9148 HOST_WIDE_INT additioanl_bytes
= zcmp_additional_adj (total
, regs_num
);
9149 return additioanl_bytes
== 0 || additioanl_bytes
== 1 * ZCMP_SP_INC_STEP
9150 || additioanl_bytes
== 2 * ZCMP_SP_INC_STEP
9151 || additioanl_bytes
== ZCMP_MAX_SPIMM
* ZCMP_SP_INC_STEP
;
9154 /* Return true if it's valid gpr_save pattern. */
9157 riscv_gpr_save_operation_p (rtx op
)
9159 unsigned len
= XVECLEN (op
, 0);
9161 if (len
> ARRAY_SIZE (gpr_save_reg_order
))
9164 for (unsigned i
= 0; i
< len
; i
++)
9166 rtx elt
= XVECEXP (op
, 0, i
);
9169 /* First element in parallel is unspec. */
9170 if (GET_CODE (elt
) != UNSPEC_VOLATILE
9171 || GET_CODE (XVECEXP (elt
, 0, 0)) != CONST_INT
9172 || XINT (elt
, 1) != UNSPECV_GPR_SAVE
)
9177 /* Two CLOBBER and USEs, must check the order. */
9178 unsigned expect_code
= i
< 3 ? CLOBBER
: USE
;
9179 if (GET_CODE (elt
) != expect_code
9180 || !REG_P (XEXP (elt
, 1))
9181 || (REGNO (XEXP (elt
, 1)) != gpr_save_reg_order
[i
]))
9189 /* Implement TARGET_ASAN_SHADOW_OFFSET. */
9191 static unsigned HOST_WIDE_INT
9192 riscv_asan_shadow_offset (void)
9194 /* We only have libsanitizer support for RV64 at present.
9196 This number must match ASAN_SHADOW_OFFSET_CONST in the file
9197 libsanitizer/asan/asan_mapping.h. */
9198 return TARGET_64BIT
? HOST_WIDE_INT_UC (0xd55550000) : 0;
9201 /* Implement TARGET_MANGLE_TYPE. */
9204 riscv_mangle_type (const_tree type
)
9206 /* Half-precision float, _Float16 is "DF16_". */
9207 if (SCALAR_FLOAT_TYPE_P (type
) && TYPE_PRECISION (type
) == 16)
9210 /* Mangle all vector type for vector extension. */
9211 /* The mangle name follows the rule of RVV LLVM
9212 that is "u" + length of (abi_name) + abi_name. */
9213 if (TYPE_NAME (type
) != NULL
)
9215 const char *res
= riscv_vector::mangle_builtin_type (type
);
9220 /* Use the default mangling. */
9224 /* Implement TARGET_SCALAR_MODE_SUPPORTED_P. */
9227 riscv_scalar_mode_supported_p (scalar_mode mode
)
9232 return default_scalar_mode_supported_p (mode
);
9235 /* Implement TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P - return TRUE
9236 if MODE is HFmode, and punt to the generic implementation otherwise. */
9239 riscv_libgcc_floating_mode_supported_p (scalar_float_mode mode
)
9244 return default_libgcc_floating_mode_supported_p (mode
);
9247 /* Set the value of FLT_EVAL_METHOD.
9248 ISO/IEC TS 18661-3 defines two values that we'd like to make use of:
9250 0: evaluate all operations and constants, whose semantic type has at
9251 most the range and precision of type float, to the range and
9252 precision of float; evaluate all other operations and constants to
9253 the range and precision of the semantic type;
9255 N, where _FloatN is a supported interchange floating type
9256 evaluate all operations and constants, whose semantic type has at
9257 most the range and precision of _FloatN type, to the range and
9258 precision of the _FloatN type; evaluate all other operations and
9259 constants to the range and precision of the semantic type;
9261 If we have the zfh/zhinx/zvfh extensions then we support _Float16
9262 in native precision, so we should set this to 16. */
9263 static enum flt_eval_method
9264 riscv_excess_precision (enum excess_precision_type type
)
9268 case EXCESS_PRECISION_TYPE_FAST
:
9269 case EXCESS_PRECISION_TYPE_STANDARD
:
9270 return ((TARGET_ZFH
|| TARGET_ZHINX
|| TARGET_ZVFH
)
9271 ? FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16
9272 : FLT_EVAL_METHOD_PROMOTE_TO_FLOAT
);
9273 case EXCESS_PRECISION_TYPE_IMPLICIT
:
9274 case EXCESS_PRECISION_TYPE_FLOAT16
:
9275 return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16
;
9279 return FLT_EVAL_METHOD_UNPREDICTABLE
;
9282 /* Implement TARGET_FLOATN_MODE. */
9283 static opt_scalar_float_mode
9284 riscv_floatn_mode (int n
, bool extended
)
9286 if (!extended
&& n
== 16)
9289 return default_floatn_mode (n
, extended
);
9293 riscv_init_libfuncs (void)
9295 /* Half-precision float operations. The compiler handles all operations
9296 with NULL libfuncs by converting to SFmode. */
9299 set_optab_libfunc (add_optab
, HFmode
, NULL
);
9300 set_optab_libfunc (sdiv_optab
, HFmode
, NULL
);
9301 set_optab_libfunc (smul_optab
, HFmode
, NULL
);
9302 set_optab_libfunc (neg_optab
, HFmode
, NULL
);
9303 set_optab_libfunc (sub_optab
, HFmode
, NULL
);
9306 set_optab_libfunc (eq_optab
, HFmode
, NULL
);
9307 set_optab_libfunc (ne_optab
, HFmode
, NULL
);
9308 set_optab_libfunc (lt_optab
, HFmode
, NULL
);
9309 set_optab_libfunc (le_optab
, HFmode
, NULL
);
9310 set_optab_libfunc (ge_optab
, HFmode
, NULL
);
9311 set_optab_libfunc (gt_optab
, HFmode
, NULL
);
9312 set_optab_libfunc (unord_optab
, HFmode
, NULL
);
9319 riscv_option_override ();
9320 init_adjust_machine_modes ();
9321 init_derived_machine_modes ();
9328 #undef TARGET_RUN_TARGET_SELFTESTS
9329 #define TARGET_RUN_TARGET_SELFTESTS selftest::riscv_run_selftests
9330 #endif /* #if CHECKING_P */
9332 /* Implement TARGET_VECTOR_MODE_SUPPORTED_P. */
9335 riscv_vector_mode_supported_p (machine_mode mode
)
9338 return riscv_v_ext_mode_p (mode
);
9343 /* Implement TARGET_VERIFY_TYPE_CONTEXT. */
9346 riscv_verify_type_context (location_t loc
, type_context_kind context
,
9347 const_tree type
, bool silent_p
)
9349 return riscv_vector::verify_type_context (loc
, context
, type
, silent_p
);
9352 /* Implement TARGET_VECTOR_ALIGNMENT. */
9354 static HOST_WIDE_INT
9355 riscv_vector_alignment (const_tree type
)
9357 /* ??? Checking the mode isn't ideal, but VECTOR_BOOLEAN_TYPE_P can
9358 be set for non-predicate vectors of booleans. Modes are the most
9359 direct way we have of identifying real RVV predicate types. */
9360 /* FIXME: RVV didn't mention the alignment of bool, we uses
9362 if (GET_MODE_CLASS (TYPE_MODE (type
)) == MODE_VECTOR_BOOL
)
9366 = constant_lower_bound (wi::to_poly_widest (TYPE_SIZE (type
)));
9367 return wi::umin (min_size
, 128).to_uhwi ();
9370 /* Implement REGMODE_NATURAL_SIZE. */
9373 riscv_regmode_natural_size (machine_mode mode
)
9375 /* The natural size for RVV data modes is one RVV data vector,
9376 and similarly for predicates. We can't independently modify
9377 anything smaller than that. */
9378 /* ??? For now, only do this for variable-width RVV registers.
9379 Doing it for constant-sized registers breaks lower-subreg.c. */
9381 if (riscv_v_ext_mode_p (mode
))
9383 if (riscv_v_ext_tuple_mode_p (mode
))
9386 = GET_MODE_SIZE (riscv_vector::get_subpart_mode (mode
));
9387 if (known_lt (size
, BYTES_PER_RISCV_VECTOR
))
9390 else if (riscv_v_ext_vector_mode_p (mode
))
9392 /* RVV mask modes always consume a single register. */
9393 if (GET_MODE_CLASS (mode
) == MODE_VECTOR_BOOL
)
9394 return BYTES_PER_RISCV_VECTOR
;
9396 if (!GET_MODE_SIZE (mode
).is_constant ())
9397 return BYTES_PER_RISCV_VECTOR
;
9399 return UNITS_PER_WORD
;
9402 /* Implement the TARGET_DWARF_POLY_INDETERMINATE_VALUE hook. */
9405 riscv_dwarf_poly_indeterminate_value (unsigned int i
, unsigned int *factor
,
9408 /* Polynomial invariant 1 == (VLENB / riscv_bytes_per_vector_chunk) - 1.
9409 1. TARGET_MIN_VLEN == 32, polynomial invariant 1 == (VLENB / 4) - 1.
9410 2. TARGET_MIN_VLEN > 32, polynomial invariant 1 == (VLENB / 8) - 1.
9412 gcc_assert (i
== 1);
9413 *factor
= riscv_bytes_per_vector_chunk
;
9415 return RISCV_DWARF_VLENB
;
9418 /* Implement TARGET_ESTIMATED_POLY_VALUE.
9419 Look into the tuning structure for an estimate.
9420 KIND specifies the type of requested estimate: min, max or likely.
9421 For cores with a known RVV width all three estimates are the same.
9422 For generic RVV tuning we want to distinguish the maximum estimate from
9423 the minimum and likely ones.
9424 The likely estimate is the same as the minimum in that case to give a
9425 conservative behavior of auto-vectorizing with RVV when it is a win
9426 even for 128-bit RVV.
9427 When RVV width information is available VAL.coeffs[1] is multiplied by
9428 the number of VQ chunks over the initial Advanced SIMD 128 bits. */
9430 static HOST_WIDE_INT
9431 riscv_estimated_poly_value (poly_int64 val
,
9432 poly_value_estimate_kind kind
= POLY_VALUE_LIKELY
)
9434 unsigned int width_source
= BITS_PER_RISCV_VECTOR
.is_constant ()
9435 ? (unsigned int) BITS_PER_RISCV_VECTOR
.to_constant ()
9436 : (unsigned int) RVV_SCALABLE
;
9438 /* If there is no core-specific information then the minimum and likely
9439 values are based on 128-bit vectors and the maximum is based on
9440 the architectural maximum of 65536 bits. */
9441 if (width_source
== RVV_SCALABLE
)
9444 case POLY_VALUE_MIN
:
9445 case POLY_VALUE_LIKELY
:
9446 return val
.coeffs
[0];
9448 case POLY_VALUE_MAX
:
9449 return val
.coeffs
[0] + val
.coeffs
[1] * 15;
9452 /* Allow BITS_PER_RISCV_VECTOR to be a bitmask of different VL, treating the
9453 lowest as likely. This could be made more general if future -mtune
9454 options need it to be. */
9455 if (kind
== POLY_VALUE_MAX
)
9456 width_source
= 1 << floor_log2 (width_source
);
9458 width_source
= least_bit_hwi (width_source
);
9460 /* If the core provides width information, use that. */
9461 HOST_WIDE_INT over_128
= width_source
- 128;
9462 return val
.coeffs
[0] + val
.coeffs
[1] * over_128
/ 128;
9465 /* Return true if the vector misalignment factor is supported by the
9468 riscv_support_vector_misalignment (machine_mode mode
,
9469 const_tree type ATTRIBUTE_UNUSED
,
9471 bool is_packed ATTRIBUTE_UNUSED
)
9473 /* Depend on movmisalign pattern. */
9474 return default_builtin_support_vector_misalignment (mode
, type
, misalignment
,
9478 /* Implement TARGET_VECTORIZE_GET_MASK_MODE. */
9480 static opt_machine_mode
9481 riscv_get_mask_mode (machine_mode mode
)
9483 if (TARGET_VECTOR
&& riscv_v_ext_mode_p (mode
))
9484 return riscv_vector::get_mask_mode (mode
);
9486 return default_get_mask_mode (mode
);
9489 /* Implement TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE. Assume for now that
9490 it isn't worth branching around empty masked ops (including masked
9494 riscv_empty_mask_is_expensive (unsigned)
9499 /* Return true if a shift-amount matches the trailing cleared bits on
9503 riscv_shamt_matches_mask_p (int shamt
, HOST_WIDE_INT mask
)
9505 return shamt
== ctz_hwi (mask
);
9509 vector_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs
)
9511 HARD_REG_SET zeroed_hardregs
;
9512 CLEAR_HARD_REG_SET (zeroed_hardregs
);
9514 /* Find a register to hold vl. */
9515 unsigned vl_regno
= INVALID_REGNUM
;
9516 /* Skip the first GPR, otherwise the existing vl is kept due to the same
9517 between vl and avl. */
9518 for (unsigned regno
= GP_REG_FIRST
+ 1; regno
<= GP_REG_LAST
; regno
++)
9520 if (TEST_HARD_REG_BIT (need_zeroed_hardregs
, regno
))
9527 if (vl_regno
> GP_REG_LAST
)
9528 sorry ("cannot allocate vl register for %qs on this target",
9529 "-fzero-call-used-regs");
9531 /* Vector configurations need not be saved and restored here. The
9532 -fzero-call-used-regs=* option will zero all vector registers and
9533 return. So there's no vector operations between them. */
9535 bool emitted_vlmax_vsetvl
= false;
9536 rtx vl
= gen_rtx_REG (Pmode
, vl_regno
); /* vl is VLMAX. */
9537 for (unsigned regno
= V_REG_FIRST
; regno
<= V_REG_LAST
; ++regno
)
9539 if (TEST_HARD_REG_BIT (need_zeroed_hardregs
, regno
))
9541 rtx target
= regno_reg_rtx
[regno
];
9542 machine_mode mode
= GET_MODE (target
);
9544 if (!emitted_vlmax_vsetvl
)
9546 riscv_vector::emit_hard_vlmax_vsetvl (mode
, vl
);
9547 emitted_vlmax_vsetvl
= true;
9550 rtx ops
[] = {target
, CONST0_RTX (mode
)};
9551 riscv_vector::emit_vlmax_insn_lra (code_for_pred_mov (mode
),
9552 riscv_vector::UNARY_OP
, ops
, vl
);
9554 SET_HARD_REG_BIT (zeroed_hardregs
, regno
);
9558 return zeroed_hardregs
;
9561 /* Generate a sequence of instructions that zero registers specified by
9562 NEED_ZEROED_HARDREGS. Return the ZEROED_HARDREGS that are actually
9565 riscv_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs
)
9567 HARD_REG_SET zeroed_hardregs
;
9568 CLEAR_HARD_REG_SET (zeroed_hardregs
);
9571 zeroed_hardregs
|= vector_zero_call_used_regs (need_zeroed_hardregs
);
9573 return zeroed_hardregs
| default_zero_call_used_regs (need_zeroed_hardregs
9574 & ~zeroed_hardregs
);
9577 /* Implement target hook TARGET_ARRAY_MODE. */
9579 static opt_machine_mode
9580 riscv_array_mode (machine_mode mode
, unsigned HOST_WIDE_INT nelems
)
9584 && riscv_vector::get_tuple_mode (mode
, nelems
).exists (&vmode
))
9587 return opt_machine_mode ();
9590 /* Given memory reference MEM, expand code to compute the aligned
9591 memory address, shift and mask values and store them into
9592 *ALIGNED_MEM, *SHIFT, *MASK and *NOT_MASK. */
9595 riscv_subword_address (rtx mem
, rtx
*aligned_mem
, rtx
*shift
, rtx
*mask
,
9598 /* Align the memory address to a word. */
9599 rtx addr
= force_reg (Pmode
, XEXP (mem
, 0));
9601 rtx addr_mask
= gen_int_mode (-4, Pmode
);
9603 rtx aligned_addr
= gen_reg_rtx (Pmode
);
9604 emit_move_insn (aligned_addr
, gen_rtx_AND (Pmode
, addr
, addr_mask
));
9606 *aligned_mem
= change_address (mem
, SImode
, aligned_addr
);
9608 /* Calculate the shift amount. */
9609 emit_move_insn (*shift
, gen_rtx_AND (SImode
, gen_lowpart (SImode
, addr
),
9610 gen_int_mode (3, SImode
)));
9611 emit_move_insn (*shift
, gen_rtx_ASHIFT (SImode
, *shift
,
9612 gen_int_mode (3, SImode
)));
9614 /* Calculate the mask. */
9615 int unshifted_mask
= GET_MODE_MASK (GET_MODE (mem
));
9617 emit_move_insn (*mask
, gen_int_mode (unshifted_mask
, SImode
));
9619 emit_move_insn (*mask
, gen_rtx_ASHIFT (SImode
, *mask
,
9620 gen_lowpart (QImode
, *shift
)));
9622 emit_move_insn (*not_mask
, gen_rtx_NOT (SImode
, *mask
));
9625 /* Leftshift a subword within an SImode register. */
9628 riscv_lshift_subword (machine_mode mode
, rtx value
, rtx shift
,
9631 rtx value_reg
= gen_reg_rtx (SImode
);
9632 emit_move_insn (value_reg
, simplify_gen_subreg (SImode
, value
,
9635 emit_move_insn (*shifted_value
, gen_rtx_ASHIFT (SImode
, value_reg
,
9636 gen_lowpart (QImode
, shift
)));
9639 /* Return TRUE if we should use the divmod expander, FALSE otherwise. This
9640 allows the behavior to be tuned for specific implementations as well as
9641 when optimizing for size. */
9644 riscv_use_divmod_expander (void)
9646 return tune_param
->use_divmod_expansion
;
9649 /* Implement TARGET_VECTORIZE_PREFERRED_SIMD_MODE. */
9652 riscv_preferred_simd_mode (scalar_mode mode
)
9655 return riscv_vector::preferred_simd_mode (mode
);
9660 /* Implement target hook TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT. */
9663 riscv_vectorize_preferred_vector_alignment (const_tree type
)
9665 if (riscv_v_ext_mode_p (TYPE_MODE (type
)))
9666 return TYPE_ALIGN (TREE_TYPE (type
));
9667 return TYPE_ALIGN (type
);
9670 /* Return true if it is static FRM rounding mode. */
9673 riscv_static_frm_mode_p (int mode
)
9677 case riscv_vector::FRM_RDN
:
9678 case riscv_vector::FRM_RUP
:
9679 case riscv_vector::FRM_RTZ
:
9680 case riscv_vector::FRM_RMM
:
9681 case riscv_vector::FRM_RNE
:
9690 /* Implement the floating-point Mode Switching. */
9693 riscv_emit_frm_mode_set (int mode
, int prev_mode
)
9695 rtx backup_reg
= DYNAMIC_FRM_RTL (cfun
);
9697 if (prev_mode
== riscv_vector::FRM_DYN_CALL
)
9698 emit_insn (gen_frrmsi (backup_reg
)); /* Backup frm when DYN_CALL. */
9700 if (mode
!= prev_mode
)
9702 rtx frm
= gen_int_mode (mode
, SImode
);
9704 if (mode
== riscv_vector::FRM_DYN_CALL
9705 && prev_mode
!= riscv_vector::FRM_DYN
&& STATIC_FRM_P (cfun
))
9706 /* No need to emit when prev mode is DYN already. */
9707 emit_insn (gen_fsrmsi_restore_volatile (backup_reg
));
9708 else if (mode
== riscv_vector::FRM_DYN_EXIT
&& STATIC_FRM_P (cfun
)
9709 && prev_mode
!= riscv_vector::FRM_DYN
9710 && prev_mode
!= riscv_vector::FRM_DYN_CALL
)
9711 /* No need to emit when prev mode is DYN or DYN_CALL already. */
9712 emit_insn (gen_fsrmsi_restore_volatile (backup_reg
));
9713 else if (mode
== riscv_vector::FRM_DYN
9714 && prev_mode
!= riscv_vector::FRM_DYN_CALL
)
9715 /* Restore frm value from backup when switch to DYN mode. */
9716 emit_insn (gen_fsrmsi_restore (backup_reg
));
9717 else if (riscv_static_frm_mode_p (mode
))
9718 /* Set frm value when switch to static mode. */
9719 emit_insn (gen_fsrmsi_restore (frm
));
9723 /* Implement Mode switching. */
9726 riscv_emit_mode_set (int entity
, int mode
, int prev_mode
,
9727 HARD_REG_SET regs_live ATTRIBUTE_UNUSED
)
9732 if (mode
!= VXRM_MODE_NONE
&& mode
!= prev_mode
)
9733 emit_insn (gen_vxrmsi (gen_int_mode (mode
, SImode
)));
9736 riscv_emit_frm_mode_set (mode
, prev_mode
);
9743 /* Adjust the FRM_NONE insn after a call to FRM_DYN for the
9747 riscv_frm_adjust_mode_after_call (rtx_insn
*cur_insn
, int mode
)
9749 rtx_insn
*insn
= prev_nonnote_nondebug_insn_bb (cur_insn
);
9751 if (insn
&& CALL_P (insn
))
9752 return riscv_vector::FRM_DYN
;
9757 /* Insert the backup frm insn to the end of the bb if and only if the call
9758 is the last insn of this bb. */
9761 riscv_frm_emit_after_bb_end (rtx_insn
*cur_insn
)
9764 bool abnormal_edge_p
= false;
9765 edge_iterator eg_iterator
;
9766 basic_block bb
= BLOCK_FOR_INSN (cur_insn
);
9768 FOR_EACH_EDGE (eg
, eg_iterator
, bb
->succs
)
9770 if (eg
->flags
& EDGE_ABNORMAL
)
9771 abnormal_edge_p
= true;
9775 emit_insn (gen_frrmsi (DYNAMIC_FRM_RTL (cfun
)));
9776 rtx_insn
*backup_insn
= get_insns ();
9779 insert_insn_on_edge (backup_insn
, eg
);
9783 if (abnormal_edge_p
)
9786 emit_insn (gen_frrmsi (DYNAMIC_FRM_RTL (cfun
)));
9787 rtx_insn
*backup_insn
= get_insns ();
9790 insert_insn_end_basic_block (backup_insn
, bb
);
9793 commit_edge_insertions ();
9796 /* Return mode that frm must be switched into
9797 prior to the execution of insn. */
9800 riscv_frm_mode_needed (rtx_insn
*cur_insn
, int code
)
9802 if (!DYNAMIC_FRM_RTL(cfun
))
9804 /* The dynamic frm will be initialized only onece during cfun. */
9805 DYNAMIC_FRM_RTL (cfun
) = gen_reg_rtx (SImode
);
9806 emit_insn_at_entry (gen_frrmsi (DYNAMIC_FRM_RTL (cfun
)));
9809 if (CALL_P (cur_insn
))
9811 rtx_insn
*insn
= next_nonnote_nondebug_insn_bb (cur_insn
);
9814 riscv_frm_emit_after_bb_end (cur_insn
);
9816 return riscv_vector::FRM_DYN_CALL
;
9819 int mode
= code
>= 0 ? get_attr_frm_mode (cur_insn
) : riscv_vector::FRM_NONE
;
9821 if (mode
== riscv_vector::FRM_NONE
)
9822 /* After meet a call, we need to backup the frm because it may be
9823 updated during the call. Here, for each insn, we will check if
9824 the previous insn is a call or not. When previous insn is call,
9825 there will be 2 cases for the emit mode set.
9827 1. Current insn is not MODE_NONE, then the mode switch framework
9828 will do the mode switch from MODE_CALL to MODE_NONE natively.
9829 2. Current insn is MODE_NONE, we need to adjust the MODE_NONE to
9830 the MODE_DYN, and leave the mode switch itself to perform
9833 mode
= riscv_frm_adjust_mode_after_call (cur_insn
, mode
);
9838 /* Return mode that entity must be switched into
9839 prior to the execution of insn. */
9842 riscv_mode_needed (int entity
, rtx_insn
*insn
, HARD_REG_SET
)
9844 int code
= recog_memoized (insn
);
9849 return code
>= 0 ? get_attr_vxrm_mode (insn
) : VXRM_MODE_NONE
;
9851 return riscv_frm_mode_needed (insn
, code
);
9857 /* Return TRUE that an insn is asm. */
9860 asm_insn_p (rtx_insn
*insn
)
9862 extract_insn (insn
);
9864 return recog_data
.is_asm
;
9867 /* Return TRUE that an insn is unknown for VXRM. */
9870 vxrm_unknown_p (rtx_insn
*insn
)
9872 /* Return true if there is a definition of VXRM. */
9873 if (reg_set_p (gen_rtx_REG (SImode
, VXRM_REGNUM
), insn
))
9876 /* A CALL function may contain an instruction that modifies the VXRM,
9877 return true in this situation. */
9881 /* Return true for all assembly since users may hardcode a assembly
9882 like this: asm volatile ("csrwi vxrm, 0"). */
9883 if (asm_insn_p (insn
))
9889 /* Return TRUE that an insn is unknown dynamic for FRM. */
9892 frm_unknown_dynamic_p (rtx_insn
*insn
)
9894 /* Return true if there is a definition of FRM. */
9895 if (reg_set_p (gen_rtx_REG (SImode
, FRM_REGNUM
), insn
))
9901 /* Return the mode that an insn results in for VXRM. */
9904 riscv_vxrm_mode_after (rtx_insn
*insn
, int mode
)
9906 if (vxrm_unknown_p (insn
))
9907 return VXRM_MODE_NONE
;
9909 if (recog_memoized (insn
) < 0)
9912 if (reg_mentioned_p (gen_rtx_REG (SImode
, VXRM_REGNUM
), PATTERN (insn
)))
9913 return get_attr_vxrm_mode (insn
);
9918 /* Return the mode that an insn results in for FRM. */
9921 riscv_frm_mode_after (rtx_insn
*insn
, int mode
)
9923 STATIC_FRM_P (cfun
) = STATIC_FRM_P (cfun
) || riscv_static_frm_mode_p (mode
);
9928 if (frm_unknown_dynamic_p (insn
))
9929 return riscv_vector::FRM_DYN
;
9931 if (recog_memoized (insn
) < 0)
9934 if (reg_mentioned_p (gen_rtx_REG (SImode
, FRM_REGNUM
), PATTERN (insn
)))
9935 return get_attr_frm_mode (insn
);
9940 /* Return the mode that an insn results in. */
9943 riscv_mode_after (int entity
, int mode
, rtx_insn
*insn
, HARD_REG_SET
)
9948 return riscv_vxrm_mode_after (insn
, mode
);
9950 return riscv_frm_mode_after (insn
, mode
);
9956 /* Return a mode that ENTITY is assumed to be
9957 switched to at function entry. */
9960 riscv_mode_entry (int entity
)
9965 return VXRM_MODE_NONE
;
9968 /* According to RVV 1.0 spec, all vector floating-point operations use
9969 the dynamic rounding mode in the frm register. Likewise in other
9971 return riscv_vector::FRM_DYN
;
9978 /* Return a mode that ENTITY is assumed to be
9979 switched to at function exit. */
9982 riscv_mode_exit (int entity
)
9987 return VXRM_MODE_NONE
;
9989 return riscv_vector::FRM_DYN_EXIT
;
9996 riscv_mode_priority (int, int n
)
10001 /* Implement TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES. */
10003 riscv_autovectorize_vector_modes (vector_modes
*modes
, bool all
)
10006 return riscv_vector::autovectorize_vector_modes (modes
, all
);
10008 return default_autovectorize_vector_modes (modes
, all
);
10011 /* Implement TARGET_VECTORIZE_RELATED_MODE. */
10013 riscv_vectorize_related_mode (machine_mode vector_mode
, scalar_mode element_mode
,
10014 poly_uint64 nunits
)
10017 return riscv_vector::vectorize_related_mode (vector_mode
, element_mode
,
10019 return default_vectorize_related_mode (vector_mode
, element_mode
, nunits
);
10022 /* Implement TARGET_VECTORIZE_VEC_PERM_CONST. */
10025 riscv_vectorize_vec_perm_const (machine_mode vmode
, machine_mode op_mode
,
10026 rtx target
, rtx op0
, rtx op1
,
10027 const vec_perm_indices
&sel
)
10029 if (TARGET_VECTOR
&& riscv_v_ext_mode_p (vmode
))
10030 return riscv_vector::expand_vec_perm_const (vmode
, op_mode
, target
, op0
,
10037 riscv_frame_pointer_required (void)
10039 return riscv_save_frame_pointer
&& !crtl
->is_leaf
;
10042 /* Implement targetm.vectorize.create_costs. */
10044 static vector_costs
*
10045 riscv_vectorize_create_costs (vec_info
*vinfo
, bool costing_for_scalar
)
10048 return new riscv_vector::costs (vinfo
, costing_for_scalar
);
10049 /* Default vector costs. */
10050 return new vector_costs (vinfo
, costing_for_scalar
);
10053 /* Implement TARGET_PREFERRED_ELSE_VALUE. */
10056 riscv_preferred_else_value (unsigned ifn
, tree vectype
, unsigned int nops
,
10059 if (riscv_v_ext_mode_p (TYPE_MODE (vectype
)))
10060 return get_or_create_ssa_default_def (cfun
, create_tmp_var (vectype
));
10062 return default_preferred_else_value (ifn
, vectype
, nops
, ops
);
10065 /* If MEM is in the form of "base+offset", extract the two parts
10066 of address and set to BASE and OFFSET, otherwise return false
10067 after clearing BASE and OFFSET. */
10070 extract_base_offset_in_addr (rtx mem
, rtx
*base
, rtx
*offset
)
10074 gcc_assert (MEM_P (mem
));
10076 addr
= XEXP (mem
, 0);
10081 *offset
= const0_rtx
;
10085 if (GET_CODE (addr
) == PLUS
10086 && REG_P (XEXP (addr
, 0)) && CONST_INT_P (XEXP (addr
, 1)))
10088 *base
= XEXP (addr
, 0);
10089 *offset
= XEXP (addr
, 1);
10094 *offset
= NULL_RTX
;
10099 /* Initialize the GCC target structure. */
10100 #undef TARGET_ASM_ALIGNED_HI_OP
10101 #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
10102 #undef TARGET_ASM_ALIGNED_SI_OP
10103 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
10104 #undef TARGET_ASM_ALIGNED_DI_OP
10105 #define TARGET_ASM_ALIGNED_DI_OP "\t.dword\t"
10107 #undef TARGET_OPTION_OVERRIDE
10108 #define TARGET_OPTION_OVERRIDE riscv_option_override
10110 #undef TARGET_OPTION_RESTORE
10111 #define TARGET_OPTION_RESTORE riscv_option_restore
10113 #undef TARGET_OPTION_VALID_ATTRIBUTE_P
10114 #define TARGET_OPTION_VALID_ATTRIBUTE_P riscv_option_valid_attribute_p
10116 #undef TARGET_LEGITIMIZE_ADDRESS
10117 #define TARGET_LEGITIMIZE_ADDRESS riscv_legitimize_address
10119 #undef TARGET_SCHED_ISSUE_RATE
10120 #define TARGET_SCHED_ISSUE_RATE riscv_issue_rate
10121 #undef TARGET_SCHED_MACRO_FUSION_P
10122 #define TARGET_SCHED_MACRO_FUSION_P riscv_macro_fusion_p
10123 #undef TARGET_SCHED_MACRO_FUSION_PAIR_P
10124 #define TARGET_SCHED_MACRO_FUSION_PAIR_P riscv_macro_fusion_pair_p
10126 #undef TARGET_SCHED_VARIABLE_ISSUE
10127 #define TARGET_SCHED_VARIABLE_ISSUE riscv_sched_variable_issue
10129 #undef TARGET_SCHED_ADJUST_COST
10130 #define TARGET_SCHED_ADJUST_COST riscv_sched_adjust_cost
10132 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
10133 #define TARGET_FUNCTION_OK_FOR_SIBCALL riscv_function_ok_for_sibcall
10135 #undef TARGET_SET_CURRENT_FUNCTION
10136 #define TARGET_SET_CURRENT_FUNCTION riscv_set_current_function
10138 #undef TARGET_REGISTER_MOVE_COST
10139 #define TARGET_REGISTER_MOVE_COST riscv_register_move_cost
10140 #undef TARGET_MEMORY_MOVE_COST
10141 #define TARGET_MEMORY_MOVE_COST riscv_memory_move_cost
10142 #undef TARGET_RTX_COSTS
10143 #define TARGET_RTX_COSTS riscv_rtx_costs
10144 #undef TARGET_ADDRESS_COST
10145 #define TARGET_ADDRESS_COST riscv_address_cost
10147 #undef TARGET_ASM_FILE_START
10148 #define TARGET_ASM_FILE_START riscv_file_start
10149 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
10150 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
10151 #undef TARGET_ASM_FILE_END
10152 #define TARGET_ASM_FILE_END file_end_indicate_exec_stack
10154 #undef TARGET_EXPAND_BUILTIN_VA_START
10155 #define TARGET_EXPAND_BUILTIN_VA_START riscv_va_start
10157 #undef TARGET_PROMOTE_FUNCTION_MODE
10158 #define TARGET_PROMOTE_FUNCTION_MODE riscv_promote_function_mode
10160 #undef TARGET_RETURN_IN_MEMORY
10161 #define TARGET_RETURN_IN_MEMORY riscv_return_in_memory
10163 #undef TARGET_ASM_OUTPUT_MI_THUNK
10164 #define TARGET_ASM_OUTPUT_MI_THUNK riscv_output_mi_thunk
10165 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
10166 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
10168 #undef TARGET_PRINT_OPERAND
10169 #define TARGET_PRINT_OPERAND riscv_print_operand
10170 #undef TARGET_PRINT_OPERAND_ADDRESS
10171 #define TARGET_PRINT_OPERAND_ADDRESS riscv_print_operand_address
10172 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
10173 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P riscv_print_operand_punct_valid_p
10175 #undef TARGET_SETUP_INCOMING_VARARGS
10176 #define TARGET_SETUP_INCOMING_VARARGS riscv_setup_incoming_varargs
10177 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
10178 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS riscv_allocate_stack_slots_for_args
10179 #undef TARGET_STRICT_ARGUMENT_NAMING
10180 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
10181 #undef TARGET_MUST_PASS_IN_STACK
10182 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
10183 #undef TARGET_PASS_BY_REFERENCE
10184 #define TARGET_PASS_BY_REFERENCE riscv_pass_by_reference
10185 #undef TARGET_ARG_PARTIAL_BYTES
10186 #define TARGET_ARG_PARTIAL_BYTES riscv_arg_partial_bytes
10187 #undef TARGET_FUNCTION_ARG
10188 #define TARGET_FUNCTION_ARG riscv_function_arg
10189 #undef TARGET_FUNCTION_ARG_ADVANCE
10190 #define TARGET_FUNCTION_ARG_ADVANCE riscv_function_arg_advance
10191 #undef TARGET_FUNCTION_ARG_BOUNDARY
10192 #define TARGET_FUNCTION_ARG_BOUNDARY riscv_function_arg_boundary
10193 #undef TARGET_FNTYPE_ABI
10194 #define TARGET_FNTYPE_ABI riscv_fntype_abi
10195 #undef TARGET_INSN_CALLEE_ABI
10196 #define TARGET_INSN_CALLEE_ABI riscv_insn_callee_abi
10198 #undef TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS
10199 #define TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS \
10200 riscv_get_separate_components
10202 #undef TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB
10203 #define TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB \
10204 riscv_components_for_bb
10206 #undef TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS
10207 #define TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS \
10208 riscv_disqualify_components
10210 #undef TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS
10211 #define TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS \
10212 riscv_emit_prologue_components
10214 #undef TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS
10215 #define TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS \
10216 riscv_emit_epilogue_components
10218 #undef TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS
10219 #define TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS \
10220 riscv_set_handled_components
10222 /* The generic ELF target does not always have TLS support. */
10224 #undef TARGET_HAVE_TLS
10225 #define TARGET_HAVE_TLS true
10228 #undef TARGET_CANNOT_FORCE_CONST_MEM
10229 #define TARGET_CANNOT_FORCE_CONST_MEM riscv_cannot_force_const_mem
10231 #undef TARGET_LEGITIMATE_CONSTANT_P
10232 #define TARGET_LEGITIMATE_CONSTANT_P riscv_legitimate_constant_p
10234 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
10235 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P hook_bool_mode_const_rtx_true
10237 #undef TARGET_LEGITIMATE_ADDRESS_P
10238 #define TARGET_LEGITIMATE_ADDRESS_P riscv_legitimate_address_p
10240 #undef TARGET_CAN_ELIMINATE
10241 #define TARGET_CAN_ELIMINATE riscv_can_eliminate
10243 #undef TARGET_CONDITIONAL_REGISTER_USAGE
10244 #define TARGET_CONDITIONAL_REGISTER_USAGE riscv_conditional_register_usage
10246 #undef TARGET_CLASS_MAX_NREGS
10247 #define TARGET_CLASS_MAX_NREGS riscv_class_max_nregs
10249 #undef TARGET_TRAMPOLINE_INIT
10250 #define TARGET_TRAMPOLINE_INIT riscv_trampoline_init
10252 #undef TARGET_IN_SMALL_DATA_P
10253 #define TARGET_IN_SMALL_DATA_P riscv_in_small_data_p
10255 #undef TARGET_HAVE_SRODATA_SECTION
10256 #define TARGET_HAVE_SRODATA_SECTION true
10258 #undef TARGET_ASM_SELECT_SECTION
10259 #define TARGET_ASM_SELECT_SECTION riscv_select_section
10261 #undef TARGET_ASM_UNIQUE_SECTION
10262 #define TARGET_ASM_UNIQUE_SECTION riscv_unique_section
10264 #undef TARGET_ASM_SELECT_RTX_SECTION
10265 #define TARGET_ASM_SELECT_RTX_SECTION riscv_elf_select_rtx_section
10267 #undef TARGET_MIN_ANCHOR_OFFSET
10268 #define TARGET_MIN_ANCHOR_OFFSET (-IMM_REACH/2)
10270 #undef TARGET_MAX_ANCHOR_OFFSET
10271 #define TARGET_MAX_ANCHOR_OFFSET (IMM_REACH/2-1)
10273 #undef TARGET_REGISTER_PRIORITY
10274 #define TARGET_REGISTER_PRIORITY riscv_register_priority
10276 #undef TARGET_CANNOT_COPY_INSN_P
10277 #define TARGET_CANNOT_COPY_INSN_P riscv_cannot_copy_insn_p
10279 #undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
10280 #define TARGET_ATOMIC_ASSIGN_EXPAND_FENV riscv_atomic_assign_expand_fenv
10282 #undef TARGET_INIT_BUILTINS
10283 #define TARGET_INIT_BUILTINS riscv_init_builtins
10285 #undef TARGET_BUILTIN_DECL
10286 #define TARGET_BUILTIN_DECL riscv_builtin_decl
10288 #undef TARGET_GIMPLE_FOLD_BUILTIN
10289 #define TARGET_GIMPLE_FOLD_BUILTIN riscv_gimple_fold_builtin
10291 #undef TARGET_EXPAND_BUILTIN
10292 #define TARGET_EXPAND_BUILTIN riscv_expand_builtin
10294 #undef TARGET_HARD_REGNO_NREGS
10295 #define TARGET_HARD_REGNO_NREGS riscv_hard_regno_nregs
10296 #undef TARGET_HARD_REGNO_MODE_OK
10297 #define TARGET_HARD_REGNO_MODE_OK riscv_hard_regno_mode_ok
10299 #undef TARGET_MODES_TIEABLE_P
10300 #define TARGET_MODES_TIEABLE_P riscv_modes_tieable_p
10302 #undef TARGET_SLOW_UNALIGNED_ACCESS
10303 #define TARGET_SLOW_UNALIGNED_ACCESS riscv_slow_unaligned_access
10305 #undef TARGET_SECONDARY_MEMORY_NEEDED
10306 #define TARGET_SECONDARY_MEMORY_NEEDED riscv_secondary_memory_needed
10308 #undef TARGET_CAN_CHANGE_MODE_CLASS
10309 #define TARGET_CAN_CHANGE_MODE_CLASS riscv_can_change_mode_class
10311 #undef TARGET_CONSTANT_ALIGNMENT
10312 #define TARGET_CONSTANT_ALIGNMENT riscv_constant_alignment
10314 #undef TARGET_MERGE_DECL_ATTRIBUTES
10315 #define TARGET_MERGE_DECL_ATTRIBUTES riscv_merge_decl_attributes
10317 #undef TARGET_ATTRIBUTE_TABLE
10318 #define TARGET_ATTRIBUTE_TABLE riscv_attribute_table
10320 #undef TARGET_WARN_FUNC_RETURN
10321 #define TARGET_WARN_FUNC_RETURN riscv_warn_func_return
10323 /* The low bit is ignored by jump instructions so is safe to use. */
10324 #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
10325 #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 1
10327 #undef TARGET_MACHINE_DEPENDENT_REORG
10328 #define TARGET_MACHINE_DEPENDENT_REORG riscv_reorg
10330 #undef TARGET_NEW_ADDRESS_PROFITABLE_P
10331 #define TARGET_NEW_ADDRESS_PROFITABLE_P riscv_new_address_profitable_p
10333 #undef TARGET_MANGLE_TYPE
10334 #define TARGET_MANGLE_TYPE riscv_mangle_type
10336 #undef TARGET_SCALAR_MODE_SUPPORTED_P
10337 #define TARGET_SCALAR_MODE_SUPPORTED_P riscv_scalar_mode_supported_p
10339 #undef TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P
10340 #define TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P \
10341 riscv_libgcc_floating_mode_supported_p
10343 #undef TARGET_INIT_LIBFUNCS
10344 #define TARGET_INIT_LIBFUNCS riscv_init_libfuncs
10346 #undef TARGET_C_EXCESS_PRECISION
10347 #define TARGET_C_EXCESS_PRECISION riscv_excess_precision
10349 #undef TARGET_FLOATN_MODE
10350 #define TARGET_FLOATN_MODE riscv_floatn_mode
10352 #undef TARGET_ASAN_SHADOW_OFFSET
10353 #define TARGET_ASAN_SHADOW_OFFSET riscv_asan_shadow_offset
10355 #ifdef TARGET_BIG_ENDIAN_DEFAULT
10356 #undef TARGET_DEFAULT_TARGET_FLAGS
10357 #define TARGET_DEFAULT_TARGET_FLAGS (MASK_BIG_ENDIAN)
10360 #undef TARGET_VECTOR_MODE_SUPPORTED_P
10361 #define TARGET_VECTOR_MODE_SUPPORTED_P riscv_vector_mode_supported_p
10363 #undef TARGET_VERIFY_TYPE_CONTEXT
10364 #define TARGET_VERIFY_TYPE_CONTEXT riscv_verify_type_context
10366 #undef TARGET_ESTIMATED_POLY_VALUE
10367 #define TARGET_ESTIMATED_POLY_VALUE riscv_estimated_poly_value
10369 #undef TARGET_VECTORIZE_GET_MASK_MODE
10370 #define TARGET_VECTORIZE_GET_MASK_MODE riscv_get_mask_mode
10372 #undef TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE
10373 #define TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE riscv_empty_mask_is_expensive
10375 #undef TARGET_VECTOR_ALIGNMENT
10376 #define TARGET_VECTOR_ALIGNMENT riscv_vector_alignment
10378 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
10379 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT riscv_support_vector_misalignment
10381 #undef TARGET_DWARF_POLY_INDETERMINATE_VALUE
10382 #define TARGET_DWARF_POLY_INDETERMINATE_VALUE riscv_dwarf_poly_indeterminate_value
10384 #undef TARGET_ZERO_CALL_USED_REGS
10385 #define TARGET_ZERO_CALL_USED_REGS riscv_zero_call_used_regs
10387 #undef TARGET_ARRAY_MODE
10388 #define TARGET_ARRAY_MODE riscv_array_mode
10390 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
10391 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE riscv_preferred_simd_mode
10393 #undef TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT
10394 #define TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT \
10395 riscv_vectorize_preferred_vector_alignment
10397 /* Mode switching hooks. */
10399 #undef TARGET_MODE_EMIT
10400 #define TARGET_MODE_EMIT riscv_emit_mode_set
10401 #undef TARGET_MODE_NEEDED
10402 #define TARGET_MODE_NEEDED riscv_mode_needed
10403 #undef TARGET_MODE_AFTER
10404 #define TARGET_MODE_AFTER riscv_mode_after
10405 #undef TARGET_MODE_ENTRY
10406 #define TARGET_MODE_ENTRY riscv_mode_entry
10407 #undef TARGET_MODE_EXIT
10408 #define TARGET_MODE_EXIT riscv_mode_exit
10409 #undef TARGET_MODE_PRIORITY
10410 #define TARGET_MODE_PRIORITY riscv_mode_priority
10412 #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES
10413 #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES \
10414 riscv_autovectorize_vector_modes
10416 #undef TARGET_VECTORIZE_RELATED_MODE
10417 #define TARGET_VECTORIZE_RELATED_MODE riscv_vectorize_related_mode
10419 #undef TARGET_VECTORIZE_VEC_PERM_CONST
10420 #define TARGET_VECTORIZE_VEC_PERM_CONST riscv_vectorize_vec_perm_const
10422 #undef TARGET_FRAME_POINTER_REQUIRED
10423 #define TARGET_FRAME_POINTER_REQUIRED riscv_frame_pointer_required
10425 #undef TARGET_VECTORIZE_CREATE_COSTS
10426 #define TARGET_VECTORIZE_CREATE_COSTS riscv_vectorize_create_costs
10428 #undef TARGET_PREFERRED_ELSE_VALUE
10429 #define TARGET_PREFERRED_ELSE_VALUE riscv_preferred_else_value
10431 struct gcc_target targetm
= TARGET_INITIALIZER
;
10433 #include "gt-riscv.h"