blob: 97c216dc07976fd2e7cf85ac2abdf6abdeec4b60 [file] [log] [blame]
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "interpreter_common.h"
18
19namespace art {
20namespace interpreter {
21
22#define HANDLE_PENDING_EXCEPTION() \
23 do { \
24 CHECK(self->IsExceptionPending()); \
Sebastien Hertz1eda2262013-09-09 16:53:14 +020025 if (UNLIKELY(self->TestAllFlags())) { \
26 CheckSuspend(self); \
27 } \
Sebastien Hertz947ff082013-09-17 14:10:13 +020028 Object* this_object = shadow_frame.GetThisObject(code_item->ins_size_); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020029 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, \
30 inst->GetDexPc(insns), \
Sebastien Hertz947ff082013-09-17 14:10:13 +020031 this_object, \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020032 instrumentation); \
33 if (found_dex_pc == DexFile::kDexNoIndex) { \
34 return JValue(); /* Handled in caller. */ \
35 } else { \
36 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc); \
37 inst = inst->RelativeAt(displacement); \
38 } \
39 } while (false)
40
41#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _next_function) \
42 do { \
43 if (UNLIKELY(_is_exception_pending)) { \
44 HANDLE_PENDING_EXCEPTION(); \
45 } else { \
46 inst = inst->_next_function(); \
47 } \
48 } while (false)
49
50// Code to run before each dex instruction.
Sebastien Hertz8379b222014-02-24 17:38:15 +010051#define PREAMBLE() \
52 do { \
53 DCHECK(!inst->IsReturn()); \
54 if (UNLIKELY(notified_method_entry_event)) { \
55 notified_method_entry_event = false; \
56 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
57 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), \
58 shadow_frame.GetMethod(), dex_pc); \
59 } \
60 } while (false)
Sebastien Hertz8ece0502013-08-07 11:26:41 +020061
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010062template<bool do_access_check, bool transaction_active>
Sebastien Hertzc6714852013-09-30 16:42:32 +020063JValue ExecuteSwitchImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item,
Sebastien Hertz8379b222014-02-24 17:38:15 +010064 ShadowFrame& shadow_frame, JValue result_register) {
Jeff Haoa3faaf42013-09-03 19:07:00 -070065 bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +020066 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
67 LOG(FATAL) << "Invalid shadow frame for interpreter use";
68 return JValue();
69 }
70 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +020071
72 uint32_t dex_pc = shadow_frame.GetDexPC();
Sebastien Hertz8379b222014-02-24 17:38:15 +010073 bool notified_method_entry_event = false;
Sebastien Hertz947ff082013-09-17 14:10:13 +020074 const instrumentation::Instrumentation* const instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +020075 if (LIKELY(dex_pc == 0)) { // We are entering the method as opposed to deoptimizing..
76 if (UNLIKELY(instrumentation->HasMethodEntryListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +020077 instrumentation->MethodEnterEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +020078 shadow_frame.GetMethod(), 0);
Sebastien Hertz8379b222014-02-24 17:38:15 +010079 notified_method_entry_event = true;
Sebastien Hertz8ece0502013-08-07 11:26:41 +020080 }
81 }
82 const uint16_t* const insns = code_item->insns_;
83 const Instruction* inst = Instruction::At(insns + dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +020084 uint16_t inst_data;
Sebastien Hertz8ece0502013-08-07 11:26:41 +020085 while (true) {
86 dex_pc = inst->GetDexPc(insns);
87 shadow_frame.SetDexPC(dex_pc);
Sebastien Hertz8ece0502013-08-07 11:26:41 +020088 TraceExecution(shadow_frame, inst, dex_pc, mh);
Sebastien Hertz3b588e02013-09-11 14:33:18 +020089 inst_data = inst->Fetch16(0);
90 switch (inst->Opcode(inst_data)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +020091 case Instruction::NOP:
92 PREAMBLE();
93 inst = inst->Next_1xx();
94 break;
95 case Instruction::MOVE:
96 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +020097 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
98 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +020099 inst = inst->Next_1xx();
100 break;
101 case Instruction::MOVE_FROM16:
102 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200103 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200104 shadow_frame.GetVReg(inst->VRegB_22x()));
105 inst = inst->Next_2xx();
106 break;
107 case Instruction::MOVE_16:
108 PREAMBLE();
109 shadow_frame.SetVReg(inst->VRegA_32x(),
110 shadow_frame.GetVReg(inst->VRegB_32x()));
111 inst = inst->Next_3xx();
112 break;
113 case Instruction::MOVE_WIDE:
114 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200115 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
116 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200117 inst = inst->Next_1xx();
118 break;
119 case Instruction::MOVE_WIDE_FROM16:
120 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200121 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200122 shadow_frame.GetVRegLong(inst->VRegB_22x()));
123 inst = inst->Next_2xx();
124 break;
125 case Instruction::MOVE_WIDE_16:
126 PREAMBLE();
127 shadow_frame.SetVRegLong(inst->VRegA_32x(),
128 shadow_frame.GetVRegLong(inst->VRegB_32x()));
129 inst = inst->Next_3xx();
130 break;
131 case Instruction::MOVE_OBJECT:
132 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200133 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
134 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200135 inst = inst->Next_1xx();
136 break;
137 case Instruction::MOVE_OBJECT_FROM16:
138 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200139 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200140 shadow_frame.GetVRegReference(inst->VRegB_22x()));
141 inst = inst->Next_2xx();
142 break;
143 case Instruction::MOVE_OBJECT_16:
144 PREAMBLE();
145 shadow_frame.SetVRegReference(inst->VRegA_32x(),
146 shadow_frame.GetVRegReference(inst->VRegB_32x()));
147 inst = inst->Next_3xx();
148 break;
149 case Instruction::MOVE_RESULT:
150 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200151 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200152 inst = inst->Next_1xx();
153 break;
154 case Instruction::MOVE_RESULT_WIDE:
155 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200156 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200157 inst = inst->Next_1xx();
158 break;
159 case Instruction::MOVE_RESULT_OBJECT:
160 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200161 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200162 inst = inst->Next_1xx();
163 break;
164 case Instruction::MOVE_EXCEPTION: {
165 PREAMBLE();
166 Throwable* exception = self->GetException(NULL);
167 self->ClearException();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200168 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200169 inst = inst->Next_1xx();
170 break;
171 }
172 case Instruction::RETURN_VOID: {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200173 JValue result;
Sebastien Hertz043036f2013-09-09 18:26:48 +0200174 if (do_access_check) {
175 // If access checks are required then the dex-to-dex compiler and analysis of
176 // whether the class has final fields hasn't been performed. Conservatively
177 // perform the memory barrier now.
Ian Rogersb122a4b2013-11-19 18:00:50 -0800178 QuasiAtomic::MembarStoreLoad();
Sebastien Hertz043036f2013-09-09 18:26:48 +0200179 }
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200180 if (UNLIKELY(self->TestAllFlags())) {
181 CheckSuspend(self);
182 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200183 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200184 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200185 shadow_frame.GetMethod(), inst->GetDexPc(insns),
186 result);
187 }
188 return result;
189 }
190 case Instruction::RETURN_VOID_BARRIER: {
Ian Rogersb122a4b2013-11-19 18:00:50 -0800191 QuasiAtomic::MembarStoreLoad();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200192 JValue result;
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200193 if (UNLIKELY(self->TestAllFlags())) {
194 CheckSuspend(self);
195 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200196 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200197 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200198 shadow_frame.GetMethod(), inst->GetDexPc(insns),
199 result);
200 }
201 return result;
202 }
203 case Instruction::RETURN: {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200204 JValue result;
205 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200206 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200207 if (UNLIKELY(self->TestAllFlags())) {
208 CheckSuspend(self);
209 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200210 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200211 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200212 shadow_frame.GetMethod(), inst->GetDexPc(insns),
213 result);
214 }
215 return result;
216 }
217 case Instruction::RETURN_WIDE: {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200218 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200219 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200220 if (UNLIKELY(self->TestAllFlags())) {
221 CheckSuspend(self);
222 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200223 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200224 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200225 shadow_frame.GetMethod(), inst->GetDexPc(insns),
226 result);
227 }
228 return result;
229 }
230 case Instruction::RETURN_OBJECT: {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200231 JValue result;
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200232 if (UNLIKELY(self->TestAllFlags())) {
233 CheckSuspend(self);
234 }
Mathieu Chartiere861ebd2013-10-09 15:01:21 -0700235 Object* obj_result = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
236 result.SetJ(0);
237 result.SetL(obj_result);
Jeff Haoa3faaf42013-09-03 19:07:00 -0700238 if (do_assignability_check && obj_result != NULL) {
239 Class* return_type = MethodHelper(shadow_frame.GetMethod()).GetReturnType();
240 if (return_type == NULL) {
241 // Return the pending exception.
242 HANDLE_PENDING_EXCEPTION();
243 }
244 if (!obj_result->VerifierInstanceOf(return_type)) {
245 // This should never happen.
246 self->ThrowNewExceptionF(self->GetCurrentLocationForThrow(),
247 "Ljava/lang/VirtualMachineError;",
248 "Returning '%s' that is not instance of return type '%s'",
249 ClassHelper(obj_result->GetClass()).GetDescriptor(),
250 ClassHelper(return_type).GetDescriptor());
251 HANDLE_PENDING_EXCEPTION();
252 }
253 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200254 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200255 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200256 shadow_frame.GetMethod(), inst->GetDexPc(insns),
257 result);
258 }
259 return result;
260 }
261 case Instruction::CONST_4: {
262 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200263 uint4_t dst = inst->VRegA_11n(inst_data);
264 int4_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200265 shadow_frame.SetVReg(dst, val);
266 if (val == 0) {
267 shadow_frame.SetVRegReference(dst, NULL);
268 }
269 inst = inst->Next_1xx();
270 break;
271 }
272 case Instruction::CONST_16: {
273 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200274 uint8_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200275 int16_t val = inst->VRegB_21s();
276 shadow_frame.SetVReg(dst, val);
277 if (val == 0) {
278 shadow_frame.SetVRegReference(dst, NULL);
279 }
280 inst = inst->Next_2xx();
281 break;
282 }
283 case Instruction::CONST: {
284 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200285 uint8_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200286 int32_t val = inst->VRegB_31i();
287 shadow_frame.SetVReg(dst, val);
288 if (val == 0) {
289 shadow_frame.SetVRegReference(dst, NULL);
290 }
291 inst = inst->Next_3xx();
292 break;
293 }
294 case Instruction::CONST_HIGH16: {
295 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200296 uint8_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200297 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
298 shadow_frame.SetVReg(dst, val);
299 if (val == 0) {
300 shadow_frame.SetVRegReference(dst, NULL);
301 }
302 inst = inst->Next_2xx();
303 break;
304 }
305 case Instruction::CONST_WIDE_16:
306 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200307 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200308 inst = inst->Next_2xx();
309 break;
310 case Instruction::CONST_WIDE_32:
311 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200312 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200313 inst = inst->Next_3xx();
314 break;
315 case Instruction::CONST_WIDE:
316 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200317 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200318 inst = inst->Next_51l();
319 break;
320 case Instruction::CONST_WIDE_HIGH16:
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200321 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200322 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
323 inst = inst->Next_2xx();
324 break;
325 case Instruction::CONST_STRING: {
326 PREAMBLE();
327 String* s = ResolveString(self, mh, inst->VRegB_21c());
328 if (UNLIKELY(s == NULL)) {
329 HANDLE_PENDING_EXCEPTION();
330 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200331 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200332 inst = inst->Next_2xx();
333 }
334 break;
335 }
336 case Instruction::CONST_STRING_JUMBO: {
337 PREAMBLE();
338 String* s = ResolveString(self, mh, inst->VRegB_31c());
339 if (UNLIKELY(s == NULL)) {
340 HANDLE_PENDING_EXCEPTION();
341 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200342 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200343 inst = inst->Next_3xx();
344 }
345 break;
346 }
347 case Instruction::CONST_CLASS: {
348 PREAMBLE();
349 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
350 self, false, do_access_check);
351 if (UNLIKELY(c == NULL)) {
352 HANDLE_PENDING_EXCEPTION();
353 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200354 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200355 inst = inst->Next_2xx();
356 }
357 break;
358 }
359 case Instruction::MONITOR_ENTER: {
360 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200361 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200362 if (UNLIKELY(obj == NULL)) {
363 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
364 HANDLE_PENDING_EXCEPTION();
365 } else {
366 DoMonitorEnter(self, obj);
367 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
368 }
369 break;
370 }
371 case Instruction::MONITOR_EXIT: {
372 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200373 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200374 if (UNLIKELY(obj == NULL)) {
375 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
376 HANDLE_PENDING_EXCEPTION();
377 } else {
378 DoMonitorExit(self, obj);
379 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
380 }
381 break;
382 }
383 case Instruction::CHECK_CAST: {
384 PREAMBLE();
385 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
386 self, false, do_access_check);
387 if (UNLIKELY(c == NULL)) {
388 HANDLE_PENDING_EXCEPTION();
389 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200390 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200391 if (UNLIKELY(obj != NULL && !obj->InstanceOf(c))) {
392 ThrowClassCastException(c, obj->GetClass());
393 HANDLE_PENDING_EXCEPTION();
394 } else {
395 inst = inst->Next_2xx();
396 }
397 }
398 break;
399 }
400 case Instruction::INSTANCE_OF: {
401 PREAMBLE();
402 Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(),
403 self, false, do_access_check);
404 if (UNLIKELY(c == NULL)) {
405 HANDLE_PENDING_EXCEPTION();
406 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200407 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
408 shadow_frame.SetVReg(inst->VRegA_22c(inst_data), (obj != NULL && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200409 inst = inst->Next_2xx();
410 }
411 break;
412 }
413 case Instruction::ARRAY_LENGTH: {
414 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200415 Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200416 if (UNLIKELY(array == NULL)) {
417 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
418 HANDLE_PENDING_EXCEPTION();
419 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200420 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200421 inst = inst->Next_1xx();
422 }
423 break;
424 }
425 case Instruction::NEW_INSTANCE: {
426 PREAMBLE();
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700427 Runtime* runtime = Runtime::Current();
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800428 Object* obj = AllocObjectFromCode<do_access_check, true>(
429 inst->VRegB_21c(), shadow_frame.GetMethod(), self,
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700430 runtime->GetHeap()->GetCurrentAllocator());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200431 if (UNLIKELY(obj == NULL)) {
432 HANDLE_PENDING_EXCEPTION();
433 } else {
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700434 // Don't allow finalizable objects to be allocated during a transaction since these can't
435 // be finalized without a started runtime.
436 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Ian Rogers2fa98e22014-05-06 15:26:39 -0700437 AbortTransaction(self, "Allocating finalizable object in transaction: %s",
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700438 PrettyTypeOf(obj).c_str());
439 HANDLE_PENDING_EXCEPTION();
440 break;
441 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200442 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200443 inst = inst->Next_2xx();
444 }
445 break;
446 }
447 case Instruction::NEW_ARRAY: {
448 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200449 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800450 Object* obj = AllocArrayFromCode<do_access_check, true>(
451 inst->VRegC_22c(), shadow_frame.GetMethod(), length, self,
452 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200453 if (UNLIKELY(obj == NULL)) {
454 HANDLE_PENDING_EXCEPTION();
455 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200456 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200457 inst = inst->Next_2xx();
458 }
459 break;
460 }
461 case Instruction::FILLED_NEW_ARRAY: {
462 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100463 bool success =
464 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame, self,
465 &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200466 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
467 break;
468 }
469 case Instruction::FILLED_NEW_ARRAY_RANGE: {
470 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100471 bool success =
472 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
473 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200474 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
475 break;
476 }
477 case Instruction::FILL_ARRAY_DATA: {
478 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200479 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200480 if (UNLIKELY(obj == NULL)) {
481 ThrowNullPointerException(NULL, "null array in FILL_ARRAY_DATA");
482 HANDLE_PENDING_EXCEPTION();
483 break;
484 }
485 Array* array = obj->AsArray();
486 DCHECK(array->IsArrayInstance() && !array->IsObjectArray());
487 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
488 const Instruction::ArrayDataPayload* payload =
489 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
490 if (UNLIKELY(static_cast<int32_t>(payload->element_count) > array->GetLength())) {
491 self->ThrowNewExceptionF(shadow_frame.GetCurrentLocationForThrow(),
492 "Ljava/lang/ArrayIndexOutOfBoundsException;",
493 "failed FILL_ARRAY_DATA; length=%d, index=%d",
494 array->GetLength(), payload->element_count);
495 HANDLE_PENDING_EXCEPTION();
496 break;
497 }
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100498 if (transaction_active) {
499 RecordArrayElementsInTransaction(array, payload->element_count);
500 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200501 uint32_t size_in_bytes = payload->element_count * payload->element_width;
Ian Rogersef7d42f2014-01-06 12:55:46 -0800502 memcpy(array->GetRawData(payload->element_width, 0), payload->data, size_in_bytes);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200503 inst = inst->Next_3xx();
504 break;
505 }
506 case Instruction::THROW: {
507 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200508 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200509 if (UNLIKELY(exception == NULL)) {
510 ThrowNullPointerException(NULL, "throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700511 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
512 // This should never happen.
513 self->ThrowNewExceptionF(self->GetCurrentLocationForThrow(),
514 "Ljava/lang/VirtualMachineError;",
515 "Throwing '%s' that is not instance of Throwable",
516 ClassHelper(exception->GetClass()).GetDescriptor());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200517 } else {
518 self->SetException(shadow_frame.GetCurrentLocationForThrow(), exception->AsThrowable());
519 }
520 HANDLE_PENDING_EXCEPTION();
521 break;
522 }
523 case Instruction::GOTO: {
524 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200525 int8_t offset = inst->VRegA_10t(inst_data);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200526 if (IsBackwardBranch(offset)) {
527 if (UNLIKELY(self->TestAllFlags())) {
528 CheckSuspend(self);
529 }
530 }
531 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200532 break;
533 }
534 case Instruction::GOTO_16: {
535 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200536 int16_t offset = inst->VRegA_20t();
537 if (IsBackwardBranch(offset)) {
538 if (UNLIKELY(self->TestAllFlags())) {
539 CheckSuspend(self);
540 }
541 }
542 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200543 break;
544 }
545 case Instruction::GOTO_32: {
546 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200547 int32_t offset = inst->VRegA_30t();
548 if (IsBackwardBranch(offset)) {
549 if (UNLIKELY(self->TestAllFlags())) {
550 CheckSuspend(self);
551 }
552 }
553 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200554 break;
555 }
556 case Instruction::PACKED_SWITCH: {
557 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200558 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200559 if (IsBackwardBranch(offset)) {
560 if (UNLIKELY(self->TestAllFlags())) {
561 CheckSuspend(self);
562 }
563 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200564 inst = inst->RelativeAt(offset);
565 break;
566 }
567 case Instruction::SPARSE_SWITCH: {
568 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200569 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200570 if (IsBackwardBranch(offset)) {
571 if (UNLIKELY(self->TestAllFlags())) {
572 CheckSuspend(self);
573 }
574 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200575 inst = inst->RelativeAt(offset);
576 break;
577 }
578 case Instruction::CMPL_FLOAT: {
579 PREAMBLE();
580 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
581 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
582 int32_t result;
583 if (val1 > val2) {
584 result = 1;
585 } else if (val1 == val2) {
586 result = 0;
587 } else {
588 result = -1;
589 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200590 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200591 inst = inst->Next_2xx();
592 break;
593 }
594 case Instruction::CMPG_FLOAT: {
595 PREAMBLE();
596 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
597 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
598 int32_t result;
599 if (val1 < val2) {
600 result = -1;
601 } else if (val1 == val2) {
602 result = 0;
603 } else {
604 result = 1;
605 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200606 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200607 inst = inst->Next_2xx();
608 break;
609 }
610 case Instruction::CMPL_DOUBLE: {
611 PREAMBLE();
612 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
613 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
614 int32_t result;
615 if (val1 > val2) {
616 result = 1;
617 } else if (val1 == val2) {
618 result = 0;
619 } else {
620 result = -1;
621 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200622 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200623 inst = inst->Next_2xx();
624 break;
625 }
626
627 case Instruction::CMPG_DOUBLE: {
628 PREAMBLE();
629 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
630 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
631 int32_t result;
632 if (val1 < val2) {
633 result = -1;
634 } else if (val1 == val2) {
635 result = 0;
636 } else {
637 result = 1;
638 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200639 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200640 inst = inst->Next_2xx();
641 break;
642 }
643 case Instruction::CMP_LONG: {
644 PREAMBLE();
645 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
646 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
647 int32_t result;
648 if (val1 > val2) {
649 result = 1;
650 } else if (val1 == val2) {
651 result = 0;
652 } else {
653 result = -1;
654 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200655 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200656 inst = inst->Next_2xx();
657 break;
658 }
659 case Instruction::IF_EQ: {
660 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200661 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) == shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200662 int16_t offset = inst->VRegC_22t();
663 if (IsBackwardBranch(offset)) {
664 if (UNLIKELY(self->TestAllFlags())) {
665 CheckSuspend(self);
666 }
667 }
668 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200669 } else {
670 inst = inst->Next_2xx();
671 }
672 break;
673 }
674 case Instruction::IF_NE: {
675 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200676 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) != shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200677 int16_t offset = inst->VRegC_22t();
678 if (IsBackwardBranch(offset)) {
679 if (UNLIKELY(self->TestAllFlags())) {
680 CheckSuspend(self);
681 }
682 }
683 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200684 } else {
685 inst = inst->Next_2xx();
686 }
687 break;
688 }
689 case Instruction::IF_LT: {
690 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200691 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) < shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200692 int16_t offset = inst->VRegC_22t();
693 if (IsBackwardBranch(offset)) {
694 if (UNLIKELY(self->TestAllFlags())) {
695 CheckSuspend(self);
696 }
697 }
698 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200699 } else {
700 inst = inst->Next_2xx();
701 }
702 break;
703 }
704 case Instruction::IF_GE: {
705 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200706 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >= shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200707 int16_t offset = inst->VRegC_22t();
708 if (IsBackwardBranch(offset)) {
709 if (UNLIKELY(self->TestAllFlags())) {
710 CheckSuspend(self);
711 }
712 }
713 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200714 } else {
715 inst = inst->Next_2xx();
716 }
717 break;
718 }
719 case Instruction::IF_GT: {
720 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200721 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) > shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200722 int16_t offset = inst->VRegC_22t();
723 if (IsBackwardBranch(offset)) {
724 if (UNLIKELY(self->TestAllFlags())) {
725 CheckSuspend(self);
726 }
727 }
728 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200729 } else {
730 inst = inst->Next_2xx();
731 }
732 break;
733 }
734 case Instruction::IF_LE: {
735 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200736 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <= shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200737 int16_t offset = inst->VRegC_22t();
738 if (IsBackwardBranch(offset)) {
739 if (UNLIKELY(self->TestAllFlags())) {
740 CheckSuspend(self);
741 }
742 }
743 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200744 } else {
745 inst = inst->Next_2xx();
746 }
747 break;
748 }
749 case Instruction::IF_EQZ: {
750 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200751 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200752 int16_t offset = inst->VRegB_21t();
753 if (IsBackwardBranch(offset)) {
754 if (UNLIKELY(self->TestAllFlags())) {
755 CheckSuspend(self);
756 }
757 }
758 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200759 } else {
760 inst = inst->Next_2xx();
761 }
762 break;
763 }
764 case Instruction::IF_NEZ: {
765 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200766 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200767 int16_t offset = inst->VRegB_21t();
768 if (IsBackwardBranch(offset)) {
769 if (UNLIKELY(self->TestAllFlags())) {
770 CheckSuspend(self);
771 }
772 }
773 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200774 } else {
775 inst = inst->Next_2xx();
776 }
777 break;
778 }
779 case Instruction::IF_LTZ: {
780 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200781 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200782 int16_t offset = inst->VRegB_21t();
783 if (IsBackwardBranch(offset)) {
784 if (UNLIKELY(self->TestAllFlags())) {
785 CheckSuspend(self);
786 }
787 }
788 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200789 } else {
790 inst = inst->Next_2xx();
791 }
792 break;
793 }
794 case Instruction::IF_GEZ: {
795 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200796 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200797 int16_t offset = inst->VRegB_21t();
798 if (IsBackwardBranch(offset)) {
799 if (UNLIKELY(self->TestAllFlags())) {
800 CheckSuspend(self);
801 }
802 }
803 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200804 } else {
805 inst = inst->Next_2xx();
806 }
807 break;
808 }
809 case Instruction::IF_GTZ: {
810 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200811 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200812 int16_t offset = inst->VRegB_21t();
813 if (IsBackwardBranch(offset)) {
814 if (UNLIKELY(self->TestAllFlags())) {
815 CheckSuspend(self);
816 }
817 }
818 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200819 } else {
820 inst = inst->Next_2xx();
821 }
822 break;
823 }
824 case Instruction::IF_LEZ: {
825 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200826 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200827 int16_t offset = inst->VRegB_21t();
828 if (IsBackwardBranch(offset)) {
829 if (UNLIKELY(self->TestAllFlags())) {
830 CheckSuspend(self);
831 }
832 }
833 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200834 } else {
835 inst = inst->Next_2xx();
836 }
837 break;
838 }
839 case Instruction::AGET_BOOLEAN: {
840 PREAMBLE();
841 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
842 if (UNLIKELY(a == NULL)) {
843 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
844 HANDLE_PENDING_EXCEPTION();
845 break;
846 }
847 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
848 BooleanArray* array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700849 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100850 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200851 inst = inst->Next_2xx();
852 } else {
853 HANDLE_PENDING_EXCEPTION();
854 }
855 break;
856 }
857 case Instruction::AGET_BYTE: {
858 PREAMBLE();
859 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
860 if (UNLIKELY(a == NULL)) {
861 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
862 HANDLE_PENDING_EXCEPTION();
863 break;
864 }
865 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
866 ByteArray* array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700867 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100868 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200869 inst = inst->Next_2xx();
870 } else {
871 HANDLE_PENDING_EXCEPTION();
872 }
873 break;
874 }
875 case Instruction::AGET_CHAR: {
876 PREAMBLE();
877 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
878 if (UNLIKELY(a == NULL)) {
879 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
880 HANDLE_PENDING_EXCEPTION();
881 break;
882 }
883 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
884 CharArray* array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700885 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100886 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200887 inst = inst->Next_2xx();
888 } else {
889 HANDLE_PENDING_EXCEPTION();
890 }
891 break;
892 }
893 case Instruction::AGET_SHORT: {
894 PREAMBLE();
895 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
896 if (UNLIKELY(a == NULL)) {
897 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
898 HANDLE_PENDING_EXCEPTION();
899 break;
900 }
901 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
902 ShortArray* array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700903 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100904 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200905 inst = inst->Next_2xx();
906 } else {
907 HANDLE_PENDING_EXCEPTION();
908 }
909 break;
910 }
911 case Instruction::AGET: {
912 PREAMBLE();
913 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
914 if (UNLIKELY(a == NULL)) {
915 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
916 HANDLE_PENDING_EXCEPTION();
917 break;
918 }
919 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
920 IntArray* array = a->AsIntArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700921 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100922 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200923 inst = inst->Next_2xx();
924 } else {
925 HANDLE_PENDING_EXCEPTION();
926 }
927 break;
928 }
929 case Instruction::AGET_WIDE: {
930 PREAMBLE();
931 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
932 if (UNLIKELY(a == NULL)) {
933 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
934 HANDLE_PENDING_EXCEPTION();
935 break;
936 }
937 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
938 LongArray* array = a->AsLongArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700939 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100940 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200941 inst = inst->Next_2xx();
942 } else {
943 HANDLE_PENDING_EXCEPTION();
944 }
945 break;
946 }
947 case Instruction::AGET_OBJECT: {
948 PREAMBLE();
949 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
950 if (UNLIKELY(a == NULL)) {
951 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
952 HANDLE_PENDING_EXCEPTION();
953 break;
954 }
955 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
956 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700957 if (array->CheckIsValidIndex(index)) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200958 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200959 inst = inst->Next_2xx();
960 } else {
961 HANDLE_PENDING_EXCEPTION();
962 }
963 break;
964 }
965 case Instruction::APUT_BOOLEAN: {
966 PREAMBLE();
967 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
968 if (UNLIKELY(a == NULL)) {
969 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
970 HANDLE_PENDING_EXCEPTION();
971 break;
972 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200973 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200974 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
975 BooleanArray* array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700976 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100977 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200978 inst = inst->Next_2xx();
979 } else {
980 HANDLE_PENDING_EXCEPTION();
981 }
982 break;
983 }
984 case Instruction::APUT_BYTE: {
985 PREAMBLE();
986 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
987 if (UNLIKELY(a == NULL)) {
988 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
989 HANDLE_PENDING_EXCEPTION();
990 break;
991 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200992 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200993 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
994 ByteArray* array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700995 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100996 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200997 inst = inst->Next_2xx();
998 } else {
999 HANDLE_PENDING_EXCEPTION();
1000 }
1001 break;
1002 }
1003 case Instruction::APUT_CHAR: {
1004 PREAMBLE();
1005 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1006 if (UNLIKELY(a == NULL)) {
1007 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
1008 HANDLE_PENDING_EXCEPTION();
1009 break;
1010 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001011 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001012 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1013 CharArray* array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001014 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001015 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001016 inst = inst->Next_2xx();
1017 } else {
1018 HANDLE_PENDING_EXCEPTION();
1019 }
1020 break;
1021 }
1022 case Instruction::APUT_SHORT: {
1023 PREAMBLE();
1024 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1025 if (UNLIKELY(a == NULL)) {
1026 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
1027 HANDLE_PENDING_EXCEPTION();
1028 break;
1029 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001030 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001031 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1032 ShortArray* array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001033 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001034 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001035 inst = inst->Next_2xx();
1036 } else {
1037 HANDLE_PENDING_EXCEPTION();
1038 }
1039 break;
1040 }
1041 case Instruction::APUT: {
1042 PREAMBLE();
1043 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1044 if (UNLIKELY(a == NULL)) {
1045 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
1046 HANDLE_PENDING_EXCEPTION();
1047 break;
1048 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001049 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001050 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1051 IntArray* array = a->AsIntArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001052 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001053 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001054 inst = inst->Next_2xx();
1055 } else {
1056 HANDLE_PENDING_EXCEPTION();
1057 }
1058 break;
1059 }
1060 case Instruction::APUT_WIDE: {
1061 PREAMBLE();
1062 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1063 if (UNLIKELY(a == NULL)) {
1064 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
1065 HANDLE_PENDING_EXCEPTION();
1066 break;
1067 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001068 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001069 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1070 LongArray* array = a->AsLongArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001071 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001072 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001073 inst = inst->Next_2xx();
1074 } else {
1075 HANDLE_PENDING_EXCEPTION();
1076 }
1077 break;
1078 }
1079 case Instruction::APUT_OBJECT: {
1080 PREAMBLE();
1081 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1082 if (UNLIKELY(a == NULL)) {
1083 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
1084 HANDLE_PENDING_EXCEPTION();
1085 break;
1086 }
1087 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001088 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001089 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001090 if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001091 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001092 inst = inst->Next_2xx();
1093 } else {
1094 HANDLE_PENDING_EXCEPTION();
1095 }
1096 break;
1097 }
1098 case Instruction::IGET_BOOLEAN: {
1099 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001100 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001101 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1102 break;
1103 }
1104 case Instruction::IGET_BYTE: {
1105 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001106 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001107 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1108 break;
1109 }
1110 case Instruction::IGET_CHAR: {
1111 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001112 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001113 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1114 break;
1115 }
1116 case Instruction::IGET_SHORT: {
1117 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001118 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001119 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1120 break;
1121 }
1122 case Instruction::IGET: {
1123 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001124 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001125 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1126 break;
1127 }
1128 case Instruction::IGET_WIDE: {
1129 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001130 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001131 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1132 break;
1133 }
1134 case Instruction::IGET_OBJECT: {
1135 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001136 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001137 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1138 break;
1139 }
1140 case Instruction::IGET_QUICK: {
1141 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001142 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001143 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1144 break;
1145 }
1146 case Instruction::IGET_WIDE_QUICK: {
1147 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001148 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001149 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1150 break;
1151 }
1152 case Instruction::IGET_OBJECT_QUICK: {
1153 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001154 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001155 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1156 break;
1157 }
1158 case Instruction::SGET_BOOLEAN: {
1159 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001160 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001161 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1162 break;
1163 }
1164 case Instruction::SGET_BYTE: {
1165 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001166 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001167 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1168 break;
1169 }
1170 case Instruction::SGET_CHAR: {
1171 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001172 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001173 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1174 break;
1175 }
1176 case Instruction::SGET_SHORT: {
1177 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001178 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001179 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1180 break;
1181 }
1182 case Instruction::SGET: {
1183 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001184 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001185 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1186 break;
1187 }
1188 case Instruction::SGET_WIDE: {
1189 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001190 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001191 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1192 break;
1193 }
1194 case Instruction::SGET_OBJECT: {
1195 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001196 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001197 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1198 break;
1199 }
1200 case Instruction::IPUT_BOOLEAN: {
1201 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001202 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001203 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1204 break;
1205 }
1206 case Instruction::IPUT_BYTE: {
1207 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001208 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001209 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1210 break;
1211 }
1212 case Instruction::IPUT_CHAR: {
1213 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001214 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001215 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1216 break;
1217 }
1218 case Instruction::IPUT_SHORT: {
1219 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001220 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001221 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1222 break;
1223 }
1224 case Instruction::IPUT: {
1225 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001226 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001227 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1228 break;
1229 }
1230 case Instruction::IPUT_WIDE: {
1231 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001232 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001233 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1234 break;
1235 }
1236 case Instruction::IPUT_OBJECT: {
1237 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001238 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001239 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1240 break;
1241 }
1242 case Instruction::IPUT_QUICK: {
1243 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001244 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001245 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1246 break;
1247 }
1248 case Instruction::IPUT_WIDE_QUICK: {
1249 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001250 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001251 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1252 break;
1253 }
1254 case Instruction::IPUT_OBJECT_QUICK: {
1255 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001256 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001257 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1258 break;
1259 }
1260 case Instruction::SPUT_BOOLEAN: {
1261 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001262 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check, transaction_active>(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::SPUT_BYTE: {
1267 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001268 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001269 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1270 break;
1271 }
1272 case Instruction::SPUT_CHAR: {
1273 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001274 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001275 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1276 break;
1277 }
1278 case Instruction::SPUT_SHORT: {
1279 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001280 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001281 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1282 break;
1283 }
1284 case Instruction::SPUT: {
1285 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001286 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001287 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1288 break;
1289 }
1290 case Instruction::SPUT_WIDE: {
1291 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001292 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001293 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1294 break;
1295 }
1296 case Instruction::SPUT_OBJECT: {
1297 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001298 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001299 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1300 break;
1301 }
1302 case Instruction::INVOKE_VIRTUAL: {
1303 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001304 bool success = DoInvoke<kVirtual, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001305 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1306 break;
1307 }
1308 case Instruction::INVOKE_VIRTUAL_RANGE: {
1309 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001310 bool success = DoInvoke<kVirtual, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001311 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1312 break;
1313 }
1314 case Instruction::INVOKE_SUPER: {
1315 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001316 bool success = DoInvoke<kSuper, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001317 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1318 break;
1319 }
1320 case Instruction::INVOKE_SUPER_RANGE: {
1321 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001322 bool success = DoInvoke<kSuper, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001323 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1324 break;
1325 }
1326 case Instruction::INVOKE_DIRECT: {
1327 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001328 bool success = DoInvoke<kDirect, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001329 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1330 break;
1331 }
1332 case Instruction::INVOKE_DIRECT_RANGE: {
1333 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001334 bool success = DoInvoke<kDirect, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001335 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1336 break;
1337 }
1338 case Instruction::INVOKE_INTERFACE: {
1339 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001340 bool success = DoInvoke<kInterface, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001341 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1342 break;
1343 }
1344 case Instruction::INVOKE_INTERFACE_RANGE: {
1345 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001346 bool success = DoInvoke<kInterface, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001347 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1348 break;
1349 }
1350 case Instruction::INVOKE_STATIC: {
1351 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001352 bool success = DoInvoke<kStatic, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001353 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1354 break;
1355 }
1356 case Instruction::INVOKE_STATIC_RANGE: {
1357 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001358 bool success = DoInvoke<kStatic, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001359 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1360 break;
1361 }
1362 case Instruction::INVOKE_VIRTUAL_QUICK: {
1363 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001364 bool success = DoInvokeVirtualQuick<false>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001365 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1366 break;
1367 }
1368 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
1369 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001370 bool success = DoInvokeVirtualQuick<true>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001371 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1372 break;
1373 }
1374 case Instruction::NEG_INT:
1375 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001376 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001377 inst = inst->Next_1xx();
1378 break;
1379 case Instruction::NOT_INT:
1380 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001381 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001382 inst = inst->Next_1xx();
1383 break;
1384 case Instruction::NEG_LONG:
1385 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001386 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001387 inst = inst->Next_1xx();
1388 break;
1389 case Instruction::NOT_LONG:
1390 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001391 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001392 inst = inst->Next_1xx();
1393 break;
1394 case Instruction::NEG_FLOAT:
1395 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001396 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001397 inst = inst->Next_1xx();
1398 break;
1399 case Instruction::NEG_DOUBLE:
1400 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001401 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001402 inst = inst->Next_1xx();
1403 break;
1404 case Instruction::INT_TO_LONG:
1405 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001406 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
1407 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001408 inst = inst->Next_1xx();
1409 break;
1410 case Instruction::INT_TO_FLOAT:
1411 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001412 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1413 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001414 inst = inst->Next_1xx();
1415 break;
1416 case Instruction::INT_TO_DOUBLE:
1417 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001418 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1419 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001420 inst = inst->Next_1xx();
1421 break;
1422 case Instruction::LONG_TO_INT:
1423 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001424 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1425 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001426 inst = inst->Next_1xx();
1427 break;
1428 case Instruction::LONG_TO_FLOAT:
1429 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001430 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1431 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001432 inst = inst->Next_1xx();
1433 break;
1434 case Instruction::LONG_TO_DOUBLE:
1435 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001436 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1437 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001438 inst = inst->Next_1xx();
1439 break;
1440 case Instruction::FLOAT_TO_INT: {
1441 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001442 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001443 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001444 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001445 inst = inst->Next_1xx();
1446 break;
1447 }
1448 case Instruction::FLOAT_TO_LONG: {
1449 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001450 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001451 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001452 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001453 inst = inst->Next_1xx();
1454 break;
1455 }
1456 case Instruction::FLOAT_TO_DOUBLE:
1457 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001458 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1459 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001460 inst = inst->Next_1xx();
1461 break;
1462 case Instruction::DOUBLE_TO_INT: {
1463 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001464 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001465 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001466 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001467 inst = inst->Next_1xx();
1468 break;
1469 }
1470 case Instruction::DOUBLE_TO_LONG: {
1471 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001472 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001473 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001474 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001475 inst = inst->Next_1xx();
1476 break;
1477 }
1478 case Instruction::DOUBLE_TO_FLOAT:
1479 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001480 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1481 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001482 inst = inst->Next_1xx();
1483 break;
1484 case Instruction::INT_TO_BYTE:
1485 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001486 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1487 static_cast<int8_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001488 inst = inst->Next_1xx();
1489 break;
1490 case Instruction::INT_TO_CHAR:
1491 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001492 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1493 static_cast<uint16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001494 inst = inst->Next_1xx();
1495 break;
1496 case Instruction::INT_TO_SHORT:
1497 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001498 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1499 static_cast<int16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001500 inst = inst->Next_1xx();
1501 break;
1502 case Instruction::ADD_INT:
1503 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001504 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001505 shadow_frame.GetVReg(inst->VRegB_23x()) +
1506 shadow_frame.GetVReg(inst->VRegC_23x()));
1507 inst = inst->Next_2xx();
1508 break;
1509 case Instruction::SUB_INT:
1510 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001511 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001512 shadow_frame.GetVReg(inst->VRegB_23x()) -
1513 shadow_frame.GetVReg(inst->VRegC_23x()));
1514 inst = inst->Next_2xx();
1515 break;
1516 case Instruction::MUL_INT:
1517 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001518 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001519 shadow_frame.GetVReg(inst->VRegB_23x()) *
1520 shadow_frame.GetVReg(inst->VRegC_23x()));
1521 inst = inst->Next_2xx();
1522 break;
1523 case Instruction::DIV_INT: {
1524 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001525 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001526 shadow_frame.GetVReg(inst->VRegB_23x()),
1527 shadow_frame.GetVReg(inst->VRegC_23x()));
1528 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1529 break;
1530 }
1531 case Instruction::REM_INT: {
1532 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001533 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001534 shadow_frame.GetVReg(inst->VRegB_23x()),
1535 shadow_frame.GetVReg(inst->VRegC_23x()));
1536 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1537 break;
1538 }
1539 case Instruction::SHL_INT:
1540 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001541 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001542 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1543 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1544 inst = inst->Next_2xx();
1545 break;
1546 case Instruction::SHR_INT:
1547 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001548 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001549 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1550 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1551 inst = inst->Next_2xx();
1552 break;
1553 case Instruction::USHR_INT:
1554 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001555 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001556 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1557 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1558 inst = inst->Next_2xx();
1559 break;
1560 case Instruction::AND_INT:
1561 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001562 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001563 shadow_frame.GetVReg(inst->VRegB_23x()) &
1564 shadow_frame.GetVReg(inst->VRegC_23x()));
1565 inst = inst->Next_2xx();
1566 break;
1567 case Instruction::OR_INT:
1568 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001569 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001570 shadow_frame.GetVReg(inst->VRegB_23x()) |
1571 shadow_frame.GetVReg(inst->VRegC_23x()));
1572 inst = inst->Next_2xx();
1573 break;
1574 case Instruction::XOR_INT:
1575 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001576 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001577 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1578 shadow_frame.GetVReg(inst->VRegC_23x()));
1579 inst = inst->Next_2xx();
1580 break;
1581 case Instruction::ADD_LONG:
1582 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001583 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001584 shadow_frame.GetVRegLong(inst->VRegB_23x()) +
1585 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1586 inst = inst->Next_2xx();
1587 break;
1588 case Instruction::SUB_LONG:
1589 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001590 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001591 shadow_frame.GetVRegLong(inst->VRegB_23x()) -
1592 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1593 inst = inst->Next_2xx();
1594 break;
1595 case Instruction::MUL_LONG:
1596 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001597 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001598 shadow_frame.GetVRegLong(inst->VRegB_23x()) *
1599 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1600 inst = inst->Next_2xx();
1601 break;
1602 case Instruction::DIV_LONG:
1603 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001604 DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001605 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1606 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1607 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1608 break;
1609 case Instruction::REM_LONG:
1610 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001611 DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001612 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1613 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1614 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1615 break;
1616 case Instruction::AND_LONG:
1617 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001618 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001619 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1620 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1621 inst = inst->Next_2xx();
1622 break;
1623 case Instruction::OR_LONG:
1624 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001625 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001626 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1627 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1628 inst = inst->Next_2xx();
1629 break;
1630 case Instruction::XOR_LONG:
1631 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001632 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001633 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1634 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1635 inst = inst->Next_2xx();
1636 break;
1637 case Instruction::SHL_LONG:
1638 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001639 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001640 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1641 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1642 inst = inst->Next_2xx();
1643 break;
1644 case Instruction::SHR_LONG:
1645 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001646 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001647 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1648 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1649 inst = inst->Next_2xx();
1650 break;
1651 case Instruction::USHR_LONG:
1652 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001653 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001654 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1655 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1656 inst = inst->Next_2xx();
1657 break;
1658 case Instruction::ADD_FLOAT:
1659 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001660 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001661 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1662 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1663 inst = inst->Next_2xx();
1664 break;
1665 case Instruction::SUB_FLOAT:
1666 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001667 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001668 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1669 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1670 inst = inst->Next_2xx();
1671 break;
1672 case Instruction::MUL_FLOAT:
1673 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001674 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001675 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1676 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1677 inst = inst->Next_2xx();
1678 break;
1679 case Instruction::DIV_FLOAT:
1680 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001681 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001682 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1683 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1684 inst = inst->Next_2xx();
1685 break;
1686 case Instruction::REM_FLOAT:
1687 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001688 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001689 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1690 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1691 inst = inst->Next_2xx();
1692 break;
1693 case Instruction::ADD_DOUBLE:
1694 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001695 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001696 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1697 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1698 inst = inst->Next_2xx();
1699 break;
1700 case Instruction::SUB_DOUBLE:
1701 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001702 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001703 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1704 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1705 inst = inst->Next_2xx();
1706 break;
1707 case Instruction::MUL_DOUBLE:
1708 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001709 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001710 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
1711 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1712 inst = inst->Next_2xx();
1713 break;
1714 case Instruction::DIV_DOUBLE:
1715 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001716 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001717 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
1718 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1719 inst = inst->Next_2xx();
1720 break;
1721 case Instruction::REM_DOUBLE:
1722 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001723 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001724 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
1725 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
1726 inst = inst->Next_2xx();
1727 break;
1728 case Instruction::ADD_INT_2ADDR: {
1729 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001730 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001731 shadow_frame.SetVReg(vregA,
1732 shadow_frame.GetVReg(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001733 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001734 inst = inst->Next_1xx();
1735 break;
1736 }
1737 case Instruction::SUB_INT_2ADDR: {
1738 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001739 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001740 shadow_frame.SetVReg(vregA,
1741 shadow_frame.GetVReg(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001742 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001743 inst = inst->Next_1xx();
1744 break;
1745 }
1746 case Instruction::MUL_INT_2ADDR: {
1747 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001748 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001749 shadow_frame.SetVReg(vregA,
1750 shadow_frame.GetVReg(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001751 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001752 inst = inst->Next_1xx();
1753 break;
1754 }
1755 case Instruction::DIV_INT_2ADDR: {
1756 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001757 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001758 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001759 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001760 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1761 break;
1762 }
1763 case Instruction::REM_INT_2ADDR: {
1764 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001765 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001766 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001767 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001768 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1769 break;
1770 }
1771 case Instruction::SHL_INT_2ADDR: {
1772 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001773 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001774 shadow_frame.SetVReg(vregA,
1775 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001776 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001777 inst = inst->Next_1xx();
1778 break;
1779 }
1780 case Instruction::SHR_INT_2ADDR: {
1781 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001782 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001783 shadow_frame.SetVReg(vregA,
1784 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001785 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001786 inst = inst->Next_1xx();
1787 break;
1788 }
1789 case Instruction::USHR_INT_2ADDR: {
1790 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001791 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001792 shadow_frame.SetVReg(vregA,
1793 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001794 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001795 inst = inst->Next_1xx();
1796 break;
1797 }
1798 case Instruction::AND_INT_2ADDR: {
1799 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001800 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001801 shadow_frame.SetVReg(vregA,
1802 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001803 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001804 inst = inst->Next_1xx();
1805 break;
1806 }
1807 case Instruction::OR_INT_2ADDR: {
1808 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001809 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001810 shadow_frame.SetVReg(vregA,
1811 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001812 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001813 inst = inst->Next_1xx();
1814 break;
1815 }
1816 case Instruction::XOR_INT_2ADDR: {
1817 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001818 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001819 shadow_frame.SetVReg(vregA,
1820 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001821 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001822 inst = inst->Next_1xx();
1823 break;
1824 }
1825 case Instruction::ADD_LONG_2ADDR: {
1826 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001827 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001828 shadow_frame.SetVRegLong(vregA,
1829 shadow_frame.GetVRegLong(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001830 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001831 inst = inst->Next_1xx();
1832 break;
1833 }
1834 case Instruction::SUB_LONG_2ADDR: {
1835 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001836 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001837 shadow_frame.SetVRegLong(vregA,
1838 shadow_frame.GetVRegLong(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001839 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001840 inst = inst->Next_1xx();
1841 break;
1842 }
1843 case Instruction::MUL_LONG_2ADDR: {
1844 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001845 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001846 shadow_frame.SetVRegLong(vregA,
1847 shadow_frame.GetVRegLong(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001848 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001849 inst = inst->Next_1xx();
1850 break;
1851 }
1852 case Instruction::DIV_LONG_2ADDR: {
1853 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001854 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001855 DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001856 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001857 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
1858 break;
1859 }
1860 case Instruction::REM_LONG_2ADDR: {
1861 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001862 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001863 DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001864 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001865 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
1866 break;
1867 }
1868 case Instruction::AND_LONG_2ADDR: {
1869 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001870 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001871 shadow_frame.SetVRegLong(vregA,
1872 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001873 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001874 inst = inst->Next_1xx();
1875 break;
1876 }
1877 case Instruction::OR_LONG_2ADDR: {
1878 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001879 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001880 shadow_frame.SetVRegLong(vregA,
1881 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001882 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001883 inst = inst->Next_1xx();
1884 break;
1885 }
1886 case Instruction::XOR_LONG_2ADDR: {
1887 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001888 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001889 shadow_frame.SetVRegLong(vregA,
1890 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001891 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001892 inst = inst->Next_1xx();
1893 break;
1894 }
1895 case Instruction::SHL_LONG_2ADDR: {
1896 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001897 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001898 shadow_frame.SetVRegLong(vregA,
1899 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001900 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001901 inst = inst->Next_1xx();
1902 break;
1903 }
1904 case Instruction::SHR_LONG_2ADDR: {
1905 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001906 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001907 shadow_frame.SetVRegLong(vregA,
1908 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001909 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001910 inst = inst->Next_1xx();
1911 break;
1912 }
1913 case Instruction::USHR_LONG_2ADDR: {
1914 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001915 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001916 shadow_frame.SetVRegLong(vregA,
1917 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001918 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001919 inst = inst->Next_1xx();
1920 break;
1921 }
1922 case Instruction::ADD_FLOAT_2ADDR: {
1923 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001924 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001925 shadow_frame.SetVRegFloat(vregA,
1926 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001927 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001928 inst = inst->Next_1xx();
1929 break;
1930 }
1931 case Instruction::SUB_FLOAT_2ADDR: {
1932 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001933 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001934 shadow_frame.SetVRegFloat(vregA,
1935 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001936 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001937 inst = inst->Next_1xx();
1938 break;
1939 }
1940 case Instruction::MUL_FLOAT_2ADDR: {
1941 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001942 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001943 shadow_frame.SetVRegFloat(vregA,
1944 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001945 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001946 inst = inst->Next_1xx();
1947 break;
1948 }
1949 case Instruction::DIV_FLOAT_2ADDR: {
1950 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001951 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001952 shadow_frame.SetVRegFloat(vregA,
1953 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001954 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001955 inst = inst->Next_1xx();
1956 break;
1957 }
1958 case Instruction::REM_FLOAT_2ADDR: {
1959 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001960 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001961 shadow_frame.SetVRegFloat(vregA,
1962 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001963 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001964 inst = inst->Next_1xx();
1965 break;
1966 }
1967 case Instruction::ADD_DOUBLE_2ADDR: {
1968 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001969 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001970 shadow_frame.SetVRegDouble(vregA,
1971 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001972 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001973 inst = inst->Next_1xx();
1974 break;
1975 }
1976 case Instruction::SUB_DOUBLE_2ADDR: {
1977 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001978 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001979 shadow_frame.SetVRegDouble(vregA,
1980 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001981 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001982 inst = inst->Next_1xx();
1983 break;
1984 }
1985 case Instruction::MUL_DOUBLE_2ADDR: {
1986 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001987 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001988 shadow_frame.SetVRegDouble(vregA,
1989 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001990 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001991 inst = inst->Next_1xx();
1992 break;
1993 }
1994 case Instruction::DIV_DOUBLE_2ADDR: {
1995 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001996 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001997 shadow_frame.SetVRegDouble(vregA,
1998 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001999 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002000 inst = inst->Next_1xx();
2001 break;
2002 }
2003 case Instruction::REM_DOUBLE_2ADDR: {
2004 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002005 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002006 shadow_frame.SetVRegDouble(vregA,
2007 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002008 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002009 inst = inst->Next_1xx();
2010 break;
2011 }
2012 case Instruction::ADD_INT_LIT16:
2013 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002014 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2015 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) +
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002016 inst->VRegC_22s());
2017 inst = inst->Next_2xx();
2018 break;
2019 case Instruction::RSUB_INT:
2020 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002021 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002022 inst->VRegC_22s() -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002023 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002024 inst = inst->Next_2xx();
2025 break;
2026 case Instruction::MUL_INT_LIT16:
2027 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002028 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2029 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) *
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002030 inst->VRegC_22s());
2031 inst = inst->Next_2xx();
2032 break;
2033 case Instruction::DIV_INT_LIT16: {
2034 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002035 bool success = DoIntDivide(shadow_frame, inst->VRegA_22s(inst_data),
2036 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)), inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002037 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2038 break;
2039 }
2040 case Instruction::REM_INT_LIT16: {
2041 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002042 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22s(inst_data),
2043 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)), inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002044 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2045 break;
2046 }
2047 case Instruction::AND_INT_LIT16:
2048 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002049 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2050 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002051 inst->VRegC_22s());
2052 inst = inst->Next_2xx();
2053 break;
2054 case Instruction::OR_INT_LIT16:
2055 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002056 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2057 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002058 inst->VRegC_22s());
2059 inst = inst->Next_2xx();
2060 break;
2061 case Instruction::XOR_INT_LIT16:
2062 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002063 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2064 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002065 inst->VRegC_22s());
2066 inst = inst->Next_2xx();
2067 break;
2068 case Instruction::ADD_INT_LIT8:
2069 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002070 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002071 shadow_frame.GetVReg(inst->VRegB_22b()) +
2072 inst->VRegC_22b());
2073 inst = inst->Next_2xx();
2074 break;
2075 case Instruction::RSUB_INT_LIT8:
2076 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002077 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002078 inst->VRegC_22b() -
2079 shadow_frame.GetVReg(inst->VRegB_22b()));
2080 inst = inst->Next_2xx();
2081 break;
2082 case Instruction::MUL_INT_LIT8:
2083 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002084 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002085 shadow_frame.GetVReg(inst->VRegB_22b()) *
2086 inst->VRegC_22b());
2087 inst = inst->Next_2xx();
2088 break;
2089 case Instruction::DIV_INT_LIT8: {
2090 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002091 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002092 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2093 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2094 break;
2095 }
2096 case Instruction::REM_INT_LIT8: {
2097 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002098 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002099 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2100 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2101 break;
2102 }
2103 case Instruction::AND_INT_LIT8:
2104 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002105 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002106 shadow_frame.GetVReg(inst->VRegB_22b()) &
2107 inst->VRegC_22b());
2108 inst = inst->Next_2xx();
2109 break;
2110 case Instruction::OR_INT_LIT8:
2111 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002112 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002113 shadow_frame.GetVReg(inst->VRegB_22b()) |
2114 inst->VRegC_22b());
2115 inst = inst->Next_2xx();
2116 break;
2117 case Instruction::XOR_INT_LIT8:
2118 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002119 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002120 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2121 inst->VRegC_22b());
2122 inst = inst->Next_2xx();
2123 break;
2124 case Instruction::SHL_INT_LIT8:
2125 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002126 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002127 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2128 (inst->VRegC_22b() & 0x1f));
2129 inst = inst->Next_2xx();
2130 break;
2131 case Instruction::SHR_INT_LIT8:
2132 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002133 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002134 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2135 (inst->VRegC_22b() & 0x1f));
2136 inst = inst->Next_2xx();
2137 break;
2138 case Instruction::USHR_INT_LIT8:
2139 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002140 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002141 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2142 (inst->VRegC_22b() & 0x1f));
2143 inst = inst->Next_2xx();
2144 break;
2145 case Instruction::UNUSED_3E ... Instruction::UNUSED_43:
2146 case Instruction::UNUSED_EB ... Instruction::UNUSED_FF:
2147 case Instruction::UNUSED_79:
2148 case Instruction::UNUSED_7A:
2149 UnexpectedOpcode(inst, mh);
2150 }
2151 }
2152} // NOLINT(readability/fn_size)
2153
2154// Explicit definitions of ExecuteSwitchImpl.
Sebastien Hertzc6714852013-09-30 16:42:32 +02002155template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002156JValue ExecuteSwitchImpl<true, false>(Thread* self, MethodHelper& mh,
2157 const DexFile::CodeItem* code_item,
2158 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertzc6714852013-09-30 16:42:32 +02002159template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002160JValue ExecuteSwitchImpl<false, false>(Thread* self, MethodHelper& mh,
2161 const DexFile::CodeItem* code_item,
2162 ShadowFrame& shadow_frame, JValue result_register);
2163template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
2164JValue ExecuteSwitchImpl<true, true>(Thread* self, MethodHelper& mh,
2165 const DexFile::CodeItem* code_item,
2166 ShadowFrame& shadow_frame, JValue result_register);
2167template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
2168JValue ExecuteSwitchImpl<false, true>(Thread* self, MethodHelper& mh,
2169 const DexFile::CodeItem* code_item,
2170 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002171
2172} // namespace interpreter
2173} // namespace art