]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
RISC-V: Add FRM and rounding mode operand into floating point intrinsics
authorJuzhe-Zhong <juzhe.zhong@rivai.ai>
Tue, 16 May 2023 03:30:20 +0000 (11:30 +0800)
committerPan Li <pan2.li@intel.com>
Tue, 16 May 2023 03:30:20 +0000 (11:30 +0800)
This patch is adding rounding mode operand and FRM_REGNUM dependency
into floating-point instructions.

The floating-point instructions we added FRM and rounding mode operand:
1. vfadd/vfsub
2. vfwadd/vfwsub
3. vfmul
4. vfdiv
5. vfwmul
6. vfwmacc/vfwnmacc/vfwmsac/vfwnmsac
7. vfsqrt
8. floating-point conversions.
9. floating-point reductions.
10. floating-point ternary.

The floating-point instructions we did NOT add FRM and rounding mode
operand:
1. vfabs/vfneg/vfsqrt7/vfrec7
2. vfmin/vfmax
3. comparisons
4. vfclass
5. vfsgnj/vfsgnjn/vfsgnjx
6. vfmerge
7. vfmv.v.f

gcc/ChangeLog:

* config/riscv/riscv-protos.h (enum frm_field_enum): New enum.
* config/riscv/riscv-vector-builtins.cc
(function_expander::use_ternop_insn): Add default rounding mode.
(function_expander::use_widen_ternop_insn): Ditto.
* config/riscv/riscv.cc (riscv_hard_regno_nregs): Add FRM REGNUM.
(riscv_hard_regno_mode_ok): Ditto.
(riscv_conditional_register_usage): Ditto.
* config/riscv/riscv.h (DWARF_FRAME_REGNUM): Ditto.
(FRM_REG_P): Ditto.
(RISCV_DWARF_FRM): Ditto.
* config/riscv/riscv.md: Ditto.
* config/riscv/vector-iterators.md: split no frm and has frm operations.
* config/riscv/vector.md (@pred_<optab><mode>_scalar): New pattern.
(@pred_<optab><mode>): Ditto.

Signed-off-by: Juzhe-Zhong <juzhe.zhong@rivai.ai>
gcc/config/riscv/riscv-protos.h
gcc/config/riscv/riscv-vector-builtins.cc
gcc/config/riscv/riscv.cc
gcc/config/riscv/riscv.h
gcc/config/riscv/riscv.md
gcc/config/riscv/vector-iterators.md
gcc/config/riscv/vector.md

index 835bb802fc6e9bce630f7ac578cc32b4c1043ef0..12634d0ac1a58535e1a16cf8411f151dad4b70a8 100644 (file)
@@ -231,6 +231,16 @@ enum vxrm_field_enum
   VXRM_RDN,
   VXRM_ROD
 };
+/* Rounding mode bitfield for floating point FRM.  */
+enum frm_field_enum
+{
+  FRM_RNE = 0b000,
+  FRM_RTZ = 0b001,
+  FRM_RDN = 0b010,
+  FRM_RUP = 0b011,
+  FRM_RMM = 0b100,
+  DYN = 0b111
+};
 }
 
 /* We classify builtin types into two classes:
index 1de075fb90dbf17492745ad4f3242e0752b597e6..b7458aaace6f2a86af0bae16231e6ec4da89a068 100644 (file)
@@ -3460,6 +3460,13 @@ function_expander::use_ternop_insn (bool vd_accum_p, insn_code icode)
   add_input_operand (Pmode, get_tail_policy_for_pred (pred));
   add_input_operand (Pmode, get_mask_policy_for_pred (pred));
   add_input_operand (Pmode, get_avl_type_rtx (avl_type::NONVLMAX));
+
+  /* TODO: Currently, we don't support intrinsic that is modeling rounding mode.
+     We add default rounding mode for the intrinsics that didn't model rounding
+     mode yet.  */
+  if (opno != insn_data[icode].n_generator_args)
+    add_input_operand (Pmode, const0_rtx);
+
   return generate_insn (icode);
 }
 
@@ -3482,6 +3489,13 @@ function_expander::use_widen_ternop_insn (insn_code icode)
   add_input_operand (Pmode, get_tail_policy_for_pred (pred));
   add_input_operand (Pmode, get_mask_policy_for_pred (pred));
   add_input_operand (Pmode, get_avl_type_rtx (avl_type::NONVLMAX));
+
+  /* TODO: Currently, we don't support intrinsic that is modeling rounding mode.
+     We add default rounding mode for the intrinsics that didn't model rounding
+     mode yet.  */
+  if (opno != insn_data[icode].n_generator_args)
+    add_input_operand (Pmode, const0_rtx);
+
   return generate_insn (icode);
 }
 
index b52e613c629acfff8d4349a433d80c382d79b30a..de5b87b1a87fbdac982e359f512957340b5a1bfb 100644 (file)
@@ -6082,7 +6082,8 @@ riscv_hard_regno_nregs (unsigned int regno, machine_mode mode)
 
   /* mode for VL or VTYPE are just a marker, not holding value,
      so it always consume one register.  */
-  if (VTYPE_REG_P (regno) || VL_REG_P (regno) || VXRM_REG_P (regno))
+  if (VTYPE_REG_P (regno) || VL_REG_P (regno) || VXRM_REG_P (regno)
+      || FRM_REG_P (regno))
     return 1;
 
   /* Assume every valid non-vector mode fits in one vector register.  */
@@ -6150,7 +6151,8 @@ riscv_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
       if (lmul != 1)
        return ((regno % lmul) == 0);
     }
-  else if (VTYPE_REG_P (regno) || VL_REG_P (regno) || VXRM_REG_P (regno))
+  else if (VTYPE_REG_P (regno) || VL_REG_P (regno) || VXRM_REG_P (regno)
+          || FRM_REG_P (regno))
     return true;
   else
     return false;
@@ -6587,6 +6589,7 @@ riscv_conditional_register_usage (void)
       fixed_regs[VTYPE_REGNUM] = call_used_regs[VTYPE_REGNUM] = 1;
       fixed_regs[VL_REGNUM] = call_used_regs[VL_REGNUM] = 1;
       fixed_regs[VXRM_REGNUM] = call_used_regs[VXRM_REGNUM] = 1;
+      fixed_regs[FRM_REGNUM] = call_used_regs[FRM_REGNUM] = 1;
     }
 }
 
index f74b70de562924116515e00e6ca111c54772353c..f55bd6112a8ae80fb69c68af150b7bcb1397e206 100644 (file)
@@ -121,8 +121,9 @@ ASM_MISA_SPEC
 
 /* The mapping from gcc register number to DWARF 2 CFA column number.  */
 #define DWARF_FRAME_REGNUM(REGNO)                                              \
-  (VXRM_REG_P (REGNO) ? RISCV_DWARF_VXRM                                       \
-   : VL_REG_P (REGNO) ? RISCV_DWARF_VL                                         \
+  (FRM_REG_P (REGNO)   ? RISCV_DWARF_FRM                                      \
+   : VXRM_REG_P (REGNO) ? RISCV_DWARF_VXRM                                     \
+   : VL_REG_P (REGNO)  ? RISCV_DWARF_VL                                       \
    : VTYPE_REG_P (REGNO)                                                       \
      ? RISCV_DWARF_VTYPE                                                       \
      : (GP_REG_P (REGNO) || FP_REG_P (REGNO) || V_REG_P (REGNO)                \
@@ -374,6 +375,7 @@ ASM_MISA_SPEC
 #define VL_REG_P(REGNO) ((REGNO) == VL_REGNUM)
 #define VTYPE_REG_P(REGNO) ((REGNO) == VTYPE_REGNUM)
 #define VXRM_REG_P(REGNO) ((REGNO) == VXRM_REGNUM)
+#define FRM_REG_P(REGNO) ((REGNO) == FRM_REGNUM)
 
 /* True when REGNO is in SIBCALL_REGS set.  */
 #define SIBCALL_REG_P(REGNO)   \
@@ -392,6 +394,7 @@ ASM_MISA_SPEC
 #define FRAME_POINTER_REGNUM 65
 
 /* Define Dwarf for RVV.  */
+#define RISCV_DWARF_FRM (4096 + 0x003)
 #define RISCV_DWARF_VXRM (4096 + 0x00a)
 #define RISCV_DWARF_VL (4096 + 0xc20)
 #define RISCV_DWARF_VTYPE (4096 + 0xc21)
index c5cf3af98682615fd3bb112771c0d562a445e450..91808d6bd2a0fe999984811153ada201f1e91123 100644 (file)
    (VL_REGNUM                  66)
    (VTYPE_REGNUM               67)
    (VXRM_REGNUM                        68)
+   (FRM_REGNUM                 69)
 ])
 
 (include "predicates.md")
index a282861335d9ad756849e09ff8625b3febddf09b..3096ac5be3cfc0a54843e487b7bbf22e710066c9 100644 (file)
 
 (define_code_iterator and_ior [and ior])
 
-(define_code_iterator any_float_binop [plus mult smax smin minus div])
-(define_code_iterator commutative_float_binop [plus mult smax smin])
+(define_code_iterator any_float_binop [plus mult minus div])
+(define_code_iterator any_float_binop_nofrm [smax smin])
+(define_code_iterator commutative_float_binop [plus mult])
+(define_code_iterator commutative_float_binop_nofrm [smax smin])
 (define_code_iterator non_commutative_float_binop [minus div])
-(define_code_iterator any_float_unop [neg abs sqrt])
+(define_code_iterator any_float_unop [sqrt])
+(define_code_iterator any_float_unop_nofrm [neg abs])
 
 (define_code_iterator any_fix [fix unsigned_fix])
 (define_code_iterator any_float [float unsigned_float])
index e0aeeea57a4dc011ebc912ede93c3fabc0b06af2..a06b84d7473e520e6e111ed251a6a1720889ba5d 100644 (file)
             (match_operand 6 "const_int_operand"        "  i,  i,  i,  i")
             (match_operand 7 "const_int_operand"        "  i,  i,  i,  i")
             (match_operand 8 "const_int_operand"        "  i,  i,  i,  i")
+            (match_operand 9 "const_int_operand"        "  i,  i,  i,  i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (any_float_binop:VF
            (match_operand:VF 3 "register_operand"       " vr, vr, vr, vr")
            (match_operand:VF 4 "register_operand"       " vr, vr, vr, vr"))
   [(set_attr "type" "<float_insn_type>")
    (set_attr "mode" "<MODE>")])
 
-(define_insn "@pred_<optab><mode>_scalar"
+(define_insn "@pred_<optab><mode>"
   [(set (match_operand:VF 0 "register_operand"           "=vd, vd, vr, vr")
        (if_then_else:VF
          (unspec:<VM>
             (match_operand 8 "const_int_operand"        "  i,  i,  i,  i")
             (reg:SI VL_REGNUM)
             (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+         (any_float_binop_nofrm:VF
+           (match_operand:VF 3 "register_operand"       " vr, vr, vr, vr")
+           (match_operand:VF 4 "register_operand"       " vr, vr, vr, vr"))
+         (match_operand:VF 2 "vector_merge_operand"     " vu,  0, vu,  0")))]
+  "TARGET_VECTOR"
+  "vf<insn>.vv\t%0,%3,%4%p1"
+  [(set_attr "type" "<float_insn_type>")
+   (set_attr "mode" "<MODE>")])
+
+(define_insn "@pred_<optab><mode>_scalar"
+  [(set (match_operand:VF 0 "register_operand"           "=vd, vd, vr, vr")
+       (if_then_else:VF
+         (unspec:<VM>
+           [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1,Wc1")
+            (match_operand 5 "vector_length_operand"    " rK, rK, rK, rK")
+            (match_operand 6 "const_int_operand"        "  i,  i,  i,  i")
+            (match_operand 7 "const_int_operand"        "  i,  i,  i,  i")
+            (match_operand 8 "const_int_operand"        "  i,  i,  i,  i")
+            (match_operand 9 "const_int_operand"        "  i,  i,  i,  i")
+            (reg:SI VL_REGNUM)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (commutative_float_binop:VF
            (vec_duplicate:VF
              (match_operand:<VEL> 4 "register_operand"  "  f,  f,  f,  f"))
             (match_operand 8 "const_int_operand"        "  i,  i,  i,  i")
             (reg:SI VL_REGNUM)
             (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+         (commutative_float_binop_nofrm:VF
+           (vec_duplicate:VF
+             (match_operand:<VEL> 4 "register_operand"  "  f,  f,  f,  f"))
+           (match_operand:VF 3 "register_operand"       " vr, vr, vr, vr"))
+         (match_operand:VF 2 "vector_merge_operand"     " vu,  0, vu,  0")))]
+  "TARGET_VECTOR"
+  "vf<insn>.vf\t%0,%3,%4%p1"
+  [(set_attr "type" "<float_insn_type>")
+   (set_attr "mode" "<MODE>")])
+
+(define_insn "@pred_<optab><mode>_scalar"
+  [(set (match_operand:VF 0 "register_operand"           "=vd, vd, vr, vr")
+       (if_then_else:VF
+         (unspec:<VM>
+           [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1,Wc1")
+            (match_operand 5 "vector_length_operand"    " rK, rK, rK, rK")
+            (match_operand 6 "const_int_operand"        "  i,  i,  i,  i")
+            (match_operand 7 "const_int_operand"        "  i,  i,  i,  i")
+            (match_operand 8 "const_int_operand"        "  i,  i,  i,  i")
+            (match_operand 9 "const_int_operand"        "  i,  i,  i,  i")
+            (reg:SI VL_REGNUM)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (non_commutative_float_binop:VF
            (match_operand:VF 3 "register_operand"       " vr, vr, vr, vr")
            (vec_duplicate:VF
             (match_operand 6 "const_int_operand"        "  i,  i,  i,  i")
             (match_operand 7 "const_int_operand"        "  i,  i,  i,  i")
             (match_operand 8 "const_int_operand"        "  i,  i,  i,  i")
+            (match_operand 9 "const_int_operand"        "  i,  i,  i,  i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (non_commutative_float_binop:VF
            (vec_duplicate:VF
              (match_operand:<VEL> 4 "register_operand"  "  f,  f,  f,  f"))
             (match_operand 7 "const_int_operand")
             (match_operand 8 "const_int_operand")
             (match_operand 9 "const_int_operand")
+            (match_operand 10 "const_int_operand")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (plus_minus:VF
            (mult:VF
              (match_operand:VF 2 "register_operand")
             (match_operand 6 "const_int_operand"        "  i,    i,  i,    i")
             (match_operand 7 "const_int_operand"        "  i,    i,  i,    i")
             (match_operand 8 "const_int_operand"        "  i,    i,  i,    i")
+            (match_operand 9 "const_int_operand"        "  i,    i,  i,    i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (plus_minus:VF
            (mult:VF
              (match_operand:VF 2 "register_operand"     "  0,   vr,  0,   vr")
             (match_operand 6 "const_int_operand"        "  i,    i,  i,    i")
             (match_operand 7 "const_int_operand"        "  i,    i,  i,    i")
             (match_operand 8 "const_int_operand"        "  i,    i,  i,    i")
+            (match_operand 9 "const_int_operand"        "  i,    i,  i,    i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (plus_minus:VF
            (mult:VF
              (match_operand:VF 2 "register_operand"     " vr,   vr, vr,   vr")
             (match_operand 7 "const_int_operand"        "    i,    i")
             (match_operand 8 "const_int_operand"        "    i,    i")
             (match_operand 9 "const_int_operand"        "    i,    i")
+            (match_operand 10 "const_int_operand"       "    i,    i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (plus_minus:VF
            (mult:VF
              (match_operand:VF 2 "register_operand"     "   vr,   vr")
             (match_operand 7 "const_int_operand")
             (match_operand 8 "const_int_operand")
             (match_operand 9 "const_int_operand")
+            (match_operand 10 "const_int_operand")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (plus_minus:VF
            (mult:VF
              (vec_duplicate:VF
             (match_operand 6 "const_int_operand"         "  i,    i,  i,    i")
             (match_operand 7 "const_int_operand"         "  i,    i,  i,    i")
             (match_operand 8 "const_int_operand"         "  i,    i,  i,    i")
+            (match_operand 9 "const_int_operand"         "  i,    i,  i,    i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (plus_minus:VF
            (mult:VF
              (vec_duplicate:VF
             (match_operand 6 "const_int_operand"         "  i,    i,  i,    i")
             (match_operand 7 "const_int_operand"         "  i,    i,  i,    i")
             (match_operand 8 "const_int_operand"         "  i,    i,  i,    i")
+            (match_operand 9 "const_int_operand"         "  i,    i,  i,    i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (plus_minus:VF
            (mult:VF
              (vec_duplicate:VF
             (match_operand 7 "const_int_operand"        "    i,    i")
             (match_operand 8 "const_int_operand"        "    i,    i")
             (match_operand 9 "const_int_operand"        "    i,    i")
+            (match_operand 10 "const_int_operand"       "    i,    i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (plus_minus:VF
            (mult:VF
              (vec_duplicate:VF
             (match_operand 7 "const_int_operand")
             (match_operand 8 "const_int_operand")
             (match_operand 9 "const_int_operand")
+            (match_operand 10 "const_int_operand")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (plus_minus:VF
            (neg:VF
              (mult:VF
             (match_operand 6 "const_int_operand"        "  i,    i,  i,    i")
             (match_operand 7 "const_int_operand"        "  i,    i,  i,    i")
             (match_operand 8 "const_int_operand"        "  i,    i,  i,    i")
+            (match_operand 9 "const_int_operand"        "  i,    i,  i,    i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (plus_minus:VF
            (neg:VF
              (mult:VF
             (match_operand 6 "const_int_operand"        "  i,    i,  i,    i")
             (match_operand 7 "const_int_operand"        "  i,    i,  i,    i")
             (match_operand 8 "const_int_operand"        "  i,    i,  i,    i")
+            (match_operand 9 "const_int_operand"        "  i,    i,  i,    i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (plus_minus:VF
            (neg:VF
              (mult:VF
             (match_operand 7 "const_int_operand"        "    i,    i")
             (match_operand 8 "const_int_operand"        "    i,    i")
             (match_operand 9 "const_int_operand"        "    i,    i")
+            (match_operand 10 "const_int_operand"       "    i,    i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (plus_minus:VF
            (neg:VF
              (mult:VF
             (match_operand 7 "const_int_operand")
             (match_operand 8 "const_int_operand")
             (match_operand 9 "const_int_operand")
+            (match_operand 10 "const_int_operand")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (plus_minus:VF
            (neg:VF
              (mult:VF
             (match_operand 6 "const_int_operand"         "  i,    i,  i,    i")
             (match_operand 7 "const_int_operand"         "  i,    i,  i,    i")
             (match_operand 8 "const_int_operand"         "  i,    i,  i,    i")
+            (match_operand 9 "const_int_operand"         "  i,    i,  i,    i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (plus_minus:VF
            (neg:VF
              (mult:VF
             (match_operand 6 "const_int_operand"           "  i,    i,  i,    i")
             (match_operand 7 "const_int_operand"           "  i,    i,  i,    i")
             (match_operand 8 "const_int_operand"           "  i,    i,  i,    i")
+            (match_operand 9 "const_int_operand"           "  i,    i,  i,    i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (plus_minus:VF
            (neg:VF
              (mult:VF
             (match_operand 7 "const_int_operand"           "    i,    i")
             (match_operand 8 "const_int_operand"           "    i,    i")
             (match_operand 9 "const_int_operand"           "    i,    i")
+            (match_operand 10 "const_int_operand"          "    i,    i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (plus_minus:VF
            (neg:VF
              (mult:VF
             (match_operand 5 "const_int_operand"        "  i,  i,  i,  i")
             (match_operand 6 "const_int_operand"        "  i,  i,  i,  i")
             (match_operand 7 "const_int_operand"        "  i,  i,  i,  i")
+            (match_operand 8 "const_int_operand"        "  i,  i,  i,  i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (any_float_unop:VF
            (match_operand:VF 3 "register_operand"       " vr, vr, vr, vr"))
          (match_operand:VF 2 "vector_merge_operand"     " vu,  0, vu,  0")))]
    (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[6])"))
    (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
 
+(define_insn "@pred_<optab><mode>"
+  [(set (match_operand:VF 0 "register_operand"           "=vd, vd, vr, vr")
+       (if_then_else:VF
+         (unspec:<VM>
+           [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1,Wc1")
+            (match_operand 4 "vector_length_operand"    " rK, rK, rK, rK")
+            (match_operand 5 "const_int_operand"        "  i,  i,  i,  i")
+            (match_operand 6 "const_int_operand"        "  i,  i,  i,  i")
+            (match_operand 7 "const_int_operand"        "  i,  i,  i,  i")
+            (reg:SI VL_REGNUM)
+            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+         (any_float_unop_nofrm:VF
+           (match_operand:VF 3 "register_operand"       " vr, vr, vr, vr"))
+         (match_operand:VF 2 "vector_merge_operand"     " vu,  0, vu,  0")))]
+  "TARGET_VECTOR"
+  "vf<insn>.v\t%0,%3%p1"
+  [(set_attr "type" "<float_insn_type>")
+   (set_attr "mode" "<MODE>")
+   (set_attr "vl_op_idx" "4")
+   (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[5])"))
+   (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[6])"))
+   (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
+
 (define_insn "@pred_<misc_op><mode>"
   [(set (match_operand:VF 0 "register_operand"           "=vd, vd, vr, vr")
        (if_then_else:VF
             (match_operand 6 "const_int_operand"                  "    i,    i")
             (match_operand 7 "const_int_operand"                  "    i,    i")
             (match_operand 8 "const_int_operand"                  "    i,    i")
+            (match_operand 9 "const_int_operand"                  "    i,    i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (any_widen_binop:VWEXTF
            (float_extend:VWEXTF
              (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand" "   vr,   vr"))
             (match_operand 6 "const_int_operand"                  "    i,    i")
             (match_operand 7 "const_int_operand"                  "    i,    i")
             (match_operand 8 "const_int_operand"                  "    i,    i")
+            (match_operand 9 "const_int_operand"                  "    i,    i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (any_widen_binop:VWEXTF
            (float_extend:VWEXTF
              (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand" "   vr,   vr"))
             (match_operand 6 "const_int_operand"                  "    i,    i")
             (match_operand 7 "const_int_operand"                  "    i,    i")
             (match_operand 8 "const_int_operand"                  "    i,    i")
+            (match_operand 9 "const_int_operand"                  "    i,    i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (plus_minus:VWEXTF
            (match_operand:VWEXTF 3 "register_operand"             "   vr,   vr")
            (float_extend:VWEXTF
             (match_operand 6 "const_int_operand"                  "    i,    i")
             (match_operand 7 "const_int_operand"                  "    i,    i")
             (match_operand 8 "const_int_operand"                  "    i,    i")
+            (match_operand 9 "const_int_operand"                  "    i,    i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (plus_minus:VWEXTF
            (match_operand:VWEXTF 3 "register_operand"             "   vr,   vr")
            (float_extend:VWEXTF
             (match_operand 6 "const_int_operand"                    "    i")
             (match_operand 7 "const_int_operand"                    "    i")
             (match_operand 8 "const_int_operand"                    "    i")
+            (match_operand 9 "const_int_operand"                    "    i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (plus_minus:VWEXTF
            (mult:VWEXTF
              (float_extend:VWEXTF
             (match_operand 6 "const_int_operand"                    "    i")
             (match_operand 7 "const_int_operand"                    "    i")
             (match_operand 8 "const_int_operand"                    "    i")
+            (match_operand 9 "const_int_operand"                    "    i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (plus_minus:VWEXTF
            (mult:VWEXTF
              (float_extend:VWEXTF
             (match_operand 6 "const_int_operand"                      "    i")
             (match_operand 7 "const_int_operand"                      "    i")
             (match_operand 8 "const_int_operand"                      "    i")
+            (match_operand 9 "const_int_operand"                      "    i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (plus_minus:VWEXTF
            (neg:VWEXTF
              (mult:VWEXTF
             (match_operand 6 "const_int_operand"                      "    i")
             (match_operand 7 "const_int_operand"                      "    i")
             (match_operand 8 "const_int_operand"                      "    i")
+            (match_operand 9 "const_int_operand"                      "    i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (plus_minus:VWEXTF
            (neg:VWEXTF
              (mult:VWEXTF
             (match_operand 5 "const_int_operand"            "  i,  i,  i,  i")
             (match_operand 6 "const_int_operand"            "  i,  i,  i,  i")
             (match_operand 7 "const_int_operand"            "  i,  i,  i,  i")
+            (match_operand 8 "const_int_operand"            "  i,  i,  i,  i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (unspec:<VCONVERT>
             [(match_operand:VF 3 "register_operand"         " vr, vr, vr, vr")] VFCVTS)
          (match_operand:<VCONVERT> 2 "vector_merge_operand" " vu,  0, vu,  0")))]
             (match_operand 5 "const_int_operand"            "  i,  i,  i,  i")
             (match_operand 6 "const_int_operand"            "  i,  i,  i,  i")
             (match_operand 7 "const_int_operand"            "  i,  i,  i,  i")
+            (match_operand 8 "const_int_operand"            "  i,  i,  i,  i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (any_fix:<VCONVERT>
             (match_operand:VF 3 "register_operand"          " vr, vr, vr, vr"))
          (match_operand:<VCONVERT> 2 "vector_merge_operand" " vu,  0, vu,  0")))]
             (match_operand 5 "const_int_operand"           "  i,  i,  i,  i")
             (match_operand 6 "const_int_operand"           "  i,  i,  i,  i")
             (match_operand 7 "const_int_operand"           "  i,  i,  i,  i")
+            (match_operand 8 "const_int_operand"           "  i,  i,  i,  i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (any_float:VF
             (match_operand:<VCONVERT> 3 "register_operand" " vr, vr, vr, vr"))
          (match_operand:VF 2 "vector_merge_operand"        " vu,  0, vu,  0")))]
             (match_operand 5 "const_int_operand"             "    i,    i")
             (match_operand 6 "const_int_operand"             "    i,    i")
             (match_operand 7 "const_int_operand"             "    i,    i")
+            (match_operand 8 "const_int_operand"             "    i,    i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (unspec:VWCONVERTI
             [(match_operand:<VNCONVERT> 3 "register_operand" "   vr,   vr")] VFCVTS)
          (match_operand:VWCONVERTI 2 "vector_merge_operand"  "   vu,    0")))]
             (match_operand 5 "const_int_operand"            "    i,    i")
             (match_operand 6 "const_int_operand"            "    i,    i")
             (match_operand 7 "const_int_operand"            "    i,    i")
+            (match_operand 8 "const_int_operand"            "    i,    i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (any_fix:VWCONVERTI
             (match_operand:<VNCONVERT> 3 "register_operand" "   vr,   vr"))
          (match_operand:VWCONVERTI 2 "vector_merge_operand" "   vu,    0")))]
             (match_operand 5 "const_int_operand"            "    i,    i")
             (match_operand 6 "const_int_operand"            "    i,    i")
             (match_operand 7 "const_int_operand"            "    i,    i")
+            (match_operand 8 "const_int_operand"            "    i,    i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (any_float:VF
             (match_operand:<VNCONVERT> 3 "register_operand" "   vr,   vr"))
          (match_operand:VF 2 "vector_merge_operand"         "   vu,    0")))]
             (match_operand 5 "const_int_operand"                 "    i,    i")
             (match_operand 6 "const_int_operand"                 "    i,    i")
             (match_operand 7 "const_int_operand"                 "    i,    i")
+            (match_operand 8 "const_int_operand"                 "    i,    i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (float_extend:VWEXTF
             (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand" "   vr,   vr"))
          (match_operand:VWEXTF 2 "vector_merge_operand"          "   vu,    0")))]
             (match_operand 5 "const_int_operand"              "  i,  i,  i,  i,    i,    i")
             (match_operand 6 "const_int_operand"              "  i,  i,  i,  i,    i,    i")
             (match_operand 7 "const_int_operand"              "  i,  i,  i,  i,    i,    i")
+            (match_operand 8 "const_int_operand"              "  i,  i,  i,  i,    i,    i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (unspec:<VNCONVERT>
             [(match_operand:VF 3 "register_operand"           "  0,  0,  0,  0,   vr,   vr")] VFCVTS)
          (match_operand:<VNCONVERT> 2 "vector_merge_operand"  " vu,  0, vu,  0,   vu,    0")))]
             (match_operand 5 "const_int_operand"             "  i,  i,  i,  i,    i,    i")
             (match_operand 6 "const_int_operand"             "  i,  i,  i,  i,    i,    i")
             (match_operand 7 "const_int_operand"             "  i,  i,  i,  i,    i,    i")
+            (match_operand 8 "const_int_operand"             "  i,  i,  i,  i,    i,    i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (any_fix:<VNCONVERT>
             (match_operand:VF 3 "register_operand"           "  0,  0,  0,  0,   vr,   vr"))
          (match_operand:<VNCONVERT> 2 "vector_merge_operand" " vu,  0, vu,  0,   vu,    0")))]
             (match_operand 5 "const_int_operand"             "  i,  i,  i,  i,    i,    i")
             (match_operand 6 "const_int_operand"             "  i,  i,  i,  i,    i,    i")
             (match_operand 7 "const_int_operand"             "  i,  i,  i,  i,    i,    i")
+            (match_operand 8 "const_int_operand"             "  i,  i,  i,  i,    i,    i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (any_float:<VNCONVERT>
             (match_operand:VWCONVERTI 3 "register_operand"   "  0,  0,  0,  0,   vr,   vr"))
          (match_operand:<VNCONVERT> 2 "vector_merge_operand" " vu,  0, vu,  0,   vu,    0")))]
             (match_operand 5 "const_int_operand"                  "  i,  i,  i,  i,    i,    i")
             (match_operand 6 "const_int_operand"                  "  i,  i,  i,  i,    i,    i")
             (match_operand 7 "const_int_operand"                  "  i,  i,  i,  i,    i,    i")
+            (match_operand 8 "const_int_operand"                  "  i,  i,  i,  i,    i,    i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (float_truncate:<V_DOUBLE_TRUNC>
             (match_operand:VWEXTF 3 "register_operand"            "  0,  0,  0,  0,   vr,   vr"))
          (match_operand:<V_DOUBLE_TRUNC> 2 "vector_merge_operand" " vu,  0, vu,  0,   vu,    0")))]
             (match_operand 5 "const_int_operand"                  "  i,  i,  i,  i,    i,    i")
             (match_operand 6 "const_int_operand"                  "  i,  i,  i,  i,    i,    i")
             (match_operand 7 "const_int_operand"                  "  i,  i,  i,  i,    i,    i")
+            (match_operand 8 "const_int_operand"                  "  i,  i,  i,  i,    i,    i")
             (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+            (reg:SI VTYPE_REGNUM)
+            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (unspec:<V_DOUBLE_TRUNC>
            [(float_truncate:<V_DOUBLE_TRUNC>
               (match_operand:VWEXTF 3 "register_operand"          "  0,  0,  0,  0,   vr,   vr"))] UNSPEC_ROD)
              (match_operand 5 "vector_length_operand"         "   rK,   rK")
              (match_operand 6 "const_int_operand"             "    i,    i")
              (match_operand 7 "const_int_operand"             "    i,    i")
+             (match_operand 8 "const_int_operand"             "    i,    i")
              (reg:SI VL_REGNUM)
-             (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+             (reg:SI VTYPE_REGNUM)
+             (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
           (any_freduc:VF
             (vec_duplicate:VF
               (vec_select:<VEL>
              (match_operand 5 "vector_length_operand"              "   rK,   rK")
              (match_operand 6 "const_int_operand"                  "    i,    i")
              (match_operand 7 "const_int_operand"                  "    i,    i")
+             (match_operand 8 "const_int_operand"                  "    i,    i")
              (reg:SI VL_REGNUM)
-             (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+             (reg:SI VTYPE_REGNUM)
+             (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
           (any_freduc:VF_ZVE64
             (vec_duplicate:VF_ZVE64
               (vec_select:<VEL>
              (match_operand 5 "vector_length_operand"              " rK, rK, rK, rK")
              (match_operand 6 "const_int_operand"                  "  i,  i,  i,  i")
              (match_operand 7 "const_int_operand"                  "  i,  i,  i,  i")
+             (match_operand 8 "const_int_operand"                  "  i,  i,  i,  i")
              (reg:SI VL_REGNUM)
-             (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+             (reg:SI VTYPE_REGNUM)
+             (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
           (any_freduc:VF_ZVE32
             (vec_duplicate:VF_ZVE32
               (vec_select:<VEL>
                (match_operand 5 "vector_length_operand"         "   rK,   rK")
                (match_operand 6 "const_int_operand"             "    i,    i")
                (match_operand 7 "const_int_operand"             "    i,    i")
+               (match_operand 8 "const_int_operand"             "    i,    i")
                (reg:SI VL_REGNUM)
-               (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+               (reg:SI VTYPE_REGNUM)
+               (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
             (plus:VF
               (vec_duplicate:VF
                 (vec_select:<VEL>
                (match_operand 5 "vector_length_operand"              "   rK,   rK")
                (match_operand 6 "const_int_operand"                  "    i,    i")
                (match_operand 7 "const_int_operand"                  "    i,    i")
+               (match_operand 8 "const_int_operand"                  "    i,    i")
                (reg:SI VL_REGNUM)
-               (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+               (reg:SI VTYPE_REGNUM)
+               (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
             (plus:VF_ZVE64
               (vec_duplicate:VF_ZVE64
                 (vec_select:<VEL>
                (match_operand 5 "vector_length_operand"              " rK, rK, rK, rK")
                (match_operand 6 "const_int_operand"                  "  i,  i,  i,  i")
                (match_operand 7 "const_int_operand"                  "  i,  i,  i,  i")
+               (match_operand 8 "const_int_operand"                  "  i,  i,  i,  i")
                (reg:SI VL_REGNUM)
-               (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+               (reg:SI VTYPE_REGNUM)
+               (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
             (plus:VF_ZVE32
               (vec_duplicate:VF_ZVE32
                 (vec_select:<VEL>
                (match_operand 5 "vector_length_operand"         "   rK,   rK")
                (match_operand 6 "const_int_operand"             "    i,    i")
                (match_operand 7 "const_int_operand"             "    i,    i")
+               (match_operand 8 "const_int_operand"             "    i,    i")
                (reg:SI VL_REGNUM)
-               (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+               (reg:SI VTYPE_REGNUM)
+               (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
             (match_operand:VWF 3 "register_operand"             "   vr,   vr")
             (match_operand:<VWLMUL1> 4 "register_operand"       "   vr,   vr")
             (match_operand:<VWLMUL1> 2 "vector_merge_operand"   "   vu,    0")] UNSPEC_WREDUC_SUM)] ORDER))]
                (match_operand 5 "vector_length_operand"         "   rK,   rK")
                (match_operand 6 "const_int_operand"             "    i,    i")
                (match_operand 7 "const_int_operand"             "    i,    i")
+               (match_operand 8 "const_int_operand"             "    i,    i")
                (reg:SI VL_REGNUM)
-               (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+               (reg:SI VTYPE_REGNUM)
+               (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
             (match_operand:VWF_ZVE64 3 "register_operand"             "   vr,   vr")
             (match_operand:<VWLMUL1_ZVE64> 4 "register_operand"       "   vr,   vr")
             (match_operand:<VWLMUL1_ZVE64> 2 "vector_merge_operand"   "   vu,    0")] UNSPEC_WREDUC_SUM)] ORDER))]