| Index: src/arm64/simulator-arm64.cc
|
| diff --git a/src/arm64/simulator-arm64.cc b/src/arm64/simulator-arm64.cc
|
| index 8f72669f499abad6a44177a9c408c22d99c78f56..a87ca7a60ee6dbafee068073479430be8240210f 100644
|
| --- a/src/arm64/simulator-arm64.cc
|
| +++ b/src/arm64/simulator-arm64.cc
|
| @@ -15,6 +15,7 @@
|
| #include "src/disasm.h"
|
| #include "src/macro-assembler.h"
|
| #include "src/ostreams.h"
|
| +#include "src/runtime/runtime-utils.h"
|
|
|
| namespace v8 {
|
| namespace internal {
|
| @@ -533,12 +534,6 @@ void Simulator::TearDown(HashMap* i_cache, Redirection* first) {
|
| // uses the ObjectPair structure.
|
| // The simulator assumes all runtime calls return two 64-bits values. If they
|
| // don't, register x1 is clobbered. This is fine because x1 is caller-saved.
|
| -struct ObjectPair {
|
| - int64_t res0;
|
| - int64_t res1;
|
| -};
|
| -
|
| -
|
| typedef ObjectPair (*SimulatorRuntimeCall)(int64_t arg0,
|
| int64_t arg1,
|
| int64_t arg2,
|
| @@ -548,6 +543,11 @@ typedef ObjectPair (*SimulatorRuntimeCall)(int64_t arg0,
|
| int64_t arg6,
|
| int64_t arg7);
|
|
|
| +typedef ObjectTriple (*SimulatorRuntimeTripleCall)(int64_t arg0, int64_t arg1,
|
| + int64_t arg2, int64_t arg3,
|
| + int64_t arg4, int64_t arg5,
|
| + int64_t arg6, int64_t arg7);
|
| +
|
| typedef int64_t (*SimulatorRuntimeCompareCall)(double arg1, double arg2);
|
| typedef double (*SimulatorRuntimeFPFPCall)(double arg1, double arg2);
|
| typedef double (*SimulatorRuntimeFPCall)(double arg1);
|
| @@ -590,7 +590,8 @@ void Simulator::DoRuntimeCall(Instruction* instr) {
|
| break;
|
|
|
| case ExternalReference::BUILTIN_CALL: {
|
| - // Object* f(v8::internal::Arguments).
|
| + // Object* f(v8::internal::Arguments) or
|
| + // ObjectPair f(v8::internal::Arguments).
|
| TraceSim("Type: BUILTIN_CALL\n");
|
| SimulatorRuntimeCall target =
|
| reinterpret_cast<SimulatorRuntimeCall>(external);
|
| @@ -607,13 +608,41 @@ void Simulator::DoRuntimeCall(Instruction* instr) {
|
| xreg(4), xreg(5), xreg(6), xreg(7));
|
| ObjectPair result = target(xreg(0), xreg(1), xreg(2), xreg(3),
|
| xreg(4), xreg(5), xreg(6), xreg(7));
|
| - TraceSim("Returned: {0x%" PRIx64 ", 0x%" PRIx64 "}\n",
|
| - result.res0, result.res1);
|
| + TraceSim("Returned: {%p, %p}\n", result.x, result.y);
|
| +#ifdef DEBUG
|
| + CorruptAllCallerSavedCPURegisters();
|
| +#endif
|
| + set_xreg(0, reinterpret_cast<int64_t>(result.x));
|
| + set_xreg(1, reinterpret_cast<int64_t>(result.y));
|
| + break;
|
| + }
|
| +
|
| + case ExternalReference::BUILTIN_CALL_TRIPLE: {
|
| + // ObjectTriple f(v8::internal::Arguments).
|
| + TraceSim("Type: BUILTIN_CALL TRIPLE\n");
|
| + SimulatorRuntimeTripleCall target =
|
| + reinterpret_cast<SimulatorRuntimeTripleCall>(external);
|
| +
|
| + // We don't know how many arguments are being passed, but we can
|
| + // pass 8 without touching the stack. They will be ignored by the
|
| + // host function if they aren't used.
|
| + TraceSim(
|
| + "Arguments: "
|
| + "0x%016" PRIx64 ", 0x%016" PRIx64 ", "
|
| + "0x%016" PRIx64 ", 0x%016" PRIx64 ", "
|
| + "0x%016" PRIx64 ", 0x%016" PRIx64 ", "
|
| + "0x%016" PRIx64 ", 0x%016" PRIx64,
|
| + xreg(0), xreg(1), xreg(2), xreg(3), xreg(4), xreg(5), xreg(6),
|
| + xreg(7));
|
| + // Return location passed in x8.
|
| + ObjectTriple* sim_result = reinterpret_cast<ObjectTriple*>(xreg(8));
|
| + ObjectTriple result = target(xreg(0), xreg(1), xreg(2), xreg(3), xreg(4),
|
| + xreg(5), xreg(6), xreg(7));
|
| + TraceSim("Returned: {%p, %p, %p}\n", result.x, result.y, result.z);
|
| #ifdef DEBUG
|
| CorruptAllCallerSavedCPURegisters();
|
| #endif
|
| - set_xreg(0, result.res0);
|
| - set_xreg(1, result.res1);
|
| + *sim_result = result;
|
| break;
|
| }
|
|
|
|
|