Index: src/mips/simulator-mips.cc |
diff --git a/src/mips/simulator-mips.cc b/src/mips/simulator-mips.cc |
index cb5647332a2cee6336c47411a21c7944e94cebe5..ea359eadea789b51cb166f9b52edc347a52089a1 100644 |
--- a/src/mips/simulator-mips.cc |
+++ b/src/mips/simulator-mips.cc |
@@ -1016,6 +1016,13 @@ void Simulator::set_register(int reg, int32_t value) { |
} |
+void Simulator::set_dw_register(int reg, const int* dbl) { |
+ ASSERT((reg >= 0) && (reg < kNumSimuRegisters)); |
+ registers_[reg] = dbl[0]; |
+ registers_[reg + 1] = dbl[1]; |
+} |
+ |
+ |
void Simulator::set_fpu_register(int fpureg, int32_t value) { |
ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
FPUregisters_[fpureg] = value; |
@@ -1045,6 +1052,19 @@ int32_t Simulator::get_register(int reg) const { |
} |
+double Simulator::get_double_from_register_pair(int reg) { |
+ ASSERT((reg >= 0) && (reg < kNumSimuRegisters) && ((reg % 2) == 0)); |
+ |
+ double dm_val = 0.0; |
+ // Read the bits from the unsigned integer register_[] array |
+ // into the double precision floating point value and return it. |
+ char buffer[2 * sizeof(registers_[0])]; |
+ memcpy(buffer, ®isters_[reg], 2 * sizeof(registers_[0])); |
+ memcpy(&dm_val, buffer, 2 * sizeof(registers_[0])); |
+ return(dm_val); |
+} |
+ |
+ |
int32_t Simulator::get_fpu_register(int fpureg) const { |
ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
return FPUregisters_[fpureg]; |
@@ -2718,34 +2738,7 @@ void Simulator::Execute() { |
} |
-int32_t Simulator::Call(byte* entry, int argument_count, ...) { |
- va_list parameters; |
- va_start(parameters, argument_count); |
- // Set up arguments. |
- |
- // First four arguments passed in registers. |
- ASSERT(argument_count >= 4); |
- set_register(a0, va_arg(parameters, int32_t)); |
- set_register(a1, va_arg(parameters, int32_t)); |
- set_register(a2, va_arg(parameters, int32_t)); |
- set_register(a3, va_arg(parameters, int32_t)); |
- |
- // Remaining arguments passed on stack. |
- int original_stack = get_register(sp); |
- // Compute position of stack on entry to generated code. |
- int entry_stack = (original_stack - (argument_count - 4) * sizeof(int32_t) |
- - kCArgsSlotsSize); |
- if (OS::ActivationFrameAlignment() != 0) { |
- entry_stack &= -OS::ActivationFrameAlignment(); |
- } |
- // Store remaining arguments on stack, from low to high memory. |
- intptr_t* stack_argument = reinterpret_cast<intptr_t*>(entry_stack); |
- for (int i = 4; i < argument_count; i++) { |
- stack_argument[i - 4 + kCArgSlotCount] = va_arg(parameters, int32_t); |
- } |
- va_end(parameters); |
- set_register(sp, entry_stack); |
- |
+void Simulator::CallInternal(byte* entry) { |
// Prepare to execute the code at entry. |
set_register(pc, reinterpret_cast<int32_t>(entry)); |
// Put down marker for end of simulation. The simulator will stop simulation |
@@ -2809,6 +2802,38 @@ int32_t Simulator::Call(byte* entry, int argument_count, ...) { |
set_register(gp, gp_val); |
set_register(sp, sp_val); |
set_register(fp, fp_val); |
+} |
+ |
+ |
+int32_t Simulator::Call(byte* entry, int argument_count, ...) { |
+ va_list parameters; |
+ va_start(parameters, argument_count); |
+ // Set up arguments. |
+ |
+ // First four arguments passed in registers. |
+ ASSERT(argument_count >= 4); |
+ set_register(a0, va_arg(parameters, int32_t)); |
+ set_register(a1, va_arg(parameters, int32_t)); |
+ set_register(a2, va_arg(parameters, int32_t)); |
+ set_register(a3, va_arg(parameters, int32_t)); |
+ |
+ // Remaining arguments passed on stack. |
+ int original_stack = get_register(sp); |
+ // Compute position of stack on entry to generated code. |
+ int entry_stack = (original_stack - (argument_count - 4) * sizeof(int32_t) |
+ - kCArgsSlotsSize); |
+ if (OS::ActivationFrameAlignment() != 0) { |
+ entry_stack &= -OS::ActivationFrameAlignment(); |
+ } |
+ // Store remaining arguments on stack, from low to high memory. |
+ intptr_t* stack_argument = reinterpret_cast<intptr_t*>(entry_stack); |
+ for (int i = 4; i < argument_count; i++) { |
+ stack_argument[i - 4 + kCArgSlotCount] = va_arg(parameters, int32_t); |
+ } |
+ va_end(parameters); |
+ set_register(sp, entry_stack); |
+ |
+ CallInternal(entry); |
// Pop stack passed arguments. |
CHECK_EQ(entry_stack, get_register(sp)); |
@@ -2819,6 +2844,27 @@ int32_t Simulator::Call(byte* entry, int argument_count, ...) { |
} |
+double Simulator::CallFP(byte* entry, double d0, double d1) { |
+ if (!IsMipsSoftFloatABI) { |
+ set_fpu_register_double(f12, d0); |
+ set_fpu_register_double(f14, d1); |
+ } else { |
+ int buffer[2]; |
+ ASSERT(sizeof(buffer[0]) * 2 == sizeof(d0)); |
+ memcpy(buffer, &d0, sizeof(d0)); |
+ set_dw_register(a0, buffer); |
+ memcpy(buffer, &d1, sizeof(d1)); |
+ set_dw_register(a2, buffer); |
+ } |
+ CallInternal(entry); |
+ if (!IsMipsSoftFloatABI) { |
+ return get_fpu_register_double(f0); |
+ } else { |
+ return get_double_from_register_pair(v0); |
+ } |
+} |
+ |
+ |
uintptr_t Simulator::PushAddress(uintptr_t address) { |
int new_sp = get_register(sp) - sizeof(uintptr_t); |
uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(new_sp); |