From 5bde7345980587284bda6d42a68cdb151fbf5d6b Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 6 Nov 2010 08:20:59 +0000 Subject: [PATCH] fix a bug where we had an implicit assumption that the result instruction operand numbering matched the result pattern. Fixing this allows us to move the xchg/test aliases to the .td file. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@118334 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/AsmParser/X86AsmParser.cpp | 21 --------------------- lib/Target/X86/X86InstrInfo.td | 20 ++++++++++++++------ utils/TableGen/AsmMatcherEmitter.cpp | 5 +++-- utils/TableGen/CodeGenInstruction.cpp | 18 ++++++++++++++++++ utils/TableGen/CodeGenInstruction.h | 5 +++++ 5 files changed, 40 insertions(+), 29 deletions(-) diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index e3c427f8ced..0837b69d3f9 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -877,27 +877,6 @@ ParseInstruction(StringRef Name, SMLoc NameLoc, Operands[0] = X86Operand::CreateToken("sldtw", NameLoc); } - // The assembler accepts "xchgX , " and "xchgX , " as - // synonyms. Our tables only have the ", " form, so if we see the - // other operand order, swap them. - if (Name == "xchgb" || Name == "xchgw" || Name == "xchgl" || Name == "xchgq"|| - Name == "xchg") - if (Operands.size() == 3 && - static_cast(Operands[1])->isMem() && - static_cast(Operands[2])->isReg()) { - std::swap(Operands[1], Operands[2]); - } - - // The assembler accepts "testX , " and "testX , " as - // synonyms. Our tables only have the ", " form, so if we see the - // other operand order, swap them. - if (Name == "testb" || Name == "testw" || Name == "testl" || Name == "testq"|| - Name == "test") - if (Operands.size() == 3 && - static_cast(Operands[1])->isReg() && - static_cast(Operands[2])->isMem()) { - std::swap(Operands[1], Operands[2]); - } // The assembler accepts these instructions with no operand as a synonym for // an instruction acting on st(1). e.g. "fxch" -> "fxch %st(1)". diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index 8b3c9bca50a..f1bc8447689 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -1060,17 +1060,14 @@ let Constraints = "$val = $dst" in { def XCHG8rm : I<0x86, MRMSrcMem, (outs GR8:$dst), (ins GR8:$val, i8mem:$ptr), "xchg{b}\t{$val, $ptr|$ptr, $val}", [(set GR8:$dst, (atomic_swap_8 addr:$ptr, GR8:$val))]>; -def XCHG16rm : I<0x87, MRMSrcMem, (outs GR16:$dst), - (ins GR16:$val, i16mem:$ptr), +def XCHG16rm : I<0x87, MRMSrcMem, (outs GR16:$dst),(ins GR16:$val, i16mem:$ptr), "xchg{w}\t{$val, $ptr|$ptr, $val}", [(set GR16:$dst, (atomic_swap_16 addr:$ptr, GR16:$val))]>, OpSize; -def XCHG32rm : I<0x87, MRMSrcMem, (outs GR32:$dst), - (ins GR32:$val, i32mem:$ptr), +def XCHG32rm : I<0x87, MRMSrcMem, (outs GR32:$dst),(ins GR32:$val, i32mem:$ptr), "xchg{l}\t{$val, $ptr|$ptr, $val}", [(set GR32:$dst, (atomic_swap_32 addr:$ptr, GR32:$val))]>; -def XCHG64rm : RI<0x87, MRMSrcMem, (outs GR64:$dst), - (ins GR64:$val,i64mem:$ptr), +def XCHG64rm : RI<0x87, MRMSrcMem, (outs GR64:$dst),(ins GR64:$val,i64mem:$ptr), "xchg{q}\t{$val, $ptr|$ptr, $val}", [(set GR64:$dst, (atomic_swap_64 addr:$ptr, GR64:$val))]>; @@ -1414,4 +1411,15 @@ def : InstAlias<"movzx $src, $dst", (MOVZX64rr8_Q GR64:$dst, GR8:$src)>; def : InstAlias<"movzx $src, $dst", (MOVZX64rr16_Q GR64:$dst, GR16:$src)>; // Note: No GR32->GR64 movzx form. +// test: We accept "testX , " and "testX , " as synonyms. +def : InstAlias<"testb $val, $mem", (TEST8rm GR8 :$val, i8mem :$mem)>; +def : InstAlias<"testw $val, $mem", (TEST16rm GR16:$val, i16mem:$mem)>; +def : InstAlias<"testl $val, $mem", (TEST32rm GR32:$val, i32mem:$mem)>; +def : InstAlias<"testq $val, $mem", (TEST64rm GR64:$val, i64mem:$mem)>; + +// xchg: We accept "xchgX , " and "xchgX , " as synonyms. +def : InstAlias<"xchgb $mem, $val", (XCHG8rm GR8 :$val, i8mem :$mem)>; +def : InstAlias<"xchgw $mem, $val", (XCHG16rm GR16:$val, i16mem:$mem)>; +def : InstAlias<"xchgl $mem, $val", (XCHG32rm GR32:$val, i32mem:$mem)>; +def : InstAlias<"xchgq $mem, $val", (XCHG64rm GR64:$val, i64mem:$mem)>; diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index 6a70c5a4b5f..23d370c506e 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -1171,13 +1171,14 @@ void AsmMatcherInfo::BuildAliasOperandReference(MatchableInfo *II, StringRef OperandName, MatchableInfo::AsmOperand &Op) { const CodeGenInstAlias &CGA = *II->DefRec.get(); - + // Set up the operand class. for (unsigned i = 0, e = CGA.ResultOperands.size(); i != e; ++i) if (CGA.ResultOperands[i].Name == OperandName) { // It's safe to go with the first one we find, because CodeGenInstAlias // validates that all operands with the same name have the same record. - Op.Class = getOperandClass(CGA.ResultInst->Operands[i]); + unsigned ResultIdx =CGA.getResultInstOperandIndexForResultOperandIndex(i); + Op.Class = getOperandClass(CGA.ResultInst->Operands[ResultIdx]); Op.SrcOpName = OperandName; return; } diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp index 73b7b78d09b..40d4206b30e 100644 --- a/utils/TableGen/CodeGenInstruction.cpp +++ b/utils/TableGen/CodeGenInstruction.cpp @@ -459,3 +459,21 @@ CodeGenInstAlias::CodeGenInstAlias(Record *R, CodeGenTarget &T) : TheDef(R) { " instruction expects " + utostr(ResultInst->Operands.size())+ " operands!"); } + +/// getResultInstOperandIndexForResultOperandIndex - Given an index into the +/// ResultOperands array, translate it to a valid index in ResultInst's +/// operand list. +unsigned CodeGenInstAlias:: +getResultInstOperandIndexForResultOperandIndex(unsigned OpNo) const { + unsigned OpIdx = 0; + + for (unsigned i = 0;; ++i) { + assert(i != ResultInst->Operands.size() && "Didn't find entry"); + if (ResultInst->Operands[i].getTiedRegister() != -1) + continue; + + if (OpIdx == OpNo) return i; + + ++OpIdx; + } +} diff --git a/utils/TableGen/CodeGenInstruction.h b/utils/TableGen/CodeGenInstruction.h index 0e636a87679..f5b22396360 100644 --- a/utils/TableGen/CodeGenInstruction.h +++ b/utils/TableGen/CodeGenInstruction.h @@ -277,6 +277,11 @@ namespace llvm { std::vector ResultOperands; CodeGenInstAlias(Record *R, CodeGenTarget &T); + + /// getResultInstOperandIndexForResultOperandIndex - Given an index into the + /// ResultOperands array, translate it to a valid index in ResultInst's + /// operand list. + unsigned getResultInstOperandIndexForResultOperandIndex(unsigned i) const; }; }