aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2013-11-24 17:55:09 -0800
committerAlon Zakai <alonzakai@gmail.com>2013-11-24 17:55:09 -0800
commit746f183f352a43b8c7728c08120ea7d2fef5292b (patch)
tree27cd50e4d2666e76e485a5fc6353020138c93f97
parenta3c874e3d132f6261a836e3a882f2dadbf50af39 (diff)
CallHandler system
-rw-r--r--lib/Target/CppBackend/CPPBackend.cpp26
-rw-r--r--lib/Target/CppBackend/CallHandlers.h50
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);
+}
+