blob: b5cc11e070c3793ab5f7fe252306378a4f490b89 [file] [log] [blame]
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "interpreter_common.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070018#include "safe_math.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020019
20namespace art {
21namespace interpreter {
22
23#define HANDLE_PENDING_EXCEPTION() \
24 do { \
Sebastien Hertz82aeddb2014-05-20 20:09:45 +020025 DCHECK(self->IsExceptionPending()); \
Ian Rogers7b078e82014-09-10 14:44:24 -070026 self->AllowThreadSuspension(); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020027 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, \
28 inst->GetDexPc(insns), \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020029 instrumentation); \
30 if (found_dex_pc == DexFile::kDexNoIndex) { \
31 return JValue(); /* Handled in caller. */ \
32 } else { \
33 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc); \
34 inst = inst->RelativeAt(displacement); \
35 } \
36 } while (false)
37
38#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _next_function) \
39 do { \
40 if (UNLIKELY(_is_exception_pending)) { \
41 HANDLE_PENDING_EXCEPTION(); \
42 } else { \
43 inst = inst->_next_function(); \
44 } \
45 } while (false)
46
47// Code to run before each dex instruction.
Sebastien Hertz8379b222014-02-24 17:38:15 +010048#define PREAMBLE() \
49 do { \
Sebastien Hertz9d6bf692015-04-10 12:12:33 +020050 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
Sebastien Hertz8379b222014-02-24 17:38:15 +010051 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), \
52 shadow_frame.GetMethod(), dex_pc); \
53 } \
54 } while (false)
Sebastien Hertz8ece0502013-08-07 11:26:41 +020055
Igor Murashkin158f35c2015-06-10 15:55:30 -070056static bool IsExperimentalInstructionEnabled(const Instruction *inst) {
57 DCHECK(inst->IsExperimental());
58 return Runtime::Current()->AreExperimentalLambdasEnabled();
59}
60
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010061template<bool do_access_check, bool transaction_active>
Ian Rogerse94652f2014-12-02 11:13:19 -080062JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertz8379b222014-02-24 17:38:15 +010063 ShadowFrame& shadow_frame, JValue result_register) {
Igor Murashkinc449e8b2015-06-10 15:56:42 -070064 constexpr bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +020065 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
66 LOG(FATAL) << "Invalid shadow frame for interpreter use";
67 return JValue();
68 }
69 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +020070
71 uint32_t dex_pc = shadow_frame.GetDexPC();
Mathieu Chartier2cebb242015-04-21 16:50:40 -070072 const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz270a0e12015-01-16 19:49:09 +010073 if (LIKELY(dex_pc == 0)) { // We are entering the method as opposed to deoptimizing.
74 if (kIsDebugBuild) {
75 self->AssertNoPendingException();
76 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +020077 if (UNLIKELY(instrumentation->HasMethodEntryListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +020078 instrumentation->MethodEnterEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +020079 shadow_frame.GetMethod(), 0);
80 }
81 }
82 const uint16_t* const insns = code_item->insns_;
83 const Instruction* inst = Instruction::At(insns + dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +020084 uint16_t inst_data;
Sebastien Hertz8ece0502013-08-07 11:26:41 +020085 while (true) {
86 dex_pc = inst->GetDexPc(insns);
87 shadow_frame.SetDexPC(dex_pc);
Ian Rogerse94652f2014-12-02 11:13:19 -080088 TraceExecution(shadow_frame, inst, dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +020089 inst_data = inst->Fetch16(0);
90 switch (inst->Opcode(inst_data)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +020091 case Instruction::NOP:
92 PREAMBLE();
93 inst = inst->Next_1xx();
94 break;
95 case Instruction::MOVE:
96 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +020097 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
98 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +020099 inst = inst->Next_1xx();
100 break;
101 case Instruction::MOVE_FROM16:
102 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200103 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200104 shadow_frame.GetVReg(inst->VRegB_22x()));
105 inst = inst->Next_2xx();
106 break;
107 case Instruction::MOVE_16:
108 PREAMBLE();
109 shadow_frame.SetVReg(inst->VRegA_32x(),
110 shadow_frame.GetVReg(inst->VRegB_32x()));
111 inst = inst->Next_3xx();
112 break;
113 case Instruction::MOVE_WIDE:
114 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200115 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
116 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200117 inst = inst->Next_1xx();
118 break;
119 case Instruction::MOVE_WIDE_FROM16:
120 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200121 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200122 shadow_frame.GetVRegLong(inst->VRegB_22x()));
123 inst = inst->Next_2xx();
124 break;
125 case Instruction::MOVE_WIDE_16:
126 PREAMBLE();
127 shadow_frame.SetVRegLong(inst->VRegA_32x(),
128 shadow_frame.GetVRegLong(inst->VRegB_32x()));
129 inst = inst->Next_3xx();
130 break;
131 case Instruction::MOVE_OBJECT:
132 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200133 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
134 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200135 inst = inst->Next_1xx();
136 break;
137 case Instruction::MOVE_OBJECT_FROM16:
138 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200139 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200140 shadow_frame.GetVRegReference(inst->VRegB_22x()));
141 inst = inst->Next_2xx();
142 break;
143 case Instruction::MOVE_OBJECT_16:
144 PREAMBLE();
145 shadow_frame.SetVRegReference(inst->VRegA_32x(),
146 shadow_frame.GetVRegReference(inst->VRegB_32x()));
147 inst = inst->Next_3xx();
148 break;
149 case Instruction::MOVE_RESULT:
150 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200151 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200152 inst = inst->Next_1xx();
153 break;
154 case Instruction::MOVE_RESULT_WIDE:
155 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200156 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200157 inst = inst->Next_1xx();
158 break;
159 case Instruction::MOVE_RESULT_OBJECT:
160 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200161 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200162 inst = inst->Next_1xx();
163 break;
164 case Instruction::MOVE_EXCEPTION: {
165 PREAMBLE();
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000166 Throwable* exception = self->GetException();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100167 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200168 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception);
Sebastien Hertz5c004902014-05-21 10:07:42 +0200169 self->ClearException();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200170 inst = inst->Next_1xx();
171 break;
172 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700173 case Instruction::RETURN_VOID_NO_BARRIER: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200174 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200175 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700176 self->AllowThreadSuspension();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200177 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200178 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200179 shadow_frame.GetMethod(), inst->GetDexPc(insns),
180 result);
181 }
182 return result;
183 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700184 case Instruction::RETURN_VOID: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200185 PREAMBLE();
Hans Boehm30359612014-05-21 17:46:23 -0700186 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200187 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700188 self->AllowThreadSuspension();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200189 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200190 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200191 shadow_frame.GetMethod(), inst->GetDexPc(insns),
192 result);
193 }
194 return result;
195 }
196 case Instruction::RETURN: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200197 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200198 JValue result;
199 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200200 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700201 self->AllowThreadSuspension();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200202 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200203 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200204 shadow_frame.GetMethod(), inst->GetDexPc(insns),
205 result);
206 }
207 return result;
208 }
209 case Instruction::RETURN_WIDE: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200210 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200211 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200212 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700213 self->AllowThreadSuspension();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200214 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200215 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200216 shadow_frame.GetMethod(), inst->GetDexPc(insns),
217 result);
218 }
219 return result;
220 }
221 case Instruction::RETURN_OBJECT: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200222 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200223 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700224 self->AllowThreadSuspension();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700225 const size_t ref_idx = inst->VRegA_11x(inst_data);
226 Object* obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700227 if (do_assignability_check && obj_result != nullptr) {
Vladimir Marko05792b92015-08-03 11:56:49 +0100228 size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
229 Class* return_type = shadow_frame.GetMethod()->GetReturnType(true /* resolve */,
230 pointer_size);
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700231 // Re-load since it might have moved.
232 obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700233 if (return_type == nullptr) {
Jeff Haoa3faaf42013-09-03 19:07:00 -0700234 // Return the pending exception.
235 HANDLE_PENDING_EXCEPTION();
236 }
237 if (!obj_result->VerifierInstanceOf(return_type)) {
238 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700239 std::string temp1, temp2;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000240 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700241 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700242 obj_result->GetClass()->GetDescriptor(&temp1),
243 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700244 HANDLE_PENDING_EXCEPTION();
245 }
246 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700247 result.SetL(obj_result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200248 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200249 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200250 shadow_frame.GetMethod(), inst->GetDexPc(insns),
251 result);
252 }
253 return result;
254 }
255 case Instruction::CONST_4: {
256 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200257 uint4_t dst = inst->VRegA_11n(inst_data);
258 int4_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200259 shadow_frame.SetVReg(dst, val);
260 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700261 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200262 }
263 inst = inst->Next_1xx();
264 break;
265 }
266 case Instruction::CONST_16: {
267 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200268 uint8_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200269 int16_t val = inst->VRegB_21s();
270 shadow_frame.SetVReg(dst, val);
271 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700272 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200273 }
274 inst = inst->Next_2xx();
275 break;
276 }
277 case Instruction::CONST: {
278 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200279 uint8_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200280 int32_t val = inst->VRegB_31i();
281 shadow_frame.SetVReg(dst, val);
282 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700283 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200284 }
285 inst = inst->Next_3xx();
286 break;
287 }
288 case Instruction::CONST_HIGH16: {
289 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200290 uint8_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200291 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
292 shadow_frame.SetVReg(dst, val);
293 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700294 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200295 }
296 inst = inst->Next_2xx();
297 break;
298 }
299 case Instruction::CONST_WIDE_16:
300 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200301 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200302 inst = inst->Next_2xx();
303 break;
304 case Instruction::CONST_WIDE_32:
305 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200306 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200307 inst = inst->Next_3xx();
308 break;
309 case Instruction::CONST_WIDE:
310 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200311 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200312 inst = inst->Next_51l();
313 break;
314 case Instruction::CONST_WIDE_HIGH16:
Sebastien Hertz3c5aec12014-06-04 09:41:21 +0200315 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200316 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200317 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
318 inst = inst->Next_2xx();
319 break;
320 case Instruction::CONST_STRING: {
321 PREAMBLE();
Ian Rogers6786a582014-10-28 12:49:06 -0700322 String* s = ResolveString(self, shadow_frame, inst->VRegB_21c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700323 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200324 HANDLE_PENDING_EXCEPTION();
325 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200326 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200327 inst = inst->Next_2xx();
328 }
329 break;
330 }
331 case Instruction::CONST_STRING_JUMBO: {
332 PREAMBLE();
Ian Rogers6786a582014-10-28 12:49:06 -0700333 String* s = ResolveString(self, shadow_frame, inst->VRegB_31c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700334 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200335 HANDLE_PENDING_EXCEPTION();
336 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200337 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200338 inst = inst->Next_3xx();
339 }
340 break;
341 }
342 case Instruction::CONST_CLASS: {
343 PREAMBLE();
344 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
345 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700346 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200347 HANDLE_PENDING_EXCEPTION();
348 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200349 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200350 inst = inst->Next_2xx();
351 }
352 break;
353 }
354 case Instruction::MONITOR_ENTER: {
355 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200356 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700357 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000358 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200359 HANDLE_PENDING_EXCEPTION();
360 } else {
361 DoMonitorEnter(self, obj);
362 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
363 }
364 break;
365 }
366 case Instruction::MONITOR_EXIT: {
367 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200368 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700369 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000370 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200371 HANDLE_PENDING_EXCEPTION();
372 } else {
373 DoMonitorExit(self, obj);
374 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
375 }
376 break;
377 }
378 case Instruction::CHECK_CAST: {
379 PREAMBLE();
380 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
381 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700382 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200383 HANDLE_PENDING_EXCEPTION();
384 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200385 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700386 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200387 ThrowClassCastException(c, obj->GetClass());
388 HANDLE_PENDING_EXCEPTION();
389 } else {
390 inst = inst->Next_2xx();
391 }
392 }
393 break;
394 }
395 case Instruction::INSTANCE_OF: {
396 PREAMBLE();
397 Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), 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 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700403 shadow_frame.SetVReg(inst->VRegA_22c(inst_data),
404 (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200405 inst = inst->Next_2xx();
406 }
407 break;
408 }
409 case Instruction::ARRAY_LENGTH: {
410 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200411 Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700412 if (UNLIKELY(array == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000413 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200414 HANDLE_PENDING_EXCEPTION();
415 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200416 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200417 inst = inst->Next_1xx();
418 }
419 break;
420 }
421 case Instruction::NEW_INSTANCE: {
422 PREAMBLE();
Jeff Hao848f70a2014-01-15 13:49:50 -0800423 Object* obj = nullptr;
424 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
425 self, false, do_access_check);
426 if (LIKELY(c != nullptr)) {
427 if (UNLIKELY(c->IsStringClass())) {
428 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
429 mirror::SetStringCountVisitor visitor(0);
430 obj = String::Alloc<true>(self, 0, allocator_type, visitor);
431 } else {
432 obj = AllocObjectFromCode<do_access_check, true>(
433 inst->VRegB_21c(), shadow_frame.GetMethod(), self,
434 Runtime::Current()->GetHeap()->GetCurrentAllocator());
435 }
436 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700437 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200438 HANDLE_PENDING_EXCEPTION();
439 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200440 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700441 // Don't allow finalizable objects to be allocated during a transaction since these can't
442 // be finalized without a started runtime.
443 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200444 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
445 PrettyTypeOf(obj).c_str());
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700446 HANDLE_PENDING_EXCEPTION();
447 break;
448 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200449 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200450 inst = inst->Next_2xx();
451 }
452 break;
453 }
454 case Instruction::NEW_ARRAY: {
455 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200456 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800457 Object* obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampe1cc7dba2014-12-17 18:43:01 -0800458 inst->VRegC_22c(), length, shadow_frame.GetMethod(), self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800459 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700460 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200461 HANDLE_PENDING_EXCEPTION();
462 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200463 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200464 inst = inst->Next_2xx();
465 }
466 break;
467 }
468 case Instruction::FILLED_NEW_ARRAY: {
469 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100470 bool success =
471 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame, self,
472 &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200473 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
474 break;
475 }
476 case Instruction::FILLED_NEW_ARRAY_RANGE: {
477 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100478 bool success =
479 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
480 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200481 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
482 break;
483 }
484 case Instruction::FILL_ARRAY_DATA: {
485 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200486 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
487 const Instruction::ArrayDataPayload* payload =
488 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
Ian Rogers832336b2014-10-08 15:35:22 -0700489 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
490 bool success = FillArrayData(obj, payload);
491 if (!success) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200492 HANDLE_PENDING_EXCEPTION();
493 break;
494 }
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100495 if (transaction_active) {
Ian Rogers832336b2014-10-08 15:35:22 -0700496 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100497 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200498 inst = inst->Next_3xx();
499 break;
500 }
501 case Instruction::THROW: {
502 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200503 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700504 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000505 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700506 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
507 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700508 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000509 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700510 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700511 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200512 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000513 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200514 }
515 HANDLE_PENDING_EXCEPTION();
516 break;
517 }
518 case Instruction::GOTO: {
519 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200520 int8_t offset = inst->VRegA_10t(inst_data);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200521 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700522 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200523 }
524 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200525 break;
526 }
527 case Instruction::GOTO_16: {
528 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200529 int16_t offset = inst->VRegA_20t();
530 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700531 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200532 }
533 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200534 break;
535 }
536 case Instruction::GOTO_32: {
537 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200538 int32_t offset = inst->VRegA_30t();
539 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700540 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200541 }
542 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200543 break;
544 }
545 case Instruction::PACKED_SWITCH: {
546 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200547 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200548 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700549 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200550 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200551 inst = inst->RelativeAt(offset);
552 break;
553 }
554 case Instruction::SPARSE_SWITCH: {
555 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200556 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200557 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700558 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200559 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200560 inst = inst->RelativeAt(offset);
561 break;
562 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700563
564#if defined(__clang__)
565#pragma clang diagnostic push
566#pragma clang diagnostic ignored "-Wfloat-equal"
567#endif
568
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200569 case Instruction::CMPL_FLOAT: {
570 PREAMBLE();
571 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
572 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
573 int32_t result;
574 if (val1 > val2) {
575 result = 1;
576 } else if (val1 == val2) {
577 result = 0;
578 } else {
579 result = -1;
580 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200581 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200582 inst = inst->Next_2xx();
583 break;
584 }
585 case Instruction::CMPG_FLOAT: {
586 PREAMBLE();
587 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
588 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
589 int32_t result;
590 if (val1 < val2) {
591 result = -1;
592 } else if (val1 == val2) {
593 result = 0;
594 } else {
595 result = 1;
596 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200597 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200598 inst = inst->Next_2xx();
599 break;
600 }
601 case Instruction::CMPL_DOUBLE: {
602 PREAMBLE();
603 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
604 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
605 int32_t result;
606 if (val1 > val2) {
607 result = 1;
608 } else if (val1 == val2) {
609 result = 0;
610 } else {
611 result = -1;
612 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200613 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200614 inst = inst->Next_2xx();
615 break;
616 }
617
618 case Instruction::CMPG_DOUBLE: {
619 PREAMBLE();
620 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
621 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
622 int32_t result;
623 if (val1 < val2) {
624 result = -1;
625 } else if (val1 == val2) {
626 result = 0;
627 } else {
628 result = 1;
629 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200630 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200631 inst = inst->Next_2xx();
632 break;
633 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700634
635#if defined(__clang__)
636#pragma clang diagnostic pop
637#endif
638
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200639 case Instruction::CMP_LONG: {
640 PREAMBLE();
641 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
642 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
643 int32_t result;
644 if (val1 > val2) {
645 result = 1;
646 } else if (val1 == val2) {
647 result = 0;
648 } else {
649 result = -1;
650 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200651 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200652 inst = inst->Next_2xx();
653 break;
654 }
655 case Instruction::IF_EQ: {
656 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700657 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) ==
658 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200659 int16_t offset = inst->VRegC_22t();
660 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700661 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200662 }
663 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200664 } else {
665 inst = inst->Next_2xx();
666 }
667 break;
668 }
669 case Instruction::IF_NE: {
670 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700671 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
672 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200673 int16_t offset = inst->VRegC_22t();
674 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700675 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200676 }
677 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200678 } else {
679 inst = inst->Next_2xx();
680 }
681 break;
682 }
683 case Instruction::IF_LT: {
684 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700685 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
686 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200687 int16_t offset = inst->VRegC_22t();
688 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700689 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200690 }
691 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200692 } else {
693 inst = inst->Next_2xx();
694 }
695 break;
696 }
697 case Instruction::IF_GE: {
698 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700699 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
700 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200701 int16_t offset = inst->VRegC_22t();
702 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700703 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200704 }
705 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200706 } else {
707 inst = inst->Next_2xx();
708 }
709 break;
710 }
711 case Instruction::IF_GT: {
712 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700713 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
714 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200715 int16_t offset = inst->VRegC_22t();
716 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700717 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200718 }
719 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200720 } else {
721 inst = inst->Next_2xx();
722 }
723 break;
724 }
725 case Instruction::IF_LE: {
726 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700727 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
728 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200729 int16_t offset = inst->VRegC_22t();
730 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700731 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200732 }
733 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200734 } else {
735 inst = inst->Next_2xx();
736 }
737 break;
738 }
739 case Instruction::IF_EQZ: {
740 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200741 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200742 int16_t offset = inst->VRegB_21t();
743 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700744 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200745 }
746 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200747 } else {
748 inst = inst->Next_2xx();
749 }
750 break;
751 }
752 case Instruction::IF_NEZ: {
753 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200754 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200755 int16_t offset = inst->VRegB_21t();
756 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700757 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200758 }
759 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200760 } else {
761 inst = inst->Next_2xx();
762 }
763 break;
764 }
765 case Instruction::IF_LTZ: {
766 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200767 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200768 int16_t offset = inst->VRegB_21t();
769 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700770 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200771 }
772 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200773 } else {
774 inst = inst->Next_2xx();
775 }
776 break;
777 }
778 case Instruction::IF_GEZ: {
779 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200780 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200781 int16_t offset = inst->VRegB_21t();
782 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700783 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200784 }
785 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200786 } else {
787 inst = inst->Next_2xx();
788 }
789 break;
790 }
791 case Instruction::IF_GTZ: {
792 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200793 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200794 int16_t offset = inst->VRegB_21t();
795 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700796 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200797 }
798 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200799 } else {
800 inst = inst->Next_2xx();
801 }
802 break;
803 }
804 case Instruction::IF_LEZ: {
805 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200806 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200807 int16_t offset = inst->VRegB_21t();
808 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700809 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200810 }
811 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200812 } else {
813 inst = inst->Next_2xx();
814 }
815 break;
816 }
817 case Instruction::AGET_BOOLEAN: {
818 PREAMBLE();
819 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700820 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000821 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200822 HANDLE_PENDING_EXCEPTION();
823 break;
824 }
825 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
826 BooleanArray* array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700827 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100828 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200829 inst = inst->Next_2xx();
830 } else {
831 HANDLE_PENDING_EXCEPTION();
832 }
833 break;
834 }
835 case Instruction::AGET_BYTE: {
836 PREAMBLE();
837 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700838 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000839 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200840 HANDLE_PENDING_EXCEPTION();
841 break;
842 }
843 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
844 ByteArray* array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700845 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100846 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200847 inst = inst->Next_2xx();
848 } else {
849 HANDLE_PENDING_EXCEPTION();
850 }
851 break;
852 }
853 case Instruction::AGET_CHAR: {
854 PREAMBLE();
855 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700856 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000857 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200858 HANDLE_PENDING_EXCEPTION();
859 break;
860 }
861 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
862 CharArray* array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700863 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100864 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200865 inst = inst->Next_2xx();
866 } else {
867 HANDLE_PENDING_EXCEPTION();
868 }
869 break;
870 }
871 case Instruction::AGET_SHORT: {
872 PREAMBLE();
873 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700874 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000875 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200876 HANDLE_PENDING_EXCEPTION();
877 break;
878 }
879 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
880 ShortArray* array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700881 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100882 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200883 inst = inst->Next_2xx();
884 } else {
885 HANDLE_PENDING_EXCEPTION();
886 }
887 break;
888 }
889 case Instruction::AGET: {
890 PREAMBLE();
891 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700892 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000893 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200894 HANDLE_PENDING_EXCEPTION();
895 break;
896 }
897 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700898 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
899 auto* array = down_cast<IntArray*>(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700900 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100901 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200902 inst = inst->Next_2xx();
903 } else {
904 HANDLE_PENDING_EXCEPTION();
905 }
906 break;
907 }
908 case Instruction::AGET_WIDE: {
909 PREAMBLE();
910 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700911 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000912 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200913 HANDLE_PENDING_EXCEPTION();
914 break;
915 }
916 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700917 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
918 auto* array = down_cast<LongArray*>(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700919 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100920 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200921 inst = inst->Next_2xx();
922 } else {
923 HANDLE_PENDING_EXCEPTION();
924 }
925 break;
926 }
927 case Instruction::AGET_OBJECT: {
928 PREAMBLE();
929 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700930 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000931 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200932 HANDLE_PENDING_EXCEPTION();
933 break;
934 }
935 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
936 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700937 if (array->CheckIsValidIndex(index)) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200938 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200939 inst = inst->Next_2xx();
940 } else {
941 HANDLE_PENDING_EXCEPTION();
942 }
943 break;
944 }
945 case Instruction::APUT_BOOLEAN: {
946 PREAMBLE();
947 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700948 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000949 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200950 HANDLE_PENDING_EXCEPTION();
951 break;
952 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200953 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200954 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
955 BooleanArray* array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700956 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100957 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200958 inst = inst->Next_2xx();
959 } else {
960 HANDLE_PENDING_EXCEPTION();
961 }
962 break;
963 }
964 case Instruction::APUT_BYTE: {
965 PREAMBLE();
966 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700967 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000968 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200969 HANDLE_PENDING_EXCEPTION();
970 break;
971 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200972 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200973 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
974 ByteArray* array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700975 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100976 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200977 inst = inst->Next_2xx();
978 } else {
979 HANDLE_PENDING_EXCEPTION();
980 }
981 break;
982 }
983 case Instruction::APUT_CHAR: {
984 PREAMBLE();
985 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700986 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000987 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200988 HANDLE_PENDING_EXCEPTION();
989 break;
990 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200991 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200992 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
993 CharArray* array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700994 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100995 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200996 inst = inst->Next_2xx();
997 } else {
998 HANDLE_PENDING_EXCEPTION();
999 }
1000 break;
1001 }
1002 case Instruction::APUT_SHORT: {
1003 PREAMBLE();
1004 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001005 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001006 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001007 HANDLE_PENDING_EXCEPTION();
1008 break;
1009 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001010 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001011 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1012 ShortArray* array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001013 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001014 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001015 inst = inst->Next_2xx();
1016 } else {
1017 HANDLE_PENDING_EXCEPTION();
1018 }
1019 break;
1020 }
1021 case Instruction::APUT: {
1022 PREAMBLE();
1023 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001024 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001025 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001026 HANDLE_PENDING_EXCEPTION();
1027 break;
1028 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001029 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001030 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001031 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1032 auto* array = down_cast<IntArray*>(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001033 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001034 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001035 inst = inst->Next_2xx();
1036 } else {
1037 HANDLE_PENDING_EXCEPTION();
1038 }
1039 break;
1040 }
1041 case Instruction::APUT_WIDE: {
1042 PREAMBLE();
1043 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001044 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001045 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001046 HANDLE_PENDING_EXCEPTION();
1047 break;
1048 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001049 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001050 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001051 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1052 LongArray* array = down_cast<LongArray*>(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001053 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001054 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001055 inst = inst->Next_2xx();
1056 } else {
1057 HANDLE_PENDING_EXCEPTION();
1058 }
1059 break;
1060 }
1061 case Instruction::APUT_OBJECT: {
1062 PREAMBLE();
1063 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001064 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001065 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001066 HANDLE_PENDING_EXCEPTION();
1067 break;
1068 }
1069 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001070 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001071 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001072 if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001073 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001074 inst = inst->Next_2xx();
1075 } else {
1076 HANDLE_PENDING_EXCEPTION();
1077 }
1078 break;
1079 }
1080 case Instruction::IGET_BOOLEAN: {
1081 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001082 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1083 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001084 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1085 break;
1086 }
1087 case Instruction::IGET_BYTE: {
1088 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001089 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1090 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001091 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1092 break;
1093 }
1094 case Instruction::IGET_CHAR: {
1095 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001096 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1097 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001098 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1099 break;
1100 }
1101 case Instruction::IGET_SHORT: {
1102 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001103 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1104 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001105 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1106 break;
1107 }
1108 case Instruction::IGET: {
1109 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001110 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1111 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001112 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1113 break;
1114 }
1115 case Instruction::IGET_WIDE: {
1116 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001117 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1118 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001119 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1120 break;
1121 }
1122 case Instruction::IGET_OBJECT: {
1123 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001124 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1125 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001126 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1127 break;
1128 }
1129 case Instruction::IGET_QUICK: {
1130 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001131 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001132 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1133 break;
1134 }
1135 case Instruction::IGET_WIDE_QUICK: {
1136 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001137 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001138 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1139 break;
1140 }
1141 case Instruction::IGET_OBJECT_QUICK: {
1142 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001143 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001144 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1145 break;
1146 }
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001147 case Instruction::IGET_BOOLEAN_QUICK: {
1148 PREAMBLE();
1149 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1150 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1151 break;
1152 }
1153 case Instruction::IGET_BYTE_QUICK: {
1154 PREAMBLE();
1155 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1156 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1157 break;
1158 }
1159 case Instruction::IGET_CHAR_QUICK: {
1160 PREAMBLE();
1161 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1162 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1163 break;
1164 }
1165 case Instruction::IGET_SHORT_QUICK: {
1166 PREAMBLE();
1167 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1168 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1169 break;
1170 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001171 case Instruction::SGET_BOOLEAN: {
1172 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001173 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1174 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001175 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1176 break;
1177 }
1178 case Instruction::SGET_BYTE: {
1179 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001180 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(
1181 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001182 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1183 break;
1184 }
1185 case Instruction::SGET_CHAR: {
1186 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001187 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(
1188 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001189 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1190 break;
1191 }
1192 case Instruction::SGET_SHORT: {
1193 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001194 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(
1195 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001196 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1197 break;
1198 }
1199 case Instruction::SGET: {
1200 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001201 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(
1202 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001203 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1204 break;
1205 }
1206 case Instruction::SGET_WIDE: {
1207 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001208 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(
1209 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001210 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1211 break;
1212 }
1213 case Instruction::SGET_OBJECT: {
1214 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001215 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(
1216 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001217 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1218 break;
1219 }
1220 case Instruction::IPUT_BOOLEAN: {
1221 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001222 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1223 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001224 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1225 break;
1226 }
1227 case Instruction::IPUT_BYTE: {
1228 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001229 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1230 transaction_active>(self, 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::IPUT_CHAR: {
1235 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001236 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1237 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001238 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1239 break;
1240 }
1241 case Instruction::IPUT_SHORT: {
1242 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001243 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1244 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001245 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1246 break;
1247 }
1248 case Instruction::IPUT: {
1249 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001250 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1251 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001252 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1253 break;
1254 }
1255 case Instruction::IPUT_WIDE: {
1256 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001257 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1258 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001259 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1260 break;
1261 }
1262 case Instruction::IPUT_OBJECT: {
1263 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001264 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1265 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001266 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1267 break;
1268 }
1269 case Instruction::IPUT_QUICK: {
1270 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001271 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1272 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001273 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1274 break;
1275 }
Fred Shih37f05ef2014-07-16 18:38:08 -07001276 case Instruction::IPUT_BOOLEAN_QUICK: {
1277 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001278 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1279 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001280 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1281 break;
1282 }
1283 case Instruction::IPUT_BYTE_QUICK: {
1284 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001285 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1286 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001287 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1288 break;
1289 }
1290 case Instruction::IPUT_CHAR_QUICK: {
1291 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001292 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1293 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001294 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1295 break;
1296 }
1297 case Instruction::IPUT_SHORT_QUICK: {
1298 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001299 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1300 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001301 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1302 break;
1303 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001304 case Instruction::IPUT_WIDE_QUICK: {
1305 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001306 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1307 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001308 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1309 break;
1310 }
1311 case Instruction::IPUT_OBJECT_QUICK: {
1312 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001313 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1314 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001315 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1316 break;
1317 }
1318 case Instruction::SPUT_BOOLEAN: {
1319 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001320 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1321 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001322 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1323 break;
1324 }
1325 case Instruction::SPUT_BYTE: {
1326 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001327 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1328 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001329 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1330 break;
1331 }
1332 case Instruction::SPUT_CHAR: {
1333 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001334 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1335 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001336 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1337 break;
1338 }
1339 case Instruction::SPUT_SHORT: {
1340 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001341 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1342 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001343 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1344 break;
1345 }
1346 case Instruction::SPUT: {
1347 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001348 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1349 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001350 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1351 break;
1352 }
1353 case Instruction::SPUT_WIDE: {
1354 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001355 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1356 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001357 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1358 break;
1359 }
1360 case Instruction::SPUT_OBJECT: {
1361 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001362 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1363 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001364 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1365 break;
1366 }
1367 case Instruction::INVOKE_VIRTUAL: {
1368 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001369 bool success = DoInvoke<kVirtual, false, do_access_check>(
1370 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001371 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1372 break;
1373 }
1374 case Instruction::INVOKE_VIRTUAL_RANGE: {
1375 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001376 bool success = DoInvoke<kVirtual, true, do_access_check>(
1377 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001378 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1379 break;
1380 }
1381 case Instruction::INVOKE_SUPER: {
1382 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001383 bool success = DoInvoke<kSuper, false, do_access_check>(
1384 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001385 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1386 break;
1387 }
1388 case Instruction::INVOKE_SUPER_RANGE: {
1389 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001390 bool success = DoInvoke<kSuper, true, do_access_check>(
1391 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001392 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1393 break;
1394 }
1395 case Instruction::INVOKE_DIRECT: {
1396 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001397 bool success = DoInvoke<kDirect, false, do_access_check>(
1398 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001399 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1400 break;
1401 }
1402 case Instruction::INVOKE_DIRECT_RANGE: {
1403 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001404 bool success = DoInvoke<kDirect, true, do_access_check>(
1405 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001406 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1407 break;
1408 }
1409 case Instruction::INVOKE_INTERFACE: {
1410 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001411 bool success = DoInvoke<kInterface, false, do_access_check>(
1412 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001413 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1414 break;
1415 }
1416 case Instruction::INVOKE_INTERFACE_RANGE: {
1417 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001418 bool success = DoInvoke<kInterface, true, do_access_check>(
1419 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001420 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1421 break;
1422 }
1423 case Instruction::INVOKE_STATIC: {
1424 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001425 bool success = DoInvoke<kStatic, false, do_access_check>(
1426 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001427 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1428 break;
1429 }
1430 case Instruction::INVOKE_STATIC_RANGE: {
1431 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001432 bool success = DoInvoke<kStatic, true, do_access_check>(
1433 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001434 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1435 break;
1436 }
1437 case Instruction::INVOKE_VIRTUAL_QUICK: {
1438 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001439 bool success = DoInvokeVirtualQuick<false>(
1440 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001441 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1442 break;
1443 }
1444 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
1445 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001446 bool success = DoInvokeVirtualQuick<true>(
1447 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001448 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1449 break;
1450 }
1451 case Instruction::NEG_INT:
1452 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001453 shadow_frame.SetVReg(
1454 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001455 inst = inst->Next_1xx();
1456 break;
1457 case Instruction::NOT_INT:
1458 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001459 shadow_frame.SetVReg(
1460 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001461 inst = inst->Next_1xx();
1462 break;
1463 case Instruction::NEG_LONG:
1464 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001465 shadow_frame.SetVRegLong(
1466 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001467 inst = inst->Next_1xx();
1468 break;
1469 case Instruction::NOT_LONG:
1470 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001471 shadow_frame.SetVRegLong(
1472 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001473 inst = inst->Next_1xx();
1474 break;
1475 case Instruction::NEG_FLOAT:
1476 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001477 shadow_frame.SetVRegFloat(
1478 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001479 inst = inst->Next_1xx();
1480 break;
1481 case Instruction::NEG_DOUBLE:
1482 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001483 shadow_frame.SetVRegDouble(
1484 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001485 inst = inst->Next_1xx();
1486 break;
1487 case Instruction::INT_TO_LONG:
1488 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001489 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
1490 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001491 inst = inst->Next_1xx();
1492 break;
1493 case Instruction::INT_TO_FLOAT:
1494 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001495 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1496 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001497 inst = inst->Next_1xx();
1498 break;
1499 case Instruction::INT_TO_DOUBLE:
1500 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001501 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1502 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001503 inst = inst->Next_1xx();
1504 break;
1505 case Instruction::LONG_TO_INT:
1506 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001507 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1508 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001509 inst = inst->Next_1xx();
1510 break;
1511 case Instruction::LONG_TO_FLOAT:
1512 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001513 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1514 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001515 inst = inst->Next_1xx();
1516 break;
1517 case Instruction::LONG_TO_DOUBLE:
1518 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001519 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1520 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001521 inst = inst->Next_1xx();
1522 break;
1523 case Instruction::FLOAT_TO_INT: {
1524 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001525 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001526 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001527 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001528 inst = inst->Next_1xx();
1529 break;
1530 }
1531 case Instruction::FLOAT_TO_LONG: {
1532 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001533 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001534 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001535 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001536 inst = inst->Next_1xx();
1537 break;
1538 }
1539 case Instruction::FLOAT_TO_DOUBLE:
1540 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001541 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1542 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001543 inst = inst->Next_1xx();
1544 break;
1545 case Instruction::DOUBLE_TO_INT: {
1546 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001547 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001548 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001549 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001550 inst = inst->Next_1xx();
1551 break;
1552 }
1553 case Instruction::DOUBLE_TO_LONG: {
1554 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001555 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001556 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001557 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001558 inst = inst->Next_1xx();
1559 break;
1560 }
1561 case Instruction::DOUBLE_TO_FLOAT:
1562 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001563 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1564 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001565 inst = inst->Next_1xx();
1566 break;
1567 case Instruction::INT_TO_BYTE:
1568 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001569 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int8_t>(
1570 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001571 inst = inst->Next_1xx();
1572 break;
1573 case Instruction::INT_TO_CHAR:
1574 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001575 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<uint16_t>(
1576 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001577 inst = inst->Next_1xx();
1578 break;
1579 case Instruction::INT_TO_SHORT:
1580 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001581 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int16_t>(
1582 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001583 inst = inst->Next_1xx();
1584 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001585 case Instruction::ADD_INT: {
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001586 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001587 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001588 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1589 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001590 inst = inst->Next_2xx();
1591 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001592 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001593 case Instruction::SUB_INT:
1594 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001595 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001596 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1597 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001598 inst = inst->Next_2xx();
1599 break;
1600 case Instruction::MUL_INT:
1601 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001602 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001603 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1604 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001605 inst = inst->Next_2xx();
1606 break;
1607 case Instruction::DIV_INT: {
1608 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001609 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001610 shadow_frame.GetVReg(inst->VRegB_23x()),
1611 shadow_frame.GetVReg(inst->VRegC_23x()));
1612 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1613 break;
1614 }
1615 case Instruction::REM_INT: {
1616 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001617 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001618 shadow_frame.GetVReg(inst->VRegB_23x()),
1619 shadow_frame.GetVReg(inst->VRegC_23x()));
1620 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1621 break;
1622 }
1623 case Instruction::SHL_INT:
1624 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001625 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001626 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1627 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1628 inst = inst->Next_2xx();
1629 break;
1630 case Instruction::SHR_INT:
1631 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001632 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001633 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1634 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1635 inst = inst->Next_2xx();
1636 break;
1637 case Instruction::USHR_INT:
1638 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001639 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001640 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1641 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1642 inst = inst->Next_2xx();
1643 break;
1644 case Instruction::AND_INT:
1645 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001646 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001647 shadow_frame.GetVReg(inst->VRegB_23x()) &
1648 shadow_frame.GetVReg(inst->VRegC_23x()));
1649 inst = inst->Next_2xx();
1650 break;
1651 case Instruction::OR_INT:
1652 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001653 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001654 shadow_frame.GetVReg(inst->VRegB_23x()) |
1655 shadow_frame.GetVReg(inst->VRegC_23x()));
1656 inst = inst->Next_2xx();
1657 break;
1658 case Instruction::XOR_INT:
1659 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001660 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001661 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1662 shadow_frame.GetVReg(inst->VRegC_23x()));
1663 inst = inst->Next_2xx();
1664 break;
1665 case Instruction::ADD_LONG:
1666 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001667 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001668 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1669 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001670 inst = inst->Next_2xx();
1671 break;
1672 case Instruction::SUB_LONG:
1673 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001674 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001675 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1676 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001677 inst = inst->Next_2xx();
1678 break;
1679 case Instruction::MUL_LONG:
1680 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001681 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001682 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1683 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001684 inst = inst->Next_2xx();
1685 break;
1686 case Instruction::DIV_LONG:
1687 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001688 DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001689 shadow_frame.GetVRegLong(inst->VRegB_23x()),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001690 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001691 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1692 break;
1693 case Instruction::REM_LONG:
1694 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001695 DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001696 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1697 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1698 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1699 break;
1700 case Instruction::AND_LONG:
1701 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001702 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001703 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1704 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1705 inst = inst->Next_2xx();
1706 break;
1707 case Instruction::OR_LONG:
1708 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001709 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001710 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1711 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1712 inst = inst->Next_2xx();
1713 break;
1714 case Instruction::XOR_LONG:
1715 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001716 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001717 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1718 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1719 inst = inst->Next_2xx();
1720 break;
1721 case Instruction::SHL_LONG:
1722 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001723 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001724 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1725 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1726 inst = inst->Next_2xx();
1727 break;
1728 case Instruction::SHR_LONG:
1729 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001730 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001731 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1732 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1733 inst = inst->Next_2xx();
1734 break;
1735 case Instruction::USHR_LONG:
1736 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001737 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001738 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1739 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1740 inst = inst->Next_2xx();
1741 break;
1742 case Instruction::ADD_FLOAT:
1743 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001744 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001745 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1746 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1747 inst = inst->Next_2xx();
1748 break;
1749 case Instruction::SUB_FLOAT:
1750 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001751 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001752 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1753 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1754 inst = inst->Next_2xx();
1755 break;
1756 case Instruction::MUL_FLOAT:
1757 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001758 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001759 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1760 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1761 inst = inst->Next_2xx();
1762 break;
1763 case Instruction::DIV_FLOAT:
1764 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001765 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001766 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1767 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1768 inst = inst->Next_2xx();
1769 break;
1770 case Instruction::REM_FLOAT:
1771 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001772 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001773 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1774 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1775 inst = inst->Next_2xx();
1776 break;
1777 case Instruction::ADD_DOUBLE:
1778 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001779 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001780 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1781 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1782 inst = inst->Next_2xx();
1783 break;
1784 case Instruction::SUB_DOUBLE:
1785 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001786 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001787 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1788 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1789 inst = inst->Next_2xx();
1790 break;
1791 case Instruction::MUL_DOUBLE:
1792 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001793 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001794 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
1795 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1796 inst = inst->Next_2xx();
1797 break;
1798 case Instruction::DIV_DOUBLE:
1799 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001800 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001801 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
1802 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1803 inst = inst->Next_2xx();
1804 break;
1805 case Instruction::REM_DOUBLE:
1806 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001807 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001808 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
1809 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
1810 inst = inst->Next_2xx();
1811 break;
1812 case Instruction::ADD_INT_2ADDR: {
1813 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001814 uint4_t vregA = inst->VRegA_12x(inst_data);
Ian Rogersf72a11d2014-10-30 15:41:08 -07001815 shadow_frame.SetVReg(vregA, SafeAdd(shadow_frame.GetVReg(vregA),
1816 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001817 inst = inst->Next_1xx();
1818 break;
1819 }
1820 case Instruction::SUB_INT_2ADDR: {
1821 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001822 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001823 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001824 SafeSub(shadow_frame.GetVReg(vregA),
1825 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001826 inst = inst->Next_1xx();
1827 break;
1828 }
1829 case Instruction::MUL_INT_2ADDR: {
1830 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001831 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001832 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001833 SafeMul(shadow_frame.GetVReg(vregA),
1834 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001835 inst = inst->Next_1xx();
1836 break;
1837 }
1838 case Instruction::DIV_INT_2ADDR: {
1839 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001840 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001841 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001842 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001843 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1844 break;
1845 }
1846 case Instruction::REM_INT_2ADDR: {
1847 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001848 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001849 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001850 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001851 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1852 break;
1853 }
1854 case Instruction::SHL_INT_2ADDR: {
1855 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001856 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001857 shadow_frame.SetVReg(vregA,
1858 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001859 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001860 inst = inst->Next_1xx();
1861 break;
1862 }
1863 case Instruction::SHR_INT_2ADDR: {
1864 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001865 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001866 shadow_frame.SetVReg(vregA,
1867 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001868 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001869 inst = inst->Next_1xx();
1870 break;
1871 }
1872 case Instruction::USHR_INT_2ADDR: {
1873 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001874 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001875 shadow_frame.SetVReg(vregA,
1876 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001877 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001878 inst = inst->Next_1xx();
1879 break;
1880 }
1881 case Instruction::AND_INT_2ADDR: {
1882 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001883 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001884 shadow_frame.SetVReg(vregA,
1885 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001886 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001887 inst = inst->Next_1xx();
1888 break;
1889 }
1890 case Instruction::OR_INT_2ADDR: {
1891 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001892 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001893 shadow_frame.SetVReg(vregA,
1894 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001895 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001896 inst = inst->Next_1xx();
1897 break;
1898 }
1899 case Instruction::XOR_INT_2ADDR: {
1900 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001901 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001902 shadow_frame.SetVReg(vregA,
1903 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001904 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001905 inst = inst->Next_1xx();
1906 break;
1907 }
1908 case Instruction::ADD_LONG_2ADDR: {
1909 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001910 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001911 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001912 SafeAdd(shadow_frame.GetVRegLong(vregA),
1913 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001914 inst = inst->Next_1xx();
1915 break;
1916 }
1917 case Instruction::SUB_LONG_2ADDR: {
1918 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001919 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001920 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001921 SafeSub(shadow_frame.GetVRegLong(vregA),
1922 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001923 inst = inst->Next_1xx();
1924 break;
1925 }
1926 case Instruction::MUL_LONG_2ADDR: {
1927 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001928 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001929 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001930 SafeMul(shadow_frame.GetVRegLong(vregA),
1931 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001932 inst = inst->Next_1xx();
1933 break;
1934 }
1935 case Instruction::DIV_LONG_2ADDR: {
1936 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001937 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001938 DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001939 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001940 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
1941 break;
1942 }
1943 case Instruction::REM_LONG_2ADDR: {
1944 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001945 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001946 DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001947 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001948 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
1949 break;
1950 }
1951 case Instruction::AND_LONG_2ADDR: {
1952 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001953 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001954 shadow_frame.SetVRegLong(vregA,
1955 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001956 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001957 inst = inst->Next_1xx();
1958 break;
1959 }
1960 case Instruction::OR_LONG_2ADDR: {
1961 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001962 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001963 shadow_frame.SetVRegLong(vregA,
1964 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001965 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001966 inst = inst->Next_1xx();
1967 break;
1968 }
1969 case Instruction::XOR_LONG_2ADDR: {
1970 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001971 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001972 shadow_frame.SetVRegLong(vregA,
1973 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001974 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001975 inst = inst->Next_1xx();
1976 break;
1977 }
1978 case Instruction::SHL_LONG_2ADDR: {
1979 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001980 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001981 shadow_frame.SetVRegLong(vregA,
1982 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001983 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001984 inst = inst->Next_1xx();
1985 break;
1986 }
1987 case Instruction::SHR_LONG_2ADDR: {
1988 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001989 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001990 shadow_frame.SetVRegLong(vregA,
1991 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001992 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001993 inst = inst->Next_1xx();
1994 break;
1995 }
1996 case Instruction::USHR_LONG_2ADDR: {
1997 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001998 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001999 shadow_frame.SetVRegLong(vregA,
2000 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002001 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002002 inst = inst->Next_1xx();
2003 break;
2004 }
2005 case Instruction::ADD_FLOAT_2ADDR: {
2006 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002007 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002008 shadow_frame.SetVRegFloat(vregA,
2009 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002010 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002011 inst = inst->Next_1xx();
2012 break;
2013 }
2014 case Instruction::SUB_FLOAT_2ADDR: {
2015 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002016 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002017 shadow_frame.SetVRegFloat(vregA,
2018 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002019 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002020 inst = inst->Next_1xx();
2021 break;
2022 }
2023 case Instruction::MUL_FLOAT_2ADDR: {
2024 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002025 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002026 shadow_frame.SetVRegFloat(vregA,
2027 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002028 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002029 inst = inst->Next_1xx();
2030 break;
2031 }
2032 case Instruction::DIV_FLOAT_2ADDR: {
2033 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002034 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002035 shadow_frame.SetVRegFloat(vregA,
2036 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002037 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002038 inst = inst->Next_1xx();
2039 break;
2040 }
2041 case Instruction::REM_FLOAT_2ADDR: {
2042 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002043 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002044 shadow_frame.SetVRegFloat(vregA,
2045 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002046 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002047 inst = inst->Next_1xx();
2048 break;
2049 }
2050 case Instruction::ADD_DOUBLE_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.SetVRegDouble(vregA,
2054 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002055 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002056 inst = inst->Next_1xx();
2057 break;
2058 }
2059 case Instruction::SUB_DOUBLE_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.SetVRegDouble(vregA,
2063 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002064 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002065 inst = inst->Next_1xx();
2066 break;
2067 }
2068 case Instruction::MUL_DOUBLE_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.SetVRegDouble(vregA,
2072 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002073 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002074 inst = inst->Next_1xx();
2075 break;
2076 }
2077 case Instruction::DIV_DOUBLE_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.SetVRegDouble(vregA,
2081 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002082 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002083 inst = inst->Next_1xx();
2084 break;
2085 }
2086 case Instruction::REM_DOUBLE_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.SetVRegDouble(vregA,
2090 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002091 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002092 inst = inst->Next_1xx();
2093 break;
2094 }
2095 case Instruction::ADD_INT_LIT16:
2096 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002097 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002098 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2099 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002100 inst = inst->Next_2xx();
2101 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07002102 case Instruction::RSUB_INT_LIT16:
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002103 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002104 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002105 SafeSub(inst->VRegC_22s(),
2106 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002107 inst = inst->Next_2xx();
2108 break;
2109 case Instruction::MUL_INT_LIT16:
2110 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002111 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002112 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2113 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002114 inst = inst->Next_2xx();
2115 break;
2116 case Instruction::DIV_INT_LIT16: {
2117 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002118 bool success = DoIntDivide(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002119 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2120 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002121 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2122 break;
2123 }
2124 case Instruction::REM_INT_LIT16: {
2125 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002126 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002127 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2128 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002129 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2130 break;
2131 }
2132 case Instruction::AND_INT_LIT16:
2133 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002134 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2135 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002136 inst->VRegC_22s());
2137 inst = inst->Next_2xx();
2138 break;
2139 case Instruction::OR_INT_LIT16:
2140 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002141 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2142 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002143 inst->VRegC_22s());
2144 inst = inst->Next_2xx();
2145 break;
2146 case Instruction::XOR_INT_LIT16:
2147 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002148 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2149 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002150 inst->VRegC_22s());
2151 inst = inst->Next_2xx();
2152 break;
2153 case Instruction::ADD_INT_LIT8:
2154 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002155 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002156 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002157 inst = inst->Next_2xx();
2158 break;
2159 case Instruction::RSUB_INT_LIT8:
2160 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002161 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002162 SafeSub(inst->VRegC_22b(), shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002163 inst = inst->Next_2xx();
2164 break;
2165 case Instruction::MUL_INT_LIT8:
2166 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002167 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002168 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002169 inst = inst->Next_2xx();
2170 break;
2171 case Instruction::DIV_INT_LIT8: {
2172 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002173 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002174 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2175 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2176 break;
2177 }
2178 case Instruction::REM_INT_LIT8: {
2179 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002180 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002181 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2182 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2183 break;
2184 }
2185 case Instruction::AND_INT_LIT8:
2186 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002187 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002188 shadow_frame.GetVReg(inst->VRegB_22b()) &
2189 inst->VRegC_22b());
2190 inst = inst->Next_2xx();
2191 break;
2192 case Instruction::OR_INT_LIT8:
2193 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002194 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002195 shadow_frame.GetVReg(inst->VRegB_22b()) |
2196 inst->VRegC_22b());
2197 inst = inst->Next_2xx();
2198 break;
2199 case Instruction::XOR_INT_LIT8:
2200 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002201 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002202 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2203 inst->VRegC_22b());
2204 inst = inst->Next_2xx();
2205 break;
2206 case Instruction::SHL_INT_LIT8:
2207 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002208 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002209 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2210 (inst->VRegC_22b() & 0x1f));
2211 inst = inst->Next_2xx();
2212 break;
2213 case Instruction::SHR_INT_LIT8:
2214 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002215 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002216 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2217 (inst->VRegC_22b() & 0x1f));
2218 inst = inst->Next_2xx();
2219 break;
2220 case Instruction::USHR_INT_LIT8:
2221 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002222 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002223 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2224 (inst->VRegC_22b() & 0x1f));
2225 inst = inst->Next_2xx();
2226 break;
Igor Murashkin158f35c2015-06-10 15:55:30 -07002227 case Instruction::INVOKE_LAMBDA: {
2228 if (!IsExperimentalInstructionEnabled(inst)) {
2229 UnexpectedOpcode(inst, shadow_frame);
2230 }
2231
2232 PREAMBLE();
2233 bool success = DoInvokeLambda<do_access_check>(self, shadow_frame, inst, inst_data,
2234 &result_register);
2235 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2236 break;
2237 }
2238 case Instruction::CREATE_LAMBDA: {
2239 if (!IsExperimentalInstructionEnabled(inst)) {
2240 UnexpectedOpcode(inst, shadow_frame);
2241 }
2242
2243 PREAMBLE();
Nicolas Geoffray7bbb80a2015-09-27 19:50:40 +00002244 bool success = DoCreateLambda<do_access_check>(self, shadow_frame, inst);
Igor Murashkin158f35c2015-06-10 15:55:30 -07002245 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2246 break;
2247 }
Nicolas Geoffray7bbb80a2015-09-27 19:50:40 +00002248 case Instruction::UNUSED_F4:
2249 case Instruction::UNUSED_F5:
2250 case Instruction::UNUSED_F7: {
Igor Murashkin158f35c2015-06-10 15:55:30 -07002251 if (!IsExperimentalInstructionEnabled(inst)) {
2252 UnexpectedOpcode(inst, shadow_frame);
2253 }
2254
2255 CHECK(false); // TODO(iam): Implement opcodes for lambdas
2256 break;
2257 }
Igor Murashkin2ee54e22015-06-18 10:05:11 -07002258 case Instruction::BOX_LAMBDA: {
2259 if (!IsExperimentalInstructionEnabled(inst)) {
2260 UnexpectedOpcode(inst, shadow_frame);
2261 }
2262
2263 PREAMBLE();
2264 bool success = DoBoxLambda<do_access_check>(self, shadow_frame, inst, inst_data);
2265 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2266 break;
2267 }
2268 case Instruction::UNBOX_LAMBDA: {
2269 if (!IsExperimentalInstructionEnabled(inst)) {
2270 UnexpectedOpcode(inst, shadow_frame);
2271 }
2272
2273 PREAMBLE();
2274 bool success = DoUnboxLambda<do_access_check>(self, shadow_frame, inst, inst_data);
2275 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2276 break;
2277 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002278 case Instruction::UNUSED_3E ... Instruction::UNUSED_43:
Igor Murashkin158f35c2015-06-10 15:55:30 -07002279 case Instruction::UNUSED_FA ... Instruction::UNUSED_FF:
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002280 case Instruction::UNUSED_79:
2281 case Instruction::UNUSED_7A:
Ian Rogerse94652f2014-12-02 11:13:19 -08002282 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002283 }
2284 }
2285} // NOLINT(readability/fn_size)
2286
2287// Explicit definitions of ExecuteSwitchImpl.
Mathieu Chartier90443472015-07-16 20:32:27 -07002288template SHARED_REQUIRES(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002289JValue ExecuteSwitchImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002290 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002291template SHARED_REQUIRES(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002292JValue ExecuteSwitchImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002293 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002294template SHARED_REQUIRES(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002295JValue ExecuteSwitchImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002296 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002297template SHARED_REQUIRES(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002298JValue ExecuteSwitchImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002299 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002300
2301} // namespace interpreter
2302} // namespace art