[llvm-commits] CVS: llvm/lib/Target/X86/X86TargetAsmInfo.cpp X86TargetAsmInfo.h

Chris Lattner sabre at nondot.org
Tue Nov 28 17:14:20 PST 2006



Changes in directory llvm/lib/Target/X86:

X86TargetAsmInfo.cpp updated: 1.9 -> 1.10
X86TargetAsmInfo.h updated: 1.2 -> 1.3
---
Log message:

Trivially lower 'bswap $0' into llvm.bswap.  This fixes hexxagon with the
JIT on darwin/x86, which has htonl implemented as inline asm.


---
Diffs of the changes:  (+75 -1)

 X86TargetAsmInfo.cpp |   72 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 X86TargetAsmInfo.h   |    4 ++
 2 files changed, 75 insertions(+), 1 deletion(-)


Index: llvm/lib/Target/X86/X86TargetAsmInfo.cpp
diff -u llvm/lib/Target/X86/X86TargetAsmInfo.cpp:1.9 llvm/lib/Target/X86/X86TargetAsmInfo.cpp:1.10
--- llvm/lib/Target/X86/X86TargetAsmInfo.cpp:1.9	Tue Nov 28 16:28:08 2006
+++ llvm/lib/Target/X86/X86TargetAsmInfo.cpp	Tue Nov 28 19:14:06 2006
@@ -14,7 +14,10 @@
 #include "X86TargetAsmInfo.h"
 #include "X86TargetMachine.h"
 #include "X86Subtarget.h"
-
+#include "llvm/InlineAsm.h"
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/ADT/StringExtras.h"
 using namespace llvm;
 
 static const char* x86_asm_table[] = {"{si}", "S",
@@ -154,3 +157,70 @@
   }
 }
 
+bool X86TargetAsmInfo::LowerToBSwap(CallInst *CI) const {
+  // FIXME: this should verify that we are targetting a 486 or better.  If not,
+  // we will turn this bswap into something that will be lowered to logical ops
+  // instead of emitting the bswap asm.  For now, we don't support 486 or lower
+  // so don't worry about this.
+  
+  // Verify this is a simple bswap.
+  if (CI->getNumOperands() != 2 ||
+      CI->getType() != CI->getOperand(1)->getType() ||
+      !CI->getType()->isInteger())
+    return false;
+  
+  const Type *Ty = CI->getType()->getUnsignedVersion();
+  const char *IntName;
+  switch (Ty->getTypeID()) {
+  default: return false;
+  case Type::UShortTyID: IntName = "llvm.bswap.i16"; break;
+  case Type::UIntTyID:   IntName = "llvm.bswap.i32"; break;
+  case Type::ULongTyID:  IntName = "llvm.bswap.i64"; break;
+  }
+
+  // Okay, we can do this xform, do so now.
+  Module *M = CI->getParent()->getParent()->getParent();
+  Function *Int = M->getOrInsertFunction(IntName, Ty, Ty, (Type*)0);
+  
+  Value *Op = CI->getOperand(1);
+  if (CI->getOperand(1)->getType() != Ty)
+    Op = new BitCastInst(Op, Ty, Op->getName(), CI);
+  
+  Op = new CallInst(Int, Op, CI->getName(), CI);
+  
+  if (Op->getType() != CI->getType())
+    Op = new BitCastInst(Op, CI->getType(), Op->getName(), CI);
+  
+  CI->replaceAllUsesWith(Op);
+  CI->eraseFromParent();
+  return true;
+}
+
+
+bool X86TargetAsmInfo::ExpandInlineAsm(CallInst *CI) const {
+  InlineAsm *IA = cast<InlineAsm>(CI->getCalledValue());
+  //std::vector<InlineAsm::ConstraintInfo> Constraints = IA->ParseConstraints();
+  
+  std::string AsmStr = IA->getAsmString();
+  
+  // TODO: should remove alternatives from the asmstring: "foo {a|b}" -> "foo a"
+  std::vector<std::string> AsmPieces;
+  SplitString(AsmStr, AsmPieces, "\n");  // ; as separator?
+  
+  switch (AsmPieces.size()) {
+  default: return false;    
+  case 1:
+    AsmStr = AsmPieces[0];
+    AsmPieces.clear();
+    SplitString(AsmStr, AsmPieces, " \t");  // Split with whitespace.
+    
+    if (AsmPieces.size() == 2 && 
+        AsmPieces[0] == "bswap" && AsmPieces[1] == "$0") {
+      // No need to check constraints, nothing other than the equivalent of
+      // "=r,0" would be valid here.
+      return LowerToBSwap(CI);
+    }
+    break;
+  }
+  return false;
+}


Index: llvm/lib/Target/X86/X86TargetAsmInfo.h
diff -u llvm/lib/Target/X86/X86TargetAsmInfo.h:1.2 llvm/lib/Target/X86/X86TargetAsmInfo.h:1.3
--- llvm/lib/Target/X86/X86TargetAsmInfo.h:1.2	Wed Oct  4 21:43:52 2006
+++ llvm/lib/Target/X86/X86TargetAsmInfo.h	Tue Nov 28 19:14:06 2006
@@ -23,6 +23,10 @@
 
   struct X86TargetAsmInfo : public TargetAsmInfo {
     X86TargetAsmInfo(const X86TargetMachine &TM);
+    
+    virtual bool ExpandInlineAsm(CallInst *CI) const;
+  private:
+    bool LowerToBSwap(CallInst *CI) const;
   };
 } // namespace llvm
 






More information about the llvm-commits mailing list