ARM: Fix simulator when using hard floating point ABI.
BUG=none TEST=make arm.release.check armfloatabi=hard R=ulan@chromium.org Review URL: https://codereview.chromium.org/23496062 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16794 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
ff2719a075
commit
86e3d4ae56
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user