blob: ee2aaf69b422cdcce128b5161220755c2243e04c [file] [log] [blame]
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001/*
2 * Copyright (C) 2012 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_common.h"
18
19namespace art {
20namespace interpreter {
21
22#define HANDLE_PENDING_EXCEPTION() \
23 do { \
24 CHECK(self->IsExceptionPending()); \
25 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, \
26 inst->GetDexPc(insns), \
27 this_object_ref, \
28 instrumentation); \
29 if (found_dex_pc == DexFile::kDexNoIndex) { \
30 return JValue(); /* Handled in caller. */ \
31 } else { \
32 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc); \
33 inst = inst->RelativeAt(displacement); \
34 } \
35 } while (false)
36
37#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _next_function) \
38 do { \
39 if (UNLIKELY(_is_exception_pending)) { \
40 HANDLE_PENDING_EXCEPTION(); \
41 } else { \
42 inst = inst->_next_function(); \
43 } \
44 } while (false)
45
46// Code to run before each dex instruction.
47#define PREAMBLE()
48
49template<bool do_access_check>
50static JValue ExecuteSwitchImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item,
51 ShadowFrame& shadow_frame, JValue result_register) {
52 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
53 LOG(FATAL) << "Invalid shadow frame for interpreter use";
54 return JValue();
55 }
56 self->VerifyStack();
57 instrumentation::Instrumentation* const instrumentation = Runtime::Current()->GetInstrumentation();
58
59 // As the 'this' object won't change during the execution of current code, we
60 // want to cache it in local variables. Nevertheless, in order to let the
61 // garbage collector access it, we store it into sirt references.
62 SirtRef<Object> this_object_ref(self, shadow_frame.GetThisObject(code_item->ins_size_));
63
64 uint32_t dex_pc = shadow_frame.GetDexPC();
65 if (LIKELY(dex_pc == 0)) { // We are entering the method as opposed to deoptimizing..
66 if (UNLIKELY(instrumentation->HasMethodEntryListeners())) {
67 instrumentation->MethodEnterEvent(self, this_object_ref.get(),
68 shadow_frame.GetMethod(), 0);
69 }
70 }
71 const uint16_t* const insns = code_item->insns_;
72 const Instruction* inst = Instruction::At(insns + dex_pc);
73 while (true) {
74 dex_pc = inst->GetDexPc(insns);
75 shadow_frame.SetDexPC(dex_pc);
76 if (UNLIKELY(self->TestAllFlags())) {
77 CheckSuspend(self);
78 }
79 if (UNLIKELY(instrumentation->HasDexPcListeners())) {
80 instrumentation->DexPcMovedEvent(self, this_object_ref.get(),
81 shadow_frame.GetMethod(), dex_pc);
82 }
83 TraceExecution(shadow_frame, inst, dex_pc, mh);
84 switch (inst->Opcode()) {
85 case Instruction::NOP:
86 PREAMBLE();
87 inst = inst->Next_1xx();
88 break;
89 case Instruction::MOVE:
90 PREAMBLE();
91 shadow_frame.SetVReg(inst->VRegA_12x(),
92 shadow_frame.GetVReg(inst->VRegB_12x()));
93 inst = inst->Next_1xx();
94 break;
95 case Instruction::MOVE_FROM16:
96 PREAMBLE();
97 shadow_frame.SetVReg(inst->VRegA_22x(),
98 shadow_frame.GetVReg(inst->VRegB_22x()));
99 inst = inst->Next_2xx();
100 break;
101 case Instruction::MOVE_16:
102 PREAMBLE();
103 shadow_frame.SetVReg(inst->VRegA_32x(),
104 shadow_frame.GetVReg(inst->VRegB_32x()));
105 inst = inst->Next_3xx();
106 break;
107 case Instruction::MOVE_WIDE:
108 PREAMBLE();
109 shadow_frame.SetVRegLong(inst->VRegA_12x(),
110 shadow_frame.GetVRegLong(inst->VRegB_12x()));
111 inst = inst->Next_1xx();
112 break;
113 case Instruction::MOVE_WIDE_FROM16:
114 PREAMBLE();
115 shadow_frame.SetVRegLong(inst->VRegA_22x(),
116 shadow_frame.GetVRegLong(inst->VRegB_22x()));
117 inst = inst->Next_2xx();
118 break;
119 case Instruction::MOVE_WIDE_16:
120 PREAMBLE();
121 shadow_frame.SetVRegLong(inst->VRegA_32x(),
122 shadow_frame.GetVRegLong(inst->VRegB_32x()));
123 inst = inst->Next_3xx();
124 break;
125 case Instruction::MOVE_OBJECT:
126 PREAMBLE();
127 shadow_frame.SetVRegReference(inst->VRegA_12x(),
128 shadow_frame.GetVRegReference(inst->VRegB_12x()));
129 inst = inst->Next_1xx();
130 break;
131 case Instruction::MOVE_OBJECT_FROM16:
132 PREAMBLE();
133 shadow_frame.SetVRegReference(inst->VRegA_22x(),
134 shadow_frame.GetVRegReference(inst->VRegB_22x()));
135 inst = inst->Next_2xx();
136 break;
137 case Instruction::MOVE_OBJECT_16:
138 PREAMBLE();
139 shadow_frame.SetVRegReference(inst->VRegA_32x(),
140 shadow_frame.GetVRegReference(inst->VRegB_32x()));
141 inst = inst->Next_3xx();
142 break;
143 case Instruction::MOVE_RESULT:
144 PREAMBLE();
145 shadow_frame.SetVReg(inst->VRegA_11x(), result_register.GetI());
146 inst = inst->Next_1xx();
147 break;
148 case Instruction::MOVE_RESULT_WIDE:
149 PREAMBLE();
150 shadow_frame.SetVRegLong(inst->VRegA_11x(), result_register.GetJ());
151 inst = inst->Next_1xx();
152 break;
153 case Instruction::MOVE_RESULT_OBJECT:
154 PREAMBLE();
155 shadow_frame.SetVRegReference(inst->VRegA_11x(), result_register.GetL());
156 inst = inst->Next_1xx();
157 break;
158 case Instruction::MOVE_EXCEPTION: {
159 PREAMBLE();
160 Throwable* exception = self->GetException(NULL);
161 self->ClearException();
162 shadow_frame.SetVRegReference(inst->VRegA_11x(), exception);
163 inst = inst->Next_1xx();
164 break;
165 }
166 case Instruction::RETURN_VOID: {
167 PREAMBLE();
168 JValue result;
169 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
170 instrumentation->MethodExitEvent(self, this_object_ref.get(),
171 shadow_frame.GetMethod(), inst->GetDexPc(insns),
172 result);
173 }
174 return result;
175 }
176 case Instruction::RETURN_VOID_BARRIER: {
177 PREAMBLE();
178 ANDROID_MEMBAR_STORE();
179 JValue result;
180 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
181 instrumentation->MethodExitEvent(self, this_object_ref.get(),
182 shadow_frame.GetMethod(), inst->GetDexPc(insns),
183 result);
184 }
185 return result;
186 }
187 case Instruction::RETURN: {
188 PREAMBLE();
189 JValue result;
190 result.SetJ(0);
191 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x()));
192 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
193 instrumentation->MethodExitEvent(self, this_object_ref.get(),
194 shadow_frame.GetMethod(), inst->GetDexPc(insns),
195 result);
196 }
197 return result;
198 }
199 case Instruction::RETURN_WIDE: {
200 PREAMBLE();
201 JValue result;
202 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x()));
203 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
204 instrumentation->MethodExitEvent(self, this_object_ref.get(),
205 shadow_frame.GetMethod(), inst->GetDexPc(insns),
206 result);
207 }
208 return result;
209 }
210 case Instruction::RETURN_OBJECT: {
211 PREAMBLE();
212 JValue result;
213 result.SetJ(0);
214 result.SetL(shadow_frame.GetVRegReference(inst->VRegA_11x()));
215 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
216 instrumentation->MethodExitEvent(self, this_object_ref.get(),
217 shadow_frame.GetMethod(), inst->GetDexPc(insns),
218 result);
219 }
220 return result;
221 }
222 case Instruction::CONST_4: {
223 PREAMBLE();
224 uint4_t dst = inst->VRegA_11n();
225 int4_t val = inst->VRegB_11n();
226 shadow_frame.SetVReg(dst, val);
227 if (val == 0) {
228 shadow_frame.SetVRegReference(dst, NULL);
229 }
230 inst = inst->Next_1xx();
231 break;
232 }
233 case Instruction::CONST_16: {
234 PREAMBLE();
235 uint8_t dst = inst->VRegA_21s();
236 int16_t val = inst->VRegB_21s();
237 shadow_frame.SetVReg(dst, val);
238 if (val == 0) {
239 shadow_frame.SetVRegReference(dst, NULL);
240 }
241 inst = inst->Next_2xx();
242 break;
243 }
244 case Instruction::CONST: {
245 PREAMBLE();
246 uint8_t dst = inst->VRegA_31i();
247 int32_t val = inst->VRegB_31i();
248 shadow_frame.SetVReg(dst, val);
249 if (val == 0) {
250 shadow_frame.SetVRegReference(dst, NULL);
251 }
252 inst = inst->Next_3xx();
253 break;
254 }
255 case Instruction::CONST_HIGH16: {
256 PREAMBLE();
257 uint8_t dst = inst->VRegA_21h();
258 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
259 shadow_frame.SetVReg(dst, val);
260 if (val == 0) {
261 shadow_frame.SetVRegReference(dst, NULL);
262 }
263 inst = inst->Next_2xx();
264 break;
265 }
266 case Instruction::CONST_WIDE_16:
267 PREAMBLE();
268 shadow_frame.SetVRegLong(inst->VRegA_21s(), inst->VRegB_21s());
269 inst = inst->Next_2xx();
270 break;
271 case Instruction::CONST_WIDE_32:
272 PREAMBLE();
273 shadow_frame.SetVRegLong(inst->VRegA_31i(), inst->VRegB_31i());
274 inst = inst->Next_3xx();
275 break;
276 case Instruction::CONST_WIDE:
277 PREAMBLE();
278 shadow_frame.SetVRegLong(inst->VRegA_51l(), inst->VRegB_51l());
279 inst = inst->Next_51l();
280 break;
281 case Instruction::CONST_WIDE_HIGH16:
282 shadow_frame.SetVRegLong(inst->VRegA_21h(),
283 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
284 inst = inst->Next_2xx();
285 break;
286 case Instruction::CONST_STRING: {
287 PREAMBLE();
288 String* s = ResolveString(self, mh, inst->VRegB_21c());
289 if (UNLIKELY(s == NULL)) {
290 HANDLE_PENDING_EXCEPTION();
291 } else {
292 shadow_frame.SetVRegReference(inst->VRegA_21c(), s);
293 inst = inst->Next_2xx();
294 }
295 break;
296 }
297 case Instruction::CONST_STRING_JUMBO: {
298 PREAMBLE();
299 String* s = ResolveString(self, mh, inst->VRegB_31c());
300 if (UNLIKELY(s == NULL)) {
301 HANDLE_PENDING_EXCEPTION();
302 } else {
303 shadow_frame.SetVRegReference(inst->VRegA_31c(), s);
304 inst = inst->Next_3xx();
305 }
306 break;
307 }
308 case Instruction::CONST_CLASS: {
309 PREAMBLE();
310 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
311 self, false, do_access_check);
312 if (UNLIKELY(c == NULL)) {
313 HANDLE_PENDING_EXCEPTION();
314 } else {
315 shadow_frame.SetVRegReference(inst->VRegA_21c(), c);
316 inst = inst->Next_2xx();
317 }
318 break;
319 }
320 case Instruction::MONITOR_ENTER: {
321 PREAMBLE();
322 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x());
323 if (UNLIKELY(obj == NULL)) {
324 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
325 HANDLE_PENDING_EXCEPTION();
326 } else {
327 DoMonitorEnter(self, obj);
328 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
329 }
330 break;
331 }
332 case Instruction::MONITOR_EXIT: {
333 PREAMBLE();
334 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x());
335 if (UNLIKELY(obj == NULL)) {
336 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
337 HANDLE_PENDING_EXCEPTION();
338 } else {
339 DoMonitorExit(self, obj);
340 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
341 }
342 break;
343 }
344 case Instruction::CHECK_CAST: {
345 PREAMBLE();
346 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
347 self, false, do_access_check);
348 if (UNLIKELY(c == NULL)) {
349 HANDLE_PENDING_EXCEPTION();
350 } else {
351 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c());
352 if (UNLIKELY(obj != NULL && !obj->InstanceOf(c))) {
353 ThrowClassCastException(c, obj->GetClass());
354 HANDLE_PENDING_EXCEPTION();
355 } else {
356 inst = inst->Next_2xx();
357 }
358 }
359 break;
360 }
361 case Instruction::INSTANCE_OF: {
362 PREAMBLE();
363 Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(),
364 self, false, do_access_check);
365 if (UNLIKELY(c == NULL)) {
366 HANDLE_PENDING_EXCEPTION();
367 } else {
368 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c());
369 shadow_frame.SetVReg(inst->VRegA_22c(), (obj != NULL && obj->InstanceOf(c)) ? 1 : 0);
370 inst = inst->Next_2xx();
371 }
372 break;
373 }
374 case Instruction::ARRAY_LENGTH: {
375 PREAMBLE();
376 Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x());
377 if (UNLIKELY(array == NULL)) {
378 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
379 HANDLE_PENDING_EXCEPTION();
380 } else {
381 shadow_frame.SetVReg(inst->VRegA_12x(), array->AsArray()->GetLength());
382 inst = inst->Next_1xx();
383 }
384 break;
385 }
386 case Instruction::NEW_INSTANCE: {
387 PREAMBLE();
388 Object* obj = AllocObjectFromCode(inst->VRegB_21c(), shadow_frame.GetMethod(),
389 self, do_access_check);
390 if (UNLIKELY(obj == NULL)) {
391 HANDLE_PENDING_EXCEPTION();
392 } else {
393 shadow_frame.SetVRegReference(inst->VRegA_21c(), obj);
394 inst = inst->Next_2xx();
395 }
396 break;
397 }
398 case Instruction::NEW_ARRAY: {
399 PREAMBLE();
400 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c());
401 Object* obj = AllocArrayFromCode(inst->VRegC_22c(), shadow_frame.GetMethod(),
402 length, self, do_access_check);
403 if (UNLIKELY(obj == NULL)) {
404 HANDLE_PENDING_EXCEPTION();
405 } else {
406 shadow_frame.SetVRegReference(inst->VRegA_22c(), obj);
407 inst = inst->Next_2xx();
408 }
409 break;
410 }
411 case Instruction::FILLED_NEW_ARRAY: {
412 PREAMBLE();
413 bool success = DoFilledNewArray<false, do_access_check>(inst, shadow_frame,
414 self, &result_register);
415 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
416 break;
417 }
418 case Instruction::FILLED_NEW_ARRAY_RANGE: {
419 PREAMBLE();
420 bool success = DoFilledNewArray<true, do_access_check>(inst, shadow_frame,
421 self, &result_register);
422 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
423 break;
424 }
425 case Instruction::FILL_ARRAY_DATA: {
426 PREAMBLE();
427 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t());
428 if (UNLIKELY(obj == NULL)) {
429 ThrowNullPointerException(NULL, "null array in FILL_ARRAY_DATA");
430 HANDLE_PENDING_EXCEPTION();
431 break;
432 }
433 Array* array = obj->AsArray();
434 DCHECK(array->IsArrayInstance() && !array->IsObjectArray());
435 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
436 const Instruction::ArrayDataPayload* payload =
437 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
438 if (UNLIKELY(static_cast<int32_t>(payload->element_count) > array->GetLength())) {
439 self->ThrowNewExceptionF(shadow_frame.GetCurrentLocationForThrow(),
440 "Ljava/lang/ArrayIndexOutOfBoundsException;",
441 "failed FILL_ARRAY_DATA; length=%d, index=%d",
442 array->GetLength(), payload->element_count);
443 HANDLE_PENDING_EXCEPTION();
444 break;
445 }
446 uint32_t size_in_bytes = payload->element_count * payload->element_width;
447 memcpy(array->GetRawData(payload->element_width), payload->data, size_in_bytes);
448 inst = inst->Next_3xx();
449 break;
450 }
451 case Instruction::THROW: {
452 PREAMBLE();
453 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x());
454 if (UNLIKELY(exception == NULL)) {
455 ThrowNullPointerException(NULL, "throw with null exception");
456 } else {
457 self->SetException(shadow_frame.GetCurrentLocationForThrow(), exception->AsThrowable());
458 }
459 HANDLE_PENDING_EXCEPTION();
460 break;
461 }
462 case Instruction::GOTO: {
463 PREAMBLE();
464 inst = inst->RelativeAt(inst->VRegA_10t());
465 break;
466 }
467 case Instruction::GOTO_16: {
468 PREAMBLE();
469 inst = inst->RelativeAt(inst->VRegA_20t());
470 break;
471 }
472 case Instruction::GOTO_32: {
473 PREAMBLE();
474 inst = inst->RelativeAt(inst->VRegA_30t());
475 break;
476 }
477 case Instruction::PACKED_SWITCH: {
478 PREAMBLE();
479 int32_t offset = DoPackedSwitch(inst, shadow_frame);
480 inst = inst->RelativeAt(offset);
481 break;
482 }
483 case Instruction::SPARSE_SWITCH: {
484 PREAMBLE();
485 int32_t offset = DoSparseSwitch(inst, shadow_frame);
486 inst = inst->RelativeAt(offset);
487 break;
488 }
489 case Instruction::CMPL_FLOAT: {
490 PREAMBLE();
491 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
492 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
493 int32_t result;
494 if (val1 > val2) {
495 result = 1;
496 } else if (val1 == val2) {
497 result = 0;
498 } else {
499 result = -1;
500 }
501 shadow_frame.SetVReg(inst->VRegA_23x(), result);
502 inst = inst->Next_2xx();
503 break;
504 }
505 case Instruction::CMPG_FLOAT: {
506 PREAMBLE();
507 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
508 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
509 int32_t result;
510 if (val1 < val2) {
511 result = -1;
512 } else if (val1 == val2) {
513 result = 0;
514 } else {
515 result = 1;
516 }
517 shadow_frame.SetVReg(inst->VRegA_23x(), result);
518 inst = inst->Next_2xx();
519 break;
520 }
521 case Instruction::CMPL_DOUBLE: {
522 PREAMBLE();
523 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
524 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
525 int32_t result;
526 if (val1 > val2) {
527 result = 1;
528 } else if (val1 == val2) {
529 result = 0;
530 } else {
531 result = -1;
532 }
533 shadow_frame.SetVReg(inst->VRegA_23x(), result);
534 inst = inst->Next_2xx();
535 break;
536 }
537
538 case Instruction::CMPG_DOUBLE: {
539 PREAMBLE();
540 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
541 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
542 int32_t result;
543 if (val1 < val2) {
544 result = -1;
545 } else if (val1 == val2) {
546 result = 0;
547 } else {
548 result = 1;
549 }
550 shadow_frame.SetVReg(inst->VRegA_23x(), result);
551 inst = inst->Next_2xx();
552 break;
553 }
554 case Instruction::CMP_LONG: {
555 PREAMBLE();
556 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
557 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
558 int32_t result;
559 if (val1 > val2) {
560 result = 1;
561 } else if (val1 == val2) {
562 result = 0;
563 } else {
564 result = -1;
565 }
566 shadow_frame.SetVReg(inst->VRegA_23x(), result);
567 inst = inst->Next_2xx();
568 break;
569 }
570 case Instruction::IF_EQ: {
571 PREAMBLE();
572 if (shadow_frame.GetVReg(inst->VRegA_22t()) == shadow_frame.GetVReg(inst->VRegB_22t())) {
573 inst = inst->RelativeAt(inst->VRegC_22t());
574 } else {
575 inst = inst->Next_2xx();
576 }
577 break;
578 }
579 case Instruction::IF_NE: {
580 PREAMBLE();
581 if (shadow_frame.GetVReg(inst->VRegA_22t()) != shadow_frame.GetVReg(inst->VRegB_22t())) {
582 inst = inst->RelativeAt(inst->VRegC_22t());
583 } else {
584 inst = inst->Next_2xx();
585 }
586 break;
587 }
588 case Instruction::IF_LT: {
589 PREAMBLE();
590 if (shadow_frame.GetVReg(inst->VRegA_22t()) < shadow_frame.GetVReg(inst->VRegB_22t())) {
591 inst = inst->RelativeAt(inst->VRegC_22t());
592 } else {
593 inst = inst->Next_2xx();
594 }
595 break;
596 }
597 case Instruction::IF_GE: {
598 PREAMBLE();
599 if (shadow_frame.GetVReg(inst->VRegA_22t()) >= shadow_frame.GetVReg(inst->VRegB_22t())) {
600 inst = inst->RelativeAt(inst->VRegC_22t());
601 } else {
602 inst = inst->Next_2xx();
603 }
604 break;
605 }
606 case Instruction::IF_GT: {
607 PREAMBLE();
608 if (shadow_frame.GetVReg(inst->VRegA_22t()) > shadow_frame.GetVReg(inst->VRegB_22t())) {
609 inst = inst->RelativeAt(inst->VRegC_22t());
610 } else {
611 inst = inst->Next_2xx();
612 }
613 break;
614 }
615 case Instruction::IF_LE: {
616 PREAMBLE();
617 if (shadow_frame.GetVReg(inst->VRegA_22t()) <= shadow_frame.GetVReg(inst->VRegB_22t())) {
618 inst = inst->RelativeAt(inst->VRegC_22t());
619 } else {
620 inst = inst->Next_2xx();
621 }
622 break;
623 }
624 case Instruction::IF_EQZ: {
625 PREAMBLE();
626 if (shadow_frame.GetVReg(inst->VRegA_21t()) == 0) {
627 inst = inst->RelativeAt(inst->VRegB_21t());
628 } else {
629 inst = inst->Next_2xx();
630 }
631 break;
632 }
633 case Instruction::IF_NEZ: {
634 PREAMBLE();
635 if (shadow_frame.GetVReg(inst->VRegA_21t()) != 0) {
636 inst = inst->RelativeAt(inst->VRegB_21t());
637 } else {
638 inst = inst->Next_2xx();
639 }
640 break;
641 }
642 case Instruction::IF_LTZ: {
643 PREAMBLE();
644 if (shadow_frame.GetVReg(inst->VRegA_21t()) < 0) {
645 inst = inst->RelativeAt(inst->VRegB_21t());
646 } else {
647 inst = inst->Next_2xx();
648 }
649 break;
650 }
651 case Instruction::IF_GEZ: {
652 PREAMBLE();
653 if (shadow_frame.GetVReg(inst->VRegA_21t()) >= 0) {
654 inst = inst->RelativeAt(inst->VRegB_21t());
655 } else {
656 inst = inst->Next_2xx();
657 }
658 break;
659 }
660 case Instruction::IF_GTZ: {
661 PREAMBLE();
662 if (shadow_frame.GetVReg(inst->VRegA_21t()) > 0) {
663 inst = inst->RelativeAt(inst->VRegB_21t());
664 } else {
665 inst = inst->Next_2xx();
666 }
667 break;
668 }
669 case Instruction::IF_LEZ: {
670 PREAMBLE();
671 if (shadow_frame.GetVReg(inst->VRegA_21t()) <= 0) {
672 inst = inst->RelativeAt(inst->VRegB_21t());
673 } else {
674 inst = inst->Next_2xx();
675 }
676 break;
677 }
678 case Instruction::AGET_BOOLEAN: {
679 PREAMBLE();
680 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
681 if (UNLIKELY(a == NULL)) {
682 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
683 HANDLE_PENDING_EXCEPTION();
684 break;
685 }
686 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
687 BooleanArray* array = a->AsBooleanArray();
688 if (LIKELY(array->IsValidIndex(index))) {
689 shadow_frame.SetVReg(inst->VRegA_23x(), array->GetData()[index]);
690 inst = inst->Next_2xx();
691 } else {
692 HANDLE_PENDING_EXCEPTION();
693 }
694 break;
695 }
696 case Instruction::AGET_BYTE: {
697 PREAMBLE();
698 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
699 if (UNLIKELY(a == NULL)) {
700 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
701 HANDLE_PENDING_EXCEPTION();
702 break;
703 }
704 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
705 ByteArray* array = a->AsByteArray();
706 if (LIKELY(array->IsValidIndex(index))) {
707 shadow_frame.SetVReg(inst->VRegA_23x(), array->GetData()[index]);
708 inst = inst->Next_2xx();
709 } else {
710 HANDLE_PENDING_EXCEPTION();
711 }
712 break;
713 }
714 case Instruction::AGET_CHAR: {
715 PREAMBLE();
716 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
717 if (UNLIKELY(a == NULL)) {
718 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
719 HANDLE_PENDING_EXCEPTION();
720 break;
721 }
722 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
723 CharArray* array = a->AsCharArray();
724 if (LIKELY(array->IsValidIndex(index))) {
725 shadow_frame.SetVReg(inst->VRegA_23x(), array->GetData()[index]);
726 inst = inst->Next_2xx();
727 } else {
728 HANDLE_PENDING_EXCEPTION();
729 }
730 break;
731 }
732 case Instruction::AGET_SHORT: {
733 PREAMBLE();
734 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
735 if (UNLIKELY(a == NULL)) {
736 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
737 HANDLE_PENDING_EXCEPTION();
738 break;
739 }
740 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
741 ShortArray* array = a->AsShortArray();
742 if (LIKELY(array->IsValidIndex(index))) {
743 shadow_frame.SetVReg(inst->VRegA_23x(), array->GetData()[index]);
744 inst = inst->Next_2xx();
745 } else {
746 HANDLE_PENDING_EXCEPTION();
747 }
748 break;
749 }
750 case Instruction::AGET: {
751 PREAMBLE();
752 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
753 if (UNLIKELY(a == NULL)) {
754 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
755 HANDLE_PENDING_EXCEPTION();
756 break;
757 }
758 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
759 IntArray* array = a->AsIntArray();
760 if (LIKELY(array->IsValidIndex(index))) {
761 shadow_frame.SetVReg(inst->VRegA_23x(), array->GetData()[index]);
762 inst = inst->Next_2xx();
763 } else {
764 HANDLE_PENDING_EXCEPTION();
765 }
766 break;
767 }
768 case Instruction::AGET_WIDE: {
769 PREAMBLE();
770 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
771 if (UNLIKELY(a == NULL)) {
772 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
773 HANDLE_PENDING_EXCEPTION();
774 break;
775 }
776 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
777 LongArray* array = a->AsLongArray();
778 if (LIKELY(array->IsValidIndex(index))) {
779 shadow_frame.SetVRegLong(inst->VRegA_23x(), array->GetData()[index]);
780 inst = inst->Next_2xx();
781 } else {
782 HANDLE_PENDING_EXCEPTION();
783 }
784 break;
785 }
786 case Instruction::AGET_OBJECT: {
787 PREAMBLE();
788 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
789 if (UNLIKELY(a == NULL)) {
790 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
791 HANDLE_PENDING_EXCEPTION();
792 break;
793 }
794 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
795 ObjectArray<Object>* array = a->AsObjectArray<Object>();
796 if (LIKELY(array->IsValidIndex(index))) {
797 shadow_frame.SetVRegReference(inst->VRegA_23x(), array->GetWithoutChecks(index));
798 inst = inst->Next_2xx();
799 } else {
800 HANDLE_PENDING_EXCEPTION();
801 }
802 break;
803 }
804 case Instruction::APUT_BOOLEAN: {
805 PREAMBLE();
806 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
807 if (UNLIKELY(a == NULL)) {
808 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
809 HANDLE_PENDING_EXCEPTION();
810 break;
811 }
812 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x());
813 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
814 BooleanArray* array = a->AsBooleanArray();
815 if (LIKELY(array->IsValidIndex(index))) {
816 array->GetData()[index] = val;
817 inst = inst->Next_2xx();
818 } else {
819 HANDLE_PENDING_EXCEPTION();
820 }
821 break;
822 }
823 case Instruction::APUT_BYTE: {
824 PREAMBLE();
825 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
826 if (UNLIKELY(a == NULL)) {
827 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
828 HANDLE_PENDING_EXCEPTION();
829 break;
830 }
831 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x());
832 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
833 ByteArray* array = a->AsByteArray();
834 if (LIKELY(array->IsValidIndex(index))) {
835 array->GetData()[index] = val;
836 inst = inst->Next_2xx();
837 } else {
838 HANDLE_PENDING_EXCEPTION();
839 }
840 break;
841 }
842 case Instruction::APUT_CHAR: {
843 PREAMBLE();
844 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
845 if (UNLIKELY(a == NULL)) {
846 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
847 HANDLE_PENDING_EXCEPTION();
848 break;
849 }
850 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x());
851 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
852 CharArray* array = a->AsCharArray();
853 if (LIKELY(array->IsValidIndex(index))) {
854 array->GetData()[index] = val;
855 inst = inst->Next_2xx();
856 } else {
857 HANDLE_PENDING_EXCEPTION();
858 }
859 break;
860 }
861 case Instruction::APUT_SHORT: {
862 PREAMBLE();
863 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
864 if (UNLIKELY(a == NULL)) {
865 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
866 HANDLE_PENDING_EXCEPTION();
867 break;
868 }
869 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x());
870 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
871 ShortArray* array = a->AsShortArray();
872 if (LIKELY(array->IsValidIndex(index))) {
873 array->GetData()[index] = val;
874 inst = inst->Next_2xx();
875 } else {
876 HANDLE_PENDING_EXCEPTION();
877 }
878 break;
879 }
880 case Instruction::APUT: {
881 PREAMBLE();
882 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
883 if (UNLIKELY(a == NULL)) {
884 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
885 HANDLE_PENDING_EXCEPTION();
886 break;
887 }
888 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x());
889 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
890 IntArray* array = a->AsIntArray();
891 if (LIKELY(array->IsValidIndex(index))) {
892 array->GetData()[index] = val;
893 inst = inst->Next_2xx();
894 } else {
895 HANDLE_PENDING_EXCEPTION();
896 }
897 break;
898 }
899 case Instruction::APUT_WIDE: {
900 PREAMBLE();
901 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
902 if (UNLIKELY(a == NULL)) {
903 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
904 HANDLE_PENDING_EXCEPTION();
905 break;
906 }
907 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x());
908 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
909 LongArray* array = a->AsLongArray();
910 if (LIKELY(array->IsValidIndex(index))) {
911 array->GetData()[index] = val;
912 inst = inst->Next_2xx();
913 } else {
914 HANDLE_PENDING_EXCEPTION();
915 }
916 break;
917 }
918 case Instruction::APUT_OBJECT: {
919 PREAMBLE();
920 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
921 if (UNLIKELY(a == NULL)) {
922 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
923 HANDLE_PENDING_EXCEPTION();
924 break;
925 }
926 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
927 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x());
928 ObjectArray<Object>* array = a->AsObjectArray<Object>();
929 if (LIKELY(array->IsValidIndex(index) && array->CheckAssignable(val))) {
930 array->SetWithoutChecks(index, val);
931 inst = inst->Next_2xx();
932 } else {
933 HANDLE_PENDING_EXCEPTION();
934 }
935 break;
936 }
937 case Instruction::IGET_BOOLEAN: {
938 PREAMBLE();
939 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst);
940 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
941 break;
942 }
943 case Instruction::IGET_BYTE: {
944 PREAMBLE();
945 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst);
946 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
947 break;
948 }
949 case Instruction::IGET_CHAR: {
950 PREAMBLE();
951 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst);
952 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
953 break;
954 }
955 case Instruction::IGET_SHORT: {
956 PREAMBLE();
957 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst);
958 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
959 break;
960 }
961 case Instruction::IGET: {
962 PREAMBLE();
963 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst);
964 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
965 break;
966 }
967 case Instruction::IGET_WIDE: {
968 PREAMBLE();
969 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst);
970 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
971 break;
972 }
973 case Instruction::IGET_OBJECT: {
974 PREAMBLE();
975 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst);
976 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
977 break;
978 }
979 case Instruction::IGET_QUICK: {
980 PREAMBLE();
981 bool success = DoIGetQuick<Primitive::kPrimInt>(self, shadow_frame, inst);
982 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
983 break;
984 }
985 case Instruction::IGET_WIDE_QUICK: {
986 PREAMBLE();
987 bool success = DoIGetQuick<Primitive::kPrimLong>(self, shadow_frame, inst);
988 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
989 break;
990 }
991 case Instruction::IGET_OBJECT_QUICK: {
992 PREAMBLE();
993 bool success = DoIGetQuick<Primitive::kPrimNot>(self, shadow_frame, inst);
994 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
995 break;
996 }
997 case Instruction::SGET_BOOLEAN: {
998 PREAMBLE();
999 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst);
1000 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1001 break;
1002 }
1003 case Instruction::SGET_BYTE: {
1004 PREAMBLE();
1005 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst);
1006 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1007 break;
1008 }
1009 case Instruction::SGET_CHAR: {
1010 PREAMBLE();
1011 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst);
1012 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1013 break;
1014 }
1015 case Instruction::SGET_SHORT: {
1016 PREAMBLE();
1017 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst);
1018 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1019 break;
1020 }
1021 case Instruction::SGET: {
1022 PREAMBLE();
1023 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst);
1024 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1025 break;
1026 }
1027 case Instruction::SGET_WIDE: {
1028 PREAMBLE();
1029 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst);
1030 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1031 break;
1032 }
1033 case Instruction::SGET_OBJECT: {
1034 PREAMBLE();
1035 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst);
1036 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1037 break;
1038 }
1039 case Instruction::IPUT_BOOLEAN: {
1040 PREAMBLE();
1041 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst);
1042 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1043 break;
1044 }
1045 case Instruction::IPUT_BYTE: {
1046 PREAMBLE();
1047 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst);
1048 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1049 break;
1050 }
1051 case Instruction::IPUT_CHAR: {
1052 PREAMBLE();
1053 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst);
1054 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1055 break;
1056 }
1057 case Instruction::IPUT_SHORT: {
1058 PREAMBLE();
1059 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst);
1060 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1061 break;
1062 }
1063 case Instruction::IPUT: {
1064 PREAMBLE();
1065 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst);
1066 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1067 break;
1068 }
1069 case Instruction::IPUT_WIDE: {
1070 PREAMBLE();
1071 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst);
1072 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1073 break;
1074 }
1075 case Instruction::IPUT_OBJECT: {
1076 PREAMBLE();
1077 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst);
1078 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1079 break;
1080 }
1081 case Instruction::IPUT_QUICK: {
1082 PREAMBLE();
1083 bool success = DoIPutQuick<Primitive::kPrimInt>(self, shadow_frame, inst);
1084 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1085 break;
1086 }
1087 case Instruction::IPUT_WIDE_QUICK: {
1088 PREAMBLE();
1089 bool success = DoIPutQuick<Primitive::kPrimLong>(self, shadow_frame, inst);
1090 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1091 break;
1092 }
1093 case Instruction::IPUT_OBJECT_QUICK: {
1094 PREAMBLE();
1095 bool success = DoIPutQuick<Primitive::kPrimNot>(self, shadow_frame, inst);
1096 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1097 break;
1098 }
1099 case Instruction::SPUT_BOOLEAN: {
1100 PREAMBLE();
1101 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst);
1102 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1103 break;
1104 }
1105 case Instruction::SPUT_BYTE: {
1106 PREAMBLE();
1107 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst);
1108 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1109 break;
1110 }
1111 case Instruction::SPUT_CHAR: {
1112 PREAMBLE();
1113 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst);
1114 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1115 break;
1116 }
1117 case Instruction::SPUT_SHORT: {
1118 PREAMBLE();
1119 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst);
1120 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1121 break;
1122 }
1123 case Instruction::SPUT: {
1124 PREAMBLE();
1125 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst);
1126 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1127 break;
1128 }
1129 case Instruction::SPUT_WIDE: {
1130 PREAMBLE();
1131 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst);
1132 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1133 break;
1134 }
1135 case Instruction::SPUT_OBJECT: {
1136 PREAMBLE();
1137 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst);
1138 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1139 break;
1140 }
1141 case Instruction::INVOKE_VIRTUAL: {
1142 PREAMBLE();
1143 bool success = DoInvoke<kVirtual, false, do_access_check>(self, shadow_frame, inst, &result_register);
1144 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1145 break;
1146 }
1147 case Instruction::INVOKE_VIRTUAL_RANGE: {
1148 PREAMBLE();
1149 bool success = DoInvoke<kVirtual, true, do_access_check>(self, shadow_frame, inst, &result_register);
1150 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1151 break;
1152 }
1153 case Instruction::INVOKE_SUPER: {
1154 PREAMBLE();
1155 bool success = DoInvoke<kSuper, false, do_access_check>(self, shadow_frame, inst, &result_register);
1156 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1157 break;
1158 }
1159 case Instruction::INVOKE_SUPER_RANGE: {
1160 PREAMBLE();
1161 bool success = DoInvoke<kSuper, true, do_access_check>(self, shadow_frame, inst, &result_register);
1162 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1163 break;
1164 }
1165 case Instruction::INVOKE_DIRECT: {
1166 PREAMBLE();
1167 bool success = DoInvoke<kDirect, false, do_access_check>(self, shadow_frame, inst, &result_register);
1168 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1169 break;
1170 }
1171 case Instruction::INVOKE_DIRECT_RANGE: {
1172 PREAMBLE();
1173 bool success = DoInvoke<kDirect, true, do_access_check>(self, shadow_frame, inst, &result_register);
1174 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1175 break;
1176 }
1177 case Instruction::INVOKE_INTERFACE: {
1178 PREAMBLE();
1179 bool success = DoInvoke<kInterface, false, do_access_check>(self, shadow_frame, inst, &result_register);
1180 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1181 break;
1182 }
1183 case Instruction::INVOKE_INTERFACE_RANGE: {
1184 PREAMBLE();
1185 bool success = DoInvoke<kInterface, true, do_access_check>(self, shadow_frame, inst, &result_register);
1186 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1187 break;
1188 }
1189 case Instruction::INVOKE_STATIC: {
1190 PREAMBLE();
1191 bool success = DoInvoke<kStatic, false, do_access_check>(self, shadow_frame, inst, &result_register);
1192 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1193 break;
1194 }
1195 case Instruction::INVOKE_STATIC_RANGE: {
1196 PREAMBLE();
1197 bool success = DoInvoke<kStatic, true, do_access_check>(self, shadow_frame, inst, &result_register);
1198 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1199 break;
1200 }
1201 case Instruction::INVOKE_VIRTUAL_QUICK: {
1202 PREAMBLE();
1203 bool success = DoInvokeVirtualQuick<false>(self, shadow_frame, inst, &result_register);
1204 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1205 break;
1206 }
1207 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
1208 PREAMBLE();
1209 bool success = DoInvokeVirtualQuick<true>(self, shadow_frame, inst, &result_register);
1210 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1211 break;
1212 }
1213 case Instruction::NEG_INT:
1214 PREAMBLE();
1215 shadow_frame.SetVReg(inst->VRegA_12x(), -shadow_frame.GetVReg(inst->VRegB_12x()));
1216 inst = inst->Next_1xx();
1217 break;
1218 case Instruction::NOT_INT:
1219 PREAMBLE();
1220 shadow_frame.SetVReg(inst->VRegA_12x(), ~shadow_frame.GetVReg(inst->VRegB_12x()));
1221 inst = inst->Next_1xx();
1222 break;
1223 case Instruction::NEG_LONG:
1224 PREAMBLE();
1225 shadow_frame.SetVRegLong(inst->VRegA_12x(), -shadow_frame.GetVRegLong(inst->VRegB_12x()));
1226 inst = inst->Next_1xx();
1227 break;
1228 case Instruction::NOT_LONG:
1229 PREAMBLE();
1230 shadow_frame.SetVRegLong(inst->VRegA_12x(), ~shadow_frame.GetVRegLong(inst->VRegB_12x()));
1231 inst = inst->Next_1xx();
1232 break;
1233 case Instruction::NEG_FLOAT:
1234 PREAMBLE();
1235 shadow_frame.SetVRegFloat(inst->VRegA_12x(), -shadow_frame.GetVRegFloat(inst->VRegB_12x()));
1236 inst = inst->Next_1xx();
1237 break;
1238 case Instruction::NEG_DOUBLE:
1239 PREAMBLE();
1240 shadow_frame.SetVRegDouble(inst->VRegA_12x(), -shadow_frame.GetVRegDouble(inst->VRegB_12x()));
1241 inst = inst->Next_1xx();
1242 break;
1243 case Instruction::INT_TO_LONG:
1244 PREAMBLE();
1245 shadow_frame.SetVRegLong(inst->VRegA_12x(), shadow_frame.GetVReg(inst->VRegB_12x()));
1246 inst = inst->Next_1xx();
1247 break;
1248 case Instruction::INT_TO_FLOAT:
1249 PREAMBLE();
1250 shadow_frame.SetVRegFloat(inst->VRegA_12x(), shadow_frame.GetVReg(inst->VRegB_12x()));
1251 inst = inst->Next_1xx();
1252 break;
1253 case Instruction::INT_TO_DOUBLE:
1254 PREAMBLE();
1255 shadow_frame.SetVRegDouble(inst->VRegA_12x(), shadow_frame.GetVReg(inst->VRegB_12x()));
1256 inst = inst->Next_1xx();
1257 break;
1258 case Instruction::LONG_TO_INT:
1259 PREAMBLE();
1260 shadow_frame.SetVReg(inst->VRegA_12x(), shadow_frame.GetVRegLong(inst->VRegB_12x()));
1261 inst = inst->Next_1xx();
1262 break;
1263 case Instruction::LONG_TO_FLOAT:
1264 PREAMBLE();
1265 shadow_frame.SetVRegFloat(inst->VRegA_12x(), shadow_frame.GetVRegLong(inst->VRegB_12x()));
1266 inst = inst->Next_1xx();
1267 break;
1268 case Instruction::LONG_TO_DOUBLE:
1269 PREAMBLE();
1270 shadow_frame.SetVRegDouble(inst->VRegA_12x(), shadow_frame.GetVRegLong(inst->VRegB_12x()));
1271 inst = inst->Next_1xx();
1272 break;
1273 case Instruction::FLOAT_TO_INT: {
1274 PREAMBLE();
1275 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x());
1276 int32_t result;
1277 if (val != val) {
1278 result = 0;
1279 } else if (val > static_cast<float>(kMaxInt)) {
1280 result = kMaxInt;
1281 } else if (val < static_cast<float>(kMinInt)) {
1282 result = kMinInt;
1283 } else {
1284 result = val;
1285 }
1286 shadow_frame.SetVReg(inst->VRegA_12x(), result);
1287 inst = inst->Next_1xx();
1288 break;
1289 }
1290 case Instruction::FLOAT_TO_LONG: {
1291 PREAMBLE();
1292 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x());
1293 int64_t result;
1294 if (val != val) {
1295 result = 0;
1296 } else if (val > static_cast<float>(kMaxLong)) {
1297 result = kMaxLong;
1298 } else if (val < static_cast<float>(kMinLong)) {
1299 result = kMinLong;
1300 } else {
1301 result = val;
1302 }
1303 shadow_frame.SetVRegLong(inst->VRegA_12x(), result);
1304 inst = inst->Next_1xx();
1305 break;
1306 }
1307 case Instruction::FLOAT_TO_DOUBLE:
1308 PREAMBLE();
1309 shadow_frame.SetVRegDouble(inst->VRegA_12x(), shadow_frame.GetVRegFloat(inst->VRegB_12x()));
1310 inst = inst->Next_1xx();
1311 break;
1312 case Instruction::DOUBLE_TO_INT: {
1313 PREAMBLE();
1314 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x());
1315 int32_t result;
1316 if (val != val) {
1317 result = 0;
1318 } else if (val > static_cast<double>(kMaxInt)) {
1319 result = kMaxInt;
1320 } else if (val < static_cast<double>(kMinInt)) {
1321 result = kMinInt;
1322 } else {
1323 result = val;
1324 }
1325 shadow_frame.SetVReg(inst->VRegA_12x(), result);
1326 inst = inst->Next_1xx();
1327 break;
1328 }
1329 case Instruction::DOUBLE_TO_LONG: {
1330 PREAMBLE();
1331 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x());
1332 int64_t result;
1333 if (val != val) {
1334 result = 0;
1335 } else if (val > static_cast<double>(kMaxLong)) {
1336 result = kMaxLong;
1337 } else if (val < static_cast<double>(kMinLong)) {
1338 result = kMinLong;
1339 } else {
1340 result = val;
1341 }
1342 shadow_frame.SetVRegLong(inst->VRegA_12x(), result);
1343 inst = inst->Next_1xx();
1344 break;
1345 }
1346 case Instruction::DOUBLE_TO_FLOAT:
1347 PREAMBLE();
1348 shadow_frame.SetVRegFloat(inst->VRegA_12x(), shadow_frame.GetVRegDouble(inst->VRegB_12x()));
1349 inst = inst->Next_1xx();
1350 break;
1351 case Instruction::INT_TO_BYTE:
1352 PREAMBLE();
1353 shadow_frame.SetVReg(inst->VRegA_12x(),
1354 static_cast<int8_t>(shadow_frame.GetVReg(inst->VRegB_12x())));
1355 inst = inst->Next_1xx();
1356 break;
1357 case Instruction::INT_TO_CHAR:
1358 PREAMBLE();
1359 shadow_frame.SetVReg(inst->VRegA_12x(),
1360 static_cast<uint16_t>(shadow_frame.GetVReg(inst->VRegB_12x())));
1361 inst = inst->Next_1xx();
1362 break;
1363 case Instruction::INT_TO_SHORT:
1364 PREAMBLE();
1365 shadow_frame.SetVReg(inst->VRegA_12x(),
1366 static_cast<int16_t>(shadow_frame.GetVReg(inst->VRegB_12x())));
1367 inst = inst->Next_1xx();
1368 break;
1369 case Instruction::ADD_INT:
1370 PREAMBLE();
1371 shadow_frame.SetVReg(inst->VRegA_23x(),
1372 shadow_frame.GetVReg(inst->VRegB_23x()) +
1373 shadow_frame.GetVReg(inst->VRegC_23x()));
1374 inst = inst->Next_2xx();
1375 break;
1376 case Instruction::SUB_INT:
1377 PREAMBLE();
1378 shadow_frame.SetVReg(inst->VRegA_23x(),
1379 shadow_frame.GetVReg(inst->VRegB_23x()) -
1380 shadow_frame.GetVReg(inst->VRegC_23x()));
1381 inst = inst->Next_2xx();
1382 break;
1383 case Instruction::MUL_INT:
1384 PREAMBLE();
1385 shadow_frame.SetVReg(inst->VRegA_23x(),
1386 shadow_frame.GetVReg(inst->VRegB_23x()) *
1387 shadow_frame.GetVReg(inst->VRegC_23x()));
1388 inst = inst->Next_2xx();
1389 break;
1390 case Instruction::DIV_INT: {
1391 PREAMBLE();
1392 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(),
1393 shadow_frame.GetVReg(inst->VRegB_23x()),
1394 shadow_frame.GetVReg(inst->VRegC_23x()));
1395 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1396 break;
1397 }
1398 case Instruction::REM_INT: {
1399 PREAMBLE();
1400 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(),
1401 shadow_frame.GetVReg(inst->VRegB_23x()),
1402 shadow_frame.GetVReg(inst->VRegC_23x()));
1403 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1404 break;
1405 }
1406 case Instruction::SHL_INT:
1407 PREAMBLE();
1408 shadow_frame.SetVReg(inst->VRegA_23x(),
1409 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1410 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1411 inst = inst->Next_2xx();
1412 break;
1413 case Instruction::SHR_INT:
1414 PREAMBLE();
1415 shadow_frame.SetVReg(inst->VRegA_23x(),
1416 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1417 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1418 inst = inst->Next_2xx();
1419 break;
1420 case Instruction::USHR_INT:
1421 PREAMBLE();
1422 shadow_frame.SetVReg(inst->VRegA_23x(),
1423 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1424 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1425 inst = inst->Next_2xx();
1426 break;
1427 case Instruction::AND_INT:
1428 PREAMBLE();
1429 shadow_frame.SetVReg(inst->VRegA_23x(),
1430 shadow_frame.GetVReg(inst->VRegB_23x()) &
1431 shadow_frame.GetVReg(inst->VRegC_23x()));
1432 inst = inst->Next_2xx();
1433 break;
1434 case Instruction::OR_INT:
1435 PREAMBLE();
1436 shadow_frame.SetVReg(inst->VRegA_23x(),
1437 shadow_frame.GetVReg(inst->VRegB_23x()) |
1438 shadow_frame.GetVReg(inst->VRegC_23x()));
1439 inst = inst->Next_2xx();
1440 break;
1441 case Instruction::XOR_INT:
1442 PREAMBLE();
1443 shadow_frame.SetVReg(inst->VRegA_23x(),
1444 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1445 shadow_frame.GetVReg(inst->VRegC_23x()));
1446 inst = inst->Next_2xx();
1447 break;
1448 case Instruction::ADD_LONG:
1449 PREAMBLE();
1450 shadow_frame.SetVRegLong(inst->VRegA_23x(),
1451 shadow_frame.GetVRegLong(inst->VRegB_23x()) +
1452 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1453 inst = inst->Next_2xx();
1454 break;
1455 case Instruction::SUB_LONG:
1456 PREAMBLE();
1457 shadow_frame.SetVRegLong(inst->VRegA_23x(),
1458 shadow_frame.GetVRegLong(inst->VRegB_23x()) -
1459 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1460 inst = inst->Next_2xx();
1461 break;
1462 case Instruction::MUL_LONG:
1463 PREAMBLE();
1464 shadow_frame.SetVRegLong(inst->VRegA_23x(),
1465 shadow_frame.GetVRegLong(inst->VRegB_23x()) *
1466 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1467 inst = inst->Next_2xx();
1468 break;
1469 case Instruction::DIV_LONG:
1470 PREAMBLE();
1471 DoLongDivide(shadow_frame, inst->VRegA_23x(),
1472 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1473 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1474 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1475 break;
1476 case Instruction::REM_LONG:
1477 PREAMBLE();
1478 DoLongRemainder(shadow_frame, inst->VRegA_23x(),
1479 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1480 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1481 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1482 break;
1483 case Instruction::AND_LONG:
1484 PREAMBLE();
1485 shadow_frame.SetVRegLong(inst->VRegA_23x(),
1486 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1487 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1488 inst = inst->Next_2xx();
1489 break;
1490 case Instruction::OR_LONG:
1491 PREAMBLE();
1492 shadow_frame.SetVRegLong(inst->VRegA_23x(),
1493 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1494 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1495 inst = inst->Next_2xx();
1496 break;
1497 case Instruction::XOR_LONG:
1498 PREAMBLE();
1499 shadow_frame.SetVRegLong(inst->VRegA_23x(),
1500 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1501 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1502 inst = inst->Next_2xx();
1503 break;
1504 case Instruction::SHL_LONG:
1505 PREAMBLE();
1506 shadow_frame.SetVRegLong(inst->VRegA_23x(),
1507 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1508 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1509 inst = inst->Next_2xx();
1510 break;
1511 case Instruction::SHR_LONG:
1512 PREAMBLE();
1513 shadow_frame.SetVRegLong(inst->VRegA_23x(),
1514 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1515 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1516 inst = inst->Next_2xx();
1517 break;
1518 case Instruction::USHR_LONG:
1519 PREAMBLE();
1520 shadow_frame.SetVRegLong(inst->VRegA_23x(),
1521 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1522 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1523 inst = inst->Next_2xx();
1524 break;
1525 case Instruction::ADD_FLOAT:
1526 PREAMBLE();
1527 shadow_frame.SetVRegFloat(inst->VRegA_23x(),
1528 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1529 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1530 inst = inst->Next_2xx();
1531 break;
1532 case Instruction::SUB_FLOAT:
1533 PREAMBLE();
1534 shadow_frame.SetVRegFloat(inst->VRegA_23x(),
1535 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1536 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1537 inst = inst->Next_2xx();
1538 break;
1539 case Instruction::MUL_FLOAT:
1540 PREAMBLE();
1541 shadow_frame.SetVRegFloat(inst->VRegA_23x(),
1542 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1543 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1544 inst = inst->Next_2xx();
1545 break;
1546 case Instruction::DIV_FLOAT:
1547 PREAMBLE();
1548 shadow_frame.SetVRegFloat(inst->VRegA_23x(),
1549 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1550 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1551 inst = inst->Next_2xx();
1552 break;
1553 case Instruction::REM_FLOAT:
1554 PREAMBLE();
1555 shadow_frame.SetVRegFloat(inst->VRegA_23x(),
1556 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1557 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1558 inst = inst->Next_2xx();
1559 break;
1560 case Instruction::ADD_DOUBLE:
1561 PREAMBLE();
1562 shadow_frame.SetVRegDouble(inst->VRegA_23x(),
1563 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1564 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1565 inst = inst->Next_2xx();
1566 break;
1567 case Instruction::SUB_DOUBLE:
1568 PREAMBLE();
1569 shadow_frame.SetVRegDouble(inst->VRegA_23x(),
1570 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1571 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1572 inst = inst->Next_2xx();
1573 break;
1574 case Instruction::MUL_DOUBLE:
1575 PREAMBLE();
1576 shadow_frame.SetVRegDouble(inst->VRegA_23x(),
1577 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
1578 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1579 inst = inst->Next_2xx();
1580 break;
1581 case Instruction::DIV_DOUBLE:
1582 PREAMBLE();
1583 shadow_frame.SetVRegDouble(inst->VRegA_23x(),
1584 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
1585 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1586 inst = inst->Next_2xx();
1587 break;
1588 case Instruction::REM_DOUBLE:
1589 PREAMBLE();
1590 shadow_frame.SetVRegDouble(inst->VRegA_23x(),
1591 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
1592 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
1593 inst = inst->Next_2xx();
1594 break;
1595 case Instruction::ADD_INT_2ADDR: {
1596 PREAMBLE();
1597 uint4_t vregA = inst->VRegA_12x();
1598 shadow_frame.SetVReg(vregA,
1599 shadow_frame.GetVReg(vregA) +
1600 shadow_frame.GetVReg(inst->VRegB_12x()));
1601 inst = inst->Next_1xx();
1602 break;
1603 }
1604 case Instruction::SUB_INT_2ADDR: {
1605 PREAMBLE();
1606 uint4_t vregA = inst->VRegA_12x();
1607 shadow_frame.SetVReg(vregA,
1608 shadow_frame.GetVReg(vregA) -
1609 shadow_frame.GetVReg(inst->VRegB_12x()));
1610 inst = inst->Next_1xx();
1611 break;
1612 }
1613 case Instruction::MUL_INT_2ADDR: {
1614 PREAMBLE();
1615 uint4_t vregA = inst->VRegA_12x();
1616 shadow_frame.SetVReg(vregA,
1617 shadow_frame.GetVReg(vregA) *
1618 shadow_frame.GetVReg(inst->VRegB_12x()));
1619 inst = inst->Next_1xx();
1620 break;
1621 }
1622 case Instruction::DIV_INT_2ADDR: {
1623 PREAMBLE();
1624 uint4_t vregA = inst->VRegA_12x();
1625 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
1626 shadow_frame.GetVReg(inst->VRegB_12x()));
1627 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1628 break;
1629 }
1630 case Instruction::REM_INT_2ADDR: {
1631 PREAMBLE();
1632 uint4_t vregA = inst->VRegA_12x();
1633 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
1634 shadow_frame.GetVReg(inst->VRegB_12x()));
1635 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1636 break;
1637 }
1638 case Instruction::SHL_INT_2ADDR: {
1639 PREAMBLE();
1640 uint4_t vregA = inst->VRegA_12x();
1641 shadow_frame.SetVReg(vregA,
1642 shadow_frame.GetVReg(vregA) <<
1643 (shadow_frame.GetVReg(inst->VRegB_12x()) & 0x1f));
1644 inst = inst->Next_1xx();
1645 break;
1646 }
1647 case Instruction::SHR_INT_2ADDR: {
1648 PREAMBLE();
1649 uint4_t vregA = inst->VRegA_12x();
1650 shadow_frame.SetVReg(vregA,
1651 shadow_frame.GetVReg(vregA) >>
1652 (shadow_frame.GetVReg(inst->VRegB_12x()) & 0x1f));
1653 inst = inst->Next_1xx();
1654 break;
1655 }
1656 case Instruction::USHR_INT_2ADDR: {
1657 PREAMBLE();
1658 uint4_t vregA = inst->VRegA_12x();
1659 shadow_frame.SetVReg(vregA,
1660 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
1661 (shadow_frame.GetVReg(inst->VRegB_12x()) & 0x1f));
1662 inst = inst->Next_1xx();
1663 break;
1664 }
1665 case Instruction::AND_INT_2ADDR: {
1666 PREAMBLE();
1667 uint4_t vregA = inst->VRegA_12x();
1668 shadow_frame.SetVReg(vregA,
1669 shadow_frame.GetVReg(vregA) &
1670 shadow_frame.GetVReg(inst->VRegB_12x()));
1671 inst = inst->Next_1xx();
1672 break;
1673 }
1674 case Instruction::OR_INT_2ADDR: {
1675 PREAMBLE();
1676 uint4_t vregA = inst->VRegA_12x();
1677 shadow_frame.SetVReg(vregA,
1678 shadow_frame.GetVReg(vregA) |
1679 shadow_frame.GetVReg(inst->VRegB_12x()));
1680 inst = inst->Next_1xx();
1681 break;
1682 }
1683 case Instruction::XOR_INT_2ADDR: {
1684 PREAMBLE();
1685 uint4_t vregA = inst->VRegA_12x();
1686 shadow_frame.SetVReg(vregA,
1687 shadow_frame.GetVReg(vregA) ^
1688 shadow_frame.GetVReg(inst->VRegB_12x()));
1689 inst = inst->Next_1xx();
1690 break;
1691 }
1692 case Instruction::ADD_LONG_2ADDR: {
1693 PREAMBLE();
1694 uint4_t vregA = inst->VRegA_12x();
1695 shadow_frame.SetVRegLong(vregA,
1696 shadow_frame.GetVRegLong(vregA) +
1697 shadow_frame.GetVRegLong(inst->VRegB_12x()));
1698 inst = inst->Next_1xx();
1699 break;
1700 }
1701 case Instruction::SUB_LONG_2ADDR: {
1702 PREAMBLE();
1703 uint4_t vregA = inst->VRegA_12x();
1704 shadow_frame.SetVRegLong(vregA,
1705 shadow_frame.GetVRegLong(vregA) -
1706 shadow_frame.GetVRegLong(inst->VRegB_12x()));
1707 inst = inst->Next_1xx();
1708 break;
1709 }
1710 case Instruction::MUL_LONG_2ADDR: {
1711 PREAMBLE();
1712 uint4_t vregA = inst->VRegA_12x();
1713 shadow_frame.SetVRegLong(vregA,
1714 shadow_frame.GetVRegLong(vregA) *
1715 shadow_frame.GetVRegLong(inst->VRegB_12x()));
1716 inst = inst->Next_1xx();
1717 break;
1718 }
1719 case Instruction::DIV_LONG_2ADDR: {
1720 PREAMBLE();
1721 uint4_t vregA = inst->VRegA_12x();
1722 DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
1723 shadow_frame.GetVRegLong(inst->VRegB_12x()));
1724 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
1725 break;
1726 }
1727 case Instruction::REM_LONG_2ADDR: {
1728 PREAMBLE();
1729 uint4_t vregA = inst->VRegA_12x();
1730 DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
1731 shadow_frame.GetVRegLong(inst->VRegB_12x()));
1732 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
1733 break;
1734 }
1735 case Instruction::AND_LONG_2ADDR: {
1736 PREAMBLE();
1737 uint4_t vregA = inst->VRegA_12x();
1738 shadow_frame.SetVRegLong(vregA,
1739 shadow_frame.GetVRegLong(vregA) &
1740 shadow_frame.GetVRegLong(inst->VRegB_12x()));
1741 inst = inst->Next_1xx();
1742 break;
1743 }
1744 case Instruction::OR_LONG_2ADDR: {
1745 PREAMBLE();
1746 uint4_t vregA = inst->VRegA_12x();
1747 shadow_frame.SetVRegLong(vregA,
1748 shadow_frame.GetVRegLong(vregA) |
1749 shadow_frame.GetVRegLong(inst->VRegB_12x()));
1750 inst = inst->Next_1xx();
1751 break;
1752 }
1753 case Instruction::XOR_LONG_2ADDR: {
1754 PREAMBLE();
1755 uint4_t vregA = inst->VRegA_12x();
1756 shadow_frame.SetVRegLong(vregA,
1757 shadow_frame.GetVRegLong(vregA) ^
1758 shadow_frame.GetVRegLong(inst->VRegB_12x()));
1759 inst = inst->Next_1xx();
1760 break;
1761 }
1762 case Instruction::SHL_LONG_2ADDR: {
1763 PREAMBLE();
1764 uint4_t vregA = inst->VRegA_12x();
1765 shadow_frame.SetVRegLong(vregA,
1766 shadow_frame.GetVRegLong(vregA) <<
1767 (shadow_frame.GetVReg(inst->VRegB_12x()) & 0x3f));
1768 inst = inst->Next_1xx();
1769 break;
1770 }
1771 case Instruction::SHR_LONG_2ADDR: {
1772 PREAMBLE();
1773 uint4_t vregA = inst->VRegA_12x();
1774 shadow_frame.SetVRegLong(vregA,
1775 shadow_frame.GetVRegLong(vregA) >>
1776 (shadow_frame.GetVReg(inst->VRegB_12x()) & 0x3f));
1777 inst = inst->Next_1xx();
1778 break;
1779 }
1780 case Instruction::USHR_LONG_2ADDR: {
1781 PREAMBLE();
1782 uint4_t vregA = inst->VRegA_12x();
1783 shadow_frame.SetVRegLong(vregA,
1784 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
1785 (shadow_frame.GetVReg(inst->VRegB_12x()) & 0x3f));
1786 inst = inst->Next_1xx();
1787 break;
1788 }
1789 case Instruction::ADD_FLOAT_2ADDR: {
1790 PREAMBLE();
1791 uint4_t vregA = inst->VRegA_12x();
1792 shadow_frame.SetVRegFloat(vregA,
1793 shadow_frame.GetVRegFloat(vregA) +
1794 shadow_frame.GetVRegFloat(inst->VRegB_12x()));
1795 inst = inst->Next_1xx();
1796 break;
1797 }
1798 case Instruction::SUB_FLOAT_2ADDR: {
1799 PREAMBLE();
1800 uint4_t vregA = inst->VRegA_12x();
1801 shadow_frame.SetVRegFloat(vregA,
1802 shadow_frame.GetVRegFloat(vregA) -
1803 shadow_frame.GetVRegFloat(inst->VRegB_12x()));
1804 inst = inst->Next_1xx();
1805 break;
1806 }
1807 case Instruction::MUL_FLOAT_2ADDR: {
1808 PREAMBLE();
1809 uint4_t vregA = inst->VRegA_12x();
1810 shadow_frame.SetVRegFloat(vregA,
1811 shadow_frame.GetVRegFloat(vregA) *
1812 shadow_frame.GetVRegFloat(inst->VRegB_12x()));
1813 inst = inst->Next_1xx();
1814 break;
1815 }
1816 case Instruction::DIV_FLOAT_2ADDR: {
1817 PREAMBLE();
1818 uint4_t vregA = inst->VRegA_12x();
1819 shadow_frame.SetVRegFloat(vregA,
1820 shadow_frame.GetVRegFloat(vregA) /
1821 shadow_frame.GetVRegFloat(inst->VRegB_12x()));
1822 inst = inst->Next_1xx();
1823 break;
1824 }
1825 case Instruction::REM_FLOAT_2ADDR: {
1826 PREAMBLE();
1827 uint4_t vregA = inst->VRegA_12x();
1828 shadow_frame.SetVRegFloat(vregA,
1829 fmodf(shadow_frame.GetVRegFloat(vregA),
1830 shadow_frame.GetVRegFloat(inst->VRegB_12x())));
1831 inst = inst->Next_1xx();
1832 break;
1833 }
1834 case Instruction::ADD_DOUBLE_2ADDR: {
1835 PREAMBLE();
1836 uint4_t vregA = inst->VRegA_12x();
1837 shadow_frame.SetVRegDouble(vregA,
1838 shadow_frame.GetVRegDouble(vregA) +
1839 shadow_frame.GetVRegDouble(inst->VRegB_12x()));
1840 inst = inst->Next_1xx();
1841 break;
1842 }
1843 case Instruction::SUB_DOUBLE_2ADDR: {
1844 PREAMBLE();
1845 uint4_t vregA = inst->VRegA_12x();
1846 shadow_frame.SetVRegDouble(vregA,
1847 shadow_frame.GetVRegDouble(vregA) -
1848 shadow_frame.GetVRegDouble(inst->VRegB_12x()));
1849 inst = inst->Next_1xx();
1850 break;
1851 }
1852 case Instruction::MUL_DOUBLE_2ADDR: {
1853 PREAMBLE();
1854 uint4_t vregA = inst->VRegA_12x();
1855 shadow_frame.SetVRegDouble(vregA,
1856 shadow_frame.GetVRegDouble(vregA) *
1857 shadow_frame.GetVRegDouble(inst->VRegB_12x()));
1858 inst = inst->Next_1xx();
1859 break;
1860 }
1861 case Instruction::DIV_DOUBLE_2ADDR: {
1862 PREAMBLE();
1863 uint4_t vregA = inst->VRegA_12x();
1864 shadow_frame.SetVRegDouble(vregA,
1865 shadow_frame.GetVRegDouble(vregA) /
1866 shadow_frame.GetVRegDouble(inst->VRegB_12x()));
1867 inst = inst->Next_1xx();
1868 break;
1869 }
1870 case Instruction::REM_DOUBLE_2ADDR: {
1871 PREAMBLE();
1872 uint4_t vregA = inst->VRegA_12x();
1873 shadow_frame.SetVRegDouble(vregA,
1874 fmod(shadow_frame.GetVRegDouble(vregA),
1875 shadow_frame.GetVRegDouble(inst->VRegB_12x())));
1876 inst = inst->Next_1xx();
1877 break;
1878 }
1879 case Instruction::ADD_INT_LIT16:
1880 PREAMBLE();
1881 shadow_frame.SetVReg(inst->VRegA_22s(),
1882 shadow_frame.GetVReg(inst->VRegB_22s()) +
1883 inst->VRegC_22s());
1884 inst = inst->Next_2xx();
1885 break;
1886 case Instruction::RSUB_INT:
1887 PREAMBLE();
1888 shadow_frame.SetVReg(inst->VRegA_22s(),
1889 inst->VRegC_22s() -
1890 shadow_frame.GetVReg(inst->VRegB_22s()));
1891 inst = inst->Next_2xx();
1892 break;
1893 case Instruction::MUL_INT_LIT16:
1894 PREAMBLE();
1895 shadow_frame.SetVReg(inst->VRegA_22s(),
1896 shadow_frame.GetVReg(inst->VRegB_22s()) *
1897 inst->VRegC_22s());
1898 inst = inst->Next_2xx();
1899 break;
1900 case Instruction::DIV_INT_LIT16: {
1901 PREAMBLE();
1902 bool success = DoIntDivide(shadow_frame, inst->VRegA_22s(),
1903 shadow_frame.GetVReg(inst->VRegB_22s()), inst->VRegC_22s());
1904 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1905 break;
1906 }
1907 case Instruction::REM_INT_LIT16: {
1908 PREAMBLE();
1909 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22s(),
1910 shadow_frame.GetVReg(inst->VRegB_22s()), inst->VRegC_22s());
1911 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1912 break;
1913 }
1914 case Instruction::AND_INT_LIT16:
1915 PREAMBLE();
1916 shadow_frame.SetVReg(inst->VRegA_22s(),
1917 shadow_frame.GetVReg(inst->VRegB_22s()) &
1918 inst->VRegC_22s());
1919 inst = inst->Next_2xx();
1920 break;
1921 case Instruction::OR_INT_LIT16:
1922 PREAMBLE();
1923 shadow_frame.SetVReg(inst->VRegA_22s(),
1924 shadow_frame.GetVReg(inst->VRegB_22s()) |
1925 inst->VRegC_22s());
1926 inst = inst->Next_2xx();
1927 break;
1928 case Instruction::XOR_INT_LIT16:
1929 PREAMBLE();
1930 shadow_frame.SetVReg(inst->VRegA_22s(),
1931 shadow_frame.GetVReg(inst->VRegB_22s()) ^
1932 inst->VRegC_22s());
1933 inst = inst->Next_2xx();
1934 break;
1935 case Instruction::ADD_INT_LIT8:
1936 PREAMBLE();
1937 shadow_frame.SetVReg(inst->VRegA_22b(),
1938 shadow_frame.GetVReg(inst->VRegB_22b()) +
1939 inst->VRegC_22b());
1940 inst = inst->Next_2xx();
1941 break;
1942 case Instruction::RSUB_INT_LIT8:
1943 PREAMBLE();
1944 shadow_frame.SetVReg(inst->VRegA_22b(),
1945 inst->VRegC_22b() -
1946 shadow_frame.GetVReg(inst->VRegB_22b()));
1947 inst = inst->Next_2xx();
1948 break;
1949 case Instruction::MUL_INT_LIT8:
1950 PREAMBLE();
1951 shadow_frame.SetVReg(inst->VRegA_22b(),
1952 shadow_frame.GetVReg(inst->VRegB_22b()) *
1953 inst->VRegC_22b());
1954 inst = inst->Next_2xx();
1955 break;
1956 case Instruction::DIV_INT_LIT8: {
1957 PREAMBLE();
1958 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(),
1959 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
1960 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1961 break;
1962 }
1963 case Instruction::REM_INT_LIT8: {
1964 PREAMBLE();
1965 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(),
1966 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
1967 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1968 break;
1969 }
1970 case Instruction::AND_INT_LIT8:
1971 PREAMBLE();
1972 shadow_frame.SetVReg(inst->VRegA_22b(),
1973 shadow_frame.GetVReg(inst->VRegB_22b()) &
1974 inst->VRegC_22b());
1975 inst = inst->Next_2xx();
1976 break;
1977 case Instruction::OR_INT_LIT8:
1978 PREAMBLE();
1979 shadow_frame.SetVReg(inst->VRegA_22b(),
1980 shadow_frame.GetVReg(inst->VRegB_22b()) |
1981 inst->VRegC_22b());
1982 inst = inst->Next_2xx();
1983 break;
1984 case Instruction::XOR_INT_LIT8:
1985 PREAMBLE();
1986 shadow_frame.SetVReg(inst->VRegA_22b(),
1987 shadow_frame.GetVReg(inst->VRegB_22b()) ^
1988 inst->VRegC_22b());
1989 inst = inst->Next_2xx();
1990 break;
1991 case Instruction::SHL_INT_LIT8:
1992 PREAMBLE();
1993 shadow_frame.SetVReg(inst->VRegA_22b(),
1994 shadow_frame.GetVReg(inst->VRegB_22b()) <<
1995 (inst->VRegC_22b() & 0x1f));
1996 inst = inst->Next_2xx();
1997 break;
1998 case Instruction::SHR_INT_LIT8:
1999 PREAMBLE();
2000 shadow_frame.SetVReg(inst->VRegA_22b(),
2001 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2002 (inst->VRegC_22b() & 0x1f));
2003 inst = inst->Next_2xx();
2004 break;
2005 case Instruction::USHR_INT_LIT8:
2006 PREAMBLE();
2007 shadow_frame.SetVReg(inst->VRegA_22b(),
2008 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2009 (inst->VRegC_22b() & 0x1f));
2010 inst = inst->Next_2xx();
2011 break;
2012 case Instruction::UNUSED_3E ... Instruction::UNUSED_43:
2013 case Instruction::UNUSED_EB ... Instruction::UNUSED_FF:
2014 case Instruction::UNUSED_79:
2015 case Instruction::UNUSED_7A:
2016 UnexpectedOpcode(inst, mh);
2017 }
2018 }
2019} // NOLINT(readability/fn_size)
2020
2021// Explicit definitions of ExecuteSwitchImpl.
2022template JValue ExecuteSwitchImpl<true>(Thread* self, MethodHelper& mh,
2023 const DexFile::CodeItem* code_item,
2024 ShadowFrame& shadow_frame, JValue result_register);
2025template JValue ExecuteSwitchImpl<false>(Thread* self, MethodHelper& mh,
2026 const DexFile::CodeItem* code_item,
2027 ShadowFrame& shadow_frame, JValue result_register);
2028
2029} // namespace interpreter
2030} // namespace art