blob: 45788e761730dda627a07c77e4169aab37f5be07 [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
Alex Lightb7edcda2017-04-27 13:20:31 -070029#define HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(instr) \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020030 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), \
Alex Lightb7edcda2017-04-27 13:20:31 -070035 instr); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020036 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
Alex Lightb7edcda2017-04-27 13:20:31 -070050#define HANDLE_PENDING_EXCEPTION() HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(instrumentation)
51
Sebastien Hertz8ece0502013-08-07 11:26:41 +020052#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _next_function) \
53 do { \
54 if (UNLIKELY(_is_exception_pending)) { \
55 HANDLE_PENDING_EXCEPTION(); \
56 } else { \
57 inst = inst->_next_function(); \
58 } \
59 } while (false)
60
Andreas Gampe03ec9302015-08-27 17:41:47 -070061#define HANDLE_MONITOR_CHECKS() \
Andreas Gampe56fdd0e2016-04-28 14:56:54 -070062 if (!DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame)) { \
Andreas Gampe03ec9302015-08-27 17:41:47 -070063 HANDLE_PENDING_EXCEPTION(); \
64 }
65
Sebastien Hertz8ece0502013-08-07 11:26:41 +020066// Code to run before each dex instruction.
Sebastien Hertz8379b222014-02-24 17:38:15 +010067#define PREAMBLE() \
68 do { \
Sebastien Hertz9d6bf692015-04-10 12:12:33 +020069 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
Sebastien Hertz8379b222014-02-24 17:38:15 +010070 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), \
71 shadow_frame.GetMethod(), dex_pc); \
72 } \
73 } while (false)
Sebastien Hertz8ece0502013-08-07 11:26:41 +020074
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000075#define BRANCH_INSTRUMENTATION(offset) \
76 do { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010077 if (UNLIKELY(instrumentation->HasBranchListeners())) { \
78 instrumentation->Branch(self, method, dex_pc, offset); \
79 } \
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000080 JValue result; \
81 if (jit::Jit::MaybeDoOnStackReplacement(self, method, dex_pc, offset, &result)) { \
buzbee93e94f22016-04-07 13:52:48 -070082 if (interpret_one_instruction) { \
83 /* OSR has completed execution of the method. Signal mterp to return to caller */ \
84 shadow_frame.SetDexPC(DexFile::kDexNoIndex); \
85 } \
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000086 return result; \
87 } \
Nicolas Geoffray3108daf2015-11-24 16:32:33 +000088 } while (false)
89
Bill Buzbee1d011d92016-04-04 16:59:29 +000090#define HOTNESS_UPDATE() \
91 do { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010092 if (jit != nullptr) { \
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +010093 jit->AddSamples(self, method, 1, /*with_backedges*/ true); \
Bill Buzbee1d011d92016-04-04 16:59:29 +000094 } \
95 } while (false)
96
Andreas Gampef4f76372016-12-13 14:43:58 -080097#define HANDLE_BACKWARD_BRANCH(offset) \
98 do { \
99 if (IsBackwardBranch(offset)) { \
100 HOTNESS_UPDATE(); \
101 /* Record new dex pc early to have consistent suspend point at loop header. */ \
102 shadow_frame.SetDexPC(inst->GetDexPc(insns)); \
103 self->AllowThreadSuspension(); \
104 } \
105 } while (false)
106
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100107template<bool do_access_check, bool transaction_active>
Ian Rogerse94652f2014-12-02 11:13:19 -0800108JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -0800109 ShadowFrame& shadow_frame, JValue result_register,
110 bool interpret_one_instruction) {
Igor Murashkinc449e8b2015-06-10 15:56:42 -0700111 constexpr bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200112 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
113 LOG(FATAL) << "Invalid shadow frame for interpreter use";
114 return JValue();
115 }
116 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200117
118 uint32_t dex_pc = shadow_frame.GetDexPC();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700119 const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200120 const uint16_t* const insns = code_item->insns_;
121 const Instruction* inst = Instruction::At(insns + dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200122 uint16_t inst_data;
Bill Buzbee1d011d92016-04-04 16:59:29 +0000123 ArtMethod* method = shadow_frame.GetMethod();
124 jit::Jit* jit = Runtime::Current()->GetJit();
Igor Murashkin6918bf12015-09-27 19:19:06 -0700125
buzbee1452bee2015-03-06 14:43:04 -0800126 do {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200127 dex_pc = inst->GetDexPc(insns);
128 shadow_frame.SetDexPC(dex_pc);
Ian Rogerse94652f2014-12-02 11:13:19 -0800129 TraceExecution(shadow_frame, inst, dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200130 inst_data = inst->Fetch16(0);
131 switch (inst->Opcode(inst_data)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200132 case Instruction::NOP:
133 PREAMBLE();
134 inst = inst->Next_1xx();
135 break;
136 case Instruction::MOVE:
137 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200138 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
139 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200140 inst = inst->Next_1xx();
141 break;
142 case Instruction::MOVE_FROM16:
143 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200144 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200145 shadow_frame.GetVReg(inst->VRegB_22x()));
146 inst = inst->Next_2xx();
147 break;
148 case Instruction::MOVE_16:
149 PREAMBLE();
150 shadow_frame.SetVReg(inst->VRegA_32x(),
151 shadow_frame.GetVReg(inst->VRegB_32x()));
152 inst = inst->Next_3xx();
153 break;
154 case Instruction::MOVE_WIDE:
155 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200156 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
157 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200158 inst = inst->Next_1xx();
159 break;
160 case Instruction::MOVE_WIDE_FROM16:
161 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200162 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200163 shadow_frame.GetVRegLong(inst->VRegB_22x()));
164 inst = inst->Next_2xx();
165 break;
166 case Instruction::MOVE_WIDE_16:
167 PREAMBLE();
168 shadow_frame.SetVRegLong(inst->VRegA_32x(),
169 shadow_frame.GetVRegLong(inst->VRegB_32x()));
170 inst = inst->Next_3xx();
171 break;
172 case Instruction::MOVE_OBJECT:
173 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200174 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
175 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200176 inst = inst->Next_1xx();
177 break;
178 case Instruction::MOVE_OBJECT_FROM16:
179 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200180 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200181 shadow_frame.GetVRegReference(inst->VRegB_22x()));
182 inst = inst->Next_2xx();
183 break;
184 case Instruction::MOVE_OBJECT_16:
185 PREAMBLE();
186 shadow_frame.SetVRegReference(inst->VRegA_32x(),
187 shadow_frame.GetVRegReference(inst->VRegB_32x()));
188 inst = inst->Next_3xx();
189 break;
190 case Instruction::MOVE_RESULT:
191 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200192 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200193 inst = inst->Next_1xx();
194 break;
195 case Instruction::MOVE_RESULT_WIDE:
196 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200197 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200198 inst = inst->Next_1xx();
199 break;
200 case Instruction::MOVE_RESULT_OBJECT:
201 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200202 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200203 inst = inst->Next_1xx();
204 break;
205 case Instruction::MOVE_EXCEPTION: {
206 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700207 ObjPtr<mirror::Throwable> exception = self->GetException();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100208 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
Mathieu Chartieref41db72016-10-25 15:08:01 -0700209 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception.Ptr());
Sebastien Hertz5c004902014-05-21 10:07:42 +0200210 self->ClearException();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200211 inst = inst->Next_1xx();
212 break;
213 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700214 case Instruction::RETURN_VOID_NO_BARRIER: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200215 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200216 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700217 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700218 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200219 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200220 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200221 shadow_frame.GetMethod(), inst->GetDexPc(insns),
222 result);
Alex Lightb7edcda2017-04-27 13:20:31 -0700223 if (UNLIKELY(self->IsExceptionPending())) {
224 // Don't send another method exit event.
225 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
226 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200227 }
buzbee1452bee2015-03-06 14:43:04 -0800228 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700229 /* Signal mterp to return to caller */
buzbee1452bee2015-03-06 14:43:04 -0800230 shadow_frame.SetDexPC(DexFile::kDexNoIndex);
231 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200232 return result;
233 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700234 case Instruction::RETURN_VOID: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200235 PREAMBLE();
Hans Boehm30359612014-05-21 17:46:23 -0700236 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200237 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700238 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700239 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200240 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200241 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200242 shadow_frame.GetMethod(), inst->GetDexPc(insns),
243 result);
Alex Lightb7edcda2017-04-27 13:20:31 -0700244 if (UNLIKELY(self->IsExceptionPending())) {
245 // Don't send another method exit event.
246 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
247 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200248 }
buzbee1452bee2015-03-06 14:43:04 -0800249 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700250 /* Signal mterp to return to caller */
buzbee1452bee2015-03-06 14:43:04 -0800251 shadow_frame.SetDexPC(DexFile::kDexNoIndex);
252 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200253 return result;
254 }
255 case Instruction::RETURN: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200256 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200257 JValue result;
258 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200259 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700260 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700261 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200262 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200263 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200264 shadow_frame.GetMethod(), inst->GetDexPc(insns),
265 result);
Alex Lightb7edcda2017-04-27 13:20:31 -0700266 if (UNLIKELY(self->IsExceptionPending())) {
267 // Don't send another method exit event.
268 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
269 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200270 }
buzbee1452bee2015-03-06 14:43:04 -0800271 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700272 /* Signal mterp to return to caller */
buzbee1452bee2015-03-06 14:43:04 -0800273 shadow_frame.SetDexPC(DexFile::kDexNoIndex);
274 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200275 return result;
276 }
277 case Instruction::RETURN_WIDE: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200278 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200279 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200280 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700281 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700282 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200283 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200284 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200285 shadow_frame.GetMethod(), inst->GetDexPc(insns),
286 result);
Alex Lightb7edcda2017-04-27 13:20:31 -0700287 if (UNLIKELY(self->IsExceptionPending())) {
288 // Don't send another method exit event.
289 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
290 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200291 }
buzbee1452bee2015-03-06 14:43:04 -0800292 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700293 /* Signal mterp to return to caller */
buzbee1452bee2015-03-06 14:43:04 -0800294 shadow_frame.SetDexPC(DexFile::kDexNoIndex);
295 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200296 return result;
297 }
298 case Instruction::RETURN_OBJECT: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200299 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200300 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700301 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700302 HANDLE_MONITOR_CHECKS();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700303 const size_t ref_idx = inst->VRegA_11x(inst_data);
Mathieu Chartieref41db72016-10-25 15:08:01 -0700304 ObjPtr<mirror::Object> obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700305 if (do_assignability_check && obj_result != nullptr) {
Vladimir Marko942fd312017-01-16 20:52:19 +0000306 ObjPtr<mirror::Class> return_type = method->GetReturnType(true /* resolve */);
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700307 // Re-load since it might have moved.
308 obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700309 if (return_type == nullptr) {
Jeff Haoa3faaf42013-09-03 19:07:00 -0700310 // Return the pending exception.
311 HANDLE_PENDING_EXCEPTION();
312 }
313 if (!obj_result->VerifierInstanceOf(return_type)) {
314 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700315 std::string temp1, temp2;
Orion Hodsonfef06642016-11-25 16:07:11 +0000316 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700317 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700318 obj_result->GetClass()->GetDescriptor(&temp1),
319 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700320 HANDLE_PENDING_EXCEPTION();
321 }
322 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700323 result.SetL(obj_result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200324 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200325 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200326 shadow_frame.GetMethod(), inst->GetDexPc(insns),
327 result);
Alex Lightb7edcda2017-04-27 13:20:31 -0700328 if (UNLIKELY(self->IsExceptionPending())) {
329 // Don't send another method exit event.
330 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
331 }
Alex Lightd7661582017-05-01 13:48:16 -0700332 // Re-load since it might have moved during the MethodExitEvent.
333 result.SetL(shadow_frame.GetVRegReference(ref_idx));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200334 }
buzbee1452bee2015-03-06 14:43:04 -0800335 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700336 /* Signal mterp to return to caller */
buzbee1452bee2015-03-06 14:43:04 -0800337 shadow_frame.SetDexPC(DexFile::kDexNoIndex);
338 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200339 return result;
340 }
341 case Instruction::CONST_4: {
342 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200343 uint4_t dst = inst->VRegA_11n(inst_data);
344 int4_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200345 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_1xx();
350 break;
351 }
352 case Instruction::CONST_16: {
353 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200354 uint8_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200355 int16_t val = inst->VRegB_21s();
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: {
364 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200365 uint8_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200366 int32_t val = inst->VRegB_31i();
367 shadow_frame.SetVReg(dst, val);
368 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700369 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200370 }
371 inst = inst->Next_3xx();
372 break;
373 }
374 case Instruction::CONST_HIGH16: {
375 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200376 uint8_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200377 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
378 shadow_frame.SetVReg(dst, val);
379 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700380 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200381 }
382 inst = inst->Next_2xx();
383 break;
384 }
385 case Instruction::CONST_WIDE_16:
386 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200387 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200388 inst = inst->Next_2xx();
389 break;
390 case Instruction::CONST_WIDE_32:
391 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200392 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200393 inst = inst->Next_3xx();
394 break;
395 case Instruction::CONST_WIDE:
396 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200397 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200398 inst = inst->Next_51l();
399 break;
400 case Instruction::CONST_WIDE_HIGH16:
Sebastien Hertz3c5aec12014-06-04 09:41:21 +0200401 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200402 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200403 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
404 inst = inst->Next_2xx();
405 break;
406 case Instruction::CONST_STRING: {
407 PREAMBLE();
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800408 ObjPtr<mirror::String> s = ResolveString(self,
409 shadow_frame,
410 dex::StringIndex(inst->VRegB_21c()));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700411 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200412 HANDLE_PENDING_EXCEPTION();
413 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700414 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s.Ptr());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200415 inst = inst->Next_2xx();
416 }
417 break;
418 }
419 case Instruction::CONST_STRING_JUMBO: {
420 PREAMBLE();
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800421 ObjPtr<mirror::String> s = ResolveString(self,
422 shadow_frame,
423 dex::StringIndex(inst->VRegB_31c()));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700424 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200425 HANDLE_PENDING_EXCEPTION();
426 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700427 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s.Ptr());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200428 inst = inst->Next_3xx();
429 }
430 break;
431 }
432 case Instruction::CONST_CLASS: {
433 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800434 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700435 shadow_frame.GetMethod(),
436 self,
437 false,
438 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700439 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200440 HANDLE_PENDING_EXCEPTION();
441 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700442 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c.Ptr());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200443 inst = inst->Next_2xx();
444 }
445 break;
446 }
447 case Instruction::MONITOR_ENTER: {
448 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700449 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700450 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000451 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200452 HANDLE_PENDING_EXCEPTION();
453 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700454 DoMonitorEnter<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200455 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
456 }
457 break;
458 }
459 case Instruction::MONITOR_EXIT: {
460 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700461 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700462 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000463 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200464 HANDLE_PENDING_EXCEPTION();
465 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700466 DoMonitorExit<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200467 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
468 }
469 break;
470 }
471 case Instruction::CHECK_CAST: {
472 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800473 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700474 shadow_frame.GetMethod(),
475 self,
476 false,
477 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700478 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200479 HANDLE_PENDING_EXCEPTION();
480 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700481 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700482 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200483 ThrowClassCastException(c, obj->GetClass());
484 HANDLE_PENDING_EXCEPTION();
485 } else {
486 inst = inst->Next_2xx();
487 }
488 }
489 break;
490 }
491 case Instruction::INSTANCE_OF: {
492 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800493 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegC_22c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700494 shadow_frame.GetMethod(),
495 self,
496 false,
497 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700498 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200499 HANDLE_PENDING_EXCEPTION();
500 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700501 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700502 shadow_frame.SetVReg(inst->VRegA_22c(inst_data),
503 (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200504 inst = inst->Next_2xx();
505 }
506 break;
507 }
508 case Instruction::ARRAY_LENGTH: {
509 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700510 ObjPtr<mirror::Object> array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700511 if (UNLIKELY(array == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000512 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200513 HANDLE_PENDING_EXCEPTION();
514 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200515 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200516 inst = inst->Next_1xx();
517 }
518 break;
519 }
520 case Instruction::NEW_INSTANCE: {
521 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700522 ObjPtr<mirror::Object> obj = nullptr;
Andreas Gampea5b09a62016-11-17 15:21:22 -0800523 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700524 shadow_frame.GetMethod(),
525 self,
526 false,
527 do_access_check);
Jeff Hao848f70a2014-01-15 13:49:50 -0800528 if (LIKELY(c != nullptr)) {
529 if (UNLIKELY(c->IsStringClass())) {
530 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
jessicahandojo3aaa37b2016-07-29 14:46:37 -0700531 obj = mirror::String::AllocEmptyString<true>(self, allocator_type);
Jeff Hao848f70a2014-01-15 13:49:50 -0800532 } else {
Nicolas Geoffray0d3998b2017-01-12 15:35:12 +0000533 obj = AllocObjectFromCode<true>(
534 c.Ptr(),
Andreas Gampea5b09a62016-11-17 15:21:22 -0800535 self,
536 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Jeff Hao848f70a2014-01-15 13:49:50 -0800537 }
538 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700539 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200540 HANDLE_PENDING_EXCEPTION();
541 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200542 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700543 // Don't allow finalizable objects to be allocated during a transaction since these can't
544 // be finalized without a started runtime.
545 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200546 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
David Sehr709b0702016-10-13 09:12:37 -0700547 obj->PrettyTypeOf().c_str());
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700548 HANDLE_PENDING_EXCEPTION();
549 break;
550 }
Mathieu Chartieref41db72016-10-25 15:08:01 -0700551 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj.Ptr());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200552 inst = inst->Next_2xx();
553 }
554 break;
555 }
556 case Instruction::NEW_ARRAY: {
557 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200558 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartieref41db72016-10-25 15:08:01 -0700559 ObjPtr<mirror::Object> obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampea5b09a62016-11-17 15:21:22 -0800560 dex::TypeIndex(inst->VRegC_22c()),
561 length,
562 shadow_frame.GetMethod(),
563 self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800564 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700565 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200566 HANDLE_PENDING_EXCEPTION();
567 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700568 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj.Ptr());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200569 inst = inst->Next_2xx();
570 }
571 break;
572 }
573 case Instruction::FILLED_NEW_ARRAY: {
574 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100575 bool success =
576 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame, self,
577 &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200578 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
579 break;
580 }
581 case Instruction::FILLED_NEW_ARRAY_RANGE: {
582 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100583 bool success =
584 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
585 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200586 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
587 break;
588 }
589 case Instruction::FILL_ARRAY_DATA: {
590 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200591 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
592 const Instruction::ArrayDataPayload* payload =
593 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
Mathieu Chartieref41db72016-10-25 15:08:01 -0700594 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
Ian Rogers832336b2014-10-08 15:35:22 -0700595 bool success = FillArrayData(obj, payload);
596 if (!success) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200597 HANDLE_PENDING_EXCEPTION();
598 break;
599 }
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100600 if (transaction_active) {
Ian Rogers832336b2014-10-08 15:35:22 -0700601 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100602 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200603 inst = inst->Next_3xx();
604 break;
605 }
606 case Instruction::THROW: {
607 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700608 ObjPtr<mirror::Object> exception =
609 shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700610 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000611 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700612 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
613 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700614 std::string temp;
Orion Hodsonfef06642016-11-25 16:07:11 +0000615 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700616 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700617 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200618 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000619 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200620 }
621 HANDLE_PENDING_EXCEPTION();
622 break;
623 }
624 case Instruction::GOTO: {
625 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200626 int8_t offset = inst->VRegA_10t(inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000627 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200628 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800629 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200630 break;
631 }
632 case Instruction::GOTO_16: {
633 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200634 int16_t offset = inst->VRegA_20t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000635 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200636 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800637 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200638 break;
639 }
640 case Instruction::GOTO_32: {
641 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200642 int32_t offset = inst->VRegA_30t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000643 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200644 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800645 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200646 break;
647 }
648 case Instruction::PACKED_SWITCH: {
649 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200650 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000651 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200652 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800653 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200654 break;
655 }
656 case Instruction::SPARSE_SWITCH: {
657 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200658 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000659 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200660 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800661 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200662 break;
663 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700664
Ian Rogers647b1a82014-10-10 11:02:11 -0700665#pragma clang diagnostic push
666#pragma clang diagnostic ignored "-Wfloat-equal"
Ian Rogers647b1a82014-10-10 11:02:11 -0700667
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200668 case Instruction::CMPL_FLOAT: {
669 PREAMBLE();
670 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
671 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
672 int32_t result;
673 if (val1 > val2) {
674 result = 1;
675 } else if (val1 == val2) {
676 result = 0;
677 } else {
678 result = -1;
679 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200680 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200681 inst = inst->Next_2xx();
682 break;
683 }
684 case Instruction::CMPG_FLOAT: {
685 PREAMBLE();
686 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
687 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
688 int32_t result;
689 if (val1 < val2) {
690 result = -1;
691 } else if (val1 == val2) {
692 result = 0;
693 } else {
694 result = 1;
695 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200696 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200697 inst = inst->Next_2xx();
698 break;
699 }
700 case Instruction::CMPL_DOUBLE: {
701 PREAMBLE();
702 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
703 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
704 int32_t result;
705 if (val1 > val2) {
706 result = 1;
707 } else if (val1 == val2) {
708 result = 0;
709 } else {
710 result = -1;
711 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200712 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200713 inst = inst->Next_2xx();
714 break;
715 }
716
717 case Instruction::CMPG_DOUBLE: {
718 PREAMBLE();
719 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
720 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
721 int32_t result;
722 if (val1 < val2) {
723 result = -1;
724 } else if (val1 == val2) {
725 result = 0;
726 } else {
727 result = 1;
728 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200729 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200730 inst = inst->Next_2xx();
731 break;
732 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700733
Ian Rogers647b1a82014-10-10 11:02:11 -0700734#pragma clang diagnostic pop
Ian Rogers647b1a82014-10-10 11:02:11 -0700735
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200736 case Instruction::CMP_LONG: {
737 PREAMBLE();
738 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
739 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
740 int32_t result;
741 if (val1 > val2) {
742 result = 1;
743 } else if (val1 == val2) {
744 result = 0;
745 } else {
746 result = -1;
747 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200748 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200749 inst = inst->Next_2xx();
750 break;
751 }
752 case Instruction::IF_EQ: {
753 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700754 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) ==
755 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200756 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000757 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200758 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800759 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200760 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800761 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200762 inst = inst->Next_2xx();
763 }
764 break;
765 }
766 case Instruction::IF_NE: {
767 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700768 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
769 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200770 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000771 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200772 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800773 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200774 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800775 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200776 inst = inst->Next_2xx();
777 }
778 break;
779 }
780 case Instruction::IF_LT: {
781 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700782 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
783 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200784 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000785 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200786 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800787 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200788 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800789 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200790 inst = inst->Next_2xx();
791 }
792 break;
793 }
794 case Instruction::IF_GE: {
795 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700796 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
797 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200798 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000799 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200800 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800801 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200802 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800803 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200804 inst = inst->Next_2xx();
805 }
806 break;
807 }
808 case Instruction::IF_GT: {
809 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700810 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
811 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200812 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000813 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200814 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800815 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200816 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800817 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200818 inst = inst->Next_2xx();
819 }
820 break;
821 }
822 case Instruction::IF_LE: {
823 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700824 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
825 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200826 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000827 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200828 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800829 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200830 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800831 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200832 inst = inst->Next_2xx();
833 }
834 break;
835 }
836 case Instruction::IF_EQZ: {
837 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200838 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200839 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000840 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200841 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800842 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200843 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800844 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200845 inst = inst->Next_2xx();
846 }
847 break;
848 }
849 case Instruction::IF_NEZ: {
850 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200851 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200852 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000853 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200854 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800855 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200856 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800857 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200858 inst = inst->Next_2xx();
859 }
860 break;
861 }
862 case Instruction::IF_LTZ: {
863 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200864 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200865 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000866 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200867 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800868 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200869 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800870 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200871 inst = inst->Next_2xx();
872 }
873 break;
874 }
875 case Instruction::IF_GEZ: {
876 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200877 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200878 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000879 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200880 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800881 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200882 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800883 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200884 inst = inst->Next_2xx();
885 }
886 break;
887 }
888 case Instruction::IF_GTZ: {
889 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200890 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200891 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000892 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200893 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800894 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200895 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800896 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200897 inst = inst->Next_2xx();
898 }
899 break;
900 }
901 case Instruction::IF_LEZ: {
902 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200903 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200904 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000905 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200906 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800907 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200908 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800909 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200910 inst = inst->Next_2xx();
911 }
912 break;
913 }
914 case Instruction::AGET_BOOLEAN: {
915 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700916 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700917 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000918 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200919 HANDLE_PENDING_EXCEPTION();
920 break;
921 }
922 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -0700923 ObjPtr<mirror::BooleanArray> array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700924 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100925 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200926 inst = inst->Next_2xx();
927 } else {
928 HANDLE_PENDING_EXCEPTION();
929 }
930 break;
931 }
932 case Instruction::AGET_BYTE: {
933 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700934 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700935 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000936 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200937 HANDLE_PENDING_EXCEPTION();
938 break;
939 }
940 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -0700941 ObjPtr<mirror::ByteArray> array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700942 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100943 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200944 inst = inst->Next_2xx();
945 } else {
946 HANDLE_PENDING_EXCEPTION();
947 }
948 break;
949 }
950 case Instruction::AGET_CHAR: {
951 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700952 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700953 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000954 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200955 HANDLE_PENDING_EXCEPTION();
956 break;
957 }
958 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -0700959 ObjPtr<mirror::CharArray> array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700960 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100961 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200962 inst = inst->Next_2xx();
963 } else {
964 HANDLE_PENDING_EXCEPTION();
965 }
966 break;
967 }
968 case Instruction::AGET_SHORT: {
969 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700970 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700971 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000972 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200973 HANDLE_PENDING_EXCEPTION();
974 break;
975 }
976 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -0700977 ObjPtr<mirror::ShortArray> array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700978 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100979 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200980 inst = inst->Next_2xx();
981 } else {
982 HANDLE_PENDING_EXCEPTION();
983 }
984 break;
985 }
986 case Instruction::AGET: {
987 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700988 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700989 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000990 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200991 HANDLE_PENDING_EXCEPTION();
992 break;
993 }
994 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -0700995 DCHECK(a->IsIntArray() || a->IsFloatArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700996 ObjPtr<mirror::IntArray> array = ObjPtr<mirror::IntArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700997 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100998 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200999 inst = inst->Next_2xx();
1000 } else {
1001 HANDLE_PENDING_EXCEPTION();
1002 }
1003 break;
1004 }
1005 case Instruction::AGET_WIDE: {
1006 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001007 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001008 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001009 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001010 HANDLE_PENDING_EXCEPTION();
1011 break;
1012 }
1013 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001014 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001015 ObjPtr<mirror::LongArray> array = ObjPtr<mirror::LongArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001016 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001017 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001018 inst = inst->Next_2xx();
1019 } else {
1020 HANDLE_PENDING_EXCEPTION();
1021 }
1022 break;
1023 }
1024 case Instruction::AGET_OBJECT: {
1025 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001026 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001027 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001028 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001029 HANDLE_PENDING_EXCEPTION();
1030 break;
1031 }
1032 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001033 ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001034 if (array->CheckIsValidIndex(index)) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001035 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001036 inst = inst->Next_2xx();
1037 } else {
1038 HANDLE_PENDING_EXCEPTION();
1039 }
1040 break;
1041 }
1042 case Instruction::APUT_BOOLEAN: {
1043 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001044 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001045 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001046 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001047 HANDLE_PENDING_EXCEPTION();
1048 break;
1049 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001050 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001051 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001052 ObjPtr<mirror::BooleanArray> array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001053 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001054 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001055 inst = inst->Next_2xx();
1056 } else {
1057 HANDLE_PENDING_EXCEPTION();
1058 }
1059 break;
1060 }
1061 case Instruction::APUT_BYTE: {
1062 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001063 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001064 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001065 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001066 HANDLE_PENDING_EXCEPTION();
1067 break;
1068 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001069 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001070 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001071 ObjPtr<mirror::ByteArray> array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001072 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001073 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001074 inst = inst->Next_2xx();
1075 } else {
1076 HANDLE_PENDING_EXCEPTION();
1077 }
1078 break;
1079 }
1080 case Instruction::APUT_CHAR: {
1081 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001082 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001083 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001084 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001085 HANDLE_PENDING_EXCEPTION();
1086 break;
1087 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001088 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001089 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001090 ObjPtr<mirror::CharArray> array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001091 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001092 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001093 inst = inst->Next_2xx();
1094 } else {
1095 HANDLE_PENDING_EXCEPTION();
1096 }
1097 break;
1098 }
1099 case Instruction::APUT_SHORT: {
1100 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001101 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001102 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001103 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001104 HANDLE_PENDING_EXCEPTION();
1105 break;
1106 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001107 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001108 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001109 ObjPtr<mirror::ShortArray> array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001110 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001111 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001112 inst = inst->Next_2xx();
1113 } else {
1114 HANDLE_PENDING_EXCEPTION();
1115 }
1116 break;
1117 }
1118 case Instruction::APUT: {
1119 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001120 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001121 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001122 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001123 HANDLE_PENDING_EXCEPTION();
1124 break;
1125 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001126 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001127 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001128 DCHECK(a->IsIntArray() || a->IsFloatArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001129 ObjPtr<mirror::IntArray> array = ObjPtr<mirror::IntArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001130 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001131 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001132 inst = inst->Next_2xx();
1133 } else {
1134 HANDLE_PENDING_EXCEPTION();
1135 }
1136 break;
1137 }
1138 case Instruction::APUT_WIDE: {
1139 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001140 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001141 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001142 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001143 HANDLE_PENDING_EXCEPTION();
1144 break;
1145 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001146 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001147 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001148 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001149 ObjPtr<mirror::LongArray> array = ObjPtr<mirror::LongArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001150 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001151 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001152 inst = inst->Next_2xx();
1153 } else {
1154 HANDLE_PENDING_EXCEPTION();
1155 }
1156 break;
1157 }
1158 case Instruction::APUT_OBJECT: {
1159 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001160 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001161 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001162 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001163 HANDLE_PENDING_EXCEPTION();
1164 break;
1165 }
1166 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001167 ObjPtr<mirror::Object> val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
1168 ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001169 if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001170 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001171 inst = inst->Next_2xx();
1172 } else {
1173 HANDLE_PENDING_EXCEPTION();
1174 }
1175 break;
1176 }
1177 case Instruction::IGET_BOOLEAN: {
1178 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001179 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, 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_BYTE: {
1185 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001186 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, 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_CHAR: {
1192 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001193 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, 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_SHORT: {
1199 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001200 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, 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: {
1206 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001207 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1208 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001209 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1210 break;
1211 }
1212 case Instruction::IGET_WIDE: {
1213 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001214 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1215 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001216 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1217 break;
1218 }
1219 case Instruction::IGET_OBJECT: {
1220 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001221 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1222 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001223 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1224 break;
1225 }
1226 case Instruction::IGET_QUICK: {
1227 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001228 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001229 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1230 break;
1231 }
1232 case Instruction::IGET_WIDE_QUICK: {
1233 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001234 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001235 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1236 break;
1237 }
1238 case Instruction::IGET_OBJECT_QUICK: {
1239 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001240 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001241 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1242 break;
1243 }
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001244 case Instruction::IGET_BOOLEAN_QUICK: {
1245 PREAMBLE();
1246 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1247 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1248 break;
1249 }
1250 case Instruction::IGET_BYTE_QUICK: {
1251 PREAMBLE();
1252 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1253 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1254 break;
1255 }
1256 case Instruction::IGET_CHAR_QUICK: {
1257 PREAMBLE();
1258 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1259 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1260 break;
1261 }
1262 case Instruction::IGET_SHORT_QUICK: {
1263 PREAMBLE();
1264 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1265 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1266 break;
1267 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001268 case Instruction::SGET_BOOLEAN: {
1269 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001270 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, 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_BYTE: {
1276 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001277 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, 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_CHAR: {
1283 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001284 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, 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_SHORT: {
1290 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001291 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, 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::SGET: {
1297 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001298 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(
1299 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::SGET_WIDE: {
1304 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001305 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(
1306 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::SGET_OBJECT: {
1311 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001312 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(
1313 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_BOOLEAN: {
1318 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001319 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, 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_BYTE: {
1325 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001326 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, 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_CHAR: {
1332 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001333 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, 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_SHORT: {
1339 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001340 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, 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: {
1346 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001347 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1348 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001349 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1350 break;
1351 }
1352 case Instruction::IPUT_WIDE: {
1353 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001354 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1355 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001356 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1357 break;
1358 }
1359 case Instruction::IPUT_OBJECT: {
1360 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001361 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1362 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001363 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1364 break;
1365 }
1366 case Instruction::IPUT_QUICK: {
1367 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001368 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1369 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001370 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1371 break;
1372 }
Fred Shih37f05ef2014-07-16 18:38:08 -07001373 case Instruction::IPUT_BOOLEAN_QUICK: {
1374 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001375 bool success = DoIPutQuick<Primitive::kPrimBoolean, 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 }
1380 case Instruction::IPUT_BYTE_QUICK: {
1381 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001382 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1383 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001384 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1385 break;
1386 }
1387 case Instruction::IPUT_CHAR_QUICK: {
1388 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001389 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1390 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001391 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1392 break;
1393 }
1394 case Instruction::IPUT_SHORT_QUICK: {
1395 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001396 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1397 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001398 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1399 break;
1400 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001401 case Instruction::IPUT_WIDE_QUICK: {
1402 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001403 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1404 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::IPUT_OBJECT_QUICK: {
1409 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001410 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1411 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_BOOLEAN: {
1416 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001417 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, 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_BYTE: {
1423 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001424 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, 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_CHAR: {
1430 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001431 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, 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_SHORT: {
1437 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001438 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, 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::SPUT: {
1444 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001445 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1446 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001447 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1448 break;
1449 }
1450 case Instruction::SPUT_WIDE: {
1451 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001452 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1453 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001454 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1455 break;
1456 }
1457 case Instruction::SPUT_OBJECT: {
1458 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001459 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1460 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001461 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1462 break;
1463 }
1464 case Instruction::INVOKE_VIRTUAL: {
1465 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001466 bool success = DoInvoke<kVirtual, false, 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_VIRTUAL_RANGE: {
1472 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001473 bool success = DoInvoke<kVirtual, true, 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_SUPER: {
1479 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001480 bool success = DoInvoke<kSuper, false, 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_SUPER_RANGE: {
1486 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001487 bool success = DoInvoke<kSuper, true, 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_DIRECT: {
1493 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001494 bool success = DoInvoke<kDirect, false, 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_DIRECT_RANGE: {
1500 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001501 bool success = DoInvoke<kDirect, true, 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_INTERFACE: {
1507 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001508 bool success = DoInvoke<kInterface, false, 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_INTERFACE_RANGE: {
1514 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001515 bool success = DoInvoke<kInterface, true, do_access_check>(
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_STATIC: {
1521 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001522 bool success = DoInvoke<kStatic, false, do_access_check>(
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 }
1527 case Instruction::INVOKE_STATIC_RANGE: {
1528 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001529 bool success = DoInvoke<kStatic, true, do_access_check>(
1530 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001531 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1532 break;
1533 }
1534 case Instruction::INVOKE_VIRTUAL_QUICK: {
1535 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001536 bool success = DoInvokeVirtualQuick<false>(
1537 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001538 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1539 break;
1540 }
1541 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
1542 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001543 bool success = DoInvokeVirtualQuick<true>(
1544 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001545 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1546 break;
1547 }
Narayan Kamath9823e782016-08-03 12:46:58 +01001548 case Instruction::INVOKE_POLYMORPHIC: {
1549 PREAMBLE();
Narayan Kamath269cb432016-10-28 10:19:54 +01001550 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
Orion Hodsonc069a302017-01-18 09:23:12 +00001551 bool success = DoInvokePolymorphic<false /* is_range */>(
Narayan Kamath9823e782016-08-03 12:46:58 +01001552 self, shadow_frame, inst, inst_data, &result_register);
1553 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_4xx);
1554 break;
1555 }
1556 case Instruction::INVOKE_POLYMORPHIC_RANGE: {
1557 PREAMBLE();
Narayan Kamath269cb432016-10-28 10:19:54 +01001558 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
Orion Hodsonc069a302017-01-18 09:23:12 +00001559 bool success = DoInvokePolymorphic<true /* is_range */>(
Narayan Kamath9823e782016-08-03 12:46:58 +01001560 self, shadow_frame, inst, inst_data, &result_register);
1561 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_4xx);
1562 break;
Narayan Kamath9823e782016-08-03 12:46:58 +01001563 }
Orion Hodsonc069a302017-01-18 09:23:12 +00001564 case Instruction::INVOKE_CUSTOM: {
1565 PREAMBLE();
1566 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1567 bool success = DoInvokeCustom<false /* is_range */>(
1568 self, shadow_frame, inst, inst_data, &result_register);
1569 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1570 break;
1571 }
1572 case Instruction::INVOKE_CUSTOM_RANGE: {
1573 PREAMBLE();
1574 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1575 bool success = DoInvokeCustom<true /* is_range */>(
1576 self, shadow_frame, inst, inst_data, &result_register);
1577 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1578 break;
1579 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001580 case Instruction::NEG_INT:
1581 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001582 shadow_frame.SetVReg(
1583 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001584 inst = inst->Next_1xx();
1585 break;
1586 case Instruction::NOT_INT:
1587 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001588 shadow_frame.SetVReg(
1589 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001590 inst = inst->Next_1xx();
1591 break;
1592 case Instruction::NEG_LONG:
1593 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001594 shadow_frame.SetVRegLong(
1595 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001596 inst = inst->Next_1xx();
1597 break;
1598 case Instruction::NOT_LONG:
1599 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001600 shadow_frame.SetVRegLong(
1601 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001602 inst = inst->Next_1xx();
1603 break;
1604 case Instruction::NEG_FLOAT:
1605 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001606 shadow_frame.SetVRegFloat(
1607 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001608 inst = inst->Next_1xx();
1609 break;
1610 case Instruction::NEG_DOUBLE:
1611 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001612 shadow_frame.SetVRegDouble(
1613 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001614 inst = inst->Next_1xx();
1615 break;
1616 case Instruction::INT_TO_LONG:
1617 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001618 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
1619 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001620 inst = inst->Next_1xx();
1621 break;
1622 case Instruction::INT_TO_FLOAT:
1623 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001624 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1625 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001626 inst = inst->Next_1xx();
1627 break;
1628 case Instruction::INT_TO_DOUBLE:
1629 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001630 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1631 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001632 inst = inst->Next_1xx();
1633 break;
1634 case Instruction::LONG_TO_INT:
1635 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001636 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1637 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001638 inst = inst->Next_1xx();
1639 break;
1640 case Instruction::LONG_TO_FLOAT:
1641 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001642 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1643 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001644 inst = inst->Next_1xx();
1645 break;
1646 case Instruction::LONG_TO_DOUBLE:
1647 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001648 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1649 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001650 inst = inst->Next_1xx();
1651 break;
1652 case Instruction::FLOAT_TO_INT: {
1653 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001654 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001655 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001656 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001657 inst = inst->Next_1xx();
1658 break;
1659 }
1660 case Instruction::FLOAT_TO_LONG: {
1661 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001662 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001663 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001664 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001665 inst = inst->Next_1xx();
1666 break;
1667 }
1668 case Instruction::FLOAT_TO_DOUBLE:
1669 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001670 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1671 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001672 inst = inst->Next_1xx();
1673 break;
1674 case Instruction::DOUBLE_TO_INT: {
1675 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001676 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001677 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001678 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001679 inst = inst->Next_1xx();
1680 break;
1681 }
1682 case Instruction::DOUBLE_TO_LONG: {
1683 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001684 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001685 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001686 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001687 inst = inst->Next_1xx();
1688 break;
1689 }
1690 case Instruction::DOUBLE_TO_FLOAT:
1691 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001692 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1693 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001694 inst = inst->Next_1xx();
1695 break;
1696 case Instruction::INT_TO_BYTE:
1697 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001698 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int8_t>(
1699 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001700 inst = inst->Next_1xx();
1701 break;
1702 case Instruction::INT_TO_CHAR:
1703 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001704 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<uint16_t>(
1705 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001706 inst = inst->Next_1xx();
1707 break;
1708 case Instruction::INT_TO_SHORT:
1709 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001710 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int16_t>(
1711 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001712 inst = inst->Next_1xx();
1713 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001714 case Instruction::ADD_INT: {
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001715 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001716 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001717 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1718 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001719 inst = inst->Next_2xx();
1720 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001721 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001722 case Instruction::SUB_INT:
1723 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001724 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001725 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1726 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001727 inst = inst->Next_2xx();
1728 break;
1729 case Instruction::MUL_INT:
1730 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001731 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001732 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1733 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001734 inst = inst->Next_2xx();
1735 break;
1736 case Instruction::DIV_INT: {
1737 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001738 bool success = DoIntDivide(shadow_frame, 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 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1742 break;
1743 }
1744 case Instruction::REM_INT: {
1745 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001746 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001747 shadow_frame.GetVReg(inst->VRegB_23x()),
1748 shadow_frame.GetVReg(inst->VRegC_23x()));
1749 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1750 break;
1751 }
1752 case Instruction::SHL_INT:
1753 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001754 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001755 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1756 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1757 inst = inst->Next_2xx();
1758 break;
1759 case Instruction::SHR_INT:
1760 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001761 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001762 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1763 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1764 inst = inst->Next_2xx();
1765 break;
1766 case Instruction::USHR_INT:
1767 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001768 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001769 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1770 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1771 inst = inst->Next_2xx();
1772 break;
1773 case Instruction::AND_INT:
1774 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001775 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001776 shadow_frame.GetVReg(inst->VRegB_23x()) &
1777 shadow_frame.GetVReg(inst->VRegC_23x()));
1778 inst = inst->Next_2xx();
1779 break;
1780 case Instruction::OR_INT:
1781 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001782 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001783 shadow_frame.GetVReg(inst->VRegB_23x()) |
1784 shadow_frame.GetVReg(inst->VRegC_23x()));
1785 inst = inst->Next_2xx();
1786 break;
1787 case Instruction::XOR_INT:
1788 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001789 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001790 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1791 shadow_frame.GetVReg(inst->VRegC_23x()));
1792 inst = inst->Next_2xx();
1793 break;
1794 case Instruction::ADD_LONG:
1795 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001796 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001797 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1798 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001799 inst = inst->Next_2xx();
1800 break;
1801 case Instruction::SUB_LONG:
1802 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001803 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001804 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1805 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001806 inst = inst->Next_2xx();
1807 break;
1808 case Instruction::MUL_LONG:
1809 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001810 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001811 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1812 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001813 inst = inst->Next_2xx();
1814 break;
1815 case Instruction::DIV_LONG:
1816 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001817 DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001818 shadow_frame.GetVRegLong(inst->VRegB_23x()),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001819 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001820 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1821 break;
1822 case Instruction::REM_LONG:
1823 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001824 DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001825 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1826 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1827 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1828 break;
1829 case Instruction::AND_LONG:
1830 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001831 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001832 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1833 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1834 inst = inst->Next_2xx();
1835 break;
1836 case Instruction::OR_LONG:
1837 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001838 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001839 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1840 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1841 inst = inst->Next_2xx();
1842 break;
1843 case Instruction::XOR_LONG:
1844 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001845 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001846 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1847 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1848 inst = inst->Next_2xx();
1849 break;
1850 case Instruction::SHL_LONG:
1851 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001852 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001853 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1854 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1855 inst = inst->Next_2xx();
1856 break;
1857 case Instruction::SHR_LONG:
1858 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001859 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001860 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1861 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1862 inst = inst->Next_2xx();
1863 break;
1864 case Instruction::USHR_LONG:
1865 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001866 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001867 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1868 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1869 inst = inst->Next_2xx();
1870 break;
1871 case Instruction::ADD_FLOAT:
1872 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001873 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001874 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1875 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1876 inst = inst->Next_2xx();
1877 break;
1878 case Instruction::SUB_FLOAT:
1879 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001880 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001881 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1882 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1883 inst = inst->Next_2xx();
1884 break;
1885 case Instruction::MUL_FLOAT:
1886 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001887 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001888 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1889 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1890 inst = inst->Next_2xx();
1891 break;
1892 case Instruction::DIV_FLOAT:
1893 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001894 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001895 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1896 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1897 inst = inst->Next_2xx();
1898 break;
1899 case Instruction::REM_FLOAT:
1900 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001901 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001902 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1903 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1904 inst = inst->Next_2xx();
1905 break;
1906 case Instruction::ADD_DOUBLE:
1907 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001908 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001909 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1910 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1911 inst = inst->Next_2xx();
1912 break;
1913 case Instruction::SUB_DOUBLE:
1914 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001915 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001916 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1917 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1918 inst = inst->Next_2xx();
1919 break;
1920 case Instruction::MUL_DOUBLE:
1921 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001922 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001923 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
1924 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1925 inst = inst->Next_2xx();
1926 break;
1927 case Instruction::DIV_DOUBLE:
1928 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001929 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001930 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
1931 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1932 inst = inst->Next_2xx();
1933 break;
1934 case Instruction::REM_DOUBLE:
1935 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001936 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001937 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
1938 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
1939 inst = inst->Next_2xx();
1940 break;
1941 case Instruction::ADD_INT_2ADDR: {
1942 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001943 uint4_t vregA = inst->VRegA_12x(inst_data);
Ian Rogersf72a11d2014-10-30 15:41:08 -07001944 shadow_frame.SetVReg(vregA, SafeAdd(shadow_frame.GetVReg(vregA),
1945 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001946 inst = inst->Next_1xx();
1947 break;
1948 }
1949 case Instruction::SUB_INT_2ADDR: {
1950 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001951 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001952 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001953 SafeSub(shadow_frame.GetVReg(vregA),
1954 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001955 inst = inst->Next_1xx();
1956 break;
1957 }
1958 case Instruction::MUL_INT_2ADDR: {
1959 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001960 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001961 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001962 SafeMul(shadow_frame.GetVReg(vregA),
1963 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001964 inst = inst->Next_1xx();
1965 break;
1966 }
1967 case Instruction::DIV_INT_2ADDR: {
1968 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001969 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001970 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001971 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001972 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1973 break;
1974 }
1975 case Instruction::REM_INT_2ADDR: {
1976 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001977 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001978 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001979 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001980 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1981 break;
1982 }
1983 case Instruction::SHL_INT_2ADDR: {
1984 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001985 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001986 shadow_frame.SetVReg(vregA,
1987 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001988 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001989 inst = inst->Next_1xx();
1990 break;
1991 }
1992 case Instruction::SHR_INT_2ADDR: {
1993 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001994 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001995 shadow_frame.SetVReg(vregA,
1996 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001997 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001998 inst = inst->Next_1xx();
1999 break;
2000 }
2001 case Instruction::USHR_INT_2ADDR: {
2002 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002003 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002004 shadow_frame.SetVReg(vregA,
2005 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002006 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002007 inst = inst->Next_1xx();
2008 break;
2009 }
2010 case Instruction::AND_INT_2ADDR: {
2011 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002012 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002013 shadow_frame.SetVReg(vregA,
2014 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002015 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002016 inst = inst->Next_1xx();
2017 break;
2018 }
2019 case Instruction::OR_INT_2ADDR: {
2020 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002021 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002022 shadow_frame.SetVReg(vregA,
2023 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002024 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002025 inst = inst->Next_1xx();
2026 break;
2027 }
2028 case Instruction::XOR_INT_2ADDR: {
2029 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002030 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002031 shadow_frame.SetVReg(vregA,
2032 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002033 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002034 inst = inst->Next_1xx();
2035 break;
2036 }
2037 case Instruction::ADD_LONG_2ADDR: {
2038 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002039 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002040 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002041 SafeAdd(shadow_frame.GetVRegLong(vregA),
2042 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002043 inst = inst->Next_1xx();
2044 break;
2045 }
2046 case Instruction::SUB_LONG_2ADDR: {
2047 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002048 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002049 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002050 SafeSub(shadow_frame.GetVRegLong(vregA),
2051 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002052 inst = inst->Next_1xx();
2053 break;
2054 }
2055 case Instruction::MUL_LONG_2ADDR: {
2056 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002057 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002058 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002059 SafeMul(shadow_frame.GetVRegLong(vregA),
2060 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002061 inst = inst->Next_1xx();
2062 break;
2063 }
2064 case Instruction::DIV_LONG_2ADDR: {
2065 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002066 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002067 DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002068 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002069 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
2070 break;
2071 }
2072 case Instruction::REM_LONG_2ADDR: {
2073 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002074 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002075 DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002076 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002077 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
2078 break;
2079 }
2080 case Instruction::AND_LONG_2ADDR: {
2081 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002082 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002083 shadow_frame.SetVRegLong(vregA,
2084 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002085 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002086 inst = inst->Next_1xx();
2087 break;
2088 }
2089 case Instruction::OR_LONG_2ADDR: {
2090 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002091 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002092 shadow_frame.SetVRegLong(vregA,
2093 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002094 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002095 inst = inst->Next_1xx();
2096 break;
2097 }
2098 case Instruction::XOR_LONG_2ADDR: {
2099 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002100 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002101 shadow_frame.SetVRegLong(vregA,
2102 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002103 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002104 inst = inst->Next_1xx();
2105 break;
2106 }
2107 case Instruction::SHL_LONG_2ADDR: {
2108 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002109 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002110 shadow_frame.SetVRegLong(vregA,
2111 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002112 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002113 inst = inst->Next_1xx();
2114 break;
2115 }
2116 case Instruction::SHR_LONG_2ADDR: {
2117 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002118 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002119 shadow_frame.SetVRegLong(vregA,
2120 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002121 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002122 inst = inst->Next_1xx();
2123 break;
2124 }
2125 case Instruction::USHR_LONG_2ADDR: {
2126 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002127 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002128 shadow_frame.SetVRegLong(vregA,
2129 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002130 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002131 inst = inst->Next_1xx();
2132 break;
2133 }
2134 case Instruction::ADD_FLOAT_2ADDR: {
2135 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002136 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002137 shadow_frame.SetVRegFloat(vregA,
2138 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002139 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002140 inst = inst->Next_1xx();
2141 break;
2142 }
2143 case Instruction::SUB_FLOAT_2ADDR: {
2144 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002145 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002146 shadow_frame.SetVRegFloat(vregA,
2147 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002148 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002149 inst = inst->Next_1xx();
2150 break;
2151 }
2152 case Instruction::MUL_FLOAT_2ADDR: {
2153 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002154 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002155 shadow_frame.SetVRegFloat(vregA,
2156 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002157 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002158 inst = inst->Next_1xx();
2159 break;
2160 }
2161 case Instruction::DIV_FLOAT_2ADDR: {
2162 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002163 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002164 shadow_frame.SetVRegFloat(vregA,
2165 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002166 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002167 inst = inst->Next_1xx();
2168 break;
2169 }
2170 case Instruction::REM_FLOAT_2ADDR: {
2171 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002172 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002173 shadow_frame.SetVRegFloat(vregA,
2174 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002175 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002176 inst = inst->Next_1xx();
2177 break;
2178 }
2179 case Instruction::ADD_DOUBLE_2ADDR: {
2180 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002181 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002182 shadow_frame.SetVRegDouble(vregA,
2183 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002184 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002185 inst = inst->Next_1xx();
2186 break;
2187 }
2188 case Instruction::SUB_DOUBLE_2ADDR: {
2189 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002190 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002191 shadow_frame.SetVRegDouble(vregA,
2192 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002193 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002194 inst = inst->Next_1xx();
2195 break;
2196 }
2197 case Instruction::MUL_DOUBLE_2ADDR: {
2198 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002199 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002200 shadow_frame.SetVRegDouble(vregA,
2201 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002202 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002203 inst = inst->Next_1xx();
2204 break;
2205 }
2206 case Instruction::DIV_DOUBLE_2ADDR: {
2207 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002208 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002209 shadow_frame.SetVRegDouble(vregA,
2210 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002211 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002212 inst = inst->Next_1xx();
2213 break;
2214 }
2215 case Instruction::REM_DOUBLE_2ADDR: {
2216 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002217 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002218 shadow_frame.SetVRegDouble(vregA,
2219 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002220 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002221 inst = inst->Next_1xx();
2222 break;
2223 }
2224 case Instruction::ADD_INT_LIT16:
2225 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002226 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002227 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2228 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002229 inst = inst->Next_2xx();
2230 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07002231 case Instruction::RSUB_INT_LIT16:
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002232 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002233 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002234 SafeSub(inst->VRegC_22s(),
2235 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002236 inst = inst->Next_2xx();
2237 break;
2238 case Instruction::MUL_INT_LIT16:
2239 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002240 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002241 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2242 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002243 inst = inst->Next_2xx();
2244 break;
2245 case Instruction::DIV_INT_LIT16: {
2246 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002247 bool success = DoIntDivide(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002248 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2249 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002250 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2251 break;
2252 }
2253 case Instruction::REM_INT_LIT16: {
2254 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002255 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002256 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2257 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002258 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2259 break;
2260 }
2261 case Instruction::AND_INT_LIT16:
2262 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002263 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2264 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002265 inst->VRegC_22s());
2266 inst = inst->Next_2xx();
2267 break;
2268 case Instruction::OR_INT_LIT16:
2269 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002270 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2271 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002272 inst->VRegC_22s());
2273 inst = inst->Next_2xx();
2274 break;
2275 case Instruction::XOR_INT_LIT16:
2276 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002277 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2278 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002279 inst->VRegC_22s());
2280 inst = inst->Next_2xx();
2281 break;
2282 case Instruction::ADD_INT_LIT8:
2283 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002284 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002285 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002286 inst = inst->Next_2xx();
2287 break;
2288 case Instruction::RSUB_INT_LIT8:
2289 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002290 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002291 SafeSub(inst->VRegC_22b(), shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002292 inst = inst->Next_2xx();
2293 break;
2294 case Instruction::MUL_INT_LIT8:
2295 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002296 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002297 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002298 inst = inst->Next_2xx();
2299 break;
2300 case Instruction::DIV_INT_LIT8: {
2301 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002302 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002303 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2304 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2305 break;
2306 }
2307 case Instruction::REM_INT_LIT8: {
2308 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002309 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002310 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2311 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2312 break;
2313 }
2314 case Instruction::AND_INT_LIT8:
2315 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002316 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002317 shadow_frame.GetVReg(inst->VRegB_22b()) &
2318 inst->VRegC_22b());
2319 inst = inst->Next_2xx();
2320 break;
2321 case Instruction::OR_INT_LIT8:
2322 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002323 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002324 shadow_frame.GetVReg(inst->VRegB_22b()) |
2325 inst->VRegC_22b());
2326 inst = inst->Next_2xx();
2327 break;
2328 case Instruction::XOR_INT_LIT8:
2329 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002330 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002331 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2332 inst->VRegC_22b());
2333 inst = inst->Next_2xx();
2334 break;
2335 case Instruction::SHL_INT_LIT8:
2336 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002337 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002338 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2339 (inst->VRegC_22b() & 0x1f));
2340 inst = inst->Next_2xx();
2341 break;
2342 case Instruction::SHR_INT_LIT8:
2343 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002344 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002345 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2346 (inst->VRegC_22b() & 0x1f));
2347 inst = inst->Next_2xx();
2348 break;
2349 case Instruction::USHR_INT_LIT8:
2350 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002351 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002352 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2353 (inst->VRegC_22b() & 0x1f));
2354 inst = inst->Next_2xx();
2355 break;
2356 case Instruction::UNUSED_3E ... Instruction::UNUSED_43:
Narayan Kamath8ec3bd22016-08-03 12:46:23 +01002357 case Instruction::UNUSED_F3 ... Instruction::UNUSED_F9:
Orion Hodsonc069a302017-01-18 09:23:12 +00002358 case Instruction::UNUSED_FE ... Instruction::UNUSED_FF:
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002359 case Instruction::UNUSED_79:
2360 case Instruction::UNUSED_7A:
Ian Rogerse94652f2014-12-02 11:13:19 -08002361 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002362 }
buzbee1452bee2015-03-06 14:43:04 -08002363 } while (!interpret_one_instruction);
2364 // Record where we stopped.
2365 shadow_frame.SetDexPC(inst->GetDexPc(insns));
buzbeed6b48db2016-01-28 15:48:55 -08002366 return result_register;
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002367} // NOLINT(readability/fn_size)
2368
2369// Explicit definitions of ExecuteSwitchImpl.
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002370template HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002371JValue ExecuteSwitchImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -08002372 ShadowFrame& shadow_frame, JValue result_register,
2373 bool interpret_one_instruction);
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002374template HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002375JValue ExecuteSwitchImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -08002376 ShadowFrame& shadow_frame, JValue result_register,
2377 bool interpret_one_instruction);
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002378template
Ian Rogerse94652f2014-12-02 11:13:19 -08002379JValue ExecuteSwitchImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -08002380 ShadowFrame& shadow_frame, JValue result_register,
2381 bool interpret_one_instruction);
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002382template
Ian Rogerse94652f2014-12-02 11:13:19 -08002383JValue ExecuteSwitchImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -08002384 ShadowFrame& shadow_frame, JValue result_register,
2385 bool interpret_one_instruction);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002386
2387} // namespace interpreter
2388} // namespace art