summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/X86/X86InstrExtension.td4
-rw-r--r--test/MC/X86/x86-32-coverage.s12
-rw-r--r--utils/TableGen/AsmMatcherEmitter.cpp57
3 files changed, 32 insertions, 41 deletions
diff --git a/lib/Target/X86/X86InstrExtension.td b/lib/Target/X86/X86InstrExtension.td
index a077fcea4b..867c0f8b68 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 f97fc4bee0..66e5c38d99 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 d4fe6beca3..5ae43a38f8 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<Record*, 16> SingletonRegisters;
@@ -917,11 +909,11 @@ void AsmMatcherInfo::BuildInfo() {
if (CGI.TheDef->getValueAsBit("isCodeGenOnly"))
continue;
- OwningPtr<InstructionInfo> II(new InstructionInfo(CGI, CommentDelimiter));
+ OwningPtr<InstructionInfo> 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;