bool Binop::int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Temp *target)
{
Q_ASSERT(leftSource->type == IR::SInt32Type);
- Assembler::RegisterID targetReg;
- if (target->kind == IR::Temp::PhysicalRegister)
- targetReg = (Assembler::RegisterID) target->index;
- else
- targetReg = Assembler::ReturnValueRegister;
+ Assembler::RegisterID targetReg = Assembler::ReturnValueRegister;
+ if (target->kind == IR::Temp::PhysicalRegister) {
+ // We try to load leftSource into the target's register, but we can't do that if
+ // the target register is the same as rightSource.
+ IR::Temp *rhs = rightSource->asTemp();
+ if (!rhs || rhs->kind != IR::Temp::PhysicalRegister || rhs->index != target->index)
+ targetReg = (Assembler::RegisterID) target->index;
+ }
switch (op) {
case IR::OpBitAnd: {
case IR::OpAdd: {
Q_ASSERT(rightSource->type == IR::SInt32Type);
- Assembler::RegisterID targetReg;
- if (target->kind == IR::Temp::PhysicalRegister)
- targetReg = (Assembler::RegisterID) target->index;
- else
- targetReg = Assembler::ReturnValueRegister;
-
as->add32(as->toInt32Register(leftSource, targetReg),
as->toInt32Register(rightSource, Assembler::ScratchRegister),
targetReg);
return true;
}
- Assembler::RegisterID targetReg;
- if (target->kind == IR::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);
case IR::OpMul: {
Q_ASSERT(rightSource->type == IR::SInt32Type);
- Assembler::RegisterID targetReg;
- if (target->kind == IR::Temp::PhysicalRegister)
- targetReg = (Assembler::RegisterID) target->index;
- else
- targetReg = Assembler::ReturnValueRegister;
-
as->mul32(as->toInt32Register(leftSource, targetReg),
as->toInt32Register(rightSource, Assembler::ScratchRegister),
targetReg);