O > diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h > index c0293a306f9..e8a728ae226 100644 > --- a/gcc/config/riscv/riscv-protos.h > +++ b/gcc/config/riscv/riscv-protos.h > @@ -219,6 +219,7 @@ rtx gen_avl_for_scalar_move (rtx); > void expand_tuple_move (machine_mode, rtx *); > machine_mode preferred_simd_mode (scalar_mode); > opt_machine_mode get_mask_mode (machine_mode); > +void expand_vec_series (rtx, rtx, rtx); > } > > /* We classify builtin types into two classes: > diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc > index 7ca49ca67c1..0c3b1b4c40b 100644 > --- a/gcc/config/riscv/riscv-v.cc > +++ b/gcc/config/riscv/riscv-v.cc > @@ -248,6 +248,111 @@ emit_nonvlmax_op (unsigned icode, rtx dest, rtx src, > rtx len, > emit_pred_op (icode, NULL_RTX, dest, src, len, mask_mode, false); > } > > +/* Emit binary operations. */ > + > +static void > +emit_binop (unsigned icode, rtx *ops, machine_mode mask_mode, > + machine_mode scalar_mode) > +{ > + insn_expander<9> e; > + machine_mode mode = GET_MODE (ops[0]); > + e.add_output_operand (ops[0], mode); > + e.add_all_one_mask_operand (mask_mode); > + e.add_vundef_operand (mode); > + if (VECTOR_MODE_P (GET_MODE (ops[1]))) > + e.add_input_operand (ops[1], GET_MODE (ops[1])); > + else > + e.add_input_operand (ops[1], scalar_mode); > + if (VECTOR_MODE_P (GET_MODE (ops[2]))) > + e.add_input_operand (ops[2], GET_MODE (ops[2])); > + else > + e.add_input_operand (ops[2], scalar_mode); > + rtx vlmax = gen_reg_rtx (Pmode); > + emit_vlmax_vsetvl (mode, vlmax); > + e.add_input_operand (vlmax, Pmode); > + e.add_policy_operand (get_prefer_tail_policy (), get_prefer_mask_policy > ()); > + e.add_avl_type_operand (avl_type::VLMAX); > + e.expand ((enum insn_code) icode, false); > +} > + > +/* Emit vid.v instruction. */ > + > +static void > +emit_indexop (rtx target, machine_mode mask_mode)
nit: rename to emit_index_op > +void > +expand_vec_series (rtx dest, rtx base, rtx step) > +{ > + machine_mode mode = GET_MODE (dest); > + machine_mode inner_mode = GET_MODE_INNER (mode); > + machine_mode mask_mode; > + gcc_assert (get_mask_mode (mode).exists (&mask_mode)); > + > + /* VECT_IV = BASE + I * STEP. */ > + > + /* Step 1: Generate I = { 0, 1, 2, ... } by vid.v. */ > + rtx tmp = gen_reg_rtx (mode); > + emit_indexop (tmp, mask_mode); > + if (rtx_equal_p (step, const1_rtx) && rtx_equal_p (base, const0_rtx)) > + { > + emit_move_insn (dest, tmp); > + return; > + } > + > + /* Step 2: Generate I * STEP. > + - STEP is 1, we don't emit any instructions. > + - STEP is power of 2, we use vsll.vi/vsll.vx. > + - STEP is non-power of 2, we use vmul.vx. */ The comment seems mismatch the structure of the code, I am prefer to restructure the code to match the comment. > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/series-1.c > b/gcc/testsuite/gcc.target/riscv/rvv/autovec/series-1.c > new file mode 100644 > index 00000000000..a01f6ce7411 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/series-1.c > @@ -0,0 +1,50 @@ > +/* { dg-do compile } */ > +/* { dg-options "-march=rv32gcv -mabi=ilp32d --param > riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m4" } */ > + > +#include <stdint.h> Use stdint-gcc.h instead