[llvm] fae40bd - [RISCV] Add MC layer support for proposed Bit Manipulation extension (version 0.92)

Simon Cook via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 9 10:04:56 PDT 2020


Author: Paolo Savini
Date: 2020-04-09T18:04:22+01:00
New Revision: fae40bd5a1d4d0ef5f60d5a441757d39a06ce077

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

LOG: [RISCV] Add MC layer support for proposed Bit Manipulation extension (version 0.92)

This adds the instruction encoding and mnenomics for the proposed
RISC-V Bit Manipulation extension (version 0.92). It is implemented with
each category of instruction as its own target feature, with the 'b'
extension feature enabling all options. Since this extension is not yet
ratified, all target features are prefixed with 'experimental-' to note
their status.

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

Added: 
    llvm/lib/Target/RISCV/RISCVInstrInfoB.td
    llvm/test/MC/RISCV/compress-rv32b.s
    llvm/test/MC/RISCV/compress-rv64b.s
    llvm/test/MC/RISCV/rv32b-aliases-valid.s
    llvm/test/MC/RISCV/rv32zbb-invalid.s
    llvm/test/MC/RISCV/rv32zbb-valid.s
    llvm/test/MC/RISCV/rv32zbbp-invalid.s
    llvm/test/MC/RISCV/rv32zbbp-valid.s
    llvm/test/MC/RISCV/rv32zbc-invalid.s
    llvm/test/MC/RISCV/rv32zbc-valid.s
    llvm/test/MC/RISCV/rv32zbe-invalid.s
    llvm/test/MC/RISCV/rv32zbe-valid.s
    llvm/test/MC/RISCV/rv32zbf-invalid.s
    llvm/test/MC/RISCV/rv32zbf-valid.s
    llvm/test/MC/RISCV/rv32zbp-invalid.s
    llvm/test/MC/RISCV/rv32zbp-valid.s
    llvm/test/MC/RISCV/rv32zbproposedc-invalid.s
    llvm/test/MC/RISCV/rv32zbproposedc-valid.s
    llvm/test/MC/RISCV/rv32zbr-invalid.s
    llvm/test/MC/RISCV/rv32zbr-valid.s
    llvm/test/MC/RISCV/rv32zbs-invalid.s
    llvm/test/MC/RISCV/rv32zbs-valid.s
    llvm/test/MC/RISCV/rv32zbt-invalid.s
    llvm/test/MC/RISCV/rv32zbt-valid.s
    llvm/test/MC/RISCV/rv64b-aliases-valid.s
    llvm/test/MC/RISCV/rv64zbb-invalid.s
    llvm/test/MC/RISCV/rv64zbb-valid.s
    llvm/test/MC/RISCV/rv64zbbp-invalid.s
    llvm/test/MC/RISCV/rv64zbbp-valid.s
    llvm/test/MC/RISCV/rv64zbc-invalid.s
    llvm/test/MC/RISCV/rv64zbc-valid.s
    llvm/test/MC/RISCV/rv64zbe-invalid.s
    llvm/test/MC/RISCV/rv64zbe-valid.s
    llvm/test/MC/RISCV/rv64zbf-invalid.s
    llvm/test/MC/RISCV/rv64zbf-valid.s
    llvm/test/MC/RISCV/rv64zbm-invalid.s
    llvm/test/MC/RISCV/rv64zbm-valid.s
    llvm/test/MC/RISCV/rv64zbp-invalid.s
    llvm/test/MC/RISCV/rv64zbp-valid.s
    llvm/test/MC/RISCV/rv64zbproposedc-invalid.s
    llvm/test/MC/RISCV/rv64zbproposedc-valid.s
    llvm/test/MC/RISCV/rv64zbr-invalid.s
    llvm/test/MC/RISCV/rv64zbr-valid.s
    llvm/test/MC/RISCV/rv64zbs-invalid.s
    llvm/test/MC/RISCV/rv64zbs-valid.s
    llvm/test/MC/RISCV/rv64zbt-invalid.s
    llvm/test/MC/RISCV/rv64zbt-valid.s

Modified: 
    llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
    llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
    llvm/lib/Target/RISCV/RISCV.td
    llvm/lib/Target/RISCV/RISCVInstrInfo.td
    llvm/lib/Target/RISCV/RISCVSubtarget.h

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index e5a98f4f71cc..388b55a83195 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -445,6 +445,17 @@ struct RISCVOperand : public MCParsedAsmOperand {
     return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm);
   }
 
+  bool isUImmLog2XLenHalf() const {
+    int64_t Imm;
+    RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
+    if (!isImm())
+      return false;
+    if (!evaluateConstantImm(getImm(), Imm, VK) ||
+        VK != RISCVMCExpr::VK_RISCV_None)
+      return false;
+    return (isRV64() && isUInt<5>(Imm)) || isUInt<4>(Imm);
+  }
+
   bool isUImm5() const {
     int64_t Imm;
     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
@@ -471,7 +482,7 @@ struct RISCVOperand : public MCParsedAsmOperand {
     int64_t Imm;
     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
     return IsConstantImm && isInt<6>(Imm) &&
-           VK == RISCVMCExpr::VK_RISCV_None;
+	    VK == RISCVMCExpr::VK_RISCV_None;
   }
 
   bool isSImm6NonZero() const {
@@ -905,6 +916,10 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
     if (isRV64())
       return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1);
     return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
+  case Match_InvalidUImmLog2XLenHalf:
+    if (isRV64())
+      return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
+    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
   case Match_InvalidUImm5:
     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
   case Match_InvalidSImm6:

diff  --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 1461a40227bf..92519be87015 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -349,6 +349,19 @@ DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
       }
     }
 
+    if (STI.getFeatureBits()[RISCV::FeatureExtZbproposedc] &&
+        STI.getFeatureBits()[RISCV::FeatureStdExtC]) {
+      LLVM_DEBUG(
+          dbgs() << "Trying RVBC32 table (BitManip 16-bit Instruction):\n");
+      // Calling the auto-generated decoder function.
+      Result = decodeInstruction(DecoderTableRVBC16, MI, Insn, Address,
+                                 this, STI);
+      if (Result != MCDisassembler::Fail) {
+        Size = 2;
+        return Result;
+      }
+    }
+
     LLVM_DEBUG(dbgs() << "Trying RISCV_C table (16-bit Instruction):\n");
     // Calling the auto-generated decoder function.
     Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI);

diff  --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td
index 31258aa487ec..6564e0aa49f1 100644
--- a/llvm/lib/Target/RISCV/RISCV.td
+++ b/llvm/lib/Target/RISCV/RISCV.td
@@ -48,6 +48,98 @@ def HasStdExtC : Predicate<"Subtarget->hasStdExtC()">,
                            AssemblerPredicate<(all_of FeatureStdExtC),
                            "'C' (Compressed Instructions)">;
 
+def FeatureExtZbb
+    : SubtargetFeature<"experimental-zbb", "HasStdExtZbb", "true",
+                       "'Zbb' (Base 'B' Instructions)">;
+def HasStdExtZbb : Predicate<"Subtarget->hasStdExtZbb()">,
+                             AssemblerPredicate<(all_of FeatureExtZbb),
+                             "'Zbb' (Base 'B' Instructions)">;
+
+def FeatureExtZbc
+    : SubtargetFeature<"experimental-zbc", "HasStdExtZbc", "true",
+                       "'Zbc' (Carry-Less 'B' Instructions)">;
+def HasStdExtZbc : Predicate<"Subtarget->hasStdExtZbc()">,
+                             AssemblerPredicate<(all_of FeatureExtZbc),
+                             "'Zbc' (Carry-Less 'B' Instructions)">;
+
+def FeatureExtZbe
+    : SubtargetFeature<"experimental-zbe", "HasStdExtZbe", "true",
+                       "'Zbe' (Extract-Deposit 'B' Instructions)">;
+def HasStdExtZbe : Predicate<"Subtarget->hasStdExtZbe()">,
+                             AssemblerPredicate<(all_of FeatureExtZbe),
+                             "'Zbe' (Extract-Deposit 'B' Instructions)">;
+
+def FeatureExtZbf
+    : SubtargetFeature<"experimental-zbf", "HasStdExtZbf", "true",
+                       "'Zbf' (Bit-Field 'B' Instructions)">;
+def HasStdExtZbf : Predicate<"Subtarget->hasStdExtZbf()">,
+                             AssemblerPredicate<(all_of FeatureExtZbf),
+                             "'Zbf' (Bit-Field 'B' Instructions)">;
+
+def FeatureExtZbm
+    : SubtargetFeature<"experimental-zbm", "HasStdExtZbm", "true",
+                       "'Zbm' (Matrix 'B' Instructions)">;
+def HasStdExtZbm : Predicate<"Subtarget->hasStdExtZbm()">,
+                             AssemblerPredicate<(all_of FeatureExtZbm),
+                             "'Zbm' (Matrix 'B' Instructions)">;
+
+def FeatureExtZbp
+    : SubtargetFeature<"experimental-zbp", "HasStdExtZbp", "true",
+                       "'Zbp' (Permutation 'B' Instructions)">;
+def HasStdExtZbp : Predicate<"Subtarget->hasStdExtZbp()">,
+                             AssemblerPredicate<(all_of FeatureExtZbp),
+                             "'Zbp' (Permutation 'B' Instructions)">;
+
+def FeatureExtZbr
+    : SubtargetFeature<"experimental-zbr", "HasStdExtZbr", "true",
+                       "'Zbr' (Polynomial Reduction 'B' Instructions)">;
+def HasStdExtZbr : Predicate<"Subtarget->hasStdExtZbr()">,
+                             AssemblerPredicate<(all_of FeatureExtZbr),
+                             "'Zbr' (Polynomial Reduction 'B' Instructions)">;
+
+def FeatureExtZbs
+    : SubtargetFeature<"experimental-zbs", "HasStdExtZbs", "true",
+                       "'Zbs' (Single-Bit 'B' Instructions)">;
+def HasStdExtZbs : Predicate<"Subtarget->hasStdExtZbs()">,
+                             AssemblerPredicate<(all_of FeatureExtZbs),
+                             "'Zbs' (Single-Bit 'B' Instructions)">;
+
+def FeatureExtZbt
+    : SubtargetFeature<"experimental-zbt", "HasStdExtZbt", "true",
+                       "'Zbt' (Ternary 'B' Instructions)">;
+def HasStdExtZbt : Predicate<"Subtarget->hasStdExtZbt()">,
+                             AssemblerPredicate<(all_of FeatureExtZbt),
+                             "'Zbt' (Ternary 'B' Instructions)">;
+
+// Some instructions belong to both the basic and the permutation
+// subextensions. They should be enabled if either has been specified.
+def HasStdExtZbbOrZbp
+    : Predicate<"Subtarget->hasStdExtZbb() || Subtarget->hasStdExtZbp()">,
+                AssemblerPredicate<(any_of FeatureExtZbb, FeatureExtZbp)>;
+
+def FeatureExtZbproposedc
+    : SubtargetFeature<"experimental-zbproposedc", "HasStdExtZbproposedc", "true",
+                       "'Zbproposedc' (Proposed Compressed 'B' Instructions)">;
+def HasStdExtZbproposedc : Predicate<"Subtarget->hasStdExtZbproposedc()">,
+                           AssemblerPredicate<(all_of FeatureExtZbproposedc),
+                           "'Zbproposedc' (Proposed Compressed 'B' Instructions)">;
+
+def FeatureStdExtB
+    : SubtargetFeature<"experimental-b", "HasStdExtB", "true",
+                       "'B' (Bit Manipulation Instructions)",
+                       [FeatureExtZbb,
+                        FeatureExtZbc,
+                        FeatureExtZbe,
+                        FeatureExtZbf,
+                        FeatureExtZbm,
+                        FeatureExtZbp,
+                        FeatureExtZbr,
+                        FeatureExtZbs,
+                        FeatureExtZbt]>;
+def HasStdExtB : Predicate<"Subtarget->hasStdExtB()">,
+                           AssemblerPredicate<(all_of FeatureStdExtB),
+                           "'B' (Bit Manipulation Instructions)">;
+
 def FeatureRVCHints
     : SubtargetFeature<"rvc-hints", "EnableRVCHintInstrs", "true",
                        "Enable RVC Hint Instructions.">;

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index 3ab300b3f744..12915100aa90 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -1164,3 +1164,4 @@ include "RISCVInstrInfoA.td"
 include "RISCVInstrInfoF.td"
 include "RISCVInstrInfoD.td"
 include "RISCVInstrInfoC.td"
+include "RISCVInstrInfoB.td"

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfoB.td b/llvm/lib/Target/RISCV/RISCVInstrInfoB.td
new file mode 100644
index 000000000000..34a463626e29
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoB.td
@@ -0,0 +1,634 @@
+//===-- RISCVInstrInfoB.td - RISC-V 'B' 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 RISC-V instructions from the standard 'B' Bitmanip
+// extension, version 0.92.
+// This version is still experimental as the 'B' extension hasn't been
+// ratified yet.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Operand definitions.
+//===----------------------------------------------------------------------===//
+
+def UImmLog2XLenHalfAsmOperand : AsmOperandClass {
+  let Name = "UImmLog2XLenHalf";
+  let RenderMethod = "addImmOperands";
+  let DiagnosticType = "InvalidUImmLog2XLenHalf";
+}
+
+def shfl_uimm : Operand<XLenVT>, ImmLeaf<XLenVT, [{
+  if (Subtarget->is64Bit())
+    return isUInt<5>(Imm);
+  return isUInt<4>(Imm);
+}]> {
+  let ParserMatchClass = UImmLog2XLenHalfAsmOperand;
+  let DecoderMethod = "decodeUImmOperand<5>";
+  let MCOperandPredicate = [{
+    int64_t Imm;
+    if (!MCOp.evaluateAsConstantImm(Imm))
+      return false;
+    if (STI.getTargetTriple().isArch64Bit())
+      return  isUInt<5>(Imm);
+    return isUInt<4>(Imm);
+  }];
+}
+
+//===----------------------------------------------------------------------===//
+// Instruction class templates
+//===----------------------------------------------------------------------===//
+
+// Some of these templates should be moved to RISCVInstrFormats.td once the B
+// extension has been ratified.
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVBUnary<bits<7> funct7, bits<5> funct5, bits<3> funct3,
+               RISCVOpcode opcode, string opcodestr>
+    : RVInstR<funct7, funct3, opcode, (outs GPR:$rd), (ins GPR:$rs1),
+              opcodestr, "$rd, $rs1"> {
+  let Inst{24-20} = funct5;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVBALUW_ri<bits<3> funct3, string opcodestr>
+    : RVInstI<funct3, OPC_OP_IMM_32, (outs GPR:$rd),
+              (ins GPR:$rs1, simm12:$imm12), opcodestr, "$rd, $rs1, $imm12">;
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVBShift_ri<bits<5> funct5, bits<3> funct3, RISCVOpcode opcode,
+                  string opcodestr>
+    : RVInstI<funct3, opcode, (outs GPR:$rd),
+              (ins GPR:$rs1, uimmlog2xlen:$shamt), opcodestr,
+              "$rd, $rs1, $shamt"> {
+  bits<6> shamt;
+
+  let Inst{31-27} = funct5;
+  // NOTE: the bit op(26)=1 is used to select funnel shifts. All other
+  // shifts operations and operations that live in the encoding space
+  // of the shifts (single bit operations, grev, gorc) use op(26) = 0
+  let Inst{26} = 0;
+  let Inst{25-20} = shamt;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVBShiftW_ri<bits<7> funct7, bits<3> funct3, RISCVOpcode opcode,
+                   string opcodestr>
+    : RVInstI<funct3, opcode, (outs GPR:$rd), (ins GPR:$rs1, uimm5:$shamt),
+              opcodestr, "$rd, $rs1, $shamt"> {
+  bits<5> shamt;
+
+  let Inst{31-25} = funct7;
+  let Inst{24-20} = shamt;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVBShfl_ri<bits<6> funct6, bits<3> funct3, RISCVOpcode opcode,
+                 string opcodestr>
+    : RVInstI<funct3, opcode, (outs GPR:$rd), (ins GPR:$rs1, shfl_uimm:$shamt),
+              opcodestr, "$rd, $rs1, $shamt"> {
+  bits<6> shamt;
+
+  let Inst{31-26} = funct6;
+  let Inst{25-20} = shamt;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVBTernaryR<bits<2> funct2, bits<3> funct3_b, RISCVOpcode opcode,
+                  string opcodestr, string argstr>
+    : RVInstR4<funct2, opcode, (outs GPR:$rd),
+               (ins GPR:$rs1, GPR:$rs2, GPR:$rs3), opcodestr, argstr> {
+  let Inst{14-12} = funct3_b;
+}
+
+// Currently used by FSRI only
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVBTernaryImm6<bits<3> funct3_b, RISCVOpcode opcode,
+                     string opcodestr, string argstr>
+    : RVInstR4<0b10, opcode, (outs GPR:$rd),
+               (ins GPR:$rs1, GPR:$rs3, uimmlog2xlen:$shamt),
+               opcodestr, argstr> {
+  bits<6> shamt;
+
+  // NOTE: the first argument of RVInstR4 is hardcoded to 0b10 like the other
+  // funnel shift instructions. The second bit of the argument though is
+  // overwritten by the shamt as the encoding of this particular instruction
+  // requires. This is to obtain op(26) = 1 as required by funnel shift
+  // instructions without the need of a confusing argument in the definition
+  // of the instruction.
+  let Inst{25-20} = shamt;
+  let Inst{14-12} = funct3_b;
+}
+
+// Currently used by FSRIW only
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVBTernaryImm5<bits<2> funct2, bits<3> funct3_b, RISCVOpcode opcode,
+                     string opcodestr, string argstr>
+    : RVInstR4<funct2, opcode, (outs GPR:$rd),
+               (ins GPR:$rs1, GPR:$rs3, uimm5:$shamt), opcodestr, argstr> {
+  bits<5> shamt;
+
+  let Inst{24-20} = shamt;
+  let Inst{14-12} = funct3_b;
+}
+
+//===----------------------------------------------------------------------===//
+// Instructions
+//===----------------------------------------------------------------------===//
+
+let Predicates = [HasStdExtZbbOrZbp] in {
+def ANDN  : ALU_rr<0b0100000, 0b111, "andn">, Sched<[]>;
+def ORN   : ALU_rr<0b0100000, 0b110, "orn">, Sched<[]>;
+def XNOR  : ALU_rr<0b0100000, 0b100, "xnor">, Sched<[]>;
+} // Predicates = [HasStdExtZbbOrZbp]
+
+let Predicates = [HasStdExtZbb] in {
+def SLO  : ALU_rr<0b0010000, 0b001, "slo">, Sched<[]>;
+def SRO  : ALU_rr<0b0010000, 0b101, "sro">, Sched<[]>;
+} // Predicates = [HasStdExtZbb]
+
+let Predicates = [HasStdExtZbbOrZbp] in {
+def ROL   : ALU_rr<0b0110000, 0b001, "rol">, Sched<[]>;
+def ROR   : ALU_rr<0b0110000, 0b101, "ror">, Sched<[]>;
+} // Predicates = [HasStdExtZbbOrZbp]
+
+let Predicates = [HasStdExtZbs] in {
+def SBCLR : ALU_rr<0b0100100, 0b001, "sbclr">, Sched<[]>;
+def SBSET : ALU_rr<0b0010100, 0b001, "sbset">, Sched<[]>;
+def SBINV : ALU_rr<0b0110100, 0b001, "sbinv">, Sched<[]>;
+def SBEXT : ALU_rr<0b0100100, 0b101, "sbext">, Sched<[]>;
+} // Predicates = [HasStdExtZbs]
+
+let Predicates = [HasStdExtZbp] in {
+def GORC : ALU_rr<0b0010100, 0b101, "gorc">, Sched<[]>;
+def GREV : ALU_rr<0b0110100, 0b101, "grev">, Sched<[]>;
+} // Predicates = [HasStdExtZbp]
+
+let Predicates = [HasStdExtZbb] in {
+def SLOI : RVBShift_ri<0b00100, 0b001, OPC_OP_IMM, "sloi">, Sched<[]>;
+def SROI : RVBShift_ri<0b00100, 0b101, OPC_OP_IMM, "sroi">, Sched<[]>;
+} // Predicates = [HasStdExtZbb]
+
+let Predicates = [HasStdExtZbbOrZbp] in
+def RORI  : RVBShift_ri<0b01100, 0b101, OPC_OP_IMM, "rori">, Sched<[]>;
+
+let Predicates = [HasStdExtZbs] in {
+def SBCLRI : RVBShift_ri<0b01001, 0b001, OPC_OP_IMM, "sbclri">, Sched<[]>;
+def SBSETI : RVBShift_ri<0b00101, 0b001, OPC_OP_IMM, "sbseti">, Sched<[]>;
+def SBINVI : RVBShift_ri<0b01101, 0b001, OPC_OP_IMM, "sbinvi">, Sched<[]>;
+def SBEXTI : RVBShift_ri<0b01001, 0b101, OPC_OP_IMM, "sbexti">, Sched<[]>;
+} // Predicates = [HasStdExtZbs]
+
+let Predicates = [HasStdExtZbp] in {
+def GREVI : RVBShift_ri<0b01101, 0b101, OPC_OP_IMM, "grevi">, Sched<[]>;
+def GORCI : RVBShift_ri<0b00101, 0b101, OPC_OP_IMM, "gorci">, Sched<[]>;
+} // Predicates = [HasStdExtZbp]
+
+let Predicates = [HasStdExtZbt] in {
+def CMIX : RVBTernaryR<0b11, 0b001, OPC_OP, "cmix", "$rd, $rs2, $rs1, $rs3">,
+           Sched<[]>;
+def CMOV : RVBTernaryR<0b11, 0b101, OPC_OP, "cmov", "$rd, $rs2, $rs1, $rs3">,
+           Sched<[]>;
+def FSL  : RVBTernaryR<0b10, 0b001, OPC_OP, "fsl", "$rd, $rs1, $rs3, $rs2">,
+           Sched<[]>;
+def FSR  : RVBTernaryR<0b10, 0b101, OPC_OP, "fsr", "$rd, $rs1, $rs3, $rs2">,
+           Sched<[]>;
+def FSRI : RVBTernaryImm6<0b101, OPC_OP_IMM, "fsri",
+                          "$rd, $rs1, $rs3, $shamt">, Sched<[]>;
+} // Predicates = [HasStdExtZbt]
+
+let Predicates = [HasStdExtZbb] in {
+def CLZ  : RVBUnary<0b0110000, 0b00000, 0b001, RISCVOpcode<0b0010011>, "clz">,
+           Sched<[]>;
+def CTZ  : RVBUnary<0b0110000, 0b00001, 0b001, RISCVOpcode<0b0010011>, "ctz">,
+           Sched<[]>;
+def PCNT : RVBUnary<0b0110000, 0b00010, 0b001, RISCVOpcode<0b0010011>, "pcnt">,
+           Sched<[]>;
+} // Predicates = [HasStdExtZbb]
+
+let Predicates = [HasStdExtZbm, IsRV64] in
+def BMATFLIP : RVBUnary<0b0110000, 0b00011, 0b001, RISCVOpcode<0b0010011>,
+                        "bmatflip">, Sched<[]>;
+
+let Predicates = [HasStdExtZbb] in {
+def SEXTB : RVBUnary<0b0110000, 0b00100, 0b001, RISCVOpcode<0b0010011>,
+                     "sext.b">, Sched<[]>;
+def SEXTH : RVBUnary<0b0110000, 0b00101, 0b001, RISCVOpcode<0b0010011>,
+                     "sext.h">, Sched<[]>;
+} // Predicates = [HasStdExtZbb]
+
+let Predicates = [HasStdExtZbr] in {
+def CRC32B : RVBUnary<0b0110000, 0b10000, 0b001, RISCVOpcode<0b0010011>,
+                      "crc32.b">, Sched<[]>;
+def CRC32H : RVBUnary<0b0110000, 0b10001, 0b001, RISCVOpcode<0b0010011>,
+                      "crc32.h">, Sched<[]>;
+def CRC32W : RVBUnary<0b0110000, 0b10010, 0b001, RISCVOpcode<0b0010011>,
+                      "crc32.w">, Sched<[]>;
+} // Predicates = [HasStdExtZbr]
+
+let Predicates = [HasStdExtZbr, IsRV64] in
+def CRC32D  : RVBUnary<0b0110000, 0b10011, 0b001, RISCVOpcode<0b0010011>,
+                       "crc32.d">, Sched<[]>;
+
+let Predicates = [HasStdExtZbr] in {
+def CRC32CB : RVBUnary<0b0110000, 0b11000, 0b001, RISCVOpcode<0b0010011>,
+                       "crc32c.b">, Sched<[]>;
+def CRC32CH : RVBUnary<0b0110000, 0b11001, 0b001, RISCVOpcode<0b0010011>,
+                       "crc32c.h">, Sched<[]>;
+def CRC32CW : RVBUnary<0b0110000, 0b11010, 0b001, RISCVOpcode<0b0010011>,
+                       "crc32c.w">, Sched<[]>;
+} // Predicates = [HasStdExtZbr]
+
+let Predicates = [HasStdExtZbr, IsRV64] in
+def CRC32CD : RVBUnary<0b0110000, 0b11011, 0b001, RISCVOpcode<0b0010011>,
+                       "crc32c.d">, Sched<[]>;
+
+let Predicates = [HasStdExtZbc] in {
+def CLMUL  : ALU_rr<0b0000101, 0b001, "clmul">, Sched<[]>;
+def CLMULR : ALU_rr<0b0000101, 0b010, "clmulr">, Sched<[]>;
+def CLMULH : ALU_rr<0b0000101, 0b011, "clmulh">, Sched<[]>;
+} // Predicates = [HasStdExtZbc]
+
+let Predicates = [HasStdExtZbb] in {
+def MIN  : ALU_rr<0b0000101, 0b100, "min">, Sched<[]>;
+def MAX  : ALU_rr<0b0000101, 0b101, "max">, Sched<[]>;
+def MINU : ALU_rr<0b0000101, 0b110, "minu">, Sched<[]>;
+def MAXU : ALU_rr<0b0000101, 0b111, "maxu">, Sched<[]>;
+} // Predicates = [HasStdExtZbb]
+
+let Predicates = [HasStdExtZbp] in {
+def SHFL   : ALU_rr<0b0000100, 0b001, "shfl">, Sched<[]>;
+def UNSHFL : ALU_rr<0b0000100, 0b101, "unshfl">, Sched<[]>;
+} // Predicates = [HasStdExtZbp]
+
+let Predicates = [HasStdExtZbe] in {
+def BDEP : ALU_rr<0b0100100, 0b110, "bdep">, Sched<[]>;
+def BEXT : ALU_rr<0b0000100, 0b110, "bext">, Sched<[]>;
+} // Predicates = [HasStdExtZbe]
+
+let Predicates = [HasStdExtZbbOrZbp] in {
+def PACK  : ALU_rr<0b0000100, 0b100, "pack">, Sched<[]>;
+def PACKU : ALU_rr<0b0100100, 0b100, "packu">, Sched<[]>;
+} // Predicates = [HasStdExtZbbOrZbp]
+
+let Predicates = [HasStdExtZbm, IsRV64] in {
+def BMATOR   : ALU_rr<0b0000100, 0b011, "bmator">, Sched<[]>;
+def BMATXOR  : ALU_rr<0b0100100, 0b011, "bmatxor">, Sched<[]>;
+} // Predicates = [HasStdExtZbm, IsRV64]
+
+let Predicates = [HasStdExtZbbOrZbp] in
+def PACKH : ALU_rr<0b0000100, 0b111, "packh">, Sched<[]>;
+
+let Predicates = [HasStdExtZbf] in
+def BFP : ALU_rr<0b0100100, 0b111, "bfp">, Sched<[]>;
+
+let Predicates = [HasStdExtZbp] in {
+def SHFLI   : RVBShfl_ri<0b000010, 0b001, OPC_OP_IMM, "shfli">, Sched<[]>;
+def UNSHFLI : RVBShfl_ri<0b000010, 0b101, OPC_OP_IMM, "unshfli">, Sched<[]>;
+} // Predicates = [HasStdExtZbp]
+
+let Predicates = [HasStdExtZbb, IsRV64] in {
+def ADDIWU : RVBALUW_ri<0b100, "addiwu">, Sched<[]>;
+def SLLIUW : RVBShift_ri<0b00001, 0b001, OPC_OP_IMM_32, "slliu.w">, Sched<[]>;
+def ADDWU : ALUW_rr<0b0000101, 0b000, "addwu">, Sched<[]>;
+def SUBWU : ALUW_rr<0b0100101, 0b000, "subwu">, Sched<[]>;
+def ADDUW : ALUW_rr<0b0000100, 0b000, "addu.w">, Sched<[]>;
+def SUBUW : ALUW_rr<0b0100100, 0b000, "subu.w">, Sched<[]>;
+} // Predicates = [HasStdExtZbb, IsRV64]
+
+let Predicates = [HasStdExtZbb, IsRV64] in {
+def SLOW   : ALUW_rr<0b0010000, 0b001, "slow">, Sched<[]>;
+def SROW   : ALUW_rr<0b0010000, 0b101, "srow">, Sched<[]>;
+} // Predicates = [HasStdExtZbb, IsRV64]
+
+let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
+def ROLW  : ALUW_rr<0b0110000, 0b001, "rolw">, Sched<[]>;
+def RORW  : ALUW_rr<0b0110000, 0b101, "rorw">, Sched<[]>;
+} // Predicates = [HasStdExtZbbOrZbp, IsRV64]
+
+let Predicates = [HasStdExtZbs, IsRV64] in {
+def SBCLRW : ALUW_rr<0b0100100, 0b001, "sbclrw">, Sched<[]>;
+def SBSETW : ALUW_rr<0b0010100, 0b001, "sbsetw">, Sched<[]>;
+def SBINVW : ALUW_rr<0b0110100, 0b001, "sbinvw">, Sched<[]>;
+def SBEXTW : ALUW_rr<0b0100100, 0b101, "sbextw">, Sched<[]>;
+} // Predicates = [HasStdExtZbs, IsRV64]
+
+let Predicates = [HasStdExtZbp, IsRV64] in {
+def GORCW  : ALUW_rr<0b0010100, 0b101, "gorcw">, Sched<[]>;
+def GREVW  : ALUW_rr<0b0110100, 0b101, "grevw">, Sched<[]>;
+} // Predicates = [HasStdExtZbp, IsRV64]
+
+let Predicates = [HasStdExtZbb, IsRV64] in {
+def SLOIW  : RVBShiftW_ri<0b0010000, 0b001, OPC_OP_IMM_32, "sloiw">, Sched<[]>;
+def SROIW  : RVBShiftW_ri<0b0010000, 0b101, OPC_OP_IMM_32, "sroiw">, Sched<[]>;
+} // Predicates = [HasStdExtZbb, IsRV64]
+
+let Predicates = [HasStdExtZbbOrZbp, IsRV64] in
+def RORIW : RVBShiftW_ri<0b0110000, 0b101, OPC_OP_IMM_32, "roriw">, Sched<[]>;
+
+let Predicates = [HasStdExtZbs, IsRV64] in {
+def SBCLRIW : RVBShiftW_ri<0b0100100, 0b001, OPC_OP_IMM_32, "sbclriw">,
+              Sched<[]>;
+def SBSETIW : RVBShiftW_ri<0b0010100, 0b001, OPC_OP_IMM_32, "sbsetiw">,
+              Sched<[]>;
+def SBINVIW : RVBShiftW_ri<0b0110100, 0b001, OPC_OP_IMM_32, "sbinviw">,
+              Sched<[]>;
+} // Predicates = [HasStdExtZbs, IsRV64]
+
+let Predicates = [HasStdExtZbp, IsRV64] in {
+def GORCIW : RVBShiftW_ri<0b0010100, 0b101, OPC_OP_IMM_32, "gorciw">, Sched<[]>;
+def GREVIW : RVBShiftW_ri<0b0110100, 0b101, OPC_OP_IMM_32, "greviw">, Sched<[]>;
+} // Predicates = [HasStdExtZbp, IsRV64]
+
+let Predicates = [HasStdExtZbt, IsRV64] in {
+def FSLW  : RVBTernaryR<0b10, 0b001, OPC_OP_32,
+                        "fslw", "$rd, $rs1, $rs3, $rs2">, Sched<[]>;
+def FSRW  : RVBTernaryR<0b10, 0b101, OPC_OP_32, "fsrw",
+                        "$rd, $rs1, $rs3, $rs2">, Sched<[]>;
+def FSRIW : RVBTernaryImm5<0b10, 0b101, OPC_OP_IMM_32,
+                           "fsriw", "$rd, $rs1, $rs3, $shamt">, Sched<[]>;
+} // Predicates = [HasStdExtZbt, IsRV64]
+
+let Predicates = [HasStdExtZbb, IsRV64] in {
+def CLZW   : RVBUnary<0b0110000, 0b00000, 0b001, RISCVOpcode<0b0011011>,
+                      "clzw">, Sched<[]>;
+def CTZW   : RVBUnary<0b0110000, 0b00001, 0b001, RISCVOpcode<0b0011011>,
+                      "ctzw">, Sched<[]>;
+def PCNTW  : RVBUnary<0b0110000, 0b00010, 0b001, RISCVOpcode<0b0011011>,
+                      "pcntw">, Sched<[]>;
+} // Predicates = [HasStdExtZbb, IsRV64]
+
+let Predicates = [HasStdExtZbc, IsRV64] in {
+def CLMULW  : ALUW_rr<0b0000101, 0b001, "clmulw">, Sched<[]>;
+def CLMULRW : ALUW_rr<0b0000101, 0b010, "clmulrw">, Sched<[]>;
+def CLMULHW : ALUW_rr<0b0000101, 0b011, "clmulhw">, Sched<[]>;
+} // Predicates = [HasStdExtZbc, IsRV64]
+
+let Predicates = [HasStdExtZbp, IsRV64] in {
+def SHFLW   : ALUW_rr<0b0000100, 0b001, "shflw">, Sched<[]>;
+def UNSHFLW : ALUW_rr<0b0000100, 0b101, "unshflw">, Sched<[]>;
+} // Predicates = [HasStdExtZbp, IsRV64]
+
+let Predicates = [HasStdExtZbe, IsRV64] in {
+def BDEPW : ALUW_rr<0b0100100, 0b110, "bdepw">, Sched<[]>;
+def BEXTW : ALUW_rr<0b0000100, 0b110, "bextw">, Sched<[]>;
+} // Predicates = [HasStdExtZbe, IsRV64]
+
+let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
+def PACKW  : ALUW_rr<0b0000100, 0b100, "packw">, Sched<[]>;
+def PACKUW : ALUW_rr<0b0100100, 0b100, "packuw">, Sched<[]>;
+} // Predicates = [HasStdExtZbbOrZbp, IsRV64]
+
+let Predicates = [HasStdExtZbf, IsRV64] in
+def BFPW : ALUW_rr<0b0100100, 0b111, "bfpw">, Sched<[]>;
+
+//===----------------------------------------------------------------------===//
+// Future compressed instructions
+//===----------------------------------------------------------------------===//
+
+// The presence of these instructions in the B extension is purely experimental
+// and they should be moved to the C extension as soon as they are ratified.
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVBInstC<bits<2> funct2, string opcodestr>
+    : RVInst16<(outs GPRC:$rs_wb), (ins GPRC:$rs), opcodestr, "$rs", [],
+               InstFormatCR> {
+  bits<3> rs;
+  let Constraints = "$rs = $rs_wb";
+
+  let Inst{15-12} = 0b0110;
+  let Inst{11-10} = funct2;
+  let Inst{9-7} = rs;
+  let Inst{6-0} = 0b0000001;
+}
+
+// The namespace RVBC exists to avoid encoding conflicts with the compressed
+// instructions c.addi16sp and c.lui already implemented in the C extension.
+
+let DecoderNamespace = "RVBC", Predicates = [HasStdExtZbproposedc, HasStdExtC] in {
+def C_NOT : RVBInstC<0b00, "c.not">, Sched<[]>;
+def C_NEG : RVBInstC<0b01, "c.neg">, Sched<[]>;
+} // DecoderNamespace = "RVBC", Predicates = [HasStdExtZbproposedc, HasStdExtC]
+
+let DecoderNamespace = "RVBC", Predicates = [HasStdExtZbproposedc, HasStdExtZbbOrZbp, HasStdExtC, IsRV64] in
+def C_ZEXTW : RVBInstC<0b10, "c.zext.w">, Sched<[]>;
+
+//===----------------------------------------------------------------------===//
+// Pseudo Instructions
+//===----------------------------------------------------------------------===//
+
+let Predicates = [HasStdExtZbb, IsRV32] in {
+def : InstAlias<"zext.b $rd, $rs", (ANDI GPR:$rd, GPR:$rs, 0xFF)>;
+def : InstAlias<"zext.h $rd, $rs", (PACK GPR:$rd, GPR:$rs, X0)>;
+} // Predicates = [HasStdExtZbb, IsRV32]
+
+let Predicates = [HasStdExtZbb, IsRV64] in {
+def : InstAlias<"zext.b $rd, $rs", (ANDI GPR:$rd, GPR:$rs, 0xFF)>;
+def : InstAlias<"zext.h $rd, $rs", (PACKW GPR:$rd, GPR:$rs, X0)>;
+def : InstAlias<"zext.w $rd, $rs", (PACK GPR:$rd, GPR:$rs, X0)>;
+} // Predicates = [HasStdExtZbb, IsRV64]
+
+let Predicates = [HasStdExtZbbOrZbp] in {
+def : InstAlias<"rev.p $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b00001)>,
+      Sched<[]>;
+def : InstAlias<"rev2.n $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00010)>,
+      Sched<[]>;
+def : InstAlias<"rev.n $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b00011)>,
+      Sched<[]>;
+def : InstAlias<"rev4.b $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00100)>,
+      Sched<[]>;
+def : InstAlias<"rev2.b $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00110)>,
+      Sched<[]>;
+def : InstAlias<"rev.b $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b00111)>,
+      Sched<[]>;
+def : InstAlias<"rev8.h $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b01000)>,
+      Sched<[]>;
+def : InstAlias<"rev4.h $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b01100)>,
+      Sched<[]>;
+def : InstAlias<"rev2.h $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b01110)>,
+      Sched<[]>;
+def : InstAlias<"rev.h $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b01111)>,
+      Sched<[]>;
+
+def : InstAlias<"zip.n $rd, $rs",    (SHFLI   GPR:$rd, GPR:$rs, 0b0001)>,
+      Sched<[]>;
+def : InstAlias<"unzip.n $rd, $rs",  (UNSHFLI GPR:$rd, GPR:$rs, 0b0001)>,
+      Sched<[]>;
+def : InstAlias<"zip2.b $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b0010)>,
+      Sched<[]>;
+def : InstAlias<"unzip2.b $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0010)>,
+      Sched<[]>;
+def : InstAlias<"zip.b $rd, $rs",    (SHFLI   GPR:$rd, GPR:$rs, 0b0011)>,
+      Sched<[]>;
+def : InstAlias<"unzip.b $rd, $rs",  (UNSHFLI GPR:$rd, GPR:$rs, 0b0011)>,
+      Sched<[]>;
+def : InstAlias<"zip4.h $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b0100)>,
+      Sched<[]>;
+def : InstAlias<"unzip4.h $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0100)>,
+      Sched<[]>;
+def : InstAlias<"zip2.h $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b0110)>,
+      Sched<[]>;
+def : InstAlias<"unzip2.h $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0110)>,
+      Sched<[]>;
+def : InstAlias<"zip.h $rd, $rs",    (SHFLI   GPR:$rd, GPR:$rs, 0b0111)>,
+      Sched<[]>;
+def : InstAlias<"unzip.h $rd, $rs",  (UNSHFLI GPR:$rd, GPR:$rs, 0b0111)>,
+      Sched<[]>;
+
+def : InstAlias<"orc.p $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b00001)>,
+      Sched<[]>;
+def : InstAlias<"orc2.n $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b00010)>,
+      Sched<[]>;
+def : InstAlias<"orc.n $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b00011)>,
+      Sched<[]>;
+def : InstAlias<"orc4.b $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b00100)>,
+      Sched<[]>;
+def : InstAlias<"orc2.b $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b00110)>,
+      Sched<[]>;
+def : InstAlias<"orc.b $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b00111)>,
+      Sched<[]>;
+def : InstAlias<"orc8.h $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b01000)>,
+      Sched<[]>;
+def : InstAlias<"orc4.h $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b01100)>,
+      Sched<[]>;
+def : InstAlias<"orc2.h $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b01110)>,
+      Sched<[]>;
+def : InstAlias<"orc.h $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b01111)>,
+      Sched<[]>;
+} // Predicates = [HasStdExtZbbOrZbp]
+
+let Predicates = [HasStdExtZbbOrZbp, IsRV32] in {
+def : InstAlias<"rev16 $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b10000)>, Sched<[]>;
+def : InstAlias<"rev8 $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b11000)>, Sched<[]>;
+def : InstAlias<"rev4 $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b11100)>, Sched<[]>;
+def : InstAlias<"rev2 $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b11110)>, Sched<[]>;
+def : InstAlias<"rev $rd, $rs",   (GREVI GPR:$rd, GPR:$rs, 0b11111)>, Sched<[]>;
+
+def : InstAlias<"zip8 $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b1000)>,
+      Sched<[]>;
+def : InstAlias<"unzip8 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b1000)>,
+      Sched<[]>;
+def : InstAlias<"zip4 $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b1100)>,
+      Sched<[]>;
+def : InstAlias<"unzip4 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b1100)>,
+      Sched<[]>;
+def : InstAlias<"zip2 $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b1110)>,
+      Sched<[]>;
+def : InstAlias<"unzip2 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b1110)>,
+      Sched<[]>;
+def : InstAlias<"zip $rd, $rs",    (SHFLI   GPR:$rd, GPR:$rs, 0b1111)>,
+      Sched<[]>;
+def : InstAlias<"unzip $rd, $rs",  (UNSHFLI GPR:$rd, GPR:$rs, 0b1111)>,
+      Sched<[]>;
+
+def : InstAlias<"orc16 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b10000)>, Sched<[]>;
+def : InstAlias<"orc8 $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b11000)>, Sched<[]>;
+def : InstAlias<"orc4 $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b11100)>, Sched<[]>;
+def : InstAlias<"orc2 $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b11110)>, Sched<[]>;
+def : InstAlias<"orc $rd, $rs",   (GORCI GPR:$rd, GPR:$rs, 0b11111)>, Sched<[]>;
+} // Predicates = [HasStdExtZbbOrZbp, IsRV32]
+
+let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
+def : InstAlias<"rev16.w $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b010000)>,
+      Sched<[]>;
+def : InstAlias<"rev8.w $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b011000)>,
+      Sched<[]>;
+def : InstAlias<"rev4.w $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b011100)>,
+      Sched<[]>;
+def : InstAlias<"rev2.w $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b011110)>,
+      Sched<[]>;
+def : InstAlias<"rev.w $rd, $rs",   (GREVI GPR:$rd, GPR:$rs, 0b011111)>,
+      Sched<[]>;
+def : InstAlias<"rev32 $rd, $rs",   (GREVI GPR:$rd, GPR:$rs, 0b100000)>,
+      Sched<[]>;
+def : InstAlias<"rev16 $rd, $rs",   (GREVI GPR:$rd, GPR:$rs, 0b110000)>,
+      Sched<[]>;
+def : InstAlias<"rev8 $rd, $rs",    (GREVI GPR:$rd, GPR:$rs, 0b111000)>,
+      Sched<[]>;
+def : InstAlias<"rev4 $rd, $rs",    (GREVI GPR:$rd, GPR:$rs, 0b111100)>,
+      Sched<[]>;
+def : InstAlias<"rev2 $rd, $rs",    (GREVI GPR:$rd, GPR:$rs, 0b111110)>,
+      Sched<[]>;
+def : InstAlias<"rev $rd, $rs",     (GREVI GPR:$rd, GPR:$rs, 0b111111)>,
+      Sched<[]>;
+
+def : InstAlias<"zip8.w $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b01000)>,
+      Sched<[]>;
+def : InstAlias<"unzip8.w $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b01000)>,
+      Sched<[]>;
+def : InstAlias<"zip4.w $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b01100)>,
+      Sched<[]>;
+def : InstAlias<"unzip4.w $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b01100)>,
+      Sched<[]>;
+def : InstAlias<"zip2.w $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b01110)>,
+      Sched<[]>;
+def : InstAlias<"unzip2.w $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b01110)>,
+      Sched<[]>;
+def : InstAlias<"zip.w $rd, $rs",    (SHFLI   GPR:$rd, GPR:$rs, 0b01111)>,
+      Sched<[]>;
+def : InstAlias<"unzip.w $rd, $rs",  (UNSHFLI GPR:$rd, GPR:$rs, 0b01111)>,
+      Sched<[]>;
+def : InstAlias<"zip16 $rd, $rs",    (SHFLI   GPR:$rd, GPR:$rs, 0b10000)>,
+      Sched<[]>;
+def : InstAlias<"unzip16 $rd, $rs",  (UNSHFLI GPR:$rd, GPR:$rs, 0b10000)>,
+      Sched<[]>;
+def : InstAlias<"zip8 $rd, $rs",     (SHFLI   GPR:$rd, GPR:$rs, 0b11000)>,
+      Sched<[]>;
+def : InstAlias<"unzip8 $rd, $rs",   (UNSHFLI GPR:$rd, GPR:$rs, 0b11000)>,
+      Sched<[]>;
+def : InstAlias<"zip4 $rd, $rs",     (SHFLI   GPR:$rd, GPR:$rs, 0b11100)>,
+      Sched<[]>;
+def : InstAlias<"unzip4 $rd, $rs",   (UNSHFLI GPR:$rd, GPR:$rs, 0b11100)>,
+      Sched<[]>;
+def : InstAlias<"zip2 $rd, $rs",     (SHFLI   GPR:$rd, GPR:$rs, 0b11110)>,
+      Sched<[]>;
+def : InstAlias<"unzip2 $rd, $rs",   (UNSHFLI GPR:$rd, GPR:$rs, 0b11110)>,
+      Sched<[]>;
+def : InstAlias<"zip $rd, $rs",      (SHFLI   GPR:$rd, GPR:$rs, 0b11111)>,
+      Sched<[]>;
+def : InstAlias<"unzip $rd, $rs",    (UNSHFLI GPR:$rd, GPR:$rs, 0b11111)>,
+      Sched<[]>;
+
+def : InstAlias<"orc16.w $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b010000)>,
+      Sched<[]>;
+def : InstAlias<"orc8.w $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b011000)>,
+      Sched<[]>;
+def : InstAlias<"orc4.w $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b011100)>,
+      Sched<[]>;
+def : InstAlias<"orc2.w $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b011110)>,
+      Sched<[]>;
+def : InstAlias<"orc.w $rd, $rs",   (GORCI GPR:$rd, GPR:$rs, 0b011111)>,
+      Sched<[]>;
+def : InstAlias<"orc32 $rd, $rs",   (GORCI GPR:$rd, GPR:$rs, 0b100000)>,
+      Sched<[]>;
+def : InstAlias<"orc16 $rd, $rs",   (GORCI GPR:$rd, GPR:$rs, 0b110000)>,
+      Sched<[]>;
+def : InstAlias<"orc8 $rd, $rs",    (GORCI GPR:$rd, GPR:$rs, 0b111000)>,
+      Sched<[]>;
+def : InstAlias<"orc4 $rd, $rs",    (GORCI GPR:$rd, GPR:$rs, 0b111100)>,
+      Sched<[]>;
+def : InstAlias<"orc2 $rd, $rs",    (GORCI GPR:$rd, GPR:$rs, 0b111110)>,
+      Sched<[]>;
+def : InstAlias<"orc $rd, $rs",     (GORCI GPR:$rd, GPR:$rs, 0b111111)>,
+      Sched<[]>;
+} // Predicates = [HasStdExtZbbOrZbp, IsRV64]
+
+//===----------------------------------------------------------------------===//
+// Compressed Instruction patterns
+//===----------------------------------------------------------------------===//
+let Predicates = [HasStdExtZbproposedc, HasStdExtC] in {
+def : CompressPat<(XORI GPRC:$rs1, GPRC:$rs1, -1),
+                  (C_NOT GPRC:$rs1)>;
+def : CompressPat<(SUB GPRC:$rs1, X0, GPRC:$rs1),
+                  (C_NEG GPRC:$rs1)>;
+} // Predicates = [HasStdExtZbproposedc, HasStdExtC]
+
+let Predicates = [HasStdExtZbproposedc, HasStdExtZbbOrZbp, HasStdExtC, IsRV64] in {
+def : CompressPat<(PACK GPRC:$rs1, GPRC:$rs1, X0),
+                  (C_ZEXTW GPRC:$rs1)>;
+} // Predicates = [HasStdExtZbproposedc, HasStdExtC, IsRV64]

diff  --git a/llvm/lib/Target/RISCV/RISCVSubtarget.h b/llvm/lib/Target/RISCV/RISCVSubtarget.h
index 5f8619e65333..8b339c3e4660 100644
--- a/llvm/lib/Target/RISCV/RISCVSubtarget.h
+++ b/llvm/lib/Target/RISCV/RISCVSubtarget.h
@@ -39,6 +39,17 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
   bool HasStdExtF = false;
   bool HasStdExtD = false;
   bool HasStdExtC = false;
+  bool HasStdExtB = false;
+  bool HasStdExtZbb = false;
+  bool HasStdExtZbc = false;
+  bool HasStdExtZbe = false;
+  bool HasStdExtZbf = false;
+  bool HasStdExtZbm = false;
+  bool HasStdExtZbp = false;
+  bool HasStdExtZbr = false;
+  bool HasStdExtZbs = false;
+  bool HasStdExtZbt = false;
+  bool HasStdExtZbproposedc = false;
   bool HasRV64 = false;
   bool IsRV32E = false;
   bool EnableLinkerRelax = false;
@@ -88,6 +99,17 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
   bool hasStdExtF() const { return HasStdExtF; }
   bool hasStdExtD() const { return HasStdExtD; }
   bool hasStdExtC() const { return HasStdExtC; }
+  bool hasStdExtB() const { return HasStdExtB; }
+  bool hasStdExtZbb() const { return HasStdExtZbb; }
+  bool hasStdExtZbc() const { return HasStdExtZbc; }
+  bool hasStdExtZbe() const { return HasStdExtZbe; }
+  bool hasStdExtZbf() const { return HasStdExtZbf; }
+  bool hasStdExtZbm() const { return HasStdExtZbm; }
+  bool hasStdExtZbp() const { return HasStdExtZbp; }
+  bool hasStdExtZbr() const { return HasStdExtZbr; }
+  bool hasStdExtZbs() const { return HasStdExtZbs; }
+  bool hasStdExtZbt() const { return HasStdExtZbt; }
+  bool hasStdExtZbproposedc() const { return HasStdExtZbproposedc; }
   bool is64Bit() const { return HasRV64; }
   bool isRV32E() const { return IsRV32E; }
   bool enableLinkerRelax() const { return EnableLinkerRelax; }

diff  --git a/llvm/test/MC/RISCV/compress-rv32b.s b/llvm/test/MC/RISCV/compress-rv32b.s
new file mode 100644
index 000000000000..46b2971d09db
--- /dev/null
+++ b/llvm/test/MC/RISCV/compress-rv32b.s
@@ -0,0 +1,35 @@
+# RUN: llvm-mc -triple riscv32 -mattr=+c,+experimental-zbproposedc -show-encoding < %s \
+# RUN: | FileCheck -check-prefixes=CHECK,CHECK-ALIAS %s
+# RUN: llvm-mc -triple riscv32 -mattr=+c,+experimental-zbproposedc -show-encoding \
+# RUN: -riscv-no-aliases <%s | FileCheck -check-prefixes=CHECK,CHECK-INST %s
+# RUN: llvm-mc -triple riscv32 -mattr=+c,+experimental-zbproposedc -filetype=obj < %s \
+# RUN: | llvm-objdump  --triple=riscv32 --mattr=+c,+experimental-zbproposedc -d - \
+# RUN: | FileCheck -check-prefixes=CHECK-BYTES,CHECK-ALIAS %s
+# RUN: llvm-mc -triple riscv32 -mattr=+c,+experimental-zbproposedc -filetype=obj < %s \
+# RUN: | llvm-objdump  --triple=riscv32 --mattr=+c,+experimental-zbproposedc -d -M no-aliases - \
+# RUN: | FileCheck -check-prefixes=CHECK-BYTES,CHECK-INST %s
+
+# RUN: llvm-mc -triple riscv64 -mattr=+c,+experimental-zbproposedc -show-encoding < %s \
+# RUN: | FileCheck -check-prefixes=CHECK-ALIAS %s
+# RUN: llvm-mc -triple riscv64 -mattr=+c,+experimental-zbproposedc -show-encoding \
+# RUN: -riscv-no-aliases <%s | FileCheck -check-prefixes=CHECK-INST %s
+# RUN: llvm-mc -triple riscv64 -mattr=+c,+experimental-zbproposedc -filetype=obj < %s \
+# RUN: | llvm-objdump  --triple=riscv64 --mattr=+c,+experimental-zbproposedc -d - \
+# RUN: | FileCheck -check-prefixes=CHECK-BYTES,CHECK-ALIAS %s
+# RUN: llvm-mc -triple riscv64 -mattr=+c,+experimental-zbproposedc -filetype=obj < %s \
+# RUN: | llvm-objdump  --triple=riscv64 --mattr=+c,+experimental-zbproposedc -d -M no-aliases - \
+# RUN: | FileCheck -check-prefixes=CHECK-BYTES,CHECK-INST %s
+
+# Tests bit manipulation instructions available in rv32 and in rv64.
+
+# CHECK-BYTES: 01 60
+# CHECK-ALIAS: not s0, s0
+# CHECK-INST: c.not s0
+# CHECK: # encoding:  [0x01,0x60]
+not s0, s0
+
+# CHECK-BYTES: 01 64
+# CHECK-ALIAS: neg s0, s0
+# CHECK-INST: c.neg s0
+# CHECK: # encoding:  [0x01,0x64]
+neg s0, s0

diff  --git a/llvm/test/MC/RISCV/compress-rv64b.s b/llvm/test/MC/RISCV/compress-rv64b.s
new file mode 100644
index 000000000000..2c0304aa4fb8
--- /dev/null
+++ b/llvm/test/MC/RISCV/compress-rv64b.s
@@ -0,0 +1,18 @@
+# RUN: llvm-mc -triple riscv64 -mattr=+c,+experimental-zbproposedc,+experimental-b -show-encoding < %s \
+# RUN: | FileCheck -check-prefixes=CHECK-ALIAS %s
+# RUN: llvm-mc -triple riscv64 -mattr=+c,+experimental-zbproposedc,+experimental-b -show-encoding \
+# RUN: -riscv-no-aliases <%s | FileCheck -check-prefixes=CHECK-INST %s
+# RUN: llvm-mc -triple riscv64 -mattr=+c,+experimental-zbproposedc,+experimental-b -filetype=obj < %s \
+# RUN: | llvm-objdump  --triple=riscv64 --mattr=+c,+experimental-zbproposedc,+experimental-b -d - \
+# RUN: | FileCheck -check-prefixes=CHECK-BYTES,CHECK-ALIAS %s
+# RUN: llvm-mc -triple riscv64 -mattr=+c,+experimental-zbproposedc,+experimental-b -filetype=obj < %s \
+# RUN: | llvm-objdump  --triple=riscv64 --mattr=+c,+experimental-zbproposedc,+experimental-b -d -M no-aliases - \
+# RUN: | FileCheck -check-prefixes=CHECK-BYTES,CHECK-INST %s
+
+# Tests compressed instructions available in rv64 and not in rv32.
+
+# CHECK-BYTES: 01 68
+# CHECK-ALIAS: zext.w s0, s0
+# CHECK-INST: c.zext.w s0
+# CHECK: # encoding:  [0x01,0x68]
+zext.w s0, s0

diff  --git a/llvm/test/MC/RISCV/rv32b-aliases-valid.s b/llvm/test/MC/RISCV/rv32b-aliases-valid.s
new file mode 100644
index 000000000000..00404c6162ed
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32b-aliases-valid.s
@@ -0,0 +1,224 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-b -riscv-no-aliases \
+# RUN:     | FileCheck -check-prefixes=CHECK-S-OBJ-NOALIAS %s
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-b \
+# RUN:     | FileCheck -check-prefixes=CHECK-S-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-b < %s \
+# RUN:     | llvm-objdump -d -r --riscv-no-aliases --mattr=+experimental-b - \
+# RUN:     | FileCheck -check-prefixes=CHECK-S-OBJ-NOALIAS %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-b < %s \
+# RUN:     | llvm-objdump -d -r --mattr=+experimental-b - \
+# RUN:     | FileCheck -check-prefixes=CHECK-S-OBJ %s
+
+# The following check prefixes are used in this test:
+# CHECK-S-OBJ            Match both the .s and objdumped object output with
+#                        aliases enabled
+# CHECK-S-OBJ-NOALIAS    Match both the .s and objdumped object output with
+#                        aliases disabled
+
+# CHECK-S-OBJ-NOALIAS: andi t0, t1, 255
+# CHECK-S-OBJ: zext.b t0, t1
+zext.b x5, x6
+
+# CHECK-S-OBJ-NOALIAS: pack t0, t1, zero
+# CHECK-S-OBJ: zext.h t0, t1
+zext.h x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 1
+# CHECK-S-OBJ: rev.p t0, t1
+rev.p x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 2
+# CHECK-S-OBJ: rev2.n t0, t1
+rev2.n x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 3
+# CHECK-S-OBJ: rev.n t0, t1
+rev.n x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 4
+# CHECK-S-OBJ: rev4.b t0, t1
+rev4.b x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 6
+# CHECK-S-OBJ: rev2.b t0, t1
+rev2.b x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 7
+# CHECK-S-OBJ: rev.b t0, t1
+rev.b x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 8
+# CHECK-S-OBJ: rev8.h t0, t1
+rev8.h x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 12
+# CHECK-S-OBJ: rev4.h t0, t1
+rev4.h x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 14
+# CHECK-S-OBJ: rev2.h t0, t1
+rev2.h x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 15
+# CHECK-S-OBJ: rev.h t0, t1
+rev.h x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 16
+# CHECK-S-OBJ: rev16 t0, t1
+rev16 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 24
+# CHECK-S-OBJ: rev8 t0, t1
+rev8 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 28
+# CHECK-S-OBJ: rev4 t0, t1
+rev4 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 30
+# CHECK-S-OBJ: rev2 t0, t1
+rev2 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 31
+# CHECK-S-OBJ: rev t0, t1
+rev x5, x6
+
+# CHECK-S-OBJ-NOALIAS: shfli t0, t1, 1
+# CHECK-S-OBJ: zip.n t0, t1
+zip.n x5, x6
+
+# CHECK-S-OBJ-NOALIAS: unshfli t0, t1, 1
+# CHECK-S-OBJ: unzip.n t0, t1
+unzip.n x5, x6
+
+# CHECK-S-OBJ-NOALIAS: shfli t0, t1, 2
+# CHECK-S-OBJ: zip2.b t0, t1
+zip2.b x5, x6
+
+# CHECK-S-OBJ-NOALIAS: unshfli t0, t1, 2
+# CHECK-S-OBJ: unzip2.b t0, t1
+unzip2.b x5, x6
+
+# CHECK-S-OBJ-NOALIAS: shfli t0, t1, 3
+# CHECK-S-OBJ: zip.b t0, t1
+zip.b x5, x6
+
+# CHECK-S-OBJ-NOALIAS: unshfli t0, t1, 3
+# CHECK-S-OBJ: unzip.b t0, t1
+unzip.b x5, x6
+
+# CHECK-S-OBJ-NOALIAS: shfli t0, t1, 4
+# CHECK-S-OBJ: zip4.h t0, t1
+zip4.h x5, x6
+
+# CHECK-S-OBJ-NOALIAS: unshfli t0, t1, 4
+# CHECK-S-OBJ: unzip4.h t0, t1
+unzip4.h x5, x6
+
+# CHECK-S-OBJ-NOALIAS: shfli t0, t1, 6
+# CHECK-S-OBJ: zip2.h t0, t1
+zip2.h x5, x6
+
+# CHECK-S-OBJ-NOALIAS: unshfli t0, t1, 6
+# CHECK-S-OBJ: unzip2.h t0, t1
+unzip2.h x5, x6
+
+# CHECK-S-OBJ-NOALIAS: shfli t0, t1, 7
+# CHECK-S-OBJ: zip.h t0, t1
+zip.h x5, x6
+
+# CHECK-S-OBJ-NOALIAS: unshfli t0, t1, 7
+# CHECK-S-OBJ: unzip.h t0, t1
+unzip.h x5, x6
+
+# CHECK-S-OBJ-NOALIAS: shfli t0, t1, 8
+# CHECK-S-OBJ: zip8 t0, t1
+zip8 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: unshfli t0, t1, 8
+# CHECK-S-OBJ: unzip8 t0, t1
+unzip8 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: shfli t0, t1, 12
+# CHECK-S-OBJ: zip4 t0, t1
+zip4 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: unshfli t0, t1, 12
+# CHECK-S-OBJ: unzip4 t0, t1
+unzip4 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: shfli t0, t1, 14
+# CHECK-S-OBJ: zip2 t0, t1
+zip2 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: unshfli t0, t1, 14
+# CHECK-S-OBJ: unzip2 t0, t1
+unzip2 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: shfli t0, t1, 15
+# CHECK-S-OBJ: zip t0, t1
+zip x5, x6
+
+# CHECK-S-OBJ-NOALIAS: unshfli t0, t1, 15
+# CHECK-S-OBJ: unzip t0, t1
+unzip x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 1
+# CHECK-S-OBJ: orc.p t0, t1
+orc.p x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 2
+# CHECK-S-OBJ: orc2.n t0, t1
+orc2.n x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 3
+# CHECK-S-OBJ: orc.n t0, t1
+orc.n x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 4
+# CHECK-S-OBJ: orc4.b t0, t1
+orc4.b x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 6
+# CHECK-S-OBJ: orc2.b t0, t1
+orc2.b x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 7
+# CHECK-S-OBJ: orc.b t0, t1
+orc.b x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 8
+# CHECK-S-OBJ: orc8.h t0, t1
+orc8.h x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 12
+# CHECK-S-OBJ: orc4.h t0, t1
+orc4.h x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 14
+# CHECK-S-OBJ: orc2.h t0, t1
+orc2.h x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 15
+# CHECK-S-OBJ: orc.h t0, t1
+orc.h x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 16
+# CHECK-S-OBJ: orc16 t0, t1
+orc16 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 24
+# CHECK-S-OBJ: orc8 t0, t1
+orc8 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 28
+# CHECK-S-OBJ: orc4 t0, t1
+orc4 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 30
+# CHECK-S-OBJ: orc2 t0, t1
+orc2 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 31
+# CHECK-S-OBJ: orc t0, t1
+orc x5, x6

diff  --git a/llvm/test/MC/RISCV/rv32zbb-invalid.s b/llvm/test/MC/RISCV/rv32zbb-invalid.s
new file mode 100644
index 000000000000..264ae021ebaf
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zbb-invalid.s
@@ -0,0 +1,34 @@
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-b,experimental-zbb < %s 2>&1 | FileCheck %s
+
+# Too few operands
+slo t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+sro t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+sloi t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Immediate operand out of range
+sloi t0, t1, 32 # CHECK: :[[@LINE]]:14: error: immediate must be an integer in the range [0, 31]
+sloi t0, t1, -1 # CHECK: :[[@LINE]]:14: error: immediate must be an integer in the range [0, 31]
+# Too few operands
+sroi t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Immediate operand out of range
+sroi t0, t1, 32 # CHECK: :[[@LINE]]:14: error: immediate must be an integer in the range [0, 31]
+sroi t0, t1, -1 # CHECK: :[[@LINE]]:14: error: immediate must be an integer in the range [0, 31]
+# Too many operands
+clz t0, t1, t2 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction
+# Too many operands
+ctz t0, t1, t2 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction
+# Too many operands
+pcnt t0, t1, t2 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction
+# Too many operands
+sext.b t0, t1, t2 # CHECK: :[[@LINE]]:16: error: invalid operand for instruction
+# Too many operands
+sext.h t0, t1, t2 # CHECK: :[[@LINE]]:16: error: invalid operand for instruction
+# Too few operands
+min t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+max t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+minu t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+maxu t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction

diff  --git a/llvm/test/MC/RISCV/rv32zbb-valid.s b/llvm/test/MC/RISCV/rv32zbb-valid.s
new file mode 100644
index 000000000000..965f1fb47ad4
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zbb-valid.s
@@ -0,0 +1,53 @@
+# With B extension:
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-b -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-b < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-b -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# With Bitmanip base extension:
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zbb -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-zbb < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zbb -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: slo t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x12,0x73,0x20]
+slo t0, t1, t2
+# CHECK-ASM-AND-OBJ: sro t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x52,0x73,0x20]
+sro t0, t1, t2
+# CHECK-ASM-AND-OBJ: sloi t0, t1, 0
+# CHECK-ASM: encoding: [0x93,0x12,0x03,0x20]
+sloi t0, t1, 0
+# CHECK-ASM-AND-OBJ: sroi t0, t1, 0
+# CHECK-ASM: encoding: [0x93,0x52,0x03,0x20]
+sroi t0, t1, 0
+# CHECK-ASM-AND-OBJ: clz t0, t1
+# CHECK-ASM: encoding: [0x93,0x12,0x03,0x60]
+clz t0, t1
+# CHECK-ASM-AND-OBJ: ctz t0, t1
+# CHECK-ASM: encoding: [0x93,0x12,0x13,0x60]
+ctz t0, t1
+# CHECK-ASM-AND-OBJ: pcnt t0, t1
+# CHECK-ASM: encoding: [0x93,0x12,0x23,0x60]
+pcnt t0, t1
+# CHECK-ASM-AND-OBJ: sext.b t0, t1
+# CHECK-ASM: encoding: [0x93,0x12,0x43,0x60]
+sext.b t0, t1
+# CHECK-ASM-AND-OBJ: sext.h t0, t1
+# CHECK-ASM: encoding: [0x93,0x12,0x53,0x60]
+sext.h t0, t1
+# CHECK-ASM-AND-OBJ: min t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x42,0x73,0x0a]
+min t0, t1, t2
+# CHECK-ASM-AND-OBJ: max t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x52,0x73,0x0a]
+max t0, t1, t2
+# CHECK-ASM-AND-OBJ: minu t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x62,0x73,0x0a]
+minu t0, t1, t2
+# CHECK-ASM-AND-OBJ: maxu t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x72,0x73,0x0a]
+maxu t0, t1, t2

diff  --git a/llvm/test/MC/RISCV/rv32zbbp-invalid.s b/llvm/test/MC/RISCV/rv32zbbp-invalid.s
new file mode 100644
index 000000000000..67e1cd5a0b7b
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zbbp-invalid.s
@@ -0,0 +1,23 @@
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-b,experimental-zbb,experimental-zbp < %s 2>&1 | FileCheck %s
+
+# Too few operands
+andn t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+orn t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+xnor t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+rol t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+ror t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+rori t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Immediate operand out of range
+rori t0, t1, 32 # CHECK: :[[@LINE]]:14: error: immediate must be an integer in the range [0, 31]
+rori t0, t1, -1 # CHECK: :[[@LINE]]:14: error: immediate must be an integer in the range [0, 31]
+# Too few operands
+pack t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+packu t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+packh t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction

diff  --git a/llvm/test/MC/RISCV/rv32zbbp-valid.s b/llvm/test/MC/RISCV/rv32zbbp-valid.s
new file mode 100644
index 000000000000..2ab9da6eb184
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zbbp-valid.s
@@ -0,0 +1,51 @@
+# With B extension:
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-b -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-b < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-b -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# With Bitmanip base extension:
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zbb -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zbb < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zbb -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# With Bitmanip permutation extension:
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zbp -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zbp < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zbp -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: andn t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x72,0x73,0x40]
+andn t0, t1, t2
+# CHECK-ASM-AND-OBJ: orn t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x62,0x73,0x40]
+orn t0, t1, t2
+# CHECK-ASM-AND-OBJ: xnor t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x42,0x73,0x40]
+xnor t0, t1, t2
+# CHECK-ASM-AND-OBJ: rol t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x12,0x73,0x60]
+rol t0, t1, t2
+# CHECK-ASM-AND-OBJ: ror t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x52,0x73,0x60]
+ror t0, t1, t2
+# CHECK-ASM-AND-OBJ: rori t0, t1, 31
+# CHECK-ASM: encoding: [0x93,0x52,0xf3,0x61]
+rori t0, t1, 31
+# CHECK-ASM-AND-OBJ: rori t0, t1, 0
+# CHECK-ASM: encoding: [0x93,0x52,0x03,0x60]
+rori t0, t1, 0
+# CHECK-ASM-AND-OBJ: pack t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x42,0x73,0x08]
+pack t0, t1, t2
+# CHECK-ASM-AND-OBJ: packu t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x42,0x73,0x48]
+packu t0, t1, t2
+# CHECK-ASM-AND-OBJ: packh t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x72,0x73,0x08]
+packh t0, t1, t2

diff  --git a/llvm/test/MC/RISCV/rv32zbc-invalid.s b/llvm/test/MC/RISCV/rv32zbc-invalid.s
new file mode 100644
index 000000000000..6af174daddb6
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zbc-invalid.s
@@ -0,0 +1,8 @@
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-b,experimental-zbc < %s 2>&1 | FileCheck %s
+
+# Too few operands
+clmul t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+clmulr t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+clmulh t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction

diff  --git a/llvm/test/MC/RISCV/rv32zbc-valid.s b/llvm/test/MC/RISCV/rv32zbc-valid.s
new file mode 100644
index 000000000000..c423c2e6f88d
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zbc-valid.s
@@ -0,0 +1,23 @@
+# With B extension:
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-b -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-b < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-b -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# With Bitmanip carry-less multiply extension:
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zbc -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-zbc < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zbc -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: clmul t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x12,0x73,0x0a]
+clmul t0, t1, t2
+# CHECK-ASM-AND-OBJ: clmulr t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x22,0x73,0x0a]
+clmulr t0, t1, t2
+# CHECK-ASM-AND-OBJ: clmulh t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x32,0x73,0x0a]
+clmulh t0, t1, t2

diff  --git a/llvm/test/MC/RISCV/rv32zbe-invalid.s b/llvm/test/MC/RISCV/rv32zbe-invalid.s
new file mode 100644
index 000000000000..84f3d579c561
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zbe-invalid.s
@@ -0,0 +1,6 @@
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-b,experimental-zbe < %s 2>&1 | FileCheck %s
+
+# Too few operands
+bdep t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+bext t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction

diff  --git a/llvm/test/MC/RISCV/rv32zbe-valid.s b/llvm/test/MC/RISCV/rv32zbe-valid.s
new file mode 100644
index 000000000000..89e38aaa98f9
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zbe-valid.s
@@ -0,0 +1,20 @@
+# With B extension:
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-b -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-b < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-b -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# With Bitmanip extract/deposit extension:
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zbe -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-zbe < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zbe -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: bdep t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x62,0x73,0x48]
+bdep t0, t1, t2
+# CHECK-ASM-AND-OBJ: bext t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x62,0x73,0x08]
+bext t0, t1, t2

diff  --git a/llvm/test/MC/RISCV/rv32zbf-invalid.s b/llvm/test/MC/RISCV/rv32zbf-invalid.s
new file mode 100644
index 000000000000..61947618562e
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zbf-invalid.s
@@ -0,0 +1,4 @@
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-b,experimental-zbf < %s 2>&1 | FileCheck %s
+
+# Too few operands
+bfp t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction

diff  --git a/llvm/test/MC/RISCV/rv32zbf-valid.s b/llvm/test/MC/RISCV/rv32zbf-valid.s
new file mode 100644
index 000000000000..1e55e07b4a4f
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zbf-valid.s
@@ -0,0 +1,17 @@
+# With B extension:
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-b -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-b < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-b -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# With Bit-Field extension:
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zbf -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-zbf < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zbf -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: bfp t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x72,0x73,0x48]
+bfp t0, t1, t2

diff  --git a/llvm/test/MC/RISCV/rv32zbp-invalid.s b/llvm/test/MC/RISCV/rv32zbp-invalid.s
new file mode 100644
index 000000000000..da804b440550
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zbp-invalid.s
@@ -0,0 +1,30 @@
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-b,experimental-zbp < %s 2>&1 | FileCheck %s
+
+# Too few operands
+gorc t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+grev t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+gorci t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Immediate operand out of range
+gorci t0, t1, 32 # CHECK: :[[@LINE]]:15: error: immediate must be an integer in the range [0, 31]
+gorci t0, t1, -1 # CHECK: :[[@LINE]]:15: error: immediate must be an integer in the range [0, 31]
+# Too few operands
+grevi t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Immediate operand out of range
+grevi t0, t1, 32 # CHECK: :[[@LINE]]:15: error: immediate must be an integer in the range [0, 31]
+grevi t0, t1, -1 # CHECK: :[[@LINE]]:15: error: immediate must be an integer in the range [0, 31]
+# Too few operands
+shfl t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+unshfl t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+shfli t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Immediate operand out of range
+shfli t0, t1, 16 # CHECK: :[[@LINE]]:15: error: immediate must be an integer in the range [0, 15]
+shfli t0, t1, -1 # CHECK: :[[@LINE]]:15: error: immediate must be an integer in the range [0, 15]
+# Too few operands
+unshfli t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Immediate operand out of range
+unshfli t0, t1, 16 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 15]
+unshfli t0, t1, -1 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 15]

diff  --git a/llvm/test/MC/RISCV/rv32zbp-valid.s b/llvm/test/MC/RISCV/rv32zbp-valid.s
new file mode 100644
index 000000000000..503174d198b5
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zbp-valid.s
@@ -0,0 +1,38 @@
+# With B extension:
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-b -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-b < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-b -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# With Bitmanip permutation extension:
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zbp -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-zbp < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zbp -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: gorc t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x52,0x73,0x28]
+gorc t0, t1, t2
+# CHECK-ASM-AND-OBJ: grev t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x52,0x73,0x68]
+grev t0, t1, t2
+# CHECK-ASM-AND-OBJ: gorci t0, t1, 0
+# CHECK-ASM: encoding: [0x93,0x52,0x03,0x28]
+gorci t0, t1, 0
+# CHECK-ASM-AND-OBJ: grevi t0, t1, 0
+# CHECK-ASM: encoding: [0x93,0x52,0x03,0x68]
+grevi t0, t1, 0
+# CHECK-ASM-AND-OBJ: shfl t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x12,0x73,0x08]
+shfl t0, t1, t2
+# CHECK-ASM-AND-OBJ: unshfl t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x52,0x73,0x08]
+unshfl t0, t1, t2
+# CHECK-ASM-AND-OBJ: shfli t0, t1, 0
+# CHECK-ASM: encoding: [0x93,0x12,0x03,0x08]
+shfli t0, t1, 0
+# CHECK-ASM-AND-OBJ: unshfli t0, t1, 0
+# CHECK-ASM: encoding: [0x93,0x52,0x03,0x08]
+unshfli t0, t1, 0

diff  --git a/llvm/test/MC/RISCV/rv32zbproposedc-invalid.s b/llvm/test/MC/RISCV/rv32zbproposedc-invalid.s
new file mode 100644
index 000000000000..a1861b74af0b
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zbproposedc-invalid.s
@@ -0,0 +1,5 @@
+# RUN: not llvm-mc -triple riscv32 -mattr=+c,+experimental-zbproposedc < %s 2>&1 | FileCheck %s
+
+# Too many operands
+c.not s0, s1 # CHECK: :[[@LINE]]:11: error: invalid operand for instruction
+c.neg s0, s1 # CHECK: :[[@LINE]]:11: error: invalid operand for instruction

diff  --git a/llvm/test/MC/RISCV/rv32zbproposedc-valid.s b/llvm/test/MC/RISCV/rv32zbproposedc-valid.s
new file mode 100644
index 000000000000..aa41b40d3424
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zbproposedc-valid.s
@@ -0,0 +1,12 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+c,+experimental-zbproposedc -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+c,+experimental-zbproposedc < %s \
+# RUN:     | llvm-objdump --mattr=+c,+experimental-zbproposedc -M no-aliases -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: c.not s0
+# CHECK-ASM: encoding: [0x01,0x60]
+c.not s0
+# CHECK-ASM-AND-OBJ: c.neg s0
+# CHECK-ASM: encoding: [0x01,0x64]
+c.neg s0

diff  --git a/llvm/test/MC/RISCV/rv32zbr-invalid.s b/llvm/test/MC/RISCV/rv32zbr-invalid.s
new file mode 100644
index 000000000000..c25d7dd0c01b
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zbr-invalid.s
@@ -0,0 +1,14 @@
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-b,experimental-zbr < %s 2>&1 | FileCheck %s
+
+# Too many operands
+crc32.b	t0, t1, t2 # CHECK: :[[@LINE]]:17: error: invalid operand for instruction
+# Too many operands
+crc32.h	t0, t1, t2 # CHECK: :[[@LINE]]:17: error: invalid operand for instruction
+# Too many operands
+crc32.w	t0, t1, t2 # CHECK: :[[@LINE]]:17: error: invalid operand for instruction
+# Too many operands
+crc32c.b t0, t1, t2 # CHECK: :[[@LINE]]:18: error: invalid operand for instruction
+# Too many operands
+crc32c.h t0, t1, t2 # CHECK: :[[@LINE]]:18: error: invalid operand for instruction
+# Too many operands
+crc32c.w t0, t1, t2 # CHECK: :[[@LINE]]:18: error: invalid operand for instruction

diff  --git a/llvm/test/MC/RISCV/rv32zbr-valid.s b/llvm/test/MC/RISCV/rv32zbr-valid.s
new file mode 100644
index 000000000000..e2943294102b
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zbr-valid.s
@@ -0,0 +1,32 @@
+# With B extension:
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-b -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-b < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-b -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# With Bitmanip CRC extension:
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zbr -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-zbr < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zbr -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: crc32.b t0, t1
+# CHECK-ASM: encoding: [0x93,0x12,0x03,0x61]
+crc32.b	t0, t1
+# CHECK-ASM-AND-OBJ: crc32.h t0, t1
+# CHECK-ASM: encoding: [0x93,0x12,0x13,0x61]
+crc32.h	t0, t1
+# CHECK-ASM-AND-OBJ: crc32.w t0, t1
+# CHECK-ASM: encoding: [0x93,0x12,0x23,0x61]
+crc32.w	t0, t1
+# CHECK-ASM-AND-OBJ: crc32c.b t0, t1
+# CHECK-ASM: encoding: [0x93,0x12,0x83,0x61]
+crc32c.b t0, t1
+# CHECK-ASM-AND-OBJ: crc32c.h t0, t1
+# CHECK-ASM: encoding: [0x93,0x12,0x93,0x61]
+crc32c.h t0, t1
+# CHECK-ASM-AND-OBJ: crc32c.w t0, t1
+# CHECK-ASM: encoding: [0x93,0x12,0xa3,0x61]
+crc32c.w t0, t1

diff  --git a/llvm/test/MC/RISCV/rv32zbs-invalid.s b/llvm/test/MC/RISCV/rv32zbs-invalid.s
new file mode 100644
index 000000000000..6df580ec9547
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zbs-invalid.s
@@ -0,0 +1,30 @@
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-b,experimental-zbs < %s 2>&1 | FileCheck %s
+
+# Too few operands
+sbclr t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+sbset t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+sbinv t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+sbext t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+sbclri t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Immediate operand out of range
+sbclri t0, t1, 32 # CHECK: :[[@LINE]]:16: error: immediate must be an integer in the range [0, 31]
+sbclri t0, t1, -1 # CHECK: :[[@LINE]]:16: error: immediate must be an integer in the range [0, 31]
+# Too few operands
+sbseti t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Immediate operand out of range
+sbseti t0, t1, 32 # CHECK: :[[@LINE]]:16: error: immediate must be an integer in the range [0, 31]
+sbseti t0, t1, -1 # CHECK: :[[@LINE]]:16: error: immediate must be an integer in the range [0, 31]
+# Too few operands
+sbinvi t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Immediate operand out of range
+sbinvi t0, t1, 32 # CHECK: :[[@LINE]]:16: error: immediate must be an integer in the range [0, 31]
+sbinvi t0, t1, -1 # CHECK: :[[@LINE]]:16: error: immediate must be an integer in the range [0, 31]
+# Too few operands
+sbexti t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Immediate operand out of range
+sbexti t0, t1, 32 # CHECK: :[[@LINE]]:16: error: immediate must be an integer in the range [0, 31]
+sbexti t0, t1, -1 # CHECK: :[[@LINE]]:16: error: immediate must be an integer in the range [0, 31]

diff  --git a/llvm/test/MC/RISCV/rv32zbs-valid.s b/llvm/test/MC/RISCV/rv32zbs-valid.s
new file mode 100644
index 000000000000..9c3d7ce0c6ce
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zbs-valid.s
@@ -0,0 +1,38 @@
+# With B extension:
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-b -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-b < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-b -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# With Bitmanip single bit extension:
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zbs -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-zbs < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zbs -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: sbclr t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x12,0x73,0x48]
+sbclr t0, t1, t2
+# CHECK-ASM-AND-OBJ: sbset t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x12,0x73,0x28]
+sbset t0, t1, t2
+# CHECK-ASM-AND-OBJ: sbinv t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x12,0x73,0x68]
+sbinv t0, t1, t2
+# CHECK-ASM-AND-OBJ: sbext t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x52,0x73,0x48]
+sbext t0, t1, t2
+# CHECK-ASM-AND-OBJ: sbclri t0, t1, 1
+# CHECK-ASM: encoding: [0x93,0x12,0x13,0x48]
+sbclri t0, t1, 1
+# CHECK-ASM-AND-OBJ: sbseti t0, t1, 1
+# CHECK-ASM: encoding: [0x93,0x12,0x13,0x28]
+sbseti t0, t1, 1
+# CHECK-ASM-AND-OBJ: sbinvi t0, t1, 1
+# CHECK-ASM: encoding: [0x93,0x12,0x13,0x68]
+sbinvi t0, t1, 1
+# CHECK-ASM-AND-OBJ: sbexti t0, t1, 1
+# CHECK-ASM: encoding: [0x93,0x52,0x13,0x48]
+sbexti t0, t1, 1

diff  --git a/llvm/test/MC/RISCV/rv32zbt-invalid.s b/llvm/test/MC/RISCV/rv32zbt-invalid.s
new file mode 100644
index 000000000000..1c41990984a0
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zbt-invalid.s
@@ -0,0 +1,15 @@
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-b,experimental-zbt < %s 2>&1 | FileCheck %s
+
+# Too few operands
+cmix t0, t1, t2 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+cmov t0, t1, t2 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+fsl t0, t1, t2 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+fsr t0, t1, t2 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+fsri t0, t1, t2 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Immediate operand out of range
+fsri t0, t1, t2, 32 # CHECK: :[[@LINE]]:18: error: immediate must be an integer in the range [0, 31]
+fsri t0, t1, t2, -1 # CHECK: :[[@LINE]]:18: error: immediate must be an integer in the range [0, 31]

diff  --git a/llvm/test/MC/RISCV/rv32zbt-valid.s b/llvm/test/MC/RISCV/rv32zbt-valid.s
new file mode 100644
index 000000000000..16827b6a3f07
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zbt-valid.s
@@ -0,0 +1,29 @@
+# With B extension:
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-b -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-b < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-b -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# With Bitmanip ternary extension:
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zbt -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-zbt < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zbt -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: cmix t0, t1, t2, t3
+# CHECK-ASM: encoding: [0xb3,0x92,0x63,0xe6]
+cmix t0, t1, t2, t3
+# CHECK-ASM-AND-OBJ: cmov t0, t1, t2, t3
+# CHECK-ASM: encoding: [0xb3,0xd2,0x63,0xe6]
+cmov t0, t1, t2, t3
+# CHECK-ASM-AND-OBJ: fsl t0, t1, t2, t3
+# CHECK-ASM: encoding: [0xb3,0x12,0xc3,0x3d]
+fsl t0, t1, t2, t3
+# CHECK-ASM-AND-OBJ: fsr t0, t1, t2, t3
+# CHECK-ASM: encoding: [0xb3,0x52,0xc3,0x3d]
+fsr t0, t1, t2, t3
+# CHECK-ASM-AND-OBJ: fsri t0, t1, t2, 0
+# CHECK-ASM: encoding: [0x93,0x52,0x03,0x3c]
+fsri t0, t1, t2, 0

diff  --git a/llvm/test/MC/RISCV/rv64b-aliases-valid.s b/llvm/test/MC/RISCV/rv64b-aliases-valid.s
new file mode 100644
index 000000000000..02f8a8517613
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64b-aliases-valid.s
@@ -0,0 +1,316 @@
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-b -riscv-no-aliases \
+# RUN:     | FileCheck -check-prefixes=CHECK-S-OBJ-NOALIAS %s
+# RUN: llvm-mc %s  -triple=riscv64 -mattr=+experimental-b \
+# RUN:     | FileCheck -check-prefixes=CHECK-S-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+experimental-b < %s \
+# RUN:     | llvm-objdump -d -r --riscv-no-aliases --mattr=+experimental-b - \
+# RUN:     | FileCheck -check-prefixes=CHECK-S-OBJ-NOALIAS %s
+# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+experimental-b < %s \
+# RUN:     | llvm-objdump -d -r --mattr=+experimental-b - \
+# RUN:     | FileCheck -check-prefixes=CHECK-S-OBJ %s
+
+# The following check prefixes are used in this test:
+# CHECK-S-OBJ            Match both the .s and objdumped object output with
+#                        aliases enabled
+# CHECK-S-OBJ-NOALIAS    Match both the .s and objdumped object output with
+#                        aliases disabled
+
+# CHECK-S-OBJ-NOALIAS: andi t0, t1, 255
+# CHECK-S-OBJ: zext.b t0, t1
+zext.b x5, x6
+
+# CHECK-S-OBJ-NOALIAS: packw t0, t1, zero
+# CHECK-S-OBJ: zext.h t0, t1
+zext.h x5, x6
+
+# CHECK-S-OBJ-NOALIAS: pack t0, t1, zero
+# CHECK-S-OBJ: zext.w t0, t1
+zext.w x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 1
+# CHECK-S-OBJ: rev.p t0, t1
+rev.p x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 2
+# CHECK-S-OBJ: rev2.n t0, t1
+rev2.n x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 3
+# CHECK-S-OBJ: rev.n t0, t1
+rev.n x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 4
+# CHECK-S-OBJ: rev4.b t0, t1
+rev4.b x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 6
+# CHECK-S-OBJ: rev2.b t0, t1
+rev2.b x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 7
+# CHECK-S-OBJ: rev.b t0, t1
+rev.b x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 8
+# CHECK-S-OBJ: rev8.h t0, t1
+rev8.h x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 12
+# CHECK-S-OBJ: rev4.h t0, t1
+rev4.h x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 14
+# CHECK-S-OBJ: rev2.h t0, t1
+rev2.h x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 15
+# CHECK-S-OBJ: rev.h t0, t1
+rev.h x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 16
+# CHECK-S-OBJ: rev16.w t0, t1
+rev16.w x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 24
+# CHECK-S-OBJ: rev8.w t0, t1
+rev8.w x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 28
+# CHECK-S-OBJ: rev4.w t0, t1
+rev4.w x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 30
+# CHECK-S-OBJ: rev2.w t0, t1
+rev2.w x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 31
+# CHECK-S-OBJ: rev.w t0, t1
+rev.w x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 32
+# CHECK-S-OBJ: rev32 t0, t1
+rev32 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 48
+# CHECK-S-OBJ: rev16 t0, t1
+rev16 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 56
+# CHECK-S-OBJ: rev8 t0, t1
+rev8 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 60
+# CHECK-S-OBJ: rev4 t0, t1
+rev4 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 62
+# CHECK-S-OBJ: rev2 t0, t1
+rev2 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: grevi t0, t1, 63
+# CHECK-S-OBJ: rev t0, t1
+rev x5, x6
+
+# CHECK-S-OBJ-NOALIAS: shfli t0, t1, 1
+# CHECK-S-OBJ: zip.n t0, t1
+zip.n x5, x6
+
+# CHECK-S-OBJ-NOALIAS: unshfli t0, t1, 1
+# CHECK-S-OBJ: unzip.n t0, t1
+unzip.n x5, x6
+
+# CHECK-S-OBJ-NOALIAS: shfli t0, t1, 2
+# CHECK-S-OBJ: zip2.b t0, t1
+zip2.b x5, x6
+
+# CHECK-S-OBJ-NOALIAS: unshfli t0, t1, 2
+# CHECK-S-OBJ: unzip2.b t0, t1
+unzip2.b x5, x6
+
+# CHECK-S-OBJ-NOALIAS: shfli t0, t1, 3
+# CHECK-S-OBJ: zip.b t0, t1
+zip.b x5, x6
+
+# CHECK-S-OBJ-NOALIAS: unshfli t0, t1, 3
+# CHECK-S-OBJ: unzip.b t0, t1
+unzip.b x5, x6
+
+# CHECK-S-OBJ-NOALIAS: shfli t0, t1, 4
+# CHECK-S-OBJ: zip4.h t0, t1
+zip4.h x5, x6
+
+# CHECK-S-OBJ-NOALIAS: unshfli t0, t1, 4
+# CHECK-S-OBJ: unzip4.h t0, t1
+unzip4.h x5, x6
+
+# CHECK-S-OBJ-NOALIAS: shfli t0, t1, 6
+# CHECK-S-OBJ: zip2.h t0, t1
+zip2.h x5, x6
+
+# CHECK-S-OBJ-NOALIAS: unshfli t0, t1, 6
+# CHECK-S-OBJ: unzip2.h t0, t1
+unzip2.h x5, x6
+
+# CHECK-S-OBJ-NOALIAS: shfli t0, t1, 7
+# CHECK-S-OBJ: zip.h t0, t1
+zip.h x5, x6
+
+# CHECK-S-OBJ-NOALIAS: unshfli t0, t1, 7
+# CHECK-S-OBJ: unzip.h t0, t1
+unzip.h x5, x6
+
+# CHECK-S-OBJ-NOALIAS: shfli t0, t1, 8
+# CHECK-S-OBJ: zip8.w t0, t1
+zip8.w x5, x6
+
+# CHECK-S-OBJ-NOALIAS: unshfli t0, t1, 8
+# CHECK-S-OBJ: unzip8.w t0, t1
+unzip8.w x5, x6
+
+# CHECK-S-OBJ-NOALIAS: shfli t0, t1, 12
+# CHECK-S-OBJ: zip4.w t0, t1
+zip4.w x5, x6
+
+# CHECK-S-OBJ-NOALIAS: unshfli t0, t1, 12
+# CHECK-S-OBJ: unzip4.w t0, t1
+unzip4.w x5, x6
+
+# CHECK-S-OBJ-NOALIAS: shfli t0, t1, 14
+# CHECK-S-OBJ: zip2.w t0, t1
+zip2.w x5, x6
+
+# CHECK-S-OBJ-NOALIAS: unshfli t0, t1, 14
+# CHECK-S-OBJ: unzip2.w t0, t1
+unzip2.w x5, x6
+
+# CHECK-S-OBJ-NOALIAS: shfli t0, t1, 15
+# CHECK-S-OBJ: zip.w t0, t1
+zip.w x5, x6
+
+# CHECK-S-OBJ-NOALIAS: unshfli t0, t1, 15
+# CHECK-S-OBJ: unzip.w t0, t1
+unzip.w x5, x6
+
+# CHECK-S-OBJ-NOALIAS: shfli t0, t1, 16
+# CHECK-S-OBJ: zip16 t0, t1
+zip16 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: unshfli t0, t1, 16
+# CHECK-S-OBJ: unzip16 t0, t1
+unzip16 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: shfli t0, t1, 24
+# CHECK-S-OBJ: zip8 t0, t1
+zip8 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: unshfli t0, t1, 24
+# CHECK-S-OBJ: unzip8 t0, t1
+unzip8 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: shfli t0, t1, 28
+# CHECK-S-OBJ: zip4 t0, t1
+zip4 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: unshfli t0, t1, 28
+# CHECK-S-OBJ: unzip4 t0, t1
+unzip4 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: shfli t0, t1, 30
+# CHECK-S-OBJ: zip2 t0, t1
+zip2 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: unshfli t0, t1, 30
+# CHECK-S-OBJ: unzip2 t0, t1
+unzip2 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: shfli t0, t1, 31
+# CHECK-S-OBJ: zip t0, t1
+zip x5, x6
+
+# CHECK-S-OBJ-NOALIAS: unshfli t0, t1, 31
+# CHECK-S-OBJ: unzip t0, t1
+unzip x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 1
+# CHECK-S-OBJ: orc.p t0, t1
+orc.p x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 2
+# CHECK-S-OBJ: orc2.n t0, t1
+orc2.n x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 3
+# CHECK-S-OBJ: orc.n t0, t1
+orc.n x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 4
+# CHECK-S-OBJ: orc4.b t0, t1
+orc4.b x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 6
+# CHECK-S-OBJ: orc2.b t0, t1
+orc2.b x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 7
+# CHECK-S-OBJ: orc.b t0, t1
+orc.b x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 8
+# CHECK-S-OBJ: orc8.h t0, t1
+orc8.h x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 12
+# CHECK-S-OBJ: orc4.h t0, t1
+orc4.h x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 14
+# CHECK-S-OBJ: orc2.h t0, t1
+orc2.h x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 15
+# CHECK-S-OBJ: orc.h t0, t1
+orc.h x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 16
+# CHECK-S-OBJ: orc16.w t0, t1
+orc16.w x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 24
+# CHECK-S-OBJ: orc8.w t0, t1
+orc8.w x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 28
+# CHECK-S-OBJ: orc4.w t0, t1
+orc4.w x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 30
+# CHECK-S-OBJ: orc2.w t0, t1
+orc2.w x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 31
+# CHECK-S-OBJ: orc.w t0, t1
+orc.w x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 32
+# CHECK-S-OBJ: orc32 t0, t1
+orc32 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 48
+# CHECK-S-OBJ: orc16 t0, t1
+orc16 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 56
+# CHECK-S-OBJ: orc8 t0, t1
+orc8 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 60
+# CHECK-S-OBJ: orc4 t0, t1
+orc4 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 62
+# CHECK-S-OBJ: orc2 t0, t1
+orc2 x5, x6
+
+# CHECK-S-OBJ-NOALIAS: gorci t0, t1, 63
+# CHECK-S-OBJ: orc t0, t1
+orc x5, x6

diff  --git a/llvm/test/MC/RISCV/rv64zbb-invalid.s b/llvm/test/MC/RISCV/rv64zbb-invalid.s
new file mode 100644
index 000000000000..49cec99a58ae
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64zbb-invalid.s
@@ -0,0 +1,40 @@
+# RUN: not llvm-mc -triple riscv64 -mattr=+experimental-b,experimental-zbb < %s 2>&1 | FileCheck %s
+
+# Too few operands
+addiwu t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Immediate operand out of range
+addiwu t0, t1, 2048 # CHECK: :[[@LINE]]:16: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047]
+addiwu t0, t1, -2049 # CHECK: :[[@LINE]]:16: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047]
+# Too few operands
+slliu.w t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Immediate operand out of range
+slliu.w t0, t1, 64 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 63]
+slliu.w t0, t1, -1 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 63]
+# Too few operands
+addwu t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+subwu t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+addu.w t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+subu.w t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+slow t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+srow t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+sloiw t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Immediate operand out of range
+sloiw t0, t1, 32 # CHECK: :[[@LINE]]:15: error: immediate must be an integer in the range [0, 31]
+sloiw t0, t1, -1 # CHECK: :[[@LINE]]:15: error: immediate must be an integer in the range [0, 31]
+# Too few operands
+sroiw t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Immediate operand out of range
+sroiw t0, t1, 32 # CHECK: :[[@LINE]]:15: error: immediate must be an integer in the range [0, 31]
+sroiw t0, t1, -1 # CHECK: :[[@LINE]]:15: error: immediate must be an integer in the range [0, 31]
+# Too many operands
+clzw t0, t1, t2 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction
+# Too many operands
+ctzw t0, t1, t2 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction
+# Too many operands
+pcntw t0, t1, t2 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction

diff  --git a/llvm/test/MC/RISCV/rv64zbb-valid.s b/llvm/test/MC/RISCV/rv64zbb-valid.s
new file mode 100644
index 000000000000..a6be8aea8029
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64zbb-valid.s
@@ -0,0 +1,53 @@
+# With B extension:
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-b -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-b < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-b -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# With Bitmanip base extension:
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zbb -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zbb < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zbb -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: addiwu t0, t1, 0
+# CHECK-ASM: encoding: [0x9b,0x42,0x03,0x00]
+addiwu t0, t1, 0
+# CHECK-ASM-AND-OBJ: slliu.w t0, t1, 0
+# CHECK-ASM: encoding: [0x9b,0x12,0x03,0x08]
+slliu.w t0, t1, 0
+# CHECK-ASM-AND-OBJ: addwu t0, t1, t2
+# CHECK-ASM: encoding: [0xbb,0x02,0x73,0x0a]
+addwu t0, t1, t2
+# CHECK-ASM-AND-OBJ: subwu t0, t1, t2
+# CHECK-ASM: encoding: [0xbb,0x02,0x73,0x4a]
+subwu t0, t1, t2
+# CHECK-ASM-AND-OBJ: addu.w t0, t1, t2
+# CHECK-ASM: encoding: [0xbb,0x02,0x73,0x08]
+addu.w t0, t1, t2
+# CHECK-ASM-AND-OBJ: subu.w t0, t1, t2
+# CHECK-ASM: encoding: [0xbb,0x02,0x73,0x48]
+subu.w t0, t1, t2
+# CHECK-ASM-AND-OBJ: slow t0, t1, t2
+# CHECK-ASM: encoding: [0xbb,0x12,0x73,0x20]
+slow t0, t1, t2
+# CHECK-ASM-AND-OBJ: srow t0, t1, t2
+# CHECK-ASM: encoding: [0xbb,0x52,0x73,0x20]
+srow t0, t1, t2
+# CHECK-ASM-AND-OBJ: sloiw t0, t1, 0
+# CHECK-ASM: encoding: [0x9b,0x12,0x03,0x20]
+sloiw t0, t1, 0
+# CHECK-ASM-AND-OBJ: sroiw t0, t1, 0
+# CHECK-ASM: encoding: [0x9b,0x52,0x03,0x20]
+sroiw t0, t1, 0
+# CHECK-ASM-AND-OBJ: clzw t0, t1
+# CHECK-ASM: encoding: [0x9b,0x12,0x03,0x60]
+clzw t0, t1
+# CHECK-ASM-AND-OBJ: ctzw t0, t1
+# CHECK-ASM: encoding: [0x9b,0x12,0x13,0x60]
+ctzw t0, t1
+# CHECK-ASM-AND-OBJ: pcntw t0, t1
+# CHECK-ASM: encoding: [0x9b,0x12,0x23,0x60]
+pcntw t0, t1

diff  --git a/llvm/test/MC/RISCV/rv64zbbp-invalid.s b/llvm/test/MC/RISCV/rv64zbbp-invalid.s
new file mode 100644
index 000000000000..78d827a1856c
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64zbbp-invalid.s
@@ -0,0 +1,15 @@
+# RUN: not llvm-mc -triple riscv64 -mattr=+experimental-b,experimental-zbb,experimental-zbp < %s 2>&1 | FileCheck %s
+
+# Too few operands
+rolw t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+rorw t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+roriw t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Immediate operand out of range
+roriw t0, t1, 32 # CHECK: :[[@LINE]]:15: error: immediate must be an integer in the range [0, 31]
+roriw t0, t1, -1 # CHECK: :[[@LINE]]:15: error: immediate must be an integer in the range [0, 31]
+# Too few operands
+packw t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+packuw t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction

diff  --git a/llvm/test/MC/RISCV/rv64zbbp-valid.s b/llvm/test/MC/RISCV/rv64zbbp-valid.s
new file mode 100644
index 000000000000..5c27472e03b0
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64zbbp-valid.s
@@ -0,0 +1,39 @@
+# With B extension:
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-b -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-b < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-b -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# With Bitmanip base extension:
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zbb -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zbb < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zbb -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# With Bitmanip permutation extension:
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zbp -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zbp < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zbp -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: rolw t0, t1, t2
+# CHECK-ASM: encoding: [0xbb,0x12,0x73,0x60]
+rolw t0, t1, t2
+# CHECK-ASM-AND-OBJ: rorw t0, t1, t2
+# CHECK-ASM: encoding: [0xbb,0x52,0x73,0x60]
+rorw t0, t1, t2
+# CHECK-ASM-AND-OBJ: roriw t0, t1, 31
+# CHECK-ASM: encoding: [0x9b,0x52,0xf3,0x61]
+roriw t0, t1, 31
+# CHECK-ASM-AND-OBJ: roriw t0, t1, 0
+# CHECK-ASM: encoding: [0x9b,0x52,0x03,0x60]
+roriw t0, t1, 0
+# CHECK-ASM-AND-OBJ: packw t0, t1, t2
+# CHECK-ASM: encoding: [0xbb,0x42,0x73,0x08]
+packw t0, t1, t2
+# CHECK-ASM-AND-OBJ: packuw t0, t1, t2
+# CHECK-ASM: encoding: [0xbb,0x42,0x73,0x48]
+packuw t0, t1, t2

diff  --git a/llvm/test/MC/RISCV/rv64zbc-invalid.s b/llvm/test/MC/RISCV/rv64zbc-invalid.s
new file mode 100644
index 000000000000..abae9cb94931
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64zbc-invalid.s
@@ -0,0 +1,8 @@
+# RUN: not llvm-mc -triple riscv64 -mattr=+experimental-b,experimental-zbc < %s 2>&1 | FileCheck %s
+
+# Too few operands
+clmulw t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+clmulrw t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+clmulhw t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction

diff  --git a/llvm/test/MC/RISCV/rv64zbc-valid.s b/llvm/test/MC/RISCV/rv64zbc-valid.s
new file mode 100644
index 000000000000..7259dc2e1b99
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64zbc-valid.s
@@ -0,0 +1,23 @@
+# With B extension:
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-b -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-b < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-b -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# With Bitmanip carry-less multiply extension:
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zbc -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zbc < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zbc -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: clmulw t0, t1, t2
+# CHECK-ASM: encoding: [0xbb,0x12,0x73,0x0a]
+clmulw t0, t1, t2
+# CHECK-ASM-AND-OBJ: clmulrw t0, t1, t2
+# CHECK-ASM: encoding: [0xbb,0x22,0x73,0x0a]
+clmulrw t0, t1, t2
+# CHECK-ASM-AND-OBJ: clmulhw t0, t1, t2
+# CHECK-ASM: encoding: [0xbb,0x32,0x73,0x0a]
+clmulhw t0, t1, t2

diff  --git a/llvm/test/MC/RISCV/rv64zbe-invalid.s b/llvm/test/MC/RISCV/rv64zbe-invalid.s
new file mode 100644
index 000000000000..5c4bb8248b9a
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64zbe-invalid.s
@@ -0,0 +1,6 @@
+# RUN: not llvm-mc -triple riscv64 -mattr=+experimental-b,experimental-zbe < %s 2>&1 | FileCheck %s
+
+# Too few operands
+bdepw t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+bextw t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction

diff  --git a/llvm/test/MC/RISCV/rv64zbe-valid.s b/llvm/test/MC/RISCV/rv64zbe-valid.s
new file mode 100644
index 000000000000..1c9d1ceee212
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64zbe-valid.s
@@ -0,0 +1,20 @@
+# With B extension:
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-b -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-b < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-b -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# With Bitmanip extract/deposit extension:
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zbe -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zbe < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zbe -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: bdepw t0, t1, t2
+# CHECK-ASM: encoding: [0xbb,0x62,0x73,0x48]
+bdepw t0, t1, t2
+# CHECK-ASM-AND-OBJ: bextw t0, t1, t2
+# CHECK-ASM: encoding: [0xbb,0x62,0x73,0x08]
+bextw t0, t1, t2

diff  --git a/llvm/test/MC/RISCV/rv64zbf-invalid.s b/llvm/test/MC/RISCV/rv64zbf-invalid.s
new file mode 100644
index 000000000000..0eb91cf0c0a9
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64zbf-invalid.s
@@ -0,0 +1,4 @@
+# RUN: not llvm-mc -triple riscv64 -mattr=+experimental-b,experimental-zbf < %s 2>&1 | FileCheck %s
+
+# Too few operands
+bfpw t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction

diff  --git a/llvm/test/MC/RISCV/rv64zbf-valid.s b/llvm/test/MC/RISCV/rv64zbf-valid.s
new file mode 100644
index 000000000000..2e02a86b95ab
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64zbf-valid.s
@@ -0,0 +1,17 @@
+# With B extension:
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-b -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-b < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-b -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# With Bit-Field extension:
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zbf -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zbf < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zbf -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: bfpw t0, t1, t2
+# CHECK-ASM: encoding: [0xbb,0x72,0x73,0x48]
+bfpw t0, t1, t2

diff  --git a/llvm/test/MC/RISCV/rv64zbm-invalid.s b/llvm/test/MC/RISCV/rv64zbm-invalid.s
new file mode 100644
index 000000000000..2a750074896c
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64zbm-invalid.s
@@ -0,0 +1,8 @@
+# RUN: not llvm-mc -triple riscv64 -mattr=+experimental-b,experimental-zbm < %s 2>&1 | FileCheck %s
+
+# Too many operands
+bmatflip t0, t1, t2 # CHECK: :[[@LINE]]:18: error: invalid operand for instruction
+# Too few operands
+bmator t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+bmatxor t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction

diff  --git a/llvm/test/MC/RISCV/rv64zbm-valid.s b/llvm/test/MC/RISCV/rv64zbm-valid.s
new file mode 100644
index 000000000000..dc095cf960db
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64zbm-valid.s
@@ -0,0 +1,23 @@
+# With B extension:
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-b -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-b < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-b -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# With Bitmanip matix extension:
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zbm -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zbm < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zbm -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: bmatflip t0, t1
+# CHECK-ASM: encoding: [0x93,0x12,0x33,0x60]
+bmatflip t0, t1
+# CHECK-ASM-AND-OBJ: bmator t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x32,0x73,0x08]
+bmator t0, t1, t2
+# CHECK-ASM-AND-OBJ: bmatxor t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x32,0x73,0x48]
+bmatxor t0, t1, t2

diff  --git a/llvm/test/MC/RISCV/rv64zbp-invalid.s b/llvm/test/MC/RISCV/rv64zbp-invalid.s
new file mode 100644
index 000000000000..c1ccd7d2480c
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64zbp-invalid.s
@@ -0,0 +1,20 @@
+# RUN: not llvm-mc -triple riscv64 -mattr=+experimental-b,experimental-zbp < %s 2>&1 | FileCheck %s
+
+# Too few operands
+gorcw t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+grevw t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+gorciw t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Immediate operand out of range
+gorciw t0, t1, 32 # CHECK: :[[@LINE]]:16: error: immediate must be an integer in the range [0, 31]
+gorciw t0, t1, -1 # CHECK: :[[@LINE]]:16: error: immediate must be an integer in the range [0, 31]
+# Too few operands
+greviw t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Immediate operand out of range
+greviw t0, t1, 32 # CHECK: :[[@LINE]]:16: error: immediate must be an integer in the range [0, 31]
+greviw t0, t1, -1 # CHECK: :[[@LINE]]:16: error: immediate must be an integer in the range [0, 31]
+# Too few operands
+shflw t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+unshflw t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction

diff  --git a/llvm/test/MC/RISCV/rv64zbp-valid.s b/llvm/test/MC/RISCV/rv64zbp-valid.s
new file mode 100644
index 000000000000..47d9002c3e85
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64zbp-valid.s
@@ -0,0 +1,32 @@
+# With B extension:
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-b -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-b < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-b -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# With Bitmanip permutation extension:
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zbp -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zbp < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zbp -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: gorcw t0, t1, t2
+# CHECK-ASM: encoding: [0xbb,0x52,0x73,0x28]
+gorcw t0, t1, t2
+# CHECK-ASM-AND-OBJ: grevw t0, t1, t2
+# CHECK-ASM: encoding: [0xbb,0x52,0x73,0x68]
+grevw t0, t1, t2
+# CHECK-ASM-AND-OBJ: gorciw t0, t1, 0
+# CHECK-ASM: encoding: [0x9b,0x52,0x03,0x28]
+gorciw t0, t1, 0
+# CHECK-ASM-AND-OBJ: greviw t0, t1, 0
+# CHECK-ASM: encoding: [0x9b,0x52,0x03,0x68]
+greviw t0, t1, 0
+# CHECK-ASM-AND-OBJ: shflw t0, t1, t2
+# CHECK-ASM: encoding: [0xbb,0x12,0x73,0x08]
+shflw t0, t1, t2
+# CHECK-ASM-AND-OBJ: unshflw t0, t1, t2
+# CHECK-ASM: encoding: [0xbb,0x52,0x73,0x08]
+unshflw t0, t1, t2

diff  --git a/llvm/test/MC/RISCV/rv64zbproposedc-invalid.s b/llvm/test/MC/RISCV/rv64zbproposedc-invalid.s
new file mode 100644
index 000000000000..98accef76204
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64zbproposedc-invalid.s
@@ -0,0 +1,4 @@
+# RUN: not llvm-mc -triple riscv64 -mattr=+c,+experimental-zbproposedc,+experimental-b < %s 2>&1 | FileCheck %s
+
+# Too many operands
+c.zext.w s0, s1 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction

diff  --git a/llvm/test/MC/RISCV/rv64zbproposedc-valid.s b/llvm/test/MC/RISCV/rv64zbproposedc-valid.s
new file mode 100644
index 000000000000..68d9329d794f
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64zbproposedc-valid.s
@@ -0,0 +1,10 @@
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+c,+experimental-zbproposedc,+experimental-b -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+c,+experimental-zbproposedc,+experimental-b < %s \
+# RUN:     | llvm-objdump --mattr=+c,+experimental-zbproposedc,+experimental-b -M no-aliases -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+
+# CHECK-ASM-AND-OBJ: c.zext.w s0
+# CHECK-ASM: encoding: [0x01,0x68]
+c.zext.w s0

diff  --git a/llvm/test/MC/RISCV/rv64zbr-invalid.s b/llvm/test/MC/RISCV/rv64zbr-invalid.s
new file mode 100644
index 000000000000..a5e6897c2530
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64zbr-invalid.s
@@ -0,0 +1,6 @@
+# RUN: not llvm-mc -triple riscv64 -mattr=+experimental-b,experimental-zbr < %s 2>&1 | FileCheck %s
+
+# Too many operands
+crc32.d t0, t1, t2 # CHECK: :[[@LINE]]:17: error: invalid operand for instruction
+# Too many operands
+crc32c.d t0, t1, t2 # CHECK: :[[@LINE]]:18: error: invalid operand for instruction

diff  --git a/llvm/test/MC/RISCV/rv64zbr-valid.s b/llvm/test/MC/RISCV/rv64zbr-valid.s
new file mode 100644
index 000000000000..497c8ec0b1bc
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64zbr-valid.s
@@ -0,0 +1,20 @@
+# With B extension:
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-b -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-b < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-b -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# With Bitmanip CRC extension:
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zbr -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zbr < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zbr -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: crc32.d t0, t1
+# CHECK-ASM: encoding: [0x93,0x12,0x33,0x61]
+crc32.d t0, t1
+# CHECK-ASM-AND-OBJ: crc32c.d t0, t1
+# CHECK-ASM: encoding: [0x93,0x12,0xb3,0x61]
+crc32c.d t0, t1

diff  --git a/llvm/test/MC/RISCV/rv64zbs-invalid.s b/llvm/test/MC/RISCV/rv64zbs-invalid.s
new file mode 100644
index 000000000000..fbadeec83c29
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64zbs-invalid.s
@@ -0,0 +1,25 @@
+# RUN: not llvm-mc -triple riscv64 -mattr=+experimental-b,experimental-zbs < %s 2>&1 | FileCheck %s
+
+# Too few operands
+sbclrw t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+sbsetw t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+sbinvw t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+sbextw t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+sbclriw t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Immediate operand out of range
+sbclriw t0, t1, 32 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 31]
+sbclriw t0, t1, -1 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 31]
+# Too few operands
+sbsetiw t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Immediate operand out of range
+sbsetiw t0, t1, 32 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 31]
+sbsetiw t0, t1, -1 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 31]
+# Too few operands
+sbinviw t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Immediate operand out of range
+sbinviw t0, t1, 32 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 31]
+sbinviw t0, t1, -1 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 31]

diff  --git a/llvm/test/MC/RISCV/rv64zbs-valid.s b/llvm/test/MC/RISCV/rv64zbs-valid.s
new file mode 100644
index 000000000000..aa010a2b7944
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64zbs-valid.s
@@ -0,0 +1,35 @@
+# With B extension:
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-b -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-b < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-b -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# With Bitmanip single bit extension:
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zbs -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zbs < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zbs -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: sbclrw t0, t1, t2
+# CHECK-ASM: encoding: [0xbb,0x12,0x73,0x48]
+sbclrw t0, t1, t2
+# CHECK-ASM-AND-OBJ: sbsetw t0, t1, t2
+# CHECK-ASM: encoding: [0xbb,0x12,0x73,0x28]
+sbsetw t0, t1, t2
+# CHECK-ASM-AND-OBJ: sbinvw t0, t1, t2
+# CHECK-ASM: encoding: [0xbb,0x12,0x73,0x68]
+sbinvw t0, t1, t2
+# CHECK-ASM-AND-OBJ: sbextw t0, t1, t2
+# CHECK-ASM: encoding: [0xbb,0x52,0x73,0x48]
+sbextw t0, t1, t2
+# CHECK-ASM-AND-OBJ: sbclriw  t0, t1, 0
+# CHECK-ASM: encoding: [0x9b,0x12,0x03,0x48]
+sbclriw	t0, t1, 0
+# CHECK-ASM-AND-OBJ: sbsetiw  t0, t1, 0
+# CHECK-ASM: encoding: [0x9b,0x12,0x03,0x28]
+sbsetiw	t0, t1, 0
+# CHECK-ASM-AND-OBJ: sbinviw  t0, t1, 0
+# CHECK-ASM: encoding: [0x9b,0x12,0x03,0x68]
+sbinviw	t0, t1, 0

diff  --git a/llvm/test/MC/RISCV/rv64zbt-invalid.s b/llvm/test/MC/RISCV/rv64zbt-invalid.s
new file mode 100644
index 000000000000..57f36b9af30c
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64zbt-invalid.s
@@ -0,0 +1,9 @@
+# RUN: not llvm-mc -triple riscv64 -mattr=+experimental-b,experimental-zbt < %s 2>&1 | FileCheck %s
+
+# Too few operands
+fslw t0, t1, t2 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Too few operands
+fsrw t0, t1, t2 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+# Immediate operand out of range
+fsriw t0, t1, t2, 32 # CHECK: :[[@LINE]]:19: error: immediate must be an integer in the range [0, 31]
+fsriw t0, t1, t2, -1 # CHECK: :[[@LINE]]:19: error: immediate must be an integer in the range [0, 31]

diff  --git a/llvm/test/MC/RISCV/rv64zbt-valid.s b/llvm/test/MC/RISCV/rv64zbt-valid.s
new file mode 100644
index 000000000000..ba0daac19a74
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64zbt-valid.s
@@ -0,0 +1,23 @@
+# With B extension:
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-b -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-b < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-b -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# With Bitmanip ternary extension:
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zbt -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zbt < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zbt -d -r - \
+# RUN:     | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: fslw t0, t1, t2, t3
+# CHECK-ASM: encoding: [0xbb,0x12,0xc3,0x3d]
+fslw t0, t1, t2, t3
+# CHECK-ASM-AND-OBJ: fsrw t0, t1, t2, t3
+# CHECK-ASM: encoding: [0xbb,0x52,0xc3,0x3d]
+fsrw t0, t1, t2, t3
+# CHECK-ASM-AND-OBJ: fsriw t0, t1, t2, 0
+# CHECK-ASM: encoding: [0x9b,0x52,0x03,0x3c]
+fsriw t0, t1, t2, 0


        


More information about the llvm-commits mailing list