Add hppa*-*-hpux* to targets which do not support split DWARF
[official-gcc.git] / gcc / config / riscv / riscv.cc
blob41626fa34e4c317f323666fa2a7e375d1b87a35e
1 /* Subroutines used for code generation for RISC-V.
2 Copyright (C) 2011-2024 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 "ifcvt.h"
47 #include "memmodel.h"
48 #include "emit-rtl.h"
49 #include "reload.h"
50 #include "tm_p.h"
51 #include "basic-block.h"
52 #include "expr.h"
53 #include "optabs.h"
54 #include "bitmap.h"
55 #include "df.h"
56 #include "function-abi.h"
57 #include "diagnostic.h"
58 #include "builtins.h"
59 #include "predict.h"
60 #include "tree-pass.h"
61 #include "opts.h"
62 #include "tm-constrs.h"
63 #include "rtl-iter.h"
64 #include "gimple.h"
65 #include "cfghooks.h"
66 #include "cfgloop.h"
67 #include "cfgrtl.h"
68 #include "shrink-wrap.h"
69 #include "sel-sched.h"
70 #include "sched-int.h"
71 #include "fold-const.h"
72 #include "gimple-iterator.h"
73 #include "gimple-expr.h"
74 #include "tree-vectorizer.h"
75 #include "gcse.h"
76 #include "tree-dfa.h"
77 #include "target-globals.h"
79 /* This file should be included last. */
80 #include "target-def.h"
81 #include "riscv-vector-costs.h"
82 #include "riscv-subset.h"
84 /* True if X is an UNSPEC wrapper around a SYMBOL_REF or LABEL_REF. */
85 #define UNSPEC_ADDRESS_P(X) \
86 (GET_CODE (X) == UNSPEC \
87 && XINT (X, 1) >= UNSPEC_ADDRESS_FIRST \
88 && XINT (X, 1) < UNSPEC_ADDRESS_FIRST + NUM_SYMBOL_TYPES)
90 /* Extract the symbol or label from UNSPEC wrapper X. */
91 #define UNSPEC_ADDRESS(X) \
92 XVECEXP (X, 0, 0)
94 /* Extract the symbol type from UNSPEC wrapper X. */
95 #define UNSPEC_ADDRESS_TYPE(X) \
96 ((enum riscv_symbol_type) (XINT (X, 1) - UNSPEC_ADDRESS_FIRST))
98 /* Extract the backup dynamic frm rtl. */
99 #define DYNAMIC_FRM_RTL(c) ((c)->machine->mode_sw_info.dynamic_frm)
101 /* True the mode switching has static frm, or false. */
102 #define STATIC_FRM_P(c) ((c)->machine->mode_sw_info.static_frm_p)
104 /* True if we can use the instructions in the XTheadInt extension
105 to handle interrupts, or false. */
106 #define TH_INT_INTERRUPT(c) \
107 (TARGET_XTHEADINT \
108 /* The XTheadInt extension only supports rv32. */ \
109 && !TARGET_64BIT \
110 && (c)->machine->interrupt_handler_p \
111 /* The XTheadInt instructions can only be executed in M-mode. */ \
112 && (c)->machine->interrupt_mode == MACHINE_MODE)
114 /* Information about a function's frame layout. */
115 struct GTY(()) riscv_frame_info {
116 /* The size of the frame in bytes. */
117 poly_int64 total_size;
119 /* Bit X is set if the function saves or restores GPR X. */
120 unsigned int mask;
122 /* Likewise FPR X. */
123 unsigned int fmask;
125 /* Likewise for vector registers. */
126 unsigned int vmask;
128 /* How much the GPR save/restore routines adjust sp (or 0 if unused). */
129 unsigned save_libcall_adjustment;
131 /* the minimum number of bytes, in multiples of 16-byte address increments,
132 required to cover the registers in a multi push & pop. */
133 unsigned multi_push_adj_base;
135 /* the number of additional 16-byte address increments allocated for the stack
136 frame in a multi push & pop. */
137 unsigned multi_push_adj_addi;
139 /* Offsets of fixed-point and floating-point save areas from frame bottom */
140 poly_int64 gp_sp_offset;
141 poly_int64 fp_sp_offset;
143 /* Top and bottom offsets of vector save areas from frame bottom. */
144 poly_int64 v_sp_offset_top;
145 poly_int64 v_sp_offset_bottom;
147 /* Offset of virtual frame pointer from stack pointer/frame bottom */
148 poly_int64 frame_pointer_offset;
150 /* Offset of hard frame pointer from stack pointer/frame bottom */
151 poly_int64 hard_frame_pointer_offset;
153 /* The offset of arg_pointer_rtx from the bottom of the frame. */
154 poly_int64 arg_pointer_offset;
156 /* Reset this struct, clean all field to zero. */
157 void reset(void);
160 enum riscv_privilege_levels {
161 UNKNOWN_MODE, USER_MODE, SUPERVISOR_MODE, MACHINE_MODE
164 struct GTY(()) mode_switching_info {
165 /* The RTL variable which stores the dynamic FRM value. We always use this
166 RTX to restore dynamic FRM rounding mode in mode switching. */
167 rtx dynamic_frm;
169 /* The boolean variables indicates there is at least one static rounding
170 mode instruction in the function or not. */
171 bool static_frm_p;
173 mode_switching_info ()
175 dynamic_frm = NULL_RTX;
176 static_frm_p = false;
180 struct GTY(()) machine_function {
181 /* The number of extra stack bytes taken up by register varargs.
182 This area is allocated by the callee at the very top of the frame. */
183 int varargs_size;
185 /* True if current function is a naked function. */
186 bool naked_p;
188 /* True if current function is an interrupt function. */
189 bool interrupt_handler_p;
190 /* For an interrupt handler, indicates the privilege level. */
191 enum riscv_privilege_levels interrupt_mode;
193 /* True if attributes on current function have been checked. */
194 bool attributes_checked_p;
196 /* True if RA must be saved because of a far jump. */
197 bool far_jump_used;
199 /* The current frame information, calculated by riscv_compute_frame_info. */
200 struct riscv_frame_info frame;
202 /* The components already handled by separate shrink-wrapping, which should
203 not be considered by the prologue and epilogue. */
204 bool reg_is_wrapped_separately[FIRST_PSEUDO_REGISTER];
206 /* The mode swithching information for the FRM rounding modes. */
207 struct mode_switching_info mode_sw_info;
210 /* Information about a single argument. */
211 struct riscv_arg_info {
212 /* True if the argument is at least partially passed on the stack. */
213 bool stack_p;
215 /* The number of integer registers allocated to this argument. */
216 unsigned int num_gprs;
218 /* The offset of the first register used, provided num_gprs is nonzero.
219 If passed entirely on the stack, the value is MAX_ARGS_IN_REGISTERS. */
220 unsigned int gpr_offset;
222 /* The number of floating-point registers allocated to this argument. */
223 unsigned int num_fprs;
225 /* The offset of the first register used, provided num_fprs is nonzero. */
226 unsigned int fpr_offset;
228 /* The number of vector registers allocated to this argument. */
229 unsigned int num_vrs;
231 /* The offset of the first register used, provided num_vrs is nonzero. */
232 unsigned int vr_offset;
234 /* The number of mask registers allocated to this argument. */
235 unsigned int num_mrs;
237 /* The offset of the first register used, provided num_mrs is nonzero. */
238 unsigned int mr_offset;
241 /* One stage in a constant building sequence. These sequences have
242 the form:
244 A = VALUE[0]
245 A = A CODE[1] VALUE[1]
246 A = A CODE[2] VALUE[2]
249 where A is an accumulator, each CODE[i] is a binary rtl operation
250 and each VALUE[i] is a constant integer. CODE[0] is undefined. */
251 struct riscv_integer_op {
252 enum rtx_code code;
253 unsigned HOST_WIDE_INT value;
256 /* The largest number of operations needed to load an integer constant.
257 The worst case is LUI, ADDI, SLLI, ADDI, SLLI, ADDI, SLLI, ADDI. */
258 #define RISCV_MAX_INTEGER_OPS 8
260 enum riscv_fusion_pairs
262 RISCV_FUSE_NOTHING = 0,
263 RISCV_FUSE_ZEXTW = (1 << 0),
264 RISCV_FUSE_ZEXTH = (1 << 1),
265 RISCV_FUSE_ZEXTWS = (1 << 2),
266 RISCV_FUSE_LDINDEXED = (1 << 3),
267 RISCV_FUSE_LUI_ADDI = (1 << 4),
268 RISCV_FUSE_AUIPC_ADDI = (1 << 5),
269 RISCV_FUSE_LUI_LD = (1 << 6),
270 RISCV_FUSE_AUIPC_LD = (1 << 7),
271 RISCV_FUSE_LDPREINCREMENT = (1 << 8),
272 RISCV_FUSE_ALIGNED_STD = (1 << 9),
275 /* Costs of various operations on the different architectures. */
277 struct riscv_tune_param
279 unsigned short fp_add[2];
280 unsigned short fp_mul[2];
281 unsigned short fp_div[2];
282 unsigned short int_mul[2];
283 unsigned short int_div[2];
284 unsigned short issue_rate;
285 unsigned short branch_cost;
286 unsigned short memory_cost;
287 unsigned short fmv_cost;
288 bool slow_unaligned_access;
289 bool use_divmod_expansion;
290 unsigned int fusible_ops;
291 const struct cpu_vector_cost *vec_costs;
295 /* Global variables for machine-dependent things. */
297 /* Whether unaligned accesses execute very slowly. */
298 bool riscv_slow_unaligned_access_p;
300 /* Whether user explicitly passed -mstrict-align. */
301 bool riscv_user_wants_strict_align;
303 /* Stack alignment to assume/maintain. */
304 unsigned riscv_stack_boundary;
306 /* Whether in riscv_output_mi_thunk. */
307 static bool riscv_in_thunk_func = false;
309 /* If non-zero, this is an offset to be added to SP to redefine the CFA
310 when restoring the FP register from the stack. Only valid when generating
311 the epilogue. */
312 static poly_int64 epilogue_cfa_sp_offset;
314 /* Which tuning parameters to use. */
315 static const struct riscv_tune_param *tune_param;
317 /* Which automaton to use for tuning. */
318 enum riscv_microarchitecture_type riscv_microarchitecture;
320 /* The number of chunks in a single vector register. */
321 poly_uint16 riscv_vector_chunks;
323 /* The number of bytes in a vector chunk. */
324 unsigned riscv_bytes_per_vector_chunk;
326 /* Index R is the smallest register class that contains register R. */
327 const enum reg_class riscv_regno_to_class[FIRST_PSEUDO_REGISTER] = {
328 GR_REGS, GR_REGS, GR_REGS, GR_REGS,
329 GR_REGS, GR_REGS, SIBCALL_REGS, SIBCALL_REGS,
330 JALR_REGS, JALR_REGS, SIBCALL_REGS, SIBCALL_REGS,
331 SIBCALL_REGS, SIBCALL_REGS, SIBCALL_REGS, SIBCALL_REGS,
332 SIBCALL_REGS, SIBCALL_REGS, JALR_REGS, JALR_REGS,
333 JALR_REGS, JALR_REGS, JALR_REGS, JALR_REGS,
334 JALR_REGS, JALR_REGS, JALR_REGS, JALR_REGS,
335 SIBCALL_REGS, SIBCALL_REGS, SIBCALL_REGS, SIBCALL_REGS,
336 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
337 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
338 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
339 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
340 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
341 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
342 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
343 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
344 FRAME_REGS, FRAME_REGS, NO_REGS, NO_REGS,
345 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
346 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
347 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
348 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
349 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
350 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
351 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
352 VM_REGS, VD_REGS, VD_REGS, VD_REGS,
353 VD_REGS, VD_REGS, VD_REGS, VD_REGS,
354 VD_REGS, VD_REGS, VD_REGS, VD_REGS,
355 VD_REGS, VD_REGS, VD_REGS, VD_REGS,
356 VD_REGS, VD_REGS, VD_REGS, VD_REGS,
357 VD_REGS, VD_REGS, VD_REGS, VD_REGS,
358 VD_REGS, VD_REGS, VD_REGS, VD_REGS,
359 VD_REGS, VD_REGS, VD_REGS, VD_REGS,
362 /* RVV costs for VLS vector operations. */
363 static const common_vector_cost rvv_vls_vector_cost = {
364 1, /* int_stmt_cost */
365 1, /* fp_stmt_cost */
366 1, /* gather_load_cost */
367 1, /* scatter_store_cost */
368 1, /* vec_to_scalar_cost */
369 1, /* scalar_to_vec_cost */
370 1, /* permute_cost */
371 1, /* align_load_cost */
372 1, /* align_store_cost */
373 2, /* unalign_load_cost */
374 2, /* unalign_store_cost */
377 /* RVV costs for VLA vector operations. */
378 static const scalable_vector_cost rvv_vla_vector_cost = {
380 1, /* int_stmt_cost */
381 1, /* fp_stmt_cost */
382 1, /* gather_load_cost */
383 1, /* scatter_store_cost */
384 1, /* vec_to_scalar_cost */
385 1, /* scalar_to_vec_cost */
386 1, /* permute_cost */
387 1, /* align_load_cost */
388 1, /* align_store_cost */
389 2, /* unalign_load_cost */
390 2, /* unalign_store_cost */
394 /* RVV register move cost. */
395 static const regmove_vector_cost rvv_regmove_vector_cost = {
396 2, /* GR2VR */
397 2, /* FR2VR */
398 2, /* VR2GR */
399 2, /* VR2FR */
402 /* Generic costs for vector insn classes. It is supposed to be the vector cost
403 models used by default if no other cost model was specified. */
404 static const struct cpu_vector_cost generic_vector_cost = {
405 1, /* scalar_int_stmt_cost */
406 1, /* scalar_fp_stmt_cost */
407 1, /* scalar_load_cost */
408 1, /* scalar_store_cost */
409 3, /* cond_taken_branch_cost */
410 1, /* cond_not_taken_branch_cost */
411 &rvv_vls_vector_cost, /* vls */
412 &rvv_vla_vector_cost, /* vla */
413 &rvv_regmove_vector_cost, /* regmove */
416 /* Costs to use when optimizing for rocket. */
417 static const struct riscv_tune_param rocket_tune_info = {
418 {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_add */
419 {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_mul */
420 {COSTS_N_INSNS (20), COSTS_N_INSNS (20)}, /* fp_div */
421 {COSTS_N_INSNS (4), COSTS_N_INSNS (4)}, /* int_mul */
422 {COSTS_N_INSNS (33), COSTS_N_INSNS (65)}, /* int_div */
423 1, /* issue_rate */
424 3, /* branch_cost */
425 5, /* memory_cost */
426 8, /* fmv_cost */
427 true, /* slow_unaligned_access */
428 false, /* use_divmod_expansion */
429 RISCV_FUSE_NOTHING, /* fusible_ops */
430 NULL, /* vector cost */
433 /* Costs to use when optimizing for Sifive 7 Series. */
434 static const struct riscv_tune_param sifive_7_tune_info = {
435 {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_add */
436 {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_mul */
437 {COSTS_N_INSNS (20), COSTS_N_INSNS (20)}, /* fp_div */
438 {COSTS_N_INSNS (4), COSTS_N_INSNS (4)}, /* int_mul */
439 {COSTS_N_INSNS (33), COSTS_N_INSNS (65)}, /* int_div */
440 2, /* issue_rate */
441 4, /* branch_cost */
442 3, /* memory_cost */
443 8, /* fmv_cost */
444 true, /* slow_unaligned_access */
445 false, /* use_divmod_expansion */
446 RISCV_FUSE_NOTHING, /* fusible_ops */
447 NULL, /* vector cost */
450 /* Costs to use when optimizing for T-HEAD c906. */
451 static const struct riscv_tune_param thead_c906_tune_info = {
452 {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_add */
453 {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_mul */
454 {COSTS_N_INSNS (20), COSTS_N_INSNS (20)}, /* fp_div */
455 {COSTS_N_INSNS (4), COSTS_N_INSNS (4)}, /* int_mul */
456 {COSTS_N_INSNS (18), COSTS_N_INSNS (34)}, /* int_div */
457 1, /* issue_rate */
458 3, /* branch_cost */
459 5, /* memory_cost */
460 8, /* fmv_cost */
461 false, /* slow_unaligned_access */
462 false, /* use_divmod_expansion */
463 RISCV_FUSE_NOTHING, /* fusible_ops */
464 NULL, /* vector cost */
467 /* Costs to use when optimizing for a generic ooo profile. */
468 static const struct riscv_tune_param generic_ooo_tune_info = {
469 {COSTS_N_INSNS (2), COSTS_N_INSNS (2)}, /* fp_add */
470 {COSTS_N_INSNS (5), COSTS_N_INSNS (6)}, /* fp_mul */
471 {COSTS_N_INSNS (7), COSTS_N_INSNS (8)}, /* fp_div */
472 {COSTS_N_INSNS (2), COSTS_N_INSNS (2)}, /* int_mul */
473 {COSTS_N_INSNS (6), COSTS_N_INSNS (6)}, /* int_div */
474 1, /* issue_rate */
475 3, /* branch_cost */
476 4, /* memory_cost */
477 4, /* fmv_cost */
478 false, /* slow_unaligned_access */
479 false, /* use_divmod_expansion */
480 RISCV_FUSE_NOTHING, /* fusible_ops */
481 &generic_vector_cost, /* vector cost */
484 /* Costs to use when optimizing for size. */
485 static const struct riscv_tune_param optimize_size_tune_info = {
486 {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* fp_add */
487 {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* fp_mul */
488 {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* fp_div */
489 {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* int_mul */
490 {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* int_div */
491 1, /* issue_rate */
492 1, /* branch_cost */
493 2, /* memory_cost */
494 8, /* fmv_cost */
495 false, /* slow_unaligned_access */
496 false, /* use_divmod_expansion */
497 RISCV_FUSE_NOTHING, /* fusible_ops */
498 NULL, /* vector cost */
501 static bool riscv_avoid_shrink_wrapping_separate ();
502 static tree riscv_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
503 static tree riscv_handle_type_attribute (tree *, tree, tree, int, bool *);
505 /* Defining target-specific uses of __attribute__. */
506 TARGET_GNU_ATTRIBUTES (riscv_attribute_table,
508 /* Syntax: { name, min_len, max_len, decl_required, type_required,
509 function_type_required, affects_type_identity, handler,
510 exclude } */
512 /* The attribute telling no prologue/epilogue. */
513 { "naked", 0, 0, true, false, false, false,
514 riscv_handle_fndecl_attribute, NULL },
515 /* This attribute generates prologue/epilogue for interrupt handlers. */
516 { "interrupt", 0, 1, false, true, true, false,
517 riscv_handle_type_attribute, NULL },
519 /* The following two are used for the built-in properties of the Vector type
520 and are not used externally */
521 {"RVV sizeless type", 4, 4, false, true, false, true, NULL, NULL},
522 {"RVV type", 0, 0, false, true, false, true, NULL, NULL}
525 /* Order for the CLOBBERs/USEs of gpr_save. */
526 static const unsigned gpr_save_reg_order[] = {
527 INVALID_REGNUM, T0_REGNUM, T1_REGNUM, RETURN_ADDR_REGNUM,
528 S0_REGNUM, S1_REGNUM, S2_REGNUM, S3_REGNUM, S4_REGNUM,
529 S5_REGNUM, S6_REGNUM, S7_REGNUM, S8_REGNUM, S9_REGNUM,
530 S10_REGNUM, S11_REGNUM
533 /* A table describing all the processors GCC knows about. */
534 static const struct riscv_tune_info riscv_tune_info_table[] = {
535 #define RISCV_TUNE(TUNE_NAME, PIPELINE_MODEL, TUNE_INFO) \
536 { TUNE_NAME, PIPELINE_MODEL, & TUNE_INFO},
537 #include "riscv-cores.def"
540 /* Global variable to distinguish whether we should save and restore s0/fp for
541 function. */
542 static bool riscv_save_frame_pointer;
544 typedef enum
546 PUSH_IDX = 0,
547 POP_IDX,
548 POPRET_IDX,
549 POPRETZ_IDX,
550 ZCMP_OP_NUM
551 } riscv_zcmp_op_t;
553 typedef insn_code (*code_for_push_pop_t) (machine_mode);
555 void riscv_frame_info::reset(void)
557 total_size = 0;
558 mask = 0;
559 fmask = 0;
560 vmask = 0;
561 save_libcall_adjustment = 0;
563 gp_sp_offset = 0;
564 fp_sp_offset = 0;
565 v_sp_offset_top = 0;
566 v_sp_offset_bottom = 0;
568 frame_pointer_offset = 0;
570 hard_frame_pointer_offset = 0;
572 arg_pointer_offset = 0;
575 /* Implement TARGET_MIN_ARITHMETIC_PRECISION. */
577 static unsigned int
578 riscv_min_arithmetic_precision (void)
580 return 32;
583 template <class T>
584 static const char *
585 get_tune_str (const T *opts)
587 const char *tune_string = RISCV_TUNE_STRING_DEFAULT;
588 if (opts->x_riscv_tune_string)
589 tune_string = opts->x_riscv_tune_string;
590 else if (opts->x_riscv_cpu_string)
591 tune_string = opts->x_riscv_cpu_string;
592 return tune_string;
595 /* Return the riscv_tune_info entry for the given name string, return nullptr
596 if NULL_P is true, otherwise return an placeholder and report error. */
598 const struct riscv_tune_info *
599 riscv_parse_tune (const char *tune_string, bool null_p)
601 const riscv_cpu_info *cpu = riscv_find_cpu (tune_string);
603 if (cpu)
604 tune_string = cpu->tune;
606 for (unsigned i = 0; i < ARRAY_SIZE (riscv_tune_info_table); i++)
607 if (strcmp (riscv_tune_info_table[i].name, tune_string) == 0)
608 return riscv_tune_info_table + i;
610 if (null_p)
611 return nullptr;
613 error ("unknown cpu %qs for %<-mtune%>", tune_string);
614 return riscv_tune_info_table;
617 /* Helper function for riscv_build_integer; arguments are as for
618 riscv_build_integer. */
620 static int
621 riscv_build_integer_1 (struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS],
622 HOST_WIDE_INT value, machine_mode mode)
624 HOST_WIDE_INT low_part = CONST_LOW_PART (value);
625 int cost = RISCV_MAX_INTEGER_OPS + 1, alt_cost;
626 struct riscv_integer_op alt_codes[RISCV_MAX_INTEGER_OPS];
628 if (SMALL_OPERAND (value) || LUI_OPERAND (value))
630 /* Simply ADDI or LUI. */
631 codes[0].code = UNKNOWN;
632 codes[0].value = value;
633 return 1;
635 if (TARGET_ZBS && SINGLE_BIT_MASK_OPERAND (value))
637 /* Simply BSETI. */
638 codes[0].code = UNKNOWN;
639 codes[0].value = value;
641 /* RISC-V sign-extends all 32bit values that live in a 32bit
642 register. To avoid paradoxes, we thus need to use the
643 sign-extended (negative) representation (-1 << 31) for the
644 value, if we want to build (1 << 31) in SImode. This will
645 then expand to an LUI instruction. */
646 if (TARGET_64BIT && mode == SImode && value == (HOST_WIDE_INT_1U << 31))
647 codes[0].value = (HOST_WIDE_INT_M1U << 31);
649 return 1;
652 /* End with ADDI. When constructing HImode constants, do not generate any
653 intermediate value that is not itself a valid HImode constant. The
654 XORI case below will handle those remaining HImode constants. */
655 if (low_part != 0
656 && (mode != HImode
657 || value - low_part <= ((1 << (GET_MODE_BITSIZE (HImode) - 1)) - 1)))
659 HOST_WIDE_INT upper_part = value - low_part;
660 if (mode != VOIDmode)
661 upper_part = trunc_int_for_mode (value - low_part, mode);
663 alt_cost = 1 + riscv_build_integer_1 (alt_codes, upper_part, mode);
664 if (alt_cost < cost)
666 alt_codes[alt_cost-1].code = PLUS;
667 alt_codes[alt_cost-1].value = low_part;
668 memcpy (codes, alt_codes, sizeof (alt_codes));
669 cost = alt_cost;
673 /* End with XORI. */
674 if (cost > 2 && (low_part < 0 || mode == HImode))
676 alt_cost = 1 + riscv_build_integer_1 (alt_codes, value ^ low_part, mode);
677 if (alt_cost < cost)
679 alt_codes[alt_cost-1].code = XOR;
680 alt_codes[alt_cost-1].value = low_part;
681 memcpy (codes, alt_codes, sizeof (alt_codes));
682 cost = alt_cost;
686 /* Eliminate trailing zeros and end with SLLI. */
687 if (cost > 2 && (value & 1) == 0)
689 int shift = ctz_hwi (value);
690 unsigned HOST_WIDE_INT x = value;
691 x = sext_hwi (x >> shift, HOST_BITS_PER_WIDE_INT - shift);
693 /* Don't eliminate the lower 12 bits if LUI might apply. */
694 if (shift > IMM_BITS && !SMALL_OPERAND (x) && LUI_OPERAND (x << IMM_BITS))
695 shift -= IMM_BITS, x <<= IMM_BITS;
697 alt_cost = 1 + riscv_build_integer_1 (alt_codes, x, mode);
698 if (alt_cost < cost)
700 alt_codes[alt_cost-1].code = ASHIFT;
701 alt_codes[alt_cost-1].value = shift;
702 memcpy (codes, alt_codes, sizeof (alt_codes));
703 cost = alt_cost;
707 if (cost > 2 && TARGET_64BIT && (TARGET_ZBB || TARGET_XTHEADBB))
709 int leading_ones = clz_hwi (~value);
710 int trailing_ones = ctz_hwi (~value);
712 /* If all bits are one except a few that are zero, and the zero bits
713 are within a range of 11 bits, then we can synthesize a constant
714 by loading a small negative constant and rotating. */
715 if (leading_ones < 64
716 && ((64 - leading_ones - trailing_ones) < 12))
718 codes[0].code = UNKNOWN;
719 /* The sign-bit might be zero, so just rotate to be safe. */
720 codes[0].value = (((unsigned HOST_WIDE_INT) value >> trailing_ones)
721 | (value << (64 - trailing_ones)));
722 codes[1].code = ROTATERT;
723 codes[1].value = 64 - trailing_ones;
724 cost = 2;
726 /* Handle the case where the 11 bit range of zero bits wraps around. */
727 else
729 int upper_trailing_ones = ctz_hwi (~value >> 32);
730 int lower_leading_ones = clz_hwi (~value << 32);
732 if (upper_trailing_ones < 32 && lower_leading_ones < 32
733 && ((64 - upper_trailing_ones - lower_leading_ones) < 12))
735 codes[0].code = UNKNOWN;
736 /* The sign-bit might be zero, so just rotate to be safe. */
737 codes[0].value = ((value << (32 - upper_trailing_ones))
738 | ((unsigned HOST_WIDE_INT) value
739 >> (32 + upper_trailing_ones)));
740 codes[1].code = ROTATERT;
741 codes[1].value = 32 - upper_trailing_ones;
742 cost = 2;
747 gcc_assert (cost <= RISCV_MAX_INTEGER_OPS);
748 return cost;
751 /* Fill CODES with a sequence of rtl operations to load VALUE.
752 Return the number of operations needed. */
754 static int
755 riscv_build_integer (struct riscv_integer_op *codes, HOST_WIDE_INT value,
756 machine_mode mode)
758 int cost = riscv_build_integer_1 (codes, value, mode);
760 /* Eliminate leading zeros and end with SRLI. */
761 if (value > 0 && cost > 2)
763 struct riscv_integer_op alt_codes[RISCV_MAX_INTEGER_OPS];
764 int alt_cost, shift = clz_hwi (value);
765 HOST_WIDE_INT shifted_val;
767 /* Try filling trailing bits with 1s. */
768 shifted_val = (value << shift) | ((((HOST_WIDE_INT) 1) << shift) - 1);
769 alt_cost = 1 + riscv_build_integer_1 (alt_codes, shifted_val, mode);
770 if (alt_cost < cost)
772 alt_codes[alt_cost-1].code = LSHIFTRT;
773 alt_codes[alt_cost-1].value = shift;
774 memcpy (codes, alt_codes, sizeof (alt_codes));
775 cost = alt_cost;
778 /* Try filling trailing bits with 0s. */
779 shifted_val = value << shift;
780 alt_cost = 1 + riscv_build_integer_1 (alt_codes, shifted_val, mode);
781 if (alt_cost < cost)
783 alt_codes[alt_cost-1].code = LSHIFTRT;
784 alt_codes[alt_cost-1].value = shift;
785 memcpy (codes, alt_codes, sizeof (alt_codes));
786 cost = alt_cost;
790 if (!TARGET_64BIT
791 && (value > INT32_MAX || value < INT32_MIN))
793 unsigned HOST_WIDE_INT loval = sext_hwi (value, 32);
794 unsigned HOST_WIDE_INT hival = sext_hwi ((value - loval) >> 32, 32);
795 struct riscv_integer_op alt_codes[RISCV_MAX_INTEGER_OPS];
796 struct riscv_integer_op hicode[RISCV_MAX_INTEGER_OPS];
797 int hi_cost, lo_cost;
799 hi_cost = riscv_build_integer_1 (hicode, hival, mode);
800 if (hi_cost < cost)
802 lo_cost = riscv_build_integer_1 (alt_codes, loval, mode);
803 if (lo_cost + hi_cost < cost)
805 memcpy (codes, alt_codes,
806 lo_cost * sizeof (struct riscv_integer_op));
807 memcpy (codes + lo_cost, hicode,
808 hi_cost * sizeof (struct riscv_integer_op));
809 cost = lo_cost + hi_cost;
814 return cost;
817 /* Return the cost of constructing VAL in the event that a scratch
818 register is available. */
820 static int
821 riscv_split_integer_cost (HOST_WIDE_INT val)
823 int cost;
824 unsigned HOST_WIDE_INT loval = sext_hwi (val, 32);
825 unsigned HOST_WIDE_INT hival = sext_hwi ((val - loval) >> 32, 32);
826 struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS];
828 cost = 2 + riscv_build_integer (codes, loval, VOIDmode);
829 if (loval != hival)
830 cost += riscv_build_integer (codes, hival, VOIDmode);
832 return cost;
835 /* Return the cost of constructing the integer constant VAL. */
837 static int
838 riscv_integer_cost (HOST_WIDE_INT val)
840 struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS];
841 return MIN (riscv_build_integer (codes, val, VOIDmode),
842 riscv_split_integer_cost (val));
845 /* Try to split a 64b integer into 32b parts, then reassemble. */
847 static rtx
848 riscv_split_integer (HOST_WIDE_INT val, machine_mode mode)
850 unsigned HOST_WIDE_INT loval = sext_hwi (val, 32);
851 unsigned HOST_WIDE_INT hival = sext_hwi ((val - loval) >> 32, 32);
852 rtx hi = gen_reg_rtx (mode), lo = gen_reg_rtx (mode);
854 riscv_move_integer (lo, lo, loval, mode);
856 if (loval == hival)
857 hi = gen_rtx_ASHIFT (mode, lo, GEN_INT (32));
858 else
860 riscv_move_integer (hi, hi, hival, mode);
861 hi = gen_rtx_ASHIFT (mode, hi, GEN_INT (32));
864 hi = force_reg (mode, hi);
865 return gen_rtx_PLUS (mode, hi, lo);
868 /* Return true if X is a thread-local symbol. */
870 static bool
871 riscv_tls_symbol_p (const_rtx x)
873 return SYMBOL_REF_P (x) && SYMBOL_REF_TLS_MODEL (x) != 0;
876 /* Return true if symbol X binds locally. */
878 static bool
879 riscv_symbol_binds_local_p (const_rtx x)
881 if (SYMBOL_REF_P (x))
882 return (SYMBOL_REF_DECL (x)
883 ? targetm.binds_local_p (SYMBOL_REF_DECL (x))
884 : SYMBOL_REF_LOCAL_P (x));
885 else
886 return false;
889 /* Return the method that should be used to access SYMBOL_REF or
890 LABEL_REF X. */
892 static enum riscv_symbol_type
893 riscv_classify_symbol (const_rtx x)
895 if (riscv_tls_symbol_p (x))
896 return SYMBOL_TLS;
898 if (GET_CODE (x) == SYMBOL_REF && flag_pic && !riscv_symbol_binds_local_p (x))
899 return SYMBOL_GOT_DISP;
901 switch (riscv_cmodel)
903 case CM_MEDLOW:
904 return SYMBOL_ABSOLUTE;
905 case CM_LARGE:
906 if (SYMBOL_REF_P (x))
907 return CONSTANT_POOL_ADDRESS_P (x) ? SYMBOL_PCREL : SYMBOL_FORCE_TO_MEM;
908 return SYMBOL_PCREL;
909 default:
910 return SYMBOL_PCREL;
914 /* Classify the base of symbolic expression X. */
916 enum riscv_symbol_type
917 riscv_classify_symbolic_expression (rtx x)
919 rtx offset;
921 split_const (x, &x, &offset);
922 if (UNSPEC_ADDRESS_P (x))
923 return UNSPEC_ADDRESS_TYPE (x);
925 return riscv_classify_symbol (x);
928 /* Return true if X is a symbolic constant. If it is, store the type of
929 the symbol in *SYMBOL_TYPE. */
931 bool
932 riscv_symbolic_constant_p (rtx x, enum riscv_symbol_type *symbol_type)
934 rtx offset;
936 split_const (x, &x, &offset);
937 if (UNSPEC_ADDRESS_P (x))
939 *symbol_type = UNSPEC_ADDRESS_TYPE (x);
940 x = UNSPEC_ADDRESS (x);
942 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF)
943 *symbol_type = riscv_classify_symbol (x);
944 else
945 return false;
947 if (offset == const0_rtx)
948 return true;
950 /* Nonzero offsets are only valid for references that don't use the GOT. */
951 switch (*symbol_type)
953 case SYMBOL_ABSOLUTE:
954 case SYMBOL_PCREL:
955 case SYMBOL_TLS_LE:
956 /* GAS rejects offsets outside the range [-2^31, 2^31-1]. */
957 return sext_hwi (INTVAL (offset), 32) == INTVAL (offset);
959 default:
960 return false;
964 /* Returns the number of instructions necessary to reference a symbol. */
966 static int riscv_symbol_insns (enum riscv_symbol_type type)
968 switch (type)
970 case SYMBOL_TLS: return 0; /* Depends on the TLS model. */
971 case SYMBOL_ABSOLUTE: return 2; /* LUI + the reference. */
972 case SYMBOL_PCREL: return 2; /* AUIPC + the reference. */
973 case SYMBOL_TLS_LE: return 3; /* LUI + ADD TP + the reference. */
974 case SYMBOL_GOT_DISP: return 3; /* AUIPC + LD GOT + the reference. */
975 case SYMBOL_FORCE_TO_MEM: return 3; /* AUIPC + LD + the reference. */
976 default: gcc_unreachable ();
980 /* Immediate values loaded by the FLI.S instruction in Chapter 25 of the latest RISC-V ISA
981 Manual draft. For details, please see:
982 https://github.com/riscv/riscv-isa-manual/releases/tag/isa-449cd0c */
984 static unsigned HOST_WIDE_INT fli_value_hf[32] =
986 0xbcp8, 0x4p8, 0x1p8, 0x2p8, 0x1cp8, 0x20p8, 0x2cp8, 0x30p8,
987 0x34p8, 0x35p8, 0x36p8, 0x37p8, 0x38p8, 0x39p8, 0x3ap8, 0x3bp8,
988 0x3cp8, 0x3dp8, 0x3ep8, 0x3fp8, 0x40p8, 0x41p8, 0x42p8, 0x44p8,
989 0x48p8, 0x4cp8, 0x58p8, 0x5cp8, 0x78p8,
990 /* Only used for filling, ensuring that 29 and 30 of HF are the same. */
991 0x78p8,
992 0x7cp8, 0x7ep8
995 static unsigned HOST_WIDE_INT fli_value_sf[32] =
997 0xbf8p20, 0x008p20, 0x378p20, 0x380p20, 0x3b8p20, 0x3c0p20, 0x3d8p20, 0x3e0p20,
998 0x3e8p20, 0x3eap20, 0x3ecp20, 0x3eep20, 0x3f0p20, 0x3f2p20, 0x3f4p20, 0x3f6p20,
999 0x3f8p20, 0x3fap20, 0x3fcp20, 0x3fep20, 0x400p20, 0x402p20, 0x404p20, 0x408p20,
1000 0x410p20, 0x418p20, 0x430p20, 0x438p20, 0x470p20, 0x478p20, 0x7f8p20, 0x7fcp20
1003 static unsigned HOST_WIDE_INT fli_value_df[32] =
1005 0xbff0p48, 0x10p48, 0x3ef0p48, 0x3f00p48,
1006 0x3f70p48, 0x3f80p48, 0x3fb0p48, 0x3fc0p48,
1007 0x3fd0p48, 0x3fd4p48, 0x3fd8p48, 0x3fdcp48,
1008 0x3fe0p48, 0x3fe4p48, 0x3fe8p48, 0x3fecp48,
1009 0x3ff0p48, 0x3ff4p48, 0x3ff8p48, 0x3ffcp48,
1010 0x4000p48, 0x4004p48, 0x4008p48, 0x4010p48,
1011 0x4020p48, 0x4030p48, 0x4060p48, 0x4070p48,
1012 0x40e0p48, 0x40f0p48, 0x7ff0p48, 0x7ff8p48
1015 /* Display floating-point values at the assembly level, which is consistent
1016 with the zfa extension of llvm:
1017 https://reviews.llvm.org/D145645. */
1019 const char *fli_value_print[32] =
1021 "-1.0", "min", "1.52587890625e-05", "3.0517578125e-05", "0.00390625", "0.0078125", "0.0625", "0.125",
1022 "0.25", "0.3125", "0.375", "0.4375", "0.5", "0.625", "0.75", "0.875",
1023 "1.0", "1.25", "1.5", "1.75", "2.0", "2.5", "3.0", "4.0",
1024 "8.0", "16.0", "128.0", "256.0", "32768.0", "65536.0", "inf", "nan"
1027 /* Return index of the FLI instruction table if rtx X is an immediate constant that can
1028 be moved using a single FLI instruction in zfa extension. Return -1 if not found. */
1031 riscv_float_const_rtx_index_for_fli (rtx x)
1033 unsigned HOST_WIDE_INT *fli_value_array;
1035 machine_mode mode = GET_MODE (x);
1037 if (!TARGET_ZFA
1038 || !CONST_DOUBLE_P(x)
1039 || mode == VOIDmode
1040 || (mode == HFmode && !(TARGET_ZFH || TARGET_ZVFH))
1041 || (mode == SFmode && !TARGET_HARD_FLOAT)
1042 || (mode == DFmode && !TARGET_DOUBLE_FLOAT))
1043 return -1;
1045 if (!SCALAR_FLOAT_MODE_P (mode)
1046 || GET_MODE_BITSIZE (mode).to_constant () > HOST_BITS_PER_WIDE_INT
1047 /* Only support up to DF mode. */
1048 || GET_MODE_BITSIZE (mode).to_constant () > GET_MODE_BITSIZE (DFmode))
1049 return -1;
1051 unsigned HOST_WIDE_INT ival = 0;
1053 long res[2];
1054 real_to_target (res,
1055 CONST_DOUBLE_REAL_VALUE (x),
1056 REAL_MODE_FORMAT (mode));
1058 if (mode == DFmode)
1060 int order = BYTES_BIG_ENDIAN ? 1 : 0;
1061 ival = zext_hwi (res[order], 32);
1062 ival |= (zext_hwi (res[1 - order], 32) << 32);
1064 /* When the lower 32 bits are not all 0, it is impossible to be in the table. */
1065 if (ival & (unsigned HOST_WIDE_INT)0xffffffff)
1066 return -1;
1068 else
1069 ival = zext_hwi (res[0], 32);
1071 switch (mode)
1073 case E_HFmode:
1074 fli_value_array = fli_value_hf;
1075 break;
1076 case E_SFmode:
1077 fli_value_array = fli_value_sf;
1078 break;
1079 case E_DFmode:
1080 fli_value_array = fli_value_df;
1081 break;
1082 default:
1083 return -1;
1086 if (fli_value_array[0] == ival)
1087 return 0;
1089 if (fli_value_array[1] == ival)
1090 return 1;
1092 /* Perform a binary search to find target index. */
1093 unsigned l, r, m;
1095 l = 2;
1096 r = 31;
1098 while (l <= r)
1100 m = (l + r) / 2;
1101 if (fli_value_array[m] == ival)
1102 return m;
1103 else if (fli_value_array[m] < ival)
1104 l = m+1;
1105 else
1106 r = m-1;
1109 return -1;
1112 /* Implement TARGET_LEGITIMATE_CONSTANT_P. */
1114 static bool
1115 riscv_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
1117 return riscv_const_insns (x) > 0;
1120 /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
1122 static bool
1123 riscv_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
1125 enum riscv_symbol_type type;
1126 rtx base, offset;
1128 /* There's no way to calculate VL-based values using relocations. */
1129 subrtx_iterator::array_type array;
1130 FOR_EACH_SUBRTX (iter, array, x, ALL)
1131 if (GET_CODE (*iter) == CONST_POLY_INT)
1132 return true;
1134 /* There is no assembler syntax for expressing an address-sized
1135 high part. */
1136 if (GET_CODE (x) == HIGH)
1137 return true;
1139 if (satisfies_constraint_zfli (x))
1140 return true;
1142 split_const (x, &base, &offset);
1143 if (riscv_symbolic_constant_p (base, &type))
1145 if (type == SYMBOL_FORCE_TO_MEM)
1146 return false;
1148 /* As an optimization, don't spill symbolic constants that are as
1149 cheap to rematerialize as to access in the constant pool. */
1150 if (SMALL_OPERAND (INTVAL (offset)) && riscv_symbol_insns (type) > 0)
1151 return true;
1153 /* As an optimization, avoid needlessly generate dynamic relocations. */
1154 if (flag_pic)
1155 return true;
1158 /* TLS symbols must be computed by riscv_legitimize_move. */
1159 if (tls_referenced_p (x))
1160 return true;
1162 return false;
1165 /* Return true if register REGNO is a valid base register for mode MODE.
1166 STRICT_P is true if REG_OK_STRICT is in effect. */
1169 riscv_regno_mode_ok_for_base_p (int regno,
1170 machine_mode mode ATTRIBUTE_UNUSED,
1171 bool strict_p)
1173 if (!HARD_REGISTER_NUM_P (regno))
1175 if (!strict_p)
1176 return true;
1177 regno = reg_renumber[regno];
1180 /* These fake registers will be eliminated to either the stack or
1181 hard frame pointer, both of which are usually valid base registers.
1182 Reload deals with the cases where the eliminated form isn't valid. */
1183 if (regno == ARG_POINTER_REGNUM || regno == FRAME_POINTER_REGNUM)
1184 return true;
1186 return GP_REG_P (regno);
1189 /* Get valid index register class.
1190 The RISC-V base instructions don't support index registers,
1191 but extensions might support that. */
1193 enum reg_class
1194 riscv_index_reg_class ()
1196 if (TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX)
1197 return GR_REGS;
1199 return NO_REGS;
1202 /* Return true if register REGNO is a valid index register.
1203 The RISC-V base instructions don't support index registers,
1204 but extensions might support that. */
1207 riscv_regno_ok_for_index_p (int regno)
1209 if (TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX)
1210 return riscv_regno_mode_ok_for_base_p (regno, VOIDmode, 1);
1212 return 0;
1215 /* Return true if X is a valid base register for mode MODE.
1216 STRICT_P is true if REG_OK_STRICT is in effect. */
1218 bool
1219 riscv_valid_base_register_p (rtx x, machine_mode mode, bool strict_p)
1221 if (!strict_p && GET_CODE (x) == SUBREG)
1222 x = SUBREG_REG (x);
1224 return (REG_P (x)
1225 && riscv_regno_mode_ok_for_base_p (REGNO (x), mode, strict_p));
1228 /* Return true if, for every base register BASE_REG, (plus BASE_REG X)
1229 can address a value of mode MODE. */
1231 static bool
1232 riscv_valid_offset_p (rtx x, machine_mode mode)
1234 /* Check that X is a signed 12-bit number. */
1235 if (!const_arith_operand (x, Pmode))
1236 return false;
1238 /* We may need to split multiword moves, so make sure that every word
1239 is accessible. */
1240 if (GET_MODE_SIZE (mode).to_constant () > UNITS_PER_WORD
1241 && !SMALL_OPERAND (INTVAL (x) + GET_MODE_SIZE (mode).to_constant () - UNITS_PER_WORD))
1242 return false;
1244 return true;
1247 /* Should a symbol of type SYMBOL_TYPE should be split in two? */
1249 bool
1250 riscv_split_symbol_type (enum riscv_symbol_type symbol_type)
1252 if (symbol_type == SYMBOL_TLS_LE)
1253 return true;
1255 if (!TARGET_EXPLICIT_RELOCS)
1256 return false;
1258 return symbol_type == SYMBOL_ABSOLUTE || symbol_type == SYMBOL_PCREL;
1261 /* Return true if a LO_SUM can address a value of mode MODE when the
1262 LO_SUM symbol has type SYM_TYPE. X is the LO_SUM second operand, which
1263 is used when the mode is BLKmode. */
1265 static bool
1266 riscv_valid_lo_sum_p (enum riscv_symbol_type sym_type, machine_mode mode,
1267 rtx x)
1269 int align, size;
1271 /* Check that symbols of type SYMBOL_TYPE can be used to access values
1272 of mode MODE. */
1273 if (riscv_symbol_insns (sym_type) == 0)
1274 return false;
1276 /* Check that there is a known low-part relocation. */
1277 if (!riscv_split_symbol_type (sym_type))
1278 return false;
1280 /* We can't tell size or alignment when we have BLKmode, so try extracing a
1281 decl from the symbol if possible. */
1282 if (mode == BLKmode)
1284 rtx offset;
1286 /* Extract the symbol from the LO_SUM operand, if any. */
1287 split_const (x, &x, &offset);
1289 /* Might be a CODE_LABEL. We can compute align but not size for that,
1290 so don't bother trying to handle it. */
1291 if (!SYMBOL_REF_P (x))
1292 return false;
1294 /* Use worst case assumptions if we don't have a SYMBOL_REF_DECL. */
1295 align = (SYMBOL_REF_DECL (x)
1296 ? DECL_ALIGN (SYMBOL_REF_DECL (x))
1297 : 1);
1298 size = (SYMBOL_REF_DECL (x) && DECL_SIZE (SYMBOL_REF_DECL (x))
1299 ? tree_to_uhwi (DECL_SIZE (SYMBOL_REF_DECL (x)))
1300 : 2*BITS_PER_WORD);
1302 else
1304 align = GET_MODE_ALIGNMENT (mode);
1305 size = GET_MODE_BITSIZE (mode).to_constant ();
1308 /* We may need to split multiword moves, so make sure that each word
1309 can be accessed without inducing a carry. */
1310 if (size > BITS_PER_WORD
1311 && (!TARGET_STRICT_ALIGN || size > align))
1312 return false;
1314 return true;
1317 /* Return true if mode is the RVV enabled mode.
1318 For example: 'RVVMF2SI' mode is disabled,
1319 wheras 'RVVM1SI' mode is enabled if MIN_VLEN == 32. */
1321 bool
1322 riscv_v_ext_vector_mode_p (machine_mode mode)
1324 #define ENTRY(MODE, REQUIREMENT, ...) \
1325 case MODE##mode: \
1326 return REQUIREMENT;
1327 switch (mode)
1329 #include "riscv-vector-switch.def"
1330 default:
1331 return false;
1334 return false;
1337 /* Return true if mode is the RVV enabled tuple mode. */
1339 bool
1340 riscv_v_ext_tuple_mode_p (machine_mode mode)
1342 #define TUPLE_ENTRY(MODE, REQUIREMENT, ...) \
1343 case MODE##mode: \
1344 return REQUIREMENT;
1345 switch (mode)
1347 #include "riscv-vector-switch.def"
1348 default:
1349 return false;
1352 return false;
1355 /* Return true if mode is the RVV enabled vls mode. */
1357 bool
1358 riscv_v_ext_vls_mode_p (machine_mode mode)
1360 #define VLS_ENTRY(MODE, REQUIREMENT) \
1361 case MODE##mode: \
1362 return REQUIREMENT;
1363 switch (mode)
1365 #include "riscv-vector-switch.def"
1366 default:
1367 return false;
1370 return false;
1373 /* Return true if it is either of below modes.
1374 1. RVV vector mode.
1375 2. RVV tuple mode.
1376 3. RVV vls mode. */
1378 static bool
1379 riscv_v_ext_mode_p (machine_mode mode)
1381 return riscv_v_ext_vector_mode_p (mode) || riscv_v_ext_tuple_mode_p (mode)
1382 || riscv_v_ext_vls_mode_p (mode);
1385 /* Call from ADJUST_NUNITS in riscv-modes.def. Return the correct
1386 NUNITS size for corresponding machine_mode. */
1388 poly_int64
1389 riscv_v_adjust_nunits (machine_mode mode, int scale)
1391 gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
1392 if (riscv_v_ext_mode_p (mode))
1394 if (TARGET_MIN_VLEN == 32)
1395 scale = scale / 2;
1396 return riscv_vector_chunks * scale;
1398 return scale;
1401 /* Call from ADJUST_NUNITS in riscv-modes.def. Return the correct
1402 NUNITS size for corresponding machine_mode. */
1404 poly_int64
1405 riscv_v_adjust_nunits (machine_mode mode, bool fractional_p, int lmul, int nf)
1407 if (riscv_v_ext_mode_p (mode))
1409 scalar_mode smode = GET_MODE_INNER (mode);
1410 int size = GET_MODE_SIZE (smode);
1411 int nunits_per_chunk = riscv_bytes_per_vector_chunk / size;
1412 if (fractional_p)
1413 return nunits_per_chunk / lmul * riscv_vector_chunks * nf;
1414 else
1415 return nunits_per_chunk * lmul * riscv_vector_chunks * nf;
1417 /* Set the disabled RVV modes size as 1 by default. */
1418 return 1;
1421 /* Call from ADJUST_BYTESIZE in riscv-modes.def. Return the correct
1422 BYTE size for corresponding machine_mode. */
1424 poly_int64
1425 riscv_v_adjust_bytesize (machine_mode mode, int scale)
1427 if (riscv_v_ext_vector_mode_p (mode))
1429 poly_int64 nunits = GET_MODE_NUNITS (mode);
1430 poly_int64 mode_size = GET_MODE_SIZE (mode);
1432 if (maybe_eq (mode_size, (uint16_t) -1))
1433 mode_size = riscv_vector_chunks * scale;
1435 if (nunits.coeffs[0] > 8)
1436 return exact_div (nunits, 8);
1437 else if (nunits.is_constant ())
1438 return 1;
1439 else
1440 return poly_int64 (1, 1);
1443 return scale;
1446 /* Call from ADJUST_PRECISION in riscv-modes.def. Return the correct
1447 PRECISION size for corresponding machine_mode. */
1449 poly_int64
1450 riscv_v_adjust_precision (machine_mode mode, int scale)
1452 return riscv_v_adjust_nunits (mode, scale);
1455 /* Return true if X is a valid address for machine mode MODE. If it is,
1456 fill in INFO appropriately. STRICT_P is true if REG_OK_STRICT is in
1457 effect. */
1459 static bool
1460 riscv_classify_address (struct riscv_address_info *info, rtx x,
1461 machine_mode mode, bool strict_p)
1463 if (th_classify_address (info, x, mode, strict_p))
1464 return true;
1466 switch (GET_CODE (x))
1468 case REG:
1469 case SUBREG:
1470 info->type = ADDRESS_REG;
1471 info->reg = x;
1472 info->offset = const0_rtx;
1473 return riscv_valid_base_register_p (info->reg, mode, strict_p);
1475 case PLUS:
1476 /* RVV load/store disallow any offset. */
1477 if (riscv_v_ext_mode_p (mode))
1478 return false;
1480 info->type = ADDRESS_REG;
1481 info->reg = XEXP (x, 0);
1482 info->offset = XEXP (x, 1);
1483 return (riscv_valid_base_register_p (info->reg, mode, strict_p)
1484 && riscv_valid_offset_p (info->offset, mode));
1486 case LO_SUM:
1487 /* RVV load/store disallow LO_SUM. */
1488 if (riscv_v_ext_mode_p (mode))
1489 return false;
1491 info->type = ADDRESS_LO_SUM;
1492 info->reg = XEXP (x, 0);
1493 info->offset = XEXP (x, 1);
1494 /* We have to trust the creator of the LO_SUM to do something vaguely
1495 sane. Target-independent code that creates a LO_SUM should also
1496 create and verify the matching HIGH. Target-independent code that
1497 adds an offset to a LO_SUM must prove that the offset will not
1498 induce a carry. Failure to do either of these things would be
1499 a bug, and we are not required to check for it here. The RISC-V
1500 backend itself should only create LO_SUMs for valid symbolic
1501 constants, with the high part being either a HIGH or a copy
1502 of _gp. */
1503 info->symbol_type
1504 = riscv_classify_symbolic_expression (info->offset);
1505 return (riscv_valid_base_register_p (info->reg, mode, strict_p)
1506 && riscv_valid_lo_sum_p (info->symbol_type, mode, info->offset));
1508 case CONST_INT:
1509 /* We only allow the const0_rtx for the RVV load/store. For example:
1510 +----------------------------------------------------------+
1511 | li a5,0 |
1512 | vsetvli zero,a1,e32,m1,ta,ma |
1513 | vle32.v v24,0(a5) <- propagate the const 0 to a5 here. |
1514 | vs1r.v v24,0(a0) |
1515 +----------------------------------------------------------+
1516 It can be folded to:
1517 +----------------------------------------------------------+
1518 | vsetvli zero,a1,e32,m1,ta,ma |
1519 | vle32.v v24,0(zero) |
1520 | vs1r.v v24,0(a0) |
1521 +----------------------------------------------------------+
1522 This behavior will benefit the underlying RVV auto vectorization. */
1523 if (riscv_v_ext_mode_p (mode))
1524 return x == const0_rtx;
1526 /* Small-integer addresses don't occur very often, but they
1527 are legitimate if x0 is a valid base register. */
1528 info->type = ADDRESS_CONST_INT;
1529 return SMALL_OPERAND (INTVAL (x));
1531 default:
1532 return false;
1536 /* Implement TARGET_LEGITIMATE_ADDRESS_P. */
1538 static bool
1539 riscv_legitimate_address_p (machine_mode mode, rtx x, bool strict_p,
1540 code_helper = ERROR_MARK)
1542 /* Disallow RVV modes base address.
1543 E.g. (mem:SI (subreg:DI (reg:V1DI 155) 0). */
1544 if (SUBREG_P (x) && riscv_v_ext_mode_p (GET_MODE (SUBREG_REG (x))))
1545 return false;
1546 struct riscv_address_info addr;
1548 return riscv_classify_address (&addr, x, mode, strict_p);
1551 /* Return true if hard reg REGNO can be used in compressed instructions. */
1553 static bool
1554 riscv_compressed_reg_p (int regno)
1556 /* x8-x15/f8-f15 are compressible registers. */
1557 return ((TARGET_RVC || TARGET_ZCA)
1558 && (IN_RANGE (regno, GP_REG_FIRST + 8, GP_REG_FIRST + 15)
1559 || IN_RANGE (regno, FP_REG_FIRST + 8, FP_REG_FIRST + 15)));
1562 /* Return true if x is an unsigned 5-bit immediate scaled by 4. */
1564 static bool
1565 riscv_compressed_lw_offset_p (rtx x)
1567 return (CONST_INT_P (x)
1568 && (INTVAL (x) & 3) == 0
1569 && IN_RANGE (INTVAL (x), 0, CSW_MAX_OFFSET));
1572 /* Return true if load/store from/to address x can be compressed. */
1574 static bool
1575 riscv_compressed_lw_address_p (rtx x)
1577 struct riscv_address_info addr;
1578 bool result = riscv_classify_address (&addr, x, GET_MODE (x),
1579 reload_completed);
1581 /* Return false if address is not compressed_reg + small_offset. */
1582 if (!result
1583 || addr.type != ADDRESS_REG
1584 /* Before reload, assume all registers are OK. */
1585 || (reload_completed
1586 && !riscv_compressed_reg_p (REGNO (addr.reg))
1587 && addr.reg != stack_pointer_rtx)
1588 || !riscv_compressed_lw_offset_p (addr.offset))
1589 return false;
1591 return result;
1594 /* Return the number of instructions needed to load or store a value
1595 of mode MODE at address X. Return 0 if X isn't valid for MODE.
1596 Assume that multiword moves may need to be split into word moves
1597 if MIGHT_SPLIT_P, otherwise assume that a single load or store is
1598 enough. */
1601 riscv_address_insns (rtx x, machine_mode mode, bool might_split_p)
1603 struct riscv_address_info addr = {};
1604 int n = 1;
1606 if (!riscv_classify_address (&addr, x, mode, false))
1608 /* This could be a pattern from the pic.md file. In which case we want
1609 this address to always have a cost of 3 to make it as expensive as the
1610 most expensive symbol. This prevents constant propagation from
1611 preferring symbols over register plus offset. */
1612 return 3;
1615 /* BLKmode is used for single unaligned loads and stores and should
1616 not count as a multiword mode. */
1617 if (!riscv_v_ext_vector_mode_p (mode) && mode != BLKmode && might_split_p)
1618 n += (GET_MODE_SIZE (mode).to_constant () + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
1620 if (addr.type == ADDRESS_LO_SUM)
1621 n += riscv_symbol_insns (addr.symbol_type) - 1;
1623 return n;
1626 /* Return the number of instructions needed to load constant X.
1627 Return 0 if X isn't a valid constant. */
1630 riscv_const_insns (rtx x)
1632 enum riscv_symbol_type symbol_type;
1633 rtx offset;
1635 switch (GET_CODE (x))
1637 case HIGH:
1638 if (!riscv_symbolic_constant_p (XEXP (x, 0), &symbol_type)
1639 || !riscv_split_symbol_type (symbol_type))
1640 return 0;
1642 /* This is simply an LUI. */
1643 return 1;
1645 case CONST_INT:
1647 int cost = riscv_integer_cost (INTVAL (x));
1648 /* Force complicated constants to memory. */
1649 return cost < 4 ? cost : 0;
1652 case CONST_DOUBLE:
1653 /* See if we can use FMV directly. */
1654 if (satisfies_constraint_zfli (x))
1655 return 1;
1657 /* We can use x0 to load floating-point zero. */
1658 return x == CONST0_RTX (GET_MODE (x)) ? 1 : 0;
1659 case CONST_VECTOR:
1661 /* TODO: This is not accurate, we will need to
1662 adapt the COST of CONST_VECTOR in the future
1663 for the following cases:
1665 - 1. const duplicate vector with element value
1666 in range of [-16, 15].
1667 - 2. const duplicate vector with element value
1668 out range of [-16, 15].
1669 - 3. const series vector.
1670 ...etc. */
1671 if (riscv_v_ext_mode_p (GET_MODE (x)))
1673 /* const series vector. */
1674 rtx base, step;
1675 if (const_vec_series_p (x, &base, &step))
1677 /* This is not accurate, we will need to adapt the COST
1678 * accurately according to BASE && STEP. */
1679 return 1;
1682 rtx elt;
1683 if (const_vec_duplicate_p (x, &elt))
1685 /* We don't allow CONST_VECTOR for DI vector on RV32
1686 system since the ELT constant value can not held
1687 within a single register to disable reload a DI
1688 register vec_duplicate into vmv.v.x. */
1689 scalar_mode smode = GET_MODE_INNER (GET_MODE (x));
1690 if (maybe_gt (GET_MODE_SIZE (smode), UNITS_PER_WORD)
1691 && !immediate_operand (elt, Pmode))
1692 return 0;
1693 /* Constants from -16 to 15 can be loaded with vmv.v.i.
1694 The Wc0, Wc1 constraints are already covered by the
1695 vi constraint so we do not need to check them here
1696 separately. */
1697 if (satisfies_constraint_vi (x))
1698 return 1;
1700 /* Any int/FP constants can always be broadcast from a
1701 scalar register. Loading of a floating-point
1702 constant incurs a literal-pool access. Allow this in
1703 order to increase vectorization possibilities. */
1704 int n = riscv_const_insns (elt);
1705 if (CONST_DOUBLE_P (elt))
1706 return 1 + 4; /* vfmv.v.f + memory access. */
1707 else
1709 /* We need as many insns as it takes to load the constant
1710 into a GPR and one vmv.v.x. */
1711 if (n != 0)
1712 return 1 + n;
1713 else
1714 return 1 + 4; /*vmv.v.x + memory access. */
1719 /* TODO: We may support more const vector in the future. */
1720 return x == CONST0_RTX (GET_MODE (x)) ? 1 : 0;
1723 case CONST:
1724 /* See if we can refer to X directly. */
1725 if (riscv_symbolic_constant_p (x, &symbol_type))
1726 return riscv_symbol_insns (symbol_type);
1728 /* Otherwise try splitting the constant into a base and offset. */
1729 split_const (x, &x, &offset);
1730 if (offset != 0)
1732 int n = riscv_const_insns (x);
1733 if (n != 0)
1734 return n + riscv_integer_cost (INTVAL (offset));
1736 return 0;
1738 case SYMBOL_REF:
1739 case LABEL_REF:
1740 return riscv_symbol_insns (riscv_classify_symbol (x));
1742 /* TODO: In RVV, we get CONST_POLY_INT by using csrr VLENB
1743 instruction and several scalar shift or mult instructions,
1744 it is so far unknown. We set it to 4 temporarily. */
1745 case CONST_POLY_INT:
1746 return 4;
1748 default:
1749 return 0;
1753 /* X is a doubleword constant that can be handled by splitting it into
1754 two words and loading each word separately. Return the number of
1755 instructions required to do this. */
1758 riscv_split_const_insns (rtx x)
1760 unsigned int low, high;
1762 low = riscv_const_insns (riscv_subword (x, false));
1763 high = riscv_const_insns (riscv_subword (x, true));
1764 gcc_assert (low > 0 && high > 0);
1765 return low + high;
1768 /* Return the number of instructions needed to implement INSN,
1769 given that it loads from or stores to MEM. */
1772 riscv_load_store_insns (rtx mem, rtx_insn *insn)
1774 machine_mode mode;
1775 bool might_split_p;
1776 rtx set;
1778 gcc_assert (MEM_P (mem));
1779 mode = GET_MODE (mem);
1781 /* Try to prove that INSN does not need to be split. */
1782 might_split_p = true;
1783 if (GET_MODE_BITSIZE (mode).to_constant () <= 32)
1784 might_split_p = false;
1785 else if (GET_MODE_BITSIZE (mode).to_constant () == 64)
1787 set = single_set (insn);
1788 if (set && !riscv_split_64bit_move_p (SET_DEST (set), SET_SRC (set)))
1789 might_split_p = false;
1792 return riscv_address_insns (XEXP (mem, 0), mode, might_split_p);
1795 /* Emit a move from SRC to DEST. Assume that the move expanders can
1796 handle all moves if !can_create_pseudo_p (). The distinction is
1797 important because, unlike emit_move_insn, the move expanders know
1798 how to force Pmode objects into the constant pool even when the
1799 constant pool address is not itself legitimate. */
1802 riscv_emit_move (rtx dest, rtx src)
1804 return (can_create_pseudo_p ()
1805 ? emit_move_insn (dest, src)
1806 : emit_move_insn_1 (dest, src));
1809 /* Emit an instruction of the form (set TARGET SRC). */
1811 static rtx
1812 riscv_emit_set (rtx target, rtx src)
1814 emit_insn (gen_rtx_SET (target, src));
1815 return target;
1818 /* Emit an instruction of the form (set DEST (CODE X)). */
1821 riscv_emit_unary (enum rtx_code code, rtx dest, rtx x)
1823 return riscv_emit_set (dest, gen_rtx_fmt_e (code, GET_MODE (dest), x));
1826 /* Emit an instruction of the form (set DEST (CODE X Y)). */
1829 riscv_emit_binary (enum rtx_code code, rtx dest, rtx x, rtx y)
1831 return riscv_emit_set (dest, gen_rtx_fmt_ee (code, GET_MODE (dest), x, y));
1834 /* Compute (CODE X Y) and store the result in a new register
1835 of mode MODE. Return that new register. */
1837 static rtx
1838 riscv_force_binary (machine_mode mode, enum rtx_code code, rtx x, rtx y)
1840 return riscv_emit_binary (code, gen_reg_rtx (mode), x, y);
1843 static rtx
1844 riscv_swap_instruction (rtx inst)
1846 gcc_assert (GET_MODE (inst) == SImode);
1847 if (BYTES_BIG_ENDIAN)
1848 inst = expand_unop (SImode, bswap_optab, inst, gen_reg_rtx (SImode), 1);
1849 return inst;
1852 /* Copy VALUE to a register and return that register. If new pseudos
1853 are allowed, copy it into a new register, otherwise use DEST. */
1855 static rtx
1856 riscv_force_temporary (rtx dest, rtx value)
1858 if (can_create_pseudo_p ())
1859 return force_reg (Pmode, value);
1860 else
1862 riscv_emit_move (dest, value);
1863 return dest;
1867 /* Wrap symbol or label BASE in an UNSPEC address of type SYMBOL_TYPE,
1868 then add CONST_INT OFFSET to the result. */
1870 static rtx
1871 riscv_unspec_address_offset (rtx base, rtx offset,
1872 enum riscv_symbol_type symbol_type)
1874 base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base),
1875 UNSPEC_ADDRESS_FIRST + symbol_type);
1876 if (offset != const0_rtx)
1877 base = gen_rtx_PLUS (Pmode, base, offset);
1878 return gen_rtx_CONST (Pmode, base);
1881 /* Return an UNSPEC address with underlying address ADDRESS and symbol
1882 type SYMBOL_TYPE. */
1885 riscv_unspec_address (rtx address, enum riscv_symbol_type symbol_type)
1887 rtx base, offset;
1889 split_const (address, &base, &offset);
1890 return riscv_unspec_address_offset (base, offset, symbol_type);
1893 /* If OP is an UNSPEC address, return the address to which it refers,
1894 otherwise return OP itself. */
1896 static rtx
1897 riscv_strip_unspec_address (rtx op)
1899 rtx base, offset;
1901 split_const (op, &base, &offset);
1902 if (UNSPEC_ADDRESS_P (base))
1903 op = plus_constant (Pmode, UNSPEC_ADDRESS (base), INTVAL (offset));
1904 return op;
1907 /* If riscv_unspec_address (ADDR, SYMBOL_TYPE) is a 32-bit value, add the
1908 high part to BASE and return the result. Just return BASE otherwise.
1909 TEMP is as for riscv_force_temporary.
1911 The returned expression can be used as the first operand to a LO_SUM. */
1913 static rtx
1914 riscv_unspec_offset_high (rtx temp, rtx addr, enum riscv_symbol_type symbol_type)
1916 addr = gen_rtx_HIGH (Pmode, riscv_unspec_address (addr, symbol_type));
1917 return riscv_force_temporary (temp, addr);
1920 /* Load an entry from the GOT for a TLS GD access. */
1922 static rtx riscv_got_load_tls_gd (rtx dest, rtx sym)
1924 if (Pmode == DImode)
1925 return gen_got_load_tls_gddi (dest, sym);
1926 else
1927 return gen_got_load_tls_gdsi (dest, sym);
1930 /* Load an entry from the GOT for a TLS IE access. */
1932 static rtx riscv_got_load_tls_ie (rtx dest, rtx sym)
1934 if (Pmode == DImode)
1935 return gen_got_load_tls_iedi (dest, sym);
1936 else
1937 return gen_got_load_tls_iesi (dest, sym);
1940 /* Add in the thread pointer for a TLS LE access. */
1942 static rtx riscv_tls_add_tp_le (rtx dest, rtx base, rtx sym)
1944 rtx tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
1945 if (Pmode == DImode)
1946 return gen_tls_add_tp_ledi (dest, base, tp, sym);
1947 else
1948 return gen_tls_add_tp_lesi (dest, base, tp, sym);
1951 /* If MODE is MAX_MACHINE_MODE, ADDR appears as a move operand, otherwise
1952 it appears in a MEM of that mode. Return true if ADDR is a legitimate
1953 constant in that context and can be split into high and low parts.
1954 If so, and if LOW_OUT is nonnull, emit the high part and store the
1955 low part in *LOW_OUT. Leave *LOW_OUT unchanged otherwise.
1957 TEMP is as for riscv_force_temporary and is used to load the high
1958 part into a register.
1960 When MODE is MAX_MACHINE_MODE, the low part is guaranteed to be
1961 a legitimize SET_SRC for an .md pattern, otherwise the low part
1962 is guaranteed to be a legitimate address for mode MODE. */
1964 bool
1965 riscv_split_symbol (rtx temp, rtx addr, machine_mode mode, rtx *low_out)
1967 enum riscv_symbol_type symbol_type;
1969 if ((GET_CODE (addr) == HIGH && mode == MAX_MACHINE_MODE)
1970 || !riscv_symbolic_constant_p (addr, &symbol_type)
1971 || riscv_symbol_insns (symbol_type) == 0
1972 || !riscv_split_symbol_type (symbol_type))
1973 return false;
1975 if (low_out)
1976 switch (symbol_type)
1978 case SYMBOL_FORCE_TO_MEM:
1979 return false;
1981 case SYMBOL_ABSOLUTE:
1983 rtx high = gen_rtx_HIGH (Pmode, copy_rtx (addr));
1984 high = riscv_force_temporary (temp, high);
1985 *low_out = gen_rtx_LO_SUM (Pmode, high, addr);
1987 break;
1989 case SYMBOL_PCREL:
1991 static unsigned seqno;
1992 char buf[32];
1993 rtx label;
1995 ssize_t bytes = snprintf (buf, sizeof (buf), ".LA%u", seqno);
1996 gcc_assert ((size_t) bytes < sizeof (buf));
1998 label = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
1999 SYMBOL_REF_FLAGS (label) |= SYMBOL_FLAG_LOCAL;
2000 /* ??? Ugly hack to make weak symbols work. May need to change the
2001 RTL for the auipc and/or low patterns to get a better fix for
2002 this. */
2003 if (! nonzero_address_p (addr))
2004 SYMBOL_REF_WEAK (label) = 1;
2006 if (temp == NULL)
2007 temp = gen_reg_rtx (Pmode);
2009 if (Pmode == DImode)
2010 emit_insn (gen_auipcdi (temp, copy_rtx (addr), GEN_INT (seqno)));
2011 else
2012 emit_insn (gen_auipcsi (temp, copy_rtx (addr), GEN_INT (seqno)));
2014 *low_out = gen_rtx_LO_SUM (Pmode, temp, label);
2016 seqno++;
2018 break;
2020 default:
2021 gcc_unreachable ();
2024 return true;
2027 /* Return a legitimate address for REG + OFFSET. TEMP is as for
2028 riscv_force_temporary; it is only needed when OFFSET is not a
2029 SMALL_OPERAND. */
2031 static rtx
2032 riscv_add_offset (rtx temp, rtx reg, HOST_WIDE_INT offset)
2034 if (!SMALL_OPERAND (offset))
2036 rtx high;
2038 /* Leave OFFSET as a 16-bit offset and put the excess in HIGH.
2039 The addition inside the macro CONST_HIGH_PART may cause an
2040 overflow, so we need to force a sign-extension check. */
2041 high = gen_int_mode (CONST_HIGH_PART (offset), Pmode);
2042 offset = CONST_LOW_PART (offset);
2043 high = riscv_force_temporary (temp, high);
2044 reg = riscv_force_temporary (temp, gen_rtx_PLUS (Pmode, high, reg));
2046 return plus_constant (Pmode, reg, offset);
2049 /* The __tls_get_attr symbol. */
2050 static GTY(()) rtx riscv_tls_symbol;
2052 /* Return an instruction sequence that calls __tls_get_addr. SYM is
2053 the TLS symbol we are referencing and TYPE is the symbol type to use
2054 (either global dynamic or local dynamic). RESULT is an RTX for the
2055 return value location. */
2057 static rtx_insn *
2058 riscv_call_tls_get_addr (rtx sym, rtx result)
2060 rtx a0 = gen_rtx_REG (Pmode, GP_ARG_FIRST), func;
2061 rtx_insn *insn;
2063 if (!riscv_tls_symbol)
2064 riscv_tls_symbol = init_one_libfunc ("__tls_get_addr");
2065 func = gen_rtx_MEM (FUNCTION_MODE, riscv_tls_symbol);
2067 start_sequence ();
2069 emit_insn (riscv_got_load_tls_gd (a0, sym));
2070 insn = emit_call_insn (gen_call_value (result, func, const0_rtx,
2071 gen_int_mode (RISCV_CC_BASE, SImode)));
2072 RTL_CONST_CALL_P (insn) = 1;
2073 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), a0);
2074 insn = get_insns ();
2076 end_sequence ();
2078 return insn;
2081 /* Generate the code to access LOC, a thread-local SYMBOL_REF, and return
2082 its address. The return value will be both a valid address and a valid
2083 SET_SRC (either a REG or a LO_SUM). */
2085 static rtx
2086 riscv_legitimize_tls_address (rtx loc)
2088 rtx dest, tp, tmp;
2089 enum tls_model model = SYMBOL_REF_TLS_MODEL (loc);
2091 #if 0
2092 /* TLS copy relocs are now deprecated and should not be used. */
2093 /* Since we support TLS copy relocs, non-PIC TLS accesses may all use LE. */
2094 if (!flag_pic)
2095 model = TLS_MODEL_LOCAL_EXEC;
2096 #endif
2098 switch (model)
2100 case TLS_MODEL_LOCAL_DYNAMIC:
2101 /* Rely on section anchors for the optimization that LDM TLS
2102 provides. The anchor's address is loaded with GD TLS. */
2103 case TLS_MODEL_GLOBAL_DYNAMIC:
2104 tmp = gen_rtx_REG (Pmode, GP_RETURN);
2105 dest = gen_reg_rtx (Pmode);
2106 emit_libcall_block (riscv_call_tls_get_addr (loc, tmp), dest, tmp, loc);
2107 break;
2109 case TLS_MODEL_INITIAL_EXEC:
2110 /* la.tls.ie; tp-relative add */
2111 tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
2112 tmp = gen_reg_rtx (Pmode);
2113 emit_insn (riscv_got_load_tls_ie (tmp, loc));
2114 dest = gen_reg_rtx (Pmode);
2115 emit_insn (gen_add3_insn (dest, tmp, tp));
2116 break;
2118 case TLS_MODEL_LOCAL_EXEC:
2119 tmp = riscv_unspec_offset_high (NULL, loc, SYMBOL_TLS_LE);
2120 dest = gen_reg_rtx (Pmode);
2121 emit_insn (riscv_tls_add_tp_le (dest, tmp, loc));
2122 dest = gen_rtx_LO_SUM (Pmode, dest,
2123 riscv_unspec_address (loc, SYMBOL_TLS_LE));
2124 break;
2126 default:
2127 gcc_unreachable ();
2129 return dest;
2132 /* If X is not a valid address for mode MODE, force it into a register. */
2134 static rtx
2135 riscv_force_address (rtx x, machine_mode mode)
2137 if (!riscv_legitimate_address_p (mode, x, false))
2139 if (can_create_pseudo_p ())
2140 return force_reg (Pmode, x);
2141 else
2143 /* It's only safe for the thunk function.
2144 Use ra as the temp regiater. */
2145 gcc_assert (riscv_in_thunk_func);
2146 rtx reg = RISCV_PROLOGUE_TEMP2 (Pmode);
2147 riscv_emit_move (reg, x);
2148 return reg;
2152 return x;
2155 /* Modify base + offset so that offset fits within a compressed load/store insn
2156 and the excess is added to base. */
2158 static rtx
2159 riscv_shorten_lw_offset (rtx base, HOST_WIDE_INT offset)
2161 rtx addr, high;
2162 /* Leave OFFSET as an unsigned 5-bit offset scaled by 4 and put the excess
2163 into HIGH. */
2164 high = GEN_INT (offset & ~CSW_MAX_OFFSET);
2165 offset &= CSW_MAX_OFFSET;
2166 if (!SMALL_OPERAND (INTVAL (high)))
2167 high = force_reg (Pmode, high);
2168 base = force_reg (Pmode, gen_rtx_PLUS (Pmode, high, base));
2169 addr = plus_constant (Pmode, base, offset);
2170 return addr;
2173 /* Helper for riscv_legitimize_address. Given X, return true if it
2174 is a left shift by 1, 2 or 3 positions or a multiply by 2, 4 or 8.
2176 This respectively represent canonical shift-add rtxs or scaled
2177 memory addresses. */
2178 static bool
2179 mem_shadd_or_shadd_rtx_p (rtx x)
2181 return ((GET_CODE (x) == ASHIFT
2182 || GET_CODE (x) == MULT)
2183 && CONST_INT_P (XEXP (x, 1))
2184 && ((GET_CODE (x) == ASHIFT && IN_RANGE (INTVAL (XEXP (x, 1)), 1, 3))
2185 || (GET_CODE (x) == MULT
2186 && IN_RANGE (exact_log2 (INTVAL (XEXP (x, 1))), 1, 3))));
2189 /* This function is used to implement LEGITIMIZE_ADDRESS. If X can
2190 be legitimized in a way that the generic machinery might not expect,
2191 return a new address, otherwise return NULL. MODE is the mode of
2192 the memory being accessed. */
2194 static rtx
2195 riscv_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
2196 machine_mode mode)
2198 rtx addr;
2200 if (riscv_tls_symbol_p (x))
2201 return riscv_legitimize_tls_address (x);
2203 /* See if the address can split into a high part and a LO_SUM. */
2204 if (riscv_split_symbol (NULL, x, mode, &addr))
2205 return riscv_force_address (addr, mode);
2207 /* Handle BASE + OFFSET. */
2208 if (GET_CODE (x) == PLUS && CONST_INT_P (XEXP (x, 1))
2209 && INTVAL (XEXP (x, 1)) != 0)
2211 rtx base = XEXP (x, 0);
2212 HOST_WIDE_INT offset = INTVAL (XEXP (x, 1));
2214 /* Handle (plus (plus (mult (a) (mem_shadd_constant)) (fp)) (C)) case. */
2215 if (GET_CODE (base) == PLUS && mem_shadd_or_shadd_rtx_p (XEXP (base, 0))
2216 && SMALL_OPERAND (offset))
2218 rtx index = XEXP (base, 0);
2219 rtx fp = XEXP (base, 1);
2220 if (REG_P (fp) && REGNO (fp) == VIRTUAL_STACK_VARS_REGNUM)
2223 /* If we were given a MULT, we must fix the constant
2224 as we're going to create the ASHIFT form. */
2225 int shift_val = INTVAL (XEXP (index, 1));
2226 if (GET_CODE (index) == MULT)
2227 shift_val = exact_log2 (shift_val);
2229 rtx reg1 = gen_reg_rtx (Pmode);
2230 rtx reg2 = gen_reg_rtx (Pmode);
2231 rtx reg3 = gen_reg_rtx (Pmode);
2232 riscv_emit_binary (PLUS, reg1, fp, GEN_INT (offset));
2233 riscv_emit_binary (ASHIFT, reg2, XEXP (index, 0), GEN_INT (shift_val));
2234 riscv_emit_binary (PLUS, reg3, reg2, reg1);
2236 return reg3;
2240 if (!riscv_valid_base_register_p (base, mode, false))
2241 base = copy_to_mode_reg (Pmode, base);
2242 if (optimize_function_for_size_p (cfun)
2243 && (strcmp (current_pass->name, "shorten_memrefs") == 0)
2244 && mode == SImode)
2245 /* Convert BASE + LARGE_OFFSET into NEW_BASE + SMALL_OFFSET to allow
2246 possible compressed load/store. */
2247 addr = riscv_shorten_lw_offset (base, offset);
2248 else
2249 addr = riscv_add_offset (NULL, base, offset);
2250 return riscv_force_address (addr, mode);
2253 return x;
2256 /* Load VALUE into DEST. TEMP is as for riscv_force_temporary. ORIG_MODE
2257 is the original src mode before promotion. */
2259 void
2260 riscv_move_integer (rtx temp, rtx dest, HOST_WIDE_INT value,
2261 machine_mode orig_mode)
2263 struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS];
2264 machine_mode mode;
2265 int i, num_ops;
2266 rtx x;
2268 mode = GET_MODE (dest);
2269 /* We use the original mode for the riscv_build_integer call, because HImode
2270 values are given special treatment. */
2271 num_ops = riscv_build_integer (codes, value, orig_mode);
2273 if (can_create_pseudo_p () && num_ops > 2 /* not a simple constant */
2274 && num_ops >= riscv_split_integer_cost (value))
2275 x = riscv_split_integer (value, mode);
2276 else
2278 codes[0].value = trunc_int_for_mode (codes[0].value, mode);
2279 /* Apply each binary operation to X. */
2280 x = GEN_INT (codes[0].value);
2282 for (i = 1; i < num_ops; i++)
2284 if (!can_create_pseudo_p ())
2285 x = riscv_emit_set (temp, x);
2286 else
2287 x = force_reg (mode, x);
2288 codes[i].value = trunc_int_for_mode (codes[i].value, mode);
2289 x = gen_rtx_fmt_ee (codes[i].code, mode, x, GEN_INT (codes[i].value));
2293 riscv_emit_set (dest, x);
2296 /* Subroutine of riscv_legitimize_move. Move constant SRC into register
2297 DEST given that SRC satisfies immediate_operand but doesn't satisfy
2298 move_operand. */
2300 static void
2301 riscv_legitimize_const_move (machine_mode mode, rtx dest, rtx src)
2303 rtx base, offset;
2305 /* Split moves of big integers into smaller pieces. */
2306 if (splittable_const_int_operand (src, mode))
2308 riscv_move_integer (dest, dest, INTVAL (src), mode);
2309 return;
2312 if (satisfies_constraint_zfli (src))
2314 riscv_emit_set (dest, src);
2315 return;
2318 /* Split moves of symbolic constants into high/low pairs. */
2319 if (riscv_split_symbol (dest, src, MAX_MACHINE_MODE, &src))
2321 riscv_emit_set (dest, src);
2322 return;
2325 /* Generate the appropriate access sequences for TLS symbols. */
2326 if (riscv_tls_symbol_p (src))
2328 riscv_emit_move (dest, riscv_legitimize_tls_address (src));
2329 return;
2332 /* If we have (const (plus symbol offset)), and that expression cannot
2333 be forced into memory, load the symbol first and add in the offset. Also
2334 prefer to do this even if the constant _can_ be forced into memory, as it
2335 usually produces better code. */
2336 split_const (src, &base, &offset);
2337 if (offset != const0_rtx
2338 && (targetm.cannot_force_const_mem (mode, src) || can_create_pseudo_p ()))
2340 base = riscv_force_temporary (dest, base);
2341 riscv_emit_move (dest, riscv_add_offset (NULL, base, INTVAL (offset)));
2342 return;
2345 /* Handle below format.
2346 (const:DI
2347 (plus:DI
2348 (symbol_ref:DI ("ic") [flags 0x2] <var_decl 0x7fe57740be10 ic>) <- op_0
2349 (const_poly_int:DI [16, 16]) // <- op_1
2352 if (GET_CODE (src) == CONST && GET_CODE (XEXP (src, 0)) == PLUS
2353 && CONST_POLY_INT_P (XEXP (XEXP (src, 0), 1)))
2355 rtx dest_tmp = gen_reg_rtx (mode);
2356 rtx tmp = gen_reg_rtx (mode);
2358 riscv_emit_move (dest, XEXP (XEXP (src, 0), 0));
2359 riscv_legitimize_poly_move (mode, dest_tmp, tmp, XEXP (XEXP (src, 0), 1));
2361 emit_insn (gen_rtx_SET (dest, gen_rtx_PLUS (mode, dest, dest_tmp)));
2362 return;
2365 src = force_const_mem (mode, src);
2367 /* When using explicit relocs, constant pool references are sometimes
2368 not legitimate addresses. */
2369 riscv_split_symbol (dest, XEXP (src, 0), mode, &XEXP (src, 0));
2370 riscv_emit_move (dest, src);
2373 /* Report when we try to do something that requires vector when vector is
2374 disabled. This is an error of last resort and isn't very high-quality. It
2375 usually involves attempts to measure the vector length in some way. */
2377 static void
2378 riscv_report_v_required (void)
2380 static bool reported_p = false;
2382 /* Avoid reporting a slew of messages for a single oversight. */
2383 if (reported_p)
2384 return;
2386 error ("this operation requires the RVV ISA extension");
2387 inform (input_location, "you can enable RVV using the command-line"
2388 " option %<-march%>, or by using the %<target%>"
2389 " attribute or pragma");
2390 reported_p = true;
2393 /* Helper function to operation for rtx_code CODE. */
2394 static void
2395 riscv_expand_op (enum rtx_code code, machine_mode mode, rtx op0, rtx op1,
2396 rtx op2)
2398 if (can_create_pseudo_p ())
2400 rtx result;
2401 if (GET_RTX_CLASS (code) == RTX_UNARY)
2402 result = expand_simple_unop (mode, code, op1, NULL_RTX, false);
2403 else
2404 result = expand_simple_binop (mode, code, op1, op2, NULL_RTX, false,
2405 OPTAB_DIRECT);
2406 riscv_emit_move (op0, result);
2408 else
2410 rtx pat;
2411 /* The following implementation is for prologue and epilogue.
2412 Because prologue and epilogue can not use pseudo register.
2413 We can't using expand_simple_binop or expand_simple_unop. */
2414 if (GET_RTX_CLASS (code) == RTX_UNARY)
2415 pat = gen_rtx_fmt_e (code, mode, op1);
2416 else
2417 pat = gen_rtx_fmt_ee (code, mode, op1, op2);
2418 emit_insn (gen_rtx_SET (op0, pat));
2422 /* Expand mult operation with constant integer, multiplicand also used as a
2423 * temporary register. */
2425 static void
2426 riscv_expand_mult_with_const_int (machine_mode mode, rtx dest, rtx multiplicand,
2427 HOST_WIDE_INT multiplier)
2429 if (multiplier == 0)
2431 riscv_emit_move (dest, GEN_INT (0));
2432 return;
2435 bool neg_p = multiplier < 0;
2436 unsigned HOST_WIDE_INT multiplier_abs = abs (multiplier);
2438 if (multiplier_abs == 1)
2440 if (neg_p)
2441 riscv_expand_op (NEG, mode, dest, multiplicand, NULL_RTX);
2442 else
2443 riscv_emit_move (dest, multiplicand);
2445 else
2447 if (pow2p_hwi (multiplier_abs))
2450 multiplicand = [BYTES_PER_RISCV_VECTOR].
2451 1. const_poly_int:P [BYTES_PER_RISCV_VECTOR * 8].
2452 Sequence:
2453 csrr a5, vlenb
2454 slli a5, a5, 3
2455 2. const_poly_int:P [-BYTES_PER_RISCV_VECTOR * 8].
2456 Sequence:
2457 csrr a5, vlenb
2458 slli a5, a5, 3
2459 neg a5, a5
2461 riscv_expand_op (ASHIFT, mode, dest, multiplicand,
2462 gen_int_mode (exact_log2 (multiplier_abs), QImode));
2463 if (neg_p)
2464 riscv_expand_op (NEG, mode, dest, dest, NULL_RTX);
2466 else if (pow2p_hwi (multiplier_abs + 1))
2469 multiplicand = [BYTES_PER_RISCV_VECTOR].
2470 1. const_poly_int:P [BYTES_PER_RISCV_VECTOR * 7].
2471 Sequence:
2472 csrr a5, vlenb
2473 slli a4, a5, 3
2474 sub a5, a4, a5
2475 2. const_poly_int:P [-BYTES_PER_RISCV_VECTOR * 7].
2476 Sequence:
2477 csrr a5, vlenb
2478 slli a4, a5, 3
2479 sub a5, a4, a5 + neg a5, a5 => sub a5, a5, a4
2481 riscv_expand_op (ASHIFT, mode, dest, multiplicand,
2482 gen_int_mode (exact_log2 (multiplier_abs + 1),
2483 QImode));
2484 if (neg_p)
2485 riscv_expand_op (MINUS, mode, dest, multiplicand, dest);
2486 else
2487 riscv_expand_op (MINUS, mode, dest, dest, multiplicand);
2489 else if (pow2p_hwi (multiplier - 1))
2492 multiplicand = [BYTES_PER_RISCV_VECTOR].
2493 1. const_poly_int:P [BYTES_PER_RISCV_VECTOR * 9].
2494 Sequence:
2495 csrr a5, vlenb
2496 slli a4, a5, 3
2497 add a5, a4, a5
2498 2. const_poly_int:P [-BYTES_PER_RISCV_VECTOR * 9].
2499 Sequence:
2500 csrr a5, vlenb
2501 slli a4, a5, 3
2502 add a5, a4, a5
2503 neg a5, a5
2505 riscv_expand_op (ASHIFT, mode, dest, multiplicand,
2506 gen_int_mode (exact_log2 (multiplier_abs - 1),
2507 QImode));
2508 riscv_expand_op (PLUS, mode, dest, dest, multiplicand);
2509 if (neg_p)
2510 riscv_expand_op (NEG, mode, dest, dest, NULL_RTX);
2512 else
2514 /* We use multiplication for remaining cases. */
2515 gcc_assert (
2516 TARGET_MUL
2517 && "M-extension must be enabled to calculate the poly_int "
2518 "size/offset.");
2519 riscv_emit_move (dest, gen_int_mode (multiplier, mode));
2520 riscv_expand_op (MULT, mode, dest, dest, multiplicand);
2525 /* Analyze src and emit const_poly_int mov sequence. */
2527 void
2528 riscv_legitimize_poly_move (machine_mode mode, rtx dest, rtx tmp, rtx src)
2530 poly_int64 value = rtx_to_poly_int64 (src);
2531 /* It use HOST_WIDE_INT intead of int since 32bit type is not enough
2532 for e.g. (const_poly_int:DI [549755813888, 549755813888]). */
2533 HOST_WIDE_INT offset = value.coeffs[0];
2534 HOST_WIDE_INT factor = value.coeffs[1];
2535 int vlenb = BYTES_PER_RISCV_VECTOR.coeffs[1];
2536 int div_factor = 0;
2537 /* Calculate (const_poly_int:MODE [m, n]) using scalar instructions.
2538 For any (const_poly_int:MODE [m, n]), the calculation formula is as
2539 follows.
2540 constant = m - n.
2541 When minimum VLEN = 32, poly of VLENB = (4, 4).
2542 base = vlenb(4, 4) or vlenb/2(2, 2) or vlenb/4(1, 1).
2543 When minimum VLEN > 32, poly of VLENB = (8, 8).
2544 base = vlenb(8, 8) or vlenb/2(4, 4) or vlenb/4(2, 2) or vlenb/8(1, 1).
2545 magn = (n, n) / base.
2546 (m, n) = base * magn + constant.
2547 This calculation doesn't need div operation. */
2549 if (known_le (GET_MODE_SIZE (mode), GET_MODE_SIZE (Pmode)))
2550 emit_move_insn (tmp, gen_int_mode (BYTES_PER_RISCV_VECTOR, mode));
2551 else
2553 emit_move_insn (gen_highpart (Pmode, tmp), CONST0_RTX (Pmode));
2554 emit_move_insn (gen_lowpart (Pmode, tmp),
2555 gen_int_mode (BYTES_PER_RISCV_VECTOR, Pmode));
2558 if (BYTES_PER_RISCV_VECTOR.is_constant ())
2560 gcc_assert (value.is_constant ());
2561 riscv_emit_move (dest, GEN_INT (value.to_constant ()));
2562 return;
2564 else
2566 int max_power = exact_log2 (MAX_POLY_VARIANT);
2567 for (int i = 0; i <= max_power; i++)
2569 int possible_div_factor = 1 << i;
2570 if (factor % (vlenb / possible_div_factor) == 0)
2572 div_factor = possible_div_factor;
2573 break;
2576 gcc_assert (div_factor != 0);
2579 if (div_factor != 1)
2580 riscv_expand_op (LSHIFTRT, mode, tmp, tmp,
2581 gen_int_mode (exact_log2 (div_factor), QImode));
2583 riscv_expand_mult_with_const_int (mode, dest, tmp,
2584 factor / (vlenb / div_factor));
2585 HOST_WIDE_INT constant = offset - factor;
2587 if (constant == 0)
2588 return;
2589 else if (SMALL_OPERAND (constant))
2590 riscv_expand_op (PLUS, mode, dest, dest, gen_int_mode (constant, mode));
2591 else
2593 /* Handle the constant value is not a 12-bit value. */
2594 rtx high;
2596 /* Leave OFFSET as a 16-bit offset and put the excess in HIGH.
2597 The addition inside the macro CONST_HIGH_PART may cause an
2598 overflow, so we need to force a sign-extension check. */
2599 high = gen_int_mode (CONST_HIGH_PART (constant), mode);
2600 constant = CONST_LOW_PART (constant);
2601 riscv_emit_move (tmp, high);
2602 riscv_expand_op (PLUS, mode, dest, tmp, dest);
2603 riscv_expand_op (PLUS, mode, dest, dest, gen_int_mode (constant, mode));
2607 /* Adjust scalable frame of vector for prologue && epilogue. */
2609 static void
2610 riscv_v_adjust_scalable_frame (rtx target, poly_int64 offset, bool epilogue)
2612 rtx tmp = RISCV_PROLOGUE_TEMP (Pmode);
2613 rtx adjust_size = RISCV_PROLOGUE_TEMP2 (Pmode);
2614 rtx insn, dwarf, adjust_frame_rtx;
2616 riscv_legitimize_poly_move (Pmode, adjust_size, tmp,
2617 gen_int_mode (offset, Pmode));
2619 if (epilogue)
2620 insn = gen_add3_insn (target, target, adjust_size);
2621 else
2622 insn = gen_sub3_insn (target, target, adjust_size);
2624 insn = emit_insn (insn);
2626 RTX_FRAME_RELATED_P (insn) = 1;
2628 adjust_frame_rtx
2629 = gen_rtx_SET (target,
2630 plus_constant (Pmode, target, epilogue ? offset : -offset));
2632 dwarf = alloc_reg_note (REG_FRAME_RELATED_EXPR, copy_rtx (adjust_frame_rtx),
2633 NULL_RTX);
2635 REG_NOTES (insn) = dwarf;
2638 /* If (set DEST SRC) is not a valid move instruction, emit an equivalent
2639 sequence that is valid. */
2641 bool
2642 riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
2644 if (CONST_POLY_INT_P (src))
2647 Handle:
2648 (insn 183 182 184 6 (set (mem:QI (plus:DI (reg/f:DI 156)
2649 (const_int 96 [0x60])) [0 S1 A8])
2650 (const_poly_int:QI [8, 8]))
2651 "../../../../riscv-gcc/libgcc/unwind-dw2.c":1579:3 -1 (nil))
2653 if (MEM_P (dest))
2655 emit_move_insn (dest, force_reg (mode, src));
2656 return true;
2658 poly_int64 value = rtx_to_poly_int64 (src);
2659 if (!value.is_constant () && !TARGET_VECTOR)
2661 riscv_report_v_required ();
2662 return false;
2665 if (satisfies_constraint_vp (src) && GET_MODE (src) == Pmode)
2666 return false;
2668 if (GET_MODE_SIZE (mode).to_constant () < GET_MODE_SIZE (Pmode))
2670 /* In RV32 system, handle (const_poly_int:QI [m, n])
2671 (const_poly_int:HI [m, n]).
2672 In RV64 system, handle (const_poly_int:QI [m, n])
2673 (const_poly_int:HI [m, n])
2674 (const_poly_int:SI [m, n]). */
2675 rtx tmp = gen_reg_rtx (Pmode);
2676 riscv_legitimize_poly_move (Pmode, gen_lowpart (Pmode, dest), tmp,
2677 src);
2679 else
2681 /* In RV32 system, handle (const_poly_int:SI [m, n])
2682 (const_poly_int:DI [m, n]).
2683 In RV64 system, handle (const_poly_int:DI [m, n]).
2684 FIXME: Maybe we could gen SImode in RV32 and then sign-extend to DImode,
2685 the offset should not exceed 4GiB in general. */
2686 rtx tmp = gen_reg_rtx (mode);
2687 riscv_legitimize_poly_move (mode, dest, tmp, src);
2689 return true;
2691 /* Expand
2692 (set (reg:DI target) (subreg:DI (reg:V8QI reg) 0))
2693 Expand this data movement instead of simply forbid it since
2694 we can improve the code generation for this following scenario
2695 by RVV auto-vectorization:
2696 (set (reg:V8QI 149) (vec_duplicate:V8QI (reg:QI))
2697 (set (reg:DI target) (subreg:DI (reg:V8QI reg) 0))
2698 Since RVV mode and scalar mode are in different REG_CLASS,
2699 we need to explicitly move data from V_REGS to GR_REGS by scalar move. */
2700 if (SUBREG_P (src) && riscv_v_ext_mode_p (GET_MODE (SUBREG_REG (src))))
2702 machine_mode vmode = GET_MODE (SUBREG_REG (src));
2703 unsigned int mode_size = GET_MODE_SIZE (mode).to_constant ();
2704 unsigned int vmode_size = GET_MODE_SIZE (vmode).to_constant ();
2705 /* We should be able to handle both partial and paradoxical subreg. */
2706 unsigned int nunits = vmode_size > mode_size ? vmode_size / mode_size : 1;
2707 scalar_mode smode = as_a<scalar_mode> (mode);
2708 unsigned int index = SUBREG_BYTE (src).to_constant () / mode_size;
2709 unsigned int num = known_eq (GET_MODE_SIZE (smode), 8)
2710 && !TARGET_VECTOR_ELEN_64 ? 2 : 1;
2711 bool need_int_reg_p = false;
2713 if (num == 2)
2715 /* If we want to extract 64bit value but ELEN < 64,
2716 we use RVV vector mode with EEW = 32 to extract
2717 the highpart and lowpart. */
2718 need_int_reg_p = smode == DFmode;
2719 smode = SImode;
2720 nunits = nunits * 2;
2723 if (riscv_vector::get_vector_mode (smode, nunits).exists (&vmode))
2725 rtx v = gen_lowpart (vmode, SUBREG_REG (src));
2726 rtx int_reg = dest;
2728 if (need_int_reg_p)
2730 int_reg = gen_reg_rtx (DImode);
2731 emit_move_insn (int_reg, gen_lowpart (GET_MODE (int_reg), dest));
2734 for (unsigned int i = 0; i < num; i++)
2736 rtx result;
2737 if (num == 1)
2738 result = int_reg;
2739 else if (i == 0)
2740 result = gen_lowpart (smode, int_reg);
2741 else
2742 result = gen_reg_rtx (smode);
2744 riscv_vector::emit_vec_extract (result, v,
2745 gen_int_mode (index + i, Pmode));
2747 if (i == 1)
2749 if (UNITS_PER_WORD < mode_size)
2750 /* If Pmode = SImode and mode = DImode, we just need to
2751 extract element of index = 1 from the vector and move it
2752 into the highpart of the DEST since DEST consists of 2
2753 scalar registers. */
2754 emit_move_insn (gen_highpart (smode, int_reg), result);
2755 else
2757 rtx tmp = expand_binop (Pmode, ashl_optab,
2758 gen_lowpart (Pmode, result),
2759 gen_int_mode (32, Pmode),
2760 NULL_RTX, 0, OPTAB_DIRECT);
2761 rtx tmp2 = expand_binop (Pmode, ior_optab, tmp, int_reg,
2762 NULL_RTX, 0, OPTAB_DIRECT);
2763 emit_move_insn (int_reg, tmp2);
2768 if (need_int_reg_p)
2769 emit_move_insn (dest, gen_lowpart (GET_MODE (dest), int_reg));
2770 else
2771 emit_move_insn (dest, int_reg);
2773 else
2774 gcc_unreachable ();
2776 return true;
2778 /* Expand
2779 (set (reg:QI target) (mem:QI (address)))
2781 (set (reg:DI temp) (zero_extend:DI (mem:QI (address))))
2782 (set (reg:QI target) (subreg:QI (reg:DI temp) 0))
2783 with auto-sign/zero extend. */
2784 if (GET_MODE_CLASS (mode) == MODE_INT
2785 && GET_MODE_SIZE (mode).to_constant () < UNITS_PER_WORD
2786 && can_create_pseudo_p ()
2787 && MEM_P (src))
2789 rtx temp_reg;
2790 int zero_extend_p;
2792 temp_reg = gen_reg_rtx (word_mode);
2793 zero_extend_p = (LOAD_EXTEND_OP (mode) == ZERO_EXTEND);
2794 emit_insn (gen_extend_insn (temp_reg, src, word_mode, mode,
2795 zero_extend_p));
2796 riscv_emit_move (dest, gen_lowpart (mode, temp_reg));
2797 return true;
2800 if (!register_operand (dest, mode) && !reg_or_0_operand (src, mode))
2802 rtx reg;
2804 if (GET_CODE (src) == CONST_INT)
2806 /* Apply the equivalent of PROMOTE_MODE here for constants to
2807 improve cse. */
2808 machine_mode promoted_mode = mode;
2809 if (GET_MODE_CLASS (mode) == MODE_INT
2810 && GET_MODE_SIZE (mode).to_constant () < UNITS_PER_WORD)
2811 promoted_mode = word_mode;
2813 if (splittable_const_int_operand (src, mode))
2815 reg = gen_reg_rtx (promoted_mode);
2816 riscv_move_integer (reg, reg, INTVAL (src), mode);
2818 else
2819 reg = force_reg (promoted_mode, src);
2821 if (promoted_mode != mode)
2822 reg = gen_lowpart (mode, reg);
2824 else
2825 reg = force_reg (mode, src);
2826 riscv_emit_move (dest, reg);
2827 return true;
2830 /* In order to fit NaN boxing, expand
2831 (set FP_REG (reg:HF src))
2833 (set (reg:SI/DI mask) (const_int -65536)
2834 (set (reg:SI/DI temp) (zero_extend:SI/DI (subreg:HI (reg:HF src) 0)))
2835 (set (reg:SI/DI temp) (ior:SI/DI (reg:SI/DI mask) (reg:SI/DI temp)))
2836 (set (reg:HF dest) (unspec:HF [ (reg:SI/DI temp) ] UNSPEC_FMV_SFP16_X))
2839 if (TARGET_HARD_FLOAT
2840 && !TARGET_ZFHMIN && mode == HFmode
2841 && REG_P (dest) && FP_REG_P (REGNO (dest))
2842 && REG_P (src) && !FP_REG_P (REGNO (src))
2843 && can_create_pseudo_p ())
2845 rtx mask = force_reg (word_mode, gen_int_mode (-65536, word_mode));
2846 rtx temp = gen_reg_rtx (word_mode);
2847 emit_insn (gen_extend_insn (temp,
2848 simplify_gen_subreg (HImode, src, mode, 0),
2849 word_mode, HImode, 1));
2850 if (word_mode == SImode)
2851 emit_insn (gen_iorsi3 (temp, mask, temp));
2852 else
2853 emit_insn (gen_iordi3 (temp, mask, temp));
2855 riscv_emit_move (dest, gen_rtx_UNSPEC (HFmode, gen_rtvec (1, temp),
2856 UNSPEC_FMV_SFP16_X));
2858 return true;
2861 /* We need to deal with constants that would be legitimate
2862 immediate_operands but aren't legitimate move_operands. */
2863 if (CONSTANT_P (src) && !move_operand (src, mode))
2865 riscv_legitimize_const_move (mode, dest, src);
2866 set_unique_reg_note (get_last_insn (), REG_EQUAL, copy_rtx (src));
2867 return true;
2870 /* RISC-V GCC may generate non-legitimate address due to we provide some
2871 pattern for optimize access PIC local symbol and it's make GCC generate
2872 unrecognizable instruction during optmizing. */
2874 if (MEM_P (dest) && !riscv_legitimate_address_p (mode, XEXP (dest, 0),
2875 reload_completed))
2877 XEXP (dest, 0) = riscv_force_address (XEXP (dest, 0), mode);
2880 if (MEM_P (src) && !riscv_legitimate_address_p (mode, XEXP (src, 0),
2881 reload_completed))
2883 XEXP (src, 0) = riscv_force_address (XEXP (src, 0), mode);
2886 return false;
2889 /* Return true if there is an instruction that implements CODE and accepts
2890 X as an immediate operand. */
2892 static int
2893 riscv_immediate_operand_p (int code, HOST_WIDE_INT x)
2895 switch (code)
2897 case ASHIFT:
2898 case ASHIFTRT:
2899 case LSHIFTRT:
2900 /* All shift counts are truncated to a valid constant. */
2901 return true;
2903 case AND:
2904 case IOR:
2905 case XOR:
2906 case PLUS:
2907 case LT:
2908 case LTU:
2909 /* These instructions take 12-bit signed immediates. */
2910 return SMALL_OPERAND (x);
2912 case LE:
2913 /* We add 1 to the immediate and use SLT. */
2914 return SMALL_OPERAND (x + 1);
2916 case LEU:
2917 /* Likewise SLTU, but reject the always-true case. */
2918 return SMALL_OPERAND (x + 1) && x + 1 != 0;
2920 case GE:
2921 case GEU:
2922 /* We can emulate an immediate of 1 by using GT/GTU against x0. */
2923 return x == 1;
2925 default:
2926 /* By default assume that x0 can be used for 0. */
2927 return x == 0;
2931 /* Return the cost of binary operation X, given that the instruction
2932 sequence for a word-sized or smaller operation takes SIGNLE_INSNS
2933 instructions and that the sequence of a double-word operation takes
2934 DOUBLE_INSNS instructions. */
2936 static int
2937 riscv_binary_cost (rtx x, int single_insns, int double_insns)
2939 if (!riscv_v_ext_mode_p (GET_MODE (x))
2940 && GET_MODE_SIZE (GET_MODE (x)).to_constant () == UNITS_PER_WORD * 2)
2941 return COSTS_N_INSNS (double_insns);
2942 return COSTS_N_INSNS (single_insns);
2945 /* Return the cost of sign- or zero-extending OP. */
2947 static int
2948 riscv_extend_cost (rtx op, bool unsigned_p)
2950 if (MEM_P (op))
2951 return 0;
2953 if (unsigned_p && GET_MODE (op) == QImode)
2954 /* We can use ANDI. */
2955 return COSTS_N_INSNS (1);
2957 /* ZBA provide zext.w. */
2958 if (TARGET_ZBA && TARGET_64BIT && unsigned_p && GET_MODE (op) == SImode)
2959 return COSTS_N_INSNS (1);
2961 /* ZBB provide zext.h, sext.b and sext.h. */
2962 if (TARGET_ZBB)
2964 if (!unsigned_p && GET_MODE (op) == QImode)
2965 return COSTS_N_INSNS (1);
2967 if (GET_MODE (op) == HImode)
2968 return COSTS_N_INSNS (1);
2971 if (!unsigned_p && GET_MODE (op) == SImode)
2972 /* We can use SEXT.W. */
2973 return COSTS_N_INSNS (1);
2975 /* We need to use a shift left and a shift right. */
2976 return COSTS_N_INSNS (2);
2979 /* Implement TARGET_RTX_COSTS. */
2981 #define SINGLE_SHIFT_COST 1
2983 static bool
2984 riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UNUSED,
2985 int *total, bool speed)
2987 /* TODO: We set RVV instruction cost as 1 by default.
2988 Cost Model need to be well analyzed and supported in the future. */
2989 if (riscv_v_ext_mode_p (mode))
2991 *total = COSTS_N_INSNS (1);
2992 return true;
2995 bool float_mode_p = FLOAT_MODE_P (mode);
2996 int cost;
2998 switch (GET_CODE (x))
3000 case SET:
3001 /* If we are called for an INSN that's a simple set of a register,
3002 then cost based on the SET_SRC alone. */
3003 if (outer_code == INSN && REG_P (SET_DEST (x)))
3005 riscv_rtx_costs (SET_SRC (x), mode, outer_code, opno, total, speed);
3006 return true;
3009 /* Otherwise return FALSE indicating we should recurse into both the
3010 SET_DEST and SET_SRC combining the cost of both. */
3011 return false;
3013 case CONST_INT:
3014 /* trivial constants checked using OUTER_CODE in case they are
3015 encodable in insn itself w/o need for additional insn(s). */
3016 if (riscv_immediate_operand_p (outer_code, INTVAL (x)))
3018 *total = 0;
3019 return true;
3021 /* Fall through. */
3023 case SYMBOL_REF:
3024 case LABEL_REF:
3025 case CONST_DOUBLE:
3026 /* With TARGET_SUPPORTS_WIDE_INT const int can't be in CONST_DOUBLE
3027 rtl object. Weird recheck due to switch-case fall through above. */
3028 if (GET_CODE (x) == CONST_DOUBLE)
3029 gcc_assert (GET_MODE (x) != VOIDmode);
3030 /* Fall through. */
3032 case CONST:
3033 /* Non trivial CONST_INT Fall through: check if need multiple insns. */
3034 if ((cost = riscv_const_insns (x)) > 0)
3036 /* 1. Hoist will GCSE constants only if TOTAL returned is non-zero.
3037 2. For constants loaded more than once, the approach so far has
3038 been to duplicate the operation than to CSE the constant.
3039 3. TODO: make cost more accurate specially if riscv_const_insns
3040 returns > 1. */
3041 if (outer_code == SET || GET_MODE (x) == VOIDmode)
3042 *total = COSTS_N_INSNS (1);
3044 else /* The instruction will be fetched from the constant pool. */
3045 *total = COSTS_N_INSNS (riscv_symbol_insns (SYMBOL_ABSOLUTE));
3046 return true;
3048 case MEM:
3049 /* If the address is legitimate, return the number of
3050 instructions it needs. */
3051 if ((cost = riscv_address_insns (XEXP (x, 0), mode, true)) > 0)
3053 /* When optimizing for size, make uncompressible 32-bit addresses
3054 more expensive so that compressible 32-bit addresses are
3055 preferred. */
3056 if ((TARGET_RVC || TARGET_ZCA)
3057 && !speed && riscv_mshorten_memrefs && mode == SImode
3058 && !riscv_compressed_lw_address_p (XEXP (x, 0)))
3059 cost++;
3061 *total = COSTS_N_INSNS (cost + tune_param->memory_cost);
3062 return true;
3064 /* Otherwise use the default handling. */
3065 return false;
3067 case IF_THEN_ELSE:
3068 if ((TARGET_SFB_ALU || TARGET_XTHEADCONDMOV)
3069 && reg_or_0_operand (XEXP (x, 1), mode)
3070 && sfb_alu_operand (XEXP (x, 2), mode)
3071 && comparison_operator (XEXP (x, 0), VOIDmode))
3073 /* For predicated conditional-move operations we assume the cost
3074 of a single instruction even though there are actually two. */
3075 *total = COSTS_N_INSNS (1);
3076 return true;
3078 else if (TARGET_ZICOND_LIKE
3079 && outer_code == SET
3080 && ((GET_CODE (XEXP (x, 1)) == REG
3081 && XEXP (x, 2) == CONST0_RTX (GET_MODE (XEXP (x, 1))))
3082 || (GET_CODE (XEXP (x, 2)) == REG
3083 && XEXP (x, 1) == CONST0_RTX (GET_MODE (XEXP (x, 2))))
3084 || (GET_CODE (XEXP (x, 1)) == REG
3085 && rtx_equal_p (XEXP (x, 1), XEXP (XEXP (x, 0), 0)))
3086 || (GET_CODE (XEXP (x, 1)) == REG
3087 && rtx_equal_p (XEXP (x, 2), XEXP (XEXP (x, 0), 0)))))
3089 *total = COSTS_N_INSNS (1);
3090 return true;
3092 else if (LABEL_REF_P (XEXP (x, 1)) && XEXP (x, 2) == pc_rtx)
3094 if (equality_operator (XEXP (x, 0), mode)
3095 && GET_CODE (XEXP (XEXP (x, 0), 0)) == ZERO_EXTRACT)
3097 *total = COSTS_N_INSNS (SINGLE_SHIFT_COST + 1);
3098 return true;
3100 if (ordered_comparison_operator (XEXP (x, 0), mode))
3102 *total = COSTS_N_INSNS (1);
3103 return true;
3106 return false;
3108 case NOT:
3109 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode).to_constant () > UNITS_PER_WORD ? 2 : 1);
3110 return false;
3112 case AND:
3113 /* slli.uw pattern for zba. */
3114 if (TARGET_ZBA && TARGET_64BIT && mode == DImode
3115 && GET_CODE (XEXP (x, 0)) == ASHIFT)
3117 rtx and_rhs = XEXP (x, 1);
3118 rtx ashift_lhs = XEXP (XEXP (x, 0), 0);
3119 rtx ashift_rhs = XEXP (XEXP (x, 0), 1);
3120 if (REG_P (ashift_lhs)
3121 && CONST_INT_P (ashift_rhs)
3122 && CONST_INT_P (and_rhs)
3123 && ((INTVAL (and_rhs) >> INTVAL (ashift_rhs)) == 0xffffffff))
3124 *total = COSTS_N_INSNS (1);
3125 return true;
3127 /* bclri pattern for zbs. */
3128 if (TARGET_ZBS
3129 && not_single_bit_mask_operand (XEXP (x, 1), VOIDmode))
3131 *total = COSTS_N_INSNS (1);
3132 return true;
3134 /* bclr pattern for zbs. */
3135 if (TARGET_ZBS
3136 && REG_P (XEXP (x, 1))
3137 && GET_CODE (XEXP (x, 0)) == ROTATE
3138 && CONST_INT_P (XEXP ((XEXP (x, 0)), 0))
3139 && INTVAL (XEXP ((XEXP (x, 0)), 0)) == -2)
3141 *total = COSTS_N_INSNS (1);
3142 return true;
3145 gcc_fallthrough ();
3146 case IOR:
3147 case XOR:
3148 /* orn, andn and xorn pattern for zbb. */
3149 if (TARGET_ZBB
3150 && GET_CODE (XEXP (x, 0)) == NOT)
3152 *total = riscv_binary_cost (x, 1, 2);
3153 return true;
3156 /* bset[i] and binv[i] pattern for zbs. */
3157 if ((GET_CODE (x) == IOR || GET_CODE (x) == XOR)
3158 && TARGET_ZBS
3159 && ((GET_CODE (XEXP (x, 0)) == ASHIFT
3160 && CONST_INT_P (XEXP (XEXP (x, 0), 0)))
3161 || single_bit_mask_operand (XEXP (x, 1), VOIDmode)))
3163 *total = COSTS_N_INSNS (1);
3164 return true;
3167 /* Double-word operations use two single-word operations. */
3168 *total = riscv_binary_cost (x, 1, 2);
3169 return false;
3171 case ZERO_EXTRACT:
3172 /* This is an SImode shift. */
3173 if (outer_code == SET
3174 && CONST_INT_P (XEXP (x, 1))
3175 && CONST_INT_P (XEXP (x, 2))
3176 && (INTVAL (XEXP (x, 2)) > 0)
3177 && (INTVAL (XEXP (x, 1)) + INTVAL (XEXP (x, 2)) == 32))
3179 *total = COSTS_N_INSNS (SINGLE_SHIFT_COST);
3180 return true;
3182 /* bit extraction pattern (zbs:bext, xtheadbs:tst). */
3183 if ((TARGET_ZBS || TARGET_XTHEADBS) && outer_code == SET
3184 && GET_CODE (XEXP (x, 1)) == CONST_INT
3185 && INTVAL (XEXP (x, 1)) == 1)
3187 *total = COSTS_N_INSNS (SINGLE_SHIFT_COST);
3188 return true;
3190 gcc_fallthrough ();
3191 case SIGN_EXTRACT:
3192 if (TARGET_XTHEADBB && outer_code == SET
3193 && CONST_INT_P (XEXP (x, 1))
3194 && CONST_INT_P (XEXP (x, 2)))
3196 *total = COSTS_N_INSNS (SINGLE_SHIFT_COST);
3197 return true;
3199 return false;
3201 case ASHIFT:
3202 /* bset pattern for zbs. */
3203 if (TARGET_ZBS
3204 && CONST_INT_P (XEXP (x, 0))
3205 && INTVAL (XEXP (x, 0)) == 1)
3207 *total = COSTS_N_INSNS (1);
3208 return true;
3210 gcc_fallthrough ();
3211 case ASHIFTRT:
3212 case LSHIFTRT:
3213 *total = riscv_binary_cost (x, SINGLE_SHIFT_COST,
3214 CONSTANT_P (XEXP (x, 1)) ? 4 : 9);
3215 return false;
3217 case ABS:
3218 *total = COSTS_N_INSNS (float_mode_p ? 1 : 3);
3219 return false;
3221 case LO_SUM:
3222 *total = set_src_cost (XEXP (x, 0), mode, speed);
3223 return true;
3225 case LT:
3226 /* This is an SImode shift. */
3227 if (outer_code == SET && GET_MODE (x) == DImode
3228 && GET_MODE (XEXP (x, 0)) == SImode)
3230 *total = COSTS_N_INSNS (SINGLE_SHIFT_COST);
3231 return true;
3233 /* Fall through. */
3234 case LTU:
3235 case LE:
3236 case LEU:
3237 case GT:
3238 case GTU:
3239 case GE:
3240 case GEU:
3241 case EQ:
3242 case NE:
3243 /* Branch comparisons have VOIDmode, so use the first operand's
3244 mode instead. */
3245 mode = GET_MODE (XEXP (x, 0));
3246 if (float_mode_p)
3247 *total = tune_param->fp_add[mode == DFmode];
3248 else
3249 *total = riscv_binary_cost (x, 1, 3);
3250 return false;
3252 case UNORDERED:
3253 case ORDERED:
3254 /* (FEQ(A, A) & FEQ(B, B)) compared against 0. */
3255 mode = GET_MODE (XEXP (x, 0));
3256 *total = tune_param->fp_add[mode == DFmode] + COSTS_N_INSNS (2);
3257 return false;
3259 case UNEQ:
3260 /* (FEQ(A, A) & FEQ(B, B)) compared against FEQ(A, B). */
3261 mode = GET_MODE (XEXP (x, 0));
3262 *total = tune_param->fp_add[mode == DFmode] + COSTS_N_INSNS (3);
3263 return false;
3265 case LTGT:
3266 /* (FLT(A, A) || FGT(B, B)). */
3267 mode = GET_MODE (XEXP (x, 0));
3268 *total = tune_param->fp_add[mode == DFmode] + COSTS_N_INSNS (2);
3269 return false;
3271 case UNGE:
3272 case UNGT:
3273 case UNLE:
3274 case UNLT:
3275 /* FLT or FLE, but guarded by an FFLAGS read and write. */
3276 mode = GET_MODE (XEXP (x, 0));
3277 *total = tune_param->fp_add[mode == DFmode] + COSTS_N_INSNS (4);
3278 return false;
3280 case MINUS:
3281 if (float_mode_p)
3282 *total = tune_param->fp_add[mode == DFmode];
3283 else
3284 *total = riscv_binary_cost (x, 1, 4);
3285 return false;
3287 case PLUS:
3288 /* add.uw pattern for zba. */
3289 if (TARGET_ZBA
3290 && (TARGET_64BIT && (mode == DImode))
3291 && GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
3292 && REG_P (XEXP (XEXP (x, 0), 0))
3293 && GET_MODE (XEXP (XEXP (x, 0), 0)) == SImode)
3295 *total = COSTS_N_INSNS (1);
3296 return true;
3298 /* shNadd pattern for zba. */
3299 if (TARGET_ZBA
3300 && ((!TARGET_64BIT && (mode == SImode)) ||
3301 (TARGET_64BIT && (mode == DImode)))
3302 && (GET_CODE (XEXP (x, 0)) == ASHIFT)
3303 && REG_P (XEXP (XEXP (x, 0), 0))
3304 && CONST_INT_P (XEXP (XEXP (x, 0), 1))
3305 && IN_RANGE (INTVAL (XEXP (XEXP (x, 0), 1)), 1, 3))
3307 *total = COSTS_N_INSNS (1);
3308 return true;
3310 /* Before strength-reduction, the shNadd can be expressed as the addition
3311 of a multiplication with a power-of-two. If this case is not handled,
3312 the strength-reduction in expmed.c will calculate an inflated cost. */
3313 if (TARGET_ZBA
3314 && mode == word_mode
3315 && GET_CODE (XEXP (x, 0)) == MULT
3316 && REG_P (XEXP (XEXP (x, 0), 0))
3317 && CONST_INT_P (XEXP (XEXP (x, 0), 1))
3318 && pow2p_hwi (INTVAL (XEXP (XEXP (x, 0), 1)))
3319 && IN_RANGE (exact_log2 (INTVAL (XEXP (XEXP (x, 0), 1))), 1, 3))
3321 *total = COSTS_N_INSNS (1);
3322 return true;
3324 /* shNadd.uw pattern for zba.
3325 [(set (match_operand:DI 0 "register_operand" "=r")
3326 (plus:DI
3327 (and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r")
3328 (match_operand:QI 2 "immediate_operand" "I"))
3329 (match_operand 3 "immediate_operand" ""))
3330 (match_operand:DI 4 "register_operand" "r")))]
3331 "TARGET_64BIT && TARGET_ZBA
3332 && (INTVAL (operands[2]) >= 1) && (INTVAL (operands[2]) <= 3)
3333 && (INTVAL (operands[3]) >> INTVAL (operands[2])) == 0xffffffff"
3335 if (TARGET_ZBA
3336 && (TARGET_64BIT && (mode == DImode))
3337 && (GET_CODE (XEXP (x, 0)) == AND)
3338 && (REG_P (XEXP (x, 1))))
3340 do {
3341 rtx and_lhs = XEXP (XEXP (x, 0), 0);
3342 rtx and_rhs = XEXP (XEXP (x, 0), 1);
3343 if (GET_CODE (and_lhs) != ASHIFT)
3344 break;
3345 if (!CONST_INT_P (and_rhs))
3346 break;
3348 rtx ashift_rhs = XEXP (and_lhs, 1);
3350 if (!CONST_INT_P (ashift_rhs)
3351 || !IN_RANGE (INTVAL (ashift_rhs), 1, 3))
3352 break;
3354 if (CONST_INT_P (and_rhs)
3355 && ((INTVAL (and_rhs) >> INTVAL (ashift_rhs)) == 0xffffffff))
3357 *total = COSTS_N_INSNS (1);
3358 return true;
3360 } while (false);
3363 if (float_mode_p)
3364 *total = tune_param->fp_add[mode == DFmode];
3365 else
3366 *total = riscv_binary_cost (x, 1, 4);
3367 return false;
3369 case NEG:
3371 rtx op = XEXP (x, 0);
3372 if (GET_CODE (op) == FMA && !HONOR_SIGNED_ZEROS (mode))
3374 *total = (tune_param->fp_mul[mode == DFmode]
3375 + set_src_cost (XEXP (op, 0), mode, speed)
3376 + set_src_cost (XEXP (op, 1), mode, speed)
3377 + set_src_cost (XEXP (op, 2), mode, speed));
3378 return true;
3382 if (float_mode_p)
3383 *total = tune_param->fp_add[mode == DFmode];
3384 else
3385 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode).to_constant () > UNITS_PER_WORD ? 4 : 1);
3386 return false;
3388 case MULT:
3389 if (float_mode_p)
3390 *total = tune_param->fp_mul[mode == DFmode];
3391 else if (!TARGET_MUL)
3392 /* Estimate the cost of a library call. */
3393 *total = COSTS_N_INSNS (speed ? 32 : 6);
3394 else if (GET_MODE_SIZE (mode).to_constant () > UNITS_PER_WORD)
3395 *total = 3 * tune_param->int_mul[0] + COSTS_N_INSNS (2);
3396 else if (!speed)
3397 *total = COSTS_N_INSNS (1);
3398 else
3399 *total = tune_param->int_mul[mode == DImode];
3400 return false;
3402 case DIV:
3403 case SQRT:
3404 case MOD:
3405 if (float_mode_p)
3407 *total = tune_param->fp_div[mode == DFmode];
3408 return false;
3410 /* Fall through. */
3412 case UDIV:
3413 case UMOD:
3414 if (!TARGET_DIV)
3415 /* Estimate the cost of a library call. */
3416 *total = COSTS_N_INSNS (speed ? 32 : 6);
3417 else if (speed)
3418 *total = tune_param->int_div[mode == DImode];
3419 else
3420 *total = COSTS_N_INSNS (1);
3421 return false;
3423 case ZERO_EXTEND:
3424 /* This is an SImode shift. */
3425 if (GET_CODE (XEXP (x, 0)) == LSHIFTRT)
3427 *total = COSTS_N_INSNS (SINGLE_SHIFT_COST);
3428 return true;
3430 /* Fall through. */
3431 case SIGN_EXTEND:
3432 *total = riscv_extend_cost (XEXP (x, 0), GET_CODE (x) == ZERO_EXTEND);
3433 return false;
3435 case BSWAP:
3436 if (TARGET_ZBB)
3438 /* RISC-V only defines rev8 for XLEN, so we will need an extra
3439 shift-right instruction for smaller modes. */
3440 *total = COSTS_N_INSNS (mode == word_mode ? 1 : 2);
3441 return true;
3443 return false;
3445 case FLOAT:
3446 case UNSIGNED_FLOAT:
3447 case FIX:
3448 case FLOAT_EXTEND:
3449 case FLOAT_TRUNCATE:
3450 *total = tune_param->fp_add[mode == DFmode];
3451 return false;
3453 case FMA:
3454 *total = (tune_param->fp_mul[mode == DFmode]
3455 + set_src_cost (XEXP (x, 0), mode, speed)
3456 + set_src_cost (XEXP (x, 1), mode, speed)
3457 + set_src_cost (XEXP (x, 2), mode, speed));
3458 return true;
3460 case UNSPEC:
3461 if (XINT (x, 1) == UNSPEC_AUIPC)
3463 /* Make AUIPC cheap to avoid spilling its result to the stack. */
3464 *total = 1;
3465 return true;
3467 return false;
3469 default:
3470 return false;
3474 /* Implement TARGET_ADDRESS_COST. */
3476 static int
3477 riscv_address_cost (rtx addr, machine_mode mode,
3478 addr_space_t as ATTRIBUTE_UNUSED,
3479 bool speed ATTRIBUTE_UNUSED)
3481 /* When optimizing for size, make uncompressible 32-bit addresses more
3482 * expensive so that compressible 32-bit addresses are preferred. */
3483 if ((TARGET_RVC || TARGET_ZCA)
3484 && !speed && riscv_mshorten_memrefs && mode == SImode
3485 && !riscv_compressed_lw_address_p (addr))
3486 return riscv_address_insns (addr, mode, false) + 1;
3487 return riscv_address_insns (addr, mode, false);
3490 /* Implement TARGET_INSN_COST. We factor in the branch cost in the cost
3491 calculation for conditional branches: one unit is considered the cost
3492 of microarchitecture-dependent actual branch execution and therefore
3493 multiplied by BRANCH_COST and any remaining units are considered fixed
3494 branch overhead. Branches on a floating-point condition incur an extra
3495 instruction cost as they will be split into an FCMP operation followed
3496 by a branch on an integer condition. */
3498 static int
3499 riscv_insn_cost (rtx_insn *insn, bool speed)
3501 rtx x = PATTERN (insn);
3502 int cost = pattern_cost (x, speed);
3504 if (JUMP_P (insn))
3506 if (GET_CODE (x) == PARALLEL)
3507 x = XVECEXP (x, 0, 0);
3508 if (GET_CODE (x) == SET
3509 && GET_CODE (SET_DEST (x)) == PC
3510 && GET_CODE (SET_SRC (x)) == IF_THEN_ELSE)
3512 cost += COSTS_N_INSNS (BRANCH_COST (speed, false) - 1);
3513 if (FLOAT_MODE_P (GET_MODE (XEXP (XEXP (SET_SRC (x), 0), 0))))
3514 cost += COSTS_N_INSNS (1);
3517 return cost;
3520 /* Implement TARGET_MAX_NOCE_IFCVT_SEQ_COST. Like the default implementation,
3521 but we consider cost units of branch instructions equal to cost units of
3522 other instructions. */
3524 static unsigned int
3525 riscv_max_noce_ifcvt_seq_cost (edge e)
3527 bool predictable_p = predictable_edge_p (e);
3529 if (predictable_p)
3531 if (OPTION_SET_P (param_max_rtl_if_conversion_predictable_cost))
3532 return param_max_rtl_if_conversion_predictable_cost;
3534 else
3536 if (OPTION_SET_P (param_max_rtl_if_conversion_unpredictable_cost))
3537 return param_max_rtl_if_conversion_unpredictable_cost;
3540 return COSTS_N_INSNS (BRANCH_COST (true, predictable_p));
3543 /* Implement TARGET_NOCE_CONVERSION_PROFITABLE_P. We replace the cost of a
3544 conditional branch assumed by `noce_find_if_block' at `COSTS_N_INSNS (2)'
3545 by our actual conditional branch cost, observing that our branches test
3546 conditions directly, so there is no preparatory extra condition-set
3547 instruction. */
3549 static bool
3550 riscv_noce_conversion_profitable_p (rtx_insn *seq,
3551 struct noce_if_info *if_info)
3553 struct noce_if_info riscv_if_info = *if_info;
3555 riscv_if_info.original_cost -= COSTS_N_INSNS (2);
3556 riscv_if_info.original_cost += insn_cost (if_info->jump, if_info->speed_p);
3558 /* Hack alert! When `noce_try_store_flag_mask' uses `cstore<mode>4'
3559 to emit a conditional set operation on DImode output it comes up
3560 with a sequence such as:
3562 (insn 26 0 27 (set (reg:SI 140)
3563 (eq:SI (reg/v:DI 137 [ c ])
3564 (const_int 0 [0]))) 302 {*seq_zero_disi}
3565 (nil))
3566 (insn 27 26 28 (set (reg:DI 139)
3567 (zero_extend:DI (reg:SI 140))) 116 {*zero_extendsidi2_internal}
3568 (nil))
3570 because our `cstore<mode>4' pattern expands to an insn that gives
3571 a SImode output. The output of conditional set is 0 or 1 boolean,
3572 so it is valid for input in any scalar integer mode and therefore
3573 combine later folds the zero extend operation into an equivalent
3574 conditional set operation that produces a DImode output, however
3575 this redundant zero extend operation counts towards the cost of
3576 the replacement sequence. Compensate for that by incrementing the
3577 cost of the original sequence as well as the maximum sequence cost
3578 accordingly. Likewise for sign extension. */
3579 rtx last_dest = NULL_RTX;
3580 for (rtx_insn *insn = seq; insn; insn = NEXT_INSN (insn))
3582 if (!NONDEBUG_INSN_P (insn))
3583 continue;
3585 rtx x = PATTERN (insn);
3586 if (NONJUMP_INSN_P (insn)
3587 && GET_CODE (x) == SET)
3589 rtx src = SET_SRC (x);
3590 enum rtx_code code = GET_CODE (src);
3591 if (last_dest != NULL_RTX
3592 && (code == SIGN_EXTEND || code == ZERO_EXTEND)
3593 && REG_P (XEXP (src, 0))
3594 && REGNO (XEXP (src, 0)) == REGNO (last_dest))
3596 riscv_if_info.original_cost += COSTS_N_INSNS (1);
3597 riscv_if_info.max_seq_cost += COSTS_N_INSNS (1);
3599 last_dest = NULL_RTX;
3600 rtx dest = SET_DEST (x);
3601 if (COMPARISON_P (src)
3602 && REG_P (dest)
3603 && GET_MODE (dest) == SImode)
3604 last_dest = dest;
3606 else
3607 last_dest = NULL_RTX;
3610 return default_noce_conversion_profitable_p (seq, &riscv_if_info);
3613 /* Return one word of double-word value OP. HIGH_P is true to select the
3614 high part or false to select the low part. */
3617 riscv_subword (rtx op, bool high_p)
3619 unsigned int byte = (high_p != BYTES_BIG_ENDIAN) ? UNITS_PER_WORD : 0;
3620 machine_mode mode = GET_MODE (op);
3622 if (mode == VOIDmode)
3623 mode = TARGET_64BIT ? TImode : DImode;
3625 if (MEM_P (op))
3626 return adjust_address (op, word_mode, byte);
3628 if (REG_P (op))
3629 gcc_assert (!FP_REG_RTX_P (op));
3631 return simplify_gen_subreg (word_mode, op, mode, byte);
3634 /* Return true if a 64-bit move from SRC to DEST should be split into two. */
3636 bool
3637 riscv_split_64bit_move_p (rtx dest, rtx src)
3639 if (TARGET_64BIT)
3640 return false;
3642 /* There is no need to split if the FLI instruction in the `Zfa` extension can be used. */
3643 if (satisfies_constraint_zfli (src))
3644 return false;
3646 /* Allow FPR <-> FPR and FPR <-> MEM moves, and permit the special case
3647 of zeroing an FPR with FCVT.D.W. */
3648 if (TARGET_DOUBLE_FLOAT
3649 && ((FP_REG_RTX_P (src) && FP_REG_RTX_P (dest))
3650 || (FP_REG_RTX_P (dest) && MEM_P (src))
3651 || (FP_REG_RTX_P (src) && MEM_P (dest))
3652 || (FP_REG_RTX_P (dest) && src == CONST0_RTX (GET_MODE (src)))))
3653 return false;
3655 return true;
3658 /* Split a doubleword move from SRC to DEST. On 32-bit targets,
3659 this function handles 64-bit moves for which riscv_split_64bit_move_p
3660 holds. For 64-bit targets, this function handles 128-bit moves. */
3662 void
3663 riscv_split_doubleword_move (rtx dest, rtx src)
3665 /* ZFA or XTheadFmv has instructions for accessing the upper bits of a double. */
3666 if (!TARGET_64BIT && (TARGET_ZFA || TARGET_XTHEADFMV))
3668 if (FP_REG_RTX_P (dest))
3670 rtx low_src = riscv_subword (src, false);
3671 rtx high_src = riscv_subword (src, true);
3673 if (TARGET_ZFA)
3674 emit_insn (gen_movdfsisi3_rv32 (dest, high_src, low_src));
3675 else
3676 emit_insn (gen_th_fmv_hw_w_x (dest, high_src, low_src));
3677 return;
3679 if (FP_REG_RTX_P (src))
3681 rtx low_dest = riscv_subword (dest, false);
3682 rtx high_dest = riscv_subword (dest, true);
3684 if (TARGET_ZFA)
3686 emit_insn (gen_movsidf2_low_rv32 (low_dest, src));
3687 emit_insn (gen_movsidf2_high_rv32 (high_dest, src));
3688 return;
3690 else
3692 emit_insn (gen_th_fmv_x_w (low_dest, src));
3693 emit_insn (gen_th_fmv_x_hw (high_dest, src));
3695 return;
3699 /* The operation can be split into two normal moves. Decide in
3700 which order to do them. */
3701 rtx low_dest = riscv_subword (dest, false);
3702 if (REG_P (low_dest) && reg_overlap_mentioned_p (low_dest, src))
3704 riscv_emit_move (riscv_subword (dest, true), riscv_subword (src, true));
3705 riscv_emit_move (low_dest, riscv_subword (src, false));
3707 else
3709 riscv_emit_move (low_dest, riscv_subword (src, false));
3710 riscv_emit_move (riscv_subword (dest, true), riscv_subword (src, true));
3714 /* Return the appropriate instructions to move SRC into DEST. Assume
3715 that SRC is operand 1 and DEST is operand 0. */
3717 const char *
3718 riscv_output_move (rtx dest, rtx src)
3720 enum rtx_code dest_code, src_code;
3721 machine_mode mode;
3722 bool dbl_p;
3723 unsigned width;
3724 const char *insn;
3726 if ((insn = th_output_move (dest, src)))
3727 return insn;
3729 dest_code = GET_CODE (dest);
3730 src_code = GET_CODE (src);
3731 mode = GET_MODE (dest);
3732 dbl_p = (GET_MODE_SIZE (mode).to_constant () == 8);
3733 width = GET_MODE_SIZE (mode).to_constant ();
3735 if (dbl_p && riscv_split_64bit_move_p (dest, src))
3736 return "#";
3738 if (dest_code == REG && GP_REG_P (REGNO (dest)))
3740 if (src_code == REG && FP_REG_P (REGNO (src)))
3741 switch (width)
3743 case 2:
3744 if (TARGET_ZFHMIN)
3745 return "fmv.x.h\t%0,%1";
3746 /* Using fmv.x.s + sign-extend to emulate fmv.x.h. */
3747 return "fmv.x.s\t%0,%1;slli\t%0,%0,16;srai\t%0,%0,16";
3748 case 4:
3749 return "fmv.x.s\t%0,%1";
3750 case 8:
3751 return "fmv.x.d\t%0,%1";
3754 if (src_code == MEM)
3755 switch (width)
3757 case 1: return "lbu\t%0,%1";
3758 case 2: return "lhu\t%0,%1";
3759 case 4: return "lw\t%0,%1";
3760 case 8: return "ld\t%0,%1";
3763 if (src_code == CONST_INT)
3765 if (SMALL_OPERAND (INTVAL (src)) || LUI_OPERAND (INTVAL (src)))
3766 return "li\t%0,%1";
3768 if (TARGET_ZBS
3769 && SINGLE_BIT_MASK_OPERAND (INTVAL (src)))
3770 return "bseti\t%0,zero,%S1";
3772 /* Should never reach here. */
3773 abort ();
3776 if (src_code == HIGH)
3777 return "lui\t%0,%h1";
3779 if (symbolic_operand (src, VOIDmode))
3780 switch (riscv_classify_symbolic_expression (src))
3782 case SYMBOL_GOT_DISP: return "la\t%0,%1";
3783 case SYMBOL_ABSOLUTE: return "lla\t%0,%1";
3784 case SYMBOL_PCREL: return "lla\t%0,%1";
3785 default: gcc_unreachable ();
3788 if ((src_code == REG && GP_REG_P (REGNO (src)))
3789 || (src == CONST0_RTX (mode)))
3791 if (dest_code == REG)
3793 if (GP_REG_P (REGNO (dest)))
3794 return "mv\t%0,%z1";
3796 if (FP_REG_P (REGNO (dest)))
3797 switch (width)
3799 case 2:
3800 if (TARGET_ZFHMIN)
3801 return "fmv.h.x\t%0,%z1";
3802 /* High 16 bits should be all-1, otherwise HW will treated
3803 as a n-bit canonical NaN, but isn't matter for softfloat. */
3804 return "fmv.s.x\t%0,%1";
3805 case 4:
3806 return "fmv.s.x\t%0,%z1";
3807 case 8:
3808 if (TARGET_64BIT)
3809 return "fmv.d.x\t%0,%z1";
3810 /* in RV32, we can emulate fmv.d.x %0, x0 using fcvt.d.w */
3811 gcc_assert (src == CONST0_RTX (mode));
3812 return "fcvt.d.w\t%0,x0";
3815 if (dest_code == MEM)
3816 switch (width)
3818 case 1: return "sb\t%z1,%0";
3819 case 2: return "sh\t%z1,%0";
3820 case 4: return "sw\t%z1,%0";
3821 case 8: return "sd\t%z1,%0";
3824 if (src_code == REG && FP_REG_P (REGNO (src)))
3826 if (dest_code == REG && FP_REG_P (REGNO (dest)))
3827 switch (width)
3829 case 2:
3830 if (TARGET_ZFH)
3831 return "fmv.h\t%0,%1";
3832 return "fmv.s\t%0,%1";
3833 case 4:
3834 return "fmv.s\t%0,%1";
3835 case 8:
3836 return "fmv.d\t%0,%1";
3839 if (dest_code == MEM)
3840 switch (width)
3842 case 2:
3843 return "fsh\t%1,%0";
3844 case 4:
3845 return "fsw\t%1,%0";
3846 case 8:
3847 return "fsd\t%1,%0";
3850 if (dest_code == REG && FP_REG_P (REGNO (dest)))
3852 if (src_code == MEM)
3853 switch (width)
3855 case 2:
3856 return "flh\t%0,%1";
3857 case 4:
3858 return "flw\t%0,%1";
3859 case 8:
3860 return "fld\t%0,%1";
3863 if (src_code == CONST_DOUBLE && satisfies_constraint_zfli (src))
3864 switch (width)
3866 case 2:
3867 return "fli.h\t%0,%1";
3868 case 4:
3869 return "fli.s\t%0,%1";
3870 case 8:
3871 return "fli.d\t%0,%1";
3874 if (dest_code == REG && GP_REG_P (REGNO (dest)) && src_code == CONST_POLY_INT)
3876 /* We only want a single full vector register VLEN read after reload. */
3877 gcc_assert (known_eq (rtx_to_poly_int64 (src), BYTES_PER_RISCV_VECTOR));
3878 return "csrr\t%0,vlenb";
3880 gcc_unreachable ();
3883 const char *
3884 riscv_output_return ()
3886 if (cfun->machine->naked_p)
3887 return "";
3889 return "ret";
3893 /* Return true if CMP1 is a suitable second operand for integer ordering
3894 test CODE. See also the *sCC patterns in riscv.md. */
3896 static bool
3897 riscv_int_order_operand_ok_p (enum rtx_code code, rtx cmp1)
3899 switch (code)
3901 case GT:
3902 case GTU:
3903 return reg_or_0_operand (cmp1, VOIDmode);
3905 case GE:
3906 case GEU:
3907 return cmp1 == const1_rtx;
3909 case LT:
3910 case LTU:
3911 return arith_operand (cmp1, VOIDmode);
3913 case LE:
3914 return sle_operand (cmp1, VOIDmode);
3916 case LEU:
3917 return sleu_operand (cmp1, VOIDmode);
3919 default:
3920 gcc_unreachable ();
3924 /* Return true if *CMP1 (of mode MODE) is a valid second operand for
3925 integer ordering test *CODE, or if an equivalent combination can
3926 be formed by adjusting *CODE and *CMP1. When returning true, update
3927 *CODE and *CMP1 with the chosen code and operand, otherwise leave
3928 them alone. */
3930 static bool
3931 riscv_canonicalize_int_order_test (enum rtx_code *code, rtx *cmp1,
3932 machine_mode mode)
3934 HOST_WIDE_INT plus_one;
3936 if (riscv_int_order_operand_ok_p (*code, *cmp1))
3937 return true;
3939 if (CONST_INT_P (*cmp1))
3940 switch (*code)
3942 case LE:
3943 plus_one = trunc_int_for_mode (UINTVAL (*cmp1) + 1, mode);
3944 if (INTVAL (*cmp1) < plus_one)
3946 *code = LT;
3947 *cmp1 = force_reg (mode, GEN_INT (plus_one));
3948 return true;
3950 break;
3952 case LEU:
3953 plus_one = trunc_int_for_mode (UINTVAL (*cmp1) + 1, mode);
3954 if (plus_one != 0)
3956 *code = LTU;
3957 *cmp1 = force_reg (mode, GEN_INT (plus_one));
3958 return true;
3960 break;
3962 default:
3963 break;
3965 return false;
3968 /* Compare CMP0 and CMP1 using ordering test CODE and store the result
3969 in TARGET. CMP0 and TARGET are register_operands. If INVERT_PTR
3970 is nonnull, it's OK to set TARGET to the inverse of the result and
3971 flip *INVERT_PTR instead. */
3973 static void
3974 riscv_emit_int_order_test (enum rtx_code code, bool *invert_ptr,
3975 rtx target, rtx cmp0, rtx cmp1)
3977 machine_mode mode;
3979 /* First see if there is a RISCV instruction that can do this operation.
3980 If not, try doing the same for the inverse operation. If that also
3981 fails, force CMP1 into a register and try again. */
3982 mode = GET_MODE (cmp0);
3983 if (riscv_canonicalize_int_order_test (&code, &cmp1, mode))
3984 riscv_emit_binary (code, target, cmp0, cmp1);
3985 else
3987 enum rtx_code inv_code = reverse_condition (code);
3988 if (!riscv_canonicalize_int_order_test (&inv_code, &cmp1, mode))
3990 cmp1 = force_reg (mode, cmp1);
3991 riscv_emit_int_order_test (code, invert_ptr, target, cmp0, cmp1);
3993 else if (invert_ptr == 0)
3995 rtx inv_target = riscv_force_binary (word_mode,
3996 inv_code, cmp0, cmp1);
3997 riscv_emit_binary (EQ, target, inv_target, const0_rtx);
3999 else
4001 *invert_ptr = !*invert_ptr;
4002 riscv_emit_binary (inv_code, target, cmp0, cmp1);
4007 /* Return a register that is zero iff CMP0 and CMP1 are equal.
4008 The register will have the same mode as CMP0. */
4010 static rtx
4011 riscv_zero_if_equal (rtx cmp0, rtx cmp1)
4013 if (cmp1 == const0_rtx)
4014 return cmp0;
4016 return expand_binop (GET_MODE (cmp0), sub_optab,
4017 cmp0, cmp1, 0, 0, OPTAB_DIRECT);
4020 /* Helper function for riscv_extend_comparands to Sign-extend the OP.
4021 However if the OP is SI subreg promoted with an inner DI, such as
4022 (subreg/s/v:SI (reg/v:DI) 0)
4023 just peel off the SUBREG to get DI, avoiding extraneous extension. */
4025 static void
4026 riscv_sign_extend_if_not_subreg_prom (rtx *op)
4028 if (GET_CODE (*op) == SUBREG
4029 && SUBREG_PROMOTED_VAR_P (*op)
4030 && SUBREG_PROMOTED_SIGNED_P (*op)
4031 && (GET_MODE_SIZE (GET_MODE (XEXP (*op, 0))).to_constant ()
4032 == GET_MODE_SIZE (word_mode)))
4033 *op = XEXP (*op, 0);
4034 else
4035 *op = gen_rtx_SIGN_EXTEND (word_mode, *op);
4038 /* Sign- or zero-extend OP0 and OP1 for integer comparisons. */
4040 static void
4041 riscv_extend_comparands (rtx_code code, rtx *op0, rtx *op1)
4043 /* Comparisons consider all XLEN bits, so extend sub-XLEN values. */
4044 if (GET_MODE_SIZE (word_mode) > GET_MODE_SIZE (GET_MODE (*op0)).to_constant ())
4046 /* It is more profitable to zero-extend QImode values. But not if the
4047 first operand has already been sign-extended, and the second one is
4048 is a constant or has already been sign-extended also. */
4049 if (unsigned_condition (code) == code
4050 && (GET_MODE (*op0) == QImode
4051 && ! (GET_CODE (*op0) == SUBREG
4052 && SUBREG_PROMOTED_VAR_P (*op0)
4053 && SUBREG_PROMOTED_SIGNED_P (*op0)
4054 && (CONST_INT_P (*op1)
4055 || (GET_CODE (*op1) == SUBREG
4056 && SUBREG_PROMOTED_VAR_P (*op1)
4057 && SUBREG_PROMOTED_SIGNED_P (*op1))))))
4059 *op0 = gen_rtx_ZERO_EXTEND (word_mode, *op0);
4060 if (CONST_INT_P (*op1))
4061 *op1 = GEN_INT ((uint8_t) INTVAL (*op1));
4062 else
4063 *op1 = gen_rtx_ZERO_EXTEND (word_mode, *op1);
4065 else
4067 riscv_sign_extend_if_not_subreg_prom (op0);
4069 if (*op1 != const0_rtx)
4070 riscv_sign_extend_if_not_subreg_prom (op1);
4075 /* Convert a comparison into something that can be used in a branch or
4076 conditional move. On entry, *OP0 and *OP1 are the values being
4077 compared and *CODE is the code used to compare them.
4079 Update *CODE, *OP0 and *OP1 so that they describe the final comparison.
4080 If NEED_EQ_NE_P, then only EQ or NE comparisons against zero are
4081 emitted. */
4083 static void
4084 riscv_emit_int_compare (enum rtx_code *code, rtx *op0, rtx *op1,
4085 bool need_eq_ne_p = false)
4087 if (need_eq_ne_p)
4089 rtx cmp_op0 = *op0;
4090 rtx cmp_op1 = *op1;
4091 if (*code == EQ || *code == NE)
4093 *op0 = riscv_zero_if_equal (cmp_op0, cmp_op1);
4094 *op1 = const0_rtx;
4095 return;
4097 gcc_unreachable ();
4100 if (splittable_const_int_operand (*op1, VOIDmode))
4102 HOST_WIDE_INT rhs = INTVAL (*op1);
4104 if (*code == EQ || *code == NE)
4106 /* Convert e.g. OP0 == 2048 into OP0 - 2048 == 0. */
4107 if (SMALL_OPERAND (-rhs))
4109 *op0 = riscv_force_binary (GET_MODE (*op0), PLUS, *op0,
4110 GEN_INT (-rhs));
4111 *op1 = const0_rtx;
4114 else
4116 static const enum rtx_code mag_comparisons[][2] = {
4117 {LEU, LTU}, {GTU, GEU}, {LE, LT}, {GT, GE}
4120 /* Convert e.g. (OP0 <= 0xFFF) into (OP0 < 0x1000). */
4121 for (size_t i = 0; i < ARRAY_SIZE (mag_comparisons); i++)
4123 HOST_WIDE_INT new_rhs;
4124 bool increment = *code == mag_comparisons[i][0];
4125 bool decrement = *code == mag_comparisons[i][1];
4126 if (!increment && !decrement)
4127 continue;
4129 new_rhs = rhs + (increment ? 1 : -1);
4130 new_rhs = trunc_int_for_mode (new_rhs, GET_MODE (*op0));
4131 if (riscv_integer_cost (new_rhs) < riscv_integer_cost (rhs)
4132 && (rhs < 0) == (new_rhs < 0))
4134 *op1 = GEN_INT (new_rhs);
4135 *code = mag_comparisons[i][increment];
4137 break;
4142 riscv_extend_comparands (*code, op0, op1);
4144 *op0 = force_reg (word_mode, *op0);
4145 if (*op1 != const0_rtx)
4146 *op1 = force_reg (word_mode, *op1);
4149 /* Like riscv_emit_int_compare, but for floating-point comparisons. */
4151 static void
4152 riscv_emit_float_compare (enum rtx_code *code, rtx *op0, rtx *op1,
4153 bool *invert_ptr = nullptr)
4155 rtx tmp0, tmp1, cmp_op0 = *op0, cmp_op1 = *op1;
4156 enum rtx_code fp_code = *code;
4157 *code = NE;
4159 switch (fp_code)
4161 case UNORDERED:
4162 *code = EQ;
4163 /* Fall through. */
4165 case ORDERED:
4166 /* a == a && b == b */
4167 tmp0 = riscv_force_binary (word_mode, EQ, cmp_op0, cmp_op0);
4168 tmp1 = riscv_force_binary (word_mode, EQ, cmp_op1, cmp_op1);
4169 *op0 = riscv_force_binary (word_mode, AND, tmp0, tmp1);
4170 *op1 = const0_rtx;
4171 break;
4173 case UNEQ:
4174 /* ordered(a, b) > (a == b) */
4175 *code = EQ;
4176 tmp0 = riscv_force_binary (word_mode, EQ, cmp_op0, cmp_op0);
4177 tmp1 = riscv_force_binary (word_mode, EQ, cmp_op1, cmp_op1);
4178 *op0 = riscv_force_binary (word_mode, AND, tmp0, tmp1);
4179 *op1 = riscv_force_binary (word_mode, EQ, cmp_op0, cmp_op1);
4180 break;
4182 #define UNORDERED_COMPARISON(CODE, CMP) \
4183 case CODE: \
4184 *code = EQ; \
4185 *op0 = gen_reg_rtx (word_mode); \
4186 if (GET_MODE (cmp_op0) == SFmode && TARGET_64BIT) \
4187 emit_insn (gen_f##CMP##_quietsfdi4 (*op0, cmp_op0, cmp_op1)); \
4188 else if (GET_MODE (cmp_op0) == SFmode) \
4189 emit_insn (gen_f##CMP##_quietsfsi4 (*op0, cmp_op0, cmp_op1)); \
4190 else if (GET_MODE (cmp_op0) == DFmode && TARGET_64BIT) \
4191 emit_insn (gen_f##CMP##_quietdfdi4 (*op0, cmp_op0, cmp_op1)); \
4192 else if (GET_MODE (cmp_op0) == DFmode) \
4193 emit_insn (gen_f##CMP##_quietdfsi4 (*op0, cmp_op0, cmp_op1)); \
4194 else if (GET_MODE (cmp_op0) == HFmode && TARGET_64BIT) \
4195 emit_insn (gen_f##CMP##_quiethfdi4 (*op0, cmp_op0, cmp_op1)); \
4196 else if (GET_MODE (cmp_op0) == HFmode) \
4197 emit_insn (gen_f##CMP##_quiethfsi4 (*op0, cmp_op0, cmp_op1)); \
4198 else \
4199 gcc_unreachable (); \
4200 *op1 = const0_rtx; \
4201 break;
4203 case UNLT:
4204 std::swap (cmp_op0, cmp_op1);
4205 gcc_fallthrough ();
4207 UNORDERED_COMPARISON(UNGT, le)
4209 case UNLE:
4210 std::swap (cmp_op0, cmp_op1);
4211 gcc_fallthrough ();
4213 UNORDERED_COMPARISON(UNGE, lt)
4214 #undef UNORDERED_COMPARISON
4216 case NE:
4217 fp_code = EQ;
4218 if (invert_ptr != nullptr)
4219 *invert_ptr = !*invert_ptr;
4220 else
4222 cmp_op0 = riscv_force_binary (word_mode, fp_code, cmp_op0, cmp_op1);
4223 cmp_op1 = const0_rtx;
4225 gcc_fallthrough ();
4227 case EQ:
4228 case LE:
4229 case LT:
4230 case GE:
4231 case GT:
4232 /* We have instructions for these cases. */
4233 *code = fp_code;
4234 *op0 = cmp_op0;
4235 *op1 = cmp_op1;
4236 break;
4238 case LTGT:
4239 /* (a < b) | (a > b) */
4240 tmp0 = riscv_force_binary (word_mode, LT, cmp_op0, cmp_op1);
4241 tmp1 = riscv_force_binary (word_mode, GT, cmp_op0, cmp_op1);
4242 *op0 = riscv_force_binary (word_mode, IOR, tmp0, tmp1);
4243 *op1 = const0_rtx;
4244 break;
4246 default:
4247 gcc_unreachable ();
4251 /* CODE-compare OP0 and OP1. Store the result in TARGET. */
4253 void
4254 riscv_expand_int_scc (rtx target, enum rtx_code code, rtx op0, rtx op1, bool *invert_ptr)
4256 riscv_extend_comparands (code, &op0, &op1);
4257 op0 = force_reg (word_mode, op0);
4259 if (code == EQ || code == NE)
4261 rtx zie = riscv_zero_if_equal (op0, op1);
4262 riscv_emit_binary (code, target, zie, const0_rtx);
4264 else
4265 riscv_emit_int_order_test (code, invert_ptr, target, op0, op1);
4268 /* Like riscv_expand_int_scc, but for floating-point comparisons. */
4270 void
4271 riscv_expand_float_scc (rtx target, enum rtx_code code, rtx op0, rtx op1,
4272 bool *invert_ptr)
4274 riscv_emit_float_compare (&code, &op0, &op1, invert_ptr);
4276 machine_mode mode = GET_MODE (target);
4277 if (mode != word_mode)
4279 rtx cmp = riscv_force_binary (word_mode, code, op0, op1);
4280 riscv_emit_set (target, lowpart_subreg (mode, cmp, word_mode));
4282 else
4283 riscv_emit_binary (code, target, op0, op1);
4286 /* Jump to LABEL if (CODE OP0 OP1) holds. */
4288 void
4289 riscv_expand_conditional_branch (rtx label, rtx_code code, rtx op0, rtx op1)
4291 if (FLOAT_MODE_P (GET_MODE (op1)))
4292 riscv_emit_float_compare (&code, &op0, &op1);
4293 else
4294 riscv_emit_int_compare (&code, &op0, &op1);
4296 if (FLOAT_MODE_P (GET_MODE (op0)))
4298 op0 = riscv_force_binary (word_mode, code, op0, op1);
4299 op1 = const0_rtx;
4300 code = NE;
4303 rtx condition = gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
4304 emit_jump_insn (gen_condjump (condition, label));
4307 /* Emit a cond move: If OP holds, move CONS to DEST; else move ALT to DEST.
4308 Return 0 if expansion failed. */
4310 bool
4311 riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt)
4313 machine_mode mode = GET_MODE (dest);
4314 rtx_code code = GET_CODE (op);
4315 rtx op0 = XEXP (op, 0);
4316 rtx op1 = XEXP (op, 1);
4318 if (((TARGET_ZICOND_LIKE
4319 || (arith_operand (cons, mode) && arith_operand (alt, mode)))
4320 && (GET_MODE_CLASS (mode) == MODE_INT))
4321 || TARGET_SFB_ALU || TARGET_XTHEADCONDMOV)
4323 machine_mode mode0 = GET_MODE (op0);
4324 machine_mode mode1 = GET_MODE (op1);
4326 /* An integer comparison must be comparing WORD_MODE objects. We
4327 must enforce that so that we don't strip away a sign_extension
4328 thinking it is unnecessary. We might consider using
4329 riscv_extend_operands if they are not already properly extended. */
4330 if ((INTEGRAL_MODE_P (mode0) && mode0 != word_mode)
4331 || (INTEGRAL_MODE_P (mode1) && mode1 != word_mode))
4332 return false;
4334 /* In the fallback generic case use MODE rather than WORD_MODE for
4335 the output of the SCC instruction, to match the mode of the NEG
4336 operation below. The output of SCC is 0 or 1 boolean, so it is
4337 valid for input in any scalar integer mode. */
4338 rtx tmp = gen_reg_rtx ((TARGET_ZICOND_LIKE
4339 || TARGET_SFB_ALU || TARGET_XTHEADCONDMOV)
4340 ? word_mode : mode);
4341 bool invert = false;
4343 /* Canonicalize the comparison. It must be an equality comparison
4344 of integer operands, or with SFB it can be any comparison of
4345 integer operands. If it isn't, then emit an SCC instruction
4346 so that we can then use an equality comparison against zero. */
4347 if ((!TARGET_SFB_ALU && !equality_operator (op, VOIDmode))
4348 || !INTEGRAL_MODE_P (mode0))
4350 bool *invert_ptr = nullptr;
4352 /* If riscv_expand_int_scc inverts the condition, then it will
4353 flip the value of INVERT. We need to know where so that
4354 we can adjust it for our needs. */
4355 if (code == LE || code == LEU || code == GE || code == GEU)
4356 invert_ptr = &invert;
4358 /* Emit an SCC-like instruction into a temporary so that we can
4359 use an EQ/NE comparison. We can support both FP and integer
4360 conditional moves. */
4361 if (INTEGRAL_MODE_P (mode0))
4362 riscv_expand_int_scc (tmp, code, op0, op1, invert_ptr);
4363 else if (FLOAT_MODE_P (mode0)
4364 && fp_scc_comparison (op, GET_MODE (op)))
4365 riscv_expand_float_scc (tmp, code, op0, op1, &invert);
4366 else
4367 return false;
4369 op = gen_rtx_fmt_ee (invert ? EQ : NE, mode, tmp, const0_rtx);
4371 /* We've generated a new comparison. Update the local variables. */
4372 code = GET_CODE (op);
4373 op0 = XEXP (op, 0);
4374 op1 = XEXP (op, 1);
4376 else if (!TARGET_ZICOND_LIKE && !TARGET_SFB_ALU && !TARGET_XTHEADCONDMOV)
4377 riscv_expand_int_scc (tmp, code, op0, op1, &invert);
4379 if (TARGET_SFB_ALU || TARGET_XTHEADCONDMOV)
4381 riscv_emit_int_compare (&code, &op0, &op1, !TARGET_SFB_ALU);
4382 rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
4384 /* The expander is a bit loose in its specification of the true
4385 arm of the conditional move. That allows us to support more
4386 cases for extensions which are more general than SFB. But
4387 does mean we need to force CONS into a register at this point. */
4388 cons = force_reg (mode, cons);
4389 /* With XTheadCondMov we need to force ALT into a register too. */
4390 alt = force_reg (mode, alt);
4391 emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (mode, cond,
4392 cons, alt)));
4393 return true;
4395 else if (!TARGET_ZICOND_LIKE)
4397 if (invert)
4398 std::swap (cons, alt);
4400 rtx reg1 = gen_reg_rtx (mode);
4401 rtx reg2 = gen_reg_rtx (mode);
4402 rtx reg3 = gen_reg_rtx (mode);
4403 rtx reg4 = gen_reg_rtx (mode);
4405 riscv_emit_unary (NEG, reg1, tmp);
4406 riscv_emit_binary (AND, reg2, reg1, cons);
4407 riscv_emit_unary (NOT, reg3, reg1);
4408 riscv_emit_binary (AND, reg4, reg3, alt);
4409 riscv_emit_binary (IOR, dest, reg2, reg4);
4410 return true;
4412 /* 0, reg or 0, imm */
4413 else if (cons == CONST0_RTX (mode)
4414 && (REG_P (alt)
4415 || (CONST_INT_P (alt) && alt != CONST0_RTX (mode))))
4417 riscv_emit_int_compare (&code, &op0, &op1, true);
4418 rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
4419 alt = force_reg (mode, alt);
4420 emit_insn (gen_rtx_SET (dest,
4421 gen_rtx_IF_THEN_ELSE (mode, cond,
4422 cons, alt)));
4423 return true;
4425 /* imm, imm */
4426 else if (CONST_INT_P (cons) && cons != CONST0_RTX (mode)
4427 && CONST_INT_P (alt) && alt != CONST0_RTX (mode))
4429 riscv_emit_int_compare (&code, &op0, &op1, true);
4430 rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
4431 HOST_WIDE_INT t = INTVAL (alt) - INTVAL (cons);
4432 alt = force_reg (mode, gen_int_mode (t, mode));
4433 emit_insn (gen_rtx_SET (dest,
4434 gen_rtx_IF_THEN_ELSE (mode, cond,
4435 CONST0_RTX (mode),
4436 alt)));
4437 /* CONS might not fit into a signed 12 bit immediate suitable
4438 for an addi instruction. If that's the case, force it
4439 into a register. */
4440 if (!SMALL_OPERAND (INTVAL (cons)))
4441 cons = force_reg (mode, cons);
4442 riscv_emit_binary (PLUS, dest, dest, cons);
4443 return true;
4445 /* imm, reg */
4446 else if (CONST_INT_P (cons) && cons != CONST0_RTX (mode) && REG_P (alt))
4448 /* Optimize for register value of 0. */
4449 if (code == NE && rtx_equal_p (op0, alt) && op1 == CONST0_RTX (mode))
4451 rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
4452 cons = force_reg (mode, cons);
4453 emit_insn (gen_rtx_SET (dest,
4454 gen_rtx_IF_THEN_ELSE (mode, cond,
4455 cons, alt)));
4456 return true;
4459 riscv_emit_int_compare (&code, &op0, &op1, true);
4460 rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
4462 rtx temp1 = gen_reg_rtx (mode);
4463 rtx temp2 = gen_int_mode (-1 * INTVAL (cons), mode);
4465 /* TEMP2 and/or CONS might not fit into a signed 12 bit immediate
4466 suitable for an addi instruction. If that's the case, force it
4467 into a register. */
4468 if (!SMALL_OPERAND (INTVAL (temp2)))
4469 temp2 = force_reg (mode, temp2);
4470 if (!SMALL_OPERAND (INTVAL (cons)))
4471 cons = force_reg (mode, cons);
4473 riscv_emit_binary (PLUS, temp1, alt, temp2);
4474 emit_insn (gen_rtx_SET (dest,
4475 gen_rtx_IF_THEN_ELSE (mode, cond,
4476 CONST0_RTX (mode),
4477 temp1)));
4478 riscv_emit_binary (PLUS, dest, dest, cons);
4479 return true;
4481 /* reg, 0 or imm, 0 */
4482 else if ((REG_P (cons)
4483 || (CONST_INT_P (cons) && cons != CONST0_RTX (mode)))
4484 && alt == CONST0_RTX (mode))
4486 riscv_emit_int_compare (&code, &op0, &op1, true);
4487 rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
4488 cons = force_reg (mode, cons);
4489 emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (mode, cond,
4490 cons, alt)));
4491 return true;
4493 /* reg, imm */
4494 else if (REG_P (cons) && CONST_INT_P (alt) && alt != CONST0_RTX (mode))
4496 /* Optimize for register value of 0. */
4497 if (code == EQ && rtx_equal_p (op0, cons) && op1 == CONST0_RTX (mode))
4499 rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
4500 alt = force_reg (mode, alt);
4501 emit_insn (gen_rtx_SET (dest,
4502 gen_rtx_IF_THEN_ELSE (mode, cond,
4503 cons, alt)));
4504 return true;
4507 riscv_emit_int_compare (&code, &op0, &op1, true);
4508 rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
4510 rtx temp1 = gen_reg_rtx (mode);
4511 rtx temp2 = gen_int_mode (-1 * INTVAL (alt), mode);
4513 /* TEMP2 and/or ALT might not fit into a signed 12 bit immediate
4514 suitable for an addi instruction. If that's the case, force it
4515 into a register. */
4516 if (!SMALL_OPERAND (INTVAL (temp2)))
4517 temp2 = force_reg (mode, temp2);
4518 if (!SMALL_OPERAND (INTVAL (alt)))
4519 alt = force_reg (mode, alt);
4521 riscv_emit_binary (PLUS, temp1, cons, temp2);
4522 emit_insn (gen_rtx_SET (dest,
4523 gen_rtx_IF_THEN_ELSE (mode, cond,
4524 temp1,
4525 CONST0_RTX (mode))));
4526 riscv_emit_binary (PLUS, dest, dest, alt);
4527 return true;
4529 /* reg, reg */
4530 else if (REG_P (cons) && REG_P (alt))
4532 if ((code == EQ && rtx_equal_p (cons, op0))
4533 || (code == NE && rtx_equal_p (alt, op0)))
4535 rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
4536 if (!rtx_equal_p (cons, op0))
4537 std::swap (alt, cons);
4538 alt = force_reg (mode, alt);
4539 emit_insn (gen_rtx_SET (dest,
4540 gen_rtx_IF_THEN_ELSE (mode, cond,
4541 cons, alt)));
4542 return true;
4545 rtx reg1 = gen_reg_rtx (mode);
4546 rtx reg2 = gen_reg_rtx (mode);
4547 riscv_emit_int_compare (&code, &op0, &op1, true);
4548 rtx cond1 = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
4549 rtx cond2 = gen_rtx_fmt_ee (code == NE ? EQ : NE,
4550 GET_MODE (op0), op0, op1);
4551 emit_insn (gen_rtx_SET (reg2,
4552 gen_rtx_IF_THEN_ELSE (mode, cond2,
4553 CONST0_RTX (mode),
4554 cons)));
4555 emit_insn (gen_rtx_SET (reg1,
4556 gen_rtx_IF_THEN_ELSE (mode, cond1,
4557 CONST0_RTX (mode),
4558 alt)));
4559 riscv_emit_binary (IOR, dest, reg1, reg2);
4560 return true;
4564 return false;
4567 /* Implement TARGET_FUNCTION_ARG_BOUNDARY. Every parameter gets at
4568 least PARM_BOUNDARY bits of alignment, but will be given anything up
4569 to PREFERRED_STACK_BOUNDARY bits if the type requires it. */
4571 static unsigned int
4572 riscv_function_arg_boundary (machine_mode mode, const_tree type)
4574 unsigned int alignment;
4576 /* Use natural alignment if the type is not aggregate data. */
4577 if (type && !AGGREGATE_TYPE_P (type))
4578 alignment = TYPE_ALIGN (TYPE_MAIN_VARIANT (type));
4579 else
4580 alignment = type ? TYPE_ALIGN (type) : GET_MODE_ALIGNMENT (mode);
4582 return MIN (PREFERRED_STACK_BOUNDARY, MAX (PARM_BOUNDARY, alignment));
4585 /* If MODE represents an argument that can be passed or returned in
4586 floating-point registers, return the number of registers, else 0. */
4588 static unsigned
4589 riscv_pass_mode_in_fpr_p (machine_mode mode)
4591 if (GET_MODE_UNIT_SIZE (mode) <= UNITS_PER_FP_ARG)
4593 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
4594 return 1;
4596 if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
4597 return 2;
4600 return 0;
4603 typedef struct {
4604 const_tree type;
4605 HOST_WIDE_INT offset;
4606 } riscv_aggregate_field;
4608 /* Identify subfields of aggregates that are candidates for passing in
4609 floating-point registers. */
4611 static int
4612 riscv_flatten_aggregate_field (const_tree type,
4613 riscv_aggregate_field fields[2],
4614 int n, HOST_WIDE_INT offset,
4615 bool ignore_zero_width_bit_field_p)
4617 switch (TREE_CODE (type))
4619 case RECORD_TYPE:
4620 /* Can't handle incomplete types nor sizes that are not fixed. */
4621 if (!COMPLETE_TYPE_P (type)
4622 || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
4623 || !tree_fits_uhwi_p (TYPE_SIZE (type)))
4624 return -1;
4626 for (tree f = TYPE_FIELDS (type); f; f = DECL_CHAIN (f))
4627 if (TREE_CODE (f) == FIELD_DECL)
4629 if (!TYPE_P (TREE_TYPE (f)))
4630 return -1;
4632 /* The C++ front end strips zero-length bit-fields from structs.
4633 So we need to ignore them in the C front end to make C code
4634 compatible with C++ code. */
4635 if (ignore_zero_width_bit_field_p
4636 && DECL_BIT_FIELD (f)
4637 && (DECL_SIZE (f) == NULL_TREE
4638 || integer_zerop (DECL_SIZE (f))))
4640 else
4642 HOST_WIDE_INT pos = offset + int_byte_position (f);
4643 n = riscv_flatten_aggregate_field (TREE_TYPE (f),
4644 fields, n, pos,
4645 ignore_zero_width_bit_field_p);
4647 if (n < 0)
4648 return -1;
4650 return n;
4652 case ARRAY_TYPE:
4654 HOST_WIDE_INT n_elts;
4655 riscv_aggregate_field subfields[2];
4656 tree index = TYPE_DOMAIN (type);
4657 tree elt_size = TYPE_SIZE_UNIT (TREE_TYPE (type));
4658 int n_subfields = riscv_flatten_aggregate_field (TREE_TYPE (type),
4659 subfields, 0, offset,
4660 ignore_zero_width_bit_field_p);
4662 /* Can't handle incomplete types nor sizes that are not fixed. */
4663 if (n_subfields <= 0
4664 || !COMPLETE_TYPE_P (type)
4665 || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
4666 || !index
4667 || !TYPE_MAX_VALUE (index)
4668 || !tree_fits_uhwi_p (TYPE_MAX_VALUE (index))
4669 || !TYPE_MIN_VALUE (index)
4670 || !tree_fits_uhwi_p (TYPE_MIN_VALUE (index))
4671 || !tree_fits_uhwi_p (elt_size))
4672 return -1;
4674 n_elts = 1 + tree_to_uhwi (TYPE_MAX_VALUE (index))
4675 - tree_to_uhwi (TYPE_MIN_VALUE (index));
4676 gcc_assert (n_elts >= 0);
4678 for (HOST_WIDE_INT i = 0; i < n_elts; i++)
4679 for (int j = 0; j < n_subfields; j++)
4681 if (n >= 2)
4682 return -1;
4684 fields[n] = subfields[j];
4685 fields[n++].offset += i * tree_to_uhwi (elt_size);
4688 return n;
4691 case COMPLEX_TYPE:
4693 /* Complex type need consume 2 field, so n must be 0. */
4694 if (n != 0)
4695 return -1;
4697 HOST_WIDE_INT elt_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (type))).to_constant ();
4699 if (elt_size <= UNITS_PER_FP_ARG)
4701 fields[0].type = TREE_TYPE (type);
4702 fields[0].offset = offset;
4703 fields[1].type = TREE_TYPE (type);
4704 fields[1].offset = offset + elt_size;
4706 return 2;
4709 return -1;
4712 default:
4713 if (n < 2
4714 && ((SCALAR_FLOAT_TYPE_P (type)
4715 && GET_MODE_SIZE (TYPE_MODE (type)).to_constant () <= UNITS_PER_FP_ARG)
4716 || (INTEGRAL_TYPE_P (type)
4717 && GET_MODE_SIZE (TYPE_MODE (type)).to_constant () <= UNITS_PER_WORD)))
4719 fields[n].type = type;
4720 fields[n].offset = offset;
4721 return n + 1;
4723 else
4724 return -1;
4728 /* Identify candidate aggregates for passing in floating-point registers.
4729 Candidates have at most two fields after flattening. */
4731 static int
4732 riscv_flatten_aggregate_argument (const_tree type,
4733 riscv_aggregate_field fields[2],
4734 bool ignore_zero_width_bit_field_p)
4736 if (!type || TREE_CODE (type) != RECORD_TYPE)
4737 return -1;
4739 return riscv_flatten_aggregate_field (type, fields, 0, 0,
4740 ignore_zero_width_bit_field_p);
4743 /* See whether TYPE is a record whose fields should be returned in one or
4744 two floating-point registers. If so, populate FIELDS accordingly. */
4746 static unsigned
4747 riscv_pass_aggregate_in_fpr_pair_p (const_tree type,
4748 riscv_aggregate_field fields[2])
4750 static int warned = 0;
4752 /* This is the old ABI, which differs for C++ and C. */
4753 int n_old = riscv_flatten_aggregate_argument (type, fields, false);
4754 for (int i = 0; i < n_old; i++)
4755 if (!SCALAR_FLOAT_TYPE_P (fields[i].type))
4757 n_old = -1;
4758 break;
4761 /* This is the new ABI, which is the same for C++ and C. */
4762 int n_new = riscv_flatten_aggregate_argument (type, fields, true);
4763 for (int i = 0; i < n_new; i++)
4764 if (!SCALAR_FLOAT_TYPE_P (fields[i].type))
4766 n_new = -1;
4767 break;
4770 if ((n_old != n_new) && (warned == 0))
4772 warning (OPT_Wpsabi, "ABI for flattened struct with zero-length "
4773 "bit-fields changed in GCC 10");
4774 warned = 1;
4777 return n_new > 0 ? n_new : 0;
4780 /* See whether TYPE is a record whose fields should be returned in one or
4781 floating-point register and one integer register. If so, populate
4782 FIELDS accordingly. */
4784 static bool
4785 riscv_pass_aggregate_in_fpr_and_gpr_p (const_tree type,
4786 riscv_aggregate_field fields[2])
4788 static int warned = 0;
4790 /* This is the old ABI, which differs for C++ and C. */
4791 unsigned num_int_old = 0, num_float_old = 0;
4792 int n_old = riscv_flatten_aggregate_argument (type, fields, false);
4793 for (int i = 0; i < n_old; i++)
4795 num_float_old += SCALAR_FLOAT_TYPE_P (fields[i].type);
4796 num_int_old += INTEGRAL_TYPE_P (fields[i].type);
4799 /* This is the new ABI, which is the same for C++ and C. */
4800 unsigned num_int_new = 0, num_float_new = 0;
4801 int n_new = riscv_flatten_aggregate_argument (type, fields, true);
4802 for (int i = 0; i < n_new; i++)
4804 num_float_new += SCALAR_FLOAT_TYPE_P (fields[i].type);
4805 num_int_new += INTEGRAL_TYPE_P (fields[i].type);
4808 if (((num_int_old == 1 && num_float_old == 1
4809 && (num_int_old != num_int_new || num_float_old != num_float_new))
4810 || (num_int_new == 1 && num_float_new == 1
4811 && (num_int_old != num_int_new || num_float_old != num_float_new)))
4812 && (warned == 0))
4814 warning (OPT_Wpsabi, "ABI for flattened struct with zero-length "
4815 "bit-fields changed in GCC 10");
4816 warned = 1;
4819 return num_int_new == 1 && num_float_new == 1;
4822 /* Return the representation of an argument passed or returned in an FPR
4823 when the value has mode VALUE_MODE and the type has TYPE_MODE. The
4824 two modes may be different for structures like:
4826 struct __attribute__((packed)) foo { float f; }
4828 where the SFmode value "f" is passed in REGNO but the struct itself
4829 has mode BLKmode. */
4831 static rtx
4832 riscv_pass_fpr_single (machine_mode type_mode, unsigned regno,
4833 machine_mode value_mode,
4834 HOST_WIDE_INT offset)
4836 rtx x = gen_rtx_REG (value_mode, regno);
4838 if (type_mode != value_mode)
4840 x = gen_rtx_EXPR_LIST (VOIDmode, x, GEN_INT (offset));
4841 x = gen_rtx_PARALLEL (type_mode, gen_rtvec (1, x));
4843 return x;
4846 /* Pass or return a composite value in the FPR pair REGNO and REGNO + 1.
4847 MODE is the mode of the composite. MODE1 and OFFSET1 are the mode and
4848 byte offset for the first value, likewise MODE2 and OFFSET2 for the
4849 second value. */
4851 static rtx
4852 riscv_pass_fpr_pair (machine_mode mode, unsigned regno1,
4853 machine_mode mode1, HOST_WIDE_INT offset1,
4854 unsigned regno2, machine_mode mode2,
4855 HOST_WIDE_INT offset2)
4857 return gen_rtx_PARALLEL
4858 (mode,
4859 gen_rtvec (2,
4860 gen_rtx_EXPR_LIST (VOIDmode,
4861 gen_rtx_REG (mode1, regno1),
4862 GEN_INT (offset1)),
4863 gen_rtx_EXPR_LIST (VOIDmode,
4864 gen_rtx_REG (mode2, regno2),
4865 GEN_INT (offset2))));
4868 /* Initialize a variable CUM of type CUMULATIVE_ARGS
4869 for a call to a function whose data type is FNTYPE.
4870 For a library call, FNTYPE is 0. */
4872 void
4873 riscv_init_cumulative_args (CUMULATIVE_ARGS *cum,
4874 tree fntype ATTRIBUTE_UNUSED,
4875 rtx libname ATTRIBUTE_UNUSED,
4876 tree fndecl,
4877 int caller ATTRIBUTE_UNUSED)
4879 memset (cum, 0, sizeof (*cum));
4881 if (fntype)
4882 cum->variant_cc = (riscv_cc) fntype_abi (fntype).id ();
4883 else
4884 cum->variant_cc = RISCV_CC_BASE;
4887 /* Return true if TYPE is a vector type that can be passed in vector registers.
4890 static bool
4891 riscv_vector_type_p (const_tree type)
4893 /* Currently, only builtin scalabler vector type is allowed, in the future,
4894 more vector types may be allowed, such as GNU vector type, etc. */
4895 return riscv_vector::builtin_type_p (type);
4898 static unsigned int
4899 riscv_hard_regno_nregs (unsigned int regno, machine_mode mode);
4901 /* Subroutine of riscv_get_arg_info. */
4903 static rtx
4904 riscv_get_vector_arg (struct riscv_arg_info *info, const CUMULATIVE_ARGS *cum,
4905 machine_mode mode, bool return_p)
4907 gcc_assert (riscv_v_ext_mode_p (mode));
4909 info->mr_offset = cum->num_mrs;
4910 if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL)
4912 /* For scalable mask return value. */
4913 if (return_p)
4914 return gen_rtx_REG (mode, V_REG_FIRST);
4916 /* For the first scalable mask argument. */
4917 if (info->mr_offset < MAX_ARGS_IN_MASK_REGISTERS)
4919 info->num_mrs = 1;
4920 return gen_rtx_REG (mode, V_REG_FIRST);
4922 else
4924 /* Rest scalable mask arguments are treated as scalable data
4925 arguments. */
4929 /* The number and alignment of vector registers need for this scalable vector
4930 argument. When the mode size is less than a full vector, we use 1 vector
4931 register to pass. Just call TARGET_HARD_REGNO_NREGS for the number
4932 information. */
4933 int nregs = riscv_hard_regno_nregs (V_ARG_FIRST, mode);
4934 int LMUL = riscv_v_ext_tuple_mode_p (mode)
4935 ? nregs / riscv_vector::get_nf (mode)
4936 : nregs;
4937 int arg_reg_start = V_ARG_FIRST - V_REG_FIRST;
4938 int arg_reg_end = V_ARG_LAST - V_REG_FIRST;
4939 int aligned_reg_start = ROUND_UP (arg_reg_start, LMUL);
4941 /* For scalable data and scalable tuple return value. */
4942 if (return_p)
4943 return gen_rtx_REG (mode, aligned_reg_start + V_REG_FIRST);
4945 /* Iterate through the USED_VRS array to find vector register groups that have
4946 not been allocated and the first register is aligned with LMUL. */
4947 for (int i = aligned_reg_start; i + nregs - 1 <= arg_reg_end; i += LMUL)
4949 /* The index in USED_VRS array. */
4950 int idx = i - arg_reg_start;
4951 /* Find the first register unused. */
4952 if (!cum->used_vrs[idx])
4954 bool find_set = true;
4955 /* Ensure there are NREGS continuous unused registers. */
4956 for (int j = 1; j < nregs; j++)
4957 if (cum->used_vrs[idx + j])
4959 find_set = false;
4960 /* Update I to the last aligned register which
4961 cannot be used and the next iteration will add
4962 LMUL step to I. */
4963 i += (j / LMUL) * LMUL;
4964 break;
4967 if (find_set)
4969 info->num_vrs = nregs;
4970 info->vr_offset = idx;
4971 return gen_rtx_REG (mode, i + V_REG_FIRST);
4976 return NULL_RTX;
4979 /* Fill INFO with information about a single argument, and return an RTL
4980 pattern to pass or return the argument. Return NULL_RTX if argument cannot
4981 pass or return in registers, then the argument may be passed by reference or
4982 through the stack or . CUM is the cumulative state for earlier arguments.
4983 MODE is the mode of this argument and TYPE is its type (if known). NAMED is
4984 true if this is a named (fixed) argument rather than a variable one. RETURN_P
4985 is true if returning the argument, or false if passing the argument. */
4987 static rtx
4988 riscv_get_arg_info (struct riscv_arg_info *info, const CUMULATIVE_ARGS *cum,
4989 machine_mode mode, const_tree type, bool named,
4990 bool return_p)
4992 unsigned num_bytes, num_words;
4993 unsigned fpr_base = return_p ? FP_RETURN : FP_ARG_FIRST;
4994 unsigned gpr_base = return_p ? GP_RETURN : GP_ARG_FIRST;
4995 unsigned alignment = riscv_function_arg_boundary (mode, type);
4997 memset (info, 0, sizeof (*info));
4998 info->gpr_offset = cum->num_gprs;
4999 info->fpr_offset = cum->num_fprs;
5001 /* When disable vector_abi or scalable vector argument is anonymous, this
5002 argument is passed by reference. */
5003 if (riscv_v_ext_mode_p (mode) && (!riscv_vector_abi || !named))
5004 return NULL_RTX;
5006 if (named)
5008 riscv_aggregate_field fields[2];
5009 unsigned fregno = fpr_base + info->fpr_offset;
5010 unsigned gregno = gpr_base + info->gpr_offset;
5012 /* Pass one- or two-element floating-point aggregates in FPRs. */
5013 if ((info->num_fprs = riscv_pass_aggregate_in_fpr_pair_p (type, fields))
5014 && info->fpr_offset + info->num_fprs <= MAX_ARGS_IN_REGISTERS)
5015 switch (info->num_fprs)
5017 case 1:
5018 return riscv_pass_fpr_single (mode, fregno,
5019 TYPE_MODE (fields[0].type),
5020 fields[0].offset);
5022 case 2:
5023 return riscv_pass_fpr_pair (mode, fregno,
5024 TYPE_MODE (fields[0].type),
5025 fields[0].offset,
5026 fregno + 1,
5027 TYPE_MODE (fields[1].type),
5028 fields[1].offset);
5030 default:
5031 gcc_unreachable ();
5034 /* Pass real and complex floating-point numbers in FPRs. */
5035 if ((info->num_fprs = riscv_pass_mode_in_fpr_p (mode))
5036 && info->fpr_offset + info->num_fprs <= MAX_ARGS_IN_REGISTERS)
5037 switch (GET_MODE_CLASS (mode))
5039 case MODE_FLOAT:
5040 return gen_rtx_REG (mode, fregno);
5042 case MODE_COMPLEX_FLOAT:
5043 return riscv_pass_fpr_pair (mode, fregno, GET_MODE_INNER (mode), 0,
5044 fregno + 1, GET_MODE_INNER (mode),
5045 GET_MODE_UNIT_SIZE (mode));
5047 default:
5048 gcc_unreachable ();
5051 /* Pass structs with one float and one integer in an FPR and a GPR. */
5052 if (riscv_pass_aggregate_in_fpr_and_gpr_p (type, fields)
5053 && info->gpr_offset < MAX_ARGS_IN_REGISTERS
5054 && info->fpr_offset < MAX_ARGS_IN_REGISTERS)
5056 info->num_gprs = 1;
5057 info->num_fprs = 1;
5059 if (!SCALAR_FLOAT_TYPE_P (fields[0].type))
5060 std::swap (fregno, gregno);
5062 return riscv_pass_fpr_pair (mode, fregno, TYPE_MODE (fields[0].type),
5063 fields[0].offset,
5064 gregno, TYPE_MODE (fields[1].type),
5065 fields[1].offset);
5068 /* For scalable vector argument. */
5069 if (riscv_vector_type_p (type) && riscv_v_ext_mode_p (mode))
5070 return riscv_get_vector_arg (info, cum, mode, return_p);
5073 /* Work out the size of the argument. */
5074 num_bytes = type ? int_size_in_bytes (type) : GET_MODE_SIZE (mode).to_constant ();
5075 num_words = (num_bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
5077 /* Doubleword-aligned varargs start on an even register boundary. */
5078 if (!named && num_bytes != 0 && alignment > BITS_PER_WORD)
5079 info->gpr_offset += info->gpr_offset & 1;
5081 /* Partition the argument between registers and stack. */
5082 info->num_fprs = 0;
5083 info->num_gprs = MIN (num_words, MAX_ARGS_IN_REGISTERS - info->gpr_offset);
5084 info->stack_p = (num_words - info->num_gprs) != 0;
5086 if (info->num_gprs || return_p)
5087 return gen_rtx_REG (mode, gpr_base + info->gpr_offset);
5089 return NULL_RTX;
5092 /* Implement TARGET_FUNCTION_ARG. */
5094 static rtx
5095 riscv_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
5097 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
5098 struct riscv_arg_info info;
5100 if (arg.end_marker_p ())
5101 /* Return the calling convention that used by the current function. */
5102 return gen_int_mode (cum->variant_cc, SImode);
5104 return riscv_get_arg_info (&info, cum, arg.mode, arg.type, arg.named, false);
5107 /* Implement TARGET_FUNCTION_ARG_ADVANCE. */
5109 static void
5110 riscv_function_arg_advance (cumulative_args_t cum_v,
5111 const function_arg_info &arg)
5113 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
5114 struct riscv_arg_info info;
5116 riscv_get_arg_info (&info, cum, arg.mode, arg.type, arg.named, false);
5118 /* Set the corresponding register in USED_VRS to used status. */
5119 for (unsigned int i = 0; i < info.num_vrs; i++)
5121 gcc_assert (!cum->used_vrs[info.vr_offset + i]);
5122 cum->used_vrs[info.vr_offset + i] = true;
5125 if ((info.num_vrs > 0 || info.num_mrs > 0) && cum->variant_cc != RISCV_CC_V)
5127 error ("RVV type %qT cannot be passed to an unprototyped function",
5128 arg.type);
5129 /* Avoid repeating the message */
5130 cum->variant_cc = RISCV_CC_V;
5133 /* Advance the register count. This has the effect of setting
5134 num_gprs to MAX_ARGS_IN_REGISTERS if a doubleword-aligned
5135 argument required us to skip the final GPR and pass the whole
5136 argument on the stack. */
5137 cum->num_fprs = info.fpr_offset + info.num_fprs;
5138 cum->num_gprs = info.gpr_offset + info.num_gprs;
5139 cum->num_mrs = info.mr_offset + info.num_mrs;
5142 /* Implement TARGET_ARG_PARTIAL_BYTES. */
5144 static int
5145 riscv_arg_partial_bytes (cumulative_args_t cum,
5146 const function_arg_info &generic_arg)
5148 struct riscv_arg_info arg;
5150 riscv_get_arg_info (&arg, get_cumulative_args (cum), generic_arg.mode,
5151 generic_arg.type, generic_arg.named, false);
5152 return arg.stack_p ? arg.num_gprs * UNITS_PER_WORD : 0;
5155 /* Implement FUNCTION_VALUE and LIBCALL_VALUE. For normal calls,
5156 VALTYPE is the return type and MODE is VOIDmode. For libcalls,
5157 VALTYPE is null and MODE is the mode of the return value. */
5160 riscv_function_value (const_tree type, const_tree func, machine_mode mode)
5162 struct riscv_arg_info info;
5163 CUMULATIVE_ARGS args;
5165 if (type)
5167 int unsigned_p = TYPE_UNSIGNED (type);
5169 mode = TYPE_MODE (type);
5171 /* Since TARGET_PROMOTE_FUNCTION_MODE unconditionally promotes,
5172 return values, promote the mode here too. */
5173 mode = promote_function_mode (type, mode, &unsigned_p, func, 1);
5176 memset (&args, 0, sizeof args);
5178 return riscv_get_arg_info (&info, &args, mode, type, true, true);
5181 /* Implement TARGET_PASS_BY_REFERENCE. */
5183 static bool
5184 riscv_pass_by_reference (cumulative_args_t cum_v, const function_arg_info &arg)
5186 HOST_WIDE_INT size = arg.type_size_in_bytes ().to_constant ();;
5187 struct riscv_arg_info info;
5188 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
5190 /* ??? std_gimplify_va_arg_expr passes NULL for cum. Fortunately, we
5191 never pass variadic arguments in floating-point and vector registers,
5192 so we can avoid the call to riscv_get_arg_info in this case. */
5193 if (cum != NULL)
5195 /* Don't pass by reference if we can use a floating-point register. */
5196 riscv_get_arg_info (&info, cum, arg.mode, arg.type, arg.named, false);
5197 if (info.num_fprs)
5198 return false;
5200 /* Don't pass by reference if we can use vector register groups. */
5201 if (info.num_vrs > 0 || info.num_mrs > 0)
5202 return false;
5205 /* When vector abi disabled(without --param=riscv-vector-abi option) or
5206 scalable vector argument is anonymous or cannot be passed through vector
5207 registers, this argument is passed by reference. */
5208 if (riscv_v_ext_mode_p (arg.mode))
5209 return true;
5211 /* Pass by reference if the data do not fit in two integer registers. */
5212 return !IN_RANGE (size, 0, 2 * UNITS_PER_WORD);
5215 /* Implement TARGET_RETURN_IN_MEMORY. */
5217 static bool
5218 riscv_return_in_memory (const_tree type, const_tree fndecl ATTRIBUTE_UNUSED)
5220 CUMULATIVE_ARGS args;
5221 cumulative_args_t cum = pack_cumulative_args (&args);
5223 /* The rules for returning in memory are the same as for passing the
5224 first named argument by reference. */
5225 memset (&args, 0, sizeof args);
5226 function_arg_info arg (const_cast<tree> (type), /*named=*/true);
5227 return riscv_pass_by_reference (cum, arg);
5230 /* Implement TARGET_SETUP_INCOMING_VARARGS. */
5232 static void
5233 riscv_setup_incoming_varargs (cumulative_args_t cum,
5234 const function_arg_info &arg,
5235 int *pretend_size ATTRIBUTE_UNUSED, int no_rtl)
5237 CUMULATIVE_ARGS local_cum;
5238 int gp_saved;
5240 /* The caller has advanced CUM up to, but not beyond, the last named
5241 argument. Advance a local copy of CUM past the last "real" named
5242 argument, to find out how many registers are left over. */
5243 local_cum = *get_cumulative_args (cum);
5244 if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl)))
5245 riscv_function_arg_advance (pack_cumulative_args (&local_cum), arg);
5247 /* Found out how many registers we need to save. */
5248 gp_saved = MAX_ARGS_IN_REGISTERS - local_cum.num_gprs;
5250 if (!no_rtl && gp_saved > 0)
5252 rtx ptr = plus_constant (Pmode, virtual_incoming_args_rtx,
5253 REG_PARM_STACK_SPACE (cfun->decl)
5254 - gp_saved * UNITS_PER_WORD);
5255 rtx mem = gen_frame_mem (BLKmode, ptr);
5256 set_mem_alias_set (mem, get_varargs_alias_set ());
5258 move_block_from_reg (local_cum.num_gprs + GP_ARG_FIRST,
5259 mem, gp_saved);
5261 if (REG_PARM_STACK_SPACE (cfun->decl) == 0)
5262 cfun->machine->varargs_size = gp_saved * UNITS_PER_WORD;
5265 /* Return the descriptor of the Standard Vector Calling Convention Variant. */
5267 static const predefined_function_abi &
5268 riscv_v_abi ()
5270 predefined_function_abi &v_abi = function_abis[RISCV_CC_V];
5271 if (!v_abi.initialized_p ())
5273 HARD_REG_SET full_reg_clobbers
5274 = default_function_abi.full_reg_clobbers ();
5275 /* Callee-saved vector registers: v1-v7, v24-v31. */
5276 for (int regno = V_REG_FIRST + 1; regno <= V_REG_FIRST + 7; regno += 1)
5277 CLEAR_HARD_REG_BIT (full_reg_clobbers, regno);
5278 for (int regno = V_REG_FIRST + 24; regno <= V_REG_FIRST + 31; regno += 1)
5279 CLEAR_HARD_REG_BIT (full_reg_clobbers, regno);
5280 v_abi.initialize (RISCV_CC_V, full_reg_clobbers);
5282 return v_abi;
5285 /* Return true if a function with type FNTYPE returns its value in
5286 RISC-V V registers. */
5288 static bool
5289 riscv_return_value_is_vector_type_p (const_tree fntype)
5291 tree return_type = TREE_TYPE (fntype);
5293 return riscv_vector_type_p (return_type);
5296 /* Return true if a function with type FNTYPE takes arguments in
5297 RISC-V V registers. */
5299 static bool
5300 riscv_arguments_is_vector_type_p (const_tree fntype)
5302 for (tree chain = TYPE_ARG_TYPES (fntype); chain && chain != void_list_node;
5303 chain = TREE_CHAIN (chain))
5305 tree arg_type = TREE_VALUE (chain);
5306 if (riscv_vector_type_p (arg_type))
5307 return true;
5310 return false;
5313 /* Implement TARGET_FNTYPE_ABI. */
5315 static const predefined_function_abi &
5316 riscv_fntype_abi (const_tree fntype)
5318 /* Implementing an experimental vector calling convention, the proposal
5319 can be viewed at the bellow link:
5320 https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/389
5322 You can enable this feature via the `--param=riscv-vector-abi` compiler
5323 option. */
5324 if (riscv_vector_abi
5325 && (riscv_return_value_is_vector_type_p (fntype)
5326 || riscv_arguments_is_vector_type_p (fntype)))
5327 return riscv_v_abi ();
5329 return default_function_abi;
5332 /* Return riscv calling convention of call_insn. */
5333 riscv_cc
5334 get_riscv_cc (const rtx use)
5336 gcc_assert (GET_CODE (use) == USE);
5337 rtx unspec = XEXP (use, 0);
5338 gcc_assert (GET_CODE (unspec) == UNSPEC
5339 && XINT (unspec, 1) == UNSPEC_CALLEE_CC);
5340 riscv_cc cc = (riscv_cc) INTVAL (XVECEXP (unspec, 0, 0));
5341 gcc_assert (cc < RISCV_CC_UNKNOWN);
5342 return cc;
5345 /* Implement TARGET_INSN_CALLEE_ABI. */
5347 const predefined_function_abi &
5348 riscv_insn_callee_abi (const rtx_insn *insn)
5350 rtx pat = PATTERN (insn);
5351 gcc_assert (GET_CODE (pat) == PARALLEL);
5352 riscv_cc cc = get_riscv_cc (XVECEXP (pat, 0, 1));
5353 return function_abis[cc];
5356 /* Handle an attribute requiring a FUNCTION_DECL;
5357 arguments as in struct attribute_spec.handler. */
5358 static tree
5359 riscv_handle_fndecl_attribute (tree *node, tree name,
5360 tree args ATTRIBUTE_UNUSED,
5361 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
5363 if (TREE_CODE (*node) != FUNCTION_DECL)
5365 warning (OPT_Wattributes, "%qE attribute only applies to functions",
5366 name);
5367 *no_add_attrs = true;
5370 return NULL_TREE;
5373 /* Verify type based attributes. NODE is the what the attribute is being
5374 applied to. NAME is the attribute name. ARGS are the attribute args.
5375 FLAGS gives info about the context. NO_ADD_ATTRS should be set to true if
5376 the attribute should be ignored. */
5378 static tree
5379 riscv_handle_type_attribute (tree *node ATTRIBUTE_UNUSED, tree name, tree args,
5380 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
5382 /* Check for an argument. */
5383 if (is_attribute_p ("interrupt", name))
5385 if (args)
5387 tree cst = TREE_VALUE (args);
5388 const char *string;
5390 if (TREE_CODE (cst) != STRING_CST)
5392 warning (OPT_Wattributes,
5393 "%qE attribute requires a string argument",
5394 name);
5395 *no_add_attrs = true;
5396 return NULL_TREE;
5399 string = TREE_STRING_POINTER (cst);
5400 if (strcmp (string, "user") && strcmp (string, "supervisor")
5401 && strcmp (string, "machine"))
5403 warning (OPT_Wattributes,
5404 "argument to %qE attribute is not %<\"user\"%>, %<\"supervisor\"%>, "
5405 "or %<\"machine\"%>", name);
5406 *no_add_attrs = true;
5411 return NULL_TREE;
5414 /* Return true if function TYPE is an interrupt function. */
5415 static bool
5416 riscv_interrupt_type_p (tree type)
5418 return lookup_attribute ("interrupt", TYPE_ATTRIBUTES (type)) != NULL;
5421 /* Return true if FUNC is a naked function. */
5422 static bool
5423 riscv_naked_function_p (tree func)
5425 tree func_decl = func;
5426 if (func == NULL_TREE)
5427 func_decl = current_function_decl;
5428 return NULL_TREE != lookup_attribute ("naked", DECL_ATTRIBUTES (func_decl));
5431 /* Implement TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS. */
5432 static bool
5433 riscv_allocate_stack_slots_for_args ()
5435 /* Naked functions should not allocate stack slots for arguments. */
5436 return !riscv_naked_function_p (current_function_decl);
5439 /* Implement TARGET_WARN_FUNC_RETURN. */
5440 static bool
5441 riscv_warn_func_return (tree decl)
5443 /* Naked functions are implemented entirely in assembly, including the
5444 return sequence, so suppress warnings about this. */
5445 return !riscv_naked_function_p (decl);
5448 /* Implement TARGET_EXPAND_BUILTIN_VA_START. */
5450 static void
5451 riscv_va_start (tree valist, rtx nextarg)
5453 nextarg = plus_constant (Pmode, nextarg, -cfun->machine->varargs_size);
5454 std_expand_builtin_va_start (valist, nextarg);
5457 /* Make ADDR suitable for use as a call or sibcall target. */
5460 riscv_legitimize_call_address (rtx addr)
5462 if (!call_insn_operand (addr, VOIDmode))
5464 rtx reg = RISCV_CALL_ADDRESS_TEMP (Pmode);
5465 riscv_emit_move (reg, addr);
5466 return reg;
5468 return addr;
5471 /* Print symbolic operand OP, which is part of a HIGH or LO_SUM
5472 in context CONTEXT. HI_RELOC indicates a high-part reloc. */
5474 static void
5475 riscv_print_operand_reloc (FILE *file, rtx op, bool hi_reloc)
5477 const char *reloc;
5479 switch (riscv_classify_symbolic_expression (op))
5481 case SYMBOL_ABSOLUTE:
5482 reloc = hi_reloc ? "%hi" : "%lo";
5483 break;
5485 case SYMBOL_PCREL:
5486 reloc = hi_reloc ? "%pcrel_hi" : "%pcrel_lo";
5487 break;
5489 case SYMBOL_TLS_LE:
5490 reloc = hi_reloc ? "%tprel_hi" : "%tprel_lo";
5491 break;
5493 default:
5494 output_operand_lossage ("invalid use of '%%%c'", hi_reloc ? 'h' : 'R');
5495 return;
5498 fprintf (file, "%s(", reloc);
5499 output_addr_const (file, riscv_strip_unspec_address (op));
5500 fputc (')', file);
5503 /* Return the memory model that encapuslates both given models. */
5505 enum memmodel
5506 riscv_union_memmodels (enum memmodel model1, enum memmodel model2)
5508 model1 = memmodel_base (model1);
5509 model2 = memmodel_base (model2);
5511 enum memmodel weaker = model1 <= model2 ? model1: model2;
5512 enum memmodel stronger = model1 > model2 ? model1: model2;
5514 switch (stronger)
5516 case MEMMODEL_SEQ_CST:
5517 case MEMMODEL_ACQ_REL:
5518 return stronger;
5519 case MEMMODEL_RELEASE:
5520 if (weaker == MEMMODEL_ACQUIRE || weaker == MEMMODEL_CONSUME)
5521 return MEMMODEL_ACQ_REL;
5522 else
5523 return stronger;
5524 case MEMMODEL_ACQUIRE:
5525 case MEMMODEL_CONSUME:
5526 case MEMMODEL_RELAXED:
5527 return stronger;
5528 default:
5529 gcc_unreachable ();
5533 /* Return true if the .AQ suffix should be added to an AMO to implement the
5534 acquire portion of memory model MODEL. */
5536 static bool
5537 riscv_memmodel_needs_amo_acquire (enum memmodel model)
5539 /* ZTSO amo mappings require no annotations. */
5540 if (TARGET_ZTSO)
5541 return false;
5543 switch (model)
5545 case MEMMODEL_ACQ_REL:
5546 case MEMMODEL_SEQ_CST:
5547 case MEMMODEL_ACQUIRE:
5548 case MEMMODEL_CONSUME:
5549 return true;
5551 case MEMMODEL_RELEASE:
5552 case MEMMODEL_RELAXED:
5553 return false;
5555 default:
5556 gcc_unreachable ();
5560 /* Return true if the .RL suffix should be added to an AMO to implement the
5561 release portion of memory model MODEL. */
5563 static bool
5564 riscv_memmodel_needs_amo_release (enum memmodel model)
5566 /* ZTSO amo mappings require no annotations. */
5567 if (TARGET_ZTSO)
5568 return false;
5570 switch (model)
5572 case MEMMODEL_ACQ_REL:
5573 case MEMMODEL_SEQ_CST:
5574 case MEMMODEL_RELEASE:
5575 return true;
5577 case MEMMODEL_ACQUIRE:
5578 case MEMMODEL_CONSUME:
5579 case MEMMODEL_RELAXED:
5580 return false;
5582 default:
5583 gcc_unreachable ();
5587 /* Get REGNO alignment of vector mode.
5588 The alignment = LMUL when the LMUL >= 1.
5589 Otherwise, alignment = 1. */
5591 riscv_get_v_regno_alignment (machine_mode mode)
5593 /* 3.3.2. LMUL = 2,4,8, register numbers should be multiple of 2,4,8.
5594 but for mask vector register, register numbers can be any number. */
5595 int lmul = 1;
5596 machine_mode rvv_mode = mode;
5597 if (riscv_v_ext_vls_mode_p (rvv_mode))
5599 int size = GET_MODE_BITSIZE (rvv_mode).to_constant ();
5600 if (size < TARGET_MIN_VLEN)
5601 return 1;
5602 else
5603 return size / TARGET_MIN_VLEN;
5605 if (riscv_v_ext_tuple_mode_p (rvv_mode))
5606 rvv_mode = riscv_vector::get_subpart_mode (rvv_mode);
5607 poly_int64 size = GET_MODE_SIZE (rvv_mode);
5608 if (known_gt (size, UNITS_PER_V_REG))
5609 lmul = exact_div (size, UNITS_PER_V_REG).to_constant ();
5610 return lmul;
5613 /* Implement TARGET_PRINT_OPERAND. The RISCV-specific operand codes are:
5615 'h' Print the high-part relocation associated with OP, after stripping
5616 any outermost HIGH.
5617 'R' Print the low-part relocation associated with OP.
5618 'C' Print the integer branch condition for comparison OP.
5619 'N' Print the inverse of the integer branch condition for comparison OP.
5620 'A' Print the atomic operation suffix for memory model OP.
5621 'I' Print the LR suffix for memory model OP.
5622 'J' Print the SC suffix for memory model OP.
5623 'z' Print x0 if OP is zero, otherwise print OP normally.
5624 'i' Print i if the operand is not a register.
5625 'S' Print shift-index of single-bit mask OP.
5626 'T' Print shift-index of inverted single-bit mask OP.
5627 '~' Print w if TARGET_64BIT is true; otherwise not print anything.
5629 Note please keep this list and the list in riscv.md in sync. */
5631 static void
5632 riscv_print_operand (FILE *file, rtx op, int letter)
5634 /* `~` does not take an operand so op will be null
5635 Check for before accessing op.
5637 if (letter == '~')
5639 if (TARGET_64BIT)
5640 fputc('w', file);
5641 return;
5643 machine_mode mode = GET_MODE (op);
5644 enum rtx_code code = GET_CODE (op);
5646 switch (letter)
5648 case 'o': {
5649 /* Print 'OP' variant for RVV instructions.
5650 1. If the operand is VECTOR REG, we print 'v'(vnsrl.wv).
5651 2. If the operand is CONST_INT/CONST_VECTOR, we print 'i'(vnsrl.wi).
5652 3. If the operand is SCALAR REG, we print 'x'(vnsrl.wx). */
5653 if (riscv_v_ext_mode_p (mode))
5655 if (REG_P (op))
5656 asm_fprintf (file, "v");
5657 else if (CONST_VECTOR_P (op))
5658 asm_fprintf (file, "i");
5659 else
5660 output_operand_lossage ("invalid vector operand");
5662 else
5664 if (CONST_INT_P (op))
5665 asm_fprintf (file, "i");
5666 else
5667 asm_fprintf (file, "x");
5669 break;
5671 case 'v': {
5672 rtx elt;
5674 if (REG_P (op))
5675 asm_fprintf (file, "%s", reg_names[REGNO (op)]);
5676 else
5678 if (!const_vec_duplicate_p (op, &elt))
5679 output_operand_lossage ("invalid vector constant");
5680 else if (satisfies_constraint_Wc0 (op))
5681 asm_fprintf (file, "0");
5682 else if (satisfies_constraint_vi (op)
5683 || satisfies_constraint_vj (op)
5684 || satisfies_constraint_vk (op))
5685 asm_fprintf (file, "%wd", INTVAL (elt));
5686 else
5687 output_operand_lossage ("invalid vector constant");
5689 break;
5691 case 'V': {
5692 rtx elt;
5693 if (!const_vec_duplicate_p (op, &elt))
5694 output_operand_lossage ("invalid vector constant");
5695 else if (satisfies_constraint_vj (op))
5696 asm_fprintf (file, "%wd", -INTVAL (elt));
5697 else
5698 output_operand_lossage ("invalid vector constant");
5699 break;
5701 case 'm': {
5702 if (riscv_v_ext_mode_p (mode))
5704 /* Calculate lmul according to mode and print the value. */
5705 int lmul = riscv_get_v_regno_alignment (mode);
5706 asm_fprintf (file, "%d", lmul);
5708 else if (code == CONST_INT)
5710 /* If it is a const_int value, it denotes the VLMUL field enum. */
5711 unsigned int vlmul = UINTVAL (op);
5712 switch (vlmul)
5714 case riscv_vector::LMUL_1:
5715 asm_fprintf (file, "%s", "m1");
5716 break;
5717 case riscv_vector::LMUL_2:
5718 asm_fprintf (file, "%s", "m2");
5719 break;
5720 case riscv_vector::LMUL_4:
5721 asm_fprintf (file, "%s", "m4");
5722 break;
5723 case riscv_vector::LMUL_8:
5724 asm_fprintf (file, "%s", "m8");
5725 break;
5726 case riscv_vector::LMUL_F8:
5727 asm_fprintf (file, "%s", "mf8");
5728 break;
5729 case riscv_vector::LMUL_F4:
5730 asm_fprintf (file, "%s", "mf4");
5731 break;
5732 case riscv_vector::LMUL_F2:
5733 asm_fprintf (file, "%s", "mf2");
5734 break;
5735 default:
5736 gcc_unreachable ();
5739 else
5740 output_operand_lossage ("invalid vector constant");
5741 break;
5743 case 'p': {
5744 if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL)
5746 /* Print for RVV mask operand.
5747 If op is reg, print ",v0.t".
5748 Otherwise, don't print anything. */
5749 if (code == REG)
5750 fprintf (file, ",%s.t", reg_names[REGNO (op)]);
5752 else if (code == CONST_INT)
5754 /* Tail && Mask policy. */
5755 asm_fprintf (file, "%s", IS_AGNOSTIC (UINTVAL (op)) ? "a" : "u");
5757 else
5758 output_operand_lossage ("invalid vector constant");
5759 break;
5761 case 'h':
5762 if (code == HIGH)
5763 op = XEXP (op, 0);
5764 riscv_print_operand_reloc (file, op, true);
5765 break;
5767 case 'R':
5768 riscv_print_operand_reloc (file, op, false);
5769 break;
5771 case 'C':
5772 /* The RTL names match the instruction names. */
5773 fputs (GET_RTX_NAME (code), file);
5774 break;
5776 case 'N':
5777 /* The RTL names match the instruction names. */
5778 fputs (GET_RTX_NAME (reverse_condition (code)), file);
5779 break;
5781 case 'A': {
5782 const enum memmodel model = memmodel_base (INTVAL (op));
5783 if (riscv_memmodel_needs_amo_acquire (model)
5784 && riscv_memmodel_needs_amo_release (model))
5785 fputs (".aqrl", file);
5786 else if (riscv_memmodel_needs_amo_acquire (model))
5787 fputs (".aq", file);
5788 else if (riscv_memmodel_needs_amo_release (model))
5789 fputs (".rl", file);
5790 break;
5793 case 'I': {
5794 const enum memmodel model = memmodel_base (INTVAL (op));
5795 if (TARGET_ZTSO && model != MEMMODEL_SEQ_CST)
5796 /* LR ops only have an annotation for SEQ_CST in the Ztso mapping. */
5797 break;
5798 else if (model == MEMMODEL_SEQ_CST)
5799 fputs (".aqrl", file);
5800 else if (riscv_memmodel_needs_amo_acquire (model))
5801 fputs (".aq", file);
5802 break;
5805 case 'J': {
5806 const enum memmodel model = memmodel_base (INTVAL (op));
5807 if (TARGET_ZTSO && model == MEMMODEL_SEQ_CST)
5808 /* SC ops only have an annotation for SEQ_CST in the Ztso mapping. */
5809 fputs (".rl", file);
5810 else if (TARGET_ZTSO)
5811 break;
5812 else if (riscv_memmodel_needs_amo_release (model))
5813 fputs (".rl", file);
5814 break;
5817 case 'i':
5818 if (code != REG)
5819 fputs ("i", file);
5820 break;
5822 case 'B':
5823 fputs (GET_RTX_NAME (code), file);
5824 break;
5826 case 'S':
5828 rtx newop = GEN_INT (ctz_hwi (INTVAL (op)));
5829 output_addr_const (file, newop);
5830 break;
5832 case 'T':
5834 rtx newop = GEN_INT (ctz_hwi (~INTVAL (op)));
5835 output_addr_const (file, newop);
5836 break;
5838 case 'X':
5840 int ival = INTVAL (op) + 1;
5841 rtx newop = GEN_INT (ctz_hwi (ival) + 1);
5842 output_addr_const (file, newop);
5843 break;
5845 default:
5846 switch (code)
5848 case REG:
5849 if (letter && letter != 'z')
5850 output_operand_lossage ("invalid use of '%%%c'", letter);
5851 fprintf (file, "%s", reg_names[REGNO (op)]);
5852 break;
5854 case MEM:
5855 if (letter && letter != 'z')
5856 output_operand_lossage ("invalid use of '%%%c'", letter);
5857 else
5858 output_address (mode, XEXP (op, 0));
5859 break;
5861 case CONST_DOUBLE:
5863 if (letter == 'z' && op == CONST0_RTX (GET_MODE (op)))
5865 fputs (reg_names[GP_REG_FIRST], file);
5866 break;
5869 int fli_index = riscv_float_const_rtx_index_for_fli (op);
5870 if (fli_index == -1 || fli_index > 31)
5872 output_operand_lossage ("invalid use of '%%%c'", letter);
5873 break;
5875 asm_fprintf (file, "%s", fli_value_print[fli_index]);
5876 break;
5879 default:
5880 if (letter == 'z' && op == CONST0_RTX (GET_MODE (op)))
5881 fputs (reg_names[GP_REG_FIRST], file);
5882 else if (letter && letter != 'z')
5883 output_operand_lossage ("invalid use of '%%%c'", letter);
5884 else
5885 output_addr_const (file, riscv_strip_unspec_address (op));
5886 break;
5891 /* Implement TARGET_PRINT_OPERAND_PUNCT_VALID_P */
5892 static bool
5893 riscv_print_operand_punct_valid_p (unsigned char code)
5895 return (code == '~');
5898 /* Implement TARGET_PRINT_OPERAND_ADDRESS. */
5900 static void
5901 riscv_print_operand_address (FILE *file, machine_mode mode ATTRIBUTE_UNUSED, rtx x)
5903 struct riscv_address_info addr;
5905 if (th_print_operand_address (file, mode, x))
5906 return;
5908 if (riscv_classify_address (&addr, x, word_mode, true))
5909 switch (addr.type)
5911 case ADDRESS_REG:
5912 output_addr_const (file, riscv_strip_unspec_address (addr.offset));
5913 fprintf (file, "(%s)", reg_names[REGNO (addr.reg)]);
5914 return;
5916 case ADDRESS_LO_SUM:
5917 riscv_print_operand_reloc (file, addr.offset, false);
5918 fprintf (file, "(%s)", reg_names[REGNO (addr.reg)]);
5919 return;
5921 case ADDRESS_CONST_INT:
5922 output_addr_const (file, x);
5923 fprintf (file, "(%s)", reg_names[GP_REG_FIRST]);
5924 return;
5926 case ADDRESS_SYMBOLIC:
5927 output_addr_const (file, riscv_strip_unspec_address (x));
5928 return;
5930 default:
5931 gcc_unreachable ();
5934 gcc_unreachable ();
5937 static bool
5938 riscv_size_ok_for_small_data_p (int size)
5940 return g_switch_value && IN_RANGE (size, 1, g_switch_value);
5943 /* Return true if EXP should be placed in the small data section. */
5945 static bool
5946 riscv_in_small_data_p (const_tree x)
5948 /* Because default_use_anchors_for_symbol_p doesn't gather small data to use
5949 the anchor symbol to address nearby objects. In large model, it can get
5950 the better result using the anchor optiomization. */
5951 if (riscv_cmodel == CM_LARGE)
5952 return false;
5954 if (TREE_CODE (x) == STRING_CST || TREE_CODE (x) == FUNCTION_DECL)
5955 return false;
5957 if (VAR_P (x) && DECL_SECTION_NAME (x))
5959 const char *sec = DECL_SECTION_NAME (x);
5960 return strcmp (sec, ".sdata") == 0 || strcmp (sec, ".sbss") == 0;
5963 return riscv_size_ok_for_small_data_p (int_size_in_bytes (TREE_TYPE (x)));
5966 /* Switch to the appropriate section for output of DECL. */
5968 static section *
5969 riscv_select_section (tree decl, int reloc,
5970 unsigned HOST_WIDE_INT align)
5972 switch (categorize_decl_for_section (decl, reloc))
5974 case SECCAT_SRODATA:
5975 return get_named_section (decl, ".srodata", reloc);
5977 default:
5978 return default_elf_select_section (decl, reloc, align);
5982 /* Switch to the appropriate section for output of DECL. */
5984 static void
5985 riscv_unique_section (tree decl, int reloc)
5987 const char *prefix = NULL;
5988 bool one_only = DECL_ONE_ONLY (decl) && !HAVE_COMDAT_GROUP;
5990 switch (categorize_decl_for_section (decl, reloc))
5992 case SECCAT_SRODATA:
5993 prefix = one_only ? ".sr" : ".srodata";
5994 break;
5996 default:
5997 break;
5999 if (prefix)
6001 const char *name, *linkonce;
6002 char *string;
6004 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
6005 name = targetm.strip_name_encoding (name);
6007 /* If we're using one_only, then there needs to be a .gnu.linkonce
6008 prefix to the section name. */
6009 linkonce = one_only ? ".gnu.linkonce" : "";
6011 string = ACONCAT ((linkonce, prefix, ".", name, NULL));
6013 set_decl_section_name (decl, string);
6014 return;
6016 default_unique_section (decl, reloc);
6019 /* Constant pools are per-function when in large code model. */
6021 static inline bool
6022 riscv_can_use_per_function_literal_pools_p (void)
6024 return riscv_cmodel == CM_LARGE;
6027 static bool
6028 riscv_use_blocks_for_constant_p (machine_mode, const_rtx)
6030 /* We can't use blocks for constants when we're using a per-function
6031 constant pool. */
6032 return !riscv_can_use_per_function_literal_pools_p ();
6035 /* Return a section for X, handling small data. */
6037 static section *
6038 riscv_elf_select_rtx_section (machine_mode mode, rtx x,
6039 unsigned HOST_WIDE_INT align)
6041 /* The literal pool stays with the function. */
6042 if (riscv_can_use_per_function_literal_pools_p ())
6043 return function_section (current_function_decl);
6045 section *s = default_elf_select_rtx_section (mode, x, align);
6047 if (riscv_size_ok_for_small_data_p (GET_MODE_SIZE (mode).to_constant ()))
6049 if (startswith (s->named.name, ".rodata.cst"))
6051 /* Rename .rodata.cst* to .srodata.cst*. */
6052 char *name = (char *) alloca (strlen (s->named.name) + 2);
6053 sprintf (name, ".s%s", s->named.name + 1);
6054 return get_section (name, s->named.common.flags, NULL);
6057 if (s == data_section)
6058 return sdata_section;
6061 return s;
6064 /* Make the last instruction frame-related and note that it performs
6065 the operation described by FRAME_PATTERN. */
6067 static void
6068 riscv_set_frame_expr (rtx frame_pattern)
6070 rtx insn;
6072 insn = get_last_insn ();
6073 RTX_FRAME_RELATED_P (insn) = 1;
6074 REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
6075 frame_pattern,
6076 REG_NOTES (insn));
6079 /* Return a frame-related rtx that stores REG at MEM.
6080 REG must be a single register. */
6082 static rtx
6083 riscv_frame_set (rtx mem, rtx reg)
6085 rtx set = gen_rtx_SET (mem, reg);
6086 RTX_FRAME_RELATED_P (set) = 1;
6087 return set;
6090 /* Returns true if the current function might contain a far jump. */
6092 static bool
6093 riscv_far_jump_used_p ()
6095 size_t func_size = 0;
6097 if (cfun->machine->far_jump_used)
6098 return true;
6100 /* We can't change far_jump_used during or after reload, as there is
6101 no chance to change stack frame layout. So we must rely on the
6102 conservative heuristic below having done the right thing. */
6103 if (reload_in_progress || reload_completed)
6104 return false;
6106 /* Estimate the function length. */
6107 for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
6108 func_size += get_attr_length (insn);
6110 /* Conservatively determine whether some jump might exceed 1 MiB
6111 displacement. */
6112 if (func_size * 2 >= 0x100000)
6113 cfun->machine->far_jump_used = true;
6115 return cfun->machine->far_jump_used;
6118 /* Return true, if the current function must save the incoming return
6119 address. */
6121 static bool
6122 riscv_save_return_addr_reg_p (void)
6124 /* The $ra register is call-clobbered: if this is not a leaf function,
6125 save it. */
6126 if (!crtl->is_leaf)
6127 return true;
6129 /* We need to save the incoming return address if __builtin_eh_return
6130 is being used to set a different return address. */
6131 if (crtl->calls_eh_return)
6132 return true;
6134 /* Far jumps/branches use $ra as a temporary to set up the target jump
6135 location (clobbering the incoming return address). */
6136 if (riscv_far_jump_used_p ())
6137 return true;
6139 /* We need to save it if anyone has used that. */
6140 if (df_regs_ever_live_p (RETURN_ADDR_REGNUM))
6141 return true;
6143 /* Need not to use ra for leaf when frame pointer is turned off by
6144 option whatever the omit-leaf-frame's value. */
6145 if (frame_pointer_needed && crtl->is_leaf
6146 && !TARGET_OMIT_LEAF_FRAME_POINTER)
6147 return true;
6149 return false;
6152 /* Return true if the current function must save register REGNO. */
6154 static bool
6155 riscv_save_reg_p (unsigned int regno)
6157 bool call_saved = !global_regs[regno] && !call_used_or_fixed_reg_p (regno);
6158 bool might_clobber = crtl->saves_all_registers
6159 || df_regs_ever_live_p (regno);
6161 if (call_saved && might_clobber)
6162 return true;
6164 /* Save callee-saved V registers. */
6165 if (V_REG_P (regno) && !crtl->abi->clobbers_full_reg_p (regno)
6166 && might_clobber)
6167 return true;
6169 if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
6170 return true;
6172 if (regno == RETURN_ADDR_REGNUM && riscv_save_return_addr_reg_p ())
6173 return true;
6175 /* If this is an interrupt handler, then must save extra registers. */
6176 if (cfun->machine->interrupt_handler_p)
6178 /* zero register is always zero. */
6179 if (regno == GP_REG_FIRST)
6180 return false;
6182 /* The function will return the stack pointer to its original value. */
6183 if (regno == STACK_POINTER_REGNUM)
6184 return false;
6186 /* By convention, we assume that gp and tp are safe. */
6187 if (regno == GP_REGNUM || regno == THREAD_POINTER_REGNUM)
6188 return false;
6190 /* We must save every register used in this function. If this is not a
6191 leaf function, then we must save all temporary registers. */
6192 if (df_regs_ever_live_p (regno)
6193 || (!crtl->is_leaf && call_used_or_fixed_reg_p (regno)))
6194 return true;
6197 return false;
6200 /* Return TRUE if Zcmp push and pop insns should be
6201 avoided. FALSE otherwise.
6202 Only use multi push & pop if all GPRs masked can be covered,
6203 and stack access is SP based,
6204 and GPRs are at top of the stack frame,
6205 and no conflicts in stack allocation with other features */
6206 static bool
6207 riscv_avoid_multi_push (const struct riscv_frame_info *frame)
6209 if (!TARGET_ZCMP || crtl->calls_eh_return || frame_pointer_needed
6210 || cfun->machine->interrupt_handler_p || cfun->machine->varargs_size != 0
6211 || crtl->args.pretend_args_size != 0
6212 || (use_shrink_wrapping_separate ()
6213 && !riscv_avoid_shrink_wrapping_separate ())
6214 || (frame->mask & ~MULTI_PUSH_GPR_MASK))
6215 return true;
6217 return false;
6220 /* Determine whether to use multi push insn. */
6221 static bool
6222 riscv_use_multi_push (const struct riscv_frame_info *frame)
6224 if (riscv_avoid_multi_push (frame))
6225 return false;
6227 return (frame->multi_push_adj_base != 0);
6230 /* Return TRUE if a libcall to save/restore GPRs should be
6231 avoided. FALSE otherwise. */
6232 static bool
6233 riscv_avoid_save_libcall (void)
6235 if (!TARGET_SAVE_RESTORE
6236 || crtl->calls_eh_return
6237 || frame_pointer_needed
6238 || cfun->machine->interrupt_handler_p
6239 || cfun->machine->varargs_size != 0
6240 || crtl->args.pretend_args_size != 0)
6241 return true;
6243 return false;
6246 /* Determine whether to call GPR save/restore routines. */
6247 static bool
6248 riscv_use_save_libcall (const struct riscv_frame_info *frame)
6250 if (riscv_avoid_save_libcall ())
6251 return false;
6253 return frame->save_libcall_adjustment != 0;
6256 /* Determine which GPR save/restore routine to call. */
6258 static unsigned
6259 riscv_save_libcall_count (unsigned mask)
6261 for (unsigned n = GP_REG_LAST; n > GP_REG_FIRST; n--)
6262 if (BITSET_P (mask, n))
6263 return CALLEE_SAVED_REG_NUMBER (n) + 1;
6264 abort ();
6267 /* calculate number of s regs in multi push and pop.
6268 Note that {s0-s10} is not valid in Zcmp, use {s0-s11} instead. */
6269 static unsigned
6270 riscv_multi_push_sregs_count (unsigned mask)
6272 unsigned num = riscv_save_libcall_count (mask);
6273 return (num == ZCMP_INVALID_S0S10_SREGS_COUNTS) ? ZCMP_S0S11_SREGS_COUNTS
6274 : num;
6277 /* calculate number of regs(ra, s0-sx) in multi push and pop. */
6278 static unsigned
6279 riscv_multi_push_regs_count (unsigned mask)
6281 /* 1 is for ra */
6282 return riscv_multi_push_sregs_count (mask) + 1;
6285 /* Handle 16 bytes align for poly_int. */
6286 static poly_int64
6287 riscv_16bytes_align (poly_int64 value)
6289 return aligned_upper_bound (value, 16);
6292 static HOST_WIDE_INT
6293 riscv_16bytes_align (HOST_WIDE_INT value)
6295 return ROUND_UP (value, 16);
6298 /* Handle stack align for poly_int. */
6299 static poly_int64
6300 riscv_stack_align (poly_int64 value)
6302 return aligned_upper_bound (value, PREFERRED_STACK_BOUNDARY / 8);
6305 static HOST_WIDE_INT
6306 riscv_stack_align (HOST_WIDE_INT value)
6308 return RISCV_STACK_ALIGN (value);
6311 /* Populate the current function's riscv_frame_info structure.
6313 RISC-V stack frames grown downward. High addresses are at the top.
6315 +-------------------------------+
6317 | incoming stack arguments |
6319 +-------------------------------+ <-- incoming stack pointer
6321 | callee-allocated save area |
6322 | for arguments that are |
6323 | split between registers and |
6324 | the stack |
6326 +-------------------------------+ <-- arg_pointer_rtx
6328 | callee-allocated save area |
6329 | for register varargs |
6331 +-------------------------------+ <-- hard_frame_pointer_rtx;
6332 | | stack_pointer_rtx + gp_sp_offset
6333 | GPR save area | + UNITS_PER_WORD
6335 +-------------------------------+ <-- stack_pointer_rtx + fp_sp_offset
6336 | | + UNITS_PER_FP_REG
6337 | FPR save area |
6339 +-------------------------------+ <-- stack_pointer_rtx
6340 | | + v_sp_offset_top
6341 | Vector Registers save area |
6343 | ----------------------------- | <-- stack_pointer_rtx
6344 | padding | + v_sp_offset_bottom
6345 +-------------------------------+ <-- frame_pointer_rtx (virtual)
6347 | local variables |
6349 P +-------------------------------+
6351 | outgoing stack arguments |
6353 +-------------------------------+ <-- stack_pointer_rtx
6355 Dynamic stack allocations such as alloca insert data at point P.
6356 They decrease stack_pointer_rtx but leave frame_pointer_rtx and
6357 hard_frame_pointer_rtx unchanged. */
6359 static HOST_WIDE_INT riscv_first_stack_step (struct riscv_frame_info *frame, poly_int64 remaining_size);
6361 static void
6362 riscv_compute_frame_info (void)
6364 struct riscv_frame_info *frame;
6365 poly_int64 offset;
6366 bool interrupt_save_prologue_temp = false;
6367 unsigned int regno, i, num_x_saved = 0, num_f_saved = 0, x_save_size = 0;
6368 unsigned int num_v_saved = 0;
6370 frame = &cfun->machine->frame;
6372 /* In an interrupt function, there are two cases in which t0 needs to be used:
6373 1, If we have a large frame, then we need to save/restore t0. We check for
6374 this before clearing the frame struct.
6375 2, Need to save and restore some CSRs in the frame. */
6376 if (cfun->machine->interrupt_handler_p)
6378 HOST_WIDE_INT step1 = riscv_first_stack_step (frame, frame->total_size);
6379 if (! POLY_SMALL_OPERAND_P ((frame->total_size - step1))
6380 || (TARGET_HARD_FLOAT || TARGET_ZFINX))
6381 interrupt_save_prologue_temp = true;
6384 frame->reset();
6386 if (!cfun->machine->naked_p)
6388 /* Find out which GPRs we need to save. */
6389 for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
6390 if (riscv_save_reg_p (regno)
6391 || (interrupt_save_prologue_temp
6392 && (regno == RISCV_PROLOGUE_TEMP_REGNUM)))
6393 frame->mask |= 1 << (regno - GP_REG_FIRST), num_x_saved++;
6395 /* If this function calls eh_return, we must also save and restore the
6396 EH data registers. */
6397 if (crtl->calls_eh_return)
6398 for (i = 0; (regno = EH_RETURN_DATA_REGNO (i)) != INVALID_REGNUM; i++)
6399 frame->mask |= 1 << (regno - GP_REG_FIRST), num_x_saved++;
6401 /* Find out which FPRs we need to save. This loop must iterate over
6402 the same space as its companion in riscv_for_each_saved_reg. */
6403 if (TARGET_HARD_FLOAT)
6404 for (regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
6405 if (riscv_save_reg_p (regno))
6406 frame->fmask |= 1 << (regno - FP_REG_FIRST), num_f_saved++;
6408 /* Find out which V registers we need to save. */
6409 if (TARGET_VECTOR)
6410 for (regno = V_REG_FIRST; regno <= V_REG_LAST; regno++)
6411 if (riscv_save_reg_p (regno))
6413 frame->vmask |= 1 << (regno - V_REG_FIRST);
6414 num_v_saved++;
6418 if (frame->mask)
6420 x_save_size = riscv_stack_align (num_x_saved * UNITS_PER_WORD);
6422 /* 1 is for ra */
6423 unsigned num_save_restore = 1 + riscv_save_libcall_count (frame->mask);
6424 /* Only use save/restore routines if they don't alter the stack size. */
6425 if (riscv_stack_align (num_save_restore * UNITS_PER_WORD) == x_save_size
6426 && !riscv_avoid_save_libcall ())
6428 /* Libcall saves/restores 3 registers at once, so we need to
6429 allocate 12 bytes for callee-saved register. */
6430 if (TARGET_RVE)
6431 x_save_size = 3 * UNITS_PER_WORD;
6433 frame->save_libcall_adjustment = x_save_size;
6436 if (!riscv_avoid_multi_push (frame))
6438 /* num(ra, s0-sx) */
6439 unsigned num_multi_push = riscv_multi_push_regs_count (frame->mask);
6440 x_save_size = riscv_stack_align (num_multi_push * UNITS_PER_WORD);
6441 frame->multi_push_adj_base = riscv_16bytes_align (x_save_size);
6445 /* In an interrupt function, we need extra space for the initial saves of CSRs. */
6446 if (cfun->machine->interrupt_handler_p
6447 && ((TARGET_HARD_FLOAT && frame->fmask)
6448 || (TARGET_ZFINX
6449 /* Except for RISCV_PROLOGUE_TEMP_REGNUM. */
6450 && (frame->mask & ~(1 << RISCV_PROLOGUE_TEMP_REGNUM)))))
6451 /* Save and restore FCSR. */
6452 /* TODO: When P or V extensions support interrupts, some of their CSRs
6453 may also need to be saved and restored. */
6454 x_save_size += riscv_stack_align (1 * UNITS_PER_WORD);
6456 /* At the bottom of the frame are any outgoing stack arguments. */
6457 offset = riscv_stack_align (crtl->outgoing_args_size);
6458 /* Next are local stack variables. */
6459 offset += riscv_stack_align (get_frame_size ());
6460 /* The virtual frame pointer points above the local variables. */
6461 frame->frame_pointer_offset = offset;
6462 /* Next are the callee-saved VRs. */
6463 if (frame->vmask)
6464 offset += riscv_stack_align (num_v_saved * UNITS_PER_V_REG);
6465 frame->v_sp_offset_top = offset;
6466 frame->v_sp_offset_bottom
6467 = frame->v_sp_offset_top - num_v_saved * UNITS_PER_V_REG;
6468 /* Next are the callee-saved FPRs. */
6469 if (frame->fmask)
6470 offset += riscv_stack_align (num_f_saved * UNITS_PER_FP_REG);
6471 frame->fp_sp_offset = offset - UNITS_PER_FP_REG;
6472 /* Next are the callee-saved GPRs. */
6473 if (frame->mask)
6475 offset += x_save_size;
6476 /* align to 16 bytes and add paddings to GPR part to honor
6477 both stack alignment and zcmp pus/pop size alignment. */
6478 if (riscv_use_multi_push (frame)
6479 && known_lt (offset, frame->multi_push_adj_base
6480 + ZCMP_SP_INC_STEP * ZCMP_MAX_SPIMM))
6481 offset = riscv_16bytes_align (offset);
6483 frame->gp_sp_offset = offset - UNITS_PER_WORD;
6484 /* The hard frame pointer points above the callee-saved GPRs. */
6485 frame->hard_frame_pointer_offset = offset;
6486 /* Above the hard frame pointer is the callee-allocated varags save area. */
6487 offset += riscv_stack_align (cfun->machine->varargs_size);
6488 /* Next is the callee-allocated area for pretend stack arguments. */
6489 offset += riscv_stack_align (crtl->args.pretend_args_size);
6490 /* Arg pointer must be below pretend args, but must be above alignment
6491 padding. */
6492 frame->arg_pointer_offset = offset - crtl->args.pretend_args_size;
6493 frame->total_size = offset;
6495 /* Next points the incoming stack pointer and any incoming arguments. */
6498 /* Make sure that we're not trying to eliminate to the wrong hard frame
6499 pointer. */
6501 static bool
6502 riscv_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
6504 return (to == HARD_FRAME_POINTER_REGNUM || to == STACK_POINTER_REGNUM);
6507 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame pointer
6508 or argument pointer. TO is either the stack pointer or hard frame
6509 pointer. */
6511 poly_int64
6512 riscv_initial_elimination_offset (int from, int to)
6514 poly_int64 src, dest;
6516 riscv_compute_frame_info ();
6518 if (to == HARD_FRAME_POINTER_REGNUM)
6519 dest = cfun->machine->frame.hard_frame_pointer_offset;
6520 else if (to == STACK_POINTER_REGNUM)
6521 dest = 0; /* The stack pointer is the base of all offsets, hence 0. */
6522 else
6523 gcc_unreachable ();
6525 if (from == FRAME_POINTER_REGNUM)
6526 src = cfun->machine->frame.frame_pointer_offset;
6527 else if (from == ARG_POINTER_REGNUM)
6528 src = cfun->machine->frame.arg_pointer_offset;
6529 else
6530 gcc_unreachable ();
6532 return src - dest;
6535 /* Implement RETURN_ADDR_RTX. We do not support moving back to a
6536 previous frame. */
6539 riscv_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
6541 if (count != 0)
6542 return const0_rtx;
6544 return get_hard_reg_initial_val (Pmode, RETURN_ADDR_REGNUM);
6547 /* Emit code to change the current function's return address to
6548 ADDRESS. SCRATCH is available as a scratch register, if needed.
6549 ADDRESS and SCRATCH are both word-mode GPRs. */
6551 void
6552 riscv_set_return_address (rtx address, rtx scratch)
6554 rtx slot_address;
6556 gcc_assert (BITSET_P (cfun->machine->frame.mask, RETURN_ADDR_REGNUM));
6557 slot_address = riscv_add_offset (scratch, stack_pointer_rtx,
6558 cfun->machine->frame.gp_sp_offset.to_constant());
6559 riscv_emit_move (gen_frame_mem (GET_MODE (address), slot_address), address);
6562 /* Save register REG to MEM. Make the instruction frame-related. */
6564 static void
6565 riscv_save_reg (rtx reg, rtx mem)
6567 riscv_emit_move (mem, reg);
6568 riscv_set_frame_expr (riscv_frame_set (mem, reg));
6571 /* Restore register REG from MEM. */
6573 static void
6574 riscv_restore_reg (rtx reg, rtx mem)
6576 rtx insn = riscv_emit_move (reg, mem);
6577 rtx dwarf = NULL_RTX;
6578 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
6580 if (known_gt (epilogue_cfa_sp_offset, 0)
6581 && REGNO (reg) == HARD_FRAME_POINTER_REGNUM)
6583 rtx cfa_adjust_rtx
6584 = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
6585 gen_int_mode (epilogue_cfa_sp_offset, Pmode));
6586 dwarf = alloc_reg_note (REG_CFA_DEF_CFA, cfa_adjust_rtx, dwarf);
6589 REG_NOTES (insn) = dwarf;
6590 RTX_FRAME_RELATED_P (insn) = 1;
6593 /* A function to save or store a register. The first argument is the
6594 register and the second is the stack slot. */
6595 typedef void (*riscv_save_restore_fn) (rtx, rtx);
6597 /* Use FN to save or restore register REGNO. MODE is the register's
6598 mode and OFFSET is the offset of its save slot from the current
6599 stack pointer. */
6601 static void
6602 riscv_save_restore_reg (machine_mode mode, int regno,
6603 HOST_WIDE_INT offset, riscv_save_restore_fn fn)
6605 rtx mem;
6607 mem = gen_frame_mem (mode, plus_constant (Pmode, stack_pointer_rtx, offset));
6608 fn (gen_rtx_REG (mode, regno), mem);
6611 /* Return the next register up from REGNO up to LIMIT for the callee
6612 to save or restore. OFFSET will be adjusted accordingly.
6613 If INC is set, then REGNO will be incremented first.
6614 Returns INVALID_REGNUM if there is no such next register. */
6616 static unsigned int
6617 riscv_next_saved_reg (unsigned int regno, unsigned int limit,
6618 HOST_WIDE_INT *offset, bool inc = true)
6620 if (inc)
6621 regno++;
6623 while (regno <= limit)
6625 if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST))
6627 *offset = *offset - UNITS_PER_WORD;
6628 return regno;
6631 regno++;
6633 return INVALID_REGNUM;
6636 /* Return TRUE if provided REGNO is eh return data register. */
6638 static bool
6639 riscv_is_eh_return_data_register (unsigned int regno)
6641 unsigned int i, regnum;
6643 if (!crtl->calls_eh_return)
6644 return false;
6646 for (i = 0; (regnum = EH_RETURN_DATA_REGNO (i)) != INVALID_REGNUM; i++)
6647 if (regno == regnum)
6649 return true;
6652 return false;
6655 /* Call FN for each register that is saved by the current function.
6656 SP_OFFSET is the offset of the current stack pointer from the start
6657 of the frame. */
6659 static void
6660 riscv_for_each_saved_reg (poly_int64 sp_offset, riscv_save_restore_fn fn,
6661 bool epilogue, bool maybe_eh_return)
6663 HOST_WIDE_INT offset, first_fp_offset;
6664 unsigned int regno, num_masked_fp = 0;
6665 unsigned int start = GP_REG_FIRST;
6666 unsigned int limit = GP_REG_LAST;
6668 /* Save the link register and s-registers. */
6669 offset = (cfun->machine->frame.gp_sp_offset - sp_offset).to_constant ()
6670 + UNITS_PER_WORD;
6671 for (regno = riscv_next_saved_reg (start, limit, &offset, false);
6672 regno != INVALID_REGNUM;
6673 regno = riscv_next_saved_reg (regno, limit, &offset))
6675 if (cfun->machine->reg_is_wrapped_separately[regno])
6676 continue;
6678 /* If this is a normal return in a function that calls the eh_return
6679 builtin, then do not restore the eh return data registers as that
6680 would clobber the return value. But we do still need to save them
6681 in the prologue, and restore them for an exception return, so we
6682 need special handling here. */
6683 if (epilogue && !maybe_eh_return
6684 && riscv_is_eh_return_data_register (regno))
6685 continue;
6687 /* In an interrupt function, save and restore some necessary CSRs in the stack
6688 to avoid changes in CSRs. */
6689 if (regno == RISCV_PROLOGUE_TEMP_REGNUM
6690 && cfun->machine->interrupt_handler_p
6691 && ((TARGET_HARD_FLOAT && cfun->machine->frame.fmask)
6692 || (TARGET_ZFINX
6693 && (cfun->machine->frame.mask & ~(1 << RISCV_PROLOGUE_TEMP_REGNUM)))))
6695 /* Always assume FCSR occupy UNITS_PER_WORD to prevent stack
6696 offset misaligned later. */
6697 unsigned int fcsr_size = UNITS_PER_WORD;
6698 if (!epilogue)
6700 riscv_save_restore_reg (word_mode, regno, offset, fn);
6701 offset -= fcsr_size;
6702 emit_insn (gen_riscv_frcsr (RISCV_PROLOGUE_TEMP (SImode)));
6703 riscv_save_restore_reg (SImode, RISCV_PROLOGUE_TEMP_REGNUM,
6704 offset, riscv_save_reg);
6706 else
6708 riscv_save_restore_reg (SImode, RISCV_PROLOGUE_TEMP_REGNUM,
6709 offset - fcsr_size, riscv_restore_reg);
6710 emit_insn (gen_riscv_fscsr (RISCV_PROLOGUE_TEMP (SImode)));
6711 riscv_save_restore_reg (word_mode, regno, offset, fn);
6712 offset -= fcsr_size;
6714 continue;
6717 if (TARGET_XTHEADMEMPAIR)
6719 /* Get the next reg/offset pair. */
6720 HOST_WIDE_INT offset2 = offset;
6721 unsigned int regno2 = riscv_next_saved_reg (regno, limit, &offset2);
6723 /* Validate everything before emitting a mempair instruction. */
6724 if (regno2 != INVALID_REGNUM
6725 && !cfun->machine->reg_is_wrapped_separately[regno2]
6726 && !(epilogue && !maybe_eh_return
6727 && riscv_is_eh_return_data_register (regno2)))
6729 bool load_p = (fn == riscv_restore_reg);
6730 rtx operands[4];
6731 th_mempair_prepare_save_restore_operands (operands,
6732 load_p, word_mode,
6733 regno, offset,
6734 regno2, offset2);
6736 /* If the operands fit into a mempair insn, then emit one. */
6737 if (th_mempair_operands_p (operands, load_p, word_mode))
6739 th_mempair_save_restore_regs (operands, load_p, word_mode);
6740 offset = offset2;
6741 regno = regno2;
6742 continue;
6747 riscv_save_restore_reg (word_mode, regno, offset, fn);
6750 /* This loop must iterate over the same space as its companion in
6751 riscv_compute_frame_info. */
6752 first_fp_offset
6753 = (cfun->machine->frame.fp_sp_offset - sp_offset).to_constant ();
6754 for (unsigned int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
6755 if (BITSET_P (cfun->machine->frame.fmask, regno - FP_REG_FIRST))
6757 bool handle_reg = !cfun->machine->reg_is_wrapped_separately[regno];
6758 machine_mode mode = TARGET_DOUBLE_FLOAT ? DFmode : SFmode;
6759 unsigned int slot = (riscv_use_multi_push (&cfun->machine->frame))
6760 ? CALLEE_SAVED_FREG_NUMBER (regno)
6761 : num_masked_fp;
6762 offset = first_fp_offset - slot * GET_MODE_SIZE (mode).to_constant ();
6763 if (handle_reg)
6764 riscv_save_restore_reg (mode, regno, offset, fn);
6765 num_masked_fp++;
6769 /* Call FN for each V register that is saved by the current function. */
6771 static void
6772 riscv_for_each_saved_v_reg (poly_int64 &remaining_size,
6773 riscv_save_restore_fn fn, bool prologue)
6775 rtx vlen = NULL_RTX;
6776 if (cfun->machine->frame.vmask != 0)
6778 if (UNITS_PER_V_REG.is_constant ()
6779 && SMALL_OPERAND (UNITS_PER_V_REG.to_constant ()))
6780 vlen = GEN_INT (UNITS_PER_V_REG.to_constant ());
6781 else
6783 vlen = RISCV_PROLOGUE_TEMP (Pmode);
6784 rtx insn
6785 = emit_move_insn (vlen, gen_int_mode (UNITS_PER_V_REG, Pmode));
6786 RTX_FRAME_RELATED_P (insn) = 1;
6790 /* Select the mode where LMUL is 1 and SEW is largest. */
6791 machine_mode m1_mode = TARGET_VECTOR_ELEN_64 ? RVVM1DImode : RVVM1SImode;
6793 if (prologue)
6795 /* This loop must iterate over the same space as its companion in
6796 riscv_compute_frame_info. */
6797 for (unsigned int regno = V_REG_FIRST; regno <= V_REG_LAST; regno++)
6798 if (BITSET_P (cfun->machine->frame.vmask, regno - V_REG_FIRST))
6800 bool handle_reg = !cfun->machine->reg_is_wrapped_separately[regno];
6801 if (handle_reg)
6803 rtx insn = NULL_RTX;
6804 if (CONST_INT_P (vlen))
6806 gcc_assert (SMALL_OPERAND (-INTVAL (vlen)));
6807 insn = emit_insn (gen_add3_insn (stack_pointer_rtx,
6808 stack_pointer_rtx,
6809 GEN_INT (-INTVAL (vlen))));
6811 else
6812 insn = emit_insn (
6813 gen_sub3_insn (stack_pointer_rtx, stack_pointer_rtx, vlen));
6814 gcc_assert (insn != NULL_RTX);
6815 RTX_FRAME_RELATED_P (insn) = 1;
6816 riscv_save_restore_reg (m1_mode, regno, 0, fn);
6817 remaining_size -= UNITS_PER_V_REG;
6821 else
6823 /* This loop must iterate over the same space as its companion in
6824 riscv_compute_frame_info. */
6825 for (unsigned int regno = V_REG_LAST; regno >= V_REG_FIRST; regno--)
6826 if (BITSET_P (cfun->machine->frame.vmask, regno - V_REG_FIRST))
6828 bool handle_reg = !cfun->machine->reg_is_wrapped_separately[regno];
6829 if (handle_reg)
6831 riscv_save_restore_reg (m1_mode, regno, 0, fn);
6832 rtx insn = emit_insn (
6833 gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx, vlen));
6834 gcc_assert (insn != NULL_RTX);
6835 RTX_FRAME_RELATED_P (insn) = 1;
6836 remaining_size -= UNITS_PER_V_REG;
6842 /* For stack frames that can't be allocated with a single ADDI instruction,
6843 compute the best value to initially allocate. It must at a minimum
6844 allocate enough space to spill the callee-saved registers. If TARGET_RVC,
6845 try to pick a value that will allow compression of the register saves
6846 without adding extra instructions. */
6848 static HOST_WIDE_INT
6849 riscv_first_stack_step (struct riscv_frame_info *frame, poly_int64 remaining_size)
6851 HOST_WIDE_INT remaining_const_size;
6852 if (!remaining_size.is_constant ())
6853 remaining_const_size
6854 = riscv_stack_align (remaining_size.coeffs[0])
6855 - riscv_stack_align (remaining_size.coeffs[1]);
6856 else
6857 remaining_const_size = remaining_size.to_constant ();
6859 /* First step must be set to the top of vector registers save area if any
6860 vector registers need be preversed. */
6861 if (frame->vmask != 0)
6862 return (remaining_size - frame->v_sp_offset_top).to_constant ();
6864 if (SMALL_OPERAND (remaining_const_size))
6865 return remaining_const_size;
6867 poly_int64 callee_saved_first_step =
6868 remaining_size - frame->frame_pointer_offset;
6869 gcc_assert(callee_saved_first_step.is_constant ());
6870 HOST_WIDE_INT min_first_step =
6871 riscv_stack_align (callee_saved_first_step.to_constant ());
6872 HOST_WIDE_INT max_first_step = IMM_REACH / 2 - PREFERRED_STACK_BOUNDARY / 8;
6873 HOST_WIDE_INT min_second_step = remaining_const_size - max_first_step;
6874 gcc_assert (min_first_step <= max_first_step);
6876 /* As an optimization, use the least-significant bits of the total frame
6877 size, so that the second adjustment step is just LUI + ADD. */
6878 if (!SMALL_OPERAND (min_second_step)
6879 && remaining_const_size % IMM_REACH <= max_first_step
6880 && remaining_const_size % IMM_REACH >= min_first_step)
6881 return remaining_const_size % IMM_REACH;
6883 if (TARGET_RVC || TARGET_ZCA)
6885 /* If we need two subtracts, and one is small enough to allow compressed
6886 loads and stores, then put that one first. */
6887 if (IN_RANGE (min_second_step, 0,
6888 (TARGET_64BIT ? SDSP_REACH : SWSP_REACH)))
6889 return MAX (min_second_step, min_first_step);
6891 /* If we need LUI + ADDI + ADD for the second adjustment step, then start
6892 with the minimum first step, so that we can get compressed loads and
6893 stores. */
6894 else if (!SMALL_OPERAND (min_second_step))
6895 return min_first_step;
6898 return max_first_step;
6901 static rtx
6902 riscv_adjust_libcall_cfi_prologue ()
6904 rtx dwarf = NULL_RTX;
6905 rtx adjust_sp_rtx, reg, mem, insn;
6906 int saved_size = cfun->machine->frame.save_libcall_adjustment;
6907 int offset;
6909 for (int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
6910 if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST))
6912 /* The save order is ra, s0, s1, s2 to s11. */
6913 if (regno == RETURN_ADDR_REGNUM)
6914 offset = saved_size - UNITS_PER_WORD;
6915 else if (regno == S0_REGNUM)
6916 offset = saved_size - UNITS_PER_WORD * 2;
6917 else if (regno == S1_REGNUM)
6918 offset = saved_size - UNITS_PER_WORD * 3;
6919 else
6920 offset = saved_size - ((regno - S2_REGNUM + 4) * UNITS_PER_WORD);
6922 reg = gen_rtx_REG (Pmode, regno);
6923 mem = gen_frame_mem (Pmode, plus_constant (Pmode,
6924 stack_pointer_rtx,
6925 offset));
6927 insn = gen_rtx_SET (mem, reg);
6928 dwarf = alloc_reg_note (REG_CFA_OFFSET, insn, dwarf);
6931 /* Debug info for adjust sp. */
6932 adjust_sp_rtx =
6933 gen_rtx_SET (stack_pointer_rtx,
6934 gen_rtx_PLUS (GET_MODE(stack_pointer_rtx), stack_pointer_rtx, GEN_INT (-saved_size)));
6935 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, adjust_sp_rtx,
6936 dwarf);
6937 return dwarf;
6940 static rtx
6941 riscv_adjust_multi_push_cfi_prologue (int saved_size)
6943 rtx dwarf = NULL_RTX;
6944 rtx adjust_sp_rtx, reg, mem, insn;
6945 unsigned int mask = cfun->machine->frame.mask;
6946 int offset;
6947 int saved_cnt = 0;
6949 if (mask & S10_MASK)
6950 mask |= S11_MASK;
6952 for (int regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
6953 if (BITSET_P (mask & MULTI_PUSH_GPR_MASK, regno - GP_REG_FIRST))
6955 /* The save order is s11-s0, ra
6956 from high to low addr. */
6957 offset = saved_size - UNITS_PER_WORD * (++saved_cnt);
6959 reg = gen_rtx_REG (Pmode, regno);
6960 mem = gen_frame_mem (Pmode,
6961 plus_constant (Pmode, stack_pointer_rtx, offset));
6963 insn = gen_rtx_SET (mem, reg);
6964 dwarf = alloc_reg_note (REG_CFA_OFFSET, insn, dwarf);
6967 /* Debug info for adjust sp. */
6968 adjust_sp_rtx
6969 = gen_rtx_SET (stack_pointer_rtx,
6970 plus_constant (Pmode, stack_pointer_rtx, -saved_size));
6971 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, adjust_sp_rtx, dwarf);
6972 return dwarf;
6975 static void
6976 riscv_emit_stack_tie (void)
6978 if (Pmode == SImode)
6979 emit_insn (gen_stack_tiesi (stack_pointer_rtx, hard_frame_pointer_rtx));
6980 else
6981 emit_insn (gen_stack_tiedi (stack_pointer_rtx, hard_frame_pointer_rtx));
6984 /*zcmp multi push and pop code_for_push_pop function ptr array */
6985 static const code_for_push_pop_t code_for_push_pop[ZCMP_MAX_GRP_SLOTS][ZCMP_OP_NUM]
6986 = {{code_for_gpr_multi_push_up_to_ra, code_for_gpr_multi_pop_up_to_ra,
6987 code_for_gpr_multi_popret_up_to_ra, code_for_gpr_multi_popretz_up_to_ra},
6988 {code_for_gpr_multi_push_up_to_s0, code_for_gpr_multi_pop_up_to_s0,
6989 code_for_gpr_multi_popret_up_to_s0, code_for_gpr_multi_popretz_up_to_s0},
6990 {code_for_gpr_multi_push_up_to_s1, code_for_gpr_multi_pop_up_to_s1,
6991 code_for_gpr_multi_popret_up_to_s1, code_for_gpr_multi_popretz_up_to_s1},
6992 {code_for_gpr_multi_push_up_to_s2, code_for_gpr_multi_pop_up_to_s2,
6993 code_for_gpr_multi_popret_up_to_s2, code_for_gpr_multi_popretz_up_to_s2},
6994 {code_for_gpr_multi_push_up_to_s3, code_for_gpr_multi_pop_up_to_s3,
6995 code_for_gpr_multi_popret_up_to_s3, code_for_gpr_multi_popretz_up_to_s3},
6996 {code_for_gpr_multi_push_up_to_s4, code_for_gpr_multi_pop_up_to_s4,
6997 code_for_gpr_multi_popret_up_to_s4, code_for_gpr_multi_popretz_up_to_s4},
6998 {code_for_gpr_multi_push_up_to_s5, code_for_gpr_multi_pop_up_to_s5,
6999 code_for_gpr_multi_popret_up_to_s5, code_for_gpr_multi_popretz_up_to_s5},
7000 {code_for_gpr_multi_push_up_to_s6, code_for_gpr_multi_pop_up_to_s6,
7001 code_for_gpr_multi_popret_up_to_s6, code_for_gpr_multi_popretz_up_to_s6},
7002 {code_for_gpr_multi_push_up_to_s7, code_for_gpr_multi_pop_up_to_s7,
7003 code_for_gpr_multi_popret_up_to_s7, code_for_gpr_multi_popretz_up_to_s7},
7004 {code_for_gpr_multi_push_up_to_s8, code_for_gpr_multi_pop_up_to_s8,
7005 code_for_gpr_multi_popret_up_to_s8, code_for_gpr_multi_popretz_up_to_s8},
7006 {code_for_gpr_multi_push_up_to_s9, code_for_gpr_multi_pop_up_to_s9,
7007 code_for_gpr_multi_popret_up_to_s9, code_for_gpr_multi_popretz_up_to_s9},
7008 {nullptr, nullptr, nullptr, nullptr},
7009 {code_for_gpr_multi_push_up_to_s11, code_for_gpr_multi_pop_up_to_s11,
7010 code_for_gpr_multi_popret_up_to_s11,
7011 code_for_gpr_multi_popretz_up_to_s11}};
7013 static rtx
7014 riscv_gen_multi_push_pop_insn (riscv_zcmp_op_t op, HOST_WIDE_INT adj_size,
7015 unsigned int regs_num)
7017 gcc_assert (op < ZCMP_OP_NUM);
7018 gcc_assert (regs_num <= ZCMP_MAX_GRP_SLOTS
7019 && regs_num != ZCMP_INVALID_S0S10_SREGS_COUNTS + 1); /* 1 for ra*/
7020 rtx stack_adj = GEN_INT (adj_size);
7021 return GEN_FCN (code_for_push_pop[regs_num - 1][op](Pmode)) (stack_adj);
7024 static unsigned
7025 get_multi_push_fpr_mask (unsigned max_fprs_push)
7027 unsigned mask_fprs_push = 0, num_f_pushed = 0;
7028 for (unsigned regno = FP_REG_FIRST;
7029 regno <= FP_REG_LAST && num_f_pushed < max_fprs_push; regno++)
7030 if (riscv_save_reg_p (regno))
7031 mask_fprs_push |= 1 << (regno - FP_REG_FIRST), num_f_pushed++;
7032 return mask_fprs_push;
7035 /* Expand the "prologue" pattern. */
7037 void
7038 riscv_expand_prologue (void)
7040 struct riscv_frame_info *frame = &cfun->machine->frame;
7041 poly_int64 remaining_size = frame->total_size;
7042 unsigned mask = frame->mask;
7043 unsigned fmask = frame->fmask;
7044 int spimm, multi_push_additional, stack_adj;
7045 rtx insn, dwarf = NULL_RTX;
7046 unsigned th_int_mask = 0;
7048 if (flag_stack_usage_info)
7049 current_function_static_stack_size = constant_lower_bound (remaining_size);
7051 if (cfun->machine->naked_p)
7052 return;
7054 /* prefer muti-push to save-restore libcall. */
7055 if (riscv_use_multi_push (frame))
7057 remaining_size -= frame->multi_push_adj_base;
7058 /* If there are vector registers that need to be saved, then it can only
7059 be reduced to the frame->v_sp_offset_top position at most, since the
7060 vector registers will need to be saved one by one by decreasing the SP
7061 later. */
7062 poly_int64 remaining_size_above_varea
7063 = frame->vmask != 0
7064 ? remaining_size - frame->v_sp_offset_top
7065 : remaining_size;
7067 if (known_gt (remaining_size_above_varea, 2 * ZCMP_SP_INC_STEP))
7068 spimm = 3;
7069 else if (known_gt (remaining_size_above_varea, ZCMP_SP_INC_STEP))
7070 spimm = 2;
7071 else if (known_gt (remaining_size_above_varea, 0))
7072 spimm = 1;
7073 else
7074 spimm = 0;
7075 multi_push_additional = spimm * ZCMP_SP_INC_STEP;
7076 frame->multi_push_adj_addi = multi_push_additional;
7077 remaining_size -= multi_push_additional;
7079 /* emit multi push insn & dwarf along with it. */
7080 stack_adj = frame->multi_push_adj_base + multi_push_additional;
7081 insn = emit_insn (riscv_gen_multi_push_pop_insn (
7082 PUSH_IDX, -stack_adj, riscv_multi_push_regs_count (frame->mask)));
7083 dwarf = riscv_adjust_multi_push_cfi_prologue (stack_adj);
7084 RTX_FRAME_RELATED_P (insn) = 1;
7085 REG_NOTES (insn) = dwarf;
7087 /* Temporarily fib that we need not save GPRs. */
7088 frame->mask = 0;
7090 /* push FPRs into the addtional reserved space by cm.push. */
7091 if (fmask)
7093 unsigned mask_fprs_push
7094 = get_multi_push_fpr_mask (multi_push_additional / UNITS_PER_WORD);
7095 frame->fmask &= mask_fprs_push;
7096 riscv_for_each_saved_reg (remaining_size, riscv_save_reg, false,
7097 false);
7098 frame->fmask = fmask & ~mask_fprs_push; /* mask for the rest FPRs. */
7101 /* When optimizing for size, call a subroutine to save the registers. */
7102 else if (riscv_use_save_libcall (frame))
7104 rtx dwarf = NULL_RTX;
7105 dwarf = riscv_adjust_libcall_cfi_prologue ();
7107 remaining_size -= frame->save_libcall_adjustment;
7108 insn = emit_insn (riscv_gen_gpr_save_insn (frame));
7109 frame->mask = 0; /* Temporarily fib that we need not save GPRs. */
7111 RTX_FRAME_RELATED_P (insn) = 1;
7112 REG_NOTES (insn) = dwarf;
7115 th_int_mask = th_int_get_mask (frame->mask);
7116 if (th_int_mask && TH_INT_INTERRUPT (cfun))
7118 frame->mask &= ~th_int_mask;
7120 /* RISCV_PROLOGUE_TEMP may be used to handle some CSR for
7121 interrupts, such as fcsr. */
7122 if ((TARGET_HARD_FLOAT && frame->fmask)
7123 || (TARGET_ZFINX && frame->mask))
7124 frame->mask |= (1 << RISCV_PROLOGUE_TEMP_REGNUM);
7126 unsigned save_adjustment = th_int_get_save_adjustment ();
7127 frame->gp_sp_offset -= save_adjustment;
7128 remaining_size -= save_adjustment;
7130 insn = emit_insn (gen_th_int_push ());
7132 rtx dwarf = th_int_adjust_cfi_prologue (th_int_mask);
7133 RTX_FRAME_RELATED_P (insn) = 1;
7134 REG_NOTES (insn) = dwarf;
7137 /* Save the GP, FP registers. */
7138 if ((frame->mask | frame->fmask) != 0)
7140 if (known_gt (remaining_size, frame->frame_pointer_offset))
7142 HOST_WIDE_INT step1 = riscv_first_stack_step (frame, remaining_size);
7143 remaining_size -= step1;
7144 insn = gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
7145 GEN_INT (-step1));
7146 RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
7148 riscv_for_each_saved_reg (remaining_size, riscv_save_reg, false, false);
7151 /* Undo the above fib. */
7152 frame->mask = mask;
7153 frame->fmask = fmask;
7155 /* Set up the frame pointer, if we're using one. */
7156 if (frame_pointer_needed)
7158 insn = gen_add3_insn (hard_frame_pointer_rtx, stack_pointer_rtx,
7159 GEN_INT ((frame->hard_frame_pointer_offset - remaining_size).to_constant ()));
7160 RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
7162 riscv_emit_stack_tie ();
7165 /* Save the V registers. */
7166 if (frame->vmask != 0)
7167 riscv_for_each_saved_v_reg (remaining_size, riscv_save_reg, true);
7169 /* Allocate the rest of the frame. */
7170 if (known_gt (remaining_size, 0))
7172 /* Two step adjustment:
7173 1.scalable frame. 2.constant frame. */
7174 poly_int64 scalable_frame (0, 0);
7175 if (!remaining_size.is_constant ())
7177 /* First for scalable frame. */
7178 poly_int64 scalable_frame = remaining_size;
7179 scalable_frame.coeffs[0] = remaining_size.coeffs[1];
7180 riscv_v_adjust_scalable_frame (stack_pointer_rtx, scalable_frame, false);
7181 remaining_size -= scalable_frame;
7184 /* Second step for constant frame. */
7185 HOST_WIDE_INT constant_frame = remaining_size.to_constant ();
7186 if (constant_frame == 0)
7187 return;
7189 if (SMALL_OPERAND (-constant_frame))
7191 insn = gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
7192 GEN_INT (-constant_frame));
7193 RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
7195 else
7197 riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode), GEN_INT (-constant_frame));
7198 emit_insn (gen_add3_insn (stack_pointer_rtx,
7199 stack_pointer_rtx,
7200 RISCV_PROLOGUE_TEMP (Pmode)));
7202 /* Describe the effect of the previous instructions. */
7203 insn = plus_constant (Pmode, stack_pointer_rtx, -constant_frame);
7204 insn = gen_rtx_SET (stack_pointer_rtx, insn);
7205 riscv_set_frame_expr (insn);
7210 static rtx
7211 riscv_adjust_multi_pop_cfi_epilogue (int saved_size)
7213 rtx dwarf = NULL_RTX;
7214 rtx adjust_sp_rtx, reg;
7215 unsigned int mask = cfun->machine->frame.mask;
7217 if (mask & S10_MASK)
7218 mask |= S11_MASK;
7220 /* Debug info for adjust sp. */
7221 adjust_sp_rtx
7222 = gen_rtx_SET (stack_pointer_rtx,
7223 plus_constant (Pmode, stack_pointer_rtx, saved_size));
7224 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, adjust_sp_rtx, dwarf);
7226 for (int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
7227 if (BITSET_P (mask, regno - GP_REG_FIRST))
7229 reg = gen_rtx_REG (Pmode, regno);
7230 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
7233 return dwarf;
7236 static rtx
7237 riscv_adjust_libcall_cfi_epilogue ()
7239 rtx dwarf = NULL_RTX;
7240 rtx adjust_sp_rtx, reg;
7241 int saved_size = cfun->machine->frame.save_libcall_adjustment;
7243 /* Debug info for adjust sp. */
7244 adjust_sp_rtx =
7245 gen_rtx_SET (stack_pointer_rtx,
7246 gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (saved_size)));
7247 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, adjust_sp_rtx,
7248 dwarf);
7250 for (int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
7251 if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST))
7253 reg = gen_rtx_REG (Pmode, regno);
7254 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
7257 return dwarf;
7260 /* return true if popretz pattern can be matched.
7261 set (reg 10 a0) (const_int 0)
7262 use (reg 10 a0)
7263 NOTE_INSN_EPILOGUE_BEG */
7264 static rtx_insn *
7265 riscv_zcmp_can_use_popretz (void)
7267 rtx_insn *insn = NULL, *use = NULL, *clear = NULL;
7269 /* sequence stack for NOTE_INSN_EPILOGUE_BEG*/
7270 struct sequence_stack *outer_seq = get_current_sequence ()->next;
7271 if (!outer_seq)
7272 return NULL;
7273 insn = outer_seq->first;
7274 if (!insn || !NOTE_P (insn) || NOTE_KIND (insn) != NOTE_INSN_EPILOGUE_BEG)
7275 return NULL;
7277 /* sequence stack for the insn before NOTE_INSN_EPILOGUE_BEG*/
7278 outer_seq = outer_seq->next;
7279 if (outer_seq)
7280 insn = outer_seq->last;
7282 /* skip notes */
7283 while (insn && NOTE_P (insn))
7285 insn = PREV_INSN (insn);
7287 use = insn;
7289 /* match use (reg 10 a0) */
7290 if (use == NULL || !INSN_P (use) || GET_CODE (PATTERN (use)) != USE
7291 || !REG_P (XEXP (PATTERN (use), 0))
7292 || REGNO (XEXP (PATTERN (use), 0)) != A0_REGNUM)
7293 return NULL;
7295 /* match set (reg 10 a0) (const_int 0 [0]) */
7296 clear = PREV_INSN (use);
7297 if (clear != NULL && INSN_P (clear) && GET_CODE (PATTERN (clear)) == SET
7298 && REG_P (SET_DEST (PATTERN (clear)))
7299 && REGNO (SET_DEST (PATTERN (clear))) == A0_REGNUM
7300 && SET_SRC (PATTERN (clear)) == const0_rtx)
7301 return clear;
7303 return NULL;
7306 static void
7307 riscv_gen_multi_pop_insn (bool use_multi_pop_normal, unsigned mask,
7308 unsigned multipop_size)
7310 rtx insn;
7311 unsigned regs_count = riscv_multi_push_regs_count (mask);
7313 if (!use_multi_pop_normal)
7314 insn = emit_insn (
7315 riscv_gen_multi_push_pop_insn (POP_IDX, multipop_size, regs_count));
7316 else if (rtx_insn *clear_a0_insn = riscv_zcmp_can_use_popretz ())
7318 delete_insn (NEXT_INSN (clear_a0_insn));
7319 delete_insn (clear_a0_insn);
7320 insn = emit_jump_insn (
7321 riscv_gen_multi_push_pop_insn (POPRETZ_IDX, multipop_size, regs_count));
7323 else
7324 insn = emit_jump_insn (
7325 riscv_gen_multi_push_pop_insn (POPRET_IDX, multipop_size, regs_count));
7327 rtx dwarf = riscv_adjust_multi_pop_cfi_epilogue (multipop_size);
7328 RTX_FRAME_RELATED_P (insn) = 1;
7329 REG_NOTES (insn) = dwarf;
7332 /* Expand an "epilogue", "sibcall_epilogue", or "eh_return_internal" pattern;
7333 style says which. */
7335 void
7336 riscv_expand_epilogue (int style)
7338 /* Split the frame into 3 steps. STEP1 is the amount of stack we should
7339 deallocate before restoring the registers. STEP2 is the amount we
7340 should deallocate afterwards including the callee saved regs. STEP3
7341 is the amount deallocated by save-restore libcall.
7343 Start off by assuming that no registers need to be restored. */
7344 struct riscv_frame_info *frame = &cfun->machine->frame;
7345 unsigned mask = frame->mask;
7346 unsigned fmask = frame->fmask;
7347 unsigned mask_fprs_push = 0;
7348 poly_int64 step2 = 0;
7349 bool use_multi_pop_normal
7350 = ((style == NORMAL_RETURN) && riscv_use_multi_push (frame));
7351 bool use_multi_pop_sibcall
7352 = ((style == SIBCALL_RETURN) && riscv_use_multi_push (frame));
7353 bool use_multi_pop = use_multi_pop_normal || use_multi_pop_sibcall;
7355 bool use_restore_libcall
7356 = !use_multi_pop
7357 && ((style == NORMAL_RETURN) && riscv_use_save_libcall (frame));
7358 unsigned libcall_size = use_restore_libcall && !use_multi_pop
7359 ? frame->save_libcall_adjustment
7360 : 0;
7361 unsigned multipop_size
7362 = use_multi_pop ? frame->multi_push_adj_base + frame->multi_push_adj_addi
7363 : 0;
7364 rtx ra = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
7365 unsigned th_int_mask = 0;
7366 rtx insn;
7368 /* We need to add memory barrier to prevent read from deallocated stack. */
7369 bool need_barrier_p = known_ne (get_frame_size ()
7370 + cfun->machine->frame.arg_pointer_offset, 0);
7372 if (cfun->machine->naked_p)
7374 gcc_assert (style == NORMAL_RETURN);
7376 emit_jump_insn (gen_return ());
7378 return;
7381 if ((style == NORMAL_RETURN) && riscv_can_use_return_insn ())
7383 emit_jump_insn (gen_return ());
7384 return;
7387 /* Reset the epilogue cfa info before starting to emit the epilogue. */
7388 epilogue_cfa_sp_offset = 0;
7390 /* Move past any dynamic stack allocations. */
7391 if (cfun->calls_alloca)
7393 /* Emit a barrier to prevent loads from a deallocated stack. */
7394 riscv_emit_stack_tie ();
7395 need_barrier_p = false;
7397 poly_int64 adjust_offset = -frame->hard_frame_pointer_offset;
7398 rtx adjust = NULL_RTX;
7400 if (!adjust_offset.is_constant ())
7402 rtx tmp1 = RISCV_PROLOGUE_TEMP (Pmode);
7403 rtx tmp2 = RISCV_PROLOGUE_TEMP2 (Pmode);
7404 riscv_legitimize_poly_move (Pmode, tmp1, tmp2,
7405 gen_int_mode (adjust_offset, Pmode));
7406 adjust = tmp1;
7408 else
7410 if (!SMALL_OPERAND (adjust_offset.to_constant ()))
7412 riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode),
7413 GEN_INT (adjust_offset.to_constant ()));
7414 adjust = RISCV_PROLOGUE_TEMP (Pmode);
7416 else
7417 adjust = GEN_INT (adjust_offset.to_constant ());
7420 insn = emit_insn (
7421 gen_add3_insn (stack_pointer_rtx, hard_frame_pointer_rtx,
7422 adjust));
7424 rtx dwarf = NULL_RTX;
7425 rtx cfa_adjust_value = gen_rtx_PLUS (
7426 Pmode, hard_frame_pointer_rtx,
7427 gen_int_mode (-frame->hard_frame_pointer_offset, Pmode));
7428 rtx cfa_adjust_rtx = gen_rtx_SET (stack_pointer_rtx, cfa_adjust_value);
7429 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, cfa_adjust_rtx, dwarf);
7430 RTX_FRAME_RELATED_P (insn) = 1;
7432 REG_NOTES (insn) = dwarf;
7435 if (use_restore_libcall || use_multi_pop)
7436 frame->mask = 0; /* Temporarily fib that we need not restore GPRs. */
7438 /* If we need to restore registers, deallocate as much stack as
7439 possible in the second step without going out of range. */
7440 if (use_multi_pop)
7442 if (frame->fmask
7443 && known_gt (frame->total_size - multipop_size,
7444 frame->frame_pointer_offset))
7445 step2
7446 = riscv_first_stack_step (frame, frame->total_size - multipop_size);
7448 else if ((frame->mask | frame->fmask) != 0)
7449 step2 = riscv_first_stack_step (frame, frame->total_size - libcall_size);
7451 if (use_restore_libcall || use_multi_pop)
7452 frame->mask = mask; /* Undo the above fib. */
7454 poly_int64 step1;
7455 /* STEP1 must be set to the bottom of vector registers save area if any
7456 vector registers need be preversed. */
7457 if (frame->vmask != 0)
7459 step1 = frame->v_sp_offset_bottom;
7460 step2 = frame->total_size - step1 - libcall_size - multipop_size;
7462 else
7463 step1 = frame->total_size - step2 - libcall_size - multipop_size;
7465 /* Set TARGET to BASE + STEP1. */
7466 if (known_gt (step1, 0))
7468 /* Emit a barrier to prevent loads from a deallocated stack. */
7469 riscv_emit_stack_tie ();
7470 need_barrier_p = false;
7472 /* Restore the scalable frame which is assigned in prologue. */
7473 if (!step1.is_constant ())
7475 poly_int64 scalable_frame = step1;
7476 scalable_frame.coeffs[0] = step1.coeffs[1];
7477 riscv_v_adjust_scalable_frame (stack_pointer_rtx, scalable_frame,
7478 true);
7479 step1 -= scalable_frame;
7482 /* Get an rtx for STEP1 that we can add to BASE.
7483 Skip if adjust equal to zero. */
7484 if (step1.to_constant () != 0)
7486 rtx adjust = GEN_INT (step1.to_constant ());
7487 if (!SMALL_OPERAND (step1.to_constant ()))
7489 riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode), adjust);
7490 adjust = RISCV_PROLOGUE_TEMP (Pmode);
7493 insn = emit_insn (gen_add3_insn (stack_pointer_rtx,
7494 stack_pointer_rtx,
7495 adjust));
7496 rtx dwarf = NULL_RTX;
7497 rtx cfa_adjust_rtx
7498 = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
7499 gen_int_mode (step2 + libcall_size + multipop_size,
7500 Pmode));
7502 dwarf = alloc_reg_note (REG_CFA_DEF_CFA, cfa_adjust_rtx, dwarf);
7503 RTX_FRAME_RELATED_P (insn) = 1;
7505 REG_NOTES (insn) = dwarf;
7508 else if (frame_pointer_needed)
7510 /* Tell riscv_restore_reg to emit dwarf to redefine CFA when restoring
7511 old value of FP. */
7512 epilogue_cfa_sp_offset = step2;
7515 if (use_multi_pop)
7517 frame->mask = 0; /* Temporarily fib that we need not restore GPRs. */
7518 if (fmask)
7520 mask_fprs_push = get_multi_push_fpr_mask (frame->multi_push_adj_addi
7521 / UNITS_PER_WORD);
7522 frame->fmask &= ~mask_fprs_push; /* FPRs not saved by cm.push */
7525 else if (use_restore_libcall)
7526 frame->mask = 0; /* Temporarily fib that we need not restore GPRs. */
7528 th_int_mask = th_int_get_mask (frame->mask);
7529 if (th_int_mask && TH_INT_INTERRUPT (cfun))
7531 frame->mask &= ~th_int_mask;
7533 /* RISCV_PROLOGUE_TEMP may be used to handle some CSR for
7534 interrupts, such as fcsr. */
7535 if ((TARGET_HARD_FLOAT && frame->fmask)
7536 || (TARGET_ZFINX && frame->mask))
7537 frame->mask |= (1 << RISCV_PROLOGUE_TEMP_REGNUM);
7540 /* Restore the registers. */
7541 riscv_for_each_saved_v_reg (step2, riscv_restore_reg, false);
7542 riscv_for_each_saved_reg (frame->total_size - step2 - libcall_size
7543 - multipop_size,
7544 riscv_restore_reg, true, style == EXCEPTION_RETURN);
7546 if (th_int_mask && TH_INT_INTERRUPT (cfun))
7548 frame->mask = mask; /* Undo the above fib. */
7549 unsigned save_adjustment = th_int_get_save_adjustment ();
7550 gcc_assert (step2.to_constant () >= save_adjustment);
7551 step2 -= save_adjustment;
7554 if (use_restore_libcall)
7555 frame->mask = mask; /* Undo the above fib. */
7557 if (need_barrier_p)
7558 riscv_emit_stack_tie ();
7560 /* Deallocate the final bit of the frame. */
7561 if (step2.to_constant () > 0)
7563 insn = emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
7564 GEN_INT (step2.to_constant ())));
7566 rtx dwarf = NULL_RTX;
7567 rtx cfa_adjust_rtx
7568 = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
7569 GEN_INT (libcall_size + multipop_size));
7570 dwarf = alloc_reg_note (REG_CFA_DEF_CFA, cfa_adjust_rtx, dwarf);
7571 RTX_FRAME_RELATED_P (insn) = 1;
7573 REG_NOTES (insn) = dwarf;
7576 if (use_multi_pop)
7578 /* restore FPRs pushed by cm.push. */
7579 frame->fmask = fmask & mask_fprs_push;
7580 if (frame->fmask)
7581 riscv_for_each_saved_reg (frame->total_size - libcall_size
7582 - multipop_size,
7583 riscv_restore_reg, true,
7584 style == EXCEPTION_RETURN);
7585 /* Undo the above fib. */
7586 frame->mask = mask;
7587 frame->fmask = fmask;
7588 riscv_gen_multi_pop_insn (use_multi_pop_normal, frame->mask,
7589 multipop_size);
7590 if (use_multi_pop_normal)
7591 return;
7593 else if (use_restore_libcall)
7595 rtx dwarf = riscv_adjust_libcall_cfi_epilogue ();
7596 insn = emit_insn (gen_gpr_restore (GEN_INT (riscv_save_libcall_count (mask))));
7597 RTX_FRAME_RELATED_P (insn) = 1;
7598 REG_NOTES (insn) = dwarf;
7600 emit_jump_insn (gen_gpr_restore_return (ra));
7601 return;
7604 /* Add in the __builtin_eh_return stack adjustment. */
7605 if ((style == EXCEPTION_RETURN) && crtl->calls_eh_return)
7606 emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
7607 EH_RETURN_STACKADJ_RTX));
7609 /* Return from interrupt. */
7610 if (cfun->machine->interrupt_handler_p)
7612 enum riscv_privilege_levels mode = cfun->machine->interrupt_mode;
7614 gcc_assert (mode != UNKNOWN_MODE);
7616 if (th_int_mask && TH_INT_INTERRUPT (cfun))
7617 emit_jump_insn (gen_th_int_pop ());
7618 else if (mode == MACHINE_MODE)
7619 emit_jump_insn (gen_riscv_mret ());
7620 else if (mode == SUPERVISOR_MODE)
7621 emit_jump_insn (gen_riscv_sret ());
7622 else
7623 emit_jump_insn (gen_riscv_uret ());
7625 else if (style != SIBCALL_RETURN)
7626 emit_jump_insn (gen_simple_return_internal (ra));
7629 /* Implement EPILOGUE_USES. */
7631 bool
7632 riscv_epilogue_uses (unsigned int regno)
7634 if (regno == RETURN_ADDR_REGNUM)
7635 return true;
7637 if (epilogue_completed && cfun->machine->interrupt_handler_p)
7639 /* An interrupt function restores temp regs, so we must indicate that
7640 they are live at function end. */
7641 if (df_regs_ever_live_p (regno)
7642 || (!crtl->is_leaf && call_used_or_fixed_reg_p (regno)))
7643 return true;
7646 return false;
7649 static bool
7650 riscv_avoid_shrink_wrapping_separate ()
7652 if (riscv_use_save_libcall (&cfun->machine->frame)
7653 || cfun->machine->interrupt_handler_p
7654 || !cfun->machine->frame.gp_sp_offset.is_constant ())
7655 return true;
7657 return false;
7660 /* Implement TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS. */
7662 static sbitmap
7663 riscv_get_separate_components (void)
7665 HOST_WIDE_INT offset;
7666 sbitmap components = sbitmap_alloc (FIRST_PSEUDO_REGISTER);
7667 bitmap_clear (components);
7669 if (riscv_avoid_shrink_wrapping_separate ())
7670 return components;
7672 offset = cfun->machine->frame.gp_sp_offset.to_constant ();
7673 for (unsigned int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
7674 if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST))
7676 /* We can only wrap registers that have small operand offsets.
7677 For large offsets a pseudo register might be needed which
7678 cannot be created during the shrink wrapping pass. */
7679 if (SMALL_OPERAND (offset))
7680 bitmap_set_bit (components, regno);
7682 offset -= UNITS_PER_WORD;
7685 offset = cfun->machine->frame.fp_sp_offset.to_constant ();
7686 for (unsigned int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
7687 if (BITSET_P (cfun->machine->frame.fmask, regno - FP_REG_FIRST))
7689 machine_mode mode = TARGET_DOUBLE_FLOAT ? DFmode : SFmode;
7691 /* We can only wrap registers that have small operand offsets.
7692 For large offsets a pseudo register might be needed which
7693 cannot be created during the shrink wrapping pass. */
7694 if (SMALL_OPERAND (offset))
7695 bitmap_set_bit (components, regno);
7697 offset -= GET_MODE_SIZE (mode).to_constant ();
7700 /* Don't mess with the hard frame pointer. */
7701 if (frame_pointer_needed)
7702 bitmap_clear_bit (components, HARD_FRAME_POINTER_REGNUM);
7704 bitmap_clear_bit (components, RETURN_ADDR_REGNUM);
7706 return components;
7709 /* Implement TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB. */
7711 static sbitmap
7712 riscv_components_for_bb (basic_block bb)
7714 bitmap in = DF_LIVE_IN (bb);
7715 bitmap gen = &DF_LIVE_BB_INFO (bb)->gen;
7716 bitmap kill = &DF_LIVE_BB_INFO (bb)->kill;
7718 sbitmap components = sbitmap_alloc (FIRST_PSEUDO_REGISTER);
7719 bitmap_clear (components);
7721 function_abi_aggregator callee_abis;
7722 rtx_insn *insn;
7723 FOR_BB_INSNS (bb, insn)
7724 if (CALL_P (insn))
7725 callee_abis.note_callee_abi (insn_callee_abi (insn));
7726 HARD_REG_SET extra_caller_saves = callee_abis.caller_save_regs (*crtl->abi);
7728 /* GPRs are used in a bb if they are in the IN, GEN, or KILL sets. */
7729 for (unsigned int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
7730 if (!fixed_regs[regno]
7731 && !crtl->abi->clobbers_full_reg_p (regno)
7732 && (TEST_HARD_REG_BIT (extra_caller_saves, regno)
7733 || bitmap_bit_p (in, regno)
7734 || bitmap_bit_p (gen, regno)
7735 || bitmap_bit_p (kill, regno)))
7736 bitmap_set_bit (components, regno);
7738 for (unsigned int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
7739 if (!fixed_regs[regno]
7740 && !crtl->abi->clobbers_full_reg_p (regno)
7741 && (TEST_HARD_REG_BIT (extra_caller_saves, regno)
7742 || bitmap_bit_p (in, regno)
7743 || bitmap_bit_p (gen, regno)
7744 || bitmap_bit_p (kill, regno)))
7745 bitmap_set_bit (components, regno);
7747 return components;
7750 /* Implement TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS. */
7752 static void
7753 riscv_disqualify_components (sbitmap, edge, sbitmap, bool)
7755 /* Nothing to do for riscv. */
7758 static void
7759 riscv_process_components (sbitmap components, bool prologue_p)
7761 HOST_WIDE_INT offset;
7762 riscv_save_restore_fn fn = prologue_p? riscv_save_reg : riscv_restore_reg;
7764 offset = cfun->machine->frame.gp_sp_offset.to_constant ();
7765 for (unsigned int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
7766 if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST))
7768 if (bitmap_bit_p (components, regno))
7769 riscv_save_restore_reg (word_mode, regno, offset, fn);
7771 offset -= UNITS_PER_WORD;
7774 offset = cfun->machine->frame.fp_sp_offset.to_constant ();
7775 for (unsigned int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
7776 if (BITSET_P (cfun->machine->frame.fmask, regno - FP_REG_FIRST))
7778 machine_mode mode = TARGET_DOUBLE_FLOAT ? DFmode : SFmode;
7780 if (bitmap_bit_p (components, regno))
7781 riscv_save_restore_reg (mode, regno, offset, fn);
7783 offset -= GET_MODE_SIZE (mode).to_constant ();
7787 /* Implement TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS. */
7789 static void
7790 riscv_emit_prologue_components (sbitmap components)
7792 riscv_process_components (components, true);
7795 /* Implement TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS. */
7797 static void
7798 riscv_emit_epilogue_components (sbitmap components)
7800 riscv_process_components (components, false);
7803 static void
7804 riscv_set_handled_components (sbitmap components)
7806 for (unsigned int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
7807 if (bitmap_bit_p (components, regno))
7808 cfun->machine->reg_is_wrapped_separately[regno] = true;
7810 for (unsigned int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
7811 if (bitmap_bit_p (components, regno))
7812 cfun->machine->reg_is_wrapped_separately[regno] = true;
7815 /* Return nonzero if this function is known to have a null epilogue.
7816 This allows the optimizer to omit jumps to jumps if no stack
7817 was created. */
7819 bool
7820 riscv_can_use_return_insn (void)
7822 return (reload_completed && known_eq (cfun->machine->frame.total_size, 0)
7823 && ! cfun->machine->interrupt_handler_p);
7826 /* Given that there exists at least one variable that is set (produced)
7827 by OUT_INSN and read (consumed) by IN_INSN, return true iff
7828 IN_INSN represents one or more memory store operations and none of
7829 the variables set by OUT_INSN is used by IN_INSN as the address of a
7830 store operation. If either IN_INSN or OUT_INSN does not represent
7831 a "single" RTL SET expression (as loosely defined by the
7832 implementation of the single_set function) or a PARALLEL with only
7833 SETs, CLOBBERs, and USEs inside, this function returns false.
7835 Borrowed from rs6000, riscv_store_data_bypass_p checks for certain
7836 conditions that result in assertion failures in the generic
7837 store_data_bypass_p function and returns FALSE in such cases.
7839 This is required to make -msave-restore work with the sifive-7
7840 pipeline description. */
7842 bool
7843 riscv_store_data_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn)
7845 rtx out_set, in_set;
7846 rtx out_pat, in_pat;
7847 rtx out_exp, in_exp;
7848 int i, j;
7850 in_set = single_set (in_insn);
7851 if (in_set)
7853 if (MEM_P (SET_DEST (in_set)))
7855 out_set = single_set (out_insn);
7856 if (!out_set)
7858 out_pat = PATTERN (out_insn);
7859 if (GET_CODE (out_pat) == PARALLEL)
7861 for (i = 0; i < XVECLEN (out_pat, 0); i++)
7863 out_exp = XVECEXP (out_pat, 0, i);
7864 if ((GET_CODE (out_exp) == CLOBBER)
7865 || (GET_CODE (out_exp) == USE))
7866 continue;
7867 else if (GET_CODE (out_exp) != SET)
7868 return false;
7874 else
7876 in_pat = PATTERN (in_insn);
7877 if (GET_CODE (in_pat) != PARALLEL)
7878 return false;
7880 for (i = 0; i < XVECLEN (in_pat, 0); i++)
7882 in_exp = XVECEXP (in_pat, 0, i);
7883 if ((GET_CODE (in_exp) == CLOBBER) || (GET_CODE (in_exp) == USE))
7884 continue;
7885 else if (GET_CODE (in_exp) != SET)
7886 return false;
7888 if (MEM_P (SET_DEST (in_exp)))
7890 out_set = single_set (out_insn);
7891 if (!out_set)
7893 out_pat = PATTERN (out_insn);
7894 if (GET_CODE (out_pat) != PARALLEL)
7895 return false;
7896 for (j = 0; j < XVECLEN (out_pat, 0); j++)
7898 out_exp = XVECEXP (out_pat, 0, j);
7899 if ((GET_CODE (out_exp) == CLOBBER)
7900 || (GET_CODE (out_exp) == USE))
7901 continue;
7902 else if (GET_CODE (out_exp) != SET)
7903 return false;
7910 return store_data_bypass_p (out_insn, in_insn);
7913 /* Implement TARGET_SECONDARY_MEMORY_NEEDED.
7915 When floating-point registers are wider than integer ones, moves between
7916 them must go through memory. */
7918 static bool
7919 riscv_secondary_memory_needed (machine_mode mode, reg_class_t class1,
7920 reg_class_t class2)
7922 return (!riscv_v_ext_mode_p (mode)
7923 && GET_MODE_SIZE (mode).to_constant () > UNITS_PER_WORD
7924 && (class1 == FP_REGS) != (class2 == FP_REGS)
7925 && !TARGET_XTHEADFMV
7926 && !TARGET_ZFA);
7929 /* Implement TARGET_REGISTER_MOVE_COST. */
7931 static int
7932 riscv_register_move_cost (machine_mode mode,
7933 reg_class_t from, reg_class_t to)
7935 if ((from == FP_REGS && to == GR_REGS) ||
7936 (from == GR_REGS && to == FP_REGS))
7937 return tune_param->fmv_cost;
7939 return riscv_secondary_memory_needed (mode, from, to) ? 8 : 2;
7942 /* Implement TARGET_HARD_REGNO_NREGS. */
7944 static unsigned int
7945 riscv_hard_regno_nregs (unsigned int regno, machine_mode mode)
7947 if (riscv_v_ext_vector_mode_p (mode))
7949 /* Handle fractional LMUL, it only occupy part of vector register but
7950 still need one vector register to hold. */
7951 if (maybe_lt (GET_MODE_SIZE (mode), UNITS_PER_V_REG))
7952 return 1;
7954 return exact_div (GET_MODE_SIZE (mode), UNITS_PER_V_REG).to_constant ();
7957 /* For tuple modes, the number of register = NF * LMUL. */
7958 if (riscv_v_ext_tuple_mode_p (mode))
7960 unsigned int nf = riscv_vector::get_nf (mode);
7961 machine_mode subpart_mode = riscv_vector::get_subpart_mode (mode);
7962 poly_int64 size = GET_MODE_SIZE (subpart_mode);
7963 gcc_assert (known_eq (size * nf, GET_MODE_SIZE (mode)));
7964 if (maybe_lt (size, UNITS_PER_V_REG))
7965 return nf;
7966 else
7968 unsigned int lmul = exact_div (size, UNITS_PER_V_REG).to_constant ();
7969 return nf * lmul;
7973 /* For VLS modes, we allocate registers according to TARGET_MIN_VLEN. */
7974 if (riscv_v_ext_vls_mode_p (mode))
7976 int size = GET_MODE_BITSIZE (mode).to_constant ();
7977 if (size < TARGET_MIN_VLEN)
7978 return 1;
7979 else
7980 return size / TARGET_MIN_VLEN;
7983 /* mode for VL or VTYPE are just a marker, not holding value,
7984 so it always consume one register. */
7985 if (VTYPE_REG_P (regno) || VL_REG_P (regno) || VXRM_REG_P (regno)
7986 || FRM_REG_P (regno))
7987 return 1;
7989 /* Assume every valid non-vector mode fits in one vector register. */
7990 if (V_REG_P (regno))
7991 return 1;
7993 if (FP_REG_P (regno))
7994 return (GET_MODE_SIZE (mode).to_constant () + UNITS_PER_FP_REG - 1) / UNITS_PER_FP_REG;
7996 /* All other registers are word-sized. */
7997 return (GET_MODE_SIZE (mode).to_constant () + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
8000 /* Implement TARGET_HARD_REGNO_MODE_OK. */
8002 static bool
8003 riscv_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
8005 unsigned int nregs = riscv_hard_regno_nregs (regno, mode);
8007 if (GP_REG_P (regno))
8009 if (riscv_v_ext_mode_p (mode))
8010 return false;
8012 if (!GP_REG_P (regno + nregs - 1))
8013 return false;
8015 else if (FP_REG_P (regno))
8017 if (riscv_v_ext_mode_p (mode))
8018 return false;
8020 if (!FP_REG_P (regno + nregs - 1))
8021 return false;
8023 if (GET_MODE_CLASS (mode) != MODE_FLOAT
8024 && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
8025 return false;
8027 /* Only use callee-saved registers if a potential callee is guaranteed
8028 to spill the requisite width. */
8029 if (GET_MODE_UNIT_SIZE (mode) > UNITS_PER_FP_REG
8030 || (!call_used_or_fixed_reg_p (regno)
8031 && GET_MODE_UNIT_SIZE (mode) > UNITS_PER_FP_ARG))
8032 return false;
8034 else if (V_REG_P (regno))
8036 if (!riscv_v_ext_mode_p (mode))
8037 return false;
8039 if (!V_REG_P (regno + nregs - 1))
8040 return false;
8042 int regno_alignment = riscv_get_v_regno_alignment (mode);
8043 if (regno_alignment != 1)
8044 return ((regno % regno_alignment) == 0);
8046 else if (VTYPE_REG_P (regno) || VL_REG_P (regno) || VXRM_REG_P (regno)
8047 || FRM_REG_P (regno))
8048 return true;
8049 else
8050 return false;
8052 /* Require same callee-savedness for all registers. */
8053 for (unsigned i = 1; i < nregs; i++)
8054 if (call_used_or_fixed_reg_p (regno)
8055 != call_used_or_fixed_reg_p (regno + i))
8056 return false;
8058 /* Only use even registers in RV32 ZDINX */
8059 if (!TARGET_64BIT && TARGET_ZDINX){
8060 if (GET_MODE_CLASS (mode) == MODE_FLOAT &&
8061 GET_MODE_UNIT_SIZE (mode) == GET_MODE_SIZE (DFmode))
8062 return !(regno & 1);
8065 return true;
8068 /* Implement TARGET_MODES_TIEABLE_P.
8070 Don't allow floating-point modes to be tied, since type punning of
8071 single-precision and double-precision is implementation defined. */
8073 static bool
8074 riscv_modes_tieable_p (machine_mode mode1, machine_mode mode2)
8076 /* We don't allow different REG_CLASS modes tieable since it
8077 will cause ICE in register allocation (RA).
8078 E.g. V2SI and DI are not tieable. */
8079 if (riscv_v_ext_mode_p (mode1) != riscv_v_ext_mode_p (mode2))
8080 return false;
8081 return (mode1 == mode2
8082 || !(GET_MODE_CLASS (mode1) == MODE_FLOAT
8083 && GET_MODE_CLASS (mode2) == MODE_FLOAT));
8086 /* Implement CLASS_MAX_NREGS. */
8088 static unsigned char
8089 riscv_class_max_nregs (reg_class_t rclass, machine_mode mode)
8091 if (reg_class_subset_p (rclass, FP_REGS))
8092 return riscv_hard_regno_nregs (FP_REG_FIRST, mode);
8094 if (reg_class_subset_p (rclass, GR_REGS))
8095 return riscv_hard_regno_nregs (GP_REG_FIRST, mode);
8097 if (reg_class_subset_p (rclass, V_REGS))
8098 return riscv_hard_regno_nregs (V_REG_FIRST, mode);
8100 return 0;
8103 /* Implement TARGET_MEMORY_MOVE_COST. */
8105 static int
8106 riscv_memory_move_cost (machine_mode mode, reg_class_t rclass, bool in)
8108 return (tune_param->memory_cost
8109 + memory_move_secondary_cost (mode, rclass, in));
8112 /* Return the number of instructions that can be issued per cycle. */
8114 static int
8115 riscv_issue_rate (void)
8117 return tune_param->issue_rate;
8120 /* Implement TARGET_SCHED_VARIABLE_ISSUE. */
8121 static int
8122 riscv_sched_variable_issue (FILE *, int, rtx_insn *insn, int more)
8124 if (DEBUG_INSN_P (insn))
8125 return more;
8127 rtx_code code = GET_CODE (PATTERN (insn));
8128 if (code == USE || code == CLOBBER)
8129 return more;
8131 /* GHOST insns are used for blockage and similar cases which
8132 effectively end a cycle. */
8133 if (get_attr_type (insn) == TYPE_GHOST)
8134 return 0;
8136 /* If we ever encounter an insn with an unknown type, trip
8137 an assert so we can find and fix this problem. */
8138 gcc_assert (get_attr_type (insn) != TYPE_UNKNOWN);
8140 /* If we ever encounter an insn without an insn reservation, trip
8141 an assert so we can find and fix this problem. */
8142 #if 0
8143 gcc_assert (insn_has_dfa_reservation_p (insn));
8144 #endif
8146 return more - 1;
8149 /* Implement TARGET_SCHED_MACRO_FUSION_P. Return true if target supports
8150 instruction fusion of some sort. */
8152 static bool
8153 riscv_macro_fusion_p (void)
8155 return tune_param->fusible_ops != RISCV_FUSE_NOTHING;
8158 /* Return true iff the instruction fusion described by OP is enabled. */
8160 static bool
8161 riscv_fusion_enabled_p(enum riscv_fusion_pairs op)
8163 return tune_param->fusible_ops & op;
8166 /* Implement TARGET_SCHED_MACRO_FUSION_PAIR_P. Return true if PREV and CURR
8167 should be kept together during scheduling. */
8169 static bool
8170 riscv_macro_fusion_pair_p (rtx_insn *prev, rtx_insn *curr)
8172 rtx prev_set = single_set (prev);
8173 rtx curr_set = single_set (curr);
8174 /* prev and curr are simple SET insns i.e. no flag setting or branching. */
8175 bool simple_sets_p = prev_set && curr_set && !any_condjump_p (curr);
8177 if (!riscv_macro_fusion_p ())
8178 return false;
8180 if (simple_sets_p
8181 && (riscv_fusion_enabled_p (RISCV_FUSE_ZEXTW)
8182 || riscv_fusion_enabled_p (RISCV_FUSE_ZEXTWS)))
8184 /* We are trying to match the following:
8185 prev (slli) == (set (reg:DI rD)
8186 (ashift:DI (reg:DI rS) (const_int 32)))
8187 curr (slri) == (set (reg:DI rD)
8188 (lshiftrt:DI (reg:DI rD) (const_int <shift>)))
8189 with <shift> being either 32 for FUSE_ZEXTW, or
8190 `less than 32 for FUSE_ZEXTWS. */
8192 if (GET_CODE (SET_SRC (prev_set)) == ASHIFT
8193 && GET_CODE (SET_SRC (curr_set)) == LSHIFTRT
8194 && REG_P (SET_DEST (prev_set))
8195 && REG_P (SET_DEST (curr_set))
8196 && REGNO (SET_DEST (prev_set)) == REGNO (SET_DEST (curr_set))
8197 && REGNO (XEXP (SET_SRC (curr_set), 0)) == REGNO(SET_DEST (curr_set))
8198 && CONST_INT_P (XEXP (SET_SRC (prev_set), 1))
8199 && CONST_INT_P (XEXP (SET_SRC (curr_set), 1))
8200 && INTVAL (XEXP (SET_SRC (prev_set), 1)) == 32
8201 && (( INTVAL (XEXP (SET_SRC (curr_set), 1)) == 32
8202 && riscv_fusion_enabled_p(RISCV_FUSE_ZEXTW) )
8203 || ( INTVAL (XEXP (SET_SRC (curr_set), 1)) < 32
8204 && riscv_fusion_enabled_p(RISCV_FUSE_ZEXTWS))))
8205 return true;
8208 if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_ZEXTH))
8210 /* We are trying to match the following:
8211 prev (slli) == (set (reg:DI rD)
8212 (ashift:DI (reg:DI rS) (const_int 48)))
8213 curr (slri) == (set (reg:DI rD)
8214 (lshiftrt:DI (reg:DI rD) (const_int 48))) */
8216 if (GET_CODE (SET_SRC (prev_set)) == ASHIFT
8217 && GET_CODE (SET_SRC (curr_set)) == LSHIFTRT
8218 && REG_P (SET_DEST (prev_set))
8219 && REG_P (SET_DEST (curr_set))
8220 && REGNO (SET_DEST (prev_set)) == REGNO (SET_DEST (curr_set))
8221 && REGNO (XEXP (SET_SRC (curr_set), 0)) == REGNO(SET_DEST (curr_set))
8222 && CONST_INT_P (XEXP (SET_SRC (prev_set), 1))
8223 && CONST_INT_P (XEXP (SET_SRC (curr_set), 1))
8224 && INTVAL (XEXP (SET_SRC (prev_set), 1)) == 48
8225 && INTVAL (XEXP (SET_SRC (curr_set), 1)) == 48)
8226 return true;
8229 if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_LDINDEXED))
8231 /* We are trying to match the following:
8232 prev (add) == (set (reg:DI rD)
8233 (plus:DI (reg:DI rS1) (reg:DI rS2))
8234 curr (ld) == (set (reg:DI rD)
8235 (mem:DI (reg:DI rD))) */
8237 if (MEM_P (SET_SRC (curr_set))
8238 && REG_P (XEXP (SET_SRC (curr_set), 0))
8239 && REGNO (XEXP (SET_SRC (curr_set), 0)) == REGNO (SET_DEST (prev_set))
8240 && GET_CODE (SET_SRC (prev_set)) == PLUS
8241 && REG_P (XEXP (SET_SRC (prev_set), 0))
8242 && REG_P (XEXP (SET_SRC (prev_set), 1)))
8243 return true;
8245 /* We are trying to match the following:
8246 prev (add) == (set (reg:DI rD)
8247 (plus:DI (reg:DI rS1) (reg:DI rS2)))
8248 curr (lw) == (set (any_extend:DI (mem:SUBX (reg:DI rD)))) */
8250 if ((GET_CODE (SET_SRC (curr_set)) == SIGN_EXTEND
8251 || (GET_CODE (SET_SRC (curr_set)) == ZERO_EXTEND))
8252 && MEM_P (XEXP (SET_SRC (curr_set), 0))
8253 && REG_P (XEXP (XEXP (SET_SRC (curr_set), 0), 0))
8254 && REGNO (XEXP (XEXP (SET_SRC (curr_set), 0), 0)) == REGNO (SET_DEST (prev_set))
8255 && GET_CODE (SET_SRC (prev_set)) == PLUS
8256 && REG_P (XEXP (SET_SRC (prev_set), 0))
8257 && REG_P (XEXP (SET_SRC (prev_set), 1)))
8258 return true;
8261 if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_LDPREINCREMENT))
8263 /* We are trying to match the following:
8264 prev (add) == (set (reg:DI rS)
8265 (plus:DI (reg:DI rS) (const_int))
8266 curr (ld) == (set (reg:DI rD)
8267 (mem:DI (reg:DI rS))) */
8269 if (MEM_P (SET_SRC (curr_set))
8270 && REG_P (XEXP (SET_SRC (curr_set), 0))
8271 && REGNO (XEXP (SET_SRC (curr_set), 0)) == REGNO (SET_DEST (prev_set))
8272 && GET_CODE (SET_SRC (prev_set)) == PLUS
8273 && REG_P (XEXP (SET_SRC (prev_set), 0))
8274 && CONST_INT_P (XEXP (SET_SRC (prev_set), 1)))
8275 return true;
8278 if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_LUI_ADDI))
8280 /* We are trying to match the following:
8281 prev (lui) == (set (reg:DI rD) (const_int UPPER_IMM_20))
8282 curr (addi) == (set (reg:DI rD)
8283 (plus:DI (reg:DI rD) (const_int IMM12))) */
8285 if ((GET_CODE (SET_SRC (curr_set)) == LO_SUM
8286 || (GET_CODE (SET_SRC (curr_set)) == PLUS
8287 && CONST_INT_P (XEXP (SET_SRC (curr_set), 1))
8288 && SMALL_OPERAND (INTVAL (XEXP (SET_SRC (curr_set), 1)))))
8289 && (GET_CODE (SET_SRC (prev_set)) == HIGH
8290 || (CONST_INT_P (SET_SRC (prev_set))
8291 && LUI_OPERAND (INTVAL (SET_SRC (prev_set))))))
8292 return true;
8295 if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_AUIPC_ADDI))
8297 /* We are trying to match the following:
8298 prev (auipc) == (set (reg:DI rD) (unspec:DI [...] UNSPEC_AUIPC))
8299 curr (addi) == (set (reg:DI rD)
8300 (plus:DI (reg:DI rD) (const_int IMM12)))
8302 prev (auipc) == (set (reg:DI rD) (unspec:DI [...] UNSPEC_AUIPC))
8303 curr (addi) == (set (reg:DI rD)
8304 (lo_sum:DI (reg:DI rD) (const_int IMM12))) */
8306 if (GET_CODE (SET_SRC (prev_set)) == UNSPEC
8307 && XINT (prev_set, 1) == UNSPEC_AUIPC
8308 && (GET_CODE (SET_SRC (curr_set)) == LO_SUM
8309 || (GET_CODE (SET_SRC (curr_set)) == PLUS
8310 && SMALL_OPERAND (INTVAL (XEXP (SET_SRC (curr_set), 1))))))
8312 return true;
8315 if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_LUI_LD))
8317 /* We are trying to match the following:
8318 prev (lui) == (set (reg:DI rD) (const_int UPPER_IMM_20))
8319 curr (ld) == (set (reg:DI rD)
8320 (mem:DI (plus:DI (reg:DI rD) (const_int IMM12)))) */
8322 if (CONST_INT_P (SET_SRC (prev_set))
8323 && LUI_OPERAND (INTVAL (SET_SRC (prev_set)))
8324 && MEM_P (SET_SRC (curr_set))
8325 && GET_CODE (XEXP (SET_SRC (curr_set), 0)) == PLUS)
8326 return true;
8328 if (GET_CODE (SET_SRC (prev_set)) == HIGH
8329 && MEM_P (SET_SRC (curr_set))
8330 && GET_CODE (XEXP (SET_SRC (curr_set), 0)) == LO_SUM
8331 && REGNO (SET_DEST (prev_set)) == REGNO (XEXP (XEXP (SET_SRC (curr_set), 0), 0)))
8332 return true;
8334 if (GET_CODE (SET_SRC (prev_set)) == HIGH
8335 && (GET_CODE (SET_SRC (curr_set)) == SIGN_EXTEND
8336 || GET_CODE (SET_SRC (curr_set)) == ZERO_EXTEND)
8337 && MEM_P (XEXP (SET_SRC (curr_set), 0))
8338 && (GET_CODE (XEXP (XEXP (SET_SRC (curr_set), 0), 0)) == LO_SUM
8339 && REGNO (SET_DEST (prev_set)) == REGNO (XEXP (XEXP (XEXP (SET_SRC (curr_set), 0), 0), 0))))
8340 return true;
8343 if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_AUIPC_LD))
8345 /* We are trying to match the following:
8346 prev (auipc) == (set (reg:DI rD) (unspec:DI [...] UNSPEC_AUIPC))
8347 curr (ld) == (set (reg:DI rD)
8348 (mem:DI (plus:DI (reg:DI rD) (const_int IMM12)))) */
8350 if (GET_CODE (SET_SRC (prev_set)) == UNSPEC
8351 && XINT (prev_set, 1) == UNSPEC_AUIPC
8352 && MEM_P (SET_SRC (curr_set))
8353 && GET_CODE (XEXP (SET_SRC (curr_set), 0)) == PLUS)
8354 return true;
8357 if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_ALIGNED_STD))
8359 /* We are trying to match the following:
8360 prev (sd) == (set (mem (plus (reg sp|fp) (const_int)))
8361 (reg rS1))
8362 curr (sd) == (set (mem (plus (reg sp|fp) (const_int)))
8363 (reg rS2)) */
8365 if (MEM_P (SET_DEST (prev_set))
8366 && MEM_P (SET_DEST (curr_set))
8367 /* We can probably relax this condition. The documentation is a bit
8368 unclear about sub-word cases. So we just model DImode for now. */
8369 && GET_MODE (SET_DEST (curr_set)) == DImode
8370 && GET_MODE (SET_DEST (prev_set)) == DImode)
8372 rtx base_prev, base_curr, offset_prev, offset_curr;
8374 extract_base_offset_in_addr (SET_DEST (prev_set), &base_prev, &offset_prev);
8375 extract_base_offset_in_addr (SET_DEST (curr_set), &base_curr, &offset_curr);
8377 /* The two stores must be contained within opposite halves of the same
8378 16 byte aligned block of memory. We know that the stack pointer and
8379 the frame pointer have suitable alignment. So we just need to check
8380 the offsets of the two stores for suitable alignment.
8382 Originally the thought was to check MEM_ALIGN, but that was reporting
8383 incorrect alignments, even for SP/FP accesses, so we gave up on that
8384 approach. */
8385 if (base_prev != NULL_RTX
8386 && base_curr != NULL_RTX
8387 && REG_P (base_prev)
8388 && REG_P (base_curr)
8389 && REGNO (base_prev) == REGNO (base_curr)
8390 && (REGNO (base_prev) == STACK_POINTER_REGNUM
8391 || REGNO (base_prev) == HARD_FRAME_POINTER_REGNUM)
8392 && ((INTVAL (offset_prev) == INTVAL (offset_curr) + 8
8393 && (INTVAL (offset_prev) % 16) == 0)
8394 || ((INTVAL (offset_curr) == INTVAL (offset_prev) + 8)
8395 && (INTVAL (offset_curr) % 16) == 0)))
8396 return true;
8400 return false;
8403 /* Adjust the cost/latency of instructions for scheduling.
8404 For now this is just used to change the latency of vector instructions
8405 according to their LMUL. We assume that an insn with LMUL == 8 requires
8406 eight times more execution cycles than the same insn with LMUL == 1.
8407 As this may cause very high latencies which lead to scheduling artifacts
8408 we currently only perform the adjustment when -madjust-lmul-cost is given.
8410 static int
8411 riscv_sched_adjust_cost (rtx_insn *, int, rtx_insn *insn, int cost,
8412 unsigned int)
8414 /* Only do adjustments for the generic out-of-order scheduling model. */
8415 if (!TARGET_VECTOR || riscv_microarchitecture != generic_ooo)
8416 return cost;
8418 if (recog_memoized (insn) < 0)
8419 return cost;
8421 enum attr_type type = get_attr_type (insn);
8423 if (type == TYPE_VFREDO || type == TYPE_VFWREDO)
8425 /* TODO: For ordered reductions scale the base cost relative to the
8426 number of units. */
8430 /* Don't do any LMUL-based latency adjustment unless explicitly asked to. */
8431 if (!TARGET_ADJUST_LMUL_COST)
8432 return cost;
8434 /* vsetvl has a vlmul attribute but its latency does not depend on it. */
8435 if (type == TYPE_VSETVL || type == TYPE_VSETVL_PRE)
8436 return cost;
8438 enum riscv_vector::vlmul_type lmul =
8439 (riscv_vector::vlmul_type)get_attr_vlmul (insn);
8441 double factor = 1;
8442 switch (lmul)
8444 case riscv_vector::LMUL_2:
8445 factor = 2;
8446 break;
8447 case riscv_vector::LMUL_4:
8448 factor = 4;
8449 break;
8450 case riscv_vector::LMUL_8:
8451 factor = 8;
8452 break;
8453 case riscv_vector::LMUL_F2:
8454 factor = 0.5;
8455 break;
8456 case riscv_vector::LMUL_F4:
8457 factor = 0.25;
8458 break;
8459 case riscv_vector::LMUL_F8:
8460 factor = 0.125;
8461 break;
8462 default:
8463 factor = 1;
8466 /* If the latency was nonzero, keep it that way. */
8467 int new_cost = MAX (cost > 0 ? 1 : 0, cost * factor);
8469 return new_cost;
8472 /* Auxiliary function to emit RISC-V ELF attribute. */
8473 static void
8474 riscv_emit_attribute ()
8476 fprintf (asm_out_file, "\t.attribute arch, \"%s\"\n",
8477 riscv_arch_str ().c_str ());
8479 fprintf (asm_out_file, "\t.attribute unaligned_access, %d\n",
8480 TARGET_STRICT_ALIGN ? 0 : 1);
8482 fprintf (asm_out_file, "\t.attribute stack_align, %d\n",
8483 riscv_stack_boundary / 8);
8486 /* Output .variant_cc for function symbol which follows vector calling
8487 convention. */
8489 static void
8490 riscv_asm_output_variant_cc (FILE *stream, const tree decl, const char *name)
8492 if (TREE_CODE (decl) == FUNCTION_DECL)
8494 riscv_cc cc = (riscv_cc) fndecl_abi (decl).id ();
8495 if (cc == RISCV_CC_V)
8497 fprintf (stream, "\t.variant_cc\t");
8498 assemble_name (stream, name);
8499 fprintf (stream, "\n");
8504 /* Implement ASM_DECLARE_FUNCTION_NAME. */
8506 void
8507 riscv_declare_function_name (FILE *stream, const char *name, tree fndecl)
8509 riscv_asm_output_variant_cc (stream, fndecl, name);
8510 ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "function");
8511 ASM_OUTPUT_FUNCTION_LABEL (stream, name, fndecl);
8512 if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl))
8514 fprintf (stream, "\t.option push\n");
8515 std::string isa = riscv_current_subset_list ()->to_string (true);
8516 fprintf (stream, "\t.option arch, %s\n", isa.c_str ());
8518 struct cl_target_option *local_cl_target =
8519 TREE_TARGET_OPTION (DECL_FUNCTION_SPECIFIC_TARGET (fndecl));
8520 struct cl_target_option *global_cl_target =
8521 TREE_TARGET_OPTION (target_option_default_node);
8522 const char *local_tune_str = get_tune_str (local_cl_target);
8523 const char *global_tune_str = get_tune_str (global_cl_target);
8524 if (strcmp (local_tune_str, global_tune_str) != 0)
8525 fprintf (stream, "\t# tune = %s\n", local_tune_str);
8529 void
8530 riscv_declare_function_size (FILE *stream, const char *name, tree fndecl)
8532 if (!flag_inhibit_size_directive)
8533 ASM_OUTPUT_MEASURED_SIZE (stream, name);
8535 if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl))
8537 fprintf (stream, "\t.option pop\n");
8541 /* Implement ASM_OUTPUT_DEF_FROM_DECLS. */
8543 void
8544 riscv_asm_output_alias (FILE *stream, const tree decl, const tree target)
8546 const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
8547 const char *value = IDENTIFIER_POINTER (target);
8548 riscv_asm_output_variant_cc (stream, decl, name);
8549 ASM_OUTPUT_DEF (stream, name, value);
8552 /* Implement ASM_OUTPUT_EXTERNAL. */
8554 void
8555 riscv_asm_output_external (FILE *stream, tree decl, const char *name)
8557 default_elf_asm_output_external (stream, decl, name);
8558 riscv_asm_output_variant_cc (stream, decl, name);
8561 /* Implement TARGET_ASM_FILE_START. */
8563 static void
8564 riscv_file_start (void)
8566 default_file_start ();
8568 /* Instruct GAS to generate position-[in]dependent code. */
8569 fprintf (asm_out_file, "\t.option %spic\n", (flag_pic ? "" : "no"));
8571 /* If the user specifies "-mno-relax" on the command line then disable linker
8572 relaxation in the assembler. */
8573 if (! riscv_mrelax)
8574 fprintf (asm_out_file, "\t.option norelax\n");
8576 /* If the user specifies "-mcsr-check" on the command line then enable csr
8577 check in the assembler. */
8578 if (riscv_mcsr_check)
8579 fprintf (asm_out_file, "\t.option csr-check\n");
8581 if (riscv_emit_attribute_p)
8582 riscv_emit_attribute ();
8585 /* Implement TARGET_ASM_OUTPUT_MI_THUNK. Generate rtl rather than asm text
8586 in order to avoid duplicating too much logic from elsewhere. */
8588 static void
8589 riscv_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
8590 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
8591 tree function)
8593 const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
8594 rtx this_rtx, temp1, temp2, fnaddr;
8595 rtx_insn *insn;
8597 riscv_in_thunk_func = true;
8599 /* Pretend to be a post-reload pass while generating rtl. */
8600 reload_completed = 1;
8602 /* Mark the end of the (empty) prologue. */
8603 emit_note (NOTE_INSN_PROLOGUE_END);
8605 /* Determine if we can use a sibcall to call FUNCTION directly. */
8606 fnaddr = gen_rtx_MEM (FUNCTION_MODE, XEXP (DECL_RTL (function), 0));
8608 /* We need two temporary registers in some cases. */
8609 temp1 = gen_rtx_REG (Pmode, RISCV_PROLOGUE_TEMP_REGNUM);
8610 temp2 = gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM);
8612 /* Find out which register contains the "this" pointer. */
8613 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
8614 this_rtx = gen_rtx_REG (Pmode, GP_ARG_FIRST + 1);
8615 else
8616 this_rtx = gen_rtx_REG (Pmode, GP_ARG_FIRST);
8618 /* Add DELTA to THIS_RTX. */
8619 if (delta != 0)
8621 rtx offset = GEN_INT (delta);
8622 if (!SMALL_OPERAND (delta))
8624 riscv_emit_move (temp1, offset);
8625 offset = temp1;
8627 emit_insn (gen_add3_insn (this_rtx, this_rtx, offset));
8630 /* If needed, add *(*THIS_RTX + VCALL_OFFSET) to THIS_RTX. */
8631 if (vcall_offset != 0)
8633 rtx addr;
8635 /* Set TEMP1 to *THIS_RTX. */
8636 riscv_emit_move (temp1, gen_rtx_MEM (Pmode, this_rtx));
8638 /* Set ADDR to a legitimate address for *THIS_RTX + VCALL_OFFSET. */
8639 addr = riscv_add_offset (temp2, temp1, vcall_offset);
8641 /* Load the offset and add it to THIS_RTX. */
8642 riscv_emit_move (temp1, gen_rtx_MEM (Pmode, addr));
8643 emit_insn (gen_add3_insn (this_rtx, this_rtx, temp1));
8646 /* Jump to the target function. */
8647 rtx callee_cc = gen_int_mode (fndecl_abi (function).id (), SImode);
8648 insn = emit_call_insn (gen_sibcall (fnaddr, const0_rtx, callee_cc));
8649 SIBLING_CALL_P (insn) = 1;
8651 /* Run just enough of rest_of_compilation. This sequence was
8652 "borrowed" from alpha.cc. */
8653 insn = get_insns ();
8654 split_all_insns_noflow ();
8655 shorten_branches (insn);
8656 assemble_start_function (thunk_fndecl, fnname);
8657 final_start_function (insn, file, 1);
8658 final (insn, file, 1);
8659 final_end_function ();
8660 assemble_end_function (thunk_fndecl, fnname);
8662 /* Clean up the vars set above. Note that final_end_function resets
8663 the global pointer for us. */
8664 reload_completed = 0;
8665 riscv_in_thunk_func = false;
8668 /* Allocate a chunk of memory for per-function machine-dependent data. */
8670 static struct machine_function *
8671 riscv_init_machine_status (void)
8673 return ggc_cleared_alloc<machine_function> ();
8676 /* Return the VLEN value associated with -march.
8677 TODO: So far we only support length-agnostic value. */
8678 static poly_uint16
8679 riscv_convert_vector_bits (struct gcc_options *opts)
8681 int chunk_num;
8682 int min_vlen = TARGET_MIN_VLEN_OPTS (opts);
8683 if (min_vlen > 32)
8685 /* When targetting minimum VLEN > 32, we should use 64-bit chunk size.
8686 Otherwise we can not include SEW = 64bits.
8687 Runtime invariant: The single indeterminate represent the
8688 number of 64-bit chunks in a vector beyond minimum length of 64 bits.
8689 Thus the number of bytes in a vector is 8 + 8 * x1 which is
8690 riscv_vector_chunks * 8 = poly_int (8, 8). */
8691 riscv_bytes_per_vector_chunk = 8;
8692 /* Adjust BYTES_PER_RISCV_VECTOR according to TARGET_MIN_VLEN:
8693 - TARGET_MIN_VLEN = 64bit: [8,8]
8694 - TARGET_MIN_VLEN = 128bit: [16,16]
8695 - TARGET_MIN_VLEN = 256bit: [32,32]
8696 - TARGET_MIN_VLEN = 512bit: [64,64]
8697 - TARGET_MIN_VLEN = 1024bit: [128,128]
8698 - TARGET_MIN_VLEN = 2048bit: [256,256]
8699 - TARGET_MIN_VLEN = 4096bit: [512,512]
8700 FIXME: We currently DON'T support TARGET_MIN_VLEN > 4096bit. */
8701 chunk_num = min_vlen / 64;
8703 else
8705 /* When targetting minimum VLEN = 32, we should use 32-bit
8706 chunk size. Runtime invariant: The single indeterminate represent the
8707 number of 32-bit chunks in a vector beyond minimum length of 32 bits.
8708 Thus the number of bytes in a vector is 4 + 4 * x1 which is
8709 riscv_vector_chunks * 4 = poly_int (4, 4). */
8710 riscv_bytes_per_vector_chunk = 4;
8711 chunk_num = 1;
8714 /* Set riscv_vector_chunks as poly (1, 1) run-time constant if TARGET_VECTOR
8715 is enabled. Set riscv_vector_chunks as 1 compile-time constant if
8716 TARGET_VECTOR is disabled. riscv_vector_chunks is used in "riscv-modes.def"
8717 to set RVV mode size. The RVV machine modes size are run-time constant if
8718 TARGET_VECTOR is enabled. The RVV machine modes size remains default
8719 compile-time constant if TARGET_VECTOR is disabled. */
8720 if (TARGET_VECTOR_OPTS_P (opts))
8722 if (opts->x_riscv_autovec_preference == RVV_FIXED_VLMAX)
8723 return (int) min_vlen / (riscv_bytes_per_vector_chunk * 8);
8724 else
8725 return poly_uint16 (chunk_num, chunk_num);
8727 else
8728 return 1;
8731 /* 'Unpack' up the internal tuning structs and update the options
8732 in OPTS. The caller must have set up selected_tune and selected_arch
8733 as all the other target-specific codegen decisions are
8734 derived from them. */
8735 void
8736 riscv_override_options_internal (struct gcc_options *opts)
8738 const struct riscv_tune_info *cpu;
8740 /* The presence of the M extension implies that division instructions
8741 are present, so include them unless explicitly disabled. */
8742 if (TARGET_MUL_OPTS_P (opts) && (target_flags_explicit & MASK_DIV) == 0)
8743 opts->x_target_flags |= MASK_DIV;
8744 else if (!TARGET_MUL_OPTS_P (opts) && TARGET_DIV_OPTS_P (opts))
8745 error ("%<-mdiv%> requires %<-march%> to subsume the %<M%> extension");
8747 /* Likewise floating-point division and square root. */
8748 if ((TARGET_HARD_FLOAT_OPTS_P (opts) || TARGET_ZFINX_OPTS_P (opts))
8749 && ((target_flags_explicit & MASK_FDIV) == 0))
8750 opts->x_target_flags |= MASK_FDIV;
8752 /* Handle -mtune, use -mcpu if -mtune is not given, and use default -mtune
8753 if both -mtune and -mcpu are not given. */
8754 const char *tune_string = get_tune_str (opts);
8755 cpu = riscv_parse_tune (tune_string, false);
8756 riscv_microarchitecture = cpu->microarchitecture;
8757 tune_param = opts->x_optimize_size
8758 ? &optimize_size_tune_info
8759 : cpu->tune_param;
8761 /* Use -mtune's setting for slow_unaligned_access, even when optimizing
8762 for size. For architectures that trap and emulate unaligned accesses,
8763 the performance cost is too great, even for -Os. Similarly, if
8764 -m[no-]strict-align is left unspecified, heed -mtune's advice. */
8765 riscv_slow_unaligned_access_p = (cpu->tune_param->slow_unaligned_access
8766 || TARGET_STRICT_ALIGN);
8768 /* Make a note if user explicity passed -mstrict-align for later
8769 builtin macro generation. Can't use target_flags_explicitly since
8770 it is set even for -mno-strict-align. */
8771 riscv_user_wants_strict_align = TARGET_STRICT_ALIGN_OPTS_P (opts);
8773 if ((target_flags_explicit & MASK_STRICT_ALIGN) == 0
8774 && cpu->tune_param->slow_unaligned_access)
8775 opts->x_target_flags |= MASK_STRICT_ALIGN;
8777 /* If the user hasn't specified a branch cost, use the processor's
8778 default. */
8779 if (opts->x_riscv_branch_cost == 0)
8780 opts->x_riscv_branch_cost = tune_param->branch_cost;
8782 /* FIXME: We don't allow TARGET_MIN_VLEN > 4096 since the datatypes of
8783 both GET_MODE_SIZE and GET_MODE_BITSIZE are poly_uint16.
8785 We can only allow TARGET_MIN_VLEN * 8 (LMUL) < 65535. */
8786 if (TARGET_MIN_VLEN_OPTS (opts) > 4096)
8787 sorry ("Current RISC-V GCC cannot support VLEN greater than 4096bit for "
8788 "'V' Extension");
8790 /* FIXME: We don't support RVV in big-endian for now, we may enable RVV with
8791 big-endian after finishing full coverage testing. */
8792 if (TARGET_VECTOR && TARGET_BIG_ENDIAN)
8793 sorry ("Current RISC-V GCC cannot support RVV in big-endian mode");
8795 /* Convert -march to a chunks count. */
8796 riscv_vector_chunks = riscv_convert_vector_bits (opts);
8799 /* Implement TARGET_OPTION_OVERRIDE. */
8801 static void
8802 riscv_option_override (void)
8804 #ifdef SUBTARGET_OVERRIDE_OPTIONS
8805 SUBTARGET_OVERRIDE_OPTIONS;
8806 #endif
8808 flag_pcc_struct_return = 0;
8810 if (flag_pic)
8811 g_switch_value = 0;
8813 /* Always prefer medlow than medany for RV32 since medlow can access
8814 full address space. */
8815 if (riscv_cmodel == CM_LARGE && !TARGET_64BIT)
8816 riscv_cmodel = CM_MEDLOW;
8818 if (riscv_cmodel == CM_LARGE && TARGET_EXPLICIT_RELOCS)
8819 sorry ("code model %qs with %qs", "large", "-mexplicit-relocs");
8821 if (riscv_cmodel == CM_LARGE && flag_pic)
8822 sorry ("code model %qs with %qs", "large",
8823 global_options.x_flag_pic > 1 ? "-fPIC" : "-fpic");
8825 if (flag_pic)
8826 riscv_cmodel = CM_PIC;
8828 /* We need to save the fp with ra for non-leaf functions with no fp and ra
8829 for leaf functions while no-omit-frame-pointer with
8830 omit-leaf-frame-pointer. The x_flag_omit_frame_pointer has the first
8831 priority to determine whether the frame pointer is needed. If we do not
8832 override it, the fp and ra will be stored for leaf functions, which is not
8833 our wanted. */
8834 riscv_save_frame_pointer = false;
8835 if (TARGET_OMIT_LEAF_FRAME_POINTER_P (global_options.x_target_flags))
8837 if (!global_options.x_flag_omit_frame_pointer)
8838 riscv_save_frame_pointer = true;
8840 global_options.x_flag_omit_frame_pointer = 1;
8843 /* We get better code with explicit relocs for CM_MEDLOW, but
8844 worse code for the others (for now). Pick the best default. */
8845 if ((target_flags_explicit & MASK_EXPLICIT_RELOCS) == 0)
8846 if (riscv_cmodel == CM_MEDLOW)
8847 target_flags |= MASK_EXPLICIT_RELOCS;
8849 /* Require that the ISA supports the requested floating-point ABI. */
8850 if (UNITS_PER_FP_ARG > (TARGET_HARD_FLOAT ? UNITS_PER_FP_REG : 0))
8851 error ("requested ABI requires %<-march%> to subsume the %qc extension",
8852 UNITS_PER_FP_ARG > 8 ? 'Q' : (UNITS_PER_FP_ARG > 4 ? 'D' : 'F'));
8854 /* RVE requires specific ABI. */
8855 if (TARGET_RVE)
8857 if (!TARGET_64BIT && riscv_abi != ABI_ILP32E)
8858 error ("rv32e requires ilp32e ABI");
8859 else if (TARGET_64BIT && riscv_abi != ABI_LP64E)
8860 error ("rv64e requires lp64e ABI");
8863 /* Zfinx require abi ilp32, ilp32e, lp64 or lp64e. */
8864 if (TARGET_ZFINX
8865 && riscv_abi != ABI_ILP32 && riscv_abi != ABI_LP64
8866 && riscv_abi != ABI_ILP32E && riscv_abi != ABI_LP64E)
8867 error ("z*inx requires ABI ilp32, ilp32e, lp64 or lp64e");
8869 /* We do not yet support ILP32 on RV64. */
8870 if (BITS_PER_WORD != POINTER_SIZE)
8871 error ("ABI requires %<-march=rv%d%>", POINTER_SIZE);
8873 /* Validate -mpreferred-stack-boundary= value. */
8874 riscv_stack_boundary = ABI_STACK_BOUNDARY;
8875 if (riscv_preferred_stack_boundary_arg)
8877 int min = ctz_hwi (STACK_BOUNDARY / 8);
8878 int max = 8;
8880 if (!IN_RANGE (riscv_preferred_stack_boundary_arg, min, max))
8881 error ("%<-mpreferred-stack-boundary=%d%> must be between %d and %d",
8882 riscv_preferred_stack_boundary_arg, min, max);
8884 riscv_stack_boundary = 8 << riscv_preferred_stack_boundary_arg;
8887 if (riscv_emit_attribute_p < 0)
8888 #ifdef HAVE_AS_RISCV_ATTRIBUTE
8889 riscv_emit_attribute_p = TARGET_RISCV_ATTRIBUTE;
8890 #else
8891 riscv_emit_attribute_p = 0;
8893 if (riscv_emit_attribute_p)
8894 error ("%<-mriscv-attribute%> RISC-V ELF attribute requires GNU as 2.32"
8895 " [%<-mriscv-attribute%>]");
8896 #endif
8898 if (riscv_stack_protector_guard == SSP_GLOBAL
8899 && OPTION_SET_P (riscv_stack_protector_guard_offset_str))
8901 error ("incompatible options %<-mstack-protector-guard=global%> and "
8902 "%<-mstack-protector-guard-offset=%s%>",
8903 riscv_stack_protector_guard_offset_str);
8906 if (riscv_stack_protector_guard == SSP_TLS
8907 && !(OPTION_SET_P (riscv_stack_protector_guard_offset_str)
8908 && OPTION_SET_P (riscv_stack_protector_guard_reg_str)))
8910 error ("both %<-mstack-protector-guard-offset%> and "
8911 "%<-mstack-protector-guard-reg%> must be used "
8912 "with %<-mstack-protector-guard=sysreg%>");
8915 if (OPTION_SET_P (riscv_stack_protector_guard_reg_str))
8917 const char *str = riscv_stack_protector_guard_reg_str;
8918 int reg = decode_reg_name (str);
8920 if (!IN_RANGE (reg, GP_REG_FIRST + 1, GP_REG_LAST))
8921 error ("%qs is not a valid base register in %qs", str,
8922 "-mstack-protector-guard-reg=");
8924 riscv_stack_protector_guard_reg = reg;
8927 if (OPTION_SET_P (riscv_stack_protector_guard_offset_str))
8929 char *end;
8930 const char *str = riscv_stack_protector_guard_offset_str;
8931 errno = 0;
8932 long offs = strtol (riscv_stack_protector_guard_offset_str, &end, 0);
8934 if (!*str || *end || errno)
8935 error ("%qs is not a valid number in %qs", str,
8936 "-mstack-protector-guard-offset=");
8938 if (!SMALL_OPERAND (offs))
8939 error ("%qs is not a valid offset in %qs", str,
8940 "-mstack-protector-guard-offset=");
8942 riscv_stack_protector_guard_offset = offs;
8945 SET_OPTION_IF_UNSET (&global_options, &global_options_set,
8946 param_sched_pressure_algorithm,
8947 SCHED_PRESSURE_MODEL);
8949 /* Function to allocate machine-dependent function status. */
8950 init_machine_status = &riscv_init_machine_status;
8952 riscv_override_options_internal (&global_options);
8954 /* Save these options as the default ones in case we push and pop them later
8955 while processing functions with potential target attributes. */
8956 target_option_default_node = target_option_current_node
8957 = build_target_option_node (&global_options, &global_options_set);
8960 /* Restore or save the TREE_TARGET_GLOBALS from or to NEW_TREE.
8961 Used by riscv_set_current_function to
8962 make sure optab availability predicates are recomputed when necessary. */
8964 void
8965 riscv_save_restore_target_globals (tree new_tree)
8967 if (TREE_TARGET_GLOBALS (new_tree))
8968 restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
8969 else if (new_tree == target_option_default_node)
8970 restore_target_globals (&default_target_globals);
8971 else
8972 TREE_TARGET_GLOBALS (new_tree) = save_target_globals_default_opts ();
8975 /* Implements TARGET_OPTION_RESTORE. Restore the backend codegen decisions
8976 using the information saved in PTR. */
8978 static void
8979 riscv_option_restore (struct gcc_options *opts,
8980 struct gcc_options * /* opts_set */,
8981 struct cl_target_option * /* ptr */)
8983 riscv_override_options_internal (opts);
8986 static GTY (()) tree riscv_previous_fndecl;
8988 /* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */
8990 static void
8991 riscv_conditional_register_usage (void)
8993 /* We have only x0~x15 on RV32E/RV64E. */
8994 if (TARGET_RVE)
8996 for (int r = 16; r <= 31; r++)
8997 fixed_regs[r] = 1;
9000 if (riscv_abi == ABI_ILP32E)
9002 for (int r = 16; r <= 31; r++)
9003 call_used_regs[r] = 1;
9006 if (!TARGET_HARD_FLOAT)
9008 for (int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
9009 fixed_regs[regno] = call_used_regs[regno] = 1;
9012 /* In the soft-float ABI, there are no callee-saved FP registers. */
9013 if (UNITS_PER_FP_ARG == 0)
9015 for (int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
9016 call_used_regs[regno] = 1;
9019 if (!TARGET_VECTOR)
9021 for (int regno = V_REG_FIRST; regno <= V_REG_LAST; regno++)
9022 fixed_regs[regno] = call_used_regs[regno] = 1;
9024 fixed_regs[VTYPE_REGNUM] = call_used_regs[VTYPE_REGNUM] = 1;
9025 fixed_regs[VL_REGNUM] = call_used_regs[VL_REGNUM] = 1;
9026 fixed_regs[VXRM_REGNUM] = call_used_regs[VXRM_REGNUM] = 1;
9027 fixed_regs[FRM_REGNUM] = call_used_regs[FRM_REGNUM] = 1;
9031 /* Return a register priority for hard reg REGNO. */
9033 static int
9034 riscv_register_priority (int regno)
9036 /* Favor compressed registers to improve the odds of RVC instruction
9037 selection. */
9038 if (riscv_compressed_reg_p (regno))
9039 return 1;
9041 return 0;
9044 /* Implement TARGET_TRAMPOLINE_INIT. */
9046 static void
9047 riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
9049 rtx addr, end_addr, mem;
9050 uint32_t trampoline[4];
9051 unsigned int i;
9052 HOST_WIDE_INT static_chain_offset, target_function_offset;
9054 /* Work out the offsets of the pointers from the start of the
9055 trampoline code. */
9056 gcc_assert (ARRAY_SIZE (trampoline) * 4 == TRAMPOLINE_CODE_SIZE);
9058 /* Get pointers to the beginning and end of the code block. */
9059 addr = force_reg (Pmode, XEXP (m_tramp, 0));
9060 end_addr = riscv_force_binary (Pmode, PLUS, addr,
9061 GEN_INT (TRAMPOLINE_CODE_SIZE));
9064 if (Pmode == SImode)
9066 chain_value = force_reg (Pmode, chain_value);
9068 rtx target_function = force_reg (Pmode, XEXP (DECL_RTL (fndecl), 0));
9069 /* lui t2, hi(chain)
9070 lui t0, hi(func)
9071 addi t2, t2, lo(chain)
9072 jr t0, lo(func)
9074 unsigned HOST_WIDE_INT lui_hi_chain_code, lui_hi_func_code;
9075 unsigned HOST_WIDE_INT lo_chain_code, lo_func_code;
9077 rtx uimm_mask = force_reg (SImode, gen_int_mode (-IMM_REACH, SImode));
9079 /* 0xfff. */
9080 rtx imm12_mask = gen_reg_rtx (SImode);
9081 emit_insn (gen_one_cmplsi2 (imm12_mask, uimm_mask));
9083 rtx fixup_value = force_reg (SImode, gen_int_mode (IMM_REACH/2, SImode));
9085 /* Gen lui t2, hi(chain). */
9086 rtx hi_chain = riscv_force_binary (SImode, PLUS, chain_value,
9087 fixup_value);
9088 hi_chain = riscv_force_binary (SImode, AND, hi_chain,
9089 uimm_mask);
9090 lui_hi_chain_code = OPCODE_LUI | (STATIC_CHAIN_REGNUM << SHIFT_RD);
9091 rtx lui_hi_chain = riscv_force_binary (SImode, IOR, hi_chain,
9092 gen_int_mode (lui_hi_chain_code, SImode));
9094 mem = adjust_address (m_tramp, SImode, 0);
9095 riscv_emit_move (mem, riscv_swap_instruction (lui_hi_chain));
9097 /* Gen lui t0, hi(func). */
9098 rtx hi_func = riscv_force_binary (SImode, PLUS, target_function,
9099 fixup_value);
9100 hi_func = riscv_force_binary (SImode, AND, hi_func,
9101 uimm_mask);
9102 lui_hi_func_code = OPCODE_LUI | (RISCV_PROLOGUE_TEMP_REGNUM << SHIFT_RD);
9103 rtx lui_hi_func = riscv_force_binary (SImode, IOR, hi_func,
9104 gen_int_mode (lui_hi_func_code, SImode));
9106 mem = adjust_address (m_tramp, SImode, 1 * GET_MODE_SIZE (SImode));
9107 riscv_emit_move (mem, riscv_swap_instruction (lui_hi_func));
9109 /* Gen addi t2, t2, lo(chain). */
9110 rtx lo_chain = riscv_force_binary (SImode, AND, chain_value,
9111 imm12_mask);
9112 lo_chain = riscv_force_binary (SImode, ASHIFT, lo_chain, GEN_INT (20));
9114 lo_chain_code = OPCODE_ADDI
9115 | (STATIC_CHAIN_REGNUM << SHIFT_RD)
9116 | (STATIC_CHAIN_REGNUM << SHIFT_RS1);
9118 rtx addi_lo_chain = riscv_force_binary (SImode, IOR, lo_chain,
9119 force_reg (SImode, GEN_INT (lo_chain_code)));
9121 mem = adjust_address (m_tramp, SImode, 2 * GET_MODE_SIZE (SImode));
9122 riscv_emit_move (mem, riscv_swap_instruction (addi_lo_chain));
9124 /* Gen jr t0, lo(func). */
9125 rtx lo_func = riscv_force_binary (SImode, AND, target_function,
9126 imm12_mask);
9127 lo_func = riscv_force_binary (SImode, ASHIFT, lo_func, GEN_INT (20));
9129 lo_func_code = OPCODE_JALR | (RISCV_PROLOGUE_TEMP_REGNUM << SHIFT_RS1);
9131 rtx jr_lo_func = riscv_force_binary (SImode, IOR, lo_func,
9132 force_reg (SImode, GEN_INT (lo_func_code)));
9134 mem = adjust_address (m_tramp, SImode, 3 * GET_MODE_SIZE (SImode));
9135 riscv_emit_move (mem, riscv_swap_instruction (jr_lo_func));
9137 else
9139 static_chain_offset = TRAMPOLINE_CODE_SIZE;
9140 target_function_offset = static_chain_offset + GET_MODE_SIZE (ptr_mode);
9142 /* auipc t2, 0
9143 l[wd] t0, target_function_offset(t2)
9144 l[wd] t2, static_chain_offset(t2)
9145 jr t0
9147 trampoline[0] = OPCODE_AUIPC | (STATIC_CHAIN_REGNUM << SHIFT_RD);
9148 trampoline[1] = (Pmode == DImode ? OPCODE_LD : OPCODE_LW)
9149 | (RISCV_PROLOGUE_TEMP_REGNUM << SHIFT_RD)
9150 | (STATIC_CHAIN_REGNUM << SHIFT_RS1)
9151 | (target_function_offset << SHIFT_IMM);
9152 trampoline[2] = (Pmode == DImode ? OPCODE_LD : OPCODE_LW)
9153 | (STATIC_CHAIN_REGNUM << SHIFT_RD)
9154 | (STATIC_CHAIN_REGNUM << SHIFT_RS1)
9155 | (static_chain_offset << SHIFT_IMM);
9156 trampoline[3] = OPCODE_JALR | (RISCV_PROLOGUE_TEMP_REGNUM << SHIFT_RS1);
9158 /* Copy the trampoline code. */
9159 for (i = 0; i < ARRAY_SIZE (trampoline); i++)
9161 if (BYTES_BIG_ENDIAN)
9162 trampoline[i] = __builtin_bswap32(trampoline[i]);
9163 mem = adjust_address (m_tramp, SImode, i * GET_MODE_SIZE (SImode));
9164 riscv_emit_move (mem, gen_int_mode (trampoline[i], SImode));
9167 /* Set up the static chain pointer field. */
9168 mem = adjust_address (m_tramp, ptr_mode, static_chain_offset);
9169 riscv_emit_move (mem, chain_value);
9171 /* Set up the target function field. */
9172 mem = adjust_address (m_tramp, ptr_mode, target_function_offset);
9173 riscv_emit_move (mem, XEXP (DECL_RTL (fndecl), 0));
9176 /* Flush the code part of the trampoline. */
9177 emit_insn (gen_add3_insn (end_addr, addr, GEN_INT (TRAMPOLINE_SIZE)));
9178 emit_insn (gen_clear_cache (addr, end_addr));
9181 /* Implement TARGET_FUNCTION_OK_FOR_SIBCALL. */
9183 static bool
9184 riscv_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
9185 tree exp ATTRIBUTE_UNUSED)
9187 /* Don't use sibcalls when use save-restore routine. */
9188 if (TARGET_SAVE_RESTORE)
9189 return false;
9191 /* Don't use sibcall for naked functions. */
9192 if (cfun->machine->naked_p)
9193 return false;
9195 /* Don't use sibcall for interrupt functions. */
9196 if (cfun->machine->interrupt_handler_p)
9197 return false;
9199 /* Don't use sibcalls in the large model, because a sibcall instruction
9200 expanding and a epilogue expanding both use RISCV_PROLOGUE_TEMP
9201 register. */
9202 if (riscv_cmodel == CM_LARGE)
9203 return false;
9205 return true;
9208 /* Get the interrupt type, return UNKNOWN_MODE if it's not
9209 interrupt function. */
9210 static enum riscv_privilege_levels
9211 riscv_get_interrupt_type (tree decl)
9213 gcc_assert (decl != NULL_TREE);
9215 if ((TREE_CODE(decl) != FUNCTION_DECL)
9216 || (!riscv_interrupt_type_p (TREE_TYPE (decl))))
9217 return UNKNOWN_MODE;
9219 tree attr_args
9220 = TREE_VALUE (lookup_attribute ("interrupt",
9221 TYPE_ATTRIBUTES (TREE_TYPE (decl))));
9223 if (attr_args && TREE_CODE (TREE_VALUE (attr_args)) != VOID_TYPE)
9225 const char *string = TREE_STRING_POINTER (TREE_VALUE (attr_args));
9227 if (!strcmp (string, "user"))
9228 return USER_MODE;
9229 else if (!strcmp (string, "supervisor"))
9230 return SUPERVISOR_MODE;
9231 else /* Must be "machine". */
9232 return MACHINE_MODE;
9234 else
9235 /* Interrupt attributes are machine mode by default. */
9236 return MACHINE_MODE;
9239 /* Implement `TARGET_SET_CURRENT_FUNCTION'. Unpack the codegen decisions
9240 like tuning and ISA features from the DECL_FUNCTION_SPECIFIC_TARGET
9241 of the function, if such exists. This function may be called multiple
9242 times on a single function so use aarch64_previous_fndecl to avoid
9243 setting up identical state. */
9245 /* Sanity cheching for above function attributes. */
9246 static void
9247 riscv_set_current_function (tree decl)
9249 if (decl == NULL_TREE
9250 || current_function_decl == NULL_TREE
9251 || current_function_decl == error_mark_node
9252 || ! cfun->machine)
9253 return;
9255 if (!cfun->machine->attributes_checked_p)
9257 cfun->machine->naked_p = riscv_naked_function_p (decl);
9258 cfun->machine->interrupt_handler_p
9259 = riscv_interrupt_type_p (TREE_TYPE (decl));
9261 if (cfun->machine->naked_p && cfun->machine->interrupt_handler_p)
9262 error ("function attributes %qs and %qs are mutually exclusive",
9263 "interrupt", "naked");
9265 if (cfun->machine->interrupt_handler_p)
9267 tree ret = TREE_TYPE (TREE_TYPE (decl));
9268 tree args = TYPE_ARG_TYPES (TREE_TYPE (decl));
9270 if (TREE_CODE (ret) != VOID_TYPE)
9271 error ("%qs function cannot return a value", "interrupt");
9273 if (args && TREE_CODE (TREE_VALUE (args)) != VOID_TYPE)
9274 error ("%qs function cannot have arguments", "interrupt");
9276 cfun->machine->interrupt_mode = riscv_get_interrupt_type (decl);
9278 gcc_assert (cfun->machine->interrupt_mode != UNKNOWN_MODE);
9281 /* Don't print the above diagnostics more than once. */
9282 cfun->machine->attributes_checked_p = 1;
9285 if (!decl || decl == riscv_previous_fndecl)
9286 return;
9288 tree old_tree = (riscv_previous_fndecl
9289 ? DECL_FUNCTION_SPECIFIC_TARGET (riscv_previous_fndecl)
9290 : NULL_TREE);
9292 tree new_tree = DECL_FUNCTION_SPECIFIC_TARGET (decl);
9294 /* If current function has no attributes but the previous one did,
9295 use the default node. */
9296 if (!new_tree && old_tree)
9297 new_tree = target_option_default_node;
9299 /* If nothing to do, return. #pragma GCC reset or #pragma GCC pop to
9300 the default have been handled by aarch64_save_restore_target_globals from
9301 aarch64_pragma_target_parse. */
9302 if (old_tree == new_tree)
9303 return;
9305 riscv_previous_fndecl = decl;
9307 /* First set the target options. */
9308 cl_target_option_restore (&global_options, &global_options_set,
9309 TREE_TARGET_OPTION (new_tree));
9311 riscv_save_restore_target_globals (new_tree);
9314 /* Implement TARGET_MERGE_DECL_ATTRIBUTES. */
9315 static tree
9316 riscv_merge_decl_attributes (tree olddecl, tree newdecl)
9318 tree combined_attrs;
9320 enum riscv_privilege_levels old_interrupt_type
9321 = riscv_get_interrupt_type (olddecl);
9322 enum riscv_privilege_levels new_interrupt_type
9323 = riscv_get_interrupt_type (newdecl);
9325 /* Check old and new has same interrupt type. */
9326 if ((old_interrupt_type != UNKNOWN_MODE)
9327 && (new_interrupt_type != UNKNOWN_MODE)
9328 && (old_interrupt_type != new_interrupt_type))
9329 error ("%qs function cannot have different interrupt type", "interrupt");
9331 /* Create combined attributes. */
9332 combined_attrs = merge_attributes (DECL_ATTRIBUTES (olddecl),
9333 DECL_ATTRIBUTES (newdecl));
9335 return combined_attrs;
9338 /* Implement TARGET_CANNOT_COPY_INSN_P. */
9340 static bool
9341 riscv_cannot_copy_insn_p (rtx_insn *insn)
9343 return recog_memoized (insn) >= 0 && get_attr_cannot_copy (insn);
9346 /* Implement TARGET_SLOW_UNALIGNED_ACCESS. */
9348 static bool
9349 riscv_slow_unaligned_access (machine_mode, unsigned int)
9351 return riscv_slow_unaligned_access_p;
9354 /* Implement TARGET_CAN_CHANGE_MODE_CLASS. */
9356 static bool
9357 riscv_can_change_mode_class (machine_mode from, machine_mode to,
9358 reg_class_t rclass)
9360 /* We have RVV VLS modes and VLA modes sharing same REG_CLASS.
9361 In 'cprop_hardreg' stage, we will try to do hard reg copy propagation
9362 between wider mode (FROM) and narrow mode (TO).
9364 E.g. We should not allow copy propagation
9365 - RVVMF8BI (precision = [16, 16]) -> V32BI (precision = [32, 0])
9366 since we can't order their size which will cause ICE in regcprop.
9368 TODO: Even though they are have different size, they always change
9369 the whole register. We may enhance such case in regcprop to optimize
9370 it in the future. */
9371 if (reg_classes_intersect_p (V_REGS, rclass)
9372 && !ordered_p (GET_MODE_PRECISION (from), GET_MODE_PRECISION (to)))
9373 return false;
9374 return !reg_classes_intersect_p (FP_REGS, rclass);
9377 /* Implement TARGET_CONSTANT_ALIGNMENT. */
9379 static HOST_WIDE_INT
9380 riscv_constant_alignment (const_tree exp, HOST_WIDE_INT align)
9382 if ((TREE_CODE (exp) == STRING_CST || TREE_CODE (exp) == CONSTRUCTOR)
9383 && (riscv_align_data_type == riscv_align_data_type_xlen))
9384 return MAX (align, BITS_PER_WORD);
9385 return align;
9388 /* Implement TARGET_PROMOTE_FUNCTION_MODE. */
9390 /* This function is equivalent to default_promote_function_mode_always_promote
9391 except that it returns a promoted mode even if type is NULL_TREE. This is
9392 needed by libcalls which have no type (only a mode) such as fixed conversion
9393 routines that take a signed or unsigned char/short/int argument and convert
9394 it to a fixed type. */
9396 static machine_mode
9397 riscv_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
9398 machine_mode mode,
9399 int *punsignedp ATTRIBUTE_UNUSED,
9400 const_tree fntype ATTRIBUTE_UNUSED,
9401 int for_return ATTRIBUTE_UNUSED)
9403 int unsignedp;
9405 if (type != NULL_TREE)
9406 return promote_mode (type, mode, punsignedp);
9408 unsignedp = *punsignedp;
9409 scalar_mode smode = as_a <scalar_mode> (mode);
9410 PROMOTE_MODE (smode, unsignedp, type);
9411 *punsignedp = unsignedp;
9412 return smode;
9415 /* Implement TARGET_MACHINE_DEPENDENT_REORG. */
9417 static void
9418 riscv_reorg (void)
9420 /* Do nothing unless we have -msave-restore */
9421 if (TARGET_SAVE_RESTORE)
9422 riscv_remove_unneeded_save_restore_calls ();
9425 /* Return nonzero if register FROM_REGNO can be renamed to register
9426 TO_REGNO. */
9428 bool
9429 riscv_hard_regno_rename_ok (unsigned from_regno ATTRIBUTE_UNUSED,
9430 unsigned to_regno)
9432 /* Interrupt functions can only use registers that have already been
9433 saved by the prologue, even if they would normally be
9434 call-clobbered. */
9435 return !cfun->machine->interrupt_handler_p || df_regs_ever_live_p (to_regno);
9438 /* Implement TARGET_NEW_ADDRESS_PROFITABLE_P. */
9440 bool
9441 riscv_new_address_profitable_p (rtx memref, rtx_insn *insn, rtx new_addr)
9443 /* Prefer old address if it is less expensive. */
9444 addr_space_t as = MEM_ADDR_SPACE (memref);
9445 bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
9446 int old_cost = address_cost (XEXP (memref, 0), GET_MODE (memref), as, speed);
9447 int new_cost = address_cost (new_addr, GET_MODE (memref), as, speed);
9448 return new_cost <= old_cost;
9451 /* Helper function for generating gpr_save pattern. */
9454 riscv_gen_gpr_save_insn (struct riscv_frame_info *frame)
9456 unsigned count = riscv_save_libcall_count (frame->mask);
9457 /* 1 for unspec 2 for clobber t0/t1 and 1 for ra. */
9458 unsigned veclen = 1 + 2 + 1 + count;
9459 rtvec vec = rtvec_alloc (veclen);
9461 gcc_assert (veclen <= ARRAY_SIZE (gpr_save_reg_order));
9463 RTVEC_ELT (vec, 0) =
9464 gen_rtx_UNSPEC_VOLATILE (VOIDmode,
9465 gen_rtvec (1, GEN_INT (count)), UNSPECV_GPR_SAVE);
9467 for (unsigned i = 1; i < veclen; ++i)
9469 unsigned regno = gpr_save_reg_order[i];
9470 rtx reg = gen_rtx_REG (Pmode, regno);
9471 rtx elt;
9473 /* t0 and t1 are CLOBBERs, others are USEs. */
9474 if (i < 3)
9475 elt = gen_rtx_CLOBBER (Pmode, reg);
9476 else
9477 elt = gen_rtx_USE (Pmode, reg);
9479 RTVEC_ELT (vec, i) = elt;
9482 /* Largest number of caller-save register must set in mask if we are
9483 not using __riscv_save_0. */
9484 gcc_assert ((count == 0) ||
9485 BITSET_P (frame->mask, gpr_save_reg_order[veclen - 1]));
9487 return gen_rtx_PARALLEL (VOIDmode, vec);
9490 static HOST_WIDE_INT
9491 zcmp_base_adj (int regs_num)
9493 return riscv_16bytes_align ((regs_num) *GET_MODE_SIZE (word_mode));
9496 static HOST_WIDE_INT
9497 zcmp_additional_adj (HOST_WIDE_INT total, int regs_num)
9499 return total - zcmp_base_adj (regs_num);
9502 bool
9503 riscv_zcmp_valid_stack_adj_bytes_p (HOST_WIDE_INT total, int regs_num)
9505 HOST_WIDE_INT additioanl_bytes = zcmp_additional_adj (total, regs_num);
9506 return additioanl_bytes == 0 || additioanl_bytes == 1 * ZCMP_SP_INC_STEP
9507 || additioanl_bytes == 2 * ZCMP_SP_INC_STEP
9508 || additioanl_bytes == ZCMP_MAX_SPIMM * ZCMP_SP_INC_STEP;
9511 /* Return true if it's valid gpr_save pattern. */
9513 bool
9514 riscv_gpr_save_operation_p (rtx op)
9516 unsigned len = XVECLEN (op, 0);
9518 if (len > ARRAY_SIZE (gpr_save_reg_order))
9519 return false;
9521 for (unsigned i = 0; i < len; i++)
9523 rtx elt = XVECEXP (op, 0, i);
9524 if (i == 0)
9526 /* First element in parallel is unspec. */
9527 if (GET_CODE (elt) != UNSPEC_VOLATILE
9528 || GET_CODE (XVECEXP (elt, 0, 0)) != CONST_INT
9529 || XINT (elt, 1) != UNSPECV_GPR_SAVE)
9530 return false;
9532 else
9534 /* Two CLOBBER and USEs, must check the order. */
9535 unsigned expect_code = i < 3 ? CLOBBER : USE;
9536 if (GET_CODE (elt) != expect_code
9537 || !REG_P (XEXP (elt, 1))
9538 || (REGNO (XEXP (elt, 1)) != gpr_save_reg_order[i]))
9539 return false;
9541 break;
9543 return true;
9546 /* Implement TARGET_ASAN_SHADOW_OFFSET. */
9548 static unsigned HOST_WIDE_INT
9549 riscv_asan_shadow_offset (void)
9551 /* We only have libsanitizer support for RV64 at present.
9553 This number must match ASAN_SHADOW_OFFSET_CONST in the file
9554 libsanitizer/asan/asan_mapping.h. */
9555 return TARGET_64BIT ? HOST_WIDE_INT_UC (0xd55550000) : 0;
9558 /* Implement TARGET_MANGLE_TYPE. */
9560 static const char *
9561 riscv_mangle_type (const_tree type)
9563 /* Half-precision float, _Float16 is "DF16_". */
9564 if (SCALAR_FLOAT_TYPE_P (type) && TYPE_PRECISION (type) == 16)
9565 return "DF16_";
9567 /* Mangle all vector type for vector extension. */
9568 /* The mangle name follows the rule of RVV LLVM
9569 that is "u" + length of (abi_name) + abi_name. */
9570 if (TYPE_NAME (type) != NULL)
9572 const char *res = riscv_vector::mangle_builtin_type (type);
9573 if (res)
9574 return res;
9577 /* Use the default mangling. */
9578 return NULL;
9581 /* Implement TARGET_SCALAR_MODE_SUPPORTED_P. */
9583 static bool
9584 riscv_scalar_mode_supported_p (scalar_mode mode)
9586 if (mode == HFmode)
9587 return true;
9588 else
9589 return default_scalar_mode_supported_p (mode);
9592 /* Implement TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P - return TRUE
9593 if MODE is HFmode, and punt to the generic implementation otherwise. */
9595 static bool
9596 riscv_libgcc_floating_mode_supported_p (scalar_float_mode mode)
9598 if (mode == HFmode)
9599 return true;
9600 else
9601 return default_libgcc_floating_mode_supported_p (mode);
9604 /* Set the value of FLT_EVAL_METHOD.
9605 ISO/IEC TS 18661-3 defines two values that we'd like to make use of:
9607 0: evaluate all operations and constants, whose semantic type has at
9608 most the range and precision of type float, to the range and
9609 precision of float; evaluate all other operations and constants to
9610 the range and precision of the semantic type;
9612 N, where _FloatN is a supported interchange floating type
9613 evaluate all operations and constants, whose semantic type has at
9614 most the range and precision of _FloatN type, to the range and
9615 precision of the _FloatN type; evaluate all other operations and
9616 constants to the range and precision of the semantic type;
9618 If we have the zfh/zhinx/zvfh extensions then we support _Float16
9619 in native precision, so we should set this to 16. */
9620 static enum flt_eval_method
9621 riscv_excess_precision (enum excess_precision_type type)
9623 switch (type)
9625 case EXCESS_PRECISION_TYPE_FAST:
9626 case EXCESS_PRECISION_TYPE_STANDARD:
9627 return ((TARGET_ZFH || TARGET_ZHINX || TARGET_ZVFH)
9628 ? FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16
9629 : FLT_EVAL_METHOD_PROMOTE_TO_FLOAT);
9630 case EXCESS_PRECISION_TYPE_IMPLICIT:
9631 case EXCESS_PRECISION_TYPE_FLOAT16:
9632 return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16;
9633 default:
9634 gcc_unreachable ();
9636 return FLT_EVAL_METHOD_UNPREDICTABLE;
9639 /* Implement TARGET_FLOATN_MODE. */
9640 static opt_scalar_float_mode
9641 riscv_floatn_mode (int n, bool extended)
9643 if (!extended && n == 16)
9644 return HFmode;
9646 return default_floatn_mode (n, extended);
9649 static void
9650 riscv_init_libfuncs (void)
9652 /* Half-precision float operations. The compiler handles all operations
9653 with NULL libfuncs by converting to SFmode. */
9655 /* Arithmetic. */
9656 set_optab_libfunc (add_optab, HFmode, NULL);
9657 set_optab_libfunc (sdiv_optab, HFmode, NULL);
9658 set_optab_libfunc (smul_optab, HFmode, NULL);
9659 set_optab_libfunc (neg_optab, HFmode, NULL);
9660 set_optab_libfunc (sub_optab, HFmode, NULL);
9662 /* Comparisons. */
9663 set_optab_libfunc (eq_optab, HFmode, NULL);
9664 set_optab_libfunc (ne_optab, HFmode, NULL);
9665 set_optab_libfunc (lt_optab, HFmode, NULL);
9666 set_optab_libfunc (le_optab, HFmode, NULL);
9667 set_optab_libfunc (ge_optab, HFmode, NULL);
9668 set_optab_libfunc (gt_optab, HFmode, NULL);
9669 set_optab_libfunc (unord_optab, HFmode, NULL);
9672 #if CHECKING_P
9673 void
9674 riscv_reinit (void)
9676 riscv_option_override ();
9677 init_adjust_machine_modes ();
9678 init_derived_machine_modes ();
9679 reinit_regs ();
9680 init_optabs ();
9682 #endif
9684 #if CHECKING_P
9685 #undef TARGET_RUN_TARGET_SELFTESTS
9686 #define TARGET_RUN_TARGET_SELFTESTS selftest::riscv_run_selftests
9687 #endif /* #if CHECKING_P */
9689 /* Implement TARGET_VECTOR_MODE_SUPPORTED_P. */
9691 static bool
9692 riscv_vector_mode_supported_p (machine_mode mode)
9694 if (TARGET_VECTOR)
9695 return riscv_v_ext_mode_p (mode);
9697 return false;
9700 /* Implement TARGET_VERIFY_TYPE_CONTEXT. */
9702 static bool
9703 riscv_verify_type_context (location_t loc, type_context_kind context,
9704 const_tree type, bool silent_p)
9706 return riscv_vector::verify_type_context (loc, context, type, silent_p);
9709 /* Implement TARGET_VECTOR_ALIGNMENT. */
9711 static HOST_WIDE_INT
9712 riscv_vector_alignment (const_tree type)
9714 /* ??? Checking the mode isn't ideal, but VECTOR_BOOLEAN_TYPE_P can
9715 be set for non-predicate vectors of booleans. Modes are the most
9716 direct way we have of identifying real RVV predicate types. */
9717 /* FIXME: RVV didn't mention the alignment of bool, we uses
9718 one byte align. */
9719 if (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_VECTOR_BOOL)
9720 return 8;
9722 widest_int min_size
9723 = constant_lower_bound (wi::to_poly_widest (TYPE_SIZE (type)));
9724 return wi::umin (min_size, 128).to_uhwi ();
9727 /* Implement REGMODE_NATURAL_SIZE. */
9729 poly_uint64
9730 riscv_regmode_natural_size (machine_mode mode)
9732 /* The natural size for RVV data modes is one RVV data vector,
9733 and similarly for predicates. We can't independently modify
9734 anything smaller than that. */
9735 /* ??? For now, only do this for variable-width RVV registers.
9736 Doing it for constant-sized registers breaks lower-subreg.c. */
9738 if (riscv_v_ext_mode_p (mode))
9740 poly_uint64 size = GET_MODE_SIZE (mode);
9741 if (riscv_v_ext_tuple_mode_p (mode))
9743 size = GET_MODE_SIZE (riscv_vector::get_subpart_mode (mode));
9744 if (known_lt (size, BYTES_PER_RISCV_VECTOR))
9745 return size;
9747 else if (riscv_v_ext_vector_mode_p (mode))
9749 /* RVV mask modes always consume a single register. */
9750 if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL)
9751 return BYTES_PER_RISCV_VECTOR;
9753 if (!size.is_constant ())
9754 return BYTES_PER_RISCV_VECTOR;
9755 else if (!riscv_v_ext_vls_mode_p (mode))
9756 /* For -march=rv64gc_zve32f, the natural vector register size
9757 is 32bits which is smaller than scalar register size, so we
9758 return minimum size between vector register size and scalar
9759 register size. */
9760 return MIN (size.to_constant (), UNITS_PER_WORD);
9762 return UNITS_PER_WORD;
9765 /* Implement the TARGET_DWARF_POLY_INDETERMINATE_VALUE hook. */
9767 static unsigned int
9768 riscv_dwarf_poly_indeterminate_value (unsigned int i, unsigned int *factor,
9769 int *offset)
9771 /* Polynomial invariant 1 == (VLENB / riscv_bytes_per_vector_chunk) - 1.
9772 1. TARGET_MIN_VLEN == 32, polynomial invariant 1 == (VLENB / 4) - 1.
9773 2. TARGET_MIN_VLEN > 32, polynomial invariant 1 == (VLENB / 8) - 1.
9775 gcc_assert (i == 1);
9776 *factor = riscv_bytes_per_vector_chunk;
9777 *offset = 1;
9778 return RISCV_DWARF_VLENB;
9781 /* Implement TARGET_ESTIMATED_POLY_VALUE. */
9783 static HOST_WIDE_INT
9784 riscv_estimated_poly_value (poly_int64 val,
9785 poly_value_estimate_kind kind = POLY_VALUE_LIKELY)
9787 if (TARGET_VECTOR)
9788 return riscv_vector::estimated_poly_value (val, kind);
9789 return default_estimated_poly_value (val, kind);
9792 /* Return true if the vector misalignment factor is supported by the
9793 target. */
9794 bool
9795 riscv_support_vector_misalignment (machine_mode mode,
9796 const_tree type ATTRIBUTE_UNUSED,
9797 int misalignment,
9798 bool is_packed ATTRIBUTE_UNUSED)
9800 /* Depend on movmisalign pattern. */
9801 return default_builtin_support_vector_misalignment (mode, type, misalignment,
9802 is_packed);
9805 /* Implement TARGET_VECTORIZE_GET_MASK_MODE. */
9807 static opt_machine_mode
9808 riscv_get_mask_mode (machine_mode mode)
9810 if (TARGET_VECTOR && riscv_v_ext_mode_p (mode))
9811 return riscv_vector::get_mask_mode (mode);
9813 return default_get_mask_mode (mode);
9816 /* Implement TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE. Assume for now that
9817 it isn't worth branching around empty masked ops (including masked
9818 stores). */
9820 static bool
9821 riscv_empty_mask_is_expensive (unsigned)
9823 return false;
9826 /* Return true if a shift-amount matches the trailing cleared bits on
9827 a bitmask. */
9829 bool
9830 riscv_shamt_matches_mask_p (int shamt, HOST_WIDE_INT mask)
9832 return shamt == ctz_hwi (mask);
9835 static HARD_REG_SET
9836 vector_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs)
9838 HARD_REG_SET zeroed_hardregs;
9839 CLEAR_HARD_REG_SET (zeroed_hardregs);
9841 /* Find a register to hold vl. */
9842 unsigned vl_regno = INVALID_REGNUM;
9843 /* Skip the first GPR, otherwise the existing vl is kept due to the same
9844 between vl and avl. */
9845 for (unsigned regno = GP_REG_FIRST + 1; regno <= GP_REG_LAST; regno++)
9847 if (TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
9849 vl_regno = regno;
9850 break;
9854 if (vl_regno > GP_REG_LAST)
9855 sorry ("cannot allocate vl register for %qs on this target",
9856 "-fzero-call-used-regs");
9858 /* Vector configurations need not be saved and restored here. The
9859 -fzero-call-used-regs=* option will zero all vector registers and
9860 return. So there's no vector operations between them. */
9862 bool emitted_vlmax_vsetvl = false;
9863 rtx vl = gen_rtx_REG (Pmode, vl_regno); /* vl is VLMAX. */
9864 for (unsigned regno = V_REG_FIRST; regno <= V_REG_LAST; ++regno)
9866 if (TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
9868 rtx target = regno_reg_rtx[regno];
9869 machine_mode mode = GET_MODE (target);
9871 if (!emitted_vlmax_vsetvl)
9873 riscv_vector::emit_hard_vlmax_vsetvl (mode, vl);
9874 emitted_vlmax_vsetvl = true;
9877 rtx ops[] = {target, CONST0_RTX (mode)};
9878 riscv_vector::emit_vlmax_insn_lra (code_for_pred_mov (mode),
9879 riscv_vector::UNARY_OP, ops, vl);
9881 SET_HARD_REG_BIT (zeroed_hardregs, regno);
9885 return zeroed_hardregs;
9888 /* Generate a sequence of instructions that zero registers specified by
9889 NEED_ZEROED_HARDREGS. Return the ZEROED_HARDREGS that are actually
9890 zeroed. */
9891 HARD_REG_SET
9892 riscv_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs)
9894 HARD_REG_SET zeroed_hardregs;
9895 CLEAR_HARD_REG_SET (zeroed_hardregs);
9897 if (TARGET_VECTOR)
9898 zeroed_hardregs |= vector_zero_call_used_regs (need_zeroed_hardregs);
9900 return zeroed_hardregs | default_zero_call_used_regs (need_zeroed_hardregs
9901 & ~zeroed_hardregs);
9904 /* Implement target hook TARGET_ARRAY_MODE. */
9906 static opt_machine_mode
9907 riscv_array_mode (machine_mode mode, unsigned HOST_WIDE_INT nelems)
9909 machine_mode vmode;
9910 if (TARGET_VECTOR
9911 && riscv_vector::get_tuple_mode (mode, nelems).exists (&vmode))
9912 return vmode;
9914 return opt_machine_mode ();
9917 /* Given memory reference MEM, expand code to compute the aligned
9918 memory address, shift and mask values and store them into
9919 *ALIGNED_MEM, *SHIFT, *MASK and *NOT_MASK. */
9921 void
9922 riscv_subword_address (rtx mem, rtx *aligned_mem, rtx *shift, rtx *mask,
9923 rtx *not_mask)
9925 /* Align the memory address to a word. */
9926 rtx addr = force_reg (Pmode, XEXP (mem, 0));
9928 rtx addr_mask = gen_int_mode (-4, Pmode);
9930 rtx aligned_addr = gen_reg_rtx (Pmode);
9931 emit_move_insn (aligned_addr, gen_rtx_AND (Pmode, addr, addr_mask));
9933 *aligned_mem = change_address (mem, SImode, aligned_addr);
9935 /* Calculate the shift amount. */
9936 emit_move_insn (*shift, gen_rtx_AND (SImode, gen_lowpart (SImode, addr),
9937 gen_int_mode (3, SImode)));
9938 emit_move_insn (*shift, gen_rtx_ASHIFT (SImode, *shift,
9939 gen_int_mode (3, SImode)));
9941 /* Calculate the mask. */
9942 int unshifted_mask = GET_MODE_MASK (GET_MODE (mem));
9944 emit_move_insn (*mask, gen_int_mode (unshifted_mask, SImode));
9946 emit_move_insn (*mask, gen_rtx_ASHIFT (SImode, *mask,
9947 gen_lowpart (QImode, *shift)));
9949 emit_move_insn (*not_mask, gen_rtx_NOT (SImode, *mask));
9952 /* Leftshift a subword within an SImode register. */
9954 void
9955 riscv_lshift_subword (machine_mode mode, rtx value, rtx shift,
9956 rtx *shifted_value)
9958 rtx value_reg = gen_reg_rtx (SImode);
9959 emit_move_insn (value_reg, simplify_gen_subreg (SImode, value,
9960 mode, 0));
9962 emit_move_insn (*shifted_value, gen_rtx_ASHIFT (SImode, value_reg,
9963 gen_lowpart (QImode, shift)));
9966 /* Return TRUE if we should use the divmod expander, FALSE otherwise. This
9967 allows the behavior to be tuned for specific implementations as well as
9968 when optimizing for size. */
9970 bool
9971 riscv_use_divmod_expander (void)
9973 return tune_param->use_divmod_expansion;
9976 /* Implement TARGET_VECTORIZE_PREFERRED_SIMD_MODE. */
9978 static machine_mode
9979 riscv_preferred_simd_mode (scalar_mode mode)
9981 if (TARGET_VECTOR)
9982 return riscv_vector::preferred_simd_mode (mode);
9984 return word_mode;
9987 /* Implement target hook TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT. */
9989 static poly_uint64
9990 riscv_vectorize_preferred_vector_alignment (const_tree type)
9992 if (riscv_v_ext_mode_p (TYPE_MODE (type)))
9993 return TYPE_ALIGN (TREE_TYPE (type));
9994 return TYPE_ALIGN (type);
9997 /* Return true if it is static FRM rounding mode. */
9999 static bool
10000 riscv_static_frm_mode_p (int mode)
10002 switch (mode)
10004 case riscv_vector::FRM_RDN:
10005 case riscv_vector::FRM_RUP:
10006 case riscv_vector::FRM_RTZ:
10007 case riscv_vector::FRM_RMM:
10008 case riscv_vector::FRM_RNE:
10009 return true;
10010 default:
10011 return false;
10014 gcc_unreachable ();
10017 /* Implement the floating-point Mode Switching. */
10019 static void
10020 riscv_emit_frm_mode_set (int mode, int prev_mode)
10022 rtx backup_reg = DYNAMIC_FRM_RTL (cfun);
10024 if (prev_mode == riscv_vector::FRM_DYN_CALL)
10025 emit_insn (gen_frrmsi (backup_reg)); /* Backup frm when DYN_CALL. */
10027 if (mode != prev_mode)
10029 rtx frm = gen_int_mode (mode, SImode);
10031 if (mode == riscv_vector::FRM_DYN_CALL
10032 && prev_mode != riscv_vector::FRM_DYN && STATIC_FRM_P (cfun))
10033 /* No need to emit when prev mode is DYN already. */
10034 emit_insn (gen_fsrmsi_restore_volatile (backup_reg));
10035 else if (mode == riscv_vector::FRM_DYN_EXIT && STATIC_FRM_P (cfun)
10036 && prev_mode != riscv_vector::FRM_DYN
10037 && prev_mode != riscv_vector::FRM_DYN_CALL)
10038 /* No need to emit when prev mode is DYN or DYN_CALL already. */
10039 emit_insn (gen_fsrmsi_restore_volatile (backup_reg));
10040 else if (mode == riscv_vector::FRM_DYN
10041 && prev_mode != riscv_vector::FRM_DYN_CALL)
10042 /* Restore frm value from backup when switch to DYN mode. */
10043 emit_insn (gen_fsrmsi_restore (backup_reg));
10044 else if (riscv_static_frm_mode_p (mode))
10045 /* Set frm value when switch to static mode. */
10046 emit_insn (gen_fsrmsi_restore (frm));
10050 /* Implement Mode switching. */
10052 static void
10053 riscv_emit_mode_set (int entity, int mode, int prev_mode,
10054 HARD_REG_SET regs_live ATTRIBUTE_UNUSED)
10056 switch (entity)
10058 case RISCV_VXRM:
10059 if (mode != VXRM_MODE_NONE && mode != prev_mode)
10060 emit_insn (gen_vxrmsi (gen_int_mode (mode, SImode)));
10061 break;
10062 case RISCV_FRM:
10063 riscv_emit_frm_mode_set (mode, prev_mode);
10064 break;
10065 default:
10066 gcc_unreachable ();
10070 /* Adjust the FRM_NONE insn after a call to FRM_DYN for the
10071 underlying emit. */
10073 static int
10074 riscv_frm_adjust_mode_after_call (rtx_insn *cur_insn, int mode)
10076 rtx_insn *insn = prev_nonnote_nondebug_insn_bb (cur_insn);
10078 if (insn && CALL_P (insn))
10079 return riscv_vector::FRM_DYN;
10081 return mode;
10084 /* Insert the backup frm insn to the end of the bb if and only if the call
10085 is the last insn of this bb. */
10087 static void
10088 riscv_frm_emit_after_bb_end (rtx_insn *cur_insn)
10090 edge eg;
10091 bool abnormal_edge_p = false;
10092 edge_iterator eg_iterator;
10093 basic_block bb = BLOCK_FOR_INSN (cur_insn);
10095 FOR_EACH_EDGE (eg, eg_iterator, bb->succs)
10097 if (eg->flags & EDGE_ABNORMAL)
10098 abnormal_edge_p = true;
10099 else
10101 start_sequence ();
10102 emit_insn (gen_frrmsi (DYNAMIC_FRM_RTL (cfun)));
10103 rtx_insn *backup_insn = get_insns ();
10104 end_sequence ();
10106 insert_insn_on_edge (backup_insn, eg);
10110 if (abnormal_edge_p)
10112 start_sequence ();
10113 emit_insn (gen_frrmsi (DYNAMIC_FRM_RTL (cfun)));
10114 rtx_insn *backup_insn = get_insns ();
10115 end_sequence ();
10117 insert_insn_end_basic_block (backup_insn, bb);
10120 commit_edge_insertions ();
10123 /* Return mode that frm must be switched into
10124 prior to the execution of insn. */
10126 static int
10127 riscv_frm_mode_needed (rtx_insn *cur_insn, int code)
10129 if (!DYNAMIC_FRM_RTL(cfun))
10131 /* The dynamic frm will be initialized only onece during cfun. */
10132 DYNAMIC_FRM_RTL (cfun) = gen_reg_rtx (SImode);
10133 emit_insn_at_entry (gen_frrmsi (DYNAMIC_FRM_RTL (cfun)));
10136 if (CALL_P (cur_insn))
10138 rtx_insn *insn = next_nonnote_nondebug_insn_bb (cur_insn);
10140 if (!insn)
10141 riscv_frm_emit_after_bb_end (cur_insn);
10143 return riscv_vector::FRM_DYN_CALL;
10146 int mode = code >= 0 ? get_attr_frm_mode (cur_insn) : riscv_vector::FRM_NONE;
10148 if (mode == riscv_vector::FRM_NONE)
10149 /* After meet a call, we need to backup the frm because it may be
10150 updated during the call. Here, for each insn, we will check if
10151 the previous insn is a call or not. When previous insn is call,
10152 there will be 2 cases for the emit mode set.
10154 1. Current insn is not MODE_NONE, then the mode switch framework
10155 will do the mode switch from MODE_CALL to MODE_NONE natively.
10156 2. Current insn is MODE_NONE, we need to adjust the MODE_NONE to
10157 the MODE_DYN, and leave the mode switch itself to perform
10158 the emit mode set.
10160 mode = riscv_frm_adjust_mode_after_call (cur_insn, mode);
10162 return mode;
10165 /* Return mode that entity must be switched into
10166 prior to the execution of insn. */
10168 static int
10169 riscv_mode_needed (int entity, rtx_insn *insn, HARD_REG_SET)
10171 int code = recog_memoized (insn);
10173 switch (entity)
10175 case RISCV_VXRM:
10176 return code >= 0 ? get_attr_vxrm_mode (insn) : VXRM_MODE_NONE;
10177 case RISCV_FRM:
10178 return riscv_frm_mode_needed (insn, code);
10179 default:
10180 gcc_unreachable ();
10184 /* Return TRUE that an insn is asm. */
10186 static bool
10187 asm_insn_p (rtx_insn *insn)
10189 extract_insn (insn);
10191 return recog_data.is_asm;
10194 /* Return TRUE that an insn is unknown for VXRM. */
10196 static bool
10197 vxrm_unknown_p (rtx_insn *insn)
10199 /* Return true if there is a definition of VXRM. */
10200 if (reg_set_p (gen_rtx_REG (SImode, VXRM_REGNUM), insn))
10201 return true;
10203 /* A CALL function may contain an instruction that modifies the VXRM,
10204 return true in this situation. */
10205 if (CALL_P (insn))
10206 return true;
10208 /* Return true for all assembly since users may hardcode a assembly
10209 like this: asm volatile ("csrwi vxrm, 0"). */
10210 if (asm_insn_p (insn))
10211 return true;
10213 return false;
10216 /* Return TRUE that an insn is unknown dynamic for FRM. */
10218 static bool
10219 frm_unknown_dynamic_p (rtx_insn *insn)
10221 /* Return true if there is a definition of FRM. */
10222 if (reg_set_p (gen_rtx_REG (SImode, FRM_REGNUM), insn))
10223 return true;
10225 return false;
10228 /* Return the mode that an insn results in for VXRM. */
10230 static int
10231 riscv_vxrm_mode_after (rtx_insn *insn, int mode)
10233 if (vxrm_unknown_p (insn))
10234 return VXRM_MODE_NONE;
10236 if (recog_memoized (insn) < 0)
10237 return mode;
10239 if (reg_mentioned_p (gen_rtx_REG (SImode, VXRM_REGNUM), PATTERN (insn)))
10240 return get_attr_vxrm_mode (insn);
10241 else
10242 return mode;
10245 /* Return the mode that an insn results in for FRM. */
10247 static int
10248 riscv_frm_mode_after (rtx_insn *insn, int mode)
10250 STATIC_FRM_P (cfun) = STATIC_FRM_P (cfun) || riscv_static_frm_mode_p (mode);
10252 if (CALL_P (insn))
10253 return mode;
10255 if (frm_unknown_dynamic_p (insn))
10256 return riscv_vector::FRM_DYN;
10258 if (recog_memoized (insn) < 0)
10259 return mode;
10261 if (reg_mentioned_p (gen_rtx_REG (SImode, FRM_REGNUM), PATTERN (insn)))
10262 return get_attr_frm_mode (insn);
10263 else
10264 return mode;
10267 /* Return the mode that an insn results in. */
10269 static int
10270 riscv_mode_after (int entity, int mode, rtx_insn *insn, HARD_REG_SET)
10272 switch (entity)
10274 case RISCV_VXRM:
10275 return riscv_vxrm_mode_after (insn, mode);
10276 case RISCV_FRM:
10277 return riscv_frm_mode_after (insn, mode);
10278 default:
10279 gcc_unreachable ();
10283 /* Return a mode that ENTITY is assumed to be
10284 switched to at function entry. */
10286 static int
10287 riscv_mode_entry (int entity)
10289 switch (entity)
10291 case RISCV_VXRM:
10292 return VXRM_MODE_NONE;
10293 case RISCV_FRM:
10295 /* According to RVV 1.0 spec, all vector floating-point operations use
10296 the dynamic rounding mode in the frm register. Likewise in other
10297 similar places. */
10298 return riscv_vector::FRM_DYN;
10300 default:
10301 gcc_unreachable ();
10305 /* Return a mode that ENTITY is assumed to be
10306 switched to at function exit. */
10308 static int
10309 riscv_mode_exit (int entity)
10311 switch (entity)
10313 case RISCV_VXRM:
10314 return VXRM_MODE_NONE;
10315 case RISCV_FRM:
10316 return riscv_vector::FRM_DYN_EXIT;
10317 default:
10318 gcc_unreachable ();
10322 static int
10323 riscv_mode_priority (int, int n)
10325 return n;
10328 /* Implement TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES. */
10329 unsigned int
10330 riscv_autovectorize_vector_modes (vector_modes *modes, bool all)
10332 if (TARGET_VECTOR)
10333 return riscv_vector::autovectorize_vector_modes (modes, all);
10335 return default_autovectorize_vector_modes (modes, all);
10338 /* Implement TARGET_VECTORIZE_RELATED_MODE. */
10339 opt_machine_mode
10340 riscv_vectorize_related_mode (machine_mode vector_mode, scalar_mode element_mode,
10341 poly_uint64 nunits)
10343 if (TARGET_VECTOR)
10344 return riscv_vector::vectorize_related_mode (vector_mode, element_mode,
10345 nunits);
10346 return default_vectorize_related_mode (vector_mode, element_mode, nunits);
10349 /* Implement TARGET_VECTORIZE_VEC_PERM_CONST. */
10351 static bool
10352 riscv_vectorize_vec_perm_const (machine_mode vmode, machine_mode op_mode,
10353 rtx target, rtx op0, rtx op1,
10354 const vec_perm_indices &sel)
10356 if (TARGET_VECTOR && riscv_v_ext_mode_p (vmode))
10357 return riscv_vector::expand_vec_perm_const (vmode, op_mode, target, op0,
10358 op1, sel);
10360 return false;
10363 static bool
10364 riscv_frame_pointer_required (void)
10366 return riscv_save_frame_pointer && !crtl->is_leaf;
10369 /* Return the appropriate common costs according to VECTYPE from COSTS. */
10370 static const common_vector_cost *
10371 get_common_costs (const cpu_vector_cost *costs, tree vectype)
10373 gcc_assert (costs);
10375 if (vectype && riscv_v_ext_vls_mode_p (TYPE_MODE (vectype)))
10376 return costs->vls;
10377 return costs->vla;
10380 /* Return the CPU vector costs according to -mtune if tune info has non-NULL
10381 vector cost. Otherwide, return the default generic vector costs. */
10382 const cpu_vector_cost *
10383 get_vector_costs ()
10385 const cpu_vector_cost *costs = tune_param->vec_costs;
10386 if (!costs)
10387 return &generic_vector_cost;
10388 return costs;
10391 /* Implement targetm.vectorize.builtin_vectorization_cost. */
10393 static int
10394 riscv_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
10395 tree vectype, int misalign ATTRIBUTE_UNUSED)
10397 const cpu_vector_cost *costs = get_vector_costs ();
10398 bool fp = false;
10400 if (vectype != NULL)
10401 fp = FLOAT_TYPE_P (vectype);
10403 const common_vector_cost *common_costs = get_common_costs (costs, vectype);
10404 gcc_assert (common_costs != NULL);
10405 switch (type_of_cost)
10407 case scalar_stmt:
10408 return fp ? costs->scalar_fp_stmt_cost : costs->scalar_int_stmt_cost;
10410 case scalar_load:
10411 return costs->scalar_load_cost;
10413 case scalar_store:
10414 return costs->scalar_store_cost;
10416 case vector_stmt:
10417 return fp ? common_costs->fp_stmt_cost : common_costs->int_stmt_cost;
10419 case vector_load:
10420 return common_costs->align_load_cost;
10422 case vector_store:
10423 return common_costs->align_store_cost;
10425 case vec_to_scalar:
10426 return common_costs->vec_to_scalar_cost;
10428 case scalar_to_vec:
10429 return common_costs->scalar_to_vec_cost;
10431 case unaligned_load:
10432 return common_costs->unalign_load_cost;
10433 case vector_gather_load:
10434 return common_costs->gather_load_cost;
10436 case unaligned_store:
10437 return common_costs->unalign_store_cost;
10438 case vector_scatter_store:
10439 return common_costs->scatter_store_cost;
10441 case cond_branch_taken:
10442 return costs->cond_taken_branch_cost;
10444 case cond_branch_not_taken:
10445 return costs->cond_not_taken_branch_cost;
10447 case vec_perm:
10448 return common_costs->permute_cost;
10450 case vec_promote_demote:
10451 return fp ? common_costs->fp_stmt_cost : common_costs->int_stmt_cost;
10453 case vec_construct:
10454 return estimated_poly_value (TYPE_VECTOR_SUBPARTS (vectype));
10456 default:
10457 gcc_unreachable ();
10460 return default_builtin_vectorization_cost (type_of_cost, vectype, misalign);
10463 /* Implement targetm.vectorize.create_costs. */
10465 static vector_costs *
10466 riscv_vectorize_create_costs (vec_info *vinfo, bool costing_for_scalar)
10468 if (TARGET_VECTOR)
10469 return new riscv_vector::costs (vinfo, costing_for_scalar);
10470 /* Default vector costs. */
10471 return new vector_costs (vinfo, costing_for_scalar);
10474 /* Implement TARGET_PREFERRED_ELSE_VALUE. */
10476 static tree
10477 riscv_preferred_else_value (unsigned ifn, tree vectype, unsigned int nops,
10478 tree *ops)
10480 if (riscv_v_ext_mode_p (TYPE_MODE (vectype)))
10481 return get_or_create_ssa_default_def (cfun, create_tmp_var (vectype));
10483 return default_preferred_else_value (ifn, vectype, nops, ops);
10486 /* If MEM is in the form of "base+offset", extract the two parts
10487 of address and set to BASE and OFFSET, otherwise return false
10488 after clearing BASE and OFFSET. */
10490 bool
10491 extract_base_offset_in_addr (rtx mem, rtx *base, rtx *offset)
10493 rtx addr;
10495 gcc_assert (MEM_P (mem));
10497 addr = XEXP (mem, 0);
10499 if (REG_P (addr))
10501 *base = addr;
10502 *offset = const0_rtx;
10503 return true;
10506 if (GET_CODE (addr) == PLUS
10507 && REG_P (XEXP (addr, 0)) && CONST_INT_P (XEXP (addr, 1)))
10509 *base = XEXP (addr, 0);
10510 *offset = XEXP (addr, 1);
10511 return true;
10514 *base = NULL_RTX;
10515 *offset = NULL_RTX;
10517 return false;
10520 /* Initialize the GCC target structure. */
10521 #undef TARGET_ASM_ALIGNED_HI_OP
10522 #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
10523 #undef TARGET_ASM_ALIGNED_SI_OP
10524 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
10525 #undef TARGET_ASM_ALIGNED_DI_OP
10526 #define TARGET_ASM_ALIGNED_DI_OP "\t.dword\t"
10528 #undef TARGET_OPTION_OVERRIDE
10529 #define TARGET_OPTION_OVERRIDE riscv_option_override
10531 #undef TARGET_OPTION_RESTORE
10532 #define TARGET_OPTION_RESTORE riscv_option_restore
10534 #undef TARGET_OPTION_VALID_ATTRIBUTE_P
10535 #define TARGET_OPTION_VALID_ATTRIBUTE_P riscv_option_valid_attribute_p
10537 #undef TARGET_LEGITIMIZE_ADDRESS
10538 #define TARGET_LEGITIMIZE_ADDRESS riscv_legitimize_address
10540 #undef TARGET_SCHED_ISSUE_RATE
10541 #define TARGET_SCHED_ISSUE_RATE riscv_issue_rate
10542 #undef TARGET_SCHED_MACRO_FUSION_P
10543 #define TARGET_SCHED_MACRO_FUSION_P riscv_macro_fusion_p
10544 #undef TARGET_SCHED_MACRO_FUSION_PAIR_P
10545 #define TARGET_SCHED_MACRO_FUSION_PAIR_P riscv_macro_fusion_pair_p
10547 #undef TARGET_SCHED_VARIABLE_ISSUE
10548 #define TARGET_SCHED_VARIABLE_ISSUE riscv_sched_variable_issue
10550 #undef TARGET_SCHED_ADJUST_COST
10551 #define TARGET_SCHED_ADJUST_COST riscv_sched_adjust_cost
10553 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
10554 #define TARGET_FUNCTION_OK_FOR_SIBCALL riscv_function_ok_for_sibcall
10556 #undef TARGET_SET_CURRENT_FUNCTION
10557 #define TARGET_SET_CURRENT_FUNCTION riscv_set_current_function
10559 #undef TARGET_REGISTER_MOVE_COST
10560 #define TARGET_REGISTER_MOVE_COST riscv_register_move_cost
10561 #undef TARGET_MEMORY_MOVE_COST
10562 #define TARGET_MEMORY_MOVE_COST riscv_memory_move_cost
10563 #undef TARGET_RTX_COSTS
10564 #define TARGET_RTX_COSTS riscv_rtx_costs
10565 #undef TARGET_ADDRESS_COST
10566 #define TARGET_ADDRESS_COST riscv_address_cost
10567 #undef TARGET_INSN_COST
10568 #define TARGET_INSN_COST riscv_insn_cost
10570 #undef TARGET_MAX_NOCE_IFCVT_SEQ_COST
10571 #define TARGET_MAX_NOCE_IFCVT_SEQ_COST riscv_max_noce_ifcvt_seq_cost
10572 #undef TARGET_NOCE_CONVERSION_PROFITABLE_P
10573 #define TARGET_NOCE_CONVERSION_PROFITABLE_P riscv_noce_conversion_profitable_p
10575 #undef TARGET_ASM_FILE_START
10576 #define TARGET_ASM_FILE_START riscv_file_start
10577 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
10578 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
10579 #undef TARGET_ASM_FILE_END
10580 #define TARGET_ASM_FILE_END file_end_indicate_exec_stack
10582 #undef TARGET_EXPAND_BUILTIN_VA_START
10583 #define TARGET_EXPAND_BUILTIN_VA_START riscv_va_start
10585 #undef TARGET_PROMOTE_FUNCTION_MODE
10586 #define TARGET_PROMOTE_FUNCTION_MODE riscv_promote_function_mode
10588 #undef TARGET_RETURN_IN_MEMORY
10589 #define TARGET_RETURN_IN_MEMORY riscv_return_in_memory
10591 #undef TARGET_ASM_OUTPUT_MI_THUNK
10592 #define TARGET_ASM_OUTPUT_MI_THUNK riscv_output_mi_thunk
10593 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
10594 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
10596 #undef TARGET_PRINT_OPERAND
10597 #define TARGET_PRINT_OPERAND riscv_print_operand
10598 #undef TARGET_PRINT_OPERAND_ADDRESS
10599 #define TARGET_PRINT_OPERAND_ADDRESS riscv_print_operand_address
10600 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
10601 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P riscv_print_operand_punct_valid_p
10603 #undef TARGET_SETUP_INCOMING_VARARGS
10604 #define TARGET_SETUP_INCOMING_VARARGS riscv_setup_incoming_varargs
10605 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
10606 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS riscv_allocate_stack_slots_for_args
10607 #undef TARGET_STRICT_ARGUMENT_NAMING
10608 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
10609 #undef TARGET_MUST_PASS_IN_STACK
10610 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
10611 #undef TARGET_PASS_BY_REFERENCE
10612 #define TARGET_PASS_BY_REFERENCE riscv_pass_by_reference
10613 #undef TARGET_ARG_PARTIAL_BYTES
10614 #define TARGET_ARG_PARTIAL_BYTES riscv_arg_partial_bytes
10615 #undef TARGET_FUNCTION_ARG
10616 #define TARGET_FUNCTION_ARG riscv_function_arg
10617 #undef TARGET_FUNCTION_ARG_ADVANCE
10618 #define TARGET_FUNCTION_ARG_ADVANCE riscv_function_arg_advance
10619 #undef TARGET_FUNCTION_ARG_BOUNDARY
10620 #define TARGET_FUNCTION_ARG_BOUNDARY riscv_function_arg_boundary
10621 #undef TARGET_FNTYPE_ABI
10622 #define TARGET_FNTYPE_ABI riscv_fntype_abi
10623 #undef TARGET_INSN_CALLEE_ABI
10624 #define TARGET_INSN_CALLEE_ABI riscv_insn_callee_abi
10626 #undef TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS
10627 #define TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS \
10628 riscv_get_separate_components
10630 #undef TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB
10631 #define TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB \
10632 riscv_components_for_bb
10634 #undef TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS
10635 #define TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS \
10636 riscv_disqualify_components
10638 #undef TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS
10639 #define TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS \
10640 riscv_emit_prologue_components
10642 #undef TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS
10643 #define TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS \
10644 riscv_emit_epilogue_components
10646 #undef TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS
10647 #define TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS \
10648 riscv_set_handled_components
10650 /* The generic ELF target does not always have TLS support. */
10651 #ifdef HAVE_AS_TLS
10652 #undef TARGET_HAVE_TLS
10653 #define TARGET_HAVE_TLS true
10654 #endif
10656 #undef TARGET_CANNOT_FORCE_CONST_MEM
10657 #define TARGET_CANNOT_FORCE_CONST_MEM riscv_cannot_force_const_mem
10659 #undef TARGET_LEGITIMATE_CONSTANT_P
10660 #define TARGET_LEGITIMATE_CONSTANT_P riscv_legitimate_constant_p
10662 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
10663 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P riscv_use_blocks_for_constant_p
10665 #undef TARGET_LEGITIMATE_ADDRESS_P
10666 #define TARGET_LEGITIMATE_ADDRESS_P riscv_legitimate_address_p
10668 #undef TARGET_CAN_ELIMINATE
10669 #define TARGET_CAN_ELIMINATE riscv_can_eliminate
10671 #undef TARGET_CONDITIONAL_REGISTER_USAGE
10672 #define TARGET_CONDITIONAL_REGISTER_USAGE riscv_conditional_register_usage
10674 #undef TARGET_CLASS_MAX_NREGS
10675 #define TARGET_CLASS_MAX_NREGS riscv_class_max_nregs
10677 #undef TARGET_TRAMPOLINE_INIT
10678 #define TARGET_TRAMPOLINE_INIT riscv_trampoline_init
10680 #undef TARGET_IN_SMALL_DATA_P
10681 #define TARGET_IN_SMALL_DATA_P riscv_in_small_data_p
10683 #undef TARGET_HAVE_SRODATA_SECTION
10684 #define TARGET_HAVE_SRODATA_SECTION true
10686 #undef TARGET_ASM_SELECT_SECTION
10687 #define TARGET_ASM_SELECT_SECTION riscv_select_section
10689 #undef TARGET_ASM_UNIQUE_SECTION
10690 #define TARGET_ASM_UNIQUE_SECTION riscv_unique_section
10692 #undef TARGET_ASM_SELECT_RTX_SECTION
10693 #define TARGET_ASM_SELECT_RTX_SECTION riscv_elf_select_rtx_section
10695 #undef TARGET_MIN_ANCHOR_OFFSET
10696 #define TARGET_MIN_ANCHOR_OFFSET (-IMM_REACH/2)
10698 #undef TARGET_MAX_ANCHOR_OFFSET
10699 #define TARGET_MAX_ANCHOR_OFFSET (IMM_REACH/2-1)
10701 #undef TARGET_REGISTER_PRIORITY
10702 #define TARGET_REGISTER_PRIORITY riscv_register_priority
10704 #undef TARGET_CANNOT_COPY_INSN_P
10705 #define TARGET_CANNOT_COPY_INSN_P riscv_cannot_copy_insn_p
10707 #undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
10708 #define TARGET_ATOMIC_ASSIGN_EXPAND_FENV riscv_atomic_assign_expand_fenv
10710 #undef TARGET_INIT_BUILTINS
10711 #define TARGET_INIT_BUILTINS riscv_init_builtins
10713 #undef TARGET_BUILTIN_DECL
10714 #define TARGET_BUILTIN_DECL riscv_builtin_decl
10716 #undef TARGET_GIMPLE_FOLD_BUILTIN
10717 #define TARGET_GIMPLE_FOLD_BUILTIN riscv_gimple_fold_builtin
10719 #undef TARGET_EXPAND_BUILTIN
10720 #define TARGET_EXPAND_BUILTIN riscv_expand_builtin
10722 #undef TARGET_HARD_REGNO_NREGS
10723 #define TARGET_HARD_REGNO_NREGS riscv_hard_regno_nregs
10724 #undef TARGET_HARD_REGNO_MODE_OK
10725 #define TARGET_HARD_REGNO_MODE_OK riscv_hard_regno_mode_ok
10727 #undef TARGET_MODES_TIEABLE_P
10728 #define TARGET_MODES_TIEABLE_P riscv_modes_tieable_p
10730 #undef TARGET_SLOW_UNALIGNED_ACCESS
10731 #define TARGET_SLOW_UNALIGNED_ACCESS riscv_slow_unaligned_access
10733 #undef TARGET_SECONDARY_MEMORY_NEEDED
10734 #define TARGET_SECONDARY_MEMORY_NEEDED riscv_secondary_memory_needed
10736 #undef TARGET_CAN_CHANGE_MODE_CLASS
10737 #define TARGET_CAN_CHANGE_MODE_CLASS riscv_can_change_mode_class
10739 #undef TARGET_CONSTANT_ALIGNMENT
10740 #define TARGET_CONSTANT_ALIGNMENT riscv_constant_alignment
10742 #undef TARGET_MERGE_DECL_ATTRIBUTES
10743 #define TARGET_MERGE_DECL_ATTRIBUTES riscv_merge_decl_attributes
10745 #undef TARGET_ATTRIBUTE_TABLE
10746 #define TARGET_ATTRIBUTE_TABLE riscv_attribute_table
10748 #undef TARGET_WARN_FUNC_RETURN
10749 #define TARGET_WARN_FUNC_RETURN riscv_warn_func_return
10751 /* The low bit is ignored by jump instructions so is safe to use. */
10752 #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
10753 #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 1
10755 #undef TARGET_MACHINE_DEPENDENT_REORG
10756 #define TARGET_MACHINE_DEPENDENT_REORG riscv_reorg
10758 #undef TARGET_NEW_ADDRESS_PROFITABLE_P
10759 #define TARGET_NEW_ADDRESS_PROFITABLE_P riscv_new_address_profitable_p
10761 #undef TARGET_MANGLE_TYPE
10762 #define TARGET_MANGLE_TYPE riscv_mangle_type
10764 #undef TARGET_SCALAR_MODE_SUPPORTED_P
10765 #define TARGET_SCALAR_MODE_SUPPORTED_P riscv_scalar_mode_supported_p
10767 #undef TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P
10768 #define TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P \
10769 riscv_libgcc_floating_mode_supported_p
10771 #undef TARGET_INIT_LIBFUNCS
10772 #define TARGET_INIT_LIBFUNCS riscv_init_libfuncs
10774 #undef TARGET_C_EXCESS_PRECISION
10775 #define TARGET_C_EXCESS_PRECISION riscv_excess_precision
10777 #undef TARGET_FLOATN_MODE
10778 #define TARGET_FLOATN_MODE riscv_floatn_mode
10780 #undef TARGET_ASAN_SHADOW_OFFSET
10781 #define TARGET_ASAN_SHADOW_OFFSET riscv_asan_shadow_offset
10783 #ifdef TARGET_BIG_ENDIAN_DEFAULT
10784 #undef TARGET_DEFAULT_TARGET_FLAGS
10785 #define TARGET_DEFAULT_TARGET_FLAGS (MASK_BIG_ENDIAN)
10786 #endif
10788 #undef TARGET_VECTOR_MODE_SUPPORTED_P
10789 #define TARGET_VECTOR_MODE_SUPPORTED_P riscv_vector_mode_supported_p
10791 #undef TARGET_VERIFY_TYPE_CONTEXT
10792 #define TARGET_VERIFY_TYPE_CONTEXT riscv_verify_type_context
10794 #undef TARGET_ESTIMATED_POLY_VALUE
10795 #define TARGET_ESTIMATED_POLY_VALUE riscv_estimated_poly_value
10797 #undef TARGET_VECTORIZE_GET_MASK_MODE
10798 #define TARGET_VECTORIZE_GET_MASK_MODE riscv_get_mask_mode
10800 #undef TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE
10801 #define TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE riscv_empty_mask_is_expensive
10803 #undef TARGET_VECTOR_ALIGNMENT
10804 #define TARGET_VECTOR_ALIGNMENT riscv_vector_alignment
10806 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
10807 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT riscv_support_vector_misalignment
10809 #undef TARGET_DWARF_POLY_INDETERMINATE_VALUE
10810 #define TARGET_DWARF_POLY_INDETERMINATE_VALUE riscv_dwarf_poly_indeterminate_value
10812 #undef TARGET_ZERO_CALL_USED_REGS
10813 #define TARGET_ZERO_CALL_USED_REGS riscv_zero_call_used_regs
10815 #undef TARGET_ARRAY_MODE
10816 #define TARGET_ARRAY_MODE riscv_array_mode
10818 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
10819 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE riscv_preferred_simd_mode
10821 #undef TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT
10822 #define TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT \
10823 riscv_vectorize_preferred_vector_alignment
10825 /* Mode switching hooks. */
10827 #undef TARGET_MODE_EMIT
10828 #define TARGET_MODE_EMIT riscv_emit_mode_set
10829 #undef TARGET_MODE_NEEDED
10830 #define TARGET_MODE_NEEDED riscv_mode_needed
10831 #undef TARGET_MODE_AFTER
10832 #define TARGET_MODE_AFTER riscv_mode_after
10833 #undef TARGET_MODE_ENTRY
10834 #define TARGET_MODE_ENTRY riscv_mode_entry
10835 #undef TARGET_MODE_EXIT
10836 #define TARGET_MODE_EXIT riscv_mode_exit
10837 #undef TARGET_MODE_PRIORITY
10838 #define TARGET_MODE_PRIORITY riscv_mode_priority
10840 #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES
10841 #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES \
10842 riscv_autovectorize_vector_modes
10844 #undef TARGET_VECTORIZE_RELATED_MODE
10845 #define TARGET_VECTORIZE_RELATED_MODE riscv_vectorize_related_mode
10847 #undef TARGET_VECTORIZE_VEC_PERM_CONST
10848 #define TARGET_VECTORIZE_VEC_PERM_CONST riscv_vectorize_vec_perm_const
10850 #undef TARGET_FRAME_POINTER_REQUIRED
10851 #define TARGET_FRAME_POINTER_REQUIRED riscv_frame_pointer_required
10853 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
10854 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
10855 riscv_builtin_vectorization_cost
10857 #undef TARGET_VECTORIZE_CREATE_COSTS
10858 #define TARGET_VECTORIZE_CREATE_COSTS riscv_vectorize_create_costs
10860 #undef TARGET_PREFERRED_ELSE_VALUE
10861 #define TARGET_PREFERRED_ELSE_VALUE riscv_preferred_else_value
10863 struct gcc_target targetm = TARGET_INITIALIZER;
10865 #include "gt-riscv.h"