MIPS: port ARM: Fix context save/restore for VFP registers.
authoryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 1 Sep 2011 07:35:33 +0000 (07:35 +0000)
committeryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 1 Sep 2011 07:35:33 +0000 (07:35 +0000)
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

src/mips/code-stubs-mips.cc
src/mips/frames-mips.h
src/mips/macro-assembler-mips.cc
src/mips/macro-assembler-mips.h

index 9385f2f..7c2a146 100644 (file)
@@ -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.
index 1899843..467eec5 100644 (file)
@@ -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
 };
 
index c7f727b..45e901b 100644 (file)
@@ -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);
 }
 
 
index 0fcf6f1..ec0b202 100644 (file)
@@ -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));