Index: src/arm/simulator-arm.cc |
diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc |
index 036fd7f877616df84928f0429d14d7d6cb4817cd..af65bc70bd247368ecfc61d6c06c1333dd7ce2f0 100644 |
--- a/src/arm/simulator-arm.cc |
+++ b/src/arm/simulator-arm.cc |
@@ -975,12 +975,14 @@ ReturnType Simulator::GetFromVFPRegister(int reg_index) { |
} |
-// For use in calls that take two double values, constructed either |
+// 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. |
-void Simulator::GetFpArgs(double* x, double* y) { |
+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]; |
} else { |
// We use a char buffer to get around the strict-aliasing rules which |
// otherwise allow the compiler to optimize away the copy. |
@@ -988,44 +990,12 @@ void Simulator::GetFpArgs(double* x, double* y) { |
// Registers 0 and 1 -> x. |
OS::MemCopy(buffer, registers_, sizeof(*x)); |
OS::MemCopy(x, buffer, sizeof(*x)); |
- // Registers 2 and 3 -> y. |
- OS::MemCopy(buffer, registers_ + 2, sizeof(*y)); |
- OS::MemCopy(y, buffer, sizeof(*y)); |
- } |
-} |
- |
-// For use in calls that take one double value, constructed either |
-// from r0 and r1 or d0. |
-void Simulator::GetFpArgs(double* x) { |
- if (use_eabi_hardfloat()) { |
- *x = vfp_registers_[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)); |
- } |
-} |
- |
- |
-// For use in calls that take one double value constructed either |
-// from r0 and r1 or d0 and one integer value. |
-void Simulator::GetFpArgs(double* x, int32_t* y) { |
- if (use_eabi_hardfloat()) { |
- *x = vfp_registers_[0]; |
- *y = registers_[1]; |
- } 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)); |
- // Register 2 -> y. |
+ // Register 2 and 3 -> y. |
OS::MemCopy(buffer, registers_ + 2, sizeof(*y)); |
OS::MemCopy(y, buffer, sizeof(*y)); |
+ // Register 2 -> z |
+ memcpy(buffer, registers_ + 2, sizeof(*z)); |
+ memcpy(z, buffer, sizeof(*z)); |
} |
} |
@@ -1648,10 +1618,12 @@ typedef int64_t (*SimulatorRuntimeCall)(int32_t arg0, |
int32_t arg3, |
int32_t arg4, |
int32_t arg5); |
-typedef double (*SimulatorRuntimeFPCall)(int32_t arg0, |
- int32_t arg1, |
- int32_t arg2, |
- int32_t arg3); |
+ |
+// These prototypes handle the four types of FP calls. |
+typedef int64_t (*SimulatorRuntimeCompareCall)(double darg0, double darg1); |
+typedef double (*SimulatorRuntimeFPFPCall)(double darg0, double darg1); |
+typedef double (*SimulatorRuntimeFPCall)(double darg0); |
+typedef double (*SimulatorRuntimeFPIntCall)(double darg0, int32_t arg0); |
// This signature supports direct call in to API function native callback |
// (refer to InvocationCallback in v8.h). |
@@ -1717,27 +1689,27 @@ void Simulator::SoftwareInterrupt(Instruction* instr) { |
intptr_t external = |
reinterpret_cast<intptr_t>(redirection->external_function()); |
if (fp_call) { |
+ double dval0, dval1; // one or two double parameters |
+ int32_t ival; // zero or one integer parameters |
+ int64_t iresult = 0; // integer return value |
+ double dresult = 0; // double return value |
+ GetFpArgs(&dval0, &dval1, &ival); |
if (::v8::internal::FLAG_trace_sim || !stack_aligned) { |
- SimulatorRuntimeFPCall target = |
- reinterpret_cast<SimulatorRuntimeFPCall>(external); |
- double dval0, dval1; |
- int32_t ival; |
+ SimulatorRuntimeCall generic_target = |
+ reinterpret_cast<SimulatorRuntimeCall>(external); |
switch (redirection->type()) { |
case ExternalReference::BUILTIN_FP_FP_CALL: |
case ExternalReference::BUILTIN_COMPARE_CALL: |
- GetFpArgs(&dval0, &dval1); |
PrintF("Call to host function at %p with args %f, %f", |
- FUNCTION_ADDR(target), dval0, dval1); |
+ FUNCTION_ADDR(generic_target), dval0, dval1); |
break; |
case ExternalReference::BUILTIN_FP_CALL: |
- GetFpArgs(&dval0); |
PrintF("Call to host function at %p with arg %f", |
- FUNCTION_ADDR(target), dval0); |
+ FUNCTION_ADDR(generic_target), dval0); |
break; |
case ExternalReference::BUILTIN_FP_INT_CALL: |
- GetFpArgs(&dval0, &ival); |
PrintF("Call to host function at %p with args %f, %d", |
- FUNCTION_ADDR(target), dval0, ival); |
+ FUNCTION_ADDR(generic_target), dval0, ival); |
break; |
default: |
UNREACHABLE(); |
@@ -1749,22 +1721,54 @@ void Simulator::SoftwareInterrupt(Instruction* instr) { |
PrintF("\n"); |
} |
CHECK(stack_aligned); |
- if (redirection->type() != ExternalReference::BUILTIN_COMPARE_CALL) { |
+ switch (redirection->type()) { |
+ case ExternalReference::BUILTIN_COMPARE_CALL: { |
+ SimulatorRuntimeCompareCall target = |
+ reinterpret_cast<SimulatorRuntimeCompareCall>(external); |
+ iresult = target(dval0, dval1); |
+ set_register(r0, static_cast<int32_t>(iresult)); |
+ set_register(r1, static_cast<int32_t>(iresult >> 32)); |
+ break; |
+ } |
+ case ExternalReference::BUILTIN_FP_FP_CALL: { |
+ SimulatorRuntimeFPFPCall target = |
+ reinterpret_cast<SimulatorRuntimeFPFPCall>(external); |
+ dresult = target(dval0, dval1); |
+ SetFpResult(dresult); |
+ break; |
+ } |
+ case ExternalReference::BUILTIN_FP_CALL: { |
SimulatorRuntimeFPCall target = |
- reinterpret_cast<SimulatorRuntimeFPCall>(external); |
- double result = target(arg0, arg1, arg2, arg3); |
- SetFpResult(result); |
- } else { |
- SimulatorRuntimeCall target = |
- reinterpret_cast<SimulatorRuntimeCall>(external); |
- int64_t result = target(arg0, arg1, arg2, arg3, arg4, arg5); |
- int32_t lo_res = static_cast<int32_t>(result); |
- int32_t hi_res = static_cast<int32_t>(result >> 32); |
- if (::v8::internal::FLAG_trace_sim) { |
- PrintF("Returned %08x\n", lo_res); |
+ reinterpret_cast<SimulatorRuntimeFPCall>(external); |
+ dresult = target(dval0); |
+ SetFpResult(dresult); |
+ break; |
+ } |
+ case ExternalReference::BUILTIN_FP_INT_CALL: { |
+ SimulatorRuntimeFPIntCall target = |
+ reinterpret_cast<SimulatorRuntimeFPIntCall>(external); |
+ dresult = target(dval0, ival); |
+ SetFpResult(dresult); |
+ break; |
+ } |
+ default: |
+ UNREACHABLE(); |
+ break; |
+ } |
+ if (::v8::internal::FLAG_trace_sim || !stack_aligned) { |
+ switch (redirection->type()) { |
+ case ExternalReference::BUILTIN_COMPARE_CALL: |
+ PrintF("Returned %08x\n", static_cast<int32_t>(iresult)); |
+ break; |
+ case ExternalReference::BUILTIN_FP_FP_CALL: |
+ case ExternalReference::BUILTIN_FP_CALL: |
+ case ExternalReference::BUILTIN_FP_INT_CALL: |
+ PrintF("Returned %f\n", dresult); |
+ break; |
+ default: |
+ UNREACHABLE(); |
+ break; |
} |
- set_register(r0, lo_res); |
- set_register(r1, hi_res); |
} |
} else if (redirection->type() == ExternalReference::DIRECT_API_CALL) { |
SimulatorRuntimeDirectApiCall target = |