Bug 893552 - OdinMonkey: (ARM) dynamic code is not preserving float registers d8 to d15 as required by the ABI r=mjrosenb
☠☠ backed out by b8af597df1d0 ☠ ☠
authorJon Coppeard <jcoppeard@mozilla.com>
Tue, 30 Jul 2013 09:57:58 +0100
changeset 152778 80e1116e4599d8e1b8677e44f6066765500746fc
parent 152777 b4e0d0d2d916ab58b4bd34d2a0600593b051a3b1
child 152779 91837985ae91d394ea96289bb43878161067bd69
push id2859
push userakeybl@mozilla.com
push dateMon, 16 Sep 2013 19:14:59 +0000
treeherdermozilla-beta@87d3c51cd2bf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmjrosenb
bugs893552
milestone25.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 893552 - OdinMonkey: (ARM) dynamic code is not preserving float registers d8 to d15 as required by the ABI r=mjrosenb
js/src/ion/arm/Architecture-arm.h
js/src/ion/arm/Trampoline-arm.cpp
--- a/js/src/ion/arm/Architecture-arm.h
+++ b/js/src/ion/arm/Architecture-arm.h
@@ -191,18 +191,27 @@ class FloatRegisters
 
     static const Code Invalid = invalid_freg;
 
     static const uint32_t Total = 16;
     static const uint32_t Allocatable = 15;
 
     static const uint32_t AllMask = (1 << Total) - 1;
 
-    static const uint32_t VolatileMask = AllMask;
-    static const uint32_t NonVolatileMask = 0;
+    static const uint32_t NonVolatileMask =
+        (1 << d8) |
+        (1 << d9) |
+        (1 << d10) |
+        (1 << d11) |
+        (1 << d12) |
+        (1 << d13) |
+        (1 << d14) |
+        (1 << d15);
+
+    static const uint32_t VolatileMask = AllMask & ~NonVolatileMask;
 
     static const uint32_t WrapperMask = VolatileMask;
 
     // d1 is the ARM scratch float register.
     static const uint32_t NonAllocatableMask = (1 << d1) | (1 << invalid_freg);
 
     // Registers that can be allocated without being saved, generally.
     static const uint32_t TempMask = VolatileMask & ~NonAllocatableMask;
--- a/js/src/ion/arm/Trampoline-arm.cpp
+++ b/js/src/ion/arm/Trampoline-arm.cpp
@@ -14,20 +14,24 @@
 #include "ion/IonFrames.h"
 #include "ion/IonLinker.h"
 #include "ion/IonSpewer.h"
 #include "ion/VMFunctions.h"
 
 using namespace js;
 using namespace js::ion;
 
+static const FloatRegisterSet NonVolatileFloatRegs =
+    FloatRegisterSet(FloatRegisters::NonVolatileMask);  /* d8 - d15 */
+
 static void
 GenerateReturn(MacroAssembler &masm, int returnCode)
 {
     // Restore non-volatile registers
+    masm.transferMultipleByRuns(NonVolatileFloatRegs, IsLoad, StackPointer, IA);
     masm.ma_mov(Imm32(returnCode), r0);
     masm.startDataTransferM(IsLoad, sp, IA, WriteBack);
     masm.transferReg(r4);
     masm.transferReg(r5);
     masm.transferReg(r6);
     masm.transferReg(r7);
     masm.transferReg(r8);
     masm.transferReg(r9);
@@ -36,16 +40,25 @@ GenerateReturn(MacroAssembler &masm, int
     // r12 isn't saved, so it shouldn't be restored.
     masm.transferReg(pc);
     masm.finishDataTransfer();
     masm.dumpPool();
 }
 
 struct EnterJITStack
 {
+    double d8;
+    double d9;
+    double d10;
+    double d11;
+    double d12;
+    double d13;
+    double d14;
+    double d15;
+
     void *r0; // alignment.
 
     // non-volatile registers.
     void *r4;
     void *r5;
     void *r6;
     void *r7;
     void *r8;
@@ -62,18 +75,18 @@ struct EnterJITStack
     // frame == r3
     CalleeToken token;
     JSObject *scopeChain;
     size_t numStackValues;
     Value *vp;
 };
 
 /*
- * This method generates a trampoline on x86 for a c++ function with
- * the following signature:
+ * This method generates a trampoline for a c++ function with the following
+ * signature:
  *   void enter(void *code, int argc, Value *argv, StackFrame *fp, CalleeToken
  *              calleeToken, JSObject *scopeChain, Value *vp)
  *   ...using standard EABI calling convention
  */
 IonCode *
 IonRuntime::generateEnterJIT(JSContext *cx, EnterJitType type)
 {
 
@@ -103,16 +116,17 @@ IonRuntime::generateEnterJIT(JSContext *
     masm.transferReg(r8); // [sp,20]
     masm.transferReg(r9); // [sp,24]
     masm.transferReg(r10); // [sp,28]
     masm.transferReg(r11); // [sp,32]
     // The abi does not expect r12 (ip) to be preserved
     masm.transferReg(lr);  // [sp,36]
     // The 5th argument is located at [sp, 40]
     masm.finishDataTransfer();
+    masm.transferMultipleByRuns(NonVolatileFloatRegs, IsStore, sp, DB);
 
     // Save stack pointer into r8
     masm.movePtr(sp, r8);
 
     // Load calleeToken into r9.
     masm.loadPtr(slot_token, r9);
 
     // Save stack pointer.