summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp69
-rw-r--r--llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp80
-rw-r--r--llvm/lib/Target/RISCV/RISCVInstrFormatsC.td11
-rw-r--r--llvm/lib/Target/RISCV/RISCVInstrInfoC.td227
-rw-r--r--llvm/lib/Target/RISCV/RISCVRegisterInfo.td23
5 files changed, 390 insertions, 20 deletions
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index cde00f5d515..0cf97f88fc6 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -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::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
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::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
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::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
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);
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 91c0b5a9d24..932bc710508 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -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;
-
- // 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;
+ 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;
}
static const unsigned FPR32DecoderTable[] = {
@@ -105,6 +105,17 @@ static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint64_t RegNo,
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 DecodeFPR64RegisterClass(MCInst &Inst, uint64_t RegNo,
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);
+}
+
+static DecodeStatus DecodeGPRNoX0X2RegisterClass(MCInst &Inst, uint64_t RegNo,
+ uint64_t Address,
+ const void *Decoder) {
+ if (RegNo == 2) {
+ return MCDisassembler::Fail;
+ }
- return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
+ return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder);
}
static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo,
@@ -155,7 +187,14 @@ static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo,
// 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::getInstruction(MCInst &MI, uint64_t &Size,
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);
diff --git a/llvm/lib/Target/RISCV/RISCVInstrFormatsC.td b/llvm/lib/Target/RISCV/RISCVInstrFormatsC.td
index fe4778bd313..6abcbd7cc8a 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrFormatsC.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrFormatsC.td
@@ -77,6 +77,17 @@ class RVInst16CSS<bits<3> funct3, bits<2> opcode, dag outs, dag ins,
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.
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td
index 76c3d559c70..d0634a395d3 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td
@@ -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 OpcodeStr,
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 OpcodeStr, PatFrag CondOp,
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, uimm7_lsb00> {
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, uimm8_lsb000>,
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, uimm7_lsb00> {
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, uimm8_lsb000>,
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), (ins simm12_lsb0:$offset),
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,16 +363,43 @@ def CJR : RVInst16CR<0b1000, 0b10, (outs), (ins GPRNoX0:$rs1),
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]> {
let Inst{12-10} = imm{5-3};
diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
index c17a359743a..21be2e332e5 100644
--- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
@@ -106,6 +106,19 @@ def GPRNoX0 : RegisterClass<"RISCV", [XLenVT], 32, (add
[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], 32, (add
(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], 64, (add
(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)
+)>;
OpenPOWER on IntegriCloud