Revision: 14359
Author:   [email protected]
Date:     Fri Apr 19 09:01:57 2013
Log:      RecordWriteStubs on ARM need to save FP registers

A previous change erroneously stopped saving fp registers for write stubs in
snapshotted code. This CL restores correct behavior, and makes sure code that saves fp registers checks at runtime for 16 or 32 fp registers. Also fix a bug
in the arm simulator debugger.

BUG=

Review URL: https://codereview.chromium.org/14246032
http://code.google.com/p/v8/source/detail?r=14359

Modified:
 /branches/bleeding_edge/src/arm/code-stubs-arm.cc
 /branches/bleeding_edge/src/arm/code-stubs-arm.h
 /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
 /branches/bleeding_edge/src/arm/macro-assembler-arm.cc
 /branches/bleeding_edge/src/arm/macro-assembler-arm.h
 /branches/bleeding_edge/src/arm/simulator-arm.cc

=======================================
--- /branches/bleeding_edge/src/arm/code-stubs-arm.cc Thu Apr 18 13:37:27 2013 +++ /branches/bleeding_edge/src/arm/code-stubs-arm.cc Fri Apr 19 09:01:57 2013
@@ -1651,14 +1651,7 @@
   const Register scratch = r1;

   if (save_doubles_ == kSaveFPRegs) {
- // Check CPU flags for number of registers, setting the Z condition flag.
-    __ CheckFor32DRegs(scratch);
-
-    __ sub(sp, sp, Operand(kDoubleSize * DwVfpRegister::kMaxNumRegisters));
-    for (int i = 0; i < DwVfpRegister::kMaxNumRegisters; i++) {
-      DwVfpRegister reg = DwVfpRegister::from_code(i);
-      __ vstr(reg, MemOperand(sp, i * kDoubleSize), i < 16 ? al : ne);
-    }
+    __ SaveFPRegs(sp, scratch);
   }
   const int argument_count = 1;
   const int fp_argument_count = 0;
@@ -1670,14 +1663,7 @@
       ExternalReference::store_buffer_overflow_function(masm->isolate()),
       argument_count);
   if (save_doubles_ == kSaveFPRegs) {
- // Check CPU flags for number of registers, setting the Z condition flag.
-    __ CheckFor32DRegs(scratch);
-
-    for (int i = 0; i < DwVfpRegister::kMaxNumRegisters; i++) {
-      DwVfpRegister reg = DwVfpRegister::from_code(i);
-      __ vldr(reg, MemOperand(sp, i * kDoubleSize), i < 16 ? al : ne);
-    }
-    __ add(sp, sp, Operand(kDoubleSize * DwVfpRegister::kMaxNumRegisters));
+    __ RestoreFPRegs(sp, scratch);
   }
   __ ldm(ia_w, sp, kCallerSaved | pc.bit());  // Also pop pc to get Ret(0).
 }
@@ -7194,6 +7180,9 @@
     Isolate* isolate) {
   StoreBufferOverflowStub stub1(kDontSaveFPRegs);
   stub1.GetCode(isolate)->set_is_pregenerated(true);
+  // Hydrogen code stubs need stub2 at snapshot time.
+  StoreBufferOverflowStub stub2(kSaveFPRegs);
+  stub2.GetCode(isolate)->set_is_pregenerated(true);
 }


=======================================
--- /branches/bleeding_edge/src/arm/code-stubs-arm.h Thu Apr 18 02:50:46 2013 +++ /branches/bleeding_edge/src/arm/code-stubs-arm.h Fri Apr 19 09:01:57 2013
@@ -469,34 +469,14 @@
void SaveCallerSaveRegisters(MacroAssembler* masm, SaveFPRegsMode mode) {
       masm->stm(db_w, sp, (kCallerSaved | lr.bit()) & ~scratch1_.bit());
       if (mode == kSaveFPRegs) {
-        // Number of d-regs not known at snapshot time.
-        ASSERT(!Serializer::enabled());
-        masm->sub(sp,
-                  sp,
- Operand(kDoubleSize * (DwVfpRegister::NumRegisters() - 1)));
-        // Save all VFP registers except d0.
-        // TODO(hans): We should probably save d0 too. And maybe use vstm.
-        for (int i = DwVfpRegister::NumRegisters() - 1; i > 0; i--) {
-          DwVfpRegister reg = DwVfpRegister::from_code(i);
-          masm->vstr(reg, MemOperand(sp, (i - 1) * kDoubleSize));
-        }
+        masm->SaveFPRegs(sp, scratch0_);
       }
     }

     inline void RestoreCallerSaveRegisters(MacroAssembler*masm,
                                            SaveFPRegsMode mode) {
       if (mode == kSaveFPRegs) {
-        // Number of d-regs not known at snapshot time.
-        ASSERT(!Serializer::enabled());
-        // Restore all VFP registers except d0.
- // TODO(hans): We should probably restore d0 too. And maybe use vldm.
-        for (int i = DwVfpRegister::NumRegisters() - 1; i > 0; i--) {
-          DwVfpRegister reg = DwVfpRegister::from_code(i);
-          masm->vldr(reg, MemOperand(sp, (i - 1) * kDoubleSize));
-        }
-        masm->add(sp,
-                  sp,
- Operand(kDoubleSize * (DwVfpRegister::NumRegisters() - 1)));
+        masm->RestoreFPRegs(sp, scratch0_);
       }
       masm->ldm(ia_w, sp, (kCallerSaved | lr.bit()) & ~scratch1_.bit());
     }
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Fri Apr 19 05:02:12 2013 +++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Fri Apr 19 09:01:57 2013
@@ -36,14 +36,6 @@
 namespace internal {


-static SaveFPRegsMode GetSaveFPRegsMode() {
-  // We don't need to save floating point regs when generating the snapshot
-  return CpuFeatures::IsSafeForSnapshot(VFP32DREGS)
-      ? kSaveFPRegs
-      : kDontSaveFPRegs;
-}
-
-
 class SafepointGenerator : public CallWrapper {
  public:
   SafepointGenerator(LCodeGen* codegen,
@@ -251,7 +243,7 @@
             r0,
             r3,
             GetLinkRegisterState(),
-            GetSaveFPRegsMode());
+            kSaveFPRegs);
       }
     }
     Comment(";;; End allocate local context");
@@ -3078,7 +3070,7 @@
                               value,
                               scratch,
                               GetLinkRegisterState(),
-                              GetSaveFPRegsMode(),
+                              kSaveFPRegs,
                               EMIT_REMEMBERED_SET,
                               check_needed);
   }
@@ -4267,7 +4259,7 @@
                           scratch,
                           temp,
                           GetLinkRegisterState(),
-                          GetSaveFPRegsMode(),
+                          kSaveFPRegs,
                           OMIT_REMEMBERED_SET,
                           OMIT_SMI_CHECK);
     }
@@ -4286,7 +4278,7 @@
                           value,
                           scratch,
                           GetLinkRegisterState(),
-                          GetSaveFPRegsMode(),
+                          kSaveFPRegs,
                           EMIT_REMEMBERED_SET,
                           check_needed);
     }
@@ -4301,7 +4293,7 @@
                           value,
                           object,
                           GetLinkRegisterState(),
-                          GetSaveFPRegsMode(),
+                          kSaveFPRegs,
                           EMIT_REMEMBERED_SET,
                           check_needed);
     }
@@ -4495,7 +4487,7 @@
                    key,
                    value,
                    GetLinkRegisterState(),
-                   GetSaveFPRegsMode(),
+                   kSaveFPRegs,
                    EMIT_REMEMBERED_SET,
                    check_needed);
   }
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Thu Apr 18 03:32:18 2013 +++ /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Fri Apr 19 09:01:57 2013
@@ -837,14 +837,7 @@

   // Optionally save all double registers.
   if (save_doubles) {
- // Check CPU flags for number of registers, setting the Z condition flag.
-    CheckFor32DRegs(ip);
-
-    // Push registers d0-d15, and possibly d16-d31, on the stack.
-    // If d16-d31 are not pushed, decrease the stack pointer instead.
-    vstm(db_w, sp, d16, d31, ne);
-    sub(sp, sp, Operand(16 * kDoubleSize), LeaveCC, eq);
-    vstm(db_w, sp, d0, d15);
+    SaveFPRegs(sp, ip);
     // Note that d0 will be accessible at
// fp - 2 * kPointerSize - DwVfpRegister::kMaxNumRegisters * kDoubleSize,
     // since the sp slot and code slot were pushed after the fp.
@@ -905,15 +898,7 @@
     const int offset = 2 * kPointerSize;
     sub(r3, fp,
         Operand(offset + DwVfpRegister::kMaxNumRegisters * kDoubleSize));
-
- // Check CPU flags for number of registers, setting the Z condition flag.
-    CheckFor32DRegs(ip);
-
-    // Pop registers d0-d15, and possibly d16-d31, from r3.
-    // If d16-d31 are not popped, increase r3 instead.
-    vldm(ia_w, r3, d0, d15);
-    vldm(ia_w, r3, d16, d31, ne);
-    add(r3, r3, Operand(16 * kDoubleSize), LeaveCC, eq);
+    RestoreFPRegs(r3, ip);
   }

   // Clear top frame.
@@ -3181,6 +3166,22 @@
   ldr(scratch, MemOperand(scratch));
   tst(scratch, Operand(1u << VFP32DREGS));
 }
+
+
+void MacroAssembler::SaveFPRegs(Register location, Register scratch) {
+  CheckFor32DRegs(scratch);
+  vstm(db_w, location, d16, d31, ne);
+  sub(location, location, Operand(16 * kDoubleSize), LeaveCC, eq);
+  vstm(db_w, location, d0, d15);
+}
+
+
+void MacroAssembler::RestoreFPRegs(Register location, Register scratch) {
+  CheckFor32DRegs(scratch);
+  vldm(ia_w, location, d0, d15);
+  vldm(ia_w, location, d16, d31, ne);
+  add(location, location, Operand(16 * kDoubleSize), LeaveCC, eq);
+}


 void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialAscii(
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.h Thu Apr 18 03:32:18 2013 +++ /branches/bleeding_edge/src/arm/macro-assembler-arm.h Fri Apr 19 09:01:57 2013
@@ -997,6 +997,13 @@
   // Z condition flag: Z==0 if d16-d31 available, Z==1 otherwise.
   void CheckFor32DRegs(Register scratch);

+ // Does a runtime check for 16/32 FP registers. Either way, pushes 32 double
+  // values to location, saving [d0..(d15|d31)].
+  void SaveFPRegs(Register location, Register scratch);
+
+ // Does a runtime check for 16/32 FP registers. Either way, pops 32 double
+  // values to location, restoring [d0..(d15|d31)].
+  void RestoreFPRegs(Register location, Register scratch);

// ---------------------------------------------------------------------------
   // Runtime calls
=======================================
--- /branches/bleeding_edge/src/arm/simulator-arm.cc Fri Apr 19 07:22:38 2013 +++ /branches/bleeding_edge/src/arm/simulator-arm.cc Fri Apr 19 09:01:57 2013
@@ -331,7 +331,7 @@
                 PrintF("\n");
               }
             }
-            for (int i = 0; i < kNumVFPDoubleRegisters; i++) {
+            for (int i = 0; i < DwVfpRegister::NumRegisters(); i++) {
               dvalue = GetVFPDoubleRegisterValue(i);
               uint64_t as_words = BitCast<uint64_t>(dvalue);
               PrintF("%3s: %f 0x%08x %08x\n",

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to