blob: bdf2a2019273687a9bd655be2b9422d26c33f20e [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"
18
19namespace art {
20namespace interpreter {
21
22#define HANDLE_PENDING_EXCEPTION() \
23 do { \
Sebastien Hertz82aeddb2014-05-20 20:09:45 +020024 DCHECK(self->IsExceptionPending()); \
Sebastien Hertz1eda2262013-09-09 16:53:14 +020025 if (UNLIKELY(self->TestAllFlags())) { \
26 CheckSuspend(self); \
27 } \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020028 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, \
29 inst->GetDexPc(insns), \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020030 instrumentation); \
31 if (found_dex_pc == DexFile::kDexNoIndex) { \
32 return JValue(); /* Handled in caller. */ \
33 } else { \
34 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc); \
35 inst = inst->RelativeAt(displacement); \
36 } \
37 } while (false)
38
39#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _next_function) \
40 do { \
41 if (UNLIKELY(_is_exception_pending)) { \
42 HANDLE_PENDING_EXCEPTION(); \
43 } else { \
44 inst = inst->_next_function(); \
45 } \
46 } while (false)
47
48// Code to run before each dex instruction.
Sebastien Hertz8379b222014-02-24 17:38:15 +010049#define PREAMBLE() \
50 do { \
51 DCHECK(!inst->IsReturn()); \
52 if (UNLIKELY(notified_method_entry_event)) { \
53 notified_method_entry_event = false; \
54 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
55 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), \
56 shadow_frame.GetMethod(), dex_pc); \
57 } \
58 } while (false)
Sebastien Hertz8ece0502013-08-07 11:26:41 +020059
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010060template<bool do_access_check, bool transaction_active>
Sebastien Hertzc6714852013-09-30 16:42:32 +020061JValue ExecuteSwitchImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item,
Sebastien Hertz8379b222014-02-24 17:38:15 +010062 ShadowFrame& shadow_frame, JValue result_register) {
Jeff Haoa3faaf42013-09-03 19:07:00 -070063 bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +020064 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
65 LOG(FATAL) << "Invalid shadow frame for interpreter use";
66 return JValue();
67 }
68 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +020069
70 uint32_t dex_pc = shadow_frame.GetDexPC();
Sebastien Hertz8379b222014-02-24 17:38:15 +010071 bool notified_method_entry_event = false;
Sebastien Hertz947ff082013-09-17 14:10:13 +020072 const instrumentation::Instrumentation* const instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +020073 if (LIKELY(dex_pc == 0)) { // We are entering the method as opposed to deoptimizing..
74 if (UNLIKELY(instrumentation->HasMethodEntryListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +020075 instrumentation->MethodEnterEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +020076 shadow_frame.GetMethod(), 0);
Sebastien Hertz8379b222014-02-24 17:38:15 +010077 notified_method_entry_event = true;
Sebastien Hertz8ece0502013-08-07 11:26:41 +020078 }
79 }
80 const uint16_t* const insns = code_item->insns_;
81 const Instruction* inst = Instruction::At(insns + dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +020082 uint16_t inst_data;
Sebastien Hertz8ece0502013-08-07 11:26:41 +020083 while (true) {
84 dex_pc = inst->GetDexPc(insns);
85 shadow_frame.SetDexPC(dex_pc);
Sebastien Hertz8ece0502013-08-07 11:26:41 +020086 TraceExecution(shadow_frame, inst, dex_pc, mh);
Sebastien Hertz3b588e02013-09-11 14:33:18 +020087 inst_data = inst->Fetch16(0);
88 switch (inst->Opcode(inst_data)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +020089 case Instruction::NOP:
90 PREAMBLE();
91 inst = inst->Next_1xx();
92 break;
93 case Instruction::MOVE:
94 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +020095 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
96 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +020097 inst = inst->Next_1xx();
98 break;
99 case Instruction::MOVE_FROM16:
100 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200101 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200102 shadow_frame.GetVReg(inst->VRegB_22x()));
103 inst = inst->Next_2xx();
104 break;
105 case Instruction::MOVE_16:
106 PREAMBLE();
107 shadow_frame.SetVReg(inst->VRegA_32x(),
108 shadow_frame.GetVReg(inst->VRegB_32x()));
109 inst = inst->Next_3xx();
110 break;
111 case Instruction::MOVE_WIDE:
112 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200113 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
114 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200115 inst = inst->Next_1xx();
116 break;
117 case Instruction::MOVE_WIDE_FROM16:
118 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200119 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200120 shadow_frame.GetVRegLong(inst->VRegB_22x()));
121 inst = inst->Next_2xx();
122 break;
123 case Instruction::MOVE_WIDE_16:
124 PREAMBLE();
125 shadow_frame.SetVRegLong(inst->VRegA_32x(),
126 shadow_frame.GetVRegLong(inst->VRegB_32x()));
127 inst = inst->Next_3xx();
128 break;
129 case Instruction::MOVE_OBJECT:
130 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200131 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
132 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200133 inst = inst->Next_1xx();
134 break;
135 case Instruction::MOVE_OBJECT_FROM16:
136 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200137 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200138 shadow_frame.GetVRegReference(inst->VRegB_22x()));
139 inst = inst->Next_2xx();
140 break;
141 case Instruction::MOVE_OBJECT_16:
142 PREAMBLE();
143 shadow_frame.SetVRegReference(inst->VRegA_32x(),
144 shadow_frame.GetVRegReference(inst->VRegB_32x()));
145 inst = inst->Next_3xx();
146 break;
147 case Instruction::MOVE_RESULT:
148 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200149 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200150 inst = inst->Next_1xx();
151 break;
152 case Instruction::MOVE_RESULT_WIDE:
153 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200154 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200155 inst = inst->Next_1xx();
156 break;
157 case Instruction::MOVE_RESULT_OBJECT:
158 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200159 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200160 inst = inst->Next_1xx();
161 break;
162 case Instruction::MOVE_EXCEPTION: {
163 PREAMBLE();
Sebastien Hertz5c004902014-05-21 10:07:42 +0200164 Throwable* exception = self->GetException(nullptr);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200165 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception);
Sebastien Hertz5c004902014-05-21 10:07:42 +0200166 self->ClearException();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200167 inst = inst->Next_1xx();
168 break;
169 }
170 case Instruction::RETURN_VOID: {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200171 JValue result;
Sebastien Hertz043036f2013-09-09 18:26:48 +0200172 if (do_access_check) {
173 // If access checks are required then the dex-to-dex compiler and analysis of
174 // whether the class has final fields hasn't been performed. Conservatively
175 // perform the memory barrier now.
Hans Boehm30359612014-05-21 17:46:23 -0700176 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz043036f2013-09-09 18:26:48 +0200177 }
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200178 if (UNLIKELY(self->TestAllFlags())) {
179 CheckSuspend(self);
180 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200181 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200182 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200183 shadow_frame.GetMethod(), inst->GetDexPc(insns),
184 result);
Sebastien Hertze713d932014-05-15 10:48:53 +0200185 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
186 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
187 shadow_frame.GetMethod(), dex_pc);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200188 }
189 return result;
190 }
191 case Instruction::RETURN_VOID_BARRIER: {
Hans Boehm30359612014-05-21 17:46:23 -0700192 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200193 JValue result;
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200194 if (UNLIKELY(self->TestAllFlags())) {
195 CheckSuspend(self);
196 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200197 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200198 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200199 shadow_frame.GetMethod(), inst->GetDexPc(insns),
200 result);
Sebastien Hertze713d932014-05-15 10:48:53 +0200201 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
202 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
203 shadow_frame.GetMethod(), dex_pc);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200204 }
205 return result;
206 }
207 case Instruction::RETURN: {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200208 JValue result;
209 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200210 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200211 if (UNLIKELY(self->TestAllFlags())) {
212 CheckSuspend(self);
213 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200214 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200215 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200216 shadow_frame.GetMethod(), inst->GetDexPc(insns),
217 result);
Sebastien Hertze713d932014-05-15 10:48:53 +0200218 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
219 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
220 shadow_frame.GetMethod(), dex_pc);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200221 }
222 return result;
223 }
224 case Instruction::RETURN_WIDE: {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200225 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200226 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200227 if (UNLIKELY(self->TestAllFlags())) {
228 CheckSuspend(self);
229 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200230 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200231 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200232 shadow_frame.GetMethod(), inst->GetDexPc(insns),
233 result);
Sebastien Hertze713d932014-05-15 10:48:53 +0200234 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
235 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
236 shadow_frame.GetMethod(), dex_pc);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200237 }
238 return result;
239 }
240 case Instruction::RETURN_OBJECT: {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200241 JValue result;
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200242 if (UNLIKELY(self->TestAllFlags())) {
243 CheckSuspend(self);
244 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700245 const size_t ref_idx = inst->VRegA_11x(inst_data);
246 Object* obj_result = shadow_frame.GetVRegReference(ref_idx);
Jeff Haoa3faaf42013-09-03 19:07:00 -0700247 if (do_assignability_check && obj_result != NULL) {
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700248 StackHandleScope<1> hs(self);
249 MethodHelper mhs(hs.NewHandle(shadow_frame.GetMethod()));
250 Class* return_type = mhs.GetReturnType();
251 // Re-load since it might have moved.
252 obj_result = shadow_frame.GetVRegReference(ref_idx);
Jeff Haoa3faaf42013-09-03 19:07:00 -0700253 if (return_type == NULL) {
254 // Return the pending exception.
255 HANDLE_PENDING_EXCEPTION();
256 }
257 if (!obj_result->VerifierInstanceOf(return_type)) {
258 // This should never happen.
259 self->ThrowNewExceptionF(self->GetCurrentLocationForThrow(),
260 "Ljava/lang/VirtualMachineError;",
261 "Returning '%s' that is not instance of return type '%s'",
Mathieu Chartierf8322842014-05-16 10:59:25 -0700262 obj_result->GetClass()->GetDescriptor().c_str(),
263 return_type->GetDescriptor().c_str());
Jeff Haoa3faaf42013-09-03 19:07:00 -0700264 HANDLE_PENDING_EXCEPTION();
265 }
266 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700267 result.SetL(obj_result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200268 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200269 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200270 shadow_frame.GetMethod(), inst->GetDexPc(insns),
271 result);
Sebastien Hertze713d932014-05-15 10:48:53 +0200272 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
273 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
274 shadow_frame.GetMethod(), dex_pc);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200275 }
276 return result;
277 }
278 case Instruction::CONST_4: {
279 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200280 uint4_t dst = inst->VRegA_11n(inst_data);
281 int4_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200282 shadow_frame.SetVReg(dst, val);
283 if (val == 0) {
284 shadow_frame.SetVRegReference(dst, NULL);
285 }
286 inst = inst->Next_1xx();
287 break;
288 }
289 case Instruction::CONST_16: {
290 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200291 uint8_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200292 int16_t val = inst->VRegB_21s();
293 shadow_frame.SetVReg(dst, val);
294 if (val == 0) {
295 shadow_frame.SetVRegReference(dst, NULL);
296 }
297 inst = inst->Next_2xx();
298 break;
299 }
300 case Instruction::CONST: {
301 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200302 uint8_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200303 int32_t val = inst->VRegB_31i();
304 shadow_frame.SetVReg(dst, val);
305 if (val == 0) {
306 shadow_frame.SetVRegReference(dst, NULL);
307 }
308 inst = inst->Next_3xx();
309 break;
310 }
311 case Instruction::CONST_HIGH16: {
312 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200313 uint8_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200314 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
315 shadow_frame.SetVReg(dst, val);
316 if (val == 0) {
317 shadow_frame.SetVRegReference(dst, NULL);
318 }
319 inst = inst->Next_2xx();
320 break;
321 }
322 case Instruction::CONST_WIDE_16:
323 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200324 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200325 inst = inst->Next_2xx();
326 break;
327 case Instruction::CONST_WIDE_32:
328 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200329 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200330 inst = inst->Next_3xx();
331 break;
332 case Instruction::CONST_WIDE:
333 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200334 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200335 inst = inst->Next_51l();
336 break;
337 case Instruction::CONST_WIDE_HIGH16:
Sebastien Hertz3c5aec12014-06-04 09:41:21 +0200338 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200339 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200340 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
341 inst = inst->Next_2xx();
342 break;
343 case Instruction::CONST_STRING: {
344 PREAMBLE();
345 String* s = ResolveString(self, mh, inst->VRegB_21c());
346 if (UNLIKELY(s == NULL)) {
347 HANDLE_PENDING_EXCEPTION();
348 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200349 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200350 inst = inst->Next_2xx();
351 }
352 break;
353 }
354 case Instruction::CONST_STRING_JUMBO: {
355 PREAMBLE();
356 String* s = ResolveString(self, mh, inst->VRegB_31c());
357 if (UNLIKELY(s == NULL)) {
358 HANDLE_PENDING_EXCEPTION();
359 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200360 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200361 inst = inst->Next_3xx();
362 }
363 break;
364 }
365 case Instruction::CONST_CLASS: {
366 PREAMBLE();
367 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
368 self, false, do_access_check);
369 if (UNLIKELY(c == NULL)) {
370 HANDLE_PENDING_EXCEPTION();
371 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200372 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200373 inst = inst->Next_2xx();
374 }
375 break;
376 }
377 case Instruction::MONITOR_ENTER: {
378 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200379 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200380 if (UNLIKELY(obj == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200381 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200382 HANDLE_PENDING_EXCEPTION();
383 } else {
384 DoMonitorEnter(self, obj);
385 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
386 }
387 break;
388 }
389 case Instruction::MONITOR_EXIT: {
390 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200391 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200392 if (UNLIKELY(obj == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200393 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200394 HANDLE_PENDING_EXCEPTION();
395 } else {
396 DoMonitorExit(self, obj);
397 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
398 }
399 break;
400 }
401 case Instruction::CHECK_CAST: {
402 PREAMBLE();
403 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
404 self, false, do_access_check);
405 if (UNLIKELY(c == NULL)) {
406 HANDLE_PENDING_EXCEPTION();
407 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200408 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200409 if (UNLIKELY(obj != NULL && !obj->InstanceOf(c))) {
410 ThrowClassCastException(c, obj->GetClass());
411 HANDLE_PENDING_EXCEPTION();
412 } else {
413 inst = inst->Next_2xx();
414 }
415 }
416 break;
417 }
418 case Instruction::INSTANCE_OF: {
419 PREAMBLE();
420 Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(),
421 self, false, do_access_check);
422 if (UNLIKELY(c == NULL)) {
423 HANDLE_PENDING_EXCEPTION();
424 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200425 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
426 shadow_frame.SetVReg(inst->VRegA_22c(inst_data), (obj != NULL && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200427 inst = inst->Next_2xx();
428 }
429 break;
430 }
431 case Instruction::ARRAY_LENGTH: {
432 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200433 Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200434 if (UNLIKELY(array == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200435 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200436 HANDLE_PENDING_EXCEPTION();
437 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200438 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200439 inst = inst->Next_1xx();
440 }
441 break;
442 }
443 case Instruction::NEW_INSTANCE: {
444 PREAMBLE();
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700445 Runtime* runtime = Runtime::Current();
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800446 Object* obj = AllocObjectFromCode<do_access_check, true>(
447 inst->VRegB_21c(), shadow_frame.GetMethod(), self,
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700448 runtime->GetHeap()->GetCurrentAllocator());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200449 if (UNLIKELY(obj == NULL)) {
450 HANDLE_PENDING_EXCEPTION();
451 } else {
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700452 // Don't allow finalizable objects to be allocated during a transaction since these can't
453 // be finalized without a started runtime.
454 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Ian Rogers2fa98e22014-05-06 15:26:39 -0700455 AbortTransaction(self, "Allocating finalizable object in transaction: %s",
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700456 PrettyTypeOf(obj).c_str());
457 HANDLE_PENDING_EXCEPTION();
458 break;
459 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200460 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200461 inst = inst->Next_2xx();
462 }
463 break;
464 }
465 case Instruction::NEW_ARRAY: {
466 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200467 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800468 Object* obj = AllocArrayFromCode<do_access_check, true>(
469 inst->VRegC_22c(), shadow_frame.GetMethod(), length, self,
470 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200471 if (UNLIKELY(obj == NULL)) {
472 HANDLE_PENDING_EXCEPTION();
473 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200474 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200475 inst = inst->Next_2xx();
476 }
477 break;
478 }
479 case Instruction::FILLED_NEW_ARRAY: {
480 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100481 bool success =
482 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame, self,
483 &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200484 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
485 break;
486 }
487 case Instruction::FILLED_NEW_ARRAY_RANGE: {
488 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100489 bool success =
490 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
491 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200492 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
493 break;
494 }
495 case Instruction::FILL_ARRAY_DATA: {
496 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200497 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200498 if (UNLIKELY(obj == NULL)) {
499 ThrowNullPointerException(NULL, "null array in FILL_ARRAY_DATA");
500 HANDLE_PENDING_EXCEPTION();
501 break;
502 }
503 Array* array = obj->AsArray();
504 DCHECK(array->IsArrayInstance() && !array->IsObjectArray());
505 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
506 const Instruction::ArrayDataPayload* payload =
507 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
508 if (UNLIKELY(static_cast<int32_t>(payload->element_count) > array->GetLength())) {
509 self->ThrowNewExceptionF(shadow_frame.GetCurrentLocationForThrow(),
510 "Ljava/lang/ArrayIndexOutOfBoundsException;",
511 "failed FILL_ARRAY_DATA; length=%d, index=%d",
512 array->GetLength(), payload->element_count);
513 HANDLE_PENDING_EXCEPTION();
514 break;
515 }
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100516 if (transaction_active) {
517 RecordArrayElementsInTransaction(array, payload->element_count);
518 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200519 uint32_t size_in_bytes = payload->element_count * payload->element_width;
Ian Rogersef7d42f2014-01-06 12:55:46 -0800520 memcpy(array->GetRawData(payload->element_width, 0), payload->data, size_in_bytes);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200521 inst = inst->Next_3xx();
522 break;
523 }
524 case Instruction::THROW: {
525 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200526 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200527 if (UNLIKELY(exception == NULL)) {
528 ThrowNullPointerException(NULL, "throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700529 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
530 // This should never happen.
531 self->ThrowNewExceptionF(self->GetCurrentLocationForThrow(),
532 "Ljava/lang/VirtualMachineError;",
533 "Throwing '%s' that is not instance of Throwable",
Mathieu Chartierf8322842014-05-16 10:59:25 -0700534 exception->GetClass()->GetDescriptor().c_str());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200535 } else {
536 self->SetException(shadow_frame.GetCurrentLocationForThrow(), exception->AsThrowable());
537 }
538 HANDLE_PENDING_EXCEPTION();
539 break;
540 }
541 case Instruction::GOTO: {
542 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200543 int8_t offset = inst->VRegA_10t(inst_data);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200544 if (IsBackwardBranch(offset)) {
545 if (UNLIKELY(self->TestAllFlags())) {
546 CheckSuspend(self);
547 }
548 }
549 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200550 break;
551 }
552 case Instruction::GOTO_16: {
553 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200554 int16_t offset = inst->VRegA_20t();
555 if (IsBackwardBranch(offset)) {
556 if (UNLIKELY(self->TestAllFlags())) {
557 CheckSuspend(self);
558 }
559 }
560 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200561 break;
562 }
563 case Instruction::GOTO_32: {
564 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200565 int32_t offset = inst->VRegA_30t();
566 if (IsBackwardBranch(offset)) {
567 if (UNLIKELY(self->TestAllFlags())) {
568 CheckSuspend(self);
569 }
570 }
571 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200572 break;
573 }
574 case Instruction::PACKED_SWITCH: {
575 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200576 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200577 if (IsBackwardBranch(offset)) {
578 if (UNLIKELY(self->TestAllFlags())) {
579 CheckSuspend(self);
580 }
581 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200582 inst = inst->RelativeAt(offset);
583 break;
584 }
585 case Instruction::SPARSE_SWITCH: {
586 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200587 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200588 if (IsBackwardBranch(offset)) {
589 if (UNLIKELY(self->TestAllFlags())) {
590 CheckSuspend(self);
591 }
592 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200593 inst = inst->RelativeAt(offset);
594 break;
595 }
596 case Instruction::CMPL_FLOAT: {
597 PREAMBLE();
598 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
599 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
600 int32_t result;
601 if (val1 > val2) {
602 result = 1;
603 } else if (val1 == val2) {
604 result = 0;
605 } else {
606 result = -1;
607 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200608 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200609 inst = inst->Next_2xx();
610 break;
611 }
612 case Instruction::CMPG_FLOAT: {
613 PREAMBLE();
614 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
615 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
616 int32_t result;
617 if (val1 < val2) {
618 result = -1;
619 } else if (val1 == val2) {
620 result = 0;
621 } else {
622 result = 1;
623 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200624 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200625 inst = inst->Next_2xx();
626 break;
627 }
628 case Instruction::CMPL_DOUBLE: {
629 PREAMBLE();
630 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
631 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
632 int32_t result;
633 if (val1 > val2) {
634 result = 1;
635 } else if (val1 == val2) {
636 result = 0;
637 } else {
638 result = -1;
639 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200640 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200641 inst = inst->Next_2xx();
642 break;
643 }
644
645 case Instruction::CMPG_DOUBLE: {
646 PREAMBLE();
647 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
648 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
649 int32_t result;
650 if (val1 < val2) {
651 result = -1;
652 } else if (val1 == val2) {
653 result = 0;
654 } else {
655 result = 1;
656 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200657 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200658 inst = inst->Next_2xx();
659 break;
660 }
661 case Instruction::CMP_LONG: {
662 PREAMBLE();
663 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
664 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
665 int32_t result;
666 if (val1 > val2) {
667 result = 1;
668 } else if (val1 == val2) {
669 result = 0;
670 } else {
671 result = -1;
672 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200673 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200674 inst = inst->Next_2xx();
675 break;
676 }
677 case Instruction::IF_EQ: {
678 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200679 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) == shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200680 int16_t offset = inst->VRegC_22t();
681 if (IsBackwardBranch(offset)) {
682 if (UNLIKELY(self->TestAllFlags())) {
683 CheckSuspend(self);
684 }
685 }
686 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200687 } else {
688 inst = inst->Next_2xx();
689 }
690 break;
691 }
692 case Instruction::IF_NE: {
693 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200694 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) != shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200695 int16_t offset = inst->VRegC_22t();
696 if (IsBackwardBranch(offset)) {
697 if (UNLIKELY(self->TestAllFlags())) {
698 CheckSuspend(self);
699 }
700 }
701 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200702 } else {
703 inst = inst->Next_2xx();
704 }
705 break;
706 }
707 case Instruction::IF_LT: {
708 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200709 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) < shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200710 int16_t offset = inst->VRegC_22t();
711 if (IsBackwardBranch(offset)) {
712 if (UNLIKELY(self->TestAllFlags())) {
713 CheckSuspend(self);
714 }
715 }
716 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200717 } else {
718 inst = inst->Next_2xx();
719 }
720 break;
721 }
722 case Instruction::IF_GE: {
723 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200724 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >= shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200725 int16_t offset = inst->VRegC_22t();
726 if (IsBackwardBranch(offset)) {
727 if (UNLIKELY(self->TestAllFlags())) {
728 CheckSuspend(self);
729 }
730 }
731 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200732 } else {
733 inst = inst->Next_2xx();
734 }
735 break;
736 }
737 case Instruction::IF_GT: {
738 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200739 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) > shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200740 int16_t offset = inst->VRegC_22t();
741 if (IsBackwardBranch(offset)) {
742 if (UNLIKELY(self->TestAllFlags())) {
743 CheckSuspend(self);
744 }
745 }
746 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200747 } else {
748 inst = inst->Next_2xx();
749 }
750 break;
751 }
752 case Instruction::IF_LE: {
753 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200754 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <= shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200755 int16_t offset = inst->VRegC_22t();
756 if (IsBackwardBranch(offset)) {
757 if (UNLIKELY(self->TestAllFlags())) {
758 CheckSuspend(self);
759 }
760 }
761 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200762 } else {
763 inst = inst->Next_2xx();
764 }
765 break;
766 }
767 case Instruction::IF_EQZ: {
768 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200769 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200770 int16_t offset = inst->VRegB_21t();
771 if (IsBackwardBranch(offset)) {
772 if (UNLIKELY(self->TestAllFlags())) {
773 CheckSuspend(self);
774 }
775 }
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_NEZ: {
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)) {
787 if (UNLIKELY(self->TestAllFlags())) {
788 CheckSuspend(self);
789 }
790 }
791 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200792 } else {
793 inst = inst->Next_2xx();
794 }
795 break;
796 }
797 case Instruction::IF_LTZ: {
798 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200799 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200800 int16_t offset = inst->VRegB_21t();
801 if (IsBackwardBranch(offset)) {
802 if (UNLIKELY(self->TestAllFlags())) {
803 CheckSuspend(self);
804 }
805 }
806 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200807 } else {
808 inst = inst->Next_2xx();
809 }
810 break;
811 }
812 case Instruction::IF_GEZ: {
813 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200814 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200815 int16_t offset = inst->VRegB_21t();
816 if (IsBackwardBranch(offset)) {
817 if (UNLIKELY(self->TestAllFlags())) {
818 CheckSuspend(self);
819 }
820 }
821 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200822 } else {
823 inst = inst->Next_2xx();
824 }
825 break;
826 }
827 case Instruction::IF_GTZ: {
828 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200829 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200830 int16_t offset = inst->VRegB_21t();
831 if (IsBackwardBranch(offset)) {
832 if (UNLIKELY(self->TestAllFlags())) {
833 CheckSuspend(self);
834 }
835 }
836 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200837 } else {
838 inst = inst->Next_2xx();
839 }
840 break;
841 }
842 case Instruction::IF_LEZ: {
843 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200844 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200845 int16_t offset = inst->VRegB_21t();
846 if (IsBackwardBranch(offset)) {
847 if (UNLIKELY(self->TestAllFlags())) {
848 CheckSuspend(self);
849 }
850 }
851 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200852 } else {
853 inst = inst->Next_2xx();
854 }
855 break;
856 }
857 case Instruction::AGET_BOOLEAN: {
858 PREAMBLE();
859 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
860 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200861 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200862 HANDLE_PENDING_EXCEPTION();
863 break;
864 }
865 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
866 BooleanArray* array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700867 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100868 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200869 inst = inst->Next_2xx();
870 } else {
871 HANDLE_PENDING_EXCEPTION();
872 }
873 break;
874 }
875 case Instruction::AGET_BYTE: {
876 PREAMBLE();
877 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
878 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200879 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200880 HANDLE_PENDING_EXCEPTION();
881 break;
882 }
883 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
884 ByteArray* array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700885 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100886 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200887 inst = inst->Next_2xx();
888 } else {
889 HANDLE_PENDING_EXCEPTION();
890 }
891 break;
892 }
893 case Instruction::AGET_CHAR: {
894 PREAMBLE();
895 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
896 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200897 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200898 HANDLE_PENDING_EXCEPTION();
899 break;
900 }
901 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
902 CharArray* array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700903 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100904 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200905 inst = inst->Next_2xx();
906 } else {
907 HANDLE_PENDING_EXCEPTION();
908 }
909 break;
910 }
911 case Instruction::AGET_SHORT: {
912 PREAMBLE();
913 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
914 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200915 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200916 HANDLE_PENDING_EXCEPTION();
917 break;
918 }
919 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
920 ShortArray* array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700921 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100922 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200923 inst = inst->Next_2xx();
924 } else {
925 HANDLE_PENDING_EXCEPTION();
926 }
927 break;
928 }
929 case Instruction::AGET: {
930 PREAMBLE();
931 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
932 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200933 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200934 HANDLE_PENDING_EXCEPTION();
935 break;
936 }
937 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
938 IntArray* array = a->AsIntArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700939 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100940 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200941 inst = inst->Next_2xx();
942 } else {
943 HANDLE_PENDING_EXCEPTION();
944 }
945 break;
946 }
947 case Instruction::AGET_WIDE: {
948 PREAMBLE();
949 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
950 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200951 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200952 HANDLE_PENDING_EXCEPTION();
953 break;
954 }
955 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
956 LongArray* array = a->AsLongArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700957 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100958 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200959 inst = inst->Next_2xx();
960 } else {
961 HANDLE_PENDING_EXCEPTION();
962 }
963 break;
964 }
965 case Instruction::AGET_OBJECT: {
966 PREAMBLE();
967 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
968 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200969 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200970 HANDLE_PENDING_EXCEPTION();
971 break;
972 }
973 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
974 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700975 if (array->CheckIsValidIndex(index)) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200976 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200977 inst = inst->Next_2xx();
978 } else {
979 HANDLE_PENDING_EXCEPTION();
980 }
981 break;
982 }
983 case Instruction::APUT_BOOLEAN: {
984 PREAMBLE();
985 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
986 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200987 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200988 HANDLE_PENDING_EXCEPTION();
989 break;
990 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200991 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200992 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
993 BooleanArray* array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700994 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100995 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200996 inst = inst->Next_2xx();
997 } else {
998 HANDLE_PENDING_EXCEPTION();
999 }
1000 break;
1001 }
1002 case Instruction::APUT_BYTE: {
1003 PREAMBLE();
1004 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1005 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001006 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001007 HANDLE_PENDING_EXCEPTION();
1008 break;
1009 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001010 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001011 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1012 ByteArray* array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001013 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001014 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001015 inst = inst->Next_2xx();
1016 } else {
1017 HANDLE_PENDING_EXCEPTION();
1018 }
1019 break;
1020 }
1021 case Instruction::APUT_CHAR: {
1022 PREAMBLE();
1023 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1024 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001025 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001026 HANDLE_PENDING_EXCEPTION();
1027 break;
1028 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001029 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001030 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1031 CharArray* array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001032 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001033 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001034 inst = inst->Next_2xx();
1035 } else {
1036 HANDLE_PENDING_EXCEPTION();
1037 }
1038 break;
1039 }
1040 case Instruction::APUT_SHORT: {
1041 PREAMBLE();
1042 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1043 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001044 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001045 HANDLE_PENDING_EXCEPTION();
1046 break;
1047 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001048 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001049 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1050 ShortArray* array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001051 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001052 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001053 inst = inst->Next_2xx();
1054 } else {
1055 HANDLE_PENDING_EXCEPTION();
1056 }
1057 break;
1058 }
1059 case Instruction::APUT: {
1060 PREAMBLE();
1061 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1062 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001063 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001064 HANDLE_PENDING_EXCEPTION();
1065 break;
1066 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001067 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001068 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1069 IntArray* array = a->AsIntArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001070 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001071 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001072 inst = inst->Next_2xx();
1073 } else {
1074 HANDLE_PENDING_EXCEPTION();
1075 }
1076 break;
1077 }
1078 case Instruction::APUT_WIDE: {
1079 PREAMBLE();
1080 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1081 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001082 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001083 HANDLE_PENDING_EXCEPTION();
1084 break;
1085 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001086 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001087 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1088 LongArray* array = a->AsLongArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001089 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001090 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001091 inst = inst->Next_2xx();
1092 } else {
1093 HANDLE_PENDING_EXCEPTION();
1094 }
1095 break;
1096 }
1097 case Instruction::APUT_OBJECT: {
1098 PREAMBLE();
1099 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1100 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001101 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001102 HANDLE_PENDING_EXCEPTION();
1103 break;
1104 }
1105 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001106 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001107 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001108 if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001109 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001110 inst = inst->Next_2xx();
1111 } else {
1112 HANDLE_PENDING_EXCEPTION();
1113 }
1114 break;
1115 }
1116 case Instruction::IGET_BOOLEAN: {
1117 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001118 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001119 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1120 break;
1121 }
1122 case Instruction::IGET_BYTE: {
1123 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001124 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001125 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1126 break;
1127 }
1128 case Instruction::IGET_CHAR: {
1129 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001130 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001131 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1132 break;
1133 }
1134 case Instruction::IGET_SHORT: {
1135 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001136 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001137 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1138 break;
1139 }
1140 case Instruction::IGET: {
1141 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001142 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001143 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1144 break;
1145 }
1146 case Instruction::IGET_WIDE: {
1147 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001148 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001149 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1150 break;
1151 }
1152 case Instruction::IGET_OBJECT: {
1153 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001154 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001155 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1156 break;
1157 }
1158 case Instruction::IGET_QUICK: {
1159 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001160 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001161 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1162 break;
1163 }
1164 case Instruction::IGET_WIDE_QUICK: {
1165 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001166 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001167 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1168 break;
1169 }
1170 case Instruction::IGET_OBJECT_QUICK: {
1171 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001172 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001173 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1174 break;
1175 }
1176 case Instruction::SGET_BOOLEAN: {
1177 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001178 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001179 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1180 break;
1181 }
1182 case Instruction::SGET_BYTE: {
1183 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001184 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001185 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1186 break;
1187 }
1188 case Instruction::SGET_CHAR: {
1189 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001190 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001191 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1192 break;
1193 }
1194 case Instruction::SGET_SHORT: {
1195 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001196 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001197 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1198 break;
1199 }
1200 case Instruction::SGET: {
1201 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001202 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001203 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1204 break;
1205 }
1206 case Instruction::SGET_WIDE: {
1207 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001208 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001209 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1210 break;
1211 }
1212 case Instruction::SGET_OBJECT: {
1213 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001214 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001215 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1216 break;
1217 }
1218 case Instruction::IPUT_BOOLEAN: {
1219 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001220 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001221 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1222 break;
1223 }
1224 case Instruction::IPUT_BYTE: {
1225 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001226 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001227 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1228 break;
1229 }
1230 case Instruction::IPUT_CHAR: {
1231 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001232 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001233 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1234 break;
1235 }
1236 case Instruction::IPUT_SHORT: {
1237 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001238 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001239 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1240 break;
1241 }
1242 case Instruction::IPUT: {
1243 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001244 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001245 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1246 break;
1247 }
1248 case Instruction::IPUT_WIDE: {
1249 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001250 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001251 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1252 break;
1253 }
1254 case Instruction::IPUT_OBJECT: {
1255 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001256 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001257 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1258 break;
1259 }
1260 case Instruction::IPUT_QUICK: {
1261 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001262 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001263 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1264 break;
1265 }
1266 case Instruction::IPUT_WIDE_QUICK: {
1267 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001268 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001269 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1270 break;
1271 }
1272 case Instruction::IPUT_OBJECT_QUICK: {
1273 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001274 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001275 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1276 break;
1277 }
1278 case Instruction::SPUT_BOOLEAN: {
1279 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001280 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001281 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1282 break;
1283 }
1284 case Instruction::SPUT_BYTE: {
1285 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001286 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001287 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1288 break;
1289 }
1290 case Instruction::SPUT_CHAR: {
1291 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001292 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001293 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1294 break;
1295 }
1296 case Instruction::SPUT_SHORT: {
1297 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001298 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001299 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1300 break;
1301 }
1302 case Instruction::SPUT: {
1303 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001304 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001305 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1306 break;
1307 }
1308 case Instruction::SPUT_WIDE: {
1309 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001310 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001311 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1312 break;
1313 }
1314 case Instruction::SPUT_OBJECT: {
1315 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001316 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001317 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1318 break;
1319 }
1320 case Instruction::INVOKE_VIRTUAL: {
1321 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001322 bool success = DoInvoke<kVirtual, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001323 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1324 break;
1325 }
1326 case Instruction::INVOKE_VIRTUAL_RANGE: {
1327 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001328 bool success = DoInvoke<kVirtual, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001329 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1330 break;
1331 }
1332 case Instruction::INVOKE_SUPER: {
1333 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001334 bool success = DoInvoke<kSuper, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001335 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1336 break;
1337 }
1338 case Instruction::INVOKE_SUPER_RANGE: {
1339 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001340 bool success = DoInvoke<kSuper, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001341 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1342 break;
1343 }
1344 case Instruction::INVOKE_DIRECT: {
1345 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001346 bool success = DoInvoke<kDirect, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001347 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1348 break;
1349 }
1350 case Instruction::INVOKE_DIRECT_RANGE: {
1351 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001352 bool success = DoInvoke<kDirect, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001353 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1354 break;
1355 }
1356 case Instruction::INVOKE_INTERFACE: {
1357 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001358 bool success = DoInvoke<kInterface, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001359 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1360 break;
1361 }
1362 case Instruction::INVOKE_INTERFACE_RANGE: {
1363 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001364 bool success = DoInvoke<kInterface, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001365 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1366 break;
1367 }
1368 case Instruction::INVOKE_STATIC: {
1369 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001370 bool success = DoInvoke<kStatic, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001371 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1372 break;
1373 }
1374 case Instruction::INVOKE_STATIC_RANGE: {
1375 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001376 bool success = DoInvoke<kStatic, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001377 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1378 break;
1379 }
1380 case Instruction::INVOKE_VIRTUAL_QUICK: {
1381 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001382 bool success = DoInvokeVirtualQuick<false>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001383 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1384 break;
1385 }
1386 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
1387 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001388 bool success = DoInvokeVirtualQuick<true>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001389 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1390 break;
1391 }
1392 case Instruction::NEG_INT:
1393 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001394 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001395 inst = inst->Next_1xx();
1396 break;
1397 case Instruction::NOT_INT:
1398 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001399 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001400 inst = inst->Next_1xx();
1401 break;
1402 case Instruction::NEG_LONG:
1403 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001404 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001405 inst = inst->Next_1xx();
1406 break;
1407 case Instruction::NOT_LONG:
1408 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001409 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001410 inst = inst->Next_1xx();
1411 break;
1412 case Instruction::NEG_FLOAT:
1413 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001414 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001415 inst = inst->Next_1xx();
1416 break;
1417 case Instruction::NEG_DOUBLE:
1418 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001419 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001420 inst = inst->Next_1xx();
1421 break;
1422 case Instruction::INT_TO_LONG:
1423 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001424 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
1425 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001426 inst = inst->Next_1xx();
1427 break;
1428 case Instruction::INT_TO_FLOAT:
1429 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001430 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1431 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001432 inst = inst->Next_1xx();
1433 break;
1434 case Instruction::INT_TO_DOUBLE:
1435 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001436 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1437 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001438 inst = inst->Next_1xx();
1439 break;
1440 case Instruction::LONG_TO_INT:
1441 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001442 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1443 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001444 inst = inst->Next_1xx();
1445 break;
1446 case Instruction::LONG_TO_FLOAT:
1447 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001448 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1449 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001450 inst = inst->Next_1xx();
1451 break;
1452 case Instruction::LONG_TO_DOUBLE:
1453 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001454 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1455 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001456 inst = inst->Next_1xx();
1457 break;
1458 case Instruction::FLOAT_TO_INT: {
1459 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001460 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001461 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001462 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001463 inst = inst->Next_1xx();
1464 break;
1465 }
1466 case Instruction::FLOAT_TO_LONG: {
1467 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001468 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001469 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001470 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001471 inst = inst->Next_1xx();
1472 break;
1473 }
1474 case Instruction::FLOAT_TO_DOUBLE:
1475 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001476 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1477 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001478 inst = inst->Next_1xx();
1479 break;
1480 case Instruction::DOUBLE_TO_INT: {
1481 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001482 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001483 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001484 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001485 inst = inst->Next_1xx();
1486 break;
1487 }
1488 case Instruction::DOUBLE_TO_LONG: {
1489 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001490 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001491 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001492 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001493 inst = inst->Next_1xx();
1494 break;
1495 }
1496 case Instruction::DOUBLE_TO_FLOAT:
1497 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001498 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1499 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001500 inst = inst->Next_1xx();
1501 break;
1502 case Instruction::INT_TO_BYTE:
1503 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001504 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1505 static_cast<int8_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001506 inst = inst->Next_1xx();
1507 break;
1508 case Instruction::INT_TO_CHAR:
1509 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001510 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1511 static_cast<uint16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001512 inst = inst->Next_1xx();
1513 break;
1514 case Instruction::INT_TO_SHORT:
1515 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001516 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1517 static_cast<int16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001518 inst = inst->Next_1xx();
1519 break;
1520 case Instruction::ADD_INT:
1521 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001522 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001523 shadow_frame.GetVReg(inst->VRegB_23x()) +
1524 shadow_frame.GetVReg(inst->VRegC_23x()));
1525 inst = inst->Next_2xx();
1526 break;
1527 case Instruction::SUB_INT:
1528 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001529 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001530 shadow_frame.GetVReg(inst->VRegB_23x()) -
1531 shadow_frame.GetVReg(inst->VRegC_23x()));
1532 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),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001537 shadow_frame.GetVReg(inst->VRegB_23x()) *
1538 shadow_frame.GetVReg(inst->VRegC_23x()));
1539 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),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001602 shadow_frame.GetVRegLong(inst->VRegB_23x()) +
1603 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1604 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),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001609 shadow_frame.GetVRegLong(inst->VRegB_23x()) -
1610 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1611 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),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001616 shadow_frame.GetVRegLong(inst->VRegB_23x()) *
1617 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1618 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()),
1624 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1625 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);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001749 shadow_frame.SetVReg(vregA,
1750 shadow_frame.GetVReg(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001751 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001752 inst = inst->Next_1xx();
1753 break;
1754 }
1755 case Instruction::SUB_INT_2ADDR: {
1756 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001757 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001758 shadow_frame.SetVReg(vregA,
1759 shadow_frame.GetVReg(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001760 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001761 inst = inst->Next_1xx();
1762 break;
1763 }
1764 case Instruction::MUL_INT_2ADDR: {
1765 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001766 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001767 shadow_frame.SetVReg(vregA,
1768 shadow_frame.GetVReg(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001769 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001770 inst = inst->Next_1xx();
1771 break;
1772 }
1773 case Instruction::DIV_INT_2ADDR: {
1774 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001775 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001776 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001777 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001778 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1779 break;
1780 }
1781 case Instruction::REM_INT_2ADDR: {
1782 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001783 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001784 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001785 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001786 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1787 break;
1788 }
1789 case Instruction::SHL_INT_2ADDR: {
1790 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001791 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001792 shadow_frame.SetVReg(vregA,
1793 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001794 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001795 inst = inst->Next_1xx();
1796 break;
1797 }
1798 case Instruction::SHR_INT_2ADDR: {
1799 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001800 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001801 shadow_frame.SetVReg(vregA,
1802 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001803 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001804 inst = inst->Next_1xx();
1805 break;
1806 }
1807 case Instruction::USHR_INT_2ADDR: {
1808 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001809 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001810 shadow_frame.SetVReg(vregA,
1811 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001812 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001813 inst = inst->Next_1xx();
1814 break;
1815 }
1816 case Instruction::AND_INT_2ADDR: {
1817 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001818 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001819 shadow_frame.SetVReg(vregA,
1820 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001821 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001822 inst = inst->Next_1xx();
1823 break;
1824 }
1825 case Instruction::OR_INT_2ADDR: {
1826 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001827 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001828 shadow_frame.SetVReg(vregA,
1829 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001830 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001831 inst = inst->Next_1xx();
1832 break;
1833 }
1834 case Instruction::XOR_INT_2ADDR: {
1835 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001836 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001837 shadow_frame.SetVReg(vregA,
1838 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001839 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001840 inst = inst->Next_1xx();
1841 break;
1842 }
1843 case Instruction::ADD_LONG_2ADDR: {
1844 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001845 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001846 shadow_frame.SetVRegLong(vregA,
1847 shadow_frame.GetVRegLong(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001848 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001849 inst = inst->Next_1xx();
1850 break;
1851 }
1852 case Instruction::SUB_LONG_2ADDR: {
1853 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001854 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001855 shadow_frame.SetVRegLong(vregA,
1856 shadow_frame.GetVRegLong(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001857 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001858 inst = inst->Next_1xx();
1859 break;
1860 }
1861 case Instruction::MUL_LONG_2ADDR: {
1862 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001863 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001864 shadow_frame.SetVRegLong(vregA,
1865 shadow_frame.GetVRegLong(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001866 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001867 inst = inst->Next_1xx();
1868 break;
1869 }
1870 case Instruction::DIV_LONG_2ADDR: {
1871 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001872 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001873 DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001874 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001875 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
1876 break;
1877 }
1878 case Instruction::REM_LONG_2ADDR: {
1879 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001880 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001881 DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001882 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001883 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
1884 break;
1885 }
1886 case Instruction::AND_LONG_2ADDR: {
1887 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001888 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001889 shadow_frame.SetVRegLong(vregA,
1890 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001891 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001892 inst = inst->Next_1xx();
1893 break;
1894 }
1895 case Instruction::OR_LONG_2ADDR: {
1896 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001897 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001898 shadow_frame.SetVRegLong(vregA,
1899 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001900 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001901 inst = inst->Next_1xx();
1902 break;
1903 }
1904 case Instruction::XOR_LONG_2ADDR: {
1905 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001906 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001907 shadow_frame.SetVRegLong(vregA,
1908 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001909 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001910 inst = inst->Next_1xx();
1911 break;
1912 }
1913 case Instruction::SHL_LONG_2ADDR: {
1914 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001915 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001916 shadow_frame.SetVRegLong(vregA,
1917 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001918 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001919 inst = inst->Next_1xx();
1920 break;
1921 }
1922 case Instruction::SHR_LONG_2ADDR: {
1923 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001924 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001925 shadow_frame.SetVRegLong(vregA,
1926 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001927 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001928 inst = inst->Next_1xx();
1929 break;
1930 }
1931 case Instruction::USHR_LONG_2ADDR: {
1932 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001933 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001934 shadow_frame.SetVRegLong(vregA,
1935 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001936 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001937 inst = inst->Next_1xx();
1938 break;
1939 }
1940 case Instruction::ADD_FLOAT_2ADDR: {
1941 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001942 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001943 shadow_frame.SetVRegFloat(vregA,
1944 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001945 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001946 inst = inst->Next_1xx();
1947 break;
1948 }
1949 case Instruction::SUB_FLOAT_2ADDR: {
1950 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001951 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001952 shadow_frame.SetVRegFloat(vregA,
1953 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001954 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001955 inst = inst->Next_1xx();
1956 break;
1957 }
1958 case Instruction::MUL_FLOAT_2ADDR: {
1959 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001960 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001961 shadow_frame.SetVRegFloat(vregA,
1962 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001963 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001964 inst = inst->Next_1xx();
1965 break;
1966 }
1967 case Instruction::DIV_FLOAT_2ADDR: {
1968 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001969 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001970 shadow_frame.SetVRegFloat(vregA,
1971 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001972 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001973 inst = inst->Next_1xx();
1974 break;
1975 }
1976 case Instruction::REM_FLOAT_2ADDR: {
1977 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001978 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001979 shadow_frame.SetVRegFloat(vregA,
1980 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001981 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001982 inst = inst->Next_1xx();
1983 break;
1984 }
1985 case Instruction::ADD_DOUBLE_2ADDR: {
1986 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001987 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001988 shadow_frame.SetVRegDouble(vregA,
1989 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001990 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001991 inst = inst->Next_1xx();
1992 break;
1993 }
1994 case Instruction::SUB_DOUBLE_2ADDR: {
1995 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001996 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001997 shadow_frame.SetVRegDouble(vregA,
1998 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001999 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002000 inst = inst->Next_1xx();
2001 break;
2002 }
2003 case Instruction::MUL_DOUBLE_2ADDR: {
2004 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002005 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002006 shadow_frame.SetVRegDouble(vregA,
2007 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002008 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002009 inst = inst->Next_1xx();
2010 break;
2011 }
2012 case Instruction::DIV_DOUBLE_2ADDR: {
2013 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002014 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002015 shadow_frame.SetVRegDouble(vregA,
2016 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002017 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002018 inst = inst->Next_1xx();
2019 break;
2020 }
2021 case Instruction::REM_DOUBLE_2ADDR: {
2022 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002023 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002024 shadow_frame.SetVRegDouble(vregA,
2025 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002026 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002027 inst = inst->Next_1xx();
2028 break;
2029 }
2030 case Instruction::ADD_INT_LIT16:
2031 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002032 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2033 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) +
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002034 inst->VRegC_22s());
2035 inst = inst->Next_2xx();
2036 break;
2037 case Instruction::RSUB_INT:
2038 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002039 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002040 inst->VRegC_22s() -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002041 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002042 inst = inst->Next_2xx();
2043 break;
2044 case Instruction::MUL_INT_LIT16:
2045 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002046 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2047 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) *
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002048 inst->VRegC_22s());
2049 inst = inst->Next_2xx();
2050 break;
2051 case Instruction::DIV_INT_LIT16: {
2052 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002053 bool success = DoIntDivide(shadow_frame, inst->VRegA_22s(inst_data),
2054 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)), inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002055 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2056 break;
2057 }
2058 case Instruction::REM_INT_LIT16: {
2059 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002060 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22s(inst_data),
2061 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)), inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002062 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2063 break;
2064 }
2065 case Instruction::AND_INT_LIT16:
2066 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002067 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2068 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002069 inst->VRegC_22s());
2070 inst = inst->Next_2xx();
2071 break;
2072 case Instruction::OR_INT_LIT16:
2073 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002074 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2075 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002076 inst->VRegC_22s());
2077 inst = inst->Next_2xx();
2078 break;
2079 case Instruction::XOR_INT_LIT16:
2080 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002081 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2082 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002083 inst->VRegC_22s());
2084 inst = inst->Next_2xx();
2085 break;
2086 case Instruction::ADD_INT_LIT8:
2087 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002088 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002089 shadow_frame.GetVReg(inst->VRegB_22b()) +
2090 inst->VRegC_22b());
2091 inst = inst->Next_2xx();
2092 break;
2093 case Instruction::RSUB_INT_LIT8:
2094 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002095 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002096 inst->VRegC_22b() -
2097 shadow_frame.GetVReg(inst->VRegB_22b()));
2098 inst = inst->Next_2xx();
2099 break;
2100 case Instruction::MUL_INT_LIT8:
2101 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002102 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002103 shadow_frame.GetVReg(inst->VRegB_22b()) *
2104 inst->VRegC_22b());
2105 inst = inst->Next_2xx();
2106 break;
2107 case Instruction::DIV_INT_LIT8: {
2108 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002109 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002110 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2111 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2112 break;
2113 }
2114 case Instruction::REM_INT_LIT8: {
2115 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002116 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002117 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2118 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2119 break;
2120 }
2121 case Instruction::AND_INT_LIT8:
2122 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002123 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002124 shadow_frame.GetVReg(inst->VRegB_22b()) &
2125 inst->VRegC_22b());
2126 inst = inst->Next_2xx();
2127 break;
2128 case Instruction::OR_INT_LIT8:
2129 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002130 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002131 shadow_frame.GetVReg(inst->VRegB_22b()) |
2132 inst->VRegC_22b());
2133 inst = inst->Next_2xx();
2134 break;
2135 case Instruction::XOR_INT_LIT8:
2136 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002137 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002138 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2139 inst->VRegC_22b());
2140 inst = inst->Next_2xx();
2141 break;
2142 case Instruction::SHL_INT_LIT8:
2143 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002144 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002145 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2146 (inst->VRegC_22b() & 0x1f));
2147 inst = inst->Next_2xx();
2148 break;
2149 case Instruction::SHR_INT_LIT8:
2150 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002151 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002152 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2153 (inst->VRegC_22b() & 0x1f));
2154 inst = inst->Next_2xx();
2155 break;
2156 case Instruction::USHR_INT_LIT8:
2157 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002158 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002159 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2160 (inst->VRegC_22b() & 0x1f));
2161 inst = inst->Next_2xx();
2162 break;
2163 case Instruction::UNUSED_3E ... Instruction::UNUSED_43:
2164 case Instruction::UNUSED_EB ... Instruction::UNUSED_FF:
2165 case Instruction::UNUSED_79:
2166 case Instruction::UNUSED_7A:
2167 UnexpectedOpcode(inst, mh);
2168 }
2169 }
2170} // NOLINT(readability/fn_size)
2171
2172// Explicit definitions of ExecuteSwitchImpl.
Sebastien Hertzc6714852013-09-30 16:42:32 +02002173template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002174JValue ExecuteSwitchImpl<true, false>(Thread* self, MethodHelper& mh,
2175 const DexFile::CodeItem* code_item,
2176 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertzc6714852013-09-30 16:42:32 +02002177template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002178JValue ExecuteSwitchImpl<false, false>(Thread* self, MethodHelper& mh,
2179 const DexFile::CodeItem* code_item,
2180 ShadowFrame& shadow_frame, JValue result_register);
2181template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
2182JValue ExecuteSwitchImpl<true, true>(Thread* self, MethodHelper& mh,
2183 const DexFile::CodeItem* code_item,
2184 ShadowFrame& shadow_frame, JValue result_register);
2185template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
2186JValue ExecuteSwitchImpl<false, true>(Thread* self, MethodHelper& mh,
2187 const DexFile::CodeItem* code_item,
2188 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002189
2190} // namespace interpreter
2191} // namespace art