Bug 893543 - Ionmonkey: (ARM) fix some instruction addressing mode corner cases. r=mjrosenb
authorDouglas Crosher <dtc-moz@scieneer.com>
Sat, 27 Jul 2013 00:45:46 +1000
changeset 153330 79899f8b526bdc4916543a067efb8431c875c0d2
parent 153329 424e1cb4850cb38b6ab289bf50de32f47c92cf9e
child 153331 50dfd0c5bc36ca267661324fa96d47e7f0ba976f
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
bugs893543
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 893543 - Ionmonkey: (ARM) fix some instruction addressing mode corner cases. r=mjrosenb
js/src/ion/arm/MacroAssembler-arm.cpp
--- a/js/src/ion/arm/MacroAssembler-arm.cpp
+++ b/js/src/ion/arm/MacroAssembler-arm.cpp
@@ -1098,79 +1098,89 @@ MacroAssemblerARM::ma_dataTransferN(Load
         // For a regular offset, base == ScratchRegister does what we want.  Modify the
         // scratch register, leaving the actual base unscathed.
         Register base = ScratchRegister;
         // For the preindex case, we want to just re-use rn as the base register, so when
         // the base register is updated *before* the load, rn is updated.
         if (mode == PreIndex)
             base = rn;
         JS_ASSERT(mode != PostIndex);
-        // at this point, both off - bottom and off + neg_bottom will be reasonable-ish
-        // quantities.
+        // At this point, both off - bottom and off + neg_bottom will be reasonable-ish quantities.
+        //
+        // Note a neg_bottom of 0x1000 can not be encoded as an immediate negative offset in the
+        // instruction and this occurs when bottom is zero, so this case is guarded against below.
+        // 
         if (off < 0) {
             Operand2 sub_off = Imm8(-(off-bottom)); // sub_off = bottom - off
             if (!sub_off.invalid) {
                 as_sub(ScratchRegister, rn, sub_off, NoSetCond, cc); // - sub_off = off - bottom
                 return as_dtr(ls, size, Offset, rt, DTRAddr(ScratchRegister, DtrOffImm(bottom)), cc);
             }
             sub_off = Imm8(-(off+neg_bottom));// sub_off = -neg_bottom - off
-            if (!sub_off.invalid) {
+            if (!sub_off.invalid && bottom != 0) {
+                JS_ASSERT(neg_bottom < 0x1000);  // Guarded against by: bottom != 0
                 as_sub(ScratchRegister, rn, sub_off, NoSetCond, cc); // - sub_off = neg_bottom + off
                 return as_dtr(ls, size, Offset, rt, DTRAddr(ScratchRegister, DtrOffImm(-neg_bottom)), cc);
             }
         } else {
             Operand2 sub_off = Imm8(off-bottom); // sub_off = off - bottom
             if (!sub_off.invalid) {
                 as_add(ScratchRegister, rn, sub_off, NoSetCond, cc); //  sub_off = off - bottom
                 return as_dtr(ls, size, Offset, rt, DTRAddr(ScratchRegister, DtrOffImm(bottom)), cc);
             }
             sub_off = Imm8(off+neg_bottom);// sub_off = neg_bottom + off
-            if (!sub_off.invalid) {
+            if (!sub_off.invalid && bottom != 0) {
+                JS_ASSERT(neg_bottom < 0x1000);  // Guarded against by: bottom != 0
                 as_add(ScratchRegister, rn, sub_off, NoSetCond,  cc); // sub_off = neg_bottom + off
                 return as_dtr(ls, size, Offset, rt, DTRAddr(ScratchRegister, DtrOffImm(-neg_bottom)), cc);
             }
         }
         ma_mov(offset, ScratchRegister);
         return as_dtr(ls, size, mode, rt, DTRAddr(rn, DtrRegImmShift(ScratchRegister, LSL, 0)));
     } else {
         // should attempt to use the extended load/store instructions
         if (off < 256 && off > -256)
             return as_extdtr(ls, size, IsSigned, mode, rt, EDtrAddr(rn, EDtrOffImm(off)), cc);
 
-        // We cannot encode this offset in a a single extldr.  Try to encode it as
+        // We cannot encode this offset in a single extldr.  Try to encode it as
         // an add scratch, base, imm; extldr dest, [scratch, +offset].
         int bottom = off & 0xff;
         int neg_bottom = 0x100 - bottom;
-        // at this point, both off - bottom and off + neg_bottom will be reasonable-ish
-        // quantities.
+        // At this point, both off - bottom and off + neg_bottom will be reasonable-ish quantities.
+        //
+        // Note a neg_bottom of 0x100 can not be encoded as an immediate negative offset in the
+        // instruction and this occurs when bottom is zero, so this case is guarded against below.
+        // 
         if (off < 0) {
             Operand2 sub_off = Imm8(-(off-bottom)); // sub_off = bottom - off
             if (!sub_off.invalid) {
                 as_sub(ScratchRegister, rn, sub_off, NoSetCond, cc); // - sub_off = off - bottom
                 return as_extdtr(ls, size, IsSigned, Offset, rt,
                                  EDtrAddr(ScratchRegister, EDtrOffImm(bottom)),
                                  cc);
             }
             sub_off = Imm8(-(off+neg_bottom));// sub_off = -neg_bottom - off
-            if (!sub_off.invalid) {
+            if (!sub_off.invalid && bottom != 0) {
+                JS_ASSERT(neg_bottom < 0x100);  // Guarded against by: bottom != 0
                 as_sub(ScratchRegister, rn, sub_off, NoSetCond, cc); // - sub_off = neg_bottom + off
                 return as_extdtr(ls, size, IsSigned, Offset, rt,
                                  EDtrAddr(ScratchRegister, EDtrOffImm(-neg_bottom)),
                                  cc);
             }
         } else {
             Operand2 sub_off = Imm8(off-bottom); // sub_off = off - bottom
             if (!sub_off.invalid) {
                 as_add(ScratchRegister, rn, sub_off, NoSetCond, cc); //  sub_off = off - bottom
                 return as_extdtr(ls, size, IsSigned, Offset, rt,
                                  EDtrAddr(ScratchRegister, EDtrOffImm(bottom)),
                                  cc);
             }
             sub_off = Imm8(off+neg_bottom);// sub_off = neg_bottom + off
-            if (!sub_off.invalid) {
+            if (!sub_off.invalid && bottom != 0) {
+                JS_ASSERT(neg_bottom < 0x100);  // Guarded against by: bottom != 0
                 as_add(ScratchRegister, rn, sub_off, NoSetCond,  cc); // sub_off = neg_bottom + off
                 return as_extdtr(ls, size, IsSigned, Offset, rt,
                                  EDtrAddr(ScratchRegister, EDtrOffImm(-neg_bottom)),
                                  cc);
             }
         }
         ma_mov(offset, ScratchRegister);
         return as_extdtr(ls, size, IsSigned, mode, rt, EDtrAddr(rn, EDtrOffReg(ScratchRegister)), cc);
@@ -1426,37 +1436,42 @@ MacroAssemblerARM::ma_vdtr(LoadStore ls,
     Register base = Register::FromCode(addr.base());
     if (off > -1024 && off < 1024)
         return as_vdtr(ls, rt, addr.toVFPAddr(), cc);
 
     // We cannot encode this offset in a a single ldr.  Try to encode it as
     // an add scratch, base, imm; ldr dest, [scratch, +offset].
     int bottom = off & (0xff << 2);
     int neg_bottom = (0x100 << 2) - bottom;
-    // at this point, both off - bottom and off + neg_bottom will be reasonable-ish
-    // quantities.
+    // At this point, both off - bottom and off + neg_bottom will be reasonable-ish quantities.
+    //
+    // Note a neg_bottom of 0x400 can not be encoded as an immediate negative offset in the
+    // instruction and this occurs when bottom is zero, so this case is guarded against below.
+    // 
     if (off < 0) {
         Operand2 sub_off = Imm8(-(off-bottom)); // sub_off = bottom - off
         if (!sub_off.invalid) {
             as_sub(ScratchRegister, base, sub_off, NoSetCond, cc); // - sub_off = off - bottom
             return as_vdtr(ls, rt, VFPAddr(ScratchRegister, VFPOffImm(bottom)), cc);
         }
         sub_off = Imm8(-(off+neg_bottom));// sub_off = -neg_bottom - off
-        if (!sub_off.invalid) {
+        if (!sub_off.invalid && bottom != 0) {
+            JS_ASSERT(neg_bottom < 0x400);  // Guarded against by: bottom != 0
             as_sub(ScratchRegister, base, sub_off, NoSetCond, cc); // - sub_off = neg_bottom + off
             return as_vdtr(ls, rt, VFPAddr(ScratchRegister, VFPOffImm(-neg_bottom)), cc);
         }
     } else {
         Operand2 sub_off = Imm8(off-bottom); // sub_off = off - bottom
         if (!sub_off.invalid) {
             as_add(ScratchRegister, base, sub_off, NoSetCond, cc); //  sub_off = off - bottom
             return as_vdtr(ls, rt, VFPAddr(ScratchRegister, VFPOffImm(bottom)), cc);
         }
         sub_off = Imm8(off+neg_bottom);// sub_off = neg_bottom + off
-        if (!sub_off.invalid) {
+        if (!sub_off.invalid && bottom != 0) {
+            JS_ASSERT(neg_bottom < 0x400);  // Guarded against by: bottom != 0
             as_add(ScratchRegister, base, sub_off, NoSetCond,  cc); // sub_off = neg_bottom + off
             return as_vdtr(ls, rt, VFPAddr(ScratchRegister, VFPOffImm(-neg_bottom)), cc);
         }
     }
     ma_add(base, Imm32(off), ScratchRegister, NoSetCond, cc);
     return as_vdtr(ls, rt, VFPAddr(ScratchRegister, VFPOffImm(0)), cc);
 }