1 /* Definition of RISC-V target for GNU compiler.
2 Copyright (C) 2011-2025 Free Software Foundation, Inc.
3 Contributed by Andrew Waterman (andrew@sifive.com).
4 Based on MIPS target for GNU compiler.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 #ifndef GCC_RISCV_PROTOS_H
23 #define GCC_RISCV_PROTOS_H
27 /* Symbol types we understand. The order of this list must match that of
28 the unspec enum in riscv.md, subsequent to UNSPEC_ADDRESS_FIRST. */
29 enum riscv_symbol_type
{
40 #define NUM_SYMBOL_TYPES (SYMBOL_TLSDESC + 1)
42 /* Classifies an address.
45 A natural register + offset address. The register satisfies
46 riscv_valid_base_register_p and the offset is a const_arith_operand.
49 A base register indexed by (optionally scaled) register.
52 A base register indexed by (optionally scaled) zero-extended register.
55 A base register indexed by immediate offset with writeback.
58 A LO_SUM rtx. The first operand is a valid base register and
59 the second operand is a symbolic address.
62 A signed 16-bit constant address.
65 A constant symbolic address. */
66 enum riscv_address_type
{
76 /* Information about an address described by riscv_address_type.
82 REG is the base register and OFFSET is the constant offset.
84 ADDRESS_REG_REG and ADDRESS_REG_UREG
85 REG is the base register and OFFSET is the index register.
88 REG is the base register, OFFSET is the constant offset, and
89 shift is the shift amount for the offset.
92 REG and OFFSET are the operands to the LO_SUM and SYMBOL_TYPE
93 is the type of symbol it references.
96 SYMBOL_TYPE is the type of symbol that the address references. */
97 struct riscv_address_info
{
98 enum riscv_address_type type
;
101 enum riscv_symbol_type symbol_type
;
105 /* Routines implemented in riscv.cc. */
106 extern const char *riscv_asm_output_opcode (FILE *asm_out_file
, const char *p
);
107 extern enum riscv_symbol_type
riscv_classify_symbolic_expression (rtx
);
108 extern bool riscv_symbolic_constant_p (rtx
, enum riscv_symbol_type
*);
109 extern int riscv_float_const_rtx_index_for_fli (rtx
);
110 extern int riscv_regno_mode_ok_for_base_p (int, machine_mode
, bool);
111 extern bool riscv_valid_base_register_p (rtx
, machine_mode
, bool);
112 extern enum reg_class
riscv_index_reg_class ();
113 extern int riscv_regno_ok_for_index_p (int);
114 extern int riscv_address_insns (rtx
, machine_mode
, bool);
115 extern int riscv_const_insns (rtx
, bool);
116 extern int riscv_split_const_insns (rtx
);
117 extern int riscv_load_store_insns (rtx
, rtx_insn
*);
118 extern rtx
riscv_emit_move (rtx
, rtx
);
119 extern bool riscv_split_symbol (rtx
, rtx
, machine_mode
, rtx
*);
120 extern bool riscv_split_symbol_type (enum riscv_symbol_type
);
121 extern rtx
riscv_unspec_address (rtx
, enum riscv_symbol_type
);
122 extern void riscv_move_integer (rtx
, rtx
, HOST_WIDE_INT
, machine_mode
);
123 extern bool riscv_legitimize_move (machine_mode
, rtx
, rtx
);
124 extern rtx
riscv_subword (rtx
, bool);
125 extern bool riscv_split_64bit_move_p (rtx
, rtx
);
126 extern void riscv_split_doubleword_move (rtx
, rtx
);
127 extern const char *riscv_output_move (rtx
, rtx
);
128 extern const char *riscv_output_return ();
129 extern void riscv_declare_function_name (FILE *, const char *, tree
);
130 extern void riscv_declare_function_size (FILE *, const char *, tree
);
131 extern void riscv_asm_output_alias (FILE *, const tree
, const tree
);
132 extern void riscv_asm_output_external (FILE *, const tree
, const char *);
134 riscv_zcmp_valid_stack_adj_bytes_p (HOST_WIDE_INT
, int);
135 extern void riscv_legitimize_poly_move (machine_mode
, rtx
, rtx
, rtx
);
136 extern void riscv_expand_usadd (rtx
, rtx
, rtx
);
137 extern void riscv_expand_ssadd (rtx
, rtx
, rtx
);
138 extern void riscv_expand_ussub (rtx
, rtx
, rtx
);
139 extern void riscv_expand_sssub (rtx
, rtx
, rtx
);
140 extern void riscv_expand_ustrunc (rtx
, rtx
);
141 extern void riscv_expand_sstrunc (rtx
, rtx
);
142 extern int riscv_register_move_cost (machine_mode
, reg_class_t
, reg_class_t
);
145 extern void riscv_expand_int_scc (rtx
, enum rtx_code
, rtx
, rtx
, bool *invert_ptr
= 0);
146 extern void riscv_expand_float_scc (rtx
, enum rtx_code
, rtx
, rtx
,
147 bool *invert_ptr
= nullptr);
148 extern void riscv_expand_conditional_branch (rtx
, enum rtx_code
, rtx
, rtx
);
149 extern rtx
riscv_emit_unary (enum rtx_code code
, rtx dest
, rtx x
);
150 extern rtx
riscv_emit_binary (enum rtx_code code
, rtx dest
, rtx x
, rtx y
);
152 extern bool riscv_expand_conditional_move (rtx
, rtx
, rtx
, rtx
);
153 extern rtx
riscv_legitimize_call_address (rtx
);
154 extern void riscv_set_return_address (rtx
, rtx
);
155 extern rtx
riscv_return_addr (int, rtx
);
156 extern poly_int64
riscv_initial_elimination_offset (int, int);
157 extern void riscv_expand_prologue (void);
158 extern void riscv_expand_epilogue (int);
159 extern bool riscv_epilogue_uses (unsigned int);
160 extern bool riscv_can_use_return_insn (void);
161 extern rtx
riscv_function_value (const_tree
, const_tree
, enum machine_mode
);
162 extern bool riscv_store_data_bypass_p (rtx_insn
*, rtx_insn
*);
163 extern rtx
riscv_gen_gpr_save_insn (struct riscv_frame_info
*);
164 extern bool riscv_gpr_save_operation_p (rtx
);
165 extern void riscv_reinit (void);
166 extern poly_uint64
riscv_regmode_natural_size (machine_mode
);
167 extern bool riscv_v_ext_vector_mode_p (machine_mode
);
168 extern bool riscv_v_ext_tuple_mode_p (machine_mode
);
169 extern bool riscv_v_ext_vls_mode_p (machine_mode
);
170 extern int riscv_get_v_regno_alignment (machine_mode
);
171 extern bool riscv_shamt_matches_mask_p (int, HOST_WIDE_INT
);
172 extern void riscv_subword_address (rtx
, rtx
*, rtx
*, rtx
*, rtx
*);
173 extern void riscv_lshift_subword (machine_mode
, rtx
, rtx
, rtx
*);
174 extern enum memmodel
riscv_union_memmodels (enum memmodel
, enum memmodel
);
175 extern bool riscv_reg_frame_related (rtx
);
176 extern void riscv_split_sum_of_two_s12 (HOST_WIDE_INT
, HOST_WIDE_INT
*,
178 extern bool riscv_vector_float_type_p (const_tree type
);
179 extern void generate_reflecting_code_using_brev (rtx
*);
180 extern void expand_crc_using_clmul (scalar_mode
, scalar_mode
, rtx
*);
181 extern void expand_reversed_crc_using_clmul (scalar_mode
, scalar_mode
, rtx
*);
183 /* Routines implemented in riscv-c.cc. */
184 void riscv_cpu_cpp_builtins (cpp_reader
*);
185 void riscv_register_pragmas (void);
187 /* Routines implemented in riscv-builtins.cc. */
188 extern void riscv_atomic_assign_expand_fenv (tree
*, tree
*, tree
*);
189 extern bool riscv_gimple_fold_builtin (gimple_stmt_iterator
*);
190 extern rtx
riscv_expand_builtin (tree
, rtx
, rtx
, machine_mode
, int);
191 extern tree
riscv_builtin_decl (unsigned int, bool);
192 extern void riscv_init_builtins (void);
194 /* Routines implemented in riscv-common.cc. */
195 extern std::string
riscv_arch_str (bool version_p
= true);
196 extern void riscv_parse_arch_string (const char *, struct gcc_options
*, location_t
);
198 extern bool riscv_hard_regno_rename_ok (unsigned, unsigned);
200 rtl_opt_pass
* make_pass_shorten_memrefs (gcc::context
*ctxt
);
201 rtl_opt_pass
* make_pass_avlprop (gcc::context
*ctxt
);
202 rtl_opt_pass
* make_pass_vsetvl (gcc::context
*ctxt
);
203 rtl_opt_pass
* make_pass_insert_landing_pad (gcc::context
*ctxt
);
205 /* Routines implemented in riscv-string.c. */
206 extern bool riscv_expand_block_compare (rtx
, rtx
, rtx
, rtx
);
207 extern bool riscv_expand_block_move (rtx
, rtx
, rtx
);
208 extern bool riscv_expand_block_clear (rtx
, rtx
);
210 /* Information about one CPU we know about. */
211 struct riscv_cpu_info
{
212 /* This CPU's canonical name. */
215 /* Default arch for this CPU, could be NULL if no default arch. */
218 /* Which automaton to use for tuning. */
222 extern const riscv_cpu_info
*riscv_find_cpu (const char *);
224 /* Common vector costs in any kind of vectorization (e.g VLA and VLS). */
225 struct common_vector_cost
227 /* Cost of any integer vector operation, excluding the ones handled
229 const int int_stmt_cost
;
231 /* Cost of any fp vector operation, excluding the ones handled
233 const int fp_stmt_cost
;
235 /* Gather/scatter vectorization cost. */
236 const int gather_load_cost
;
237 const int scatter_store_cost
;
239 /* Segment load/store permute cost. */
240 const int segment_permute_2
;
241 const int segment_permute_3
;
242 const int segment_permute_4
;
243 const int segment_permute_5
;
244 const int segment_permute_6
;
245 const int segment_permute_7
;
246 const int segment_permute_8
;
248 /* Cost of a vector-to-scalar operation. */
249 const int vec_to_scalar_cost
;
251 /* Cost of a scalar-to-vector operation. */
252 const int scalar_to_vec_cost
;
254 /* Cost of a permute operation. */
255 const int permute_cost
;
257 /* Cost of an aligned vector load. */
258 const int align_load_cost
;
260 /* Cost of an aligned vector store. */
261 const int align_store_cost
;
263 /* Cost of an unaligned vector load. */
264 const int unalign_load_cost
;
266 /* Cost of an unaligned vector store. */
267 const int unalign_store_cost
;
270 /* scalable vectorization (VLA) specific cost. */
271 struct scalable_vector_cost
: common_vector_cost
273 CONSTEXPR
scalable_vector_cost (const common_vector_cost
&base
)
274 : common_vector_cost (base
)
277 /* TODO: We will need more other kinds of vector cost for VLA.
278 E.g. fold_left reduction cost, lanes load/store cost, ..., etc. */
281 /* Additional costs for register copies. Cost is for one register. */
282 struct regmove_vector_cost
290 /* Cost for vector insn classes. */
291 struct cpu_vector_cost
293 /* Cost of any integer scalar operation, excluding load and store. */
294 const int scalar_int_stmt_cost
;
296 /* Cost of any fp scalar operation, excluding load and store. */
297 const int scalar_fp_stmt_cost
;
299 /* Cost of a scalar load. */
300 const int scalar_load_cost
;
302 /* Cost of a scalar store. */
303 const int scalar_store_cost
;
305 /* Cost of a taken branch. */
306 const int cond_taken_branch_cost
;
308 /* Cost of a not-taken branch. */
309 const int cond_not_taken_branch_cost
;
311 /* Cost of an VLS modes operations. */
312 const common_vector_cost
*vls
;
314 /* Cost of an VLA modes operations. */
315 const scalable_vector_cost
*vla
;
317 /* Cost of vector register move operations. */
318 const regmove_vector_cost
*regmove
;
321 /* Routines implemented in riscv-selftests.cc. */
324 void riscv_run_selftests (void);
325 } // namespace selftest
328 namespace riscv_vector
{
329 #define RVV_VLMAX regno_reg_rtx[X0_REGNUM]
330 #define RVV_VUNDEF(MODE) \
331 gen_rtx_UNSPEC (MODE, gen_rtvec (1, RVV_VLMAX), UNSPEC_VUNDEF)
333 /* These flags describe how to pass the operands to a rvv insn pattern.
335 If a insn has this flags:
336 HAS_DEST_P | HAS_MASK_P | USE_VUNDEF_MERGE_P
337 | TU_POLICY_P | BINARY_OP_P | FRM_DYN_P
339 operands[0] is the dest operand
340 operands[1] is the mask operand
341 operands[2] is the merge operand
342 operands[3] and operands[4] is the two operand to do the operation.
343 operands[5] is the vl operand
344 operands[6] is the tail policy operand
345 operands[7] is the mask policy operands
346 operands[8] is the rounding mode operands
348 Then you can call `emit_vlmax_insn (flags, icode, ops)` to emit a insn.
349 and ops[0] is the dest operand (operands[0]), ops[1] is the mask
350 operand (operands[1]), ops[2] and ops[3] is the two
351 operands (operands[3], operands[4]) to do the operation. Other operands
352 will be created by emit_vlmax_insn according to the flags information.
354 enum insn_flags
: unsigned int
356 /* flags for dest, mask, merge operands. */
357 /* Means INSN has dest operand. False for STORE insn. */
359 /* Means INSN has mask operand. */
361 /* Means using ALL_TRUES for mask operand. */
362 USE_ALL_TRUES_MASK_P
= 1 << 2,
363 /* Means using ONE_TRUE for mask operand. */
364 USE_ONE_TRUE_MASK_P
= 1 << 3,
365 /* Means INSN has merge operand. */
366 HAS_MERGE_P
= 1 << 4,
367 /* Means using VUNDEF for merge operand. */
368 USE_VUNDEF_MERGE_P
= 1 << 5,
370 /* flags for tail policy and mask policy operands. */
371 /* Means the tail policy is TAIL_UNDISTURBED. */
372 TU_POLICY_P
= 1 << 6,
373 /* Means the tail policy is default (return by get_prefer_tail_policy). */
374 TDEFAULT_POLICY_P
= 1 << 7,
375 /* Means the mask policy is MASK_UNDISTURBED. */
376 MU_POLICY_P
= 1 << 8,
377 /* Means the mask policy is default (return by get_prefer_mask_policy). */
378 MDEFAULT_POLICY_P
= 1 << 9,
380 /* flags for the number operands to do the operation. */
381 /* Means INSN need zero operand to do the operation. e.g. vid.v */
382 NULLARY_OP_P
= 1 << 10,
383 /* Means INSN need one operand to do the operation. */
384 UNARY_OP_P
= 1 << 11,
385 /* Means INSN need two operands to do the operation. */
386 BINARY_OP_P
= 1 << 12,
387 /* Means INSN need two operands to do the operation. */
388 TERNARY_OP_P
= 1 << 13,
390 /* flags for get vtype mode from the index number. default from dest operand. */
391 VTYPE_MODE_FROM_OP1_P
= 1 << 14,
393 /* flags for the floating-point rounding mode. */
394 /* Means INSN has FRM operand and the value is FRM_DYN. */
397 /* Means INSN has FRM operand and the value is FRM_RUP. */
400 /* Means INSN has FRM operand and the value is FRM_RDN. */
403 /* Means INSN has FRM operand and the value is FRM_RMM. */
406 /* Means INSN has FRM operand and the value is FRM_RNE. */
409 /* Means INSN has VXRM operand and the value is VXRM_RNU. */
410 VXRM_RNU_P
= 1 << 20,
412 /* Means INSN has VXRM operand and the value is VXRM_RDN. */
413 VXRM_RDN_P
= 1 << 21,
416 enum insn_type
: unsigned int
418 /* some flags macros. */
419 /* For non-mask insn with tama. */
420 __NORMAL_OP
= HAS_DEST_P
| HAS_MASK_P
| USE_ALL_TRUES_MASK_P
| HAS_MERGE_P
421 | USE_VUNDEF_MERGE_P
| TDEFAULT_POLICY_P
| MDEFAULT_POLICY_P
,
422 /* For non-mask insn with ta, without mask policy operand. */
423 __NORMAL_OP_TA
= HAS_DEST_P
| HAS_MASK_P
| USE_ALL_TRUES_MASK_P
| HAS_MERGE_P
424 | USE_VUNDEF_MERGE_P
| TDEFAULT_POLICY_P
,
425 /* For non-mask insn with ta, without mask operand and mask policy operand. */
427 = HAS_DEST_P
| HAS_MERGE_P
| USE_VUNDEF_MERGE_P
| TDEFAULT_POLICY_P
,
428 /* For non-mask insn with ma, without tail policy operand. */
429 __NORMAL_OP_MA
= HAS_DEST_P
| HAS_MASK_P
| USE_ALL_TRUES_MASK_P
| HAS_MERGE_P
430 | USE_VUNDEF_MERGE_P
| MDEFAULT_POLICY_P
,
431 /* For mask insn with tama. */
432 __MASK_OP_TAMA
= HAS_DEST_P
| HAS_MASK_P
| HAS_MERGE_P
| USE_VUNDEF_MERGE_P
433 | TDEFAULT_POLICY_P
| MDEFAULT_POLICY_P
,
434 /* For mask insn with tamu. */
436 = HAS_DEST_P
| HAS_MASK_P
| HAS_MERGE_P
| TDEFAULT_POLICY_P
| MU_POLICY_P
,
437 /* For mask insn with tuma. */
438 __MASK_OP_TUMA
= HAS_DEST_P
| HAS_MASK_P
| USE_ALL_TRUES_MASK_P
| HAS_MERGE_P
439 | TU_POLICY_P
| MDEFAULT_POLICY_P
,
440 /* For mask insn with mu. */
441 __MASK_OP_MU
= HAS_DEST_P
| HAS_MASK_P
| HAS_MERGE_P
| MU_POLICY_P
,
442 /* For mask insn with ta, without mask policy operand. */
443 __MASK_OP_TA
= HAS_DEST_P
| HAS_MASK_P
| HAS_MERGE_P
| USE_VUNDEF_MERGE_P
446 /* Nullary operator. e.g. vid.v */
447 NULLARY_OP
= __NORMAL_OP
| NULLARY_OP_P
,
449 /* Unary operator. */
450 UNARY_OP
= __NORMAL_OP
| UNARY_OP_P
,
451 UNARY_OP_TAMA
= __MASK_OP_TAMA
| UNARY_OP_P
,
452 UNARY_OP_TAMU
= __MASK_OP_TAMU
| UNARY_OP_P
,
453 UNARY_OP_FRM_DYN
= UNARY_OP
| FRM_DYN_P
,
454 UNARY_OP_FRM_RMM
= UNARY_OP
| FRM_RMM_P
,
455 UNARY_OP_FRM_RUP
= UNARY_OP
| FRM_RUP_P
,
456 UNARY_OP_FRM_RDN
= UNARY_OP
| FRM_RDN_P
,
457 UNARY_OP_TAMA_FRM_DYN
= UNARY_OP_TAMA
| FRM_DYN_P
,
458 UNARY_OP_TAMA_FRM_RUP
= UNARY_OP_TAMA
| FRM_RUP_P
,
459 UNARY_OP_TAMA_FRM_RDN
= UNARY_OP_TAMA
| FRM_RDN_P
,
460 UNARY_OP_TAMA_FRM_RMM
= UNARY_OP_TAMA
| FRM_RMM_P
,
461 UNARY_OP_TAMA_FRM_RNE
= UNARY_OP_TAMA
| FRM_RNE_P
,
462 UNARY_OP_TAMU_FRM_DYN
= UNARY_OP_TAMU
| FRM_DYN_P
,
463 UNARY_OP_TAMU_FRM_RUP
= UNARY_OP_TAMU
| FRM_RUP_P
,
464 UNARY_OP_TAMU_FRM_RDN
= UNARY_OP_TAMU
| FRM_RDN_P
,
465 UNARY_OP_TAMU_FRM_RMM
= UNARY_OP_TAMU
| FRM_RMM_P
,
466 UNARY_OP_TAMU_FRM_RNE
= UNARY_OP_TAMU
| FRM_RNE_P
,
468 /* Binary operator. */
469 BINARY_OP
= __NORMAL_OP
| BINARY_OP_P
,
470 BINARY_OP_TAMA
= __MASK_OP_TAMA
| BINARY_OP_P
,
471 BINARY_OP_TAMU
= __MASK_OP_TAMU
| BINARY_OP_P
,
472 BINARY_OP_TUMA
= __MASK_OP_TUMA
| BINARY_OP_P
,
473 BINARY_OP_FRM_DYN
= BINARY_OP
| FRM_DYN_P
,
474 BINARY_OP_VXRM_RNU
= BINARY_OP
| VXRM_RNU_P
,
475 BINARY_OP_VXRM_RDN
= BINARY_OP
| VXRM_RDN_P
,
477 /* Ternary operator. Always have real merge operand. */
478 TERNARY_OP
= HAS_DEST_P
| HAS_MASK_P
| USE_ALL_TRUES_MASK_P
| HAS_MERGE_P
479 | TDEFAULT_POLICY_P
| MDEFAULT_POLICY_P
| TERNARY_OP_P
,
480 TERNARY_OP_FRM_DYN
= TERNARY_OP
| FRM_DYN_P
,
482 /* For vwmacc, no merge operand. */
483 WIDEN_TERNARY_OP
= HAS_DEST_P
| HAS_MASK_P
| USE_ALL_TRUES_MASK_P
484 | TDEFAULT_POLICY_P
| MDEFAULT_POLICY_P
| TERNARY_OP_P
,
485 WIDEN_TERNARY_OP_FRM_DYN
= WIDEN_TERNARY_OP
| FRM_DYN_P
,
487 /* For vmerge, no mask operand, no mask policy operand. */
488 MERGE_OP
= __NORMAL_OP_TA2
| TERNARY_OP_P
,
490 /* For vmerge with TU policy. */
491 MERGE_OP_TU
= HAS_DEST_P
| HAS_MERGE_P
| TERNARY_OP_P
| TU_POLICY_P
,
493 /* For vm<compare>, no tail policy operand. */
494 COMPARE_OP
= __NORMAL_OP_MA
| TERNARY_OP_P
,
495 COMPARE_OP_MU
= __MASK_OP_MU
| TERNARY_OP_P
,
497 /* For scatter insn: no dest operand, no merge operand, no tail and mask
499 SCATTER_OP_M
= HAS_MASK_P
| TERNARY_OP_P
,
501 /* For vcpop.m, no merge operand, no tail and mask policy operands. */
502 CPOP_OP
= HAS_DEST_P
| HAS_MASK_P
| USE_ALL_TRUES_MASK_P
| UNARY_OP_P
503 | VTYPE_MODE_FROM_OP1_P
,
505 /* For mask instructions, no tail and mask policy operands. */
506 UNARY_MASK_OP
= HAS_DEST_P
| HAS_MASK_P
| USE_ALL_TRUES_MASK_P
| HAS_MERGE_P
507 | USE_VUNDEF_MERGE_P
| UNARY_OP_P
,
508 BINARY_MASK_OP
= HAS_DEST_P
| HAS_MASK_P
| USE_ALL_TRUES_MASK_P
| HAS_MERGE_P
509 | USE_VUNDEF_MERGE_P
| BINARY_OP_P
,
511 /* For vcompress.vm */
512 COMPRESS_OP
= __NORMAL_OP_TA2
| BINARY_OP_P
,
513 /* has merge operand but use tu. */
515 = HAS_DEST_P
| HAS_MERGE_P
| TU_POLICY_P
| BINARY_OP_P
,
517 /* For vslideup.up has merge operand but use ta. */
518 SLIDEUP_OP_MERGE
= HAS_DEST_P
| HAS_MASK_P
| USE_ALL_TRUES_MASK_P
519 | HAS_MERGE_P
| TDEFAULT_POLICY_P
| MDEFAULT_POLICY_P
522 /* For vreduce, no mask policy operand. */
523 REDUCE_OP
= __NORMAL_OP_TA
| BINARY_OP_P
| VTYPE_MODE_FROM_OP1_P
,
524 REDUCE_OP_M
= __MASK_OP_TA
| BINARY_OP_P
| VTYPE_MODE_FROM_OP1_P
,
525 REDUCE_OP_FRM_DYN
= REDUCE_OP
| FRM_DYN_P
| VTYPE_MODE_FROM_OP1_P
,
527 = __MASK_OP_TA
| BINARY_OP_P
| FRM_DYN_P
| VTYPE_MODE_FROM_OP1_P
,
529 /* For vmv.s.x/vfmv.s.f. */
530 SCALAR_MOVE_OP
= HAS_DEST_P
| HAS_MASK_P
| USE_ONE_TRUE_MASK_P
| HAS_MERGE_P
531 | USE_VUNDEF_MERGE_P
| TDEFAULT_POLICY_P
| MDEFAULT_POLICY_P
534 SCALAR_MOVE_MERGED_OP
= HAS_DEST_P
| HAS_MASK_P
| USE_ONE_TRUE_MASK_P
535 | HAS_MERGE_P
| TDEFAULT_POLICY_P
| MDEFAULT_POLICY_P
538 SCALAR_MOVE_MERGED_OP_TU
= HAS_DEST_P
| HAS_MASK_P
| USE_ONE_TRUE_MASK_P
539 | HAS_MERGE_P
| TU_POLICY_P
| MDEFAULT_POLICY_P
556 /* The RISC-V vsetvli pass uses "known vlmax" operations for optimization.
557 Whether or not an instruction actually is a vlmax operation is not
558 recognizable from the length operand alone but the avl_type operand
559 is used instead. In general, there are two cases:
561 - Emit a vlmax operation by calling emit_vlmax_insn[_lra]. Here we emit
562 a vsetvli with vlmax configuration and set the avl_type to VLMAX for
563 VLA modes or VLS for VLS modes.
564 - Emit an operation that uses the existing (last-set) length and
565 set the avl_type to NONVLMAX.
567 Sometimes we also need to set the VLMAX or VLS avl_type to an operation that
568 already uses a given length register. This can happen during or after
569 register allocation when we are not allowed to create a new register.
570 For that case we also allow to set the avl_type to VLMAX or VLS.
578 /* Routines implemented in riscv-vector-builtins.cc. */
579 void init_builtins (void);
580 void reinit_builtins (void);
581 const char *mangle_builtin_type (const_tree
);
582 tree
lookup_vector_type_attribute (const_tree
);
583 bool builtin_type_p (const_tree
);
585 bool verify_type_context (location_t
, type_context_kind
, const_tree
, bool);
586 bool expand_vec_perm_const (machine_mode
, machine_mode
, rtx
, rtx
, rtx
,
587 const vec_perm_indices
&);
589 void handle_pragma_vector (void);
590 tree
builtin_decl (unsigned, bool);
591 gimple
*gimple_fold_builtin (unsigned int, gimple_stmt_iterator
*, gcall
*);
592 rtx
expand_builtin (unsigned int, tree
, rtx
);
593 bool check_builtin_call (location_t
, vec
<location_t
>, unsigned int,
594 tree
, unsigned int, tree
*);
595 tree
resolve_overloaded_builtin (location_t
, unsigned int, tree
, vec
<tree
, va_gc
> *);
596 bool const_vec_all_same_in_range_p (rtx
, HOST_WIDE_INT
, HOST_WIDE_INT
);
597 bool legitimize_move (rtx
, rtx
*);
598 void emit_vlmax_vsetvl (machine_mode
, rtx
);
599 void emit_hard_vlmax_vsetvl (machine_mode
, rtx
);
600 void emit_vlmax_insn (unsigned, unsigned, rtx
*);
601 void emit_nonvlmax_insn (unsigned, unsigned, rtx
*, rtx
);
602 void emit_vlmax_insn_lra (unsigned, unsigned, rtx
*, rtx
);
603 enum vlmul_type
get_vlmul (machine_mode
);
604 rtx
get_vlmax_rtx (machine_mode
);
605 unsigned int get_ratio (machine_mode
);
606 unsigned int get_nf (machine_mode
);
607 machine_mode
get_subpart_mode (machine_mode
);
610 int get_avl_type (rtx
);
611 unsigned int calculate_ratio (unsigned int, enum vlmul_type
);
614 TAIL_UNDISTURBED
= 0,
621 MASK_UNDISTURBED
= 0,
626 /* Return true if VALUE is agnostic or any policy. */
627 #define IS_AGNOSTIC(VALUE) (bool) (VALUE & 0x1 || (VALUE >> 1 & 0x1))
629 enum tail_policy
get_prefer_tail_policy ();
630 enum mask_policy
get_prefer_mask_policy ();
631 rtx
get_avl_type_rtx (enum avl_type
);
632 opt_machine_mode
get_lmul_mode (scalar_mode
, int);
633 opt_machine_mode
get_vector_mode (scalar_mode
, poly_uint64
);
634 opt_machine_mode
get_tuple_mode (machine_mode
, unsigned int);
636 bool neg_simm5_p (rtx
);
638 bool has_vi_variant_p (rtx_code
, rtx
);
639 void expand_vec_cmp (rtx
, rtx_code
, rtx
, rtx
, rtx
= nullptr, rtx
= nullptr);
640 bool expand_vec_cmp_float (rtx
, rtx_code
, rtx
, rtx
, bool);
641 void expand_cond_len_unop (unsigned, rtx
*);
642 void expand_cond_len_binop (unsigned, rtx
*);
643 void expand_reduction (unsigned, unsigned, unsigned, rtx
*, rtx
);
644 void expand_vec_ceil (rtx
, rtx
, machine_mode
, machine_mode
);
645 void expand_vec_floor (rtx
, rtx
, machine_mode
, machine_mode
);
646 void expand_vec_nearbyint (rtx
, rtx
, machine_mode
, machine_mode
);
647 void expand_vec_rint (rtx
, rtx
, machine_mode
, machine_mode
);
648 void expand_vec_round (rtx
, rtx
, machine_mode
, machine_mode
);
649 void expand_vec_trunc (rtx
, rtx
, machine_mode
, machine_mode
);
650 void expand_vec_roundeven (rtx
, rtx
, machine_mode
, machine_mode
);
651 void expand_vec_lrint (rtx
, rtx
, machine_mode
, machine_mode
, machine_mode
);
652 void expand_vec_lround (rtx
, rtx
, machine_mode
, machine_mode
, machine_mode
);
653 void expand_vec_lceil (rtx
, rtx
, machine_mode
, machine_mode
);
654 void expand_vec_lfloor (rtx
, rtx
, machine_mode
, machine_mode
);
655 void expand_vec_usadd (rtx
, rtx
, rtx
, machine_mode
);
656 void expand_vec_ssadd (rtx
, rtx
, rtx
, machine_mode
);
657 void expand_vec_ussub (rtx
, rtx
, rtx
, machine_mode
);
658 void expand_vec_sssub (rtx
, rtx
, rtx
, machine_mode
);
659 void expand_vec_double_ustrunc (rtx
, rtx
, machine_mode
);
660 void expand_vec_double_sstrunc (rtx
, rtx
, machine_mode
);
661 void expand_vec_quad_ustrunc (rtx
, rtx
, machine_mode
, machine_mode
);
662 void expand_vec_quad_sstrunc (rtx
, rtx
, machine_mode
, machine_mode
);
663 void expand_vec_oct_ustrunc (rtx
, rtx
, machine_mode
, machine_mode
,
665 void expand_vec_oct_sstrunc (rtx
, rtx
, machine_mode
, machine_mode
,
668 bool sew64_scalar_helper (rtx
*, rtx
*, rtx
, machine_mode
,
669 bool, void (*)(rtx
*, rtx
), enum avl_type
);
670 rtx
gen_scalar_move_mask (machine_mode
);
671 rtx
gen_no_side_effects_vsetvl_rtx (machine_mode
, rtx
, rtx
);
673 /* RVV vector register sizes.
674 TODO: Currently, we only add RVV_32/RVV_64/RVV_128, we may need to
675 support other values in the future. */
682 bool slide1_sew64_helper (int, machine_mode
, machine_mode
,
683 machine_mode
, rtx
*);
684 rtx
gen_avl_for_scalar_move (rtx
);
685 void expand_tuple_move (rtx
*);
686 bool expand_block_move (rtx
, rtx
, rtx
, bool);
687 machine_mode
preferred_simd_mode (scalar_mode
);
688 machine_mode
get_mask_mode (machine_mode
);
689 void expand_vec_series (rtx
, rtx
, rtx
, rtx
= 0);
690 void expand_vec_init (rtx
, rtx
);
691 void expand_vec_perm (rtx
, rtx
, rtx
, rtx
);
692 void expand_select_vl (rtx
*);
693 void expand_load_store (rtx
*, bool);
694 void expand_gather_scatter (rtx
*, bool);
695 void expand_cond_len_ternop (unsigned, rtx
*);
696 void prepare_ternary_operands (rtx
*);
697 void expand_lanes_load_store (rtx
*, bool);
698 void expand_fold_extract_last (rtx
*);
699 void expand_cond_unop (unsigned, rtx
*);
700 void expand_cond_binop (unsigned, rtx
*);
701 void expand_cond_ternop (unsigned, rtx
*);
702 void expand_popcount (rtx
*);
703 void expand_rawmemchr (machine_mode
, rtx
, rtx
, rtx
, bool = false);
704 bool expand_strcmp (rtx
, rtx
, rtx
, rtx
, unsigned HOST_WIDE_INT
, bool);
705 void emit_vec_extract (rtx
, rtx
, rtx
);
706 bool expand_vec_setmem (rtx
, rtx
, rtx
);
707 bool expand_vec_cmpmem (rtx
, rtx
, rtx
, rtx
);
708 void expand_strided_load (machine_mode
, rtx
*);
709 void expand_strided_store (machine_mode
, rtx
*);
711 /* Rounding mode bitfield for fixed point VXRM. */
712 enum fixed_point_rounding_mode
720 /* Rounding mode bitfield for floating point FRM. The value of enum comes
722 https://github.com/riscv/riscv-isa-manual/blob/main/src/f-st-ext.adoc#floating-point-control-and-status-register
724 enum floating_point_rounding_mode
726 FRM_RNE
= 0, /* Aka 0b000. */
727 FRM_RTZ
= 1, /* Aka 0b001. */
728 FRM_RDN
= 2, /* Aka 0b010. */
729 FRM_RUP
= 3, /* Aka 0b011. */
730 FRM_RMM
= 4, /* Aka 0b100. */
731 FRM_DYN
= 7, /* Aka 0b111. */
732 FRM_STATIC_MIN
= FRM_RNE
,
733 FRM_STATIC_MAX
= FRM_RMM
,
739 enum floating_point_rounding_mode
get_frm_mode (rtx
);
740 opt_machine_mode
vectorize_related_mode (machine_mode
, scalar_mode
,
742 unsigned int autovectorize_vector_modes (vec
<machine_mode
> *, bool);
743 bool cmp_lmul_le_one (machine_mode
);
744 bool cmp_lmul_gt_one (machine_mode
);
745 bool vls_mode_valid_p (machine_mode
);
746 bool vlmax_avl_type_p (rtx_insn
*);
747 bool has_vl_op (rtx_insn
*);
748 bool tail_agnostic_p (rtx_insn
*);
749 void validate_change_or_fail (rtx
, rtx
*, rtx
, bool);
750 bool nonvlmax_avl_type_p (rtx_insn
*);
751 bool vlmax_avl_p (rtx
);
752 uint8_t get_sew (rtx_insn
*);
753 enum vlmul_type
get_vlmul (rtx_insn
*);
754 int count_regno_occurrences (rtx_insn
*, unsigned int);
755 bool imm_avl_p (machine_mode
);
756 bool can_be_broadcasted_p (rtx
);
757 bool gather_scatter_valid_offset_p (machine_mode
);
758 HOST_WIDE_INT
estimated_poly_value (poly_int64
, unsigned int);
759 bool whole_reg_to_reg_move_p (rtx
*, machine_mode
, int);
760 bool splat_to_scalar_move_p (rtx
*);
761 rtx
get_fp_rounding_coefficient (machine_mode
);
764 /* We classify builtin types into two classes:
765 1. General builtin class which is defined in riscv_builtins.
766 2. Vector builtin class which is a special builtin architecture
767 that implement intrinsic short into "pragma". */
768 enum riscv_builtin_class
770 RISCV_BUILTIN_GENERAL
,
774 const unsigned int RISCV_BUILTIN_SHIFT
= 1;
776 /* Mask that selects the riscv_builtin_class part of a function code. */
777 const unsigned int RISCV_BUILTIN_CLASS
= (1 << RISCV_BUILTIN_SHIFT
) - 1;
779 /* Routines implemented in riscv-string.cc. */
780 extern bool riscv_expand_strcmp (rtx
, rtx
, rtx
, rtx
, rtx
);
781 extern bool riscv_expand_strlen (rtx
, rtx
, rtx
, rtx
);
783 /* Routines implemented in thead.cc. */
784 extern bool extract_base_offset_in_addr (rtx
, rtx
*, rtx
*);
785 extern bool th_mempair_operands_p (rtx
[4], bool, machine_mode
);
786 extern void th_mempair_order_operands (rtx
[4], bool, machine_mode
);
787 extern void th_mempair_prepare_save_restore_operands (rtx
[4], bool,
791 extern void th_mempair_save_restore_regs (rtx
[4], bool, machine_mode
);
792 extern unsigned int th_int_get_mask (unsigned int);
793 extern unsigned int th_int_get_save_adjustment (void);
794 extern rtx
th_int_adjust_cfi_prologue (unsigned int);
795 extern const char *th_asm_output_opcode (FILE *asm_out_file
, const char *p
);
798 th_mempair_output_move (rtx
[4], bool, machine_mode
, RTX_CODE
);
799 extern bool th_memidx_legitimate_modify_p (rtx
);
800 extern bool th_memidx_legitimate_modify_p (rtx
, bool);
801 extern bool th_memidx_legitimate_index_p (rtx
);
802 extern bool th_memidx_legitimate_index_p (rtx
, bool);
803 extern bool th_classify_address (struct riscv_address_info
*,
804 rtx
, machine_mode
, bool);
805 extern const char *th_output_move (rtx
, rtx
);
806 extern bool th_print_operand_address (FILE *, machine_mode
, rtx
);
809 extern bool riscv_use_divmod_expander (void);
810 void riscv_init_cumulative_args (CUMULATIVE_ARGS
*, tree
, rtx
, tree
, int);
812 riscv_option_valid_attribute_p (tree
, tree
, tree
, int);
814 riscv_option_valid_version_attribute_p (tree
, tree
, tree
, int);
816 riscv_process_target_version_attr (tree
, location_t
);
818 riscv_override_options_internal (struct gcc_options
*);
819 extern void riscv_option_override (void);
821 struct riscv_tune_param
;
822 /* Information about one micro-arch we know about. */
823 struct riscv_tune_info
{
824 /* This micro-arch canonical name. */
827 /* Which automaton to use for tuning. */
828 enum riscv_microarchitecture_type microarchitecture
;
830 /* Tuning parameters for this micro-arch. */
831 const struct riscv_tune_param
*tune_param
;
834 const struct riscv_tune_info
*
835 riscv_parse_tune (const char *, bool);
836 const cpu_vector_cost
*get_vector_costs ();
840 RISCV_MAJOR_VERSION_BASE
= 1000000,
841 RISCV_MINOR_VERSION_BASE
= 1000,
842 RISCV_REVISION_VERSION_BASE
= 1,
845 #endif /* ! GCC_RISCV_PROTOS_H */