interpreter_switch_impl.cc revision 45b1597c152af90f6d5792d02b64fd4e7c81ac9d
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 instrumentation::Instrumentation* 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 != NULL) {
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 == NULL) {
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, NULL);
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, NULL);
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, NULL);
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, NULL);
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 == NULL)) {
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 == NULL)) {
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 == NULL)) {
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 == NULL)) {
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 == NULL)) {
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 == NULL)) {
391          HANDLE_PENDING_EXCEPTION();
392        } else {
393          Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
394          if (UNLIKELY(obj != NULL && !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 == NULL)) {
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), (obj != NULL && obj->InstanceOf(c)) ? 1 : 0);
412          inst = inst->Next_2xx();
413        }
414        break;
415      }
416      case Instruction::ARRAY_LENGTH:  {
417        PREAMBLE();
418        Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
419        if (UNLIKELY(array == NULL)) {
420          ThrowNullPointerExceptionFromInterpreter();
421          HANDLE_PENDING_EXCEPTION();
422        } else {
423          shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
424          inst = inst->Next_1xx();
425        }
426        break;
427      }
428      case Instruction::NEW_INSTANCE: {
429        PREAMBLE();
430        Runtime* runtime = Runtime::Current();
431        Object* obj = AllocObjectFromCode<do_access_check, true>(
432            inst->VRegB_21c(), shadow_frame.GetMethod(), self,
433            runtime->GetHeap()->GetCurrentAllocator());
434        if (UNLIKELY(obj == NULL)) {
435          HANDLE_PENDING_EXCEPTION();
436        } else {
437          obj->GetClass()->AssertInitializedOrInitializingInThread(self);
438          // Don't allow finalizable objects to be allocated during a transaction since these can't
439          // be finalized without a started runtime.
440          if (transaction_active && obj->GetClass()->IsFinalizable()) {
441            AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
442                              PrettyTypeOf(obj).c_str());
443            HANDLE_PENDING_EXCEPTION();
444            break;
445          }
446          shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
447          inst = inst->Next_2xx();
448        }
449        break;
450      }
451      case Instruction::NEW_ARRAY: {
452        PREAMBLE();
453        int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
454        Object* obj = AllocArrayFromCode<do_access_check, true>(
455            inst->VRegC_22c(), length, shadow_frame.GetMethod(), self,
456            Runtime::Current()->GetHeap()->GetCurrentAllocator());
457        if (UNLIKELY(obj == NULL)) {
458          HANDLE_PENDING_EXCEPTION();
459        } else {
460          shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
461          inst = inst->Next_2xx();
462        }
463        break;
464      }
465      case Instruction::FILLED_NEW_ARRAY: {
466        PREAMBLE();
467        bool success =
468            DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame, self,
469                                                                         &result_register);
470        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
471        break;
472      }
473      case Instruction::FILLED_NEW_ARRAY_RANGE: {
474        PREAMBLE();
475        bool success =
476            DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
477                                                                        self, &result_register);
478        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
479        break;
480      }
481      case Instruction::FILL_ARRAY_DATA: {
482        PREAMBLE();
483        const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
484        const Instruction::ArrayDataPayload* payload =
485            reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
486        Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
487        bool success = FillArrayData(obj, payload);
488        if (!success) {
489          HANDLE_PENDING_EXCEPTION();
490          break;
491        }
492        if (transaction_active) {
493          RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
494        }
495        inst = inst->Next_3xx();
496        break;
497      }
498      case Instruction::THROW: {
499        PREAMBLE();
500        Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
501        if (UNLIKELY(exception == NULL)) {
502          ThrowNullPointerException("throw with null exception");
503        } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
504          // This should never happen.
505          std::string temp;
506          self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
507                                   "Throwing '%s' that is not instance of Throwable",
508                                   exception->GetClass()->GetDescriptor(&temp));
509        } else {
510          self->SetException(exception->AsThrowable());
511        }
512        HANDLE_PENDING_EXCEPTION();
513        break;
514      }
515      case Instruction::GOTO: {
516        PREAMBLE();
517        int8_t offset = inst->VRegA_10t(inst_data);
518        if (IsBackwardBranch(offset)) {
519          self->AllowThreadSuspension();
520        }
521        inst = inst->RelativeAt(offset);
522        break;
523      }
524      case Instruction::GOTO_16: {
525        PREAMBLE();
526        int16_t offset = inst->VRegA_20t();
527        if (IsBackwardBranch(offset)) {
528          self->AllowThreadSuspension();
529        }
530        inst = inst->RelativeAt(offset);
531        break;
532      }
533      case Instruction::GOTO_32: {
534        PREAMBLE();
535        int32_t offset = inst->VRegA_30t();
536        if (IsBackwardBranch(offset)) {
537          self->AllowThreadSuspension();
538        }
539        inst = inst->RelativeAt(offset);
540        break;
541      }
542      case Instruction::PACKED_SWITCH: {
543        PREAMBLE();
544        int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
545        if (IsBackwardBranch(offset)) {
546          self->AllowThreadSuspension();
547        }
548        inst = inst->RelativeAt(offset);
549        break;
550      }
551      case Instruction::SPARSE_SWITCH: {
552        PREAMBLE();
553        int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
554        if (IsBackwardBranch(offset)) {
555          self->AllowThreadSuspension();
556        }
557        inst = inst->RelativeAt(offset);
558        break;
559      }
560
561#if defined(__clang__)
562#pragma clang diagnostic push
563#pragma clang diagnostic ignored "-Wfloat-equal"
564#endif
565
566      case Instruction::CMPL_FLOAT: {
567        PREAMBLE();
568        float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
569        float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
570        int32_t result;
571        if (val1 > val2) {
572          result = 1;
573        } else if (val1 == val2) {
574          result = 0;
575        } else {
576          result = -1;
577        }
578        shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
579        inst = inst->Next_2xx();
580        break;
581      }
582      case Instruction::CMPG_FLOAT: {
583        PREAMBLE();
584        float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
585        float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
586        int32_t result;
587        if (val1 < val2) {
588          result = -1;
589        } else if (val1 == val2) {
590          result = 0;
591        } else {
592          result = 1;
593        }
594        shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
595        inst = inst->Next_2xx();
596        break;
597      }
598      case Instruction::CMPL_DOUBLE: {
599        PREAMBLE();
600        double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
601        double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
602        int32_t result;
603        if (val1 > val2) {
604          result = 1;
605        } else if (val1 == val2) {
606          result = 0;
607        } else {
608          result = -1;
609        }
610        shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
611        inst = inst->Next_2xx();
612        break;
613      }
614
615      case Instruction::CMPG_DOUBLE: {
616        PREAMBLE();
617        double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
618        double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
619        int32_t result;
620        if (val1 < val2) {
621          result = -1;
622        } else if (val1 == val2) {
623          result = 0;
624        } else {
625          result = 1;
626        }
627        shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
628        inst = inst->Next_2xx();
629        break;
630      }
631
632#if defined(__clang__)
633#pragma clang diagnostic pop
634#endif
635
636      case Instruction::CMP_LONG: {
637        PREAMBLE();
638        int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
639        int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
640        int32_t result;
641        if (val1 > val2) {
642          result = 1;
643        } else if (val1 == val2) {
644          result = 0;
645        } else {
646          result = -1;
647        }
648        shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
649        inst = inst->Next_2xx();
650        break;
651      }
652      case Instruction::IF_EQ: {
653        PREAMBLE();
654        if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) == shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
655          int16_t offset = inst->VRegC_22t();
656          if (IsBackwardBranch(offset)) {
657            self->AllowThreadSuspension();
658          }
659          inst = inst->RelativeAt(offset);
660        } else {
661          inst = inst->Next_2xx();
662        }
663        break;
664      }
665      case Instruction::IF_NE: {
666        PREAMBLE();
667        if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) != shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
668          int16_t offset = inst->VRegC_22t();
669          if (IsBackwardBranch(offset)) {
670            self->AllowThreadSuspension();
671          }
672          inst = inst->RelativeAt(offset);
673        } else {
674          inst = inst->Next_2xx();
675        }
676        break;
677      }
678      case Instruction::IF_LT: {
679        PREAMBLE();
680        if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) < 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_GE: {
692        PREAMBLE();
693        if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >= shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
694          int16_t offset = inst->VRegC_22t();
695          if (IsBackwardBranch(offset)) {
696            self->AllowThreadSuspension();
697          }
698          inst = inst->RelativeAt(offset);
699        } else {
700          inst = inst->Next_2xx();
701        }
702        break;
703      }
704      case Instruction::IF_GT: {
705        PREAMBLE();
706        if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) > shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
707          int16_t offset = inst->VRegC_22t();
708          if (IsBackwardBranch(offset)) {
709            self->AllowThreadSuspension();
710          }
711          inst = inst->RelativeAt(offset);
712        } else {
713          inst = inst->Next_2xx();
714        }
715        break;
716      }
717      case Instruction::IF_LE: {
718        PREAMBLE();
719        if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <= shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
720          int16_t offset = inst->VRegC_22t();
721          if (IsBackwardBranch(offset)) {
722            self->AllowThreadSuspension();
723          }
724          inst = inst->RelativeAt(offset);
725        } else {
726          inst = inst->Next_2xx();
727        }
728        break;
729      }
730      case Instruction::IF_EQZ: {
731        PREAMBLE();
732        if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
733          int16_t offset = inst->VRegB_21t();
734          if (IsBackwardBranch(offset)) {
735            self->AllowThreadSuspension();
736          }
737          inst = inst->RelativeAt(offset);
738        } else {
739          inst = inst->Next_2xx();
740        }
741        break;
742      }
743      case Instruction::IF_NEZ: {
744        PREAMBLE();
745        if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
746          int16_t offset = inst->VRegB_21t();
747          if (IsBackwardBranch(offset)) {
748            self->AllowThreadSuspension();
749          }
750          inst = inst->RelativeAt(offset);
751        } else {
752          inst = inst->Next_2xx();
753        }
754        break;
755      }
756      case Instruction::IF_LTZ: {
757        PREAMBLE();
758        if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
759          int16_t offset = inst->VRegB_21t();
760          if (IsBackwardBranch(offset)) {
761            self->AllowThreadSuspension();
762          }
763          inst = inst->RelativeAt(offset);
764        } else {
765          inst = inst->Next_2xx();
766        }
767        break;
768      }
769      case Instruction::IF_GEZ: {
770        PREAMBLE();
771        if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
772          int16_t offset = inst->VRegB_21t();
773          if (IsBackwardBranch(offset)) {
774            self->AllowThreadSuspension();
775          }
776          inst = inst->RelativeAt(offset);
777        } else {
778          inst = inst->Next_2xx();
779        }
780        break;
781      }
782      case Instruction::IF_GTZ: {
783        PREAMBLE();
784        if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
785          int16_t offset = inst->VRegB_21t();
786          if (IsBackwardBranch(offset)) {
787            self->AllowThreadSuspension();
788          }
789          inst = inst->RelativeAt(offset);
790        } else {
791          inst = inst->Next_2xx();
792        }
793        break;
794      }
795      case Instruction::IF_LEZ:  {
796        PREAMBLE();
797        if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
798          int16_t offset = inst->VRegB_21t();
799          if (IsBackwardBranch(offset)) {
800            self->AllowThreadSuspension();
801          }
802          inst = inst->RelativeAt(offset);
803        } else {
804          inst = inst->Next_2xx();
805        }
806        break;
807      }
808      case Instruction::AGET_BOOLEAN: {
809        PREAMBLE();
810        Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
811        if (UNLIKELY(a == NULL)) {
812          ThrowNullPointerExceptionFromInterpreter();
813          HANDLE_PENDING_EXCEPTION();
814          break;
815        }
816        int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
817        BooleanArray* array = a->AsBooleanArray();
818        if (array->CheckIsValidIndex(index)) {
819          shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
820          inst = inst->Next_2xx();
821        } else {
822          HANDLE_PENDING_EXCEPTION();
823        }
824        break;
825      }
826      case Instruction::AGET_BYTE: {
827        PREAMBLE();
828        Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
829        if (UNLIKELY(a == NULL)) {
830          ThrowNullPointerExceptionFromInterpreter();
831          HANDLE_PENDING_EXCEPTION();
832          break;
833        }
834        int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
835        ByteArray* array = a->AsByteArray();
836        if (array->CheckIsValidIndex(index)) {
837          shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
838          inst = inst->Next_2xx();
839        } else {
840          HANDLE_PENDING_EXCEPTION();
841        }
842        break;
843      }
844      case Instruction::AGET_CHAR: {
845        PREAMBLE();
846        Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
847        if (UNLIKELY(a == NULL)) {
848          ThrowNullPointerExceptionFromInterpreter();
849          HANDLE_PENDING_EXCEPTION();
850          break;
851        }
852        int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
853        CharArray* array = a->AsCharArray();
854        if (array->CheckIsValidIndex(index)) {
855          shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
856          inst = inst->Next_2xx();
857        } else {
858          HANDLE_PENDING_EXCEPTION();
859        }
860        break;
861      }
862      case Instruction::AGET_SHORT: {
863        PREAMBLE();
864        Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
865        if (UNLIKELY(a == NULL)) {
866          ThrowNullPointerExceptionFromInterpreter();
867          HANDLE_PENDING_EXCEPTION();
868          break;
869        }
870        int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
871        ShortArray* array = a->AsShortArray();
872        if (array->CheckIsValidIndex(index)) {
873          shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
874          inst = inst->Next_2xx();
875        } else {
876          HANDLE_PENDING_EXCEPTION();
877        }
878        break;
879      }
880      case Instruction::AGET: {
881        PREAMBLE();
882        Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
883        if (UNLIKELY(a == NULL)) {
884          ThrowNullPointerExceptionFromInterpreter();
885          HANDLE_PENDING_EXCEPTION();
886          break;
887        }
888        int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
889        IntArray* array = a->AsIntArray();
890        if (array->CheckIsValidIndex(index)) {
891          shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
892          inst = inst->Next_2xx();
893        } else {
894          HANDLE_PENDING_EXCEPTION();
895        }
896        break;
897      }
898      case Instruction::AGET_WIDE:  {
899        PREAMBLE();
900        Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
901        if (UNLIKELY(a == NULL)) {
902          ThrowNullPointerExceptionFromInterpreter();
903          HANDLE_PENDING_EXCEPTION();
904          break;
905        }
906        int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
907        LongArray* array = a->AsLongArray();
908        if (array->CheckIsValidIndex(index)) {
909          shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
910          inst = inst->Next_2xx();
911        } else {
912          HANDLE_PENDING_EXCEPTION();
913        }
914        break;
915      }
916      case Instruction::AGET_OBJECT: {
917        PREAMBLE();
918        Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
919        if (UNLIKELY(a == NULL)) {
920          ThrowNullPointerExceptionFromInterpreter();
921          HANDLE_PENDING_EXCEPTION();
922          break;
923        }
924        int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
925        ObjectArray<Object>* array = a->AsObjectArray<Object>();
926        if (array->CheckIsValidIndex(index)) {
927          shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
928          inst = inst->Next_2xx();
929        } else {
930          HANDLE_PENDING_EXCEPTION();
931        }
932        break;
933      }
934      case Instruction::APUT_BOOLEAN: {
935        PREAMBLE();
936        Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
937        if (UNLIKELY(a == NULL)) {
938          ThrowNullPointerExceptionFromInterpreter();
939          HANDLE_PENDING_EXCEPTION();
940          break;
941        }
942        uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
943        int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
944        BooleanArray* array = a->AsBooleanArray();
945        if (array->CheckIsValidIndex(index)) {
946          array->SetWithoutChecks<transaction_active>(index, val);
947          inst = inst->Next_2xx();
948        } else {
949          HANDLE_PENDING_EXCEPTION();
950        }
951        break;
952      }
953      case Instruction::APUT_BYTE: {
954        PREAMBLE();
955        Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
956        if (UNLIKELY(a == NULL)) {
957          ThrowNullPointerExceptionFromInterpreter();
958          HANDLE_PENDING_EXCEPTION();
959          break;
960        }
961        int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
962        int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
963        ByteArray* array = a->AsByteArray();
964        if (array->CheckIsValidIndex(index)) {
965          array->SetWithoutChecks<transaction_active>(index, val);
966          inst = inst->Next_2xx();
967        } else {
968          HANDLE_PENDING_EXCEPTION();
969        }
970        break;
971      }
972      case Instruction::APUT_CHAR: {
973        PREAMBLE();
974        Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
975        if (UNLIKELY(a == NULL)) {
976          ThrowNullPointerExceptionFromInterpreter();
977          HANDLE_PENDING_EXCEPTION();
978          break;
979        }
980        uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
981        int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
982        CharArray* array = a->AsCharArray();
983        if (array->CheckIsValidIndex(index)) {
984          array->SetWithoutChecks<transaction_active>(index, val);
985          inst = inst->Next_2xx();
986        } else {
987          HANDLE_PENDING_EXCEPTION();
988        }
989        break;
990      }
991      case Instruction::APUT_SHORT: {
992        PREAMBLE();
993        Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
994        if (UNLIKELY(a == NULL)) {
995          ThrowNullPointerExceptionFromInterpreter();
996          HANDLE_PENDING_EXCEPTION();
997          break;
998        }
999        int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
1000        int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1001        ShortArray* array = a->AsShortArray();
1002        if (array->CheckIsValidIndex(index)) {
1003          array->SetWithoutChecks<transaction_active>(index, val);
1004          inst = inst->Next_2xx();
1005        } else {
1006          HANDLE_PENDING_EXCEPTION();
1007        }
1008        break;
1009      }
1010      case Instruction::APUT: {
1011        PREAMBLE();
1012        Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1013        if (UNLIKELY(a == NULL)) {
1014          ThrowNullPointerExceptionFromInterpreter();
1015          HANDLE_PENDING_EXCEPTION();
1016          break;
1017        }
1018        int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
1019        int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1020        IntArray* array = a->AsIntArray();
1021        if (array->CheckIsValidIndex(index)) {
1022          array->SetWithoutChecks<transaction_active>(index, val);
1023          inst = inst->Next_2xx();
1024        } else {
1025          HANDLE_PENDING_EXCEPTION();
1026        }
1027        break;
1028      }
1029      case Instruction::APUT_WIDE: {
1030        PREAMBLE();
1031        Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1032        if (UNLIKELY(a == NULL)) {
1033          ThrowNullPointerExceptionFromInterpreter();
1034          HANDLE_PENDING_EXCEPTION();
1035          break;
1036        }
1037        int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
1038        int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1039        LongArray* array = a->AsLongArray();
1040        if (array->CheckIsValidIndex(index)) {
1041          array->SetWithoutChecks<transaction_active>(index, val);
1042          inst = inst->Next_2xx();
1043        } else {
1044          HANDLE_PENDING_EXCEPTION();
1045        }
1046        break;
1047      }
1048      case Instruction::APUT_OBJECT: {
1049        PREAMBLE();
1050        Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1051        if (UNLIKELY(a == NULL)) {
1052          ThrowNullPointerExceptionFromInterpreter();
1053          HANDLE_PENDING_EXCEPTION();
1054          break;
1055        }
1056        int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1057        Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
1058        ObjectArray<Object>* array = a->AsObjectArray<Object>();
1059        if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
1060          array->SetWithoutChecks<transaction_active>(index, val);
1061          inst = inst->Next_2xx();
1062        } else {
1063          HANDLE_PENDING_EXCEPTION();
1064        }
1065        break;
1066      }
1067      case Instruction::IGET_BOOLEAN: {
1068        PREAMBLE();
1069        bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst, inst_data);
1070        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1071        break;
1072      }
1073      case Instruction::IGET_BYTE: {
1074        PREAMBLE();
1075        bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst, inst_data);
1076        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1077        break;
1078      }
1079      case Instruction::IGET_CHAR: {
1080        PREAMBLE();
1081        bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst, inst_data);
1082        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1083        break;
1084      }
1085      case Instruction::IGET_SHORT: {
1086        PREAMBLE();
1087        bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst, inst_data);
1088        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1089        break;
1090      }
1091      case Instruction::IGET: {
1092        PREAMBLE();
1093        bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst, inst_data);
1094        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1095        break;
1096      }
1097      case Instruction::IGET_WIDE: {
1098        PREAMBLE();
1099        bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst, inst_data);
1100        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1101        break;
1102      }
1103      case Instruction::IGET_OBJECT: {
1104        PREAMBLE();
1105        bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst, inst_data);
1106        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1107        break;
1108      }
1109      case Instruction::IGET_QUICK: {
1110        PREAMBLE();
1111        bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
1112        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1113        break;
1114      }
1115      case Instruction::IGET_WIDE_QUICK: {
1116        PREAMBLE();
1117        bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
1118        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1119        break;
1120      }
1121      case Instruction::IGET_OBJECT_QUICK: {
1122        PREAMBLE();
1123        bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
1124        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1125        break;
1126      }
1127      case Instruction::IGET_BOOLEAN_QUICK: {
1128        PREAMBLE();
1129        bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1130        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1131        break;
1132      }
1133      case Instruction::IGET_BYTE_QUICK: {
1134        PREAMBLE();
1135        bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1136        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1137        break;
1138      }
1139      case Instruction::IGET_CHAR_QUICK: {
1140        PREAMBLE();
1141        bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1142        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1143        break;
1144      }
1145      case Instruction::IGET_SHORT_QUICK: {
1146        PREAMBLE();
1147        bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1148        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1149        break;
1150      }
1151      case Instruction::SGET_BOOLEAN: {
1152        PREAMBLE();
1153        bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst, inst_data);
1154        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1155        break;
1156      }
1157      case Instruction::SGET_BYTE: {
1158        PREAMBLE();
1159        bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst, inst_data);
1160        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1161        break;
1162      }
1163      case Instruction::SGET_CHAR: {
1164        PREAMBLE();
1165        bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst, inst_data);
1166        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1167        break;
1168      }
1169      case Instruction::SGET_SHORT: {
1170        PREAMBLE();
1171        bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst, inst_data);
1172        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1173        break;
1174      }
1175      case Instruction::SGET: {
1176        PREAMBLE();
1177        bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst, inst_data);
1178        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1179        break;
1180      }
1181      case Instruction::SGET_WIDE: {
1182        PREAMBLE();
1183        bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst, inst_data);
1184        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1185        break;
1186      }
1187      case Instruction::SGET_OBJECT: {
1188        PREAMBLE();
1189        bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst, inst_data);
1190        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1191        break;
1192      }
1193      case Instruction::IPUT_BOOLEAN: {
1194        PREAMBLE();
1195        bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
1196        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1197        break;
1198      }
1199      case Instruction::IPUT_BYTE: {
1200        PREAMBLE();
1201        bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
1202        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1203        break;
1204      }
1205      case Instruction::IPUT_CHAR: {
1206        PREAMBLE();
1207        bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
1208        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1209        break;
1210      }
1211      case Instruction::IPUT_SHORT: {
1212        PREAMBLE();
1213        bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
1214        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1215        break;
1216      }
1217      case Instruction::IPUT: {
1218        PREAMBLE();
1219        bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
1220        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1221        break;
1222      }
1223      case Instruction::IPUT_WIDE: {
1224        PREAMBLE();
1225        bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
1226        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1227        break;
1228      }
1229      case Instruction::IPUT_OBJECT: {
1230        PREAMBLE();
1231        bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
1232        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1233        break;
1234      }
1235      case Instruction::IPUT_QUICK: {
1236        PREAMBLE();
1237        bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(shadow_frame, inst, inst_data);
1238        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1239        break;
1240      }
1241      case Instruction::IPUT_BOOLEAN_QUICK: {
1242        PREAMBLE();
1243        bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(shadow_frame, inst, inst_data);
1244        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1245        break;
1246      }
1247      case Instruction::IPUT_BYTE_QUICK: {
1248        PREAMBLE();
1249        bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(shadow_frame, inst, inst_data);
1250        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1251        break;
1252      }
1253      case Instruction::IPUT_CHAR_QUICK: {
1254        PREAMBLE();
1255        bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(shadow_frame, inst, inst_data);
1256        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1257        break;
1258      }
1259      case Instruction::IPUT_SHORT_QUICK: {
1260        PREAMBLE();
1261        bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(shadow_frame, inst, inst_data);
1262        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1263        break;
1264      }
1265      case Instruction::IPUT_WIDE_QUICK: {
1266        PREAMBLE();
1267        bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(shadow_frame, inst, inst_data);
1268        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1269        break;
1270      }
1271      case Instruction::IPUT_OBJECT_QUICK: {
1272        PREAMBLE();
1273        bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(shadow_frame, inst, inst_data);
1274        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1275        break;
1276      }
1277      case Instruction::SPUT_BOOLEAN: {
1278        PREAMBLE();
1279        bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
1280        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1281        break;
1282      }
1283      case Instruction::SPUT_BYTE: {
1284        PREAMBLE();
1285        bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
1286        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1287        break;
1288      }
1289      case Instruction::SPUT_CHAR: {
1290        PREAMBLE();
1291        bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
1292        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1293        break;
1294      }
1295      case Instruction::SPUT_SHORT: {
1296        PREAMBLE();
1297        bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
1298        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1299        break;
1300      }
1301      case Instruction::SPUT: {
1302        PREAMBLE();
1303        bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
1304        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1305        break;
1306      }
1307      case Instruction::SPUT_WIDE: {
1308        PREAMBLE();
1309        bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
1310        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1311        break;
1312      }
1313      case Instruction::SPUT_OBJECT: {
1314        PREAMBLE();
1315        bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
1316        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1317        break;
1318      }
1319      case Instruction::INVOKE_VIRTUAL: {
1320        PREAMBLE();
1321        bool success = DoInvoke<kVirtual, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
1322        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1323        break;
1324      }
1325      case Instruction::INVOKE_VIRTUAL_RANGE: {
1326        PREAMBLE();
1327        bool success = DoInvoke<kVirtual, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
1328        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1329        break;
1330      }
1331      case Instruction::INVOKE_SUPER: {
1332        PREAMBLE();
1333        bool success = DoInvoke<kSuper, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
1334        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1335        break;
1336      }
1337      case Instruction::INVOKE_SUPER_RANGE: {
1338        PREAMBLE();
1339        bool success = DoInvoke<kSuper, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
1340        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1341        break;
1342      }
1343      case Instruction::INVOKE_DIRECT: {
1344        PREAMBLE();
1345        bool success = DoInvoke<kDirect, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
1346        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1347        break;
1348      }
1349      case Instruction::INVOKE_DIRECT_RANGE: {
1350        PREAMBLE();
1351        bool success = DoInvoke<kDirect, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
1352        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1353        break;
1354      }
1355      case Instruction::INVOKE_INTERFACE: {
1356        PREAMBLE();
1357        bool success = DoInvoke<kInterface, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
1358        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1359        break;
1360      }
1361      case Instruction::INVOKE_INTERFACE_RANGE: {
1362        PREAMBLE();
1363        bool success = DoInvoke<kInterface, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
1364        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1365        break;
1366      }
1367      case Instruction::INVOKE_STATIC: {
1368        PREAMBLE();
1369        bool success = DoInvoke<kStatic, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
1370        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1371        break;
1372      }
1373      case Instruction::INVOKE_STATIC_RANGE: {
1374        PREAMBLE();
1375        bool success = DoInvoke<kStatic, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
1376        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1377        break;
1378      }
1379      case Instruction::INVOKE_VIRTUAL_QUICK: {
1380        PREAMBLE();
1381        bool success = DoInvokeVirtualQuick<false>(self, shadow_frame, inst, inst_data, &result_register);
1382        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1383        break;
1384      }
1385      case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
1386        PREAMBLE();
1387        bool success = DoInvokeVirtualQuick<true>(self, shadow_frame, inst, inst_data, &result_register);
1388        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1389        break;
1390      }
1391      case Instruction::NEG_INT:
1392        PREAMBLE();
1393        shadow_frame.SetVReg(inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
1394        inst = inst->Next_1xx();
1395        break;
1396      case Instruction::NOT_INT:
1397        PREAMBLE();
1398        shadow_frame.SetVReg(inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
1399        inst = inst->Next_1xx();
1400        break;
1401      case Instruction::NEG_LONG:
1402        PREAMBLE();
1403        shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
1404        inst = inst->Next_1xx();
1405        break;
1406      case Instruction::NOT_LONG:
1407        PREAMBLE();
1408        shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
1409        inst = inst->Next_1xx();
1410        break;
1411      case Instruction::NEG_FLOAT:
1412        PREAMBLE();
1413        shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
1414        inst = inst->Next_1xx();
1415        break;
1416      case Instruction::NEG_DOUBLE:
1417        PREAMBLE();
1418        shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
1419        inst = inst->Next_1xx();
1420        break;
1421      case Instruction::INT_TO_LONG:
1422        PREAMBLE();
1423        shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
1424                                 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
1425        inst = inst->Next_1xx();
1426        break;
1427      case Instruction::INT_TO_FLOAT:
1428        PREAMBLE();
1429        shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1430                                  shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
1431        inst = inst->Next_1xx();
1432        break;
1433      case Instruction::INT_TO_DOUBLE:
1434        PREAMBLE();
1435        shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1436                                   shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
1437        inst = inst->Next_1xx();
1438        break;
1439      case Instruction::LONG_TO_INT:
1440        PREAMBLE();
1441        shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1442                             shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
1443        inst = inst->Next_1xx();
1444        break;
1445      case Instruction::LONG_TO_FLOAT:
1446        PREAMBLE();
1447        shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1448                                  shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
1449        inst = inst->Next_1xx();
1450        break;
1451      case Instruction::LONG_TO_DOUBLE:
1452        PREAMBLE();
1453        shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1454                                   shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
1455        inst = inst->Next_1xx();
1456        break;
1457      case Instruction::FLOAT_TO_INT: {
1458        PREAMBLE();
1459        float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
1460        int32_t result = art_float_to_integral<int32_t, float>(val);
1461        shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
1462        inst = inst->Next_1xx();
1463        break;
1464      }
1465      case Instruction::FLOAT_TO_LONG: {
1466        PREAMBLE();
1467        float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
1468        int64_t result = art_float_to_integral<int64_t, float>(val);
1469        shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
1470        inst = inst->Next_1xx();
1471        break;
1472      }
1473      case Instruction::FLOAT_TO_DOUBLE:
1474        PREAMBLE();
1475        shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1476                                   shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
1477        inst = inst->Next_1xx();
1478        break;
1479      case Instruction::DOUBLE_TO_INT: {
1480        PREAMBLE();
1481        double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
1482        int32_t result = art_float_to_integral<int32_t, double>(val);
1483        shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
1484        inst = inst->Next_1xx();
1485        break;
1486      }
1487      case Instruction::DOUBLE_TO_LONG: {
1488        PREAMBLE();
1489        double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
1490        int64_t result = art_float_to_integral<int64_t, double>(val);
1491        shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
1492        inst = inst->Next_1xx();
1493        break;
1494      }
1495      case Instruction::DOUBLE_TO_FLOAT:
1496        PREAMBLE();
1497        shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1498                                  shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
1499        inst = inst->Next_1xx();
1500        break;
1501      case Instruction::INT_TO_BYTE:
1502        PREAMBLE();
1503        shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1504                             static_cast<int8_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
1505        inst = inst->Next_1xx();
1506        break;
1507      case Instruction::INT_TO_CHAR:
1508        PREAMBLE();
1509        shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1510                             static_cast<uint16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
1511        inst = inst->Next_1xx();
1512        break;
1513      case Instruction::INT_TO_SHORT:
1514        PREAMBLE();
1515        shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1516                             static_cast<int16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
1517        inst = inst->Next_1xx();
1518        break;
1519      case Instruction::ADD_INT: {
1520        PREAMBLE();
1521        shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
1522                             SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1523                                     shadow_frame.GetVReg(inst->VRegC_23x())));
1524        inst = inst->Next_2xx();
1525        break;
1526      }
1527      case Instruction::SUB_INT:
1528        PREAMBLE();
1529        shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
1530                             SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1531                                     shadow_frame.GetVReg(inst->VRegC_23x())));
1532        inst = inst->Next_2xx();
1533        break;
1534      case Instruction::MUL_INT:
1535        PREAMBLE();
1536        shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
1537                             SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1538                                     shadow_frame.GetVReg(inst->VRegC_23x())));
1539        inst = inst->Next_2xx();
1540        break;
1541      case Instruction::DIV_INT: {
1542        PREAMBLE();
1543        bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
1544                                   shadow_frame.GetVReg(inst->VRegB_23x()),
1545                                   shadow_frame.GetVReg(inst->VRegC_23x()));
1546        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1547        break;
1548      }
1549      case Instruction::REM_INT: {
1550        PREAMBLE();
1551        bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1552                                      shadow_frame.GetVReg(inst->VRegB_23x()),
1553                                      shadow_frame.GetVReg(inst->VRegC_23x()));
1554        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1555        break;
1556      }
1557      case Instruction::SHL_INT:
1558        PREAMBLE();
1559        shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
1560                             shadow_frame.GetVReg(inst->VRegB_23x()) <<
1561                             (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1562        inst = inst->Next_2xx();
1563        break;
1564      case Instruction::SHR_INT:
1565        PREAMBLE();
1566        shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
1567                             shadow_frame.GetVReg(inst->VRegB_23x()) >>
1568                             (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1569        inst = inst->Next_2xx();
1570        break;
1571      case Instruction::USHR_INT:
1572        PREAMBLE();
1573        shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
1574                             static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1575                             (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1576        inst = inst->Next_2xx();
1577        break;
1578      case Instruction::AND_INT:
1579        PREAMBLE();
1580        shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
1581                             shadow_frame.GetVReg(inst->VRegB_23x()) &
1582                             shadow_frame.GetVReg(inst->VRegC_23x()));
1583        inst = inst->Next_2xx();
1584        break;
1585      case Instruction::OR_INT:
1586        PREAMBLE();
1587        shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
1588                             shadow_frame.GetVReg(inst->VRegB_23x()) |
1589                             shadow_frame.GetVReg(inst->VRegC_23x()));
1590        inst = inst->Next_2xx();
1591        break;
1592      case Instruction::XOR_INT:
1593        PREAMBLE();
1594        shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
1595                             shadow_frame.GetVReg(inst->VRegB_23x()) ^
1596                             shadow_frame.GetVReg(inst->VRegC_23x()));
1597        inst = inst->Next_2xx();
1598        break;
1599      case Instruction::ADD_LONG:
1600        PREAMBLE();
1601        shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
1602                                 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1603                                         shadow_frame.GetVRegLong(inst->VRegC_23x())));
1604        inst = inst->Next_2xx();
1605        break;
1606      case Instruction::SUB_LONG:
1607        PREAMBLE();
1608        shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
1609                                 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1610                                         shadow_frame.GetVRegLong(inst->VRegC_23x())));
1611        inst = inst->Next_2xx();
1612        break;
1613      case Instruction::MUL_LONG:
1614        PREAMBLE();
1615        shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
1616                                 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1617                                         shadow_frame.GetVRegLong(inst->VRegC_23x())));
1618        inst = inst->Next_2xx();
1619        break;
1620      case Instruction::DIV_LONG:
1621        PREAMBLE();
1622        DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
1623                     shadow_frame.GetVRegLong(inst->VRegB_23x()),
1624                     shadow_frame.GetVRegLong(inst->VRegC_23x()));
1625        POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1626        break;
1627      case Instruction::REM_LONG:
1628        PREAMBLE();
1629        DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1630                        shadow_frame.GetVRegLong(inst->VRegB_23x()),
1631                        shadow_frame.GetVRegLong(inst->VRegC_23x()));
1632        POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1633        break;
1634      case Instruction::AND_LONG:
1635        PREAMBLE();
1636        shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
1637                                 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1638                                 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1639        inst = inst->Next_2xx();
1640        break;
1641      case Instruction::OR_LONG:
1642        PREAMBLE();
1643        shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
1644                                 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1645                                 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1646        inst = inst->Next_2xx();
1647        break;
1648      case Instruction::XOR_LONG:
1649        PREAMBLE();
1650        shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
1651                                 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1652                                 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1653        inst = inst->Next_2xx();
1654        break;
1655      case Instruction::SHL_LONG:
1656        PREAMBLE();
1657        shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
1658                                 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1659                                 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1660        inst = inst->Next_2xx();
1661        break;
1662      case Instruction::SHR_LONG:
1663        PREAMBLE();
1664        shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
1665                                 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1666                                 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1667        inst = inst->Next_2xx();
1668        break;
1669      case Instruction::USHR_LONG:
1670        PREAMBLE();
1671        shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
1672                                 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1673                                 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1674        inst = inst->Next_2xx();
1675        break;
1676      case Instruction::ADD_FLOAT:
1677        PREAMBLE();
1678        shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
1679                                  shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1680                                  shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1681        inst = inst->Next_2xx();
1682        break;
1683      case Instruction::SUB_FLOAT:
1684        PREAMBLE();
1685        shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
1686                                  shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1687                                  shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1688        inst = inst->Next_2xx();
1689        break;
1690      case Instruction::MUL_FLOAT:
1691        PREAMBLE();
1692        shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
1693                                  shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1694                                  shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1695        inst = inst->Next_2xx();
1696        break;
1697      case Instruction::DIV_FLOAT:
1698        PREAMBLE();
1699        shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
1700                                  shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1701                                  shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1702        inst = inst->Next_2xx();
1703        break;
1704      case Instruction::REM_FLOAT:
1705        PREAMBLE();
1706        shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
1707                                  fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1708                                        shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1709        inst = inst->Next_2xx();
1710        break;
1711      case Instruction::ADD_DOUBLE:
1712        PREAMBLE();
1713        shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
1714                                   shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1715                                   shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1716        inst = inst->Next_2xx();
1717        break;
1718      case Instruction::SUB_DOUBLE:
1719        PREAMBLE();
1720        shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
1721                                   shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1722                                   shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1723        inst = inst->Next_2xx();
1724        break;
1725      case Instruction::MUL_DOUBLE:
1726        PREAMBLE();
1727        shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
1728                                   shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
1729                                   shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1730        inst = inst->Next_2xx();
1731        break;
1732      case Instruction::DIV_DOUBLE:
1733        PREAMBLE();
1734        shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
1735                                   shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
1736                                   shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1737        inst = inst->Next_2xx();
1738        break;
1739      case Instruction::REM_DOUBLE:
1740        PREAMBLE();
1741        shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
1742                                   fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
1743                                        shadow_frame.GetVRegDouble(inst->VRegC_23x())));
1744        inst = inst->Next_2xx();
1745        break;
1746      case Instruction::ADD_INT_2ADDR: {
1747        PREAMBLE();
1748        uint4_t vregA = inst->VRegA_12x(inst_data);
1749        shadow_frame.SetVReg(vregA, SafeAdd(shadow_frame.GetVReg(vregA),
1750                                            shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
1751        inst = inst->Next_1xx();
1752        break;
1753      }
1754      case Instruction::SUB_INT_2ADDR: {
1755        PREAMBLE();
1756        uint4_t vregA = inst->VRegA_12x(inst_data);
1757        shadow_frame.SetVReg(vregA,
1758                             SafeSub(shadow_frame.GetVReg(vregA),
1759                                     shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
1760        inst = inst->Next_1xx();
1761        break;
1762      }
1763      case Instruction::MUL_INT_2ADDR: {
1764        PREAMBLE();
1765        uint4_t vregA = inst->VRegA_12x(inst_data);
1766        shadow_frame.SetVReg(vregA,
1767                             SafeMul(shadow_frame.GetVReg(vregA),
1768                                     shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
1769        inst = inst->Next_1xx();
1770        break;
1771      }
1772      case Instruction::DIV_INT_2ADDR: {
1773        PREAMBLE();
1774        uint4_t vregA = inst->VRegA_12x(inst_data);
1775        bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
1776                                   shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
1777        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1778        break;
1779      }
1780      case Instruction::REM_INT_2ADDR: {
1781        PREAMBLE();
1782        uint4_t vregA = inst->VRegA_12x(inst_data);
1783        bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
1784                                      shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
1785        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1786        break;
1787      }
1788      case Instruction::SHL_INT_2ADDR: {
1789        PREAMBLE();
1790        uint4_t vregA = inst->VRegA_12x(inst_data);
1791        shadow_frame.SetVReg(vregA,
1792                             shadow_frame.GetVReg(vregA) <<
1793                             (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
1794        inst = inst->Next_1xx();
1795        break;
1796      }
1797      case Instruction::SHR_INT_2ADDR: {
1798        PREAMBLE();
1799        uint4_t vregA = inst->VRegA_12x(inst_data);
1800        shadow_frame.SetVReg(vregA,
1801                             shadow_frame.GetVReg(vregA) >>
1802                             (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
1803        inst = inst->Next_1xx();
1804        break;
1805      }
1806      case Instruction::USHR_INT_2ADDR: {
1807        PREAMBLE();
1808        uint4_t vregA = inst->VRegA_12x(inst_data);
1809        shadow_frame.SetVReg(vregA,
1810                             static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
1811                             (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
1812        inst = inst->Next_1xx();
1813        break;
1814      }
1815      case Instruction::AND_INT_2ADDR: {
1816        PREAMBLE();
1817        uint4_t vregA = inst->VRegA_12x(inst_data);
1818        shadow_frame.SetVReg(vregA,
1819                             shadow_frame.GetVReg(vregA) &
1820                             shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
1821        inst = inst->Next_1xx();
1822        break;
1823      }
1824      case Instruction::OR_INT_2ADDR: {
1825        PREAMBLE();
1826        uint4_t vregA = inst->VRegA_12x(inst_data);
1827        shadow_frame.SetVReg(vregA,
1828                             shadow_frame.GetVReg(vregA) |
1829                             shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
1830        inst = inst->Next_1xx();
1831        break;
1832      }
1833      case Instruction::XOR_INT_2ADDR: {
1834        PREAMBLE();
1835        uint4_t vregA = inst->VRegA_12x(inst_data);
1836        shadow_frame.SetVReg(vregA,
1837                             shadow_frame.GetVReg(vregA) ^
1838                             shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
1839        inst = inst->Next_1xx();
1840        break;
1841      }
1842      case Instruction::ADD_LONG_2ADDR: {
1843        PREAMBLE();
1844        uint4_t vregA = inst->VRegA_12x(inst_data);
1845        shadow_frame.SetVRegLong(vregA,
1846                                 SafeAdd(shadow_frame.GetVRegLong(vregA),
1847                                         shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
1848        inst = inst->Next_1xx();
1849        break;
1850      }
1851      case Instruction::SUB_LONG_2ADDR: {
1852        PREAMBLE();
1853        uint4_t vregA = inst->VRegA_12x(inst_data);
1854        shadow_frame.SetVRegLong(vregA,
1855                                 SafeSub(shadow_frame.GetVRegLong(vregA),
1856                                         shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
1857        inst = inst->Next_1xx();
1858        break;
1859      }
1860      case Instruction::MUL_LONG_2ADDR: {
1861        PREAMBLE();
1862        uint4_t vregA = inst->VRegA_12x(inst_data);
1863        shadow_frame.SetVRegLong(vregA,
1864                                 SafeMul(shadow_frame.GetVRegLong(vregA),
1865                                         shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
1866        inst = inst->Next_1xx();
1867        break;
1868      }
1869      case Instruction::DIV_LONG_2ADDR: {
1870        PREAMBLE();
1871        uint4_t vregA = inst->VRegA_12x(inst_data);
1872        DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
1873                    shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
1874        POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
1875        break;
1876      }
1877      case Instruction::REM_LONG_2ADDR: {
1878        PREAMBLE();
1879        uint4_t vregA = inst->VRegA_12x(inst_data);
1880        DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
1881                        shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
1882        POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
1883        break;
1884      }
1885      case Instruction::AND_LONG_2ADDR: {
1886        PREAMBLE();
1887        uint4_t vregA = inst->VRegA_12x(inst_data);
1888        shadow_frame.SetVRegLong(vregA,
1889                                 shadow_frame.GetVRegLong(vregA) &
1890                                 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
1891        inst = inst->Next_1xx();
1892        break;
1893      }
1894      case Instruction::OR_LONG_2ADDR: {
1895        PREAMBLE();
1896        uint4_t vregA = inst->VRegA_12x(inst_data);
1897        shadow_frame.SetVRegLong(vregA,
1898                                 shadow_frame.GetVRegLong(vregA) |
1899                                 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
1900        inst = inst->Next_1xx();
1901        break;
1902      }
1903      case Instruction::XOR_LONG_2ADDR: {
1904        PREAMBLE();
1905        uint4_t vregA = inst->VRegA_12x(inst_data);
1906        shadow_frame.SetVRegLong(vregA,
1907                                 shadow_frame.GetVRegLong(vregA) ^
1908                                 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
1909        inst = inst->Next_1xx();
1910        break;
1911      }
1912      case Instruction::SHL_LONG_2ADDR: {
1913        PREAMBLE();
1914        uint4_t vregA = inst->VRegA_12x(inst_data);
1915        shadow_frame.SetVRegLong(vregA,
1916                                 shadow_frame.GetVRegLong(vregA) <<
1917                                 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
1918        inst = inst->Next_1xx();
1919        break;
1920      }
1921      case Instruction::SHR_LONG_2ADDR: {
1922        PREAMBLE();
1923        uint4_t vregA = inst->VRegA_12x(inst_data);
1924        shadow_frame.SetVRegLong(vregA,
1925                                 shadow_frame.GetVRegLong(vregA) >>
1926                                 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
1927        inst = inst->Next_1xx();
1928        break;
1929      }
1930      case Instruction::USHR_LONG_2ADDR: {
1931        PREAMBLE();
1932        uint4_t vregA = inst->VRegA_12x(inst_data);
1933        shadow_frame.SetVRegLong(vregA,
1934                                 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
1935                                 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
1936        inst = inst->Next_1xx();
1937        break;
1938      }
1939      case Instruction::ADD_FLOAT_2ADDR: {
1940        PREAMBLE();
1941        uint4_t vregA = inst->VRegA_12x(inst_data);
1942        shadow_frame.SetVRegFloat(vregA,
1943                                  shadow_frame.GetVRegFloat(vregA) +
1944                                  shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
1945        inst = inst->Next_1xx();
1946        break;
1947      }
1948      case Instruction::SUB_FLOAT_2ADDR: {
1949        PREAMBLE();
1950        uint4_t vregA = inst->VRegA_12x(inst_data);
1951        shadow_frame.SetVRegFloat(vregA,
1952                                  shadow_frame.GetVRegFloat(vregA) -
1953                                  shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
1954        inst = inst->Next_1xx();
1955        break;
1956      }
1957      case Instruction::MUL_FLOAT_2ADDR: {
1958        PREAMBLE();
1959        uint4_t vregA = inst->VRegA_12x(inst_data);
1960        shadow_frame.SetVRegFloat(vregA,
1961                                  shadow_frame.GetVRegFloat(vregA) *
1962                                  shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
1963        inst = inst->Next_1xx();
1964        break;
1965      }
1966      case Instruction::DIV_FLOAT_2ADDR: {
1967        PREAMBLE();
1968        uint4_t vregA = inst->VRegA_12x(inst_data);
1969        shadow_frame.SetVRegFloat(vregA,
1970                                  shadow_frame.GetVRegFloat(vregA) /
1971                                  shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
1972        inst = inst->Next_1xx();
1973        break;
1974      }
1975      case Instruction::REM_FLOAT_2ADDR: {
1976        PREAMBLE();
1977        uint4_t vregA = inst->VRegA_12x(inst_data);
1978        shadow_frame.SetVRegFloat(vregA,
1979                                  fmodf(shadow_frame.GetVRegFloat(vregA),
1980                                        shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
1981        inst = inst->Next_1xx();
1982        break;
1983      }
1984      case Instruction::ADD_DOUBLE_2ADDR: {
1985        PREAMBLE();
1986        uint4_t vregA = inst->VRegA_12x(inst_data);
1987        shadow_frame.SetVRegDouble(vregA,
1988                                   shadow_frame.GetVRegDouble(vregA) +
1989                                   shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
1990        inst = inst->Next_1xx();
1991        break;
1992      }
1993      case Instruction::SUB_DOUBLE_2ADDR: {
1994        PREAMBLE();
1995        uint4_t vregA = inst->VRegA_12x(inst_data);
1996        shadow_frame.SetVRegDouble(vregA,
1997                                   shadow_frame.GetVRegDouble(vregA) -
1998                                   shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
1999        inst = inst->Next_1xx();
2000        break;
2001      }
2002      case Instruction::MUL_DOUBLE_2ADDR: {
2003        PREAMBLE();
2004        uint4_t vregA = inst->VRegA_12x(inst_data);
2005        shadow_frame.SetVRegDouble(vregA,
2006                                   shadow_frame.GetVRegDouble(vregA) *
2007                                   shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
2008        inst = inst->Next_1xx();
2009        break;
2010      }
2011      case Instruction::DIV_DOUBLE_2ADDR: {
2012        PREAMBLE();
2013        uint4_t vregA = inst->VRegA_12x(inst_data);
2014        shadow_frame.SetVRegDouble(vregA,
2015                                   shadow_frame.GetVRegDouble(vregA) /
2016                                   shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
2017        inst = inst->Next_1xx();
2018        break;
2019      }
2020      case Instruction::REM_DOUBLE_2ADDR: {
2021        PREAMBLE();
2022        uint4_t vregA = inst->VRegA_12x(inst_data);
2023        shadow_frame.SetVRegDouble(vregA,
2024                                   fmod(shadow_frame.GetVRegDouble(vregA),
2025                                        shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
2026        inst = inst->Next_1xx();
2027        break;
2028      }
2029      case Instruction::ADD_INT_LIT16:
2030        PREAMBLE();
2031        shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2032                             SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2033                                     inst->VRegC_22s()));
2034        inst = inst->Next_2xx();
2035        break;
2036      case Instruction::RSUB_INT_LIT16:
2037        PREAMBLE();
2038        shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2039                             SafeSub(inst->VRegC_22s(),
2040                                     shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
2041        inst = inst->Next_2xx();
2042        break;
2043      case Instruction::MUL_INT_LIT16:
2044        PREAMBLE();
2045        shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2046                             SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2047                                     inst->VRegC_22s()));
2048        inst = inst->Next_2xx();
2049        break;
2050      case Instruction::DIV_INT_LIT16: {
2051        PREAMBLE();
2052        bool success = DoIntDivide(shadow_frame, inst->VRegA_22s(inst_data),
2053                                   shadow_frame.GetVReg(inst->VRegB_22s(inst_data)), inst->VRegC_22s());
2054        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2055        break;
2056      }
2057      case Instruction::REM_INT_LIT16: {
2058        PREAMBLE();
2059        bool success = DoIntRemainder(shadow_frame, inst->VRegA_22s(inst_data),
2060                                      shadow_frame.GetVReg(inst->VRegB_22s(inst_data)), inst->VRegC_22s());
2061        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2062        break;
2063      }
2064      case Instruction::AND_INT_LIT16:
2065        PREAMBLE();
2066        shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2067                             shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
2068                             inst->VRegC_22s());
2069        inst = inst->Next_2xx();
2070        break;
2071      case Instruction::OR_INT_LIT16:
2072        PREAMBLE();
2073        shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2074                             shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
2075                             inst->VRegC_22s());
2076        inst = inst->Next_2xx();
2077        break;
2078      case Instruction::XOR_INT_LIT16:
2079        PREAMBLE();
2080        shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2081                             shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
2082                             inst->VRegC_22s());
2083        inst = inst->Next_2xx();
2084        break;
2085      case Instruction::ADD_INT_LIT8:
2086        PREAMBLE();
2087        shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
2088                             SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
2089        inst = inst->Next_2xx();
2090        break;
2091      case Instruction::RSUB_INT_LIT8:
2092        PREAMBLE();
2093        shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
2094                             SafeSub(inst->VRegC_22b(), shadow_frame.GetVReg(inst->VRegB_22b())));
2095        inst = inst->Next_2xx();
2096        break;
2097      case Instruction::MUL_INT_LIT8:
2098        PREAMBLE();
2099        shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
2100                             SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
2101        inst = inst->Next_2xx();
2102        break;
2103      case Instruction::DIV_INT_LIT8: {
2104        PREAMBLE();
2105        bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
2106                                   shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2107        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2108        break;
2109      }
2110      case Instruction::REM_INT_LIT8: {
2111        PREAMBLE();
2112        bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
2113                                      shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2114        POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2115        break;
2116      }
2117      case Instruction::AND_INT_LIT8:
2118        PREAMBLE();
2119        shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
2120                             shadow_frame.GetVReg(inst->VRegB_22b()) &
2121                             inst->VRegC_22b());
2122        inst = inst->Next_2xx();
2123        break;
2124      case Instruction::OR_INT_LIT8:
2125        PREAMBLE();
2126        shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
2127                             shadow_frame.GetVReg(inst->VRegB_22b()) |
2128                             inst->VRegC_22b());
2129        inst = inst->Next_2xx();
2130        break;
2131      case Instruction::XOR_INT_LIT8:
2132        PREAMBLE();
2133        shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
2134                             shadow_frame.GetVReg(inst->VRegB_22b()) ^
2135                             inst->VRegC_22b());
2136        inst = inst->Next_2xx();
2137        break;
2138      case Instruction::SHL_INT_LIT8:
2139        PREAMBLE();
2140        shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
2141                             shadow_frame.GetVReg(inst->VRegB_22b()) <<
2142                             (inst->VRegC_22b() & 0x1f));
2143        inst = inst->Next_2xx();
2144        break;
2145      case Instruction::SHR_INT_LIT8:
2146        PREAMBLE();
2147        shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
2148                             shadow_frame.GetVReg(inst->VRegB_22b()) >>
2149                             (inst->VRegC_22b() & 0x1f));
2150        inst = inst->Next_2xx();
2151        break;
2152      case Instruction::USHR_INT_LIT8:
2153        PREAMBLE();
2154        shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
2155                             static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2156                             (inst->VRegC_22b() & 0x1f));
2157        inst = inst->Next_2xx();
2158        break;
2159      case Instruction::UNUSED_3E ... Instruction::UNUSED_43:
2160      case Instruction::UNUSED_F3 ... Instruction::UNUSED_FF:
2161      case Instruction::UNUSED_79:
2162      case Instruction::UNUSED_7A:
2163        UnexpectedOpcode(inst, shadow_frame);
2164    }
2165  }
2166}  // NOLINT(readability/fn_size)
2167
2168// Explicit definitions of ExecuteSwitchImpl.
2169template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
2170JValue ExecuteSwitchImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
2171                                      ShadowFrame& shadow_frame, JValue result_register);
2172template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
2173JValue ExecuteSwitchImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
2174                                       ShadowFrame& shadow_frame, JValue result_register);
2175template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
2176JValue ExecuteSwitchImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
2177                                     ShadowFrame& shadow_frame, JValue result_register);
2178template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
2179JValue ExecuteSwitchImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
2180                                      ShadowFrame& shadow_frame, JValue result_register);
2181
2182}  // namespace interpreter
2183}  // namespace art
2184