blob: b0d7fb247a5f709df4c0b4274442207f05bf03ed [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
Andreas Gampe5e26eb12016-08-22 17:54:17 -070017#include "interpreter_switch_impl.h"
18
Andreas Gampe542451c2016-07-26 09:02:02 -070019#include "base/enums.h"
Alex Lighteb7c1442015-08-31 13:17:42 -070020#include "experimental_flags.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020021#include "interpreter_common.h"
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000022#include "jit/jit.h"
Mathieu Chartier28bd2e42016-10-04 13:54:57 -070023#include "jvalue-inl.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070024#include "safe_math.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020025
26namespace art {
27namespace interpreter {
28
29#define HANDLE_PENDING_EXCEPTION() \
30 do { \
Sebastien Hertz82aeddb2014-05-20 20:09:45 +020031 DCHECK(self->IsExceptionPending()); \
Ian Rogers7b078e82014-09-10 14:44:24 -070032 self->AllowThreadSuspension(); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020033 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, \
34 inst->GetDexPc(insns), \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020035 instrumentation); \
36 if (found_dex_pc == DexFile::kDexNoIndex) { \
Andreas Gampe03ec9302015-08-27 17:41:47 -070037 /* Structured locking is to be enforced for abnormal termination, too. */ \
Andreas Gampe56fdd0e2016-04-28 14:56:54 -070038 DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame); \
buzbee1452bee2015-03-06 14:43:04 -080039 if (interpret_one_instruction) { \
buzbee93e94f22016-04-07 13:52:48 -070040 /* Signal mterp to return to caller */ \
buzbee1452bee2015-03-06 14:43:04 -080041 shadow_frame.SetDexPC(DexFile::kDexNoIndex); \
42 } \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020043 return JValue(); /* Handled in caller. */ \
44 } else { \
45 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc); \
46 inst = inst->RelativeAt(displacement); \
47 } \
48 } while (false)
49
50#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _next_function) \
51 do { \
52 if (UNLIKELY(_is_exception_pending)) { \
53 HANDLE_PENDING_EXCEPTION(); \
54 } else { \
55 inst = inst->_next_function(); \
56 } \
57 } while (false)
58
Andreas Gampe03ec9302015-08-27 17:41:47 -070059#define HANDLE_MONITOR_CHECKS() \
Andreas Gampe56fdd0e2016-04-28 14:56:54 -070060 if (!DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame)) { \
Andreas Gampe03ec9302015-08-27 17:41:47 -070061 HANDLE_PENDING_EXCEPTION(); \
62 }
63
Sebastien Hertz8ece0502013-08-07 11:26:41 +020064// Code to run before each dex instruction.
Sebastien Hertz8379b222014-02-24 17:38:15 +010065#define PREAMBLE() \
66 do { \
Sebastien Hertz9d6bf692015-04-10 12:12:33 +020067 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
Sebastien Hertz8379b222014-02-24 17:38:15 +010068 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), \
69 shadow_frame.GetMethod(), dex_pc); \
70 } \
71 } while (false)
Sebastien Hertz8ece0502013-08-07 11:26:41 +020072
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000073#define BRANCH_INSTRUMENTATION(offset) \
74 do { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010075 if (UNLIKELY(instrumentation->HasBranchListeners())) { \
76 instrumentation->Branch(self, method, dex_pc, offset); \
77 } \
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000078 JValue result; \
79 if (jit::Jit::MaybeDoOnStackReplacement(self, method, dex_pc, offset, &result)) { \
buzbee93e94f22016-04-07 13:52:48 -070080 if (interpret_one_instruction) { \
81 /* OSR has completed execution of the method. Signal mterp to return to caller */ \
82 shadow_frame.SetDexPC(DexFile::kDexNoIndex); \
83 } \
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000084 return result; \
85 } \
Nicolas Geoffray3108daf2015-11-24 16:32:33 +000086 } while (false)
87
Bill Buzbee1d011d92016-04-04 16:59:29 +000088#define HOTNESS_UPDATE() \
89 do { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010090 if (jit != nullptr) { \
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +010091 jit->AddSamples(self, method, 1, /*with_backedges*/ true); \
Bill Buzbee1d011d92016-04-04 16:59:29 +000092 } \
93 } while (false)
94
Andreas Gampef4f76372016-12-13 14:43:58 -080095#define HANDLE_BACKWARD_BRANCH(offset) \
96 do { \
97 if (IsBackwardBranch(offset)) { \
98 HOTNESS_UPDATE(); \
99 /* Record new dex pc early to have consistent suspend point at loop header. */ \
100 shadow_frame.SetDexPC(inst->GetDexPc(insns)); \
101 self->AllowThreadSuspension(); \
102 } \
103 } while (false)
104
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100105template<bool do_access_check, bool transaction_active>
Ian Rogerse94652f2014-12-02 11:13:19 -0800106JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -0800107 ShadowFrame& shadow_frame, JValue result_register,
108 bool interpret_one_instruction) {
Igor Murashkinc449e8b2015-06-10 15:56:42 -0700109 constexpr bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200110 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
111 LOG(FATAL) << "Invalid shadow frame for interpreter use";
112 return JValue();
113 }
114 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200115
116 uint32_t dex_pc = shadow_frame.GetDexPC();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700117 const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200118 const uint16_t* const insns = code_item->insns_;
119 const Instruction* inst = Instruction::At(insns + dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200120 uint16_t inst_data;
Bill Buzbee1d011d92016-04-04 16:59:29 +0000121 ArtMethod* method = shadow_frame.GetMethod();
122 jit::Jit* jit = Runtime::Current()->GetJit();
Igor Murashkin6918bf12015-09-27 19:19:06 -0700123
buzbee1452bee2015-03-06 14:43:04 -0800124 do {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200125 dex_pc = inst->GetDexPc(insns);
126 shadow_frame.SetDexPC(dex_pc);
Ian Rogerse94652f2014-12-02 11:13:19 -0800127 TraceExecution(shadow_frame, inst, dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200128 inst_data = inst->Fetch16(0);
129 switch (inst->Opcode(inst_data)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200130 case Instruction::NOP:
131 PREAMBLE();
132 inst = inst->Next_1xx();
133 break;
134 case Instruction::MOVE:
135 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200136 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
137 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200138 inst = inst->Next_1xx();
139 break;
140 case Instruction::MOVE_FROM16:
141 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200142 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200143 shadow_frame.GetVReg(inst->VRegB_22x()));
144 inst = inst->Next_2xx();
145 break;
146 case Instruction::MOVE_16:
147 PREAMBLE();
148 shadow_frame.SetVReg(inst->VRegA_32x(),
149 shadow_frame.GetVReg(inst->VRegB_32x()));
150 inst = inst->Next_3xx();
151 break;
152 case Instruction::MOVE_WIDE:
153 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200154 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
155 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200156 inst = inst->Next_1xx();
157 break;
158 case Instruction::MOVE_WIDE_FROM16:
159 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200160 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200161 shadow_frame.GetVRegLong(inst->VRegB_22x()));
162 inst = inst->Next_2xx();
163 break;
164 case Instruction::MOVE_WIDE_16:
165 PREAMBLE();
166 shadow_frame.SetVRegLong(inst->VRegA_32x(),
167 shadow_frame.GetVRegLong(inst->VRegB_32x()));
168 inst = inst->Next_3xx();
169 break;
170 case Instruction::MOVE_OBJECT:
171 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200172 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
173 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200174 inst = inst->Next_1xx();
175 break;
176 case Instruction::MOVE_OBJECT_FROM16:
177 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200178 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200179 shadow_frame.GetVRegReference(inst->VRegB_22x()));
180 inst = inst->Next_2xx();
181 break;
182 case Instruction::MOVE_OBJECT_16:
183 PREAMBLE();
184 shadow_frame.SetVRegReference(inst->VRegA_32x(),
185 shadow_frame.GetVRegReference(inst->VRegB_32x()));
186 inst = inst->Next_3xx();
187 break;
188 case Instruction::MOVE_RESULT:
189 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200190 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200191 inst = inst->Next_1xx();
192 break;
193 case Instruction::MOVE_RESULT_WIDE:
194 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200195 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200196 inst = inst->Next_1xx();
197 break;
198 case Instruction::MOVE_RESULT_OBJECT:
199 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200200 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200201 inst = inst->Next_1xx();
202 break;
203 case Instruction::MOVE_EXCEPTION: {
204 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700205 ObjPtr<mirror::Throwable> exception = self->GetException();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100206 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
Mathieu Chartieref41db72016-10-25 15:08:01 -0700207 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception.Ptr());
Sebastien Hertz5c004902014-05-21 10:07:42 +0200208 self->ClearException();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200209 inst = inst->Next_1xx();
210 break;
211 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700212 case Instruction::RETURN_VOID_NO_BARRIER: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200213 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200214 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700215 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700216 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200217 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200218 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200219 shadow_frame.GetMethod(), inst->GetDexPc(insns),
220 result);
221 }
buzbee1452bee2015-03-06 14:43:04 -0800222 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700223 /* Signal mterp to return to caller */
buzbee1452bee2015-03-06 14:43:04 -0800224 shadow_frame.SetDexPC(DexFile::kDexNoIndex);
225 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200226 return result;
227 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700228 case Instruction::RETURN_VOID: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200229 PREAMBLE();
Hans Boehm30359612014-05-21 17:46:23 -0700230 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200231 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700232 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700233 HANDLE_MONITOR_CHECKS();
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 }
buzbee1452bee2015-03-06 14:43:04 -0800239 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700240 /* Signal mterp to return to caller */
buzbee1452bee2015-03-06 14:43:04 -0800241 shadow_frame.SetDexPC(DexFile::kDexNoIndex);
242 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200243 return result;
244 }
245 case Instruction::RETURN: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200246 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200247 JValue result;
248 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200249 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700250 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700251 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200252 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200253 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200254 shadow_frame.GetMethod(), inst->GetDexPc(insns),
255 result);
256 }
buzbee1452bee2015-03-06 14:43:04 -0800257 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700258 /* Signal mterp to return to caller */
buzbee1452bee2015-03-06 14:43:04 -0800259 shadow_frame.SetDexPC(DexFile::kDexNoIndex);
260 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200261 return result;
262 }
263 case Instruction::RETURN_WIDE: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200264 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200265 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200266 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700267 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700268 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200269 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200270 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200271 shadow_frame.GetMethod(), inst->GetDexPc(insns),
272 result);
273 }
buzbee1452bee2015-03-06 14:43:04 -0800274 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700275 /* Signal mterp to return to caller */
buzbee1452bee2015-03-06 14:43:04 -0800276 shadow_frame.SetDexPC(DexFile::kDexNoIndex);
277 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200278 return result;
279 }
280 case Instruction::RETURN_OBJECT: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200281 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200282 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700283 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700284 HANDLE_MONITOR_CHECKS();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700285 const size_t ref_idx = inst->VRegA_11x(inst_data);
Mathieu Chartieref41db72016-10-25 15:08:01 -0700286 ObjPtr<mirror::Object> obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700287 if (do_assignability_check && obj_result != nullptr) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700288 PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700289 ObjPtr<mirror::Class> return_type = method->GetReturnType(true /* resolve */,
290 pointer_size);
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700291 // Re-load since it might have moved.
292 obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700293 if (return_type == nullptr) {
Jeff Haoa3faaf42013-09-03 19:07:00 -0700294 // Return the pending exception.
295 HANDLE_PENDING_EXCEPTION();
296 }
297 if (!obj_result->VerifierInstanceOf(return_type)) {
298 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700299 std::string temp1, temp2;
Orion Hodsonfef06642016-11-25 16:07:11 +0000300 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700301 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700302 obj_result->GetClass()->GetDescriptor(&temp1),
303 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700304 HANDLE_PENDING_EXCEPTION();
305 }
306 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700307 result.SetL(obj_result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200308 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200309 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200310 shadow_frame.GetMethod(), inst->GetDexPc(insns),
311 result);
312 }
buzbee1452bee2015-03-06 14:43:04 -0800313 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700314 /* Signal mterp to return to caller */
buzbee1452bee2015-03-06 14:43:04 -0800315 shadow_frame.SetDexPC(DexFile::kDexNoIndex);
316 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200317 return result;
318 }
319 case Instruction::CONST_4: {
320 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200321 uint4_t dst = inst->VRegA_11n(inst_data);
322 int4_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200323 shadow_frame.SetVReg(dst, val);
324 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700325 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200326 }
327 inst = inst->Next_1xx();
328 break;
329 }
330 case Instruction::CONST_16: {
331 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200332 uint8_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200333 int16_t val = inst->VRegB_21s();
334 shadow_frame.SetVReg(dst, val);
335 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700336 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200337 }
338 inst = inst->Next_2xx();
339 break;
340 }
341 case Instruction::CONST: {
342 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200343 uint8_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200344 int32_t val = inst->VRegB_31i();
345 shadow_frame.SetVReg(dst, val);
346 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700347 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200348 }
349 inst = inst->Next_3xx();
350 break;
351 }
352 case Instruction::CONST_HIGH16: {
353 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200354 uint8_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200355 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
356 shadow_frame.SetVReg(dst, val);
357 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700358 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200359 }
360 inst = inst->Next_2xx();
361 break;
362 }
363 case Instruction::CONST_WIDE_16:
364 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200365 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200366 inst = inst->Next_2xx();
367 break;
368 case Instruction::CONST_WIDE_32:
369 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200370 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200371 inst = inst->Next_3xx();
372 break;
373 case Instruction::CONST_WIDE:
374 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200375 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200376 inst = inst->Next_51l();
377 break;
378 case Instruction::CONST_WIDE_HIGH16:
Sebastien Hertz3c5aec12014-06-04 09:41:21 +0200379 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200380 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200381 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
382 inst = inst->Next_2xx();
383 break;
384 case Instruction::CONST_STRING: {
385 PREAMBLE();
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800386 ObjPtr<mirror::String> s = ResolveString(self,
387 shadow_frame,
388 dex::StringIndex(inst->VRegB_21c()));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700389 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200390 HANDLE_PENDING_EXCEPTION();
391 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700392 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s.Ptr());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200393 inst = inst->Next_2xx();
394 }
395 break;
396 }
397 case Instruction::CONST_STRING_JUMBO: {
398 PREAMBLE();
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800399 ObjPtr<mirror::String> s = ResolveString(self,
400 shadow_frame,
401 dex::StringIndex(inst->VRegB_31c()));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700402 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200403 HANDLE_PENDING_EXCEPTION();
404 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700405 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s.Ptr());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200406 inst = inst->Next_3xx();
407 }
408 break;
409 }
410 case Instruction::CONST_CLASS: {
411 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800412 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700413 shadow_frame.GetMethod(),
414 self,
415 false,
416 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700417 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200418 HANDLE_PENDING_EXCEPTION();
419 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700420 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c.Ptr());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200421 inst = inst->Next_2xx();
422 }
423 break;
424 }
425 case Instruction::MONITOR_ENTER: {
426 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700427 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700428 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000429 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200430 HANDLE_PENDING_EXCEPTION();
431 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700432 DoMonitorEnter<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200433 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
434 }
435 break;
436 }
437 case Instruction::MONITOR_EXIT: {
438 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700439 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700440 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000441 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200442 HANDLE_PENDING_EXCEPTION();
443 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700444 DoMonitorExit<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200445 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
446 }
447 break;
448 }
449 case Instruction::CHECK_CAST: {
450 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800451 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700452 shadow_frame.GetMethod(),
453 self,
454 false,
455 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700456 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200457 HANDLE_PENDING_EXCEPTION();
458 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700459 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700460 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200461 ThrowClassCastException(c, obj->GetClass());
462 HANDLE_PENDING_EXCEPTION();
463 } else {
464 inst = inst->Next_2xx();
465 }
466 }
467 break;
468 }
469 case Instruction::INSTANCE_OF: {
470 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800471 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegC_22c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700472 shadow_frame.GetMethod(),
473 self,
474 false,
475 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700476 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200477 HANDLE_PENDING_EXCEPTION();
478 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700479 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700480 shadow_frame.SetVReg(inst->VRegA_22c(inst_data),
481 (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200482 inst = inst->Next_2xx();
483 }
484 break;
485 }
486 case Instruction::ARRAY_LENGTH: {
487 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700488 ObjPtr<mirror::Object> array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700489 if (UNLIKELY(array == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000490 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200491 HANDLE_PENDING_EXCEPTION();
492 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200493 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200494 inst = inst->Next_1xx();
495 }
496 break;
497 }
498 case Instruction::NEW_INSTANCE: {
499 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700500 ObjPtr<mirror::Object> obj = nullptr;
Andreas Gampea5b09a62016-11-17 15:21:22 -0800501 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700502 shadow_frame.GetMethod(),
503 self,
504 false,
505 do_access_check);
Jeff Hao848f70a2014-01-15 13:49:50 -0800506 if (LIKELY(c != nullptr)) {
507 if (UNLIKELY(c->IsStringClass())) {
508 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
jessicahandojo3aaa37b2016-07-29 14:46:37 -0700509 obj = mirror::String::AllocEmptyString<true>(self, allocator_type);
Jeff Hao848f70a2014-01-15 13:49:50 -0800510 } else {
511 obj = AllocObjectFromCode<do_access_check, true>(
Andreas Gampea5b09a62016-11-17 15:21:22 -0800512 dex::TypeIndex(inst->VRegB_21c()),
513 shadow_frame.GetMethod(),
514 self,
515 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Jeff Hao848f70a2014-01-15 13:49:50 -0800516 }
517 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700518 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200519 HANDLE_PENDING_EXCEPTION();
520 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200521 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700522 // Don't allow finalizable objects to be allocated during a transaction since these can't
523 // be finalized without a started runtime.
524 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200525 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
David Sehr709b0702016-10-13 09:12:37 -0700526 obj->PrettyTypeOf().c_str());
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700527 HANDLE_PENDING_EXCEPTION();
528 break;
529 }
Mathieu Chartieref41db72016-10-25 15:08:01 -0700530 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj.Ptr());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200531 inst = inst->Next_2xx();
532 }
533 break;
534 }
535 case Instruction::NEW_ARRAY: {
536 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200537 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartieref41db72016-10-25 15:08:01 -0700538 ObjPtr<mirror::Object> obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampea5b09a62016-11-17 15:21:22 -0800539 dex::TypeIndex(inst->VRegC_22c()),
540 length,
541 shadow_frame.GetMethod(),
542 self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800543 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700544 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200545 HANDLE_PENDING_EXCEPTION();
546 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700547 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj.Ptr());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200548 inst = inst->Next_2xx();
549 }
550 break;
551 }
552 case Instruction::FILLED_NEW_ARRAY: {
553 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100554 bool success =
555 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame, self,
556 &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200557 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
558 break;
559 }
560 case Instruction::FILLED_NEW_ARRAY_RANGE: {
561 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100562 bool success =
563 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
564 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200565 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
566 break;
567 }
568 case Instruction::FILL_ARRAY_DATA: {
569 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200570 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
571 const Instruction::ArrayDataPayload* payload =
572 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
Mathieu Chartieref41db72016-10-25 15:08:01 -0700573 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
Ian Rogers832336b2014-10-08 15:35:22 -0700574 bool success = FillArrayData(obj, payload);
575 if (!success) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200576 HANDLE_PENDING_EXCEPTION();
577 break;
578 }
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100579 if (transaction_active) {
Ian Rogers832336b2014-10-08 15:35:22 -0700580 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100581 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200582 inst = inst->Next_3xx();
583 break;
584 }
585 case Instruction::THROW: {
586 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700587 ObjPtr<mirror::Object> exception =
588 shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700589 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000590 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700591 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
592 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700593 std::string temp;
Orion Hodsonfef06642016-11-25 16:07:11 +0000594 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700595 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700596 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200597 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000598 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200599 }
600 HANDLE_PENDING_EXCEPTION();
601 break;
602 }
603 case Instruction::GOTO: {
604 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200605 int8_t offset = inst->VRegA_10t(inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000606 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200607 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800608 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200609 break;
610 }
611 case Instruction::GOTO_16: {
612 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200613 int16_t offset = inst->VRegA_20t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000614 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200615 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800616 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200617 break;
618 }
619 case Instruction::GOTO_32: {
620 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200621 int32_t offset = inst->VRegA_30t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000622 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200623 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800624 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200625 break;
626 }
627 case Instruction::PACKED_SWITCH: {
628 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200629 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000630 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200631 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800632 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200633 break;
634 }
635 case Instruction::SPARSE_SWITCH: {
636 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200637 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000638 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200639 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800640 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200641 break;
642 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700643
Ian Rogers647b1a82014-10-10 11:02:11 -0700644#pragma clang diagnostic push
645#pragma clang diagnostic ignored "-Wfloat-equal"
Ian Rogers647b1a82014-10-10 11:02:11 -0700646
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200647 case Instruction::CMPL_FLOAT: {
648 PREAMBLE();
649 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
650 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
651 int32_t result;
652 if (val1 > val2) {
653 result = 1;
654 } else if (val1 == val2) {
655 result = 0;
656 } else {
657 result = -1;
658 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200659 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200660 inst = inst->Next_2xx();
661 break;
662 }
663 case Instruction::CMPG_FLOAT: {
664 PREAMBLE();
665 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
666 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
667 int32_t result;
668 if (val1 < val2) {
669 result = -1;
670 } else if (val1 == val2) {
671 result = 0;
672 } else {
673 result = 1;
674 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200675 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200676 inst = inst->Next_2xx();
677 break;
678 }
679 case Instruction::CMPL_DOUBLE: {
680 PREAMBLE();
681 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
682 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
683 int32_t result;
684 if (val1 > val2) {
685 result = 1;
686 } else if (val1 == val2) {
687 result = 0;
688 } else {
689 result = -1;
690 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200691 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200692 inst = inst->Next_2xx();
693 break;
694 }
695
696 case Instruction::CMPG_DOUBLE: {
697 PREAMBLE();
698 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
699 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
700 int32_t result;
701 if (val1 < val2) {
702 result = -1;
703 } else if (val1 == val2) {
704 result = 0;
705 } else {
706 result = 1;
707 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200708 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200709 inst = inst->Next_2xx();
710 break;
711 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700712
Ian Rogers647b1a82014-10-10 11:02:11 -0700713#pragma clang diagnostic pop
Ian Rogers647b1a82014-10-10 11:02:11 -0700714
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200715 case Instruction::CMP_LONG: {
716 PREAMBLE();
717 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
718 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
719 int32_t result;
720 if (val1 > val2) {
721 result = 1;
722 } else if (val1 == val2) {
723 result = 0;
724 } else {
725 result = -1;
726 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200727 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200728 inst = inst->Next_2xx();
729 break;
730 }
731 case Instruction::IF_EQ: {
732 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700733 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) ==
734 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200735 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000736 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200737 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800738 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200739 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800740 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200741 inst = inst->Next_2xx();
742 }
743 break;
744 }
745 case Instruction::IF_NE: {
746 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700747 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
748 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200749 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000750 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200751 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800752 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200753 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800754 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200755 inst = inst->Next_2xx();
756 }
757 break;
758 }
759 case Instruction::IF_LT: {
760 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700761 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
762 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200763 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000764 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200765 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800766 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200767 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800768 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200769 inst = inst->Next_2xx();
770 }
771 break;
772 }
773 case Instruction::IF_GE: {
774 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700775 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
776 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200777 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000778 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200779 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800780 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200781 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800782 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200783 inst = inst->Next_2xx();
784 }
785 break;
786 }
787 case Instruction::IF_GT: {
788 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700789 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
790 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200791 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000792 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200793 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800794 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200795 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800796 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200797 inst = inst->Next_2xx();
798 }
799 break;
800 }
801 case Instruction::IF_LE: {
802 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700803 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
804 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200805 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000806 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200807 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800808 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200809 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800810 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200811 inst = inst->Next_2xx();
812 }
813 break;
814 }
815 case Instruction::IF_EQZ: {
816 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200817 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200818 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000819 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200820 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800821 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200822 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800823 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200824 inst = inst->Next_2xx();
825 }
826 break;
827 }
828 case Instruction::IF_NEZ: {
829 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200830 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200831 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000832 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200833 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800834 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200835 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800836 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200837 inst = inst->Next_2xx();
838 }
839 break;
840 }
841 case Instruction::IF_LTZ: {
842 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200843 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200844 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000845 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200846 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800847 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200848 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800849 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200850 inst = inst->Next_2xx();
851 }
852 break;
853 }
854 case Instruction::IF_GEZ: {
855 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200856 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200857 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000858 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200859 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800860 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200861 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800862 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200863 inst = inst->Next_2xx();
864 }
865 break;
866 }
867 case Instruction::IF_GTZ: {
868 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200869 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200870 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000871 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200872 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800873 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200874 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800875 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200876 inst = inst->Next_2xx();
877 }
878 break;
879 }
880 case Instruction::IF_LEZ: {
881 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200882 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200883 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000884 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200885 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800886 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200887 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800888 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200889 inst = inst->Next_2xx();
890 }
891 break;
892 }
893 case Instruction::AGET_BOOLEAN: {
894 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700895 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700896 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000897 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200898 HANDLE_PENDING_EXCEPTION();
899 break;
900 }
901 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -0700902 ObjPtr<mirror::BooleanArray> array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700903 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100904 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200905 inst = inst->Next_2xx();
906 } else {
907 HANDLE_PENDING_EXCEPTION();
908 }
909 break;
910 }
911 case Instruction::AGET_BYTE: {
912 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700913 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700914 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000915 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200916 HANDLE_PENDING_EXCEPTION();
917 break;
918 }
919 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -0700920 ObjPtr<mirror::ByteArray> array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700921 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100922 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200923 inst = inst->Next_2xx();
924 } else {
925 HANDLE_PENDING_EXCEPTION();
926 }
927 break;
928 }
929 case Instruction::AGET_CHAR: {
930 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700931 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700932 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000933 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200934 HANDLE_PENDING_EXCEPTION();
935 break;
936 }
937 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -0700938 ObjPtr<mirror::CharArray> array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700939 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100940 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200941 inst = inst->Next_2xx();
942 } else {
943 HANDLE_PENDING_EXCEPTION();
944 }
945 break;
946 }
947 case Instruction::AGET_SHORT: {
948 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700949 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700950 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000951 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200952 HANDLE_PENDING_EXCEPTION();
953 break;
954 }
955 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -0700956 ObjPtr<mirror::ShortArray> array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700957 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100958 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200959 inst = inst->Next_2xx();
960 } else {
961 HANDLE_PENDING_EXCEPTION();
962 }
963 break;
964 }
965 case Instruction::AGET: {
966 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700967 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700968 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000969 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200970 HANDLE_PENDING_EXCEPTION();
971 break;
972 }
973 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -0700974 DCHECK(a->IsIntArray() || a->IsFloatArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700975 ObjPtr<mirror::IntArray> array = ObjPtr<mirror::IntArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700976 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100977 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200978 inst = inst->Next_2xx();
979 } else {
980 HANDLE_PENDING_EXCEPTION();
981 }
982 break;
983 }
984 case Instruction::AGET_WIDE: {
985 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700986 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700987 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000988 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200989 HANDLE_PENDING_EXCEPTION();
990 break;
991 }
992 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -0700993 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700994 ObjPtr<mirror::LongArray> array = ObjPtr<mirror::LongArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700995 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100996 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200997 inst = inst->Next_2xx();
998 } else {
999 HANDLE_PENDING_EXCEPTION();
1000 }
1001 break;
1002 }
1003 case Instruction::AGET_OBJECT: {
1004 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001005 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001006 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001007 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001008 HANDLE_PENDING_EXCEPTION();
1009 break;
1010 }
1011 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001012 ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001013 if (array->CheckIsValidIndex(index)) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001014 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001015 inst = inst->Next_2xx();
1016 } else {
1017 HANDLE_PENDING_EXCEPTION();
1018 }
1019 break;
1020 }
1021 case Instruction::APUT_BOOLEAN: {
1022 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001023 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001024 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001025 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001026 HANDLE_PENDING_EXCEPTION();
1027 break;
1028 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001029 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001030 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001031 ObjPtr<mirror::BooleanArray> array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001032 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001033 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001034 inst = inst->Next_2xx();
1035 } else {
1036 HANDLE_PENDING_EXCEPTION();
1037 }
1038 break;
1039 }
1040 case Instruction::APUT_BYTE: {
1041 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001042 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001043 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001044 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001045 HANDLE_PENDING_EXCEPTION();
1046 break;
1047 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001048 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001049 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001050 ObjPtr<mirror::ByteArray> array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001051 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001052 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001053 inst = inst->Next_2xx();
1054 } else {
1055 HANDLE_PENDING_EXCEPTION();
1056 }
1057 break;
1058 }
1059 case Instruction::APUT_CHAR: {
1060 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001061 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001062 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001063 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001064 HANDLE_PENDING_EXCEPTION();
1065 break;
1066 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001067 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001068 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001069 ObjPtr<mirror::CharArray> array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001070 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001071 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001072 inst = inst->Next_2xx();
1073 } else {
1074 HANDLE_PENDING_EXCEPTION();
1075 }
1076 break;
1077 }
1078 case Instruction::APUT_SHORT: {
1079 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001080 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001081 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001082 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001083 HANDLE_PENDING_EXCEPTION();
1084 break;
1085 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001086 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001087 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001088 ObjPtr<mirror::ShortArray> array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001089 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001090 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001091 inst = inst->Next_2xx();
1092 } else {
1093 HANDLE_PENDING_EXCEPTION();
1094 }
1095 break;
1096 }
1097 case Instruction::APUT: {
1098 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001099 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001100 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001101 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001102 HANDLE_PENDING_EXCEPTION();
1103 break;
1104 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001105 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001106 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001107 DCHECK(a->IsIntArray() || a->IsFloatArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001108 ObjPtr<mirror::IntArray> array = ObjPtr<mirror::IntArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001109 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001110 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001111 inst = inst->Next_2xx();
1112 } else {
1113 HANDLE_PENDING_EXCEPTION();
1114 }
1115 break;
1116 }
1117 case Instruction::APUT_WIDE: {
1118 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001119 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001120 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001121 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001122 HANDLE_PENDING_EXCEPTION();
1123 break;
1124 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001125 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001126 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001127 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001128 ObjPtr<mirror::LongArray> array = ObjPtr<mirror::LongArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001129 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001130 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001131 inst = inst->Next_2xx();
1132 } else {
1133 HANDLE_PENDING_EXCEPTION();
1134 }
1135 break;
1136 }
1137 case Instruction::APUT_OBJECT: {
1138 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001139 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001140 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001141 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001142 HANDLE_PENDING_EXCEPTION();
1143 break;
1144 }
1145 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001146 ObjPtr<mirror::Object> val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
1147 ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001148 if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001149 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001150 inst = inst->Next_2xx();
1151 } else {
1152 HANDLE_PENDING_EXCEPTION();
1153 }
1154 break;
1155 }
1156 case Instruction::IGET_BOOLEAN: {
1157 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001158 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1159 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001160 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1161 break;
1162 }
1163 case Instruction::IGET_BYTE: {
1164 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001165 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1166 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::IGET_CHAR: {
1171 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001172 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1173 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001174 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1175 break;
1176 }
1177 case Instruction::IGET_SHORT: {
1178 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001179 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1180 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001181 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1182 break;
1183 }
1184 case Instruction::IGET: {
1185 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001186 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1187 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001188 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1189 break;
1190 }
1191 case Instruction::IGET_WIDE: {
1192 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001193 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1194 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001195 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1196 break;
1197 }
1198 case Instruction::IGET_OBJECT: {
1199 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001200 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1201 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001202 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1203 break;
1204 }
1205 case Instruction::IGET_QUICK: {
1206 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001207 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001208 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1209 break;
1210 }
1211 case Instruction::IGET_WIDE_QUICK: {
1212 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001213 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001214 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1215 break;
1216 }
1217 case Instruction::IGET_OBJECT_QUICK: {
1218 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001219 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001220 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1221 break;
1222 }
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001223 case Instruction::IGET_BOOLEAN_QUICK: {
1224 PREAMBLE();
1225 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1226 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1227 break;
1228 }
1229 case Instruction::IGET_BYTE_QUICK: {
1230 PREAMBLE();
1231 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1232 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1233 break;
1234 }
1235 case Instruction::IGET_CHAR_QUICK: {
1236 PREAMBLE();
1237 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1238 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1239 break;
1240 }
1241 case Instruction::IGET_SHORT_QUICK: {
1242 PREAMBLE();
1243 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1244 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1245 break;
1246 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001247 case Instruction::SGET_BOOLEAN: {
1248 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001249 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1250 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::SGET_BYTE: {
1255 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001256 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(
1257 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001258 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1259 break;
1260 }
1261 case Instruction::SGET_CHAR: {
1262 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001263 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(
1264 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001265 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1266 break;
1267 }
1268 case Instruction::SGET_SHORT: {
1269 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001270 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(
1271 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001272 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1273 break;
1274 }
1275 case Instruction::SGET: {
1276 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001277 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(
1278 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001279 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1280 break;
1281 }
1282 case Instruction::SGET_WIDE: {
1283 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001284 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(
1285 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001286 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1287 break;
1288 }
1289 case Instruction::SGET_OBJECT: {
1290 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001291 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(
1292 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001293 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1294 break;
1295 }
1296 case Instruction::IPUT_BOOLEAN: {
1297 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001298 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1299 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001300 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1301 break;
1302 }
1303 case Instruction::IPUT_BYTE: {
1304 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001305 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1306 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001307 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1308 break;
1309 }
1310 case Instruction::IPUT_CHAR: {
1311 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001312 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1313 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001314 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1315 break;
1316 }
1317 case Instruction::IPUT_SHORT: {
1318 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001319 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1320 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001321 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1322 break;
1323 }
1324 case Instruction::IPUT: {
1325 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001326 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1327 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001328 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1329 break;
1330 }
1331 case Instruction::IPUT_WIDE: {
1332 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001333 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1334 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001335 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1336 break;
1337 }
1338 case Instruction::IPUT_OBJECT: {
1339 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001340 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1341 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001342 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1343 break;
1344 }
1345 case Instruction::IPUT_QUICK: {
1346 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001347 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1348 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001349 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1350 break;
1351 }
Fred Shih37f05ef2014-07-16 18:38:08 -07001352 case Instruction::IPUT_BOOLEAN_QUICK: {
1353 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001354 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1355 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001356 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1357 break;
1358 }
1359 case Instruction::IPUT_BYTE_QUICK: {
1360 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001361 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1362 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001363 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1364 break;
1365 }
1366 case Instruction::IPUT_CHAR_QUICK: {
1367 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001368 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1369 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001370 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1371 break;
1372 }
1373 case Instruction::IPUT_SHORT_QUICK: {
1374 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001375 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1376 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001377 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1378 break;
1379 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001380 case Instruction::IPUT_WIDE_QUICK: {
1381 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001382 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1383 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001384 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1385 break;
1386 }
1387 case Instruction::IPUT_OBJECT_QUICK: {
1388 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001389 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1390 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001391 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1392 break;
1393 }
1394 case Instruction::SPUT_BOOLEAN: {
1395 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001396 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1397 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001398 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1399 break;
1400 }
1401 case Instruction::SPUT_BYTE: {
1402 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001403 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1404 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001405 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1406 break;
1407 }
1408 case Instruction::SPUT_CHAR: {
1409 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001410 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1411 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001412 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1413 break;
1414 }
1415 case Instruction::SPUT_SHORT: {
1416 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001417 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1418 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001419 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1420 break;
1421 }
1422 case Instruction::SPUT: {
1423 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001424 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1425 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001426 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1427 break;
1428 }
1429 case Instruction::SPUT_WIDE: {
1430 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001431 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1432 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001433 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1434 break;
1435 }
1436 case Instruction::SPUT_OBJECT: {
1437 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001438 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1439 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001440 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1441 break;
1442 }
1443 case Instruction::INVOKE_VIRTUAL: {
1444 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001445 bool success = DoInvoke<kVirtual, false, do_access_check>(
1446 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001447 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1448 break;
1449 }
1450 case Instruction::INVOKE_VIRTUAL_RANGE: {
1451 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001452 bool success = DoInvoke<kVirtual, true, do_access_check>(
1453 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001454 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1455 break;
1456 }
1457 case Instruction::INVOKE_SUPER: {
1458 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001459 bool success = DoInvoke<kSuper, false, do_access_check>(
1460 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001461 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1462 break;
1463 }
1464 case Instruction::INVOKE_SUPER_RANGE: {
1465 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001466 bool success = DoInvoke<kSuper, true, do_access_check>(
1467 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001468 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1469 break;
1470 }
1471 case Instruction::INVOKE_DIRECT: {
1472 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001473 bool success = DoInvoke<kDirect, false, do_access_check>(
1474 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001475 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1476 break;
1477 }
1478 case Instruction::INVOKE_DIRECT_RANGE: {
1479 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001480 bool success = DoInvoke<kDirect, true, do_access_check>(
1481 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001482 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1483 break;
1484 }
1485 case Instruction::INVOKE_INTERFACE: {
1486 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001487 bool success = DoInvoke<kInterface, false, do_access_check>(
1488 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001489 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1490 break;
1491 }
1492 case Instruction::INVOKE_INTERFACE_RANGE: {
1493 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001494 bool success = DoInvoke<kInterface, true, do_access_check>(
1495 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001496 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1497 break;
1498 }
1499 case Instruction::INVOKE_STATIC: {
1500 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001501 bool success = DoInvoke<kStatic, false, do_access_check>(
1502 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001503 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1504 break;
1505 }
1506 case Instruction::INVOKE_STATIC_RANGE: {
1507 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001508 bool success = DoInvoke<kStatic, true, do_access_check>(
1509 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001510 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1511 break;
1512 }
1513 case Instruction::INVOKE_VIRTUAL_QUICK: {
1514 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001515 bool success = DoInvokeVirtualQuick<false>(
1516 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001517 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1518 break;
1519 }
1520 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
1521 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001522 bool success = DoInvokeVirtualQuick<true>(
1523 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001524 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1525 break;
1526 }
Narayan Kamath9823e782016-08-03 12:46:58 +01001527 case Instruction::INVOKE_POLYMORPHIC: {
1528 PREAMBLE();
Narayan Kamath269cb432016-10-28 10:19:54 +01001529 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
Narayan Kamath9823e782016-08-03 12:46:58 +01001530 bool success = DoInvokePolymorphic<false, do_access_check>(
1531 self, shadow_frame, inst, inst_data, &result_register);
1532 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_4xx);
1533 break;
1534 }
1535 case Instruction::INVOKE_POLYMORPHIC_RANGE: {
1536 PREAMBLE();
Narayan Kamath269cb432016-10-28 10:19:54 +01001537 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
Narayan Kamath9823e782016-08-03 12:46:58 +01001538 bool success = DoInvokePolymorphic<true, do_access_check>(
1539 self, shadow_frame, inst, inst_data, &result_register);
1540 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_4xx);
1541 break;
Narayan Kamath9823e782016-08-03 12:46:58 +01001542 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001543 case Instruction::NEG_INT:
1544 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001545 shadow_frame.SetVReg(
1546 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001547 inst = inst->Next_1xx();
1548 break;
1549 case Instruction::NOT_INT:
1550 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001551 shadow_frame.SetVReg(
1552 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001553 inst = inst->Next_1xx();
1554 break;
1555 case Instruction::NEG_LONG:
1556 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001557 shadow_frame.SetVRegLong(
1558 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001559 inst = inst->Next_1xx();
1560 break;
1561 case Instruction::NOT_LONG:
1562 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001563 shadow_frame.SetVRegLong(
1564 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001565 inst = inst->Next_1xx();
1566 break;
1567 case Instruction::NEG_FLOAT:
1568 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001569 shadow_frame.SetVRegFloat(
1570 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001571 inst = inst->Next_1xx();
1572 break;
1573 case Instruction::NEG_DOUBLE:
1574 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001575 shadow_frame.SetVRegDouble(
1576 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001577 inst = inst->Next_1xx();
1578 break;
1579 case Instruction::INT_TO_LONG:
1580 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001581 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
1582 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001583 inst = inst->Next_1xx();
1584 break;
1585 case Instruction::INT_TO_FLOAT:
1586 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001587 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1588 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001589 inst = inst->Next_1xx();
1590 break;
1591 case Instruction::INT_TO_DOUBLE:
1592 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001593 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1594 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001595 inst = inst->Next_1xx();
1596 break;
1597 case Instruction::LONG_TO_INT:
1598 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001599 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1600 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001601 inst = inst->Next_1xx();
1602 break;
1603 case Instruction::LONG_TO_FLOAT:
1604 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001605 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1606 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001607 inst = inst->Next_1xx();
1608 break;
1609 case Instruction::LONG_TO_DOUBLE:
1610 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001611 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1612 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001613 inst = inst->Next_1xx();
1614 break;
1615 case Instruction::FLOAT_TO_INT: {
1616 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001617 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001618 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001619 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001620 inst = inst->Next_1xx();
1621 break;
1622 }
1623 case Instruction::FLOAT_TO_LONG: {
1624 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001625 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001626 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001627 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001628 inst = inst->Next_1xx();
1629 break;
1630 }
1631 case Instruction::FLOAT_TO_DOUBLE:
1632 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001633 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1634 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001635 inst = inst->Next_1xx();
1636 break;
1637 case Instruction::DOUBLE_TO_INT: {
1638 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001639 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001640 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001641 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001642 inst = inst->Next_1xx();
1643 break;
1644 }
1645 case Instruction::DOUBLE_TO_LONG: {
1646 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001647 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001648 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001649 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001650 inst = inst->Next_1xx();
1651 break;
1652 }
1653 case Instruction::DOUBLE_TO_FLOAT:
1654 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001655 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1656 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001657 inst = inst->Next_1xx();
1658 break;
1659 case Instruction::INT_TO_BYTE:
1660 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001661 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int8_t>(
1662 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001663 inst = inst->Next_1xx();
1664 break;
1665 case Instruction::INT_TO_CHAR:
1666 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001667 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<uint16_t>(
1668 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001669 inst = inst->Next_1xx();
1670 break;
1671 case Instruction::INT_TO_SHORT:
1672 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001673 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int16_t>(
1674 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001675 inst = inst->Next_1xx();
1676 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001677 case Instruction::ADD_INT: {
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001678 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001679 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001680 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1681 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001682 inst = inst->Next_2xx();
1683 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001684 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001685 case Instruction::SUB_INT:
1686 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001687 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001688 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1689 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001690 inst = inst->Next_2xx();
1691 break;
1692 case Instruction::MUL_INT:
1693 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001694 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001695 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1696 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001697 inst = inst->Next_2xx();
1698 break;
1699 case Instruction::DIV_INT: {
1700 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001701 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001702 shadow_frame.GetVReg(inst->VRegB_23x()),
1703 shadow_frame.GetVReg(inst->VRegC_23x()));
1704 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1705 break;
1706 }
1707 case Instruction::REM_INT: {
1708 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001709 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001710 shadow_frame.GetVReg(inst->VRegB_23x()),
1711 shadow_frame.GetVReg(inst->VRegC_23x()));
1712 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1713 break;
1714 }
1715 case Instruction::SHL_INT:
1716 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001717 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001718 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1719 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1720 inst = inst->Next_2xx();
1721 break;
1722 case Instruction::SHR_INT:
1723 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001724 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001725 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1726 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1727 inst = inst->Next_2xx();
1728 break;
1729 case Instruction::USHR_INT:
1730 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001731 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001732 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1733 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1734 inst = inst->Next_2xx();
1735 break;
1736 case Instruction::AND_INT:
1737 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001738 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001739 shadow_frame.GetVReg(inst->VRegB_23x()) &
1740 shadow_frame.GetVReg(inst->VRegC_23x()));
1741 inst = inst->Next_2xx();
1742 break;
1743 case Instruction::OR_INT:
1744 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001745 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001746 shadow_frame.GetVReg(inst->VRegB_23x()) |
1747 shadow_frame.GetVReg(inst->VRegC_23x()));
1748 inst = inst->Next_2xx();
1749 break;
1750 case Instruction::XOR_INT:
1751 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001752 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001753 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1754 shadow_frame.GetVReg(inst->VRegC_23x()));
1755 inst = inst->Next_2xx();
1756 break;
1757 case Instruction::ADD_LONG:
1758 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001759 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001760 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1761 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001762 inst = inst->Next_2xx();
1763 break;
1764 case Instruction::SUB_LONG:
1765 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001766 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001767 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1768 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001769 inst = inst->Next_2xx();
1770 break;
1771 case Instruction::MUL_LONG:
1772 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001773 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001774 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1775 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001776 inst = inst->Next_2xx();
1777 break;
1778 case Instruction::DIV_LONG:
1779 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001780 DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001781 shadow_frame.GetVRegLong(inst->VRegB_23x()),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001782 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001783 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1784 break;
1785 case Instruction::REM_LONG:
1786 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001787 DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001788 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1789 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1790 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1791 break;
1792 case Instruction::AND_LONG:
1793 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001794 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001795 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1796 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1797 inst = inst->Next_2xx();
1798 break;
1799 case Instruction::OR_LONG:
1800 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001801 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001802 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1803 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1804 inst = inst->Next_2xx();
1805 break;
1806 case Instruction::XOR_LONG:
1807 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001808 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001809 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1810 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1811 inst = inst->Next_2xx();
1812 break;
1813 case Instruction::SHL_LONG:
1814 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001815 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001816 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1817 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1818 inst = inst->Next_2xx();
1819 break;
1820 case Instruction::SHR_LONG:
1821 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001822 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001823 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1824 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1825 inst = inst->Next_2xx();
1826 break;
1827 case Instruction::USHR_LONG:
1828 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001829 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001830 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1831 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1832 inst = inst->Next_2xx();
1833 break;
1834 case Instruction::ADD_FLOAT:
1835 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001836 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001837 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1838 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1839 inst = inst->Next_2xx();
1840 break;
1841 case Instruction::SUB_FLOAT:
1842 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001843 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001844 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1845 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1846 inst = inst->Next_2xx();
1847 break;
1848 case Instruction::MUL_FLOAT:
1849 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001850 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001851 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1852 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1853 inst = inst->Next_2xx();
1854 break;
1855 case Instruction::DIV_FLOAT:
1856 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001857 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001858 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1859 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1860 inst = inst->Next_2xx();
1861 break;
1862 case Instruction::REM_FLOAT:
1863 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001864 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001865 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1866 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1867 inst = inst->Next_2xx();
1868 break;
1869 case Instruction::ADD_DOUBLE:
1870 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001871 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001872 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1873 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1874 inst = inst->Next_2xx();
1875 break;
1876 case Instruction::SUB_DOUBLE:
1877 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001878 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001879 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1880 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1881 inst = inst->Next_2xx();
1882 break;
1883 case Instruction::MUL_DOUBLE:
1884 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001885 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001886 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
1887 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1888 inst = inst->Next_2xx();
1889 break;
1890 case Instruction::DIV_DOUBLE:
1891 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001892 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001893 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
1894 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1895 inst = inst->Next_2xx();
1896 break;
1897 case Instruction::REM_DOUBLE:
1898 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001899 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001900 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
1901 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
1902 inst = inst->Next_2xx();
1903 break;
1904 case Instruction::ADD_INT_2ADDR: {
1905 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001906 uint4_t vregA = inst->VRegA_12x(inst_data);
Ian Rogersf72a11d2014-10-30 15:41:08 -07001907 shadow_frame.SetVReg(vregA, SafeAdd(shadow_frame.GetVReg(vregA),
1908 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001909 inst = inst->Next_1xx();
1910 break;
1911 }
1912 case Instruction::SUB_INT_2ADDR: {
1913 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001914 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001915 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001916 SafeSub(shadow_frame.GetVReg(vregA),
1917 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001918 inst = inst->Next_1xx();
1919 break;
1920 }
1921 case Instruction::MUL_INT_2ADDR: {
1922 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001923 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001924 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001925 SafeMul(shadow_frame.GetVReg(vregA),
1926 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001927 inst = inst->Next_1xx();
1928 break;
1929 }
1930 case Instruction::DIV_INT_2ADDR: {
1931 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001932 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001933 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001934 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001935 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1936 break;
1937 }
1938 case Instruction::REM_INT_2ADDR: {
1939 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001940 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001941 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001942 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001943 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1944 break;
1945 }
1946 case Instruction::SHL_INT_2ADDR: {
1947 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001948 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001949 shadow_frame.SetVReg(vregA,
1950 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001951 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001952 inst = inst->Next_1xx();
1953 break;
1954 }
1955 case Instruction::SHR_INT_2ADDR: {
1956 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001957 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001958 shadow_frame.SetVReg(vregA,
1959 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001960 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001961 inst = inst->Next_1xx();
1962 break;
1963 }
1964 case Instruction::USHR_INT_2ADDR: {
1965 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001966 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001967 shadow_frame.SetVReg(vregA,
1968 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001969 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001970 inst = inst->Next_1xx();
1971 break;
1972 }
1973 case Instruction::AND_INT_2ADDR: {
1974 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001975 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001976 shadow_frame.SetVReg(vregA,
1977 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001978 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001979 inst = inst->Next_1xx();
1980 break;
1981 }
1982 case Instruction::OR_INT_2ADDR: {
1983 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001984 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001985 shadow_frame.SetVReg(vregA,
1986 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001987 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001988 inst = inst->Next_1xx();
1989 break;
1990 }
1991 case Instruction::XOR_INT_2ADDR: {
1992 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001993 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001994 shadow_frame.SetVReg(vregA,
1995 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001996 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001997 inst = inst->Next_1xx();
1998 break;
1999 }
2000 case Instruction::ADD_LONG_2ADDR: {
2001 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002002 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002003 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002004 SafeAdd(shadow_frame.GetVRegLong(vregA),
2005 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002006 inst = inst->Next_1xx();
2007 break;
2008 }
2009 case Instruction::SUB_LONG_2ADDR: {
2010 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002011 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002012 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002013 SafeSub(shadow_frame.GetVRegLong(vregA),
2014 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002015 inst = inst->Next_1xx();
2016 break;
2017 }
2018 case Instruction::MUL_LONG_2ADDR: {
2019 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002020 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002021 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002022 SafeMul(shadow_frame.GetVRegLong(vregA),
2023 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002024 inst = inst->Next_1xx();
2025 break;
2026 }
2027 case Instruction::DIV_LONG_2ADDR: {
2028 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002029 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002030 DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002031 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002032 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
2033 break;
2034 }
2035 case Instruction::REM_LONG_2ADDR: {
2036 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002037 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002038 DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002039 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002040 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
2041 break;
2042 }
2043 case Instruction::AND_LONG_2ADDR: {
2044 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002045 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002046 shadow_frame.SetVRegLong(vregA,
2047 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002048 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002049 inst = inst->Next_1xx();
2050 break;
2051 }
2052 case Instruction::OR_LONG_2ADDR: {
2053 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002054 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002055 shadow_frame.SetVRegLong(vregA,
2056 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002057 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002058 inst = inst->Next_1xx();
2059 break;
2060 }
2061 case Instruction::XOR_LONG_2ADDR: {
2062 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002063 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002064 shadow_frame.SetVRegLong(vregA,
2065 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002066 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002067 inst = inst->Next_1xx();
2068 break;
2069 }
2070 case Instruction::SHL_LONG_2ADDR: {
2071 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002072 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002073 shadow_frame.SetVRegLong(vregA,
2074 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002075 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002076 inst = inst->Next_1xx();
2077 break;
2078 }
2079 case Instruction::SHR_LONG_2ADDR: {
2080 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002081 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002082 shadow_frame.SetVRegLong(vregA,
2083 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002084 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002085 inst = inst->Next_1xx();
2086 break;
2087 }
2088 case Instruction::USHR_LONG_2ADDR: {
2089 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002090 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002091 shadow_frame.SetVRegLong(vregA,
2092 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002093 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002094 inst = inst->Next_1xx();
2095 break;
2096 }
2097 case Instruction::ADD_FLOAT_2ADDR: {
2098 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002099 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002100 shadow_frame.SetVRegFloat(vregA,
2101 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002102 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002103 inst = inst->Next_1xx();
2104 break;
2105 }
2106 case Instruction::SUB_FLOAT_2ADDR: {
2107 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002108 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002109 shadow_frame.SetVRegFloat(vregA,
2110 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002111 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002112 inst = inst->Next_1xx();
2113 break;
2114 }
2115 case Instruction::MUL_FLOAT_2ADDR: {
2116 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002117 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002118 shadow_frame.SetVRegFloat(vregA,
2119 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002120 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002121 inst = inst->Next_1xx();
2122 break;
2123 }
2124 case Instruction::DIV_FLOAT_2ADDR: {
2125 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002126 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002127 shadow_frame.SetVRegFloat(vregA,
2128 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002129 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002130 inst = inst->Next_1xx();
2131 break;
2132 }
2133 case Instruction::REM_FLOAT_2ADDR: {
2134 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002135 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002136 shadow_frame.SetVRegFloat(vregA,
2137 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002138 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002139 inst = inst->Next_1xx();
2140 break;
2141 }
2142 case Instruction::ADD_DOUBLE_2ADDR: {
2143 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002144 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002145 shadow_frame.SetVRegDouble(vregA,
2146 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002147 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002148 inst = inst->Next_1xx();
2149 break;
2150 }
2151 case Instruction::SUB_DOUBLE_2ADDR: {
2152 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002153 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002154 shadow_frame.SetVRegDouble(vregA,
2155 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002156 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002157 inst = inst->Next_1xx();
2158 break;
2159 }
2160 case Instruction::MUL_DOUBLE_2ADDR: {
2161 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002162 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002163 shadow_frame.SetVRegDouble(vregA,
2164 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002165 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002166 inst = inst->Next_1xx();
2167 break;
2168 }
2169 case Instruction::DIV_DOUBLE_2ADDR: {
2170 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002171 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002172 shadow_frame.SetVRegDouble(vregA,
2173 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002174 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002175 inst = inst->Next_1xx();
2176 break;
2177 }
2178 case Instruction::REM_DOUBLE_2ADDR: {
2179 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002180 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002181 shadow_frame.SetVRegDouble(vregA,
2182 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002183 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002184 inst = inst->Next_1xx();
2185 break;
2186 }
2187 case Instruction::ADD_INT_LIT16:
2188 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002189 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002190 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2191 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002192 inst = inst->Next_2xx();
2193 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07002194 case Instruction::RSUB_INT_LIT16:
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002195 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002196 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002197 SafeSub(inst->VRegC_22s(),
2198 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002199 inst = inst->Next_2xx();
2200 break;
2201 case Instruction::MUL_INT_LIT16:
2202 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002203 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002204 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2205 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002206 inst = inst->Next_2xx();
2207 break;
2208 case Instruction::DIV_INT_LIT16: {
2209 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002210 bool success = DoIntDivide(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002211 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2212 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002213 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2214 break;
2215 }
2216 case Instruction::REM_INT_LIT16: {
2217 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002218 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002219 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2220 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002221 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2222 break;
2223 }
2224 case Instruction::AND_INT_LIT16:
2225 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002226 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2227 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002228 inst->VRegC_22s());
2229 inst = inst->Next_2xx();
2230 break;
2231 case Instruction::OR_INT_LIT16:
2232 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002233 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2234 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002235 inst->VRegC_22s());
2236 inst = inst->Next_2xx();
2237 break;
2238 case Instruction::XOR_INT_LIT16:
2239 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002240 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2241 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002242 inst->VRegC_22s());
2243 inst = inst->Next_2xx();
2244 break;
2245 case Instruction::ADD_INT_LIT8:
2246 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002247 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002248 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002249 inst = inst->Next_2xx();
2250 break;
2251 case Instruction::RSUB_INT_LIT8:
2252 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002253 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002254 SafeSub(inst->VRegC_22b(), shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002255 inst = inst->Next_2xx();
2256 break;
2257 case Instruction::MUL_INT_LIT8:
2258 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002259 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002260 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002261 inst = inst->Next_2xx();
2262 break;
2263 case Instruction::DIV_INT_LIT8: {
2264 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002265 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002266 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2267 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2268 break;
2269 }
2270 case Instruction::REM_INT_LIT8: {
2271 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002272 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002273 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2274 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2275 break;
2276 }
2277 case Instruction::AND_INT_LIT8:
2278 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002279 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002280 shadow_frame.GetVReg(inst->VRegB_22b()) &
2281 inst->VRegC_22b());
2282 inst = inst->Next_2xx();
2283 break;
2284 case Instruction::OR_INT_LIT8:
2285 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002286 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002287 shadow_frame.GetVReg(inst->VRegB_22b()) |
2288 inst->VRegC_22b());
2289 inst = inst->Next_2xx();
2290 break;
2291 case Instruction::XOR_INT_LIT8:
2292 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002293 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002294 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2295 inst->VRegC_22b());
2296 inst = inst->Next_2xx();
2297 break;
2298 case Instruction::SHL_INT_LIT8:
2299 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002300 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002301 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2302 (inst->VRegC_22b() & 0x1f));
2303 inst = inst->Next_2xx();
2304 break;
2305 case Instruction::SHR_INT_LIT8:
2306 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002307 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002308 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2309 (inst->VRegC_22b() & 0x1f));
2310 inst = inst->Next_2xx();
2311 break;
2312 case Instruction::USHR_INT_LIT8:
2313 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002314 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002315 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2316 (inst->VRegC_22b() & 0x1f));
2317 inst = inst->Next_2xx();
2318 break;
2319 case Instruction::UNUSED_3E ... Instruction::UNUSED_43:
Narayan Kamath8ec3bd22016-08-03 12:46:23 +01002320 case Instruction::UNUSED_F3 ... Instruction::UNUSED_F9:
2321 case Instruction::UNUSED_FC ... Instruction::UNUSED_FF:
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002322 case Instruction::UNUSED_79:
2323 case Instruction::UNUSED_7A:
Ian Rogerse94652f2014-12-02 11:13:19 -08002324 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002325 }
buzbee1452bee2015-03-06 14:43:04 -08002326 } while (!interpret_one_instruction);
2327 // Record where we stopped.
2328 shadow_frame.SetDexPC(inst->GetDexPc(insns));
buzbeed6b48db2016-01-28 15:48:55 -08002329 return result_register;
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002330} // NOLINT(readability/fn_size)
2331
2332// Explicit definitions of ExecuteSwitchImpl.
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002333template HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002334JValue ExecuteSwitchImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -08002335 ShadowFrame& shadow_frame, JValue result_register,
2336 bool interpret_one_instruction);
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002337template HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002338JValue ExecuteSwitchImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -08002339 ShadowFrame& shadow_frame, JValue result_register,
2340 bool interpret_one_instruction);
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002341template
Ian Rogerse94652f2014-12-02 11:13:19 -08002342JValue ExecuteSwitchImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -08002343 ShadowFrame& shadow_frame, JValue result_register,
2344 bool interpret_one_instruction);
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002345template
Ian Rogerse94652f2014-12-02 11:13:19 -08002346JValue ExecuteSwitchImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -08002347 ShadowFrame& shadow_frame, JValue result_register,
2348 bool interpret_one_instruction);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002349
2350} // namespace interpreter
2351} // namespace art