Align the stack correctly on ARM on calls to fp operation helpers.
Review URL: http://codereview.chromium.org/259013 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3011 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
4b19c36068
commit
8cf140259d
@ -645,8 +645,8 @@ class Assembler : public Malloced {
|
||||
str(src, MemOperand(sp, 4, NegPreIndex), cond);
|
||||
}
|
||||
|
||||
void pop(Register dst) {
|
||||
ldr(dst, MemOperand(sp, 4, PostIndex), al);
|
||||
void pop(Register dst, Condition cond = al) {
|
||||
ldr(dst, MemOperand(sp, 4, PostIndex), cond);
|
||||
}
|
||||
|
||||
void pop() {
|
||||
|
@ -5061,11 +5061,14 @@ static void HandleBinaryOpSlowCases(MacroAssembler* masm,
|
||||
// r5: Address of heap number for result.
|
||||
__ push(lr); // For later.
|
||||
__ push(r5); // Address of heap number that is answer.
|
||||
__ AlignStack(0);
|
||||
// Call C routine that may not cause GC or other trouble.
|
||||
__ mov(r5, Operand(ExternalReference::double_fp_operation(operation)));
|
||||
__ Call(r5);
|
||||
__ pop(r4); // Address of heap number.
|
||||
__ cmp(r4, Operand(Smi::FromInt(0)));
|
||||
__ pop(r4, eq); // Conditional pop instruction to get rid of alignment push.
|
||||
// Store answer in the overwritable heap number.
|
||||
__ pop(r4);
|
||||
#if !defined(USE_ARM_EABI)
|
||||
// Double returned in fp coprocessor register 0 and 1, encoded as register
|
||||
// cr8. Offsets must be divisible by 4 for coprocessor so we need to
|
||||
|
@ -291,27 +291,8 @@ void MacroAssembler::EnterExitFrame(StackFrame::Type type) {
|
||||
|
||||
// Align the stack at this point. After this point we have 5 pushes,
|
||||
// so in fact we have to unalign here! See also the assert on the
|
||||
// alignment immediately below.
|
||||
#if defined(V8_HOST_ARCH_ARM)
|
||||
// Running on the real platform. Use the alignment as mandated by the local
|
||||
// environment.
|
||||
// Note: This will break if we ever start generating snapshots on one ARM
|
||||
// platform for another ARM platform with a different alignment.
|
||||
int activation_frame_alignment = OS::ActivationFrameAlignment();
|
||||
#else // defined(V8_HOST_ARCH_ARM)
|
||||
// If we are using the simulator then we should always align to the expected
|
||||
// alignment. As the simulator is used to generate snapshots we do not know
|
||||
// if the target platform will need alignment, so we will always align at
|
||||
// this point here.
|
||||
int activation_frame_alignment = 2 * kPointerSize;
|
||||
#endif // defined(V8_HOST_ARCH_ARM)
|
||||
if (activation_frame_alignment != kPointerSize) {
|
||||
// This code needs to be made more general if this assert doesn't hold.
|
||||
ASSERT(activation_frame_alignment == 2 * kPointerSize);
|
||||
mov(r7, Operand(Smi::FromInt(0)));
|
||||
tst(sp, Operand(activation_frame_alignment - 1));
|
||||
push(r7, eq); // Conditional push instruction.
|
||||
}
|
||||
// alignment in AlignStack.
|
||||
AlignStack(1);
|
||||
|
||||
// Push in reverse order: caller_fp, sp_on_exit, and caller_pc.
|
||||
stm(db_w, sp, fp.bit() | ip.bit() | lr.bit());
|
||||
@ -343,6 +324,30 @@ void MacroAssembler::EnterExitFrame(StackFrame::Type type) {
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::AlignStack(int offset) {
|
||||
#if defined(V8_HOST_ARCH_ARM)
|
||||
// Running on the real platform. Use the alignment as mandated by the local
|
||||
// environment.
|
||||
// Note: This will break if we ever start generating snapshots on one ARM
|
||||
// platform for another ARM platform with a different alignment.
|
||||
int activation_frame_alignment = OS::ActivationFrameAlignment();
|
||||
#else // defined(V8_HOST_ARCH_ARM)
|
||||
// If we are using the simulator then we should always align to the expected
|
||||
// alignment. As the simulator is used to generate snapshots we do not know
|
||||
// if the target platform will need alignment, so we will always align at
|
||||
// this point here.
|
||||
int activation_frame_alignment = 2 * kPointerSize;
|
||||
#endif // defined(V8_HOST_ARCH_ARM)
|
||||
if (activation_frame_alignment != kPointerSize) {
|
||||
// This code needs to be made more general if this assert doesn't hold.
|
||||
ASSERT(activation_frame_alignment == 2 * kPointerSize);
|
||||
mov(r7, Operand(Smi::FromInt(0)));
|
||||
tst(sp, Operand(activation_frame_alignment - offset));
|
||||
push(r7, eq); // Conditional push instruction.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::LeaveExitFrame(StackFrame::Type type) {
|
||||
#ifdef ENABLE_DEBUGGER_SUPPORT
|
||||
// Restore the memory copy of the registers by digging them out from
|
||||
|
@ -96,6 +96,8 @@ class MacroAssembler: public Assembler {
|
||||
// Leave the current exit frame. Expects the return value in r0.
|
||||
void LeaveExitFrame(StackFrame::Type type);
|
||||
|
||||
// Align the stack by optionally pushing a Smi zero.
|
||||
void AlignStack(int offset);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// JavaScript invokes
|
||||
|
Loading…
Reference in New Issue
Block a user