Bug 1863794 - Generate ABIFunctionType code using build script. r=jandem

Today adding a new ABIFunctionType requires:
  1. Adding a new option to the enum
  2. Updating all the simulators to handle redirects of this type

(1) is easy after we added some constexpr code for constructing
these types.

(2) is really painful, because it requires building on multiple
platforms to test, and requires knowledge of all ABI's to get
details about registers/stack/etc correct.

This patch adds a build-time step which will generate (1) and (2)
from a declarative YAML file.

The interesting piece is (2) which has to understand the ABI
rules and simulator data structures for generating the code.
It's tricky code, but think it's easier to maintain and prove
correct in one place vs. in a big simulator switch. A data point
for this is that implementing this uncovered a few cases where
our hand-written code was technically incorrect (although practically
not an issue yet).

Depends on D193111

Differential Revision: https://phabricator.services.mozilla.com/D193112
This commit is contained in:
Ryan Hunt 2023-11-30 00:46:31 +00:00
Родитель 343cd58824
Коммит 9c5801d32d
11 изменённых файлов: 745 добавлений и 1833 удалений

Просмотреть файл

@ -63,6 +63,7 @@ included_inclnames_to_ignore = set(
"frontend/smoosh_generated.h", # generated in $OBJDIR
"gc/StatsPhasesGenerated.h", # generated in $OBJDIR
"gc/StatsPhasesGenerated.inc", # generated in $OBJDIR
"jit/ABIFunctionTypeGenerated.h", # generated in $OBJDIR"
"jit/AtomicOperationsGenerated.h", # generated in $OBJDIR
"jit/CacheIROpsGenerated.h", # generated in $OBJDIR
"jit/LIROpsGenerated.h", # generated in $OBJDIR

Просмотреть файл

@ -0,0 +1,65 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: set ts=8 sts=2 et sw=2 tw=80:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef jit_ABIFunctionType_h
#define jit_ABIFunctionType_h
#include <initializer_list>
#include <stdint.h>
#include "jit/ABIFunctionTypeGenerated.h"
namespace js {
namespace jit {
enum ABIArgType {
// A pointer sized integer
ArgType_General = 0x1,
// A 32-bit integer
ArgType_Int32 = 0x2,
// A 64-bit integer
ArgType_Int64 = 0x3,
// A 32-bit floating point number
ArgType_Float32 = 0x4,
// A 64-bit floating point number
ArgType_Float64 = 0x5,
RetType_Shift = 0x0,
ArgType_Shift = 0x3,
ArgType_Mask = 0x7
};
namespace detail {
static constexpr uint64_t MakeABIFunctionType(
ABIArgType ret, std::initializer_list<ABIArgType> args) {
uint64_t abiType = 0;
for (auto arg : args) {
abiType <<= ArgType_Shift;
abiType |= (uint64_t)arg;
}
abiType <<= ArgType_Shift;
abiType |= (uint64_t)ret;
return abiType;
}
} // namespace detail
enum ABIFunctionType : uint64_t {
// The enum must be explicitly typed to avoid UB: some validly constructed
// members are larger than any explicitly declared members.
ABI_FUNCTION_TYPE_ENUM
};
static constexpr ABIFunctionType MakeABIFunctionType(
ABIArgType ret, std::initializer_list<ABIArgType> args) {
return ABIFunctionType(detail::MakeABIFunctionType(ret, args));
}
} // namespace jit
} // namespace js
#endif /* jit_ABIFunctionType_h */

Просмотреть файл

@ -0,0 +1,271 @@
# The definitions in here are processed by GenerateABIFunctionType.py to
# generate the ABIFunctionType enum and simulator code for handling these
# function types.
#
# The name field is optional and will be autogenerated if omitted. New
# additions should generally use the autogenerated name.
# VM functions that take 0-9 non-double arguments
# and return a non-double value.
- name: General0
ret: General
args: []
- name: General1
ret: General
args: [General]
- name: General2
ret: General
args: [General, General]
- name: General3
ret: General
args: [General, General, General]
- name: General4
ret: General
args: [General, General, General, General]
- name: General5
ret: General
args: [General, General, General, General, General]
- name: General6
ret: General
args: [General, General, General, General, General, General]
- name: General7
ret: General
args: [General, General, General, General, General, General, General]
- name: General8
ret: General
args: [General, General, General, General, General, General, General, General]
# int64 f(double)
- name: Int64_Double
ret: Int64
args: [Float64]
# double f()
- name: Double_None
ret: Float64
args: []
# int f(double)
- name: Int_Double
ret: General
args: [Float64]
# int f(float32)
- name: Int_Float32
ret: General
args: [Float32]
# float f(float)
- ret: Float32
args: [Float32]
# float f(int, int)
- name: Float32_IntInt
ret: Float32
args: [General, General]
# double f(double)
- name: Double_Double
ret: Float64
args: [Float64]
# double f(int)
- name: Double_Int
ret: Float64
args: [General]
# double f(int, int)
- name: Double_IntInt
ret: Float64
args: [General, General]
# double f(double, int)
- name: Double_DoubleInt
ret: Float64
args: [Float64, General]
# double f(double, double)
- name: Double_DoubleDouble
ret: Float64
args: [Float64, Float64]
# float f(float, float)
- ret: Float32
args: [Float32, Float32]
# double f(int, double)
- name: Double_IntDouble
ret: Float64
args: [General, Float64]
# int f(int, double)
- name: Int_IntDouble
ret: General
args: [General, Float64]
# int f(double, int)
- name: Int_DoubleInt
ret: General
args: [Float64, General]
# double f(double, double, double)
- name: Double_DoubleDoubleDouble
ret: Float64
args: [Float64, Float64, Float64]
# double f(double, double, double, double)
- name: Double_DoubleDoubleDoubleDouble
ret: Float64
args: [Float64, Float64, Float64, Float64]
# int f(double, int, int)
- name: Int_DoubleIntInt
ret: General
args: [Float64, General, General]
# int f(int, double, int, int)
- name: Int_IntDoubleIntInt
ret: General
args: [General, Float64, General, General]
- name: Int_GeneralGeneralGeneralInt64
ret: General
args: [General, General, General, Int64]
- name: Int_GeneralGeneralInt64Int64
ret: General
args: [General, General, Int64, Int64]
# int32_t f(...) variants
- ret: General
args: [General, Int32]
- ret: General
args: [General, Int32, General]
- ret: General
args: [General, Int32, Int32]
- ret: General
args: [General, Int32, Int32, General, Int32]
# int32_t f(...) variants
- ret: Int32
args: [General]
- ret: Int32
args: [General, General]
- ret: Int32
args: [General, General, General]
- ret: Int32
args: [General, General, Int32, General]
- ret: Int32
args: [General, General, Int32, General, Int32, Int32, Int32]
- ret: Int32
args: [General, General, Int32, Int32]
- ret: Int32
args: [General, General, Int32, Int32, Int32, General, Int32]
- ret: Int32
args: [General, Int32]
- ret: Int32
args: [General, Int32, Float32, Float32, Float32, Float32, Int32, Int32, Int32, Int32, General]
- ret: Int32
args: [General, Int32, Float32, Float32, Int32, Float32, Float32, Int32, Float32, Int32, Int32, Int32, Int32, General]
- ret: Int32
args: [General, Int32, Float32, Float32, Int32, Int32, Int32, General]
- ret: Int32
args: [General, Int32, General, Int32]
- ret: Int32
args: [General, Int32, General, Int32, Int32]
- ret: Int32
args: [General, Int32, Int32]
- ret: Int32
args: [General, Int32, Int32, General]
- ret: Int32
args: [General, Int32, Int32, Int32]
- ret: Int32
args: [General, Int32, Int32, Int32, General]
- ret: Int32
args: [General, Int32, Int32, Int32, Int32]
- ret: Int32
args: [General, Int32, Int32, Int32, Int32, General]
- ret: Int32
args: [General, Int32, Int32, Int32, Int32, Int32]
- ret: Int32
args: [General, Int32, Int32, Int32, Int32, Int32, Int32, General]
- ret: Int32
args: [General, Int32, Int32, Int64, Int32]
- ret: Int32
args: [General, Int32, Int64, Int64, Int32]
- ret: Int32
args: [General, Int64, Int32, Int32]
- ret: Int32
args: [General, Int64, Int32, Int32, Int32, Int32]
- ret: Int32
args: [General, Int64, Int32, Int64, General]
- ret: Int32
args: [General, Int64, Int32, Int64, Int32]
- ret: Int32
args: [General, Int64, Int64, General]
- ret: Int32
args: [General, Int64, Int64, Int64]
- ret: Int32
args: [General, Int64, Int64, Int64, General]
- ret: Int32
args: [General, Int64, Int64, Int64, General, General]
- ret: Int32
args: [General, Int64, Int64, Int64, Int32]
- ret: Int32
args: [General, Int64, Int64, Int64, Int32, Int32]
# Functions that return Int64 are tricky because SpiderMonkey's ReturnRegI64
# does not match the ABI int64 return register on x86. Wasm only!
- ret: Int64
args: [General]
- ret: Int64
args: [General, General]
- ret: Int64
args: [Int32, Int32, Int32, Int32]
- ret: Int64
args: [General, Int32]
- ret: Int64
args: [General, Int64]
- ret: Int64
args: [General, Int64, Int32]

Просмотреть файл

@ -0,0 +1,339 @@
from collections import OrderedDict
import buildconfig
import six
import yaml
from mozbuild.preprocessor import Preprocessor
HEADER_TEMPLATE = """\
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef %(includeguard)s
#define %(includeguard)s
/* This file is generated by jit/GenerateABIFunctionType.py. Do not edit! */
%(contents)s
#endif // %(includeguard)s
"""
def generate_header(c_out, includeguard, contents):
c_out.write(
HEADER_TEMPLATE
% {
"includeguard": includeguard,
"contents": contents,
}
)
def load_yaml(yaml_path):
# First invoke preprocessor.py so that we can use #ifdef JS_SIMULATOR in
# the YAML file.
pp = Preprocessor()
pp.context.update(buildconfig.defines["ALLDEFINES"])
pp.out = six.StringIO()
pp.do_filter("substitution")
pp.do_include(yaml_path)
contents = pp.out.getvalue()
# Load into an OrderedDict to ensure order is preserved. Note: Python 3.7+
# also preserves ordering for normal dictionaries.
# Code based on https://stackoverflow.com/a/21912744.
class OrderedLoader(yaml.Loader):
pass
def construct_mapping(loader, node):
loader.flatten_mapping(node)
return OrderedDict(loader.construct_pairs(node))
tag = yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG
OrderedLoader.add_constructor(tag, construct_mapping)
return yaml.load(contents, OrderedLoader)
def cpp_arg_type(arg_type):
if arg_type == "General":
return "intptr_t"
elif arg_type == "Int32":
return "int32_t"
elif arg_type == "Int64":
return "int64_t"
elif arg_type == "Float32":
return "float"
elif arg_type == "Float64":
return "double"
else:
raise ValueError(arg_type)
def func_type_name(func_type):
if "name" in func_type:
return func_type["name"]
# Autogenerate a name like `General_GeneralGeneral` if none is specified
return f"{func_type['ret']}_{''.join(func_type['args'])}"
def func_type_has_floats(func_type):
for arg in func_type["args"]:
if arg == "Float32" or arg == "Float64":
return True
return False
# Generate the ARM32 argument loading for a func type for when soft-FP is enabled
def arm32_soft_fp_args(func_type):
# This must match ABIArgGenerator::softNext() in Assembler-arm.cpp
contents = ""
numIntArgRegs = 4
intRegIndex = 0
stackOffset = 0
for i, arg in enumerate(func_type["args"]):
if i != 0:
contents += ", "
if arg == "General":
if intRegIndex == numIntArgRegs:
contents += f"stack_pointer[{stackOffset}]"
stackOffset += 1
else:
contents += f"a{intRegIndex}"
intRegIndex += 1
elif arg == "Int32":
if intRegIndex == numIntArgRegs:
contents += f"stack_pointer[{stackOffset}]"
stackOffset += 1
else:
contents += f"a{intRegIndex}"
intRegIndex += 1
elif arg == "Int64":
intRegIndex += intRegIndex % 2
if intRegIndex == numIntArgRegs:
stackOffset += stackOffset % 2
contents += f"MakeInt64(stack_pointer[{stackOffset}], stack_pointer[{stackOffset + 1}])"
stackOffset += 2
else:
contents += f"MakeInt64(a{intRegIndex}, a{intRegIndex+1})"
intRegIndex += 2
elif arg == "Float32":
if intRegIndex == numIntArgRegs:
contents += f"mozilla::BitwiseCast<float>(stack_pointer[{stackOffset}])"
stackOffset += 1
else:
contents += f"mozilla::BitwiseCast<float>(a{intRegIndex})"
intRegIndex += 1
elif arg == "Float64":
intRegIndex += intRegIndex % 2
if intRegIndex == numIntArgRegs:
stackOffset += stackOffset % 2
contents += f"mozilla::BitwiseCast<double>(MakeInt64(stack_pointer[{stackOffset}], stack_pointer[{stackOffset + 1}]))"
stackOffset += 2
else:
contents += f"mozilla::BitwiseCast<double>(MakeInt64(a{intRegIndex}, a{intRegIndex + 1}))"
intRegIndex += 2
assert intRegIndex <= numIntArgRegs
return contents
# Generate the ARM32 argument loading for a func type for when hard-FP is enabled
def arm32_hard_fp_args(func_type):
# This must match ABIArgGenerator::hardNext() in Assembler-arm.cpp
contents = ""
numIntArgRegs = 4
numFloatArgRegs = 16
intRegIndex = 0
floatRegIndex = 0
stackOffset = 0
for i, arg in enumerate(func_type["args"]):
if i != 0:
contents += ", "
if arg == "General":
if intRegIndex == numIntArgRegs:
contents += f"stack_pointer[{stackOffset}]"
stackOffset += 1
else:
contents += f"a{intRegIndex}"
intRegIndex += 1
elif arg == "Int32":
if intRegIndex == numIntArgRegs:
contents += f"stack_pointer[{stackOffset}]"
stackOffset += 1
else:
contents += f"a{intRegIndex}"
intRegIndex += 1
elif arg == "Int64":
intRegIndex += intRegIndex % 2
if intRegIndex == numIntArgRegs:
stackOffset += stackOffset % 2
contents += f"MakeInt64(stack_pointer[{stackOffset}], stack_pointer[{stackOffset + 1}])"
stackOffset += 2
else:
contents += f"MakeInt64(a{intRegIndex}, a{intRegIndex+1})"
intRegIndex += 2
elif arg == "Float32":
if floatRegIndex == numFloatArgRegs:
contents += f"mozilla::BitwiseCast<float>(stack_pointer[{stackOffset}])"
stackOffset += 1
else:
contents += f"s{floatRegIndex}"
floatRegIndex += 1
elif arg == "Float64":
floatRegIndex += floatRegIndex % 2
if floatRegIndex == numFloatArgRegs:
stackOffset += stackOffset % 2
contents += f"mozilla::BitwiseCast<double>(MakeInt64(stack_pointer[{stackOffset}], stack_pointer[{stackOffset + 1}]))"
stackOffset += 2
else:
contents += f"d{round(floatRegIndex / 2)}"
floatRegIndex += 2
assert intRegIndex <= numIntArgRegs
assert floatRegIndex <= numFloatArgRegs
return contents
def arm32_simulator_dispatch(func_types):
contents = ""
for func_type in func_types:
hard_fp_args = arm32_hard_fp_args(func_type)
soft_fp_args = arm32_soft_fp_args(func_type)
ret = func_type["ret"]
contents += f"case js::jit::Args_{func_type_name(func_type)}: {{\\\n"
contents += f" auto target = reinterpret_cast<Prototype_{func_type_name(func_type)}>(external);\\\n"
contents += f" {cpp_arg_type(ret)} ret;\\\n"
if func_type_has_floats(func_type):
contents += " if (UseHardFpABI()) {\\\n"
contents += f" ret = target({hard_fp_args});\\\n"
contents += " } else {\\\n"
contents += f" ret = target({soft_fp_args});\\\n"
contents += " }\\\n"
else:
# No float args means we don't need to check the float ABI and
# either generated args will do.
contents += f" ret = target({soft_fp_args});\\\n"
contents += " scratchVolatileRegisters((void*)target);\\\n"
if ret == "General" or ret == "Int32" or ret == "Int64":
contents += " setCallResult(ret);\\\n"
elif ret == "Float32":
contents += " setCallResultFloat(ret);\\\n"
elif ret == "Float64":
contents += " setCallResultDouble(ret);\\\n"
contents += " break;\\\n"
contents += "}\\\n"
return contents
# Generate the ARM64 argument loading for a func type
def arm64_args(func_type):
# This must match ABIArgGenerator::next() in Assembler-arm64.cpp
contents = ""
numIntArgRegs = 8
numFloatArgRegs = 8
intRegIndex = 0
floatRegIndex = 0
stackOffset = 0
for i, arg in enumerate(func_type["args"]):
if i != 0:
contents += ", "
if arg == "General":
if intRegIndex == numIntArgRegs:
contents += f"sp[{stackOffset}]"
stackOffset += 1
else:
contents += f"x{intRegIndex}"
intRegIndex += 1
elif arg == "Int32":
if intRegIndex == numIntArgRegs:
contents += f"sp[{stackOffset}]"
stackOffset += 1
else:
contents += f"x{intRegIndex}"
intRegIndex += 1
elif arg == "Int64":
if intRegIndex == numIntArgRegs:
contents += f"sp[{stackOffset}]"
stackOffset += 1
else:
contents += f"x{intRegIndex}"
intRegIndex += 1
elif arg == "Float32":
if floatRegIndex == numFloatArgRegs:
contents += f"mozilla::BitwiseCast<float>(sp[{stackOffset}])"
stackOffset += 1
else:
contents += f"s{floatRegIndex}"
floatRegIndex += 1
elif arg == "Float64":
if floatRegIndex == numFloatArgRegs:
contents += f"mozilla::BitwiseCast<double>(sp[{stackOffset}])"
stackOffset += 1
else:
contents += f"d{floatRegIndex}"
floatRegIndex += 1
assert intRegIndex <= numIntArgRegs
assert floatRegIndex <= numFloatArgRegs
return contents
def arm64_simulator_dispatch(func_types):
contents = ""
for func_type in func_types:
args = arm64_args(func_type)
contents += f"case js::jit::Args_{func_type_name(func_type)}: {{\\\n"
contents += f" auto target = reinterpret_cast<Prototype_{func_type_name(func_type)}>(nativeFn);\\\n"
contents += f" auto ret = target({args});\\\n"
ret = func_type["ret"]
if ret == "General":
contents += " setGPR64Result(ret);\\\n"
elif ret == "Int32":
contents += " setGPR32Result(ret);\\\n"
elif ret == "Int64":
contents += " setGPR64Result(ret);\\\n"
elif ret == "Float32":
contents += " setFP32Result(ret);\\\n"
elif ret == "Float64":
contents += " setFP64Result(ret);\\\n"
contents += " break;\\\n"
contents += "}\\\n"
return contents
def main(c_out, yaml_path):
func_types = load_yaml(yaml_path)
# Define the ABIFunctionType enum
contents = "#define ABI_FUNCTION_TYPE_ENUM \\\n"
for func_type in func_types:
name = "Args_" + func_type_name(func_type)
args = ", ".join(f"ArgType_{p}" for p in func_type["args"])
ret = f"ArgType_{func_type['ret']}"
contents += f" {name} = detail::MakeABIFunctionType({ret}, {{{args}}}),\\\n"
contents += "\n"
# Define the prototypes of the types
contents += "#define ABI_FUNCTION_TYPE_SIM_PROTOTYPES \\\n"
for func_type in func_types:
name = "Prototype_" + func_type_name(func_type)
args = ", ".join(cpp_arg_type(p) for p in func_type["args"])
ret = cpp_arg_type(func_type["ret"])
contents += f" typedef {ret} (*{name})({args});\\\n"
contents += "\n"
contents += "#define ABI_FUNCTION_TYPE_ARM64_SIM_DISPATCH \\\n"
contents += arm64_simulator_dispatch(func_types)
contents += "\n"
contents += "#define ABI_FUNCTION_TYPE_ARM32_SIM_DISPATCH \\\n"
contents += arm32_simulator_dispatch(func_types)
contents += "\n"
generate_header(c_out, "jit_ABIFunctionTypeGenerated_h", contents)

Просмотреть файл

@ -10,12 +10,13 @@
#include "mozilla/HashFunctions.h"
#include <algorithm>
#include <initializer_list>
#include <stdint.h>
#include "jstypes.h"
#include "NamespaceImports.h"
#include "jit/ABIFunctionType.h"
#include "js/ScalarType.h" // js::Scalar::Type
#include "js/Value.h"
@ -762,284 +763,6 @@ static constexpr bool NeedsPostBarrier(MIRType type) {
#endif // DEBUG
enum ABIArgType {
// A pointer sized integer
ArgType_General = 0x1,
// A 32-bit integer
ArgType_Int32 = 0x2,
// A 64-bit integer
ArgType_Int64 = 0x3,
// A 32-bit floating point number
ArgType_Float32 = 0x4,
// A 64-bit floating point number
ArgType_Float64 = 0x5,
RetType_Shift = 0x0,
ArgType_Shift = 0x3,
ArgType_Mask = 0x7
};
namespace detail {
static constexpr uint64_t MakeABIFunctionType(
ABIArgType ret, std::initializer_list<ABIArgType> args) {
uint64_t abiType = (uint64_t)ret << RetType_Shift;
int i = 1;
for (auto arg : args) {
abiType |= ((uint64_t)arg << (ArgType_Shift * i));
i++;
}
return abiType;
}
} // namespace detail
enum ABIFunctionType : uint64_t {
// The enum must be explicitly typed to avoid UB: some validly constructed
// members are larger than any explicitly declared members.
// VM functions that take 0-9 non-double arguments
// and return a non-double value.
Args_General0 = ArgType_General << RetType_Shift,
Args_General1 = Args_General0 | (ArgType_General << (ArgType_Shift * 1)),
Args_General2 = Args_General1 | (ArgType_General << (ArgType_Shift * 2)),
Args_General3 = Args_General2 | (ArgType_General << (ArgType_Shift * 3)),
Args_General4 = Args_General3 | (ArgType_General << (ArgType_Shift * 4)),
Args_General5 = Args_General4 | (ArgType_General << (ArgType_Shift * 5)),
Args_General6 = Args_General5 | (ArgType_General << (ArgType_Shift * 6)),
Args_General7 = Args_General6 | (ArgType_General << (ArgType_Shift * 7)),
Args_General8 = Args_General7 | (ArgType_General << (ArgType_Shift * 8)),
// int64 f(double)
Args_Int64_Double =
(ArgType_Int64 << RetType_Shift) | (ArgType_Float64 << ArgType_Shift),
// double f()
Args_Double_None = ArgType_Float64 << RetType_Shift,
// int f(double)
Args_Int_Double = Args_General0 | (ArgType_Float64 << ArgType_Shift),
// int f(float32)
Args_Int_Float32 = Args_General0 | (ArgType_Float32 << ArgType_Shift),
// float f(float)
Args_Float32_Float32 =
(ArgType_Float32 << RetType_Shift) | (ArgType_Float32 << ArgType_Shift),
// float f(int, int)
Args_Float32_IntInt = (ArgType_Float32 << RetType_Shift) |
(ArgType_General << (ArgType_Shift * 1)) |
(ArgType_General << (ArgType_Shift * 2)),
// double f(double)
Args_Double_Double = Args_Double_None | (ArgType_Float64 << ArgType_Shift),
// double f(int)
Args_Double_Int = Args_Double_None | (ArgType_General << ArgType_Shift),
// double f(int, int)
Args_Double_IntInt =
Args_Double_Int | (ArgType_General << (ArgType_Shift * 2)),
// double f(double, int)
Args_Double_DoubleInt = Args_Double_None |
(ArgType_General << (ArgType_Shift * 1)) |
(ArgType_Float64 << (ArgType_Shift * 2)),
// double f(double, double)
Args_Double_DoubleDouble =
Args_Double_Double | (ArgType_Float64 << (ArgType_Shift * 2)),
// float f(float, float)
Args_Float32_Float32Float32 =
Args_Float32_Float32 | (ArgType_Float32 << (ArgType_Shift * 2)),
// double f(int, double)
Args_Double_IntDouble = Args_Double_None |
(ArgType_Float64 << (ArgType_Shift * 1)) |
(ArgType_General << (ArgType_Shift * 2)),
// int f(int, double)
Args_Int_IntDouble = Args_General0 |
(ArgType_Float64 << (ArgType_Shift * 1)) |
(ArgType_General << (ArgType_Shift * 2)),
// int f(double, int)
Args_Int_DoubleInt = Args_General0 |
(ArgType_General << (ArgType_Shift * 1)) |
(ArgType_Float64 << (ArgType_Shift * 2)),
// double f(double, double, double)
Args_Double_DoubleDoubleDouble =
Args_Double_DoubleDouble | (ArgType_Float64 << (ArgType_Shift * 3)),
// double f(double, double, double, double)
Args_Double_DoubleDoubleDoubleDouble =
Args_Double_DoubleDoubleDouble | (ArgType_Float64 << (ArgType_Shift * 4)),
// int f(double, int, int)
Args_Int_DoubleIntInt = Args_General0 |
(ArgType_General << (ArgType_Shift * 1)) |
(ArgType_General << (ArgType_Shift * 2)) |
(ArgType_Float64 << (ArgType_Shift * 3)),
// int f(int, double, int, int)
Args_Int_IntDoubleIntInt = Args_General0 |
(ArgType_General << (ArgType_Shift * 1)) |
(ArgType_General << (ArgType_Shift * 2)) |
(ArgType_Float64 << (ArgType_Shift * 3)) |
(ArgType_General << (ArgType_Shift * 4)),
Args_Int_GeneralGeneralGeneralInt64 =
Args_General0 | (ArgType_General << (ArgType_Shift * 1)) |
(ArgType_General << (ArgType_Shift * 2)) |
(ArgType_General << (ArgType_Shift * 3)) |
(ArgType_Int64 << (ArgType_Shift * 4)),
Args_Int_GeneralGeneralInt64Int64 = Args_General0 |
(ArgType_General << (ArgType_Shift * 1)) |
(ArgType_General << (ArgType_Shift * 2)) |
(ArgType_Int64 << (ArgType_Shift * 3)) |
(ArgType_Int64 << (ArgType_Shift * 4)),
// int32_t f(...) variants
Args_Int32_General =
detail::MakeABIFunctionType(ArgType_Int32, {ArgType_General}),
Args_Int32_GeneralInt32 = detail::MakeABIFunctionType(
ArgType_Int32, {ArgType_General, ArgType_Int32}),
Args_Int32_GeneralInt32Int32 = detail::MakeABIFunctionType(
ArgType_Int32, {ArgType_General, ArgType_Int32, ArgType_Int32}),
Args_Int32_GeneralInt32Int32Int32 = detail::MakeABIFunctionType(
ArgType_Int32,
{ArgType_General, ArgType_Int32, ArgType_Int32, ArgType_Int32}),
Args_Int32_GeneralInt32Int32Int32Int32 = detail::MakeABIFunctionType(
ArgType_Int32, {ArgType_General, ArgType_Int32, ArgType_Int32,
ArgType_Int32, ArgType_Int32}),
Args_Int32_GeneralInt32Int32Int32Int32Int32 = detail::MakeABIFunctionType(
ArgType_Int32, {ArgType_General, ArgType_Int32, ArgType_Int32,
ArgType_Int32, ArgType_Int32, ArgType_Int32}),
Args_Int32_GeneralInt32Int32Int32Int32General = detail::MakeABIFunctionType(
ArgType_Int32, {ArgType_General, ArgType_Int32, ArgType_Int32,
ArgType_Int32, ArgType_Int32, ArgType_General}),
Args_Int32_GeneralGeneralInt32General = detail::MakeABIFunctionType(
ArgType_Int32,
{ArgType_General, ArgType_General, ArgType_Int32, ArgType_General}),
Args_Int32_GeneralGeneralInt32GeneralInt32Int32Int32 =
detail::MakeABIFunctionType(
ArgType_Int32,
{ArgType_General, ArgType_General, ArgType_Int32, ArgType_General,
ArgType_Int32, ArgType_Int32, ArgType_Int32}),
Args_Int32_GeneralInt32Int32Int32Int32Int32Int32General =
detail::MakeABIFunctionType(
ArgType_Int32,
{ArgType_General, ArgType_Int32, ArgType_Int32, ArgType_Int32,
ArgType_Int32, ArgType_Int32, ArgType_Int32, ArgType_General}),
Args_Int32_GeneralInt32Float32Float32Int32Int32Int32General =
detail::MakeABIFunctionType(
ArgType_Int32,
{ArgType_General, ArgType_Int32, ArgType_Float32, ArgType_Float32,
ArgType_Int32, ArgType_Int32, ArgType_Int32, ArgType_General}),
Args_Int32_GeneralInt32Float32Float32Float32Float32Int32Int32Int32Int32General =
detail::MakeABIFunctionType(
ArgType_Int32,
{ArgType_General, ArgType_Int32, ArgType_Float32, ArgType_Float32,
ArgType_Float32, ArgType_Float32, ArgType_Int32, ArgType_Int32,
ArgType_Int32, ArgType_Int32, ArgType_General}),
Args_Int32_GeneralInt32Float32Float32Int32Float32Float32Int32Float32Int32Int32Int32Int32General =
detail::MakeABIFunctionType(
ArgType_Int32,
{ArgType_General, ArgType_Int32, ArgType_Float32, ArgType_Float32,
ArgType_Int32, ArgType_Float32, ArgType_Float32, ArgType_Int32,
ArgType_Float32, ArgType_Int32, ArgType_Int32, ArgType_Int32,
ArgType_Int32, ArgType_General}),
Args_Int32_GeneralInt32Int32Int32General = detail::MakeABIFunctionType(
ArgType_Int32, {ArgType_General, ArgType_Int32, ArgType_Int32,
ArgType_Int32, ArgType_General}),
Args_Int32_GeneralInt32Int32General = detail::MakeABIFunctionType(
ArgType_Int32,
{ArgType_General, ArgType_Int32, ArgType_Int32, ArgType_General}),
Args_Int32_GeneralInt32Int32Int64Int32 = detail::MakeABIFunctionType(
ArgType_Int32, {ArgType_General, ArgType_Int32, ArgType_Int32,
ArgType_Int64, ArgType_Int32}),
Args_Int32_GeneralInt32GeneralInt32 = detail::MakeABIFunctionType(
ArgType_Int32,
{ArgType_General, ArgType_Int32, ArgType_General, ArgType_Int32}),
Args_Int32_GeneralInt32GeneralInt32Int32 = detail::MakeABIFunctionType(
ArgType_Int32, {ArgType_General, ArgType_Int32, ArgType_General,
ArgType_Int32, ArgType_Int32}),
Args_Int32_GeneralInt32Int64Int64Int32 = detail::MakeABIFunctionType(
ArgType_Int32, {ArgType_General, ArgType_Int32, ArgType_Int64,
ArgType_Int64, ArgType_Int32}),
Args_Int32_GeneralGeneral = detail::MakeABIFunctionType(
ArgType_Int32, {ArgType_General, ArgType_General}),
Args_Int32_GeneralGeneralGeneral = detail::MakeABIFunctionType(
ArgType_Int32, {ArgType_General, ArgType_General, ArgType_General}),
Args_Int32_GeneralGeneralInt32Int32 = detail::MakeABIFunctionType(
ArgType_Int32,
{ArgType_General, ArgType_General, ArgType_Int32, ArgType_Int32}),
// general f(...) variants
Args_General_GeneralInt32 = detail::MakeABIFunctionType(
ArgType_General, {ArgType_General, ArgType_Int32}),
Args_General_GeneralInt32Int32 = detail::MakeABIFunctionType(
ArgType_General, {ArgType_General, ArgType_Int32, ArgType_Int32}),
Args_General_GeneralInt32General = detail::MakeABIFunctionType(
ArgType_General, {ArgType_General, ArgType_Int32, ArgType_General}),
Args_General_GeneralInt32Int32GeneralInt32 = detail::MakeABIFunctionType(
ArgType_General, {ArgType_General, ArgType_Int32, ArgType_Int32,
ArgType_General, ArgType_Int32}),
Args_Int32_GeneralInt64Int32Int32 = detail::MakeABIFunctionType(
ArgType_Int32,
{ArgType_General, ArgType_Int64, ArgType_Int32, ArgType_Int32}),
Args_Int32_GeneralInt64Int32Int32Int32Int32 = detail::MakeABIFunctionType(
ArgType_Int32, {ArgType_General, ArgType_Int64, ArgType_Int32,
ArgType_Int32, ArgType_Int32, ArgType_Int32}),
Args_Int32_GeneralInt64Int32Int64Int32 = detail::MakeABIFunctionType(
ArgType_Int32, {ArgType_General, ArgType_Int64, ArgType_Int32,
ArgType_Int64, ArgType_Int32}),
Args_Int32_GeneralInt64Int32Int64General = detail::MakeABIFunctionType(
ArgType_Int32, {ArgType_General, ArgType_Int64, ArgType_Int32,
ArgType_Int64, ArgType_General}),
Args_Int32_GeneralGeneralInt32Int32Int32GeneralInt32 =
detail::MakeABIFunctionType(
ArgType_Int32,
{ArgType_General, ArgType_General, ArgType_Int32, ArgType_Int32,
ArgType_Int32, ArgType_General, ArgType_Int32}),
Args_Int32_GeneralInt64Int64Int64 = detail::MakeABIFunctionType(
ArgType_Int32,
{ArgType_General, ArgType_Int64, ArgType_Int64, ArgType_Int64}),
Args_Int32_GeneralInt64Int64Int64Int32 = detail::MakeABIFunctionType(
ArgType_Int32, {ArgType_General, ArgType_Int64, ArgType_Int64,
ArgType_Int64, ArgType_Int32}),
Args_Int32_GeneralInt64Int64General = detail::MakeABIFunctionType(
ArgType_Int32,
{ArgType_General, ArgType_Int64, ArgType_Int64, ArgType_General}),
Args_Int32_GeneralInt64Int64Int64General = detail::MakeABIFunctionType(
ArgType_Int32, {ArgType_General, ArgType_Int64, ArgType_Int64,
ArgType_Int64, ArgType_General}),
Args_Int32_GeneralInt64Int64Int64Int32Int32 = detail::MakeABIFunctionType(
ArgType_Int32, {ArgType_General, ArgType_Int64, ArgType_Int64,
ArgType_Int64, ArgType_Int32, ArgType_Int32}),
// Functions that return Int64 are tricky because SpiderMonkey's ReturnRegI64
// does not match the ABI int64 return register on x86. Wasm only!
Args_Int64_General =
detail::MakeABIFunctionType(ArgType_Int64, {ArgType_General}),
Args_Int64_GeneralInt32 = detail::MakeABIFunctionType(
ArgType_Int64, {ArgType_General, ArgType_Int32}),
Args_Int64_GeneralInt64 = detail::MakeABIFunctionType(
ArgType_Int64, {ArgType_General, ArgType_Int64}),
Args_Int64_GeneralInt64Int32 = detail::MakeABIFunctionType(
ArgType_Int64, {ArgType_General, ArgType_Int64, ArgType_Int32}),
};
static constexpr ABIFunctionType MakeABIFunctionType(
ABIArgType ret, std::initializer_list<ABIArgType> args) {
return ABIFunctionType(detail::MakeABIFunctionType(ret, args));
}
// Rounding modes for round instructions.
enum class RoundingMode { Down, Up, NearestTiesToEven, TowardsZero };

Просмотреть файл

@ -2309,147 +2309,7 @@ void Simulator::handleVList(SimInstruction* instr) {
}
}
// Note: With the code below we assume that all runtime calls return a 64 bits
// result. If they don't, the r1 result register contains a bogus value, which
// is fine because it is caller-saved.
typedef int64_t (*Prototype_General0)();
typedef int64_t (*Prototype_General1)(int32_t arg0);
typedef int64_t (*Prototype_General2)(int32_t arg0, int32_t arg1);
typedef int64_t (*Prototype_General3)(int32_t arg0, int32_t arg1, int32_t arg2);
typedef int64_t (*Prototype_General4)(int32_t arg0, int32_t arg1, int32_t arg2,
int32_t arg3);
typedef int64_t (*Prototype_General5)(int32_t arg0, int32_t arg1, int32_t arg2,
int32_t arg3, int32_t arg4);
typedef int64_t (*Prototype_General6)(int32_t arg0, int32_t arg1, int32_t arg2,
int32_t arg3, int32_t arg4, int32_t arg5);
typedef int64_t (*Prototype_General7)(int32_t arg0, int32_t arg1, int32_t arg2,
int32_t arg3, int32_t arg4, int32_t arg5,
int32_t arg6);
typedef int64_t (*Prototype_General8)(int32_t arg0, int32_t arg1, int32_t arg2,
int32_t arg3, int32_t arg4, int32_t arg5,
int32_t arg6, int32_t arg7);
typedef int64_t (*Prototype_GeneralGeneralGeneralInt64)(int32_t arg0,
int32_t arg1,
int32_t arg2,
int64_t arg3);
typedef int64_t (*Prototype_GeneralGeneralInt64Int64)(int32_t arg0,
int32_t arg1,
int64_t arg2,
int64_t arg3);
typedef double (*Prototype_Double_None)();
typedef double (*Prototype_Double_Double)(double arg0);
typedef double (*Prototype_Double_Int)(int32_t arg0);
typedef double (*Prototype_Double_IntInt)(int32_t arg0, int32_t arg1);
typedef int32_t (*Prototype_Int_Double)(double arg0);
typedef int64_t (*Prototype_Int64_Double)(double arg0);
typedef int32_t (*Prototype_Int_DoubleIntInt)(double arg0, int32_t arg1,
int32_t arg2);
typedef int32_t (*Prototype_Int_IntDoubleIntInt)(int32_t arg0, double arg1,
int32_t arg2, int32_t arg3);
typedef int32_t (*Prototype_Int_Float32)(float arg0);
typedef float (*Prototype_Float32_Float32)(float arg0);
typedef float (*Prototype_Float32_Float32Float32)(float arg0, float arg1);
typedef float (*Prototype_Float32_IntInt)(int arg0, int arg1);
typedef double (*Prototype_Double_DoubleInt)(double arg0, int32_t arg1);
typedef double (*Prototype_Double_IntDouble)(int32_t arg0, double arg1);
typedef double (*Prototype_Double_DoubleDouble)(double arg0, double arg1);
typedef int32_t (*Prototype_Int_IntDouble)(int32_t arg0, double arg1);
typedef int32_t (*Prototype_Int_DoubleInt)(double arg0, int32_t arg1);
typedef double (*Prototype_Double_DoubleDoubleDouble)(double arg0, double arg1,
double arg2);
typedef double (*Prototype_Double_DoubleDoubleDoubleDouble)(double arg0,
double arg1,
double arg2,
double arg3);
typedef int32_t (*Prototype_Int32_General)(int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt32)(int32_t, int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt32Int32)(int32_t, int32_t, int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt32Int32Int32)(int32_t, int32_t,
int32_t, int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt32Int32Int32Int32)(int32_t, int32_t,
int32_t, int32_t,
int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt32Int32Int32Int32Int32)(
int32_t, int32_t, int32_t, int32_t, int32_t, int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt32Int32Int32Int32General)(
int32_t, int32_t, int32_t, int32_t, int32_t, int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt32Int32Int32Int32Int32Int32General)(
int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t);
typedef int32_t (
*Prototype_Int32_GeneralInt32Float32Float32Int32Int32Int32General)(
int32_t, int32_t, float, float, int32_t, int32_t, int32_t, int32_t);
typedef int32_t (
*Prototype_Int32_GeneralInt32Float32Float32Float32Float32Int32Int32Int32Int32General)(
int32_t, int32_t, float, float, float, float, int32_t, int32_t, int32_t,
int32_t, int32_t);
typedef int32_t (
*Prototype_Int32_GeneralInt32Float32Float32Int32Float32Float32Int32Float32Int32Int32Int32Int32General)(
int32_t, int32_t, float, float, int32_t, float, float, int32_t, float,
int32_t, int32_t, int32_t, int32_t, int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt32Int32Int32General)(
int32_t, int32_t, int32_t, int32_t, int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt32Int32General)(int32_t, int32_t,
int32_t, int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt32Int32Int64Int32)(int32_t, int32_t,
int32_t, int64_t,
int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt32GeneralInt32)(int32_t, int32_t,
int32_t, int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt32GeneralInt32Int32)(
int32_t, int32_t, int32_t, int32_t, int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt32Int64Int64Int32)(int32_t, int32_t,
int64_t, int64_t,
int32_t);
typedef int32_t (*Prototype_Int32_GeneralGeneral)(int32_t, int32_t);
typedef int32_t (*Prototype_Int32_GeneralGeneralGeneral)(int32_t, int32_t,
int32_t);
typedef int32_t (*Prototype_Int32_GeneralGeneralInt32Int32)(int32_t, int32_t,
int32_t, int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt64Int32Int32)(int32_t, int64_t,
int32_t, int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt64Int32Int32Int32Int32)(
int32_t, int64_t, int32_t, int32_t, int32_t, int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt64Int32Int32Int32)(int32_t, int64_t,
int32_t, int32_t,
int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt64Int32Int64Int32)(int32_t, int64_t,
int32_t, int64_t,
int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt64Int32Int64General)(
int32_t, int64_t, int32_t, int64_t, int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt64Int64Int64)(int32_t, int64_t,
int64_t, int64_t);
typedef int32_t (*Prototype_Int32_GeneralInt64Int64Int64Int32)(int32_t, int64_t,
int64_t, int64_t,
int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt64Int64General)(int32_t, int64_t,
int64_t, int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt64Int64Int64General)(
int32_t, int64_t, int64_t, int64_t, int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt64Int64Int64Int32Int32)(
int32_t, int64_t, int64_t, int64_t, int32_t, int32_t);
typedef int32_t (*Prototype_General_GeneralInt32)(int32_t, int32_t);
typedef int32_t (*Prototype_General_GeneralInt32Int32)(int32_t, int32_t,
int32_t);
typedef int32_t (*Prototype_General_GeneralInt32General)(int32_t, int32_t,
int32_t);
typedef int32_t (*Prototype_General_GeneralInt32Int32GeneralInt32)(
int32_t, int32_t, int32_t, int32_t, int32_t);
typedef int32_t (*Prototype_Int32_GeneralGeneralInt32General)(int32_t, int32_t,
int32_t, int32_t);
typedef int32_t (*Prototype_Int32_GeneralGeneralInt32GeneralInt32Int32Int32)(
int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t);
typedef int32_t (*Prototype_Int32_GeneralGeneralInt32Int32Int32GeneralInt32)(
int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t);
typedef int64_t (*Prototype_Int64_General)(int32_t);
typedef int64_t (*Prototype_Int64_GeneralInt32)(int32_t, int32_t);
typedef int64_t (*Prototype_Int64_GeneralInt64)(int32_t, int64_t);
typedef int64_t (*Prototype_Int64_GeneralInt64Int32)(int32_t, int64_t, int32_t);
ABI_FUNCTION_TYPE_SIM_PROTOTYPES
// Fill the volatile registers with scratch values.
//
@ -2459,7 +2319,12 @@ typedef int64_t (*Prototype_Int64_GeneralInt64Int32)(int32_t, int64_t, int32_t);
// so for now the simulator does not scratch any float registers for these
// calls. Should try to narrow it further in future.
//
void Simulator::scratchVolatileRegisters(bool scratchFloat) {
void Simulator::scratchVolatileRegisters(void* target) {
// The ARM backend makes calls to __aeabi_idivmod and
// __aeabi_uidivmod assuming that the float registers are
// non-volatile as a performance optimization, so the float
// registers must not be scratch when calling these.
bool scratchFloat = target != __aeabi_idivmod && target != __aeabi_uidivmod;
int32_t scratch_value = 0xa5a5a5a5 ^ uint32_t(icount_);
set_register(r0, scratch_value);
set_register(r1, scratch_value);
@ -2491,21 +2356,23 @@ void Simulator::softwareInterrupt(SimInstruction* instr) {
switch (svc) {
case kCallRtRedirected: {
Redirection* redirection = Redirection::FromSwiInstruction(instr);
int32_t arg0 = get_register(r0);
int32_t arg1 = get_register(r1);
int32_t arg2 = get_register(r2);
int32_t arg3 = get_register(r3);
int32_t* stack_pointer = reinterpret_cast<int32_t*>(get_register(sp));
int32_t arg4 = stack_pointer[0];
int32_t arg5 = stack_pointer[1];
int32_t arg6 = stack_pointer[2];
int32_t arg7 = stack_pointer[3];
int32_t arg8 = stack_pointer[4];
int32_t arg9 = stack_pointer[5];
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 a0 = get_register(r0);
int32_t a1 = get_register(r1);
int32_t a2 = get_register(r2);
int32_t a3 = get_register(r3);
float s0, s1, s2, s3, s4;
get_float_from_s_register(0, &s0);
get_float_from_s_register(0, &s1);
get_float_from_s_register(0, &s2);
get_float_from_s_register(0, &s3);
get_float_from_s_register(0, &s4);
double d0, d1, d2, d3, d4;
get_double_from_d_register(0, &d0);
get_double_from_d_register(1, &d1);
get_double_from_d_register(2, &d2);
get_double_from_d_register(3, &d3);
get_double_from_d_register(4, &d4);
int32_t saved_lr = get_register(lr);
intptr_t external =
@ -2522,751 +2389,7 @@ void Simulator::softwareInterrupt(SimInstruction* instr) {
}
switch (redirection->type()) {
case Args_General0: {
Prototype_General0 target =
reinterpret_cast<Prototype_General0>(external);
int64_t result = target();
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_General1: {
Prototype_General1 target =
reinterpret_cast<Prototype_General1>(external);
int64_t result = target(arg0);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_General2: {
Prototype_General2 target =
reinterpret_cast<Prototype_General2>(external);
int64_t result = target(arg0, arg1);
// The ARM backend makes calls to __aeabi_idivmod and
// __aeabi_uidivmod assuming that the float registers are
// non-volatile as a performance optimization, so the float
// registers must not be scratch when calling these.
bool scratchFloat =
target != __aeabi_idivmod && target != __aeabi_uidivmod;
scratchVolatileRegisters(/* scratchFloat = */ scratchFloat);
setCallResult(result);
break;
}
case Args_General3: {
Prototype_General3 target =
reinterpret_cast<Prototype_General3>(external);
int64_t result = target(arg0, arg1, arg2);
scratchVolatileRegisters(/* scratchFloat = true*/);
setCallResult(result);
break;
}
case Args_General4: {
Prototype_General4 target =
reinterpret_cast<Prototype_General4>(external);
int64_t result = target(arg0, arg1, arg2, arg3);
scratchVolatileRegisters(/* scratchFloat = true*/);
setCallResult(result);
break;
}
case Args_General5: {
Prototype_General5 target =
reinterpret_cast<Prototype_General5>(external);
int64_t result = target(arg0, arg1, arg2, arg3, arg4);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_General6: {
Prototype_General6 target =
reinterpret_cast<Prototype_General6>(external);
int64_t result = target(arg0, arg1, arg2, arg3, arg4, arg5);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_General7: {
Prototype_General7 target =
reinterpret_cast<Prototype_General7>(external);
int32_t arg6 = stack_pointer[2];
int64_t result = target(arg0, arg1, arg2, arg3, arg4, arg5, arg6);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_General8: {
Prototype_General8 target =
reinterpret_cast<Prototype_General8>(external);
int32_t arg6 = stack_pointer[2];
int32_t arg7 = stack_pointer[3];
int64_t result =
target(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int_GeneralGeneralGeneralInt64: {
Prototype_GeneralGeneralGeneralInt64 target =
reinterpret_cast<Prototype_GeneralGeneralGeneralInt64>(external);
// The int64 arg is not split across register and stack
int64_t result = target(arg0, arg1, arg2, MakeInt64(arg4, arg5));
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int_GeneralGeneralInt64Int64: {
Prototype_GeneralGeneralInt64Int64 target =
reinterpret_cast<Prototype_GeneralGeneralInt64Int64>(external);
int64_t result =
target(arg0, arg1, MakeInt64(arg2, arg3), MakeInt64(arg4, arg5));
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int64_Double: {
double dval0, dval1;
int32_t ival;
getFpArgs(&dval0, &dval1, &ival);
Prototype_Int64_Double target =
reinterpret_cast<Prototype_Int64_Double>(external);
int64_t result = target(dval0);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Double_None: {
Prototype_Double_None target =
reinterpret_cast<Prototype_Double_None>(external);
double dresult = target();
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResultDouble(dresult);
break;
}
case Args_Int_Double: {
double dval0, dval1;
int32_t ival;
getFpArgs(&dval0, &dval1, &ival);
Prototype_Int_Double target =
reinterpret_cast<Prototype_Int_Double>(external);
int32_t res = target(dval0);
scratchVolatileRegisters(/* scratchFloat = true */);
set_register(r0, res);
break;
}
case Args_Int_Float32: {
float fval0;
if (UseHardFpABI()) {
get_float_from_s_register(0, &fval0);
} else {
fval0 = mozilla::BitwiseCast<float>(arg0);
}
auto target = reinterpret_cast<Prototype_Int_Float32>(external);
int32_t res = target(fval0);
scratchVolatileRegisters(/* scratchFloat = true */);
set_register(r0, res);
break;
}
case Args_Double_Double: {
double dval0, dval1;
int32_t ival;
getFpArgs(&dval0, &dval1, &ival);
Prototype_Double_Double target =
reinterpret_cast<Prototype_Double_Double>(external);
double dresult = target(dval0);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResultDouble(dresult);
break;
}
case Args_Float32_Float32: {
float fval0;
if (UseHardFpABI()) {
get_float_from_s_register(0, &fval0);
} else {
fval0 = mozilla::BitwiseCast<float>(arg0);
}
Prototype_Float32_Float32 target =
reinterpret_cast<Prototype_Float32_Float32>(external);
float fresult = target(fval0);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResultFloat(fresult);
break;
}
case Args_Float32_Float32Float32: {
float fval0, fval1;
if (UseHardFpABI()) {
get_float_from_s_register(0, &fval0);
get_float_from_s_register(1, &fval1);
} else {
fval0 = mozilla::BitwiseCast<float>(arg0);
fval1 = mozilla::BitwiseCast<float>(arg1);
}
Prototype_Float32_Float32Float32 target =
reinterpret_cast<Prototype_Float32_Float32Float32>(external);
float fresult = target(fval0, fval1);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResultFloat(fresult);
break;
}
case Args_Float32_IntInt: {
Prototype_Float32_IntInt target =
reinterpret_cast<Prototype_Float32_IntInt>(external);
float fresult = target(arg0, arg1);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResultFloat(fresult);
break;
}
case Args_Double_Int: {
Prototype_Double_Int target =
reinterpret_cast<Prototype_Double_Int>(external);
double dresult = target(arg0);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResultDouble(dresult);
break;
}
case Args_Double_IntInt: {
Prototype_Double_IntInt target =
reinterpret_cast<Prototype_Double_IntInt>(external);
double dresult = target(arg0, arg1);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResultDouble(dresult);
break;
}
case Args_Double_DoubleInt: {
double dval0, dval1;
int32_t ival;
getFpArgs(&dval0, &dval1, &ival);
Prototype_Double_DoubleInt target =
reinterpret_cast<Prototype_Double_DoubleInt>(external);
double dresult = target(dval0, ival);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResultDouble(dresult);
break;
}
case Args_Double_DoubleDouble: {
double dval0, dval1;
int32_t ival;
getFpArgs(&dval0, &dval1, &ival);
Prototype_Double_DoubleDouble target =
reinterpret_cast<Prototype_Double_DoubleDouble>(external);
double dresult = target(dval0, dval1);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResultDouble(dresult);
break;
}
case Args_Double_IntDouble: {
int32_t ival = get_register(0);
double dval0;
if (UseHardFpABI()) {
get_double_from_d_register(0, &dval0);
} else {
dval0 = get_double_from_register_pair(2);
}
Prototype_Double_IntDouble target =
reinterpret_cast<Prototype_Double_IntDouble>(external);
double dresult = target(ival, dval0);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResultDouble(dresult);
break;
}
case Args_Int_IntDouble: {
int32_t ival = get_register(0);
double dval0;
if (UseHardFpABI()) {
get_double_from_d_register(0, &dval0);
} else {
dval0 = get_double_from_register_pair(2);
}
Prototype_Int_IntDouble target =
reinterpret_cast<Prototype_Int_IntDouble>(external);
int32_t result = target(ival, dval0);
scratchVolatileRegisters(/* scratchFloat = true */);
set_register(r0, result);
break;
}
case Args_Int_DoubleInt: {
double dval;
int32_t result;
Prototype_Int_DoubleInt target =
reinterpret_cast<Prototype_Int_DoubleInt>(external);
if (UseHardFpABI()) {
get_double_from_d_register(0, &dval);
result = target(dval, arg0);
} else {
dval = get_double_from_register_pair(0);
result = target(dval, arg2);
}
scratchVolatileRegisters(/* scratchFloat = true */);
set_register(r0, result);
break;
}
case Args_Int_DoubleIntInt: {
double dval;
int32_t result;
Prototype_Int_DoubleIntInt target =
reinterpret_cast<Prototype_Int_DoubleIntInt>(external);
if (UseHardFpABI()) {
get_double_from_d_register(0, &dval);
result = target(dval, arg0, arg1);
} else {
dval = get_double_from_register_pair(0);
result = target(dval, arg2, arg3);
}
scratchVolatileRegisters(/* scratchFloat = true */);
set_register(r0, result);
break;
}
case Args_Int_IntDoubleIntInt: {
double dval;
int32_t result;
Prototype_Int_IntDoubleIntInt target =
reinterpret_cast<Prototype_Int_IntDoubleIntInt>(external);
if (UseHardFpABI()) {
get_double_from_d_register(0, &dval);
result = target(arg0, dval, arg1, arg2);
} else {
dval = get_double_from_register_pair(2);
result = target(arg0, dval, arg4, arg5);
}
scratchVolatileRegisters(/* scratchFloat = true */);
set_register(r0, result);
break;
}
case Args_Double_DoubleDoubleDouble: {
double dval0, dval1, dval2;
int32_t ival;
getFpArgs(&dval0, &dval1, &ival);
// the last argument is on stack
getFpFromStack(stack_pointer, &dval2);
Prototype_Double_DoubleDoubleDouble target =
reinterpret_cast<Prototype_Double_DoubleDoubleDouble>(external);
double dresult = target(dval0, dval1, dval2);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResultDouble(dresult);
break;
}
case Args_Double_DoubleDoubleDoubleDouble: {
double dval0, dval1, dval2, dval3;
int32_t ival;
getFpArgs(&dval0, &dval1, &ival);
// the two last arguments are on stack
getFpFromStack(stack_pointer, &dval2);
getFpFromStack(stack_pointer + 2, &dval3);
Prototype_Double_DoubleDoubleDoubleDouble target =
reinterpret_cast<Prototype_Double_DoubleDoubleDoubleDouble>(
external);
double dresult = target(dval0, dval1, dval2, dval3);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResultDouble(dresult);
break;
}
case Args_Int32_General: {
Prototype_Int32_General target =
reinterpret_cast<Prototype_Int32_General>(external);
int64_t result = target(arg0);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int32_GeneralInt32: {
Prototype_Int32_GeneralInt32 target =
reinterpret_cast<Prototype_Int32_GeneralInt32>(external);
int64_t result = target(arg0, arg1);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int32_GeneralInt32Int32: {
Prototype_Int32_GeneralInt32Int32 target =
reinterpret_cast<Prototype_Int32_GeneralInt32Int32>(external);
int64_t result = target(arg0, arg1, arg2);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int32_GeneralInt32Int32Int32: {
Prototype_Int32_GeneralInt32Int32Int32 target =
reinterpret_cast<Prototype_Int32_GeneralInt32Int32Int32>(
external);
int64_t result = target(arg0, arg1, arg2, arg3);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int32_GeneralInt32Int32Int32Int32: {
Prototype_Int32_GeneralInt32Int32Int32Int32 target =
reinterpret_cast<Prototype_Int32_GeneralInt32Int32Int32Int32>(
external);
int64_t result = target(arg0, arg1, arg2, arg3, arg4);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int32_GeneralInt32Int32Int32Int32Int32: {
Prototype_Int32_GeneralInt32Int32Int32Int32Int32 target =
reinterpret_cast<
Prototype_Int32_GeneralInt32Int32Int32Int32Int32>(external);
int64_t result = target(arg0, arg1, arg2, arg3, arg4, arg5);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int32_GeneralInt32Int32Int32Int32General: {
Prototype_Int32_GeneralInt32Int32Int32Int32General target =
reinterpret_cast<
Prototype_Int32_GeneralInt32Int32Int32Int32General>(external);
int64_t result = target(arg0, arg1, arg2, arg3, arg4, arg5);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int32_GeneralInt32Int32Int32Int32Int32Int32General: {
Prototype_Int32_GeneralInt32Int32Int32Int32Int32Int32General target =
reinterpret_cast<
Prototype_Int32_GeneralInt32Int32Int32Int32Int32Int32General>(
external);
int64_t result =
target(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int32_GeneralInt32Float32Float32Int32Int32Int32General: {
float fval0, fval1;
if (UseHardFpABI()) {
get_float_from_s_register(2, &fval0);
get_float_from_s_register(3, &fval1);
} else {
fval0 = mozilla::BitwiseCast<float>(arg2);
fval1 = mozilla::BitwiseCast<float>(arg3);
}
Prototype_Int32_GeneralInt32Float32Float32Int32Int32Int32General
target = reinterpret_cast<
Prototype_Int32_GeneralInt32Float32Float32Int32Int32Int32General>(
external);
int64_t result =
target(arg0, arg1, fval0, fval1, arg4, arg5, arg6, arg7);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int32_GeneralInt32Float32Float32Float32Float32Int32Int32Int32Int32General: {
float fval0, fval1, fval2, fval3;
if (UseHardFpABI()) {
get_float_from_s_register(2, &fval0);
get_float_from_s_register(3, &fval1);
get_float_from_s_register(4, &fval2);
get_float_from_s_register(5, &fval3);
} else {
fval0 = mozilla::BitwiseCast<float>(arg2);
fval1 = mozilla::BitwiseCast<float>(arg3);
fval2 = mozilla::BitwiseCast<float>(arg4);
fval3 = mozilla::BitwiseCast<float>(arg5);
}
Prototype_Int32_GeneralInt32Float32Float32Float32Float32Int32Int32Int32Int32General
target = reinterpret_cast<
Prototype_Int32_GeneralInt32Float32Float32Float32Float32Int32Int32Int32Int32General>(
external);
int64_t result = target(arg0, arg1, fval0, fval1, fval2, fval3, arg6,
arg7, arg8, arg9, arg10);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int32_GeneralInt32Float32Float32Int32Float32Float32Int32Float32Int32Int32Int32Int32General: {
float fval0, fval1, fval2, fval3, fval4;
if (UseHardFpABI()) {
get_float_from_s_register(2, &fval0);
get_float_from_s_register(3, &fval1);
get_float_from_s_register(5, &fval2);
get_float_from_s_register(6, &fval3);
get_float_from_s_register(8, &fval4);
} else {
fval0 = mozilla::BitwiseCast<float>(arg2);
fval1 = mozilla::BitwiseCast<float>(arg3);
fval2 = mozilla::BitwiseCast<float>(arg5);
fval3 = mozilla::BitwiseCast<float>(arg6);
fval4 = mozilla::BitwiseCast<float>(arg8);
}
Prototype_Int32_GeneralInt32Float32Float32Int32Float32Float32Int32Float32Int32Int32Int32Int32General
target = reinterpret_cast<
Prototype_Int32_GeneralInt32Float32Float32Int32Float32Float32Int32Float32Int32Int32Int32Int32General>(
external);
int64_t result =
target(arg0, arg1, fval0, fval1, arg4, fval2, fval3, arg7, fval4,
arg9, arg10, arg11, arg12, arg13);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int32_GeneralInt32Int32Int32General: {
Prototype_Int32_GeneralInt32Int32Int32General target =
reinterpret_cast<Prototype_Int32_GeneralInt32Int32Int32General>(
external);
int64_t result = target(arg0, arg1, arg2, arg3, arg4);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int32_GeneralInt32Int32General: {
Prototype_Int32_GeneralInt32Int32General target =
reinterpret_cast<Prototype_Int32_GeneralInt32Int32General>(
external);
int64_t result = target(arg0, arg1, arg2, arg3);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int32_GeneralInt32Int32Int64Int32: {
Prototype_Int32_GeneralInt32Int32Int64Int32 target =
reinterpret_cast<Prototype_Int32_GeneralInt32Int32Int64Int32>(
external);
int64_t result =
target(arg0, arg1, arg2, MakeInt64(arg4, arg5), arg6);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int32_GeneralInt32GeneralInt32: {
Prototype_Int32_GeneralInt32GeneralInt32 target =
reinterpret_cast<Prototype_Int32_GeneralInt32GeneralInt32>(
external);
int64_t result = target(arg0, arg1, arg2, arg3);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int32_GeneralInt32GeneralInt32Int32: {
Prototype_Int32_GeneralInt32GeneralInt32Int32 target =
reinterpret_cast<Prototype_Int32_GeneralInt32GeneralInt32Int32>(
external);
int64_t result = target(arg0, arg1, arg2, arg3, arg4);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int32_GeneralInt32Int64Int64Int32: {
Prototype_Int32_GeneralInt32Int64Int64Int32 target =
reinterpret_cast<Prototype_Int32_GeneralInt32Int64Int64Int32>(
external);
int64_t result = target(arg0, arg1, MakeInt64(arg2, arg3),
MakeInt64(arg4, arg5), arg6);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int32_GeneralGeneral: {
Prototype_Int32_GeneralGeneral target =
reinterpret_cast<Prototype_Int32_GeneralGeneral>(external);
int64_t result = target(arg0, arg1);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int32_GeneralGeneralGeneral: {
Prototype_Int32_GeneralGeneralGeneral target =
reinterpret_cast<Prototype_Int32_GeneralGeneralGeneral>(external);
int64_t result = target(arg0, arg1, arg2);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int32_GeneralGeneralInt32Int32: {
Prototype_Int32_GeneralGeneralInt32Int32 target =
reinterpret_cast<Prototype_Int32_GeneralGeneralInt32Int32>(
external);
int64_t result = target(arg0, arg1, arg2, arg3);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int32_GeneralInt64Int32Int32: {
Prototype_Int32_GeneralInt64Int32Int32 target =
reinterpret_cast<Prototype_Int32_GeneralInt64Int32Int32>(
external);
int64_t result = target(arg0, MakeInt64(arg2, arg3), arg4, arg5);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int32_GeneralInt64Int32Int32Int32Int32: {
Prototype_Int32_GeneralInt64Int32Int32Int32Int32 target =
reinterpret_cast<
Prototype_Int32_GeneralInt64Int32Int32Int32Int32>(external);
int64_t result =
target(arg0, MakeInt64(arg2, arg3), arg4, arg5, arg6, arg7);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int32_GeneralInt64Int32Int64Int32: {
Prototype_Int32_GeneralInt64Int32Int64Int32 target =
reinterpret_cast<Prototype_Int32_GeneralInt64Int32Int64Int32>(
external);
int64_t result = target(arg0, MakeInt64(arg2, arg3), arg4,
MakeInt64(arg6, arg7), arg8);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int32_GeneralInt64Int32Int64General: {
Prototype_Int32_GeneralInt64Int32Int64General target =
reinterpret_cast<Prototype_Int32_GeneralInt64Int32Int64General>(
external);
int64_t result = target(arg0, MakeInt64(arg2, arg3), arg4,
MakeInt64(arg6, arg7), arg8);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int32_GeneralInt64Int64Int64: {
Prototype_Int32_GeneralInt64Int64Int64 target =
reinterpret_cast<Prototype_Int32_GeneralInt64Int64Int64>(
external);
int64_t result = target(arg0, MakeInt64(arg2, arg3),
MakeInt64(arg4, arg5), MakeInt64(arg6, arg7));
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int32_GeneralInt64Int64Int64Int32: {
Prototype_Int32_GeneralInt64Int64Int64Int32 target =
reinterpret_cast<Prototype_Int32_GeneralInt64Int64Int64Int32>(
external);
int64_t result =
target(arg0, MakeInt64(arg2, arg3), MakeInt64(arg4, arg5),
MakeInt64(arg6, arg7), arg8);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int32_GeneralInt64Int64General: {
Prototype_Int32_GeneralInt64Int64General target =
reinterpret_cast<Prototype_Int32_GeneralInt64Int64General>(
external);
int64_t result =
target(arg0, MakeInt64(arg2, arg3), MakeInt64(arg4, arg5), arg6);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int32_GeneralInt64Int64Int64General: {
Prototype_Int32_GeneralInt64Int64Int64General target =
reinterpret_cast<Prototype_Int32_GeneralInt64Int64Int64General>(
external);
int64_t result =
target(arg0, MakeInt64(arg2, arg3), MakeInt64(arg4, arg5),
MakeInt64(arg6, arg7), arg8);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int32_GeneralInt64Int64Int64Int32Int32: {
Prototype_Int32_GeneralInt64Int64Int64Int32Int32 target =
reinterpret_cast<
Prototype_Int32_GeneralInt64Int64Int64Int32Int32>(external);
int64_t result =
target(arg0, MakeInt64(arg2, arg3), MakeInt64(arg4, arg5),
MakeInt64(arg6, arg7), arg8, arg9);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_General_GeneralInt32: {
Prototype_General_GeneralInt32 target =
reinterpret_cast<Prototype_General_GeneralInt32>(external);
int64_t result = target(arg0, arg1);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_General_GeneralInt32Int32: {
Prototype_General_GeneralInt32Int32 target =
reinterpret_cast<Prototype_General_GeneralInt32Int32>(external);
int64_t result = target(arg0, arg1, arg2);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_General_GeneralInt32General: {
Prototype_General_GeneralInt32General target =
reinterpret_cast<Prototype_General_GeneralInt32General>(external);
int64_t result = target(arg0, arg1, arg2);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case js::jit::Args_General_GeneralInt32Int32GeneralInt32: {
Prototype_General_GeneralInt32Int32GeneralInt32 target =
reinterpret_cast<Prototype_General_GeneralInt32Int32GeneralInt32>(
external);
int64_t result = target(arg0, arg1, arg2, arg3, arg4);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case js::jit::Args_Int32_GeneralGeneralInt32General: {
Prototype_Int32_GeneralGeneralInt32General target =
reinterpret_cast<Prototype_Int32_GeneralGeneralInt32General>(
external);
int64_t result = target(arg0, arg1, arg2, arg3);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case js::jit::Args_Int32_GeneralGeneralInt32GeneralInt32Int32Int32: {
Prototype_Int32_GeneralGeneralInt32GeneralInt32Int32Int32 target =
reinterpret_cast<
Prototype_Int32_GeneralGeneralInt32GeneralInt32Int32Int32>(
external);
int64_t result = target(arg0, arg1, arg2, arg3, arg4, arg5, arg6);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
// So many Generals, but no Colonels or Sargeants anywhere to be seen.
case js::jit::Args_Int32_GeneralGeneralInt32Int32Int32GeneralInt32: {
Prototype_Int32_GeneralGeneralInt32Int32Int32GeneralInt32 target =
reinterpret_cast<
Prototype_Int32_GeneralGeneralInt32Int32Int32GeneralInt32>(
external);
int64_t result = target(arg0, arg1, arg2, arg3, arg4, arg5, arg6);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int64_General: {
Prototype_Int64_General target =
reinterpret_cast<Prototype_Int64_General>(external);
int64_t result = target(arg0);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int64_GeneralInt32: {
Prototype_Int64_GeneralInt32 target =
reinterpret_cast<Prototype_Int64_GeneralInt32>(external);
int64_t result = target(arg0, arg1);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int64_GeneralInt64: {
Prototype_Int64_GeneralInt64 target =
reinterpret_cast<Prototype_Int64_GeneralInt64>(external);
int64_t result = target(arg0, MakeInt64(arg2, arg3));
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
case Args_Int64_GeneralInt64Int32: {
Prototype_Int64_GeneralInt64Int32 target =
reinterpret_cast<Prototype_Int64_GeneralInt64Int32>(external);
int64_t result = target(arg0, MakeInt64(arg2, arg3), arg4);
scratchVolatileRegisters(/* scratchFloat = true */);
setCallResult(result);
break;
}
ABI_FUNCTION_TYPE_ARM32_SIM_DISPATCH
default:
MOZ_CRASH("call");
}

Просмотреть файл

@ -472,7 +472,7 @@ class Simulator {
void setCallResultDouble(double result);
void setCallResultFloat(float result);
void setCallResult(int64_t res);
void scratchVolatileRegisters(bool scratchFloat = true);
void scratchVolatileRegisters(void* target = nullptr);
template <class ReturnType, int register_size>
void getFromVFPRegister(int reg_index, ReturnType* out);

Просмотреть файл

@ -487,226 +487,7 @@ void Simulator::setFP64Result(double result) {
set_dreg(0, result);
}
typedef int64_t (*Prototype_General0)();
typedef int64_t (*Prototype_General1)(int64_t arg0);
typedef int64_t (*Prototype_General2)(int64_t arg0, int64_t arg1);
typedef int64_t (*Prototype_General3)(int64_t arg0, int64_t arg1, int64_t arg2);
typedef int64_t (*Prototype_General4)(int64_t arg0, int64_t arg1, int64_t arg2, int64_t arg3);
typedef int64_t (*Prototype_General5)(int64_t arg0, int64_t arg1, int64_t arg2, int64_t arg3,
int64_t arg4);
typedef int64_t (*Prototype_General6)(int64_t arg0, int64_t arg1, int64_t arg2, int64_t arg3,
int64_t arg4, int64_t arg5);
typedef int64_t (*Prototype_General7)(int64_t arg0, int64_t arg1, int64_t arg2, int64_t arg3,
int64_t arg4, int64_t arg5, int64_t arg6);
typedef int64_t (*Prototype_General8)(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 (*Prototype_GeneralGeneralGeneralInt64)(int64_t arg0, int64_t arg1, int64_t arg2,
int64_t arg3);
typedef int64_t (*Prototype_GeneralGeneralInt64Int64)(int64_t arg0, int64_t arg1, int64_t arg2,
int64_t arg3);
typedef int64_t (*Prototype_Int_Double)(double arg0);
typedef int64_t (*Prototype_Int_IntDouble)(int64_t arg0, double arg1);
typedef int64_t (*Prototype_Int_DoubleInt)(double arg0, int64_t arg1);
typedef int64_t (*Prototype_Int_DoubleIntInt)(double arg0, uint64_t arg1, uint64_t arg2);
typedef int64_t (*Prototype_Int_IntDoubleIntInt)(uint64_t arg0, double arg1,
uint64_t arg2, uint64_t arg3);
typedef float (*Prototype_Float32_Float32)(float arg0);
typedef int64_t (*Prototype_Int_Float32)(float arg0);
typedef float (*Prototype_Float32_Float32Float32)(float arg0, float arg1);
typedef double (*Prototype_Double_None)();
typedef double (*Prototype_Double_Double)(double arg0);
typedef double (*Prototype_Double_Int)(int64_t arg0);
typedef double (*Prototype_Double_DoubleInt)(double arg0, int64_t arg1);
typedef double (*Prototype_Double_IntDouble)(int64_t arg0, double arg1);
typedef double (*Prototype_Double_DoubleDouble)(double arg0, double arg1);
typedef double (*Prototype_Double_DoubleDoubleDouble)(double arg0, double arg1, double arg2);
typedef double (*Prototype_Double_DoubleDoubleDoubleDouble)(double arg0, double arg1,
double arg2, double arg3);
typedef int32_t (*Prototype_Int32_General)(int64_t);
typedef int32_t (*Prototype_Int32_GeneralInt32)(int64_t, int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt32Int32)(int64_t, int32_t, int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt32Int32Int32)(int64_t,
int32_t,
int32_t,
int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt32Int32Int32Int32)(int64_t,
int32_t,
int32_t,
int32_t,
int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt32Int32Int32Int32Int32)(int64_t,
int32_t,
int32_t,
int32_t,
int32_t,
int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt32Int32Int32Int32General)(int64_t,
int32_t,
int32_t,
int32_t,
int32_t,
int64_t);
typedef int32_t (*Prototype_Int32_GeneralInt32Int32Int32Int32Int32Int32General)(int64_t,
int32_t,
int32_t,
int32_t,
int32_t,
int32_t,
int32_t,
int64_t);
typedef int32_t (*Prototype_Int32_GeneralInt32Float32Float32Int32Int32Int32General)(int64_t,
int32_t,
float,
float,
int32_t,
int32_t,
int32_t,
int64_t);
typedef int32_t (*Prototype_Int32_GeneralInt32Float32Float32Float32Float32Int32Int32Int32Int32General)(int64_t,
int32_t,
float,
float,
float,
float,
int32_t,
int32_t,
int32_t,
int32_t,
int64_t);
typedef int32_t (*Prototype_Int32_GeneralInt32Float32Float32Int32Float32Float32Int32Float32Int32Int32Int32Int32General)(int64_t,
int32_t,
float,
float,
int32_t,
float,
float,
int32_t,
float,
int32_t,
int32_t,
int32_t,
int32_t,
int64_t);
typedef int32_t (*Prototype_Int32_GeneralInt32Int32Int32General)(int64_t,
int32_t,
int32_t,
int32_t,
int64_t);
typedef int32_t (*Prototype_Int32_GeneralInt32Int32General)(int64_t,
int32_t,
int32_t,
int64_t);
typedef int32_t (*Prototype_Int32_GeneralInt32Int32Int64Int32)(int64_t,
int32_t,
int32_t,
int64_t,
int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt32Int64Int64)(int64_t,
int32_t,
int32_t,
int64_t);
typedef int32_t (*Prototype_Int32_GeneralInt32GeneralInt32)(int64_t,
int32_t,
int64_t,
int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt32GeneralInt32Int32)(int64_t,
int32_t,
int64_t,
int32_t,
int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt32Int64Int64Int32)(int64_t,
int32_t,
int64_t,
int64_t,
int32_t);
typedef int32_t (*Prototype_Int32_GeneralGeneral)(int64_t, int64_t);
typedef int32_t (*Prototype_Int32_GeneralGeneralGeneral)(int64_t,
int64_t,
int64_t);
typedef int32_t (*Prototype_Int32_GeneralGeneralInt32Int32)(int64_t,
int64_t,
int32_t,
int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt64Int32Int32Int32)(int64_t, int64_t,
int32_t, int32_t,
int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt64Int32Int32)(int64_t,
int64_t,
int32_t,
int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt64Int32Int32Int32Int32)(int64_t,
int64_t,
int32_t,
int32_t,
int32_t,
int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt64Int32Int64Int32)(int64_t,
int64_t,
int32_t,
int64_t,
int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt64Int32Int64General)(int64_t, int64_t,
int32_t, int64_t,
int64_t);
typedef int32_t (*Prototype_Int32_GeneralInt64Int64Int64)(int64_t, int64_t,
int64_t, int64_t);
typedef int32_t (*Prototype_Int32_GeneralInt64Int64Int64Int32)(int64_t,
int64_t,
int64_t,
int64_t,
int32_t);
typedef int32_t (*Prototype_Int32_GeneralInt64Int64General)(int64_t, int64_t,
int64_t, int64_t);
typedef int32_t (*Prototype_Int32_GeneralInt64Int64Int64General)(int64_t, int64_t,
int64_t, int64_t,
int64_t);
typedef int32_t (*Prototype_Int32_GeneralInt64Int64Int64Int32Int32)(int64_t,
int64_t,
int64_t,
int64_t,
int32_t,
int32_t);
typedef int64_t (*Prototype_General_GeneralInt32)(int64_t, int32_t);
typedef int64_t (*Prototype_General_GeneralInt32Int32)(int64_t,
int32_t,
int32_t);
typedef int64_t (*Prototype_General_GeneralInt32General)(int64_t,
int32_t,
int64_t);
typedef int64_t (*Prototype_General_GeneralInt32Int32GeneralInt32)(int64_t,
int32_t,
int32_t,
int64_t,
int32_t);
typedef int32_t (*Prototype_Int32_GeneralGeneralInt32GeneralInt32Int32Int32)(
int64_t,
int64_t,
int32_t,
int64_t,
int32_t,
int32_t,
int32_t);
typedef int32_t (*Prototype_Int32_GeneralGeneralInt32Int32Int32GeneralInt32)(
int64_t,
int64_t,
int32_t,
int32_t,
int32_t,
int64_t,
int32_t);
typedef int32_t (*Prototype_Int32_GeneralGeneralInt32General)(int64_t,
int64_t,
int32_t,
int64_t);
typedef int64_t (*Prototype_Int64_General)(int64_t);
typedef int64_t (*Prototype_Int64_GeneralInt32)(int64_t, int32_t);
typedef int64_t (*Prototype_Int64_GeneralInt64)(int64_t, int64_t);
typedef int64_t (*Prototype_Int64_GeneralInt64Int32)(int64_t, int64_t, int32_t);
ABI_FUNCTION_TYPE_SIM_PROTOTYPES
// Simulator support for callWithABI().
void
@ -736,6 +517,8 @@ Simulator::VisitCallRedirection(const Instruction* instr)
DebugOnly<int64_t> x29 = xreg(29);
DebugOnly<int64_t> savedSP = get_sp();
// Get the SP for reading stack arguments
int64_t* sp = reinterpret_cast<int64_t*>(get_sp());
// Remember LR for returning from the "call".
int64_t savedLR = xreg(30);
@ -752,7 +535,6 @@ Simulator::VisitCallRedirection(const Instruction* instr)
int64_t x5 = xreg(5);
int64_t x6 = xreg(6);
int64_t x7 = xreg(7);
int64_t x8 = xreg(8);
double d0 = dreg(0);
double d1 = dreg(1);
double d2 = dreg(2);
@ -765,414 +547,7 @@ Simulator::VisitCallRedirection(const Instruction* instr)
// Dispatch the call and set the return value.
switch (redir->type()) {
// Cases with int64_t return type.
case js::jit::Args_General0: {
int64_t ret = reinterpret_cast<Prototype_General0>(nativeFn)();
setGPR64Result(ret);
break;
}
case js::jit::Args_General1: {
int64_t ret = reinterpret_cast<Prototype_General1>(nativeFn)(x0);
setGPR64Result(ret);
break;
}
case js::jit::Args_General2: {
int64_t ret = reinterpret_cast<Prototype_General2>(nativeFn)(x0, x1);
setGPR64Result(ret);
break;
}
case js::jit::Args_General3: {
int64_t ret = reinterpret_cast<Prototype_General3>(nativeFn)(x0, x1, x2);
setGPR64Result(ret);
break;
}
case js::jit::Args_General4: {
int64_t ret = reinterpret_cast<Prototype_General4>(nativeFn)(x0, x1, x2, x3);
setGPR64Result(ret);
break;
}
case js::jit::Args_General5: {
int64_t ret = reinterpret_cast<Prototype_General5>(nativeFn)(x0, x1, x2, x3, x4);
setGPR64Result(ret);
break;
}
case js::jit::Args_General6: {
int64_t ret = reinterpret_cast<Prototype_General6>(nativeFn)(x0, x1, x2, x3, x4, x5);
setGPR64Result(ret);
break;
}
case js::jit::Args_General7: {
int64_t ret = reinterpret_cast<Prototype_General7>(nativeFn)(x0, x1, x2, x3, x4, x5, x6);
setGPR64Result(ret);
break;
}
case js::jit::Args_General8: {
int64_t ret = reinterpret_cast<Prototype_General8>(nativeFn)(x0, x1, x2, x3, x4, x5, x6, x7);
setGPR64Result(ret);
break;
}
case js::jit::Args_Int_GeneralGeneralGeneralInt64: {
int64_t ret = reinterpret_cast<Prototype_GeneralGeneralGeneralInt64>(nativeFn)(x0, x1, x2, x3);
setGPR64Result(ret);
break;
}
case js::jit::Args_Int_GeneralGeneralInt64Int64: {
int64_t ret = reinterpret_cast<Prototype_GeneralGeneralInt64Int64>(nativeFn)(x0, x1, x2, x3);
setGPR64Result(ret);
break;
}
// Cases with GPR return type. This can be int32 or int64, but int64 is a safer assumption.
case js::jit::Args_Int_Double: {
int64_t ret = reinterpret_cast<Prototype_Int_Double>(nativeFn)(d0);
setGPR64Result(ret);
break;
}
case js::jit::Args_Int_IntDouble: {
int64_t ret = reinterpret_cast<Prototype_Int_IntDouble>(nativeFn)(x0, d0);
setGPR64Result(ret);
break;
}
case js::jit::Args_Int_DoubleInt: {
int64_t ret = reinterpret_cast<Prototype_Int_DoubleInt>(nativeFn)(d0, x0);
setGPR64Result(ret);
break;
}
case js::jit::Args_Int_IntDoubleIntInt: {
int64_t ret = reinterpret_cast<Prototype_Int_IntDoubleIntInt>(nativeFn)(x0, d0, x1, x2);
setGPR64Result(ret);
break;
}
case js::jit::Args_Int_DoubleIntInt: {
int64_t ret = reinterpret_cast<Prototype_Int_DoubleIntInt>(nativeFn)(d0, x0, x1);
setGPR64Result(ret);
break;
}
// Cases with float return type.
case js::jit::Args_Float32_Float32: {
float ret = reinterpret_cast<Prototype_Float32_Float32>(nativeFn)(s0);
setFP32Result(ret);
break;
}
case js::jit::Args_Int_Float32: {
int64_t ret = reinterpret_cast<Prototype_Int_Float32>(nativeFn)(s0);
setGPR64Result(ret);
break;
}
case js::jit::Args_Float32_Float32Float32: {
float ret = reinterpret_cast<Prototype_Float32_Float32Float32>(nativeFn)(s0, s1);
setFP32Result(ret);
break;
}
// Cases with double return type.
case js::jit::Args_Double_None: {
double ret = reinterpret_cast<Prototype_Double_None>(nativeFn)();
setFP64Result(ret);
break;
}
case js::jit::Args_Double_Double: {
double ret = reinterpret_cast<Prototype_Double_Double>(nativeFn)(d0);
setFP64Result(ret);
break;
}
case js::jit::Args_Double_Int: {
double ret = reinterpret_cast<Prototype_Double_Int>(nativeFn)(x0);
setFP64Result(ret);
break;
}
case js::jit::Args_Double_DoubleInt: {
double ret = reinterpret_cast<Prototype_Double_DoubleInt>(nativeFn)(d0, x0);
setFP64Result(ret);
break;
}
case js::jit::Args_Double_DoubleDouble: {
double ret = reinterpret_cast<Prototype_Double_DoubleDouble>(nativeFn)(d0, d1);
setFP64Result(ret);
break;
}
case js::jit::Args_Double_DoubleDoubleDouble: {
double ret = reinterpret_cast<Prototype_Double_DoubleDoubleDouble>(nativeFn)(d0, d1, d2);
setFP64Result(ret);
break;
}
case js::jit::Args_Double_DoubleDoubleDoubleDouble: {
double ret = reinterpret_cast<Prototype_Double_DoubleDoubleDoubleDouble>(nativeFn)(d0, d1, d2, d3);
setFP64Result(ret);
break;
}
case js::jit::Args_Double_IntDouble: {
double ret = reinterpret_cast<Prototype_Double_IntDouble>(nativeFn)(x0, d0);
setFP64Result(ret);
break;
}
case js::jit::Args_Int32_General: {
int32_t ret = reinterpret_cast<Prototype_Int32_General>(nativeFn)(x0);
setGPR32Result(ret);
break;
}
case js::jit::Args_Int32_GeneralInt32: {
int32_t ret =
reinterpret_cast<Prototype_Int32_GeneralInt32>(nativeFn)(x0, x1);
setGPR32Result(ret);
break;
}
case js::jit::Args_Int32_GeneralInt32Int32: {
int32_t ret = reinterpret_cast<Prototype_Int32_GeneralInt32Int32>(
nativeFn)(x0, x1, x2);
setGPR32Result(ret);
break;
}
case js::jit::Args_Int32_GeneralInt32Int32Int32: {
int32_t ret = reinterpret_cast<Prototype_Int32_GeneralInt32Int32Int32>(
nativeFn)(x0, x1, x2, x3);
setGPR32Result(ret);
break;
}
case js::jit::Args_Int32_GeneralInt32Int32Int32Int32: {
int32_t ret =
reinterpret_cast<Prototype_Int32_GeneralInt32Int32Int32Int32>(
nativeFn)(x0, x1, x2, x3, x4);
setGPR32Result(ret);
break;
}
case js::jit::Args_Int32_GeneralInt32Int32Int32Int32Int32: {
int32_t ret =
reinterpret_cast<Prototype_Int32_GeneralInt32Int32Int32Int32Int32>(
nativeFn)(x0, x1, x2, x3, x4, x5);
setGPR32Result(ret);
break;
}
case js::jit::Args_Int32_GeneralInt32Int32Int32Int32General: {
int32_t ret =
reinterpret_cast<Prototype_Int32_GeneralInt32Int32Int32Int32General>(
nativeFn)(x0, x1, x2, x3, x4, x5);
setGPR32Result(ret);
break;
}
case js::jit::Args_Int32_GeneralInt32Int32Int32Int32Int32Int32General: {
int32_t ret =
reinterpret_cast<Prototype_Int32_GeneralInt32Int32Int32Int32Int32Int32General>(
nativeFn)(x0, x1, x2, x3, x4, x5, x6, x7);
setGPR32Result(ret);
break;
}
case js::jit::Args_Int32_GeneralInt32Float32Float32Int32Int32Int32General: {
int32_t ret =
reinterpret_cast<Prototype_Int32_GeneralInt32Float32Float32Int32Int32Int32General>(
nativeFn)(x0, x1, s0, s1, x2, x3, x4, x5);
setGPR32Result(ret);
break;
}
case js::jit::Args_Int32_GeneralInt32Float32Float32Float32Float32Int32Int32Int32Int32General: {
int32_t ret =
reinterpret_cast<Prototype_Int32_GeneralInt32Float32Float32Float32Float32Int32Int32Int32Int32General>(
nativeFn)(x0, x1, s0, s1, s2, s3, x2, x3, x4, x5, x6);
setGPR32Result(ret);
break;
}
case js::jit::Args_Int32_GeneralInt32Float32Float32Int32Float32Float32Int32Float32Int32Int32Int32Int32General: {
int32_t ret =
reinterpret_cast<Prototype_Int32_GeneralInt32Float32Float32Int32Float32Float32Int32Float32Int32Int32Int32Int32General>(
nativeFn)(x0, x1, s0, s1, x2, s2, s3, x3, s4, x4, x5, x6, x7, x8);
setGPR32Result(ret);
break;
}
case js::jit::Args_Int32_GeneralInt32Int32Int32General: {
int32_t ret =
reinterpret_cast<Prototype_Int32_GeneralInt32Int32Int32General>(
nativeFn)(x0, x1, x2, x3, x4);
setGPR32Result(ret);
break;
}
case js::jit::Args_Int32_GeneralInt32Int32General: {
int32_t ret = reinterpret_cast<Prototype_Int32_GeneralInt32Int32General>(
nativeFn)(x0, x1, x2, x3);
setGPR32Result(ret);
break;
}
case js::jit::Args_Int32_GeneralInt32Int32Int64Int32: {
int32_t ret =
reinterpret_cast<Prototype_Int32_GeneralInt32Int32Int64Int32>(
nativeFn)(x0, x1, x2, x3, x4);
setGPR32Result(ret);
break;
}
case js::jit::Args_Int32_GeneralInt32GeneralInt32: {
int32_t ret = reinterpret_cast<Prototype_Int32_GeneralInt32GeneralInt32>(
nativeFn)(x0, x1, x2, x3);
setGPR32Result(ret);
break;
}
case js::jit::Args_Int32_GeneralInt32GeneralInt32Int32: {
int32_t ret =
reinterpret_cast<Prototype_Int32_GeneralInt32GeneralInt32Int32>(
nativeFn)(x0, x1, x2, x3, x4);
setGPR32Result(ret);
break;
}
case js::jit::Args_Int32_GeneralInt32Int64Int64Int32: {
int32_t ret =
reinterpret_cast<Prototype_Int32_GeneralInt32Int64Int64Int32>(
nativeFn)(x0, x1, x2, x3, x4);
setGPR32Result(ret);
break;
}
case js::jit::Args_Int32_GeneralGeneral: {
int32_t ret =
reinterpret_cast<Prototype_Int32_GeneralGeneral>(nativeFn)(x0, x1);
setGPR32Result(ret);
break;
}
case js::jit::Args_Int32_GeneralGeneralGeneral: {
int32_t ret = reinterpret_cast<Prototype_Int32_GeneralGeneralGeneral>(
nativeFn)(x0, x1, x2);
setGPR32Result(ret);
break;
}
case js::jit::Args_Int32_GeneralGeneralInt32Int32: {
int32_t ret = reinterpret_cast<Prototype_Int32_GeneralGeneralInt32Int32>(
nativeFn)(x0, x1, x2, x3);
setGPR32Result(ret);
break;
}
case js::jit::Args_Int32_GeneralInt64Int32Int32: {
int32_t ret = reinterpret_cast<Prototype_Int32_GeneralInt64Int32Int32>(
nativeFn)(x0, x1, x2, x3);
setGPR32Result(ret);
break;
}
case js::jit::Args_Int32_GeneralInt64Int32Int32Int32Int32: {
int32_t ret =
reinterpret_cast<Prototype_Int32_GeneralInt64Int32Int32Int32Int32>(
nativeFn)(x0, x1, x2, x3, x4, x5);
setGPR32Result(ret);
break;
}
case js::jit::Args_Int32_GeneralInt64Int32Int64Int32: {
int32_t ret =
reinterpret_cast<Prototype_Int32_GeneralInt64Int32Int64Int32>(
nativeFn)(x0, x1, x2, x3, x4);
setGPR32Result(ret);
break;
}
case js::jit::Args_Int32_GeneralInt64Int32Int64General: {
int32_t ret = reinterpret_cast<Prototype_Int32_GeneralInt64Int32Int64General>(
nativeFn)(x0, x1, x2, x3, x4);
setGPR32Result(ret);
break;
}
case js::jit::Args_Int32_GeneralInt64Int64Int64: {
int32_t ret = reinterpret_cast<Prototype_Int32_GeneralInt64Int64Int64>(
nativeFn)(x0, x1, x2, x3);
setGPR32Result(ret);
break;
}
case js::jit::Args_Int32_GeneralInt64Int64Int64Int32: {
int32_t ret =
reinterpret_cast<Prototype_Int32_GeneralInt64Int64Int64Int32>(
nativeFn)(x0, x1, x2, x3, x4);
setGPR32Result(ret);
break;
}
case js::jit::Args_Int32_GeneralInt64Int64General: {
int32_t ret = reinterpret_cast<Prototype_Int32_GeneralInt64Int64General>(
nativeFn)(x0, x1, x2, x3);
setGPR32Result(ret);
break;
}
case js::jit::Args_Int32_GeneralInt64Int64Int64General: {
int32_t ret = reinterpret_cast<Prototype_Int32_GeneralInt64Int64Int64General>(
nativeFn)(x0, x1, x2, x3, x4);
setGPR32Result(ret);
break;
}
case js::jit::Args_Int32_GeneralInt64Int64Int64Int32Int32: {
int32_t ret =
reinterpret_cast<Prototype_Int32_GeneralInt64Int64Int64Int32Int32>(
nativeFn)(x0, x1, x2, x3, x4, x5);
setGPR32Result(ret);
break;
}
case js::jit::Args_General_GeneralInt32: {
int64_t ret =
reinterpret_cast<Prototype_General_GeneralInt32>(nativeFn)(x0, x1);
setGPR64Result(ret);
break;
}
case js::jit::Args_General_GeneralInt32Int32: {
int64_t ret = reinterpret_cast<Prototype_General_GeneralInt32Int32>(
nativeFn)(x0, x1, x2);
setGPR64Result(ret);
break;
}
case js::jit::Args_General_GeneralInt32General: {
int64_t ret =
reinterpret_cast<Prototype_General_GeneralInt32General>(
nativeFn)(x0, x1, x2);
setGPR64Result(ret);
break;
}
case js::jit::Args_General_GeneralInt32Int32GeneralInt32: {
int64_t ret =
reinterpret_cast<Prototype_General_GeneralInt32Int32GeneralInt32>(
nativeFn)(x0, x1, x2, x3, x4);
setGPR64Result(ret);
break;
}
case js::jit::Args_Int32_GeneralGeneralInt32GeneralInt32Int32Int32: {
int32_t ret = reinterpret_cast<
Prototype_Int32_GeneralGeneralInt32GeneralInt32Int32Int32>(nativeFn)(
x0, x1, x2, x3, x4, x5, x6);
setGPR32Result(ret);
break;
}
case js::jit::Args_Int32_GeneralGeneralInt32Int32Int32GeneralInt32: {
int32_t ret = reinterpret_cast<
Prototype_Int32_GeneralGeneralInt32Int32Int32GeneralInt32>(nativeFn)(
x0, x1, x2, x3, x4, x5, x6);
setGPR32Result(ret);
break;
}
case js::jit::Args_Int32_GeneralGeneralInt32General: {
int32_t ret =
reinterpret_cast<Prototype_Int32_GeneralGeneralInt32General>(
nativeFn)(x0, x1, x2, x3);
setGPR32Result(ret);
break;
}
case js::jit::Args_Int64_General: {
int64_t ret =
reinterpret_cast<Prototype_Int64_General>(
nativeFn)(x0);
setGPR64Result(ret);
break;
}
case js::jit::Args_Int64_GeneralInt32: {
int64_t ret =
reinterpret_cast<Prototype_Int64_GeneralInt32>(nativeFn)(x0, x1);
setGPR64Result(ret);
break;
}
case js::jit::Args_Int64_GeneralInt64: {
int64_t ret =
reinterpret_cast<Prototype_Int64_GeneralInt64>(
nativeFn)(x0, x1);
setGPR64Result(ret);
break;
}
case js::jit::Args_Int64_GeneralInt64Int32: {
int64_t ret = reinterpret_cast<Prototype_Int64_GeneralInt64Int32>(
nativeFn)(x0, x1, x2);
setGPR64Result(ret);
break;
}
ABI_FUNCTION_TYPE_ARM64_SIM_DISPATCH
default:
MOZ_CRASH("Unknown function type.");

Просмотреть файл

@ -260,6 +260,13 @@ elif CONFIG["JS_CODEGEN_WASM32"]:
"wasm32/Trampoline-wasm32.cpp",
]
# Generate jit/ABIFunctionTypeGenerated.h from jit/ABIFunctionType.yaml
GeneratedFile(
"ABIFunctionTypeGenerated.h",
script="GenerateABIFunctionType.py",
inputs=["ABIFunctionType.yaml"],
)
# Generate jit/MIROpsGenerated.h from jit/MIROps.yaml
GeneratedFile(
"MIROpsGenerated.h",

Просмотреть файл

@ -453,10 +453,13 @@ ABIArgType ToABIType(MIRType type) {
ABIFunctionType ToABIType(const SymbolicAddressSignature& sig) {
MOZ_ASSERT_IF(sig.failureMode != FailureMode::Infallible,
ToABIType(sig.failureMode) == ToABIType(sig.retType));
int abiType = ToABIType(sig.retType) << RetType_Shift;
int abiType = 0;
for (int i = 0; i < sig.numArgs; i++) {
abiType |= (ToABIType(sig.argTypes[i]) << (ArgType_Shift * (i + 1)));
abiType <<= ArgType_Shift;
abiType |= ToABIType(sig.argTypes[i]);
}
abiType <<= ArgType_Shift;
abiType |= ToABIType(sig.retType);
return ABIFunctionType(abiType);
}
#endif
@ -1125,16 +1128,16 @@ void* wasm::AddressOf(SymbolicAddress imm, ABIFunctionType* abiType) {
*abiType = Args_General0;
return FuncCast(AllocateBigIntTenuredNoGC, *abiType);
case SymbolicAddress::DivI64:
*abiType = Args_General4;
*abiType = Args_Int64_Int32Int32Int32Int32;
return FuncCast(DivI64, *abiType);
case SymbolicAddress::UDivI64:
*abiType = Args_General4;
*abiType = Args_Int64_Int32Int32Int32Int32;
return FuncCast(UDivI64, *abiType);
case SymbolicAddress::ModI64:
*abiType = Args_General4;
*abiType = Args_Int64_Int32Int32Int32Int32;
return FuncCast(ModI64, *abiType);
case SymbolicAddress::UModI64:
*abiType = Args_General4;
*abiType = Args_Int64_Int32Int32Int32Int32;
return FuncCast(UModI64, *abiType);
case SymbolicAddress::TruncateDoubleToUint64:
*abiType = Args_Int64_Double;
@ -1162,10 +1165,10 @@ void* wasm::AddressOf(SymbolicAddress imm, ABIFunctionType* abiType) {
return FuncCast(Int64ToFloat32, *abiType);
#if defined(JS_CODEGEN_ARM)
case SymbolicAddress::aeabi_idivmod:
*abiType = Args_General2;
*abiType = Args_Int64_GeneralGeneral;
return FuncCast(__aeabi_idivmod, *abiType);
case SymbolicAddress::aeabi_uidivmod:
*abiType = Args_General2;
*abiType = Args_Int64_GeneralGeneral;
return FuncCast(__aeabi_uidivmod, *abiType);
#endif
case SymbolicAddress::ModD:
@ -1977,35 +1980,38 @@ static Maybe<ABIFunctionType> ToBuiltinABIFunctionType(
return Nothing();
}
uint32_t abiType;
switch (results[0].kind()) {
case ValType::F32:
abiType = ArgType_Float32 << RetType_Shift;
break;
case ValType::F64:
abiType = ArgType_Float64 << RetType_Shift;
break;
default:
return Nothing();
}
if ((args.length() + 1) > (sizeof(uint32_t) * 8 / ArgType_Shift)) {
return Nothing();
}
uint32_t abiType = 0;
for (size_t i = 0; i < args.length(); i++) {
switch (args[i].kind()) {
case ValType::F32:
abiType |= (ArgType_Float32 << (ArgType_Shift * (i + 1)));
abiType <<= ArgType_Shift;
abiType |= ArgType_Float32;
break;
case ValType::F64:
abiType |= (ArgType_Float64 << (ArgType_Shift * (i + 1)));
abiType <<= ArgType_Shift;
abiType |= ArgType_Float64;
break;
default:
return Nothing();
}
}
abiType <<= ArgType_Shift;
switch (results[0].kind()) {
case ValType::F32:
abiType |= ArgType_Float32;
break;
case ValType::F64:
abiType |= ArgType_Float64;
break;
default:
return Nothing();
}
return Some(ABIFunctionType(abiType));
}

Просмотреть файл

@ -2428,8 +2428,10 @@ struct ABIFunctionArgs {
MIRType operator[](size_t i) const {
MOZ_ASSERT(i < len);
uint64_t abi = uint64_t(abiType);
while (i--) {
size_t argAtLSB = len - 1;
while (argAtLSB != i) {
abi = abi >> ArgType_Shift;
argAtLSB--;
}
return ToMIRType(ABIArgType(abi & ArgType_Mask));
}