Skip to content

Commit 0cfabd3

Browse files
authored
[RISCV] Add Xqci Insn Formats (#132986)
1 parent d40bab3 commit 0cfabd3

File tree

9 files changed

+429
-29
lines changed

9 files changed

+429
-29
lines changed

llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,16 @@ struct RISCVOperand final : public MCParsedAsmOperand {
867867
[](int64_t Imm) { return Imm != 0 && isShiftedInt<6, 4>(Imm); });
868868
}
869869

870+
bool isSImm16() const {
871+
if (!isImm())
872+
return false;
873+
RISCVMCExpr::Specifier VK = RISCVMCExpr::VK_None;
874+
int64_t Imm;
875+
bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
876+
return IsConstantImm && isInt<16>(fixImmediateForRV32(Imm, isRV64Imm())) &&
877+
VK == RISCVMCExpr::VK_None;
878+
}
879+
870880
bool isSImm16NonZero() const {
871881
return isSImmPred([](int64_t Imm) { return Imm != 0 && isInt<16>(Imm); });
872882
}
@@ -1511,6 +1521,9 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
15111521
return generateImmOutOfRangeError(
15121522
Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2,
15131523
"immediate must be a multiple of 2 bytes in the range");
1524+
case Match_InvalidSImm16:
1525+
return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 15),
1526+
(1 << 15) - 1);
15141527
case Match_InvalidSImm16NonZero:
15151528
return generateImmOutOfRangeError(
15161529
Operands, ErrorInfo, -(1 << 15), (1 << 15) - 1,
@@ -3150,10 +3163,13 @@ bool RISCVAsmParser::parseDirectiveAttribute() {
31503163
return false;
31513164
}
31523165

3153-
bool isValidInsnFormat(StringRef Format, bool AllowC) {
3166+
bool isValidInsnFormat(StringRef Format, const MCSubtargetInfo &STI) {
31543167
return StringSwitch<bool>(Format)
31553168
.Cases("r", "r4", "i", "b", "sb", "u", "j", "uj", "s", true)
3156-
.Cases("cr", "ci", "ciw", "css", "cl", "cs", "ca", "cb", "cj", AllowC)
3169+
.Cases("cr", "ci", "ciw", "css", "cl", "cs", "ca", "cb", "cj",
3170+
STI.hasFeature(RISCV::FeatureStdExtZca))
3171+
.Cases("qc.eai", "qc.ei", "qc.eb", "qc.ej", "qc.es",
3172+
!STI.hasFeature(RISCV::Feature64Bit))
31573173
.Default(false);
31583174
}
31593175

@@ -3243,7 +3259,7 @@ bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) {
32433259
return false;
32443260
}
32453261

3246-
if (!isValidInsnFormat(Format, AllowC))
3262+
if (!isValidInsnFormat(Format, getSTI()))
32473263
return Error(ErrorLoc, "invalid instruction format");
32483264

32493265
std::string FormatName = (".insn_" + Format).str();

llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,12 @@ enum {
5151
InstFormatCLH = 19,
5252
InstFormatCSB = 20,
5353
InstFormatCSH = 21,
54-
InstFormatOther = 22,
54+
InstFormatQC_EAI = 22,
55+
InstFormatQC_EI = 23,
56+
InstFormatQC_EB = 24,
57+
InstFormatQC_EJ = 25,
58+
InstFormatQC_ES = 26,
59+
InstFormatOther = 31,
5560

5661
InstFormatMask = 31,
5762
InstFormatShift = 0,
@@ -333,6 +338,7 @@ enum OperandType : unsigned {
333338
OPERAND_SIMM11,
334339
OPERAND_SIMM12,
335340
OPERAND_SIMM12_LSB00000,
341+
OPERAND_SIMM16,
336342
OPERAND_SIMM16_NONZERO,
337343
OPERAND_SIMM20,
338344
OPERAND_SIMM26,

llvm/lib/Target/RISCV/RISCVInstrFormats.td

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,13 @@ def InstFormatCLB : InstFormat<18>;
5252
def InstFormatCLH : InstFormat<19>;
5353
def InstFormatCSB : InstFormat<20>;
5454
def InstFormatCSH : InstFormat<21>;
55-
def InstFormatOther : InstFormat<22>;
55+
def InstFormatQC_EAI : InstFormat<22>;
56+
def InstFormatQC_EI : InstFormat<23>;
57+
def InstFormatQC_EB : InstFormat<24>;
58+
def InstFormatQC_EJ : InstFormat<25>;
59+
def InstFormatQC_ES : InstFormat<26>;
60+
def InstFormatOther : InstFormat<31>;
61+
5662

5763
class RISCVVConstraint<bits<3> val> {
5864
bits<3> Value = val;

llvm/lib/Target/RISCV/RISCVInstrInfo.td

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,6 +1144,33 @@ def AnyReg : Operand<XLenVT> {
11441144
let ParserMatchClass = AnyRegOperand;
11451145
}
11461146

1147+
// isCodeGenOnly = 1 to hide them from the tablegened assembly parser.
1148+
let isCodeGenOnly = 1, hasSideEffects = 1, mayLoad = 1, mayStore = 1,
1149+
hasNoSchedulingInfo = 1 in {
1150+
def Insn16 : RVInst16<(outs), (ins uimm16:$value), "", "", [], InstFormatOther> {
1151+
bits<16> value;
1152+
1153+
let Inst{15-0} = value;
1154+
let AsmString = ".insn 0x2, $value";
1155+
}
1156+
def Insn32 : RVInst<(outs), (ins uimm32:$value), "", "", [], InstFormatOther> {
1157+
bits<32> value;
1158+
1159+
let Inst{31-0} = value;
1160+
let AsmString = ".insn 0x4, $value";
1161+
}
1162+
def Insn48 : RVInst48<(outs), (ins uimm48:$value), "", "", [], InstFormatOther> {
1163+
bits<48> value;
1164+
let Inst{47-0} = value;
1165+
let AsmString = ".insn 0x6, $value";
1166+
}
1167+
def Insn64 : RVInst64<(outs), (ins uimm64:$value), "", "", [], InstFormatOther> {
1168+
bits<64> value;
1169+
let Inst{63-0} = value;
1170+
let AsmString = ".insn 0x8, $value";
1171+
}
1172+
} // isCodeGenOnly, hasSideEffects, mayLoad, mayStore, hasNoSchedulingInfo
1173+
11471174
// isCodeGenOnly = 1 to hide them from the tablegened assembly parser.
11481175
let isCodeGenOnly = 1, hasSideEffects = 1, mayLoad = 1, mayStore = 1,
11491176
hasNoSchedulingInfo = 1 in {
@@ -1179,23 +1206,7 @@ def InsnS : DirectiveInsnS<(outs), (ins uimm7_opcode:$opcode, uimm3:$funct3,
11791206
AnyReg:$rs2, AnyReg:$rs1,
11801207
simm12:$imm12),
11811208
"$opcode, $funct3, $rs2, ${imm12}(${rs1})">;
1182-
def Insn32 : RVInst<(outs), (ins uimm32:$value), "", "", [], InstFormatOther> {
1183-
bits<32> value;
1184-
1185-
let Inst{31-0} = value;
1186-
let AsmString = ".insn 0x4, $value";
1187-
}
1188-
def Insn48 : RVInst48<(outs), (ins uimm48:$value), "", "", [], InstFormatOther> {
1189-
bits<48> value;
1190-
let Inst{47-0} = value;
1191-
let AsmString = ".insn 0x6, $value";
1192-
}
1193-
def Insn64 : RVInst64<(outs), (ins uimm64:$value), "", "", [], InstFormatOther> {
1194-
bits<64> value;
1195-
let Inst{63-0} = value;
1196-
let AsmString = ".insn 0x8, $value";
1197-
}
1198-
}
1209+
} // isCodeGenOnly, hasSideEffects, mayLoad, mayStore, hasNoSchedulingInfo
11991210

12001211
// Use InstAliases to match these so that we can combine the insn and format
12011212
// into a mnemonic to use as the key for the tablegened asm matcher table. The

llvm/lib/Target/RISCV/RISCVInstrInfoC.td

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -799,12 +799,6 @@ def InsnCJ : DirectiveInsnCJ<(outs), (ins uimm2_opcode:$opcode,
799799
uimm3:$funct3,
800800
bare_simm12_lsb0:$imm11),
801801
"$opcode, $funct3, $imm11">;
802-
def Insn16 : RVInst16<(outs), (ins uimm16:$value), "", "", [], InstFormatOther> {
803-
bits<16> value;
804-
805-
let Inst{15-0} = value;
806-
let AsmString = ".insn 0x2, $value";
807-
}
808802
}
809803

810804
// Use InstAliases to match these so that we can combine the insn and format

llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ def simm5nonzero : RISCVOp<XLenVT>,
9494

9595
def simm11 : RISCVSImmLeafOp<11>;
9696

97+
def simm16 : RISCVSImmOp<16>;
98+
9799
def simm16nonzero : RISCVOp<XLenVT>,
98100
ImmLeaf<XLenVT, [{return (Imm != 0) && isInt<16>(Imm);}]> {
99101
let ParserMatchClass = SImmAsmOperand<16, "NonZero">;
@@ -139,6 +141,219 @@ def simm32_lsb0 : Operand<OtherVT> {
139141
// Instruction Formats
140142
//===----------------------------------------------------------------------===//
141143

144+
145+
class DirectiveInsnQC_EAI<dag outs, dag ins, string argstr>
146+
: RVInst48<outs, ins, "", "", [], InstFormatQC_EAI> {
147+
bits<7> opcode;
148+
bits<3> func3;
149+
bits<1> func1;
150+
151+
bits<5> rd;
152+
bits<32> imm32;
153+
154+
let Inst{47-16} = imm32;
155+
let Inst{15} = func1;
156+
let Inst{14-12} = func3;
157+
let Inst{11-7} = rd;
158+
let Inst{6-0} = opcode;
159+
160+
let AsmString = ".insn qc.eai " # argstr;
161+
}
162+
163+
class DirectiveInsnQC_EI<dag outs, dag ins, string argstr>
164+
: RVInst48<outs, ins, "", "", [], InstFormatQC_EI> {
165+
bits<7> opcode;
166+
bits<3> func3;
167+
bits<2> func2;
168+
169+
bits<5> rd;
170+
bits<5> rs1;
171+
bits<26> imm26;
172+
173+
let Inst{47-32} = imm26{25-10};
174+
let Inst{31-30} = func2;
175+
let Inst{29-20} = imm26{9-0};
176+
let Inst{19-15} = rs1;
177+
let Inst{14-12} = func3;
178+
let Inst{11-7} = rd;
179+
let Inst{6-0} = opcode;
180+
181+
let AsmString = ".insn qc.ei " # argstr;
182+
}
183+
184+
class DirectiveInsnQC_EB<dag outs, dag ins, string argstr>
185+
: RVInst48<outs, ins, "", "", [], InstFormatQC_EB> {
186+
bits<7> opcode;
187+
bits<3> func3;
188+
bits<5> func5;
189+
190+
bits<5> rs1;
191+
bits<12> imm12; // This one is the PC-relative offset
192+
bits<16> imm16;
193+
194+
let Inst{47-32} = imm16;
195+
let Inst{31} = imm12{11};
196+
let Inst{30-25} = imm12{9-4};
197+
let Inst{24-20} = func5;
198+
let Inst{19-15} = rs1;
199+
let Inst{14-12} = func3;
200+
let Inst{11-8} = imm12{3-0};
201+
let Inst{7} = imm12{10};
202+
let Inst{6-0} = opcode;
203+
204+
let AsmString = ".insn qc.eb " # argstr;
205+
}
206+
207+
class DirectiveInsnQC_EJ<dag outs, dag ins, string argstr>
208+
: RVInst48<outs, ins, "", "", [], InstFormatQC_EJ> {
209+
bits<7> opcode;
210+
bits<3> func3;
211+
bits<2> func2;
212+
bits<5> func5;
213+
214+
bits<31> imm31;
215+
216+
let Inst{47-32} = imm31{30-15};
217+
let Inst{31} = imm31{11};
218+
let Inst{30-25} = imm31{9-4};
219+
let Inst{24-20} = func5;
220+
let Inst{19-17} = imm31{14-12};
221+
let Inst{16-15} = func2;
222+
let Inst{14-12} = func3;
223+
let Inst{11-8} = imm31{3-0};
224+
let Inst{7} = imm31{10};
225+
let Inst{6-0} = opcode;
226+
227+
let AsmString = ".insn qc.ej " # argstr;
228+
}
229+
230+
class DirectiveInsnQC_ES<dag outs, dag ins, string argstr>
231+
: RVInst48<outs, ins, "", "", [], InstFormatQC_ES> {
232+
bits<7> opcode;
233+
bits<3> func3;
234+
bits<2> func2;
235+
236+
bits<5> rs1;
237+
bits<5> rs2;
238+
bits<26> imm26;
239+
240+
let Inst{47-32} = imm26{25-10};
241+
let Inst{31-30} = func2;
242+
let Inst{29-25} = imm26{9-5};
243+
let Inst{24-20} = rs2;
244+
let Inst{19-15} = rs1;
245+
let Inst{14-12} = func3;
246+
let Inst{11-7} = imm26{4-0};
247+
let Inst{6-0} = opcode;
248+
249+
let AsmString = ".insn qc.es " # argstr;
250+
}
251+
252+
253+
let isCodeGenOnly = true, hasSideEffects = true, mayLoad = true,
254+
mayStore = true, hasNoSchedulingInfo = true, Predicates=[IsRV32] in {
255+
def InsnQC_EAI : DirectiveInsnQC_EAI<(outs AnyReg:$rd),
256+
(ins uimm7_opcode:$opcode,
257+
uimm3:$func3,
258+
uimm1:$func1,
259+
simm32:$imm32),
260+
"$opcode, $func3, $func1, $rd, $imm32">;
261+
def InsnQC_EI : DirectiveInsnQC_EI<(outs AnyReg:$rd),
262+
(ins uimm7_opcode:$opcode,
263+
uimm3:$func3,
264+
uimm2:$func2,
265+
AnyReg:$rs1,
266+
simm26:$imm26),
267+
"$opcode, $func3, $func2, $rd, $rs1, $imm26">;
268+
def InsnQC_EI_Mem : DirectiveInsnQC_EI<(outs AnyReg:$rd),
269+
(ins uimm7_opcode:$opcode,
270+
uimm3:$func3,
271+
uimm2:$func2,
272+
AnyReg:$rs1,
273+
simm26:$imm26),
274+
"$opcode, $func3, $func2, $rd, ${imm26}(${rs1})">;
275+
def InsnQC_EB : DirectiveInsnQC_EB<(outs),
276+
(ins uimm7_opcode:$opcode,
277+
uimm3:$func3,
278+
uimm5:$func5,
279+
AnyReg:$rs1,
280+
simm16:$imm16,
281+
simm13_lsb0:$imm12),
282+
"$opcode, $func3, $func5, $rs1, $imm16, $imm12">;
283+
def InsnQC_EJ : DirectiveInsnQC_EJ<(outs),
284+
(ins uimm7_opcode:$opcode,
285+
uimm3:$func3,
286+
uimm2:$func2,
287+
uimm5:$func5,
288+
simm32_lsb0:$imm31),
289+
"$opcode, $func3, $func2, $func5, $imm31">;
290+
def InsnQC_ES : DirectiveInsnQC_ES<(outs),
291+
(ins uimm7_opcode:$opcode,
292+
uimm3:$func3,
293+
uimm2:$func2,
294+
AnyReg:$rs2,
295+
AnyReg:$rs1,
296+
simm26:$imm26),
297+
"$opcode, $func3, $func2, $rs2, ${imm26}(${rs1})">;
298+
} // isCodeGenOnly, hasSideEffects, mayLoad, mayStore, hasNoSchedulingInfo, Predicates
299+
300+
let EmitPriority = 0, Predicates = [IsRV32] in {
301+
def : InstAlias<".insn_qc.eai $opcode, $func3, $func1, $rd, $imm32",
302+
(InsnQC_EAI AnyReg:$rd,
303+
uimm7_opcode:$opcode,
304+
uimm3:$func3,
305+
uimm1:$func1,
306+
simm32:$imm32)>;
307+
def : InstAlias<".insn_qc.ei $opcode, $func3, $func2, $rd, $rs1, $imm26",
308+
(InsnQC_EI AnyReg:$rd,
309+
uimm7_opcode:$opcode,
310+
uimm3:$func3,
311+
uimm2:$func2,
312+
AnyReg:$rs1,
313+
simm26:$imm26)>;
314+
def : InstAlias<".insn_qc.ei $opcode, $func3, $func2, $rd, ${imm26}(${rs1})",
315+
(InsnQC_EI_Mem AnyReg:$rd,
316+
uimm7_opcode:$opcode,
317+
uimm3:$func3,
318+
uimm2:$func2,
319+
AnyReg:$rs1,
320+
simm26:$imm26)>;
321+
def : InstAlias<".insn_qc.ei $opcode, $func3, $func2, $rd, (${rs1})",
322+
(InsnQC_EI_Mem AnyReg:$rd,
323+
uimm7_opcode:$opcode,
324+
uimm3:$func3,
325+
uimm2:$func2,
326+
AnyReg:$rs1,
327+
0)>;
328+
def : InstAlias<".insn_qc.eb $opcode, $func3, $func5, $rs1, $imm16, $imm12",
329+
(InsnQC_EB uimm7_opcode:$opcode,
330+
uimm3:$func3,
331+
uimm5:$func5,
332+
AnyReg:$rs1,
333+
simm16:$imm16,
334+
simm13_lsb0:$imm12)>;
335+
def : InstAlias<".insn_qc.ej $opcode, $func3, $func2, $func5, $imm31",
336+
(InsnQC_EJ uimm7_opcode:$opcode,
337+
uimm3:$func3,
338+
uimm2:$func2,
339+
uimm5:$func5,
340+
simm32_lsb0:$imm31)>;
341+
def : InstAlias<".insn_qc.es $opcode, $func3, $func2, $rs2, ${imm26}(${rs1})",
342+
(InsnQC_ES uimm7_opcode:$opcode,
343+
uimm3:$func3,
344+
uimm2:$func2,
345+
AnyReg:$rs2,
346+
AnyReg:$rs1,
347+
simm26:$imm26)>;
348+
def : InstAlias<".insn_qc.es $opcode, $func3, $func2, $rs2, (${rs1})",
349+
(InsnQC_ES uimm7_opcode:$opcode,
350+
uimm3:$func3,
351+
uimm2:$func2,
352+
AnyReg:$rs2,
353+
AnyReg:$rs1,
354+
0)>;
355+
} // EmitPriority = 0, Predicates = [IsRV32]
356+
142357
//===----------------------------------------------------------------------===//
143358
// Instruction Class Templates
144359
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)