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