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