diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2024-01-11 18:29:01 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2024-04-06 20:13:39 +0000 |
commit | 297eecfb02bb25902531dbb5c3b9a88caf8adf29 (patch) | |
tree | f83ae8ea4aeae9e08a965b28d3355cb3e0475e07 /contrib/llvm-project/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp | |
parent | 1db9f3b21e39176dd5b67cf8ac378633b172463e (diff) | |
parent | 950076cd18f3fa9d789b4add9d405898efff09a5 (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.cpp | 77 |
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; |