blob: 2514f0c3833408a427b7d84ba2f1141f29212909 [file] [log] [blame]
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Andreas Gampe5e26eb12016-08-22 17:54:17 -070017#include "interpreter_switch_impl.h"
18
Andreas Gampe542451c2016-07-26 09:02:02 -070019#include "base/enums.h"
Andreas Gampee2abbc62017-09-15 11:59:26 -070020#include "dex_file_types.h"
Alex Lighteb7c1442015-08-31 13:17:42 -070021#include "experimental_flags.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020022#include "interpreter_common.h"
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000023#include "jit/jit.h"
Mathieu Chartier28bd2e42016-10-04 13:54:57 -070024#include "jvalue-inl.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070025#include "safe_math.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020026
27namespace art {
28namespace interpreter {
29
Alex Lightb7edcda2017-04-27 13:20:31 -070030#define HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(instr) \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020031 do { \
Sebastien Hertz82aeddb2014-05-20 20:09:45 +020032 DCHECK(self->IsExceptionPending()); \
Ian Rogers7b078e82014-09-10 14:44:24 -070033 self->AllowThreadSuspension(); \
Alex Light9fb1ab12017-09-05 09:32:49 -070034 if (!MoveToExceptionHandler(self, shadow_frame, instr)) { \
Andreas Gampe03ec9302015-08-27 17:41:47 -070035 /* Structured locking is to be enforced for abnormal termination, too. */ \
Andreas Gampe56fdd0e2016-04-28 14:56:54 -070036 DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame); \
buzbee1452bee2015-03-06 14:43:04 -080037 if (interpret_one_instruction) { \
buzbee93e94f22016-04-07 13:52:48 -070038 /* Signal mterp to return to caller */ \
Andreas Gampee2abbc62017-09-15 11:59:26 -070039 shadow_frame.SetDexPC(dex::kDexNoIndex); \
buzbee1452bee2015-03-06 14:43:04 -080040 } \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020041 return JValue(); /* Handled in caller. */ \
42 } else { \
Alex Light9fb1ab12017-09-05 09:32:49 -070043 int32_t displacement = \
44 static_cast<int32_t>(shadow_frame.GetDexPC()) - static_cast<int32_t>(dex_pc); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020045 inst = inst->RelativeAt(displacement); \
46 } \
47 } while (false)
48
Alex Lightb7edcda2017-04-27 13:20:31 -070049#define HANDLE_PENDING_EXCEPTION() HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(instrumentation)
50
Sebastien Hertz8ece0502013-08-07 11:26:41 +020051#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _next_function) \
52 do { \
53 if (UNLIKELY(_is_exception_pending)) { \
54 HANDLE_PENDING_EXCEPTION(); \
55 } else { \
56 inst = inst->_next_function(); \
57 } \
58 } while (false)
59
Andreas Gampe03ec9302015-08-27 17:41:47 -070060#define HANDLE_MONITOR_CHECKS() \
Andreas Gampe56fdd0e2016-04-28 14:56:54 -070061 if (!DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame)) { \
Andreas Gampe03ec9302015-08-27 17:41:47 -070062 HANDLE_PENDING_EXCEPTION(); \
63 }
64
Sebastien Hertz8ece0502013-08-07 11:26:41 +020065// Code to run before each dex instruction.
Alex Lightfc905672017-06-27 17:53:15 -070066#define PREAMBLE_SAVE(save_ref) \
67 { \
68 if (UNLIKELY(instrumentation->HasDexPcListeners()) && \
69 UNLIKELY(!DoDexPcMoveEvent(self, \
70 code_item, \
71 shadow_frame, \
72 dex_pc, \
73 instrumentation, \
74 save_ref))) { \
75 HANDLE_PENDING_EXCEPTION(); \
76 break; \
Sebastien Hertz8379b222014-02-24 17:38:15 +010077 } \
Alex Lightfc905672017-06-27 17:53:15 -070078 } \
79 do {} while (false)
80
81#define PREAMBLE() PREAMBLE_SAVE(nullptr)
Sebastien Hertz8ece0502013-08-07 11:26:41 +020082
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000083#define BRANCH_INSTRUMENTATION(offset) \
84 do { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010085 if (UNLIKELY(instrumentation->HasBranchListeners())) { \
86 instrumentation->Branch(self, method, dex_pc, offset); \
87 } \
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000088 JValue result; \
89 if (jit::Jit::MaybeDoOnStackReplacement(self, method, dex_pc, offset, &result)) { \
buzbee93e94f22016-04-07 13:52:48 -070090 if (interpret_one_instruction) { \
91 /* OSR has completed execution of the method. Signal mterp to return to caller */ \
Andreas Gampee2abbc62017-09-15 11:59:26 -070092 shadow_frame.SetDexPC(dex::kDexNoIndex); \
buzbee93e94f22016-04-07 13:52:48 -070093 } \
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000094 return result; \
95 } \
Nicolas Geoffray3108daf2015-11-24 16:32:33 +000096 } while (false)
97
Bill Buzbee1d011d92016-04-04 16:59:29 +000098#define HOTNESS_UPDATE() \
99 do { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100100 if (jit != nullptr) { \
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +0100101 jit->AddSamples(self, method, 1, /*with_backedges*/ true); \
Bill Buzbee1d011d92016-04-04 16:59:29 +0000102 } \
103 } while (false)
104
Andreas Gampef4f76372016-12-13 14:43:58 -0800105#define HANDLE_BACKWARD_BRANCH(offset) \
106 do { \
107 if (IsBackwardBranch(offset)) { \
108 HOTNESS_UPDATE(); \
109 /* Record new dex pc early to have consistent suspend point at loop header. */ \
110 shadow_frame.SetDexPC(inst->GetDexPc(insns)); \
111 self->AllowThreadSuspension(); \
112 } \
113 } while (false)
114
Alex Lightfc905672017-06-27 17:53:15 -0700115// Unlike most other events the DexPcMovedEvent can be sent when there is a pending exception (if
116// the next instruction is MOVE_EXCEPTION). This means it needs to be handled carefully to be able
117// to detect exceptions thrown by the DexPcMovedEvent itself. These exceptions could be thrown by
118// jvmti-agents while handling breakpoint or single step events. We had to move this into its own
119// function because it was making ExecuteSwitchImpl have too large a stack.
Alex Light2989a4a2017-06-29 09:44:57 -0700120NO_INLINE static bool DoDexPcMoveEvent(Thread* self,
121 const DexFile::CodeItem* code_item,
122 const ShadowFrame& shadow_frame,
123 uint32_t dex_pc,
124 const instrumentation::Instrumentation* instrumentation,
125 JValue* save_ref)
Alex Lightfc905672017-06-27 17:53:15 -0700126 REQUIRES_SHARED(Locks::mutator_lock_) {
127 DCHECK(instrumentation->HasDexPcListeners());
128 StackHandleScope<2> hs(self);
129 Handle<mirror::Throwable> thr(hs.NewHandle(self->GetException()));
130 mirror::Object* null_obj = nullptr;
131 HandleWrapper<mirror::Object> h(
132 hs.NewHandleWrapper(LIKELY(save_ref == nullptr) ? &null_obj : save_ref->GetGCRoot()));
133 self->ClearException();
134 instrumentation->DexPcMovedEvent(self,
135 shadow_frame.GetThisObject(code_item->ins_size_),
136 shadow_frame.GetMethod(),
137 dex_pc);
138 if (UNLIKELY(self->IsExceptionPending())) {
139 // We got a new exception in the dex-pc-moved event. We just let this exception replace the old
140 // one.
141 // TODO It would be good to add the old exception to the suppressed exceptions of the new one if
142 // possible.
143 return false;
144 } else {
145 if (UNLIKELY(!thr.IsNull())) {
146 self->SetException(thr.Get());
147 }
148 return true;
149 }
150}
151
Alex Lighte814f9d2017-07-31 16:14:39 -0700152static bool NeedsMethodExitEvent(const instrumentation::Instrumentation* ins)
153 REQUIRES_SHARED(Locks::mutator_lock_) {
154 return ins->HasMethodExitListeners() || ins->HasWatchedFramePopListeners();
155}
156
157// Sends the normal method exit event. Returns true if the events succeeded and false if there is a
158// pending exception.
159NO_INLINE static bool SendMethodExitEvents(Thread* self,
160 const instrumentation::Instrumentation* instrumentation,
161 const ShadowFrame& frame,
162 ObjPtr<mirror::Object> thiz,
163 ArtMethod* method,
164 uint32_t dex_pc,
165 const JValue& result)
166 REQUIRES_SHARED(Locks::mutator_lock_) {
167 bool had_event = false;
168 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
169 had_event = true;
170 instrumentation->MethodExitEvent(self, thiz.Ptr(), method, dex_pc, result);
171 }
172 if (UNLIKELY(frame.NeedsNotifyPop() && instrumentation->HasWatchedFramePopListeners())) {
173 had_event = true;
174 instrumentation->WatchedFramePopped(self, frame);
175 }
176 if (UNLIKELY(had_event)) {
177 return !self->IsExceptionPending();
178 } else {
179 return true;
180 }
181}
182
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100183template<bool do_access_check, bool transaction_active>
Ian Rogerse94652f2014-12-02 11:13:19 -0800184JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -0800185 ShadowFrame& shadow_frame, JValue result_register,
186 bool interpret_one_instruction) {
Igor Murashkinc449e8b2015-06-10 15:56:42 -0700187 constexpr bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200188 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
189 LOG(FATAL) << "Invalid shadow frame for interpreter use";
190 return JValue();
191 }
192 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200193
194 uint32_t dex_pc = shadow_frame.GetDexPC();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700195 const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200196 const uint16_t* const insns = code_item->insns_;
197 const Instruction* inst = Instruction::At(insns + dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200198 uint16_t inst_data;
Bill Buzbee1d011d92016-04-04 16:59:29 +0000199 ArtMethod* method = shadow_frame.GetMethod();
200 jit::Jit* jit = Runtime::Current()->GetJit();
Igor Murashkin6918bf12015-09-27 19:19:06 -0700201
buzbee1452bee2015-03-06 14:43:04 -0800202 do {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200203 dex_pc = inst->GetDexPc(insns);
204 shadow_frame.SetDexPC(dex_pc);
Ian Rogerse94652f2014-12-02 11:13:19 -0800205 TraceExecution(shadow_frame, inst, dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200206 inst_data = inst->Fetch16(0);
207 switch (inst->Opcode(inst_data)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200208 case Instruction::NOP:
209 PREAMBLE();
210 inst = inst->Next_1xx();
211 break;
212 case Instruction::MOVE:
213 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200214 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
215 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200216 inst = inst->Next_1xx();
217 break;
218 case Instruction::MOVE_FROM16:
219 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200220 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200221 shadow_frame.GetVReg(inst->VRegB_22x()));
222 inst = inst->Next_2xx();
223 break;
224 case Instruction::MOVE_16:
225 PREAMBLE();
226 shadow_frame.SetVReg(inst->VRegA_32x(),
227 shadow_frame.GetVReg(inst->VRegB_32x()));
228 inst = inst->Next_3xx();
229 break;
230 case Instruction::MOVE_WIDE:
231 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200232 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
233 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200234 inst = inst->Next_1xx();
235 break;
236 case Instruction::MOVE_WIDE_FROM16:
237 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200238 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200239 shadow_frame.GetVRegLong(inst->VRegB_22x()));
240 inst = inst->Next_2xx();
241 break;
242 case Instruction::MOVE_WIDE_16:
243 PREAMBLE();
244 shadow_frame.SetVRegLong(inst->VRegA_32x(),
245 shadow_frame.GetVRegLong(inst->VRegB_32x()));
246 inst = inst->Next_3xx();
247 break;
248 case Instruction::MOVE_OBJECT:
249 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200250 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
251 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200252 inst = inst->Next_1xx();
253 break;
254 case Instruction::MOVE_OBJECT_FROM16:
255 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200256 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200257 shadow_frame.GetVRegReference(inst->VRegB_22x()));
258 inst = inst->Next_2xx();
259 break;
260 case Instruction::MOVE_OBJECT_16:
261 PREAMBLE();
262 shadow_frame.SetVRegReference(inst->VRegA_32x(),
263 shadow_frame.GetVRegReference(inst->VRegB_32x()));
264 inst = inst->Next_3xx();
265 break;
266 case Instruction::MOVE_RESULT:
267 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200268 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200269 inst = inst->Next_1xx();
270 break;
271 case Instruction::MOVE_RESULT_WIDE:
272 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200273 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200274 inst = inst->Next_1xx();
275 break;
276 case Instruction::MOVE_RESULT_OBJECT:
Alex Lightfc905672017-06-27 17:53:15 -0700277 PREAMBLE_SAVE(&result_register);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200278 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200279 inst = inst->Next_1xx();
280 break;
281 case Instruction::MOVE_EXCEPTION: {
282 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700283 ObjPtr<mirror::Throwable> exception = self->GetException();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100284 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
Mathieu Chartieref41db72016-10-25 15:08:01 -0700285 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception.Ptr());
Sebastien Hertz5c004902014-05-21 10:07:42 +0200286 self->ClearException();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200287 inst = inst->Next_1xx();
288 break;
289 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700290 case Instruction::RETURN_VOID_NO_BARRIER: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200291 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200292 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700293 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700294 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700295 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
296 !SendMethodExitEvents(self,
297 instrumentation,
298 shadow_frame,
299 shadow_frame.GetThisObject(code_item->ins_size_),
300 shadow_frame.GetMethod(),
301 inst->GetDexPc(insns),
302 result))) {
303 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200304 }
buzbee1452bee2015-03-06 14:43:04 -0800305 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700306 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700307 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800308 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200309 return result;
310 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700311 case Instruction::RETURN_VOID: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200312 PREAMBLE();
Hans Boehm30359612014-05-21 17:46:23 -0700313 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200314 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700315 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700316 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700317 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
318 !SendMethodExitEvents(self,
319 instrumentation,
320 shadow_frame,
321 shadow_frame.GetThisObject(code_item->ins_size_),
322 shadow_frame.GetMethod(),
323 inst->GetDexPc(insns),
324 result))) {
325 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200326 }
buzbee1452bee2015-03-06 14:43:04 -0800327 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700328 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700329 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800330 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200331 return result;
332 }
333 case Instruction::RETURN: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200334 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200335 JValue result;
336 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200337 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700338 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700339 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700340 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
341 !SendMethodExitEvents(self,
342 instrumentation,
343 shadow_frame,
344 shadow_frame.GetThisObject(code_item->ins_size_),
345 shadow_frame.GetMethod(),
346 inst->GetDexPc(insns),
347 result))) {
348 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200349 }
buzbee1452bee2015-03-06 14:43:04 -0800350 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700351 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700352 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800353 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200354 return result;
355 }
356 case Instruction::RETURN_WIDE: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200357 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200358 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200359 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700360 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700361 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700362 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
363 !SendMethodExitEvents(self,
364 instrumentation,
365 shadow_frame,
366 shadow_frame.GetThisObject(code_item->ins_size_),
367 shadow_frame.GetMethod(),
368 inst->GetDexPc(insns),
369 result))) {
370 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200371 }
buzbee1452bee2015-03-06 14:43:04 -0800372 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700373 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700374 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800375 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200376 return result;
377 }
378 case Instruction::RETURN_OBJECT: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200379 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200380 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700381 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700382 HANDLE_MONITOR_CHECKS();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700383 const size_t ref_idx = inst->VRegA_11x(inst_data);
Mathieu Chartieref41db72016-10-25 15:08:01 -0700384 ObjPtr<mirror::Object> obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700385 if (do_assignability_check && obj_result != nullptr) {
Vladimir Markob45528c2017-07-27 14:14:28 +0100386 ObjPtr<mirror::Class> return_type = method->ResolveReturnType();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700387 // Re-load since it might have moved.
388 obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700389 if (return_type == nullptr) {
Jeff Haoa3faaf42013-09-03 19:07:00 -0700390 // Return the pending exception.
391 HANDLE_PENDING_EXCEPTION();
392 }
393 if (!obj_result->VerifierInstanceOf(return_type)) {
394 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700395 std::string temp1, temp2;
Orion Hodsonfef06642016-11-25 16:07:11 +0000396 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700397 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700398 obj_result->GetClass()->GetDescriptor(&temp1),
399 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700400 HANDLE_PENDING_EXCEPTION();
401 }
402 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700403 result.SetL(obj_result);
Alex Lighte814f9d2017-07-31 16:14:39 -0700404 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
405 !SendMethodExitEvents(self,
406 instrumentation,
407 shadow_frame,
408 shadow_frame.GetThisObject(code_item->ins_size_),
409 shadow_frame.GetMethod(),
410 inst->GetDexPc(insns),
411 result))) {
412 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200413 }
Alex Lighte814f9d2017-07-31 16:14:39 -0700414 // Re-load since it might have moved during the MethodExitEvent.
415 result.SetL(shadow_frame.GetVRegReference(ref_idx));
buzbee1452bee2015-03-06 14:43:04 -0800416 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700417 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700418 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800419 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200420 return result;
421 }
422 case Instruction::CONST_4: {
423 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200424 uint4_t dst = inst->VRegA_11n(inst_data);
425 int4_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200426 shadow_frame.SetVReg(dst, val);
427 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700428 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200429 }
430 inst = inst->Next_1xx();
431 break;
432 }
433 case Instruction::CONST_16: {
434 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200435 uint8_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200436 int16_t val = inst->VRegB_21s();
437 shadow_frame.SetVReg(dst, val);
438 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700439 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200440 }
441 inst = inst->Next_2xx();
442 break;
443 }
444 case Instruction::CONST: {
445 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200446 uint8_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200447 int32_t val = inst->VRegB_31i();
448 shadow_frame.SetVReg(dst, val);
449 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700450 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200451 }
452 inst = inst->Next_3xx();
453 break;
454 }
455 case Instruction::CONST_HIGH16: {
456 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200457 uint8_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200458 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
459 shadow_frame.SetVReg(dst, val);
460 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700461 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200462 }
463 inst = inst->Next_2xx();
464 break;
465 }
466 case Instruction::CONST_WIDE_16:
467 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200468 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200469 inst = inst->Next_2xx();
470 break;
471 case Instruction::CONST_WIDE_32:
472 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200473 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200474 inst = inst->Next_3xx();
475 break;
476 case Instruction::CONST_WIDE:
477 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200478 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200479 inst = inst->Next_51l();
480 break;
481 case Instruction::CONST_WIDE_HIGH16:
Sebastien Hertz3c5aec12014-06-04 09:41:21 +0200482 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200483 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200484 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
485 inst = inst->Next_2xx();
486 break;
487 case Instruction::CONST_STRING: {
488 PREAMBLE();
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800489 ObjPtr<mirror::String> s = ResolveString(self,
490 shadow_frame,
491 dex::StringIndex(inst->VRegB_21c()));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700492 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200493 HANDLE_PENDING_EXCEPTION();
494 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700495 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s.Ptr());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200496 inst = inst->Next_2xx();
497 }
498 break;
499 }
500 case Instruction::CONST_STRING_JUMBO: {
501 PREAMBLE();
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800502 ObjPtr<mirror::String> s = ResolveString(self,
503 shadow_frame,
504 dex::StringIndex(inst->VRegB_31c()));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700505 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200506 HANDLE_PENDING_EXCEPTION();
507 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700508 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s.Ptr());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200509 inst = inst->Next_3xx();
510 }
511 break;
512 }
513 case Instruction::CONST_CLASS: {
514 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800515 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700516 shadow_frame.GetMethod(),
517 self,
518 false,
519 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700520 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200521 HANDLE_PENDING_EXCEPTION();
522 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700523 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c.Ptr());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200524 inst = inst->Next_2xx();
525 }
526 break;
527 }
Orion Hodson2e599942017-09-22 16:17:41 +0100528 case Instruction::CONST_METHOD_HANDLE: {
529 PREAMBLE();
530 ObjPtr<mirror::MethodHandle> mh =
531 Runtime::Current()->GetClassLinker()->ResolveMethodHandle(inst->VRegB_21c(), method);
532 if (UNLIKELY(mh == nullptr)) {
533 HANDLE_PENDING_EXCEPTION();
534 } else {
535 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), mh.Ptr());
536 inst = inst->Next_2xx();
537 }
538 break;
539 }
540 case Instruction::CONST_METHOD_TYPE: {
541 PREAMBLE();
542 ObjPtr<mirror::MethodType> mt =
543 Runtime::Current()->GetClassLinker()->ResolveMethodType(inst->VRegB_21c(), method);
544 if (UNLIKELY(mt == nullptr)) {
545 HANDLE_PENDING_EXCEPTION();
546 } else {
547 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), mt.Ptr());
548 inst = inst->Next_2xx();
549 }
550 break;
551 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200552 case Instruction::MONITOR_ENTER: {
553 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700554 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700555 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000556 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200557 HANDLE_PENDING_EXCEPTION();
558 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700559 DoMonitorEnter<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200560 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
561 }
562 break;
563 }
564 case Instruction::MONITOR_EXIT: {
565 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700566 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700567 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000568 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200569 HANDLE_PENDING_EXCEPTION();
570 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700571 DoMonitorExit<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200572 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
573 }
574 break;
575 }
576 case Instruction::CHECK_CAST: {
577 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800578 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700579 shadow_frame.GetMethod(),
580 self,
581 false,
582 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700583 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200584 HANDLE_PENDING_EXCEPTION();
585 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700586 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700587 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200588 ThrowClassCastException(c, obj->GetClass());
589 HANDLE_PENDING_EXCEPTION();
590 } else {
591 inst = inst->Next_2xx();
592 }
593 }
594 break;
595 }
596 case Instruction::INSTANCE_OF: {
597 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800598 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegC_22c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700599 shadow_frame.GetMethod(),
600 self,
601 false,
602 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700603 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200604 HANDLE_PENDING_EXCEPTION();
605 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700606 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700607 shadow_frame.SetVReg(inst->VRegA_22c(inst_data),
608 (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200609 inst = inst->Next_2xx();
610 }
611 break;
612 }
613 case Instruction::ARRAY_LENGTH: {
614 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700615 ObjPtr<mirror::Object> array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700616 if (UNLIKELY(array == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000617 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200618 HANDLE_PENDING_EXCEPTION();
619 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200620 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200621 inst = inst->Next_1xx();
622 }
623 break;
624 }
625 case Instruction::NEW_INSTANCE: {
626 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700627 ObjPtr<mirror::Object> obj = nullptr;
Andreas Gampea5b09a62016-11-17 15:21:22 -0800628 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700629 shadow_frame.GetMethod(),
630 self,
631 false,
632 do_access_check);
Jeff Hao848f70a2014-01-15 13:49:50 -0800633 if (LIKELY(c != nullptr)) {
634 if (UNLIKELY(c->IsStringClass())) {
635 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
jessicahandojo3aaa37b2016-07-29 14:46:37 -0700636 obj = mirror::String::AllocEmptyString<true>(self, allocator_type);
Jeff Hao848f70a2014-01-15 13:49:50 -0800637 } else {
Nicolas Geoffray0d3998b2017-01-12 15:35:12 +0000638 obj = AllocObjectFromCode<true>(
639 c.Ptr(),
Andreas Gampea5b09a62016-11-17 15:21:22 -0800640 self,
641 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Jeff Hao848f70a2014-01-15 13:49:50 -0800642 }
643 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700644 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200645 HANDLE_PENDING_EXCEPTION();
646 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200647 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700648 // Don't allow finalizable objects to be allocated during a transaction since these can't
649 // be finalized without a started runtime.
650 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200651 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
David Sehr709b0702016-10-13 09:12:37 -0700652 obj->PrettyTypeOf().c_str());
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700653 HANDLE_PENDING_EXCEPTION();
654 break;
655 }
Mathieu Chartieref41db72016-10-25 15:08:01 -0700656 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj.Ptr());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200657 inst = inst->Next_2xx();
658 }
659 break;
660 }
661 case Instruction::NEW_ARRAY: {
662 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200663 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartieref41db72016-10-25 15:08:01 -0700664 ObjPtr<mirror::Object> obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampea5b09a62016-11-17 15:21:22 -0800665 dex::TypeIndex(inst->VRegC_22c()),
666 length,
667 shadow_frame.GetMethod(),
668 self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800669 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700670 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200671 HANDLE_PENDING_EXCEPTION();
672 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700673 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj.Ptr());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200674 inst = inst->Next_2xx();
675 }
676 break;
677 }
678 case Instruction::FILLED_NEW_ARRAY: {
679 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100680 bool success =
681 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame, self,
682 &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200683 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
684 break;
685 }
686 case Instruction::FILLED_NEW_ARRAY_RANGE: {
687 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100688 bool success =
689 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
690 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200691 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
692 break;
693 }
694 case Instruction::FILL_ARRAY_DATA: {
695 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200696 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
697 const Instruction::ArrayDataPayload* payload =
698 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
Mathieu Chartieref41db72016-10-25 15:08:01 -0700699 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
Ian Rogers832336b2014-10-08 15:35:22 -0700700 bool success = FillArrayData(obj, payload);
701 if (!success) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200702 HANDLE_PENDING_EXCEPTION();
703 break;
704 }
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100705 if (transaction_active) {
Ian Rogers832336b2014-10-08 15:35:22 -0700706 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100707 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200708 inst = inst->Next_3xx();
709 break;
710 }
711 case Instruction::THROW: {
712 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700713 ObjPtr<mirror::Object> exception =
714 shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700715 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000716 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700717 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
718 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700719 std::string temp;
Orion Hodsonfef06642016-11-25 16:07:11 +0000720 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700721 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700722 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200723 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000724 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200725 }
726 HANDLE_PENDING_EXCEPTION();
727 break;
728 }
729 case Instruction::GOTO: {
730 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200731 int8_t offset = inst->VRegA_10t(inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000732 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200733 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800734 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200735 break;
736 }
737 case Instruction::GOTO_16: {
738 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200739 int16_t offset = inst->VRegA_20t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000740 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200741 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800742 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200743 break;
744 }
745 case Instruction::GOTO_32: {
746 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200747 int32_t offset = inst->VRegA_30t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000748 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200749 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800750 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200751 break;
752 }
753 case Instruction::PACKED_SWITCH: {
754 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200755 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000756 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200757 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800758 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200759 break;
760 }
761 case Instruction::SPARSE_SWITCH: {
762 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200763 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000764 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200765 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800766 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200767 break;
768 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700769
Ian Rogers647b1a82014-10-10 11:02:11 -0700770#pragma clang diagnostic push
771#pragma clang diagnostic ignored "-Wfloat-equal"
Ian Rogers647b1a82014-10-10 11:02:11 -0700772
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200773 case Instruction::CMPL_FLOAT: {
774 PREAMBLE();
775 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
776 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
777 int32_t result;
778 if (val1 > val2) {
779 result = 1;
780 } else if (val1 == val2) {
781 result = 0;
782 } else {
783 result = -1;
784 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200785 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200786 inst = inst->Next_2xx();
787 break;
788 }
789 case Instruction::CMPG_FLOAT: {
790 PREAMBLE();
791 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
792 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
793 int32_t result;
794 if (val1 < val2) {
795 result = -1;
796 } else if (val1 == val2) {
797 result = 0;
798 } else {
799 result = 1;
800 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200801 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200802 inst = inst->Next_2xx();
803 break;
804 }
805 case Instruction::CMPL_DOUBLE: {
806 PREAMBLE();
807 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
808 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
809 int32_t result;
810 if (val1 > val2) {
811 result = 1;
812 } else if (val1 == val2) {
813 result = 0;
814 } else {
815 result = -1;
816 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200817 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200818 inst = inst->Next_2xx();
819 break;
820 }
821
822 case Instruction::CMPG_DOUBLE: {
823 PREAMBLE();
824 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
825 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
826 int32_t result;
827 if (val1 < val2) {
828 result = -1;
829 } else if (val1 == val2) {
830 result = 0;
831 } else {
832 result = 1;
833 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200834 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200835 inst = inst->Next_2xx();
836 break;
837 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700838
Ian Rogers647b1a82014-10-10 11:02:11 -0700839#pragma clang diagnostic pop
Ian Rogers647b1a82014-10-10 11:02:11 -0700840
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200841 case Instruction::CMP_LONG: {
842 PREAMBLE();
843 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
844 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
845 int32_t result;
846 if (val1 > val2) {
847 result = 1;
848 } else if (val1 == val2) {
849 result = 0;
850 } else {
851 result = -1;
852 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200853 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200854 inst = inst->Next_2xx();
855 break;
856 }
857 case Instruction::IF_EQ: {
858 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700859 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) ==
860 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200861 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000862 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200863 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800864 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200865 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800866 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200867 inst = inst->Next_2xx();
868 }
869 break;
870 }
871 case Instruction::IF_NE: {
872 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700873 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
874 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200875 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000876 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200877 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800878 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200879 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800880 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200881 inst = inst->Next_2xx();
882 }
883 break;
884 }
885 case Instruction::IF_LT: {
886 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700887 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
888 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200889 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000890 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200891 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800892 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200893 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800894 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200895 inst = inst->Next_2xx();
896 }
897 break;
898 }
899 case Instruction::IF_GE: {
900 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700901 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
902 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200903 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000904 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200905 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800906 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200907 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800908 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200909 inst = inst->Next_2xx();
910 }
911 break;
912 }
913 case Instruction::IF_GT: {
914 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700915 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
916 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200917 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000918 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200919 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800920 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200921 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800922 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200923 inst = inst->Next_2xx();
924 }
925 break;
926 }
927 case Instruction::IF_LE: {
928 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700929 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
930 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200931 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000932 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200933 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800934 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200935 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800936 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200937 inst = inst->Next_2xx();
938 }
939 break;
940 }
941 case Instruction::IF_EQZ: {
942 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200943 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200944 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000945 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200946 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800947 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200948 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800949 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200950 inst = inst->Next_2xx();
951 }
952 break;
953 }
954 case Instruction::IF_NEZ: {
955 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200956 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200957 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000958 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200959 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800960 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200961 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800962 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200963 inst = inst->Next_2xx();
964 }
965 break;
966 }
967 case Instruction::IF_LTZ: {
968 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200969 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200970 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000971 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200972 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800973 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200974 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800975 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200976 inst = inst->Next_2xx();
977 }
978 break;
979 }
980 case Instruction::IF_GEZ: {
981 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200982 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200983 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000984 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200985 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800986 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200987 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800988 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200989 inst = inst->Next_2xx();
990 }
991 break;
992 }
993 case Instruction::IF_GTZ: {
994 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200995 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200996 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000997 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200998 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800999 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001000 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001001 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001002 inst = inst->Next_2xx();
1003 }
1004 break;
1005 }
1006 case Instruction::IF_LEZ: {
1007 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001008 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001009 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001010 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001011 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001012 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001013 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001014 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001015 inst = inst->Next_2xx();
1016 }
1017 break;
1018 }
1019 case Instruction::AGET_BOOLEAN: {
1020 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001021 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001022 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001023 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001024 HANDLE_PENDING_EXCEPTION();
1025 break;
1026 }
1027 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001028 ObjPtr<mirror::BooleanArray> array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001029 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001030 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001031 inst = inst->Next_2xx();
1032 } else {
1033 HANDLE_PENDING_EXCEPTION();
1034 }
1035 break;
1036 }
1037 case Instruction::AGET_BYTE: {
1038 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001039 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001040 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001041 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001042 HANDLE_PENDING_EXCEPTION();
1043 break;
1044 }
1045 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001046 ObjPtr<mirror::ByteArray> array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001047 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001048 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001049 inst = inst->Next_2xx();
1050 } else {
1051 HANDLE_PENDING_EXCEPTION();
1052 }
1053 break;
1054 }
1055 case Instruction::AGET_CHAR: {
1056 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001057 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001058 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001059 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001060 HANDLE_PENDING_EXCEPTION();
1061 break;
1062 }
1063 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001064 ObjPtr<mirror::CharArray> array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001065 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001066 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001067 inst = inst->Next_2xx();
1068 } else {
1069 HANDLE_PENDING_EXCEPTION();
1070 }
1071 break;
1072 }
1073 case Instruction::AGET_SHORT: {
1074 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001075 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001076 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001077 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001078 HANDLE_PENDING_EXCEPTION();
1079 break;
1080 }
1081 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001082 ObjPtr<mirror::ShortArray> array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001083 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001084 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001085 inst = inst->Next_2xx();
1086 } else {
1087 HANDLE_PENDING_EXCEPTION();
1088 }
1089 break;
1090 }
1091 case Instruction::AGET: {
1092 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001093 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001094 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001095 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001096 HANDLE_PENDING_EXCEPTION();
1097 break;
1098 }
1099 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001100 DCHECK(a->IsIntArray() || a->IsFloatArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001101 ObjPtr<mirror::IntArray> array = ObjPtr<mirror::IntArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001102 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001103 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001104 inst = inst->Next_2xx();
1105 } else {
1106 HANDLE_PENDING_EXCEPTION();
1107 }
1108 break;
1109 }
1110 case Instruction::AGET_WIDE: {
1111 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001112 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001113 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001114 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001115 HANDLE_PENDING_EXCEPTION();
1116 break;
1117 }
1118 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001119 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001120 ObjPtr<mirror::LongArray> array = ObjPtr<mirror::LongArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001121 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001122 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001123 inst = inst->Next_2xx();
1124 } else {
1125 HANDLE_PENDING_EXCEPTION();
1126 }
1127 break;
1128 }
1129 case Instruction::AGET_OBJECT: {
1130 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001131 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001132 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001133 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001134 HANDLE_PENDING_EXCEPTION();
1135 break;
1136 }
1137 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001138 ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001139 if (array->CheckIsValidIndex(index)) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001140 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001141 inst = inst->Next_2xx();
1142 } else {
1143 HANDLE_PENDING_EXCEPTION();
1144 }
1145 break;
1146 }
1147 case Instruction::APUT_BOOLEAN: {
1148 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001149 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001150 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001151 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001152 HANDLE_PENDING_EXCEPTION();
1153 break;
1154 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001155 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001156 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001157 ObjPtr<mirror::BooleanArray> array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001158 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001159 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001160 inst = inst->Next_2xx();
1161 } else {
1162 HANDLE_PENDING_EXCEPTION();
1163 }
1164 break;
1165 }
1166 case Instruction::APUT_BYTE: {
1167 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001168 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001169 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001170 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001171 HANDLE_PENDING_EXCEPTION();
1172 break;
1173 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001174 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001175 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001176 ObjPtr<mirror::ByteArray> array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001177 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001178 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001179 inst = inst->Next_2xx();
1180 } else {
1181 HANDLE_PENDING_EXCEPTION();
1182 }
1183 break;
1184 }
1185 case Instruction::APUT_CHAR: {
1186 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001187 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001188 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001189 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001190 HANDLE_PENDING_EXCEPTION();
1191 break;
1192 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001193 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001194 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001195 ObjPtr<mirror::CharArray> array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001196 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001197 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001198 inst = inst->Next_2xx();
1199 } else {
1200 HANDLE_PENDING_EXCEPTION();
1201 }
1202 break;
1203 }
1204 case Instruction::APUT_SHORT: {
1205 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001206 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001207 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001208 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001209 HANDLE_PENDING_EXCEPTION();
1210 break;
1211 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001212 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001213 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001214 ObjPtr<mirror::ShortArray> array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001215 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001216 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001217 inst = inst->Next_2xx();
1218 } else {
1219 HANDLE_PENDING_EXCEPTION();
1220 }
1221 break;
1222 }
1223 case Instruction::APUT: {
1224 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001225 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001226 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001227 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001228 HANDLE_PENDING_EXCEPTION();
1229 break;
1230 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001231 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001232 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001233 DCHECK(a->IsIntArray() || a->IsFloatArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001234 ObjPtr<mirror::IntArray> array = ObjPtr<mirror::IntArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001235 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001236 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001237 inst = inst->Next_2xx();
1238 } else {
1239 HANDLE_PENDING_EXCEPTION();
1240 }
1241 break;
1242 }
1243 case Instruction::APUT_WIDE: {
1244 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001245 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001246 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001247 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001248 HANDLE_PENDING_EXCEPTION();
1249 break;
1250 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001251 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001252 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001253 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001254 ObjPtr<mirror::LongArray> array = ObjPtr<mirror::LongArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001255 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001256 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001257 inst = inst->Next_2xx();
1258 } else {
1259 HANDLE_PENDING_EXCEPTION();
1260 }
1261 break;
1262 }
1263 case Instruction::APUT_OBJECT: {
1264 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001265 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001266 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001267 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001268 HANDLE_PENDING_EXCEPTION();
1269 break;
1270 }
1271 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001272 ObjPtr<mirror::Object> val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
1273 ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001274 if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001275 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001276 inst = inst->Next_2xx();
1277 } else {
1278 HANDLE_PENDING_EXCEPTION();
1279 }
1280 break;
1281 }
1282 case Instruction::IGET_BOOLEAN: {
1283 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001284 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1285 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001286 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1287 break;
1288 }
1289 case Instruction::IGET_BYTE: {
1290 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001291 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1292 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001293 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1294 break;
1295 }
1296 case Instruction::IGET_CHAR: {
1297 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001298 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1299 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001300 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1301 break;
1302 }
1303 case Instruction::IGET_SHORT: {
1304 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001305 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1306 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001307 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1308 break;
1309 }
1310 case Instruction::IGET: {
1311 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001312 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1313 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001314 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1315 break;
1316 }
1317 case Instruction::IGET_WIDE: {
1318 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001319 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1320 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001321 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1322 break;
1323 }
1324 case Instruction::IGET_OBJECT: {
1325 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001326 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1327 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001328 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1329 break;
1330 }
1331 case Instruction::IGET_QUICK: {
1332 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001333 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001334 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1335 break;
1336 }
1337 case Instruction::IGET_WIDE_QUICK: {
1338 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001339 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001340 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1341 break;
1342 }
1343 case Instruction::IGET_OBJECT_QUICK: {
1344 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001345 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001346 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1347 break;
1348 }
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001349 case Instruction::IGET_BOOLEAN_QUICK: {
1350 PREAMBLE();
1351 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1352 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1353 break;
1354 }
1355 case Instruction::IGET_BYTE_QUICK: {
1356 PREAMBLE();
1357 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1358 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1359 break;
1360 }
1361 case Instruction::IGET_CHAR_QUICK: {
1362 PREAMBLE();
1363 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1364 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1365 break;
1366 }
1367 case Instruction::IGET_SHORT_QUICK: {
1368 PREAMBLE();
1369 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1370 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1371 break;
1372 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001373 case Instruction::SGET_BOOLEAN: {
1374 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001375 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check,
1376 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001377 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1378 break;
1379 }
1380 case Instruction::SGET_BYTE: {
1381 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001382 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check,
1383 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001384 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1385 break;
1386 }
1387 case Instruction::SGET_CHAR: {
1388 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001389 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check,
1390 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001391 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1392 break;
1393 }
1394 case Instruction::SGET_SHORT: {
1395 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001396 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check,
1397 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001398 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1399 break;
1400 }
1401 case Instruction::SGET: {
1402 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001403 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check,
1404 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001405 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1406 break;
1407 }
1408 case Instruction::SGET_WIDE: {
1409 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001410 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check,
1411 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001412 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1413 break;
1414 }
1415 case Instruction::SGET_OBJECT: {
1416 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001417 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check,
1418 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001419 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1420 break;
1421 }
1422 case Instruction::IPUT_BOOLEAN: {
1423 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001424 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1425 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001426 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1427 break;
1428 }
1429 case Instruction::IPUT_BYTE: {
1430 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001431 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1432 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001433 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1434 break;
1435 }
1436 case Instruction::IPUT_CHAR: {
1437 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001438 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1439 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001440 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1441 break;
1442 }
1443 case Instruction::IPUT_SHORT: {
1444 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001445 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1446 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001447 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1448 break;
1449 }
1450 case Instruction::IPUT: {
1451 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001452 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1453 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001454 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1455 break;
1456 }
1457 case Instruction::IPUT_WIDE: {
1458 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001459 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1460 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001461 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1462 break;
1463 }
1464 case Instruction::IPUT_OBJECT: {
1465 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001466 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1467 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001468 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1469 break;
1470 }
1471 case Instruction::IPUT_QUICK: {
1472 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001473 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1474 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001475 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1476 break;
1477 }
Fred Shih37f05ef2014-07-16 18:38:08 -07001478 case Instruction::IPUT_BOOLEAN_QUICK: {
1479 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001480 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1481 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001482 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1483 break;
1484 }
1485 case Instruction::IPUT_BYTE_QUICK: {
1486 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001487 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1488 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001489 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1490 break;
1491 }
1492 case Instruction::IPUT_CHAR_QUICK: {
1493 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001494 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1495 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001496 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1497 break;
1498 }
1499 case Instruction::IPUT_SHORT_QUICK: {
1500 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001501 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1502 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001503 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1504 break;
1505 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001506 case Instruction::IPUT_WIDE_QUICK: {
1507 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001508 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1509 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001510 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1511 break;
1512 }
1513 case Instruction::IPUT_OBJECT_QUICK: {
1514 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001515 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1516 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001517 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1518 break;
1519 }
1520 case Instruction::SPUT_BOOLEAN: {
1521 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001522 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1523 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001524 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1525 break;
1526 }
1527 case Instruction::SPUT_BYTE: {
1528 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001529 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1530 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001531 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1532 break;
1533 }
1534 case Instruction::SPUT_CHAR: {
1535 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001536 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1537 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001538 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1539 break;
1540 }
1541 case Instruction::SPUT_SHORT: {
1542 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001543 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1544 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001545 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1546 break;
1547 }
1548 case Instruction::SPUT: {
1549 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001550 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1551 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001552 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1553 break;
1554 }
1555 case Instruction::SPUT_WIDE: {
1556 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001557 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1558 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001559 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1560 break;
1561 }
1562 case Instruction::SPUT_OBJECT: {
1563 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001564 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1565 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001566 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1567 break;
1568 }
1569 case Instruction::INVOKE_VIRTUAL: {
1570 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001571 bool success = DoInvoke<kVirtual, false, do_access_check>(
1572 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001573 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1574 break;
1575 }
1576 case Instruction::INVOKE_VIRTUAL_RANGE: {
1577 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001578 bool success = DoInvoke<kVirtual, true, do_access_check>(
1579 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001580 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1581 break;
1582 }
1583 case Instruction::INVOKE_SUPER: {
1584 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001585 bool success = DoInvoke<kSuper, false, do_access_check>(
1586 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001587 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1588 break;
1589 }
1590 case Instruction::INVOKE_SUPER_RANGE: {
1591 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001592 bool success = DoInvoke<kSuper, true, do_access_check>(
1593 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001594 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1595 break;
1596 }
1597 case Instruction::INVOKE_DIRECT: {
1598 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001599 bool success = DoInvoke<kDirect, false, do_access_check>(
1600 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001601 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1602 break;
1603 }
1604 case Instruction::INVOKE_DIRECT_RANGE: {
1605 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001606 bool success = DoInvoke<kDirect, true, do_access_check>(
1607 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001608 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1609 break;
1610 }
1611 case Instruction::INVOKE_INTERFACE: {
1612 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001613 bool success = DoInvoke<kInterface, false, do_access_check>(
1614 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001615 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1616 break;
1617 }
1618 case Instruction::INVOKE_INTERFACE_RANGE: {
1619 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001620 bool success = DoInvoke<kInterface, true, do_access_check>(
1621 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001622 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1623 break;
1624 }
1625 case Instruction::INVOKE_STATIC: {
1626 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001627 bool success = DoInvoke<kStatic, false, do_access_check>(
1628 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001629 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1630 break;
1631 }
1632 case Instruction::INVOKE_STATIC_RANGE: {
1633 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001634 bool success = DoInvoke<kStatic, true, do_access_check>(
1635 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001636 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1637 break;
1638 }
1639 case Instruction::INVOKE_VIRTUAL_QUICK: {
1640 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001641 bool success = DoInvokeVirtualQuick<false>(
1642 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001643 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1644 break;
1645 }
1646 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
1647 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001648 bool success = DoInvokeVirtualQuick<true>(
1649 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001650 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1651 break;
1652 }
Narayan Kamath9823e782016-08-03 12:46:58 +01001653 case Instruction::INVOKE_POLYMORPHIC: {
1654 PREAMBLE();
Narayan Kamath269cb432016-10-28 10:19:54 +01001655 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
Orion Hodsonc069a302017-01-18 09:23:12 +00001656 bool success = DoInvokePolymorphic<false /* is_range */>(
Narayan Kamath9823e782016-08-03 12:46:58 +01001657 self, shadow_frame, inst, inst_data, &result_register);
1658 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_4xx);
1659 break;
1660 }
1661 case Instruction::INVOKE_POLYMORPHIC_RANGE: {
1662 PREAMBLE();
Narayan Kamath269cb432016-10-28 10:19:54 +01001663 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
Orion Hodsonc069a302017-01-18 09:23:12 +00001664 bool success = DoInvokePolymorphic<true /* is_range */>(
Narayan Kamath9823e782016-08-03 12:46:58 +01001665 self, shadow_frame, inst, inst_data, &result_register);
1666 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_4xx);
1667 break;
Narayan Kamath9823e782016-08-03 12:46:58 +01001668 }
Orion Hodsonc069a302017-01-18 09:23:12 +00001669 case Instruction::INVOKE_CUSTOM: {
1670 PREAMBLE();
1671 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1672 bool success = DoInvokeCustom<false /* is_range */>(
1673 self, shadow_frame, inst, inst_data, &result_register);
1674 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1675 break;
1676 }
1677 case Instruction::INVOKE_CUSTOM_RANGE: {
1678 PREAMBLE();
1679 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1680 bool success = DoInvokeCustom<true /* is_range */>(
1681 self, shadow_frame, inst, inst_data, &result_register);
1682 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1683 break;
1684 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001685 case Instruction::NEG_INT:
1686 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001687 shadow_frame.SetVReg(
1688 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001689 inst = inst->Next_1xx();
1690 break;
1691 case Instruction::NOT_INT:
1692 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001693 shadow_frame.SetVReg(
1694 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001695 inst = inst->Next_1xx();
1696 break;
1697 case Instruction::NEG_LONG:
1698 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001699 shadow_frame.SetVRegLong(
1700 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001701 inst = inst->Next_1xx();
1702 break;
1703 case Instruction::NOT_LONG:
1704 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001705 shadow_frame.SetVRegLong(
1706 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001707 inst = inst->Next_1xx();
1708 break;
1709 case Instruction::NEG_FLOAT:
1710 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001711 shadow_frame.SetVRegFloat(
1712 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001713 inst = inst->Next_1xx();
1714 break;
1715 case Instruction::NEG_DOUBLE:
1716 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001717 shadow_frame.SetVRegDouble(
1718 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001719 inst = inst->Next_1xx();
1720 break;
1721 case Instruction::INT_TO_LONG:
1722 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001723 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
1724 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001725 inst = inst->Next_1xx();
1726 break;
1727 case Instruction::INT_TO_FLOAT:
1728 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001729 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1730 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001731 inst = inst->Next_1xx();
1732 break;
1733 case Instruction::INT_TO_DOUBLE:
1734 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001735 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1736 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001737 inst = inst->Next_1xx();
1738 break;
1739 case Instruction::LONG_TO_INT:
1740 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001741 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1742 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001743 inst = inst->Next_1xx();
1744 break;
1745 case Instruction::LONG_TO_FLOAT:
1746 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001747 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1748 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001749 inst = inst->Next_1xx();
1750 break;
1751 case Instruction::LONG_TO_DOUBLE:
1752 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001753 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1754 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001755 inst = inst->Next_1xx();
1756 break;
1757 case Instruction::FLOAT_TO_INT: {
1758 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001759 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001760 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001761 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001762 inst = inst->Next_1xx();
1763 break;
1764 }
1765 case Instruction::FLOAT_TO_LONG: {
1766 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001767 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001768 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001769 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001770 inst = inst->Next_1xx();
1771 break;
1772 }
1773 case Instruction::FLOAT_TO_DOUBLE:
1774 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001775 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1776 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001777 inst = inst->Next_1xx();
1778 break;
1779 case Instruction::DOUBLE_TO_INT: {
1780 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001781 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001782 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001783 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001784 inst = inst->Next_1xx();
1785 break;
1786 }
1787 case Instruction::DOUBLE_TO_LONG: {
1788 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001789 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001790 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001791 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001792 inst = inst->Next_1xx();
1793 break;
1794 }
1795 case Instruction::DOUBLE_TO_FLOAT:
1796 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001797 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1798 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001799 inst = inst->Next_1xx();
1800 break;
1801 case Instruction::INT_TO_BYTE:
1802 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001803 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int8_t>(
1804 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001805 inst = inst->Next_1xx();
1806 break;
1807 case Instruction::INT_TO_CHAR:
1808 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001809 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<uint16_t>(
1810 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001811 inst = inst->Next_1xx();
1812 break;
1813 case Instruction::INT_TO_SHORT:
1814 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001815 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int16_t>(
1816 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001817 inst = inst->Next_1xx();
1818 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001819 case Instruction::ADD_INT: {
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001820 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001821 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001822 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1823 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001824 inst = inst->Next_2xx();
1825 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001826 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001827 case Instruction::SUB_INT:
1828 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001829 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001830 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1831 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001832 inst = inst->Next_2xx();
1833 break;
1834 case Instruction::MUL_INT:
1835 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001836 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001837 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1838 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001839 inst = inst->Next_2xx();
1840 break;
1841 case Instruction::DIV_INT: {
1842 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001843 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001844 shadow_frame.GetVReg(inst->VRegB_23x()),
1845 shadow_frame.GetVReg(inst->VRegC_23x()));
1846 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1847 break;
1848 }
1849 case Instruction::REM_INT: {
1850 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001851 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001852 shadow_frame.GetVReg(inst->VRegB_23x()),
1853 shadow_frame.GetVReg(inst->VRegC_23x()));
1854 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1855 break;
1856 }
1857 case Instruction::SHL_INT:
1858 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001859 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001860 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1861 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1862 inst = inst->Next_2xx();
1863 break;
1864 case Instruction::SHR_INT:
1865 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001866 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001867 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1868 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1869 inst = inst->Next_2xx();
1870 break;
1871 case Instruction::USHR_INT:
1872 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001873 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001874 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1875 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1876 inst = inst->Next_2xx();
1877 break;
1878 case Instruction::AND_INT:
1879 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001880 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001881 shadow_frame.GetVReg(inst->VRegB_23x()) &
1882 shadow_frame.GetVReg(inst->VRegC_23x()));
1883 inst = inst->Next_2xx();
1884 break;
1885 case Instruction::OR_INT:
1886 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001887 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001888 shadow_frame.GetVReg(inst->VRegB_23x()) |
1889 shadow_frame.GetVReg(inst->VRegC_23x()));
1890 inst = inst->Next_2xx();
1891 break;
1892 case Instruction::XOR_INT:
1893 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001894 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001895 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1896 shadow_frame.GetVReg(inst->VRegC_23x()));
1897 inst = inst->Next_2xx();
1898 break;
1899 case Instruction::ADD_LONG:
1900 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001901 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001902 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1903 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001904 inst = inst->Next_2xx();
1905 break;
1906 case Instruction::SUB_LONG:
1907 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001908 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001909 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1910 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001911 inst = inst->Next_2xx();
1912 break;
1913 case Instruction::MUL_LONG:
1914 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001915 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001916 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1917 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001918 inst = inst->Next_2xx();
1919 break;
1920 case Instruction::DIV_LONG:
1921 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001922 DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001923 shadow_frame.GetVRegLong(inst->VRegB_23x()),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001924 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001925 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1926 break;
1927 case Instruction::REM_LONG:
1928 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001929 DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001930 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1931 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1932 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1933 break;
1934 case Instruction::AND_LONG:
1935 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001936 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001937 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1938 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1939 inst = inst->Next_2xx();
1940 break;
1941 case Instruction::OR_LONG:
1942 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001943 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001944 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1945 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1946 inst = inst->Next_2xx();
1947 break;
1948 case Instruction::XOR_LONG:
1949 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001950 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001951 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1952 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1953 inst = inst->Next_2xx();
1954 break;
1955 case Instruction::SHL_LONG:
1956 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001957 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001958 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1959 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1960 inst = inst->Next_2xx();
1961 break;
1962 case Instruction::SHR_LONG:
1963 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001964 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001965 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1966 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1967 inst = inst->Next_2xx();
1968 break;
1969 case Instruction::USHR_LONG:
1970 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001971 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001972 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1973 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1974 inst = inst->Next_2xx();
1975 break;
1976 case Instruction::ADD_FLOAT:
1977 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001978 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001979 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1980 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1981 inst = inst->Next_2xx();
1982 break;
1983 case Instruction::SUB_FLOAT:
1984 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001985 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001986 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1987 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1988 inst = inst->Next_2xx();
1989 break;
1990 case Instruction::MUL_FLOAT:
1991 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001992 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001993 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1994 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1995 inst = inst->Next_2xx();
1996 break;
1997 case Instruction::DIV_FLOAT:
1998 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001999 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002000 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
2001 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
2002 inst = inst->Next_2xx();
2003 break;
2004 case Instruction::REM_FLOAT:
2005 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002006 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002007 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
2008 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
2009 inst = inst->Next_2xx();
2010 break;
2011 case Instruction::ADD_DOUBLE:
2012 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002013 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002014 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
2015 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2016 inst = inst->Next_2xx();
2017 break;
2018 case Instruction::SUB_DOUBLE:
2019 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002020 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002021 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
2022 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2023 inst = inst->Next_2xx();
2024 break;
2025 case Instruction::MUL_DOUBLE:
2026 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002027 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002028 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
2029 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2030 inst = inst->Next_2xx();
2031 break;
2032 case Instruction::DIV_DOUBLE:
2033 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002034 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002035 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
2036 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2037 inst = inst->Next_2xx();
2038 break;
2039 case Instruction::REM_DOUBLE:
2040 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002041 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002042 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
2043 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
2044 inst = inst->Next_2xx();
2045 break;
2046 case Instruction::ADD_INT_2ADDR: {
2047 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002048 uint4_t vregA = inst->VRegA_12x(inst_data);
Ian Rogersf72a11d2014-10-30 15:41:08 -07002049 shadow_frame.SetVReg(vregA, SafeAdd(shadow_frame.GetVReg(vregA),
2050 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002051 inst = inst->Next_1xx();
2052 break;
2053 }
2054 case Instruction::SUB_INT_2ADDR: {
2055 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002056 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002057 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002058 SafeSub(shadow_frame.GetVReg(vregA),
2059 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002060 inst = inst->Next_1xx();
2061 break;
2062 }
2063 case Instruction::MUL_INT_2ADDR: {
2064 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002065 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002066 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002067 SafeMul(shadow_frame.GetVReg(vregA),
2068 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002069 inst = inst->Next_1xx();
2070 break;
2071 }
2072 case Instruction::DIV_INT_2ADDR: {
2073 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002074 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002075 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002076 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002077 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
2078 break;
2079 }
2080 case Instruction::REM_INT_2ADDR: {
2081 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002082 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002083 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002084 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002085 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
2086 break;
2087 }
2088 case Instruction::SHL_INT_2ADDR: {
2089 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002090 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002091 shadow_frame.SetVReg(vregA,
2092 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002093 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002094 inst = inst->Next_1xx();
2095 break;
2096 }
2097 case Instruction::SHR_INT_2ADDR: {
2098 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002099 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002100 shadow_frame.SetVReg(vregA,
2101 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002102 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002103 inst = inst->Next_1xx();
2104 break;
2105 }
2106 case Instruction::USHR_INT_2ADDR: {
2107 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002108 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002109 shadow_frame.SetVReg(vregA,
2110 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002111 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002112 inst = inst->Next_1xx();
2113 break;
2114 }
2115 case Instruction::AND_INT_2ADDR: {
2116 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002117 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002118 shadow_frame.SetVReg(vregA,
2119 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002120 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002121 inst = inst->Next_1xx();
2122 break;
2123 }
2124 case Instruction::OR_INT_2ADDR: {
2125 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002126 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002127 shadow_frame.SetVReg(vregA,
2128 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002129 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002130 inst = inst->Next_1xx();
2131 break;
2132 }
2133 case Instruction::XOR_INT_2ADDR: {
2134 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002135 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002136 shadow_frame.SetVReg(vregA,
2137 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002138 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002139 inst = inst->Next_1xx();
2140 break;
2141 }
2142 case Instruction::ADD_LONG_2ADDR: {
2143 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002144 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002145 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002146 SafeAdd(shadow_frame.GetVRegLong(vregA),
2147 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002148 inst = inst->Next_1xx();
2149 break;
2150 }
2151 case Instruction::SUB_LONG_2ADDR: {
2152 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002153 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002154 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002155 SafeSub(shadow_frame.GetVRegLong(vregA),
2156 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002157 inst = inst->Next_1xx();
2158 break;
2159 }
2160 case Instruction::MUL_LONG_2ADDR: {
2161 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002162 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002163 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002164 SafeMul(shadow_frame.GetVRegLong(vregA),
2165 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002166 inst = inst->Next_1xx();
2167 break;
2168 }
2169 case Instruction::DIV_LONG_2ADDR: {
2170 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002171 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002172 DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002173 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002174 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
2175 break;
2176 }
2177 case Instruction::REM_LONG_2ADDR: {
2178 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002179 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002180 DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002181 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002182 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
2183 break;
2184 }
2185 case Instruction::AND_LONG_2ADDR: {
2186 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002187 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002188 shadow_frame.SetVRegLong(vregA,
2189 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002190 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002191 inst = inst->Next_1xx();
2192 break;
2193 }
2194 case Instruction::OR_LONG_2ADDR: {
2195 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002196 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002197 shadow_frame.SetVRegLong(vregA,
2198 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002199 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002200 inst = inst->Next_1xx();
2201 break;
2202 }
2203 case Instruction::XOR_LONG_2ADDR: {
2204 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002205 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002206 shadow_frame.SetVRegLong(vregA,
2207 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002208 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002209 inst = inst->Next_1xx();
2210 break;
2211 }
2212 case Instruction::SHL_LONG_2ADDR: {
2213 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002214 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002215 shadow_frame.SetVRegLong(vregA,
2216 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002217 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002218 inst = inst->Next_1xx();
2219 break;
2220 }
2221 case Instruction::SHR_LONG_2ADDR: {
2222 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002223 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002224 shadow_frame.SetVRegLong(vregA,
2225 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002226 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002227 inst = inst->Next_1xx();
2228 break;
2229 }
2230 case Instruction::USHR_LONG_2ADDR: {
2231 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002232 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002233 shadow_frame.SetVRegLong(vregA,
2234 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002235 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002236 inst = inst->Next_1xx();
2237 break;
2238 }
2239 case Instruction::ADD_FLOAT_2ADDR: {
2240 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002241 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002242 shadow_frame.SetVRegFloat(vregA,
2243 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002244 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002245 inst = inst->Next_1xx();
2246 break;
2247 }
2248 case Instruction::SUB_FLOAT_2ADDR: {
2249 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002250 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002251 shadow_frame.SetVRegFloat(vregA,
2252 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002253 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002254 inst = inst->Next_1xx();
2255 break;
2256 }
2257 case Instruction::MUL_FLOAT_2ADDR: {
2258 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002259 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002260 shadow_frame.SetVRegFloat(vregA,
2261 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002262 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002263 inst = inst->Next_1xx();
2264 break;
2265 }
2266 case Instruction::DIV_FLOAT_2ADDR: {
2267 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002268 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002269 shadow_frame.SetVRegFloat(vregA,
2270 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002271 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002272 inst = inst->Next_1xx();
2273 break;
2274 }
2275 case Instruction::REM_FLOAT_2ADDR: {
2276 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002277 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002278 shadow_frame.SetVRegFloat(vregA,
2279 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002280 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002281 inst = inst->Next_1xx();
2282 break;
2283 }
2284 case Instruction::ADD_DOUBLE_2ADDR: {
2285 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002286 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002287 shadow_frame.SetVRegDouble(vregA,
2288 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002289 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002290 inst = inst->Next_1xx();
2291 break;
2292 }
2293 case Instruction::SUB_DOUBLE_2ADDR: {
2294 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002295 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002296 shadow_frame.SetVRegDouble(vregA,
2297 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002298 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002299 inst = inst->Next_1xx();
2300 break;
2301 }
2302 case Instruction::MUL_DOUBLE_2ADDR: {
2303 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002304 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002305 shadow_frame.SetVRegDouble(vregA,
2306 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002307 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002308 inst = inst->Next_1xx();
2309 break;
2310 }
2311 case Instruction::DIV_DOUBLE_2ADDR: {
2312 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002313 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002314 shadow_frame.SetVRegDouble(vregA,
2315 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002316 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002317 inst = inst->Next_1xx();
2318 break;
2319 }
2320 case Instruction::REM_DOUBLE_2ADDR: {
2321 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002322 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002323 shadow_frame.SetVRegDouble(vregA,
2324 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002325 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002326 inst = inst->Next_1xx();
2327 break;
2328 }
2329 case Instruction::ADD_INT_LIT16:
2330 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002331 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002332 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2333 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002334 inst = inst->Next_2xx();
2335 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07002336 case Instruction::RSUB_INT_LIT16:
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002337 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002338 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002339 SafeSub(inst->VRegC_22s(),
2340 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002341 inst = inst->Next_2xx();
2342 break;
2343 case Instruction::MUL_INT_LIT16:
2344 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002345 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002346 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2347 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002348 inst = inst->Next_2xx();
2349 break;
2350 case Instruction::DIV_INT_LIT16: {
2351 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002352 bool success = DoIntDivide(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002353 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2354 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002355 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2356 break;
2357 }
2358 case Instruction::REM_INT_LIT16: {
2359 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002360 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002361 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2362 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002363 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2364 break;
2365 }
2366 case Instruction::AND_INT_LIT16:
2367 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002368 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2369 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002370 inst->VRegC_22s());
2371 inst = inst->Next_2xx();
2372 break;
2373 case Instruction::OR_INT_LIT16:
2374 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002375 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2376 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002377 inst->VRegC_22s());
2378 inst = inst->Next_2xx();
2379 break;
2380 case Instruction::XOR_INT_LIT16:
2381 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002382 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2383 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002384 inst->VRegC_22s());
2385 inst = inst->Next_2xx();
2386 break;
2387 case Instruction::ADD_INT_LIT8:
2388 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002389 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002390 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002391 inst = inst->Next_2xx();
2392 break;
2393 case Instruction::RSUB_INT_LIT8:
2394 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002395 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002396 SafeSub(inst->VRegC_22b(), shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002397 inst = inst->Next_2xx();
2398 break;
2399 case Instruction::MUL_INT_LIT8:
2400 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002401 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002402 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002403 inst = inst->Next_2xx();
2404 break;
2405 case Instruction::DIV_INT_LIT8: {
2406 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002407 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002408 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2409 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2410 break;
2411 }
2412 case Instruction::REM_INT_LIT8: {
2413 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002414 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002415 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2416 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2417 break;
2418 }
2419 case Instruction::AND_INT_LIT8:
2420 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002421 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002422 shadow_frame.GetVReg(inst->VRegB_22b()) &
2423 inst->VRegC_22b());
2424 inst = inst->Next_2xx();
2425 break;
2426 case Instruction::OR_INT_LIT8:
2427 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002428 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002429 shadow_frame.GetVReg(inst->VRegB_22b()) |
2430 inst->VRegC_22b());
2431 inst = inst->Next_2xx();
2432 break;
2433 case Instruction::XOR_INT_LIT8:
2434 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002435 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002436 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2437 inst->VRegC_22b());
2438 inst = inst->Next_2xx();
2439 break;
2440 case Instruction::SHL_INT_LIT8:
2441 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002442 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002443 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2444 (inst->VRegC_22b() & 0x1f));
2445 inst = inst->Next_2xx();
2446 break;
2447 case Instruction::SHR_INT_LIT8:
2448 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002449 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002450 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2451 (inst->VRegC_22b() & 0x1f));
2452 inst = inst->Next_2xx();
2453 break;
2454 case Instruction::USHR_INT_LIT8:
2455 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002456 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002457 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2458 (inst->VRegC_22b() & 0x1f));
2459 inst = inst->Next_2xx();
2460 break;
2461 case Instruction::UNUSED_3E ... Instruction::UNUSED_43:
Orion Hodson2e599942017-09-22 16:17:41 +01002462 case Instruction::UNUSED_79 ... Instruction::UNUSED_7A:
Narayan Kamath8ec3bd22016-08-03 12:46:23 +01002463 case Instruction::UNUSED_F3 ... Instruction::UNUSED_F9:
Ian Rogerse94652f2014-12-02 11:13:19 -08002464 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002465 }
buzbee1452bee2015-03-06 14:43:04 -08002466 } while (!interpret_one_instruction);
2467 // Record where we stopped.
2468 shadow_frame.SetDexPC(inst->GetDexPc(insns));
buzbeed6b48db2016-01-28 15:48:55 -08002469 return result_register;
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002470} // NOLINT(readability/fn_size)
2471
2472// Explicit definitions of ExecuteSwitchImpl.
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002473template HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002474JValue ExecuteSwitchImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -08002475 ShadowFrame& shadow_frame, JValue result_register,
2476 bool interpret_one_instruction);
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002477template HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002478JValue ExecuteSwitchImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -08002479 ShadowFrame& shadow_frame, JValue result_register,
2480 bool interpret_one_instruction);
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002481template
Ian Rogerse94652f2014-12-02 11:13:19 -08002482JValue ExecuteSwitchImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -08002483 ShadowFrame& shadow_frame, JValue result_register,
2484 bool interpret_one_instruction);
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002485template
Ian Rogerse94652f2014-12-02 11:13:19 -08002486JValue ExecuteSwitchImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -08002487 ShadowFrame& shadow_frame, JValue result_register,
2488 bool interpret_one_instruction);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002489
2490} // namespace interpreter
2491} // namespace art