From: yangguo@chromium.org Date: Thu, 1 Sep 2011 07:35:33 +0000 (+0000) Subject: MIPS: port ARM: Fix context save/restore for VFP registers. X-Git-Tag: upstream/4.7.83~18600 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d586e9c504e9b9582eaf9c94e4400c577c670357;p=platform%2Fupstream%2Fv8.git MIPS: port ARM: Fix context save/restore for VFP registers. This commit was missed/skipped earlier for some reason. Ported r8357 (d78dae4) BUG= TEST= Review URL: http://codereview.chromium.org/7809014 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9088 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc index 9385f2fda..7c2a146f4 100644 --- a/src/mips/code-stubs-mips.cc +++ b/src/mips/code-stubs-mips.cc @@ -3695,9 +3695,20 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { // Save callee saved registers on the stack. __ MultiPush(kCalleeSaved | ra.bit()); + if (CpuFeatures::IsSupported(FPU)) { + CpuFeatures::Scope scope(FPU); + // Save callee-saved FPU registers. + __ MultiPushFPU(kCalleeSavedFPU); + } + // Load argv in s0 register. - __ lw(s0, MemOperand(sp, (kNumCalleeSaved + 1) * kPointerSize + - StandardFrameConstants::kCArgsSlotsSize)); + int offset_to_argv = (kNumCalleeSaved + 1) * kPointerSize; + if (CpuFeatures::IsSupported(FPU)) { + offset_to_argv += kNumCalleeSavedFPU * kDoubleSize; + } + + __ lw(s0, MemOperand(sp, offset_to_argv + + StandardFrameConstants::kCArgsSlotsSize)); // We build an EntryFrame. __ li(t3, Operand(-1)); // Push a bad frame pointer to fail if it is used. @@ -3829,6 +3840,12 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { // Reset the stack to the callee saved registers. __ addiu(sp, sp, -EntryFrameConstants::kCallerFPOffset); + if (CpuFeatures::IsSupported(FPU)) { + CpuFeatures::Scope scope(FPU); + // Restore callee-saved fpu registers. + __ MultiPopFPU(kCalleeSavedFPU); + } + // Restore callee saved registers from the stack. __ MultiPop(kCalleeSaved | ra.bit()); // Return. diff --git a/src/mips/frames-mips.h b/src/mips/frames-mips.h index 1899843a1..467eec5db 100644 --- a/src/mips/frames-mips.h +++ b/src/mips/frames-mips.h @@ -30,7 +30,6 @@ #ifndef V8_MIPS_FRAMES_MIPS_H_ #define V8_MIPS_FRAMES_MIPS_H_ - namespace v8 { namespace internal { @@ -40,13 +39,22 @@ namespace internal { static const int kNumRegs = 32; static const RegList kJSCallerSaved = - 1 << 2 | // v0 - 1 << 4 | // a0 - 1 << 5 | // a1 - 1 << 6 | // a2 - 1 << 7; // a3 - -static const int kNumJSCallerSaved = 5; + 1 << 2 | // v0 + 1 << 3 | // v1 + 1 << 4 | // a0 + 1 << 5 | // a1 + 1 << 6 | // a2 + 1 << 7 | // a3 + 1 << 8 | // t0 + 1 << 9 | // t1 + 1 << 10 | // t2 + 1 << 11 | // t3 + 1 << 12 | // t4 + 1 << 13 | // t5 + 1 << 14 | // t6 + 1 << 15; // t7 + +static const int kNumJSCallerSaved = 14; // Return the code of the n-th caller-saved register available to JavaScript @@ -56,19 +64,31 @@ int JSCallerSavedCode(int n); // Callee-saved registers preserved when switching from C to JavaScript. static const RegList kCalleeSaved = - // Saved temporaries. - 1 << 16 | 1 << 17 | 1 << 18 | 1 << 19 | - 1 << 20 | 1 << 21 | 1 << 22 | 1 << 23 | - // fp. - 1 << 30; + 1 << 16 | // s0 + 1 << 17 | // s1 + 1 << 18 | // s2 + 1 << 19 | // s3 + 1 << 20 | // s4 + 1 << 21 | // s5 + 1 << 22 | // s6 (roots in Javascript code) + 1 << 23 | // s7 (cp in Javascript code) + 1 << 30; // fp/s8 static const int kNumCalleeSaved = 9; +static const RegList kCalleeSavedFPU = + 1 << 20 | // f20 + 1 << 22 | // f22 + 1 << 24 | // f24 + 1 << 26 | // f26 + 1 << 28 | // f28 + 1 << 30; // f30 +static const int kNumCalleeSavedFPU = 6; // Number of registers for which space is reserved in safepoints. Must be a // multiple of 8. // TODO(mips): Only 8 registers may actually be sufficient. Revisit. -static const int kNumSafepointRegisters = 16; +static const int kNumSafepointRegisters = 24; // Define the list of registers actually saved at safepoints. // Note that the number of saved registers may be smaller than the reserved @@ -82,37 +102,37 @@ typedef Object* JSCallerSavedBuffer[kNumJSCallerSaved]; static const int kUndefIndex = -1; // Map with indexes on stack that corresponds to codes of saved registers. static const int kSafepointRegisterStackIndexMap[kNumRegs] = { - kUndefIndex, - kUndefIndex, - 0, // v0 - kUndefIndex, - 1, // a0 - 2, // a1 - 3, // a2 - 4, // a3 - kUndefIndex, - kUndefIndex, - kUndefIndex, - kUndefIndex, - kUndefIndex, - kUndefIndex, - kUndefIndex, - kUndefIndex, - 5, // Saved temporaries. - 6, - 7, - 8, - 9, - 10, - 11, - 12, - kUndefIndex, - kUndefIndex, - kUndefIndex, - kUndefIndex, - 13, // gp - 14, // sp - 15, // fp + kUndefIndex, // zero_reg + kUndefIndex, // at + 0, // v0 + 1, // v1 + 2, // a0 + 3, // a1 + 4, // a2 + 5, // a3 + 6, // t0 + 7, // t1 + 8, // t2 + 9, // t3 + 10, // t4 + 11, // t5 + 12, // t6 + 13, // t7 + 14, // s0 + 15, // s1 + 16, // s2 + 17, // s3 + 18, // s4 + 19, // s5 + 20, // s6 + 21, // s7 + kUndefIndex, // t8 + kUndefIndex, // t9 + kUndefIndex, // k0 + kUndefIndex, // k1 + kUndefIndex, // gp + kUndefIndex, // sp + 22, // fp kUndefIndex }; diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc index c7f727bef..45e901bdb 100644 --- a/src/mips/macro-assembler-mips.cc +++ b/src/mips/macro-assembler-mips.cc @@ -703,52 +703,114 @@ void MacroAssembler::li(Register rd, Operand j, bool gen2instr) { void MacroAssembler::MultiPush(RegList regs) { - int16_t NumSaved = 0; - int16_t NumToPush = NumberOfBitsSet(regs); + int16_t num_to_push = NumberOfBitsSet(regs); + int16_t stack_offset = num_to_push * kPointerSize; - addiu(sp, sp, -4 * NumToPush); + Subu(sp, sp, Operand(stack_offset)); for (int16_t i = kNumRegisters; i > 0; i--) { if ((regs & (1 << i)) != 0) { - sw(ToRegister(i), MemOperand(sp, 4 * (NumToPush - ++NumSaved))); + stack_offset -= kPointerSize; + sw(ToRegister(i), MemOperand(sp, stack_offset)); } } } void MacroAssembler::MultiPushReversed(RegList regs) { - int16_t NumSaved = 0; - int16_t NumToPush = NumberOfBitsSet(regs); + int16_t num_to_push = NumberOfBitsSet(regs); + int16_t stack_offset = num_to_push * kPointerSize; - addiu(sp, sp, -4 * NumToPush); + Subu(sp, sp, Operand(stack_offset)); for (int16_t i = 0; i < kNumRegisters; i++) { if ((regs & (1 << i)) != 0) { - sw(ToRegister(i), MemOperand(sp, 4 * (NumToPush - ++NumSaved))); + stack_offset -= kPointerSize; + sw(ToRegister(i), MemOperand(sp, stack_offset)); } } } void MacroAssembler::MultiPop(RegList regs) { - int16_t NumSaved = 0; + int16_t stack_offset = 0; for (int16_t i = 0; i < kNumRegisters; i++) { if ((regs & (1 << i)) != 0) { - lw(ToRegister(i), MemOperand(sp, 4 * (NumSaved++))); + lw(ToRegister(i), MemOperand(sp, stack_offset)); + stack_offset += kPointerSize; } } - addiu(sp, sp, 4 * NumSaved); + addiu(sp, sp, stack_offset); } void MacroAssembler::MultiPopReversed(RegList regs) { - int16_t NumSaved = 0; + int16_t stack_offset = 0; for (int16_t i = kNumRegisters; i > 0; i--) { if ((regs & (1 << i)) != 0) { - lw(ToRegister(i), MemOperand(sp, 4 * (NumSaved++))); + lw(ToRegister(i), MemOperand(sp, stack_offset)); + stack_offset += kPointerSize; } } - addiu(sp, sp, 4 * NumSaved); + addiu(sp, sp, stack_offset); +} + + +void MacroAssembler::MultiPushFPU(RegList regs) { + CpuFeatures::Scope scope(FPU); + int16_t num_to_push = NumberOfBitsSet(regs); + int16_t stack_offset = num_to_push * kDoubleSize; + + Subu(sp, sp, Operand(stack_offset)); + for (int16_t i = kNumRegisters; i > 0; i--) { + if ((regs & (1 << i)) != 0) { + stack_offset -= kDoubleSize; + sdc1(FPURegister::from_code(i), MemOperand(sp, stack_offset)); + } + } +} + + +void MacroAssembler::MultiPushReversedFPU(RegList regs) { + CpuFeatures::Scope scope(FPU); + int16_t num_to_push = NumberOfBitsSet(regs); + int16_t stack_offset = num_to_push * kDoubleSize; + + Subu(sp, sp, Operand(stack_offset)); + for (int16_t i = 0; i < kNumRegisters; i++) { + if ((regs & (1 << i)) != 0) { + stack_offset -= kDoubleSize; + sdc1(FPURegister::from_code(i), MemOperand(sp, stack_offset)); + } + } +} + + +void MacroAssembler::MultiPopFPU(RegList regs) { + CpuFeatures::Scope scope(FPU); + int16_t stack_offset = 0; + + for (int16_t i = 0; i < kNumRegisters; i++) { + if ((regs & (1 << i)) != 0) { + ldc1(FPURegister::from_code(i), MemOperand(sp, stack_offset)); + stack_offset += kDoubleSize; + } + } + addiu(sp, sp, stack_offset); +} + + +void MacroAssembler::MultiPopReversedFPU(RegList regs) { + CpuFeatures::Scope scope(FPU); + int16_t stack_offset = 0; + + for (int16_t i = kNumRegisters; i > 0; i--) { + if ((regs & (1 << i)) != 0) { + ldc1(FPURegister::from_code(i), MemOperand(sp, stack_offset)); + stack_offset += kDoubleSize; + } + } + addiu(sp, sp, stack_offset); } diff --git a/src/mips/macro-assembler-mips.h b/src/mips/macro-assembler-mips.h index 0fcf6f1d8..ec0b2029e 100644 --- a/src/mips/macro-assembler-mips.h +++ b/src/mips/macro-assembler-mips.h @@ -442,6 +442,9 @@ class MacroAssembler: public Assembler { void MultiPush(RegList regs); void MultiPushReversed(RegList regs); + void MultiPushFPU(RegList regs); + void MultiPushReversedFPU(RegList regs); + // Lower case push() for compatibility with arch-independent code. void push(Register src) { Addu(sp, sp, Operand(-kPointerSize)); @@ -487,6 +490,9 @@ class MacroAssembler: public Assembler { void MultiPop(RegList regs); void MultiPopReversed(RegList regs); + void MultiPopFPU(RegList regs); + void MultiPopReversedFPU(RegList regs); + // Lower case pop() for compatibility with arch-independent code. void pop(Register dst) { lw(dst, MemOperand(sp, 0));