blob: 4bef770408331a536054ad10a3ad145ecb0ddfbf [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.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020027// - "mh": the current MethodHelper.
28// - "currentHandlersTable": the current table of pointer to each instruction handler.
29
30// Advance to the next instruction and updates interpreter state.
31// TODO: move check suspend to backward branch, return and exception handling.
32#define ADVANCE(_offset) \
33 do { \
34 int32_t disp = static_cast<int32_t>(_offset); \
35 inst = inst->RelativeAt(disp); \
36 dex_pc = static_cast<uint32_t>(static_cast<int32_t>(dex_pc) + disp); \
37 shadow_frame.SetDexPC(dex_pc); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020038 TraceExecution(shadow_frame, inst, dex_pc, mh); \
39 goto *currentHandlersTable[inst->Opcode()]; \
40 } while (false)
41
42#define HANDLE_PENDING_EXCEPTION() goto exception_pending_label
43
44#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _offset) \
45 do { \
46 if (UNLIKELY(_is_exception_pending)) { \
47 HANDLE_PENDING_EXCEPTION(); \
48 } else { \
49 ADVANCE(_offset); \
50 } \
51 } while (false)
52
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +020053#define UPDATE_HANDLER_TABLE() \
54 do { \
55 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
56 currentHandlersTable = instrumentationHandlersTable; \
57 } else { \
58 currentHandlersTable = handlersTable; \
59 } \
60 } while (false);
61
Sebastien Hertz8ece0502013-08-07 11:26:41 +020062#define UNREACHABLE_CODE_CHECK() \
63 do { \
64 if (kIsDebugBuild) { \
65 LOG(FATAL) << "We should not be here !"; \
66 } \
67 } while (false)
68
69#define HANDLE_INSTRUCTION_START(opcode) op_##opcode: // NOLINT(whitespace/labels)
70#define HANDLE_INSTRUCTION_END() UNREACHABLE_CODE_CHECK()
71
Sebastien Hertz8ece0502013-08-07 11:26:41 +020072template<bool do_access_check>
73JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item,
74 ShadowFrame& shadow_frame, JValue result_register) {
75 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
76 LOG(FATAL) << "Invalid shadow frame for interpreter use";
77 return JValue();
78 }
79 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +020080
81 uint32_t dex_pc = shadow_frame.GetDexPC();
Sebastien Hertz947ff082013-09-17 14:10:13 +020082 const instrumentation::Instrumentation* const instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +020083 if (LIKELY(dex_pc == 0)) { // We are entering the method as opposed to deoptimizing..
84 if (UNLIKELY(instrumentation->HasMethodEntryListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +020085 instrumentation->MethodEnterEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +020086 shadow_frame.GetMethod(), 0);
87 }
88 }
Sebastien Hertz947ff082013-09-17 14:10:13 +020089 const Instruction* inst = Instruction::At(code_item->insns_ + dex_pc);
Sebastien Hertz8ece0502013-08-07 11:26:41 +020090
91 // Define handlers table.
92 static const void* handlersTable[kNumPackedOpcodes] = {
93#define INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) &&op_##code,
94#include "dex_instruction_list.h"
95 DEX_INSTRUCTION_LIST(INSTRUCTION_HANDLER)
96#undef DEX_INSTRUCTION_LIST
97#undef INSTRUCTION_HANDLER
98 };
99
100 static const void* instrumentationHandlersTable[kNumPackedOpcodes] = {
101#define INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) &&instrumentation_op_##code,
102#include "dex_instruction_list.h"
103 DEX_INSTRUCTION_LIST(INSTRUCTION_HANDLER)
104#undef DEX_INSTRUCTION_LIST
105#undef INSTRUCTION_HANDLER
106 };
107
108 const void** currentHandlersTable;
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +0200109 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200110
111 // Jump to first instruction.
112 ADVANCE(0);
113 UNREACHABLE_CODE_CHECK();
114
115 HANDLE_INSTRUCTION_START(NOP)
116 ADVANCE(1);
117 HANDLE_INSTRUCTION_END();
118
119 HANDLE_INSTRUCTION_START(MOVE)
120 shadow_frame.SetVReg(inst->VRegA_12x(),
121 shadow_frame.GetVReg(inst->VRegB_12x()));
122 ADVANCE(1);
123 HANDLE_INSTRUCTION_END();
124
125 HANDLE_INSTRUCTION_START(MOVE_FROM16)
126 shadow_frame.SetVReg(inst->VRegA_22x(),
127 shadow_frame.GetVReg(inst->VRegB_22x()));
128 ADVANCE(2);
129 HANDLE_INSTRUCTION_END();
130
131 HANDLE_INSTRUCTION_START(MOVE_16)
132 shadow_frame.SetVReg(inst->VRegA_32x(),
133 shadow_frame.GetVReg(inst->VRegB_32x()));
134 ADVANCE(3);
135 HANDLE_INSTRUCTION_END();
136
137 HANDLE_INSTRUCTION_START(MOVE_WIDE)
138 shadow_frame.SetVRegLong(inst->VRegA_12x(),
139 shadow_frame.GetVRegLong(inst->VRegB_12x()));
140 ADVANCE(1);
141 HANDLE_INSTRUCTION_END();
142
143 HANDLE_INSTRUCTION_START(MOVE_WIDE_FROM16)
144 shadow_frame.SetVRegLong(inst->VRegA_22x(),
145 shadow_frame.GetVRegLong(inst->VRegB_22x()));
146 ADVANCE(2);
147 HANDLE_INSTRUCTION_END();
148
149 HANDLE_INSTRUCTION_START(MOVE_WIDE_16)
150 shadow_frame.SetVRegLong(inst->VRegA_32x(),
151 shadow_frame.GetVRegLong(inst->VRegB_32x()));
152 ADVANCE(3);
153 HANDLE_INSTRUCTION_END();
154
155 HANDLE_INSTRUCTION_START(MOVE_OBJECT)
156 shadow_frame.SetVRegReference(inst->VRegA_12x(),
157 shadow_frame.GetVRegReference(inst->VRegB_12x()));
158 ADVANCE(1);
159 HANDLE_INSTRUCTION_END();
160
161 HANDLE_INSTRUCTION_START(MOVE_OBJECT_FROM16)
162 shadow_frame.SetVRegReference(inst->VRegA_22x(),
163 shadow_frame.GetVRegReference(inst->VRegB_22x()));
164 ADVANCE(2);
165 HANDLE_INSTRUCTION_END();
166
167 HANDLE_INSTRUCTION_START(MOVE_OBJECT_16)
168 shadow_frame.SetVRegReference(inst->VRegA_32x(),
169 shadow_frame.GetVRegReference(inst->VRegB_32x()));
170 ADVANCE(3);
171 HANDLE_INSTRUCTION_END();
172
173 HANDLE_INSTRUCTION_START(MOVE_RESULT)
174 shadow_frame.SetVReg(inst->VRegA_11x(), result_register.GetI());
175 ADVANCE(1);
176 HANDLE_INSTRUCTION_END();
177
178 HANDLE_INSTRUCTION_START(MOVE_RESULT_WIDE)
179 shadow_frame.SetVRegLong(inst->VRegA_11x(), result_register.GetJ());
180 ADVANCE(1);
181 HANDLE_INSTRUCTION_END();
182
183 HANDLE_INSTRUCTION_START(MOVE_RESULT_OBJECT)
184 shadow_frame.SetVRegReference(inst->VRegA_11x(), result_register.GetL());
185 ADVANCE(1);
186 HANDLE_INSTRUCTION_END();
187
188 HANDLE_INSTRUCTION_START(MOVE_EXCEPTION) {
189 Throwable* exception = self->GetException(NULL);
190 self->ClearException();
191 shadow_frame.SetVRegReference(inst->VRegA_11x(), exception);
192 ADVANCE(1);
193 }
194 HANDLE_INSTRUCTION_END();
195
196 HANDLE_INSTRUCTION_START(RETURN_VOID) {
197 JValue result;
Sebastien Hertz043036f2013-09-09 18:26:48 +0200198 if (do_access_check) {
199 // If access checks are required then the dex-to-dex compiler and analysis of
200 // whether the class has final fields hasn't been performed. Conservatively
201 // perform the memory barrier now.
202 ANDROID_MEMBAR_STORE();
203 }
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200204 if (UNLIKELY(self->TestAllFlags())) {
205 CheckSuspend(self);
206 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200207 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200208 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200209 shadow_frame.GetMethod(), dex_pc,
210 result);
211 }
212 return result;
213 }
214 HANDLE_INSTRUCTION_END();
215
216 HANDLE_INSTRUCTION_START(RETURN_VOID_BARRIER) {
217 ANDROID_MEMBAR_STORE();
218 JValue result;
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200219 if (UNLIKELY(self->TestAllFlags())) {
220 CheckSuspend(self);
221 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200222 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200223 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200224 shadow_frame.GetMethod(), dex_pc,
225 result);
226 }
227 return result;
228 }
229 HANDLE_INSTRUCTION_END();
230
231 HANDLE_INSTRUCTION_START(RETURN) {
232 JValue result;
233 result.SetJ(0);
234 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x()));
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200235 if (UNLIKELY(self->TestAllFlags())) {
236 CheckSuspend(self);
237 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200238 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200239 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200240 shadow_frame.GetMethod(), dex_pc,
241 result);
242 }
243 return result;
244 }
245 HANDLE_INSTRUCTION_END();
246
247 HANDLE_INSTRUCTION_START(RETURN_WIDE) {
248 JValue result;
249 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x()));
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200250 if (UNLIKELY(self->TestAllFlags())) {
251 CheckSuspend(self);
252 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200253 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200254 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200255 shadow_frame.GetMethod(), dex_pc,
256 result);
257 }
258 return result;
259 }
260 HANDLE_INSTRUCTION_END();
261
262 HANDLE_INSTRUCTION_START(RETURN_OBJECT) {
263 JValue result;
264 result.SetJ(0);
265 result.SetL(shadow_frame.GetVRegReference(inst->VRegA_11x()));
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200266 if (UNLIKELY(self->TestAllFlags())) {
267 CheckSuspend(self);
268 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200269 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200270 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200271 shadow_frame.GetMethod(), dex_pc,
272 result);
273 }
274 return result;
275 }
276 HANDLE_INSTRUCTION_END();
277
278 HANDLE_INSTRUCTION_START(CONST_4) {
279 uint32_t dst = inst->VRegA_11n();
280 int32_t val = inst->VRegB_11n();
281 shadow_frame.SetVReg(dst, val);
282 if (val == 0) {
283 shadow_frame.SetVRegReference(dst, NULL);
284 }
285 ADVANCE(1);
286 }
287 HANDLE_INSTRUCTION_END();
288
289 HANDLE_INSTRUCTION_START(CONST_16) {
290 uint32_t dst = inst->VRegA_21s();
291 int32_t val = inst->VRegB_21s();
292 shadow_frame.SetVReg(dst, val);
293 if (val == 0) {
294 shadow_frame.SetVRegReference(dst, NULL);
295 }
296 ADVANCE(2);
297 }
298 HANDLE_INSTRUCTION_END();
299
300 HANDLE_INSTRUCTION_START(CONST) {
301 uint32_t dst = inst->VRegA_31i();
302 int32_t val = inst->VRegB_31i();
303 shadow_frame.SetVReg(dst, val);
304 if (val == 0) {
305 shadow_frame.SetVRegReference(dst, NULL);
306 }
307 ADVANCE(3);
308 }
309 HANDLE_INSTRUCTION_END();
310
311 HANDLE_INSTRUCTION_START(CONST_HIGH16) {
312 uint32_t dst = inst->VRegA_21h();
313 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
314 shadow_frame.SetVReg(dst, val);
315 if (val == 0) {
316 shadow_frame.SetVRegReference(dst, NULL);
317 }
318 ADVANCE(2);
319 }
320 HANDLE_INSTRUCTION_END();
321
322 HANDLE_INSTRUCTION_START(CONST_WIDE_16)
323 shadow_frame.SetVRegLong(inst->VRegA_21s(), inst->VRegB_21s());
324 ADVANCE(2);
325 HANDLE_INSTRUCTION_END();
326
327 HANDLE_INSTRUCTION_START(CONST_WIDE_32)
328 shadow_frame.SetVRegLong(inst->VRegA_31i(), inst->VRegB_31i());
329 ADVANCE(3);
330 HANDLE_INSTRUCTION_END();
331
332 HANDLE_INSTRUCTION_START(CONST_WIDE)
333 shadow_frame.SetVRegLong(inst->VRegA_51l(), inst->VRegB_51l());
334 ADVANCE(5);
335 HANDLE_INSTRUCTION_END();
336
337 HANDLE_INSTRUCTION_START(CONST_WIDE_HIGH16)
338 shadow_frame.SetVRegLong(inst->VRegA_21h(),
339 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
340 ADVANCE(2);
341 HANDLE_INSTRUCTION_END();
342
343 HANDLE_INSTRUCTION_START(CONST_STRING) {
344 String* s = ResolveString(self, mh, inst->VRegB_21c());
345 if (UNLIKELY(s == NULL)) {
346 HANDLE_PENDING_EXCEPTION();
347 } else {
348 shadow_frame.SetVRegReference(inst->VRegA_21c(), s);
349 ADVANCE(2);
350 }
351 }
352 HANDLE_INSTRUCTION_END();
353
354 HANDLE_INSTRUCTION_START(CONST_STRING_JUMBO) {
355 String* s = ResolveString(self, mh, inst->VRegB_31c());
356 if (UNLIKELY(s == NULL)) {
357 HANDLE_PENDING_EXCEPTION();
358 } else {
359 shadow_frame.SetVRegReference(inst->VRegA_31c(), s);
360 ADVANCE(3);
361 }
362 }
363 HANDLE_INSTRUCTION_END();
364
365 HANDLE_INSTRUCTION_START(CONST_CLASS) {
366 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
367 self, false, do_access_check);
368 if (UNLIKELY(c == NULL)) {
369 HANDLE_PENDING_EXCEPTION();
370 } else {
371 shadow_frame.SetVRegReference(inst->VRegA_21c(), c);
372 ADVANCE(2);
373 }
374 }
375 HANDLE_INSTRUCTION_END();
376
377 HANDLE_INSTRUCTION_START(MONITOR_ENTER) {
378 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x());
379 if (UNLIKELY(obj == NULL)) {
380 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
381 HANDLE_PENDING_EXCEPTION();
382 } else {
383 DoMonitorEnter(self, obj);
384 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
385 }
386 }
387 HANDLE_INSTRUCTION_END();
388
389 HANDLE_INSTRUCTION_START(MONITOR_EXIT) {
390 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x());
391 if (UNLIKELY(obj == NULL)) {
392 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
393 HANDLE_PENDING_EXCEPTION();
394 } else {
395 DoMonitorExit(self, obj);
396 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
397 }
398 }
399 HANDLE_INSTRUCTION_END();
400
401 HANDLE_INSTRUCTION_START(CHECK_CAST) {
402 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
403 self, false, do_access_check);
404 if (UNLIKELY(c == NULL)) {
405 HANDLE_PENDING_EXCEPTION();
406 } else {
407 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c());
408 if (UNLIKELY(obj != NULL && !obj->InstanceOf(c))) {
409 ThrowClassCastException(c, obj->GetClass());
410 HANDLE_PENDING_EXCEPTION();
411 } else {
412 ADVANCE(2);
413 }
414 }
415 }
416 HANDLE_INSTRUCTION_END();
417
418 HANDLE_INSTRUCTION_START(INSTANCE_OF) {
419 Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(),
420 self, false, do_access_check);
421 if (UNLIKELY(c == NULL)) {
422 HANDLE_PENDING_EXCEPTION();
423 } else {
424 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c());
425 shadow_frame.SetVReg(inst->VRegA_22c(), (obj != NULL && obj->InstanceOf(c)) ? 1 : 0);
426 ADVANCE(2);
427 }
428 }
429 HANDLE_INSTRUCTION_END();
430
431 HANDLE_INSTRUCTION_START(ARRAY_LENGTH) {
432 Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x());
433 if (UNLIKELY(array == NULL)) {
434 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
435 HANDLE_PENDING_EXCEPTION();
436 } else {
437 shadow_frame.SetVReg(inst->VRegA_12x(), array->AsArray()->GetLength());
438 ADVANCE(1);
439 }
440 }
441 HANDLE_INSTRUCTION_END();
442
443 HANDLE_INSTRUCTION_START(NEW_INSTANCE) {
444 Object* obj = AllocObjectFromCode(inst->VRegB_21c(), shadow_frame.GetMethod(),
445 self, do_access_check);
446 if (UNLIKELY(obj == NULL)) {
447 HANDLE_PENDING_EXCEPTION();
448 } else {
449 shadow_frame.SetVRegReference(inst->VRegA_21c(), obj);
450 ADVANCE(2);
451 }
452 }
453 HANDLE_INSTRUCTION_END();
454
455 HANDLE_INSTRUCTION_START(NEW_ARRAY) {
456 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c());
457 Object* obj = AllocArrayFromCode(inst->VRegC_22c(), shadow_frame.GetMethod(),
458 length, self, do_access_check);
459 if (UNLIKELY(obj == NULL)) {
460 HANDLE_PENDING_EXCEPTION();
461 } else {
462 shadow_frame.SetVRegReference(inst->VRegA_22c(), obj);
463 ADVANCE(2);
464 }
465 }
466 HANDLE_INSTRUCTION_END();
467
468 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY) {
469 bool success = DoFilledNewArray<false, do_access_check>(inst, shadow_frame,
470 self, &result_register);
471 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
472 }
473 HANDLE_INSTRUCTION_END();
474
475 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY_RANGE) {
476 bool success = DoFilledNewArray<true, 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(FILL_ARRAY_DATA) {
483 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t());
484 if (UNLIKELY(obj == NULL)) {
485 ThrowNullPointerException(NULL, "null array in FILL_ARRAY_DATA");
486 HANDLE_PENDING_EXCEPTION();
487 } else {
488 Array* array = obj->AsArray();
489 DCHECK(array->IsArrayInstance() && !array->IsObjectArray());
490 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
491 const Instruction::ArrayDataPayload* payload =
492 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
493 if (UNLIKELY(static_cast<int32_t>(payload->element_count) > array->GetLength())) {
494 self->ThrowNewExceptionF(shadow_frame.GetCurrentLocationForThrow(),
495 "Ljava/lang/ArrayIndexOutOfBoundsException;",
496 "failed FILL_ARRAY_DATA; length=%d, index=%d",
497 array->GetLength(), payload->element_count);
498 HANDLE_PENDING_EXCEPTION();
499 } else {
500 uint32_t size_in_bytes = payload->element_count * payload->element_width;
501 memcpy(array->GetRawData(payload->element_width), payload->data, size_in_bytes);
502 ADVANCE(3);
503 }
504 }
505 }
506 HANDLE_INSTRUCTION_END();
507
508 HANDLE_INSTRUCTION_START(THROW) {
509 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x());
510 if (UNLIKELY(exception == NULL)) {
511 ThrowNullPointerException(NULL, "throw with null exception");
512 } else {
513 self->SetException(shadow_frame.GetCurrentLocationForThrow(), exception->AsThrowable());
514 }
515 HANDLE_PENDING_EXCEPTION();
516 }
517 HANDLE_INSTRUCTION_END();
518
519 HANDLE_INSTRUCTION_START(GOTO) {
520 int8_t offset = inst->VRegA_10t();
521 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200522 if (UNLIKELY(self->TestAllFlags())) {
523 CheckSuspend(self);
524 }
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +0200525 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200526 }
527 ADVANCE(offset);
528 }
529 HANDLE_INSTRUCTION_END();
530
531 HANDLE_INSTRUCTION_START(GOTO_16) {
532 int16_t offset = inst->VRegA_20t();
533 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200534 if (UNLIKELY(self->TestAllFlags())) {
535 CheckSuspend(self);
536 }
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +0200537 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200538 }
539 ADVANCE(offset);
540 }
541 HANDLE_INSTRUCTION_END();
542
543 HANDLE_INSTRUCTION_START(GOTO_32) {
544 int32_t offset = inst->VRegA_30t();
545 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200546 if (UNLIKELY(self->TestAllFlags())) {
547 CheckSuspend(self);
548 }
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +0200549 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200550 }
551 ADVANCE(offset);
552 }
553 HANDLE_INSTRUCTION_END();
554
555 HANDLE_INSTRUCTION_START(PACKED_SWITCH) {
556 int32_t offset = DoPackedSwitch(inst, shadow_frame);
557 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200558 if (UNLIKELY(self->TestAllFlags())) {
559 CheckSuspend(self);
560 }
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +0200561 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200562 }
563 ADVANCE(offset);
564 }
565 HANDLE_INSTRUCTION_END();
566
567 HANDLE_INSTRUCTION_START(SPARSE_SWITCH) {
568 int32_t offset = DoSparseSwitch(inst, shadow_frame);
569 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200570 if (UNLIKELY(self->TestAllFlags())) {
571 CheckSuspend(self);
572 }
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +0200573 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200574 }
575 ADVANCE(offset);
576 }
577 HANDLE_INSTRUCTION_END();
578
579 HANDLE_INSTRUCTION_START(CMPL_FLOAT) {
580 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
581 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
582 int32_t result;
583 if (val1 > val2) {
584 result = 1;
585 } else if (val1 == val2) {
586 result = 0;
587 } else {
588 result = -1;
589 }
590 shadow_frame.SetVReg(inst->VRegA_23x(), result);
591 ADVANCE(2);
592 }
593 HANDLE_INSTRUCTION_END();
594
595 HANDLE_INSTRUCTION_START(CMPG_FLOAT) {
596 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
597 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
598 int32_t result;
599 if (val1 < val2) {
600 result = -1;
601 } else if (val1 == val2) {
602 result = 0;
603 } else {
604 result = 1;
605 }
606 shadow_frame.SetVReg(inst->VRegA_23x(), result);
607 ADVANCE(2);
608 }
609 HANDLE_INSTRUCTION_END();
610
611 HANDLE_INSTRUCTION_START(CMPL_DOUBLE) {
612 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
613 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
614 int32_t result;
615 if (val1 > val2) {
616 result = 1;
617 } else if (val1 == val2) {
618 result = 0;
619 } else {
620 result = -1;
621 }
622 shadow_frame.SetVReg(inst->VRegA_23x(), result);
623 ADVANCE(2);
624 }
625 HANDLE_INSTRUCTION_END();
626
627 HANDLE_INSTRUCTION_START(CMPG_DOUBLE) {
628 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
629 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
630 int32_t result;
631 if (val1 < val2) {
632 result = -1;
633 } else if (val1 == val2) {
634 result = 0;
635 } else {
636 result = 1;
637 }
638 shadow_frame.SetVReg(inst->VRegA_23x(), result);
639 ADVANCE(2);
640 }
641 HANDLE_INSTRUCTION_END();
642
643 HANDLE_INSTRUCTION_START(CMP_LONG) {
644 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
645 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
646 int32_t result;
647 if (val1 > val2) {
648 result = 1;
649 } else if (val1 == val2) {
650 result = 0;
651 } else {
652 result = -1;
653 }
654 shadow_frame.SetVReg(inst->VRegA_23x(), result);
655 ADVANCE(2);
656 }
657 HANDLE_INSTRUCTION_END();
658
659 HANDLE_INSTRUCTION_START(IF_EQ) {
660 if (shadow_frame.GetVReg(inst->VRegA_22t()) == shadow_frame.GetVReg(inst->VRegB_22t())) {
661 int16_t offset = inst->VRegC_22t();
662 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200663 if (UNLIKELY(self->TestAllFlags())) {
664 CheckSuspend(self);
665 }
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +0200666 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200667 }
668 ADVANCE(offset);
669 } else {
670 ADVANCE(2);
671 }
672 }
673 HANDLE_INSTRUCTION_END();
674
675 HANDLE_INSTRUCTION_START(IF_NE) {
676 if (shadow_frame.GetVReg(inst->VRegA_22t()) != shadow_frame.GetVReg(inst->VRegB_22t())) {
677 int16_t offset = inst->VRegC_22t();
678 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200679 if (UNLIKELY(self->TestAllFlags())) {
680 CheckSuspend(self);
681 }
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +0200682 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200683 }
684 ADVANCE(offset);
685 } else {
686 ADVANCE(2);
687 }
688 }
689 HANDLE_INSTRUCTION_END();
690
691 HANDLE_INSTRUCTION_START(IF_LT) {
692 if (shadow_frame.GetVReg(inst->VRegA_22t()) < shadow_frame.GetVReg(inst->VRegB_22t())) {
693 int16_t offset = inst->VRegC_22t();
694 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200695 if (UNLIKELY(self->TestAllFlags())) {
696 CheckSuspend(self);
697 }
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +0200698 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200699 }
700 ADVANCE(offset);
701 } else {
702 ADVANCE(2);
703 }
704 }
705 HANDLE_INSTRUCTION_END();
706
707 HANDLE_INSTRUCTION_START(IF_GE) {
708 if (shadow_frame.GetVReg(inst->VRegA_22t()) >= shadow_frame.GetVReg(inst->VRegB_22t())) {
709 int16_t offset = inst->VRegC_22t();
710 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200711 if (UNLIKELY(self->TestAllFlags())) {
712 CheckSuspend(self);
713 }
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +0200714 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200715 }
716 ADVANCE(offset);
717 } else {
718 ADVANCE(2);
719 }
720 }
721 HANDLE_INSTRUCTION_END();
722
723 HANDLE_INSTRUCTION_START(IF_GT) {
724 if (shadow_frame.GetVReg(inst->VRegA_22t()) > shadow_frame.GetVReg(inst->VRegB_22t())) {
725 int16_t offset = inst->VRegC_22t();
726 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200727 if (UNLIKELY(self->TestAllFlags())) {
728 CheckSuspend(self);
729 }
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +0200730 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200731 }
732 ADVANCE(offset);
733 } else {
734 ADVANCE(2);
735 }
736 }
737 HANDLE_INSTRUCTION_END();
738
739 HANDLE_INSTRUCTION_START(IF_LE) {
740 if (shadow_frame.GetVReg(inst->VRegA_22t()) <= shadow_frame.GetVReg(inst->VRegB_22t())) {
741 int16_t offset = inst->VRegC_22t();
742 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200743 if (UNLIKELY(self->TestAllFlags())) {
744 CheckSuspend(self);
745 }
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +0200746 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200747 }
748 ADVANCE(offset);
749 } else {
750 ADVANCE(2);
751 }
752 }
753 HANDLE_INSTRUCTION_END();
754
755 HANDLE_INSTRUCTION_START(IF_EQZ) {
756 if (shadow_frame.GetVReg(inst->VRegA_21t()) == 0) {
757 int16_t offset = inst->VRegB_21t();
758 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200759 if (UNLIKELY(self->TestAllFlags())) {
760 CheckSuspend(self);
761 }
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +0200762 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200763 }
764 ADVANCE(offset);
765 } else {
766 ADVANCE(2);
767 }
768 }
769 HANDLE_INSTRUCTION_END();
770
771 HANDLE_INSTRUCTION_START(IF_NEZ) {
772 if (shadow_frame.GetVReg(inst->VRegA_21t()) != 0) {
773 int16_t offset = inst->VRegB_21t();
774 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200775 if (UNLIKELY(self->TestAllFlags())) {
776 CheckSuspend(self);
777 }
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +0200778 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200779 }
780 ADVANCE(offset);
781 } else {
782 ADVANCE(2);
783 }
784 }
785 HANDLE_INSTRUCTION_END();
786
787 HANDLE_INSTRUCTION_START(IF_LTZ) {
788 if (shadow_frame.GetVReg(inst->VRegA_21t()) < 0) {
789 int16_t offset = inst->VRegB_21t();
790 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200791 if (UNLIKELY(self->TestAllFlags())) {
792 CheckSuspend(self);
793 }
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +0200794 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200795 }
796 ADVANCE(offset);
797 } else {
798 ADVANCE(2);
799 }
800 }
801 HANDLE_INSTRUCTION_END();
802
803 HANDLE_INSTRUCTION_START(IF_GEZ) {
804 if (shadow_frame.GetVReg(inst->VRegA_21t()) >= 0) {
805 int16_t offset = inst->VRegB_21t();
806 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200807 if (UNLIKELY(self->TestAllFlags())) {
808 CheckSuspend(self);
809 }
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +0200810 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200811 }
812 ADVANCE(offset);
813 } else {
814 ADVANCE(2);
815 }
816 }
817 HANDLE_INSTRUCTION_END();
818
819 HANDLE_INSTRUCTION_START(IF_GTZ) {
820 if (shadow_frame.GetVReg(inst->VRegA_21t()) > 0) {
821 int16_t offset = inst->VRegB_21t();
822 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200823 if (UNLIKELY(self->TestAllFlags())) {
824 CheckSuspend(self);
825 }
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +0200826 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200827 }
828 ADVANCE(offset);
829 } else {
830 ADVANCE(2);
831 }
832 }
833 HANDLE_INSTRUCTION_END();
834
835 HANDLE_INSTRUCTION_START(IF_LEZ) {
836 if (shadow_frame.GetVReg(inst->VRegA_21t()) <= 0) {
837 int16_t offset = inst->VRegB_21t();
838 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200839 if (UNLIKELY(self->TestAllFlags())) {
840 CheckSuspend(self);
841 }
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +0200842 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200843 }
844 ADVANCE(offset);
845 } else {
846 ADVANCE(2);
847 }
848 }
849 HANDLE_INSTRUCTION_END();
850
851 HANDLE_INSTRUCTION_START(AGET_BOOLEAN) {
852 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
853 if (UNLIKELY(a == NULL)) {
854 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
855 HANDLE_PENDING_EXCEPTION();
856 } else {
857 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
858 BooleanArray* array = a->AsBooleanArray();
859 if (LIKELY(array->IsValidIndex(index))) {
860 shadow_frame.SetVReg(inst->VRegA_23x(), array->GetData()[index]);
861 ADVANCE(2);
862 } else {
863 HANDLE_PENDING_EXCEPTION();
864 }
865 }
866 }
867 HANDLE_INSTRUCTION_END();
868
869 HANDLE_INSTRUCTION_START(AGET_BYTE) {
870 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
871 if (UNLIKELY(a == NULL)) {
872 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
873 HANDLE_PENDING_EXCEPTION();
874 } else {
875 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
876 ByteArray* array = a->AsByteArray();
877 if (LIKELY(array->IsValidIndex(index))) {
878 shadow_frame.SetVReg(inst->VRegA_23x(), array->GetData()[index]);
879 ADVANCE(2);
880 } else {
881 HANDLE_PENDING_EXCEPTION();
882 }
883 }
884 }
885 HANDLE_INSTRUCTION_END();
886
887 HANDLE_INSTRUCTION_START(AGET_CHAR) {
888 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
889 if (UNLIKELY(a == NULL)) {
890 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
891 HANDLE_PENDING_EXCEPTION();
892 } else {
893 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
894 CharArray* array = a->AsCharArray();
895 if (LIKELY(array->IsValidIndex(index))) {
896 shadow_frame.SetVReg(inst->VRegA_23x(), array->GetData()[index]);
897 ADVANCE(2);
898 } else {
899 HANDLE_PENDING_EXCEPTION();
900 }
901 }
902 }
903 HANDLE_INSTRUCTION_END();
904
905 HANDLE_INSTRUCTION_START(AGET_SHORT) {
906 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
907 if (UNLIKELY(a == NULL)) {
908 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
909 HANDLE_PENDING_EXCEPTION();
910 } else {
911 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
912 ShortArray* array = a->AsShortArray();
913 if (LIKELY(array->IsValidIndex(index))) {
914 shadow_frame.SetVReg(inst->VRegA_23x(), array->GetData()[index]);
915 ADVANCE(2);
916 } else {
917 HANDLE_PENDING_EXCEPTION();
918 }
919 }
920 }
921 HANDLE_INSTRUCTION_END();
922
923 HANDLE_INSTRUCTION_START(AGET) {
924 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
925 if (UNLIKELY(a == NULL)) {
926 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
927 HANDLE_PENDING_EXCEPTION();
928 } else {
929 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
930 IntArray* array = a->AsIntArray();
931 if (LIKELY(array->IsValidIndex(index))) {
932 shadow_frame.SetVReg(inst->VRegA_23x(), array->GetData()[index]);
933 ADVANCE(2);
934 } else {
935 HANDLE_PENDING_EXCEPTION();
936 }
937 }
938 }
939 HANDLE_INSTRUCTION_END();
940
941 HANDLE_INSTRUCTION_START(AGET_WIDE) {
942 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
943 if (UNLIKELY(a == NULL)) {
944 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
945 HANDLE_PENDING_EXCEPTION();
946 } else {
947 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
948 LongArray* array = a->AsLongArray();
949 if (LIKELY(array->IsValidIndex(index))) {
950 shadow_frame.SetVRegLong(inst->VRegA_23x(), array->GetData()[index]);
951 ADVANCE(2);
952 } else {
953 HANDLE_PENDING_EXCEPTION();
954 }
955 }
956 }
957 HANDLE_INSTRUCTION_END();
958
959 HANDLE_INSTRUCTION_START(AGET_OBJECT) {
960 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
961 if (UNLIKELY(a == NULL)) {
962 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
963 HANDLE_PENDING_EXCEPTION();
964 } else {
965 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
966 ObjectArray<Object>* array = a->AsObjectArray<Object>();
967 if (LIKELY(array->IsValidIndex(index))) {
968 shadow_frame.SetVRegReference(inst->VRegA_23x(), array->GetWithoutChecks(index));
969 ADVANCE(2);
970 } else {
971 HANDLE_PENDING_EXCEPTION();
972 }
973 }
974 }
975 HANDLE_INSTRUCTION_END();
976
977 HANDLE_INSTRUCTION_START(APUT_BOOLEAN) {
978 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
979 if (UNLIKELY(a == NULL)) {
980 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
981 HANDLE_PENDING_EXCEPTION();
982 } else {
983 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x());
984 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
985 BooleanArray* array = a->AsBooleanArray();
986 if (LIKELY(array->IsValidIndex(index))) {
987 array->GetData()[index] = val;
988 ADVANCE(2);
989 } else {
990 HANDLE_PENDING_EXCEPTION();
991 }
992 }
993 }
994 HANDLE_INSTRUCTION_END();
995
996 HANDLE_INSTRUCTION_START(APUT_BYTE) {
997 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
998 if (UNLIKELY(a == NULL)) {
999 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
1000 HANDLE_PENDING_EXCEPTION();
1001 } else {
1002 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x());
1003 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1004 ByteArray* array = a->AsByteArray();
1005 if (LIKELY(array->IsValidIndex(index))) {
1006 array->GetData()[index] = val;
1007 ADVANCE(2);
1008 } else {
1009 HANDLE_PENDING_EXCEPTION();
1010 }
1011 }
1012 }
1013 HANDLE_INSTRUCTION_END();
1014
1015 HANDLE_INSTRUCTION_START(APUT_CHAR) {
1016 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1017 if (UNLIKELY(a == NULL)) {
1018 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
1019 HANDLE_PENDING_EXCEPTION();
1020 } else {
1021 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x());
1022 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1023 CharArray* array = a->AsCharArray();
1024 if (LIKELY(array->IsValidIndex(index))) {
1025 array->GetData()[index] = val;
1026 ADVANCE(2);
1027 } else {
1028 HANDLE_PENDING_EXCEPTION();
1029 }
1030 }
1031 }
1032 HANDLE_INSTRUCTION_END();
1033
1034 HANDLE_INSTRUCTION_START(APUT_SHORT) {
1035 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1036 if (UNLIKELY(a == NULL)) {
1037 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
1038 HANDLE_PENDING_EXCEPTION();
1039 } else {
1040 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x());
1041 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1042 ShortArray* array = a->AsShortArray();
1043 if (LIKELY(array->IsValidIndex(index))) {
1044 array->GetData()[index] = val;
1045 ADVANCE(2);
1046 } else {
1047 HANDLE_PENDING_EXCEPTION();
1048 }
1049 }
1050 }
1051 HANDLE_INSTRUCTION_END();
1052
1053 HANDLE_INSTRUCTION_START(APUT) {
1054 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1055 if (UNLIKELY(a == NULL)) {
1056 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
1057 HANDLE_PENDING_EXCEPTION();
1058 } else {
1059 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x());
1060 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1061 IntArray* array = a->AsIntArray();
1062 if (LIKELY(array->IsValidIndex(index))) {
1063 array->GetData()[index] = val;
1064 ADVANCE(2);
1065 } else {
1066 HANDLE_PENDING_EXCEPTION();
1067 }
1068 }
1069 }
1070 HANDLE_INSTRUCTION_END();
1071
1072 HANDLE_INSTRUCTION_START(APUT_WIDE) {
1073 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1074 if (UNLIKELY(a == NULL)) {
1075 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
1076 HANDLE_PENDING_EXCEPTION();
1077 } else {
1078 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x());
1079 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1080 LongArray* array = a->AsLongArray();
1081 if (LIKELY(array->IsValidIndex(index))) {
1082 array->GetData()[index] = val;
1083 ADVANCE(2);
1084 } else {
1085 HANDLE_PENDING_EXCEPTION();
1086 }
1087 }
1088 }
1089 HANDLE_INSTRUCTION_END();
1090
1091 HANDLE_INSTRUCTION_START(APUT_OBJECT) {
1092 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1093 if (UNLIKELY(a == NULL)) {
1094 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
1095 HANDLE_PENDING_EXCEPTION();
1096 } else {
1097 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1098 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x());
1099 ObjectArray<Object>* array = a->AsObjectArray<Object>();
1100 if (LIKELY(array->IsValidIndex(index) && array->CheckAssignable(val))) {
1101 array->SetWithoutChecks(index, val);
1102 ADVANCE(2);
1103 } else {
1104 HANDLE_PENDING_EXCEPTION();
1105 }
1106 }
1107 }
1108 HANDLE_INSTRUCTION_END();
1109
1110 HANDLE_INSTRUCTION_START(IGET_BOOLEAN) {
1111 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst);
1112 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1113 }
1114 HANDLE_INSTRUCTION_END();
1115
1116 HANDLE_INSTRUCTION_START(IGET_BYTE) {
1117 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst);
1118 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1119 }
1120 HANDLE_INSTRUCTION_END();
1121
1122 HANDLE_INSTRUCTION_START(IGET_CHAR) {
1123 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst);
1124 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1125 }
1126 HANDLE_INSTRUCTION_END();
1127
1128 HANDLE_INSTRUCTION_START(IGET_SHORT) {
1129 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst);
1130 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1131 }
1132 HANDLE_INSTRUCTION_END();
1133
1134 HANDLE_INSTRUCTION_START(IGET) {
1135 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst);
1136 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1137 }
1138 HANDLE_INSTRUCTION_END();
1139
1140 HANDLE_INSTRUCTION_START(IGET_WIDE) {
1141 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst);
1142 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1143 }
1144 HANDLE_INSTRUCTION_END();
1145
1146 HANDLE_INSTRUCTION_START(IGET_OBJECT) {
1147 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst);
1148 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1149 }
1150 HANDLE_INSTRUCTION_END();
1151
1152 HANDLE_INSTRUCTION_START(IGET_QUICK) {
1153 bool success = DoIGetQuick<Primitive::kPrimInt>(self, shadow_frame, inst);
1154 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1155 }
1156 HANDLE_INSTRUCTION_END();
1157
1158 HANDLE_INSTRUCTION_START(IGET_WIDE_QUICK) {
1159 bool success = DoIGetQuick<Primitive::kPrimLong>(self, shadow_frame, inst);
1160 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1161 }
1162 HANDLE_INSTRUCTION_END();
1163
1164 HANDLE_INSTRUCTION_START(IGET_OBJECT_QUICK) {
1165 bool success = DoIGetQuick<Primitive::kPrimNot>(self, shadow_frame, inst);
1166 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1167 }
1168 HANDLE_INSTRUCTION_END();
1169
1170 HANDLE_INSTRUCTION_START(SGET_BOOLEAN) {
1171 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst);
1172 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1173 }
1174 HANDLE_INSTRUCTION_END();
1175
1176 HANDLE_INSTRUCTION_START(SGET_BYTE) {
1177 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst);
1178 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1179 }
1180 HANDLE_INSTRUCTION_END();
1181
1182 HANDLE_INSTRUCTION_START(SGET_CHAR) {
1183 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst);
1184 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1185 }
1186 HANDLE_INSTRUCTION_END();
1187
1188 HANDLE_INSTRUCTION_START(SGET_SHORT) {
1189 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst);
1190 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1191 }
1192 HANDLE_INSTRUCTION_END();
1193
1194 HANDLE_INSTRUCTION_START(SGET) {
1195 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst);
1196 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1197 }
1198 HANDLE_INSTRUCTION_END();
1199
1200 HANDLE_INSTRUCTION_START(SGET_WIDE) {
1201 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst);
1202 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1203 }
1204 HANDLE_INSTRUCTION_END();
1205
1206 HANDLE_INSTRUCTION_START(SGET_OBJECT) {
1207 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst);
1208 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1209 }
1210 HANDLE_INSTRUCTION_END();
1211
1212 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN) {
1213 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst);
1214 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1215 }
1216 HANDLE_INSTRUCTION_END();
1217
1218 HANDLE_INSTRUCTION_START(IPUT_BYTE) {
1219 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst);
1220 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1221 }
1222 HANDLE_INSTRUCTION_END();
1223
1224 HANDLE_INSTRUCTION_START(IPUT_CHAR) {
1225 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst);
1226 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1227 }
1228 HANDLE_INSTRUCTION_END();
1229
1230 HANDLE_INSTRUCTION_START(IPUT_SHORT) {
1231 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst);
1232 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1233 }
1234 HANDLE_INSTRUCTION_END();
1235
1236 HANDLE_INSTRUCTION_START(IPUT) {
1237 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst);
1238 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1239 }
1240 HANDLE_INSTRUCTION_END();
1241
1242 HANDLE_INSTRUCTION_START(IPUT_WIDE) {
1243 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst);
1244 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1245 }
1246 HANDLE_INSTRUCTION_END();
1247
1248 HANDLE_INSTRUCTION_START(IPUT_OBJECT) {
1249 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst);
1250 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1251 }
1252 HANDLE_INSTRUCTION_END();
1253
1254 HANDLE_INSTRUCTION_START(IPUT_QUICK) {
1255 bool success = DoIPutQuick<Primitive::kPrimInt>(self, shadow_frame, inst);
1256 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1257 }
1258 HANDLE_INSTRUCTION_END();
1259
1260 HANDLE_INSTRUCTION_START(IPUT_WIDE_QUICK) {
1261 bool success = DoIPutQuick<Primitive::kPrimLong>(self, shadow_frame, inst);
1262 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1263 }
1264 HANDLE_INSTRUCTION_END();
1265
1266 HANDLE_INSTRUCTION_START(IPUT_OBJECT_QUICK) {
1267 bool success = DoIPutQuick<Primitive::kPrimNot>(self, shadow_frame, inst);
1268 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1269 }
1270 HANDLE_INSTRUCTION_END();
1271
1272 HANDLE_INSTRUCTION_START(SPUT_BOOLEAN) {
1273 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst);
1274 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1275 }
1276 HANDLE_INSTRUCTION_END();
1277
1278 HANDLE_INSTRUCTION_START(SPUT_BYTE) {
1279 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst);
1280 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1281 }
1282 HANDLE_INSTRUCTION_END();
1283
1284 HANDLE_INSTRUCTION_START(SPUT_CHAR) {
1285 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst);
1286 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1287 }
1288 HANDLE_INSTRUCTION_END();
1289
1290 HANDLE_INSTRUCTION_START(SPUT_SHORT) {
1291 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst);
1292 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1293 }
1294 HANDLE_INSTRUCTION_END();
1295
1296 HANDLE_INSTRUCTION_START(SPUT) {
1297 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst);
1298 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1299 }
1300 HANDLE_INSTRUCTION_END();
1301
1302 HANDLE_INSTRUCTION_START(SPUT_WIDE) {
1303 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst);
1304 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1305 }
1306 HANDLE_INSTRUCTION_END();
1307
1308 HANDLE_INSTRUCTION_START(SPUT_OBJECT) {
1309 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst);
1310 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1311 }
1312 HANDLE_INSTRUCTION_END();
1313
1314 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL) {
1315 bool success = DoInvoke<kVirtual, false, do_access_check>(self, shadow_frame, inst, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001316 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001317 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1318 }
1319 HANDLE_INSTRUCTION_END();
1320
1321 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE) {
1322 bool success = DoInvoke<kVirtual, true, 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_SUPER) {
1329 bool success = DoInvoke<kSuper, false, 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_RANGE) {
1336 bool success = DoInvoke<kSuper, true, 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_DIRECT) {
1343 bool success = DoInvoke<kDirect, false, 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_RANGE) {
1350 bool success = DoInvoke<kDirect, true, 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_INTERFACE) {
1357 bool success = DoInvoke<kInterface, false, 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_RANGE) {
1364 bool success = DoInvoke<kInterface, true, 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_STATIC) {
1371 bool success = DoInvoke<kStatic, false, 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_RANGE) {
1378 bool success = DoInvoke<kStatic, true, 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_VIRTUAL_QUICK) {
1385 bool success = DoInvokeVirtualQuick<false>(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_RANGE_QUICK) {
1392 bool success = DoInvokeVirtualQuick<true>(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(NEG_INT)
1399 shadow_frame.SetVReg(inst->VRegA_12x(), -shadow_frame.GetVReg(inst->VRegB_12x()));
1400 ADVANCE(1);
1401 HANDLE_INSTRUCTION_END();
1402
1403 HANDLE_INSTRUCTION_START(NOT_INT)
1404 shadow_frame.SetVReg(inst->VRegA_12x(), ~shadow_frame.GetVReg(inst->VRegB_12x()));
1405 ADVANCE(1);
1406 HANDLE_INSTRUCTION_END();
1407
1408 HANDLE_INSTRUCTION_START(NEG_LONG)
1409 shadow_frame.SetVRegLong(inst->VRegA_12x(), -shadow_frame.GetVRegLong(inst->VRegB_12x()));
1410 ADVANCE(1);
1411 HANDLE_INSTRUCTION_END();
1412
1413 HANDLE_INSTRUCTION_START(NOT_LONG)
1414 shadow_frame.SetVRegLong(inst->VRegA_12x(), ~shadow_frame.GetVRegLong(inst->VRegB_12x()));
1415 ADVANCE(1);
1416 HANDLE_INSTRUCTION_END();
1417
1418 HANDLE_INSTRUCTION_START(NEG_FLOAT)
1419 shadow_frame.SetVRegFloat(inst->VRegA_12x(), -shadow_frame.GetVRegFloat(inst->VRegB_12x()));
1420 ADVANCE(1);
1421 HANDLE_INSTRUCTION_END();
1422
1423 HANDLE_INSTRUCTION_START(NEG_DOUBLE)
1424 shadow_frame.SetVRegDouble(inst->VRegA_12x(), -shadow_frame.GetVRegDouble(inst->VRegB_12x()));
1425 ADVANCE(1);
1426 HANDLE_INSTRUCTION_END();
1427
1428 HANDLE_INSTRUCTION_START(INT_TO_LONG)
1429 shadow_frame.SetVRegLong(inst->VRegA_12x(), shadow_frame.GetVReg(inst->VRegB_12x()));
1430 ADVANCE(1);
1431 HANDLE_INSTRUCTION_END();
1432
1433 HANDLE_INSTRUCTION_START(INT_TO_FLOAT)
1434 shadow_frame.SetVRegFloat(inst->VRegA_12x(), shadow_frame.GetVReg(inst->VRegB_12x()));
1435 ADVANCE(1);
1436 HANDLE_INSTRUCTION_END();
1437
1438 HANDLE_INSTRUCTION_START(INT_TO_DOUBLE)
1439 shadow_frame.SetVRegDouble(inst->VRegA_12x(), shadow_frame.GetVReg(inst->VRegB_12x()));
1440 ADVANCE(1);
1441 HANDLE_INSTRUCTION_END();
1442
1443 HANDLE_INSTRUCTION_START(LONG_TO_INT)
1444 shadow_frame.SetVReg(inst->VRegA_12x(), shadow_frame.GetVRegLong(inst->VRegB_12x()));
1445 ADVANCE(1);
1446 HANDLE_INSTRUCTION_END();
1447
1448 HANDLE_INSTRUCTION_START(LONG_TO_FLOAT)
1449 shadow_frame.SetVRegFloat(inst->VRegA_12x(), shadow_frame.GetVRegLong(inst->VRegB_12x()));
1450 ADVANCE(1);
1451 HANDLE_INSTRUCTION_END();
1452
1453 HANDLE_INSTRUCTION_START(LONG_TO_DOUBLE)
1454 shadow_frame.SetVRegDouble(inst->VRegA_12x(), shadow_frame.GetVRegLong(inst->VRegB_12x()));
1455 ADVANCE(1);
1456 HANDLE_INSTRUCTION_END();
1457
1458 HANDLE_INSTRUCTION_START(FLOAT_TO_INT) {
1459 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x());
1460 int32_t result;
1461 if (val != val) {
1462 result = 0;
1463 } else if (val > static_cast<float>(kMaxInt)) {
1464 result = kMaxInt;
1465 } else if (val < static_cast<float>(kMinInt)) {
1466 result = kMinInt;
1467 } else {
1468 result = val;
1469 }
1470 shadow_frame.SetVReg(inst->VRegA_12x(), result);
1471 ADVANCE(1);
1472 }
1473 HANDLE_INSTRUCTION_END();
1474
1475 HANDLE_INSTRUCTION_START(FLOAT_TO_LONG) {
1476 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x());
1477 int64_t result;
1478 if (val != val) {
1479 result = 0;
1480 } else if (val > static_cast<float>(kMaxLong)) {
1481 result = kMaxLong;
1482 } else if (val < static_cast<float>(kMinLong)) {
1483 result = kMinLong;
1484 } else {
1485 result = val;
1486 }
1487 shadow_frame.SetVRegLong(inst->VRegA_12x(), result);
1488 ADVANCE(1);
1489 }
1490 HANDLE_INSTRUCTION_END();
1491
1492 HANDLE_INSTRUCTION_START(FLOAT_TO_DOUBLE)
1493 shadow_frame.SetVRegDouble(inst->VRegA_12x(), shadow_frame.GetVRegFloat(inst->VRegB_12x()));
1494 ADVANCE(1);
1495 HANDLE_INSTRUCTION_END();
1496
1497 HANDLE_INSTRUCTION_START(DOUBLE_TO_INT) {
1498 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x());
1499 int32_t result;
1500 if (val != val) {
1501 result = 0;
1502 } else if (val > static_cast<double>(kMaxInt)) {
1503 result = kMaxInt;
1504 } else if (val < static_cast<double>(kMinInt)) {
1505 result = kMinInt;
1506 } else {
1507 result = val;
1508 }
1509 shadow_frame.SetVReg(inst->VRegA_12x(), result);
1510 ADVANCE(1);
1511 }
1512 HANDLE_INSTRUCTION_END();
1513
1514 HANDLE_INSTRUCTION_START(DOUBLE_TO_LONG) {
1515 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x());
1516 int64_t result;
1517 if (val != val) {
1518 result = 0;
1519 } else if (val > static_cast<double>(kMaxLong)) {
1520 result = kMaxLong;
1521 } else if (val < static_cast<double>(kMinLong)) {
1522 result = kMinLong;
1523 } else {
1524 result = val;
1525 }
1526 shadow_frame.SetVRegLong(inst->VRegA_12x(), result);
1527 ADVANCE(1);
1528 }
1529 HANDLE_INSTRUCTION_END();
1530
1531 HANDLE_INSTRUCTION_START(DOUBLE_TO_FLOAT)
1532 shadow_frame.SetVRegFloat(inst->VRegA_12x(), shadow_frame.GetVRegDouble(inst->VRegB_12x()));
1533 ADVANCE(1);
1534 HANDLE_INSTRUCTION_END();
1535
1536 HANDLE_INSTRUCTION_START(INT_TO_BYTE)
1537 shadow_frame.SetVReg(inst->VRegA_12x(),
1538 static_cast<int8_t>(shadow_frame.GetVReg(inst->VRegB_12x())));
1539 ADVANCE(1);
1540 HANDLE_INSTRUCTION_END();
1541
1542 HANDLE_INSTRUCTION_START(INT_TO_CHAR)
1543 shadow_frame.SetVReg(inst->VRegA_12x(),
1544 static_cast<uint16_t>(shadow_frame.GetVReg(inst->VRegB_12x())));
1545 ADVANCE(1);
1546 HANDLE_INSTRUCTION_END();
1547
1548 HANDLE_INSTRUCTION_START(INT_TO_SHORT)
1549 shadow_frame.SetVReg(inst->VRegA_12x(),
1550 static_cast<int16_t>(shadow_frame.GetVReg(inst->VRegB_12x())));
1551 ADVANCE(1);
1552 HANDLE_INSTRUCTION_END();
1553
1554 HANDLE_INSTRUCTION_START(ADD_INT)
1555 shadow_frame.SetVReg(inst->VRegA_23x(),
1556 shadow_frame.GetVReg(inst->VRegB_23x()) +
1557 shadow_frame.GetVReg(inst->VRegC_23x()));
1558 ADVANCE(2);
1559 HANDLE_INSTRUCTION_END();
1560
1561 HANDLE_INSTRUCTION_START(SUB_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(MUL_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(DIV_INT) {
1576 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(),
1577 shadow_frame.GetVReg(inst->VRegB_23x()),
1578 shadow_frame.GetVReg(inst->VRegC_23x()));
1579 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1580 }
1581 HANDLE_INSTRUCTION_END();
1582
1583 HANDLE_INSTRUCTION_START(REM_INT) {
1584 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(),
1585 shadow_frame.GetVReg(inst->VRegB_23x()),
1586 shadow_frame.GetVReg(inst->VRegC_23x()));
1587 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1588 }
1589 HANDLE_INSTRUCTION_END();
1590
1591 HANDLE_INSTRUCTION_START(SHL_INT)
1592 shadow_frame.SetVReg(inst->VRegA_23x(),
1593 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1594 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1595 ADVANCE(2);
1596 HANDLE_INSTRUCTION_END();
1597
1598 HANDLE_INSTRUCTION_START(SHR_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(USHR_INT)
1606 shadow_frame.SetVReg(inst->VRegA_23x(),
1607 static_cast<uint32_t>(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(AND_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(OR_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(XOR_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(ADD_LONG)
1634 shadow_frame.SetVRegLong(inst->VRegA_23x(),
1635 shadow_frame.GetVRegLong(inst->VRegB_23x()) +
1636 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1637 ADVANCE(2);
1638 HANDLE_INSTRUCTION_END();
1639
1640 HANDLE_INSTRUCTION_START(SUB_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(MUL_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(DIV_LONG) {
1655 bool success = DoLongDivide(shadow_frame, inst->VRegA_23x(),
1656 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1657 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1658 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1659 }
1660 HANDLE_INSTRUCTION_END();
1661
1662 HANDLE_INSTRUCTION_START(REM_LONG) {
1663 bool success = DoLongRemainder(shadow_frame, inst->VRegA_23x(),
1664 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1665 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1666 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1667 }
1668 HANDLE_INSTRUCTION_END();
1669
1670 HANDLE_INSTRUCTION_START(AND_LONG)
1671 shadow_frame.SetVRegLong(inst->VRegA_23x(),
1672 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1673 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1674 ADVANCE(2);
1675 HANDLE_INSTRUCTION_END();
1676
1677 HANDLE_INSTRUCTION_START(OR_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(XOR_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(SHL_LONG)
1692 shadow_frame.SetVRegLong(inst->VRegA_23x(),
1693 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1694 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1695 ADVANCE(2);
1696 HANDLE_INSTRUCTION_END();
1697
1698 HANDLE_INSTRUCTION_START(SHR_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(USHR_LONG)
1706 shadow_frame.SetVRegLong(inst->VRegA_23x(),
1707 static_cast<uint64_t>(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(ADD_FLOAT)
1713 shadow_frame.SetVRegFloat(inst->VRegA_23x(),
1714 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1715 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1716 ADVANCE(2);
1717 HANDLE_INSTRUCTION_END();
1718
1719 HANDLE_INSTRUCTION_START(SUB_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(MUL_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(DIV_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(REM_FLOAT)
1741 shadow_frame.SetVRegFloat(inst->VRegA_23x(),
1742 fmodf(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(ADD_DOUBLE)
1748 shadow_frame.SetVRegDouble(inst->VRegA_23x(),
1749 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1750 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1751 ADVANCE(2);
1752 HANDLE_INSTRUCTION_END();
1753
1754 HANDLE_INSTRUCTION_START(SUB_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(MUL_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(DIV_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(REM_DOUBLE)
1776 shadow_frame.SetVRegDouble(inst->VRegA_23x(),
1777 fmod(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(ADD_INT_2ADDR) {
1783 uint32_t vregA = inst->VRegA_12x();
1784 shadow_frame.SetVReg(vregA,
1785 shadow_frame.GetVReg(vregA) +
1786 shadow_frame.GetVReg(inst->VRegB_12x()));
1787 ADVANCE(1);
1788 }
1789 HANDLE_INSTRUCTION_END();
1790
1791 HANDLE_INSTRUCTION_START(SUB_INT_2ADDR) {
1792 uint32_t vregA = inst->VRegA_12x();
1793 shadow_frame.SetVReg(vregA,
1794 shadow_frame.GetVReg(vregA) -
1795 shadow_frame.GetVReg(inst->VRegB_12x()));
1796 ADVANCE(1);
1797 }
1798 HANDLE_INSTRUCTION_END();
1799
1800 HANDLE_INSTRUCTION_START(MUL_INT_2ADDR) {
1801 uint32_t vregA = inst->VRegA_12x();
1802 shadow_frame.SetVReg(vregA,
1803 shadow_frame.GetVReg(vregA) *
1804 shadow_frame.GetVReg(inst->VRegB_12x()));
1805 ADVANCE(1);
1806 }
1807 HANDLE_INSTRUCTION_END();
1808
1809 HANDLE_INSTRUCTION_START(DIV_INT_2ADDR) {
1810 uint32_t vregA = inst->VRegA_12x();
1811 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
1812 shadow_frame.GetVReg(inst->VRegB_12x()));
1813 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
1814 }
1815 HANDLE_INSTRUCTION_END();
1816
1817 HANDLE_INSTRUCTION_START(REM_INT_2ADDR) {
1818 uint32_t vregA = inst->VRegA_12x();
1819 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
1820 shadow_frame.GetVReg(inst->VRegB_12x()));
1821 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
1822 }
1823 HANDLE_INSTRUCTION_END();
1824
1825 HANDLE_INSTRUCTION_START(SHL_INT_2ADDR) {
1826 uint32_t vregA = inst->VRegA_12x();
1827 shadow_frame.SetVReg(vregA,
1828 shadow_frame.GetVReg(vregA) <<
1829 (shadow_frame.GetVReg(inst->VRegB_12x()) & 0x1f));
1830 ADVANCE(1);
1831 }
1832 HANDLE_INSTRUCTION_END();
1833
1834 HANDLE_INSTRUCTION_START(SHR_INT_2ADDR) {
1835 uint32_t vregA = inst->VRegA_12x();
1836 shadow_frame.SetVReg(vregA,
1837 shadow_frame.GetVReg(vregA) >>
1838 (shadow_frame.GetVReg(inst->VRegB_12x()) & 0x1f));
1839 ADVANCE(1);
1840 }
1841 HANDLE_INSTRUCTION_END();
1842
1843 HANDLE_INSTRUCTION_START(USHR_INT_2ADDR) {
1844 uint32_t vregA = inst->VRegA_12x();
1845 shadow_frame.SetVReg(vregA,
1846 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
1847 (shadow_frame.GetVReg(inst->VRegB_12x()) & 0x1f));
1848 ADVANCE(1);
1849 }
1850 HANDLE_INSTRUCTION_END();
1851
1852 HANDLE_INSTRUCTION_START(AND_INT_2ADDR) {
1853 uint32_t vregA = inst->VRegA_12x();
1854 shadow_frame.SetVReg(vregA,
1855 shadow_frame.GetVReg(vregA) &
1856 shadow_frame.GetVReg(inst->VRegB_12x()));
1857 ADVANCE(1);
1858 }
1859 HANDLE_INSTRUCTION_END();
1860
1861 HANDLE_INSTRUCTION_START(OR_INT_2ADDR) {
1862 uint32_t vregA = inst->VRegA_12x();
1863 shadow_frame.SetVReg(vregA,
1864 shadow_frame.GetVReg(vregA) |
1865 shadow_frame.GetVReg(inst->VRegB_12x()));
1866 ADVANCE(1);
1867 }
1868 HANDLE_INSTRUCTION_END();
1869
1870 HANDLE_INSTRUCTION_START(XOR_INT_2ADDR) {
1871 uint32_t vregA = inst->VRegA_12x();
1872 shadow_frame.SetVReg(vregA,
1873 shadow_frame.GetVReg(vregA) ^
1874 shadow_frame.GetVReg(inst->VRegB_12x()));
1875 ADVANCE(1);
1876 }
1877 HANDLE_INSTRUCTION_END();
1878
1879 HANDLE_INSTRUCTION_START(ADD_LONG_2ADDR) {
1880 uint32_t vregA = inst->VRegA_12x();
1881 shadow_frame.SetVRegLong(vregA,
1882 shadow_frame.GetVRegLong(vregA) +
1883 shadow_frame.GetVRegLong(inst->VRegB_12x()));
1884 ADVANCE(1);
1885 }
1886 HANDLE_INSTRUCTION_END();
1887
1888 HANDLE_INSTRUCTION_START(SUB_LONG_2ADDR) {
1889 uint32_t vregA = inst->VRegA_12x();
1890 shadow_frame.SetVRegLong(vregA,
1891 shadow_frame.GetVRegLong(vregA) -
1892 shadow_frame.GetVRegLong(inst->VRegB_12x()));
1893 ADVANCE(1);
1894 }
1895 HANDLE_INSTRUCTION_END();
1896
1897 HANDLE_INSTRUCTION_START(MUL_LONG_2ADDR) {
1898 uint32_t vregA = inst->VRegA_12x();
1899 shadow_frame.SetVRegLong(vregA,
1900 shadow_frame.GetVRegLong(vregA) *
1901 shadow_frame.GetVRegLong(inst->VRegB_12x()));
1902 ADVANCE(1);
1903 }
1904 HANDLE_INSTRUCTION_END();
1905
1906 HANDLE_INSTRUCTION_START(DIV_LONG_2ADDR) {
1907 uint32_t vregA = inst->VRegA_12x();
1908 bool success = DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
1909 shadow_frame.GetVRegLong(inst->VRegB_12x()));
1910 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
1911 }
1912 HANDLE_INSTRUCTION_END();
1913
1914 HANDLE_INSTRUCTION_START(REM_LONG_2ADDR) {
1915 uint32_t vregA = inst->VRegA_12x();
1916 bool success = DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
1917 shadow_frame.GetVRegLong(inst->VRegB_12x()));
1918 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
1919 }
1920 HANDLE_INSTRUCTION_END();
1921
1922 HANDLE_INSTRUCTION_START(AND_LONG_2ADDR) {
1923 uint32_t vregA = inst->VRegA_12x();
1924 shadow_frame.SetVRegLong(vregA,
1925 shadow_frame.GetVRegLong(vregA) &
1926 shadow_frame.GetVRegLong(inst->VRegB_12x()));
1927 ADVANCE(1);
1928 }
1929 HANDLE_INSTRUCTION_END();
1930
1931 HANDLE_INSTRUCTION_START(OR_LONG_2ADDR) {
1932 uint32_t vregA = inst->VRegA_12x();
1933 shadow_frame.SetVRegLong(vregA,
1934 shadow_frame.GetVRegLong(vregA) |
1935 shadow_frame.GetVRegLong(inst->VRegB_12x()));
1936 ADVANCE(1);
1937 }
1938 HANDLE_INSTRUCTION_END();
1939
1940 HANDLE_INSTRUCTION_START(XOR_LONG_2ADDR) {
1941 uint32_t vregA = inst->VRegA_12x();
1942 shadow_frame.SetVRegLong(vregA,
1943 shadow_frame.GetVRegLong(vregA) ^
1944 shadow_frame.GetVRegLong(inst->VRegB_12x()));
1945 ADVANCE(1);
1946 }
1947 HANDLE_INSTRUCTION_END();
1948
1949 HANDLE_INSTRUCTION_START(SHL_LONG_2ADDR) {
1950 uint32_t vregA = inst->VRegA_12x();
1951 shadow_frame.SetVRegLong(vregA,
1952 shadow_frame.GetVRegLong(vregA) <<
1953 (shadow_frame.GetVReg(inst->VRegB_12x()) & 0x3f));
1954 ADVANCE(1);
1955 }
1956 HANDLE_INSTRUCTION_END();
1957
1958 HANDLE_INSTRUCTION_START(SHR_LONG_2ADDR) {
1959 uint32_t vregA = inst->VRegA_12x();
1960 shadow_frame.SetVRegLong(vregA,
1961 shadow_frame.GetVRegLong(vregA) >>
1962 (shadow_frame.GetVReg(inst->VRegB_12x()) & 0x3f));
1963 ADVANCE(1);
1964 }
1965 HANDLE_INSTRUCTION_END();
1966
1967 HANDLE_INSTRUCTION_START(USHR_LONG_2ADDR) {
1968 uint32_t vregA = inst->VRegA_12x();
1969 shadow_frame.SetVRegLong(vregA,
1970 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
1971 (shadow_frame.GetVReg(inst->VRegB_12x()) & 0x3f));
1972 ADVANCE(1);
1973 }
1974 HANDLE_INSTRUCTION_END();
1975
1976 HANDLE_INSTRUCTION_START(ADD_FLOAT_2ADDR) {
1977 uint32_t vregA = inst->VRegA_12x();
1978 shadow_frame.SetVRegFloat(vregA,
1979 shadow_frame.GetVRegFloat(vregA) +
1980 shadow_frame.GetVRegFloat(inst->VRegB_12x()));
1981 ADVANCE(1);
1982 }
1983 HANDLE_INSTRUCTION_END();
1984
1985 HANDLE_INSTRUCTION_START(SUB_FLOAT_2ADDR) {
1986 uint32_t vregA = inst->VRegA_12x();
1987 shadow_frame.SetVRegFloat(vregA,
1988 shadow_frame.GetVRegFloat(vregA) -
1989 shadow_frame.GetVRegFloat(inst->VRegB_12x()));
1990 ADVANCE(1);
1991 }
1992 HANDLE_INSTRUCTION_END();
1993
1994 HANDLE_INSTRUCTION_START(MUL_FLOAT_2ADDR) {
1995 uint32_t vregA = inst->VRegA_12x();
1996 shadow_frame.SetVRegFloat(vregA,
1997 shadow_frame.GetVRegFloat(vregA) *
1998 shadow_frame.GetVRegFloat(inst->VRegB_12x()));
1999 ADVANCE(1);
2000 }
2001 HANDLE_INSTRUCTION_END();
2002
2003 HANDLE_INSTRUCTION_START(DIV_FLOAT_2ADDR) {
2004 uint32_t vregA = inst->VRegA_12x();
2005 shadow_frame.SetVRegFloat(vregA,
2006 shadow_frame.GetVRegFloat(vregA) /
2007 shadow_frame.GetVRegFloat(inst->VRegB_12x()));
2008 ADVANCE(1);
2009 }
2010 HANDLE_INSTRUCTION_END();
2011
2012 HANDLE_INSTRUCTION_START(REM_FLOAT_2ADDR) {
2013 uint32_t vregA = inst->VRegA_12x();
2014 shadow_frame.SetVRegFloat(vregA,
2015 fmodf(shadow_frame.GetVRegFloat(vregA),
2016 shadow_frame.GetVRegFloat(inst->VRegB_12x())));
2017 ADVANCE(1);
2018 }
2019 HANDLE_INSTRUCTION_END();
2020
2021 HANDLE_INSTRUCTION_START(ADD_DOUBLE_2ADDR) {
2022 uint32_t vregA = inst->VRegA_12x();
2023 shadow_frame.SetVRegDouble(vregA,
2024 shadow_frame.GetVRegDouble(vregA) +
2025 shadow_frame.GetVRegDouble(inst->VRegB_12x()));
2026 ADVANCE(1);
2027 }
2028 HANDLE_INSTRUCTION_END();
2029
2030 HANDLE_INSTRUCTION_START(SUB_DOUBLE_2ADDR) {
2031 uint32_t vregA = inst->VRegA_12x();
2032 shadow_frame.SetVRegDouble(vregA,
2033 shadow_frame.GetVRegDouble(vregA) -
2034 shadow_frame.GetVRegDouble(inst->VRegB_12x()));
2035 ADVANCE(1);
2036 }
2037 HANDLE_INSTRUCTION_END();
2038
2039 HANDLE_INSTRUCTION_START(MUL_DOUBLE_2ADDR) {
2040 uint32_t vregA = inst->VRegA_12x();
2041 shadow_frame.SetVRegDouble(vregA,
2042 shadow_frame.GetVRegDouble(vregA) *
2043 shadow_frame.GetVRegDouble(inst->VRegB_12x()));
2044 ADVANCE(1);
2045 }
2046 HANDLE_INSTRUCTION_END();
2047
2048 HANDLE_INSTRUCTION_START(DIV_DOUBLE_2ADDR) {
2049 uint32_t vregA = inst->VRegA_12x();
2050 shadow_frame.SetVRegDouble(vregA,
2051 shadow_frame.GetVRegDouble(vregA) /
2052 shadow_frame.GetVRegDouble(inst->VRegB_12x()));
2053 ADVANCE(1);
2054 }
2055 HANDLE_INSTRUCTION_END();
2056
2057 HANDLE_INSTRUCTION_START(REM_DOUBLE_2ADDR) {
2058 uint32_t vregA = inst->VRegA_12x();
2059 shadow_frame.SetVRegDouble(vregA,
2060 fmod(shadow_frame.GetVRegDouble(vregA),
2061 shadow_frame.GetVRegDouble(inst->VRegB_12x())));
2062 ADVANCE(1);
2063 }
2064 HANDLE_INSTRUCTION_END();
2065
2066 HANDLE_INSTRUCTION_START(ADD_INT_LIT16)
2067 shadow_frame.SetVReg(inst->VRegA_22s(),
2068 shadow_frame.GetVReg(inst->VRegB_22s()) +
2069 inst->VRegC_22s());
2070 ADVANCE(2);
2071 HANDLE_INSTRUCTION_END();
2072
2073 HANDLE_INSTRUCTION_START(RSUB_INT)
2074 shadow_frame.SetVReg(inst->VRegA_22s(),
2075 inst->VRegC_22s() -
2076 shadow_frame.GetVReg(inst->VRegB_22s()));
2077 ADVANCE(2);
2078 HANDLE_INSTRUCTION_END();
2079
2080 HANDLE_INSTRUCTION_START(MUL_INT_LIT16)
2081 shadow_frame.SetVReg(inst->VRegA_22s(),
2082 shadow_frame.GetVReg(inst->VRegB_22s()) *
2083 inst->VRegC_22s());
2084 ADVANCE(2);
2085 HANDLE_INSTRUCTION_END();
2086
2087 HANDLE_INSTRUCTION_START(DIV_INT_LIT16) {
2088 bool success = DoIntDivide(shadow_frame, inst->VRegA_22s(),
2089 shadow_frame.GetVReg(inst->VRegB_22s()), inst->VRegC_22s());
2090 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2091 }
2092 HANDLE_INSTRUCTION_END();
2093
2094 HANDLE_INSTRUCTION_START(REM_INT_LIT16) {
2095 bool success = DoIntRemainder(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(AND_INT_LIT16)
2102 shadow_frame.SetVReg(inst->VRegA_22s(),
2103 shadow_frame.GetVReg(inst->VRegB_22s()) &
2104 inst->VRegC_22s());
2105 ADVANCE(2);
2106 HANDLE_INSTRUCTION_END();
2107
2108 HANDLE_INSTRUCTION_START(OR_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(XOR_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(ADD_INT_LIT8)
2123 shadow_frame.SetVReg(inst->VRegA_22b(),
2124 shadow_frame.GetVReg(inst->VRegB_22b()) +
2125 inst->VRegC_22b());
2126 ADVANCE(2);
2127 HANDLE_INSTRUCTION_END();
2128
2129 HANDLE_INSTRUCTION_START(RSUB_INT_LIT8)
2130 shadow_frame.SetVReg(inst->VRegA_22b(),
2131 inst->VRegC_22b() -
2132 shadow_frame.GetVReg(inst->VRegB_22b()));
2133 ADVANCE(2);
2134 HANDLE_INSTRUCTION_END();
2135
2136 HANDLE_INSTRUCTION_START(MUL_INT_LIT8)
2137 shadow_frame.SetVReg(inst->VRegA_22b(),
2138 shadow_frame.GetVReg(inst->VRegB_22b()) *
2139 inst->VRegC_22b());
2140 ADVANCE(2);
2141 HANDLE_INSTRUCTION_END();
2142
2143 HANDLE_INSTRUCTION_START(DIV_INT_LIT8) {
2144 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(),
2145 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2146 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2147 }
2148 HANDLE_INSTRUCTION_END();
2149
2150 HANDLE_INSTRUCTION_START(REM_INT_LIT8) {
2151 bool success = DoIntRemainder(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(AND_INT_LIT8)
2158 shadow_frame.SetVReg(inst->VRegA_22b(),
2159 shadow_frame.GetVReg(inst->VRegB_22b()) &
2160 inst->VRegC_22b());
2161 ADVANCE(2);
2162 HANDLE_INSTRUCTION_END();
2163
2164 HANDLE_INSTRUCTION_START(OR_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(XOR_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(SHL_INT_LIT8)
2179 shadow_frame.SetVReg(inst->VRegA_22b(),
2180 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2181 (inst->VRegC_22b() & 0x1f));
2182 ADVANCE(2);
2183 HANDLE_INSTRUCTION_END();
2184
2185 HANDLE_INSTRUCTION_START(SHR_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(USHR_INT_LIT8)
2193 shadow_frame.SetVReg(inst->VRegA_22b(),
2194 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2195 (inst->VRegC_22b() & 0x1f));
2196 ADVANCE(2);
2197 HANDLE_INSTRUCTION_END();
2198
2199 HANDLE_INSTRUCTION_START(UNUSED_3E)
2200 UnexpectedOpcode(inst, mh);
2201 HANDLE_INSTRUCTION_END();
2202
2203 HANDLE_INSTRUCTION_START(UNUSED_3F)
2204 UnexpectedOpcode(inst, mh);
2205 HANDLE_INSTRUCTION_END();
2206
2207 HANDLE_INSTRUCTION_START(UNUSED_40)
2208 UnexpectedOpcode(inst, mh);
2209 HANDLE_INSTRUCTION_END();
2210
2211 HANDLE_INSTRUCTION_START(UNUSED_41)
2212 UnexpectedOpcode(inst, mh);
2213 HANDLE_INSTRUCTION_END();
2214
2215 HANDLE_INSTRUCTION_START(UNUSED_42)
2216 UnexpectedOpcode(inst, mh);
2217 HANDLE_INSTRUCTION_END();
2218
2219 HANDLE_INSTRUCTION_START(UNUSED_43)
2220 UnexpectedOpcode(inst, mh);
2221 HANDLE_INSTRUCTION_END();
2222
2223 HANDLE_INSTRUCTION_START(UNUSED_79)
2224 UnexpectedOpcode(inst, mh);
2225 HANDLE_INSTRUCTION_END();
2226
2227 HANDLE_INSTRUCTION_START(UNUSED_7A)
2228 UnexpectedOpcode(inst, mh);
2229 HANDLE_INSTRUCTION_END();
2230
2231 HANDLE_INSTRUCTION_START(UNUSED_EB)
2232 UnexpectedOpcode(inst, mh);
2233 HANDLE_INSTRUCTION_END();
2234
2235 HANDLE_INSTRUCTION_START(UNUSED_EC)
2236 UnexpectedOpcode(inst, mh);
2237 HANDLE_INSTRUCTION_END();
2238
2239 HANDLE_INSTRUCTION_START(UNUSED_ED)
2240 UnexpectedOpcode(inst, mh);
2241 HANDLE_INSTRUCTION_END();
2242
2243 HANDLE_INSTRUCTION_START(UNUSED_EE)
2244 UnexpectedOpcode(inst, mh);
2245 HANDLE_INSTRUCTION_END();
2246
2247 HANDLE_INSTRUCTION_START(UNUSED_EF)
2248 UnexpectedOpcode(inst, mh);
2249 HANDLE_INSTRUCTION_END();
2250
2251 HANDLE_INSTRUCTION_START(UNUSED_F0)
2252 UnexpectedOpcode(inst, mh);
2253 HANDLE_INSTRUCTION_END();
2254
2255 HANDLE_INSTRUCTION_START(UNUSED_F1)
2256 UnexpectedOpcode(inst, mh);
2257 HANDLE_INSTRUCTION_END();
2258
2259 HANDLE_INSTRUCTION_START(UNUSED_F2)
2260 UnexpectedOpcode(inst, mh);
2261 HANDLE_INSTRUCTION_END();
2262
2263 HANDLE_INSTRUCTION_START(UNUSED_F3)
2264 UnexpectedOpcode(inst, mh);
2265 HANDLE_INSTRUCTION_END();
2266
2267 HANDLE_INSTRUCTION_START(UNUSED_F4)
2268 UnexpectedOpcode(inst, mh);
2269 HANDLE_INSTRUCTION_END();
2270
2271 HANDLE_INSTRUCTION_START(UNUSED_F5)
2272 UnexpectedOpcode(inst, mh);
2273 HANDLE_INSTRUCTION_END();
2274
2275 HANDLE_INSTRUCTION_START(UNUSED_F6)
2276 UnexpectedOpcode(inst, mh);
2277 HANDLE_INSTRUCTION_END();
2278
2279 HANDLE_INSTRUCTION_START(UNUSED_F7)
2280 UnexpectedOpcode(inst, mh);
2281 HANDLE_INSTRUCTION_END();
2282
2283 HANDLE_INSTRUCTION_START(UNUSED_F8)
2284 UnexpectedOpcode(inst, mh);
2285 HANDLE_INSTRUCTION_END();
2286
2287 HANDLE_INSTRUCTION_START(UNUSED_F9)
2288 UnexpectedOpcode(inst, mh);
2289 HANDLE_INSTRUCTION_END();
2290
2291 HANDLE_INSTRUCTION_START(UNUSED_FA)
2292 UnexpectedOpcode(inst, mh);
2293 HANDLE_INSTRUCTION_END();
2294
2295 HANDLE_INSTRUCTION_START(UNUSED_FB)
2296 UnexpectedOpcode(inst, mh);
2297 HANDLE_INSTRUCTION_END();
2298
2299 HANDLE_INSTRUCTION_START(UNUSED_FC)
2300 UnexpectedOpcode(inst, mh);
2301 HANDLE_INSTRUCTION_END();
2302
2303 HANDLE_INSTRUCTION_START(UNUSED_FD)
2304 UnexpectedOpcode(inst, mh);
2305 HANDLE_INSTRUCTION_END();
2306
2307 HANDLE_INSTRUCTION_START(UNUSED_FE)
2308 UnexpectedOpcode(inst, mh);
2309 HANDLE_INSTRUCTION_END();
2310
2311 HANDLE_INSTRUCTION_START(UNUSED_FF)
2312 UnexpectedOpcode(inst, mh);
2313 HANDLE_INSTRUCTION_END();
2314
2315 exception_pending_label: {
2316 CHECK(self->IsExceptionPending());
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002317 if (UNLIKELY(self->TestAllFlags())) {
2318 CheckSuspend(self);
2319 }
Sebastien Hertz947ff082013-09-17 14:10:13 +02002320 Object* this_object = shadow_frame.GetThisObject(code_item->ins_size_);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002321 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, dex_pc,
Sebastien Hertz947ff082013-09-17 14:10:13 +02002322 this_object,
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002323 instrumentation);
2324 if (found_dex_pc == DexFile::kDexNoIndex) {
2325 return JValue(); /* Handled in caller. */
2326 } else {
2327 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc);
2328 ADVANCE(displacement);
2329 }
2330 }
2331
2332 // Create alternative instruction handlers dedicated to instrumentation.
Sebastien Hertz947ff082013-09-17 14:10:13 +02002333#define INSTRUMENTATION_INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) \
2334 instrumentation_op_##code: { \
2335 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), \
2336 shadow_frame.GetMethod(), dex_pc); \
2337 goto *handlersTable[Instruction::code]; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002338 }
2339#include "dex_instruction_list.h"
2340 DEX_INSTRUCTION_LIST(INSTRUMENTATION_INSTRUCTION_HANDLER)
2341#undef DEX_INSTRUCTION_LIST
2342#undef INSTRUMENTATION_INSTRUCTION_HANDLER
2343} // NOLINT(readability/fn_size)
2344
2345// Explicit definitions of ExecuteGotoImpl.
2346template JValue ExecuteGotoImpl<true>(Thread* self, MethodHelper& mh,
2347 const DexFile::CodeItem* code_item,
2348 ShadowFrame& shadow_frame, JValue result_register);
2349template JValue ExecuteGotoImpl<false>(Thread* self, MethodHelper& mh,
2350 const DexFile::CodeItem* code_item,
2351 ShadowFrame& shadow_frame, JValue result_register);
2352
2353} // namespace interpreter
2354} // namespace art