Bug 1166037 - Part 2 - Modify common Baseline code for ARM64. r=djvj
authorSean Stangl <sstangl@mozilla.com>
Thu, 11 Jun 2015 14:45:41 -0700
changeset 279379 2372db222b854eb71699f97b3e6290f2b8257d55
parent 279378 a06337f75bb3be512899ff29c1da078fa9b05bd7
child 279380 ffbaa1a08d2357c22ebf9392963c02c6b23597a5
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-beta@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdjvj
bugs1166037
milestone41.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 1166037 - Part 2 - Modify common Baseline code for ARM64. r=djvj
js/src/jit/BaselineIC.cpp
js/src/jit/BaselineIC.h
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -256,18 +256,18 @@ ICWarmUpCounter_Fallback::Compiler::gene
 
     // Push a stub frame so that we can perform a non-tail call.
     enterStubFrame(masm, R1.scratchReg());
 
     Label noCompiledCode;
     // Call DoWarmUpCounterFallback to compile/check-for Ion-compiled function
     {
         // Push IonOsrTempData pointer storage
-        masm.subPtr(Imm32(sizeof(void*)), BaselineStackReg);
-        masm.push(BaselineStackReg);
+        masm.subFromStackPtr(Imm32(sizeof(void*)));
+        masm.push(masm.getStackPointer());
 
         // Push stub pointer.
         masm.push(ICStubReg);
 
         pushFramePtr(masm, R0.scratchReg());
 
         if (!callVM(DoWarmUpCounterFallbackInfo, masm))
             return false;
@@ -293,17 +293,17 @@ ICWarmUpCounter_Fallback::Compiler::gene
     //  +-> [...Calling-Frame...]
     //  |   [...Actual-Args/ThisV/ArgCount/Callee...]
     //  |   [Descriptor]
     //  |   [Return-Addr]
     //  +---[Saved-FramePtr]            <-- BaselineFrameReg points here.
     //      [...Baseline-Frame...]
 
     // Restore the stack pointer to point to the saved frame pointer.
-    masm.movePtr(BaselineFrameReg, BaselineStackReg);
+    masm.moveToStackPtr(BaselineFrameReg);
 
     // Discard saved frame pointer, so that the return address is on top of
     // the stack.
     masm.pop(scratchReg);
 
 #ifdef DEBUG
     // If profiler instrumentation is on, ensure that lastProfilingFrame is
     // the frame currently being OSR-ed
@@ -314,19 +314,19 @@ ICWarmUpCounter_Fallback::Compiler::gene
         masm.loadPtr(AbsoluteAddress((void*)&cx->runtime()->jitActivation), scratchReg);
         masm.loadPtr(Address(scratchReg, JitActivation::offsetOfLastProfilingFrame()), scratchReg);
 
         // It may be the case that we entered the baseline frame with
         // profiling turned off on, then in a call within a loop (i.e. a
         // callee frame), turn on profiling, then return to this frame,
         // and then OSR with profiling turned on.  In this case, allow for
         // lastProfilingFrame to be null.
-        masm.branchPtr(Assembler::Equal, scratchReg, Imm32(0), &checkOk);
-
-        masm.branchPtr(Assembler::Equal, scratchReg, BaselineStackReg, &checkOk);
+        masm.branchPtr(Assembler::Equal, scratchReg, ImmWord(0), &checkOk);
+
+        masm.branchStackPtr(Assembler::Equal, scratchReg, &checkOk);
         masm.assumeUnreachable("Baseline OSR lastProfilingFrame mismatch.");
         masm.bind(&checkOk);
     }
 #endif
 
     // Jump into Ion.
     masm.loadPtr(Address(osrDataReg, offsetof(IonOsrTempData, jitcode)), scratchReg);
     masm.loadPtr(Address(osrDataReg, offsetof(IonOsrTempData, baselineFrame)), OsrFrameReg);
@@ -3665,17 +3665,17 @@ ICGetElemNativeCompiler::emitCallScripte
         // Call the arguments rectifier.
         MOZ_ASSERT(ArgumentsRectifierReg != code);
 
         JitCode* argumentsRectifier =
             cx->runtime()->jitRuntime()->getArgumentsRectifier();
 
         masm.movePtr(ImmGCPtr(argumentsRectifier), code);
         masm.loadPtr(Address(code, JitCode::offsetOfCode()), code);
-        masm.mov(ImmWord(0), ArgumentsRectifierReg);
+        masm.movePtr(ImmWord(0), ArgumentsRectifierReg);
     }
 
     masm.bind(&noUnderflow);
     masm.callJit(code);
 
     leaveStubFrame(masm, true);
 
     return true;
@@ -3842,52 +3842,52 @@ ICGetElemNativeCompiler::generateStubCod
 
             if (popR1)
                 masm.pop(R1.scratchReg());
             masm.loadValue(valAddr, R0);
             masm.bind(&afterNoSuchMethod);
         } else {
             masm.loadValue(valAddr, R0);
             if (popR1)
-                masm.addPtr(ImmWord(sizeof(size_t)), BaselineStackReg);
+                masm.addToStackPtr(ImmWord(sizeof(size_t)));
         }
 #else
         masm.loadValue(valAddr, R0);
         if (popR1)
-            masm.addPtr(ImmWord(sizeof(size_t)), BaselineStackReg);
+            masm.addToStackPtr(ImmWord(sizeof(size_t)));
 #endif
 
     } else {
         MOZ_ASSERT(acctype_ == ICGetElemNativeStub::NativeGetter ||
                    acctype_ == ICGetElemNativeStub::ScriptedGetter);
         MOZ_ASSERT(kind == ICStub::GetElem_NativePrototypeCallNative ||
                    kind == ICStub::GetElem_NativePrototypeCallScripted);
 
         if (acctype_ == ICGetElemNativeStub::NativeGetter) {
             // If calling a native getter, there is no chance of failure now.
 
             // GetElem key (R1) is no longer needed.
             if (popR1)
-                masm.addPtr(ImmWord(sizeof(size_t)), BaselineStackReg);
+                masm.addToStackPtr(ImmWord(sizeof(size_t)));
 
             emitCallNative(masm, objReg);
 
         } else {
             MOZ_ASSERT(acctype_ == ICGetElemNativeStub::ScriptedGetter);
 
             // Load function in scratchReg and ensure that it has a jit script.
             masm.loadPtr(Address(ICStubReg, ICGetElemNativeGetterStub::offsetOfGetter()),
                          scratchReg);
             masm.branchIfFunctionHasNoScript(scratchReg, popR1 ? &failurePopR1 : &failure);
             masm.loadPtr(Address(scratchReg, JSFunction::offsetOfNativeOrScript()), scratchReg);
             masm.loadBaselineOrIonRaw(scratchReg, scratchReg, popR1 ? &failurePopR1 : &failure);
 
             // At this point, we are guaranteed to successfully complete.
             if (popR1)
-                masm.addPtr(Imm32(sizeof(size_t)), BaselineStackReg);
+                masm.addToStackPtr(Imm32(sizeof(size_t)));
 
             emitCallScripted(masm, objReg);
         }
     }
 
     // Enter type monitor IC to type-check result.
     EmitEnterTypeMonitorIC(masm);
 
@@ -4737,32 +4737,32 @@ ICSetElem_Fallback::Compiler::generateSt
 
     EmitRestoreTailCallReg(masm);
 
     // State: R0: object, R1: index, stack: rhs.
     // For the decompiler, the stack has to be: object, index, rhs,
     // so we push the index, then overwrite the rhs Value with R0
     // and push the rhs value.
     masm.pushValue(R1);
-    masm.loadValue(Address(BaselineStackReg, sizeof(Value)), R1);
-    masm.storeValue(R0, Address(BaselineStackReg, sizeof(Value)));
+    masm.loadValue(Address(masm.getStackPointer(), sizeof(Value)), R1);
+    masm.storeValue(R0, Address(masm.getStackPointer(), sizeof(Value)));
     masm.pushValue(R1);
 
     // Push arguments.
     masm.pushValue(R1); // RHS
 
     // Push index. On x86 and ARM two push instructions are emitted so use a
     // separate register to store the old stack pointer.
-    masm.mov(BaselineStackReg, R1.scratchReg());
+    masm.moveStackPtrTo(R1.scratchReg());
     masm.pushValue(Address(R1.scratchReg(), 2 * sizeof(Value)));
     masm.pushValue(R0); // Object.
 
     // Push pointer to stack values, so that the stub can overwrite the object
     // (pushed for the decompiler) with the rhs.
-    masm.computeEffectiveAddress(Address(BaselineStackReg, 3 * sizeof(Value)), R0.scratchReg());
+    masm.computeEffectiveAddress(Address(masm.getStackPointer(), 3 * sizeof(Value)), R0.scratchReg());
     masm.push(R0.scratchReg());
 
     masm.push(ICStubReg);
     pushFramePtr(masm, R0.scratchReg());
 
     return tailCallVM(DoSetElemFallbackInfo, masm);
 }
 
@@ -4820,32 +4820,32 @@ ICSetElem_DenseOrUnboxedArray::Compiler:
 
     if (needsUpdateStubs()) {
         // Stow both R0 and R1 (object and key)
         // But R0 and R1 still hold their values.
         EmitStowICValues(masm, 2);
 
         // Stack is now: { ..., rhs-value, object-value, key-value, maybe?-RET-ADDR }
         // Load rhs-value into R0
-        masm.loadValue(Address(BaselineStackReg, 2 * sizeof(Value) + ICStackValueOffset), R0);
+        masm.loadValue(Address(masm.getStackPointer(), 2 * sizeof(Value) + ICStackValueOffset), R0);
 
         // Call the type-update stub.
         if (!callTypeUpdateIC(masm, sizeof(Value)))
             return false;
 
         // Unstow R0 and R1 (object and key)
         EmitUnstowICValues(masm, 2);
 
         // Restore object.
         obj = masm.extractObject(R0, ExtractTemp0);
 
         // Trigger post barriers here on the value being written. Fields which
         // objects can be written to also need update stubs.
         masm.Push(R1);
-        masm.loadValue(Address(BaselineStackReg, sizeof(Value) + ICStackValueOffset), R1);
+        masm.loadValue(Address(masm.getStackPointer(), sizeof(Value) + ICStackValueOffset), R1);
 
         LiveGeneralRegisterSet saveRegs;
         saveRegs.add(R0);
         saveRegs.addUnchecked(obj);
         saveRegs.add(ICStubReg);
         emitPostWriteBarrierSlot(masm, obj, R1, scratchReg, saveRegs);
 
         masm.Pop(R1);
@@ -4883,17 +4883,17 @@ ICSetElem_DenseOrUnboxedArray::Compiler:
                           &failure);
 
         // Failure is not possible now.  Free up registers.
         regs.add(R0);
         regs.add(R1);
         regs.takeUnchecked(obj);
         regs.takeUnchecked(key);
 
-        Address valueAddr(BaselineStackReg, ICStackValueOffset);
+        Address valueAddr(masm.getStackPointer(), ICStackValueOffset);
 
         // We need to convert int32 values being stored into doubles. In this case
         // the heap typeset is guaranteed to contain both int32 and double, so it's
         // okay to store a double. Note that double arrays are only created by
         // IonMonkey, so if we have no floating-point support Ion is disabled and
         // there should be no double arrays.
         if (cx->runtime()->jitSupportsFloatingPoint)
             masm.convertInt32ValueToDouble(valueAddr, regs.getAny(), &noSpecialHandling);
@@ -4918,17 +4918,17 @@ ICSetElem_DenseOrUnboxedArray::Compiler:
         // Load obj->elements.
         masm.loadPtr(Address(obj, UnboxedArrayObject::offsetOfElements()), scratchReg);
 
         // Compute the address being written to.
         BaseIndex address(scratchReg, key, ScaleFromElemWidth(UnboxedTypeSize(unboxedType_)));
 
         EmitUnboxedPreBarrierForBaseline(masm, address, unboxedType_);
 
-        Address valueAddr(BaselineStackReg, ICStackValueOffset + sizeof(Value));
+        Address valueAddr(masm.getStackPointer(), ICStackValueOffset + sizeof(Value));
         masm.Push(R0);
         masm.loadValue(valueAddr, R0);
         masm.storeUnboxedProperty(address, unboxedType_,
                                   ConstantOrRegister(TypedOrValueRegister(R0)), &failurePopR0);
         masm.Pop(R0);
     }
 
     EmitReturnFromIC(masm);
@@ -5032,34 +5032,34 @@ ICSetElemDenseOrUnboxedArrayAddCompiler:
         masm.branchTestObjShape(Assembler::NotEqual, protoReg, scratchReg, &failureUnstow);
     }
     regs.add(protoReg);
     regs.add(scratchReg);
 
     if (needsUpdateStubs()) {
         // Stack is now: { ..., rhs-value, object-value, key-value, maybe?-RET-ADDR }
         // Load rhs-value in to R0
-        masm.loadValue(Address(BaselineStackReg, 2 * sizeof(Value) + ICStackValueOffset), R0);
+        masm.loadValue(Address(masm.getStackPointer(), 2 * sizeof(Value) + ICStackValueOffset), R0);
 
         // Call the type-update stub.
         if (!callTypeUpdateIC(masm, sizeof(Value)))
             return false;
     }
 
     // Unstow R0 and R1 (object and key)
     EmitUnstowICValues(masm, 2);
 
     // Restore object.
     obj = masm.extractObject(R0, ExtractTemp0);
 
     if (needsUpdateStubs()) {
         // Trigger post barriers here on the value being written. Fields which
         // objects can be written to also need update stubs.
         masm.Push(R1);
-        masm.loadValue(Address(BaselineStackReg, sizeof(Value) + ICStackValueOffset), R1);
+        masm.loadValue(Address(masm.getStackPointer(), sizeof(Value) + ICStackValueOffset), R1);
 
         LiveGeneralRegisterSet saveRegs;
         saveRegs.add(R0);
         saveRegs.addUnchecked(obj);
         saveRegs.add(ICStubReg);
         emitPostWriteBarrierSlot(masm, obj, R1, scratchReg, saveRegs);
 
         masm.Pop(R1);
@@ -5111,17 +5111,17 @@ ICSetElemDenseOrUnboxedArrayAddCompiler:
         // Convert int32 values to double if convertDoubleElements is set. In this
         // case the heap typeset is guaranteed to contain both int32 and double, so
         // it's okay to store a double.
         Label dontConvertDoubles;
         masm.branchTest32(Assembler::Zero, elementsFlags,
                           Imm32(ObjectElements::CONVERT_DOUBLE_ELEMENTS),
                           &dontConvertDoubles);
 
-        Address valueAddr(BaselineStackReg, ICStackValueOffset);
+        Address valueAddr(masm.getStackPointer(), ICStackValueOffset);
 
         // Note that double arrays are only created by IonMonkey, so if we have no
         // floating-point support Ion is disabled and there should be no double arrays.
         if (cx->runtime()->jitSupportsFloatingPoint)
             masm.convertInt32ValueToDouble(valueAddr, regs.getAny(), &dontConvertDoubles);
         else
             masm.assumeUnreachable("There shouldn't be double arrays when there is no FP support.");
         masm.bind(&dontConvertDoubles);
@@ -5144,17 +5144,17 @@ ICSetElemDenseOrUnboxedArrayAddCompiler:
         masm.checkUnboxedArrayCapacity(obj, Int32Key(key), scratchReg, &failure);
 
         // Load obj->elements.
         masm.loadPtr(Address(obj, UnboxedArrayObject::offsetOfElements()), scratchReg);
 
         // Write the value first, since this can fail. No need for pre-barrier
         // since we're not overwriting an old value.
         masm.Push(R0);
-        Address valueAddr(BaselineStackReg, ICStackValueOffset + sizeof(Value));
+        Address valueAddr(masm.getStackPointer(), ICStackValueOffset + sizeof(Value));
         masm.loadValue(valueAddr, R0);
         BaseIndex address(scratchReg, key, ScaleFromElemWidth(UnboxedTypeSize(unboxedType_)));
         masm.storeUnboxedProperty(address, unboxedType_,
                                   ConstantOrRegister(TypedOrValueRegister(R0)), &failurePopR0);
         masm.Pop(R0);
 
         // Increment initialized length.
         masm.add32(Imm32(1), initLengthAddr);
@@ -5301,17 +5301,17 @@ ICSetElem_TypedArray::Compiler::generate
     LoadTypedThingLength(masm, layout_, obj, scratchReg);
     masm.branch32(Assembler::BelowOrEqual, scratchReg, key,
                   expectOutOfBounds_ ? &oobWrite : &failure);
 
     // Load the elements vector.
     LoadTypedThingData(masm, layout_, obj, scratchReg);
 
     BaseIndex dest(scratchReg, key, ScaleFromElemWidth(Scalar::byteSize(type_)));
-    Address value(BaselineStackReg, ICStackValueOffset);
+    Address value(masm.getStackPointer(), ICStackValueOffset);
 
     // We need a second scratch register. It's okay to clobber the type tag of
     // R0 or R1, as long as it's restored before jumping to the next stub.
     regs = availableGeneralRegs(0);
     regs.takeUnchecked(obj);
     regs.takeUnchecked(key);
     regs.take(scratchReg);
     Register secondScratch = regs.takeAny();
@@ -7400,17 +7400,17 @@ ICGetPropNativeCompiler::generateStubCod
 
         // Pop pushed obj from baseline stack.
         EmitUnstowICValues(masm, 1, /* discard = */ true);
 
         masm.jump(&afterNoSuchMethod);
         masm.bind(&skipNoSuchMethod);
 
         // Pop pushed objReg.
-        masm.addPtr(Imm32(sizeof(void*)), BaselineStackReg);
+        masm.addToStackPtr(Imm32(sizeof(void*)));
         masm.bind(&afterNoSuchMethod);
     } else {
         masm.loadValue(result, R0);
     }
 #else
     masm.loadValue(result, R0);
 #endif
 
@@ -7568,17 +7568,17 @@ ICGetProp_CallScripted::Compiler::genera
         // Call the arguments rectifier.
         MOZ_ASSERT(ArgumentsRectifierReg != code);
 
         JitCode* argumentsRectifier =
             cx->runtime()->jitRuntime()->getArgumentsRectifier();
 
         masm.movePtr(ImmGCPtr(argumentsRectifier), code);
         masm.loadPtr(Address(code, JitCode::offsetOfCode()), code);
-        masm.mov(ImmWord(0), ArgumentsRectifierReg);
+        masm.movePtr(ImmWord(0), ArgumentsRectifierReg);
     }
 
     masm.bind(&noUnderflow);
     masm.callJit(code);
 
     leaveStubFrame(masm, true);
 
     // Enter type monitor IC to type-check result.
@@ -8732,17 +8732,17 @@ ICSetPropNativeAddCompiler::generateStub
                      scratch);
         masm.branchTestObjShape(Assembler::NotEqual, protoReg, scratch, &failureUnstow);
     }
 
     // Shape and type checks succeeded, ok to proceed.
 
     // Load RHS into R0 for TypeUpdate check.
     // Stack is currently: [..., ObjValue, RHSValue, MaybeReturnAddr? ]
-    masm.loadValue(Address(BaselineStackReg, ICStackValueOffset), R0);
+    masm.loadValue(Address(masm.getStackPointer(), ICStackValueOffset), R0);
 
     // Call the type-update stub.
     if (!callTypeUpdateIC(masm, sizeof(Value)))
         return false;
 
     // Unstow R0 and R1 (object and key)
     EmitUnstowICValues(masm, 2);
     regs = availableGeneralRegs(2);
@@ -8962,17 +8962,17 @@ ICSetProp_TypedObject::Compiler::generat
     // Get the object's data pointer.
     LoadTypedThingData(masm, layout_, object, scratch);
 
     // Compute the address being written to.
     masm.load32(Address(ICStubReg, ICSetProp_TypedObject::offsetOfFieldOffset()), secondScratch);
     masm.addPtr(secondScratch, scratch);
 
     Address dest(scratch, 0);
-    Address value(BaselineStackReg, 0);
+    Address value(masm.getStackPointer(), 0);
 
     if (fieldDescr_->is<ScalarTypeDescr>()) {
         Scalar::Type type = fieldDescr_->as<ScalarTypeDescr>().type();
         StoreToTypedArray(cx, masm, type, value, dest,
                           secondScratch, &failurePopRHS, &failurePopRHS);
         masm.popValue(R1);
         EmitReturnFromIC(masm);
     } else {
@@ -9096,17 +9096,17 @@ ICSetProp_CallScripted::Compiler::genera
         // Call the arguments rectifier.
         MOZ_ASSERT(ArgumentsRectifierReg != code);
 
         JitCode* argumentsRectifier =
             cx->runtime()->jitRuntime()->getArgumentsRectifier();
 
         masm.movePtr(ImmGCPtr(argumentsRectifier), code);
         masm.loadPtr(Address(code, JitCode::offsetOfCode()), code);
-        masm.mov(ImmWord(1), ArgumentsRectifierReg);
+        masm.movePtr(ImmWord(1), ArgumentsRectifierReg);
     }
 
     masm.bind(&noUnderflow);
     masm.callJit(code);
 
     leaveStubFrame(masm, true);
     // Do not care about return value from function. The original RHS should be returned
     // as the result of this operation.
@@ -9182,17 +9182,17 @@ ICSetProp_CallNative::Compiler::generate
 
     // Load callee function and code.  To ensure that |code| doesn't end up being
     // ArgumentsRectifierReg, if it's available we assign it to |callee| instead.
     Register callee = regs.takeAny();
     masm.loadPtr(Address(ICStubReg, ICSetProp_CallNative::offsetOfSetter()), callee);
 
     // To Push R1, read it off of the stowed values on stack.
     // Stack: [ ..., R0, R1, ..STUBFRAME-HEADER.. ]
-    masm.movePtr(BaselineStackReg, scratch);
+    masm.moveStackPtrTo(scratch);
     masm.pushValue(Address(scratch, STUB_FRAME_SIZE));
     masm.push(objReg);
     masm.push(callee);
 
     // Don't need to preserve R0 anymore.
     regs.add(R0);
 
     if (!callVM(DoCallNativeSetterInfo, masm))
@@ -9866,33 +9866,33 @@ void
 ICCallStubCompiler::pushCallArguments(MacroAssembler& masm, AllocatableGeneralRegisterSet regs,
                                       Register argcReg, bool isJitCall, bool isConstructing)
 {
     MOZ_ASSERT(!regs.has(argcReg));
 
     // Account for new.target
     Register count = regs.takeAny();
 
-    masm.mov(argcReg, count);
+    masm.move32(argcReg, count);
 
     // If we are setting up for a jitcall, we have to align the stack taking
     // into account the args and newTarget. We could also count callee and |this|,
     // but it's a waste of stack space. Because we want to keep argcReg unchanged,
     // just account for newTarget initially, and add the other 2 after assuring
     // allignment.
     if (isJitCall) {
         if (isConstructing)
             masm.add32(Imm32(1), count);
     } else {
         masm.add32(Imm32(2 + isConstructing), count);
     }
 
     // argPtr initially points to the last argument.
     Register argPtr = regs.takeAny();
-    masm.mov(BaselineStackReg, argPtr);
+    masm.moveStackPtrTo(argPtr);
 
     // Skip 4 pointers pushed on top of the arguments: the frame descriptor,
     // return address, old frame pointer and stub reg.
     masm.addPtr(Imm32(STUB_FRAME_SIZE), argPtr);
 
     // Align the stack such that the JitFrameLayout is aligned on the
     // JitStackAlignment.
     if (isJitCall) {
@@ -9915,17 +9915,18 @@ ICCallStubCompiler::pushCallArguments(Ma
     }
     masm.bind(&done);
 }
 
 void
 ICCallStubCompiler::guardSpreadCall(MacroAssembler& masm, Register argcReg, Label* failure,
                                     bool isConstructing)
 {
-    masm.unboxObject(Address(BaselineStackReg, isConstructing * sizeof(Value) + ICStackValueOffset), argcReg);
+    masm.unboxObject(Address(masm.getStackPointer(),
+                     isConstructing * sizeof(Value) + ICStackValueOffset), argcReg);
     masm.loadPtr(Address(argcReg, NativeObject::offsetOfElements()), argcReg);
     masm.load32(Address(argcReg, ObjectElements::offsetOfLength()), argcReg);
 
     // Limit actual argc to something reasonable (huge number of arguments can
     // blow the stack limit).
     static_assert(ICCall_Scripted::MAX_ARGS_SPREAD_LENGTH <= ARGS_LENGTH_MAX,
                   "maximum arguments length for optimized stub should be <= ARGS_LENGTH_MAX");
     masm.branch32(Assembler::Above, argcReg, Imm32(ICCall_Scripted::MAX_ARGS_SPREAD_LENGTH),
@@ -9935,42 +9936,43 @@ ICCallStubCompiler::guardSpreadCall(Macr
 void
 ICCallStubCompiler::pushSpreadCallArguments(MacroAssembler& masm,
                                             AllocatableGeneralRegisterSet regs,
                                             Register argcReg, bool isJitCall,
                                             bool isConstructing)
 {
     // Pull the array off the stack before aligning.
     Register startReg = regs.takeAny();
-    masm.unboxObject(Address(BaselineStackReg, (isConstructing * sizeof(Value)) + STUB_FRAME_SIZE), startReg);
+    masm.unboxObject(Address(masm.getStackPointer(),
+                             (isConstructing * sizeof(Value)) + STUB_FRAME_SIZE), startReg);
     masm.loadPtr(Address(startReg, NativeObject::offsetOfElements()), startReg);
     
     // Align the stack such that the JitFrameLayout is aligned on the
     // JitStackAlignment.
     if (isJitCall) {
         Register alignReg = argcReg;
         if (isConstructing) {
             alignReg = regs.takeAny();
-            masm.mov(argcReg, alignReg);
+            masm.movePtr(argcReg, alignReg);
             masm.addPtr(Imm32(1), alignReg);
         }
         masm.alignJitStackBasedOnNArgs(alignReg);
         if (isConstructing) {
             MOZ_ASSERT(alignReg != argcReg);
             regs.add(alignReg);
         }
     }
 
     // Push newTarget, if necessary
     if (isConstructing)
         masm.pushValue(Address(BaselineFrameReg, STUB_FRAME_SIZE));
 
     // Push arguments: set up endReg to point to &array[argc]
     Register endReg = regs.takeAny();
-    masm.mov(argcReg, endReg);
+    masm.movePtr(argcReg, endReg);
     static_assert(sizeof(Value) == 8, "Value must be 8 bytes");
     masm.lshiftPtr(Imm32(3), endReg);
     masm.addPtr(startReg, endReg);
 
     // Copying pre-decrements endReg by 8 until startReg is reached
     Label copyDone;
     Label copyStart;
     masm.bind(&copyStart);
@@ -9999,17 +10001,17 @@ ICCallStubCompiler::guardFunApply(MacroA
                                   Label* failure)
 {
     // Ensure argc == 2
     masm.branch32(Assembler::NotEqual, argcReg, Imm32(2), failure);
 
     // Stack looks like:
     //      [..., CalleeV, ThisV, Arg0V, Arg1V <MaybeReturnReg>]
 
-    Address secondArgSlot(BaselineStackReg, ICStackValueOffset);
+    Address secondArgSlot(masm.getStackPointer(), ICStackValueOffset);
     if (applyThing == FunApply_MagicArgs) {
         // Ensure that the second arg is magic arguments.
         masm.branchTestMagic(Assembler::NotEqual, secondArgSlot, failure);
 
         // Ensure that this frame doesn't have an arguments object.
         masm.branchTest32(Assembler::NonZero,
                           Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfFlags()),
                           Imm32(BaselineFrame::HAS_ARGS_OBJ),
@@ -10066,31 +10068,31 @@ ICCallStubCompiler::guardFunApply(MacroA
         masm.bind(&endLoop);
     }
 
     // Stack now confirmed to be like:
     //      [..., CalleeV, ThisV, Arg0V, MagicValue(Arguments), <MaybeReturnAddr>]
 
     // Load the callee, ensure that it's fun_apply
     ValueOperand val = regs.takeAnyValue();
-    Address calleeSlot(BaselineStackReg, ICStackValueOffset + (3 * sizeof(Value)));
+    Address calleeSlot(masm.getStackPointer(), ICStackValueOffset + (3 * sizeof(Value)));
     masm.loadValue(calleeSlot, val);
 
     masm.branchTestObject(Assembler::NotEqual, val, failure);
     Register callee = masm.extractObject(val, ExtractTemp1);
 
     masm.branchTestObjClass(Assembler::NotEqual, callee, regs.getAny(), &JSFunction::class_,
                             failure);
     masm.loadPtr(Address(callee, JSFunction::offsetOfNativeOrScript()), callee);
 
     masm.branchPtr(Assembler::NotEqual, callee, ImmPtr(fun_apply), failure);
 
     // Load the |thisv|, ensure that it's a scripted function with a valid baseline or ion
     // script, or a native function.
-    Address thisSlot(BaselineStackReg, ICStackValueOffset + (2 * sizeof(Value)));
+    Address thisSlot(masm.getStackPointer(), ICStackValueOffset + (2 * sizeof(Value)));
     masm.loadValue(thisSlot, val);
 
     masm.branchTestObject(Assembler::NotEqual, val, failure);
     Register target = masm.extractObject(val, ExtractTemp1);
     regs.add(val);
     regs.takeUnchecked(target);
 
     masm.branchTestObjClass(Assembler::NotEqual, target, regs.getAny(), &JSFunction::class_,
@@ -10202,17 +10204,17 @@ ICCall_Fallback::Compiler::generateStubC
         masm.pushValue(Address(BaselineFrameReg, valueOffset++ * sizeof(Value) + STUB_FRAME_SIZE));
         
         // this
         masm.pushValue(Address(BaselineFrameReg, valueOffset++ * sizeof(Value) + STUB_FRAME_SIZE));
         
         // callee
         masm.pushValue(Address(BaselineFrameReg, valueOffset++ * sizeof(Value) + STUB_FRAME_SIZE));
 
-        masm.push(BaselineStackReg);
+        masm.push(masm.getStackPointer());
         masm.push(ICStubReg);
 
         pushFramePtr(masm, R0.scratchReg());
 
         if (!callVM(DoSpreadCallFallbackInfo, masm))
             return false;
 
         leaveStubFrame(masm);
@@ -10225,17 +10227,17 @@ ICCall_Fallback::Compiler::generateStubC
 
     // Push a stub frame so that we can perform a non-tail call.
     enterStubFrame(masm, R1.scratchReg());
 
     regs.take(R0.scratchReg()); // argc.
 
     pushCallArguments(masm, regs, R0.scratchReg(), /* isJitCall = */ false, isConstructing_);
 
-    masm.push(BaselineStackReg);
+    masm.push(masm.getStackPointer());
     masm.push(R0.scratchReg());
     masm.push(ICStubReg);
 
     pushFramePtr(masm, R0.scratchReg());
 
     if (!callVM(DoCallFallbackInfo, masm))
         return false;
 
@@ -10248,17 +10250,17 @@ ICCall_Fallback::Compiler::generateStubC
     returnOffset_ = masm.currentOffset();
 
     // Here we are again in a stub frame. Marking as so.
     inStubFrame_ = true;
 
     // Load passed-in ThisV into R1 just in case it's needed.  Need to do this before
     // we leave the stub frame since that info will be lost.
     // Current stack:  [...., ThisV, ActualArgc, CalleeToken, Descriptor ]
-    masm.loadValue(Address(BaselineStackReg, 3 * sizeof(size_t)), R1);
+    masm.loadValue(Address(masm.getStackPointer(), 3 * sizeof(size_t)), R1);
 
     leaveStubFrame(masm, true);
 
     // If this is a |constructing| call, if the callee returns a non-object, we replace it with
     // the |this| object passed in.
     if (isConstructing_) {
         MOZ_ASSERT(JSReturnOperand == R0);
         Label skipThisReplace;
@@ -10317,21 +10319,21 @@ ICCallScriptedCompiler::generateStubCode
 
     if (isSpread_)
         guardSpreadCall(masm, argcReg, &failure, isConstructing_);
 
     // Load the callee in R1, accounting for newTarget, if necessary
     // Stack Layout: [ ..., CalleeVal, ThisVal, Arg0Val, ..., ArgNVal, [newTarget] +ICStackValueOffset+ ]
     if (isSpread_) {
         unsigned skipToCallee = (2 + isConstructing_) * sizeof(Value);
-        masm.loadValue(Address(BaselineStackReg, skipToCallee + ICStackValueOffset), R1);
+        masm.loadValue(Address(masm.getStackPointer(), skipToCallee + ICStackValueOffset), R1);
     } else {
         // Account for newTarget, if necessary
         unsigned nonArgsSkip = (1 + isConstructing_) * sizeof(Value);
-        BaseValueIndex calleeSlot(BaselineStackReg, argcReg, ICStackValueOffset + nonArgsSkip);
+        BaseValueIndex calleeSlot(masm.getStackPointer(), argcReg, ICStackValueOffset + nonArgsSkip);
         masm.loadValue(calleeSlot, R1);
     }
     regs.take(R1);
 
     // Ensure callee is an object.
     masm.branchTestObject(Assembler::NotEqual, R1, &failure);
 
     // Ensure callee is a function.
@@ -10383,20 +10385,20 @@ ICCallScriptedCompiler::generateStubCode
 
     if (isConstructing_) {
         // Save argc before call.
         masm.push(argcReg);
 
         // Stack now looks like:
         //      [..., Callee, ThisV, Arg0V, ..., ArgNV, NewTarget, StubFrameHeader, ArgC ]
         if (isSpread_) {
-            masm.loadValue(Address(BaselineStackReg,
+            masm.loadValue(Address(masm.getStackPointer(),
                                    3 * sizeof(Value) + STUB_FRAME_SIZE + sizeof(size_t)), R1);
         } else {
-            BaseValueIndex calleeSlot2(BaselineStackReg, argcReg,
+            BaseValueIndex calleeSlot2(masm.getStackPointer(), argcReg,
                                        2 * sizeof(Value) + STUB_FRAME_SIZE + sizeof(size_t));
             masm.loadValue(calleeSlot2, R1);
         }
         masm.push(masm.extractObject(R1, ExtractTemp0));
         if (!callVM(CreateThisInfoBaseline, masm))
             return false;
 
         // Return of CreateThis must be an object.
@@ -10417,38 +10419,40 @@ ICCallScriptedCompiler::generateStubCode
         // Restore saved argc so we can use it to calculate the address to save
         // the resulting this object to.
         masm.pop(argcReg);
 
         // Save "this" value back into pushed arguments on stack.  R0 can be clobbered after that.
         // Stack now looks like:
         //      [..., Callee, ThisV, Arg0V, ..., ArgNV, [NewTarget], StubFrameHeader ]
         if (isSpread_) {
-            masm.storeValue(R0, Address(BaselineStackReg, (1 + isConstructing_) * sizeof(Value) + STUB_FRAME_SIZE));
+            masm.storeValue(R0, Address(masm.getStackPointer(),
+                                        (1 + isConstructing_) * sizeof(Value) + STUB_FRAME_SIZE));
         } else {
-            BaseValueIndex thisSlot(BaselineStackReg, argcReg, STUB_FRAME_SIZE + isConstructing_ * sizeof(Value));
+            BaseValueIndex thisSlot(masm.getStackPointer(), argcReg,
+                                    STUB_FRAME_SIZE + isConstructing_ * sizeof(Value));
             masm.storeValue(R0, thisSlot);
         }
 
         // Restore the stub register from the baseline stub frame.
-        masm.loadPtr(Address(BaselineStackReg, STUB_FRAME_SAVED_STUB_OFFSET), ICStubReg);
+        masm.loadPtr(Address(masm.getStackPointer(), STUB_FRAME_SAVED_STUB_OFFSET), ICStubReg);
 
         // Reload callee script. Note that a GC triggered by CreateThis may
         // have destroyed the callee BaselineScript and IonScript. CreateThis is
         // safely repeatable though, so in this case we just leave the stub frame
         // and jump to the next stub.
 
         // Just need to load the script now.
         if (isSpread_) {
             unsigned skipForCallee = (2 + isConstructing_) * sizeof(Value);
-            masm.loadValue(Address(BaselineStackReg, skipForCallee + STUB_FRAME_SIZE), R0);
+            masm.loadValue(Address(masm.getStackPointer(), skipForCallee + STUB_FRAME_SIZE), R0);
         } else {
             // Account for newTarget, if necessary
             unsigned nonArgsSkip = (1 + isConstructing_) * sizeof(Value);
-            BaseValueIndex calleeSlot3(BaselineStackReg, argcReg, nonArgsSkip + STUB_FRAME_SIZE);
+            BaseValueIndex calleeSlot3(masm.getStackPointer(), argcReg, nonArgsSkip + STUB_FRAME_SIZE);
             masm.loadValue(calleeSlot3, R0);
         }
         callee = masm.extractObject(R0, ExtractTemp0);
         regs.add(R0);
         regs.takeUnchecked(callee);
         masm.loadPtr(Address(callee, JSFunction::offsetOfNativeOrScript()), callee);
 
         code = regs.takeAny();
@@ -10495,17 +10499,17 @@ ICCallScriptedCompiler::generateStubCode
         MOZ_ASSERT(ArgumentsRectifierReg != code);
         MOZ_ASSERT(ArgumentsRectifierReg != argcReg);
 
         JitCode* argumentsRectifier =
             cx->runtime()->jitRuntime()->getArgumentsRectifier();
 
         masm.movePtr(ImmGCPtr(argumentsRectifier), code);
         masm.loadPtr(Address(code, JitCode::offsetOfCode()), code);
-        masm.mov(argcReg, ArgumentsRectifierReg);
+        masm.movePtr(argcReg, ArgumentsRectifierReg);
     }
 
     masm.bind(&noUnderflow);
     masm.callJit(code);
 
     // If this is a constructing call, and the callee returns a non-object, replace it with
     // the |this| object passed in.
     if (isConstructing_) {
@@ -10519,29 +10523,29 @@ ICCallScriptedCompiler::generateStubCode
         //                  Padding?, ARGVALS..., ThisVal, ActualArgc, Callee, Descriptor ]
 
         // Restore the BaselineFrameReg based on the frame descriptor.
         //
         // BaselineFrameReg = BaselineStackReg
         //                  + sizeof(Descriptor) + sizeof(Callee) + sizeof(ActualArgc)
         //                  + stubFrameSize(Descriptor)
         //                  - sizeof(ICStubReg) - sizeof(BaselineFrameReg)
-        Address descriptorAddr(BaselineStackReg, 0);
+        Address descriptorAddr(masm.getStackPointer(), 0);
         masm.loadPtr(descriptorAddr, BaselineFrameReg);
         masm.rshiftPtr(Imm32(FRAMESIZE_SHIFT), BaselineFrameReg);
         masm.addPtr(Imm32((3 - 2) * sizeof(size_t)), BaselineFrameReg);
-        masm.addPtr(BaselineStackReg, BaselineFrameReg);
+        masm.addStackPtrTo(BaselineFrameReg);
 
         // Load the number of arguments present before the stub frame.
         Register argcReg = JSReturnOperand.scratchReg();
         if (isSpread_) {
             // Account for the Array object.
             masm.move32(Imm32(1), argcReg);
         } else {
-            Address argcAddr(BaselineStackReg, 2 * sizeof(size_t));
+            Address argcAddr(masm.getStackPointer(), 2 * sizeof(size_t));
             masm.loadPtr(argcAddr, argcReg);
         }
 
         // Current stack: [ ThisVal, ARGVALS..., ...STUB FRAME..., <-- BaselineFrameReg
         //                  Padding?, ARGVALS..., ThisVal, ActualArgc, Callee, Descriptor ]
         //
         // &ThisVal = BaselineFrameReg + argc * sizeof(Value) + STUB_FRAME_SIZE + sizeof(Value)
         // This last sizeof(Value) accounts for the newTarget on the end of the arguments vector
@@ -10560,17 +10564,17 @@ ICCallScriptedCompiler::generateStubCode
     // Enter type monitor IC to type-check result.
     EmitEnterTypeMonitorIC(masm);
 
     // Leave stub frame and restore argc for the next stub.
     masm.bind(&failureLeaveStubFrame);
     inStubFrame_ = true;
     leaveStubFrame(masm, false);
     if (argcReg != R0.scratchReg())
-        masm.mov(argcReg, R0.scratchReg());
+        masm.movePtr(argcReg, R0.scratchReg());
 
     masm.bind(&failure);
     EmitStubGuardFailure(masm);
     return true;
 }
 
 typedef bool (*CopyArrayFn)(JSContext*, HandleObject, MutableHandleValue);
 static const VMFunction CopyArrayInfo = FunctionInfo<CopyArrayFn>(CopyArray);
@@ -10589,17 +10593,17 @@ ICCall_StringSplit::Compiler::generateSt
     masm.branch32(Assembler::Equal, argcReg, Imm32(1), &oneArg);
     masm.assumeUnreachable("Expected argc == 1");
     masm.bind(&oneArg);
 #endif
     Register scratchReg = regs.takeAny();
 
     // Guard that callee is native function js::str_split.
     {
-        Address calleeAddr(BaselineStackReg, ICStackValueOffset + (2 * sizeof(Value)));
+        Address calleeAddr(masm.getStackPointer(), ICStackValueOffset + (2 * sizeof(Value)));
         ValueOperand calleeVal = regs.takeAnyValue();
 
         // Ensure that callee is an object.
         masm.loadValue(calleeAddr, calleeVal);
         masm.branchTestObject(Assembler::NotEqual, calleeVal, &failureRestoreArgc);
 
         // Ensure that callee is a function.
         Register calleeObj = masm.extractObject(calleeVal, ExtractTemp0);
@@ -10611,32 +10615,32 @@ ICCall_StringSplit::Compiler::generateSt
         masm.branchPtr(Assembler::NotEqual, scratchReg, ImmPtr(js::str_split), &failureRestoreArgc);
 
         regs.add(calleeVal);
     }
 
     // Guard argument.
     {
         // Ensure that arg is a string.
-        Address argAddr(BaselineStackReg, ICStackValueOffset);
+        Address argAddr(masm.getStackPointer(), ICStackValueOffset);
         ValueOperand argVal = regs.takeAnyValue();
 
         masm.loadValue(argAddr, argVal);
         masm.branchTestString(Assembler::NotEqual, argVal, &failureRestoreArgc);
 
         Register argString = masm.extractString(argVal, ExtractTemp0);
         masm.branchPtr(Assembler::NotEqual, Address(ICStubReg, offsetOfExpectedArg()),
                        argString, &failureRestoreArgc);
         regs.add(argVal);
     }
 
     // Guard this-value.
     {
         // Ensure that thisv is a string.
-        Address thisvAddr(BaselineStackReg, ICStackValueOffset + sizeof(Value));
+        Address thisvAddr(masm.getStackPointer(), ICStackValueOffset + sizeof(Value));
         ValueOperand thisvVal = regs.takeAnyValue();
 
         masm.loadValue(thisvAddr, thisvVal);
         masm.branchTestString(Assembler::NotEqual, thisvVal, &failureRestoreArgc);
 
         Register thisvString = masm.extractString(thisvVal, ExtractTemp0);
         masm.branchPtr(Assembler::NotEqual, Address(ICStubReg, offsetOfExpectedThis()),
                        thisvString, &failureRestoreArgc);
@@ -10675,17 +10679,17 @@ ICCall_IsSuspendedStarGenerator::Compile
 
     // The IsSuspendedStarGenerator intrinsic is only called in self-hosted
     // code, so it's safe to assume we have a single argument and the callee
     // is our intrinsic.
 
     AllocatableGeneralRegisterSet regs(availableGeneralRegs(0));
 
     // Load the argument.
-    Address argAddr(BaselineStackReg, ICStackValueOffset);
+    Address argAddr(masm.getStackPointer(), ICStackValueOffset);
     ValueOperand argVal = regs.takeAnyValue();
     masm.loadValue(argAddr, argVal);
 
     // Check if it's an object.
     Label returnFalse;
     Register genObj = regs.takeAny();
     masm.branchTestObject(Assembler::NotEqual, argVal, &returnFalse);
     masm.unboxObject(argVal, genObj);
@@ -10724,20 +10728,20 @@ ICCall_Native::Compiler::generateStubCod
     regs.take(argcReg);
     regs.takeUnchecked(ICTailCallReg);
 
     if (isSpread_)
         guardSpreadCall(masm, argcReg, &failure, isConstructing_);
 
     // Load the callee in R1.
     if (isSpread_) {
-        masm.loadValue(Address(BaselineStackReg, ICStackValueOffset + 2 * sizeof(Value)), R1);
+        masm.loadValue(Address(masm.getStackPointer(), ICStackValueOffset + 2 * sizeof(Value)), R1);
     } else {
         unsigned nonArgsSlots = (1 + isConstructing_) * sizeof(Value);
-        BaseValueIndex calleeSlot(BaselineStackReg, argcReg, ICStackValueOffset + nonArgsSlots);
+        BaseValueIndex calleeSlot(masm.getStackPointer(), argcReg, ICStackValueOffset + nonArgsSlots);
         masm.loadValue(calleeSlot, R1);
     }
     regs.take(R1);
 
     masm.branchTestObject(Assembler::NotEqual, R1, &failure);
 
     // Ensure callee matches this stub's callee.
     Register callee = masm.extractObject(R1, ExtractTemp0);
@@ -10757,20 +10761,19 @@ ICCall_Native::Compiler::generateStubCod
     if (isSpread_)
         pushSpreadCallArguments(masm, regs, argcReg, /* isJitCall = */ false, isConstructing_);
     else
         pushCallArguments(masm, regs, argcReg, /* isJitCall = */ false, isConstructing_);
 
     if (isConstructing_) {
         // Stack looks like: [ ..., Arg0Val, ThisVal, CalleeVal ]
         // Replace ThisVal with MagicValue(JS_IS_CONSTRUCTING)
-        masm.storeValue(MagicValue(JS_IS_CONSTRUCTING), Address(BaselineStackReg, sizeof(Value)));
-    }
-
-    masm.checkStackAlignment();
+        masm.storeValue(MagicValue(JS_IS_CONSTRUCTING), Address(masm.getStackPointer(), sizeof(Value)));
+    }
+
 
     // Native functions have the signature:
     //
     //    bool (*)(JSContext*, unsigned, Value* vp)
     //
     // Where vp[0] is space for callee/return value, vp[1] is |this|, and vp[2] onward
     // are the function arguments.
 
@@ -10789,17 +10792,17 @@ ICCall_Native::Compiler::generateStubCod
 
     // Execute call.
     masm.setupUnalignedABICall(3, scratch);
     masm.loadJSContext(scratch);
     masm.passABIArg(scratch);
     masm.passABIArg(argcReg);
     masm.passABIArg(vpReg);
 
-#if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR)
+#if defined(JS_ARM_SIMULATOR) || defined(JS_ARM64_SIMULATOR) || defined(JS_MIPS_SIMULATOR)
     // The simulator requires VM calls to be redirected to a special swi
     // instruction to handle them, so we store the redirected pointer in the
     // stub and use that instead of the original one.
     masm.callWithABI(Address(ICStubReg, ICCall_Native::offsetOfNative()));
 #else
     masm.callWithABI(Address(callee, JSFunction::offsetOfNativeOrScript()));
 #endif
 
@@ -10828,17 +10831,17 @@ ICCall_ClassHook::Compiler::generateStub
     AllocatableGeneralRegisterSet regs(availableGeneralRegs(0));
 
     Register argcReg = R0.scratchReg();
     regs.take(argcReg);
     regs.takeUnchecked(ICTailCallReg);
 
     // Load the callee in R1.
     unsigned nonArgSlots = (1 + isConstructing_) * sizeof(Value);
-    BaseValueIndex calleeSlot(BaselineStackReg, argcReg, ICStackValueOffset + nonArgSlots);
+    BaseValueIndex calleeSlot(masm.getStackPointer(), argcReg, ICStackValueOffset + nonArgSlots);
     masm.loadValue(calleeSlot, R1);
     regs.take(R1);
 
     masm.branchTestObject(Assembler::NotEqual, R1, &failure);
 
     // Ensure the callee's class matches the one in this stub.
     Register callee = masm.extractObject(R1, ExtractTemp0);
     Register scratch = regs.takeAny();
@@ -10856,17 +10859,17 @@ ICCall_ClassHook::Compiler::generateStub
 
     regs.add(scratch);
     pushCallArguments(masm, regs, argcReg, /* isJitCall = */ false, isConstructing_);
     regs.take(scratch);
 
     if (isConstructing_) {
         // Stack looks like: [ ..., Arg0Val, ThisVal, CalleeVal ]
         // Replace ThisVal with MagicValue(JS_IS_CONSTRUCTING)
-        masm.storeValue(MagicValue(JS_IS_CONSTRUCTING), Address(BaselineStackReg, sizeof(Value)));
+        masm.storeValue(MagicValue(JS_IS_CONSTRUCTING), Address(masm.getStackPointer(), sizeof(Value)));
     }
 
     masm.checkStackAlignment();
 
     // Native functions have the signature:
     //
     //    bool (*)(JSContext*, unsigned, Value* vp)
     //
@@ -10991,17 +10994,17 @@ ICCall_ScriptedApplyArray::Compiler::gen
         MOZ_ASSERT(ArgumentsRectifierReg != target);
         MOZ_ASSERT(ArgumentsRectifierReg != argcReg);
 
         JitCode* argumentsRectifier =
             cx->runtime()->jitRuntime()->getArgumentsRectifier();
 
         masm.movePtr(ImmGCPtr(argumentsRectifier), target);
         masm.loadPtr(Address(target, JitCode::offsetOfCode()), target);
-        masm.mov(argcReg, ArgumentsRectifierReg);
+        masm.movePtr(argcReg, ArgumentsRectifierReg);
     }
     masm.bind(&noUnderflow);
     regs.add(argcReg);
 
     // Do call
     masm.callJit(target);
     leaveStubFrame(masm, true);
 
@@ -11089,17 +11092,17 @@ ICCall_ScriptedApplyArguments::Compiler:
         MOZ_ASSERT(ArgumentsRectifierReg != target);
         MOZ_ASSERT(ArgumentsRectifierReg != argcReg);
 
         JitCode* argumentsRectifier =
             cx->runtime()->jitRuntime()->getArgumentsRectifier();
 
         masm.movePtr(ImmGCPtr(argumentsRectifier), target);
         masm.loadPtr(Address(target, JitCode::offsetOfCode()), target);
-        masm.mov(argcReg, ArgumentsRectifierReg);
+        masm.movePtr(argcReg, ArgumentsRectifierReg);
     }
     masm.bind(&noUnderflow);
     regs.add(argcReg);
 
     // Do call
     masm.callJit(target);
     leaveStubFrame(masm, true);
 
@@ -11124,31 +11127,31 @@ ICCall_ScriptedFunCall::Compiler::genera
     MOZ_ASSERT(argcReg != ArgumentsRectifierReg);
 
     regs.take(argcReg);
     regs.take(ArgumentsRectifierReg);
     regs.takeUnchecked(ICTailCallReg);
 
     // Load the callee in R1.
     // Stack Layout: [ ..., CalleeVal, ThisVal, Arg0Val, ..., ArgNVal, +ICStackValueOffset+ ]
-    BaseValueIndex calleeSlot(BaselineStackReg, argcReg, ICStackValueOffset + sizeof(Value));
+    BaseValueIndex calleeSlot(masm.getStackPointer(), argcReg, ICStackValueOffset + sizeof(Value));
     masm.loadValue(calleeSlot, R1);
     regs.take(R1);
 
     // Ensure callee is fun_call.
     masm.branchTestObject(Assembler::NotEqual, R1, &failure);
 
     Register callee = masm.extractObject(R1, ExtractTemp0);
     masm.branchTestObjClass(Assembler::NotEqual, callee, regs.getAny(), &JSFunction::class_,
                             &failure);
     masm.loadPtr(Address(callee, JSFunction::offsetOfNativeOrScript()), callee);
     masm.branchPtr(Assembler::NotEqual, callee, ImmPtr(fun_call), &failure);
 
     // Ensure |this| is a scripted function with JIT code.
-    BaseIndex thisSlot(BaselineStackReg, argcReg, TimesEight, ICStackValueOffset);
+    BaseIndex thisSlot(masm.getStackPointer(), argcReg, TimesEight, ICStackValueOffset);
     masm.loadValue(thisSlot, R1);
 
     masm.branchTestObject(Assembler::NotEqual, R1, &failure);
     callee = masm.extractObject(R1, ExtractTemp0);
 
     masm.branchTestObjClass(Assembler::NotEqual, callee, regs.getAny(), &JSFunction::class_,
                             &failure);
     masm.branchIfFunctionHasNoScript(callee, &failure);
@@ -11170,16 +11173,17 @@ ICCall_ScriptedFunCall::Compiler::genera
     Label zeroArgs, done;
     masm.branchTest32(Assembler::Zero, argcReg, argcReg, &zeroArgs);
 
     // Avoid the copy of the callee (function.call).
     masm.sub32(Imm32(1), argcReg);
 
     // Values are on the stack left-to-right. Calling convention wants them
     // right-to-left so duplicate them on the stack in reverse order.
+
     pushCallArguments(masm, regs, argcReg, /* isJitCall = */ true);
 
     // Pop scripted callee (the original |this|).
     ValueOperand val = regs.takeAnyValue();
     masm.popValue(val);
 
     masm.jump(&done);
     masm.bind(&zeroArgs);
@@ -11217,17 +11221,17 @@ ICCall_ScriptedFunCall::Compiler::genera
         MOZ_ASSERT(ArgumentsRectifierReg != code);
         MOZ_ASSERT(ArgumentsRectifierReg != argcReg);
 
         JitCode* argumentsRectifier =
             cx->runtime()->jitRuntime()->getArgumentsRectifier();
 
         masm.movePtr(ImmGCPtr(argumentsRectifier), code);
         masm.loadPtr(Address(code, JitCode::offsetOfCode()), code);
-        masm.mov(argcReg, ArgumentsRectifierReg);
+        masm.movePtr(argcReg, ArgumentsRectifierReg);
     }
 
     masm.bind(&noUnderflow);
     masm.callJit(code);
 
     leaveStubFrame(masm, true);
 
     // Enter type monitor IC to type-check result.
@@ -11289,17 +11293,17 @@ ICTableSwitch::Compiler::generateStubCod
         masm.moveStackPtrTo(R0.scratchReg());
 
         masm.setupUnalignedABICall(1, scratch);
         masm.passABIArg(R0.scratchReg());
         masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, DoubleValueToInt32ForSwitch));
 
         // If the function returns |true|, the value has been converted to
         // int32.
-        masm.mov(ReturnReg, scratch);
+        masm.movePtr(ReturnReg, scratch);
         masm.popValue(R0);
         masm.branchIfFalseBool(scratch, &outOfRange);
         masm.unboxInt32(R0, key);
     }
     masm.jump(&isInt32);
 
     masm.bind(&outOfRange);
 
@@ -12407,17 +12411,17 @@ ICCall_AnyScripted::Clone(JSContext* cx,
 ICCall_Native::ICCall_Native(JitCode* stubCode, ICStub* firstMonitorStub,
                              JSFunction* callee, JSObject* templateObject,
                              uint32_t pcOffset)
   : ICMonitoredStub(ICStub::Call_Native, stubCode, firstMonitorStub),
     callee_(callee),
     templateObject_(templateObject),
     pcOffset_(pcOffset)
 {
-#if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR)
+#if defined(JS_ARM_SIMULATOR) || defined(JS_ARM64_SIMULATOR) || defined(JS_MIPS_SIMULATOR)
     // The simulator requires VM calls to be redirected to a special swi
     // instruction to handle them. To make this work, we store the redirected
     // pointer in the stub.
     native_ = Simulator::RedirectNativeFunction(JS_FUNC_TO_DATA_PTR(void*, callee->native()),
                                                 Args_General3);
 #endif
 }
 
@@ -12433,17 +12437,17 @@ ICCall_ClassHook::ICCall_ClassHook(JitCo
                                    const Class* clasp, Native native,
                                    JSObject* templateObject, uint32_t pcOffset)
   : ICMonitoredStub(ICStub::Call_ClassHook, stubCode, firstMonitorStub),
     clasp_(clasp),
     native_(JS_FUNC_TO_DATA_PTR(void*, native)),
     templateObject_(templateObject),
     pcOffset_(pcOffset)
 {
-#if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR)
+#if defined(JS_ARM_SIMULATOR) || defined(JS_ARM64_SIMULATOR) || defined(JS_MIPS_SIMULATOR)
     // The simulator requires VM calls to be redirected to a special swi
     // instruction to handle them. To make this work, we store the redirected
     // pointer in the stub.
     native_ = Simulator::RedirectNativeFunction(native_, Args_General3);
 #endif
 }
 
 /* static */ ICCall_ClassHook*
--- a/js/src/jit/BaselineIC.h
+++ b/js/src/jit/BaselineIC.h
@@ -4612,18 +4612,18 @@ class ICCall_Native : public ICMonitored
 {
     friend class ICStubSpace;
 
   protected:
     HeapPtrFunction callee_;
     HeapPtrObject templateObject_;
     uint32_t pcOffset_;
 
-#if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR)
-    void* native_;
+#if defined(JS_ARM_SIMULATOR) || defined(JS_ARM64_SIMULATOR) || defined(JS_MIPS_SIMULATOR)
+    void *native_;
 #endif
 
     ICCall_Native(JitCode* stubCode, ICStub* firstMonitorStub,
                   JSFunction* callee, JSObject* templateObject,
                   uint32_t pcOffset);
 
   public:
     static ICCall_Native* Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
@@ -4638,17 +4638,17 @@ class ICCall_Native : public ICMonitored
 
     static size_t offsetOfCallee() {
         return offsetof(ICCall_Native, callee_);
     }
     static size_t offsetOfPCOffset() {
         return offsetof(ICCall_Native, pcOffset_);
     }
 
-#if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR)
+#if defined(JS_ARM_SIMULATOR) || defined(JS_ARM64_SIMULATOR) || defined(JS_MIPS_SIMULATOR)
     static size_t offsetOfNative() {
         return offsetof(ICCall_Native, native_);
     }
 #endif
 
     // Compiler for this stub kind.
     class Compiler : public ICCallStubCompiler {
       protected: