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