DBC: Adds simdbc64 target, adds arm64 arithmetic overflow logic

There were differences between linux gcc, android gcc,
MacOS clang, and 32 vs. 64-bit w.r.t the __builtin
functions for detecting arithmetic overflow. I couldn't get
them all working at the same time. Instead, I removed them,
and changed to always use the inline assembly. This works
in all the configurations above.

This change also adds a simdbc64 target for building simdbc
for 64-bit, and sets up the android targets. simdbc targets
arm, and simdbc64 targets arm64. You can build them with:

$ ./tools/build.py -m release -a simdbc{64} --os=android runtime

R=iposva@google.com

Review URL: https://codereview.chromium.org/1904153003 .
This commit is contained in:
Zachary Anderson 2016-04-25 12:48:34 -07:00
parent 5542568adc
commit 3d7202bad3
19 changed files with 156 additions and 69 deletions

View file

@ -44,7 +44,7 @@ coverage_test: Pass, Slow
[ $compiler == dart2analyzer ]
evaluate_activation_in_method_class_test: CompileTimeError # Issue 24478
[ $arch == simdbc ]
[ $arch == simdbc || $arch == simdbc64 ]
# TODO(vegorov) re-enable when debugger, coverage and profiling is completely
# fixed for SIMDBC.
*: Skip

View file

@ -33,7 +33,7 @@ cc/Service_Profile: Skip
cc/Dart2JSCompilerStats: Skip
cc/CorelibCompilerStats: Skip
[ $arch == simarm || $arch == simarmv6 || $arch == simarmv5te || $arch == simarm64 || $arch == simmips || $arch == simdbc ]
[ $arch == simarm || $arch == simarmv6 || $arch == simarmv5te || $arch == simarm64 || $arch == simmips || $arch == simdbc || $arch == simdbc64 ]
cc/Service_Profile: Skip
[ $compiler == dart2js ]
@ -98,7 +98,7 @@ cc/IsolateSetCheckedMode: Fail,OK # Expects exact type name.
cc/LibraryGetClassNames: Fail,OK # Expects exact type name.
cc/StackTraceFormat: Fail,OK # Expects exact type name.
[ $arch == simdbc ]
[ $arch == simdbc || $arch == simdbc64 ]
# TODO(vegorov) Profiler is completely disabled in SIMDBC builds.
cc/Profiler_AllocationSampleTest: Skip
cc/Profiler_ArrayAllocation: Skip

View file

@ -106,11 +106,13 @@ DART_FORCE_INLINE static RawObject** FrameArguments(RawObject** FP,
class SimulatorHelpers {
public:
DART_FORCE_INLINE static RawSmi* GetClassIdAsSmi(RawObject* obj) {
return Smi::New(obj->IsHeapObject() ? obj->GetClassId() : kSmiCid);
return Smi::New(obj->IsHeapObject() ? obj->GetClassId()
: static_cast<intptr_t>(kSmiCid));
}
DART_FORCE_INLINE static intptr_t GetClassId(RawObject* obj) {
return obj->IsHeapObject() ? obj->GetClassId() : kSmiCid;
return obj->IsHeapObject() ? obj->GetClassId()
: static_cast<intptr_t>(kSmiCid);
}
DART_FORCE_INLINE static void IncrementUsageCounter(RawICData* icdata) {
@ -312,10 +314,10 @@ uword Simulator::StackTop() const {
typedef void (*SimulatorRuntimeCall)(NativeArguments arguments);
// Calls to leaf Dart runtime functions are based on this interface.
typedef int32_t (*SimulatorLeafRuntimeCall)(int32_t r0,
int32_t r1,
int32_t r2,
int32_t r3);
typedef intptr_t (*SimulatorLeafRuntimeCall)(intptr_t r0,
intptr_t r1,
intptr_t r2,
intptr_t r3);
// Calls to leaf float Dart runtime functions are based on this interface.
typedef double (*SimulatorLeafFloatRuntimeCall)(double d0, double d1);
@ -337,28 +339,15 @@ void Simulator::Exit(Thread* thread,
thread->set_top_exit_frame_info(reinterpret_cast<uword>(sp_));
}
#if defined(__has_builtin)
#if __has_builtin(__builtin_smul_overflow)
#define HAS_MUL_OVERFLOW
#endif
#if __has_builtin(__builtin_sadd_overflow)
#define HAS_ADD_OVERFLOW
#endif
#if __has_builtin(__builtin_ssub_overflow)
#define HAS_SUB_OVERFLOW
#endif
#endif
DART_FORCE_INLINE static bool SignedAddWithOverflow(int32_t lhs,
int32_t rhs,
// TODO(vegorov): Investigate advantages of using
// __builtin_s{add,sub,mul}_overflow() intrinsics here and below.
// Note that they may clobber the output location even when there is overflow:
// https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
DART_FORCE_INLINE static bool SignedAddWithOverflow(intptr_t lhs,
intptr_t rhs,
intptr_t* out) {
int32_t res = 1;
#if defined(HAS_ADD_OVERFLOW)
res = static_cast<int32_t>(__builtin_sadd_overflow(
lhs, rhs, reinterpret_cast<int32_t*>(out)));
#elif defined(__i386__)
intptr_t res = 1;
#if defined(HOST_ARCH_IA32) || defined(HOST_ARCH_X64)
asm volatile(
"add %2, %1\n"
"jo 1f;\n"
@ -368,16 +357,16 @@ DART_FORCE_INLINE static bool SignedAddWithOverflow(int32_t lhs,
: "+r"(res), "+r"(lhs)
: "r"(rhs), "r"(out)
: "cc");
#elif defined(__arm__)
#elif defined(HOST_ARCH_ARM) || defined(HOST_ARCH_ARM64)
asm volatile(
"adds %1, %1, %2;\n"
"bvs 1f;\n"
"mov %0, $0;\n"
"mov %0, #0;\n"
"str %1, [%3, #0]\n"
"1:"
: "+r"(res), "+r"(lhs)
: "r"(rhs), "r"(out)
: "cc", "r12");
: "cc");
#else
#error "Unsupported platform"
#endif
@ -385,14 +374,11 @@ DART_FORCE_INLINE static bool SignedAddWithOverflow(int32_t lhs,
}
DART_FORCE_INLINE static bool SignedSubWithOverflow(int32_t lhs,
int32_t rhs,
DART_FORCE_INLINE static bool SignedSubWithOverflow(intptr_t lhs,
intptr_t rhs,
intptr_t* out) {
int32_t res = 1;
#if defined(HAS_SUB_OVERFLOW)
res = static_cast<int32_t>(__builtin_ssub_overflow(
lhs, rhs, reinterpret_cast<int32_t*>(out)));
#elif defined(__i386__)
intptr_t res = 1;
#if defined(HOST_ARCH_IA32) || defined(HOST_ARCH_X64)
asm volatile(
"sub %2, %1\n"
"jo 1f;\n"
@ -402,16 +388,16 @@ DART_FORCE_INLINE static bool SignedSubWithOverflow(int32_t lhs,
: "+r"(res), "+r"(lhs)
: "r"(rhs), "r"(out)
: "cc");
#elif defined(__arm__)
#elif defined(HOST_ARCH_ARM) || defined(HOST_ARCH_ARM64)
asm volatile(
"subs %1, %1, %2;\n"
"bvs 1f;\n"
"mov %0, $0;\n"
"mov %0, #0;\n"
"str %1, [%3, #0]\n"
"1:"
: "+r"(res), "+r"(lhs)
: "r"(rhs), "r"(out)
: "cc", "r12");
: "cc");
#else
#error "Unsupported platform"
#endif
@ -419,14 +405,11 @@ DART_FORCE_INLINE static bool SignedSubWithOverflow(int32_t lhs,
}
DART_FORCE_INLINE static bool SignedMulWithOverflow(int32_t lhs,
int32_t rhs,
DART_FORCE_INLINE static bool SignedMulWithOverflow(intptr_t lhs,
intptr_t rhs,
intptr_t* out) {
int32_t res = 1;
#if defined(HAS_MUL_OVERFLOW)
res = static_cast<int32_t>(__builtin_smul_overflow(
lhs, rhs, reinterpret_cast<int32_t*>(out)));
#elif defined(__i386__)
intptr_t res = 1;
#if defined(HOST_ARCH_IA32) || defined(HOST_ARCH_X64)
asm volatile(
"imul %2, %1\n"
"jo 1f;\n"
@ -436,7 +419,7 @@ DART_FORCE_INLINE static bool SignedMulWithOverflow(int32_t lhs,
: "+r"(res), "+r"(lhs)
: "r"(rhs), "r"(out)
: "cc");
#elif defined(__arm__)
#elif defined(HOST_ARCH_ARM)
asm volatile(
"smull %1, ip, %1, %2;\n"
"cmp ip, %1, ASR #31;\n"
@ -447,6 +430,19 @@ DART_FORCE_INLINE static bool SignedMulWithOverflow(int32_t lhs,
: "+r"(res), "+r"(lhs)
: "r"(rhs), "r"(out)
: "cc", "r12");
#elif defined(HOST_ARCH_ARM64)
int64_t prod_lo;
asm volatile(
"mul %1, %2, %3\n"
"smulh %2, %2, %3\n"
"cmp %2, %1, ASR #63;\n"
"bne 1f;\n"
"mov %0, #0;\n"
"str %1, [%4, #0]\n"
"1:"
: "+r"(res), "=r"(prod_lo), "+r"(lhs)
: "r"(rhs), "r"(out)
: "cc");
#else
#error "Unsupported platform"
#endif

View file

@ -37,7 +37,7 @@ typedef bool (*IntrinsicHandler)(Thread* thread,
class Simulator {
public:
static const uword kSimulatorStackUnderflowSize = 64;
static const uword kSimulatorStackUnderflowSize = 0x80;
Simulator();
~Simulator();

View file

@ -164,7 +164,7 @@ LibTest/typed_data/Uint64List/runtimeType_A01_t01: Fail,OK # Expects exact type
LibTest/typed_data/Uint8ClampedList/runtimeType_A01_t01: Fail,OK # Expects exact type name.
LibTest/typed_data/Uint8List/runtimeType_A01_t01: Fail,OK # Expects exact type name.
[ $arch == simdbc && $mode == debug ]
[ ($arch == simdbc || $arch == simdbc64) && $mode == debug ]
# TODO(vegorov) These tests are very slow on unoptimized SIMDBC
LibTest/collection/ListMixin/ListMixin_class_A01_t02: Timeout
LibTest/collection/ListBase/ListBase_class_A01_t02: Timeout

View file

@ -209,5 +209,5 @@ package_resource_test: Skip # Resolve URI not supported yet in product mode.
file_resource_test: Skip # Resolve URI not supported yet in product mode.
http_resource_test: Skip # Resolve URI not supported yet in product mode.
[ $arch == simdbc ]
[ $arch == simdbc || $arch == simdbc64 ]
regexp/stack-overflow_test: RuntimeError, OK # Smaller limit with irregex interpreter

View file

@ -212,7 +212,7 @@ library_env_test/has_no_mirror_support: RuntimeError, OK
# The following tests are supposed to fail.
library_env_test/has_mirror_support: RuntimeError, OK
[ $arch == simdbc ]
[ $arch == simdbc || $arch == simdbc64 ]
# TODO(vegorov) StopInstr is unimplemented.
vm/debug_break_enabled_vm_test/none: Skip

View file

@ -363,7 +363,7 @@ mirrors/*: SkipByDesign
convert/chunked_conversion_utf88_test: Pass, Timeout
convert/utf85_test: Pass, Timeout
[ $arch == simdbc ]
[ $arch == simdbc || $arch == simdbc64 ]
# TODO(vegorov) LoadField bytecode supports only up to 256 fields. Need a long
# version.
mirrors/accessor_cache_overflow_test: Skip

View file

@ -286,7 +286,7 @@ package/scenarios/empty_packages_file/empty_packages_file_noimports_test: Skip
package/scenarios/packages_option_only/packages_option_only_noimports_test: Skip
package/scenarios/packages_option_only/packages_option_only_test: Skip
[ $arch == simdbc ]
[ $arch == simdbc || $arch == simdbc64 ]
# TODO(vegorov) SIMDBC interpreter doesn't support coverage yet.
full_coverage_test: Skip

View file

@ -87,6 +87,13 @@
'OPENSSL_NO_ASM',
],
},
# Android 64-bit dbc build is for arm64, disable temporarily as well.
'Dart_Android_arm64_Base': {
'abstract': 1,
'defines': [
'OPENSSL_NO_ASM',
],
},
# When being built for Android nss expects __linux__ to be defined.
'Dart_Android_Base': {
'target_conditions': [

View file

@ -48,9 +48,10 @@ def main():
link_args = sys.argv[4:]
# Check arguments.
if target_arch not in ['arm', 'arm64', 'ia32', 'x64']:
if target_arch not in ['arm', 'arm64', 'ia32', 'x64', 'simdbc', 'simdbc64']:
raise Exception(sys.argv[0] +
" first argument must be 'arm', 'arm64', 'ia32', or 'x64'")
" first argument must be 'arm', 'arm64', 'ia32', 'x64', "
"'simdbc', or 'simdbc64'")
if link_type not in ['executable', 'library', 'shared_library']:
raise Exception(sys.argv[0] +
" second argument must be 'executable' or 'library'")
@ -77,7 +78,7 @@ def main():
# Set up the directory of the Android NDK cross-compiler toolchain.
toolchain_arch = 'arm-linux-androideabi-4.9'
if target_arch == 'arm64':
if target_arch == 'arm64' or target_arch == "simdbc64":
toolchain_arch = 'aarch64-linux-android-4.9'
if target_arch == 'ia32':
toolchain_arch = 'x86-4.9'
@ -91,7 +92,7 @@ def main():
# Set up the path to the linker executable.
android_linker = os.path.join(android_toolchain, 'arm-linux-androideabi-g++')
if target_arch == 'arm64':
if target_arch == 'arm64' or target_arch == "simdbc64":
android_linker = os.path.join(
android_toolchain, 'aarch64-linux-android-c++')
if target_arch == 'ia32':
@ -102,7 +103,7 @@ def main():
# Grab the path to libgcc.a, which we must explicitly add to the link,
# by invoking the cross-compiler with the -print-libgcc-file-name flag.
android_gcc = os.path.join(android_toolchain, 'arm-linux-androideabi-gcc')
if target_arch == 'arm64':
if target_arch == 'arm64' or target_arch == "simdbc64":
android_gcc = os.path.join(android_toolchain, 'aarch64-linux-android-gcc')
if target_arch == 'ia32':
android_gcc = os.path.join(android_toolchain, 'i686-linux-android-gcc')
@ -116,7 +117,7 @@ def main():
android_ndk_sysroot = os.path.join(android_ndk_root,
'platforms', 'android-14', 'arch-arm')
libdir = 'lib'
if target_arch == 'arm64':
if target_arch == 'arm64' or target_arch == "simdbc64":
android_ndk_sysroot = os.path.join(android_ndk_root,
'platforms', 'android-21', 'arch-arm64')
if target_arch == 'ia32':

View file

@ -103,7 +103,7 @@ def ProcessOptions(options, args):
for arch in options.arch:
archs = ['ia32', 'x64', 'simarm', 'arm', 'simarmv6', 'armv6',
'simarmv5te', 'armv5te', 'simmips', 'mips', 'simarm64', 'arm64',
'simdbc',]
'simdbc', 'simdbc64']
if not arch in archs:
print "Unknown arch %s" % arch
return False
@ -121,7 +121,7 @@ def ProcessOptions(options, args):
% (os_name, HOST_OS))
return False
if not arch in ['ia32', 'x64', 'arm', 'armv6', 'armv5te', 'arm64', 'mips',
'simdbc',]:
'simdbc', 'simdbc64']:
print ("Cross-compilation to %s is not supported for architecture %s."
% (os_name, arch))
return False
@ -141,7 +141,7 @@ def GetToolchainPrefix(target_os, arch, options):
android_toolchain = GetAndroidToolchainDir(HOST_OS, arch)
if arch == 'arm' or arch == 'simdbc':
return os.path.join(android_toolchain, 'arm-linux-androideabi')
if arch == 'arm64':
if arch == 'arm64' or arch == 'simdbc64':
return os.path.join(android_toolchain, 'aarch64-linux-android')
if arch == 'ia32':
return os.path.join(android_toolchain, 'i686-linux-android')
@ -199,7 +199,7 @@ def GetAndroidToolchainDir(host_os, target_arch):
global THIRD_PARTY_ROOT
if host_os not in ['linux']:
raise Exception('Unsupported host os %s' % host_os)
if target_arch not in ['ia32', 'x64', 'arm', 'arm64', 'simdbc']:
if target_arch not in ['ia32', 'x64', 'arm', 'arm64', 'simdbc', 'simdbc64']:
raise Exception('Unsupported target architecture %s' % target_arch)
# Set up path to the Android NDK.
@ -211,7 +211,7 @@ def GetAndroidToolchainDir(host_os, target_arch):
# Set up the directory of the Android NDK cross-compiler toolchain.
toolchain_arch = 'arm-linux-androideabi-4.9'
if target_arch == 'arm64':
if target_arch == 'arm64' or target_arch == 'simdbc64':
toolchain_arch = 'aarch64-linux-android-4.9'
if target_arch == 'ia32':
toolchain_arch = 'x86-4.9'

View file

@ -27,6 +27,7 @@
['"<(target_arch)"=="mips"', { 'dart_target_arch': 'MIPS', }],
['"<(target_arch)"=="simmips"', { 'dart_target_arch': 'SIMMIPS', }],
['"<(target_arch)"=="simdbc"', { 'dart_target_arch': 'SIMDBC', }],
['"<(target_arch)"=="simdbc64"', { 'dart_target_arch': 'SIMDBC64', }],
[ 'OS=="linux"', { 'dart_target_os': 'Linux', } ],
[ 'OS=="mac"', { 'dart_target_os': 'Macos', } ],
[ 'OS=="win"', { 'dart_target_os': 'Win', } ],
@ -386,6 +387,27 @@
],
},
'DebugSIMDBC64': {
'inherit_from': [
'Dart_Base', 'Dart_simdbc_Base', 'Dart_Debug',
'Dart_<(dart_target_os)_Base',
'Dart_<(dart_target_os)_simdbc64_Base',
'Dart_<(dart_target_os)_Debug',
],
'defines': [
'DEBUG',
],
},
'ReleaseSIMDBC64': {
'inherit_from': [
'Dart_Base', 'Dart_simdbc_Base', 'Dart_Release',
'Dart_<(dart_target_os)_Base',
'Dart_<(dart_target_os)_simdbc64_Base',
'Dart_<(dart_target_os)_Release',
],
},
# ARM and MIPS hardware configurations are only for Linux and Android.
'DebugXARM': {
'inherit_from': [
@ -770,6 +792,52 @@
],
},
'DebugAndroidSIMDBC': {
'inherit_from': [
'Dart_Base', 'Dart_simdbc_Base', 'Dart_Debug',
'Dart_Android_Base',
# Default SIMDBC on Android targets arm.
'Dart_Android_arm_Base',
'Dart_Android_Debug',
],
'defines': [
'DEBUG',
],
},
'ReleaseAndroidSIMDBC': {
'inherit_from': [
'Dart_Base', 'Dart_simdbc_Base', 'Dart_Release',
'Dart_Android_Base',
# Default SIMDBC on Android targets arm.
'Dart_Android_arm_Base',
'Dart_Android_Release',
],
},
'DebugAndroidSIMDBC64': {
'inherit_from': [
'Dart_Base', 'Dart_simdbc_Base', 'Dart_Debug',
'Dart_Android_Base',
# Default SIMDBC on Android targets arm64.
'Dart_Android_arm64_Base',
'Dart_Android_Debug',
],
'defines': [
'DEBUG',
],
},
'ReleaseAndroidSIMDBC64': {
'inherit_from': [
'Dart_Base', 'Dart_simdbc_Base', 'Dart_Release',
'Dart_Android_Base',
# Default SIMDBC on Android targets arm64.
'Dart_Android_arm64_Base',
'Dart_Android_Release',
],
},
# These targets assume that target_arch is passed in explicitly
# by the containing project (e.g., chromium).
'Debug': {

View file

@ -119,6 +119,12 @@
'ldflags': [ '-m32', ],
},
'Dart_Linux_simdbc64_Base': {
'abstract': 1,
'cflags': [ '-O3', '-m64', '-msse2', '-mfpmath=sse' ],
'ldflags': [ '-m64', ],
},
# ARM cross-build
'Dart_Linux_xarm_Base': {
'abstract': 1,

View file

@ -39,6 +39,9 @@
'Dart_Win_simdbc_Base': {
'abstract': 1,
},
'Dart_Win_simdbc64_Base': {
'abstract': 1,
},
'Dart_Win_Debug': {
'abstract': 1,
'msvs_settings': {

View file

@ -80,6 +80,9 @@
'Dart_Macos_simdbc_Base': {
'abstract': 1,
},
'Dart_Macos_simdbc64_Base': {
'abstract': 1,
},
'Dart_Macos_Debug': {
'abstract': 1,
'xcode_settings': {

View file

@ -172,6 +172,7 @@ class DartVmRuntimeConfiguration extends RuntimeConfiguration {
case 'mips':
case 'simarm64':
case 'simdbc':
case 'simdbc64':
multiplier *= 4;
break;
}

View file

@ -149,7 +149,8 @@ class TestOptionsParser {
'simarmv5te',
'simarm64',
'simmips',
'simdbc'
'simdbc',
'simdbc64',
],
'x64'),
new _TestOptionSpecification(

View file

@ -241,6 +241,7 @@ ARCH_FAMILY = {
'simmips': 'ia32',
'simarm64': 'ia32',
'simdbc': 'ia32',
'simdbc64': 'ia32',
}
ARCH_GUESS = GuessArchitecture()