Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
bool isSImm5() const { return isSImm<5>(); }
bool isSImm6() const { return isSImm<6>(); }
bool isSImm11() const { return isSImm<11>(); }
bool isSImm16() const { return isSImm<16>(); }
bool isSImm20() const { return isSImm<20>(); }
bool isSImm26() const { return isSImm<26>(); }
bool isSImm32() const { return isSImm<32>(); }
Expand Down Expand Up @@ -1511,6 +1512,9 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2,
"immediate must be a multiple of 2 bytes in the range");
case Match_InvalidSImm16:
return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 15),
(1 << 15) - 1);
case Match_InvalidSImm16NonZero:
return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 15), (1 << 15) - 1,
Expand Down Expand Up @@ -3150,10 +3154,13 @@ bool RISCVAsmParser::parseDirectiveAttribute() {
return false;
}

bool isValidInsnFormat(StringRef Format, bool AllowC) {
bool isValidInsnFormat(StringRef Format, const MCSubtargetInfo &STI) {
return StringSwitch<bool>(Format)
.Cases("r", "r4", "i", "b", "sb", "u", "j", "uj", "s", true)
.Cases("cr", "ci", "ciw", "css", "cl", "cs", "ca", "cb", "cj", AllowC)
.Cases("cr", "ci", "ciw", "css", "cl", "cs", "ca", "cb", "cj",
STI.hasFeature(RISCV::FeatureStdExtZca))
.Cases("qc.eai", "qc.ei", "qc.eb", "qc.ej", "qc.es",
!STI.hasFeature(RISCV::Feature64Bit))
.Default(false);
}

Expand Down Expand Up @@ -3243,7 +3250,7 @@ bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) {
return false;
}

if (!isValidInsnFormat(Format, AllowC))
if (!isValidInsnFormat(Format, getSTI()))
return Error(ErrorLoc, "invalid instruction format");

std::string FormatName = (".insn_" + Format).str();
Expand Down
8 changes: 7 additions & 1 deletion llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,12 @@ enum {
InstFormatCLH = 19,
InstFormatCSB = 20,
InstFormatCSH = 21,
InstFormatOther = 22,
InstFormatQC_EAI = 22,
InstFormatQC_EI = 23,
InstFormatQC_EB = 24,
InstFormatQC_EJ = 25,
InstFormatQC_ES = 26,
InstFormatOther = 31,

InstFormatMask = 31,
InstFormatShift = 0,
Expand Down Expand Up @@ -333,6 +338,7 @@ enum OperandType : unsigned {
OPERAND_SIMM11,
OPERAND_SIMM12,
OPERAND_SIMM12_LSB00000,
OPERAND_SIMM16,
OPERAND_SIMM16_NONZERO,
OPERAND_SIMM20,
OPERAND_SIMM26,
Expand Down
8 changes: 7 additions & 1 deletion llvm/lib/Target/RISCV/RISCVInstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,13 @@ def InstFormatCLB : InstFormat<18>;
def InstFormatCLH : InstFormat<19>;
def InstFormatCSB : InstFormat<20>;
def InstFormatCSH : InstFormat<21>;
def InstFormatOther : InstFormat<22>;
def InstFormatQC_EAI : InstFormat<22>;
def InstFormatQC_EI : InstFormat<23>;
def InstFormatQC_EB : InstFormat<24>;
def InstFormatQC_EJ : InstFormat<25>;
def InstFormatQC_ES : InstFormat<26>;
def InstFormatOther : InstFormat<31>;


class RISCVVConstraint<bits<3> val> {
bits<3> Value = val;
Expand Down
45 changes: 28 additions & 17 deletions llvm/lib/Target/RISCV/RISCVInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -1144,6 +1144,33 @@ def AnyReg : Operand<XLenVT> {
let ParserMatchClass = AnyRegOperand;
}

// isCodeGenOnly = 1 to hide them from the tablegened assembly parser.
let isCodeGenOnly = 1, hasSideEffects = 1, mayLoad = 1, mayStore = 1,
hasNoSchedulingInfo = 1 in {
def Insn16 : RVInst16<(outs), (ins uimm16:$value), "", "", [], InstFormatOther> {
bits<16> value;

let Inst{15-0} = value;
let AsmString = ".insn 0x2, $value";
}
def Insn32 : RVInst<(outs), (ins uimm32:$value), "", "", [], InstFormatOther> {
bits<32> value;

let Inst{31-0} = value;
let AsmString = ".insn 0x4, $value";
}
def Insn48 : RVInst48<(outs), (ins uimm48:$value), "", "", [], InstFormatOther> {
bits<48> value;
let Inst{47-0} = value;
let AsmString = ".insn 0x6, $value";
}
def Insn64 : RVInst64<(outs), (ins uimm64:$value), "", "", [], InstFormatOther> {
bits<64> value;
let Inst{63-0} = value;
let AsmString = ".insn 0x8, $value";
}
} // isCodeGenOnly, hasSideEffects, mayLoad, mayStore, hasNoSchedulingInfo

// isCodeGenOnly = 1 to hide them from the tablegened assembly parser.
let isCodeGenOnly = 1, hasSideEffects = 1, mayLoad = 1, mayStore = 1,
hasNoSchedulingInfo = 1 in {
Expand Down Expand Up @@ -1179,23 +1206,7 @@ def InsnS : DirectiveInsnS<(outs), (ins uimm7_opcode:$opcode, uimm3:$funct3,
AnyReg:$rs2, AnyReg:$rs1,
simm12:$imm12),
"$opcode, $funct3, $rs2, ${imm12}(${rs1})">;
def Insn32 : RVInst<(outs), (ins uimm32:$value), "", "", [], InstFormatOther> {
bits<32> value;

let Inst{31-0} = value;
let AsmString = ".insn 0x4, $value";
}
def Insn48 : RVInst48<(outs), (ins uimm48:$value), "", "", [], InstFormatOther> {
bits<48> value;
let Inst{47-0} = value;
let AsmString = ".insn 0x6, $value";
}
def Insn64 : RVInst64<(outs), (ins uimm64:$value), "", "", [], InstFormatOther> {
bits<64> value;
let Inst{63-0} = value;
let AsmString = ".insn 0x8, $value";
}
}
} // isCodeGenOnly, hasSideEffects, mayLoad, mayStore, hasNoSchedulingInfo

// Use InstAliases to match these so that we can combine the insn and format
// into a mnemonic to use as the key for the tablegened asm matcher table. The
Expand Down
6 changes: 0 additions & 6 deletions llvm/lib/Target/RISCV/RISCVInstrInfoC.td
Original file line number Diff line number Diff line change
Expand Up @@ -799,12 +799,6 @@ def InsnCJ : DirectiveInsnCJ<(outs), (ins uimm2_opcode:$opcode,
uimm3:$funct3,
bare_simm12_lsb0:$imm11),
"$opcode, $funct3, $imm11">;
def Insn16 : RVInst16<(outs), (ins uimm16:$value), "", "", [], InstFormatOther> {
bits<16> value;

let Inst{15-0} = value;
let AsmString = ".insn 0x2, $value";
}
}

// Use InstAliases to match these so that we can combine the insn and format
Expand Down
215 changes: 215 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ def simm5nonzero : RISCVOp<XLenVT>,

def simm11 : RISCVSImmLeafOp<11>;

def simm16 : RISCVSImmOp<16>;

def simm16nonzero : RISCVOp<XLenVT>,
ImmLeaf<XLenVT, [{return (Imm != 0) && isInt<16>(Imm);}]> {
let ParserMatchClass = SImmAsmOperand<16, "NonZero">;
Expand Down Expand Up @@ -139,6 +141,219 @@ def simm32_lsb0 : Operand<OtherVT> {
// Instruction Formats
//===----------------------------------------------------------------------===//


class DirectiveInsnQC_EAI<dag outs, dag ins, string argstr>
: RVInst48<outs, ins, "", "", [], InstFormatQC_EAI> {
bits<7> opcode;
bits<3> func3;
bits<1> func1;

bits<5> rd;
bits<32> imm32;

let Inst{47-16} = imm32;
let Inst{15} = func1;
let Inst{14-12} = func3;
let Inst{11-7} = rd;
let Inst{6-0} = opcode;

let AsmString = ".insn qc.eai " # argstr;
}

class DirectiveInsnQC_EI<dag outs, dag ins, string argstr>
: RVInst48<outs, ins, "", "", [], InstFormatQC_EI> {
bits<7> opcode;
bits<3> func3;
bits<2> func2;

bits<5> rd;
bits<5> rs1;
bits<26> imm26;

let Inst{47-32} = imm26{25-10};
let Inst{31-30} = func2;
let Inst{29-20} = imm26{9-0};
let Inst{19-15} = rs1;
let Inst{14-12} = func3;
let Inst{11-7} = rd;
let Inst{6-0} = opcode;

let AsmString = ".insn qc.ei " # argstr;
}

class DirectiveInsnQC_EB<dag outs, dag ins, string argstr>
: RVInst48<outs, ins, "", "", [], InstFormatQC_EB> {
bits<7> opcode;
bits<3> func3;
bits<5> func5;

bits<5> rs1;
bits<12> imm12; // This one is the PC-relative offset
bits<16> imm16;

let Inst{47-32} = imm16;
let Inst{31} = imm12{11};
let Inst{30-25} = imm12{9-4};
let Inst{24-20} = func5;
let Inst{19-15} = rs1;
let Inst{14-12} = func3;
let Inst{11-8} = imm12{3-0};
let Inst{7} = imm12{10};
let Inst{6-0} = opcode;

let AsmString = ".insn qc.eb " # argstr;
}

class DirectiveInsnQC_EJ<dag outs, dag ins, string argstr>
: RVInst48<outs, ins, "", "", [], InstFormatQC_EJ> {
bits<7> opcode;
bits<3> func3;
bits<2> func2;
bits<5> func5;

bits<31> imm31;

let Inst{47-32} = imm31{30-15};
let Inst{31} = imm31{11};
let Inst{30-25} = imm31{9-4};
let Inst{24-20} = func5;
let Inst{19-17} = imm31{14-12};
let Inst{16-15} = func2;
let Inst{14-12} = func3;
let Inst{11-8} = imm31{3-0};
let Inst{7} = imm31{10};
let Inst{6-0} = opcode;

let AsmString = ".insn qc.ej " # argstr;
}

class DirectiveInsnQC_ES<dag outs, dag ins, string argstr>
: RVInst48<outs, ins, "", "", [], InstFormatQC_ES> {
bits<7> opcode;
bits<3> func3;
bits<2> func2;

bits<5> rs1;
bits<5> rs2;
bits<26> imm26;

let Inst{47-32} = imm26{25-10};
let Inst{31-30} = func2;
let Inst{29-25} = imm26{9-5};
let Inst{24-20} = rs2;
let Inst{19-15} = rs1;
let Inst{14-12} = func3;
let Inst{11-7} = imm26{4-0};
let Inst{6-0} = opcode;

let AsmString = ".insn qc.es " # argstr;
}


let isCodeGenOnly = true, hasSideEffects = true, mayLoad = true,
mayStore = true, hasNoSchedulingInfo = true, Predicates=[IsRV32] in {
def InsnQC_EAI : DirectiveInsnQC_EAI<(outs AnyReg:$rd),
(ins uimm7_opcode:$opcode,
uimm3:$func3,
uimm1:$func1,
simm32:$imm32),
"$opcode, $func3, $func1, $rd, $imm32">;
def InsnQC_EI : DirectiveInsnQC_EI<(outs AnyReg:$rd),
(ins uimm7_opcode:$opcode,
uimm3:$func3,
uimm2:$func2,
AnyReg:$rs1,
simm26:$imm26),
"$opcode, $func3, $func2, $rd, $rs1, $imm26">;
def InsnQC_EI_Mem : DirectiveInsnQC_EI<(outs AnyReg:$rd),
(ins uimm7_opcode:$opcode,
uimm3:$func3,
uimm2:$func2,
AnyReg:$rs1,
simm26:$imm26),
"$opcode, $func3, $func2, $rd, ${imm26}(${rs1})">;
def InsnQC_EB : DirectiveInsnQC_EB<(outs),
(ins uimm7_opcode:$opcode,
uimm3:$func3,
uimm5:$func5,
AnyReg:$rs1,
simm16:$imm16,
bare_simm13_lsb0:$imm12),
"$opcode, $func3, $func5, $rs1, $imm16, $imm12">;
def InsnQC_EJ : DirectiveInsnQC_EJ<(outs),
(ins uimm7_opcode:$opcode,
uimm3:$func3,
uimm2:$func2,
uimm5:$func5,
simm32_lsb0:$imm31),
"$opcode, $func3, $func2, $func5, $imm31">;
def InsnQC_ES : DirectiveInsnQC_ES<(outs),
(ins uimm7_opcode:$opcode,
uimm3:$func3,
uimm2:$func2,
AnyReg:$rs2,
AnyReg:$rs1,
simm26:$imm26),
"$opcode, $func3, $func2, $rs2, ${imm26}(${rs1})">;
} // isCodeGenOnly, hasSideEffects, mayLoad, mayStore, hasNoSchedulingInfo, Predicates

let EmitPriority = 0, Predicates = [IsRV32] in {
def : InstAlias<".insn_qc.eai $opcode, $func3, $func1, $rd, $imm32",
(InsnQC_EAI AnyReg:$rd,
uimm7_opcode:$opcode,
uimm3:$func3,
uimm1:$func1,
simm32:$imm32)>;
def : InstAlias<".insn_qc.ei $opcode, $func3, $func2, $rd, $rs1, $imm26",
(InsnQC_EI AnyReg:$rd,
uimm7_opcode:$opcode,
uimm3:$func3,
uimm2:$func2,
AnyReg:$rs1,
simm26:$imm26)>;
def : InstAlias<".insn_qc.ei $opcode, $func3, $func2, $rd, ${imm26}(${rs1})",
(InsnQC_EI_Mem AnyReg:$rd,
uimm7_opcode:$opcode,
uimm3:$func3,
uimm2:$func2,
AnyReg:$rs1,
simm26:$imm26)>;
def : InstAlias<".insn_qc.ei $opcode, $func3, $func2, $rd, (${rs1})",
(InsnQC_EI_Mem AnyReg:$rd,
uimm7_opcode:$opcode,
uimm3:$func3,
uimm2:$func2,
AnyReg:$rs1,
0)>;
def : InstAlias<".insn_qc.eb $opcode, $func3, $func5, $rs1, $imm16, $imm12",
(InsnQC_EB uimm7_opcode:$opcode,
uimm3:$func3,
uimm5:$func5,
AnyReg:$rs1,
simm16:$imm16,
bare_simm13_lsb0:$imm12)>;
def : InstAlias<".insn_qc.ej $opcode, $func3, $func2, $func5, $imm31",
(InsnQC_EJ uimm7_opcode:$opcode,
uimm3:$func3,
uimm2:$func2,
uimm5:$func5,
simm32_lsb0:$imm31)>;
def : InstAlias<".insn_qc.es $opcode, $func3, $func2, $rs2, ${imm26}(${rs1})",
(InsnQC_ES uimm7_opcode:$opcode,
uimm3:$func3,
uimm2:$func2,
AnyReg:$rs2,
AnyReg:$rs1,
simm26:$imm26)>;
def : InstAlias<".insn_qc.es $opcode, $func3, $func2, $rs2, (${rs1})",
(InsnQC_ES uimm7_opcode:$opcode,
uimm3:$func3,
uimm2:$func2,
AnyReg:$rs2,
AnyReg:$rs1,
0)>;
} // EmitPriority = 0, Predicates = [IsRV32]

//===----------------------------------------------------------------------===//
// Instruction Class Templates
//===----------------------------------------------------------------------===//
Expand Down
Loading