V4 JIT: tweak generated int32 to double conversion code
authorErik Verbruggen <erik.verbruggen@digia.com>
Thu, 7 Aug 2014 12:33:55 +0000 (14:33 +0200)
committerErik Verbruggen <erik.verbruggen@digia.com>
Wed, 13 Aug 2014 08:00:32 +0000 (10:00 +0200)
If the target is a FP register, and the source is a memory address, do
not load the int32 ourselves, but leave it to the assembler to decide
what to do. On x86(_64) this is generates a single instruction, while on
ARM the assembler will insert a load on its own.

For the case where the target is not a FP register, use the return value
register as base register for the target address. The advantage is that
the address calculation is now independent of the preceding conversion,
so it can fit in a different pipeline without dependencies.

Change-Id: Ib7cefa636274ba8596e4d11ae0170a091a0def3e
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
src/qml/jit/qv4isel_masm_p.h

index f54b18d..af518a0 100644 (file)
@@ -179,6 +179,15 @@ private:
     {
         if (IR::Temp *targetTemp = target->asTemp()) {
             if (targetTemp->kind == IR::Temp::PhysicalRegister) {
+                if (IR::Temp *sourceTemp = source->asTemp()) {
+                    if (sourceTemp->kind == IR::Temp::PhysicalRegister) {
+                        _as->convertInt32ToDouble((Assembler::RegisterID) sourceTemp->index,
+                                                  (Assembler::FPRegisterID) targetTemp->index);
+                    } else {
+                        _as->convertInt32ToDouble(_as->loadAddress(Assembler::ReturnValueRegister, sourceTemp),
+                                                  (Assembler::FPRegisterID) targetTemp->index);
+                    }
+                }
                 _as->convertInt32ToDouble(_as->toInt32Register(source, Assembler::ScratchRegister),
                                           (Assembler::FPRegisterID) targetTemp->index);
                 return;
@@ -187,7 +196,7 @@ private:
 
         _as->convertInt32ToDouble(_as->toInt32Register(source, Assembler::ScratchRegister),
                                   Assembler::FPGpr0);
-        _as->storeDouble(Assembler::FPGpr0, _as->loadAddress(Assembler::ScratchRegister, target));
+        _as->storeDouble(Assembler::FPGpr0, _as->loadAddress(Assembler::ReturnValueRegister, target));
     }
 
     void convertUIntToDouble(IR::Expr *source, IR::Expr *target)