diff options
author | Chris Lattner <sabre@nondot.org> | 2010-10-30 17:36:36 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-10-30 17:36:36 +0000 |
commit | 674c1dcca21f5edf9f7380902971fc5471c0bd4a (patch) | |
tree | b25b3b65baa600caf962eb7b8b666d378dfdcc40 | |
parent | 905b8f76142b43cd33c36c554d359ee8740f51d5 (diff) | |
download | external_llvm-674c1dcca21f5edf9f7380902971fc5471c0bd4a.zip external_llvm-674c1dcca21f5edf9f7380902971fc5471c0bd4a.tar.gz external_llvm-674c1dcca21f5edf9f7380902971fc5471c0bd4a.tar.bz2 |
implement (and document!) the first kind of MC assembler alias, which
just remaps one mnemonic to another. Convert a few of the X86 aliases
from .cpp to .td code.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@117815 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | docs/CodeGenerator.html | 55 | ||||
-rw-r--r-- | include/llvm/Target/Target.td | 19 | ||||
-rw-r--r-- | lib/Target/X86/AsmParser/X86AsmParser.cpp | 15 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrInfo.td | 23 | ||||
-rw-r--r-- | utils/TableGen/AsmMatcherEmitter.cpp | 30 |
5 files changed, 120 insertions, 22 deletions
diff --git a/docs/CodeGenerator.html b/docs/CodeGenerator.html index 3e0ac1b..de6a5c1 100644 --- a/docs/CodeGenerator.html +++ b/docs/CodeGenerator.html @@ -1878,15 +1878,64 @@ We've tried hard to automate the generation of the assembler from the .td files part of the manual and repetitive data entry can be factored and shared with the compiler.</p> +</div> +<!-- ======================================================================= --> +<div class="doc_subsection" id="na_instparsing">Instruction Parsing</div> -</div> +<div class="doc_text"><p>To Be Written</p></div> <!-- ======================================================================= --> -<div class="doc_subsection"> - <a name="proepicode">Prolog/Epilog Code Insertion</a> +<div class="doc_subsection" id="na_instaliases"> + Instruction Alias Processing </div> + +<div class="doc_text"> +<p>Once the instruction is parsed, it enters the MatchInstructionImpl function. +The MatchInstructionImpl function performs alias processing and then does +actual matching.</p> + +<p>Alias processing if the phase that canonicalizes different lexical forms of +the same instructions down to one representation. There are several different +kinds of alias that are possible to implement and they are listed below in the +order that they are processed (which is in order from simplest/weakest to most +complex/powerful). Generally you want to use the first alias mechanism that +meets the needs of your instruction, because it will allow a more concise +description.</p> + +<!-- _______________________________________________________________________ --> +<div class="doc_subsubsection">Mnemonic Aliases</div> + +<div class="doc_text"> + +<p>The first phase of alias processing is simple instruction mneomonic +remapping for classes of instructions which are allowed with two different +mneomonics. This phase is a simple and unconditionally remapping from one input +mnemonic to one output mnemonic. It isn't possible for this form of alias to +look at the operands at all, so the remapping must apply for all forms of a +given mnemonic. Mnemonic aliases are defined simply, for example X86 has: +</p> + +<div class="doc_code"> +<pre> +def : MnemonicAlias<"cbw", "cbtw">; +def : MnemonicAlias<"smovq", "movsq">; +def : MnemonicAlias<"fldcww", "fldcw">; +def : MnemonicAlias<"fucompi", "fucomip">; +def : MnemonicAlias<"ud2a", "ud2">; +</pre> +</div> + +<p>... and many others. With a MnemonicAlias definition, the mnemonic is +remapped simply and directly.</p> + +</div> + + +<!-- ======================================================================= --> +<div class="doc_subsection" id="na_matching">Instruction Matching</div> + <div class="doc_text"><p>To Be Written</p></div> diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 7db2e86..39f4ba7 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -530,6 +530,25 @@ class AsmParser { def DefaultAsmParser : AsmParser; +/// MnemonicAlias - This class allows targets to define assembler mnemonic +/// aliases. This should be used when all forms of one mnemonic are accepted +/// with a different mnemonic. For example, X86 allows: +/// sal %al, 1 -> shl %al, 1 +/// sal %ax, %cl -> shl %ax, %cl +/// sal %eax, %cl -> shl %eax, %cl +/// etc. Though "sal" is accepted with many forms, all of them are directly +/// translated to a shl, so it can be handled with (in the case of X86, it +/// actually has one for each suffix as well): +/// def : MnemonicAlias<"sal", "shl">; +/// +/// Mnemonic aliases are mapped before any other translation in the match phase. +/// +class MnemonicAlias<string From, string To> { + string FromMnemonic = From; + string ToMnemonic = To; +} + + //===----------------------------------------------------------------------===// // AsmWriter - This class can be implemented by targets that need to customize // the format of the .s file writer. diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index 4a8a63e..0666414 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -632,17 +632,6 @@ ParseInstruction(StringRef Name, SMLoc NameLoc, .Case("repe", "rep") .Case("repz", "rep") .Case("repnz", "repne") - .Case("iret", "iretl") - .Case("sysret", "sysretl") - .Case("cbw", "cbtw") - .Case("cwd", "cwtd") - .Case("cdq", "cltd") - .Case("cwde", "cwtl") - .Case("cdqe", "cltq") - .Case("smovb", "movsb") - .Case("smovw", "movsw") - .Case("smovl", "movsl") - .Case("smovq", "movsq") .Case("push", Is64Bit ? "pushq" : "pushl") .Case("pop", Is64Bit ? "popq" : "popl") .Case("pushf", Is64Bit ? "pushfq" : "pushfl") @@ -704,14 +693,10 @@ ParseInstruction(StringRef Name, SMLoc NameLoc, .Case("movzx", "movzb") // FIXME: Not correct. .Case("fildq", "fildll") .Case("fcompi", "fcomip") - .Case("fucompi", "fucomip") - .Case("fldcww", "fldcw") .Case("fnstcww", "fnstcw") .Case("fstcww", "fstcw") .Case("fnstsww", "fnstsw") .Case("fstsww", "fstsw") - .Case("verrw", "verr") - .Case("ud2a", "ud2") .Default(Name); // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}. diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index 86e0616..fd0caac 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -1254,3 +1254,26 @@ include "X86InstrSystem.td" // Compiler Pseudo Instructions and Pat Patterns include "X86InstrCompiler.td" +//===----------------------------------------------------------------------===// +// Assembler Aliases +//===----------------------------------------------------------------------===// + +def : MnemonicAlias<"iret", "iretl">; +def : MnemonicAlias<"sysret", "sysretl">; +def : MnemonicAlias<"cbw", "cbtw">; +def : MnemonicAlias<"cwd", "cwtd">; +def : MnemonicAlias<"cdq", "cltd">; +def : MnemonicAlias<"cwde", "cwtl">; +def : MnemonicAlias<"cdqe", "cltq">; +def : MnemonicAlias<"smovb", "movsb">; +def : MnemonicAlias<"smovw", "movsw">; +def : MnemonicAlias<"smovl", "movsl">; +def : MnemonicAlias<"smovq", "movsq">; + +def : MnemonicAlias<"fldcww", "fldcw">; +def : MnemonicAlias<"fucompi", "fucomip">; +def : MnemonicAlias<"ud2a", "ud2">; +def : MnemonicAlias<"verrw", "verr">; + + + diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index e64ce2f..99a32d8 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -1514,6 +1514,26 @@ static void EmitComputeAvailableFeatures(CodeGenTarget &Target, OS << "}\n\n"; } +/// EmitMnemonicAliases - If the target has any MnemonicAlias<> definitions, +/// emit them. +static void EmitMnemonicAliases(raw_ostream &OS) { + std::vector<Record*> Aliases = + Records.getAllDerivedDefinitions("MnemonicAlias"); + if (Aliases.empty()) return; + + OS << " // Process all MnemonicAliases to remap the mnemonic.\n"; + std::vector<StringMatcher::StringPair> Cases; + for (unsigned i = 0, e = Aliases.size(); i != e; ++i) { + Record *R = Aliases[i]; + Cases.push_back(std::make_pair(R->getValueAsString("FromMnemonic"), + "Mnemonic = \"" + + R->getValueAsString("ToMnemonic") + + "\"; break;")); + } + + StringMatcher("Mnemonic", Cases, OS).Emit(); +} + void AsmMatcherEmitter::run(raw_ostream &OS) { CodeGenTarget Target; Record *AsmParser = Target.getAsmParser(); @@ -1701,6 +1721,12 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << " // Get the current feature set.\n"; OS << " unsigned AvailableFeatures = getAvailableFeatures();\n\n"; + OS << " // Get the instruction mnemonic, which is the first token.\n"; + OS << " StringRef Mnemonic = ((" << Target.getName() + << "Operand*)Operands[0])->getToken();\n\n"; + + EmitMnemonicAliases(OS); + // Emit code to compute the class list for this operand vector. OS << " // Eliminate obvious mismatches.\n"; OS << " if (Operands.size() > " << (MaxNumOperands+1) << ") {\n"; @@ -1725,10 +1751,6 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { << "i != e; ++i)\n"; OS << " Classes[i] = InvalidMatchClass;\n\n"; - OS << " // Get the instruction mnemonic, which is the first token.\n"; - OS << " StringRef Mnemonic = ((" << Target.getName() - << "Operand*)Operands[0])->getToken();\n\n"; - OS << " // Some state to try to produce better error messages.\n"; OS << " bool HadMatchOtherThanFeatures = false;\n\n"; OS << " // Set ErrorInfo to the operand that mismatches if it is \n"; |