aboutsummaryrefslogtreecommitdiffstats
path: root/qv4isel_llvm.cpp
diff options
context:
space:
mode:
authorRoberto Raggi <roberto.raggi@nokia.com>2012-06-05 14:30:04 +0200
committerRoberto Raggi <roberto.raggi@nokia.com>2012-06-05 14:30:04 +0200
commita48ece9a5cfb54a073aae7de8717eea1f1b357fb (patch)
treed5764bdd16b2636603b0f34a15d0724830417945 /qv4isel_llvm.cpp
parent437c25fe33f766844ad297fb2e4135c22af042a6 (diff)
Generate LLVM code for the binary expressions
Diffstat (limited to 'qv4isel_llvm.cpp')
-rw-r--r--qv4isel_llvm.cpp57
1 files changed, 54 insertions, 3 deletions
diff --git a/qv4isel_llvm.cpp b/qv4isel_llvm.cpp
index 8b72cf8239..1557d7ae67 100644
--- a/qv4isel_llvm.cpp
+++ b/qv4isel_llvm.cpp
@@ -273,9 +273,60 @@ void LLVMInstructionSelection::visitUnop(IR::Unop *e)
void LLVMInstructionSelection::visitBinop(IR::Binop *e)
{
- llvm::Value *left = getLLVMValue(e->left);
- llvm::Value *right = getLLVMValue(e->right);
- Q_UNIMPLEMENTED();
+ llvm::Value *result = CreateAlloca(_valueTy);
+ genBinop(result, e);
+ _llvmValue = CreateLoad(result);
+}
+
+void LLVMInstructionSelection::genBinop(llvm::Value *result, IR::Binop *e)
+{
+ IR::Temp *t1 = e->left->asTemp();
+ IR::Temp *t2 = e->right->asTemp();
+ assert(t1 != 0);
+ assert(t2 != 0);
+
+ llvm::Value *left = getLLVMTemp(t1);
+ llvm::Value *right = getLLVMTemp(t2);
+ llvm::Value *op = 0;
+ switch (e->op) {
+ case IR::OpInvalid:
+ case IR::OpIfTrue:
+ case IR::OpNot:
+ case IR::OpUMinus:
+ case IR::OpUPlus:
+ case IR::OpCompl:
+ Q_UNREACHABLE();
+ break;
+
+ case IR::OpBitAnd: op = _llvmModule->getFunction("__qmljs_llvm_bit_and"); break;
+ case IR::OpBitOr: op = _llvmModule->getFunction("__qmljs_llvm_bit_or"); break;
+ case IR::OpBitXor: op = _llvmModule->getFunction("__qmljs_llvm_bit_xor"); break;
+ case IR::OpAdd: op = _llvmModule->getFunction("__qmljs_llvm_add"); break;
+ case IR::OpSub: op = _llvmModule->getFunction("__qmljs_llvm_sub"); break;
+ case IR::OpMul: op = _llvmModule->getFunction("__qmljs_llvm_mul"); break;
+ case IR::OpDiv: op = _llvmModule->getFunction("__qmljs_llvm_div"); break;
+ case IR::OpMod: op = _llvmModule->getFunction("__qmljs_llvm_mod"); break;
+ case IR::OpLShift: op = _llvmModule->getFunction("__qmljs_llvm_shl"); break;
+ case IR::OpRShift: op = _llvmModule->getFunction("__qmljs_llvm_shr"); break;
+ case IR::OpURShift: op = _llvmModule->getFunction("__qmljs_llvm_ushr"); break;
+ case IR::OpGt: op = _llvmModule->getFunction("__qmljs_llvm_gt"); break;
+ case IR::OpLt: op = _llvmModule->getFunction("__qmljs_llvm_lt"); break;
+ case IR::OpGe: op = _llvmModule->getFunction("__qmljs_llvm_ge"); break;
+ case IR::OpLe: op = _llvmModule->getFunction("__qmljs_llvm_le"); break;
+ case IR::OpEqual: op = _llvmModule->getFunction("__qmljs_llvm_eq"); break;
+ case IR::OpNotEqual: op = _llvmModule->getFunction("__qmljs_llvm_ne"); break;
+ case IR::OpStrictEqual: op = _llvmModule->getFunction("__qmljs_llvm_se"); break;
+ case IR::OpStrictNotEqual: op = _llvmModule->getFunction("__qmljs_llvm_sne"); break;
+ case IR::OpInstanceof: op = _llvmModule->getFunction("__qmljs_llvm_instanceof"); break;
+ case IR::OpIn: op = _llvmModule->getFunction("__qmljs_llvm_in"); break;
+
+ case IR::OpAnd:
+ case IR::OpOr:
+ Q_UNREACHABLE();
+ break;
+ }
+
+ CreateCall4(op, _llvmFunction->arg_begin(), result, left, right);
}
void LLVMInstructionSelection::visitCall(IR::Call *e)