RaiseAsm.cpp

Go to the documentation of this file.
00001 //===-- RaiseAsm.cpp ------------------------------------------------------===//
00002 //
00003 //                     The KLEE Symbolic Virtual Machine
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #include "Passes.h"
00011 
00012 #include "llvm/InlineAsm.h"
00013 
00014 using namespace llvm;
00015 using namespace klee;
00016 
00017 char RaiseAsmPass::ID = 0;
00018 
00019 Function *RaiseAsmPass::getIntrinsic(llvm::Module &M,
00020                                      unsigned IID,
00021                                      const Type **Tys,
00022                                      unsigned NumTys) {  
00023   return Intrinsic::getDeclaration(&M, (llvm::Intrinsic::ID) IID, Tys, NumTys);
00024 }
00025 
00026 // FIXME: This should just be implemented as a patch to
00027 // X86TargetAsmInfo.cpp, then everyone will benefit.
00028 bool RaiseAsmPass::runOnInstruction(Module &M, Instruction *I) {
00029   if (CallInst *ci = dyn_cast<CallInst>(I)) {
00030     if (InlineAsm *ia = dyn_cast<InlineAsm>(ci->getCalledValue())) {
00031       const std::string &as = ia->getAsmString();
00032       const std::string &cs = ia->getConstraintString();
00033       const llvm::Type *T = ci->getType();
00034 
00035       // bswaps
00036       if (ci->getNumOperands() == 2 && 
00037           T == ci->getOperand(1)->getType() &&
00038           ((T == llvm::Type::Int16Ty && 
00039             as == "rorw $$8, ${0:w}" &&
00040             cs == "=r,0,~{dirflag},~{fpsr},~{flags},~{cc}") ||
00041            (T == llvm::Type::Int32Ty &&
00042             as == "rorw $$8, ${0:w};rorl $$16, $0;rorw $$8, ${0:w}" &&
00043             cs == "=r,0,~{dirflag},~{fpsr},~{flags},~{cc}"))) {
00044         llvm::Value *Arg0 = ci->getOperand(1);
00045         Function *F = getIntrinsic(M, Intrinsic::bswap, Arg0->getType());
00046         ci->setOperand(0, F);
00047         return true;
00048       }
00049     }
00050   }
00051 
00052   return false;
00053 }
00054 
00055 bool RaiseAsmPass::runOnModule(Module &M) {
00056   bool changed = false;
00057   
00058   for (Module::iterator fi = M.begin(), fe = M.end(); fi != fe; ++fi) {
00059     for (Function::iterator bi = fi->begin(), be = fi->end(); bi != be; ++bi) {
00060       for (BasicBlock::iterator ii = bi->begin(), ie = bi->end(); ii != ie;) {
00061         Instruction *i = ii;
00062         ++ii;  
00063         changed |= runOnInstruction(M, i);
00064       }
00065     }
00066   }
00067 
00068   return changed;
00069 }

Generated on Fri Jun 5 03:31:32 2009 for klee by  doxygen 1.5.8