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