Commit d586e9c5 authored by yangguo@chromium.org's avatar yangguo@chromium.org

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
parent c657d440
......@@ -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.
......
......@@ -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
};
......
......@@ -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);
}
......
......@@ -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));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment