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