diff options
Diffstat (limited to 'lib/Target/X86/AsmParser/X86AsmParser.cpp')
-rw-r--r-- | lib/Target/X86/AsmParser/X86AsmParser.cpp | 84 |
1 files changed, 66 insertions, 18 deletions
diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index d45dd35..cb4f15f 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -7,14 +7,12 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Target/TargetAsmParser.h" -#include "X86.h" -#include "X86Subtarget.h" -#include "llvm/Target/TargetRegistry.h" -#include "llvm/Target/TargetAsmParser.h" +#include "MCTargetDesc/X86BaseInfo.h" +#include "llvm/MC/MCTargetAsmParser.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" +#include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCParser/MCAsmLexer.h" #include "llvm/MC/MCParser/MCAsmParser.h" @@ -26,6 +24,7 @@ #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/SourceMgr.h" +#include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -33,7 +32,7 @@ using namespace llvm; namespace { struct X86Operand; -class X86ATTAsmParser : public TargetAsmParser { +class X86ATTAsmParser : public MCTargetAsmParser { MCSubtargetInfo &STI; MCAsmParser &Parser; @@ -48,6 +47,7 @@ private: X86Operand *ParseMemOperand(unsigned SegReg, SMLoc StartLoc); bool ParseDirectiveWord(unsigned Size, SMLoc L); + bool ParseDirectiveCode(StringRef IDVal, SMLoc L); bool MatchAndEmitInstruction(SMLoc IDLoc, SmallVectorImpl<MCParsedAsmOperand*> &Operands, @@ -65,6 +65,10 @@ private: // FIXME: Can tablegen auto-generate this? return (STI.getFeatureBits() & X86::Mode64Bit) != 0; } + void SwitchMode() { + unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(X86::Mode64Bit)); + setAvailableFeatures(FB); + } /// @name Auto-generated Matcher Functions /// { @@ -76,7 +80,7 @@ private: public: X86ATTAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser) - : TargetAsmParser(), STI(sti), Parser(parser) { + : MCTargetAsmParser(), STI(sti), Parser(parser) { // Initialize the set of available features. setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); @@ -223,6 +227,21 @@ struct X86Operand : public MCParsedAsmOperand { (0x00000000FFFFFF80ULL <= Value && Value <= 0x00000000FFFFFFFFULL)|| (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL)); } + bool isImmZExtu32u8() const { + if (!isImm()) + return false; + + // If this isn't a constant expr, just assume it fits and let relaxation + // handle it. + const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); + if (!CE) + return true; + + // Otherwise, check the value is in a range that makes sense for this + // extension. + uint64_t Value = CE->getValue(); + return (Value <= 0x00000000000000FFULL); + } bool isImmSExti64i8() const { if (!isImm()) return false; @@ -382,19 +401,25 @@ bool X86ATTAsmParser::ParseRegister(unsigned &RegNo, if (Tok.isNot(AsmToken::Identifier)) return Error(Tok.getLoc(), "invalid register name"); - // FIXME: Validate register for the current architecture; we have to do - // validation later, so maybe there is no need for this here. RegNo = MatchRegisterName(Tok.getString()); // If the match failed, try the register name as lowercase. if (RegNo == 0) RegNo = MatchRegisterName(LowercaseString(Tok.getString())); - // FIXME: This should be done using Requires<In32BitMode> and - // Requires<In64BitMode> so "eiz" usage in 64-bit instructions - // can be also checked. - if (RegNo == X86::RIZ && !is64BitMode()) - return Error(Tok.getLoc(), "riz register in 64-bit mode only"); + if (!is64BitMode()) { + // FIXME: This should be done using Requires<In32BitMode> and + // Requires<In64BitMode> so "eiz" usage in 64-bit instructions can be also + // checked. + // FIXME: Check AH, CH, DH, BH cannot be used in an instruction requiring a + // REX prefix. + if (RegNo == X86::RIZ || + X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) || + X86II::isX86_64NonExtLowByteReg(RegNo) || + X86II::isX86_64ExtendedReg(RegNo)) + return Error(Tok.getLoc(), "register %" + + Tok.getString() + " is only available in 64-bit mode"); + } // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens. if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) { @@ -472,7 +497,7 @@ X86Operand *X86ATTAsmParser::ParseOperand() { SMLoc Start, End; if (ParseRegister(RegNo, Start, End)) return 0; if (RegNo == X86::EIZ || RegNo == X86::RIZ) { - Error(Start, "eiz and riz can only be used as index registers"); + Error(Start, "%eiz and %riz can only be used as index registers"); return 0; } @@ -956,6 +981,7 @@ MatchAndEmitInstruction(SMLoc IDLoc, // First, try a direct match. switch (MatchInstructionImpl(Operands, Inst, OrigErrorInfo)) { + default: break; case Match_Success: Out.EmitInstruction(Inst); return false; @@ -994,7 +1020,7 @@ MatchAndEmitInstruction(SMLoc IDLoc, // Check for the various suffix matches. Tmp[Base.size()] = Suffixes[0]; unsigned ErrorInfoIgnore; - MatchResultTy Match1, Match2, Match3, Match4; + unsigned Match1, Match2, Match3, Match4; Match1 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore); Tmp[Base.size()] = Suffixes[1]; @@ -1096,6 +1122,8 @@ bool X86ATTAsmParser::ParseDirective(AsmToken DirectiveID) { StringRef IDVal = DirectiveID.getIdentifier(); if (IDVal == ".word") return ParseDirectiveWord(2, DirectiveID.getLoc()); + else if (IDVal.startswith(".code")) + return ParseDirectiveCode(IDVal, DirectiveID.getLoc()); return true; } @@ -1124,15 +1152,35 @@ bool X86ATTAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { return false; } +/// ParseDirectiveCode +/// ::= .code32 | .code64 +bool X86ATTAsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) { + if (IDVal == ".code32") { + Parser.Lex(); + if (is64BitMode()) { + SwitchMode(); + getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); + } + } else if (IDVal == ".code64") { + Parser.Lex(); + if (!is64BitMode()) { + SwitchMode(); + getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64); + } + } else { + return Error(L, "unexpected directive " + IDVal); + } + return false; +} extern "C" void LLVMInitializeX86AsmLexer(); // Force static initialization. extern "C" void LLVMInitializeX86AsmParser() { - RegisterAsmParser<X86ATTAsmParser> X(TheX86_32Target); - RegisterAsmParser<X86ATTAsmParser> Y(TheX86_64Target); + RegisterMCAsmParser<X86ATTAsmParser> X(TheX86_32Target); + RegisterMCAsmParser<X86ATTAsmParser> Y(TheX86_64Target); LLVMInitializeX86AsmLexer(); } |