blob: a6349fcf88d2951209f694db7972682b26e28a0f [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
Andreas Gampe542451c2016-07-26 09:02:02 -070017#include "base/enums.h"
Alex Lighteb7c1442015-08-31 13:17:42 -070018#include "experimental_flags.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020019#include "interpreter_common.h"
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000020#include "jit/jit.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070021#include "safe_math.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020022
23namespace art {
24namespace interpreter {
25
26#define HANDLE_PENDING_EXCEPTION() \
27 do { \
Sebastien Hertz82aeddb2014-05-20 20:09:45 +020028 DCHECK(self->IsExceptionPending()); \
Ian Rogers7b078e82014-09-10 14:44:24 -070029 self->AllowThreadSuspension(); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020030 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, \
31 inst->GetDexPc(insns), \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020032 instrumentation); \
33 if (found_dex_pc == DexFile::kDexNoIndex) { \
Andreas Gampe03ec9302015-08-27 17:41:47 -070034 /* Structured locking is to be enforced for abnormal termination, too. */ \
Andreas Gampe56fdd0e2016-04-28 14:56:54 -070035 DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame); \
buzbee1452bee2015-03-06 14:43:04 -080036 if (interpret_one_instruction) { \
buzbee93e94f22016-04-07 13:52:48 -070037 /* Signal mterp to return to caller */ \
buzbee1452bee2015-03-06 14:43:04 -080038 shadow_frame.SetDexPC(DexFile::kDexNoIndex); \
39 } \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020040 return JValue(); /* Handled in caller. */ \
41 } else { \
42 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc); \
43 inst = inst->RelativeAt(displacement); \
44 } \
45 } while (false)
46
47#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _next_function) \
48 do { \
49 if (UNLIKELY(_is_exception_pending)) { \
50 HANDLE_PENDING_EXCEPTION(); \
51 } else { \
52 inst = inst->_next_function(); \
53 } \
54 } while (false)
55
Andreas Gampe03ec9302015-08-27 17:41:47 -070056#define HANDLE_MONITOR_CHECKS() \
Andreas Gampe56fdd0e2016-04-28 14:56:54 -070057 if (!DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame)) { \
Andreas Gampe03ec9302015-08-27 17:41:47 -070058 HANDLE_PENDING_EXCEPTION(); \
59 }
60
Sebastien Hertz8ece0502013-08-07 11:26:41 +020061// Code to run before each dex instruction.
Sebastien Hertz8379b222014-02-24 17:38:15 +010062#define PREAMBLE() \
63 do { \
Sebastien Hertz9d6bf692015-04-10 12:12:33 +020064 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
Sebastien Hertz8379b222014-02-24 17:38:15 +010065 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), \
66 shadow_frame.GetMethod(), dex_pc); \
67 } \
68 } while (false)
Sebastien Hertz8ece0502013-08-07 11:26:41 +020069
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000070#define BRANCH_INSTRUMENTATION(offset) \
71 do { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010072 if (UNLIKELY(instrumentation->HasBranchListeners())) { \
73 instrumentation->Branch(self, method, dex_pc, offset); \
74 } \
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000075 JValue result; \
76 if (jit::Jit::MaybeDoOnStackReplacement(self, method, dex_pc, offset, &result)) { \
buzbee93e94f22016-04-07 13:52:48 -070077 if (interpret_one_instruction) { \
78 /* OSR has completed execution of the method. Signal mterp to return to caller */ \
79 shadow_frame.SetDexPC(DexFile::kDexNoIndex); \
80 } \
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000081 return result; \
82 } \
Nicolas Geoffray3108daf2015-11-24 16:32:33 +000083 } while (false)
84
Bill Buzbee1d011d92016-04-04 16:59:29 +000085#define HOTNESS_UPDATE() \
86 do { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010087 if (jit != nullptr) { \
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +010088 jit->AddSamples(self, method, 1, /*with_backedges*/ true); \
Bill Buzbee1d011d92016-04-04 16:59:29 +000089 } \
90 } while (false)
91
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010092template<bool do_access_check, bool transaction_active>
Ian Rogerse94652f2014-12-02 11:13:19 -080093JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -080094 ShadowFrame& shadow_frame, JValue result_register,
95 bool interpret_one_instruction) {
Igor Murashkinc449e8b2015-06-10 15:56:42 -070096 constexpr bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +020097 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
98 LOG(FATAL) << "Invalid shadow frame for interpreter use";
99 return JValue();
100 }
101 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200102
103 uint32_t dex_pc = shadow_frame.GetDexPC();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700104 const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200105 const uint16_t* const insns = code_item->insns_;
106 const Instruction* inst = Instruction::At(insns + dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200107 uint16_t inst_data;
Bill Buzbee1d011d92016-04-04 16:59:29 +0000108 ArtMethod* method = shadow_frame.GetMethod();
109 jit::Jit* jit = Runtime::Current()->GetJit();
Igor Murashkin6918bf12015-09-27 19:19:06 -0700110
buzbee1452bee2015-03-06 14:43:04 -0800111 do {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200112 dex_pc = inst->GetDexPc(insns);
113 shadow_frame.SetDexPC(dex_pc);
Ian Rogerse94652f2014-12-02 11:13:19 -0800114 TraceExecution(shadow_frame, inst, dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200115 inst_data = inst->Fetch16(0);
116 switch (inst->Opcode(inst_data)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200117 case Instruction::NOP:
118 PREAMBLE();
119 inst = inst->Next_1xx();
120 break;
121 case Instruction::MOVE:
122 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200123 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
124 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200125 inst = inst->Next_1xx();
126 break;
127 case Instruction::MOVE_FROM16:
128 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200129 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200130 shadow_frame.GetVReg(inst->VRegB_22x()));
131 inst = inst->Next_2xx();
132 break;
133 case Instruction::MOVE_16:
134 PREAMBLE();
135 shadow_frame.SetVReg(inst->VRegA_32x(),
136 shadow_frame.GetVReg(inst->VRegB_32x()));
137 inst = inst->Next_3xx();
138 break;
139 case Instruction::MOVE_WIDE:
140 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200141 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
142 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200143 inst = inst->Next_1xx();
144 break;
145 case Instruction::MOVE_WIDE_FROM16:
146 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200147 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200148 shadow_frame.GetVRegLong(inst->VRegB_22x()));
149 inst = inst->Next_2xx();
150 break;
151 case Instruction::MOVE_WIDE_16:
152 PREAMBLE();
153 shadow_frame.SetVRegLong(inst->VRegA_32x(),
154 shadow_frame.GetVRegLong(inst->VRegB_32x()));
155 inst = inst->Next_3xx();
156 break;
157 case Instruction::MOVE_OBJECT:
158 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200159 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
160 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200161 inst = inst->Next_1xx();
162 break;
163 case Instruction::MOVE_OBJECT_FROM16:
164 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200165 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200166 shadow_frame.GetVRegReference(inst->VRegB_22x()));
167 inst = inst->Next_2xx();
168 break;
169 case Instruction::MOVE_OBJECT_16:
170 PREAMBLE();
171 shadow_frame.SetVRegReference(inst->VRegA_32x(),
172 shadow_frame.GetVRegReference(inst->VRegB_32x()));
173 inst = inst->Next_3xx();
174 break;
175 case Instruction::MOVE_RESULT:
176 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200177 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200178 inst = inst->Next_1xx();
179 break;
180 case Instruction::MOVE_RESULT_WIDE:
181 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200182 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200183 inst = inst->Next_1xx();
184 break;
185 case Instruction::MOVE_RESULT_OBJECT:
186 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200187 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200188 inst = inst->Next_1xx();
189 break;
190 case Instruction::MOVE_EXCEPTION: {
191 PREAMBLE();
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000192 Throwable* exception = self->GetException();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100193 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200194 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception);
Sebastien Hertz5c004902014-05-21 10:07:42 +0200195 self->ClearException();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200196 inst = inst->Next_1xx();
197 break;
198 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700199 case Instruction::RETURN_VOID_NO_BARRIER: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200200 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200201 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700202 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700203 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200204 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200205 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200206 shadow_frame.GetMethod(), inst->GetDexPc(insns),
207 result);
208 }
buzbee1452bee2015-03-06 14:43:04 -0800209 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700210 /* Signal mterp to return to caller */
buzbee1452bee2015-03-06 14:43:04 -0800211 shadow_frame.SetDexPC(DexFile::kDexNoIndex);
212 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200213 return result;
214 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700215 case Instruction::RETURN_VOID: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200216 PREAMBLE();
Hans Boehm30359612014-05-21 17:46:23 -0700217 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200218 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700219 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700220 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200221 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200222 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200223 shadow_frame.GetMethod(), inst->GetDexPc(insns),
224 result);
225 }
buzbee1452bee2015-03-06 14:43:04 -0800226 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700227 /* Signal mterp to return to caller */
buzbee1452bee2015-03-06 14:43:04 -0800228 shadow_frame.SetDexPC(DexFile::kDexNoIndex);
229 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200230 return result;
231 }
232 case Instruction::RETURN: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200233 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200234 JValue result;
235 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200236 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700237 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700238 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200239 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200240 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200241 shadow_frame.GetMethod(), inst->GetDexPc(insns),
242 result);
243 }
buzbee1452bee2015-03-06 14:43:04 -0800244 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700245 /* Signal mterp to return to caller */
buzbee1452bee2015-03-06 14:43:04 -0800246 shadow_frame.SetDexPC(DexFile::kDexNoIndex);
247 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200248 return result;
249 }
250 case Instruction::RETURN_WIDE: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200251 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200252 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200253 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700254 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700255 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200256 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200257 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200258 shadow_frame.GetMethod(), inst->GetDexPc(insns),
259 result);
260 }
buzbee1452bee2015-03-06 14:43:04 -0800261 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700262 /* Signal mterp to return to caller */
buzbee1452bee2015-03-06 14:43:04 -0800263 shadow_frame.SetDexPC(DexFile::kDexNoIndex);
264 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200265 return result;
266 }
267 case Instruction::RETURN_OBJECT: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200268 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200269 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700270 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700271 HANDLE_MONITOR_CHECKS();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700272 const size_t ref_idx = inst->VRegA_11x(inst_data);
273 Object* obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700274 if (do_assignability_check && obj_result != nullptr) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700275 PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Vladimir Marko05792b92015-08-03 11:56:49 +0100276 Class* return_type = shadow_frame.GetMethod()->GetReturnType(true /* resolve */,
277 pointer_size);
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700278 // Re-load since it might have moved.
279 obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700280 if (return_type == nullptr) {
Jeff Haoa3faaf42013-09-03 19:07:00 -0700281 // Return the pending exception.
282 HANDLE_PENDING_EXCEPTION();
283 }
284 if (!obj_result->VerifierInstanceOf(return_type)) {
285 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700286 std::string temp1, temp2;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000287 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700288 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700289 obj_result->GetClass()->GetDescriptor(&temp1),
290 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700291 HANDLE_PENDING_EXCEPTION();
292 }
293 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700294 result.SetL(obj_result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200295 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200296 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200297 shadow_frame.GetMethod(), inst->GetDexPc(insns),
298 result);
299 }
buzbee1452bee2015-03-06 14:43:04 -0800300 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700301 /* Signal mterp to return to caller */
buzbee1452bee2015-03-06 14:43:04 -0800302 shadow_frame.SetDexPC(DexFile::kDexNoIndex);
303 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200304 return result;
305 }
306 case Instruction::CONST_4: {
307 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200308 uint4_t dst = inst->VRegA_11n(inst_data);
309 int4_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200310 shadow_frame.SetVReg(dst, val);
311 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700312 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200313 }
314 inst = inst->Next_1xx();
315 break;
316 }
317 case Instruction::CONST_16: {
318 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200319 uint8_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200320 int16_t val = inst->VRegB_21s();
321 shadow_frame.SetVReg(dst, val);
322 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700323 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200324 }
325 inst = inst->Next_2xx();
326 break;
327 }
328 case Instruction::CONST: {
329 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200330 uint8_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200331 int32_t val = inst->VRegB_31i();
332 shadow_frame.SetVReg(dst, val);
333 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700334 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200335 }
336 inst = inst->Next_3xx();
337 break;
338 }
339 case Instruction::CONST_HIGH16: {
340 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200341 uint8_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200342 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
343 shadow_frame.SetVReg(dst, val);
344 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700345 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200346 }
347 inst = inst->Next_2xx();
348 break;
349 }
350 case Instruction::CONST_WIDE_16:
351 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200352 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200353 inst = inst->Next_2xx();
354 break;
355 case Instruction::CONST_WIDE_32:
356 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200357 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200358 inst = inst->Next_3xx();
359 break;
360 case Instruction::CONST_WIDE:
361 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200362 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200363 inst = inst->Next_51l();
364 break;
365 case Instruction::CONST_WIDE_HIGH16:
Sebastien Hertz3c5aec12014-06-04 09:41:21 +0200366 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200367 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200368 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
369 inst = inst->Next_2xx();
370 break;
371 case Instruction::CONST_STRING: {
372 PREAMBLE();
Ian Rogers6786a582014-10-28 12:49:06 -0700373 String* s = ResolveString(self, shadow_frame, inst->VRegB_21c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700374 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200375 HANDLE_PENDING_EXCEPTION();
376 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200377 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200378 inst = inst->Next_2xx();
379 }
380 break;
381 }
382 case Instruction::CONST_STRING_JUMBO: {
383 PREAMBLE();
Ian Rogers6786a582014-10-28 12:49:06 -0700384 String* s = ResolveString(self, shadow_frame, inst->VRegB_31c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700385 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200386 HANDLE_PENDING_EXCEPTION();
387 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200388 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200389 inst = inst->Next_3xx();
390 }
391 break;
392 }
393 case Instruction::CONST_CLASS: {
394 PREAMBLE();
395 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
396 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700397 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200398 HANDLE_PENDING_EXCEPTION();
399 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200400 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200401 inst = inst->Next_2xx();
402 }
403 break;
404 }
405 case Instruction::MONITOR_ENTER: {
406 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200407 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700408 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000409 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200410 HANDLE_PENDING_EXCEPTION();
411 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700412 DoMonitorEnter<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200413 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
414 }
415 break;
416 }
417 case Instruction::MONITOR_EXIT: {
418 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200419 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700420 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000421 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200422 HANDLE_PENDING_EXCEPTION();
423 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700424 DoMonitorExit<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200425 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
426 }
427 break;
428 }
429 case Instruction::CHECK_CAST: {
430 PREAMBLE();
431 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
432 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700433 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200434 HANDLE_PENDING_EXCEPTION();
435 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200436 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700437 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200438 ThrowClassCastException(c, obj->GetClass());
439 HANDLE_PENDING_EXCEPTION();
440 } else {
441 inst = inst->Next_2xx();
442 }
443 }
444 break;
445 }
446 case Instruction::INSTANCE_OF: {
447 PREAMBLE();
448 Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(),
449 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700450 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200451 HANDLE_PENDING_EXCEPTION();
452 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200453 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700454 shadow_frame.SetVReg(inst->VRegA_22c(inst_data),
455 (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200456 inst = inst->Next_2xx();
457 }
458 break;
459 }
460 case Instruction::ARRAY_LENGTH: {
461 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200462 Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700463 if (UNLIKELY(array == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000464 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200465 HANDLE_PENDING_EXCEPTION();
466 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200467 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200468 inst = inst->Next_1xx();
469 }
470 break;
471 }
472 case Instruction::NEW_INSTANCE: {
473 PREAMBLE();
Jeff Hao848f70a2014-01-15 13:49:50 -0800474 Object* obj = nullptr;
475 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
476 self, false, do_access_check);
477 if (LIKELY(c != nullptr)) {
478 if (UNLIKELY(c->IsStringClass())) {
479 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
480 mirror::SetStringCountVisitor visitor(0);
481 obj = String::Alloc<true>(self, 0, allocator_type, visitor);
482 } else {
483 obj = AllocObjectFromCode<do_access_check, true>(
484 inst->VRegB_21c(), shadow_frame.GetMethod(), self,
485 Runtime::Current()->GetHeap()->GetCurrentAllocator());
486 }
487 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700488 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200489 HANDLE_PENDING_EXCEPTION();
490 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200491 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700492 // Don't allow finalizable objects to be allocated during a transaction since these can't
493 // be finalized without a started runtime.
494 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200495 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
496 PrettyTypeOf(obj).c_str());
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700497 HANDLE_PENDING_EXCEPTION();
498 break;
499 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200500 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200501 inst = inst->Next_2xx();
502 }
503 break;
504 }
505 case Instruction::NEW_ARRAY: {
506 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200507 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800508 Object* obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampe1cc7dba2014-12-17 18:43:01 -0800509 inst->VRegC_22c(), length, shadow_frame.GetMethod(), self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800510 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700511 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200512 HANDLE_PENDING_EXCEPTION();
513 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200514 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200515 inst = inst->Next_2xx();
516 }
517 break;
518 }
519 case Instruction::FILLED_NEW_ARRAY: {
520 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100521 bool success =
522 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame, self,
523 &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200524 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
525 break;
526 }
527 case Instruction::FILLED_NEW_ARRAY_RANGE: {
528 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100529 bool success =
530 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
531 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200532 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
533 break;
534 }
535 case Instruction::FILL_ARRAY_DATA: {
536 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200537 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
538 const Instruction::ArrayDataPayload* payload =
539 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
Ian Rogers832336b2014-10-08 15:35:22 -0700540 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
541 bool success = FillArrayData(obj, payload);
542 if (!success) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200543 HANDLE_PENDING_EXCEPTION();
544 break;
545 }
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100546 if (transaction_active) {
Ian Rogers832336b2014-10-08 15:35:22 -0700547 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100548 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200549 inst = inst->Next_3xx();
550 break;
551 }
552 case Instruction::THROW: {
553 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200554 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700555 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000556 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700557 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
558 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700559 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000560 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700561 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700562 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200563 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000564 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200565 }
566 HANDLE_PENDING_EXCEPTION();
567 break;
568 }
569 case Instruction::GOTO: {
570 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200571 int8_t offset = inst->VRegA_10t(inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000572 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200573 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000574 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700575 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200576 }
577 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200578 break;
579 }
580 case Instruction::GOTO_16: {
581 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200582 int16_t offset = inst->VRegA_20t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000583 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200584 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000585 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700586 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200587 }
588 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200589 break;
590 }
591 case Instruction::GOTO_32: {
592 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200593 int32_t offset = inst->VRegA_30t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000594 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200595 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000596 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700597 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200598 }
599 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200600 break;
601 }
602 case Instruction::PACKED_SWITCH: {
603 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200604 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000605 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200606 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000607 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700608 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200609 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200610 inst = inst->RelativeAt(offset);
611 break;
612 }
613 case Instruction::SPARSE_SWITCH: {
614 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200615 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000616 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200617 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000618 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700619 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200620 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200621 inst = inst->RelativeAt(offset);
622 break;
623 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700624
625#if defined(__clang__)
626#pragma clang diagnostic push
627#pragma clang diagnostic ignored "-Wfloat-equal"
628#endif
629
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200630 case Instruction::CMPL_FLOAT: {
631 PREAMBLE();
632 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
633 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
634 int32_t result;
635 if (val1 > val2) {
636 result = 1;
637 } else if (val1 == val2) {
638 result = 0;
639 } else {
640 result = -1;
641 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200642 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200643 inst = inst->Next_2xx();
644 break;
645 }
646 case Instruction::CMPG_FLOAT: {
647 PREAMBLE();
648 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
649 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
650 int32_t result;
651 if (val1 < val2) {
652 result = -1;
653 } else if (val1 == val2) {
654 result = 0;
655 } else {
656 result = 1;
657 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200658 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200659 inst = inst->Next_2xx();
660 break;
661 }
662 case Instruction::CMPL_DOUBLE: {
663 PREAMBLE();
664 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
665 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
666 int32_t result;
667 if (val1 > val2) {
668 result = 1;
669 } else if (val1 == val2) {
670 result = 0;
671 } else {
672 result = -1;
673 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200674 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200675 inst = inst->Next_2xx();
676 break;
677 }
678
679 case Instruction::CMPG_DOUBLE: {
680 PREAMBLE();
681 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
682 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
683 int32_t result;
684 if (val1 < val2) {
685 result = -1;
686 } else if (val1 == val2) {
687 result = 0;
688 } else {
689 result = 1;
690 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200691 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200692 inst = inst->Next_2xx();
693 break;
694 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700695
696#if defined(__clang__)
697#pragma clang diagnostic pop
698#endif
699
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200700 case Instruction::CMP_LONG: {
701 PREAMBLE();
702 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
703 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
704 int32_t result;
705 if (val1 > val2) {
706 result = 1;
707 } else if (val1 == val2) {
708 result = 0;
709 } else {
710 result = -1;
711 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200712 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200713 inst = inst->Next_2xx();
714 break;
715 }
716 case Instruction::IF_EQ: {
717 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700718 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) ==
719 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200720 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000721 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200722 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000723 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700724 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200725 }
726 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200727 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800728 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200729 inst = inst->Next_2xx();
730 }
731 break;
732 }
733 case Instruction::IF_NE: {
734 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700735 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
736 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200737 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000738 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200739 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000740 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700741 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200742 }
743 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200744 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800745 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200746 inst = inst->Next_2xx();
747 }
748 break;
749 }
750 case Instruction::IF_LT: {
751 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700752 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
753 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200754 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000755 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200756 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000757 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700758 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200759 }
760 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200761 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800762 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200763 inst = inst->Next_2xx();
764 }
765 break;
766 }
767 case Instruction::IF_GE: {
768 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700769 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
770 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200771 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000772 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200773 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000774 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700775 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200776 }
777 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200778 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800779 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200780 inst = inst->Next_2xx();
781 }
782 break;
783 }
784 case Instruction::IF_GT: {
785 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700786 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
787 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200788 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000789 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200790 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000791 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700792 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200793 }
794 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200795 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800796 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200797 inst = inst->Next_2xx();
798 }
799 break;
800 }
801 case Instruction::IF_LE: {
802 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700803 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
804 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200805 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000806 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200807 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000808 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700809 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200810 }
811 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200812 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800813 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200814 inst = inst->Next_2xx();
815 }
816 break;
817 }
818 case Instruction::IF_EQZ: {
819 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200820 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200821 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000822 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200823 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000824 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700825 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200826 }
827 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200828 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800829 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200830 inst = inst->Next_2xx();
831 }
832 break;
833 }
834 case Instruction::IF_NEZ: {
835 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200836 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200837 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000838 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200839 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000840 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700841 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200842 }
843 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200844 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800845 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200846 inst = inst->Next_2xx();
847 }
848 break;
849 }
850 case Instruction::IF_LTZ: {
851 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200852 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200853 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000854 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200855 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000856 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700857 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200858 }
859 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200860 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800861 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200862 inst = inst->Next_2xx();
863 }
864 break;
865 }
866 case Instruction::IF_GEZ: {
867 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200868 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200869 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000870 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200871 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000872 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700873 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200874 }
875 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200876 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800877 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200878 inst = inst->Next_2xx();
879 }
880 break;
881 }
882 case Instruction::IF_GTZ: {
883 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200884 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200885 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000886 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200887 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000888 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700889 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200890 }
891 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200892 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800893 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200894 inst = inst->Next_2xx();
895 }
896 break;
897 }
898 case Instruction::IF_LEZ: {
899 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200900 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200901 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000902 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200903 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000904 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700905 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200906 }
907 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200908 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800909 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200910 inst = inst->Next_2xx();
911 }
912 break;
913 }
914 case Instruction::AGET_BOOLEAN: {
915 PREAMBLE();
916 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700917 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000918 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200919 HANDLE_PENDING_EXCEPTION();
920 break;
921 }
922 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
923 BooleanArray* array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700924 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100925 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200926 inst = inst->Next_2xx();
927 } else {
928 HANDLE_PENDING_EXCEPTION();
929 }
930 break;
931 }
932 case Instruction::AGET_BYTE: {
933 PREAMBLE();
934 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700935 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000936 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200937 HANDLE_PENDING_EXCEPTION();
938 break;
939 }
940 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
941 ByteArray* array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700942 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100943 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200944 inst = inst->Next_2xx();
945 } else {
946 HANDLE_PENDING_EXCEPTION();
947 }
948 break;
949 }
950 case Instruction::AGET_CHAR: {
951 PREAMBLE();
952 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700953 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000954 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200955 HANDLE_PENDING_EXCEPTION();
956 break;
957 }
958 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
959 CharArray* array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700960 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100961 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200962 inst = inst->Next_2xx();
963 } else {
964 HANDLE_PENDING_EXCEPTION();
965 }
966 break;
967 }
968 case Instruction::AGET_SHORT: {
969 PREAMBLE();
970 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700971 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000972 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200973 HANDLE_PENDING_EXCEPTION();
974 break;
975 }
976 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
977 ShortArray* array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700978 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100979 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200980 inst = inst->Next_2xx();
981 } else {
982 HANDLE_PENDING_EXCEPTION();
983 }
984 break;
985 }
986 case Instruction::AGET: {
987 PREAMBLE();
988 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700989 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000990 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200991 HANDLE_PENDING_EXCEPTION();
992 break;
993 }
994 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700995 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
996 auto* array = down_cast<IntArray*>(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700997 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100998 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200999 inst = inst->Next_2xx();
1000 } else {
1001 HANDLE_PENDING_EXCEPTION();
1002 }
1003 break;
1004 }
1005 case Instruction::AGET_WIDE: {
1006 PREAMBLE();
1007 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001008 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001009 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001010 HANDLE_PENDING_EXCEPTION();
1011 break;
1012 }
1013 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001014 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1015 auto* array = down_cast<LongArray*>(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001016 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001017 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001018 inst = inst->Next_2xx();
1019 } else {
1020 HANDLE_PENDING_EXCEPTION();
1021 }
1022 break;
1023 }
1024 case Instruction::AGET_OBJECT: {
1025 PREAMBLE();
1026 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001027 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001028 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001029 HANDLE_PENDING_EXCEPTION();
1030 break;
1031 }
1032 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1033 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001034 if (array->CheckIsValidIndex(index)) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001035 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001036 inst = inst->Next_2xx();
1037 } else {
1038 HANDLE_PENDING_EXCEPTION();
1039 }
1040 break;
1041 }
1042 case Instruction::APUT_BOOLEAN: {
1043 PREAMBLE();
1044 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001045 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001046 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001047 HANDLE_PENDING_EXCEPTION();
1048 break;
1049 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001050 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001051 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1052 BooleanArray* array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001053 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001054 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001055 inst = inst->Next_2xx();
1056 } else {
1057 HANDLE_PENDING_EXCEPTION();
1058 }
1059 break;
1060 }
1061 case Instruction::APUT_BYTE: {
1062 PREAMBLE();
1063 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001064 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001065 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001066 HANDLE_PENDING_EXCEPTION();
1067 break;
1068 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001069 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001070 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1071 ByteArray* array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001072 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001073 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001074 inst = inst->Next_2xx();
1075 } else {
1076 HANDLE_PENDING_EXCEPTION();
1077 }
1078 break;
1079 }
1080 case Instruction::APUT_CHAR: {
1081 PREAMBLE();
1082 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001083 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001084 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001085 HANDLE_PENDING_EXCEPTION();
1086 break;
1087 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001088 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001089 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1090 CharArray* array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001091 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001092 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001093 inst = inst->Next_2xx();
1094 } else {
1095 HANDLE_PENDING_EXCEPTION();
1096 }
1097 break;
1098 }
1099 case Instruction::APUT_SHORT: {
1100 PREAMBLE();
1101 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001102 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001103 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001104 HANDLE_PENDING_EXCEPTION();
1105 break;
1106 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001107 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001108 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1109 ShortArray* array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001110 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001111 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001112 inst = inst->Next_2xx();
1113 } else {
1114 HANDLE_PENDING_EXCEPTION();
1115 }
1116 break;
1117 }
1118 case Instruction::APUT: {
1119 PREAMBLE();
1120 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001121 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001122 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001123 HANDLE_PENDING_EXCEPTION();
1124 break;
1125 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001126 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001127 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001128 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1129 auto* array = down_cast<IntArray*>(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001130 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001131 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001132 inst = inst->Next_2xx();
1133 } else {
1134 HANDLE_PENDING_EXCEPTION();
1135 }
1136 break;
1137 }
1138 case Instruction::APUT_WIDE: {
1139 PREAMBLE();
1140 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001141 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001142 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001143 HANDLE_PENDING_EXCEPTION();
1144 break;
1145 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001146 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001147 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001148 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1149 LongArray* array = down_cast<LongArray*>(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001150 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001151 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001152 inst = inst->Next_2xx();
1153 } else {
1154 HANDLE_PENDING_EXCEPTION();
1155 }
1156 break;
1157 }
1158 case Instruction::APUT_OBJECT: {
1159 PREAMBLE();
1160 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001161 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001162 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001163 HANDLE_PENDING_EXCEPTION();
1164 break;
1165 }
1166 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001167 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001168 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001169 if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001170 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001171 inst = inst->Next_2xx();
1172 } else {
1173 HANDLE_PENDING_EXCEPTION();
1174 }
1175 break;
1176 }
1177 case Instruction::IGET_BOOLEAN: {
1178 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001179 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1180 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001181 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1182 break;
1183 }
1184 case Instruction::IGET_BYTE: {
1185 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001186 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1187 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001188 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1189 break;
1190 }
1191 case Instruction::IGET_CHAR: {
1192 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001193 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1194 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001195 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1196 break;
1197 }
1198 case Instruction::IGET_SHORT: {
1199 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001200 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1201 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001202 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1203 break;
1204 }
1205 case Instruction::IGET: {
1206 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001207 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1208 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001209 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1210 break;
1211 }
1212 case Instruction::IGET_WIDE: {
1213 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001214 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1215 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001216 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1217 break;
1218 }
1219 case Instruction::IGET_OBJECT: {
1220 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001221 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1222 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001223 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1224 break;
1225 }
1226 case Instruction::IGET_QUICK: {
1227 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001228 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001229 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1230 break;
1231 }
1232 case Instruction::IGET_WIDE_QUICK: {
1233 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001234 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001235 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1236 break;
1237 }
1238 case Instruction::IGET_OBJECT_QUICK: {
1239 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001240 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001241 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1242 break;
1243 }
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001244 case Instruction::IGET_BOOLEAN_QUICK: {
1245 PREAMBLE();
1246 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1247 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1248 break;
1249 }
1250 case Instruction::IGET_BYTE_QUICK: {
1251 PREAMBLE();
1252 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1253 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1254 break;
1255 }
1256 case Instruction::IGET_CHAR_QUICK: {
1257 PREAMBLE();
1258 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1259 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1260 break;
1261 }
1262 case Instruction::IGET_SHORT_QUICK: {
1263 PREAMBLE();
1264 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1265 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1266 break;
1267 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001268 case Instruction::SGET_BOOLEAN: {
1269 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001270 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1271 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001272 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1273 break;
1274 }
1275 case Instruction::SGET_BYTE: {
1276 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001277 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(
1278 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001279 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1280 break;
1281 }
1282 case Instruction::SGET_CHAR: {
1283 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001284 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(
1285 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001286 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1287 break;
1288 }
1289 case Instruction::SGET_SHORT: {
1290 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001291 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(
1292 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001293 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1294 break;
1295 }
1296 case Instruction::SGET: {
1297 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001298 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(
1299 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001300 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1301 break;
1302 }
1303 case Instruction::SGET_WIDE: {
1304 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001305 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(
1306 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001307 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1308 break;
1309 }
1310 case Instruction::SGET_OBJECT: {
1311 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001312 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(
1313 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001314 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1315 break;
1316 }
1317 case Instruction::IPUT_BOOLEAN: {
1318 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001319 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1320 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001321 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1322 break;
1323 }
1324 case Instruction::IPUT_BYTE: {
1325 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001326 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1327 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001328 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1329 break;
1330 }
1331 case Instruction::IPUT_CHAR: {
1332 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001333 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1334 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001335 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1336 break;
1337 }
1338 case Instruction::IPUT_SHORT: {
1339 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001340 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1341 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001342 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1343 break;
1344 }
1345 case Instruction::IPUT: {
1346 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001347 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1348 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001349 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1350 break;
1351 }
1352 case Instruction::IPUT_WIDE: {
1353 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001354 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1355 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001356 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1357 break;
1358 }
1359 case Instruction::IPUT_OBJECT: {
1360 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001361 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1362 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001363 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1364 break;
1365 }
1366 case Instruction::IPUT_QUICK: {
1367 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001368 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1369 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001370 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1371 break;
1372 }
Fred Shih37f05ef2014-07-16 18:38:08 -07001373 case Instruction::IPUT_BOOLEAN_QUICK: {
1374 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001375 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1376 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001377 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1378 break;
1379 }
1380 case Instruction::IPUT_BYTE_QUICK: {
1381 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001382 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1383 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001384 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1385 break;
1386 }
1387 case Instruction::IPUT_CHAR_QUICK: {
1388 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001389 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1390 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001391 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1392 break;
1393 }
1394 case Instruction::IPUT_SHORT_QUICK: {
1395 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001396 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1397 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001398 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1399 break;
1400 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001401 case Instruction::IPUT_WIDE_QUICK: {
1402 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001403 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1404 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001405 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1406 break;
1407 }
1408 case Instruction::IPUT_OBJECT_QUICK: {
1409 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001410 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1411 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001412 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1413 break;
1414 }
1415 case Instruction::SPUT_BOOLEAN: {
1416 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001417 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1418 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001419 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1420 break;
1421 }
1422 case Instruction::SPUT_BYTE: {
1423 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001424 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1425 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001426 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1427 break;
1428 }
1429 case Instruction::SPUT_CHAR: {
1430 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001431 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1432 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001433 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1434 break;
1435 }
1436 case Instruction::SPUT_SHORT: {
1437 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001438 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1439 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001440 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1441 break;
1442 }
1443 case Instruction::SPUT: {
1444 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001445 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1446 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001447 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1448 break;
1449 }
1450 case Instruction::SPUT_WIDE: {
1451 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001452 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1453 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001454 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1455 break;
1456 }
1457 case Instruction::SPUT_OBJECT: {
1458 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001459 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1460 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001461 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1462 break;
1463 }
1464 case Instruction::INVOKE_VIRTUAL: {
1465 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001466 bool success = DoInvoke<kVirtual, false, do_access_check>(
1467 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001468 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1469 break;
1470 }
1471 case Instruction::INVOKE_VIRTUAL_RANGE: {
1472 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001473 bool success = DoInvoke<kVirtual, true, do_access_check>(
1474 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001475 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1476 break;
1477 }
1478 case Instruction::INVOKE_SUPER: {
1479 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001480 bool success = DoInvoke<kSuper, false, do_access_check>(
1481 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001482 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1483 break;
1484 }
1485 case Instruction::INVOKE_SUPER_RANGE: {
1486 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001487 bool success = DoInvoke<kSuper, true, do_access_check>(
1488 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001489 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1490 break;
1491 }
1492 case Instruction::INVOKE_DIRECT: {
1493 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001494 bool success = DoInvoke<kDirect, false, do_access_check>(
1495 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001496 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1497 break;
1498 }
1499 case Instruction::INVOKE_DIRECT_RANGE: {
1500 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001501 bool success = DoInvoke<kDirect, true, do_access_check>(
1502 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001503 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1504 break;
1505 }
1506 case Instruction::INVOKE_INTERFACE: {
1507 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001508 bool success = DoInvoke<kInterface, false, do_access_check>(
1509 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001510 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1511 break;
1512 }
1513 case Instruction::INVOKE_INTERFACE_RANGE: {
1514 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001515 bool success = DoInvoke<kInterface, true, do_access_check>(
1516 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001517 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1518 break;
1519 }
1520 case Instruction::INVOKE_STATIC: {
1521 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001522 bool success = DoInvoke<kStatic, false, do_access_check>(
1523 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001524 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1525 break;
1526 }
1527 case Instruction::INVOKE_STATIC_RANGE: {
1528 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001529 bool success = DoInvoke<kStatic, true, do_access_check>(
1530 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001531 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1532 break;
1533 }
1534 case Instruction::INVOKE_VIRTUAL_QUICK: {
1535 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001536 bool success = DoInvokeVirtualQuick<false>(
1537 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001538 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1539 break;
1540 }
1541 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
1542 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001543 bool success = DoInvokeVirtualQuick<true>(
1544 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001545 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1546 break;
1547 }
1548 case Instruction::NEG_INT:
1549 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001550 shadow_frame.SetVReg(
1551 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001552 inst = inst->Next_1xx();
1553 break;
1554 case Instruction::NOT_INT:
1555 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001556 shadow_frame.SetVReg(
1557 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001558 inst = inst->Next_1xx();
1559 break;
1560 case Instruction::NEG_LONG:
1561 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001562 shadow_frame.SetVRegLong(
1563 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001564 inst = inst->Next_1xx();
1565 break;
1566 case Instruction::NOT_LONG:
1567 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001568 shadow_frame.SetVRegLong(
1569 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001570 inst = inst->Next_1xx();
1571 break;
1572 case Instruction::NEG_FLOAT:
1573 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001574 shadow_frame.SetVRegFloat(
1575 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001576 inst = inst->Next_1xx();
1577 break;
1578 case Instruction::NEG_DOUBLE:
1579 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001580 shadow_frame.SetVRegDouble(
1581 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001582 inst = inst->Next_1xx();
1583 break;
1584 case Instruction::INT_TO_LONG:
1585 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001586 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
1587 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001588 inst = inst->Next_1xx();
1589 break;
1590 case Instruction::INT_TO_FLOAT:
1591 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001592 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1593 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001594 inst = inst->Next_1xx();
1595 break;
1596 case Instruction::INT_TO_DOUBLE:
1597 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001598 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1599 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001600 inst = inst->Next_1xx();
1601 break;
1602 case Instruction::LONG_TO_INT:
1603 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001604 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1605 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001606 inst = inst->Next_1xx();
1607 break;
1608 case Instruction::LONG_TO_FLOAT:
1609 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001610 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1611 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001612 inst = inst->Next_1xx();
1613 break;
1614 case Instruction::LONG_TO_DOUBLE:
1615 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001616 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1617 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001618 inst = inst->Next_1xx();
1619 break;
1620 case Instruction::FLOAT_TO_INT: {
1621 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001622 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001623 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001624 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001625 inst = inst->Next_1xx();
1626 break;
1627 }
1628 case Instruction::FLOAT_TO_LONG: {
1629 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001630 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001631 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001632 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001633 inst = inst->Next_1xx();
1634 break;
1635 }
1636 case Instruction::FLOAT_TO_DOUBLE:
1637 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001638 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1639 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001640 inst = inst->Next_1xx();
1641 break;
1642 case Instruction::DOUBLE_TO_INT: {
1643 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001644 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001645 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001646 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001647 inst = inst->Next_1xx();
1648 break;
1649 }
1650 case Instruction::DOUBLE_TO_LONG: {
1651 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001652 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001653 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001654 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001655 inst = inst->Next_1xx();
1656 break;
1657 }
1658 case Instruction::DOUBLE_TO_FLOAT:
1659 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001660 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1661 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001662 inst = inst->Next_1xx();
1663 break;
1664 case Instruction::INT_TO_BYTE:
1665 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001666 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int8_t>(
1667 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001668 inst = inst->Next_1xx();
1669 break;
1670 case Instruction::INT_TO_CHAR:
1671 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001672 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<uint16_t>(
1673 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001674 inst = inst->Next_1xx();
1675 break;
1676 case Instruction::INT_TO_SHORT:
1677 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001678 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int16_t>(
1679 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001680 inst = inst->Next_1xx();
1681 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001682 case Instruction::ADD_INT: {
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001683 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001684 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001685 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1686 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001687 inst = inst->Next_2xx();
1688 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001689 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001690 case Instruction::SUB_INT:
1691 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001692 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001693 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1694 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001695 inst = inst->Next_2xx();
1696 break;
1697 case Instruction::MUL_INT:
1698 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001699 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001700 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1701 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001702 inst = inst->Next_2xx();
1703 break;
1704 case Instruction::DIV_INT: {
1705 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001706 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001707 shadow_frame.GetVReg(inst->VRegB_23x()),
1708 shadow_frame.GetVReg(inst->VRegC_23x()));
1709 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1710 break;
1711 }
1712 case Instruction::REM_INT: {
1713 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001714 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001715 shadow_frame.GetVReg(inst->VRegB_23x()),
1716 shadow_frame.GetVReg(inst->VRegC_23x()));
1717 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1718 break;
1719 }
1720 case Instruction::SHL_INT:
1721 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001722 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001723 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1724 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1725 inst = inst->Next_2xx();
1726 break;
1727 case Instruction::SHR_INT:
1728 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001729 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001730 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1731 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1732 inst = inst->Next_2xx();
1733 break;
1734 case Instruction::USHR_INT:
1735 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001736 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001737 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1738 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1739 inst = inst->Next_2xx();
1740 break;
1741 case Instruction::AND_INT:
1742 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001743 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001744 shadow_frame.GetVReg(inst->VRegB_23x()) &
1745 shadow_frame.GetVReg(inst->VRegC_23x()));
1746 inst = inst->Next_2xx();
1747 break;
1748 case Instruction::OR_INT:
1749 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001750 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001751 shadow_frame.GetVReg(inst->VRegB_23x()) |
1752 shadow_frame.GetVReg(inst->VRegC_23x()));
1753 inst = inst->Next_2xx();
1754 break;
1755 case Instruction::XOR_INT:
1756 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001757 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001758 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1759 shadow_frame.GetVReg(inst->VRegC_23x()));
1760 inst = inst->Next_2xx();
1761 break;
1762 case Instruction::ADD_LONG:
1763 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001764 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001765 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1766 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001767 inst = inst->Next_2xx();
1768 break;
1769 case Instruction::SUB_LONG:
1770 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001771 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001772 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1773 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001774 inst = inst->Next_2xx();
1775 break;
1776 case Instruction::MUL_LONG:
1777 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001778 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001779 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1780 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001781 inst = inst->Next_2xx();
1782 break;
1783 case Instruction::DIV_LONG:
1784 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001785 DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001786 shadow_frame.GetVRegLong(inst->VRegB_23x()),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001787 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001788 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1789 break;
1790 case Instruction::REM_LONG:
1791 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001792 DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001793 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1794 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1795 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1796 break;
1797 case Instruction::AND_LONG:
1798 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001799 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001800 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1801 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1802 inst = inst->Next_2xx();
1803 break;
1804 case Instruction::OR_LONG:
1805 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001806 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001807 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1808 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1809 inst = inst->Next_2xx();
1810 break;
1811 case Instruction::XOR_LONG:
1812 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001813 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001814 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1815 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1816 inst = inst->Next_2xx();
1817 break;
1818 case Instruction::SHL_LONG:
1819 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001820 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001821 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1822 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1823 inst = inst->Next_2xx();
1824 break;
1825 case Instruction::SHR_LONG:
1826 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001827 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001828 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1829 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1830 inst = inst->Next_2xx();
1831 break;
1832 case Instruction::USHR_LONG:
1833 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001834 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001835 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1836 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1837 inst = inst->Next_2xx();
1838 break;
1839 case Instruction::ADD_FLOAT:
1840 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001841 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001842 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1843 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1844 inst = inst->Next_2xx();
1845 break;
1846 case Instruction::SUB_FLOAT:
1847 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001848 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001849 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1850 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1851 inst = inst->Next_2xx();
1852 break;
1853 case Instruction::MUL_FLOAT:
1854 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001855 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001856 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1857 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1858 inst = inst->Next_2xx();
1859 break;
1860 case Instruction::DIV_FLOAT:
1861 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001862 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001863 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1864 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1865 inst = inst->Next_2xx();
1866 break;
1867 case Instruction::REM_FLOAT:
1868 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001869 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001870 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1871 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1872 inst = inst->Next_2xx();
1873 break;
1874 case Instruction::ADD_DOUBLE:
1875 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001876 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001877 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1878 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1879 inst = inst->Next_2xx();
1880 break;
1881 case Instruction::SUB_DOUBLE:
1882 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001883 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001884 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1885 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1886 inst = inst->Next_2xx();
1887 break;
1888 case Instruction::MUL_DOUBLE:
1889 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001890 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001891 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
1892 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1893 inst = inst->Next_2xx();
1894 break;
1895 case Instruction::DIV_DOUBLE:
1896 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001897 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001898 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
1899 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1900 inst = inst->Next_2xx();
1901 break;
1902 case Instruction::REM_DOUBLE:
1903 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001904 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001905 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
1906 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
1907 inst = inst->Next_2xx();
1908 break;
1909 case Instruction::ADD_INT_2ADDR: {
1910 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001911 uint4_t vregA = inst->VRegA_12x(inst_data);
Ian Rogersf72a11d2014-10-30 15:41:08 -07001912 shadow_frame.SetVReg(vregA, SafeAdd(shadow_frame.GetVReg(vregA),
1913 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001914 inst = inst->Next_1xx();
1915 break;
1916 }
1917 case Instruction::SUB_INT_2ADDR: {
1918 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001919 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001920 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001921 SafeSub(shadow_frame.GetVReg(vregA),
1922 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001923 inst = inst->Next_1xx();
1924 break;
1925 }
1926 case Instruction::MUL_INT_2ADDR: {
1927 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001928 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001929 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001930 SafeMul(shadow_frame.GetVReg(vregA),
1931 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001932 inst = inst->Next_1xx();
1933 break;
1934 }
1935 case Instruction::DIV_INT_2ADDR: {
1936 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001937 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001938 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001939 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001940 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1941 break;
1942 }
1943 case Instruction::REM_INT_2ADDR: {
1944 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001945 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001946 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001947 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001948 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1949 break;
1950 }
1951 case Instruction::SHL_INT_2ADDR: {
1952 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001953 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001954 shadow_frame.SetVReg(vregA,
1955 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001956 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001957 inst = inst->Next_1xx();
1958 break;
1959 }
1960 case Instruction::SHR_INT_2ADDR: {
1961 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001962 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001963 shadow_frame.SetVReg(vregA,
1964 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001965 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001966 inst = inst->Next_1xx();
1967 break;
1968 }
1969 case Instruction::USHR_INT_2ADDR: {
1970 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001971 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001972 shadow_frame.SetVReg(vregA,
1973 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001974 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001975 inst = inst->Next_1xx();
1976 break;
1977 }
1978 case Instruction::AND_INT_2ADDR: {
1979 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001980 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001981 shadow_frame.SetVReg(vregA,
1982 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001983 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001984 inst = inst->Next_1xx();
1985 break;
1986 }
1987 case Instruction::OR_INT_2ADDR: {
1988 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001989 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001990 shadow_frame.SetVReg(vregA,
1991 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001992 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001993 inst = inst->Next_1xx();
1994 break;
1995 }
1996 case Instruction::XOR_INT_2ADDR: {
1997 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001998 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001999 shadow_frame.SetVReg(vregA,
2000 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002001 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002002 inst = inst->Next_1xx();
2003 break;
2004 }
2005 case Instruction::ADD_LONG_2ADDR: {
2006 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002007 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002008 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002009 SafeAdd(shadow_frame.GetVRegLong(vregA),
2010 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002011 inst = inst->Next_1xx();
2012 break;
2013 }
2014 case Instruction::SUB_LONG_2ADDR: {
2015 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002016 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002017 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002018 SafeSub(shadow_frame.GetVRegLong(vregA),
2019 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002020 inst = inst->Next_1xx();
2021 break;
2022 }
2023 case Instruction::MUL_LONG_2ADDR: {
2024 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002025 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002026 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002027 SafeMul(shadow_frame.GetVRegLong(vregA),
2028 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002029 inst = inst->Next_1xx();
2030 break;
2031 }
2032 case Instruction::DIV_LONG_2ADDR: {
2033 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002034 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002035 DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002036 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002037 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
2038 break;
2039 }
2040 case Instruction::REM_LONG_2ADDR: {
2041 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002042 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002043 DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002044 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002045 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
2046 break;
2047 }
2048 case Instruction::AND_LONG_2ADDR: {
2049 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002050 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002051 shadow_frame.SetVRegLong(vregA,
2052 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002053 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002054 inst = inst->Next_1xx();
2055 break;
2056 }
2057 case Instruction::OR_LONG_2ADDR: {
2058 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002059 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002060 shadow_frame.SetVRegLong(vregA,
2061 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002062 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002063 inst = inst->Next_1xx();
2064 break;
2065 }
2066 case Instruction::XOR_LONG_2ADDR: {
2067 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002068 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002069 shadow_frame.SetVRegLong(vregA,
2070 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002071 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002072 inst = inst->Next_1xx();
2073 break;
2074 }
2075 case Instruction::SHL_LONG_2ADDR: {
2076 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002077 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002078 shadow_frame.SetVRegLong(vregA,
2079 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002080 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002081 inst = inst->Next_1xx();
2082 break;
2083 }
2084 case Instruction::SHR_LONG_2ADDR: {
2085 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002086 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002087 shadow_frame.SetVRegLong(vregA,
2088 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002089 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002090 inst = inst->Next_1xx();
2091 break;
2092 }
2093 case Instruction::USHR_LONG_2ADDR: {
2094 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002095 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002096 shadow_frame.SetVRegLong(vregA,
2097 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002098 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002099 inst = inst->Next_1xx();
2100 break;
2101 }
2102 case Instruction::ADD_FLOAT_2ADDR: {
2103 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002104 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002105 shadow_frame.SetVRegFloat(vregA,
2106 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002107 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002108 inst = inst->Next_1xx();
2109 break;
2110 }
2111 case Instruction::SUB_FLOAT_2ADDR: {
2112 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002113 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002114 shadow_frame.SetVRegFloat(vregA,
2115 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002116 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002117 inst = inst->Next_1xx();
2118 break;
2119 }
2120 case Instruction::MUL_FLOAT_2ADDR: {
2121 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002122 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002123 shadow_frame.SetVRegFloat(vregA,
2124 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002125 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002126 inst = inst->Next_1xx();
2127 break;
2128 }
2129 case Instruction::DIV_FLOAT_2ADDR: {
2130 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002131 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002132 shadow_frame.SetVRegFloat(vregA,
2133 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002134 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002135 inst = inst->Next_1xx();
2136 break;
2137 }
2138 case Instruction::REM_FLOAT_2ADDR: {
2139 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002140 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002141 shadow_frame.SetVRegFloat(vregA,
2142 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002143 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002144 inst = inst->Next_1xx();
2145 break;
2146 }
2147 case Instruction::ADD_DOUBLE_2ADDR: {
2148 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002149 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002150 shadow_frame.SetVRegDouble(vregA,
2151 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002152 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002153 inst = inst->Next_1xx();
2154 break;
2155 }
2156 case Instruction::SUB_DOUBLE_2ADDR: {
2157 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002158 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002159 shadow_frame.SetVRegDouble(vregA,
2160 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002161 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002162 inst = inst->Next_1xx();
2163 break;
2164 }
2165 case Instruction::MUL_DOUBLE_2ADDR: {
2166 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002167 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002168 shadow_frame.SetVRegDouble(vregA,
2169 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002170 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002171 inst = inst->Next_1xx();
2172 break;
2173 }
2174 case Instruction::DIV_DOUBLE_2ADDR: {
2175 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002176 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002177 shadow_frame.SetVRegDouble(vregA,
2178 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002179 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002180 inst = inst->Next_1xx();
2181 break;
2182 }
2183 case Instruction::REM_DOUBLE_2ADDR: {
2184 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002185 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002186 shadow_frame.SetVRegDouble(vregA,
2187 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002188 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002189 inst = inst->Next_1xx();
2190 break;
2191 }
2192 case Instruction::ADD_INT_LIT16:
2193 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002194 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002195 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2196 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002197 inst = inst->Next_2xx();
2198 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07002199 case Instruction::RSUB_INT_LIT16:
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002200 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002201 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002202 SafeSub(inst->VRegC_22s(),
2203 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002204 inst = inst->Next_2xx();
2205 break;
2206 case Instruction::MUL_INT_LIT16:
2207 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002208 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002209 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2210 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002211 inst = inst->Next_2xx();
2212 break;
2213 case Instruction::DIV_INT_LIT16: {
2214 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002215 bool success = DoIntDivide(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002216 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2217 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002218 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2219 break;
2220 }
2221 case Instruction::REM_INT_LIT16: {
2222 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002223 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002224 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2225 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002226 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2227 break;
2228 }
2229 case Instruction::AND_INT_LIT16:
2230 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002231 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2232 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002233 inst->VRegC_22s());
2234 inst = inst->Next_2xx();
2235 break;
2236 case Instruction::OR_INT_LIT16:
2237 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002238 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2239 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002240 inst->VRegC_22s());
2241 inst = inst->Next_2xx();
2242 break;
2243 case Instruction::XOR_INT_LIT16:
2244 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002245 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2246 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002247 inst->VRegC_22s());
2248 inst = inst->Next_2xx();
2249 break;
2250 case Instruction::ADD_INT_LIT8:
2251 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002252 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002253 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002254 inst = inst->Next_2xx();
2255 break;
2256 case Instruction::RSUB_INT_LIT8:
2257 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002258 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002259 SafeSub(inst->VRegC_22b(), shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002260 inst = inst->Next_2xx();
2261 break;
2262 case Instruction::MUL_INT_LIT8:
2263 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002264 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002265 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002266 inst = inst->Next_2xx();
2267 break;
2268 case Instruction::DIV_INT_LIT8: {
2269 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002270 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002271 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2272 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2273 break;
2274 }
2275 case Instruction::REM_INT_LIT8: {
2276 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002277 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002278 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2279 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2280 break;
2281 }
2282 case Instruction::AND_INT_LIT8:
2283 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002284 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002285 shadow_frame.GetVReg(inst->VRegB_22b()) &
2286 inst->VRegC_22b());
2287 inst = inst->Next_2xx();
2288 break;
2289 case Instruction::OR_INT_LIT8:
2290 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002291 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002292 shadow_frame.GetVReg(inst->VRegB_22b()) |
2293 inst->VRegC_22b());
2294 inst = inst->Next_2xx();
2295 break;
2296 case Instruction::XOR_INT_LIT8:
2297 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002298 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002299 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2300 inst->VRegC_22b());
2301 inst = inst->Next_2xx();
2302 break;
2303 case Instruction::SHL_INT_LIT8:
2304 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002305 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002306 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2307 (inst->VRegC_22b() & 0x1f));
2308 inst = inst->Next_2xx();
2309 break;
2310 case Instruction::SHR_INT_LIT8:
2311 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002312 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002313 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2314 (inst->VRegC_22b() & 0x1f));
2315 inst = inst->Next_2xx();
2316 break;
2317 case Instruction::USHR_INT_LIT8:
2318 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002319 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002320 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2321 (inst->VRegC_22b() & 0x1f));
2322 inst = inst->Next_2xx();
2323 break;
2324 case Instruction::UNUSED_3E ... Instruction::UNUSED_43:
Narayan Kamath8ec3bd22016-08-03 12:46:23 +01002325 case Instruction::UNUSED_F3 ... Instruction::UNUSED_F9:
2326 case Instruction::UNUSED_FC ... Instruction::UNUSED_FF:
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002327 case Instruction::UNUSED_79:
2328 case Instruction::UNUSED_7A:
Narayan Kamath8ec3bd22016-08-03 12:46:23 +01002329 case Instruction::INVOKE_POLYMORPHIC:
2330 case Instruction::INVOKE_POLYMORPHIC_RANGE:
Ian Rogerse94652f2014-12-02 11:13:19 -08002331 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002332 }
buzbee1452bee2015-03-06 14:43:04 -08002333 } while (!interpret_one_instruction);
2334 // Record where we stopped.
2335 shadow_frame.SetDexPC(inst->GetDexPc(insns));
buzbeed6b48db2016-01-28 15:48:55 -08002336 return result_register;
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002337} // NOLINT(readability/fn_size)
2338
2339// Explicit definitions of ExecuteSwitchImpl.
Mathieu Chartier90443472015-07-16 20:32:27 -07002340template SHARED_REQUIRES(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002341JValue ExecuteSwitchImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -08002342 ShadowFrame& shadow_frame, JValue result_register,
2343 bool interpret_one_instruction);
Mathieu Chartier90443472015-07-16 20:32:27 -07002344template SHARED_REQUIRES(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002345JValue ExecuteSwitchImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -08002346 ShadowFrame& shadow_frame, JValue result_register,
2347 bool interpret_one_instruction);
Mathieu Chartier90443472015-07-16 20:32:27 -07002348template SHARED_REQUIRES(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002349JValue ExecuteSwitchImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -08002350 ShadowFrame& shadow_frame, JValue result_register,
2351 bool interpret_one_instruction);
Mathieu Chartier90443472015-07-16 20:32:27 -07002352template SHARED_REQUIRES(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002353JValue ExecuteSwitchImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -08002354 ShadowFrame& shadow_frame, JValue result_register,
2355 bool interpret_one_instruction);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002356
2357} // namespace interpreter
2358} // namespace art