aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler/qv4isel_masm.cpp
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@me.com>2013-10-18 17:02:57 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-12-04 16:42:46 +0100
commit7e3578728edec27301b71f5ab5d7b43874ae35a2 (patch)
tree25b66bfd38acd67a2ad032699edf9d00864c50c3 /src/qml/compiler/qv4isel_masm.cpp
parent102f57376f5d1ace2e9a3e0ffa829a1bbc0d002c (diff)
V4 IR: reverse propagate int32 truncation.
Change-Id: I5cb0c7798d0e530f3137710bf0e723bd7b64dc89 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml/compiler/qv4isel_masm.cpp')
-rw-r--r--src/qml/compiler/qv4isel_masm.cpp109
1 files changed, 84 insertions, 25 deletions
diff --git a/src/qml/compiler/qv4isel_masm.cpp b/src/qml/compiler/qv4isel_masm.cpp
index bdcfc11f56..35097bae49 100644
--- a/src/qml/compiler/qv4isel_masm.cpp
+++ b/src/qml/compiler/qv4isel_masm.cpp
@@ -2494,11 +2494,10 @@ bool InstructionSelection::int32Binop(V4IR::AluOp oper, V4IR::Expr *leftSource,
else
targetReg = Assembler::ReturnValueRegister;
- _as->move(_as->toInt32Register(leftSource, targetReg), targetReg);
- Assembler::RegisterID rReg = _as->toInt32Register(rightSource, Assembler::ScratchRegister);
- _as->and32(rReg, targetReg);
- if (Assembler::ReturnValueRegister == targetReg)
- _as->storeInt32(targetReg, target);
+ _as->and32(_as->toInt32Register(leftSource, targetReg),
+ _as->toInt32Register(rightSource, Assembler::ScratchRegister),
+ targetReg);
+ _as->storeInt32(targetReg, target);
} return true;
case V4IR::OpBitOr: {
Q_ASSERT(rightSource->type == V4IR::SInt32Type);
@@ -2515,11 +2514,10 @@ bool InstructionSelection::int32Binop(V4IR::AluOp oper, V4IR::Expr *leftSource,
else
targetReg = Assembler::ReturnValueRegister;
- _as->move(_as->toInt32Register(leftSource, targetReg), targetReg);
- Assembler::RegisterID rReg = _as->toInt32Register(rightSource, Assembler::ScratchRegister);
- _as->or32(rReg, targetReg);
- if (Assembler::ReturnValueRegister == targetReg)
- _as->storeInt32(targetReg, target);
+ _as->or32(_as->toInt32Register(leftSource, targetReg),
+ _as->toInt32Register(rightSource, Assembler::ScratchRegister),
+ targetReg);
+ _as->storeInt32(targetReg, target);
} return true;
case V4IR::OpBitXor: {
Q_ASSERT(rightSource->type == V4IR::SInt32Type);
@@ -2536,32 +2534,41 @@ bool InstructionSelection::int32Binop(V4IR::AluOp oper, V4IR::Expr *leftSource,
else
targetReg = Assembler::ReturnValueRegister;
- _as->move(_as->toInt32Register(leftSource, targetReg), targetReg);
- Assembler::RegisterID rReg = _as->toInt32Register(rightSource, Assembler::ScratchRegister);
- _as->xor32(rReg, targetReg);
- if (Assembler::ReturnValueRegister == targetReg)
- _as->storeInt32(targetReg, target);
+ _as->xor32(_as->toInt32Register(leftSource, targetReg),
+ _as->toInt32Register(rightSource, Assembler::ScratchRegister),
+ targetReg);
+ _as->storeInt32(targetReg, target);
} return true;
- case V4IR::OpLShift:
+ case V4IR::OpLShift: {
Q_ASSERT(rightSource->type == V4IR::SInt32Type);
- _as->move(_as->toInt32Register(leftSource, Assembler::ReturnValueRegister),
- Assembler::ReturnValueRegister);
+ Assembler::RegisterID targetReg;
+ if (target->kind == V4IR::Temp::PhysicalRegister)
+ targetReg = (Assembler::RegisterID) target->index;
+ else
+ targetReg = Assembler::ReturnValueRegister;
+
_as->move(_as->toInt32Register(rightSource, Assembler::ScratchRegister),
Assembler::ScratchRegister);
_as->and32(Assembler::TrustedImm32(0x1f), Assembler::ScratchRegister); // TODO: for constants, do this in the IR
- _as->lshift32(Assembler::ScratchRegister, Assembler::ReturnValueRegister);
+ _as->lshift32(_as->toInt32Register(leftSource, targetReg), Assembler::ScratchRegister,
+ Assembler::ReturnValueRegister);
_as->storeInt32(Assembler::ReturnValueRegister, target);
- return true;
- case V4IR::OpRShift:
+ } return true;
+ case V4IR::OpRShift: {
Q_ASSERT(rightSource->type == V4IR::SInt32Type);
- _as->move(_as->toInt32Register(leftSource, Assembler::ReturnValueRegister),
- Assembler::ReturnValueRegister);
+ Assembler::RegisterID targetReg;
+ if (target->kind == V4IR::Temp::PhysicalRegister)
+ targetReg = (Assembler::RegisterID) target->index;
+ else
+ targetReg = Assembler::ReturnValueRegister;
+
_as->move(_as->toInt32Register(rightSource, Assembler::ScratchRegister),
Assembler::ScratchRegister);
_as->and32(Assembler::TrustedImm32(0x1f), Assembler::ScratchRegister); // TODO: for constants, do this in the IR
- _as->rshift32(Assembler::ScratchRegister, Assembler::ReturnValueRegister);
+ _as->rshift32(_as->toInt32Register(leftSource, targetReg), Assembler::ScratchRegister,
+ Assembler::ReturnValueRegister);
_as->storeInt32(Assembler::ReturnValueRegister, target);
- return true;
+ } return true;
case V4IR::OpURShift:
Q_ASSERT(rightSource->type == V4IR::SInt32Type);
_as->move(_as->toInt32Register(leftSource, Assembler::ReturnValueRegister),
@@ -2572,6 +2579,58 @@ bool InstructionSelection::int32Binop(V4IR::AluOp oper, V4IR::Expr *leftSource,
_as->urshift32(Assembler::ScratchRegister, Assembler::ReturnValueRegister);
_as->storeUInt32(Assembler::ReturnValueRegister, target);
return true;
+ case V4IR::OpAdd: {
+ Q_ASSERT(rightSource->type == V4IR::SInt32Type);
+
+ Assembler::RegisterID targetReg;
+ if (target->kind == V4IR::Temp::PhysicalRegister)
+ targetReg = (Assembler::RegisterID) target->index;
+ else
+ targetReg = Assembler::ReturnValueRegister;
+
+ _as->add32(_as->toInt32Register(leftSource, targetReg),
+ _as->toInt32Register(rightSource, Assembler::ScratchRegister),
+ targetReg);
+ _as->storeInt32(targetReg, target);
+ } return true;
+ case V4IR::OpSub: {
+ Q_ASSERT(rightSource->type == V4IR::SInt32Type);
+
+ if (rightSource->asTemp() && rightSource->asTemp()->kind == V4IR::Temp::PhysicalRegister
+ && target->kind == V4IR::Temp::PhysicalRegister
+ && target->index == rightSource->asTemp()->index) {
+ Assembler::RegisterID targetReg = (Assembler::RegisterID) target->index;
+ _as->move(targetReg, Assembler::ScratchRegister);
+ _as->move(_as->toInt32Register(leftSource, targetReg), targetReg);
+ _as->sub32(Assembler::ScratchRegister, targetReg);
+ _as->storeInt32(targetReg, target);
+ return true;
+ }
+
+ Assembler::RegisterID targetReg;
+ if (target->kind == V4IR::Temp::PhysicalRegister)
+ targetReg = (Assembler::RegisterID) target->index;
+ else
+ targetReg = Assembler::ReturnValueRegister;
+
+ _as->move(_as->toInt32Register(leftSource, targetReg), targetReg);
+ _as->sub32(_as->toInt32Register(rightSource, Assembler::ScratchRegister), targetReg);
+ _as->storeInt32(targetReg, target);
+ } return true;
+ case V4IR::OpMul: {
+ Q_ASSERT(rightSource->type == V4IR::SInt32Type);
+
+ Assembler::RegisterID targetReg;
+ if (target->kind == V4IR::Temp::PhysicalRegister)
+ targetReg = (Assembler::RegisterID) target->index;
+ else
+ targetReg = Assembler::ReturnValueRegister;
+
+ _as->mul32(_as->toInt32Register(leftSource, targetReg),
+ _as->toInt32Register(rightSource, Assembler::ScratchRegister),
+ targetReg);
+ _as->storeInt32(targetReg, target);
+ } return true;
default:
return false;
}