Reviewers: ulan, Benedikt Meurer,

Description:
ARM: Fix simulator when using hard floating point ABI.

BUG=none
TEST=make arm.release.check armfloatabi=hard

Please review this at https://codereview.chromium.org/23496062/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files (+41, -51 lines):
  M src/arm/codegen-arm.cc
  M src/arm/simulator-arm.h
  M src/arm/simulator-arm.cc
  M test/cctest/test-code-stubs-arm.cc


Index: src/arm/codegen-arm.cc
diff --git a/src/arm/codegen-arm.cc b/src/arm/codegen-arm.cc
index 732d9f3060e6b1da24a760132370cd379dbc7578..5b80d6facc5ea8e4a0b2fb6fcf985a83bdbc1cba 100644
--- a/src/arm/codegen-arm.cc
+++ b/src/arm/codegen-arm.cc
@@ -55,7 +55,7 @@ UnaryMathFunction CreateTranscendentalFunction(TranscendentalCache::Type type) {
 #if defined(USE_SIMULATOR)
 byte* fast_exp_arm_machine_code = NULL;
 double fast_exp_simulator(double x) {
-  return Simulator::current(Isolate::Current())->CallFP(
+  return Simulator::current(Isolate::Current())->CallFPReturnsDouble(
       fast_exp_arm_machine_code, x, 0);
 }
 #endif
Index: src/arm/simulator-arm.cc
diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc
index def18186305f102da97890f23af79d7facc14bdf..461d032b99f56171bb41eec2997de9f34fddb7d5 100644
--- a/src/arm/simulator-arm.cc
+++ b/src/arm/simulator-arm.cc
@@ -912,6 +912,12 @@ double Simulator::get_double_from_register_pair(int reg) {
 }


+void Simulator::set_register_pair_from_double(int reg, double* value) {
+  ASSERT((reg >= 0) && (reg < num_registers) && ((reg % 2) == 0));
+  memcpy(registers_ + reg, value, sizeof(*value));
+}
+
+
 void Simulator::set_dw_register(int dreg, const int* dbl) {
   ASSERT((dreg >= 0) && (dreg < num_d_registers));
   registers_[dreg] = dbl[0];
@@ -1026,27 +1032,22 @@ ReturnType Simulator::GetFromVFPRegister(int reg_index) {
 }


-// Runtime FP routines take up to two double arguments and zero
-// or one integer arguments. All are consructed here.
-// from r0-r3 or d0 and d1.
+// Runtime FP routines take:
+// - two double arguments
+// - one double argument and zero or one integer arguments.
+// All are consructed here from r0-r3 or d0, d1 and r0.
 void Simulator::GetFpArgs(double* x, double* y, int32_t* z) {
   if (use_eabi_hardfloat()) {
-    *x = vfp_registers_[0];
-    *y = vfp_registers_[1];
-    *z = registers_[1];
+    *x = get_double_from_d_register(0);
+    *y = get_double_from_d_register(1);
+    *z = get_register(0);
   } else {
-    // We use a char buffer to get around the strict-aliasing rules which
-    // otherwise allow the compiler to optimize away the copy.
-    char buffer[sizeof(*x)];
     // Registers 0 and 1 -> x.
-    OS::MemCopy(buffer, registers_, sizeof(*x));
-    OS::MemCopy(x, buffer, sizeof(*x));
+    *x = get_double_from_register_pair(0);
     // Register 2 and 3 -> y.
-    OS::MemCopy(buffer, registers_ + 2, sizeof(*y));
-    OS::MemCopy(y, buffer, sizeof(*y));
+    *y = get_double_from_register_pair(2);
     // Register 2 -> z
-    memcpy(buffer, registers_ + 2, sizeof(*z));
-    memcpy(z, buffer, sizeof(*z));
+    *z = get_register(2);
   }
 }

@@ -1718,32 +1719,6 @@ void Simulator::SoftwareInterrupt(Instruction* instr) { (redirection->type() == ExternalReference::BUILTIN_COMPARE_CALL) | |
          (redirection->type() == ExternalReference::BUILTIN_FP_CALL) ||
          (redirection->type() == ExternalReference::BUILTIN_FP_INT_CALL);
-      if (use_eabi_hardfloat()) {
-        // With the hard floating point calling convention, double
-        // arguments are passed in VFP registers. Fetch the arguments
-        // from there and call the builtin using soft floating point
-        // convention.
-        switch (redirection->type()) {
-        case ExternalReference::BUILTIN_FP_FP_CALL:
-        case ExternalReference::BUILTIN_COMPARE_CALL:
-          arg0 = vfp_registers_[0];
-          arg1 = vfp_registers_[1];
-          arg2 = vfp_registers_[2];
-          arg3 = vfp_registers_[3];
-          break;
-        case ExternalReference::BUILTIN_FP_CALL:
-          arg0 = vfp_registers_[0];
-          arg1 = vfp_registers_[1];
-          break;
-        case ExternalReference::BUILTIN_FP_INT_CALL:
-          arg0 = vfp_registers_[0];
-          arg1 = vfp_registers_[1];
-          arg2 = get_register(0);
-          break;
-        default:
-          break;
-        }
-      }
// This is dodgy but it works because the C entry stubs are never moved.
       // See comment in codegen-arm.cc and bug 1242173.
       int32_t saved_lr = get_register(lr);
@@ -3816,19 +3791,27 @@ int32_t Simulator::Call(byte* entry, int argument_count, ...) {
 }


-double Simulator::CallFP(byte* entry, double d0, double d1) {
+void Simulator::CallFP(byte* entry, double d0, double d1) {
   if (use_eabi_hardfloat()) {
     set_d_register_from_double(0, d0);
     set_d_register_from_double(1, d1);
   } else {
-    int buffer[2];
-    ASSERT(sizeof(buffer[0]) * 2 == sizeof(d0));
-    OS::MemCopy(buffer, &d0, sizeof(d0));
-    set_dw_register(0, buffer);
-    OS::MemCopy(buffer, &d1, sizeof(d1));
-    set_dw_register(2, buffer);
+    set_register_pair_from_double(0, &d0);
+    set_register_pair_from_double(2, &d1);
   }
   CallInternal(entry);
+}
+
+
+int32_t Simulator::CallFPReturnsInt(byte* entry, double d0, double d1) {
+  CallFP(entry, d0, d1);
+  int32_t result = get_register(r0);
+  return result;
+}
+
+
+double Simulator::CallFPReturnsDouble(byte* entry, double d0, double d1) {
+  CallFP(entry, d0, d1);
   if (use_eabi_hardfloat()) {
     return get_double_from_d_register(0);
   } else {
Index: src/arm/simulator-arm.h
diff --git a/src/arm/simulator-arm.h b/src/arm/simulator-arm.h
index 7fca7432bf704c143138d633e374370986d5bee8..e392c5cb3637045e7ab43613ad1675a5e82db01b 100644
--- a/src/arm/simulator-arm.h
+++ b/src/arm/simulator-arm.h
@@ -163,6 +163,7 @@ class Simulator {
   void set_register(int reg, int32_t value);
   int32_t get_register(int reg) const;
   double get_double_from_register_pair(int reg);
+  void set_register_pair_from_double(int reg, double* value);
   void set_dw_register(int dreg, const int* dbl);

   // Support for VFP.
@@ -220,7 +221,9 @@ class Simulator {
   // which sets up the simulator state and grabs the result on return.
   int32_t Call(byte* entry, int argument_count, ...);
   // Alternative: call a 2-argument double function.
-  double CallFP(byte* entry, double d0, double d1);
+  void CallFP(byte* entry, double d0, double d1);
+  int32_t CallFPReturnsInt(byte* entry, double d0, double d1);
+  double CallFPReturnsDouble(byte* entry, double d0, double d1);

   // Push an address onto the JS stack.
   uintptr_t PushAddress(uintptr_t address);
@@ -444,6 +447,10 @@ class Simulator {
   reinterpret_cast<Object*>(Simulator::current(Isolate::Current())->Call( \
       FUNCTION_ADDR(entry), 5, p0, p1, p2, p3, p4))

+#define CALL_GENERATED_FP_INT(entry, p0, p1) \
+  Simulator::current(Isolate::Current())->CallFPReturnsInt( \
+      FUNCTION_ADDR(entry), p0, p1)
+
#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7, p8) \
   Simulator::current(Isolate::Current())->Call( \
       entry, 10, p0, p1, p2, p3, NULL, p4, p5, p6, p7, p8)
Index: test/cctest/test-code-stubs-arm.cc
diff --git a/test/cctest/test-code-stubs-arm.cc b/test/cctest/test-code-stubs-arm.cc index c99433edad4c281b3a1c2b2e5b14dd772567c432..54eaa58318f823a85fe2a6a4cb363e7a8f10793d 100644
--- a/test/cctest/test-code-stubs-arm.cc
+++ b/test/cctest/test-code-stubs-arm.cc
@@ -143,7 +143,7 @@ static Isolate* GetIsolateFrom(LocalContext* context) {
 int32_t RunGeneratedCodeCallWrapper(ConvertDToIFunc func,
                                     double from) {
 #ifdef USE_SIMULATOR
- return reinterpret_cast<int32_t>(CALL_GENERATED_CODE(func, from, 0, 0, 0, 0));
+  return CALL_GENERATED_FP_INT(func, from, 0);
 #else
   return (*func)(from);
 #endif


--
--
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