aboutsummaryrefslogtreecommitdiffstats
path: root/qv4isel_llvm.cpp
diff options
context:
space:
mode:
authorRoberto Raggi <roberto.raggi@nokia.com>2012-06-05 15:03:49 +0200
committerRoberto Raggi <roberto.raggi@nokia.com>2012-06-05 15:03:49 +0200
commit7f3a694adce3c971cca5081ed9b8c737adfb0948 (patch)
tree4790bea6aa3d9347bce150ba8dd47d38bc0e50cf /qv4isel_llvm.cpp
parenta48ece9a5cfb54a073aae7de8717eea1f1b357fb (diff)
LLVM code for unary expressions
Diffstat (limited to 'qv4isel_llvm.cpp')
-rw-r--r--qv4isel_llvm.cpp27
1 files changed, 25 insertions, 2 deletions
diff --git a/qv4isel_llvm.cpp b/qv4isel_llvm.cpp
index 1557d7ae67..1d4f412f0e 100644
--- a/qv4isel_llvm.cpp
+++ b/qv4isel_llvm.cpp
@@ -267,8 +267,9 @@ void LLVMInstructionSelection::visitClosure(IR::Closure *)
void LLVMInstructionSelection::visitUnop(IR::Unop *e)
{
- llvm::Value *expr = getLLVMValue(e->expr);
- Q_UNIMPLEMENTED();
+ llvm::Value *result = CreateAlloca(_valueTy);
+ genUnop(result, e);
+ _llvmValue = CreateLoad(result);
}
void LLVMInstructionSelection::visitBinop(IR::Binop *e)
@@ -278,6 +279,28 @@ void LLVMInstructionSelection::visitBinop(IR::Binop *e)
_llvmValue = CreateLoad(result);
}
+void LLVMInstructionSelection::genUnop(llvm::Value *result, IR::Unop *e)
+{
+ IR::Temp *t = e->expr->asTemp();
+ assert(t != 0);
+
+ llvm::Value *expr = getLLVMTemp(t);
+ llvm::Value *op = 0;
+
+ switch (e->op) {
+ default:
+ Q_UNREACHABLE();
+ break;
+
+ case IR::OpNot: _llvmModule->getFunction("__qmljs_llvm_not"); break;
+ case IR::OpUMinus: _llvmModule->getFunction("__qmljs_llvm_uminus"); break;
+ case IR::OpUPlus: _llvmModule->getFunction("__qmljs_llvm_uplus"); break;
+ case IR::OpCompl: _llvmModule->getFunction("__qmljs_llvm_compl"); break;
+ }
+
+ CreateCall3(op, _llvmFunction->arg_begin(), result, expr);
+}
+
void LLVMInstructionSelection::genBinop(llvm::Value *result, IR::Binop *e)
{
IR::Temp *t1 = e->left->asTemp();