diff options
| author | Roman Divacky <rdivacky@FreeBSD.org> | 2010-05-04 20:50:39 +0000 |
|---|---|---|
| committer | Roman Divacky <rdivacky@FreeBSD.org> | 2010-05-04 20:50:39 +0000 |
| commit | 59161dfae3225dd9151afbc76ca9074598c0c605 (patch) | |
| tree | 3c3ffb5df9fa6dfb2c48b807faf73dd2943db75d /lib/Target/X86 | |
| parent | d7f7719e5e082c0b8ea2182dcbd2242b7834aa26 (diff) | |
Notes
Diffstat (limited to 'lib/Target/X86')
| -rw-r--r-- | lib/Target/X86/AsmParser/X86AsmParser.cpp | 60 | ||||
| -rw-r--r-- | lib/Target/X86/X86.td | 5 |
2 files changed, 61 insertions, 4 deletions
diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index da013505dabd..6b403c10a1eb 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -51,11 +51,14 @@ private: void InstructionCleanup(MCInst &Inst); /// @name Auto-generated Match Functions - /// { + /// { bool MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> &Operands, MCInst &Inst); + bool MatchInstructionImpl( + const SmallVectorImpl<MCParsedAsmOperand*> &Operands, MCInst &Inst); + /// } public: @@ -132,7 +135,7 @@ struct X86Operand : public MCParsedAsmOperand { X86Operand(KindTy K, SMLoc Start, SMLoc End) : Kind(K), StartLoc(Start), EndLoc(End) {} - + /// getStartLoc - Get the location of the first token of this operand. SMLoc getStartLoc() const { return StartLoc; } /// getEndLoc - Get the location of the last token of this operand. @@ -142,6 +145,11 @@ struct X86Operand : public MCParsedAsmOperand { assert(Kind == Token && "Invalid access!"); return StringRef(Tok.Data, Tok.Length); } + void setTokenValue(StringRef Value) { + assert(Kind == Token && "Invalid access!"); + Tok.Data = Value.data(); + Tok.Length = Value.size(); + } unsigned getReg() const { assert(Kind == Register && "Invalid access!"); @@ -632,6 +640,54 @@ void X86ATTAsmParser::InstructionCleanup(MCInst &Inst) { } } +bool +X86ATTAsmParser::MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> + &Operands, + MCInst &Inst) { + // First, try a direct match. + if (!MatchInstructionImpl(Operands, Inst)) + return false; + + // Ignore anything which is obviously not a suffix match. + if (Operands.size() == 0) + return true; + X86Operand *Op = static_cast<X86Operand*>(Operands[0]); + if (!Op->isToken() || Op->getToken().size() > 15) + return true; + + // FIXME: Ideally, we would only attempt suffix matches for things which are + // valid prefixes, and we could just infer the right unambiguous + // type. However, that requires substantially more matcher support than the + // following hack. + + // Change the operand to point to a temporary token. + char Tmp[16]; + StringRef Base = Op->getToken(); + memcpy(Tmp, Base.data(), Base.size()); + Op->setTokenValue(StringRef(Tmp, Base.size() + 1)); + + // Check for the various suffix matches. + Tmp[Base.size()] = 'b'; + bool MatchB = MatchInstructionImpl(Operands, Inst); + Tmp[Base.size()] = 'w'; + bool MatchW = MatchInstructionImpl(Operands, Inst); + Tmp[Base.size()] = 'l'; + bool MatchL = MatchInstructionImpl(Operands, Inst); + + // Restore the old token. + 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 + // matches won't have modified it). + if (MatchB + MatchW + MatchL == 2) + return false; + + // Otherwise, the match failed. + return true; +} + + extern "C" void LLVMInitializeX86AsmLexer(); // Force static initialization. diff --git a/lib/Target/X86/X86.td b/lib/Target/X86/X86.td index ec86fc248e3d..a53f973c1c43 100644 --- a/lib/Target/X86/X86.td +++ b/lib/Target/X86/X86.td @@ -179,8 +179,9 @@ include "X86CallingConv.td" // Currently the X86 assembly parser only supports ATT syntax. def ATTAsmParser : AsmParser { - string AsmParserClassName = "ATTAsmParser"; - string AsmParserInstCleanup = "InstructionCleanup"; + string AsmParserClassName = "ATTAsmParser"; + string AsmParserInstCleanup = "InstructionCleanup"; + string MatchInstructionName = "MatchInstructionImpl"; int Variant = 0; // Discard comments in assembly strings. |
