[vm] Add a stub simx64.

This allows building gen_snapshot with host=arm64, target=x64.

TEST=ci
Bug: https://github.com/flutter/flutter/issues/103386
Change-Id: I478cc0917462896de9b598455d2ed68401323b50
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/252962
Reviewed-by: Alexander Aprelev <aam@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
diff --git a/pkg/smith/lib/configuration.dart b/pkg/smith/lib/configuration.dart
index f5a7d94..07a7618 100644
--- a/pkg/smith/lib/configuration.dart
+++ b/pkg/smith/lib/configuration.dart
@@ -578,6 +578,8 @@
   static const ia32 = Architecture._('ia32');
   static const x64 = Architecture._('x64');
   static const x64c = Architecture._('x64c');
+  static const simx64 = Architecture._('simx64');
+  static const simx64c = Architecture._('simx64c');
   static const arm = Architecture._('arm');
   // ignore: constant_identifier_names
   static const arm_x64 = Architecture._('arm_x64');
@@ -597,6 +599,8 @@
     ia32,
     x64,
     x64c,
+    simx64,
+    simx64c,
     arm,
     arm_x64,
     arm64,
diff --git a/pkg/test_runner/lib/src/compiler_configuration.dart b/pkg/test_runner/lib/src/compiler_configuration.dart
index 190e81d..1b6e70b 100644
--- a/pkg/test_runner/lib/src/compiler_configuration.dart
+++ b/pkg/test_runner/lib/src/compiler_configuration.dart
@@ -1005,6 +1005,8 @@
     switch (_configuration.architecture) {
       case Architecture.x64:
       case Architecture.x64c:
+      case Architecture.simx64:
+      case Architecture.simx64c:
         ccFlags = "-m64";
         break;
       case Architecture.simarm64:
diff --git a/runtime/vm/cpu_x64.cc b/runtime/vm/cpu_x64.cc
index cf0acf3..bd78c504 100644
--- a/runtime/vm/cpu_x64.cc
+++ b/runtime/vm/cpu_x64.cc
@@ -40,6 +40,7 @@
 bool HostCPUFeatures::initialized_ = false;
 #endif
 
+#if !defined(USING_SIMULATOR)
 void HostCPUFeatures::Init() {
   CpuInfo::Init();
   hardware_ = CpuInfo::GetCpuModel();
@@ -63,6 +64,31 @@
   CpuInfo::Cleanup();
 }
 
+#else  // !defined(USING_SIMULATOR)
+
+void HostCPUFeatures::Init() {
+  CpuInfo::Init();
+  hardware_ = CpuInfo::GetCpuModel();
+  sse4_1_supported_ = false;
+  popcnt_supported_ = false;
+  abm_supported_ = false;
+#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(USING_SIMULATOR)
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_X64
diff --git a/runtime/vm/simulator.h b/runtime/vm/simulator.h
index 7738d0c..659bc8b 100644
--- a/runtime/vm/simulator.h
+++ b/runtime/vm/simulator.h
@@ -8,8 +8,10 @@
 #include "vm/globals.h"
 
 #if defined(USING_SIMULATOR)
-#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
+#if defined(TARGET_ARCH_IA32)
 #error Simulator not implemented.
+#elif defined(TARGET_ARCH_X64)
+#include "vm/simulator_x64.h"
 #elif defined(TARGET_ARCH_ARM)
 #include "vm/simulator_arm.h"
 #elif defined(TARGET_ARCH_ARM64)
diff --git a/runtime/vm/simulator_x64.cc b/runtime/vm/simulator_x64.cc
new file mode 100644
index 0000000..9364271
--- /dev/null
+++ b/runtime/vm/simulator_x64.cc
@@ -0,0 +1,72 @@
+// Copyright (c) 2022, 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 <setjmp.h>  // NOLINT
+#include <stdlib.h>
+
+#include "vm/globals.h"
+#if defined(TARGET_ARCH_X64)
+
+// Only build the simulator if not compiling for real X64 hardware.
+#if defined(USING_SIMULATOR)
+
+#include "vm/simulator.h"
+
+#include "vm/heap/safepoint.h"
+#include "vm/isolate.h"
+
+namespace dart {
+
+// Get the active Simulator for the current isolate.
+Simulator* Simulator::Current() {
+  Isolate* isolate = Isolate::Current();
+  Simulator* simulator = isolate->simulator();
+  if (simulator == NULL) {
+    NoSafepointScope no_safepoint;
+    simulator = new Simulator();
+    isolate->set_simulator(simulator);
+  }
+  return simulator;
+}
+
+void Simulator::Init() {}
+
+Simulator::Simulator() {}
+
+Simulator::~Simulator() {
+  Isolate* isolate = Isolate::Current();
+  if (isolate != NULL) {
+    isolate->set_simulator(NULL);
+  }
+}
+
+int64_t Simulator::Call(int64_t entry,
+                        int64_t parameter0,
+                        int64_t parameter1,
+                        int64_t parameter2,
+                        int64_t parameter3,
+                        bool fp_return,
+                        bool fp_args) {
+  UNIMPLEMENTED();
+}
+
+void Simulator::JumpToFrame(uword pc, uword sp, uword fp, Thread* thread) {
+  UNIMPLEMENTED();
+}
+
+uword Simulator::RedirectExternalReference(uword function,
+                                           CallKind call_kind,
+                                           int argument_count) {
+  return 0;
+}
+
+uword Simulator::FunctionForRedirect(uword redirect) {
+  return 0;
+}
+
+}  // namespace dart
+
+#endif  // !defined(USING_SIMULATOR)
+
+#endif  // defined TARGET_ARCH_RISCV
diff --git a/runtime/vm/simulator_x64.h b/runtime/vm/simulator_x64.h
new file mode 100644
index 0000000..dad98f2
--- /dev/null
+++ b/runtime/vm/simulator_x64.h
@@ -0,0 +1,76 @@
+// Copyright (c) 2022, 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_SIMULATOR_X64_H_
+#define RUNTIME_VM_SIMULATOR_X64_H_
+
+#ifndef RUNTIME_VM_SIMULATOR_H_
+#error Do not include simulator_x64.h directly; use simulator.h.
+#endif
+
+#include "vm/constants.h"
+#include "vm/random.h"
+
+namespace dart {
+
+class Thread;
+
+class Simulator {
+ public:
+  static const uword kSimulatorStackUnderflowSize = 64;
+
+  Simulator();
+  ~Simulator();
+
+  static Simulator* Current();
+
+  int64_t Call(int64_t entry,
+               int64_t parameter0,
+               int64_t parameter1,
+               int64_t parameter2,
+               int64_t parameter3,
+               bool fp_return = false,
+               bool fp_args = false);
+
+  // Runtime and native call support.
+  enum CallKind {
+    kRuntimeCall,
+    kLeafRuntimeCall,
+    kLeafFloatRuntimeCall,
+    kNativeCallWrapper
+  };
+  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);
+
+  uint64_t get_register(Register rs) const { return 0; }
+  uint64_t get_pc() const { return 0; }
+  uint64_t get_sp() const { return 0; }
+  uint64_t get_fp() const { return 0; }
+  uint64_t get_lr() const { return 0; }
+
+  // High address.
+  uword stack_base() const { return 0; }
+  // Limit for StackOverflowError.
+  uword overflow_stack_limit() const { return 0; }
+  // Low address.
+  uword stack_limit() const { return 0; }
+
+  // Accessor to the instruction counter.
+  uint64_t get_icount() const { return 0; }
+
+  // Call on program start.
+  static void Init();
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(Simulator);
+};
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_SIMULATOR_X64_H_
diff --git a/runtime/vm/vm_sources.gni b/runtime/vm/vm_sources.gni
index 5efb504..4af1fd1 100644
--- a/runtime/vm/vm_sources.gni
+++ b/runtime/vm/vm_sources.gni
@@ -301,6 +301,8 @@
   "simulator_arm64.h",
   "simulator_riscv.cc",
   "simulator_riscv.h",
+  "simulator_x64.cc",
+  "simulator_x64.h",
   "snapshot.cc",
   "snapshot.h",
   "source_report.cc",
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 87cb254..15995b8 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -1338,6 +1338,14 @@
           ]
         },
         {
+          "name": "build dart (cross x64)",
+          "script": "tools/build.py",
+          "arguments": [
+            "--arch=simx64",
+            "gen_snapshot"
+          ]
+        },
+        {
           "name": "vm nnbd tests in weak mode with asserts",
           "arguments": [
             "-ndartkp-weak-asserts-${system}-${mode}-${arch}",
diff --git a/tools/gn.py b/tools/gn.py
index c93daea..b532f0b 100755
--- a/tools/gn.py
+++ b/tools/gn.py
@@ -82,8 +82,8 @@
     # - using a host architecture with a different word size (supports only AOT and only 32-bit target on 64-bit host)
     if arch in ['ia32']:
         candidates = ['x86']
-    elif arch in ['x64', 'x64c']:
-        candidates = ['x64']
+    elif arch in ['x64', 'x64c', 'simx64', 'simx64c']:
+        candidates = ['x64', 'arm64']
     elif arch in ['arm', 'simarm']:
         candidates = ['arm', 'x86', 'riscv32', 'arm64', 'x64', 'riscv64']
     elif arch in ['arm64', 'arm64c', 'simarm64', 'simarm64c']:
@@ -124,7 +124,7 @@
     # Simulators
     if arch in ['simarm_x64', 'simriscv32_x64']:
         return 'x64'
-    elif arch in ['simarm_arm64', 'simriscv32_arm64']:
+    elif arch in ['simarm_arm64', 'simriscv32_arm64', 'simx64', 'simx64c']:
         return 'arm64'
     elif arch in ['simarm_riscv64', 'simriscv32_riscv64']:
         return 'riscv64'
@@ -149,7 +149,7 @@
 def DartTargetCpuForArch(arch):
     if arch in ['ia32']:
         return 'ia32'
-    if arch in ['x64', 'x64c']:
+    if arch in ['x64', 'x64c', 'simx64', 'simx64c']:
         return 'x64'
     if arch in [
             'arm', 'simarm', 'simarm_x64', 'arm_x64', 'simarm_arm64',
diff --git a/tools/utils.py b/tools/utils.py
index 9141d93..9186fdd 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -77,6 +77,8 @@
     'simarm64c': 'ia32',
     'simriscv32': 'ia32',
     'simriscv64': 'ia32',
+    'simx64': 'arm',
+    'simx64c': 'arm',
     'riscv32': 'riscv',
     'riscv64': 'riscv',
 }