aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler/qv4isel_masm_p.h
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@me.com>2013-08-28 15:05:24 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-11 17:12:27 +0200
commit7a73e68b613ea724c90507d81801fc8f1de7fce1 (patch)
tree455ac7b52b9e0a414a99a3b7919888214b4d0566 /src/qml/compiler/qv4isel_masm_p.h
parent6aabeb55e663933149b716b47bcfbb37525babb4 (diff)
V4 JIT: generate code for binary expressions.
Change-Id: If32ee3528fa0b6a2d04263d6c6abe1d34053d658 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml/compiler/qv4isel_masm_p.h')
-rw-r--r--src/qml/compiler/qv4isel_masm_p.h69
1 files changed, 57 insertions, 12 deletions
diff --git a/src/qml/compiler/qv4isel_masm_p.h b/src/qml/compiler/qv4isel_masm_p.h
index 00e4fcb2fe..0813e59ed1 100644
--- a/src/qml/compiler/qv4isel_masm_p.h
+++ b/src/qml/compiler/qv4isel_masm_p.h
@@ -711,6 +711,13 @@ public:
template <typename Result>
void copyValue(Result result, V4IR::Expr* source);
+ void storeValue(QV4::Value value, RegisterID destination)
+ {
+ Q_UNUSED(value);
+ Q_UNUSED(destination);
+ Q_UNREACHABLE();
+ }
+
void storeValue(QV4::Value value, Address destination)
{
#ifdef VALUE_FITS_IN_REGISTER
@@ -1027,15 +1034,18 @@ public:
store32(TrustedImm32(QV4::Value::fromBoolean(0).tag), addr);
}
+ void storeBool(RegisterID src, RegisterID dest)
+ {
+ move(src, dest);
+ }
+
void storeBool(RegisterID reg, V4IR::Temp *target)
{
if (target->kind == V4IR::Temp::PhysicalRegister) {
move(reg, (RegisterID) target->index);
- } else if (target->kind == V4IR::Temp::StackSlot) {
- Pointer addr = stackSlotPointer(target);
- storeBool(reg, addr);
} else {
- Q_UNIMPLEMENTED();
+ Pointer addr = loadTempAddress(ScratchRegister, target);
+ storeBool(reg, addr);
}
}
@@ -1049,6 +1059,11 @@ public:
}
}
+ void storeInt32(RegisterID src, RegisterID dest)
+ {
+ move(src, dest);
+ }
+
void storeInt32(RegisterID reg, Pointer addr)
{
store32(reg, addr);
@@ -1066,19 +1081,24 @@ public:
}
}
+ void storeUInt32(RegisterID src, RegisterID dest)
+ {
+ move(src, dest);
+ }
+
void storeUInt32(RegisterID reg, Pointer addr)
{
+ // The UInt32 representation in QV4::Value is really convoluted. See also toUInt32Register.
#if CPU(X86_64) | CPU(X86)
- Q_ASSERT(reg != ScratchRegister);
Jump intRange = branch32(GreaterThanOrEqual, reg, TrustedImm32(0));
- convertUInt32ToDouble(reg, FPGpr0, ScratchRegister);
+ convertUInt32ToDouble(reg, FPGpr0, ReturnValueRegister);
storeDouble(FPGpr0, addr);
Jump done = jump();
intRange.link(this);
storeInt32(reg, addr);
done.link(this);
#else
- Q_ASSERT(!"Not supported on this platform!");
+ Q_ASSERT(!"Not tested on this platform!");
#endif
}
@@ -1094,8 +1114,7 @@ public:
if (t->kind == V4IR::Temp::PhysicalRegister)
return (FPRegisterID) t->index;
- Q_ASSERT(t->kind == V4IR::Temp::StackSlot);
- loadDouble(loadTempAddress(ScratchRegister, t), target);
+ loadDouble(t, target);
return target;
}
@@ -1137,7 +1156,26 @@ public:
RegisterID toUInt32Register(Pointer addr, RegisterID scratchReg)
{
+ // The UInt32 representation in QV4::Value is really convoluted. See also storeUInt32.
+ Pointer tagAddr = addr;
+ tagAddr.offset += 4;
+ load32(tagAddr, scratchReg);
+ Jump inIntRange = branch32(Equal, scratchReg, TrustedImm32(QV4::Value::_Integer_Type));
+
+ // it's not in signed int range, so load it as a double, and truncate it down
+ loadDouble(addr, FPGpr0);
+ static const QV4::Value magic = QV4::Value::fromDouble(double(INT_MAX) + 1);
+ ImplicitAddress magicAddr = constantTable().loadValueAddress(magic, scratchReg);
+ subDouble(Address(magicAddr.base, magicAddr.offset), FPGpr0);
+ Jump canNeverHappen = branchTruncateDoubleToUint32(FPGpr0, scratchReg);
+ canNeverHappen.link(this);
+ or32(TrustedImm32(1 << 31), scratchReg);
+ Jump done = jump();
+
+ inIntRange.link(this);
load32(addr, scratchReg);
+
+ done.link(this);
return scratchReg;
}
@@ -1272,6 +1310,15 @@ protected:
virtual void visitRet(V4IR::Ret *);
virtual void visitTry(V4IR::Try *);
+ Assembler::Jump genTryDoubleConversion(V4IR::Expr *src, Assembler::FPRegisterID dest);
+ Assembler::Jump genInlineBinop(V4IR::AluOp oper, V4IR::Expr *leftSource,
+ V4IR::Expr *rightSource, V4IR::Temp *target);
+ void doubleBinop(V4IR::AluOp oper, V4IR::Expr *leftSource, V4IR::Expr *rightSource,
+ V4IR::Temp *target);
+ Assembler::Jump branchDouble(V4IR::AluOp op, V4IR::Expr *left, V4IR::Expr *right);
+ bool visitCJumpDouble(V4IR::AluOp op, V4IR::Expr *left, V4IR::Expr *right,
+ V4IR::BasicBlock *iftrue, V4IR::BasicBlock *iffalse);
+
private:
void convertTypeSlowPath(V4IR::Temp *source, V4IR::Temp *target);
void convertTypeToDouble(V4IR::Temp *source, V4IR::Temp *target);
@@ -1283,12 +1330,10 @@ private:
if (target->kind == V4IR::Temp::PhysicalRegister) {
_as->convertInt32ToDouble(_as->toInt32Register(source, Assembler::ScratchRegister),
(Assembler::FPRegisterID) target->index);
- } else if (target->kind == V4IR::Temp::StackSlot) {
+ } else {
_as->convertInt32ToDouble(_as->toInt32Register(source, Assembler::ScratchRegister),
Assembler::FPGpr0);
_as->storeDouble(Assembler::FPGpr0, _as->stackSlotPointer(target));
- } else {
- Q_UNIMPLEMENTED();
}
}