Bug 1516701 - Implement MacroAssembler::storeRegsInMask(). r=nbp
authorSean Stangl <sean.stangl@gmail.com>
Fri, 28 Dec 2018 14:26:00 +0200
changeset 509417 fcf60924da90d2242cefc64d5ae83a85db395749
parent 509416 7b71897ff6be49225613180bac536673a03bb7c0
child 509418 d3d32e312a50622e2a0cdb7ac1afc1170ac60154
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs1516701
milestone66.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 1516701 - Implement MacroAssembler::storeRegsInMask(). r=nbp Makes progress in basic/array-copyWithin.js. Fixup for storeRegsInMask.
js/src/jit/arm64/MacroAssembler-arm64.cpp
--- a/js/src/jit/arm64/MacroAssembler-arm64.cpp
+++ b/js/src/jit/arm64/MacroAssembler-arm64.cpp
@@ -448,17 +448,48 @@ void MacroAssembler::PushRegsInMask(Live
       adjustFrame(8);
     }
     vixl::MacroAssembler::Push(src[0], src[1], src[2], src[3]);
   }
 }
 
 void MacroAssembler::storeRegsInMask(LiveRegisterSet set, Address dest,
                                      Register scratch) {
-  MOZ_CRASH("NYI: storeRegsInMask");
+  FloatRegisterSet fpuSet(set.fpus().reduceSetForPush());
+  unsigned numFpu = fpuSet.size();
+  int32_t diffF = fpuSet.getPushSizeInBytes();
+  int32_t diffG = set.gprs().size() * sizeof(intptr_t);
+
+  MOZ_ASSERT(dest.offset >= diffG + diffF);
+
+  for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); ++iter) {
+    diffG -= sizeof(intptr_t);
+    dest.offset -= sizeof(intptr_t);
+    storePtr(*iter, dest);
+  }
+  MOZ_ASSERT(diffG == 0);
+
+  for (FloatRegisterBackwardIterator iter(fpuSet); iter.more(); ++iter) {
+    FloatRegister reg = *iter;
+    diffF -= reg.size();
+    numFpu -= 1;
+    dest.offset -= reg.size();
+    if (reg.isDouble()) {
+      storeDouble(reg, dest);
+    } else if (reg.isSingle()) {
+      storeFloat32(reg, dest);
+    } else {
+      MOZ_CRASH("Unknown register type.");
+    }
+
+  }
+  MOZ_ASSERT(numFpu == 0);
+  // Padding to keep the stack aligned, taken from the x64 and mips64 implementations.
+  diffF -= diffF % sizeof(uintptr_t);
+  MOZ_ASSERT(diffF == 0);
 }
 
 void MacroAssembler::PopRegsInMaskIgnore(LiveRegisterSet set,
                                          LiveRegisterSet ignore) {
   // The offset of the data from the stack pointer.
   uint32_t offset = 0;
 
   for (FloatRegisterIterator iter(set.fpus().reduceSetForPush());