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