blob: c6356485a9eae5528c1da3ba49b74e78674b7b43 [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 {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200452 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700453 // Don't allow finalizable objects to be allocated during a transaction since these can't
454 // be finalized without a started runtime.
455 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Ian Rogers2fa98e22014-05-06 15:26:39 -0700456 AbortTransaction(self, "Allocating finalizable object in transaction: %s",
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700457 PrettyTypeOf(obj).c_str());
458 HANDLE_PENDING_EXCEPTION();
459 break;
460 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200461 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200462 inst = inst->Next_2xx();
463 }
464 break;
465 }
466 case Instruction::NEW_ARRAY: {
467 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200468 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800469 Object* obj = AllocArrayFromCode<do_access_check, true>(
470 inst->VRegC_22c(), shadow_frame.GetMethod(), length, self,
471 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200472 if (UNLIKELY(obj == NULL)) {
473 HANDLE_PENDING_EXCEPTION();
474 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200475 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200476 inst = inst->Next_2xx();
477 }
478 break;
479 }
480 case Instruction::FILLED_NEW_ARRAY: {
481 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100482 bool success =
483 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame, self,
484 &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200485 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
486 break;
487 }
488 case Instruction::FILLED_NEW_ARRAY_RANGE: {
489 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100490 bool success =
491 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
492 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200493 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
494 break;
495 }
496 case Instruction::FILL_ARRAY_DATA: {
497 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200498 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200499 if (UNLIKELY(obj == NULL)) {
500 ThrowNullPointerException(NULL, "null array in FILL_ARRAY_DATA");
501 HANDLE_PENDING_EXCEPTION();
502 break;
503 }
504 Array* array = obj->AsArray();
505 DCHECK(array->IsArrayInstance() && !array->IsObjectArray());
506 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
507 const Instruction::ArrayDataPayload* payload =
508 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
509 if (UNLIKELY(static_cast<int32_t>(payload->element_count) > array->GetLength())) {
510 self->ThrowNewExceptionF(shadow_frame.GetCurrentLocationForThrow(),
511 "Ljava/lang/ArrayIndexOutOfBoundsException;",
512 "failed FILL_ARRAY_DATA; length=%d, index=%d",
513 array->GetLength(), payload->element_count);
514 HANDLE_PENDING_EXCEPTION();
515 break;
516 }
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100517 if (transaction_active) {
518 RecordArrayElementsInTransaction(array, payload->element_count);
519 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200520 uint32_t size_in_bytes = payload->element_count * payload->element_width;
Ian Rogersef7d42f2014-01-06 12:55:46 -0800521 memcpy(array->GetRawData(payload->element_width, 0), payload->data, size_in_bytes);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200522 inst = inst->Next_3xx();
523 break;
524 }
525 case Instruction::THROW: {
526 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200527 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200528 if (UNLIKELY(exception == NULL)) {
529 ThrowNullPointerException(NULL, "throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700530 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
531 // This should never happen.
532 self->ThrowNewExceptionF(self->GetCurrentLocationForThrow(),
533 "Ljava/lang/VirtualMachineError;",
534 "Throwing '%s' that is not instance of Throwable",
Mathieu Chartierf8322842014-05-16 10:59:25 -0700535 exception->GetClass()->GetDescriptor().c_str());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200536 } else {
537 self->SetException(shadow_frame.GetCurrentLocationForThrow(), exception->AsThrowable());
538 }
539 HANDLE_PENDING_EXCEPTION();
540 break;
541 }
542 case Instruction::GOTO: {
543 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200544 int8_t offset = inst->VRegA_10t(inst_data);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200545 if (IsBackwardBranch(offset)) {
546 if (UNLIKELY(self->TestAllFlags())) {
547 CheckSuspend(self);
548 }
549 }
550 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200551 break;
552 }
553 case Instruction::GOTO_16: {
554 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200555 int16_t offset = inst->VRegA_20t();
556 if (IsBackwardBranch(offset)) {
557 if (UNLIKELY(self->TestAllFlags())) {
558 CheckSuspend(self);
559 }
560 }
561 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200562 break;
563 }
564 case Instruction::GOTO_32: {
565 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200566 int32_t offset = inst->VRegA_30t();
567 if (IsBackwardBranch(offset)) {
568 if (UNLIKELY(self->TestAllFlags())) {
569 CheckSuspend(self);
570 }
571 }
572 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200573 break;
574 }
575 case Instruction::PACKED_SWITCH: {
576 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200577 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200578 if (IsBackwardBranch(offset)) {
579 if (UNLIKELY(self->TestAllFlags())) {
580 CheckSuspend(self);
581 }
582 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200583 inst = inst->RelativeAt(offset);
584 break;
585 }
586 case Instruction::SPARSE_SWITCH: {
587 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200588 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200589 if (IsBackwardBranch(offset)) {
590 if (UNLIKELY(self->TestAllFlags())) {
591 CheckSuspend(self);
592 }
593 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200594 inst = inst->RelativeAt(offset);
595 break;
596 }
597 case Instruction::CMPL_FLOAT: {
598 PREAMBLE();
599 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
600 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
601 int32_t result;
602 if (val1 > val2) {
603 result = 1;
604 } else if (val1 == val2) {
605 result = 0;
606 } else {
607 result = -1;
608 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200609 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200610 inst = inst->Next_2xx();
611 break;
612 }
613 case Instruction::CMPG_FLOAT: {
614 PREAMBLE();
615 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
616 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
617 int32_t result;
618 if (val1 < val2) {
619 result = -1;
620 } else if (val1 == val2) {
621 result = 0;
622 } else {
623 result = 1;
624 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200625 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200626 inst = inst->Next_2xx();
627 break;
628 }
629 case Instruction::CMPL_DOUBLE: {
630 PREAMBLE();
631 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
632 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
633 int32_t result;
634 if (val1 > val2) {
635 result = 1;
636 } else if (val1 == val2) {
637 result = 0;
638 } else {
639 result = -1;
640 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200641 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200642 inst = inst->Next_2xx();
643 break;
644 }
645
646 case Instruction::CMPG_DOUBLE: {
647 PREAMBLE();
648 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
649 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
650 int32_t result;
651 if (val1 < val2) {
652 result = -1;
653 } else if (val1 == val2) {
654 result = 0;
655 } else {
656 result = 1;
657 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200658 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200659 inst = inst->Next_2xx();
660 break;
661 }
662 case Instruction::CMP_LONG: {
663 PREAMBLE();
664 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
665 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
666 int32_t result;
667 if (val1 > val2) {
668 result = 1;
669 } else if (val1 == val2) {
670 result = 0;
671 } else {
672 result = -1;
673 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200674 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200675 inst = inst->Next_2xx();
676 break;
677 }
678 case Instruction::IF_EQ: {
679 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200680 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) == shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200681 int16_t offset = inst->VRegC_22t();
682 if (IsBackwardBranch(offset)) {
683 if (UNLIKELY(self->TestAllFlags())) {
684 CheckSuspend(self);
685 }
686 }
687 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200688 } else {
689 inst = inst->Next_2xx();
690 }
691 break;
692 }
693 case Instruction::IF_NE: {
694 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200695 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) != shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200696 int16_t offset = inst->VRegC_22t();
697 if (IsBackwardBranch(offset)) {
698 if (UNLIKELY(self->TestAllFlags())) {
699 CheckSuspend(self);
700 }
701 }
702 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200703 } else {
704 inst = inst->Next_2xx();
705 }
706 break;
707 }
708 case Instruction::IF_LT: {
709 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200710 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) < shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200711 int16_t offset = inst->VRegC_22t();
712 if (IsBackwardBranch(offset)) {
713 if (UNLIKELY(self->TestAllFlags())) {
714 CheckSuspend(self);
715 }
716 }
717 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200718 } else {
719 inst = inst->Next_2xx();
720 }
721 break;
722 }
723 case Instruction::IF_GE: {
724 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200725 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >= shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200726 int16_t offset = inst->VRegC_22t();
727 if (IsBackwardBranch(offset)) {
728 if (UNLIKELY(self->TestAllFlags())) {
729 CheckSuspend(self);
730 }
731 }
732 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200733 } else {
734 inst = inst->Next_2xx();
735 }
736 break;
737 }
738 case Instruction::IF_GT: {
739 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200740 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) > shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200741 int16_t offset = inst->VRegC_22t();
742 if (IsBackwardBranch(offset)) {
743 if (UNLIKELY(self->TestAllFlags())) {
744 CheckSuspend(self);
745 }
746 }
747 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200748 } else {
749 inst = inst->Next_2xx();
750 }
751 break;
752 }
753 case Instruction::IF_LE: {
754 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200755 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <= shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200756 int16_t offset = inst->VRegC_22t();
757 if (IsBackwardBranch(offset)) {
758 if (UNLIKELY(self->TestAllFlags())) {
759 CheckSuspend(self);
760 }
761 }
762 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200763 } else {
764 inst = inst->Next_2xx();
765 }
766 break;
767 }
768 case Instruction::IF_EQZ: {
769 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200770 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200771 int16_t offset = inst->VRegB_21t();
772 if (IsBackwardBranch(offset)) {
773 if (UNLIKELY(self->TestAllFlags())) {
774 CheckSuspend(self);
775 }
776 }
777 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200778 } else {
779 inst = inst->Next_2xx();
780 }
781 break;
782 }
783 case Instruction::IF_NEZ: {
784 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200785 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200786 int16_t offset = inst->VRegB_21t();
787 if (IsBackwardBranch(offset)) {
788 if (UNLIKELY(self->TestAllFlags())) {
789 CheckSuspend(self);
790 }
791 }
792 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200793 } else {
794 inst = inst->Next_2xx();
795 }
796 break;
797 }
798 case Instruction::IF_LTZ: {
799 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200800 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200801 int16_t offset = inst->VRegB_21t();
802 if (IsBackwardBranch(offset)) {
803 if (UNLIKELY(self->TestAllFlags())) {
804 CheckSuspend(self);
805 }
806 }
807 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200808 } else {
809 inst = inst->Next_2xx();
810 }
811 break;
812 }
813 case Instruction::IF_GEZ: {
814 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200815 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200816 int16_t offset = inst->VRegB_21t();
817 if (IsBackwardBranch(offset)) {
818 if (UNLIKELY(self->TestAllFlags())) {
819 CheckSuspend(self);
820 }
821 }
822 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200823 } else {
824 inst = inst->Next_2xx();
825 }
826 break;
827 }
828 case Instruction::IF_GTZ: {
829 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200830 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200831 int16_t offset = inst->VRegB_21t();
832 if (IsBackwardBranch(offset)) {
833 if (UNLIKELY(self->TestAllFlags())) {
834 CheckSuspend(self);
835 }
836 }
837 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200838 } else {
839 inst = inst->Next_2xx();
840 }
841 break;
842 }
843 case Instruction::IF_LEZ: {
844 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200845 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200846 int16_t offset = inst->VRegB_21t();
847 if (IsBackwardBranch(offset)) {
848 if (UNLIKELY(self->TestAllFlags())) {
849 CheckSuspend(self);
850 }
851 }
852 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200853 } else {
854 inst = inst->Next_2xx();
855 }
856 break;
857 }
858 case Instruction::AGET_BOOLEAN: {
859 PREAMBLE();
860 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
861 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200862 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200863 HANDLE_PENDING_EXCEPTION();
864 break;
865 }
866 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
867 BooleanArray* array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700868 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100869 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200870 inst = inst->Next_2xx();
871 } else {
872 HANDLE_PENDING_EXCEPTION();
873 }
874 break;
875 }
876 case Instruction::AGET_BYTE: {
877 PREAMBLE();
878 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
879 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200880 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200881 HANDLE_PENDING_EXCEPTION();
882 break;
883 }
884 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
885 ByteArray* array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700886 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100887 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200888 inst = inst->Next_2xx();
889 } else {
890 HANDLE_PENDING_EXCEPTION();
891 }
892 break;
893 }
894 case Instruction::AGET_CHAR: {
895 PREAMBLE();
896 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
897 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200898 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200899 HANDLE_PENDING_EXCEPTION();
900 break;
901 }
902 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
903 CharArray* array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700904 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100905 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200906 inst = inst->Next_2xx();
907 } else {
908 HANDLE_PENDING_EXCEPTION();
909 }
910 break;
911 }
912 case Instruction::AGET_SHORT: {
913 PREAMBLE();
914 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
915 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200916 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200917 HANDLE_PENDING_EXCEPTION();
918 break;
919 }
920 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
921 ShortArray* array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700922 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100923 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200924 inst = inst->Next_2xx();
925 } else {
926 HANDLE_PENDING_EXCEPTION();
927 }
928 break;
929 }
930 case Instruction::AGET: {
931 PREAMBLE();
932 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
933 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200934 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200935 HANDLE_PENDING_EXCEPTION();
936 break;
937 }
938 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
939 IntArray* array = a->AsIntArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700940 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100941 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200942 inst = inst->Next_2xx();
943 } else {
944 HANDLE_PENDING_EXCEPTION();
945 }
946 break;
947 }
948 case Instruction::AGET_WIDE: {
949 PREAMBLE();
950 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
951 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200952 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200953 HANDLE_PENDING_EXCEPTION();
954 break;
955 }
956 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
957 LongArray* array = a->AsLongArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700958 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100959 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200960 inst = inst->Next_2xx();
961 } else {
962 HANDLE_PENDING_EXCEPTION();
963 }
964 break;
965 }
966 case Instruction::AGET_OBJECT: {
967 PREAMBLE();
968 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
969 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200970 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200971 HANDLE_PENDING_EXCEPTION();
972 break;
973 }
974 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
975 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700976 if (array->CheckIsValidIndex(index)) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200977 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200978 inst = inst->Next_2xx();
979 } else {
980 HANDLE_PENDING_EXCEPTION();
981 }
982 break;
983 }
984 case Instruction::APUT_BOOLEAN: {
985 PREAMBLE();
986 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
987 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200988 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200989 HANDLE_PENDING_EXCEPTION();
990 break;
991 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200992 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200993 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
994 BooleanArray* array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700995 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100996 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200997 inst = inst->Next_2xx();
998 } else {
999 HANDLE_PENDING_EXCEPTION();
1000 }
1001 break;
1002 }
1003 case Instruction::APUT_BYTE: {
1004 PREAMBLE();
1005 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1006 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001007 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001008 HANDLE_PENDING_EXCEPTION();
1009 break;
1010 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001011 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001012 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1013 ByteArray* array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001014 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001015 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001016 inst = inst->Next_2xx();
1017 } else {
1018 HANDLE_PENDING_EXCEPTION();
1019 }
1020 break;
1021 }
1022 case Instruction::APUT_CHAR: {
1023 PREAMBLE();
1024 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1025 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001026 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001027 HANDLE_PENDING_EXCEPTION();
1028 break;
1029 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001030 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001031 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1032 CharArray* array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001033 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001034 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001035 inst = inst->Next_2xx();
1036 } else {
1037 HANDLE_PENDING_EXCEPTION();
1038 }
1039 break;
1040 }
1041 case Instruction::APUT_SHORT: {
1042 PREAMBLE();
1043 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1044 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001045 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001046 HANDLE_PENDING_EXCEPTION();
1047 break;
1048 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001049 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001050 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1051 ShortArray* array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001052 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001053 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001054 inst = inst->Next_2xx();
1055 } else {
1056 HANDLE_PENDING_EXCEPTION();
1057 }
1058 break;
1059 }
1060 case Instruction::APUT: {
1061 PREAMBLE();
1062 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1063 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001064 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001065 HANDLE_PENDING_EXCEPTION();
1066 break;
1067 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001068 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001069 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1070 IntArray* array = a->AsIntArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001071 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001072 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001073 inst = inst->Next_2xx();
1074 } else {
1075 HANDLE_PENDING_EXCEPTION();
1076 }
1077 break;
1078 }
1079 case Instruction::APUT_WIDE: {
1080 PREAMBLE();
1081 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1082 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001083 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001084 HANDLE_PENDING_EXCEPTION();
1085 break;
1086 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001087 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001088 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1089 LongArray* array = a->AsLongArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001090 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001091 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001092 inst = inst->Next_2xx();
1093 } else {
1094 HANDLE_PENDING_EXCEPTION();
1095 }
1096 break;
1097 }
1098 case Instruction::APUT_OBJECT: {
1099 PREAMBLE();
1100 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1101 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001102 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001103 HANDLE_PENDING_EXCEPTION();
1104 break;
1105 }
1106 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001107 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001108 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001109 if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001110 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001111 inst = inst->Next_2xx();
1112 } else {
1113 HANDLE_PENDING_EXCEPTION();
1114 }
1115 break;
1116 }
1117 case Instruction::IGET_BOOLEAN: {
1118 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001119 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001120 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1121 break;
1122 }
1123 case Instruction::IGET_BYTE: {
1124 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001125 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001126 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1127 break;
1128 }
1129 case Instruction::IGET_CHAR: {
1130 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001131 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001132 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1133 break;
1134 }
1135 case Instruction::IGET_SHORT: {
1136 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001137 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001138 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1139 break;
1140 }
1141 case Instruction::IGET: {
1142 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001143 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001144 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1145 break;
1146 }
1147 case Instruction::IGET_WIDE: {
1148 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001149 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001150 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1151 break;
1152 }
1153 case Instruction::IGET_OBJECT: {
1154 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001155 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001156 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1157 break;
1158 }
1159 case Instruction::IGET_QUICK: {
1160 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001161 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001162 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1163 break;
1164 }
1165 case Instruction::IGET_WIDE_QUICK: {
1166 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001167 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001168 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1169 break;
1170 }
1171 case Instruction::IGET_OBJECT_QUICK: {
1172 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001173 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001174 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1175 break;
1176 }
1177 case Instruction::SGET_BOOLEAN: {
1178 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001179 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001180 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1181 break;
1182 }
1183 case Instruction::SGET_BYTE: {
1184 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001185 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001186 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1187 break;
1188 }
1189 case Instruction::SGET_CHAR: {
1190 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001191 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001192 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1193 break;
1194 }
1195 case Instruction::SGET_SHORT: {
1196 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001197 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001198 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1199 break;
1200 }
1201 case Instruction::SGET: {
1202 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001203 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001204 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1205 break;
1206 }
1207 case Instruction::SGET_WIDE: {
1208 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001209 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001210 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1211 break;
1212 }
1213 case Instruction::SGET_OBJECT: {
1214 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001215 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001216 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1217 break;
1218 }
1219 case Instruction::IPUT_BOOLEAN: {
1220 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001221 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001222 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1223 break;
1224 }
1225 case Instruction::IPUT_BYTE: {
1226 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001227 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001228 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1229 break;
1230 }
1231 case Instruction::IPUT_CHAR: {
1232 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001233 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001234 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1235 break;
1236 }
1237 case Instruction::IPUT_SHORT: {
1238 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001239 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001240 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1241 break;
1242 }
1243 case Instruction::IPUT: {
1244 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001245 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001246 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1247 break;
1248 }
1249 case Instruction::IPUT_WIDE: {
1250 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001251 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001252 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1253 break;
1254 }
1255 case Instruction::IPUT_OBJECT: {
1256 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001257 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001258 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1259 break;
1260 }
1261 case Instruction::IPUT_QUICK: {
1262 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001263 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001264 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1265 break;
1266 }
1267 case Instruction::IPUT_WIDE_QUICK: {
1268 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001269 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001270 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1271 break;
1272 }
1273 case Instruction::IPUT_OBJECT_QUICK: {
1274 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001275 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001276 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1277 break;
1278 }
1279 case Instruction::SPUT_BOOLEAN: {
1280 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001281 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001282 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1283 break;
1284 }
1285 case Instruction::SPUT_BYTE: {
1286 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001287 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001288 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1289 break;
1290 }
1291 case Instruction::SPUT_CHAR: {
1292 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001293 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001294 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1295 break;
1296 }
1297 case Instruction::SPUT_SHORT: {
1298 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001299 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001300 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1301 break;
1302 }
1303 case Instruction::SPUT: {
1304 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001305 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001306 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1307 break;
1308 }
1309 case Instruction::SPUT_WIDE: {
1310 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001311 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001312 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1313 break;
1314 }
1315 case Instruction::SPUT_OBJECT: {
1316 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001317 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001318 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1319 break;
1320 }
1321 case Instruction::INVOKE_VIRTUAL: {
1322 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001323 bool success = DoInvoke<kVirtual, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001324 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1325 break;
1326 }
1327 case Instruction::INVOKE_VIRTUAL_RANGE: {
1328 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001329 bool success = DoInvoke<kVirtual, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001330 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1331 break;
1332 }
1333 case Instruction::INVOKE_SUPER: {
1334 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001335 bool success = DoInvoke<kSuper, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001336 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1337 break;
1338 }
1339 case Instruction::INVOKE_SUPER_RANGE: {
1340 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001341 bool success = DoInvoke<kSuper, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001342 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1343 break;
1344 }
1345 case Instruction::INVOKE_DIRECT: {
1346 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001347 bool success = DoInvoke<kDirect, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001348 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1349 break;
1350 }
1351 case Instruction::INVOKE_DIRECT_RANGE: {
1352 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001353 bool success = DoInvoke<kDirect, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001354 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1355 break;
1356 }
1357 case Instruction::INVOKE_INTERFACE: {
1358 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001359 bool success = DoInvoke<kInterface, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001360 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1361 break;
1362 }
1363 case Instruction::INVOKE_INTERFACE_RANGE: {
1364 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001365 bool success = DoInvoke<kInterface, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001366 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1367 break;
1368 }
1369 case Instruction::INVOKE_STATIC: {
1370 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001371 bool success = DoInvoke<kStatic, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001372 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1373 break;
1374 }
1375 case Instruction::INVOKE_STATIC_RANGE: {
1376 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001377 bool success = DoInvoke<kStatic, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001378 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1379 break;
1380 }
1381 case Instruction::INVOKE_VIRTUAL_QUICK: {
1382 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001383 bool success = DoInvokeVirtualQuick<false>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001384 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1385 break;
1386 }
1387 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
1388 PREAMBLE();
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001389 bool success = DoInvokeVirtualQuick<true>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001390 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1391 break;
1392 }
1393 case Instruction::NEG_INT:
1394 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001395 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001396 inst = inst->Next_1xx();
1397 break;
1398 case Instruction::NOT_INT:
1399 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001400 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001401 inst = inst->Next_1xx();
1402 break;
1403 case Instruction::NEG_LONG:
1404 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001405 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001406 inst = inst->Next_1xx();
1407 break;
1408 case Instruction::NOT_LONG:
1409 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001410 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001411 inst = inst->Next_1xx();
1412 break;
1413 case Instruction::NEG_FLOAT:
1414 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001415 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001416 inst = inst->Next_1xx();
1417 break;
1418 case Instruction::NEG_DOUBLE:
1419 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001420 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001421 inst = inst->Next_1xx();
1422 break;
1423 case Instruction::INT_TO_LONG:
1424 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001425 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
1426 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001427 inst = inst->Next_1xx();
1428 break;
1429 case Instruction::INT_TO_FLOAT:
1430 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001431 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1432 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001433 inst = inst->Next_1xx();
1434 break;
1435 case Instruction::INT_TO_DOUBLE:
1436 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001437 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1438 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001439 inst = inst->Next_1xx();
1440 break;
1441 case Instruction::LONG_TO_INT:
1442 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001443 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1444 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001445 inst = inst->Next_1xx();
1446 break;
1447 case Instruction::LONG_TO_FLOAT:
1448 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001449 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1450 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001451 inst = inst->Next_1xx();
1452 break;
1453 case Instruction::LONG_TO_DOUBLE:
1454 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001455 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1456 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001457 inst = inst->Next_1xx();
1458 break;
1459 case Instruction::FLOAT_TO_INT: {
1460 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001461 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001462 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001463 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001464 inst = inst->Next_1xx();
1465 break;
1466 }
1467 case Instruction::FLOAT_TO_LONG: {
1468 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001469 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001470 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001471 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001472 inst = inst->Next_1xx();
1473 break;
1474 }
1475 case Instruction::FLOAT_TO_DOUBLE:
1476 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001477 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1478 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001479 inst = inst->Next_1xx();
1480 break;
1481 case Instruction::DOUBLE_TO_INT: {
1482 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001483 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001484 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001485 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001486 inst = inst->Next_1xx();
1487 break;
1488 }
1489 case Instruction::DOUBLE_TO_LONG: {
1490 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001491 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001492 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001493 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001494 inst = inst->Next_1xx();
1495 break;
1496 }
1497 case Instruction::DOUBLE_TO_FLOAT:
1498 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001499 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1500 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001501 inst = inst->Next_1xx();
1502 break;
1503 case Instruction::INT_TO_BYTE:
1504 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001505 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1506 static_cast<int8_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001507 inst = inst->Next_1xx();
1508 break;
1509 case Instruction::INT_TO_CHAR:
1510 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001511 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1512 static_cast<uint16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001513 inst = inst->Next_1xx();
1514 break;
1515 case Instruction::INT_TO_SHORT:
1516 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001517 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1518 static_cast<int16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001519 inst = inst->Next_1xx();
1520 break;
1521 case Instruction::ADD_INT:
1522 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001523 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001524 shadow_frame.GetVReg(inst->VRegB_23x()) +
1525 shadow_frame.GetVReg(inst->VRegC_23x()));
1526 inst = inst->Next_2xx();
1527 break;
1528 case Instruction::SUB_INT:
1529 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001530 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001531 shadow_frame.GetVReg(inst->VRegB_23x()) -
1532 shadow_frame.GetVReg(inst->VRegC_23x()));
1533 inst = inst->Next_2xx();
1534 break;
1535 case Instruction::MUL_INT:
1536 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001537 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001538 shadow_frame.GetVReg(inst->VRegB_23x()) *
1539 shadow_frame.GetVReg(inst->VRegC_23x()));
1540 inst = inst->Next_2xx();
1541 break;
1542 case Instruction::DIV_INT: {
1543 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001544 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001545 shadow_frame.GetVReg(inst->VRegB_23x()),
1546 shadow_frame.GetVReg(inst->VRegC_23x()));
1547 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1548 break;
1549 }
1550 case Instruction::REM_INT: {
1551 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001552 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001553 shadow_frame.GetVReg(inst->VRegB_23x()),
1554 shadow_frame.GetVReg(inst->VRegC_23x()));
1555 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1556 break;
1557 }
1558 case Instruction::SHL_INT:
1559 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001560 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001561 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1562 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1563 inst = inst->Next_2xx();
1564 break;
1565 case Instruction::SHR_INT:
1566 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001567 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001568 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1569 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1570 inst = inst->Next_2xx();
1571 break;
1572 case Instruction::USHR_INT:
1573 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001574 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001575 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1576 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1577 inst = inst->Next_2xx();
1578 break;
1579 case Instruction::AND_INT:
1580 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001581 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001582 shadow_frame.GetVReg(inst->VRegB_23x()) &
1583 shadow_frame.GetVReg(inst->VRegC_23x()));
1584 inst = inst->Next_2xx();
1585 break;
1586 case Instruction::OR_INT:
1587 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001588 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001589 shadow_frame.GetVReg(inst->VRegB_23x()) |
1590 shadow_frame.GetVReg(inst->VRegC_23x()));
1591 inst = inst->Next_2xx();
1592 break;
1593 case Instruction::XOR_INT:
1594 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001595 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001596 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1597 shadow_frame.GetVReg(inst->VRegC_23x()));
1598 inst = inst->Next_2xx();
1599 break;
1600 case Instruction::ADD_LONG:
1601 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001602 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001603 shadow_frame.GetVRegLong(inst->VRegB_23x()) +
1604 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1605 inst = inst->Next_2xx();
1606 break;
1607 case Instruction::SUB_LONG:
1608 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001609 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001610 shadow_frame.GetVRegLong(inst->VRegB_23x()) -
1611 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1612 inst = inst->Next_2xx();
1613 break;
1614 case Instruction::MUL_LONG:
1615 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001616 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001617 shadow_frame.GetVRegLong(inst->VRegB_23x()) *
1618 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1619 inst = inst->Next_2xx();
1620 break;
1621 case Instruction::DIV_LONG:
1622 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001623 DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001624 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1625 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1626 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1627 break;
1628 case Instruction::REM_LONG:
1629 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001630 DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001631 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1632 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1633 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1634 break;
1635 case Instruction::AND_LONG:
1636 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001637 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001638 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1639 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1640 inst = inst->Next_2xx();
1641 break;
1642 case Instruction::OR_LONG:
1643 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001644 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001645 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1646 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1647 inst = inst->Next_2xx();
1648 break;
1649 case Instruction::XOR_LONG:
1650 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001651 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001652 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1653 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1654 inst = inst->Next_2xx();
1655 break;
1656 case Instruction::SHL_LONG:
1657 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001658 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001659 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1660 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1661 inst = inst->Next_2xx();
1662 break;
1663 case Instruction::SHR_LONG:
1664 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001665 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001666 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1667 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1668 inst = inst->Next_2xx();
1669 break;
1670 case Instruction::USHR_LONG:
1671 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001672 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001673 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1674 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1675 inst = inst->Next_2xx();
1676 break;
1677 case Instruction::ADD_FLOAT:
1678 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001679 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001680 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1681 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1682 inst = inst->Next_2xx();
1683 break;
1684 case Instruction::SUB_FLOAT:
1685 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001686 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001687 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1688 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1689 inst = inst->Next_2xx();
1690 break;
1691 case Instruction::MUL_FLOAT:
1692 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001693 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001694 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1695 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1696 inst = inst->Next_2xx();
1697 break;
1698 case Instruction::DIV_FLOAT:
1699 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001700 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001701 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1702 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1703 inst = inst->Next_2xx();
1704 break;
1705 case Instruction::REM_FLOAT:
1706 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001707 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001708 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1709 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1710 inst = inst->Next_2xx();
1711 break;
1712 case Instruction::ADD_DOUBLE:
1713 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001714 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001715 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1716 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1717 inst = inst->Next_2xx();
1718 break;
1719 case Instruction::SUB_DOUBLE:
1720 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001721 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001722 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1723 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1724 inst = inst->Next_2xx();
1725 break;
1726 case Instruction::MUL_DOUBLE:
1727 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001728 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001729 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
1730 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1731 inst = inst->Next_2xx();
1732 break;
1733 case Instruction::DIV_DOUBLE:
1734 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001735 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001736 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
1737 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1738 inst = inst->Next_2xx();
1739 break;
1740 case Instruction::REM_DOUBLE:
1741 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001742 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001743 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
1744 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
1745 inst = inst->Next_2xx();
1746 break;
1747 case Instruction::ADD_INT_2ADDR: {
1748 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001749 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001750 shadow_frame.SetVReg(vregA,
1751 shadow_frame.GetVReg(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001752 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001753 inst = inst->Next_1xx();
1754 break;
1755 }
1756 case Instruction::SUB_INT_2ADDR: {
1757 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001758 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001759 shadow_frame.SetVReg(vregA,
1760 shadow_frame.GetVReg(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001761 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001762 inst = inst->Next_1xx();
1763 break;
1764 }
1765 case Instruction::MUL_INT_2ADDR: {
1766 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001767 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001768 shadow_frame.SetVReg(vregA,
1769 shadow_frame.GetVReg(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001770 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001771 inst = inst->Next_1xx();
1772 break;
1773 }
1774 case Instruction::DIV_INT_2ADDR: {
1775 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001776 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001777 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001778 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001779 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1780 break;
1781 }
1782 case Instruction::REM_INT_2ADDR: {
1783 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001784 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001785 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001786 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001787 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1788 break;
1789 }
1790 case Instruction::SHL_INT_2ADDR: {
1791 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001792 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001793 shadow_frame.SetVReg(vregA,
1794 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001795 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001796 inst = inst->Next_1xx();
1797 break;
1798 }
1799 case Instruction::SHR_INT_2ADDR: {
1800 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001801 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001802 shadow_frame.SetVReg(vregA,
1803 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001804 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001805 inst = inst->Next_1xx();
1806 break;
1807 }
1808 case Instruction::USHR_INT_2ADDR: {
1809 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001810 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001811 shadow_frame.SetVReg(vregA,
1812 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001813 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001814 inst = inst->Next_1xx();
1815 break;
1816 }
1817 case Instruction::AND_INT_2ADDR: {
1818 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001819 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001820 shadow_frame.SetVReg(vregA,
1821 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001822 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001823 inst = inst->Next_1xx();
1824 break;
1825 }
1826 case Instruction::OR_INT_2ADDR: {
1827 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001828 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001829 shadow_frame.SetVReg(vregA,
1830 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001831 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001832 inst = inst->Next_1xx();
1833 break;
1834 }
1835 case Instruction::XOR_INT_2ADDR: {
1836 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001837 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001838 shadow_frame.SetVReg(vregA,
1839 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001840 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001841 inst = inst->Next_1xx();
1842 break;
1843 }
1844 case Instruction::ADD_LONG_2ADDR: {
1845 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001846 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001847 shadow_frame.SetVRegLong(vregA,
1848 shadow_frame.GetVRegLong(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001849 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001850 inst = inst->Next_1xx();
1851 break;
1852 }
1853 case Instruction::SUB_LONG_2ADDR: {
1854 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001855 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001856 shadow_frame.SetVRegLong(vregA,
1857 shadow_frame.GetVRegLong(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001858 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001859 inst = inst->Next_1xx();
1860 break;
1861 }
1862 case Instruction::MUL_LONG_2ADDR: {
1863 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001864 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001865 shadow_frame.SetVRegLong(vregA,
1866 shadow_frame.GetVRegLong(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001867 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001868 inst = inst->Next_1xx();
1869 break;
1870 }
1871 case Instruction::DIV_LONG_2ADDR: {
1872 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001873 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001874 DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001875 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001876 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
1877 break;
1878 }
1879 case Instruction::REM_LONG_2ADDR: {
1880 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001881 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001882 DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001883 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001884 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
1885 break;
1886 }
1887 case Instruction::AND_LONG_2ADDR: {
1888 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001889 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001890 shadow_frame.SetVRegLong(vregA,
1891 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001892 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001893 inst = inst->Next_1xx();
1894 break;
1895 }
1896 case Instruction::OR_LONG_2ADDR: {
1897 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001898 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001899 shadow_frame.SetVRegLong(vregA,
1900 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001901 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001902 inst = inst->Next_1xx();
1903 break;
1904 }
1905 case Instruction::XOR_LONG_2ADDR: {
1906 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001907 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001908 shadow_frame.SetVRegLong(vregA,
1909 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001910 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001911 inst = inst->Next_1xx();
1912 break;
1913 }
1914 case Instruction::SHL_LONG_2ADDR: {
1915 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001916 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001917 shadow_frame.SetVRegLong(vregA,
1918 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001919 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001920 inst = inst->Next_1xx();
1921 break;
1922 }
1923 case Instruction::SHR_LONG_2ADDR: {
1924 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001925 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001926 shadow_frame.SetVRegLong(vregA,
1927 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001928 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001929 inst = inst->Next_1xx();
1930 break;
1931 }
1932 case Instruction::USHR_LONG_2ADDR: {
1933 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001934 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001935 shadow_frame.SetVRegLong(vregA,
1936 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001937 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001938 inst = inst->Next_1xx();
1939 break;
1940 }
1941 case Instruction::ADD_FLOAT_2ADDR: {
1942 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001943 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001944 shadow_frame.SetVRegFloat(vregA,
1945 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001946 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001947 inst = inst->Next_1xx();
1948 break;
1949 }
1950 case Instruction::SUB_FLOAT_2ADDR: {
1951 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001952 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001953 shadow_frame.SetVRegFloat(vregA,
1954 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001955 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001956 inst = inst->Next_1xx();
1957 break;
1958 }
1959 case Instruction::MUL_FLOAT_2ADDR: {
1960 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001961 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001962 shadow_frame.SetVRegFloat(vregA,
1963 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001964 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001965 inst = inst->Next_1xx();
1966 break;
1967 }
1968 case Instruction::DIV_FLOAT_2ADDR: {
1969 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001970 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001971 shadow_frame.SetVRegFloat(vregA,
1972 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001973 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001974 inst = inst->Next_1xx();
1975 break;
1976 }
1977 case Instruction::REM_FLOAT_2ADDR: {
1978 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001979 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001980 shadow_frame.SetVRegFloat(vregA,
1981 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001982 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001983 inst = inst->Next_1xx();
1984 break;
1985 }
1986 case Instruction::ADD_DOUBLE_2ADDR: {
1987 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001988 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001989 shadow_frame.SetVRegDouble(vregA,
1990 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001991 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001992 inst = inst->Next_1xx();
1993 break;
1994 }
1995 case Instruction::SUB_DOUBLE_2ADDR: {
1996 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001997 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001998 shadow_frame.SetVRegDouble(vregA,
1999 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002000 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002001 inst = inst->Next_1xx();
2002 break;
2003 }
2004 case Instruction::MUL_DOUBLE_2ADDR: {
2005 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002006 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002007 shadow_frame.SetVRegDouble(vregA,
2008 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002009 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002010 inst = inst->Next_1xx();
2011 break;
2012 }
2013 case Instruction::DIV_DOUBLE_2ADDR: {
2014 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002015 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002016 shadow_frame.SetVRegDouble(vregA,
2017 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002018 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002019 inst = inst->Next_1xx();
2020 break;
2021 }
2022 case Instruction::REM_DOUBLE_2ADDR: {
2023 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002024 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002025 shadow_frame.SetVRegDouble(vregA,
2026 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002027 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002028 inst = inst->Next_1xx();
2029 break;
2030 }
2031 case Instruction::ADD_INT_LIT16:
2032 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002033 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2034 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) +
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002035 inst->VRegC_22s());
2036 inst = inst->Next_2xx();
2037 break;
2038 case Instruction::RSUB_INT:
2039 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002040 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002041 inst->VRegC_22s() -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002042 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002043 inst = inst->Next_2xx();
2044 break;
2045 case Instruction::MUL_INT_LIT16:
2046 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002047 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2048 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) *
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002049 inst->VRegC_22s());
2050 inst = inst->Next_2xx();
2051 break;
2052 case Instruction::DIV_INT_LIT16: {
2053 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002054 bool success = DoIntDivide(shadow_frame, inst->VRegA_22s(inst_data),
2055 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)), inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002056 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2057 break;
2058 }
2059 case Instruction::REM_INT_LIT16: {
2060 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002061 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22s(inst_data),
2062 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)), inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002063 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2064 break;
2065 }
2066 case Instruction::AND_INT_LIT16:
2067 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002068 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2069 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002070 inst->VRegC_22s());
2071 inst = inst->Next_2xx();
2072 break;
2073 case Instruction::OR_INT_LIT16:
2074 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002075 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2076 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002077 inst->VRegC_22s());
2078 inst = inst->Next_2xx();
2079 break;
2080 case Instruction::XOR_INT_LIT16:
2081 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002082 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2083 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002084 inst->VRegC_22s());
2085 inst = inst->Next_2xx();
2086 break;
2087 case Instruction::ADD_INT_LIT8:
2088 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002089 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002090 shadow_frame.GetVReg(inst->VRegB_22b()) +
2091 inst->VRegC_22b());
2092 inst = inst->Next_2xx();
2093 break;
2094 case Instruction::RSUB_INT_LIT8:
2095 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002096 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002097 inst->VRegC_22b() -
2098 shadow_frame.GetVReg(inst->VRegB_22b()));
2099 inst = inst->Next_2xx();
2100 break;
2101 case Instruction::MUL_INT_LIT8:
2102 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002103 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002104 shadow_frame.GetVReg(inst->VRegB_22b()) *
2105 inst->VRegC_22b());
2106 inst = inst->Next_2xx();
2107 break;
2108 case Instruction::DIV_INT_LIT8: {
2109 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002110 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002111 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2112 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2113 break;
2114 }
2115 case Instruction::REM_INT_LIT8: {
2116 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002117 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002118 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2119 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2120 break;
2121 }
2122 case Instruction::AND_INT_LIT8:
2123 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002124 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002125 shadow_frame.GetVReg(inst->VRegB_22b()) &
2126 inst->VRegC_22b());
2127 inst = inst->Next_2xx();
2128 break;
2129 case Instruction::OR_INT_LIT8:
2130 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002131 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002132 shadow_frame.GetVReg(inst->VRegB_22b()) |
2133 inst->VRegC_22b());
2134 inst = inst->Next_2xx();
2135 break;
2136 case Instruction::XOR_INT_LIT8:
2137 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002138 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002139 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2140 inst->VRegC_22b());
2141 inst = inst->Next_2xx();
2142 break;
2143 case Instruction::SHL_INT_LIT8:
2144 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002145 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002146 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2147 (inst->VRegC_22b() & 0x1f));
2148 inst = inst->Next_2xx();
2149 break;
2150 case Instruction::SHR_INT_LIT8:
2151 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002152 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002153 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2154 (inst->VRegC_22b() & 0x1f));
2155 inst = inst->Next_2xx();
2156 break;
2157 case Instruction::USHR_INT_LIT8:
2158 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002159 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002160 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2161 (inst->VRegC_22b() & 0x1f));
2162 inst = inst->Next_2xx();
2163 break;
2164 case Instruction::UNUSED_3E ... Instruction::UNUSED_43:
2165 case Instruction::UNUSED_EB ... Instruction::UNUSED_FF:
2166 case Instruction::UNUSED_79:
2167 case Instruction::UNUSED_7A:
2168 UnexpectedOpcode(inst, mh);
2169 }
2170 }
2171} // NOLINT(readability/fn_size)
2172
2173// Explicit definitions of ExecuteSwitchImpl.
Sebastien Hertzc6714852013-09-30 16:42:32 +02002174template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002175JValue ExecuteSwitchImpl<true, false>(Thread* self, MethodHelper& mh,
2176 const DexFile::CodeItem* code_item,
2177 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertzc6714852013-09-30 16:42:32 +02002178template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002179JValue ExecuteSwitchImpl<false, false>(Thread* self, MethodHelper& mh,
2180 const DexFile::CodeItem* code_item,
2181 ShadowFrame& shadow_frame, JValue result_register);
2182template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
2183JValue ExecuteSwitchImpl<true, true>(Thread* self, MethodHelper& mh,
2184 const DexFile::CodeItem* code_item,
2185 ShadowFrame& shadow_frame, JValue result_register);
2186template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
2187JValue ExecuteSwitchImpl<false, true>(Thread* self, MethodHelper& mh,
2188 const DexFile::CodeItem* code_item,
2189 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002190
2191} // namespace interpreter
2192} // namespace art