blob: dd10052ebde06dae278c5a8f181a73ec83652400 [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 Gampe5e26eb12016-08-22 17:54:17 -070017#include "interpreter_switch_impl.h"
18
Andreas Gampe542451c2016-07-26 09:02:02 -070019#include "base/enums.h"
Alex Lighteb7c1442015-08-31 13:17:42 -070020#include "experimental_flags.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020021#include "interpreter_common.h"
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000022#include "jit/jit.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070023#include "safe_math.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020024
25namespace art {
26namespace interpreter {
27
28#define HANDLE_PENDING_EXCEPTION() \
29 do { \
Sebastien Hertz82aeddb2014-05-20 20:09:45 +020030 DCHECK(self->IsExceptionPending()); \
Ian Rogers7b078e82014-09-10 14:44:24 -070031 self->AllowThreadSuspension(); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020032 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, \
33 inst->GetDexPc(insns), \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020034 instrumentation); \
35 if (found_dex_pc == DexFile::kDexNoIndex) { \
Andreas Gampe03ec9302015-08-27 17:41:47 -070036 /* Structured locking is to be enforced for abnormal termination, too. */ \
Andreas Gampe56fdd0e2016-04-28 14:56:54 -070037 DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame); \
buzbee1452bee2015-03-06 14:43:04 -080038 if (interpret_one_instruction) { \
buzbee93e94f22016-04-07 13:52:48 -070039 /* Signal mterp to return to caller */ \
buzbee1452bee2015-03-06 14:43:04 -080040 shadow_frame.SetDexPC(DexFile::kDexNoIndex); \
41 } \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020042 return JValue(); /* Handled in caller. */ \
43 } else { \
44 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc); \
45 inst = inst->RelativeAt(displacement); \
46 } \
47 } while (false)
48
49#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _next_function) \
50 do { \
51 if (UNLIKELY(_is_exception_pending)) { \
52 HANDLE_PENDING_EXCEPTION(); \
53 } else { \
54 inst = inst->_next_function(); \
55 } \
56 } while (false)
57
Andreas Gampe03ec9302015-08-27 17:41:47 -070058#define HANDLE_MONITOR_CHECKS() \
Andreas Gampe56fdd0e2016-04-28 14:56:54 -070059 if (!DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame)) { \
Andreas Gampe03ec9302015-08-27 17:41:47 -070060 HANDLE_PENDING_EXCEPTION(); \
61 }
62
Sebastien Hertz8ece0502013-08-07 11:26:41 +020063// Code to run before each dex instruction.
Sebastien Hertz8379b222014-02-24 17:38:15 +010064#define PREAMBLE() \
65 do { \
Sebastien Hertz9d6bf692015-04-10 12:12:33 +020066 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
Sebastien Hertz8379b222014-02-24 17:38:15 +010067 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), \
68 shadow_frame.GetMethod(), dex_pc); \
69 } \
70 } while (false)
Sebastien Hertz8ece0502013-08-07 11:26:41 +020071
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000072#define BRANCH_INSTRUMENTATION(offset) \
73 do { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010074 if (UNLIKELY(instrumentation->HasBranchListeners())) { \
75 instrumentation->Branch(self, method, dex_pc, offset); \
76 } \
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000077 JValue result; \
78 if (jit::Jit::MaybeDoOnStackReplacement(self, method, dex_pc, offset, &result)) { \
buzbee93e94f22016-04-07 13:52:48 -070079 if (interpret_one_instruction) { \
80 /* OSR has completed execution of the method. Signal mterp to return to caller */ \
81 shadow_frame.SetDexPC(DexFile::kDexNoIndex); \
82 } \
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000083 return result; \
84 } \
Nicolas Geoffray3108daf2015-11-24 16:32:33 +000085 } while (false)
86
Bill Buzbee1d011d92016-04-04 16:59:29 +000087#define HOTNESS_UPDATE() \
88 do { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010089 if (jit != nullptr) { \
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +010090 jit->AddSamples(self, method, 1, /*with_backedges*/ true); \
Bill Buzbee1d011d92016-04-04 16:59:29 +000091 } \
92 } while (false)
93
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010094template<bool do_access_check, bool transaction_active>
Ian Rogerse94652f2014-12-02 11:13:19 -080095JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -080096 ShadowFrame& shadow_frame, JValue result_register,
97 bool interpret_one_instruction) {
Igor Murashkinc449e8b2015-06-10 15:56:42 -070098 constexpr bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +020099 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
100 LOG(FATAL) << "Invalid shadow frame for interpreter use";
101 return JValue();
102 }
103 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200104
105 uint32_t dex_pc = shadow_frame.GetDexPC();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700106 const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200107 const uint16_t* const insns = code_item->insns_;
108 const Instruction* inst = Instruction::At(insns + dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200109 uint16_t inst_data;
Bill Buzbee1d011d92016-04-04 16:59:29 +0000110 ArtMethod* method = shadow_frame.GetMethod();
111 jit::Jit* jit = Runtime::Current()->GetJit();
Igor Murashkin6918bf12015-09-27 19:19:06 -0700112
buzbee1452bee2015-03-06 14:43:04 -0800113 do {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200114 dex_pc = inst->GetDexPc(insns);
115 shadow_frame.SetDexPC(dex_pc);
Ian Rogerse94652f2014-12-02 11:13:19 -0800116 TraceExecution(shadow_frame, inst, dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200117 inst_data = inst->Fetch16(0);
118 switch (inst->Opcode(inst_data)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200119 case Instruction::NOP:
120 PREAMBLE();
121 inst = inst->Next_1xx();
122 break;
123 case Instruction::MOVE:
124 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200125 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
126 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200127 inst = inst->Next_1xx();
128 break;
129 case Instruction::MOVE_FROM16:
130 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200131 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200132 shadow_frame.GetVReg(inst->VRegB_22x()));
133 inst = inst->Next_2xx();
134 break;
135 case Instruction::MOVE_16:
136 PREAMBLE();
137 shadow_frame.SetVReg(inst->VRegA_32x(),
138 shadow_frame.GetVReg(inst->VRegB_32x()));
139 inst = inst->Next_3xx();
140 break;
141 case Instruction::MOVE_WIDE:
142 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200143 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
144 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200145 inst = inst->Next_1xx();
146 break;
147 case Instruction::MOVE_WIDE_FROM16:
148 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200149 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200150 shadow_frame.GetVRegLong(inst->VRegB_22x()));
151 inst = inst->Next_2xx();
152 break;
153 case Instruction::MOVE_WIDE_16:
154 PREAMBLE();
155 shadow_frame.SetVRegLong(inst->VRegA_32x(),
156 shadow_frame.GetVRegLong(inst->VRegB_32x()));
157 inst = inst->Next_3xx();
158 break;
159 case Instruction::MOVE_OBJECT:
160 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200161 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
162 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200163 inst = inst->Next_1xx();
164 break;
165 case Instruction::MOVE_OBJECT_FROM16:
166 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200167 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200168 shadow_frame.GetVRegReference(inst->VRegB_22x()));
169 inst = inst->Next_2xx();
170 break;
171 case Instruction::MOVE_OBJECT_16:
172 PREAMBLE();
173 shadow_frame.SetVRegReference(inst->VRegA_32x(),
174 shadow_frame.GetVRegReference(inst->VRegB_32x()));
175 inst = inst->Next_3xx();
176 break;
177 case Instruction::MOVE_RESULT:
178 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200179 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200180 inst = inst->Next_1xx();
181 break;
182 case Instruction::MOVE_RESULT_WIDE:
183 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200184 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200185 inst = inst->Next_1xx();
186 break;
187 case Instruction::MOVE_RESULT_OBJECT:
188 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200189 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200190 inst = inst->Next_1xx();
191 break;
192 case Instruction::MOVE_EXCEPTION: {
193 PREAMBLE();
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000194 Throwable* exception = self->GetException();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100195 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200196 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception);
Sebastien Hertz5c004902014-05-21 10:07:42 +0200197 self->ClearException();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200198 inst = inst->Next_1xx();
199 break;
200 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700201 case Instruction::RETURN_VOID_NO_BARRIER: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200202 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200203 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700204 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700205 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200206 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200207 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200208 shadow_frame.GetMethod(), inst->GetDexPc(insns),
209 result);
210 }
buzbee1452bee2015-03-06 14:43:04 -0800211 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700212 /* Signal mterp to return to caller */
buzbee1452bee2015-03-06 14:43:04 -0800213 shadow_frame.SetDexPC(DexFile::kDexNoIndex);
214 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200215 return result;
216 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700217 case Instruction::RETURN_VOID: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200218 PREAMBLE();
Hans Boehm30359612014-05-21 17:46:23 -0700219 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200220 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700221 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700222 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200223 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200224 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200225 shadow_frame.GetMethod(), inst->GetDexPc(insns),
226 result);
227 }
buzbee1452bee2015-03-06 14:43:04 -0800228 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700229 /* Signal mterp to return to caller */
buzbee1452bee2015-03-06 14:43:04 -0800230 shadow_frame.SetDexPC(DexFile::kDexNoIndex);
231 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200232 return result;
233 }
234 case Instruction::RETURN: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200235 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200236 JValue result;
237 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200238 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700239 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700240 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200241 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200242 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200243 shadow_frame.GetMethod(), inst->GetDexPc(insns),
244 result);
245 }
buzbee1452bee2015-03-06 14:43:04 -0800246 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700247 /* Signal mterp to return to caller */
buzbee1452bee2015-03-06 14:43:04 -0800248 shadow_frame.SetDexPC(DexFile::kDexNoIndex);
249 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200250 return result;
251 }
252 case Instruction::RETURN_WIDE: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200253 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200254 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200255 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700256 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700257 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200258 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200259 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200260 shadow_frame.GetMethod(), inst->GetDexPc(insns),
261 result);
262 }
buzbee1452bee2015-03-06 14:43:04 -0800263 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700264 /* Signal mterp to return to caller */
buzbee1452bee2015-03-06 14:43:04 -0800265 shadow_frame.SetDexPC(DexFile::kDexNoIndex);
266 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200267 return result;
268 }
269 case Instruction::RETURN_OBJECT: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200270 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200271 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700272 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700273 HANDLE_MONITOR_CHECKS();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700274 const size_t ref_idx = inst->VRegA_11x(inst_data);
275 Object* obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700276 if (do_assignability_check && obj_result != nullptr) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700277 PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Vladimir Marko05792b92015-08-03 11:56:49 +0100278 Class* return_type = shadow_frame.GetMethod()->GetReturnType(true /* resolve */,
279 pointer_size);
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700280 // Re-load since it might have moved.
281 obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700282 if (return_type == nullptr) {
Jeff Haoa3faaf42013-09-03 19:07:00 -0700283 // Return the pending exception.
284 HANDLE_PENDING_EXCEPTION();
285 }
286 if (!obj_result->VerifierInstanceOf(return_type)) {
287 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700288 std::string temp1, temp2;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000289 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700290 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700291 obj_result->GetClass()->GetDescriptor(&temp1),
292 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700293 HANDLE_PENDING_EXCEPTION();
294 }
295 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700296 result.SetL(obj_result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200297 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200298 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200299 shadow_frame.GetMethod(), inst->GetDexPc(insns),
300 result);
301 }
buzbee1452bee2015-03-06 14:43:04 -0800302 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700303 /* Signal mterp to return to caller */
buzbee1452bee2015-03-06 14:43:04 -0800304 shadow_frame.SetDexPC(DexFile::kDexNoIndex);
305 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200306 return result;
307 }
308 case Instruction::CONST_4: {
309 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200310 uint4_t dst = inst->VRegA_11n(inst_data);
311 int4_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200312 shadow_frame.SetVReg(dst, val);
313 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700314 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200315 }
316 inst = inst->Next_1xx();
317 break;
318 }
319 case Instruction::CONST_16: {
320 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200321 uint8_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200322 int16_t val = inst->VRegB_21s();
323 shadow_frame.SetVReg(dst, val);
324 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700325 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200326 }
327 inst = inst->Next_2xx();
328 break;
329 }
330 case Instruction::CONST: {
331 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200332 uint8_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200333 int32_t val = inst->VRegB_31i();
334 shadow_frame.SetVReg(dst, val);
335 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700336 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200337 }
338 inst = inst->Next_3xx();
339 break;
340 }
341 case Instruction::CONST_HIGH16: {
342 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200343 uint8_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200344 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
345 shadow_frame.SetVReg(dst, val);
346 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700347 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200348 }
349 inst = inst->Next_2xx();
350 break;
351 }
352 case Instruction::CONST_WIDE_16:
353 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200354 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200355 inst = inst->Next_2xx();
356 break;
357 case Instruction::CONST_WIDE_32:
358 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200359 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200360 inst = inst->Next_3xx();
361 break;
362 case Instruction::CONST_WIDE:
363 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200364 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200365 inst = inst->Next_51l();
366 break;
367 case Instruction::CONST_WIDE_HIGH16:
Sebastien Hertz3c5aec12014-06-04 09:41:21 +0200368 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200369 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200370 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
371 inst = inst->Next_2xx();
372 break;
373 case Instruction::CONST_STRING: {
374 PREAMBLE();
Ian Rogers6786a582014-10-28 12:49:06 -0700375 String* s = ResolveString(self, shadow_frame, inst->VRegB_21c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700376 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200377 HANDLE_PENDING_EXCEPTION();
378 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200379 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200380 inst = inst->Next_2xx();
381 }
382 break;
383 }
384 case Instruction::CONST_STRING_JUMBO: {
385 PREAMBLE();
Ian Rogers6786a582014-10-28 12:49:06 -0700386 String* s = ResolveString(self, shadow_frame, inst->VRegB_31c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700387 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200388 HANDLE_PENDING_EXCEPTION();
389 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200390 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200391 inst = inst->Next_3xx();
392 }
393 break;
394 }
395 case Instruction::CONST_CLASS: {
396 PREAMBLE();
397 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
398 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700399 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200400 HANDLE_PENDING_EXCEPTION();
401 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200402 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200403 inst = inst->Next_2xx();
404 }
405 break;
406 }
407 case Instruction::MONITOR_ENTER: {
408 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200409 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700410 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000411 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200412 HANDLE_PENDING_EXCEPTION();
413 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700414 DoMonitorEnter<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200415 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
416 }
417 break;
418 }
419 case Instruction::MONITOR_EXIT: {
420 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200421 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700422 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000423 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200424 HANDLE_PENDING_EXCEPTION();
425 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700426 DoMonitorExit<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200427 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
428 }
429 break;
430 }
431 case Instruction::CHECK_CAST: {
432 PREAMBLE();
433 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
434 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700435 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200436 HANDLE_PENDING_EXCEPTION();
437 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200438 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700439 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200440 ThrowClassCastException(c, obj->GetClass());
441 HANDLE_PENDING_EXCEPTION();
442 } else {
443 inst = inst->Next_2xx();
444 }
445 }
446 break;
447 }
448 case Instruction::INSTANCE_OF: {
449 PREAMBLE();
450 Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(),
451 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700452 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200453 HANDLE_PENDING_EXCEPTION();
454 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200455 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700456 shadow_frame.SetVReg(inst->VRegA_22c(inst_data),
457 (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200458 inst = inst->Next_2xx();
459 }
460 break;
461 }
462 case Instruction::ARRAY_LENGTH: {
463 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200464 Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700465 if (UNLIKELY(array == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000466 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200467 HANDLE_PENDING_EXCEPTION();
468 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200469 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200470 inst = inst->Next_1xx();
471 }
472 break;
473 }
474 case Instruction::NEW_INSTANCE: {
475 PREAMBLE();
Jeff Hao848f70a2014-01-15 13:49:50 -0800476 Object* obj = nullptr;
477 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
478 self, false, do_access_check);
479 if (LIKELY(c != nullptr)) {
480 if (UNLIKELY(c->IsStringClass())) {
481 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
482 mirror::SetStringCountVisitor visitor(0);
483 obj = String::Alloc<true>(self, 0, allocator_type, visitor);
484 } else {
485 obj = AllocObjectFromCode<do_access_check, true>(
486 inst->VRegB_21c(), shadow_frame.GetMethod(), self,
487 Runtime::Current()->GetHeap()->GetCurrentAllocator());
488 }
489 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700490 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200491 HANDLE_PENDING_EXCEPTION();
492 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200493 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700494 // Don't allow finalizable objects to be allocated during a transaction since these can't
495 // be finalized without a started runtime.
496 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200497 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
498 PrettyTypeOf(obj).c_str());
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700499 HANDLE_PENDING_EXCEPTION();
500 break;
501 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200502 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200503 inst = inst->Next_2xx();
504 }
505 break;
506 }
507 case Instruction::NEW_ARRAY: {
508 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200509 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800510 Object* obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampe1cc7dba2014-12-17 18:43:01 -0800511 inst->VRegC_22c(), length, shadow_frame.GetMethod(), self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800512 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700513 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200514 HANDLE_PENDING_EXCEPTION();
515 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200516 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200517 inst = inst->Next_2xx();
518 }
519 break;
520 }
521 case Instruction::FILLED_NEW_ARRAY: {
522 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100523 bool success =
524 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame, self,
525 &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200526 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
527 break;
528 }
529 case Instruction::FILLED_NEW_ARRAY_RANGE: {
530 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100531 bool success =
532 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
533 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200534 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
535 break;
536 }
537 case Instruction::FILL_ARRAY_DATA: {
538 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200539 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
540 const Instruction::ArrayDataPayload* payload =
541 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
Ian Rogers832336b2014-10-08 15:35:22 -0700542 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
543 bool success = FillArrayData(obj, payload);
544 if (!success) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200545 HANDLE_PENDING_EXCEPTION();
546 break;
547 }
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100548 if (transaction_active) {
Ian Rogers832336b2014-10-08 15:35:22 -0700549 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100550 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200551 inst = inst->Next_3xx();
552 break;
553 }
554 case Instruction::THROW: {
555 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200556 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700557 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000558 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700559 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
560 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700561 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000562 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700563 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700564 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200565 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000566 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200567 }
568 HANDLE_PENDING_EXCEPTION();
569 break;
570 }
571 case Instruction::GOTO: {
572 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200573 int8_t offset = inst->VRegA_10t(inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000574 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200575 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000576 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700577 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200578 }
579 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200580 break;
581 }
582 case Instruction::GOTO_16: {
583 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200584 int16_t offset = inst->VRegA_20t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000585 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200586 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000587 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700588 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200589 }
590 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200591 break;
592 }
593 case Instruction::GOTO_32: {
594 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200595 int32_t offset = inst->VRegA_30t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000596 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200597 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000598 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700599 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200600 }
601 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200602 break;
603 }
604 case Instruction::PACKED_SWITCH: {
605 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200606 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000607 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200608 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000609 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700610 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200611 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200612 inst = inst->RelativeAt(offset);
613 break;
614 }
615 case Instruction::SPARSE_SWITCH: {
616 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200617 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000618 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200619 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000620 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700621 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200622 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200623 inst = inst->RelativeAt(offset);
624 break;
625 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700626
627#if defined(__clang__)
628#pragma clang diagnostic push
629#pragma clang diagnostic ignored "-Wfloat-equal"
630#endif
631
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200632 case Instruction::CMPL_FLOAT: {
633 PREAMBLE();
634 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
635 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
636 int32_t result;
637 if (val1 > val2) {
638 result = 1;
639 } else if (val1 == val2) {
640 result = 0;
641 } else {
642 result = -1;
643 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200644 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200645 inst = inst->Next_2xx();
646 break;
647 }
648 case Instruction::CMPG_FLOAT: {
649 PREAMBLE();
650 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
651 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
652 int32_t result;
653 if (val1 < val2) {
654 result = -1;
655 } else if (val1 == val2) {
656 result = 0;
657 } else {
658 result = 1;
659 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200660 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200661 inst = inst->Next_2xx();
662 break;
663 }
664 case Instruction::CMPL_DOUBLE: {
665 PREAMBLE();
666 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
667 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
668 int32_t result;
669 if (val1 > val2) {
670 result = 1;
671 } else if (val1 == val2) {
672 result = 0;
673 } else {
674 result = -1;
675 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200676 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200677 inst = inst->Next_2xx();
678 break;
679 }
680
681 case Instruction::CMPG_DOUBLE: {
682 PREAMBLE();
683 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
684 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
685 int32_t result;
686 if (val1 < val2) {
687 result = -1;
688 } else if (val1 == val2) {
689 result = 0;
690 } else {
691 result = 1;
692 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200693 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200694 inst = inst->Next_2xx();
695 break;
696 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700697
698#if defined(__clang__)
699#pragma clang diagnostic pop
700#endif
701
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200702 case Instruction::CMP_LONG: {
703 PREAMBLE();
704 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
705 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
706 int32_t result;
707 if (val1 > val2) {
708 result = 1;
709 } else if (val1 == val2) {
710 result = 0;
711 } else {
712 result = -1;
713 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200714 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200715 inst = inst->Next_2xx();
716 break;
717 }
718 case Instruction::IF_EQ: {
719 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700720 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) ==
721 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200722 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000723 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200724 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000725 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700726 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200727 }
728 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200729 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800730 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200731 inst = inst->Next_2xx();
732 }
733 break;
734 }
735 case Instruction::IF_NE: {
736 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700737 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
738 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200739 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000740 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200741 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000742 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700743 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200744 }
745 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200746 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800747 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200748 inst = inst->Next_2xx();
749 }
750 break;
751 }
752 case Instruction::IF_LT: {
753 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700754 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
755 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200756 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000757 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200758 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000759 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700760 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200761 }
762 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200763 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800764 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200765 inst = inst->Next_2xx();
766 }
767 break;
768 }
769 case Instruction::IF_GE: {
770 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700771 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
772 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200773 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000774 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200775 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000776 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700777 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200778 }
779 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200780 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800781 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200782 inst = inst->Next_2xx();
783 }
784 break;
785 }
786 case Instruction::IF_GT: {
787 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700788 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
789 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200790 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000791 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200792 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000793 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700794 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200795 }
796 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200797 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800798 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200799 inst = inst->Next_2xx();
800 }
801 break;
802 }
803 case Instruction::IF_LE: {
804 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700805 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
806 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200807 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000808 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200809 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000810 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700811 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200812 }
813 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200814 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800815 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200816 inst = inst->Next_2xx();
817 }
818 break;
819 }
820 case Instruction::IF_EQZ: {
821 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200822 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200823 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000824 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200825 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000826 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700827 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200828 }
829 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200830 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800831 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200832 inst = inst->Next_2xx();
833 }
834 break;
835 }
836 case Instruction::IF_NEZ: {
837 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200838 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200839 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000840 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200841 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000842 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700843 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200844 }
845 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200846 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800847 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200848 inst = inst->Next_2xx();
849 }
850 break;
851 }
852 case Instruction::IF_LTZ: {
853 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200854 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200855 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000856 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200857 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000858 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700859 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200860 }
861 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200862 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800863 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200864 inst = inst->Next_2xx();
865 }
866 break;
867 }
868 case Instruction::IF_GEZ: {
869 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200870 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200871 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000872 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200873 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000874 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700875 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200876 }
877 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200878 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800879 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200880 inst = inst->Next_2xx();
881 }
882 break;
883 }
884 case Instruction::IF_GTZ: {
885 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200886 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200887 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000888 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200889 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000890 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700891 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200892 }
893 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200894 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800895 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200896 inst = inst->Next_2xx();
897 }
898 break;
899 }
900 case Instruction::IF_LEZ: {
901 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200902 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200903 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000904 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200905 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000906 HOTNESS_UPDATE();
Ian Rogers7b078e82014-09-10 14:44:24 -0700907 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200908 }
909 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200910 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800911 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200912 inst = inst->Next_2xx();
913 }
914 break;
915 }
916 case Instruction::AGET_BOOLEAN: {
917 PREAMBLE();
918 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700919 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000920 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200921 HANDLE_PENDING_EXCEPTION();
922 break;
923 }
924 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
925 BooleanArray* array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700926 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100927 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200928 inst = inst->Next_2xx();
929 } else {
930 HANDLE_PENDING_EXCEPTION();
931 }
932 break;
933 }
934 case Instruction::AGET_BYTE: {
935 PREAMBLE();
936 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700937 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000938 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200939 HANDLE_PENDING_EXCEPTION();
940 break;
941 }
942 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
943 ByteArray* array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700944 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100945 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200946 inst = inst->Next_2xx();
947 } else {
948 HANDLE_PENDING_EXCEPTION();
949 }
950 break;
951 }
952 case Instruction::AGET_CHAR: {
953 PREAMBLE();
954 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700955 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000956 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200957 HANDLE_PENDING_EXCEPTION();
958 break;
959 }
960 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
961 CharArray* array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700962 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100963 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200964 inst = inst->Next_2xx();
965 } else {
966 HANDLE_PENDING_EXCEPTION();
967 }
968 break;
969 }
970 case Instruction::AGET_SHORT: {
971 PREAMBLE();
972 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700973 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000974 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200975 HANDLE_PENDING_EXCEPTION();
976 break;
977 }
978 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
979 ShortArray* array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700980 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100981 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200982 inst = inst->Next_2xx();
983 } else {
984 HANDLE_PENDING_EXCEPTION();
985 }
986 break;
987 }
988 case Instruction::AGET: {
989 PREAMBLE();
990 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700991 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000992 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200993 HANDLE_PENDING_EXCEPTION();
994 break;
995 }
996 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700997 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
998 auto* array = down_cast<IntArray*>(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700999 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001000 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001001 inst = inst->Next_2xx();
1002 } else {
1003 HANDLE_PENDING_EXCEPTION();
1004 }
1005 break;
1006 }
1007 case Instruction::AGET_WIDE: {
1008 PREAMBLE();
1009 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001010 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001011 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001012 HANDLE_PENDING_EXCEPTION();
1013 break;
1014 }
1015 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001016 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1017 auto* array = down_cast<LongArray*>(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001018 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001019 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001020 inst = inst->Next_2xx();
1021 } else {
1022 HANDLE_PENDING_EXCEPTION();
1023 }
1024 break;
1025 }
1026 case Instruction::AGET_OBJECT: {
1027 PREAMBLE();
1028 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001029 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001030 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001031 HANDLE_PENDING_EXCEPTION();
1032 break;
1033 }
1034 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1035 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001036 if (array->CheckIsValidIndex(index)) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001037 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001038 inst = inst->Next_2xx();
1039 } else {
1040 HANDLE_PENDING_EXCEPTION();
1041 }
1042 break;
1043 }
1044 case Instruction::APUT_BOOLEAN: {
1045 PREAMBLE();
1046 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001047 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001048 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001049 HANDLE_PENDING_EXCEPTION();
1050 break;
1051 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001052 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001053 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1054 BooleanArray* array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001055 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001056 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001057 inst = inst->Next_2xx();
1058 } else {
1059 HANDLE_PENDING_EXCEPTION();
1060 }
1061 break;
1062 }
1063 case Instruction::APUT_BYTE: {
1064 PREAMBLE();
1065 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001066 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001067 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001068 HANDLE_PENDING_EXCEPTION();
1069 break;
1070 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001071 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001072 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1073 ByteArray* array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001074 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001075 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001076 inst = inst->Next_2xx();
1077 } else {
1078 HANDLE_PENDING_EXCEPTION();
1079 }
1080 break;
1081 }
1082 case Instruction::APUT_CHAR: {
1083 PREAMBLE();
1084 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001085 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001086 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001087 HANDLE_PENDING_EXCEPTION();
1088 break;
1089 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001090 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001091 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1092 CharArray* array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001093 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001094 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001095 inst = inst->Next_2xx();
1096 } else {
1097 HANDLE_PENDING_EXCEPTION();
1098 }
1099 break;
1100 }
1101 case Instruction::APUT_SHORT: {
1102 PREAMBLE();
1103 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001104 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001105 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001106 HANDLE_PENDING_EXCEPTION();
1107 break;
1108 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001109 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001110 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1111 ShortArray* array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001112 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001113 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001114 inst = inst->Next_2xx();
1115 } else {
1116 HANDLE_PENDING_EXCEPTION();
1117 }
1118 break;
1119 }
1120 case Instruction::APUT: {
1121 PREAMBLE();
1122 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001123 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001124 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001125 HANDLE_PENDING_EXCEPTION();
1126 break;
1127 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001128 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001129 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001130 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1131 auto* array = down_cast<IntArray*>(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001132 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001133 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001134 inst = inst->Next_2xx();
1135 } else {
1136 HANDLE_PENDING_EXCEPTION();
1137 }
1138 break;
1139 }
1140 case Instruction::APUT_WIDE: {
1141 PREAMBLE();
1142 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001143 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001144 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001145 HANDLE_PENDING_EXCEPTION();
1146 break;
1147 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001148 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001149 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001150 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1151 LongArray* array = down_cast<LongArray*>(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001152 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001153 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001154 inst = inst->Next_2xx();
1155 } else {
1156 HANDLE_PENDING_EXCEPTION();
1157 }
1158 break;
1159 }
1160 case Instruction::APUT_OBJECT: {
1161 PREAMBLE();
1162 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001163 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001164 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001165 HANDLE_PENDING_EXCEPTION();
1166 break;
1167 }
1168 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001169 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001170 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001171 if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001172 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001173 inst = inst->Next_2xx();
1174 } else {
1175 HANDLE_PENDING_EXCEPTION();
1176 }
1177 break;
1178 }
1179 case Instruction::IGET_BOOLEAN: {
1180 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001181 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1182 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001183 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1184 break;
1185 }
1186 case Instruction::IGET_BYTE: {
1187 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001188 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1189 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001190 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1191 break;
1192 }
1193 case Instruction::IGET_CHAR: {
1194 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001195 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1196 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001197 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1198 break;
1199 }
1200 case Instruction::IGET_SHORT: {
1201 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001202 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1203 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001204 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1205 break;
1206 }
1207 case Instruction::IGET: {
1208 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001209 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1210 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001211 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1212 break;
1213 }
1214 case Instruction::IGET_WIDE: {
1215 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001216 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1217 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001218 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1219 break;
1220 }
1221 case Instruction::IGET_OBJECT: {
1222 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001223 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1224 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001225 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1226 break;
1227 }
1228 case Instruction::IGET_QUICK: {
1229 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001230 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001231 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1232 break;
1233 }
1234 case Instruction::IGET_WIDE_QUICK: {
1235 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001236 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001237 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1238 break;
1239 }
1240 case Instruction::IGET_OBJECT_QUICK: {
1241 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001242 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001243 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1244 break;
1245 }
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001246 case Instruction::IGET_BOOLEAN_QUICK: {
1247 PREAMBLE();
1248 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1249 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1250 break;
1251 }
1252 case Instruction::IGET_BYTE_QUICK: {
1253 PREAMBLE();
1254 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1255 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1256 break;
1257 }
1258 case Instruction::IGET_CHAR_QUICK: {
1259 PREAMBLE();
1260 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1261 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1262 break;
1263 }
1264 case Instruction::IGET_SHORT_QUICK: {
1265 PREAMBLE();
1266 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1267 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1268 break;
1269 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001270 case Instruction::SGET_BOOLEAN: {
1271 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001272 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1273 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001274 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1275 break;
1276 }
1277 case Instruction::SGET_BYTE: {
1278 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001279 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(
1280 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001281 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1282 break;
1283 }
1284 case Instruction::SGET_CHAR: {
1285 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001286 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(
1287 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001288 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1289 break;
1290 }
1291 case Instruction::SGET_SHORT: {
1292 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001293 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(
1294 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001295 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1296 break;
1297 }
1298 case Instruction::SGET: {
1299 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001300 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(
1301 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001302 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1303 break;
1304 }
1305 case Instruction::SGET_WIDE: {
1306 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001307 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(
1308 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001309 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1310 break;
1311 }
1312 case Instruction::SGET_OBJECT: {
1313 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001314 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(
1315 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001316 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1317 break;
1318 }
1319 case Instruction::IPUT_BOOLEAN: {
1320 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001321 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1322 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001323 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1324 break;
1325 }
1326 case Instruction::IPUT_BYTE: {
1327 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001328 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1329 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001330 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1331 break;
1332 }
1333 case Instruction::IPUT_CHAR: {
1334 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001335 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1336 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001337 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1338 break;
1339 }
1340 case Instruction::IPUT_SHORT: {
1341 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001342 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1343 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001344 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1345 break;
1346 }
1347 case Instruction::IPUT: {
1348 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001349 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1350 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001351 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1352 break;
1353 }
1354 case Instruction::IPUT_WIDE: {
1355 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001356 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1357 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001358 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1359 break;
1360 }
1361 case Instruction::IPUT_OBJECT: {
1362 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001363 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1364 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001365 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1366 break;
1367 }
1368 case Instruction::IPUT_QUICK: {
1369 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001370 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1371 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001372 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1373 break;
1374 }
Fred Shih37f05ef2014-07-16 18:38:08 -07001375 case Instruction::IPUT_BOOLEAN_QUICK: {
1376 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001377 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1378 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001379 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1380 break;
1381 }
1382 case Instruction::IPUT_BYTE_QUICK: {
1383 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001384 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1385 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001386 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1387 break;
1388 }
1389 case Instruction::IPUT_CHAR_QUICK: {
1390 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001391 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1392 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001393 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1394 break;
1395 }
1396 case Instruction::IPUT_SHORT_QUICK: {
1397 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001398 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1399 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001400 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1401 break;
1402 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001403 case Instruction::IPUT_WIDE_QUICK: {
1404 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001405 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1406 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001407 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1408 break;
1409 }
1410 case Instruction::IPUT_OBJECT_QUICK: {
1411 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001412 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1413 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001414 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1415 break;
1416 }
1417 case Instruction::SPUT_BOOLEAN: {
1418 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001419 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1420 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001421 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1422 break;
1423 }
1424 case Instruction::SPUT_BYTE: {
1425 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001426 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1427 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001428 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1429 break;
1430 }
1431 case Instruction::SPUT_CHAR: {
1432 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001433 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1434 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001435 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1436 break;
1437 }
1438 case Instruction::SPUT_SHORT: {
1439 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001440 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1441 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001442 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1443 break;
1444 }
1445 case Instruction::SPUT: {
1446 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001447 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1448 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001449 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1450 break;
1451 }
1452 case Instruction::SPUT_WIDE: {
1453 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001454 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1455 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001456 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1457 break;
1458 }
1459 case Instruction::SPUT_OBJECT: {
1460 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001461 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1462 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001463 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1464 break;
1465 }
1466 case Instruction::INVOKE_VIRTUAL: {
1467 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001468 bool success = DoInvoke<kVirtual, false, do_access_check>(
1469 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001470 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1471 break;
1472 }
1473 case Instruction::INVOKE_VIRTUAL_RANGE: {
1474 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001475 bool success = DoInvoke<kVirtual, true, do_access_check>(
1476 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001477 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1478 break;
1479 }
1480 case Instruction::INVOKE_SUPER: {
1481 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001482 bool success = DoInvoke<kSuper, false, do_access_check>(
1483 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001484 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1485 break;
1486 }
1487 case Instruction::INVOKE_SUPER_RANGE: {
1488 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001489 bool success = DoInvoke<kSuper, true, do_access_check>(
1490 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001491 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1492 break;
1493 }
1494 case Instruction::INVOKE_DIRECT: {
1495 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001496 bool success = DoInvoke<kDirect, false, do_access_check>(
1497 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001498 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1499 break;
1500 }
1501 case Instruction::INVOKE_DIRECT_RANGE: {
1502 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001503 bool success = DoInvoke<kDirect, true, do_access_check>(
1504 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001505 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1506 break;
1507 }
1508 case Instruction::INVOKE_INTERFACE: {
1509 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001510 bool success = DoInvoke<kInterface, false, do_access_check>(
1511 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001512 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1513 break;
1514 }
1515 case Instruction::INVOKE_INTERFACE_RANGE: {
1516 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001517 bool success = DoInvoke<kInterface, true, do_access_check>(
1518 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001519 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1520 break;
1521 }
1522 case Instruction::INVOKE_STATIC: {
1523 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001524 bool success = DoInvoke<kStatic, false, do_access_check>(
1525 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001526 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1527 break;
1528 }
1529 case Instruction::INVOKE_STATIC_RANGE: {
1530 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001531 bool success = DoInvoke<kStatic, true, do_access_check>(
1532 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001533 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1534 break;
1535 }
1536 case Instruction::INVOKE_VIRTUAL_QUICK: {
1537 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001538 bool success = DoInvokeVirtualQuick<false>(
1539 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001540 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1541 break;
1542 }
1543 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
1544 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001545 bool success = DoInvokeVirtualQuick<true>(
1546 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001547 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1548 break;
1549 }
1550 case Instruction::NEG_INT:
1551 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001552 shadow_frame.SetVReg(
1553 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001554 inst = inst->Next_1xx();
1555 break;
1556 case Instruction::NOT_INT:
1557 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001558 shadow_frame.SetVReg(
1559 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001560 inst = inst->Next_1xx();
1561 break;
1562 case Instruction::NEG_LONG:
1563 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001564 shadow_frame.SetVRegLong(
1565 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001566 inst = inst->Next_1xx();
1567 break;
1568 case Instruction::NOT_LONG:
1569 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001570 shadow_frame.SetVRegLong(
1571 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001572 inst = inst->Next_1xx();
1573 break;
1574 case Instruction::NEG_FLOAT:
1575 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001576 shadow_frame.SetVRegFloat(
1577 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001578 inst = inst->Next_1xx();
1579 break;
1580 case Instruction::NEG_DOUBLE:
1581 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001582 shadow_frame.SetVRegDouble(
1583 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001584 inst = inst->Next_1xx();
1585 break;
1586 case Instruction::INT_TO_LONG:
1587 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001588 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
1589 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001590 inst = inst->Next_1xx();
1591 break;
1592 case Instruction::INT_TO_FLOAT:
1593 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001594 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1595 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001596 inst = inst->Next_1xx();
1597 break;
1598 case Instruction::INT_TO_DOUBLE:
1599 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001600 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1601 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001602 inst = inst->Next_1xx();
1603 break;
1604 case Instruction::LONG_TO_INT:
1605 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001606 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1607 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001608 inst = inst->Next_1xx();
1609 break;
1610 case Instruction::LONG_TO_FLOAT:
1611 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001612 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1613 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001614 inst = inst->Next_1xx();
1615 break;
1616 case Instruction::LONG_TO_DOUBLE:
1617 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001618 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1619 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001620 inst = inst->Next_1xx();
1621 break;
1622 case Instruction::FLOAT_TO_INT: {
1623 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001624 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001625 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001626 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001627 inst = inst->Next_1xx();
1628 break;
1629 }
1630 case Instruction::FLOAT_TO_LONG: {
1631 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001632 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001633 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001634 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001635 inst = inst->Next_1xx();
1636 break;
1637 }
1638 case Instruction::FLOAT_TO_DOUBLE:
1639 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001640 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1641 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001642 inst = inst->Next_1xx();
1643 break;
1644 case Instruction::DOUBLE_TO_INT: {
1645 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001646 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001647 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001648 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001649 inst = inst->Next_1xx();
1650 break;
1651 }
1652 case Instruction::DOUBLE_TO_LONG: {
1653 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001654 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001655 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001656 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001657 inst = inst->Next_1xx();
1658 break;
1659 }
1660 case Instruction::DOUBLE_TO_FLOAT:
1661 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001662 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1663 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001664 inst = inst->Next_1xx();
1665 break;
1666 case Instruction::INT_TO_BYTE:
1667 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001668 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int8_t>(
1669 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001670 inst = inst->Next_1xx();
1671 break;
1672 case Instruction::INT_TO_CHAR:
1673 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001674 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<uint16_t>(
1675 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001676 inst = inst->Next_1xx();
1677 break;
1678 case Instruction::INT_TO_SHORT:
1679 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001680 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int16_t>(
1681 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001682 inst = inst->Next_1xx();
1683 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001684 case Instruction::ADD_INT: {
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001685 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001686 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001687 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1688 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001689 inst = inst->Next_2xx();
1690 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001691 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001692 case Instruction::SUB_INT:
1693 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001694 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001695 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1696 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001697 inst = inst->Next_2xx();
1698 break;
1699 case Instruction::MUL_INT:
1700 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001701 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001702 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1703 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001704 inst = inst->Next_2xx();
1705 break;
1706 case Instruction::DIV_INT: {
1707 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001708 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001709 shadow_frame.GetVReg(inst->VRegB_23x()),
1710 shadow_frame.GetVReg(inst->VRegC_23x()));
1711 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1712 break;
1713 }
1714 case Instruction::REM_INT: {
1715 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001716 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001717 shadow_frame.GetVReg(inst->VRegB_23x()),
1718 shadow_frame.GetVReg(inst->VRegC_23x()));
1719 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1720 break;
1721 }
1722 case Instruction::SHL_INT:
1723 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001724 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001725 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1726 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1727 inst = inst->Next_2xx();
1728 break;
1729 case Instruction::SHR_INT:
1730 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001731 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001732 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1733 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1734 inst = inst->Next_2xx();
1735 break;
1736 case Instruction::USHR_INT:
1737 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001738 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001739 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1740 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1741 inst = inst->Next_2xx();
1742 break;
1743 case Instruction::AND_INT:
1744 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001745 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001746 shadow_frame.GetVReg(inst->VRegB_23x()) &
1747 shadow_frame.GetVReg(inst->VRegC_23x()));
1748 inst = inst->Next_2xx();
1749 break;
1750 case Instruction::OR_INT:
1751 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001752 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001753 shadow_frame.GetVReg(inst->VRegB_23x()) |
1754 shadow_frame.GetVReg(inst->VRegC_23x()));
1755 inst = inst->Next_2xx();
1756 break;
1757 case Instruction::XOR_INT:
1758 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001759 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001760 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1761 shadow_frame.GetVReg(inst->VRegC_23x()));
1762 inst = inst->Next_2xx();
1763 break;
1764 case Instruction::ADD_LONG:
1765 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001766 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001767 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1768 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001769 inst = inst->Next_2xx();
1770 break;
1771 case Instruction::SUB_LONG:
1772 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001773 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001774 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1775 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001776 inst = inst->Next_2xx();
1777 break;
1778 case Instruction::MUL_LONG:
1779 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001780 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001781 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1782 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001783 inst = inst->Next_2xx();
1784 break;
1785 case Instruction::DIV_LONG:
1786 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001787 DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001788 shadow_frame.GetVRegLong(inst->VRegB_23x()),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001789 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001790 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1791 break;
1792 case Instruction::REM_LONG:
1793 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001794 DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001795 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1796 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1797 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1798 break;
1799 case Instruction::AND_LONG:
1800 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001801 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001802 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1803 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1804 inst = inst->Next_2xx();
1805 break;
1806 case Instruction::OR_LONG:
1807 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001808 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001809 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1810 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1811 inst = inst->Next_2xx();
1812 break;
1813 case Instruction::XOR_LONG:
1814 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001815 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001816 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1817 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1818 inst = inst->Next_2xx();
1819 break;
1820 case Instruction::SHL_LONG:
1821 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001822 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001823 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1824 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1825 inst = inst->Next_2xx();
1826 break;
1827 case Instruction::SHR_LONG:
1828 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001829 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001830 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1831 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1832 inst = inst->Next_2xx();
1833 break;
1834 case Instruction::USHR_LONG:
1835 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001836 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001837 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1838 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1839 inst = inst->Next_2xx();
1840 break;
1841 case Instruction::ADD_FLOAT:
1842 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001843 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001844 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1845 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1846 inst = inst->Next_2xx();
1847 break;
1848 case Instruction::SUB_FLOAT:
1849 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001850 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001851 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1852 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1853 inst = inst->Next_2xx();
1854 break;
1855 case Instruction::MUL_FLOAT:
1856 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001857 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001858 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1859 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1860 inst = inst->Next_2xx();
1861 break;
1862 case Instruction::DIV_FLOAT:
1863 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001864 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001865 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1866 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1867 inst = inst->Next_2xx();
1868 break;
1869 case Instruction::REM_FLOAT:
1870 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001871 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001872 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1873 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1874 inst = inst->Next_2xx();
1875 break;
1876 case Instruction::ADD_DOUBLE:
1877 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001878 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001879 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1880 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1881 inst = inst->Next_2xx();
1882 break;
1883 case Instruction::SUB_DOUBLE:
1884 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001885 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001886 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1887 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1888 inst = inst->Next_2xx();
1889 break;
1890 case Instruction::MUL_DOUBLE:
1891 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001892 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001893 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
1894 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1895 inst = inst->Next_2xx();
1896 break;
1897 case Instruction::DIV_DOUBLE:
1898 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001899 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001900 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
1901 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1902 inst = inst->Next_2xx();
1903 break;
1904 case Instruction::REM_DOUBLE:
1905 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001906 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001907 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
1908 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
1909 inst = inst->Next_2xx();
1910 break;
1911 case Instruction::ADD_INT_2ADDR: {
1912 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001913 uint4_t vregA = inst->VRegA_12x(inst_data);
Ian Rogersf72a11d2014-10-30 15:41:08 -07001914 shadow_frame.SetVReg(vregA, SafeAdd(shadow_frame.GetVReg(vregA),
1915 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001916 inst = inst->Next_1xx();
1917 break;
1918 }
1919 case Instruction::SUB_INT_2ADDR: {
1920 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001921 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001922 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001923 SafeSub(shadow_frame.GetVReg(vregA),
1924 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001925 inst = inst->Next_1xx();
1926 break;
1927 }
1928 case Instruction::MUL_INT_2ADDR: {
1929 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001930 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001931 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001932 SafeMul(shadow_frame.GetVReg(vregA),
1933 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001934 inst = inst->Next_1xx();
1935 break;
1936 }
1937 case Instruction::DIV_INT_2ADDR: {
1938 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001939 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001940 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001941 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001942 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1943 break;
1944 }
1945 case Instruction::REM_INT_2ADDR: {
1946 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001947 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001948 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001949 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001950 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1951 break;
1952 }
1953 case Instruction::SHL_INT_2ADDR: {
1954 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001955 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001956 shadow_frame.SetVReg(vregA,
1957 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001958 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001959 inst = inst->Next_1xx();
1960 break;
1961 }
1962 case Instruction::SHR_INT_2ADDR: {
1963 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001964 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001965 shadow_frame.SetVReg(vregA,
1966 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001967 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001968 inst = inst->Next_1xx();
1969 break;
1970 }
1971 case Instruction::USHR_INT_2ADDR: {
1972 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001973 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001974 shadow_frame.SetVReg(vregA,
1975 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001976 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001977 inst = inst->Next_1xx();
1978 break;
1979 }
1980 case Instruction::AND_INT_2ADDR: {
1981 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001982 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001983 shadow_frame.SetVReg(vregA,
1984 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001985 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001986 inst = inst->Next_1xx();
1987 break;
1988 }
1989 case Instruction::OR_INT_2ADDR: {
1990 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001991 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001992 shadow_frame.SetVReg(vregA,
1993 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001994 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001995 inst = inst->Next_1xx();
1996 break;
1997 }
1998 case Instruction::XOR_INT_2ADDR: {
1999 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002000 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002001 shadow_frame.SetVReg(vregA,
2002 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002003 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002004 inst = inst->Next_1xx();
2005 break;
2006 }
2007 case Instruction::ADD_LONG_2ADDR: {
2008 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002009 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002010 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002011 SafeAdd(shadow_frame.GetVRegLong(vregA),
2012 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002013 inst = inst->Next_1xx();
2014 break;
2015 }
2016 case Instruction::SUB_LONG_2ADDR: {
2017 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002018 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002019 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002020 SafeSub(shadow_frame.GetVRegLong(vregA),
2021 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002022 inst = inst->Next_1xx();
2023 break;
2024 }
2025 case Instruction::MUL_LONG_2ADDR: {
2026 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002027 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002028 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002029 SafeMul(shadow_frame.GetVRegLong(vregA),
2030 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002031 inst = inst->Next_1xx();
2032 break;
2033 }
2034 case Instruction::DIV_LONG_2ADDR: {
2035 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002036 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002037 DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002038 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002039 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
2040 break;
2041 }
2042 case Instruction::REM_LONG_2ADDR: {
2043 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002044 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002045 DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002046 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002047 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
2048 break;
2049 }
2050 case Instruction::AND_LONG_2ADDR: {
2051 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002052 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002053 shadow_frame.SetVRegLong(vregA,
2054 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002055 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002056 inst = inst->Next_1xx();
2057 break;
2058 }
2059 case Instruction::OR_LONG_2ADDR: {
2060 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002061 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002062 shadow_frame.SetVRegLong(vregA,
2063 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002064 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002065 inst = inst->Next_1xx();
2066 break;
2067 }
2068 case Instruction::XOR_LONG_2ADDR: {
2069 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002070 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002071 shadow_frame.SetVRegLong(vregA,
2072 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002073 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002074 inst = inst->Next_1xx();
2075 break;
2076 }
2077 case Instruction::SHL_LONG_2ADDR: {
2078 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002079 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002080 shadow_frame.SetVRegLong(vregA,
2081 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002082 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002083 inst = inst->Next_1xx();
2084 break;
2085 }
2086 case Instruction::SHR_LONG_2ADDR: {
2087 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002088 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002089 shadow_frame.SetVRegLong(vregA,
2090 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002091 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002092 inst = inst->Next_1xx();
2093 break;
2094 }
2095 case Instruction::USHR_LONG_2ADDR: {
2096 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002097 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002098 shadow_frame.SetVRegLong(vregA,
2099 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002100 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002101 inst = inst->Next_1xx();
2102 break;
2103 }
2104 case Instruction::ADD_FLOAT_2ADDR: {
2105 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002106 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002107 shadow_frame.SetVRegFloat(vregA,
2108 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002109 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002110 inst = inst->Next_1xx();
2111 break;
2112 }
2113 case Instruction::SUB_FLOAT_2ADDR: {
2114 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002115 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002116 shadow_frame.SetVRegFloat(vregA,
2117 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002118 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002119 inst = inst->Next_1xx();
2120 break;
2121 }
2122 case Instruction::MUL_FLOAT_2ADDR: {
2123 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002124 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002125 shadow_frame.SetVRegFloat(vregA,
2126 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002127 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002128 inst = inst->Next_1xx();
2129 break;
2130 }
2131 case Instruction::DIV_FLOAT_2ADDR: {
2132 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002133 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002134 shadow_frame.SetVRegFloat(vregA,
2135 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002136 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002137 inst = inst->Next_1xx();
2138 break;
2139 }
2140 case Instruction::REM_FLOAT_2ADDR: {
2141 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002142 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002143 shadow_frame.SetVRegFloat(vregA,
2144 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002145 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002146 inst = inst->Next_1xx();
2147 break;
2148 }
2149 case Instruction::ADD_DOUBLE_2ADDR: {
2150 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002151 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002152 shadow_frame.SetVRegDouble(vregA,
2153 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002154 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002155 inst = inst->Next_1xx();
2156 break;
2157 }
2158 case Instruction::SUB_DOUBLE_2ADDR: {
2159 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002160 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002161 shadow_frame.SetVRegDouble(vregA,
2162 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002163 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002164 inst = inst->Next_1xx();
2165 break;
2166 }
2167 case Instruction::MUL_DOUBLE_2ADDR: {
2168 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002169 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002170 shadow_frame.SetVRegDouble(vregA,
2171 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002172 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002173 inst = inst->Next_1xx();
2174 break;
2175 }
2176 case Instruction::DIV_DOUBLE_2ADDR: {
2177 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002178 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002179 shadow_frame.SetVRegDouble(vregA,
2180 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002181 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002182 inst = inst->Next_1xx();
2183 break;
2184 }
2185 case Instruction::REM_DOUBLE_2ADDR: {
2186 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002187 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002188 shadow_frame.SetVRegDouble(vregA,
2189 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002190 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002191 inst = inst->Next_1xx();
2192 break;
2193 }
2194 case Instruction::ADD_INT_LIT16:
2195 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002196 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002197 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2198 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002199 inst = inst->Next_2xx();
2200 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07002201 case Instruction::RSUB_INT_LIT16:
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002202 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002203 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002204 SafeSub(inst->VRegC_22s(),
2205 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002206 inst = inst->Next_2xx();
2207 break;
2208 case Instruction::MUL_INT_LIT16:
2209 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002210 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002211 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2212 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002213 inst = inst->Next_2xx();
2214 break;
2215 case Instruction::DIV_INT_LIT16: {
2216 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002217 bool success = DoIntDivide(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002218 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2219 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002220 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2221 break;
2222 }
2223 case Instruction::REM_INT_LIT16: {
2224 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002225 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002226 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2227 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002228 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2229 break;
2230 }
2231 case Instruction::AND_INT_LIT16:
2232 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002233 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2234 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002235 inst->VRegC_22s());
2236 inst = inst->Next_2xx();
2237 break;
2238 case Instruction::OR_INT_LIT16:
2239 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002240 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2241 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002242 inst->VRegC_22s());
2243 inst = inst->Next_2xx();
2244 break;
2245 case Instruction::XOR_INT_LIT16:
2246 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002247 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2248 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002249 inst->VRegC_22s());
2250 inst = inst->Next_2xx();
2251 break;
2252 case Instruction::ADD_INT_LIT8:
2253 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002254 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002255 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002256 inst = inst->Next_2xx();
2257 break;
2258 case Instruction::RSUB_INT_LIT8:
2259 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002260 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002261 SafeSub(inst->VRegC_22b(), shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002262 inst = inst->Next_2xx();
2263 break;
2264 case Instruction::MUL_INT_LIT8:
2265 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002266 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002267 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002268 inst = inst->Next_2xx();
2269 break;
2270 case Instruction::DIV_INT_LIT8: {
2271 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002272 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002273 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2274 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2275 break;
2276 }
2277 case Instruction::REM_INT_LIT8: {
2278 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002279 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002280 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2281 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2282 break;
2283 }
2284 case Instruction::AND_INT_LIT8:
2285 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002286 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002287 shadow_frame.GetVReg(inst->VRegB_22b()) &
2288 inst->VRegC_22b());
2289 inst = inst->Next_2xx();
2290 break;
2291 case Instruction::OR_INT_LIT8:
2292 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002293 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002294 shadow_frame.GetVReg(inst->VRegB_22b()) |
2295 inst->VRegC_22b());
2296 inst = inst->Next_2xx();
2297 break;
2298 case Instruction::XOR_INT_LIT8:
2299 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002300 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002301 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2302 inst->VRegC_22b());
2303 inst = inst->Next_2xx();
2304 break;
2305 case Instruction::SHL_INT_LIT8:
2306 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002307 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002308 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2309 (inst->VRegC_22b() & 0x1f));
2310 inst = inst->Next_2xx();
2311 break;
2312 case Instruction::SHR_INT_LIT8:
2313 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002314 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002315 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2316 (inst->VRegC_22b() & 0x1f));
2317 inst = inst->Next_2xx();
2318 break;
2319 case Instruction::USHR_INT_LIT8:
2320 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002321 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002322 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2323 (inst->VRegC_22b() & 0x1f));
2324 inst = inst->Next_2xx();
2325 break;
2326 case Instruction::UNUSED_3E ... Instruction::UNUSED_43:
Narayan Kamath8ec3bd22016-08-03 12:46:23 +01002327 case Instruction::UNUSED_F3 ... Instruction::UNUSED_F9:
2328 case Instruction::UNUSED_FC ... Instruction::UNUSED_FF:
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002329 case Instruction::UNUSED_79:
2330 case Instruction::UNUSED_7A:
Narayan Kamath8ec3bd22016-08-03 12:46:23 +01002331 case Instruction::INVOKE_POLYMORPHIC:
2332 case Instruction::INVOKE_POLYMORPHIC_RANGE:
Ian Rogerse94652f2014-12-02 11:13:19 -08002333 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002334 }
buzbee1452bee2015-03-06 14:43:04 -08002335 } while (!interpret_one_instruction);
2336 // Record where we stopped.
2337 shadow_frame.SetDexPC(inst->GetDexPc(insns));
buzbeed6b48db2016-01-28 15:48:55 -08002338 return result_register;
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002339} // NOLINT(readability/fn_size)
2340
2341// Explicit definitions of ExecuteSwitchImpl.
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002342template HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002343JValue ExecuteSwitchImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -08002344 ShadowFrame& shadow_frame, JValue result_register,
2345 bool interpret_one_instruction);
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002346template HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002347JValue ExecuteSwitchImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -08002348 ShadowFrame& shadow_frame, JValue result_register,
2349 bool interpret_one_instruction);
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002350template
Ian Rogerse94652f2014-12-02 11:13:19 -08002351JValue ExecuteSwitchImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -08002352 ShadowFrame& shadow_frame, JValue result_register,
2353 bool interpret_one_instruction);
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002354template
Ian Rogerse94652f2014-12-02 11:13:19 -08002355JValue ExecuteSwitchImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -08002356 ShadowFrame& shadow_frame, JValue result_register,
2357 bool interpret_one_instruction);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002358
2359} // namespace interpreter
2360} // namespace art