Index: lib/Target/X86/AsmParser/X86AsmParser.cpp =================================================================== --- lib/Target/X86/AsmParser/X86AsmParser.cpp +++ lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -1694,8 +1694,9 @@ bool Parse32 = is32BitMode() || Code16GCC; unsigned RegNo = is64BitMode() ? X86::RBX : (Parse32 ? X86::EBX : X86::BX); - return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true, - OffsetOfLoc, Identifier, Decl); + return X86Operand::CreateReg( + RegNo, Start, End, getContext().getRegisterInfo(), /*GetAddress=*/true, + OffsetOfLoc, Identifier, Decl); } // Query a candidate string for being an Intel assembly operator @@ -1803,9 +1804,11 @@ return ErrorOperand(Start, "rip can only be used as a base register"); // A Register followed by ':' is considered a segment override if (Tok.isNot(AsmToken::Colon)) - return !PtrInOperand ? X86Operand::CreateReg(RegNo, Start, End) : - ErrorOperand(Start, "expected memory operand after 'ptr', " - "found register operand instead"); + return !PtrInOperand + ? X86Operand::CreateReg(RegNo, Start, End, + getContext().getRegisterInfo()) + : ErrorOperand(Start, "expected memory operand after 'ptr', " + "found register operand instead"); // An alleged segment override. check if we have a valid segment register if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo)) return ErrorOperand(Start, "invalid segment register"); @@ -1877,7 +1880,8 @@ // If this is a segment register followed by a ':', then this is the start // of a memory reference, otherwise this is a normal register reference. if (getLexer().isNot(AsmToken::Colon)) - return X86Operand::CreateReg(RegNo, Start, End); + return X86Operand::CreateReg(RegNo, Start, End, + getContext().getRegisterInfo()); if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo)) return ErrorOperand(Start, "invalid segment register"); @@ -1983,8 +1987,8 @@ if (!getLexer().is(AsmToken::RCurly)) return Error(getLexer().getLoc(), "Expected } at this point"); Operands.push_back(X86Operand::CreateToken("{", StartLoc)); - Operands.push_back( - X86Operand::CreateReg(RegNo, StartLoc, StartLoc)); + Operands.push_back(X86Operand::CreateReg( + RegNo, StartLoc, StartLoc, getContext().getRegisterInfo())); Operands.push_back(X86Operand::CreateToken("}", consumeToken())); } else return Error(getLexer().getLoc(), @@ -2468,7 +2472,8 @@ // Select the correct equivalent 16-/32-bit source register. unsigned Reg = getX86SubSuperRegisterOrZero(Op1.getReg(), is16BitMode() ? 16 : 32); - Operands[1] = X86Operand::CreateReg(Reg, Loc, Loc); + Operands[1] = + X86Operand::CreateReg(Reg, Loc, Loc, getContext().getRegisterInfo()); } } @@ -2484,7 +2489,8 @@ cast(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); + Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc, + getContext().getRegisterInfo()); } } // Same hack for "in[s]?[bwl]? (%dx), %al" -> "inb %dx, %al". @@ -2497,7 +2503,8 @@ cast(Op.Mem.Disp)->getValue() == 0 && Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) { SMLoc Loc = Op.getEndLoc(); - Operands[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc); + Operands[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc, + getContext().getRegisterInfo()); } } @@ -2509,10 +2516,11 @@ (Operands.size() == 1 || Operands.size() == 3) && (Name == "insb" || Name == "insw" || Name == "insl" || Name == "insd" || Name == "ins")) { - - AddDefaultSrcDestOperands(TmpOperands, - X86Operand::CreateReg(X86::DX, NameLoc, NameLoc), - DefaultMemDIOperand(NameLoc)); + + AddDefaultSrcDestOperands( + TmpOperands, X86Operand::CreateReg(X86::DX, NameLoc, NameLoc, + getContext().getRegisterInfo()), + DefaultMemDIOperand(NameLoc)); HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands); } @@ -2521,8 +2529,10 @@ (Operands.size() == 1 || Operands.size() == 3) && (Name == "outsb" || Name == "outsw" || Name == "outsl" || Name == "outsd" || Name == "outs")) { - AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc), - X86Operand::CreateReg(X86::DX, NameLoc, NameLoc)); + AddDefaultSrcDestOperands( + TmpOperands, DefaultMemSIOperand(NameLoc), + X86Operand::CreateReg(X86::DX, NameLoc, NameLoc, + getContext().getRegisterInfo())); HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands); } Index: lib/Target/X86/AsmParser/X86Operand.h =================================================================== --- lib/Target/X86/AsmParser/X86Operand.h +++ lib/Target/X86/AsmParser/X86Operand.h @@ -36,6 +36,7 @@ StringRef SymName; void *OpDecl; bool AddressOf; + const MCRegisterInfo *MRI; struct TokOp { const char *Data; @@ -76,8 +77,9 @@ struct PrefOp Pref; }; - X86Operand(KindTy K, SMLoc Start, SMLoc End) - : Kind(K), StartLoc(Start), EndLoc(End) {} + X86Operand(KindTy K, SMLoc Start, SMLoc End, + const MCRegisterInfo *RI = nullptr) + : Kind(K), StartLoc(Start), EndLoc(End), MRI(RI) {} StringRef getSymName() override { return SymName; } void *getOpDecl() override { return OpDecl; } @@ -95,7 +97,65 @@ /// getOffsetOfLoc - Get the location of the offset operator. SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; } - void print(raw_ostream &OS) const override {} + union ImmValResult { + const char* SResult; + int64_t IResult; + }; + + static bool getImmValue(const MCExpr *Val, union ImmValResult &Result) { + if (Val->getKind() == MCExpr::Constant) { + Result.IResult = cast(Val)->getValue(); + return false; + } + assert(Val->getKind() == MCExpr::SymbolRef); + const MCSymbolRefExpr &SRE = cast(*Val); + const MCSymbol &Sym = SRE.getSymbol(); + Result.SResult = Sym.getName().data(); + return true; + } + + void print(raw_ostream &OS) const override { + union ImmValResult Result; + switch (Kind) { + case Token: + OS << Tok.Data; + break; + case Register: + assert(MRI && "Invalid register operand"); + OS << "Reg:" << MRI->getName(Reg.RegNo); + break; + case Immediate: + if (getImmValue(Imm.Val, Result)) { + if (Result.SResult) + OS << "Imm:" << Result.SResult; + } else + OS << "Imm:" << Result.IResult; + break; + case Prefix: + OS << "Prefix:" << Pref.Prefixes; + break; + case Memory: + OS << "Memory: ModeSize=" << Mem.ModeSize; + if (Mem.Size) + OS << ",Size=" << Mem.Size; + if (Mem.BaseReg) + OS << ",BaseReg=" << Mem.BaseReg; + if (Mem.IndexReg) + OS << ",IndexReg=" << Mem.IndexReg; + if (Mem.Scale) + OS << ",Scale=" << Mem.Scale; + if (Mem.Disp) { + if (getImmValue(Mem.Disp, Result)) { + if (Result.SResult) + OS << ",Disp=" << Result.SResult; + } else if (Result.IResult) + OS << ",Disp=" << Result.IResult; + } + if (Mem.SegReg) + OS << ",SegReg=" << Mem.SegReg; + break; + } + } StringRef getToken() const { assert(Kind == Token && "Invalid access!"); @@ -505,9 +565,10 @@ static std::unique_ptr CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc, - bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(), - StringRef SymName = StringRef(), void *OpDecl = nullptr) { - auto Res = llvm::make_unique(Register, StartLoc, EndLoc); + const MCRegisterInfo *MRI, bool AddressOf = false, + SMLoc OffsetOfLoc = SMLoc(), StringRef SymName = StringRef(), + void *OpDecl = nullptr) { + auto Res = llvm::make_unique(Register, StartLoc, EndLoc, MRI); Res->Reg.RegNo = RegNo; Res->AddressOf = AddressOf; Res->OffsetOfLoc = OffsetOfLoc; Index: test/MC/X86/x86_64-asm-match.s =================================================================== --- test/MC/X86/x86_64-asm-match.s +++ test/MC/X86/x86_64-asm-match.s @@ -2,46 +2,45 @@ // REQUIRES: asserts // CHECK: AsmMatcher: found 4 encodings with mnemonic 'pshufb' -// CHECK:Trying to match opcode MMX_PSHUFBrr64 -// CHECK: Matching formal operand class MCK_VR64 against actual operand at index 1 (): Opcode result: multiple operand mismatches, ignoring this opcode -// CHECK:Trying to match opcode PSHUFBrr -// CHECK: Matching formal operand class MCK_FR32 against actual operand at index 1 (): Opcode result: multiple operand mismatches, ignoring this opcode -// CHECK:Trying to match opcode PSHUFBrm -// CHECK: Matching formal operand class MCK_Mem128 against actual operand at index 1 (): match success using generic matcher -// CHECK: Matching formal operand class MCK_FR32 against actual operand at index 2 (): match success using generic matcher -// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range Opcode result: complete match, selecting this opcode -// CHECK:AsmMatcher: found 2 encodings with mnemonic 'sha1rnds4' -// CHECK:Trying to match opcode SHA1RNDS4rri -// CHECK: Matching formal operand class MCK_ImmUnsignedi8 against actual operand at index 1 (): match success using generic matcher -// CHECK: Matching formal operand class MCK_FR32 against actual operand at index 2 (): match success using generic matcher -// CHECK: Matching formal operand class MCK_FR32 against actual operand at index 3 (): match success using generic matcher -// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range Opcode result: complete match, selecting this opcode -// CHECK:AsmMatcher: found 4 encodings with mnemonic 'pinsrw' -// CHECK:Trying to match opcode MMX_PINSRWirri -// CHECK: Matching formal operand class MCK_ImmUnsignedi8 against actual operand at index 1 (): match success using generic matcher -// CHECK: Matching formal operand class MCK_GR32orGR64 against actual operand at index 2 (): match success using generic matcher -// CHECK: Matching formal operand class MCK_VR64 against actual operand at index 3 (): Opcode result: multiple operand mismatches, ignoring this opcode -// CHECK:Trying to match opcode PINSRWrri -// CHECK: Matching formal operand class MCK_ImmUnsignedi8 against actual operand at index 1 (): match success using generic matcher -// CHECK: Matching formal operand class MCK_GR32orGR64 against actual operand at index 2 (): match success using generic matcher -// CHECK: Matching formal operand class MCK_FR32 against actual operand at index 3 (): match success using generic matcher -// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range Opcode result: complete match, selecting this opcode -// CHECK:AsmMatcher: found 2 encodings with mnemonic 'crc32l' -// CHECK:Trying to match opcode CRC32r32r32 -// CHECK: Matching formal operand class MCK_GR32 against actual operand at index 1 (): Opcode result: multiple operand mismatches, ignoring this opcode -// CHECK:Trying to match opcode CRC32r32m32 -// CHECK: Matching formal operand class MCK_Mem32 against actual operand at index 1 (): match success using generic matcher -// CHECK: Matching formal operand class MCK_GR32 against actual operand at index 2 (): match success using generic matcher -// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range Opcode result: complete match, selecting this opcode -// CHECK:AsmMatcher: found 4 encodings with mnemonic 'punpcklbw' -// CHECK:Trying to match opcode MMX_PUNPCKLBWirr -// CHECK: Matching formal operand class MCK_VR64 against actual operand at index 1 (): match success using generic matcher -// CHECK: Matching formal operand class MCK_VR64 against actual operand at index 2 (): Opcode result: multiple operand mismatches, ignoring this opcode -// CHECK:Trying to match opcode MMX_PUNPCKLBWirm -// CHECK: Matching formal operand class MCK_VR64 against actual operand at index 1 (): match success using generic matcher -// CHECK: Matching formal operand class MCK_Mem64 against actual operand at index 2 (): match success using generic matcher -// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range Opcode result: complete match, selecting this opcode - +// CHECK: Trying to match opcode MMX_PSHUFBrr64 +// CHECK: Matching formal operand class MCK_VR64 against actual operand at index 1 (Memory: ModeSize=64,BaseReg=41,Scale=1,Disp=CPI1_0): Opcode result: multiple operand mismatches, ignoring this opcode +// CHECK: Trying to match opcode PSHUFBrr +// CHECK: Matching formal operand class MCK_FR32 against actual operand at index 1 (Memory: ModeSize=64,BaseReg=41,Scale=1,Disp=CPI1_0): Opcode result: multiple operand mismatches, ignoring this opcode +// CHECK: Trying to match opcode PSHUFBrm +// CHECK: Matching formal operand class MCK_Mem128 against actual operand at index 1 (Memory: ModeSize=64,BaseReg=41,Scale=1,Disp=CPI1_0): match success using generic matcher +// CHECK: Matching formal operand class MCK_FR32 against actual operand at index 2 (Reg:XMM1): match success using generic matcher +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range Opcode result: complete match, selecting this opcode +// CHECK: AsmMatcher: found 2 encodings with mnemonic 'sha1rnds4' +// CHECK: Trying to match opcode SHA1RNDS4rri +// CHECK: Matching formal operand class MCK_ImmUnsignedi8 against actual operand at index 1 (Imm:1): match success using generic matcher +// CHECK: Matching formal operand class MCK_FR32 against actual operand at index 2 (Reg:XMM1): match success using generic matcher +// CHECK: Matching formal operand class MCK_FR32 against actual operand at index 3 (Reg:XMM2): match success using generic matcher +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range Opcode result: complete match, selecting this opcode +// CHECK: AsmMatcher: found 4 encodings with mnemonic 'pinsrw' +// CHECK: Trying to match opcode MMX_PINSRWirri +// CHECK: Matching formal operand class MCK_ImmUnsignedi8 against actual operand at index 1 (Imm:3): match success using generic matcher +// CHECK: Matching formal operand class MCK_GR32orGR64 against actual operand at index 2 (Reg:ECX): match success using generic matcher +// CHECK: Matching formal operand class MCK_VR64 against actual operand at index 3 (Reg:XMM5): Opcode result: multiple operand mismatches, ignoring this opcode +// CHECK: Trying to match opcode PINSRWrri +// CHECK: Matching formal operand class MCK_ImmUnsignedi8 against actual operand at index 1 (Imm:3): match success using generic matcher +// CHECK: Matching formal operand class MCK_GR32orGR64 against actual operand at index 2 (Reg:ECX): match success using generic matcher +// CHECK: Matching formal operand class MCK_FR32 against actual operand at index 3 (Reg:XMM5): match success using generic matcher +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range Opcode result: complete match, selecting this opcode +// CHECK: AsmMatcher: found 2 encodings with mnemonic 'crc32l' +// CHECK: Trying to match opcode CRC32r32r32 +// CHECK: Matching formal operand class MCK_GR32 against actual operand at index 1 (Memory: ModeSize=64,BaseReg=37,IndexReg=38,Scale=8,Disp=3735928559,SegReg=33): Opcode result: multiple operand mismatches, ignoring this opcode +// CHECK: Trying to match opcode CRC32r32m32 +// CHECK: Matching formal operand class MCK_Mem32 against actual operand at index 1 (Memory: ModeSize=64,BaseReg=37,IndexReg=38,Scale=8,Disp=3735928559,SegReg=33): match success using generic matcher +// CHECK: Matching formal operand class MCK_GR32 against actual operand at index 2 (Reg:ECX): match success using generic matcher +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range Opcode result: complete match, selecting this opcode +// CHECK: AsmMatcher: found 4 encodings with mnemonic 'punpcklbw' +// CHECK: Trying to match opcode MMX_PUNPCKLBWirr +// CHECK: Matching formal operand class MCK_VR64 against actual operand at index 1 (Reg:MM0): match success using generic matcher +// CHECK: Matching formal operand class MCK_VR64 against actual operand at index 2 (Memory: ModeSize=64,Size=64,BaseReg=44,Scale=1): Opcode result: multiple operand mismatches, ignoring this opcode +// CHECK: Trying to match opcode MMX_PUNPCKLBWirm +// CHECK: Matching formal operand class MCK_VR64 against actual operand at index 1 (Reg:MM0): match success using generic matcher +// CHECK: Matching formal operand class MCK_Mem64 against actual operand at index 2 (Memory: ModeSize=64,Size=64,BaseReg=44,Scale=1): match success using generic matcher +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range Opcode result: complete match, selecting this opcode pshufb CPI1_0(%rip), %xmm1 sha1rnds4 $1, %xmm1, %xmm2