[vm/compiler] Instroduce SIMARM_X64 build architecture.

This is variant of SIMARM build (ARM target and non-ARM host) but with a
word size mismatch (32-bit target and 64-bit host). We only expect to
build gen_snapshot binary in this mode.

This is the first step towards enabling AOT compilation targeting ARM
using 64-bit gen_snapshot binary.

This change also introduces --gen-snapshot flag for test.py which allows
to specify which gen_snapshot binary should be used for running tests.

Expected workflow with SIMARM_X64 build:

$ tools/build.py -a simarm_x64 -m release gen_snapshot
$ tools/build.py -a simarm -m release dart_precompiled_runtime
vm_platform
$ tools/test.py -a simarm -m release -c dartkp --gen-snapshot
out/ReleaseSIMARM_X64/gen_snapshot

Note that our ARM simulator can't be built as a 64-binary so we are
going to be using SIMARM runtime to test AOT compiled code produced by
SIMARM_X64 binary.

Issue https://github.com/dart-lang/sdk/issues/36839
Issue https://github.com/flutter/flutter/issues/22598

Change-Id: Id003900e8b46fc9d57975ab82b0c21852a176079
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/100968
Commit-Queue: Vyacheslav Egorov <vegorov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
diff --git a/tools/build.py b/tools/build.py
index fa05e23..1782f2b 100755
--- a/tools/build.py
+++ b/tools/build.py
@@ -18,7 +18,7 @@
 DART_ROOT = os.path.realpath(os.path.join(SCRIPT_DIR, '..'))
 AVAILABLE_ARCHS = ['ia32', 'x64', 'simarm', 'arm', 'simarmv6', 'armv6',
     'simarmv5te', 'armv5te', 'simarm64', 'arm64',
-    'simdbc', 'simdbc64', 'armsimdbc', 'armsimdbc64']
+    'simdbc', 'simdbc64', 'armsimdbc', 'armsimdbc64', 'simarm_x64']
 
 
 usage = """\
diff --git a/tools/gn.py b/tools/gn.py
index 2bf358f..18725d2 100755
--- a/tools/gn.py
+++ b/tools/gn.py
@@ -82,7 +82,7 @@
 def HostCpuForArch(arch):
   if arch in ['ia32', 'arm', 'armv6', 'armv5te',
               'simarm', 'simarmv6', 'simarmv5te', 'simdbc',
-              'armsimdbc']:
+              'armsimdbc', 'simarm_x64']:
     return 'x86'
   if arch in ['x64', 'arm64', 'simarm64', 'simdbc64', 'armsimdbc64']:
     return 'x64'
@@ -92,7 +92,7 @@
 def TargetCpuForArch(arch, target_os):
   if arch in ['ia32', 'simarm', 'simarmv6', 'simarmv5te']:
     return 'x86'
-  if arch in ['x64', 'simarm64']:
+  if arch in ['x64', 'simarm64', 'simarm_x64']:
     return 'x64'
   if arch == 'simdbc':
     return 'arm' if target_os == 'android' else 'x86'
@@ -111,7 +111,7 @@
     return 'ia32'
   if arch in ['x64']:
     return 'x64'
-  if arch in ['arm', 'simarm']:
+  if arch in ['arm', 'simarm', 'simarm_x64']:
     return 'arm'
   if arch in ['armv6', 'simarmv6']:
     return 'armv6'
@@ -306,7 +306,7 @@
   for arch in args.arch:
     archs = ['ia32', 'x64', 'simarm', 'arm', 'simarmv6', 'armv6',
              'simarmv5te', 'armv5te', 'simarm64', 'arm64',
-             'simdbc', 'simdbc64', 'armsimdbc', 'armsimdbc64']
+             'simdbc', 'simdbc64', 'armsimdbc', 'armsimdbc64','simarm_x64']
     if not arch in archs:
       print ("Unknown arch %s" % arch)
       return False
@@ -359,7 +359,7 @@
       type=str,
       help='Target architectures (comma-separated).',
       metavar='[all,ia32,x64,simarm,arm,simarmv6,armv6,simarmv5te,armv5te,'
-              'simarm64,arm64,simdbc,armsimdbc]',
+              'simarm64,arm64,simdbc,armsimdbc,simarm_x64]',
       default='x64')
   common_group.add_argument('--mode', '-m',
       type=str,
diff --git a/tools/testing/dart/compiler_configuration.dart b/tools/testing/dart/compiler_configuration.dart
index 9edb9fb..f3fee45 100644
--- a/tools/testing/dart/compiler_configuration.dart
+++ b/tools/testing/dart/compiler_configuration.dart
@@ -712,15 +712,17 @@
   Command computeDartBootstrapCommand(String tempDir, List<String> arguments,
       Map<String, String> environmentOverrides) {
     var buildDir = _configuration.buildDirectory;
-    String exec;
-    if (_isAndroid) {
-      if (_isArm) {
-        exec = "$buildDir/clang_x86/gen_snapshot";
-      } else if (_configuration.architecture == Architecture.arm64) {
-        exec = "$buildDir/clang_x64/gen_snapshot";
+    String exec = _configuration.genSnapshotPath;
+    if (exec == null) {
+      if (_isAndroid) {
+        if (_isArm) {
+          exec = "$buildDir/clang_x86/gen_snapshot";
+        } else if (_configuration.architecture == Architecture.arm64) {
+          exec = "$buildDir/clang_x64/gen_snapshot";
+        }
+      } else {
+        exec = "$buildDir/gen_snapshot";
       }
-    } else {
-      exec = "$buildDir/gen_snapshot";
     }
 
     final args = <String>[];
diff --git a/tools/testing/dart/configuration.dart b/tools/testing/dart/configuration.dart
index 85a0433..fac39a9 100644
--- a/tools/testing/dart/configuration.dart
+++ b/tools/testing/dart/configuration.dart
@@ -50,6 +50,7 @@
       this.firefoxPath,
       this.dartPath,
       this.dartPrecompiledPath,
+      this.genSnapshotPath,
       this.taskCount,
       this.shardCount,
       this.shard,
@@ -125,6 +126,7 @@
   final String firefoxPath;
   final String dartPath;
   final String dartPrecompiledPath;
+  final String genSnapshotPath;
   final List<String> testList;
 
   final int taskCount;
diff --git a/tools/testing/dart/options.dart b/tools/testing/dart/options.dart
index 67f5b27..bf979ac 100644
--- a/tools/testing/dart/options.dart
+++ b/tools/testing/dart/options.dart
@@ -229,6 +229,7 @@
         hide: true),
     new _Option.bool('time', 'Print timing information after running tests.'),
     new _Option('dart', 'Path to dart executable.', hide: true),
+    new _Option('gen-snapshot', 'Path to gen_snapshot executable.', hide: true),
     new _Option('firefox', 'Path to firefox browser executable.', hide: true),
     new _Option('chrome', 'Path to chrome browser executable.', hide: true),
     new _Option('safari', 'Path to safari browser executable.', hide: true),
@@ -727,6 +728,7 @@
                 firefoxPath: data["firefox"] as String,
                 dartPath: data["dart"] as String,
                 dartPrecompiledPath: data["dart_precompiled"] as String,
+                genSnapshotPath: data["gen-snapshot"] as String,
                 keepGeneratedFiles: data["keep_generated_files"] as bool,
                 taskCount: data["tasks"] as int,
                 shardCount: data["shards"] as int,
diff --git a/tools/utils.py b/tools/utils.py
index 6582cb0..7b69465 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -270,6 +270,7 @@
   'simdbc64': 'ia32',
   'armsimdbc': 'arm',
   'armsimdbc64': 'arm',
+  'simarm_x64': 'ia32',
 }
 
 ARCH_GUESS = GuessArchitecture()