aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2024-01-11 18:29:01 +0000
committerDimitry Andric <dim@FreeBSD.org>2024-04-06 20:13:39 +0000
commit297eecfb02bb25902531dbb5c3b9a88caf8adf29 (patch)
treef83ae8ea4aeae9e08a965b28d3355cb3e0475e07 /contrib/llvm-project/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
parent1db9f3b21e39176dd5b67cf8ac378633b172463e (diff)
parent950076cd18f3fa9d789b4add9d405898efff09a5 (diff)
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp77
1 files changed, 55 insertions, 22 deletions
diff --git a/contrib/llvm-project/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/contrib/llvm-project/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index d616aaeddf41..7d42481db57f 100644
--- a/contrib/llvm-project/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/contrib/llvm-project/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -199,6 +199,8 @@ class RISCVAsmParser : public MCTargetAsmParser {
ParseStatus parseInsnDirectiveOpcode(OperandVector &Operands);
ParseStatus parseInsnCDirectiveOpcode(OperandVector &Operands);
ParseStatus parseGPRAsFPR(OperandVector &Operands);
+ template <bool IsRV64Inst> ParseStatus parseGPRPair(OperandVector &Operands);
+ ParseStatus parseGPRPair(OperandVector &Operands, bool IsRV64Inst);
ParseStatus parseFRMArg(OperandVector &Operands);
ParseStatus parseFenceArg(OperandVector &Operands);
ParseStatus parseReglist(OperandVector &Operands);
@@ -466,6 +468,12 @@ public:
bool isGPRAsFPR() const { return isGPR() && Reg.IsGPRAsFPR; }
+ bool isGPRPair() const {
+ return Kind == KindTy::Register &&
+ RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].contains(
+ Reg.RegNum);
+ }
+
static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm,
RISCVMCExpr::VariantKind &VK) {
if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) {
@@ -1295,11 +1303,15 @@ unsigned RISCVAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
for (unsigned I = 0; I < MCID.NumOperands; ++I) {
- if (MCID.operands()[I].RegClass == RISCV::GPRPF64RegClassID) {
+ if (MCID.operands()[I].RegClass == RISCV::GPRPairRegClassID) {
const auto &Op = Inst.getOperand(I);
assert(Op.isReg());
MCRegister Reg = Op.getReg();
+ if (RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].contains(Reg))
+ continue;
+
+ // FIXME: We should form a paired register during parsing/matching.
if (((Reg.id() - RISCV::X0) & 1) != 0)
return Match_RequiresEvenGPRs;
}
@@ -2222,6 +2234,48 @@ ParseStatus RISCVAsmParser::parseGPRAsFPR(OperandVector &Operands) {
return ParseStatus::Success;
}
+template <bool IsRV64>
+ParseStatus RISCVAsmParser::parseGPRPair(OperandVector &Operands) {
+ return parseGPRPair(Operands, IsRV64);
+}
+
+ParseStatus RISCVAsmParser::parseGPRPair(OperandVector &Operands,
+ bool IsRV64Inst) {
+ // If this is not an RV64 GPRPair instruction, don't parse as a GPRPair on
+ // RV64 as it will prevent matching the RV64 version of the same instruction
+ // that doesn't use a GPRPair.
+ // If this is an RV64 GPRPair instruction, there is no RV32 version so we can
+ // still parse as a pair.
+ if (!IsRV64Inst && isRV64())
+ return ParseStatus::NoMatch;
+
+ if (getLexer().isNot(AsmToken::Identifier))
+ return ParseStatus::NoMatch;
+
+ StringRef Name = getLexer().getTok().getIdentifier();
+ MCRegister RegNo = matchRegisterNameHelper(isRVE(), Name);
+
+ if (!RegNo)
+ return ParseStatus::NoMatch;
+
+ if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(RegNo))
+ return ParseStatus::NoMatch;
+
+ if ((RegNo - RISCV::X0) & 1)
+ return TokError("register must be even");
+
+ SMLoc S = getLoc();
+ SMLoc E = SMLoc::getFromPointer(S.getPointer() + Name.size());
+ getLexer().Lex();
+
+ const MCRegisterInfo *RI = getContext().getRegisterInfo();
+ unsigned Pair = RI->getMatchingSuperReg(
+ RegNo, RISCV::sub_gpr_even,
+ &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
+ Operands.push_back(RISCVOperand::createReg(Pair, S, E));
+ return ParseStatus::Success;
+}
+
ParseStatus RISCVAsmParser::parseFRMArg(OperandVector &Operands) {
if (getLexer().isNot(AsmToken::Identifier))
return TokError(
@@ -3335,27 +3389,6 @@ bool RISCVAsmParser::validateInstruction(MCInst &Inst,
return Error(Loc, "Operand must be constant 4.");
}
- bool IsAMOCAS_D = Opcode == RISCV::AMOCAS_D || Opcode == RISCV::AMOCAS_D_AQ ||
- Opcode == RISCV::AMOCAS_D_RL ||
- Opcode == RISCV::AMOCAS_D_AQ_RL;
- bool IsAMOCAS_Q = Opcode == RISCV::AMOCAS_Q || Opcode == RISCV::AMOCAS_Q_AQ ||
- Opcode == RISCV::AMOCAS_Q_RL ||
- Opcode == RISCV::AMOCAS_Q_AQ_RL;
- if ((!isRV64() && IsAMOCAS_D) || IsAMOCAS_Q) {
- unsigned Rd = Inst.getOperand(0).getReg();
- unsigned Rs2 = Inst.getOperand(2).getReg();
- assert(Rd >= RISCV::X0 && Rd <= RISCV::X31);
- if ((Rd - RISCV::X0) % 2 != 0) {
- SMLoc Loc = Operands[1]->getStartLoc();
- return Error(Loc, "The destination register must be even.");
- }
- assert(Rs2 >= RISCV::X0 && Rs2 <= RISCV::X31);
- if ((Rs2 - RISCV::X0) % 2 != 0) {
- SMLoc Loc = Operands[2]->getStartLoc();
- return Error(Loc, "The source register must be even.");
- }
- }
-
const MCInstrDesc &MCID = MII.get(Opcode);
if (!(MCID.TSFlags & RISCVII::ConstraintMask))
return false;