blob: 609faf5b5d515276c1d859c39a0ba94ca931895d [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 { \
50 DCHECK(!inst->IsReturn()); \
51 if (UNLIKELY(notified_method_entry_event)) { \
52 notified_method_entry_event = false; \
53 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
54 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), \
55 shadow_frame.GetMethod(), dex_pc); \
56 } \
57 } while (false)
Sebastien Hertz8ece0502013-08-07 11:26:41 +020058
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010059template<bool do_access_check, bool transaction_active>
Ian Rogerse94652f2014-12-02 11:13:19 -080060JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertz8379b222014-02-24 17:38:15 +010061 ShadowFrame& shadow_frame, JValue result_register) {
Jeff Haoa3faaf42013-09-03 19:07:00 -070062 bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +020063 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
64 LOG(FATAL) << "Invalid shadow frame for interpreter use";
65 return JValue();
66 }
67 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +020068
69 uint32_t dex_pc = shadow_frame.GetDexPC();
Sebastien Hertz8379b222014-02-24 17:38:15 +010070 bool notified_method_entry_event = false;
Sebastien Hertz947ff082013-09-17 14:10:13 +020071 const instrumentation::Instrumentation* const instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz270a0e12015-01-16 19:49:09 +010072 if (LIKELY(dex_pc == 0)) { // We are entering the method as opposed to deoptimizing.
73 if (kIsDebugBuild) {
74 self->AssertNoPendingException();
75 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +020076 if (UNLIKELY(instrumentation->HasMethodEntryListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +020077 instrumentation->MethodEnterEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +020078 shadow_frame.GetMethod(), 0);
Sebastien Hertz8379b222014-02-24 17:38:15 +010079 notified_method_entry_event = true;
Sebastien Hertz8ece0502013-08-07 11:26:41 +020080 }
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 Hertz8ece0502013-08-07 11:26:41 +0200174 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700175 self->AllowThreadSuspension();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200176 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200177 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200178 shadow_frame.GetMethod(), inst->GetDexPc(insns),
179 result);
Sebastien Hertze713d932014-05-15 10:48:53 +0200180 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
181 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
182 shadow_frame.GetMethod(), dex_pc);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200183 }
184 return result;
185 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700186 case Instruction::RETURN_VOID: {
Hans Boehm30359612014-05-21 17:46:23 -0700187 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200188 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700189 self->AllowThreadSuspension();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200190 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200191 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200192 shadow_frame.GetMethod(), inst->GetDexPc(insns),
193 result);
Sebastien Hertze713d932014-05-15 10:48:53 +0200194 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
195 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
196 shadow_frame.GetMethod(), dex_pc);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200197 }
198 return result;
199 }
200 case Instruction::RETURN: {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200201 JValue result;
202 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200203 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700204 self->AllowThreadSuspension();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200205 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200206 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200207 shadow_frame.GetMethod(), inst->GetDexPc(insns),
208 result);
Sebastien Hertze713d932014-05-15 10:48:53 +0200209 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
210 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
211 shadow_frame.GetMethod(), dex_pc);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200212 }
213 return result;
214 }
215 case Instruction::RETURN_WIDE: {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200216 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200217 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700218 self->AllowThreadSuspension();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200219 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200220 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200221 shadow_frame.GetMethod(), inst->GetDexPc(insns),
222 result);
Sebastien Hertze713d932014-05-15 10:48:53 +0200223 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
224 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
225 shadow_frame.GetMethod(), dex_pc);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200226 }
227 return result;
228 }
229 case Instruction::RETURN_OBJECT: {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200230 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700231 self->AllowThreadSuspension();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700232 const size_t ref_idx = inst->VRegA_11x(inst_data);
233 Object* obj_result = shadow_frame.GetVRegReference(ref_idx);
Jeff Haoa3faaf42013-09-03 19:07:00 -0700234 if (do_assignability_check && obj_result != NULL) {
Ian Rogersded66a02014-10-28 18:12:55 -0700235 Class* return_type = shadow_frame.GetMethod()->GetReturnType();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700236 // Re-load since it might have moved.
237 obj_result = shadow_frame.GetVRegReference(ref_idx);
Jeff Haoa3faaf42013-09-03 19:07:00 -0700238 if (return_type == NULL) {
239 // Return the pending exception.
240 HANDLE_PENDING_EXCEPTION();
241 }
242 if (!obj_result->VerifierInstanceOf(return_type)) {
243 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700244 std::string temp1, temp2;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000245 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700246 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700247 obj_result->GetClass()->GetDescriptor(&temp1),
248 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700249 HANDLE_PENDING_EXCEPTION();
250 }
251 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700252 result.SetL(obj_result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200253 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200254 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200255 shadow_frame.GetMethod(), inst->GetDexPc(insns),
256 result);
Sebastien Hertze713d932014-05-15 10:48:53 +0200257 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
258 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
259 shadow_frame.GetMethod(), dex_pc);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200260 }
261 return result;
262 }
263 case Instruction::CONST_4: {
264 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200265 uint4_t dst = inst->VRegA_11n(inst_data);
266 int4_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200267 shadow_frame.SetVReg(dst, val);
268 if (val == 0) {
269 shadow_frame.SetVRegReference(dst, NULL);
270 }
271 inst = inst->Next_1xx();
272 break;
273 }
274 case Instruction::CONST_16: {
275 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200276 uint8_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200277 int16_t val = inst->VRegB_21s();
278 shadow_frame.SetVReg(dst, val);
279 if (val == 0) {
280 shadow_frame.SetVRegReference(dst, NULL);
281 }
282 inst = inst->Next_2xx();
283 break;
284 }
285 case Instruction::CONST: {
286 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200287 uint8_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200288 int32_t val = inst->VRegB_31i();
289 shadow_frame.SetVReg(dst, val);
290 if (val == 0) {
291 shadow_frame.SetVRegReference(dst, NULL);
292 }
293 inst = inst->Next_3xx();
294 break;
295 }
296 case Instruction::CONST_HIGH16: {
297 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200298 uint8_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200299 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
300 shadow_frame.SetVReg(dst, val);
301 if (val == 0) {
302 shadow_frame.SetVRegReference(dst, NULL);
303 }
304 inst = inst->Next_2xx();
305 break;
306 }
307 case Instruction::CONST_WIDE_16:
308 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200309 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200310 inst = inst->Next_2xx();
311 break;
312 case Instruction::CONST_WIDE_32:
313 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200314 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200315 inst = inst->Next_3xx();
316 break;
317 case Instruction::CONST_WIDE:
318 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200319 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200320 inst = inst->Next_51l();
321 break;
322 case Instruction::CONST_WIDE_HIGH16:
Sebastien Hertz3c5aec12014-06-04 09:41:21 +0200323 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200324 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200325 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
326 inst = inst->Next_2xx();
327 break;
328 case Instruction::CONST_STRING: {
329 PREAMBLE();
Ian Rogers6786a582014-10-28 12:49:06 -0700330 String* s = ResolveString(self, shadow_frame, inst->VRegB_21c());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200331 if (UNLIKELY(s == NULL)) {
332 HANDLE_PENDING_EXCEPTION();
333 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200334 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200335 inst = inst->Next_2xx();
336 }
337 break;
338 }
339 case Instruction::CONST_STRING_JUMBO: {
340 PREAMBLE();
Ian Rogers6786a582014-10-28 12:49:06 -0700341 String* s = ResolveString(self, shadow_frame, inst->VRegB_31c());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200342 if (UNLIKELY(s == NULL)) {
343 HANDLE_PENDING_EXCEPTION();
344 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200345 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200346 inst = inst->Next_3xx();
347 }
348 break;
349 }
350 case Instruction::CONST_CLASS: {
351 PREAMBLE();
352 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
353 self, false, do_access_check);
354 if (UNLIKELY(c == NULL)) {
355 HANDLE_PENDING_EXCEPTION();
356 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200357 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200358 inst = inst->Next_2xx();
359 }
360 break;
361 }
362 case Instruction::MONITOR_ENTER: {
363 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200364 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200365 if (UNLIKELY(obj == NULL)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000366 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200367 HANDLE_PENDING_EXCEPTION();
368 } else {
369 DoMonitorEnter(self, obj);
370 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
371 }
372 break;
373 }
374 case Instruction::MONITOR_EXIT: {
375 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200376 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200377 if (UNLIKELY(obj == NULL)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000378 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200379 HANDLE_PENDING_EXCEPTION();
380 } else {
381 DoMonitorExit(self, obj);
382 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
383 }
384 break;
385 }
386 case Instruction::CHECK_CAST: {
387 PREAMBLE();
388 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
389 self, false, do_access_check);
390 if (UNLIKELY(c == NULL)) {
391 HANDLE_PENDING_EXCEPTION();
392 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200393 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200394 if (UNLIKELY(obj != NULL && !obj->InstanceOf(c))) {
395 ThrowClassCastException(c, obj->GetClass());
396 HANDLE_PENDING_EXCEPTION();
397 } else {
398 inst = inst->Next_2xx();
399 }
400 }
401 break;
402 }
403 case Instruction::INSTANCE_OF: {
404 PREAMBLE();
405 Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(),
406 self, false, do_access_check);
407 if (UNLIKELY(c == NULL)) {
408 HANDLE_PENDING_EXCEPTION();
409 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200410 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
411 shadow_frame.SetVReg(inst->VRegA_22c(inst_data), (obj != NULL && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200412 inst = inst->Next_2xx();
413 }
414 break;
415 }
416 case Instruction::ARRAY_LENGTH: {
417 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200418 Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200419 if (UNLIKELY(array == NULL)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000420 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200421 HANDLE_PENDING_EXCEPTION();
422 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200423 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200424 inst = inst->Next_1xx();
425 }
426 break;
427 }
428 case Instruction::NEW_INSTANCE: {
429 PREAMBLE();
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700430 Runtime* runtime = Runtime::Current();
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800431 Object* obj = AllocObjectFromCode<do_access_check, true>(
432 inst->VRegB_21c(), shadow_frame.GetMethod(), self,
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700433 runtime->GetHeap()->GetCurrentAllocator());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200434 if (UNLIKELY(obj == NULL)) {
435 HANDLE_PENDING_EXCEPTION();
436 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200437 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700438 // Don't allow finalizable objects to be allocated during a transaction since these can't
439 // be finalized without a started runtime.
440 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Ian Rogers2fa98e22014-05-06 15:26:39 -0700441 AbortTransaction(self, "Allocating finalizable object in transaction: %s",
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700442 PrettyTypeOf(obj).c_str());
443 HANDLE_PENDING_EXCEPTION();
444 break;
445 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200446 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200447 inst = inst->Next_2xx();
448 }
449 break;
450 }
451 case Instruction::NEW_ARRAY: {
452 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200453 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800454 Object* obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampe1cc7dba2014-12-17 18:43:01 -0800455 inst->VRegC_22c(), length, shadow_frame.GetMethod(), self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800456 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200457 if (UNLIKELY(obj == NULL)) {
458 HANDLE_PENDING_EXCEPTION();
459 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200460 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200461 inst = inst->Next_2xx();
462 }
463 break;
464 }
465 case Instruction::FILLED_NEW_ARRAY: {
466 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100467 bool success =
468 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame, self,
469 &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200470 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
471 break;
472 }
473 case Instruction::FILLED_NEW_ARRAY_RANGE: {
474 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100475 bool success =
476 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
477 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200478 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
479 break;
480 }
481 case Instruction::FILL_ARRAY_DATA: {
482 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200483 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
484 const Instruction::ArrayDataPayload* payload =
485 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
Ian Rogers832336b2014-10-08 15:35:22 -0700486 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
487 bool success = FillArrayData(obj, payload);
488 if (!success) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200489 HANDLE_PENDING_EXCEPTION();
490 break;
491 }
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100492 if (transaction_active) {
Ian Rogers832336b2014-10-08 15:35:22 -0700493 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100494 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200495 inst = inst->Next_3xx();
496 break;
497 }
498 case Instruction::THROW: {
499 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200500 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200501 if (UNLIKELY(exception == NULL)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000502 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700503 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
504 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700505 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000506 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700507 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700508 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200509 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000510 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200511 }
512 HANDLE_PENDING_EXCEPTION();
513 break;
514 }
515 case Instruction::GOTO: {
516 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200517 int8_t offset = inst->VRegA_10t(inst_data);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200518 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700519 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200520 }
521 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200522 break;
523 }
524 case Instruction::GOTO_16: {
525 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200526 int16_t offset = inst->VRegA_20t();
527 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700528 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200529 }
530 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200531 break;
532 }
533 case Instruction::GOTO_32: {
534 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200535 int32_t offset = inst->VRegA_30t();
536 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700537 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200538 }
539 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200540 break;
541 }
542 case Instruction::PACKED_SWITCH: {
543 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200544 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200545 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700546 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200547 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200548 inst = inst->RelativeAt(offset);
549 break;
550 }
551 case Instruction::SPARSE_SWITCH: {
552 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200553 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200554 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700555 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200556 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200557 inst = inst->RelativeAt(offset);
558 break;
559 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700560
561#if defined(__clang__)
562#pragma clang diagnostic push
563#pragma clang diagnostic ignored "-Wfloat-equal"
564#endif
565
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200566 case Instruction::CMPL_FLOAT: {
567 PREAMBLE();
568 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
569 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
570 int32_t result;
571 if (val1 > val2) {
572 result = 1;
573 } else if (val1 == val2) {
574 result = 0;
575 } else {
576 result = -1;
577 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200578 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200579 inst = inst->Next_2xx();
580 break;
581 }
582 case Instruction::CMPG_FLOAT: {
583 PREAMBLE();
584 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
585 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
586 int32_t result;
587 if (val1 < val2) {
588 result = -1;
589 } else if (val1 == val2) {
590 result = 0;
591 } else {
592 result = 1;
593 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200594 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200595 inst = inst->Next_2xx();
596 break;
597 }
598 case Instruction::CMPL_DOUBLE: {
599 PREAMBLE();
600 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
601 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
602 int32_t result;
603 if (val1 > val2) {
604 result = 1;
605 } else if (val1 == val2) {
606 result = 0;
607 } else {
608 result = -1;
609 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200610 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200611 inst = inst->Next_2xx();
612 break;
613 }
614
615 case Instruction::CMPG_DOUBLE: {
616 PREAMBLE();
617 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
618 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
619 int32_t result;
620 if (val1 < val2) {
621 result = -1;
622 } else if (val1 == val2) {
623 result = 0;
624 } else {
625 result = 1;
626 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200627 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200628 inst = inst->Next_2xx();
629 break;
630 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700631
632#if defined(__clang__)
633#pragma clang diagnostic pop
634#endif
635
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200636 case Instruction::CMP_LONG: {
637 PREAMBLE();
638 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
639 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
640 int32_t result;
641 if (val1 > val2) {
642 result = 1;
643 } else if (val1 == val2) {
644 result = 0;
645 } else {
646 result = -1;
647 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200648 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200649 inst = inst->Next_2xx();
650 break;
651 }
652 case Instruction::IF_EQ: {
653 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200654 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) == shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200655 int16_t offset = inst->VRegC_22t();
656 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700657 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200658 }
659 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200660 } else {
661 inst = inst->Next_2xx();
662 }
663 break;
664 }
665 case Instruction::IF_NE: {
666 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200667 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) != shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200668 int16_t offset = inst->VRegC_22t();
669 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700670 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200671 }
672 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200673 } else {
674 inst = inst->Next_2xx();
675 }
676 break;
677 }
678 case Instruction::IF_LT: {
679 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200680 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) < shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200681 int16_t offset = inst->VRegC_22t();
682 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700683 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200684 }
685 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200686 } else {
687 inst = inst->Next_2xx();
688 }
689 break;
690 }
691 case Instruction::IF_GE: {
692 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200693 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >= shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200694 int16_t offset = inst->VRegC_22t();
695 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700696 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200697 }
698 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200699 } else {
700 inst = inst->Next_2xx();
701 }
702 break;
703 }
704 case Instruction::IF_GT: {
705 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200706 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) > shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200707 int16_t offset = inst->VRegC_22t();
708 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700709 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200710 }
711 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200712 } else {
713 inst = inst->Next_2xx();
714 }
715 break;
716 }
717 case Instruction::IF_LE: {
718 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200719 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <= shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200720 int16_t offset = inst->VRegC_22t();
721 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700722 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200723 }
724 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200725 } else {
726 inst = inst->Next_2xx();
727 }
728 break;
729 }
730 case Instruction::IF_EQZ: {
731 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200732 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200733 int16_t offset = inst->VRegB_21t();
734 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700735 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200736 }
737 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200738 } else {
739 inst = inst->Next_2xx();
740 }
741 break;
742 }
743 case Instruction::IF_NEZ: {
744 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200745 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200746 int16_t offset = inst->VRegB_21t();
747 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700748 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200749 }
750 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200751 } else {
752 inst = inst->Next_2xx();
753 }
754 break;
755 }
756 case Instruction::IF_LTZ: {
757 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200758 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200759 int16_t offset = inst->VRegB_21t();
760 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700761 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200762 }
763 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200764 } else {
765 inst = inst->Next_2xx();
766 }
767 break;
768 }
769 case Instruction::IF_GEZ: {
770 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200771 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200772 int16_t offset = inst->VRegB_21t();
773 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700774 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200775 }
776 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200777 } else {
778 inst = inst->Next_2xx();
779 }
780 break;
781 }
782 case Instruction::IF_GTZ: {
783 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200784 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200785 int16_t offset = inst->VRegB_21t();
786 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700787 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200788 }
789 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200790 } else {
791 inst = inst->Next_2xx();
792 }
793 break;
794 }
795 case Instruction::IF_LEZ: {
796 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200797 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200798 int16_t offset = inst->VRegB_21t();
799 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700800 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200801 }
802 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200803 } else {
804 inst = inst->Next_2xx();
805 }
806 break;
807 }
808 case Instruction::AGET_BOOLEAN: {
809 PREAMBLE();
810 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
811 if (UNLIKELY(a == NULL)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000812 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200813 HANDLE_PENDING_EXCEPTION();
814 break;
815 }
816 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
817 BooleanArray* array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700818 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100819 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200820 inst = inst->Next_2xx();
821 } else {
822 HANDLE_PENDING_EXCEPTION();
823 }
824 break;
825 }
826 case Instruction::AGET_BYTE: {
827 PREAMBLE();
828 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
829 if (UNLIKELY(a == NULL)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000830 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200831 HANDLE_PENDING_EXCEPTION();
832 break;
833 }
834 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
835 ByteArray* array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700836 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100837 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200838 inst = inst->Next_2xx();
839 } else {
840 HANDLE_PENDING_EXCEPTION();
841 }
842 break;
843 }
844 case Instruction::AGET_CHAR: {
845 PREAMBLE();
846 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
847 if (UNLIKELY(a == NULL)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000848 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200849 HANDLE_PENDING_EXCEPTION();
850 break;
851 }
852 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
853 CharArray* array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700854 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100855 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200856 inst = inst->Next_2xx();
857 } else {
858 HANDLE_PENDING_EXCEPTION();
859 }
860 break;
861 }
862 case Instruction::AGET_SHORT: {
863 PREAMBLE();
864 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
865 if (UNLIKELY(a == NULL)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000866 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200867 HANDLE_PENDING_EXCEPTION();
868 break;
869 }
870 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
871 ShortArray* array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700872 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100873 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200874 inst = inst->Next_2xx();
875 } else {
876 HANDLE_PENDING_EXCEPTION();
877 }
878 break;
879 }
880 case Instruction::AGET: {
881 PREAMBLE();
882 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
883 if (UNLIKELY(a == NULL)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000884 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200885 HANDLE_PENDING_EXCEPTION();
886 break;
887 }
888 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
889 IntArray* array = a->AsIntArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700890 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100891 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200892 inst = inst->Next_2xx();
893 } else {
894 HANDLE_PENDING_EXCEPTION();
895 }
896 break;
897 }
898 case Instruction::AGET_WIDE: {
899 PREAMBLE();
900 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
901 if (UNLIKELY(a == NULL)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000902 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200903 HANDLE_PENDING_EXCEPTION();
904 break;
905 }
906 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
907 LongArray* array = a->AsLongArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700908 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100909 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200910 inst = inst->Next_2xx();
911 } else {
912 HANDLE_PENDING_EXCEPTION();
913 }
914 break;
915 }
916 case Instruction::AGET_OBJECT: {
917 PREAMBLE();
918 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
919 if (UNLIKELY(a == NULL)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000920 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200921 HANDLE_PENDING_EXCEPTION();
922 break;
923 }
924 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
925 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700926 if (array->CheckIsValidIndex(index)) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200927 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200928 inst = inst->Next_2xx();
929 } else {
930 HANDLE_PENDING_EXCEPTION();
931 }
932 break;
933 }
934 case Instruction::APUT_BOOLEAN: {
935 PREAMBLE();
936 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
937 if (UNLIKELY(a == NULL)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000938 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200939 HANDLE_PENDING_EXCEPTION();
940 break;
941 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200942 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200943 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
944 BooleanArray* array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700945 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100946 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200947 inst = inst->Next_2xx();
948 } else {
949 HANDLE_PENDING_EXCEPTION();
950 }
951 break;
952 }
953 case Instruction::APUT_BYTE: {
954 PREAMBLE();
955 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
956 if (UNLIKELY(a == NULL)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000957 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200958 HANDLE_PENDING_EXCEPTION();
959 break;
960 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200961 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200962 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
963 ByteArray* array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700964 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100965 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200966 inst = inst->Next_2xx();
967 } else {
968 HANDLE_PENDING_EXCEPTION();
969 }
970 break;
971 }
972 case Instruction::APUT_CHAR: {
973 PREAMBLE();
974 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
975 if (UNLIKELY(a == NULL)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000976 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200977 HANDLE_PENDING_EXCEPTION();
978 break;
979 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200980 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200981 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
982 CharArray* array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700983 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100984 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200985 inst = inst->Next_2xx();
986 } else {
987 HANDLE_PENDING_EXCEPTION();
988 }
989 break;
990 }
991 case Instruction::APUT_SHORT: {
992 PREAMBLE();
993 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
994 if (UNLIKELY(a == NULL)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000995 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200996 HANDLE_PENDING_EXCEPTION();
997 break;
998 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200999 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001000 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1001 ShortArray* array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001002 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001003 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001004 inst = inst->Next_2xx();
1005 } else {
1006 HANDLE_PENDING_EXCEPTION();
1007 }
1008 break;
1009 }
1010 case Instruction::APUT: {
1011 PREAMBLE();
1012 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1013 if (UNLIKELY(a == NULL)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001014 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001015 HANDLE_PENDING_EXCEPTION();
1016 break;
1017 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001018 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001019 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1020 IntArray* array = a->AsIntArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001021 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001022 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001023 inst = inst->Next_2xx();
1024 } else {
1025 HANDLE_PENDING_EXCEPTION();
1026 }
1027 break;
1028 }
1029 case Instruction::APUT_WIDE: {
1030 PREAMBLE();
1031 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1032 if (UNLIKELY(a == NULL)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001033 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001034 HANDLE_PENDING_EXCEPTION();
1035 break;
1036 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001037 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001038 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1039 LongArray* array = a->AsLongArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001040 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001041 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001042 inst = inst->Next_2xx();
1043 } else {
1044 HANDLE_PENDING_EXCEPTION();
1045 }
1046 break;
1047 }
1048 case Instruction::APUT_OBJECT: {
1049 PREAMBLE();
1050 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1051 if (UNLIKELY(a == NULL)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001052 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001053 HANDLE_PENDING_EXCEPTION();
1054 break;
1055 }
1056 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001057 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001058 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001059 if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001060 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001061 inst = inst->Next_2xx();
1062 } else {
1063 HANDLE_PENDING_EXCEPTION();
1064 }
1065 break;
1066 }
1067 case Instruction::IGET_BOOLEAN: {
1068 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001069 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001070 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1071 break;
1072 }
1073 case Instruction::IGET_BYTE: {
1074 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001075 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001076 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1077 break;
1078 }
1079 case Instruction::IGET_CHAR: {
1080 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001081 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001082 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1083 break;
1084 }
1085 case Instruction::IGET_SHORT: {
1086 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001087 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001088 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1089 break;
1090 }
1091 case Instruction::IGET: {
1092 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001093 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001094 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1095 break;
1096 }
1097 case Instruction::IGET_WIDE: {
1098 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001099 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001100 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1101 break;
1102 }
1103 case Instruction::IGET_OBJECT: {
1104 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001105 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001106 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1107 break;
1108 }
1109 case Instruction::IGET_QUICK: {
1110 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001111 bool success = DoIGetQuick<Primitive::kPrimInt>(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_QUICK: {
1116 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001117 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001118 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1119 break;
1120 }
1121 case Instruction::IGET_OBJECT_QUICK: {
1122 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001123 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001124 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1125 break;
1126 }
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001127 case Instruction::IGET_BOOLEAN_QUICK: {
1128 PREAMBLE();
1129 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1130 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1131 break;
1132 }
1133 case Instruction::IGET_BYTE_QUICK: {
1134 PREAMBLE();
1135 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1136 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1137 break;
1138 }
1139 case Instruction::IGET_CHAR_QUICK: {
1140 PREAMBLE();
1141 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1142 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1143 break;
1144 }
1145 case Instruction::IGET_SHORT_QUICK: {
1146 PREAMBLE();
1147 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1148 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1149 break;
1150 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001151 case Instruction::SGET_BOOLEAN: {
1152 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001153 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001154 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1155 break;
1156 }
1157 case Instruction::SGET_BYTE: {
1158 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001159 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001160 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1161 break;
1162 }
1163 case Instruction::SGET_CHAR: {
1164 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001165 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001166 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1167 break;
1168 }
1169 case Instruction::SGET_SHORT: {
1170 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001171 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001172 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1173 break;
1174 }
1175 case Instruction::SGET: {
1176 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001177 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001178 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1179 break;
1180 }
1181 case Instruction::SGET_WIDE: {
1182 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001183 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001184 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1185 break;
1186 }
1187 case Instruction::SGET_OBJECT: {
1188 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001189 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001190 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1191 break;
1192 }
1193 case Instruction::IPUT_BOOLEAN: {
1194 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001195 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check, transaction_active>(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::IPUT_BYTE: {
1200 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001201 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001202 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1203 break;
1204 }
1205 case Instruction::IPUT_CHAR: {
1206 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001207 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001208 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1209 break;
1210 }
1211 case Instruction::IPUT_SHORT: {
1212 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001213 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001214 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1215 break;
1216 }
1217 case Instruction::IPUT: {
1218 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001219 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001220 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1221 break;
1222 }
1223 case Instruction::IPUT_WIDE: {
1224 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001225 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001226 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1227 break;
1228 }
1229 case Instruction::IPUT_OBJECT: {
1230 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001231 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001232 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1233 break;
1234 }
1235 case Instruction::IPUT_QUICK: {
1236 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001237 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001238 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1239 break;
1240 }
Fred Shih37f05ef2014-07-16 18:38:08 -07001241 case Instruction::IPUT_BOOLEAN_QUICK: {
1242 PREAMBLE();
1243 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(shadow_frame, inst, inst_data);
1244 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1245 break;
1246 }
1247 case Instruction::IPUT_BYTE_QUICK: {
1248 PREAMBLE();
1249 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(shadow_frame, inst, inst_data);
1250 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1251 break;
1252 }
1253 case Instruction::IPUT_CHAR_QUICK: {
1254 PREAMBLE();
1255 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(shadow_frame, inst, inst_data);
1256 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1257 break;
1258 }
1259 case Instruction::IPUT_SHORT_QUICK: {
1260 PREAMBLE();
1261 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(shadow_frame, inst, inst_data);
1262 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1263 break;
1264 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001265 case Instruction::IPUT_WIDE_QUICK: {
1266 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001267 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001268 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1269 break;
1270 }
1271 case Instruction::IPUT_OBJECT_QUICK: {
1272 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001273 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001274 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1275 break;
1276 }
1277 case Instruction::SPUT_BOOLEAN: {
1278 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001279 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001280 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1281 break;
1282 }
1283 case Instruction::SPUT_BYTE: {
1284 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001285 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001286 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1287 break;
1288 }
1289 case Instruction::SPUT_CHAR: {
1290 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001291 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001292 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1293 break;
1294 }
1295 case Instruction::SPUT_SHORT: {
1296 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001297 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001298 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1299 break;
1300 }
1301 case Instruction::SPUT: {
1302 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001303 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001304 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1305 break;
1306 }
1307 case Instruction::SPUT_WIDE: {
1308 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001309 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001310 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1311 break;
1312 }
1313 case Instruction::SPUT_OBJECT: {
1314 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001315 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001316 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1317 break;
1318 }
1319 case Instruction::INVOKE_VIRTUAL: {
1320 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001321 bool success = DoInvoke<kVirtual, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001322 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1323 break;
1324 }
1325 case Instruction::INVOKE_VIRTUAL_RANGE: {
1326 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001327 bool success = DoInvoke<kVirtual, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001328 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1329 break;
1330 }
1331 case Instruction::INVOKE_SUPER: {
1332 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001333 bool success = DoInvoke<kSuper, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001334 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1335 break;
1336 }
1337 case Instruction::INVOKE_SUPER_RANGE: {
1338 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001339 bool success = DoInvoke<kSuper, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001340 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1341 break;
1342 }
1343 case Instruction::INVOKE_DIRECT: {
1344 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001345 bool success = DoInvoke<kDirect, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001346 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1347 break;
1348 }
1349 case Instruction::INVOKE_DIRECT_RANGE: {
1350 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001351 bool success = DoInvoke<kDirect, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001352 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1353 break;
1354 }
1355 case Instruction::INVOKE_INTERFACE: {
1356 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001357 bool success = DoInvoke<kInterface, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001358 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1359 break;
1360 }
1361 case Instruction::INVOKE_INTERFACE_RANGE: {
1362 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001363 bool success = DoInvoke<kInterface, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001364 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1365 break;
1366 }
1367 case Instruction::INVOKE_STATIC: {
1368 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001369 bool success = DoInvoke<kStatic, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001370 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1371 break;
1372 }
1373 case Instruction::INVOKE_STATIC_RANGE: {
1374 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001375 bool success = DoInvoke<kStatic, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001376 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1377 break;
1378 }
1379 case Instruction::INVOKE_VIRTUAL_QUICK: {
1380 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001381 bool success = DoInvokeVirtualQuick<false>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001382 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1383 break;
1384 }
1385 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
1386 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001387 bool success = DoInvokeVirtualQuick<true>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001388 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1389 break;
1390 }
1391 case Instruction::NEG_INT:
1392 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001393 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001394 inst = inst->Next_1xx();
1395 break;
1396 case Instruction::NOT_INT:
1397 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001398 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001399 inst = inst->Next_1xx();
1400 break;
1401 case Instruction::NEG_LONG:
1402 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001403 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001404 inst = inst->Next_1xx();
1405 break;
1406 case Instruction::NOT_LONG:
1407 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001408 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001409 inst = inst->Next_1xx();
1410 break;
1411 case Instruction::NEG_FLOAT:
1412 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001413 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001414 inst = inst->Next_1xx();
1415 break;
1416 case Instruction::NEG_DOUBLE:
1417 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001418 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001419 inst = inst->Next_1xx();
1420 break;
1421 case Instruction::INT_TO_LONG:
1422 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001423 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
1424 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001425 inst = inst->Next_1xx();
1426 break;
1427 case Instruction::INT_TO_FLOAT:
1428 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001429 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1430 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001431 inst = inst->Next_1xx();
1432 break;
1433 case Instruction::INT_TO_DOUBLE:
1434 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001435 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1436 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001437 inst = inst->Next_1xx();
1438 break;
1439 case Instruction::LONG_TO_INT:
1440 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001441 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1442 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001443 inst = inst->Next_1xx();
1444 break;
1445 case Instruction::LONG_TO_FLOAT:
1446 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001447 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1448 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001449 inst = inst->Next_1xx();
1450 break;
1451 case Instruction::LONG_TO_DOUBLE:
1452 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001453 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1454 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001455 inst = inst->Next_1xx();
1456 break;
1457 case Instruction::FLOAT_TO_INT: {
1458 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001459 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001460 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001461 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001462 inst = inst->Next_1xx();
1463 break;
1464 }
1465 case Instruction::FLOAT_TO_LONG: {
1466 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001467 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001468 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001469 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001470 inst = inst->Next_1xx();
1471 break;
1472 }
1473 case Instruction::FLOAT_TO_DOUBLE:
1474 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001475 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1476 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001477 inst = inst->Next_1xx();
1478 break;
1479 case Instruction::DOUBLE_TO_INT: {
1480 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001481 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001482 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001483 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001484 inst = inst->Next_1xx();
1485 break;
1486 }
1487 case Instruction::DOUBLE_TO_LONG: {
1488 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001489 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001490 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001491 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001492 inst = inst->Next_1xx();
1493 break;
1494 }
1495 case Instruction::DOUBLE_TO_FLOAT:
1496 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001497 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1498 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001499 inst = inst->Next_1xx();
1500 break;
1501 case Instruction::INT_TO_BYTE:
1502 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001503 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1504 static_cast<int8_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001505 inst = inst->Next_1xx();
1506 break;
1507 case Instruction::INT_TO_CHAR:
1508 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001509 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1510 static_cast<uint16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001511 inst = inst->Next_1xx();
1512 break;
1513 case Instruction::INT_TO_SHORT:
1514 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001515 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1516 static_cast<int16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001517 inst = inst->Next_1xx();
1518 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001519 case Instruction::ADD_INT: {
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001520 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001521 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001522 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1523 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001524 inst = inst->Next_2xx();
1525 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001526 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001527 case Instruction::SUB_INT:
1528 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001529 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001530 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1531 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001532 inst = inst->Next_2xx();
1533 break;
1534 case Instruction::MUL_INT:
1535 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001536 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001537 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1538 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001539 inst = inst->Next_2xx();
1540 break;
1541 case Instruction::DIV_INT: {
1542 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001543 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001544 shadow_frame.GetVReg(inst->VRegB_23x()),
1545 shadow_frame.GetVReg(inst->VRegC_23x()));
1546 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1547 break;
1548 }
1549 case Instruction::REM_INT: {
1550 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001551 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001552 shadow_frame.GetVReg(inst->VRegB_23x()),
1553 shadow_frame.GetVReg(inst->VRegC_23x()));
1554 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1555 break;
1556 }
1557 case Instruction::SHL_INT:
1558 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001559 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001560 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1561 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1562 inst = inst->Next_2xx();
1563 break;
1564 case Instruction::SHR_INT:
1565 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001566 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001567 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1568 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1569 inst = inst->Next_2xx();
1570 break;
1571 case Instruction::USHR_INT:
1572 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001573 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001574 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1575 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1576 inst = inst->Next_2xx();
1577 break;
1578 case Instruction::AND_INT:
1579 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001580 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001581 shadow_frame.GetVReg(inst->VRegB_23x()) &
1582 shadow_frame.GetVReg(inst->VRegC_23x()));
1583 inst = inst->Next_2xx();
1584 break;
1585 case Instruction::OR_INT:
1586 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001587 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001588 shadow_frame.GetVReg(inst->VRegB_23x()) |
1589 shadow_frame.GetVReg(inst->VRegC_23x()));
1590 inst = inst->Next_2xx();
1591 break;
1592 case Instruction::XOR_INT:
1593 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001594 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001595 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1596 shadow_frame.GetVReg(inst->VRegC_23x()));
1597 inst = inst->Next_2xx();
1598 break;
1599 case Instruction::ADD_LONG:
1600 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001601 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001602 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1603 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001604 inst = inst->Next_2xx();
1605 break;
1606 case Instruction::SUB_LONG:
1607 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001608 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001609 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1610 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001611 inst = inst->Next_2xx();
1612 break;
1613 case Instruction::MUL_LONG:
1614 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001615 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001616 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1617 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001618 inst = inst->Next_2xx();
1619 break;
1620 case Instruction::DIV_LONG:
1621 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001622 DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001623 shadow_frame.GetVRegLong(inst->VRegB_23x()),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001624 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001625 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1626 break;
1627 case Instruction::REM_LONG:
1628 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001629 DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001630 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1631 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1632 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1633 break;
1634 case Instruction::AND_LONG:
1635 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001636 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001637 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1638 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1639 inst = inst->Next_2xx();
1640 break;
1641 case Instruction::OR_LONG:
1642 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001643 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001644 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1645 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1646 inst = inst->Next_2xx();
1647 break;
1648 case Instruction::XOR_LONG:
1649 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001650 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001651 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1652 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1653 inst = inst->Next_2xx();
1654 break;
1655 case Instruction::SHL_LONG:
1656 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001657 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001658 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1659 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1660 inst = inst->Next_2xx();
1661 break;
1662 case Instruction::SHR_LONG:
1663 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001664 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001665 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1666 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1667 inst = inst->Next_2xx();
1668 break;
1669 case Instruction::USHR_LONG:
1670 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001671 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001672 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1673 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1674 inst = inst->Next_2xx();
1675 break;
1676 case Instruction::ADD_FLOAT:
1677 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001678 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001679 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1680 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1681 inst = inst->Next_2xx();
1682 break;
1683 case Instruction::SUB_FLOAT:
1684 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001685 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001686 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1687 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1688 inst = inst->Next_2xx();
1689 break;
1690 case Instruction::MUL_FLOAT:
1691 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001692 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001693 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1694 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1695 inst = inst->Next_2xx();
1696 break;
1697 case Instruction::DIV_FLOAT:
1698 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001699 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001700 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1701 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1702 inst = inst->Next_2xx();
1703 break;
1704 case Instruction::REM_FLOAT:
1705 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001706 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001707 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1708 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1709 inst = inst->Next_2xx();
1710 break;
1711 case Instruction::ADD_DOUBLE:
1712 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001713 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001714 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1715 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1716 inst = inst->Next_2xx();
1717 break;
1718 case Instruction::SUB_DOUBLE:
1719 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001720 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001721 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1722 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1723 inst = inst->Next_2xx();
1724 break;
1725 case Instruction::MUL_DOUBLE:
1726 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001727 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001728 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
1729 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1730 inst = inst->Next_2xx();
1731 break;
1732 case Instruction::DIV_DOUBLE:
1733 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001734 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001735 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
1736 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1737 inst = inst->Next_2xx();
1738 break;
1739 case Instruction::REM_DOUBLE:
1740 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001741 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001742 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
1743 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
1744 inst = inst->Next_2xx();
1745 break;
1746 case Instruction::ADD_INT_2ADDR: {
1747 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001748 uint4_t vregA = inst->VRegA_12x(inst_data);
Ian Rogersf72a11d2014-10-30 15:41:08 -07001749 shadow_frame.SetVReg(vregA, SafeAdd(shadow_frame.GetVReg(vregA),
1750 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001751 inst = inst->Next_1xx();
1752 break;
1753 }
1754 case Instruction::SUB_INT_2ADDR: {
1755 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001756 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001757 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001758 SafeSub(shadow_frame.GetVReg(vregA),
1759 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001760 inst = inst->Next_1xx();
1761 break;
1762 }
1763 case Instruction::MUL_INT_2ADDR: {
1764 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001765 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001766 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001767 SafeMul(shadow_frame.GetVReg(vregA),
1768 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001769 inst = inst->Next_1xx();
1770 break;
1771 }
1772 case Instruction::DIV_INT_2ADDR: {
1773 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001774 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001775 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001776 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001777 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1778 break;
1779 }
1780 case Instruction::REM_INT_2ADDR: {
1781 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001782 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001783 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001784 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001785 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1786 break;
1787 }
1788 case Instruction::SHL_INT_2ADDR: {
1789 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001790 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001791 shadow_frame.SetVReg(vregA,
1792 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001793 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001794 inst = inst->Next_1xx();
1795 break;
1796 }
1797 case Instruction::SHR_INT_2ADDR: {
1798 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001799 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001800 shadow_frame.SetVReg(vregA,
1801 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001802 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001803 inst = inst->Next_1xx();
1804 break;
1805 }
1806 case Instruction::USHR_INT_2ADDR: {
1807 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001808 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001809 shadow_frame.SetVReg(vregA,
1810 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001811 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001812 inst = inst->Next_1xx();
1813 break;
1814 }
1815 case Instruction::AND_INT_2ADDR: {
1816 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001817 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001818 shadow_frame.SetVReg(vregA,
1819 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001820 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001821 inst = inst->Next_1xx();
1822 break;
1823 }
1824 case Instruction::OR_INT_2ADDR: {
1825 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001826 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001827 shadow_frame.SetVReg(vregA,
1828 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001829 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001830 inst = inst->Next_1xx();
1831 break;
1832 }
1833 case Instruction::XOR_INT_2ADDR: {
1834 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001835 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001836 shadow_frame.SetVReg(vregA,
1837 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001838 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001839 inst = inst->Next_1xx();
1840 break;
1841 }
1842 case Instruction::ADD_LONG_2ADDR: {
1843 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001844 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001845 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001846 SafeAdd(shadow_frame.GetVRegLong(vregA),
1847 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001848 inst = inst->Next_1xx();
1849 break;
1850 }
1851 case Instruction::SUB_LONG_2ADDR: {
1852 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001853 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001854 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001855 SafeSub(shadow_frame.GetVRegLong(vregA),
1856 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001857 inst = inst->Next_1xx();
1858 break;
1859 }
1860 case Instruction::MUL_LONG_2ADDR: {
1861 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001862 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001863 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001864 SafeMul(shadow_frame.GetVRegLong(vregA),
1865 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001866 inst = inst->Next_1xx();
1867 break;
1868 }
1869 case Instruction::DIV_LONG_2ADDR: {
1870 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001871 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001872 DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001873 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001874 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
1875 break;
1876 }
1877 case Instruction::REM_LONG_2ADDR: {
1878 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001879 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001880 DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001881 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001882 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
1883 break;
1884 }
1885 case Instruction::AND_LONG_2ADDR: {
1886 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001887 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001888 shadow_frame.SetVRegLong(vregA,
1889 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001890 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001891 inst = inst->Next_1xx();
1892 break;
1893 }
1894 case Instruction::OR_LONG_2ADDR: {
1895 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001896 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001897 shadow_frame.SetVRegLong(vregA,
1898 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001899 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001900 inst = inst->Next_1xx();
1901 break;
1902 }
1903 case Instruction::XOR_LONG_2ADDR: {
1904 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001905 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001906 shadow_frame.SetVRegLong(vregA,
1907 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001908 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001909 inst = inst->Next_1xx();
1910 break;
1911 }
1912 case Instruction::SHL_LONG_2ADDR: {
1913 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001914 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001915 shadow_frame.SetVRegLong(vregA,
1916 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001917 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001918 inst = inst->Next_1xx();
1919 break;
1920 }
1921 case Instruction::SHR_LONG_2ADDR: {
1922 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001923 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001924 shadow_frame.SetVRegLong(vregA,
1925 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001926 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001927 inst = inst->Next_1xx();
1928 break;
1929 }
1930 case Instruction::USHR_LONG_2ADDR: {
1931 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001932 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001933 shadow_frame.SetVRegLong(vregA,
1934 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001935 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001936 inst = inst->Next_1xx();
1937 break;
1938 }
1939 case Instruction::ADD_FLOAT_2ADDR: {
1940 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001941 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001942 shadow_frame.SetVRegFloat(vregA,
1943 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001944 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001945 inst = inst->Next_1xx();
1946 break;
1947 }
1948 case Instruction::SUB_FLOAT_2ADDR: {
1949 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001950 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001951 shadow_frame.SetVRegFloat(vregA,
1952 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001953 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001954 inst = inst->Next_1xx();
1955 break;
1956 }
1957 case Instruction::MUL_FLOAT_2ADDR: {
1958 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001959 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001960 shadow_frame.SetVRegFloat(vregA,
1961 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001962 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001963 inst = inst->Next_1xx();
1964 break;
1965 }
1966 case Instruction::DIV_FLOAT_2ADDR: {
1967 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001968 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001969 shadow_frame.SetVRegFloat(vregA,
1970 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001971 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001972 inst = inst->Next_1xx();
1973 break;
1974 }
1975 case Instruction::REM_FLOAT_2ADDR: {
1976 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001977 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001978 shadow_frame.SetVRegFloat(vregA,
1979 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001980 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001981 inst = inst->Next_1xx();
1982 break;
1983 }
1984 case Instruction::ADD_DOUBLE_2ADDR: {
1985 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001986 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001987 shadow_frame.SetVRegDouble(vregA,
1988 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001989 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001990 inst = inst->Next_1xx();
1991 break;
1992 }
1993 case Instruction::SUB_DOUBLE_2ADDR: {
1994 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001995 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001996 shadow_frame.SetVRegDouble(vregA,
1997 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001998 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001999 inst = inst->Next_1xx();
2000 break;
2001 }
2002 case Instruction::MUL_DOUBLE_2ADDR: {
2003 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002004 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002005 shadow_frame.SetVRegDouble(vregA,
2006 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002007 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002008 inst = inst->Next_1xx();
2009 break;
2010 }
2011 case Instruction::DIV_DOUBLE_2ADDR: {
2012 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002013 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002014 shadow_frame.SetVRegDouble(vregA,
2015 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002016 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002017 inst = inst->Next_1xx();
2018 break;
2019 }
2020 case Instruction::REM_DOUBLE_2ADDR: {
2021 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002022 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002023 shadow_frame.SetVRegDouble(vregA,
2024 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002025 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002026 inst = inst->Next_1xx();
2027 break;
2028 }
2029 case Instruction::ADD_INT_LIT16:
2030 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002031 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002032 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2033 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002034 inst = inst->Next_2xx();
2035 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07002036 case Instruction::RSUB_INT_LIT16:
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002037 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002038 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002039 SafeSub(inst->VRegC_22s(),
2040 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002041 inst = inst->Next_2xx();
2042 break;
2043 case Instruction::MUL_INT_LIT16:
2044 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002045 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002046 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2047 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002048 inst = inst->Next_2xx();
2049 break;
2050 case Instruction::DIV_INT_LIT16: {
2051 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002052 bool success = DoIntDivide(shadow_frame, inst->VRegA_22s(inst_data),
2053 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)), inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002054 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2055 break;
2056 }
2057 case Instruction::REM_INT_LIT16: {
2058 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002059 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22s(inst_data),
2060 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)), inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002061 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2062 break;
2063 }
2064 case Instruction::AND_INT_LIT16:
2065 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002066 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2067 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002068 inst->VRegC_22s());
2069 inst = inst->Next_2xx();
2070 break;
2071 case Instruction::OR_INT_LIT16:
2072 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002073 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2074 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002075 inst->VRegC_22s());
2076 inst = inst->Next_2xx();
2077 break;
2078 case Instruction::XOR_INT_LIT16:
2079 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002080 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2081 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002082 inst->VRegC_22s());
2083 inst = inst->Next_2xx();
2084 break;
2085 case Instruction::ADD_INT_LIT8:
2086 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002087 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002088 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002089 inst = inst->Next_2xx();
2090 break;
2091 case Instruction::RSUB_INT_LIT8:
2092 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002093 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002094 SafeSub(inst->VRegC_22b(), shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002095 inst = inst->Next_2xx();
2096 break;
2097 case Instruction::MUL_INT_LIT8:
2098 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002099 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002100 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002101 inst = inst->Next_2xx();
2102 break;
2103 case Instruction::DIV_INT_LIT8: {
2104 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002105 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002106 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2107 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2108 break;
2109 }
2110 case Instruction::REM_INT_LIT8: {
2111 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002112 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002113 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2114 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2115 break;
2116 }
2117 case Instruction::AND_INT_LIT8:
2118 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002119 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002120 shadow_frame.GetVReg(inst->VRegB_22b()) &
2121 inst->VRegC_22b());
2122 inst = inst->Next_2xx();
2123 break;
2124 case Instruction::OR_INT_LIT8:
2125 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002126 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002127 shadow_frame.GetVReg(inst->VRegB_22b()) |
2128 inst->VRegC_22b());
2129 inst = inst->Next_2xx();
2130 break;
2131 case Instruction::XOR_INT_LIT8:
2132 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002133 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002134 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2135 inst->VRegC_22b());
2136 inst = inst->Next_2xx();
2137 break;
2138 case Instruction::SHL_INT_LIT8:
2139 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002140 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002141 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2142 (inst->VRegC_22b() & 0x1f));
2143 inst = inst->Next_2xx();
2144 break;
2145 case Instruction::SHR_INT_LIT8:
2146 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002147 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002148 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2149 (inst->VRegC_22b() & 0x1f));
2150 inst = inst->Next_2xx();
2151 break;
2152 case Instruction::USHR_INT_LIT8:
2153 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002154 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002155 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2156 (inst->VRegC_22b() & 0x1f));
2157 inst = inst->Next_2xx();
2158 break;
2159 case Instruction::UNUSED_3E ... Instruction::UNUSED_43:
Mathieu Chartierffc605c2014-12-10 10:35:44 -08002160 case Instruction::UNUSED_F3 ... Instruction::UNUSED_FF:
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002161 case Instruction::UNUSED_79:
2162 case Instruction::UNUSED_7A:
Ian Rogerse94652f2014-12-02 11:13:19 -08002163 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002164 }
2165 }
2166} // NOLINT(readability/fn_size)
2167
2168// Explicit definitions of ExecuteSwitchImpl.
Sebastien Hertzc6714852013-09-30 16:42:32 +02002169template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002170JValue ExecuteSwitchImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002171 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertzc6714852013-09-30 16:42:32 +02002172template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002173JValue ExecuteSwitchImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002174 ShadowFrame& shadow_frame, JValue result_register);
2175template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002176JValue ExecuteSwitchImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002177 ShadowFrame& shadow_frame, JValue result_register);
2178template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002179JValue ExecuteSwitchImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002180 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002181
2182} // namespace interpreter
2183} // namespace art