Commit 4de20cb1 authored by Maya Lekova's avatar Maya Lekova Committed by V8 LUCI CQ

[arm] Increase the number of args supported by the simulator to 20

This CL adds a minor change to the arm/arm64 simulators to support up to
20 arguments in a C function call. This change is necessary for an
upcoming CL which adds float support to the simulator and tests with
more than 20 arguments, see
https://chromium-review.googlesource.com/c/v8/v8/+/3060486

Bug: chromium:1052746
Change-Id: I60ae603c96554525d28f1cd248d7766f86c9cc3e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3256785
Commit-Queue: Maya Lekova <mslekova@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/main@{#77651}
parent 2179ac84
...@@ -78,7 +78,7 @@ namespace internal { ...@@ -78,7 +78,7 @@ namespace internal {
// defines a limit of 256 parameters but in simulator builds we provide only // defines a limit of 256 parameters but in simulator builds we provide only
// limited support. // limited support.
#ifdef USE_SIMULATOR #ifdef USE_SIMULATOR
static constexpr int kMaxCParameters = 10; static constexpr int kMaxCParameters = 20;
#else #else
static constexpr int kMaxCParameters = 256; static constexpr int kMaxCParameters = 256;
#endif #endif
......
...@@ -1595,11 +1595,11 @@ void Simulator::HandleVList(Instruction* instr) { ...@@ -1595,11 +1595,11 @@ void Simulator::HandleVList(Instruction* instr) {
// 64-bit value. With the code below we assume that all runtime calls return // 64-bit value. With the code below we assume that all runtime calls return
// 64 bits of result. If they don't, the r1 result register contains a bogus // 64 bits of result. If they don't, the r1 result register contains a bogus
// value, which is fine because it is caller-saved. // value, which is fine because it is caller-saved.
using SimulatorRuntimeCall = int64_t (*)(int32_t arg0, int32_t arg1, using SimulatorRuntimeCall = int64_t (*)(
int32_t arg2, int32_t arg3, int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3, int32_t arg4,
int32_t arg4, int32_t arg5, int32_t arg5, int32_t arg6, int32_t arg7, int32_t arg8, int32_t arg9,
int32_t arg6, int32_t arg7, int32_t arg10, int32_t arg11, int32_t arg12, int32_t arg13, int32_t arg14,
int32_t arg8, int32_t arg9); int32_t arg15, int32_t arg16, int32_t arg17, int32_t arg18, int32_t arg19);
// These prototypes handle the four types of FP calls. // These prototypes handle the four types of FP calls.
using SimulatorRuntimeCompareCall = int64_t (*)(double darg0, double darg1); using SimulatorRuntimeCompareCall = int64_t (*)(double darg0, double darg1);
...@@ -1624,10 +1624,15 @@ using SimulatorRuntimeProfilingGetterCall = void (*)(int32_t arg0, int32_t arg1, ...@@ -1624,10 +1624,15 @@ using SimulatorRuntimeProfilingGetterCall = void (*)(int32_t arg0, int32_t arg1,
int64_t UnsafeGenericFunctionCall(intptr_t function, int32_t arg0, int32_t arg1, int64_t UnsafeGenericFunctionCall(intptr_t function, int32_t arg0, int32_t arg1,
int32_t arg2, int32_t arg3, int32_t arg4, int32_t arg2, int32_t arg3, int32_t arg4,
int32_t arg5, int32_t arg6, int32_t arg7, int32_t arg5, int32_t arg6, int32_t arg7,
int32_t arg8, int32_t arg9) { int32_t arg8, int32_t arg9, int32_t arg10,
int32_t arg11, int32_t arg12, int32_t arg13,
int32_t arg14, int32_t arg15, int32_t arg16,
int32_t arg17, int32_t arg18, int32_t arg19) {
SimulatorRuntimeCall target = SimulatorRuntimeCall target =
reinterpret_cast<SimulatorRuntimeCall>(function); reinterpret_cast<SimulatorRuntimeCall>(function);
return target(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); return target(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9,
arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18,
arg19);
} }
void UnsafeDirectApiCall(intptr_t function, int32_t arg0) { void UnsafeDirectApiCall(intptr_t function, int32_t arg0) {
SimulatorRuntimeDirectApiCall target = SimulatorRuntimeDirectApiCall target =
...@@ -1668,7 +1673,17 @@ void Simulator::SoftwareInterrupt(Instruction* instr) { ...@@ -1668,7 +1673,17 @@ void Simulator::SoftwareInterrupt(Instruction* instr) {
int32_t arg7 = stack_pointer[3]; int32_t arg7 = stack_pointer[3];
int32_t arg8 = stack_pointer[4]; int32_t arg8 = stack_pointer[4];
int32_t arg9 = stack_pointer[5]; int32_t arg9 = stack_pointer[5];
STATIC_ASSERT(kMaxCParameters == 10); int32_t arg10 = stack_pointer[6];
int32_t arg11 = stack_pointer[7];
int32_t arg12 = stack_pointer[8];
int32_t arg13 = stack_pointer[9];
int32_t arg14 = stack_pointer[10];
int32_t arg15 = stack_pointer[11];
int32_t arg16 = stack_pointer[12];
int32_t arg17 = stack_pointer[13];
int32_t arg18 = stack_pointer[14];
int32_t arg19 = stack_pointer[15];
STATIC_ASSERT(kMaxCParameters == 20);
bool fp_call = bool fp_call =
(redirection->type() == ExternalReference::BUILTIN_FP_FP_CALL) || (redirection->type() == ExternalReference::BUILTIN_FP_FP_CALL) ||
...@@ -1851,18 +1866,22 @@ void Simulator::SoftwareInterrupt(Instruction* instr) { ...@@ -1851,18 +1866,22 @@ void Simulator::SoftwareInterrupt(Instruction* instr) {
if (::v8::internal::FLAG_trace_sim || !stack_aligned) { if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
PrintF( PrintF(
"Call to host function at %p " "Call to host function at %p "
"args %08x, %08x, %08x, %08x, %08x, %08x, %08x, %08x, %08x, %08x", "args %08x, %08x, %08x, %08x, %08x, %08x, %08x, %08x, %08x, "
"%08x, %08x, %08x, %08x, %08x, %08x, %08x, %08x, %08x, %08x, "
"%08x",
reinterpret_cast<void*>(external), arg0, arg1, arg2, arg3, arg4, reinterpret_cast<void*>(external), arg0, arg1, arg2, arg3, arg4,
arg5, arg6, arg7, arg8, arg9); arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14,
arg15, arg16, arg17, arg18, arg19);
if (!stack_aligned) { if (!stack_aligned) {
PrintF(" with unaligned stack %08x\n", get_register(sp)); PrintF(" with unaligned stack %08x\n", get_register(sp));
} }
PrintF("\n"); PrintF("\n");
} }
CHECK(stack_aligned); CHECK(stack_aligned);
int64_t result = int64_t result = UnsafeGenericFunctionCall(
UnsafeGenericFunctionCall(external, arg0, arg1, arg2, arg3, arg4, external, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
arg5, arg6, arg7, arg8, arg9); arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18,
arg19);
#ifdef DEBUG #ifdef DEBUG
TrashCallerSaveRegisters(); TrashCallerSaveRegisters();
#endif #endif
......
...@@ -443,18 +443,18 @@ void Simulator::RunFrom(Instruction* start) { ...@@ -443,18 +443,18 @@ void Simulator::RunFrom(Instruction* start) {
// The simulator assumes all runtime calls return two 64-bits values. If they // 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. // don't, register x1 is clobbered. This is fine because x1 is caller-saved.
#if defined(V8_OS_WIN) #if defined(V8_OS_WIN)
using SimulatorRuntimeCall_ReturnPtr = int64_t (*)(int64_t arg0, int64_t arg1, using SimulatorRuntimeCall_ReturnPtr = int64_t (*)(
int64_t arg2, int64_t arg3, int64_t arg0, int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg4,
int64_t arg4, int64_t arg5, int64_t arg5, int64_t arg6, int64_t arg7, int64_t arg8, int64_t arg9,
int64_t arg6, int64_t arg7, int64_t arg10, int64_t arg11, int64_t arg12, int64_t arg13, int64_t arg14,
int64_t arg8, int64_t arg9); int64_t arg15, int64_t arg16, int64_t arg17, int64_t arg18, int64_t arg19);
#endif #endif
using SimulatorRuntimeCall = ObjectPair (*)(int64_t arg0, int64_t arg1, using SimulatorRuntimeCall = ObjectPair (*)(
int64_t arg2, int64_t arg3, int64_t arg0, int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg4,
int64_t arg4, int64_t arg5, int64_t arg5, int64_t arg6, int64_t arg7, int64_t arg8, int64_t arg9,
int64_t arg6, int64_t arg7, int64_t arg10, int64_t arg11, int64_t arg12, int64_t arg13, int64_t arg14,
int64_t arg8, int64_t arg9); int64_t arg15, int64_t arg16, int64_t arg17, int64_t arg18, int64_t arg19);
using SimulatorRuntimeCompareCall = int64_t (*)(double arg1, double arg2); using SimulatorRuntimeCompareCall = int64_t (*)(double arg1, double arg2);
using SimulatorRuntimeFPFPCall = double (*)(double arg1, double arg2); using SimulatorRuntimeFPFPCall = double (*)(double arg1, double arg2);
...@@ -475,13 +475,17 @@ using SimulatorRuntimeProfilingGetterCall = void (*)(int64_t arg0, int64_t arg1, ...@@ -475,13 +475,17 @@ using SimulatorRuntimeProfilingGetterCall = void (*)(int64_t arg0, int64_t arg1,
// function to {SimulatorRuntimeCall} is undefined behavior; but since // function to {SimulatorRuntimeCall} is undefined behavior; but since
// the target function can indeed be any function that's exposed via // the target function can indeed be any function that's exposed via
// the "fast C call" mechanism, we can't reconstruct its signature here. // the "fast C call" mechanism, we can't reconstruct its signature here.
ObjectPair UnsafeGenericFunctionCall(int64_t function, int64_t arg0, ObjectPair UnsafeGenericFunctionCall(
int64_t arg1, int64_t arg2, int64_t arg3, int64_t function, int64_t arg0, int64_t arg1, int64_t arg2, int64_t arg3,
int64_t arg4, int64_t arg5, int64_t arg6, int64_t arg4, int64_t arg5, int64_t arg6, int64_t arg7, int64_t arg8,
int64_t arg7, int64_t arg8, int64_t arg9) { int64_t arg9, int64_t arg10, int64_t arg11, int64_t arg12, int64_t arg13,
int64_t arg14, int64_t arg15, int64_t arg16, int64_t arg17, int64_t arg18,
int64_t arg19) {
SimulatorRuntimeCall target = SimulatorRuntimeCall target =
reinterpret_cast<SimulatorRuntimeCall>(function); reinterpret_cast<SimulatorRuntimeCall>(function);
return target(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); return target(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9,
arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18,
arg19);
} }
void UnsafeDirectApiCall(int64_t function, int64_t arg0) { void UnsafeDirectApiCall(int64_t function, int64_t arg0) {
SimulatorRuntimeDirectApiCall target = SimulatorRuntimeDirectApiCall target =
...@@ -531,7 +535,17 @@ void Simulator::DoRuntimeCall(Instruction* instr) { ...@@ -531,7 +535,17 @@ void Simulator::DoRuntimeCall(Instruction* instr) {
const int64_t arg7 = xreg(7); const int64_t arg7 = xreg(7);
const int64_t arg8 = stack_pointer[0]; const int64_t arg8 = stack_pointer[0];
const int64_t arg9 = stack_pointer[1]; const int64_t arg9 = stack_pointer[1];
STATIC_ASSERT(kMaxCParameters == 10); const int64_t arg10 = stack_pointer[2];
const int64_t arg11 = stack_pointer[3];
const int64_t arg12 = stack_pointer[4];
const int64_t arg13 = stack_pointer[5];
const int64_t arg14 = stack_pointer[6];
const int64_t arg15 = stack_pointer[7];
const int64_t arg16 = stack_pointer[8];
const int64_t arg17 = stack_pointer[9];
const int64_t arg18 = stack_pointer[10];
const int64_t arg19 = stack_pointer[11];
STATIC_ASSERT(kMaxCParameters == 20);
switch (redirection->type()) { switch (redirection->type()) {
default: default:
...@@ -574,14 +588,26 @@ void Simulator::DoRuntimeCall(Instruction* instr) { ...@@ -574,14 +588,26 @@ void Simulator::DoRuntimeCall(Instruction* instr) {
", " ", "
"0x%016" PRIx64 ", 0x%016" PRIx64 "0x%016" PRIx64 ", 0x%016" PRIx64
", " ", "
"0x%016" PRIx64 ", 0x%016" PRIx64
", "
"0x%016" PRIx64 ", 0x%016" PRIx64
", "
"0x%016" PRIx64 ", 0x%016" PRIx64
", "
"0x%016" PRIx64 ", 0x%016" PRIx64
", "
"0x%016" PRIx64 ", 0x%016" PRIx64
", "
"0x%016" PRIx64 ", 0x%016" PRIx64, "0x%016" PRIx64 ", 0x%016" PRIx64,
arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,
arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19);
SimulatorRuntimeCall_ReturnPtr target = SimulatorRuntimeCall_ReturnPtr target =
reinterpret_cast<SimulatorRuntimeCall_ReturnPtr>(external); reinterpret_cast<SimulatorRuntimeCall_ReturnPtr>(external);
int64_t result = int64_t result = target(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,
target(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); arg8, arg9, arg10, arg11, arg12, arg13, arg14,
arg15, arg16, arg17, arg18, arg19);
TraceSim("Returned: 0x%16\n", result); TraceSim("Returned: 0x%16\n", result);
#ifdef DEBUG #ifdef DEBUG
CorruptAllCallerSavedCPURegisters(); CorruptAllCallerSavedCPURegisters();
...@@ -609,10 +635,23 @@ void Simulator::DoRuntimeCall(Instruction* instr) { ...@@ -609,10 +635,23 @@ void Simulator::DoRuntimeCall(Instruction* instr) {
", " ", "
"0x%016" PRIx64 ", 0x%016" PRIx64 "0x%016" PRIx64 ", 0x%016" PRIx64
", " ", "
"0x%016" PRIx64 ", 0x%016" PRIx64
", "
"0x%016" PRIx64 ", 0x%016" PRIx64
", "
"0x%016" PRIx64 ", 0x%016" PRIx64
", "
"0x%016" PRIx64 ", 0x%016" PRIx64
", "
"0x%016" PRIx64 ", 0x%016" PRIx64
", "
"0x%016" PRIx64 ", 0x%016" PRIx64, "0x%016" PRIx64 ", 0x%016" PRIx64,
arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,
arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19);
ObjectPair result = UnsafeGenericFunctionCall( ObjectPair result = UnsafeGenericFunctionCall(
external, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); external, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9,
arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19);
TraceSim("Returned: {%p, %p}\n", reinterpret_cast<void*>(result.x), TraceSim("Returned: {%p, %p}\n", reinterpret_cast<void*>(result.x),
reinterpret_cast<void*>(result.y)); reinterpret_cast<void*>(result.y));
#ifdef DEBUG #ifdef DEBUG
......
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