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