Skip to content

Commit 23324b8

Browse files
authored
[RISCV] Move checking for constant 3/4 for XTHeadMemPair to the instruction matching stage. (#136165)
This removes a special case from processInstruction and removes an untested range diagnostic we would print if the constant didn't fit in 3 bits.
1 parent c134e99 commit 23324b8

File tree

5 files changed

+51
-24
lines changed

5 files changed

+51
-24
lines changed

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

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -932,6 +932,14 @@ struct RISCVOperand final : public MCParsedAsmOperand {
932932
return isUImmPred([](int64_t Imm) { return 0 == Imm; });
933933
}
934934

935+
bool isImmThree() const {
936+
return isUImmPred([](int64_t Imm) { return 3 == Imm; });
937+
}
938+
939+
bool isImmFour() const {
940+
return isUImmPred([](int64_t Imm) { return 4 == Imm; });
941+
}
942+
935943
bool isSImm5Plus1() const {
936944
return isSImmPred(
937945
[](int64_t Imm) { return Imm != INT64_MIN && isInt<5>(Imm - 1); });
@@ -3663,19 +3671,6 @@ bool RISCVAsmParser::validateInstruction(MCInst &Inst,
36633671
}
36643672
}
36653673

3666-
bool IsTHeadMemPair32 = (Opcode == RISCV::TH_LWD ||
3667-
Opcode == RISCV::TH_LWUD || Opcode == RISCV::TH_SWD);
3668-
bool IsTHeadMemPair64 = (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_SDD);
3669-
// The last operand of XTHeadMemPair instructions must be constant 3 or 4
3670-
// depending on the data width.
3671-
if (IsTHeadMemPair32 && Inst.getOperand(4).getImm() != 3) {
3672-
SMLoc Loc = Operands.back()->getStartLoc();
3673-
return Error(Loc, "operand must be constant 3");
3674-
} else if (IsTHeadMemPair64 && Inst.getOperand(4).getImm() != 4) {
3675-
SMLoc Loc = Operands.back()->getStartLoc();
3676-
return Error(Loc, "operand must be constant 4");
3677-
}
3678-
36793674
const MCInstrDesc &MCID = MII.get(Opcode);
36803675
if (!(MCID.TSFlags & RISCVII::ConstraintMask))
36813676
return false;

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,8 @@ enum OperandType : unsigned {
329329
OPERAND_UIMM48,
330330
OPERAND_UIMM64,
331331
OPERAND_ZERO,
332+
OPERAND_THREE,
333+
OPERAND_FOUR,
332334
OPERAND_SIMM5,
333335
OPERAND_SIMM5_NONZERO,
334336
OPERAND_SIMM5_PLUS1,

llvm/lib/Target/RISCV/RISCVInstrInfo.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2645,6 +2645,12 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
26452645
case RISCVOp::OPERAND_ZERO:
26462646
Ok = Imm == 0;
26472647
break;
2648+
case RISCVOp::OPERAND_THREE:
2649+
Ok = Imm == 3;
2650+
break;
2651+
case RISCVOp::OPERAND_FOUR:
2652+
Ok = Imm == 4;
2653+
break;
26482654
// clang-format off
26492655
CASE_OPERAND_SIMM(5)
26502656
CASE_OPERAND_SIMM(6)

llvm/lib/Target/RISCV/RISCVInstrInfoXTHead.td

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,30 @@ def th_swd : SDNode<"RISCVISD::TH_SWD", SDT_StorePair,
3434
def th_sdd : SDNode<"RISCVISD::TH_SDD", SDT_StorePair,
3535
[SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
3636

37+
def ImmThreeAsmOperand : AsmOperandClass {
38+
let Name = "ImmThree";
39+
let RenderMethod = "addImmOperands";
40+
let DiagnosticType = !strconcat("Invalid", Name);
41+
let DiagnosticString = "operand must be constant 3";
42+
}
43+
44+
def immthree : RISCVOp {
45+
let ParserMatchClass = ImmThreeAsmOperand;
46+
let OperandType = "OPERAND_THREE";
47+
}
48+
49+
def ImmFourAsmOperand : AsmOperandClass {
50+
let Name = "ImmFour";
51+
let RenderMethod = "addImmOperands";
52+
let DiagnosticType = !strconcat("Invalid", Name);
53+
let DiagnosticString = "operand must be constant 4";
54+
}
55+
56+
def immfour : RISCVOp {
57+
let ParserMatchClass = ImmFourAsmOperand;
58+
let OperandType = "OPERAND_FOUR";
59+
}
60+
3761
//===----------------------------------------------------------------------===//
3862
// Instruction class templates
3963
//===----------------------------------------------------------------------===//
@@ -131,10 +155,10 @@ class THMulAccumulate_rr<bits<7> funct7, string opcodestr>
131155
}
132156

133157
let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
134-
class THLoadPair<bits<5> funct5, string opcodestr>
158+
class THLoadPair<bits<5> funct5, string opcodestr, Operand consttype>
135159
: RVInstRBase<0b100, OPC_CUSTOM_0,
136160
(outs GPR:$rd, GPR:$rs2),
137-
(ins GPR:$rs1, uimm2:$uimm2, uimm7:$const3or4),
161+
(ins GPR:$rs1, uimm2:$uimm2, consttype:$const3or4),
138162
opcodestr, "$rd, $rs2, (${rs1}), $uimm2, $const3or4"> {
139163
bits<2> uimm2;
140164
let Inst{31-27} = funct5;
@@ -144,9 +168,9 @@ class THLoadPair<bits<5> funct5, string opcodestr>
144168
}
145169

146170
let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
147-
class THStorePair<bits<5> funct5, string opcodestr>
171+
class THStorePair<bits<5> funct5, string opcodestr, Operand consttype>
148172
: RVInstRBase<0b101, OPC_CUSTOM_0, (outs),
149-
(ins GPR:$rd, GPR:$rs2, GPR:$rs1, uimm2:$uimm2, uimm7:$const3or4),
173+
(ins GPR:$rd, GPR:$rs2, GPR:$rs1, uimm2:$uimm2, consttype:$const3or4),
150174
opcodestr, "$rd, $rs2, (${rs1}), $uimm2, $const3or4"> {
151175
bits<2> uimm2;
152176
let Inst{31-27} = funct5;
@@ -290,19 +314,19 @@ def TH_MULSW : THMulAccumulate_rr<0b0010011, "th.mulsw">;
290314
} // Predicates = [HasVendorXTHeadMac, IsRV64]
291315

292316
let Predicates = [HasVendorXTHeadMemPair] in {
293-
def TH_LWUD : THLoadPair<0b11110, "th.lwud">,
317+
def TH_LWUD : THLoadPair<0b11110, "th.lwud", immthree>,
294318
Sched<[WriteLDW, WriteLDW, ReadMemBase]>;
295-
def TH_SWD : THStorePair<0b11100, "th.swd">,
319+
def TH_SWD : THStorePair<0b11100, "th.swd", immthree>,
296320
Sched<[WriteSTW, WriteSTW, ReadStoreData, ReadMemBase]>;
297321
let IsSignExtendingOpW = 1 in
298-
def TH_LWD : THLoadPair<0b11100, "th.lwd">,
322+
def TH_LWD : THLoadPair<0b11100, "th.lwd", immthree>,
299323
Sched<[WriteLDW, WriteLDW, ReadMemBase]>;
300324
}
301325

302326
let Predicates = [HasVendorXTHeadMemPair, IsRV64] in {
303-
def TH_LDD : THLoadPair<0b11111, "th.ldd">,
327+
def TH_LDD : THLoadPair<0b11111, "th.ldd", immfour>,
304328
Sched<[WriteLDD, WriteLDD, ReadMemBase]>;
305-
def TH_SDD : THStorePair<0b11111, "th.sdd">,
329+
def TH_SDD : THStorePair<0b11111, "th.sdd", immfour>,
306330
Sched<[WriteSTD, WriteSTD, ReadStoreData, ReadMemBase]>;
307331
}
308332

llvm/test/MC/RISCV/rv32xtheadmempair-invalid.s

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
th.ldd t0, t1, (t2), 5, 4 # CHECK: [[@LINE]]:22: error: invalid operand for instruction
44
th.ldd t0, t1, (t2) # CHECK: [[@LINE]]:1: error: too few operands for instruction
5-
th.ldd t0, t1, (t2), 3, 5 # CHECK: [[@LINE]]:1: error: instruction requires the following: RV64I Base Instruction Set{{$}}
5+
th.ldd t0, t1, (t2), 3, 5 # CHECK: [[@LINE]]:25: error: invalid operand for instruction
66
th.sdd a0, a1, (a2), 5, 4 # CHECK: [[@LINE]]:22: error: invalid operand for instruction
77
th.sdd a0, a1, (a2) # CHECK: [[@LINE]]:1: error: too few operands for instruction
8-
th.sdd a0, a1, (a2), 3, 5 # CHECK: [[@LINE]]:1: error: instruction requires the following: RV64I Base Instruction Set{{$}}
8+
th.sdd a0, a1, (a2), 3, 5 # CHECK: [[@LINE]]:25: error: invalid operand for instruction
99
th.lwud t0, t1, (t2), 5, 4 # CHECK: [[@LINE]]:23: error: immediate must be an integer in the range [0, 3]
1010
th.lwud t0, t1, (t2) # CHECK: [[@LINE]]:1: error: too few operands for instruction
1111
th.lwud t0, t1, (t2), 3, 5 # CHECK: [[@LINE]]:26: error: operand must be constant 3

0 commit comments

Comments
 (0)