interpreter_intrinsics.cc revision 4a4610a438ff2b836f6fe07839a0689ce618863a
178f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee/*
278f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee * Copyright (C) 2017 The Android Open Source Project
378f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee *
478f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee * Licensed under the Apache License, Version 2.0 (the "License");
578f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee * you may not use this file except in compliance with the License.
678f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee * You may obtain a copy of the License at
778f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee *
878f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee *      http://www.apache.org/licenses/LICENSE-2.0
978f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee *
1078f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee * Unless required by applicable law or agreed to in writing, software
1178f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee * distributed under the License is distributed on an "AS IS" BASIS,
1278f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1378f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee * See the License for the specific language governing permissions and
1478f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee * limitations under the License.
1578f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee */
1678f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee
1778f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee#include "interpreter/interpreter_intrinsics.h"
1878f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee
19d9911eeca13f609c885e0f6a5ce81af9b6340bfaAndreas Gampe#include "compiler/intrinsics_enum.h"
20d9911eeca13f609c885e0f6a5ce81af9b6340bfaAndreas Gampe#include "dex_instruction.h"
21d9911eeca13f609c885e0f6a5ce81af9b6340bfaAndreas Gampe#include "interpreter/interpreter_common.h"
22d9911eeca13f609c885e0f6a5ce81af9b6340bfaAndreas Gampe
2378f1bdc6bbf0ac07a333ada2396987e8391eee49buzbeenamespace art {
2478f1bdc6bbf0ac07a333ada2396987e8391eee49buzbeenamespace interpreter {
2578f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee
2631afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
2731afbec96e9f9c8e58778694e74aea7ce55e1378buzbee#define BINARY_INTRINSIC(name, op, get1, get2, set)                 \
2831afbec96e9f9c8e58778694e74aea7ce55e1378buzbeestatic ALWAYS_INLINE bool name(ShadowFrame* shadow_frame,           \
2931afbec96e9f9c8e58778694e74aea7ce55e1378buzbee                               const Instruction* inst,             \
3031afbec96e9f9c8e58778694e74aea7ce55e1378buzbee                               uint16_t inst_data,                  \
3131afbec96e9f9c8e58778694e74aea7ce55e1378buzbee                               JValue* result_register)             \
3231afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    REQUIRES_SHARED(Locks::mutator_lock_) {                         \
3331afbec96e9f9c8e58778694e74aea7ce55e1378buzbee  uint32_t arg[Instruction::kMaxVarArgRegs] = {};                   \
3431afbec96e9f9c8e58778694e74aea7ce55e1378buzbee  inst->GetVarArgs(arg, inst_data);                                 \
3531afbec96e9f9c8e58778694e74aea7ce55e1378buzbee  result_register->set(op(shadow_frame->get1, shadow_frame->get2)); \
3631afbec96e9f9c8e58778694e74aea7ce55e1378buzbee  return true;                                                      \
3778f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee}
3878f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee
3931afbec96e9f9c8e58778694e74aea7ce55e1378buzbee#define BINARY_II_INTRINSIC(name, op, set) \
4031afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    BINARY_INTRINSIC(name, op, GetVReg(arg[0]), GetVReg(arg[1]), set)
4131afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
4231afbec96e9f9c8e58778694e74aea7ce55e1378buzbee#define BINARY_JJ_INTRINSIC(name, op, set) \
4331afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    BINARY_INTRINSIC(name, op, GetVRegLong(arg[0]), GetVRegLong(arg[2]), set)
4431afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
4531afbec96e9f9c8e58778694e74aea7ce55e1378buzbee#define BINARY_JI_INTRINSIC(name, op, set) \
4631afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    BINARY_INTRINSIC(name, op, GetVRegLong(arg[0]), GetVReg(arg[2]), set)
4731afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
4831afbec96e9f9c8e58778694e74aea7ce55e1378buzbee#define UNARY_INTRINSIC(name, op, get, set)                  \
4978f1bdc6bbf0ac07a333ada2396987e8391eee49buzbeestatic ALWAYS_INLINE bool name(ShadowFrame* shadow_frame,    \
5078f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee                               const Instruction* inst,      \
5178f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee                               uint16_t inst_data,           \
5278f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee                               JValue* result_register)      \
5378f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee    REQUIRES_SHARED(Locks::mutator_lock_) {                  \
5478f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee  uint32_t arg[Instruction::kMaxVarArgRegs] = {};            \
5578f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee  inst->GetVarArgs(arg, inst_data);                          \
5678f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee  result_register->set(op(shadow_frame->get(arg[0])));       \
5778f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee  return true;                                               \
5878f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee}
5978f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee
6031afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
6131afbec96e9f9c8e58778694e74aea7ce55e1378buzbee// java.lang.Integer.reverse(I)I
6231afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeUNARY_INTRINSIC(MterpIntegerReverse, ReverseBits32, GetVReg, SetI);
6331afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
6431afbec96e9f9c8e58778694e74aea7ce55e1378buzbee// java.lang.Integer.reverseBytes(I)I
6531afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeUNARY_INTRINSIC(MterpIntegerReverseBytes, BSWAP, GetVReg, SetI);
6631afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
6731afbec96e9f9c8e58778694e74aea7ce55e1378buzbee// java.lang.Integer.bitCount(I)I
6831afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeUNARY_INTRINSIC(MterpIntegerBitCount, POPCOUNT, GetVReg, SetI);
6931afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
7031afbec96e9f9c8e58778694e74aea7ce55e1378buzbee// java.lang.Integer.compare(II)I
7131afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeBINARY_II_INTRINSIC(MterpIntegerCompare, Compare, SetI);
7231afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
7331afbec96e9f9c8e58778694e74aea7ce55e1378buzbee// java.lang.Integer.highestOneBit(I)I
7431afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeUNARY_INTRINSIC(MterpIntegerHighestOneBit, HighestOneBitValue, GetVReg, SetI);
7531afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
7631afbec96e9f9c8e58778694e74aea7ce55e1378buzbee// java.lang.Integer.LowestOneBit(I)I
7731afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeUNARY_INTRINSIC(MterpIntegerLowestOneBit, LowestOneBitValue, GetVReg, SetI);
7831afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
7931afbec96e9f9c8e58778694e74aea7ce55e1378buzbee// java.lang.Integer.numberOfLeadingZeros(I)I
8031afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeUNARY_INTRINSIC(MterpIntegerNumberOfLeadingZeros, JAVASTYLE_CLZ, GetVReg, SetI);
8131afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
8231afbec96e9f9c8e58778694e74aea7ce55e1378buzbee// java.lang.Integer.numberOfTrailingZeros(I)I
8331afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeUNARY_INTRINSIC(MterpIntegerNumberOfTrailingZeros, JAVASTYLE_CTZ, GetVReg, SetI);
8431afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
8531afbec96e9f9c8e58778694e74aea7ce55e1378buzbee// java.lang.Integer.rotateRight(II)I
8631afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeBINARY_II_INTRINSIC(MterpIntegerRotateRight, (Rot<int32_t, false>), SetI);
8731afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
8831afbec96e9f9c8e58778694e74aea7ce55e1378buzbee// java.lang.Integer.rotateLeft(II)I
8931afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeBINARY_II_INTRINSIC(MterpIntegerRotateLeft, (Rot<int32_t, true>), SetI);
9031afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
9131afbec96e9f9c8e58778694e74aea7ce55e1378buzbee// java.lang.Integer.signum(I)I
9231afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeUNARY_INTRINSIC(MterpIntegerSignum, Signum, GetVReg, SetI);
9331afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
9431afbec96e9f9c8e58778694e74aea7ce55e1378buzbee// java.lang.Long.reverse(I)I
9531afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeUNARY_INTRINSIC(MterpLongReverse, ReverseBits64, GetVRegLong, SetJ);
9631afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
9731afbec96e9f9c8e58778694e74aea7ce55e1378buzbee// java.lang.Long.reverseBytes(J)J
9831afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeUNARY_INTRINSIC(MterpLongReverseBytes, BSWAP, GetVRegLong, SetJ);
9931afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
10031afbec96e9f9c8e58778694e74aea7ce55e1378buzbee// java.lang.Long.bitCount(J)I
10131afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeUNARY_INTRINSIC(MterpLongBitCount, POPCOUNT, GetVRegLong, SetI);
10231afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
10331afbec96e9f9c8e58778694e74aea7ce55e1378buzbee// java.lang.Long.compare(JJ)I
10431afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeBINARY_JJ_INTRINSIC(MterpLongCompare, Compare, SetI);
10531afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
10631afbec96e9f9c8e58778694e74aea7ce55e1378buzbee// java.lang.Long.highestOneBit(J)J
10731afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeUNARY_INTRINSIC(MterpLongHighestOneBit, HighestOneBitValue, GetVRegLong, SetJ);
10831afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
10931afbec96e9f9c8e58778694e74aea7ce55e1378buzbee// java.lang.Long.lowestOneBit(J)J
11031afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeUNARY_INTRINSIC(MterpLongLowestOneBit, LowestOneBitValue, GetVRegLong, SetJ);
11131afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
11231afbec96e9f9c8e58778694e74aea7ce55e1378buzbee// java.lang.Long.numberOfLeadingZeros(J)I
11331afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeUNARY_INTRINSIC(MterpLongNumberOfLeadingZeros, JAVASTYLE_CLZ, GetVRegLong, SetJ);
11431afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
11531afbec96e9f9c8e58778694e74aea7ce55e1378buzbee// java.lang.Long.numberOfTrailingZeros(J)I
11631afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeUNARY_INTRINSIC(MterpLongNumberOfTrailingZeros, JAVASTYLE_CTZ, GetVRegLong, SetJ);
11731afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
11831afbec96e9f9c8e58778694e74aea7ce55e1378buzbee// java.lang.Long.rotateRight(JI)J
11931afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeBINARY_JJ_INTRINSIC(MterpLongRotateRight, (Rot<int64_t, false>), SetJ);
12031afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
12131afbec96e9f9c8e58778694e74aea7ce55e1378buzbee// java.lang.Long.rotateLeft(JI)J
12231afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeBINARY_JJ_INTRINSIC(MterpLongRotateLeft, (Rot<int64_t, true>), SetJ);
12331afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
12431afbec96e9f9c8e58778694e74aea7ce55e1378buzbee// java.lang.Long.signum(J)I
12531afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeUNARY_INTRINSIC(MterpLongSignum, Signum, GetVRegLong, SetI);
12631afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
12731afbec96e9f9c8e58778694e74aea7ce55e1378buzbee// java.lang.Short.reverseBytes(S)S
12831afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeUNARY_INTRINSIC(MterpShortReverseBytes, BSWAP, GetVRegShort, SetS);
12931afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
13078f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.min(II)I
13131afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeBINARY_II_INTRINSIC(MterpMathMinIntInt, std::min, SetI);
13231afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
13378f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.min(JJ)J
13431afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeBINARY_JJ_INTRINSIC(MterpMathMinLongLong, std::min, SetJ);
13531afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
13678f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.max(II)I
13731afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeBINARY_II_INTRINSIC(MterpMathMaxIntInt, std::max, SetI);
13831afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
13978f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.max(JJ)J
14031afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeBINARY_JJ_INTRINSIC(MterpMathMaxLongLong, std::max, SetJ);
14131afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
14278f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.abs(I)I
14331afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeUNARY_INTRINSIC(MterpMathAbsInt, std::abs, GetVReg, SetI);
14431afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
14578f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.abs(J)J
14631afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeUNARY_INTRINSIC(MterpMathAbsLong, std::abs, GetVRegLong, SetJ);
14731afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
14878f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.abs(F)F
14931afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeUNARY_INTRINSIC(MterpMathAbsFloat, 0x7fffffff&, GetVReg, SetI);
15031afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
15178f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.abs(D)D
15231afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeUNARY_INTRINSIC(MterpMathAbsDouble, INT64_C(0x7fffffffffffffff)&, GetVRegLong, SetJ);
15331afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
15478f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.sqrt(D)D
15531afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeUNARY_INTRINSIC(MterpMathSqrt, std::sqrt, GetVRegDouble, SetD);
15631afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
15778f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.ceil(D)D
15831afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeUNARY_INTRINSIC(MterpMathCeil, std::ceil, GetVRegDouble, SetD);
15931afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
16078f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.floor(D)D
16131afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeUNARY_INTRINSIC(MterpMathFloor, std::floor, GetVRegDouble, SetD);
16231afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
16378f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.sin(D)D
16431afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeUNARY_INTRINSIC(MterpMathSin, std::sin, GetVRegDouble, SetD);
16531afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
16678f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.cos(D)D
16731afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeUNARY_INTRINSIC(MterpMathCos, std::cos, GetVRegDouble, SetD);
16831afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
16978f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.tan(D)D
17031afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeUNARY_INTRINSIC(MterpMathTan, std::tan, GetVRegDouble, SetD);
17131afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
17278f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.asin(D)D
17331afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeUNARY_INTRINSIC(MterpMathAsin, std::asin, GetVRegDouble, SetD);
17431afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
17578f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.acos(D)D
17631afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeUNARY_INTRINSIC(MterpMathAcos, std::acos, GetVRegDouble, SetD);
17731afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
17878f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.atan(D)D
17931afbec96e9f9c8e58778694e74aea7ce55e1378buzbeeUNARY_INTRINSIC(MterpMathAtan, std::atan, GetVRegDouble, SetD);
18078f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee
181e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee// java.lang.String.charAt(I)C
182e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbeestatic ALWAYS_INLINE bool MterpStringCharAt(ShadowFrame* shadow_frame,
183e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee                                            const Instruction* inst,
184e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee                                            uint16_t inst_data,
185e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee                                            JValue* result_register)
186e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee    REQUIRES_SHARED(Locks::mutator_lock_) {
187e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  uint32_t arg[Instruction::kMaxVarArgRegs] = {};
188e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  inst->GetVarArgs(arg, inst_data);
189e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  mirror::String* str = shadow_frame->GetVRegReference(arg[0])->AsString();
190e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  int length = str->GetLength();
191e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  int index = shadow_frame->GetVReg(arg[1]);
192e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  uint16_t res;
193e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  if (UNLIKELY(index < 0) || (index >= length)) {
194e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee    return false;  // Punt and let non-intrinsic version deal with the throw.
195e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  }
196e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  if (str->IsCompressed()) {
197e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee    res = str->GetValueCompressed()[index];
198e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  } else {
199e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee    res = str->GetValue()[index];
200e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  }
201e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  result_register->SetC(res);
202e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  return true;
203e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee}
204e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee
205e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee// java.lang.String.compareTo(Ljava/lang/string)I
206e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbeestatic ALWAYS_INLINE bool MterpStringCompareTo(ShadowFrame* shadow_frame,
207e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee                                               const Instruction* inst,
208e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee                                               uint16_t inst_data,
209e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee                                               JValue* result_register)
210e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee    REQUIRES_SHARED(Locks::mutator_lock_) {
211e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  uint32_t arg[Instruction::kMaxVarArgRegs] = {};
212e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  inst->GetVarArgs(arg, inst_data);
213e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  mirror::String* str = shadow_frame->GetVRegReference(arg[0])->AsString();
214e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  mirror::Object* arg1 = shadow_frame->GetVRegReference(arg[1]);
215e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  if (arg1 == nullptr) {
216e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee    return false;
217e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  }
218e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  result_register->SetI(str->CompareTo(arg1->AsString()));
219e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  return true;
220e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee}
221e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee
222e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee#define STRING_INDEXOF_INTRINSIC(name, starting_pos)             \
223e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbeestatic ALWAYS_INLINE bool Mterp##name(ShadowFrame* shadow_frame, \
224e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee                                      const Instruction* inst,   \
225e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee                                      uint16_t inst_data,        \
226e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee                                      JValue* result_register)   \
227e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee    REQUIRES_SHARED(Locks::mutator_lock_) {                      \
228e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  uint32_t arg[Instruction::kMaxVarArgRegs] = {};                \
229e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  inst->GetVarArgs(arg, inst_data);                              \
230e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  mirror::String* str = shadow_frame->GetVRegReference(arg[0])->AsString(); \
231e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  int ch = shadow_frame->GetVReg(arg[1]);                        \
232e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  if (ch >= 0x10000) {                                           \
233e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee    /* Punt if supplementary char. */                            \
234e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee    return false;                                                \
235e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  }                                                              \
236e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  result_register->SetI(str->FastIndexOf(ch, starting_pos));     \
237e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  return true;                                                   \
238e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee}
239e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee
240e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee// java.lang.String.indexOf(I)I
241e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbeeSTRING_INDEXOF_INTRINSIC(StringIndexOf, 0);
242e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee
243e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee// java.lang.String.indexOf(II)I
244e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbeeSTRING_INDEXOF_INTRINSIC(StringIndexOfAfter, shadow_frame->GetVReg(arg[2]));
245e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee
246e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee#define SIMPLE_STRING_INTRINSIC(name, operation)                 \
247e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbeestatic ALWAYS_INLINE bool Mterp##name(ShadowFrame* shadow_frame, \
248e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee                                      const Instruction* inst,   \
249e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee                                      uint16_t inst_data,        \
250e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee                                      JValue* result_register)   \
251e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee    REQUIRES_SHARED(Locks::mutator_lock_) {                      \
252e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  uint32_t arg[Instruction::kMaxVarArgRegs] = {};                \
253e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  inst->GetVarArgs(arg, inst_data);                              \
254e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  mirror::String* str = shadow_frame->GetVRegReference(arg[0])->AsString(); \
255e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  result_register->operation;                                    \
256e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  return true;                                                   \
257e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee}
258e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee
259e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee// java.lang.String.isEmpty()Z
260e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbeeSIMPLE_STRING_INTRINSIC(StringIsEmpty, SetZ(str->GetLength() == 0))
261e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee
262e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee// java.lang.String.length()I
263e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbeeSIMPLE_STRING_INTRINSIC(StringLength, SetI(str->GetLength()))
264e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee
265e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee// java.lang.String.getCharsNoCheck(II[CI)V
266e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbeestatic ALWAYS_INLINE bool MterpStringGetCharsNoCheck(ShadowFrame* shadow_frame,
267e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee                                                     const Instruction* inst,
268e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee                                                     uint16_t inst_data,
269e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee                                                     JValue* result_register ATTRIBUTE_UNUSED)
270e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee    REQUIRES_SHARED(Locks::mutator_lock_) {
271e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  // Start, end & index already checked by caller - won't throw.  Destination is uncompressed.
272e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  uint32_t arg[Instruction::kMaxVarArgRegs] = {};
273e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  inst->GetVarArgs(arg, inst_data);
274e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  mirror::String* str = shadow_frame->GetVRegReference(arg[0])->AsString();
275e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  int32_t start = shadow_frame->GetVReg(arg[1]);
276e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  int32_t end = shadow_frame->GetVReg(arg[2]);
277e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  int32_t index = shadow_frame->GetVReg(arg[4]);
278e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  mirror::CharArray* array = shadow_frame->GetVRegReference(arg[3])->AsCharArray();
279e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  uint16_t* dst = array->GetData() + index;
280e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  int32_t len = (end - start);
281e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  if (str->IsCompressed()) {
282e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee    const uint8_t* src_8 = str->GetValueCompressed() + start;
283e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee    for (int i = 0; i < len; i++) {
284e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee      dst[i] = src_8[i];
285e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee    }
286e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  } else {
287e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee    uint16_t* src_16 = str->GetValue() + start;
288e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee    memcpy(dst, src_16, len * sizeof(uint16_t));
289e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  }
290e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  return true;
291e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee}
292e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee
293e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee// java.lang.String.equalsLjava/lang/Object;)Z
294e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbeestatic ALWAYS_INLINE bool MterpStringEquals(ShadowFrame* shadow_frame,
295e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee                                            const Instruction* inst,
296e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee                                            uint16_t inst_data,
297e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee                                            JValue* result_register)
298e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee    REQUIRES_SHARED(Locks::mutator_lock_) {
299e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  uint32_t arg[Instruction::kMaxVarArgRegs] = {};
300e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  inst->GetVarArgs(arg, inst_data);
301e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  mirror::String* str = shadow_frame->GetVRegReference(arg[0])->AsString();
302e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  mirror::Object* obj = shadow_frame->GetVRegReference(arg[1]);
303e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  bool res = false;  // Assume not equal.
304e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  if ((obj != nullptr) && obj->IsString()) {
305e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee    mirror::String* str2 = obj->AsString();
306e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee    if (str->GetCount() == str2->GetCount()) {
307e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee      // Length & compression status are same.  Can use block compare.
308e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee      void* bytes1;
309e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee      void* bytes2;
310e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee      int len = str->GetLength();
311e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee      if (str->IsCompressed()) {
312e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee        bytes1 = str->GetValueCompressed();
313e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee        bytes2 = str2->GetValueCompressed();
314e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee      } else {
315e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee        len *= sizeof(uint16_t);
316e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee        bytes1 = str->GetValue();
317e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee        bytes2 = str2->GetValue();
318e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee      }
319e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee      res = (memcmp(bytes1, bytes2, len) == 0);
320e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee    }
321e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  }
322e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  result_register->SetZ(res);
323e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee  return true;
324e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee}
325e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee
3264a4610a438ff2b836f6fe07839a0689ce618863aOrion Hodson#define VARHANDLE_FENCE_INTRINSIC(name, std_memory_operation)   \
3274a4610a438ff2b836f6fe07839a0689ce618863aOrion Hodsonstatic ALWAYS_INLINE bool name(ShadowFrame* /* shadow_frame */, \
3284a4610a438ff2b836f6fe07839a0689ce618863aOrion Hodson                               const Instruction* /* inst */,   \
3294a4610a438ff2b836f6fe07839a0689ce618863aOrion Hodson                               uint16_t /* inst_data */,        \
3304a4610a438ff2b836f6fe07839a0689ce618863aOrion Hodson                               JValue* /* result_register */)   \
3314a4610a438ff2b836f6fe07839a0689ce618863aOrion Hodson    REQUIRES_SHARED(Locks::mutator_lock_) {                     \
3324a4610a438ff2b836f6fe07839a0689ce618863aOrion Hodson    std::atomic_thread_fence(std_memory_operation);             \
3334a4610a438ff2b836f6fe07839a0689ce618863aOrion Hodson    return true;                                                \
3344a4610a438ff2b836f6fe07839a0689ce618863aOrion Hodson}
3354a4610a438ff2b836f6fe07839a0689ce618863aOrion Hodson
3364a4610a438ff2b836f6fe07839a0689ce618863aOrion Hodson// The VarHandle fence methods are static (unlike sun.misc.Unsafe versions).
3374a4610a438ff2b836f6fe07839a0689ce618863aOrion Hodson// The fences for the LoadLoadFence and StoreStoreFence are stronger
3384a4610a438ff2b836f6fe07839a0689ce618863aOrion Hodson// than strictly required, but the impact should be marginal.
3394a4610a438ff2b836f6fe07839a0689ce618863aOrion HodsonVARHANDLE_FENCE_INTRINSIC(MterpVarHandleFullFence, std::memory_order_seq_cst)
3404a4610a438ff2b836f6fe07839a0689ce618863aOrion HodsonVARHANDLE_FENCE_INTRINSIC(MterpVarHandleAcquireFence, std::memory_order_acquire)
3414a4610a438ff2b836f6fe07839a0689ce618863aOrion HodsonVARHANDLE_FENCE_INTRINSIC(MterpVarHandleReleaseFence, std::memory_order_release)
3424a4610a438ff2b836f6fe07839a0689ce618863aOrion HodsonVARHANDLE_FENCE_INTRINSIC(MterpVarHandleLoadLoadFence, std::memory_order_acquire)
3434a4610a438ff2b836f6fe07839a0689ce618863aOrion HodsonVARHANDLE_FENCE_INTRINSIC(MterpVarHandleStoreStoreFence, std::memory_order_release)
3444a4610a438ff2b836f6fe07839a0689ce618863aOrion Hodson
34531afbec96e9f9c8e58778694e74aea7ce55e1378buzbee// Macro to help keep track of what's left to implement.
34631afbec96e9f9c8e58778694e74aea7ce55e1378buzbee#define UNIMPLEMENTED_CASE(name)    \
34731afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    case Intrinsics::k##name:       \
34831afbec96e9f9c8e58778694e74aea7ce55e1378buzbee      res = false;                  \
34931afbec96e9f9c8e58778694e74aea7ce55e1378buzbee      break;
35031afbec96e9f9c8e58778694e74aea7ce55e1378buzbee
35178f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee#define INTRINSIC_CASE(name)                                           \
35278f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee    case Intrinsics::k##name:                                          \
35378f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee      res = Mterp##name(shadow_frame, inst, inst_data, result_register); \
35478f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee      break;
35578f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee
35678f1bdc6bbf0ac07a333ada2396987e8391eee49buzbeebool MterpHandleIntrinsic(ShadowFrame* shadow_frame,
35778f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee                          ArtMethod* const called_method,
35878f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee                          const Instruction* inst,
35978f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee                          uint16_t inst_data,
36078f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee                          JValue* result_register)
36178f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee    REQUIRES_SHARED(Locks::mutator_lock_) {
36278f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee  Intrinsics intrinsic = static_cast<Intrinsics>(called_method->GetIntrinsic());
36378f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee  bool res = false;  // Assume failure
36478f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee  switch (intrinsic) {
36531afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(DoubleDoubleToRawLongBits /* (D)J */)
36631afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(DoubleDoubleToLongBits /* (D)J */)
36731afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(DoubleIsInfinite /* (D)Z */)
36831afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(DoubleIsNaN /* (D)Z */)
36931afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(DoubleLongBitsToDouble /* (J)D */)
37031afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(FloatFloatToRawIntBits /* (F)I */)
37131afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(FloatFloatToIntBits /* (F)I */)
37231afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(FloatIsInfinite /* (F)Z */)
37331afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(FloatIsNaN /* (F)Z */)
37431afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(FloatIntBitsToFloat /* (I)F */)
37531afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(IntegerReverse)
37631afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(IntegerReverseBytes)
37731afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(IntegerBitCount)
37831afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(IntegerCompare)
37931afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(IntegerHighestOneBit)
38031afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(IntegerLowestOneBit)
38131afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(IntegerNumberOfLeadingZeros)
38231afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(IntegerNumberOfTrailingZeros)
38331afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(IntegerRotateRight)
38431afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(IntegerRotateLeft)
38531afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(IntegerSignum)
38631afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(LongReverse)
38731afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(LongReverseBytes)
38831afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(LongBitCount)
38931afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(LongCompare)
39031afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(LongHighestOneBit)
39131afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(LongLowestOneBit)
39231afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(LongNumberOfLeadingZeros)
39331afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(LongNumberOfTrailingZeros)
39431afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(LongRotateRight)
39531afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(LongRotateLeft)
39631afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(LongSignum)
39731afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(ShortReverseBytes)
39831afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(MathAbsDouble)
39931afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(MathAbsFloat)
40031afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(MathAbsLong)
40131afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(MathAbsInt)
40231afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(MathMinDoubleDouble /* (DD)D */)
40331afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(MathMinFloatFloat /* (FF)F */)
40478f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee    INTRINSIC_CASE(MathMinLongLong)
40531afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(MathMinIntInt)
40631afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(MathMaxDoubleDouble /* (DD)D */)
40731afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(MathMaxFloatFloat /* (FF)F */)
40878f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee    INTRINSIC_CASE(MathMaxLongLong)
40931afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(MathMaxIntInt)
41078f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee    INTRINSIC_CASE(MathCos)
41131afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(MathSin)
41278f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee    INTRINSIC_CASE(MathAcos)
41331afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(MathAsin)
41478f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee    INTRINSIC_CASE(MathAtan)
41531afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(MathAtan2 /* (DD)D */)
41631afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(MathCbrt /* (D)D */)
41731afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(MathCosh /* (D)D */)
41831afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(MathExp /* (D)D */)
41931afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(MathExpm1 /* (D)D */)
42031afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(MathHypot /* (DD)D */)
42131afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(MathLog /* (D)D */)
42231afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(MathLog10 /* (D)D */)
42331afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(MathNextAfter /* (DD)D */)
42431afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(MathSinh /* (D)D */)
42531afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(MathTan)
42631afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(MathTanh /* (D)D */)
42731afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(MathSqrt)
42831afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(MathCeil)
42931afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(MathFloor)
43031afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(MathRint /* (D)D */)
43131afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(MathRoundDouble /* (D)J */)
43231afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(MathRoundFloat /* (F)I */)
43331afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(SystemArrayCopyChar /* ([CI[CII)V */)
43431afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(SystemArrayCopy /* (Ljava/lang/Object;ILjava/lang/Object;II)V */)
43531afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(ThreadCurrentThread /* ()Ljava/lang/Thread; */)
43631afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(MemoryPeekByte /* (J)B */)
43731afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(MemoryPeekIntNative /* (J)I */)
43831afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(MemoryPeekLongNative /* (J)J */)
43931afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(MemoryPeekShortNative /* (J)S */)
44031afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(MemoryPokeByte /* (JB)V */)
44131afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(MemoryPokeIntNative /* (JI)V */)
44231afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(MemoryPokeLongNative /* (JJ)V */)
44331afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(MemoryPokeShortNative /* (JS)V */)
444e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee    INTRINSIC_CASE(StringCharAt)
445e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee    INTRINSIC_CASE(StringCompareTo)
446e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee    INTRINSIC_CASE(StringEquals)
447e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee    INTRINSIC_CASE(StringGetCharsNoCheck)
44831afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(StringIndexOf)
44931afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    INTRINSIC_CASE(StringIndexOfAfter)
45031afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(StringStringIndexOf /* (Ljava/lang/String;)I */)
45131afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(StringStringIndexOfAfter /* (Ljava/lang/String;I)I */)
452e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee    INTRINSIC_CASE(StringIsEmpty)
453e667a3c2e4cae5a977e412a1d80f31a1dc4f3028buzbee    INTRINSIC_CASE(StringLength)
45431afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(StringNewStringFromBytes /* ([BIII)Ljava/lang/String; */)
45531afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(StringNewStringFromChars /* (II[C)Ljava/lang/String; */)
45631afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(StringNewStringFromString /* (Ljava/lang/String;)Ljava/lang/String; */)
45731afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(StringBufferAppend /* (Ljava/lang/String;)Ljava/lang/StringBuffer; */)
45831afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(StringBufferLength /* ()I */)
45931afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(StringBufferToString /* ()Ljava/lang/String; */)
46031afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(StringBuilderAppend /* (Ljava/lang/String;)Ljava/lang/StringBuilder; */)
46131afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(StringBuilderLength /* ()I */)
46231afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(StringBuilderToString /* ()Ljava/lang/String; */)
46331afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(UnsafeCASInt /* (Ljava/lang/Object;JII)Z */)
46431afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(UnsafeCASLong /* (Ljava/lang/Object;JJJ)Z */)
46531afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(UnsafeCASObject /* (Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z */)
46631afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(UnsafeGet /* (Ljava/lang/Object;J)I */)
46731afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(UnsafeGetVolatile /* (Ljava/lang/Object;J)I */)
46831afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(UnsafeGetObject /* (Ljava/lang/Object;J)Ljava/lang/Object; */)
46931afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(UnsafeGetObjectVolatile /* (Ljava/lang/Object;J)Ljava/lang/Object; */)
47031afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(UnsafeGetLong /* (Ljava/lang/Object;J)J */)
47131afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(UnsafeGetLongVolatile /* (Ljava/lang/Object;J)J */)
47231afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(UnsafePut /* (Ljava/lang/Object;JI)V */)
47331afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(UnsafePutOrdered /* (Ljava/lang/Object;JI)V */)
47431afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(UnsafePutVolatile /* (Ljava/lang/Object;JI)V */)
47531afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(UnsafePutObject /* (Ljava/lang/Object;JLjava/lang/Object;)V */)
47631afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(UnsafePutObjectOrdered /* (Ljava/lang/Object;JLjava/lang/Object;)V */)
47731afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(UnsafePutObjectVolatile /* (Ljava/lang/Object;JLjava/lang/Object;)V */)
47831afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(UnsafePutLong /* (Ljava/lang/Object;JJ)V */)
47931afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(UnsafePutLongOrdered /* (Ljava/lang/Object;JJ)V */)
48031afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(UnsafePutLongVolatile /* (Ljava/lang/Object;JJ)V */)
48131afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(UnsafeGetAndAddInt /* (Ljava/lang/Object;JI)I */)
48231afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(UnsafeGetAndAddLong /* (Ljava/lang/Object;JJ)J */)
48331afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(UnsafeGetAndSetInt /* (Ljava/lang/Object;JI)I */)
48431afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(UnsafeGetAndSetLong /* (Ljava/lang/Object;JJ)J */)
48531afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(UnsafeGetAndSetObject /* (Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object; */)
48631afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(UnsafeLoadFence /* ()V */)
48731afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(UnsafeStoreFence /* ()V */)
48831afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(UnsafeFullFence /* ()V */)
48931afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(ReferenceGetReferent /* ()Ljava/lang/Object; */)
49031afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    UNIMPLEMENTED_CASE(IntegerValueOf /* (I)Ljava/lang/Integer; */)
491365719c23d809e595cf320bfba40e76bb4e87940Nicolas Geoffray    UNIMPLEMENTED_CASE(ThreadInterrupted /* ()Z */)
4924a4610a438ff2b836f6fe07839a0689ce618863aOrion Hodson    INTRINSIC_CASE(VarHandleFullFence)
4934a4610a438ff2b836f6fe07839a0689ce618863aOrion Hodson    INTRINSIC_CASE(VarHandleAcquireFence)
4944a4610a438ff2b836f6fe07839a0689ce618863aOrion Hodson    INTRINSIC_CASE(VarHandleReleaseFence)
4954a4610a438ff2b836f6fe07839a0689ce618863aOrion Hodson    INTRINSIC_CASE(VarHandleLoadLoadFence)
4964a4610a438ff2b836f6fe07839a0689ce618863aOrion Hodson    INTRINSIC_CASE(VarHandleStoreStoreFence)
49731afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    case Intrinsics::kNone:
49831afbec96e9f9c8e58778694e74aea7ce55e1378buzbee      res = false;
49978f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee      break;
50031afbec96e9f9c8e58778694e74aea7ce55e1378buzbee    // Note: no default case to ensure we catch any newly added intrinsics.
50178f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee  }
50278f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee  return res;
50378f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee}
50478f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee
50578f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee}  // namespace interpreter
50678f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee}  // namespace art
507