| Index: runtime/vm/simulator_dbc.cc | 
| diff --git a/runtime/vm/simulator_dbc.cc b/runtime/vm/simulator_dbc.cc | 
| index 8623a643e1db258ea960f2d3abdb5679f76cd1d7..7329114a00f6fe899e2b76a7f240d0ef8362ae50 100644 | 
| --- a/runtime/vm/simulator_dbc.cc | 
| +++ b/runtime/vm/simulator_dbc.cc | 
| @@ -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 | 
|  |