diff options
author | Alon Zakai <alonzakai@gmail.com> | 2013-11-24 17:55:09 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2013-11-24 17:55:09 -0800 |
commit | 746f183f352a43b8c7728c08120ea7d2fef5292b (patch) | |
tree | 27cd50e4d2666e76e485a5fc6353020138c93f97 | |
parent | a3c874e3d132f6261a836e3a882f2dadbf50af39 (diff) |
CallHandler system
-rw-r--r-- | lib/Target/CppBackend/CPPBackend.cpp | 26 | ||||
-rw-r--r-- | lib/Target/CppBackend/CallHandlers.h | 50 |
2 files changed, 56 insertions, 20 deletions
diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp index bb121b2388..b20319fd4e 100644 --- a/lib/Target/CppBackend/CPPBackend.cpp +++ b/lib/Target/CppBackend/CPPBackend.cpp @@ -138,6 +138,8 @@ namespace { HeapData GlobalData64; std::map<std::string, Address> GlobalAddresses; + #include "CallHandlers.h" + public: static char ID; explicit CppWriter(formatted_raw_ostream &o) : @@ -1702,26 +1704,8 @@ std::string CppWriter::generateInstruction(const Instruction *I) { break; } case Instruction::Call: { - const CallInst* call = cast<CallInst>(I); - const int numArgs = call->getNumArgOperands(); - Type *RT = call->getCalledFunction()->getReturnType(); - text = opNames[numArgs] + "("; - for (int i = 0; i < numArgs; i++) { - Value *Arg = call->getArgOperand(i); - Type *t = dyn_cast<PointerType>(Arg->getType()); - const GlobalVariable *GV; - if (t && (GV = dyn_cast<GlobalVariable>(Arg))) { - text += utostr(getGlobalAddress(GV->getName().str())); - } else { - text += getValueAsCastStr(call->getArgOperand(i)); // FIXME: differentiate ffi calls - } - if (i < numArgs - 1) text += ", "; - } - text += ")"; - if (!RT->isVoidTy()) { - text = getAssign(iName, RT) + getCast(text, RT); - } - text += ";"; + const CallInst *CI = cast<CallInst>(I); + text = handleCall(CI); break; } case Instruction::Select: { @@ -2430,6 +2414,8 @@ void CppWriter::printType(const std::string &fname, bool CppWriter::runOnModule(Module &M) { TheModule = &M; + setupCallHandlers(); + // Emit a header Out << "//========================================\n\n"; diff --git a/lib/Target/CppBackend/CallHandlers.h b/lib/Target/CppBackend/CallHandlers.h new file mode 100644 index 0000000000..8395d97b4f --- /dev/null +++ b/lib/Target/CppBackend/CallHandlers.h @@ -0,0 +1,50 @@ +// Call handlers: flexible map of call targets to arbitrary handling code +// +// Each handler needs DEF_CALL_HANDLER and SETUP_CALL_HANDLER + +typedef std::string (CppWriter::*CallHandler)(const CallInst*); +typedef std::map<const char *, CallHandler> CallHandlerMap; +CallHandlerMap *CallHandlers; + +// Definitions + +#define DEF_CALL_HANDLER(Ident, Code) \ + std::string CH_##Ident(const CallInst *CI) { Code } + +DEF_CALL_HANDLER(__default__, { + const int numArgs = CI->getNumArgOperands(); + Type *RT = CI->getCalledFunction()->getReturnType(); + std::string text = getCppName(CI->getCalledValue()) + "("; + for (int i = 0; i < numArgs; i++) { + text += getValueAsCastStr(CI->getArgOperand(i)); // FIXME: differentiate ffi calls + if (i < numArgs - 1) text += ", "; + } + text += ")"; + if (!RT->isVoidTy()) { + text = getAssign(getCppName(CI), RT) + getCast(text, RT); + } + return text + ';'; +}) + +DEF_CALL_HANDLER(llvm_nacl_atomic_store_i32, { + return "throw 'atomic store!';"; +}) + + +// Setups + +void setupCallHandlers() { + CallHandlers = new CallHandlerMap; + #define SETUP_CALL_HANDLER(Ident) \ + (*CallHandlers)[#Ident] = &CppWriter::CH_##Ident; + + SETUP_CALL_HANDLER(__default__); + SETUP_CALL_HANDLER(llvm_nacl_atomic_store_i32); +} + +std::string handleCall(const CallInst *CI) { + CallHandlerMap::iterator CH = CallHandlers->find(getCppName(CI->getCalledValue()).c_str()); + if (CH == CallHandlers->end()) CH = CallHandlers->find("__default__"); + return (this->*(CH->second))(CI); +} + |