1 /*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "interpreter/interpreter_intrinsics.h"
18
19 #include "dex/dex_instruction.h"
20 #include "intrinsics_enum.h"
21 #include "interpreter/interpreter_common.h"
22
23 namespace art {
24 namespace interpreter {
25
26
27 #define BINARY_INTRINSIC(name, op, get1, get2, set) \
28 static ALWAYS_INLINE bool name(ShadowFrame* shadow_frame, \
29 const Instruction* inst, \
30 uint16_t inst_data, \
31 JValue* result_register) \
32 REQUIRES_SHARED(Locks::mutator_lock_) { \
33 uint32_t arg[Instruction::kMaxVarArgRegs] = {}; \
34 inst->GetVarArgs(arg, inst_data); \
35 result_register->set(op(shadow_frame->get1, shadow_frame->get2)); \
36 return true; \
37 }
38
39 #define BINARY_II_INTRINSIC(name, op, set) \
40 BINARY_INTRINSIC(name, op, GetVReg(arg[0]), GetVReg(arg[1]), set)
41
42 #define BINARY_JJ_INTRINSIC(name, op, set) \
43 BINARY_INTRINSIC(name, op, GetVRegLong(arg[0]), GetVRegLong(arg[2]), set)
44
45 #define BINARY_JI_INTRINSIC(name, op, set) \
46 BINARY_INTRINSIC(name, op, GetVRegLong(arg[0]), GetVReg(arg[2]), set)
47
48 #define UNARY_INTRINSIC(name, op, get, set) \
49 static ALWAYS_INLINE bool name(ShadowFrame* shadow_frame, \
50 const Instruction* inst, \
51 uint16_t inst_data, \
52 JValue* result_register) \
53 REQUIRES_SHARED(Locks::mutator_lock_) { \
54 uint32_t arg[Instruction::kMaxVarArgRegs] = {}; \
55 inst->GetVarArgs(arg, inst_data); \
56 result_register->set(op(shadow_frame->get(arg[0]))); \
57 return true; \
58 }
59
60
61 // java.lang.Integer.reverse(I)I
62 UNARY_INTRINSIC(MterpIntegerReverse, ReverseBits32, GetVReg, SetI);
63
64 // java.lang.Integer.reverseBytes(I)I
65 UNARY_INTRINSIC(MterpIntegerReverseBytes, BSWAP, GetVReg, SetI);
66
67 // java.lang.Integer.bitCount(I)I
68 UNARY_INTRINSIC(MterpIntegerBitCount, POPCOUNT, GetVReg, SetI);
69
70 // java.lang.Integer.compare(II)I
71 BINARY_II_INTRINSIC(MterpIntegerCompare, Compare, SetI);
72
73 // java.lang.Integer.highestOneBit(I)I
74 UNARY_INTRINSIC(MterpIntegerHighestOneBit, HighestOneBitValue, GetVReg, SetI);
75
76 // java.lang.Integer.LowestOneBit(I)I
77 UNARY_INTRINSIC(MterpIntegerLowestOneBit, LowestOneBitValue, GetVReg, SetI);
78
79 // java.lang.Integer.numberOfLeadingZeros(I)I
80 UNARY_INTRINSIC(MterpIntegerNumberOfLeadingZeros, JAVASTYLE_CLZ, GetVReg, SetI);
81
82 // java.lang.Integer.numberOfTrailingZeros(I)I
83 UNARY_INTRINSIC(MterpIntegerNumberOfTrailingZeros, JAVASTYLE_CTZ, GetVReg, SetI);
84
85 // java.lang.Integer.rotateRight(II)I
86 BINARY_II_INTRINSIC(MterpIntegerRotateRight, (Rot<int32_t, false>), SetI);
87
88 // java.lang.Integer.rotateLeft(II)I
89 BINARY_II_INTRINSIC(MterpIntegerRotateLeft, (Rot<int32_t, true>), SetI);
90
91 // java.lang.Integer.signum(I)I
92 UNARY_INTRINSIC(MterpIntegerSignum, Signum, GetVReg, SetI);
93
94 // java.lang.Long.reverse(J)J
95 UNARY_INTRINSIC(MterpLongReverse, ReverseBits64, GetVRegLong, SetJ);
96
97 // java.lang.Long.reverseBytes(J)J
98 UNARY_INTRINSIC(MterpLongReverseBytes, BSWAP, GetVRegLong, SetJ);
99
100 // java.lang.Long.bitCount(J)I
101 UNARY_INTRINSIC(MterpLongBitCount, POPCOUNT, GetVRegLong, SetI);
102
103 // java.lang.Long.compare(JJ)I
104 BINARY_JJ_INTRINSIC(MterpLongCompare, Compare, SetI);
105
106 // java.lang.Long.highestOneBit(J)J
107 UNARY_INTRINSIC(MterpLongHighestOneBit, HighestOneBitValue, GetVRegLong, SetJ);
108
109 // java.lang.Long.lowestOneBit(J)J
110 UNARY_INTRINSIC(MterpLongLowestOneBit, LowestOneBitValue, GetVRegLong, SetJ);
111
112 // java.lang.Long.numberOfLeadingZeros(J)I
113 UNARY_INTRINSIC(MterpLongNumberOfLeadingZeros, JAVASTYLE_CLZ, GetVRegLong, SetJ);
114
115 // java.lang.Long.numberOfTrailingZeros(J)I
116 UNARY_INTRINSIC(MterpLongNumberOfTrailingZeros, JAVASTYLE_CTZ, GetVRegLong, SetJ);
117
118 // java.lang.Long.rotateRight(JI)J
119 BINARY_JI_INTRINSIC(MterpLongRotateRight, (Rot<int64_t, false>), SetJ);
120
121 // java.lang.Long.rotateLeft(JI)J
122 BINARY_JI_INTRINSIC(MterpLongRotateLeft, (Rot<int64_t, true>), SetJ);
123
124 // java.lang.Long.signum(J)I
125 UNARY_INTRINSIC(MterpLongSignum, Signum, GetVRegLong, SetI);
126
127 // java.lang.Short.reverseBytes(S)S
128 UNARY_INTRINSIC(MterpShortReverseBytes, BSWAP, GetVRegShort, SetS);
129
130 // java.lang.Math.min(II)I
131 BINARY_II_INTRINSIC(MterpMathMinIntInt, std::min, SetI);
132
133 // java.lang.Math.min(JJ)J
134 BINARY_JJ_INTRINSIC(MterpMathMinLongLong, std::min, SetJ);
135
136 // java.lang.Math.max(II)I
137 BINARY_II_INTRINSIC(MterpMathMaxIntInt, std::max, SetI);
138
139 // java.lang.Math.max(JJ)J
140 BINARY_JJ_INTRINSIC(MterpMathMaxLongLong, std::max, SetJ);
141
142 // java.lang.Math.abs(I)I
143 UNARY_INTRINSIC(MterpMathAbsInt, std::abs, GetVReg, SetI);
144
145 // java.lang.Math.abs(J)J
146 UNARY_INTRINSIC(MterpMathAbsLong, std::abs, GetVRegLong, SetJ);
147
148 // java.lang.Math.abs(F)F
149 UNARY_INTRINSIC(MterpMathAbsFloat, 0x7fffffff&, GetVReg, SetI);
150
151 // java.lang.Math.abs(D)D
152 UNARY_INTRINSIC(MterpMathAbsDouble, INT64_C(0x7fffffffffffffff)&, GetVRegLong, SetJ);
153
154 // java.lang.Math.sqrt(D)D
155 UNARY_INTRINSIC(MterpMathSqrt, std::sqrt, GetVRegDouble, SetD);
156
157 // java.lang.Math.ceil(D)D
158 UNARY_INTRINSIC(MterpMathCeil, std::ceil, GetVRegDouble, SetD);
159
160 // java.lang.Math.floor(D)D
161 UNARY_INTRINSIC(MterpMathFloor, std::floor, GetVRegDouble, SetD);
162
163 // java.lang.Math.sin(D)D
164 UNARY_INTRINSIC(MterpMathSin, std::sin, GetVRegDouble, SetD);
165
166 // java.lang.Math.cos(D)D
167 UNARY_INTRINSIC(MterpMathCos, std::cos, GetVRegDouble, SetD);
168
169 // java.lang.Math.tan(D)D
170 UNARY_INTRINSIC(MterpMathTan, std::tan, GetVRegDouble, SetD);
171
172 // java.lang.Math.asin(D)D
173 UNARY_INTRINSIC(MterpMathAsin, std::asin, GetVRegDouble, SetD);
174
175 // java.lang.Math.acos(D)D
176 UNARY_INTRINSIC(MterpMathAcos, std::acos, GetVRegDouble, SetD);
177
178 // java.lang.Math.atan(D)D
179 UNARY_INTRINSIC(MterpMathAtan, std::atan, GetVRegDouble, SetD);
180
181 // java.lang.String.charAt(I)C
MterpStringCharAt(ShadowFrame * shadow_frame,const Instruction * inst,uint16_t inst_data,JValue * result_register)182 static ALWAYS_INLINE bool MterpStringCharAt(ShadowFrame* shadow_frame,
183 const Instruction* inst,
184 uint16_t inst_data,
185 JValue* result_register)
186 REQUIRES_SHARED(Locks::mutator_lock_) {
187 uint32_t arg[Instruction::kMaxVarArgRegs] = {};
188 inst->GetVarArgs(arg, inst_data);
189 ObjPtr<mirror::String> str = shadow_frame->GetVRegReference(arg[0])->AsString();
190 int length = str->GetLength();
191 int index = shadow_frame->GetVReg(arg[1]);
192 uint16_t res;
193 if (UNLIKELY(index < 0) || (index >= length)) {
194 return false; // Punt and let non-intrinsic version deal with the throw.
195 }
196 if (str->IsCompressed()) {
197 res = str->GetValueCompressed()[index];
198 } else {
199 res = str->GetValue()[index];
200 }
201 result_register->SetC(res);
202 return true;
203 }
204
205 // java.lang.String.compareTo(Ljava/lang/string)I
MterpStringCompareTo(ShadowFrame * shadow_frame,const Instruction * inst,uint16_t inst_data,JValue * result_register)206 static ALWAYS_INLINE bool MterpStringCompareTo(ShadowFrame* shadow_frame,
207 const Instruction* inst,
208 uint16_t inst_data,
209 JValue* result_register)
210 REQUIRES_SHARED(Locks::mutator_lock_) {
211 uint32_t arg[Instruction::kMaxVarArgRegs] = {};
212 inst->GetVarArgs(arg, inst_data);
213 ObjPtr<mirror::String> str = shadow_frame->GetVRegReference(arg[0])->AsString();
214 ObjPtr<mirror::Object> arg1 = shadow_frame->GetVRegReference(arg[1]);
215 if (arg1 == nullptr) {
216 return false;
217 }
218 result_register->SetI(str->CompareTo(arg1->AsString()));
219 return true;
220 }
221
222 #define STRING_INDEXOF_INTRINSIC(name, starting_pos) \
223 static ALWAYS_INLINE bool Mterp##name(ShadowFrame* shadow_frame, \
224 const Instruction* inst, \
225 uint16_t inst_data, \
226 JValue* result_register) \
227 REQUIRES_SHARED(Locks::mutator_lock_) { \
228 uint32_t arg[Instruction::kMaxVarArgRegs] = {}; \
229 inst->GetVarArgs(arg, inst_data); \
230 ObjPtr<mirror::String> str = shadow_frame->GetVRegReference(arg[0])->AsString(); \
231 int ch = shadow_frame->GetVReg(arg[1]); \
232 if (ch >= 0x10000) { \
233 /* Punt if supplementary char. */ \
234 return false; \
235 } \
236 result_register->SetI(str->FastIndexOf(ch, starting_pos)); \
237 return true; \
238 }
239
240 // java.lang.String.indexOf(I)I
241 STRING_INDEXOF_INTRINSIC(StringIndexOf, 0);
242
243 // java.lang.String.indexOf(II)I
244 STRING_INDEXOF_INTRINSIC(StringIndexOfAfter, shadow_frame->GetVReg(arg[2]));
245
246 #define SIMPLE_STRING_INTRINSIC(name, operation) \
247 static ALWAYS_INLINE bool Mterp##name(ShadowFrame* shadow_frame, \
248 const Instruction* inst, \
249 uint16_t inst_data, \
250 JValue* result_register) \
251 REQUIRES_SHARED(Locks::mutator_lock_) { \
252 uint32_t arg[Instruction::kMaxVarArgRegs] = {}; \
253 inst->GetVarArgs(arg, inst_data); \
254 ObjPtr<mirror::String> str = shadow_frame->GetVRegReference(arg[0])->AsString(); \
255 result_register->operation; \
256 return true; \
257 }
258
259 // java.lang.String.isEmpty()Z
260 SIMPLE_STRING_INTRINSIC(StringIsEmpty, SetZ(str->GetLength() == 0))
261
262 // java.lang.String.length()I
263 SIMPLE_STRING_INTRINSIC(StringLength, SetI(str->GetLength()))
264
265 // java.lang.String.getCharsNoCheck(II[CI)V
MterpStringGetCharsNoCheck(ShadowFrame * shadow_frame,const Instruction * inst,uint16_t inst_data,JValue * result_register ATTRIBUTE_UNUSED)266 static ALWAYS_INLINE bool MterpStringGetCharsNoCheck(ShadowFrame* shadow_frame,
267 const Instruction* inst,
268 uint16_t inst_data,
269 JValue* result_register ATTRIBUTE_UNUSED)
270 REQUIRES_SHARED(Locks::mutator_lock_) {
271 // Start, end & index already checked by caller - won't throw. Destination is uncompressed.
272 uint32_t arg[Instruction::kMaxVarArgRegs] = {};
273 inst->GetVarArgs(arg, inst_data);
274 ObjPtr<mirror::String> str = shadow_frame->GetVRegReference(arg[0])->AsString();
275 int32_t start = shadow_frame->GetVReg(arg[1]);
276 int32_t end = shadow_frame->GetVReg(arg[2]);
277 int32_t index = shadow_frame->GetVReg(arg[4]);
278 ObjPtr<mirror::CharArray> array = shadow_frame->GetVRegReference(arg[3])->AsCharArray();
279 uint16_t* dst = array->GetData() + index;
280 int32_t len = (end - start);
281 if (str->IsCompressed()) {
282 const uint8_t* src_8 = str->GetValueCompressed() + start;
283 for (int i = 0; i < len; i++) {
284 dst[i] = src_8[i];
285 }
286 } else {
287 uint16_t* src_16 = str->GetValue() + start;
288 memcpy(dst, src_16, len * sizeof(uint16_t));
289 }
290 return true;
291 }
292
293 // java.lang.String.equalsLjava/lang/Object;)Z
MterpStringEquals(ShadowFrame * shadow_frame,const Instruction * inst,uint16_t inst_data,JValue * result_register)294 static ALWAYS_INLINE bool MterpStringEquals(ShadowFrame* shadow_frame,
295 const Instruction* inst,
296 uint16_t inst_data,
297 JValue* result_register)
298 REQUIRES_SHARED(Locks::mutator_lock_) {
299 uint32_t arg[Instruction::kMaxVarArgRegs] = {};
300 inst->GetVarArgs(arg, inst_data);
301 ObjPtr<mirror::String> str = shadow_frame->GetVRegReference(arg[0])->AsString();
302 ObjPtr<mirror::Object> obj = shadow_frame->GetVRegReference(arg[1]);
303 bool res = false; // Assume not equal.
304 if ((obj != nullptr) && obj->IsString()) {
305 ObjPtr<mirror::String> str2 = obj->AsString();
306 if (str->GetCount() == str2->GetCount()) {
307 // Length & compression status are same. Can use block compare.
308 void* bytes1;
309 void* bytes2;
310 int len = str->GetLength();
311 if (str->IsCompressed()) {
312 bytes1 = str->GetValueCompressed();
313 bytes2 = str2->GetValueCompressed();
314 } else {
315 len *= sizeof(uint16_t);
316 bytes1 = str->GetValue();
317 bytes2 = str2->GetValue();
318 }
319 res = (memcmp(bytes1, bytes2, len) == 0);
320 }
321 }
322 result_register->SetZ(res);
323 return true;
324 }
325
326 #define VARHANDLE_FENCE_INTRINSIC(name, std_memory_operation) \
327 static ALWAYS_INLINE bool name(ShadowFrame* shadow_frame ATTRIBUTE_UNUSED, \
328 const Instruction* inst ATTRIBUTE_UNUSED, \
329 uint16_t inst_data ATTRIBUTE_UNUSED, \
330 JValue* result_register ATTRIBUTE_UNUSED) \
331 REQUIRES_SHARED(Locks::mutator_lock_) { \
332 std::atomic_thread_fence(std_memory_operation); \
333 return true; \
334 }
335
336 // The VarHandle fence methods are static (unlike sun.misc.Unsafe versions).
337 // The fences for the LoadLoadFence and StoreStoreFence are stronger
338 // than strictly required, but the impact should be marginal.
339 VARHANDLE_FENCE_INTRINSIC(MterpVarHandleFullFence, std::memory_order_seq_cst)
340 VARHANDLE_FENCE_INTRINSIC(MterpVarHandleAcquireFence, std::memory_order_acquire)
341 VARHANDLE_FENCE_INTRINSIC(MterpVarHandleReleaseFence, std::memory_order_release)
342 VARHANDLE_FENCE_INTRINSIC(MterpVarHandleLoadLoadFence, std::memory_order_acquire)
343 VARHANDLE_FENCE_INTRINSIC(MterpVarHandleStoreStoreFence, std::memory_order_release)
344
345 #define METHOD_HANDLE_INVOKE_INTRINSIC(name) \
346 static ALWAYS_INLINE bool Mterp##name(ShadowFrame* shadow_frame, \
347 const Instruction* inst, \
348 uint16_t inst_data, \
349 JValue* result) \
350 REQUIRES_SHARED(Locks::mutator_lock_) { \
351 if (inst->Opcode() == Instruction::INVOKE_POLYMORPHIC) { \
352 return DoInvokePolymorphic<false>(Thread::Current(), *shadow_frame, inst, inst_data, result); \
353 } else { \
354 return DoInvokePolymorphic<true>(Thread::Current(), *shadow_frame, inst, inst_data, result); \
355 } \
356 }
357
358 METHOD_HANDLE_INVOKE_INTRINSIC(MethodHandleInvokeExact)
359 METHOD_HANDLE_INVOKE_INTRINSIC(MethodHandleInvoke)
360
361 #define VAR_HANDLE_ACCESSOR_INTRINSIC(name) \
362 static ALWAYS_INLINE bool Mterp##name(ShadowFrame* shadow_frame, \
363 const Instruction* inst, \
364 uint16_t inst_data, \
365 JValue* result) \
366 REQUIRES_SHARED(Locks::mutator_lock_) { \
367 return Do##name(Thread::Current(), *shadow_frame, inst, inst_data, result); \
368 }
369
370 VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleCompareAndExchange)
371 VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleCompareAndExchangeAcquire)
372 VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleCompareAndExchangeRelease)
373 VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleCompareAndSet)
374 VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleGet);
375 VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleGetAcquire)
VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleGetAndAdd)376 VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleGetAndAdd)
377 VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleGetAndAddAcquire)
378 VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleGetAndAddRelease)
379 VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleGetAndBitwiseAnd)
380 VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleGetAndBitwiseAndAcquire)
381 VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleGetAndBitwiseAndRelease)
382 VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleGetAndBitwiseOr)
383 VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleGetAndBitwiseOrAcquire)
384 VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleGetAndBitwiseOrRelease)
385 VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleGetAndBitwiseXor)
386 VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleGetAndBitwiseXorAcquire)
387 VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleGetAndBitwiseXorRelease)
388 VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleGetAndSet)
389 VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleGetAndSetAcquire)
390 VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleGetAndSetRelease)
391 VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleGetOpaque)
392 VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleGetVolatile)
393 VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleSet)
394 VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleSetOpaque)
395 VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleSetRelease)
396 VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleSetVolatile)
397 VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleWeakCompareAndSet)
398 VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleWeakCompareAndSetAcquire)
399 VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleWeakCompareAndSetPlain)
400 VAR_HANDLE_ACCESSOR_INTRINSIC(VarHandleWeakCompareAndSetRelease)
401
402 static ALWAYS_INLINE bool MterpReachabilityFence(ShadowFrame* shadow_frame ATTRIBUTE_UNUSED,
403 const Instruction* inst ATTRIBUTE_UNUSED,
404 uint16_t inst_data ATTRIBUTE_UNUSED,
405 JValue* result_register ATTRIBUTE_UNUSED)
406 REQUIRES_SHARED(Locks::mutator_lock_) {
407 // Do nothing; Its only purpose is to keep the argument reference live
408 // at preceding suspend points. That's automatic in the interpreter.
409 return true;
410 }
411
412 // Macro to help keep track of what's left to implement.
413 #define UNIMPLEMENTED_CASE(name) \
414 case Intrinsics::k##name: \
415 res = false; \
416 break;
417
418 #define INTRINSIC_CASE(name) \
419 case Intrinsics::k##name: \
420 res = Mterp##name(shadow_frame, inst, inst_data, result_register); \
421 break;
422
MterpHandleIntrinsic(ShadowFrame * shadow_frame,ArtMethod * const called_method,const Instruction * inst,uint16_t inst_data,JValue * result_register)423 bool MterpHandleIntrinsic(ShadowFrame* shadow_frame,
424 ArtMethod* const called_method,
425 const Instruction* inst,
426 uint16_t inst_data,
427 JValue* result_register)
428 REQUIRES_SHARED(Locks::mutator_lock_) {
429 Intrinsics intrinsic = static_cast<Intrinsics>(called_method->GetIntrinsic());
430 bool res = false; // Assume failure
431 switch (intrinsic) {
432 UNIMPLEMENTED_CASE(DoubleDoubleToRawLongBits /* (D)J */)
433 UNIMPLEMENTED_CASE(DoubleDoubleToLongBits /* (D)J */)
434 UNIMPLEMENTED_CASE(DoubleIsInfinite /* (D)Z */)
435 UNIMPLEMENTED_CASE(DoubleIsNaN /* (D)Z */)
436 UNIMPLEMENTED_CASE(DoubleLongBitsToDouble /* (J)D */)
437 UNIMPLEMENTED_CASE(FloatFloatToRawIntBits /* (F)I */)
438 UNIMPLEMENTED_CASE(FloatFloatToIntBits /* (F)I */)
439 UNIMPLEMENTED_CASE(FloatIsInfinite /* (F)Z */)
440 UNIMPLEMENTED_CASE(FloatIsNaN /* (F)Z */)
441 UNIMPLEMENTED_CASE(FloatIntBitsToFloat /* (I)F */)
442 UNIMPLEMENTED_CASE(IntegerDivideUnsigned /* (II)I */)
443 UNIMPLEMENTED_CASE(LongDivideUnsigned /* (JJ)J */)
444 INTRINSIC_CASE(IntegerReverse)
445 INTRINSIC_CASE(IntegerReverseBytes)
446 INTRINSIC_CASE(IntegerBitCount)
447 INTRINSIC_CASE(IntegerCompare)
448 INTRINSIC_CASE(IntegerHighestOneBit)
449 INTRINSIC_CASE(IntegerLowestOneBit)
450 INTRINSIC_CASE(IntegerNumberOfLeadingZeros)
451 INTRINSIC_CASE(IntegerNumberOfTrailingZeros)
452 INTRINSIC_CASE(IntegerRotateRight)
453 INTRINSIC_CASE(IntegerRotateLeft)
454 INTRINSIC_CASE(IntegerSignum)
455 INTRINSIC_CASE(LongReverse)
456 INTRINSIC_CASE(LongReverseBytes)
457 INTRINSIC_CASE(LongBitCount)
458 INTRINSIC_CASE(LongCompare)
459 INTRINSIC_CASE(LongHighestOneBit)
460 INTRINSIC_CASE(LongLowestOneBit)
461 INTRINSIC_CASE(LongNumberOfLeadingZeros)
462 INTRINSIC_CASE(LongNumberOfTrailingZeros)
463 INTRINSIC_CASE(LongRotateRight)
464 INTRINSIC_CASE(LongRotateLeft)
465 INTRINSIC_CASE(LongSignum)
466 INTRINSIC_CASE(ShortReverseBytes)
467 INTRINSIC_CASE(MathAbsDouble)
468 INTRINSIC_CASE(MathAbsFloat)
469 INTRINSIC_CASE(MathAbsLong)
470 INTRINSIC_CASE(MathAbsInt)
471 UNIMPLEMENTED_CASE(MathMinDoubleDouble /* (DD)D */)
472 UNIMPLEMENTED_CASE(MathMinFloatFloat /* (FF)F */)
473 INTRINSIC_CASE(MathMinLongLong)
474 INTRINSIC_CASE(MathMinIntInt)
475 UNIMPLEMENTED_CASE(MathMaxDoubleDouble /* (DD)D */)
476 UNIMPLEMENTED_CASE(MathMaxFloatFloat /* (FF)F */)
477 INTRINSIC_CASE(MathMaxLongLong)
478 INTRINSIC_CASE(MathMaxIntInt)
479 INTRINSIC_CASE(MathCos)
480 INTRINSIC_CASE(MathSin)
481 INTRINSIC_CASE(MathAcos)
482 INTRINSIC_CASE(MathAsin)
483 INTRINSIC_CASE(MathAtan)
484 UNIMPLEMENTED_CASE(MathAtan2 /* (DD)D */)
485 UNIMPLEMENTED_CASE(MathCbrt /* (D)D */)
486 UNIMPLEMENTED_CASE(MathCosh /* (D)D */)
487 UNIMPLEMENTED_CASE(MathExp /* (D)D */)
488 UNIMPLEMENTED_CASE(MathExpm1 /* (D)D */)
489 UNIMPLEMENTED_CASE(MathHypot /* (DD)D */)
490 UNIMPLEMENTED_CASE(MathLog /* (D)D */)
491 UNIMPLEMENTED_CASE(MathLog10 /* (D)D */)
492 UNIMPLEMENTED_CASE(MathNextAfter /* (DD)D */)
493 UNIMPLEMENTED_CASE(MathPow /* (DD)D */)
494 UNIMPLEMENTED_CASE(MathSinh /* (D)D */)
495 INTRINSIC_CASE(MathTan)
496 UNIMPLEMENTED_CASE(MathTanh /* (D)D */)
497 INTRINSIC_CASE(MathSqrt)
498 INTRINSIC_CASE(MathCeil)
499 INTRINSIC_CASE(MathFloor)
500 UNIMPLEMENTED_CASE(MathRint /* (D)D */)
501 UNIMPLEMENTED_CASE(MathRoundDouble /* (D)J */)
502 UNIMPLEMENTED_CASE(MathRoundFloat /* (F)I */)
503 UNIMPLEMENTED_CASE(MathMultiplyHigh /* (JJ)J */)
504 UNIMPLEMENTED_CASE(SystemArrayCopyChar /* ([CI[CII)V */)
505 UNIMPLEMENTED_CASE(SystemArrayCopy /* (Ljava/lang/Object;ILjava/lang/Object;II)V */)
506 UNIMPLEMENTED_CASE(ThreadCurrentThread /* ()Ljava/lang/Thread; */)
507 UNIMPLEMENTED_CASE(MemoryPeekByte /* (J)B */)
508 UNIMPLEMENTED_CASE(MemoryPeekIntNative /* (J)I */)
509 UNIMPLEMENTED_CASE(MemoryPeekLongNative /* (J)J */)
510 UNIMPLEMENTED_CASE(MemoryPeekShortNative /* (J)S */)
511 UNIMPLEMENTED_CASE(MemoryPokeByte /* (JB)V */)
512 UNIMPLEMENTED_CASE(MemoryPokeIntNative /* (JI)V */)
513 UNIMPLEMENTED_CASE(MemoryPokeLongNative /* (JJ)V */)
514 UNIMPLEMENTED_CASE(MemoryPokeShortNative /* (JS)V */)
515 INTRINSIC_CASE(ReachabilityFence /* (Ljava/lang/Object;)V */)
516 INTRINSIC_CASE(StringCharAt)
517 INTRINSIC_CASE(StringCompareTo)
518 INTRINSIC_CASE(StringEquals)
519 INTRINSIC_CASE(StringGetCharsNoCheck)
520 INTRINSIC_CASE(StringIndexOf)
521 INTRINSIC_CASE(StringIndexOfAfter)
522 UNIMPLEMENTED_CASE(StringStringIndexOf /* (Ljava/lang/String;)I */)
523 UNIMPLEMENTED_CASE(StringStringIndexOfAfter /* (Ljava/lang/String;I)I */)
524 INTRINSIC_CASE(StringIsEmpty)
525 INTRINSIC_CASE(StringLength)
526 UNIMPLEMENTED_CASE(StringNewStringFromBytes /* ([BIII)Ljava/lang/String; */)
527 UNIMPLEMENTED_CASE(StringNewStringFromChars /* (II[C)Ljava/lang/String; */)
528 UNIMPLEMENTED_CASE(StringNewStringFromString /* (Ljava/lang/String;)Ljava/lang/String; */)
529 UNIMPLEMENTED_CASE(StringBufferAppend /* (Ljava/lang/String;)Ljava/lang/StringBuffer; */)
530 UNIMPLEMENTED_CASE(StringBufferLength /* ()I */)
531 UNIMPLEMENTED_CASE(StringBufferToString /* ()Ljava/lang/String; */)
532 UNIMPLEMENTED_CASE(
533 StringBuilderAppendObject /* (Ljava/lang/Object;)Ljava/lang/StringBuilder; */)
534 UNIMPLEMENTED_CASE(
535 StringBuilderAppendString /* (Ljava/lang/String;)Ljava/lang/StringBuilder; */)
536 UNIMPLEMENTED_CASE(
537 StringBuilderAppendCharSequence /* (Ljava/lang/CharSequence;)Ljava/lang/StringBuilder; */)
538 UNIMPLEMENTED_CASE(StringBuilderAppendCharArray /* ([C)Ljava/lang/StringBuilder; */)
539 UNIMPLEMENTED_CASE(StringBuilderAppendBoolean /* (Z)Ljava/lang/StringBuilder; */)
540 UNIMPLEMENTED_CASE(StringBuilderAppendChar /* (C)Ljava/lang/StringBuilder; */)
541 UNIMPLEMENTED_CASE(StringBuilderAppendInt /* (I)Ljava/lang/StringBuilder; */)
542 UNIMPLEMENTED_CASE(StringBuilderAppendLong /* (J)Ljava/lang/StringBuilder; */)
543 UNIMPLEMENTED_CASE(StringBuilderAppendFloat /* (F)Ljava/lang/StringBuilder; */)
544 UNIMPLEMENTED_CASE(StringBuilderAppendDouble /* (D)Ljava/lang/StringBuilder; */)
545 UNIMPLEMENTED_CASE(StringBuilderLength /* ()I */)
546 UNIMPLEMENTED_CASE(StringBuilderToString /* ()Ljava/lang/String; */)
547 UNIMPLEMENTED_CASE(UnsafeCASInt /* (Ljava/lang/Object;JII)Z */)
548 UNIMPLEMENTED_CASE(UnsafeCASLong /* (Ljava/lang/Object;JJJ)Z */)
549 UNIMPLEMENTED_CASE(UnsafeCASObject /* (Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z */)
550 UNIMPLEMENTED_CASE(UnsafeGet /* (Ljava/lang/Object;J)I */)
551 UNIMPLEMENTED_CASE(UnsafeGetVolatile /* (Ljava/lang/Object;J)I */)
552 UNIMPLEMENTED_CASE(UnsafeGetObject /* (Ljava/lang/Object;J)Ljava/lang/Object; */)
553 UNIMPLEMENTED_CASE(UnsafeGetObjectVolatile /* (Ljava/lang/Object;J)Ljava/lang/Object; */)
554 UNIMPLEMENTED_CASE(UnsafeGetLong /* (Ljava/lang/Object;J)J */)
555 UNIMPLEMENTED_CASE(UnsafeGetLongVolatile /* (Ljava/lang/Object;J)J */)
556 UNIMPLEMENTED_CASE(UnsafePut /* (Ljava/lang/Object;JI)V */)
557 UNIMPLEMENTED_CASE(UnsafePutOrdered /* (Ljava/lang/Object;JI)V */)
558 UNIMPLEMENTED_CASE(UnsafePutVolatile /* (Ljava/lang/Object;JI)V */)
559 UNIMPLEMENTED_CASE(UnsafePutObject /* (Ljava/lang/Object;JLjava/lang/Object;)V */)
560 UNIMPLEMENTED_CASE(UnsafePutObjectOrdered /* (Ljava/lang/Object;JLjava/lang/Object;)V */)
561 UNIMPLEMENTED_CASE(UnsafePutObjectVolatile /* (Ljava/lang/Object;JLjava/lang/Object;)V */)
562 UNIMPLEMENTED_CASE(UnsafePutLong /* (Ljava/lang/Object;JJ)V */)
563 UNIMPLEMENTED_CASE(UnsafePutLongOrdered /* (Ljava/lang/Object;JJ)V */)
564 UNIMPLEMENTED_CASE(UnsafePutLongVolatile /* (Ljava/lang/Object;JJ)V */)
565 UNIMPLEMENTED_CASE(UnsafeGetAndAddInt /* (Ljava/lang/Object;JI)I */)
566 UNIMPLEMENTED_CASE(UnsafeGetAndAddLong /* (Ljava/lang/Object;JJ)J */)
567 UNIMPLEMENTED_CASE(UnsafeGetAndSetInt /* (Ljava/lang/Object;JI)I */)
568 UNIMPLEMENTED_CASE(UnsafeGetAndSetLong /* (Ljava/lang/Object;JJ)J */)
569 UNIMPLEMENTED_CASE(UnsafeGetAndSetObject /* (Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object; */)
570 UNIMPLEMENTED_CASE(UnsafeLoadFence /* ()V */)
571 UNIMPLEMENTED_CASE(UnsafeStoreFence /* ()V */)
572 UNIMPLEMENTED_CASE(UnsafeFullFence /* ()V */)
573 UNIMPLEMENTED_CASE(ReferenceGetReferent /* ()Ljava/lang/Object; */)
574 UNIMPLEMENTED_CASE(ReferenceRefersTo /* (Ljava/lang/Object;)Z */)
575 UNIMPLEMENTED_CASE(IntegerValueOf /* (I)Ljava/lang/Integer; */)
576 UNIMPLEMENTED_CASE(ThreadInterrupted /* ()Z */)
577 UNIMPLEMENTED_CASE(CRC32Update /* (II)I */)
578 UNIMPLEMENTED_CASE(CRC32UpdateBytes /* (I[BII)I */)
579 UNIMPLEMENTED_CASE(CRC32UpdateByteBuffer /* (IJII)I */)
580 UNIMPLEMENTED_CASE(FP16ToFloat /* (S)F */)
581 UNIMPLEMENTED_CASE(FP16ToHalf /* (F)S */)
582 UNIMPLEMENTED_CASE(FP16Floor /* (S)S */)
583 UNIMPLEMENTED_CASE(FP16Ceil /* (S)S */)
584 UNIMPLEMENTED_CASE(FP16Rint /* (S)S */)
585 UNIMPLEMENTED_CASE(FP16Greater /* (SS)Z */)
586 UNIMPLEMENTED_CASE(FP16GreaterEquals /* (SS)Z */)
587 UNIMPLEMENTED_CASE(FP16Less /* (SS)Z */)
588 UNIMPLEMENTED_CASE(FP16LessEquals /* (SS)Z */)
589 INTRINSIC_CASE(VarHandleFullFence)
590 INTRINSIC_CASE(VarHandleAcquireFence)
591 INTRINSIC_CASE(VarHandleReleaseFence)
592 INTRINSIC_CASE(VarHandleLoadLoadFence)
593 INTRINSIC_CASE(VarHandleStoreStoreFence)
594 INTRINSIC_CASE(MethodHandleInvokeExact)
595 INTRINSIC_CASE(MethodHandleInvoke)
596 INTRINSIC_CASE(VarHandleCompareAndExchange)
597 INTRINSIC_CASE(VarHandleCompareAndExchangeAcquire)
598 INTRINSIC_CASE(VarHandleCompareAndExchangeRelease)
599 INTRINSIC_CASE(VarHandleCompareAndSet)
600 INTRINSIC_CASE(VarHandleGet)
601 INTRINSIC_CASE(VarHandleGetAcquire)
602 INTRINSIC_CASE(VarHandleGetAndAdd)
603 INTRINSIC_CASE(VarHandleGetAndAddAcquire)
604 INTRINSIC_CASE(VarHandleGetAndAddRelease)
605 INTRINSIC_CASE(VarHandleGetAndBitwiseAnd)
606 INTRINSIC_CASE(VarHandleGetAndBitwiseAndAcquire)
607 INTRINSIC_CASE(VarHandleGetAndBitwiseAndRelease)
608 INTRINSIC_CASE(VarHandleGetAndBitwiseOr)
609 INTRINSIC_CASE(VarHandleGetAndBitwiseOrAcquire)
610 INTRINSIC_CASE(VarHandleGetAndBitwiseOrRelease)
611 INTRINSIC_CASE(VarHandleGetAndBitwiseXor)
612 INTRINSIC_CASE(VarHandleGetAndBitwiseXorAcquire)
613 INTRINSIC_CASE(VarHandleGetAndBitwiseXorRelease)
614 INTRINSIC_CASE(VarHandleGetAndSet)
615 INTRINSIC_CASE(VarHandleGetAndSetAcquire)
616 INTRINSIC_CASE(VarHandleGetAndSetRelease)
617 INTRINSIC_CASE(VarHandleGetOpaque)
618 INTRINSIC_CASE(VarHandleGetVolatile)
619 INTRINSIC_CASE(VarHandleSet)
620 INTRINSIC_CASE(VarHandleSetOpaque)
621 INTRINSIC_CASE(VarHandleSetRelease)
622 INTRINSIC_CASE(VarHandleSetVolatile)
623 INTRINSIC_CASE(VarHandleWeakCompareAndSet)
624 INTRINSIC_CASE(VarHandleWeakCompareAndSetAcquire)
625 INTRINSIC_CASE(VarHandleWeakCompareAndSetPlain)
626 INTRINSIC_CASE(VarHandleWeakCompareAndSetRelease)
627 case Intrinsics::kNone:
628 res = false;
629 break;
630 // Note: no default case to ensure we catch any newly added intrinsics.
631 }
632 return res;
633 }
634
635 } // namespace interpreter
636 } // namespace art
637