blob: d49807cc5ddc92bd6f9e4b9490a27bd1a785c116 [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 { \
24 CHECK(self->IsExceptionPending()); \
Sebastien Hertz1eda2262013-09-09 16:53:14 +020025 if (UNLIKELY(self->TestAllFlags())) { \
26 CheckSuspend(self); \
27 } \
Sebastien Hertz947ff082013-09-17 14:10:13 +020028 Object* this_object = shadow_frame.GetThisObject(code_item->ins_size_); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020029 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, \
30 inst->GetDexPc(insns), \
Sebastien Hertz947ff082013-09-17 14:10:13 +020031 this_object, \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020032 instrumentation); \
33 if (found_dex_pc == DexFile::kDexNoIndex) { \
34 return JValue(); /* Handled in caller. */ \
35 } else { \
36 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc); \
37 inst = inst->RelativeAt(displacement); \
38 } \
39 } while (false)
40
41#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _next_function) \
42 do { \
43 if (UNLIKELY(_is_exception_pending)) { \
44 HANDLE_PENDING_EXCEPTION(); \
45 } else { \
46 inst = inst->_next_function(); \
47 } \
48 } while (false)
49
50// Code to run before each dex instruction.
51#define PREAMBLE()
52
53template<bool do_access_check>
54static JValue ExecuteSwitchImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item,
55 ShadowFrame& shadow_frame, JValue result_register) {
56 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
57 LOG(FATAL) << "Invalid shadow frame for interpreter use";
58 return JValue();
59 }
60 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +020061
62 uint32_t dex_pc = shadow_frame.GetDexPC();
Sebastien Hertz947ff082013-09-17 14:10:13 +020063 const instrumentation::Instrumentation* const instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +020064 if (LIKELY(dex_pc == 0)) { // We are entering the method as opposed to deoptimizing..
65 if (UNLIKELY(instrumentation->HasMethodEntryListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +020066 instrumentation->MethodEnterEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +020067 shadow_frame.GetMethod(), 0);
68 }
69 }
70 const uint16_t* const insns = code_item->insns_;
71 const Instruction* inst = Instruction::At(insns + dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +020072 uint16_t inst_data;
Sebastien Hertz8ece0502013-08-07 11:26:41 +020073 while (true) {
74 dex_pc = inst->GetDexPc(insns);
75 shadow_frame.SetDexPC(dex_pc);
Sebastien Hertz8ece0502013-08-07 11:26:41 +020076 if (UNLIKELY(instrumentation->HasDexPcListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +020077 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +020078 shadow_frame.GetMethod(), dex_pc);
79 }
80 TraceExecution(shadow_frame, inst, dex_pc, mh);
Sebastien Hertz3b588e02013-09-11 14:33:18 +020081 inst_data = inst->Fetch16(0);
82 switch (inst->Opcode(inst_data)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +020083 case Instruction::NOP:
84 PREAMBLE();
85 inst = inst->Next_1xx();
86 break;
87 case Instruction::MOVE:
88 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +020089 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
90 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +020091 inst = inst->Next_1xx();
92 break;
93 case Instruction::MOVE_FROM16:
94 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +020095 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +020096 shadow_frame.GetVReg(inst->VRegB_22x()));
97 inst = inst->Next_2xx();
98 break;
99 case Instruction::MOVE_16:
100 PREAMBLE();
101 shadow_frame.SetVReg(inst->VRegA_32x(),
102 shadow_frame.GetVReg(inst->VRegB_32x()));
103 inst = inst->Next_3xx();
104 break;
105 case Instruction::MOVE_WIDE:
106 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200107 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
108 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200109 inst = inst->Next_1xx();
110 break;
111 case Instruction::MOVE_WIDE_FROM16:
112 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200113 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200114 shadow_frame.GetVRegLong(inst->VRegB_22x()));
115 inst = inst->Next_2xx();
116 break;
117 case Instruction::MOVE_WIDE_16:
118 PREAMBLE();
119 shadow_frame.SetVRegLong(inst->VRegA_32x(),
120 shadow_frame.GetVRegLong(inst->VRegB_32x()));
121 inst = inst->Next_3xx();
122 break;
123 case Instruction::MOVE_OBJECT:
124 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200125 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
126 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200127 inst = inst->Next_1xx();
128 break;
129 case Instruction::MOVE_OBJECT_FROM16:
130 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200131 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200132 shadow_frame.GetVRegReference(inst->VRegB_22x()));
133 inst = inst->Next_2xx();
134 break;
135 case Instruction::MOVE_OBJECT_16:
136 PREAMBLE();
137 shadow_frame.SetVRegReference(inst->VRegA_32x(),
138 shadow_frame.GetVRegReference(inst->VRegB_32x()));
139 inst = inst->Next_3xx();
140 break;
141 case Instruction::MOVE_RESULT:
142 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200143 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200144 inst = inst->Next_1xx();
145 break;
146 case Instruction::MOVE_RESULT_WIDE:
147 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200148 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200149 inst = inst->Next_1xx();
150 break;
151 case Instruction::MOVE_RESULT_OBJECT:
152 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200153 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200154 inst = inst->Next_1xx();
155 break;
156 case Instruction::MOVE_EXCEPTION: {
157 PREAMBLE();
158 Throwable* exception = self->GetException(NULL);
159 self->ClearException();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200160 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200161 inst = inst->Next_1xx();
162 break;
163 }
164 case Instruction::RETURN_VOID: {
165 PREAMBLE();
166 JValue result;
Sebastien Hertz043036f2013-09-09 18:26:48 +0200167 if (do_access_check) {
168 // If access checks are required then the dex-to-dex compiler and analysis of
169 // whether the class has final fields hasn't been performed. Conservatively
170 // perform the memory barrier now.
171 ANDROID_MEMBAR_STORE();
172 }
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200173 if (UNLIKELY(self->TestAllFlags())) {
174 CheckSuspend(self);
175 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200176 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200177 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200178 shadow_frame.GetMethod(), inst->GetDexPc(insns),
179 result);
180 }
181 return result;
182 }
183 case Instruction::RETURN_VOID_BARRIER: {
184 PREAMBLE();
185 ANDROID_MEMBAR_STORE();
186 JValue result;
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200187 if (UNLIKELY(self->TestAllFlags())) {
188 CheckSuspend(self);
189 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200190 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200191 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200192 shadow_frame.GetMethod(), inst->GetDexPc(insns),
193 result);
194 }
195 return result;
196 }
197 case Instruction::RETURN: {
198 PREAMBLE();
199 JValue result;
200 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200201 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200202 if (UNLIKELY(self->TestAllFlags())) {
203 CheckSuspend(self);
204 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200205 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200206 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200207 shadow_frame.GetMethod(), inst->GetDexPc(insns),
208 result);
209 }
210 return result;
211 }
212 case Instruction::RETURN_WIDE: {
213 PREAMBLE();
214 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200215 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200216 if (UNLIKELY(self->TestAllFlags())) {
217 CheckSuspend(self);
218 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200219 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200220 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200221 shadow_frame.GetMethod(), inst->GetDexPc(insns),
222 result);
223 }
224 return result;
225 }
226 case Instruction::RETURN_OBJECT: {
227 PREAMBLE();
228 JValue result;
229 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200230 result.SetL(shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data)));
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200231 if (UNLIKELY(self->TestAllFlags())) {
232 CheckSuspend(self);
233 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200234 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200235 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200236 shadow_frame.GetMethod(), inst->GetDexPc(insns),
237 result);
238 }
239 return result;
240 }
241 case Instruction::CONST_4: {
242 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200243 uint4_t dst = inst->VRegA_11n(inst_data);
244 int4_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200245 shadow_frame.SetVReg(dst, val);
246 if (val == 0) {
247 shadow_frame.SetVRegReference(dst, NULL);
248 }
249 inst = inst->Next_1xx();
250 break;
251 }
252 case Instruction::CONST_16: {
253 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200254 uint8_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200255 int16_t val = inst->VRegB_21s();
256 shadow_frame.SetVReg(dst, val);
257 if (val == 0) {
258 shadow_frame.SetVRegReference(dst, NULL);
259 }
260 inst = inst->Next_2xx();
261 break;
262 }
263 case Instruction::CONST: {
264 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200265 uint8_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200266 int32_t val = inst->VRegB_31i();
267 shadow_frame.SetVReg(dst, val);
268 if (val == 0) {
269 shadow_frame.SetVRegReference(dst, NULL);
270 }
271 inst = inst->Next_3xx();
272 break;
273 }
274 case Instruction::CONST_HIGH16: {
275 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200276 uint8_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200277 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
278 shadow_frame.SetVReg(dst, val);
279 if (val == 0) {
280 shadow_frame.SetVRegReference(dst, NULL);
281 }
282 inst = inst->Next_2xx();
283 break;
284 }
285 case Instruction::CONST_WIDE_16:
286 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200287 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200288 inst = inst->Next_2xx();
289 break;
290 case Instruction::CONST_WIDE_32:
291 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200292 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200293 inst = inst->Next_3xx();
294 break;
295 case Instruction::CONST_WIDE:
296 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200297 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200298 inst = inst->Next_51l();
299 break;
300 case Instruction::CONST_WIDE_HIGH16:
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200301 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200302 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
303 inst = inst->Next_2xx();
304 break;
305 case Instruction::CONST_STRING: {
306 PREAMBLE();
307 String* s = ResolveString(self, mh, inst->VRegB_21c());
308 if (UNLIKELY(s == NULL)) {
309 HANDLE_PENDING_EXCEPTION();
310 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200311 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200312 inst = inst->Next_2xx();
313 }
314 break;
315 }
316 case Instruction::CONST_STRING_JUMBO: {
317 PREAMBLE();
318 String* s = ResolveString(self, mh, inst->VRegB_31c());
319 if (UNLIKELY(s == NULL)) {
320 HANDLE_PENDING_EXCEPTION();
321 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200322 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200323 inst = inst->Next_3xx();
324 }
325 break;
326 }
327 case Instruction::CONST_CLASS: {
328 PREAMBLE();
329 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
330 self, false, do_access_check);
331 if (UNLIKELY(c == NULL)) {
332 HANDLE_PENDING_EXCEPTION();
333 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200334 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200335 inst = inst->Next_2xx();
336 }
337 break;
338 }
339 case Instruction::MONITOR_ENTER: {
340 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200341 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200342 if (UNLIKELY(obj == NULL)) {
343 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
344 HANDLE_PENDING_EXCEPTION();
345 } else {
346 DoMonitorEnter(self, obj);
347 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
348 }
349 break;
350 }
351 case Instruction::MONITOR_EXIT: {
352 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200353 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200354 if (UNLIKELY(obj == NULL)) {
355 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
356 HANDLE_PENDING_EXCEPTION();
357 } else {
358 DoMonitorExit(self, obj);
359 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
360 }
361 break;
362 }
363 case Instruction::CHECK_CAST: {
364 PREAMBLE();
365 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
366 self, false, do_access_check);
367 if (UNLIKELY(c == NULL)) {
368 HANDLE_PENDING_EXCEPTION();
369 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200370 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200371 if (UNLIKELY(obj != NULL && !obj->InstanceOf(c))) {
372 ThrowClassCastException(c, obj->GetClass());
373 HANDLE_PENDING_EXCEPTION();
374 } else {
375 inst = inst->Next_2xx();
376 }
377 }
378 break;
379 }
380 case Instruction::INSTANCE_OF: {
381 PREAMBLE();
382 Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(),
383 self, false, do_access_check);
384 if (UNLIKELY(c == NULL)) {
385 HANDLE_PENDING_EXCEPTION();
386 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200387 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
388 shadow_frame.SetVReg(inst->VRegA_22c(inst_data), (obj != NULL && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200389 inst = inst->Next_2xx();
390 }
391 break;
392 }
393 case Instruction::ARRAY_LENGTH: {
394 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200395 Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200396 if (UNLIKELY(array == NULL)) {
397 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
398 HANDLE_PENDING_EXCEPTION();
399 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200400 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200401 inst = inst->Next_1xx();
402 }
403 break;
404 }
405 case Instruction::NEW_INSTANCE: {
406 PREAMBLE();
407 Object* obj = AllocObjectFromCode(inst->VRegB_21c(), shadow_frame.GetMethod(),
408 self, do_access_check);
409 if (UNLIKELY(obj == NULL)) {
410 HANDLE_PENDING_EXCEPTION();
411 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200412 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200413 inst = inst->Next_2xx();
414 }
415 break;
416 }
417 case Instruction::NEW_ARRAY: {
418 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200419 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200420 Object* obj = AllocArrayFromCode(inst->VRegC_22c(), shadow_frame.GetMethod(),
421 length, self, do_access_check);
422 if (UNLIKELY(obj == NULL)) {
423 HANDLE_PENDING_EXCEPTION();
424 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200425 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200426 inst = inst->Next_2xx();
427 }
428 break;
429 }
430 case Instruction::FILLED_NEW_ARRAY: {
431 PREAMBLE();
432 bool success = DoFilledNewArray<false, do_access_check>(inst, shadow_frame,
433 self, &result_register);
434 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
435 break;
436 }
437 case Instruction::FILLED_NEW_ARRAY_RANGE: {
438 PREAMBLE();
439 bool success = DoFilledNewArray<true, do_access_check>(inst, shadow_frame,
440 self, &result_register);
441 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
442 break;
443 }
444 case Instruction::FILL_ARRAY_DATA: {
445 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200446 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200447 if (UNLIKELY(obj == NULL)) {
448 ThrowNullPointerException(NULL, "null array in FILL_ARRAY_DATA");
449 HANDLE_PENDING_EXCEPTION();
450 break;
451 }
452 Array* array = obj->AsArray();
453 DCHECK(array->IsArrayInstance() && !array->IsObjectArray());
454 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
455 const Instruction::ArrayDataPayload* payload =
456 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
457 if (UNLIKELY(static_cast<int32_t>(payload->element_count) > array->GetLength())) {
458 self->ThrowNewExceptionF(shadow_frame.GetCurrentLocationForThrow(),
459 "Ljava/lang/ArrayIndexOutOfBoundsException;",
460 "failed FILL_ARRAY_DATA; length=%d, index=%d",
461 array->GetLength(), payload->element_count);
462 HANDLE_PENDING_EXCEPTION();
463 break;
464 }
465 uint32_t size_in_bytes = payload->element_count * payload->element_width;
466 memcpy(array->GetRawData(payload->element_width), payload->data, size_in_bytes);
467 inst = inst->Next_3xx();
468 break;
469 }
470 case Instruction::THROW: {
471 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200472 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200473 if (UNLIKELY(exception == NULL)) {
474 ThrowNullPointerException(NULL, "throw with null exception");
475 } else {
476 self->SetException(shadow_frame.GetCurrentLocationForThrow(), exception->AsThrowable());
477 }
478 HANDLE_PENDING_EXCEPTION();
479 break;
480 }
481 case Instruction::GOTO: {
482 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200483 int8_t offset = inst->VRegA_10t(inst_data);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200484 if (IsBackwardBranch(offset)) {
485 if (UNLIKELY(self->TestAllFlags())) {
486 CheckSuspend(self);
487 }
488 }
489 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200490 break;
491 }
492 case Instruction::GOTO_16: {
493 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200494 int16_t offset = inst->VRegA_20t();
495 if (IsBackwardBranch(offset)) {
496 if (UNLIKELY(self->TestAllFlags())) {
497 CheckSuspend(self);
498 }
499 }
500 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200501 break;
502 }
503 case Instruction::GOTO_32: {
504 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200505 int32_t offset = inst->VRegA_30t();
506 if (IsBackwardBranch(offset)) {
507 if (UNLIKELY(self->TestAllFlags())) {
508 CheckSuspend(self);
509 }
510 }
511 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200512 break;
513 }
514 case Instruction::PACKED_SWITCH: {
515 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200516 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200517 if (IsBackwardBranch(offset)) {
518 if (UNLIKELY(self->TestAllFlags())) {
519 CheckSuspend(self);
520 }
521 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200522 inst = inst->RelativeAt(offset);
523 break;
524 }
525 case Instruction::SPARSE_SWITCH: {
526 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200527 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200528 if (IsBackwardBranch(offset)) {
529 if (UNLIKELY(self->TestAllFlags())) {
530 CheckSuspend(self);
531 }
532 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200533 inst = inst->RelativeAt(offset);
534 break;
535 }
536 case Instruction::CMPL_FLOAT: {
537 PREAMBLE();
538 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
539 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
540 int32_t result;
541 if (val1 > val2) {
542 result = 1;
543 } else if (val1 == val2) {
544 result = 0;
545 } else {
546 result = -1;
547 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200548 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200549 inst = inst->Next_2xx();
550 break;
551 }
552 case Instruction::CMPG_FLOAT: {
553 PREAMBLE();
554 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
555 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
556 int32_t result;
557 if (val1 < val2) {
558 result = -1;
559 } else if (val1 == val2) {
560 result = 0;
561 } else {
562 result = 1;
563 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200564 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200565 inst = inst->Next_2xx();
566 break;
567 }
568 case Instruction::CMPL_DOUBLE: {
569 PREAMBLE();
570 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
571 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
572 int32_t result;
573 if (val1 > val2) {
574 result = 1;
575 } else if (val1 == val2) {
576 result = 0;
577 } else {
578 result = -1;
579 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200580 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200581 inst = inst->Next_2xx();
582 break;
583 }
584
585 case Instruction::CMPG_DOUBLE: {
586 PREAMBLE();
587 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
588 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
589 int32_t result;
590 if (val1 < val2) {
591 result = -1;
592 } else if (val1 == val2) {
593 result = 0;
594 } else {
595 result = 1;
596 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200597 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200598 inst = inst->Next_2xx();
599 break;
600 }
601 case Instruction::CMP_LONG: {
602 PREAMBLE();
603 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
604 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
605 int32_t result;
606 if (val1 > val2) {
607 result = 1;
608 } else if (val1 == val2) {
609 result = 0;
610 } else {
611 result = -1;
612 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200613 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200614 inst = inst->Next_2xx();
615 break;
616 }
617 case Instruction::IF_EQ: {
618 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200619 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) == shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200620 int16_t offset = inst->VRegC_22t();
621 if (IsBackwardBranch(offset)) {
622 if (UNLIKELY(self->TestAllFlags())) {
623 CheckSuspend(self);
624 }
625 }
626 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200627 } else {
628 inst = inst->Next_2xx();
629 }
630 break;
631 }
632 case Instruction::IF_NE: {
633 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200634 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) != shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200635 int16_t offset = inst->VRegC_22t();
636 if (IsBackwardBranch(offset)) {
637 if (UNLIKELY(self->TestAllFlags())) {
638 CheckSuspend(self);
639 }
640 }
641 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200642 } else {
643 inst = inst->Next_2xx();
644 }
645 break;
646 }
647 case Instruction::IF_LT: {
648 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200649 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) < shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200650 int16_t offset = inst->VRegC_22t();
651 if (IsBackwardBranch(offset)) {
652 if (UNLIKELY(self->TestAllFlags())) {
653 CheckSuspend(self);
654 }
655 }
656 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200657 } else {
658 inst = inst->Next_2xx();
659 }
660 break;
661 }
662 case Instruction::IF_GE: {
663 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200664 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >= shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200665 int16_t offset = inst->VRegC_22t();
666 if (IsBackwardBranch(offset)) {
667 if (UNLIKELY(self->TestAllFlags())) {
668 CheckSuspend(self);
669 }
670 }
671 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200672 } else {
673 inst = inst->Next_2xx();
674 }
675 break;
676 }
677 case Instruction::IF_GT: {
678 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200679 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) > shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200680 int16_t offset = inst->VRegC_22t();
681 if (IsBackwardBranch(offset)) {
682 if (UNLIKELY(self->TestAllFlags())) {
683 CheckSuspend(self);
684 }
685 }
686 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200687 } else {
688 inst = inst->Next_2xx();
689 }
690 break;
691 }
692 case Instruction::IF_LE: {
693 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200694 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <= shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200695 int16_t offset = inst->VRegC_22t();
696 if (IsBackwardBranch(offset)) {
697 if (UNLIKELY(self->TestAllFlags())) {
698 CheckSuspend(self);
699 }
700 }
701 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200702 } else {
703 inst = inst->Next_2xx();
704 }
705 break;
706 }
707 case Instruction::IF_EQZ: {
708 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200709 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200710 int16_t offset = inst->VRegB_21t();
711 if (IsBackwardBranch(offset)) {
712 if (UNLIKELY(self->TestAllFlags())) {
713 CheckSuspend(self);
714 }
715 }
716 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200717 } else {
718 inst = inst->Next_2xx();
719 }
720 break;
721 }
722 case Instruction::IF_NEZ: {
723 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200724 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200725 int16_t offset = inst->VRegB_21t();
726 if (IsBackwardBranch(offset)) {
727 if (UNLIKELY(self->TestAllFlags())) {
728 CheckSuspend(self);
729 }
730 }
731 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200732 } else {
733 inst = inst->Next_2xx();
734 }
735 break;
736 }
737 case Instruction::IF_LTZ: {
738 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200739 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200740 int16_t offset = inst->VRegB_21t();
741 if (IsBackwardBranch(offset)) {
742 if (UNLIKELY(self->TestAllFlags())) {
743 CheckSuspend(self);
744 }
745 }
746 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200747 } else {
748 inst = inst->Next_2xx();
749 }
750 break;
751 }
752 case Instruction::IF_GEZ: {
753 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200754 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200755 int16_t offset = inst->VRegB_21t();
756 if (IsBackwardBranch(offset)) {
757 if (UNLIKELY(self->TestAllFlags())) {
758 CheckSuspend(self);
759 }
760 }
761 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200762 } else {
763 inst = inst->Next_2xx();
764 }
765 break;
766 }
767 case Instruction::IF_GTZ: {
768 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200769 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200770 int16_t offset = inst->VRegB_21t();
771 if (IsBackwardBranch(offset)) {
772 if (UNLIKELY(self->TestAllFlags())) {
773 CheckSuspend(self);
774 }
775 }
776 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200777 } else {
778 inst = inst->Next_2xx();
779 }
780 break;
781 }
782 case Instruction::IF_LEZ: {
783 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200784 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200785 int16_t offset = inst->VRegB_21t();
786 if (IsBackwardBranch(offset)) {
787 if (UNLIKELY(self->TestAllFlags())) {
788 CheckSuspend(self);
789 }
790 }
791 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200792 } else {
793 inst = inst->Next_2xx();
794 }
795 break;
796 }
797 case Instruction::AGET_BOOLEAN: {
798 PREAMBLE();
799 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
800 if (UNLIKELY(a == NULL)) {
801 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
802 HANDLE_PENDING_EXCEPTION();
803 break;
804 }
805 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
806 BooleanArray* array = a->AsBooleanArray();
807 if (LIKELY(array->IsValidIndex(index))) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200808 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetData()[index]);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200809 inst = inst->Next_2xx();
810 } else {
811 HANDLE_PENDING_EXCEPTION();
812 }
813 break;
814 }
815 case Instruction::AGET_BYTE: {
816 PREAMBLE();
817 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
818 if (UNLIKELY(a == NULL)) {
819 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
820 HANDLE_PENDING_EXCEPTION();
821 break;
822 }
823 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
824 ByteArray* array = a->AsByteArray();
825 if (LIKELY(array->IsValidIndex(index))) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200826 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetData()[index]);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200827 inst = inst->Next_2xx();
828 } else {
829 HANDLE_PENDING_EXCEPTION();
830 }
831 break;
832 }
833 case Instruction::AGET_CHAR: {
834 PREAMBLE();
835 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
836 if (UNLIKELY(a == NULL)) {
837 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
838 HANDLE_PENDING_EXCEPTION();
839 break;
840 }
841 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
842 CharArray* array = a->AsCharArray();
843 if (LIKELY(array->IsValidIndex(index))) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200844 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetData()[index]);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200845 inst = inst->Next_2xx();
846 } else {
847 HANDLE_PENDING_EXCEPTION();
848 }
849 break;
850 }
851 case Instruction::AGET_SHORT: {
852 PREAMBLE();
853 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
854 if (UNLIKELY(a == NULL)) {
855 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
856 HANDLE_PENDING_EXCEPTION();
857 break;
858 }
859 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
860 ShortArray* array = a->AsShortArray();
861 if (LIKELY(array->IsValidIndex(index))) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200862 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetData()[index]);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200863 inst = inst->Next_2xx();
864 } else {
865 HANDLE_PENDING_EXCEPTION();
866 }
867 break;
868 }
869 case Instruction::AGET: {
870 PREAMBLE();
871 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
872 if (UNLIKELY(a == NULL)) {
873 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
874 HANDLE_PENDING_EXCEPTION();
875 break;
876 }
877 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
878 IntArray* array = a->AsIntArray();
879 if (LIKELY(array->IsValidIndex(index))) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200880 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetData()[index]);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200881 inst = inst->Next_2xx();
882 } else {
883 HANDLE_PENDING_EXCEPTION();
884 }
885 break;
886 }
887 case Instruction::AGET_WIDE: {
888 PREAMBLE();
889 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
890 if (UNLIKELY(a == NULL)) {
891 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
892 HANDLE_PENDING_EXCEPTION();
893 break;
894 }
895 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
896 LongArray* array = a->AsLongArray();
897 if (LIKELY(array->IsValidIndex(index))) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200898 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetData()[index]);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200899 inst = inst->Next_2xx();
900 } else {
901 HANDLE_PENDING_EXCEPTION();
902 }
903 break;
904 }
905 case Instruction::AGET_OBJECT: {
906 PREAMBLE();
907 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
908 if (UNLIKELY(a == NULL)) {
909 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
910 HANDLE_PENDING_EXCEPTION();
911 break;
912 }
913 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
914 ObjectArray<Object>* array = a->AsObjectArray<Object>();
915 if (LIKELY(array->IsValidIndex(index))) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200916 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200917 inst = inst->Next_2xx();
918 } else {
919 HANDLE_PENDING_EXCEPTION();
920 }
921 break;
922 }
923 case Instruction::APUT_BOOLEAN: {
924 PREAMBLE();
925 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
926 if (UNLIKELY(a == NULL)) {
927 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
928 HANDLE_PENDING_EXCEPTION();
929 break;
930 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200931 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200932 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
933 BooleanArray* array = a->AsBooleanArray();
934 if (LIKELY(array->IsValidIndex(index))) {
935 array->GetData()[index] = val;
936 inst = inst->Next_2xx();
937 } else {
938 HANDLE_PENDING_EXCEPTION();
939 }
940 break;
941 }
942 case Instruction::APUT_BYTE: {
943 PREAMBLE();
944 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
945 if (UNLIKELY(a == NULL)) {
946 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
947 HANDLE_PENDING_EXCEPTION();
948 break;
949 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200950 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200951 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
952 ByteArray* array = a->AsByteArray();
953 if (LIKELY(array->IsValidIndex(index))) {
954 array->GetData()[index] = val;
955 inst = inst->Next_2xx();
956 } else {
957 HANDLE_PENDING_EXCEPTION();
958 }
959 break;
960 }
961 case Instruction::APUT_CHAR: {
962 PREAMBLE();
963 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
964 if (UNLIKELY(a == NULL)) {
965 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
966 HANDLE_PENDING_EXCEPTION();
967 break;
968 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200969 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200970 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
971 CharArray* array = a->AsCharArray();
972 if (LIKELY(array->IsValidIndex(index))) {
973 array->GetData()[index] = val;
974 inst = inst->Next_2xx();
975 } else {
976 HANDLE_PENDING_EXCEPTION();
977 }
978 break;
979 }
980 case Instruction::APUT_SHORT: {
981 PREAMBLE();
982 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
983 if (UNLIKELY(a == NULL)) {
984 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
985 HANDLE_PENDING_EXCEPTION();
986 break;
987 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200988 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200989 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
990 ShortArray* array = a->AsShortArray();
991 if (LIKELY(array->IsValidIndex(index))) {
992 array->GetData()[index] = val;
993 inst = inst->Next_2xx();
994 } else {
995 HANDLE_PENDING_EXCEPTION();
996 }
997 break;
998 }
999 case Instruction::APUT: {
1000 PREAMBLE();
1001 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1002 if (UNLIKELY(a == NULL)) {
1003 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
1004 HANDLE_PENDING_EXCEPTION();
1005 break;
1006 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001007 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001008 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1009 IntArray* array = a->AsIntArray();
1010 if (LIKELY(array->IsValidIndex(index))) {
1011 array->GetData()[index] = val;
1012 inst = inst->Next_2xx();
1013 } else {
1014 HANDLE_PENDING_EXCEPTION();
1015 }
1016 break;
1017 }
1018 case Instruction::APUT_WIDE: {
1019 PREAMBLE();
1020 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1021 if (UNLIKELY(a == NULL)) {
1022 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
1023 HANDLE_PENDING_EXCEPTION();
1024 break;
1025 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001026 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001027 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1028 LongArray* array = a->AsLongArray();
1029 if (LIKELY(array->IsValidIndex(index))) {
1030 array->GetData()[index] = val;
1031 inst = inst->Next_2xx();
1032 } else {
1033 HANDLE_PENDING_EXCEPTION();
1034 }
1035 break;
1036 }
1037 case Instruction::APUT_OBJECT: {
1038 PREAMBLE();
1039 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1040 if (UNLIKELY(a == NULL)) {
1041 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
1042 HANDLE_PENDING_EXCEPTION();
1043 break;
1044 }
1045 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001046 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001047 ObjectArray<Object>* array = a->AsObjectArray<Object>();
1048 if (LIKELY(array->IsValidIndex(index) && array->CheckAssignable(val))) {
1049 array->SetWithoutChecks(index, val);
1050 inst = inst->Next_2xx();
1051 } else {
1052 HANDLE_PENDING_EXCEPTION();
1053 }
1054 break;
1055 }
1056 case Instruction::IGET_BOOLEAN: {
1057 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001058 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001059 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1060 break;
1061 }
1062 case Instruction::IGET_BYTE: {
1063 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001064 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001065 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1066 break;
1067 }
1068 case Instruction::IGET_CHAR: {
1069 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001070 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001071 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1072 break;
1073 }
1074 case Instruction::IGET_SHORT: {
1075 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001076 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001077 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1078 break;
1079 }
1080 case Instruction::IGET: {
1081 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001082 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001083 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1084 break;
1085 }
1086 case Instruction::IGET_WIDE: {
1087 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001088 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001089 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1090 break;
1091 }
1092 case Instruction::IGET_OBJECT: {
1093 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001094 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001095 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1096 break;
1097 }
1098 case Instruction::IGET_QUICK: {
1099 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001100 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001101 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1102 break;
1103 }
1104 case Instruction::IGET_WIDE_QUICK: {
1105 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001106 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001107 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1108 break;
1109 }
1110 case Instruction::IGET_OBJECT_QUICK: {
1111 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001112 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001113 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1114 break;
1115 }
1116 case Instruction::SGET_BOOLEAN: {
1117 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001118 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001119 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1120 break;
1121 }
1122 case Instruction::SGET_BYTE: {
1123 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001124 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001125 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1126 break;
1127 }
1128 case Instruction::SGET_CHAR: {
1129 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001130 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001131 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1132 break;
1133 }
1134 case Instruction::SGET_SHORT: {
1135 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001136 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001137 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1138 break;
1139 }
1140 case Instruction::SGET: {
1141 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001142 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001143 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1144 break;
1145 }
1146 case Instruction::SGET_WIDE: {
1147 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001148 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001149 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1150 break;
1151 }
1152 case Instruction::SGET_OBJECT: {
1153 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001154 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001155 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1156 break;
1157 }
1158 case Instruction::IPUT_BOOLEAN: {
1159 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001160 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001161 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1162 break;
1163 }
1164 case Instruction::IPUT_BYTE: {
1165 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001166 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001167 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1168 break;
1169 }
1170 case Instruction::IPUT_CHAR: {
1171 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001172 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001173 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1174 break;
1175 }
1176 case Instruction::IPUT_SHORT: {
1177 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001178 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001179 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1180 break;
1181 }
1182 case Instruction::IPUT: {
1183 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001184 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001185 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1186 break;
1187 }
1188 case Instruction::IPUT_WIDE: {
1189 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001190 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001191 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1192 break;
1193 }
1194 case Instruction::IPUT_OBJECT: {
1195 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001196 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001197 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1198 break;
1199 }
1200 case Instruction::IPUT_QUICK: {
1201 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001202 bool success = DoIPutQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001203 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1204 break;
1205 }
1206 case Instruction::IPUT_WIDE_QUICK: {
1207 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001208 bool success = DoIPutQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001209 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1210 break;
1211 }
1212 case Instruction::IPUT_OBJECT_QUICK: {
1213 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001214 bool success = DoIPutQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001215 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1216 break;
1217 }
1218 case Instruction::SPUT_BOOLEAN: {
1219 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001220 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001221 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1222 break;
1223 }
1224 case Instruction::SPUT_BYTE: {
1225 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001226 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001227 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1228 break;
1229 }
1230 case Instruction::SPUT_CHAR: {
1231 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001232 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001233 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1234 break;
1235 }
1236 case Instruction::SPUT_SHORT: {
1237 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001238 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001239 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1240 break;
1241 }
1242 case Instruction::SPUT: {
1243 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001244 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001245 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1246 break;
1247 }
1248 case Instruction::SPUT_WIDE: {
1249 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001250 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001251 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1252 break;
1253 }
1254 case Instruction::SPUT_OBJECT: {
1255 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001256 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001257 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1258 break;
1259 }
1260 case Instruction::INVOKE_VIRTUAL: {
1261 PREAMBLE();
1262 bool success = DoInvoke<kVirtual, false, do_access_check>(self, shadow_frame, inst, &result_register);
1263 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1264 break;
1265 }
1266 case Instruction::INVOKE_VIRTUAL_RANGE: {
1267 PREAMBLE();
1268 bool success = DoInvoke<kVirtual, true, do_access_check>(self, shadow_frame, inst, &result_register);
1269 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1270 break;
1271 }
1272 case Instruction::INVOKE_SUPER: {
1273 PREAMBLE();
1274 bool success = DoInvoke<kSuper, false, do_access_check>(self, shadow_frame, inst, &result_register);
1275 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1276 break;
1277 }
1278 case Instruction::INVOKE_SUPER_RANGE: {
1279 PREAMBLE();
1280 bool success = DoInvoke<kSuper, true, do_access_check>(self, shadow_frame, inst, &result_register);
1281 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1282 break;
1283 }
1284 case Instruction::INVOKE_DIRECT: {
1285 PREAMBLE();
1286 bool success = DoInvoke<kDirect, false, do_access_check>(self, shadow_frame, inst, &result_register);
1287 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1288 break;
1289 }
1290 case Instruction::INVOKE_DIRECT_RANGE: {
1291 PREAMBLE();
1292 bool success = DoInvoke<kDirect, true, do_access_check>(self, shadow_frame, inst, &result_register);
1293 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1294 break;
1295 }
1296 case Instruction::INVOKE_INTERFACE: {
1297 PREAMBLE();
1298 bool success = DoInvoke<kInterface, false, do_access_check>(self, shadow_frame, inst, &result_register);
1299 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1300 break;
1301 }
1302 case Instruction::INVOKE_INTERFACE_RANGE: {
1303 PREAMBLE();
1304 bool success = DoInvoke<kInterface, true, do_access_check>(self, shadow_frame, inst, &result_register);
1305 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1306 break;
1307 }
1308 case Instruction::INVOKE_STATIC: {
1309 PREAMBLE();
1310 bool success = DoInvoke<kStatic, false, do_access_check>(self, shadow_frame, inst, &result_register);
1311 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1312 break;
1313 }
1314 case Instruction::INVOKE_STATIC_RANGE: {
1315 PREAMBLE();
1316 bool success = DoInvoke<kStatic, true, do_access_check>(self, shadow_frame, inst, &result_register);
1317 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1318 break;
1319 }
1320 case Instruction::INVOKE_VIRTUAL_QUICK: {
1321 PREAMBLE();
1322 bool success = DoInvokeVirtualQuick<false>(self, shadow_frame, inst, &result_register);
1323 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1324 break;
1325 }
1326 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
1327 PREAMBLE();
1328 bool success = DoInvokeVirtualQuick<true>(self, shadow_frame, inst, &result_register);
1329 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1330 break;
1331 }
1332 case Instruction::NEG_INT:
1333 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001334 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001335 inst = inst->Next_1xx();
1336 break;
1337 case Instruction::NOT_INT:
1338 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001339 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001340 inst = inst->Next_1xx();
1341 break;
1342 case Instruction::NEG_LONG:
1343 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001344 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001345 inst = inst->Next_1xx();
1346 break;
1347 case Instruction::NOT_LONG:
1348 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001349 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001350 inst = inst->Next_1xx();
1351 break;
1352 case Instruction::NEG_FLOAT:
1353 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001354 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001355 inst = inst->Next_1xx();
1356 break;
1357 case Instruction::NEG_DOUBLE:
1358 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001359 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001360 inst = inst->Next_1xx();
1361 break;
1362 case Instruction::INT_TO_LONG:
1363 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001364 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
1365 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001366 inst = inst->Next_1xx();
1367 break;
1368 case Instruction::INT_TO_FLOAT:
1369 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001370 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1371 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001372 inst = inst->Next_1xx();
1373 break;
1374 case Instruction::INT_TO_DOUBLE:
1375 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001376 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1377 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001378 inst = inst->Next_1xx();
1379 break;
1380 case Instruction::LONG_TO_INT:
1381 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001382 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1383 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001384 inst = inst->Next_1xx();
1385 break;
1386 case Instruction::LONG_TO_FLOAT:
1387 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001388 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1389 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001390 inst = inst->Next_1xx();
1391 break;
1392 case Instruction::LONG_TO_DOUBLE:
1393 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001394 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1395 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001396 inst = inst->Next_1xx();
1397 break;
1398 case Instruction::FLOAT_TO_INT: {
1399 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001400 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001401 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001402 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001403 inst = inst->Next_1xx();
1404 break;
1405 }
1406 case Instruction::FLOAT_TO_LONG: {
1407 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001408 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001409 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001410 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001411 inst = inst->Next_1xx();
1412 break;
1413 }
1414 case Instruction::FLOAT_TO_DOUBLE:
1415 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001416 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1417 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001418 inst = inst->Next_1xx();
1419 break;
1420 case Instruction::DOUBLE_TO_INT: {
1421 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001422 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001423 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001424 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001425 inst = inst->Next_1xx();
1426 break;
1427 }
1428 case Instruction::DOUBLE_TO_LONG: {
1429 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001430 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001431 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001432 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001433 inst = inst->Next_1xx();
1434 break;
1435 }
1436 case Instruction::DOUBLE_TO_FLOAT:
1437 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001438 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1439 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001440 inst = inst->Next_1xx();
1441 break;
1442 case Instruction::INT_TO_BYTE:
1443 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001444 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1445 static_cast<int8_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001446 inst = inst->Next_1xx();
1447 break;
1448 case Instruction::INT_TO_CHAR:
1449 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001450 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1451 static_cast<uint16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001452 inst = inst->Next_1xx();
1453 break;
1454 case Instruction::INT_TO_SHORT:
1455 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001456 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1457 static_cast<int16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001458 inst = inst->Next_1xx();
1459 break;
1460 case Instruction::ADD_INT:
1461 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001462 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001463 shadow_frame.GetVReg(inst->VRegB_23x()) +
1464 shadow_frame.GetVReg(inst->VRegC_23x()));
1465 inst = inst->Next_2xx();
1466 break;
1467 case Instruction::SUB_INT:
1468 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001469 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001470 shadow_frame.GetVReg(inst->VRegB_23x()) -
1471 shadow_frame.GetVReg(inst->VRegC_23x()));
1472 inst = inst->Next_2xx();
1473 break;
1474 case Instruction::MUL_INT:
1475 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001476 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001477 shadow_frame.GetVReg(inst->VRegB_23x()) *
1478 shadow_frame.GetVReg(inst->VRegC_23x()));
1479 inst = inst->Next_2xx();
1480 break;
1481 case Instruction::DIV_INT: {
1482 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001483 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001484 shadow_frame.GetVReg(inst->VRegB_23x()),
1485 shadow_frame.GetVReg(inst->VRegC_23x()));
1486 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1487 break;
1488 }
1489 case Instruction::REM_INT: {
1490 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001491 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001492 shadow_frame.GetVReg(inst->VRegB_23x()),
1493 shadow_frame.GetVReg(inst->VRegC_23x()));
1494 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1495 break;
1496 }
1497 case Instruction::SHL_INT:
1498 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001499 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001500 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1501 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1502 inst = inst->Next_2xx();
1503 break;
1504 case Instruction::SHR_INT:
1505 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001506 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001507 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1508 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1509 inst = inst->Next_2xx();
1510 break;
1511 case Instruction::USHR_INT:
1512 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001513 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001514 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1515 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1516 inst = inst->Next_2xx();
1517 break;
1518 case Instruction::AND_INT:
1519 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001520 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001521 shadow_frame.GetVReg(inst->VRegB_23x()) &
1522 shadow_frame.GetVReg(inst->VRegC_23x()));
1523 inst = inst->Next_2xx();
1524 break;
1525 case Instruction::OR_INT:
1526 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001527 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001528 shadow_frame.GetVReg(inst->VRegB_23x()) |
1529 shadow_frame.GetVReg(inst->VRegC_23x()));
1530 inst = inst->Next_2xx();
1531 break;
1532 case Instruction::XOR_INT:
1533 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001534 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001535 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1536 shadow_frame.GetVReg(inst->VRegC_23x()));
1537 inst = inst->Next_2xx();
1538 break;
1539 case Instruction::ADD_LONG:
1540 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001541 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001542 shadow_frame.GetVRegLong(inst->VRegB_23x()) +
1543 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1544 inst = inst->Next_2xx();
1545 break;
1546 case Instruction::SUB_LONG:
1547 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001548 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001549 shadow_frame.GetVRegLong(inst->VRegB_23x()) -
1550 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1551 inst = inst->Next_2xx();
1552 break;
1553 case Instruction::MUL_LONG:
1554 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001555 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001556 shadow_frame.GetVRegLong(inst->VRegB_23x()) *
1557 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1558 inst = inst->Next_2xx();
1559 break;
1560 case Instruction::DIV_LONG:
1561 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001562 DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001563 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1564 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1565 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1566 break;
1567 case Instruction::REM_LONG:
1568 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001569 DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001570 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1571 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1572 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1573 break;
1574 case Instruction::AND_LONG:
1575 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001576 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001577 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1578 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1579 inst = inst->Next_2xx();
1580 break;
1581 case Instruction::OR_LONG:
1582 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001583 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001584 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1585 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1586 inst = inst->Next_2xx();
1587 break;
1588 case Instruction::XOR_LONG:
1589 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001590 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001591 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1592 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1593 inst = inst->Next_2xx();
1594 break;
1595 case Instruction::SHL_LONG:
1596 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001597 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001598 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1599 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1600 inst = inst->Next_2xx();
1601 break;
1602 case Instruction::SHR_LONG:
1603 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001604 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001605 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1606 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1607 inst = inst->Next_2xx();
1608 break;
1609 case Instruction::USHR_LONG:
1610 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001611 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001612 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1613 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1614 inst = inst->Next_2xx();
1615 break;
1616 case Instruction::ADD_FLOAT:
1617 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001618 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001619 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1620 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1621 inst = inst->Next_2xx();
1622 break;
1623 case Instruction::SUB_FLOAT:
1624 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001625 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001626 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1627 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1628 inst = inst->Next_2xx();
1629 break;
1630 case Instruction::MUL_FLOAT:
1631 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001632 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001633 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1634 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1635 inst = inst->Next_2xx();
1636 break;
1637 case Instruction::DIV_FLOAT:
1638 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001639 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001640 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1641 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1642 inst = inst->Next_2xx();
1643 break;
1644 case Instruction::REM_FLOAT:
1645 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001646 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001647 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1648 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1649 inst = inst->Next_2xx();
1650 break;
1651 case Instruction::ADD_DOUBLE:
1652 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001653 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001654 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1655 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1656 inst = inst->Next_2xx();
1657 break;
1658 case Instruction::SUB_DOUBLE:
1659 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001660 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001661 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1662 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1663 inst = inst->Next_2xx();
1664 break;
1665 case Instruction::MUL_DOUBLE:
1666 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001667 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001668 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
1669 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1670 inst = inst->Next_2xx();
1671 break;
1672 case Instruction::DIV_DOUBLE:
1673 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001674 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001675 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
1676 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1677 inst = inst->Next_2xx();
1678 break;
1679 case Instruction::REM_DOUBLE:
1680 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001681 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001682 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
1683 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
1684 inst = inst->Next_2xx();
1685 break;
1686 case Instruction::ADD_INT_2ADDR: {
1687 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001688 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001689 shadow_frame.SetVReg(vregA,
1690 shadow_frame.GetVReg(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001691 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001692 inst = inst->Next_1xx();
1693 break;
1694 }
1695 case Instruction::SUB_INT_2ADDR: {
1696 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001697 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001698 shadow_frame.SetVReg(vregA,
1699 shadow_frame.GetVReg(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001700 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001701 inst = inst->Next_1xx();
1702 break;
1703 }
1704 case Instruction::MUL_INT_2ADDR: {
1705 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001706 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001707 shadow_frame.SetVReg(vregA,
1708 shadow_frame.GetVReg(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001709 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001710 inst = inst->Next_1xx();
1711 break;
1712 }
1713 case Instruction::DIV_INT_2ADDR: {
1714 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001715 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001716 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001717 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001718 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1719 break;
1720 }
1721 case Instruction::REM_INT_2ADDR: {
1722 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001723 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001724 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001725 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001726 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1727 break;
1728 }
1729 case Instruction::SHL_INT_2ADDR: {
1730 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001731 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001732 shadow_frame.SetVReg(vregA,
1733 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001734 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001735 inst = inst->Next_1xx();
1736 break;
1737 }
1738 case Instruction::SHR_INT_2ADDR: {
1739 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001740 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001741 shadow_frame.SetVReg(vregA,
1742 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001743 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001744 inst = inst->Next_1xx();
1745 break;
1746 }
1747 case Instruction::USHR_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 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001752 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001753 inst = inst->Next_1xx();
1754 break;
1755 }
1756 case Instruction::AND_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::OR_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::XOR_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 shadow_frame.SetVReg(vregA,
1778 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001779 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001780 inst = inst->Next_1xx();
1781 break;
1782 }
1783 case Instruction::ADD_LONG_2ADDR: {
1784 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001785 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001786 shadow_frame.SetVRegLong(vregA,
1787 shadow_frame.GetVRegLong(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001788 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001789 inst = inst->Next_1xx();
1790 break;
1791 }
1792 case Instruction::SUB_LONG_2ADDR: {
1793 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001794 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001795 shadow_frame.SetVRegLong(vregA,
1796 shadow_frame.GetVRegLong(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001797 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001798 inst = inst->Next_1xx();
1799 break;
1800 }
1801 case Instruction::MUL_LONG_2ADDR: {
1802 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001803 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001804 shadow_frame.SetVRegLong(vregA,
1805 shadow_frame.GetVRegLong(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001806 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001807 inst = inst->Next_1xx();
1808 break;
1809 }
1810 case Instruction::DIV_LONG_2ADDR: {
1811 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001812 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001813 DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001814 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001815 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
1816 break;
1817 }
1818 case Instruction::REM_LONG_2ADDR: {
1819 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001820 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001821 DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001822 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001823 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
1824 break;
1825 }
1826 case Instruction::AND_LONG_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.SetVRegLong(vregA,
1830 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001831 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001832 inst = inst->Next_1xx();
1833 break;
1834 }
1835 case Instruction::OR_LONG_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.SetVRegLong(vregA,
1839 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001840 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001841 inst = inst->Next_1xx();
1842 break;
1843 }
1844 case Instruction::XOR_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::SHL_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.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001859 inst = inst->Next_1xx();
1860 break;
1861 }
1862 case Instruction::SHR_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.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001868 inst = inst->Next_1xx();
1869 break;
1870 }
1871 case Instruction::USHR_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 shadow_frame.SetVRegLong(vregA,
1875 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001876 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001877 inst = inst->Next_1xx();
1878 break;
1879 }
1880 case Instruction::ADD_FLOAT_2ADDR: {
1881 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001882 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001883 shadow_frame.SetVRegFloat(vregA,
1884 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001885 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001886 inst = inst->Next_1xx();
1887 break;
1888 }
1889 case Instruction::SUB_FLOAT_2ADDR: {
1890 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001891 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001892 shadow_frame.SetVRegFloat(vregA,
1893 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001894 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001895 inst = inst->Next_1xx();
1896 break;
1897 }
1898 case Instruction::MUL_FLOAT_2ADDR: {
1899 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001900 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001901 shadow_frame.SetVRegFloat(vregA,
1902 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001903 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001904 inst = inst->Next_1xx();
1905 break;
1906 }
1907 case Instruction::DIV_FLOAT_2ADDR: {
1908 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001909 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001910 shadow_frame.SetVRegFloat(vregA,
1911 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001912 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001913 inst = inst->Next_1xx();
1914 break;
1915 }
1916 case Instruction::REM_FLOAT_2ADDR: {
1917 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001918 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001919 shadow_frame.SetVRegFloat(vregA,
1920 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001921 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001922 inst = inst->Next_1xx();
1923 break;
1924 }
1925 case Instruction::ADD_DOUBLE_2ADDR: {
1926 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001927 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001928 shadow_frame.SetVRegDouble(vregA,
1929 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001930 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001931 inst = inst->Next_1xx();
1932 break;
1933 }
1934 case Instruction::SUB_DOUBLE_2ADDR: {
1935 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001936 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001937 shadow_frame.SetVRegDouble(vregA,
1938 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001939 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001940 inst = inst->Next_1xx();
1941 break;
1942 }
1943 case Instruction::MUL_DOUBLE_2ADDR: {
1944 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001945 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001946 shadow_frame.SetVRegDouble(vregA,
1947 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001948 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001949 inst = inst->Next_1xx();
1950 break;
1951 }
1952 case Instruction::DIV_DOUBLE_2ADDR: {
1953 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001954 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001955 shadow_frame.SetVRegDouble(vregA,
1956 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001957 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001958 inst = inst->Next_1xx();
1959 break;
1960 }
1961 case Instruction::REM_DOUBLE_2ADDR: {
1962 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001963 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001964 shadow_frame.SetVRegDouble(vregA,
1965 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001966 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001967 inst = inst->Next_1xx();
1968 break;
1969 }
1970 case Instruction::ADD_INT_LIT16:
1971 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001972 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
1973 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) +
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001974 inst->VRegC_22s());
1975 inst = inst->Next_2xx();
1976 break;
1977 case Instruction::RSUB_INT:
1978 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001979 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001980 inst->VRegC_22s() -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001981 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001982 inst = inst->Next_2xx();
1983 break;
1984 case Instruction::MUL_INT_LIT16:
1985 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001986 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
1987 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) *
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001988 inst->VRegC_22s());
1989 inst = inst->Next_2xx();
1990 break;
1991 case Instruction::DIV_INT_LIT16: {
1992 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001993 bool success = DoIntDivide(shadow_frame, inst->VRegA_22s(inst_data),
1994 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)), inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001995 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1996 break;
1997 }
1998 case Instruction::REM_INT_LIT16: {
1999 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002000 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22s(inst_data),
2001 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)), inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002002 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2003 break;
2004 }
2005 case Instruction::AND_INT_LIT16:
2006 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002007 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2008 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002009 inst->VRegC_22s());
2010 inst = inst->Next_2xx();
2011 break;
2012 case Instruction::OR_INT_LIT16:
2013 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002014 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2015 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002016 inst->VRegC_22s());
2017 inst = inst->Next_2xx();
2018 break;
2019 case Instruction::XOR_INT_LIT16:
2020 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002021 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2022 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002023 inst->VRegC_22s());
2024 inst = inst->Next_2xx();
2025 break;
2026 case Instruction::ADD_INT_LIT8:
2027 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002028 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002029 shadow_frame.GetVReg(inst->VRegB_22b()) +
2030 inst->VRegC_22b());
2031 inst = inst->Next_2xx();
2032 break;
2033 case Instruction::RSUB_INT_LIT8:
2034 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002035 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002036 inst->VRegC_22b() -
2037 shadow_frame.GetVReg(inst->VRegB_22b()));
2038 inst = inst->Next_2xx();
2039 break;
2040 case Instruction::MUL_INT_LIT8:
2041 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002042 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002043 shadow_frame.GetVReg(inst->VRegB_22b()) *
2044 inst->VRegC_22b());
2045 inst = inst->Next_2xx();
2046 break;
2047 case Instruction::DIV_INT_LIT8: {
2048 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002049 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002050 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2051 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2052 break;
2053 }
2054 case Instruction::REM_INT_LIT8: {
2055 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002056 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002057 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2058 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2059 break;
2060 }
2061 case Instruction::AND_INT_LIT8:
2062 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002063 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002064 shadow_frame.GetVReg(inst->VRegB_22b()) &
2065 inst->VRegC_22b());
2066 inst = inst->Next_2xx();
2067 break;
2068 case Instruction::OR_INT_LIT8:
2069 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002070 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002071 shadow_frame.GetVReg(inst->VRegB_22b()) |
2072 inst->VRegC_22b());
2073 inst = inst->Next_2xx();
2074 break;
2075 case Instruction::XOR_INT_LIT8:
2076 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002077 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002078 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2079 inst->VRegC_22b());
2080 inst = inst->Next_2xx();
2081 break;
2082 case Instruction::SHL_INT_LIT8:
2083 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002084 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002085 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2086 (inst->VRegC_22b() & 0x1f));
2087 inst = inst->Next_2xx();
2088 break;
2089 case Instruction::SHR_INT_LIT8:
2090 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002091 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002092 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2093 (inst->VRegC_22b() & 0x1f));
2094 inst = inst->Next_2xx();
2095 break;
2096 case Instruction::USHR_INT_LIT8:
2097 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002098 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002099 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2100 (inst->VRegC_22b() & 0x1f));
2101 inst = inst->Next_2xx();
2102 break;
2103 case Instruction::UNUSED_3E ... Instruction::UNUSED_43:
2104 case Instruction::UNUSED_EB ... Instruction::UNUSED_FF:
2105 case Instruction::UNUSED_79:
2106 case Instruction::UNUSED_7A:
2107 UnexpectedOpcode(inst, mh);
2108 }
2109 }
2110} // NOLINT(readability/fn_size)
2111
2112// Explicit definitions of ExecuteSwitchImpl.
2113template JValue ExecuteSwitchImpl<true>(Thread* self, MethodHelper& mh,
2114 const DexFile::CodeItem* code_item,
2115 ShadowFrame& shadow_frame, JValue result_register);
2116template JValue ExecuteSwitchImpl<false>(Thread* self, MethodHelper& mh,
2117 const DexFile::CodeItem* code_item,
2118 ShadowFrame& shadow_frame, JValue result_register);
2119
2120} // namespace interpreter
2121} // namespace art