https://github.com/ArcaneNibble updated 
https://github.com/llvm/llvm-project/pull/97925

>From e83b666bdd445a265bd12c5c1611566adb0d9914 Mon Sep 17 00:00:00 2001
From: R <r...@berkeley.edu>
Date: Sat, 29 Jun 2024 20:51:51 +0100
Subject: [PATCH] [RISCV] Add QingKe "XW" compressed opcode extension

This extension consists of 8 additional 16-bit compressed forms
for existing standard load/store opcodes.

These opcodes are found in some RISC-V microcontrollers from
WCH / Nanjing Qinheng Microelectronics.

As discussed in the Discourse forums, this uses incompatible
extension and opcode names vs the vendor binary toolchain.
The chosen names instead follow the conventions for other
vendor extensions listed on the "riscv-non-isa" project.
---
 .../Driver/print-supported-extensions-riscv.c |   1 +
 llvm/docs/RISCVUsage.rst                      |   3 +
 llvm/docs/ReleaseNotes.rst                    |   2 +
 .../Target/RISCV/AsmParser/RISCVAsmParser.cpp |  28 +++
 .../RISCV/Disassembler/RISCVDisassembler.cpp  |   3 +
 .../Target/RISCV/MCTargetDesc/RISCVBaseInfo.h |   2 +
 llvm/lib/Target/RISCV/RISCVFeatures.td        |  10 +
 llvm/lib/Target/RISCV/RISCVInstrInfo.cpp      |   6 +
 llvm/lib/Target/RISCV/RISCVInstrInfo.td       |   1 +
 llvm/lib/Target/RISCV/RISCVInstrInfoXwch.td   | 199 ++++++++++++++++++
 llvm/lib/TargetParser/RISCVISAInfo.cpp        |  15 +-
 llvm/test/CodeGen/RISCV/attributes.ll         |   2 +
 llvm/test/MC/RISCV/xwchc-compress.s           | 198 +++++++++++++++++
 llvm/test/MC/RISCV/xwchc-invalid.s            |  21 ++
 llvm/test/MC/RISCV/xwchc-valid.s              | 145 +++++++++++++
 .../TargetParser/RISCVISAInfoTest.cpp         |   1 +
 16 files changed, 635 insertions(+), 2 deletions(-)
 create mode 100644 llvm/lib/Target/RISCV/RISCVInstrInfoXwch.td
 create mode 100644 llvm/test/MC/RISCV/xwchc-compress.s
 create mode 100644 llvm/test/MC/RISCV/xwchc-invalid.s
 create mode 100644 llvm/test/MC/RISCV/xwchc-valid.s

diff --git a/clang/test/Driver/print-supported-extensions-riscv.c 
b/clang/test/Driver/print-supported-extensions-riscv.c
index 49bdb21ac59d6..317e308fd21b2 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -166,6 +166,7 @@
 // CHECK-NEXT:     xtheadsync           1.0       'xtheadsync' (T-Head 
multicore synchronization instructions)
 // CHECK-NEXT:     xtheadvdot           1.0       'xtheadvdot' (T-Head Vector 
Extensions for Dot)
 // CHECK-NEXT:     xventanacondops      1.0       'XVentanaCondOps' (Ventana 
Conditional Ops)
+// CHECK-NEXT:     xwchc                2.2       'Xwchc' (WCH/QingKe 
additional compressed opcodes)
 // CHECK-EMPTY:
 // CHECK-NEXT: Experimental extensions
 // CHECK-NEXT:     zicfilp              0.4       'Zicfilp' (Landing pad)
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 41b22020670d8..2e3b68227ae62 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -369,6 +369,9 @@ The current vendor extensions supported are:
 ``XSfcease``
   LLVM implements `the SiFive sf.cease instruction specified in 
<https://sifive.cdn.prismic.io/sifive/767804da-53b2-4893-97d5-b7c030ae0a94_s76mc_core_complex_manual_21G3.pdf>`_
 by SiFive.
 
+``Xwchc``
+  LLVM implements `the custom compressed opcodes present in some QingKe cores` 
by WCH / Nanjing Qinheng Microelectronics. The vendor refers to these opcodes 
by the name "XW".
+
 Experimental C Intrinsics
 =========================
 
diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index 9e8a2b24e1a4e..8daa4d0be5989 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -195,6 +195,8 @@ Changes to the RISC-V Backend
   fully compatible with objects produced prior to this change. The mapping
   (ABI) used is recorded as an ELF attribute.
 * Ztso is no longer experimental.
+* The WCH / Nanjing Qinheng Microelectronics QingKe "XW" compressed opcodes are
+  supported under the name "Xwchc".
 
 Changes to the WebAssembly Backend
 ----------------------------------
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp 
b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 5424c8154d555..333db1b233d1a 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -809,6 +809,26 @@ struct RISCVOperand final : public MCParsedAsmOperand {
            VK == RISCVMCExpr::VK_RISCV_None;
   }
 
+  bool isUImm5Lsb0() const {
+    if (!isImm())
+      return false;
+    int64_t Imm;
+    RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
+    bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
+    return IsConstantImm && isShiftedUInt<4, 1>(Imm) &&
+           VK == RISCVMCExpr::VK_RISCV_None;
+  }
+
+  bool isUImm6Lsb0() const {
+    if (!isImm())
+      return false;
+    int64_t Imm;
+    RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
+    bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
+    return IsConstantImm && isShiftedUInt<5, 1>(Imm) &&
+           VK == RISCVMCExpr::VK_RISCV_None;
+  }
+
   bool isUImm7Lsb00() const {
     if (!isImm())
       return false;
@@ -1502,6 +1522,14 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc 
IDLoc, unsigned &Opcode,
     return generateImmOutOfRangeError(
         Operands, ErrorInfo, 1, (1 << 5) - 1,
         "immediate must be in [0xfffe0, 0xfffff] or");
+  case Match_InvalidUImm5Lsb0:
+    return generateImmOutOfRangeError(
+        Operands, ErrorInfo, 0, (1 << 5) - 2,
+        "immediate must be a multiple of 2 bytes in the range");
+  case Match_InvalidUImm6Lsb0:
+    return generateImmOutOfRangeError(
+        Operands, ErrorInfo, 0, (1 << 6) - 2,
+        "immediate must be a multiple of 2 bytes in the range");
   case Match_InvalidUImm7Lsb00:
     return generateImmOutOfRangeError(
         Operands, ErrorInfo, 0, (1 << 7) - 4,
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp 
b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index b9e8e1f33d3ae..23897e2d98f63 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -646,6 +646,9 @@ DecodeStatus RISCVDisassembler::getInstruction16(MCInst 
&MI, uint64_t &Size,
   TRY_TO_DECODE_FEATURE(
       RISCV::FeatureStdExtZcmp, DecoderTableRVZcmp16,
       "Zcmp table (16-bit Push/Pop & Double Move Instructions)");
+  TRY_TO_DECODE_AND_ADD_SP(STI.hasFeature(RISCV::FeatureVendorXwchc),
+                           DecoderTableXwchc16,
+                           "WCH QingKe XW custom opcode table");
   TRY_TO_DECODE_AND_ADD_SP(true, DecoderTable16,
                            "RISCV_C table (16-bit Instruction)");
 
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h 
b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index cf83bd977939e..626206962e752 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -269,7 +269,9 @@ enum OperandType : unsigned {
   OPERAND_UIMM3,
   OPERAND_UIMM4,
   OPERAND_UIMM5,
+  OPERAND_UIMM5_LSB0,
   OPERAND_UIMM6,
+  OPERAND_UIMM6_LSB0,
   OPERAND_UIMM7,
   OPERAND_UIMM7_LSB00,
   OPERAND_UIMM8_LSB00,
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td 
b/llvm/lib/Target/RISCV/RISCVFeatures.td
index e2a8fb485850f..a96ccc8864429 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1210,6 +1210,16 @@ def HasVendorXCVbi
       AssemblerPredicate<(all_of FeatureVendorXCVbi),
                          "'XCVbi' (CORE-V Immediate Branching)">;
 
+// WCH / Nanjing Qinheng Microelectronics Extension(s)
+
+def FeatureVendorXwchc
+    : RISCVExtension<"xwchc", 2, 2,
+                     "'Xwchc' (WCH/QingKe additional compressed opcodes)">;
+def HasVendorXwchc
+    : Predicate<"Subtarget->hasVendorXwchc()">,
+      AssemblerPredicate<(all_of FeatureVendorXwchc),
+                         "'Xwchc' (WCH/QingKe additional compressed opcodes)">;
+
 
//===----------------------------------------------------------------------===//
 // LLVM specific features and extensions
 
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp 
b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index 3e3292ccc148a..3578a34a3478e 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -2387,6 +2387,12 @@ bool RISCVInstrInfo::verifyInstruction(const 
MachineInstr &MI,
         case RISCVOp::OPERAND_UIMM2_LSB0:
           Ok = isShiftedUInt<1, 1>(Imm);
           break;
+        case RISCVOp::OPERAND_UIMM5_LSB0:
+          Ok = isShiftedUInt<4, 1>(Imm);
+          break;
+        case RISCVOp::OPERAND_UIMM6_LSB0:
+          Ok = isShiftedUInt<5, 1>(Imm);
+          break;
         case RISCVOp::OPERAND_UIMM7_LSB00:
           Ok = isShiftedUInt<5, 2>(Imm);
           break;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td 
b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index 075aaae2ce507..04054d2c3feee 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -2080,6 +2080,7 @@ include "RISCVInstrInfoXTHead.td"
 include "RISCVInstrInfoXSf.td"
 include "RISCVInstrInfoSFB.td"
 include "RISCVInstrInfoXCV.td"
+include "RISCVInstrInfoXwch.td"
 
 
//===----------------------------------------------------------------------===//
 // Global ISel
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXwch.td 
b/llvm/lib/Target/RISCV/RISCVInstrInfoXwch.td
new file mode 100644
index 0000000000000..91ff804ba105a
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXwch.td
@@ -0,0 +1,199 @@
+//===-- RISCVInstrInfoXwch.td ------------------------------*- tablegen 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the vendor extension(s) defined by WCH.
+//
+//===----------------------------------------------------------------------===//
+
+class QKStackInst<bits<2> funct2, dag outs, dag ins,
+                  string opcodestr, string argstr>
+    : RVInst16<outs, ins, opcodestr, argstr, [], InstFormatOther> {
+  bits<3> rd_rs2;
+
+  let Inst{15-11} = 0b10000;
+  let Inst{6-5} = funct2;
+  let Inst{4-2} = rd_rs2;
+  let Inst{1-0} = 0b00;
+}
+
+//===----------------------------------------------------------------------===//
+// Operand definitions.
+//===----------------------------------------------------------------------===//
+
+def uimm4_with_predicate : RISCVUImmLeafOp<4> {
+  let MCOperandPredicate = [{
+    int64_t Imm;
+    if (!MCOp.evaluateAsConstantImm(Imm))
+      return false;
+    return isUInt<4>(Imm);
+  }];
+}
+
+def uimm5_with_predicate : RISCVUImmLeafOp<5> {
+  let MCOperandPredicate = [{
+    int64_t Imm;
+    if (!MCOp.evaluateAsConstantImm(Imm))
+      return false;
+    return isUInt<5>(Imm);
+  }];
+}
+
+// A 5-bit unsigned immediate where the least significant bit is zero.
+def uimm5_lsb0 : RISCVOp,
+                 ImmLeaf<XLenVT, [{return isShiftedUInt<4, 1>(Imm);}]> {
+  let ParserMatchClass = UImmAsmOperand<5, "Lsb0">;
+  let EncoderMethod = "getImmOpValue";
+  let DecoderMethod = "decodeUImmOperand<5>";
+  let OperandType = "OPERAND_UIMM5_LSB0";
+  let MCOperandPredicate = [{
+    int64_t Imm;
+    if (!MCOp.evaluateAsConstantImm(Imm))
+      return false;
+    return isShiftedUInt<4, 1>(Imm);
+  }];
+}
+
+// A 6-bit unsigned immediate where the least significant bit is zero.
+def uimm6_lsb0 : RISCVOp,
+                 ImmLeaf<XLenVT, [{return isShiftedUInt<5, 1>(Imm);}]> {
+  let ParserMatchClass = UImmAsmOperand<6, "Lsb0">;
+  let EncoderMethod = "getImmOpValue";
+  let DecoderMethod = "decodeUImmOperand<6>";
+  let OperandType = "OPERAND_UIMM6_LSB0";
+  let MCOperandPredicate = [{
+    int64_t Imm;
+    if (!MCOp.evaluateAsConstantImm(Imm))
+      return false;
+    return isShiftedUInt<5, 1>(Imm);
+  }];
+}
+
+//===----------------------------------------------------------------------===//
+// Instructions
+//===----------------------------------------------------------------------===//
+let Predicates = [HasVendorXwchc], DecoderNamespace = "Xwchc" in {
+
+let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
+def QK_C_LBU : RVInst16CL<0b001, 0b00, (outs GPRC:$rd),
+                          (ins GPRCMem:$rs1, uimm5_with_predicate:$imm),
+                          "qk.c.lbu", "$rd, ${imm}(${rs1})">,
+               Sched<[WriteLDB, ReadMemBase]> {
+  bits<5> imm;
+  let Inst{12} = imm{0};
+  let Inst{11-10} = imm{4-3};
+  let Inst{6-5} = imm{2-1};
+}
+let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
+def QK_C_SB : RVInst16CS<0b101, 0b00, (outs),
+                         (ins GPRC:$rs2, GPRCMem:$rs1,
+                              uimm5_with_predicate:$imm),
+                         "qk.c.sb", "$rs2, ${imm}(${rs1})">,
+              Sched<[WriteSTB, ReadStoreData, ReadMemBase]> {
+  bits<5> imm;
+  let Inst{12} = imm{0};
+  let Inst{11-10} = imm{4-3};
+  let Inst{6-5} = imm{2-1};
+}
+
+let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
+def QK_C_LHU : RVInst16CL<0b001, 0b10, (outs GPRC:$rd),
+                          (ins GPRCMem:$rs1, uimm6_lsb0:$imm),
+                          "qk.c.lhu", "$rd, ${imm}(${rs1})">,
+               Sched<[WriteLDH, ReadMemBase]> {
+  bits<6> imm;
+  let Inst{12-10} = imm{5-3};
+  let Inst{6-5} = imm{2-1};
+}
+let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
+def QK_C_SH : RVInst16CS<0b101, 0b10, (outs),
+                         (ins GPRC:$rs2, GPRCMem:$rs1, uimm6_lsb0:$imm),
+                         "qk.c.sh", "$rs2, ${imm}(${rs1})">,
+              Sched<[WriteSTH, ReadStoreData, ReadMemBase]> {
+  bits<6> imm;
+  let Inst{12-10} = imm{5-3};
+  let Inst{6-5} = imm{2-1};
+}
+
+let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
+def QK_C_LBUSP : QKStackInst<0b00, (outs GPRC:$rd_rs2),
+                             (ins SPMem:$rs1, uimm4_with_predicate:$imm),
+                             "qk.c.lbusp", "$rd_rs2, ${imm}(${rs1})">,
+                 Sched<[WriteLDB, ReadMemBase]> {
+  bits<4> imm;
+  let Inst{10-7} = imm;
+}
+let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
+def QK_C_SBSP : QKStackInst<0b10, (outs),
+                            (ins GPRC:$rd_rs2, SPMem:$rs1,
+                                 uimm4_with_predicate:$imm),
+                            "qk.c.sbsp", "$rd_rs2, ${imm}(${rs1})">,
+                Sched<[WriteSTB, ReadStoreData, ReadMemBase]> {
+  bits<4> imm;
+  let Inst{10-7} = imm;
+}
+
+let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
+def QK_C_LHUSP : QKStackInst<0b01, (outs GPRC:$rd_rs2),
+                             (ins SPMem:$rs1, uimm5_lsb0:$imm),
+                             "qk.c.lhusp", "$rd_rs2, ${imm}(${rs1})">,
+                 Sched<[WriteLDH, ReadMemBase]> {
+  bits<5> imm;
+  let Inst{10-8} = imm{3-1};
+  let Inst{7} = imm{4};
+}
+let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
+def QK_C_SHSP : QKStackInst<0b11, (outs),
+                            (ins GPRC:$rd_rs2, SPMem:$rs1, uimm5_lsb0:$imm),
+                            "qk.c.shsp", "$rd_rs2, ${imm}(${rs1})">,
+                Sched<[WriteSTH, ReadStoreData, ReadMemBase]> {
+  bits<5> imm;
+  let Inst{10-8} = imm{3-1};
+  let Inst{7} = imm{4};
+}
+
+} // Predicates = [HasVendorXwchc], DecoderNamespace = "Xwchc"
+
+//===----------------------------------------------------------------------===//
+// Assembler Pseudo Instructions
+//===----------------------------------------------------------------------===//
+
+let EmitPriority = 0 in {
+let Predicates = [HasVendorXwchc] in {
+def : InstAlias<"qk.c.lbu $rd, (${rs1})", (QK_C_LBU GPRC:$rd, GPRCMem:$rs1, 
0)>;
+def : InstAlias<"qk.c.sb $rs2, (${rs1})", (QK_C_SB GPRC:$rs2, GPRCMem:$rs1, 
0)>;
+def : InstAlias<"qk.c.lhu $rd, (${rs1})", (QK_C_LHU GPRC:$rd, GPRCMem:$rs1, 
0)>;
+def : InstAlias<"qk.c.sh $rs2, (${rs1})", (QK_C_SH GPRC:$rs2, GPRCMem:$rs1, 
0)>;
+def : InstAlias<"qk.c.lbusp $rd, (${rs1})", (QK_C_LBUSP GPRC:$rd, SPMem:$rs1, 
0)>;
+def : InstAlias<"qk.c.sbsp $rs2, (${rs1})", (QK_C_SBSP GPRC:$rs2, SPMem:$rs1, 
0)>;
+def : InstAlias<"qk.c.lhusp $rd, (${rs1})", (QK_C_LHUSP GPRC:$rd, SPMem:$rs1, 
0)>;
+def : InstAlias<"qk.c.shsp $rs2, (${rs1})", (QK_C_SHSP GPRC:$rs2, SPMem:$rs1, 
0)>;
+}
+}
+
+//===----------------------------------------------------------------------===/
+// Compress Instruction tablegen backend.
+//===----------------------------------------------------------------------===//
+
+let Predicates = [HasVendorXwchc] in {
+def : CompressPat<(LBU GPRC:$rd, GPRCMem:$rs1, uimm5_with_predicate:$imm),
+                  (QK_C_LBU GPRC:$rd, GPRCMem:$rs1, 
uimm5_with_predicate:$imm)>;
+def : CompressPat<(SB GPRC:$rs2, GPRCMem:$rs1, uimm5_with_predicate:$imm),
+                  (QK_C_SB GPRC:$rs2, GPRCMem:$rs1, 
uimm5_with_predicate:$imm)>;
+def : CompressPat<(LHU GPRC:$rd, GPRCMem:$rs1, uimm6_lsb0:$imm),
+                  (QK_C_LHU GPRC:$rd, GPRCMem:$rs1, uimm6_lsb0:$imm)>;
+def : CompressPat<(SH GPRC:$rs2, GPRCMem:$rs1, uimm6_lsb0:$imm),
+                  (QK_C_SH GPRC:$rs2, GPRCMem:$rs1, uimm6_lsb0:$imm)>;
+def : CompressPat<(LBU GPRC:$rd, SPMem:$rs1,   uimm4_with_predicate:$imm),
+                  (QK_C_LBUSP GPRC:$rd, SPMem:$rs1, 
uimm4_with_predicate:$imm)>;
+def : CompressPat<(SB GPRC:$rs2, SPMem:$rs1,   uimm4_with_predicate:$imm),
+                  (QK_C_SBSP GPRC:$rs2, SPMem:$rs1, 
uimm4_with_predicate:$imm)>;
+def : CompressPat<(LHU GPRC:$rd, SPMem:$rs1,   uimm5_lsb0:$imm),
+                  (QK_C_LHUSP GPRC:$rd, SPMem:$rs1, uimm5_lsb0:$imm)>;
+def : CompressPat<(SH GPRC:$rs2, SPMem:$rs1,   uimm5_lsb0:$imm),
+                  (QK_C_SHSP GPRC:$rs2, SPMem:$rs1, uimm5_lsb0:$imm)>;
+}
diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp 
b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index 0229b5a140f91..a980973a287f8 100644
--- a/llvm/lib/TargetParser/RISCVISAInfo.cpp
+++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp
@@ -688,6 +688,7 @@ Error RISCVISAInfo::checkDependency() {
   bool HasI = Exts.count("i") != 0;
   bool HasC = Exts.count("c") != 0;
   bool HasF = Exts.count("f") != 0;
+  bool HasD = Exts.count("d") != 0;
   bool HasZfinx = Exts.count("zfinx") != 0;
   bool HasVector = Exts.count("zve32x") != 0;
   bool HasZvl = MinVLen != 0;
@@ -721,8 +722,7 @@ Error RISCVISAInfo::checkDependency() {
     return getError(
         "'zvknhb' requires 'v' or 'zve64*' extension to also be specified");
 
-  if ((HasZcmt || Exts.count("zcmp")) && Exts.count("d") &&
-      (HasC || Exts.count("zcd")))
+  if ((HasZcmt || Exts.count("zcmp")) && HasD && (HasC || Exts.count("zcd")))
     return getError(Twine("'") + (HasZcmt ? "zcmt" : "zcmp") +
                     "' extension is incompatible with '" +
                     (HasC ? "c" : "zcd") +
@@ -739,6 +739,17 @@ Error RISCVISAInfo::checkDependency() {
     return getError(
         "'zabha' requires 'a' or 'zaamo' extension to also be specified");
 
+  if (Exts.count("xwchc") != 0) {
+    if (XLen != 32)
+      return getError("'Xwchc' is only supported for 'rv32'");
+
+    if (HasD)
+      return getError("'D' and 'Xwchc' extensions are incompatible");
+
+    if (Exts.count("zcb") != 0)
+      return getError("'Xwchc' and 'Zcb' extensions are incompatible");
+  }
+
   return Error::success();
 }
 
diff --git a/llvm/test/CodeGen/RISCV/attributes.ll 
b/llvm/test/CodeGen/RISCV/attributes.ll
index 1150f6d30e7f9..5f82d757a22ec 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -77,6 +77,7 @@
 ; RUN: llc -mtriple=riscv32 -mattr=+xtheadmemidx %s -o - | FileCheck 
--check-prefix=RV32XTHEADMEMIDX %s
 ; RUN: llc -mtriple=riscv32 -mattr=+xtheadmempair %s -o - | FileCheck 
--check-prefix=RV32XTHEADMEMPAIR %s
 ; RUN: llc -mtriple=riscv32 -mattr=+xtheadsync %s -o - | FileCheck 
--check-prefix=RV32XTHEADSYNC %s
+; RUN: llc -mtriple=riscv32 -mattr=+xwchc %s -o - | FileCheck 
--check-prefix=RV32XWCHC %s
 ; RUN: llc -mtriple=riscv32 -mattr=+zaamo %s -o - | FileCheck 
--check-prefix=RV32ZAAMO %s
 ; RUN: llc -mtriple=riscv32 -mattr=+zalrsc %s -o - | FileCheck 
--check-prefix=RV32ZALRSC %s
 ; RUN: llc -mtriple=riscv32 -mattr=+zca %s -o - | FileCheck 
--check-prefixes=CHECK,RV32ZCA %s
@@ -360,6 +361,7 @@
 ; RV32XTHEADMEMIDX: .attribute 5, "rv32i2p1_xtheadmemidx1p0"
 ; RV32XTHEADMEMPAIR: .attribute 5, "rv32i2p1_xtheadmempair1p0"
 ; RV32XTHEADSYNC: .attribute 5, "rv32i2p1_xtheadsync1p0"
+; RV32XWCHC: .attribute 5, "rv32i2p1_xwchc2p2"
 ; RV32ZAAMO: .attribute 5, "rv32i2p1_zaamo1p0"
 ; RV32ZALRSC: .attribute 5, "rv32i2p1_zalrsc1p0"
 ; RV32ZCA: .attribute 5, "rv32i2p1_zca1p0"
diff --git a/llvm/test/MC/RISCV/xwchc-compress.s 
b/llvm/test/MC/RISCV/xwchc-compress.s
new file mode 100644
index 0000000000000..4bdce1c02cfff
--- /dev/null
+++ b/llvm/test/MC/RISCV/xwchc-compress.s
@@ -0,0 +1,198 @@
+# RUN: llvm-mc -triple riscv32 -mattr=+xwchc -show-encoding < %s \
+# RUN:   | FileCheck -check-prefixes=CHECK,CHECK-ALIAS %s
+# RUN: llvm-mc -triple riscv32 -mattr=+xwchc -show-encoding \
+# RUN:   -riscv-no-aliases < %s | FileCheck -check-prefixes=CHECK,CHECK-INST %s
+# RUN: llvm-mc -triple riscv32 -mattr=+xwchc -filetype=obj < %s \
+# RUN:   | llvm-objdump  --triple=riscv32 --mattr=+xwchc --no-print-imm-hex -d 
- \
+# RUN:   | FileCheck -check-prefixes=CHECK-ALIAS %s
+# RUN: llvm-mc -triple riscv32 -mattr=+xwchc -filetype=obj < %s \
+# RUN:   | llvm-objdump  --triple=riscv32 --mattr=+xwchc --no-print-imm-hex -d 
-M no-aliases - \
+# RUN:   | FileCheck -check-prefixes=CHECK-INST %s
+
+
+# CHECK-ALIAS: lbu s0, 5(s1)
+# CHECK-INST: qk.c.lbu s0, 5(s1)
+# CHECK: # encoding: [0xc0,0x30]
+lbu s0, 5(s1)
+
+# CHECK-ALIAS: lbu s0, 31(a0)
+# CHECK-INST: qk.c.lbu s0, 31(a0)
+# CHECK: # encoding: [0x60,0x3d]
+lbu s0, 31(a0)
+
+# CHECK-ALIAS: lbu s0, 0(s2)
+# CHECK-INST: lbu s0, 0(s2)
+# CHECK: # encoding: [0x03,0x44,0x09,0x00]
+lbu s0, 0(s2)
+
+# CHECK-ALIAS: lbu s0, 32(s0)
+# CHECK-INST: lbu s0, 32(s0)
+# CHECK: # encoding: [0x03,0x44,0x04,0x02]
+lbu s0, 32(s0)
+
+
+# CHECK-ALIAS: sb s0, 5(s1)
+# CHECK-INST: qk.c.sb s0, 5(s1)
+# CHECK: # encoding: [0xc0,0xb0]
+sb s0, 5(s1)
+
+# CHECK-ALIAS: sb s0, 31(a0)
+# CHECK-INST: qk.c.sb s0, 31(a0)
+# CHECK: # encoding: [0x60,0xbd]
+sb s0, 31(a0)
+
+# CHECK-ALIAS: sb s0, 0(s2)
+# CHECK-INST: sb s0, 0(s2)
+# CHECK: # encoding: [0x23,0x00,0x89,0x00]
+sb s0, 0(s2)
+
+# CHECK-ALIAS: sb s0, 32(s0)
+# CHECK-INST: sb s0, 32(s0)
+# CHECK: # encoding: [0x23,0x00,0x84,0x02]
+sb s0, 32(s0)
+
+
+# CHECK-ALIAS: lhu s0, 10(s1)
+# CHECK-INST: qk.c.lhu s0, 10(s1)
+# CHECK: # encoding: [0xa2,0x24]
+lhu s0, 10(s1)
+
+# CHECK-ALIAS: lhu s0, 62(a0)
+# CHECK-INST: qk.c.lhu s0, 62(a0)
+# CHECK: # encoding: [0x62,0x3d]
+lhu s0, 62(a0)
+
+# CHECK-ALIAS: lhu s0, 0(s2)
+# CHECK-INST: lhu s0, 0(s2)
+# CHECK: # encoding: [0x03,0x54,0x09,0x00]
+lhu s0, 0(s2)
+
+# CHECK-ALIAS: lhu s0, 1(s0)
+# CHECK-INST: lhu s0, 1(s0)
+# CHECK: # encoding: [0x03,0x54,0x14,0x00]
+lhu s0, 1(s0)
+
+# CHECK-ALIAS: lhu s0, 64(s0)
+# CHECK-INST: lhu s0, 64(s0)
+# CHECK: # encoding: [0x03,0x54,0x04,0x04]
+lhu s0, 64(s0)
+
+
+# CHECK-ALIAS: sh s0, 10(s1)
+# CHECK-INST: qk.c.sh s0, 10(s1)
+# CHECK: # encoding: [0xa2,0xa4]
+sh s0, 10(s1)
+
+# CHECK-ALIAS: sh s0, 62(a0)
+# CHECK-INST: qk.c.sh s0, 62(a0)
+# CHECK: # encoding: [0x62,0xbd]
+sh s0, 62(a0)
+
+# CHECK-ALIAS: sh s0, 0(s2)
+# CHECK-INST: sh s0, 0(s2)
+# CHECK: # encoding: [0x23,0x10,0x89,0x00]
+sh s0, 0(s2)
+
+# CHECK-ALIAS: sh s0, 1(s0)
+# CHECK-INST: sh s0, 1(s0)
+# CHECK: # encoding: [0xa3,0x10,0x84,0x00]
+sh s0, 1(s0)
+
+# CHECK-ALIAS: sh s0, 64(s0)
+# CHECK-INST: sh s0, 64(s0)
+# CHECK: # encoding: [0x23,0x10,0x84,0x04]
+sh s0, 64(s0)
+
+
+# CHECK-ALIAS: lbu a2, 7(sp)
+# CHECK-INST: qk.c.lbusp a2, 7(sp)
+# CHECK: # encoding: [0x90,0x83]
+lbu a2, 7(sp)
+
+# CHECK-ALIAS: lbu a2, 15(sp)
+# CHECK-INST: qk.c.lbusp a2, 15(sp)
+# CHECK: # encoding: [0x90,0x87]
+lbu a2, 15(sp)
+
+# CHECK-ALIAS: lbu s2, 0(sp)
+# CHECK-INST: lbu s2, 0(sp)
+# CHECK: # encoding: [0x03,0x49,0x01,0x00]
+lbu s2, 0(sp)
+
+# CHECK-ALIAS: lbu s0, 16(sp)
+# CHECK-INST: lbu s0, 16(sp)
+# CHECK: # encoding: [0x03,0x44,0x01,0x01]
+lbu s0, 16(sp)
+
+
+# CHECK-ALIAS: sb a2, 7(sp)
+# CHECK-INST: qk.c.sbsp a2, 7(sp)
+# CHECK: # encoding: [0xd0,0x83]
+sb a2, 7(sp)
+
+# CHECK-ALIAS: sb a2, 15(sp)
+# CHECK-INST: qk.c.sbsp a2, 15(sp)
+# CHECK: # encoding: [0xd0,0x87]
+sb a2, 15(sp)
+
+# CHECK-ALIAS: sb s2, 0(sp)
+# CHECK-INST: sb s2, 0(sp)
+# CHECK: # encoding: [0x23,0x00,0x21,0x01]
+sb s2, 0(sp)
+
+# CHECK-ALIAS: sb s0, 16(sp)
+# CHECK-INST: sb s0, 16(sp)
+# CHECK: # encoding: [0x23,0x08,0x81,0x00]
+sb s0, 16(sp)
+
+
+# CHECK-ALIAS: lhu a2, 14(sp)
+# CHECK-INST: qk.c.lhusp a2, 14(sp)
+# CHECK: # encoding: [0x30,0x87]
+lhu a2, 14(sp)
+
+# CHECK-ALIAS: lhu a2, 30(sp)
+# CHECK-INST: qk.c.lhusp a2, 30(sp)
+# CHECK: # encoding: [0xb0,0x87]
+lhu a2, 30(sp)
+
+# CHECK-ALIAS: lhu s2, 0(sp)
+# CHECK-INST: lhu s2, 0(sp)
+# CHECK: # encoding: [0x03,0x59,0x01,0x00]
+lhu s2, 0(sp)
+
+# CHECK-ALIAS: lhu s2, 1(sp)
+# CHECK-INST: lhu s2, 1(sp)
+# CHECK: # encoding: [0x03,0x59,0x11,0x00]
+lhu s2, 1(sp)
+
+# CHECK-ALIAS: lhu s0, 32(sp)
+# CHECK-INST: lhu s0, 32(sp)
+# CHECK: # encoding: [0x03,0x54,0x01,0x02]
+lhu s0, 32(sp)
+
+
+# CHECK-ALIAS: sh a2, 14(sp)
+# CHECK-INST: qk.c.shsp a2, 14(sp)
+# CHECK: # encoding: [0x70,0x87]
+sh a2, 14(sp)
+
+# CHECK-ALIAS: sh a2, 30(sp)
+# CHECK-INST: qk.c.shsp a2, 30(sp)
+# CHECK: # encoding: [0xf0,0x87]
+sh a2, 30(sp)
+
+# CHECK-ALIAS: sh s2, 0(sp)
+# CHECK-INST: sh s2, 0(sp)
+# CHECK: # encoding: [0x23,0x10,0x21,0x01]
+sh s2, 0(sp)
+
+# CHECK-ALIAS: sh s2, 1(sp)
+# CHECK-INST: sh s2, 1(sp)
+# CHECK: # encoding: [0xa3,0x10,0x21,0x01]
+sh s2, 1(sp)
+
+# CHECK-ALIAS: sh s0, 32(sp)
+# CHECK-INST: sh s0, 32(sp)
+# CHECK: # encoding: [0x23,0x10,0x81,0x02]
+sh s0, 32(sp)
diff --git a/llvm/test/MC/RISCV/xwchc-invalid.s 
b/llvm/test/MC/RISCV/xwchc-invalid.s
new file mode 100644
index 0000000000000..99cc519573895
--- /dev/null
+++ b/llvm/test/MC/RISCV/xwchc-invalid.s
@@ -0,0 +1,21 @@
+# RUN: not llvm-mc -triple riscv32 -mattr=+xwchc < %s 2>&1 | FileCheck %s
+
+qk.c.lbu x8, 32(x8) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate must be 
an integer in the range [0, 31]
+qk.c.sb x8, 32(x8) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate must be an 
integer in the range [0, 31]
+
+qk.c.lhu x8, 1(x8) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate must be a 
multiple of 2 bytes in the range [0, 62]
+qk.c.sh x8, 1(x8) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate must be a 
multiple of 2 bytes in the range [0, 62]
+qk.c.lhu x8, 64(x8) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate must be a 
multiple of 2 bytes in the range [0, 62]
+qk.c.sh x8, 64(x8) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate must be a 
multiple of 2 bytes in the range [0, 62]
+
+qk.c.lbusp x8, 0(x8) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand 
for instruction
+qk.c.sbsp x8, 0(x8) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for 
instruction
+qk.c.lbusp x8, 32(sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate must be 
an integer in the range [0, 15]
+qk.c.sbsp x8, 32(sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate must be 
an integer in the range [0, 15]
+
+qk.c.lhusp x8, 0(x8) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand 
for instruction
+qk.c.shsp x8, 0(x8) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for 
instruction
+qk.c.lhusp x8, 1(sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate must be 
a multiple of 2 bytes in the range [0, 30]
+qk.c.shsp x8, 1(sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate must be a 
multiple of 2 bytes in the range [0, 30]
+qk.c.lhusp x8, 32(sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate must be 
a multiple of 2 bytes in the range [0, 30]
+qk.c.shsp x8, 32(sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate must be 
a multiple of 2 bytes in the range [0, 30]
diff --git a/llvm/test/MC/RISCV/xwchc-valid.s b/llvm/test/MC/RISCV/xwchc-valid.s
new file mode 100644
index 0000000000000..292a042805232
--- /dev/null
+++ b/llvm/test/MC/RISCV/xwchc-valid.s
@@ -0,0 +1,145 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+xwchc -riscv-no-aliases 
-show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+xwchc < %s \
+# RUN:     | llvm-objdump --mattr=+xwchc --no-print-imm-hex -M no-aliases -d 
-r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: qk.c.lbu s0, 0(s0)
+# CHECK-ASM: encoding: [0x00,0x20]
+qk.c.lbu s0, 0(s0)
+# CHECK-ASM-AND-OBJ: qk.c.lbu s0, 1(s0)
+# CHECK-ASM: encoding: [0x00,0x30]
+qk.c.lbu s0, 1(s0)
+# CHECK-ASM-AND-OBJ: qk.c.lbu s0, 2(s0)
+# CHECK-ASM: encoding: [0x20,0x20]
+qk.c.lbu s0, 2(s0)
+# CHECK-ASM-AND-OBJ: qk.c.lbu s0, 4(s0)
+# CHECK-ASM: encoding: [0x40,0x20]
+qk.c.lbu s0, 4(s0)
+# CHECK-ASM-AND-OBJ: qk.c.lbu s0, 8(s0)
+# CHECK-ASM: encoding: [0x00,0x24]
+qk.c.lbu s0, 8(s0)
+# CHECK-ASM-AND-OBJ: qk.c.lbu s0, 16(s0)
+# CHECK-ASM: encoding: [0x00,0x28]
+qk.c.lbu s0, 16(s0)
+
+# CHECK-ASM-AND-OBJ: qk.c.sb s0, 0(s0)
+# CHECK-ASM: encoding: [0x00,0xa0]
+qk.c.sb s0, 0(s0)
+# CHECK-ASM-AND-OBJ: qk.c.sb s0, 1(s0)
+# CHECK-ASM: encoding: [0x00,0xb0]
+qk.c.sb s0, 1(s0)
+# CHECK-ASM-AND-OBJ: qk.c.sb s0, 2(s0)
+# CHECK-ASM: encoding: [0x20,0xa0]
+qk.c.sb s0, 2(s0)
+# CHECK-ASM-AND-OBJ: qk.c.sb s0, 4(s0)
+# CHECK-ASM: encoding: [0x40,0xa0]
+qk.c.sb s0, 4(s0)
+# CHECK-ASM-AND-OBJ: qk.c.sb s0, 8(s0)
+# CHECK-ASM: encoding: [0x00,0xa4]
+qk.c.sb s0, 8(s0)
+# CHECK-ASM-AND-OBJ: qk.c.sb s0, 16(s0)
+# CHECK-ASM: encoding: [0x00,0xa8]
+qk.c.sb s0, 16(s0)
+
+# CHECK-ASM-AND-OBJ: qk.c.lhu s0, 0(s0)
+# CHECK-ASM: encoding: [0x02,0x20]
+qk.c.lhu s0, 0(s0)
+# CHECK-ASM-AND-OBJ: qk.c.lhu s0, 2(s0)
+# CHECK-ASM: encoding: [0x22,0x20]
+qk.c.lhu s0, 2(s0)
+# CHECK-ASM-AND-OBJ: qk.c.lhu s0, 4(s0)
+# CHECK-ASM: encoding: [0x42,0x20]
+qk.c.lhu s0, 4(s0)
+# CHECK-ASM-AND-OBJ: qk.c.lhu s0, 8(s0)
+# CHECK-ASM: encoding: [0x02,0x24]
+qk.c.lhu s0, 8(s0)
+# CHECK-ASM-AND-OBJ: qk.c.lhu s0, 16(s0)
+# CHECK-ASM: encoding: [0x02,0x28]
+qk.c.lhu s0, 16(s0)
+# CHECK-ASM-AND-OBJ: qk.c.lhu s0, 32(s0)
+# CHECK-ASM: encoding: [0x02,0x30]
+qk.c.lhu s0, 32(s0)
+
+# CHECK-ASM-AND-OBJ: qk.c.sh s0, 0(s0)
+# CHECK-ASM: encoding: [0x02,0xa0]
+qk.c.sh s0, 0(s0)
+# CHECK-ASM-AND-OBJ: qk.c.sh s0, 2(s0)
+# CHECK-ASM: encoding: [0x22,0xa0]
+qk.c.sh s0, 2(s0)
+# CHECK-ASM-AND-OBJ: qk.c.sh s0, 4(s0)
+# CHECK-ASM: encoding: [0x42,0xa0]
+qk.c.sh s0, 4(s0)
+# CHECK-ASM-AND-OBJ: qk.c.sh s0, 8(s0)
+# CHECK-ASM: encoding: [0x02,0xa4]
+qk.c.sh s0, 8(s0)
+# CHECK-ASM-AND-OBJ: qk.c.sh s0, 16(s0)
+# CHECK-ASM: encoding: [0x02,0xa8]
+qk.c.sh s0, 16(s0)
+# CHECK-ASM-AND-OBJ: qk.c.sh s0, 32(s0)
+# CHECK-ASM: encoding: [0x02,0xb0]
+qk.c.sh s0, 32(s0)
+
+# CHECK-ASM-AND-OBJ: qk.c.lbusp s0, 0(sp)
+# CHECK-ASM: encoding: [0x00,0x80]
+qk.c.lbusp s0, 0(sp)
+# CHECK-ASM-AND-OBJ: qk.c.lbusp s0, 1(sp)
+# CHECK-ASM: encoding: [0x80,0x80]
+qk.c.lbusp s0, 1(sp)
+# CHECK-ASM-AND-OBJ: qk.c.lbusp s0, 2(sp)
+# CHECK-ASM: encoding: [0x00,0x81]
+qk.c.lbusp s0, 2(sp)
+# CHECK-ASM-AND-OBJ: qk.c.lbusp s0, 4(sp)
+# CHECK-ASM: encoding: [0x00,0x82]
+qk.c.lbusp s0, 4(sp)
+# CHECK-ASM-AND-OBJ: qk.c.lbusp s0, 8(sp)
+# CHECK-ASM: encoding: [0x00,0x84]
+qk.c.lbusp s0, 8(sp)
+
+# CHECK-ASM-AND-OBJ: qk.c.sbsp s0, 0(sp)
+# CHECK-ASM: encoding: [0x40,0x80]
+qk.c.sbsp s0, 0(sp)
+# CHECK-ASM-AND-OBJ: qk.c.sbsp s0, 1(sp)
+# CHECK-ASM: encoding: [0xc0,0x80]
+qk.c.sbsp s0, 1(sp)
+# CHECK-ASM-AND-OBJ: qk.c.sbsp s0, 2(sp)
+# CHECK-ASM: encoding: [0x40,0x81]
+qk.c.sbsp s0, 2(sp)
+# CHECK-ASM-AND-OBJ: qk.c.sbsp s0, 4(sp)
+# CHECK-ASM: encoding: [0x40,0x82]
+qk.c.sbsp s0, 4(sp)
+# CHECK-ASM-AND-OBJ: qk.c.sbsp s0, 8(sp)
+# CHECK-ASM: encoding: [0x40,0x84]
+qk.c.sbsp s0, 8(sp)
+
+# CHECK-ASM-AND-OBJ: qk.c.lhusp s0, 0(sp)
+# CHECK-ASM: encoding: [0x20,0x80]
+qk.c.lhusp s0, 0(sp)
+# CHECK-ASM-AND-OBJ: qk.c.lhusp s0, 2(sp)
+# CHECK-ASM: encoding: [0x20,0x81]
+qk.c.lhusp s0, 2(sp)
+# CHECK-ASM-AND-OBJ: qk.c.lhusp s0, 4(sp)
+# CHECK-ASM: encoding: [0x20,0x82]
+qk.c.lhusp s0, 4(sp)
+# CHECK-ASM-AND-OBJ: qk.c.lhusp s0, 8(sp)
+# CHECK-ASM: encoding: [0x20,0x84]
+qk.c.lhusp s0, 8(sp)
+# CHECK-ASM-AND-OBJ: qk.c.lhusp s0, 16(sp)
+# CHECK-ASM: encoding: [0xa0,0x80]
+qk.c.lhusp s0, 16(sp)
+
+# CHECK-ASM-AND-OBJ: qk.c.shsp s0, 0(sp)
+# CHECK-ASM: encoding: [0x60,0x80]
+qk.c.shsp s0, 0(sp)
+# CHECK-ASM-AND-OBJ: qk.c.shsp s0, 2(sp)
+# CHECK-ASM: encoding: [0x60,0x81]
+qk.c.shsp s0, 2(sp)
+# CHECK-ASM-AND-OBJ: qk.c.shsp s0, 4(sp)
+# CHECK-ASM: encoding: [0x60,0x82]
+qk.c.shsp s0, 4(sp)
+# CHECK-ASM-AND-OBJ: qk.c.shsp s0, 8(sp)
+# CHECK-ASM: encoding: [0x60,0x84]
+qk.c.shsp s0, 8(sp)
+# CHECK-ASM-AND-OBJ: qk.c.shsp s0, 16(sp)
+# CHECK-ASM: encoding: [0xe0,0x80]
+qk.c.shsp s0, 16(sp)
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp 
b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index 50a8d7b6b1211..2619f7be53c1a 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -1023,6 +1023,7 @@ R"(All available -march extensions for RISC-V
     xtheadsync           1.0
     xtheadvdot           1.0
     xventanacondops      1.0
+    xwchc                2.2
 
 Experimental extensions
     zicfilp              0.4       This is a long dummy description

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to