-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[RISCV] Add Xqci Insn Formats #132986
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RISCV] Add Xqci Insn Formats #132986
Conversation
This adds the following instruction formats from the Xqci Spec: - QC.EAI - QC.EI - QC.EB - QC.EJ - QC.ES The update to the THead test is because the largest number of operands for a valid instruction has been bumped by this change.
@llvm/pr-subscribers-backend-risc-v @llvm/pr-subscribers-mc Author: Sam Elliott (lenary) ChangesThis adds the following instruction formats from the Xqci Spec:
The update to the THead test is because the largest number of operands for a valid instruction has been bumped by this change. Patch is 23.38 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/132986.diff 9 Files Affected:
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 05997cf78c6b1..c7c42c9a45f13 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -1042,6 +1042,17 @@ struct RISCVOperand final : public MCParsedAsmOperand {
VK == RISCVMCExpr::VK_None;
}
+ bool isSImm16() const {
+ if (!isImm())
+ return false;
+ RISCVMCExpr::Specifier VK = RISCVMCExpr::VK_None;
+ int64_t Imm;
+ bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
+ return IsConstantImm &&
+ isInt<16>(fixImmediateForRV32(Imm, isRV64Imm())) &&
+ VK == RISCVMCExpr::VK_None;
+ }
+
bool isSImm16NonZero() const {
if (!isImm())
return false;
@@ -1760,6 +1771,8 @@ 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,
@@ -3347,10 +3360,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);
}
@@ -3440,7 +3456,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();
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index db305b0083415..dc766a697db22 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -51,7 +51,12 @@ enum {
InstFormatCLH = 19,
InstFormatCSB = 20,
InstFormatCSH = 21,
- InstFormatOther = 22,
+ InstFormatQCEAI = 22,
+ InstFormatQCEI = 23,
+ InstFormatQCEB = 24,
+ InstFormatQCEJ = 25,
+ InstFormatQCES = 26,
+ InstFormatOther = 31,
InstFormatMask = 31,
InstFormatShift = 0,
@@ -332,6 +337,7 @@ enum OperandType : unsigned {
OPERAND_SIMM11,
OPERAND_SIMM12,
OPERAND_SIMM12_LSB00000,
+ OPERAND_SIMM16,
OPERAND_SIMM16_NONZERO,
OPERAND_SIMM20,
OPERAND_SIMM26,
diff --git a/llvm/lib/Target/RISCV/RISCVInstrFormats.td b/llvm/lib/Target/RISCV/RISCVInstrFormats.td
index d95e806b79f25..0bb0ba57ff50d 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrFormats.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrFormats.td
@@ -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;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index 7d650fea97c8b..7063513cbfcc8 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -1142,6 +1142,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 {
@@ -1177,23 +1204,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
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td
index 375fe640c6c3d..72311675aeaf0 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td
@@ -799,12 +799,6 @@ def InsnCJ : DirectiveInsnCJ<(outs), (ins uimm2_opcode:$opcode,
uimm3:$funct3,
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
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 69290c0da1824..143a85e39a628 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -85,6 +85,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">;
@@ -130,6 +132,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,
+ 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,
+ 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
//===----------------------------------------------------------------------===//
diff --git a/llvm/test/MC/RISCV/insn_xqci-invalid.s b/llvm/test/MC/RISCV/insn_xqci-invalid.s
new file mode 100644
index 0000000000000..8177adaf8ac50
--- /dev/null
+++ b/llvm/test/MC/RISCV/insn_xqci-invalid.s
@@ -0,0 +1,111 @@
+# RUN: not llvm-mc %s -triple=riscv32 -M no-aliases -show-encoding \
+# RUN: 2>&1 | FileCheck -check-prefixes=CHECK-ERR %s
+
+.insn qc.eai 128, 0, 0, x0, 0
+# CHECK-ERR: [[@LINE-1]]:14: error: opcode must be a valid opcode name or an immediate in the range [0, 127]
+
+.insn qc.eai 127, 8, 0, x0, 0
+# CHECK-ERR: [[@LINE-1]]:19: error: immediate must be an integer in the range [0, 7]
+
+.insn qc.eai 127, 7, 2, x0, 0
+# CHECK-ERR: [[@LINE-1]]:22: error: immediate must be an integer in the range [0, 1]
+
+.insn qc.eai 127, 7, 1, not_a_reg, 0
+# CHECK-ERR: [[@LINE-1]]:25: error: invalid operand for instruction
+
+.insn qc.eai 127, 7, 1, x31, 0x100000000
+# CHECK-ERR: [[@LINE-1]]:30: error: immediate must be an integer in the range [-2147483648, 4294967295]
+
+.insn qc.eai 126, 7, 1, x31, 0xFFFFFFFF, extra
+# CHECK-ERR: [[@LINE-1]]:42: error: invalid operand for instruction
+
+.insn qc.ei 128, 0, 0, x31, x0, 0
+# CHECK-ERR: [[@LINE-1]]:13: error: opcode must be a valid opcode name or an immediate in the range [0, 127]
+
+.insn qc.ei 127, 8, 0, x0, x0, 0
+# CHECK-ERR: [[@LINE-1]]:18: error: immediate must be an integer in the range [0, 7]
+
+.insn qc.ei 127, 7, 4, x0, x0, 0
+# CHECK-ERR: [[@LINE-1]]:21: error: immediate must be an integer in the range [0, 3]
+
+.insn qc.ei 127, 7, 3, not_a_reg, x0, 0
+# CHECK-ERR: [[@LINE-1]]:24: error: invalid operand for instruction
+
+.insn qc.ei 127, 7, 3, x31, not_a_reg, 0
+# CHECK-ERR: [[@LINE-1]]:29: error: immediate must be an integer in the range [-33554432, 33554431]
+
+.insn qc.ei 127, 7, 3, x31, x31, 0x2000000
+# CHECK-ERR: [[@LINE-1]]:34: error: immediate must be an integer in the range [-33554432, 33554431]
+
+.insn qc.ei 127, 7, 3, x31, x31, 0x1000000, extra
+# CHECK-ERR: [[@LINE-1]]:45: error: invalid operand for instruction
+
+.insn qc.ei 126, 7, 3, x31, 0x2000000(x0)
+# CHECK-ERR: [[@LINE-1]]:29: error: immediate must be an integer in the range [-33554432, 33554431]
+
+.insn qc.ei 126, 7, 3, x31, 0x1000000(not_a_reg)
+# CHECK-ERR: [[@LINE-1]]:39: error: expected register
+
+.insn qc.ei 126, 7, 3, x31, 0x1000000(x31), extra
+# CHECK-ERR: [[@LINE-1]]:45: error: invalid operand for instruction
+
+.insn qc.eb 128, 0, 0, x0, 0, 0
+# CHECK-ERR: [[@LINE-1]]:13: error: opcode must be a valid opcode name or an immediate in the range [0, 127]
+
+.insn qc.eb 127, 8, 0, x0, 0, 0
+# CHECK-ERR: [[@LINE-1]]:18: error: immediate must be an integer in the range [0, 7]
+
+.insn qc.eb 127, 7, 32, x0, 0, 0
+# CHECK-ERR: [[@LINE-1]]:21: error: immediate must be an integer in the range [0, 31]
+
+.insn qc.eb 127, 7, 31, not_a_reg, 0, 0
+# CHECK-ERR: [[@LINE-1]]:25: error: invalid operand for instruction
+
+.insn qc.eb 127, 7, 31, x31, 0x8000, 0
+# CHECK-ERR: [[@LINE-1]]:30: error: immediate must be an integer in the range [-32768, 32767]
+
+.insn qc.eb 127, 7, 31, x31, 0x4000, 0x1000
+# CHECK-ERR: [[@LINE-1]]:38: error: immediate must be a multiple of 2 bytes in the range [-4096, 4094]
+
+.insn qc.eb 127, 7, 31, x31, 0x4000, 0x800, extra
+# CHECK-ERR: [[@LINE-1]]:45: error: invalid operand for instruction
+
+
+.insn qc.ej 128, 0, 0, 0, 0
+# CHECK-ERR: [[@LINE-1]]:13: error: opcode must be a valid opcode name or an immediate in the range [0, 127]
+
+.insn qc.ej 127, 8, 0, 0, 0
+# CHECK-ERR: [[@LINE-1]]:18: error: immediate must be an integer in the range [0, 7]
+
+.insn qc.ej 127, 7, 4, 0, 0
+# CHECK-ERR: [[@LINE-1]]:21: error: immediate must be an integer in the range [0, 3]
+
+.insn qc.ej 127, 7, 3, 32, 0
+# CHECK-ERR: [[@LINE-1]]:24: error: immediate must be an integer in the range [0, 31]
+
+.insn qc.ej 127, 7, 3, 31, 0x100000000
+# CHECK-ERR: [[@LINE-1]]:28: error: operand must be a multiple of 2 bytes in the range [-2147483648, 2147483646]
+
+.insn qc.ej 127, 7, 3, 31, 0x80000000, extra
+# CHECK-ERR: [[@LINE-1]]:40: error: invalid operand for instruction
+
+.insn qc.es 128, 0, 0, x0, 0(x0)
+# CHECK-ERR: [[@LINE-1]]:13: error: opcode must be a valid opcode name or an immediate in the range [0, 127]
+
+.insn qc.es 127, 8, 0, x0, 0(x0)
+# CHECK-ERR: [[@LI...
[truncated]
|
def Insn16 : RVInst16<(outs), (ins uimm16:$value), "", "", [], InstFormatOther> { | ||
bits<16> value; | ||
|
||
let Inst{15-0} = value; | ||
let AsmString = ".insn 0x2, $value"; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was under a predicate, which I wasn't sure was right, so I moved it, with the others, into their own unpredicated block, separate from the .insn_<format>
instructions/aliases.
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
bits<12> imm12; // This one is the PC-relative offset | ||
bits<16> imm16; | ||
|
||
let Inst{47-32} = imm16; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The qc.e. instructions all take a non zero imm16. While some take a simm16 there are two that take a uimm16 (qc.e.bgeui/qc.e.bltui). We will not be able to accommodate all valid values for them in simm16.
Also would the .insn for these instructions error out if the comparison is against 0? I took a look and could not find a test for it. Could you point me to it or add one please?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The intention not to honour the "nonzero" bit of the 16-bit immediate is on purpose - the formats don't put these restrictions in, only individual instructions do.
As for the uimm16/simm16 difference, I'm not sure how to deal with this, but I want to punt on it, as users should be able to convert any unsigned immediates to the equivalent signed 16-bit immediate in their own assembly code, which would be accepted, and would give the expected bit pattern.
This is broadly a limitation of the instruction format idea in practice, especially when architects think of the fields as "just N bits" and push the sign/zero extension into the operation of different instructions.
def InstFormatQC_EI : InstFormat<23>; | ||
def InstFormatQC_EB : InstFormat<24>; | ||
def InstFormatQC_EJ : InstFormat<25>; | ||
def InstFormatQC_ES : InstFormat<26>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a mismatch between the naming here and in RISCVBaseInfo above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/10/builds/2653 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/153/builds/27590 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/203/builds/6431 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/204/builds/5244 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/33/builds/14176 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/144/builds/21783 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/137/builds/16234 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/205/builds/5222 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/157/builds/24145 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/129/builds/18054 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/185/builds/15996 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/175/builds/16108 Here is the relevant piece of the build log for the reference
|
This reverts commit 0cfabd3. Multiple builtbot failures have been reported: llvm/llvm-project#132986
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/60/builds/23647 Here is the relevant piece of the build log for the reference
|
This reverts commit 0cfabd3. Multiple builtbot failures have been reported: llvm#132986
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/92/builds/16467 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/2/builds/20695 Here is the relevant piece of the build log for the reference
|
This adds the following instruction formats from the Xqci Spec:
The update to the THead test is because the largest number of operands for a valid instruction has been bumped by this change.