diff --git a/lib/Target/X86/X86InstrExtension.td b/lib/Target/X86/X86InstrExtension.td index a077fcea4b3..867c0f8b684 100644 --- a/lib/Target/X86/X86InstrExtension.td +++ b/lib/Target/X86/X86InstrExtension.td @@ -98,12 +98,12 @@ def MOVZX32rm16: I<0xB7, MRMSrcMem, (outs GR32:$dst), (ins i16mem:$src), // instead of GR32. This allows them to operate on h registers on x86-64. def MOVZX32_NOREXrr8 : I<0xB6, MRMSrcReg, (outs GR32_NOREX:$dst), (ins GR8:$src), - "movz{bl|x}\t{$src, $dst|$dst, $src} # NOREX", + "movz{bl|x}\t{$src, $dst|$dst, $src}", []>, TB; let mayLoad = 1 in def MOVZX32_NOREXrm8 : I<0xB6, MRMSrcMem, (outs GR32_NOREX:$dst), (ins i8mem:$src), - "movz{bl|x}\t{$src, $dst|$dst, $src} # NOREX", + "movz{bl|x}\t{$src, $dst|$dst, $src}", []>, TB; // MOVSX64rr8 always has a REX prefix and it has an 8-bit register diff --git a/test/MC/X86/x86-32-coverage.s b/test/MC/X86/x86-32-coverage.s index f97fc4bee03..66e5c38d996 100644 --- a/test/MC/X86/x86-32-coverage.s +++ b/test/MC/X86/x86-32-coverage.s @@ -18,7 +18,7 @@ // CHECK: movswl 3735928559(%ebx,%ecx,8), %ecx movswl 0xdeadbeef(%ebx,%ecx,8),%ecx -// CHECK: movzbl 3735928559(%ebx,%ecx,8), %ecx # NOREX +// CHECK: movzbl 3735928559(%ebx,%ecx,8), %ecx movzbl 0xdeadbeef(%ebx,%ecx,8),%ecx // CHECK: movzwl 3735928559(%ebx,%ecx,8), %ecx @@ -11807,19 +11807,19 @@ // CHECK: movswl 305419896, %ecx movswl 0x12345678,%ecx -// CHECK: movzbl 3735928559(%ebx,%ecx,8), %ecx # NOREX +// CHECK: movzbl 3735928559(%ebx,%ecx,8), %ecx movzbl 0xdeadbeef(%ebx,%ecx,8),%ecx -// CHECK: movzbl 69, %ecx # NOREX +// CHECK: movzbl 69, %ecx movzbl 0x45,%ecx -// CHECK: movzbl 32493, %ecx # NOREX +// CHECK: movzbl 32493, %ecx movzbl 0x7eed,%ecx -// CHECK: movzbl 3133065982, %ecx # NOREX +// CHECK: movzbl 3133065982, %ecx movzbl 0xbabecafe,%ecx -// CHECK: movzbl 305419896, %ecx # NOREX +// CHECK: movzbl 305419896, %ecx movzbl 0x12345678,%ecx // CHECK: movzbw 3735928559(%ebx,%ecx,8), %bx diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index d4fe6beca3b..5ae43a38f86 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -355,26 +355,18 @@ struct InstructionInfo { /// function. std::string ConversionFnKind; - InstructionInfo(const CodeGenInstruction &CGI, StringRef CommentDelimiter) + InstructionInfo(const CodeGenInstruction &CGI) : TheDef(CGI.TheDef), OperandList(CGI.Operands) { InstrName = TheDef->getName(); // TODO: Eventually support asmparser for Variant != 0. AsmString = CGI.FlattenAsmStringVariants(CGI.AsmString, 0); - // Remove comments from the asm string. We know that the asmstring only - // has one line. - if (!CommentDelimiter.empty()) { - size_t Idx = StringRef(AsmString).find(CommentDelimiter); - if (Idx != StringRef::npos) - AsmString = AsmString.substr(0, Idx); - } - TokenizeAsmString(AsmString, Tokens); } /// isAssemblerInstruction - Return true if this matchable is a valid thing to /// match against. - bool isAssemblerInstruction() const; + bool isAssemblerInstruction(StringRef CommentDelimiter) const; /// getSingletonRegisterForToken - If the specified token is a singleton /// register, return the Record for it, otherwise return null. @@ -465,9 +457,6 @@ public: /// Target - The target information. CodeGenTarget &Target; - /// The AsmParser "CommentDelimiter" value. - std::string CommentDelimiter; - /// The AsmParser "RegisterPrefix" value. std::string RegisterPrefix; @@ -567,7 +556,7 @@ static Record *getRegisterRecord(CodeGenTarget &Target, StringRef Name) { return 0; } -bool InstructionInfo::isAssemblerInstruction() const { +bool InstructionInfo::isAssemblerInstruction(StringRef CommentDelimiter) const { StringRef Name = InstrName; // Reject instructions with no .s string. @@ -581,6 +570,14 @@ bool InstructionInfo::isAssemblerInstruction() const { "multiline instruction is not valid for the asmparser, " "mark it isCodeGenOnly"); + // Remove comments from the asm string. We know that the asmstring only + // has one line. + if (!CommentDelimiter.empty() && + StringRef(AsmString).find(CommentDelimiter) != StringRef::npos) + throw TGError(TheDef->getLoc(), + "asmstring for instruction has comment character in it, " + "mark it isCodeGenOnly"); + // Reject instructions with attributes, these aren't something we can handle, // the target should be refactored to use operands instead of modifiers. // @@ -674,10 +671,8 @@ AsmMatcherInfo::getOperandClass(StringRef Token, if (OI.Rec->isSubClassOf("RegisterClass")) { ClassInfo *CI = RegisterClassClasses[OI.Rec]; - if (!CI) { - PrintError(OI.Rec->getLoc(), "register class has no class info!"); - throw std::string("ERROR: Missing register class!"); - } + if (!CI) + throw TGError(OI.Rec->getLoc(), "register class has no class info!"); return CI; } @@ -686,10 +681,8 @@ AsmMatcherInfo::getOperandClass(StringRef Token, Record *MatchClass = OI.Rec->getValueAsDef("ParserMatchClass"); ClassInfo *CI = AsmOperandClasses[MatchClass]; - if (!CI) { - PrintError(OI.Rec->getLoc(), "operand has no match class!"); - throw std::string("ERROR: Missing match class!"); - } + if (!CI) + throw TGError(OI.Rec->getLoc(), "operand has no match class!"); return CI; } @@ -876,7 +869,6 @@ void AsmMatcherInfo::BuildOperandClasses() { AsmMatcherInfo::AsmMatcherInfo(Record *asmParser, CodeGenTarget &target) : AsmParser(asmParser), Target(target), - CommentDelimiter(AsmParser->getValueAsString("CommentDelimiter")), RegisterPrefix(AsmParser->getValueAsString("RegisterPrefix")) { } @@ -891,16 +883,16 @@ void AsmMatcherInfo::BuildInfo() { if (!Pred->getValueAsBit("AssemblerMatcherPredicate")) continue; - if (Pred->getName().empty()) { - PrintError(Pred->getLoc(), "Predicate has no name!"); - throw std::string("ERROR: Predicate defs must be named"); - } + if (Pred->getName().empty()) + throw TGError(Pred->getLoc(), "Predicate has no name!"); unsigned FeatureNo = SubtargetFeatures.size(); SubtargetFeatures[Pred] = new SubtargetFeatureInfo(Pred, FeatureNo); assert(FeatureNo < 32 && "Too many subtarget features!"); } + StringRef CommentDelimiter = AsmParser->getValueAsString("CommentDelimiter"); + // Parse the instructions; we need to do this first so that we can gather the // singleton register classes. SmallPtrSet SingletonRegisters; @@ -917,11 +909,11 @@ void AsmMatcherInfo::BuildInfo() { if (CGI.TheDef->getValueAsBit("isCodeGenOnly")) continue; - OwningPtr II(new InstructionInfo(CGI, CommentDelimiter)); + OwningPtr II(new InstructionInfo(CGI)); // Ignore instructions which shouldn't be matched and diagnose invalid // instruction definitions with an error. - if (!II->isAssemblerInstruction()) + if (!II->isAssemblerInstruction(CommentDelimiter)) continue; // Ignore "Int_*" and "*_Int" instructions, which are internal aliases. @@ -1010,8 +1002,8 @@ void AsmMatcherInfo::BuildInfo() { // Map this token to an operand. FIXME: Move elsewhere. unsigned Idx; if (!II->OperandList.hasOperandNamed(OperandName, Idx)) - throw std::string("error: unable to find operand: '" + - OperandName.str() + "'"); + throw TGError(II->TheDef->getLoc(), "error: unable to find operand: '" + + OperandName.str() + "'"); // FIXME: This is annoying, the named operand may be tied (e.g., // XCHG8rm). What we want is the untied operand, which we now have to @@ -1536,8 +1528,7 @@ static bool EmitMnemonicAliases(raw_ostream &OS, const AsmMatcherInfo &Info) { // We can't have two aliases from the same mnemonic with no predicate. PrintError(ToVec[AliasWithNoPredicate]->getLoc(), "two MnemonicAliases with the same 'from' mnemonic!"); - PrintError(R->getLoc(), "this is the other MnemonicAlias."); - throw std::string("ERROR: Invalid MnemonicAlias definitions!"); + throw TGError(R->getLoc(), "this is the other MnemonicAlias."); } AliasWithNoPredicate = i;