mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-03-01 01:30:36 +00:00
AsmMatchers: Use unique_ptr to manage ownership of MCParsedAsmOperand
I saw at least a memory leak or two from inspection (on probably untested error paths) and r206991, which was the original inspiration for this change. I ran this idea by Jim Grosbach a few weeks ago & he was OK with it. Since it's a basically mechanical patch that seemed sufficient - usual post-commit review, revert, etc, as needed. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@210427 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e570687bd8
commit
c50f986b4d
@ -14,6 +14,8 @@
|
||||
#include "llvm/MC/MCParser/MCAsmParserExtension.h"
|
||||
#include "llvm/MC/MCTargetOptions.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace llvm {
|
||||
class AsmToken;
|
||||
class MCInst;
|
||||
@ -23,6 +25,8 @@ class SMLoc;
|
||||
class StringRef;
|
||||
template <typename T> class SmallVectorImpl;
|
||||
|
||||
typedef SmallVectorImpl<std::unique_ptr<MCParsedAsmOperand>> OperandVector;
|
||||
|
||||
enum AsmRewriteKind {
|
||||
AOK_Delete = 0, // Rewrite should be ignored.
|
||||
AOK_Align, // Rewrite align as .align.
|
||||
@ -131,8 +135,7 @@ public:
|
||||
/// ownership of them to the caller.
|
||||
/// \return True on failure.
|
||||
virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
|
||||
SMLoc NameLoc,
|
||||
SmallVectorImpl<MCParsedAsmOperand*> &Operands) = 0;
|
||||
SMLoc NameLoc, OperandVector &Operands) = 0;
|
||||
|
||||
/// ParseDirective - Parse a target specific assembler directive
|
||||
///
|
||||
@ -156,17 +159,16 @@ public:
|
||||
///
|
||||
/// On failure, the target parser is responsible for emitting a diagnostic
|
||||
/// explaining the match failure.
|
||||
virtual bool
|
||||
MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||
MCStreamer &Out, unsigned &ErrorInfo,
|
||||
bool MatchingInlineAsm) = 0;
|
||||
virtual bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
OperandVector &Operands, MCStreamer &Out,
|
||||
unsigned &ErrorInfo,
|
||||
bool MatchingInlineAsm) = 0;
|
||||
|
||||
/// Allow a target to add special case operand matching for things that
|
||||
/// tblgen doesn't/can't handle effectively. For example, literal
|
||||
/// immediates on ARM. TableGen expects a token operand, but the parser
|
||||
/// will recognize them as immediates.
|
||||
virtual unsigned validateTargetOperandClass(MCParsedAsmOperand *Op,
|
||||
virtual unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
|
||||
unsigned Kind) {
|
||||
return Match_InvalidOperand;
|
||||
}
|
||||
@ -178,7 +180,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void convertToMapAndConstraints(unsigned Kind,
|
||||
const SmallVectorImpl<MCParsedAsmOperand*> &Operands) = 0;
|
||||
const OperandVector &Operands) = 0;
|
||||
|
||||
virtual const MCExpr *applyModifierToExpr(const MCExpr *E,
|
||||
MCSymbolRefExpr::VariantKind,
|
||||
|
@ -102,7 +102,7 @@ public:
|
||||
|
||||
struct ParseStatementInfo {
|
||||
/// \brief The parsed operands from the last parsed statement.
|
||||
SmallVector<MCParsedAsmOperand*, 8> ParsedOperands;
|
||||
SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> ParsedOperands;
|
||||
|
||||
/// \brief The opcode from the last parsed instruction.
|
||||
unsigned Opcode;
|
||||
@ -115,13 +115,6 @@ struct ParseStatementInfo {
|
||||
ParseStatementInfo() : Opcode(~0U), ParseError(false), AsmRewrites(nullptr) {}
|
||||
ParseStatementInfo(SmallVectorImpl<AsmRewrite> *rewrites)
|
||||
: Opcode(~0), ParseError(false), AsmRewrites(rewrites) {}
|
||||
|
||||
~ParseStatementInfo() {
|
||||
// Free any parsed operands.
|
||||
for (unsigned i = 0, e = ParsedOperands.size(); i != e; ++i)
|
||||
delete ParsedOperands[i];
|
||||
ParsedOperands.clear();
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief The concrete assembly parser instance.
|
||||
@ -4465,27 +4458,27 @@ bool AsmParser::parseMSInlineAsm(
|
||||
|
||||
// Build the list of clobbers, outputs and inputs.
|
||||
for (unsigned i = 1, e = Info.ParsedOperands.size(); i != e; ++i) {
|
||||
MCParsedAsmOperand *Operand = Info.ParsedOperands[i];
|
||||
MCParsedAsmOperand &Operand = *Info.ParsedOperands[i];
|
||||
|
||||
// Immediate.
|
||||
if (Operand->isImm())
|
||||
if (Operand.isImm())
|
||||
continue;
|
||||
|
||||
// Register operand.
|
||||
if (Operand->isReg() && !Operand->needAddressOf()) {
|
||||
if (Operand.isReg() && !Operand.needAddressOf()) {
|
||||
unsigned NumDefs = Desc.getNumDefs();
|
||||
// Clobber.
|
||||
if (NumDefs && Operand->getMCOperandNum() < NumDefs)
|
||||
ClobberRegs.push_back(Operand->getReg());
|
||||
if (NumDefs && Operand.getMCOperandNum() < NumDefs)
|
||||
ClobberRegs.push_back(Operand.getReg());
|
||||
continue;
|
||||
}
|
||||
|
||||
// Expr/Input or Output.
|
||||
StringRef SymName = Operand->getSymName();
|
||||
StringRef SymName = Operand.getSymName();
|
||||
if (SymName.empty())
|
||||
continue;
|
||||
|
||||
void *OpDecl = Operand->getOpDecl();
|
||||
void *OpDecl = Operand.getOpDecl();
|
||||
if (!OpDecl)
|
||||
continue;
|
||||
|
||||
@ -4494,13 +4487,13 @@ bool AsmParser::parseMSInlineAsm(
|
||||
if (isOutput) {
|
||||
++InputIdx;
|
||||
OutputDecls.push_back(OpDecl);
|
||||
OutputDeclsAddressOf.push_back(Operand->needAddressOf());
|
||||
OutputConstraints.push_back('=' + Operand->getConstraint().str());
|
||||
OutputDeclsAddressOf.push_back(Operand.needAddressOf());
|
||||
OutputConstraints.push_back('=' + Operand.getConstraint().str());
|
||||
AsmStrRewrites.push_back(AsmRewrite(AOK_Output, Start, SymName.size()));
|
||||
} else {
|
||||
InputDecls.push_back(OpDecl);
|
||||
InputDeclsAddressOf.push_back(Operand->needAddressOf());
|
||||
InputConstraints.push_back(Operand->getConstraint().str());
|
||||
InputDeclsAddressOf.push_back(Operand.needAddressOf());
|
||||
InputConstraints.push_back(Operand.getConstraint().str());
|
||||
AsmStrRewrites.push_back(AsmRewrite(AOK_Input, Start, SymName.size()));
|
||||
}
|
||||
}
|
||||
|
@ -38,9 +38,6 @@ namespace {
|
||||
class AArch64Operand;
|
||||
|
||||
class AArch64AsmParser : public MCTargetAsmParser {
|
||||
public:
|
||||
typedef SmallVectorImpl<MCParsedAsmOperand *> OperandVector;
|
||||
|
||||
private:
|
||||
StringRef Mnemonic; ///< Instruction mnemonic.
|
||||
MCSubtargetInfo &STI;
|
||||
@ -117,7 +114,7 @@ public:
|
||||
SMLoc NameLoc, OperandVector &Operands) override;
|
||||
bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
|
||||
bool ParseDirective(AsmToken DirectiveID) override;
|
||||
unsigned validateTargetOperandClass(MCParsedAsmOperand *Op,
|
||||
unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
|
||||
unsigned Kind) override;
|
||||
|
||||
static bool classifySymbolRef(const MCExpr *Expr,
|
||||
@ -240,10 +237,10 @@ private:
|
||||
// the add<>Operands() calls.
|
||||
MCContext &Ctx;
|
||||
|
||||
public:
|
||||
AArch64Operand(KindTy K, MCContext &_Ctx)
|
||||
: MCParsedAsmOperand(), Kind(K), Ctx(_Ctx) {}
|
||||
|
||||
public:
|
||||
AArch64Operand(const AArch64Operand &o) : MCParsedAsmOperand(), Ctx(o.Ctx) {
|
||||
Kind = o.Kind;
|
||||
StartLoc = o.StartLoc;
|
||||
@ -1523,9 +1520,9 @@ public:
|
||||
|
||||
void print(raw_ostream &OS) const override;
|
||||
|
||||
static AArch64Operand *CreateToken(StringRef Str, bool IsSuffix, SMLoc S,
|
||||
MCContext &Ctx) {
|
||||
AArch64Operand *Op = new AArch64Operand(k_Token, Ctx);
|
||||
static std::unique_ptr<AArch64Operand>
|
||||
CreateToken(StringRef Str, bool IsSuffix, SMLoc S, MCContext &Ctx) {
|
||||
auto Op = make_unique<AArch64Operand>(k_Token, Ctx);
|
||||
Op->Tok.Data = Str.data();
|
||||
Op->Tok.Length = Str.size();
|
||||
Op->Tok.IsSuffix = IsSuffix;
|
||||
@ -1534,9 +1531,9 @@ public:
|
||||
return Op;
|
||||
}
|
||||
|
||||
static AArch64Operand *CreateReg(unsigned RegNum, bool isVector, SMLoc S,
|
||||
SMLoc E, MCContext &Ctx) {
|
||||
AArch64Operand *Op = new AArch64Operand(k_Register, Ctx);
|
||||
static std::unique_ptr<AArch64Operand>
|
||||
CreateReg(unsigned RegNum, bool isVector, SMLoc S, SMLoc E, MCContext &Ctx) {
|
||||
auto Op = make_unique<AArch64Operand>(k_Register, Ctx);
|
||||
Op->Reg.RegNum = RegNum;
|
||||
Op->Reg.isVector = isVector;
|
||||
Op->StartLoc = S;
|
||||
@ -1544,10 +1541,10 @@ public:
|
||||
return Op;
|
||||
}
|
||||
|
||||
static AArch64Operand *CreateVectorList(unsigned RegNum, unsigned Count,
|
||||
unsigned NumElements, char ElementKind,
|
||||
SMLoc S, SMLoc E, MCContext &Ctx) {
|
||||
AArch64Operand *Op = new AArch64Operand(k_VectorList, Ctx);
|
||||
static std::unique_ptr<AArch64Operand>
|
||||
CreateVectorList(unsigned RegNum, unsigned Count, unsigned NumElements,
|
||||
char ElementKind, SMLoc S, SMLoc E, MCContext &Ctx) {
|
||||
auto Op = make_unique<AArch64Operand>(k_VectorList, Ctx);
|
||||
Op->VectorList.RegNum = RegNum;
|
||||
Op->VectorList.Count = Count;
|
||||
Op->VectorList.NumElements = NumElements;
|
||||
@ -1557,28 +1554,29 @@ public:
|
||||
return Op;
|
||||
}
|
||||
|
||||
static AArch64Operand *CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E,
|
||||
MCContext &Ctx) {
|
||||
AArch64Operand *Op = new AArch64Operand(k_VectorIndex, Ctx);
|
||||
static std::unique_ptr<AArch64Operand>
|
||||
CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E, MCContext &Ctx) {
|
||||
auto Op = make_unique<AArch64Operand>(k_VectorIndex, Ctx);
|
||||
Op->VectorIndex.Val = Idx;
|
||||
Op->StartLoc = S;
|
||||
Op->EndLoc = E;
|
||||
return Op;
|
||||
}
|
||||
|
||||
static AArch64Operand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E,
|
||||
MCContext &Ctx) {
|
||||
AArch64Operand *Op = new AArch64Operand(k_Immediate, Ctx);
|
||||
static std::unique_ptr<AArch64Operand> CreateImm(const MCExpr *Val, SMLoc S,
|
||||
SMLoc E, MCContext &Ctx) {
|
||||
auto Op = make_unique<AArch64Operand>(k_Immediate, Ctx);
|
||||
Op->Imm.Val = Val;
|
||||
Op->StartLoc = S;
|
||||
Op->EndLoc = E;
|
||||
return Op;
|
||||
}
|
||||
|
||||
static AArch64Operand *CreateShiftedImm(const MCExpr *Val,
|
||||
unsigned ShiftAmount, SMLoc S,
|
||||
SMLoc E, MCContext &Ctx) {
|
||||
AArch64Operand *Op = new AArch64Operand(k_ShiftedImm, Ctx);
|
||||
static std::unique_ptr<AArch64Operand> CreateShiftedImm(const MCExpr *Val,
|
||||
unsigned ShiftAmount,
|
||||
SMLoc S, SMLoc E,
|
||||
MCContext &Ctx) {
|
||||
auto Op = make_unique<AArch64Operand>(k_ShiftedImm, Ctx);
|
||||
Op->ShiftedImm .Val = Val;
|
||||
Op->ShiftedImm.ShiftAmount = ShiftAmount;
|
||||
Op->StartLoc = S;
|
||||
@ -1586,34 +1584,36 @@ public:
|
||||
return Op;
|
||||
}
|
||||
|
||||
static AArch64Operand *CreateCondCode(AArch64CC::CondCode Code, SMLoc S,
|
||||
SMLoc E, MCContext &Ctx) {
|
||||
AArch64Operand *Op = new AArch64Operand(k_CondCode, Ctx);
|
||||
static std::unique_ptr<AArch64Operand>
|
||||
CreateCondCode(AArch64CC::CondCode Code, SMLoc S, SMLoc E, MCContext &Ctx) {
|
||||
auto Op = make_unique<AArch64Operand>(k_CondCode, Ctx);
|
||||
Op->CondCode.Code = Code;
|
||||
Op->StartLoc = S;
|
||||
Op->EndLoc = E;
|
||||
return Op;
|
||||
}
|
||||
|
||||
static AArch64Operand *CreateFPImm(unsigned Val, SMLoc S, MCContext &Ctx) {
|
||||
AArch64Operand *Op = new AArch64Operand(k_FPImm, Ctx);
|
||||
static std::unique_ptr<AArch64Operand> CreateFPImm(unsigned Val, SMLoc S,
|
||||
MCContext &Ctx) {
|
||||
auto Op = make_unique<AArch64Operand>(k_FPImm, Ctx);
|
||||
Op->FPImm.Val = Val;
|
||||
Op->StartLoc = S;
|
||||
Op->EndLoc = S;
|
||||
return Op;
|
||||
}
|
||||
|
||||
static AArch64Operand *CreateBarrier(unsigned Val, SMLoc S, MCContext &Ctx) {
|
||||
AArch64Operand *Op = new AArch64Operand(k_Barrier, Ctx);
|
||||
static std::unique_ptr<AArch64Operand> CreateBarrier(unsigned Val, SMLoc S,
|
||||
MCContext &Ctx) {
|
||||
auto Op = make_unique<AArch64Operand>(k_Barrier, Ctx);
|
||||
Op->Barrier.Val = Val;
|
||||
Op->StartLoc = S;
|
||||
Op->EndLoc = S;
|
||||
return Op;
|
||||
}
|
||||
|
||||
static AArch64Operand *CreateSysReg(StringRef Str, SMLoc S,
|
||||
uint64_t FeatureBits, MCContext &Ctx) {
|
||||
AArch64Operand *Op = new AArch64Operand(k_SysReg, Ctx);
|
||||
static std::unique_ptr<AArch64Operand>
|
||||
CreateSysReg(StringRef Str, SMLoc S, uint64_t FeatureBits, MCContext &Ctx) {
|
||||
auto Op = make_unique<AArch64Operand>(k_SysReg, Ctx);
|
||||
Op->SysReg.Data = Str.data();
|
||||
Op->SysReg.Length = Str.size();
|
||||
Op->SysReg.FeatureBits = FeatureBits;
|
||||
@ -1622,27 +1622,28 @@ public:
|
||||
return Op;
|
||||
}
|
||||
|
||||
static AArch64Operand *CreateSysCR(unsigned Val, SMLoc S, SMLoc E,
|
||||
MCContext &Ctx) {
|
||||
AArch64Operand *Op = new AArch64Operand(k_SysCR, Ctx);
|
||||
static std::unique_ptr<AArch64Operand> CreateSysCR(unsigned Val, SMLoc S,
|
||||
SMLoc E, MCContext &Ctx) {
|
||||
auto Op = make_unique<AArch64Operand>(k_SysCR, Ctx);
|
||||
Op->SysCRImm.Val = Val;
|
||||
Op->StartLoc = S;
|
||||
Op->EndLoc = E;
|
||||
return Op;
|
||||
}
|
||||
|
||||
static AArch64Operand *CreatePrefetch(unsigned Val, SMLoc S, MCContext &Ctx) {
|
||||
AArch64Operand *Op = new AArch64Operand(k_Prefetch, Ctx);
|
||||
static std::unique_ptr<AArch64Operand> CreatePrefetch(unsigned Val, SMLoc S,
|
||||
MCContext &Ctx) {
|
||||
auto Op = make_unique<AArch64Operand>(k_Prefetch, Ctx);
|
||||
Op->Prefetch.Val = Val;
|
||||
Op->StartLoc = S;
|
||||
Op->EndLoc = S;
|
||||
return Op;
|
||||
}
|
||||
|
||||
static AArch64Operand *CreateShiftExtend(AArch64_AM::ShiftExtendType ShOp,
|
||||
unsigned Val, bool HasExplicitAmount,
|
||||
SMLoc S, SMLoc E, MCContext &Ctx) {
|
||||
AArch64Operand *Op = new AArch64Operand(k_ShiftExtend, Ctx);
|
||||
static std::unique_ptr<AArch64Operand>
|
||||
CreateShiftExtend(AArch64_AM::ShiftExtendType ShOp, unsigned Val,
|
||||
bool HasExplicitAmount, SMLoc S, SMLoc E, MCContext &Ctx) {
|
||||
auto Op = make_unique<AArch64Operand>(k_ShiftExtend, Ctx);
|
||||
Op->ShiftExtend.Type = ShOp;
|
||||
Op->ShiftExtend.Amount = Val;
|
||||
Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount;
|
||||
@ -3456,23 +3457,23 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
unsigned &ErrorInfo,
|
||||
bool MatchingInlineAsm) {
|
||||
assert(!Operands.empty() && "Unexpect empty operand list!");
|
||||
AArch64Operand *Op = static_cast<AArch64Operand *>(Operands[0]);
|
||||
assert(Op->isToken() && "Leading operand should always be a mnemonic!");
|
||||
AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[0]);
|
||||
assert(Op.isToken() && "Leading operand should always be a mnemonic!");
|
||||
|
||||
StringRef Tok = Op->getToken();
|
||||
StringRef Tok = Op.getToken();
|
||||
unsigned NumOperands = Operands.size();
|
||||
|
||||
if (NumOperands == 4 && Tok == "lsl") {
|
||||
AArch64Operand *Op2 = static_cast<AArch64Operand *>(Operands[2]);
|
||||
AArch64Operand *Op3 = static_cast<AArch64Operand *>(Operands[3]);
|
||||
if (Op2->isReg() && Op3->isImm()) {
|
||||
const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3->getImm());
|
||||
AArch64Operand &Op2 = static_cast<AArch64Operand &>(*Operands[2]);
|
||||
AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
|
||||
if (Op2.isReg() && Op3.isImm()) {
|
||||
const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
|
||||
if (Op3CE) {
|
||||
uint64_t Op3Val = Op3CE->getValue();
|
||||
uint64_t NewOp3Val = 0;
|
||||
uint64_t NewOp4Val = 0;
|
||||
if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].contains(
|
||||
Op2->getReg())) {
|
||||
Op2.getReg())) {
|
||||
NewOp3Val = (32 - Op3Val) & 0x1f;
|
||||
NewOp4Val = 31 - Op3Val;
|
||||
} else {
|
||||
@ -3484,26 +3485,24 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
const MCExpr *NewOp4 = MCConstantExpr::Create(NewOp4Val, getContext());
|
||||
|
||||
Operands[0] = AArch64Operand::CreateToken(
|
||||
"ubfm", false, Op->getStartLoc(), getContext());
|
||||
Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3->getStartLoc(),
|
||||
Op3->getEndLoc(), getContext());
|
||||
"ubfm", false, Op.getStartLoc(), getContext());
|
||||
Operands.push_back(AArch64Operand::CreateImm(
|
||||
NewOp4, Op3->getStartLoc(), Op3->getEndLoc(), getContext()));
|
||||
delete Op3;
|
||||
delete Op;
|
||||
NewOp4, Op3.getStartLoc(), Op3.getEndLoc(), getContext()));
|
||||
Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
|
||||
Op3.getEndLoc(), getContext());
|
||||
}
|
||||
}
|
||||
} else if (NumOperands == 5) {
|
||||
// FIXME: Horrible hack to handle the BFI -> BFM, SBFIZ->SBFM, and
|
||||
// UBFIZ -> UBFM aliases.
|
||||
if (Tok == "bfi" || Tok == "sbfiz" || Tok == "ubfiz") {
|
||||
AArch64Operand *Op1 = static_cast<AArch64Operand *>(Operands[1]);
|
||||
AArch64Operand *Op3 = static_cast<AArch64Operand *>(Operands[3]);
|
||||
AArch64Operand *Op4 = static_cast<AArch64Operand *>(Operands[4]);
|
||||
AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
|
||||
AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
|
||||
AArch64Operand &Op4 = static_cast<AArch64Operand &>(*Operands[4]);
|
||||
|
||||
if (Op1->isReg() && Op3->isImm() && Op4->isImm()) {
|
||||
const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3->getImm());
|
||||
const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4->getImm());
|
||||
if (Op1.isReg() && Op3.isImm() && Op4.isImm()) {
|
||||
const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
|
||||
const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
|
||||
|
||||
if (Op3CE && Op4CE) {
|
||||
uint64_t Op3Val = Op3CE->getValue();
|
||||
@ -3511,21 +3510,21 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
|
||||
uint64_t RegWidth = 0;
|
||||
if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
|
||||
Op1->getReg()))
|
||||
Op1.getReg()))
|
||||
RegWidth = 64;
|
||||
else
|
||||
RegWidth = 32;
|
||||
|
||||
if (Op3Val >= RegWidth)
|
||||
return Error(Op3->getStartLoc(),
|
||||
return Error(Op3.getStartLoc(),
|
||||
"expected integer in range [0, 31]");
|
||||
if (Op4Val < 1 || Op4Val > RegWidth)
|
||||
return Error(Op4->getStartLoc(),
|
||||
return Error(Op4.getStartLoc(),
|
||||
"expected integer in range [1, 32]");
|
||||
|
||||
uint64_t NewOp3Val = 0;
|
||||
if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].contains(
|
||||
Op1->getReg()))
|
||||
Op1.getReg()))
|
||||
NewOp3Val = (32 - Op3Val) & 0x1f;
|
||||
else
|
||||
NewOp3Val = (64 - Op3Val) & 0x3f;
|
||||
@ -3533,7 +3532,7 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
uint64_t NewOp4Val = Op4Val - 1;
|
||||
|
||||
if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
|
||||
return Error(Op4->getStartLoc(),
|
||||
return Error(Op4.getStartLoc(),
|
||||
"requested insert overflows register");
|
||||
|
||||
const MCExpr *NewOp3 =
|
||||
@ -3541,24 +3540,20 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
const MCExpr *NewOp4 =
|
||||
MCConstantExpr::Create(NewOp4Val, getContext());
|
||||
Operands[3] = AArch64Operand::CreateImm(
|
||||
NewOp3, Op3->getStartLoc(), Op3->getEndLoc(), getContext());
|
||||
NewOp3, Op3.getStartLoc(), Op3.getEndLoc(), getContext());
|
||||
Operands[4] = AArch64Operand::CreateImm(
|
||||
NewOp4, Op4->getStartLoc(), Op4->getEndLoc(), getContext());
|
||||
NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
|
||||
if (Tok == "bfi")
|
||||
Operands[0] = AArch64Operand::CreateToken(
|
||||
"bfm", false, Op->getStartLoc(), getContext());
|
||||
"bfm", false, Op.getStartLoc(), getContext());
|
||||
else if (Tok == "sbfiz")
|
||||
Operands[0] = AArch64Operand::CreateToken(
|
||||
"sbfm", false, Op->getStartLoc(), getContext());
|
||||
"sbfm", false, Op.getStartLoc(), getContext());
|
||||
else if (Tok == "ubfiz")
|
||||
Operands[0] = AArch64Operand::CreateToken(
|
||||
"ubfm", false, Op->getStartLoc(), getContext());
|
||||
"ubfm", false, Op.getStartLoc(), getContext());
|
||||
else
|
||||
llvm_unreachable("No valid mnemonic for alias?");
|
||||
|
||||
delete Op;
|
||||
delete Op3;
|
||||
delete Op4;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3566,13 +3561,13 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
// UBFX -> UBFM aliases.
|
||||
} else if (NumOperands == 5 &&
|
||||
(Tok == "bfxil" || Tok == "sbfx" || Tok == "ubfx")) {
|
||||
AArch64Operand *Op1 = static_cast<AArch64Operand *>(Operands[1]);
|
||||
AArch64Operand *Op3 = static_cast<AArch64Operand *>(Operands[3]);
|
||||
AArch64Operand *Op4 = static_cast<AArch64Operand *>(Operands[4]);
|
||||
AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
|
||||
AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
|
||||
AArch64Operand &Op4 = static_cast<AArch64Operand &>(*Operands[4]);
|
||||
|
||||
if (Op1->isReg() && Op3->isImm() && Op4->isImm()) {
|
||||
const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3->getImm());
|
||||
const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4->getImm());
|
||||
if (Op1.isReg() && Op3.isImm() && Op4.isImm()) {
|
||||
const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
|
||||
const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
|
||||
|
||||
if (Op3CE && Op4CE) {
|
||||
uint64_t Op3Val = Op3CE->getValue();
|
||||
@ -3580,42 +3575,39 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
|
||||
uint64_t RegWidth = 0;
|
||||
if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
|
||||
Op1->getReg()))
|
||||
Op1.getReg()))
|
||||
RegWidth = 64;
|
||||
else
|
||||
RegWidth = 32;
|
||||
|
||||
if (Op3Val >= RegWidth)
|
||||
return Error(Op3->getStartLoc(),
|
||||
return Error(Op3.getStartLoc(),
|
||||
"expected integer in range [0, 31]");
|
||||
if (Op4Val < 1 || Op4Val > RegWidth)
|
||||
return Error(Op4->getStartLoc(),
|
||||
return Error(Op4.getStartLoc(),
|
||||
"expected integer in range [1, 32]");
|
||||
|
||||
uint64_t NewOp4Val = Op3Val + Op4Val - 1;
|
||||
|
||||
if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
|
||||
return Error(Op4->getStartLoc(),
|
||||
return Error(Op4.getStartLoc(),
|
||||
"requested extract overflows register");
|
||||
|
||||
const MCExpr *NewOp4 =
|
||||
MCConstantExpr::Create(NewOp4Val, getContext());
|
||||
Operands[4] = AArch64Operand::CreateImm(
|
||||
NewOp4, Op4->getStartLoc(), Op4->getEndLoc(), getContext());
|
||||
NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
|
||||
if (Tok == "bfxil")
|
||||
Operands[0] = AArch64Operand::CreateToken(
|
||||
"bfm", false, Op->getStartLoc(), getContext());
|
||||
"bfm", false, Op.getStartLoc(), getContext());
|
||||
else if (Tok == "sbfx")
|
||||
Operands[0] = AArch64Operand::CreateToken(
|
||||
"sbfm", false, Op->getStartLoc(), getContext());
|
||||
"sbfm", false, Op.getStartLoc(), getContext());
|
||||
else if (Tok == "ubfx")
|
||||
Operands[0] = AArch64Operand::CreateToken(
|
||||
"ubfm", false, Op->getStartLoc(), getContext());
|
||||
"ubfm", false, Op.getStartLoc(), getContext());
|
||||
else
|
||||
llvm_unreachable("No valid mnemonic for alias?");
|
||||
|
||||
delete Op;
|
||||
delete Op4;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3626,63 +3618,58 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
if (NumOperands == 3 && (Tok == "sxtw" || Tok == "uxtw")) {
|
||||
// The source register can be Wn here, but the matcher expects a
|
||||
// GPR64. Twiddle it here if necessary.
|
||||
AArch64Operand *Op = static_cast<AArch64Operand *>(Operands[2]);
|
||||
if (Op->isReg()) {
|
||||
unsigned Reg = getXRegFromWReg(Op->getReg());
|
||||
Operands[2] = AArch64Operand::CreateReg(Reg, false, Op->getStartLoc(),
|
||||
Op->getEndLoc(), getContext());
|
||||
delete Op;
|
||||
AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[2]);
|
||||
if (Op.isReg()) {
|
||||
unsigned Reg = getXRegFromWReg(Op.getReg());
|
||||
Operands[2] = AArch64Operand::CreateReg(Reg, false, Op.getStartLoc(),
|
||||
Op.getEndLoc(), getContext());
|
||||
}
|
||||
}
|
||||
// FIXME: Likewise for sxt[bh] with a Xd dst operand
|
||||
else if (NumOperands == 3 && (Tok == "sxtb" || Tok == "sxth")) {
|
||||
AArch64Operand *Op = static_cast<AArch64Operand *>(Operands[1]);
|
||||
if (Op->isReg() &&
|
||||
AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
|
||||
if (Op.isReg() &&
|
||||
AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
|
||||
Op->getReg())) {
|
||||
Op.getReg())) {
|
||||
// The source register can be Wn here, but the matcher expects a
|
||||
// GPR64. Twiddle it here if necessary.
|
||||
AArch64Operand *Op = static_cast<AArch64Operand *>(Operands[2]);
|
||||
if (Op->isReg()) {
|
||||
unsigned Reg = getXRegFromWReg(Op->getReg());
|
||||
Operands[2] = AArch64Operand::CreateReg(Reg, false, Op->getStartLoc(),
|
||||
Op->getEndLoc(), getContext());
|
||||
delete Op;
|
||||
AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[2]);
|
||||
if (Op.isReg()) {
|
||||
unsigned Reg = getXRegFromWReg(Op.getReg());
|
||||
Operands[2] = AArch64Operand::CreateReg(Reg, false, Op.getStartLoc(),
|
||||
Op.getEndLoc(), getContext());
|
||||
}
|
||||
}
|
||||
}
|
||||
// FIXME: Likewise for uxt[bh] with a Xd dst operand
|
||||
else if (NumOperands == 3 && (Tok == "uxtb" || Tok == "uxth")) {
|
||||
AArch64Operand *Op = static_cast<AArch64Operand *>(Operands[1]);
|
||||
if (Op->isReg() &&
|
||||
AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
|
||||
if (Op.isReg() &&
|
||||
AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
|
||||
Op->getReg())) {
|
||||
Op.getReg())) {
|
||||
// The source register can be Wn here, but the matcher expects a
|
||||
// GPR32. Twiddle it here if necessary.
|
||||
AArch64Operand *Op = static_cast<AArch64Operand *>(Operands[1]);
|
||||
if (Op->isReg()) {
|
||||
unsigned Reg = getWRegFromXReg(Op->getReg());
|
||||
Operands[1] = AArch64Operand::CreateReg(Reg, false, Op->getStartLoc(),
|
||||
Op->getEndLoc(), getContext());
|
||||
delete Op;
|
||||
AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
|
||||
if (Op.isReg()) {
|
||||
unsigned Reg = getWRegFromXReg(Op.getReg());
|
||||
Operands[1] = AArch64Operand::CreateReg(Reg, false, Op.getStartLoc(),
|
||||
Op.getEndLoc(), getContext());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Yet another horrible hack to handle FMOV Rd, #0.0 using [WX]ZR.
|
||||
if (NumOperands == 3 && Tok == "fmov") {
|
||||
AArch64Operand *RegOp = static_cast<AArch64Operand *>(Operands[1]);
|
||||
AArch64Operand *ImmOp = static_cast<AArch64Operand *>(Operands[2]);
|
||||
if (RegOp->isReg() && ImmOp->isFPImm() &&
|
||||
ImmOp->getFPImm() == (unsigned)-1) {
|
||||
AArch64Operand &RegOp = static_cast<AArch64Operand &>(*Operands[1]);
|
||||
AArch64Operand &ImmOp = static_cast<AArch64Operand &>(*Operands[2]);
|
||||
if (RegOp.isReg() && ImmOp.isFPImm() && ImmOp.getFPImm() == (unsigned)-1) {
|
||||
unsigned zreg =
|
||||
AArch64MCRegisterClasses[AArch64::FPR32RegClassID].contains(
|
||||
RegOp->getReg())
|
||||
RegOp.getReg())
|
||||
? AArch64::WZR
|
||||
: AArch64::XZR;
|
||||
Operands[2] = AArch64Operand::CreateReg(zreg, false, Op->getStartLoc(),
|
||||
Op->getEndLoc(), getContext());
|
||||
delete ImmOp;
|
||||
Operands[2] = AArch64Operand::CreateReg(zreg, false, Op.getStartLoc(),
|
||||
Op.getEndLoc(), getContext());
|
||||
}
|
||||
}
|
||||
|
||||
@ -3735,14 +3722,14 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
if (ErrorInfo >= Operands.size())
|
||||
return Error(IDLoc, "too few operands for instruction");
|
||||
|
||||
ErrorLoc = ((AArch64Operand *)Operands[ErrorInfo])->getStartLoc();
|
||||
ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
|
||||
if (ErrorLoc == SMLoc())
|
||||
ErrorLoc = IDLoc;
|
||||
}
|
||||
// If the match failed on a suffix token operand, tweak the diagnostic
|
||||
// accordingly.
|
||||
if (((AArch64Operand *)Operands[ErrorInfo])->isToken() &&
|
||||
((AArch64Operand *)Operands[ErrorInfo])->isTokenSuffix())
|
||||
if (((AArch64Operand &)*Operands[ErrorInfo]).isToken() &&
|
||||
((AArch64Operand &)*Operands[ErrorInfo]).isTokenSuffix())
|
||||
MatchResult = Match_InvalidSuffix;
|
||||
|
||||
return showMatchError(ErrorLoc, MatchResult);
|
||||
@ -3798,7 +3785,7 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
return Error(IDLoc, "too few operands for instruction");
|
||||
// Any time we get here, there's nothing fancy to do. Just get the
|
||||
// operand SMLoc and display the diagnostic.
|
||||
SMLoc ErrorLoc = ((AArch64Operand *)Operands[ErrorInfo])->getStartLoc();
|
||||
SMLoc ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
|
||||
if (ErrorLoc == SMLoc())
|
||||
ErrorLoc = IDLoc;
|
||||
return showMatchError(ErrorLoc, MatchResult);
|
||||
@ -3988,9 +3975,9 @@ extern "C" void LLVMInitializeAArch64AsmParser() {
|
||||
|
||||
// Define this matcher function after the auto-generated include so we
|
||||
// have the match class enum definitions.
|
||||
unsigned AArch64AsmParser::validateTargetOperandClass(MCParsedAsmOperand *AsmOp,
|
||||
unsigned AArch64AsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
|
||||
unsigned Kind) {
|
||||
AArch64Operand *Op = static_cast<AArch64Operand *>(AsmOp);
|
||||
AArch64Operand &Op = static_cast<AArch64Operand &>(AsmOp);
|
||||
// If the kind is a token for a literal immediate, check if our asm
|
||||
// operand matches. This is for InstAliases which have a fixed-value
|
||||
// immediate in the syntax.
|
||||
@ -4038,9 +4025,9 @@ unsigned AArch64AsmParser::validateTargetOperandClass(MCParsedAsmOperand *AsmOp,
|
||||
ExpectedVal = 8;
|
||||
break;
|
||||
}
|
||||
if (!Op->isImm())
|
||||
if (!Op.isImm())
|
||||
return Match_InvalidOperand;
|
||||
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
|
||||
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm());
|
||||
if (!CE)
|
||||
return Match_InvalidOperand;
|
||||
if (CE->getValue() == ExpectedVal)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -73,55 +73,44 @@ class MipsAsmParser : public MCTargetAsmParser {
|
||||
#include "MipsGenAsmMatcher.inc"
|
||||
|
||||
bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
SmallVectorImpl<MCParsedAsmOperand *> &Operands,
|
||||
MCStreamer &Out, unsigned &ErrorInfo,
|
||||
OperandVector &Operands, MCStreamer &Out,
|
||||
unsigned &ErrorInfo,
|
||||
bool MatchingInlineAsm) override;
|
||||
|
||||
/// Parse a register as used in CFI directives
|
||||
bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
|
||||
|
||||
bool ParseParenSuffix(StringRef Name,
|
||||
SmallVectorImpl<MCParsedAsmOperand *> &Operands);
|
||||
bool ParseParenSuffix(StringRef Name, OperandVector &Operands);
|
||||
|
||||
bool ParseBracketSuffix(StringRef Name,
|
||||
SmallVectorImpl<MCParsedAsmOperand *> &Operands);
|
||||
bool ParseBracketSuffix(StringRef Name, OperandVector &Operands);
|
||||
|
||||
bool
|
||||
ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
|
||||
SmallVectorImpl<MCParsedAsmOperand *> &Operands) override;
|
||||
bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
|
||||
SMLoc NameLoc, OperandVector &Operands) override;
|
||||
|
||||
bool ParseDirective(AsmToken DirectiveID) override;
|
||||
|
||||
MipsAsmParser::OperandMatchResultTy
|
||||
parseMemOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
|
||||
|
||||
MipsAsmParser::OperandMatchResultTy MatchAnyRegisterNameWithoutDollar(
|
||||
SmallVectorImpl<MCParsedAsmOperand *> &Operands, StringRef Identifier,
|
||||
SMLoc S);
|
||||
MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
|
||||
|
||||
MipsAsmParser::OperandMatchResultTy
|
||||
MatchAnyRegisterWithoutDollar(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
|
||||
SMLoc S);
|
||||
MatchAnyRegisterNameWithoutDollar(OperandVector &Operands,
|
||||
StringRef Identifier, SMLoc S);
|
||||
|
||||
MipsAsmParser::OperandMatchResultTy
|
||||
ParseAnyRegister(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
|
||||
MatchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
|
||||
|
||||
MipsAsmParser::OperandMatchResultTy
|
||||
ParseImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
|
||||
MipsAsmParser::OperandMatchResultTy ParseAnyRegister(OperandVector &Operands);
|
||||
|
||||
MipsAsmParser::OperandMatchResultTy
|
||||
ParseJumpTarget(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
|
||||
MipsAsmParser::OperandMatchResultTy ParseImm(OperandVector &Operands);
|
||||
|
||||
MipsAsmParser::OperandMatchResultTy
|
||||
parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
|
||||
MipsAsmParser::OperandMatchResultTy ParseJumpTarget(OperandVector &Operands);
|
||||
|
||||
MipsAsmParser::OperandMatchResultTy
|
||||
ParseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
|
||||
MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
|
||||
|
||||
bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
|
||||
MipsAsmParser::OperandMatchResultTy ParseLSAImm(OperandVector &Operands);
|
||||
|
||||
bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &,
|
||||
StringRef Mnemonic);
|
||||
bool searchSymbolAlias(OperandVector &Operands);
|
||||
|
||||
bool ParseOperand(OperandVector &, StringRef Mnemonic);
|
||||
|
||||
bool needsExpansion(MCInst &Inst);
|
||||
|
||||
@ -289,9 +278,11 @@ private:
|
||||
k_Token /// A simple token
|
||||
} Kind;
|
||||
|
||||
public:
|
||||
MipsOperand(KindTy K, MipsAsmParser &Parser)
|
||||
: MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
|
||||
|
||||
private:
|
||||
/// For diagnostics, and checking the assembler temporary
|
||||
MipsAsmParser &AsmParser;
|
||||
|
||||
@ -330,10 +321,11 @@ private:
|
||||
SMLoc StartLoc, EndLoc;
|
||||
|
||||
/// Internal constructor for register kinds
|
||||
static MipsOperand *CreateReg(unsigned Index, RegKind RegKind,
|
||||
const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
|
||||
MipsAsmParser &Parser) {
|
||||
MipsOperand *Op = new MipsOperand(k_RegisterIndex, Parser);
|
||||
static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
|
||||
const MCRegisterInfo *RegInfo,
|
||||
SMLoc S, SMLoc E,
|
||||
MipsAsmParser &Parser) {
|
||||
auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
|
||||
Op->RegIdx.Index = Index;
|
||||
Op->RegIdx.RegInfo = RegInfo;
|
||||
Op->RegIdx.Kind = RegKind;
|
||||
@ -656,9 +648,9 @@ public:
|
||||
return Mem.Off;
|
||||
}
|
||||
|
||||
static MipsOperand *CreateToken(StringRef Str, SMLoc S,
|
||||
MipsAsmParser &Parser) {
|
||||
MipsOperand *Op = new MipsOperand(k_Token, Parser);
|
||||
static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
|
||||
MipsAsmParser &Parser) {
|
||||
auto Op = make_unique<MipsOperand>(k_Token, Parser);
|
||||
Op->Tok.Data = Str.data();
|
||||
Op->Tok.Length = Str.size();
|
||||
Op->StartLoc = S;
|
||||
@ -668,74 +660,75 @@ public:
|
||||
|
||||
/// Create a numeric register (e.g. $1). The exact register remains
|
||||
/// unresolved until an instruction successfully matches
|
||||
static MipsOperand *CreateNumericReg(unsigned Index,
|
||||
const MCRegisterInfo *RegInfo, SMLoc S,
|
||||
SMLoc E, MipsAsmParser &Parser) {
|
||||
static std::unique_ptr<MipsOperand>
|
||||
CreateNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
|
||||
SMLoc E, MipsAsmParser &Parser) {
|
||||
DEBUG(dbgs() << "CreateNumericReg(" << Index << ", ...)\n");
|
||||
return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
|
||||
}
|
||||
|
||||
/// Create a register that is definitely a GPR.
|
||||
/// This is typically only used for named registers such as $gp.
|
||||
static MipsOperand *CreateGPRReg(unsigned Index,
|
||||
const MCRegisterInfo *RegInfo, SMLoc S,
|
||||
SMLoc E, MipsAsmParser &Parser) {
|
||||
static std::unique_ptr<MipsOperand>
|
||||
CreateGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
|
||||
MipsAsmParser &Parser) {
|
||||
return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
|
||||
}
|
||||
|
||||
/// Create a register that is definitely a FGR.
|
||||
/// This is typically only used for named registers such as $f0.
|
||||
static MipsOperand *CreateFGRReg(unsigned Index,
|
||||
const MCRegisterInfo *RegInfo, SMLoc S,
|
||||
SMLoc E, MipsAsmParser &Parser) {
|
||||
static std::unique_ptr<MipsOperand>
|
||||
CreateFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
|
||||
MipsAsmParser &Parser) {
|
||||
return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
|
||||
}
|
||||
|
||||
/// Create a register that is definitely an FCC.
|
||||
/// This is typically only used for named registers such as $fcc0.
|
||||
static MipsOperand *CreateFCCReg(unsigned Index,
|
||||
const MCRegisterInfo *RegInfo, SMLoc S,
|
||||
SMLoc E, MipsAsmParser &Parser) {
|
||||
static std::unique_ptr<MipsOperand>
|
||||
CreateFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
|
||||
MipsAsmParser &Parser) {
|
||||
return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
|
||||
}
|
||||
|
||||
/// Create a register that is definitely an ACC.
|
||||
/// This is typically only used for named registers such as $ac0.
|
||||
static MipsOperand *CreateACCReg(unsigned Index,
|
||||
const MCRegisterInfo *RegInfo, SMLoc S,
|
||||
SMLoc E, MipsAsmParser &Parser) {
|
||||
static std::unique_ptr<MipsOperand>
|
||||
CreateACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
|
||||
MipsAsmParser &Parser) {
|
||||
return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
|
||||
}
|
||||
|
||||
/// Create a register that is definitely an MSA128.
|
||||
/// This is typically only used for named registers such as $w0.
|
||||
static MipsOperand *CreateMSA128Reg(unsigned Index,
|
||||
const MCRegisterInfo *RegInfo, SMLoc S,
|
||||
SMLoc E, MipsAsmParser &Parser) {
|
||||
static std::unique_ptr<MipsOperand>
|
||||
CreateMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
|
||||
SMLoc E, MipsAsmParser &Parser) {
|
||||
return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
|
||||
}
|
||||
|
||||
/// Create a register that is definitely an MSACtrl.
|
||||
/// This is typically only used for named registers such as $msaaccess.
|
||||
static MipsOperand *CreateMSACtrlReg(unsigned Index,
|
||||
const MCRegisterInfo *RegInfo, SMLoc S,
|
||||
SMLoc E, MipsAsmParser &Parser) {
|
||||
static std::unique_ptr<MipsOperand>
|
||||
CreateMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
|
||||
SMLoc E, MipsAsmParser &Parser) {
|
||||
return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
|
||||
}
|
||||
|
||||
static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E,
|
||||
MipsAsmParser &Parser) {
|
||||
MipsOperand *Op = new MipsOperand(k_Immediate, Parser);
|
||||
static std::unique_ptr<MipsOperand>
|
||||
CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
|
||||
auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
|
||||
Op->Imm.Val = Val;
|
||||
Op->StartLoc = S;
|
||||
Op->EndLoc = E;
|
||||
return Op;
|
||||
}
|
||||
|
||||
static MipsOperand *CreateMem(MipsOperand *Base, const MCExpr *Off, SMLoc S,
|
||||
SMLoc E, MipsAsmParser &Parser) {
|
||||
MipsOperand *Op = new MipsOperand(k_Memory, Parser);
|
||||
Op->Mem.Base = Base;
|
||||
static std::unique_ptr<MipsOperand>
|
||||
CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
|
||||
SMLoc E, MipsAsmParser &Parser) {
|
||||
auto Op = make_unique<MipsOperand>(k_Memory, Parser);
|
||||
Op->Mem.Base = Base.release();
|
||||
Op->Mem.Off = Off;
|
||||
Op->StartLoc = S;
|
||||
Op->EndLoc = E;
|
||||
@ -1164,10 +1157,11 @@ void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
|
||||
TempInst.clear();
|
||||
}
|
||||
|
||||
bool MipsAsmParser::MatchAndEmitInstruction(
|
||||
SMLoc IDLoc, unsigned &Opcode,
|
||||
SmallVectorImpl<MCParsedAsmOperand *> &Operands, MCStreamer &Out,
|
||||
unsigned &ErrorInfo, bool MatchingInlineAsm) {
|
||||
bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
OperandVector &Operands,
|
||||
MCStreamer &Out,
|
||||
unsigned &ErrorInfo,
|
||||
bool MatchingInlineAsm) {
|
||||
MCInst Inst;
|
||||
SmallVector<MCInst, 8> Instructions;
|
||||
unsigned MatchResult =
|
||||
@ -1192,7 +1186,7 @@ bool MipsAsmParser::MatchAndEmitInstruction(
|
||||
if (ErrorInfo >= Operands.size())
|
||||
return Error(IDLoc, "too few operands for instruction");
|
||||
|
||||
ErrorLoc = ((MipsOperand *)Operands[ErrorInfo])->getStartLoc();
|
||||
ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
|
||||
if (ErrorLoc == SMLoc())
|
||||
ErrorLoc = IDLoc;
|
||||
}
|
||||
@ -1378,9 +1372,7 @@ int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
|
||||
return getReg(RegClass, RegNum);
|
||||
}
|
||||
|
||||
bool
|
||||
MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
|
||||
StringRef Mnemonic) {
|
||||
bool MipsAsmParser::ParseOperand(OperandVector &Operands, StringRef Mnemonic) {
|
||||
DEBUG(dbgs() << "ParseOperand\n");
|
||||
|
||||
// Check if the current operand has a custom associated parser, if so, try to
|
||||
@ -1578,11 +1570,11 @@ bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
|
||||
|
||||
bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
|
||||
SMLoc &EndLoc) {
|
||||
SmallVector<MCParsedAsmOperand *, 1> Operands;
|
||||
SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
|
||||
OperandMatchResultTy ResTy = ParseAnyRegister(Operands);
|
||||
if (ResTy == MatchOperand_Success) {
|
||||
assert(Operands.size() == 1);
|
||||
MipsOperand &Operand = *static_cast<MipsOperand *>(Operands.front());
|
||||
MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
|
||||
StartLoc = Operand.getStartLoc();
|
||||
EndLoc = Operand.getEndLoc();
|
||||
|
||||
@ -1595,8 +1587,6 @@ bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
|
||||
RegNo = isGP64() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
|
||||
}
|
||||
|
||||
delete &Operand;
|
||||
|
||||
return (RegNo == (unsigned)-1);
|
||||
}
|
||||
|
||||
@ -1632,8 +1622,8 @@ bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
|
||||
return Result;
|
||||
}
|
||||
|
||||
MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
|
||||
SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
|
||||
MipsAsmParser::OperandMatchResultTy
|
||||
MipsAsmParser::parseMemOperand(OperandVector &Operands) {
|
||||
DEBUG(dbgs() << "parseMemOperand\n");
|
||||
const MCExpr *IdVal = nullptr;
|
||||
SMLoc S;
|
||||
@ -1653,8 +1643,8 @@ MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
|
||||
|
||||
const AsmToken &Tok = Parser.getTok(); // Get the next token.
|
||||
if (Tok.isNot(AsmToken::LParen)) {
|
||||
MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
|
||||
if (Mnemonic->getToken() == "la") {
|
||||
MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
|
||||
if (Mnemonic.getToken() == "la") {
|
||||
SMLoc E =
|
||||
SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
|
||||
Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
|
||||
@ -1666,9 +1656,10 @@ MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
|
||||
|
||||
// Zero register assumed, add a memory operand with ZERO as its base.
|
||||
// "Base" will be managed by k_Memory.
|
||||
MipsOperand *Base = MipsOperand::CreateGPRReg(
|
||||
0, getContext().getRegisterInfo(), S, E, *this);
|
||||
Operands.push_back(MipsOperand::CreateMem(Base, IdVal, S, E, *this));
|
||||
auto Base = MipsOperand::CreateGPRReg(0, getContext().getRegisterInfo(),
|
||||
S, E, *this);
|
||||
Operands.push_back(
|
||||
MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
Error(Parser.getTok().getLoc(), "'(' expected");
|
||||
@ -1695,7 +1686,8 @@ MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
|
||||
IdVal = MCConstantExpr::Create(0, getContext());
|
||||
|
||||
// Replace the register operand with the memory operand.
|
||||
MipsOperand *op = static_cast<MipsOperand *>(Operands.back());
|
||||
std::unique_ptr<MipsOperand> op(
|
||||
static_cast<MipsOperand *>(Operands.back().release()));
|
||||
// Remove the register from the operands.
|
||||
// "op" will be managed by k_Memory.
|
||||
Operands.pop_back();
|
||||
@ -1709,12 +1701,11 @@ MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
|
||||
getContext());
|
||||
}
|
||||
|
||||
Operands.push_back(MipsOperand::CreateMem(op, IdVal, S, E, *this));
|
||||
Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
|
||||
bool MipsAsmParser::searchSymbolAlias(
|
||||
SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
|
||||
bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
|
||||
|
||||
MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
|
||||
if (Sym) {
|
||||
@ -1740,9 +1731,8 @@ bool MipsAsmParser::searchSymbolAlias(
|
||||
} else if (Expr->getKind() == MCExpr::Constant) {
|
||||
Parser.Lex();
|
||||
const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
|
||||
MipsOperand *op =
|
||||
MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this);
|
||||
Operands.push_back(op);
|
||||
Operands.push_back(
|
||||
MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1750,9 +1740,9 @@ bool MipsAsmParser::searchSymbolAlias(
|
||||
}
|
||||
|
||||
MipsAsmParser::OperandMatchResultTy
|
||||
MipsAsmParser::MatchAnyRegisterNameWithoutDollar(
|
||||
SmallVectorImpl<MCParsedAsmOperand *> &Operands, StringRef Identifier,
|
||||
SMLoc S) {
|
||||
MipsAsmParser::MatchAnyRegisterNameWithoutDollar(OperandVector &Operands,
|
||||
StringRef Identifier,
|
||||
SMLoc S) {
|
||||
int Index = matchCPURegisterName(Identifier);
|
||||
if (Index != -1) {
|
||||
Operands.push_back(MipsOperand::CreateGPRReg(
|
||||
@ -1799,8 +1789,7 @@ MipsAsmParser::MatchAnyRegisterNameWithoutDollar(
|
||||
}
|
||||
|
||||
MipsAsmParser::OperandMatchResultTy
|
||||
MipsAsmParser::MatchAnyRegisterWithoutDollar(
|
||||
SmallVectorImpl<MCParsedAsmOperand *> &Operands, SMLoc S) {
|
||||
MipsAsmParser::MatchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
|
||||
auto Token = Parser.getLexer().peekTok(false);
|
||||
|
||||
if (Token.is(AsmToken::Identifier)) {
|
||||
@ -1822,8 +1811,8 @@ MipsAsmParser::MatchAnyRegisterWithoutDollar(
|
||||
return MatchOperand_NoMatch;
|
||||
}
|
||||
|
||||
MipsAsmParser::OperandMatchResultTy MipsAsmParser::ParseAnyRegister(
|
||||
SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
|
||||
MipsAsmParser::OperandMatchResultTy
|
||||
MipsAsmParser::ParseAnyRegister(OperandVector &Operands) {
|
||||
DEBUG(dbgs() << "ParseAnyRegister\n");
|
||||
|
||||
auto Token = Parser.getTok();
|
||||
@ -1850,7 +1839,7 @@ MipsAsmParser::OperandMatchResultTy MipsAsmParser::ParseAnyRegister(
|
||||
}
|
||||
|
||||
MipsAsmParser::OperandMatchResultTy
|
||||
MipsAsmParser::ParseImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
|
||||
MipsAsmParser::ParseImm(OperandVector &Operands) {
|
||||
switch (getLexer().getKind()) {
|
||||
default:
|
||||
return MatchOperand_NoMatch;
|
||||
@ -1872,8 +1861,8 @@ MipsAsmParser::ParseImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
|
||||
MipsAsmParser::OperandMatchResultTy MipsAsmParser::ParseJumpTarget(
|
||||
SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
|
||||
MipsAsmParser::OperandMatchResultTy
|
||||
MipsAsmParser::ParseJumpTarget(OperandVector &Operands) {
|
||||
DEBUG(dbgs() << "ParseJumpTarget\n");
|
||||
|
||||
SMLoc S = getLexer().getLoc();
|
||||
@ -1899,7 +1888,7 @@ MipsAsmParser::OperandMatchResultTy MipsAsmParser::ParseJumpTarget(
|
||||
}
|
||||
|
||||
MipsAsmParser::OperandMatchResultTy
|
||||
MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
|
||||
MipsAsmParser::parseInvNum(OperandVector &Operands) {
|
||||
const MCExpr *IdVal;
|
||||
// If the first token is '$' we may have register operand.
|
||||
if (Parser.getTok().is(AsmToken::Dollar))
|
||||
@ -1917,7 +1906,7 @@ MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
|
||||
}
|
||||
|
||||
MipsAsmParser::OperandMatchResultTy
|
||||
MipsAsmParser::ParseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
|
||||
MipsAsmParser::ParseLSAImm(OperandVector &Operands) {
|
||||
switch (getLexer().getKind()) {
|
||||
default:
|
||||
return MatchOperand_NoMatch;
|
||||
@ -1996,8 +1985,7 @@ MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
|
||||
/// ::= '(', register, ')'
|
||||
/// handle it before we iterate so we don't get tripped up by the lack of
|
||||
/// a comma.
|
||||
bool MipsAsmParser::ParseParenSuffix(
|
||||
StringRef Name, SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
|
||||
bool MipsAsmParser::ParseParenSuffix(StringRef Name, OperandVector &Operands) {
|
||||
if (getLexer().is(AsmToken::LParen)) {
|
||||
Operands.push_back(
|
||||
MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
|
||||
@ -2025,8 +2013,8 @@ bool MipsAsmParser::ParseParenSuffix(
|
||||
/// ::= '[', integer, ']'
|
||||
/// handle it before we iterate so we don't get tripped up by the lack of
|
||||
/// a comma.
|
||||
bool MipsAsmParser::ParseBracketSuffix(
|
||||
StringRef Name, SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
|
||||
bool MipsAsmParser::ParseBracketSuffix(StringRef Name,
|
||||
OperandVector &Operands) {
|
||||
if (getLexer().is(AsmToken::LBrac)) {
|
||||
Operands.push_back(
|
||||
MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
|
||||
@ -2048,9 +2036,8 @@ bool MipsAsmParser::ParseBracketSuffix(
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MipsAsmParser::ParseInstruction(
|
||||
ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
|
||||
SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
|
||||
bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
|
||||
SMLoc NameLoc, OperandVector &Operands) {
|
||||
DEBUG(dbgs() << "ParseInstruction\n");
|
||||
// Check if we have valid mnemonic
|
||||
if (!mnemonicIsValid(Name, 0)) {
|
||||
@ -2332,21 +2319,20 @@ bool MipsAsmParser::parseDirectiveCPLoad(SMLoc Loc) {
|
||||
|
||||
// FIXME: Warn if cpload is used in Mips16 mode.
|
||||
|
||||
SmallVector<MCParsedAsmOperand *, 1> Reg;
|
||||
SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
|
||||
OperandMatchResultTy ResTy = ParseAnyRegister(Reg);
|
||||
if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
|
||||
reportParseError("expected register containing function address");
|
||||
return false;
|
||||
}
|
||||
|
||||
MipsOperand *RegOpnd = static_cast<MipsOperand *>(Reg[0]);
|
||||
if (!RegOpnd->isGPRAsmReg()) {
|
||||
reportParseError(RegOpnd->getStartLoc(), "invalid register");
|
||||
MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
|
||||
if (!RegOpnd.isGPRAsmReg()) {
|
||||
reportParseError(RegOpnd.getStartLoc(), "invalid register");
|
||||
return false;
|
||||
}
|
||||
|
||||
getTargetStreamer().emitDirectiveCpload(RegOpnd->getGPR32Reg());
|
||||
delete RegOpnd;
|
||||
getTargetStreamer().emitDirectiveCpload(RegOpnd.getGPR32Reg());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -238,7 +238,7 @@ class PPCAsmParser : public MCTargetAsmParser {
|
||||
bool ParseExpression(const MCExpr *&EVal);
|
||||
bool ParseDarwinExpression(const MCExpr *&EVal);
|
||||
|
||||
bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
|
||||
bool ParseOperand(OperandVector &Operands);
|
||||
|
||||
bool ParseDirectiveWord(unsigned Size, SMLoc L);
|
||||
bool ParseDirectiveTC(unsigned Size, SMLoc L);
|
||||
@ -246,12 +246,11 @@ class PPCAsmParser : public MCTargetAsmParser {
|
||||
bool ParseDarwinDirectiveMachine(SMLoc L);
|
||||
|
||||
bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||
MCStreamer &Out, unsigned &ErrorInfo,
|
||||
OperandVector &Operands, MCStreamer &Out,
|
||||
unsigned &ErrorInfo,
|
||||
bool MatchingInlineAsm) override;
|
||||
|
||||
void ProcessInstruction(MCInst &Inst,
|
||||
const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
|
||||
void ProcessInstruction(MCInst &Inst, const OperandVector &Ops);
|
||||
|
||||
/// @name Auto-generated Match Functions
|
||||
/// {
|
||||
@ -276,13 +275,12 @@ public:
|
||||
setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
|
||||
}
|
||||
|
||||
bool ParseInstruction(ParseInstructionInfo &Info,
|
||||
StringRef Name, SMLoc NameLoc,
|
||||
SmallVectorImpl<MCParsedAsmOperand*> &Operands) override;
|
||||
bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
|
||||
SMLoc NameLoc, OperandVector &Operands) override;
|
||||
|
||||
bool ParseDirective(AsmToken DirectiveID) override;
|
||||
|
||||
unsigned validateTargetOperandClass(MCParsedAsmOperand *Op,
|
||||
unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
|
||||
unsigned Kind) override;
|
||||
|
||||
const MCExpr *applyModifierToExpr(const MCExpr *E,
|
||||
@ -548,8 +546,9 @@ public:
|
||||
|
||||
void print(raw_ostream &OS) const override;
|
||||
|
||||
static PPCOperand *CreateToken(StringRef Str, SMLoc S, bool IsPPC64) {
|
||||
PPCOperand *Op = new PPCOperand(Token);
|
||||
static std::unique_ptr<PPCOperand> CreateToken(StringRef Str, SMLoc S,
|
||||
bool IsPPC64) {
|
||||
auto Op = make_unique<PPCOperand>(Token);
|
||||
Op->Tok.Data = Str.data();
|
||||
Op->Tok.Length = Str.size();
|
||||
Op->StartLoc = S;
|
||||
@ -558,22 +557,27 @@ public:
|
||||
return Op;
|
||||
}
|
||||
|
||||
static PPCOperand *CreateTokenWithStringCopy(StringRef Str, SMLoc S,
|
||||
bool IsPPC64) {
|
||||
static std::unique_ptr<PPCOperand>
|
||||
CreateTokenWithStringCopy(StringRef Str, SMLoc S, bool IsPPC64) {
|
||||
// Allocate extra memory for the string and copy it.
|
||||
// FIXME: This is incorrect, Operands are owned by unique_ptr with a default
|
||||
// deleter which will destroy them by simply using "delete", not correctly
|
||||
// calling operator delete on this extra memory after calling the dtor
|
||||
// explicitly.
|
||||
void *Mem = ::operator new(sizeof(PPCOperand) + Str.size());
|
||||
PPCOperand *Op = new (Mem) PPCOperand(Token);
|
||||
Op->Tok.Data = (const char *)(Op + 1);
|
||||
std::unique_ptr<PPCOperand> Op(new (Mem) PPCOperand(Token));
|
||||
Op->Tok.Data = (const char *)(Op.get() + 1);
|
||||
Op->Tok.Length = Str.size();
|
||||
std::memcpy((char *)(Op + 1), Str.data(), Str.size());
|
||||
std::memcpy((void *)Op->Tok.Data, Str.data(), Str.size());
|
||||
Op->StartLoc = S;
|
||||
Op->EndLoc = S;
|
||||
Op->IsPPC64 = IsPPC64;
|
||||
return Op;
|
||||
}
|
||||
|
||||
static PPCOperand *CreateImm(int64_t Val, SMLoc S, SMLoc E, bool IsPPC64) {
|
||||
PPCOperand *Op = new PPCOperand(Immediate);
|
||||
static std::unique_ptr<PPCOperand> CreateImm(int64_t Val, SMLoc S, SMLoc E,
|
||||
bool IsPPC64) {
|
||||
auto Op = make_unique<PPCOperand>(Immediate);
|
||||
Op->Imm.Val = Val;
|
||||
Op->StartLoc = S;
|
||||
Op->EndLoc = E;
|
||||
@ -581,9 +585,9 @@ public:
|
||||
return Op;
|
||||
}
|
||||
|
||||
static PPCOperand *CreateExpr(const MCExpr *Val,
|
||||
SMLoc S, SMLoc E, bool IsPPC64) {
|
||||
PPCOperand *Op = new PPCOperand(Expression);
|
||||
static std::unique_ptr<PPCOperand> CreateExpr(const MCExpr *Val, SMLoc S,
|
||||
SMLoc E, bool IsPPC64) {
|
||||
auto Op = make_unique<PPCOperand>(Expression);
|
||||
Op->Expr.Val = Val;
|
||||
Op->Expr.CRVal = EvaluateCRExpr(Val);
|
||||
Op->StartLoc = S;
|
||||
@ -592,9 +596,9 @@ public:
|
||||
return Op;
|
||||
}
|
||||
|
||||
static PPCOperand *CreateTLSReg(const MCSymbolRefExpr *Sym,
|
||||
SMLoc S, SMLoc E, bool IsPPC64) {
|
||||
PPCOperand *Op = new PPCOperand(TLSRegister);
|
||||
static std::unique_ptr<PPCOperand>
|
||||
CreateTLSReg(const MCSymbolRefExpr *Sym, SMLoc S, SMLoc E, bool IsPPC64) {
|
||||
auto Op = make_unique<PPCOperand>(TLSRegister);
|
||||
Op->TLSReg.Sym = Sym;
|
||||
Op->StartLoc = S;
|
||||
Op->EndLoc = E;
|
||||
@ -602,8 +606,8 @@ public:
|
||||
return Op;
|
||||
}
|
||||
|
||||
static PPCOperand *CreateFromMCExpr(const MCExpr *Val,
|
||||
SMLoc S, SMLoc E, bool IsPPC64) {
|
||||
static std::unique_ptr<PPCOperand>
|
||||
CreateFromMCExpr(const MCExpr *Val, SMLoc S, SMLoc E, bool IsPPC64) {
|
||||
if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Val))
|
||||
return CreateImm(CE->getValue(), S, E, IsPPC64);
|
||||
|
||||
@ -634,10 +638,8 @@ void PPCOperand::print(raw_ostream &OS) const {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PPCAsmParser::
|
||||
ProcessInstruction(MCInst &Inst,
|
||||
const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
void PPCAsmParser::ProcessInstruction(MCInst &Inst,
|
||||
const OperandVector &Operands) {
|
||||
int Opcode = Inst.getOpcode();
|
||||
switch (Opcode) {
|
||||
case PPC::LAx: {
|
||||
@ -917,11 +919,10 @@ ProcessInstruction(MCInst &Inst,
|
||||
}
|
||||
}
|
||||
|
||||
bool PPCAsmParser::
|
||||
MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||
MCStreamer &Out, unsigned &ErrorInfo,
|
||||
bool MatchingInlineAsm) {
|
||||
bool PPCAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
OperandVector &Operands,
|
||||
MCStreamer &Out, unsigned &ErrorInfo,
|
||||
bool MatchingInlineAsm) {
|
||||
MCInst Inst;
|
||||
|
||||
switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
|
||||
@ -942,7 +943,7 @@ MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
if (ErrorInfo >= Operands.size())
|
||||
return Error(IDLoc, "too few operands for instruction");
|
||||
|
||||
ErrorLoc = ((PPCOperand*)Operands[ErrorInfo])->getStartLoc();
|
||||
ErrorLoc = ((PPCOperand &)*Operands[ErrorInfo]).getStartLoc();
|
||||
if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
|
||||
}
|
||||
|
||||
@ -1216,12 +1217,10 @@ ParseDarwinExpression(const MCExpr *&EVal) {
|
||||
/// ParseOperand
|
||||
/// This handles registers in the form 'NN', '%rNN' for ELF platforms and
|
||||
/// rNN for MachO.
|
||||
bool PPCAsmParser::
|
||||
ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
bool PPCAsmParser::ParseOperand(OperandVector &Operands) {
|
||||
SMLoc S = Parser.getTok().getLoc();
|
||||
SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
|
||||
const MCExpr *EVal;
|
||||
PPCOperand *Op;
|
||||
|
||||
// Attempt to parse the next token as an immediate
|
||||
switch (getLexer().getKind()) {
|
||||
@ -1233,8 +1232,7 @@ ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
int64_t IntVal;
|
||||
if (!MatchRegisterName(Parser.getTok(), RegNo, IntVal)) {
|
||||
Parser.Lex(); // Eat the identifier token.
|
||||
Op = PPCOperand::CreateImm(IntVal, S, E, isPPC64());
|
||||
Operands.push_back(Op);
|
||||
Operands.push_back(PPCOperand::CreateImm(IntVal, S, E, isPPC64()));
|
||||
return false;
|
||||
}
|
||||
return Error(S, "invalid register name");
|
||||
@ -1249,8 +1247,7 @@ ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
int64_t IntVal;
|
||||
if (!MatchRegisterName(Parser.getTok(), RegNo, IntVal)) {
|
||||
Parser.Lex(); // Eat the identifier token.
|
||||
Op = PPCOperand::CreateImm(IntVal, S, E, isPPC64());
|
||||
Operands.push_back(Op);
|
||||
Operands.push_back(PPCOperand::CreateImm(IntVal, S, E, isPPC64()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1272,8 +1269,7 @@ ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
}
|
||||
|
||||
// Push the parsed operand into the list of operands
|
||||
Op = PPCOperand::CreateFromMCExpr(EVal, S, E, isPPC64());
|
||||
Operands.push_back(Op);
|
||||
Operands.push_back(PPCOperand::CreateFromMCExpr(EVal, S, E, isPPC64()));
|
||||
|
||||
// Check whether this is a TLS call expression
|
||||
bool TLSCall = false;
|
||||
@ -1292,8 +1288,7 @@ ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
E = Parser.getTok().getLoc();
|
||||
Parser.Lex(); // Eat the ')'.
|
||||
|
||||
Op = PPCOperand::CreateFromMCExpr(TLSSym, S, E, isPPC64());
|
||||
Operands.push_back(Op);
|
||||
Operands.push_back(PPCOperand::CreateFromMCExpr(TLSSym, S, E, isPPC64()));
|
||||
}
|
||||
|
||||
// Otherwise, check for D-form memory operands
|
||||
@ -1340,17 +1335,15 @@ ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
E = Parser.getTok().getLoc();
|
||||
Parser.Lex(); // Eat the ')'.
|
||||
|
||||
Op = PPCOperand::CreateImm(IntVal, S, E, isPPC64());
|
||||
Operands.push_back(Op);
|
||||
Operands.push_back(PPCOperand::CreateImm(IntVal, S, E, isPPC64()));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Parse an instruction mnemonic followed by its operands.
|
||||
bool PPCAsmParser::
|
||||
ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
|
||||
SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
bool PPCAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
|
||||
SMLoc NameLoc, OperandVector &Operands) {
|
||||
// The first operand is the token for the instruction name.
|
||||
// If the next character is a '+' or '-', we need to add it to the
|
||||
// instruction name, to match what TableGen is doing.
|
||||
@ -1554,7 +1547,7 @@ extern "C" void LLVMInitializePowerPCAsmParser() {
|
||||
|
||||
// Define this matcher function after the auto-generated include so we
|
||||
// have the match class enum definitions.
|
||||
unsigned PPCAsmParser::validateTargetOperandClass(MCParsedAsmOperand *AsmOp,
|
||||
unsigned PPCAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
|
||||
unsigned Kind) {
|
||||
// If the kind is a token for a literal immediate, check if our asm
|
||||
// operand matches. This is for InstAliases which have a fixed-value
|
||||
@ -1568,8 +1561,8 @@ unsigned PPCAsmParser::validateTargetOperandClass(MCParsedAsmOperand *AsmOp,
|
||||
default: return Match_InvalidOperand;
|
||||
}
|
||||
|
||||
PPCOperand *Op = static_cast<PPCOperand*>(AsmOp);
|
||||
if (Op->isImm() && Op->getImm() == ImmVal)
|
||||
PPCOperand &Op = static_cast<PPCOperand &>(AsmOp);
|
||||
if (Op.isImm() && Op.getImm() == ImmVal)
|
||||
return Match_Success;
|
||||
|
||||
return Match_InvalidOperand;
|
||||
|
@ -47,31 +47,27 @@ class SparcAsmParser : public MCTargetAsmParser {
|
||||
|
||||
// public interface of the MCTargetAsmParser.
|
||||
bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||
MCStreamer &Out, unsigned &ErrorInfo,
|
||||
OperandVector &Operands, MCStreamer &Out,
|
||||
unsigned &ErrorInfo,
|
||||
bool MatchingInlineAsm) override;
|
||||
bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
|
||||
bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
|
||||
SMLoc NameLoc,
|
||||
SmallVectorImpl<MCParsedAsmOperand*> &Operands) override;
|
||||
SMLoc NameLoc, OperandVector &Operands) override;
|
||||
bool ParseDirective(AsmToken DirectiveID) override;
|
||||
|
||||
unsigned validateTargetOperandClass(MCParsedAsmOperand *Op,
|
||||
unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
|
||||
unsigned Kind) override;
|
||||
|
||||
// Custom parse functions for Sparc specific operands.
|
||||
OperandMatchResultTy
|
||||
parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
|
||||
OperandMatchResultTy parseMEMOperand(OperandVector &Operands);
|
||||
|
||||
OperandMatchResultTy parseOperand(OperandVector &Operands, StringRef Name);
|
||||
|
||||
OperandMatchResultTy
|
||||
parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||
StringRef Name);
|
||||
parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Operand,
|
||||
bool isCall = false);
|
||||
|
||||
OperandMatchResultTy
|
||||
parseSparcAsmOperand(SparcOperand *&Operand, bool isCall = false);
|
||||
|
||||
OperandMatchResultTy
|
||||
parseBranchModifiers(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
|
||||
OperandMatchResultTy parseBranchModifiers(OperandVector &Operands);
|
||||
|
||||
// returns true if Tok is matched to a register and returns register in RegNo.
|
||||
bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo,
|
||||
@ -153,8 +149,6 @@ private:
|
||||
|
||||
SMLoc StartLoc, EndLoc;
|
||||
|
||||
SparcOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
|
||||
|
||||
struct Token {
|
||||
const char *Data;
|
||||
unsigned Length;
|
||||
@ -182,6 +176,8 @@ private:
|
||||
struct MemOp Mem;
|
||||
};
|
||||
public:
|
||||
SparcOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
|
||||
|
||||
bool isToken() const override { return Kind == k_Token; }
|
||||
bool isReg() const override { return Kind == k_Register; }
|
||||
bool isImm() const override { return Kind == k_Immediate; }
|
||||
@ -291,8 +287,8 @@ public:
|
||||
addExpr(Inst, Expr);
|
||||
}
|
||||
|
||||
static SparcOperand *CreateToken(StringRef Str, SMLoc S) {
|
||||
SparcOperand *Op = new SparcOperand(k_Token);
|
||||
static std::unique_ptr<SparcOperand> CreateToken(StringRef Str, SMLoc S) {
|
||||
auto Op = make_unique<SparcOperand>(k_Token);
|
||||
Op->Tok.Data = Str.data();
|
||||
Op->Tok.Length = Str.size();
|
||||
Op->StartLoc = S;
|
||||
@ -300,10 +296,9 @@ public:
|
||||
return Op;
|
||||
}
|
||||
|
||||
static SparcOperand *CreateReg(unsigned RegNum,
|
||||
unsigned Kind,
|
||||
SMLoc S, SMLoc E) {
|
||||
SparcOperand *Op = new SparcOperand(k_Register);
|
||||
static std::unique_ptr<SparcOperand> CreateReg(unsigned RegNum, unsigned Kind,
|
||||
SMLoc S, SMLoc E) {
|
||||
auto Op = make_unique<SparcOperand>(k_Register);
|
||||
Op->Reg.RegNum = RegNum;
|
||||
Op->Reg.Kind = (SparcOperand::RegisterKind)Kind;
|
||||
Op->StartLoc = S;
|
||||
@ -311,49 +306,51 @@ public:
|
||||
return Op;
|
||||
}
|
||||
|
||||
static SparcOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
|
||||
SparcOperand *Op = new SparcOperand(k_Immediate);
|
||||
static std::unique_ptr<SparcOperand> CreateImm(const MCExpr *Val, SMLoc S,
|
||||
SMLoc E) {
|
||||
auto Op = make_unique<SparcOperand>(k_Immediate);
|
||||
Op->Imm.Val = Val;
|
||||
Op->StartLoc = S;
|
||||
Op->EndLoc = E;
|
||||
return Op;
|
||||
}
|
||||
|
||||
static SparcOperand *MorphToDoubleReg(SparcOperand *Op) {
|
||||
unsigned Reg = Op->getReg();
|
||||
assert(Op->Reg.Kind == rk_FloatReg);
|
||||
static bool MorphToDoubleReg(SparcOperand &Op) {
|
||||
unsigned Reg = Op.getReg();
|
||||
assert(Op.Reg.Kind == rk_FloatReg);
|
||||
unsigned regIdx = Reg - Sparc::F0;
|
||||
if (regIdx % 2 || regIdx > 31)
|
||||
return nullptr;
|
||||
Op->Reg.RegNum = DoubleRegs[regIdx / 2];
|
||||
Op->Reg.Kind = rk_DoubleReg;
|
||||
return Op;
|
||||
return false;
|
||||
Op.Reg.RegNum = DoubleRegs[regIdx / 2];
|
||||
Op.Reg.Kind = rk_DoubleReg;
|
||||
return true;
|
||||
}
|
||||
|
||||
static SparcOperand *MorphToQuadReg(SparcOperand *Op) {
|
||||
unsigned Reg = Op->getReg();
|
||||
static bool MorphToQuadReg(SparcOperand &Op) {
|
||||
unsigned Reg = Op.getReg();
|
||||
unsigned regIdx = 0;
|
||||
switch (Op->Reg.Kind) {
|
||||
switch (Op.Reg.Kind) {
|
||||
default: assert(0 && "Unexpected register kind!");
|
||||
case rk_FloatReg:
|
||||
regIdx = Reg - Sparc::F0;
|
||||
if (regIdx % 4 || regIdx > 31)
|
||||
return nullptr;
|
||||
return false;
|
||||
Reg = QuadFPRegs[regIdx / 4];
|
||||
break;
|
||||
case rk_DoubleReg:
|
||||
regIdx = Reg - Sparc::D0;
|
||||
if (regIdx % 2 || regIdx > 31)
|
||||
return nullptr;
|
||||
return false;
|
||||
Reg = QuadFPRegs[regIdx / 2];
|
||||
break;
|
||||
}
|
||||
Op->Reg.RegNum = Reg;
|
||||
Op->Reg.Kind = rk_QuadReg;
|
||||
return Op;
|
||||
Op.Reg.RegNum = Reg;
|
||||
Op.Reg.Kind = rk_QuadReg;
|
||||
return true;
|
||||
}
|
||||
|
||||
static SparcOperand *MorphToMEMrr(unsigned Base, SparcOperand *Op) {
|
||||
static std::unique_ptr<SparcOperand>
|
||||
MorphToMEMrr(unsigned Base, std::unique_ptr<SparcOperand> Op) {
|
||||
unsigned offsetReg = Op->getReg();
|
||||
Op->Kind = k_MemoryReg;
|
||||
Op->Mem.Base = Base;
|
||||
@ -362,10 +359,9 @@ public:
|
||||
return Op;
|
||||
}
|
||||
|
||||
static SparcOperand *CreateMEMri(unsigned Base,
|
||||
const MCExpr *Off,
|
||||
SMLoc S, SMLoc E) {
|
||||
SparcOperand *Op = new SparcOperand(k_MemoryImm);
|
||||
static std::unique_ptr<SparcOperand>
|
||||
CreateMEMri(unsigned Base, const MCExpr *Off, SMLoc S, SMLoc E) {
|
||||
auto Op = make_unique<SparcOperand>(k_MemoryImm);
|
||||
Op->Mem.Base = Base;
|
||||
Op->Mem.OffsetReg = 0;
|
||||
Op->Mem.Off = Off;
|
||||
@ -374,7 +370,8 @@ public:
|
||||
return Op;
|
||||
}
|
||||
|
||||
static SparcOperand *MorphToMEMri(unsigned Base, SparcOperand *Op) {
|
||||
static std::unique_ptr<SparcOperand>
|
||||
MorphToMEMri(unsigned Base, std::unique_ptr<SparcOperand> Op) {
|
||||
const MCExpr *Imm = Op->getImm();
|
||||
Op->Kind = k_MemoryImm;
|
||||
Op->Mem.Base = Base;
|
||||
@ -386,11 +383,11 @@ public:
|
||||
|
||||
} // end namespace
|
||||
|
||||
bool SparcAsmParser::
|
||||
MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||
MCStreamer &Out, unsigned &ErrorInfo,
|
||||
bool MatchingInlineAsm) {
|
||||
bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
OperandVector &Operands,
|
||||
MCStreamer &Out,
|
||||
unsigned &ErrorInfo,
|
||||
bool MatchingInlineAsm) {
|
||||
MCInst Inst;
|
||||
SmallVector<MCInst, 8> Instructions;
|
||||
unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
|
||||
@ -415,7 +412,7 @@ MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
if (ErrorInfo >= Operands.size())
|
||||
return Error(IDLoc, "too few operands for instruction");
|
||||
|
||||
ErrorLoc = ((SparcOperand*) Operands[ErrorInfo])->getStartLoc();
|
||||
ErrorLoc = ((SparcOperand &)*Operands[ErrorInfo]).getStartLoc();
|
||||
if (ErrorLoc == SMLoc())
|
||||
ErrorLoc = IDLoc;
|
||||
}
|
||||
@ -450,11 +447,9 @@ ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc)
|
||||
static void applyMnemonicAliases(StringRef &Mnemonic, unsigned Features,
|
||||
unsigned VariantID);
|
||||
|
||||
bool SparcAsmParser::
|
||||
ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
|
||||
SMLoc NameLoc,
|
||||
SmallVectorImpl<MCParsedAsmOperand*> &Operands)
|
||||
{
|
||||
bool SparcAsmParser::ParseInstruction(ParseInstructionInfo &Info,
|
||||
StringRef Name, SMLoc NameLoc,
|
||||
OperandVector &Operands) {
|
||||
|
||||
// First operand in MCInst is instruction mnemonic.
|
||||
Operands.push_back(SparcOperand::CreateToken(Name, NameLoc));
|
||||
@ -548,9 +543,8 @@ bool SparcAsmParser:: parseDirectiveWord(unsigned Size, SMLoc L) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SparcAsmParser::OperandMatchResultTy SparcAsmParser::
|
||||
parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands)
|
||||
{
|
||||
SparcAsmParser::OperandMatchResultTy
|
||||
SparcAsmParser::parseMEMOperand(OperandVector &Operands) {
|
||||
|
||||
SMLoc S, E;
|
||||
unsigned BaseReg = 0;
|
||||
@ -575,23 +569,20 @@ parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands)
|
||||
break;
|
||||
}
|
||||
|
||||
SparcOperand *Offset = nullptr;
|
||||
std::unique_ptr<SparcOperand> Offset;
|
||||
OperandMatchResultTy ResTy = parseSparcAsmOperand(Offset);
|
||||
if (ResTy != MatchOperand_Success || !Offset)
|
||||
return MatchOperand_NoMatch;
|
||||
|
||||
Offset = (Offset->isImm()
|
||||
? SparcOperand::MorphToMEMri(BaseReg, Offset)
|
||||
: SparcOperand::MorphToMEMrr(BaseReg, Offset));
|
||||
Operands.push_back(
|
||||
Offset->isImm() ? SparcOperand::MorphToMEMri(BaseReg, std::move(Offset))
|
||||
: SparcOperand::MorphToMEMrr(BaseReg, std::move(Offset)));
|
||||
|
||||
Operands.push_back(Offset);
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
|
||||
SparcAsmParser::OperandMatchResultTy SparcAsmParser::
|
||||
parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||
StringRef Mnemonic)
|
||||
{
|
||||
SparcAsmParser::OperandMatchResultTy
|
||||
SparcAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
|
||||
|
||||
OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
|
||||
|
||||
@ -637,21 +628,21 @@ parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
|
||||
SparcOperand *Op = nullptr;
|
||||
std::unique_ptr<SparcOperand> Op;
|
||||
|
||||
ResTy = parseSparcAsmOperand(Op, (Mnemonic == "call"));
|
||||
if (ResTy != MatchOperand_Success || !Op)
|
||||
return MatchOperand_ParseFail;
|
||||
|
||||
// Push the parsed operand into the list of operands
|
||||
Operands.push_back(Op);
|
||||
Operands.push_back(std::move(Op));
|
||||
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
|
||||
SparcAsmParser::OperandMatchResultTy
|
||||
SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op, bool isCall)
|
||||
{
|
||||
SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op,
|
||||
bool isCall) {
|
||||
|
||||
SMLoc S = Parser.getTok().getLoc();
|
||||
SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
|
||||
@ -718,8 +709,8 @@ SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op, bool isCall)
|
||||
return (Op) ? MatchOperand_Success : MatchOperand_ParseFail;
|
||||
}
|
||||
|
||||
SparcAsmParser::OperandMatchResultTy SparcAsmParser::
|
||||
parseBranchModifiers(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
SparcAsmParser::OperandMatchResultTy
|
||||
SparcAsmParser::parseBranchModifiers(OperandVector &Operands) {
|
||||
|
||||
// parse (,a|,pn|,pt)+
|
||||
|
||||
@ -928,18 +919,14 @@ extern "C" void LLVMInitializeSparcAsmParser() {
|
||||
#define GET_MATCHER_IMPLEMENTATION
|
||||
#include "SparcGenAsmMatcher.inc"
|
||||
|
||||
|
||||
|
||||
unsigned SparcAsmParser::
|
||||
validateTargetOperandClass(MCParsedAsmOperand *GOp,
|
||||
unsigned Kind)
|
||||
{
|
||||
SparcOperand *Op = (SparcOperand*)GOp;
|
||||
if (Op->isFloatOrDoubleReg()) {
|
||||
unsigned SparcAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp,
|
||||
unsigned Kind) {
|
||||
SparcOperand &Op = (SparcOperand &)GOp;
|
||||
if (Op.isFloatOrDoubleReg()) {
|
||||
switch (Kind) {
|
||||
default: break;
|
||||
case MCK_DFPRegs:
|
||||
if (!Op->isFloatReg() || SparcOperand::MorphToDoubleReg(Op))
|
||||
if (!Op.isFloatReg() || SparcOperand::MorphToDoubleReg(Op))
|
||||
return MCTargetAsmParser::Match_Success;
|
||||
break;
|
||||
case MCK_QFPRegs:
|
||||
|
@ -104,10 +104,6 @@ private:
|
||||
MemOp Mem;
|
||||
};
|
||||
|
||||
SystemZOperand(OperandKind kind, SMLoc startLoc, SMLoc endLoc)
|
||||
: Kind(kind), StartLoc(startLoc), EndLoc(endLoc)
|
||||
{}
|
||||
|
||||
void addExpr(MCInst &Inst, const MCExpr *Expr) const {
|
||||
// Add as immediates when possible. Null MCExpr = 0.
|
||||
if (!Expr)
|
||||
@ -119,40 +115,44 @@ private:
|
||||
}
|
||||
|
||||
public:
|
||||
SystemZOperand(OperandKind kind, SMLoc startLoc, SMLoc endLoc)
|
||||
: Kind(kind), StartLoc(startLoc), EndLoc(endLoc) {}
|
||||
|
||||
// Create particular kinds of operand.
|
||||
static SystemZOperand *createInvalid(SMLoc StartLoc, SMLoc EndLoc) {
|
||||
return new SystemZOperand(KindInvalid, StartLoc, EndLoc);
|
||||
static std::unique_ptr<SystemZOperand> createInvalid(SMLoc StartLoc,
|
||||
SMLoc EndLoc) {
|
||||
return make_unique<SystemZOperand>(KindInvalid, StartLoc, EndLoc);
|
||||
}
|
||||
static SystemZOperand *createToken(StringRef Str, SMLoc Loc) {
|
||||
SystemZOperand *Op = new SystemZOperand(KindToken, Loc, Loc);
|
||||
static std::unique_ptr<SystemZOperand> createToken(StringRef Str, SMLoc Loc) {
|
||||
auto Op = make_unique<SystemZOperand>(KindToken, Loc, Loc);
|
||||
Op->Token.Data = Str.data();
|
||||
Op->Token.Length = Str.size();
|
||||
return Op;
|
||||
}
|
||||
static SystemZOperand *createReg(RegisterKind Kind, unsigned Num,
|
||||
SMLoc StartLoc, SMLoc EndLoc) {
|
||||
SystemZOperand *Op = new SystemZOperand(KindReg, StartLoc, EndLoc);
|
||||
static std::unique_ptr<SystemZOperand>
|
||||
createReg(RegisterKind Kind, unsigned Num, SMLoc StartLoc, SMLoc EndLoc) {
|
||||
auto Op = make_unique<SystemZOperand>(KindReg, StartLoc, EndLoc);
|
||||
Op->Reg.Kind = Kind;
|
||||
Op->Reg.Num = Num;
|
||||
return Op;
|
||||
}
|
||||
static SystemZOperand *createAccessReg(unsigned Num, SMLoc StartLoc,
|
||||
SMLoc EndLoc) {
|
||||
SystemZOperand *Op = new SystemZOperand(KindAccessReg, StartLoc, EndLoc);
|
||||
static std::unique_ptr<SystemZOperand>
|
||||
createAccessReg(unsigned Num, SMLoc StartLoc, SMLoc EndLoc) {
|
||||
auto Op = make_unique<SystemZOperand>(KindAccessReg, StartLoc, EndLoc);
|
||||
Op->AccessReg = Num;
|
||||
return Op;
|
||||
}
|
||||
static SystemZOperand *createImm(const MCExpr *Expr, SMLoc StartLoc,
|
||||
SMLoc EndLoc) {
|
||||
SystemZOperand *Op = new SystemZOperand(KindImm, StartLoc, EndLoc);
|
||||
static std::unique_ptr<SystemZOperand>
|
||||
createImm(const MCExpr *Expr, SMLoc StartLoc, SMLoc EndLoc) {
|
||||
auto Op = make_unique<SystemZOperand>(KindImm, StartLoc, EndLoc);
|
||||
Op->Imm = Expr;
|
||||
return Op;
|
||||
}
|
||||
static SystemZOperand *createMem(RegisterKind RegKind, unsigned Base,
|
||||
const MCExpr *Disp, unsigned Index,
|
||||
const MCExpr *Length, SMLoc StartLoc,
|
||||
SMLoc EndLoc) {
|
||||
SystemZOperand *Op = new SystemZOperand(KindMem, StartLoc, EndLoc);
|
||||
static std::unique_ptr<SystemZOperand>
|
||||
createMem(RegisterKind RegKind, unsigned Base, const MCExpr *Disp,
|
||||
unsigned Index, const MCExpr *Length, SMLoc StartLoc,
|
||||
SMLoc EndLoc) {
|
||||
auto Op = make_unique<SystemZOperand>(KindMem, StartLoc, EndLoc);
|
||||
Op->Mem.RegKind = RegKind;
|
||||
Op->Mem.Base = Base;
|
||||
Op->Mem.Index = Index;
|
||||
@ -313,21 +313,19 @@ private:
|
||||
bool parseRegister(Register &Reg, RegisterGroup Group, const unsigned *Regs,
|
||||
bool IsAddress = false);
|
||||
|
||||
OperandMatchResultTy
|
||||
parseRegister(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||
RegisterGroup Group, const unsigned *Regs, RegisterKind Kind);
|
||||
OperandMatchResultTy parseRegister(OperandVector &Operands,
|
||||
RegisterGroup Group, const unsigned *Regs,
|
||||
RegisterKind Kind);
|
||||
|
||||
bool parseAddress(unsigned &Base, const MCExpr *&Disp,
|
||||
unsigned &Index, const MCExpr *&Length,
|
||||
const unsigned *Regs, RegisterKind RegKind);
|
||||
|
||||
OperandMatchResultTy
|
||||
parseAddress(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||
const unsigned *Regs, RegisterKind RegKind,
|
||||
MemoryKind MemKind);
|
||||
OperandMatchResultTy parseAddress(OperandVector &Operands,
|
||||
const unsigned *Regs, RegisterKind RegKind,
|
||||
MemoryKind MemKind);
|
||||
|
||||
bool parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||
StringRef Mnemonic);
|
||||
bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
|
||||
|
||||
public:
|
||||
SystemZAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
|
||||
@ -343,87 +341,66 @@ public:
|
||||
// Override MCTargetAsmParser.
|
||||
bool ParseDirective(AsmToken DirectiveID) override;
|
||||
bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
|
||||
bool ParseInstruction(ParseInstructionInfo &Info,
|
||||
StringRef Name, SMLoc NameLoc,
|
||||
SmallVectorImpl<MCParsedAsmOperand*> &Operands)
|
||||
override;
|
||||
bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
|
||||
SMLoc NameLoc, OperandVector &Operands) override;
|
||||
bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||
MCStreamer &Out, unsigned &ErrorInfo,
|
||||
OperandVector &Operands, MCStreamer &Out,
|
||||
unsigned &ErrorInfo,
|
||||
bool MatchingInlineAsm) override;
|
||||
|
||||
// Used by the TableGen code to parse particular operand types.
|
||||
OperandMatchResultTy
|
||||
parseGR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
OperandMatchResultTy parseGR32(OperandVector &Operands) {
|
||||
return parseRegister(Operands, RegGR, SystemZMC::GR32Regs, GR32Reg);
|
||||
}
|
||||
OperandMatchResultTy
|
||||
parseGRH32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
OperandMatchResultTy parseGRH32(OperandVector &Operands) {
|
||||
return parseRegister(Operands, RegGR, SystemZMC::GRH32Regs, GRH32Reg);
|
||||
}
|
||||
OperandMatchResultTy
|
||||
parseGRX32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
OperandMatchResultTy parseGRX32(OperandVector &Operands) {
|
||||
llvm_unreachable("GRX32 should only be used for pseudo instructions");
|
||||
}
|
||||
OperandMatchResultTy
|
||||
parseGR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
OperandMatchResultTy parseGR64(OperandVector &Operands) {
|
||||
return parseRegister(Operands, RegGR, SystemZMC::GR64Regs, GR64Reg);
|
||||
}
|
||||
OperandMatchResultTy
|
||||
parseGR128(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
OperandMatchResultTy parseGR128(OperandVector &Operands) {
|
||||
return parseRegister(Operands, RegGR, SystemZMC::GR128Regs, GR128Reg);
|
||||
}
|
||||
OperandMatchResultTy
|
||||
parseADDR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
OperandMatchResultTy parseADDR32(OperandVector &Operands) {
|
||||
return parseRegister(Operands, RegGR, SystemZMC::GR32Regs, ADDR32Reg);
|
||||
}
|
||||
OperandMatchResultTy
|
||||
parseADDR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
OperandMatchResultTy parseADDR64(OperandVector &Operands) {
|
||||
return parseRegister(Operands, RegGR, SystemZMC::GR64Regs, ADDR64Reg);
|
||||
}
|
||||
OperandMatchResultTy
|
||||
parseADDR128(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
OperandMatchResultTy parseADDR128(OperandVector &Operands) {
|
||||
llvm_unreachable("Shouldn't be used as an operand");
|
||||
}
|
||||
OperandMatchResultTy
|
||||
parseFP32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
OperandMatchResultTy parseFP32(OperandVector &Operands) {
|
||||
return parseRegister(Operands, RegFP, SystemZMC::FP32Regs, FP32Reg);
|
||||
}
|
||||
OperandMatchResultTy
|
||||
parseFP64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
OperandMatchResultTy parseFP64(OperandVector &Operands) {
|
||||
return parseRegister(Operands, RegFP, SystemZMC::FP64Regs, FP64Reg);
|
||||
}
|
||||
OperandMatchResultTy
|
||||
parseFP128(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
OperandMatchResultTy parseFP128(OperandVector &Operands) {
|
||||
return parseRegister(Operands, RegFP, SystemZMC::FP128Regs, FP128Reg);
|
||||
}
|
||||
OperandMatchResultTy
|
||||
parseBDAddr32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
OperandMatchResultTy parseBDAddr32(OperandVector &Operands) {
|
||||
return parseAddress(Operands, SystemZMC::GR32Regs, ADDR32Reg, BDMem);
|
||||
}
|
||||
OperandMatchResultTy
|
||||
parseBDAddr64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
OperandMatchResultTy parseBDAddr64(OperandVector &Operands) {
|
||||
return parseAddress(Operands, SystemZMC::GR64Regs, ADDR64Reg, BDMem);
|
||||
}
|
||||
OperandMatchResultTy
|
||||
parseBDXAddr64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
OperandMatchResultTy parseBDXAddr64(OperandVector &Operands) {
|
||||
return parseAddress(Operands, SystemZMC::GR64Regs, ADDR64Reg, BDXMem);
|
||||
}
|
||||
OperandMatchResultTy
|
||||
parseBDLAddr64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
OperandMatchResultTy parseBDLAddr64(OperandVector &Operands) {
|
||||
return parseAddress(Operands, SystemZMC::GR64Regs, ADDR64Reg, BDLMem);
|
||||
}
|
||||
OperandMatchResultTy
|
||||
parseAccessReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
|
||||
OperandMatchResultTy
|
||||
parsePCRel(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||
int64_t MinVal, int64_t MaxVal);
|
||||
OperandMatchResultTy
|
||||
parsePCRel16(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
OperandMatchResultTy parseAccessReg(OperandVector &Operands);
|
||||
OperandMatchResultTy parsePCRel(OperandVector &Operands, int64_t MinVal,
|
||||
int64_t MaxVal);
|
||||
OperandMatchResultTy parsePCRel16(OperandVector &Operands) {
|
||||
return parsePCRel(Operands, -(1LL << 16), (1LL << 16) - 1);
|
||||
}
|
||||
OperandMatchResultTy
|
||||
parsePCRel32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
OperandMatchResultTy parsePCRel32(OperandVector &Operands) {
|
||||
return parsePCRel(Operands, -(1LL << 32), (1LL << 32) - 1);
|
||||
}
|
||||
};
|
||||
@ -497,9 +474,8 @@ bool SystemZAsmParser::parseRegister(Register &Reg, RegisterGroup Group,
|
||||
|
||||
// Parse a register and add it to Operands. The other arguments are as above.
|
||||
SystemZAsmParser::OperandMatchResultTy
|
||||
SystemZAsmParser::parseRegister(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||
RegisterGroup Group, const unsigned *Regs,
|
||||
RegisterKind Kind) {
|
||||
SystemZAsmParser::parseRegister(OperandVector &Operands, RegisterGroup Group,
|
||||
const unsigned *Regs, RegisterKind Kind) {
|
||||
if (Parser.getTok().isNot(AsmToken::Percent))
|
||||
return MatchOperand_NoMatch;
|
||||
|
||||
@ -566,9 +542,8 @@ bool SystemZAsmParser::parseAddress(unsigned &Base, const MCExpr *&Disp,
|
||||
// Parse a memory operand and add it to Operands. The other arguments
|
||||
// are as above.
|
||||
SystemZAsmParser::OperandMatchResultTy
|
||||
SystemZAsmParser::parseAddress(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||
const unsigned *Regs, RegisterKind RegKind,
|
||||
MemoryKind MemKind) {
|
||||
SystemZAsmParser::parseAddress(OperandVector &Operands, const unsigned *Regs,
|
||||
RegisterKind RegKind, MemoryKind MemKind) {
|
||||
SMLoc StartLoc = Parser.getTok().getLoc();
|
||||
unsigned Base, Index;
|
||||
const MCExpr *Disp;
|
||||
@ -622,9 +597,9 @@ bool SystemZAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SystemZAsmParser::
|
||||
ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
|
||||
SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
bool SystemZAsmParser::ParseInstruction(ParseInstructionInfo &Info,
|
||||
StringRef Name, SMLoc NameLoc,
|
||||
OperandVector &Operands) {
|
||||
Operands.push_back(SystemZOperand::createToken(Name, NameLoc));
|
||||
|
||||
// Read the remaining operands.
|
||||
@ -655,9 +630,8 @@ ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SystemZAsmParser::
|
||||
parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||
StringRef Mnemonic) {
|
||||
bool SystemZAsmParser::parseOperand(OperandVector &Operands,
|
||||
StringRef Mnemonic) {
|
||||
// Check if the current operand has a custom associated parser, if so, try to
|
||||
// custom parse the operand, or fallback to the general approach.
|
||||
OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
|
||||
@ -700,11 +674,11 @@ parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SystemZAsmParser::
|
||||
MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||
MCStreamer &Out, unsigned &ErrorInfo,
|
||||
bool MatchingInlineAsm) {
|
||||
bool SystemZAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
OperandVector &Operands,
|
||||
MCStreamer &Out,
|
||||
unsigned &ErrorInfo,
|
||||
bool MatchingInlineAsm) {
|
||||
MCInst Inst;
|
||||
unsigned MatchResult;
|
||||
|
||||
@ -739,7 +713,7 @@ MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
if (ErrorInfo >= Operands.size())
|
||||
return Error(IDLoc, "too few operands for instruction");
|
||||
|
||||
ErrorLoc = ((SystemZOperand*)Operands[ErrorInfo])->getStartLoc();
|
||||
ErrorLoc = ((SystemZOperand &)*Operands[ErrorInfo]).getStartLoc();
|
||||
if (ErrorLoc == SMLoc())
|
||||
ErrorLoc = IDLoc;
|
||||
}
|
||||
@ -753,8 +727,8 @@ MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
llvm_unreachable("Unexpected match type");
|
||||
}
|
||||
|
||||
SystemZAsmParser::OperandMatchResultTy SystemZAsmParser::
|
||||
parseAccessReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
SystemZAsmParser::OperandMatchResultTy
|
||||
SystemZAsmParser::parseAccessReg(OperandVector &Operands) {
|
||||
if (Parser.getTok().isNot(AsmToken::Percent))
|
||||
return MatchOperand_NoMatch;
|
||||
|
||||
@ -768,9 +742,9 @@ parseAccessReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
|
||||
SystemZAsmParser::OperandMatchResultTy SystemZAsmParser::
|
||||
parsePCRel(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||
int64_t MinVal, int64_t MaxVal) {
|
||||
SystemZAsmParser::OperandMatchResultTy
|
||||
SystemZAsmParser::parsePCRel(OperandVector &Operands, int64_t MinVal,
|
||||
int64_t MaxVal) {
|
||||
MCContext &Ctx = getContext();
|
||||
MCStreamer &Out = getStreamer();
|
||||
const MCExpr *Expr;
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
|
||||
#include "llvm/MC/MCStreamer.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
#include "llvm/MC/MCTargetAsmParser.h"
|
||||
#include "llvm/MC/MCTargetOptions.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
|
||||
@ -46,21 +47,21 @@ public:
|
||||
virtual ~X86AddressSanitizer() {}
|
||||
|
||||
// X86AsmInstrumentation implementation:
|
||||
virtual void InstrumentInstruction(
|
||||
const MCInst &Inst, SmallVectorImpl<MCParsedAsmOperand *> &Operands,
|
||||
MCContext &Ctx, const MCInstrInfo &MII, MCStreamer &Out) override {
|
||||
virtual void InstrumentInstruction(const MCInst &Inst,
|
||||
OperandVector &Operands, MCContext &Ctx,
|
||||
const MCInstrInfo &MII,
|
||||
MCStreamer &Out) override {
|
||||
InstrumentMOV(Inst, Operands, Ctx, MII, Out);
|
||||
}
|
||||
|
||||
// Should be implemented differently in x86_32 and x86_64 subclasses.
|
||||
virtual void InstrumentMemOperandImpl(X86Operand *Op, unsigned AccessSize,
|
||||
virtual void InstrumentMemOperandImpl(X86Operand &Op, unsigned AccessSize,
|
||||
bool IsWrite, MCContext &Ctx,
|
||||
MCStreamer &Out) = 0;
|
||||
|
||||
void InstrumentMemOperand(MCParsedAsmOperand *Op, unsigned AccessSize,
|
||||
void InstrumentMemOperand(MCParsedAsmOperand &Op, unsigned AccessSize,
|
||||
bool IsWrite, MCContext &Ctx, MCStreamer &Out);
|
||||
void InstrumentMOV(const MCInst &Inst,
|
||||
SmallVectorImpl<MCParsedAsmOperand *> &Operands,
|
||||
void InstrumentMOV(const MCInst &Inst, OperandVector &Operands,
|
||||
MCContext &Ctx, const MCInstrInfo &MII, MCStreamer &Out);
|
||||
void EmitInstruction(MCStreamer &Out, const MCInst &Inst) {
|
||||
Out.EmitInstruction(Inst, STI);
|
||||
@ -70,24 +71,26 @@ protected:
|
||||
const MCSubtargetInfo &STI;
|
||||
};
|
||||
|
||||
void X86AddressSanitizer::InstrumentMemOperand(
|
||||
MCParsedAsmOperand *Op, unsigned AccessSize, bool IsWrite, MCContext &Ctx,
|
||||
MCStreamer &Out) {
|
||||
assert(Op && Op->isMem() && "Op should be a memory operand.");
|
||||
void X86AddressSanitizer::InstrumentMemOperand(MCParsedAsmOperand &Op,
|
||||
unsigned AccessSize,
|
||||
bool IsWrite, MCContext &Ctx,
|
||||
MCStreamer &Out) {
|
||||
assert(Op.isMem() && "Op should be a memory operand.");
|
||||
assert((AccessSize & (AccessSize - 1)) == 0 && AccessSize <= 16 &&
|
||||
"AccessSize should be a power of two, less or equal than 16.");
|
||||
|
||||
X86Operand *MemOp = static_cast<X86Operand *>(Op);
|
||||
X86Operand &MemOp = static_cast<X86Operand &>(Op);
|
||||
// FIXME: get rid of this limitation.
|
||||
if (IsStackReg(MemOp->getMemBaseReg()) || IsStackReg(MemOp->getMemIndexReg()))
|
||||
if (IsStackReg(MemOp.getMemBaseReg()) || IsStackReg(MemOp.getMemIndexReg()))
|
||||
return;
|
||||
|
||||
InstrumentMemOperandImpl(MemOp, AccessSize, IsWrite, Ctx, Out);
|
||||
}
|
||||
|
||||
void X86AddressSanitizer::InstrumentMOV(
|
||||
const MCInst &Inst, SmallVectorImpl<MCParsedAsmOperand *> &Operands,
|
||||
MCContext &Ctx, const MCInstrInfo &MII, MCStreamer &Out) {
|
||||
void X86AddressSanitizer::InstrumentMOV(const MCInst &Inst,
|
||||
OperandVector &Operands, MCContext &Ctx,
|
||||
const MCInstrInfo &MII,
|
||||
MCStreamer &Out) {
|
||||
// Access size in bytes.
|
||||
unsigned AccessSize = 0;
|
||||
|
||||
@ -124,8 +127,9 @@ void X86AddressSanitizer::InstrumentMOV(
|
||||
|
||||
const bool IsWrite = MII.get(Inst.getOpcode()).mayStore();
|
||||
for (unsigned Ix = 0; Ix < Operands.size(); ++Ix) {
|
||||
MCParsedAsmOperand *Op = Operands[Ix];
|
||||
if (Op && Op->isMem())
|
||||
assert(Operands[Ix]);
|
||||
MCParsedAsmOperand &Op = *Operands[Ix];
|
||||
if (Op.isMem())
|
||||
InstrumentMemOperand(Op, AccessSize, IsWrite, Ctx, Out);
|
||||
}
|
||||
}
|
||||
@ -136,21 +140,23 @@ public:
|
||||
: X86AddressSanitizer(STI) {}
|
||||
virtual ~X86AddressSanitizer32() {}
|
||||
|
||||
virtual void InstrumentMemOperandImpl(X86Operand *Op, unsigned AccessSize,
|
||||
virtual void InstrumentMemOperandImpl(X86Operand &Op, unsigned AccessSize,
|
||||
bool IsWrite, MCContext &Ctx,
|
||||
MCStreamer &Out) override;
|
||||
};
|
||||
|
||||
void X86AddressSanitizer32::InstrumentMemOperandImpl(
|
||||
X86Operand *Op, unsigned AccessSize, bool IsWrite, MCContext &Ctx,
|
||||
MCStreamer &Out) {
|
||||
void X86AddressSanitizer32::InstrumentMemOperandImpl(X86Operand &Op,
|
||||
unsigned AccessSize,
|
||||
bool IsWrite,
|
||||
MCContext &Ctx,
|
||||
MCStreamer &Out) {
|
||||
// FIXME: emit .cfi directives for correct stack unwinding.
|
||||
EmitInstruction(Out, MCInstBuilder(X86::PUSH32r).addReg(X86::EAX));
|
||||
{
|
||||
MCInst Inst;
|
||||
Inst.setOpcode(X86::LEA32r);
|
||||
Inst.addOperand(MCOperand::CreateReg(X86::EAX));
|
||||
Op->addMemOperands(Inst, 5);
|
||||
Op.addMemOperands(Inst, 5);
|
||||
EmitInstruction(Out, Inst);
|
||||
}
|
||||
EmitInstruction(Out, MCInstBuilder(X86::PUSH32r).addReg(X86::EAX));
|
||||
@ -171,12 +177,12 @@ public:
|
||||
: X86AddressSanitizer(STI) {}
|
||||
virtual ~X86AddressSanitizer64() {}
|
||||
|
||||
virtual void InstrumentMemOperandImpl(X86Operand *Op, unsigned AccessSize,
|
||||
virtual void InstrumentMemOperandImpl(X86Operand &Op, unsigned AccessSize,
|
||||
bool IsWrite, MCContext &Ctx,
|
||||
MCStreamer &Out) override;
|
||||
};
|
||||
|
||||
void X86AddressSanitizer64::InstrumentMemOperandImpl(X86Operand *Op,
|
||||
void X86AddressSanitizer64::InstrumentMemOperandImpl(X86Operand &Op,
|
||||
unsigned AccessSize,
|
||||
bool IsWrite,
|
||||
MCContext &Ctx,
|
||||
@ -201,7 +207,7 @@ void X86AddressSanitizer64::InstrumentMemOperandImpl(X86Operand *Op,
|
||||
MCInst Inst;
|
||||
Inst.setOpcode(X86::LEA64r);
|
||||
Inst.addOperand(MCOperand::CreateReg(X86::RDI));
|
||||
Op->addMemOperands(Inst, 5);
|
||||
Op.addMemOperands(Inst, 5);
|
||||
EmitInstruction(Out, Inst);
|
||||
}
|
||||
{
|
||||
@ -232,9 +238,11 @@ void X86AddressSanitizer64::InstrumentMemOperandImpl(X86Operand *Op,
|
||||
X86AsmInstrumentation::X86AsmInstrumentation() {}
|
||||
X86AsmInstrumentation::~X86AsmInstrumentation() {}
|
||||
|
||||
void X86AsmInstrumentation::InstrumentInstruction(
|
||||
const MCInst &Inst, SmallVectorImpl<MCParsedAsmOperand *> &Operands,
|
||||
MCContext &Ctx, const MCInstrInfo &MII, MCStreamer &Out) {}
|
||||
void X86AsmInstrumentation::InstrumentInstruction(const MCInst &Inst,
|
||||
OperandVector &Operands,
|
||||
MCContext &Ctx,
|
||||
const MCInstrInfo &MII,
|
||||
MCStreamer &Out) {}
|
||||
|
||||
X86AsmInstrumentation *
|
||||
CreateX86AsmInstrumentation(const MCTargetOptions &MCOptions,
|
||||
|
@ -12,6 +12,8 @@
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class MCContext;
|
||||
@ -35,10 +37,9 @@ public:
|
||||
// Instruments Inst. Should be called just before the original
|
||||
// instruction is sent to Out.
|
||||
virtual void InstrumentInstruction(
|
||||
const MCInst &Inst, SmallVectorImpl<MCParsedAsmOperand *> &Operands,
|
||||
MCContext &Ctx,
|
||||
const MCInstrInfo &MII,
|
||||
MCStreamer &Out);
|
||||
const MCInst &Inst,
|
||||
SmallVectorImpl<std::unique_ptr<MCParsedAsmOperand>> &Operands,
|
||||
MCContext &Ctx, const MCInstrInfo &MII, MCStreamer &Out);
|
||||
|
||||
protected:
|
||||
friend X86AsmInstrumentation *
|
||||
|
@ -618,52 +618,52 @@ private:
|
||||
return Error(L, Msg, Ranges, MatchingInlineAsm);
|
||||
}
|
||||
|
||||
X86Operand *ErrorOperand(SMLoc Loc, StringRef Msg) {
|
||||
std::nullptr_t ErrorOperand(SMLoc Loc, StringRef Msg) {
|
||||
Error(Loc, Msg);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
X86Operand *DefaultMemSIOperand(SMLoc Loc);
|
||||
X86Operand *DefaultMemDIOperand(SMLoc Loc);
|
||||
X86Operand *ParseOperand();
|
||||
X86Operand *ParseATTOperand();
|
||||
X86Operand *ParseIntelOperand();
|
||||
X86Operand *ParseIntelOffsetOfOperator();
|
||||
std::unique_ptr<X86Operand> DefaultMemSIOperand(SMLoc Loc);
|
||||
std::unique_ptr<X86Operand> DefaultMemDIOperand(SMLoc Loc);
|
||||
std::unique_ptr<X86Operand> ParseOperand();
|
||||
std::unique_ptr<X86Operand> ParseATTOperand();
|
||||
std::unique_ptr<X86Operand> ParseIntelOperand();
|
||||
std::unique_ptr<X86Operand> ParseIntelOffsetOfOperator();
|
||||
bool ParseIntelDotOperator(const MCExpr *Disp, const MCExpr *&NewDisp);
|
||||
X86Operand *ParseIntelOperator(unsigned OpKind);
|
||||
X86Operand *ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start, unsigned Size);
|
||||
X86Operand *ParseIntelMemOperand(int64_t ImmDisp, SMLoc StartLoc,
|
||||
unsigned Size);
|
||||
std::unique_ptr<X86Operand> ParseIntelOperator(unsigned OpKind);
|
||||
std::unique_ptr<X86Operand>
|
||||
ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start, unsigned Size);
|
||||
std::unique_ptr<X86Operand>
|
||||
ParseIntelMemOperand(int64_t ImmDisp, SMLoc StartLoc, unsigned Size);
|
||||
bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End);
|
||||
X86Operand *ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
|
||||
int64_t ImmDisp, unsigned Size);
|
||||
std::unique_ptr<X86Operand> ParseIntelBracExpression(unsigned SegReg,
|
||||
SMLoc Start,
|
||||
int64_t ImmDisp,
|
||||
unsigned Size);
|
||||
bool ParseIntelIdentifier(const MCExpr *&Val, StringRef &Identifier,
|
||||
InlineAsmIdentifierInfo &Info,
|
||||
bool IsUnevaluatedOperand, SMLoc &End);
|
||||
|
||||
X86Operand *ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
|
||||
std::unique_ptr<X86Operand> ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
|
||||
|
||||
X86Operand *CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp,
|
||||
unsigned BaseReg, unsigned IndexReg,
|
||||
unsigned Scale, SMLoc Start, SMLoc End,
|
||||
unsigned Size, StringRef Identifier,
|
||||
InlineAsmIdentifierInfo &Info);
|
||||
std::unique_ptr<X86Operand>
|
||||
CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp, unsigned BaseReg,
|
||||
unsigned IndexReg, unsigned Scale, SMLoc Start,
|
||||
SMLoc End, unsigned Size, StringRef Identifier,
|
||||
InlineAsmIdentifierInfo &Info);
|
||||
|
||||
bool ParseDirectiveWord(unsigned Size, SMLoc L);
|
||||
bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
|
||||
|
||||
bool processInstruction(MCInst &Inst,
|
||||
const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
|
||||
bool processInstruction(MCInst &Inst, const OperandVector &Ops);
|
||||
|
||||
/// Wrapper around MCStreamer::EmitInstruction(). Possibly adds
|
||||
/// instrumentation around Inst.
|
||||
void EmitInstruction(MCInst &Inst,
|
||||
SmallVectorImpl<MCParsedAsmOperand *> &Operands,
|
||||
MCStreamer &Out);
|
||||
void EmitInstruction(MCInst &Inst, OperandVector &Operands, MCStreamer &Out);
|
||||
|
||||
bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||
MCStreamer &Out, unsigned &ErrorInfo,
|
||||
OperandVector &Operands, MCStreamer &Out,
|
||||
unsigned &ErrorInfo,
|
||||
bool MatchingInlineAsm) override;
|
||||
|
||||
/// doSrcDstMatch - Returns true if operands are matching in their
|
||||
@ -674,8 +674,8 @@ private:
|
||||
/// Parses AVX512 specific operand primitives: masked registers ({%k<NUM>}, {z})
|
||||
/// and memory broadcasting ({1to<NUM>}) primitives, updating Operands vector if required.
|
||||
/// \return \c true if no parsing errors occurred, \c false otherwise.
|
||||
bool HandleAVX512Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||
const MCParsedAsmOperand &Op);
|
||||
bool HandleAVX512Operand(OperandVector &Operands,
|
||||
const MCParsedAsmOperand &Op);
|
||||
|
||||
bool is64BitMode() const {
|
||||
// FIXME: Can tablegen auto-generate this?
|
||||
@ -725,9 +725,8 @@ public:
|
||||
|
||||
bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
|
||||
|
||||
bool
|
||||
ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
|
||||
SmallVectorImpl<MCParsedAsmOperand*> &Operands) override;
|
||||
bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
|
||||
SMLoc NameLoc, OperandVector &Operands) override;
|
||||
|
||||
bool ParseDirective(AsmToken DirectiveID) override;
|
||||
};
|
||||
@ -908,7 +907,7 @@ bool X86AsmParser::ParseRegister(unsigned &RegNo,
|
||||
return false;
|
||||
}
|
||||
|
||||
X86Operand *X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
|
||||
std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
|
||||
unsigned basereg =
|
||||
is64BitMode() ? X86::RSI : (is32BitMode() ? X86::ESI : X86::SI);
|
||||
const MCExpr *Disp = MCConstantExpr::Create(0, getContext());
|
||||
@ -916,7 +915,7 @@ X86Operand *X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
|
||||
/*IndexReg=*/0, /*Scale=*/1, Loc, Loc, 0);
|
||||
}
|
||||
|
||||
X86Operand *X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
|
||||
std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
|
||||
unsigned basereg =
|
||||
is64BitMode() ? X86::RDI : (is32BitMode() ? X86::EDI : X86::DI);
|
||||
const MCExpr *Disp = MCConstantExpr::Create(0, getContext());
|
||||
@ -924,7 +923,7 @@ X86Operand *X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
|
||||
/*IndexReg=*/0, /*Scale=*/1, Loc, Loc, 0);
|
||||
}
|
||||
|
||||
X86Operand *X86AsmParser::ParseOperand() {
|
||||
std::unique_ptr<X86Operand> X86AsmParser::ParseOperand() {
|
||||
if (isParsingIntelSyntax())
|
||||
return ParseIntelOperand();
|
||||
return ParseATTOperand();
|
||||
@ -946,12 +945,10 @@ static unsigned getIntelMemOperandSize(StringRef OpStr) {
|
||||
return Size;
|
||||
}
|
||||
|
||||
X86Operand *
|
||||
X86AsmParser::CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp,
|
||||
unsigned BaseReg, unsigned IndexReg,
|
||||
unsigned Scale, SMLoc Start, SMLoc End,
|
||||
unsigned Size, StringRef Identifier,
|
||||
InlineAsmIdentifierInfo &Info){
|
||||
std::unique_ptr<X86Operand> X86AsmParser::CreateMemForInlineAsm(
|
||||
unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, unsigned IndexReg,
|
||||
unsigned Scale, SMLoc Start, SMLoc End, unsigned Size, StringRef Identifier,
|
||||
InlineAsmIdentifierInfo &Info) {
|
||||
// If this is not a VarDecl then assume it is a FuncDecl or some other label
|
||||
// reference. We need an 'r' constraint here, so we need to create register
|
||||
// operand to ensure proper matching. Just pick a GPR based on the size of
|
||||
@ -1164,9 +1161,9 @@ bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
|
||||
return false;
|
||||
}
|
||||
|
||||
X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
|
||||
int64_t ImmDisp,
|
||||
unsigned Size) {
|
||||
std::unique_ptr<X86Operand>
|
||||
X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
|
||||
int64_t ImmDisp, unsigned Size) {
|
||||
const AsmToken &Tok = Parser.getTok();
|
||||
SMLoc BracLoc = Tok.getLoc(), End = Tok.getEndLoc();
|
||||
if (getLexer().isNot(AsmToken::LBrac))
|
||||
@ -1270,9 +1267,9 @@ bool X86AsmParser::ParseIntelIdentifier(const MCExpr *&Val,
|
||||
}
|
||||
|
||||
/// \brief Parse intel style segment override.
|
||||
X86Operand *X86AsmParser::ParseIntelSegmentOverride(unsigned SegReg,
|
||||
SMLoc Start,
|
||||
unsigned Size) {
|
||||
std::unique_ptr<X86Operand>
|
||||
X86AsmParser::ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start,
|
||||
unsigned Size) {
|
||||
assert(SegReg != 0 && "Tried to parse a segment override without a segment!");
|
||||
const AsmToken &Tok = Parser.getTok(); // Eat colon.
|
||||
if (Tok.isNot(AsmToken::Colon))
|
||||
@ -1321,8 +1318,9 @@ X86Operand *X86AsmParser::ParseIntelSegmentOverride(unsigned SegReg,
|
||||
}
|
||||
|
||||
/// ParseIntelMemOperand - Parse intel style memory operand.
|
||||
X86Operand *X86AsmParser::ParseIntelMemOperand(int64_t ImmDisp, SMLoc Start,
|
||||
unsigned Size) {
|
||||
std::unique_ptr<X86Operand> X86AsmParser::ParseIntelMemOperand(int64_t ImmDisp,
|
||||
SMLoc Start,
|
||||
unsigned Size) {
|
||||
const AsmToken &Tok = Parser.getTok();
|
||||
SMLoc End;
|
||||
|
||||
@ -1425,7 +1423,7 @@ bool X86AsmParser::ParseIntelDotOperator(const MCExpr *Disp,
|
||||
|
||||
/// Parse the 'offset' operator. This operator is used to specify the
|
||||
/// location rather then the content of a variable.
|
||||
X86Operand *X86AsmParser::ParseIntelOffsetOfOperator() {
|
||||
std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOffsetOfOperator() {
|
||||
const AsmToken &Tok = Parser.getTok();
|
||||
SMLoc OffsetOfLoc = Tok.getLoc();
|
||||
Parser.Lex(); // Eat offset.
|
||||
@ -1462,7 +1460,7 @@ enum IntelOperatorKind {
|
||||
/// variable. A variable's size is the product of its LENGTH and TYPE. The
|
||||
/// TYPE operator returns the size of a C or C++ type or variable. If the
|
||||
/// variable is an array, TYPE returns the size of a single element.
|
||||
X86Operand *X86AsmParser::ParseIntelOperator(unsigned OpKind) {
|
||||
std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperator(unsigned OpKind) {
|
||||
const AsmToken &Tok = Parser.getTok();
|
||||
SMLoc TypeLoc = Tok.getLoc();
|
||||
Parser.Lex(); // Eat operator.
|
||||
@ -1495,7 +1493,7 @@ X86Operand *X86AsmParser::ParseIntelOperator(unsigned OpKind) {
|
||||
return X86Operand::CreateImm(Imm, Start, End);
|
||||
}
|
||||
|
||||
X86Operand *X86AsmParser::ParseIntelOperand() {
|
||||
std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
|
||||
const AsmToken &Tok = Parser.getTok();
|
||||
SMLoc Start, End;
|
||||
|
||||
@ -1577,7 +1575,7 @@ X86Operand *X86AsmParser::ParseIntelOperand() {
|
||||
return ParseIntelMemOperand(/*Disp=*/0, Start, Size);
|
||||
}
|
||||
|
||||
X86Operand *X86AsmParser::ParseATTOperand() {
|
||||
std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() {
|
||||
switch (getLexer().getKind()) {
|
||||
default:
|
||||
// Parse a memory operand with no segment register.
|
||||
@ -1613,9 +1611,8 @@ X86Operand *X86AsmParser::ParseATTOperand() {
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
X86AsmParser::HandleAVX512Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||
const MCParsedAsmOperand &Op) {
|
||||
bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
|
||||
const MCParsedAsmOperand &Op) {
|
||||
if(STI.getFeatureBits() & X86::FeatureAVX512) {
|
||||
if (getLexer().is(AsmToken::LCurly)) {
|
||||
// Eat "{" and mark the current place.
|
||||
@ -1653,8 +1650,8 @@ X86AsmParser::HandleAVX512Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands
|
||||
} else {
|
||||
// Parse mask register {%k1}
|
||||
Operands.push_back(X86Operand::CreateToken("{", consumedToken));
|
||||
if (X86Operand *Op = ParseOperand()) {
|
||||
Operands.push_back(Op);
|
||||
if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
|
||||
Operands.push_back(std::move(Op));
|
||||
if (!getLexer().is(AsmToken::RCurly))
|
||||
return !ErrorAndEatStatement(getLexer().getLoc(),
|
||||
"Expected } at this point");
|
||||
@ -1682,7 +1679,8 @@ X86AsmParser::HandleAVX512Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands
|
||||
|
||||
/// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix
|
||||
/// has already been parsed if present.
|
||||
X86Operand *X86AsmParser::ParseMemOperand(unsigned SegReg, SMLoc MemStart) {
|
||||
std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(unsigned SegReg,
|
||||
SMLoc MemStart) {
|
||||
|
||||
// We have to disambiguate a parenthesized expression "(4+5)" from the start
|
||||
// of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The
|
||||
@ -1845,9 +1843,8 @@ X86Operand *X86AsmParser::ParseMemOperand(unsigned SegReg, SMLoc MemStart) {
|
||||
MemStart, MemEnd);
|
||||
}
|
||||
|
||||
bool X86AsmParser::
|
||||
ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
|
||||
SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
|
||||
SMLoc NameLoc, OperandVector &Operands) {
|
||||
InstInfo = &Info;
|
||||
StringRef PatchedName = Name;
|
||||
|
||||
@ -1940,9 +1937,9 @@ ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
|
||||
|
||||
// Read the operands.
|
||||
while(1) {
|
||||
if (X86Operand *Op = ParseOperand()) {
|
||||
Operands.push_back(Op);
|
||||
if (!HandleAVX512Operand(Operands, *Op))
|
||||
if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
|
||||
Operands.push_back(std::move(Op));
|
||||
if (!HandleAVX512Operand(Operands, *Operands.back()))
|
||||
return true;
|
||||
} else {
|
||||
Parser.eatToEndOfStatement();
|
||||
@ -1973,27 +1970,25 @@ ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
|
||||
// documented form in various unofficial manuals, so a lot of code uses it.
|
||||
if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") &&
|
||||
Operands.size() == 3) {
|
||||
X86Operand &Op = *(X86Operand*)Operands.back();
|
||||
X86Operand &Op = (X86Operand &)*Operands.back();
|
||||
if (Op.isMem() && Op.Mem.SegReg == 0 &&
|
||||
isa<MCConstantExpr>(Op.Mem.Disp) &&
|
||||
cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
|
||||
Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
|
||||
SMLoc Loc = Op.getEndLoc();
|
||||
Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
|
||||
delete &Op;
|
||||
}
|
||||
}
|
||||
// Same hack for "in[bwl]? (%dx), %al" -> "inb %dx, %al".
|
||||
if ((Name == "inb" || Name == "inw" || Name == "inl" || Name == "in") &&
|
||||
Operands.size() == 3) {
|
||||
X86Operand &Op = *(X86Operand*)Operands.begin()[1];
|
||||
X86Operand &Op = (X86Operand &)*Operands[1];
|
||||
if (Op.isMem() && Op.Mem.SegReg == 0 &&
|
||||
isa<MCConstantExpr>(Op.Mem.Disp) &&
|
||||
cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
|
||||
Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
|
||||
SMLoc Loc = Op.getEndLoc();
|
||||
Operands.begin()[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
|
||||
delete &Op;
|
||||
Operands[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2060,8 +2055,8 @@ ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
|
||||
Operands.push_back(DefaultMemSIOperand(NameLoc));
|
||||
}
|
||||
} else if (Operands.size() == 3) {
|
||||
X86Operand &Op = *(X86Operand*)Operands.begin()[1];
|
||||
X86Operand &Op2 = *(X86Operand*)Operands.begin()[2];
|
||||
X86Operand &Op = (X86Operand &)*Operands[1];
|
||||
X86Operand &Op2 = (X86Operand &)*Operands[2];
|
||||
if (!doSrcDstMatch(Op, Op2))
|
||||
return Error(Op.getStartLoc(),
|
||||
"mismatching source and destination index registers");
|
||||
@ -2076,10 +2071,8 @@ ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
|
||||
(Name == "smov" || Name == "smovb" || Name == "smovw" ||
|
||||
Name == "smovl" || Name == "smovd" || Name == "smovq"))) {
|
||||
if (Operands.size() == 1) {
|
||||
if (Name == "movsd") {
|
||||
delete Operands.back();
|
||||
if (Name == "movsd")
|
||||
Operands.back() = X86Operand::CreateToken("movsl", NameLoc);
|
||||
}
|
||||
if (isParsingIntelSyntax()) {
|
||||
Operands.push_back(DefaultMemDIOperand(NameLoc));
|
||||
Operands.push_back(DefaultMemSIOperand(NameLoc));
|
||||
@ -2088,8 +2081,8 @@ ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
|
||||
Operands.push_back(DefaultMemDIOperand(NameLoc));
|
||||
}
|
||||
} else if (Operands.size() == 3) {
|
||||
X86Operand &Op = *(X86Operand*)Operands.begin()[1];
|
||||
X86Operand &Op2 = *(X86Operand*)Operands.begin()[2];
|
||||
X86Operand &Op = (X86Operand &)*Operands[1];
|
||||
X86Operand &Op2 = (X86Operand &)*Operands[2];
|
||||
if (!doSrcDstMatch(Op, Op2))
|
||||
return Error(Op.getStartLoc(),
|
||||
"mismatching source and destination index registers");
|
||||
@ -2105,31 +2098,26 @@ ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
|
||||
Operands.size() == 3) {
|
||||
if (isParsingIntelSyntax()) {
|
||||
// Intel syntax
|
||||
X86Operand *Op1 = static_cast<X86Operand*>(Operands[2]);
|
||||
if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) &&
|
||||
cast<MCConstantExpr>(Op1->getImm())->getValue() == 1) {
|
||||
delete Operands[2];
|
||||
X86Operand &Op1 = static_cast<X86Operand &>(*Operands[2]);
|
||||
if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
|
||||
cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
|
||||
Operands.pop_back();
|
||||
}
|
||||
} else {
|
||||
X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
|
||||
if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) &&
|
||||
cast<MCConstantExpr>(Op1->getImm())->getValue() == 1) {
|
||||
delete Operands[1];
|
||||
X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
|
||||
if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
|
||||
cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
|
||||
Operands.erase(Operands.begin() + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Transforms "int $3" into "int3" as a size optimization. We can't write an
|
||||
// instalias with an immediate operand yet.
|
||||
if (Name == "int" && Operands.size() == 2) {
|
||||
X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
|
||||
if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) &&
|
||||
cast<MCConstantExpr>(Op1->getImm())->getValue() == 3) {
|
||||
delete Operands[1];
|
||||
X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
|
||||
if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
|
||||
cast<MCConstantExpr>(Op1.getImm())->getValue() == 3) {
|
||||
Operands.erase(Operands.begin() + 1);
|
||||
static_cast<X86Operand*>(Operands[0])->setTokenValue("int3");
|
||||
static_cast<X86Operand &>(*Operands[0]).setTokenValue("int3");
|
||||
}
|
||||
}
|
||||
|
||||
@ -2175,9 +2163,7 @@ static bool convert64i32to64ri8(MCInst &Inst, unsigned Opcode,
|
||||
return convertToSExti8(Inst, Opcode, X86::RAX, isCmp);
|
||||
}
|
||||
|
||||
bool X86AsmParser::
|
||||
processInstruction(MCInst &Inst,
|
||||
const SmallVectorImpl<MCParsedAsmOperand*> &Ops) {
|
||||
bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
|
||||
switch (Inst.getOpcode()) {
|
||||
default: return false;
|
||||
case X86::AND16i16: return convert16i16to16ri8(Inst, X86::AND16ri8);
|
||||
@ -2258,51 +2244,47 @@ processInstruction(MCInst &Inst,
|
||||
|
||||
static const char *getSubtargetFeatureName(unsigned Val);
|
||||
|
||||
void X86AsmParser::EmitInstruction(
|
||||
MCInst &Inst, SmallVectorImpl<MCParsedAsmOperand *> &Operands,
|
||||
MCStreamer &Out) {
|
||||
void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
|
||||
MCStreamer &Out) {
|
||||
Instrumentation->InstrumentInstruction(Inst, Operands, getContext(), MII,
|
||||
Out);
|
||||
Out.EmitInstruction(Inst, STI);
|
||||
}
|
||||
|
||||
bool X86AsmParser::
|
||||
MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||
MCStreamer &Out, unsigned &ErrorInfo,
|
||||
bool MatchingInlineAsm) {
|
||||
bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
OperandVector &Operands,
|
||||
MCStreamer &Out, unsigned &ErrorInfo,
|
||||
bool MatchingInlineAsm) {
|
||||
assert(!Operands.empty() && "Unexpect empty operand list!");
|
||||
X86Operand *Op = static_cast<X86Operand*>(Operands[0]);
|
||||
assert(Op->isToken() && "Leading operand should always be a mnemonic!");
|
||||
X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
|
||||
assert(Op.isToken() && "Leading operand should always be a mnemonic!");
|
||||
ArrayRef<SMRange> EmptyRanges = None;
|
||||
|
||||
// First, handle aliases that expand to multiple instructions.
|
||||
// FIXME: This should be replaced with a real .td file alias mechanism.
|
||||
// Also, MatchInstructionImpl should actually *do* the EmitInstruction
|
||||
// call.
|
||||
if (Op->getToken() == "fstsw" || Op->getToken() == "fstcw" ||
|
||||
Op->getToken() == "fstsww" || Op->getToken() == "fstcww" ||
|
||||
Op->getToken() == "finit" || Op->getToken() == "fsave" ||
|
||||
Op->getToken() == "fstenv" || Op->getToken() == "fclex") {
|
||||
if (Op.getToken() == "fstsw" || Op.getToken() == "fstcw" ||
|
||||
Op.getToken() == "fstsww" || Op.getToken() == "fstcww" ||
|
||||
Op.getToken() == "finit" || Op.getToken() == "fsave" ||
|
||||
Op.getToken() == "fstenv" || Op.getToken() == "fclex") {
|
||||
MCInst Inst;
|
||||
Inst.setOpcode(X86::WAIT);
|
||||
Inst.setLoc(IDLoc);
|
||||
if (!MatchingInlineAsm)
|
||||
EmitInstruction(Inst, Operands, Out);
|
||||
|
||||
const char *Repl =
|
||||
StringSwitch<const char*>(Op->getToken())
|
||||
.Case("finit", "fninit")
|
||||
.Case("fsave", "fnsave")
|
||||
.Case("fstcw", "fnstcw")
|
||||
.Case("fstcww", "fnstcw")
|
||||
.Case("fstenv", "fnstenv")
|
||||
.Case("fstsw", "fnstsw")
|
||||
.Case("fstsww", "fnstsw")
|
||||
.Case("fclex", "fnclex")
|
||||
.Default(nullptr);
|
||||
const char *Repl = StringSwitch<const char *>(Op.getToken())
|
||||
.Case("finit", "fninit")
|
||||
.Case("fsave", "fnsave")
|
||||
.Case("fstcw", "fnstcw")
|
||||
.Case("fstcww", "fnstcw")
|
||||
.Case("fstenv", "fnstenv")
|
||||
.Case("fstsw", "fnstsw")
|
||||
.Case("fstsww", "fnstsw")
|
||||
.Case("fclex", "fnclex")
|
||||
.Default(nullptr);
|
||||
assert(Repl && "Unknown wait-prefixed instruction");
|
||||
delete Operands[0];
|
||||
Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
|
||||
}
|
||||
|
||||
@ -2355,11 +2337,11 @@ MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
// following hack.
|
||||
|
||||
// Change the operand to point to a temporary token.
|
||||
StringRef Base = Op->getToken();
|
||||
StringRef Base = Op.getToken();
|
||||
SmallString<16> Tmp;
|
||||
Tmp += Base;
|
||||
Tmp += ' ';
|
||||
Op->setTokenValue(Tmp.str());
|
||||
Op.setTokenValue(Tmp.str());
|
||||
|
||||
// If this instruction starts with an 'f', then it is a floating point stack
|
||||
// instruction. These come in up to three forms for 32-bit, 64-bit, and
|
||||
@ -2400,7 +2382,7 @@ MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
ErrorInfoMissingFeature = ErrorInfoIgnore;
|
||||
|
||||
// Restore the old token.
|
||||
Op->setTokenValue(Base);
|
||||
Op.setTokenValue(Base);
|
||||
|
||||
// If exactly one matched, then we treat that as a successful match (and the
|
||||
// instruction will already have been filled in correctly, since the failing
|
||||
@ -2450,8 +2432,8 @@ MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
if ((Match1 == Match_MnemonicFail) && (Match2 == Match_MnemonicFail) &&
|
||||
(Match3 == Match_MnemonicFail) && (Match4 == Match_MnemonicFail)) {
|
||||
if (!WasOriginallyInvalidOperand) {
|
||||
ArrayRef<SMRange> Ranges = MatchingInlineAsm ? EmptyRanges :
|
||||
Op->getLocRange();
|
||||
ArrayRef<SMRange> Ranges =
|
||||
MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
|
||||
return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
|
||||
Ranges, MatchingInlineAsm);
|
||||
}
|
||||
@ -2462,10 +2444,10 @@ MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
return Error(IDLoc, "too few operands for instruction",
|
||||
EmptyRanges, MatchingInlineAsm);
|
||||
|
||||
X86Operand *Operand = (X86Operand*)Operands[ErrorInfo];
|
||||
if (Operand->getStartLoc().isValid()) {
|
||||
SMRange OperandRange = Operand->getLocRange();
|
||||
return Error(Operand->getStartLoc(), "invalid operand for instruction",
|
||||
X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
|
||||
if (Operand.getStartLoc().isValid()) {
|
||||
SMRange OperandRange = Operand.getLocRange();
|
||||
return Error(Operand.getStartLoc(), "invalid operand for instruction",
|
||||
OperandRange, MatchingInlineAsm);
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "X86AsmParserCommon.h"
|
||||
#include "llvm/MC/MCExpr.h"
|
||||
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -410,20 +411,19 @@ struct X86Operand : public MCParsedAsmOperand {
|
||||
Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
|
||||
}
|
||||
|
||||
static X86Operand *CreateToken(StringRef Str, SMLoc Loc) {
|
||||
static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) {
|
||||
SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
|
||||
X86Operand *Res = new X86Operand(Token, Loc, EndLoc);
|
||||
auto Res = llvm::make_unique<X86Operand>(Token, Loc, EndLoc);
|
||||
Res->Tok.Data = Str.data();
|
||||
Res->Tok.Length = Str.size();
|
||||
return Res;
|
||||
}
|
||||
|
||||
static X86Operand *CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
|
||||
bool AddressOf = false,
|
||||
SMLoc OffsetOfLoc = SMLoc(),
|
||||
StringRef SymName = StringRef(),
|
||||
void *OpDecl = nullptr) {
|
||||
X86Operand *Res = new X86Operand(Register, StartLoc, EndLoc);
|
||||
static std::unique_ptr<X86Operand>
|
||||
CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
|
||||
bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(),
|
||||
StringRef SymName = StringRef(), void *OpDecl = nullptr) {
|
||||
auto Res = llvm::make_unique<X86Operand>(Register, StartLoc, EndLoc);
|
||||
Res->Reg.RegNo = RegNo;
|
||||
Res->AddressOf = AddressOf;
|
||||
Res->OffsetOfLoc = OffsetOfLoc;
|
||||
@ -432,17 +432,18 @@ struct X86Operand : public MCParsedAsmOperand {
|
||||
return Res;
|
||||
}
|
||||
|
||||
static X86Operand *CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc){
|
||||
X86Operand *Res = new X86Operand(Immediate, StartLoc, EndLoc);
|
||||
static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val,
|
||||
SMLoc StartLoc, SMLoc EndLoc) {
|
||||
auto Res = llvm::make_unique<X86Operand>(Immediate, StartLoc, EndLoc);
|
||||
Res->Imm.Val = Val;
|
||||
return Res;
|
||||
}
|
||||
|
||||
/// Create an absolute memory operand.
|
||||
static X86Operand *CreateMem(const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,
|
||||
unsigned Size = 0, StringRef SymName = StringRef(),
|
||||
void *OpDecl = nullptr) {
|
||||
X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
|
||||
static std::unique_ptr<X86Operand>
|
||||
CreateMem(const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc, unsigned Size = 0,
|
||||
StringRef SymName = StringRef(), void *OpDecl = nullptr) {
|
||||
auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
|
||||
Res->Mem.SegReg = 0;
|
||||
Res->Mem.Disp = Disp;
|
||||
Res->Mem.BaseReg = 0;
|
||||
@ -456,12 +457,11 @@ struct X86Operand : public MCParsedAsmOperand {
|
||||
}
|
||||
|
||||
/// Create a generalized memory operand.
|
||||
static X86Operand *CreateMem(unsigned SegReg, const MCExpr *Disp,
|
||||
unsigned BaseReg, unsigned IndexReg,
|
||||
unsigned Scale, SMLoc StartLoc, SMLoc EndLoc,
|
||||
unsigned Size = 0,
|
||||
StringRef SymName = StringRef(),
|
||||
void *OpDecl = nullptr) {
|
||||
static std::unique_ptr<X86Operand>
|
||||
CreateMem(unsigned SegReg, const MCExpr *Disp, unsigned BaseReg,
|
||||
unsigned IndexReg, unsigned Scale, SMLoc StartLoc, SMLoc EndLoc,
|
||||
unsigned Size = 0, StringRef SymName = StringRef(),
|
||||
void *OpDecl = nullptr) {
|
||||
// We should never just have a displacement, that should be parsed as an
|
||||
// absolute memory operand.
|
||||
assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
|
||||
@ -469,7 +469,7 @@ struct X86Operand : public MCParsedAsmOperand {
|
||||
// The scale should always be one of {1,2,4,8}.
|
||||
assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
|
||||
"Invalid scale!");
|
||||
X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
|
||||
auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
|
||||
Res->Mem.SegReg = SegReg;
|
||||
Res->Mem.Disp = Disp;
|
||||
Res->Mem.BaseReg = BaseReg;
|
||||
|
@ -1722,8 +1722,8 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
|
||||
CvtOS << "void " << Target.getName() << ClassName << "::\n"
|
||||
<< "convertToMCInst(unsigned Kind, MCInst &Inst, "
|
||||
<< "unsigned Opcode,\n"
|
||||
<< " const SmallVectorImpl<MCParsedAsmOperand*"
|
||||
<< "> &Operands) {\n"
|
||||
<< " const OperandVector"
|
||||
<< " &Operands) {\n"
|
||||
<< " assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n"
|
||||
<< " const uint8_t *Converter = ConversionTable[Kind];\n"
|
||||
<< " Inst.setOpcode(Opcode);\n"
|
||||
@ -1732,7 +1732,7 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
|
||||
<< " default: llvm_unreachable(\"invalid conversion entry!\");\n"
|
||||
<< " case CVT_Reg:\n"
|
||||
<< " static_cast<" << TargetOperandClass
|
||||
<< "*>(Operands[*(p + 1)])->addRegOperands(Inst, 1);\n"
|
||||
<< "&>(*Operands[*(p + 1)]).addRegOperands(Inst, 1);\n"
|
||||
<< " break;\n"
|
||||
<< " case CVT_Tied:\n"
|
||||
<< " Inst.addOperand(Inst.getOperand(*(p + 1)));\n"
|
||||
@ -1744,7 +1744,7 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
|
||||
OpOS << "void " << Target.getName() << ClassName << "::\n"
|
||||
<< "convertToMapAndConstraints(unsigned Kind,\n";
|
||||
OpOS.indent(27);
|
||||
OpOS << "const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {\n"
|
||||
OpOS << "const OperandVector &Operands) {\n"
|
||||
<< " assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n"
|
||||
<< " unsigned NumMCOperands = 0;\n"
|
||||
<< " const uint8_t *Converter = ConversionTable[Kind];\n"
|
||||
@ -1849,9 +1849,8 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
|
||||
// converter driver.
|
||||
CvtOS << " case " << Name << ":\n"
|
||||
<< " static_cast<" << TargetOperandClass
|
||||
<< "*>(Operands[*(p + 1)])->"
|
||||
<< Op.Class->RenderMethod << "(Inst, " << OpInfo.MINumOperands
|
||||
<< ");\n"
|
||||
<< "&>(*Operands[*(p + 1)])." << Op.Class->RenderMethod
|
||||
<< "(Inst, " << OpInfo.MINumOperands << ");\n"
|
||||
<< " break;\n";
|
||||
|
||||
// Add a handler for the operand number lookup.
|
||||
@ -2036,10 +2035,10 @@ static void emitMatchClassEnumeration(CodeGenTarget &Target,
|
||||
/// emitValidateOperandClass - Emit the function to validate an operand class.
|
||||
static void emitValidateOperandClass(AsmMatcherInfo &Info,
|
||||
raw_ostream &OS) {
|
||||
OS << "static unsigned validateOperandClass(MCParsedAsmOperand *GOp, "
|
||||
OS << "static unsigned validateOperandClass(MCParsedAsmOperand &GOp, "
|
||||
<< "MatchClassKind Kind) {\n";
|
||||
OS << " " << Info.Target.getName() << "Operand &Operand = *("
|
||||
<< Info.Target.getName() << "Operand*)GOp;\n";
|
||||
OS << " " << Info.Target.getName() << "Operand &Operand = ("
|
||||
<< Info.Target.getName() << "Operand&)GOp;\n";
|
||||
|
||||
// The InvalidMatchClass is not to match any operand.
|
||||
OS << " if (Kind == InvalidMatchClass)\n";
|
||||
@ -2561,7 +2560,7 @@ static void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target,
|
||||
// the found operand class.
|
||||
OS << Target.getName() << ClassName << "::OperandMatchResultTy "
|
||||
<< Target.getName() << ClassName << "::\n"
|
||||
<< "tryCustomParseOperand(SmallVectorImpl<MCParsedAsmOperand*>"
|
||||
<< "tryCustomParseOperand(OperandVector"
|
||||
<< " &Operands,\n unsigned MCK) {\n\n"
|
||||
<< " switch(MCK) {\n";
|
||||
|
||||
@ -2585,7 +2584,7 @@ static void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target,
|
||||
// a better error handling.
|
||||
OS << Target.getName() << ClassName << "::OperandMatchResultTy "
|
||||
<< Target.getName() << ClassName << "::\n"
|
||||
<< "MatchOperandParserImpl(SmallVectorImpl<MCParsedAsmOperand*>"
|
||||
<< "MatchOperandParserImpl(OperandVector"
|
||||
<< " &Operands,\n StringRef Mnemonic) {\n";
|
||||
|
||||
// Emit code to get the available features.
|
||||
@ -2695,14 +2694,14 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
||||
OS << " unsigned ComputeAvailableFeatures(uint64_t FeatureBits) const;\n";
|
||||
OS << " void convertToMCInst(unsigned Kind, MCInst &Inst, "
|
||||
<< "unsigned Opcode,\n"
|
||||
<< " const SmallVectorImpl<MCParsedAsmOperand*> "
|
||||
<< " const OperandVector "
|
||||
<< "&Operands);\n";
|
||||
OS << " void convertToMapAndConstraints(unsigned Kind,\n ";
|
||||
OS << " const SmallVectorImpl<MCParsedAsmOperand*> &Operands) override;\n";
|
||||
OS << " const OperandVector &Operands) override;\n";
|
||||
OS << " bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) override;\n";
|
||||
OS << " unsigned MatchInstructionImpl(\n";
|
||||
OS.indent(27);
|
||||
OS << "const SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n"
|
||||
OS << "const OperandVector &Operands,\n"
|
||||
<< " MCInst &Inst,\n"
|
||||
<< " unsigned &ErrorInfo,"
|
||||
<< " bool matchingInlineAsm,\n"
|
||||
@ -2715,11 +2714,11 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
||||
OS << " MatchOperand_ParseFail // operand matched but had errors\n";
|
||||
OS << " };\n";
|
||||
OS << " OperandMatchResultTy MatchOperandParserImpl(\n";
|
||||
OS << " SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n";
|
||||
OS << " OperandVector &Operands,\n";
|
||||
OS << " StringRef Mnemonic);\n";
|
||||
|
||||
OS << " OperandMatchResultTy tryCustomParseOperand(\n";
|
||||
OS << " SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n";
|
||||
OS << " OperandVector &Operands,\n";
|
||||
OS << " unsigned MCK);\n\n";
|
||||
}
|
||||
|
||||
@ -2909,9 +2908,8 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
||||
OS << "}\n\n";
|
||||
|
||||
// Finally, build the match function.
|
||||
OS << "unsigned "
|
||||
<< Target.getName() << ClassName << "::\n"
|
||||
<< "MatchInstructionImpl(const SmallVectorImpl<MCParsedAsmOperand*>"
|
||||
OS << "unsigned " << Target.getName() << ClassName << "::\n"
|
||||
<< "MatchInstructionImpl(const OperandVector"
|
||||
<< " &Operands,\n";
|
||||
OS << " MCInst &Inst,\n"
|
||||
<< "unsigned &ErrorInfo, bool matchingInlineAsm, unsigned VariantID) {\n";
|
||||
@ -2928,7 +2926,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
||||
|
||||
OS << " // Get the instruction mnemonic, which is the first token.\n";
|
||||
OS << " StringRef Mnemonic = ((" << Target.getName()
|
||||
<< "Operand*)Operands[0])->getToken();\n\n";
|
||||
<< "Operand&)*Operands[0]).getToken();\n\n";
|
||||
|
||||
if (HasMnemonicAliases) {
|
||||
OS << " // Process all MnemonicAliases to remap the mnemonic.\n";
|
||||
@ -2980,7 +2978,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
||||
OS << " if (!OperandsValid) ErrorInfo = i + 1;\n";
|
||||
OS << " break;\n";
|
||||
OS << " }\n";
|
||||
OS << " unsigned Diag = validateOperandClass(Operands[i+1],\n";
|
||||
OS << " unsigned Diag = validateOperandClass(*Operands[i+1],\n";
|
||||
OS.indent(43);
|
||||
OS << "(MatchClassKind)it->Classes[i]);\n";
|
||||
OS << " if (Diag == Match_Success)\n";
|
||||
@ -2988,7 +2986,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
||||
OS << " // If the generic handler indicates an invalid operand\n";
|
||||
OS << " // failure, check for a special case.\n";
|
||||
OS << " if (Diag == Match_InvalidOperand) {\n";
|
||||
OS << " Diag = validateTargetOperandClass(Operands[i+1],\n";
|
||||
OS << " Diag = validateTargetOperandClass(*Operands[i+1],\n";
|
||||
OS.indent(43);
|
||||
OS << "(MatchClassKind)it->Classes[i]);\n";
|
||||
OS << " if (Diag == Match_Success)\n";
|
||||
@ -3055,7 +3053,8 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
||||
if (HasDeprecation) {
|
||||
OS << " std::string Info;\n";
|
||||
OS << " if (MII.get(Inst.getOpcode()).getDeprecatedInfo(Inst, STI, Info)) {\n";
|
||||
OS << " SMLoc Loc = ((" << Target.getName() << "Operand*)Operands[0])->getStartLoc();\n";
|
||||
OS << " SMLoc Loc = ((" << Target.getName()
|
||||
<< "Operand&)*Operands[0]).getStartLoc();\n";
|
||||
OS << " Parser.Warning(Loc, Info, None);\n";
|
||||
OS << " }\n";
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user