[llvm-commits] [llvm] r118350 - in /llvm/trunk: docs/CodeGenerator.html lib/Target/X86/AsmParser/X86AsmParser.cpp lib/Target/X86/X86InstrInfo.td utils/TableGen/AsmMatcherEmitter.cpp utils/TableGen/CodeGenInstruction.cpp utils/TableGen/CodeGenInstruction.h

Chris Lattner sabre at nondot.org
Sat Nov 6 12:25:43 PDT 2010


Author: lattner
Date: Sat Nov  6 14:25:43 2010
New Revision: 118350

URL: http://llvm.org/viewvc/llvm-project?rev=118350&view=rev
Log:
generalize alias support to allow the result of an alias to
add fixed immediate values.  Move the aad and aam aliases to
use this, and document it.

Modified:
    llvm/trunk/docs/CodeGenerator.html
    llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp
    llvm/trunk/lib/Target/X86/X86InstrInfo.td
    llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp
    llvm/trunk/utils/TableGen/CodeGenInstruction.cpp
    llvm/trunk/utils/TableGen/CodeGenInstruction.h

Modified: llvm/trunk/docs/CodeGenerator.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CodeGenerator.html?rev=118350&r1=118349&r2=118350&view=diff
==============================================================================
--- llvm/trunk/docs/CodeGenerator.html (original)
+++ llvm/trunk/docs/CodeGenerator.html Sat Nov  6 14:25:43 2010
@@ -1998,7 +1998,15 @@
 <p>This example also shows that tied operands are only listed once.  In the X86
 backend, XOR8rr has two input GR8's and one output GR8 (where an input is tied
 to the output).  InstAliases take a flattened operand list without duplicates
-for tied operands.</p>
+for tied operands.  The result of an instruction alias can also use immediates,
+which are added as simple immediate operands in the result, for example:</p>
+
+<div class="doc_code">
+<pre>
+def : InstAlias<"aad", (AAD8i8 10)>;
+</pre>
+</div>
+
 
 <p>Instruction aliases can also have a Requires clause to make them
 subtarget specific.</p>

Modified: llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp?rev=118350&r1=118349&r2=118350&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp (original)
+++ llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp Sat Nov  6 14:25:43 2010
@@ -752,6 +752,22 @@
   if (getLexer().is(AsmToken::EndOfStatement))
     Parser.Lex(); // Consume the EndOfStatement
 
+  // This is a terrible hack to handle "out[bwl]? %al, (%dx)" ->
+  // "outb %al, %dx".  Out doesn't take a memory form, but this is a widely
+  // documented form in various unofficial manuals, so a lot of code uses it.
+  if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") &&
+      Operands.size() == 3) {
+    X86Operand &Op = *(X86Operand*)Operands.back();
+    if (Op.isMem() && Op.Mem.SegReg == 0 &&
+        isa<MCConstantExpr>(Op.Mem.Disp) &&
+        cast<MCConstantExpr>(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);
+      delete &Op;
+    }
+  }
+  
   // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>.  Canonicalize to
   // "shift <op>".
   if ((Name.startswith("shr") || Name.startswith("sar") ||
@@ -781,20 +797,6 @@
                     X86Operand::CreateImm(One, NameLoc, NameLoc));
   }
 
-  // FIXME: Hack to handle "out[bwl]? %al, (%dx)" -> "outb %al, %dx".
-  if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") &&
-      Operands.size() == 3) {
-    X86Operand &Op = *(X86Operand*)Operands.back();
-    if (Op.isMem() && Op.Mem.SegReg == 0 &&
-        isa<MCConstantExpr>(Op.Mem.Disp) &&
-        cast<MCConstantExpr>(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);
-      delete &Op;
-    }
-  }
-
   // FIXME: Hack to handle "f{mul*,add*,sub*,div*} $op, st(0)" the same as
   // "f{mul*,add*,sub*,div*} $op"
   if ((Name.startswith("fmul") || Name.startswith("fadd") ||
@@ -839,13 +841,6 @@
                                              NameLoc, NameLoc));
   }
 
-  // FIXME: Hack to handle recognize "aa[dm]" -> "aa[dm] $0xA".
-  if ((Name.startswith("aad") || Name.startswith("aam")) &&
-      Operands.size() == 1) {
-    const MCExpr *A = MCConstantExpr::Create(0xA, getParser().getContext());
-    Operands.push_back(X86Operand::CreateImm(A, NameLoc, NameLoc));
-  }
-
   return false;
 }
 

Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=118350&r1=118349&r2=118350&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Sat Nov  6 14:25:43 2010
@@ -1367,6 +1367,10 @@
 // Assembler Instruction Aliases
 //===----------------------------------------------------------------------===//
 
+// aad/aam default to base 10 if no operand is specified.
+def : InstAlias<"aad", (AAD8i8 10)>;
+def : InstAlias<"aam", (AAM8i8 10)>;
+
 // clr aliases.
 def : InstAlias<"clrb $reg", (XOR8rr  GR8 :$reg, GR8 :$reg)>;
 def : InstAlias<"clrw $reg", (XOR16rr GR16:$reg, GR16:$reg)>;

Modified: llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp?rev=118350&r1=118349&r2=118350&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp Sat Nov  6 14:25:43 2010
@@ -270,7 +270,11 @@
       
       /// TiedOperand - This represents a result operand that is a duplicate of
       /// a previous result operand.
-      TiedOperand
+      TiedOperand,
+      
+      /// ImmOperand - This represents an immediate value that is dumped into
+      /// the operand.
+      ImmOperand
     } Kind;
     
     union {
@@ -281,6 +285,9 @@
       /// TiedOperandNum - This is the (earlier) result operand that should be
       /// copied from.
       unsigned TiedOperandNum;
+      
+      /// ImmVal - This is the immediate value added to the instruction.
+      int64_t ImmVal;
     };
     
     /// OpInfo - This is the information about the instruction operand that is
@@ -304,6 +311,15 @@
       X.OpInfo = Op;
       return X;
     }
+    
+    static ResOperand getImmOp(int64_t Val,
+                               const CGIOperandList::OperandInfo *Op) {
+      ResOperand X;
+      X.Kind = ImmOperand;
+      X.ImmVal = Val;
+      X.OpInfo = Op;
+      return X;
+    }
   };
 
   /// TheDef - This is the definition of the instruction or InstAlias that this
@@ -538,16 +554,6 @@
     AsmOperand &Op = AsmOperands[i];
     errs() << "  op[" << i << "] = " << Op.Class->ClassName << " - ";
     errs() << '\"' << Op.Token << "\"\n";
-#if 0
-    if (!Op.OperandInfo) {
-      errs() << "(singleton register)\n";
-      continue;
-    }
-
-    const CGIOperandList::OperandInfo &OI = *Op.OperandInfo;
-    errs() << OI.Name << " " << OI.Rec->getName()
-           << " (" << OI.MIOperandNo << ", " << OI.MINumOperands << ")\n";
-#endif
   }
 }
 
@@ -1174,7 +1180,8 @@
    
   // Set up the operand class.
   for (unsigned i = 0, e = CGA.ResultOperands.size(); i != e; ++i)
-    if (CGA.ResultOperands[i].Name == OperandName) {
+    if (CGA.ResultOperands[i].isRecord() &&
+        CGA.ResultOperands[i].getName() == 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.
       unsigned ResultIdx =CGA.getResultInstOperandIndexForResultOperandIndex(i);
@@ -1236,15 +1243,22 @@
     
     // Find out what operand from the asmparser that this MCInst operand comes
     // from.
-    int SrcOperand = FindAsmOperandNamed(CGA.ResultOperands[AliasOpNo++].Name);
-    if (SrcOperand != -1) {
-      ResOperands.push_back(ResOperand::getRenderedOp(SrcOperand, &OpInfo));
-      continue;
+    if (CGA.ResultOperands[AliasOpNo].isRecord()) {
+      StringRef Name = CGA.ResultOperands[AliasOpNo++].getName();
+      int SrcOperand = FindAsmOperandNamed(Name);
+      if (SrcOperand != -1) {
+        ResOperands.push_back(ResOperand::getRenderedOp(SrcOperand, &OpInfo));
+        continue;
+      }
+      
+      throw TGError(TheDef->getLoc(), "Instruction '" +
+                    TheDef->getName() + "' has operand '" + OpInfo.Name +
+                    "' that doesn't appear in asm string!");
     }
     
-    throw TGError(TheDef->getLoc(), "Instruction '" +
-                  TheDef->getName() + "' has operand '" + OpInfo.Name +
-                  "' that doesn't appear in asm string!");
+    int64_t ImmVal = CGA.ResultOperands[AliasOpNo++].getImm();
+    ResOperands.push_back(ResOperand::getImmOp(ImmVal, &OpInfo));
+    continue;
   }
 }
 
@@ -1291,7 +1305,6 @@
 
       // Generate code to populate each result operand.
       switch (OpInfo.Kind) {
-      default: assert(0 && "Unknown result operand kind");
       case MatchableInfo::ResOperand::RenderAsmOperand: {
         // This comes from something we parsed.
         MatchableInfo::AsmOperand &Op = II.AsmOperands[OpInfo.AsmOperandNum];
@@ -1322,6 +1335,12 @@
         Signature += "__Tie" + utostr(TiedOp);
         break;
       }
+      case MatchableInfo::ResOperand::ImmOperand: {
+        int64_t Val = OpInfo.ImmVal;
+        CaseOS << "    Inst.addOperand(MCOperand::CreateImm(" << Val << "));\n";
+        Signature += "__imm" + itostr(Val);
+        break;
+      }
       }
     }
     

Modified: llvm/trunk/utils/TableGen/CodeGenInstruction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenInstruction.cpp?rev=118350&r1=118349&r2=118350&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenInstruction.cpp (original)
+++ llvm/trunk/utils/TableGen/CodeGenInstruction.cpp Sat Nov  6 14:25:43 2010
@@ -449,6 +449,21 @@
       ++AliasOpNo;
       continue;
     }
+    
+    if (IntInit *II = dynamic_cast<IntInit*>(Arg)) {
+      // Integer arguments can't have names.
+      if (!Result->getArgName(AliasOpNo).empty())
+        throw TGError(R->getLoc(), "result argument #" + utostr(AliasOpNo) +
+                      " must not have a name!");
+      if (ResultInst->Operands[i].MINumOperands != 1 ||
+          !ResultInst->Operands[i].Rec->isSubClassOf("Operand"))
+        throw TGError(R->getLoc(), "invalid argument class " + 
+                      ResultInst->Operands[i].Rec->getName() +
+                      " for integer result operand!");
+      ResultOperands.push_back(ResultOperand(II->getValue()));
+      ++AliasOpNo;
+      continue;
+    }
 
     throw TGError(R->getLoc(), "result of inst alias has unknown operand type");
   }

Modified: llvm/trunk/utils/TableGen/CodeGenInstruction.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenInstruction.h?rev=118350&r1=118349&r2=118350&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenInstruction.h (original)
+++ llvm/trunk/utils/TableGen/CodeGenInstruction.h Sat Nov  6 14:25:43 2010
@@ -267,10 +267,26 @@
     
     
     struct ResultOperand {
+    private:
       StringRef Name;
       Record *R;
       
-      ResultOperand(StringRef N, Record *r) : Name(N), R(r) {}
+      int64_t Imm;
+    public:      
+      enum {
+        K_Record,
+        K_Imm
+      } Kind;
+      
+      ResultOperand(StringRef N, Record *r) : Name(N), R(r), Kind(K_Record) {}
+      ResultOperand(int64_t I) : Imm(I), Kind(K_Imm) {}
+
+      bool isRecord() const { return Kind == K_Record; }
+      bool isImm() const { return Kind == K_Imm; }
+      
+      StringRef getName() const { assert(isRecord()); return Name; }
+      Record *getRecord() const { assert(isRecord()); return R; }
+      int64_t getImm() const { assert(isImm()); return Imm; }
     };
     
     /// ResultOperands - The decoded operands for the result instruction.





More information about the llvm-commits mailing list