Index: src/ppc/simulator-ppc.cc |
diff --git a/src/ppc/simulator-ppc.cc b/src/ppc/simulator-ppc.cc |
index 75074317a6d258c1b0b60cf2336121fba3021ef9..e9c94044958c84e23de1e60664d3dc8aa49f0c9e 100644 |
--- a/src/ppc/simulator-ppc.cc |
+++ b/src/ppc/simulator-ppc.cc |
@@ -1188,17 +1188,13 @@ static void decodeObjectPair(ObjectPair* pair, intptr_t* x, intptr_t* y) { |
} |
#endif |
-// Calls into the V8 runtime are based on this very simple interface. |
-// Note: To be able to return two values from some calls the code in |
-// runtime.cc uses the ObjectPair which is essentially two pointer |
-// values stuffed into a structure. With the code below we assume that |
-// all runtime calls return this pair. If they don't, the r4 result |
-// register contains a bogus value, which is fine because it is |
-// caller-saved. |
-typedef ObjectPair (*SimulatorRuntimeCall)(intptr_t arg0, intptr_t arg1, |
- intptr_t arg2, intptr_t arg3, |
- intptr_t arg4, intptr_t arg5); |
- |
+// Calls into the V8 runtime. |
+typedef intptr_t (*SimulatorRuntimeCall)(intptr_t arg0, intptr_t arg1, |
+ intptr_t arg2, intptr_t arg3, |
+ intptr_t arg4, intptr_t arg5); |
+typedef ObjectPair (*SimulatorRuntimePairCall)(intptr_t arg0, intptr_t arg1, |
+ intptr_t arg2, intptr_t arg3, |
+ intptr_t arg4, intptr_t arg5); |
typedef ObjectTriple (*SimulatorRuntimeTripleCall)(intptr_t arg0, intptr_t arg1, |
intptr_t arg2, intptr_t arg3, |
intptr_t arg4, |
@@ -1236,7 +1232,9 @@ void Simulator::SoftwareInterrupt(Instruction* instr) { |
int arg0_regnum = 3; |
intptr_t result_buffer = 0; |
bool uses_result_buffer = |
- redirection->type() == ExternalReference::BUILTIN_CALL_TRIPLE; |
+ redirection->type() == ExternalReference::BUILTIN_CALL_TRIPLE || |
+ (redirection->type() == ExternalReference::BUILTIN_CALL_PAIR && |
+ !ABI_RETURNS_OBJECT_PAIRS_IN_REGS); |
if (uses_result_buffer) { |
result_buffer = get_register(r3); |
arg0_regnum++; |
@@ -1443,19 +1441,36 @@ void Simulator::SoftwareInterrupt(Instruction* instr) { |
sizeof(ObjectTriple)); |
set_register(r3, result_buffer); |
} else { |
- DCHECK(redirection->type() == ExternalReference::BUILTIN_CALL); |
- SimulatorRuntimeCall target = |
- reinterpret_cast<SimulatorRuntimeCall>(external); |
- ObjectPair result = |
- target(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]); |
- intptr_t x; |
- intptr_t y; |
- decodeObjectPair(&result, &x, &y); |
- if (::v8::internal::FLAG_trace_sim) { |
- PrintF("Returned {%08" V8PRIxPTR ", %08" V8PRIxPTR "}\n", x, y); |
+ if (redirection->type() == ExternalReference::BUILTIN_CALL_PAIR) { |
+ SimulatorRuntimePairCall target = |
+ reinterpret_cast<SimulatorRuntimePairCall>(external); |
+ ObjectPair result = |
+ target(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]); |
+ intptr_t x; |
+ intptr_t y; |
+ decodeObjectPair(&result, &x, &y); |
+ if (::v8::internal::FLAG_trace_sim) { |
+ PrintF("Returned {%08" V8PRIxPTR ", %08" V8PRIxPTR "}\n", x, y); |
+ } |
+ if (ABI_RETURNS_OBJECT_PAIRS_IN_REGS) { |
+ set_register(r3, x); |
+ set_register(r4, y); |
+ } else { |
+ memcpy(reinterpret_cast<void*>(result_buffer), &result, |
+ sizeof(ObjectPair)); |
+ set_register(r3, result_buffer); |
+ } |
+ } else { |
+ DCHECK(redirection->type() == ExternalReference::BUILTIN_CALL); |
+ SimulatorRuntimeCall target = |
+ reinterpret_cast<SimulatorRuntimeCall>(external); |
+ intptr_t result = |
+ target(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]); |
+ if (::v8::internal::FLAG_trace_sim) { |
+ PrintF("Returned %08" V8PRIxPTR "\n", result); |
+ } |
+ set_register(r3, result); |
} |
- set_register(r3, x); |
- set_register(r4, y); |
} |
} |
set_pc(saved_lr); |