blob: f352960204dbea4052208748e5af42d199003478 [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"
Alex Lighteb7c1442015-08-31 13:17:42 -070020#include "experimental_flags.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020021#include "interpreter_common.h"
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000022#include "jit/jit.h"
Mathieu Chartier28bd2e42016-10-04 13:54:57 -070023#include "jvalue-inl.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070024#include "safe_math.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020025
26namespace art {
27namespace interpreter {
28
Alex Lightb7edcda2017-04-27 13:20:31 -070029#define HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(instr) \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020030 do { \
Sebastien Hertz82aeddb2014-05-20 20:09:45 +020031 DCHECK(self->IsExceptionPending()); \
Ian Rogers7b078e82014-09-10 14:44:24 -070032 self->AllowThreadSuspension(); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020033 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, \
34 inst->GetDexPc(insns), \
Alex Lightb7edcda2017-04-27 13:20:31 -070035 instr); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020036 if (found_dex_pc == DexFile::kDexNoIndex) { \
Andreas Gampe03ec9302015-08-27 17:41:47 -070037 /* Structured locking is to be enforced for abnormal termination, too. */ \
Andreas Gampe56fdd0e2016-04-28 14:56:54 -070038 DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame); \
buzbee1452bee2015-03-06 14:43:04 -080039 if (interpret_one_instruction) { \
buzbee93e94f22016-04-07 13:52:48 -070040 /* Signal mterp to return to caller */ \
buzbee1452bee2015-03-06 14:43:04 -080041 shadow_frame.SetDexPC(DexFile::kDexNoIndex); \
42 } \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020043 return JValue(); /* Handled in caller. */ \
44 } else { \
45 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc); \
46 inst = inst->RelativeAt(displacement); \
47 } \
48 } while (false)
49
Alex Lightb7edcda2017-04-27 13:20:31 -070050#define HANDLE_PENDING_EXCEPTION() HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(instrumentation)
51
Sebastien Hertz8ece0502013-08-07 11:26:41 +020052#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _next_function) \
53 do { \
54 if (UNLIKELY(_is_exception_pending)) { \
55 HANDLE_PENDING_EXCEPTION(); \
56 } else { \
57 inst = inst->_next_function(); \
58 } \
59 } while (false)
60
Andreas Gampe03ec9302015-08-27 17:41:47 -070061#define HANDLE_MONITOR_CHECKS() \
Andreas Gampe56fdd0e2016-04-28 14:56:54 -070062 if (!DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame)) { \
Andreas Gampe03ec9302015-08-27 17:41:47 -070063 HANDLE_PENDING_EXCEPTION(); \
64 }
65
Sebastien Hertz8ece0502013-08-07 11:26:41 +020066// Code to run before each dex instruction.
Alex Lightfc905672017-06-27 17:53:15 -070067#define PREAMBLE_SAVE(save_ref) \
68 { \
69 if (UNLIKELY(instrumentation->HasDexPcListeners()) && \
70 UNLIKELY(!DoDexPcMoveEvent(self, \
71 code_item, \
72 shadow_frame, \
73 dex_pc, \
74 instrumentation, \
75 save_ref))) { \
76 HANDLE_PENDING_EXCEPTION(); \
77 break; \
Sebastien Hertz8379b222014-02-24 17:38:15 +010078 } \
Alex Lightfc905672017-06-27 17:53:15 -070079 } \
80 do {} while (false)
81
82#define PREAMBLE() PREAMBLE_SAVE(nullptr)
Sebastien Hertz8ece0502013-08-07 11:26:41 +020083
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000084#define BRANCH_INSTRUMENTATION(offset) \
85 do { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010086 if (UNLIKELY(instrumentation->HasBranchListeners())) { \
87 instrumentation->Branch(self, method, dex_pc, offset); \
88 } \
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000089 JValue result; \
90 if (jit::Jit::MaybeDoOnStackReplacement(self, method, dex_pc, offset, &result)) { \
buzbee93e94f22016-04-07 13:52:48 -070091 if (interpret_one_instruction) { \
92 /* OSR has completed execution of the method. Signal mterp to return to caller */ \
93 shadow_frame.SetDexPC(DexFile::kDexNoIndex); \
94 } \
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000095 return result; \
96 } \
Nicolas Geoffray3108daf2015-11-24 16:32:33 +000097 } while (false)
98
Bill Buzbee1d011d92016-04-04 16:59:29 +000099#define HOTNESS_UPDATE() \
100 do { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100101 if (jit != nullptr) { \
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +0100102 jit->AddSamples(self, method, 1, /*with_backedges*/ true); \
Bill Buzbee1d011d92016-04-04 16:59:29 +0000103 } \
104 } while (false)
105
Andreas Gampef4f76372016-12-13 14:43:58 -0800106#define HANDLE_BACKWARD_BRANCH(offset) \
107 do { \
108 if (IsBackwardBranch(offset)) { \
109 HOTNESS_UPDATE(); \
110 /* Record new dex pc early to have consistent suspend point at loop header. */ \
111 shadow_frame.SetDexPC(inst->GetDexPc(insns)); \
112 self->AllowThreadSuspension(); \
113 } \
114 } while (false)
115
Alex Lightfc905672017-06-27 17:53:15 -0700116// Unlike most other events the DexPcMovedEvent can be sent when there is a pending exception (if
117// the next instruction is MOVE_EXCEPTION). This means it needs to be handled carefully to be able
118// to detect exceptions thrown by the DexPcMovedEvent itself. These exceptions could be thrown by
119// jvmti-agents while handling breakpoint or single step events. We had to move this into its own
120// function because it was making ExecuteSwitchImpl have too large a stack.
Alex Light2989a4a2017-06-29 09:44:57 -0700121NO_INLINE static bool DoDexPcMoveEvent(Thread* self,
122 const DexFile::CodeItem* code_item,
123 const ShadowFrame& shadow_frame,
124 uint32_t dex_pc,
125 const instrumentation::Instrumentation* instrumentation,
126 JValue* save_ref)
Alex Lightfc905672017-06-27 17:53:15 -0700127 REQUIRES_SHARED(Locks::mutator_lock_) {
128 DCHECK(instrumentation->HasDexPcListeners());
129 StackHandleScope<2> hs(self);
130 Handle<mirror::Throwable> thr(hs.NewHandle(self->GetException()));
131 mirror::Object* null_obj = nullptr;
132 HandleWrapper<mirror::Object> h(
133 hs.NewHandleWrapper(LIKELY(save_ref == nullptr) ? &null_obj : save_ref->GetGCRoot()));
134 self->ClearException();
135 instrumentation->DexPcMovedEvent(self,
136 shadow_frame.GetThisObject(code_item->ins_size_),
137 shadow_frame.GetMethod(),
138 dex_pc);
139 if (UNLIKELY(self->IsExceptionPending())) {
140 // We got a new exception in the dex-pc-moved event. We just let this exception replace the old
141 // one.
142 // TODO It would be good to add the old exception to the suppressed exceptions of the new one if
143 // possible.
144 return false;
145 } else {
146 if (UNLIKELY(!thr.IsNull())) {
147 self->SetException(thr.Get());
148 }
149 return true;
150 }
151}
152
Alex Lighte814f9d2017-07-31 16:14:39 -0700153static bool NeedsMethodExitEvent(const instrumentation::Instrumentation* ins)
154 REQUIRES_SHARED(Locks::mutator_lock_) {
155 return ins->HasMethodExitListeners() || ins->HasWatchedFramePopListeners();
156}
157
158// Sends the normal method exit event. Returns true if the events succeeded and false if there is a
159// pending exception.
160NO_INLINE static bool SendMethodExitEvents(Thread* self,
161 const instrumentation::Instrumentation* instrumentation,
162 const ShadowFrame& frame,
163 ObjPtr<mirror::Object> thiz,
164 ArtMethod* method,
165 uint32_t dex_pc,
166 const JValue& result)
167 REQUIRES_SHARED(Locks::mutator_lock_) {
168 bool had_event = false;
169 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
170 had_event = true;
171 instrumentation->MethodExitEvent(self, thiz.Ptr(), method, dex_pc, result);
172 }
173 if (UNLIKELY(frame.NeedsNotifyPop() && instrumentation->HasWatchedFramePopListeners())) {
174 had_event = true;
175 instrumentation->WatchedFramePopped(self, frame);
176 }
177 if (UNLIKELY(had_event)) {
178 return !self->IsExceptionPending();
179 } else {
180 return true;
181 }
182}
183
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100184template<bool do_access_check, bool transaction_active>
Ian Rogerse94652f2014-12-02 11:13:19 -0800185JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -0800186 ShadowFrame& shadow_frame, JValue result_register,
187 bool interpret_one_instruction) {
Igor Murashkinc449e8b2015-06-10 15:56:42 -0700188 constexpr bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200189 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
190 LOG(FATAL) << "Invalid shadow frame for interpreter use";
191 return JValue();
192 }
193 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200194
195 uint32_t dex_pc = shadow_frame.GetDexPC();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700196 const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200197 const uint16_t* const insns = code_item->insns_;
198 const Instruction* inst = Instruction::At(insns + dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200199 uint16_t inst_data;
Bill Buzbee1d011d92016-04-04 16:59:29 +0000200 ArtMethod* method = shadow_frame.GetMethod();
201 jit::Jit* jit = Runtime::Current()->GetJit();
Igor Murashkin6918bf12015-09-27 19:19:06 -0700202
buzbee1452bee2015-03-06 14:43:04 -0800203 do {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200204 dex_pc = inst->GetDexPc(insns);
205 shadow_frame.SetDexPC(dex_pc);
Ian Rogerse94652f2014-12-02 11:13:19 -0800206 TraceExecution(shadow_frame, inst, dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200207 inst_data = inst->Fetch16(0);
208 switch (inst->Opcode(inst_data)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200209 case Instruction::NOP:
210 PREAMBLE();
211 inst = inst->Next_1xx();
212 break;
213 case Instruction::MOVE:
214 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200215 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
216 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200217 inst = inst->Next_1xx();
218 break;
219 case Instruction::MOVE_FROM16:
220 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200221 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200222 shadow_frame.GetVReg(inst->VRegB_22x()));
223 inst = inst->Next_2xx();
224 break;
225 case Instruction::MOVE_16:
226 PREAMBLE();
227 shadow_frame.SetVReg(inst->VRegA_32x(),
228 shadow_frame.GetVReg(inst->VRegB_32x()));
229 inst = inst->Next_3xx();
230 break;
231 case Instruction::MOVE_WIDE:
232 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200233 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
234 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200235 inst = inst->Next_1xx();
236 break;
237 case Instruction::MOVE_WIDE_FROM16:
238 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200239 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200240 shadow_frame.GetVRegLong(inst->VRegB_22x()));
241 inst = inst->Next_2xx();
242 break;
243 case Instruction::MOVE_WIDE_16:
244 PREAMBLE();
245 shadow_frame.SetVRegLong(inst->VRegA_32x(),
246 shadow_frame.GetVRegLong(inst->VRegB_32x()));
247 inst = inst->Next_3xx();
248 break;
249 case Instruction::MOVE_OBJECT:
250 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200251 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
252 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200253 inst = inst->Next_1xx();
254 break;
255 case Instruction::MOVE_OBJECT_FROM16:
256 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200257 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200258 shadow_frame.GetVRegReference(inst->VRegB_22x()));
259 inst = inst->Next_2xx();
260 break;
261 case Instruction::MOVE_OBJECT_16:
262 PREAMBLE();
263 shadow_frame.SetVRegReference(inst->VRegA_32x(),
264 shadow_frame.GetVRegReference(inst->VRegB_32x()));
265 inst = inst->Next_3xx();
266 break;
267 case Instruction::MOVE_RESULT:
268 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200269 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200270 inst = inst->Next_1xx();
271 break;
272 case Instruction::MOVE_RESULT_WIDE:
273 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200274 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200275 inst = inst->Next_1xx();
276 break;
277 case Instruction::MOVE_RESULT_OBJECT:
Alex Lightfc905672017-06-27 17:53:15 -0700278 PREAMBLE_SAVE(&result_register);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200279 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200280 inst = inst->Next_1xx();
281 break;
282 case Instruction::MOVE_EXCEPTION: {
283 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700284 ObjPtr<mirror::Throwable> exception = self->GetException();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100285 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
Mathieu Chartieref41db72016-10-25 15:08:01 -0700286 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception.Ptr());
Sebastien Hertz5c004902014-05-21 10:07:42 +0200287 self->ClearException();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200288 inst = inst->Next_1xx();
289 break;
290 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700291 case Instruction::RETURN_VOID_NO_BARRIER: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200292 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200293 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700294 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700295 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700296 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
297 !SendMethodExitEvents(self,
298 instrumentation,
299 shadow_frame,
300 shadow_frame.GetThisObject(code_item->ins_size_),
301 shadow_frame.GetMethod(),
302 inst->GetDexPc(insns),
303 result))) {
304 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200305 }
buzbee1452bee2015-03-06 14:43:04 -0800306 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700307 /* Signal mterp to return to caller */
buzbee1452bee2015-03-06 14:43:04 -0800308 shadow_frame.SetDexPC(DexFile::kDexNoIndex);
309 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200310 return result;
311 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700312 case Instruction::RETURN_VOID: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200313 PREAMBLE();
Hans Boehm30359612014-05-21 17:46:23 -0700314 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200315 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700316 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700317 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700318 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
319 !SendMethodExitEvents(self,
320 instrumentation,
321 shadow_frame,
322 shadow_frame.GetThisObject(code_item->ins_size_),
323 shadow_frame.GetMethod(),
324 inst->GetDexPc(insns),
325 result))) {
326 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200327 }
buzbee1452bee2015-03-06 14:43:04 -0800328 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700329 /* Signal mterp to return to caller */
buzbee1452bee2015-03-06 14:43:04 -0800330 shadow_frame.SetDexPC(DexFile::kDexNoIndex);
331 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200332 return result;
333 }
334 case Instruction::RETURN: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200335 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200336 JValue result;
337 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200338 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700339 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700340 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700341 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
342 !SendMethodExitEvents(self,
343 instrumentation,
344 shadow_frame,
345 shadow_frame.GetThisObject(code_item->ins_size_),
346 shadow_frame.GetMethod(),
347 inst->GetDexPc(insns),
348 result))) {
349 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200350 }
buzbee1452bee2015-03-06 14:43:04 -0800351 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700352 /* Signal mterp to return to caller */
buzbee1452bee2015-03-06 14:43:04 -0800353 shadow_frame.SetDexPC(DexFile::kDexNoIndex);
354 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200355 return result;
356 }
357 case Instruction::RETURN_WIDE: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200358 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200359 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200360 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700361 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700362 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700363 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
364 !SendMethodExitEvents(self,
365 instrumentation,
366 shadow_frame,
367 shadow_frame.GetThisObject(code_item->ins_size_),
368 shadow_frame.GetMethod(),
369 inst->GetDexPc(insns),
370 result))) {
371 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200372 }
buzbee1452bee2015-03-06 14:43:04 -0800373 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700374 /* Signal mterp to return to caller */
buzbee1452bee2015-03-06 14:43:04 -0800375 shadow_frame.SetDexPC(DexFile::kDexNoIndex);
376 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200377 return result;
378 }
379 case Instruction::RETURN_OBJECT: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200380 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200381 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700382 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700383 HANDLE_MONITOR_CHECKS();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700384 const size_t ref_idx = inst->VRegA_11x(inst_data);
Mathieu Chartieref41db72016-10-25 15:08:01 -0700385 ObjPtr<mirror::Object> obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700386 if (do_assignability_check && obj_result != nullptr) {
Vladimir Markob45528c2017-07-27 14:14:28 +0100387 ObjPtr<mirror::Class> return_type = method->ResolveReturnType();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700388 // Re-load since it might have moved.
389 obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700390 if (return_type == nullptr) {
Jeff Haoa3faaf42013-09-03 19:07:00 -0700391 // Return the pending exception.
392 HANDLE_PENDING_EXCEPTION();
393 }
394 if (!obj_result->VerifierInstanceOf(return_type)) {
395 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700396 std::string temp1, temp2;
Orion Hodsonfef06642016-11-25 16:07:11 +0000397 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700398 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700399 obj_result->GetClass()->GetDescriptor(&temp1),
400 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700401 HANDLE_PENDING_EXCEPTION();
402 }
403 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700404 result.SetL(obj_result);
Alex Lighte814f9d2017-07-31 16:14:39 -0700405 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
406 !SendMethodExitEvents(self,
407 instrumentation,
408 shadow_frame,
409 shadow_frame.GetThisObject(code_item->ins_size_),
410 shadow_frame.GetMethod(),
411 inst->GetDexPc(insns),
412 result))) {
413 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200414 }
Alex Lighte814f9d2017-07-31 16:14:39 -0700415 // Re-load since it might have moved during the MethodExitEvent.
416 result.SetL(shadow_frame.GetVRegReference(ref_idx));
buzbee1452bee2015-03-06 14:43:04 -0800417 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700418 /* Signal mterp to return to caller */
buzbee1452bee2015-03-06 14:43:04 -0800419 shadow_frame.SetDexPC(DexFile::kDexNoIndex);
420 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200421 return result;
422 }
423 case Instruction::CONST_4: {
424 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200425 uint4_t dst = inst->VRegA_11n(inst_data);
426 int4_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200427 shadow_frame.SetVReg(dst, val);
428 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700429 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200430 }
431 inst = inst->Next_1xx();
432 break;
433 }
434 case Instruction::CONST_16: {
435 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200436 uint8_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200437 int16_t val = inst->VRegB_21s();
438 shadow_frame.SetVReg(dst, val);
439 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700440 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200441 }
442 inst = inst->Next_2xx();
443 break;
444 }
445 case Instruction::CONST: {
446 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200447 uint8_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200448 int32_t val = inst->VRegB_31i();
449 shadow_frame.SetVReg(dst, val);
450 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700451 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200452 }
453 inst = inst->Next_3xx();
454 break;
455 }
456 case Instruction::CONST_HIGH16: {
457 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200458 uint8_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200459 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
460 shadow_frame.SetVReg(dst, val);
461 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700462 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200463 }
464 inst = inst->Next_2xx();
465 break;
466 }
467 case Instruction::CONST_WIDE_16:
468 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200469 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200470 inst = inst->Next_2xx();
471 break;
472 case Instruction::CONST_WIDE_32:
473 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200474 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200475 inst = inst->Next_3xx();
476 break;
477 case Instruction::CONST_WIDE:
478 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200479 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200480 inst = inst->Next_51l();
481 break;
482 case Instruction::CONST_WIDE_HIGH16:
Sebastien Hertz3c5aec12014-06-04 09:41:21 +0200483 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200484 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200485 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
486 inst = inst->Next_2xx();
487 break;
488 case Instruction::CONST_STRING: {
489 PREAMBLE();
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800490 ObjPtr<mirror::String> s = ResolveString(self,
491 shadow_frame,
492 dex::StringIndex(inst->VRegB_21c()));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700493 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200494 HANDLE_PENDING_EXCEPTION();
495 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700496 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s.Ptr());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200497 inst = inst->Next_2xx();
498 }
499 break;
500 }
501 case Instruction::CONST_STRING_JUMBO: {
502 PREAMBLE();
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800503 ObjPtr<mirror::String> s = ResolveString(self,
504 shadow_frame,
505 dex::StringIndex(inst->VRegB_31c()));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700506 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200507 HANDLE_PENDING_EXCEPTION();
508 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700509 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s.Ptr());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200510 inst = inst->Next_3xx();
511 }
512 break;
513 }
514 case Instruction::CONST_CLASS: {
515 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800516 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700517 shadow_frame.GetMethod(),
518 self,
519 false,
520 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700521 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200522 HANDLE_PENDING_EXCEPTION();
523 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700524 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c.Ptr());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200525 inst = inst->Next_2xx();
526 }
527 break;
528 }
529 case Instruction::MONITOR_ENTER: {
530 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700531 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700532 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000533 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200534 HANDLE_PENDING_EXCEPTION();
535 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700536 DoMonitorEnter<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200537 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
538 }
539 break;
540 }
541 case Instruction::MONITOR_EXIT: {
542 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700543 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700544 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000545 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200546 HANDLE_PENDING_EXCEPTION();
547 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700548 DoMonitorExit<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200549 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
550 }
551 break;
552 }
553 case Instruction::CHECK_CAST: {
554 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800555 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700556 shadow_frame.GetMethod(),
557 self,
558 false,
559 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700560 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200561 HANDLE_PENDING_EXCEPTION();
562 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700563 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700564 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200565 ThrowClassCastException(c, obj->GetClass());
566 HANDLE_PENDING_EXCEPTION();
567 } else {
568 inst = inst->Next_2xx();
569 }
570 }
571 break;
572 }
573 case Instruction::INSTANCE_OF: {
574 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800575 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegC_22c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700576 shadow_frame.GetMethod(),
577 self,
578 false,
579 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700580 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200581 HANDLE_PENDING_EXCEPTION();
582 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700583 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700584 shadow_frame.SetVReg(inst->VRegA_22c(inst_data),
585 (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200586 inst = inst->Next_2xx();
587 }
588 break;
589 }
590 case Instruction::ARRAY_LENGTH: {
591 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700592 ObjPtr<mirror::Object> array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700593 if (UNLIKELY(array == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000594 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200595 HANDLE_PENDING_EXCEPTION();
596 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200597 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200598 inst = inst->Next_1xx();
599 }
600 break;
601 }
602 case Instruction::NEW_INSTANCE: {
603 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700604 ObjPtr<mirror::Object> obj = nullptr;
Andreas Gampea5b09a62016-11-17 15:21:22 -0800605 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700606 shadow_frame.GetMethod(),
607 self,
608 false,
609 do_access_check);
Jeff Hao848f70a2014-01-15 13:49:50 -0800610 if (LIKELY(c != nullptr)) {
611 if (UNLIKELY(c->IsStringClass())) {
612 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
jessicahandojo3aaa37b2016-07-29 14:46:37 -0700613 obj = mirror::String::AllocEmptyString<true>(self, allocator_type);
Jeff Hao848f70a2014-01-15 13:49:50 -0800614 } else {
Nicolas Geoffray0d3998b2017-01-12 15:35:12 +0000615 obj = AllocObjectFromCode<true>(
616 c.Ptr(),
Andreas Gampea5b09a62016-11-17 15:21:22 -0800617 self,
618 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Jeff Hao848f70a2014-01-15 13:49:50 -0800619 }
620 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700621 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200622 HANDLE_PENDING_EXCEPTION();
623 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200624 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700625 // Don't allow finalizable objects to be allocated during a transaction since these can't
626 // be finalized without a started runtime.
627 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200628 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
David Sehr709b0702016-10-13 09:12:37 -0700629 obj->PrettyTypeOf().c_str());
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700630 HANDLE_PENDING_EXCEPTION();
631 break;
632 }
Mathieu Chartieref41db72016-10-25 15:08:01 -0700633 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj.Ptr());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200634 inst = inst->Next_2xx();
635 }
636 break;
637 }
638 case Instruction::NEW_ARRAY: {
639 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200640 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartieref41db72016-10-25 15:08:01 -0700641 ObjPtr<mirror::Object> obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampea5b09a62016-11-17 15:21:22 -0800642 dex::TypeIndex(inst->VRegC_22c()),
643 length,
644 shadow_frame.GetMethod(),
645 self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800646 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700647 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200648 HANDLE_PENDING_EXCEPTION();
649 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700650 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj.Ptr());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200651 inst = inst->Next_2xx();
652 }
653 break;
654 }
655 case Instruction::FILLED_NEW_ARRAY: {
656 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100657 bool success =
658 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame, self,
659 &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200660 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
661 break;
662 }
663 case Instruction::FILLED_NEW_ARRAY_RANGE: {
664 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100665 bool success =
666 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
667 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200668 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
669 break;
670 }
671 case Instruction::FILL_ARRAY_DATA: {
672 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200673 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
674 const Instruction::ArrayDataPayload* payload =
675 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
Mathieu Chartieref41db72016-10-25 15:08:01 -0700676 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
Ian Rogers832336b2014-10-08 15:35:22 -0700677 bool success = FillArrayData(obj, payload);
678 if (!success) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200679 HANDLE_PENDING_EXCEPTION();
680 break;
681 }
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100682 if (transaction_active) {
Ian Rogers832336b2014-10-08 15:35:22 -0700683 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100684 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200685 inst = inst->Next_3xx();
686 break;
687 }
688 case Instruction::THROW: {
689 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700690 ObjPtr<mirror::Object> exception =
691 shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700692 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000693 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700694 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
695 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700696 std::string temp;
Orion Hodsonfef06642016-11-25 16:07:11 +0000697 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700698 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700699 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200700 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000701 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200702 }
703 HANDLE_PENDING_EXCEPTION();
704 break;
705 }
706 case Instruction::GOTO: {
707 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200708 int8_t offset = inst->VRegA_10t(inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000709 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200710 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800711 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200712 break;
713 }
714 case Instruction::GOTO_16: {
715 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200716 int16_t offset = inst->VRegA_20t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000717 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200718 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800719 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200720 break;
721 }
722 case Instruction::GOTO_32: {
723 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200724 int32_t offset = inst->VRegA_30t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000725 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200726 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800727 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200728 break;
729 }
730 case Instruction::PACKED_SWITCH: {
731 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200732 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000733 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200734 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800735 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200736 break;
737 }
738 case Instruction::SPARSE_SWITCH: {
739 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200740 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000741 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200742 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800743 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200744 break;
745 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700746
Ian Rogers647b1a82014-10-10 11:02:11 -0700747#pragma clang diagnostic push
748#pragma clang diagnostic ignored "-Wfloat-equal"
Ian Rogers647b1a82014-10-10 11:02:11 -0700749
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200750 case Instruction::CMPL_FLOAT: {
751 PREAMBLE();
752 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
753 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
754 int32_t result;
755 if (val1 > val2) {
756 result = 1;
757 } else if (val1 == val2) {
758 result = 0;
759 } else {
760 result = -1;
761 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200762 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200763 inst = inst->Next_2xx();
764 break;
765 }
766 case Instruction::CMPG_FLOAT: {
767 PREAMBLE();
768 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
769 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
770 int32_t result;
771 if (val1 < val2) {
772 result = -1;
773 } else if (val1 == val2) {
774 result = 0;
775 } else {
776 result = 1;
777 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200778 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200779 inst = inst->Next_2xx();
780 break;
781 }
782 case Instruction::CMPL_DOUBLE: {
783 PREAMBLE();
784 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
785 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
786 int32_t result;
787 if (val1 > val2) {
788 result = 1;
789 } else if (val1 == val2) {
790 result = 0;
791 } else {
792 result = -1;
793 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200794 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200795 inst = inst->Next_2xx();
796 break;
797 }
798
799 case Instruction::CMPG_DOUBLE: {
800 PREAMBLE();
801 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
802 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
803 int32_t result;
804 if (val1 < val2) {
805 result = -1;
806 } else if (val1 == val2) {
807 result = 0;
808 } else {
809 result = 1;
810 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200811 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200812 inst = inst->Next_2xx();
813 break;
814 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700815
Ian Rogers647b1a82014-10-10 11:02:11 -0700816#pragma clang diagnostic pop
Ian Rogers647b1a82014-10-10 11:02:11 -0700817
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200818 case Instruction::CMP_LONG: {
819 PREAMBLE();
820 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
821 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
822 int32_t result;
823 if (val1 > val2) {
824 result = 1;
825 } else if (val1 == val2) {
826 result = 0;
827 } else {
828 result = -1;
829 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200830 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200831 inst = inst->Next_2xx();
832 break;
833 }
834 case Instruction::IF_EQ: {
835 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700836 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) ==
837 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200838 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000839 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200840 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800841 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200842 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800843 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200844 inst = inst->Next_2xx();
845 }
846 break;
847 }
848 case Instruction::IF_NE: {
849 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700850 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
851 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200852 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000853 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200854 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800855 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200856 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800857 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200858 inst = inst->Next_2xx();
859 }
860 break;
861 }
862 case Instruction::IF_LT: {
863 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700864 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
865 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200866 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000867 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200868 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800869 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200870 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800871 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200872 inst = inst->Next_2xx();
873 }
874 break;
875 }
876 case Instruction::IF_GE: {
877 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700878 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
879 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200880 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000881 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200882 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800883 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200884 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800885 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200886 inst = inst->Next_2xx();
887 }
888 break;
889 }
890 case Instruction::IF_GT: {
891 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700892 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
893 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200894 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000895 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200896 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800897 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200898 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800899 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200900 inst = inst->Next_2xx();
901 }
902 break;
903 }
904 case Instruction::IF_LE: {
905 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700906 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
907 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200908 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000909 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200910 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800911 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200912 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800913 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200914 inst = inst->Next_2xx();
915 }
916 break;
917 }
918 case Instruction::IF_EQZ: {
919 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200920 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200921 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000922 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200923 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800924 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200925 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800926 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200927 inst = inst->Next_2xx();
928 }
929 break;
930 }
931 case Instruction::IF_NEZ: {
932 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200933 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200934 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000935 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200936 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800937 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200938 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800939 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200940 inst = inst->Next_2xx();
941 }
942 break;
943 }
944 case Instruction::IF_LTZ: {
945 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200946 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200947 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000948 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200949 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800950 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200951 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800952 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200953 inst = inst->Next_2xx();
954 }
955 break;
956 }
957 case Instruction::IF_GEZ: {
958 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200959 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200960 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000961 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200962 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800963 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200964 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800965 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200966 inst = inst->Next_2xx();
967 }
968 break;
969 }
970 case Instruction::IF_GTZ: {
971 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200972 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200973 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000974 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200975 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800976 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200977 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800978 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200979 inst = inst->Next_2xx();
980 }
981 break;
982 }
983 case Instruction::IF_LEZ: {
984 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200985 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200986 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000987 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200988 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800989 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200990 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800991 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200992 inst = inst->Next_2xx();
993 }
994 break;
995 }
996 case Instruction::AGET_BOOLEAN: {
997 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700998 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700999 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001000 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001001 HANDLE_PENDING_EXCEPTION();
1002 break;
1003 }
1004 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001005 ObjPtr<mirror::BooleanArray> array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001006 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001007 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001008 inst = inst->Next_2xx();
1009 } else {
1010 HANDLE_PENDING_EXCEPTION();
1011 }
1012 break;
1013 }
1014 case Instruction::AGET_BYTE: {
1015 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001016 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001017 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001018 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001019 HANDLE_PENDING_EXCEPTION();
1020 break;
1021 }
1022 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001023 ObjPtr<mirror::ByteArray> array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001024 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001025 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001026 inst = inst->Next_2xx();
1027 } else {
1028 HANDLE_PENDING_EXCEPTION();
1029 }
1030 break;
1031 }
1032 case Instruction::AGET_CHAR: {
1033 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001034 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001035 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001036 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001037 HANDLE_PENDING_EXCEPTION();
1038 break;
1039 }
1040 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001041 ObjPtr<mirror::CharArray> array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001042 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001043 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001044 inst = inst->Next_2xx();
1045 } else {
1046 HANDLE_PENDING_EXCEPTION();
1047 }
1048 break;
1049 }
1050 case Instruction::AGET_SHORT: {
1051 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001052 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001053 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001054 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001055 HANDLE_PENDING_EXCEPTION();
1056 break;
1057 }
1058 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001059 ObjPtr<mirror::ShortArray> array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001060 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001061 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001062 inst = inst->Next_2xx();
1063 } else {
1064 HANDLE_PENDING_EXCEPTION();
1065 }
1066 break;
1067 }
1068 case Instruction::AGET: {
1069 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001070 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001071 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001072 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001073 HANDLE_PENDING_EXCEPTION();
1074 break;
1075 }
1076 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001077 DCHECK(a->IsIntArray() || a->IsFloatArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001078 ObjPtr<mirror::IntArray> array = ObjPtr<mirror::IntArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001079 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001080 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001081 inst = inst->Next_2xx();
1082 } else {
1083 HANDLE_PENDING_EXCEPTION();
1084 }
1085 break;
1086 }
1087 case Instruction::AGET_WIDE: {
1088 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001089 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001090 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001091 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001092 HANDLE_PENDING_EXCEPTION();
1093 break;
1094 }
1095 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001096 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001097 ObjPtr<mirror::LongArray> array = ObjPtr<mirror::LongArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001098 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001099 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001100 inst = inst->Next_2xx();
1101 } else {
1102 HANDLE_PENDING_EXCEPTION();
1103 }
1104 break;
1105 }
1106 case Instruction::AGET_OBJECT: {
1107 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001108 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001109 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001110 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001111 HANDLE_PENDING_EXCEPTION();
1112 break;
1113 }
1114 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001115 ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001116 if (array->CheckIsValidIndex(index)) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001117 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001118 inst = inst->Next_2xx();
1119 } else {
1120 HANDLE_PENDING_EXCEPTION();
1121 }
1122 break;
1123 }
1124 case Instruction::APUT_BOOLEAN: {
1125 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001126 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001127 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001128 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001129 HANDLE_PENDING_EXCEPTION();
1130 break;
1131 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001132 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001133 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001134 ObjPtr<mirror::BooleanArray> array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001135 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001136 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001137 inst = inst->Next_2xx();
1138 } else {
1139 HANDLE_PENDING_EXCEPTION();
1140 }
1141 break;
1142 }
1143 case Instruction::APUT_BYTE: {
1144 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001145 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001146 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001147 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001148 HANDLE_PENDING_EXCEPTION();
1149 break;
1150 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001151 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001152 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001153 ObjPtr<mirror::ByteArray> array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001154 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001155 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001156 inst = inst->Next_2xx();
1157 } else {
1158 HANDLE_PENDING_EXCEPTION();
1159 }
1160 break;
1161 }
1162 case Instruction::APUT_CHAR: {
1163 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001164 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001165 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001166 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001167 HANDLE_PENDING_EXCEPTION();
1168 break;
1169 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001170 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001171 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001172 ObjPtr<mirror::CharArray> array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001173 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001174 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001175 inst = inst->Next_2xx();
1176 } else {
1177 HANDLE_PENDING_EXCEPTION();
1178 }
1179 break;
1180 }
1181 case Instruction::APUT_SHORT: {
1182 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001183 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001184 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001185 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001186 HANDLE_PENDING_EXCEPTION();
1187 break;
1188 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001189 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001190 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001191 ObjPtr<mirror::ShortArray> array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001192 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001193 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001194 inst = inst->Next_2xx();
1195 } else {
1196 HANDLE_PENDING_EXCEPTION();
1197 }
1198 break;
1199 }
1200 case Instruction::APUT: {
1201 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001202 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001203 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001204 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001205 HANDLE_PENDING_EXCEPTION();
1206 break;
1207 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001208 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001209 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001210 DCHECK(a->IsIntArray() || a->IsFloatArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001211 ObjPtr<mirror::IntArray> array = ObjPtr<mirror::IntArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001212 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001213 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001214 inst = inst->Next_2xx();
1215 } else {
1216 HANDLE_PENDING_EXCEPTION();
1217 }
1218 break;
1219 }
1220 case Instruction::APUT_WIDE: {
1221 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001222 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001223 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001224 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001225 HANDLE_PENDING_EXCEPTION();
1226 break;
1227 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001228 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001229 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001230 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001231 ObjPtr<mirror::LongArray> array = ObjPtr<mirror::LongArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001232 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001233 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001234 inst = inst->Next_2xx();
1235 } else {
1236 HANDLE_PENDING_EXCEPTION();
1237 }
1238 break;
1239 }
1240 case Instruction::APUT_OBJECT: {
1241 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001242 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001243 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001244 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001245 HANDLE_PENDING_EXCEPTION();
1246 break;
1247 }
1248 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001249 ObjPtr<mirror::Object> val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
1250 ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001251 if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001252 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001253 inst = inst->Next_2xx();
1254 } else {
1255 HANDLE_PENDING_EXCEPTION();
1256 }
1257 break;
1258 }
1259 case Instruction::IGET_BOOLEAN: {
1260 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001261 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1262 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001263 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1264 break;
1265 }
1266 case Instruction::IGET_BYTE: {
1267 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001268 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1269 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001270 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1271 break;
1272 }
1273 case Instruction::IGET_CHAR: {
1274 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001275 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1276 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001277 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1278 break;
1279 }
1280 case Instruction::IGET_SHORT: {
1281 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001282 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1283 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001284 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1285 break;
1286 }
1287 case Instruction::IGET: {
1288 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001289 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1290 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001291 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1292 break;
1293 }
1294 case Instruction::IGET_WIDE: {
1295 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001296 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1297 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001298 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1299 break;
1300 }
1301 case Instruction::IGET_OBJECT: {
1302 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001303 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1304 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001305 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1306 break;
1307 }
1308 case Instruction::IGET_QUICK: {
1309 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001310 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001311 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1312 break;
1313 }
1314 case Instruction::IGET_WIDE_QUICK: {
1315 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001316 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001317 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1318 break;
1319 }
1320 case Instruction::IGET_OBJECT_QUICK: {
1321 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001322 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001323 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1324 break;
1325 }
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001326 case Instruction::IGET_BOOLEAN_QUICK: {
1327 PREAMBLE();
1328 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1329 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1330 break;
1331 }
1332 case Instruction::IGET_BYTE_QUICK: {
1333 PREAMBLE();
1334 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1335 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1336 break;
1337 }
1338 case Instruction::IGET_CHAR_QUICK: {
1339 PREAMBLE();
1340 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1341 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1342 break;
1343 }
1344 case Instruction::IGET_SHORT_QUICK: {
1345 PREAMBLE();
1346 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1347 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1348 break;
1349 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001350 case Instruction::SGET_BOOLEAN: {
1351 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001352 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check,
1353 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001354 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1355 break;
1356 }
1357 case Instruction::SGET_BYTE: {
1358 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001359 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check,
1360 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001361 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1362 break;
1363 }
1364 case Instruction::SGET_CHAR: {
1365 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001366 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check,
1367 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001368 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1369 break;
1370 }
1371 case Instruction::SGET_SHORT: {
1372 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001373 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check,
1374 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001375 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1376 break;
1377 }
1378 case Instruction::SGET: {
1379 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001380 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check,
1381 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001382 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1383 break;
1384 }
1385 case Instruction::SGET_WIDE: {
1386 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001387 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check,
1388 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001389 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1390 break;
1391 }
1392 case Instruction::SGET_OBJECT: {
1393 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001394 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check,
1395 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001396 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1397 break;
1398 }
1399 case Instruction::IPUT_BOOLEAN: {
1400 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001401 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1402 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001403 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1404 break;
1405 }
1406 case Instruction::IPUT_BYTE: {
1407 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001408 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1409 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001410 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1411 break;
1412 }
1413 case Instruction::IPUT_CHAR: {
1414 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001415 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1416 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001417 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1418 break;
1419 }
1420 case Instruction::IPUT_SHORT: {
1421 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001422 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1423 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001424 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1425 break;
1426 }
1427 case Instruction::IPUT: {
1428 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001429 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1430 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001431 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1432 break;
1433 }
1434 case Instruction::IPUT_WIDE: {
1435 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001436 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1437 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001438 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1439 break;
1440 }
1441 case Instruction::IPUT_OBJECT: {
1442 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001443 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1444 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001445 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1446 break;
1447 }
1448 case Instruction::IPUT_QUICK: {
1449 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001450 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1451 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001452 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1453 break;
1454 }
Fred Shih37f05ef2014-07-16 18:38:08 -07001455 case Instruction::IPUT_BOOLEAN_QUICK: {
1456 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001457 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1458 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001459 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1460 break;
1461 }
1462 case Instruction::IPUT_BYTE_QUICK: {
1463 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001464 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1465 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001466 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1467 break;
1468 }
1469 case Instruction::IPUT_CHAR_QUICK: {
1470 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001471 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1472 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001473 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1474 break;
1475 }
1476 case Instruction::IPUT_SHORT_QUICK: {
1477 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001478 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1479 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001480 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1481 break;
1482 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001483 case Instruction::IPUT_WIDE_QUICK: {
1484 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001485 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1486 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001487 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1488 break;
1489 }
1490 case Instruction::IPUT_OBJECT_QUICK: {
1491 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001492 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1493 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001494 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1495 break;
1496 }
1497 case Instruction::SPUT_BOOLEAN: {
1498 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001499 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1500 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001501 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1502 break;
1503 }
1504 case Instruction::SPUT_BYTE: {
1505 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001506 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1507 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001508 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1509 break;
1510 }
1511 case Instruction::SPUT_CHAR: {
1512 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001513 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1514 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001515 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1516 break;
1517 }
1518 case Instruction::SPUT_SHORT: {
1519 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001520 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1521 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001522 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1523 break;
1524 }
1525 case Instruction::SPUT: {
1526 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001527 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1528 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001529 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1530 break;
1531 }
1532 case Instruction::SPUT_WIDE: {
1533 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001534 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1535 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001536 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1537 break;
1538 }
1539 case Instruction::SPUT_OBJECT: {
1540 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001541 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1542 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001543 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1544 break;
1545 }
1546 case Instruction::INVOKE_VIRTUAL: {
1547 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001548 bool success = DoInvoke<kVirtual, false, do_access_check>(
1549 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001550 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1551 break;
1552 }
1553 case Instruction::INVOKE_VIRTUAL_RANGE: {
1554 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001555 bool success = DoInvoke<kVirtual, true, do_access_check>(
1556 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001557 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1558 break;
1559 }
1560 case Instruction::INVOKE_SUPER: {
1561 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001562 bool success = DoInvoke<kSuper, false, do_access_check>(
1563 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001564 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1565 break;
1566 }
1567 case Instruction::INVOKE_SUPER_RANGE: {
1568 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001569 bool success = DoInvoke<kSuper, true, do_access_check>(
1570 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001571 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1572 break;
1573 }
1574 case Instruction::INVOKE_DIRECT: {
1575 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001576 bool success = DoInvoke<kDirect, false, do_access_check>(
1577 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001578 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1579 break;
1580 }
1581 case Instruction::INVOKE_DIRECT_RANGE: {
1582 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001583 bool success = DoInvoke<kDirect, true, do_access_check>(
1584 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001585 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1586 break;
1587 }
1588 case Instruction::INVOKE_INTERFACE: {
1589 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001590 bool success = DoInvoke<kInterface, false, do_access_check>(
1591 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001592 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1593 break;
1594 }
1595 case Instruction::INVOKE_INTERFACE_RANGE: {
1596 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001597 bool success = DoInvoke<kInterface, true, do_access_check>(
1598 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001599 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1600 break;
1601 }
1602 case Instruction::INVOKE_STATIC: {
1603 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001604 bool success = DoInvoke<kStatic, false, do_access_check>(
1605 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001606 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1607 break;
1608 }
1609 case Instruction::INVOKE_STATIC_RANGE: {
1610 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001611 bool success = DoInvoke<kStatic, true, do_access_check>(
1612 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001613 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1614 break;
1615 }
1616 case Instruction::INVOKE_VIRTUAL_QUICK: {
1617 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001618 bool success = DoInvokeVirtualQuick<false>(
1619 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001620 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1621 break;
1622 }
1623 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
1624 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001625 bool success = DoInvokeVirtualQuick<true>(
1626 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001627 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1628 break;
1629 }
Narayan Kamath9823e782016-08-03 12:46:58 +01001630 case Instruction::INVOKE_POLYMORPHIC: {
1631 PREAMBLE();
Narayan Kamath269cb432016-10-28 10:19:54 +01001632 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
Orion Hodsonc069a302017-01-18 09:23:12 +00001633 bool success = DoInvokePolymorphic<false /* is_range */>(
Narayan Kamath9823e782016-08-03 12:46:58 +01001634 self, shadow_frame, inst, inst_data, &result_register);
1635 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_4xx);
1636 break;
1637 }
1638 case Instruction::INVOKE_POLYMORPHIC_RANGE: {
1639 PREAMBLE();
Narayan Kamath269cb432016-10-28 10:19:54 +01001640 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
Orion Hodsonc069a302017-01-18 09:23:12 +00001641 bool success = DoInvokePolymorphic<true /* is_range */>(
Narayan Kamath9823e782016-08-03 12:46:58 +01001642 self, shadow_frame, inst, inst_data, &result_register);
1643 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_4xx);
1644 break;
Narayan Kamath9823e782016-08-03 12:46:58 +01001645 }
Orion Hodsonc069a302017-01-18 09:23:12 +00001646 case Instruction::INVOKE_CUSTOM: {
1647 PREAMBLE();
1648 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1649 bool success = DoInvokeCustom<false /* is_range */>(
1650 self, shadow_frame, inst, inst_data, &result_register);
1651 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1652 break;
1653 }
1654 case Instruction::INVOKE_CUSTOM_RANGE: {
1655 PREAMBLE();
1656 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1657 bool success = DoInvokeCustom<true /* is_range */>(
1658 self, shadow_frame, inst, inst_data, &result_register);
1659 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1660 break;
1661 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001662 case Instruction::NEG_INT:
1663 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001664 shadow_frame.SetVReg(
1665 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001666 inst = inst->Next_1xx();
1667 break;
1668 case Instruction::NOT_INT:
1669 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001670 shadow_frame.SetVReg(
1671 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001672 inst = inst->Next_1xx();
1673 break;
1674 case Instruction::NEG_LONG:
1675 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001676 shadow_frame.SetVRegLong(
1677 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001678 inst = inst->Next_1xx();
1679 break;
1680 case Instruction::NOT_LONG:
1681 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001682 shadow_frame.SetVRegLong(
1683 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001684 inst = inst->Next_1xx();
1685 break;
1686 case Instruction::NEG_FLOAT:
1687 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001688 shadow_frame.SetVRegFloat(
1689 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001690 inst = inst->Next_1xx();
1691 break;
1692 case Instruction::NEG_DOUBLE:
1693 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001694 shadow_frame.SetVRegDouble(
1695 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001696 inst = inst->Next_1xx();
1697 break;
1698 case Instruction::INT_TO_LONG:
1699 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001700 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
1701 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001702 inst = inst->Next_1xx();
1703 break;
1704 case Instruction::INT_TO_FLOAT:
1705 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001706 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1707 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001708 inst = inst->Next_1xx();
1709 break;
1710 case Instruction::INT_TO_DOUBLE:
1711 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001712 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1713 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001714 inst = inst->Next_1xx();
1715 break;
1716 case Instruction::LONG_TO_INT:
1717 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001718 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1719 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001720 inst = inst->Next_1xx();
1721 break;
1722 case Instruction::LONG_TO_FLOAT:
1723 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001724 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1725 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001726 inst = inst->Next_1xx();
1727 break;
1728 case Instruction::LONG_TO_DOUBLE:
1729 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001730 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1731 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001732 inst = inst->Next_1xx();
1733 break;
1734 case Instruction::FLOAT_TO_INT: {
1735 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001736 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001737 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001738 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001739 inst = inst->Next_1xx();
1740 break;
1741 }
1742 case Instruction::FLOAT_TO_LONG: {
1743 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001744 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001745 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001746 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001747 inst = inst->Next_1xx();
1748 break;
1749 }
1750 case Instruction::FLOAT_TO_DOUBLE:
1751 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001752 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1753 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001754 inst = inst->Next_1xx();
1755 break;
1756 case Instruction::DOUBLE_TO_INT: {
1757 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001758 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001759 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001760 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001761 inst = inst->Next_1xx();
1762 break;
1763 }
1764 case Instruction::DOUBLE_TO_LONG: {
1765 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001766 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001767 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001768 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001769 inst = inst->Next_1xx();
1770 break;
1771 }
1772 case Instruction::DOUBLE_TO_FLOAT:
1773 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001774 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1775 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001776 inst = inst->Next_1xx();
1777 break;
1778 case Instruction::INT_TO_BYTE:
1779 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001780 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int8_t>(
1781 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001782 inst = inst->Next_1xx();
1783 break;
1784 case Instruction::INT_TO_CHAR:
1785 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001786 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<uint16_t>(
1787 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001788 inst = inst->Next_1xx();
1789 break;
1790 case Instruction::INT_TO_SHORT:
1791 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001792 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int16_t>(
1793 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001794 inst = inst->Next_1xx();
1795 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001796 case Instruction::ADD_INT: {
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001797 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001798 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001799 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1800 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001801 inst = inst->Next_2xx();
1802 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001803 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001804 case Instruction::SUB_INT:
1805 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001806 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001807 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1808 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001809 inst = inst->Next_2xx();
1810 break;
1811 case Instruction::MUL_INT:
1812 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001813 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001814 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1815 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001816 inst = inst->Next_2xx();
1817 break;
1818 case Instruction::DIV_INT: {
1819 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001820 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001821 shadow_frame.GetVReg(inst->VRegB_23x()),
1822 shadow_frame.GetVReg(inst->VRegC_23x()));
1823 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1824 break;
1825 }
1826 case Instruction::REM_INT: {
1827 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001828 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001829 shadow_frame.GetVReg(inst->VRegB_23x()),
1830 shadow_frame.GetVReg(inst->VRegC_23x()));
1831 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1832 break;
1833 }
1834 case Instruction::SHL_INT:
1835 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001836 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001837 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1838 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1839 inst = inst->Next_2xx();
1840 break;
1841 case Instruction::SHR_INT:
1842 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001843 shadow_frame.SetVReg(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()) & 0x1f));
1846 inst = inst->Next_2xx();
1847 break;
1848 case Instruction::USHR_INT:
1849 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001850 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001851 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1852 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1853 inst = inst->Next_2xx();
1854 break;
1855 case Instruction::AND_INT:
1856 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001857 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001858 shadow_frame.GetVReg(inst->VRegB_23x()) &
1859 shadow_frame.GetVReg(inst->VRegC_23x()));
1860 inst = inst->Next_2xx();
1861 break;
1862 case Instruction::OR_INT:
1863 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001864 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001865 shadow_frame.GetVReg(inst->VRegB_23x()) |
1866 shadow_frame.GetVReg(inst->VRegC_23x()));
1867 inst = inst->Next_2xx();
1868 break;
1869 case Instruction::XOR_INT:
1870 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001871 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001872 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1873 shadow_frame.GetVReg(inst->VRegC_23x()));
1874 inst = inst->Next_2xx();
1875 break;
1876 case Instruction::ADD_LONG:
1877 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001878 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001879 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1880 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001881 inst = inst->Next_2xx();
1882 break;
1883 case Instruction::SUB_LONG:
1884 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001885 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001886 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1887 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001888 inst = inst->Next_2xx();
1889 break;
1890 case Instruction::MUL_LONG:
1891 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001892 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001893 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1894 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001895 inst = inst->Next_2xx();
1896 break;
1897 case Instruction::DIV_LONG:
1898 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001899 DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001900 shadow_frame.GetVRegLong(inst->VRegB_23x()),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001901 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001902 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1903 break;
1904 case Instruction::REM_LONG:
1905 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001906 DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001907 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1908 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1909 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1910 break;
1911 case Instruction::AND_LONG:
1912 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001913 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001914 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1915 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1916 inst = inst->Next_2xx();
1917 break;
1918 case Instruction::OR_LONG:
1919 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001920 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001921 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1922 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1923 inst = inst->Next_2xx();
1924 break;
1925 case Instruction::XOR_LONG:
1926 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001927 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001928 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1929 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1930 inst = inst->Next_2xx();
1931 break;
1932 case Instruction::SHL_LONG:
1933 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001934 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001935 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1936 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1937 inst = inst->Next_2xx();
1938 break;
1939 case Instruction::SHR_LONG:
1940 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001941 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001942 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1943 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1944 inst = inst->Next_2xx();
1945 break;
1946 case Instruction::USHR_LONG:
1947 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001948 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001949 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1950 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1951 inst = inst->Next_2xx();
1952 break;
1953 case Instruction::ADD_FLOAT:
1954 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001955 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001956 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1957 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1958 inst = inst->Next_2xx();
1959 break;
1960 case Instruction::SUB_FLOAT:
1961 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001962 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001963 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1964 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1965 inst = inst->Next_2xx();
1966 break;
1967 case Instruction::MUL_FLOAT:
1968 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001969 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001970 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1971 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1972 inst = inst->Next_2xx();
1973 break;
1974 case Instruction::DIV_FLOAT:
1975 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001976 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001977 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1978 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1979 inst = inst->Next_2xx();
1980 break;
1981 case Instruction::REM_FLOAT:
1982 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001983 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001984 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1985 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1986 inst = inst->Next_2xx();
1987 break;
1988 case Instruction::ADD_DOUBLE:
1989 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001990 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001991 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1992 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1993 inst = inst->Next_2xx();
1994 break;
1995 case Instruction::SUB_DOUBLE:
1996 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001997 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001998 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1999 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2000 inst = inst->Next_2xx();
2001 break;
2002 case Instruction::MUL_DOUBLE:
2003 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002004 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002005 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
2006 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2007 inst = inst->Next_2xx();
2008 break;
2009 case Instruction::DIV_DOUBLE:
2010 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002011 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002012 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
2013 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2014 inst = inst->Next_2xx();
2015 break;
2016 case Instruction::REM_DOUBLE:
2017 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002018 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002019 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
2020 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
2021 inst = inst->Next_2xx();
2022 break;
2023 case Instruction::ADD_INT_2ADDR: {
2024 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002025 uint4_t vregA = inst->VRegA_12x(inst_data);
Ian Rogersf72a11d2014-10-30 15:41:08 -07002026 shadow_frame.SetVReg(vregA, SafeAdd(shadow_frame.GetVReg(vregA),
2027 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002028 inst = inst->Next_1xx();
2029 break;
2030 }
2031 case Instruction::SUB_INT_2ADDR: {
2032 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002033 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002034 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002035 SafeSub(shadow_frame.GetVReg(vregA),
2036 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002037 inst = inst->Next_1xx();
2038 break;
2039 }
2040 case Instruction::MUL_INT_2ADDR: {
2041 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002042 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002043 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002044 SafeMul(shadow_frame.GetVReg(vregA),
2045 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002046 inst = inst->Next_1xx();
2047 break;
2048 }
2049 case Instruction::DIV_INT_2ADDR: {
2050 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002051 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002052 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002053 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002054 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
2055 break;
2056 }
2057 case Instruction::REM_INT_2ADDR: {
2058 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002059 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002060 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002061 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002062 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
2063 break;
2064 }
2065 case Instruction::SHL_INT_2ADDR: {
2066 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002067 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002068 shadow_frame.SetVReg(vregA,
2069 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002070 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002071 inst = inst->Next_1xx();
2072 break;
2073 }
2074 case Instruction::SHR_INT_2ADDR: {
2075 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002076 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002077 shadow_frame.SetVReg(vregA,
2078 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002079 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002080 inst = inst->Next_1xx();
2081 break;
2082 }
2083 case Instruction::USHR_INT_2ADDR: {
2084 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002085 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002086 shadow_frame.SetVReg(vregA,
2087 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002088 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002089 inst = inst->Next_1xx();
2090 break;
2091 }
2092 case Instruction::AND_INT_2ADDR: {
2093 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002094 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002095 shadow_frame.SetVReg(vregA,
2096 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002097 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002098 inst = inst->Next_1xx();
2099 break;
2100 }
2101 case Instruction::OR_INT_2ADDR: {
2102 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002103 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002104 shadow_frame.SetVReg(vregA,
2105 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002106 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002107 inst = inst->Next_1xx();
2108 break;
2109 }
2110 case Instruction::XOR_INT_2ADDR: {
2111 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002112 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002113 shadow_frame.SetVReg(vregA,
2114 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002115 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002116 inst = inst->Next_1xx();
2117 break;
2118 }
2119 case Instruction::ADD_LONG_2ADDR: {
2120 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002121 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002122 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002123 SafeAdd(shadow_frame.GetVRegLong(vregA),
2124 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002125 inst = inst->Next_1xx();
2126 break;
2127 }
2128 case Instruction::SUB_LONG_2ADDR: {
2129 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002130 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002131 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002132 SafeSub(shadow_frame.GetVRegLong(vregA),
2133 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002134 inst = inst->Next_1xx();
2135 break;
2136 }
2137 case Instruction::MUL_LONG_2ADDR: {
2138 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002139 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002140 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002141 SafeMul(shadow_frame.GetVRegLong(vregA),
2142 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002143 inst = inst->Next_1xx();
2144 break;
2145 }
2146 case Instruction::DIV_LONG_2ADDR: {
2147 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002148 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002149 DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002150 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002151 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
2152 break;
2153 }
2154 case Instruction::REM_LONG_2ADDR: {
2155 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002156 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002157 DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002158 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002159 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
2160 break;
2161 }
2162 case Instruction::AND_LONG_2ADDR: {
2163 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002164 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002165 shadow_frame.SetVRegLong(vregA,
2166 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002167 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002168 inst = inst->Next_1xx();
2169 break;
2170 }
2171 case Instruction::OR_LONG_2ADDR: {
2172 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002173 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002174 shadow_frame.SetVRegLong(vregA,
2175 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002176 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002177 inst = inst->Next_1xx();
2178 break;
2179 }
2180 case Instruction::XOR_LONG_2ADDR: {
2181 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002182 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002183 shadow_frame.SetVRegLong(vregA,
2184 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002185 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002186 inst = inst->Next_1xx();
2187 break;
2188 }
2189 case Instruction::SHL_LONG_2ADDR: {
2190 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002191 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002192 shadow_frame.SetVRegLong(vregA,
2193 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002194 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002195 inst = inst->Next_1xx();
2196 break;
2197 }
2198 case Instruction::SHR_LONG_2ADDR: {
2199 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002200 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002201 shadow_frame.SetVRegLong(vregA,
2202 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002203 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002204 inst = inst->Next_1xx();
2205 break;
2206 }
2207 case Instruction::USHR_LONG_2ADDR: {
2208 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002209 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002210 shadow_frame.SetVRegLong(vregA,
2211 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002212 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002213 inst = inst->Next_1xx();
2214 break;
2215 }
2216 case Instruction::ADD_FLOAT_2ADDR: {
2217 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002218 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002219 shadow_frame.SetVRegFloat(vregA,
2220 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002221 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002222 inst = inst->Next_1xx();
2223 break;
2224 }
2225 case Instruction::SUB_FLOAT_2ADDR: {
2226 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002227 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002228 shadow_frame.SetVRegFloat(vregA,
2229 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002230 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002231 inst = inst->Next_1xx();
2232 break;
2233 }
2234 case Instruction::MUL_FLOAT_2ADDR: {
2235 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002236 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002237 shadow_frame.SetVRegFloat(vregA,
2238 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002239 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002240 inst = inst->Next_1xx();
2241 break;
2242 }
2243 case Instruction::DIV_FLOAT_2ADDR: {
2244 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002245 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002246 shadow_frame.SetVRegFloat(vregA,
2247 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002248 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002249 inst = inst->Next_1xx();
2250 break;
2251 }
2252 case Instruction::REM_FLOAT_2ADDR: {
2253 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002254 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002255 shadow_frame.SetVRegFloat(vregA,
2256 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002257 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002258 inst = inst->Next_1xx();
2259 break;
2260 }
2261 case Instruction::ADD_DOUBLE_2ADDR: {
2262 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002263 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002264 shadow_frame.SetVRegDouble(vregA,
2265 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002266 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002267 inst = inst->Next_1xx();
2268 break;
2269 }
2270 case Instruction::SUB_DOUBLE_2ADDR: {
2271 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002272 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002273 shadow_frame.SetVRegDouble(vregA,
2274 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002275 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002276 inst = inst->Next_1xx();
2277 break;
2278 }
2279 case Instruction::MUL_DOUBLE_2ADDR: {
2280 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002281 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002282 shadow_frame.SetVRegDouble(vregA,
2283 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002284 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002285 inst = inst->Next_1xx();
2286 break;
2287 }
2288 case Instruction::DIV_DOUBLE_2ADDR: {
2289 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002290 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002291 shadow_frame.SetVRegDouble(vregA,
2292 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002293 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002294 inst = inst->Next_1xx();
2295 break;
2296 }
2297 case Instruction::REM_DOUBLE_2ADDR: {
2298 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002299 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002300 shadow_frame.SetVRegDouble(vregA,
2301 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002302 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002303 inst = inst->Next_1xx();
2304 break;
2305 }
2306 case Instruction::ADD_INT_LIT16:
2307 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002308 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002309 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2310 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002311 inst = inst->Next_2xx();
2312 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07002313 case Instruction::RSUB_INT_LIT16:
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002314 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002315 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002316 SafeSub(inst->VRegC_22s(),
2317 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002318 inst = inst->Next_2xx();
2319 break;
2320 case Instruction::MUL_INT_LIT16:
2321 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002322 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002323 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2324 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002325 inst = inst->Next_2xx();
2326 break;
2327 case Instruction::DIV_INT_LIT16: {
2328 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002329 bool success = DoIntDivide(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002330 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2331 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002332 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2333 break;
2334 }
2335 case Instruction::REM_INT_LIT16: {
2336 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002337 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002338 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2339 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002340 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2341 break;
2342 }
2343 case Instruction::AND_INT_LIT16:
2344 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002345 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2346 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002347 inst->VRegC_22s());
2348 inst = inst->Next_2xx();
2349 break;
2350 case Instruction::OR_INT_LIT16:
2351 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002352 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2353 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002354 inst->VRegC_22s());
2355 inst = inst->Next_2xx();
2356 break;
2357 case Instruction::XOR_INT_LIT16:
2358 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002359 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2360 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002361 inst->VRegC_22s());
2362 inst = inst->Next_2xx();
2363 break;
2364 case Instruction::ADD_INT_LIT8:
2365 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002366 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002367 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002368 inst = inst->Next_2xx();
2369 break;
2370 case Instruction::RSUB_INT_LIT8:
2371 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002372 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002373 SafeSub(inst->VRegC_22b(), shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002374 inst = inst->Next_2xx();
2375 break;
2376 case Instruction::MUL_INT_LIT8:
2377 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002378 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002379 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002380 inst = inst->Next_2xx();
2381 break;
2382 case Instruction::DIV_INT_LIT8: {
2383 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002384 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002385 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2386 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2387 break;
2388 }
2389 case Instruction::REM_INT_LIT8: {
2390 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002391 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002392 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2393 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2394 break;
2395 }
2396 case Instruction::AND_INT_LIT8:
2397 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002398 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002399 shadow_frame.GetVReg(inst->VRegB_22b()) &
2400 inst->VRegC_22b());
2401 inst = inst->Next_2xx();
2402 break;
2403 case Instruction::OR_INT_LIT8:
2404 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002405 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002406 shadow_frame.GetVReg(inst->VRegB_22b()) |
2407 inst->VRegC_22b());
2408 inst = inst->Next_2xx();
2409 break;
2410 case Instruction::XOR_INT_LIT8:
2411 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002412 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002413 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2414 inst->VRegC_22b());
2415 inst = inst->Next_2xx();
2416 break;
2417 case Instruction::SHL_INT_LIT8:
2418 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002419 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002420 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2421 (inst->VRegC_22b() & 0x1f));
2422 inst = inst->Next_2xx();
2423 break;
2424 case Instruction::SHR_INT_LIT8:
2425 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002426 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002427 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2428 (inst->VRegC_22b() & 0x1f));
2429 inst = inst->Next_2xx();
2430 break;
2431 case Instruction::USHR_INT_LIT8:
2432 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002433 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002434 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2435 (inst->VRegC_22b() & 0x1f));
2436 inst = inst->Next_2xx();
2437 break;
2438 case Instruction::UNUSED_3E ... Instruction::UNUSED_43:
Narayan Kamath8ec3bd22016-08-03 12:46:23 +01002439 case Instruction::UNUSED_F3 ... Instruction::UNUSED_F9:
Orion Hodsonc069a302017-01-18 09:23:12 +00002440 case Instruction::UNUSED_FE ... Instruction::UNUSED_FF:
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002441 case Instruction::UNUSED_79:
2442 case Instruction::UNUSED_7A:
Ian Rogerse94652f2014-12-02 11:13:19 -08002443 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002444 }
buzbee1452bee2015-03-06 14:43:04 -08002445 } while (!interpret_one_instruction);
2446 // Record where we stopped.
2447 shadow_frame.SetDexPC(inst->GetDexPc(insns));
buzbeed6b48db2016-01-28 15:48:55 -08002448 return result_register;
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002449} // NOLINT(readability/fn_size)
2450
2451// Explicit definitions of ExecuteSwitchImpl.
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002452template HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002453JValue ExecuteSwitchImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -08002454 ShadowFrame& shadow_frame, JValue result_register,
2455 bool interpret_one_instruction);
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002456template HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002457JValue ExecuteSwitchImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -08002458 ShadowFrame& shadow_frame, JValue result_register,
2459 bool interpret_one_instruction);
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002460template
Ian Rogerse94652f2014-12-02 11:13:19 -08002461JValue ExecuteSwitchImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -08002462 ShadowFrame& shadow_frame, JValue result_register,
2463 bool interpret_one_instruction);
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002464template
Ian Rogerse94652f2014-12-02 11:13:19 -08002465JValue ExecuteSwitchImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -08002466 ShadowFrame& shadow_frame, JValue result_register,
2467 bool interpret_one_instruction);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002468
2469} // namespace interpreter
2470} // namespace art