[llvm] r320558 - [RISCV] MC layer support for the remaining RVC instructions

Alex Bradbury via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 13 01:32:56 PST 2017


Author: asb
Date: Wed Dec 13 01:32:55 2017
New Revision: 320558

URL: http://llvm.org/viewvc/llvm-project?rev=320558&view=rev
Log:
[RISCV] MC layer support for the remaining RVC instructions

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

Patch by Shiva Chen.

Added:
    llvm/trunk/test/MC/RISCV/rv32c-only-valid.s
    llvm/trunk/test/MC/RISCV/rv32dc-invalid.s
    llvm/trunk/test/MC/RISCV/rv32dc-valid.s
    llvm/trunk/test/MC/RISCV/rv32fc-invalid.s
    llvm/trunk/test/MC/RISCV/rv32fc-valid.s
Modified:
    llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
    llvm/trunk/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
    llvm/trunk/lib/Target/RISCV/RISCVInstrFormatsC.td
    llvm/trunk/lib/Target/RISCV/RISCVInstrInfoC.td
    llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.td
    llvm/trunk/test/MC/RISCV/rv32c-invalid.s
    llvm/trunk/test/MC/RISCV/rv32c-valid.s
    llvm/trunk/test/MC/RISCV/rv64c-invalid.s
    llvm/trunk/test/MC/RISCV/rv64c-valid.s

Modified: llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp?rev=320558&r1=320557&r2=320558&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp Wed Dec 13 01:32:55 2017
@@ -225,6 +225,24 @@ public:
     return IsConstantImm && isUInt<5>(Imm) && VK == RISCVMCExpr::VK_RISCV_None;
   }
 
+  bool isUImm5NonZero() const {
+    int64_t Imm;
+    RISCVMCExpr::VariantKind VK;
+    if (!isImm())
+      return false;
+    bool IsConstantImm = evaluateConstantImm(Imm, VK);
+    return IsConstantImm && isUInt<5>(Imm) && (Imm != 0) &&
+           VK == RISCVMCExpr::VK_RISCV_None;
+  }
+
+  bool isUImm6NonZero() const {
+    int64_t Imm;
+    RISCVMCExpr::VariantKind VK;
+    bool IsConstantImm = evaluateConstantImm(Imm, VK);
+    return IsConstantImm && isUInt<6>(Imm) && (Imm != 0) &&
+           VK == RISCVMCExpr::VK_RISCV_None;
+  }
+
   bool isUImm7Lsb00() const {
     int64_t Imm;
     RISCVMCExpr::VariantKind VK;
@@ -259,6 +277,27 @@ public:
            VK == RISCVMCExpr::VK_RISCV_None;
   }
 
+  bool isUImm10Lsb00NonZero() const {
+    int64_t Imm;
+    RISCVMCExpr::VariantKind VK;
+    bool IsConstantImm = evaluateConstantImm(Imm, VK);
+    return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (Imm != 0) &&
+           VK == RISCVMCExpr::VK_RISCV_None;
+  }
+
+  bool isSImm6() const {
+    RISCVMCExpr::VariantKind VK;
+    int64_t Imm;
+    bool IsValid;
+    bool IsConstantImm = evaluateConstantImm(Imm, VK);
+    if (!IsConstantImm)
+      IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
+    else
+      IsValid = isInt<6>(Imm);
+    return IsValid &&
+           (VK == RISCVMCExpr::VK_RISCV_None || VK == RISCVMCExpr::VK_RISCV_LO);
+  }
+
   bool isSImm12() const {
     RISCVMCExpr::VariantKind VK;
     int64_t Imm;
@@ -287,6 +326,14 @@ public:
 
   bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); }
 
+  bool isSImm10Lsb0000() const {
+    int64_t Imm;
+    RISCVMCExpr::VariantKind VK;
+    bool IsConstantImm = evaluateConstantImm(Imm, VK);
+    return IsConstantImm && isShiftedInt<6, 4>(Imm) &&
+           VK == RISCVMCExpr::VK_RISCV_None;
+  }
+
   bool isUImm20() const {
     RISCVMCExpr::VariantKind VK;
     int64_t Imm;
@@ -491,10 +538,13 @@ unsigned RISCVAsmParser::validateTargetO
   unsigned Reg = Op.getReg();
   bool IsRegFPR32 =
       RISCVMCRegisterClasses[RISCV::FPR32RegClassID].contains(Reg);
+  bool IsRegFPR32C =
+      RISCVMCRegisterClasses[RISCV::FPR32CRegClassID].contains(Reg);
 
   // As the parser couldn't differentiate an FPR32 from an FPR64, coerce the
-  // register from FPR32 to FPR64 if necessary.
-  if (IsRegFPR32 && Kind == MCK_FPR64) {
+  // register from FPR32 to FPR64 or FPR32C to FPR64C if necessary.
+  if ((IsRegFPR32 && Kind == MCK_FPR64) ||
+      (IsRegFPR32C && Kind == MCK_FPR64C)) {
     Op.Reg.RegNum = convertFPR32ToFPR64(Reg);
     return Match_Success;
   }
@@ -544,6 +594,10 @@ bool RISCVAsmParser::MatchAndEmitInstruc
     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
   case Match_InvalidUImm5:
     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
+  case Match_InvalidUImm5NonZero:
+    return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
+  case Match_InvalidUImm6NonZero:
+    return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1);
   case Match_InvalidUImm7Lsb00:
     return generateImmOutOfRangeError(
         Operands, ErrorInfo, 0, (1 << 7) - 4,
@@ -564,6 +618,17 @@ bool RISCVAsmParser::MatchAndEmitInstruc
     return generateImmOutOfRangeError(
         Operands, ErrorInfo, 0, (1 << 9) - 8,
         "immediate must be a multiple of 8 bytes in the range");
+  case Match_InvalidUImm10Lsb00NonZero:
+    return generateImmOutOfRangeError(
+        Operands, ErrorInfo, 4, (1 << 10) - 4,
+        "immediate must be a multiple of 4 bytes in the range");
+  case Match_InvalidSImm6:
+    return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5),
+                                      (1 << 5) - 1);
+  case Match_InvalidSImm10Lsb0000:
+    return generateImmOutOfRangeError(
+        Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
+        "immediate must be a multiple of 16 bytes in the range");
   case Match_InvalidSImm12:
     return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 11),
                                       (1 << 11) - 1);

Modified: llvm/trunk/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp?rev=320558&r1=320557&r2=320558&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (original)
+++ llvm/trunk/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp Wed Dec 13 01:32:55 2017
@@ -69,15 +69,15 @@ static const unsigned GPRDecoderTable[]
 static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint64_t RegNo,
                                            uint64_t Address,
                                            const void *Decoder) {
-   if (RegNo > sizeof(GPRDecoderTable))
-     return MCDisassembler::Fail;
+  if (RegNo > sizeof(GPRDecoderTable))
+    return MCDisassembler::Fail;
 
-   // We must define our own mapping from RegNo to register identifier.
-   // Accessing index RegNo in the register class will work in the case that
-   // registers were added in ascending order, but not in general.
-   unsigned Reg = GPRDecoderTable[RegNo];
-   Inst.addOperand(MCOperand::createReg(Reg));
-   return MCDisassembler::Success;
+  // We must define our own mapping from RegNo to register identifier.
+  // Accessing index RegNo in the register class will work in the case that
+  // registers were added in ascending order, but not in general.
+  unsigned Reg = GPRDecoderTable[RegNo];
+  Inst.addOperand(MCOperand::createReg(Reg));
+  return MCDisassembler::Success;
 }
 
 static const unsigned FPR32DecoderTable[] = {
@@ -105,6 +105,17 @@ static DecodeStatus DecodeFPR32RegisterC
   return MCDisassembler::Success;
 }
 
+static DecodeStatus DecodeFPR32CRegisterClass(MCInst &Inst, uint64_t RegNo,
+                                              uint64_t Address,
+                                              const void *Decoder) {
+  if (RegNo > 8) {
+    return MCDisassembler::Fail;
+  }
+  unsigned Reg = FPR32DecoderTable[RegNo + 8];
+  Inst.addOperand(MCOperand::createReg(Reg));
+  return MCDisassembler::Success;
+}
+
 static const unsigned FPR64DecoderTable[] = {
   RISCV::F0_64,  RISCV::F1_64,  RISCV::F2_64,  RISCV::F3_64,
   RISCV::F4_64,  RISCV::F5_64,  RISCV::F6_64,  RISCV::F7_64,
@@ -130,14 +141,35 @@ static DecodeStatus DecodeFPR64RegisterC
   return MCDisassembler::Success;
 }
 
+static DecodeStatus DecodeFPR64CRegisterClass(MCInst &Inst, uint64_t RegNo,
+                                              uint64_t Address,
+                                              const void *Decoder) {
+  if (RegNo > 8) {
+    return MCDisassembler::Fail;
+  }
+  unsigned Reg = FPR64DecoderTable[RegNo + 8];
+  Inst.addOperand(MCOperand::createReg(Reg));
+  return MCDisassembler::Success;
+}
+
 static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst &Inst, uint64_t RegNo,
                                                uint64_t Address,
                                                const void *Decoder) {
-   if (RegNo == 0) {
-     return MCDisassembler::Fail;
-   }
+  if (RegNo == 0) {
+    return MCDisassembler::Fail;
+  }
 
-   return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
+  return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
+}
+
+static DecodeStatus DecodeGPRNoX0X2RegisterClass(MCInst &Inst, uint64_t RegNo,
+                                                 uint64_t Address,
+                                                 const void *Decoder) {
+  if (RegNo == 2) {
+    return MCDisassembler::Fail;
+  }
+
+  return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder);
 }
 
 static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo,
@@ -155,7 +187,14 @@ static DecodeStatus DecodeGPRCRegisterCl
 // operand isn't explicitly encoded in the instruction.
 static void addImplySP(MCInst &Inst, int64_t Address, const void *Decoder) {
   if (Inst.getOpcode() == RISCV::CLWSP || Inst.getOpcode() == RISCV::CSWSP ||
-      Inst.getOpcode() == RISCV::CLDSP || Inst.getOpcode() == RISCV::CSDSP) {
+      Inst.getOpcode() == RISCV::CLDSP || Inst.getOpcode() == RISCV::CSDSP ||
+      Inst.getOpcode() == RISCV::CFLWSP || Inst.getOpcode() == RISCV::CFSWSP ||
+      Inst.getOpcode() == RISCV::CFLDSP || Inst.getOpcode() == RISCV::CFSDSP ||
+      Inst.getOpcode() == RISCV::CADDI4SPN) {
+    DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
+  }
+  if (Inst.getOpcode() == RISCV::CADDI16SP) {
+    DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
     DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
   }
 }
@@ -173,6 +212,7 @@ template <unsigned N>
 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm,
                                       int64_t Address, const void *Decoder) {
   assert(isUInt<N>(Imm) && "Invalid immediate");
+  addImplySP(Inst, Address, Decoder);
   // Sign-extend the number in the bottom N bits of Imm
   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
   return MCDisassembler::Success;
@@ -210,6 +250,18 @@ DecodeStatus RISCVDisassembler::getInstr
     Size = 4;
   } else {
     Insn = support::endian::read16le(Bytes.data());
+
+    if (!STI.getFeatureBits()[RISCV::Feature64Bit]) {
+      DEBUG(dbgs() << "Trying RISCV32Only_16 table (16-bit Instruction):\n");
+      // Calling the auto-generated decoder function.
+      Result = decodeInstruction(DecoderTableRISCV32Only_16, MI, Insn, Address,
+                                 this, STI);
+      if (Result != MCDisassembler::Fail) {
+        Size = 2;
+        return Result;
+      }
+    }
+
     DEBUG(dbgs() << "Trying RISCV_C table (16-bit Instruction):\n");
     // Calling the auto-generated decoder function.
     Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI);

Modified: llvm/trunk/lib/Target/RISCV/RISCVInstrFormatsC.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVInstrFormatsC.td?rev=320558&r1=320557&r2=320558&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVInstrFormatsC.td (original)
+++ llvm/trunk/lib/Target/RISCV/RISCVInstrFormatsC.td Wed Dec 13 01:32:55 2017
@@ -77,6 +77,17 @@ class RVInst16CSS<bits<3> funct3, bits<2
   let Inst{1-0} = opcode;
 }
 
+class RVInst16CIW<bits<3> funct3, bits<2> opcode, dag outs, dag ins,
+                  string opcodestr, string argstr>
+    : RVInst16<outs, ins, opcodestr, argstr, [], InstFormatCIW> {
+  bits<10> imm;
+  bits<3> rd;
+
+  let Inst{15-13} = funct3;
+  let Inst{4-2} = rd;
+  let Inst{1-0} = opcode;
+}
+
 // The immediate value encoding differs for each instruction, so each subclass
 // is responsible for setting the appropriate bits in the Inst field.
 // The bits Inst{12-10} and Inst{6-5} must be set for each instruction.

Modified: llvm/trunk/lib/Target/RISCV/RISCVInstrInfoC.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVInstrInfoC.td?rev=320558&r1=320557&r2=320558&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVInstrInfoC.td (original)
+++ llvm/trunk/lib/Target/RISCV/RISCVInstrInfoC.td Wed Dec 13 01:32:55 2017
@@ -13,6 +13,24 @@ include "RISCVInstrFormatsC.td"
 // Operand definitions.
 //===----------------------------------------------------------------------===//
 
+def simm6 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isInt<6>(Imm);}]> {
+  let ParserMatchClass = SImmAsmOperand<6>;
+  let EncoderMethod = "getImmOpValue";
+  let DecoderMethod = "decodeSImmOperand<6>";
+}
+
+def uimm5nonzero : Operand<XLenVT>,
+                   ImmLeaf<XLenVT, [{return isUInt<5>(Imm) && (Imm != 0);}]> {
+  let ParserMatchClass = UImmAsmOperand<5, "NonZero">;
+  let DecoderMethod = "decodeUImmOperand<5>";
+}
+
+def uimm6nonzero : Operand<XLenVT>,
+                   ImmLeaf<XLenVT, [{return isUInt<6>(Imm) && (Imm != 0);}]> {
+  let ParserMatchClass = UImmAsmOperand<6, "NonZero">;
+  let DecoderMethod = "decodeUImmOperand<6>";
+}
+
 // A 7-bit unsigned immediate where the least significant two bits are zero.
 def uimm7_lsb00 : Operand<XLenVT>,
                   ImmLeaf<XLenVT, [{return isShiftedUInt<5, 2>(Imm);}]> {
@@ -52,6 +70,24 @@ def uimm9_lsb000 : Operand<XLenVT>,
   let DecoderMethod = "decodeUImmOperand<9>";
 }
 
+// A 10-bit unsigned immediate where the least significant two bits are zero
+// and the immediate can't be zero.
+def uimm10_lsb00nonzero : Operand<XLenVT>,
+                          ImmLeaf<XLenVT,
+                          [{return isShiftedUInt<8, 2>(Imm) && (Imm != 0);}]> {
+  let ParserMatchClass = UImmAsmOperand<10, "Lsb00NonZero">;
+  let EncoderMethod = "getImmOpValue";
+  let DecoderMethod = "decodeUImmOperand<10>";
+}
+
+// A 10-bit signed immediate where the least significant four bits are zero.
+def simm10_lsb0000 : Operand<XLenVT>,
+                     ImmLeaf<XLenVT, [{return isShiftedInt<6, 4>(Imm);}]> {
+  let ParserMatchClass = SImmAsmOperand<10, "Lsb0000">;
+  let EncoderMethod = "getImmOpValue";
+  let DecoderMethod = "decodeSImmOperand<10>";
+}
+
 // A 12-bit signed immediate where the least significant bit is zero.
 def simm12_lsb0 : Operand<OtherVT> {
   let ParserMatchClass = SImmAsmOperand<12, "Lsb0">;
@@ -78,13 +114,13 @@ class CStackStore<bits<3> funct3, string
 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
 class CLoad_ri<bits<3> funct3, string OpcodeStr,
                RegisterClass cls, DAGOperand opnd> :
-      RVInst16CL<funct3, 0b00, (outs cls:$rd), (ins cls:$rs1, opnd:$imm),
+      RVInst16CL<funct3, 0b00, (outs cls:$rd), (ins GPRC:$rs1, opnd:$imm),
                  OpcodeStr, "$rd, ${imm}(${rs1})">;
 
 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
 class CStore_rri<bits<3> funct3, string OpcodeStr,
                  RegisterClass cls, DAGOperand opnd> :
-      RVInst16CS<funct3, 0b00, (outs), (ins cls:$rs2, cls:$rs1, opnd:$imm),
+      RVInst16CS<funct3, 0b00, (outs), (ins cls:$rs2, GPRC:$rs1, opnd:$imm),
                  OpcodeStr, "$rs2, ${imm}(${rs1})">;
 
 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
@@ -101,12 +137,54 @@ class Bcz<bits<3> funct3, string OpcodeS
   let Inst{2} = imm{4};
 }
 
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class Shift_right<bits<2> funct2, string OpcodeStr, RegisterClass cls,
+                  Operand ImmOpnd> :
+      RVInst16CB<0b100, 0b01, (outs cls:$rs1_wb), (ins cls:$rs1, ImmOpnd:$imm),
+                 OpcodeStr, "$rs1, $imm"> {
+  let Constraints = "$rs1 = $rs1_wb";
+  let Inst{12} = imm{5};
+  let Inst{11-10} = funct2;
+  let Inst{6-2} = imm{4-0};
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class CS_ALU<bits<2> funct2, string OpcodeStr, RegisterClass cls,
+             bit RV64only> :
+      RVInst16CS<0b100, 0b01, (outs cls:$rd_wb), (ins cls:$rd, cls:$rs2),
+                 OpcodeStr, "$rd, $rs2"> {
+  bits<3> rd;
+  let Constraints = "$rd = $rd_wb";
+  let Inst{12} = RV64only;
+  let Inst{11-10} = 0b11;
+  let Inst{9-7} = rd;
+  let Inst{6-5} = funct2;
+}
+
 //===----------------------------------------------------------------------===//
 // Instructions
 //===----------------------------------------------------------------------===//
 
 let Predicates = [HasStdExtC] in {
 
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+def CADDI4SPN : RVInst16CIW<0b000, 0b00, (outs GPRC:$rd),
+                            (ins SP:$rs1, uimm10_lsb00nonzero:$imm),
+                            "c.addi4spn", "$rd, $rs1, $imm"> {
+  bits<5> rs1;
+  let Inst{12-11} = imm{5-4};
+  let Inst{10-7} = imm{9-6};
+  let Inst{6} = imm{2};
+  let Inst{5} = imm{3};
+}
+
+def CFLD  : CLoad_ri<0b001, "c.fld", FPR64C, uimm8_lsb000>,
+            Requires<[HasStdExtD]> {
+  bits<8> imm;
+  let Inst{12-10} = imm{5-3};
+  let Inst{6-5} = imm{7-6};
+}
+
 def CLW : CLoad_ri<0b010, "c.lw", GPRC, uimm7_lsb00> {
   bits<7> imm;
   let Inst{12-10} = imm{5-3};
@@ -114,6 +192,15 @@ def CLW : CLoad_ri<0b010, "c.lw", GPRC,
   let Inst{5} = imm{6};
 }
 
+let DecoderNamespace = "RISCV32Only_" in
+def CFLW  : CLoad_ri<0b011, "c.flw", FPR32C, uimm7_lsb00>,
+            Requires<[HasStdExtF, IsRV32]> {
+  bits<7> imm;
+  let Inst{12-10} = imm{5-3};
+  let Inst{6} = imm{2};
+  let Inst{5} = imm{6};
+}
+
 def CLD : CLoad_ri<0b011, "c.ld", GPRC, uimm8_lsb000>,
           Requires<[IsRV64]> {
   bits<8> imm;
@@ -121,6 +208,13 @@ def CLD : CLoad_ri<0b011, "c.ld", GPRC,
   let Inst{6-5} = imm{7-6};
 }
 
+def CFSD  : CStore_rri<0b101, "c.fsd", FPR64C, uimm8_lsb000>,
+            Requires<[HasStdExtD]> {
+  bits<8> imm;
+  let Inst{12-10} = imm{5-3};
+  let Inst{6-5} = imm{7-6};
+}
+
 def CSW : CStore_rri<0b110, "c.sw", GPRC, uimm7_lsb00> {
   bits<7> imm;
   let Inst{12-10} = imm{5-3};
@@ -128,6 +222,15 @@ def CSW : CStore_rri<0b110, "c.sw", GPRC
   let Inst{5} = imm{6};
 }
 
+let DecoderNamespace = "RISCV32Only_" in
+def CFSW  : CStore_rri<0b111, "c.fsw", FPR32C, uimm7_lsb00>,
+            Requires<[HasStdExtF, IsRV32]> {
+  bits<7> imm;
+  let Inst{12-10} = imm{5-3};
+  let Inst{6} = imm{2};
+  let Inst{5} = imm{6};
+}
+
 def CSD : CStore_rri<0b111, "c.sd", GPRC, uimm8_lsb000>,
           Requires<[IsRV64]> {
   bits<8> imm;
@@ -135,9 +238,77 @@ def CSD : CStore_rri<0b111, "c.sd", GPRC
   let Inst{6-5} = imm{7-6};
 }
 
-let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCall = 1 in
+let rd = 0, imm = 0, hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+def CNOP : RVInst16CI<0b000, 0b01, (outs), (ins), "c.nop", "">;
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+def CADDI : RVInst16CI<0b000, 0b01, (outs GPRNoX0:$rd_wb),
+                       (ins GPRNoX0:$rd, simm6:$imm),
+                       "c.addi", "$rd, $imm"> {
+  let Constraints = "$rd = $rd_wb";
+  let Inst{6-2} = imm{4-0};
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCall = 1,
+DecoderNamespace = "RISCV32Only_" in
 def CJAL : RVInst16CJ<0b001, 0b01, (outs), (ins simm12_lsb0:$offset),
-                      "c.jal", "$offset">;
+                      "c.jal", "$offset">,
+           Requires<[IsRV32]>;
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+def CADDIW : RVInst16CI<0b001, 0b01, (outs GPRNoX0:$rd_wb),
+                        (ins GPRNoX0:$rd, simm6:$imm),
+                        "c.addiw", "$rd, $imm">,
+             Requires<[IsRV64]> {
+  let Constraints = "$rd = $rd_wb";
+  let Inst{6-2} = imm{4-0};
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+def CLI : RVInst16CI<0b010, 0b01, (outs GPRNoX0:$rd), (ins simm6:$imm),
+                     "c.li", "$rd, $imm"> {
+  let Inst{6-2} = imm{4-0};
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+def CADDI16SP : RVInst16CI<0b011, 0b01, (outs SP:$rd_wb),
+                           (ins SP:$rd, simm10_lsb0000:$imm),
+                           "c.addi16sp", "$rd, $imm"> {
+  let Constraints = "$rd = $rd_wb";
+  let Inst{12} = imm{9};
+  let Inst{11-7} = 2;
+  let Inst{6} = imm{4};
+  let Inst{5} = imm{6};
+  let Inst{4-3} = imm{8-7};
+  let Inst{2} = imm{5};
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+def CLUI : RVInst16CI<0b011, 0b01, (outs GPRNoX0X2:$rd),
+                      (ins uimm6nonzero:$imm),
+                      "c.lui", "$rd, $imm"> {
+  let Inst{6-2} = imm{4-0};
+}
+
+def CSRLI   : Shift_right<0b00, "c.srli", GPRC, uimm5nonzero>;
+def CSRAI   : Shift_right<0b01, "c.srai", GPRC, uimm5nonzero>;
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+def CANDI : RVInst16CB<0b100, 0b01, (outs GPRC:$rs1_wb), (ins GPRC:$rs1, simm6:$imm),
+                       "c.andi", "$rs1, $imm"> {
+  let Constraints = "$rs1 = $rs1_wb";
+  let Inst{12} = imm{5};
+  let Inst{11-10} = 0b10;
+  let Inst{6-2} = imm{4-0};
+}
+
+def CSUB   : CS_ALU<0b00, "c.sub", GPRC, 0>;
+def CXOR   : CS_ALU<0b01, "c.xor", GPRC, 0>;
+def COR    : CS_ALU<0b10, "c.or" , GPRC, 0>;
+def CAND   : CS_ALU<0b11, "c.and", GPRC, 0>;
+
+def CSUBW  : CS_ALU<0b00, "c.subw", GPRC, 1>, Requires<[IsRV64]>;
+def CADDW  : CS_ALU<0b01, "c.addw", GPRC, 1>, Requires<[IsRV64]>;
 
 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
 def CJ : RVInst16CJ<0b101, 0b01, (outs), (ins simm12_lsb0:$offset),
@@ -150,11 +321,32 @@ def CJ : RVInst16CJ<0b101, 0b01, (outs),
 def CBEQZ : Bcz<0b110, "c.beqz",  seteq, GPRC>;
 def CBNEZ : Bcz<0b111, "c.bnez",  setne, GPRC>;
 
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+def CSLLI : RVInst16CI<0b000, 0b10, (outs GPRNoX0:$rd_wb),
+                       (ins GPRNoX0:$rd, uimm5nonzero:$imm),
+                       "c.slli" ,"$rd, $imm"> {
+  let Constraints = "$rd = $rd_wb";
+  let Inst{6-2} = imm{4-0};
+}
+
+def CFLDSP  : CStackLoad<0b001, "c.fldsp", FPR64, uimm9_lsb000>,
+              Requires<[HasStdExtD]> {
+  let Inst{6-5} = imm{4-3};
+  let Inst{4-2} = imm{8-6};
+}
+
 def CLWSP : CStackLoad<0b010, "c.lwsp", GPRNoX0, uimm8_lsb00> {
   let Inst{6-4} = imm{4-2};
   let Inst{3-2} = imm{7-6};
 }
 
+let DecoderNamespace = "RISCV32Only_" in
+def CFLWSP  : CStackLoad<0b011, "c.flwsp", FPR32, uimm8_lsb00>,
+              Requires<[HasStdExtF, IsRV32]> {
+  let Inst{6-4} = imm{4-2};
+  let Inst{3-2} = imm{7-6};
+}
+
 def CLDSP : CStackLoad<0b011, "c.ldsp", GPRNoX0, uimm9_lsb000>,
             Requires<[IsRV64]> {
   let Inst{6-5} = imm{4-3};
@@ -171,15 +363,42 @@ def CJR : RVInst16CR<0b1000, 0b10, (outs
   let rs2 = 0;
 }
 
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+def CMV : RVInst16CR<0b1000, 0b10, (outs GPRNoX0:$rs1), (ins GPRNoX0:$rs2),
+                     "c.mv", "$rs1, $rs2">;
+
+let rs1 = 0, rs2 = 0, hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+def CEBREAK : RVInst16CR<0b1001, 0b10, (outs), (ins), "c.ebreak", "">;
+
 let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
     isCall=1, Defs=[X1], rs2 = 0 in
 def CJALR : RVInst16CR<0b1001, 0b10, (outs), (ins GPRNoX0:$rs1),
                        "c.jalr", "$rs1">;
 
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+def CADD : RVInst16CR<0b1001, 0b10, (outs GPRNoX0:$rs1_wb),
+                      (ins GPRNoX0:$rs1, GPRNoX0:$rs2),
+                      "c.add", "$rs1, $rs2"> {
+  let Constraints = "$rs1 = $rs1_wb";
+}
+
+def CFSDSP  : CStackStore<0b101, "c.fsdsp", FPR64, uimm9_lsb000>,
+              Requires<[HasStdExtD]> {
+  let Inst{12-10} = imm{5-3};
+  let Inst{9-7}   = imm{8-6};
+}
+
 def CSWSP : CStackStore<0b110, "c.swsp", GPR, uimm8_lsb00> {
   let Inst{12-9} = imm{5-2};
   let Inst{8-7}  = imm{7-6};
 }
+
+let DecoderNamespace = "RISCV32Only_" in
+def CFSWSP  : CStackStore<0b111, "c.fswsp", FPR32, uimm8_lsb00>,
+              Requires<[HasStdExtF, IsRV32]> {
+  let Inst{12-9} = imm{5-2};
+  let Inst{8-7}  = imm{7-6};
+}
 
 def CSDSP : CStackStore<0b111, "c.sdsp", GPR, uimm9_lsb000>,
             Requires<[IsRV64]> {

Modified: llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.td?rev=320558&r1=320557&r2=320558&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.td (original)
+++ llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.td Wed Dec 13 01:32:55 2017
@@ -106,6 +106,19 @@ def GPRNoX0 : RegisterClass<"RISCV", [XL
       [RegInfo<32,32,32>, RegInfo<64,64,64>, RegInfo<32,32,32>]>;
 }
 
+def GPRNoX0X2 : RegisterClass<"RISCV", [XLenVT], 32, (add
+    (sequence "X%u", 10, 17),
+    (sequence "X%u", 5, 7),
+    (sequence "X%u", 28, 31),
+    (sequence "X%u", 8, 9),
+    (sequence "X%u", 18, 27),
+    X1, X3, X4
+  )> {
+  let RegInfos = RegInfoByHwMode<
+      [RV32,              RV64,              DefaultMode],
+      [RegInfo<32,32,32>, RegInfo<64,64,64>, RegInfo<32,32,32>]>;
+}
+
 def GPRC : RegisterClass<"RISCV", [XLenVT], 32, (add
     (sequence "X%u", 10, 15),
     (sequence "X%u", 8, 9)
@@ -172,6 +185,11 @@ def FPR32 : RegisterClass<"RISCV", [f32]
     (sequence "F%u_32", 18, 27)
 )>;
 
+def FPR32C : RegisterClass<"RISCV", [f32], 32, (add
+  (sequence "F%u_32", 10, 15),
+  (sequence "F%u_32", 8, 9)
+)>;
+
 // The order of registers represents the preferred allocation sequence,
 // meaning caller-save regs are listed before callee-save.
 def FPR64 : RegisterClass<"RISCV", [f64], 64, (add
@@ -181,3 +199,8 @@ def FPR64 : RegisterClass<"RISCV", [f64]
     (sequence "F%u_64", 8, 9),
     (sequence "F%u_64", 18, 27)
 )>;
+
+def FPR64C : RegisterClass<"RISCV", [f64], 64, (add
+  (sequence "F%u_64", 10, 15),
+  (sequence "F%u_64", 8, 9)
+)>;

Modified: llvm/trunk/test/MC/RISCV/rv32c-invalid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/rv32c-invalid.s?rev=320558&r1=320557&r2=320558&view=diff
==============================================================================
--- llvm/trunk/test/MC/RISCV/rv32c-invalid.s (original)
+++ llvm/trunk/test/MC/RISCV/rv32c-invalid.s Wed Dec 13 01:32:55 2017
@@ -6,15 +6,52 @@ c.lw  ra, 4(sp) # CHECK: :[[@LINE]]:7: e
 c.sw  sp, 4(sp) # CHECK: :[[@LINE]]:7: error: invalid operand for instruction
 c.beqz  t0, .LBB # CHECK: :[[@LINE]]:9: error: invalid operand for instruction
 c.bnez  s8, .LBB # CHECK: :[[@LINE]]:9: error: invalid operand for instruction
+c.addi4spn  s4, sp, 12 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction
+c.srli  s7, 12 # CHECK: :[[@LINE]]:9: error: invalid operand for instruction
+c.srai  t0, 12 # CHECK: :[[@LINE]]:9: error: invalid operand for instruction
+c.andi  t1, 12 # CHECK: :[[@LINE]]:9: error: invalid operand for instruction
+c.and  t1, a0 # CHECK: :[[@LINE]]:8: error: invalid operand for instruction
+c.or   a0, s8 # CHECK: :[[@LINE]]:12: error: invalid operand for instruction
+c.xor  t2, a0 # CHECK: :[[@LINE]]:8: error: invalid operand for instruction
+c.sub  a0, s8 # CHECK: :[[@LINE]]:12: error: invalid operand for instruction
 
 ## GPRNoX0
 c.lwsp  x0, 4(sp) # CHECK: :[[@LINE]]:9: error: invalid operand for instruction
 c.lwsp  zero, 4(sp) # CHECK: :[[@LINE]]:9: error: invalid operand for instruction
 c.jr  x0 # CHECK: :[[@LINE]]:7: error: invalid operand for instruction
 c.jalr  zero # CHECK: :[[@LINE]]:9: error: invalid operand for instruction
+c.addi  x0, x0, 1 # CHECK: :[[@LINE]]:9: error: invalid operand for instruction
+c.li  zero, 2 # CHECK: :[[@LINE]]:7: error: invalid operand for instruction
+c.slli  zero, zero, 4 # CHECK: :[[@LINE]]:9: error: invalid operand for instruction
+c.mv  zero, s0 # CHECK: :[[@LINE]]:7: error: invalid operand for instruction
+c.mv  ra, x0 # CHECK: :[[@LINE]]:11: error: invalid operand for instruction
+c.add  ra, ra, x0 # CHECK: :[[@LINE]]:16: error: invalid operand for instruction
+c.add  zero, zero, sp # CHECK: :[[@LINE]]:8: error: invalid operand for instruction
+
+## GPRNoX0X2
+c.lui x0, 4 # CHECK: :[[@LINE]]:7: error: invalid operand for instruction
+c.lui x2, 4 # CHECK: :[[@LINE]]:7: error: invalid operand for instruction
+
+## SP
+c.addi4spn  a0, a0, 12 # CHECK: :[[@LINE]]:17: error: invalid operand for instruction
+c.addi16sp  t0, 16 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction
 
 # Out of range immediates
 
+## uimm5nonzero
+c.slli t0, 64 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [1, 31]
+c.srli a0, 32 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [1, 31]
+c.srai a0, 0  # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [1, 31]
+
+## simm6
+c.li t0, 128 # CHECK: :[[@LINE]]:10: error: immediate must be an integer in the range [-32, 31]
+c.addi t0, 32 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [-32, 31]
+c.andi a0, -33 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [-32, 31]
+
+## uimm6nonzero
+c.lui t0, 64 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [1, 63]
+c.lui t0, 0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [1, 63]
+
 ## uimm8_lsb00
 c.lwsp  ra, 256(sp) # CHECK: :[[@LINE]]:13: error: immediate must be a multiple of 4 bytes in the range [0, 252]
 c.swsp  ra, -4(sp) # CHECK: :[[@LINE]]:13: error: immediate must be a multiple of 4 bytes in the range [0, 252]
@@ -29,3 +66,11 @@ c.beqz  a0, 256 # CHECK: :[[@LINE]]:13:
 ## simm12_lsb0
 c.j 2048 # CHECK: :[[@LINE]]:5: error: immediate must be a multiple of 2 bytes in the range [-2048, 2046]
 c.jal -2050 # CHECK: :[[@LINE]]:7: error: immediate must be a multiple of 2 bytes in the range [-2048, 2046]
+
+## uimm10_lsb00nonzero
+c.addi4spn  a0, sp, 0 # CHECK: :[[@LINE]]:21: error: immediate must be a multiple of 4 bytes in the range [4, 1020]
+c.addi4spn  a0, sp, 1024 # CHECK: :[[@LINE]]:21: error: immediate must be a multiple of 4 bytes in the range [4, 1020]
+
+## simm10_lsb0000
+c.addi16sp  sp, -528 # CHECK: :[[@LINE]]:17: error: immediate must be a multiple of 16 bytes in the range [-512, 496]
+c.addi16sp  sp, 512 # CHECK: :[[@LINE]]:17: error: immediate must be a multiple of 16 bytes in the range [-512, 496]

Added: llvm/trunk/test/MC/RISCV/rv32c-only-valid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/rv32c-only-valid.s?rev=320558&view=auto
==============================================================================
--- llvm/trunk/test/MC/RISCV/rv32c-only-valid.s (added)
+++ llvm/trunk/test/MC/RISCV/rv32c-only-valid.s Wed Dec 13 01:32:55 2017
@@ -0,0 +1,8 @@
+# RUN: llvm-mc -triple=riscv32 -mattr=+c -show-encoding < %s \
+# RUN:     | FileCheck -check-prefixes=CHECK,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+c < %s \
+# RUN:     | llvm-objdump -mattr=+c -d - | FileCheck -check-prefix=CHECK-INST %s
+
+# CHECK-INST: c.jal    2046
+# CHECK: encoding: [0xfd,0x2f]
+c.jal    2046

Modified: llvm/trunk/test/MC/RISCV/rv32c-valid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/rv32c-valid.s?rev=320558&r1=320557&r2=320558&view=diff
==============================================================================
--- llvm/trunk/test/MC/RISCV/rv32c-valid.s (original)
+++ llvm/trunk/test/MC/RISCV/rv32c-valid.s Wed Dec 13 01:32:55 2017
@@ -25,9 +25,6 @@ c.sw    a5, 124(a3)
 # CHECK-INST: c.j     -2048
 # CHECK: encoding: [0x01,0xb0]
 c.j     -2048
-# CHECK-INST: c.jal    2046
-# CHECK: encoding: [0xfd,0x2f]
-c.jal    2046
 # CHECK-INST: c.jr    a7
 # CHECK: encoding: [0x82,0x88]
 c.jr    a7
@@ -40,3 +37,61 @@ c.beqz  a3, -256
 # CHECK-INST: c.bnez  a5,  254
 # CHECK: encoding: [0xfd,0xef]
 c.bnez  a5,  254
+
+# CHECK-INST: c.li  a7, 31
+# CHECK: encoding: [0xfd,0x48]
+c.li    a7, 31
+# CHECK-INST: c.addi  a3, -32
+# CHECK: encoding: [0x81,0x16]
+c.addi  a3, -32
+# CHECK-INST: c.addi16sp  sp, -512
+# CHECK: encoding: [0x01,0x71]
+c.addi16sp  sp, -512
+# CHECK-INST: c.addi16sp  sp, 496
+# CHECK: encoding: [0x7d,0x61]
+c.addi16sp  sp, 496
+# CHECK-INST: c.addi4spn  a3, sp, 1020
+# CHECK: encoding: [0xf4,0x1f]
+c.addi4spn      a3, sp, 1020
+# CHECK-INST: c.addi4spn  a3, sp, 4
+# CHECK: encoding: [0x54,0x00]
+c.addi4spn      a3, sp, 4
+# CHECK-INST: c.slli  a1, 1
+# CHECK: encoding: [0x86,0x05]
+c.slli  a1, 1
+# CHECK-INST: c.srli  a3, 31
+# CHECK: encoding: [0xfd,0x82]
+c.srli  a3, 31
+# CHECK-INST: c.srai  a4, 2
+# CHECK: encoding: [0x09,0x87]
+c.srai  a4, 2
+# CHECK-INST: c.andi  a5, 15
+# CHECK: encoding: [0xbd,0x8b]
+c.andi  a5, 15
+# CHECK-INST: c.mv    a7, s0
+# CHECK: encoding: [0xa2,0x88]
+c.mv    a7, s0
+# CHECK-INST: c.and   a1, a2
+# CHECK: encoding: [0xf1,0x8d]
+c.and   a1, a2
+# CHECK-INST: c.or    a2, a3
+# CHECK: encoding: [0x55,0x8e]
+c.or    a2, a3
+# CHECK-INST: c.xor   a3, a4
+# CHECK: encoding: [0xb9,0x8e]
+c.xor   a3, a4
+# CHECK-INST: c.sub   a4, a5
+# CHECK: encoding: [0x1d,0x8f]
+c.sub   a4, a5
+# CHECK-INST: c.nop
+# CHECK: encoding: [0x01,0x00]
+c.nop
+# CHECK-INST: c.ebreak
+# CHECK: encoding: [0x02,0x90]
+c.ebreak
+# CHECK-INST: c.lui   s0, 1
+# CHECK: encoding: [0x05,0x64]
+c.lui   s0, 1
+# CHECK-INST: c.lui   s0, 63
+# CHECK: encoding: [0x7d,0x74]
+c.lui   s0, 63

Added: llvm/trunk/test/MC/RISCV/rv32dc-invalid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/rv32dc-invalid.s?rev=320558&view=auto
==============================================================================
--- llvm/trunk/test/MC/RISCV/rv32dc-invalid.s (added)
+++ llvm/trunk/test/MC/RISCV/rv32dc-invalid.s Wed Dec 13 01:32:55 2017
@@ -0,0 +1,12 @@
+# RUN: not llvm-mc -triple=riscv32 -mattr=+c,+d < %s 2>&1 | FileCheck %s
+
+## FPRC
+c.fld  ft3, 8(a5) # CHECK: :[[@LINE]]:8: error: invalid operand for instruction
+
+## uimm9_lsb000
+c.fldsp  fs1, 512(sp) # CHECK: :[[@LINE]]:15: error: immediate must be a multiple of 8 bytes in the range [0, 504]
+c.fsdsp  fs2, -8(sp) # CHECK: :[[@LINE]]:15: error: immediate must be a multiple of 8 bytes in the range [0, 504]
+
+## uimm8_lsb000
+c.fld  fs0, -8(sp) # CHECK: :[[@LINE]]:13: error: immediate must be a multiple of 8 bytes in the range [0, 248]
+c.fsd  fs1, 256(sp) # CHECK: :[[@LINE]]:13: error: immediate must be a multiple of 8 bytes in the range [0, 248]

Added: llvm/trunk/test/MC/RISCV/rv32dc-valid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/rv32dc-valid.s?rev=320558&view=auto
==============================================================================
--- llvm/trunk/test/MC/RISCV/rv32dc-valid.s (added)
+++ llvm/trunk/test/MC/RISCV/rv32dc-valid.s Wed Dec 13 01:32:55 2017
@@ -0,0 +1,18 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+c,+d -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+c,+d < %s \
+# RUN:     | llvm-objdump -mattr=+c,+d -d - | FileCheck -check-prefix=CHECK-INST %s
+
+# CHECK-INST: c.fldsp  fs0, 504(sp)
+# CHECK: encoding: [0x7e,0x34]
+c.fldsp  fs0, 504(sp)
+# CHECK-INST: c.fsdsp  fa7, 504(sp)
+# CHECK: encoding: [0xc6,0xbf]
+c.fsdsp  fa7, 504(sp)
+
+# CHECK-INST: c.fld  fa3, 248(a5)
+# CHECK: encoding: [0xf4,0x3f]
+c.fld  fa3, 248(a5)
+# CHECK-INST: c.fsd  fa2, 248(a1)
+# CHECK: encoding: [0xf0,0xbd]
+c.fsd  fa2, 248(a1)

Added: llvm/trunk/test/MC/RISCV/rv32fc-invalid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/rv32fc-invalid.s?rev=320558&view=auto
==============================================================================
--- llvm/trunk/test/MC/RISCV/rv32fc-invalid.s (added)
+++ llvm/trunk/test/MC/RISCV/rv32fc-invalid.s Wed Dec 13 01:32:55 2017
@@ -0,0 +1,12 @@
+# RUN: not llvm-mc -triple=riscv32 -mattr=+c,+f < %s 2>&1 | FileCheck %s
+
+## FPRC
+c.flw  ft3, 8(a5) # CHECK: :[[@LINE]]:8: error: invalid operand for instruction
+
+## uimm8_lsb00
+c.flwsp  fs1, 256(sp) # CHECK: :[[@LINE]]:15: error: immediate must be a multiple of 4 bytes in the range [0, 252]
+c.fswsp  fs2, -4(sp) # CHECK: :[[@LINE]]:15: error: immediate must be a multiple of 4 bytes in the range [0, 252]
+
+## uimm7_lsb00
+c.flw  fs0, -4(sp) # CHECK: :[[@LINE]]:13: error: immediate must be a multiple of 4 bytes in the range [0, 124]
+c.fsw  fs1, 128(sp) # CHECK: :[[@LINE]]:13: error: immediate must be a multiple of 4 bytes in the range [0, 124]

Added: llvm/trunk/test/MC/RISCV/rv32fc-valid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/rv32fc-valid.s?rev=320558&view=auto
==============================================================================
--- llvm/trunk/test/MC/RISCV/rv32fc-valid.s (added)
+++ llvm/trunk/test/MC/RISCV/rv32fc-valid.s Wed Dec 13 01:32:55 2017
@@ -0,0 +1,18 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+c,+f -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+c,+f < %s \
+# RUN:     | llvm-objdump -mattr=+c,+f -d - | FileCheck -check-prefix=CHECK-INST %s
+
+# CHECK-INST: c.flwsp  fs0, 252(sp)
+# CHECK: encoding: [0x7e,0x74]
+c.flwsp  fs0, 252(sp)
+# CHECK-INST: c.fswsp  fa7, 252(sp)
+# CHECK: encoding: [0xc6,0xff]
+c.fswsp  fa7, 252(sp)
+
+# CHECK-INST: c.flw  fa3, 124(a5)
+# CHECK: encoding: [0xf4,0x7f]
+c.flw  fa3, 124(a5)
+# CHECK-INST: c.fsw  fa2, 124(a1)
+# CHECK: encoding: [0xf0,0xfd]
+c.fsw  fa2, 124(a1)

Modified: llvm/trunk/test/MC/RISCV/rv64c-invalid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/rv64c-invalid.s?rev=320558&r1=320557&r2=320558&view=diff
==============================================================================
--- llvm/trunk/test/MC/RISCV/rv64c-invalid.s (original)
+++ llvm/trunk/test/MC/RISCV/rv64c-invalid.s Wed Dec 13 01:32:55 2017
@@ -3,6 +3,8 @@
 ## GPRC
 c.ld ra, 4(sp) # CHECK: :[[@LINE]]:6: error: invalid operand for instruction
 c.sd sp, 4(sp) # CHECK: :[[@LINE]]:6: error: invalid operand for instruction
+c.addw   a0, a7 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction
+c.subw   a0, a6 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction
 
 ## GPRNoX0
 c.ldsp  x0, 4(sp) # CHECK: :[[@LINE]]:9: error: invalid operand for instruction
@@ -10,6 +12,10 @@ c.ldsp  zero, 4(sp) # CHECK: :[[@LINE]]:
 
 # Out of range immediates
 
+## simm6
+c.addiw t0, -33 # CHECK: :[[@LINE]]:13: error: immediate must be an integer in the range [-32, 31]
+c.addiw t0, 32 # CHECK: :[[@LINE]]:13: error: immediate must be an integer in the range [-32, 31]
+
 ## uimm9_lsb000
 c.ldsp  ra, 512(sp) # CHECK: :[[@LINE]]:13: error: immediate must be a multiple of 8 bytes in the range [0, 504]
 c.sdsp  ra, -8(sp) # CHECK: :[[@LINE]]:13: error: immediate must be a multiple of 8 bytes in the range [0, 504]

Modified: llvm/trunk/test/MC/RISCV/rv64c-valid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/rv64c-valid.s?rev=320558&r1=320557&r2=320558&view=diff
==============================================================================
--- llvm/trunk/test/MC/RISCV/rv64c-valid.s (original)
+++ llvm/trunk/test/MC/RISCV/rv64c-valid.s Wed Dec 13 01:32:55 2017
@@ -17,3 +17,17 @@ c.ld    a4, 0(a3)
 # CHECK-INST: c.sd    a5, 248(a3)
 # CHECK: encoding: [0xfc,0xfe]
 c.sd    a5, 248(a3)
+
+# CHECK-INST: c.subw   a3, a4
+# CHECK: encoding: [0x99,0x9e]
+c.subw   a3, a4
+# CHECK-INST: c.addw   a0, a2
+# CHECK: encoding: [0x31,0x9d]
+c.addw   a0, a2
+
+# CHECK-INST: c.addiw  a3, -32
+# CHECK: encoding: [0x81,0x36]
+c.addiw  a3, -32
+# CHECK-INST: c.addiw  a3, 31
+# CHECK: encoding: [0xfd,0x26]
+c.addiw  a3, 31




More information about the llvm-commits mailing list