[arm] make asm_quad stick its constants into the instruction stream, with a branch over, to ensure that the data is close enough for a PC-relative FLDD
authorVladimir Vukicevic <vladimir@pobox.com>
Fri, 05 Sep 2008 17:15:23 -0700
changeset 19060 678377cbc8786755ce5e62b414ce8766659f5660
parent 19059 0d0354ea085b7d3054a36a877951a51a3cc55886
child 19061 b8ea641cd20db35fcd6bf8deabaef00c5d49e290
push id1930
push usermrbkap@mozilla.com
push dateWed, 10 Sep 2008 06:40:47 +0000
treeherderautoland@ee61af1469cd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone1.9.1b1pre
[arm] make asm_quad stick its constants into the instruction stream, with a branch over, to ensure that the data is close enough for a PC-relative FLDD
js/src/nanojit/NativeARM.cpp
--- a/js/src/nanojit/NativeARM.cpp
+++ b/js/src/nanojit/NativeARM.cpp
@@ -500,54 +500,50 @@ Assembler::asm_store64(LInsp value, int 
         LD32_nochk(Scratch, dr);
     }
 
     // if it's a constant, make sure our baseReg/baseOffset location
     // has the right value
     if (value->isconstq()) {
         const int32_t* p = (const int32_t*) (value-2);
 
-        underrunProtect(12 + LD32_size);
+        underrunProtect(12);
 
         asm_quad_nochk(rv, p);
     }
 #else
     int da = findMemFor(value);
     Register rb = findRegFor(base, GpRegs);
     asm_mmq(rb, dr, FP, da);
 #endif
     //asm_output(">>> store64");
 }
 
 // stick a quad into register rr, where p points to the two
 // 32-bit parts of the quad, optinally also storing at FP+d
 void
 Assembler::asm_quad_nochk(Register rr, const int32_t* p)
 {
-    *(++_nSlot) = p[0];
-    *(++_nSlot) = p[1];
-
-    intptr_t constAddr = (intptr_t) (_nSlot-1);
-    intptr_t realOffset = PC_OFFSET_FROM(constAddr, _nIns-1);
-    intptr_t offset = realOffset;
-    Register baseReg = PC;
-
-    //int32_t *q = (int32_t*) constAddr;
-    //fprintf (stderr, "asm_quad_nochk: rr = %d cAddr: 0x%x quad: %08x:%08x q: %f @0x%08x\n", rr, constAddr, p[0], p[1], *(double*)q, _nIns);
+    // We're not going to use a slot, because it might be too far
+    // away.  Instead, we're going to stick a branch in the stream to
+    // jump over the constants, and then load from a short PC relative
+    // offset.
 
-    // for FLDD, we only get a left-shifted 8-bit offset
-    if (!isS8(realOffset >> 2)) {
-        offset = 0;
-        baseReg = Scratch;
-    }
+    // stream should look like:
+    //    branch A
+    //    p[0]
+    //    p[1]
+    // A: FLDD PC-16
 
-    FLDD(rr, baseReg, offset);
+    FLDD(rr, PC, -16);
 
-    if (!isS8(realOffset >> 2))
-        LD32_nochk(Scratch, constAddr);
+    *(--_nIns) = (NIns) p[1];
+    *(--_nIns) = (NIns) p[0];
+
+    JMP_nochk(_nIns+2);
 }
 
 void
 Assembler::asm_quad(LInsp ins)
 {
     //asm_output(">>> asm_quad");
 
     Reservation *res = getresv(ins);
@@ -557,17 +553,17 @@ Assembler::asm_quad(LInsp ins)
     NanoAssert(d || rr != UnknownReg);
 
     const int32_t* p = (const int32_t*) (ins-2);
 
 #ifdef NJ_ARM_VFP
     freeRsrcOf(ins, false);
 
     // XXX We probably want nochk versions of FLDD/FSTD
-    underrunProtect(16 + LD32_size);
+    underrunProtect(d ? 20 : 16);
 
     // grab a register to do the load into if we don't have one already;
     // XXX -- maybe do a mmq in this case?  We're going to use our
     // D7 register that's never allocated (since it's the one we use
     // for int-to-double conversions), so we don't have to worry about
     // spilling something in a fp reg.
     if (rr == UnknownReg)
         rr = D7;