not be considered by the prologue and epilogue. */
bool reg_is_wrapped_separately[FIRST_PSEUDO_REGISTER];
+ /* The RTL variable which stores the dynamic FRM value. We always use this
+ RTX to restore dynamic FRM rounding mode in mode switching. */
+ rtx dynamic_frm;
};
/* Information about a single argument. */
return TYPE_ALIGN (type);
}
+/* Return true if it is static FRM rounding mode. */
+
+static bool
+riscv_static_frm_mode_p (int mode)
+{
+ switch (mode)
+ {
+ case FRM_MODE_RDN:
+ case FRM_MODE_RUP:
+ case FRM_MODE_RTZ:
+ case FRM_MODE_RMM:
+ case FRM_MODE_RNE:
+ return true;
+ default:
+ return false;
+ }
+
+ gcc_unreachable ();
+}
+
+/* Implement the floating-point Mode Switching. */
+
+static void
+riscv_emit_frm_mode_set (int mode, int prev_mode)
+{
+ if (mode != prev_mode)
+ {
+ rtx backup_reg = cfun->machine->dynamic_frm;
+ /* TODO: By design, FRM_MODE_xxx used by mode switch which is
+ different from the FRM value like FRM_RTZ defined in
+ riscv-protos.h. When mode switching we actually need a conversion
+ function to convert the mode of mode switching to the actual
+ FRM value like FRM_RTZ. For now, the value between the mode of
+ mode swith and the FRM value in riscv-protos.h take the same value,
+ and then we leverage this assumption when emit. */
+ rtx frm = gen_int_mode (mode, SImode);
+
+ if (mode == FRM_MODE_DYN_EXIT && prev_mode != FRM_MODE_DYN)
+ /* No need to emit when prev mode is DYN already. */
+ emit_insn (gen_fsrmsi_restore_exit (backup_reg));
+ else if (mode == FRM_MODE_DYN)
+ /* Restore frm value from backup when switch to DYN mode. */
+ emit_insn (gen_fsrmsi_restore (backup_reg));
+ else if (riscv_static_frm_mode_p (mode))
+ /* Set frm value when switch to static mode. */
+ emit_insn (gen_fsrmsi_restore (frm));
+ }
+}
+
/* Implement Mode switching. */
static void
emit_insn (gen_vxrmsi (gen_int_mode (mode, SImode)));
break;
case RISCV_FRM:
- /* Switching to the dynamic rounding mode is not necessary. When an
- instruction requests it, it effectively uses the rounding mode already
- set in the FRM register. All other rounding modes require us to
- switch the rounding mode via the FRM register. */
- if (mode != FRM_MODE_DYN && mode != prev_mode)
- {
- /* TODO: By design, FRM_MODE_xxx used by mode switch which is
- different from the FRM value like FRM_RTZ defined in
- riscv-protos.h. When mode switching we actually need a conversion
- function to convert the mode of mode switching to the actual
- FRM value like FRM_RTZ. For now, the value between the mode of
- mode swith and the FRM value in riscv-protos.h take the same value,
- and then we leverage this assumption when emit. */
- rtx scaler = gen_reg_rtx (SImode);
- rtx imm = gen_int_mode (mode, SImode);
-
- emit_insn (gen_movsi (scaler, imm));
- emit_insn (gen_fsrm (scaler, scaler));
- }
+ riscv_emit_frm_mode_set (mode, prev_mode);
break;
default:
gcc_unreachable ();
case RISCV_VXRM:
return code >= 0 ? get_attr_vxrm_mode (insn) : VXRM_MODE_NONE;
case RISCV_FRM:
- /* TODO: Here we may return FRM_MODE_NONE from get_attr_frm_mode, as well
- as FRM_MODE_DYN as default. It is kind of inconsistent and we will
- take care of it after dynamic rounding mode. */
- return code >= 0 ? get_attr_frm_mode (insn) : FRM_MODE_DYN;
+ return code >= 0 ? get_attr_frm_mode (insn) : FRM_MODE_NONE;
default:
gcc_unreachable ();
}
case RISCV_VXRM:
return VXRM_MODE_NONE;
case RISCV_FRM:
- /* According to RVV 1.0 spec, all vector floating-point operations use
- the dynamic rounding mode in the frm register. Likewise in other
- similar places. */
- return FRM_MODE_DYN;
+ {
+ if (!cfun->machine->dynamic_frm)
+ {
+ cfun->machine->dynamic_frm = gen_reg_rtx (SImode);
+ emit_insn_at_entry (gen_frrmsi (cfun->machine->dynamic_frm));
+ }
+
+ /* According to RVV 1.0 spec, all vector floating-point operations use
+ the dynamic rounding mode in the frm register. Likewise in other
+ similar places. */
+ return FRM_MODE_DYN;
+ }
default:
gcc_unreachable ();
}
case RISCV_VXRM:
return VXRM_MODE_NONE;
case RISCV_FRM:
- return FRM_MODE_DYN;
+ return FRM_MODE_DYN_EXIT;
default:
gcc_unreachable ();
}
mtc,mfc,const,arith,logical,shift,slt,imul,idiv,move,fmove,fadd,fmul,
fmadd,fdiv,fcmp,fcvt,fsqrt,multi,auipc,sfb_alu,nop,ghost,bitmanip,rotate,
clmul,min,max,minu,maxu,clz,ctz,cpop,
- atomic,condmove,crypto,rdvlenb,rdvl,wrvxrm,wrfrm,vsetvl,
+ atomic,condmove,crypto,rdvlenb,rdvl,wrvxrm,wrfrm,rdfrm,vsetvl,
vlde,vste,vldm,vstm,vlds,vsts,
vldux,vldox,vstux,vstox,vldff,vldr,vstr,
vlsegde,vssegte,vlsegds,vssegts,vlsegdux,vlsegdox,vssegtux,vssegtox,vlsegdff,
UNSPEC_VCOMPRESS
UNSPEC_VLEFF
UNSPEC_MODIFY_VL
+])
- UNSPEC_FSRM
+(define_c_enum "unspecv" [
+ UNSPECV_FRM_RESTORE_EXIT
])
(define_mode_iterator V [
)
;; Defines rounding mode of an floating-point operation.
-(define_attr "frm_mode" "rne,rtz,rdn,rup,rmm,dyn,none"
+(define_attr "frm_mode" "rne,rtz,rdn,rup,rmm,dyn,dyn_exit,none"
(cond
[
(eq_attr "type" "vfalu")
(set_attr "mode" "SI")])
;; Set FRM
-(define_insn "fsrm"
- [
- (set
- (reg:SI FRM_REGNUM)
- (unspec:SI
- [
- (match_operand:SI 0 "register_operand" "=&r")
- (match_operand:SI 1 "register_operand" "r")
- ] UNSPEC_FSRM
- )
- )
- ]
+(define_insn "fsrmsi_backup"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (reg:SI FRM_REGNUM))
+ (set (reg:SI FRM_REGNUM)
+ (match_operand:SI 1 "reg_or_int_operand" "r,i"))]
+ "TARGET_VECTOR"
+ "@
+ fsrm\t%0,%1
+ fsrmi\t%0,%1"
+ [(set_attr "type" "wrfrm,wrfrm")
+ (set_attr "mode" "SI")]
+)
+
+(define_insn "fsrmsi_restore"
+ [(set (reg:SI FRM_REGNUM)
+ (match_operand:SI 0 "reg_or_int_operand" "r,i"))]
"TARGET_VECTOR"
- "fsrm\t%0,%1"
- [
- (set_attr "type" "wrfrm")
- (set_attr "mode" "SI")
- ]
+ "@
+ fsrm\t%0
+ fsrmi\t%0"
+ [(set_attr "type" "wrfrm,wrfrm")
+ (set_attr "mode" "SI")]
+ )
+
+;; The volatile fsrmsi restore is used for the exit point for the
+;; dynamic mode switching. It will generate one volatile fsrm a5
+;; which won't be eliminated.
+(define_insn "fsrmsi_restore_exit"
+ [(set (reg:SI FRM_REGNUM)
+ (unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
+ UNSPECV_FRM_RESTORE_EXIT))]
+ "TARGET_VECTOR"
+ "fsrm\t%0"
+ [(set_attr "type" "wrfrm")
+ (set_attr "mode" "SI")]
+)
+
+;; Read FRM
+(define_insn "frrmsi"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (reg:SI FRM_REGNUM))]
+ "TARGET_VECTOR"
+ "frrm\t%0"
+ [(set_attr "type" "rdfrm")
+ (set_attr "mode" "SI")]
)
;; -----------------------------------------------------------------
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl)
+{
+ vfloat32m1_t result;
+
+ result = __riscv_vfadd_vv_f32m1 (op1, op2, vl);
+ result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+
+ return result;
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 2 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[01234]} } } */
+/* { dg-final { scan-assembler-not {fsrm\s+[axs][0-9]+} } } */
+/* { dg-final { scan-assembler-not {frrm\s+[axs][0-9]+} } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+ int count, size_t vl)
+{
+ vfloat32m1_t result = op1;
+
+ for (int i = 0; i < count; i++)
+ {
+ result = __riscv_vfadd_vv_f32m1 (result, op2, vl);
+ result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl);
+ result = __riscv_vfadd_vv_f32m1_rm (result, op2, 3, vl);
+ }
+
+ return result;
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+ int count, size_t vl)
+{
+ vfloat32m1_t result = op1;
+
+ for (int i = 0; i < count; i++)
+ {
+ result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl);
+ result = __riscv_vfadd_vv_f32m1_rm (result, op2, 3, vl);
+ result = __riscv_vfadd_vv_f32m1 (result, op2, vl);
+ }
+
+ return result;
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+ int count, size_t vl)
+{
+ vfloat32m1_t result = op1;
+
+ for (int i = 0; i < count; i++)
+ {
+ result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl);
+
+ if (i % 2 == 0)
+ result = __riscv_vfadd_vv_f32m1_rm (result, op2, 3, vl);
+
+ result = __riscv_vfadd_vv_f32m1 (result, op2, vl);
+ }
+
+ return result;
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 4 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+ int count, size_t vl)
+{
+ vfloat32m1_t result = op1;
+
+ for (int i = 0; i < count; i++)
+ {
+ result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl);
+
+ if (i % 2 == 0)
+ result = __riscv_vfadd_vv_f32m1 (result, op2, vl);
+
+ result = __riscv_vfadd_vv_f32m1_rm (result, op2, 3, vl);
+ }
+
+ return result;
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 4 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 3 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+ int count, size_t vl)
+{
+ vfloat32m1_t result = op1;
+
+ for (int i = 0; i < count; i++)
+ {
+ result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl);
+ result = __riscv_vfadd_vv_f32m1_rm (result, op2, 3, vl);
+
+ if (i % 2 == 0)
+ result = __riscv_vfadd_vv_f32m1 (result, op2, vl);
+ }
+
+ return result;
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+ int count, size_t vl)
+{
+ vfloat32m1_t result = op1;
+
+ for (int i = 0; i < count; i++)
+ {
+ result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl);
+ result = __riscv_vfadd_vv_f32m1 (result, op2, vl);
+
+ if (i % 2 == 0)
+ result = __riscv_vfadd_vv_f32m1_rm (result, op2, 3, vl);
+ }
+
+ return result;
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl)
+{
+ vfloat32m1_t result = op1;
+
+ result = __riscv_vfadd_vv_f32m1 (result, op2, vl);
+ result = __riscv_vfadd_vv_f32m1_rm (op1, result, 2, vl);
+ result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+
+ return result;
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl)
+{
+ vfloat32m1_t result = op1;
+
+ result = __riscv_vfadd_vv_f32m1_rm (op1, result, 2, vl);
+ result = __riscv_vfadd_vv_f32m1 (result, op2, vl);
+ result = __riscv_vfadd_vv_f32m1_rm (op1, result, 3, vl);
+
+ return result;
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl)
+{
+ vfloat32m1_t result = op1;
+
+ result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+
+ if (vl % 4 == 0)
+ result = __riscv_vfadd_vv_f32m1_rm(op1, result, 2, vl);
+
+ result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+
+ return result;
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl)
+{
+ vfloat32m1_t result = op1;
+
+ result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+
+ if (vl % 4 == 0)
+ result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+
+ result = __riscv_vfadd_vv_f32m1_rm(op1, result, 2, vl);
+
+ return result;
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl)
+{
+ vfloat32m1_t result = op1;
+
+ result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl);
+
+ return __riscv_vfadd_vv_f32m1 (result, op2, vl);
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl)
+{
+ vfloat32m1_t result = op1;
+
+ result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+
+ if (vl % 4 == 0)
+ result = __riscv_vfadd_vv_f32m1_rm(op1, result, 2, vl);
+ else
+ result = __riscv_vfadd_vv_f32m1_rm(op2, result, 2, vl);
+
+ result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+
+ return result;
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 5 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl)
+{
+ vfloat32m1_t result = op1;
+
+ result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+
+ if (vl % 4 == 0)
+ result = __riscv_vfadd_vv_f32m1_rm(op1, result, 2, vl);
+ else
+ result = __riscv_vfadd_vv_f32m1_rm(op2, result, 3, vl);
+
+ result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+
+ return result;
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 5 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl)
+{
+ vfloat32m1_t result = op1;
+
+ result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+
+ if (vl % 4 == 0)
+ result = __riscv_vfadd_vv_f32m1_rm(op1, result, 4, vl);
+ else
+ result = __riscv_vfadd_vv_f32m1_rm(op2, result, 3, vl);
+
+ return result;
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl)
+{
+ vfloat32m1_t result = op1;
+
+ result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+
+ if (vl % 4 == 0)
+ result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+ else
+ result = __riscv_vfadd_vv_f32m1_rm(op2, result, 3, vl);
+
+ return result;
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
--- /dev/null
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+void
+test_float_point_dynamic_frm (vfloat32m1_t *out, vfloat32m1_t op1, size_t vl)
+{
+}
+
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[01234]} } } */
+/* { dg-final { scan-assembler-not {fsrm\s+[axs][0-9]+} } } */
+/* { dg-final { scan-assembler-not {frrm\s+[axs][0-9]+} } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+void
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl,
+ float *out)
+{
+ vfloat32m1_t result = __riscv_vfadd_vv_f32m1 (op1, op2, vl);
+
+ if (vl % 4 == 0)
+ {
+ result = __riscv_vfadd_vv_f32m1_rm (op1, result, 4, vl);
+ *(vfloat32m1_t *) out = result;
+ }
+ else
+ {
+ result = __riscv_vfadd_vv_f32m1_rm (op2, result, 3, vl);
+ *(vfloat32m1_t *) out = result;
+ }
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+void
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl,
+ float *out)
+{
+ vfloat32m1_t result = __riscv_vfadd_vv_f32m1 (op1, op2, vl);
+
+ if (vl % 4 == 0)
+ {
+ result = __riscv_vfadd_vv_f32m1_rm (op1, result, 4, vl);
+ *(vfloat32m1_t *) out = result;
+ }
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+void
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl,
+ float *out)
+{
+ vfloat32m1_t result = op1;
+
+ result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+
+ if (vl % 4 == 0)
+ {
+ result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+ *(vfloat32m1_t *) out = result;
+ }
+ else
+ {
+ result = __riscv_vfadd_vv_f32m1 (op2, result, vl);
+ *(vfloat32m1_t *) (out + 16) = result;
+ }
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */
+/* { dg-final { scan-assembler-not {frrm\s+[axs][0-9]+} } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[01234]} } } */
+/* { dg-final { scan-assembler-not {fsrm\s+[axs][0-9]+} } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+void
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl,
+ float *out)
+{
+ vfloat32m1_t result = op1;
+
+ result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+
+ if (vl % 4 == 0)
+ {
+ result = __riscv_vfadd_vv_f32m1_rm (op1, result, 4, vl);
+ *(vfloat32m1_t *) out = result;
+ }
+ else
+ {
+ result = __riscv_vfadd_vv_f32m1_rm (op2, result, 3, vl);
+ *(vfloat32m1_t *) (out + 16) = result;
+ }
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+void
+test_float_point_dynamic_frm (float *in, float *out, int n, size_t vl)
+{
+ for (int i = 0; i < n; i++)
+ {
+ vfloat32m1_t v = __riscv_vle32_v_f32m1 (in + i, vl);
+ vfloat32m1_t result = __riscv_vfadd_vv_f32m1_rm (v, v, 4, vl);
+ __riscv_vse32_v_f32m1 (out + i, result, vl);
+ }
+
+ for (int i = 0; i < n; i++)
+ {
+ vfloat32m1_t v = __riscv_vle32_v_f32m1 (in + i + 100, vl);
+ vfloat32m1_t result = __riscv_vfadd_vv_f32m1_rm (v, v, 3, vl);
+ __riscv_vse32_v_f32m1 (out + i + 100, result, vl);
+ }
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl)
+{
+ vfloat32m1_t result = op1;
+
+ result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl);
+ result = __riscv_vfadd_vv_f32m1_rm (op1, result, 2, vl);
+
+ return result;
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+void
+test_float_point_dynamic_frm (float *in, float *out, int n, int cond, size_t vl)
+{
+ for (int i = 0; i < n; i++)
+ {
+ if (cond)
+ {
+ vfloat32m1_t v = __riscv_vle32_v_f32m1 (in + i + 100, vl);
+ vfloat32m1_t result = __riscv_vfadd_vv_f32m1_rm (v, v, 3, vl);
+ __riscv_vse32_v_f32m1 (out + i + 100, result, vl);
+ }
+ else
+ {
+ vfloat32m1_t v = __riscv_vle32_v_f32m1 (in + i + 200, vl);
+ vfloat32m1_t result = __riscv_vfadd_vv_f32m1_rm (v, v, 3, vl);
+ __riscv_vse32_v_f32m1 (out + i + 200, result, vl);
+ }
+ }
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+void
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl,
+ int n, float *out)
+{
+ vfloat32m1_t result = __riscv_vfadd_vv_f32m1 (op1, op2, vl);
+
+ if (vl % 4 == 0)
+ {
+ result = __riscv_vfadd_vv_f32m1_rm (op1, result, 4, vl);
+ *(vfloat32m1_t *) out = result;
+ }
+
+ if (n > 0)
+ {
+ result = __riscv_vfadd_vv_f32m1 (op2, result, vl);
+ *(vfloat32m1_t *) (out + 100) = result;
+ }
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+size_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, int count,
+ size_t vl, float *out)
+{
+ vfloat32m1_t result = op1;
+
+ if (count == 0)
+ {
+ result = __riscv_vfadd_vv_f32m1_rm (result, op2, 4, vl);
+ *(vfloat32m1_t *) out = result;
+ }
+
+ return vl;
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl)
+{
+ vfloat32m1_t result = op1;
+
+ if (vl % 4 == 0)
+ result = __riscv_vfadd_vv_f32m1_rm (result, op2, 2, vl);
+
+ return result;
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl)
+{
+ vfloat32m1_t result = op1;
+
+ if (vl % 4 == 0)
+ result = __riscv_vfadd_vv_f32m1 (result, op2, vl);
+
+ return result;
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 1 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[01234]} } } */
+/* { dg-final { scan-assembler-not {fsrm\s+[axs][0-9]+} } } */
+/* { dg-final { scan-assembler-not {frrm\s+[axs][0-9]+} } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+ int count, size_t vl)
+{
+ vfloat32m1_t result = op1;
+
+ for (int i = 0; i < count; i++)
+ {
+ if (i % 2 == 0)
+ result = __riscv_vfadd_vv_f32m1_rm (result, op2, 2, vl);
+ else
+ result = __riscv_vfadd_vv_f32m1_rm (result, op2, 3, vl);
+ }
+
+ return result;
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+ int count, size_t vl)
+{
+ vfloat32m1_t result = op1;
+
+ for (int i = 0; i < count; i++)
+ {
+ if (i % 2 == 0)
+ result = __riscv_vfadd_vv_f32m1_rm (result, op2, 4, vl);
+ else
+ result = __riscv_vfadd_vv_f32m1 (result, op2, vl);
+ }
+
+ return result;
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+ int count, size_t vl)
+{
+ vfloat32m1_t result = op1;
+
+ for (int i = 0; i < count; i++)
+ {
+ result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl);
+ result = __riscv_vfadd_vv_f32m1_rm (result, op2, 2, vl);
+ result = __riscv_vfadd_vv_f32m1_rm (result, op2, 3, vl);
+ }
+
+ return result;
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[asx][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 3 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[asx][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[asx][0-9]+,\s*[01234]} } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+ int count, size_t vl)
+{
+ vfloat32m1_t result = op1;
+
+ for (int i = 0; i < count; i++)
+ {
+ result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl);
+ result = __riscv_vfadd_vv_f32m1 (result, op2, vl);
+ result = __riscv_vfadd_vv_f32m1_rm (result, op2, 3, vl);
+ }
+
+ return result;
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
}
/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 4 } } */
-/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 4 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 4 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 4 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 4 } } */
}
/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 2 } } */
-/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */
}
/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v+[0-9]+} 2 } } */
-/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */
}
/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v+[0-9]+} 2 } } */
-/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */
}
/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v+[0-9]+} 4 } } */
-/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */
}
/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v+[0-9]+} 4 } } */
-/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 3 } } */
}
/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 4 } } */
-/* { dg-final { scan-assembler-not {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} } } */
+/* { dg-final { scan-assembler-not {fsrm\s+[axs][0-9]+} } } */
+/* { dg-final { scan-assembler-not {frrm\s+[axs][0-9]+} } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[01234]} } } */
}
/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 2 } } */
-/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */
}
/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 1 } } */
-/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */
}
/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 2 } } */
-/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 3 } } */
vfloat32m1_t __attribute__ ((noinline))
test_float_point_frm_run (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl)
{
- set_frm (0);
-
vfloat32m1_t result;
result = __riscv_vfadd_vv_f32m1_rm (op1, result, 1, vl);
vfloat32m1_t op1;
vfloat32m1_t op2;
+ set_frm (4);
test_float_point_frm_run (op1, op2, vl);
+ assert_equal (4, get_frm (), "The value of frm register should be 4.");
+
return 0;
}
vfloat32m1_t __attribute__ ((noinline))
test_float_point_frm_run (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl)
{
- set_frm (0);
-
vfloat32m1_t result = {};
result = __riscv_vfadd_vv_f32m1_rm (op1, result, 1, vl);
vfloat32m1_t op1 = {};
vfloat32m1_t op2 = {};
+ set_frm (2);
test_float_point_frm_run (op1, op2, vl);
+ assert_equal (2, get_frm (), "The value of frm register should be 2.");
+
return 0;
}
vfloat32m1_t __attribute__ ((noinline))
test_float_point_frm_run (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl)
{
- set_frm (0);
-
vfloat32m1_t result = {};
result = __riscv_vfadd_vv_f32m1_rm (op1, result, 4, vl);
+ assert_equal (4, get_frm (), "The value of frm register should be 4.");
+
result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
- assert_equal (4, get_frm (), "The value of frm register should be 4.");
-
return result;
}
vfloat32m1_t op1 = {};
vfloat32m1_t op2 = {};
+ set_frm (0);
test_float_point_frm_run (op1, op2, vl);
+ assert_equal (0, get_frm (), "The value of frm register should be 0.");
+
return 0;
}