achieveartificialintelligence updated this revision to Diff 379924.
achieveartificialintelligence added a comment.

add tests


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111866/new/

https://reviews.llvm.org/D111866

Files:
  clang/lib/Basic/Targets/RISCV.cpp
  clang/lib/Basic/Targets/RISCV.h
  clang/lib/Driver/ToolChains/Arch/RISCV.cpp
  clang/test/Driver/riscv-arch.c
  llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
  llvm/lib/Target/RISCV/RISCV.td
  llvm/lib/Target/RISCV/RISCVISelLowering.cpp
  llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
  llvm/lib/Target/RISCV/RISCVSubtarget.h
  llvm/test/MC/RISCV/attribute-arch.s
  llvm/test/MC/RISCV/rv32zfhmin-invalid.s
  llvm/test/MC/RISCV/rv32zfhmin-valid.s

Index: llvm/test/MC/RISCV/rv32zfhmin-valid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv32zfhmin-valid.s
@@ -0,0 +1,62 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zfhmin,+d -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zfhmin,+d -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-zfhmin,+d < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zfhmin,+d -M no-aliases -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zfhmin,+d < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zfhmin,+d -M no-aliases -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: flh ft0, 12(a0)
+# CHECK-ASM: encoding: [0x07,0x10,0xc5,0x00]
+flh f0, 12(a0)
+# CHECK-ASM-AND-OBJ: flh ft1, 4(ra)
+# CHECK-ASM: encoding: [0x87,0x90,0x40,0x00]
+flh f1, +4(ra)
+# CHECK-ASM-AND-OBJ: flh ft2, -2048(a3)
+# CHECK-ASM: encoding: [0x07,0x91,0x06,0x80]
+flh f2, -2048(x13)
+# CHECK-ASM-AND-OBJ: flh ft3, -2048(s1)
+# CHECK-ASM: encoding: [0x87,0x91,0x04,0x80]
+flh f3, %lo(2048)(s1)
+# CHECK-ASM-AND-OBJ: flh ft4, 2047(s2)
+# CHECK-ASM: encoding: [0x07,0x12,0xf9,0x7f]
+flh f4, 2047(s2)
+# CHECK-ASM-AND-OBJ: flh ft5, 0(s3)
+# CHECK-ASM: encoding: [0x87,0x92,0x09,0x00]
+flh f5, 0(s3)
+
+# CHECK-ASM-AND-OBJ: fsh ft6, 2047(s4)
+# CHECK-ASM: encoding: [0xa7,0x1f,0x6a,0x7e]
+fsh f6, 2047(s4)
+# CHECK-ASM-AND-OBJ: fsh ft7, -2048(s5)
+# CHECK-ASM: encoding: [0x27,0x90,0x7a,0x80]
+fsh f7, -2048(s5)
+# CHECK-ASM-AND-OBJ: fsh fs0, -2048(s6)
+# CHECK-ASM: encoding: [0x27,0x10,0x8b,0x80]
+fsh f8, %lo(2048)(s6)
+# CHECK-ASM-AND-OBJ: fsh fs1, 999(s7)
+# CHECK-ASM: encoding: [0xa7,0x93,0x9b,0x3e]
+fsh f9, 999(s7)
+
+# CHECK-ASM-AND-OBJ: fmv.x.h a2, fs7
+# CHECK-ASM: encoding: [0x53,0x86,0x0b,0xe4]
+fmv.x.h a2, fs7
+# CHECK-ASM-AND-OBJ: fmv.h.x ft1, a6
+# CHECK-ASM: encoding: [0xd3,0x00,0x08,0xf4]
+fmv.h.x ft1, a6
+
+# CHECK-ASM-AND-OBJ: fcvt.s.h fa0, ft0
+# CHECK-ASM: encoding: [0x53,0x05,0x20,0x40]
+fcvt.s.h fa0, ft0
+# CHECK-ASM-AND-OBJ: fcvt.h.s ft2, fa2
+# CHECK-ASM: encoding: [0x53,0x71,0x06,0x44]
+fcvt.h.s ft2, fa2
+# CHECK-ASM-AND-OBJ: fcvt.d.h fa0, ft0
+# CHECK-ASM: encoding: [0x53,0x05,0x20,0x42]
+fcvt.d.h fa0, ft0
+# CHECK-ASM-AND-OBJ: fcvt.h.d ft2, fa2
+# CHECK-ASM: encoding: [0x53,0x71,0x16,0x44]
+fcvt.h.d ft2, fa2
Index: llvm/test/MC/RISCV/rv32zfhmin-invalid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv32zfhmin-invalid.s
@@ -0,0 +1,23 @@
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-zfhmin < %s 2>&1 | \
+# RUN:   FileCheck %s
+
+# Out of range immediates
+## simm12
+flh ft1, -2049(a0) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047]
+fsh ft2, 2048(a1) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047]
+
+# Memory operand not formatted correctly
+flh ft1, a0, -200 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction
+
+# Invalid register names
+flh ft15, 100(a0) # CHECK: :[[@LINE]]:5: error: invalid operand for instruction
+flh ft1, 100(a10) # CHECK: :[[@LINE]]:14: error: expected register
+
+# Integer registers where FP regs are expected
+fmv.x.h fs7, a2 # CHECK: :[[@LINE]]:9: error: invalid operand for instruction
+
+# FP registers where integer regs are expected
+fmv.h.x a8, ft2 # CHECK: :[[@LINE]]:9: error: invalid operand for instruction
+
+# Zfh instructions
+fmadd.h f10, f11, f12, f13, dyn # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zfh' (Half-Precision Floating-Point)
Index: llvm/test/MC/RISCV/attribute-arch.s
===================================================================
--- llvm/test/MC/RISCV/attribute-arch.s
+++ llvm/test/MC/RISCV/attribute-arch.s
@@ -69,8 +69,11 @@
 .attribute arch, "rv32izbt"
 # CHECK: attribute      5, "rv32i2p0_zbt0p93"
 
+.attribute arch, "rv32ifzfhmin"
+# CHECK: attribute      5, "rv32i2p0_f2p0_zfhmin0p1"
+
 .attribute arch, "rv32ifzfh"
-# CHECK: attribute      5, "rv32i2p0_f2p0_zfh0p1"
+# CHECK: attribute      5, "rv32i2p0_f2p0_zfh0p1_zfhmin0p1"
 
 .attribute arch, "rv32ivzvamo_zvlsseg"
 # CHECK: attribute      5, "rv32i2p0_v0p10_zvamo0p10_zvlsseg0p10"
Index: llvm/lib/Target/RISCV/RISCVSubtarget.h
===================================================================
--- llvm/lib/Target/RISCV/RISCVSubtarget.h
+++ llvm/lib/Target/RISCV/RISCVSubtarget.h
@@ -53,6 +53,7 @@
   bool HasStdExtZvlsseg = false;
   bool HasStdExtZvamo = false;
   bool HasStdExtZfh = false;
+  bool HasStdExtZfhmin = false;
   bool HasRV64 = false;
   bool IsRV32E = false;
   bool EnableLinkerRelax = false;
@@ -119,6 +120,7 @@
   bool hasStdExtZvlsseg() const { return HasStdExtZvlsseg; }
   bool hasStdExtZvamo() const { return HasStdExtZvamo; }
   bool hasStdExtZfh() const { return HasStdExtZfh; }
+  bool hasStdExtZfhmin() const { return HasStdExtZfhmin; }
   bool is64Bit() const { return HasRV64; }
   bool isRV32E() const { return IsRV32E; }
   bool enableLinkerRelax() const { return EnableLinkerRelax; }
Index: llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
===================================================================
--- llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
+++ llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
@@ -66,7 +66,7 @@
 // Instructions
 //===----------------------------------------------------------------------===//
 
-let Predicates = [HasStdExtZfh] in {
+let Predicates = [HasStdExtZfhmin] in {
 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
 def FLH : RVInstI<0b001, OPC_LOAD_FP, (outs FPR16:$rd),
                   (ins GPR:$rs1, simm12:$imm12),
@@ -81,7 +81,9 @@
                   (ins FPR16:$rs2, GPR:$rs1, simm12:$imm12),
                    "fsh", "$rs2, ${imm12}(${rs1})">,
           Sched<[WriteFST16, ReadStoreData, ReadFMemBase]>;
+} // Predicates = [HasStdExtZfhmin]
 
+let Predicates = [HasStdExtZfh] in {
 def FMADD_H  : FPFMAH_rrr_frm<OPC_MADD, "fmadd.h">,
                Sched<[WriteFMA16, ReadFMA16, ReadFMA16, ReadFMA16]>;
 def          : FPFMAHDynFrmAlias<FMADD_H, "fmadd.h">;
@@ -148,7 +150,9 @@
   let rs2 = 0b00001;
 }
 def           : FPUnaryOpDynFrmAlias<FCVT_H_WU, "fcvt.h.wu", FPR16, GPR>;
+} // Predicates = [HasStdExtZfh]
 
+let Predicates = [HasStdExtZfhmin] in {
 def FCVT_H_S : FPUnaryOp_r_frm<0b0100010, FPR16, FPR32, "fcvt.h.s">,
                Sched<[WriteFCvtF32ToF16, ReadFCvtF32ToF16]> {
   let rs2 = 0b00000;
@@ -169,7 +173,9 @@
               Sched<[WriteFMovI16ToF16, ReadFMovI16ToF16]> {
   let rs2 = 0b00000;
 }
+} // Predicates = [HasStdExtZfhmin]
 
+let Predicates = [HasStdExtZfh] in {
 def FEQ_H : FPCmpH_rr<0b010, "feq.h">;
 def FLT_H : FPCmpH_rr<0b001, "flt.h">;
 def FLE_H : FPCmpH_rr<0b000, "fle.h">;
@@ -178,7 +184,7 @@
                Sched<[WriteFClass16, ReadFClass16]> {
   let rs2 = 0b00000;
 }
-} // Predicates = [HasStdExtZfh]
+}
 
 let Predicates = [HasStdExtZfh, IsRV64] in {
 def FCVT_L_H  : FPUnaryOp_r_frm<0b1100010, GPR, FPR16, "fcvt.l.h">,
@@ -206,7 +212,7 @@
 def           : FPUnaryOpDynFrmAlias<FCVT_H_LU, "fcvt.h.lu", FPR16, GPR>;
 } // Predicates = [HasStdExtZfh, IsRV64]
 
-let Predicates = [HasStdExtZfh, HasStdExtD] in {
+let Predicates = [HasStdExtZfhmin, HasStdExtD] in {
 def FCVT_H_D : FPUnaryOp_r_frm<0b0100010, FPR16, FPR64, "fcvt.h.d">,
                Sched<[WriteFCvtF64ToF16, ReadFCvtF64ToF16]> {
   let rs2 = 0b00001;
@@ -223,10 +229,12 @@
 // Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20)
 //===----------------------------------------------------------------------===//
 
-let Predicates = [HasStdExtZfh] in {
+let Predicates = [HasStdExtZfhmin] in {
 def : InstAlias<"flh $rd, (${rs1})",  (FLH FPR16:$rd,  GPR:$rs1, 0), 0>;
 def : InstAlias<"fsh $rs2, (${rs1})", (FSH FPR16:$rs2, GPR:$rs1, 0), 0>;
+} // Predicates = [HasStdExtZfhmin]
 
+let Predicates = [HasStdExtZfh] in {
 def : InstAlias<"fmv.h $rd, $rs",  (FSGNJ_H  FPR16:$rd, FPR16:$rs, FPR16:$rs)>;
 def : InstAlias<"fabs.h $rd, $rs", (FSGNJX_H FPR16:$rd, FPR16:$rs, FPR16:$rs)>;
 def : InstAlias<"fneg.h $rd, $rs", (FSGNJN_H FPR16:$rd, FPR16:$rs, FPR16:$rs)>;
@@ -237,7 +245,9 @@
                 (FLT_H GPR:$rd, FPR16:$rt, FPR16:$rs), 0>;
 def : InstAlias<"fge.h $rd, $rs, $rt",
                 (FLE_H GPR:$rd, FPR16:$rt, FPR16:$rs), 0>;
+} // Predicates = [HasStdExtZfh]
 
+let Predicates = [HasStdExtZfhmin] in {
 def PseudoFLH  : PseudoFloatLoad<"flh", FPR16>;
 def PseudoFSH  : PseudoStore<"fsh", FPR16>;
 } // Predicates = [HasStdExtZfh]
@@ -313,7 +323,9 @@
 def : PatFpr16Fpr16<setole, FLE_H>;
 
 def Select_FPR16_Using_CC_GPR : SelectCC_rrirr<FPR16, GPR>;
+} // Predicates = [HasStdExtZfh]
 
+let Predicates = [HasStdExtZfhmin] in {
 /// Loads
 
 defm : LdPat<load, FLH, f16>;
@@ -331,7 +343,7 @@
 // Moves (no conversion)
 def : Pat<(riscv_fmv_h_x GPR:$src), (FMV_H_X GPR:$src)>;
 def : Pat<(riscv_fmv_x_anyexth FPR16:$src), (FMV_X_H FPR16:$src)>;
-} // Predicates = [HasStdExtZfh]
+} // Predicates = [HasStdExtZfhmin]
 
 let Predicates = [HasStdExtZfh, IsRV32] in {
 // half->[u]int. Round-to-zero must be used.
@@ -383,7 +395,7 @@
 def : Pat<(uint_to_fp (i64 GPR:$rs1)), (FCVT_H_LU $rs1, 0b111)>;
 } // Predicates = [HasStdExtZfh, IsRV64]
 
-let Predicates = [HasStdExtZfh, HasStdExtD] in {
+let Predicates = [HasStdExtZfhmin, HasStdExtD] in {
 /// Float conversion operations
 // f64 -> f16, f16 -> f64
 def : Pat<(fpround FPR64:$rs1), (FCVT_H_D FPR64:$rs1, 0b111)>;
Index: llvm/lib/Target/RISCV/RISCVISelLowering.cpp
===================================================================
--- llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -85,7 +85,7 @@
   // Set up the register classes.
   addRegisterClass(XLenVT, &RISCV::GPRRegClass);
 
-  if (Subtarget.hasStdExtZfh())
+  if (Subtarget.hasStdExtZfhmin() || Subtarget.hasStdExtZfh())
     addRegisterClass(MVT::f16, &RISCV::FPR16RegClass);
   if (Subtarget.hasStdExtF())
     addRegisterClass(MVT::f32, &RISCV::FPR32RegClass);
@@ -131,7 +131,7 @@
     for (MVT VT : IntVecVTs)
       addRegClassForRVV(VT);
 
-    if (Subtarget.hasStdExtZfh())
+    if (Subtarget.hasStdExtZfhmin() || Subtarget.hasStdExtZfh())
       for (MVT VT : F16VecVTs)
         addRegClassForRVV(VT);
 
@@ -316,7 +316,7 @@
       ISD::FSIN, ISD::FCOS,       ISD::FSINCOS,   ISD::FPOW,
       ISD::FREM, ISD::FP16_TO_FP, ISD::FP_TO_FP16};
 
-  if (Subtarget.hasStdExtZfh())
+  if (Subtarget.hasStdExtZfhmin()||Subtarget.hasStdExtZfh())
     setOperationAction(ISD::BITCAST, MVT::i16, Custom);
 
   if (Subtarget.hasStdExtZfh()) {
@@ -1150,7 +1150,8 @@
 
 bool RISCVTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
                                        bool ForCodeSize) const {
-  if (VT == MVT::f16 && !Subtarget.hasStdExtZfh())
+  if (VT == MVT::f16 && !Subtarget.hasStdExtZfhmin() &&
+      !Subtarget.hasStdExtZfh())
     return false;
   if (VT == MVT::f32 && !Subtarget.hasStdExtF())
     return false;
@@ -1162,7 +1163,8 @@
 }
 
 bool RISCVTargetLowering::hasBitPreservingFPLogic(EVT VT) const {
-  return (VT == MVT::f16 && Subtarget.hasStdExtZfh()) ||
+  return (VT == MVT::f16 &&
+          (Subtarget.hasStdExtZfhmin() || Subtarget.hasStdExtZfh())) ||
          (VT == MVT::f32 && Subtarget.hasStdExtF()) ||
          (VT == MVT::f64 && Subtarget.hasStdExtD());
 }
@@ -1170,9 +1172,10 @@
 MVT RISCVTargetLowering::getRegisterTypeForCallingConv(LLVMContext &Context,
                                                       CallingConv::ID CC,
                                                       EVT VT) const {
-  // Use f32 to pass f16 if it is legal and Zfh is not enabled. We might still
-  // end up using a GPR but that will be decided based on ABI.
-  if (VT == MVT::f16 && Subtarget.hasStdExtF() && !Subtarget.hasStdExtZfh())
+  // Use f32 to pass f16 if it is legal and Zfhmin/Zfh is not enabled.
+  // We might still end up using a GPR but that will be decided based on ABI.
+  if (VT == MVT::f16 && Subtarget.hasStdExtF() &&
+      !Subtarget.hasStdExtZfhmin() && !Subtarget.hasStdExtZfh())
     return MVT::f32;
 
   return TargetLowering::getRegisterTypeForCallingConv(Context, CC, VT);
@@ -1181,9 +1184,10 @@
 unsigned RISCVTargetLowering::getNumRegistersForCallingConv(LLVMContext &Context,
                                                            CallingConv::ID CC,
                                                            EVT VT) const {
-  // Use f32 to pass f16 if it is legal and Zfh is not enabled. We might still
-  // end up using a GPR but that will be decided based on ABI.
-  if (VT == MVT::f16 && Subtarget.hasStdExtF() && !Subtarget.hasStdExtZfh())
+  // Use f32 to pass f16 if it is legal and Zfhmin/Zfh is not enabled.
+  // We might still end up using a GPR but that will be decided based on ABI.
+  if (VT == MVT::f16 && Subtarget.hasStdExtF() &&
+      !Subtarget.hasStdExtZfhmin() && !Subtarget.hasStdExtZfh())
     return 1;
 
   return TargetLowering::getNumRegistersForCallingConv(Context, CC, VT);
@@ -1347,7 +1351,7 @@
     return true;
 
   if (ScalarTy->isHalfTy())
-    return Subtarget.hasStdExtZfh();
+    return Subtarget.hasStdExtZfhmin() || Subtarget.hasStdExtZfh();
   if (ScalarTy->isFloatTy())
     return Subtarget.hasStdExtF();
   if (ScalarTy->isDoubleTy())
@@ -1390,7 +1394,7 @@
   case MVT::i64:
     break;
   case MVT::f16:
-    if (!Subtarget.hasStdExtZfh())
+    if (!Subtarget.hasStdExtZfh() && !Subtarget.hasStdExtZfh())
       return false;
     break;
   case MVT::f32:
@@ -2400,7 +2404,8 @@
       return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, BVec,
                          DAG.getConstant(0, DL, XLenVT));
     }
-    if (VT == MVT::f16 && Op0VT == MVT::i16 && Subtarget.hasStdExtZfh()) {
+    if (VT == MVT::f16 && Op0VT == MVT::i16 &&
+        (Subtarget.hasStdExtZfh() || Subtarget.hasStdExtZfh())) {
       SDValue NewOp0 = DAG.getNode(ISD::ANY_EXTEND, DL, XLenVT, Op0);
       SDValue FPConv = DAG.getNode(RISCVISD::FMV_H_X, DL, MVT::f16, NewOp0);
       return FPConv;
@@ -5668,7 +5673,8 @@
     SDValue Op0 = N->getOperand(0);
     EVT Op0VT = Op0.getValueType();
     MVT XLenVT = Subtarget.getXLenVT();
-    if (VT == MVT::i16 && Op0VT == MVT::f16 && Subtarget.hasStdExtZfh()) {
+    if (VT == MVT::i16 && Op0VT == MVT::f16 &&
+        (Subtarget.hasStdExtZfhmin() || Subtarget.hasStdExtZfh())) {
       SDValue FPConv = DAG.getNode(RISCVISD::FMV_X_ANYEXTH, DL, XLenVT, Op0);
       Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i16, FPConv));
     } else if (VT == MVT::i32 && Op0VT == MVT::f32 && Subtarget.is64Bit() &&
@@ -9286,7 +9292,8 @@
     case 'r':
       return std::make_pair(0U, &RISCV::GPRRegClass);
     case 'f':
-      if (Subtarget.hasStdExtZfh() && VT == MVT::f16)
+      if ((Subtarget.hasStdExtZfhmin() || Subtarget.hasStdExtZfh()) &&
+          VT == MVT::f16)
         return std::make_pair(0U, &RISCV::FPR16RegClass);
       if (Subtarget.hasStdExtF() && VT == MVT::f32)
         return std::make_pair(0U, &RISCV::FPR32RegClass);
@@ -9688,7 +9695,7 @@
 
   switch (VT.getSimpleVT().SimpleTy) {
   case MVT::f16:
-    return Subtarget.hasStdExtZfh();
+    return Subtarget.hasStdExtZfhmin() || Subtarget.hasStdExtZfh();
   case MVT::f32:
     return Subtarget.hasStdExtF();
   case MVT::f64:
Index: llvm/lib/Target/RISCV/RISCV.td
===================================================================
--- llvm/lib/Target/RISCV/RISCV.td
+++ llvm/lib/Target/RISCV/RISCV.td
@@ -41,10 +41,18 @@
                            AssemblerPredicate<(all_of FeatureStdExtD),
                            "'D' (Double-Precision Floating-Point)">;
 
+def FeatureStdExtZfhmin
+    : SubtargetFeature<"experimental-zfhmin", "HasStdExtZfhmin", "true",
+                       "'Zfhmin' (Half-Precision Floating-Point Minimal)",
+                       [FeatureStdExtF]>;
+def HasStdExtZfhmin : Predicate<"Subtarget->hasStdExtZfhmin()">,
+                             AssemblerPredicate<(all_of FeatureStdExtZfhmin),
+                             "'Zfhmin' (Half-Precision Floating-Point Minimal)">;
+
 def FeatureStdExtZfh
     : SubtargetFeature<"experimental-zfh", "HasStdExtZfh", "true",
                        "'Zfh' (Half-Precision Floating-Point)",
-                       [FeatureStdExtF]>;
+                       [FeatureStdExtZfhmin, FeatureStdExtF]>;
 def HasStdExtZfh : Predicate<"Subtarget->hasStdExtZfh()">,
                              AssemblerPredicate<(all_of FeatureStdExtZfh),
                              "'Zfh' (Half-Precision Floating-Point)">;
Index: llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
===================================================================
--- llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -2070,6 +2070,7 @@
     clearFeatureBits(RISCV::FeatureStdExtC, "c");
     clearFeatureBits(RISCV::FeatureStdExtV, "experimental-v");
     clearFeatureBits(RISCV::FeatureStdExtZfh, "experimental-zfh");
+    clearFeatureBits(RISCV::FeatureStdExtZfhmin, "experimental-zfhmin");
     clearFeatureBits(RISCV::FeatureStdExtZba, "experimental-zba");
     clearFeatureBits(RISCV::FeatureStdExtZbb, "experimental-zbb");
     clearFeatureBits(RISCV::FeatureStdExtZbc, "experimental-zbc");
@@ -2133,6 +2134,8 @@
           setFeatureBits(RISCV::FeatureStdExtZbt, "experimental-zbt");
         else if (Ext == "zfh")
           setFeatureBits(RISCV::FeatureStdExtZfh, "experimental-zfh");
+        else if (Ext == "zfhmin")
+          setFeatureBits(RISCV::FeatureStdExtZfhmin, "experimental-zfhmin");
         else if (Ext == "zvamo")
           setFeatureBits(RISCV::FeatureStdExtZvamo, "experimental-zvamo");
         else if (Ext == "zvlsseg")
@@ -2183,6 +2186,8 @@
         formalArchStr = (Twine(formalArchStr) + "_v0p10").str();
       if (getFeatureBits(RISCV::FeatureStdExtZfh))
         formalArchStr = (Twine(formalArchStr) + "_zfh0p1").str();
+      if (getFeatureBits(RISCV::FeatureStdExtZfhmin))
+        formalArchStr = (Twine(formalArchStr) + "_zfhmin0p1").str();
       if (getFeatureBits(RISCV::FeatureStdExtZba))
         formalArchStr = (Twine(formalArchStr) + "_zba1p0").str();
       if (getFeatureBits(RISCV::FeatureStdExtZbb))
Index: clang/test/Driver/riscv-arch.c
===================================================================
--- clang/test/Driver/riscv-arch.c
+++ clang/test/Driver/riscv-arch.c
@@ -432,6 +432,15 @@
 // RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-EXPERIMENTAL-ZFH %s
 // RV32-EXPERIMENTAL-ZFH: "-target-feature" "+experimental-zfh"
 
+// RUN: %clang -target riscv32-unknown-elf -march=rv32izfhmin -### %s \
+// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-EXPERIMENTAL-ZFHMIN-NOFLAG %s
+// RV32-EXPERIMENTAL-ZFHMIN-NOFLAG: error: invalid arch name 'rv32izfhmin'
+// RV32-EXPERIMENTAL-ZFHMIN-NOFLAG: requires '-menable-experimental-extensions'
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32izfhmin0p1 -menable-experimental-extensions -### %s \
+// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-EXPERIMENTAL-ZFHMIN %s
+// RV32-EXPERIMENTAL-ZFHMIN: "-target-feature" "+experimental-zfhmin"
+
 // RUN: %clang -target riscv32-unknown-elf -march=rv32izvamo -### %s -c 2>&1 | \
 // RUN:   FileCheck -check-prefix=RV32-EXPERIMENTAL-ZVAMO-NOFLAG %s
 // RV32-EXPERIMENTAL-ZVAMO-NOFLAG: error: invalid arch name 'rv32izvamo'
Index: clang/lib/Driver/ToolChains/Arch/RISCV.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Arch/RISCV.cpp
+++ clang/lib/Driver/ToolChains/Arch/RISCV.cpp
@@ -65,7 +65,7 @@
     return RISCVExtensionVersion{"0", "93"};
   if (Ext == "v" || Ext == "zvamo" || Ext == "zvlsseg")
     return RISCVExtensionVersion{"0", "10"};
-  if (Ext == "zfh")
+  if (Ext == "zfh" || Ext == "zfhmin")
     return RISCVExtensionVersion{"0", "1"};
   return None;
 }
Index: clang/lib/Basic/Targets/RISCV.h
===================================================================
--- clang/lib/Basic/Targets/RISCV.h
+++ clang/lib/Basic/Targets/RISCV.h
@@ -42,6 +42,7 @@
   bool HasZbs = false;
   bool HasZbt = false;
   bool HasZfh = false;
+  bool HasZfhmin = false;
   bool HasZvamo = false;
   bool HasZvlsseg = false;
 
Index: clang/lib/Basic/Targets/RISCV.cpp
===================================================================
--- clang/lib/Basic/Targets/RISCV.cpp
+++ clang/lib/Basic/Targets/RISCV.cpp
@@ -211,7 +211,7 @@
   if (HasZbt)
     Builder.defineMacro("__riscv_zbt", "93000");
 
-  if (HasZfh)
+  if (HasZfh || HasZfhmin)
     Builder.defineMacro("__riscv_zfh", "1000");
 
   if (HasZvamo)
@@ -269,6 +269,7 @@
       .Case("experimental-zbs", HasZbs)
       .Case("experimental-zbt", HasZbt)
       .Case("experimental-zfh", HasZfh)
+      .Case("experimental-zfhmin", HasZfhmin)
       .Case("experimental-zvamo", HasZvamo)
       .Case("experimental-zvlsseg", HasZvlsseg)
       .Default(false);
@@ -312,6 +313,8 @@
       HasZbt = true;
     else if (Feature == "+experimental-zfh")
       HasZfh = true;
+    else if (Feature == "+experimental-zfhmin")
+      HasZfhmin = true;
     else if (Feature == "+experimental-zvamo")
       HasZvamo = true;
     else if (Feature == "+experimental-zvlsseg")
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to