Index: lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp =================================================================== --- lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -194,6 +194,24 @@ 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; @@ -210,6 +228,14 @@ 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 isUImm8Lsb000() const { int64_t Imm; RISCVMCExpr::VariantKind VK; @@ -226,6 +252,19 @@ 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; @@ -256,6 +295,14 @@ 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; @@ -426,6 +473,10 @@ } 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, @@ -442,6 +493,13 @@ 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_InvalidSImm12: return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1); @@ -459,6 +517,10 @@ return generateImmOutOfRangeError( Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2, "immediate must be a multiple of 2 bytes in the range"); + 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_InvalidUImm20: return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1); case Match_InvalidSImm21Lsb0: Index: lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp =================================================================== --- lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -91,6 +91,16 @@ return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder); } +static DecodeStatus DecodeGPRNonX0X2RegisterClass(MCInst &Inst, uint64_t RegNo, + uint64_t Address, + const void *Decoder) { + if (RegNo == 2) { + return MCDisassembler::Fail; + } + + return DecodeGPRNonX0RegisterClass(Inst, RegNo, Address, Decoder); +} + static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder) { @@ -106,7 +116,12 @@ // in bit field). 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::CADDI4SPN) { + DecodeGPRRegisterClass(Inst, 2, Address, Decoder); + } + if (Inst.getOpcode() == RISCV::CADDI16SP) { + DecodeGPRRegisterClass(Inst, 2, Address, Decoder); DecodeGPRRegisterClass(Inst, 2, Address, Decoder); } } @@ -124,6 +139,7 @@ static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm, int64_t Address, const void *Decoder) { assert(isUInt(Imm) && "Invalid immediate"); + addImplySP(Inst, Address, Decoder); // Sign-extend the number in the bottom N bits of Imm Inst.addOperand(MCOperand::createImm(SignExtend64(Imm))); return MCDisassembler::Success; Index: lib/Target/RISCV/RISCVInstrFormatsC.td =================================================================== --- lib/Target/RISCV/RISCVInstrFormatsC.td +++ lib/Target/RISCV/RISCVInstrFormatsC.td @@ -77,6 +77,17 @@ let Inst{1-0} = opcode; } +class RVInst16CIW funct3, bits<2> opcode, dag outs, dag ins, + string opcodestr, string argstr> + : RVInst16 { + 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. Index: lib/Target/RISCV/RISCVInstrInfoC.td =================================================================== --- lib/Target/RISCV/RISCVInstrInfoC.td +++ lib/Target/RISCV/RISCVInstrInfoC.td @@ -13,6 +13,24 @@ // Operand definitions. //===----------------------------------------------------------------------===// +def uimm5nonzero : Operand, + ImmLeaf(Imm) && (Imm != 0);}]> { + let ParserMatchClass = UImmAsmOperand<5, "NonZero">; + let DecoderMethod = "decodeUImmOperand<5>"; +} + +def uimm6nonzero : Operand, + ImmLeaf(Imm) && (Imm != 0);}]> { + let ParserMatchClass = UImmAsmOperand<6, "NonZero">; + let DecoderMethod = "decodeUImmOperand<6>"; +} + +def simm6 : Operand, ImmLeaf(Imm);}]> { + let ParserMatchClass = SImmAsmOperand<6>; + let EncoderMethod = "getImmOpValue"; + let DecoderMethod = "decodeSImmOperand<6>"; +} + // A 9-bit signed immediate where the least significant bit is zero. def simm9_lsb0 : Operand { let ParserMatchClass = SImmAsmOperand<9, "Lsb0">; @@ -59,6 +77,24 @@ 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, + ImmLeaf(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, + ImmLeaf(Imm);}]> { + let ParserMatchClass = SImmAsmOperand<10, "Lsb0000">; + let EncoderMethod = "getImmOpValue"; + let DecoderMethod = "decodeSImmOperand<10>"; +} + //===----------------------------------------------------------------------===// // Instruction Class Templates //===----------------------------------------------------------------------===// @@ -101,12 +137,47 @@ let Inst{2} = imm{4}; } +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class Shift_right 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 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 CLW : CLoad_ri<0b010, "c.lw", GPRC, uimm7_lsb00> { bits<7> imm; let Inst{12-10} = imm{5-3}; @@ -135,11 +206,68 @@ let Inst{6-5} = imm{7-6}; } +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 GPRNonX0:$rd_wb), + (ins GPRNonX0:$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 in def CJAL : RVInst16CJ<0b001, 0b01, (outs), (ins simm12_lsb0:$offset), "c.jal", "$offset">; let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +def CLI : RVInst16CI<0b010, 0b01, (outs GPRNonX0:$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 GPRNonX0X2:$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), "c.j", "$offset"> { let isBranch = 1; @@ -150,6 +278,14 @@ 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 GPRNonX0:$rd_wb), + (ins GPRNonX0:$rd, uimm5nonzero:$imm), + "c.slli" ,"$rd, $imm"> { + let Constraints = "$rd = $rd_wb"; + let Inst{6-2} = imm{4-0}; +} + def CLWSP : CStackLoad<0b010, "c.lwsp", GPRNonX0, uimm8_lsb00> { let Inst{6-4} = imm{4-2}; let Inst{3-2} = imm{7-6}; @@ -171,11 +307,25 @@ let rs2 = 0; } +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +def CMV : RVInst16CR<0b1000, 0b10, (outs GPRNonX0:$rs1), (ins GPRNonX0:$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 GPRNonX0:$rs1), "c.jalr", "$rs1">; +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +def CADD : RVInst16CR<0b1001, 0b10, (outs GPRNonX0:$rs1_wb), + (ins GPRNonX0:$rs1, GPRNonX0:$rs2), + "c.add", "$rs1, $rs2"> { + let Constraints = "$rs1 = $rs1_wb"; +} + def CSWSP : CStackStore<0b110, "c.swsp", GPR, uimm8_lsb00> { let Inst{12-9} = imm{5-2}; let Inst{8-7} = imm{7-6}; Index: lib/Target/RISCV/RISCVRegisterInfo.td =================================================================== --- lib/Target/RISCV/RISCVRegisterInfo.td +++ lib/Target/RISCV/RISCVRegisterInfo.td @@ -88,6 +88,19 @@ [RegInfo<32,32,32>, RegInfo<64,64,64>, RegInfo<32,32,32>]>; } +def GPRNonX0X2 : 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) Index: test/MC/RISCV/rv32c-invalid.s =================================================================== --- test/MC/RISCV/rv32c-invalid.s +++ test/MC/RISCV/rv32c-invalid.s @@ -6,15 +6,52 @@ 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 ## GPRNonX0 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 + +## GPRNonX0X2 +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 @@ ## 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] Index: test/MC/RISCV/rv32c-valid.s =================================================================== --- test/MC/RISCV/rv32c-valid.s +++ test/MC/RISCV/rv32c-valid.s @@ -39,3 +39,61 @@ # 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 Index: test/MC/RISCV/rv64c-invalid.s =================================================================== --- test/MC/RISCV/rv64c-invalid.s +++ test/MC/RISCV/rv64c-invalid.s @@ -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 ## GPRNonX0 c.ldsp x0, 4(sp) # CHECK: :[[@LINE]]:9: error: invalid operand for instruction Index: test/MC/RISCV/rv64c-valid.s =================================================================== --- test/MC/RISCV/rv64c-valid.s +++ test/MC/RISCV/rv64c-valid.s @@ -16,3 +16,10 @@ # 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