171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe/*
271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe * Copyright (C) 2015 The Android Open Source Project
371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe *
471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe * Licensed under the Apache License, Version 2.0 (the "License");
571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe * you may not use this file except in compliance with the License.
671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe * You may obtain a copy of the License at
771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe *
871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe *      http://www.apache.org/licenses/LICENSE-2.0
971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe *
1071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe * Unless required by applicable law or agreed to in writing, software
1171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe * distributed under the License is distributed on an "AS IS" BASIS,
1271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe * See the License for the specific language governing permissions and
1471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe * limitations under the License.
1571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe */
1671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
1771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#include "intrinsics.h"
1871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
19bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe#include "art_method.h"
20bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe#include "class_linker.h"
2171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#include "dex/quick/dex_file_method_inliner.h"
2271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#include "dex/quick/dex_file_to_method_inliner_map.h"
2371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#include "driver/compiler_driver.h"
2471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#include "invoke_type.h"
25bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe#include "mirror/dex_cache-inl.h"
2671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#include "nodes.h"
2771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#include "quick/inline_method_analyser.h"
28bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe#include "scoped_thread_state_change.h"
29bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe#include "thread-inl.h"
3080afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko#include "utils.h"
3171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
3271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampenamespace art {
3371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
3471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe// Function that returns whether an intrinsic is static/direct or virtual.
3571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampestatic inline InvokeType GetIntrinsicInvokeType(Intrinsics i) {
3671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  switch (i) {
3771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case Intrinsics::kNone:
3871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      return kInterface;  // Non-sensical for intrinsic.
395d75afe333f57546786686d9bee16b52f1bbe971Aart Bik#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \
405d75afe333f57546786686d9bee16b52f1bbe971Aart Bik    case Intrinsics::k ## Name: \
4171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      return IsStatic;
4271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#include "intrinsics_list.h"
4371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas GampeINTRINSICS_LIST(OPTIMIZING_INTRINSICS)
4471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#undef INTRINSICS_LIST
4571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#undef OPTIMIZING_INTRINSICS
4671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  }
4771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  return kInterface;
4871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
4971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
5057b81ecbe74138992dd447251e94ed06cd5eb802agicsaki// Function that returns whether an intrinsic needs an environment or not.
5105f2056b4f11e0b2bac92b2655abe7030771f5dcAgi Csakistatic inline IntrinsicNeedsEnvironmentOrCache NeedsEnvironmentOrCache(Intrinsics i) {
5257b81ecbe74138992dd447251e94ed06cd5eb802agicsaki  switch (i) {
5357b81ecbe74138992dd447251e94ed06cd5eb802agicsaki    case Intrinsics::kNone:
5405f2056b4f11e0b2bac92b2655abe7030771f5dcAgi Csaki      return kNeedsEnvironmentOrCache;  // Non-sensical for intrinsic.
555d75afe333f57546786686d9bee16b52f1bbe971Aart Bik#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \
565d75afe333f57546786686d9bee16b52f1bbe971Aart Bik    case Intrinsics::k ## Name: \
5705f2056b4f11e0b2bac92b2655abe7030771f5dcAgi Csaki      return NeedsEnvironmentOrCache;
5857b81ecbe74138992dd447251e94ed06cd5eb802agicsaki#include "intrinsics_list.h"
5957b81ecbe74138992dd447251e94ed06cd5eb802agicsakiINTRINSICS_LIST(OPTIMIZING_INTRINSICS)
6057b81ecbe74138992dd447251e94ed06cd5eb802agicsaki#undef INTRINSICS_LIST
6157b81ecbe74138992dd447251e94ed06cd5eb802agicsaki#undef OPTIMIZING_INTRINSICS
6257b81ecbe74138992dd447251e94ed06cd5eb802agicsaki  }
6305f2056b4f11e0b2bac92b2655abe7030771f5dcAgi Csaki  return kNeedsEnvironmentOrCache;
6457b81ecbe74138992dd447251e94ed06cd5eb802agicsaki}
6571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
665d75afe333f57546786686d9bee16b52f1bbe971Aart Bik// Function that returns whether an intrinsic has side effects.
675d75afe333f57546786686d9bee16b52f1bbe971Aart Bikstatic inline IntrinsicSideEffects GetSideEffects(Intrinsics i) {
685d75afe333f57546786686d9bee16b52f1bbe971Aart Bik  switch (i) {
695d75afe333f57546786686d9bee16b52f1bbe971Aart Bik    case Intrinsics::kNone:
705d75afe333f57546786686d9bee16b52f1bbe971Aart Bik      return kAllSideEffects;
715d75afe333f57546786686d9bee16b52f1bbe971Aart Bik#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \
725d75afe333f57546786686d9bee16b52f1bbe971Aart Bik    case Intrinsics::k ## Name: \
735d75afe333f57546786686d9bee16b52f1bbe971Aart Bik      return SideEffects;
745d75afe333f57546786686d9bee16b52f1bbe971Aart Bik#include "intrinsics_list.h"
755d75afe333f57546786686d9bee16b52f1bbe971Aart BikINTRINSICS_LIST(OPTIMIZING_INTRINSICS)
765d75afe333f57546786686d9bee16b52f1bbe971Aart Bik#undef INTRINSICS_LIST
775d75afe333f57546786686d9bee16b52f1bbe971Aart Bik#undef OPTIMIZING_INTRINSICS
785d75afe333f57546786686d9bee16b52f1bbe971Aart Bik  }
795d75afe333f57546786686d9bee16b52f1bbe971Aart Bik  return kAllSideEffects;
805d75afe333f57546786686d9bee16b52f1bbe971Aart Bik}
815d75afe333f57546786686d9bee16b52f1bbe971Aart Bik
825d75afe333f57546786686d9bee16b52f1bbe971Aart Bik// Function that returns whether an intrinsic can throw exceptions.
835d75afe333f57546786686d9bee16b52f1bbe971Aart Bikstatic inline IntrinsicExceptions GetExceptions(Intrinsics i) {
845d75afe333f57546786686d9bee16b52f1bbe971Aart Bik  switch (i) {
855d75afe333f57546786686d9bee16b52f1bbe971Aart Bik    case Intrinsics::kNone:
865d75afe333f57546786686d9bee16b52f1bbe971Aart Bik      return kCanThrow;
875d75afe333f57546786686d9bee16b52f1bbe971Aart Bik#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \
885d75afe333f57546786686d9bee16b52f1bbe971Aart Bik    case Intrinsics::k ## Name: \
895d75afe333f57546786686d9bee16b52f1bbe971Aart Bik      return Exceptions;
905d75afe333f57546786686d9bee16b52f1bbe971Aart Bik#include "intrinsics_list.h"
915d75afe333f57546786686d9bee16b52f1bbe971Aart BikINTRINSICS_LIST(OPTIMIZING_INTRINSICS)
925d75afe333f57546786686d9bee16b52f1bbe971Aart Bik#undef INTRINSICS_LIST
935d75afe333f57546786686d9bee16b52f1bbe971Aart Bik#undef OPTIMIZING_INTRINSICS
945d75afe333f57546786686d9bee16b52f1bbe971Aart Bik  }
955d75afe333f57546786686d9bee16b52f1bbe971Aart Bik  return kCanThrow;
965d75afe333f57546786686d9bee16b52f1bbe971Aart Bik}
975d75afe333f57546786686d9bee16b52f1bbe971Aart Bik
9871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampestatic Primitive::Type GetType(uint64_t data, bool is_op_size) {
9971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  if (is_op_size) {
10071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    switch (static_cast<OpSize>(data)) {
10171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      case kSignedByte:
102878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe        return Primitive::kPrimByte;
10371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      case kSignedHalf:
104878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe        return Primitive::kPrimShort;
10571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      case k32:
106878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe        return Primitive::kPrimInt;
10771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      case k64:
108878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe        return Primitive::kPrimLong;
10971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      default:
11071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe        LOG(FATAL) << "Unknown/unsupported op size " << data;
11171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe        UNREACHABLE();
11271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    }
11371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  } else {
11471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    if ((data & kIntrinsicFlagIsLong) != 0) {
115878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe      return Primitive::kPrimLong;
11671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    }
11771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    if ((data & kIntrinsicFlagIsObject) != 0) {
118878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe      return Primitive::kPrimNot;
11971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    }
120878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe    return Primitive::kPrimInt;
12171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  }
12271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
12371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
12416ba2b4726cafc2d83cae4a65132aac15f372689Chris Larsenstatic Intrinsics GetIntrinsic(InlineMethod method) {
12571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  switch (method.opcode) {
12671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    // Floating-point conversions.
12771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kIntrinsicDoubleCvt:
12871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      return ((method.d.data & kIntrinsicFlagToFloatingPoint) == 0) ?
12971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          Intrinsics::kDoubleDoubleToRawLongBits : Intrinsics::kDoubleLongBitsToDouble;
13071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kIntrinsicFloatCvt:
13171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      return ((method.d.data & kIntrinsicFlagToFloatingPoint) == 0) ?
13271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          Intrinsics::kFloatFloatToRawIntBits : Intrinsics::kFloatIntBitsToFloat;
1332a6aad9d388bd29bff04aeec3eb9429d436d1873Aart Bik    case kIntrinsicFloat2Int:
1342a6aad9d388bd29bff04aeec3eb9429d436d1873Aart Bik      return Intrinsics::kFloatFloatToIntBits;
1352a6aad9d388bd29bff04aeec3eb9429d436d1873Aart Bik    case kIntrinsicDouble2Long:
1362a6aad9d388bd29bff04aeec3eb9429d436d1873Aart Bik      return Intrinsics::kDoubleDoubleToLongBits;
13771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
13859c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik    // Floating-point tests.
13959c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik    case kIntrinsicFloatIsInfinite:
14059c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik      return Intrinsics::kFloatIsInfinite;
14159c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik    case kIntrinsicDoubleIsInfinite:
14259c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik      return Intrinsics::kDoubleIsInfinite;
14359c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik    case kIntrinsicFloatIsNaN:
14459c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik      return Intrinsics::kFloatIsNaN;
14559c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik    case kIntrinsicDoubleIsNaN:
14659c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik      return Intrinsics::kDoubleIsNaN;
14759c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik
14871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    // Bit manipulations.
14971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kIntrinsicReverseBits:
15071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      switch (GetType(method.d.data, true)) {
151878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe        case Primitive::kPrimInt:
15271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          return Intrinsics::kIntegerReverse;
153878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe        case Primitive::kPrimLong:
15471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          return Intrinsics::kLongReverse;
15571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe        default:
15671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          LOG(FATAL) << "Unknown/unsupported op size " << method.d.data;
15771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          UNREACHABLE();
15871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      }
15971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kIntrinsicReverseBytes:
16071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      switch (GetType(method.d.data, true)) {
161878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe        case Primitive::kPrimShort:
16271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          return Intrinsics::kShortReverseBytes;
163878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe        case Primitive::kPrimInt:
16471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          return Intrinsics::kIntegerReverseBytes;
165878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe        case Primitive::kPrimLong:
16671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          return Intrinsics::kLongReverseBytes;
16771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe        default:
16871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          LOG(FATAL) << "Unknown/unsupported op size " << method.d.data;
16971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          UNREACHABLE();
17071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      }
1719ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling    case kIntrinsicRotateRight:
1729ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling      switch (GetType(method.d.data, true)) {
1739ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling        case Primitive::kPrimInt:
1749ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling          return Intrinsics::kIntegerRotateRight;
1759ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling        case Primitive::kPrimLong:
1769ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling          return Intrinsics::kLongRotateRight;
1779ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling        default:
1789ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling          LOG(FATAL) << "Unknown/unsupported op size " << method.d.data;
1799ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling          UNREACHABLE();
1809ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling      }
1819ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling    case kIntrinsicRotateLeft:
1829ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling      switch (GetType(method.d.data, true)) {
1839ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling        case Primitive::kPrimInt:
1849ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling          return Intrinsics::kIntegerRotateLeft;
1859ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling        case Primitive::kPrimLong:
1869ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling          return Intrinsics::kLongRotateLeft;
1879ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling        default:
1889ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling          LOG(FATAL) << "Unknown/unsupported op size " << method.d.data;
1899ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling          UNREACHABLE();
1909ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling      }
1919ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling
1929ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling    // Misc data processing.
1933f67e692860d281858485d48a4f1f81b907f1444Aart Bik    case kIntrinsicBitCount:
1943f67e692860d281858485d48a4f1f81b907f1444Aart Bik      switch (GetType(method.d.data, true)) {
1953f67e692860d281858485d48a4f1f81b907f1444Aart Bik        case Primitive::kPrimInt:
1963f67e692860d281858485d48a4f1f81b907f1444Aart Bik          return Intrinsics::kIntegerBitCount;
1973f67e692860d281858485d48a4f1f81b907f1444Aart Bik        case Primitive::kPrimLong:
1983f67e692860d281858485d48a4f1f81b907f1444Aart Bik          return Intrinsics::kLongBitCount;
1993f67e692860d281858485d48a4f1f81b907f1444Aart Bik        default:
2003f67e692860d281858485d48a4f1f81b907f1444Aart Bik          LOG(FATAL) << "Unknown/unsupported op size " << method.d.data;
2013f67e692860d281858485d48a4f1f81b907f1444Aart Bik          UNREACHABLE();
2023f67e692860d281858485d48a4f1f81b907f1444Aart Bik      }
20359c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik    case kIntrinsicCompare:
20459c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik      switch (GetType(method.d.data, true)) {
20559c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik        case Primitive::kPrimInt:
20659c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik          return Intrinsics::kIntegerCompare;
20759c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik        case Primitive::kPrimLong:
20859c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik          return Intrinsics::kLongCompare;
20959c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik        default:
21059c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik          LOG(FATAL) << "Unknown/unsupported op size " << method.d.data;
21159c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik          UNREACHABLE();
21259c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik      }
21359c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik    case kIntrinsicHighestOneBit:
21459c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik      switch (GetType(method.d.data, true)) {
21559c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik        case Primitive::kPrimInt:
21659c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik          return Intrinsics::kIntegerHighestOneBit;
21759c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik        case Primitive::kPrimLong:
21859c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik          return Intrinsics::kLongHighestOneBit;
21959c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik        default:
22059c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik          LOG(FATAL) << "Unknown/unsupported op size " << method.d.data;
22159c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik          UNREACHABLE();
22259c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik      }
22359c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik    case kIntrinsicLowestOneBit:
22459c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik      switch (GetType(method.d.data, true)) {
22559c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik        case Primitive::kPrimInt:
22659c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik          return Intrinsics::kIntegerLowestOneBit;
22759c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik        case Primitive::kPrimLong:
22859c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik          return Intrinsics::kLongLowestOneBit;
22959c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik        default:
23059c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik          LOG(FATAL) << "Unknown/unsupported op size " << method.d.data;
23159c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik          UNREACHABLE();
23259c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik      }
233611d3395e9efc0ab8dbfa4a197fa022fbd8c7204Scott Wakeling    case kIntrinsicNumberOfLeadingZeros:
234611d3395e9efc0ab8dbfa4a197fa022fbd8c7204Scott Wakeling      switch (GetType(method.d.data, true)) {
235611d3395e9efc0ab8dbfa4a197fa022fbd8c7204Scott Wakeling        case Primitive::kPrimInt:
236611d3395e9efc0ab8dbfa4a197fa022fbd8c7204Scott Wakeling          return Intrinsics::kIntegerNumberOfLeadingZeros;
237611d3395e9efc0ab8dbfa4a197fa022fbd8c7204Scott Wakeling        case Primitive::kPrimLong:
238611d3395e9efc0ab8dbfa4a197fa022fbd8c7204Scott Wakeling          return Intrinsics::kLongNumberOfLeadingZeros;
239611d3395e9efc0ab8dbfa4a197fa022fbd8c7204Scott Wakeling        default:
240611d3395e9efc0ab8dbfa4a197fa022fbd8c7204Scott Wakeling          LOG(FATAL) << "Unknown/unsupported op size " << method.d.data;
241611d3395e9efc0ab8dbfa4a197fa022fbd8c7204Scott Wakeling          UNREACHABLE();
242611d3395e9efc0ab8dbfa4a197fa022fbd8c7204Scott Wakeling      }
2439ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling    case kIntrinsicNumberOfTrailingZeros:
2449ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling      switch (GetType(method.d.data, true)) {
2459ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling        case Primitive::kPrimInt:
2469ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling          return Intrinsics::kIntegerNumberOfTrailingZeros;
2479ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling        case Primitive::kPrimLong:
2489ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling          return Intrinsics::kLongNumberOfTrailingZeros;
2499ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling        default:
2509ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling          LOG(FATAL) << "Unknown/unsupported op size " << method.d.data;
2519ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling          UNREACHABLE();
2529ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling      }
25359c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik    case kIntrinsicSignum:
25459c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik      switch (GetType(method.d.data, true)) {
25559c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik        case Primitive::kPrimInt:
25659c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik          return Intrinsics::kIntegerSignum;
25759c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik        case Primitive::kPrimLong:
25859c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik          return Intrinsics::kLongSignum;
25959c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik        default:
26059c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik          LOG(FATAL) << "Unknown/unsupported op size " << method.d.data;
26159c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik          UNREACHABLE();
26259c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik      }
26371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
26471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    // Abs.
26571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kIntrinsicAbsDouble:
26671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      return Intrinsics::kMathAbsDouble;
26771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kIntrinsicAbsFloat:
26871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      return Intrinsics::kMathAbsFloat;
26971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kIntrinsicAbsInt:
27071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      return Intrinsics::kMathAbsInt;
27171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kIntrinsicAbsLong:
27271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      return Intrinsics::kMathAbsLong;
27371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
27471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    // Min/max.
27571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kIntrinsicMinMaxDouble:
27671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      return ((method.d.data & kIntrinsicFlagMin) == 0) ?
27771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          Intrinsics::kMathMaxDoubleDouble : Intrinsics::kMathMinDoubleDouble;
27871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kIntrinsicMinMaxFloat:
27971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      return ((method.d.data & kIntrinsicFlagMin) == 0) ?
28071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          Intrinsics::kMathMaxFloatFloat : Intrinsics::kMathMinFloatFloat;
28171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kIntrinsicMinMaxInt:
28271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      return ((method.d.data & kIntrinsicFlagMin) == 0) ?
28371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          Intrinsics::kMathMaxIntInt : Intrinsics::kMathMinIntInt;
28471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kIntrinsicMinMaxLong:
28571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      return ((method.d.data & kIntrinsicFlagMin) == 0) ?
28671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          Intrinsics::kMathMaxLongLong : Intrinsics::kMathMinLongLong;
28771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
288a4f1220c1518074db18ca1044e9201492975750bMark Mendell    // More math builtins.
289a4f1220c1518074db18ca1044e9201492975750bMark Mendell    case kIntrinsicCos:
290a4f1220c1518074db18ca1044e9201492975750bMark Mendell      return Intrinsics::kMathCos;
291a4f1220c1518074db18ca1044e9201492975750bMark Mendell    case kIntrinsicSin:
292a4f1220c1518074db18ca1044e9201492975750bMark Mendell      return Intrinsics::kMathSin;
293a4f1220c1518074db18ca1044e9201492975750bMark Mendell    case kIntrinsicAcos:
294a4f1220c1518074db18ca1044e9201492975750bMark Mendell      return Intrinsics::kMathAcos;
295a4f1220c1518074db18ca1044e9201492975750bMark Mendell    case kIntrinsicAsin:
296a4f1220c1518074db18ca1044e9201492975750bMark Mendell      return Intrinsics::kMathAsin;
297a4f1220c1518074db18ca1044e9201492975750bMark Mendell    case kIntrinsicAtan:
298a4f1220c1518074db18ca1044e9201492975750bMark Mendell      return Intrinsics::kMathAtan;
299a4f1220c1518074db18ca1044e9201492975750bMark Mendell    case kIntrinsicAtan2:
300a4f1220c1518074db18ca1044e9201492975750bMark Mendell      return Intrinsics::kMathAtan2;
301a4f1220c1518074db18ca1044e9201492975750bMark Mendell    case kIntrinsicCbrt:
302a4f1220c1518074db18ca1044e9201492975750bMark Mendell      return Intrinsics::kMathCbrt;
303a4f1220c1518074db18ca1044e9201492975750bMark Mendell    case kIntrinsicCosh:
304a4f1220c1518074db18ca1044e9201492975750bMark Mendell      return Intrinsics::kMathCosh;
305a4f1220c1518074db18ca1044e9201492975750bMark Mendell    case kIntrinsicExp:
306a4f1220c1518074db18ca1044e9201492975750bMark Mendell      return Intrinsics::kMathExp;
307a4f1220c1518074db18ca1044e9201492975750bMark Mendell    case kIntrinsicExpm1:
308a4f1220c1518074db18ca1044e9201492975750bMark Mendell      return Intrinsics::kMathExpm1;
309a4f1220c1518074db18ca1044e9201492975750bMark Mendell    case kIntrinsicHypot:
310a4f1220c1518074db18ca1044e9201492975750bMark Mendell      return Intrinsics::kMathHypot;
311a4f1220c1518074db18ca1044e9201492975750bMark Mendell    case kIntrinsicLog:
312a4f1220c1518074db18ca1044e9201492975750bMark Mendell      return Intrinsics::kMathLog;
313a4f1220c1518074db18ca1044e9201492975750bMark Mendell    case kIntrinsicLog10:
314a4f1220c1518074db18ca1044e9201492975750bMark Mendell      return Intrinsics::kMathLog10;
315a4f1220c1518074db18ca1044e9201492975750bMark Mendell    case kIntrinsicNextAfter:
316a4f1220c1518074db18ca1044e9201492975750bMark Mendell      return Intrinsics::kMathNextAfter;
317a4f1220c1518074db18ca1044e9201492975750bMark Mendell    case kIntrinsicSinh:
318a4f1220c1518074db18ca1044e9201492975750bMark Mendell      return Intrinsics::kMathSinh;
319a4f1220c1518074db18ca1044e9201492975750bMark Mendell    case kIntrinsicTan:
320a4f1220c1518074db18ca1044e9201492975750bMark Mendell      return Intrinsics::kMathTan;
321a4f1220c1518074db18ca1044e9201492975750bMark Mendell    case kIntrinsicTanh:
322a4f1220c1518074db18ca1044e9201492975750bMark Mendell      return Intrinsics::kMathTanh;
323a4f1220c1518074db18ca1044e9201492975750bMark Mendell
32471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    // Misc math.
32571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kIntrinsicSqrt:
32671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      return Intrinsics::kMathSqrt;
32771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kIntrinsicCeil:
32871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      return Intrinsics::kMathCeil;
32971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kIntrinsicFloor:
33071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      return Intrinsics::kMathFloor;
33171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kIntrinsicRint:
33271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      return Intrinsics::kMathRint;
33371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kIntrinsicRoundDouble:
33471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      return Intrinsics::kMathRoundDouble;
33571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kIntrinsicRoundFloat:
33671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      return Intrinsics::kMathRoundFloat;
33771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
33871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    // System.arraycopy.
33971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kIntrinsicSystemArrayCopyCharArray:
34071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      return Intrinsics::kSystemArrayCopyChar;
34171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
342ee3cf0731d0ef0787bc2947c8e3ca432b513956bNicolas Geoffray    case kIntrinsicSystemArrayCopy:
343ee3cf0731d0ef0787bc2947c8e3ca432b513956bNicolas Geoffray      return Intrinsics::kSystemArrayCopy;
344ee3cf0731d0ef0787bc2947c8e3ca432b513956bNicolas Geoffray
34571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    // Thread.currentThread.
34671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kIntrinsicCurrentThread:
3475d75afe333f57546786686d9bee16b52f1bbe971Aart Bik      return Intrinsics::kThreadCurrentThread;
34871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
34971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    // Memory.peek.
35071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kIntrinsicPeek:
35171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      switch (GetType(method.d.data, true)) {
352878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe        case Primitive::kPrimByte:
35371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          return Intrinsics::kMemoryPeekByte;
354878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe        case Primitive::kPrimShort:
35571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          return Intrinsics::kMemoryPeekShortNative;
356878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe        case Primitive::kPrimInt:
35771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          return Intrinsics::kMemoryPeekIntNative;
358878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe        case Primitive::kPrimLong:
35971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          return Intrinsics::kMemoryPeekLongNative;
36071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe        default:
36171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          LOG(FATAL) << "Unknown/unsupported op size " << method.d.data;
36271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          UNREACHABLE();
36371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      }
36471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
36571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    // Memory.poke.
36671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kIntrinsicPoke:
36771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      switch (GetType(method.d.data, true)) {
368878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe        case Primitive::kPrimByte:
36971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          return Intrinsics::kMemoryPokeByte;
370878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe        case Primitive::kPrimShort:
37171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          return Intrinsics::kMemoryPokeShortNative;
372878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe        case Primitive::kPrimInt:
37371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          return Intrinsics::kMemoryPokeIntNative;
374878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe        case Primitive::kPrimLong:
37571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          return Intrinsics::kMemoryPokeLongNative;
37671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe        default:
37771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          LOG(FATAL) << "Unknown/unsupported op size " << method.d.data;
37871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          UNREACHABLE();
37971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      }
38071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
38171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    // String.
38271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kIntrinsicCharAt:
38371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      return Intrinsics::kStringCharAt;
38471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kIntrinsicCompareTo:
38571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      return Intrinsics::kStringCompareTo;
3867da072feb160079734331e994ea52760cb2a3243agicsaki    case kIntrinsicEquals:
3877da072feb160079734331e994ea52760cb2a3243agicsaki      return Intrinsics::kStringEquals;
388848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    case kIntrinsicGetCharsNoCheck:
389848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao      return Intrinsics::kStringGetCharsNoCheck;
39071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kIntrinsicIsEmptyOrLength:
3913e90a96f403cbc353731e6687fe12a088f996ceeRazvan A Lupusoru      // The inliner can handle these two cases - and this is the preferred approach
3923e90a96f403cbc353731e6687fe12a088f996ceeRazvan A Lupusoru      // since after inlining the call is no longer visible (as opposed to waiting
3933e90a96f403cbc353731e6687fe12a088f996ceeRazvan A Lupusoru      // until codegen to handle intrinsic).
3943e90a96f403cbc353731e6687fe12a088f996ceeRazvan A Lupusoru      return Intrinsics::kNone;
39571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kIntrinsicIndexOf:
39671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      return ((method.d.data & kIntrinsicFlagBase0) == 0) ?
39771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          Intrinsics::kStringIndexOfAfter : Intrinsics::kStringIndexOf;
398848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    case kIntrinsicNewStringFromBytes:
399848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao      return Intrinsics::kStringNewStringFromBytes;
400848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    case kIntrinsicNewStringFromChars:
401848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao      return Intrinsics::kStringNewStringFromChars;
402848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    case kIntrinsicNewStringFromString:
403848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao      return Intrinsics::kStringNewStringFromString;
40471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
40571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kIntrinsicCas:
40671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      switch (GetType(method.d.data, false)) {
407878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe        case Primitive::kPrimNot:
40871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          return Intrinsics::kUnsafeCASObject;
409878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe        case Primitive::kPrimInt:
41071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          return Intrinsics::kUnsafeCASInt;
411878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe        case Primitive::kPrimLong:
41271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          return Intrinsics::kUnsafeCASLong;
41371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe        default:
41471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          LOG(FATAL) << "Unknown/unsupported op size " << method.d.data;
41571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          UNREACHABLE();
41671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      }
41771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kIntrinsicUnsafeGet: {
41871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      const bool is_volatile = (method.d.data & kIntrinsicFlagIsVolatile);
41971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      switch (GetType(method.d.data, false)) {
420878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe        case Primitive::kPrimInt:
42171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          return is_volatile ? Intrinsics::kUnsafeGetVolatile : Intrinsics::kUnsafeGet;
422878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe        case Primitive::kPrimLong:
42371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          return is_volatile ? Intrinsics::kUnsafeGetLongVolatile : Intrinsics::kUnsafeGetLong;
424878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe        case Primitive::kPrimNot:
425878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe          return is_volatile ? Intrinsics::kUnsafeGetObjectVolatile : Intrinsics::kUnsafeGetObject;
42671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe        default:
42771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          LOG(FATAL) << "Unknown/unsupported op size " << method.d.data;
42871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          UNREACHABLE();
42971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      }
43071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    }
43171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kIntrinsicUnsafePut: {
43271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      enum Sync { kNoSync, kVolatile, kOrdered };
43371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      const Sync sync =
43471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          ((method.d.data & kIntrinsicFlagIsVolatile) != 0) ? kVolatile :
43571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          ((method.d.data & kIntrinsicFlagIsOrdered) != 0)  ? kOrdered :
43671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe                                                              kNoSync;
43771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      switch (GetType(method.d.data, false)) {
438878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe        case Primitive::kPrimInt:
43971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          switch (sync) {
44071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe            case kNoSync:
44171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe              return Intrinsics::kUnsafePut;
44271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe            case kVolatile:
44371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe              return Intrinsics::kUnsafePutVolatile;
44471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe            case kOrdered:
44571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe              return Intrinsics::kUnsafePutOrdered;
44671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          }
44771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          break;
448878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe        case Primitive::kPrimLong:
44971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          switch (sync) {
45071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe            case kNoSync:
45171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe              return Intrinsics::kUnsafePutLong;
45271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe            case kVolatile:
45371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe              return Intrinsics::kUnsafePutLongVolatile;
45471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe            case kOrdered:
45571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe              return Intrinsics::kUnsafePutLongOrdered;
45671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          }
45771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          break;
458878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe        case Primitive::kPrimNot:
45971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          switch (sync) {
46071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe            case kNoSync:
46171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe              return Intrinsics::kUnsafePutObject;
46271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe            case kVolatile:
46371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe              return Intrinsics::kUnsafePutObjectVolatile;
46471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe            case kOrdered:
46571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe              return Intrinsics::kUnsafePutObjectOrdered;
46671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          }
46771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          break;
46871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe        default:
46971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          LOG(FATAL) << "Unknown/unsupported op size " << method.d.data;
47071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          UNREACHABLE();
47171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      }
47271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      break;
47371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    }
47471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
4750e54c0160c84894696c05af6cad9eae3690f9496Aart Bik    // 1.8.
4760e54c0160c84894696c05af6cad9eae3690f9496Aart Bik    case kIntrinsicUnsafeGetAndAddInt:
4770e54c0160c84894696c05af6cad9eae3690f9496Aart Bik      return Intrinsics::kUnsafeGetAndAddInt;
4780e54c0160c84894696c05af6cad9eae3690f9496Aart Bik    case kIntrinsicUnsafeGetAndAddLong:
4790e54c0160c84894696c05af6cad9eae3690f9496Aart Bik      return Intrinsics::kUnsafeGetAndAddLong;
4800e54c0160c84894696c05af6cad9eae3690f9496Aart Bik    case kIntrinsicUnsafeGetAndSetInt:
4810e54c0160c84894696c05af6cad9eae3690f9496Aart Bik      return Intrinsics::kUnsafeGetAndSetInt;
4820e54c0160c84894696c05af6cad9eae3690f9496Aart Bik    case kIntrinsicUnsafeGetAndSetLong:
4830e54c0160c84894696c05af6cad9eae3690f9496Aart Bik      return Intrinsics::kUnsafeGetAndSetLong;
4840e54c0160c84894696c05af6cad9eae3690f9496Aart Bik    case kIntrinsicUnsafeGetAndSetObject:
4850e54c0160c84894696c05af6cad9eae3690f9496Aart Bik      return Intrinsics::kUnsafeGetAndSetObject;
4860e54c0160c84894696c05af6cad9eae3690f9496Aart Bik    case kIntrinsicUnsafeLoadFence:
4870e54c0160c84894696c05af6cad9eae3690f9496Aart Bik      return Intrinsics::kUnsafeLoadFence;
4880e54c0160c84894696c05af6cad9eae3690f9496Aart Bik    case kIntrinsicUnsafeStoreFence:
4890e54c0160c84894696c05af6cad9eae3690f9496Aart Bik      return Intrinsics::kUnsafeStoreFence;
4900e54c0160c84894696c05af6cad9eae3690f9496Aart Bik    case kIntrinsicUnsafeFullFence:
4910e54c0160c84894696c05af6cad9eae3690f9496Aart Bik      return Intrinsics::kUnsafeFullFence;
4920e54c0160c84894696c05af6cad9eae3690f9496Aart Bik
49371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    // Virtual cases.
49471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
49571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kIntrinsicReferenceGetReferent:
49671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      return Intrinsics::kReferenceGetReferent;
49771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
49871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    // Quick inliner cases. Remove after refactoring. They are here so that we can use the
49971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    // compiler to warn on missing cases.
50071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
50171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kInlineOpNop:
50271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kInlineOpReturnArg:
50371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kInlineOpNonWideConst:
50471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kInlineOpIGet:
50571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kInlineOpIPut:
506354efa6cdf558b2331e8fec539893fa51763806eVladimir Marko    case kInlineOpConstructor:
50771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      return Intrinsics::kNone;
50871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
509848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    // String init cases, not intrinsics.
510848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao
511848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    case kInlineStringInit:
512848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao      return Intrinsics::kNone;
513848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao
51471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    // No default case to make the compiler warn on missing cases.
51571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  }
51671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  return Intrinsics::kNone;
51771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
51871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
519bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampestatic bool CheckInvokeType(Intrinsics intrinsic, HInvoke* invoke, const DexFile& dex_file) {
52071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  // The DexFileMethodInliner should have checked whether the methods are agreeing with
52171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  // what we expect, i.e., static methods are called as such. Add another check here for
52271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  // our expectations:
523bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe  //
524bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe  // Whenever the intrinsic is marked as static, report an error if we find an InvokeVirtual.
525bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe  //
526bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe  // Whenever the intrinsic is marked as direct and we find an InvokeVirtual, a devirtualization
527bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe  // failure occured. We might be in a situation where we have inlined a method that calls an
528bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe  // intrinsic, but that method is in a different dex file on which we do not have a
529bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe  // verified_method that would have helped the compiler driver sharpen the call. In that case,
530bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe  // make sure that the intrinsic is actually for some final method (or in a final class), as
531bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe  // otherwise the intrinsics setup is broken.
532bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe  //
533bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe  // For the last direction, we have intrinsics for virtual functions that will perform a check
534bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe  // inline. If the precise type is known, however, the instruction will be sharpened to an
535bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe  // InvokeStaticOrDirect.
53671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  InvokeType intrinsic_type = GetIntrinsicInvokeType(intrinsic);
53771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  InvokeType invoke_type = invoke->IsInvokeStaticOrDirect() ?
538e523423a053af5cb55837f07ceae9ff2fd581712Nicolas Geoffray      invoke->AsInvokeStaticOrDirect()->GetOptimizedInvokeType() :
53971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      invoke->IsInvokeVirtual() ? kVirtual : kSuper;
54071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  switch (intrinsic_type) {
54171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kStatic:
54271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      return (invoke_type == kStatic);
543bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe
54471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kDirect:
545bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe      if (invoke_type == kDirect) {
546bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe        return true;
547bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe      }
548bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe      if (invoke_type == kVirtual) {
549bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe        ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
550bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe        ScopedObjectAccess soa(Thread::Current());
551bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe        ArtMethod* art_method =
552bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe            class_linker->FindDexCache(soa.Self(), dex_file)->GetResolvedMethod(
553bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe                invoke->GetDexMethodIndex(), class_linker->GetImagePointerSize());
554bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe        return art_method != nullptr &&
555bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe            (art_method->IsFinal() || art_method->GetDeclaringClass()->IsFinal());
556bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe      }
557bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe      return false;
558bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe
55971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case kVirtual:
56071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      // Call might be devirtualized.
56171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      return (invoke_type == kVirtual || invoke_type == kDirect);
56271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
56371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    default:
56471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      return false;
56571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  }
56671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
56771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
56871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe// TODO: Refactor DexFileMethodInliner and have something nicer than InlineMethod.
56971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid IntrinsicsRecognizer::Run() {
57071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  for (HReversePostOrderIterator it(*graph_); !it.Done(); it.Advance()) {
57171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    HBasicBlock* block = it.Current();
57271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    for (HInstructionIterator inst_it(block->GetInstructions()); !inst_it.Done();
57371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe         inst_it.Advance()) {
57471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      HInstruction* inst = inst_it.Current();
57571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      if (inst->IsInvoke()) {
57671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe        HInvoke* invoke = inst->AsInvoke();
57771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe        InlineMethod method;
578bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe        const DexFile& dex_file = invoke->GetDexFile();
579bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe        DexFileMethodInliner* inliner = driver_->GetMethodInlinerMap()->GetMethodInliner(&dex_file);
580d5111bf05fc0a9974280a80eeb43db6d5227a81eNicolas Geoffray        DCHECK(inliner != nullptr);
58171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe        if (inliner->IsIntrinsic(invoke->GetDexMethodIndex(), &method)) {
58216ba2b4726cafc2d83cae4a65132aac15f372689Chris Larsen          Intrinsics intrinsic = GetIntrinsic(method);
58371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
58471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          if (intrinsic != Intrinsics::kNone) {
585bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe            if (!CheckInvokeType(intrinsic, invoke, dex_file)) {
586a14b9fef395b94fa9a32147862c198fe7c22e3d7Andreas Gampe              LOG(WARNING) << "Found an intrinsic with unexpected invoke type: "
587bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe                  << intrinsic << " for "
588bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe                  << PrettyMethod(invoke->GetDexMethodIndex(), invoke->GetDexFile())
589bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe                  << invoke->DebugName();
59071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe            } else {
5915d75afe333f57546786686d9bee16b52f1bbe971Aart Bik              invoke->SetIntrinsic(intrinsic,
5925d75afe333f57546786686d9bee16b52f1bbe971Aart Bik                                   NeedsEnvironmentOrCache(intrinsic),
5935d75afe333f57546786686d9bee16b52f1bbe971Aart Bik                                   GetSideEffects(intrinsic),
5945d75afe333f57546786686d9bee16b52f1bbe971Aart Bik                                   GetExceptions(intrinsic));
59538e9e8046ea2196284bdb4638771c31108a30a4aJean-Philippe Halimi              MaybeRecordStat(MethodCompilationStat::kIntrinsicRecognized);
59671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe            }
59771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe          }
59871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe        }
59971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      }
60071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    }
60171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  }
60271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
60371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
60471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampestd::ostream& operator<<(std::ostream& os, const Intrinsics& intrinsic) {
60571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  switch (intrinsic) {
60671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case Intrinsics::kNone:
607109c89a8e3b5023d123f8c1313f5843a0ba2e15eDavid Brazdil      os << "None";
60871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      break;
6095d75afe333f57546786686d9bee16b52f1bbe971Aart Bik#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \
61071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    case Intrinsics::k ## Name: \
61171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      os << # Name; \
61271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      break;
61371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#include "intrinsics_list.h"
61471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas GampeINTRINSICS_LIST(OPTIMIZING_INTRINSICS)
61571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#undef STATIC_INTRINSICS_LIST
61671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#undef VIRTUAL_INTRINSICS_LIST
61771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#undef OPTIMIZING_INTRINSICS
61871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  }
61971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  return os;
62071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
62171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
62271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}  // namespace art
623