mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 16:41:07 +00:00
Remove MIPS support
R=asiva@google.com Review-Url: https://codereview.chromium.org/2858623002 .
This commit is contained in:
parent
a420a1fbb5
commit
ac16656161
|
@ -27,6 +27,7 @@
|
||||||
occur sooner than specified in 'timeout'.
|
occur sooner than specified in 'timeout'.
|
||||||
|
|
||||||
### Dart VM
|
### Dart VM
|
||||||
|
* Support for MIPS has been remvoed.
|
||||||
|
|
||||||
### Tool Changes
|
### Tool Changes
|
||||||
|
|
||||||
|
|
|
@ -1,143 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
|
||||||
# Use of this source code is governed by a BSD-style license that can be
|
|
||||||
# found in the LICENSE file.
|
|
||||||
|
|
||||||
"""Compiler version checking tool for gcc
|
|
||||||
|
|
||||||
Print gcc version as XY if you are running gcc X.Y.*.
|
|
||||||
This is used to tweak build flags for gcc 4.4.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
|
|
||||||
|
|
||||||
compiler_version_cache = {} # Map from (compiler, tool) -> version.
|
|
||||||
|
|
||||||
|
|
||||||
def Usage(program_name):
|
|
||||||
print '%s MODE TOOL' % os.path.basename(program_name)
|
|
||||||
print 'MODE: host or target.'
|
|
||||||
print 'TOOL: assembler or compiler or linker.'
|
|
||||||
return 1
|
|
||||||
|
|
||||||
|
|
||||||
def ParseArgs(args):
|
|
||||||
if len(args) != 2:
|
|
||||||
raise Exception('Invalid number of arguments')
|
|
||||||
mode = args[0]
|
|
||||||
tool = args[1]
|
|
||||||
if mode not in ('host', 'target'):
|
|
||||||
raise Exception('Invalid mode: %s' % mode)
|
|
||||||
if tool not in ('assembler', 'compiler', 'linker'):
|
|
||||||
raise Exception('Invalid tool: %s' % tool)
|
|
||||||
return mode, tool
|
|
||||||
|
|
||||||
|
|
||||||
def GetEnvironFallback(var_list, default):
|
|
||||||
"""Look up an environment variable from a possible list of variable names."""
|
|
||||||
for var in var_list:
|
|
||||||
if var in os.environ:
|
|
||||||
return os.environ[var]
|
|
||||||
return default
|
|
||||||
|
|
||||||
|
|
||||||
def GetVersion(compiler, tool):
|
|
||||||
tool_output = tool_error = None
|
|
||||||
cache_key = (compiler, tool)
|
|
||||||
cached_version = compiler_version_cache.get(cache_key)
|
|
||||||
if cached_version:
|
|
||||||
return cached_version
|
|
||||||
try:
|
|
||||||
# Note that compiler could be something tricky like "distcc g++".
|
|
||||||
if tool == "compiler":
|
|
||||||
compiler = compiler + " -dumpversion"
|
|
||||||
# 4.6
|
|
||||||
version_re = re.compile(r"(\d+)\.(\d+)")
|
|
||||||
elif tool == "assembler":
|
|
||||||
compiler = compiler + " -Xassembler --version -x assembler -c /dev/null"
|
|
||||||
# Unmodified: GNU assembler (GNU Binutils) 2.24
|
|
||||||
# Ubuntu: GNU assembler (GNU Binutils for Ubuntu) 2.22
|
|
||||||
# Fedora: GNU assembler version 2.23.2
|
|
||||||
version_re = re.compile(r"^GNU [^ ]+ .* (\d+).(\d+).*?$", re.M)
|
|
||||||
elif tool == "linker":
|
|
||||||
compiler = compiler + " -Xlinker --version"
|
|
||||||
# Using BFD linker
|
|
||||||
# Unmodified: GNU ld (GNU Binutils) 2.24
|
|
||||||
# Ubuntu: GNU ld (GNU Binutils for Ubuntu) 2.22
|
|
||||||
# Fedora: GNU ld version 2.23.2
|
|
||||||
# Using Gold linker
|
|
||||||
# Unmodified: GNU gold (GNU Binutils 2.24) 1.11
|
|
||||||
# Ubuntu: GNU gold (GNU Binutils for Ubuntu 2.22) 1.11
|
|
||||||
# Fedora: GNU gold (version 2.23.2) 1.11
|
|
||||||
version_re = re.compile(r"^GNU [^ ]+ .* (\d+).(\d+).*?$", re.M)
|
|
||||||
else:
|
|
||||||
raise Exception("Unknown tool %s" % tool)
|
|
||||||
|
|
||||||
# Force the locale to C otherwise the version string could be localized
|
|
||||||
# making regex matching fail.
|
|
||||||
env = os.environ.copy()
|
|
||||||
env["LC_ALL"] = "C"
|
|
||||||
pipe = subprocess.Popen(compiler, shell=True, env=env,
|
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
||||||
tool_output, tool_error = pipe.communicate()
|
|
||||||
if pipe.returncode:
|
|
||||||
raise subprocess.CalledProcessError(pipe.returncode, compiler)
|
|
||||||
|
|
||||||
parsed_output = version_re.match(tool_output)
|
|
||||||
result = parsed_output.group(1) + parsed_output.group(2)
|
|
||||||
compiler_version_cache[cache_key] = result
|
|
||||||
return result
|
|
||||||
except Exception, e:
|
|
||||||
if tool_error:
|
|
||||||
sys.stderr.write(tool_error)
|
|
||||||
print >> sys.stderr, "compiler_version.py failed to execute:", compiler
|
|
||||||
print >> sys.stderr, e
|
|
||||||
return ""
|
|
||||||
|
|
||||||
|
|
||||||
def main(args):
|
|
||||||
try:
|
|
||||||
(mode, tool) = ParseArgs(args[1:])
|
|
||||||
except Exception, e:
|
|
||||||
sys.stderr.write(e.message + '\n\n')
|
|
||||||
return Usage(args[0])
|
|
||||||
|
|
||||||
ret_code, result = ExtractVersion(mode, tool)
|
|
||||||
if ret_code == 0:
|
|
||||||
print result
|
|
||||||
return ret_code
|
|
||||||
|
|
||||||
|
|
||||||
def DoMain(args):
|
|
||||||
"""Hook to be called from gyp without starting a separate python
|
|
||||||
interpreter."""
|
|
||||||
(mode, tool) = ParseArgs(args)
|
|
||||||
ret_code, result = ExtractVersion(mode, tool)
|
|
||||||
if ret_code == 0:
|
|
||||||
return result
|
|
||||||
raise Exception("Failed to extract compiler version for args: %s" % args)
|
|
||||||
|
|
||||||
|
|
||||||
def ExtractVersion(mode, tool):
|
|
||||||
# Check if various CXX environment variables exist and use them if they
|
|
||||||
# exist. The preferences and fallback order is a close approximation of
|
|
||||||
# GenerateOutputForConfig() in GYP's ninja generator.
|
|
||||||
# The main difference being not supporting GYP's make_global_settings.
|
|
||||||
environments = ['CXX_target', 'CXX']
|
|
||||||
if mode == 'host':
|
|
||||||
environments = ['CXX_host'] + environments;
|
|
||||||
compiler = GetEnvironFallback(environments, 'c++')
|
|
||||||
|
|
||||||
if compiler:
|
|
||||||
compiler_version = GetVersion(compiler, tool)
|
|
||||||
if compiler_version != "":
|
|
||||||
return (0, compiler_version)
|
|
||||||
return (1, None)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
sys.exit(main(sys.argv))
|
|
|
@ -71,14 +71,10 @@ if (is_android) {
|
||||||
"platforms/android-${_android_api_level}/arch-x86"
|
"platforms/android-${_android_api_level}/arch-x86"
|
||||||
arm_android_sysroot_subdir =
|
arm_android_sysroot_subdir =
|
||||||
"platforms/android-${_android_api_level}/arch-arm"
|
"platforms/android-${_android_api_level}/arch-arm"
|
||||||
mips_android_sysroot_subdir =
|
|
||||||
"platforms/android-${_android_api_level}/arch-mips"
|
|
||||||
x86_64_android_sysroot_subdir =
|
x86_64_android_sysroot_subdir =
|
||||||
"platforms/android-${_android_api_level}/arch-x86_64"
|
"platforms/android-${_android_api_level}/arch-x86_64"
|
||||||
arm64_android_sysroot_subdir =
|
arm64_android_sysroot_subdir =
|
||||||
"platforms/android-${_android_api_level}/arch-arm64"
|
"platforms/android-${_android_api_level}/arch-arm64"
|
||||||
mips64_android_sysroot_subdir =
|
|
||||||
"platforms/android-${_android_api_level}/arch-mips64"
|
|
||||||
|
|
||||||
# Toolchain root directory for each build. The actual binaries are inside
|
# Toolchain root directory for each build. The actual binaries are inside
|
||||||
# a "bin" directory inside of these.
|
# a "bin" directory inside of these.
|
||||||
|
@ -86,10 +82,8 @@ if (is_android) {
|
||||||
_android_toolchain_detailed_version = "4.9.x"
|
_android_toolchain_detailed_version = "4.9.x"
|
||||||
x86_android_toolchain_root = "$android_ndk_root/toolchains/x86-${_android_toolchain_version}/prebuilt/${android_host_os}-${android_host_arch}"
|
x86_android_toolchain_root = "$android_ndk_root/toolchains/x86-${_android_toolchain_version}/prebuilt/${android_host_os}-${android_host_arch}"
|
||||||
arm_android_toolchain_root = "$android_ndk_root/toolchains/arm-linux-androideabi-${_android_toolchain_version}/prebuilt/${android_host_os}-${android_host_arch}"
|
arm_android_toolchain_root = "$android_ndk_root/toolchains/arm-linux-androideabi-${_android_toolchain_version}/prebuilt/${android_host_os}-${android_host_arch}"
|
||||||
mips_android_toolchain_root = "$android_ndk_root/toolchains/mipsel-linux-android-${_android_toolchain_version}/prebuilt/${android_host_os}-${android_host_arch}"
|
|
||||||
x86_64_android_toolchain_root = "$android_ndk_root/toolchains/x86_64-${_android_toolchain_version}/prebuilt/${android_host_os}-${android_host_arch}"
|
x86_64_android_toolchain_root = "$android_ndk_root/toolchains/x86_64-${_android_toolchain_version}/prebuilt/${android_host_os}-${android_host_arch}"
|
||||||
arm64_android_toolchain_root = "$android_ndk_root/toolchains/aarch64-linux-android-${_android_toolchain_version}/prebuilt/${android_host_os}-${android_host_arch}"
|
arm64_android_toolchain_root = "$android_ndk_root/toolchains/aarch64-linux-android-${_android_toolchain_version}/prebuilt/${android_host_os}-${android_host_arch}"
|
||||||
mips64_android_toolchain_root = "$android_ndk_root/toolchains/mips64el-linux-android-${_android_toolchain_version}/prebuilt/${android_host_os}-${android_host_arch}"
|
|
||||||
|
|
||||||
# Location of libgcc. This is only needed for the current GN toolchain, so we
|
# Location of libgcc. This is only needed for the current GN toolchain, so we
|
||||||
# only need to define the current one, rather than one for every platform
|
# only need to define the current one, rather than one for every platform
|
||||||
|
@ -102,10 +96,6 @@ if (is_android) {
|
||||||
android_prebuilt_arch = "android-arm"
|
android_prebuilt_arch = "android-arm"
|
||||||
_binary_prefix = "arm-linux-androideabi"
|
_binary_prefix = "arm-linux-androideabi"
|
||||||
android_toolchain_root = "$arm_android_toolchain_root"
|
android_toolchain_root = "$arm_android_toolchain_root"
|
||||||
} else if (current_cpu == "mipsel") {
|
|
||||||
android_prebuilt_arch = "android-mips"
|
|
||||||
_binary_prefix = "mipsel-linux-android"
|
|
||||||
android_toolchain_root = "$mips_android_toolchain_root"
|
|
||||||
} else if (current_cpu == "x64") {
|
} else if (current_cpu == "x64") {
|
||||||
android_prebuilt_arch = "android-x86_64"
|
android_prebuilt_arch = "android-x86_64"
|
||||||
_binary_prefix = "x86_64-linux-android"
|
_binary_prefix = "x86_64-linux-android"
|
||||||
|
@ -114,10 +104,6 @@ if (is_android) {
|
||||||
android_prebuilt_arch = "android-arm64"
|
android_prebuilt_arch = "android-arm64"
|
||||||
_binary_prefix = "aarch64-linux-android"
|
_binary_prefix = "aarch64-linux-android"
|
||||||
android_toolchain_root = "$arm64_android_toolchain_root"
|
android_toolchain_root = "$arm64_android_toolchain_root"
|
||||||
} else if (current_cpu == "mips64el") {
|
|
||||||
android_prebuilt_arch = "android-mips64"
|
|
||||||
_binary_prefix = "mips64el-linux-android"
|
|
||||||
android_toolchain_root = "$mips64_android_toolchain_root"
|
|
||||||
} else {
|
} else {
|
||||||
assert(false, "Need android libgcc support for your target arch.")
|
assert(false, "Need android libgcc support for your target arch.")
|
||||||
}
|
}
|
||||||
|
@ -156,14 +142,10 @@ if (is_android) {
|
||||||
} else {
|
} else {
|
||||||
android_app_abi = "armeabi-v7a"
|
android_app_abi = "armeabi-v7a"
|
||||||
}
|
}
|
||||||
} else if (current_cpu == "mipsel") {
|
|
||||||
android_app_abi = "mips"
|
|
||||||
} else if (current_cpu == "x64") {
|
} else if (current_cpu == "x64") {
|
||||||
android_app_abi = "x86_64"
|
android_app_abi = "x86_64"
|
||||||
} else if (current_cpu == "arm64") {
|
} else if (current_cpu == "arm64") {
|
||||||
android_app_abi = "arm64-v8a"
|
android_app_abi = "arm64-v8a"
|
||||||
} else if (current_cpu == "mips64el") {
|
|
||||||
android_app_abi = "mips64"
|
|
||||||
} else {
|
} else {
|
||||||
assert(false, "Unknown Android ABI: " + current_cpu)
|
assert(false, "Unknown Android ABI: " + current_cpu)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,12 +17,6 @@ import("//build/config/android/config.gni")
|
||||||
if (current_cpu == "arm") {
|
if (current_cpu == "arm") {
|
||||||
import("//build/config/arm.gni")
|
import("//build/config/arm.gni")
|
||||||
}
|
}
|
||||||
if (current_cpu == "mipsel" || current_cpu == "mips64el") {
|
|
||||||
import("//build/config/mips.gni")
|
|
||||||
}
|
|
||||||
if (is_posix) {
|
|
||||||
import("//build/config/gcc/gcc_version.gni")
|
|
||||||
}
|
|
||||||
if (is_win) {
|
if (is_win) {
|
||||||
import("//build/config/win/visual_studio_version.gni")
|
import("//build/config/win/visual_studio_version.gni")
|
||||||
}
|
}
|
||||||
|
@ -225,73 +219,10 @@ config("compiler") {
|
||||||
"-fno-caller-saves",
|
"-fno-caller-saves",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
} else if (current_cpu == "mipsel") {
|
|
||||||
# Some toolchains default to big-endian.
|
|
||||||
cflags += [ "-EL" ]
|
|
||||||
ldflags += [ "-EL" ]
|
|
||||||
|
|
||||||
# We have to explicitly request exceptions to get good heap profiles from
|
|
||||||
# tcmalloc.
|
|
||||||
if (is_debug || is_release) {
|
|
||||||
cflags += [
|
|
||||||
"-fexceptions",
|
|
||||||
"-funwind-tables",
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mips_arch_variant == "r6") {
|
|
||||||
cflags += [
|
|
||||||
"-mips32r6",
|
|
||||||
"-Wa,-mips32r6",
|
|
||||||
]
|
|
||||||
if (is_android) {
|
|
||||||
ldflags += [
|
|
||||||
"-mips32r6",
|
|
||||||
"-Wl,-melf32ltsmip",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
} else if (mips_arch_variant == "r2") {
|
|
||||||
cflags += [
|
|
||||||
"-mips32r2",
|
|
||||||
"-Wa,-mips32r2",
|
|
||||||
]
|
|
||||||
if (mips_float_abi == "hard" && mips_fpu_mode != "") {
|
|
||||||
cflags += [ "-m$mips_fpu_mode" ]
|
|
||||||
}
|
|
||||||
} else if (mips_arch_variant == "r1") {
|
|
||||||
cflags += [
|
|
||||||
"-mips32",
|
|
||||||
"-Wa,-mips32",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mips_dsp_rev == 1) {
|
|
||||||
cflags += [ "-mdsp" ]
|
|
||||||
} else if (mips_dsp_rev == 2) {
|
|
||||||
cflags += [ "-mdspr2" ]
|
|
||||||
}
|
|
||||||
|
|
||||||
cflags += [ "-m${mips_float_abi}-float" ]
|
|
||||||
} else if (current_cpu == "mips64el") {
|
|
||||||
if (mips_arch_variant == "r6") {
|
|
||||||
cflags += [
|
|
||||||
"-mips64r6",
|
|
||||||
"-Wa,-mips64r6",
|
|
||||||
]
|
|
||||||
ldflags += [ "-mips64r6" ]
|
|
||||||
} else if (mips_arch_variant == "r2") {
|
|
||||||
cflags += [
|
|
||||||
"-mips64r2",
|
|
||||||
"-Wa,-mips64r2",
|
|
||||||
]
|
|
||||||
ldflags += [ "-mips64r2" ]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (current_cpu != "mipsel") {
|
|
||||||
cflags += [ "-fno-exceptions" ]
|
cflags += [ "-fno-exceptions" ]
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
# Linux/Android common flags setup.
|
# Linux/Android common flags setup.
|
||||||
# ---------------------------------
|
# ---------------------------------
|
||||||
|
@ -304,12 +235,12 @@ config("compiler") {
|
||||||
}
|
}
|
||||||
|
|
||||||
# We need -fPIC:
|
# We need -fPIC:
|
||||||
# 1. On ARM and MIPS for tcmalloc.
|
# 1. On ARM for tcmalloc.
|
||||||
# 2. On Android.
|
# 2. On Android.
|
||||||
# 3. When using the sanitizers.
|
# 3. When using the sanitizers.
|
||||||
# Otherwise there is a performance hit, in particular on ia32.
|
# Otherwise there is a performance hit, in particular on ia32.
|
||||||
if (is_android || is_asan || is_lsan || is_msan || is_tsan ||
|
if (is_android || is_asan || is_lsan || is_msan || is_tsan ||
|
||||||
(is_linux && (current_cpu == "arm" || current_cpu == "mipsel"))) {
|
(is_linux && current_cpu == "arm")) {
|
||||||
cflags += [ "-fPIC" ]
|
cflags += [ "-fPIC" ]
|
||||||
ldflags += [ "-fPIC" ]
|
ldflags += [ "-fPIC" ]
|
||||||
}
|
}
|
||||||
|
@ -447,19 +378,15 @@ config("runtime_library") {
|
||||||
if (is_android) {
|
if (is_android) {
|
||||||
if (is_clang) {
|
if (is_clang) {
|
||||||
# Work around incompatibilities between bionic and clang headers.
|
# Work around incompatibilities between bionic and clang headers.
|
||||||
defines += [
|
defines += [ "__compiler_offsetof=__builtin_offsetof" ]
|
||||||
"__compiler_offsetof=__builtin_offsetof",
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
defines += [ "__GNU_SOURCE=1" ] # Necessary for clone().
|
defines += [ "__GNU_SOURCE=1" ] # Necessary for clone().
|
||||||
|
|
||||||
# TODO(jdduke) Re-enable on mips after resolving linking
|
ldflags += [
|
||||||
# issues with libc++ (crbug.com/456380).
|
"-Wl,--warn-shared-textrel",
|
||||||
if (current_cpu != "mipsel" && current_cpu != "mips64el") {
|
"-nostdlib",
|
||||||
ldflags += [ "-Wl,--warn-shared-textrel" ]
|
]
|
||||||
}
|
|
||||||
ldflags += [ "-nostdlib" ]
|
|
||||||
|
|
||||||
# NOTE: The libc++ header include paths below are specified in cflags
|
# NOTE: The libc++ header include paths below are specified in cflags
|
||||||
# rather than include_dirs because they need to come after include_dirs.
|
# rather than include_dirs because they need to come after include_dirs.
|
||||||
|
@ -572,24 +499,11 @@ if (is_win) {
|
||||||
"-Wno-type-limits",
|
"-Wno-type-limits",
|
||||||
]
|
]
|
||||||
default_warning_flags_cc += [
|
default_warning_flags_cc += [
|
||||||
# Disabling c++0x-compat should be handled in WebKit, but
|
|
||||||
# this currently doesn't work because gcc_version is not set
|
|
||||||
# correctly when building with the Android build system.
|
|
||||||
# TODO(torne): Fix this in WebKit.
|
|
||||||
"-Wno-error=c++0x-compat",
|
|
||||||
|
|
||||||
# Other things unrelated to -Wextra:
|
# Other things unrelated to -Wextra:
|
||||||
"-Wno-non-virtual-dtor",
|
"-Wno-non-virtual-dtor",
|
||||||
"-Wno-sign-promo",
|
"-Wno-sign-promo",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gcc_version >= 48) {
|
|
||||||
# Don't warn about the "typedef 'foo' locally defined but not used"
|
|
||||||
# for gcc 4.8.
|
|
||||||
# TODO: remove this flag once all builds work. See crbug.com/227506
|
|
||||||
default_warning_flags += [ "-Wno-unused-local-typedefs" ]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# chromium_code ---------------------------------------------------------------
|
# chromium_code ---------------------------------------------------------------
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
# Copyright 2014 The Chromium Authors. All rights reserved.
|
|
||||||
# Use of this source code is governed by a BSD-style license that can be
|
|
||||||
# found in the LICENSE file.
|
|
||||||
|
|
||||||
if (is_android) {
|
|
||||||
gcc_version = 49
|
|
||||||
} else if (current_toolchain == "//build/toolchain/cros:target" ||
|
|
||||||
current_toolchain == "//build/toolchain/linux:mipsel") {
|
|
||||||
gcc_version = exec_script("../../compiler_version.py",
|
|
||||||
[
|
|
||||||
"target",
|
|
||||||
"compiler",
|
|
||||||
],
|
|
||||||
"value")
|
|
||||||
} else if (current_toolchain == "//build/toolchain/linux:x64" ||
|
|
||||||
current_toolchain == "//build/toolchain/linux:x86") {
|
|
||||||
# These are both the same and just use the default gcc on the system.
|
|
||||||
gcc_version = exec_script("../../compiler_version.py",
|
|
||||||
[
|
|
||||||
"host",
|
|
||||||
"compiler",
|
|
||||||
],
|
|
||||||
"value")
|
|
||||||
} else {
|
|
||||||
gcc_version = 0
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
# Copyright 2015 The Chromium Authors. All rights reserved.
|
|
||||||
# Use of this source code is governed by a BSD-style license that can be
|
|
||||||
# found in the LICENSE file.
|
|
||||||
|
|
||||||
if (current_cpu == "mipsel") {
|
|
||||||
declare_args() {
|
|
||||||
# MIPS arch variant. Possible values are:
|
|
||||||
# "r1"
|
|
||||||
# "r2"
|
|
||||||
# "r6"
|
|
||||||
mips_arch_variant = "r1"
|
|
||||||
|
|
||||||
# MIPS DSP ASE revision. Possible values are:
|
|
||||||
# 0: unavailable
|
|
||||||
# 1: revision 1
|
|
||||||
# 2: revision 2
|
|
||||||
mips_dsp_rev = 0
|
|
||||||
|
|
||||||
# MIPS floating-point ABI. Possible values are:
|
|
||||||
# "hard": sets the GCC -mhard-float option.
|
|
||||||
# "soft": sets the GCC -msoft-float option.
|
|
||||||
mips_float_abi = "hard"
|
|
||||||
|
|
||||||
# MIPS32 floating-point register width. Possible values are:
|
|
||||||
# "fp32": sets the GCC -mfp32 option.
|
|
||||||
# "fp64": sets the GCC -mfp64 option.
|
|
||||||
# "fpxx": sets the GCC -mfpxx option.
|
|
||||||
mips_fpu_mode = "fp32"
|
|
||||||
}
|
|
||||||
} else if (current_cpu == "mips64el") {
|
|
||||||
# MIPS arch variant. Possible values are:
|
|
||||||
# "r2"
|
|
||||||
# "r6"
|
|
||||||
if (is_android) {
|
|
||||||
declare_args() {
|
|
||||||
mips_arch_variant = "r6"
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
declare_args() {
|
|
||||||
mips_arch_variant = "r2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -33,14 +33,10 @@ if (current_toolchain == default_toolchain && target_sysroot != "") {
|
||||||
sysroot = rebase_path("$android_ndk_root/$x86_android_sysroot_subdir")
|
sysroot = rebase_path("$android_ndk_root/$x86_android_sysroot_subdir")
|
||||||
} else if (current_cpu == "arm") {
|
} else if (current_cpu == "arm") {
|
||||||
sysroot = rebase_path("$android_ndk_root/$arm_android_sysroot_subdir")
|
sysroot = rebase_path("$android_ndk_root/$arm_android_sysroot_subdir")
|
||||||
} else if (current_cpu == "mipsel") {
|
|
||||||
sysroot = rebase_path("$android_ndk_root/$mips_android_sysroot_subdir")
|
|
||||||
} else if (current_cpu == "x64") {
|
} else if (current_cpu == "x64") {
|
||||||
sysroot = rebase_path("$android_ndk_root/$x86_64_android_sysroot_subdir")
|
sysroot = rebase_path("$android_ndk_root/$x86_64_android_sysroot_subdir")
|
||||||
} else if (current_cpu == "arm64") {
|
} else if (current_cpu == "arm64") {
|
||||||
sysroot = rebase_path("$android_ndk_root/$arm64_android_sysroot_subdir")
|
sysroot = rebase_path("$android_ndk_root/$arm64_android_sysroot_subdir")
|
||||||
} else if (current_cpu == "mips64") {
|
|
||||||
sysroot = rebase_path("$android_ndk_root/$mips64_android_sysroot_subdir")
|
|
||||||
} else {
|
} else {
|
||||||
sysroot = ""
|
sysroot = ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,14 +132,6 @@ android_gcc_toolchains_helper("arm") {
|
||||||
toolchain_cpu = "arm"
|
toolchain_cpu = "arm"
|
||||||
}
|
}
|
||||||
|
|
||||||
android_gcc_toolchains_helper("mipsel") {
|
|
||||||
android_ndk_sysroot = "$android_ndk_root/$mips_android_sysroot_subdir"
|
|
||||||
android_ndk_lib_dir = "usr/lib"
|
|
||||||
|
|
||||||
tool_prefix = "$mips_android_toolchain_root/bin/mipsel-linux-android-"
|
|
||||||
toolchain_cpu = "mipsel"
|
|
||||||
}
|
|
||||||
|
|
||||||
android_gcc_toolchains_helper("x64") {
|
android_gcc_toolchains_helper("x64") {
|
||||||
android_ndk_sysroot = "$android_ndk_root/$x86_64_android_sysroot_subdir"
|
android_ndk_sysroot = "$android_ndk_root/$x86_64_android_sysroot_subdir"
|
||||||
android_ndk_lib_dir = "usr/lib64"
|
android_ndk_lib_dir = "usr/lib64"
|
||||||
|
@ -155,11 +147,3 @@ android_gcc_toolchains_helper("arm64") {
|
||||||
tool_prefix = "$arm64_android_toolchain_root/bin/aarch64-linux-android-"
|
tool_prefix = "$arm64_android_toolchain_root/bin/aarch64-linux-android-"
|
||||||
toolchain_cpu = "aarch64"
|
toolchain_cpu = "aarch64"
|
||||||
}
|
}
|
||||||
|
|
||||||
android_gcc_toolchains_helper("mips64el") {
|
|
||||||
android_ndk_sysroot = "$android_ndk_root/$mips64_android_sysroot_subdir"
|
|
||||||
android_ndk_lib_dir = "usr/lib64"
|
|
||||||
|
|
||||||
tool_prefix = "$mips64_android_toolchain_root/bin/mipsel-linux-android-"
|
|
||||||
toolchain_cpu = "mipsel64el"
|
|
||||||
}
|
|
||||||
|
|
|
@ -126,17 +126,3 @@ gcc_toolchain("x64") {
|
||||||
toolchain_os = "linux"
|
toolchain_os = "linux"
|
||||||
is_clang = false
|
is_clang = false
|
||||||
}
|
}
|
||||||
|
|
||||||
gcc_toolchain("mipsel") {
|
|
||||||
cc = "${compiler_prefix}${toolchain_prefix}gcc"
|
|
||||||
cxx = "${compiler_prefix}${toolchain_prefix}g++"
|
|
||||||
ar = "${toolchain_prefix}ar"
|
|
||||||
ld = cxx
|
|
||||||
readelf = "${toolchain_prefix}readelf"
|
|
||||||
nm = "${toolchain_prefix}nm"
|
|
||||||
strip = "${toolchain_prefix}strip"
|
|
||||||
|
|
||||||
toolchain_cpu = "${target_cpu}"
|
|
||||||
toolchain_os = "linux"
|
|
||||||
is_clang = is_clang
|
|
||||||
}
|
|
||||||
|
|
|
@ -189,7 +189,7 @@ dart_messages/test/dart_messages_test: Skip # Uses dart:io.
|
||||||
[ $browser || $jscl ]
|
[ $browser || $jscl ]
|
||||||
kernel/test/*: SkipByDesign # Uses dart:io and bigints.
|
kernel/test/*: SkipByDesign # Uses dart:io and bigints.
|
||||||
|
|
||||||
[ $runtime == vm && ($arch == simarm64 || $arch == simarm || $arch == simarmv6 || $arch == simarmv5te || $arch == simmips || $arch == armv6 || $arch == armv5te) ]
|
[ $runtime == vm && ($arch == simarm64 || $arch == simarm || $arch == simarmv6 || $arch == simarmv5te || $arch == armv6 || $arch == armv5te) ]
|
||||||
# Timeout. These are not unit tests. They do not run efficiently on our
|
# Timeout. These are not unit tests. They do not run efficiently on our
|
||||||
# simulator or low-end devices.
|
# simulator or low-end devices.
|
||||||
*: Skip
|
*: Skip
|
||||||
|
|
|
@ -26,7 +26,7 @@ declare_args() {
|
||||||
|
|
||||||
# Explicitly set the target architecture in case of precompilation. Leaving
|
# Explicitly set the target architecture in case of precompilation. Leaving
|
||||||
# this unspecified results in automatic target architecture detection.
|
# this unspecified results in automatic target architecture detection.
|
||||||
# Available options are: arm, arm64, mips, x64 and ia32
|
# Available options are: arm, arm64, x64, and ia32
|
||||||
dart_target_arch = ""
|
dart_target_arch = ""
|
||||||
|
|
||||||
# The optimization level to use for debug builds.
|
# The optimization level to use for debug builds.
|
||||||
|
@ -105,8 +105,6 @@ config("dart_config") {
|
||||||
defines += [ "TARGET_ARCH_ARM_5TE" ]
|
defines += [ "TARGET_ARCH_ARM_5TE" ]
|
||||||
} else if (dart_target_arch == "arm64" || dart_target_arch == "simarm64") {
|
} else if (dart_target_arch == "arm64" || dart_target_arch == "simarm64") {
|
||||||
defines += [ "TARGET_ARCH_ARM64" ]
|
defines += [ "TARGET_ARCH_ARM64" ]
|
||||||
} else if (dart_target_arch == "mips" || dart_target_arch == "simmips") {
|
|
||||||
defines += [ "TARGET_ARCH_MIPS" ]
|
|
||||||
} else if (dart_target_arch == "x64") {
|
} else if (dart_target_arch == "x64") {
|
||||||
defines += [ "TARGET_ARCH_X64" ]
|
defines += [ "TARGET_ARCH_X64" ]
|
||||||
} else if (dart_target_arch == "ia32") {
|
} else if (dart_target_arch == "ia32") {
|
||||||
|
|
|
@ -25,7 +25,7 @@ class Platform {
|
||||||
static const char* OperatingSystem();
|
static const char* OperatingSystem();
|
||||||
|
|
||||||
// Returns the architecture name of the processor the VM is running on
|
// Returns the architecture name of the processor the VM is running on
|
||||||
// (ia32, x64, arm, arm64, or mips).
|
// (ia32, x64, arm, or arm64).
|
||||||
static const char* HostArchitecture() {
|
static const char* HostArchitecture() {
|
||||||
#if defined(HOST_ARCH_ARM)
|
#if defined(HOST_ARCH_ARM)
|
||||||
return "arm";
|
return "arm";
|
||||||
|
@ -33,8 +33,6 @@ class Platform {
|
||||||
return "arm64";
|
return "arm64";
|
||||||
#elif defined(HOST_ARCH_IA32)
|
#elif defined(HOST_ARCH_IA32)
|
||||||
return "ia32";
|
return "ia32";
|
||||||
#elif defined(HOST_ARCH_MIPS)
|
|
||||||
return "mips";
|
|
||||||
#elif defined(HOST_ARCH_X64)
|
#elif defined(HOST_ARCH_X64)
|
||||||
return "x64";
|
return "x64";
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -43,9 +43,9 @@ debugger_location_second_test: Pass, Slow
|
||||||
debugger_location_test: Pass, Slow
|
debugger_location_test: Pass, Slow
|
||||||
|
|
||||||
# These tests are slow on simulators.
|
# These tests are slow on simulators.
|
||||||
[ $arch == simarm || $arch == simmips || $arch == simarm64 ]
|
[ $arch == simarm || $arch == simarm64 ]
|
||||||
*: Pass, Slow
|
*: Pass, Slow
|
||||||
[ $mode == debug && ($arch == simarm || $arch == simmips || $arch == simarm64) ]
|
[ $mode == debug && ($arch == simarm || $arch == simarm64) ]
|
||||||
*: SkipSlow
|
*: SkipSlow
|
||||||
|
|
||||||
# All tests use dart:io
|
# All tests use dart:io
|
||||||
|
|
|
@ -212,13 +212,8 @@ typedef simd128_value_t fpu_register_t;
|
||||||
#elif defined(_M_IX86) || defined(__i386__)
|
#elif defined(_M_IX86) || defined(__i386__)
|
||||||
#define HOST_ARCH_IA32 1
|
#define HOST_ARCH_IA32 1
|
||||||
#define ARCH_IS_32_BIT 1
|
#define ARCH_IS_32_BIT 1
|
||||||
#if defined(TARGET_ARCH_MIPS)
|
|
||||||
#define kFpuRegisterSize 8
|
|
||||||
typedef double fpu_register_t;
|
|
||||||
#else
|
|
||||||
#define kFpuRegisterSize 16
|
#define kFpuRegisterSize 16
|
||||||
typedef simd128_value_t fpu_register_t;
|
typedef simd128_value_t fpu_register_t;
|
||||||
#endif
|
|
||||||
#elif defined(__ARMEL__)
|
#elif defined(__ARMEL__)
|
||||||
#define HOST_ARCH_ARM 1
|
#define HOST_ARCH_ARM 1
|
||||||
#define ARCH_IS_32_BIT 1
|
#define ARCH_IS_32_BIT 1
|
||||||
|
@ -241,14 +236,6 @@ typedef simd_value_t fpu_register_t;
|
||||||
reinterpret_cast<simd_value_t*>(addr)->data_[3] = value.data_[3]; \
|
reinterpret_cast<simd_value_t*>(addr)->data_[3] = value.data_[3]; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#elif defined(__MIPSEL__)
|
|
||||||
#define HOST_ARCH_MIPS 1
|
|
||||||
#define ARCH_IS_32_BIT 1
|
|
||||||
#define kFpuRegisterSize 8
|
|
||||||
typedef double fpu_register_t;
|
|
||||||
#elif defined(__MIPSEB__)
|
|
||||||
#error Big-endian MIPS is not supported by Dart. Try passing -EL to your \
|
|
||||||
compiler.
|
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
#define HOST_ARCH_ARM64 1
|
#define HOST_ARCH_ARM64 1
|
||||||
#define ARCH_IS_64_BIT 1
|
#define ARCH_IS_64_BIT 1
|
||||||
|
@ -316,13 +303,11 @@ typedef simd128_value_t fpu_register_t;
|
||||||
#error Automatic compiler detection failed.
|
#error Automatic compiler detection failed.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(TARGET_ARCH_MIPS) && !defined(TARGET_ARCH_ARM) && \
|
#if !defined(TARGET_ARCH_ARM) && !defined(TARGET_ARCH_X64) && \
|
||||||
!defined(TARGET_ARCH_X64) && !defined(TARGET_ARCH_IA32) && \
|
!defined(TARGET_ARCH_IA32) && !defined(TARGET_ARCH_ARM64) && \
|
||||||
!defined(TARGET_ARCH_ARM64) && !defined(TARGET_ARCH_DBC)
|
!defined(TARGET_ARCH_DBC)
|
||||||
// No target architecture specified pick the one matching the host architecture.
|
// No target architecture specified pick the one matching the host architecture.
|
||||||
#if defined(HOST_ARCH_MIPS)
|
#if defined(HOST_ARCH_ARM)
|
||||||
#define TARGET_ARCH_MIPS 1
|
|
||||||
#elif defined(HOST_ARCH_ARM)
|
|
||||||
#define TARGET_ARCH_ARM 1
|
#define TARGET_ARCH_ARM 1
|
||||||
#elif defined(HOST_ARCH_X64)
|
#elif defined(HOST_ARCH_X64)
|
||||||
#define TARGET_ARCH_X64 1
|
#define TARGET_ARCH_X64 1
|
||||||
|
@ -341,8 +326,7 @@ typedef simd128_value_t fpu_register_t;
|
||||||
#if !defined(ARCH_IS_64_BIT)
|
#if !defined(ARCH_IS_64_BIT)
|
||||||
#error Mismatched Host/Target architectures.
|
#error Mismatched Host/Target architectures.
|
||||||
#endif
|
#endif
|
||||||
#elif defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM) || \
|
#elif defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM)
|
||||||
defined(TARGET_ARCH_MIPS)
|
|
||||||
#if !defined(ARCH_IS_32_BIT)
|
#if !defined(ARCH_IS_32_BIT)
|
||||||
#error Mismatched Host/Target architectures.
|
#error Mismatched Host/Target architectures.
|
||||||
#endif
|
#endif
|
||||||
|
@ -363,11 +347,6 @@ typedef simd128_value_t fpu_register_t;
|
||||||
#define USING_SIMULATOR 1
|
#define USING_SIMULATOR 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#elif defined(TARGET_ARCH_MIPS)
|
|
||||||
#if !defined(HOST_ARCH_MIPS)
|
|
||||||
#define USING_SIMULATOR 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#elif defined(TARGET_ARCH_DBC)
|
#elif defined(TARGET_ARCH_DBC)
|
||||||
#define USING_SIMULATOR 1
|
#define USING_SIMULATOR 1
|
||||||
|
|
||||||
|
@ -663,8 +642,7 @@ inline D bit_copy(const S& source) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined(HOST_ARCH_ARM) || defined(HOST_ARCH_MIPS) || \
|
#if defined(HOST_ARCH_ARM) || defined(HOST_ARCH_ARM64)
|
||||||
defined(HOST_ARCH_ARM64)
|
|
||||||
// Similar to bit_copy and bit_cast, but does take the type from the argument.
|
// Similar to bit_copy and bit_cast, but does take the type from the argument.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static inline T ReadUnaligned(const T* ptr) {
|
static inline T ReadUnaligned(const T* ptr) {
|
||||||
|
@ -681,7 +659,7 @@ static inline void StoreUnaligned(T* ptr, T value) {
|
||||||
memcpy(reinterpret_cast<void*>(ptr), reinterpret_cast<const void*>(&value),
|
memcpy(reinterpret_cast<void*>(ptr), reinterpret_cast<const void*>(&value),
|
||||||
sizeof(value));
|
sizeof(value));
|
||||||
}
|
}
|
||||||
#else // !(HOST_ARCH_ARM || HOST_ARCH_MIPS || HOST_ARCH_ARM64)
|
#else // !(HOST_ARCH_ARM || HOST_ARCH_ARM64)
|
||||||
// Similar to bit_copy and bit_cast, but does take the type from the argument.
|
// Similar to bit_copy and bit_cast, but does take the type from the argument.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static inline T ReadUnaligned(const T* ptr) {
|
static inline T ReadUnaligned(const T* ptr) {
|
||||||
|
@ -694,7 +672,7 @@ template <typename T>
|
||||||
static inline void StoreUnaligned(T* ptr, T value) {
|
static inline void StoreUnaligned(T* ptr, T value) {
|
||||||
*ptr = value;
|
*ptr = value;
|
||||||
}
|
}
|
||||||
#endif // !(HOST_ARCH_ARM || HOST_ARCH_MIPS || HOST_ARCH_ARM64)
|
#endif // !(HOST_ARCH_ARM || HOST_ARCH_ARM64)
|
||||||
|
|
||||||
|
|
||||||
// On Windows the reentrent version of strtok is called
|
// On Windows the reentrent version of strtok is called
|
||||||
|
|
|
@ -54,7 +54,7 @@ def BuildOptions():
|
||||||
default=False, action="store_true")
|
default=False, action="store_true")
|
||||||
result.add_option("--arch",
|
result.add_option("--arch",
|
||||||
help='Target architectures (comma-separated).',
|
help='Target architectures (comma-separated).',
|
||||||
metavar='[all,ia32,x64,simarm,simmips,arm,mips,dartc]',
|
metavar='[all,ia32,x64,simarm,arm,dartc]',
|
||||||
default=utils.GuessArchitecture())
|
default=utils.GuessArchitecture())
|
||||||
result.add_option("--executable",
|
result.add_option("--executable",
|
||||||
help='Virtual machine to execute.',
|
help='Virtual machine to execute.',
|
||||||
|
@ -68,7 +68,7 @@ def BuildOptions():
|
||||||
|
|
||||||
def ProcessOptions(options):
|
def ProcessOptions(options):
|
||||||
if options.arch == 'all':
|
if options.arch == 'all':
|
||||||
options.arch = 'ia32,x64,simarm,simmips,dartc'
|
options.arch = 'ia32,x64,simarm,dartc'
|
||||||
if options.mode == 'all':
|
if options.mode == 'all':
|
||||||
options.mode = 'debug,release'
|
options.mode = 'debug,release'
|
||||||
options.mode = options.mode.split(',')
|
options.mode = options.mode.split(',')
|
||||||
|
@ -78,7 +78,7 @@ def ProcessOptions(options):
|
||||||
print "Unknown mode %s" % mode
|
print "Unknown mode %s" % mode
|
||||||
return False
|
return False
|
||||||
for arch in options.arch:
|
for arch in options.arch:
|
||||||
if not arch in ['ia32', 'x64', 'simarm', 'simmips', 'arm', 'mips', 'dartc']:
|
if not arch in ['ia32', 'x64', 'simarm', 'arm', 'dartc']:
|
||||||
print "Unknown arch %s" % arch
|
print "Unknown arch %s" % arch
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -93,13 +93,6 @@
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
'Dart_simmips_Base': {
|
|
||||||
'abstract': 1,
|
|
||||||
'xcode_settings': {
|
|
||||||
'ARCHS': [ 'i386' ],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
'Dart_Debug': {
|
'Dart_Debug': {
|
||||||
'abstract': 1,
|
'abstract': 1,
|
||||||
'defines': [
|
'defines': [
|
||||||
|
|
|
@ -22,11 +22,8 @@ DEFINE_FLAG(bool,
|
||||||
code_comments,
|
code_comments,
|
||||||
false,
|
false,
|
||||||
"Include comments into code and disassembly");
|
"Include comments into code and disassembly");
|
||||||
#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS)
|
#if defined(TARGET_ARCH_ARM)
|
||||||
DEFINE_FLAG(bool,
|
DEFINE_FLAG(bool, use_far_branches, false, "Enable far branches for ARM.");
|
||||||
use_far_branches,
|
|
||||||
false,
|
|
||||||
"Enable far branches for ARM and MIPS");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static uword NewContents(intptr_t capacity) {
|
static uword NewContents(intptr_t capacity) {
|
||||||
|
|
|
@ -14,8 +14,7 @@
|
||||||
|
|
||||||
namespace dart {
|
namespace dart {
|
||||||
|
|
||||||
#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64) || \
|
#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64)
|
||||||
defined(TARGET_ARCH_MIPS)
|
|
||||||
DECLARE_FLAG(bool, use_far_branches);
|
DECLARE_FLAG(bool, use_far_branches);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -335,8 +334,6 @@ enum RestorePP { kRestoreCallerPP, kKeepCalleePP };
|
||||||
#include "vm/assembler_arm.h"
|
#include "vm/assembler_arm.h"
|
||||||
#elif defined(TARGET_ARCH_ARM64)
|
#elif defined(TARGET_ARCH_ARM64)
|
||||||
#include "vm/assembler_arm64.h"
|
#include "vm/assembler_arm64.h"
|
||||||
#elif defined(TARGET_ARCH_MIPS)
|
|
||||||
#include "vm/assembler_mips.h"
|
|
||||||
#elif defined(TARGET_ARCH_DBC)
|
#elif defined(TARGET_ARCH_DBC)
|
||||||
#include "vm/assembler_dbc.h"
|
#include "vm/assembler_dbc.h"
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -301,7 +301,7 @@ class Assembler : public ValueObject {
|
||||||
jit_cookie_(0),
|
jit_cookie_(0),
|
||||||
comments_(),
|
comments_(),
|
||||||
code_(Code::ZoneHandle()) {
|
code_(Code::ZoneHandle()) {
|
||||||
// This mode is only needed and implemented for MIPS and ARM.
|
// This mode is only needed and implemented for ARM.
|
||||||
ASSERT(!use_far_branches);
|
ASSERT(!use_far_branches);
|
||||||
}
|
}
|
||||||
~Assembler() {}
|
~Assembler() {}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -27,7 +27,7 @@ Assembler::Assembler(bool use_far_branches)
|
||||||
has_single_entry_point_(true),
|
has_single_entry_point_(true),
|
||||||
comments_(),
|
comments_(),
|
||||||
constant_pool_allowed_(false) {
|
constant_pool_allowed_(false) {
|
||||||
// Far branching mode is only needed and implemented for MIPS and ARM.
|
// Far branching mode is only needed and implemented for ARM.
|
||||||
ASSERT(!use_far_branches);
|
ASSERT(!use_far_branches);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,12 +32,7 @@ inline void AtomicOperations::IncrementBy(intptr_t* p, intptr_t value) {
|
||||||
|
|
||||||
|
|
||||||
inline void AtomicOperations::IncrementInt64By(int64_t* p, int64_t value) {
|
inline void AtomicOperations::IncrementInt64By(int64_t* p, int64_t value) {
|
||||||
#if defined(TARGET_ARCH_MIPS)
|
|
||||||
// No double-word atomics on MIPS32.
|
|
||||||
*p += value;
|
|
||||||
#else
|
|
||||||
__sync_fetch_and_add(p, value);
|
__sync_fetch_and_add(p, value);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,119 +0,0 @@
|
||||||
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
#include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS.
|
|
||||||
#if defined(TARGET_ARCH_MIPS)
|
|
||||||
|
|
||||||
#include "vm/code_patcher.h"
|
|
||||||
|
|
||||||
#include "vm/instructions.h"
|
|
||||||
#include "vm/object.h"
|
|
||||||
|
|
||||||
namespace dart {
|
|
||||||
|
|
||||||
RawCode* CodePatcher::GetStaticCallTargetAt(uword return_address,
|
|
||||||
const Code& code) {
|
|
||||||
ASSERT(code.ContainsInstructionAt(return_address));
|
|
||||||
CallPattern call(return_address, code);
|
|
||||||
return call.TargetCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CodePatcher::PatchStaticCallAt(uword return_address,
|
|
||||||
const Code& code,
|
|
||||||
const Code& new_target) {
|
|
||||||
ASSERT(code.ContainsInstructionAt(return_address));
|
|
||||||
CallPattern call(return_address, code);
|
|
||||||
call.SetTargetCode(new_target);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CodePatcher::InsertDeoptimizationCallAt(uword start) {
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
RawCode* CodePatcher::GetInstanceCallAt(uword return_address,
|
|
||||||
const Code& code,
|
|
||||||
ICData* ic_data) {
|
|
||||||
ASSERT(code.ContainsInstructionAt(return_address));
|
|
||||||
CallPattern call(return_address, code);
|
|
||||||
if (ic_data != NULL) {
|
|
||||||
*ic_data = call.IcData();
|
|
||||||
}
|
|
||||||
return call.TargetCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
intptr_t CodePatcher::InstanceCallSizeInBytes() {
|
|
||||||
// The instance call instruction sequence has a variable size on MIPS.
|
|
||||||
UNREACHABLE();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
RawFunction* CodePatcher::GetUnoptimizedStaticCallAt(uword return_address,
|
|
||||||
const Code& code,
|
|
||||||
ICData* ic_data_result) {
|
|
||||||
ASSERT(code.ContainsInstructionAt(return_address));
|
|
||||||
CallPattern static_call(return_address, code);
|
|
||||||
ICData& ic_data = ICData::Handle();
|
|
||||||
ic_data ^= static_call.IcData();
|
|
||||||
if (ic_data_result != NULL) {
|
|
||||||
*ic_data_result = ic_data.raw();
|
|
||||||
}
|
|
||||||
return ic_data.GetTargetAt(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CodePatcher::PatchSwitchableCallAt(uword return_address,
|
|
||||||
const Code& caller_code,
|
|
||||||
const Object& data,
|
|
||||||
const Code& target) {
|
|
||||||
ASSERT(caller_code.ContainsInstructionAt(return_address));
|
|
||||||
SwitchableCallPattern call(return_address, caller_code);
|
|
||||||
call.SetData(data);
|
|
||||||
call.SetTarget(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
RawCode* CodePatcher::GetSwitchableCallTargetAt(uword return_address,
|
|
||||||
const Code& caller_code) {
|
|
||||||
ASSERT(caller_code.ContainsInstructionAt(return_address));
|
|
||||||
SwitchableCallPattern call(return_address, caller_code);
|
|
||||||
return call.target();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
RawObject* CodePatcher::GetSwitchableCallDataAt(uword return_address,
|
|
||||||
const Code& caller_code) {
|
|
||||||
ASSERT(caller_code.ContainsInstructionAt(return_address));
|
|
||||||
SwitchableCallPattern call(return_address, caller_code);
|
|
||||||
return call.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CodePatcher::PatchNativeCallAt(uword return_address,
|
|
||||||
const Code& code,
|
|
||||||
NativeFunction target,
|
|
||||||
const Code& trampoline) {
|
|
||||||
ASSERT(code.ContainsInstructionAt(return_address));
|
|
||||||
NativeCallPattern call(return_address, code);
|
|
||||||
call.set_target(trampoline);
|
|
||||||
call.set_native_function(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
RawCode* CodePatcher::GetNativeCallAt(uword return_address,
|
|
||||||
const Code& code,
|
|
||||||
NativeFunction* target) {
|
|
||||||
ASSERT(code.ContainsInstructionAt(return_address));
|
|
||||||
NativeCallPattern call(return_address, code);
|
|
||||||
*target = call.native_function();
|
|
||||||
return call.target();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace dart
|
|
||||||
|
|
||||||
#endif // defined TARGET_ARCH_MIPS
|
|
|
@ -1,62 +0,0 @@
|
||||||
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
#include "vm/globals.h"
|
|
||||||
#if defined(TARGET_ARCH_MIPS)
|
|
||||||
|
|
||||||
#include "vm/assembler.h"
|
|
||||||
#include "vm/code_patcher.h"
|
|
||||||
#include "vm/dart_entry.h"
|
|
||||||
#include "vm/instructions.h"
|
|
||||||
#include "vm/native_entry.h"
|
|
||||||
#include "vm/native_entry_test.h"
|
|
||||||
#include "vm/runtime_entry.h"
|
|
||||||
#include "vm/stub_code.h"
|
|
||||||
#include "vm/symbols.h"
|
|
||||||
#include "vm/unit_test.h"
|
|
||||||
|
|
||||||
namespace dart {
|
|
||||||
|
|
||||||
#define __ assembler->
|
|
||||||
|
|
||||||
ASSEMBLER_TEST_GENERATE(IcDataAccess, assembler) {
|
|
||||||
Thread* thread = Thread::Current();
|
|
||||||
const String& class_name = String::Handle(Symbols::New(thread, "ownerClass"));
|
|
||||||
const Script& script = Script::Handle();
|
|
||||||
const Class& owner_class = Class::Handle(Class::New(
|
|
||||||
Library::Handle(), class_name, script, TokenPosition::kNoSource));
|
|
||||||
const String& function_name =
|
|
||||||
String::Handle(Symbols::New(thread, "callerFunction"));
|
|
||||||
const Function& function = Function::Handle(Function::New(
|
|
||||||
function_name, RawFunction::kRegularFunction, true, false, false, false,
|
|
||||||
false, owner_class, TokenPosition::kNoSource));
|
|
||||||
|
|
||||||
const String& target_name = String::Handle(String::New("targetFunction"));
|
|
||||||
const intptr_t kTypeArgsLen = 0;
|
|
||||||
const intptr_t kNumArgs = 1;
|
|
||||||
const Array& args_descriptor = Array::Handle(
|
|
||||||
ArgumentsDescriptor::New(kTypeArgsLen, kNumArgs, Object::null_array()));
|
|
||||||
const ICData& ic_data = ICData::ZoneHandle(
|
|
||||||
ICData::New(function, target_name, args_descriptor, 15, 1, false));
|
|
||||||
|
|
||||||
__ LoadObject(S5, ic_data);
|
|
||||||
__ BranchLinkPatchable(*StubCode::OneArgCheckInlineCache_entry());
|
|
||||||
__ Ret();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ASSEMBLER_TEST_RUN(IcDataAccess, test) {
|
|
||||||
uword end = test->payload_start() + test->code().Size();
|
|
||||||
uword return_address = end - 2 * Instr::kInstrSize;
|
|
||||||
ICData& ic_data = ICData::Handle();
|
|
||||||
CodePatcher::GetInstanceCallAt(return_address, test->code(), &ic_data);
|
|
||||||
EXPECT_STREQ("targetFunction",
|
|
||||||
String::Handle(ic_data.target_name()).ToCString());
|
|
||||||
EXPECT_EQ(1, ic_data.NumArgsTested());
|
|
||||||
EXPECT_EQ(0, ic_data.NumberOfChecks());
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace dart
|
|
||||||
|
|
||||||
#endif // TARGET_ARCH_MIPS
|
|
|
@ -718,11 +718,10 @@ RawCode* CompileParsedFunctionHelper::Compile(CompilationPipeline* pipeline) {
|
||||||
HANDLESCOPE(thread());
|
HANDLESCOPE(thread());
|
||||||
|
|
||||||
// We may reattempt compilation if the function needs to be assembled using
|
// We may reattempt compilation if the function needs to be assembled using
|
||||||
// far branches on ARM and MIPS. In the else branch of the setjmp call,
|
// far branches on ARM. In the else branch of the setjmp call, done is set to
|
||||||
// done is set to false, and use_far_branches is set to true if there is a
|
// false, and use_far_branches is set to true if there is a longjmp from the
|
||||||
// longjmp from the ARM or MIPS assemblers. In all other paths through this
|
// ARM assembler. In all other paths through this while loop, done is set to
|
||||||
// while loop, done is set to true. use_far_branches is always false on ia32
|
// true. use_far_branches is always false on ia32 and x64.
|
||||||
// and x64.
|
|
||||||
volatile bool done = false;
|
volatile bool done = false;
|
||||||
// volatile because the variable may be clobbered by a longjmp.
|
// volatile because the variable may be clobbered by a longjmp.
|
||||||
volatile bool use_far_branches = false;
|
volatile bool use_far_branches = false;
|
||||||
|
|
|
@ -1,644 +0,0 @@
|
||||||
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef RUNTIME_VM_CONSTANTS_MIPS_H_
|
|
||||||
#define RUNTIME_VM_CONSTANTS_MIPS_H_
|
|
||||||
|
|
||||||
#include "platform/assert.h"
|
|
||||||
|
|
||||||
namespace dart {
|
|
||||||
|
|
||||||
enum Register {
|
|
||||||
R0 = 0,
|
|
||||||
R1 = 1, // AT aka TMP
|
|
||||||
R2 = 2,
|
|
||||||
R3 = 3,
|
|
||||||
R4 = 4,
|
|
||||||
R5 = 5,
|
|
||||||
R6 = 6,
|
|
||||||
R7 = 7,
|
|
||||||
R8 = 8,
|
|
||||||
R9 = 9,
|
|
||||||
R10 = 10,
|
|
||||||
R11 = 11,
|
|
||||||
R12 = 12,
|
|
||||||
R13 = 13,
|
|
||||||
R14 = 14,
|
|
||||||
R15 = 15,
|
|
||||||
R16 = 16,
|
|
||||||
R17 = 17,
|
|
||||||
R18 = 18,
|
|
||||||
R19 = 19, // THR
|
|
||||||
R20 = 20,
|
|
||||||
R21 = 21,
|
|
||||||
R22 = 22, // CTX
|
|
||||||
R23 = 23, // PP
|
|
||||||
R24 = 24,
|
|
||||||
R25 = 25,
|
|
||||||
R26 = 26,
|
|
||||||
R27 = 27,
|
|
||||||
R28 = 28,
|
|
||||||
R29 = 29, // SP
|
|
||||||
R30 = 30, // FP
|
|
||||||
R31 = 31, // RA
|
|
||||||
kNumberOfCpuRegisters = 32,
|
|
||||||
IMM = 32, // Positive value is easier to encode than kNoRegister in bitfield.
|
|
||||||
kNoRegister = -1, // Signals an illegal register.
|
|
||||||
|
|
||||||
|
|
||||||
// Register aliases.
|
|
||||||
ZR = R0,
|
|
||||||
AT = R1,
|
|
||||||
|
|
||||||
V0 = R2,
|
|
||||||
V1 = R3,
|
|
||||||
|
|
||||||
A0 = R4,
|
|
||||||
A1 = R5,
|
|
||||||
A2 = R6,
|
|
||||||
A3 = R7,
|
|
||||||
|
|
||||||
T0 = R8,
|
|
||||||
T1 = R9,
|
|
||||||
T2 = R10,
|
|
||||||
T3 = R11,
|
|
||||||
T4 = R12,
|
|
||||||
T5 = R13,
|
|
||||||
T6 = R14,
|
|
||||||
T7 = R15,
|
|
||||||
|
|
||||||
S0 = R16,
|
|
||||||
S1 = R17,
|
|
||||||
S2 = R18,
|
|
||||||
S3 = R19,
|
|
||||||
S4 = R20,
|
|
||||||
S5 = R21,
|
|
||||||
S6 = R22,
|
|
||||||
S7 = R23,
|
|
||||||
|
|
||||||
T8 = R24,
|
|
||||||
T9 = R25,
|
|
||||||
|
|
||||||
K0 = R26,
|
|
||||||
K1 = R27,
|
|
||||||
|
|
||||||
GP = R28,
|
|
||||||
SP = R29,
|
|
||||||
FP = R30,
|
|
||||||
RA = R31,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Values for floating point registers.
|
|
||||||
// Double-precision values use register pairs.
|
|
||||||
enum FRegister {
|
|
||||||
F0 = 0,
|
|
||||||
F1 = 1,
|
|
||||||
F2 = 2,
|
|
||||||
F3 = 3,
|
|
||||||
F4 = 4,
|
|
||||||
F5 = 5,
|
|
||||||
F6 = 6,
|
|
||||||
F7 = 7,
|
|
||||||
F8 = 8,
|
|
||||||
F9 = 9,
|
|
||||||
F10 = 10,
|
|
||||||
F11 = 11,
|
|
||||||
F12 = 12,
|
|
||||||
F13 = 13,
|
|
||||||
F14 = 14,
|
|
||||||
F15 = 15,
|
|
||||||
F16 = 16,
|
|
||||||
F17 = 17,
|
|
||||||
F18 = 18,
|
|
||||||
F19 = 19,
|
|
||||||
F20 = 20,
|
|
||||||
F21 = 21,
|
|
||||||
F22 = 22,
|
|
||||||
F23 = 23,
|
|
||||||
F24 = 24,
|
|
||||||
F25 = 25,
|
|
||||||
F26 = 26,
|
|
||||||
F27 = 27,
|
|
||||||
F28 = 28,
|
|
||||||
F29 = 29,
|
|
||||||
F30 = 30,
|
|
||||||
F31 = 31,
|
|
||||||
kNumberOfFRegisters = 32,
|
|
||||||
kNoFRegister = -1,
|
|
||||||
};
|
|
||||||
|
|
||||||
// The double precision floating point registers are concatenated pairs of the
|
|
||||||
// single precision registers, e.g. D0 is F1:F0, D1 is F3:F2, etc.. We only
|
|
||||||
// tell the architecture generic code about the double precision registers, then
|
|
||||||
// convert to the single precision registers when needed in the mips-specific
|
|
||||||
// code.
|
|
||||||
enum DRegister {
|
|
||||||
D0 = 0, // Function return value 1.
|
|
||||||
D1 = 1, // Function return value 2.
|
|
||||||
D2 = 2, // Not preserved.
|
|
||||||
D3 = 3, // Not preserved.
|
|
||||||
D4 = 4, // Not preserved.
|
|
||||||
D5 = 5, // Not preserved.
|
|
||||||
D6 = 6, // Argument 1.
|
|
||||||
D7 = 7, // Argument 2.
|
|
||||||
D8 = 8, // Not preserved.
|
|
||||||
D9 = 9, // Not preserved.
|
|
||||||
D10 = 10, // Preserved.
|
|
||||||
D11 = 11, // Preserved.
|
|
||||||
D12 = 12, // Preserved.
|
|
||||||
D13 = 13, // Preserved.
|
|
||||||
D14 = 14, // Preserved.
|
|
||||||
D15 = 15, // Preserved.
|
|
||||||
kNumberOfDRegisters = 16,
|
|
||||||
kNoDRegister = -1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline FRegister EvenFRegisterOf(DRegister d) {
|
|
||||||
return static_cast<FRegister>(d * 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline FRegister OddFRegisterOf(DRegister d) {
|
|
||||||
return static_cast<FRegister>((d * 2) + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const DRegister DTMP = D9;
|
|
||||||
const FRegister STMP1 = F18;
|
|
||||||
const FRegister STMP2 = F19;
|
|
||||||
|
|
||||||
// Architecture independent aliases.
|
|
||||||
typedef DRegister FpuRegister;
|
|
||||||
const FpuRegister FpuTMP = DTMP;
|
|
||||||
const int kNumberOfFpuRegisters = kNumberOfDRegisters;
|
|
||||||
const FpuRegister kNoFpuRegister = kNoDRegister;
|
|
||||||
|
|
||||||
|
|
||||||
// Register aliases.
|
|
||||||
const Register TMP = AT; // Used as scratch register by assembler.
|
|
||||||
const Register TMP2 = kNoRegister; // No second assembler scratch register.
|
|
||||||
const Register CTX = S6; // Location of current context at method entry.
|
|
||||||
const Register CODE_REG = S6;
|
|
||||||
const Register PP = S7; // Caches object pool pointer in generated code.
|
|
||||||
const Register SPREG = SP; // Stack pointer register.
|
|
||||||
const Register FPREG = FP; // Frame pointer register.
|
|
||||||
const Register LRREG = RA; // Link register.
|
|
||||||
const Register ICREG = S5; // IC data register.
|
|
||||||
const Register ARGS_DESC_REG = S4;
|
|
||||||
const Register THR = S3; // Caches current thread in generated code.
|
|
||||||
const Register CALLEE_SAVED_TEMP = S5;
|
|
||||||
|
|
||||||
// The code that generates a comparison can be far away from the code that
|
|
||||||
// generates the branch that uses the result of that comparison. In this case,
|
|
||||||
// CMPRES1 and CMPRES2 are used for the results of the comparison. We need two
|
|
||||||
// since TMP is clobbered by a far branch.
|
|
||||||
const Register CMPRES1 = T8;
|
|
||||||
const Register CMPRES2 = T9;
|
|
||||||
|
|
||||||
// Exception object is passed in this register to the catch handlers when an
|
|
||||||
// exception is thrown.
|
|
||||||
const Register kExceptionObjectReg = V0;
|
|
||||||
|
|
||||||
// Stack trace object is passed in this register to the catch handlers when
|
|
||||||
// an exception is thrown.
|
|
||||||
const Register kStackTraceObjectReg = V1;
|
|
||||||
|
|
||||||
|
|
||||||
typedef uint32_t RegList;
|
|
||||||
const RegList kAllCpuRegistersList = 0xFFFFFFFF;
|
|
||||||
|
|
||||||
const RegList kAbiArgumentCpuRegs =
|
|
||||||
(1 << A0) | (1 << A1) | (1 << A2) | (1 << A3);
|
|
||||||
const RegList kAbiPreservedCpuRegs = (1 << S0) | (1 << S1) | (1 << S2) |
|
|
||||||
(1 << S3) | (1 << S4) | (1 << S5) |
|
|
||||||
(1 << S6) | (1 << S7);
|
|
||||||
const int kAbiPreservedCpuRegCount = 8;
|
|
||||||
|
|
||||||
// FPU registers 20 - 31 are preserved across calls.
|
|
||||||
const FRegister kAbiFirstPreservedFpuReg = F20;
|
|
||||||
const FRegister kAbiLastPreservedFpuReg =
|
|
||||||
static_cast<FRegister>(kNumberOfFRegisters - 1);
|
|
||||||
const int kAbiPreservedFpuRegCount = 12;
|
|
||||||
|
|
||||||
const RegList kReservedCpuRegisters =
|
|
||||||
(1 << SPREG) | (1 << FPREG) | (1 << TMP) | (1 << PP) | (1 << THR) |
|
|
||||||
(1 << CTX) | (1 << ZR) | (1 << CMPRES1) | (1 << CMPRES2) | (1 << K0) |
|
|
||||||
(1 << K1) | (1 << GP) | (1 << RA);
|
|
||||||
// CPU registers available to Dart allocator.
|
|
||||||
const RegList kDartAvailableCpuRegs =
|
|
||||||
kAllCpuRegistersList & ~kReservedCpuRegisters;
|
|
||||||
// Registers available to Dart that are not preserved by runtime calls.
|
|
||||||
const RegList kDartVolatileCpuRegs =
|
|
||||||
kDartAvailableCpuRegs & ~kAbiPreservedCpuRegs;
|
|
||||||
const int kDartVolatileCpuRegCount = 14;
|
|
||||||
const Register kDartFirstVolatileCpuReg = R2;
|
|
||||||
const Register kDartLastVolatileCpuReg = R15;
|
|
||||||
|
|
||||||
// FPU registers 0 - 19 are not preserved across calls.
|
|
||||||
const FRegister kDartFirstVolatileFpuReg = F0;
|
|
||||||
const FRegister kDartLastVolatileFpuReg = F19;
|
|
||||||
const int kDartVolatileFpuRegCount = 20;
|
|
||||||
|
|
||||||
|
|
||||||
// There is no status register on MIPS. Instead of representing a condition
|
|
||||||
// code, type Condition (see assembler_mips.h) represents a pair of operands and
|
|
||||||
// a relation operator between them.
|
|
||||||
enum RelationOperator {
|
|
||||||
AL, // always
|
|
||||||
NV, // never
|
|
||||||
EQ, // equal
|
|
||||||
NE, // not equal
|
|
||||||
GT, // greater than
|
|
||||||
GE, // greater equal
|
|
||||||
LT, // less than
|
|
||||||
LE, // less equal
|
|
||||||
UGT, // unsigned greater than
|
|
||||||
UGE, // unsigned greater equal
|
|
||||||
ULT, // unsigned less than
|
|
||||||
ULE, // unsigned less equal
|
|
||||||
INVALID_RELATION
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Constants used for the decoding or encoding of the individual fields of
|
|
||||||
// instructions. Based on the "Table 4.25 CPU Instruction Format Fields".
|
|
||||||
enum InstructionFields {
|
|
||||||
kOpcodeShift = 26,
|
|
||||||
kOpcodeBits = 6,
|
|
||||||
kRsShift = 21,
|
|
||||||
kRsBits = 5,
|
|
||||||
kFmtShift = 21,
|
|
||||||
kFmtBits = 5,
|
|
||||||
kRtShift = 16,
|
|
||||||
kRtBits = 5,
|
|
||||||
kFtShift = 16,
|
|
||||||
kFtBits = 5,
|
|
||||||
kRdShift = 11,
|
|
||||||
kRdBits = 5,
|
|
||||||
kFsShift = 11,
|
|
||||||
kFsBits = 5,
|
|
||||||
kSaShift = 6,
|
|
||||||
kSaBits = 5,
|
|
||||||
kFdShift = 6,
|
|
||||||
kFdBits = 5,
|
|
||||||
kFunctionShift = 0,
|
|
||||||
kFunctionBits = 6,
|
|
||||||
kCop1FnShift = 0,
|
|
||||||
kCop1FnBits = 6,
|
|
||||||
kCop1SubShift = 21,
|
|
||||||
kCop1SubBits = 5,
|
|
||||||
kImmShift = 0,
|
|
||||||
kImmBits = 16,
|
|
||||||
kInstrShift = 0,
|
|
||||||
kInstrBits = 26,
|
|
||||||
kBreakCodeShift = 6,
|
|
||||||
kBreakCodeBits = 20,
|
|
||||||
kFpuCCShift = 8,
|
|
||||||
kFpuCCBits = 3,
|
|
||||||
|
|
||||||
kBranchOffsetMask = 0x0000ffff,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
enum Opcode {
|
|
||||||
SPECIAL = 0,
|
|
||||||
REGIMM = 1,
|
|
||||||
J = 2,
|
|
||||||
JAL = 3,
|
|
||||||
BEQ = 4,
|
|
||||||
BNE = 5,
|
|
||||||
BLEZ = 6,
|
|
||||||
BGTZ = 7,
|
|
||||||
ADDI = 8,
|
|
||||||
ADDIU = 9,
|
|
||||||
SLTI = 10,
|
|
||||||
SLTIU = 11,
|
|
||||||
ANDI = 12,
|
|
||||||
ORI = 13,
|
|
||||||
XORI = 14,
|
|
||||||
LUI = 15,
|
|
||||||
CPO0 = 16,
|
|
||||||
COP1 = 17,
|
|
||||||
COP2 = 18,
|
|
||||||
COP1X = 19,
|
|
||||||
BEQL = 20,
|
|
||||||
BNEL = 21,
|
|
||||||
BLEZL = 22,
|
|
||||||
BGTZL = 23,
|
|
||||||
SPECIAL2 = 28,
|
|
||||||
JALX = 29,
|
|
||||||
SPECIAL3 = 31,
|
|
||||||
LB = 32,
|
|
||||||
LH = 33,
|
|
||||||
LWL = 34,
|
|
||||||
LW = 35,
|
|
||||||
LBU = 36,
|
|
||||||
LHU = 37,
|
|
||||||
LWR = 38,
|
|
||||||
SB = 40,
|
|
||||||
SH = 41,
|
|
||||||
SWL = 42,
|
|
||||||
SW = 43,
|
|
||||||
SWR = 46,
|
|
||||||
CACHE = 47,
|
|
||||||
LL = 48,
|
|
||||||
LWC1 = 49,
|
|
||||||
LWC2 = 50,
|
|
||||||
PREF = 51,
|
|
||||||
LDC1 = 53,
|
|
||||||
LDC2 = 54,
|
|
||||||
SC = 56,
|
|
||||||
SWC1 = 57,
|
|
||||||
SWC2 = 58,
|
|
||||||
SDC1 = 61,
|
|
||||||
SDC2 = 62,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
enum SpecialFunction {
|
|
||||||
// SPECIAL opcodes.
|
|
||||||
SLL = 0,
|
|
||||||
MOVCI = 1,
|
|
||||||
SRL = 2,
|
|
||||||
SRA = 3,
|
|
||||||
SLLV = 4,
|
|
||||||
SRLV = 6,
|
|
||||||
SRAV = 7,
|
|
||||||
JR = 8,
|
|
||||||
JALR = 9,
|
|
||||||
MOVZ = 10,
|
|
||||||
MOVN = 11,
|
|
||||||
SYSCALL = 12,
|
|
||||||
BREAK = 13,
|
|
||||||
SYNC = 15,
|
|
||||||
MFHI = 16,
|
|
||||||
MTHI = 17,
|
|
||||||
MFLO = 18,
|
|
||||||
MTLO = 19,
|
|
||||||
MULT = 24,
|
|
||||||
MULTU = 25,
|
|
||||||
DIV = 26,
|
|
||||||
DIVU = 27,
|
|
||||||
ADD = 32,
|
|
||||||
ADDU = 33,
|
|
||||||
SUB = 34,
|
|
||||||
SUBU = 35,
|
|
||||||
AND = 36,
|
|
||||||
OR = 37,
|
|
||||||
XOR = 38,
|
|
||||||
NOR = 39,
|
|
||||||
SLT = 42,
|
|
||||||
SLTU = 43,
|
|
||||||
TGE = 48,
|
|
||||||
TGEU = 49,
|
|
||||||
TLT = 50,
|
|
||||||
TLTU = 51,
|
|
||||||
TEQ = 52,
|
|
||||||
TNE = 54,
|
|
||||||
|
|
||||||
// SPECIAL2 opcodes.
|
|
||||||
MADD = 0,
|
|
||||||
MADDU = 1,
|
|
||||||
CLZ = 32,
|
|
||||||
CLO = 33,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
enum RtRegImm {
|
|
||||||
BLTZ = 0,
|
|
||||||
BGEZ = 1,
|
|
||||||
BLTZL = 2,
|
|
||||||
BGEZL = 3,
|
|
||||||
TGEI = 8,
|
|
||||||
TGEIU = 9,
|
|
||||||
TLTI = 10,
|
|
||||||
TLTIU = 11,
|
|
||||||
TEQI = 12,
|
|
||||||
TNEI = 14,
|
|
||||||
BLTZAL = 16,
|
|
||||||
BGEZAL = 17,
|
|
||||||
BLTZALL = 18,
|
|
||||||
BGEZALL = 19,
|
|
||||||
SYNCI = 31,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
enum Cop1Function {
|
|
||||||
COP1_ADD = 0x00,
|
|
||||||
COP1_SUB = 0x01,
|
|
||||||
COP1_MUL = 0x02,
|
|
||||||
COP1_DIV = 0x03,
|
|
||||||
COP1_SQRT = 0x04,
|
|
||||||
COP1_MOV = 0x06,
|
|
||||||
COP1_NEG = 0x07,
|
|
||||||
COP1_TRUNC_W = 0x0d,
|
|
||||||
COP1_CVT_S = 0x20,
|
|
||||||
COP1_CVT_D = 0x21,
|
|
||||||
COP1_C_F = 0x30,
|
|
||||||
COP1_C_UN = 0x31,
|
|
||||||
COP1_C_EQ = 0x32,
|
|
||||||
COP1_C_UEQ = 0x33,
|
|
||||||
COP1_C_OLT = 0x34,
|
|
||||||
COP1_C_ULT = 0x35,
|
|
||||||
COP1_C_OLE = 0x36,
|
|
||||||
COP1_C_ULE = 0x37,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
enum Cop1Sub {
|
|
||||||
COP1_MF = 0,
|
|
||||||
COP1_MT = 4,
|
|
||||||
COP1_BC = 8,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
enum Format {
|
|
||||||
FMT_S = 16,
|
|
||||||
FMT_D = 17,
|
|
||||||
FMT_W = 20,
|
|
||||||
FMT_L = 21,
|
|
||||||
FMT_PS = 22,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class Instr {
|
|
||||||
public:
|
|
||||||
enum {
|
|
||||||
kInstrSize = 4,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const int32_t kNopInstruction = 0;
|
|
||||||
|
|
||||||
// Reserved break instruction codes.
|
|
||||||
static const int32_t kBreakPointCode = 0xdeb0; // For breakpoint.
|
|
||||||
static const int32_t kStopMessageCode = 0xdeb1; // For Stop(message).
|
|
||||||
static const int32_t kSimulatorBreakCode = 0xdeb2; // For breakpoint in sim.
|
|
||||||
static const int32_t kSimulatorRedirectCode = 0xca11; // For redirection.
|
|
||||||
|
|
||||||
static const int32_t kBreakPointZeroInstruction =
|
|
||||||
(SPECIAL << kOpcodeShift) | (BREAK << kFunctionShift);
|
|
||||||
|
|
||||||
// Breakpoint instruction filling assembler code buffers in debug mode.
|
|
||||||
static const int32_t kBreakPointInstruction =
|
|
||||||
kBreakPointZeroInstruction | (kBreakPointCode << kBreakCodeShift);
|
|
||||||
|
|
||||||
// Breakpoint instruction used by the simulator.
|
|
||||||
// Should be distinct from kBreakPointInstruction and from a typical user
|
|
||||||
// breakpoint inserted in generated code for debugging, e.g. break_(0).
|
|
||||||
static const int32_t kSimulatorBreakpointInstruction =
|
|
||||||
kBreakPointZeroInstruction | (kSimulatorBreakCode << kBreakCodeShift);
|
|
||||||
|
|
||||||
// Runtime call redirection instruction used by the simulator.
|
|
||||||
static const int32_t kSimulatorRedirectInstruction =
|
|
||||||
kBreakPointZeroInstruction | (kSimulatorRedirectCode << kBreakCodeShift);
|
|
||||||
|
|
||||||
// Get the raw instruction bits.
|
|
||||||
inline int32_t InstructionBits() const {
|
|
||||||
return *reinterpret_cast<const int32_t*>(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the raw instruction bits to value.
|
|
||||||
inline void SetInstructionBits(int32_t value) {
|
|
||||||
*reinterpret_cast<int32_t*>(this) = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void SetImmInstrBits(Opcode op,
|
|
||||||
Register rs,
|
|
||||||
Register rt,
|
|
||||||
uint16_t imm) {
|
|
||||||
SetInstructionBits(op << kOpcodeShift | rs << kRsShift | rt << kRtShift |
|
|
||||||
imm << kImmShift);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void SetSpecialInstrBits(SpecialFunction f,
|
|
||||||
Register rs,
|
|
||||||
Register rt,
|
|
||||||
Register rd) {
|
|
||||||
SetInstructionBits(SPECIAL << kOpcodeShift | f << kFunctionShift |
|
|
||||||
rs << kRsShift | rt << kRtShift | rd << kRdShift);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read one particular bit out of the instruction bits.
|
|
||||||
inline int32_t Bit(int nr) const { return (InstructionBits() >> nr) & 1; }
|
|
||||||
|
|
||||||
// Read a bit field out of the instruction bits.
|
|
||||||
inline int32_t Bits(int shift, int count) const {
|
|
||||||
return (InstructionBits() >> shift) & ((1 << count) - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Accessors to the different named fields used in the MIPS encoding.
|
|
||||||
inline Opcode OpcodeField() const {
|
|
||||||
return static_cast<Opcode>(Bits(kOpcodeShift, kOpcodeBits));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void SetOpcodeField(Opcode b) {
|
|
||||||
int32_t instr = InstructionBits();
|
|
||||||
int32_t mask = ((1 << kOpcodeBits) - 1) << kOpcodeShift;
|
|
||||||
SetInstructionBits((b << kOpcodeShift) | (instr & ~mask));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Register RsField() const {
|
|
||||||
return static_cast<Register>(Bits(kRsShift, kRsBits));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Register RtField() const {
|
|
||||||
return static_cast<Register>(Bits(kRtShift, kRtBits));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Register RdField() const {
|
|
||||||
return static_cast<Register>(Bits(kRdShift, kRdBits));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline FRegister FsField() const {
|
|
||||||
return static_cast<FRegister>(Bits(kFsShift, kFsBits));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline FRegister FtField() const {
|
|
||||||
return static_cast<FRegister>(Bits(kFtShift, kFtBits));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline FRegister FdField() const {
|
|
||||||
return static_cast<FRegister>(Bits(kFdShift, kFdBits));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int SaField() const { return Bits(kSaShift, kSaBits); }
|
|
||||||
|
|
||||||
inline int32_t UImmField() const { return Bits(kImmShift, kImmBits); }
|
|
||||||
|
|
||||||
inline int32_t SImmField() const {
|
|
||||||
// Sign-extend the imm field.
|
|
||||||
return (Bits(kImmShift, kImmBits) << (32 - kImmBits)) >> (32 - kImmBits);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int32_t BreakCodeField() const {
|
|
||||||
return Bits(kBreakCodeShift, kBreakCodeBits);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline SpecialFunction FunctionField() const {
|
|
||||||
return static_cast<SpecialFunction>(Bits(kFunctionShift, kFunctionBits));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline RtRegImm RegImmFnField() const {
|
|
||||||
return static_cast<RtRegImm>(Bits(kRtShift, kRtBits));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void SetRegImmFnField(RtRegImm b) {
|
|
||||||
int32_t instr = InstructionBits();
|
|
||||||
int32_t mask = ((1 << kRtBits) - 1) << kRtShift;
|
|
||||||
SetInstructionBits((b << kRtShift) | (instr & ~mask));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool IsBreakPoint() {
|
|
||||||
return (OpcodeField() == SPECIAL) && (FunctionField() == BREAK);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Cop1Function Cop1FunctionField() const {
|
|
||||||
return static_cast<Cop1Function>(Bits(kCop1FnShift, kCop1FnBits));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Cop1Sub Cop1SubField() const {
|
|
||||||
return static_cast<Cop1Sub>(Bits(kCop1SubShift, kCop1SubBits));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool HasFormat() const {
|
|
||||||
return (OpcodeField() == COP1) && (Bit(25) == 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Format FormatField() const {
|
|
||||||
return static_cast<Format>(Bits(kFmtShift, kFmtBits));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int32_t FpuCCField() const { return Bits(kFpuCCShift, kFpuCCBits); }
|
|
||||||
|
|
||||||
// Instructions are read out of a code stream. The only way to get a
|
|
||||||
// reference to an instruction is to convert a pc. There is no way
|
|
||||||
// to allocate or create instances of class Instr.
|
|
||||||
// Use the At(pc) function to create references to Instr.
|
|
||||||
static Instr* At(uword pc) { return reinterpret_cast<Instr*>(pc); }
|
|
||||||
|
|
||||||
#if defined(DEBUG)
|
|
||||||
inline void AssertIsImmInstr(Opcode op,
|
|
||||||
Register rs,
|
|
||||||
Register rt,
|
|
||||||
int32_t imm) {
|
|
||||||
ASSERT((OpcodeField() == op) && (RsField() == rs) && (RtField() == rt) &&
|
|
||||||
(SImmField() == imm));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void AssertIsSpecialInstr(SpecialFunction f,
|
|
||||||
Register rs,
|
|
||||||
Register rt,
|
|
||||||
Register rd) {
|
|
||||||
ASSERT((OpcodeField() == SPECIAL) && (FunctionField() == f) &&
|
|
||||||
(RsField() == rs) && (RtField() == rt) && (RdField() == rd));
|
|
||||||
}
|
|
||||||
#endif // defined(DEBUG)
|
|
||||||
|
|
||||||
private:
|
|
||||||
DISALLOW_ALLOCATION();
|
|
||||||
DISALLOW_IMPLICIT_CONSTRUCTORS(Instr);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace dart
|
|
||||||
|
|
||||||
#endif // RUNTIME_VM_CONSTANTS_MIPS_H_
|
|
|
@ -31,8 +31,6 @@ class CPU : public AllStatic {
|
||||||
#include "vm/cpu_arm.h"
|
#include "vm/cpu_arm.h"
|
||||||
#elif defined(TARGET_ARCH_ARM64)
|
#elif defined(TARGET_ARCH_ARM64)
|
||||||
#include "vm/cpu_arm64.h"
|
#include "vm/cpu_arm64.h"
|
||||||
#elif defined(TARGET_ARCH_MIPS)
|
|
||||||
#include "vm/cpu_mips.h"
|
|
||||||
#elif defined(TARGET_ARCH_DBC)
|
#elif defined(TARGET_ARCH_DBC)
|
||||||
#include "vm/cpu_dbc.h"
|
#include "vm/cpu_dbc.h"
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -1,109 +0,0 @@
|
||||||
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
#include "vm/globals.h"
|
|
||||||
#if defined(TARGET_ARCH_MIPS)
|
|
||||||
|
|
||||||
#include "vm/cpu.h"
|
|
||||||
#include "vm/cpu_mips.h"
|
|
||||||
|
|
||||||
#include "vm/cpuinfo.h"
|
|
||||||
#include "vm/simulator.h"
|
|
||||||
|
|
||||||
#if !defined(USING_SIMULATOR)
|
|
||||||
#include <asm/cachectl.h> /* NOLINT */
|
|
||||||
#include <sys/syscall.h> /* NOLINT */
|
|
||||||
#include <unistd.h> /* NOLINT */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace dart {
|
|
||||||
|
|
||||||
void CPU::FlushICache(uword start, uword size) {
|
|
||||||
#if !defined(USING_SIMULATOR)
|
|
||||||
int res;
|
|
||||||
// See http://www.linux-mips.org/wiki/Cacheflush_Syscall.
|
|
||||||
res = syscall(__NR_cacheflush, start, size, ICACHE);
|
|
||||||
ASSERT(res == 0);
|
|
||||||
#else // defined(HOST_ARCH_MIPS)
|
|
||||||
// When running in simulated mode we do not need to flush the ICache because
|
|
||||||
// we are not running on the actual hardware.
|
|
||||||
#endif // defined(HOST_ARCH_MIPS)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const char* CPU::Id() {
|
|
||||||
return
|
|
||||||
#if defined(USING_SIMULATOR)
|
|
||||||
"sim"
|
|
||||||
#endif // !defined(HOST_ARCH_MIPS)
|
|
||||||
"mips";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const char* HostCPUFeatures::hardware_ = NULL;
|
|
||||||
MIPSVersion HostCPUFeatures::mips_version_ = MIPSvUnknown;
|
|
||||||
#if defined(DEBUG)
|
|
||||||
bool HostCPUFeatures::initialized_ = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if !defined(USING_SIMULATOR)
|
|
||||||
void HostCPUFeatures::InitOnce() {
|
|
||||||
CpuInfo::InitOnce();
|
|
||||||
hardware_ = CpuInfo::GetCpuModel();
|
|
||||||
// Has a floating point unit.
|
|
||||||
ASSERT(CpuInfo::FieldContains(kCpuInfoModel, "FPU"));
|
|
||||||
|
|
||||||
// We want to know the ISA version, but on MIPS, CpuInfo can't tell us, so
|
|
||||||
// we use the same ISA version that Dart's C++ compiler targeted.
|
|
||||||
#if defined(_MIPS_ARCH_MIPS32R2)
|
|
||||||
mips_version_ = MIPS32r2;
|
|
||||||
#elif defined(_MIPS_ARCH_MIPS32)
|
|
||||||
mips_version_ = MIPS32;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(DEBUG)
|
|
||||||
initialized_ = true;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void HostCPUFeatures::Cleanup() {
|
|
||||||
DEBUG_ASSERT(initialized_);
|
|
||||||
#if defined(DEBUG)
|
|
||||||
initialized_ = false;
|
|
||||||
#endif
|
|
||||||
ASSERT(hardware_ != NULL);
|
|
||||||
free(const_cast<char*>(hardware_));
|
|
||||||
hardware_ = NULL;
|
|
||||||
CpuInfo::Cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
void HostCPUFeatures::InitOnce() {
|
|
||||||
CpuInfo::InitOnce();
|
|
||||||
hardware_ = CpuInfo::GetCpuModel();
|
|
||||||
mips_version_ = MIPS32r2;
|
|
||||||
#if defined(DEBUG)
|
|
||||||
initialized_ = true;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void HostCPUFeatures::Cleanup() {
|
|
||||||
DEBUG_ASSERT(initialized_);
|
|
||||||
#if defined(DEBUG)
|
|
||||||
initialized_ = false;
|
|
||||||
#endif
|
|
||||||
ASSERT(hardware_ != NULL);
|
|
||||||
free(const_cast<char*>(hardware_));
|
|
||||||
hardware_ = NULL;
|
|
||||||
CpuInfo::Cleanup();
|
|
||||||
}
|
|
||||||
#endif // defined(HOST_ARCH_MIPS)
|
|
||||||
|
|
||||||
} // namespace dart
|
|
||||||
|
|
||||||
#endif // defined TARGET_ARCH_MIPS
|
|
|
@ -1,58 +0,0 @@
|
||||||
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef RUNTIME_VM_CPU_MIPS_H_
|
|
||||||
#define RUNTIME_VM_CPU_MIPS_H_
|
|
||||||
|
|
||||||
#include "vm/allocation.h"
|
|
||||||
|
|
||||||
namespace dart {
|
|
||||||
|
|
||||||
// TargetCPUFeatures gives CPU features for the architecture that we are
|
|
||||||
// generating code for. HostCPUFeatures gives the CPU features for the
|
|
||||||
// architecture that we are actually running on. When the architectures
|
|
||||||
// are the same, TargetCPUFeatures will query HostCPUFeatures. When they are
|
|
||||||
// different (i.e. we are running in a simulator), HostCPUFeatures will
|
|
||||||
// additionally mock the options needed for the target architecture so that
|
|
||||||
// they may be altered for testing.
|
|
||||||
|
|
||||||
enum MIPSVersion {
|
|
||||||
MIPS32,
|
|
||||||
MIPS32r2,
|
|
||||||
MIPSvUnknown,
|
|
||||||
};
|
|
||||||
|
|
||||||
class HostCPUFeatures : public AllStatic {
|
|
||||||
public:
|
|
||||||
static void InitOnce();
|
|
||||||
static void Cleanup();
|
|
||||||
static const char* hardware() {
|
|
||||||
DEBUG_ASSERT(initialized_);
|
|
||||||
return hardware_;
|
|
||||||
}
|
|
||||||
static MIPSVersion mips_version() {
|
|
||||||
DEBUG_ASSERT(initialized_);
|
|
||||||
return mips_version_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static const char* hardware_;
|
|
||||||
static MIPSVersion mips_version_;
|
|
||||||
#if defined(DEBUG)
|
|
||||||
static bool initialized_;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
class TargetCPUFeatures : public AllStatic {
|
|
||||||
public:
|
|
||||||
static void InitOnce() { HostCPUFeatures::InitOnce(); }
|
|
||||||
static void Cleanup() { HostCPUFeatures::Cleanup(); }
|
|
||||||
static const char* hardware() { return HostCPUFeatures::hardware(); }
|
|
||||||
static bool double_truncate_round_supported() { return false; }
|
|
||||||
static MIPSVersion mips_version() { return HostCPUFeatures::mips_version(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace dart
|
|
||||||
|
|
||||||
#endif // RUNTIME_VM_CPU_MIPS_H_
|
|
|
@ -26,12 +26,6 @@ VM_UNIT_TEST_CASE(Id) {
|
||||||
#else // defined(HOST_ARCH_ARM64)
|
#else // defined(HOST_ARCH_ARM64)
|
||||||
EXPECT_STREQ("simarm64", CPU::Id());
|
EXPECT_STREQ("simarm64", CPU::Id());
|
||||||
#endif // defined(HOST_ARCH_ARM64)
|
#endif // defined(HOST_ARCH_ARM64)
|
||||||
#elif defined(TARGET_ARCH_MIPS)
|
|
||||||
#if defined(HOST_ARCH_MIPS)
|
|
||||||
EXPECT_STREQ("mips", CPU::Id());
|
|
||||||
#else // defined(HOST_ARCH_MIPS)
|
|
||||||
EXPECT_STREQ("simmips", CPU::Id());
|
|
||||||
#endif // defined(HOST_ARCH_MIPS)
|
|
||||||
#elif defined(TARGET_ARCH_DBC)
|
#elif defined(TARGET_ARCH_DBC)
|
||||||
EXPECT_STREQ("dbc", CPU::Id());
|
EXPECT_STREQ("dbc", CPU::Id());
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -32,12 +32,6 @@ void CpuInfo::InitOnce() {
|
||||||
fields_[kCpuInfoHardware] = "Hardware";
|
fields_[kCpuInfoHardware] = "Hardware";
|
||||||
fields_[kCpuInfoFeatures] = "Features";
|
fields_[kCpuInfoFeatures] = "Features";
|
||||||
fields_[kCpuInfoArchitecture] = "CPU architecture";
|
fields_[kCpuInfoArchitecture] = "CPU architecture";
|
||||||
#elif defined(HOST_ARCH_MIPS)
|
|
||||||
fields_[kCpuInfoProcessor] = "system type";
|
|
||||||
fields_[kCpuInfoModel] = "cpu model";
|
|
||||||
fields_[kCpuInfoHardware] = "cpu model";
|
|
||||||
fields_[kCpuInfoFeatures] = "ASEs implemented";
|
|
||||||
fields_[kCpuInfoArchitecture] = "CPU architecture";
|
|
||||||
#else
|
#else
|
||||||
#error Unrecognized target architecture
|
#error Unrecognized target architecture
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include "platform/assert.h"
|
#include "platform/assert.h"
|
||||||
|
|
||||||
// As with Windows, on IA32 and X64, we use the cpuid instruction.
|
// As with Windows, on IA32 and X64, we use the cpuid instruction.
|
||||||
// The analogous instruction is privileged on ARM and MIPS, so we resort to
|
// The analogous instruction is privileged on ARM, so we resort to
|
||||||
// reading from /proc/cpuinfo.
|
// reading from /proc/cpuinfo.
|
||||||
|
|
||||||
namespace dart {
|
namespace dart {
|
||||||
|
@ -45,14 +45,6 @@ void CpuInfo::InitOnce() {
|
||||||
fields_[kCpuInfoArchitecture] = "CPU architecture";
|
fields_[kCpuInfoArchitecture] = "CPU architecture";
|
||||||
method_ = kCpuInfoSystem;
|
method_ = kCpuInfoSystem;
|
||||||
ProcCpuInfo::InitOnce();
|
ProcCpuInfo::InitOnce();
|
||||||
#elif defined(HOST_ARCH_MIPS)
|
|
||||||
fields_[kCpuInfoProcessor] = "system type";
|
|
||||||
fields_[kCpuInfoModel] = "cpu model";
|
|
||||||
fields_[kCpuInfoHardware] = "cpu model";
|
|
||||||
fields_[kCpuInfoFeatures] = "ASEs implemented";
|
|
||||||
fields_[kCpuInfoArchitecture] = "CPU architecture";
|
|
||||||
method_ = kCpuInfoSystem;
|
|
||||||
ProcCpuInfo::InitOnce();
|
|
||||||
#else
|
#else
|
||||||
#error Unrecognized target architecture
|
#error Unrecognized target architecture
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -97,16 +97,6 @@ static void CheckOffsets() {
|
||||||
CHECK_OFFSET(Isolate::object_store_offset(), 28);
|
CHECK_OFFSET(Isolate::object_store_offset(), 28);
|
||||||
NOT_IN_PRODUCT(CHECK_OFFSET(sizeof(ClassHeapStats), 120));
|
NOT_IN_PRODUCT(CHECK_OFFSET(sizeof(ClassHeapStats), 120));
|
||||||
#endif
|
#endif
|
||||||
#if defined(TARGET_ARCH_MIPS)
|
|
||||||
// These offsets are embedded in precompiled instructions. We need simmips
|
|
||||||
// (compiler) and mips (runtime) to agree.
|
|
||||||
CHECK_OFFSET(Heap::TopOffset(Heap::kNew), 8);
|
|
||||||
CHECK_OFFSET(Thread::stack_limit_offset(), 4);
|
|
||||||
CHECK_OFFSET(Thread::object_null_offset(), 40);
|
|
||||||
CHECK_OFFSET(SingleTargetCache::upper_limit_offset(), 14);
|
|
||||||
CHECK_OFFSET(Isolate::object_store_offset(), 28);
|
|
||||||
NOT_IN_PRODUCT(CHECK_OFFSET(sizeof(ClassHeapStats), 120));
|
|
||||||
#endif
|
|
||||||
#if defined(TARGET_ARCH_ARM64)
|
#if defined(TARGET_ARCH_ARM64)
|
||||||
// These offsets are embedded in precompiled instructions. We need simarm64
|
// These offsets are embedded in precompiled instructions. We need simarm64
|
||||||
// (compiler) and arm64 (runtime) to agree.
|
// (compiler) and arm64 (runtime) to agree.
|
||||||
|
@ -701,8 +691,6 @@ const char* Dart::FeaturesString(Isolate* isolate, Snapshot::Kind kind) {
|
||||||
: " softfp");
|
: " softfp");
|
||||||
#elif defined(TARGET_ARCH_ARM64)
|
#elif defined(TARGET_ARCH_ARM64)
|
||||||
buffer.AddString(" arm64");
|
buffer.AddString(" arm64");
|
||||||
#elif defined(TARGET_ARCH_MIPS)
|
|
||||||
buffer.AddString(" mips");
|
|
||||||
#elif defined(TARGET_ARCH_IA32)
|
#elif defined(TARGET_ARCH_IA32)
|
||||||
buffer.AddString(" ia32");
|
buffer.AddString(" ia32");
|
||||||
#elif defined(TARGET_ARCH_X64)
|
#elif defined(TARGET_ARCH_X64)
|
||||||
|
|
|
@ -1,64 +0,0 @@
|
||||||
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
#include "vm/globals.h"
|
|
||||||
#if defined(TARGET_ARCH_MIPS)
|
|
||||||
|
|
||||||
#include "vm/code_patcher.h"
|
|
||||||
#include "vm/cpu.h"
|
|
||||||
#include "vm/debugger.h"
|
|
||||||
#include "vm/instructions.h"
|
|
||||||
#include "vm/stub_code.h"
|
|
||||||
|
|
||||||
namespace dart {
|
|
||||||
|
|
||||||
#ifndef PRODUCT
|
|
||||||
|
|
||||||
RawCode* CodeBreakpoint::OrigStubAddress() const {
|
|
||||||
return saved_value_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CodeBreakpoint::PatchCode() {
|
|
||||||
ASSERT(!is_enabled_);
|
|
||||||
Code& stub_target = Code::Handle();
|
|
||||||
switch (breakpoint_kind_) {
|
|
||||||
case RawPcDescriptors::kIcCall:
|
|
||||||
case RawPcDescriptors::kUnoptStaticCall:
|
|
||||||
stub_target = StubCode::ICCallBreakpoint_entry()->code();
|
|
||||||
break;
|
|
||||||
case RawPcDescriptors::kRuntimeCall:
|
|
||||||
stub_target = StubCode::RuntimeCallBreakpoint_entry()->code();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
const Code& code = Code::Handle(code_);
|
|
||||||
saved_value_ = CodePatcher::GetStaticCallTargetAt(pc_, code);
|
|
||||||
CodePatcher::PatchStaticCallAt(pc_, code, stub_target);
|
|
||||||
is_enabled_ = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CodeBreakpoint::RestoreCode() {
|
|
||||||
ASSERT(is_enabled_);
|
|
||||||
const Code& code = Code::Handle(code_);
|
|
||||||
switch (breakpoint_kind_) {
|
|
||||||
case RawPcDescriptors::kIcCall:
|
|
||||||
case RawPcDescriptors::kUnoptStaticCall:
|
|
||||||
case RawPcDescriptors::kRuntimeCall: {
|
|
||||||
CodePatcher::PatchStaticCallAt(pc_, code, Code::Handle(saved_value_));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
is_enabled_ = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // !PRODUCT
|
|
||||||
|
|
||||||
} // namespace dart
|
|
||||||
|
|
||||||
#endif // defined TARGET_ARCH_MIPS
|
|
|
@ -73,7 +73,7 @@ DeoptContext::DeoptContext(const StackFrame* frame,
|
||||||
function.HasOptionalParameters() ? 0 : function.num_fixed_parameters();
|
function.HasOptionalParameters() ? 0 : function.num_fixed_parameters();
|
||||||
|
|
||||||
// The fixed size section of the (fake) Dart frame called via a stub by the
|
// The fixed size section of the (fake) Dart frame called via a stub by the
|
||||||
// optimized function contains FP, PP (ARM and MIPS only), PC-marker and
|
// optimized function contains FP, PP (ARM only), PC-marker and
|
||||||
// return-address. This section is copied as well, so that its contained
|
// return-address. This section is copied as well, so that its contained
|
||||||
// values can be updated before returning to the deoptimized function.
|
// values can be updated before returning to the deoptimized function.
|
||||||
// Note: on DBC stack grows upwards unlike on all other architectures.
|
// Note: on DBC stack grows upwards unlike on all other architectures.
|
||||||
|
|
|
@ -1,792 +0,0 @@
|
||||||
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
#include "vm/disassembler.h"
|
|
||||||
|
|
||||||
#include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS.
|
|
||||||
#if defined(TARGET_ARCH_MIPS)
|
|
||||||
#include "platform/assert.h"
|
|
||||||
#include "vm/instructions.h"
|
|
||||||
|
|
||||||
namespace dart {
|
|
||||||
|
|
||||||
#ifndef PRODUCT
|
|
||||||
|
|
||||||
class MIPSDecoder : public ValueObject {
|
|
||||||
public:
|
|
||||||
MIPSDecoder(char* buffer, size_t buffer_size)
|
|
||||||
: buffer_(buffer), buffer_size_(buffer_size), buffer_pos_(0) {
|
|
||||||
buffer_[buffer_pos_] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
~MIPSDecoder() {}
|
|
||||||
|
|
||||||
// Writes one disassembled instruction into 'buffer' (0-terminated).
|
|
||||||
// Returns true if the instruction was successfully decoded, false otherwise.
|
|
||||||
void InstructionDecode(Instr* instr);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Bottleneck functions to print into the out_buffer.
|
|
||||||
void Print(const char* str);
|
|
||||||
|
|
||||||
// Printing of common values.
|
|
||||||
void PrintRegister(Register reg);
|
|
||||||
void PrintFRegister(FRegister reg);
|
|
||||||
void PrintFormat(Instr* instr);
|
|
||||||
|
|
||||||
int FormatRegister(Instr* instr, const char* format);
|
|
||||||
int FormatFRegister(Instr* instr, const char* format);
|
|
||||||
int FormatOption(Instr* instr, const char* format);
|
|
||||||
void Format(Instr* instr, const char* format);
|
|
||||||
void Unknown(Instr* instr);
|
|
||||||
|
|
||||||
void DecodeSpecial(Instr* instr);
|
|
||||||
void DecodeSpecial2(Instr* instr);
|
|
||||||
void DecodeRegImm(Instr* instr);
|
|
||||||
void DecodeCop1(Instr* instr);
|
|
||||||
|
|
||||||
// Convenience functions.
|
|
||||||
char* get_buffer() const { return buffer_; }
|
|
||||||
char* current_position_in_buffer() { return buffer_ + buffer_pos_; }
|
|
||||||
size_t remaining_size_in_buffer() { return buffer_size_ - buffer_pos_; }
|
|
||||||
|
|
||||||
char* buffer_; // Decode instructions into this buffer.
|
|
||||||
size_t buffer_size_; // The size of the character buffer.
|
|
||||||
size_t buffer_pos_; // Current character position in buffer.
|
|
||||||
|
|
||||||
DISALLOW_ALLOCATION();
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(MIPSDecoder);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Support for assertions in the MIPSDecoder formatting functions.
|
|
||||||
#define STRING_STARTS_WITH(string, compare_string) \
|
|
||||||
(strncmp(string, compare_string, strlen(compare_string)) == 0)
|
|
||||||
|
|
||||||
|
|
||||||
// Append the str to the output buffer.
|
|
||||||
void MIPSDecoder::Print(const char* str) {
|
|
||||||
char cur = *str++;
|
|
||||||
while (cur != '\0' && (buffer_pos_ < (buffer_size_ - 1))) {
|
|
||||||
buffer_[buffer_pos_++] = cur;
|
|
||||||
cur = *str++;
|
|
||||||
}
|
|
||||||
buffer_[buffer_pos_] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static const char* reg_names[kNumberOfCpuRegisters] = {
|
|
||||||
"zr", "at", "v0", "v1", "a0", "a1", "a2", "a3", "t0", "t1", "t2",
|
|
||||||
"t3", "t4", "t5", "t6", "t7", "s0", "s1", "s2", "thr", "s4", "s5",
|
|
||||||
"s6", "pp", "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra",
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static const char* freg_names[kNumberOfFRegisters] = {
|
|
||||||
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10",
|
|
||||||
"f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21",
|
|
||||||
"f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void MIPSDecoder::PrintRegister(Register reg) {
|
|
||||||
ASSERT(0 <= reg);
|
|
||||||
ASSERT(reg < kNumberOfCpuRegisters);
|
|
||||||
Print(reg_names[reg]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void MIPSDecoder::PrintFRegister(FRegister reg) {
|
|
||||||
ASSERT(0 <= reg);
|
|
||||||
ASSERT(reg < kNumberOfFRegisters);
|
|
||||||
Print(freg_names[reg]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Handle all register based formatting in these functions to reduce the
|
|
||||||
// complexity of FormatOption.
|
|
||||||
int MIPSDecoder::FormatRegister(Instr* instr, const char* format) {
|
|
||||||
ASSERT(format[0] == 'r');
|
|
||||||
switch (format[1]) {
|
|
||||||
case 's': { // 'rs: Rs register
|
|
||||||
PrintRegister(instr->RsField());
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
case 't': { // 'rt: Rt register
|
|
||||||
PrintRegister(instr->RtField());
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
case 'd': { // 'rd: Rd register
|
|
||||||
PrintRegister(instr->RdField());
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UNREACHABLE();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int MIPSDecoder::FormatFRegister(Instr* instr, const char* format) {
|
|
||||||
ASSERT(format[0] == 'f');
|
|
||||||
switch (format[1]) {
|
|
||||||
case 's': { // 'fs: Fs register
|
|
||||||
PrintFRegister(instr->FsField());
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
case 't': { // 'ft: Ft register
|
|
||||||
PrintFRegister(instr->FtField());
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
case 'd': { // 'fd: Fd register
|
|
||||||
PrintFRegister(instr->FdField());
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UNREACHABLE();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void MIPSDecoder::PrintFormat(Instr* instr) {
|
|
||||||
switch (instr->FormatField()) {
|
|
||||||
case FMT_S: {
|
|
||||||
Print("s");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FMT_D: {
|
|
||||||
Print("d");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FMT_W: {
|
|
||||||
Print("w");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FMT_L: {
|
|
||||||
Print("l");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FMT_PS: {
|
|
||||||
Print("ps");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
Print("unknown");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// FormatOption takes a formatting string and interprets it based on
|
|
||||||
// the current instructions. The format string points to the first
|
|
||||||
// character of the option string (the option escape has already been
|
|
||||||
// consumed by the caller.) FormatOption returns the number of
|
|
||||||
// characters that were consumed from the formatting string.
|
|
||||||
int MIPSDecoder::FormatOption(Instr* instr, const char* format) {
|
|
||||||
switch (format[0]) {
|
|
||||||
case 'c': {
|
|
||||||
ASSERT(STRING_STARTS_WITH(format, "code"));
|
|
||||||
buffer_pos_ +=
|
|
||||||
OS::SNPrint(current_position_in_buffer(), remaining_size_in_buffer(),
|
|
||||||
"0x%x", instr->BreakCodeField());
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
case 'h': {
|
|
||||||
ASSERT(STRING_STARTS_WITH(format, "hint"));
|
|
||||||
if (instr->SaField() == 0x10) {
|
|
||||||
// The high bit of the SA field is the only one that means something for
|
|
||||||
// JALR and JR. TODO(zra): Fill in the other cases for PREF if needed.
|
|
||||||
buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
|
|
||||||
remaining_size_in_buffer(), ".hb");
|
|
||||||
} else if (instr->SaField() != 0) {
|
|
||||||
buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
|
|
||||||
remaining_size_in_buffer(), ".unknown");
|
|
||||||
}
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
case 'd': {
|
|
||||||
ASSERT(STRING_STARTS_WITH(format, "dest"));
|
|
||||||
int off = instr->SImmField() << 2;
|
|
||||||
uword destination =
|
|
||||||
reinterpret_cast<uword>(instr) + off + Instr::kInstrSize;
|
|
||||||
buffer_pos_ +=
|
|
||||||
OS::SNPrint(current_position_in_buffer(), remaining_size_in_buffer(),
|
|
||||||
"%#" Px "", destination);
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
case 'i': {
|
|
||||||
ASSERT(STRING_STARTS_WITH(format, "imm"));
|
|
||||||
if (format[3] == 'u') {
|
|
||||||
int32_t imm = instr->UImmField();
|
|
||||||
buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
|
|
||||||
remaining_size_in_buffer(), "0x%x", imm);
|
|
||||||
} else {
|
|
||||||
ASSERT(STRING_STARTS_WITH(format, "imms"));
|
|
||||||
int32_t imm = instr->SImmField();
|
|
||||||
buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
|
|
||||||
remaining_size_in_buffer(), "%d", imm);
|
|
||||||
}
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
case 'r': {
|
|
||||||
return FormatRegister(instr, format);
|
|
||||||
}
|
|
||||||
case 'f': {
|
|
||||||
if (format[1] == 'm') {
|
|
||||||
ASSERT(STRING_STARTS_WITH(format, "fmt"));
|
|
||||||
PrintFormat(instr);
|
|
||||||
return 3;
|
|
||||||
} else {
|
|
||||||
return FormatFRegister(instr, format);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 's': {
|
|
||||||
ASSERT(STRING_STARTS_WITH(format, "sa"));
|
|
||||||
buffer_pos_ +=
|
|
||||||
OS::SNPrint(current_position_in_buffer(), remaining_size_in_buffer(),
|
|
||||||
"%d", instr->SaField());
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
default: { UNREACHABLE(); }
|
|
||||||
}
|
|
||||||
UNREACHABLE();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Format takes a formatting string for a whole instruction and prints it into
|
|
||||||
// the output buffer. All escaped options are handed to FormatOption to be
|
|
||||||
// parsed further.
|
|
||||||
void MIPSDecoder::Format(Instr* instr, const char* format) {
|
|
||||||
char cur = *format++;
|
|
||||||
while ((cur != 0) && (buffer_pos_ < (buffer_size_ - 1))) {
|
|
||||||
if (cur == '\'') { // Single quote is used as the formatting escape.
|
|
||||||
format += FormatOption(instr, format);
|
|
||||||
} else {
|
|
||||||
buffer_[buffer_pos_++] = cur;
|
|
||||||
}
|
|
||||||
cur = *format++;
|
|
||||||
}
|
|
||||||
buffer_[buffer_pos_] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// For currently unimplemented decodings the disassembler calls Unknown(instr)
|
|
||||||
// which will just print "unknown" of the instruction bits.
|
|
||||||
void MIPSDecoder::Unknown(Instr* instr) {
|
|
||||||
Format(instr, "unknown");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void MIPSDecoder::DecodeSpecial(Instr* instr) {
|
|
||||||
ASSERT(instr->OpcodeField() == SPECIAL);
|
|
||||||
switch (instr->FunctionField()) {
|
|
||||||
case ADDU: {
|
|
||||||
Format(instr, "addu 'rd, 'rs, 'rt");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case AND: {
|
|
||||||
Format(instr, "and 'rd, 'rs, 'rt");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BREAK: {
|
|
||||||
Format(instr, "break 'code");
|
|
||||||
if (instr->BreakCodeField() == Instr::kStopMessageCode) {
|
|
||||||
const char* message = *reinterpret_cast<const char**>(
|
|
||||||
reinterpret_cast<intptr_t>(instr) - Instr::kInstrSize);
|
|
||||||
buffer_pos_ +=
|
|
||||||
OS::SNPrint(current_position_in_buffer(),
|
|
||||||
remaining_size_in_buffer(), " ; \"%s\"", message);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DIV: {
|
|
||||||
Format(instr, "div 'rs, 'rt");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DIVU: {
|
|
||||||
Format(instr, "divu 'rs, 'rt");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case JALR: {
|
|
||||||
Format(instr, "jalr'hint 'rd, 'rs");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case JR: {
|
|
||||||
Format(instr, "jr'hint 'rs");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MFHI: {
|
|
||||||
Format(instr, "mfhi 'rd");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MFLO: {
|
|
||||||
Format(instr, "mflo 'rd");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MOVCI: {
|
|
||||||
if (instr->Bit(16)) {
|
|
||||||
Format(instr, "movt 'rd, 'rs");
|
|
||||||
} else {
|
|
||||||
Format(instr, "movf 'rd, 'rs");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MOVN: {
|
|
||||||
Format(instr, "movn 'rd, 'rs, 'rt");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MOVZ: {
|
|
||||||
Format(instr, "movz 'rd, 'rs, 'rt");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MTHI: {
|
|
||||||
Format(instr, "mthi 'rs");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MTLO: {
|
|
||||||
Format(instr, "mtlo 'rs");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MULT: {
|
|
||||||
Format(instr, "mult 'rs, 'rt");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MULTU: {
|
|
||||||
Format(instr, "multu 'rs, 'rt");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NOR: {
|
|
||||||
Format(instr, "nor 'rd, 'rs, 'rt");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case OR: {
|
|
||||||
if (instr->RsField() == 0 && instr->RtField() == 0) {
|
|
||||||
Format(instr, "mov 'rd, 0");
|
|
||||||
} else if (instr->RsField() == R0) {
|
|
||||||
Format(instr, "mov 'rd, 'rt");
|
|
||||||
} else if (instr->RtField() == R0) {
|
|
||||||
Format(instr, "mov 'rd, 'rs");
|
|
||||||
} else {
|
|
||||||
Format(instr, "or 'rd, 'rs, 'rt");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SLL: {
|
|
||||||
if ((instr->RdField() == R0) && (instr->RtField() == R0) &&
|
|
||||||
(instr->SaField() == 0)) {
|
|
||||||
Format(instr, "nop");
|
|
||||||
} else {
|
|
||||||
Format(instr, "sll 'rd, 'rt, 'sa");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SLLV: {
|
|
||||||
Format(instr, "sllv 'rd, 'rt, 'rs");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SLT: {
|
|
||||||
Format(instr, "slt 'rd, 'rs, 'rt");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SLTU: {
|
|
||||||
Format(instr, "sltu 'rd, 'rs, 'rt");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SRA: {
|
|
||||||
if (instr->RsField() == 0) {
|
|
||||||
Format(instr, "sra 'rd, 'rt, 'sa");
|
|
||||||
} else {
|
|
||||||
Unknown(instr);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SRAV: {
|
|
||||||
Format(instr, "srav 'rd, 'rt, 'rs");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SRL: {
|
|
||||||
if (instr->RsField() == 0) {
|
|
||||||
Format(instr, "srl 'rd, 'rt, 'sa");
|
|
||||||
} else {
|
|
||||||
Unknown(instr);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SRLV: {
|
|
||||||
if (instr->SaField() == 0) {
|
|
||||||
Format(instr, "srlv 'rd, 'rt, 'rs");
|
|
||||||
} else {
|
|
||||||
Unknown(instr);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SUBU: {
|
|
||||||
Format(instr, "subu 'rd, 'rs, 'rt");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case XOR: {
|
|
||||||
Format(instr, "xor 'rd, 'rs, 'rt");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
Unknown(instr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void MIPSDecoder::DecodeSpecial2(Instr* instr) {
|
|
||||||
ASSERT(instr->OpcodeField() == SPECIAL2);
|
|
||||||
switch (instr->FunctionField()) {
|
|
||||||
case MADD: {
|
|
||||||
Format(instr, "madd 'rs, 'rt");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MADDU: {
|
|
||||||
Format(instr, "maddu 'rs, 'rt");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CLO: {
|
|
||||||
Format(instr, "clo 'rd, 'rs");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CLZ: {
|
|
||||||
Format(instr, "clz 'rd, 'rs");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
Unknown(instr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void MIPSDecoder::DecodeRegImm(Instr* instr) {
|
|
||||||
ASSERT(instr->OpcodeField() == REGIMM);
|
|
||||||
switch (instr->RegImmFnField()) {
|
|
||||||
case BGEZ: {
|
|
||||||
Format(instr, "bgez 'rs, 'dest");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BGEZAL: {
|
|
||||||
Format(instr, "bgezal 'rs, 'dest");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BLTZAL: {
|
|
||||||
Format(instr, "bltzal 'rs, 'dest");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BGEZL: {
|
|
||||||
Format(instr, "bgezl 'rs, 'dest");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BLTZ: {
|
|
||||||
Format(instr, "bltz 'rs, 'dest");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BLTZL: {
|
|
||||||
Format(instr, "bltzl 'rs, 'dest");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
Unknown(instr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MIPSDecoder::DecodeCop1(Instr* instr) {
|
|
||||||
ASSERT(instr->OpcodeField() == COP1);
|
|
||||||
if (instr->HasFormat()) {
|
|
||||||
// If the rs field is a valid format, then the function field identifies
|
|
||||||
// the instruction.
|
|
||||||
switch (instr->Cop1FunctionField()) {
|
|
||||||
case COP1_ADD: {
|
|
||||||
Format(instr, "add.'fmt 'fd, 'fs, 'ft");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case COP1_SUB: {
|
|
||||||
Format(instr, "sub.'fmt 'fd, 'fs, 'ft");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case COP1_MUL: {
|
|
||||||
Format(instr, "mul.'fmt 'fd, 'fs, 'ft");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case COP1_DIV: {
|
|
||||||
Format(instr, "div.'fmt 'fd, 'fs, 'ft");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case COP1_SQRT: {
|
|
||||||
Format(instr, "sqrt.'fmt 'fd, 'fs");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case COP1_MOV: {
|
|
||||||
Format(instr, "mov.'fmt 'fd, 'fs");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case COP1_NEG: {
|
|
||||||
Format(instr, "neg.'fmt 'fd, 'fs");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case COP1_C_F: {
|
|
||||||
Format(instr, "c.f.'fmt 'fs, 'ft");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case COP1_C_UN: {
|
|
||||||
Format(instr, "c.un.'fmt 'fs, 'ft");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case COP1_C_EQ: {
|
|
||||||
Format(instr, "c.eq.'fmt 'fs, 'ft");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case COP1_C_UEQ: {
|
|
||||||
Format(instr, "c.ueq.'fmt 'fs, 'ft");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case COP1_C_OLT: {
|
|
||||||
Format(instr, "c.olt.'fmt 'fs, 'ft");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case COP1_C_ULT: {
|
|
||||||
Format(instr, "c.ult.'fmt 'fs, 'ft");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case COP1_C_OLE: {
|
|
||||||
Format(instr, "c.ole.'fmt 'fs, 'ft");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case COP1_C_ULE: {
|
|
||||||
Format(instr, "c.ule.'fmt 'fs, 'ft");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case COP1_TRUNC_W: {
|
|
||||||
Format(instr, "trunc.w.'fmt 'fd, 'fs");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case COP1_CVT_S: {
|
|
||||||
Format(instr, "cvt.s.'fmt 'fd, 'fs");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case COP1_CVT_D: {
|
|
||||||
Format(instr, "cvt.d.'fmt 'fd, 'fs");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
Unknown(instr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// If the rs field isn't a valid format, then it must be a sub-opcode.
|
|
||||||
switch (instr->Cop1SubField()) {
|
|
||||||
case COP1_MF: {
|
|
||||||
if (instr->Bits(0, 11) != 0) {
|
|
||||||
Unknown(instr);
|
|
||||||
} else {
|
|
||||||
Format(instr, "mfc1 'rt, 'fs");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case COP1_MT: {
|
|
||||||
if (instr->Bits(0, 11) != 0) {
|
|
||||||
Unknown(instr);
|
|
||||||
} else {
|
|
||||||
Format(instr, "mtc1 'rt, 'fs");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case COP1_BC: {
|
|
||||||
ASSERT(instr->Bit(17) == 0);
|
|
||||||
if (instr->Bit(16) == 1) { // Branch on true.
|
|
||||||
Format(instr, "bc1t 'dest");
|
|
||||||
} else { // Branch on false.
|
|
||||||
Format(instr, "bc1f 'dest");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
Unknown(instr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MIPSDecoder::InstructionDecode(Instr* instr) {
|
|
||||||
switch (instr->OpcodeField()) {
|
|
||||||
case SPECIAL: {
|
|
||||||
DecodeSpecial(instr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SPECIAL2: {
|
|
||||||
DecodeSpecial2(instr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case REGIMM: {
|
|
||||||
DecodeRegImm(instr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case COP1: {
|
|
||||||
DecodeCop1(instr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ADDIU: {
|
|
||||||
Format(instr, "addiu 'rt, 'rs, 'imms");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ANDI: {
|
|
||||||
Format(instr, "andi 'rt, 'rs, 'immu");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BEQ: {
|
|
||||||
Format(instr, "beq 'rs, 'rt, 'dest");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BEQL: {
|
|
||||||
Format(instr, "beql 'rs, 'rt, 'dest");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BGTZ: {
|
|
||||||
Format(instr, "bgtz 'rs, 'dest");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BGTZL: {
|
|
||||||
Format(instr, "bgtzl 'rs, 'dest");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BLEZ: {
|
|
||||||
Format(instr, "blez 'rs, 'dest");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BLEZL: {
|
|
||||||
Format(instr, "blezl 'rs, 'dest");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BNE: {
|
|
||||||
Format(instr, "bne 'rs, 'rt, 'dest");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BNEL: {
|
|
||||||
Format(instr, "bnel 'rs, 'rt, 'dest");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LB: {
|
|
||||||
Format(instr, "lb 'rt, 'imms('rs)");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LBU: {
|
|
||||||
Format(instr, "lbu 'rt, 'imms('rs)");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LDC1: {
|
|
||||||
Format(instr, "ldc1 'ft, 'imms('rs)");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LH: {
|
|
||||||
Format(instr, "lh 'rt, 'imms('rs)");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LHU: {
|
|
||||||
Format(instr, "lhu 'rt, 'imms('rs)");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LUI: {
|
|
||||||
Format(instr, "lui 'rt, 'immu");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LL: {
|
|
||||||
Format(instr, "ll 'rt, 'imms('rs)");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LW: {
|
|
||||||
Format(instr, "lw 'rt, 'imms('rs)");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LWC1: {
|
|
||||||
Format(instr, "lwc1 'ft, 'imms('rs)");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ORI: {
|
|
||||||
Format(instr, "ori 'rt, 'rs, 'immu");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SB: {
|
|
||||||
Format(instr, "sb 'rt, 'imms('rs)");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SC: {
|
|
||||||
Format(instr, "sc 'rt, 'imms('rs)");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SLTI: {
|
|
||||||
Format(instr, "slti 'rt, 'rs, 'imms");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SLTIU: {
|
|
||||||
Format(instr, "sltiu 'rt, 'rs, 'imms");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SH: {
|
|
||||||
Format(instr, "sh 'rt, 'imms('rs)");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SDC1: {
|
|
||||||
Format(instr, "sdc1 'ft, 'imms('rs)");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SW: {
|
|
||||||
Format(instr, "sw 'rt, 'imms('rs)");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SWC1: {
|
|
||||||
Format(instr, "swc1 'ft, 'imms('rs)");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case XORI: {
|
|
||||||
Format(instr, "xori 'rt, 'rs, 'immu");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
Unknown(instr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Disassembler::DecodeInstruction(char* hex_buffer,
|
|
||||||
intptr_t hex_size,
|
|
||||||
char* human_buffer,
|
|
||||||
intptr_t human_size,
|
|
||||||
int* out_instr_len,
|
|
||||||
const Code& code,
|
|
||||||
Object** object,
|
|
||||||
uword pc) {
|
|
||||||
MIPSDecoder decoder(human_buffer, human_size);
|
|
||||||
Instr* instr = Instr::At(pc);
|
|
||||||
decoder.InstructionDecode(instr);
|
|
||||||
OS::SNPrint(hex_buffer, hex_size, "%08x", instr->InstructionBits());
|
|
||||||
if (out_instr_len) {
|
|
||||||
*out_instr_len = Instr::kInstrSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
*object = NULL;
|
|
||||||
if (!code.IsNull()) {
|
|
||||||
*object = &Object::Handle();
|
|
||||||
if (!DecodeLoadObjectFromPoolOrThread(pc, code, *object)) {
|
|
||||||
*object = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // !PRODUCT
|
|
||||||
|
|
||||||
} // namespace dart
|
|
||||||
|
|
||||||
#endif // defined TARGET_ARCH_MIPS
|
|
File diff suppressed because it is too large
Load diff
|
@ -15,8 +15,6 @@
|
||||||
#include "vm/instructions_arm.h"
|
#include "vm/instructions_arm.h"
|
||||||
#elif defined(TARGET_ARCH_ARM64)
|
#elif defined(TARGET_ARCH_ARM64)
|
||||||
#include "vm/instructions_arm64.h"
|
#include "vm/instructions_arm64.h"
|
||||||
#elif defined(TARGET_ARCH_MIPS)
|
|
||||||
#include "vm/instructions_mips.h"
|
|
||||||
#elif defined(TARGET_ARCH_DBC)
|
#elif defined(TARGET_ARCH_DBC)
|
||||||
#include "vm/instructions_dbc.h"
|
#include "vm/instructions_dbc.h"
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -1,265 +0,0 @@
|
||||||
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
#include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS.
|
|
||||||
#if defined(TARGET_ARCH_MIPS)
|
|
||||||
|
|
||||||
#include "vm/instructions.h"
|
|
||||||
#include "vm/instructions_mips.h"
|
|
||||||
|
|
||||||
#include "vm/constants_mips.h"
|
|
||||||
#include "vm/cpu.h"
|
|
||||||
#include "vm/object.h"
|
|
||||||
|
|
||||||
namespace dart {
|
|
||||||
|
|
||||||
CallPattern::CallPattern(uword pc, const Code& code)
|
|
||||||
: object_pool_(ObjectPool::Handle(code.GetObjectPool())),
|
|
||||||
end_(pc),
|
|
||||||
ic_data_load_end_(0),
|
|
||||||
target_code_pool_index_(-1),
|
|
||||||
ic_data_(ICData::Handle()) {
|
|
||||||
ASSERT(code.ContainsInstructionAt(pc));
|
|
||||||
// Last instruction: jalr RA, T9(=R25).
|
|
||||||
ASSERT(*(reinterpret_cast<uword*>(end_) - 2) == 0x0320f809);
|
|
||||||
Register reg;
|
|
||||||
// The end of the pattern is the instruction after the delay slot of the jalr.
|
|
||||||
ic_data_load_end_ = InstructionPattern::DecodeLoadWordFromPool(
|
|
||||||
end_ - (3 * Instr::kInstrSize), ®, &target_code_pool_index_);
|
|
||||||
ASSERT(reg == CODE_REG);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Decodes a load sequence ending at 'end' (the last instruction of the load
|
|
||||||
// sequence is the instruction before the one at end). Returns a pointer to
|
|
||||||
// the first instruction in the sequence. Returns the register being loaded
|
|
||||||
// and the loaded object in the output parameters 'reg' and 'obj'
|
|
||||||
// respectively.
|
|
||||||
uword InstructionPattern::DecodeLoadObject(uword end,
|
|
||||||
const ObjectPool& object_pool,
|
|
||||||
Register* reg,
|
|
||||||
Object* obj) {
|
|
||||||
uword start = 0;
|
|
||||||
Instr* instr = Instr::At(end - Instr::kInstrSize);
|
|
||||||
if (instr->OpcodeField() == LW) {
|
|
||||||
intptr_t index = 0;
|
|
||||||
start = DecodeLoadWordFromPool(end, reg, &index);
|
|
||||||
*obj = object_pool.ObjectAt(index);
|
|
||||||
} else {
|
|
||||||
intptr_t value = 0;
|
|
||||||
start = DecodeLoadWordImmediate(end, reg, &value);
|
|
||||||
*obj = reinterpret_cast<RawObject*>(value);
|
|
||||||
}
|
|
||||||
return start;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Decodes a load sequence ending at 'end' (the last instruction of the load
|
|
||||||
// sequence is the instruction before the one at end). Returns a pointer to
|
|
||||||
// the first instruction in the sequence. Returns the register being loaded
|
|
||||||
// and the loaded immediate value in the output parameters 'reg' and 'value'
|
|
||||||
// respectively.
|
|
||||||
uword InstructionPattern::DecodeLoadWordImmediate(uword end,
|
|
||||||
Register* reg,
|
|
||||||
intptr_t* value) {
|
|
||||||
// The pattern is a fixed size, but match backwards for uniformity with
|
|
||||||
// DecodeLoadWordFromPool.
|
|
||||||
uword start = end - Instr::kInstrSize;
|
|
||||||
Instr* instr = Instr::At(start);
|
|
||||||
intptr_t imm = 0;
|
|
||||||
ASSERT(instr->OpcodeField() == ORI);
|
|
||||||
imm = instr->UImmField();
|
|
||||||
*reg = instr->RtField();
|
|
||||||
|
|
||||||
start -= Instr::kInstrSize;
|
|
||||||
instr = Instr::At(start);
|
|
||||||
ASSERT(instr->OpcodeField() == LUI);
|
|
||||||
ASSERT(instr->RtField() == *reg);
|
|
||||||
imm |= (instr->UImmField() << 16);
|
|
||||||
*value = imm;
|
|
||||||
return start;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Decodes a load sequence ending at 'end' (the last instruction of the load
|
|
||||||
// sequence is the instruction before the one at end). Returns a pointer to
|
|
||||||
// the first instruction in the sequence. Returns the register being loaded
|
|
||||||
// and the index in the pool being read from in the output parameters 'reg'
|
|
||||||
// and 'index' respectively.
|
|
||||||
uword InstructionPattern::DecodeLoadWordFromPool(uword end,
|
|
||||||
Register* reg,
|
|
||||||
intptr_t* index) {
|
|
||||||
uword start = end - Instr::kInstrSize;
|
|
||||||
Instr* instr = Instr::At(start);
|
|
||||||
intptr_t offset = 0;
|
|
||||||
if ((instr->OpcodeField() == LW) && (instr->RsField() == PP)) {
|
|
||||||
offset = instr->SImmField();
|
|
||||||
*reg = instr->RtField();
|
|
||||||
} else {
|
|
||||||
ASSERT(instr->OpcodeField() == LW);
|
|
||||||
offset = instr->SImmField();
|
|
||||||
*reg = instr->RtField();
|
|
||||||
|
|
||||||
start -= Instr::kInstrSize;
|
|
||||||
instr = Instr::At(start);
|
|
||||||
ASSERT(instr->OpcodeField() == SPECIAL);
|
|
||||||
ASSERT(instr->FunctionField() == ADDU);
|
|
||||||
ASSERT(instr->RdField() == *reg);
|
|
||||||
ASSERT(instr->RsField() == *reg);
|
|
||||||
ASSERT(instr->RtField() == PP);
|
|
||||||
|
|
||||||
start -= Instr::kInstrSize;
|
|
||||||
instr = Instr::At(start);
|
|
||||||
ASSERT(instr->OpcodeField() == LUI);
|
|
||||||
ASSERT(instr->RtField() == *reg);
|
|
||||||
// Offset is signed, so add the upper 16 bits.
|
|
||||||
offset += (instr->UImmField() << 16);
|
|
||||||
}
|
|
||||||
*index = ObjectPool::IndexFromOffset(offset);
|
|
||||||
return start;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool DecodeLoadObjectFromPoolOrThread(uword pc, const Code& code, Object* obj) {
|
|
||||||
ASSERT(code.ContainsInstructionAt(pc));
|
|
||||||
|
|
||||||
Instr* instr = Instr::At(pc);
|
|
||||||
if ((instr->OpcodeField() == LW)) {
|
|
||||||
intptr_t offset = instr->SImmField();
|
|
||||||
if (instr->RsField() == PP) {
|
|
||||||
intptr_t index = ObjectPool::IndexFromOffset(offset);
|
|
||||||
const ObjectPool& pool = ObjectPool::Handle(code.object_pool());
|
|
||||||
if (pool.InfoAt(index) == ObjectPool::kTaggedObject) {
|
|
||||||
*obj = pool.ObjectAt(index);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else if (instr->RsField() == THR) {
|
|
||||||
return Thread::ObjectAtOffset(offset, obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// TODO(rmacnak): Sequence for loads beyond 16 bits.
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
RawICData* CallPattern::IcData() {
|
|
||||||
if (ic_data_.IsNull()) {
|
|
||||||
Register reg;
|
|
||||||
InstructionPattern::DecodeLoadObject(ic_data_load_end_, object_pool_, ®,
|
|
||||||
&ic_data_);
|
|
||||||
ASSERT(reg == S5);
|
|
||||||
}
|
|
||||||
return ic_data_.raw();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
RawCode* CallPattern::TargetCode() const {
|
|
||||||
return reinterpret_cast<RawCode*>(
|
|
||||||
object_pool_.ObjectAt(target_code_pool_index_));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CallPattern::SetTargetCode(const Code& target) const {
|
|
||||||
object_pool_.SetObjectAt(target_code_pool_index_, target);
|
|
||||||
// No need to flush the instruction cache, since the code is not modified.
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
NativeCallPattern::NativeCallPattern(uword pc, const Code& code)
|
|
||||||
: object_pool_(ObjectPool::Handle(code.GetObjectPool())),
|
|
||||||
end_(pc),
|
|
||||||
native_function_pool_index_(-1),
|
|
||||||
target_code_pool_index_(-1) {
|
|
||||||
ASSERT(code.ContainsInstructionAt(pc));
|
|
||||||
// Last instruction: jalr RA, T9(=R25).
|
|
||||||
ASSERT(*(reinterpret_cast<uword*>(end_) - 2) == 0x0320f809);
|
|
||||||
|
|
||||||
Register reg;
|
|
||||||
uword native_function_load_end = InstructionPattern::DecodeLoadWordFromPool(
|
|
||||||
end_ - 3 * Instr::kInstrSize, ®, &target_code_pool_index_);
|
|
||||||
ASSERT(reg == CODE_REG);
|
|
||||||
InstructionPattern::DecodeLoadWordFromPool(native_function_load_end, ®,
|
|
||||||
&native_function_pool_index_);
|
|
||||||
ASSERT(reg == T5);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
RawCode* NativeCallPattern::target() const {
|
|
||||||
return reinterpret_cast<RawCode*>(
|
|
||||||
object_pool_.ObjectAt(target_code_pool_index_));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void NativeCallPattern::set_target(const Code& target) const {
|
|
||||||
object_pool_.SetObjectAt(target_code_pool_index_, target);
|
|
||||||
// No need to flush the instruction cache, since the code is not modified.
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
NativeFunction NativeCallPattern::native_function() const {
|
|
||||||
return reinterpret_cast<NativeFunction>(
|
|
||||||
object_pool_.RawValueAt(native_function_pool_index_));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void NativeCallPattern::set_native_function(NativeFunction func) const {
|
|
||||||
object_pool_.SetRawValueAt(native_function_pool_index_,
|
|
||||||
reinterpret_cast<uword>(func));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
SwitchableCallPattern::SwitchableCallPattern(uword pc, const Code& code)
|
|
||||||
: object_pool_(ObjectPool::Handle(code.GetObjectPool())),
|
|
||||||
data_pool_index_(-1),
|
|
||||||
target_pool_index_(-1) {
|
|
||||||
ASSERT(code.ContainsInstructionAt(pc));
|
|
||||||
// Last instruction: jalr t9.
|
|
||||||
ASSERT(*(reinterpret_cast<uword*>(pc) - 1) == 0); // Delay slot.
|
|
||||||
ASSERT(*(reinterpret_cast<uword*>(pc) - 2) == 0x0320f809);
|
|
||||||
|
|
||||||
Register reg;
|
|
||||||
uword data_load_end = InstructionPattern::DecodeLoadWordFromPool(
|
|
||||||
pc - 2 * Instr::kInstrSize, ®, &data_pool_index_);
|
|
||||||
ASSERT(reg == S5);
|
|
||||||
InstructionPattern::DecodeLoadWordFromPool(data_load_end - Instr::kInstrSize,
|
|
||||||
®, &target_pool_index_);
|
|
||||||
ASSERT(reg == CODE_REG);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
RawObject* SwitchableCallPattern::data() const {
|
|
||||||
return object_pool_.ObjectAt(data_pool_index_);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
RawCode* SwitchableCallPattern::target() const {
|
|
||||||
return reinterpret_cast<RawCode*>(object_pool_.ObjectAt(target_pool_index_));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SwitchableCallPattern::SetData(const Object& data) const {
|
|
||||||
ASSERT(!Object::Handle(object_pool_.ObjectAt(data_pool_index_)).IsCode());
|
|
||||||
object_pool_.SetObjectAt(data_pool_index_, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SwitchableCallPattern::SetTarget(const Code& target) const {
|
|
||||||
ASSERT(Object::Handle(object_pool_.ObjectAt(target_pool_index_)).IsCode());
|
|
||||||
object_pool_.SetObjectAt(target_pool_index_, target);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ReturnPattern::ReturnPattern(uword pc) : pc_(pc) {}
|
|
||||||
|
|
||||||
|
|
||||||
bool ReturnPattern::IsValid() const {
|
|
||||||
Instr* jr = Instr::At(pc_);
|
|
||||||
return (jr->OpcodeField() == SPECIAL) && (jr->FunctionField() == JR) &&
|
|
||||||
(jr->RsField() == RA);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace dart
|
|
||||||
|
|
||||||
#endif // defined TARGET_ARCH_MIPS
|
|
|
@ -1,134 +0,0 @@
|
||||||
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
|
||||||
// Classes that describe assembly patterns as used by inline caches.
|
|
||||||
|
|
||||||
#ifndef RUNTIME_VM_INSTRUCTIONS_MIPS_H_
|
|
||||||
#define RUNTIME_VM_INSTRUCTIONS_MIPS_H_
|
|
||||||
|
|
||||||
#ifndef RUNTIME_VM_INSTRUCTIONS_H_
|
|
||||||
#error Do not include instructions_mips.h directly; use instructions.h instead.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "vm/constants_mips.h"
|
|
||||||
#include "vm/native_entry.h"
|
|
||||||
#include "vm/object.h"
|
|
||||||
|
|
||||||
namespace dart {
|
|
||||||
|
|
||||||
class InstructionPattern : public AllStatic {
|
|
||||||
public:
|
|
||||||
// Decodes a load sequence ending at 'end' (the last instruction of the
|
|
||||||
// load sequence is the instruction before the one at end). Returns the
|
|
||||||
// address of the first instruction in the sequence. Returns the register
|
|
||||||
// being loaded and the loaded object in the output parameters 'reg' and
|
|
||||||
// 'obj' respectively.
|
|
||||||
static uword DecodeLoadObject(uword end,
|
|
||||||
const ObjectPool& object_pool,
|
|
||||||
Register* reg,
|
|
||||||
Object* obj);
|
|
||||||
|
|
||||||
// Decodes a load sequence ending at 'end' (the last instruction of the
|
|
||||||
// load sequence is the instruction before the one at end). Returns the
|
|
||||||
// address of the first instruction in the sequence. Returns the register
|
|
||||||
// being loaded and the loaded immediate value in the output parameters
|
|
||||||
// 'reg' and 'value' respectively.
|
|
||||||
static uword DecodeLoadWordImmediate(uword end,
|
|
||||||
Register* reg,
|
|
||||||
intptr_t* value);
|
|
||||||
|
|
||||||
// Decodes a load sequence ending at 'end' (the last instruction of the
|
|
||||||
// load sequence is the instruction before the one at end). Returns the
|
|
||||||
// address of the first instruction in the sequence. Returns the register
|
|
||||||
// being loaded and the index in the pool being read from in the output
|
|
||||||
// parameters 'reg' and 'index' respectively.
|
|
||||||
static uword DecodeLoadWordFromPool(uword end,
|
|
||||||
Register* reg,
|
|
||||||
intptr_t* index);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class CallPattern : public ValueObject {
|
|
||||||
public:
|
|
||||||
CallPattern(uword pc, const Code& code);
|
|
||||||
|
|
||||||
RawICData* IcData();
|
|
||||||
|
|
||||||
RawCode* TargetCode() const;
|
|
||||||
void SetTargetCode(const Code& target) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
const ObjectPool& object_pool_;
|
|
||||||
|
|
||||||
uword end_;
|
|
||||||
uword ic_data_load_end_;
|
|
||||||
|
|
||||||
intptr_t target_code_pool_index_;
|
|
||||||
ICData& ic_data_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(CallPattern);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class NativeCallPattern : public ValueObject {
|
|
||||||
public:
|
|
||||||
NativeCallPattern(uword pc, const Code& code);
|
|
||||||
|
|
||||||
RawCode* target() const;
|
|
||||||
void set_target(const Code& target) const;
|
|
||||||
|
|
||||||
NativeFunction native_function() const;
|
|
||||||
void set_native_function(NativeFunction target) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
const ObjectPool& object_pool_;
|
|
||||||
|
|
||||||
uword end_;
|
|
||||||
intptr_t native_function_pool_index_;
|
|
||||||
intptr_t target_code_pool_index_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(NativeCallPattern);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Instance call that can switch between a direct monomorphic call, an IC call,
|
|
||||||
// and a megamorphic call.
|
|
||||||
// load guarded cid load ICData load MegamorphicCache
|
|
||||||
// load monomorphic target <-> load ICLookup stub -> load MMLookup stub
|
|
||||||
// call target.entry call stub.entry call stub.entry
|
|
||||||
class SwitchableCallPattern : public ValueObject {
|
|
||||||
public:
|
|
||||||
SwitchableCallPattern(uword pc, const Code& code);
|
|
||||||
|
|
||||||
RawObject* data() const;
|
|
||||||
RawCode* target() const;
|
|
||||||
void SetData(const Object& data) const;
|
|
||||||
void SetTarget(const Code& target) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
const ObjectPool& object_pool_;
|
|
||||||
intptr_t data_pool_index_;
|
|
||||||
intptr_t target_pool_index_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(SwitchableCallPattern);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class ReturnPattern : public ValueObject {
|
|
||||||
public:
|
|
||||||
explicit ReturnPattern(uword pc);
|
|
||||||
|
|
||||||
// jr(RA) = 1
|
|
||||||
static const int kLengthInBytes = 1 * Instr::kInstrSize;
|
|
||||||
|
|
||||||
int pattern_length_in_bytes() const { return kLengthInBytes; }
|
|
||||||
|
|
||||||
bool IsValid() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
const uword pc_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace dart
|
|
||||||
|
|
||||||
#endif // RUNTIME_VM_INSTRUCTIONS_MIPS_H_
|
|
|
@ -1,36 +0,0 @@
|
||||||
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
#include "vm/globals.h"
|
|
||||||
#if defined(TARGET_ARCH_MIPS)
|
|
||||||
|
|
||||||
#include "vm/assembler.h"
|
|
||||||
#include "vm/instructions.h"
|
|
||||||
#include "vm/stub_code.h"
|
|
||||||
#include "vm/unit_test.h"
|
|
||||||
|
|
||||||
namespace dart {
|
|
||||||
|
|
||||||
#define __ assembler->
|
|
||||||
|
|
||||||
ASSEMBLER_TEST_GENERATE(Call, assembler) {
|
|
||||||
__ BranchLinkPatchable(*StubCode::InvokeDartCode_entry());
|
|
||||||
__ Ret();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ASSEMBLER_TEST_RUN(Call, test) {
|
|
||||||
// The return address, which must be the address of an instruction contained
|
|
||||||
// in the code, points to the Ret instruction above, i.e. two instructions
|
|
||||||
// before the end of the code buffer, including the delay slot for the
|
|
||||||
// return jump.
|
|
||||||
uword end = test->payload_start() + test->code().Size();
|
|
||||||
CallPattern call(end - (2 * Instr::kInstrSize), test->code());
|
|
||||||
EXPECT_EQ(StubCode::InvokeDartCode_entry()->code(), call.TargetCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace dart
|
|
||||||
|
|
||||||
#endif // defined TARGET_ARCH_MIPS
|
|
|
@ -3051,8 +3051,8 @@ void TargetEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// The deoptimization descriptor points after the edge counter code for
|
// The deoptimization descriptor points after the edge counter code for
|
||||||
// uniformity with ARM and MIPS, where we can reuse pattern matching
|
// uniformity with ARM, where we can reuse pattern matching code that
|
||||||
// code that matches backwards from the end of the pattern.
|
// matches backwards from the end of the pattern.
|
||||||
compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, GetDeoptId(),
|
compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, GetDeoptId(),
|
||||||
TokenPosition::kNoSource);
|
TokenPosition::kNoSource);
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,17 +0,0 @@
|
||||||
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
#include "vm/malloc_hooks.h"
|
|
||||||
|
|
||||||
#include "vm/globals.h"
|
|
||||||
|
|
||||||
#if defined(HOST_ARCH_MIPS)
|
|
||||||
|
|
||||||
namespace dart {
|
|
||||||
|
|
||||||
const intptr_t kSkipCount = 5;
|
|
||||||
|
|
||||||
} // namespace dart
|
|
||||||
|
|
||||||
#endif // defined(HOST_ARCH_MIPS)
|
|
|
@ -4230,9 +4230,6 @@ class Instructions : public Object {
|
||||||
#elif defined(TARGET_ARCH_ARM64)
|
#elif defined(TARGET_ARCH_ARM64)
|
||||||
static const intptr_t kCheckedEntryOffset = 16;
|
static const intptr_t kCheckedEntryOffset = 16;
|
||||||
static const intptr_t kUncheckedEntryOffset = 40;
|
static const intptr_t kUncheckedEntryOffset = 40;
|
||||||
#elif defined(TARGET_ARCH_MIPS)
|
|
||||||
static const intptr_t kCheckedEntryOffset = 12;
|
|
||||||
static const intptr_t kUncheckedEntryOffset = 52;
|
|
||||||
#elif defined(TARGET_ARCH_DBC)
|
#elif defined(TARGET_ARCH_DBC)
|
||||||
static const intptr_t kCheckedEntryOffset = 0;
|
static const intptr_t kCheckedEntryOffset = 0;
|
||||||
static const intptr_t kUncheckedEntryOffset = 0;
|
static const intptr_t kUncheckedEntryOffset = 0;
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
#include "platform/assert.h"
|
|
||||||
#include "vm/globals.h"
|
|
||||||
#if defined(TARGET_ARCH_MIPS)
|
|
||||||
|
|
||||||
#include "vm/assembler.h"
|
|
||||||
#include "vm/object.h"
|
|
||||||
#include "vm/unit_test.h"
|
|
||||||
|
|
||||||
namespace dart {
|
|
||||||
|
|
||||||
#define __ assembler->
|
|
||||||
|
|
||||||
|
|
||||||
// Generate a simple dart code sequence.
|
|
||||||
// This is used to test Code and Instruction object creation.
|
|
||||||
void GenerateIncrement(Assembler* assembler) {
|
|
||||||
__ Push(ZR);
|
|
||||||
__ lw(TMP, Address(SP, 0));
|
|
||||||
__ addiu(TMP, TMP, Immediate(1));
|
|
||||||
__ sw(TMP, Address(SP, 0));
|
|
||||||
__ lw(TMP, Address(SP, 0));
|
|
||||||
__ addiu(TMP, TMP, Immediate(1));
|
|
||||||
__ Pop(V0);
|
|
||||||
__ mov(V0, TMP);
|
|
||||||
__ Ret();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Generate a dart code sequence that embeds a string object in it.
|
|
||||||
// This is used to test Embedded String objects in the instructions.
|
|
||||||
void GenerateEmbedStringInCode(Assembler* assembler, const char* str) {
|
|
||||||
__ EnterDartFrame(0); // To setup pp.
|
|
||||||
const String& string_object =
|
|
||||||
String::ZoneHandle(String::New(str, Heap::kOld));
|
|
||||||
__ LoadObject(V0, string_object);
|
|
||||||
__ LeaveDartFrameAndReturn();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Generate a dart code sequence that embeds a smi object in it.
|
|
||||||
// This is used to test Embedded Smi objects in the instructions.
|
|
||||||
void GenerateEmbedSmiInCode(Assembler* assembler, intptr_t value) {
|
|
||||||
// No need to setup pp, since Smis are not stored in the object pool.
|
|
||||||
const Smi& smi_object = Smi::ZoneHandle(Smi::New(value));
|
|
||||||
__ LoadObject(V0, smi_object);
|
|
||||||
__ Ret();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace dart
|
|
||||||
|
|
||||||
#endif // defined TARGET_ARCH_MIPS
|
|
|
@ -209,7 +209,7 @@ intptr_t OS::PreferredCodeAlignment() {
|
||||||
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
|
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
|
||||||
defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_DBC)
|
defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_DBC)
|
||||||
const int kMinimumAlignment = 32;
|
const int kMinimumAlignment = 32;
|
||||||
#elif defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS)
|
#elif defined(TARGET_ARCH_ARM)
|
||||||
const int kMinimumAlignment = 16;
|
const int kMinimumAlignment = 16;
|
||||||
#else
|
#else
|
||||||
#error Unsupported architecture.
|
#error Unsupported architecture.
|
||||||
|
|
|
@ -130,7 +130,7 @@ intptr_t OS::PreferredCodeAlignment() {
|
||||||
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
|
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
|
||||||
defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_DBC)
|
defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_DBC)
|
||||||
const int kMinimumAlignment = 32;
|
const int kMinimumAlignment = 32;
|
||||||
#elif defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS)
|
#elif defined(TARGET_ARCH_ARM)
|
||||||
const int kMinimumAlignment = 16;
|
const int kMinimumAlignment = 16;
|
||||||
#else
|
#else
|
||||||
#error Unsupported architecture.
|
#error Unsupported architecture.
|
||||||
|
|
|
@ -198,7 +198,7 @@ intptr_t OS::ActivationFrameAlignment() {
|
||||||
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
|
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
|
||||||
defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_DBC)
|
defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_DBC)
|
||||||
const int kMinimumAlignment = 16;
|
const int kMinimumAlignment = 16;
|
||||||
#elif defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS)
|
#elif defined(TARGET_ARCH_ARM)
|
||||||
const int kMinimumAlignment = 8;
|
const int kMinimumAlignment = 8;
|
||||||
#else
|
#else
|
||||||
#error Unsupported architecture.
|
#error Unsupported architecture.
|
||||||
|
@ -217,7 +217,7 @@ intptr_t OS::PreferredCodeAlignment() {
|
||||||
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
|
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
|
||||||
defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_DBC)
|
defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_DBC)
|
||||||
const int kMinimumAlignment = 32;
|
const int kMinimumAlignment = 32;
|
||||||
#elif defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS)
|
#elif defined(TARGET_ARCH_ARM)
|
||||||
const int kMinimumAlignment = 16;
|
const int kMinimumAlignment = 16;
|
||||||
#else
|
#else
|
||||||
#error Unsupported architecture.
|
#error Unsupported architecture.
|
||||||
|
|
|
@ -195,7 +195,7 @@ intptr_t OS::PreferredCodeAlignment() {
|
||||||
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
|
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
|
||||||
defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_DBC)
|
defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_DBC)
|
||||||
const int kMinimumAlignment = 32;
|
const int kMinimumAlignment = 32;
|
||||||
#elif defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS)
|
#elif defined(TARGET_ARCH_ARM)
|
||||||
const int kMinimumAlignment = 16;
|
const int kMinimumAlignment = 16;
|
||||||
#else
|
#else
|
||||||
#error Unsupported architecture.
|
#error Unsupported architecture.
|
||||||
|
|
|
@ -191,7 +191,7 @@ int64_t OS::GetCurrentThreadCPUMicros() {
|
||||||
intptr_t OS::ActivationFrameAlignment() {
|
intptr_t OS::ActivationFrameAlignment() {
|
||||||
#if defined(TARGET_ARCH_ARM64)
|
#if defined(TARGET_ARCH_ARM64)
|
||||||
return 16;
|
return 16;
|
||||||
#elif defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS)
|
#elif defined(TARGET_ARCH_ARM)
|
||||||
return 8;
|
return 8;
|
||||||
#elif defined(_WIN64)
|
#elif defined(_WIN64)
|
||||||
// Windows 64-bit ABI requires the stack to be 16-byte aligned.
|
// Windows 64-bit ABI requires the stack to be 16-byte aligned.
|
||||||
|
@ -208,7 +208,7 @@ intptr_t OS::PreferredCodeAlignment() {
|
||||||
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
|
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
|
||||||
defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_DBC)
|
defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_DBC)
|
||||||
return 32;
|
return 32;
|
||||||
#elif defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS)
|
#elif defined(TARGET_ARCH_ARM)
|
||||||
return 16;
|
return 16;
|
||||||
#else
|
#else
|
||||||
#error Unsupported architecture.
|
#error Unsupported architecture.
|
||||||
|
|
|
@ -2798,11 +2798,10 @@ bool PrecompileParsedFunctionHelper::Compile(CompilationPipeline* pipeline) {
|
||||||
HANDLESCOPE(thread());
|
HANDLESCOPE(thread());
|
||||||
|
|
||||||
// We may reattempt compilation if the function needs to be assembled using
|
// We may reattempt compilation if the function needs to be assembled using
|
||||||
// far branches on ARM and MIPS. In the else branch of the setjmp call,
|
// far branches on ARM. In the else branch of the setjmp call, done is set to
|
||||||
// done is set to false, and use_far_branches is set to true if there is a
|
// false, and use_far_branches is set to true if there is a longjmp from the
|
||||||
// longjmp from the ARM or MIPS assemblers. In all other paths through this
|
// ARM assembler. In all other paths through this while loop, done is set to
|
||||||
// while loop, done is set to true. use_far_branches is always false on ia32
|
// true. use_far_branches is always false on ia32 and x64.
|
||||||
// and x64.
|
|
||||||
bool done = false;
|
bool done = false;
|
||||||
// volatile because the variable may be clobbered by a longjmp.
|
// volatile because the variable may be clobbered by a longjmp.
|
||||||
volatile bool use_far_branches = false;
|
volatile bool use_far_branches = false;
|
||||||
|
|
|
@ -32,7 +32,7 @@ static const intptr_t kMaxSamplesPerTick = 4;
|
||||||
DEFINE_FLAG(bool, trace_profiled_isolates, false, "Trace profiled isolates.");
|
DEFINE_FLAG(bool, trace_profiled_isolates, false, "Trace profiled isolates.");
|
||||||
|
|
||||||
#if defined(HOST_OS_ANDROID) || defined(TARGET_ARCH_ARM64) || \
|
#if defined(HOST_OS_ANDROID) || defined(TARGET_ARCH_ARM64) || \
|
||||||
defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS)
|
defined(TARGET_ARCH_ARM)
|
||||||
DEFINE_FLAG(int,
|
DEFINE_FLAG(int,
|
||||||
profile_period,
|
profile_period,
|
||||||
10000,
|
10000,
|
||||||
|
@ -288,11 +288,6 @@ bool ReturnAddressLocator::LocateReturnAddress(uword* return_address) {
|
||||||
ASSERT(return_address != NULL);
|
ASSERT(return_address != NULL);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#elif defined(TARGET_ARCH_MIPS)
|
|
||||||
bool ReturnAddressLocator::LocateReturnAddress(uword* return_address) {
|
|
||||||
ASSERT(return_address != NULL);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#elif defined(TARGET_ARCH_DBC)
|
#elif defined(TARGET_ARCH_DBC)
|
||||||
bool ReturnAddressLocator::LocateReturnAddress(uword* return_address) {
|
bool ReturnAddressLocator::LocateReturnAddress(uword* return_address) {
|
||||||
ASSERT(return_address != NULL);
|
ASSERT(return_address != NULL);
|
||||||
|
|
|
@ -1013,7 +1013,7 @@ class RawField : public RawObject {
|
||||||
// any other value otherwise.
|
// any other value otherwise.
|
||||||
// Offset to the guarded length field inside an instance of class matching
|
// Offset to the guarded length field inside an instance of class matching
|
||||||
// guarded_cid_. Stored corrected by -kHeapObjectTag to simplify code
|
// guarded_cid_. Stored corrected by -kHeapObjectTag to simplify code
|
||||||
// generated on platforms with weak addressing modes (ARM, MIPS).
|
// generated on platforms with weak addressing modes (ARM).
|
||||||
int8_t guarded_list_length_in_object_offset_;
|
int8_t guarded_list_length_in_object_offset_;
|
||||||
|
|
||||||
uint8_t kind_bits_; // static, final, const, has initializer....
|
uint8_t kind_bits_; // static, final, const, has initializer....
|
||||||
|
|
|
@ -302,8 +302,7 @@ void IRRegExpMacroAssembler::FinalizeRegistersArray() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_ARM) || \
|
#if defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_ARM)
|
||||||
defined(TARGET_ARCH_MIPS)
|
|
||||||
// Disabling unaligned accesses forces the regexp engine to load characters one
|
// Disabling unaligned accesses forces the regexp engine to load characters one
|
||||||
// by one instead of up to 4 at once, along with the associated performance hit.
|
// by one instead of up to 4 at once, along with the associated performance hit.
|
||||||
// TODO(zerny): Be less conservative about disabling unaligned accesses.
|
// TODO(zerny): Be less conservative about disabling unaligned accesses.
|
||||||
|
|
|
@ -130,7 +130,7 @@ class RuntimeEntry : public ValueObject {
|
||||||
|
|
||||||
#define END_LEAF_RUNTIME_ENTRY }
|
#define END_LEAF_RUNTIME_ENTRY }
|
||||||
|
|
||||||
// TODO(rmacnak): Fix alignment issue on simarm and simmips and use
|
// TODO(rmacnak): Fix alignment issue on simarm and use
|
||||||
// DEFINE_LEAF_RUNTIME_ENTRY instead.
|
// DEFINE_LEAF_RUNTIME_ENTRY instead.
|
||||||
#define DEFINE_RAW_LEAF_RUNTIME_ENTRY(name, argument_count, is_float, func) \
|
#define DEFINE_RAW_LEAF_RUNTIME_ENTRY(name, argument_count, is_float, func) \
|
||||||
extern const RuntimeEntry k##name##RuntimeEntry( \
|
extern const RuntimeEntry k##name##RuntimeEntry( \
|
||||||
|
|
|
@ -1,62 +0,0 @@
|
||||||
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
#include "vm/globals.h"
|
|
||||||
#if defined(TARGET_ARCH_MIPS)
|
|
||||||
|
|
||||||
#include "vm/runtime_entry.h"
|
|
||||||
|
|
||||||
#include "vm/assembler.h"
|
|
||||||
#include "vm/simulator.h"
|
|
||||||
#include "vm/stub_code.h"
|
|
||||||
|
|
||||||
namespace dart {
|
|
||||||
|
|
||||||
#define __ assembler->
|
|
||||||
|
|
||||||
|
|
||||||
uword RuntimeEntry::GetEntryPoint() const {
|
|
||||||
// Compute the effective address. When running under the simulator,
|
|
||||||
// this is a redirection address that forces the simulator to call
|
|
||||||
// into the runtime system.
|
|
||||||
uword entry = reinterpret_cast<uword>(function());
|
|
||||||
#if defined(USING_SIMULATOR)
|
|
||||||
// Redirection to leaf runtime calls supports a maximum of 4 arguments passed
|
|
||||||
// in registers (maximum 2 double arguments for leaf float runtime calls).
|
|
||||||
ASSERT(argument_count() >= 0);
|
|
||||||
ASSERT(!is_leaf() || (!is_float() && (argument_count() <= 4)) ||
|
|
||||||
(argument_count() <= 2));
|
|
||||||
Simulator::CallKind call_kind =
|
|
||||||
is_leaf() ? (is_float() ? Simulator::kLeafFloatRuntimeCall
|
|
||||||
: Simulator::kLeafRuntimeCall)
|
|
||||||
: Simulator::kRuntimeCall;
|
|
||||||
entry =
|
|
||||||
Simulator::RedirectExternalReference(entry, call_kind, argument_count());
|
|
||||||
#endif
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Generate code to call into the stub which will call the runtime
|
|
||||||
// function. Input for the stub is as follows:
|
|
||||||
// SP : points to the arguments and return value array.
|
|
||||||
// S5 : address of the runtime function to call.
|
|
||||||
// S4 : number of arguments to the call.
|
|
||||||
void RuntimeEntry::Call(Assembler* assembler, intptr_t argument_count) const {
|
|
||||||
if (is_leaf()) {
|
|
||||||
ASSERT(argument_count == this->argument_count());
|
|
||||||
__ lw(T9, Address(THR, Thread::OffsetFromThread(this)));
|
|
||||||
__ jalr(T9);
|
|
||||||
} else {
|
|
||||||
// Argument count is not checked here, but in the runtime entry for a more
|
|
||||||
// informative error message.
|
|
||||||
__ lw(S5, Address(THR, Thread::OffsetFromThread(this)));
|
|
||||||
__ LoadImmediate(S4, argument_count);
|
|
||||||
__ BranchLinkToRuntime();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace dart
|
|
||||||
|
|
||||||
#endif // defined TARGET_ARCH_MIPS
|
|
|
@ -21,8 +21,6 @@ uintptr_t SignalHandler::GetProgramCounter(const mcontext_t& mcontext) {
|
||||||
pc = static_cast<uintptr_t>(mcontext.arm_pc);
|
pc = static_cast<uintptr_t>(mcontext.arm_pc);
|
||||||
#elif defined(HOST_ARCH_ARM64)
|
#elif defined(HOST_ARCH_ARM64)
|
||||||
pc = static_cast<uintptr_t>(mcontext.pc);
|
pc = static_cast<uintptr_t>(mcontext.pc);
|
||||||
#elif defined(HOST_ARCH_MIPS)
|
|
||||||
pc = static_cast<uintptr_t>(mcontext.pc);
|
|
||||||
#else
|
#else
|
||||||
#error Unsupported architecture.
|
#error Unsupported architecture.
|
||||||
#endif // HOST_ARCH_...
|
#endif // HOST_ARCH_...
|
||||||
|
@ -41,8 +39,6 @@ uintptr_t SignalHandler::GetFramePointer(const mcontext_t& mcontext) {
|
||||||
fp = static_cast<uintptr_t>(mcontext.arm_fp);
|
fp = static_cast<uintptr_t>(mcontext.arm_fp);
|
||||||
#elif defined(HOST_ARCH_ARM64)
|
#elif defined(HOST_ARCH_ARM64)
|
||||||
fp = static_cast<uintptr_t>(mcontext.regs[29]);
|
fp = static_cast<uintptr_t>(mcontext.regs[29]);
|
||||||
#elif defined(HOST_ARCH_MIPS)
|
|
||||||
fp = static_cast<uintptr_t>(mcontext.gregs[30]);
|
|
||||||
#else
|
#else
|
||||||
#error Unsupported architecture.
|
#error Unsupported architecture.
|
||||||
#endif // HOST_ARCH_...
|
#endif // HOST_ARCH_...
|
||||||
|
@ -62,8 +58,6 @@ uintptr_t SignalHandler::GetCStackPointer(const mcontext_t& mcontext) {
|
||||||
sp = static_cast<uintptr_t>(mcontext.arm_sp);
|
sp = static_cast<uintptr_t>(mcontext.arm_sp);
|
||||||
#elif defined(HOST_ARCH_ARM64)
|
#elif defined(HOST_ARCH_ARM64)
|
||||||
sp = static_cast<uintptr_t>(mcontext.sp);
|
sp = static_cast<uintptr_t>(mcontext.sp);
|
||||||
#elif defined(HOST_ARCH_MIPS)
|
|
||||||
sp = static_cast<uintptr_t>(mcontext.gregs[29]);
|
|
||||||
#else
|
#else
|
||||||
#error Unsupported architecture.
|
#error Unsupported architecture.
|
||||||
#endif // HOST_ARCH_...
|
#endif // HOST_ARCH_...
|
||||||
|
@ -91,8 +85,6 @@ uintptr_t SignalHandler::GetLinkRegister(const mcontext_t& mcontext) {
|
||||||
lr = static_cast<uintptr_t>(mcontext.arm_lr);
|
lr = static_cast<uintptr_t>(mcontext.arm_lr);
|
||||||
#elif defined(HOST_ARCH_ARM64)
|
#elif defined(HOST_ARCH_ARM64)
|
||||||
lr = static_cast<uintptr_t>(mcontext.regs[30]);
|
lr = static_cast<uintptr_t>(mcontext.regs[30]);
|
||||||
#elif defined(HOST_ARCH_MIPS)
|
|
||||||
lr = static_cast<uintptr_t>(mcontext.gregs[31]);
|
|
||||||
#else
|
#else
|
||||||
#error Unsupported architecture.
|
#error Unsupported architecture.
|
||||||
#endif // HOST_ARCH_...
|
#endif // HOST_ARCH_...
|
||||||
|
|
|
@ -15,8 +15,6 @@
|
||||||
#include "vm/simulator_arm.h"
|
#include "vm/simulator_arm.h"
|
||||||
#elif defined(TARGET_ARCH_ARM64)
|
#elif defined(TARGET_ARCH_ARM64)
|
||||||
#include "vm/simulator_arm64.h"
|
#include "vm/simulator_arm64.h"
|
||||||
#elif defined(TARGET_ARCH_MIPS)
|
|
||||||
#include "vm/simulator_mips.h"
|
|
||||||
#elif defined(TARGET_ARCH_DBC)
|
#elif defined(TARGET_ARCH_DBC)
|
||||||
#include "vm/simulator_dbc.h"
|
#include "vm/simulator_dbc.h"
|
||||||
#else
|
#else
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,257 +0,0 @@
|
||||||
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// Declares a Simulator for MIPS instructions if we are not generating a native
|
|
||||||
// MIPS binary. This Simulator allows us to run and debug MIPS code generation
|
|
||||||
// on regular desktop machines.
|
|
||||||
// Dart calls into generated code by "calling" the InvokeDartCode stub,
|
|
||||||
// which will start execution in the Simulator or forwards to the real entry
|
|
||||||
// on a MIPS HW platform.
|
|
||||||
|
|
||||||
#ifndef RUNTIME_VM_SIMULATOR_MIPS_H_
|
|
||||||
#define RUNTIME_VM_SIMULATOR_MIPS_H_
|
|
||||||
|
|
||||||
#ifndef RUNTIME_VM_SIMULATOR_H_
|
|
||||||
#error Do not include simulator_mips.h directly; use simulator.h.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "vm/constants_mips.h"
|
|
||||||
|
|
||||||
namespace dart {
|
|
||||||
|
|
||||||
class Isolate;
|
|
||||||
class Mutex;
|
|
||||||
class RawObject;
|
|
||||||
class SimulatorSetjmpBuffer;
|
|
||||||
class Thread;
|
|
||||||
|
|
||||||
class Simulator {
|
|
||||||
public:
|
|
||||||
static const uword kSimulatorStackUnderflowSize = 64;
|
|
||||||
|
|
||||||
Simulator();
|
|
||||||
~Simulator();
|
|
||||||
|
|
||||||
// The currently executing Simulator instance, which is associated to the
|
|
||||||
// current isolate
|
|
||||||
static Simulator* Current();
|
|
||||||
|
|
||||||
// Accessors for register state.
|
|
||||||
void set_register(Register reg, int32_t value);
|
|
||||||
int32_t get_register(Register reg) const;
|
|
||||||
|
|
||||||
// Accessors for floating point register state.
|
|
||||||
void set_fregister(FRegister freg, int32_t value);
|
|
||||||
void set_fregister_float(FRegister freg, float value);
|
|
||||||
void set_fregister_double(FRegister freg, double value);
|
|
||||||
void set_fregister_long(FRegister freg, int64_t value);
|
|
||||||
|
|
||||||
int32_t get_fregister(FRegister freg) const;
|
|
||||||
float get_fregister_float(FRegister freg) const;
|
|
||||||
double get_fregister_double(FRegister freg) const;
|
|
||||||
int64_t get_fregister_long(FRegister freg) const;
|
|
||||||
|
|
||||||
void set_dregister_bits(DRegister freg, int64_t value);
|
|
||||||
void set_dregister(DRegister freg, double value);
|
|
||||||
|
|
||||||
int64_t get_dregister_bits(DRegister freg) const;
|
|
||||||
double get_dregister(DRegister freg) const;
|
|
||||||
|
|
||||||
int32_t get_sp() const { return get_register(SPREG); }
|
|
||||||
|
|
||||||
// Accessor for the pc.
|
|
||||||
void set_pc(int32_t value) { pc_ = value; }
|
|
||||||
int32_t get_pc() const { return pc_; }
|
|
||||||
|
|
||||||
// Accessors for hi, lo registers.
|
|
||||||
void set_hi_register(int32_t value) { hi_reg_ = value; }
|
|
||||||
void set_lo_register(int32_t value) { lo_reg_ = value; }
|
|
||||||
int32_t get_hi_register() const { return hi_reg_; }
|
|
||||||
int32_t get_lo_register() const { return lo_reg_; }
|
|
||||||
|
|
||||||
int32_t get_fcsr_condition_bit(int32_t cc) const {
|
|
||||||
if (cc == 0) {
|
|
||||||
return 23;
|
|
||||||
} else {
|
|
||||||
return 24 + cc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_fcsr_bit(uint32_t cc, bool value) {
|
|
||||||
if (value) {
|
|
||||||
fcsr_ |= (1 << cc);
|
|
||||||
} else {
|
|
||||||
fcsr_ &= ~(1 << cc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool test_fcsr_bit(uint32_t cc) { return fcsr_ & (1 << cc); }
|
|
||||||
|
|
||||||
// Accessors to the internal simulator stack base and top.
|
|
||||||
uword StackBase() const { return reinterpret_cast<uword>(stack_); }
|
|
||||||
uword StackTop() const;
|
|
||||||
|
|
||||||
// Accessor to the instruction counter.
|
|
||||||
uint64_t get_icount() const { return icount_; }
|
|
||||||
|
|
||||||
// The thread's top_exit_frame_info refers to a Dart frame in the simulator
|
|
||||||
// stack. The simulator's top_exit_frame_info refers to a C++ frame in the
|
|
||||||
// native stack.
|
|
||||||
uword top_exit_frame_info() const { return top_exit_frame_info_; }
|
|
||||||
void set_top_exit_frame_info(uword value) { top_exit_frame_info_ = value; }
|
|
||||||
|
|
||||||
// Call on program start.
|
|
||||||
static void InitOnce();
|
|
||||||
|
|
||||||
// Dart generally calls into generated code with 4 parameters. This is a
|
|
||||||
// convenience function, which sets up the simulator state and grabs the
|
|
||||||
// result on return. When fp_return is true the return value is the D0
|
|
||||||
// floating point register. Otherwise, the return value is V1:V0.
|
|
||||||
int64_t Call(int32_t entry,
|
|
||||||
int32_t parameter0,
|
|
||||||
int32_t parameter1,
|
|
||||||
int32_t parameter2,
|
|
||||||
int32_t parameter3,
|
|
||||||
bool fp_return = false,
|
|
||||||
bool fp_args = false);
|
|
||||||
|
|
||||||
// Implementation of atomic compare and exchange in the same synchronization
|
|
||||||
// domain as other synchronization primitive instructions (e.g. ldrex, strex).
|
|
||||||
static uword CompareExchange(uword* address,
|
|
||||||
uword compare_value,
|
|
||||||
uword new_value);
|
|
||||||
static uint32_t CompareExchangeUint32(uint32_t* address,
|
|
||||||
uint32_t compare_value,
|
|
||||||
uint32_t new_value);
|
|
||||||
|
|
||||||
// Runtime and native call support.
|
|
||||||
enum CallKind {
|
|
||||||
kRuntimeCall,
|
|
||||||
kLeafRuntimeCall,
|
|
||||||
kLeafFloatRuntimeCall,
|
|
||||||
kBootstrapNativeCall,
|
|
||||||
kNativeCall
|
|
||||||
};
|
|
||||||
static uword RedirectExternalReference(uword function,
|
|
||||||
CallKind call_kind,
|
|
||||||
int argument_count);
|
|
||||||
|
|
||||||
static uword FunctionForRedirect(uword redirect);
|
|
||||||
|
|
||||||
void JumpToFrame(uword pc, uword sp, uword fp, Thread* thread);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// A pc value used to signal the simulator to stop execution. Generally
|
|
||||||
// the ra is set to this value on transition from native C code to
|
|
||||||
// simulated execution, so that the simulator can "return" to the native
|
|
||||||
// C code.
|
|
||||||
static const uword kEndSimulatingPC = -1;
|
|
||||||
|
|
||||||
// Special registers for the results of div, divu.
|
|
||||||
int32_t hi_reg_;
|
|
||||||
int32_t lo_reg_;
|
|
||||||
|
|
||||||
int32_t registers_[kNumberOfCpuRegisters];
|
|
||||||
int32_t fregisters_[kNumberOfFRegisters];
|
|
||||||
int32_t fcsr_;
|
|
||||||
uword pc_;
|
|
||||||
|
|
||||||
// Simulator support.
|
|
||||||
char* stack_;
|
|
||||||
uint64_t icount_;
|
|
||||||
bool delay_slot_;
|
|
||||||
SimulatorSetjmpBuffer* last_setjmp_buffer_;
|
|
||||||
uword top_exit_frame_info_;
|
|
||||||
|
|
||||||
// Registered breakpoints.
|
|
||||||
Instr* break_pc_;
|
|
||||||
int32_t break_instr_;
|
|
||||||
|
|
||||||
// Illegal memory access support.
|
|
||||||
static bool IsIllegalAddress(uword addr) { return addr < 64 * 1024; }
|
|
||||||
void HandleIllegalAccess(uword addr, Instr* instr);
|
|
||||||
|
|
||||||
// Read and write memory.
|
|
||||||
void UnalignedAccess(const char* msg, uword addr, Instr* instr);
|
|
||||||
|
|
||||||
// Handles a legal instruction that the simulator does not implement.
|
|
||||||
void UnimplementedInstruction(Instr* instr);
|
|
||||||
|
|
||||||
void set_pc(uword value) { pc_ = value; }
|
|
||||||
|
|
||||||
void Format(Instr* instr, const char* format);
|
|
||||||
|
|
||||||
inline int8_t ReadB(uword addr);
|
|
||||||
inline uint8_t ReadBU(uword addr);
|
|
||||||
inline int16_t ReadH(uword addr, Instr* instr);
|
|
||||||
inline uint16_t ReadHU(uword addr, Instr* instr);
|
|
||||||
inline intptr_t ReadW(uword addr, Instr* instr);
|
|
||||||
|
|
||||||
inline void WriteB(uword addr, uint8_t value);
|
|
||||||
inline void WriteH(uword addr, uint16_t value, Instr* isntr);
|
|
||||||
inline void WriteW(uword addr, intptr_t value, Instr* instr);
|
|
||||||
|
|
||||||
inline double ReadD(uword addr, Instr* instr);
|
|
||||||
inline void WriteD(uword addr, double value, Instr* instr);
|
|
||||||
|
|
||||||
// We keep track of 16 exclusive access address tags across all threads.
|
|
||||||
// Since we cannot simulate a native context switch, which clears
|
|
||||||
// the exclusive access state of the local monitor, we associate the thread
|
|
||||||
// requesting exclusive access to the address tag.
|
|
||||||
// Multiple threads requesting exclusive access (using the LL instruction)
|
|
||||||
// to the same address will result in multiple address tags being created for
|
|
||||||
// the same address, one per thread.
|
|
||||||
// At any given time, each thread is associated to at most one address tag.
|
|
||||||
static Mutex* exclusive_access_lock_;
|
|
||||||
static const int kNumAddressTags = 16;
|
|
||||||
static struct AddressTag {
|
|
||||||
Thread* thread;
|
|
||||||
uword addr;
|
|
||||||
} exclusive_access_state_[kNumAddressTags];
|
|
||||||
static int next_address_tag_;
|
|
||||||
|
|
||||||
// Synchronization primitives support.
|
|
||||||
void ClearExclusive();
|
|
||||||
intptr_t ReadExclusiveW(uword addr, Instr* instr);
|
|
||||||
intptr_t WriteExclusiveW(uword addr, intptr_t value, Instr* instr);
|
|
||||||
|
|
||||||
// Set access to given address to 'exclusive state' for current thread.
|
|
||||||
static void SetExclusiveAccess(uword addr);
|
|
||||||
|
|
||||||
// Returns true if the current thread has exclusive access to given address,
|
|
||||||
// returns false otherwise. In either case, set access to given address to
|
|
||||||
// 'open state' for all threads.
|
|
||||||
// If given addr is NULL, set access to 'open state' for current
|
|
||||||
// thread (CLREX).
|
|
||||||
static bool HasExclusiveAccessAndOpen(uword addr);
|
|
||||||
|
|
||||||
void DoBranch(Instr* instr, bool taken, bool likely);
|
|
||||||
void DoBreak(Instr* instr);
|
|
||||||
|
|
||||||
void DecodeSpecial(Instr* instr);
|
|
||||||
void DecodeSpecial2(Instr* instr);
|
|
||||||
void DecodeRegImm(Instr* instr);
|
|
||||||
void DecodeCop1(Instr* instr);
|
|
||||||
void InstructionDecode(Instr* instr);
|
|
||||||
|
|
||||||
void Execute();
|
|
||||||
void ExecuteDelaySlot();
|
|
||||||
|
|
||||||
// Returns true if tracing of executed instructions is enabled.
|
|
||||||
bool IsTracingExecution() const;
|
|
||||||
|
|
||||||
// Longjmp support for exceptions.
|
|
||||||
SimulatorSetjmpBuffer* last_setjmp_buffer() { return last_setjmp_buffer_; }
|
|
||||||
void set_last_setjmp_buffer(SimulatorSetjmpBuffer* buffer) {
|
|
||||||
last_setjmp_buffer_ = buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
friend class SimulatorDebugger;
|
|
||||||
friend class SimulatorSetjmpBuffer;
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(Simulator);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace dart
|
|
||||||
|
|
||||||
#endif // RUNTIME_VM_SIMULATOR_MIPS_H_
|
|
|
@ -992,21 +992,6 @@ void AssemblyImageWriter::FrameUnwindPrologue() {
|
||||||
assembly_stream_.Print(".setfp r11, sp, #0\n");
|
assembly_stream_.Print(".setfp r11, sp, #0\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#elif defined(TARGET_ARCH_MIPS)
|
|
||||||
COMPILE_ASSERT(FP == R30);
|
|
||||||
COMPILE_ASSERT(RA == R31);
|
|
||||||
assembly_stream_.Print(".cfi_def_cfa r30, 0\n"); // CFA is fp+0
|
|
||||||
assembly_stream_.Print(".cfi_offset r30, 0\n"); // saved fp is *(CFA+0)
|
|
||||||
assembly_stream_.Print(".cfi_offset r31, 4\n"); // saved pc is *(CFA+4)
|
|
||||||
// saved sp is CFA+16
|
|
||||||
// Should be ".cfi_value_offset sp, 8", but requires gcc newer than late
|
|
||||||
// 2016 and not supported by Android's libunwind.
|
|
||||||
// DW_CFA_expression 0x10
|
|
||||||
// uleb128 register (sp) 29
|
|
||||||
// uleb128 size of operation 2
|
|
||||||
// DW_OP_plus_uconst 0x23
|
|
||||||
// uleb128 addend 8
|
|
||||||
assembly_stream_.Print(".cfi_escape 0x10, 29, 2, 0x23, 8\n");
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
#include "vm/stack_frame_arm.h"
|
#include "vm/stack_frame_arm.h"
|
||||||
#elif defined(TARGET_ARCH_ARM64)
|
#elif defined(TARGET_ARCH_ARM64)
|
||||||
#include "vm/stack_frame_arm64.h"
|
#include "vm/stack_frame_arm64.h"
|
||||||
#elif defined(TARGET_ARCH_MIPS)
|
|
||||||
#include "vm/stack_frame_mips.h"
|
|
||||||
#elif defined(TARGET_ARCH_DBC)
|
#elif defined(TARGET_ARCH_DBC)
|
||||||
#include "vm/stack_frame_dbc.h"
|
#include "vm/stack_frame_dbc.h"
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef RUNTIME_VM_STACK_FRAME_MIPS_H_
|
|
||||||
#define RUNTIME_VM_STACK_FRAME_MIPS_H_
|
|
||||||
|
|
||||||
namespace dart {
|
|
||||||
|
|
||||||
/* MIPS Dart Frame Layout
|
|
||||||
|
|
||||||
| | <- TOS
|
|
||||||
Callee frame | ... |
|
|
||||||
| current RA | (PC of current frame)
|
|
||||||
| callee's PC marker |
|
|
||||||
+--------------------+
|
|
||||||
Current frame | ... T| <- SP of current frame
|
|
||||||
| first local T|
|
|
||||||
| caller's PP T|
|
|
||||||
| CODE_REG T| (current frame's code object)
|
|
||||||
| caller's FP | <- FP of current frame
|
|
||||||
| caller's RA | (PC of caller frame)
|
|
||||||
+--------------------+
|
|
||||||
Caller frame | last parameter | <- SP of caller frame
|
|
||||||
| ... |
|
|
||||||
|
|
||||||
T against a slot indicates it needs to be traversed during GC.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static const int kDartFrameFixedSize = 4; // PP, FP, RA, PC marker.
|
|
||||||
static const int kSavedPcSlotFromSp = -1;
|
|
||||||
|
|
||||||
static const int kFirstObjectSlotFromFp = -1; // Used by GC to traverse stack.
|
|
||||||
|
|
||||||
static const int kFirstLocalSlotFromFp = -3;
|
|
||||||
static const int kSavedCallerPpSlotFromFp = -2;
|
|
||||||
static const int kPcMarkerSlotFromFp = -1;
|
|
||||||
static const int kSavedCallerFpSlotFromFp = 0;
|
|
||||||
static const int kSavedCallerPcSlotFromFp = 1;
|
|
||||||
static const int kParamEndSlotFromFp = 1; // One slot past last parameter.
|
|
||||||
static const int kCallerSpSlotFromFp = 2;
|
|
||||||
|
|
||||||
// Entry and exit frame layout.
|
|
||||||
static const int kExitLinkSlotFromEntryFp = -24;
|
|
||||||
COMPILE_ASSERT(kAbiPreservedCpuRegCount == 8);
|
|
||||||
COMPILE_ASSERT(kAbiPreservedFpuRegCount == 12);
|
|
||||||
|
|
||||||
} // namespace dart
|
|
||||||
|
|
||||||
#endif // RUNTIME_VM_STACK_FRAME_MIPS_H_
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,106 +0,0 @@
|
||||||
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
#include "vm/globals.h"
|
|
||||||
#if defined(TARGET_ARCH_MIPS)
|
|
||||||
|
|
||||||
#include "vm/isolate.h"
|
|
||||||
#include "vm/dart_entry.h"
|
|
||||||
#include "vm/native_entry.h"
|
|
||||||
#include "vm/native_entry_test.h"
|
|
||||||
#include "vm/object.h"
|
|
||||||
#include "vm/runtime_entry.h"
|
|
||||||
#include "vm/stub_code.h"
|
|
||||||
#include "vm/symbols.h"
|
|
||||||
#include "vm/unit_test.h"
|
|
||||||
|
|
||||||
#define __ assembler->
|
|
||||||
|
|
||||||
namespace dart {
|
|
||||||
|
|
||||||
static Function* CreateFunction(const char* name) {
|
|
||||||
const String& class_name =
|
|
||||||
String::Handle(Symbols::New(Thread::Current(), "ownerClass"));
|
|
||||||
const Script& script = Script::Handle();
|
|
||||||
const Library& lib = Library::Handle(Library::New(class_name));
|
|
||||||
const Class& owner_class = Class::Handle(
|
|
||||||
Class::New(lib, class_name, script, TokenPosition::kNoSource));
|
|
||||||
const String& function_name =
|
|
||||||
String::ZoneHandle(Symbols::New(Thread::Current(), name));
|
|
||||||
Function& function = Function::ZoneHandle(Function::New(
|
|
||||||
function_name, RawFunction::kRegularFunction, true, false, false, false,
|
|
||||||
false, owner_class, TokenPosition::kNoSource));
|
|
||||||
return &function;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Test calls to stub code which calls into the runtime.
|
|
||||||
static void GenerateCallToCallRuntimeStub(Assembler* assembler, int length) {
|
|
||||||
const int argc = 2;
|
|
||||||
const Smi& smi_length = Smi::ZoneHandle(Smi::New(length));
|
|
||||||
__ EnterDartFrame(0);
|
|
||||||
__ PushObject(Object::null_object()); // Push Null object for return value.
|
|
||||||
__ PushObject(smi_length); // Push argument 1: length.
|
|
||||||
__ PushObject(Object::null_object()); // Push argument 2: type arguments.
|
|
||||||
ASSERT(kAllocateArrayRuntimeEntry.argument_count() == argc);
|
|
||||||
__ CallRuntime(kAllocateArrayRuntimeEntry, argc);
|
|
||||||
__ addiu(SP, SP, Immediate(argc * kWordSize));
|
|
||||||
__ Pop(V0); // Pop return value from return slot.
|
|
||||||
__ LeaveDartFrameAndReturn();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TEST_CASE(CallRuntimeStubCode) {
|
|
||||||
extern const Function& RegisterFakeFunction(const char* name,
|
|
||||||
const Code& code);
|
|
||||||
const int length = 10;
|
|
||||||
const char* kName = "Test_CallRuntimeStubCode";
|
|
||||||
Assembler _assembler_;
|
|
||||||
GenerateCallToCallRuntimeStub(&_assembler_, length);
|
|
||||||
const Code& code = Code::Handle(Code::FinalizeCode(
|
|
||||||
*CreateFunction("Test_CallRuntimeStubCode"), &_assembler_));
|
|
||||||
const Function& function = RegisterFakeFunction(kName, code);
|
|
||||||
Array& result = Array::Handle();
|
|
||||||
result ^= DartEntry::InvokeFunction(function, Object::empty_array());
|
|
||||||
EXPECT_EQ(length, result.Length());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Test calls to stub code which calls into a leaf runtime entry.
|
|
||||||
static void GenerateCallToCallLeafRuntimeStub(Assembler* assembler,
|
|
||||||
const char* value1,
|
|
||||||
const char* value2) {
|
|
||||||
const Bigint& bigint1 =
|
|
||||||
Bigint::ZoneHandle(Bigint::NewFromCString(value1, Heap::kOld));
|
|
||||||
const Bigint& bigint2 =
|
|
||||||
Bigint::ZoneHandle(Bigint::NewFromCString(value2, Heap::kOld));
|
|
||||||
__ EnterDartFrame(0);
|
|
||||||
__ ReserveAlignedFrameSpace(0);
|
|
||||||
__ LoadObject(A0, bigint1); // Set up argument 1 bigint1.
|
|
||||||
__ LoadObject(A1, bigint2); // Set up argument 2 bigint2.
|
|
||||||
__ CallRuntime(kBigintCompareRuntimeEntry, 2);
|
|
||||||
__ SmiTag(V0);
|
|
||||||
__ LeaveDartFrameAndReturn(); // Return value is in V0.
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TEST_CASE(CallLeafRuntimeStubCode) {
|
|
||||||
extern const Function& RegisterFakeFunction(const char* name,
|
|
||||||
const Code& code);
|
|
||||||
const char* value1 = "0xAAABBCCDDAABBCCDD";
|
|
||||||
const char* value2 = "0xAABBCCDDAABBCCDD";
|
|
||||||
const char* kName = "Test_CallLeafRuntimeStubCode";
|
|
||||||
Assembler _assembler_;
|
|
||||||
GenerateCallToCallLeafRuntimeStub(&_assembler_, value1, value2);
|
|
||||||
const Code& code = Code::Handle(Code::FinalizeCode(
|
|
||||||
*CreateFunction("Test_CallLeafRuntimeStubCode"), &_assembler_));
|
|
||||||
const Function& function = RegisterFakeFunction(kName, code);
|
|
||||||
Smi& result = Smi::Handle();
|
|
||||||
result ^= DartEntry::InvokeFunction(function, Object::empty_array());
|
|
||||||
EXPECT_EQ(1, result.Value());
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace dart
|
|
||||||
|
|
||||||
#endif // defined TARGET_ARCH_MIPS
|
|
|
@ -162,11 +162,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS) || \
|
#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64)
|
||||||
defined(TARGET_ARCH_ARM64)
|
#if defined(HOST_ARCH_ARM) || defined(HOST_ARCH_ARM64)
|
||||||
#if defined(HOST_ARCH_ARM) || defined(HOST_ARCH_MIPS) || \
|
// Running on actual ARM hardware, execute code natively.
|
||||||
defined(HOST_ARCH_ARM64)
|
|
||||||
// Running on actual ARM or MIPS hardware, execute code natively.
|
|
||||||
#define EXECUTE_TEST_CODE_INT32(name, entry) reinterpret_cast<name>(entry)()
|
#define EXECUTE_TEST_CODE_INT32(name, entry) reinterpret_cast<name>(entry)()
|
||||||
#define EXECUTE_TEST_CODE_INT64(name, entry) reinterpret_cast<name>(entry)()
|
#define EXECUTE_TEST_CODE_INT64(name, entry) reinterpret_cast<name>(entry)()
|
||||||
#define EXECUTE_TEST_CODE_INT64_LL(name, entry, long_arg0, long_arg1) \
|
#define EXECUTE_TEST_CODE_INT64_LL(name, entry, long_arg0, long_arg1) \
|
||||||
|
@ -182,7 +180,7 @@
|
||||||
#define EXECUTE_TEST_CODE_INT32_INTPTR(name, entry, pointer_arg) \
|
#define EXECUTE_TEST_CODE_INT32_INTPTR(name, entry, pointer_arg) \
|
||||||
reinterpret_cast<name>(entry)(pointer_arg)
|
reinterpret_cast<name>(entry)(pointer_arg)
|
||||||
#else
|
#else
|
||||||
// Not running on ARM or MIPS hardware, call simulator to execute code.
|
// Not running on ARM hardware, call simulator to execute code.
|
||||||
#if defined(ARCH_IS_64_BIT)
|
#if defined(ARCH_IS_64_BIT)
|
||||||
#define EXECUTE_TEST_CODE_INT64(name, entry) \
|
#define EXECUTE_TEST_CODE_INT64(name, entry) \
|
||||||
static_cast<int64_t>( \
|
static_cast<int64_t>( \
|
||||||
|
@ -232,8 +230,8 @@
|
||||||
Utils::Low32Bits(bit_cast<int64_t, double>(double_arg)), \
|
Utils::Low32Bits(bit_cast<int64_t, double>(double_arg)), \
|
||||||
Utils::High32Bits(bit_cast<int64_t, double>(double_arg)), 0, 0, false, \
|
Utils::High32Bits(bit_cast<int64_t, double>(double_arg)), 0, 0, false, \
|
||||||
true))
|
true))
|
||||||
#endif // defined(HOST_ARCH_ARM) || defined(HOST_ARCH_MIPS)
|
#endif // defined(HOST_ARCH_ARM)
|
||||||
#endif // defined(TARGET_ARCH_{ARM, ARM64, MIPS})
|
#endif // defined(TARGET_ARCH_{ARM, ARM64})
|
||||||
|
|
||||||
|
|
||||||
inline Dart_Handle NewString(const char* str) {
|
inline Dart_Handle NewString(const char* str) {
|
||||||
|
|
|
@ -25,9 +25,6 @@
|
||||||
'assembler_ia32.cc',
|
'assembler_ia32.cc',
|
||||||
'assembler_ia32.h',
|
'assembler_ia32.h',
|
||||||
'assembler_ia32_test.cc',
|
'assembler_ia32_test.cc',
|
||||||
'assembler_mips.cc',
|
|
||||||
'assembler_mips.h',
|
|
||||||
'assembler_mips_test.cc',
|
|
||||||
'assembler_test.cc',
|
'assembler_test.cc',
|
||||||
'assembler_x64.cc',
|
'assembler_x64.cc',
|
||||||
'assembler_x64.h',
|
'assembler_x64.h',
|
||||||
|
@ -98,8 +95,6 @@
|
||||||
'code_patcher_dbc.cc',
|
'code_patcher_dbc.cc',
|
||||||
'code_patcher_ia32.cc',
|
'code_patcher_ia32.cc',
|
||||||
'code_patcher_ia32_test.cc',
|
'code_patcher_ia32_test.cc',
|
||||||
'code_patcher_mips.cc',
|
|
||||||
'code_patcher_mips_test.cc',
|
|
||||||
'code_patcher_x64.cc',
|
'code_patcher_x64.cc',
|
||||||
'code_patcher_x64_test.cc',
|
'code_patcher_x64_test.cc',
|
||||||
'compilation_trace.cc',
|
'compilation_trace.cc',
|
||||||
|
@ -114,14 +109,12 @@
|
||||||
'constants_arm.h',
|
'constants_arm.h',
|
||||||
'constants_arm64.h',
|
'constants_arm64.h',
|
||||||
'constants_ia32.h',
|
'constants_ia32.h',
|
||||||
'constants_mips.h',
|
|
||||||
'constants_x64.h',
|
'constants_x64.h',
|
||||||
'cpu.h',
|
'cpu.h',
|
||||||
'cpu_arm.cc',
|
'cpu_arm.cc',
|
||||||
'cpu_arm64.cc',
|
'cpu_arm64.cc',
|
||||||
'cpu_dbc.cc',
|
'cpu_dbc.cc',
|
||||||
'cpu_ia32.cc',
|
'cpu_ia32.cc',
|
||||||
'cpu_mips.cc',
|
|
||||||
'cpu_test.cc',
|
'cpu_test.cc',
|
||||||
'cpu_x64.cc',
|
'cpu_x64.cc',
|
||||||
'cpuid.h',
|
'cpuid.h',
|
||||||
|
@ -154,7 +147,6 @@
|
||||||
'debugger_arm64.cc',
|
'debugger_arm64.cc',
|
||||||
'debugger_dbc.cc',
|
'debugger_dbc.cc',
|
||||||
'debugger_ia32.cc',
|
'debugger_ia32.cc',
|
||||||
'debugger_mips.cc',
|
|
||||||
'debugger_x64.cc',
|
'debugger_x64.cc',
|
||||||
'deferred_objects.cc',
|
'deferred_objects.cc',
|
||||||
'deferred_objects.h',
|
'deferred_objects.h',
|
||||||
|
@ -166,7 +158,6 @@
|
||||||
'disassembler_arm64.cc',
|
'disassembler_arm64.cc',
|
||||||
'disassembler_dbc.cc',
|
'disassembler_dbc.cc',
|
||||||
'disassembler_ia32.cc',
|
'disassembler_ia32.cc',
|
||||||
'disassembler_mips.cc',
|
|
||||||
'disassembler_test.cc',
|
'disassembler_test.cc',
|
||||||
'disassembler_x64.cc',
|
'disassembler_x64.cc',
|
||||||
'double_conversion.cc',
|
'double_conversion.cc',
|
||||||
|
@ -197,7 +188,6 @@
|
||||||
'flow_graph_compiler_arm64.cc',
|
'flow_graph_compiler_arm64.cc',
|
||||||
'flow_graph_compiler_dbc.cc',
|
'flow_graph_compiler_dbc.cc',
|
||||||
'flow_graph_compiler_ia32.cc',
|
'flow_graph_compiler_ia32.cc',
|
||||||
'flow_graph_compiler_mips.cc',
|
|
||||||
'flow_graph_compiler_x64.cc',
|
'flow_graph_compiler_x64.cc',
|
||||||
'flow_graph_inliner.cc',
|
'flow_graph_inliner.cc',
|
||||||
'flow_graph_inliner.h',
|
'flow_graph_inliner.h',
|
||||||
|
@ -242,9 +232,6 @@
|
||||||
'instructions_ia32.cc',
|
'instructions_ia32.cc',
|
||||||
'instructions_ia32.h',
|
'instructions_ia32.h',
|
||||||
'instructions_ia32_test.cc',
|
'instructions_ia32_test.cc',
|
||||||
'instructions_mips.cc',
|
|
||||||
'instructions_mips.h',
|
|
||||||
'instructions_mips_test.cc',
|
|
||||||
'instructions_x64.cc',
|
'instructions_x64.cc',
|
||||||
'instructions_x64.h',
|
'instructions_x64.h',
|
||||||
'instructions_x64_test.cc',
|
'instructions_x64_test.cc',
|
||||||
|
@ -254,7 +241,6 @@
|
||||||
'intermediate_language_arm64.cc',
|
'intermediate_language_arm64.cc',
|
||||||
'intermediate_language_dbc.cc',
|
'intermediate_language_dbc.cc',
|
||||||
'intermediate_language_ia32.cc',
|
'intermediate_language_ia32.cc',
|
||||||
'intermediate_language_mips.cc',
|
|
||||||
'intermediate_language_test.cc',
|
'intermediate_language_test.cc',
|
||||||
'intermediate_language_x64.cc',
|
'intermediate_language_x64.cc',
|
||||||
'intrinsifier.cc',
|
'intrinsifier.cc',
|
||||||
|
@ -263,7 +249,6 @@
|
||||||
'intrinsifier_arm64.cc',
|
'intrinsifier_arm64.cc',
|
||||||
'intrinsifier_dbc.cc',
|
'intrinsifier_dbc.cc',
|
||||||
'intrinsifier_ia32.cc',
|
'intrinsifier_ia32.cc',
|
||||||
'intrinsifier_mips.cc',
|
|
||||||
'intrinsifier_x64.cc',
|
'intrinsifier_x64.cc',
|
||||||
'isolate.cc',
|
'isolate.cc',
|
||||||
'isolate.h',
|
'isolate.h',
|
||||||
|
@ -294,7 +279,6 @@
|
||||||
'malloc_hooks_arm.cc',
|
'malloc_hooks_arm.cc',
|
||||||
'malloc_hooks_arm64.cc',
|
'malloc_hooks_arm64.cc',
|
||||||
'malloc_hooks_ia32.cc',
|
'malloc_hooks_ia32.cc',
|
||||||
'malloc_hooks_mips.cc',
|
|
||||||
'malloc_hooks_x64.cc',
|
'malloc_hooks_x64.cc',
|
||||||
'malloc_hooks.h',
|
'malloc_hooks.h',
|
||||||
'malloc_hooks_test.cc',
|
'malloc_hooks_test.cc',
|
||||||
|
@ -340,7 +324,6 @@
|
||||||
'object_id_ring.cc',
|
'object_id_ring.cc',
|
||||||
'object_id_ring.h',
|
'object_id_ring.h',
|
||||||
'object_id_ring_test.cc',
|
'object_id_ring_test.cc',
|
||||||
'object_mips_test.cc',
|
|
||||||
'object_reload.cc',
|
'object_reload.cc',
|
||||||
'object_service.cc',
|
'object_service.cc',
|
||||||
'object_set.h',
|
'object_set.h',
|
||||||
|
@ -438,7 +421,6 @@
|
||||||
'runtime_entry_arm64.cc',
|
'runtime_entry_arm64.cc',
|
||||||
'runtime_entry_dbc.cc',
|
'runtime_entry_dbc.cc',
|
||||||
'runtime_entry_ia32.cc',
|
'runtime_entry_ia32.cc',
|
||||||
'runtime_entry_mips.cc',
|
|
||||||
'runtime_entry.cc',
|
'runtime_entry.cc',
|
||||||
'runtime_entry_x64.cc',
|
'runtime_entry_x64.cc',
|
||||||
'safepoint.cc',
|
'safepoint.cc',
|
||||||
|
@ -473,8 +455,6 @@
|
||||||
'simulator_arm64.h',
|
'simulator_arm64.h',
|
||||||
'simulator_dbc.cc',
|
'simulator_dbc.cc',
|
||||||
'simulator_dbc.h',
|
'simulator_dbc.h',
|
||||||
'simulator_mips.cc',
|
|
||||||
'simulator_mips.h',
|
|
||||||
'snapshot.cc',
|
'snapshot.cc',
|
||||||
'snapshot.h',
|
'snapshot.h',
|
||||||
'snapshot_ids.h',
|
'snapshot_ids.h',
|
||||||
|
@ -488,7 +468,6 @@
|
||||||
'stack_frame_arm.h',
|
'stack_frame_arm.h',
|
||||||
'stack_frame_arm64.h',
|
'stack_frame_arm64.h',
|
||||||
'stack_frame_ia32.h',
|
'stack_frame_ia32.h',
|
||||||
'stack_frame_mips.h',
|
|
||||||
'stack_frame_test.cc',
|
'stack_frame_test.cc',
|
||||||
'stack_frame_x64.h',
|
'stack_frame_x64.h',
|
||||||
'stack_trace.cc',
|
'stack_trace.cc',
|
||||||
|
@ -504,8 +483,6 @@
|
||||||
'stub_code_dbc.cc',
|
'stub_code_dbc.cc',
|
||||||
'stub_code_ia32.cc',
|
'stub_code_ia32.cc',
|
||||||
'stub_code_ia32_test.cc',
|
'stub_code_ia32_test.cc',
|
||||||
'stub_code_mips.cc',
|
|
||||||
'stub_code_mips_test.cc',
|
|
||||||
'stub_code_x64.cc',
|
'stub_code_x64.cc',
|
||||||
'stub_code_x64_test.cc',
|
'stub_code_x64_test.cc',
|
||||||
'symbols.cc',
|
'symbols.cc',
|
||||||
|
|
|
@ -30,8 +30,8 @@ then
|
||||||
DIRS=$( ls "$OUT_DIR" )
|
DIRS=$( ls "$OUT_DIR" )
|
||||||
# list of possible configurations in decreasing desirability
|
# list of possible configurations in decreasing desirability
|
||||||
CONFIGS=("ReleaseX64" "ReleaseIA32" "DebugX64" "DebugIA32"
|
CONFIGS=("ReleaseX64" "ReleaseIA32" "DebugX64" "DebugIA32"
|
||||||
"ReleaseARM" "ReleaseARM64" "ReleaseARMV5TE" "ReleaseMIPS"
|
"ReleaseARM" "ReleaseARM64" "ReleaseARMV5TE"
|
||||||
"DebugARM" "DebugARM64" "DebugARMV5TE" "DebugMIPS")
|
"DebugARM" "DebugARM64" "DebugARMV5TE")
|
||||||
DART_CONFIGURATION="None"
|
DART_CONFIGURATION="None"
|
||||||
for CONFIG in ${CONFIGS[*]}
|
for CONFIG in ${CONFIGS[*]}
|
||||||
do
|
do
|
||||||
|
|
|
@ -47,8 +47,8 @@ then
|
||||||
DIRS=$( ls "$OUT_DIR" )
|
DIRS=$( ls "$OUT_DIR" )
|
||||||
# list of possible configurations in decreasing desirability
|
# list of possible configurations in decreasing desirability
|
||||||
CONFIGS=("ReleaseX64" "ReleaseIA32" "DebugX64" "DebugIA32"
|
CONFIGS=("ReleaseX64" "ReleaseIA32" "DebugX64" "DebugIA32"
|
||||||
"ReleaseARM" "ReleaseARM64" "ReleaseARMV5TE" "ReleaseMIPS"
|
"ReleaseARM" "ReleaseARM64" "ReleaseARMV5TE"
|
||||||
"DebugARM" "DebugARM64" "DebugARMV5TE" "DebugMIPS")
|
"DebugARM" "DebugARM64" "DebugARMV5TE")
|
||||||
DART_CONFIGURATION="None"
|
DART_CONFIGURATION="None"
|
||||||
for CONFIG in ${CONFIGS[*]}
|
for CONFIG in ${CONFIGS[*]}
|
||||||
do
|
do
|
||||||
|
|
|
@ -55,14 +55,14 @@ LibTest/core/List/List_class_A01_t02: Pass, Slow
|
||||||
[ ($runtime == vm || $runtime == dart_precompiled) && ($arch != x64 && $arch != simarm64 && $arch != arm64 && $arch != simdbc64 && $arch != simdbc) ]
|
[ ($runtime == vm || $runtime == dart_precompiled) && ($arch != x64 && $arch != simarm64 && $arch != arm64 && $arch != simdbc64 && $arch != simdbc) ]
|
||||||
LibTest/core/int/operator_left_shift_A01_t02: Fail # co19 issue 129
|
LibTest/core/int/operator_left_shift_A01_t02: Fail # co19 issue 129
|
||||||
|
|
||||||
[ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) && ($arch == mips || $arch == arm64) ]
|
[ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) && $arch == arm64 ]
|
||||||
# These tests take too much memory (300 MB) for our 1 GB test machine.
|
# These tests take too much memory (300 MB) for our 1 GB test machine.
|
||||||
# co19 issue 673. http://code.google.com/p/co19/issues/detail?id=673
|
# co19 issue 673. http://code.google.com/p/co19/issues/detail?id=673
|
||||||
LibTest/core/List/List_class_A01_t02: Skip # co19 issue 673
|
LibTest/core/List/List_class_A01_t02: Skip # co19 issue 673
|
||||||
LibTest/collection/ListMixin/ListMixin_class_A01_t02: Skip # co19 issue 673
|
LibTest/collection/ListMixin/ListMixin_class_A01_t02: Skip # co19 issue 673
|
||||||
LibTest/collection/ListBase/ListBase_class_A01_t02: Skip # co19 issue 673
|
LibTest/collection/ListBase/ListBase_class_A01_t02: Skip # co19 issue 673
|
||||||
|
|
||||||
[ ($runtime == vm || $runtime == dart_precompiled) && ($arch == simarm || $arch == simarmv6 || $arch == simarmv5te || $arch == simmips || $arch == simarm64 || $arch == simdbc || $arch == simdbc64) ]
|
[ ($runtime == vm || $runtime == dart_precompiled) && ($arch == simarm || $arch == simarmv6 || $arch == simarmv5te || $arch == simarm64 || $arch == simdbc || $arch == simdbc64) ]
|
||||||
LibTest/collection/DoubleLinkedQueue/DoubleLinkedQueue_class_A01_t01: Skip # Timeout
|
LibTest/collection/DoubleLinkedQueue/DoubleLinkedQueue_class_A01_t01: Skip # Timeout
|
||||||
LibTest/collection/IterableBase/IterableBase_class_A01_t02: Skip # Timeout
|
LibTest/collection/IterableBase/IterableBase_class_A01_t02: Skip # Timeout
|
||||||
LibTest/collection/IterableMixin/IterableMixin_class_A02_t01: Skip # Timeout
|
LibTest/collection/IterableMixin/IterableMixin_class_A02_t01: Skip # Timeout
|
||||||
|
|
|
@ -12,9 +12,6 @@ isolate_stress_test: Skip # Issue 12588: Uses dart:html. This should be able to
|
||||||
[ $runtime != vm || $mode == product || $compiler == app_jit ]
|
[ $runtime != vm || $mode == product || $compiler == app_jit ]
|
||||||
checked_test: Skip # Unsupported.
|
checked_test: Skip # Unsupported.
|
||||||
|
|
||||||
[ ($runtime == vm || $runtime == dart_precompiled) && $arch == mips && $mode == debug ]
|
|
||||||
mandel_isolate_test: Skip # Uses 600 MB Ram on our 1 GB test device.
|
|
||||||
|
|
||||||
[ $compiler == none || $compiler == precompiler || $compiler == app_jit ]
|
[ $compiler == none || $compiler == precompiler || $compiler == app_jit ]
|
||||||
compile_time_error_test/01: Skip # Issue 12587
|
compile_time_error_test/01: Skip # Issue 12587
|
||||||
ping_test: Skip # Resolve test issues
|
ping_test: Skip # Resolve test issues
|
||||||
|
|
|
@ -144,9 +144,6 @@ async_await_test: Skip # Issue 26198
|
||||||
[ $compiler == none && $runtime == drt ]
|
[ $compiler == none && $runtime == drt ]
|
||||||
disassemble_test: Pass, Fail # Issue 18122
|
disassemble_test: Pass, Fail # Issue 18122
|
||||||
|
|
||||||
[ ($runtime == vm || $runtime == dart_precompiled) && $arch == mips && $mode == debug ]
|
|
||||||
large_class_declaration_test: SkipSlow # Times out. Issue 20352
|
|
||||||
|
|
||||||
[ ($runtime == vm || $runtime == flutter || $runtime == dart_precompiled) && $arch == arm64 ]
|
[ ($runtime == vm || $runtime == flutter || $runtime == dart_precompiled) && $arch == arm64 ]
|
||||||
large_class_declaration_test: SkipSlow # Uses too much memory.
|
large_class_declaration_test: SkipSlow # Uses too much memory.
|
||||||
closure_cycles_test: Pass, Slow
|
closure_cycles_test: Pass, Slow
|
||||||
|
@ -154,12 +151,11 @@ closure_cycles_test: Pass, Slow
|
||||||
[ $compiler == none && ($runtime == dartium || $runtime == drt) && $mode == debug ]
|
[ $compiler == none && ($runtime == dartium || $runtime == drt) && $mode == debug ]
|
||||||
large_class_declaration_test: SkipSlow # Times out. Issue 20352
|
large_class_declaration_test: SkipSlow # Times out. Issue 20352
|
||||||
|
|
||||||
[ ($runtime == vm || $runtime == dart_precompiled) && ($arch == simmips || $arch == mips) ]
|
[ $runtime == vm || $runtime == dart_precompiled ]
|
||||||
vm/load_to_load_unaligned_forwarding_vm_test: Pass, Crash # Unaligned offset. Issue 22151
|
vm/load_to_load_unaligned_forwarding_vm_test: Pass, Crash # Unaligned offset. Issue 22151
|
||||||
vm/unaligned_float_access_literal_index_test: Pass, Crash # Unaligned offset. Issue 22151
|
vm/unaligned_float_access_literal_index_test: Pass, Crash # Unaligned offset. Issue 22151
|
||||||
vm/unaligned_float_access_literal_index_test: Pass, Crash # Unaligned offset. Issue 22151
|
vm/unaligned_float_access_literal_index_test: Pass, Crash # Unaligned offset. Issue 22151
|
||||||
|
|
||||||
|
|
||||||
[ $compiler == none && ($runtime == dartium || $runtime == drt) ]
|
[ $compiler == none && ($runtime == dartium || $runtime == drt) ]
|
||||||
issue23244_test: Fail # Issue 23244
|
issue23244_test: Fail # Issue 23244
|
||||||
|
|
||||||
|
|
|
@ -57,11 +57,9 @@ String getArchFromBuildDir(String buildDirectory) {
|
||||||
if (buildDirectory.endsWith('SIMARM64')) return '';
|
if (buildDirectory.endsWith('SIMARM64')) return '';
|
||||||
if (buildDirectory.endsWith('SIMDBC')) return '';
|
if (buildDirectory.endsWith('SIMDBC')) return '';
|
||||||
if (buildDirectory.endsWith('SIMDBC64')) return '';
|
if (buildDirectory.endsWith('SIMDBC64')) return '';
|
||||||
if (buildDirectory.endsWith('SIMMIPS')) return '';
|
|
||||||
if (buildDirectory.endsWith('ARM')) return '-arm';
|
if (buildDirectory.endsWith('ARM')) return '-arm';
|
||||||
if (buildDirectory.endsWith('ARM64')) return '-arm64';
|
if (buildDirectory.endsWith('ARM64')) return '-arm64';
|
||||||
if (buildDirectory.endsWith('IA32')) return '-ia32';
|
if (buildDirectory.endsWith('IA32')) return '-ia32';
|
||||||
if (buildDirectory.endsWith('MIPS')) return '-mips';
|
|
||||||
if (buildDirectory.endsWith('X64')) return '-x64';
|
if (buildDirectory.endsWith('X64')) return '-x64';
|
||||||
return 'unknown';
|
return 'unknown';
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,31 +119,16 @@ io/file_stream_test: Skip # Issue 26109
|
||||||
io/file_typed_data_test: Skip # Issue 26109
|
io/file_typed_data_test: Skip # Issue 26109
|
||||||
io/file_input_stream_test: Skip # Issue 26109
|
io/file_input_stream_test: Skip # Issue 26109
|
||||||
|
|
||||||
[ $runtime != vm || $arch == arm || $arch == arm64 || $arch == mips || ($system == windows && $mode == debug) ]
|
[ $runtime != vm || $arch == arm || $arch == arm64 || ($system == windows && $mode == debug) ]
|
||||||
fragmentation_test: Skip # VM test uses too much memory for small systems.
|
fragmentation_test: Skip # VM test uses too much memory for small systems.
|
||||||
|
|
||||||
[ $arch == simarm || $arch == simarmv6 || $arch == simarmv5te || $arch == simmips ]
|
[ $arch == simarm || $arch == simarmv6 || $arch == simarmv5te ]
|
||||||
out_of_memory_test: Skip # passes on Mac, crashes on Linux
|
out_of_memory_test: Skip # passes on Mac, crashes on Linux
|
||||||
oom_error_stacktrace_test: Skip # Fails on Linux
|
oom_error_stacktrace_test: Skip # Fails on Linux
|
||||||
|
|
||||||
[ $arch == simmips ]
|
|
||||||
io/socket_bind_test: Pass, Fail # Issue 28315
|
|
||||||
io/http_server_response_test: Pass, Crash # Issue 29012
|
|
||||||
|
|
||||||
[ ($arch == simarm || $arch == simdbc || $arch == simdbc64) && $mode == debug && $checked ]
|
[ ($arch == simarm || $arch == simdbc || $arch == simdbc64) && $mode == debug && $checked ]
|
||||||
io/web_socket_test: Pass, Fail # Issue 26814
|
io/web_socket_test: Pass, Fail # Issue 26814
|
||||||
|
|
||||||
[ $arch == mips ]
|
|
||||||
io/file_stat_test: Fail # Issue 17440
|
|
||||||
io/process_sync_test: Skip # Starts 10 dart subprocesses, uses too much memory.
|
|
||||||
io/signals_test: Skip # Starts 10 dart subprocesses, uses too much memory
|
|
||||||
io/socket_source_address_test: Fail # Issue 22597
|
|
||||||
|
|
||||||
[ $arch == mips && $mode == debug ]
|
|
||||||
io/web_socket_test: SkipSlow # Times out. Issue 20352
|
|
||||||
io/test_runner_test: Skip # Flakily times out in a subtest. Issue 201351
|
|
||||||
io/http_client_stays_alive_test: Skip # Timing dependent test, MIPS machine too slow.
|
|
||||||
|
|
||||||
[ $compiler == none && $runtime == dartium && ! $checked ]
|
[ $compiler == none && $runtime == dartium && ! $checked ]
|
||||||
assert_test: Fail # Issue 14651.
|
assert_test: Fail # Issue 14651.
|
||||||
|
|
||||||
|
|
6
third_party/pkg_tested/pkg_tested.status
vendored
6
third_party/pkg_tested/pkg_tested.status
vendored
|
@ -23,7 +23,7 @@ pub/*: SkipByDesign
|
||||||
pub/test/run/app_can_read_from_stdin_test: Fail # Issue 19448
|
pub/test/run/app_can_read_from_stdin_test: Fail # Issue 19448
|
||||||
pub/test/run/forwards_signal_posix_test: SkipByDesign
|
pub/test/run/forwards_signal_posix_test: SkipByDesign
|
||||||
|
|
||||||
[ $runtime == vm && ($mode == debug || $arch == mips || $arch == simmips || $arch == simarm || $arch == simarmv6 || $arch == simarmv5te || $arch == simarm64 || $builder_tag == asan) ]
|
[ $runtime == vm && ($mode == debug || $arch == simarm || $arch == simarmv6 || $arch == simarmv5te || $arch == simarm64 || $builder_tag == asan) ]
|
||||||
dart_style/test/command_line_test: Skip # The test controller does not take into account that tests take much longer in debug mode or on simulators/mips.
|
dart_style/test/command_line_test: Skip # The test controller does not take into account that tests take much longer in debug mode or on simulators.
|
||||||
dart_style/test/formatter_test: Skip # The test controller does not take into account that tests take much longer in debug mode or on simulators/mips.
|
dart_style/test/formatter_test: Skip # The test controller does not take into account that tests take much longer in debug mode or on simulators.
|
||||||
|
|
||||||
|
|
2
third_party/tcmalloc/README.dart
vendored
2
third_party/tcmalloc/README.dart
vendored
|
@ -21,5 +21,5 @@ To roll tcmalloc forward:
|
||||||
|
|
||||||
. Update the DEPS file with the new git hash.
|
. Update the DEPS file with the new git hash.
|
||||||
|
|
||||||
. Build and run tests for Debug, Release, and Product builds for ia32, x64, mips
|
. Build and run tests for Debug, Release, and Product builds for ia32, x64,
|
||||||
and arm for Linux and any other OSs that are supported.
|
and arm for Linux and any other OSs that are supported.
|
||||||
|
|
|
@ -63,7 +63,7 @@ def BuildOptions():
|
||||||
result.add_option("-a", "--arch",
|
result.add_option("-a", "--arch",
|
||||||
help='Target architectures (comma-separated).',
|
help='Target architectures (comma-separated).',
|
||||||
metavar='[all,ia32,x64,simarm,arm,simarmv6,armv6,simarmv5te,armv5te,'
|
metavar='[all,ia32,x64,simarm,arm,simarmv6,armv6,simarmv5te,armv5te,'
|
||||||
'simmips,mips,simarm64,arm64,simdbc,armsimdbc]',
|
'simarm64,arm64,simdbc,armsimdbc]',
|
||||||
default=utils.GuessArchitecture())
|
default=utils.GuessArchitecture())
|
||||||
result.add_option("--os",
|
result.add_option("--os",
|
||||||
help='Target OSs (comma-separated).',
|
help='Target OSs (comma-separated).',
|
||||||
|
@ -117,7 +117,7 @@ def ProcessOptions(options, args):
|
||||||
return False
|
return False
|
||||||
for arch in options.arch:
|
for arch in options.arch:
|
||||||
archs = ['ia32', 'x64', 'simarm', 'arm', 'simarmv6', 'armv6',
|
archs = ['ia32', 'x64', 'simarm', 'arm', 'simarmv6', 'armv6',
|
||||||
'simarmv5te', 'armv5te', 'simmips', 'mips', 'simarm64', 'arm64',
|
'simarmv5te', 'armv5te', 'simarm64', 'arm64',
|
||||||
'simdbc', 'simdbc64', 'armsimdbc', 'armsimdbc64']
|
'simdbc', 'simdbc64', 'armsimdbc', 'armsimdbc64']
|
||||||
if not arch in archs:
|
if not arch in archs:
|
||||||
print "Unknown arch %s" % arch
|
print "Unknown arch %s" % arch
|
||||||
|
@ -135,7 +135,7 @@ def ProcessOptions(options, args):
|
||||||
print ("Cross-compilation to %s is not supported on host os %s."
|
print ("Cross-compilation to %s is not supported on host os %s."
|
||||||
% (os_name, HOST_OS))
|
% (os_name, HOST_OS))
|
||||||
return False
|
return False
|
||||||
if not arch in ['ia32', 'x64', 'arm', 'armv6', 'armv5te', 'arm64', 'mips',
|
if not arch in ['ia32', 'x64', 'arm', 'armv6', 'armv5te', 'arm64',
|
||||||
'simdbc', 'simdbc64']:
|
'simdbc', 'simdbc64']:
|
||||||
print ("Cross-compilation to %s is not supported for architecture %s."
|
print ("Cross-compilation to %s is not supported for architecture %s."
|
||||||
% (os_name, arch))
|
% (os_name, arch))
|
||||||
|
@ -175,8 +175,6 @@ def GetToolchainPrefix(target_os, arch, options):
|
||||||
if arch == 'arm64':
|
if arch == 'arm64':
|
||||||
return (DEFAULT_ARM_CROSS_COMPILER_PATH + "/aarch64-linux-gnu")
|
return (DEFAULT_ARM_CROSS_COMPILER_PATH + "/aarch64-linux-gnu")
|
||||||
|
|
||||||
# TODO(zra): Find default MIPS Linux cross-compiler.
|
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
@ -484,13 +482,6 @@ def BuildNinjaCommand(options, target, target_os, mode, arch):
|
||||||
filter_xcodebuild_output = False
|
filter_xcodebuild_output = False
|
||||||
def BuildOneConfig(options, target, target_os, mode, arch):
|
def BuildOneConfig(options, target, target_os, mode, arch):
|
||||||
global filter_xcodebuild_output
|
global filter_xcodebuild_output
|
||||||
if arch.startswith('mips'):
|
|
||||||
bold = '\033[1m'
|
|
||||||
reset = '\033[0m'
|
|
||||||
print(bold + "Warning: MIPS architectures are unlikely to be supported in "
|
|
||||||
"upcoming releases. Please consider using another architecture "
|
|
||||||
"and/or file an issue explaining your specific use of and need for "
|
|
||||||
"MIPS support." + reset)
|
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
args = []
|
args = []
|
||||||
build_config = utils.GetBuildConf(mode, arch, target_os)
|
build_config = utils.GetBuildConf(mode, arch, target_os)
|
||||||
|
|
|
@ -96,18 +96,6 @@ const List<BuildGroup> buildGroups = const <BuildGroup>[
|
||||||
'vm tests',
|
'vm tests',
|
||||||
'checked vm tests',
|
'checked vm tests',
|
||||||
]),
|
]),
|
||||||
const BuildSubgroup(shardNames: const <String>[
|
|
||||||
'vm-linux-debug-simmips-be',
|
|
||||||
], testSteps: const <String>[
|
|
||||||
'vm tests',
|
|
||||||
'checked vm tests',
|
|
||||||
]),
|
|
||||||
const BuildSubgroup(shardNames: const <String>[
|
|
||||||
'vm-linux-release-simmips-be',
|
|
||||||
], testSteps: const <String>[
|
|
||||||
'vm tests',
|
|
||||||
'checked vm tests',
|
|
||||||
]),
|
|
||||||
const BuildSubgroup(shardNames: const <String>[
|
const BuildSubgroup(shardNames: const <String>[
|
||||||
'vm-linux-debug-simarm-be',
|
'vm-linux-debug-simarm-be',
|
||||||
], testSteps: const <String>[
|
], testSteps: const <String>[
|
||||||
|
|
|
@ -22,8 +22,6 @@ const Map<String, List<String>> shardGroups = const {
|
||||||
'vm-win-release-x64-be',
|
'vm-win-release-x64-be',
|
||||||
'vm-win-debug-ia32-be',
|
'vm-win-debug-ia32-be',
|
||||||
'vm-win-release-ia32-be',
|
'vm-win-release-ia32-be',
|
||||||
'vm-linux-debug-simmips-be',
|
|
||||||
'vm-linux-release-simmips-be',
|
|
||||||
'vm-linux-debug-simarm-be',
|
'vm-linux-debug-simarm-be',
|
||||||
'vm-linux-release-simarm-be',
|
'vm-linux-release-simarm-be',
|
||||||
'vm-linux-release-simarm64-be',
|
'vm-linux-release-simarm64-be',
|
||||||
|
@ -175,8 +173,6 @@ const Map<String, List<String>> shardGroups = const {
|
||||||
'vm-win-release-x64-dev',
|
'vm-win-release-x64-dev',
|
||||||
'vm-win-debug-ia32-dev',
|
'vm-win-debug-ia32-dev',
|
||||||
'vm-win-release-ia32-dev',
|
'vm-win-release-ia32-dev',
|
||||||
'vm-linux-debug-simmips-dev',
|
|
||||||
'vm-linux-release-simmips-dev',
|
|
||||||
'vm-linux-debug-simarm-dev',
|
'vm-linux-debug-simarm-dev',
|
||||||
'vm-linux-release-simarm-dev',
|
'vm-linux-release-simarm-dev',
|
||||||
'vm-linux-release-simarm64-dev',
|
'vm-linux-release-simarm64-dev',
|
||||||
|
@ -356,8 +352,6 @@ const Map<String, List<String>> shardGroups = const {
|
||||||
'vm-win-release-x64-stable',
|
'vm-win-release-x64-stable',
|
||||||
'vm-win-debug-ia32-stable',
|
'vm-win-debug-ia32-stable',
|
||||||
'vm-win-release-ia32-stable',
|
'vm-win-release-ia32-stable',
|
||||||
'vm-linux-debug-simmips-stable',
|
|
||||||
'vm-linux-release-simmips-stable',
|
|
||||||
'vm-linux-debug-simarm-stable',
|
'vm-linux-debug-simarm-stable',
|
||||||
'vm-linux-release-simarm-stable',
|
'vm-linux-release-simarm-stable',
|
||||||
'vm-linux-release-simarm64-stable',
|
'vm-linux-release-simarm64-stable',
|
||||||
|
|
28
tools/gn.py
28
tools/gn.py
|
@ -75,8 +75,8 @@ def ToCommandLine(gn_args):
|
||||||
|
|
||||||
|
|
||||||
def HostCpuForArch(arch):
|
def HostCpuForArch(arch):
|
||||||
if arch in ['ia32', 'arm', 'armv6', 'armv5te', 'mips',
|
if arch in ['ia32', 'arm', 'armv6', 'armv5te',
|
||||||
'simarm', 'simarmv6', 'simarmv5te', 'simmips', 'simdbc',
|
'simarm', 'simarmv6', 'simarmv5te', 'simdbc',
|
||||||
'armsimdbc']:
|
'armsimdbc']:
|
||||||
return 'x86'
|
return 'x86'
|
||||||
if arch in ['x64', 'arm64', 'simarm64', 'simdbc64', 'armsimdbc64']:
|
if arch in ['x64', 'arm64', 'simarm64', 'simdbc64', 'armsimdbc64']:
|
||||||
|
@ -84,12 +84,10 @@ def HostCpuForArch(arch):
|
||||||
|
|
||||||
|
|
||||||
def TargetCpuForArch(arch, target_os):
|
def TargetCpuForArch(arch, target_os):
|
||||||
if arch in ['ia32', 'simarm', 'simarmv6', 'simarmv5te', 'simmips']:
|
if arch in ['ia32', 'simarm', 'simarmv6', 'simarmv5te']:
|
||||||
return 'x86'
|
return 'x86'
|
||||||
if arch in ['simarm64']:
|
if arch in ['simarm64']:
|
||||||
return 'x64'
|
return 'x64'
|
||||||
if arch == 'mips':
|
|
||||||
return 'mipsel'
|
|
||||||
if arch == 'simdbc':
|
if arch == 'simdbc':
|
||||||
return 'arm' if target_os == 'android' else 'x86'
|
return 'arm' if target_os == 'android' else 'x86'
|
||||||
if arch == 'simdbc64':
|
if arch == 'simdbc64':
|
||||||
|
@ -127,14 +125,12 @@ def DontUseClang(args, target_os, host_cpu, target_cpu):
|
||||||
# We don't have clang on Windows.
|
# We don't have clang on Windows.
|
||||||
return (target_os == 'win'
|
return (target_os == 'win'
|
||||||
# TODO(zra): Experiment with using clang for the arm cross-builds.
|
# TODO(zra): Experiment with using clang for the arm cross-builds.
|
||||||
or (target_os == 'linux'
|
or (target_os == 'linux' and target_cpu.startswith('arm'))
|
||||||
and (target_cpu.startswith('arm') or
|
|
||||||
target_cpu.startswith('mips'))
|
|
||||||
# TODO(zra): Only use clang when a sanitizer build is specified until
|
# TODO(zra): Only use clang when a sanitizer build is specified until
|
||||||
# clang bugs in tcmalloc inline assembly for ia32 are fixed.
|
# clang bugs in tcmalloc inline assembly for ia32 are fixed.
|
||||||
or (target_os == 'linux'
|
or (target_os == 'linux'
|
||||||
and host_cpu == 'x86'
|
and host_cpu == 'x86'
|
||||||
and not UseSanitizer(args))))
|
and not UseSanitizer(args)))
|
||||||
|
|
||||||
|
|
||||||
def ToGnArgs(args, mode, arch, target_os):
|
def ToGnArgs(args, mode, arch, target_os):
|
||||||
|
@ -146,14 +142,6 @@ def ToGnArgs(args, mode, arch, target_os):
|
||||||
else:
|
else:
|
||||||
gn_args['target_os'] = target_os
|
gn_args['target_os'] = target_os
|
||||||
|
|
||||||
if arch.startswith('mips'):
|
|
||||||
bold = '\033[1m'
|
|
||||||
reset = '\033[0m'
|
|
||||||
print(bold + "Warning: MIPS architectures are unlikely to be supported in "
|
|
||||||
"upcoming releases. Please consider using another architecture "
|
|
||||||
"and/or file an issue explaining your specific use of and need for "
|
|
||||||
"MIPS support." + reset)
|
|
||||||
|
|
||||||
gn_args['dart_target_arch'] = arch
|
gn_args['dart_target_arch'] = arch
|
||||||
gn_args['target_cpu'] = TargetCpuForArch(arch, target_os)
|
gn_args['target_cpu'] = TargetCpuForArch(arch, target_os)
|
||||||
gn_args['host_cpu'] = HostCpuForArch(arch)
|
gn_args['host_cpu'] = HostCpuForArch(arch)
|
||||||
|
@ -272,7 +260,7 @@ def ProcessOptions(args):
|
||||||
return False
|
return False
|
||||||
for arch in args.arch:
|
for arch in args.arch:
|
||||||
archs = ['ia32', 'x64', 'simarm', 'arm', 'simarmv6', 'armv6',
|
archs = ['ia32', 'x64', 'simarm', 'arm', 'simarmv6', 'armv6',
|
||||||
'simarmv5te', 'armv5te', 'simmips', 'mips', 'simarm64', 'arm64',
|
'simarmv5te', 'armv5te', 'simarm64', 'arm64',
|
||||||
'simdbc', 'simdbc64', 'armsimdbc', 'armsimdbc64']
|
'simdbc', 'simdbc64', 'armsimdbc', 'armsimdbc64']
|
||||||
if not arch in archs:
|
if not arch in archs:
|
||||||
print "Unknown arch %s" % arch
|
print "Unknown arch %s" % arch
|
||||||
|
@ -290,7 +278,7 @@ def ProcessOptions(args):
|
||||||
print ("Cross-compilation to %s is not supported on host os %s."
|
print ("Cross-compilation to %s is not supported on host os %s."
|
||||||
% (os_name, HOST_OS))
|
% (os_name, HOST_OS))
|
||||||
return False
|
return False
|
||||||
if not arch in ['ia32', 'x64', 'arm', 'armv6', 'armv5te', 'arm64', 'mips',
|
if not arch in ['ia32', 'x64', 'arm', 'armv6', 'armv5te', 'arm64',
|
||||||
'simdbc', 'simdbc64']:
|
'simdbc', 'simdbc64']:
|
||||||
print ("Cross-compilation to %s is not supported for architecture %s."
|
print ("Cross-compilation to %s is not supported for architecture %s."
|
||||||
% (os_name, arch))
|
% (os_name, arch))
|
||||||
|
@ -323,7 +311,7 @@ def parse_args(args):
|
||||||
type=str,
|
type=str,
|
||||||
help='Target architectures (comma-separated).',
|
help='Target architectures (comma-separated).',
|
||||||
metavar='[all,ia32,x64,simarm,arm,simarmv6,armv6,simarmv5te,armv5te,'
|
metavar='[all,ia32,x64,simarm,arm,simarmv6,armv6,simarmv5te,armv5te,'
|
||||||
'simmips,mips,simarm64,arm64,simdbc,armsimdbc]',
|
'simarm64,arm64,simdbc,armsimdbc]',
|
||||||
default='x64')
|
default='x64')
|
||||||
common_group.add_argument('--mode', '-m',
|
common_group.add_argument('--mode', '-m',
|
||||||
type=str,
|
type=str,
|
||||||
|
|
|
@ -24,8 +24,6 @@
|
||||||
['"<(target_arch)"=="simarmv6"', { 'dart_target_arch': 'SIMARMV6', }],
|
['"<(target_arch)"=="simarmv6"', { 'dart_target_arch': 'SIMARMV6', }],
|
||||||
['"<(target_arch)"=="simarmv5te"', { 'dart_target_arch': 'SIMARMV5TE', }],
|
['"<(target_arch)"=="simarmv5te"', { 'dart_target_arch': 'SIMARMV5TE', }],
|
||||||
['"<(target_arch)"=="simarm64"', { 'dart_target_arch': 'SIMARM64', }],
|
['"<(target_arch)"=="simarm64"', { 'dart_target_arch': 'SIMARM64', }],
|
||||||
['"<(target_arch)"=="mips"', { 'dart_target_arch': 'MIPS', }],
|
|
||||||
['"<(target_arch)"=="simmips"', { 'dart_target_arch': 'SIMMIPS', }],
|
|
||||||
['"<(target_arch)"=="simdbc"', { 'dart_target_arch': 'SIMDBC', }],
|
['"<(target_arch)"=="simdbc"', { 'dart_target_arch': 'SIMDBC', }],
|
||||||
['"<(target_arch)"=="simdbc64"', { 'dart_target_arch': 'SIMDBC64', }],
|
['"<(target_arch)"=="simdbc64"', { 'dart_target_arch': 'SIMDBC64', }],
|
||||||
[ 'OS=="linux"', { 'dart_target_os': 'Linux', } ],
|
[ 'OS=="linux"', { 'dart_target_os': 'Linux', } ],
|
||||||
|
@ -120,20 +118,6 @@
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
'Dart_simmips_Base': {
|
|
||||||
'abstract': 1,
|
|
||||||
'defines': [
|
|
||||||
'TARGET_ARCH_MIPS',
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
'Dart_mips_Base': {
|
|
||||||
'abstract': 1,
|
|
||||||
'defines': [
|
|
||||||
'TARGET_ARCH_MIPS',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
'Dart_simdbc_Base': {
|
'Dart_simdbc_Base': {
|
||||||
'abstract': 1,
|
'abstract': 1,
|
||||||
'defines': [
|
'defines': [
|
||||||
|
@ -336,36 +320,6 @@
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
'DebugSIMMIPS': {
|
|
||||||
'inherit_from': [
|
|
||||||
'Dart_Base', 'Dart_simmips_Base', 'Dart_Debug',
|
|
||||||
'Dart_<(dart_target_os)_Base',
|
|
||||||
'Dart_<(dart_target_os)_simmips_Base',
|
|
||||||
'Dart_<(dart_target_os)_Debug',
|
|
||||||
],
|
|
||||||
'defines': [
|
|
||||||
'DEBUG',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
'ReleaseSIMMIPS': {
|
|
||||||
'inherit_from': [
|
|
||||||
'Dart_Base', 'Dart_simmips_Base', 'Dart_Release',
|
|
||||||
'Dart_<(dart_target_os)_Base',
|
|
||||||
'Dart_<(dart_target_os)_simmips_Base',
|
|
||||||
'Dart_<(dart_target_os)_Release',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
'ProductSIMMIPS': {
|
|
||||||
'inherit_from': [
|
|
||||||
'Dart_Base', 'Dart_simmips_Base', 'Dart_Product',
|
|
||||||
'Dart_<(dart_target_os)_Base',
|
|
||||||
'Dart_<(dart_target_os)_simmips_Base',
|
|
||||||
'Dart_<(dart_target_os)_Product',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
'DebugSIMDBC': {
|
'DebugSIMDBC': {
|
||||||
'inherit_from': [
|
'inherit_from': [
|
||||||
'Dart_Base', 'Dart_simdbc_Base', 'Dart_Debug',
|
'Dart_Base', 'Dart_simdbc_Base', 'Dart_Debug',
|
||||||
|
@ -458,7 +412,7 @@
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
# ARM and MIPS hardware configurations are only for Linux and Android.
|
# ARM hardware configurations are only for Linux and Android.
|
||||||
'DebugXARM': {
|
'DebugXARM': {
|
||||||
'inherit_from': [
|
'inherit_from': [
|
||||||
'Dart_Base', 'Dart_arm_Base', 'Dart_Debug',
|
'Dart_Base', 'Dart_arm_Base', 'Dart_Debug',
|
||||||
|
@ -675,62 +629,6 @@
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
'DebugXMIPS': {
|
|
||||||
'inherit_from': [
|
|
||||||
'Dart_Base', 'Dart_mips_Base', 'Dart_Debug',
|
|
||||||
'Dart_Linux_Base',
|
|
||||||
'Dart_Linux_xmips_Base',
|
|
||||||
'Dart_Linux_xmips_Debug',
|
|
||||||
'Dart_Linux_Debug',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
'ReleaseXMIPS': {
|
|
||||||
'inherit_from': [
|
|
||||||
'Dart_Base', 'Dart_mips_Base', 'Dart_Release',
|
|
||||||
'Dart_Linux_Base',
|
|
||||||
'Dart_Linux_xmips_Base',
|
|
||||||
'Dart_Linux_xmips_Release',
|
|
||||||
'Dart_Linux_Release',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
'ProductXMIPS': {
|
|
||||||
'inherit_from': [
|
|
||||||
'Dart_Base', 'Dart_mips_Base', 'Dart_Product',
|
|
||||||
'Dart_Linux_Base',
|
|
||||||
'Dart_Linux_xmips_Base',
|
|
||||||
'Dart_Linux_Product',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
'DebugMIPS': {
|
|
||||||
'inherit_from': [
|
|
||||||
'Dart_Base', 'Dart_mips_Base', 'Dart_Debug',
|
|
||||||
'Dart_Linux_Base',
|
|
||||||
'Dart_Linux_mips_Base',
|
|
||||||
'Dart_Linux_Debug',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
'ReleaseMIPS': {
|
|
||||||
'inherit_from': [
|
|
||||||
'Dart_Base', 'Dart_mips_Base', 'Dart_Release',
|
|
||||||
'Dart_Linux_Base',
|
|
||||||
'Dart_Linux_mips_Base',
|
|
||||||
'Dart_Linux_Release',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
'ProductMIPS': {
|
|
||||||
'inherit_from': [
|
|
||||||
'Dart_Base', 'Dart_mips_Base', 'Dart_Product',
|
|
||||||
'Dart_Linux_Base',
|
|
||||||
'Dart_Linux_mips_Base',
|
|
||||||
'Dart_Linux_Product',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
# Android configurations. The configuration names explicitly include
|
# Android configurations. The configuration names explicitly include
|
||||||
# 'Android' because we are cross-building from Linux, and, when building
|
# 'Android' because we are cross-building from Linux, and, when building
|
||||||
# the standalone VM, we cannot inspect the gyp built-in 'OS' variable to
|
# the standalone VM, we cannot inspect the gyp built-in 'OS' variable to
|
||||||
|
|
|
@ -257,91 +257,6 @@
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
'Dart_Linux_simmips_Base': {
|
|
||||||
'abstract': 1,
|
|
||||||
'cflags': [
|
|
||||||
'-O3',
|
|
||||||
'-m32',
|
|
||||||
'-msse2',
|
|
||||||
'-mfpmath=sse',
|
|
||||||
],
|
|
||||||
'ldflags': [
|
|
||||||
'-m32',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
# MIPS cross-build
|
|
||||||
'Dart_Linux_xmips_Base': {
|
|
||||||
'abstract': 1,
|
|
||||||
'target_conditions': [
|
|
||||||
['_toolset=="target"', {
|
|
||||||
'cflags': [
|
|
||||||
'-EL',
|
|
||||||
'-march=mips32',
|
|
||||||
'-mhard-float',
|
|
||||||
'-fno-strict-overflow',
|
|
||||||
],
|
|
||||||
'ldflags': [
|
|
||||||
'-EL',
|
|
||||||
],
|
|
||||||
}],
|
|
||||||
['_toolset=="host"',{
|
|
||||||
'cflags': [
|
|
||||||
'-O3',
|
|
||||||
'-m32',
|
|
||||||
'-msse2',
|
|
||||||
'-mfpmath=sse',
|
|
||||||
],
|
|
||||||
'ldflags': [
|
|
||||||
'-m32',
|
|
||||||
],
|
|
||||||
}]]
|
|
||||||
},
|
|
||||||
|
|
||||||
# These flags are needed for tcmalloc to be able to collect stack traces
|
|
||||||
# for heap profiling on mips.
|
|
||||||
'Dart_Linux_xmips_Debug': {
|
|
||||||
'abstract': 1,
|
|
||||||
'target_conditions': [
|
|
||||||
['_toolset=="target"', {
|
|
||||||
'cflags!': [
|
|
||||||
'-fno-exceptions',
|
|
||||||
],
|
|
||||||
'cflags': [
|
|
||||||
'-fexceptions',
|
|
||||||
'-funwind-tables',
|
|
||||||
],
|
|
||||||
}],
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
# These flags are needed for tcmalloc to be able to collect stack traces
|
|
||||||
# for heap profiling on mips.
|
|
||||||
'Dart_Linux_xmips_Release': {
|
|
||||||
'abstract': 1,
|
|
||||||
'target_conditions': [
|
|
||||||
['_toolset=="target"', {
|
|
||||||
'cflags!': [
|
|
||||||
'-fno-exceptions',
|
|
||||||
],
|
|
||||||
'cflags': [
|
|
||||||
'-fexceptions',
|
|
||||||
'-funwind-tables',
|
|
||||||
],
|
|
||||||
}],
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
# MIPS native build
|
|
||||||
'Dart_Linux_mips_Base': {
|
|
||||||
'abstract': 1,
|
|
||||||
'cflags': [
|
|
||||||
'-march=mips32',
|
|
||||||
'-mhard-float',
|
|
||||||
'-fno-strict-overflow',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
'Dart_Linux_Debug': {
|
'Dart_Linux_Debug': {
|
||||||
'abstract': 1,
|
'abstract': 1,
|
||||||
'cflags': [
|
'cflags': [
|
||||||
|
|
|
@ -38,9 +38,6 @@
|
||||||
'Dart_Win_simarm64_Base': {
|
'Dart_Win_simarm64_Base': {
|
||||||
'abstract': 1,
|
'abstract': 1,
|
||||||
},
|
},
|
||||||
'Dart_Win_simmips_Base': {
|
|
||||||
'abstract': 1,
|
|
||||||
},
|
|
||||||
'Dart_Win_simdbc_Base': {
|
'Dart_Win_simdbc_Base': {
|
||||||
'abstract': 1,
|
'abstract': 1,
|
||||||
},
|
},
|
||||||
|
|
|
@ -74,9 +74,6 @@
|
||||||
'Dart_Macos_simarm64_Base': {
|
'Dart_Macos_simarm64_Base': {
|
||||||
'abstract': 1,
|
'abstract': 1,
|
||||||
},
|
},
|
||||||
'Dart_Macos_simmips_Base': {
|
|
||||||
'abstract': 1,
|
|
||||||
},
|
|
||||||
'Dart_Macos_simdbc_Base': {
|
'Dart_Macos_simdbc_Base': {
|
||||||
'abstract': 1,
|
'abstract': 1,
|
||||||
},
|
},
|
||||||
|
|
|
@ -40,7 +40,7 @@ def BuildOptions():
|
||||||
result.add_option("-a", "--arch",
|
result.add_option("-a", "--arch",
|
||||||
help='Target architectures (comma-separated).',
|
help='Target architectures (comma-separated).',
|
||||||
metavar='[all,ia32,x64,simarm,arm,simarmv6,armv6,simarmv5te,armv5te,'
|
metavar='[all,ia32,x64,simarm,arm,simarmv6,armv6,simarmv5te,armv5te,'
|
||||||
'simmips,mips,simarm64,arm64,simdbc,armsimdbc]',
|
'simarm64,arm64,simdbc,armsimdbc]',
|
||||||
default=utils.GuessArchitecture())
|
default=utils.GuessArchitecture())
|
||||||
result.add_option("--os",
|
result.add_option("--os",
|
||||||
help='Target OSs (comma-separated).',
|
help='Target OSs (comma-separated).',
|
||||||
|
@ -76,7 +76,7 @@ def ProcessOptions(options, args):
|
||||||
return False
|
return False
|
||||||
for arch in options.arch:
|
for arch in options.arch:
|
||||||
archs = ['ia32', 'x64', 'simarm', 'arm', 'simarmv6', 'armv6',
|
archs = ['ia32', 'x64', 'simarm', 'arm', 'simarmv6', 'armv6',
|
||||||
'simarmv5te', 'armv5te', 'simmips', 'mips', 'simarm64', 'arm64',
|
'simarmv5te', 'armv5te', 'simarm64', 'arm64',
|
||||||
'simdbc', 'simdbc64', 'armsimdbc', 'armsimdbc64']
|
'simdbc', 'simdbc64', 'armsimdbc', 'armsimdbc64']
|
||||||
if not arch in archs:
|
if not arch in archs:
|
||||||
print "Unknown arch %s" % arch
|
print "Unknown arch %s" % arch
|
||||||
|
@ -94,7 +94,7 @@ def ProcessOptions(options, args):
|
||||||
print ("Cross-compilation to %s is not supported on host os %s."
|
print ("Cross-compilation to %s is not supported on host os %s."
|
||||||
% (os_name, HOST_OS))
|
% (os_name, HOST_OS))
|
||||||
return False
|
return False
|
||||||
if not arch in ['ia32', 'x64', 'arm', 'armv6', 'armv5te', 'arm64', 'mips',
|
if not arch in ['ia32', 'x64', 'arm', 'armv6', 'armv5te', 'arm64',
|
||||||
'simdbc', 'simdbc64']:
|
'simdbc', 'simdbc64']:
|
||||||
print ("Cross-compilation to %s is not supported for architecture %s."
|
print ("Cross-compilation to %s is not supported for architecture %s."
|
||||||
% (os_name, arch))
|
% (os_name, arch))
|
||||||
|
@ -225,13 +225,6 @@ def EnsureGomaStarted(out_dir):
|
||||||
|
|
||||||
# Returns a tuple (build_config, command to run, whether goma is used)
|
# Returns a tuple (build_config, command to run, whether goma is used)
|
||||||
def BuildOneConfig(options, targets, target_os, mode, arch):
|
def BuildOneConfig(options, targets, target_os, mode, arch):
|
||||||
if arch.startswith('mips'):
|
|
||||||
bold = '\033[1m'
|
|
||||||
reset = '\033[0m'
|
|
||||||
print(bold + "Warning: MIPS architectures are unlikely to be supported in "
|
|
||||||
"upcoming releases. Please consider using another architecture "
|
|
||||||
"and/or file an issue explaining your specific use of and need for "
|
|
||||||
"MIPS support." + reset)
|
|
||||||
build_config = utils.GetBuildConf(mode, arch, target_os)
|
build_config = utils.GetBuildConf(mode, arch, target_os)
|
||||||
out_dir = utils.GetBuildRoot(HOST_OS, mode, arch, target_os)
|
out_dir = utils.GetBuildRoot(HOST_OS, mode, arch, target_os)
|
||||||
using_goma = False
|
using_goma = False
|
||||||
|
|
|
@ -18,8 +18,7 @@ processor architecture.
|
||||||
|
|
||||||
To upload new versions of these tar files, use the "upload_to_google_storage"
|
To upload new versions of these tar files, use the "upload_to_google_storage"
|
||||||
tool in depot_tools, and download the new stable SDKs from the dartlang.org
|
tool in depot_tools, and download the new stable SDKs from the dartlang.org
|
||||||
web page. The mips and arm executables must be copied from the machines that
|
web page. The arm executables must be copied from the machines that
|
||||||
build them, and stripped. Because these SDKs are used for the presubmit
|
build them, and stripped. Because these SDKs are used for the presubmit
|
||||||
dartfmt check on changed files, they may need to be updated often when
|
dartfmt check on changed files, they may need to be updated often when
|
||||||
dartfmt is changing rapidly.
|
dartfmt is changing rapidly.
|
||||||
|
|
||||||
|
|
|
@ -722,16 +722,10 @@ class PrecompilerCompilerConfiguration extends CompilerConfiguration {
|
||||||
break;
|
break;
|
||||||
case Architecture.ia32:
|
case Architecture.ia32:
|
||||||
case Architecture.simarm:
|
case Architecture.simarm:
|
||||||
case Architecture.simmips:
|
|
||||||
ccFlags = "-m32";
|
|
||||||
break;
|
|
||||||
case Architecture.arm:
|
case Architecture.arm:
|
||||||
case Architecture.arm64:
|
case Architecture.arm64:
|
||||||
ccFlags = null;
|
ccFlags = null;
|
||||||
break;
|
break;
|
||||||
case Architecture.mips:
|
|
||||||
ccFlags = "-EL";
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
throw "Architecture not supported: ${arch.name}";
|
throw "Architecture not supported: ${arch.name}";
|
||||||
}
|
}
|
||||||
|
|
|
@ -443,8 +443,6 @@ class Architecture {
|
||||||
static const simarmv6 = const Architecture._('simarmv6');
|
static const simarmv6 = const Architecture._('simarmv6');
|
||||||
static const simarmv5te = const Architecture._('simarmv5te');
|
static const simarmv5te = const Architecture._('simarmv5te');
|
||||||
static const simarm64 = const Architecture._('simarm64');
|
static const simarm64 = const Architecture._('simarm64');
|
||||||
static const mips = const Architecture._('mips');
|
|
||||||
static const simmips = const Architecture._('simmips');
|
|
||||||
static const simdbc = const Architecture._('simdbc');
|
static const simdbc = const Architecture._('simdbc');
|
||||||
static const simdbc64 = const Architecture._('simdbc64');
|
static const simdbc64 = const Architecture._('simdbc64');
|
||||||
|
|
||||||
|
@ -461,8 +459,6 @@ class Architecture {
|
||||||
simarmv6,
|
simarmv6,
|
||||||
simarmv5te,
|
simarmv5te,
|
||||||
simarm64,
|
simarm64,
|
||||||
mips,
|
|
||||||
simmips,
|
|
||||||
simdbc,
|
simdbc,
|
||||||
simdbc64
|
simdbc64
|
||||||
], key: (Architecture architecture) => architecture.name);
|
], key: (Architecture architecture) => architecture.name);
|
||||||
|
|
|
@ -163,7 +163,6 @@ all
|
||||||
ia32, x64
|
ia32, x64
|
||||||
arm, armv6, armv5te, arm64,
|
arm, armv6, armv5te, arm64,
|
||||||
simarm, simarmv6, simarmv5te, simarm64,
|
simarm, simarmv6, simarmv5te, simarm64,
|
||||||
mips, simmips
|
|
||||||
simdbc, simdbc64''',
|
simdbc, simdbc64''',
|
||||||
abbr: 'a',
|
abbr: 'a',
|
||||||
values: ['all']..addAll(Architecture.names),
|
values: ['all']..addAll(Architecture.names),
|
||||||
|
|
|
@ -181,8 +181,6 @@ class DartVmRuntimeConfiguration extends RuntimeConfiguration {
|
||||||
case Architecture.armv6:
|
case Architecture.armv6:
|
||||||
case Architecture.simarmv5te:
|
case Architecture.simarmv5te:
|
||||||
case Architecture.armv5te:
|
case Architecture.armv5te:
|
||||||
case Architecture.simmips:
|
|
||||||
case Architecture.mips:
|
|
||||||
case Architecture.simarm64:
|
case Architecture.simarm64:
|
||||||
case Architecture.simdbc:
|
case Architecture.simdbc:
|
||||||
case Architecture.simdbc64:
|
case Architecture.simdbc64:
|
||||||
|
|
|
@ -16,7 +16,7 @@ final _combinations = {
|
||||||
{
|
{
|
||||||
'runtimes': ['vm'],
|
'runtimes': ['vm'],
|
||||||
'modes': ['debug', 'release'],
|
'modes': ['debug', 'release'],
|
||||||
'archs': ['ia32', 'x64', 'simarm', 'simmips'],
|
'archs': ['ia32', 'x64', 'simarm'],
|
||||||
'compiler': 'none'
|
'compiler': 'none'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -76,8 +76,6 @@ def GuessArchitecture():
|
||||||
return 'arm'
|
return 'arm'
|
||||||
elif os_id.startswith('aarch64'):
|
elif os_id.startswith('aarch64'):
|
||||||
return 'arm64'
|
return 'arm64'
|
||||||
elif os_id.startswith('mips'):
|
|
||||||
return 'mips'
|
|
||||||
elif '64' in os_id:
|
elif '64' in os_id:
|
||||||
return 'x64'
|
return 'x64'
|
||||||
elif (not os_id) or (not re.match('(x|i[3-6])86', os_id) is None):
|
elif (not os_id) or (not re.match('(x|i[3-6])86', os_id) is None):
|
||||||
|
@ -252,11 +250,9 @@ ARCH_FAMILY = {
|
||||||
'armv6': 'arm',
|
'armv6': 'arm',
|
||||||
'armv5te': 'arm',
|
'armv5te': 'arm',
|
||||||
'arm64': 'arm',
|
'arm64': 'arm',
|
||||||
'mips': 'mips',
|
|
||||||
'simarm': 'ia32',
|
'simarm': 'ia32',
|
||||||
'simarmv6': 'ia32',
|
'simarmv6': 'ia32',
|
||||||
'simarmv5te': 'ia32',
|
'simarmv5te': 'ia32',
|
||||||
'simmips': 'ia32',
|
|
||||||
'simarm64': 'ia32',
|
'simarm64': 'ia32',
|
||||||
'simdbc': 'ia32',
|
'simdbc': 'ia32',
|
||||||
'simdbc64': 'ia32',
|
'simdbc64': 'ia32',
|
||||||
|
@ -620,9 +616,7 @@ def CheckedInSdkExecutable():
|
||||||
name = 'dart.exe'
|
name = 'dart.exe'
|
||||||
elif GuessOS() == 'linux':
|
elif GuessOS() == 'linux':
|
||||||
arch = GuessArchitecture()
|
arch = GuessArchitecture()
|
||||||
if arch == 'mips':
|
if arch == 'arm':
|
||||||
name = 'dart-mips'
|
|
||||||
elif arch == 'arm':
|
|
||||||
name = 'dart-arm'
|
name = 'dart-arm'
|
||||||
elif arch == 'arm64':
|
elif arch == 'arm64':
|
||||||
name = 'dart-arm64'
|
name = 'dart-arm64'
|
||||||
|
|
|
@ -13,9 +13,3 @@
|
||||||
|
|
||||||
[ $arch == simarm64 ]
|
[ $arch == simarm64 ]
|
||||||
*: Skip
|
*: Skip
|
||||||
|
|
||||||
[ $arch == mips ]
|
|
||||||
*: Skip
|
|
||||||
|
|
||||||
[ $arch == simmips ]
|
|
||||||
*: Skip
|
|
||||||
|
|
Loading…
Reference in a new issue