[llvm] 0b9a620 - [RISCV] Support assembler and dis-assembler for VCIX extension.

via llvm-commits llvm-commits at lists.llvm.org
Sun Apr 9 20:41:22 PDT 2023


Author: Nelson Chu
Date: 2023-04-09T20:41:01-07:00
New Revision: 0b9a620b832e3a493de0e550ac00a1903129092d

URL: https://github.com/llvm/llvm-project/commit/0b9a620b832e3a493de0e550ac00a1903129092d
DIFF: https://github.com/llvm/llvm-project/commit/0b9a620b832e3a493de0e550ac00a1903129092d.diff

LOG: [RISCV] Support assembler and dis-assembler for VCIX extension.

Spec: https://sifive.cdn.prismic.io/sifive/c3829e36-8552-41f0-a841-79945784241b_vcix-spec-software.pdf

Differential Revision: https://reviews.llvm.org/D144530

Added: 
    llvm/lib/Target/RISCV/RISCVInstrInfoXSf.td
    llvm/test/MC/RISCV/rvv/xsfvcp-invalid.s
    llvm/test/MC/RISCV/rvv/xsfvcp.s

Modified: 
    llvm/docs/RISCVUsage.rst
    llvm/docs/ReleaseNotes.rst
    llvm/lib/Support/RISCVISAInfo.cpp
    llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
    llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
    llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
    llvm/lib/Target/RISCV/RISCVFeatures.td
    llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
    llvm/lib/Target/RISCV/RISCVInstrInfo.td
    llvm/test/MC/RISCV/attribute-arch.s

Removed: 
    


################################################################################
diff  --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 2a9321c113258..e9a786eaa4146 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -253,3 +253,6 @@ The current vendor extensions supported are:
 
 ``XVentanaCondOps``
   LLVM implements `version 1.0.0 of the VTx-family custom instructions specification <https://github.com/ventanamicro/ventana-custom-extensions/releases/download/v1.0.0/ventana-custom-extensions-v1.0.0.pdf>`_ by Ventana Micro Systems.  All instructions are prefixed with `vt.` as described in the specification, and the riscv-toolchain-convention document linked above.  These instructions are only available for riscv64 at this time.
+
+``XSfvcp``
+  LLVM implements `version 1.0.0 of the SiFive Vector Coprocessor Interface (VCIX) Software Specification <https://sifive.cdn.prismic.io/sifive/c3829e36-8552-41f0-a841-79945784241b_vcix-spec-software.pdf>`_ by SiFive.  All instructions are prefixed with `sf.vc.` as described in the specification, and the riscv-toolchain-convention document linked above.

diff  --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index 9dd2d4300a2f0..88d43a3befa5e 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -149,6 +149,8 @@ Changes to the RISC-V Backend
   extension disassembler/assembler.
 * Added support for the vendor-defined XTHeadMemIdx (indexed memory operations)
   extension disassembler/assembler.
+* Added support for the vendor-defined Xsfvcp (SiFive VCIX) extension
+  disassembler/assembler.
 * Support for the now-ratified Zawrs extension is no longer experimental.
 * Adds support for the vendor-defined XTHeadCmo (cache management operations) extension.
 * Adds support for the vendor-defined XTHeadSync (multi-core synchronization instructions) extension.

diff  --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp
index e890cca0d9062..9adcd925658d4 100644
--- a/llvm/lib/Support/RISCVISAInfo.cpp
+++ b/llvm/lib/Support/RISCVISAInfo.cpp
@@ -117,6 +117,7 @@ static const RISCVSupportedExtension SupportedExtensions[] = {
     {"svinval", RISCVExtensionVersion{1, 0}},
 
     // vendor-defined ('X') extensions
+    {"xsfvcp", RISCVExtensionVersion{1, 0}},
     {"xtheadba", RISCVExtensionVersion{1, 0}},
     {"xtheadbb", RISCVExtensionVersion{1, 0}},
     {"xtheadbs", RISCVExtensionVersion{1, 0}},
@@ -935,6 +936,7 @@ static const char *ImpliedExtsZvfh[] = {"zve32f"};
 static const char *ImpliedExtsZvkn[] = {"zvkned", "zvknhb", "zvkb"};
 static const char *ImpliedExtsZvknhb[] = {"zvknha"};
 static const char *ImpliedExtsZvks[] = {"zvksed", "zvksh", "zvkb"};
+static const char *ImpliedExtsXsfvcp[] = {"zve32x"};
 static const char *ImpliedExtsXTHeadVdot[] = {"v"};
 static const char *ImpliedExtsZcb[] = {"zca"};
 static const char *ImpliedExtsZfa[] = {"f"};
@@ -955,6 +957,7 @@ static constexpr ImpliedExtsEntry ImpliedExts[] = {
     {{"d"}, {ImpliedExtsD}},
     {{"f"}, {ImpliedExtsF}},
     {{"v"}, {ImpliedExtsV}},
+    {{"xsfvcp"}, {ImpliedExtsXsfvcp}},
     {{"xtheadvdot"}, {ImpliedExtsXTHeadVdot}},
     {{"zcb"}, {ImpliedExtsZcb}},
     {{"zdinx"}, {ImpliedExtsZdinx}},

diff  --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 03e97f9cb669f..c29deb2ef4135 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -575,6 +575,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
     return IsConstantImm && isUInt<N>(Imm) && VK == RISCVMCExpr::VK_RISCV_None;
   }
 
+  bool isUImm1() const { return IsUImm<1>(); }
   bool isUImm2() const { return IsUImm<2>(); }
   bool isUImm3() const { return IsUImm<3>(); }
   bool isUImm4() const { return IsUImm<4>(); }
@@ -1253,6 +1254,8 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
     if (isRV64())
       return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
+  case Match_InvalidUImm1:
+    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1);
   case Match_InvalidUImm2:
     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1);
   case Match_InvalidUImm2Lsb0:
@@ -2933,6 +2936,26 @@ bool RISCVAsmParser::validateInstruction(MCInst &Inst,
   if (Constraints == RISCVII::NoConstraint)
     return false;
 
+  if (Opcode == RISCV::VC_V_XVW || Opcode == RISCV::VC_V_IVW ||
+      Opcode == RISCV::VC_V_FVW || Opcode == RISCV::VC_V_VVW) {
+    // Operands Opcode, Dst, uimm, Dst, Rs2, Rs1 for VC_V_XVW.
+    unsigned VCIXDst = Inst.getOperand(0).getReg();
+    SMLoc VCIXDstLoc = Operands[2]->getStartLoc();
+    if (Constraints & RISCVII::VS1Constraint) {
+      unsigned VCIXRs1 = Inst.getOperand(Inst.getNumOperands() - 1).getReg();
+      if (VCIXDst == VCIXRs1)
+        return Error(VCIXDstLoc, "The destination vector register group cannot"
+                                 " overlap the source vector register group.");
+    }
+    if (Constraints & RISCVII::VS2Constraint) {
+      unsigned VCIXRs2 = Inst.getOperand(Inst.getNumOperands() - 2).getReg();
+      if (VCIXDst == VCIXRs2)
+        return Error(VCIXDstLoc, "The destination vector register group cannot"
+                                 " overlap the source vector register group.");
+    }
+    return false;
+  }
+
   unsigned DestReg = Inst.getOperand(0).getReg();
   // Operands[1] will be the first operand, DestReg.
   SMLoc Loc = Operands[1]->getStartLoc();

diff  --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index b6e58389ad98d..2121a0e9feabc 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -576,6 +576,13 @@ DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
       if (Result != MCDisassembler::Fail)
         return Result;
     }
+    if (STI.hasFeature(RISCV::FeatureVendorXSfvcp)) {
+      LLVM_DEBUG(dbgs() << "Trying SiFive VCIX custom opcode table:\n");
+      Result = decodeInstruction(DecoderTableXSfvcp32, MI, Insn, Address, this,
+                                 STI);
+      if (Result != MCDisassembler::Fail)
+        return Result;
+    }
 
     LLVM_DEBUG(dbgs() << "Trying RISCV32 table :\n");
     return decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI);

diff  --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index 0e3a85428ab14..a6aeb80643a6e 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -240,7 +240,8 @@ enum {
 namespace RISCVOp {
 enum OperandType : unsigned {
   OPERAND_FIRST_RISCV_IMM = MCOI::OPERAND_FIRST_TARGET,
-  OPERAND_UIMM2 = OPERAND_FIRST_RISCV_IMM,
+  OPERAND_UIMM1 = OPERAND_FIRST_RISCV_IMM,
+  OPERAND_UIMM2,
   OPERAND_UIMM2_LSB0,
   OPERAND_UIMM3,
   OPERAND_UIMM4,

diff  --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 0d44f576c64bd..b761c99faa93f 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -635,6 +635,14 @@ def HasVendorXTHeadVdot : Predicate<"Subtarget->hasVendorXTHeadVdot()">,
                                     AssemblerPredicate<(all_of FeatureVendorXTHeadVdot),
                                     "'xtheadvdot' (T-Head Vector Extensions for Dot)">;
 
+def FeatureVendorXSfvcp
+    : SubtargetFeature<"xsfvcp", "HasVendorXSfvcp", "true",
+                       "XSfvcp (SiFive Custom Vector Coprocessor Interface Instructions)",
+                       [FeatureStdExtZve32x]>;
+def HasVendorXSfvcp : Predicate<"Subtarget->hasVendorXSfvcp()">,
+                                AssemblerPredicate<(all_of FeatureVendorXSfvcp),
+                                "'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions)">;
+
 //===----------------------------------------------------------------------===//
 // LLVM specific features and extensions
 //===----------------------------------------------------------------------===//

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index 17b5c790711eb..0dd1a8db4cfca 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -1682,6 +1682,7 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
   case RISCVOp::OPERAND_UIMM##NUM:                                             \
     Ok = isUInt<NUM>(Imm);                                                     \
     break;
+        CASE_OPERAND_UIMM(1)
         CASE_OPERAND_UIMM(2)
         CASE_OPERAND_UIMM(3)
         CASE_OPERAND_UIMM(4)

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index fc21af37d0bc5..0e52b133b4db2 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -191,6 +191,13 @@ def uimmlog2xlen : Operand<XLenVT>, ImmLeaf<XLenVT, [{
   let OperandNamespace = "RISCVOp";
 }
 
+def uimm1 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isUInt<1>(Imm);}]> {
+  let ParserMatchClass = UImmAsmOperand<1>;
+  let DecoderMethod = "decodeUImmOperand<1>";
+  let OperandType = "OPERAND_UIMM1";
+  let OperandNamespace = "RISCVOp";
+}
+
 def uimm2 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isUInt<2>(Imm);}]> {
   let ParserMatchClass = UImmAsmOperand<2>;
   let DecoderMethod = "decodeUImmOperand<2>";
@@ -1921,3 +1928,4 @@ include "RISCVInstrInfoZicond.td"
 include "RISCVInstrInfoXVentana.td"
 include "RISCVInstrInfoXTHead.td"
 include "RISCVInstrInfoZihintntl.td"
+include "RISCVInstrInfoXSf.td"

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXSf.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXSf.td
new file mode 100644
index 0000000000000..dd68318716211
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXSf.td
@@ -0,0 +1,162 @@
+//===-- RISCVInstrInfoXsf.td - SiFive custom instructions --*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the vendor extensions defined by SiFive.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// XSFVCP extension instructions.
+//===----------------------------------------------------------------------===//
+
+def VCIXVS2    : RISCVVConstraint<VS2Constraint.Value>;
+def VCIXVS2VS1 : RISCVVConstraint<!or(VS2Constraint.Value,
+                                      VS1Constraint.Value)>;
+
+class VCIXType<bits<4> val> {
+  bits<4> Val = val;
+}
+
+def VCIX_X   : VCIXType<0b0000>;
+def VCIX_XV  : VCIXType<0b0010>;
+def VCIX_XVV : VCIXType<0b1010>;
+def VCIX_XVW : VCIXType<0b1111>;
+
+class SwapVCIXIns<dag funct6, dag rd, dag rs2, dag rs1, bit swap> {
+  dag Ins = !con(funct6, !if(swap, rs2, rd), !if(swap, rd, rs2), rs1);
+}
+
+class RVInstVCCustom2<bits<4> funct6_hi4, bits<3> funct3, dag outs, dag ins,
+                      string opcodestr, string argstr>
+    : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> {
+  bits<5> rs2;
+  bits<5> rs1;
+  bits<5> rd;
+  bits<2> funct6_lo2;
+  bit vm;
+
+  let Inst{31-28} = funct6_hi4;
+  let Inst{27-26} = funct6_lo2;
+  let Inst{25} = vm;
+  let Inst{24-20} = rs2;
+  let Inst{19-15} = rs1;
+  let Inst{14-12} = funct3;
+  let Inst{11-7} = rd;
+  let Opcode = OPC_CUSTOM_2.Value;
+
+  let Uses = [VTYPE, VL];
+  let RVVConstraint = NoConstraint;
+}
+
+class RVInstVCFCustom2<bits<4> funct6_hi4, bits<3> funct3, dag outs, dag ins,
+                       string opcodestr, string argstr>
+    : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> {
+  bits<5> rs2;
+  bits<5> rs1;
+  bits<5> rd;
+  bit funct6_lo1;
+  bit vm;
+
+  let Inst{31-28} = funct6_hi4;
+  let Inst{27} = 1;
+  let Inst{26} = funct6_lo1;
+  let Inst{25} = vm;
+  let Inst{24-20} = rs2;
+  let Inst{19-15} = rs1;
+  let Inst{14-12} = funct3;
+  let Inst{11-7} = rd;
+  let Opcode = OPC_CUSTOM_2.Value;
+
+  let Uses = [VTYPE, VL];
+  let RVVConstraint = NoConstraint;
+}
+
+class VCIXInfo<string suffix, VCIXType type, DAGOperand TyRd,
+               DAGOperand TyRs2, DAGOperand TyRs1, bit HaveOutputDst> {
+  string OpcodeStr = !if(HaveOutputDst, "sf.vc.v." # suffix,
+                                        "sf.vc." # suffix);
+  bits<4> Funct6_hi4 = type.Val;
+  bits<3> Funct3 = !cond(!eq(TyRs1, VR):    0b000,
+                         !eq(TyRs1, GPR):   0b100,
+                         !eq(TyRs1, FPR32): 0b101,
+                         !eq(TyRs1, simm5): 0b011);
+  dag Outs = !if(!not(HaveOutputDst), (outs),
+                 !if(!or(!eq(type, VCIX_XVV), !eq(type, VCIX_XVW)),
+                     (outs TyRd:$rd_wb), (outs TyRd:$rd)));
+  dag Ins = SwapVCIXIns<!if(!ne(TyRs1, FPR32), (ins uimm2:$funct6_lo2),
+                                               (ins uimm1:$funct6_lo1)),
+                        !if(!and(HaveOutputDst, !or(!eq(type, VCIX_X),
+                                                    !eq(type, VCIX_XV))),
+                            (ins), (ins TyRd:$rd)),
+                        (ins TyRs2:$rs2),
+                        (ins TyRs1:$rs1),
+                        !if(!eq(type, VCIX_X), 1, 0)>.Ins;
+  string Prototype = !if(!eq(type, VCIX_X), "$funct6_lo2, $rs2, $rd, $rs1",
+                         !if(!ne(TyRs1, FPR32), "$funct6_lo2, $rd, $rs2, $rs1",
+                                                "$funct6_lo1, $rd, $rs2, $rs1"));
+  string Constraints = !if(!not(HaveOutputDst), "",
+                           !if(!or(!eq(type, VCIX_XVV),
+                                   !eq(type, VCIX_XVW)), "$rd = $rd_wb", ""));
+  RISCVVConstraint RVVConstraint = !if(!or(!not(HaveOutputDst),
+                                           !ne(type, VCIX_XVW)), NoConstraint,
+                                       !if(!eq(TyRs1, VR), VCIXVS2VS1, VCIXVS2));
+}
+
+class CustomSiFiveVCIX<VCIXInfo info>
+  : RVInstVCCustom2<info.Funct6_hi4, info.Funct3, info.Outs,
+                    info.Ins, info.OpcodeStr, info.Prototype> {
+  let Constraints = info.Constraints;
+  let RVVConstraint = info.RVVConstraint;
+}
+
+class CustomSiFiveVCIF<VCIXInfo info>
+  : RVInstVCFCustom2<info.Funct6_hi4, info.Funct3, info.Outs,
+                     info.Ins, info.OpcodeStr, info.Prototype> {
+  let Constraints = info.Constraints;
+  let RVVConstraint = info.RVVConstraint;
+}
+
+multiclass CustomSiFiveVCIXorVCIF<string suffix, VCIXType type,
+                                  DAGOperand TyRd, DAGOperand TyRs2,
+                                  DAGOperand TyRs1, bit HaveOutputDst> {
+  defvar info = VCIXInfo<suffix, type, TyRd, TyRs2, TyRs1, HaveOutputDst>;
+  if !eq(TyRs1, FPR32) then {
+    def NAME : CustomSiFiveVCIF<info>;
+  } else {
+    def NAME : CustomSiFiveVCIX<info>;
+  }
+}
+
+multiclass CustomSiFiveVCIX<string suffix, VCIXType type,
+                            DAGOperand InTyRd, DAGOperand InTyRs2,
+                            DAGOperand InTyRs1> {
+  let vm = 1 in
+  defm VC_ # NAME   : CustomSiFiveVCIXorVCIF<suffix, type, InTyRd, InTyRs2,
+                                             InTyRs1, 0>;
+  let vm = 0 in
+  defm VC_V_ # NAME : CustomSiFiveVCIXorVCIF<suffix, type, VR, InTyRs2,
+                                             InTyRs1, 1>;
+}
+
+let Predicates = [HasVendorXSfvcp], mayLoad = 0, mayStore = 0,
+    hasSideEffects = 1, hasNoSchedulingInfo = 1, DecoderNamespace = "XSfvcp" in {
+  defm X   : CustomSiFiveVCIX<"x",   VCIX_X,   uimm5, uimm5, GPR>,   Sched<[]>;
+  defm I   : CustomSiFiveVCIX<"i",   VCIX_X,   uimm5, uimm5, simm5>, Sched<[]>;
+  defm XV  : CustomSiFiveVCIX<"xv",  VCIX_XV,  uimm5, VR,    GPR>,   Sched<[]>;
+  defm IV  : CustomSiFiveVCIX<"iv",  VCIX_XV,  uimm5, VR,    simm5>, Sched<[]>;
+  defm VV  : CustomSiFiveVCIX<"vv",  VCIX_XV,  uimm5, VR,    VR>,    Sched<[]>;
+  defm FV  : CustomSiFiveVCIX<"fv",  VCIX_XV,  uimm5, VR,    FPR32>, Sched<[]>;
+  defm XVV : CustomSiFiveVCIX<"xvv", VCIX_XVV, VR,    VR,    GPR>,   Sched<[]>;
+  defm IVV : CustomSiFiveVCIX<"ivv", VCIX_XVV, VR,    VR,    simm5>, Sched<[]>;
+  defm VVV : CustomSiFiveVCIX<"vvv", VCIX_XVV, VR,    VR,    VR>,    Sched<[]>;
+  defm FVV : CustomSiFiveVCIX<"fvv", VCIX_XVV, VR,    VR,    FPR32>, Sched<[]>;
+  defm XVW : CustomSiFiveVCIX<"xvw", VCIX_XVW, VR,    VR,    GPR>,   Sched<[]>;
+  defm IVW : CustomSiFiveVCIX<"ivw", VCIX_XVW, VR,    VR,    simm5>, Sched<[]>;
+  defm VVW : CustomSiFiveVCIX<"vvw", VCIX_XVW, VR,    VR,    VR>,    Sched<[]>;
+  defm FVW : CustomSiFiveVCIX<"fvw", VCIX_XVW, VR,    VR,    FPR32>, Sched<[]>;
+}

diff  --git a/llvm/test/MC/RISCV/attribute-arch.s b/llvm/test/MC/RISCV/attribute-arch.s
index 64a4d92f31451..9daad8f790bca 100644
--- a/llvm/test/MC/RISCV/attribute-arch.s
+++ b/llvm/test/MC/RISCV/attribute-arch.s
@@ -219,6 +219,9 @@
 .attribute arch, "rv32izcb1p0"
 # CHECK: attribute      5, "rv32i2p1_zca1p0_zcb1p0"
 
+.attribute arch, "rv64i_xsfvcp"
+# CHECK: attribute      5, "rv64i2p1_zicsr2p0_zve32x1p0_zvl32b1p0_xsfvcp1p0"
+
 .attribute arch, "rv32izawrs1p0"
 # CHECK: attribute      5, "rv32i2p1_zawrs1p0"
 

diff  --git a/llvm/test/MC/RISCV/rvv/xsfvcp-invalid.s b/llvm/test/MC/RISCV/rvv/xsfvcp-invalid.s
new file mode 100644
index 0000000000000..52dc32b8c6a8d
--- /dev/null
+++ b/llvm/test/MC/RISCV/rvv/xsfvcp-invalid.s
@@ -0,0 +1,20 @@
+# RUN: not llvm-mc -triple=riscv32 --mattr=+v,+xsfvcp %s 2>&1 \
+# RUN:        | FileCheck %s --check-prefix=CHECK-ERROR
+# RUN: not llvm-mc -triple=riscv64 --mattr=+v,+xsfvcp %s 2>&1 \
+# RUN:        | FileCheck %s --check-prefix=CHECK-ERROR
+
+sf.vc.v.vvw 0x3, v0, v2, v0
+# CHECK-ERROR: The destination vector register group cannot overlap the source vector register group.{{$}}
+# CHECK-ERROR-LABEL: sf.vc.v.vvw 0x3, v0, v2, v0{{$}}
+
+sf.vc.v.xvw 0x3, v0, v0, a1
+# CHECK-ERROR: The destination vector register group cannot overlap the source vector register group.{{$}}
+# CHECK-ERROR-LABEL: sf.vc.v.xvw 0x3, v0, v0, a1{{$}}
+
+sf.vc.v.ivw 0x3, v0, v0, 15
+# CHECK-ERROR: The destination vector register group cannot overlap the source vector register group.{{$}}
+# CHECK-ERROR-LABEL: sf.vc.v.ivw 0x3, v0, v0, 15{{$}}
+
+sf.vc.v.fvw 0x1, v0, v0, fa1
+# CHECK-ERROR: The destination vector register group cannot overlap the source vector register group.{{$}}
+# CHECK-ERROR-LABEL: sf.vc.v.fvw 0x1, v0, v0, fa1{{$}}

diff  --git a/llvm/test/MC/RISCV/rvv/xsfvcp.s b/llvm/test/MC/RISCV/rvv/xsfvcp.s
new file mode 100644
index 0000000000000..6ba67850281bc
--- /dev/null
+++ b/llvm/test/MC/RISCV/rvv/xsfvcp.s
@@ -0,0 +1,186 @@
+# RUN: llvm-mc -triple=riscv32 -show-encoding --mattr=+v,+xsfvcp %s \
+# RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+# RUN: llvm-mc -triple=riscv64 -show-encoding --mattr=+v,+xsfvcp %s \
+# RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+# RUN: not llvm-mc -triple=riscv32 -show-encoding %s 2>&1 \
+# RUN:        | FileCheck %s --check-prefix=CHECK-ERROR
+# RUN: not llvm-mc -triple=riscv64 -show-encoding %s 2>&1 \
+# RUN:        | FileCheck %s --check-prefix=CHECK-ERROR
+# RUN: llvm-mc -triple=riscv32 -filetype=obj --mattr=+v,+xsfvcp %s \
+# RUN:        | llvm-objdump -d --mattr=+v,+xsfvcp - \
+# RUN:        | FileCheck %s --check-prefix=CHECK-INST
+# RUN: llvm-mc -triple=riscv64 -filetype=obj --mattr=+v,+xsfvcp %s \
+# RUN:        | llvm-objdump -d --mattr=+v,+xsfvcp - \
+# RUN:        | FileCheck %s --check-prefix=CHECK-INST
+# RUN: llvm-mc -triple=riscv32 -filetype=obj --mattr=+v,+xsfvcp %s \
+# RUN:        | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+# RUN: llvm-mc -triple=riscv64 -filetype=obj --mattr=+v,+xsfvcp %s \
+# RUN:        | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+
+sf.vc.x 0x3, 0xf, 0x1f, a1
+# CHECK-INST: sf.vc.x 3, 15, 31, a1
+# CHECK-ENCODING: [0xdb,0xcf,0xf5,0x0e]
+# CHECK-ERROR: instruction requires the following: 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions){{$}}
+# CHECK-UNKNOWN: db cf f5 0e <unknown>
+
+sf.vc.i 0x3, 0xf, 0x1f, 15
+# CHECK-INST: sf.vc.i 3, 15, 31, 15
+# CHECK-ENCODING: [0xdb,0xbf,0xf7,0x0e]
+# CHECK-ERROR: instruction requires the following: 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions){{$}}
+# CHECK-UNKNOWN: db bf f7 0e <unknown>
+
+sf.vc.vv 0x3, 0x1f, v2, v1
+# CHECK-INST: sf.vc.vv 3, 31, v2, v1
+# CHECK-ENCODING: [0xdb,0x8f,0x20,0x2e]
+# CHECK-ERROR: instruction requires the following: 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions){{$}}
+# CHECK-UNKNOWN: db 8f 20 2e <unknown>
+
+sf.vc.xv 0x3, 0x1f, v2, a1
+# CHECK-INST: sf.vc.xv 3, 31, v2, a1
+# CHECK-ENCODING: [0xdb,0xcf,0x25,0x2e]
+# CHECK-ERROR: instruction requires the following: 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions){{$}}
+# CHECK-UNKNOWN: db cf 25 2e <unknown>
+
+sf.vc.iv 0x3, 0x1f, v2, 15
+# CHECK-INST: sf.vc.iv 3, 31, v2, 15
+# CHECK-ENCODING: [0xdb,0xbf,0x27,0x2e]
+# CHECK-ERROR: instruction requires the following: 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions){{$}}
+# CHECK-UNKNOWN: db bf 27 2e <unknown>
+
+sf.vc.fv 0x1, 0x1f, v2, fa1
+# CHECK-INST: sf.vc.fv 1, 31, v2, fa1
+# CHECK-ENCODING: [0xdb,0xdf,0x25,0x2e]
+# CHECK-ERROR: instruction requires the following: 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions){{$}}
+# CHECK-UNKNOWN: db df 25 2e <unknown>
+
+sf.vc.vvv 0x3, v0, v2, v1
+# CHECK-INST: sf.vc.vvv 3, v0, v2, v1
+# CHECK-ENCODING: [0x5b,0x80,0x20,0xae]
+# CHECK-ERROR: instruction requires the following: 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions){{$}}
+# CHECK-UNKNOWN: 5b 80 20 ae <unknown>
+
+sf.vc.xvv 0x3, v0, v2, a1
+# CHECK-INST: sf.vc.xvv 3, v0, v2, a1
+# CHECK-ENCODING: [0x5b,0xc0,0x25,0xae]
+# CHECK-ERROR: instruction requires the following: 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions){{$}}
+# CHECK-UNKNOWN: 5b c0 25 ae <unknown>
+
+sf.vc.ivv 0x3, v0, v2, 15
+# CHECK-INST: sf.vc.ivv 3, v0, v2, 15
+# CHECK-ENCODING: [0x5b,0xb0,0x27,0xae]
+# CHECK-ERROR: instruction requires the following: 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions){{$}}
+# CHECK-UNKNOWN: 5b b0 27 ae <unknown>
+
+sf.vc.fvv 0x1, v0, v2, fa1
+# CHECK-INST: sf.vc.fvv 1, v0, v2, fa1
+# CHECK-ENCODING: [0x5b,0xd0,0x25,0xae]
+# CHECK-ERROR: instruction requires the following: 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions){{$}}
+# CHECK-UNKNOWN: 5b d0 25 ae <unknown>
+
+sf.vc.vvw 0x3, v0, v2, v1
+# CHECK-INST: sf.vc.vvw 3, v0, v2, v1
+# CHECK-ENCODING: [0x5b,0x80,0x20,0xfe]
+# CHECK-ERROR: instruction requires the following: 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions){{$}}
+# CHECK-UNKNOWN: 5b 80 20 fe <unknown>
+
+sf.vc.xvw 0x3, v0, v2, a1
+# CHECK-INST: sf.vc.xvw 3, v0, v2, a1
+# CHECK-ENCODING: [0x5b,0xc0,0x25,0xfe]
+# CHECK-ERROR: instruction requires the following: 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions){{$}}
+# CHECK-UNKNOWN: 5b c0 25 fe <unknown>
+
+sf.vc.ivw 0x3, v0, v2, 15
+# CHECK-INST: sf.vc.ivw 3, v0, v2, 15
+# CHECK-ENCODING: [0x5b,0xb0,0x27,0xfe]
+# CHECK-ERROR: instruction requires the following: 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions){{$}}
+# CHECK-UNKNOWN: 5b b0 27 fe <unknown>
+
+sf.vc.fvw 0x1, v0, v2, fa1
+# CHECK-INST: sf.vc.fvw 1, v0, v2, fa1
+# CHECK-ENCODING: [0x5b,0xd0,0x25,0xfe]
+# CHECK-ERROR: instruction requires the following: 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions){{$}}
+# CHECK-UNKNOWN: 5b d0 25 fe <unknown>
+
+sf.vc.v.x 0x3, 0xf, v0, a1
+# CHECK-INST: sf.vc.v.x 3, 15, v0, a1
+# CHECK-ENCODING: [0x5b,0xc0,0xf5,0x0c]
+# CHECK-ERROR: instruction requires the following: 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions){{$}}
+# CHECK-UNKNOWN: 5b c0 f5 0c <unknown>
+
+sf.vc.v.i 0x3, 0xf, v0, 15
+# CHECK-INST: sf.vc.v.i 3, 15, v0, 15
+# CHECK-ENCODING: [0x5b,0xb0,0xf7,0x0c]
+# CHECK-ERROR: instruction requires the following: 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions){{$}}
+# CHECK-UNKNOWN: 5b b0 f7 0c <unknown>
+
+sf.vc.v.vv 0x3, v0, v2, v1
+# CHECK-INST: sf.vc.v.vv 3, v0, v2, v1
+# CHECK-ENCODING: [0x5b,0x80,0x20,0x2c]
+# CHECK-ERROR: instruction requires the following: 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions){{$}}
+# CHECK-UNKNOWN: 5b 80 20 2c <unknown>
+
+sf.vc.v.xv 0x3, v0, v2, a1
+# CHECK-INST: sf.vc.v.xv 3, v0, v2, a1
+# CHECK-ENCODING: [0x5b,0xc0,0x25,0x2c]
+# CHECK-ERROR: instruction requires the following: 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions){{$}}
+# CHECK-UNKNOWN: 5b c0 25 2c <unknown>
+
+sf.vc.v.iv 0x3, v0, v2, 15
+# CHECK-INST: sf.vc.v.iv 3, v0, v2, 15
+# CHECK-ENCODING: [0x5b,0xb0,0x27,0x2c]
+# CHECK-ERROR: instruction requires the following: 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions){{$}}
+# CHECK-UNKNOWN: 5b b0 27 2c <unknown>
+
+sf.vc.v.fv 0x1, v0, v2, fa1
+# CHECK-INST: sf.vc.v.fv 1, v0, v2, fa1
+# CHECK-ENCODING: [0x5b,0xd0,0x25,0x2c]
+# CHECK-ERROR: instruction requires the following: 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions){{$}}
+# CHECK-UNKNOWN: 5b d0 25 2c <unknown>
+
+sf.vc.v.vvv 0x3, v0, v2, v1
+# CHECK-INST: sf.vc.v.vvv 3, v0, v2, v1
+# CHECK-ENCODING: [0x5b,0x80,0x20,0xac]
+# CHECK-ERROR: instruction requires the following: 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions){{$}}
+# CHECK-UNKNOWN: 5b 80 20 ac <unknown>
+
+sf.vc.v.xvv 0x3, v0, v2, a1
+# CHECK-INST: sf.vc.v.xvv 3, v0, v2, a1
+# CHECK-ENCODING: [0x5b,0xc0,0x25,0xac]
+# CHECK-ERROR: instruction requires the following: 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions){{$}}
+# CHECK-UNKNOWN: 5b c0 25 ac <unknown>
+
+sf.vc.v.ivv 0x3, v0, v2, 15
+# CHECK-INST: sf.vc.v.ivv 3, v0, v2, 15
+# CHECK-ENCODING: [0x5b,0xb0,0x27,0xac]
+# CHECK-ERROR: instruction requires the following: 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions){{$}}
+# CHECK-UNKNOWN: 5b b0 27 ac <unknown>
+
+sf.vc.v.fvv 0x1, v0, v2, fa1
+# CHECK-INST: sf.vc.v.fvv 1, v0, v2, fa1
+# CHECK-ENCODING: [0x5b,0xd0,0x25,0xac]
+# CHECK-ERROR: instruction requires the following: 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions){{$}}
+# CHECK-UNKNOWN: 5b d0 25 ac <unknown>
+
+sf.vc.v.vvw 0x3, v0, v2, v1
+# CHECK-INST: sf.vc.v.vvw 3, v0, v2, v1
+# CHECK-ENCODING: [0x5b,0x80,0x20,0xfc]
+# CHECK-ERROR: instruction requires the following: 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions){{$}}
+# CHECK-UNKNOWN: 5b 80 20 fc <unknown>
+
+sf.vc.v.xvw 0x3, v0, v2, a1
+# CHECK-INST: sf.vc.v.xvw 3, v0, v2, a1
+# CHECK-ENCODING: [0x5b,0xc0,0x25,0xfc]
+# CHECK-ERROR: instruction requires the following: 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions){{$}}
+# CHECK-UNKNOWN: 5b c0 25 fc <unknown>
+
+sf.vc.v.ivw 0x3, v0, v2, 15
+# CHECK-INST: sf.vc.v.ivw 3, v0, v2, 15
+# CHECK-ENCODING: [0x5b,0xb0,0x27,0xfc]
+# CHECK-ERROR: instruction requires the following: 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions){{$}}
+# CHECK-UNKNOWN: 5b b0 27 fc <unknown>
+
+sf.vc.v.fvw 0x1, v0, v2, fa1
+# CHECK-INST: sf.vc.v.fvw 1, v0, v2, fa1
+# CHECK-ENCODING: [0x5b,0xd0,0x25,0xfc]
+# CHECK-ERROR: instruction requires the following: 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions){{$}}
+# CHECK-UNKNOWN: 5b d0 25 fc <unknown>


        


More information about the llvm-commits mailing list