Commit 433e8848 authored by mbrandy's avatar mbrandy Committed by Commit bot

Introduce BUILTIN_CALL_PAIR.

This change allows the PPC simulator to execute on PPC hardware where,
due to calling conventions, we must distinguish between Object* and
ObjectPair return values.

We find this useful as another available option for debugging certain
problems.  While not strictly necessary for Intel platforms, we hope
that this is less offensive now that BUILTIN_CALL_TRIPLE has been
added.

BUG=
R=rmcilroy@chromium.org, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com

Review URL: https://codereview.chromium.org/1604653006

Cr-Commit-Position: refs/heads/master@{#33475}
parent 00b0a536
...@@ -1933,7 +1933,8 @@ void Simulator::SoftwareInterrupt(Instruction* instr) { ...@@ -1933,7 +1933,8 @@ void Simulator::SoftwareInterrupt(Instruction* instr) {
set_register(r0, arg0); set_register(r0, arg0);
} else { } else {
// builtin call. // builtin call.
DCHECK(redirection->type() == ExternalReference::BUILTIN_CALL); DCHECK(redirection->type() == ExternalReference::BUILTIN_CALL ||
redirection->type() == ExternalReference::BUILTIN_CALL_PAIR);
SimulatorRuntimeCall target = SimulatorRuntimeCall target =
reinterpret_cast<SimulatorRuntimeCall>(external); reinterpret_cast<SimulatorRuntimeCall>(external);
if (::v8::internal::FLAG_trace_sim || !stack_aligned) { if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
......
...@@ -589,7 +589,8 @@ void Simulator::DoRuntimeCall(Instruction* instr) { ...@@ -589,7 +589,8 @@ void Simulator::DoRuntimeCall(Instruction* instr) {
UNREACHABLE(); UNREACHABLE();
break; break;
case ExternalReference::BUILTIN_CALL: { case ExternalReference::BUILTIN_CALL:
case ExternalReference::BUILTIN_CALL_PAIR: {
// Object* f(v8::internal::Arguments) or // Object* f(v8::internal::Arguments) or
// ObjectPair f(v8::internal::Arguments). // ObjectPair f(v8::internal::Arguments).
TraceSim("Type: BUILTIN_CALL\n"); TraceSim("Type: BUILTIN_CALL\n");
......
...@@ -942,6 +942,20 @@ void RelocInfo::Verify(Isolate* isolate) { ...@@ -942,6 +942,20 @@ void RelocInfo::Verify(Isolate* isolate) {
// Implementation of ExternalReference // Implementation of ExternalReference
static ExternalReference::Type BuiltinCallTypeForResultSize(int result_size) {
switch (result_size) {
case 1:
return ExternalReference::BUILTIN_CALL;
case 2:
return ExternalReference::BUILTIN_CALL_PAIR;
case 3:
return ExternalReference::BUILTIN_CALL_TRIPLE;
}
UNREACHABLE();
return ExternalReference::BUILTIN_CALL;
}
void ExternalReference::SetUp() { void ExternalReference::SetUp() {
double_constants.min_int = kMinInt; double_constants.min_int = kMinInt;
double_constants.one_half = 0.5; double_constants.one_half = 0.5;
...@@ -1029,9 +1043,8 @@ ExternalReference::ExternalReference(Runtime::FunctionId id, Isolate* isolate) ...@@ -1029,9 +1043,8 @@ ExternalReference::ExternalReference(Runtime::FunctionId id, Isolate* isolate)
ExternalReference::ExternalReference(const Runtime::Function* f, ExternalReference::ExternalReference(const Runtime::Function* f,
Isolate* isolate) Isolate* isolate)
: address_(Redirect(isolate, f->entry, f->result_size == 3 : address_(Redirect(isolate, f->entry,
? BUILTIN_CALL_TRIPLE BuiltinCallTypeForResultSize(f->result_size))) {}
: BUILTIN_CALL)) {}
ExternalReference ExternalReference::isolate_address(Isolate* isolate) { ExternalReference ExternalReference::isolate_address(Isolate* isolate) {
......
...@@ -814,10 +814,13 @@ class ExternalReference BASE_EMBEDDED { ...@@ -814,10 +814,13 @@ class ExternalReference BASE_EMBEDDED {
// Used in the simulator to support different native api calls. // Used in the simulator to support different native api calls.
enum Type { enum Type {
// Builtin call. // Builtin call.
// Object* f(v8::internal::Arguments) or // Object* f(v8::internal::Arguments).
// ObjectPair f(v8::internal::Arguments).
BUILTIN_CALL, // default BUILTIN_CALL, // default
// Builtin call returning object pair.
// ObjectPair f(v8::internal::Arguments).
BUILTIN_CALL_PAIR,
// Builtin call that returns . // Builtin call that returns .
// ObjectTriple f(v8::internal::Arguments). // ObjectTriple f(v8::internal::Arguments).
BUILTIN_CALL_TRIPLE, BUILTIN_CALL_TRIPLE,
......
...@@ -1205,17 +1205,13 @@ static void decodeObjectPair(ObjectPair* pair, intptr_t* x, intptr_t* y) { ...@@ -1205,17 +1205,13 @@ static void decodeObjectPair(ObjectPair* pair, intptr_t* x, intptr_t* y) {
} }
#endif #endif
// Calls into the V8 runtime are based on this very simple interface. // Calls into the V8 runtime.
// Note: To be able to return two values from some calls the code in typedef intptr_t (*SimulatorRuntimeCall)(intptr_t arg0, intptr_t arg1,
// runtime.cc uses the ObjectPair which is essentially two pointer intptr_t arg2, intptr_t arg3,
// values stuffed into a structure. With the code below we assume that intptr_t arg4, intptr_t arg5);
// all runtime calls return this pair. If they don't, the r4 result typedef ObjectPair (*SimulatorRuntimePairCall)(intptr_t arg0, intptr_t arg1,
// register contains a bogus value, which is fine because it is intptr_t arg2, intptr_t arg3,
// caller-saved. intptr_t arg4, intptr_t arg5);
typedef ObjectPair (*SimulatorRuntimeCall)(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, typedef ObjectTriple (*SimulatorRuntimeTripleCall)(intptr_t arg0, intptr_t arg1,
intptr_t arg2, intptr_t arg3, intptr_t arg2, intptr_t arg3,
intptr_t arg4, intptr_t arg4,
...@@ -1253,7 +1249,9 @@ void Simulator::SoftwareInterrupt(Instruction* instr) { ...@@ -1253,7 +1249,9 @@ void Simulator::SoftwareInterrupt(Instruction* instr) {
int arg0_regnum = 3; int arg0_regnum = 3;
intptr_t result_buffer = 0; intptr_t result_buffer = 0;
bool uses_result_buffer = 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) { if (uses_result_buffer) {
result_buffer = get_register(r3); result_buffer = get_register(r3);
arg0_regnum++; arg0_regnum++;
...@@ -1460,19 +1458,36 @@ void Simulator::SoftwareInterrupt(Instruction* instr) { ...@@ -1460,19 +1458,36 @@ void Simulator::SoftwareInterrupt(Instruction* instr) {
sizeof(ObjectTriple)); sizeof(ObjectTriple));
set_register(r3, result_buffer); set_register(r3, result_buffer);
} else { } else {
DCHECK(redirection->type() == ExternalReference::BUILTIN_CALL); if (redirection->type() == ExternalReference::BUILTIN_CALL_PAIR) {
SimulatorRuntimeCall target = SimulatorRuntimePairCall target =
reinterpret_cast<SimulatorRuntimeCall>(external); reinterpret_cast<SimulatorRuntimePairCall>(external);
ObjectPair result = ObjectPair result =
target(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]); target(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]);
intptr_t x; intptr_t x;
intptr_t y; intptr_t y;
decodeObjectPair(&result, &x, &y); decodeObjectPair(&result, &x, &y);
if (::v8::internal::FLAG_trace_sim) { if (::v8::internal::FLAG_trace_sim) {
PrintF("Returned {%08" V8PRIxPTR ", %08" V8PRIxPTR "}\n", x, y); 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); set_pc(saved_lr);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment